Skip to content

Effector commands and safety

Effector methods update a buffered setpoint. A background communication loop sends the complete command state at a fixed rate through the extension.

robot.thruster("A1").set_duty(30)
robot.servo("A5").angle(90)

The most recent command remains buffered until it is replaced or HELM idles the outputs. HELM automatically idles outputs when a phase callback returns and when run() exits.

Thruster modes

thruster.set_duty(duty)       # intended range: -100 to 100
thruster.set_current(amps)    # closed-loop current target
thruster.set_power(watts)     # converts watts to current using battery voltage

set_power() is feedforward: it divides the requested power by the latest cached battery voltage and sends a current command. It raises RuntimeError if the voltage is missing or at most 0.1 V.

Measured telemetry is read-only:

amps = thruster.current
watts = thruster.power

Servo modes

servo.angle(90)     # intended range: 0 to 180 degrees
servo.micros(1500)  # intended range: 500 to 2500 microseconds

Use angle() for normal programs. micros() is a raw pulse-width escape hatch for hardware that requires it.

Range enforcement

The documented ranges describe intended hardware use. The current Python library does not clamp duty, servo angle, or pulse width to those ranges. It rounds and encodes the value, rejecting only values that cannot fit the signed 13-bit command field.

For current commands:

  • the built-in thruster limit is currently 4.0 A;
  • values above that magnitude produce a Python warning but are still sent;
  • the robot brain is responsible for applying the actual safety clamp;
  • values beyond the command field's representable range raise ValueError.

This distinction is deliberate: Python warns, while the robot remains the final clamp authority. Student code should still clamp normal commands explicitly.

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

robot.thruster("A1").set_duty(clamp(requested_duty, -100, 100))

Safety ownership

  • The robot brain enforces per-effector magnitude limits.
  • The HELM extension and field system own E-Stop.
  • The Python runtime idles outputs when callbacks finish or the match ends.
  • Student code should react safely to stale sensors, lost links, and unexpected status values.

The Python API does not make match-safety decisions on the student's behalf and does not provide an E-Stop command.