0
$\begingroup$

Rosanswers logo

Hello,

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.


Originally posted by stevej_80 on ROS Answers with karma: 75 on 2016-08-04

Post score: 3

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

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.


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

This answer was ACCEPTED on the original site

Post score: 1


Original comments

Comment by Mark Rose on 2016-08-04:
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.

Comment by stevej_80 on 2016-08-04:
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!

Comment by Mark Rose on 2016-08-04:
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: https://github.com/jfstepha/differential-drive/blob/master/scripts/diff_tf.py

Comment by Mark Rose on 2016-08-04:
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.

Comment by stevej_80 on 2016-08-04:
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?

Comment by Mark Rose on 2016-08-05:
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.

Comment by stevej_80 on 2016-08-08:
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.

Comment by stevej_80 on 2016-08-08:
@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...?

Comment by Mark Rose on 2016-08-09:
Yes, angles are always in radians. A couple of good things to read are REP 103 - Standard Units of Measure and Coordinate Conventions and REP 105 - Coordinate Frames for Mobile Platforms. And yes, vy will be zero.

Comment by kartikmadhira1 on 2016-12-29:
So basically, I dont need to calculate dt on the Arduino explicitly beacause of the constant frequency of the loop? @Mark Rose and @ stevej_80 please kindly correct me.

$\endgroup$

Your Answer

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