Skip to content

Commit 3b81383

Browse files
author
Takumi Ito
committed
- Add method getWaypoints() into the astar class.
- No need to convert to serial when user passes ros2 message to methods. Signed-off-by: Takumi Ito <takumi.ito@tier4.jp>
1 parent fc0085b commit 3b81383

File tree

4 files changed

+90
-17
lines changed

4 files changed

+90
-17
lines changed

planning/freespace_planning_algorithms/CMakeLists.txt

+5-5
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,17 @@ find_package(Python3 REQUIRED COMPONENTS Interpreter Development)
6060
find_package(pybind11_vendor REQUIRED)
6161
find_package(pybind11 REQUIRED)
6262

63-
pybind11_add_module(freespace_planning_algorithms_python SHARED
63+
pybind11_add_module(${PROJECT_NAME}_pybind SHARED
6464
scripts/bind/astar_search_pybind.cpp
6565
)
6666

67-
include_directories(freespace_planning_algorithms_python PRIVATE
67+
include_directories(${PROJECT_NAME}_pybind PRIVATE
6868
include/
6969
)
70-
target_link_libraries(freespace_planning_algorithms_python PRIVATE
71-
freespace_planning_algorithms
70+
target_link_libraries(${PROJECT_NAME}_pybind PRIVATE
71+
${PROJECT_NAME}
7272
)
7373

74-
install(TARGETS freespace_planning_algorithms_python
74+
install(TARGETS ${PROJECT_NAME}_pybind
7575
DESTINATION "${PYTHON_INSTALL_DIR}/${PROJECT_NAME}"
7676
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
from nav_msgs.msg import OccupancyGrid
2+
from geometry_msgs.msg import Pose, Point, Quaternion
3+
4+
import freespace_planning_algorithms.freespace_planning_algorithms_pybind as _fp
5+
from rclpy.serialization import serialize_message
6+
7+
PlannerCommonParam = _fp.PlannerCommonParam
8+
VehicleShape = _fp.VehicleShape
9+
AstarParam = _fp.AstarParam
10+
11+
class PlannerWaypoints:
12+
def __init__(self):
13+
self.waypoints = []
14+
self.length = 0.0
15+
16+
def compute_length(self):
17+
return self.length
18+
19+
class AstarSearch:
20+
def __init__(self, planner_param: PlannerCommonParam, vehicle_shape: VehicleShape, astar_param: AstarParam):
21+
self.astar_search = _fp.AstarSearch(planner_param, vehicle_shape, astar_param)
22+
23+
def setMap(self, costmap: OccupancyGrid):
24+
costmap_byte = serialize_message(costmap)
25+
self.astar_search.setMap(costmap_byte)
26+
27+
def makePlan(self, start_pose: Pose, goal_pose: Pose):
28+
start_pose_byte = serialize_message(start_pose)
29+
goal_pose_byte = serialize_message(goal_pose)
30+
return self.astar_search.makePlan(start_pose_byte, goal_pose_byte)
31+
32+
def getWaypoints(self):
33+
waypoints_vetor = self.astar_search.getWaypoints()
34+
waypoints = PlannerWaypoints()
35+
36+
waypoints.length = waypoints_vetor.length
37+
for waypoint in waypoints_vetor.waypoints:
38+
pos = Point(x=waypoint[0], y=waypoint[1], z=waypoint[2])
39+
quat = Quaternion(x=waypoint[3], y=waypoint[4], z=waypoint[5], w=waypoint[6])
40+
waypoints.waypoints.append(Pose(position=pos, orientation=quat))
41+
42+
return waypoints

planning/freespace_planning_algorithms/scripts/bind/astar_search_pybind.cpp

+39-8
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,17 @@
2222
#include <nav_msgs/msg/occupancy_grid.hpp>
2323

2424
#include <pybind11/pybind11.h>
25+
#include <pybind11/stl.h>
2526

2627
using namespace freespace_planning_algorithms;
2728

29+
struct PlannerWaypointsVector
30+
{
31+
std::vector<std::vector<double>> waypoints;
32+
double length;
33+
};
34+
35+
2836
class AstarSearchPython : public AstarSearch
2937
{
3038
using AstarSearch::AstarSearch;
@@ -71,12 +79,33 @@ class AstarSearchPython : public AstarSearch
7179

7280
return AstarSearch::makePlan(start_pose, goal_pose);
7381
}
82+
83+
PlannerWaypointsVector getWaypointsAsVector()
84+
{
85+
PlannerWaypoints waypoints = AstarSearch::getWaypoints();
86+
PlannerWaypointsVector waypoints_vector;
87+
for (const auto& waypoint : waypoints.waypoints)
88+
{
89+
// NOTE: it was difficult to return the deserialized pose_byte and serialize the pose_byte on
90+
// python-side. So this function returns [*position, *quaternion] as double array
91+
const auto & xyz = waypoint.pose.pose.position;
92+
const auto & quat = waypoint.pose.pose.orientation;
93+
waypoints_vector.waypoints.push_back(std::vector<double>({xyz.x, xyz.y, xyz.z, quat.x, quat.y, quat.z, quat.w}));
94+
}
95+
waypoints_vector.length = waypoints.compute_length();
96+
return waypoints_vector;
97+
}
7498
};
7599

76100
namespace py = pybind11;
77101

78-
PYBIND11_MODULE(freespace_planning_algorithms_python, p)
102+
PYBIND11_MODULE(freespace_planning_algorithms_pybind, p)
79103
{
104+
auto pyPlannerWaypointsVector =
105+
py::class_<PlannerWaypointsVector>(p, "PlannerWaypointsVector", py::dynamic_attr())
106+
.def(py::init<>())
107+
.def_readwrite("waypoints", &PlannerWaypointsVector::waypoints)
108+
.def_readwrite("length", &PlannerWaypointsVector::length);
80109
auto pyAstarParam =
81110
py::class_<AstarParam>(p, "AstarParam", py::dynamic_attr())
82111
.def(py::init<>())
@@ -97,17 +126,19 @@ PYBIND11_MODULE(freespace_planning_algorithms_python, p)
97126
.def_readwrite("longitudinal_goal_range", &PlannerCommonParam::longitudinal_goal_range)
98127
.def_readwrite("angle_goal_range", &PlannerCommonParam::angle_goal_range)
99128
.def_readwrite("obstacle_threshold", &PlannerCommonParam::obstacle_threshold);
100-
auto pyVSehicleShape = py::class_<VehicleShape>(p, "VehicleShape", py::dynamic_attr())
101-
.def(py::init<>())
102-
.def(py::init<double, double, double>())
103-
.def_readwrite("length", &VehicleShape::length)
104-
.def_readwrite("width", &VehicleShape::width)
105-
.def_readwrite("base2back", &VehicleShape::base2back);
129+
auto pyVSehicleShape =
130+
py::class_<VehicleShape>(p, "VehicleShape", py::dynamic_attr())
131+
.def(py::init<>())
132+
.def(py::init<double, double, double>())
133+
.def_readwrite("length", &VehicleShape::length)
134+
.def_readwrite("width", &VehicleShape::width)
135+
.def_readwrite("base2back", &VehicleShape::base2back);
106136

107137
py::class_<AbstractPlanningAlgorithm>(p, "AbstractPlanningAlgorithm");
108138
py::class_<AstarSearch, AbstractPlanningAlgorithm>(p, "AstarSearchCpp");
109139
py::class_<AstarSearchPython, AstarSearch>(p, "AstarSearch")
110140
.def(py::init<PlannerCommonParam &, VehicleShape &, AstarParam &>())
111141
.def("setMap", &AstarSearchPython::setMapByte)
112-
.def("makePlan", &AstarSearchPython::makePlanByte);
142+
.def("makePlan", &AstarSearchPython::makePlanByte)
143+
.def("getWaypoints", &AstarSearchPython::getWaypointsAsVector);
113144
}

planning/freespace_planning_algorithms/scripts/example/example.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import freespace_planning_algorithms.freespace_planning_algorithms_python as fp
1+
import freespace_planning_algorithms.astar_search as fp
22
from geometry_msgs.msg import Pose
33
from nav_msgs.msg import OccupancyGrid
44
from pyquaternion import Quaternion
5-
from rclpy.serialization import serialize_message
65

76
# -- Vehicle Shape --
87
vehicle_shape = fp.VehicleShape()
@@ -50,7 +49,7 @@
5049
costmap.info.origin.position.y = -size * resolution / 2
5150
costmap.data = [0 for i in range(size**2)]
5251

53-
astar.setMap(serialize_message(costmap))
52+
astar.setMap(costmap)
5453

5554

5655
# -- Start and Goal Pose
@@ -73,7 +72,8 @@
7372

7473

7574
# -- Search --
76-
if astar.makePlan(serialize_message(start_pose), serialize_message(goal_pose)):
75+
if astar.makePlan(start_pose, goal_pose):
7776
print("Success to find path.")
77+
print(" Path length:", astar.getWaypoints().length)
7878
else:
7979
print("Fail to find path.")

0 commit comments

Comments
 (0)