Skip to content

Commit c37ba58

Browse files
Merge pull request #5179 from mini-1235/bp/5162
Backport 5162 to Jazzy
2 parents 2dde228 + 4bd7dcf commit c37ba58

File tree

11 files changed

+299
-89
lines changed

11 files changed

+299
-89
lines changed

nav2_controller/CMakeLists.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ add_library(stopped_goal_checker SHARED plugins/stopped_goal_checker.cpp)
6262
target_link_libraries(stopped_goal_checker simple_goal_checker)
6363
ament_target_dependencies(stopped_goal_checker ${dependencies})
6464

65+
add_library(position_goal_checker SHARED plugins/position_goal_checker.cpp)
66+
target_link_libraries(position_goal_checker simple_goal_checker)
67+
ament_target_dependencies(position_goal_checker ${dependencies})
68+
6569
ament_target_dependencies(${library_name}
6670
${dependencies}
6771
)
@@ -84,7 +88,7 @@ target_link_libraries(${executable_name} ${library_name})
8488

8589
rclcpp_components_register_nodes(${library_name} "nav2_controller::ControllerServer")
8690

87-
install(TARGETS simple_progress_checker pose_progress_checker simple_goal_checker stopped_goal_checker ${library_name}
91+
install(TARGETS simple_progress_checker position_goal_checker pose_progress_checker simple_goal_checker stopped_goal_checker ${library_name}
8892
ARCHIVE DESTINATION lib
8993
LIBRARY DESTINATION lib
9094
RUNTIME DESTINATION bin
@@ -110,6 +114,7 @@ ament_export_libraries(simple_progress_checker
110114
pose_progress_checker
111115
simple_goal_checker
112116
stopped_goal_checker
117+
position_goal_checker
113118
${library_name})
114119
ament_export_dependencies(${dependencies})
115120
pluginlib_export_plugin_description_file(nav2_core plugins.xml)
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright (c) 2025 Prabhav Saxena
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef NAV2_CONTROLLER__PLUGINS__POSITION_GOAL_CHECKER_HPP_
16+
#define NAV2_CONTROLLER__PLUGINS__POSITION_GOAL_CHECKER_HPP_
17+
18+
#include <string>
19+
#include <memory>
20+
#include <vector>
21+
#include "rclcpp/rclcpp.hpp"
22+
#include "rclcpp_lifecycle/lifecycle_node.hpp"
23+
#include "nav2_core/goal_checker.hpp"
24+
#include "nav2_costmap_2d/costmap_2d_ros.hpp"
25+
26+
namespace nav2_controller
27+
{
28+
29+
/**
30+
* @class PositionGoalChecker
31+
* @brief Goal Checker plugin that only checks XY position, ignoring orientation
32+
*/
33+
class PositionGoalChecker : public nav2_core::GoalChecker
34+
{
35+
public:
36+
PositionGoalChecker();
37+
~PositionGoalChecker() override = default;
38+
39+
void initialize(
40+
const rclcpp_lifecycle::LifecycleNode::WeakPtr & parent,
41+
const std::string & plugin_name,
42+
const std::shared_ptr<nav2_costmap_2d::Costmap2DROS> costmap_ros) override;
43+
44+
void reset() override;
45+
46+
bool isGoalReached(
47+
const geometry_msgs::msg::Pose & query_pose, const geometry_msgs::msg::Pose & goal_pose,
48+
const geometry_msgs::msg::Twist & velocity) override;
49+
50+
bool getTolerances(
51+
geometry_msgs::msg::Pose & pose_tolerance,
52+
geometry_msgs::msg::Twist & vel_tolerance) override;
53+
54+
/**
55+
* @brief Set the XY goal tolerance
56+
* @param tolerance New tolerance value
57+
*/
58+
void setXYGoalTolerance(double tolerance);
59+
60+
protected:
61+
double xy_goal_tolerance_;
62+
double xy_goal_tolerance_sq_;
63+
bool stateful_;
64+
bool position_reached_;
65+
std::string plugin_name_;
66+
rclcpp::Node::OnSetParametersCallbackHandle::SharedPtr dyn_params_handler_;
67+
68+
/**
69+
* @brief Callback executed when a parameter change is detected
70+
* @param parameters list of changed parameters
71+
*/
72+
rcl_interfaces::msg::SetParametersResult
73+
dynamicParametersCallback(std::vector<rclcpp::Parameter> parameters);
74+
};
75+
76+
} // namespace nav2_controller
77+
78+
#endif // NAV2_CONTROLLER__PLUGINS__POSITION_GOAL_CHECKER_HPP_

nav2_controller/plugins.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,9 @@
1919
<description>Checks linear and angular velocity after stopping</description>
2020
</class>
2121
</library>
22+
<library path="position_goal_checker">
23+
<class type="nav2_controller::PositionGoalChecker" base_class_type="nav2_core::GoalChecker">
24+
<description>Goal checker that only checks XY position and ignores orientation</description>
25+
</class>
26+
</library>
2227
</class_libraries>
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
// Copyright (c) 2025 Prabhav Saxena
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include <memory>
16+
#include <string>
17+
#include <limits>
18+
#include "nav2_controller/plugins/position_goal_checker.hpp"
19+
#include "pluginlib/class_list_macros.hpp"
20+
#include "nav2_util/node_utils.hpp"
21+
22+
using rcl_interfaces::msg::ParameterType;
23+
using std::placeholders::_1;
24+
25+
namespace nav2_controller
26+
{
27+
28+
PositionGoalChecker::PositionGoalChecker()
29+
: xy_goal_tolerance_(0.25),
30+
xy_goal_tolerance_sq_(0.0625),
31+
stateful_(true),
32+
position_reached_(false)
33+
{
34+
}
35+
36+
void PositionGoalChecker::initialize(
37+
const rclcpp_lifecycle::LifecycleNode::WeakPtr & parent,
38+
const std::string & plugin_name,
39+
const std::shared_ptr<nav2_costmap_2d::Costmap2DROS>/*costmap_ros*/)
40+
{
41+
plugin_name_ = plugin_name;
42+
auto node = parent.lock();
43+
44+
nav2_util::declare_parameter_if_not_declared(
45+
node,
46+
plugin_name + ".xy_goal_tolerance", rclcpp::ParameterValue(0.25));
47+
nav2_util::declare_parameter_if_not_declared(
48+
node,
49+
plugin_name + ".stateful", rclcpp::ParameterValue(true));
50+
51+
node->get_parameter(plugin_name + ".xy_goal_tolerance", xy_goal_tolerance_);
52+
node->get_parameter(plugin_name + ".stateful", stateful_);
53+
54+
xy_goal_tolerance_sq_ = xy_goal_tolerance_ * xy_goal_tolerance_;
55+
56+
// Add callback for dynamic parameters
57+
dyn_params_handler_ = node->add_on_set_parameters_callback(
58+
std::bind(&PositionGoalChecker::dynamicParametersCallback, this, _1));
59+
}
60+
61+
void PositionGoalChecker::reset()
62+
{
63+
position_reached_ = false;
64+
}
65+
66+
bool PositionGoalChecker::isGoalReached(
67+
const geometry_msgs::msg::Pose & query_pose, const geometry_msgs::msg::Pose & goal_pose,
68+
const geometry_msgs::msg::Twist &)
69+
{
70+
// If stateful and position was already reached, maintain state
71+
if (stateful_ && position_reached_) {
72+
return true;
73+
}
74+
75+
// Check if position is within tolerance
76+
double dx = query_pose.position.x - goal_pose.position.x;
77+
double dy = query_pose.position.y - goal_pose.position.y;
78+
79+
bool position_reached = (dx * dx + dy * dy <= xy_goal_tolerance_sq_);
80+
81+
// If stateful, remember that we reached the position
82+
if (stateful_ && position_reached) {
83+
position_reached_ = true;
84+
}
85+
86+
return position_reached;
87+
}
88+
89+
bool PositionGoalChecker::getTolerances(
90+
geometry_msgs::msg::Pose & pose_tolerance,
91+
geometry_msgs::msg::Twist & vel_tolerance)
92+
{
93+
double invalid_field = std::numeric_limits<double>::lowest();
94+
95+
pose_tolerance.position.x = xy_goal_tolerance_;
96+
pose_tolerance.position.y = xy_goal_tolerance_;
97+
pose_tolerance.position.z = invalid_field;
98+
99+
// Return zero orientation tolerance as we don't check it
100+
pose_tolerance.orientation.x = 0.0;
101+
pose_tolerance.orientation.y = 0.0;
102+
pose_tolerance.orientation.z = 0.0;
103+
pose_tolerance.orientation.w = 1.0;
104+
105+
vel_tolerance.linear.x = invalid_field;
106+
vel_tolerance.linear.y = invalid_field;
107+
vel_tolerance.linear.z = invalid_field;
108+
109+
vel_tolerance.angular.x = invalid_field;
110+
vel_tolerance.angular.y = invalid_field;
111+
vel_tolerance.angular.z = invalid_field;
112+
113+
return true;
114+
}
115+
116+
void nav2_controller::PositionGoalChecker::setXYGoalTolerance(double tolerance)
117+
{
118+
xy_goal_tolerance_ = tolerance;
119+
xy_goal_tolerance_sq_ = tolerance * tolerance;
120+
}
121+
122+
rcl_interfaces::msg::SetParametersResult
123+
PositionGoalChecker::dynamicParametersCallback(std::vector<rclcpp::Parameter> parameters)
124+
{
125+
rcl_interfaces::msg::SetParametersResult result;
126+
for (auto & parameter : parameters) {
127+
const auto & param_type = parameter.get_type();
128+
const auto & param_name = parameter.get_name();
129+
if (param_name.find(plugin_name_ + ".") != 0) {
130+
continue;
131+
}
132+
133+
if (param_type == ParameterType::PARAMETER_DOUBLE) {
134+
if (param_name == plugin_name_ + ".xy_goal_tolerance") {
135+
xy_goal_tolerance_ = parameter.as_double();
136+
xy_goal_tolerance_sq_ = xy_goal_tolerance_ * xy_goal_tolerance_;
137+
}
138+
} else if (param_type == ParameterType::PARAMETER_BOOL) {
139+
if (param_name == plugin_name_ + ".stateful") {
140+
stateful_ = parameter.as_bool();
141+
}
142+
}
143+
}
144+
result.successful = true;
145+
return result;
146+
}
147+
148+
} // namespace nav2_controller
149+
150+
PLUGINLIB_EXPORT_CLASS(nav2_controller::PositionGoalChecker, nav2_core::GoalChecker)

nav2_rotation_shim_controller/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ project(nav2_rotation_shim_controller)
33

44
find_package(ament_cmake REQUIRED)
55
find_package(nav2_common REQUIRED)
6+
find_package(nav2_controller REQUIRED)
67
find_package(nav2_core REQUIRED)
78
find_package(nav2_costmap_2d REQUIRED)
89
find_package(nav2_util REQUIRED)
@@ -30,6 +31,7 @@ set(dependencies
3031
nav2_core
3132
tf2
3233
angles
34+
nav2_controller
3335
)
3436

3537
set(library_name nav2_rotation_shim_controller)

nav2_rotation_shim_controller/README.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,14 @@ See its [Configuration Guide Page](https://docs.nav2.org/configuration/packages/
3131

3232
| Parameter | Description |
3333
|-----|----|
34-
| `angular_dist_threshold` | Maximum angular distance, in radians, away from the path heading to trigger rotation until within. |
35-
| `forward_sampling_distance` | Forward distance, in meters, along path to select a sampling point to use to approximate path heading |
36-
| `rotate_to_heading_angular_vel` | Angular rotational velocity, in rad/s, to rotate to the path heading |
37-
| `primary_controller` | Internal controller plugin to use for actual control behavior after rotating to heading |
38-
| `max_angular_accel` | Maximum angular acceleration for rotation to heading |
39-
| `simulate_ahead_time` | Time in seconds to forward simulate a rotation command to check for collisions. If a collision is found, forwards control back to the primary controller plugin. |
40-
| `rotate_to_goal_heading` | If true, the rotationShimController will take back control of the robot when in XY tolerance of the goal and start rotating to the goal heading |
34+
| `angular_dist_threshold` | Maximum angular distance, in radians, away from the path heading to trigger rotation until within. |
35+
| `forward_sampling_distance` | Forward distance, in meters, along path to select a sampling point to use to approximate path heading |
36+
| `rotate_to_heading_angular_vel` | Angular rotational velocity, in rad/s, to rotate to the path heading |
37+
| `primary_controller` | Internal controller plugin to use for actual control behavior after rotating to heading |
38+
| `max_angular_accel` | Maximum angular acceleration for rotation to heading |
39+
| `simulate_ahead_time` | Time in seconds to forward simulate a rotation command to check for collisions. If a collision is found, forwards control back to the primary controller plugin. |
40+
| `rotate_to_goal_heading` | If true, the rotationShimController will take back control of the robot when in XY tolerance of the goal and start rotating to the goal heading |
41+
| `use_path_orientations` | If true, the controller will use the orientations of the path points to compute the heading of the path instead of computing the heading from the path points. If true, the controller will use the orientations of the path points to compute the heading of the path instead of computing the heading from the path points. Use for for feasible planners like the Smac Planner which generate feasible paths with orientations for forward and reverse motion. |
4142

4243
Example fully-described XML with default parameter values:
4344

@@ -70,6 +71,7 @@ controller_server:
7071
max_angular_accel: 3.2
7172
simulate_ahead_time: 1.0
7273
rotate_to_goal_heading: false
74+
use_path_orientations: false
7375
7476
# DWB parameters
7577
...

nav2_rotation_shim_controller/include/nav2_rotation_shim_controller/nav2_rotation_shim_controller.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "nav2_core/controller_exceptions.hpp"
3232
#include "nav2_util/node_utils.hpp"
3333
#include "nav2_costmap_2d/footprint_collision_checker.hpp"
34+
#include "nav2_controller/plugins/position_goal_checker.hpp"
3435
#include "angles/angles.h"
3536

3637
namespace nav2_rotation_shim_controller
@@ -190,11 +191,13 @@ class RotationShimController : public nav2_core::Controller
190191
double control_duration_, simulate_ahead_time_;
191192
bool rotate_to_goal_heading_, in_rotation_, rotate_to_heading_once_;
192193
bool closed_loop_;
194+
bool use_path_orientations_;
193195
double last_angular_vel_ = std::numeric_limits<double>::max();
194196

195197
// Dynamic parameters handler
196198
std::mutex mutex_;
197199
rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr dyn_params_handler_;
200+
std::unique_ptr<nav2_controller::PositionGoalChecker> position_goal_checker_;
198201
};
199202

200203
} // namespace nav2_rotation_shim_controller

nav2_rotation_shim_controller/include/nav2_rotation_shim_controller/tools/utils.hpp

Lines changed: 0 additions & 60 deletions
This file was deleted.

0 commit comments

Comments
 (0)