ros2_control - rolling
joint_limiter_interface.hpp
1 // Copyright (c) 2024, Stogl Robotics Consulting UG (haftungsbeschränkt)
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 
16 
17 #ifndef JOINT_LIMITS__JOINT_LIMITER_INTERFACE_HPP_
18 #define JOINT_LIMITS__JOINT_LIMITER_INTERFACE_HPP_
19 
20 #include <string>
21 #include <vector>
22 
23 #include "joint_limits/joint_limits_rosparam.hpp"
24 #include "joint_limits/visibility_control.h"
25 #include "rclcpp/node.hpp"
26 #include "rclcpp_lifecycle/lifecycle_node.hpp"
27 #include "realtime_tools/realtime_buffer.h"
28 #include "trajectory_msgs/msg/joint_trajectory_point.hpp"
29 
30 namespace joint_limits
31 {
32 using JointLimitsStateDataType = trajectory_msgs::msg::JointTrajectoryPoint;
33 
34 template <typename LimitsType>
36 {
37 public:
38  JOINT_LIMITS_PUBLIC JointLimiterInterface() = default;
39 
40  JOINT_LIMITS_PUBLIC virtual ~JointLimiterInterface() = default;
41 
43 
55  JOINT_LIMITS_PUBLIC virtual bool init(
56  const std::vector<std::string> & joint_names,
57  const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr & param_itf,
58  const rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr & logging_itf,
59  const std::string & robot_description_topic = "/robot_description")
60  {
61  number_of_joints_ = joint_names.size();
62  joint_names_ = joint_names;
63  joint_limits_.resize(number_of_joints_);
64  node_param_itf_ = param_itf;
65  node_logging_itf_ = logging_itf;
66 
67  bool result = true;
68 
69  // TODO(destogl): get limits from URDF
70 
71  // Initialize and get joint limits from parameter server
72  for (size_t i = 0; i < number_of_joints_; ++i)
73  {
74  if (!declare_parameters(joint_names[i], node_param_itf_, node_logging_itf_))
75  {
76  RCLCPP_ERROR(
77  node_logging_itf_->get_logger(),
78  "JointLimiter: Joint '%s': parameter declaration has failed", joint_names[i].c_str());
79  result = false;
80  break;
81  }
82  if (!get_joint_limits(joint_names[i], node_param_itf_, node_logging_itf_, joint_limits_[i]))
83  {
84  RCLCPP_ERROR(
85  node_logging_itf_->get_logger(),
86  "JointLimiter: Joint '%s': getting parameters has failed", joint_names[i].c_str());
87  result = false;
88  break;
89  }
90  RCLCPP_INFO(
91  node_logging_itf_->get_logger(), "Limits for joint %zu (%s) are:\n%s", i,
92  joint_names[i].c_str(), joint_limits_[i].to_string().c_str());
93  }
94  updated_limits_.writeFromNonRT(joint_limits_);
95 
96  auto on_parameter_event_callback = [this](const std::vector<rclcpp::Parameter> & parameters)
97  {
98  rcl_interfaces::msg::SetParametersResult set_parameters_result;
99  set_parameters_result.successful = true;
100 
101  std::vector<LimitsType> updated_joint_limits = joint_limits_;
102  bool changed = false;
103 
104  for (size_t i = 0; i < number_of_joints_; ++i)
105  {
107  joint_names_[i], parameters, node_logging_itf_, updated_joint_limits[i]);
108  }
109 
110  if (changed)
111  {
112  updated_limits_.writeFromNonRT(updated_joint_limits);
113  RCLCPP_INFO(node_logging_itf_->get_logger(), "Limits are dynamically updated!");
114  }
115 
116  return set_parameters_result;
117  };
118 
119  parameter_callback_ =
120  node_param_itf_->add_on_set_parameters_callback(on_parameter_event_callback);
121 
122  if (result)
123  {
124  result = on_init();
125  }
126 
127  (void)robot_description_topic; // avoid linters output
128 
129  return result;
130  }
131 
136  JOINT_LIMITS_PUBLIC virtual bool init(
137  const std::vector<std::string> & joint_names, const rclcpp::Node::SharedPtr & node,
138  const std::string & robot_description_topic = "/robot_description")
139  {
140  return init(
141  joint_names, node->get_node_parameters_interface(), node->get_node_logging_interface(),
142  robot_description_topic);
143  }
144 
149  JOINT_LIMITS_PUBLIC virtual bool init(
150  const std::vector<std::string> & joint_names,
151  const rclcpp_lifecycle::LifecycleNode::SharedPtr & lifecycle_node,
152  const std::string & robot_description_topic = "/robot_description")
153  {
154  return init(
155  joint_names, lifecycle_node->get_node_parameters_interface(),
156  lifecycle_node->get_node_logging_interface(), robot_description_topic);
157  }
158 
159  JOINT_LIMITS_PUBLIC virtual bool configure(const JointLimitsStateDataType & current_joint_states)
160  {
161  return on_configure(current_joint_states);
162  }
163 
173  JOINT_LIMITS_PUBLIC virtual bool enforce(
174  JointLimitsStateDataType & current_joint_states,
175  JointLimitsStateDataType & desired_joint_states, const rclcpp::Duration & dt)
176  {
177  joint_limits_ = *(updated_limits_.readFromRT());
178  return on_enforce(current_joint_states, desired_joint_states, dt);
179  }
180 
188  JOINT_LIMITS_PUBLIC virtual bool enforce(std::vector<double> & desired_joint_states)
189  {
190  joint_limits_ = *(updated_limits_.readFromRT());
191  return on_enforce(desired_joint_states);
192  }
193 
194 protected:
200  JOINT_LIMITS_PUBLIC virtual bool on_init() = 0;
201 
207  JOINT_LIMITS_PUBLIC virtual bool on_configure(
208  const JointLimitsStateDataType & current_joint_states) = 0;
209 
220  JOINT_LIMITS_PUBLIC virtual bool on_enforce(
221  JointLimitsStateDataType & current_joint_states,
222  JointLimitsStateDataType & desired_joint_states, const rclcpp::Duration & dt) = 0;
223 
234  JOINT_LIMITS_PUBLIC virtual bool on_enforce(std::vector<double> & desired_joint_states) = 0;
235 
236  size_t number_of_joints_;
237  std::vector<std::string> joint_names_;
238  std::vector<LimitsType> joint_limits_;
239  rclcpp::node_interfaces::NodeParametersInterface::SharedPtr node_param_itf_;
240  rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging_itf_;
241 
242 private:
243  rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr parameter_callback_;
245 };
246 
247 } // namespace joint_limits
248 
249 #endif // JOINT_LIMITS__JOINT_LIMITER_INTERFACE_HPP_
Definition: joint_limiter_interface.hpp:36
virtual JOINT_LIMITS_PUBLIC bool init(const std::vector< std::string > &joint_names, const rclcpp::Node::SharedPtr &node, const std::string &robot_description_topic="/robot_description")
Definition: joint_limiter_interface.hpp:136
virtual JOINT_LIMITS_PUBLIC bool init(const std::vector< std::string > &joint_names, const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr &param_itf, const rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr &logging_itf, const std::string &robot_description_topic="/robot_description")
Initialization of every JointLimiter.
Definition: joint_limiter_interface.hpp:55
virtual JOINT_LIMITS_PUBLIC bool on_enforce(std::vector< double > &desired_joint_states)=0
Method is realized by an implementation.
virtual JOINT_LIMITS_PUBLIC bool on_configure(const JointLimitsStateDataType &current_joint_states)=0
Method is realized by an implementation.
virtual JOINT_LIMITS_PUBLIC bool enforce(std::vector< double > &desired_joint_states)
Enforce joint limits to desired joint state for single physical quantity.
Definition: joint_limiter_interface.hpp:188
virtual JOINT_LIMITS_PUBLIC bool on_enforce(JointLimitsStateDataType &current_joint_states, JointLimitsStateDataType &desired_joint_states, const rclcpp::Duration &dt)=0
Method is realized by an implementation.
virtual JOINT_LIMITS_PUBLIC bool init(const std::vector< std::string > &joint_names, const rclcpp_lifecycle::LifecycleNode::SharedPtr &lifecycle_node, const std::string &robot_description_topic="/robot_description")
Definition: joint_limiter_interface.hpp:149
virtual JOINT_LIMITS_PUBLIC bool enforce(JointLimitsStateDataType &current_joint_states, JointLimitsStateDataType &desired_joint_states, const rclcpp::Duration &dt)
Enforce joint limits to desired joint state for multiple physical quantities.
Definition: joint_limiter_interface.hpp:173
virtual JOINT_LIMITS_PUBLIC bool on_init()=0
Method is realized by an implementation.
Definition: realtime_buffer.h:49
Definition: joint_limiter_interface.hpp:31
bool check_for_limits_update(const std::string &joint_name, const std::vector< rclcpp::Parameter > &parameters, const rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr &logging_itf, JointLimits &updated_limits)
Definition: joint_limits_rosparam.hpp:431
bool declare_parameters(const std::string &joint_name, const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr &param_itf, const rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr &logging_itf)
Definition: joint_limits_rosparam.hpp:86
bool get_joint_limits(const std::string &joint_name, const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr &param_itf, const rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr &logging_itf, JointLimits &limits)
Populate a JointLimits instance from the node parameters.
Definition: joint_limits_rosparam.hpp:225