ZERO Notificatons

NO Feedback yet!!

okay

xparo
X.P.A.R.O



Differential Drive Calculator

Convert cmd_vel to wheel speeds and back, see the turning circle, and turn encoder ticks into an odometry update for a differential-drive robot.

Robot geometry

centre to centre of the tyres
Twist linear.x
Twist angular.z, positive turns left
optional limit
optional, for ticks/s
Left wheel—
Right wheel—
Turning radius—to the ICC

Top-down view

How to use the differential drive calculator

  1. Measure the geometry. Enter the wheel diameter and the wheel separation, the distance between the centres of the two tyres' contact patches. The defaults (66 mm wheels, 160 mm apart) are typical of small TurtleBot-style robots.
  2. cmd_vel → wheels. Enter the linear and angular speed from a geometry_msgs/Twist and get each wheel's speed in m/s, rad/s, RPM and encoder ticks per second. Add your motors' top speed to see how the command is scaled when a wheel would exceed it.
  3. Wheels → cmd_vel. Enter measured wheel speeds to get the robot's actual linear and angular velocity, for example to check that a driver obeys its command.
  4. Encoder odometry. Enter the tick counts since the last update and the start pose to get the new pose, the way an odometry node computes it.

The kinematics

A differential-drive robot moves on a circle around its instantaneous centre of rotation (ICC), which lies on the line through both wheel axles. With wheel radius r and wheel separation L:

Inverse (cmd_vel → wheels) v_left = v − ω·L/2 ω_left = v_left / r v_right = v + ω·L/2 ω_right = v_right / r Forward (wheels → cmd_vel) v = (v_right + v_left) / 2 ω = (v_right − v_left) / L turning radius R = v / ω Odometry from ticks d = 2πr · Δticks / ticks_per_rev (each wheel) Δs = (d_right + d_left) / 2 Δθ = (d_right − d_left) / L x += (Δs/Δθ)·(sin(θ+Δθ) − sin θ) y −= (Δs/Δθ)·(cos(θ+Δθ) − cos θ) (x += Δs·cos θ, y += Δs·sin θ when Δθ = 0)

Worked example

Commanding v = 0.2 m/s and ω = 0.5 rad/s on the default robot (r = 33 mm, L = 160 mm) gives v_left = 0.2 − 0.5 × 0.08 = 0.16 m/s and v_right = 0.24 m/s. Dividing by the radius: 4.85 rad/s (46 RPM) and 7.27 rad/s (69 RPM). The turning radius is 0.2 ÷ 0.5 = 0.4 m, to the left. With a 60 RPM limit, the right wheel is too fast, so both commands are scaled by about 0.86 and the robot drives the same 0.4 m circle a little slower.

In the odometry tab, the defaults describe one second in which the left wheel turned 5730 ticks and the right 7003. That is 0.9 m and 1.1 m of travel, so the robot moved 1.0 m along an arc and turned 1.25 rad (71.6°). The arc update puts it at (0.759, 0.548); a simple straight-line update would put it at (1.0, 0), about 60 cm away. Running odometry at a high rate keeps each step small, and the arc update keeps it accurate even when steps are large.

Tips

Frequently asked questions

How do I convert cmd_vel to wheel speeds?

Left wheel speed = (v − ω × L/2) ÷ r and right wheel speed = (v + ω × L/2) ÷ r, in radians per second, where v is linear.x, ω is angular.z, L is the wheel separation and r the wheel radius.

What is wheel separation?

The distance between the centres of the two drive wheels' contact patches, measured across the axle. It is not the outside width of the robot.

Why does my robot turn less than commanded?

Usually because the effective wheel separation is larger than the measured one, especially on skid-steer or wide tyres. Calibrate it with the rotation test in the guides.

How are encoder ticks turned into distance?

Distance per tick = 2π × wheel radius ÷ (encoder counts per revolution × gear ratio). The odometry tab does this and updates the pose.

Guides for this tool

In-depth articles that explain the ideas behind the Differential Drive Calculator, with worked examples.

Differential Drive Calculator has its own project page with the story behind the tool, a gallery and every guide in one place.

Visit the project page →

More free tools

Every tool runs in your browser. Nothing you enter is uploaded.