Apollo 10.0
自动驾驶开放平台
mrf_engine.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2023 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#include "Eigen/Geometry"
21
22#include "modules/common_msgs/localization_msgs/localization.pb.h"
23#include "modules/common_msgs/prediction_msgs/feature.pb.h"
24#include "modules/perception/radar4d_detection/lib/tracker/multi_radar_fusion/proto/mrf_config.pb.h"
25
26#include "cyber/common/file.h"
29
30namespace apollo {
31namespace perception {
32namespace radar4d {
33
35
37 main_sensors_.clear();
38 foreground_objects_.clear();
39 background_objects_.clear();
42}
43
45 std::string config_file = GetConfigFile(
46 options.config_path, options.config_file);
47 MrfEngineConfig config;
48 ACHECK(cyber::common::GetProtoFromFile(config_file, &config));
49
50 Clear();
51
52 for (int i = 0; i < config.main_sensor_size(); ++i) {
53 main_sensors_.emplace(config.main_sensor(i));
54 }
55
56 // default value
57 if (main_sensors_.empty()) {
58 main_sensors_.emplace("radar_front");
59 }
60
66
68 MrfTrackObjectMatcherInitOptions matcher_init_options;
69 matcher_init_options.config_path = options.config_path;
70 ACHECK(matcher_->Init(matcher_init_options));
71
72 tracker_.reset(new MrfTracker);
73 MrfTrackerInitOptions tracker_init_options;
74 tracker_init_options.config_path = options.config_path;
75 ACHECK(tracker_->Init(tracker_init_options));
76 return true;
77}
78
80 RadarFrame* frame) {
81 // 0. modify objects timestamp if necessary
83 for (auto& object : frame->segmented_objects) {
84 object->latest_tracked_time = frame->timestamp;
85 }
86 }
87 // 1. add global offset to pose (only when no track exists)
88 if (foreground_track_data_.empty() && background_track_data_.empty()) {
89 global_to_local_offset_ = -frame->radar2world_pose.translation();
90 }
93 // 2. split fg and bg objects, and transform to tracked objects
95 frame->sensor_info);
96 // 3. assign tracked objects to tracks
97 MrfTrackObjectMatcherOptions match_options;
98 TrackObjectMatchAndAssign(match_options, foreground_objects_, "foreground",
100 TrackObjectMatchAndAssign(match_options, background_objects_, "background",
102 // 4. state filter in tracker if is main sensor
103 bool is_main_sensor =
104 (main_sensors_.find(frame->sensor_info.name) != main_sensors_.end());
105 if (is_main_sensor) {
108 }
109 // 5. track to object if is main sensor
110 frame->tracked_objects.clear();
111 if (is_main_sensor) {
113 }
114 // 6. remove stale data
117
118 AINFO << "MrfEngine publish objects: " << frame->tracked_objects.size()
119 << " sensor_name: " << frame->sensor_info.name
120 << " at timestamp: " << frame->timestamp;
121 return true;
122}
123
125 const std::vector<base::ObjectPtr>& objects,
126 const base::SensorInfo& sensor_info) {
127 std::vector<TrackedObjectPtr> tracked_objects;
128 TrackedObjectPool::Instance().BatchGet(objects.size(), &tracked_objects);
129 foreground_objects_.clear();
130 background_objects_.clear();
131 for (size_t i = 0; i < objects.size(); ++i) {
132 tracked_objects[i]->AttachObject(objects[i], sensor_to_local_pose_,
133 global_to_local_offset_, sensor_info);
134 if (!objects[i]->radar4d_supplement.is_background &&
136 tracked_objects[i]->histogram_bin_size = histogram_bin_size_;
137 tracked_objects[i]->ComputeShapeFeatures();
138 }
139 if (objects[i]->radar4d_supplement.is_background) {
140 background_objects_.push_back(tracked_objects[i]);
141 } else {
142 foreground_objects_.push_back(tracked_objects[i]);
143 }
144 }
145 AINFO << "MrfEngine: " << sensor_info.name
146 << " foreground: " << foreground_objects_.size()
147 << " background: " << background_objects_.size();
148}
149
151 const MrfTrackObjectMatcherOptions& match_options,
152 const std::vector<TrackedObjectPtr>& objects, const std::string& name,
153 std::vector<MrfTrackDataPtr>* tracks) {
154 std::vector<std::pair<size_t, size_t>> assignments;
155 std::vector<size_t> unassigned_tracks;
156 std::vector<size_t> unassigned_objects;
157 matcher_->Match(match_options, objects, *tracks, &assignments,
158 &unassigned_tracks, &unassigned_objects);
159 AINFO << "MrfEngine: " + name + " assignments " << assignments.size()
160 << " unassigned_tracks " << unassigned_tracks.size()
161 << " unassigned_objects " << unassigned_objects.size();
162 // 1. for assignment, push object to cache of track_data
163 for (auto& pair : assignments) {
164 const size_t track_id = pair.first;
165 const size_t object_id = pair.second;
166 tracks->at(track_id)->PushTrackedObjectToCache(objects[object_id]);
167 }
168 // 2. for unassigned_objects, create new tracks
169 for (auto& id : unassigned_objects) {
171 tracker_->InitializeTrack(track_data, objects[id]);
172 tracks->push_back(track_data);
173 }
174}
175
176void MrfEngine::TrackStateFilter(const std::vector<MrfTrackDataPtr>& tracks,
177 double frame_timestamp) {
178 std::vector<TrackedObjectPtr> objects;
179 for (auto& track_data : tracks) {
180 track_data->GetAndCleanCachedObjectsInTimeInterval(&objects);
181 for (auto& obj : objects) {
182 tracker_->UpdateTrackDataWithObject(track_data, obj);
183 }
184 if (objects.empty()) {
185 tracker_->UpdateTrackDataWithoutObject(frame_timestamp, track_data);
186 }
187 }
188}
189
190void convertPoseToLoc(const Eigen::Affine3d& pose,
192 ADEBUG << "translation x y z " << pose.translation()[0] << " "
193 << pose.translation()[1] << " " << pose.translation()[2];
194 localization->mutable_pose()->mutable_position()->set_x(
195 pose.translation()[0]);
196 localization->mutable_pose()->mutable_position()->set_y(
197 pose.translation()[1]);
198 localization->mutable_pose()->mutable_position()->set_z(
199 pose.translation()[2]);
200 Eigen::Quaterniond p(pose.rotation());
201 localization->mutable_pose()->mutable_orientation()->set_qx(p.x());
202 localization->mutable_pose()->mutable_orientation()->set_qy(p.y());
203 localization->mutable_pose()->mutable_orientation()->set_qz(p.z());
204 localization->mutable_pose()->mutable_orientation()->set_qw(p.w());
205}
206
207// TODO(all): semantic map related, for debugging
208// void MrfEngine::AttachDebugInfo(
209// std::vector<std::shared_ptr<base::Object>>* foreground_objs) {
210// for (auto i : obstacle_container_.curr_frame_movable_obstacle_ids()) {
211// Obstacle* obj = obstacle_container_.GetObstacle(i);
212// for (size_t i = 0; i < (*foreground_objs).size(); ++i) {
213// if (obj->id() == (*foreground_objs)[static_cast<int>(i)]->track_id) {
214// (*foreground_objs)[static_cast<int>(i)]->feature.reset(
215// new Feature(obj->latest_feature()));
216// ADEBUG << "traj size is mrf engine is "
217// << (*foreground_objs)[static_cast<int>(i)]
218// ->feature->predicted_trajectory_size()
219// << " track id "
220// << (*foreground_objs)[static_cast<int>(i)]->track_id
221// << " feature address is "
222// << static_cast<void*>(
223// (*foreground_objs)[static_cast<int>(i)]->feature.get());
224// }
225// }
226// }
227//}
228
229// TODO(all): semantic map related, for debugging
230// void MrfEngine::AttachSemanticPredictedTrajectory(
231// const std::vector<MrfTrackDataPtr>& tracks) {
232// for (auto i : obstacle_container_.curr_frame_movable_obstacle_ids()) {
233// Obstacle* obj = obstacle_container_.GetObstacle(i);
234// for (size_t j = 0; j < tracks.size(); ++j) {
235// MrfTrackDataPtr ptr = tracks[j];
236// if (obj->id() == ptr->track_id_) {
237// ptr->feature_.reset(new Feature(obj->latest_feature()));
238// }
239// }
240// }
241//}
242
244 auto& tracked_objects = frame->tracked_objects;
245 tracked_objects.clear();
246 size_t num_objects =
248 base::ObjectPool::Instance().BatchGet(num_objects, &tracked_objects);
249 size_t pos = 0;
250 size_t num_predict = 0;
251 auto collect = [&](std::vector<MrfTrackDataPtr>* tracks) {
252 for (auto& track_data : *tracks) {
253 if (!output_predict_objects_ && track_data->is_current_state_predicted_) {
254 ++num_predict;
255 } else {
256 if (!track_data->ToObject(-global_to_local_offset_, frame->timestamp,
257 tracked_objects[pos])) {
258 AERROR << "Tracking failed";
259 continue;
260 }
261 ++pos;
262 }
263 }
264 };
265 collect(&foreground_track_data_);
266 // update semantic map object container
267// TODO(all): semantic map related, for debugging
268// if (use_semantic_map_) {
269// obstacle_container_.CleanUp();
270// // use msg serializer to convert object to perception obstacles
271// apollo::common::ErrorCode err = apollo::common::ErrorCode::OK;
272// apollo::perception::PerceptionObstacles obstacles;
273// double radar_ts = frame->timestamp;
274// localization::LocalizationEstimate localization;
275// localization.mutable_header()->set_timestamp_sec(radar_ts);
276// localization.mutable_header()->set_radar_timestamp(radar_ts * 1e9);
277// localization.mutable_pose()->mutable_linear_velocity()->set_x(0.0f);
278// localization.mutable_pose()->mutable_linear_velocity()->set_y(0.0f);
279// localization.mutable_pose()->mutable_linear_velocity()->set_z(0.0f);
280// convertPoseToLoc(frame->novatel2world_pose, &localization);
281// pose_container_.Insert(localization);
282// obstacle_container_.InsertPerceptionObstacle(
283// *(pose_container_.ToPerceptionObstacle()), radar_ts);
284// std::vector<std::shared_ptr<base::Object>> foreground_objs(
285// tracked_objects.begin(), tracked_objects.begin() + pos);
286// serializer_.SerializeMsg(0, static_cast<uint64_t>(radar_ts * 1e9), 0,
287// foreground_objs, err, &obstacles);
288// obstacle_container_.Insert(obstacles);
289// evaluator_.Run(&obstacle_container_);
290// AttachDebugInfo(&foreground_objs);
291// AttachSemanticPredictedTrajectory(foreground_track_data_);
292// }
293
294 collect(&background_track_data_);
295 if (num_predict != 0) {
296 AINFO << "MrfEngine, num_predict: " << num_predict
297 << " num_objects: " << num_objects;
298 if (num_predict > num_objects) {
299 AERROR << "num_predict > num_objects";
300 return;
301 }
302 tracked_objects.resize(num_objects - num_predict);
303 }
304}
305
306void MrfEngine::RemoveStaleTrackData(const std::string& name, double timestamp,
307 std::vector<MrfTrackDataPtr>* tracks) {
308 size_t pos = 0;
309 for (size_t i = 0; i < tracks->size(); ++i) {
310 if (tracks->at(i)->latest_visible_time_ + reserved_invisible_time_ >=
311 timestamp) {
312 if (i != pos) {
313 tracks->at(pos) = tracks->at(i);
314 }
315 ++pos;
316 }
317 }
318 AINFO << "MrfEngine: " << name << " remove stale tracks, from "
319 << tracks->size() << " to " << pos;
320 tracks->resize(pos);
321}
322
324
325} // namespace radar4d
326} // namespace perception
327} // namespace apollo
void BatchGet(size_t num, std::vector< std::shared_ptr< ObjectType > > *data) override
std::shared_ptr< ObjectType > Get() override
void SplitAndTransformToTrackedObjects(const std::vector< base::ObjectPtr > &objects, const base::SensorInfo &sensor_info)
Split foreground/background objects and attach to tracked objects
void TrackObjectMatchAndAssign(const MrfTrackObjectMatcherOptions &match_options, const std::vector< TrackedObjectPtr > &objects, const std::string &name, std::vector< MrfTrackDataPtr > *tracks)
Match tracks and objets and object-track assignment
std::vector< TrackedObjectPtr > foreground_objects_
Definition mrf_engine.h:136
std::set< std::string > main_sensors_
Definition mrf_engine.h:146
std::unique_ptr< MrfTracker > tracker_
Definition mrf_engine.h:139
std::vector< TrackedObjectPtr > background_objects_
Definition mrf_engine.h:137
bool Track(const MultiTargetTrackerOptions &options, RadarFrame *frame) override
Track segmented objects from multiple radar sensors
Definition mrf_engine.cc:79
std::vector< MrfTrackDataPtr > background_track_data_
Definition mrf_engine.h:134
void CollectTrackedResult(RadarFrame *frame)
Collect track results and store in frame tracked objects
void TrackStateFilter(const std::vector< MrfTrackDataPtr > &tracks, double frame_timestamp)
Filter tracks
void RemoveStaleTrackData(const std::string &name, double timestamp, std::vector< MrfTrackDataPtr > *tracks)
Remove stale track data for memory management
std::unique_ptr< MrfTrackObjectMatcher > matcher_
Definition mrf_engine.h:141
std::vector< MrfTrackDataPtr > foreground_track_data_
Definition mrf_engine.h:133
bool Init(const MultiTargetTrackerInitOptions &options=MultiTargetTrackerInitOptions()) override
Init mrf engine
Definition mrf_engine.cc:44
#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
std::shared_ptr< MrfTrackData > MrfTrackDataPtr
void convertPoseToLoc(const Eigen::Affine3d &pose, localization::LocalizationEstimate *localization)
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::vector< std::shared_ptr< base::Object > > tracked_objects
Definition radar_frame.h:49
std::vector< std::shared_ptr< base::Object > > segmented_objects
Definition radar_frame.h:47