Rosanswers logo


I'm building a small prototype robot for learning. My hardware layout is similar to the image below. I already have the complete urdf model.

To count the ticks of the encoders of the two engines I will use two ls7366r or through events with pigpio directly on the pins of the raspberrypi (I don't know what is better, I accept suggestions... https://answers.ros.org/question/356896/count-encoders-with-raspberry-pi-4/).

I'm a little confused about the implementation of diff_drive_controller. I understood that he will publish odometry and transformations (odom -> base_footprint) and subscribe to the topic / cmd_vel, which contains the velocity commands sent by move_base or a joystick.

What I am unable to understand is:

  • how does diff_drive_controller know how far the robot has moved? Because he does not subscribe to any topic that tells how many encoder ticks have passed.

  • Who calculates the correct rotation speed for each wheel?

  • Is it diff_drive_controller that will generate the PWM for electric motors? Who should generate the pwm for the engines?

  • There must be a PID for each wheel. Which node implements the PID? Is it the same node that generates the PWM on the raspberry pin?

image description

Thank you

Originally posted by mateusguilherme on ROS Answers with karma: 125 on 2020-07-10

Post score: 0

Original comments

Comment by Humpelstilzchen on 2020-07-11:
The basic answer to your questions is that you are the one to implement it. diff_drive_controller takes at input the velocities from each wheel and generates as output the desired velocity for each wheel. So the wheel velocity<->hardware needs to be done by you in your Implementation of hardware_interface::RobotHW

It is probably a good idea to copy from examples, e.g. this answer

Comment by mateusguilherme on 2020-07-12:
ok, but where does he publish the velocity information for each wheel?


1 Answer 1


Rosanswers logo

A lot of answers to this question are in the understanding of how ros_control works. Below there are three links that will explain how it does work:

So, to answer your questions, I'll make a briefing that how ros_control works. In ros_control there are a lot of layers as you can see in this image image description http://wiki.ros.org/ros_control?action=AttachFile&do=get&target=gazebo_ros_control.png

**Source: ** ros_control wiki

Starting from down to up, the Real Robot in your case is the dc motors and its encoders. So, the first thing that you need to do is to write one class to control the velocity of the dc motors and another class to read the values from the encoders. These classes could be totally independent of ROS. My suggestion is to implement methods that get an angular velocity as an argument and convert this value to PWM and for encoders, you need to implement methods to get angular velocity and position for each wheel. Below some examples that I made for my robot

If possible, my suggestion is to make an independent process only to control the wheels. So in this process, you will implement the PID for each wheel. And the communication with this process could be through a UDP socket for example. Another solution is to make the control process in a microcontroller and communicate with it through a serial interface like UART.

After this implementation, you need to implement the RobotHW. Is the RobotHW that get the velocities from diff_drive_controller and send it to the real robot. The RobotHW is a class that has some virtual methods: init, write, and read. You need to inherit this class and implement these virtual methods. The init method is where is some initialization methods like to open the communication port. The write method is where you send the commands to the real robot. The commands are the angular velocity for each wheel. Based in my suggestions above, these commands would be sent through UDP socket or UART interface. Finally, the read is the method that you get the values from the encoders. Remember that for diff_drive_controller you need to provide angular velocity and position. Follow the example for my robot:

Note: In my robot I didn't make an independent process to control the wheel. It Is in the future plan to do this. And how I tried to use the wheels control mixed with the main loop control (I'll talk about it yet) I don't recommend this approach

The yellow block of the diagram is where is the diff_drive_controller. The diff_driver_controller based on the physical parameters of your robot (wheel diameter and distance between wheels), that is passed in a config file like this, compute which is the angular velocity that must be applied in each wheel of the robot to it reaches the linear and angular velocities published in the cmd_vel topic. To compute the odometry data and then makes the tfs, the diff_drive_controller uses the values from the encoders and also the robot's physical parameters. But remember there are other layers between the diff_drive_controller and the real robot.

Finally, the ros_control has a control_manager to manage all these things. And for the control of your robot finally works, you need to make one control loop. You can see how it does works in this code. To run the control node, you need to make a launch file like this

For advanced examples, see the Husky robot packages:

Originally posted by mateussmenezes with karma: 46 on 2020-07-11

This answer was ACCEPTED on the original site

Post score: 3

Original comments

Comment by mateusguilherme on 2020-07-14:
thanks for your reply, it was of great help!


Your Answer

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