Apollo 11.0
自动驾驶开放平台
interaction_filter.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2021 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 <limits>
20#include <queue>
21#include <unordered_map>
22#include <utility>
23
30
31namespace apollo {
32namespace prediction {
33
39using ConstLaneInfoPtr = std::shared_ptr<const LaneInfo>;
40
41namespace {
42
43bool IsLaneSequenceInReferenceLine(
44 const LaneSequence& lane_sequence,
45 const ADCTrajectoryContainer* ego_trajectory_container) {
46 for (const auto& lane_segment : lane_sequence.lane_segment()) {
47 std::string lane_id = lane_segment.lane_id();
48 if (ego_trajectory_container->IsLaneIdInTargetReferenceLine(lane_id)) {
49 return true;
50 }
51 }
52 return false;
53}
54
55int NearestFrontObstacleIdOnLaneSequence(const LaneSequence& lane_sequence) {
56 int nearest_front_obstacle_id = std::numeric_limits<int>::min();
57 double smallest_relative_s = std::numeric_limits<double>::max();
58 for (const auto& nearby_obs : lane_sequence.nearby_obstacle()) {
59 if (nearby_obs.s() < 0.0 ||
60 nearby_obs.s() > FLAGS_interaction_search_distance_ahead) {
61 continue;
62 }
63 if (nearby_obs.s() < smallest_relative_s) {
64 smallest_relative_s = nearby_obs.s();
65 nearest_front_obstacle_id = nearby_obs.id();
66 }
67 }
68 return nearest_front_obstacle_id;
69}
70
71int NearestBackwardObstacleIdOnLaneSequence(const LaneSequence& lane_sequence) {
72 int nearest_backward_obstacle_id = std::numeric_limits<int>::min();
73 double smallest_relative_s = std::numeric_limits<double>::max();
74 for (const auto& nearby_obs : lane_sequence.nearby_obstacle()) {
75 if (nearby_obs.s() > 0.0 ||
76 nearby_obs.s() < -FLAGS_interaction_search_distance_backward) {
77 continue;
78 }
79 if (-nearby_obs.s() < smallest_relative_s) {
80 smallest_relative_s = -nearby_obs.s();
81 nearest_backward_obstacle_id = nearby_obs.id();
82 }
83 }
84 return nearest_backward_obstacle_id;
85}
86
87} // namespace
88
90 const std::shared_ptr<ContainerManager>& container_manager)
91 : container_manager_(container_manager) {}
92
94 auto obstacles_container =
95 container_manager_->GetContainer<ObstaclesContainer>(
97 if (obstacles_container == nullptr) {
98 AERROR << "Obstacles container pointer is a null pointer.";
99 return;
100 }
101 Obstacle* ego_vehicle =
102 obstacles_container->GetObstacle(FLAGS_ego_vehicle_id);
103 if (ego_vehicle == nullptr) {
104 AERROR << "Ego vehicle not found";
105 return;
106 }
107 if (ego_vehicle->history_size() == 0) {
108 AERROR << "Ego vehicle has no history";
109 return;
110 }
111
112 const auto& obstacle_ids =
113 obstacles_container->curr_frame_movable_obstacle_ids();
114 for (const int obstacle_id : obstacle_ids) {
115 Obstacle* obstacle_ptr = obstacles_container->GetObstacle(obstacle_id);
116 if (obstacle_ptr == nullptr) {
117 AERROR << "Null obstacle pointer found.";
118 continue;
119 }
120 if (obstacle_ptr->history_size() == 0) {
121 AERROR << "Obstacle [" << obstacle_ptr->id() << "] has no feature.";
122 continue;
123 }
124 Feature* latest_feature_ptr = obstacle_ptr->mutable_latest_feature();
125 latest_feature_ptr->mutable_interactive_tag()->set_interactive_tag(
127 }
128 auto storytelling_container =
129 container_manager_->GetContainer<StoryTellingContainer>(
131 if (storytelling_container->ADCDistanceToJunction() <
132 FLAGS_junction_distance_threshold) {
133 AssignInteractiveTagInJunction(*ego_vehicle, obstacles_container,
134 storytelling_container->ADCJunctionId());
135 }
136 AssignInteractiveTagCruiseKeepLane(*ego_vehicle, obstacles_container);
137 AssignInteractiveTagCruiseChangeLane(*ego_vehicle, obstacles_container);
138 AssignInteractiveTagByEgoReferenceLine(*ego_vehicle, obstacles_container);
139 if (FLAGS_enable_rank_interactive_obstacles) {
140 RankingInteractiveTagObstacles(*ego_vehicle, obstacles_container);
141 }
142}
143
144void InteractionFilter::AssignInteractiveTagInJunction(
145 const Obstacle& ego_vehicle, ObstaclesContainer* obstacles_container,
146 const std::string& junction_id) {
147 const auto& obstacle_ids =
148 obstacles_container->curr_frame_movable_obstacle_ids();
149 for (const int obstacle_id : obstacle_ids) {
150 Obstacle* obstacle_ptr = obstacles_container->GetObstacle(obstacle_id);
151 if (obstacle_ptr == nullptr) {
152 AERROR << "Null obstacle pointer found.";
153 continue;
154 }
155 if (obstacle_ptr->IsInJunction(junction_id)) {
156 SetInteractiveIfCloseToEgo(ego_vehicle,
157 FLAGS_interaction_distance_threshold,
158 obstacle_ptr);
159 }
160 }
161}
162
163void InteractionFilter::AssignInteractiveTagCruiseKeepLane(
164 const Obstacle& ego_vehicle, ObstaclesContainer* obstacles_container) {
165 const Feature& ego_latest_feature = ego_vehicle.latest_feature();
166 for (const LaneSequence& lane_sequence :
167 ego_latest_feature.lane().lane_graph().lane_sequence()) {
168 int nearest_front_obstacle_id =
169 NearestFrontObstacleIdOnLaneSequence(lane_sequence);
170 if (nearest_front_obstacle_id < 0) {
171 continue;
172 }
173 Obstacle* obstacle_ptr =
174 obstacles_container->GetObstacle(nearest_front_obstacle_id);
175 if (obstacle_ptr == nullptr) {
176 AERROR << "Obstacle [" << nearest_front_obstacle_id << "] Not found";
177 continue;
178 }
179 SetInteractiveIfCloseToEgo(ego_vehicle,
180 FLAGS_interaction_distance_threshold,
181 obstacle_ptr);
182 }
183}
184
185void InteractionFilter::AssignInteractiveTagCruiseChangeLane(
186 const Obstacle& ego_vehicle, ObstaclesContainer* obstacles_container) {
187 ADCTrajectoryContainer* ego_trajectory_container =
188 container_manager_->GetContainer<ADCTrajectoryContainer>(
190 const Feature& ego_latest_feature = ego_vehicle.latest_feature();
191 for (const LaneSequence& lane_sequence :
192 ego_latest_feature.lane().lane_graph().lane_sequence()) {
193 if (lane_sequence.vehicle_on_lane()) {
194 int nearest_front_obstacle_id =
195 NearestFrontObstacleIdOnLaneSequence(lane_sequence);
196 if (nearest_front_obstacle_id < 0) {
197 continue;
198 }
199 Obstacle* obstacle_ptr =
200 obstacles_container->GetObstacle(nearest_front_obstacle_id);
201 if (obstacle_ptr == nullptr) {
202 AERROR << "Obstacle [" << nearest_front_obstacle_id << "] Not found";
203 continue;
204 }
205 SetInteractiveIfCloseToEgo(ego_vehicle,
206 FLAGS_interaction_distance_threshold,
207 obstacle_ptr);
208 } else if (IsLaneSequenceInReferenceLine(lane_sequence,
209 ego_trajectory_container)) {
210 int nearest_front_obstacle_id =
211 NearestFrontObstacleIdOnLaneSequence(lane_sequence);
212 int nearest_backward_obstacle_id =
213 NearestBackwardObstacleIdOnLaneSequence(lane_sequence);
214 if (nearest_front_obstacle_id >= 0) {
215 Obstacle* front_obstacle_ptr =
216 obstacles_container->GetObstacle(nearest_front_obstacle_id);
217 if (front_obstacle_ptr != nullptr) {
218 SetInteractiveIfCloseToEgo(ego_vehicle,
219 FLAGS_interaction_distance_threshold,
220 front_obstacle_ptr);
221 }
222 }
223 if (nearest_backward_obstacle_id >= 0) {
224 Obstacle* backward_obstacle_ptr =
225 obstacles_container->GetObstacle(nearest_backward_obstacle_id);
226 if (backward_obstacle_ptr != nullptr) {
227 SetInteractiveIfCloseToEgo(ego_vehicle,
228 FLAGS_interaction_distance_threshold,
229 backward_obstacle_ptr);
230 }
231 }
232 }
233 }
234}
235
236void InteractionFilter::AssignInteractiveTagByEgoReferenceLine(
237 const Obstacle& ego_vehicle, ObstaclesContainer* obstacles_container) {
238 ADCTrajectoryContainer* adc_trajectory_container =
239 container_manager_->GetContainer<ADCTrajectoryContainer>(
241 if (adc_trajectory_container == nullptr) {
242 AERROR << "adc_trajectory_container is nullptr";
243 return;
244 }
245 const std::vector<std::string>& lane_ids =
246 adc_trajectory_container->GetADCTargetLaneIDSequence();
247 if (lane_ids.empty()) {
248 return;
249 }
250
251 const Feature& ego_feature = ego_vehicle.latest_feature();
252 double ego_x = ego_feature.position().x();
253 double ego_y = ego_feature.position().y();
254 double ego_vehicle_s = std::numeric_limits<double>::max();
255 double ego_vehicle_l = std::numeric_limits<double>::max();
256 double accumulated_s = 0.0;
257 // first loop for lane_ids to findout ego_vehicle_s
258 for (const std::string& lane_id : lane_ids) {
259 std::shared_ptr<const LaneInfo> lane_info_ptr =
261 if (lane_info_ptr == nullptr) {
262 AERROR << "Null lane info pointer found.";
263 continue;
264 }
265 double s = 0.0;
266 double l = 0.0;
267 if (PredictionMap::GetProjection({ego_x, ego_y}, lane_info_ptr, &s, &l)) {
268 if (std::fabs(l) < std::fabs(ego_vehicle_l)) {
269 ego_vehicle_s = accumulated_s + s;
270 ego_vehicle_l = l;
271 ego_lane_id_ = lane_id;
272 ego_lane_s_ = s;
273 }
274 }
275 accumulated_s += lane_info_ptr->total_length();
276 }
277
278 // insert ego_back_lane_id
279 accumulated_s = 0.0;
280 for (const std::string& lane_id : lane_ids) {
281 if (lane_id == ego_lane_id_) {
282 break;
283 }
284 ego_back_lane_id_set_.insert(lane_id);
285 }
286
287 std::unordered_set<std::string> visited_lanes(lane_ids.begin(),
288 lane_ids.end());
289
290 // then loop through lane_ids to AssignInteractive for obstacle vehicles
291 for (const std::string& lane_id : lane_ids) {
292 if (ego_back_lane_id_set_.find(lane_id) != ego_back_lane_id_set_.end()) {
293 continue;
294 }
295 std::shared_ptr<const LaneInfo> lane_info_ptr =
297 if (lane_info_ptr == nullptr) {
298 AERROR << "Null lane info pointer found.";
299 continue;
300 }
301 accumulated_s += lane_info_ptr->total_length();
302 if (lane_id != ego_lane_id_) {
303 AssignInteractiveByMerge(ego_vehicle, lane_info_ptr, &visited_lanes,
304 obstacles_container);
305 }
306 AssignInteractiveByOverlap(ego_vehicle, lane_info_ptr, &visited_lanes,
307 obstacles_container);
308 if (accumulated_s >
309 FLAGS_interaction_search_distance_ahead + ego_vehicle_s) {
310 break;
311 }
312 }
313}
314
315void InteractionFilter::RankingInteractiveTagObstacles(
316 const Obstacle& ego_vehicle, ObstaclesContainer* obstacles_container) {
317 const Point3D& ego_position = ego_vehicle.latest_feature().position();
318 const auto& obstacle_ids =
319 obstacles_container->curr_frame_movable_obstacle_ids();
320 std::priority_queue<std::pair<double, Obstacle*>> interactive_obstacle_queue;
321 for (const int obstacle_id : obstacle_ids) {
322 Obstacle* obstacle_ptr = obstacles_container->GetObstacle(obstacle_id);
323 if (obstacle_ptr == nullptr) {
324 AERROR << "Obstacle [" << obstacle_id << "] Not found";
325 continue;
326 }
327 if (!obstacle_ptr->IsInteractiveObstacle()) {
328 continue;
329 }
330 const Point3D& obstacle_position =
331 obstacle_ptr->latest_feature().position();
332 double distance = std::hypot(obstacle_position.x() - ego_position.x(),
333 obstacle_position.y() - ego_position.y());
334 interactive_obstacle_queue.push({distance, obstacle_ptr});
335 }
336 while (static_cast<int>(interactive_obstacle_queue.size()) >
337 FLAGS_interactive_obs_max_nums) {
338 Obstacle* obstacle_ptr = interactive_obstacle_queue.top().second;
339 obstacle_ptr->mutable_latest_feature()->
340 mutable_interactive_tag()->set_interactive_tag(
342 interactive_obstacle_queue.pop();
343 }
344}
345
346void InteractionFilter::AssignInteractiveByMerge(
347 const Obstacle& ego_vehicle, std::shared_ptr<const LaneInfo> lane_info_ptr,
348 std::unordered_set<std::string>* const visited_lanes,
349 ObstaclesContainer* obstacles_container) {
350 SetInteractiveBackward(FLAGS_interaction_search_distance_backward_for_merge,
351 ego_vehicle, lane_info_ptr, visited_lanes,
352 obstacles_container);
353}
354
355void InteractionFilter::AssignInteractiveByOverlap(
356 const Obstacle& ego_vehicle, std::shared_ptr<const LaneInfo> lane_info_ptr,
357 std::unordered_set<std::string>* const visited_lanes,
358 ObstaclesContainer* obstacles_container) {
359 std::string lane_id = lane_info_ptr->id().id();
360 const std::vector<std::shared_ptr<const OverlapInfo>> cross_lanes =
361 lane_info_ptr->cross_lanes();
362 for (const auto overlap_ptr : cross_lanes) {
363 bool consider_overlap = true;
364 for (const auto& object : overlap_ptr->overlap().object()) {
365 if (object.id().id() == lane_info_ptr->id().id() &&
366 object.lane_overlap_info().end_s() < ego_lane_s_) {
367 consider_overlap = false;
368 }
369 }
370
371 if (!consider_overlap) {
372 continue;
373 }
374
375 for (const auto& object : overlap_ptr->overlap().object()) {
376 const auto& object_id = object.id().id();
377 if (object_id == lane_info_ptr->id().id()) {
378 continue;
379 }
380 std::shared_ptr<const LaneInfo> overlap_lane_ptr =
381 PredictionMap::LaneById(object_id);
382 // ahead_s is the length in front of the overlap
383 double ahead_s = overlap_lane_ptr->total_length() -
384 object.lane_overlap_info().start_s();
385 SetInteractiveBackward(
386 ahead_s + FLAGS_interaction_search_distance_backward_for_overlap,
387 ego_vehicle, overlap_lane_ptr, visited_lanes, obstacles_container);
388 }
389 }
390}
391
392void InteractionFilter::SetInteractiveBackward(
393 const double max_distance, const Obstacle& ego_vehicle,
394 std::shared_ptr<const LaneInfo> start_lane_info_ptr,
395 std::unordered_set<std::string>* const visited_lanes,
396 ObstaclesContainer* obstacles_container) {
397 std::string start_lane_id = start_lane_info_ptr->id().id();
398 if (ego_back_lane_id_set_.find(start_lane_id) !=
399 ego_back_lane_id_set_.end()) {
400 return;
401 }
402 std::unordered_map<std::string, std::vector<LaneObstacle>> lane_obstacles =
403 obstacles_container->GetClustersPtr()->GetLaneObstacles();
404 std::queue<std::pair<ConstLaneInfoPtr, double>> lane_info_queue;
405 lane_info_queue.emplace(start_lane_info_ptr,
406 start_lane_info_ptr->total_length());
407 while (!lane_info_queue.empty()) {
408 ConstLaneInfoPtr curr_lane = lane_info_queue.front().first;
409 double cumu_distance = lane_info_queue.front().second;
410 lane_info_queue.pop();
411 const std::string& lane_id = curr_lane->id().id();
412 if (visited_lanes->find(lane_id) == visited_lanes->end() &&
413 lane_obstacles.find(lane_id) != lane_obstacles.end() &&
414 !lane_obstacles[lane_id].empty()) {
415 visited_lanes->insert(lane_id);
416 // find the obstacle with largest lane_s on the lane
417 int obstacle_id = lane_obstacles[lane_id].front().obstacle_id();
418 double obstacle_s = lane_obstacles[lane_id].front().lane_s();
419 for (const LaneObstacle& lane_obstacle : lane_obstacles[lane_id]) {
420 if (lane_obstacle.lane_s() > obstacle_s) {
421 obstacle_id = lane_obstacle.obstacle_id();
422 obstacle_s = lane_obstacle.lane_s();
423 }
424 }
425 Obstacle* obstacle_ptr = obstacles_container->GetObstacle(obstacle_id);
426 if (obstacle_ptr == nullptr) {
427 AERROR << "Obstacle [" << obstacle_id << "] Not found";
428 continue;
429 }
430 SetInteractiveIfCloseToEgo(ego_vehicle,
431 FLAGS_interaction_distance_threshold,
432 obstacle_ptr);
433 continue;
434 }
435 if (cumu_distance > max_distance) {
436 continue;
437 }
438 for (const auto& pre_lane_id : curr_lane->lane().predecessor_id()) {
439 if (ego_back_lane_id_set_.find(pre_lane_id.id()) !=
440 ego_back_lane_id_set_.end()) {
441 continue;
442 }
443 ConstLaneInfoPtr pre_lane_ptr = PredictionMap::LaneById(pre_lane_id.id());
444 lane_info_queue.emplace(pre_lane_ptr,
445 cumu_distance + pre_lane_ptr->total_length());
446 }
447 }
448}
449
450void InteractionFilter::SetInteractiveIfCloseToEgo(
451 const Obstacle& ego_vehicle, const double distance_threshold,
452 Obstacle* obstacle_ptr) {
453 const Point3D& obstacle_position = obstacle_ptr->latest_feature().position();
454 const Point3D& ego_position = ego_vehicle.latest_feature().position();
455 double diff_x = obstacle_position.x() - ego_position.x();
456 double diff_y = obstacle_position.y() - ego_position.y();
457 double distance = std::hypot(diff_x, diff_y);
458 // Add interactive tag only for vehicles
459 if (distance < distance_threshold &&
460 obstacle_ptr->latest_feature().type() == PerceptionObstacle::VEHICLE) {
461 obstacle_ptr->SetInteractiveTag();
462 } else {
463 obstacle_ptr->SetNonInteractiveTag();
464 }
465}
466
467} // namespace prediction
468} // namespace apollo
ADC trajectory container
void AssignInteractiveTag()
Assign interactive tag for vehicle type obstacles which are close to ADC
Prediction obstacle.
Definition obstacle.h:52
bool IsInJunction(const std::string &junction_id) const
Check if the obstacle is a junction.
Definition obstacle.cc:223
Feature * mutable_latest_feature()
Get a pointer to the latest feature.
Definition obstacle.cc:88
int id() const
Get the obstacle's ID.
Definition obstacle.cc:60
size_t history_size() const
Get the number of historical features.
Definition obstacle.cc:93
const std::vector< int > & curr_frame_movable_obstacle_ids()
Get movable obstacle IDs in the current frame
Obstacle * GetObstacle(const int id)
Get obstacle pointer
static std::shared_ptr< const hdmap::LaneInfo > LaneById(const std::string &id)
Get a shared pointer to a lane by lane ID.
static bool GetProjection(const Eigen::Vector2d &position, const std::shared_ptr< const hdmap::LaneInfo > lane_info, double *s, double *l)
Get the frenet coordinates (s, l) on a lane by a position.
#define AERROR
Definition log.h:44
std::shared_ptr< const LaneInfo > ConstLaneInfoPtr
class register implement
Definition arena_queue.h:37
Obstacles container
story telling container