explainer
Omnidirectional drives: move sideways with three omniwheels
Derive the wheel speeds for a three-wheel Kiwi drive. Command forward, sideways, and turning motion, preserve direction when motors saturate, and integrate the resulting world path.
What you will learn
- Derive each wheel speed from its mount position and driven direction.
- Recover forward, lateral, and yaw velocity from three wheel rates.
- Distinguish this Kiwi layout from a four-wheel mecanum drive.
- Scale wheel commands together when a motor reaches its speed limit.
- Convert constant body motion into a world-frame path.
Before you start
A robot faces a shelf but sits 30 centimeters too far to the right. An omnidirectional base can shift left while keeping its heading. The wheel commands must account for every wheel's mounting geometry.
This lesson derives a three-wheel Kiwi drive from its geometry. You can check a sideways command by hand, combine translation with rotation, and see what happens when a wheel reaches its speed limit.
Move sideways while keeping the same heading
Use a body frame with x_b forward, y_b left, and positive yaw counterclockwise. The requested body motion is (v_x, v_y, ω): two linear velocities in meters per second and one angular velocity in radians per second. This three-component velocity is a planar body twist.
An ideal differential-drive robot has zero sideways velocity at its axle midpoint. It can reach a position to the side by turning and driving. The omniwheel arrangement here can instead command v_y directly, including while v_x and ω are zero.
That ability concerns instantaneous motion. It does not mean every speed is possible. Wheel limits still bound the available combinations.
Specify the wheel layout first
Place three identical omniwheels at angles φ₁ = 0°, φ₂ = 120°, φ₃ = 240° around the body center. Their mount radius is a; each wheel's rolling radius is r. These are different lengths.
p_i = a (cos φ_i, sin φ_i)
t_i = (−sin φ_i, cos φ_i)
Each wheel drives along the counterclockwise tangent t_i. Its passive rollers allow motion in the radial direction. Positive wheel rate q_i means motion along the chosen tangent; motor wiring must be mapped to this convention.
An omniwheel's free rolling direction is perpendicular to its driven direction. A typical mecanum wheel uses angled rollers, often 45°, and needs a different velocity equation. Modern Robotics, Section 13.2 derives the general wheel model.
Do not reuse the following three-wheel matrix for a four-wheel mecanum base. For example, WPILib's mecanum kinematics takes four wheel locations and returns four wheel speeds. Its geometry and wheel ordering are part of that interface.
Project the velocity at one wheel
The body center translates, and yaw adds a velocity at each wheel mount. For a wheel at (p_x, p_y), rigid-body motion gives:
u_i = (v_x − ω p_y, v_y + ω p_x)
r q_i = t_i · u_i
q_i = (−sin φ_i v_x + cos φ_i v_y + aω) / r
The dot product selects the velocity along the driven tangent. The rollers accommodate the remaining radial component. Assuming no slip in the driven direction makes that tangent velocity equal to r q_i.
Every wheel gets the same aω contribution because its positive tangent points along counterclockwise rotation. A pure positive yaw command therefore gives three positive wheel rates in this convention.
Assemble the three wheel equations
Insert the three mount angles:
q₁ = (v_y + aω) / r
q₂ = (−√3 v_x/2 − v_y/2 + aω) / r
q₃ = (+√3 v_x/2 − v_y/2 + aω) / r
These equations form a linear map q = H v, where v = (v_x, v_y, ω). Its rows are [0, 1, a], [−√3/2, −1/2, a], and [√3/2, −1/2, a], each divided by r.
For this chosen layout, expanding the determinant gives det(H) = 3√3 a / (2r³). It is nonzero for positive a and r, so H has rank three. The three motor rates can specify all three planar velocity components under this ideal model.
Changing the wheel angles, tangent directions, or roller geometry changes H. Three motors alone do not guarantee the same rank or equations.
Recover body motion from wheel rates
Subtract the second wheel equation from the third to isolate v_x. Combine twice the first equation minus the other two to isolate v_y. Add all three to isolate yaw:
v_x = r (q₃ − q₂) / √3
v_y = r (2q₁ − q₂ − q₃) / 3
ω = r (q₁ + q₂ + q₃) / (3a)
Equivalently, symmetry gives v_x = −(2r/3) Σ sin φ_i q_i and v_y = (2r/3) Σ cos φ_i q_i. The expanded equations above make the signs easier to check.
The lab applies this inverse to its limited wheel rates. With measured encoder rates, the same kinematic inverse could provide an estimated body twist. Wheel odometry explains why measurements, calibration, and slip still affect the resulting pose estimate.
Calculate a sideways command
Use r = 0.1 m and a = 0.3 m. Ask for (v_x, v_y, ω) = (0, 0.3, 0):
q₁ = 0.3 / 0.1 = 3 rad/s
q₂ = −0.15 / 0.1 = −1.5 rad/s
q₃ = −0.15 / 0.1 = −1.5 rad/s
The inverse confirms the command. The difference q₃ − q₂ is zero, so v_x = 0. The sum of all rates is zero, so ω = 0. The lateral equation gives 0.1 × (6 + 1.5 + 1.5) / 3 = 0.3 m/s.
Starting at world pose (0, 0, 0), four seconds of this motion ends at (0, 1.2, 0). The robot moves left while continuing to face the positive world x direction.
Try forward, sideways, and turning motion
The initial view reproduces that sideways calculation. Every preset starts at the same zero pose and runs a constant applied body twist for four seconds. Changing a control recomputes the whole experiment; reset restores Sideways and the original geometry.
The wheel diagram shows the mount layout, signed drive arrows, and free radial directions. Wheel drawings are schematic. Arrow length shows the applied rate as a fraction of the wheel limit. A stopped drive motor can still accompany radial motion through its rollers.
The world plot compares the requested and applied center paths on equal x and y scales. A heading arrow shows where the body faces, which can differ from its direction of travel. Overlapping routes appear as one solid line.
Choose Combined motion for (0.3, 0.2, 0.5). The rates are approximately (3.500000, −2.098076, 3.098076) rad/s. None exceeds the default 6 rad/s limit. After four seconds, the final pose is (−0.020880, 1.213407, 2.000000). Constant body velocities curve in the world as the heading changes.
Respect the wheel speed limits
Let Q be the common maximum absolute wheel rate. Each wheel must satisfy |q_i| ≤ Q. The collection of wheel limits bounds the body twist; Modern Robotics, Section 13.2, Part 2 develops this feasible velocity region.
The lab uses a single scaling factor:
α = min(1, Q / max_i |q_i|)
q_applied = α q_requested
v_applied = α v_requested
For a zero request, define α = 1. Linearity of H and its inverse gives the last equality. Scaling preserves the ratios of the requested velocity components. Clipping individual wheel rates generally changes those ratios and therefore changes the intended motion.
Choose Limited wheel speeds. The requested twist is (0.6, 0.4, 1), producing wheel rates approximately (7, −4.196152, 6.196152). With Q = 4 rad/s, α = 4/7 ≈ 0.571429. The applied twist becomes (0.342857, 0.228571, 0.571429).
The robot follows the same geometric motion more slowly. At four seconds, it has reached the requested motion's pose at 16/7 seconds: approximately (−0.209134, 1.295392, 2.285714). It would need seven seconds to reach the originally requested four-second pose under these constant commands.
Uniform scaling is one command policy. A controller that prioritizes yaw or translation may choose a different feasible twist. This example makes its policy explicit so the change is predictable.
Integrate motion in the world frame
The coordinate-frame rotation converts body velocities to world velocities:
ẋ = v_x cos θ − v_y sin θ
ẏ = v_x sin θ + v_y cos θ
θ̇ = ω
For constant applied body motion over duration T, define h = ωT/2 and sinc(h) = sin(h)/h, with sinc(0) = 1. Integrating the sine and cosine terms gives:
Δx = T sinc(h) [v_x cos(θ + h) − v_y sin(θ + h)]
Δy = T sinc(h) [v_x sin(θ + h) + v_y cos(θ + h)]
θ′ = θ + ωT
This handles straight translation at zero yaw and keeps heading unwrapped. A full turn reads 2π even though its final orientation matches zero. Center travel is T√(v_x² + v_y²); it can exceed the straight distance between endpoints.
The experiment assumes ideal rolling, free rollers, accurate geometry, and immediate wheel-rate tracking. It models neither acceleration nor forces, traction loss, floor unevenness, or motor dynamics. The plot omits obstacles and swept-footprint checks. A physical planner and controller must account for those effects.
Reproduce the calculations in Python
This Python 3 example uses only the standard library. It implements this exact three-wheel layout, applies the shared wheel limit, and integrates the sideways and limited-motion examples.
from math import cos, sin, sqrt
def run(vx, vy, yaw, limit, radius=0.1, mount=0.3, duration=4):
rates = [(vy + mount * yaw) / radius,
(-sqrt(3) * vx / 2 - vy / 2 + mount * yaw) / radius,
(sqrt(3) * vx / 2 - vy / 2 + mount * yaw) / radius]
peak = max(abs(q) for q in rates)
scale = min(1, limit / peak) if peak else 1
q1, q2, q3 = [q * scale for q in rates]
ax = radius * (q3 - q2) / sqrt(3)
ay = radius * (2 * q1 - q2 - q3) / 3
aw = radius * (q1 + q2 + q3) / (3 * mount)
half = aw * duration / 2
sinc = 1 - half**2 / 6 + half**4 / 120 if abs(half) < 1e-4 else sin(half) / half
x = duration * sinc * (ax * cos(half) - ay * sin(half))
y = duration * sinc * (ax * sin(half) + ay * cos(half))
return rates, scale, (ax, ay, aw), (x, y, aw * duration)
def numbers(values):
return ", ".join(f"{0.0 if abs(v) < 1e-10 else v:.6f}" for v in values)
for name, command in [("Sideways", (0, 0.3, 0, 6)),
("Limited", (0.6, 0.4, 1, 4))]:
rates, scale, applied, pose = run(*command)
print(f"{name} requested wheels (rad/s): {numbers(rates)}")
print(f"{name} scale: {scale:.6f}; applied twist: {numbers(applied)}")
print(f"{name} final pose (m, m, rad): {numbers(pose)}")
Expected output:
Sideways requested wheels (rad/s): 3.000000, -1.500000, -1.500000
Sideways scale: 1.000000; applied twist: 0.000000, 0.300000, 0.000000
Sideways final pose (m, m, rad): 0.000000, 1.200000, 0.000000
Limited requested wheels (rad/s): 7.000000, -4.196152, 6.196152
Limited scale: 0.571429; applied twist: 0.342857, 0.228571, 0.571429
Limited final pose (m, m, rad): -0.209134, 1.295392, 2.285714
The first two applied-twist components use m/s; the third uses rad/s. Change the wheel radius and watch the requested rates. A larger rolling radius needs fewer wheel revolutions for the same driven ground speed.
Try it yourself
Exercise 1. Drive forward with one motor stopped. Use r = 0.1 m and a = 0.3 m. Request (0.3, 0, 0). Find all three wheel rates. Why can wheel 1 have zero motor speed while its mount moves?
Check the forward calculation
The rates are (0, −1.5√3, +1.5√3), approximately (0, −2.598076, 2.598076) rad/s. Their sum is zero, so yaw is zero. The inverse gives v_x = 0.3 m/s and v_y = 0.
Wheel 1's driven direction is body y. Its mount travels in body x, which is its free radial direction. The passive rollers accommodate that motion. Choose Forward in the lab: after four seconds, the center is at (1.2, 0) with heading zero.
Exercise 2. Limit the sideways command. Reset to Sideways, then set the wheel rate limit to 2 rad/s. What are the scaling factor, applied wheel rates, lateral velocity, and four-second endpoint?
Check the shared scaling factor
The requested peak is 3 rad/s, so α = 2/3. Multiplying (3, −1.5, −1.5) by that factor gives (2, −1, −1) rad/s. The applied twist is (0, 0.2, 0).
The robot reaches (0, 0.8, 0) after four seconds. It needs six seconds to reach the original 1.2 m lateral displacement. Its heading stays unchanged throughout.
Sources and further study
- Kevin M. Lynch and Frank C. Park, Modern Robotics, Section 13.2, Part 1, for omniwheel and mecanum wheel constraints and the chassis-to-wheel velocity map.
- Modern Robotics, Section 13.2, Part 2, for body-velocity limits induced by bounded wheel rates.
- WPILib: Mecanum Drive Kinematics, for a practical four-wheel model with explicit wheel locations and velocity conventions.
Continue with differential-drive kinematics to compare the velocity constraints. The instantaneous center of rotation connects combined translation and yaw to a turning center. Skid steering explains a different mechanism for lateral motion at wheel contacts.