ros2_control - rolling
Loading...
Searching...
No Matches
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 <cstddef>
21#include <string>
22#include <vector>
23
24#include "joint_limits/joint_limits.hpp"
25#include "joint_limits/joint_limits_rosparam.hpp"
26#include "rcl_interfaces/msg/set_parameters_result.hpp"
27#include "rclcpp/duration.hpp"
28#include "rclcpp/logging.hpp"
29#include "rclcpp/node.hpp"
30#include "rclcpp/parameter.hpp"
31#include "rclcpp_lifecycle/lifecycle_node.hpp"
32#include "realtime_tools/realtime_thread_safe_box.hpp"
33
34namespace joint_limits
35{
36
37template <typename JointLimitsStateDataType>
39{
40public:
41 JointLimiterInterface() = default;
42
43 virtual ~JointLimiterInterface() = default;
44
59 virtual bool init(
60 const std::vector<std::string> & joint_names,
61 const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr & param_itf,
62 const rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr & logging_itf,
63 const std::string & robot_description_topic = "/robot_description")
64 {
65 number_of_joints_ = joint_names.size();
66 joint_names_ = joint_names;
67 joint_limits_.resize(number_of_joints_);
68 node_param_itf_ = param_itf;
69 node_logging_itf_ = logging_itf;
70
71 bool result = true;
72
73 // TODO(destogl): get limits from URDF
74
75 // Initialize and get joint limits from parameter server
77 {
78 for (size_t i = 0; i < number_of_joints_; ++i)
79 {
80 if (!declare_parameters(joint_names[i], node_param_itf_, node_logging_itf_))
81 {
82 RCLCPP_ERROR(
83 node_logging_itf_->get_logger(),
84 "JointLimiter: Joint '%s': parameter declaration has failed", joint_names[i].c_str());
85 result = false;
86 break;
87 }
88 if (!get_joint_limits(joint_names[i], node_param_itf_, node_logging_itf_, joint_limits_[i]))
89 {
90 RCLCPP_ERROR(
91 node_logging_itf_->get_logger(),
92 "JointLimiter: Joint '%s': getting parameters has failed", joint_names[i].c_str());
93 result = false;
94 break;
95 }
96 RCLCPP_INFO(
97 node_logging_itf_->get_logger(), "Limits for joint %zu (%s) are:\n%s", i,
98 joint_names[i].c_str(), joint_limits_[i].to_string().c_str());
99 }
100 updated_limits_.set(joint_limits_);
101
102 auto on_parameter_event_callback = [this](const std::vector<rclcpp::Parameter> & parameters)
103 {
104 rcl_interfaces::msg::SetParametersResult set_parameters_result;
105 set_parameters_result.successful = true;
106
107 std::vector<joint_limits::JointLimits> updated_joint_limits = joint_limits_;
108 bool changed = false;
109
110 for (size_t i = 0; i < number_of_joints_; ++i)
111 {
113 joint_names_[i], parameters, node_logging_itf_, updated_joint_limits[i]);
114 }
115
116 if (changed)
117 {
118 updated_limits_.set(updated_joint_limits);
119 RCLCPP_INFO(node_logging_itf_->get_logger(), "Limits are dynamically updated!");
120 }
121
122 return set_parameters_result;
123 };
124
125 parameter_callback_ =
126 node_param_itf_->add_on_set_parameters_callback(on_parameter_event_callback);
127 }
128
129 if (result)
130 {
131 result = on_init();
132 }
133
134 (void)robot_description_topic; // avoid linters output
135
136 return result;
137 }
138
142 virtual bool init(
143 const std::vector<std::string> & joint_names,
144 const std::vector<joint_limits::JointLimits> & joint_limits,
145 const std::vector<joint_limits::SoftJointLimits> & soft_joint_limits,
146 const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr & param_itf,
147 const rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr & logging_itf)
148 {
149 number_of_joints_ = joint_names.size();
150 joint_names_ = joint_names;
151 joint_limits_ = joint_limits;
152 soft_joint_limits_ = soft_joint_limits;
153 node_param_itf_ = param_itf;
154 node_logging_itf_ = logging_itf;
155 updated_limits_.set(joint_limits_);
156
157 if ((number_of_joints_ != joint_limits_.size()) && has_logging_interface())
158 {
159 RCLCPP_ERROR(
160 node_logging_itf_->get_logger(),
161 "JointLimiter: Number of joint names and limits do not match: %zu != %zu",
162 number_of_joints_, joint_limits_.size());
163 }
164 return (number_of_joints_ == joint_limits_.size()) && on_init();
165 }
166
172 virtual bool init(
173 const std::vector<std::string> & joint_names, const rclcpp::Node::SharedPtr & node,
174 const std::string & robot_description_topic = "/robot_description")
175 {
176 return init(
177 joint_names, node->get_node_parameters_interface(), node->get_node_logging_interface(),
178 robot_description_topic);
179 }
180
186 virtual bool init(
187 const std::vector<std::string> & joint_names,
188 const rclcpp_lifecycle::LifecycleNode::SharedPtr & lifecycle_node,
189 const std::string & robot_description_topic = "/robot_description")
190 {
191 return init(
192 joint_names, lifecycle_node->get_node_parameters_interface(),
193 lifecycle_node->get_node_logging_interface(), robot_description_topic);
194 }
195
196 virtual bool configure(const JointLimitsStateDataType & current_joint_states)
197 {
198 return on_configure(current_joint_states);
199 }
200
211 virtual bool enforce(
212 const JointLimitsStateDataType & current_joint_states,
213 JointLimitsStateDataType & desired_joint_states, const rclcpp::Duration & dt)
214 {
215 auto joint_limits_op = updated_limits_.try_get();
216 if (joint_limits_op.has_value())
217 {
218 joint_limits_ = joint_limits_op.value();
219 return on_enforce(current_joint_states, desired_joint_states, dt);
220 }
221 else
222 {
223 return false;
224 }
225 }
226
227 virtual void reset_internals() = 0;
228
229protected:
236 virtual bool on_init() = 0;
237
244 virtual bool on_configure(const JointLimitsStateDataType & current_joint_states) = 0;
245
257 virtual bool on_enforce(
258 const JointLimitsStateDataType & current_joint_states,
259 JointLimitsStateDataType & desired_joint_states, const rclcpp::Duration & dt) = 0;
260
269 bool has_logging_interface() const { return node_logging_itf_ != nullptr; }
270
279 bool has_parameter_interface() const { return node_param_itf_ != nullptr; }
280
281 size_t number_of_joints_;
282 std::vector<std::string> joint_names_;
283 std::vector<joint_limits::JointLimits> joint_limits_;
284 std::vector<joint_limits::SoftJointLimits> soft_joint_limits_;
285 rclcpp::node_interfaces::NodeParametersInterface::SharedPtr node_param_itf_;
286 rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging_itf_;
287
288private:
289 rclcpp::node_interfaces::OnSetParametersCallbackHandle::SharedPtr parameter_callback_;
291};
292
293} // namespace joint_limits
294
295#endif // JOINT_LIMITS__JOINT_LIMITER_INTERFACE_HPP_
Definition joint_limiter_interface.hpp:39
virtual bool on_init()=0
Initialize the limiter's internal states and libraries.
virtual 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")
Initialize every JointLimiter.
Definition joint_limiter_interface.hpp:59
bool has_logging_interface() const
Checks if the logging interface is set.
Definition joint_limiter_interface.hpp:269
bool has_parameter_interface() const
Checks if the parameter interface is set.
Definition joint_limiter_interface.hpp:279
virtual bool on_enforce(const JointLimitsStateDataType &current_joint_states, JointLimitsStateDataType &desired_joint_states, const rclcpp::Duration &dt)=0
Enforce joint limits for multiple dependent physical quantities.
virtual bool enforce(const 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:211
virtual bool on_configure(const JointLimitsStateDataType &current_joint_states)=0
Configure the limiter's internal states and libraries.
virtual bool init(const std::vector< std::string > &joint_names, const rclcpp_lifecycle::LifecycleNode::SharedPtr &lifecycle_node, const std::string &robot_description_topic="/robot_description")
Initialize joints using a LifecycleNode pointer.
Definition joint_limiter_interface.hpp:186
virtual bool init(const std::vector< std::string > &joint_names, const rclcpp::Node::SharedPtr &node, const std::string &robot_description_topic="/robot_description")
Initialize joints using a Node pointer.
Definition joint_limiter_interface.hpp:172
virtual bool init(const std::vector< std::string > &joint_names, const std::vector< joint_limits::JointLimits > &joint_limits, const std::vector< joint_limits::SoftJointLimits > &soft_joint_limits, const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr &param_itf, const rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr &logging_itf)
Initialize joints from directly provided names and limits.
Definition joint_limiter_interface.hpp:142
Definition realtime_thread_safe_box.hpp:68
std::enable_if_t<!is_ptr_or_smart_ptr< U >, void > set(const T &value)
Wait until the mutex can be locked and set the content (RealtimeThreadSafeBox behavior)
Definition realtime_thread_safe_box.hpp:199
std::enable_if_t<!is_ptr_or_smart_ptr< U >, std::optional< U > > try_get() const
get the content with best effort
Definition realtime_thread_safe_box.hpp:168
Definition data_structures.hpp:38
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)
Check if any of updated parameters are related to JointLimits.
Definition joint_limits_rosparam.hpp:445
bool declare_parameters(const std::string &joint_name, const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr &param_itf, const rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr &logging_itf)
Declare JointLimits and SoftJointLimits parameters for joint with joint_name using node parameters in...
Definition joint_limits_rosparam.hpp:94
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:237