21#include <boost/format.hpp>
23#include "absl/strings/str_cat.h"
24#include "absl/strings/str_join.h"
26#include "modules/perception/multi_sensor_fusion/proto/dst_type_fusion_config.pb.h"
40template <
typename Type>
42 return absl::StrCat(
"(", absl::StrJoin(values,
" "),
")");
45std::string DstTypeFusion::name_ =
"DstTypeFusion";
46DstMaps DstTypeFusion::dst_maps_;
47DstTypeFusionOptions DstTypeFusion::options_;
51 Dst sensor_dst(name_);
53 TypeProbsToDst(track->GetFusedObject()->GetBaseObject()->type_probs);
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";
65 fused_dst_ + sensor_dst * GetReliability(sensor_obj->GetSensorId());
70 std::string config_file =
75 AERROR <<
"Read config failed: " << config_file;
80 std::string camera_id = camera_param.name();
84 camera_param.reliability_for_unknown();
85 AINFO <<
"dst type fusion params: " << camera_id
88 <<
" reliability for unknown: "
93 std::string lidar_id = lidar_param.name();
96 lidar_param.reliability_for_unknown();
97 AINFO <<
"dst type fusion params: " << lidar_id
99 <<
" reliability for unknown: "
112 double target_timestamp) {
113 Dst measurement_dst(name_);
114 measurement_dst = TypeProbsToDst(measurement->GetBaseObject()->type_probs);
116 << vector2string<float>(measurement->GetBaseObject()->type_probs);
118 fused_dst_ + measurement_dst * GetReliability(measurement->GetSensorId());
119 ADEBUG <<
"reliability: " << GetReliability(measurement->GetSensorId());
122 track_ref_->GetFusedObject()->GetBaseObject()->sub_type =
123 measurement->GetBaseObject()->sub_type;
129 double measurement_timestamp,
130 double target_timestamp,
131 double min_match_dist) {
133 algorithm::SensorManager::Instance();
134 if (sensor_manager->
IsCamera(sensor_id)) {
136 double in_view_ratio = 0.0;
141 ACHECK(camera_model !=
nullptr)
142 <<
"Failed to get camera intrinsic for " << sensor_id;
144 Eigen::Affine3d sensor2world_pose;
145 bool status = sensor_data_manager->
GetPose(sensor_id, measurement_timestamp,
149 AWARN << boost::format(
150 "There is no pre-defined max valid camera"
151 " dist for sensor type: %s") %
157 double camera_max_dist = max_dist_it->second;
158 if (lidar_object !=
nullptr) {
160 lidar_object, camera_model, sensor2world_pose,
161 measurement_timestamp, camera_max_dist,
true,
false);
162 }
else if (radar_object !=
nullptr) {
164 radar_object, camera_model, sensor2world_pose,
165 measurement_timestamp, camera_max_dist,
false,
false);
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) {
181 double res = 1 - (dist_score / th) * (dist_score / th);
184 double occlusion_score = loss_fun(min_match_dist);
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);
198bool DstTypeFusion::TypToHyp(
size_t object_type,
199 uint64_t *hypothesis_type)
const {
204 *hypothesis_type = find_res->second;
208bool DstTypeFusion::HypToTyp(uint64_t hypothesis_type,
209 size_t *object_type)
const {
214 *object_type = find_res->second;
218Dst DstTypeFusion::TypeProbsToDst(
const std::vector<float> &type_probs) {
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()) {
231 std::map<uint64_t, double> res_bba_map;
232 for (
size_t i = 0; i < type_probs.size(); ++i) {
235 if (!TypToHyp(typ, &hyp)) {
238 res_bba_map[hyp] = type_probs[typ];
249 ACHECK(res_dst.SetBba(res_bba_map));
253double DstTypeFusion::GetReliability(
const std::string &sensor_id)
const {
256 ADEBUG <<
"the sensor type: " << sensor_id
257 <<
" is not supported by class fusion";
260 return find_res->second;
263double DstTypeFusion::GetReliabilityForUnKnown(
264 const std::string &sensor_id,
double measurement_timestamp)
const {
267 ADEBUG <<
"the sensor type: " << sensor_id
268 <<
" is not supported by class fusion";
271 time_t rawtime =
static_cast<time_t
>(measurement_timestamp);
273 localtime_r(&rawtime, &timeinfo);
274 bool is_night = (timeinfo.tm_hour >= 17);
276 (algorithm::SensorManager::Instance()->IsCamera(sensor_id) && is_night)
279 return find_res->second * prob;
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();
292 size_t object_type = 0;
293 HypToTyp(max_hyp, &object_type);
294 track_ref_->GetFusedObject()->GetBaseObject()->type =
298 track_ref_->GetFusedObject()->GetBaseObject()->sub_type);
300 type->second !=
track_ref_->GetFusedObject()->GetBaseObject()->type) {
301 track_ref_->GetFusedObject()->GetBaseObject()->sub_type =
306 std::vector<float> type_probs(
308 for (
size_t i = 0; i < fused_dst_vec.size(); ++i) {
311 HypToTyp(hyp, &type);
312 type_probs[type] +=
static_cast<float>(fused_dst_vec[i]);
314 track_ref_->GetFusedObject()->GetBaseObject()->type_probs = type_probs;
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
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 >())
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
DstTypeFusion(TrackPtr track)
std::string PrintBba() const
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
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
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
std::string vector2string(const std::vector< Type > &values)
std::string GetConfigFile(const std::string &config_path, const std::string &config_file)
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_
repeated LidarDstTypeFusionParam lidar_params
repeated CameraDstTypeFusionParam camera_params
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