robot.heading_reference

Classes

TurnDirection

Physical direction a heading turn may be forced to take.

HeadingReferenceService

Stores an absolute IMU heading reference and computes turns relative to it.

Module Contents

class robot.heading_reference.TurnDirection

Bases: str, enum.Enum

Physical direction a heading turn may be forced to take.

Subclasses str so existing call sites that pass the bare strings "left" / "right" keep working (TurnDirection.LEFT == "left") while new code gets a real, self-validating type. Coerce any user input via coerce(), which raises ValueError on an unknown value instead of silently falling back to the shortest path.

LEFT = 'left'

Counter-clockwise (CCW) — positive angular direction.

RIGHT = 'right'

Clockwise (CW) — negative angular direction.

classmethod coerce(value: TurnDirection | str | None) TurnDirection | None

Normalize value to a TurnDirection, validating it.

None passes through (meaning “shortest path”). A TurnDirection is returned as-is. A string is matched case-insensitively against the members. Anything else raises ValueError so a typo (e.g. "lft") fails loudly rather than being silently ignored.

class robot.heading_reference.HeadingReferenceService(robot: robot.api.GenericRobot)

Bases: robot.service.RobotService

Stores an absolute IMU heading reference and computes turns relative to it.

Use robot.get_service(HeadingReferenceService) to access.

mark(origin_offset_deg: float = 0.0, positive_direction: str = 'left') None

Capture the current absolute world heading as the reference.

Parameters:
  • origin_offset_deg – Offset in degrees added to the captured heading. Use this to define a consistent origin regardless of the robot’s physical starting rotation. For example, if the robot is placed at 30° to the board edge but you want 0° to mean “along the board edge”, pass origin_offset_deg=-30.

  • positive_direction – Which physical direction corresponds to positive angles. "left" (default) means CCW is positive, matching the standard mathematical convention. "right" flips the sign so CW is positive.

tilt_reference_quat() tuple[float, float, float, float] | None

The flat DMP orientation quaternion from the last mark(), or None.

property reference_deg: float | None

The stored reference in degrees, or None if not set.

current_relative_deg() float

The current world heading in degrees relative to the reference.

Uses the same positive-direction convention as compute_turn() ("left" → CCW positive). Useful for logging “where we are now” before a heading turn.

Raises:

RuntimeError – If no reference has been marked yet.

target_absolute_rad(target_deg: float) float

Convert a relative target (degrees from reference) to absolute IMU radians.

Used by motion controllers that want to hold an absolute heading rather than turn to it — they need the raw absolute target without [-180, 180] normalisation, since the chassis controller carries continuous heading state across consecutive commands.

Raises:

RuntimeError – If no reference has been marked yet.

compute_turn(target_deg: float, force_direction: TurnDirection | str | None = None) float

Compute the signed relative turn angle to reach target_deg from reference.

Reads the current world heading via _world_heading() (odometry, the same source the motion controllers regulate on), so the computed turn delta and the executed feedback share one frame.

Parameters:
  • target_deg – Desired heading in degrees relative to the reference.

  • force_directionTurnDirection.LEFT to force CCW, TurnDirection.RIGHT to force CW, or None (default) for shortest path. Plain strings "left" / "right" are accepted and validated; an unknown value raises ValueError.

Returns:

Signed angle in degrees (positive = CCW / left, negative = CW / right). Normalized to [-180, 180] for shortest path, or extended past ±180 (up to ±360) to honour the forced direction.

Raises:
  • RuntimeError – If no reference has been marked yet.

  • ValueError – If force_direction is not a valid direction.