Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/saquer916/odyssey/llms.txt

Use this file to discover all available pages before exploring further.

On a mecanum robot, heading (the angle the robot faces) is mechanically decoupled from the direction of travel. Odyssey takes advantage of this by controlling orientation independently from the translational path: each BezierCurve segment carries its own HeadingInterpolator instance, which maps the curve parameter t ∈ [0, 1] to a desired robot heading in radians. The Follower queries getHeadingAtT(t) on every control cycle and feeds the result to its heading PID, so you can mix and match orientation strategies across the segments of a single Path.

The HeadingInterpolator interface

All four strategies implement a single-method interface:
public interface HeadingInterpolator {
    double getHeading(double t, BezierCurve curve);
}
t is the arc-length–normalized curve parameter produced by getTAtDistance, and curve is the segment being followed — passed so that interpolators like TangentInterpolator can query the curve’s geometry directly.

The four strategies

ConstantInterpolator(double heading) — the robot holds a fixed heading for the entire segment, regardless of where it is on the curve. This is ideal for strafing manoeuvres where you want the robot to face a particular direction (toward a scoring target, for example) while sliding sideways.
// Hold 90° (facing the positive-Y axis) throughout the segment
new ConstantInterpolator(Math.PI / 2)
Internally, getHeading simply returns the stored value:
@Override
public double getHeading(double t, BezierCurve curve) {
    return heading; // constant — t is ignored
}

Quick-reference examples

// Hold 90° throughout
new ConstantInterpolator(Math.PI / 2)

// Rotate from 0° to 90°
new LinearInterpolator(0, Math.PI / 2)

// Face direction of travel
new TangentInterpolator()

// Always face the submersible at (1800, 1800)
new FaceTargetInterpolator(new Vector2d(1800, 1800))

Choosing a strategy

ConstantInterpolator

Robot orientation is fixed. Best for strafing across the field or when the robot must face a fixed direction for the whole segment.

LinearInterpolator

Smooth turn from one angle to another. The go-to choice for most path segments that need an orientation change.

TangentInterpolator

Robot faces the direction of travel. Natural feel for high-speed sweeping curves; no tuning required.

FaceTargetInterpolator

Robot always points at a field landmark. Useful when a sensor or mechanism must track a fixed target while the robot moves.
All angles are in radians. Use Math.toRadians() to convert degree values from a driver-station dashboard or competition sheet into the radians that every HeadingInterpolator expects. For example, Math.toRadians(90) gives π/2 ≈ 1.5708.

Build docs developers (and LLMs) love