ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

odometry message from Arduino

asked 2016-08-04 16:53:58 -0600

stevej_80 gravatar image


I am trying to create and publish odometry data for a differential drive robot from an Arduino Due board with the data coming from wheel encoders and a gyro sensor attached to the board.

my intention is to create and publish the Odom messages from the Arduino Due itself, since it has a fairly powerful Microcontroller. (Is it a good practice?)

I have a few question though to clarify & make sure about a few things for myself. I check out the publishing odometry tutorial and i notice that there is a odom.twist.twist.linear.y = vy field, do I have to hard code this to 0.0 for a differential drive robot?

Is it alright if I just convert the gyro’s readings (which is in Degree Per Second) to Radian/sec and pass it straight as vth to odom.twist.twist.angular.z = vth?

In the Arduino it seems like that i can not use the odom_quat as in the tutorial to convert my heading to quats. Instead should I add odom_trans.transform.rotation.z and odom_trans.transform.rotation.w to the message manually and calculate the value?

At what rate is the best practice to calculate and publish odometry for a Turtlebot class diff drive robot?

if you have any heads up or pointers regarding to what i'm trying to do I would appreciate it.

Thank you.

edit retag flag offensive close merge delete

1 Answer

Sort by » oldest newest most voted

answered 2016-08-04 17:27:18 -0600

Mark Rose gravatar image

updated 2016-08-04 18:46:17 -0600

Yes, you can publish on /odom directly from the Due, and it should work fine. One possibility is to use the rosserial package. I've done this from an Arduino Leonardo. (However, I've dropped rosserial on the smaller Arduinos because of the memory usage of rosserial. You shouldn't have any problems on a Due.)

You should publish the odometry as nav_msgs/Odometry. Normally, you want to publish in the base_link frame, which often has its origin midway between the two wheels. By convention, x is straight ahead, and z is up. Therefore, since we assume there is no side-slip, you'll have the velocities in twist.linear.x and twist.angular.z. The pose will be in pose, including a quaternion for orientation. All other velocity values will be zero.

You should publish odometry at a rate equal to or higher than your planning loop rate. Also take your other sensors into account: you want up-to-date odometry when publishing a point cloud, for example. Depending on your setup, anything from 10-100 Hz might be best. Keep in mind the bandwidth required by rosserial, too. By default it's only 57600 baud, and messages are not tiny.

edit flag offensive delete link more


Another option is to just deal with encoder tick rates on the Arduino and convert between ticks and /cmd_vel and /odom in a node on the host side. The ros_arduino_bridge package is set up this way, for example.

Mark Rose gravatar image Mark Rose  ( 2016-08-04 17:29:11 -0600 )edit

Hi Mark, I am currently using the rosserial package ofc. I didnt get the part where you wrote i should publish odom as geometry_msgs/Twist. Do you happen to have any sample codes of the Arduino project you done? thanks for the reply!

stevej_80 gravatar image stevej_80  ( 2016-08-04 18:11:04 -0600 )edit

I don't have any C++ code that does it. Instead, I usually publish encoder ticks from the Arduino and then convert to a Twist in Python on the host. For example, see this code in the differential_drive package :

Mark Rose gravatar image Mark Rose  ( 2016-08-04 18:41:39 -0600 )edit

Also see this explanation of differential drive kinematics. And I've edited my answer above, which was wrong: you publish nav_msgs/Odometry, of course.

Mark Rose gravatar image Mark Rose  ( 2016-08-04 18:44:00 -0600 )edit

Since the Arduino's loop function (which controls wheels and sensor readings too) loops at a constant low delay, my dt will always be the same amount & messages could overwhelm the link. I think the good practice is to just calc the velocities and send them to the host machine to manage Odom. right?

stevej_80 gravatar image stevej_80  ( 2016-08-04 19:12:15 -0600 )edit

That's the way I've done it, but YMMV. As far as the send rate, you'll need to control the motors only periodically on the Arduino, either using delay() at the bottom of the loop() code, or checking the elapsed time during the loop to see if it's time to control the motors and publish.

Mark Rose gravatar image Mark Rose  ( 2016-08-05 11:28:10 -0600 )edit

Thank you @Mark Rose. I'll wait a little longer to see if anyone else wants to chip in with ideas and then mark your answer as correct.

stevej_80 gravatar image stevej_80  ( 2016-08-08 03:09:07 -0600 )edit

@Mark Rose, another tiny confirmation; Theta must be presented in Radians in all odom calculations, is that correct? for example where it says: delta_x = (vx * cos(th) - vy * sin(th)) * dt "th" should be in rad and "vy = 0" for a differential drive robot...?

stevej_80 gravatar image stevej_80  ( 2016-08-08 11:20:53 -0600 )edit

Question Tools

1 follower


Asked: 2016-08-04 16:53:58 -0600

Seen: 4,111 times

Last updated: Aug 04 '16