brian.pilot.Pilot
Pilot class objects
Differential-drive pilot for controlling a robot with left and right wheels.
Supports brake/hold/coast, forward/backward with optional distance,
turn (small pivots), arc (large pivots), and travel (curved path).
Movement methods wait for all controlled motors to become ready first (same timeout as
brian.motors.Motor commands, via brian.motors.set_wait_until_timeout_ms), then wait for
completion by default and return EndReason. timeout_ms semantics match
wait_until_done() (None = wait until done, 0 or negative = return from the wait immediately,
often EndReason.TIMED_OUT if still moving). Unlimited path limits (None / 0 / ±inf on
distance or turn angle) also return immediately unless timeout_ms is set. Movement methods and
wait_until_done() also share return_earlier_for_movement_chaining to return during slowdown
(before full stop), so the next movement can be chained sooner.
Speed and acceleration can be set once and used as defaults in movement commands.
Odometry (distance and angle) is available with optional zeroing.
__init__
def __init__(left_motor: Motor,
right_motor: Motor,
wheelbase_mm: int,
wheel_diameter_mm: Optional[int] = None,
gear_ratio: Optional[float] = None,
helper_left_motor: Optional[Motor] = None,
helper_right_motor: Optional[Motor] = None,
left_motor_reversed: bool = False,
right_motor_reversed: bool = False,
helper_left_motor_reversed: bool = False,
helper_right_motor_reversed: bool = False,
*,
wheel_circumference_mm: Optional[int] = None) -> None
Create a pilot for a differential-drive chassis.
Arguments:
left_motor: Primary left motor.right_motor: Primary right motor.wheelbase_mm: Distance between left and right wheel (centre to centre), in mm.wheel_diameter_mm: Wheel diameter in mm. Circumference is derived as π × diameter before gear ratio is applied. Provide exactly one ofwheel_diameter_mmorwheel_circumference_mm.gear_ratio: Optional gear ratio used by the drivetrain model.helper_left_motor: Optional helper left motor.helper_right_motor: Optional helper right motor.left_motor_reversed: Reverse primary left motor direction.right_motor_reversed: Reverse primary right motor direction.helper_left_motor_reversed: Reverse helper left motor direction.helper_right_motor_reversed: Reverse helper right motor direction.wheel_circumference_mm: Keyword-only. Wheel circumference in mm, used directly before gear ratio is applied. Provide exactly one ofwheel_diameter_mmorwheel_circumference_mm.
Raises:
ValueError: If neither or both ofwheel_diameter_mmandwheel_circumference_mmare provided, or if other numeric or topology arguments are invalid.brian.pilot.PilotAlreadyReservedError: If another active pilot already reserves PilotSync control.brian.pilot.PilotConfigurationError: If pilot creation fails for non-argument reasons.
__del__
Close the pilot: disable PilotSync control. Returns control to motors themselves.
close_pilot
Close the pilot: disable PilotSync control. Returns control to motors themselves.
set_speed
Set the default linear speed used when a movement method is called without the optional speed argument.
Arguments:
speed_mm_per_sec: Default speed in mm/s.
Raises:
brian.pilot.PilotAlreadyClosedError: If the pilot instance is already closed.
get_default_speed
Get the current default linear speed used when movement methods are called without speed.
Raises:
brian.pilot.PilotAlreadyClosedError: If the pilot instance is already closed.
Returns:
Default speed in mm/s.
set_acceleration
Set acceleration so callers do not pass it in every command.
Arguments:
acceleration_mm_per_sec_sq: Acceleration in mm/s².
Raises:
brian.pilot.PilotAlreadyClosedError: If the pilot instance is already closed.brian.pilot.PilotNotReadyError: If a controlled motor is not ready.
get_acceleration
Get the current acceleration used by movement commands.
Until :meth:set_acceleration is called, this is the mean acceleration limit of the motors
managed by this pilot, converted to mm/s² through the wheel circumference and gear ratio.
Raises:
brian.pilot.PilotAlreadyClosedError: If the pilot instance is already closed.
Returns:
Acceleration in mm/s².
brake
Apply passive braking on all registered motors (short the windings).
Raises:
brian.pilot.PilotAlreadyClosedError: If the pilot instance is already closed.brian.pilot.PilotNotReadyError: If a controlled motor is not ready after the readiness wait.
hold
Actively hold all registered motors at their current positions.
Raises:
brian.pilot.PilotAlreadyClosedError: If the pilot instance is already closed.brian.pilot.PilotNotReadyError: If a controlled motor is not ready after the readiness wait.
coast
Let all motors spin freely (float the windings).
Raises:
brian.pilot.PilotAlreadyClosedError: If the pilot instance is already closed.brian.pilot.PilotNotReadyError: If a controlled motor is not ready after the readiness wait.
wait_until_done
def wait_until_done(
timeout_ms: Optional[int] = None,
return_earlier_for_movement_chaining: bool = False) -> EndReason
Block until the current movement reaches the requested PilotSync state or the timeout expires.
Waits on STM32-reported pilotStatus (plan id must match the active travel plan).
Arguments:
timeout_ms: Max wait in milliseconds. IfNone, wait until the condition is met; if0or negative, return immediately.return_earlier_for_movement_chaining: IfFalse(default), wait until the plan has stopped. IfTrue, return once PilotSync enters slowdown, before full stop, so another movement can be started immediately.
Raises:
brian.pilot.PilotAlreadyClosedError: If the pilot instance is already closed.brian.pilot.PilotNotReadyError: If a controlled motor is not ready.
Returns:
A value of brian.motors.EndReason (e.g. FINISHED, TIMED_OUT).
Movement commands (forward, backward, turn, arc, travel) use the same timeout_ms
rules for their internal wait and return the same kind of EndReason value.
is_done
Check whether the last movement has completed.
Raises:
brian.pilot.PilotAlreadyClosedError: If the pilot instance is already closed.
Returns:
True if no movement is in progress, False if still moving.
forward
def forward(distance_mm: Optional[int] = None,
speed: Optional[int] = None,
timeout_ms: Optional[int] = None,
return_earlier_for_movement_chaining: bool = False) -> EndReason
Drive forward and wait up to timeout_ms for the commanded move to finish.
Arguments:
distance_mm: If None, 0, or ±inf, no limit (see class docstring). Negative finite values flip direction by reversing speed; negative speed + negative distance becomes forward.speed: Speed in mm/s. If None, uses default from set_speed(). Negative values reverse travel along the same circle.timeout_ms: Same as :meth:wait_until_done.return_earlier_for_movement_chaining: Same as :meth:wait_until_done.
Raises:
brian.pilot.PilotAlreadyClosedError: If the pilot instance is already closed.brian.pilot.PilotNotReadyError: If a controlled motor is not ready after the readiness wait.
Returns:
EndReason.FINISHED or EndReason.TIMED_OUT (script abort also surfaces as TIMED_OUT if incomplete).
backward
def backward(distance_mm: Optional[int] = None,
speed: Optional[int] = None,
timeout_ms: Optional[int] = None,
return_earlier_for_movement_chaining: bool = False) -> EndReason
Drive backward and wait up to timeout_ms for the commanded move to finish.
Arguments:
distance_mm: If None, 0, or ±inf, no limit (see class docstring). Negative finite values flip direction by reversing speed; negative speed + negative distance becomes backward.speed: Speed in mm/s. If None, uses default from set_speed(). Negative values reverse travel along the same circle.timeout_ms: Same as :meth:wait_until_done.return_earlier_for_movement_chaining: Same as :meth:wait_until_done.
Raises:
brian.pilot.PilotAlreadyClosedError: If the pilot instance is already closed.brian.pilot.PilotNotReadyError: If a controlled motor is not ready after the readiness wait.
Returns:
EndReason value for how the wait ended.
turn
def turn(turn_radius_mm: int,
max_angle_deg: Optional[int] = None,
turn_rate: Optional[int] = None,
timeout_ms: Optional[int] = None,
return_earlier_for_movement_chaining: bool = False) -> EndReason
Turn and wait for completion (or timeout).
Arguments:
turn_radius_mm: Turning radius in mm; 0 means turn on the spot (pivot). Sign combines withturn_rate(same convention as :meth:arc).max_angle_deg: Optional cap in degrees; None, 0, or ±inf means no limit (see class docstring). Negative finite values flip direction by reversingturn_rate; negativeturn_rate+ negativemax_angle_degbecomes a positive turn.turn_rate: Turn rate in degrees per second. Must be non-zero. If None, it is derived from the default speed (:meth:set_speed) andturn_radius_mmthe same way :meth:arcdoes, so a wider radius keeps the same speed along the path; for radii below the pivot radius (wheelbase / 2) that pivot radius is used. Sign combines withturn_radius_mmlike normal multiplication: one negative turns left (CCW), both negative cancel to turn right (CW). With pivot radius 0, sign alone selects direction.timeout_ms: Same as :meth:wait_until_done.return_earlier_for_movement_chaining: Same as :meth:wait_until_done.
Raises:
ValueError: Ifturn_rateis zero, or if it is omitted and the derived rate rounds to zero (default speed of 0, or a radius far too large for that speed).brian.pilot.PilotAlreadyClosedError: If the pilot instance is already closed.brian.pilot.PilotNotReadyError: If a controlled motor is not ready after the readiness wait.
Returns:
EndReason value for how the wait ended.
arc
def arc(radius_mm: int,
max_distance_mm: Optional[int] = None,
speed: Optional[int] = None,
timeout_ms: Optional[int] = None,
return_earlier_for_movement_chaining: bool = False) -> EndReason
Drive along an arc and wait for completion (or timeout).
Arguments:
radius_mm: Turning radius in mm (from turn centre to robot centreline).0means turn around the robot centre,-wheelbase_mm/2means the left wheel is stationary,+wheelbase_mm/2means the right wheel is stationary.- Negative values turn left, positive values turn right.
max_distance_mm: Optional path length in mm; None, 0, or ±inf means no limit (see class docstring). Negative finite values reverse travel along the same circle (equivalent to negating speed).speed: Speed in mm/s. If None, uses default from set_speed(). Negative values reverse travel along the same circle (radius sign still selects left vs right).timeout_ms: Same as :meth:wait_until_done.return_earlier_for_movement_chaining: Same as :meth:wait_until_done.
Raises:
brian.pilot.PilotAlreadyClosedError: If the pilot instance is already closed.brian.pilot.PilotNotReadyError: If a controlled motor is not ready after the readiness wait.
Returns:
EndReason value for how the wait ended.
travel
def travel(turn_rate: float,
max_distance_mm: Optional[int] = None,
speed: Optional[int] = None,
timeout_ms: Optional[int] = None,
return_earlier_for_movement_chaining: bool = False) -> EndReason
Drive along a curved path and wait for completion (or timeout).
turn_rate is the ratio between the two wheel speeds, not an angular rate, so the shape of
the path stays the same at any speed:
0drives straight,0.5stops one wheel,1.0runs the wheels in opposite directions, turning on the spot,- positive values turn right, negative values turn left.
Arguments:
turn_rate: Wheel-speed ratio from -1.0 to 1.0. Values outside that range are clamped.max_distance_mm: Optional path length in mm; None, 0, or ±inf means no limit (see class docstring). Negative finite values reverse travel along the same circle (equivalent to negating speed).speed: Speed in mm/s. If None, uses default from set_speed(). Negative values reverse travel along the same circle (turn_ratestill selects left vs right).timeout_ms: Same as :meth:wait_until_done.return_earlier_for_movement_chaining: Same as :meth:wait_until_done.
Raises:
brian.pilot.PilotAlreadyClosedError: If the pilot instance is already closed.brian.pilot.PilotNotReadyError: If a controlled motor is not ready after the readiness wait.
Returns:
EndReason value for how the wait ended.
is_ready
Check whether every motor controlled by the pilot is ready to be controlled,
without waiting (same readiness criteria as brian.motors.Motor.is_ready()).
When a motor is not connected, this function returns False. When a wrong motor type is connected, this function raises an exception.
Raises:
brian.pilot.PilotAlreadyClosedError: If the pilot instance is already closed.brian.motors.MotorIncompatibleTypeError: If a wrong motor type is connected.
Returns:
True if all controlled motors meet the readiness criteria, False if any is not connected.
wait_until_ready
def wait_until_ready(
timeout_ms: Optional[int] = None,
optimism_level: Optional[MotorWaitOptimismLevel] = None) -> bool
Block until all configured pilot motors are ready or the timeout expires.
Arguments:
timeout_ms: Max wait in milliseconds. IfNone, no per-call wall-clock limit; if0or negative, return/raise immediately without waiting (same asbrian.motors.Motor.wait_until_ready).optimism_level: Readiness strictness (same enum as brian.motors.Motor.wait_until_ready()).
Raises:
brian.pilot.PilotAlreadyClosedError: If the pilot instance is already closed.brian.pilot.PilotNotReadyError: If a controlled motor is not ready when the wait ends.
Returns:
True if all motors are ready.
distance_travelled_mm
Signed integrated robot path distance (odometry), in mm, relative to the last
reset_distance_travelled() call (or pilot start heading angle if never reset).
Raises:
brian.pilot.PilotAlreadyClosedError: If the pilot instance is already closed.
Returns:
Signed distance in mm.
heading_angle_deg
Signed integrated heading change (odometry), in degrees, relative to the last
reset_heading_angle() call (or pilot creation if never reset).
Raises:
brian.pilot.PilotAlreadyClosedError: If the pilot instance is already closed.
Returns:
Signed heading angle in degrees.
reset_distance_travelled
Set current integrated distance travelled to the provided value (in mm).
Raises:
brian.pilot.PilotAlreadyClosedError: If the pilot instance is already closed.