Apollo 11.0
自动驾驶开放平台
dst_type_fusion.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 <limits>
19#include <numeric>
20
21#include <boost/format.hpp>
22
23#include "absl/strings/str_cat.h"
24#include "absl/strings/str_join.h"
25
26#include "modules/perception/multi_sensor_fusion/proto/dst_type_fusion_config.pb.h"
27
28#include "cyber/common/file.h"
33
34namespace apollo {
35namespace perception {
36namespace fusion {
37
39
40template <typename Type>
41std::string vector2string(const std::vector<Type> &values) {
42 return absl::StrCat("(", absl::StrJoin(values, " "), ")");
43}
44
45std::string DstTypeFusion::name_ = "DstTypeFusion"; // NOLINT
46DstMaps DstTypeFusion::dst_maps_;
47DstTypeFusionOptions DstTypeFusion::options_;
48
50 : BaseTypeFusion(track), fused_dst_(name_) {
51 Dst sensor_dst(name_);
52 sensor_dst =
53 TypeProbsToDst(track->GetFusedObject()->GetBaseObject()->type_probs);
54 SensorObjectConstPtr lidar_object = track->GetLatestLidarObject();
55 SensorObjectConstPtr camera_object = track->GetLatestCameraObject();
56 SensorObjectConstPtr radar_object = track->GetLatestRadarObject();
57 SensorObjectConstPtr sensor_obj = lidar_object;
58 sensor_obj = sensor_obj != nullptr ? sensor_obj : camera_object;
59 sensor_obj = sensor_obj != nullptr ? sensor_obj : radar_object;
60 if (sensor_obj == nullptr) {
61 AERROR << "track has no sensor_obj";
62 return;
63 }
64 fused_dst_ =
65 fused_dst_ + sensor_dst * GetReliability(sensor_obj->GetSensorId());
66 UpdateTypeState();
67}
68
70 std::string config_file =
71 GetConfigFile(options.config_path, options.config_file);
72
74 if (!cyber::common::GetProtoFromFile(config_file, &params)) {
75 AERROR << "Read config failed: " << config_file;
76 return false;
77 }
78
79 for (auto camera_param : params.camera_params()) {
80 std::string camera_id = camera_param.name();
81 options_.camera_max_valid_dist[camera_id] = camera_param.valid_dist();
82 options_.sensor_reliability[camera_id] = camera_param.reliability();
83 options_.sensor_reliability_for_unknown[camera_id] =
84 camera_param.reliability_for_unknown();
85 AINFO << "dst type fusion params: " << camera_id
86 << " max valid dist: " << options_.camera_max_valid_dist[camera_id]
87 << " reliability: " << options_.sensor_reliability[camera_id]
88 << " reliability for unknown: "
89 << options_.sensor_reliability_for_unknown[camera_id];
90 }
91
92 for (auto lidar_param : params.lidar_params()) {
93 std::string lidar_id = lidar_param.name();
94 options_.sensor_reliability[lidar_id] = lidar_param.reliability();
95 options_.sensor_reliability_for_unknown[lidar_id] =
96 lidar_param.reliability_for_unknown();
97 AINFO << "dst type fusion params: " << lidar_id
98 << " reliability: " << options_.sensor_reliability[lidar_id]
99 << " reliability for unknown: "
100 << options_.sensor_reliability_for_unknown[lidar_id];
101 }
102
103 if (DstManager::Instance()->IsAppAdded(name_)) {
104 return true;
105 }
106 DstManager::Instance()->AddApp(name_, dst_maps_.fod_subsets_,
107 dst_maps_.subset_names_);
108 return DstManager::Instance()->IsAppAdded(name_);
109}
110
112 double target_timestamp) {
113 Dst measurement_dst(name_);
114 measurement_dst = TypeProbsToDst(measurement->GetBaseObject()->type_probs);
115 ADEBUG << "type_probs: "
116 << vector2string<float>(measurement->GetBaseObject()->type_probs);
117 fused_dst_ =
118 fused_dst_ + measurement_dst * GetReliability(measurement->GetSensorId());
119 ADEBUG << "reliability: " << GetReliability(measurement->GetSensorId());
120 // update subtype
121 if (IsCamera(measurement)) {
122 track_ref_->GetFusedObject()->GetBaseObject()->sub_type =
123 measurement->GetBaseObject()->sub_type;
124 }
125 UpdateTypeState();
126}
127
128void DstTypeFusion::UpdateWithoutMeasurement(const std::string &sensor_id,
129 double measurement_timestamp,
130 double target_timestamp,
131 double min_match_dist) {
132 algorithm::SensorManager *sensor_manager =
133 algorithm::SensorManager::Instance();
134 if (sensor_manager->IsCamera(sensor_id)) {
135 // add the evidence of OTHERS_UNMOVABLE
136 double in_view_ratio = 0.0;
137 // 1.get camera intrinsic and pose
138 SensorDataManager *sensor_data_manager = SensorDataManager::Instance();
139 base::BaseCameraModelPtr camera_model =
140 sensor_data_manager->GetCameraIntrinsic(sensor_id);
141 ACHECK(camera_model != nullptr)
142 << "Failed to get camera intrinsic for " << sensor_id;
143
144 Eigen::Affine3d sensor2world_pose;
145 bool status = sensor_data_manager->GetPose(sensor_id, measurement_timestamp,
146 &sensor2world_pose);
147 auto max_dist_it = options_.camera_max_valid_dist.find(sensor_id);
148 if (max_dist_it == options_.camera_max_valid_dist.end()) {
149 AWARN << boost::format(
150 "There is no pre-defined max valid camera"
151 " dist for sensor type: %s") %
152 sensor_id;
153 }
154 if (status && max_dist_it != options_.camera_max_valid_dist.end()) {
155 SensorObjectConstPtr lidar_object = track_ref_->GetLatestLidarObject();
156 SensorObjectConstPtr radar_object = track_ref_->GetLatestRadarObject();
157 double camera_max_dist = max_dist_it->second;
158 if (lidar_object != nullptr) {
159 in_view_ratio = ObjectInCameraView(
160 lidar_object, camera_model, sensor2world_pose,
161 measurement_timestamp, camera_max_dist, true, false);
162 } else if (radar_object != nullptr) {
163 in_view_ratio = ObjectInCameraView(
164 radar_object, camera_model, sensor2world_pose,
165 measurement_timestamp, camera_max_dist, false, false);
166 }
167 }
168
169 // TODO(yuantingrong): need consider the camera object only
170 // use the min_match_dist to decide the occlusion
171 // TODO(yuantingrong): not reasonable, when sensor type is camera,
172 // the input min_match_dist is a probability([0, 1], 1 is better)
173 // to measure how well the fused object locate
174 // in a box detected by the camera.
175 auto loss_fun = [](double dist_score) {
176 CHECK_GE(dist_score, 0.0);
177 static constexpr double th = 0.9;
178 if (dist_score >= th) {
179 return 0.0;
180 }
181 double res = 1 - (dist_score / th) * (dist_score / th);
182 return res * res;
183 };
184 double occlusion_score = loss_fun(min_match_dist);
185 std::map<uint64_t, double> fp_dst_map = {{DstMaps::OTHERS, 0.7},
186 {DstMaps::UNKNOWN, 0.3}};
187 Dst fp_dst(name_);
188 fp_dst.SetBba(fp_dst_map);
189 fused_dst_ = fused_dst_ +
190 (fp_dst * in_view_ratio * occlusion_score) *
191 GetReliabilityForUnKnown(sensor_id, measurement_timestamp);
192 UpdateTypeState();
193 }
194}
195
196std::string DstTypeFusion::Name() const { return name_; }
197
198bool DstTypeFusion::TypToHyp(size_t object_type,
199 uint64_t *hypothesis_type) const {
200 auto find_res = dst_maps_.typ_to_hyp_map_.find(object_type);
201 if (find_res == dst_maps_.typ_to_hyp_map_.end()) {
202 return false;
203 }
204 *hypothesis_type = find_res->second;
205 return true;
206}
207
208bool DstTypeFusion::HypToTyp(uint64_t hypothesis_type,
209 size_t *object_type) const {
210 auto find_res = dst_maps_.hyp_to_typ_map_.find(hypothesis_type);
211 if (find_res == dst_maps_.hyp_to_typ_map_.end()) {
212 return false;
213 }
214 *object_type = find_res->second;
215 return true;
216}
217
218Dst DstTypeFusion::TypeProbsToDst(const std::vector<float> &type_probs) {
219 Dst res_dst(name_);
220 double type_probs_sum =
221 std::accumulate(type_probs.begin(), type_probs.end(), 0.0);
222 if (type_probs_sum < std::numeric_limits<double>::min()) {
223 // AWARN << "the sum of types probability equal 0.0";
224 return res_dst;
225 }
226 // if (type_probs.size() > base::ObjectType::UNKNOWN_UNMOVABLE &&
227 // type_probs[(int)base::ObjectType::UNKNOWN_UNMOVABLE] > 0.0f) {
228 // AINFO << "unknonw_unmovable prob = " <<
229 // type_probs[(int)base::ObjectType::UNKNOWN_UNMOVABLE] << " > 0.0f";
230 //}
231 std::map<uint64_t, double> res_bba_map;
232 for (size_t i = 0; i < type_probs.size(); ++i) {
233 size_t typ = i;
234 uint64_t hyp = 0;
235 if (!TypToHyp(typ, &hyp)) {
236 continue;
237 }
238 res_bba_map[hyp] = type_probs[typ];
239 }
240 // for support camera probs detection prob
241 // if (type_probs_sum < 1.0) {
242 // auto find_res = res_bba_map.find(DSTInitiator::OTHERS);
243 // if (find_res == res_bba_map.end()) {
244 // res_bba_map[DSTInitiator::OTHERS] = 1 - type_probs_sum;
245 // } else {
246 // find_res->second += (1 - type_probs_sum);
247 // }
248 // }
249 ACHECK(res_dst.SetBba(res_bba_map));
250 return res_dst;
251}
252
253double DstTypeFusion::GetReliability(const std::string &sensor_id) const {
254 auto find_res = options_.sensor_reliability.find(sensor_id);
255 if (find_res == options_.sensor_reliability.end()) {
256 ADEBUG << "the sensor type: " << sensor_id
257 << " is not supported by class fusion";
258 return 0.0;
259 }
260 return find_res->second;
261}
262
263double DstTypeFusion::GetReliabilityForUnKnown(
264 const std::string &sensor_id, double measurement_timestamp) const {
265 auto find_res = options_.sensor_reliability_for_unknown.find(sensor_id);
266 if (find_res == options_.sensor_reliability_for_unknown.end()) {
267 ADEBUG << "the sensor type: " << sensor_id
268 << " is not supported by class fusion";
269 return 0.0;
270 }
271 time_t rawtime = static_cast<time_t>(measurement_timestamp);
272 struct tm timeinfo;
273 localtime_r(&rawtime, &timeinfo);
274 bool is_night = (timeinfo.tm_hour >= 17);
275 double prob =
276 (algorithm::SensorManager::Instance()->IsCamera(sensor_id) && is_night)
277 ? 0.1
278 : 1.0;
279 return find_res->second * prob;
280}
281
282void DstTypeFusion::UpdateTypeState() {
283 const std::vector<double> &fused_dst_vec = fused_dst_.GetBbaVec();
284 auto max_iter = std::max_element(fused_dst_vec.begin(), fused_dst_vec.end());
285 size_t max_hyp_ind = max_iter - fused_dst_vec.begin();
286 uint64_t max_hyp = DstManager::Instance()->IndToFodSubset(name_, max_hyp_ind);
287 if (max_hyp == DstMaps::OTHERS_MOVABLE) {
288 ADEBUG << "max hyp is UNKNOWN_MOVABLE" << fused_dst_.PrintBba();
289 }
290
291 // update type
292 size_t object_type = 0;
293 HypToTyp(max_hyp, &object_type);
294 track_ref_->GetFusedObject()->GetBaseObject()->type =
295 static_cast<base::ObjectType>(object_type);
296 // modify subtype
297 auto type = base::kSubType2TypeMap.find(
298 track_ref_->GetFusedObject()->GetBaseObject()->sub_type);
299 if (type != base::kSubType2TypeMap.end() &&
300 type->second != track_ref_->GetFusedObject()->GetBaseObject()->type) {
301 track_ref_->GetFusedObject()->GetBaseObject()->sub_type =
303 }
304
305 // update type_probs
306 std::vector<float> type_probs(
307 static_cast<int>(base::ObjectType::MAX_OBJECT_TYPE), 0);
308 for (size_t i = 0; i < fused_dst_vec.size(); ++i) {
309 size_t type = 0;
310 uint64_t hyp = DstManager::Instance()->IndToFodSubset(name_, i);
311 HypToTyp(hyp, &type);
312 type_probs[type] += static_cast<float>(fused_dst_vec[i]);
313 }
314 track_ref_->GetFusedObject()->GetBaseObject()->type_probs = type_probs;
315}
316
317} // namespace fusion
318} // namespace perception
319} // namespace apollo
bool IsCamera(const std::string &name) const
uint64_t IndToFodSubset(const std::string &app_name, const size_t &ind)
bool IsAppAdded(const std::string &app_name)
Whether app added
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 >())
void UpdateWithoutMeasurement(const std::string &sensor_id, double measurement_timestamp, double target_timestamp, double min_match_dist) override
update track state without measurement
void UpdateWithMeasurement(const SensorObjectPtr measurement, double target_timestamp) override
update track type state with measurement
static bool Init(const TypeFusionInitOptions &options)
std::string Name() const
The name of BaseTypeFusion
bool SetBba(const std::map< uint64_t, double > &bba_map)
Set the Bba object, strictly require the fod in bba_map is valid
const std::vector< double > & GetBbaVec() const
Get the Bba Vec object
bool GetPose(const std::string &sensor_id, double timestamp, Eigen::Affine3d *pose) const
Get the Pose object
base::BaseCameraModelPtr GetCameraIntrinsic(const std::string &sensor_id) const
Get the Camera Intrinsic object
#define ACHECK(cond)
Definition log.h:80
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
#define AWARN
Definition log.h:43
bool GetProtoFromFile(const std::string &file_name, google::protobuf::Message *message)
Parses the content of the file specified by the file_name as a representation of protobufs,...
Definition file.cc:132
std::string GetAbsolutePath(const std::string &prefix, const std::string &relative_path)
Get absolute path by concatenating prefix and relative_path.
Definition file.cc:179
std::shared_ptr< BaseCameraModel > BaseCameraModelPtr
Definition camera.h:75
const std::map< ObjectSubType, ObjectType > kSubType2TypeMap
ObjectSubType mapping
std::shared_ptr< const SensorObject > SensorObjectConstPtr
std::shared_ptr< SensorObject > SensorObjectPtr
bool IsCamera(const SensorObjectConstPtr &obj)
float ObjectInCameraView(SensorObjectConstPtr sensor_object, base::BaseCameraModelPtr camera_model, const Eigen::Affine3d &camera_sensor2world_pose, double camera_ts, double camera_max_dist, bool motion_compensation, bool all_in)
std::shared_ptr< Track > TrackPtr
Definition track.h:397
std::string vector2string(const std::vector< Type > &values)
std::string GetConfigFile(const std::string &config_path, const std::string &config_file)
Definition util.cc:80
class register implement
Definition arena_queue.h:37
std::map< uint64_t, size_t > hyp_to_typ_map_
std::vector< std::string > subset_names_
std::unordered_map< size_t, uint64_t > typ_to_hyp_map_
std::vector< uint64_t > fod_subsets_
std::map< std::string, double > sensor_reliability_for_unknown
std::map< std::string, double > camera_max_valid_dist
std::map< std::string, double > sensor_reliability