Learn Robotics
Module: Move Carefully

Velocity Commands

Learn how to command robot motion using linear and angular velocity, and understand the kinematics of differential drive and Ackermann steering.

8 min read

Velocity Commands

You've learned how to control individual motors. But when you want your robot to move as a whole — drive forward, turn, or follow a curved path — you need a higher-level abstraction.

Enter velocity commands: a way to specify the robot's overall motion using just two numbers:

  • Linear velocity (how fast to move forward/backward)
  • Angular velocity (how fast to turn)

This lesson covers how these commands work, how they translate to individual wheel speeds, and the two most common robot drive systems.

The Twist Message

In robotics, velocity commands are typically sent as a Twist message. It has six fields:

Twist:
  linear:
    x: 0.5    # forward/backward speed (m/s)
    y: 0.0    # left/right strafe (m/s) — usually 0 for wheeled robots
    z: 0.0    # up/down (m/s) — usually 0 for ground robots
  angular:
    x: 0.0    # roll rate (rad/s) — usually 0
    y: 0.0    # pitch rate (rad/s) — usually 0
    z: 0.3    # yaw rate (rad/s) — turning left/right

For most ground robots, only two fields matter:

  • linear.x — forward (+) or backward (−) speed
  • angular.z — counterclockwise (+) or clockwise (−) turn rate

This is published to a topic called /cmd_vel (command velocity), and the motor driver subscribes to it and converts the Twist into individual wheel commands.

send_velocity_command.py

The beauty of this abstraction is that you don't need to know how many wheels the robot has or how they're arranged. The motor driver handles the translation.

Differential Drive: Two Wheels

The simplest mobile robot has two driven wheels side by side (like a Roomba or a TurtleBot). This is called differential drive.

How It Works

  • Both wheels forward at equal speed → Robot drives straight
  • Left wheel faster than right → Robot turns right
  • Right wheel faster than left → Robot turns left
  • Wheels spinning opposite directions → Robot spins in place

The Math: Twist to Wheel Speeds

Given a Twist command with linear.x = v and angular.z = ω (omega), the individual wheel speeds are:

v_left = v - (ω × L / 2)
v_right = v + (ω × L / 2)

where:
  v = forward speed (m/s)
  ω = turn rate (rad/s)
  L = wheelbase (distance between wheels, in meters)

Let's say:

  • Wheelbase L = 0.3 m (30 cm between wheels)
  • Command: v = 0.5 m/s, ω = 0.2 rad/s

Then:

v_left = 0.5 - (0.2 × 0.3 / 2) = 0.5 - 0.03 = 0.47 m/s
v_right = 0.5 + (0.2 × 0.3 / 2) = 0.5 + 0.03 = 0.53 m/s

The right wheel spins slightly faster, so the robot curves to the left.

differential_drive.py

Inverse Kinematics: Wheel Speeds to Twist

You can also go the other way — if you measure the wheel speeds (from encoders), you can calculate the robot's actual velocity:

v = (v_left + v_right) / 2
ω = (v_right - v_left) / L

This is called forward kinematics in robotics, and it's useful for odometry (estimating the robot's position based on wheel motion).

Warning

Differential drive has one major limitation: it cannot move sideways. If you need to strafe (move left/right without turning), you need omnidirectional wheels (like mecanum or omni wheels) or a different drive configuration.

Ackermann Steering: Car-Like Robots

If your robot steers like a car — with a front steering axle and a rear driving axle — you're using Ackermann steering.

How It Works

The front wheels turn to a steering angle δ (delta), and the rear wheels drive the robot forward. The robot follows a curved path around a turning radius R.

The Math: Twist to Steering Angle

Given a Twist command with linear.x = v and angular.z = ω, the steering angle is:

δ = atan(ω × L / v)

where:
  ω = turn rate (rad/s)
  v = forward speed (m/s)
  L = wheelbase (distance from front axle to rear axle)

If v = 0, the robot can't turn (you need forward motion to follow a curve). To turn in place, you'd need a differential drive system.

ackermann_drive.py

Why "Ackermann"?

The term comes from Ackermann geometry, which ensures that all wheels follow circular arcs with a common center. This prevents wheel scrubbing (dragging sideways) during turns.

In a perfect Ackermann system, the inside wheel turns at a sharper angle than the outside wheel. Real cars use a linkage system to achieve this automatically.

Comparing Drive Systems

Drive TypeWheelsCan turn in place?Can strafe?Examples
Differential2 driven, 0-2 castersYesNoRoomba, TurtleBot, warehouse robots
Ackermann2 driven (rear), 2 steered (front)NoNoRC cars, autonomous vehicles
Mecanum4 omni wheelsYesYesCompetition robots, forklifts
Omni3+ omni wheelsYesYesHolonomic research robots

For most beginner robots, differential drive is the simplest and most versatile.

What's Next?

You now know how to command robot motion at a high level using Twist messages and how those commands translate to wheel speeds. But there's a gap between theory and practice: tuning.

In the next lesson, we'll tackle the art of tuning PID controllers in real systems — how to adjust the gains, what to look for when things go wrong, and practical methods like Ziegler-Nichols.

Got questions? Join the community

Discuss this lesson, get help, and connect with other learners on Discord.

Join Discord

Discussion

Sign in to join the discussion.