23#include "google/protobuf/repeated_field.h"
56 injector_->planning_context()->mutable_planning_status()->Clear();
62 if (!CheckPlanningConfig(config)) {
63 return Status(ErrorCode::PLANNING_ERROR,
64 "planning config error: " + config.DebugString());
73 injector_->planning_context()->mutable_planning_status()->Clear();
78 ErrorCode::PLANNING_ERROR,
79 "planning is not initialized with config : " +
config_.DebugString());
87Status NaviPlanning::InitFrame(
const uint32_t sequence_num,
91 vehicle_state, reference_line_provider_.get()));
93 std::list<ReferenceLine> reference_lines;
94 std::list<hdmap::RouteSegments> segments;
95 if (!reference_line_provider_->GetReferenceLines(&reference_lines,
97 const std::string msg =
"Failed to create reference line";
99 return Status(ErrorCode::PLANNING_ERROR, msg);
102 auto status =
frame_->Init(
103 injector_->vehicle_state(), reference_lines, segments,
104 reference_line_provider_->FutureRouteWaypoints(),
injector_->ego_info());
107 AERROR <<
"failed to init frame:" << status.ToString();
121 if (
config_.has_reference_line_config()) {
126 reference_line_provider_ = std::make_unique<ReferenceLineProvider>(
127 injector_->vehicle_state(), reference_line_config,
131 ADEBUG <<
"Get localization: "
140 auto vehicle_config =
143 if (last_vehicle_config_.is_valid_ && vehicle_config.is_valid_) {
144 auto x_diff_map = vehicle_config.x_ - last_vehicle_config_.x_;
145 auto y_diff_map = vehicle_config.y_ - last_vehicle_config_.y_;
147 auto cos_map_veh = std::cos(last_vehicle_config_.theta_);
148 auto sin_map_veh = std::sin(last_vehicle_config_.theta_);
150 auto x_diff_veh = cos_map_veh * x_diff_map + sin_map_veh * y_diff_map;
151 auto y_diff_veh = -sin_map_veh * x_diff_map + cos_map_veh * y_diff_map;
153 auto theta_diff = vehicle_config.theta_ - last_vehicle_config_.theta_;
158 last_vehicle_config_ = vehicle_config;
166 DCHECK_GE(start_timestamp, vehicle_state.
timestamp());
167 if (start_timestamp - vehicle_state.
timestamp() <
168 FLAGS_message_latency_threshold) {
169 auto future_xy =
injector_->vehicle_state()->EstimateFuturePosition(
170 start_timestamp - vehicle_state.
timestamp());
171 vehicle_state.set_x(future_xy.x());
172 vehicle_state.set_y(future_xy.y());
173 vehicle_state.set_timestamp(start_timestamp);
176 auto* not_ready = trajectory_pb->mutable_decision()
177 ->mutable_main_decision()
178 ->mutable_not_ready();
181 const std::string msg =
"Update VehicleStateProvider failed";
183 not_ready->set_reason(msg);
184 status.
Save(trajectory_pb->mutable_header()->mutable_status());
191 const double planning_cycle_time = 1.0 / FLAGS_planning_loop_rate;
193 std::vector<TrajectoryPoint> stitching_trajectory;
194 std::string replan_reason;
197 planning_cycle_time, FLAGS_trajectory_stitching_preserved_length,
true,
201 const uint32_t frame_num =
static_cast<uint32_t
>(
seq_num_++);
202 status = InitFrame(frame_num, stitching_trajectory.back(), vehicle_state);
205 const std::string msg =
"Failed to init frame";
207 not_ready->set_reason(msg);
208 status.
Save(trajectory_pb->mutable_header()->mutable_status());
215 injector_->ego_info()->Update(stitching_trajectory.back(), vehicle_state);
217 if (FLAGS_enable_record_debug) {
218 frame_->RecordInputDebug(trajectory_pb->mutable_debug());
220 trajectory_pb->mutable_latency_stats()->set_init_frame_time_ms(
224 if (FLAGS_publish_estop) {
230 EStop* estop = estop_trajectory.mutable_estop();
231 estop->set_is_estop(
true);
233 status.
Save(estop_trajectory.mutable_header()->mutable_status());
238 trajectory_pb->mutable_decision()
239 ->mutable_main_decision()
240 ->mutable_not_ready()
242 status.
Save(trajectory_pb->mutable_header()->mutable_status());
248 frame_->set_current_frame_planned_trajectory(*trajectory_pb);
249 auto seq_num =
frame_->SequenceNum();
256 if (FLAGS_enable_planning_pad_msg) {
257 const auto& pad_msg_driving_action =
frame_->GetPadMsgDrivingAction();
258 ProcessPadMsg(pad_msg_driving_action);
261 for (
auto& ref_line_info : *
frame_->mutable_reference_line_info()) {
262 auto traffic_status =
264 if (!traffic_status.ok() || !ref_line_info.IsDrivable()) {
265 ref_line_info.SetDrivable(
false);
266 AWARN <<
"Reference line " << ref_line_info.Lanes().Id()
267 <<
" traffic decider failed";
272 status =
Plan(start_timestamp, stitching_trajectory, trajectory_pb);
275 ADEBUG <<
"total planning time spend: " << time_diff_ms <<
" ms.";
277 trajectory_pb->mutable_latency_stats()->set_total_time_ms(time_diff_ms);
278 ADEBUG <<
"Planning latency: "
281 auto* ref_line_task =
282 trajectory_pb->mutable_latency_stats()->add_task_stats();
283 ref_line_task->set_time_ms(reference_line_provider_->LastTimeDelay() *
285 ref_line_task->set_name(
"ReferenceLineProvider");
288 status.
Save(trajectory_pb->mutable_header()->mutable_status());
290 if (FLAGS_publish_estop) {
291 AERROR <<
"Planning failed and set estop";
296 EStop* estop = trajectory_pb->mutable_estop();
297 estop->set_is_estop(
true);
302 trajectory_pb->set_is_replan(stitching_trajectory.size() == 1);
306 ADEBUG <<
"Planning pb:" << trajectory_pb->
header().DebugString();
308 auto seq_num =
frame_->SequenceNum();
313 if (FLAGS_use_navigation_mode) {
314 std::map<std::string, uint32_t> lane_id_to_priority;
315 auto& ref_line_info_group = *
frame_->mutable_reference_line_info();
317 using LaneInfoPair = std::pair<std::string, double>;
318 std::string current_lane_id;
319 switch (drvie_action) {
321 AINFO <<
"Received follow drive action";
322 std::string current_lane_id = GetCurrentLaneId();
323 if (!current_lane_id.empty()) {
324 target_lane_id_ = current_lane_id;
329 AINFO <<
"Received change left lane drive action";
330 std::vector<LaneInfoPair> lane_info_group;
331 GetLeftNeighborLanesInfo(&lane_info_group);
332 if (!lane_info_group.empty()) {
333 target_lane_id_ = lane_info_group.front().first;
338 AINFO <<
"Received change right lane drive action";
339 std::vector<LaneInfoPair> lane_info_group;
340 GetRightNeighborLanesInfo(&lane_info_group);
341 if (!lane_info_group.empty()) {
342 target_lane_id_ = lane_info_group.front().first;
347 AINFO <<
"Received pull over drive action";
352 AINFO <<
"Received stop drive action";
357 AWARN <<
"Received undefined drive action.";
363 if (!target_lane_id_.empty()) {
364 static constexpr uint32_t KTargetRefLinePriority = 0;
365 static constexpr uint32_t kOtherRefLinePriority = 10;
366 for (
auto& ref_line_info : ref_line_info_group) {
367 auto lane_id = ref_line_info.Lanes().Id();
368 ADEBUG <<
"lane_id : " << lane_id;
369 lane_id_to_priority[lane_id] = kOtherRefLinePriority;
370 if (lane_id == target_lane_id_) {
371 lane_id_to_priority[lane_id] = KTargetRefLinePriority;
372 ADEBUG <<
"target lane_id : " << lane_id;
375 frame_->UpdateReferenceLinePriority(lane_id_to_priority);
382std::string NaviPlanning::GetCurrentLaneId() {
383 auto& ref_line_info_group = *
frame_->mutable_reference_line_info();
384 const auto& vehicle_state =
frame_->vehicle_state();
385 common::math::Vec2d adc_position(vehicle_state.
x(), vehicle_state.
y());
386 std::string current_lane_id;
387 for (
auto& ref_line_info : ref_line_info_group) {
388 auto lane_id = ref_line_info.Lanes().Id();
389 auto& ref_line = ref_line_info.reference_line();
390 if (ref_line.IsOnLane(adc_position)) {
391 current_lane_id = lane_id;
394 return current_lane_id;
397void NaviPlanning::GetLeftNeighborLanesInfo(
398 std::vector<std::pair<std::string, double>>*
const lane_info_group) {
399 auto& ref_line_info_group = *
frame_->mutable_reference_line_info();
400 const auto& vehicle_state =
frame_->vehicle_state();
401 for (
auto& ref_line_info : ref_line_info_group) {
402 common::math::Vec2d adc_position(vehicle_state.
x(), vehicle_state.
y());
403 auto& ref_line = ref_line_info.reference_line();
404 if (ref_line.IsOnLane(adc_position)) {
407 auto lane_id = ref_line_info.Lanes().Id();
409 ref_line.GetReferencePoint(vehicle_state.
x(), vehicle_state.
y());
410 double y = ref_point.y();
413 lane_info_group->emplace_back(lane_id, y);
417 using LaneInfoPair = std::pair<std::string, double>;
418 std::sort(lane_info_group->begin(), lane_info_group->end(),
419 [](
const LaneInfoPair& left,
const LaneInfoPair& right) {
420 return left.second < right.second;
424void NaviPlanning::GetRightNeighborLanesInfo(
425 std::vector<std::pair<std::string, double>>*
const lane_info_group) {
426 auto& ref_line_info_group = *
frame_->mutable_reference_line_info();
427 const auto& vehicle_state =
frame_->vehicle_state();
428 for (
auto& ref_line_info : ref_line_info_group) {
429 common::math::Vec2d adc_position(vehicle_state.
x(), vehicle_state.
y());
430 auto& ref_line = ref_line_info.reference_line();
431 if (ref_line.IsOnLane(adc_position)) {
434 auto lane_id = ref_line_info.Lanes().Id();
436 ref_line.GetReferencePoint(vehicle_state.
x(), vehicle_state.
y());
437 double y = ref_point.y();
440 lane_info_group->emplace_back(lane_id, y);
445 using LaneInfoPair = std::pair<std::string, double>;
446 std::sort(lane_info_group->begin(), lane_info_group->end(),
447 [](
const LaneInfoPair& left,
const LaneInfoPair& right) {
448 return left.second > right.second;
452void NaviPlanning::ExportReferenceLineDebug(planning_internal::Debug* debug) {
453 if (!FLAGS_enable_record_debug) {
456 for (
auto& reference_line_info : *
frame_->mutable_reference_line_info()) {
457 auto rl_debug = debug->mutable_planning_data()->add_reference_line();
458 rl_debug->set_id(reference_line_info.Lanes().Id());
459 rl_debug->set_length(reference_line_info.reference_line().Length());
460 rl_debug->set_cost(reference_line_info.Cost());
461 rl_debug->set_is_change_lane_path(reference_line_info.IsChangeLanePath());
462 rl_debug->set_is_drivable(reference_line_info.IsDrivable());
463 rl_debug->set_is_protected(reference_line_info.GetRightOfWayStatus() ==
469 const double current_time_stamp,
470 const std::vector<TrajectoryPoint>& stitching_trajectory,
472 auto* ptr_debug = trajectory_pb->mutable_debug();
473 if (FLAGS_enable_record_debug) {
474 ptr_debug->mutable_planning_data()->mutable_init_point()->CopyFrom(
475 stitching_trajectory.back());
479 planner_->Plan(stitching_trajectory.back(),
frame_.get(), trajectory_pb);
481 ExportReferenceLineDebug(ptr_debug);
483 const auto* best_ref_info =
frame_->FindDriveReferenceLineInfo();
484 if (!best_ref_info) {
485 const std::string msg =
"planner failed to make a driving plan";
490 return Status(ErrorCode::PLANNING_ERROR, msg);
492 ptr_debug->MergeFrom(best_ref_info->debug());
493 trajectory_pb->mutable_latency_stats()->MergeFrom(
494 best_ref_info->latency_stats());
496 trajectory_pb->set_right_of_way_status(best_ref_info->GetRightOfWayStatus());
497 for (
const auto&
id : best_ref_info->TargetLaneId()) {
498 trajectory_pb->add_lane_id()->CopyFrom(
id);
501 best_ref_info->ExportDecision(trajectory_pb->mutable_decision(),
505 if (FLAGS_enable_record_debug) {
506 auto* reference_line = ptr_debug->mutable_planning_data()->add_path();
507 reference_line->set_name(
"planning_reference_line");
508 const auto& reference_points =
509 best_ref_info->reference_line().reference_points();
513 bool empty_path =
true;
514 for (
const auto& reference_point : reference_points) {
515 auto* path_point = reference_line->add_path_point();
516 path_point->set_x(reference_point.x());
517 path_point->set_y(reference_point.y());
518 path_point->set_theta(reference_point.heading());
519 path_point->set_kappa(reference_point.kappa());
520 path_point->set_dkappa(reference_point.dkappa());
522 path_point->set_s(0.0);
525 double dx = reference_point.x() - prev_x;
526 double dy = reference_point.y() - prev_y;
527 s += std::hypot(dx, dy);
528 path_point->set_s(s);
530 prev_x = reference_point.x();
531 prev_y = reference_point.y();
536 current_time_stamp, best_ref_info->trajectory()));
538 ADEBUG <<
"current_time_stamp: " << current_time_stamp;
554 FLAGS_trajectory_time_high_density_period) {
563 best_ref_info->ExportEngageAdvice(trajectory_pb->mutable_engage_advice(),
578NaviPlanning::VehicleConfig NaviPlanning::ComputeVehicleConfigFromLocalization(
580 NaviPlanning::VehicleConfig vehicle_config;
582 if (!localization.
pose().has_position()) {
583 return vehicle_config;
591 if (localization.
pose().has_heading()) {
592 vehicle_config.theta_ = localization.
pose().
heading();
595 orientation.qw(), orientation.qx(), orientation.qy(), orientation.qz());
598 vehicle_config.is_valid_ =
true;
599 return vehicle_config;
602bool NaviPlanning::CheckPlanningConfig(
const PlanningConfig& config) {
A general class to denote the return status of an API call.
bool ok() const
check whether the return status is OK.
const std::string & error_message() const
returns the error message of the status, empty if the status is OK.
std::string ToString() const
returns a string representation in a readable format.
void Save(StatusPb *status_pb)
save the error_code and error message to protobuf
static Status OK()
generate a success status.
The class of vehicle state.
a singleton clock that can be used to get the current timestamp.
static double NowInSeconds()
gets the current time in second.
static const HDMap * BaseMapPtr()
Frame holds all data for one planning cycle.
apollo::common::Status Init(const PlanningConfig &config) override
module initialization function
std::string Name() const override
Planning algorithm name.
void RunOnce(const LocalView &local_view, ADCTrajectory *const trajectory_pb) override
main logic of the planning module, runs periodically triggered by timer.
apollo::common::Status Plan(const double current_time_stamp, const std::vector< common::TrajectoryPoint > &stitching_trajectory, ADCTrajectory *const trajectory) override
Plan the trajectory given current vehicle state
virtual apollo::common::Status Init(const PlanningConfig &config)
std::unique_ptr< Frame > frame_
virtual void FillPlanningPb(const double timestamp, ADCTrajectory *const trajectory_pb)
TrafficDecider traffic_decider_
std::unique_ptr< PublishableTrajectory > last_publishable_trajectory_
const hdmap::HDMap * hdmap_
std::shared_ptr< Planner > planner_
std::shared_ptr< DependencyInjector > injector_
apollo::common::Status Execute(Frame *frame, ReferenceLineInfo *reference_line_info)
bool Init(const std::shared_ptr< DependencyInjector > &injector)
static std::vector< common::TrajectoryPoint > ComputeStitchingTrajectory(const canbus::Chassis &vehicle_chassis, const common::VehicleState &vehicle_state, const double current_timestamp, const double planning_cycle_time, const size_t preserved_points_num, const bool replan_by_offset, const PublishableTrajectory *prev_trajectory, std::string *replan_reason, const control::ControlInteractiveMsg &control_interactive_msg)
static void TransformLastPublishedTrajectory(const double x_diff, const double y_diff, const double theta_diff, PublishableTrajectory *prev_trajectory)
Planning module main class.
double QuaternionToHeading(const double qw, const double qx, const double qy, const double qz)
bool IsVehicleStateValid(const VehicleState &vehicle_state)
Contains a number of helper functions related to quaternions.
Declaration of the class ReferenceLineProvider.
optional double timestamp
optional apollo::localization::Pose pose
optional apollo::common::Quaternion orientation
optional apollo::common::PointENU position
optional LatencyStats latency_stats
optional apollo::common::Header header
std::shared_ptr< localization::LocalizationEstimate > localization_estimate
std::shared_ptr< relative_map::MapMsg > relative_map
std::shared_ptr< control::ControlInteractiveMsg > control_interactive_msg
std::shared_ptr< canbus::Chassis > chassis
optional ReferenceLineConfig reference_line_config
LocalView contains all necessary data as planning input