# computing odometry, creating base controller

I am building my own custom robot and am finding it difficult to interface it to ROS (standard odometry and cmd_vel motor control). All I need is to publish odometry, based on the encoder ticks, and translate the twist messages (subscribed) into motor control signals, to be used with Navigation stacks. I found this tutorial - Publish odometry. But it only explains half of the problem. They insert vx, vy and vth values to generate fake odometry of a robot driving in circles. I am trying to calculate real odometry. Can someone help with the code for calculating vx, vy and vth from actual encoder ticks? I will measure the wheel diameter, the amount of ticks per revolution, and the distance between the wheels. But not sure how to implement that in calculating the vx, vy and vth. Intuitively it seems like a simple task, and there are pieces of code on odometry all over ROS tutorials/documentation. But I just can't seem to put it all together. Later, I will also need to find a way to convert geometry/Twist messages to motor power signal. I would really appreciate any help, and believe it will help others in the future.

Originally posted by scandrew on ROS Answers with karma: 31 on 2016-08-30

Post score: 3

There are a couple of examples you can look at. First, assuming you can publish the encoder ticks in some way, the differential_drive package has nodes to both publish odometry from encoder ticks and to convert from Twist to motor speeds. All the source is in Python, so it's reasonably easy to read.

Second, if you are using a microcontroller like an Arduino to talk to the hardware, you could use a package like ros_arduino_bridge. It has a ROS node (Python) and an Arduino sketch that communicate to share the work. The Python side does the conversion from ticks to odometry and from Twist to motor control. It also includes a PID controller on the Arduino side. (In my robot I'm using a Pololu A-Star board that fits on top of a Raspberry Pi, for example.)

I think most commercial robots using ROS (PR2, Husky, etc.) use the C++-based hardware interfaces instead. If you're going to follow the same path, you might look at how one of those commercial robots are handling this problem. The examples on the ClearPath site might be a good starting point.

Originally posted by Mark Rose with karma: 1563 on 2016-08-30

This answer was ACCEPTED on the original site

Post score: 1

Comment by scandrew on 2016-08-31:
Thank you for such a complete answer. ros_arduino_bridge looks pretty good actually. Unfortunately it is not yet released for kinetic. I am still not sure how that affects the installation/usage in new distros. At the very least I can look at the source files, and try to figure it out on my own

Comment by Mark Rose on 2016-08-31:
You should not have any problems using ros_arduino_bridge for kinetic, but you probably need to get source. I recommend using the fork maintained by Marco Werther. I've contributed code to specify a frame for each sensor, if desired, for example.

Comment by Mark Rose on 2016-08-31:
Use the indigo-devel branch (even in kinetic).

Comment by Mark Rose on 2016-08-31:
One more thing: ros_arduino_bridge has support for some distance sensors, publishing as sensor_msgs/Range. You will have to write/get another node that subscribes to the Range values and publishes as a point cloud or laser scan, if you want to use the nav stack, or modify ros_arduino_bridge.

Comment by scandrew on 2016-08-31:
Thanks Mark. I will be using Intel's Realsense depth images for that. But it's good to know there is a library that supports simple sensors as well. For now, I will try to get this to publish odometry and send motor signals to my Teensy 3.1.

Comment by Mark Rose on 2016-08-31:
With a Teensy you might also consider rosserial_arduino and rosserial_python. The Arduino programming model is ROS-like: you publish and subscribe directly from the Arduino side. On smaller microcontrollers memory is an issue, but shouldn't be a problem with the Teensy.

Comment by scandrew on 2016-09-01:
Mark, I already have rosserial_arduino working. Where I had a challenge, was computing the odometry. It even came with an example of publishing odometry on the Arduino side, but it is publishing fake odometry of the robot driving in a circle. If only I could modify it to compute from actual encoders

Comment by Mark Rose on 2016-09-01:
OK, here's what I did previously. I published odometry as ticks from rosserial, then used the differential_drive package to publish odometry on /odom.

Comment by Mark Rose on 2016-09-01:
I abandoned rosserial because I'm using a Leonardo that only has 2kb RAM. rosserial is a relative memory hog on that class machine. Now I'm using ros_arduino_bridge, as I mentioned. Both approaches work.

Comment by scandrew on 2016-09-01:
That is precisely what I was trying to do. Publish the ticks and use differential_drive package. I ran into a problem of trying to install that package on kinetic, and was under impression it was just outdated. I will try again today. I will use catkin_make. Hopefully it works

Comment by Mark Rose on 2016-09-01:
You'll also need a PID controller on the Arduino side. There are several Arduino libraries available or you can write your own. ros_arduino_bridge has one as well.

Comment by scandrew on 2016-09-01:
differential_drive package comes with PID controllers. If I succeed installing and making that package work, it should take care of everything by the looks of it.

Comment by Mark Rose on 2016-09-01:
Yes, that's true, but the author of the package told me he found that putting the PID controller on the microcontroller worked better, so I did the same thing. I haven't tried using the PID control in differential_drive. Instead I used a library I wrote.

Comment by Kishore Kumar on 2016-09-11:
@ Mark Rose I don't want to use PID in Arduino, can you please direct me to simple Arduino code to publish motor encoder ticks alone. I ll handle rest of the things in ROS.

Comment by Kishore Kumar on 2016-09-11:
@ Mark Rose I have built a code but ended up in error.

Comment by Mekateng on 2020-02-24:
I want to do same thing but unfortunately ı did not solve my problem yet. If you don't mind, would you please share the arduino and ros code with me? I wrote the arduino code to find the odometry but I couldn't integrate this arduino code with ros code.

Comment by Mark Rose on 2020-02-24:
Again, I recommend looking at ros_arduino_bridge. It includes Arduino code for publishing odometer from encoder ticks that you can use as an example, and you can modify it to use your code instead. It also includes a ROS node that talks to the Arduino over a serial connection. (So it has source code for both sides, as you are asking for.) I recommend Marco Werther's fork, as it has some fixes that aren't in the original code.