20#include <boost/format.hpp>
22#include "modules/perception/multi_sensor_fusion/proto/dst_existence_fusion_config.pb.h"
36const char *DstExistenceFusion::name_ =
"DstExistenceFusion";
37const char *DstExistenceFusion::toic_name_ =
"DstToicFusion";
38ExistenceDstMaps DstExistenceFusion::existence_dst_maps_;
39ToicDstMaps DstExistenceFusion::toic_dst_maps_;
40DstExistenceFusionOptions DstExistenceFusion::options_;
44 fused_toic_(toic_name_),
45 fused_existence_(name_) {}
48 std::string config_file =
53 AERROR <<
"Read config failed: " << config_file;
57 std::string camera_id = valid_dist.camera_name();
59 AINFO <<
"dst existence fusion params: " << camera_id
65 AINFO <<
"dst existence fusion params: "
66 <<
" track_object_max_match_distance: "
82 std::string sensor_id = measurement->GetSensorId();
83 double timestamp = measurement->GetTimestamp();
85 double association_prob = 1 - match_dist / max_match_distance;
87 association_prob = 1.0;
90 double exist_factor = GetExistReliability(measurement);
91 double decay = ComputeDistDecay(obj, sensor_id, timestamp);
93 decay = ComputeFeatureInfluence(measurement);
95 double obj_exist_prob = exist_factor * decay;
96 Dst existence_evidence(fused_existence_.
Name());
101 const double exist_fused_w = 1.0;
104 fused_existence_ + existence_evidence * exist_fused_w * association_prob;
106 <<
" obj_id " << measurement->GetBaseObject()->track_id
107 <<
" association_prob: " << association_prob <<
" decay: " << decay
108 <<
" exist_prob: " << obj_exist_prob
109 <<
" sensor_id: " << measurement->GetSensorId()
112 UpdateToicWithCameraMeasurement(measurement, match_dist);
114 UpdateExistenceState();
118 double measurement_timestamp,
119 double target_timestamp,
120 double min_match_dist) {
122 if (algorithm::SensorManager::Instance()->
IsCamera(sensor_id)) {
123 camera_object =
track_ref_->GetSensorObject(sensor_id);
124 UpdateToicWithoutCameraMeasurement(sensor_id, measurement_timestamp,
131 if ((lidar_object !=
nullptr && lidar_object->GetSensorId() == sensor_id) ||
132 (camera_object_latest !=
nullptr &&
133 camera_object_latest->GetSensorId() == sensor_id) ||
134 (radar_object !=
nullptr && radar_object->GetSensorId() == sensor_id &&
135 lidar_object ==
nullptr && camera_object_latest ==
nullptr)) {
136 Dst existence_evidence(fused_existence_.
Name());
137 double unexist_factor = GetUnexistReliability(sensor_id);
139 double dist_decay = ComputeDistDecay(obj, sensor_id, measurement_timestamp);
140 double obj_unexist_prob = unexist_factor * dist_decay;
141 existence_evidence.
SetBba(
145 const double unexist_fused_w = 1.0;
146 double min_match_dist_score = min_match_dist;
152 <<
" min_match_dist: " << min_match_dist
153 <<
" min_match_dist_score: " << min_match_dist_score;
154 fused_existence_ = fused_existence_ + existence_evidence * unexist_fused_w *
155 (1 - min_match_dist_score);
157 <<
" 1 - match_dist_score: " << 1 - min_match_dist_score
158 <<
" sensor_id: " << sensor_id <<
" dist_decay: " << dist_decay
161 UpdateExistenceState();
165 const std::string &sensor_id,
167 double distance = std::numeric_limits<float>::max();
168 double dist_decay = 1.0;
169 Eigen::Affine3d sensor2world_pose;
170 bool status = SensorDataManager::Instance()->GetPose(sensor_id, timestamp,
173 AERROR <<
"Failed to get pose";
176 Eigen::Matrix4d world2sensor_pose = sensor2world_pose.matrix().inverse();
177 if (!world2sensor_pose.allFinite()) {
179 "The obtained camera pose is invalid. sensor_id : %s"
180 " timestamp %16.6f") %
181 sensor_id % timestamp;
184 Eigen::Vector3d obj_ct = obj->center;
185 Eigen::Vector3d obj_ct_local =
186 (world2sensor_pose * obj_ct.homogeneous()).head(3);
187 distance = std::sqrt(obj_ct_local.cwiseProduct(obj_ct_local).sum());
194double DstExistenceFusion::ComputeFeatureInfluence(
196 double velocity = measurement->GetBaseObject()->velocity.norm();
197 auto sigmoid_fun = [](
double velocity) {
198 return 1.0 / (1.0 + exp(-velocity));
200 double velocity_fact = sigmoid_fun(velocity);
201 velocity_fact = velocity > 4.0 ? velocity_fact : 0.0;
202 double confidence = measurement->GetBaseObject()->confidence;
203 ADEBUG <<
" sensor_id: " << measurement->GetSensorId()
204 <<
" velocity: " << velocity <<
" velocity_fact: " << velocity_fact
205 <<
" confidence: " << confidence;
206 return velocity_fact * confidence;
209double DstExistenceFusion::GetExistReliability(
214 double unknown_ratio = unknown ? 0.6 : 1.0;
215 algorithm::SensorManager *sensor_manager =
216 algorithm::SensorManager::Instance();
217 CHECK_NOTNULL(sensor_manager);
218 if (sensor_manager->IsCamera(measurement->GetSensorId())) {
219 return 0.8 * unknown_ratio;
221 if (sensor_manager->IsLidar(measurement->GetSensorId())) {
222 return 0.9 * unknown_ratio;
227double DstExistenceFusion::GetUnexistReliability(
const std::string &sensor_id) {
228 algorithm::SensorManager *sensor_manager =
229 algorithm::SensorManager::Instance();
230 CHECK_NOTNULL(sensor_manager);
231 if (sensor_manager->IsCamera(sensor_id)) {
234 if (sensor_manager->IsLidar(sensor_id)) {
240void DstExistenceFusion::UpdateToicWithoutCameraMeasurement(
241 const std::string &sensor_id,
double measurement_timestamp,
242 double min_match_dist) {
243 double dist_score = min_match_dist;
244 double in_view_ratio = 0.0;
246 SensorDataManager *sensor_manager = SensorDataManager::Instance();
247 ACHECK(sensor_manager !=
nullptr) <<
"Failed to get sensor manager";
250 sensor_manager->GetCameraIntrinsic(sensor_id);
251 ACHECK(camera_model !=
nullptr)
252 <<
"Failed to get camera intrinsic for " << sensor_id;
254 Eigen::Affine3d sensor2world_pose;
255 bool status = sensor_manager->GetPose(sensor_id, measurement_timestamp,
259 AWARN << boost::format(
260 "There is no pre-defined max valid camera"
261 " dist for sensor type: %s") %
267 double camera_max_dist = max_dist_it->second;
268 if (lidar_object !=
nullptr) {
270 lidar_object, camera_model, sensor2world_pose, measurement_timestamp,
271 camera_max_dist,
true,
false);
272 }
else if (radar_object !=
nullptr) {
274 radar_object, camera_model, sensor2world_pose, measurement_timestamp,
275 camera_max_dist,
false,
false);
279 Dst toic_evidence(fused_toic_.
Name());
283 const double toic_fused_w = 1.0;
284 fused_toic_ = fused_toic_ + toic_evidence * in_view_ratio * toic_fused_w;
287void DstExistenceFusion::UpdateToicWithCameraMeasurement(
289 std::string sensor_id = camera_obj->GetSensorId();
290 double timestamp = camera_obj->GetTimestamp();
291 double in_view_ratio = 0.0;
293 SensorDataManager *sensor_manager = SensorDataManager::Instance();
296 sensor_manager->GetCameraIntrinsic(sensor_id);
297 ACHECK(camera_model !=
nullptr)
298 <<
"Failed to get camera intrinsic for " << sensor_id;
300 Eigen::Affine3d sensor2world_pose;
302 sensor_manager->GetPose(sensor_id, timestamp, &sensor2world_pose);
305 AWARN << boost::format(
306 "There is no pre-defined max valid camera"
307 " dist for sensor type: %s") %
310 ADEBUG <<
"camera dist: " << sensor_id <<
" " << max_dist_it->second;
315 double camera_max_dist = max_dist_it->second;
316 if (lidar_object !=
nullptr) {
319 timestamp, camera_max_dist,
true,
false);
320 }
else if (radar_object !=
nullptr) {
323 timestamp, camera_max_dist,
false,
false);
328 double association_prob = 1 - match_dist / max_match_distance;
330 Dst toic_evidence(fused_toic_.
Name());
334 const double toic_fused_w = 0.7;
335 fused_toic_ = fused_toic_ + toic_evidence * toic_fused_w * in_view_ratio;
344 const std::vector<double> &existence_probs_vec =
346 return existence_probs_vec[toic_ind];
349double DstExistenceFusion::GetToicProbability()
const {
354 return toic_probs_vec[toic_ind];
357void DstExistenceFusion::UpdateExistenceState() {
358 double toic_p = GetToicProbability();
363 auto scale_probability = [](
double p,
double max_p,
double min_p) {
365 p = 0.5 + (p - 0.5) * (max_p - 0.5) / 0.5;
367 p = 0.5 - (0.5 - p) * (0.5 - min_p) / 0.5;
372 const double max_p = 0.8;
373 const double min_p = 0.2;
374 double toic_score = scale_probability(toic_p, max_p, min_p);
380 if (!(
track_ref_->GetLidarObjects()).empty()) {
382 }
else if (!
track_ref_->GetRadarObjects().empty()) {
383 toic_score_ = toic_score;
384 }
else if (!
track_ref_->GetCameraObjects().empty()) {
387 AERROR << boost::format(
"this fused object: %d has no sensor objects") %
void UpdateWithMeasurement(const SensorObjectPtr measurement, double target_timestamp, double match_dist) override
update track existence state with measurement
double GetExistenceProbability() const
Get existence probability
static bool Init(const ExistenceFusionInitOptions &options)
add dst application
void UpdateWithoutMeasurement(const std::string &sensor_id, double measurement_timestamp, double target_timestamp, double min_match_dist) override
update track state without measurement
DstExistenceFusion(TrackPtr track)
bool IsAppAdded(const std::string &app_name)
Whether app added
size_t FodSubsetToInd(const std::string &app_name, const uint64_t &fod_subset)
static DstManager * Instance()
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 >())
const std::vector< double > & GetProbabilityVec() const
Get the Probability Vec object
void ComputeProbability() const
bool SetBba(const std::map< uint64_t, double > &bba_map)
Set the Bba object, strictly require the fod in bba_map is valid
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,...
std::string GetAbsolutePath(const std::string &prefix, const std::string &relative_path)
Get absolute path by concatenating prefix and relative_path.
std::shared_ptr< BaseCameraModel > BaseCameraModelPtr
std::shared_ptr< const Object > ObjectConstPtr
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
bool IsRadar(const SensorObjectConstPtr &obj)
std::string GetConfigFile(const std::string &config_path, const std::string &config_file)
repeated CameraValidDist camera_valid_dist
optional double track_object_max_match_distance
std::map< std::string, double > camera_max_valid_dist_
double track_object_max_match_distance_
std::vector< uint64_t > fod_subsets_
std::vector< std::string > subset_names_
std::vector< uint64_t > fod_subsets_
std::vector< std::string > subset_names_