Apollo 11.0
自动驾驶开放平台
dst_evidence.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2018 The Apollo Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *****************************************************************************/
17
18#include <algorithm>
19#include <bitset>
20#include <numeric>
21
22#include <boost/format.hpp>
23
24#include "cyber/common/log.h"
25
26namespace apollo {
27namespace perception {
28namespace fusion {
29
30bool DstManager::AddApp(const std::string &app_name,
31 const std::vector<uint64_t> &fod_subsets,
32 const std::vector<std::string> &fod_subset_names) {
33 if (dst_common_data_.find(app_name) != dst_common_data_.end()) {
34 AWARN << boost::format("Dst %s was added!") % app_name;
35 }
36 DstCommonData dst_data;
37 dst_data.fod_subsets_ = fod_subsets;
38 BuildSubsetsIndMap(&dst_data);
39 if (dst_data.subsets_ind_map_.size() != dst_data.fod_subsets_.size()) {
40 AERROR << boost::format(
41 "Dst %s: The input fod subsets"
42 " have repetitive elements.") %
43 app_name;
44 return false;
45 }
46 FodCheck(&dst_data);
47 ComputeCardinalities(&dst_data);
48 if (!ComputeRelations(&dst_data)) {
49 return false;
50 }
51 dst_data.init_ = true;
52 BuildNamesMap(fod_subset_names, &dst_data);
53
54 std::lock_guard<std::mutex> lock(map_mutex_);
55 dst_common_data_[app_name] = dst_data;
56 return true;
57}
58
59bool DstManager::IsAppAdded(const std::string &app_name) {
60 auto iter = dst_common_data_.find(app_name);
61 if (iter == dst_common_data_.end()) {
62 return false;
63 }
64 return iter->second.init_;
65}
66
67DstCommonDataPtr DstManager::GetAppDataPtr(const std::string &app_name) {
68 if (!IsAppAdded(app_name)) {
69 AERROR << "app_name is not available";
70 return nullptr;
71 }
72 auto iter = dst_common_data_.find(app_name);
73 if (iter != dst_common_data_.end()) {
74 return &iter->second;
75 }
76 return nullptr;
77}
78
79size_t DstManager::FodSubsetToInd(const std::string &app_name,
80 const uint64_t &fod_subset) {
81 auto iter0 = dst_common_data_.find(app_name);
82 ACHECK(iter0 != dst_common_data_.end());
83 auto iter = iter0->second.subsets_ind_map_.find(fod_subset);
84 ACHECK(iter != iter0->second.subsets_ind_map_.end());
85 return iter->second;
86}
87
88uint64_t DstManager::IndToFodSubset(const std::string &app_name,
89 const size_t &ind) {
90 auto iter = dst_common_data_.find(app_name);
91 ACHECK(iter != dst_common_data_.end());
92 return iter->second.fod_subsets_[ind];
93}
94
95void DstManager::BuildSubsetsIndMap(DstCommonData *dst_data) {
96 dst_data->subsets_ind_map_.clear();
97 for (size_t i = 0; i < dst_data->fod_subsets_.size(); ++i) {
98 dst_data->subsets_ind_map_[dst_data->fod_subsets_[i]] = i;
99 }
100}
101
102void DstManager::FodCheck(DstCommonData *dst_data) {
103 uint64_t fod = 0;
104 for (auto fod_subset : dst_data->fod_subsets_) {
105 fod |= fod_subset;
106 }
107 dst_data->fod_loc_ = dst_data->fod_subsets_.size();
108 auto find_res = dst_data->subsets_ind_map_.insert(
109 std::make_pair(fod, dst_data->fod_subsets_.size()));
110 if (find_res.second) {
111 dst_data->fod_subsets_.push_back(fod);
112 } else {
113 dst_data->fod_loc_ = find_res.first->second;
114 }
115}
116
117void DstManager::ComputeCardinalities(DstCommonData *dst_data) {
118 auto count_set_bits = [](uint64_t fod_subset) {
119 size_t count = 0;
120 while (fod_subset) {
121 fod_subset &= (fod_subset - 1);
122 ++count;
123 }
124 return count;
125 };
126 dst_data->fod_subset_cardinalities_.reserve(dst_data->fod_subsets_.size());
127 for (auto fod_subset : dst_data->fod_subsets_) {
128 dst_data->fod_subset_cardinalities_.push_back(count_set_bits(fod_subset));
129 }
130}
131
132bool DstManager::ComputeRelations(DstCommonData *dst_data) {
133 auto reserve_space = [](std::vector<std::vector<size_t>> &relations,
134 size_t size) {
135 relations.clear();
136 relations.resize(size);
137 for (auto &relation : relations) {
138 relation.reserve(size);
139 }
140 };
141 reserve_space(dst_data->subset_relations_, dst_data->fod_subsets_.size());
142 reserve_space(dst_data->inter_relations_, dst_data->fod_subsets_.size());
143 // reserve space for combination_relations
144 dst_data->combination_relations_.clear();
145 dst_data->combination_relations_.resize(dst_data->fod_subsets_.size());
146 for (auto &combination_relation : dst_data->combination_relations_) {
147 combination_relation.reserve(2 * dst_data->fod_subsets_.size());
148 }
149 for (size_t i = 0; i < dst_data->fod_subsets_.size(); ++i) {
150 uint64_t fod_subset = dst_data->fod_subsets_[i];
151 auto &subset_inds = dst_data->subset_relations_[i];
152 auto &inter_inds = dst_data->inter_relations_[i];
153
154 for (size_t j = 0; j < dst_data->fod_subsets_.size(); ++j) {
155 if ((fod_subset | dst_data->fod_subsets_[j]) == fod_subset) {
156 subset_inds.push_back(j);
157 }
158 uint64_t inter_res = fod_subset & dst_data->fod_subsets_[j];
159 if (inter_res) {
160 inter_inds.push_back(j);
161 auto find_res = dst_data->subsets_ind_map_.find(inter_res);
162 if (find_res == dst_data->subsets_ind_map_.end()) {
163 AERROR << boost::format(
164 "Dst: The input set "
165 "of fod subsets has no closure under the operation "
166 "intersection");
167 return false;
168 }
169 dst_data->combination_relations_[find_res->second].push_back(
170 std::make_pair(i, j));
171 }
172 }
173 }
174 return true;
175}
176
177void DstManager::BuildNamesMap(const std::vector<std::string> &fod_subset_names,
178 DstCommonData *dst_data) {
179 // reset and reserve space
180 dst_data->fod_subset_names_.clear();
181 dst_data->fod_subset_names_.resize(dst_data->fod_subsets_.size());
182 for (size_t i = 0; i < dst_data->fod_subsets_.size(); ++i) {
183 dst_data->fod_subset_names_[i] =
184 std::bitset<64>(dst_data->fod_subsets_[i]).to_string();
185 }
186 // set fod to unknown
187 dst_data->fod_subset_names_[dst_data->fod_loc_] = "unknown";
188 for (size_t i = 0;
189 i < std::min(fod_subset_names.size(), dst_data->fod_subsets_.size());
190 ++i) {
191 dst_data->fod_subset_names_[i] = fod_subset_names[i];
192 }
193}
194
195Dst::Dst(const std::string &app_name) : app_name_(app_name) {
196 if (DstManager::Instance()->IsAppAdded(app_name)) {
197 dst_data_ptr_ = DstManager::Instance()->GetAppDataPtr(app_name);
198 // default BBA provide no more evidence
199 bba_vec_.resize(dst_data_ptr_->fod_subsets_.size(), 0.0);
200 bba_vec_[dst_data_ptr_->fod_loc_] = 1.0;
201 }
202}
203
204void Dst::SelfCheck() const {
205 ACHECK(DstManager::Instance()->IsAppAdded(app_name_));
206 if (dst_data_ptr_ == nullptr) {
207 dst_data_ptr_ = DstManager::Instance()->GetAppDataPtr(app_name_);
208 CHECK_NOTNULL(dst_data_ptr_);
209 bba_vec_.resize(dst_data_ptr_->fod_subsets_.size(), 0.0);
210 bba_vec_[dst_data_ptr_->fod_loc_] = 1.0;
211 }
212}
213
214double Dst::GetSubsetBfmass(uint64_t fod_subset) const {
215 SelfCheck();
216 size_t idx = DstManager::Instance()->FodSubsetToInd(app_name_, fod_subset);
217 return bba_vec_[idx];
218}
219
220double Dst::GetIndBfmass(size_t ind) const {
221 SelfCheck();
222 return bba_vec_[ind];
223}
224
225bool Dst::SetBbaVec(const std::vector<double> &bba_vec) {
226 SelfCheck();
227 if (bba_vec.size() != dst_data_ptr_->fod_subsets_.size()) {
228 AERROR << boost::format("input bba_vec size: %d != Dst subsets size: %d") %
229 bba_vec.size() % dst_data_ptr_->fod_subsets_.size();
230 return false;
231 }
232 // check belief mass valid
233 for (auto belief_mass : bba_vec) {
234 if (belief_mass < 0.0) {
235 AWARN << boost::format(" belief mass: %lf is not valid") % belief_mass;
236 return false;
237 }
238 }
239 // reset
240 // *this = Dst(app_name_);
241 bba_vec_ = bba_vec;
242 Normalize();
243 return true;
244}
245
246bool Dst::SetBba(const std::map<uint64_t, double> &bba_map) {
247 SelfCheck();
248 std::vector<double> bba_vec(dst_data_ptr_->fod_subsets_.size(), 0.0);
249 const auto &subsets_ind_map = dst_data_ptr_->subsets_ind_map_;
250 for (auto bba_map_iter : bba_map) {
251 uint64_t fod_subset = bba_map_iter.first;
252 double belief_mass = bba_map_iter.second;
253 auto find_res = subsets_ind_map.find(fod_subset);
254 if (find_res == subsets_ind_map.end()) {
255 AERROR << "the input bba map has invalid fod subset";
256 return false;
257 }
258 if (belief_mass < 0.0) {
259 AWARN << boost::format("belief mass: %lf is not valid. Dst name: %s") %
260 belief_mass % app_name_;
261 return false;
262 }
263 bba_vec[find_res->second] = belief_mass;
264 }
265 // reset
266 // *this = Dst(app_name_);
267 bba_vec_ = bba_vec;
268 Normalize();
269 return true;
270}
271
272std::string Dst::PrintBba() const {
273 SelfCheck();
274 static constexpr size_t total_res_size = 10000;
275 static constexpr size_t row_res_size = 1000;
276 static auto print_row = [](const std::string &row_header,
277 const std::vector<double> &data) {
278 std::string row_str = (boost::format("%19s ") % row_header).str();
279 row_str.reserve(row_res_size);
280 for (auto flt : data) {
281 row_str += (boost::format("%20.6lf") % (flt * 100)).str();
282 }
283 row_str += "\n";
284 return row_str;
285 };
286 std::string res;
287 res.reserve(total_res_size);
288 res += "\n";
289 // output table header
290 std::string header = (boost::format("%20s") % " ").str();
291 header.reserve(row_res_size);
292 const std::vector<std::string> &fod_subset_names =
293 dst_data_ptr_->fod_subset_names_;
294 for (const auto &fod_subset_name : fod_subset_names) {
295 header += (boost::format("%20s") % fod_subset_name).str();
296 }
297 res += header + "\n";
298 res += print_row("belief_mass", bba_vec_);
299 // res += print_row("support", support_vec_);
300 // res += print_row("uncertainty", uncertainty_vec_);
301 // res += print_row("probability", probability_vec_);
302 return res;
303}
304
306 SelfCheck();
307 auto resize_space = [](std::vector<double> &vec, size_t size) {
308 vec.clear();
309 vec.resize(size, 0.0);
310 };
311 size_t size = bba_vec_.size();
312 resize_space(support_vec_, size);
313 resize_space(plausibility_vec_, size);
314 resize_space(uncertainty_vec_, size);
315 const std::vector<std::vector<size_t>> &subset_relations =
316 dst_data_ptr_->subset_relations_;
317 const std::vector<std::vector<size_t>> &inter_relations =
318 dst_data_ptr_->inter_relations_;
319 for (size_t i = 0; i < size; ++i) {
320 double &spt = support_vec_[i];
321 double &pls = plausibility_vec_[i];
322 double &uct = uncertainty_vec_[i];
323 const auto &subset_inds = subset_relations[i];
324 const auto &inter_inds = inter_relations[i];
325 // AINFO << boost::format("inter_size: (%d %d)") % i % inter_inds.size();
326 for (auto subset_ind : subset_inds) {
327 spt += bba_vec_[subset_ind];
328 }
329 for (auto inter_ind : inter_inds) {
330 pls += bba_vec_[inter_ind];
331 }
332 // AINFO << boost::format("pls: (%d %lf)") % i % pls;
333 uct = pls - spt;
334 }
335}
336
337// use combination_relations to compute all the probability at one time
339 SelfCheck();
340 probability_vec_.clear();
341 probability_vec_.resize(bba_vec_.size(), 0.0);
342 const auto &combination_relations = dst_data_ptr_->combination_relations_;
343 const std::vector<size_t> &fod_subset_cardinalities =
344 dst_data_ptr_->fod_subset_cardinalities_;
345 for (size_t i = 0; i < combination_relations.size(); ++i) {
346 const auto &combination_pairs = combination_relations[i];
347 double intersection_card = static_cast<double>(fod_subset_cardinalities[i]);
348 for (auto combination_pair : combination_pairs) {
349 size_t a_ind = combination_pair.first;
350 size_t b_ind = combination_pair.second;
351 probability_vec_[a_ind] +=
352 intersection_card /
353 static_cast<double>(fod_subset_cardinalities[b_ind]) *
354 bba_vec_[b_ind];
355 }
356 }
357}
358
359void Dst::Normalize() {
360 SelfCheck();
361 double mass_sum = std::accumulate(bba_vec_.begin(), bba_vec_.end(), 0.0);
362 if (mass_sum == 0.0) {
363 ADEBUG << "mass_sum equal 0!!";
364 }
365 for (auto &belief_mass : bba_vec_) {
366 belief_mass /= mass_sum;
367 }
368}
369
370Dst operator+(const Dst &lhs, const Dst &rhs) {
371 CHECK_EQ(lhs.app_name_, rhs.app_name_)
372 << boost::format("lhs Dst(%s) is not equal to rhs Dst(%s)") %
373 lhs.app_name_ % rhs.app_name_;
374 lhs.SelfCheck();
375 rhs.SelfCheck();
376 Dst res(lhs.app_name_);
377 std::vector<double> &resbba_vec_ = res.bba_vec_;
378 const auto &combination_relations = lhs.dst_data_ptr_->combination_relations_;
379 for (size_t i = 0; i < resbba_vec_.size(); ++i) {
380 const auto &combination_pairs = combination_relations[i];
381 // AINFO << "pairs size: " << combination_pairs.size();
382 double &belief_mass = resbba_vec_[i];
383 belief_mass = 0.0;
384 for (auto combination_pair : combination_pairs) {
385 // AINFO << boost::format("(%d %d)") % combination_pair.first
386 // % combination_pair.second;
387 belief_mass += lhs.GetIndBfmass(combination_pair.first) *
388 rhs.GetIndBfmass(combination_pair.second);
389 }
390 // AINFO << boost::format("belief_mass: %lf") % belief_mass;
391 }
392 res.Normalize();
393 return res;
394}
395
396Dst operator*(const Dst &dst, double w) {
397 dst.SelfCheck();
398 Dst res(dst.app_name_);
399 // check w
400 if (w < 0.0 || w > 1.0) {
401 AERROR << boost::format(
402 "the weight of bba %lf is not valid, return default bba") %
403 w;
404 return res;
405 }
406 size_t fod_loc = dst.dst_data_ptr_->fod_loc_;
407 std::vector<double> &resbba_vec_ = res.bba_vec_;
408 const std::vector<double> &bba_vec = dst.bba_vec_;
409 for (size_t i = 0; i < resbba_vec_.size(); ++i) {
410 if (i == fod_loc) {
411 resbba_vec_[i] = 1.0 - w + w * bba_vec[i];
412 } else {
413 resbba_vec_[i] = w * bba_vec[i];
414 }
415 }
416 return res;
417}
418
419} // namespace fusion
420} // namespace perception
421} // namespace apollo
uint64_t IndToFodSubset(const std::string &app_name, const size_t &ind)
DstCommonDataPtr GetAppDataPtr(const std::string &app_name)
Get the app data ptr object
bool IsAppAdded(const std::string &app_name)
Whether app added
size_t FodSubsetToInd(const std::string &app_name, const uint64_t &fod_subset)
bool AddApp(const std::string &app_name, const std::vector< uint64_t > &fod_subsets, const std::vector< std::string > &fod_subset_names=std::vector< std::string >())
double GetIndBfmass(size_t ind) const
Get the Ind Bfmass object
double GetSubsetBfmass(uint64_t fod_subset) const
Get the Subset Bfmass object
bool SetBbaVec(const std::vector< double > &bba_vec)
Set the Bba Vec object
bool SetBba(const std::map< uint64_t, double > &bba_map)
Set the Bba object, strictly require the fod in bba_map is valid
Dst(const std::string &app_name)
#define ACHECK(cond)
Definition log.h:80
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AWARN
Definition log.h:43
Dst operator*(const Dst &dst, double w)
class register implement
Definition arena_queue.h:37
std::vector< size_t > fod_subset_cardinalities_
std::vector< std::vector< std::pair< size_t, size_t > > > combination_relations_
std::vector< std::vector< size_t > > subset_relations_
std::vector< std::string > fod_subset_names_
std::vector< std::vector< size_t > > inter_relations_
std::map< uint64_t, size_t > subsets_ind_map_