explainer
Differential-drive kinematics: from wheel rates to pose
Convert left and right wheel rates into robot speed, turning rate, and an exact constant-rate pose update. Explore straight travel, arcs, spins, and reverse motion, then check the limits of wheel odometry.
What you will learn
- Convert signed wheel rotation rates into body forward speed and yaw rate.
- Calculate wheel rates for a requested linear and angular velocity.
- Predict straight, circular, spinning, and reverse motion from one model.
- Integrate a constant body velocity without a division-by-zero case at straight motion.
- Explain why an exact model update still leaves physical odometry error.
Before you start
A robot drives its left wheel at 2 radians per second and its right wheel at 4. Where will its center be four seconds later?
Differential-drive kinematics answers that question using wheel size, wheel separation, and the starting pose. The calculation has two parts: convert wheel rotation into body velocity, then integrate that velocity as the heading changes.
Model a robot with two driven wheels
A differential-drive robot steers by controlling two wheels independently. The wheels share an axle line, and each wheel rolls forward or backward along the direction it faces. A caster can support the chassis without adding a steering command.
Use an ideal model with equal wheel radii, a rigid chassis, and a flat floor. Assume the wheels roll without longitudinal slip and do not slide sideways. This lesson predicts geometry from wheel motion; it does not calculate motor torque or acceleration.
The sideways restriction links differential drive to the unicycle model in Modern Robotics. The robot has a planar pose with three coordinates, but its instantaneous body velocity has only two independent controls: forward speed and yaw rate.
Set the axes and measure the geometry
Track the midpoint between the wheel centers. Its pose is (x, y, θ): two world coordinates in meters and a heading in radians. World x points right in the plot, world y points up, and positive θ turns counterclockwise from world x.
The body x axis points forward along the current heading; body y points left. At θ = 0, forward agrees with world x. Review coordinate frames if a velocity that changes direction in the world feels different from a constant forward command.
| Symbol | Meaning | Unit |
|---|---|---|
| r | Radius of each driven wheel | m |
| b | Full distance between left and right wheel centers | m |
| φ̇L, φ̇R | Signed left and right wheel rotation rates | rad/s |
| v | Forward velocity of the axle midpoint in the body frame | m/s |
| ω | Counterclockwise yaw rate | rad/s |
Track width b is the whole axle separation, so each wheel sits b/2 from the midpoint. Wheel radius r converts rotation into rolling distance. The turning radius introduced below is a third quantity with a different job.
Positive wheel rotation means forward rolling for each wheel. A hardware encoder may use the opposite sign on one side, so map its readings into this convention before applying the equations.
Convert wheel rates to body motion
Rolling through one radian advances a wheel by its radius. The left and right forward rim speeds are therefore uL = rφ̇L and uR = rφ̇R.
The midpoint takes the average forward speed. Their difference, divided by the full track width, sets the yaw rate:
v = r(φ̇L + φ̇R) / 2
ω = r(φ̇R − φ̇L) / b
For the sign check, imagine a forward left turn. The right wheel follows the outside of the turn and travels faster, so φ̇R − φ̇L is positive. These are the forward velocity equations derived in Dellaert and Hutchinson's differential-drive motion model.
Rotate the forward velocity into world coordinates:
ẋ = v cos θ
ẏ = v sin θ
θ̇ = ω
The body has zero sideways velocity. Its world y coordinate can still change because the robot's forward direction turns with θ; nonholonomic constraints develops that distinction.
Calculate the wheel rates for a command
A controller often requests v and ω. At the left wheel, rotation subtracts bω/2 from the midpoint's forward speed; at the right wheel, rotation adds bω/2. Divide each result by r to recover wheel rates:
φ̇L = (v − bω/2) / r
φ̇R = (v + bω/2) / r
For v = 0.4 m/s, ω = −0.6 rad/s, r = 0.1 m, and b = 0.5 m, the left wheel needs (0.4 + 0.15)/0.1 = 5.5 rad/s. The right needs (0.4 − 0.15)/0.1 = 2.5 rad/s. The faster left wheel produces the requested clockwise turn.
Check both results against the wheels' speed limits. Independently clipping one wheel changes both v and ω. WPILib's differential-drive kinematics documentation uses the same body-to-wheel relationship with wheel linear speeds; divide by radius when you need angular rates.
Recognize straight motion, arcs, and spins
These examples all use r = 0.1 m and b = 0.5 m. Wheel rates stay constant, and the robot starts facing world x.
| Left rate | Right rate | v | ω | Center motion |
|---|---|---|---|---|
| 3 rad/s | 3 rad/s | 0.3 m/s | 0 rad/s | Straight forward |
| 2 rad/s | 4 rad/s | 0.3 m/s | 0.4 rad/s | Forward left arc |
| −2 rad/s | 2 rad/s | 0 m/s | 0.8 rad/s | Spin in place |
| −3 rad/s | −3 rad/s | −0.3 m/s | 0 rad/s | Straight reverse |
When ω is nonzero, the signed turning radius of the midpoint is R = v/ω. The instantaneous rotation center lies R meters along the robot's body y axis: positive R lies to its left. A spin has R = 0; straight motion has no finite rotation center.
The magnitude |R| describes the center's circle, while r describes each wheel. For the forward arc above, R = 0.3/0.4 = 0.75 m even though each wheel has radius 0.1 m. Unlike a forward-only Dubins vehicle, this ideal differential drive can spin at zero center speed.
Integrate a constant command exactly
Holding v and ω constant does not hold the world velocity constant during a turn. The heading evolves as θ(t) = θ₀ + ωt, so x and y integrate a rotating forward direction.
For nonzero ω, direct integration gives the circular-arc update:
θ₁ = θ₀ + ωt
x₁ = x₀ + (v/ω)(sin θ₁ − sin θ₀)
y₁ = y₀ + (v/ω)(cos θ₀ − cos θ₁)
Near ω = 0, those differences lose numerical precision, and division by zero prevents using the expression for a straight line. A trigonometric identity gives a form that covers the straight limit:
a = ωt/2, sinc(a) = sin(a)/a, sinc(0) = 1
d = vt sinc(a)
x₁ = x₀ + d cos(θ₀ + a)
y₁ = y₀ + d sin(θ₀ + a)
θ₁ = θ₀ + 2a
Here sinc is unnormalized: its argument is in radians, with no extra π. The midpoint angle alone is insufficient; the sinc factor accounts for the arc's displacement. At ω = 0, this reduces continuously to a straight translation of vt along θ₀.
The formula is exact for the ideal model with constant rates; floating-point arithmetic still rounds the calculation. Keep θ unwrapped when you want to count turns. The same update can be expressed through homogeneous transformations and the constant-twist integration used in Modern Robotics' odometry lesson.
Work through a four-second left turn
Start at (0, 0, 0) with r = 0.1 m, b = 0.5 m, φ̇L = 2 rad/s, and φ̇R = 4 rad/s. Hold those rates for four seconds.
- Wheel rim speeds are 0.2 and 0.4 m/s.
- Forward speed is
(0.2 + 0.4)/2 = 0.3 m/s. - Yaw rate is
(0.4 − 0.2)/0.5 = 0.4 rad/s. - The final heading is
0.4 × 4 = 1.6 rad, and R is 0.75 m. - The final center is
x = 0.75 sin(1.6) = 0.749680 mandy = 0.75(1 − cos(1.6)) = 0.771900 m, rounded to six decimals.
The center travels 0.3 × 4 = 1.2 m along its arc. The straight distance between the two endpoint positions is only 1.076034 m. During a full circle, that endpoint distance would return to zero while travel remained positive.
A single forward Euler update using only the starting heading would predict (1.2, 0). It misses the changing direction during these four seconds. The exact constant-rate update follows the whole turn without requiring a smaller integration step.
Change the wheels and inspect the pose
The initial experiment reproduces the calculation above. The amber path traces the axle midpoint, and the final arrow shows heading. Each change recomputes a motion from (0, 0) with the selected initial heading; it does not append to the previous path.
Choose Spin in place and compare the heading with center travel. After four seconds, θ is 3.2 rad while the center stays at (0, 0). Choose Reverse straight to reach x = −1.2 m with heading still zero: reversing changes the signed speed without rotating the body.
Reset the experiment and choose an initial heading of 90°. The final position becomes (−0.771900, 0.749680) m while the speeds and travel stay the same. This rotates the trajectory into a different world direction.
With the default wheel rates, doubling the track width would halve yaw rate while preserving forward speed. Doubling both wheel radii doubles v and ω, so it preserves R while advancing farther around the same circle in the same time. Use the radius control to check that second prediction.
Separate a motion prediction from measured odometry
This lab predicts motion from prescribed wheel rates. Wheel odometry starts from measured encoder increments and estimates pose over successive intervals. With equal radii, an interval's signed center travel is Δs = r(ΔφL + ΔφR)/2, and its heading change is Δθ = r(ΔφR − ΔφL)/b.
Treating those increments as one constant body motion gives d = Δs sinc(Δθ/2) and the same midpoint-angle update. Total encoder increments do not reveal every possible ordering of changing rates within an interval. Use shorter measurement intervals when a single constant motion poorly represents what happened.
An exact integration formula cannot correct wheel slip, an incorrect wheel radius, or a mismeasured track width. Each pose update carries previous error forward. Modern Robotics describes combining odometry with observations from external sensors to constrain that accumulated error.
For a concrete implementation example, WPILib's differential-drive odometry combines wheel distances with a gyro heading and still warns of drift. The wheel odometry lesson works through encoder intervals and shows how calibration error and lost wheel travel affect the estimate. A motion model also needs separate collision checks and actuator limits before it becomes an executable robot plan. If you train a model to correct odometry, compare it against this kinematic baseline and ground-truth poses across the conditions it must handle.
Reproduce the motion in Python
This example uses only Python's standard library. It implements the same constant-rate update, with a short Taylor expansion for sinc near zero. Inputs use meters, seconds, and radians; the wheel geometry must be positive and duration nonnegative.
from math import cos, sin
def forward(left, right, radius=0.1, track=0.5):
return radius * (left + right) / 2, radius * (right - left) / track
def inverse(v, omega, radius=0.1, track=0.5):
return (v - track * omega / 2) / radius, (v + track * omega / 2) / radius
def integrate(pose, v, omega, duration):
x, y, theta = pose
half_turn = omega * duration / 2
if abs(half_turn) < 1e-4:
z = half_turn * half_turn
sinc = 1 - z / 6 + z * z / 120 - z * z * z / 5040
else:
sinc = sin(half_turn) / half_turn
chord = v * duration * sinc
midpoint = theta + half_turn
return (
x + chord * cos(midpoint),
y + chord * sin(midpoint),
theta + 2 * half_turn,
)
for name, left, right in [
("arc", 2, 4),
("straight", 3, 3),
("spin", -2, 2),
("reverse", -3, -3),
]:
v, omega = forward(left, right)
x, y, theta = integrate((0.0, 0.0, 0.0), v, omega, 4)
print(f"{name}: pose=({x:.6f}, {y:.6f}, {theta:.6f})")
left, right = inverse(0.4, -0.6)
print(f"inverse: left={left:.6f}, right={right:.6f} rad/s")
x, y, theta = integrate((0.0, 0.0, 0.0), 0.5, 1e-12, 2)
print(f"tiny turn: x={x:.6f}, y={y:.3e}, theta={theta:.3e}")
Expected output:
arc: pose=(0.749680, 0.771900, 1.600000)
straight: pose=(1.200000, 0.000000, 0.000000)
spin: pose=(0.000000, 0.000000, 3.200000)
reverse: pose=(-1.200000, 0.000000, 0.000000)
inverse: left=5.500000, right=2.500000 rad/s
tiny turn: x=1.000000, y=1.000e-12, theta=2.000e-12
The tiny-turn result keeps its small positive sideways displacement in world coordinates. A rule that replaces every small nonzero ω with zero would erase that motion. The sinc expression gives a continuous result without such a cutoff.
Try it yourself
Exercise 1: request a quarter-circle motion. A robot has r = 0.1 m and b = 0.4 m. Request v = 0.2 m/s and ω = 0.5 rad/s from (0, 0, 0) for π seconds. Calculate both wheel rates, the final pose, and the center's travel distance.
Show the quarter-circle solution
The wheel rates are (0.2 − 0.4 × 0.5/2)/0.1 = 1 rad/s on the left and (0.2 + 0.4 × 0.5/2)/0.1 = 3 rad/s on the right. The heading change is π/2 rad, and the turning radius is 0.2/0.5 = 0.4 m.
The final pose is (0.4, 0.4, π/2). Center travel is 0.2π = 0.628319 m, while the endpoint distance is √(0.4² + 0.4²) = 0.565685 m. Set duration = 3.141592653589793 in the Python example to verify the pose.
Exercise 2: reverse a turn. Run the default arc for four seconds. From that final pose, run both wheel rates with the opposite sign, −2 and −4 rad/s, for four more seconds. Predict the final pose and the total center travel across both intervals; explain why changing only v's sign would give a different result.
Show the reversed-motion solution
Negating both wheel rates gives v = −0.3 m/s and ω = −0.4 rad/s. The second interval retraces the first and returns to (0, 0, 0) within floating-point rounding. Total center travel is 1.2 + 1.2 = 2.4 m, even though the net displacement is zero.
Negating only v while keeping ω positive continues increasing the heading, so it cannot undo the first interval. Check the true reversal with first = integrate((0, 0, 0), 0.3, 0.4, 4) followed by integrate(first, -0.3, -0.4, 4).
Sources and further study
- Dellaert and Hutchinson, Motion Model for the Differential Drive Robot: wheel geometry, forward and inverse velocity equations, and body-to-world velocity conversion.
- Lynch and Park, Modern Robotics, Modeling of Nonholonomic Wheeled Mobile Robots: rolling constraints and the common body-velocity model.
- Lynch and Park, Modern Robotics, Odometry: encoder increments, constant-twist pose integration, and accumulated estimation error.
- WPILib, Differential Drive Kinematics and Differential Drive Odometry: practical wheel-speed and pose-estimation interfaces.
Continue with nonholonomic constraints to test which instantaneous motions rolling wheels allow and how several allowed maneuvers can produce a sideways displacement.