Skip to content

Commit c5d5c2d

Browse files
docs(planner): updating docs for global planner accepting viapoints. (#904)
Signed-off-by: Sanchit B <researchbadamikar@gmail.com>
1 parent 39e9f73 commit c5d5c2d

3 files changed

Lines changed: 53 additions & 25 deletions

File tree

configuration/packages/bt-plugins/actions/ComputePathToPose.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,17 @@ Input Ports
4343
Description
4444
Goal pose. Takes in a blackboard variable, e.g. "{goal}".
4545

46+
:viapoints:
47+
48+
============================================= =======
49+
Type Default
50+
--------------------------------------------- -------
51+
std::vector<geometry_msgs::msg::PoseStamped> N/A
52+
============================================= =======
53+
54+
Description
55+
Optional. A list of intermediate viapoints (excluding goal) to consider for planning. Takes in a blackboard variable, e.g. "{viapoints}".
56+
4657
:planner_id:
4758

4859
============== =======

migration/Kilted.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -938,3 +938,10 @@ Key changes:
938938
- New parameters ``publish_scan``, ``odom_publish_dur``, and ``scan_noise_std`` are available.
939939

940940
See :ref:`configuring_loopback_sim` for full parameter documentation.
941+
942+
Global planner plugin natively accepts viapoints
943+
-------------------------------------------------
944+
945+
`PR #5995 <https://github.com/ros-navigation/navigation2/pull/5995>`_ updates the ``createPath`` API for the ``BaseGlobalPlanner`` to include a vector ``std::vector<geometry_msgs::msg::PoseStamped>`` argument that takes in a list of intermediate points and passes them to the planner plugin implementation.
946+
947+
The function signature for ``createPath`` must be updated accordingly for all custom planner plugins inheriting from the ``BaseGlobalPlanner``. This change does not alter the behavior of ``ComputePathThroughPoses`` that connects consecutive segments end-to-end but does upgrade the ``ComputePathToPose`` action.

plugin_tutorials/docs/writing_new_nav2planner_plugin.rst

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,10 @@ Let's learn more about the methods needed to write a planner plugin.
5959
| | method should clean up resources which are created for the planner. | |
6060
+----------------------+-----------------------------------------------------------------------------+-------------------------+
6161
| createPlan() | Method is called when planner server demands a global plan for specified | Yes |
62-
| | start and goal pose. This method returns `nav_msgs\:\:msg\:\:Path` carrying | |
63-
| | global plan. This method takes 3 input params: start pose, goal pose and | |
64-
| | a function to check if the action has been canceled. | |
62+
| | start pose, goal pose, and intermediate viapoint poses. This method returns | |
63+
| | `nav_msgs\:\:msg\:\:Path` carrying global plan. This method takes 4 input | |
64+
| | params: start pose, goal pose, a vector of intermediate poses and a function| |
65+
| | to check if the action has been canceled. | |
6566
+----------------------+-----------------------------------------------------------------------------+-------------------------+
6667

6768
For this tutorial, we will be using methods ``StraightLine::configure()`` and ``StraightLine::createPlan()`` to create straight-line planner.
@@ -82,12 +83,16 @@ In planners, ``configure()`` method must set member variables from ROS parameter
8283

8384
Here, ``name_ + ".interpolation_resolution"`` is fetching the ROS parameters ``interpolation_resolution`` which is specific to our planner. Nav2 allows the loading of multiple plugins, and to keep things organized, each plugin is mapped to some ID/name. Now if we want to retrieve the parameters for that specific plugin, we use ``<mapped_name_of_plugin>.<name_of_parameter>`` as done in the above snippet. For example, our example planner is mapped to the name "GridBased" and to retrieve the ``interpolation_resolution`` parameter which is specific to "GridBased", we used ``Gridbased.interpolation_resolution``. In other words, ``GridBased`` is used as a namespace for plugin-specific parameters. We will see more on this when we discuss the parameters file (or params file).
8485

85-
In ``createPlan()`` method, we need to create a path from the given start to goal poses. The ``StraightLine::createPlan()`` is called using start pose and goal pose to solve the global path planning problem. Upon succeeding, it converts the path to the ``nav_msgs::msg::Path`` and returns to the planner server. Below annotation shows the implementation of this method.
86+
In ``createPlan()`` method, we need to create a path from the given start to goal poses, passing through intermediate viapoints if provided. The ``StraightLine::createPlan()`` is called with a start pose, a goal pose, and a vector of intermediate viapoints to solve the global path planning problem. Upon succeeding, it converts the path to the ``nav_msgs::msg::Path`` and returns to the planner server. Below annotation shows the implementation of this method.
8687

8788
.. code-block:: c++
8889

8990
nav_msgs::msg::Path global_path;
9091

92+
// copy the viapoints and append the goal since intermediate points would not include the goal
93+
std::vector<geometry_msgs::msg::PoseStamped> goals = viapoints;
94+
goals.push_back(goal);
95+
9196
// Checking if the goal and start state is in the global frame
9297
if (start.header.frame_id != global_frame_) {
9398
RCLCPP_ERROR(
@@ -106,28 +111,33 @@ In ``createPlan()`` method, we need to create a path from the given start to goa
106111
global_path.poses.clear();
107112
global_path.header.stamp = node_->now();
108113
global_path.header.frame_id = global_frame_;
109-
// calculating the number of loops for current value of interpolation_resolution_
110-
int total_number_of_loop = std::hypot(
111-
goal.pose.position.x - start.pose.position.x,
112-
goal.pose.position.y - start.pose.position.y) /
113-
interpolation_resolution_;
114-
double x_increment = (goal.pose.position.x - start.pose.position.x) / total_number_of_loop;
115-
double y_increment = (goal.pose.position.y - start.pose.position.y) / total_number_of_loop;
116-
117-
for (int i = 0; i < total_number_of_loop; ++i) {
118-
geometry_msgs::msg::PoseStamped pose;
119-
pose.pose.position.x = start.pose.position.x + x_increment * i;
120-
pose.pose.position.y = start.pose.position.y + y_increment * i;
121-
pose.pose.position.z = 0.0;
122-
pose.pose.orientation.x = 0.0;
123-
pose.pose.orientation.y = 0.0;
124-
pose.pose.orientation.z = 0.0;
125-
pose.pose.orientation.w = 1.0;
126-
pose.header.stamp = node_->now();
127-
pose.header.frame_id = global_frame_;
128-
global_path.poses.push_back(pose);
129-
}
130114

115+
geometry_msgs::msg::PoseStamped start_i = start;
116+
for (auto goal_i : goals)
117+
{
118+
// calculating the number of loops for current value of interpolation_resolution_
119+
int total_number_of_loop = std::hypot(
120+
goal_i.pose.position.x - start_i.pose.position.x,
121+
goal_i.pose.position.y - start_i.pose.position.y) /
122+
interpolation_resolution_;
123+
double x_increment = (goal_i.pose.position.x - start_i.pose.position.x) / total_number_of_loop;
124+
double y_increment = (goal_i.pose.position.y - start_i.pose.position.y) / total_number_of_loop;
125+
126+
for (int i = 0; i < total_number_of_loop; ++i) {
127+
geometry_msgs::msg::PoseStamped pose;
128+
pose.pose.position.x = start_i.pose.position.x + x_increment * i;
129+
pose.pose.position.y = start_i.pose.position.y + y_increment * i;
130+
pose.pose.position.z = 0.0;
131+
pose.pose.orientation.x = 0.0;
132+
pose.pose.orientation.y = 0.0;
133+
pose.pose.orientation.z = 0.0;
134+
pose.pose.orientation.w = 1.0;
135+
pose.header.stamp = node_->now();
136+
pose.header.frame_id = global_frame_;
137+
global_path.poses.push_back(pose);
138+
}
139+
start_i = goal_i;
140+
}
131141
global_path.poses.push_back(goal);
132142

133143
return global_path;

0 commit comments

Comments
 (0)