step.motion.drive_angle¶
Classes¶
Drive at an arbitrary angle with distance or condition-based termination. |
|
Drive at an angle to the left with distance or condition-based termination. |
|
Drive at an angle to the right with distance or condition-based termination. |
Module Contents¶
- class step.motion.drive_angle.DriveAngle(angle_deg: float, cm: float | None = None, speed: float = 1.0, until: step.condition.StopCondition = None, heading: float | None = None)¶
Bases:
step.motion.motion_step.MotionStepDrive at an arbitrary angle with distance or condition-based termination.
Decomposes the desired heading into forward and lateral velocity components, then runs a profiled PID controller in a rotated coordinate frame with heading maintenance and cross-track correction.
Requires a mecanum or omni-wheel drivetrain.
Angle convention (robot-centric):
0= forward,90= right,-90= left,180= backward.The
angle_degtravel direction is always robot-centric. The held heading, however, is decoupled: whenheadingis given the controller holds that absolute heading (degrees from the heading reference) viaHeadingReferenceService— the same frameturn_to_headingand theheading=argument ofdrive_forward/strafe_*use — instead of the heading captured at start. This prevents drift accumulation across consecutive diagonal drives.Requires
mark_heading_reference()when usingheading.- Parameters:
angle_deg – Travel angle in degrees.
cm – Distance to travel in centimeters. Omit to use condition-only mode.
speed – Fraction of max speed, 0.0 to 1.0.
until – Stop condition for early termination.
heading – Absolute heading in degrees from the heading reference to hold during the drive.
None(default) holds the heading at the start of the drive (relative mode).
Example:
from raccoon.step.motion import drive_angle # Drive diagonally forward-right at 45 degrees drive_angle(45, cm=30) # Drive pure right (same as strafe_right) drive_angle(90, cm=20) # Push diagonally while holding an absolute 0° heading drive_angle(-120, heading=0).until(on_black(s))
- lower_to_segments() list¶
Lower a drive-angle into a single segment.
Axis-aligned angles (0 / ±180 / ±90) lower to a
linearsegment; true diagonals lower to adiagonalsegment (see below).DriveAngleholds the robot’s heading fixed while translating the chassis along a vector atangle_degrelative to that heading. The path IR’slinearsegment can only express travel along theForwardorLateralaxis (travel direction == held heading, or 90° off it) — it has no field to decouple the travel direction from the held heading. So only the axis-aligned angles map cleanly:0→ forward (Forwardaxis, +sign)180/-180→ backward (Forwardaxis, -sign)90→ right (Lateralaxis, +sign)-90→ left (Lateralaxis, -sign)
Any other angle is a true diagonal (simultaneous vx+vy at a held heading). A single Forward/Lateral linear axis can’t express it, so it lowers to a
"diagonal"segment carrying the known body-frame displacement (forward_m/left_m). That segment runs via an opaque adapter (this step’s own lifecycle) andto_absoluteintegrates the body-frame displacement into a waypoint.angle_deg(the robot-centric travel direction) is never stamped ontoheading_deg— it is not an absolute heading-reference angle, so emitting it there would mis-bind it throughHeadingReferenceService. The optionalheadingargument, on the other hand, is an absolute heading-reference angle, so it is threaded through asheading_deg(linear case) / honoured via the opaque step’son_start(diagonal case). With noheadingthe segment holds the current world heading at execution — matchingon_start’s relative-mode fallback.
- class step.motion.drive_angle.DriveAngleLeft(angle_deg: float, cm: float | None = None, speed: float = 1.0, until: step.condition.StopCondition = None, heading: float | None = None)¶
Bases:
DriveAngleDrive at an angle to the left with distance or condition-based termination.
Convenience wrapper around
DriveAnglethat negates the angle so that theangle_degparameter is always positive (pointing left).The angle is measured as degrees to the left of forward:
0= forward,45= forward-left diagonal,90= pure left.- Parameters:
angle_deg – Degrees to the left of forward (0 = forward, 90 = pure left).
cm – Distance to travel in centimeters. Omit to use condition-only mode.
speed – Fraction of max speed, 0.0 to 1.0.
until – Stop condition for early termination.
heading – Absolute heading in degrees from the heading reference to hold during the drive.
None(default) holds the heading at the start of the drive (relative mode).
Example:
from raccoon.step.motion import drive_angle_left # Drive diagonally forward-left at 45 degrees drive_angle_left(45, cm=30) # Drive pure left until sensor drive_angle_left(90, speed=0.6).until(on_black(s))
- class step.motion.drive_angle.DriveAngleRight(angle_deg: float, cm: float | None = None, speed: float = 1.0, until: step.condition.StopCondition = None, heading: float | None = None)¶
Bases:
DriveAngleDrive at an angle to the right with distance or condition-based termination.
Convenience wrapper around
DriveAnglethat passes the angle directly (positive = right in the robot frame).The angle is measured as degrees to the right of forward:
0= forward,45= forward-right diagonal,90= pure right.- Parameters:
angle_deg – Degrees to the right of forward (0 = forward, 90 = pure right).
cm – Distance to travel in centimeters. Omit to use condition-only mode.
speed – Fraction of max speed, 0.0 to 1.0.
until – Stop condition for early termination.
heading – Absolute heading in degrees from the heading reference to hold during the drive.
None(default) holds the heading at the start of the drive (relative mode).
Example:
from raccoon.step.motion import drive_angle_right # Drive diagonally forward-right at 45 degrees drive_angle_right(45, cm=30) # Drive pure right until sensor drive_angle_right(90, speed=0.6).until(on_black(s))