├── figs
├── RSR.png
├── CCC_path.png
├── rosgraph.png
├── bicycle_model.png
├── vehicle_model.png
├── arc_length_calc.png
├── arc_length_algorithm.png
├── hybrid_astar_result1.png
├── hybrid_astar_result2.png
├── hybrid_astar_result3.png
├── hybrid_astar_result4.png
├── hybrid_astar_result5.png
├── hybrid_astar_result6.png
├── hybrid_astar_result7.png
├── reeds-shepp-curve-words.png
└── compute_tangents_via_the_vector_method.png
├── maps
├── map_demo.png
├── map_large.png
├── map_maze.png
├── map_dead_end.png
├── map_parking.png
└── map.yaml
├── launch
├── graph_search_node.launch
└── config.rviz
├── src
├── hybrid_a_star_node.cpp
├── graph_search_utils.cpp
├── a_star.cpp
└── hybrid_a_star.cpp
├── include
├── graph_search_utils.hpp
├── a_star.hpp
└── hybrid_a_star.hpp
├── package.xml
├── CMakeLists.txt
└── README.md
/figs/RSR.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stoneman404/hybrid-a-star/HEAD/figs/RSR.png
--------------------------------------------------------------------------------
/figs/CCC_path.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stoneman404/hybrid-a-star/HEAD/figs/CCC_path.png
--------------------------------------------------------------------------------
/figs/rosgraph.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stoneman404/hybrid-a-star/HEAD/figs/rosgraph.png
--------------------------------------------------------------------------------
/maps/map_demo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stoneman404/hybrid-a-star/HEAD/maps/map_demo.png
--------------------------------------------------------------------------------
/maps/map_large.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stoneman404/hybrid-a-star/HEAD/maps/map_large.png
--------------------------------------------------------------------------------
/maps/map_maze.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stoneman404/hybrid-a-star/HEAD/maps/map_maze.png
--------------------------------------------------------------------------------
/maps/map_dead_end.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stoneman404/hybrid-a-star/HEAD/maps/map_dead_end.png
--------------------------------------------------------------------------------
/maps/map_parking.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stoneman404/hybrid-a-star/HEAD/maps/map_parking.png
--------------------------------------------------------------------------------
/figs/bicycle_model.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stoneman404/hybrid-a-star/HEAD/figs/bicycle_model.png
--------------------------------------------------------------------------------
/figs/vehicle_model.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stoneman404/hybrid-a-star/HEAD/figs/vehicle_model.png
--------------------------------------------------------------------------------
/figs/arc_length_calc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stoneman404/hybrid-a-star/HEAD/figs/arc_length_calc.png
--------------------------------------------------------------------------------
/figs/arc_length_algorithm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stoneman404/hybrid-a-star/HEAD/figs/arc_length_algorithm.png
--------------------------------------------------------------------------------
/figs/hybrid_astar_result1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stoneman404/hybrid-a-star/HEAD/figs/hybrid_astar_result1.png
--------------------------------------------------------------------------------
/figs/hybrid_astar_result2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stoneman404/hybrid-a-star/HEAD/figs/hybrid_astar_result2.png
--------------------------------------------------------------------------------
/figs/hybrid_astar_result3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stoneman404/hybrid-a-star/HEAD/figs/hybrid_astar_result3.png
--------------------------------------------------------------------------------
/figs/hybrid_astar_result4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stoneman404/hybrid-a-star/HEAD/figs/hybrid_astar_result4.png
--------------------------------------------------------------------------------
/figs/hybrid_astar_result5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stoneman404/hybrid-a-star/HEAD/figs/hybrid_astar_result5.png
--------------------------------------------------------------------------------
/figs/hybrid_astar_result6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stoneman404/hybrid-a-star/HEAD/figs/hybrid_astar_result6.png
--------------------------------------------------------------------------------
/figs/hybrid_astar_result7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stoneman404/hybrid-a-star/HEAD/figs/hybrid_astar_result7.png
--------------------------------------------------------------------------------
/figs/reeds-shepp-curve-words.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stoneman404/hybrid-a-star/HEAD/figs/reeds-shepp-curve-words.png
--------------------------------------------------------------------------------
/figs/compute_tangents_via_the_vector_method.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/stoneman404/hybrid-a-star/HEAD/figs/compute_tangents_via_the_vector_method.png
--------------------------------------------------------------------------------
/maps/map.yaml:
--------------------------------------------------------------------------------
1 | image: map_large.png
2 | resolution: 0.5
3 | origin: [0.0, 0.0, 0.0]
4 | occupied_thresh: 0.1
5 | free_thresh: 0.05
6 | negate: 0
7 |
8 |
9 |
--------------------------------------------------------------------------------
/launch/graph_search_node.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/hybrid_a_star_node.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include
5 |
6 | int main(int argc, char **argv) {
7 | ros::init(argc, argv, "hybrid_a_star_planner");
8 | ros::NodeHandle nh;
9 | std::unique_ptr hybrid_a_star =
10 | std::make_unique(nh);
11 | ros::Rate loop_rate(10);
12 | while (ros::ok()) {
13 | ros::spinOnce();
14 | loop_rate.sleep();
15 | ros::Time begin = ros::Time::now();
16 | hybrid_a_star->RunOnce();
17 | ros::Time end = ros::Time::now();
18 | ros::Duration d(end - begin);
19 | ROS_WARN("[RUNONCE Time: %lf ms]", d.toSec() * 1000.0);
20 | }
21 | return 0;
22 | }
--------------------------------------------------------------------------------
/include/graph_search_utils.hpp:
--------------------------------------------------------------------------------
1 |
2 | #ifndef CATKIN_WS_SRC_GRAPH_SEARCH_PLANNER_INCLUDE_GRAPH_SEARCH_UTILS_HPP_
3 | #define CATKIN_WS_SRC_GRAPH_SEARCH_PLANNER_INCLUDE_GRAPH_SEARCH_UTILS_HPP_
4 |
5 | #include
6 | #include
7 | #include
8 |
9 | namespace planning {
10 |
11 | bool InBoudary(int index_x, int index_y,
12 | nav_msgs::OccupancyGrid::Ptr grid_map);
13 | void Index2Pose(int index_x, int index_y,
14 | nav_msgs::OccupancyGrid::Ptr grid_map,
15 | double *x, double *y);
16 | void Pose2Index(double x, double y,
17 | nav_msgs::OccupancyGrid::Ptr grid_map,
18 | int *index_x, int *index_y);
19 | int CalcIndex(int index_x, int index_y, int width, int height);
20 | bool CheckPose2d(double x, double y,
21 | nav_msgs::OccupancyGrid::Ptr grid_map);
22 | double NormalizeAngle(const double &angle);
23 | double CalcAngleDist(double from, double to);
24 | bool CheckPose3d(double base_x, double base_y, double base_phi,
25 | double adc_length, double adc_width,
26 | double axle_ref_x, double expand_dist,
27 | const nav_msgs::OccupancyGrid::Ptr &grid_map);
28 | bool CheckCircleRobotPose(double x, double y, double raidus,
29 | nav_msgs::OccupancyGrid::Ptr grid_map);
30 | }
31 |
32 | #endif //CATKIN_WS_SRC_GRAPH_SEARCH_PLANNER_INCLUDE_GRAPH_SEARCH_UTILS_HPP_
33 |
--------------------------------------------------------------------------------
/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | graph_search_planner
4 | 0.0.0
5 | The graph_search_planner package
6 |
7 |
8 |
9 |
10 | ldh
11 |
12 |
13 |
14 |
15 |
16 | TODO
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | catkin
52 | geometry_msgs
53 | nav_msgs
54 | roscpp
55 | rospy
56 | std_msgs
57 | tf
58 |
59 | geometry_msgs
60 | nav_msgs
61 | roscpp
62 | rospy
63 | std_msgs
64 | geometry_msgs
65 | nav_msgs
66 | roscpp
67 | rospy
68 |
69 | std_msgs
70 | tf
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/src/graph_search_utils.cpp:
--------------------------------------------------------------------------------
1 | #include "graph_search_utils.hpp"
2 |
3 | namespace planning {
4 | bool InBoudary(int index_x, int index_y, nav_msgs::OccupancyGrid::Ptr grid_map) {
5 | return index_x >= 0 && index_x < grid_map->info.width && index_y >= 0
6 | && index_y < grid_map->info.height;
7 | }
8 |
9 | void Index2Pose(int index_x, int index_y,
10 | nav_msgs::OccupancyGrid::Ptr grid_map,
11 | double *x, double *y) {
12 | const double theta = tf::getYaw(grid_map->info.origin.orientation);
13 | const double robot_x = index_x * grid_map->info.resolution;
14 | const double robot_y = index_y * grid_map->info.resolution;
15 | // const double relative_x = std::cos(theta) * robot_x - std::sin(theta) * robot_y;
16 | // const double relative_y = std::sin(theta) * robot_x + std::cos(theta) * robot_y;
17 | const double relative_x = robot_x;
18 | const double relative_y = robot_y;
19 | *x = grid_map->info.origin.position.x + relative_x;
20 | *y = grid_map->info.origin.position.y + relative_y;
21 | }
22 |
23 | void Pose2Index(double x, double y,
24 | nav_msgs::OccupancyGrid::Ptr grid_map,
25 | int *index_x, int *index_y) {
26 | // double origin_x = grid_map->info.origin.position.x;
27 | // double origin_y = grid_map->info.origin.position.y;
28 | // double origin_theta = tf::getYaw(grid_map->info.origin.orientation);
29 | // double dx = x - origin_x;
30 | // double dy = y - origin_y;
31 | // const double robot_x = std::cos(origin_theta) * dx + std::sin(origin_theta) * dy;
32 | // const double robot_y = -std::sin(origin_theta) * dx + std::cos(origin_theta) * dy;
33 | *index_x = static_cast(std::round(x / grid_map->info.resolution));
34 | *index_y = static_cast(std::round(y / grid_map->info.resolution));
35 | }
36 |
37 | int CalcIndex(int index_x, int index_y, int width, int height) {
38 | int index = index_y * width + index_x;
39 | return index;
40 | }
41 |
42 | bool CheckPose2d(double x, double y, nav_msgs::OccupancyGrid::Ptr grid_map) {
43 | int index_x, index_y;
44 | Pose2Index(x, y, grid_map, &index_x, &index_y);
45 | if (!InBoudary(index_x, index_y, grid_map)) {
46 | return false;
47 | }
48 | int index = CalcIndex(index_x, index_y, grid_map->info.width, grid_map->info.height);
49 | return grid_map->data[index] < 0.1;
50 | }
51 |
52 | double NormalizeAngle(const double &angle) {
53 | double a = std::fmod(angle + M_PI, 2.0 * M_PI);
54 | if (a < 0.0) {
55 | a += (2.0 * M_PI);
56 | }
57 | return a - M_PI;
58 | }
59 |
60 | double CalcAngleDist(double from, double to) {
61 | return NormalizeAngle(to - from);
62 | }
63 |
64 | bool CheckPose3d(double base_x, double base_y, double base_phi,
65 |
66 | double adc_length, double adc_width,
67 | double axle_ref_x, double expand_dist,
68 | const nav_msgs::OccupancyGrid::Ptr &grid_map) {
69 |
70 | const double adc_expand_length = adc_length + expand_dist;
71 | const double adc_expand_width = adc_width + expand_dist;
72 | const double axle2back = 0.5 * adc_expand_length - axle_ref_x;
73 | if (axle2back < 0.0) {
74 | return false;
75 | }
76 | const double left = -1.0 * axle2back;
77 | const double right = adc_expand_length - 1.0 * axle2back;
78 | const double top = adc_expand_width / 2.0;
79 | const double bottom = -adc_expand_width / 2.0;
80 | const double sin_phi = std::sin(base_phi);
81 | const double cos_phi = std::cos(base_phi);
82 | double xy_resolution = std::min(0.5, static_cast(grid_map->info.resolution));
83 | for (double x = left; x < right; x += xy_resolution) {
84 | for (double y = top; y > bottom; y -= xy_resolution) {
85 | double map_x = x * cos_phi - y * sin_phi + base_x;
86 | double map_y = x * sin_phi + y * cos_phi + base_y;
87 | if (!CheckPose2d(map_x, map_y, grid_map)) {
88 | return false;
89 | }
90 | }
91 | }
92 | return true;
93 | }
94 |
95 | bool CheckCircleRobotPose(double x, double y, double raidus,
96 | nav_msgs::OccupancyGrid::Ptr grid_map) {
97 | for (double theta = -M_PI; theta < M_PI; theta += 1.0 / 6.0 * M_PI) {
98 | for (double r = 0.0; r < raidus; r += grid_map->info.resolution) {
99 | double robot_x = x + r * std::cos(theta);
100 | double robot_y = y + r * std::sin(theta);
101 | if (!CheckPose2d(robot_x, robot_y, grid_map)) {
102 | return false;
103 | }
104 | }
105 | }
106 | return true;
107 | }
108 |
109 | }
110 |
111 |
--------------------------------------------------------------------------------
/include/a_star.hpp:
--------------------------------------------------------------------------------
1 | #ifndef PLANNING_ALGORITHM_SRC_GRAPH_SEARCH_PLANNER_INCLUDE_A_STAR_HPP_
2 | #define PLANNING_ALGORITHM_SRC_GRAPH_SEARCH_PLANNER_INCLUDE_A_STAR_HPP_
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include "graph_search_utils.hpp"
13 | #include