39 const std::string& config_dir,
40 const std::string& name,
41 const std::shared_ptr<DependencyInjector>& injector) {
43 AINFO <<
"Failed to initialize task";
47 if (!Task::LoadConfig<ReversePathConfig>(&config_)) {
48 AINFO <<
"Failed to load config";
51 AINFO <<
"ReversePath config: " << config_.DebugString();
59 AERROR <<
"not in square junction";
62 PathBoundary path_boundary;
67 static constexpr double kEpsilon = 0.1;
68 double reference_line_backward_length =
init_sl_state_.first[0] - reference_line_backward_s - kEpsilon;
69 if (!DecidePathBounds(&path_boundary, reference_line_backward_length)) {
70 AERROR <<
"Decide path bound failed";
73 if (!OptimizePathOsqp(path_boundary, &path_data)) {
74 AERROR <<
"Optimize path failed";
87bool ReversePath::DecidePathBounds(PathBoundary* boundary,
double& reference_line_backward_length) {
88 if (!InitPathBoundary(boundary,
init_sl_state_, reference_line_backward_length)) {
89 const std::string msg =
"Failed to initialize path boundaries.";
97 AERROR <<
"Get boundary from self lane failed";
103 AINFO <<
"init l out of range" <<
init_sl_state_.second[0] << boundary->at(0).l_lower.l <<
","
104 << boundary->at(0).l_upper.l;
106 AERROR <<
"Failed to decide a rough boundary based on adc.";
109 AINFO <<
"extend boundary by adc";
111 boundary->set_label(
"reverse_path");
116bool ReversePath::OptimizePath(PathBoundary* path_boundary, PathData* candidate_path_data) {
117 double delta_s = path_boundary->delta_s();
118 double start_s = path_boundary->at(0).s;
119 size_t path_boundary_size = path_boundary->boundary().size();
120 FrenetFramePath frenet_frame_path;
121 std::vector<double> opt_l, opt_dl, opt_ddl;
122 opt_l.resize(path_boundary_size, 0.0);
124 opt_ddl.resize(path_boundary_size, 0.0);
125 for (
size_t i = 0; i < path_boundary_size; i++) {
127 if (cur_l > path_boundary->at(i).l_upper.l || cur_l < path_boundary->at(i).l_lower.l) {
128 AINFO <<
"trim the path" << cur_l <<
"," << path_boundary->delta_s() * i;
131 common::FrenetFramePoint frenet_frame_point;
132 frenet_frame_point.set_s(delta_s * i + start_s);
133 frenet_frame_point.set_l(cur_l);
135 frenet_frame_point.set_ddl(0);
136 frenet_frame_path.push_back(std::move(frenet_frame_point));
138 if (path_boundary_size <= 1U) {
139 AERROR <<
"Get invalid path boundary with size: " << path_boundary_size;
143 candidate_path_data->SetFrenetPath(frenet_frame_path);
144 candidate_path_data->set_is_reverse_path(
true);
145 candidate_path_data->set_path_label(
"reverse_path");
149bool ReversePath::OptimizePathOsqp(PathBoundary& path_boundary, PathData* candidate_path_data) {
152 std::array<double, 3> end_state = {0.0, 0.0, 0.0};
153 size_t path_boundary_size = path_boundary.boundary().size();
154 if (path_boundary_size <= 1U) {
155 AERROR <<
"Get invalid path boundary with size: " << path_boundary_size;
158 std::vector<double> opt_l, opt_dl, opt_ddl;
159 std::vector<std::pair<double, double>> ddl_bounds;
161 std::for_each(ddl_bounds.begin(), ddl_bounds.end(),
162 [](std::pair<double, double>& bound) {
163 double temp = bound.first;
164 bound.first = -bound.second;
165 bound.second = -temp;
167 PrintCurves print_debug;
168 for (
size_t i = 0; i < path_boundary_size; ++i) {
169 double s =
static_cast<double>(i) * path_boundary.delta_s() + path_boundary.start_s();
170 double kappa = reference_line.GetNearestReferencePoint(s).kappa();
171 print_debug.AddPoint(
"ref_kappa", s, kappa);
173 print_debug.PrintToLog();
175 std::vector<double> ref_l(path_boundary_size, 0);
176 std::vector<double> weight_ref_l(path_boundary_size, 0);
179 path_boundary.set_delta_s(0.1);
181 reverse_init_sl_state.second[1] = -reverse_init_sl_state.second[1];
182 reverse_init_sl_state.second[2] = -reverse_init_sl_state.second[2];
184 reverse_init_sl_state,
197 opt_l, opt_dl, opt_ddl, path_boundary.delta_s(), path_boundary.start_s());
199 double frenet_delta_s = 0.0;
200 for (
auto& point : frenet_frame_path) {
201 frenet_delta_s = point.s() - path_boundary.start_s();
202 AINFO << point.dl() <<
"," << point.ddl();
203 point.set_s(path_boundary.start_s() - frenet_delta_s);
204 point.set_dl(-point.dl());
205 point.set_ddl(-point.ddl());
206 AINFO << point.dl() <<
"," << point.ddl();
209 path_data.SetReferenceLine(&reference_line);
210 path_data.SetFrenetPath(std::move(frenet_frame_path));
211 if (FLAGS_use_front_axe_center_in_path_planning) {
212 auto discretized_path
214 path_data.SetDiscretizedPath(discretized_path);
216 path_data.set_path_label(path_boundary.label());
217 path_data.set_blocking_obstacle_id(path_boundary.blocking_obstacle_id());
218 path_data.set_is_reverse_path(
true);
219 *candidate_path_data = std::move(path_data);
221 path_boundary.set_delta_s(-0.1);
225bool ReversePath::GetBoundaryFromSquare(
226 const ReferenceLineInfo& reference_line_info,
227 PathBoundary*
const path_boundary,
228 const SLState& init_sl_state) {
231 const auto& junction_polygon = junction->polygon();
232 const auto& reference_line = reference_line_info.reference_line();
233 SLBoundary sl_boundary;
234 reference_line.GetSLBoundary(junction_polygon, &sl_boundary);
235 SLPolygon sl_polygon(sl_boundary, junction_overlap_.
object_id);
237 for (
size_t i = 0; i < path_boundary->size(); i++) {
238 auto& point = path_boundary->at(i);
239 if (point.s < sl_polygon.MinS() || point.s > sl_polygon.MaxS()) {
242 double l_min = sl_polygon.GetRightBoundaryByS(point.s);
243 double l_max = sl_polygon.GetLeftBoundaryByS(point.s);
246 if (point.l_lower.l > l_min) {
247 point.l_lower.l = l_min;
250 if (point.l_upper.l < l_max) {
251 point.l_upper.l = l_max;
258bool ReversePath::InitPathBoundary(
259 PathBoundary*
const path_bound,
261 double& reference_line_backward_length) {
263 CHECK_NOTNULL(path_bound);
265 path_bound->set_delta_s(-0.1);
266 double delta_s = path_bound->delta_s();
267 double end_s = init_sl_state.first[0] - std::min(config_.
max_s_distance(), reference_line_backward_length);
268 for (
double curr_s = init_sl_state.first[0]; curr_s > end_s; curr_s += delta_s) {
272 if (path_bound->empty()) {
273 AERROR <<
"Empty path boundary in InitPathBoundary";
A general class to denote the return status of an API call.
static Status OK()
generate a success status.
@Brief This is a helper class that can load vehicle configurations.
static const HDMap * BaseMapPtr()
const std::vector< double > & accumulated_s() const
Frame holds all data for one planning cycle.
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 ExtendBoundaryByADC(const ReferenceLineInfo &reference_line_info, const SLState &init_sl_state, const double extend_buffer, PathBoundary *const path_bound)
extend boundary to include adc
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.
int GetJunction(const double s, hdmap::PathOverlap *junction_overlap) const
const ReferenceLine & reference_line() const
PathData * mutable_path_data()
const hdmap::Path & GetMapPath() const
bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector) override
ReferenceLineInfo * reference_line_info_
virtual bool Init(const std::string &config_dir, const std::string &name, const std::shared_ptr< DependencyInjector > &injector)
Planning module main class.
apollo::hdmap::Id MakeMapId(const std::string &id)
create a Map ID given a string.
std::pair< std::array< double, 3 >, std::array< double, 3 > > SLState
optional double max_lateral_distance
optional PiecewiseJerkPathConfig path_optimizer_config
optional double max_s_distance
optional bool is_considered_square_boundary
optional bool is_considered_lane_boundary