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.

odyssey-gui is a JavaFX desktop application that renders a single cubic Bézier curve over a 650×650 px FTC field image. You drag four colour-coded handles to shape the curve visually, then read the resulting mm coordinates directly from the handle positions and paste them into your BezierCurve constructor calls. It removes the guesswork of choosing control point positions by hand in code.

Running the editor

The odyssey-gui module is a standard Gradle Java application. From the repository root:
./gradlew :odyssey-gui:run
Gradle will compile the module and launch the JavaFX window. No additional installation is required beyond a JDK with JavaFX on the module path.

Editor interface

The editor opens a 650×650 px window titled “Odyssey Path Editor” showing the FTC field image scaled to fill the canvas. Four draggable handles appear on top:

Green circles — endpoints

p0 (start) and p3 (end). The curve passes through these points exactly. Drag them to your desired start and finish positions on the field.

Blue circles — handles

p1 and p2. These are the interior control points that shape the curve. The curve is attracted toward them but does not pass through them. Drag them to control the curvature of each half of the segment.
The curve is redrawn in yellow in real time as you drag any handle. Light-grey lines connect each endpoint to its adjacent handle so you can see the tangent directions.

Coordinate system

The editor uses FieldCoordinates to convert between pixel positions and millimetres. The FTC field is 3657.5 mm × 3657.5 mm scaled to 650 px:
// Pixel → mm (X axis)
double xMM = px * (3657.5 / 650.0);

// Pixel → mm (Y axis — Y is flipped: Y=0 is at the bottom of the image)
double yMM = (650.0 - py) * (3657.5 / 650.0);
This matches the FieldCoordinates helper used internally:
public static double fieldX_PX_TO_MM(double px) {
    return px * (3657.5 / 650.0);       // mmPerPX = 3657.5 / 650
}

public static double fieldY_PX_TO_MM(double px) {
    return fieldX_PX_TO_MM(650.0 - px); // Y axis is flipped
}
The inverse (mm → px) is used to place handles at their initial positions when the window opens:
public static double fieldX_MM_TO_PX(double mm) {
    return mm * (650.0 / 3657.5);       // pxPerMM = 650 / 3657.5
}

public static double fieldY_MM_TO_PX(double mm) {
    return fieldX_MM_TO_PX(3657.5 - mm); // Y axis is flipped
}

Reading coordinates after dragging

After placing the handles where you want them, the underlying Vector2d fields (p0p3) in Main.java hold the converted mm values. The simplest way to read them is to add a telemetry print or System.out.println call inside drawCurve():
System.out.printf("p0=(%.1f, %.1f)  p1=(%.1f, %.1f)%n",
    p0.getX(), p0.getY(), p1.getX(), p1.getY());
System.out.printf("p2=(%.1f, %.1f)  p3=(%.1f, %.1f)%n",
    p2.getX(), p2.getY(), p3.getX(), p3.getY());
Then paste the printed values into your BezierCurve constructor:
BezierCurve curve = new BezierCurve(
    new Vector2d(p0.getX(), p0.getY()),
    new Vector2d(p1.getX(), p1.getY()),
    new Vector2d(p2.getX(), p2.getY()),
    new Vector2d(p3.getX(), p3.getY()),
    new TangentInterpolator()
);

Multi-segment paths

The current GUI visualises a single curve at a time. For a multi-segment autonomous routine, run the editor once per segment:
1

Design segment 1

Place handles for the first BezierCurve. Note the coordinates of all four handles — especially p3, which will become p0 of the next segment.
2

Design segment 2

Relaunch the editor (or move the green handles to the new start/end positions). The starting green handle p0 of this run should be placed at the same position as p3 from the previous run to ensure geometric continuity.
3

Chain in code

Construct each BezierCurve with the coordinates you recorded and pass them to Path as varargs:
Path fullPath = new Path(segment1, segment2, segment3);
Take a screenshot of the editor window with your desired curve shape, then compare the handle positions against visible field features — tile corners are spaced 609.6 mm apart — to cross-check that your mm coordinates land where you expect on the physical field.

Build docs developers (and LLMs) love