Two frames

The robot's forward is not the world's forward. Naming the frame is half the work.

U2.1Kinematics and framesUniversity20 min

Do this lesson in the simulator

Ask where the robot is going and there are two right answers. Forward, says the robot. North, says the room. Both are true, and confusing them is the single commonest bug in mobile robotics.

The two frames

The body frame is fixed to the robot. Its axes are right and forward, whichever way the robot happens to be pointing. Every sensor mounted on the robot speaks this language: flow() gives right and forward, imu() gives the acceleration the body feels, the camera sees what is in front of the camera.

The world frame is fixed to the mat. Its axes are x to the right and y away from you, and they stay put. Zones, targets, walls and other robots live here.

drive(fwd, lat, rot) is a body frame command. position() is a world frame answer. Anything that connects them has to know the heading.

Watch the difference

The robot below starts facing along the world's x axis, so its own forward is the world's x.

from bugbot import *
connect()

print("heading", round(heading()))
forward(60)
for i in range(10):
    bx, by = flow()
    x, y = position()
    print("body", (round(bx), round(by)), "world", (round(x), round(y)))
    wait(0.1)
stop()

Run this in the simulator

The body reads "nothing sideways, plenty forward" the whole way. The world reads "x is climbing, y is not". Same motion, two descriptions.

Conventions, stated once

Every robotics codebase needs these written down somewhere, because there is no universal answer and a wrong guess is silent.

  • Lengths are centimetres.
  • The world's x runs right, y runs away.
  • Heading is degrees, clockwise positive, and 0 means facing along +y.
  • The body's x is right, y is forward.
  • A robot at heading 90 faces along the world's +x.

Clockwise-positive is worth a second look, because most maths textbooks are anticlockwise-positive. This one follows the compass instead, as most vehicles do. Mixing the two gives you a robot that turns the wrong way, which at least is a loud failure.

Naming your variables

The cheapest defence against frame bugs is in the names. vx tells you nothing. vx_body and vx_world tell you everything, and a line that mixes them looks wrong on sight.

dx_world = target_x - x_world          # fine
command_lat = dx_world                 # wrong, and it looks wrong

Task: name the frame

The robot starts facing along the world's x axis. Drive it forward at least 25 cm, then print two numbers: body: the average sideways speed in the robot's own frame while it drove, and world x: how far it actually moved along the world's x axis.

from bugbot import *
connect()

forward(60)

Challenges

  1. Turn the robot to heading 45 and drive forward. Which world axes change, and in what ratio?
  2. Drive sideways and print both frames. Which numbers change places?
  3. Write down the sign of the heading for a robot turning left. Test it.