ros-controls / ros_controllers

Generic robotic controllers to accompany ros_control
http://wiki.ros.org/ros_control
BSD 3-Clause "New" or "Revised" License
561 stars 526 forks source link

[ackermann_steering_controller] angular velocity vs. steering angle #412

Open stertingen opened 5 years ago

stertingen commented 5 years ago

I have a question regarding the ackermann_steering_controller:

The controller subscribes to cmd_vel, which contains the desired angular velocity. This must be converted (using the linear velocity and the wheel distance) into a steering angle for the front_steer_joint, but according to the source code, the angular velocity (rad/s) gets directly passed to the controller (rad). Am I overseeing something?

Angular velocity gets fetched: (https://github.com/ros-controls/ros_controllers/blob/kinetic-devel/ackermann_steering_controller/src/ackermann_steering_controller.cpp#L382)

Angular velocity gets written to joint: (https://github.com/ros-controls/ros_controllers/blob/kinetic-devel/ackermann_steering_controller/src/ackermann_steering_controller.cpp#L338)

Odometry does the conversion: (https://github.com/ros-controls/ros_controllers/blob/kinetic-devel/ackermann_steering_controller/src/odometry.cpp#L92)

Achllle commented 4 years ago

I was surprised to see this too and it is in fact incorrect. The angular velocity indeed doesn't convert to a turning angle directly, instead it converts to a turning radius through the linear velocity: r = twist.linear.x / twist.angular.z. The turning radius in turn then informs what the wheel angles should be. This makes sense: a car driving very fast will have a higher angular velocity than when it's driving slowly, for the same wheel angles.

aslucki commented 3 years ago

It seems that there are all the necessary variables available and the actual steering angle could be calculated based on that turning radius and the wheelbase. I wonder, are there any reasons why it wasn't corrected? Would it break some other tools that already somehow depend on this controller?

I see that there are some problems as the angular velocity is related to the linear velocity and it's not obvious which one should be prioritized (for example, should the linear velocity be increased by the controller to achieve angular velocity specified in the command or the linear velocity should be considered constant).

But in general, it seems more intuitive if the angular velocity was converted to steering angle by the controller. I'll work on it for my own project and gladly open a PR if I succeed in correcting this issue without introducing any new ones. Please let me know if you are aware of any previous attempts that were deliberately abandoned because of good reasons :)