Apollo 11.0
自动驾驶开放平台
square_path.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 <algorithm>
20#include <memory>
21#include <string>
22#include <utility>
23#include <vector>
32namespace apollo {
33namespace planning {
34
37
39 const std::string& config_dir,
40 const std::string& name,
41 const std::shared_ptr<DependencyInjector>& injector) {
42 if (!Task::Init(config_dir, name, injector)) {
43 return false;
44 }
45 // Load the config this task.
46 return Task::LoadConfig<SquarePathConfig>(&config_);
47}
48
49apollo::common::Status SquarePath::Process(Frame* frame, ReferenceLineInfo* reference_line_info) {
50 std::vector<PathBoundary> candidate_path_boundaries;
51 std::vector<PathData> candidate_path_data;
52
54 AINFO << init_sl_state_.first[0] << "," << init_sl_state_.first[1] << "," << init_sl_state_.second[0] << ","
55 << init_sl_state_.second[1];
56 common::TrajectoryPoint planning_start_point = frame_->PlanningStartPoint();
57 AINFO << std::fixed << "Plan at the starting point: x = " << planning_start_point.path_point().x()
58 << ", y = " << planning_start_point.path_point().y()
59 << ", and angle = " << planning_start_point.path_point().theta();
60 if (!DecidePathBounds(&candidate_path_boundaries)) {
61 AERROR << "Decide path bound failed";
62 return Status::OK();
63 }
64 if (!OptimizePath(candidate_path_boundaries, &candidate_path_data)) {
65 AERROR << "Optmize path failed";
66 return Status::OK();
67 }
68 if (!AssessPath(&candidate_path_data, reference_line_info)) {
69 AERROR << "Path assessment failed";
70 }
71
72 return Status::OK();
73}
74
75bool SquarePath::DecidePathBounds(std::vector<PathBoundary>* boundary) {
76 boundary->emplace_back();
77 auto& path_bound = boundary->back();
78 std::string blocking_obstacle_id = "";
79 std::string lane_type = "";
80 double path_narrowest_width = 0;
82 const std::string msg = "Failed to initialize path boundaries.";
83 AERROR << msg;
84 return false;
85 }
86 path_bound.set_label(absl::StrCat("regular/", "square"));
88
89 GetBoundaryFromSquare(*reference_line_info_, &path_bound, init_sl_state_);
90 PathBound temp_path_bound = path_bound;
91 std::vector<SLPolygon> obs_sl_polygons;
95 &obs_sl_polygons,
97 &path_bound,
98 &blocking_obstacle_id,
99 &path_narrowest_width)) {
100 const std::string msg
101 = "Failed to decide fine tune the boundaries after "
102 "taking into consideration all static obstacles.";
103 AERROR << msg;
104 return false;
105 }
106
107 int counter = 0;
108 while (!blocking_obstacle_id.empty() && path_bound.size() < temp_path_bound.size()
109 && counter < FLAGS_num_extra_tail_bound_point) {
110 path_bound.push_back(temp_path_bound[path_bound.size()]);
111 counter++;
112 }
113
114 if (init_sl_state_.second[0] > path_bound[0].l_upper.l || init_sl_state_.second[0] < path_bound[0].l_lower.l) {
115 AINFO << "init l out of range" << init_sl_state_.second[0] << path_bound[0].l_lower.l << ","
116 << path_bound[0].l_upper.l;
117 return false;
118 }
119
120 path_bound.set_blocking_obstacle_id(blocking_obstacle_id);
121 RecordDebugInfo(path_bound, path_bound.label(), reference_line_info_);
122 return true;
123}
124
125bool SquarePath::OptimizePath(
126 const std::vector<PathBoundary>& path_boundaries,
127 std::vector<PathData>* candidate_path_data) {
128 const auto& config = config_.path_optimizer_config();
129 const ReferenceLine& reference_line = reference_line_info_->reference_line();
130 std::array<double, 3> end_state = {0.0, 0.0, 0.0};
131 for (const auto& path_boundary : path_boundaries) {
132 size_t path_boundary_size = path_boundary.boundary().size();
133 if (path_boundary_size <= 1U) {
134 AERROR << "Get invalid path boundary with size: " << path_boundary_size;
135 return false;
136 }
137 std::vector<double> opt_l, opt_dl, opt_ddl;
138 std::vector<std::pair<double, double>> ddl_bounds;
139 PathOptimizerUtil::CalculateAccBound(path_boundary, reference_line, &ddl_bounds);
140 PrintCurves print_debug;
141 for (size_t i = 0; i < path_boundary_size; ++i) {
142 double s = static_cast<double>(i) * path_boundary.delta_s() + path_boundary.start_s();
143 double kappa = reference_line.GetNearestReferencePoint(s).kappa();
144 print_debug.AddPoint("ref_kappa", s, kappa);
145 }
146 print_debug.PrintToLog();
147 const double jerk_bound = PathOptimizerUtil::EstimateJerkBoundary(std::fmax(init_sl_state_.first[1], 1e-12));
148 std::vector<double> ref_l(path_boundary_size, 0);
149 std::vector<double> weight_ref_l(path_boundary_size, 0);
151 path_boundary, config.path_reference_l_weight(), &ref_l, &weight_ref_l);
152 bool res_opt = PathOptimizerUtil::OptimizePath(
154 end_state,
155 ref_l,
156 weight_ref_l,
157 path_boundary,
158 ddl_bounds,
159 jerk_bound,
160 config,
161 &opt_l,
162 &opt_dl,
163 &opt_ddl);
164 if (res_opt) {
165 auto frenet_frame_path = PathOptimizerUtil::ToPiecewiseJerkPath(
166 opt_l, opt_dl, opt_ddl, path_boundary.delta_s(), path_boundary.start_s());
167 PathData path_data;
168 path_data.SetReferenceLine(&reference_line);
169 path_data.SetFrenetPath(std::move(frenet_frame_path));
170 if (FLAGS_use_front_axe_center_in_path_planning) {
171 auto discretized_path
173 path_data.SetDiscretizedPath(discretized_path);
174 }
175 path_data.set_path_label(path_boundary.label());
176 path_data.set_blocking_obstacle_id(path_boundary.blocking_obstacle_id());
177 candidate_path_data->push_back(std::move(path_data));
178 }
179 }
180 if (candidate_path_data->empty()) {
181 return false;
182 }
183 return true;
184}
185
186bool SquarePath::AssessPath(std::vector<PathData>* candidate_path_data, ReferenceLineInfo* reference_line_info) {
187 PathData& curr_path_data = candidate_path_data->back();
188 RecordDebugInfo(curr_path_data, curr_path_data.path_label(), reference_line_info_);
190 AINFO << "Lane follow path is invalid";
191 return false;
192 }
193 double max_kappa
194 = std::tan(vehicle_param_.max_steer_angle() / vehicle_param_.steer_ratio()) / vehicle_param_.wheel_base();
195 AINFO << "max_kappa:" << max_kappa;
196 // bool is_valid_path = true;
197 for (const auto& path_point : curr_path_data.discretized_path()) {
198 AINFO << path_point.x() << "," << path_point.y() << "," << path_point.theta() << "," << path_point.kappa()
199 << "," << path_point.dkappa();
200 if (std::fabs(path_point.kappa()) > max_kappa) {
201 AINFO << "Path kappa is too large" << path_point.kappa();
202 // is_valid_path = false;
203 }
204 }
205 // if (!is_valid_path) {
206 // return false;
207 // }
208 reference_line_info->MutableCandidatePathData()->push_back(curr_path_data);
209 if (reference_line_info->mutable_path_data()->Empty()) {
210 (*reference_line_info->mutable_path_data()) = std::move(curr_path_data);
211 }
212 return true;
213}
214
215bool SquarePath::GetBoundaryFromSquare(
216 const ReferenceLineInfo& reference_line_info,
217 PathBoundary* const path_boundary,
218 const SLState& init_sl_state) {
219 hdmap::PathOverlap junction_overlap;
220 if (reference_line_info.GetJunction(init_sl_state.first[0], &junction_overlap) == 0) {
221 return false;
222 }
223 const auto& hdmap = hdmap::HDMapUtil::BaseMapPtr();
224 const auto& junction = hdmap->GetJunctionById(hdmap::MakeMapId(junction_overlap.object_id));
225 const auto& junction_polygon = junction->polygon();
226 const auto& reference_line = reference_line_info.reference_line();
227 SLBoundary sl_boundary;
228 reference_line.GetSLBoundary(junction_polygon, &sl_boundary);
229 SLPolygon sl_polygon(sl_boundary, junction_overlap.object_id);
230
231 for (size_t i = 0; i < path_boundary->size(); i++) {
232 auto& point = path_boundary->at(i);
233 if (point.s < sl_polygon.MinS() || point.s > sl_polygon.MaxS()) {
234 continue;
235 }
236 double l_min = sl_polygon.GetRightBoundaryByS(point.s);
237 double l_max = sl_polygon.GetLeftBoundaryByS(point.s);
238 double road_left_width = config_.max_lateral_distance();
239 double road_right_width = config_.max_lateral_distance();
240 if (config_.enable_road_boundary_constraint()) {
241 reference_line.GetRoadWidth(point.s, &road_left_width, &road_right_width);
242 road_left_width = std::min(road_left_width, config_.max_lateral_distance());
243 road_right_width = std::min(road_right_width, config_.max_lateral_distance());
244 }
245 l_min = std::max<double>(l_min, -road_right_width);
246 l_max = std::min<double>(l_max, road_left_width);
247 if (point.l_lower.l > l_min) {
248 point.l_lower.l = l_min;
249 point.l_lower.type = BoundType::ROAD;
250 }
251 if (point.l_upper.l < l_max) {
252 point.l_upper.l = l_max;
253 point.l_upper.type = BoundType::ROAD;
254 }
255 }
256 return true;
257}
258
259} // namespace planning
260} // namespace apollo
A general class to denote the return status of an API call.
Definition status.h:43
static Status OK()
generate a success status.
Definition status.h:60
@Brief This is a helper class that can load vehicle configurations.
static const HDMap * BaseMapPtr()
Frame holds all data for one planning cycle.
Definition frame.h:62
const common::TrajectoryPoint & PlanningStartPoint() const
Definition frame.cc:79
static bool IsValidRegularPath(const ReferenceLineInfo &reference_line_info, const PathData &path_data)
Check if the generated path is valid
static bool GetBoundaryFromSelfLane(const ReferenceLineInfo &reference_line_info, const SLState &init_sl_state, PathBoundary *const path_bound)
generate path bound by self lane and adc position
static bool GetBoundaryFromStaticObstacles(const ReferenceLineInfo &reference_line_info, std::vector< SLPolygon > *const sl_polygons, const SLState &init_sl_state, PathBoundary *const path_boundaries, std::string *const blocking_obstacle_id, double *const narrowest_width)
Refine the boundary based on static obstacles.
static void GetSLPolygons(const ReferenceLineInfo &reference_line_info, std::vector< SLPolygon > *polygons, const SLState &init_sl_state)
static bool InitPathBoundary(const ReferenceLineInfo &reference_line_info, PathBoundary *const path_bound, SLState init_sl_state)
Starting from ADC's current position, increment until the path length, and set lateral bounds to be i...
void RecordDebugInfo(const PathBound &path_boundaries, const std::string &debug_name, ReferenceLineInfo *const reference_line_info)
add path_boundary debug info for PnC monitor
void GetStartPointSLState()
calculate init sl state by planning start point, result will store in init_sl_state_
static std::vector< common::PathPoint > ConvertPathPointRefFromFrontAxeToRearAxe(const PathData &path_data)
static void CalculateAccBound(const PathBoundary &path_boundary, const ReferenceLine &reference_line, std::vector< std::pair< double, double > > *ddl_bounds)
calculate ddl bound by referenceline kappa and adc lat accleration
static FrenetFramePath ToPiecewiseJerkPath(const std::vector< double > &x, const std::vector< double > &dx, const std::vector< double > &ddx, const double delta_s, const double start_s)
Data format tramform from raw data to FrenetFramePath
static double EstimateJerkBoundary(const double vehicle_speed)
Calculation of jerk boundary based on vehicle kinematics model.
static bool OptimizePath(const SLState &init_state, const std::array< double, 3 > &end_state, std::vector< double > l_ref, std::vector< double > l_ref_weight, const PathBoundary &path_boundary, const std::vector< std::pair< double, double > > &ddl_bounds, double dddl_bound, const PiecewiseJerkPathConfig &config, std::vector< double > *x, std::vector< double > *dx, std::vector< double > *ddx)
Piecewise jerk path optimizer.
static void UpdatePathRefWithBound(const PathBoundary &path_boundary, double weight, std::vector< double > *ref_l, std::vector< double > *weight_ref_l)
If ref_l is below or above path boundary, will update its values and weights
ReferenceLineInfo holds all data for one reference line.
const ReferenceLine & reference_line() const
bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector) override
ReferenceLineInfo * reference_line_info_
Definition task.h:58
virtual bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector)
Definition task.cc:40
Planning module main class.
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
apollo::hdmap::Id MakeMapId(const std::string &id)
create a Map ID given a string.
Definition hdmap_util.h:85
std::pair< std::array< double, 3 >, std::array< double, 3 > > SLState
std::vector< PathBoundPoint > PathBound
class register implement
Definition arena_queue.h:37
optional PiecewiseJerkPathConfig path_optimizer_config