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

Best way to define the odometry of the robot without sensors

asked 2014-09-01 14:06:02 -0500

Andromeda gravatar image

updated 2014-09-01 14:11:08 -0500

Recently I put another question about odometry (you see it here). Even if the question was answered with courtesy by aHendrix I ve geting more confused about the odometry of a robot. Let's start with an easy robot created just for fun and for simulation porpouses. No data are collected by scanner, laser, GPS or whatever... So: in absence of odometry data I must change the variable (line 12-18 of the tutorial) with other changing variables to "simulate" the encoder/decoder of my imaginary robot. In my code I used to integrate the geometry_msgs/Twist information of the /cmd_vel (generated automatically by move_base)topic over time to see the robot moving in Rviz. Here my code:

void updateVel( const geometry_msgs::TwistPtr& msg ) {

vel_x = msg->linear.x;
vel_y = msg->linear.y;
vel_z = msg->linear.z;

rot_x = msg->angular.x;
rot_y = msg->angular.y;
rot_z = msg->angular.z;

and here the broadcast of the odometry informations and transformations (running in a loop)

    double position_x = vel_x;
    double position_y = vel_y;
    double position_z = vel_z;

   while( ros::ok() ) {

    position_x = vel_x;
    position_y = vel_y;
    position_z = vel_z;

    geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromYaw( rot_z );

    odom_trans.header.stamp = current_time;
    odom_trans.transform.translation.x = position_x;
    odom_trans.transform.translation.y = position_y;
    odom_trans.transform.translation.z = position_z;
    odom_trans.transform.rotation = odom_quat;

    /* broadcast the transform */
    broadcaster.sendTransform( odom_trans );

    /* broadcast the odom over ROS */
    odom.header.stamp = current_time;
    odom.header.frame_id = "odom";
    odom.pose.pose.position.x = position_x;
    odom.pose.pose.position.y = position_y;
    odom.pose.pose.position.z = position_z;
    odom.pose.pose.orientation = odom_quat;

    odom.child_frame_id = "base_link";
    odom.twist.twist.linear.x = vel_x;
    odom.twist.twist.linear.y = vel_y;
    odom.twist.twist.linear.z = vel_z;
    odom.twist.twist.angular.x = rot_x;
    odom.twist.twist.angular.y = rot_y;
    odom.twist.twist.angular.z = rot_z;

    odom_pub.publish( odom );


please note the


in the following code :

/* update position */
position_x += vel_x;
position_y += vel_y;
position_z += vel_z;

for a rude integration over time.

Is this the right way to get odometry information when no sensor or other instruments are available to read the position position of the robot? If not, how to extrapolate and convert the /cmd_vel information to geenrate the right movement of the robot? Many thanks in advance

edit retag flag offensive close merge delete


You've got the right idea. Integrating the velocity command is the correct way to simulate motion over time and produce odometry messages. The math for the integration neglects the orientation of the robot.

ahendrix gravatar image ahendrix  ( 2014-09-01 17:31:00 -0500 )edit

1 Answer

Sort by ยป oldest newest most voted

answered 2014-09-01 20:45:21 -0500

Quoting @ahendrix's comment: "You've got the right idea. Integrating the velocity command is the correct way to simulate motion over time and produce odometry messages." Please, note that I have emphasised the word time.

To properly integrate your fake odometry you need to keep track of time. I'll try to explain clearly as possible. In your code, you store the velocities that you receive on the /cmd_vel topic (which are in meters per second for linear velocities and radians per second for angular velocities) and then add them to your position variables.

Now, lets consider a simplified example case for a robot that only moves along the x axis : Imagine that you start your node and you receive a value of vel_x = 3 (this means that the robot should travel at 3 meters per second on the x direction). For every iteration of your main loop you will be adding a value of 3 to the variable pos_x. So, here you are assuming that the robot moved 3 meters since the last time that you updated pos_x. Which would be true if the main loop took exactly one second to execute. Do you see where I am going?

Usually your main loop would take a very short time to execute, lets say for example 0.01 seconds. So, having a robot traveling at 3 m/s... how many meters will it move in 0.01 seconds? Easy! 3 m/s * 0.01s = 0.03m!! Therefore, in this example, we would have to add 0.03 to pos_x to have the proper odometry value.

Also, as @ahendrix pointed out, you are forgetting to deal with the rotation in your code (which requires a bit of math, but it is really simple). Here you can find some example code of how to calculate properly a fake odometry, mix that with your code and you will be calculating a fake odometry like a pro!

edit flag offensive delete link more


Great answer.

Thomas D gravatar image Thomas D  ( 2014-09-01 20:54:38 -0500 )edit

Ok! I got it! Thanks for the reply!

UPDATE: it are right, I didn't integrate over time. Bye!!!!

Andromeda gravatar image Andromeda  ( 2014-09-02 14:03:33 -0500 )edit

Glad I could help. Best regards.

Martin Peris gravatar image Martin Peris  ( 2014-09-02 19:28:12 -0500 )edit

Question Tools



Asked: 2014-09-01 14:06:02 -0500

Seen: 1,549 times

Last updated: Sep 01 '14