17#ifndef JOINT_LIMITS_INTERFACE__JOINT_LIMITS_INTERFACE_HPP_
18#define JOINT_LIMITS_INTERFACE__JOINT_LIMITS_INTERFACE_HPP_
20#include <hardware_interface/joint_handle.hpp>
21#include <hardware_interface/types/hardware_interface_type_values.hpp>
23#include <rclcpp/duration.hpp>
24#include <rclcpp/rclcpp.hpp>
26#include <rcppmath/clamp.hpp>
35#include "joint_limits_interface/joint_limits.hpp"
36#include "joint_limits_interface/joint_limits_interface_exception.hpp"
48 : prev_pos_(std::numeric_limits<double>::quiet_NaN()),
52 jcmdh_(
"position_command")
57 const hardware_interface::JointHandle & jposh,
const hardware_interface::JointHandle & jcmdh,
63 prev_pos_(std::numeric_limits<double>::quiet_NaN()),
69 const hardware_interface::JointHandle & jposh,
const hardware_interface::JointHandle & jvelh,
70 const hardware_interface::JointHandle & jcmdh,
const JointLimits & limits)
75 prev_pos_(std::numeric_limits<double>::quiet_NaN()),
83 return jposh_ ? jposh_.get_name()
84 : jvelh_ ? jvelh_.get_name() : jcmdh_ ? jcmdh_.get_name() : std::string();
93 prev_pos_ = std::numeric_limits<double>::quiet_NaN();
98 hardware_interface::JointHandle jposh_;
99 hardware_interface::JointHandle jvelh_;
100 hardware_interface::JointHandle jcmdh_;
116 return jvelh_ ? jvelh_.get_value() : (jposh_.get_value() - prev_pos_) / period.seconds();
129 const hardware_interface::JointHandle & jposh,
const hardware_interface::JointHandle & jcmdh,
136 const hardware_interface::JointHandle & jposh,
const hardware_interface::JointHandle & jvelh,
137 const hardware_interface::JointHandle & jcmdh,
const JointLimits & limits,
155 const hardware_interface::JointHandle & jposh,
const hardware_interface::JointHandle & jcmdh,
159 if (limits_.has_position_limits)
161 min_pos_limit_ = limits_.min_position;
162 max_pos_limit_ = limits_.max_position;
166 min_pos_limit_ = -std::numeric_limits<double>::max();
167 max_pos_limit_ = std::numeric_limits<double>::max();
177 if (std::isnan(prev_pos_))
179 prev_pos_ = jposh_.get_value();
182 double min_pos, max_pos;
183 if (limits_.has_velocity_limits)
188 const double delta_pos = limits_.max_velocity * period.seconds();
189 min_pos = std::max(prev_pos_ - delta_pos, min_pos_limit_);
190 max_pos = std::min(prev_pos_ + delta_pos, max_pos_limit_);
195 min_pos = min_pos_limit_;
196 max_pos = max_pos_limit_;
200 const double cmd = rcppmath::clamp(jcmdh_.get_value(), min_pos, max_pos);
201 jcmdh_.set_value(cmd);
207 double min_pos_limit_, max_pos_limit_;
246 const hardware_interface::JointHandle & jposh,
const hardware_interface::JointHandle & jcmdh,
251 if (!limits.has_velocity_limits)
254 "Cannot enforce limits for joint '" +
get_name() +
255 "'. It has no velocity limits specification.");
267 assert(period.seconds() > 0.0);
270 if (std::isnan(prev_pos_))
273 prev_pos_ = jposh_.get_value();
275 const double pos = prev_pos_;
281 if (limits_.has_position_limits)
284 soft_min_vel = rcppmath::clamp(
285 -soft_limits_.k_position * (pos - soft_limits_.min_position), -limits_.max_velocity,
286 limits_.max_velocity);
288 soft_max_vel = rcppmath::clamp(
289 -soft_limits_.k_position * (pos - soft_limits_.max_position), -limits_.max_velocity,
290 limits_.max_velocity);
295 soft_min_vel = -limits_.max_velocity;
296 soft_max_vel = limits_.max_velocity;
300 const double dt = period.seconds();
301 double pos_low = pos + soft_min_vel * dt;
302 double pos_high = pos + soft_max_vel * dt;
304 if (limits_.has_position_limits)
308 pos_low = std::max(pos_low, limits_.min_position);
309 pos_high = std::min(pos_high, limits_.max_position);
313 const double pos_cmd = rcppmath::clamp(jcmdh_.get_value(), pos_low, pos_high);
314 jcmdh_.set_value(pos_cmd);
319 prev_pos_ = jcmdh_.get_value();
333 const hardware_interface::JointHandle & jposh,
const hardware_interface::JointHandle & jvelh,
334 const hardware_interface::JointHandle & jcmdh,
338 if (!limits.has_velocity_limits)
341 "Cannot enforce limits for joint '" +
get_name() +
342 "'. It has no velocity limits specification.");
344 if (!limits.has_effort_limits)
347 "Cannot enforce limits for joint '" +
get_name() +
348 "'. It has no efforts limits specification.");
353 const hardware_interface::JointHandle & jposh,
const hardware_interface::JointHandle & jcmdh,
368 double min_eff = -limits_.max_effort;
369 double max_eff = limits_.max_effort;
371 if (limits_.has_position_limits)
373 const double pos = jposh_.get_value();
374 if (pos < limits_.min_position)
378 else if (pos > limits_.max_position)
385 if (vel < -limits_.max_velocity)
389 else if (vel > limits_.max_velocity)
394 double clamped = rcppmath::clamp(jcmdh_.get_value(), min_eff, max_eff);
395 jcmdh_.set_value(clamped);
407 const hardware_interface::JointHandle & jposh,
const hardware_interface::JointHandle & jvelh,
408 const hardware_interface::JointHandle & jcmdh,
413 if (!limits.has_velocity_limits)
416 "Cannot enforce limits for joint '" +
get_name() +
417 "'. It has no velocity limits specification.");
419 if (!limits.has_effort_limits)
422 "Cannot enforce limits for joint '" +
get_name() +
423 "'. It has no effort limits specification.");
428 const hardware_interface::JointHandle & jposh,
const hardware_interface::JointHandle & jcmdh,
447 const double pos = jposh_.get_value();
454 if (limits_.has_position_limits)
457 soft_min_vel = rcppmath::clamp(
458 -soft_limits_.k_position * (pos - soft_limits_.min_position), -limits_.max_velocity,
459 limits_.max_velocity);
461 soft_max_vel = rcppmath::clamp(
462 -soft_limits_.k_position * (pos - soft_limits_.max_position), -limits_.max_velocity,
463 limits_.max_velocity);
468 soft_min_vel = -limits_.max_velocity;
469 soft_max_vel = limits_.max_velocity;
473 const double soft_min_eff = rcppmath::clamp(
474 -soft_limits_.k_velocity * (vel - soft_min_vel), -limits_.max_effort, limits_.max_effort);
476 const double soft_max_eff = rcppmath::clamp(
477 -soft_limits_.k_velocity * (vel - soft_max_vel), -limits_.max_effort, limits_.max_effort);
480 const double eff_cmd = rcppmath::clamp(jcmdh_.get_value(), soft_min_eff, soft_max_eff);
481 jcmdh_.set_value(eff_cmd);
492 const hardware_interface::JointHandle & jvelh,
493 const hardware_interface::JointHandle & jcmdh,
498 if (!limits.has_velocity_limits)
501 "Cannot enforce limits for joint '" +
get_name() +
502 "'. It has no velocity limits specification.");
507 const hardware_interface::JointHandle & jcmdh,
513 if (!limits.has_velocity_limits)
516 "Cannot enforce limits for joint '" +
get_name() +
517 "'. It has no velocity limits specification.");
531 if (limits_.has_acceleration_limits)
533 assert(period.seconds() > 0.0);
534 const double dt = period.seconds();
536 vel_low = std::max(prev_vel_ - limits_.max_acceleration * dt, -limits_.max_velocity);
537 vel_high = std::min(prev_vel_ + limits_.max_acceleration * dt, limits_.max_velocity);
541 vel_low = -limits_.max_velocity;
542 vel_high = limits_.max_velocity;
546 const double vel_cmd = rcppmath::clamp(jcmdh_.get_value(), vel_low, vel_high);
547 jcmdh_.set_value(vel_cmd);
550 prev_vel_ = jcmdh_.get_value();
564 const hardware_interface::JointHandle & jposh,
const hardware_interface::JointHandle & jvelh,
565 const hardware_interface::JointHandle & jcmdh,
570 if (limits.has_velocity_limits)
572 max_vel_limit_ = limits.max_velocity;
576 max_vel_limit_ = std::numeric_limits<double>::max();
588 double min_vel, max_vel;
589 if (limits_.has_position_limits)
592 const double pos = jposh_.get_value();
593 min_vel = rcppmath::clamp(
594 -soft_limits_.k_position * (pos - soft_limits_.min_position), -max_vel_limit_,
596 max_vel = rcppmath::clamp(
597 -soft_limits_.k_position * (pos - soft_limits_.max_position), -max_vel_limit_,
602 min_vel = -max_vel_limit_;
603 max_vel = max_vel_limit_;
606 if (limits_.has_acceleration_limits)
609 const double delta_t = period.seconds();
610 min_vel = std::max(vel - limits_.max_acceleration * delta_t, min_vel);
611 max_vel = std::min(vel + limits_.max_acceleration * delta_t, max_vel);
614 jcmdh_.set_value(rcppmath::clamp(jcmdh_.get_value(), min_vel, max_vel));
618 double max_vel_limit_;
Definition joint_limits_interface.hpp:328
void enforce_limits(const rclcpp::Duration &period) override
Definition joint_limits_interface.hpp:366
A handle used to enforce position, velocity and effort limits of an effort-controlled joint.
Definition joint_limits_interface.hpp:402
void enforce_limits(const rclcpp::Duration &period) override
Enforce position, velocity and effort limits for a joint subject to soft limits.
Definition joint_limits_interface.hpp:444
Definition joint_limits_interface.hpp:45
virtual void reset()
Clear stored state, causing it to reset next iteration.
Definition joint_limits_interface.hpp:91
double get_velocity(const rclcpp::Duration &period) const
Return velocity for limit calculations.
Definition joint_limits_interface.hpp:112
virtual void enforce_limits(const rclcpp::Duration &period)=0
Sub-class implementation of limit enforcing policy.
std::string get_name() const
Definition joint_limits_interface.hpp:81
An exception related to a JointLimitsInterface.
Definition joint_limits_interface_exception.hpp:24
Definition joint_limits_interface.hpp:124
Definition joint_limits_interface.hpp:150
void enforce_limits(const rclcpp::Duration &period)
Enforce position and velocity limits for a joint that is not subject to soft limits.
Definition joint_limits_interface.hpp:175
A handle used to enforce position and velocity limits of a position-controlled joint.
Definition joint_limits_interface.hpp:241
void enforce_limits(const rclcpp::Duration &period) override
Enforce position and velocity limits for a joint subject to soft limits.
Definition joint_limits_interface.hpp:265
A handle used to enforce velocity and acceleration limits of a velocity-controlled joint.
Definition joint_limits_interface.hpp:487
void enforce_limits(const rclcpp::Duration &period) override
Enforce joint velocity and acceleration limits.
Definition joint_limits_interface.hpp:525
Definition joint_limits_interface.hpp:559
void enforce_limits(const rclcpp::Duration &period)
Definition joint_limits_interface.hpp:586
constexpr char HW_IF_VELOCITY[]
Constant defining velocity interface.
Definition hardware_interface_type_values.hpp:23
constexpr char HW_IF_POSITION[]
Constant defining position interface.
Definition hardware_interface_type_values.hpp:21
Definition joint_limits.hpp:21
Definition joint_limits.hpp:23
Definition joint_limits.hpp:56