# Get odometry from wheels encoders Hi all, I have a problem to compute odometry from wheel encoders, I mean, i don't have a real problem, I just don't understand a step.
I get the ticks from the encoders (they are about 2626 ticks for a full wheel rotation) and I perform the odometry calculation in the following way(of course this is in a loop...i paste just the important lines about the odometry calculation)

current_time = ros::Time::now();
double DistancePerCount = (3.14159265 * 0.13) / 2626;
double lengthBetweenTwoWheels = 0.25;

// extract the wheel velocities from the tick signals count
deltaLeft = tick_x - _PreviousLeftEncoderCounts;
deltaRight = tick_y - _PreviousRightEncoderCounts;

omega_left = (deltaLeft * DistancePerCount) / (current_time - last_time).toSec();
omega_right = (deltaRight * DistancePerCount) / (current_time - last_time).toSec();

v_left = omega_left * 0.065; //radius
v_right = omega_right * 0.065;

vx = ((v_right + v_left) / 2)*10;
vy = 0;
vth = ((v_right - v_left)/lengthBetweenTwoWheels)*10;

double dt = (current_time - last_time).toSec();
double delta_x = (vx * cos(th)) * dt;
double delta_y = (vx * sin(th)) * dt;
double delta_th = vth * dt;

x += delta_x;
y += delta_y;
th += delta_th;

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

geometry_msgs::TransformStamped odom_trans;

odom_trans.transform.translation.x = x;
odom_trans.transform.translation.y = y;
odom_trans.transform.translation.z = 0.0;
odom_trans.transform.rotation = odom_quat;

// send the transform

// Odometry message
nav_msgs::Odometry odom;

// set the position
odom.pose.pose.position.x = x;
odom.pose.pose.position.y = y;
odom.pose.pose.position.z = 0.0;
odom.pose.pose.orientation = odom_quat;

// set the velocity
odom.twist.twist.linear.x = vx;
odom.twist.twist.linear.y = vy;
odom.twist.twist.angular.z = vth;

// publish the message
odom_pub.publish(odom);
_PreviousLeftEncoderCounts = tick_x;
_PreviousRightEncoderCounts = tick_y;

last_time = current_time;


The thing that I don't understand is why i have to multiply vx and vth for 10 (it is a value that i set randomly and seems to work) to make the odometry consistent with the movements of the robot (if i dont multply, the odometry will change very slowly compared to what the robot does in terms of meters done).
Maybe I'm doing some errors calculating the velocities.
An help would be very very appreciated, thank you.

edit retag close merge delete

My i please know the source from where i can implement the same? I am also trying to retrieve the encoder values but not able to find anything useful so far. Regards

Can u please share the whole code for encoders plzz. I am really stuck and can't seem to find any solution ...

Could I ask where you are getting the equations for your v and theta?

This topic is old, there's no need to perform that, the formula was wrong cause I had to fix some hardware issue related to the IMU and I completely changed the code introducing a PID control for the velocities commands to the robot which now gives me smooth values and a quite perfect odometry (of course with a little slippage whose value can be seen only after a long time). Just remove the *10 and be sure to have perfect values from the IMU.

Sort by » oldest newest most voted

omega_left and omega-right is the wheel velocity components already. You do not need to do anything with radius in your v_left and v_right. That is where the error is.

NOTE: Calculations are fine for a simulation, but in real life you want to actually measure the encoder response to real movement. Your calculations will not account for slippage and slippage could be significant depending on wheels, robot weighting and surface.

Spin the robot around 10 times to the right and see how many counts on each wheel, then to the left, then 5 meters straight forward, then 5 meters straight back. And watch the path - if you send it straight forward does it really go straight? You may need different multipliers for each wheel, or for different directions.

more

Factor 10 feels too much for slippage, but I don't see anything wrong with the code either.

Agreed that slippage can't account for 10x. Wasn't meaning to suggest it, just pointing out that for actual robots, you need to measure. The 10x comes from the error I pointed out in his calculation (the error in the calcs actually is more like 15x)

Hi billy,

Do you have an example taking into account the slippage condition?

Thank you.

The term slippage is used to capture the idea that motion based on wheels is going to be inaccurate. If this slippage was predictable you could account for it in your motion calculations. So I'll say there isn't a way to do it in code. - continued next comment

Slippage however can be mitigated through the use of additional sensors that provide additional position/movement data. In ROS Navigation stack, Laser scans are used in the AMCL node to generate a correction to account for slippage and other errors. That correction is the map-to-odom transform.

Another sensor that can be used to mitigate slippage is an IMU which can help with rotational errors. Of course there are more such as GPS, cameras, ultrasonic, bumpers that can all be used to make corrections for slippage. Does that help?

Thank you! I was confused because I thought that it has a specific solution. In my case I will use odometry and IMU data to obtain an estimated position and fuse them through robot_localization module to get an odometry/filtered output.

Instead of finding omega_left and omega_right to calculate v_left and v_right, You can calculate v_left and v_right from deltaLeft.

        double DistancePerCount = (2 * 3.14159265 * 0.065) / 2626; // (2*PI*r)/ppr
double lengthBetweenTwoWheels = 0.25;

deltaLeft = tick_x - _PreviousLeftEncoderCounts;
deltaRight = tick_y - _PreviousRightEncoderCounts;

v_left = (deltaLeft * DistancePerCount) / (current_time - last_time).toSec();
v_right = (deltaRight * DistancePerCount) / (current_time - last_time).toSec();
`
more

This is really old.
Thanks a lot about the answers, but i fixed it more than an year ago and now my robot can move autonomously without problems.

more

1

I had to fix some hardware issue related to the IMU and I completely changed the code introducing a PID control for the velocities commands to the robot which now gives me smooth values and a quite perfect odometry (of course with a little slippage whose value can be seen only after a long time)

Do you mind sharing your code? I'm having some bug in my code.

hello sir ! how you accomplish wheel odometry so successfully please share your method and code as for guide line for my project and recommend some authentic source for wheel odometry and visual odometry . Thanks in advance

Do you have the arduino encoder code you use next to this code for a real application? If yes, could you please share it? @huang27c@dottant