Drive Straight with a Gyro: Proportional Steering in SPIKE Prime Python
To make a SPIKE Prime robot drive straight with the gyro, read the hub's yaw angle many times a second and steer against any drift: steering = KP × (target heading − current heading). If the robot turns 3 degrees right, it steers a little left; when it is back on course, the correction fades to zero. That one line is called proportional steering, and below is a complete SPIKE Prime Python program you can copy, plus how to tune it.
Why robots don't drive straight on their own
Two motors set to the same speed almost never turn at exactly the same rate. One wheel has a bit more friction, a tire is slightly squished, or the robot bumps a mission model. Over a meter, a tiny difference becomes a big miss. Using motor degrees alone can't fix this, because both wheels may report the right distance while the robot is pointing the wrong way.
The SPIKE Prime hub has a built-in motion sensor (a gyro) that measures yaw: which way the robot is facing. Instead of hoping the wheels match, the program watches the heading and fixes it continuously.
How proportional steering works
Every 10 milliseconds the robot asks three questions:
Which way am I facing right now? (current heading)
Which way should I be facing? (target heading, usually 0)
How big is the difference? (the error)
Then it multiplies the error by a number called KP and uses the result as the steering value. A big error gives a strong correction; a small error gives a gentle one. That is why it's called proportional: the fix is proportional to the mistake. It's the same idea behind the line follower in our PID control guide, just using a gyro instead of a light sensor.
What you need
A SPIKE Prime hub with the SPIKE App (version 3 Python)
A two-wheel drive base: left motor in port A, right motor in port B
The standard 56 mm SPIKE wheels (circumference about 17.6 cm)
A flat floor and about a meter of space
If your ports or wheels are different, you only need to change the settings at the top of the program.
Step 1: Check which way yaw counts
Different setups can report yaw with opposite signs, so do this 30-second test first. Run the program below, then turn the robot right (clockwise) by hand and watch the console.
from hub import motion_sensor
import runloop
async def main():
motion_sensor.reset_yaw(0)
while True:
print(motion_sensor.tilt_angles()[0])
await runloop.sleep_ms(250)
runloop.run(main())The value is in tenths of a degree, so 900 means 90 degrees. If the number goes down when you turn right, keep YAW_SIGN = -1 in the main program. If it goes up, change it to YAW_SIGN = 1. This way, heading() always gets bigger when the robot turns right, which matches motor_pair steering (positive steering curves right).
Step 2: The gyro straight program
from hub import port, motion_sensor
import motor
import motor_pair
import runloop
# ---- Robot settings (change these to match your robot) ----
LEFT_PORT = port.A # left drive motor
RIGHT_PORT = port.B # right drive motor
WHEEL_CM = 17.6 # wheel circumference in cm (56 mm SPIKE wheel)
KP = 2.0 # steering strength: start at 2, tune 1-4
YAW_SIGN = -1 # set so that turning RIGHT makes heading() go UP
def heading():
# tilt_angles() returns (yaw, pitch, roll) in tenths of a degree
return YAW_SIGN * motion_sensor.tilt_angles()[0] / 10
def clamp(value, low, high):
return max(low, min(high, value))
async def gyro_straight(distance_cm, speed=500, target=0):
"""Drive straight for distance_cm while holding the heading 'target'."""
motor.reset_relative_position(LEFT_PORT, 0)
goal_degrees = distance_cm / WHEEL_CM * 360
while abs(motor.relative_position(LEFT_PORT)) < goal_degrees:
error = target - heading() # how far off course we are
steering = int(clamp(KP * error, -100, 100))
motor_pair.move(motor_pair.PAIR_1, steering, velocity=speed)
await runloop.sleep_ms(10)
motor_pair.stop(motor_pair.PAIR_1)
async def main():
motor_pair.pair(motor_pair.PAIR_1, LEFT_PORT, RIGHT_PORT)
motion_sensor.reset_yaw(0)
await runloop.sleep_ms(200) # let the hub settle
await gyro_straight(60) # 60 cm forward, heading 0
runloop.run(main())We tested this logic in a small simulator before publishing: starting 7 degrees off course with one weaker wheel, the robot steered itself back and held within about 3 degrees for the rest of the run.
How the code works
heading() reads yaw from tilt_angles(), turns tenths of a degree into degrees, and applies YAW_SIGN.
error = target - heading(): if the robot drifted right, heading is positive, the error is negative, and the robot steers left.
clamp(...) keeps steering between -100 and 100, the range motor_pair.move accepts. It must also be a whole number, hence int().
Distance comes from the left motor's degrees. We use abs() because a mirrored motor may count backwards when the robot drives forward.
sleep_ms(10) lets the loop run about 100 times a second without starving the hub.
Tuning KP
Start with KP = 2.
If the robot drifts and corrects slowly, raise KP by 0.5.
If it wiggles side to side (oscillates), lower KP.
Faster speeds usually need a slightly smaller KP.
A tiny leftover error of a degree or two is normal for proportional-only control. Adding an integral term (the I in PID) can remove it later.
Two habits make a big difference: reset the yaw when the robot is still and square at the start, and give the hub a short pause before driving. To drive straight on a new heading after a turn, pass that heading as target, for example gyro_straight(40, target=90).
A note on SPIKE in 2026
LEGO Education retired SPIKE on June 30, 2026, but hubs already in homes and classrooms keep working, and this technique carries over to any robot with a gyro. If you're deciding what to buy next, see our robotics kit guide.
Common questions
Do I need gyro straight for FIRST LEGO League?
It isn't required, but most consistent robot-game runs use some kind of heading correction. Straight driving is usually the first skill teams learn after basic movement.
Why does my robot still curve a little?
Check that yaw was reset while the robot was still, that YAW_SIGN is correct, and that KP isn't too low. Loose wheels or a dragging cable can also cause curves the gyro has to fight.
Is this too advanced for a beginner?
Kids around 10 and up who know basic Python variables and loops can follow it. Younger builders can learn the same idea with word blocks first.
Keep learning with Fusion Robotics Education
Want to go further? Our SPIKE Prime Python course walks through motors, sensors and smarter driving step by step. Browse all online courses (several are free), try All-Access with a 7-day free trial, or ask about Remote 1-on-1 live lessons by texting (619) 786-5731.
In San Diego? Our weekend group sessions in Scripps Ranch are 1.5 hours a week for ages 6–18, with at most 10 kids and every child on their own project. Your first session is free. Text (619) 786-5731 to book it.



Comments