39 #include "nav2_controller/plugins/simple_goal_checker.hpp"
40 #include "pluginlib/class_list_macros.hpp"
41 #include "angles/angles.h"
42 #include "nav2_ros_common/node_utils.hpp"
43 #include "nav2_util/geometry_utils.hpp"
44 #include "tf2/utils.hpp"
46 using rcl_interfaces::msg::ParameterType;
47 using std::placeholders::_1;
49 namespace nav2_controller
53 : xy_goal_tolerance_(0.25),
54 xy_goal_tolerance_buffer_(0.0),
55 yaw_goal_tolerance_(0.25),
56 path_length_tolerance_(1.0),
59 symmetric_yaw_tolerance_(false),
60 xy_goal_tolerance_sq_(0.0625),
61 xy_goal_tolerance_reset_sq_(0.0625)
67 auto node = node_.lock();
68 if (post_set_params_handler_ && node) {
69 node->remove_post_set_parameters_callback(post_set_params_handler_.get());
71 post_set_params_handler_.reset();
72 if (on_set_params_handler_ && node) {
73 node->remove_on_set_parameters_callback(on_set_params_handler_.get());
75 on_set_params_handler_.reset();
79 const nav2::LifecycleNode::WeakPtr & parent,
80 const std::string & plugin_name,
81 const std::shared_ptr<nav2_costmap_2d::Costmap2DROS>)
83 plugin_name_ = plugin_name;
85 auto node = node_.lock();
86 logger_ = node->get_logger();
88 xy_goal_tolerance_ = node->declare_or_get_parameter(plugin_name +
".xy_goal_tolerance", 0.25);
89 xy_goal_tolerance_buffer_ = node->declare_or_get_parameter(
90 plugin_name +
".xy_goal_tolerance_buffer", 0.0);
91 yaw_goal_tolerance_ = node->declare_or_get_parameter(plugin_name +
".yaw_goal_tolerance", 0.25);
92 path_length_tolerance_ = node->declare_or_get_parameter(
93 plugin_name +
".path_length_tolerance", 1.0);
94 stateful_ = node->declare_or_get_parameter(plugin_name +
".stateful",
true);
95 symmetric_yaw_tolerance_ = node->declare_or_get_parameter(
96 plugin_name +
".symmetric_yaw_tolerance",
false);
98 xy_goal_tolerance_sq_ = xy_goal_tolerance_ * xy_goal_tolerance_;
99 xy_goal_tolerance_reset_sq_ = (xy_goal_tolerance_ + xy_goal_tolerance_buffer_) *
100 (xy_goal_tolerance_ + xy_goal_tolerance_buffer_);
103 post_set_params_handler_ = node->add_post_set_parameters_callback(
106 this, std::placeholders::_1));
107 on_set_params_handler_ = node->add_on_set_parameters_callback(
110 this, std::placeholders::_1));
119 const geometry_msgs::msg::Pose & query_pose,
const geometry_msgs::msg::Pose & goal_pose,
120 const geometry_msgs::msg::Twist & velocity,
const nav_msgs::msg::Path & transformed_global_plan)
122 if (!
isGoalXYReached(query_pose, goal_pose, velocity, transformed_global_plan)) {
126 std::lock_guard<std::mutex> lock_reinit(mutex_);
128 double query_yaw = tf2::getYaw(query_pose.orientation);
129 double goal_yaw = tf2::getYaw(goal_pose.orientation);
130 if (symmetric_yaw_tolerance_) {
132 double dyaw_forward = angles::shortest_angular_distance(query_yaw, goal_yaw);
133 double dyaw_backward = angles::shortest_angular_distance(
134 query_yaw, angles::normalize_angle(goal_yaw + M_PI));
136 bool forward_match = fabs(dyaw_forward) <= yaw_goal_tolerance_;
137 bool backward_match = fabs(dyaw_backward) <= yaw_goal_tolerance_;
139 return forward_match || backward_match;
141 double dyaw = angles::shortest_angular_distance(query_yaw, goal_yaw);
142 return fabs(dyaw) <= yaw_goal_tolerance_;
147 const geometry_msgs::msg::Pose & query_pose,
const geometry_msgs::msg::Pose & goal_pose,
148 const geometry_msgs::msg::Twist &,
const nav_msgs::msg::Path & transformed_global_plan)
150 std::lock_guard<std::mutex> lock_reinit(mutex_);
152 if (nav2_util::geometry_utils::calculate_path_length(transformed_global_plan) >
153 path_length_tolerance_)
158 double dx = query_pose.position.x - goal_pose.position.x,
159 dy = query_pose.position.y - goal_pose.position.y;
160 if (dx * dx + dy * dy > xy_goal_tolerance_sq_) {
168 }
else if (stateful_ && xy_goal_tolerance_buffer_ > 0.0) {
171 double dx = query_pose.position.x - goal_pose.position.x,
172 dy = query_pose.position.y - goal_pose.position.y;
173 if (dx * dx + dy * dy > xy_goal_tolerance_reset_sq_) {
183 geometry_msgs::msg::Pose & pose_tolerance,
184 geometry_msgs::msg::Twist & vel_tolerance,
185 double & path_length_tolerance)
187 std::lock_guard<std::mutex> lock_reinit(mutex_);
188 double invalid_field = std::numeric_limits<double>::lowest();
190 pose_tolerance.position.x = xy_goal_tolerance_;
191 pose_tolerance.position.y = xy_goal_tolerance_;
192 pose_tolerance.position.z = invalid_field;
193 pose_tolerance.orientation =
194 nav2_util::geometry_utils::orientationAroundZAxis(yaw_goal_tolerance_);
196 vel_tolerance.linear.x = invalid_field;
197 vel_tolerance.linear.y = invalid_field;
198 vel_tolerance.linear.z = invalid_field;
200 vel_tolerance.angular.x = invalid_field;
201 vel_tolerance.angular.y = invalid_field;
202 vel_tolerance.angular.z = invalid_field;
204 path_length_tolerance = path_length_tolerance_;
209 rcl_interfaces::msg::SetParametersResult
211 const std::vector<rclcpp::Parameter> & parameters)
213 rcl_interfaces::msg::SetParametersResult result;
214 result.successful =
true;
215 for (
const auto & parameter : parameters) {
216 const auto & param_type = parameter.get_type();
217 const auto & param_name = parameter.get_name();
218 if (param_name.find(plugin_name_ +
".") != 0) {
221 if (param_type == ParameterType::PARAMETER_DOUBLE) {
222 if (parameter.as_double() < 0.0) {
224 logger_,
"The value of parameter '%s' is incorrectly set to %f, "
225 "it should be >=0. Ignoring parameter update.",
226 param_name.c_str(), parameter.as_double());
227 result.successful =
false;
236 const std::vector<rclcpp::Parameter> & parameters)
238 std::lock_guard<std::mutex> lock_reinit(mutex_);
239 rcl_interfaces::msg::SetParametersResult result;
240 for (
const auto & parameter : parameters) {
241 const auto & param_type = parameter.get_type();
242 const auto & param_name = parameter.get_name();
243 if (param_name.find(plugin_name_ +
".") != 0) {
246 if (param_type == ParameterType::PARAMETER_DOUBLE) {
247 if (param_name == plugin_name_ +
".xy_goal_tolerance") {
248 xy_goal_tolerance_ = parameter.as_double();
249 xy_goal_tolerance_sq_ = xy_goal_tolerance_ * xy_goal_tolerance_;
250 xy_goal_tolerance_reset_sq_ = (xy_goal_tolerance_ + xy_goal_tolerance_buffer_) *
251 (xy_goal_tolerance_ + xy_goal_tolerance_buffer_);
252 }
else if (param_name == plugin_name_ +
".xy_goal_tolerance_buffer") {
253 xy_goal_tolerance_buffer_ = parameter.as_double();
254 xy_goal_tolerance_reset_sq_ = (xy_goal_tolerance_ + xy_goal_tolerance_buffer_) *
255 (xy_goal_tolerance_ + xy_goal_tolerance_buffer_);
256 }
else if (param_name == plugin_name_ +
".yaw_goal_tolerance") {
257 yaw_goal_tolerance_ = parameter.as_double();
258 }
else if (param_name == plugin_name_ +
".path_length_tolerance") {
259 path_length_tolerance_ = parameter.as_double();
261 }
else if (param_type == ParameterType::PARAMETER_BOOL) {
262 if (param_name == plugin_name_ +
".stateful") {
263 stateful_ = parameter.as_bool();
264 }
else if (param_name == plugin_name_ +
".symmetric_yaw_tolerance") {
265 symmetric_yaw_tolerance_ = parameter.as_bool();
Goal Checker plugin that only checks the position difference.
bool getTolerances(geometry_msgs::msg::Pose &pose_tolerance, geometry_msgs::msg::Twist &vel_tolerance, double &path_length_tolerance) override
Get the position and velocity tolerances.
void reset() override
Reset the goal checker state.
bool isGoalReached(const geometry_msgs::msg::Pose &query_pose, const geometry_msgs::msg::Pose &goal_pose, const geometry_msgs::msg::Twist &velocity, const nav_msgs::msg::Path &transformed_global_plan) override
Check if the goal is reached.
~SimpleGoalChecker()
Destroy the Simple Goal Checker object.
void updateParametersCallback(const std::vector< rclcpp::Parameter > ¶meters)
Apply parameter updates after validation This callback is executed when parameters have been successf...
SimpleGoalChecker()
Construct a new Simple Goal Checker object.
bool isGoalXYReached(const geometry_msgs::msg::Pose &query_pose, const geometry_msgs::msg::Pose &goal_pose, const geometry_msgs::msg::Twist &velocity, const nav_msgs::msg::Path &transformed_global_plan) override
Check if XY goal position has been reached (without considering yaw)
rcl_interfaces::msg::SetParametersResult validateParameterUpdatesCallback(const std::vector< rclcpp::Parameter > ¶meters)
Validate incoming parameter updates before applying them. This callback is triggered when one or more...
void initialize(const nav2::LifecycleNode::WeakPtr &parent, const std::string &plugin_name, const std::shared_ptr< nav2_costmap_2d::Costmap2DROS > costmap_ros) override
Initialize the goal checker.
Function-object for checking whether a goal has been reached.