Skip to content

Conversation

ipa-dmo
Copy link

@ipa-dmo ipa-dmo commented Oct 13, 2025

The scale velocity flag is not maintaining the curvature as i would assume. It says:

Whether or not to adjust other components of velocity proportionally to a component’s required changes due to acceleration limits. This will try to adjust all components to follow the same direction, but still enforces acceleration limits to guarantee compliance, even if it means deviating off commanded trajectory slightly.

The eta factor is currently calculated based on the planned velocity change dv and the maximum velocity change v_component_max. So not related to the absolute velocity but only the difference of the commanded velocity to the current velocity.

Later later the eta factor is used in the applyConstraints function in the same way:
return v_curr + std::clamp(eta * dv, v_component_min, v_component_max);

This is fine, as long both are used with the same velocities, but when the eta is calculated from e.g. the turning limitations and used in the x-velocity constraint this results in problems.

E.g. we have a limitation in turning acceleration resulting in following eta and then used in the v_x and omega constraint.
With some example values: omega_component_max = 10, frequency = 20 Hz, v_x_curr = 1.5, v_x_cmd = 2.0, omega_curr = 0.0, omega_cmd = 1.5
This has a commanded radius of r = 2.0/1.5 = 1.33.
eta = omega_component_max / (omega_cmd - omega_curr) = 1/3
results for the scaled difference before clamping of the velocity:
v_diff_before_clamping = eta * (v_x_cmd - v_x_curr) = 1/6
and the angular velocity:
omega_diff_before_clamping = eta * (omega_cmd - omega_curr) = 1/2
If we assume no further clamping, we get the following resulting path radius:
r = ( v_curr + v_diff_before_clamping ) / ( omega_curr + omega_diff_before_clamping ) = 3.33

So the robot would accelerate and miss the planned curvature.
This happens because only the difference is scaled by eta not the absolute, resulting values.

With the suggested approach, we redefine eta a bit by (actually bad example for this since omega_curr = 0, so it is the same result here):
eta = (omega_component_max + omega_curr) / omega_cmd = 1/3
and use it in the calculation for x velocity:
v_diff_before_clamping = eta * v_x_cmd - v_x_curr = -5/6
and the angular velocity:
omega_diff_before_clamping = eta * omega_cmd - omega_curr = 1/2
If we assume no further clamping, we get the following resulting path radius:
r = ( v_curr + v_diff_before_clamping ) / ( omega_curr + omega_diff_before_clamping ) = 1.33

Tests on our robot showed this improves the accuracy of the curvature drastically on different limit settings. And from my understanding this is the expected behavior based on the parameter description.

Or did i misunderstood the desired behavior?


Basic Info

Info Please fill out this column
Ticket(s) this addresses (add tickets here #1)
Primary OS tested on Ubuntu
Robotic platform tested on skid-steer / diff drive tracked robot
Does this PR contain AI generated software? No
Was this PR description generated by AI software? No

Description of contribution in a few bullet points

  • Updated the velocity scaling to remain on the curvature

Description of documentation updates required from your changes

Description of how this change was tested

  • Tested it on a robot during some coverage navigation.

Future work that may be required in bullet points

  • Not sure about the solution for 0 command values, I guess it could be fine to just skip it like this, but we would not really enforce any acceleration limits anymore when stopping.

For Maintainers:

  • Check that any new parameters added are updated in docs.nav2.org
  • Check that any significant change is added to the migration guide
  • Check that any new features OR changes to existing behaviors are reflected in the tuning guide
  • Check that any new functions have Doxygen added
  • Check that any new features have test coverage
  • Check that any new plugins is added to the plugins page
  • If BT Node, Additionally: add to BT's XML index of nodes for groot, BT package's readme table, and BT library lists
  • Should this be backported to current distributions? If so, tag with backport-*.

Copy link
Member

@SteveMacenski SteveMacenski left a comment

Choose a reason for hiding this comment

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

Please remove the debug logging updated in development & fix the linting/DCO issues before a human review.

@ipa-dmo ipa-dmo force-pushed the velocity_smoother_true_curvature branch from 9c3885a to ccd288a Compare October 14, 2025 08:18
Comment on lines 277 to 279
if (std::abs(v_cmd) < 1e-6) {
return -1.0;
}
Copy link
Member

Choose a reason for hiding this comment

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

How should we smooth while slowing then if v_cmd cannot be zero without a divide by zero error for the new implementation? Slowing to a stop seems like a pretty key element of this work

Copy link
Member

Choose a reason for hiding this comment

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

Is there an option that would retain the shape as you see it that allows for the (pretty important?) feature of being able to slow to a stop using the smoother?

Copy link
Author

Choose a reason for hiding this comment

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

This return does no change the slowdown on a stop, it just does not update the eta, that is used the lower the other factors (yaw velocity e.g.) to keep the curvature. So this should be fine imo.

@ipa-dmo
Copy link
Author

ipa-dmo commented Oct 19, 2025

I added some tests to show the behavior of the scale_velocity feature.
In general there are two main expections from updating to the commanded curvature:

  • When we are slowing down, but hit an limit, we would need to increase the linear/angular velocity to maintain the commanded curvature (eta would be > 1.0). With both the old implementation and the new one this is not used. I guess we do not want to unexpectedly accelerate based on the limitation on a different factor.
  • When switching velocity directions, the calculation of eta could result in a negative eta. This would also lead to weird accelerations or deceleration, so negative eta are ignored. This behavior is also the same as before.
    So in both those cases the commanded curvature is not executed, even if it would be possible in theory, but i would lead to probably unintended motions.
    Any opinions on this?

Copy link

codecov bot commented Oct 19, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.

Files with missing lines Coverage Δ
nav2_velocity_smoother/src/velocity_smoother.cpp 93.22% <100.00%> (-0.81%) ⬇️

... and 25 files with indirect coverage changes

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

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.

2 participants