Apollo 11.0
自动驾驶开放平台
stage_pre_stop.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 <algorithm>
24#include <utility>
25
26#include "modules/common_msgs/perception_msgs/perception_obstacle.pb.h"
27
28#include "cyber/common/log.h"
29#include "cyber/time/clock.h"
38
39namespace apollo {
40namespace planning {
41
49
51 std::unordered_map<std::string, std::vector<std::string>>;
52
54 const TrajectoryPoint& planning_init_point, Frame* frame) {
55 ADEBUG << "stage: PreStop";
56 CHECK_NOTNULL(frame);
57 CHECK_NOTNULL(context_);
58
59 StageResult result = ExecuteTaskOnReferenceLine(planning_init_point, frame);
60 if (result.HasError()) {
61 AERROR << "StopSignUnprotectedStagePreStop planning error";
62 }
63
64 const auto& reference_line_info = frame->reference_line_info().front();
65 auto context = GetContextAs<StopSignUnprotectedContext>();
66 std::string stop_sign_overlap_id = context->current_stop_sign_overlap_id;
67
68 // get overlap along reference line
69 PathOverlap* current_stop_sign_overlap =
70 reference_line_info.GetOverlapOnReferenceLine(
71 stop_sign_overlap_id, ReferenceLineInfo::STOP_SIGN);
72 if (!current_stop_sign_overlap) {
73 return FinishScenario();
74 }
75
76 static constexpr double kPassStopLineBuffer = 0.3; // unit: m
77 const double adc_front_edge_s = reference_line_info.AdcSlBoundary().end_s();
78 const double distance_adc_pass_stop_sign =
79 adc_front_edge_s - current_stop_sign_overlap->start_s;
80 if (distance_adc_pass_stop_sign <= kPassStopLineBuffer) {
81 // not passed stop line, check valid stop
82 if (CheckADCStop(adc_front_edge_s, current_stop_sign_overlap->start_s)) {
83 return FinishStage();
84 }
85 } else {
86 // passed stop line
87 return FinishStage();
88 }
89
90 // PRE-STOP
91 const PathDecision& path_decision = reference_line_info.path_decision();
92 auto& watch_vehicles = context->watch_vehicles;
93
94 std::vector<std::string> watch_vehicle_ids;
95 for (const auto& vehicle : watch_vehicles) {
96 std::copy(vehicle.second.begin(), vehicle.second.end(),
97 std::back_inserter(watch_vehicle_ids));
98
99 // for debug string
100 std::string associated_lane_id = vehicle.first;
101 std::string s;
102 for (const std::string& vehicle_id : vehicle.second) {
103 s = s.empty() ? vehicle_id : s + "," + vehicle_id;
104 }
105 ADEBUG << "watch_vehicles: lane_id[" << associated_lane_id << "] vehicle["
106 << s << "]";
107 }
108
109 // pass vehicles being watched to DECIDER_RULE_BASED_STOP task
110 // for visualization
111 for (const auto& perception_obstacle_id : watch_vehicle_ids) {
112 injector_->planning_context()
113 ->mutable_planning_status()
114 ->mutable_stop_sign()
115 ->add_wait_for_obstacle_id(perception_obstacle_id);
116 }
117
118 for (const auto* obstacle : path_decision.obstacles().Items()) {
119 // add to watch_vehicles if adc is still proceeding to stop sign
120 AddWatchVehicle(*obstacle, &watch_vehicles);
121 }
122
124}
125
129int StopSignUnprotectedStagePreStop::AddWatchVehicle(
130 const Obstacle& obstacle, StopSignLaneVehicles* watch_vehicles) {
131 CHECK_NOTNULL(watch_vehicles);
132
133 const PerceptionObstacle& perception_obstacle = obstacle.Perception();
134 const std::string& perception_obstacle_id =
135 std::to_string(perception_obstacle.id());
136 PerceptionObstacle::Type obstacle_type = perception_obstacle.type();
137 std::string obstacle_type_name = PerceptionObstacle_Type_Name(obstacle_type);
138
139 // check type
140 if (obstacle_type != PerceptionObstacle::UNKNOWN &&
141 obstacle_type != PerceptionObstacle::UNKNOWN_MOVABLE &&
142 obstacle_type != PerceptionObstacle::BICYCLE &&
143 obstacle_type != PerceptionObstacle::VEHICLE) {
144 ADEBUG << "obstacle_id[" << perception_obstacle_id << "] type["
145 << obstacle_type_name << "]. skip";
146 return 0;
147 }
148
149 const auto point =
151 double obstacle_s = 0.0;
152 double obstacle_l = 0.0;
153 LaneInfoConstPtr obstacle_lane;
154 if (HDMapUtil::BaseMap().GetNearestLaneWithHeading(
155 point, 5.0, perception_obstacle.theta(), M_PI / 3.0, &obstacle_lane,
156 &obstacle_s, &obstacle_l) != 0) {
157 ADEBUG << "obstacle_id[" << perception_obstacle_id << "] type["
158 << obstacle_type_name
159 << "]: Failed to find nearest lane from map for position: "
160 << point.DebugString() << "; heading[" << perception_obstacle.theta()
161 << "]";
162 return -1;
163 }
164 if (!obstacle_lane->IsOnLane(common::util::PointFactory::ToVec2d(
165 perception_obstacle.position()))) {
166 ADEBUG << "obstacle_id[" << perception_obstacle_id << "] type["
167 << obstacle_type_name << "]: is off road. " << point.DebugString()
168 << "; heading[" << perception_obstacle.theta() << "]";
169 return -1;
170 }
171
172 // check obstacle is on an associate lane guarded by stop sign
173 std::string obstable_lane_id = obstacle_lane.get()->id().id();
174 auto context = GetContextAs<StopSignUnprotectedContext>();
175 auto assoc_lane_it = std::find_if(
176 context->associated_lanes.begin(), context->associated_lanes.end(),
177 [&obstable_lane_id](
178 std::pair<LaneInfoConstPtr, OverlapInfoConstPtr>& assc_lane) {
179 return assc_lane.first.get()->id().id() == obstable_lane_id;
180 });
181 if (assoc_lane_it == context->associated_lanes.end()) {
182 ADEBUG << "obstacle_id[" << perception_obstacle_id << "] type["
183 << obstacle_type_name << "] lane_id[" << obstable_lane_id
184 << "] not associated with current stop_sign. skip";
185 return -1;
186 }
187
188 // check a valid stop for stop line of the stop_sign
189 auto over_lap_info = assoc_lane_it->second.get()->GetObjectOverlapInfo(
190 obstacle_lane.get()->id());
191 if (over_lap_info == nullptr) {
192 AERROR << "can't find over_lap_info for id: " << obstable_lane_id;
193 return -1;
194 }
195 const double stop_line_s = over_lap_info->lane_overlap_info().start_s();
196 const double obstacle_end_s = obstacle_s + perception_obstacle.length() / 2;
197 const double distance_to_stop_line = stop_line_s - obstacle_end_s;
198 if (distance_to_stop_line >
199 GetContextAs<StopSignUnprotectedContext>()
200 ->scenario_config.watch_vehicle_max_valid_stop_distance()) {
201 ADEBUG << "obstacle_id[" << perception_obstacle_id << "] type["
202 << obstacle_type_name << "] distance_to_stop_line["
203 << distance_to_stop_line << "]; stop_line_s" << stop_line_s
204 << "]; obstacle_end_s[" << obstacle_end_s
205 << "] too far from stop line. skip";
206 return -1;
207 }
208
209 // use a vector since motocycles/bicycles can be more than one
210 std::vector<std::string> vehicles =
211 (*watch_vehicles)[obstacle_lane->id().id()];
212 if (std::find(vehicles.begin(), vehicles.end(), perception_obstacle_id) ==
213 vehicles.end()) {
214 ADEBUG << "AddWatchVehicle: lane[" << obstacle_lane->id().id()
215 << "] obstacle_id[" << perception_obstacle_id << "]";
216 (*watch_vehicles)[obstacle_lane->id().id()].push_back(
217 perception_obstacle_id);
218 }
219
220 return 0;
221}
222
226bool StopSignUnprotectedStagePreStop::CheckADCStop(
227 const double adc_front_edge_s, const double stop_line_s) {
228 const double adc_speed = injector_->vehicle_state()->linear_velocity();
229 const double max_adc_stop_speed = common::VehicleConfigHelper::Instance()
230 ->GetConfig()
231 .vehicle_param()
232 .max_abs_speed_when_stopped();
233 if (adc_speed > max_adc_stop_speed) {
234 ADEBUG << "ADC not stopped: speed[" << adc_speed << "]";
235 return false;
236 }
237
238 // check stop close enough to stop line of the stop_sign
239 const double distance_stop_line_to_adc_front_edge =
240 stop_line_s - adc_front_edge_s;
241 ADEBUG << "distance_stop_line_to_adc_front_edge["
242 << distance_stop_line_to_adc_front_edge << "]";
243
244 if (distance_stop_line_to_adc_front_edge >
245 GetContextAs<StopSignUnprotectedContext>()
246 ->scenario_config.max_valid_stop_distance()) {
247 ADEBUG << "not a valid stop. too far from stop line.";
248 return false;
249 }
250
251 // TODO(all): check no BICYCLE in between.
252
253 return true;
254}
255
256StageResult StopSignUnprotectedStagePreStop::FinishStage() {
257 auto scenario_context = GetContextAs<StopSignUnprotectedContext>();
258 scenario_context->stop_start_time = Clock::NowInSeconds();
259 next_stage_ = "STOP_SIGN_UNPROTECTED_STOP";
260
261 return StageResult(StageStatusType::FINISHED);
262}
263
264} // namespace planning
265} // namespace apollo
static math::Vec2d ToVec2d(const XY &xy)
static PointENU ToPointENU(const double x, const double y, const double z=0)
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 const HDMap & BaseMap()
Frame holds all data for one planning cycle.
Definition frame.h:62
const std::list< ReferenceLineInfo > & reference_line_info() const
Definition frame.cc:123
const std::vector< const T * > & Items() const
List all the items in the container.
This is the class that associates an Obstacle with its path properties.
Definition obstacle.h:62
const perception::PerceptionObstacle & Perception() const
Definition obstacle.h:102
PathDecision represents all obstacle decisions on one path.
const IndexedList< std::string, Obstacle > & obstacles() const
const StageResult & SetStageStatus(const StageStatusType &stage_status)
Set the stage status.
bool HasError() const
Check if StageResult contains error.
std::string next_stage_
Definition stage.h:89
virtual StageResult FinishScenario()
Definition stage.cc:258
std::shared_ptr< DependencyInjector > injector_
Definition stage.h:91
StageResult ExecuteTaskOnReferenceLine(const common::TrajectoryPoint &planning_start_point, Frame *frame)
Definition stage.cc:101
StageResult Process(const common::TrajectoryPoint &planning_init_point, Frame *frame) override
Each stage does its business logic inside Process function.
Planning module main class.
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
std::shared_ptr< const LaneInfo > LaneInfoConstPtr
std::shared_ptr< const OverlapInfo > OverlapInfoConstPtr
std::unordered_map< std::string, std::vector< std::string > > StopSignLaneVehicles
class register implement
Definition arena_queue.h:37
optional apollo::common::Point3D position