Skip to content

Get started

This guide creates a complete HELM program with autonomous and driver-controlled behavior.

What you need

  • Python 3.10 or newer.
  • The HELM extension running in the editor.
  • A student Python file selected in the extension.
  • A Controller connected through the extension when using real hardware.

The extension launches the selected script with the HELM library and local link already configured. There is no need to copy the API into your project or open the Controller's serial port from Python.

1. Import the hardware types

from helm import IMU, Robot, Servo, Thruster

Robot is the main program object. IMU, Thruster, and Servo are type tokens used to describe the hardware connected to each port.

2. Declare the robot

robot = Robot()
robot.configure(
    sensors={"S2": IMU},
    effectors={
        "A1": Thruster,
        "A2": Thruster,
        "A5": Servo,
    },
    pid={
        "A1": (0.8, 0.1, 0.0),
        "A2": (0.8, 0.1, 0.0),
    },
)

Sensor ports begin with S; effector ports begin with A. Configuration is sent through the extension and checked against the robot's response before the program can arm.

3. Write the callbacks

initialize runs once after arming. autonomous and driver run when the matching phase begins.

def initialize(robot):
    robot.servo("A5").angle(0)


def autonomous(robot):
    while robot.running:
        reading = robot.imu.read()

        if reading.ok and reading.heading >= 90:
            robot.thruster("A1").set_duty(0)
            robot.thruster("A2").set_duty(0)
        else:
            robot.thruster("A1").set_duty(30)
            robot.thruster("A2").set_duty(-30)


def driver(robot):
    previous_a = False

    while robot.running:
        forward = robot.controller.left_stick.y
        turn = robot.controller.right_stick.x

        left = clamp(forward + turn, -100, 100)
        right = clamp(forward - turn, -100, 100)

        robot.thruster("A1").set_duty(left)
        robot.thruster("A2").set_duty(right)

        a_is_down = robot.controller.button("A").is_down
        if a_is_down and not previous_a:
            robot.servo("A5").angle(90)
        previous_a = a_is_down


def clamp(value, low, high):
    return max(low, min(high, value))

Always check a sensor reading's ok field before using it for robot behavior. Buttons report their current level only, so the example compares the current and previous values to detect a new press.

4. Run the match

robot.run(
    initialize=initialize,
    autonomous=autonomous,
    driver=driver,
)

run() blocks while the session is active. It arms the robot, dispatches each callback as phases change, idles outputs when a callback returns, and disarms when the session ends.

Complete program

from helm import IMU, Robot, Servo, Thruster

robot = Robot()
robot.configure(
    sensors={"S2": IMU},
    effectors={"A1": Thruster, "A2": Thruster, "A5": Servo},
    pid={"A1": (0.8, 0.1, 0.0), "A2": (0.8, 0.1, 0.0)},
)


def clamp(value, low, high):
    return max(low, min(high, value))


def initialize(robot):
    robot.servo("A5").angle(0)


def autonomous(robot):
    while robot.running:
        reading = robot.imu.read()
        if reading.ok and reading.heading >= 90:
            robot.thruster("A1").set_duty(0)
            robot.thruster("A2").set_duty(0)
        else:
            robot.thruster("A1").set_duty(30)
            robot.thruster("A2").set_duty(-30)


def driver(robot):
    previous_a = False
    while robot.running:
        forward = robot.controller.left_stick.y
        turn = robot.controller.right_stick.x
        robot.thruster("A1").set_duty(clamp(forward + turn, -100, 100))
        robot.thruster("A2").set_duty(clamp(forward - turn, -100, 100))

        a_is_down = robot.controller.button("A").is_down
        if a_is_down and not previous_a:
            robot.servo("A5").angle(90)
        previous_a = a_is_down


robot.run(
    initialize=initialize,
    autonomous=autonomous,
    driver=driver,
)

Next, read Hardware configuration and Match lifecycle for the rules behind this program.