step.motion.heading_reference

Classes

MarkHeadingReference

Mark the current IMU heading as a reference point for absolute turns.

TurnToHeading

Turn to an absolute heading defined relative to the heading reference.

Functions

turn_to_heading_right(→ TurnToHeading)

Turn to face a heading measured clockwise from the origin.

turn_to_heading_left(→ TurnToHeading)

Turn to face a heading measured counter-clockwise from the origin.

Module Contents

class step.motion.heading_reference.MarkHeadingReference(origin_offset_deg: float = 0.0, positive_direction: Literal['left', 'right'] = 'left')

Bases: step.Step

Mark the current IMU heading as a reference point for absolute turns.

Captures the robot’s current absolute IMU heading and stores it as a reference. Subsequent calls to turn_to_heading_right() and turn_to_heading_left() will compute turn angles relative to this stored reference, enabling absolute heading control even after the robot has moved and turned through other motion steps.

The reference uses the raw IMU heading which is unaffected by odometry resets that occur during normal motion steps.

It also captures the current DMP orientation as the flat tilt reference used by on_incline() / on_level() / over_ramp(). Those ramp conditions measure tilt relative to it, so mark it on flat ground (and after the DMP has converged — i.e. after some motion, not dead-still right after power-on) before driving onto a ramp.

Multiple calls overwrite the previous reference.

Place this step right after wait_for_light() so the heading origin is captured before the robot moves.

Parameters:
  • origin_offset_deg – Offset in degrees added to the captured heading. Use this to define a consistent board-relative origin regardless of the robot’s physical starting rotation. For example, if the robot always starts angled 30° clockwise from “forward on the board”, pass origin_offset_deg=-30 so that 0° means “forward on the board”.

  • positive_direction – Which physical direction is treated as positive for subsequent turn_to_heading_left and turn_to_heading_right calls. "left" (default) means counter-clockwise angles are positive, matching the standard mathematical convention. "right" flips the sign so clockwise angles are positive.

Example:

from raccoon.step.motion import mark_heading_reference, turn_to_heading_right

# Capture heading origin right after wait-for-light
mark_heading_reference()

# ... robot drives around ...

# Turn to face 90 degrees clockwise from origin
turn_to_heading_right(90)

# With offset: robot starts 30° CW from board forward
mark_heading_reference(origin_offset_deg=-30)

# Positive direction is clockwise (right)
mark_heading_reference(positive_direction="right")
class step.motion.heading_reference.TurnToHeading(target_deg: float, speed: float = 1.0, force_direction: raccoon.robot.heading_reference.TurnDirection | str | None = None)

Bases: step.motion.motion_step.MotionStep

Turn to an absolute heading defined relative to the heading reference.

This is a KNOWN-endpoint turn: it targets an absolute world heading derived from the HeadingReferenceService, NOT an opaque runtime-deferred angle. At on_start it asks the reference service for the signed shortest-path delta (compute_turn) from the current heading to target_deg (reference-relative, CCW-positive), then turns to the resulting ABSOLUTE world heading.

Because the target is absolute, the underlying TurnMotion regulates onto a fixed world heading (drift-corrected) rather than integrating a pre-computed relative angle. Behaviour for plain seq() use matches the historical step: it resolves the shortest-path turn to the reference heading; the only change is that the turn now holds the absolute target instead of a one-shot relative angle.

Users normally go through turn_to_heading_right() / turn_to_heading_left().

Parameters:
  • target_deg – Target heading in degrees relative to the reference, CCW-positive (turn_to_heading_right(d) passes -d; turn_to_heading_left(d) passes +d).

  • speed – Fraction of max angular speed, 0.0 to 1.0.

  • force_directionTurnDirection (or the strings "left" / "right") to force the physical turn direction, or None for shortest path. An invalid value raises ValueError.

required_resources() frozenset[str]
on_start(robot: raccoon.robot.api.GenericRobot) None
on_update(robot: raccoon.robot.api.GenericRobot, dt: float) bool
lower_to_segments() list
step.motion.heading_reference.turn_to_heading_right(degrees: float, speed: float = 1.0, force_direction: raccoon.robot.heading_reference.TurnDirection | str | None = None) TurnToHeading

Turn to face a heading measured clockwise from the origin.

Computes the absolute target heading as origin - degrees (since clockwise is the negative direction), then turns via the shortest path. The actual turn direction (left or right) is chosen automatically to minimize rotation — only the target angle convention is clockwise.

Use force_direction to override the automatic shortest-path choice when obstacles prevent turning in one direction.

Requires mark_heading_reference() to have been called earlier in the mission.

Parameters:
  • degrees – Angle in degrees clockwise from the heading origin. Must be positive. For example, 90 means “face 90° to the right of origin”.

  • speed – Fraction of max angular speed, 0.0 to 1.0 (default 1.0).

  • force_directionTurnDirection (TurnDirection.LEFT / TurnDirection.RIGHT, or the equivalent strings "left" / "right") to force the physical turn direction regardless of shortest path, or None (default) for automatic shortest-path selection. An invalid value raises ValueError.

Returns:

A TurnToHeading step that resolves the shortest-path turn to the absolute reference heading at start time.

Raises:
  • RuntimeError – If no heading reference has been set.

  • ValueError – If force_direction is not a valid direction.

Example:

from raccoon.step.motion import mark_heading_reference, turn_to_heading_right
from raccoon.robot.heading_reference import TurnDirection

# Capture origin after wait-for-light
mark_heading_reference()

drive_forward(30)

# Face 90° clockwise from where we started (shortest path)
turn_to_heading_right(90)

# Force turning right even if left would be shorter
turn_to_heading_right(30, force_direction=TurnDirection.RIGHT)

# Return to origin heading
turn_to_heading_right(0)
step.motion.heading_reference.turn_to_heading_left(degrees: float, speed: float = 1.0, force_direction: raccoon.robot.heading_reference.TurnDirection | str | None = None) TurnToHeading

Turn to face a heading measured counter-clockwise from the origin.

Computes the absolute target heading as origin + degrees (since counter-clockwise is the positive direction), then turns via the shortest path. The actual turn direction (left or right) is chosen automatically to minimize rotation — only the target angle convention is counter-clockwise.

Use force_direction to override the automatic shortest-path choice when obstacles prevent turning in one direction.

Requires mark_heading_reference() to have been called earlier in the mission.

Parameters:
  • degrees – Angle in degrees counter-clockwise from the heading origin. Must be positive. For example, 90 means “face 90° to the left of origin”.

  • speed – Fraction of max angular speed, 0.0 to 1.0 (default 1.0).

  • force_directionTurnDirection (TurnDirection.LEFT / TurnDirection.RIGHT, or the equivalent strings "left" / "right") to force the physical turn direction regardless of shortest path, or None (default) for automatic shortest-path selection. An invalid value raises ValueError.

Returns:

A TurnToHeading step that resolves the shortest-path turn to the absolute reference heading at start time.

Raises:
  • RuntimeError – If no heading reference has been set.

  • ValueError – If force_direction is not a valid direction.

Example:

from raccoon.step.motion import mark_heading_reference, turn_to_heading_left
from raccoon.robot.heading_reference import TurnDirection

# Capture origin after wait-for-light
mark_heading_reference()

drive_forward(30)

# Face 90° counter-clockwise from where we started
turn_to_heading_left(90)

# Force turning right to avoid obstacle on the left
turn_to_heading_left(45, force_direction=TurnDirection.RIGHT)

# Return to origin heading
turn_to_heading_left(0)