Skip to content

Commit 98f03d1

Browse files
committed
Refine joint saturation velocity clamping
Adjusts the logic for calculating safe target velocities when a joint limit is hit to ensure smoother deceleration towards the limit. This replaces the placeholder calculation with physics-based limits considering deceleration and time constraints. Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
1 parent cc204f6 commit 98f03d1

1 file changed

Lines changed: 31 additions & 7 deletions

File tree

joint_limits/src/joint_saturation_limiter.cpp

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -468,15 +468,39 @@ void JointSaturationLimiter<trajectory_msgs::msg::JointTrajectoryPoint>::clamp_j
468468
joint_limits_[index].max_position);
469469
if (pos != expected_pos_[index])
470470
{
471-
// TODO(gwalck) compute vel_cmd that would permit to slow down in time at full
472-
// deceleration in any case limit pos to max
473-
expected_pos_[index] = pos;
474-
// and recompute vel_cmd that would lead to pos_max (not ideal as velocity would not be
475-
// zero)
476-
desired_vel_[index] =
477-
(expected_pos_[index] - current_joint_states.positions[index]) / dt_seconds;
478471
pos_limit_hit_[index] = true;
479472
limits_enforced = true;
473+
474+
double decel;
475+
if (joint_limits_[index].has_deceleration_limits)
476+
{
477+
decel = joint_limits_[index].max_deceleration;
478+
}
479+
else if (joint_limits_[index].has_acceleration_limits)
480+
{
481+
decel = joint_limits_[index].max_acceleration;
482+
}
483+
else
484+
{
485+
decel = std::fabs(desired_vel_[index] / dt_seconds);
486+
}
487+
488+
const double distance_to_limit =
489+
(desired_vel_[index] < 0)
490+
? current_joint_states.positions[index] - joint_limits_[index].min_position
491+
: joint_limits_[index].max_position - current_joint_states.positions[index];
492+
493+
const double vel_to_stop = std::sqrt(2.0 * decel * std::max(distance_to_limit, 0.0));
494+
const double vel_to_not_exceed = std::max(distance_to_limit, 0.0) / dt_seconds;
495+
const double safe_vel = std::min(vel_to_stop, vel_to_not_exceed);
496+
497+
if (std::fabs(desired_vel_[index]) > safe_vel)
498+
{
499+
desired_vel_[index] = std::copysign(safe_vel, desired_vel_[index]);
500+
}
501+
502+
expected_pos_[index] =
503+
current_joint_states.positions[index] + desired_vel_[index] * dt_seconds;
480504
}
481505
}
482506

0 commit comments

Comments
 (0)