ros-controls / ros-controls/ros2_controllers
bug(tricycle_controller): strict inequality for M_PI_2 boundary causes speed scale to drop to ~0 instead of 0.01 limit
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 834
- Forks
- 530
- Avg merge
- 18h 3m
- Merged PRs (30d)
- 19
Description
Describe the bug
In TricycleController::update(), there is an attenuation mechanism that scales down the wheel speed (Ws_write) based on the steering angle error (alpha_delta) between the target wheel angle (alpha_write) and the current reading (alpha_read).
However, there is an edge case at the boundary of M_PI_2 (90 degrees) where a strict inequality check (alpha_delta > M_PI_2) prevents the controller from applying the intended 1% speed limit (0.01). Instead, it falls through to the else branch and calculates cos(alpha_delta) where alpha_delta is exactly M_PI_2. Due to floating-point precision, cos(M_PI_2) yields a value near zero (~6.12e-17), which virtually halts the wheel instead of scaling it to the intended 1% creep speed.
To Reproduce
- Command a spin action (set
linear.x = 0.0m/s,angular.z = 0.5rad/s). - The controller sets
alpha_writeto exactlyM_PI_2(~1.5707963268 rad). - At the initial transition state (where current steering angle
alpha_readis0.0rad),alpha_deltabecomes exactlyM_PI_2. - The condition
alpha_delta > M_PI_2evaluates tofalsebecause they are equal. - The execution flow falls through to the
elseblock, calculatingscale = cos(M_PI_2). - The output wheel speed is scaled to near-zero (e.g.,
2.47e-16rad/s for an unattenuated target speed of4.04rad/s) during the first control cycle, instead of the intended 1% speed limit (0.04rad/s).
Here is the empirical CSV printout captured from the cmd_ackermann topic at a 50Hz control rate:
# steering_angle, steering_angle_velocity, speed, acceleration, jerk
0.0,0.0,2.915452003479004,0.0,0.0 # straight driving
0.0,0.0,0.0,0.0,0.0 # timeout stop
1.5707963705062866,0.0,2.4725010844361235e-16,0.0,0.0 # Transition transient (cos boundary error!)
1.5707963705062866,0.0,4.037900924682617,0.0,0.0 # Steady state (angle tracking complete)
Expected behavior
When the steering error is exactly at or larger than M_PI_2, the speed scale should be limited to 0.01 to allow a slow creep motion rather than dropping to 10^-16 (virtually a zero-command dead zone).
Code Reference
Proposed Solution
Change the strict inequality > to >= in the boundary check to catch the exact boundary case:
- else if (alpha_delta > M_PI_2)
+ else if (alpha_delta >= M_PI_2)
{
scale = 0.01;
}
Environment
- OS: Ubuntu 24.04 LTS (Noble Numbat)
- ROS 2 Distro: Jazzy Jalisco
- Version or commit hash:
ros2_controllersversion4.40.1
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in tricycle_controller/src/tricycle_controller.cpp at TricycleController::update(), around the referenced boundary check, and trace how alpha_delta determines the speed scale. Verify the exact M_PI_2 transition behavior against the reported CSV values; done means the boundary uses the intended 0.01 limit rather than a near-zero cosine result.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- robotics
- Issue type
- Bug
- Difficulty
- 1/5
- Estimated time
- Under an hour
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 84/100