Skip to main content
blog.philz.dev

pybricks

Pybricks is excellent. Through a web-based IDE, that supports both Python and block-based programming (costs extra, compiling the blocks down into Python, uses Google's Blockly), you can program your Lego hubs and motors.

The household winner was controlling the Lego remote-controlled cars (e.g., Off-Road Buggy) with an Xbox controller.

Some notes:

Here's the Xbox-controlled car with a record-replay capability that runs out of memory to give you a sense:

from pybricks.iodevices import XboxController
from pybricks.parameters import Direction, Port, Button
from pybricks.pupdevices import Motor
from pybricks.robotics import Car
from pybricks.tools import wait
from micropython import mem_info

# Set up all devices.
read = Motor(Port.D, Direction.CLOCKWISE)
steer = Motor(Port.B, Direction.CLOCKWISE)
car = Car(steer, read)

controller = XboxController()

memory = []
is_recording = False

# Drive with controller triggers, and steer with left joystick.
# Start recording with A, stop with B, replay with X.

while True:
    if not is_recording and Button.A in controller.buttons.pressed():
        is_recording = True
        memory = []

    if is_recording and Button.B in controller.buttons.pressed():
        is_recording = False

    if Button.X in controller.buttons.pressed():
        for (power, steer, duration) in memory:
            car.drive_power(power)
            car.steer(steer)
            wait(duration)

    power = controller.triggers()[1] - controller.triggers()[0]
    steer = controller.joystick_left()[0]
    car.drive_power(power)
    car.steer(steer)

    if is_recording:
        if len(memory) > 0:
						# Extend previous recording rather than recording something every
						# 10ms, as a memory optimization. Perhaps better would be to pre-allocate
						# a fixed bufffer.
            (previous_power, previous_steer, previous_time) = memory[-1]
            if power == previous_power and steer == previous_steer:
                memory[-1] = (power, steer, 10 + previous_time)
            else:
                memory.append( (power, steer, 10) )
        else:
            memory.append( (power, steer, 10) )

    wait(10)