Apollo 10.0
自动驾驶开放平台
mlf_engine.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 *****************************************************************************/
16
18
19#include <utility>
20
21#include "Eigen/Geometry"
22
23#include "modules/perception/lidar_tracking/tracker/multi_lidar_fusion/proto/multi_lidar_fusion_config.pb.h"
24
25#include "cyber/common/file.h"
31
32namespace apollo {
33namespace perception {
34namespace lidar {
35
42
44 std::string config_file =
45 GetConfigFile(options.config_path, options.config_file);
46 MlfEngineConfig config;
47 ACHECK(cyber::common::GetProtoFromFile(config_file, &config));
48
49 Clear();
50
60
62 MlfTrackObjectMatcherInitOptions matcher_init_options;
63 matcher_init_options.config_path = options.config_path;
64 ACHECK(matcher_->Init(matcher_init_options));
65
66 tracker_.reset(new MlfTracker);
67 MlfTrackerInitOptions tracker_init_options;
68 tracker_init_options.config_path = options.config_path;
69 ACHECK(tracker_->Init(tracker_init_options));
70 return true;
71}
72
74 LidarFrame* frame) {
75 // 0. modify objects timestamp if necessary
77 for (auto& object : frame->segmented_objects) {
78 object->latest_tracked_time = frame->timestamp;
79 }
80 }
81 if (print_debug_log_) {
82 ObjectsDebugInfo(frame, true);
83 ObjectsDebugInfo(frame, false);
84 }
85 // 1. add global offset to pose (only when no track exists)
86 if (foreground_track_data_.empty() && background_track_data_.empty()) {
87 global_to_local_offset_ = -frame->lidar2world_pose.translation();
88 }
91 // 2. split fg and bg objects, and transform to tracked objects
93 frame->sensor_info, frame->timestamp);
94 // 3. assign tracked objects to tracks
95 MlfTrackObjectMatcherOptions match_options;
96 TrackObjectMatchAndAssign(match_options, foreground_objects_, "foreground",
98 TrackObjectMatchAndAssign(match_options, background_objects_, "background",
100 // 4. state filter in tracker if is main sensor
101 bool is_main_sensor = algorithm::SensorManager::Instance()->IsMainSensor(
102 frame->sensor_info.name);
103 if (is_main_sensor) {
106 }
107 // 5. track to object if is main sensor
108 if (print_debug_log_) {
109 TrackDebugInfo(frame);
110 }
111 frame->tracked_objects.clear();
112 if (is_main_sensor) {
114 }
115 // 6. remove stale data
118
119 // Startegy: Set velocity and acceleration to ZERO outside hdmap_struct
120 // temporarily located here, best is in mlf_motion_refiner.cc
121 auto roi = frame->hdmap_struct;
122 if (!set_static_outside_hdmap_ || roi == nullptr ||
123 (roi->road_polygons.empty() && roi->junction_polygons.empty() &&
124 roi->road_boundary.empty())) {
125 AINFO << "MlfEngine publish objects: " << frame->tracked_objects.size()
126 << " sensor_name: " << frame->sensor_info.name
127 << " at timestamp: " << frame->timestamp;
128 return true;
129 }
130 std::stringstream sstr;
131 sstr << "Object Outside Hdmap. Set velocity to zero. track_id: ";
132 for (auto obj : frame->tracked_objects) {
133 if (algorithm::IsObjectInRoi(roi, obj)) {
134 continue;
135 }
136 obj->velocity = Eigen::Vector3f::Zero();
137 obj->acceleration = Eigen::Vector3f::Zero();
138 sstr << obj->track_id << ", ";
139 }
140 AINFO << sstr.str();
141
142 AINFO << "MlfEngine publish objects: " << frame->tracked_objects.size()
143 << " sensor_name: " << frame->sensor_info.name
144 << " at timestamp: " << frame->timestamp;
145 return true;
146}
147
149 const std::vector<base::ObjectPtr>& objects,
150 const base::SensorInfo& sensor_info, double frame_timestamp) {
151 std::vector<TrackedObjectPtr> tracked_objects;
152 TrackedObjectPool::Instance().BatchGet(objects.size(), &tracked_objects);
153 foreground_objects_.clear();
154 background_objects_.clear();
155 for (size_t i = 0; i < objects.size(); ++i) {
156 double tracked_time = objects[i]->latest_tracked_time;
157 double timestamp = use_frame_timestamp_ ? frame_timestamp : tracked_time;
158 tracked_objects[i]->AttachObject(objects[i], sensor_to_local_pose_,
159 global_to_local_offset_, sensor_info, timestamp);
160 if (!objects[i]->lidar_supplement.is_background &&
162 tracked_objects[i]->histogram_bin_size = histogram_bin_size_;
163 tracked_objects[i]->ComputeShapeFeatures();
164 }
165 if (objects[i]->lidar_supplement.is_background) {
166 background_objects_.push_back(tracked_objects[i]);
167 } else {
168 foreground_objects_.push_back(tracked_objects[i]);
169 }
170 }
171 AINFO << "MlfEngine: " << sensor_info.name
172 << " foreground: " << foreground_objects_.size()
173 << " background: " << background_objects_.size();
174}
175
177 const MlfTrackObjectMatcherOptions& match_options,
178 const std::vector<TrackedObjectPtr>& objects, const std::string& name,
179 std::vector<MlfTrackDataPtr>* tracks) {
180 std::vector<std::pair<size_t, size_t>> assignments;
181 std::vector<size_t> unassigned_tracks;
182 std::vector<size_t> unassigned_objects;
183 matcher_->Match(match_options, objects, *tracks, &assignments,
184 &unassigned_tracks, &unassigned_objects);
185 AINFO << "MlfEngine: " + name + " assignments " << assignments.size()
186 << " unassigned_tracks " << unassigned_tracks.size()
187 << " unassigned_objects " << unassigned_objects.size();
188 // 1. for assignment, push object to cache of track_data
189 for (auto& pair : assignments) {
190 const size_t track_id = pair.first;
191 const size_t object_id = pair.second;
192 tracks->at(track_id)->PushTrackedObjectToCache(objects[object_id]);
193 }
194 // 2. for unassigned_objects, create new tracks
195 for (auto& id : unassigned_objects) {
197 tracker_->InitializeTrack(track_data, objects[id]);
198 tracks->push_back(track_data);
199 }
200}
201
202void MlfEngine::TrackStateFilter(const std::vector<MlfTrackDataPtr>& tracks,
203 double frame_timestamp) {
204 std::vector<TrackedObjectPtr> objects;
205 for (auto& track_data : tracks) {
206 track_data->GetAndCleanCachedObjectsInTimeInterval(&objects);
207 for (auto& obj : objects) {
208 tracker_->UpdateTrackDataWithObject(track_data, obj);
209 }
210 if (objects.empty()) {
211 tracker_->UpdateTrackDataWithoutObject(frame_timestamp, track_data);
212 }
213 }
214}
215
217 auto& tracked_objects = frame->tracked_objects;
218 tracked_objects.clear();
219 size_t num_objects =
221 base::ObjectPool::Instance().BatchGet(num_objects, &tracked_objects);
222 size_t pos = 0;
223 size_t num_predict = 0;
224 size_t num_delay_output = 0;
225 size_t num_front_critical_reserve = 0;
226 size_t num_blind_trafficcone = 0;
227 auto collect = [&](std::vector<MlfTrackDataPtr>* tracks) {
228 for (auto& track_data : *tracks) {
229 // if (!output_predict_objects_ &&
230 // track_data->is_current_state_predicted_) {
231 // ++num_predict;
232 // } else {
233 // if (!track_data->ToObject(-global_to_local_offset_,
234 // frame->timestamp, tracked_objects[pos], true)) {
235 // AERROR << "Tracking failed";
236 // continue;
237 // }
238 // ++pos;
239 // }
240 if (track_data->age_ <= pub_track_times_) {
241 if (track_data->is_front_critical_track_) {
242 ADEBUG << "[DelayOutput] track_id: " << track_data->track_id_
243 << " time is " << std::to_string(frame->timestamp)
244 << " not output";
245 }
246 ++num_delay_output;
247 continue;
248 }
249 track_data->is_reserve_blind_cone_ = false;
250 // == false -> OUTPUT
251 if (!track_data->is_current_state_predicted_) {
252 if (!track_data->ToObject(-global_to_local_offset_,
253 frame->timestamp, tracked_objects[pos], true)) {
254 AERROR << "Tracking failed";
255 continue;
256 }
257 ++pos;
258 ADEBUG << "track_id: " << track_data->track_id_
259 << " detetcted, obj-time is "
260 << std::to_string(frame->timestamp) << " and output";
261 continue;
262 } else {
263 // == true: output_predict_objects_ == true -> OUTPUT
265 if (!track_data->ToObject(-global_to_local_offset_,
266 frame->timestamp, tracked_objects[pos], true)) {
267 AERROR << "Tracking failed";
268 continue;
269 }
270 ++pos;
271 continue;
272 } else {
273 // output_predict_objects_ == false
274 // should judge front-critical and time
275 TrackedObjectConstPtr latest_object =
276 track_data->GetLatestObject().second;
277 // front-critical and within time -> OUTPUT
278 if (latest_object != nullptr &&
279 track_data->is_front_critical_track_ &&
280 latest_object->output_velocity.head<2>().norm() < 0.01 &&
281 frame->timestamp -
282 track_data->GetLatestObject().first <= delay_output_) {
283 ++num_front_critical_reserve;
284 AINFO << "track_id: " << track_data->track_id_
285 << " missed, obj-time is "
286 << std::to_string(track_data->GetLatestObject().first)
287 << " and predict output";
288 if (!track_data->ToObject(-global_to_local_offset_,
289 frame->timestamp, tracked_objects[pos], false)) {
290 AERROR << "Tracking failed";
291 continue;
292 }
293 ++pos;
294 continue;
295 } else if (JudgeBlindTrafficCone(track_data, frame->timestamp,
297 frame->lidar2novatel_extrinsics)) {
298 ++num_blind_trafficcone;
299 if (!track_data->ToObject(-global_to_local_offset_,
300 frame->timestamp, tracked_objects[pos], false)) {
301 AERROR << "Tracking failed";
302 continue;
303 }
304 track_data->is_reserve_blind_cone_ = true;
305 ++pos;
306 continue;
307 } else {
308 // NO front-critical or beyond time -> NO OUTPUT
309 ++num_predict;
310 continue;
311 }
312 }
313 }
314 }
315 };
316 collect(&foreground_track_data_);
317 collect(&background_track_data_);
318 AINFO << "MlfEngine, num_predict: " << num_predict
319 << " num delay_output: " << num_delay_output
320 << " num front_critical: " << num_front_critical_reserve
321 << " num blind trafficcone: " << num_blind_trafficcone
322 << " num_objects: " << num_objects;
323 if (num_predict > num_objects) {
324 AERROR << "num_predict > num_objects";
325 return;
326 }
327 tracked_objects.resize(num_objects - num_predict - num_delay_output);
328}
329
330void MlfEngine::RemoveStaleTrackData(const std::string& name, double timestamp,
331 std::vector<MlfTrackDataPtr>* tracks) {
332 size_t pos = 0;
333 for (size_t i = 0; i < tracks->size(); ++i) {
334 float reserve_time = reserved_invisible_time_;
335 if (tracks->at(i)->is_front_critical_track_ &&
337 reserve_time = delay_output_;
338 }
339 if (tracks->at(i)->latest_visible_time_ + reserve_time >= timestamp ||
340 tracks->at(i)->is_reserve_blind_cone_) {
341 if (i != pos) {
342 tracks->at(pos) = tracks->at(i);
343 }
344 ++pos;
345 }
346 }
347 AINFO << "MlfEngine: " << name << " remove stale tracks, from "
348 << tracks->size() << " to " << pos;
349 tracks->resize(pos);
350}
351
352void MlfEngine::ObjectsDebugInfo(LidarFrame* frame, bool foreground_log) {
353 size_t objcnt = 0;
354 for (auto obj : frame->segmented_objects) {
355 if (foreground_log && !obj->lidar_supplement.is_background) {
356 objcnt++;
357 }
358 if (!foreground_log && obj->lidar_supplement.is_background) {
359 objcnt++;
360 }
361 }
362 std::stringstream ssstr;
363 if (foreground_log) {
364 ssstr << "[Foreground-objects] timestamp: "
365 << std::to_string(frame->timestamp) << " objs: " << objcnt
366 << std::endl;
367 } else {
368 ssstr << "[Background-objects] timestamp: "
369 << std::to_string(frame->timestamp) << " objs: " << objcnt
370 << std::endl;
371 }
372 for (auto obj : frame->segmented_objects) {
373 if (foreground_log && obj->lidar_supplement.is_background) {
374 continue;
375 }
376 if (!foreground_log && !obj->lidar_supplement.is_background) {
377 continue;
378 }
379 ssstr << "id = " << obj->id << ": " << obj->center(0) << ", "
380 << obj->center(1) << ", " << obj->center(2) << ", "
381 << obj->size(0) << ", " << obj->size(1) << ", "
382 << obj->size(2) << ", " << obj->theta << ", "
383 << static_cast<int>(obj->type) << std::endl;
384 }
385 AINFO << ssstr.str();
386}
387
389 std::stringstream sstr;
390 sstr << "[This frame TrackDataDebugInfo]: timestamp: "
391 << std::to_string(frame->timestamp) << " tracks: "
392 << foreground_track_data_.size() << std::endl;
393 sstr << "lidar2world_pose: " << sensor_to_local_pose_(0, 0) << ", "
394 << sensor_to_local_pose_(0, 1) << ", " << sensor_to_local_pose_(0, 2)
395 << ", " << sensor_to_local_pose_(0, 3) << ", "
396 << sensor_to_local_pose_(1, 0) << ", " << sensor_to_local_pose_(1, 1)
397 << ", " << sensor_to_local_pose_(1, 2) << ", "
398 << sensor_to_local_pose_(1, 3) << ", " << sensor_to_local_pose_(2, 0)
399 << ", " << sensor_to_local_pose_(2, 1) << ", "
400 << sensor_to_local_pose_(2, 2) << ", " << sensor_to_local_pose_(2, 3)
401 << ", "<< sensor_to_local_pose_(3, 0) << ", "
402 << sensor_to_local_pose_(3, 1) << ", " << sensor_to_local_pose_(3, 2)
403 << ", " << sensor_to_local_pose_(3, 3) << ", "
404 << std::to_string(global_to_local_offset_(0)) << ", "
405 << std::to_string(global_to_local_offset_(1)) << ", "
406 << std::to_string(global_to_local_offset_(2)) << std::endl;
407
408 auto debug_info = [&](std::vector<MlfTrackDataPtr>* tracks) {
409 for (auto& track_data : *tracks) {
410 const TrackedObjectConstPtr latest_obj =
411 track_data->GetLatestObject().second;
412 sstr << " track_id = " << track_data->track_id_ << ": "
413 << latest_obj->center(0) << ", " << latest_obj->center(1)
414 << ", " << latest_obj->center(2) << ", "
415 << latest_obj->size(0) << ", " << latest_obj->size(1) << ", "
416 << latest_obj->size(2) << ", "
417 << latest_obj->output_direction(0) << ", "
418 << latest_obj->output_direction(1) << ", "
419 << latest_obj->output_direction(2) << ", "
420 << static_cast<int>(latest_obj->type) << ", "
421 << std::to_string(latest_obj->object_ptr->latest_tracked_time)
422 << std::endl;
423 }
424 };
425 debug_info(&foreground_track_data_);
426 AINFO << sstr.str();
427}
428
430
431} // namespace lidar
432} // namespace perception
433} // namespace apollo
void BatchGet(size_t num, std::vector< std::shared_ptr< ObjectType > > *data) override
std::shared_ptr< ObjectType > Get() override
std::unique_ptr< MlfTracker > tracker_
Definition mlf_engine.h:146
std::vector< MlfTrackDataPtr > foreground_track_data_
Definition mlf_engine.h:140
void RemoveStaleTrackData(const std::string &name, double timestamp, std::vector< MlfTrackDataPtr > *tracks)
Remove stale track data for memory management
void TrackDebugInfo(LidarFrame *frame)
bool Track(const MultiTargetTrackerOptions &options, LidarFrame *frame) override
Track segmented objects from multiple lidar sensors
Definition mlf_engine.cc:73
std::unique_ptr< MlfTrackObjectMatcher > matcher_
Definition mlf_engine.h:148
std::vector< TrackedObjectPtr > foreground_objects_
Definition mlf_engine.h:143
void SplitAndTransformToTrackedObjects(const std::vector< base::ObjectPtr > &objects, const base::SensorInfo &sensor_info, double frame_timestamp)
Split foreground/background objects and attach to tracked objects
std::vector< MlfTrackDataPtr > background_track_data_
Definition mlf_engine.h:141
void ObjectsDebugInfo(LidarFrame *frame, bool foreground_log=true)
Output object-detection-model results and latest track results
void TrackObjectMatchAndAssign(const MlfTrackObjectMatcherOptions &match_options, const std::vector< TrackedObjectPtr > &objects, const std::string &name, std::vector< MlfTrackDataPtr > *tracks)
Match tracks and objets and object-track assignment
void TrackStateFilter(const std::vector< MlfTrackDataPtr > &tracks, double frame_timestamp)
Filter tracks
std::vector< TrackedObjectPtr > background_objects_
Definition mlf_engine.h:144
bool Init(const MultiTargetTrackerInitOptions &options=MultiTargetTrackerInitOptions()) override
Init mlf engine
Definition mlf_engine.cc:43
void CollectTrackedResult(LidarFrame *frame)
Collect track results and store in frame tracked objects
#define PERCEPTION_REGISTER_MULTITARGET_TRACKER(name)
#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
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
bool IsObjectInRoi(const HdmapStructConstPtr roi, const ObjectConstPtr obj)
Definition roi_filter.cc:51
std::shared_ptr< const TrackedObject > TrackedObjectConstPtr
std::shared_ptr< MlfTrackData > MlfTrackDataPtr
bool JudgeBlindTrafficCone(const MlfTrackDataConstPtr &track_data, double frame_timestamp, const Eigen::Vector3d &local_to_global_offset, Eigen::Affine3d &lidar2world_pose, Eigen::Affine3d &lidar2novatel_pose)
Definition util.cc:24
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::shared_ptr< base::HdmapStruct > hdmap_struct
Definition lidar_frame.h:51
std::vector< std::shared_ptr< base::Object > > segmented_objects
Definition lidar_frame.h:53
std::vector< std::shared_ptr< base::Object > > tracked_objects
Definition lidar_frame.h:55