Apollo 11.0
自动驾驶开放平台
apollo::planning::HybridAStar类 参考

#include <hybrid_a_star.h>

apollo::planning::HybridAStar 的协作图:

Public 成员函数

 HybridAStar (const PlannerOpenSpaceConfig &open_space_conf)
 
virtual ~HybridAStar ()=default
 
bool TrajectoryPartition (const HybridAStartResult &result, std::vector< HybridAStartResult > *partitioned_result)
 
 HybridAStar (const WarmStartConfig &open_space_conf)
 
bool Plan (double sx, double sy, double sphi, double ex, double ey, double ephi, const std::vector< double > &XYbounds, const std::vector< std::vector< common::math::Vec2d > > &obstacles_vertices_vec, HybridAStartResult *result, const std::vector< std::vector< common::math::Vec2d > > &soft_boundary_vertices_vec={}, bool reeds_sheep_last_straight=false)
 

详细描述

在文件 hybrid_a_star.h 第 59 行定义.

构造及析构函数说明

◆ HybridAStar() [1/2]

apollo::planning::HybridAStar::HybridAStar ( const PlannerOpenSpaceConfig &  open_space_conf)
explicit

在文件 hybrid_a_star.cc 第 38 行定义.

38 {
39 planner_open_space_config_.CopyFrom(open_space_conf);
40 reed_shepp_generator_ = std::make_unique<ReedShepp>(vehicle_param_, planner_open_space_config_);
41 grid_a_star_heuristic_generator_ = std::make_unique<GridSearch>(planner_open_space_config_);
42 next_node_num_ = planner_open_space_config_.warm_start_config().next_node_num();
43 max_steer_angle_ = vehicle_param_.max_steer_angle() / vehicle_param_.steer_ratio()
44 * planner_open_space_config_.warm_start_config().traj_kappa_contraint_ratio();
45 step_size_ = planner_open_space_config_.warm_start_config().step_size();
46 xy_grid_resolution_ = planner_open_space_config_.warm_start_config().xy_grid_resolution();
47 arc_length_ = planner_open_space_config_.warm_start_config().phi_grid_resolution() * vehicle_param_.wheel_base()
48 / std::tan(max_steer_angle_ * 2 / (next_node_num_ / 2 - 1));
49 if (arc_length_ < std::sqrt(2) * xy_grid_resolution_) {
50 arc_length_ = std::sqrt(2) * xy_grid_resolution_;
51 }
52 AINFO << "arc_length" << arc_length_;
53 delta_t_ = planner_open_space_config_.delta_t();
54 traj_forward_penalty_ = planner_open_space_config_.warm_start_config().traj_forward_penalty();
55 traj_back_penalty_ = planner_open_space_config_.warm_start_config().traj_back_penalty();
56 traj_gear_switch_penalty_ = planner_open_space_config_.warm_start_config().traj_gear_switch_penalty();
57 traj_steer_penalty_ = planner_open_space_config_.warm_start_config().traj_steer_penalty();
58 traj_steer_change_penalty_ = planner_open_space_config_.warm_start_config().traj_steer_change_penalty();
59 acc_weight_ = planner_open_space_config_.iterative_anchoring_smoother_config().s_curve_config().acc_weight();
60 jerk_weight_ = planner_open_space_config_.iterative_anchoring_smoother_config().s_curve_config().jerk_weight();
61 kappa_penalty_weight_
63 ref_s_weight_ = planner_open_space_config_.iterative_anchoring_smoother_config().s_curve_config().ref_s_weight();
64 ref_v_weight_ = planner_open_space_config_.iterative_anchoring_smoother_config().s_curve_config().ref_v_weight();
65 max_forward_v_ = planner_open_space_config_.iterative_anchoring_smoother_config().max_forward_v();
66 max_reverse_v_ = planner_open_space_config_.iterative_anchoring_smoother_config().max_reverse_v();
67 max_forward_acc_ = planner_open_space_config_.iterative_anchoring_smoother_config().max_forward_acc();
68 max_reverse_acc_ = planner_open_space_config_.iterative_anchoring_smoother_config().max_reverse_acc();
69 max_acc_jerk_ = planner_open_space_config_.iterative_anchoring_smoother_config().max_acc_jerk();
70}
#define AINFO
Definition log.h:42
optional IterativeAnchoringConfig iterative_anchoring_smoother_config

◆ ~HybridAStar()

virtual apollo::planning::HybridAStar::~HybridAStar ( )
virtualdefault

◆ HybridAStar() [2/2]

apollo::planning::HybridAStar::HybridAStar ( const WarmStartConfig &  open_space_conf)
explicit

在文件 hybrid_a_star.cc 第 72 行定义.

72 {
73 planner_warm_start_config_.CopyFrom(warm_start_conf);
74 reed_shepp_generator_ = std::make_unique<ReedShepp>(vehicle_param_, planner_warm_start_config_);
75 grid_a_star_heuristic_generator_ = std::make_unique<GridSearch>(planner_warm_start_config_);
76 next_node_num_ = planner_warm_start_config_.next_node_num();
77 max_steer_angle_ = vehicle_param_.max_steer_angle() / vehicle_param_.steer_ratio()
78 * planner_warm_start_config_.traj_kappa_contraint_ratio();
79 max_kappa_ = std::tan(max_steer_angle_) / vehicle_param_.wheel_base();
80 step_size_ = planner_warm_start_config_.step_size();
81 xy_grid_resolution_ = planner_warm_start_config_.xy_grid_resolution();
82 arc_length_ = std::sqrt(2) * xy_grid_resolution_;
83 AINFO << "arc_length" << arc_length_;
84 delta_t_ = FLAGS_open_space_delta_t;
85 traj_forward_penalty_ = planner_warm_start_config_.traj_forward_penalty();
86 traj_back_penalty_ = planner_warm_start_config_.traj_back_penalty();
87 traj_gear_switch_penalty_ = planner_warm_start_config_.traj_gear_switch_penalty();
88 traj_steer_penalty_ = planner_warm_start_config_.traj_steer_penalty();
89 traj_steer_change_penalty_ = planner_warm_start_config_.traj_steer_change_penalty();
90 soft_boundary_penalty_ = planner_warm_start_config_.soft_boundary_penalty();
91 acc_weight_ = FLAGS_open_space_acc_weight;
92 jerk_weight_ = FLAGS_open_space_jerk_weight;
93 kappa_penalty_weight_ = FLAGS_open_space_kappa_weight;
94 ref_s_weight_ = FLAGS_open_space_reference_s_weight;
95 ref_v_weight_ = FLAGS_open_space_reference_v_weight;
96 max_forward_v_ = FLAGS_open_space_max_forward_v;
97 max_reverse_v_ = FLAGS_open_space_max_reverse_v;
98 max_forward_acc_ = FLAGS_open_space_max_forward_acc;
99 max_reverse_acc_ = FLAGS_open_space_max_reverse_acc;
100 max_acc_jerk_ = FLAGS_open_space_max_jerk;
101 traj_expected_shortest_length_ = planner_warm_start_config_.traj_expected_shortest_length();
102 traj_short_length_penalty_ = planner_warm_start_config_.traj_short_length_penalty();
103}

成员函数说明

◆ Plan()

bool apollo::planning::HybridAStar::Plan ( double  sx,
double  sy,
double  sphi,
double  ex,
double  ey,
double  ephi,
const std::vector< double > &  XYbounds,
const std::vector< std::vector< common::math::Vec2d > > &  obstacles_vertices_vec,
HybridAStartResult *  result,
const std::vector< std::vector< common::math::Vec2d > > &  soft_boundary_vertices_vec = {},
bool  reeds_sheep_last_straight = false 
)

在文件 hybrid_a_star.cc 第 693 行定义.

704 {
705 reed_shepp_generator_->reeds_sheep_last_straight_ = reeds_sheep_last_straight;
706 // clear containers
707 open_set_.clear();
708 close_set_.clear();
709 open_pq_ = decltype(open_pq_)();
710 final_node_ = nullptr;
711 PrintCurves print_curves;
712 std::vector<std::vector<common::math::LineSegment2d>> obstacles_linesegments_vec;
713 for (const auto& obstacle_vertices : obstacles_vertices_vec) {
714 size_t vertices_num = obstacle_vertices.size();
715 std::vector<common::math::LineSegment2d> obstacle_linesegments;
716 for (size_t i = 0; i < vertices_num - 1; ++i) {
717 common::math::LineSegment2d line_segment
718 = common::math::LineSegment2d(obstacle_vertices[i], obstacle_vertices[i + 1]);
719 obstacle_linesegments.emplace_back(line_segment);
720 }
721 obstacles_linesegments_vec.emplace_back(obstacle_linesegments);
722 }
723 obstacles_linesegments_vec_ = std::move(obstacles_linesegments_vec);
724 std::vector<std::vector<common::math::LineSegment2d>> soft_boundary_linesegments_vec;
725 for (const auto& soft_boundary_vertices : soft_boundary_vertices_vec) {
726 size_t vertices_num = soft_boundary_vertices.size();
727 std::vector<common::math::LineSegment2d> soft_boundary_linesegments;
728 for (size_t i = 0; i < vertices_num - 1; ++i) {
729 common::math::LineSegment2d line_segment
730 = common::math::LineSegment2d(soft_boundary_vertices[i], soft_boundary_vertices[i + 1]);
731 soft_boundary_linesegments.emplace_back(line_segment);
732 }
733 soft_boundary_linesegments_vec.emplace_back(soft_boundary_linesegments);
734 }
735 soft_boundary_linesegments_vec_ = std::move(soft_boundary_linesegments_vec);
736 for (size_t i = 0; i < obstacles_linesegments_vec_.size(); i++) {
737 for (auto linesg : obstacles_linesegments_vec_[i]) {
738 std::string name = std::to_string(i) + "roi_boundary";
739 print_curves.AddPoint(name, linesg.start());
740 print_curves.AddPoint(name, linesg.end());
741 }
742 }
743 Vec2d sposition(sx, sy);
744 Vec2d svec_to_center(
745 (vehicle_param_.front_edge_to_center() - vehicle_param_.back_edge_to_center()) / 2.0,
746 (vehicle_param_.left_edge_to_center() - vehicle_param_.right_edge_to_center()) / 2.0);
747 Vec2d scenter(sposition + svec_to_center.rotate(sphi));
748 Box2d sbox(scenter, sphi, vehicle_param_.length(), vehicle_param_.width());
749 print_curves.AddPoint("vehicle_start_box", sbox.GetAllCorners());
750 Vec2d eposition(ex, ey);
751 print_curves.AddPoint("end_position", eposition);
752 Vec2d evec_to_center(
753 (vehicle_param_.front_edge_to_center() - vehicle_param_.back_edge_to_center()) / 2.0,
754 (vehicle_param_.left_edge_to_center() - vehicle_param_.right_edge_to_center()) / 2.0);
755 Vec2d ecenter(eposition + evec_to_center.rotate(ephi));
756 Box2d ebox(ecenter, ephi, vehicle_param_.length(), vehicle_param_.width());
757 print_curves.AddPoint("vehicle_end_box", ebox.GetAllCorners());
758 XYbounds_ = XYbounds;
759 // load nodes and obstacles
760 start_node_.reset(new Node3d({sx}, {sy}, {sphi}, XYbounds_, planner_warm_start_config_));
761 end_node_.reset(new Node3d({ex}, {ey}, {ephi}, XYbounds_, planner_warm_start_config_));
762 AINFO << "start node" << sx << "," << sy << "," << sphi;
763 AINFO << "end node " << ex << "," << ey << "," << ephi;
764 if (!ValidityCheck(start_node_)) {
765 AERROR << "start_node in collision with obstacles";
766 AERROR << start_node_->GetX() << "," << start_node_->GetY() << "," << start_node_->GetPhi();
767 print_curves.PrintToLog();
768 return false;
769 }
770 if (!ValidityCheck(end_node_)) {
771 AERROR << "end_node in collision with obstacles";
772 print_curves.PrintToLog();
773 return false;
774 }
775 double map_time = Clock::NowInSeconds();
776 grid_a_star_heuristic_generator_->GenerateDpMap(
777 ex, ey, XYbounds_, obstacles_linesegments_vec_, soft_boundary_linesegments_vec_);
778 ADEBUG << "map time " << Clock::NowInSeconds() - map_time;
779 // load open set, pq
780 open_set_.insert(start_node_->GetIndex());
781 open_pq_.emplace(start_node_, start_node_->GetCost());
782 // Hybrid A* begins
783 size_t explored_node_num = 0;
784 size_t available_result_num = 0;
785 auto best_explored_num = explored_node_num;
786 auto best_available_result_num = available_result_num;
787 double astar_start_time = Clock::NowInSeconds();
788 double heuristic_time = 0.0;
789 double rs_time = 0.0;
790 double node_generator_time = 0.0;
791 double validity_check_time = 0.0;
792 size_t max_explored_num = planner_warm_start_config_.max_explored_num();
793 size_t desired_explored_num = std::min(
794 planner_warm_start_config_.desired_explored_num(), planner_warm_start_config_.max_explored_num());
795 static constexpr int kMaxNodeNum = 200000;
796 std::vector<std::shared_ptr<Node3d>> candidate_final_nodes;
797 while (!open_pq_.empty() && open_pq_.size() < kMaxNodeNum && available_result_num < desired_explored_num
798 && explored_node_num < max_explored_num) {
799 std::shared_ptr<Node3d> current_node = open_pq_.top().first;
800 if (current_node->GetPreNode() != nullptr) {
801 AINFO << "print_open_pq:" << "(" << current_node->GetPreNode()->GetX() << ", "
802 << current_node->GetPreNode()->GetY() << ")" << ";" << "(" << current_node->GetX() << ", "
803 << current_node->GetY() << ");";
804 }
805 open_pq_.pop();
806 const double rs_start_time = Clock::NowInSeconds();
807 std::shared_ptr<Node3d> final_node = nullptr;
808 if (AnalyticExpansion(current_node, &final_node)) {
809 if (final_node_ == nullptr || final_node_->GetTrajCost() > final_node->GetTrajCost()) {
810 final_node_ = final_node;
811 best_explored_num = explored_node_num + 1;
812 best_available_result_num = available_result_num + 1;
813 }
814 available_result_num++;
815 }
816 explored_node_num++;
817 const double rs_end_time = Clock::NowInSeconds();
818 rs_time += rs_end_time - rs_start_time;
819 close_set_.insert(current_node->GetIndex());
820
821 if (Clock::NowInSeconds() - astar_start_time > planner_warm_start_config_.astar_max_search_time()
822 && available_result_num > 0) {
823 break;
824 }
825
826 size_t begin_index = 0;
827 size_t end_index = next_node_num_;
828 std::unordered_set<std::string> temp_set;
829 for (size_t i = begin_index; i < end_index; ++i) {
830 const double gen_node_time = Clock::NowInSeconds();
831 std::shared_ptr<Node3d> next_node = Next_node_generator(current_node, i);
832 node_generator_time += Clock::NowInSeconds() - gen_node_time;
833
834 // boundary check failure handle
835 if (next_node == nullptr) {
836 continue;
837 }
838 // check if the node is already in the close set
839 if (close_set_.count(next_node->GetIndex()) > 0) {
840 continue;
841 }
842 // collision check
843 const double validity_check_start_time = Clock::NowInSeconds();
844 if (!ValidityCheck(next_node)) {
845 continue;
846 }
847 validity_check_time += Clock::NowInSeconds() - validity_check_start_time;
848 if (open_set_.count(next_node->GetIndex()) == 0) {
849 const double start_time = Clock::NowInSeconds();
850 CalculateNodeCost(current_node, next_node);
851 const double end_time = Clock::NowInSeconds();
852 heuristic_time += end_time - start_time;
853 temp_set.insert(next_node->GetIndex());
854 open_pq_.emplace(next_node, next_node->GetCost());
855 }
856 }
857 open_set_.insert(temp_set.begin(), temp_set.end());
858 }
859
860 if (final_node_ == nullptr) {
861 AERROR << "Hybird A* cannot find a valid path";
862 print_curves.PrintToLog();
863 return false;
864 }
865
866 AINFO << "open_pq_.empty()" << (open_pq_.empty() ? "true" : "false");
867 AINFO << "open_pq_.size()" << open_pq_.size();
868 AINFO << "desired_explored_num" << desired_explored_num;
869 AINFO << "min cost is : " << final_node_->GetTrajCost();
870 AINFO << "max_explored_num is " << max_explored_num;
871 AINFO << "explored node num is " << explored_node_num << "available_result_num " << available_result_num;
872 AINFO << "best_explored_num is " << best_explored_num << "best_available_result_num is "
873 << best_available_result_num;
874 AINFO << "cal node time is " << heuristic_time << "validity_check_time " << validity_check_time
875 << "node_generator_time " << node_generator_time;
876 AINFO << "reed shepp time is " << rs_time;
877 AINFO << "hybrid astar total time is " << Clock::NowInSeconds() - astar_start_time;
878
879 print_curves.AddPoint("rs_point", final_node_->GetXs().front(), final_node_->GetYs().front());
880 if (!GetResult(result)) {
881 AERROR << "GetResult failed";
882 print_curves.PrintToLog();
883 return false;
884 }
885 for (size_t i = 0; i < result->x.size(); i++) {
886 print_curves.AddPoint("warm_path", result->x[i], result->y[i]);
887 }
888 // PrintBox print_box("warm_path_box");
889 // for (size_t i = 0; i < result->x.size(); i = i + 5) {
890 // print_box.AddAdcBox(result->x[i], result->y[i], result->phi[i]);
891 // }
892 // print_box.PrintToLog();
893 print_curves.PrintToLog();
894 return true;
895}
static double NowInSeconds()
gets the current time in second.
Definition clock.cc:56
#define ADEBUG
Definition log.h:41
#define AERROR
Definition log.h:44

◆ TrajectoryPartition()

bool apollo::planning::HybridAStar::TrajectoryPartition ( const HybridAStartResult &  result,
std::vector< HybridAStartResult > *  partitioned_result 
)

在文件 hybrid_a_star.cc 第 603 行定义.

605 {
606 const auto& x = result.x;
607 const auto& y = result.y;
608 const auto& phi = result.phi;
609 if (x.size() != y.size() || x.size() != phi.size()) {
610 AERROR << "states sizes are not equal when do trajectory partitioning of "
611 "Hybrid A Star result";
612 return false;
613 }
614
615 size_t horizon = x.size();
616 partitioned_result->clear();
617 partitioned_result->emplace_back();
618 auto* current_traj = &(partitioned_result->back());
619 double heading_angle = phi.front();
620 const Vec2d init_tracking_vector(x[1] - x[0], y[1] - y[0]);
621 double tracking_angle = init_tracking_vector.Angle();
622 bool current_gear = std::abs(common::math::NormalizeAngle(tracking_angle - heading_angle)) < (M_PI_2);
623 AINFO << x[0] << " " << y[0] << " " << phi[0];
624 for (size_t i = 0; i < horizon - 1; ++i) {
625 heading_angle = phi[i];
626 const Vec2d tracking_vector(x[i + 1] - x[i], y[i + 1] - y[i]);
627 tracking_angle = tracking_vector.Angle();
628 bool gear = std::abs(common::math::NormalizeAngle(tracking_angle - heading_angle)) < (M_PI_2);
629 if (gear != current_gear) {
630 current_traj->x.push_back(x[i]);
631 current_traj->y.push_back(y[i]);
632 current_traj->phi.push_back(phi[i]);
633 partitioned_result->emplace_back();
634 current_traj = &(partitioned_result->back());
635 current_gear = gear;
636 }
637 current_traj->x.push_back(x[i]);
638 current_traj->y.push_back(y[i]);
639 current_traj->phi.push_back(phi[i]);
640 }
641 AINFO << x.back() << " " << y.back() << " " << phi.back();
642 current_traj->x.push_back(x.back());
643 current_traj->y.push_back(y.back());
644 current_traj->phi.push_back(phi.back());
645
646 const auto start_timestamp = std::chrono::system_clock::now();
647
648 // Retrieve v, a and steer from path
649 for (auto& result : *partitioned_result) {
650 if (FLAGS_use_s_curve_speed_smooth) {
651 if (!GenerateSCurveSpeedAcceleration(&result)) {
652 AERROR << "GenerateSCurveSpeedAcceleration fail";
653 return false;
654 }
655 } else {
656 if (!GenerateSpeedAcceleration(&result)) {
657 AERROR << "GenerateSpeedAcceleration fail";
658 return false;
659 }
660 }
661 }
662
663 const auto end_timestamp = std::chrono::system_clock::now();
664 std::chrono::duration<double> diff = end_timestamp - start_timestamp;
665 ADEBUG << "speed profile total time: " << diff.count() * 1000.0 << " ms.";
666 return true;
667}
double NormalizeAngle(const double angle)
Normalize angle to [-PI, PI).
Definition math_utils.cc:53
float diff(Image< float > *I, int x1, int y1, int x2, int y2)
Dissimilarity measure between pixels

该类的文档由以下文件生成: