21#include "modules/perception/multi_sensor_fusion/proto/probabilistic_fusion_config.pb.h"
42 std::string config_file =
46 AERROR <<
"Read config failed: " << config_file;
53 for (
int i = 0; i < params.prohibition_sensors_size(); ++i) {
63 scenes_.reset(
new Scene());
68 association_init_options.
config_path = data_association_param.config_path();
69 association_init_options.
config_file = data_association_param.config_file();
71 BaseDataAssociationRegisterer::GetInstanceByName(
72 data_association_param.name());
73 CHECK_NOTNULL(matcher);
74 matcher_.reset(matcher);
75 ACHECK(matcher_->Init(association_init_options))
76 <<
"Fusion matcher init error";
81 gatekeeper_init_options.
config_path = gatekeeper_param.config_path();
82 gatekeeper_init_options.
config_file = gatekeeper_param.config_file();
84 BaseGatekeeperRegisterer::GetInstanceByName(gatekeeper_param.name());
85 CHECK_NOTNULL(gate_keeper);
86 gate_keeper_.reset(gate_keeper);
87 ACHECK(gate_keeper_->Init(gatekeeper_init_options))
88 <<
"Fusion gate_keeper init error";
95 tracker_init_options.
config_path = tracker_param.config_path();
96 tracker_init_options.
config_file = tracker_param.config_file();
103 std::vector<base::ObjectPtr>* fused_objects) {
104 if (fused_objects ==
nullptr) {
105 AERROR <<
"fusion error: fused_objects is nullptr";
109 auto* sensor_data_manager = SensorDataManager::Instance();
112 std::lock_guard<std::mutex> data_lock(data_mutex_);
113 if (!params_.
use_lidar && sensor_data_manager->IsLidar(sensor_frame)) {
116 if (!params_.
use_radar && sensor_data_manager->IsRadar(sensor_frame)) {
119 if (!params_.
use_camera && sensor_data_manager->IsCamera(sensor_frame)) {
123 bool is_publish_sensor = IsPublishSensor(sensor_frame);
125 AINFO <<
"add sensor measurement: " << sensor_frame->sensor_info.name
126 <<
", obj_cnt : " << sensor_frame->objects.size() <<
", "
128 sensor_data_manager->AddSensorMeasurements(sensor_frame);
130 if (!is_publish_sensor) {
136 std::lock_guard<std::mutex> fuse_lock(fuse_mutex_);
137 double fusion_time = sensor_frame->timestamp;
138 std::vector<SensorFramePtr> frames;
139 sensor_data_manager->GetLatestFrames(fusion_time, &frames);
140 AINFO <<
"Get " << frames.size() <<
" related frames for fusion";
143 for (
const auto& frame : frames) {
148 CollectFusedObjects(fusion_time, fused_objects);
152bool ProbabilisticFusion::IsPublishSensor(
154 std::string sensor_id = sensor_frame->sensor_info.name;
155 bool is_main_sensor =
156 algorithm::SensorManager::Instance()->IsMainSensor(sensor_id);
157 return is_main_sensor;
161 AINFO <<
"Fusing frame: " << frame->GetSensorId()
162 <<
", foreground_object_number: "
163 << frame->GetForegroundObjects().size()
164 <<
", background_object_number: "
165 << frame->GetBackgroundObjects().size()
167 FuseForegroundTrack(frame);
168 FusebackgroundTrack(frame);
172void ProbabilisticFusion::FuseForegroundTrack(
const SensorFramePtr& frame) {
173 AssociationOptions options;
174 AssociationResult association_result;
175 matcher_->Associate(options, frame, scenes_, &association_result);
177 const std::vector<TrackMeasurmentPair>& assignments =
178 association_result.assignments;
179 UpdateAssignedTracks(frame, assignments);
181 const std::vector<size_t>& unassigned_track_inds =
182 association_result.unassigned_tracks;
183 UpdateUnassignedTracks(frame, unassigned_track_inds);
185 const std::vector<size_t>& unassigned_obj_inds =
186 association_result.unassigned_measurements;
187 CreateNewTracks(frame, unassigned_obj_inds);
190void ProbabilisticFusion::UpdateAssignedTracks(
192 const std::vector<TrackMeasurmentPair>& assignments) {
197 TrackerOptions options;
198 options.match_distance = 0;
199 std::vector<SensorObjectPtr>& f_ground_objs = frame->GetForegroundObjects();
200 for (
size_t i = 0; i < assignments.size(); ++i) {
201 size_t track_ind = assignments[i].first;
202 size_t obj_ind = assignments[i].second;
203 trackers_[track_ind]->UpdateWithMeasurement(options, f_ground_objs[obj_ind],
204 frame->GetTimestamp());
208void ProbabilisticFusion::UpdateUnassignedTracks(
210 const std::vector<size_t>& unassigned_track_inds) {
216 TrackerOptions options;
217 options.match_distance = 0;
218 std::string sensor_id = frame->GetSensorId();
219 for (
size_t i = 0; i < unassigned_track_inds.size(); ++i) {
220 size_t track_ind = unassigned_track_inds[i];
221 trackers_[track_ind]->UpdateWithoutMeasurement(
222 options, sensor_id, frame->GetTimestamp(), frame->GetTimestamp());
226void ProbabilisticFusion::CreateNewTracks(
228 const std::vector<size_t>& unassigned_obj_inds) {
230 bool prohibition_sensor_flag =
false;
233 [&](
const std::string& sensor_name) {
234 if (sensor_name == frame->GetSensorId())
235 prohibition_sensor_flag = true;
237 if (prohibition_sensor_flag) {
242 std::vector<SensorObjectPtr>& f_ground_objs = frame->GetForegroundObjects();
243 for (
const size_t& obj_ind : unassigned_obj_inds) {
245 track->Initialize(f_ground_objs[obj_ind]);
246 scenes_->AddForegroundTrack(track);
248 ADEBUG <<
"object id: " << f_ground_objs[obj_ind]->GetBaseObject()->track_id
249 <<
", create new track: " << track->GetTrackId();
252 std::shared_ptr<BaseTracker> tracker;
253 tracker.reset(
new PbfTracker());
254 tracker->Init(track, f_ground_objs[obj_ind]);
255 trackers_.emplace_back(tracker);
260void ProbabilisticFusion::FusebackgroundTrack(
const SensorFramePtr& frame) {
262 size_t track_size = scenes_->GetBackgroundTracks().size();
263 size_t obj_size = frame->GetBackgroundObjects().size();
264 std::map<int, size_t> local_id_2_track_ind_map;
265 std::vector<bool> track_tag(track_size,
false);
266 std::vector<bool> object_tag(obj_size,
false);
268 std::vector<TrackPtr>& background_tracks = scenes_->GetBackgroundTracks();
269 for (
size_t i = 0; i < track_size; ++i) {
270 const FusedObjectPtr& obj = background_tracks[i]->GetFusedObject();
271 int local_id = obj->GetBaseObject()->track_id;
272 local_id_2_track_ind_map[local_id] = i;
275 std::vector<TrackMeasurmentPair> assignments;
276 std::vector<SensorObjectPtr>& frame_objs = frame->GetBackgroundObjects();
277 for (
size_t i = 0; i < obj_size; ++i) {
278 int local_id = frame_objs[i]->GetBaseObject()->track_id;
279 const auto& it = local_id_2_track_ind_map.find(local_id);
280 if (it != local_id_2_track_ind_map.end()) {
281 size_t track_ind = it->second;
282 assignments.push_back(std::make_pair(track_ind, i));
283 track_tag[track_ind] =
true;
284 object_tag[i] =
true;
289 for (
size_t i = 0; i < assignments.size(); ++i) {
290 size_t track_ind = assignments[i].first;
291 size_t obj_ind = assignments[i].second;
292 background_tracks[track_ind]->UpdateWithSensorObject(frame_objs[obj_ind]);
296 std::string sensor_id = frame->GetSensorId();
297 for (
size_t i = 0; i < track_tag.size(); ++i) {
299 background_tracks[i]->UpdateWithoutSensorObject(sensor_id,
300 frame->GetTimestamp());
305 for (
size_t i = 0; i < object_tag.size(); ++i) {
306 if (!object_tag[i]) {
308 track->Initialize(frame_objs[i],
true);
309 scenes_->AddBackgroundTrack(track);
314void ProbabilisticFusion::RemoveLostTrack() {
316 size_t f_alive_index = 0;
317 std::vector<TrackPtr>& foreground_tracks = scenes_->GetForegroundTracks();
318 for (
size_t i = 0; i < foreground_tracks.size(); ++i) {
319 if (foreground_tracks[i]->IsAlive()) {
320 foreground_tracks[f_alive_index] = foreground_tracks[i];
321 trackers_[f_alive_index] = trackers_[i];
325 AINFO <<
"Remove " << foreground_tracks.size() - f_alive_index
326 <<
" foreground tracks. " << f_alive_index <<
" tracks left.";
327 foreground_tracks.resize(f_alive_index);
328 trackers_.resize(f_alive_index);
331 size_t b_alive_index = 0;
332 std::vector<TrackPtr>& background_tracks = scenes_->GetBackgroundTracks();
333 for (
size_t i = 0; i < background_tracks.size(); ++i) {
334 if (background_tracks[i]->IsAlive()) {
335 background_tracks[b_alive_index] = background_tracks[i];
339 AINFO <<
"Remove " << background_tracks.size() - b_alive_index
340 <<
" background tracks";
341 background_tracks.resize(b_alive_index);
344void ProbabilisticFusion::CollectFusedObjects(
345 double timestamp, std::vector<base::ObjectPtr>* fused_objects) {
346 CHECK_NOTNULL(fused_objects);
347 fused_objects->clear();
349 size_t fg_obj_num = 0;
350 const std::vector<TrackPtr>& foreground_tracks =
351 scenes_->GetForegroundTracks();
352 for (
const auto& track_ptr : foreground_tracks) {
353 if (gate_keeper_->AbleToPublish(track_ptr)) {
354 CollectObjectsByTrack(timestamp, track_ptr, fused_objects);
359 size_t bg_obj_num = 0;
360 const std::vector<TrackPtr>& background_tracks =
361 scenes_->GetBackgroundTracks();
362 for (
const auto& track_ptr : background_tracks) {
363 if (gate_keeper_->AbleToPublish(track_ptr)) {
364 CollectObjectsByTrack(timestamp, track_ptr, fused_objects);
369 AINFO <<
"collect objects : fg_obj_cnt = " << fg_obj_num
370 <<
", bg_obj_cnt = " << bg_obj_num
374void ProbabilisticFusion::CollectObjectsByTrack(
375 double timestamp,
const TrackPtr& track,
376 std::vector<base::ObjectPtr>* fused_objects) {
377 CHECK_NOTNULL(track);
380 *obj = *(fused_object->GetBaseObject());
387 size_t num_measurements = lidar_measurements.size() +
388 camera_measurements.size() +
389 radar_measurements.size();
390 obj->fusion_supplement.on_use =
true;
391 auto& measurements = obj->fusion_supplement.measurements;
392 measurements.resize(num_measurements);
396 for (
const auto& iter : lidar_measurements) {
397 CollectSensorMeasurementFromObject(iter.second, &measurements[m_index++]);
399 for (
const auto& iter : camera_measurements) {
400 CollectSensorMeasurementFromObject(iter.second, &measurements[m_index++]);
402 for (
const auto& iter : radar_measurements) {
403 CollectSensorMeasurementFromObject(iter.second, &measurements[m_index++]);
407 obj->track_id = track->GetTrackId();
409 obj->tracking_time = track->GetTrackingPeriod();
410 fused_objects->emplace_back(obj);
412 ADEBUG <<
"fusion_reporting..." << obj->track_id <<
"@"
414 << obj->center(0) <<
"," << obj->center(1) <<
","
415 << obj->center_uncertainty(0, 0) <<
","
416 << obj->center_uncertainty(0, 1) <<
","
417 << obj->center_uncertainty(1, 0) <<
","
418 << obj->center_uncertainty(1, 1) <<
"," << obj->velocity(0) <<
","
419 << obj->velocity(1) <<
"," << obj->velocity_uncertainty(0, 0) <<
","
420 << obj->velocity_uncertainty(0, 1) <<
","
421 << obj->velocity_uncertainty(1, 0) <<
","
422 << obj->velocity_uncertainty(1, 1) <<
")";
425void ProbabilisticFusion::CollectSensorMeasurementFromObject(
427 base::SensorObjectMeasurement* measurement) {
428 CHECK_NOTNULL(
object);
429 CHECK_NOTNULL(measurement);
430 measurement->sensor_id =
object->GetSensorId();
431 measurement->timestamp =
object->GetTimestamp();
432 measurement->track_id =
object->GetBaseObject()->track_id;
433 measurement->center =
object->GetBaseObject()->center;
434 measurement->theta =
object->GetBaseObject()->theta;
435 measurement->size =
object->GetBaseObject()->size;
436 measurement->velocity =
object->GetBaseObject()->velocity;
437 measurement->type =
object->GetBaseObject()->type;
439 measurement->box =
object->GetBaseObject()->camera_supplement.box;
#define FUSION_REGISTER_FUSIONSYSTEM(name)
static ConcurrentObjectPool & Instance()
std::shared_ptr< ObjectType > Get() override
static bool InitParams(const TrackerInitOptions &options)
Init params
bool Init(const FusionInitOptions &options) override
Initialization
bool Fuse(const base::FrameConstPtr &sensor_frame, std::vector< base::ObjectPtr > *fused_objects) override
Probabilistic fusion of sensor data, the input is the detection results of different sensors,...
static void SetMaxCachedFrameNumber(size_t number)
static void SetMaxRadarInvisiblePeriod(double period)
Set the max radar invisible period
static void SetMaxCameraInvisiblePeriod(double period)
Set the max camera invisible period
static void SetMaxLidarInvisiblePeriod(double period)
Set the max lidar invisible period
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< Object > ObjectPtr
std::shared_ptr< const Frame > FrameConstPtr
std::shared_ptr< const SensorObject > SensorObjectConstPtr
bool IsCamera(const SensorObjectConstPtr &obj)
std::shared_ptr< SensorFrame > SensorFramePtr
std::shared_ptr< Track > TrackPtr
std::shared_ptr< FusedObject > FusedObjectPtr
std::map< std::string, SensorObjectPtr > SensorId2ObjectMap
std::string GetConfigFile(const std::string &config_path, const std::string &config_file)
Some string util functions.
#define FORMAT_TIMESTAMP(timestamp)
std::string tracker_method
std::vector< std::string > prohibition_sensors
optional double max_radar_invisible_period
optional perception::PluginParam gatekeeper_param
optional perception::PluginParam tracker_param
repeated string prohibition_sensors
optional int64 max_cached_frame_num
optional double max_lidar_invisible_period
optional double max_camera_invisible_period
optional perception::PluginParam data_association_param