Apollo 11.0
自动驾驶开放平台
on_lane_planning.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
18
19#include <algorithm>
20#include <limits>
21#include <list>
22#include <utility>
23
24#include "gtest/gtest_prod.h"
25
26#include "absl/strings/str_cat.h"
27
28#include "modules/common_msgs/planning_msgs/planning_internal.pb.h"
29#include "modules/common_msgs/routing_msgs/routing.pb.h"
30#include "modules/planning/planning_base/proto/planning_semantic_map_config.pb.h"
31
32#include "cyber/common/file.h"
33#include "cyber/common/log.h"
34#include "cyber/time/clock.h"
49
50namespace apollo {
51namespace planning {
66void SetChartminmax(apollo::dreamview::Chart* chart, std::string label_name_x,
67 std::string label_name_y) {
68 auto* options = chart->mutable_options();
69 double xmin(std::numeric_limits<double>::max()),
70 xmax(std::numeric_limits<double>::lowest()),
71 ymin(std::numeric_limits<double>::max()),
72 ymax(std::numeric_limits<double>::lowest());
73 for (int i = 0; i < chart->line_size(); i++) {
74 auto* line = chart->mutable_line(i);
75 for (auto& pt : line->point()) {
76 xmin = std::min(xmin, pt.x());
77 ymin = std::min(ymin, pt.y());
78 xmax = std::max(xmax, pt.x());
79 ymax = std::max(ymax, pt.y());
80 }
81 auto* properties = line->mutable_properties();
82 (*properties)["borderWidth"] = "2";
83 (*properties)["pointRadius"] = "0";
84 (*properties)["lineTension"] = "0";
85 (*properties)["fill"] = "false";
86 (*properties)["showLine"] = "true";
87 }
88 options->mutable_x()->set_min(xmin);
89 options->mutable_x()->set_max(xmax);
90 options->mutable_x()->set_label_string(label_name_x);
91 options->mutable_y()->set_min(ymin);
92 options->mutable_y()->set_max(ymax);
93 options->mutable_y()->set_label_string(label_name_y);
94 // Set chartJS's dataset properties
95}
97 if (reference_line_provider_) {
98 reference_line_provider_->Stop();
99 }
100 planner_->Stop();
101 injector_->frame_history()->Clear();
102 injector_->history()->Clear();
103 injector_->planning_context()->mutable_planning_status()->Clear();
104 last_command_.Clear();
105 injector_->ego_info()->Clear();
106}
107
108std::string OnLanePlanning::Name() const { return "on_lane_planning"; }
109
111 if (!CheckPlanningConfig(config)) {
112 return Status(ErrorCode::PLANNING_ERROR,
113 "planning config error: " + config.DebugString());
114 }
115
116 PlanningBase::Init(config);
117
118 // clear planning history
119 injector_->history()->Clear();
120
121 // clear planning status
122 injector_->planning_context()->mutable_planning_status()->Clear();
123
124 // load map
126 ACHECK(hdmap_) << "Failed to load map";
127
128 // instantiate reference line provider
129 const ReferenceLineConfig* reference_line_config = nullptr;
130 if (config_.has_reference_line_config()) {
131 reference_line_config = &config_.reference_line_config();
132 }
133 reference_line_provider_ = std::make_unique<ReferenceLineProvider>(
134 injector_->vehicle_state(), reference_line_config);
135 reference_line_provider_->Start();
136
137 // dispatch planner
138 LoadPlanner();
139 if (!planner_) {
140 return Status(
141 ErrorCode::PLANNING_ERROR,
142 "planning is not initialized with config : " + config_.DebugString());
143 }
144
146 PlanningSemanticMapConfig renderer_config;
148 FLAGS_planning_birdview_img_feature_renderer_config_file,
149 &renderer_config))
150 << "Failed to load renderer config"
151 << FLAGS_planning_birdview_img_feature_renderer_config_file;
152
153 BirdviewImgFeatureRenderer::Instance()->Init(renderer_config);
154 }
155
157
159 return planner_->Init(injector_, FLAGS_planner_config_path);
160}
161
162Status OnLanePlanning::InitFrame(const uint32_t sequence_num,
163 const TrajectoryPoint& planning_start_point,
164 const VehicleState& vehicle_state) {
165 frame_.reset(new Frame(sequence_num, local_view_, planning_start_point,
166 vehicle_state, reference_line_provider_.get()));
167
168 if (frame_ == nullptr) {
169 return Status(ErrorCode::PLANNING_ERROR, "Fail to init frame: nullptr.");
170 }
171
172 std::list<ReferenceLine> reference_lines;
173 std::list<hdmap::RouteSegments> segments;
174 reference_line_provider_->GetReferenceLines(&reference_lines, &segments);
175 DCHECK_EQ(reference_lines.size(), segments.size());
176
178 vehicle_state.linear_velocity());
179
180 for (auto& ref_line : reference_lines) {
181 ref_line.SetEgoPosition(Vec2d(vehicle_state.x(), vehicle_state.y()));
182 if (!ref_line.Segment(Vec2d(vehicle_state.x(), vehicle_state.y()),
183 planning::FLAGS_look_backward_distance,
184 forward_limit)) {
185 const std::string msg = "Fail to shrink reference line.";
186 AERROR << msg;
187 return Status(ErrorCode::PLANNING_ERROR, msg);
188 }
189 }
190 for (auto& seg : segments) {
191 if (!seg.Shrink(Vec2d(vehicle_state.x(), vehicle_state.y()),
192 planning::FLAGS_look_backward_distance, forward_limit)) {
193 const std::string msg = "Fail to shrink routing segments.";
194 AERROR << msg;
195 return Status(ErrorCode::PLANNING_ERROR, msg);
196 }
197 }
198
199 auto status = frame_->Init(
200 injector_->vehicle_state(), reference_lines, segments,
201 reference_line_provider_->FutureRouteWaypoints(), injector_->ego_info());
202 if (!status.ok()) {
203 AERROR << "failed to init frame:" << status.ToString();
204 return status;
205 }
206 return Status::OK();
207}
208
209// TODO(all): fix this! this will cause unexpected behavior from controller
210void OnLanePlanning::GenerateStopTrajectory(ADCTrajectory* ptr_trajectory_pb) {
211 ptr_trajectory_pb->clear_trajectory_point();
212
213 const auto& vehicle_state = injector_->vehicle_state()->vehicle_state();
214 const double max_t = FLAGS_fallback_total_time;
215 const double unit_t = FLAGS_fallback_time_unit;
216
217 TrajectoryPoint tp;
218 auto* path_point = tp.mutable_path_point();
219 path_point->set_x(vehicle_state.x());
220 path_point->set_y(vehicle_state.y());
221 path_point->set_theta(vehicle_state.heading());
222 path_point->set_s(0.0);
223 tp.set_v(0.0);
224 tp.set_a(0.0);
225 for (double t = 0.0; t < max_t; t += unit_t) {
226 tp.set_relative_time(t);
227 auto next_point = ptr_trajectory_pb->add_trajectory_point();
228 next_point->CopyFrom(tp);
229 }
230}
231
233 ADCTrajectory* const ptr_trajectory_pb) {
234 // when rerouting, reference line might not be updated. In this case, planning
235 // module maintains not-ready until be restarted.
237 const double start_timestamp = Clock::NowInSeconds();
238 const double start_system_timestamp =
239 std::chrono::duration<double>(
240 std::chrono::system_clock::now().time_since_epoch())
241 .count();
242
243 // localization
244 ADEBUG << "Get localization:"
245 << local_view_.localization_estimate->DebugString();
246
247 // chassis
248 ADEBUG << "Get chassis:" << local_view_.chassis->DebugString();
249
250 Status status = injector_->vehicle_state()->Update(
252
253 VehicleState vehicle_state = injector_->vehicle_state()->vehicle_state();
254 const double vehicle_state_timestamp = vehicle_state.timestamp();
255 DCHECK_GE(start_timestamp, vehicle_state_timestamp)
256 << "start_timestamp is behind vehicle_state_timestamp by "
257 << start_timestamp - vehicle_state_timestamp << " secs";
258
259 if (!status.ok() || !util::IsVehicleStateValid(vehicle_state)) {
260 const std::string msg =
261 "Update VehicleStateProvider failed "
262 "or the vehicle state is out dated.";
263 AERROR << msg;
264 ptr_trajectory_pb->mutable_decision()
265 ->mutable_main_decision()
266 ->mutable_not_ready()
267 ->set_reason(msg);
268 status.Save(ptr_trajectory_pb->mutable_header()->mutable_status());
269 // TODO(all): integrate reverse gear
270 ptr_trajectory_pb->set_gear(canbus::Chassis::GEAR_DRIVE);
271 FillPlanningPb(start_timestamp, ptr_trajectory_pb);
272 GenerateStopTrajectory(ptr_trajectory_pb);
273 return;
274 }
275
276 if (start_timestamp + 1e-6 < vehicle_state_timestamp) {
277 common::monitor::MonitorLogBuffer monitor_logger_buffer(
279 monitor_logger_buffer.ERROR("ego system time is behind GPS time");
280 }
281
282 if (start_timestamp - vehicle_state_timestamp <
283 FLAGS_message_latency_threshold) {
284 vehicle_state = AlignTimeStamp(vehicle_state, start_timestamp);
285 }
286
287 // Update reference line provider and reset scenario if new routing
288 reference_line_provider_->UpdateVehicleState(vehicle_state);
289 if (local_view_.planning_command->is_motion_command() &&
291 last_command_ = *local_view_.planning_command;
292 // AINFO << "new_command:" << last_command_.DebugString();
293 reference_line_provider_->Reset();
294 injector_->history()->Clear();
295 injector_->planning_context()->mutable_planning_status()->Clear();
296 reference_line_provider_->UpdatePlanningCommand(
298 planner_->Reset(frame_.get());
299 }
300 // Get end lane way point.
301 reference_line_provider_->GetEndLaneWayPoint(local_view_.end_lane_way_point);
302
303 // planning is triggered by prediction data, but we can still use an estimated
304 // cycle time for stitching
305 const double planning_cycle_time =
306 1.0 / static_cast<double>(FLAGS_planning_loop_rate);
307
308 std::string replan_reason;
309 std::vector<TrajectoryPoint> stitching_trajectory =
311 *(local_view_.chassis), vehicle_state, start_timestamp,
312 planning_cycle_time, FLAGS_trajectory_stitching_preserved_length,
313 true, last_publishable_trajectory_.get(), &replan_reason,
315
316 injector_->ego_info()->Update(stitching_trajectory.back(), vehicle_state);
317 const uint32_t frame_num = static_cast<uint32_t>(seq_num_++);
318 AINFO << "Planning start frame sequence id = [" << frame_num << "]";
319 status = InitFrame(frame_num, stitching_trajectory.back(), vehicle_state);
320 if (status.ok()) {
321 injector_->ego_info()->CalculateFrontObstacleClearDistance(
322 frame_->obstacles());
323 injector_->ego_info()->CalculateCurrentRouteInfo(
324 reference_line_provider_.get());
325 }
326
327 if (FLAGS_enable_record_debug) {
328 frame_->RecordInputDebug(ptr_trajectory_pb->mutable_debug());
329 }
330 ptr_trajectory_pb->mutable_latency_stats()->set_init_frame_time_ms(
331 Clock::NowInSeconds() - start_timestamp);
332
333 if (!status.ok()) {
334 AERROR << status.ToString();
335 if (FLAGS_publish_estop) {
336 // "estop" signal check in function "Control::ProduceControlCommand()"
337 // estop_ = estop_ || local_view_.trajectory.estop().is_estop();
338 // we should add more information to ensure the estop being triggered.
339 ADCTrajectory estop_trajectory;
340 EStop* estop = estop_trajectory.mutable_estop();
341 estop->set_is_estop(true);
342 estop->set_reason(status.error_message());
343 status.Save(estop_trajectory.mutable_header()->mutable_status());
344 ptr_trajectory_pb->CopyFrom(estop_trajectory);
345 } else {
346 ptr_trajectory_pb->mutable_decision()
347 ->mutable_main_decision()
348 ->mutable_not_ready()
349 ->set_reason(status.ToString());
350 status.Save(ptr_trajectory_pb->mutable_header()->mutable_status());
351 GenerateStopTrajectory(ptr_trajectory_pb);
352 }
353 // TODO(all): integrate reverse gear
354 ptr_trajectory_pb->set_gear(canbus::Chassis::GEAR_DRIVE);
355 FillPlanningPb(start_timestamp, ptr_trajectory_pb);
356 frame_->set_current_frame_planned_trajectory(*ptr_trajectory_pb);
357 const uint32_t n = frame_->SequenceNum();
358 injector_->frame_history()->Add(n, std::move(frame_));
359 return;
360 }
361
362 for (auto& ref_line_info : *frame_->mutable_reference_line_info()) {
363 auto traffic_status =
364 traffic_decider_.Execute(frame_.get(), &ref_line_info);
365 if (!traffic_status.ok() || !ref_line_info.IsDrivable()) {
366 ref_line_info.SetDrivable(false);
367 AWARN << "Reference line " << ref_line_info.Lanes().Id()
368 << " traffic decider failed";
369 }
370 }
371
372 status = Plan(start_timestamp, stitching_trajectory, ptr_trajectory_pb);
373
374 // print trajxy
375 PrintCurves trajectory_print_curve;
376 for (const auto& p : ptr_trajectory_pb->trajectory_point()) {
377 trajectory_print_curve.AddPoint("trajxy", p.path_point().x(),
378 p.path_point().y());
379 }
380 trajectory_print_curve.PrintToLog();
381
382 // print obstacle polygon
383 for (const auto& obstacle : frame_->obstacles()) {
384 obstacle->PrintPolygonCurve();
385 }
386 // print ego box
387 PrintBox print_box("ego_box");
388 print_box.AddAdcBox(vehicle_state.x(), vehicle_state.y(),
389 vehicle_state.heading(), true);
390 print_box.PrintToLog();
391
392 const auto end_system_timestamp =
393 std::chrono::duration<double>(
394 std::chrono::system_clock::now().time_since_epoch())
395 .count();
396 const auto time_diff_ms =
397 (end_system_timestamp - start_system_timestamp) * 1000;
398 ADEBUG << "total planning time spend: " << time_diff_ms << " ms.";
399
400 ptr_trajectory_pb->mutable_latency_stats()->set_total_time_ms(time_diff_ms);
401 ADEBUG << "Planning latency: "
402 << ptr_trajectory_pb->latency_stats().DebugString();
403
404 if (!status.ok()) {
405 status.Save(ptr_trajectory_pb->mutable_header()->mutable_status());
406 AERROR << "Planning failed:" << status.ToString();
407 if (FLAGS_publish_estop) {
408 AERROR << "Planning failed and set estop";
409 // "estop" signal check in function "Control::ProduceControlCommand()"
410 // estop_ = estop_ || local_view_.trajectory.estop().is_estop();
411 // we should add more information to ensure the estop being triggered.
412 EStop* estop = ptr_trajectory_pb->mutable_estop();
413 estop->set_is_estop(true);
414 estop->set_reason(status.error_message());
415 }
416 }
417
418 ptr_trajectory_pb->set_is_replan(stitching_trajectory.size() == 1);
419 if (ptr_trajectory_pb->is_replan()) {
420 ptr_trajectory_pb->set_replan_reason(replan_reason);
421 }
422
423 if (frame_->open_space_info().is_on_open_space_trajectory()) {
424 FillPlanningPb(start_timestamp, ptr_trajectory_pb);
425 ADEBUG << "Planning pb:" << ptr_trajectory_pb->header().DebugString();
426 frame_->set_current_frame_planned_trajectory(*ptr_trajectory_pb);
427 } else {
428 auto* ref_line_task =
429 ptr_trajectory_pb->mutable_latency_stats()->add_task_stats();
430 ref_line_task->set_time_ms(reference_line_provider_->LastTimeDelay() *
431 1000.0);
432 ref_line_task->set_name("ReferenceLineProvider");
433
434 FillPlanningPb(start_timestamp, ptr_trajectory_pb);
435 ADEBUG << "Planning pb:" << ptr_trajectory_pb->header().DebugString();
436
437 frame_->set_current_frame_planned_trajectory(*ptr_trajectory_pb);
438 if (FLAGS_enable_planning_smoother) {
439 planning_smoother_.Smooth(injector_->frame_history(), frame_.get(),
440 ptr_trajectory_pb);
441 }
442 }
443
444 const auto end_planning_perf_timestamp =
445 std::chrono::duration<double>(
446 std::chrono::system_clock::now().time_since_epoch())
447 .count();
448 const auto plnning_perf_ms =
449 (end_planning_perf_timestamp - start_system_timestamp) * 1000;
450 AINFO << "Planning Perf: planning name [" << Name() << "], "
451 << plnning_perf_ms << " ms.";
452 AINFO << "Planning end frame sequence id = [" << frame_num << "]";
453 injector_->frame_history()->Add(frame_num, std::move(frame_));
454}
455
456void OnLanePlanning::ExportReferenceLineDebug(planning_internal::Debug* debug) {
457 if (!FLAGS_enable_record_debug) {
458 return;
459 }
460 for (auto& reference_line_info : *frame_->mutable_reference_line_info()) {
461 auto rl_debug = debug->mutable_planning_data()->add_reference_line();
462 rl_debug->set_id(reference_line_info.Lanes().Id());
463 rl_debug->set_length(reference_line_info.reference_line().Length());
464 rl_debug->set_cost(reference_line_info.Cost());
465 rl_debug->set_is_change_lane_path(reference_line_info.IsChangeLanePath());
466 rl_debug->set_is_drivable(reference_line_info.IsDrivable());
467 rl_debug->set_is_protected(reference_line_info.GetRightOfWayStatus() ==
469
470 // store kappa and dkappa for performance evaluation
471 const auto& reference_points =
472 reference_line_info.reference_line().reference_points();
473 double kappa_rms = 0.0;
474 double dkappa_rms = 0.0;
475 double kappa_max_abs = std::numeric_limits<double>::lowest();
476 double dkappa_max_abs = std::numeric_limits<double>::lowest();
477 for (const auto& reference_point : reference_points) {
478 double kappa_sq = reference_point.kappa() * reference_point.kappa();
479 double dkappa_sq = reference_point.dkappa() * reference_point.dkappa();
480 kappa_rms += kappa_sq;
481 dkappa_rms += dkappa_sq;
482 kappa_max_abs = kappa_max_abs < kappa_sq ? kappa_sq : kappa_max_abs;
483 dkappa_max_abs = dkappa_max_abs < dkappa_sq ? dkappa_sq : dkappa_max_abs;
484 }
485 double reference_points_size = static_cast<double>(reference_points.size());
486 kappa_rms /= reference_points_size;
487 dkappa_rms /= reference_points_size;
488 kappa_rms = std::sqrt(kappa_rms);
489 dkappa_rms = std::sqrt(dkappa_rms);
490 rl_debug->set_kappa_rms(kappa_rms);
491 rl_debug->set_dkappa_rms(dkappa_rms);
492 rl_debug->set_kappa_max_abs(kappa_max_abs);
493 rl_debug->set_dkappa_max_abs(dkappa_max_abs);
494
495 bool is_off_road = false;
496 double minimum_boundary = std::numeric_limits<double>::infinity();
497
498 const double adc_half_width =
500 const auto& reference_line_path =
501 reference_line_info.reference_line().GetMapPath();
502 const auto sample_s = 0.1;
503 const auto reference_line_length =
504 reference_line_info.reference_line().Length();
505 double average_offset = 0.0;
506 double sample_count = 0.0;
507 for (double s = 0.0; s < reference_line_length; s += sample_s) {
508 double left_width = reference_line_path.GetLaneLeftWidth(s);
509 double right_width = reference_line_path.GetLaneRightWidth(s);
510 average_offset += 0.5 * std::abs(left_width - right_width);
511 if (left_width < adc_half_width || right_width < adc_half_width) {
512 is_off_road = true;
513 }
514 if (left_width < minimum_boundary) {
515 minimum_boundary = left_width;
516 }
517 if (right_width < minimum_boundary) {
518 minimum_boundary = right_width;
519 }
520 ++sample_count;
521 }
522 rl_debug->set_is_offroad(is_off_road);
523 rl_debug->set_minimum_boundary(minimum_boundary);
524 rl_debug->set_average_offset(average_offset / sample_count);
525 }
526}
527
529 const double current_time_stamp,
530 const std::vector<TrajectoryPoint>& stitching_trajectory,
531 ADCTrajectory* const ptr_trajectory_pb) {
532 auto* ptr_debug = ptr_trajectory_pb->mutable_debug();
533 if (FLAGS_enable_record_debug) {
534 ptr_debug->mutable_planning_data()->mutable_init_point()->CopyFrom(
535 stitching_trajectory.back());
536 frame_->mutable_open_space_info()->set_debug(ptr_debug);
537 frame_->mutable_open_space_info()->sync_debug_instance();
538 }
539
540 auto status = planner_->Plan(stitching_trajectory.back(), frame_.get(),
541 ptr_trajectory_pb);
542
543 if (frame_->open_space_info().is_on_open_space_trajectory()) {
544 frame_->mutable_open_space_info()->sync_debug_instance();
545 const auto& publishable_trajectory =
546 frame_->open_space_info().publishable_trajectory_data().first;
547 const auto& publishable_trajectory_gear =
548 frame_->open_space_info().publishable_trajectory_data().second;
549 const auto& trajectory_type = frame_->open_space_info().trajectory_type();
550 const auto& is_collision = frame_->open_space_info().is_collision();
551 publishable_trajectory.PopulateTrajectoryProtobuf(ptr_trajectory_pb);
552 ptr_trajectory_pb->set_gear(publishable_trajectory_gear);
553 ptr_trajectory_pb->set_trajectory_type(trajectory_type);
554 ptr_trajectory_pb->set_is_collision(is_collision);
555 // TODO(QiL): refine engage advice in open space trajectory optimizer.
556 auto* engage_advice = ptr_trajectory_pb->mutable_engage_advice();
557
558 // enable start auto from open_space planner.
559 if (injector_->vehicle_state()->vehicle_state().driving_mode() !=
560 Chassis::DrivingMode::Chassis_DrivingMode_COMPLETE_AUTO_DRIVE) {
561 engage_advice->set_advice(EngageAdvice::READY_TO_ENGAGE);
562 engage_advice->set_reason(
563 "Ready to engage when staring with OPEN_SPACE_PLANNER");
564 } else {
565 engage_advice->set_advice(EngageAdvice::KEEP_ENGAGED);
566 engage_advice->set_reason("Keep engage while in parking");
567 }
568 // TODO(QiL): refine the export decision in open space info
569 ptr_trajectory_pb->mutable_decision()
570 ->mutable_main_decision()
571 ->mutable_parking()
572 ->set_status(MainParking::IN_PARKING);
573
574 if (FLAGS_enable_record_debug) {
575 // ptr_debug->MergeFrom(frame_->open_space_info().debug_instance());
576 frame_->mutable_open_space_info()->RecordDebug(ptr_debug);
577 ADEBUG << "Open space debug information added!";
578 // call open space info load debug
579 // TODO(Runxin): create a new flag to enable openspace chart
580 ExportOpenSpaceChart(ptr_trajectory_pb->debug(), *ptr_trajectory_pb,
581 ptr_debug);
582 }
583 } else {
584 const auto* best_ref_info = frame_->FindDriveReferenceLineInfo();
585 const auto* target_ref_info = frame_->FindTargetReferenceLineInfo();
586 if (!best_ref_info) {
587 const std::string msg = "planner failed to make a driving plan";
588 AERROR << msg;
591 }
592 return Status(ErrorCode::PLANNING_ERROR, msg);
593 }
594 // Store current frame stitched path for possible speed fallback in next
595 // frames
596 DiscretizedPath current_frame_planned_path;
597 for (const auto& trajectory_point : stitching_trajectory) {
598 current_frame_planned_path.push_back(trajectory_point.path_point());
599 }
600 const auto& best_ref_path = best_ref_info->path_data().discretized_path();
601 std::copy(best_ref_path.begin() + 1, best_ref_path.end(),
602 std::back_inserter(current_frame_planned_path));
603 frame_->set_current_frame_planned_path(current_frame_planned_path);
604
605 ptr_debug->MergeFrom(best_ref_info->debug());
606 if (FLAGS_export_chart) {
607 ExportOnLaneChart(best_ref_info->debug(), ptr_debug);
608 } else {
609 ExportReferenceLineDebug(ptr_debug);
610 // Export additional ST-chart for failed lane-change speed planning
611 const auto* failed_ref_info = frame_->FindFailedReferenceLineInfo();
612 if (failed_ref_info) {
613 ExportFailedLaneChangeSTChart(failed_ref_info->debug(), ptr_debug);
614 }
615 }
616 ptr_trajectory_pb->mutable_latency_stats()->MergeFrom(
617 best_ref_info->latency_stats());
618 // set right of way status
619 ptr_trajectory_pb->set_right_of_way_status(
620 best_ref_info->GetRightOfWayStatus());
621
622 for (const auto& id : best_ref_info->TargetLaneId()) {
623 ptr_trajectory_pb->add_lane_id()->CopyFrom(id);
624 }
625
626 for (const auto& id : target_ref_info->TargetLaneId()) {
627 ptr_trajectory_pb->add_target_lane_id()->CopyFrom(id);
628 }
629
630 ptr_trajectory_pb->set_trajectory_type(best_ref_info->trajectory_type());
631
632 if (FLAGS_enable_rss_info) {
633 *ptr_trajectory_pb->mutable_rss_info() = best_ref_info->rss_info();
634 }
635
636 best_ref_info->ExportDecision(ptr_trajectory_pb->mutable_decision(),
637 injector_->planning_context());
638
639 // Add debug information.
640 if (FLAGS_enable_record_debug) {
641 auto* reference_line = ptr_debug->mutable_planning_data()->add_path();
642 reference_line->set_name("planning_reference_line");
643 const auto& reference_points =
644 best_ref_info->reference_line().reference_points();
645 double s = 0.0;
646 double prev_x = 0.0;
647 double prev_y = 0.0;
648 bool empty_path = true;
649 for (const auto& reference_point : reference_points) {
650 auto* path_point = reference_line->add_path_point();
651 path_point->set_x(reference_point.x());
652 path_point->set_y(reference_point.y());
653 path_point->set_theta(reference_point.heading());
654 path_point->set_kappa(reference_point.kappa());
655 path_point->set_dkappa(reference_point.dkappa());
656 if (empty_path) {
657 path_point->set_s(0.0);
658 empty_path = false;
659 } else {
660 double dx = reference_point.x() - prev_x;
661 double dy = reference_point.y() - prev_y;
662 s += std::hypot(dx, dy);
663 path_point->set_s(s);
664 }
665 prev_x = reference_point.x();
666 prev_y = reference_point.y();
667 }
668 }
669
671 current_time_stamp, best_ref_info->trajectory()));
672 PrintCurves debug_traj;
673 for (size_t i = 0; i < last_publishable_trajectory_->size(); i++) {
674 auto& traj_pt = last_publishable_trajectory_->at(i);
675 debug_traj.AddPoint("traj_sv", traj_pt.path_point().s(), traj_pt.v());
676 debug_traj.AddPoint("traj_sa", traj_pt.path_point().s(), traj_pt.a());
677 debug_traj.AddPoint("traj_sk", traj_pt.path_point().s(),
678 traj_pt.path_point().kappa());
679 }
680 // debug_traj.PrintToLog();
681 ADEBUG << "current_time_stamp: " << current_time_stamp;
682
683 last_publishable_trajectory_->PrependTrajectoryPoints(
684 std::vector<TrajectoryPoint>(stitching_trajectory.begin(),
685 stitching_trajectory.end() - 1));
686
687 last_publishable_trajectory_->PopulateTrajectoryProtobuf(ptr_trajectory_pb);
688
689 best_ref_info->ExportEngageAdvice(
690 ptr_trajectory_pb->mutable_engage_advice(),
691 injector_->planning_context());
692 }
693
694 AddADCDrivingStateInfo(ptr_debug);
695
696 return status;
697}
698
699bool OnLanePlanning::CheckPlanningConfig(const PlanningConfig& config) {
700 // TODO(All): check other config params
701 return true;
702}
703
704void PopulateChartOptions(double x_min, double x_max, std::string x_label,
705 double y_min, double y_max, std::string y_label,
706 bool display, Chart* chart) {
707 auto* options = chart->mutable_options();
708 options->mutable_x()->set_min(x_min);
709 options->mutable_x()->set_max(x_max);
710 options->mutable_y()->set_min(y_min);
711 options->mutable_y()->set_max(y_max);
712 options->mutable_x()->set_label_string(x_label);
713 options->mutable_y()->set_label_string(y_label);
714 options->set_legend_display(display);
715}
716
717void AddSTGraph(const STGraphDebug& st_graph, Chart* chart) {
718 if (st_graph.name() == "DP_ST_SPEED_OPTIMIZER") {
719 chart->set_title("Speed Heuristic");
720 } else {
721 chart->set_title("Planning S-T Graph");
722 }
723 PopulateChartOptions(-2.0, 10.0, "t (second)", -10.0, 220.0, "s (meter)",
724 false, chart);
725
726 for (const auto& boundary : st_graph.boundary()) {
727 // from 'ST_BOUNDARY_TYPE_' to the end
728 std::string type =
729 StGraphBoundaryDebug_StBoundaryType_Name(boundary.type()).substr(17);
730
731 auto* boundary_chart = chart->add_polygon();
732 auto* properties = boundary_chart->mutable_properties();
733 (*properties)["borderWidth"] = "2";
734 (*properties)["pointRadius"] = "0";
735 (*properties)["lineTension"] = "0";
736 (*properties)["cubicInterpolationMode"] = "monotone";
737 (*properties)["showLine"] = "true";
738 (*properties)["showText"] = "true";
739 (*properties)["fill"] = "false";
740
741 if (type == "DRIVABLE_REGION") {
742 (*properties)["color"] = "\"rgba(0, 255, 0, 0.5)\"";
743 } else {
744 (*properties)["color"] = "\"rgba(255, 0, 0, 0.8)\"";
745 }
746
747 boundary_chart->set_label(boundary.name() + "_" + type);
748 for (const auto& point : boundary.point()) {
749 auto* point_debug = boundary_chart->add_point();
750 point_debug->set_x(point.t());
751 point_debug->set_y(point.s());
752 }
753 }
754
755 auto* speed_profile = chart->add_line();
756 auto* properties = speed_profile->mutable_properties();
757 (*properties)["color"] = "\"rgba(255, 255, 255, 0.5)\"";
758 for (const auto& point : st_graph.speed_profile()) {
759 auto* point_debug = speed_profile->add_point();
760 point_debug->set_x(point.t());
761 point_debug->set_y(point.s());
762 }
763}
764
765void AddSLFrame(const SLFrameDebug& sl_frame, Chart* chart) {
766 chart->set_title(sl_frame.name());
767 PopulateChartOptions(0.0, 80.0, "s (meter)", -8.0, 8.0, "l (meter)", false,
768 chart);
769 auto* sl_line = chart->add_line();
770 sl_line->set_label("SL Path");
771 for (const auto& sl_point : sl_frame.sl_path()) {
772 auto* point_debug = sl_line->add_point();
773 point_debug->set_x(sl_point.s());
774 point_debug->set_x(sl_point.l());
775 }
776}
777
779 const ::google::protobuf::RepeatedPtrField<SpeedPlan>& speed_plans,
780 Chart* chart) {
781 chart->set_title("Speed Plan");
782 PopulateChartOptions(0.0, 80.0, "s (meter)", 0.0, 50.0, "v (m/s)", false,
783 chart);
784
785 for (const auto& speed_plan : speed_plans) {
786 auto* line = chart->add_line();
787 line->set_label(speed_plan.name());
788 for (const auto& point : speed_plan.speed_point()) {
789 auto* point_debug = line->add_point();
790 point_debug->set_x(point.s());
791 point_debug->set_y(point.v());
792 }
793
794 // Set chartJS's dataset properties
795 auto* properties = line->mutable_properties();
796 (*properties)["borderWidth"] = "2";
797 (*properties)["pointRadius"] = "0";
798 (*properties)["fill"] = "false";
799 (*properties)["showLine"] = "true";
800 if (speed_plan.name() == "DpStSpeedOptimizer") {
801 (*properties)["color"] = "\"rgba(27, 249, 105, 0.5)\"";
802 } else if (speed_plan.name() == "QpSplineStSpeedOptimizer") {
803 (*properties)["color"] = "\"rgba(54, 162, 235, 1)\"";
804 }
805 }
806}
807
808void OnLanePlanning::ExportFailedLaneChangeSTChart(
809 const planning_internal::Debug& debug_info,
810 planning_internal::Debug* debug_chart) {
811 const auto& src_data = debug_info.planning_data();
812 auto* dst_data = debug_chart->mutable_planning_data();
813 for (const auto& st_graph : src_data.st_graph()) {
814 AddSTGraph(st_graph, dst_data->add_chart());
815 }
816}
817
818void OnLanePlanning::ExportOnLaneChart(
819 const planning_internal::Debug& debug_info,
820 planning_internal::Debug* debug_chart) {
821 const auto& src_data = debug_info.planning_data();
822 auto* dst_data = debug_chart->mutable_planning_data();
823 for (const auto& st_graph : src_data.st_graph()) {
824 AddSTGraph(st_graph, dst_data->add_chart());
825 }
826 for (const auto& sl_frame : src_data.sl_frame()) {
827 AddSLFrame(sl_frame, dst_data->add_chart());
828 }
829 AddSpeedPlan(src_data.speed_plan(), dst_data->add_chart());
830}
831
832void OnLanePlanning::ExportOpenSpaceChart(
833 const planning_internal::Debug& debug_info,
834 const ADCTrajectory& trajectory_pb, planning_internal::Debug* debug_chart) {
835 // Export Trajectory Visualization Chart.
836 if (FLAGS_enable_record_debug) {
837 AddOpenSpaceOptimizerResult(debug_info, debug_chart);
838 AddPartitionedTrajectory(debug_info, debug_chart);
839 AddStitchSpeedProfile(debug_chart);
840 AddPublishedSpeed(trajectory_pb, debug_chart);
841 AddPublishedAcceleration(trajectory_pb, debug_chart);
842 // AddFallbackTrajectory(debug_info, debug_chart);
843 }
844}
845
846void OnLanePlanning::AddOpenSpaceOptimizerResult(
847 const planning_internal::Debug& debug_info,
848 planning_internal::Debug* debug_chart) {
849 // if open space info provider success run
850 if (!frame_->open_space_info().open_space_provider_success()) {
851 return;
852 }
853
854 auto chart = debug_chart->mutable_planning_data()->add_chart();
855 auto open_space_debug = debug_info.planning_data().open_space();
856
857 chart->set_title("Open Space Trajectory Optimizer Visualization");
858 PopulateChartOptions(open_space_debug.xy_boundary(0) - 1.0,
859 open_space_debug.xy_boundary(1) + 1.0, "x (meter)",
860 open_space_debug.xy_boundary(2) - 1.0,
861 open_space_debug.xy_boundary(3) + 1.0, "y (meter)", true,
862 chart);
863
864 chart->mutable_options()->set_sync_xy_window_size(true);
865 chart->mutable_options()->set_aspect_ratio(0.9);
866 int obstacle_index = 1;
867 for (const auto& obstacle : open_space_debug.obstacles()) {
868 auto* obstacle_outline = chart->add_line();
869 obstacle_outline->set_label(absl::StrCat("Bdr", obstacle_index));
870 obstacle_index += 1;
871 for (int vertice_index = 0;
872 vertice_index < obstacle.vertices_x_coords_size(); vertice_index++) {
873 auto* point_debug = obstacle_outline->add_point();
874 point_debug->set_x(obstacle.vertices_x_coords(vertice_index));
875 point_debug->set_y(obstacle.vertices_y_coords(vertice_index));
876 }
877 // Set chartJS's dataset properties
878 auto* obstacle_properties = obstacle_outline->mutable_properties();
879 (*obstacle_properties)["borderWidth"] = "2";
880 (*obstacle_properties)["pointRadius"] = "0";
881 (*obstacle_properties)["lineTension"] = "0";
882 (*obstacle_properties)["fill"] = "false";
883 (*obstacle_properties)["showLine"] = "true";
884 }
885
886 auto smoothed_trajectory = open_space_debug.smoothed_trajectory();
887 auto* smoothed_line = chart->add_line();
888 smoothed_line->set_label("Smooth");
889 // size_t adc_label = 0;
890 for (int i = 0; i < smoothed_trajectory.vehicle_motion_point_size() / 2;
891 i++) {
892 auto& point = smoothed_trajectory.vehicle_motion_point(i);
893 const auto x = point.trajectory_point().path_point().x();
894 const auto y = point.trajectory_point().path_point().y();
895 // const auto heading = point.trajectory_point().path_point().theta();
896 /*
897 // Draw vehicle shape along the trajectory
898 auto* adc_shape = chart->add_car();
899 adc_shape->set_x(x);
900 adc_shape->set_y(y);
901 adc_shape->set_heading(heading);
902 adc_shape->set_color("rgba(54, 162, 235, 1)");
903 adc_shape->set_label(std::to_string(adc_label));
904 adc_shape->set_hide_label_in_legend(true);
905 ++adc_label;
906 */
907 // Draw vehicle trajectory points
908 auto* point_debug = smoothed_line->add_point();
909 point_debug->set_x(x);
910 point_debug->set_y(y);
911 }
912
913 // Set chartJS's dataset properties
914 auto* smoothed_properties = smoothed_line->mutable_properties();
915 (*smoothed_properties)["borderWidth"] = "2";
916 (*smoothed_properties)["pointRadius"] = "0";
917 (*smoothed_properties)["lineTension"] = "0";
918 (*smoothed_properties)["fill"] = "false";
919 (*smoothed_properties)["showLine"] = "true";
920
921 auto warm_start_trajectory = open_space_debug.warm_start_trajectory();
922 auto* warm_start_line = chart->add_line();
923 warm_start_line->set_label("WarmStart");
924 for (int i = 0; i < warm_start_trajectory.vehicle_motion_point_size() / 2;
925 i++) {
926 auto* point_debug = warm_start_line->add_point();
927 auto& point = warm_start_trajectory.vehicle_motion_point(i);
928 point_debug->set_x(point.trajectory_point().path_point().x());
929 point_debug->set_y(point.trajectory_point().path_point().y());
930 }
931 // Set chartJS's dataset properties
932 auto* warm_start_properties = warm_start_line->mutable_properties();
933 (*warm_start_properties)["borderWidth"] = "2";
934 (*warm_start_properties)["pointRadius"] = "0";
935 (*warm_start_properties)["lineTension"] = "0";
936 (*warm_start_properties)["fill"] = "false";
937 (*warm_start_properties)["showLine"] = "true";
938}
939
940void OnLanePlanning::AddPartitionedTrajectory(
941 const planning_internal::Debug& debug_info,
942 planning_internal::Debug* debug_chart) {
943 // if open space info provider success run
944 if (!frame_->open_space_info().open_space_provider_success()) {
945 return;
946 }
947
948 const auto& open_space_debug = debug_info.planning_data().open_space();
949 const auto& chosen_trajectories =
950 open_space_debug.chosen_trajectory().trajectory();
951 if (chosen_trajectories.empty() ||
952 chosen_trajectories[0].trajectory_point().empty()) {
953 return;
954 }
955
956 const auto& vehicle_state = frame_->vehicle_state();
957 auto chart = debug_chart->mutable_planning_data()->add_chart();
958 auto chart_kappa = debug_chart->mutable_planning_data()->add_chart();
959 auto chart_theta = debug_chart->mutable_planning_data()->add_chart();
960 chart->set_title("Open Space Partitioned Trajectory");
961 chart_kappa->set_title("total kappa");
962 chart_theta->set_title("total theta");
963 auto* options = chart->mutable_options();
964 options->mutable_x()->set_label_string("x (meter)");
965 options->mutable_y()->set_label_string("y (meter)");
966 options->set_sync_xy_window_size(true);
967 options->set_aspect_ratio(0.9);
968
969 // Draw vehicle state
970 auto* adc_shape = chart->add_car();
971 adc_shape->set_x(vehicle_state.x());
972 adc_shape->set_y(vehicle_state.y());
973 adc_shape->set_heading(vehicle_state.heading());
974 adc_shape->set_label("ADV");
975 adc_shape->set_color("rgba(54, 162, 235, 1)");
976
977 // Draw the chosen trajectories
978 const auto& chosen_trajectory = chosen_trajectories[0];
979 auto* chosen_line = chart->add_line();
980 chosen_line->set_label("Chosen");
981 for (const auto& point : chosen_trajectory.trajectory_point()) {
982 auto* point_debug = chosen_line->add_point();
983 point_debug->set_x(point.path_point().x());
984 point_debug->set_y(point.path_point().y());
985 }
986 auto* chosen_properties = chosen_line->mutable_properties();
987 (*chosen_properties)["borderWidth"] = "2";
988 (*chosen_properties)["pointRadius"] = "0";
989 (*chosen_properties)["lineTension"] = "0";
990 (*chosen_properties)["fill"] = "false";
991 (*chosen_properties)["showLine"] = "true";
992 auto* theta_line = chart_theta->add_line();
993 auto* kappa_line = chart_kappa->add_line();
994 // Draw partitioned trajectories
995 size_t partitioned_trajectory_label = 0;
996 for (const auto& partitioned_trajectory :
997 open_space_debug.partitioned_trajectories().trajectory()) {
998 auto* partition_line = chart->add_line();
999 partition_line->set_label(
1000 absl::StrCat("Partitioned ", partitioned_trajectory_label));
1001 ++partitioned_trajectory_label;
1002 for (const auto& point : partitioned_trajectory.trajectory_point()) {
1003 auto* point_debug = partition_line->add_point();
1004 auto* point_theta = theta_line->add_point();
1005 auto* point_kappa = kappa_line->add_point();
1006 point_debug->set_x(point.path_point().x());
1007 point_debug->set_y(point.path_point().y());
1008 point_theta->set_x(point.relative_time());
1009 point_kappa->set_x(point.relative_time());
1010 point_theta->set_y(point.path_point().theta());
1011 point_kappa->set_y(point.path_point().kappa());
1012 }
1013
1014 auto* partition_properties = partition_line->mutable_properties();
1015 (*partition_properties)["borderWidth"] = "2";
1016 (*partition_properties)["pointRadius"] = "0";
1017 (*partition_properties)["lineTension"] = "0";
1018 (*partition_properties)["fill"] = "false";
1019 (*partition_properties)["showLine"] = "true";
1020 SetChartminmax(chart_kappa, "time", "total kappa");
1021 SetChartminmax(chart_theta, "time", "total theta");
1022 }
1023
1024 // Draw trajectory stitching point (line with only one point)
1025 // auto* stitching_line = chart->add_line();
1026 // stitching_line->set_label("TrajectoryStitchingPoint");
1027 // auto* trajectory_stitching_point = stitching_line->add_point();
1028 // trajectory_stitching_point->set_x(
1029 // open_space_debug.trajectory_stitching_point().path_point().x());
1030 // trajectory_stitching_point->set_y(
1031 // open_space_debug.trajectory_stitching_point().path_point().y());
1032 // // Set chartJS's dataset properties
1033 // auto* stitching_properties = stitching_line->mutable_properties();
1034 // (*stitching_properties)["borderWidth"] = "3";
1035 // (*stitching_properties)["pointRadius"] = "5";
1036 // (*stitching_properties)["lineTension"] = "0";
1037 // (*stitching_properties)["fill"] = "true";
1038 // (*stitching_properties)["showLine"] = "true";
1039
1040 // Draw fallback trajectory compared with the partitioned and potential
1041 // collision_point (line with only one point)
1042 // if (open_space_debug.is_fallback_trajectory()) {
1043 // auto* collision_line = chart->add_line();
1044 // collision_line->set_label("FutureCollisionPoint");
1045 // auto* future_collision_point = collision_line->add_point();
1046 // future_collision_point->set_x(
1047 // open_space_debug.future_collision_point().path_point().x());
1048 // future_collision_point->set_y(
1049 // open_space_debug.future_collision_point().path_point().y());
1050 // // Set chartJS's dataset properties
1051 // auto* collision_properties = collision_line->mutable_properties();
1052 // (*collision_properties)["borderWidth"] = "3";
1053 // (*collision_properties)["pointRadius"] = "8";
1054 // (*collision_properties)["lineTension"] = "0";
1055 // (*collision_properties)["fill"] = "true";
1056 // (*stitching_properties)["showLine"] = "true";
1057 // (*stitching_properties)["pointStyle"] = "cross";
1058
1059 // const auto& fallback_trajectories =
1060 // open_space_debug.fallback_trajectory().trajectory();
1061 // if (fallback_trajectories.empty() ||
1062 // fallback_trajectories[0].trajectory_point().empty()) {
1063 // return;
1064 // }
1065 // const auto& fallback_trajectory = fallback_trajectories[0];
1066 // // has to define chart boundary first
1067 // auto* fallback_line = chart->add_line();
1068 // fallback_line->set_label("Fallback");
1069 // for (const auto& point : fallback_trajectory.trajectory_point()) {
1070 // auto* point_debug = fallback_line->add_point();
1071 // point_debug->set_x(point.path_point().x());
1072 // point_debug->set_y(point.path_point().y());
1073 // }
1074 // // Set chartJS's dataset properties
1075 // auto* fallback_properties = fallback_line->mutable_properties();
1076 // (*fallback_properties)["borderWidth"] = "3";
1077 // (*fallback_properties)["pointRadius"] = "2";
1078 // (*fallback_properties)["lineTension"] = "0";
1079 // (*fallback_properties)["fill"] = "false";
1080 // (*fallback_properties)["showLine"] = "true";
1081 // }
1082}
1083
1084void OnLanePlanning::AddStitchSpeedProfile(
1085 planning_internal::Debug* debug_chart) {
1086 if (!injector_->frame_history()->Latest()) {
1087 AINFO << "Planning frame is empty!";
1088 return;
1089 }
1090
1091 // if open space info provider success run
1092 if (!frame_->open_space_info().open_space_provider_success()) {
1093 return;
1094 }
1095
1096 auto chart = debug_chart->mutable_planning_data()->add_chart();
1097 chart->set_title("Open Space Speed Plan Visualization");
1098 auto* options = chart->mutable_options();
1099 // options->mutable_x()->set_mid_value(Clock::NowInSeconds());
1100 double xmin(std::numeric_limits<double>::max()),
1101 xmax(std::numeric_limits<double>::lowest()),
1102 ymin(std::numeric_limits<double>::max()),
1103 ymax(std::numeric_limits<double>::lowest());
1104 // auto smoothed_trajectory = open_space_debug.smoothed_trajectory();
1105 auto* speed_profile = chart->add_line();
1106 speed_profile->set_label("Speed Profile");
1107 const auto& last_trajectory =
1108 injector_->frame_history()->Latest()->current_frame_planned_trajectory();
1109 for (const auto& point : last_trajectory.trajectory_point()) {
1110 auto* point_debug = speed_profile->add_point();
1111 point_debug->set_x(point.relative_time() +
1112 last_trajectory.header().timestamp_sec());
1113 point_debug->set_y(point.v());
1114 if (point_debug->x() > xmax) xmax = point_debug->x();
1115 if (point_debug->x() < xmin) xmin = point_debug->x();
1116 if (point_debug->y() > ymax) ymax = point_debug->y();
1117 if (point_debug->y() < ymin) ymin = point_debug->y();
1118 }
1119 options->mutable_x()->set_window_size(xmax - xmin);
1120 options->mutable_x()->set_label_string("time (s)");
1121 options->mutable_y()->set_min(ymin);
1122 options->mutable_y()->set_max(ymax);
1123 options->mutable_y()->set_label_string("speed (m/s)");
1124 // Set chartJS's dataset properties
1125 auto* speed_profile_properties = speed_profile->mutable_properties();
1126 (*speed_profile_properties)["borderWidth"] = "2";
1127 (*speed_profile_properties)["pointRadius"] = "0";
1128 (*speed_profile_properties)["lineTension"] = "0";
1129 (*speed_profile_properties)["fill"] = "false";
1130 (*speed_profile_properties)["showLine"] = "true";
1131}
1132
1133void OnLanePlanning::AddPublishedSpeed(const ADCTrajectory& trajectory_pb,
1134 planning_internal::Debug* debug_chart) {
1135 // if open space info provider success run
1136 if (!frame_->open_space_info().open_space_provider_success()) {
1137 return;
1138 }
1139
1140 auto chart = debug_chart->mutable_planning_data()->add_chart();
1141 chart->set_title("Speed Partition Visualization");
1142 auto* options = chart->mutable_options();
1143 // options->mutable_x()->set_mid_value(Clock::NowInSeconds());
1144 // auto smoothed_trajectory = open_space_debug.smoothed_trajectory();
1145 auto* speed_profile = chart->add_line();
1146 speed_profile->set_label("Speed Profile");
1147 double xmin(std::numeric_limits<double>::max()),
1148 xmax(std::numeric_limits<double>::lowest()),
1149 ymin(std::numeric_limits<double>::max()),
1150 ymax(std::numeric_limits<double>::lowest());
1151 for (const auto& point : trajectory_pb.trajectory_point()) {
1152 auto* point_debug = speed_profile->add_point();
1153 point_debug->set_x(point.relative_time() +
1154 trajectory_pb.header().timestamp_sec());
1155 if (trajectory_pb.gear() == canbus::Chassis::GEAR_DRIVE) {
1156 point_debug->set_y(point.v());
1157 }
1158 if (trajectory_pb.gear() == canbus::Chassis::GEAR_REVERSE) {
1159 point_debug->set_y(-point.v());
1160 }
1161 if (point_debug->x() > xmax) xmax = point_debug->x();
1162 if (point_debug->x() < xmin) xmin = point_debug->x();
1163 if (point_debug->y() > ymax) ymax = point_debug->y();
1164 if (point_debug->y() < ymin) ymin = point_debug->y();
1165 }
1166 options->mutable_x()->set_window_size(xmax - xmin);
1167 options->mutable_x()->set_label_string("time (s)");
1168 options->mutable_y()->set_min(ymin);
1169 options->mutable_y()->set_max(ymax);
1170 options->mutable_y()->set_label_string("speed (m/s)");
1171 // Set chartJS's dataset properties
1172 auto* speed_profile_properties = speed_profile->mutable_properties();
1173 (*speed_profile_properties)["borderWidth"] = "2";
1174 (*speed_profile_properties)["pointRadius"] = "0";
1175 (*speed_profile_properties)["lineTension"] = "0";
1176 (*speed_profile_properties)["fill"] = "false";
1177 (*speed_profile_properties)["showLine"] = "true";
1178
1179 auto* sliding_line = chart->add_line();
1180 sliding_line->set_label("Time");
1181
1182 auto* point_debug_up = sliding_line->add_point();
1183 point_debug_up->set_x(Clock::NowInSeconds());
1184 point_debug_up->set_y(2.1);
1185 auto* point_debug_down = sliding_line->add_point();
1186 point_debug_down->set_x(Clock::NowInSeconds());
1187 point_debug_down->set_y(-1.1);
1188
1189 // Set chartJS's dataset properties
1190 auto* sliding_line_properties = sliding_line->mutable_properties();
1191 (*sliding_line_properties)["borderWidth"] = "2";
1192 (*sliding_line_properties)["pointRadius"] = "0";
1193 (*sliding_line_properties)["lineTension"] = "0";
1194 (*sliding_line_properties)["fill"] = "false";
1195 (*sliding_line_properties)["showLine"] = "true";
1196}
1197
1198VehicleState OnLanePlanning::AlignTimeStamp(const VehicleState& vehicle_state,
1199 const double curr_timestamp) const {
1200 // TODO(Jinyun): use the same method in trajectory stitching
1201 // for forward prediction
1202 auto future_xy = injector_->vehicle_state()->EstimateFuturePosition(
1203 curr_timestamp - vehicle_state.timestamp());
1204
1205 VehicleState aligned_vehicle_state = vehicle_state;
1206 aligned_vehicle_state.set_x(future_xy.x());
1207 aligned_vehicle_state.set_y(future_xy.y());
1208 aligned_vehicle_state.set_timestamp(curr_timestamp);
1209 return aligned_vehicle_state;
1210}
1211
1212void OnLanePlanning::AddPublishedAcceleration(
1213 const ADCTrajectory& trajectory_pb, planning_internal::Debug* debug) {
1214 // if open space info provider success run
1215 if (!frame_->open_space_info().open_space_provider_success()) {
1216 return;
1217 }
1218 double xmin(std::numeric_limits<double>::max()),
1219 xmax(std::numeric_limits<double>::lowest()),
1220 ymin(std::numeric_limits<double>::max()),
1221 ymax(std::numeric_limits<double>::lowest());
1222 auto chart = debug->mutable_planning_data()->add_chart();
1223 chart->set_title("Acceleration Partition Visualization");
1224 auto* options = chart->mutable_options();
1225 // options->mutable_x()->set_mid_value(Clock::NowInSeconds());
1226
1227 auto* acceleration_profile = chart->add_line();
1228 acceleration_profile->set_label("Acceleration Profile");
1229 for (const auto& point : trajectory_pb.trajectory_point()) {
1230 auto* point_debug = acceleration_profile->add_point();
1231 point_debug->set_x(point.relative_time() +
1232 trajectory_pb.header().timestamp_sec());
1233 if (trajectory_pb.gear() == canbus::Chassis::GEAR_DRIVE)
1234 point_debug->set_y(point.a());
1235 if (trajectory_pb.gear() == canbus::Chassis::GEAR_REVERSE)
1236 point_debug->set_y(-point.a());
1237 if (point_debug->x() > xmax) xmax = point_debug->x();
1238 if (point_debug->x() < xmin) xmin = point_debug->x();
1239 if (point_debug->y() > ymax) ymax = point_debug->y();
1240 if (point_debug->y() < ymin) ymin = point_debug->y();
1241 }
1242 options->mutable_x()->set_window_size(xmax - xmin);
1243 options->mutable_x()->set_label_string("time (s)");
1244 options->mutable_y()->set_min(ymin);
1245 options->mutable_y()->set_max(ymax);
1246 options->mutable_y()->set_label_string("acceleration (m/s)");
1247 // Set chartJS's dataset properties
1248 auto* acceleration_profile_properties =
1249 acceleration_profile->mutable_properties();
1250 (*acceleration_profile_properties)["borderWidth"] = "2";
1251 (*acceleration_profile_properties)["pointRadius"] = "0";
1252 (*acceleration_profile_properties)["lineTension"] = "0";
1253 (*acceleration_profile_properties)["fill"] = "false";
1254 (*acceleration_profile_properties)["showLine"] = "true";
1255
1256 auto* sliding_line = chart->add_line();
1257 sliding_line->set_label("Time");
1258
1259 auto* point_debug_up = sliding_line->add_point();
1260 point_debug_up->set_x(Clock::NowInSeconds());
1261 point_debug_up->set_y(2.1);
1262 auto* point_debug_down = sliding_line->add_point();
1263 point_debug_down->set_x(Clock::NowInSeconds());
1264 point_debug_down->set_y(-1.1);
1265
1266 // Set chartJS's dataset properties
1267 auto* sliding_line_properties = sliding_line->mutable_properties();
1268 (*sliding_line_properties)["borderWidth"] = "2";
1269 (*sliding_line_properties)["pointRadius"] = "0";
1270 (*sliding_line_properties)["lineTension"] = "0";
1271 (*sliding_line_properties)["fill"] = "false";
1272 (*sliding_line_properties)["showLine"] = "true";
1273}
1274
1275void OnLanePlanning::AddADCDrivingStateInfo(
1276 planning_internal::Debug* const debug) {
1277 debug->mutable_planning_data()->set_front_clear_distance(
1278 injector_->ego_info()->front_clear_distance());
1279
1280 DrivingStateGenerator state_generator;
1281 state_generator.generate(
1282 frame_->DriveReferenceLineInfo(), injector_->ego_info(),
1283 debug->mutable_planning_data()->mutable_adc_driving_state());
1284}
1285
1286} // namespace planning
1287} // namespace apollo
Define the birdview img feature renderer class
A general class to denote the return status of an API call.
Definition status.h:43
bool ok() const
check whether the return status is OK.
Definition status.h:67
const std::string & error_message() const
returns the error message of the status, empty if the status is OK.
Definition status.h:91
std::string ToString() const
returns a string representation in a readable format.
Definition status.h:98
void Save(StatusPb *status_pb)
save the error_code and error message to protobuf
Definition status.h:109
static Status OK()
generate a success status.
Definition status.h:60
static const VehicleConfig & GetConfig()
Get the current vehicle configuration.
Implements a class of 2-dimensional vectors.
Definition vec2d.h:42
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 * BaseMapPtr()
Frame holds all data for one planning cycle.
Definition frame.h:62
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
void RunOnce(const LocalView &local_view, ADCTrajectory *const ptr_trajectory_pb) override
main logic of the planning module, runs periodically triggered by timer.
common::Status Init(const PlanningConfig &config) override
module initialization function
std::string Name() const override
Planning name.
virtual apollo::common::Status Init(const PlanningConfig &config)
std::unique_ptr< Frame > frame_
virtual void FillPlanningPb(const double timestamp, ADCTrajectory *const trajectory_pb)
std::unique_ptr< PublishableTrajectory > last_publishable_trajectory_
const hdmap::HDMap * hdmap_
std::shared_ptr< Planner > planner_
std::shared_ptr< DependencyInjector > injector_
static double LookForwardDistance(const double velocity)
void AddAdcBox(double x, double y, double heading, bool is_rear_axle_point=true)
void AddPoint(std::string key, double x, double y)
add point to curve key
apollo::common::Status Smooth(const FrameHistory *frame_history, const Frame *current_frame, ADCTrajectory *const current_trajectory_pb)
Definition smoother.cc:55
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)
Planning module main class.
#define ACHECK(cond)
Definition log.h:80
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44
#define AINFO
Definition log.h:42
#define AWARN
Definition log.h:43
bool GetProtoFromFile(const std::string &file_name, google::protobuf::Message *message)
Parses the content of the file specified by the file_name as a representation of protobufs,...
Definition file.cc:132
bool IsVehicleStateValid(const VehicleState &vehicle_state)
Definition util.cc:35
bool IsDifferentRouting(const PlanningCommand &first, const PlanningCommand &second)
Definition util.cc:46
void SetChartminmax(apollo::dreamview::Chart *chart, std::string label_name_x, std::string label_name_y)
void AddSpeedPlan(const ::google::protobuf::RepeatedPtrField< SpeedPlan > &speed_plans, Chart *chart)
void AddSTGraph(const STGraphDebug &st_graph, Chart *chart)
void PopulateChartOptions(double x_min, double x_max, std::string x_label, double y_min, double y_max, std::string y_label, bool display, Chart *chart)
void AddSLFrame(const SLFrameDebug &sl_frame, Chart *chart)
class register implement
Definition arena_queue.h:37
Contains a number of helper functions related to quaternions.
Declaration of the class ReferenceLineProvider.
optional VehicleParam vehicle_param
optional LatencyStats latency_stats
repeated apollo::common::TrajectoryPoint trajectory_point
optional TrajectoryType trajectory_type
optional apollo::common::Header header
optional apollo::planning_internal::Debug debug
std::shared_ptr< routing::LaneWaypoint > end_lane_way_point
Definition local_view.h:49
std::shared_ptr< localization::LocalizationEstimate > localization_estimate
Definition local_view.h:43
std::shared_ptr< PlanningCommand > planning_command
Definition local_view.h:48
std::shared_ptr< control::ControlInteractiveMsg > control_interactive_msg
Definition local_view.h:50
std::shared_ptr< canbus::Chassis > chassis
Definition local_view.h:42
optional ReferenceLineConfig reference_line_config
optional PlanningLearningMode learning_mode
repeated apollo::common::SLPoint sl_path
repeated apollo::common::SpeedPoint speed_profile
LocalView contains all necessary data as planning input