Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ackermann Steering 'Turning Radius' Confusion #2529

Open
Doge-God opened this issue Aug 19, 2024 · 1 comment
Open

Ackermann Steering 'Turning Radius' Confusion #2529

Doge-God opened this issue Aug 19, 2024 · 1 comment
Assignees
Labels
bug Something isn't working

Comments

@Doge-God
Copy link

Environment

  • OS Version: Ubuntu 22.04
  • Sourced, gz-sim8, 9e31084

Description

  • Expected behavior: <steering_limit> is the maximum ideal-wheel steering angle and we can derive a minimum turning radius from it.
  • Actual behavior: <steering_limit> does not have any semantic meaning OR the simulator does not follow the correct minimum turning radius.
    image

According to the doc, <steering_limit> should be asin(wheel_base / turning_radius)(https://gazebosim.org/api/sim/8/classgz_1_1sim_1_1systems_1_1AckermannSteering.html), see the graph and formula, that means the turning_radius here should refer to RF.

This turning radius is later extracted to be used in the code:

double minimumTurningRadius = this->wheelBase / sin(this->steeringLimit);

Everywhere else in the following calculation turning_radius is assumed to be RR: notice the usage of tan

double leftSteeringJointAngle =
atan(this->wheelBase / (turningRadius - (this->kingpinWidth / 2.0)));
double rightSteeringJointAngle =
atan(this->wheelBase / (turningRadius + (this->kingpinWidth / 2.0)));

This is especially obvious in the differential simulation calculations:

double phi = atan(this->wheelBase / turningRadius);

The left and right joint speed calculation below can be simplified to (Linear Velocity / Wheel Radius) * (1 +- 0.5KingPinWidth / TurningRadius)

// Partially simulate a simple differential
this->rightJointSpeed =
(linVel * (1.0 + (this->wheelSeparation * tan(phi)) /
(2.0 * this->wheelBase))) / this->wheelRadius;
this->leftJointSpeed =
(linVel * (1.0 - (this->wheelSeparation * tan(phi)) /
(2.0 * this->wheelBase))) / this->wheelRadius;

This checks out if the left and right joint speed refers to angular velocities of the 2 non-steering wheels at the back axel and turning radius being drawn to the center between the back wheels, meaning TurningRadius should be refering to RR and NOT RF.

HOWEVER if we blindly follow the documentation and mistakenly use RR as 'turning_radius' of our physical car and follow <steering_limit> = asin(wheel_base / turning_radius), the behavior of the car in the simulator will actually be correct since

double minimumTurningRadius = this->wheelBase / sin(this->steeringLimit);

will then extract RR and use it as RR correctly in the following calculations, but in this case our steering_limit is no longer SA in the diagram and doesn't have any useful meaning.

We should update line 839 to use tan instead of sin then update and clarify the documentation to avoid any confusion.

@Doge-God Doge-God added the bug Something isn't working label Aug 19, 2024
@azeey azeey moved this from Inbox to In progress in Core development Nov 11, 2024
@scpeters
Copy link
Member

it looks like it would be more consistent to use tan in that line as you propose. would you like to open a pull request for this change?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Status: In progress
Development

No branches or pull requests

3 participants