0
$\begingroup$

Rosanswers logo

What steps need to be followed to use diff_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.

my 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:

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 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."

I have absolute encoders on both motors. This "control system" is for me.

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.

hmm, I am working towards Navigation, and 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 (robotHW in image below) - within the context of the image, it would be very appreciated!

image description

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.

Not applicable to my robot; and fun fact, you can see the torque-RPM chart on motors to figure out what they are capable of. For example: https://www.applied-motion.com/sites/default/files/STAC5_speed-torque.pdf of course you need to calculate for offset from the shaft, and a few other things...


Originally posted by BuilderMike on ROS Answers with karma: 247 on 2018-11-02

Post score: 4

$\endgroup$

3 Answers 3

0
$\begingroup$

Rosanswers logo

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.


Originally posted by gvdhoorn with karma: 86574 on 2018-11-04

This answer was ACCEPTED on the original site

Post score: 7


Original comments

Comment by Syrine on 2019-08-07:
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

Here's my question https://answers.ros.org/question/330178/can-i-replace-hardware_interface-to-send-velocity-to-a-plc/?answer=330189#post-id-330189

$\endgroup$
0
$\begingroup$

Rosanswers logo

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!


Originally posted by PeteBlackerThe3rd with karma: 9529 on 2018-11-03

This answer was NOT ACCEPTED on the original site

Post score: 1


Original comments

Comment by BuilderMike on 2018-11-03:
@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.

Comment by gvdhoorn on 2018-11-04:\

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.

$\endgroup$
0
$\begingroup$

Rosanswers logo

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/kinetic-devel/husky_base/src/husky_base.cpp

...which is launched with diff_drive_controller here:

https://github.com/husky/husky/blob/kinetic-devel/husky_base/launch/base.launch


Originally posted by paulbovbel with karma: 4518 on 2018-11-06

This answer was NOT ACCEPTED on the original site

Post score: 1

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.