Apollo 11.0
自动驾驶开放平台
lane_change_util.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 "modules/common_msgs/basic_msgs/pnc_point.pb.h"
20
22
23namespace apollo {
24namespace planning {
25
26bool IsClearToChangeLane(ReferenceLineInfo* reference_line_info) {
27 double ego_start_s = reference_line_info->AdcSlBoundary().start_s();
28 double ego_end_s = reference_line_info->AdcSlBoundary().end_s();
29 double ego_v =
30 std::abs(reference_line_info->vehicle_state().linear_velocity());
31
32 for (const auto* obstacle :
33 reference_line_info->path_decision()->obstacles().Items()) {
34 if (obstacle->IsVirtual() || obstacle->IsStatic()) {
35 ADEBUG << "skip one virtual or static obstacle";
36 continue;
37 }
38
39 double start_s = std::numeric_limits<double>::max();
40 double end_s = -std::numeric_limits<double>::max();
41 double start_l = std::numeric_limits<double>::max();
42 double end_l = -std::numeric_limits<double>::max();
43
44 for (const auto& p : obstacle->PerceptionPolygon().points()) {
46 reference_line_info->reference_line().XYToSL(p, &sl_point);
47 start_s = std::fmin(start_s, sl_point.s());
48 end_s = std::fmax(end_s, sl_point.s());
49
50 start_l = std::fmin(start_l, sl_point.l());
51 end_l = std::fmax(end_l, sl_point.l());
52 }
53
54 if (reference_line_info->IsChangeLanePath()) {
55 double left_width(0), right_width(0);
56 reference_line_info->mutable_reference_line()->GetLaneWidth(
57 (start_s + end_s) * 0.5, &left_width, &right_width);
58 if (end_l < -right_width || start_l > left_width) {
59 continue;
60 }
61 }
62
63 // Raw estimation on whether same direction with ADC or not based on
64 // prediction trajectory
65 bool same_direction = true;
66 if (obstacle->HasTrajectory()) {
67 double obstacle_moving_direction =
68 obstacle->Trajectory().trajectory_point(0).path_point().theta();
69 const auto& vehicle_state = reference_line_info->vehicle_state();
70 double vehicle_moving_direction = vehicle_state.heading();
71 if (vehicle_state.gear() == canbus::Chassis::GEAR_REVERSE) {
72 vehicle_moving_direction =
73 common::math::NormalizeAngle(vehicle_moving_direction + M_PI);
74 }
75 double heading_difference = std::abs(common::math::NormalizeAngle(
76 obstacle_moving_direction - vehicle_moving_direction));
77 same_direction = heading_difference < (M_PI / 2.0);
78 }
79
80 // TODO(All) move to confs
81 static constexpr double kSafeTimeOnSameDirection = 3.0;
82 static constexpr double kSafeTimeOnOppositeDirection = 5.0;
83 static constexpr double kForwardMinSafeDistanceOnSameDirection = 10.0;
84 static constexpr double kBackwardMinSafeDistanceOnSameDirection = 10.0;
85 static constexpr double kForwardMinSafeDistanceOnOppositeDirection = 50.0;
86 static constexpr double kBackwardMinSafeDistanceOnOppositeDirection = 1.0;
87 static constexpr double kDistanceBuffer = 0.5;
88
89 double kForwardSafeDistance = 0.0;
90 double kBackwardSafeDistance = 0.0;
91 if (same_direction) {
92 kForwardSafeDistance =
93 std::fmax(kForwardMinSafeDistanceOnSameDirection,
94 (ego_v - obstacle->speed()) * kSafeTimeOnSameDirection);
95 kBackwardSafeDistance =
96 std::fmax(kBackwardMinSafeDistanceOnSameDirection,
97 (obstacle->speed() - ego_v) * kSafeTimeOnSameDirection);
98 } else {
99 kForwardSafeDistance =
100 std::fmax(kForwardMinSafeDistanceOnOppositeDirection,
101 (ego_v + obstacle->speed()) * kSafeTimeOnOppositeDirection);
102 kBackwardSafeDistance = kBackwardMinSafeDistanceOnOppositeDirection;
103 }
104
105 if (HysteresisFilter(ego_start_s - end_s, kBackwardSafeDistance,
106 kDistanceBuffer, obstacle->IsLaneChangeBlocking()) &&
107 HysteresisFilter(start_s - ego_end_s, kForwardSafeDistance,
108 kDistanceBuffer, obstacle->IsLaneChangeBlocking())) {
109 reference_line_info->path_decision()
110 ->Find(obstacle->Id())
111 ->SetLaneChangeBlocking(true);
112 ADEBUG << "Lane Change is blocked by obstacle" << obstacle->Id();
113 return false;
114 } else {
115 reference_line_info->path_decision()
116 ->Find(obstacle->Id())
117 ->SetLaneChangeBlocking(false);
118 }
119 }
120 return true;
121}
122
123bool IsPerceptionBlocked(const ReferenceLineInfo& reference_line_info,
124 const double search_beam_length,
125 const double search_beam_radius_intensity,
126 const double search_range,
127 const double is_block_angle_threshold) {
128 const auto& vehicle_state = reference_line_info.vehicle_state();
129 const common::math::Vec2d adv_pos(vehicle_state.x(), vehicle_state.y());
130 const double adv_heading = vehicle_state.heading();
131
132 for (auto* obstacle :
133 reference_line_info.path_decision().obstacles().Items()) {
134 double left_most_angle =
135 common::math::NormalizeAngle(adv_heading + 0.5 * search_range);
136 double right_most_angle =
137 common::math::NormalizeAngle(adv_heading - 0.5 * search_range);
138 bool right_most_found = false;
139 if (obstacle->IsVirtual()) {
140 ADEBUG << "skip one virtual obstacle";
141 continue;
142 }
143 const auto& obstacle_polygon = obstacle->PerceptionPolygon();
144 for (double search_angle = 0.0; search_angle < search_range;
145 search_angle += search_beam_radius_intensity) {
146 common::math::Vec2d search_beam_end(search_beam_length, 0.0);
147 const double beam_heading = common::math::NormalizeAngle(
148 adv_heading - 0.5 * search_range + search_angle);
149 search_beam_end.SelfRotate(beam_heading);
150 search_beam_end += adv_pos;
151 common::math::LineSegment2d search_beam(adv_pos, search_beam_end);
152
153 if (!right_most_found && obstacle_polygon.HasOverlap(search_beam)) {
154 right_most_found = true;
155 right_most_angle = beam_heading;
156 }
157
158 if (right_most_found && !obstacle_polygon.HasOverlap(search_beam)) {
159 left_most_angle = beam_heading;
160 break;
161 }
162 }
163 if (!right_most_found) {
164 // obstacle is not in search range
165 continue;
166 }
167 if (std::fabs(common::math::NormalizeAngle(
168 left_most_angle - right_most_angle)) > is_block_angle_threshold) {
169 return true;
170 }
171 }
172
173 return false;
174}
175
176bool HysteresisFilter(const double obstacle_distance,
177 const double safe_distance, const double distance_buffer,
178 const bool is_obstacle_blocking) {
179 if (is_obstacle_blocking) {
180 return obstacle_distance < safe_distance + distance_buffer;
181 } else {
182 return obstacle_distance < safe_distance - distance_buffer;
183 }
184}
185
186} // namespace planning
187} // namespace apollo
Implements a class of 2-dimensional vectors.
Definition vec2d.h:42
void SelfRotate(const double angle)
rotate the vector itself by angle.
Definition vec2d.cc:70
const std::vector< const T * > & Items() const
List all the items in the container.
void SetLaneChangeBlocking(const bool is_distance_clear)
Definition obstacle.cc:767
const Obstacle * Find(const std::string &object_id) const
const IndexedList< std::string, Obstacle > & obstacles() const
ReferenceLineInfo holds all data for one reference line.
const common::VehicleState & vehicle_state() const
const ReferenceLine & reference_line() const
const SLBoundary & AdcSlBoundary() const
bool IsChangeLanePath() const
Check if the current reference line is a change lane reference line, i.e., ADC's current position is ...
bool XYToSL(const common::math::Vec2d &xy_point, common::SLPoint *const sl_point, double warm_start_s=-1.0) const
Transvert Cartesian coordinates to Frenet.
bool GetLaneWidth(const double s, double *const lane_left_width, double *const lane_right_width) const
Planning module main class.
This file contains the static member functions from LaneChangeDecider, which are deleted from the cla...
#define ADEBUG
Definition log.h:41
double NormalizeAngle(const double angle)
Normalize angle to [-PI, PI).
Definition math_utils.cc:53
bool IsClearToChangeLane(ReferenceLineInfo *reference_line_info)
A static function to check if the ChangeLanePath type of reference line is safe or if current referen...
bool HysteresisFilter(const double obstacle_distance, const double safe_distance, const double distance_buffer, const bool is_obstacle_blocking)
bool IsPerceptionBlocked(const ReferenceLineInfo &reference_line_info, const double search_beam_length, const double search_beam_radius_intensity, const double search_range, const double is_block_angle_threshold)
A static function to estimate if an obstacle in certain range in front of ADV blocks too much space p...
class register implement
Definition arena_queue.h:37