ros2_control - iron
Loading...
Searching...
No Matches
joint_limits_rosparam.hpp
1// Copyright 2020 PAL Robotics S.L.
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_LIMITS_ROSPARAM_HPP_
18#define JOINT_LIMITS__JOINT_LIMITS_ROSPARAM_HPP_
19
20#include <limits>
21#include <string>
22
23#include "joint_limits/joint_limits.hpp"
24#include "rclcpp/rclcpp.hpp"
25#include "rclcpp_lifecycle/lifecycle_node.hpp"
26
27namespace // utilities
28{
30
36template <typename ParameterT>
37auto auto_declare(
38 const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr & param_itf,
39 const std::string & name, const ParameterT & default_value)
40{
41 if (!param_itf->has_parameter(name))
42 {
43 auto param_default_value = rclcpp::ParameterValue(default_value);
44 param_itf->declare_parameter(name, param_default_value);
45 }
46 return param_itf->get_parameter(name).get_value<ParameterT>();
47}
48} // namespace
49
50namespace joint_limits
51{
86 const std::string & joint_name,
87 const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr & param_itf,
88 const rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr & logging_itf)
89{
90 const std::string param_base_name = "joint_limits." + joint_name;
91 try
92 {
93 auto_declare<bool>(param_itf, param_base_name + ".has_position_limits", false);
94 auto_declare<double>(
95 param_itf, param_base_name + ".min_position", std::numeric_limits<double>::quiet_NaN());
96 auto_declare<double>(
97 param_itf, param_base_name + ".max_position", std::numeric_limits<double>::quiet_NaN());
98 auto_declare<bool>(param_itf, param_base_name + ".has_velocity_limits", false);
99 auto_declare<double>(
100 param_itf, param_base_name + ".min_velocity", std::numeric_limits<double>::quiet_NaN());
101 auto_declare<double>(
102 param_itf, param_base_name + ".max_velocity", std::numeric_limits<double>::quiet_NaN());
103 auto_declare<bool>(param_itf, param_base_name + ".has_acceleration_limits", false);
104 auto_declare<double>(
105 param_itf, param_base_name + ".max_acceleration", std::numeric_limits<double>::quiet_NaN());
106 auto_declare<bool>(param_itf, param_base_name + ".has_deceleration_limits", false);
107 auto_declare<double>(
108 param_itf, param_base_name + ".max_deceleration", std::numeric_limits<double>::quiet_NaN());
109 auto_declare<bool>(param_itf, param_base_name + ".has_jerk_limits", false);
110 auto_declare<double>(
111 param_itf, param_base_name + ".max_jerk", std::numeric_limits<double>::quiet_NaN());
112 auto_declare<bool>(param_itf, param_base_name + ".has_effort_limits", false);
113 auto_declare<double>(
114 param_itf, param_base_name + ".max_effort", std::numeric_limits<double>::quiet_NaN());
115 auto_declare<bool>(param_itf, param_base_name + ".angle_wraparound", false);
116 auto_declare<bool>(param_itf, param_base_name + ".has_soft_limits", false);
117 auto_declare<double>(
118 param_itf, param_base_name + ".k_position", std::numeric_limits<double>::quiet_NaN());
119 auto_declare<double>(
120 param_itf, param_base_name + ".k_velocity", std::numeric_limits<double>::quiet_NaN());
121 auto_declare<double>(
122 param_itf, param_base_name + ".soft_lower_limit", std::numeric_limits<double>::quiet_NaN());
123 auto_declare<double>(
124 param_itf, param_base_name + ".soft_upper_limit", std::numeric_limits<double>::quiet_NaN());
125 }
126 catch (const std::exception & ex)
127 {
128 RCLCPP_ERROR(logging_itf->get_logger(), "%s", ex.what());
129 return false;
130 }
131 return true;
132}
133
145inline bool declare_parameters(const std::string & joint_name, const rclcpp::Node::SharedPtr & node)
146{
147 return declare_parameters(
148 joint_name, node->get_node_parameters_interface(), node->get_node_logging_interface());
149}
150
162 const std::string & joint_name, const rclcpp_lifecycle::LifecycleNode::SharedPtr & lifecycle_node)
163{
164 return declare_parameters(
165 joint_name, lifecycle_node->get_node_parameters_interface(),
166 lifecycle_node->get_node_logging_interface());
167}
168
170
227 const std::string & joint_name,
228 const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr & param_itf,
229 const rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr & logging_itf,
230 JointLimits & limits)
231{
232 const std::string param_base_name = "joint_limits." + joint_name;
233 try
234 {
235 if (
236 !param_itf->has_parameter(param_base_name + ".has_position_limits") &&
237 !param_itf->has_parameter(param_base_name + ".min_position") &&
238 !param_itf->has_parameter(param_base_name + ".max_position") &&
239 !param_itf->has_parameter(param_base_name + ".has_velocity_limits") &&
240 !param_itf->has_parameter(param_base_name + ".min_velocity") &&
241 !param_itf->has_parameter(param_base_name + ".max_velocity") &&
242 !param_itf->has_parameter(param_base_name + ".has_acceleration_limits") &&
243 !param_itf->has_parameter(param_base_name + ".max_acceleration") &&
244 !param_itf->has_parameter(param_base_name + ".has_deceleration_limits") &&
245 !param_itf->has_parameter(param_base_name + ".max_deceleration") &&
246 !param_itf->has_parameter(param_base_name + ".has_jerk_limits") &&
247 !param_itf->has_parameter(param_base_name + ".max_jerk") &&
248 !param_itf->has_parameter(param_base_name + ".has_effort_limits") &&
249 !param_itf->has_parameter(param_base_name + ".max_effort") &&
250 !param_itf->has_parameter(param_base_name + ".angle_wraparound") &&
251 !param_itf->has_parameter(param_base_name + ".has_soft_limits") &&
252 !param_itf->has_parameter(param_base_name + ".k_position") &&
253 !param_itf->has_parameter(param_base_name + ".k_velocity") &&
254 !param_itf->has_parameter(param_base_name + ".soft_lower_limit") &&
255 !param_itf->has_parameter(param_base_name + ".soft_upper_limit"))
256 {
257 RCLCPP_ERROR(
258 logging_itf->get_logger(),
259 "No joint limits specification found for joint '%s' in the parameter server "
260 "(param name: %s).",
261 joint_name.c_str(), param_base_name.c_str());
262 return false;
263 }
264 }
265 catch (const std::exception & ex)
266 {
267 RCLCPP_ERROR(logging_itf->get_logger(), "%s", ex.what());
268 return false;
269 }
270
271 // Position limits
272 if (param_itf->has_parameter(param_base_name + ".has_position_limits"))
273 {
274 limits.has_position_limits =
275 param_itf->get_parameter(param_base_name + ".has_position_limits").as_bool();
276 if (
277 limits.has_position_limits && param_itf->has_parameter(param_base_name + ".min_position") &&
278 param_itf->has_parameter(param_base_name + ".max_position"))
279 {
280 limits.min_position = param_itf->get_parameter(param_base_name + ".min_position").as_double();
281 limits.max_position = param_itf->get_parameter(param_base_name + ".max_position").as_double();
282 }
283 else
284 {
285 limits.has_position_limits = false;
286 }
287
288 if (
289 !limits.has_position_limits &&
290 param_itf->has_parameter(param_base_name + ".angle_wraparound"))
291 {
292 limits.angle_wraparound =
293 param_itf->get_parameter(param_base_name + ".angle_wraparound").as_bool();
294 }
295 }
296
297 // Velocity limits
298 if (param_itf->has_parameter(param_base_name + ".has_velocity_limits"))
299 {
300 limits.has_velocity_limits =
301 param_itf->get_parameter(param_base_name + ".has_velocity_limits").as_bool();
302 if (limits.has_velocity_limits && param_itf->has_parameter(param_base_name + ".max_velocity"))
303 {
304 limits.max_velocity = param_itf->get_parameter(param_base_name + ".max_velocity").as_double();
305 }
306 else
307 {
308 limits.has_velocity_limits = false;
309 }
310 }
311
312 // Acceleration limits
313 if (param_itf->has_parameter(param_base_name + ".has_acceleration_limits"))
314 {
315 limits.has_acceleration_limits =
316 param_itf->get_parameter(param_base_name + ".has_acceleration_limits").as_bool();
317 if (
318 limits.has_acceleration_limits &&
319 param_itf->has_parameter(param_base_name + ".max_acceleration"))
320 {
321 limits.max_acceleration =
322 param_itf->get_parameter(param_base_name + ".max_acceleration").as_double();
323 }
324 else
325 {
326 limits.has_acceleration_limits = false;
327 }
328 }
329
330 // Deceleration limits
331 if (param_itf->has_parameter(param_base_name + ".has_deceleration_limits"))
332 {
333 limits.has_deceleration_limits =
334 param_itf->get_parameter(param_base_name + ".has_deceleration_limits").as_bool();
335 if (
336 limits.has_deceleration_limits &&
337 param_itf->has_parameter(param_base_name + ".max_deceleration"))
338 {
339 limits.max_deceleration =
340 param_itf->get_parameter(param_base_name + ".max_deceleration").as_double();
341 }
342 else
343 {
344 limits.has_deceleration_limits = false;
345 }
346 }
347
348 // Jerk limits
349 if (param_itf->has_parameter(param_base_name + ".has_jerk_limits"))
350 {
351 limits.has_jerk_limits =
352 param_itf->get_parameter(param_base_name + ".has_jerk_limits").as_bool();
353 if (limits.has_jerk_limits && param_itf->has_parameter(param_base_name + ".max_jerk"))
354 {
355 limits.max_jerk = param_itf->get_parameter(param_base_name + ".max_jerk").as_double();
356 }
357 else
358 {
359 limits.has_jerk_limits = false;
360 }
361 }
362
363 // Effort limits
364 if (param_itf->has_parameter(param_base_name + ".has_effort_limits"))
365 {
366 limits.has_effort_limits =
367 param_itf->get_parameter(param_base_name + ".has_effort_limits").as_bool();
368 if (limits.has_effort_limits && param_itf->has_parameter(param_base_name + ".max_effort"))
369 {
370 limits.has_effort_limits = true;
371 limits.max_effort = param_itf->get_parameter(param_base_name + ".max_effort").as_double();
372 }
373 else
374 {
375 limits.has_effort_limits = false;
376 }
377 }
378
379 return true;
380}
381
396 const std::string & joint_name, const rclcpp::Node::SharedPtr & node, JointLimits & limits)
397{
398 return get_joint_limits(
399 joint_name, node->get_node_parameters_interface(), node->get_node_logging_interface(), limits);
400}
401
416 const std::string & joint_name, const rclcpp_lifecycle::LifecycleNode::SharedPtr & lifecycle_node,
417 JointLimits & limits)
418{
419 return get_joint_limits(
420 joint_name, lifecycle_node->get_node_parameters_interface(),
421 lifecycle_node->get_node_logging_interface(), limits);
422}
423
425
457 const std::string & joint_name,
458 const rclcpp::node_interfaces::NodeParametersInterface::SharedPtr & param_itf,
459 const rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr & logging_itf,
460 SoftJointLimits & soft_limits)
461{
462 const std::string param_base_name = "joint_limits." + joint_name;
463 try
464 {
465 if (
466 !param_itf->has_parameter(param_base_name + ".has_soft_limits") &&
467 !param_itf->has_parameter(param_base_name + ".k_velocity") &&
468 !param_itf->has_parameter(param_base_name + ".k_position") &&
469 !param_itf->has_parameter(param_base_name + ".soft_lower_limit") &&
470 !param_itf->has_parameter(param_base_name + ".soft_upper_limit"))
471 {
472 RCLCPP_DEBUG(
473 logging_itf->get_logger(),
474 "No soft joint limits specification found for joint '%s' in the parameter server "
475 "(param name: %s).",
476 joint_name.c_str(), param_base_name.c_str());
477 return false;
478 }
479 }
480 catch (const std::exception & ex)
481 {
482 RCLCPP_ERROR(logging_itf->get_logger(), "%s", ex.what());
483 return false;
484 }
485
486 // Override soft limits if complete specification is found
487 if (param_itf->has_parameter(param_base_name + ".has_soft_limits"))
488 {
489 if (
490 param_itf->get_parameter(param_base_name + ".has_soft_limits").as_bool() &&
491 param_itf->has_parameter(param_base_name + ".k_position") &&
492 param_itf->has_parameter(param_base_name + ".k_velocity") &&
493 param_itf->has_parameter(param_base_name + ".soft_lower_limit") &&
494 param_itf->has_parameter(param_base_name + ".soft_upper_limit"))
495 {
496 soft_limits.k_position =
497 param_itf->get_parameter(param_base_name + ".k_position").as_double();
498 soft_limits.k_velocity =
499 param_itf->get_parameter(param_base_name + ".k_velocity").as_double();
500 soft_limits.min_position =
501 param_itf->get_parameter(param_base_name + ".soft_lower_limit").as_double();
502 soft_limits.max_position =
503 param_itf->get_parameter(param_base_name + ".soft_upper_limit").as_double();
504 return true;
505 }
506 }
507
508 return false;
509}
510
524 const std::string & joint_name, const rclcpp::Node::SharedPtr & node,
525 SoftJointLimits & soft_limits)
526{
527 return get_joint_limits(
528 joint_name, node->get_node_parameters_interface(), node->get_node_logging_interface(),
529 soft_limits);
530}
531
545 const std::string & joint_name, const rclcpp_lifecycle::LifecycleNode::SharedPtr & lifecycle_node,
546 SoftJointLimits & soft_limits)
547{
548 return get_joint_limits(
549 joint_name, lifecycle_node->get_node_parameters_interface(),
550 lifecycle_node->get_node_logging_interface(), soft_limits);
551}
552
553} // namespace joint_limits
554
555#endif // JOINT_LIMITS__JOINT_LIMITS_ROSPARAM_HPP_
Definition joint_limits.hpp:25
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:85
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:226
Definition joint_limits.hpp:35
Definition joint_limits.hpp:113