Odyssey is an open-source autonomous path-following library purpose-built for FIRST Tech Challenge mecanum drivetrains. Where encoder-tick-based dead-reckoning breaks down on carpet seams and collisions, Odyssey keeps your robot on the intended trajectory by continuously correcting against a high-frequency odometry pose. Its path representation uses cubic Bézier curves — smooth, differentiable splines that let you express a sweeping S-curve or a tight arc with four intuitive control points — and its motion planner ensures the robot never exceeds the centripetal acceleration the wheels can deliver.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.
Architecture overview
Odyssey is organized into three cooperating layers, each with a clear responsibility. Path geometry —BezierCurve and Path — answers questions like “where on the curve is the robot right now?” and “what heading should it have here?”. BezierCurve stores the four De Casteljau control points, computes exact arc length via a 5-point Gauss–Legendre integrator, and inverts that integral with a Brent root-solver to convert a physical distance along the curve into the curve parameter t. Path chains one or more BezierCurve segments into a composite spline, caching each segment’s length so multi-segment queries are fast.
Motion planning — VelocityProfile — pre-computes a curvature-aware trapezoidal speed schedule across the full path at construction time. A forward pass enforces the acceleration limit; a backward pass enforces the braking limit; and at every sample point the speed is also clamped by sqrt(maxCentripetalAccel / curvature) so cornering forces stay within traction budget.
Execution — Follower reads the robot’s current Pose2d from a Localizer, projects it onto the path to find the closest arc-length position, and blends three concurrent outputs into a DriveSignal: a translational PID correction toward the reference point, a feedforward velocity along the path tangent, and a heading PID from the HeadingInterpolator. MecanumDrive converts that DriveSignal into per-motor power values using kS/kV/kA feedforward with live battery-voltage compensation.
Key features
Arc-length parameterization
Gauss–Legendre integration (5 points, 10⁻⁹ tolerance) computes exact curve length; a Brent solver inverts the integral to map physical distance → curve parameter
t. Speed targets are therefore in real units (mm/s), not unitless t increments.Curvature-aware velocity profile
VelocityProfile runs a three-pass trapezoidal planner: centripetal-acceleration cap → forward acceleration sweep → backward braking sweep. The robot automatically slows through tight corners and accelerates on straights.Translational + heading PID with feedforward
Follower runs a translational PIDController for cross-track correction, a heading PIDController for orientation, and a kS/kV/kA feedforward applied inside MecanumDrive with real-time voltage compensation so power stays consistent across battery states.Pluggable HeadingInterpolator
Four built-in strategies:
TangentInterpolator (robot faces the direction of travel), LinearInterpolator (linearly sweeps start→end heading), ConstantInterpolator (fixed heading throughout), and FaceTargetInterpolator (always points at a field coordinate). Implement the one-method HeadingInterpolator interface to add your own.Localizer interface
The
Localizer interface (getPose() + update()) decouples path following from any specific sensor. PinpointLocalizer is provided out of the box, wrapping the GoBILDA Pinpoint odometry computer. Swap in your own two-wheel odometry or April Tag localization by implementing the interface.JavaFX path editor GUI
The
odyssey-gui module (included in the repository) provides a desktop JavaFX application for visually designing and exporting paths. Drag control points, inspect velocity profiles, and copy generated Java code directly into your OpMode.Project structure
The repository is a multi-module Gradle project with four modules registered insettings.gradle:
| Module | Purpose |
|---|---|
FtcRobotController | Standard FTC SDK module — provides hardware abstraction, DcMotorEx, VoltageSensor, and all FTC runtime APIs. |
odyssey-core | Pure Java library — BezierCurve, Path, VelocityProfile, Follower, PIDController, geometry, and interpolators. No Android dependencies. |
TeamCode | FTC Android integration — MecanumDrive (motor wiring + feedforward) and PinpointLocalizer (GoBILDA Pinpoint). Depends on odyssey-core. |
odyssey-gui | Desktop JavaFX path editor. Standalone; not deployed to the robot. |
odyssey-core has exactly one runtime dependency: Apache Commons Math 3 (org.apache.commons:commons-math3:3.6.1), used for the Gauss–Legendre integrator and Brent solver. It is declared in odyssey-core/build.gradle and propagates transitively to TeamCode at build time.Next steps
Quickstart
Follow a single Bézier path in one autonomous OpMode — from control-point definition to
follower.update() loop.Bézier curves
Deep-dive into arc-length parameterization, curvature, and how Odyssey picks the closest point on the path.
