Nav2 Navigation Stack - lyrical  lyrical
ROS 2 Navigation Stack
stopped_goal_checker.cpp
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2017, Locus Robotics
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above
14  * copyright notice, this list of conditions and the following
15  * disclaimer in the documentation and/or other materials provided
16  * with the distribution.
17  * * Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived
19  * from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include <cmath>
36 #include <string>
37 #include <memory>
38 #include <limits>
39 #include <vector>
40 #include "nav2_controller/plugins/stopped_goal_checker.hpp"
41 #include "pluginlib/class_list_macros.hpp"
42 #include "nav2_ros_common/node_utils.hpp"
43 
44 using std::hypot;
45 using std::fabs;
46 
47 using rcl_interfaces::msg::ParameterType;
48 using std::placeholders::_1;
49 
50 namespace nav2_controller
51 {
52 
54 : SimpleGoalChecker(), rot_stopped_velocity_(0.25), trans_stopped_velocity_(0.25)
55 {
56 }
57 
59 {
60  auto node = node_.lock();
61  if (post_set_params_handler_ && node) {
62  node->remove_post_set_parameters_callback(post_set_params_handler_.get());
63  }
64  post_set_params_handler_.reset();
65  if (on_set_params_handler_ && node) {
66  node->remove_on_set_parameters_callback(on_set_params_handler_.get());
67  }
68  on_set_params_handler_.reset();
69 }
70 
72  const nav2::LifecycleNode::WeakPtr & parent,
73  const std::string & plugin_name,
74  const std::shared_ptr<nav2_costmap_2d::Costmap2DROS> costmap_ros)
75 {
76  plugin_name_ = plugin_name;
77  SimpleGoalChecker::initialize(parent, plugin_name, costmap_ros);
78 
79  node_ = parent;
80  auto node = node_.lock();
81  logger_ = node->get_logger();
82 
83  rot_stopped_velocity_ = node->declare_or_get_parameter(
84  plugin_name + ".rot_stopped_velocity", 0.25);
85  trans_stopped_velocity_ = node->declare_or_get_parameter(
86  plugin_name + ".trans_stopped_velocity", 0.25);
87 
88  // Add callback for dynamic parameters
89  post_set_params_handler_ = node->add_post_set_parameters_callback(
90  std::bind(
92  this, std::placeholders::_1));
93  on_set_params_handler_ = node->add_on_set_parameters_callback(
94  std::bind(
96  this, std::placeholders::_1));
97 }
98 
100  const geometry_msgs::msg::Pose & query_pose, const geometry_msgs::msg::Pose & goal_pose,
101  const geometry_msgs::msg::Twist & velocity, const nav_msgs::msg::Path & transformed_global_plan)
102 {
103  std::lock_guard<std::mutex> lock_reinit(mutex_);
104  bool ret = SimpleGoalChecker::isGoalReached(query_pose, goal_pose, velocity,
105  transformed_global_plan);
106  if (!ret) {
107  return ret;
108  }
109 
110  return fabs(velocity.angular.z) <= rot_stopped_velocity_ &&
111  hypot(velocity.linear.x, velocity.linear.y) <= trans_stopped_velocity_;
112 }
113 
115  const geometry_msgs::msg::Pose & query_pose, const geometry_msgs::msg::Pose & goal_pose,
116  const geometry_msgs::msg::Twist & velocity, const nav_msgs::msg::Path & transformed_global_plan)
117 {
118  return SimpleGoalChecker::isGoalXYReached(query_pose, goal_pose, velocity,
119  transformed_global_plan);
120 }
121 
123  geometry_msgs::msg::Pose & pose_tolerance,
124  geometry_msgs::msg::Twist & vel_tolerance,
125  double & path_length_tolerance)
126 {
127  std::lock_guard<std::mutex> lock_reinit(mutex_);
128  double invalid_field = std::numeric_limits<double>::lowest();
129 
130  // populate the poses
131  bool rtn = SimpleGoalChecker::getTolerances(pose_tolerance, vel_tolerance, path_length_tolerance);
132 
133  // override the velocities
134  vel_tolerance.linear.x = trans_stopped_velocity_;
135  vel_tolerance.linear.y = trans_stopped_velocity_;
136  vel_tolerance.linear.z = invalid_field;
137 
138  vel_tolerance.angular.x = invalid_field;
139  vel_tolerance.angular.y = invalid_field;
140  vel_tolerance.angular.z = rot_stopped_velocity_;
141 
142  path_length_tolerance = path_length_tolerance_;
143 
144  return true && rtn;
145 }
146 
147 rcl_interfaces::msg::SetParametersResult
149  const std::vector<rclcpp::Parameter> & parameters)
150 {
151  rcl_interfaces::msg::SetParametersResult result;
152  result.successful = true;
153  for (const auto & parameter : parameters) {
154  const auto & param_type = parameter.get_type();
155  const auto & param_name = parameter.get_name();
156  if (param_name.find(plugin_name_ + ".") != 0) {
157  continue;
158  }
159  if (param_type == ParameterType::PARAMETER_DOUBLE) {
160  if (parameter.as_double() < 0.0) {
161  RCLCPP_WARN(
162  logger_, "The value of parameter '%s' is incorrectly set to %f, "
163  "it should be >=0. Ignoring parameter update.",
164  param_name.c_str(), parameter.as_double());
165  result.successful = false;
166  }
167  }
168  }
169  return result;
170 }
171 
172 void
174  const std::vector<rclcpp::Parameter> & parameters)
175 {
176  std::lock_guard<std::mutex> lock_reinit(mutex_);
177  rcl_interfaces::msg::SetParametersResult result;
178  for (const auto & parameter : parameters) {
179  const auto & param_type = parameter.get_type();
180  const auto & param_name = parameter.get_name();
181  if (param_name.find(plugin_name_ + ".") != 0) {
182  continue;
183  }
184 
185  if (param_type == ParameterType::PARAMETER_DOUBLE) {
186  if (param_name == plugin_name_ + ".rot_stopped_velocity") {
187  rot_stopped_velocity_ = parameter.as_double();
188  } else if (param_name == plugin_name_ + ".trans_stopped_velocity") {
189  trans_stopped_velocity_ = parameter.as_double();
190  }
191  }
192  }
193 }
194 
195 } // namespace nav2_controller
196 
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.
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.
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)
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.
Goal Checker plugin that checks the position difference and velocity.
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.
rcl_interfaces::msg::SetParametersResult validateParameterUpdatesCallback(const std::vector< rclcpp::Parameter > &parameters)
Validate incoming parameter updates before applying them. This callback is triggered when one or more...
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.
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)
StoppedGoalChecker()
Construct a new Stopped Goal Checker object.
void updateParametersCallback(const std::vector< rclcpp::Parameter > &parameters)
Apply parameter updates after validation This callback is executed when parameters have been successf...
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.
~StoppedGoalChecker()
Destroy the Stopped Goal Checker object.
Function-object for checking whether a goal has been reached.