Apollo 10.0
自动驾驶开放平台
util.cc
浏览该文件的文档.
1/******************************************************************************
2 * Copyright 2019 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 <algorithm>
20#include <limits>
21#include <vector>
22
27
28namespace apollo {
29namespace planning {
30namespace util {
31
34
35bool IsVehicleStateValid(const VehicleState& vehicle_state) {
36 if (std::isnan(vehicle_state.x()) || std::isnan(vehicle_state.y()) ||
37 std::isnan(vehicle_state.z()) || std::isnan(vehicle_state.heading()) ||
38 std::isnan(vehicle_state.kappa()) ||
39 std::isnan(vehicle_state.linear_velocity()) ||
40 std::isnan(vehicle_state.linear_acceleration())) {
41 return false;
42 }
43 return true;
44}
45
47 const PlanningCommand& second) {
48 if (first.has_header() && second.has_header()) {
49 const auto& first_header = first.header();
50 const auto& second_header = second.header();
51 return (first_header.sequence_num() != second_header.sequence_num() ||
52 first_header.module_name() != second_header.module_name());
53 }
54 return true;
55}
56
59 const double adc_front_edge_s, const double stop_line_s) {
60 double adc_speed = vehicle_state->linear_velocity();
61 const double max_adc_stop_speed = common::VehicleConfigHelper::Instance()
62 ->GetConfig()
63 .vehicle_param()
64 .max_abs_speed_when_stopped();
65 if (adc_speed < max_adc_stop_speed) {
66 return 0.0;
67 }
68
69 double stop_distance = 0;
70
71 if (stop_line_s > adc_front_edge_s) {
72 stop_distance = stop_line_s - adc_front_edge_s;
73 }
74 if (stop_distance < 1e-5) {
75 return std::numeric_limits<double>::max();
76 }
77 return (adc_speed * adc_speed) / (2 * stop_distance);
78}
79
80/*
81 * @brief: check if a stop_sign_overlap is still along reference_line
82 */
83bool CheckStopSignOnReferenceLine(const ReferenceLineInfo& reference_line_info,
84 const std::string& stop_sign_overlap_id) {
85 const std::vector<PathOverlap>& stop_sign_overlaps =
86 reference_line_info.reference_line().map_path().stop_sign_overlaps();
87 auto stop_sign_overlap_it =
88 std::find_if(stop_sign_overlaps.begin(), stop_sign_overlaps.end(),
89 [&stop_sign_overlap_id](const PathOverlap& overlap) {
90 return overlap.object_id == stop_sign_overlap_id;
91 });
92 return (stop_sign_overlap_it != stop_sign_overlaps.end());
93}
94
95/*
96 * @brief: check if a traffic_light_overlap is still along reference_line
97 */
99 const ReferenceLineInfo& reference_line_info,
100 const std::string& traffic_light_overlap_id) {
101 const std::vector<PathOverlap>& traffic_light_overlaps =
102 reference_line_info.reference_line().map_path().signal_overlaps();
103 auto traffic_light_overlap_it =
104 std::find_if(traffic_light_overlaps.begin(), traffic_light_overlaps.end(),
105 [&traffic_light_overlap_id](const PathOverlap& overlap) {
106 return overlap.object_id == traffic_light_overlap_id;
107 });
108 return (traffic_light_overlap_it != traffic_light_overlaps.end());
109}
110
111/*
112 * @brief: check if ADC is till inside a pnc-junction
113 */
114bool CheckInsideJunction(const ReferenceLineInfo& reference_line_info) {
115 const double adc_front_edge_s = reference_line_info.AdcSlBoundary().end_s();
116 const double adc_back_edge_s = reference_line_info.AdcSlBoundary().start_s();
117
118 hdmap::PathOverlap junction_overlap;
119 reference_line_info.GetJunction(adc_front_edge_s, &junction_overlap);
120 if (junction_overlap.object_id.empty()) {
121 return false;
122 }
123
124 static constexpr double kIntersectionPassDist = 2.0; // unit: m
125 const double distance_adc_pass_intersection =
126 adc_back_edge_s - junction_overlap.end_s;
127 ADEBUG << "distance_adc_pass_intersection[" << distance_adc_pass_intersection
128 << "] junction_overlap[" << junction_overlap.object_id << "] start_s["
129 << junction_overlap.start_s << "]";
130
131 return distance_adc_pass_intersection < kIntersectionPassDist;
132}
133
134/*
135 * @brief: get files at a path
136 */
137void GetFilesByPath(const boost::filesystem::path& path,
138 std::vector<std::string>* files) {
139 ACHECK(files);
140 if (!boost::filesystem::exists(path)) {
141 return;
142 }
143 if (boost::filesystem::is_regular_file(path)) {
144 AINFO << "Found record file: " << path.c_str();
145 files->push_back(path.c_str());
146 return;
147 }
148 if (boost::filesystem::is_directory(path)) {
149 for (auto& entry : boost::make_iterator_range(
150 boost::filesystem::directory_iterator(path), {})) {
151 GetFilesByPath(entry.path(), files);
152 }
153 }
154}
155
156/*
157 * @brief: get path equivalent ego width
158 */
159double CalculateEquivalentEgoWidth(const ReferenceLineInfo& reference_line_info,
160 double s, bool* is_left) {
161 const auto& vehicle_param =
162 common::VehicleConfigHelper::Instance()->GetConfig().vehicle_param();
163 double max_kappa = 1.0 / vehicle_param.min_turn_radius();
164 double half_wb = 0.5 * vehicle_param.wheel_base();
165 double front_l = vehicle_param.front_edge_to_center() - half_wb;
166 double half_w = 0.5 * vehicle_param.width();
167 double current_heading =
168 reference_line_info.reference_line().GetReferencePoint(s).heading();
169 double heading_f = reference_line_info.reference_line()
170 .GetReferencePoint(s + front_l)
171 .heading();
172 double heading_b = reference_line_info.reference_line()
173 .GetReferencePoint(s - half_wb)
174 .heading();
175 // average kappa from front edge to center
176 double kappa_f =
177 apollo::common::math::NormalizeAngle(heading_f - current_heading) /
178 front_l;
179 // average kappa from center to rear axle
180 double kappa_b =
181 apollo::common::math::NormalizeAngle(current_heading - heading_b) /
182 half_wb;
183 *is_left = (kappa_b < 0.0);
184 // prevent devide by 0, and quit if lane bends to difference direction
185 if (kappa_f * kappa_b < 0.0 || fabs(kappa_f) < 1e-6) {
186 return half_w;
187 }
188
189 kappa_f = std::min(fabs(kappa_f), max_kappa);
190 kappa_b = std::min(fabs(kappa_b), max_kappa);
191 double theta = apollo::common::math::Vec2d(1.0, half_wb * kappa_b).Angle();
192 double sint = std::sin(theta);
193 double cost = std::cos(theta);
194 double r_f = 1.0 / kappa_f;
195 double eq_half_w =
196 apollo::common::math::Vec2d(front_l * cost - half_w * sint,
197 r_f + front_l * sint + half_w * cost)
198 .Length() -
199 r_f;
200 return std::max(eq_half_w, half_w);
201}
202
204 const apollo::hdmap::LaneInfoConstPtr lane_info, double s, bool* is_left) {
205 const auto& vehicle_param =
206 common::VehicleConfigHelper::Instance()->GetConfig().vehicle_param();
207 double max_kappa = 1.0 / vehicle_param.min_turn_radius();
208 double half_wb = 0.5 * vehicle_param.wheel_base();
209 double front_l = vehicle_param.front_edge_to_center() - half_wb;
210 double half_w = 0.5 * vehicle_param.width();
211 double current_heading = lane_info->Heading(s);
212 double heading_f = lane_info->Heading(s + front_l);
213 double heading_b = lane_info->Heading(s - half_wb);
214 // average kappa from front edge to center
215 double kappa_f =
216 apollo::common::math::NormalizeAngle(heading_f - current_heading) /
217 front_l;
218 // average kappa from center to rear axle
219 double kappa_b =
220 apollo::common::math::NormalizeAngle(current_heading - heading_b) /
221 half_wb;
222 *is_left = (kappa_b < 0.0);
223 // prevent devide by 0, and quit if lane bends to difference direction
224 if (kappa_f * kappa_b < 0.0 || fabs(kappa_f) < 1e-6) {
225 return half_w;
226 }
227
228 kappa_f = std::min(fabs(kappa_f), max_kappa);
229 kappa_b = std::min(fabs(kappa_b), max_kappa);
230 double theta = apollo::common::math::Vec2d(1.0, half_wb * kappa_b).Angle();
231 double sint = std::sin(theta);
232 double cost = std::cos(theta);
233 double r_f = 1.0 / kappa_f;
234 double eq_half_w =
235 apollo::common::math::Vec2d(front_l * cost - half_w * sint,
236 r_f + front_l * sint + half_w * cost)
237 .Length() -
238 r_f;
239 return std::max(eq_half_w, half_w);
240}
241
242bool left_arc_bound_with_heading(double delta_x, double r, double heading,
243 double* result) {
244 // calculate △L(positive or negative) with an arc with given radius, and given
245 // init_heading the circle can be written as (x-Rsin)^2 + (y+Rcos)^2 = R^2 the
246 // upper side of the circel = (sqrt(R^2 - (x-Rsin)^2) - Rcos) is what we need
247 if (delta_x > r * (1.0 + std::sin(heading)) - 1e-6) {
248 *result = std::numeric_limits<double>::lowest();
249 return false;
250 }
251
252 *result = std::sqrt(r * r - std::pow(delta_x - r * std::sin(heading), 2)) -
253 r * std::cos(heading);
254 return true;
255}
256
257bool right_arc_bound_with_heading(double delta_x, double r, double heading,
258 double* result) {
259 // calculate △L(positive or negative) with an arc with given radius, and given
260 // init_heading the circle can be written as (x+Rsin)^2 + (y-Rcos)^2 = R^2 the
261 // upper side of the circel = (Rcos - sqrt(R^2 - (x+Rsin)^2) )is what we need
262 if (delta_x > r * (1.0 - std::sin(heading)) - 1e-6) {
263 *result = std::numeric_limits<double>::max();
264 return false;
265 }
266 *result = r * std::cos(heading) -
267 std::sqrt(r * r - std::pow(delta_x + r * std::sin(heading), 2));
268 return true;
269}
270
272 double heading,
273 double kappa,
274 double* result) {
275 // calculate △L(positive or negative) with an arc with given radius, and given
276 // init_heading the circle can be written as (x-Rsin)^2 + (y+Rcos)^2 = R^2 the
277 // upper side of the circel = (sqrt(R^2 - (x-Rsin)^2) - Rcos) is what we need
278 if (heading > 0 || kappa < 0 ||
279 delta_x > r * (1.0 - std::sin(heading)) - 1e-6) {
280 *result = std::numeric_limits<double>::lowest();
281 return false;
282 }
283 if (delta_x < -r * std::sin(heading)) {
284 *result = r * std::cos(heading) -
285 std::sqrt(r * r - std::pow(delta_x - r * std::sin(heading), 2));
286 } else {
287 *result = std::sqrt(r * r - std::pow(delta_x + r * std::sin(heading), 2)) -
288 r * (2 - std::cos(heading));
289 }
290 return true;
291}
292
294 double heading,
295 double kappa,
296 double* result) {
297 // calculate △L(positive or negative) with an arc with given radius, and given
298 // init_heading the circle can be written as (x+Rsin)^2 + (y-Rcos)^2 = R^2 the
299 // upper side of the circel = (Rcos - sqrt(R^2 - (x+Rsin)^2) )is what we need
300 if (heading < 0 || kappa > 0 ||
301 delta_x > r * (1.0 - std::sin(heading)) - 1e-6) {
302 *result = std::numeric_limits<double>::max();
303 return false;
304 }
305 if (delta_x < r * std::sin(heading)) {
306 *result = std::sqrt(r * r - std::pow(delta_x - r * std::sin(heading), 2)) -
307 r * std::cos(heading);
308 } else {
309 *result = r * (2 - std::cos(heading)) -
310 std::sqrt(r * r - std::pow(delta_x - r * std::sin(heading), 2));
311 }
312 return true;
313}
314
315} // namespace util
316} // namespace planning
317} // namespace apollo
double linear_velocity() const
Get the vehicle's linear velocity.
Implements a class of 2-dimensional vectors.
Definition vec2d.h:42
double Length() const
Gets the length of the vector
Definition vec2d.cc:33
double Angle() const
Gets the angle between the vector and the positive x semi-axis
Definition vec2d.cc:37
double heading() const
Definition path.h:118
const std::vector< PathOverlap > & signal_overlaps() const
Definition path.h:301
const std::vector< PathOverlap > & stop_sign_overlaps() const
Definition path.h:307
ReferenceLineInfo holds all data for one reference line.
int GetJunction(const double s, hdmap::PathOverlap *junction_overlap) const
const ReferenceLine & reference_line() const
const SLBoundary & AdcSlBoundary() const
const hdmap::Path & map_path() const
ReferencePoint GetReferencePoint(const double s) const
Planning module main class.
#define ACHECK(cond)
Definition log.h:80
#define ADEBUG
Definition log.h:41
#define AINFO
Definition log.h:42
double NormalizeAngle(const double angle)
Normalize angle to [-PI, PI).
Definition math_utils.cc:53
std::shared_ptr< const LaneInfo > LaneInfoConstPtr
bool left_arc_bound_with_heading(double delta_x, double r, double heading, double *result)
Definition util.cc:242
bool CheckInsideJunction(const ReferenceLineInfo &reference_line_info)
Definition util.cc:114
bool CheckStopSignOnReferenceLine(const ReferenceLineInfo &reference_line_info, const std::string &stop_sign_overlap_id)
Definition util.cc:83
bool right_arc_bound_with_heading(double delta_x, double r, double heading, double *result)
Definition util.cc:257
double CalculateEquivalentEgoWidth(const ReferenceLineInfo &reference_line_info, double s, bool *is_left)
Definition util.cc:159
bool left_arc_bound_with_heading_with_reverse_kappa(double delta_x, double r, double heading, double kappa, double *result)
Definition util.cc:271
void GetFilesByPath(const boost::filesystem::path &path, std::vector< std::string > *files)
Definition util.cc:137
bool IsVehicleStateValid(const VehicleState &vehicle_state)
Definition util.cc:35
double GetADCStopDeceleration(apollo::common::VehicleStateProvider *vehicle_state, const double adc_front_edge_s, const double stop_line_s)
Definition util.cc:57
bool IsDifferentRouting(const PlanningCommand &first, const PlanningCommand &second)
Definition util.cc:46
bool right_arc_bound_with_heading_with_reverse_kappa(double delta_x, double r, double heading, double kappa, double *result)
Definition util.cc:293
bool CheckTrafficLightOnReferenceLine(const ReferenceLineInfo &reference_line_info, const std::string &traffic_light_overlap_id)
Definition util.cc:98
class register implement
Definition arena_queue.h:37
std::string object_id
Definition path.h:95
optional apollo::common::Header header