21#include <unordered_map>
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)) {
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) {
63 if (nearby_obs.s() < smallest_relative_s) {
64 smallest_relative_s = nearby_obs.s();
65 nearest_front_obstacle_id = nearby_obs.id();
68 return nearest_front_obstacle_id;
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) {
79 if (-nearby_obs.s() < smallest_relative_s) {
80 smallest_relative_s = -nearby_obs.s();
81 nearest_backward_obstacle_id = nearby_obs.id();
84 return nearest_backward_obstacle_id;
90 const std::shared_ptr<ContainerManager>& container_manager)
91 : container_manager_(container_manager) {}
94 auto obstacles_container =
97 if (obstacles_container ==
nullptr) {
98 AERROR <<
"Obstacles container pointer is a null pointer.";
102 obstacles_container->GetObstacle(FLAGS_ego_vehicle_id);
103 if (ego_vehicle ==
nullptr) {
104 AERROR <<
"Ego vehicle not found";
108 AERROR <<
"Ego vehicle has no history";
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.";
121 AERROR <<
"Obstacle [" << obstacle_ptr->
id() <<
"] has no feature.";
125 latest_feature_ptr->mutable_interactive_tag()->set_interactive_tag(
128 auto storytelling_container =
131 if (storytelling_container->ADCDistanceToJunction() <
132 FLAGS_junction_distance_threshold) {
133 AssignInteractiveTagInJunction(*ego_vehicle, obstacles_container,
134 storytelling_container->ADCJunctionId());
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);
144void InteractionFilter::AssignInteractiveTagInJunction(
146 const std::string& junction_id) {
147 const auto& obstacle_ids =
149 for (
const int obstacle_id : obstacle_ids) {
151 if (obstacle_ptr ==
nullptr) {
152 AERROR <<
"Null obstacle pointer found.";
156 SetInteractiveIfCloseToEgo(ego_vehicle,
157 FLAGS_interaction_distance_threshold,
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) {
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";
179 SetInteractiveIfCloseToEgo(ego_vehicle,
180 FLAGS_interaction_distance_threshold,
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) {
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";
205 SetInteractiveIfCloseToEgo(ego_vehicle,
206 FLAGS_interaction_distance_threshold,
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,
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);
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";
245 const std::vector<std::string>& lane_ids =
246 adc_trajectory_container->GetADCTargetLaneIDSequence();
247 if (lane_ids.empty()) {
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;
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.";
268 if (std::fabs(l) < std::fabs(ego_vehicle_l)) {
269 ego_vehicle_s = accumulated_s + s;
271 ego_lane_id_ = lane_id;
275 accumulated_s += lane_info_ptr->total_length();
280 for (
const std::string& lane_id : lane_ids) {
281 if (lane_id == ego_lane_id_) {
284 ego_back_lane_id_set_.insert(lane_id);
287 std::unordered_set<std::string> visited_lanes(lane_ids.begin(),
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()) {
295 std::shared_ptr<const LaneInfo> lane_info_ptr =
297 if (lane_info_ptr ==
nullptr) {
298 AERROR <<
"Null lane info pointer found.";
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);
306 AssignInteractiveByOverlap(ego_vehicle, lane_info_ptr, &visited_lanes,
307 obstacles_container);
309 FLAGS_interaction_search_distance_ahead + ego_vehicle_s) {
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";
327 if (!obstacle_ptr->IsInteractiveObstacle()) {
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});
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();
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);
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;
371 if (!consider_overlap) {
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()) {
380 std::shared_ptr<const LaneInfo> overlap_lane_ptr =
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);
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()) {
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()) {
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);
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();
425 Obstacle* obstacle_ptr = obstacles_container->GetObstacle(obstacle_id);
426 if (obstacle_ptr ==
nullptr) {
427 AERROR <<
"Obstacle [" << obstacle_id <<
"] Not found";
430 SetInteractiveIfCloseToEgo(ego_vehicle,
431 FLAGS_interaction_distance_threshold,
435 if (cumu_distance > max_distance) {
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()) {
444 lane_info_queue.emplace(pre_lane_ptr,
445 cumu_distance + pre_lane_ptr->total_length());
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);
459 if (distance < distance_threshold &&
461 obstacle_ptr->SetInteractiveTag();
463 obstacle_ptr->SetNonInteractiveTag();
InteractionFilter()=delete
void AssignInteractiveTag()
Assign interactive tag for vehicle type obstacles which are close to ADC
bool IsInJunction(const std::string &junction_id) const
Check if the obstacle is a junction.
Feature * mutable_latest_feature()
Get a pointer to the latest feature.
int id() const
Get the obstacle's ID.
size_t history_size() const
Get the number of historical features.
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.
std::shared_ptr< const LaneInfo > ConstLaneInfoPtr