Skip to content

Warn user when implicit vel exceeds max vel and recal effective acc limits#3456

Open
sachinkum0009 wants to merge 11 commits into
ros-controls:masterfrom
sachinkum0009:feat/jerk-limit-implicit-vel
Open

Warn user when implicit vel exceeds max vel and recal effective acc limits#3456
sachinkum0009 wants to merge 11 commits into
ros-controls:masterfrom
sachinkum0009:feat/jerk-limit-implicit-vel

Conversation

@sachinkum0009

@sachinkum0009 sachinkum0009 commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Description

Warn when dt is too large for acceleration limits and implicit vel exceeds max velocity

  • Add code to warn users when implicit vel exceeds the max vel
  • Add code to recal effective max acceleration/deceleration.

Fixes #Issue 2434

Is this user-facing behavior change?

Not much only the users will get warn when implicit vel execeeds max vel

Did you use Generative AI?

No

Additional Information

TODOs

To send us a pull request, please:

  • Fork the repository.
  • Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
  • Ensure local tests pass. (colcon test and pre-commit run (requires you to install pre-commit by pip3 install pre-commit)
  • Commit to your fork using clear commit messages.
  • Send a pull request, answering any default questions in the pull request interface.
  • Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.

Warn when dt is too large for acceleration limits and clamp desired
velocity to satisfy max velocity constraints.

Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
The velocity clipping is handled later in the limiter loop, making this
redundant calculation unnecessary.

Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
@sachinkum0009 sachinkum0009 changed the title Warn user when implicit vel exceeds max vel and add velocity saturation checks and clamping Warn user when implicit vel exceeds max vel Jul 10, 2026
@sachinkum0009 sachinkum0009 marked this pull request as ready for review July 10, 2026 13:32
@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.75000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.52%. Comparing base (427cb38) to head (4c01a70).
⚠️ Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
joint_limits/src/joint_saturation_limiter.cpp 93.75% 0 Missing and 1 partial ⚠️
...oint_limits/test/test_joint_saturation_limiter.cpp 91.66% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##           master    #3456   +/-   ##
=======================================
  Coverage   89.51%   89.52%           
=======================================
  Files         164      164           
  Lines       21269    21295   +26     
  Branches     1656     1662    +6     
=======================================
+ Hits        19040    19064   +24     
  Misses       1529     1529           
- Partials      700      702    +2     
Flag Coverage Δ
unittests 89.52% <93.75%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
.../include/joint_limits/joint_saturation_limiter.hpp 100.00% <100.00%> (ø)
joint_limits/src/joint_saturation_limiter.cpp 85.63% <93.75%> (+0.25%) ⬆️
...oint_limits/test/test_joint_saturation_limiter.cpp 91.21% <91.66%> (-0.02%) ⬇️

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@sachinkum0009 sachinkum0009 marked this pull request as draft July 10, 2026 14:01
Caches effective acceleration and deceleration limits to ensure they do
not exceed the velocity limit when the control cycle duration (dt)
changes.

Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
@sachinkum0009 sachinkum0009 changed the title Warn user when implicit vel exceeds max vel Warn user when implicit vel exceeds max vel and recal effective acc limits Jul 10, 2026
desired_joint_states_.positions[0] = 1.0;
desired_joint_states_.velocities[0] = 1.5; // valid pos derivative as well
desired_joint_states_.accelerations[0] = 2.9; // valid pos derivative as well
desired_joint_states_.accelerations[0] = 2.0; // valid pos derivative as well

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @destogl, when recalculating the max acc/dec if impl vel exceed max vel, this test fails. So I have updated the test. I want to ask if it is fine or should I do something else?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pleaes create a new test for this and call it "when_derivative_too_high_expect_lower_effective_limits".

Also make the exact values checks.

effective acc.

Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
@sachinkum0009 sachinkum0009 marked this pull request as ready for review July 13, 2026 10:39
destogl
destogl previously approved these changes Jul 13, 2026

@destogl destogl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally good, few smaller issues in tests.

prev_command_ = current_joint_states;
const auto num_joints = this->number_of_joints_;
prev_dt_seconds_ = 0.0;
effective_max_acc_.assign(num_joints, 0.0);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need here additional variables? Why? If this is just calculated, we don't need to keep the values. And if we are just storing them locally within a method, this should be on a heap and should not initialize any memory.

This makes sense as we need to later adjust all joint togeather.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I decided to remove the dt recalculation logic as in RT system dt should be constant. Now will remove these additional variables and update the on_enforce to update the max acc/dec when implicit vel exceeds the max vel.

Pls LMK if is approach is good?

// TODO(gwalck) compute if the max are not implicitly violated with the given dt
// e.g. for max vel 2.0 and max acc 5.0, with dt >0.4
// velocity max is implicitly already violated due to max_acc * dt > 2.0
// if the dt is changed then recalculate the max_acceleration/max_deceleration if implicit vel

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does it mean that dt is changend?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this also a problem for the velocity too?

}
else
{
effective_max_acc_[i] = joint_limits_[i].max_acceleration;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this might cause a problem if done only for one joint. We should scale down then all other joints appropriately...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are for now not scaling down also in other cases, then we don't have to do now, but in the followup PR, as this is important to not change robot trajectories.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I am thinking of calculating the max_reduction_factor = max_vel/implicit_vel, for all the joints and then use the min max_reduction_factor to scale down all the joints acc/dec.

Pls LMK if this approach is good?

desired_joint_states_.positions[0] = 1.0;
desired_joint_states_.velocities[0] = 1.5; // valid pos derivative as well
desired_joint_states_.accelerations[0] = 2.9; // valid pos derivative as well
desired_joint_states_.accelerations[0] = 2.0; // valid pos derivative as well

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pleaes create a new test for this and call it "when_derivative_too_high_expect_lower_effective_limits".

Also make the exact values checks.

// velocity max is implicitly already violated due to max_acc * dt > 2.0
// if the dt is changed then recalculate the max_acceleration/max_deceleration if implicit vel
// exceeds max vel
if (std::fabs(dt_seconds - prev_dt_seconds_) > 1e-9)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a chance that the dt won't be changed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Earlier, I was thinking as the enforce fn has dt argument, then the user can change it. But now I think for the real-time control system, dt should be constant. I will remove this comparison of dt and only update the params max_acceleration and max_deceleration to effective acc/dec when impl vel exceeds the max acc/dec.
Pls LMK if this approach is good?

Comment on lines +54 to +60
RCLCPP_WARN_STREAM_THROTTLE(
node_logging_itf_->get_logger(), *clock_, ROS_LOG_THROTTLE_PERIOD,
"Joint '" << joint_names_[i] << "': dt (" << dt_seconds
<< ") is too large for max_acceleration ("
<< joint_limits_[i].max_acceleration << ") and max_velocity ("
<< joint_limits_[i].max_velocity << "); max_acc * dt = " << implicit_vel
<< " exceeds max_velocity");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change this to non STREAM version please. STREAM versions are not realtime safe

Comment on lines +73 to +79
RCLCPP_WARN_STREAM_THROTTLE(
node_logging_itf_->get_logger(), *clock_, ROS_LOG_THROTTLE_PERIOD,
"Joint '" << joint_names_[i] << "': dt (" << dt_seconds
<< ") is too large for max_deceleration ("
<< joint_limits_[i].max_deceleration << ") and max_velocity ("
<< joint_limits_[i].max_velocity << "); max_dec * dt = " << implicit_vel
<< " exceeds max_velocity");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here non STREAM version

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the code for non stream version

Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
Replace the time-based delta check with a boolean flag to compute
effective
acceleration and deceleration limits only once, and update the limits
directly within the configuration rather than maintaining separate
vectors.

Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
Apply the minimum reduction factor across all joints when implicit
velocity exceeds velocity limits to maintain synchronized trajectory
execution.

Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
Updates an existing test value and adds a new test case to verify that
the joint limiter correctly enforces limits when derivatives exceed
configured thresholds.

Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Jerk Limiting in the Joint Limits and Integrated to JTC

3 participants