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 plugin's steering only mode shows opposite behaviour. Additionally added a gz PID for steering #2315

Closed
wants to merge 7 commits into from

Conversation

sauk2
Copy link
Contributor

@sauk2 sauk2 commented Feb 15, 2024

🦟 Bug fix

Fixes #2314

Summary

Issue pertains to Ackermann Steering plugin's steering_only mode specifically these lines.

  • Expected behavior: The inner wheel should turn more than the outer wheel during turning
  • Actual behavior: The opposite takes place. (Here I have commented out the chassis visual in the SDF for better visibility)

Screenshot from 2024-02-15 14-27-11

Steps to reproduce

  1. Add the following tag in the example SDF file of Ackermann Steering plugin.
  <steering_only>True</steering_only>
  1. Build and source the workspace
  2. Launch using the following command
  gz sim ackermann_steering.sdf
  1. Publish the following
  gz topic -t "/model/vehicle_blue/steer_angle" -m gz.msgs.Double -p "data: 0.4"

Additionally comment out chassis visual for better visibility

Solution

Changing signs in these equations should suffice.

Check output after implementation
Screenshot from 2024-02-15 14-51-32

Checklist

  • Signed all commits for DCO
  • Added tests
  • Updated documentation (as needed)
  • Updated migration guide (as needed)
  • Consider updating Python bindings (if the library has them)
  • codecheck passed (See contributing)
  • All tests passed (See test coverage)
  • While waiting for a review on your PR, please help review another open pull request to support the maintainers

Note to maintainers: Remember to use Squash-Merge and edit the commit message to match the pull request summary while retaining Signed-off-by messages.

🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸🔸

🎉 New feature

Summary

  • Added a programmable PID (gz::math::PID) to control the steering joints for both modes - velocity and steering only.
  • Default gains and other parameters are defined in Configure which can be overwritten from the SDF using appropriate tags.
  • A single PID is used to control both, left and right steering joints.

Test it

For steering only mode

  1. Add the following tag in the example SDF file of Ackermann Steering plugin.
  <steering_only>True</steering_only>
  1. Build and source the workspace
  2. Launch using the following command
  gz sim ackermann_steering.sdf
  1. Publish the following
  gz topic -t "/model/vehicle_blue/steer_angle" -m gz.msgs.Double -p "data: 0.4"

For velocity mode

  1. Build and source the workspace
  2. Launch using the following command
  gz sim ackermann_steering.sdf
  1. Publish the following
  gz topic -t "/model/vehicle_blue/cmd_vel" -m gz.msgs.Twist -p "linear: {x: 1.0}, angular: {z: 0.5}"

Checklist

  • Signed all commits for DCO
  • Added tests
  • Added example and/or tutorial
  • Updated documentation (as needed)
  • Updated migration guide (as needed)
  • Consider updating Python bindings (if the library has them)
  • codecheck passed (See contributing)
  • All tests passed (See test coverage)
  • While waiting for a review on your PR, please help review another open pull request to support the maintainers

Note to maintainers: Remember to use Squash-Merge and edit the commit message to match the pull request summary while retaining Signed-off-by messages.

Signed-off-by: Saurabh Kamat <saurabh.kamat@accelerationrobotics.com>
Signed-off-by: Saurabh Kamat <saurabh.kamat@accelerationrobotics.com>
Signed-off-by: Saurabh Kamat <saurabh.kamat@accelerationrobotics.com>
@sauk2 sauk2 requested a review from mjcarroll as a code owner February 15, 2024 07:10
@github-actions github-actions bot added the 🎵 harmonic Gazebo Harmonic label Feb 15, 2024
@sauk2 sauk2 changed the title Ackermann steering plugin's steering only mode shows opposite behaviour Ackermann steering plugin's steering only mode shows opposite behaviour. Additionally added a gz PID for steering Feb 15, 2024
@azeey azeey requested a review from bperseghetti February 28, 2024 16:42
@retinfai
Copy link
Contributor

A little tangent but somewhat related. Is it possible with the current plugin to be able to drive the vehicle using steering angle and forward velocity?

If not, is it something that can be implemented within the scope of this plugin?

Copy link
Member

@bperseghetti bperseghetti left a comment

Choose a reason for hiding this comment

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

Good catch, it looks like there is a trailing whitespace that needs fixed to pass CI.

@bperseghetti
Copy link
Member

A little tangent but somewhat related. Is it possible with the current plugin to be able to drive the vehicle using steering angle and forward velocity?

If not, is it something that can be implemented within the scope of this plugin?

Hmmmm, I think that's more the role of JointController,
Here's how I use them in a model together: https://github.com/CogniPilot/b3rb_simulator/blob/31554eb3126d6ee306a295b2f9f5e8524907b940/b3rb_gz_resource/models/b3rb/model.sdf#L540-L562

Note that JointController uses the velocity rad/s field when using actuator_msg and steering_only in Ackermann with actuator_msg uses the position (rad).

Signed-off-by: Saurabh Kamat <saurabh.kamat@accelerationrobotics.com>
@sauk2
Copy link
Contributor Author

sauk2 commented Mar 12, 2024

@bperseghetti, on a completely unrelated note. Would it be a good idea to calculate wheel separation in case it is not provided by the user?

We can use the world pose of the left and right steering joints and calculate that value. This calculation will not be performed if there is a value given in the SDF.

Would like to hear your thoughts on this

@sauk2 sauk2 requested a review from bperseghetti March 12, 2024 06:31
Copy link

codecov bot commented Mar 12, 2024

Codecov Report

Attention: Patch coverage is 77.27273% with 10 lines in your changes are missing coverage. Please review.

Project coverage is 65.98%. Comparing base (633ce72) to head (929a15b).
Report is 5 commits behind head on gz-sim8.

Files Patch % Lines
...rc/systems/ackermann_steering/AckermannSteering.cc 77.27% 10 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##           gz-sim8    #2315   +/-   ##
========================================
  Coverage    65.97%   65.98%           
========================================
  Files          327      327           
  Lines        31328    31379   +51     
========================================
+ Hits         20668    20704   +36     
- Misses       10660    10675   +15     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@bperseghetti
Copy link
Member

bperseghetti commented Mar 13, 2024

@bperseghetti, on a completely unrelated note. Would it be a good idea to calculate wheel separation in case it is not provided by the user?

We can use the world pose of the left and right steering joints and calculate that value. This calculation will not be performed if there is a value given in the SDF.

Would like to hear your thoughts on this

Hmmmm, I think that might be risky depending on the intended use case for it. IE using 4 wheel steering (like you see on a good amount of newer electric trucks). I think maybe you could calculate it though and then see if it does not match the provided value within a "reasonable error percentage" (IE 15%) that it publishes a gz-warn to let you know what value it thinks it should be.

But depending on things like suspension etc the steering joint might actually be a relative reference to another joint and then that would be somewhat messy to follow that potential dependency tree.

IE having joints for a suspension such as macpherson, wishbone, etc would make the steering joint a relative joint to those other suspension joints and that just starts to possibly become more risk than reward.

Therefore, my personal take on it might lean toward it "probably not being a good choice"?

Adds test for steering_only PID and conditional for the SDF PID
elements.

Signed-off-by: Benjamin Perseghetti <bperseghetti@rudislabs.com>
@bperseghetti
Copy link
Member

@sauk2 if you merge this it should fix the code coverage issue and cleanly separate the PID steering_only SDF elements:
sauk2#1

Ackermann: steering_only add tests and conditional.
@sauk2
Copy link
Contributor Author

sauk2 commented Mar 14, 2024

Hmmmm, I think that might be risky depending on the intended use case for it. IE using 4 wheel steering (like you see on a good amount of newer electric trucks). I think maybe you could calculate it though and then see if it does not match the provided value within a "reasonable error percentage" (IE 15%) that it publishes a gz-warn to let you know what value it thinks it should be.

But depending on things like suspension etc the steering joint might actually be a relative reference to another joint and then that would be somewhat messy to follow that potential dependency tree.

IE having joints for a suspension such as macpherson, wishbone, etc would make the steering joint a relative joint to those other suspension joints and that just starts to possibly become more risk than reward.

Therefore, my personal take on it might lean toward it "probably not being a good choice"?

Yes, that makes sense. Thanks!

Signed-off-by: Benjamin Perseghetti <bperseghetti@rudislabs.com>
// Simple PID control with settable gains.
this->leftSteeringJointSpeed = this->steerPosPid.Update(
leftDelta, _info.dt);
this->steerPosPid.Reset();
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason for resetting steerPosPid here? If I'm not mistaken, if we reset it, the D and I terms of the PID will not do anything.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was resetting the steerPosPid because I was using the same PID for both steering joints and it was causing random motions. I didn't realise it would render the I and D terms useless.

After giving it more thought, I think this will be solved if I create 2 PID controllers in Configure - one for each steering joint.

Would like to hear your thoughts on this.

Copy link
Member

@bperseghetti bperseghetti Mar 18, 2024

Choose a reason for hiding this comment

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

@sauk2 So, I have two thoughts, first is typically Ackermann steering is done through a physical linkage with a single steering actuator. In this case the "PID" would only be the central steering angle and that would cause some problems for the method attempting to be implemented here, I wouldn't really like to have one of my wheels with a different PID tuning or response based on angle than the other. So if it were to be done I think you would have to take the average of both wheel angles back to the central steering angle and run the PID on the central steering angle till they aligned properly (this could also have other downsides like lower convergence or a skew between the two wheels that solves the recalculated central steering angle but not having the wheels in the desired spot as they offset eachother).

The second thought I have is that while a PID might make sense for a "cmd_vel" based "miniature controller", when using the steering_only I think the only thing that should be used is P gain as it can always be wrapped with some sort of input shaping, and a lot of "raw" actuators are just proportional anyhow.

Copy link
Member

Choose a reason for hiding this comment

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

I think we should get the fix in for the steering angle, but I don't think we should necessarily couple that with the PID changes. I think these should be separate PRs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense. So all the changes will have to be rolled back. The easiest way I can see is to reset this branch to commit id 633ce72 and then resolve the bug.

Should I go ahead with this or is there any alternate method that you have thought of?

Copy link
Member

Choose a reason for hiding this comment

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

I guess I would just pull latest commit on branch and then make the fix ontop of it: 6cfcd07

Copy link
Member

@bperseghetti bperseghetti Mar 18, 2024

Choose a reason for hiding this comment

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

And then push your current branch to another branch like ackermann-pid so you could reference it later, and push the changes ontop the other temp working branch based on 6cfcd07 to this current branch so you don't lose history in this PR.

@bperseghetti
Copy link
Member

A little tangent but somewhat related. Is it possible with the current plugin to be able to drive the vehicle using steering angle and forward velocity?

If not, is it something that can be implemented within the scope of this plugin?

Yes, for that you just set wheel velocity with rad/s using the JointController plugin and also the steering angle all using the actuator msg, example is here:

https://github.com/CogniPilot/b3rb_simulator/blob/7830685f9b9c3aca2105ee9e149969d2db696350/b3rb_gz_resource/models/b3rb/model.sdf#L1090-L1112

@sauk2
Copy link
Contributor Author

sauk2 commented Mar 23, 2024

@bperseghetti Created a seperate PR #2342 for the steering error fix! Request you to take a look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🎵 harmonic Gazebo Harmonic
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Ackermann Steering plugin's steering only mode shows opposite behaviour than expected
4 participants