Skip to content

Enhance: Added joint limit loader plugin - #2442

Open
sachinkum0009 wants to merge 23 commits into
ros-controls:masterfrom
sachinkum0009:feat/jtc-jerk-limits
Open

Enhance: Added joint limit loader plugin#2442
sachinkum0009 wants to merge 23 commits into
ros-controls:masterfrom
sachinkum0009:feat/jtc-jerk-limits

Conversation

@sachinkum0009

Copy link
Copy Markdown

Description

This PR integrates the Joint Limiter using Plugin Loader to use Joint Saturation Limiter.

Summary

  • Added Pluginlib to load the JointSaturationLimit plugin
  • Added Tests to validate the plugin for Pos, Vel, Vel + Acc and Pos + Vel + Acc

Fixes #2434

Is this user-facing behavior change?

Yes, with this PR, the JTC uses Joint Saturation Limiter to limit the pos, vel, acc, or jerk based on the configuration.

Did you use Generative AI?

Used OpenCode to understand the code and write tests.

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.

…ation limits

Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
@codecov

codecov Bot commented Jun 26, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.85965% with 21 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.97%. Comparing base (c7b97ca) to head (6172714).
⚠️ Report is 4 commits behind head on master.

Files with missing lines Patch % Lines
...ory_controller/src/joint_trajectory_controller.cpp 39.28% 12 Missing and 5 partials ⚠️
...jectory_controller/test/test_joint_limiter_jtc.cpp 98.51% 0 Missing and 4 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2442      +/-   ##
==========================================
+ Coverage   86.83%   86.97%   +0.13%     
==========================================
  Files         148      149       +1     
  Lines       16273    16615     +342     
  Branches     1368     1394      +26     
==========================================
+ Hits        14131    14451     +320     
- Misses       1635     1644       +9     
- Partials      507      520      +13     
Flag Coverage Δ
unittests 86.97% <93.85%> (+0.13%) ⬆️

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

Files with missing lines Coverage Δ
...jectory_controller/joint_trajectory_controller.hpp 62.50% <ø> (ø)
...ory_controller/test/test_trajectory_controller.cpp 98.83% <100.00%> (+0.01%) ⬆️
...ntroller/test/test_trajectory_controller_utils.hpp 83.97% <100.00%> (+0.25%) ⬆️
...jectory_controller/test/test_joint_limiter_jtc.cpp 98.51% <98.51%> (ø)
...ory_controller/src/joint_trajectory_controller.cpp 83.85% <39.28%> (-1.39%) ⬇️

... and 1 file with indirect coverage changes

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

type

Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
@sachinkum0009

sachinkum0009 commented Jun 29, 2026

Copy link
Copy Markdown
Author

Test Integrated

Test Name Implemented
Joint limiter failed to configure
Joint limiter config successfully
joint limiter failed to activate
Joint limiter activate successfully
Limits Position
Limits Velocity
Limits Acceleration
Limits Pos, Vel, Acc
Short Sample Traj within limits
Short Sample Traj on limits
Short Sample Traj over limits
Long Sample Traj within limits
Long Sample Traj on limits
Long Sample Traj over limits

Moved joint limiter tests from `test_trajectory_controller.cpp` to a new
`test_joint_limiter_jtc.cpp` file and added a helper function to provide
default limiter parameters to reduce duplication.

Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
Expanded the test suite to include long and short trajectories that
exceed defined limits. Also replaced `std::abs` with `std::fabs` for
floating-point comparisons in tests and marked helper function as
inline.

Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
@mergify

mergify Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

This pull request is in conflict. Could you fix it @sachinkum0009?

@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.

Please comment. It seems a bit trivial implemenation. Explain why you think it is correct.

// Apply joint limiter to the next commanded state
if (joint_limiter_)
{
joint_limiter_->enforce(state_current_, command_next_, update_period_);

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.

why is here the right place to enforce limits? Shouldn't we do this in before and after interpolation?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I think the best place to enforce limits is after the interpolation. If appied limits before interpolation, it can produce inconsistent interpolation results.

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 happens than with the interpolation? Will we still have interpolated values?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks. Yes, we still have the interpolated values, as the joint limiter is applied before publishing the next cmd to hardware interface.

// Apply joint limiter to the requested state
if (joint_limiter_)
{
joint_limiter_->enforce(state_current_, state_requested, update_period_);

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.

Why this second call in the query state service?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

As the ~/query_state service (control_msgs::srv::QueryTrajectoryState) allows querying the expected state at a future time. I think if we have joint limiter plugin enabled then we should return the response with limits applied.

EXPECT_NEAR(joint_vel_[0], 0.5, COMMON_THRESHOLD);
EXPECT_NEAR(joint_vel_[1], 0.5, COMMON_THRESHOLD);
EXPECT_NEAR(joint_vel_[2], 0.5, COMMON_THRESHOLD);
EXPECT_NEAR(joint_pos_[0], INITIAL_POS_JOINT1 + 0.5 * 0.01, COMMON_THRESHOLD);

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.

I am not sure whether this is correct, as you are testing the limiter. What happens with interpolation in this case? Are we breaking it?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks, I have updated the tests to validate the interpolated values and make sure the position, velocity and acceleration remains within the limits.

updates

Replace static initial positions with a trajectory containing three
distinct waypoints. Adjust the update loop to step through each segment
using constant 10ms intervals, ensuring verification covers the full
duration of the published points up to t=0.6s. Use
`limit_enforced_points` for assertions to account for clamped values at
specific times rather than checking immediately after publishing a
single point.

Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
Replaced single-step snapshot assertions with a loop that advances the
controller at 10ms intervals. This change verifies both velocity and
acceleration limits across multiple interpolated points for each segment
of the trajectory. Tests now iterate through all waypoints, ensuring
constraints hold throughout motion rather than just after initial
application.

Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
Increase `max_velocity` for joint1, joint2, and joint3 from 0.5 to 2.0
radians/s in the unit tests configuration function. This adjustment
reflects realistic actuator capabilities used during testing scenarios
involving dynamic motion commands.

Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
clamping

- Remove unused `limit_enforced_points` vectors from velocity and
  acceleration tests.
- Replace manual assertions with a loop stepping through the trajectory
  at 10ms intervals.
- Verify that commanded velocities, accelerations, and positions respect
  all limits throughout execution.

Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
Signed-off-by: Sachin Kumar <sachinkum123567@gmail.com>
@sachinkum0009

Copy link
Copy Markdown
Author

I have plotted few test cases for JTC with joint saturation limiter plugin.

Trajector on the limits

trajectory_plot1

Trajectory over the limits

trajectory_plot2

Pls LMK if there are some more suggestions or feedback. I would like to merge this ASAP. 🙏

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

2 participants