# What are the steps to use diff_drive_controller in a physical robot?

What steps need to be followed to usediff_drive_controller on a physical robot that is using differential drive (including all packages diff_drive_controller needs)?

I need a bridge between geometry_msgs/Twist messages and my physical robot.

The code to send messages to my stepper drives is finished (the two robot wheels are turned via stepper motors that are controller by Ethernet stepper drives). All I need is a way to translate geometry_msgs/Twist to my code that tells the stepper drives how to move (number of steps, accel, decel, velocity, etc....). This will allow me to:

1. Test the robot, by publishing to the topic manually (and getting robot motion)
2. Convert Navigation stack messages to robot motion.

I am running Ubuntu 16.04 with Kinetic.

Some background on the question: For this robot I did all the mechanical, electrical and coding (both design and implementation) myself. As you can imagine, I am not very strong at any one of those 3 things (I am a very, very persistent generalist). At this point I find myself in programmer territory, and I am getting to a point where the documentation is getting very hard to digest or I can't find any.

I have looked through the diff_drive_controller source code, and the package overall. I have looked over the diff_drive_wiki (including the so called diff_drive_controller website). I have looked over all 25 FAQs. None of those places have tutorials, or something I can use to get going. What I know is what I learned from the 25 questions and answers for the FAQs for diff_drive_controller:

• I need to create a hardware_interface to abstract my hardware for the diff_drive_controller . I found a sample here: https://github.com/eborghi10/my_ROS_m...
• I have to describe my robot using robot_description.
• I understand that ros_control is somehow related to ros_controllers and that diff_drive_controller is part of ros_controllers.
• I now understand that this package is suitable for “real-time”, but I don't need that functionality.
• I understand that diff_drive_controller is not a typical node, and I need a controller_manager.
• the video https://vimeo.com/107507546 provided by Adolfo Rodriguez offered in one of the answers does a great job of explaining interaction between packages (as a high level overview).

The problem is that all those things that I understand do not get me any closer to utilizing these wonderful packages as I have no idea where to start, where to continue, and what the finished code looks like. I am not the first person to build a robot with two drive wheels (as it's the easiest robot to build), who insists to use ROS (thank you so much to all you ROS people, you are beautiful), who has many talents, but is not a programmer. Could you provide a list of steps that people like me can follow to convert geometry_msgs/Twist to low level code our robot understands? Could you please make each step small enough for a beginner to follow?

EDIT #1

The ros_control packages are all ...

edit retag close merge delete

Sort by » oldest newest most voted

if you could please assist by providing the steps for implementing the geometry_msgs/Twist which the base_controller (in image below) is getting, and converting it to messages I can map to commands for my stepper drives

what you write here is exactly what the diff_drive_controller does: it takes in Twists and converts those to rad/s for each wheel based on the configuration that you provide it.

The only thing you need to do is write a hardware_interface that can convert those rad/s into something your actuators can work with. And "work with" means:

1. convert from rad/s to whatever units your actuators use / expect
2. use whatever control interface your actuators expose (registers, motor board API, serial, whatever) to send that converted setpoint to the actuators

That is what a hardware_interface does (here in the implementation that you link to).

They typically also read whatever sensor you then have on those actuators and convert whatever internal units those sensors use to SI units and offer them up to the "higher layers" of ros_control (ie: the controllers) to publish them as ROS messages or to use them directly if configured for closed-loop control (reading happens here).

As to your example hardware_interface: that one happens to be using ROS messages as its input and output. That is fine. It's not a requirement though. A lot of hardware_interfaces read or write directly from/to registers or shared memory and don't use ROS messages at all.

In the end it doesn't matter: as long as the hardware_interface implements the required interface (ie: read(..), write(..) and some other methods) ros_control can work with it.

more

Hi gvdhoorn

"what you write here is exactly what the diff_drive_controller does: it takes in Twists and converts those to rad/s for each wheel based on the configuration that you provide it.
The only thing you need to do is write a hardware_interface that can convert those rad/s into something your actuators can work withode here"


I'm writing a hardware interface for my robot and I don't understand how the diff_drive_controller sends the data to the actuators? I mean I understand the code but didn't get the link between diff_drive and hardware_interface. Does the fact that diff_drive node has joint_command_interface.h file answer my question? Thanks

( 2019-08-07 08:40:22 -0600 )edit

As far as an example of a HardwareInterface + ControllerManager out of the wild, I can offer up the husky_base node:

https://github.com/husky/husky/blob/k...

...which is launched with diff_drive_controller here:

https://github.com/husky/husky/blob/k...

more

The ros_control packages are all closed loop controllers of one sort or another, designed for working with encoders and DC motors. If you're motors are driven by open loop stepper drivers without encoders then you'll need a different control system.

The maths behind a two wheel differential drive system is fairly simple. First you calculate the wheel velocities needed to produce the desired linear speed, then calculate the wheel velocities needed to produce the desired angular rate. Adding the two pairs of velocities together will tell you how fast the left and right wheels need to turn in order to produce the desired x linear and z angular velocities from a geometry_msgs/Twist message.

For an open loop stepper driver you'll want to experimentally determine your maximum acceleration possible without losing steps then choose a threshold a certain safety factor beneath this. You'll then want to use the velocities calculated above but with a limiter to make sure that you don't exceed the maximum acceleration of the motors.

However if you don't have encoders there will always be a risk of losing steps if there is more resistance to motion than expected due to slopes or rough surfaces. The usual solution is to significantly over-rate the motors.

Hope this doesn't throw a spanner in the works too much!

more

@PeteBlackerThe3rd Hey dude, your two cents did not provide a list of suggestions I could act on. Can you please provide a list of actions to act on? kindly see Edit #1. Thank you in advance.

( 2018-11-03 23:50:24 -0600 )edit

The ros_control packages are all closed loop controllers of one sort or another,

actually, there are quite a few "controllers" in there that are only forwarding the command they received. No closed loop then.

( 2018-11-04 01:26:12 -0600 )edit