Apollo 11.0
自动驾驶开放平台
lane_follow_stage.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
22
23#include <utility>
24
25#include "cyber/common/log.h"
26#include "cyber/time/clock.h"
39
40namespace apollo {
41namespace planning {
42
49
50namespace {
51constexpr double kStraightForwardLineCost = 10.0;
52} // namespace
53
55 ReferenceLineInfo* reference_line_info) {
56 if (!FLAGS_enable_record_debug) {
57 ADEBUG << "Skip record debug info";
58 return;
59 }
60 auto ptr_debug = reference_line_info->mutable_debug();
61
62 const auto path_decision = reference_line_info->path_decision();
63 for (const auto obstacle : path_decision->obstacles().Items()) {
64 auto obstacle_debug = ptr_debug->mutable_planning_data()->add_obstacle();
65 obstacle_debug->set_id(obstacle->Id());
66 obstacle_debug->mutable_sl_boundary()->CopyFrom(
67 obstacle->PerceptionSLBoundary());
68 const auto& decider_tags = obstacle->decider_tags();
69 const auto& decisions = obstacle->decisions();
70 if (decider_tags.size() != decisions.size()) {
71 AERROR << "decider_tags size: " << decider_tags.size()
72 << " different from decisions size:" << decisions.size();
73 }
74 for (size_t i = 0; i < decider_tags.size(); ++i) {
75 auto decision_tag = obstacle_debug->add_decision_tag();
76 decision_tag->set_decider_tag(decider_tags[i]);
77 decision_tag->mutable_decision()->CopyFrom(decisions[i]);
78 }
79 }
80}
81
83 const TrajectoryPoint& planning_start_point, Frame* frame) {
84 if (frame->reference_line_info().empty()) {
86 }
87
88 bool has_drivable_reference_line = false;
89
90 ADEBUG << "Number of reference lines:\t"
91 << frame->mutable_reference_line_info()->size();
92
93 unsigned int count = 0;
94 StageResult result;
95 for (auto& reference_line_info : *frame->mutable_reference_line_info()) {
96 // TODO(SHU): need refactor
97 if (count++ == frame->mutable_reference_line_info()->size()) {
98 break;
99 }
100 ADEBUG << "No: [" << count << "] Reference Line.";
101 ADEBUG << "IsChangeLanePath: " << reference_line_info.IsChangeLanePath();
102
103 if (has_drivable_reference_line) {
104 reference_line_info.SetDrivable(false);
105 break;
106 }
107
108 result =
109 PlanOnReferenceLine(planning_start_point, frame, &reference_line_info);
110
111 if (!result.HasError()) {
112 if (!reference_line_info.IsChangeLanePath()) {
113 ADEBUG << "reference line is NOT lane change ref.";
114 has_drivable_reference_line = true;
115 continue;
116 }
117 if (reference_line_info.Cost() < kStraightForwardLineCost) {
118 // If the path and speed optimization succeed on target lane while
119 // under smart lane-change or IsClearToChangeLane under older version
120 has_drivable_reference_line = true;
121 reference_line_info.SetDrivable(true);
122 } else {
123 reference_line_info.SetDrivable(false);
124 ADEBUG << "\tlane change failed";
125 }
126 } else {
127 reference_line_info.SetDrivable(false);
128 }
129 }
130
131 return has_drivable_reference_line
134}
135
137 const TrajectoryPoint& planning_start_point, Frame* frame,
138 ReferenceLineInfo* reference_line_info) {
139 if (!reference_line_info->IsChangeLanePath()) {
140 reference_line_info->AddCost(kStraightForwardLineCost);
141 }
142 ADEBUG << "planning start point:" << planning_start_point.DebugString();
143 ADEBUG << "Current reference_line_info is IsChangeLanePath: "
144 << reference_line_info->IsChangeLanePath();
145
146 StageResult ret;
147 for (auto task : task_list_) {
148 const double start_timestamp = Clock::NowInSeconds();
149 const auto start_planning_perf_timestamp =
150 std::chrono::duration<double>(
151 std::chrono::system_clock::now().time_since_epoch())
152 .count();
153
154 ret.SetTaskStatus(task->Execute(frame, reference_line_info));
155
156 const double end_timestamp = Clock::NowInSeconds();
157 const double time_diff_ms = (end_timestamp - start_timestamp) * 1000;
158 ADEBUG << "after task[" << task->Name()
159 << "]:" << reference_line_info->PathSpeedDebugString();
160 ADEBUG << task->Name() << " time spend: " << time_diff_ms << " ms.";
161 RecordDebugInfo(reference_line_info, task->Name(), time_diff_ms);
162
163 const auto end_planning_perf_timestamp =
164 std::chrono::duration<double>(
165 std::chrono::system_clock::now().time_since_epoch())
166 .count();
167 const auto plnning_perf_ms =
168 (end_planning_perf_timestamp - start_planning_perf_timestamp) * 1000;
169 AINFO << "Planning Perf: task name [" << task->Name() << "], "
170 << plnning_perf_ms << " ms.";
171
172 if (ret.IsTaskError()) {
173 AERROR << "Failed to run tasks[" << task->Name()
174 << "], Error message: " << ret.GetTaskStatus().error_message();
175 break;
176 }
177
178 // TODO(SHU): disable reference line order changes for now
179 // updated reference_line_info, because it is changed in
180 // lane_change_decider by PrioritizeChangeLane().
181 // reference_line_info = &frame->mutable_reference_line_info()->front();
182 // ADEBUG << "Current reference_line_info is IsChangeLanePath: "
183 // << reference_line_info->IsChangeLanePath();
184 }
185
186 RecordObstacleDebugInfo(reference_line_info);
187
188 // check path and speed results for path or speed fallback
189 reference_line_info->set_trajectory_type(ADCTrajectory::NORMAL);
190 if (ret.IsTaskError()) {
191 fallback_task_->Execute(frame, reference_line_info);
192 }
193
194 DiscretizedTrajectory trajectory;
195 if (!reference_line_info->CombinePathAndSpeedProfile(
196 planning_start_point.relative_time(),
197 planning_start_point.path_point().s(), &trajectory)) {
198 const std::string msg = "Fail to aggregate planning trajectory.";
199 AERROR << msg;
200 return ret.SetStageStatus(StageStatusType::ERROR, msg);
201 }
202
203 // determine if there is a destination on reference line.
204 double dest_stop_s = -1.0;
205 for (const auto* obstacle :
206 reference_line_info->path_decision()->obstacles().Items()) {
207 if (obstacle->LongitudinalDecision().has_stop() &&
208 obstacle->LongitudinalDecision().stop().reason_code() ==
209 STOP_REASON_DESTINATION) {
210 SLPoint dest_sl = GetStopSL(obstacle->LongitudinalDecision().stop(),
211 reference_line_info->reference_line());
212 dest_stop_s = dest_sl.s();
213 }
214 }
215
216 for (const auto* obstacle :
217 reference_line_info->path_decision()->obstacles().Items()) {
218 if (obstacle->IsVirtual()) {
219 continue;
220 }
221 if (!obstacle->IsStatic()) {
222 continue;
223 }
224 if (obstacle->LongitudinalDecision().has_stop()) {
225 bool add_stop_obstacle_cost = false;
226 if (dest_stop_s < 0.0) {
227 add_stop_obstacle_cost = true;
228 } else {
229 SLPoint stop_sl = GetStopSL(obstacle->LongitudinalDecision().stop(),
230 reference_line_info->reference_line());
231 if (stop_sl.s() < dest_stop_s &&
232 (dest_stop_s - reference_line_info->AdcSlBoundary().end_s()) <
233 20.0) {
234 add_stop_obstacle_cost = true;
235 }
236 }
237 if (add_stop_obstacle_cost) {
238 static constexpr double kReferenceLineStaticObsCost = 1e3;
239 reference_line_info->AddCost(kReferenceLineStaticObsCost);
240 }
241 }
242 }
243
244 if (FLAGS_enable_trajectory_check) {
245 if (ConstraintChecker::ValidTrajectory(trajectory) !=
247 const std::string msg = "Current planning trajectory is not valid.";
248 AERROR << msg;
249 return ret.SetStageStatus(StageStatusType::ERROR, msg);
250 }
251 }
252
253 reference_line_info->SetTrajectory(trajectory);
254 reference_line_info->SetDrivable(true);
256 return ret;
257}
258
259SLPoint LaneFollowStage::GetStopSL(const ObjectStop& stop_decision,
260 const ReferenceLine& reference_line) const {
261 SLPoint sl_point;
262 reference_line.XYToSL(stop_decision.stop_point(), &sl_point);
263 return sl_point;
264}
265
266} // namespace planning
267} // namespace apollo
A general class to denote the return status of an API call.
Definition status.h:43
const std::string & error_message() const
returns the error message of the status, empty if the status is OK.
Definition status.h:91
a singleton clock that can be used to get the current timestamp.
Definition clock.h:39
static double NowInSeconds()
gets the current time in second.
Definition clock.cc:56
static Result ValidTrajectory(const DiscretizedTrajectory &trajectory)
Frame holds all data for one planning cycle.
Definition frame.h:62
const std::list< ReferenceLineInfo > & reference_line_info() const
Definition frame.cc:123
std::list< ReferenceLineInfo > * mutable_reference_line_info()
Definition frame.cc:127
const std::vector< const T * > & Items() const
List all the items in the container.
StageResult PlanOnReferenceLine(const common::TrajectoryPoint &planning_start_point, Frame *frame, ReferenceLineInfo *reference_line_info)
StageResult Process(const common::TrajectoryPoint &planning_init_point, Frame *frame) override
Each stage does its business logic inside Process function.
void RecordObstacleDebugInfo(ReferenceLineInfo *reference_line_info)
common::SLPoint GetStopSL(const ObjectStop &stop_decision, const ReferenceLine &reference_line) const
const IndexedList< std::string, Obstacle > & obstacles() const
ReferenceLineInfo holds all data for one reference line.
void SetTrajectory(const DiscretizedTrajectory &trajectory)
void set_trajectory_type(const ADCTrajectory::TrajectoryType trajectory_type)
void SetDrivable(bool drivable)
Set if the vehicle can drive following this reference line A planner need to set this value to true i...
bool CombinePathAndSpeedProfile(const double relative_time, const double start_s, DiscretizedTrajectory *discretized_trajectory)
const ReferenceLine & reference_line() const
planning_internal::Debug * mutable_debug()
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.
const StageResult & SetStageStatus(const StageStatusType &stage_status)
Set the stage status.
bool HasError() const
Check if StageResult contains error.
const StageResult & SetTaskStatus(const common::Status &status)
Set the task execution result.
const common::Status & GetTaskStatus() const
Get the task execution result.
void RecordDebugInfo(ReferenceLineInfo *reference_line_info, const std::string &name, const double time_diff_ms)
Definition stage.cc:263
std::shared_ptr< Task > fallback_task_
Definition stage.h:88
std::vector< std::shared_ptr< Task > > task_list_
Definition stage.h:87
Planning module main class.
Math-related util functions.
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
class register implement
Definition arena_queue.h:37
Some string util functions.