Team 7421's vendor library for FRC, built against WPILib 2026.
The library ships in both C++ and Java. The two implementations are kept feature
equivalent, but Java is the one being actively developed ahead of the 2027 SystemCore
transition, and builds are Java only by default. The C++ sources remain in the tree
and still build on demand, with -PjavaOnly=false.
| Language | Sources | Published artifact |
|---|---|---|
| C++ | src/main/native/cpp, src/main/native/include |
com.overture.lib:OvertureLib-cpp (only with -PjavaOnly=false) |
| Java | src/main/java |
com.overture.lib:OvertureLib-java |
The Java root package is com.overture.lib. Package names mirror the C++ include
directories, lowercased:
| C++ header | Java package |
|---|---|
OvertureLib/Gamepads/... |
com.overture.lib.gamepads |
OvertureLib/Math/... |
com.overture.lib.math |
OvertureLib/MotorControllers/... |
com.overture.lib.motorcontrollers |
OvertureLib/Robots/... |
com.overture.lib.robots |
OvertureLib/Sensors/... |
com.overture.lib.sensors |
OvertureLib/Simulation/... |
com.overture.lib.simulation |
OvertureLib/Subsystems/LedsManager/... |
com.overture.lib.subsystems.leds |
OvertureLib/Subsystems/Swerve/... |
com.overture.lib.subsystems.swerve |
OvertureLib/Subsystems/Vision/... |
com.overture.lib.subsystems.vision |
OvertureLib/Utils/... |
com.overture.lib.utils |
- Units are plain SI doubles, matching WPILib Java itself: meters, meters per second,
seconds, radians, volts, amps. Motor-native quantities stay in rotations, which is what
Phoenix 6's
doubleoverloads expect. - Simulation is selected at runtime, not compile time. The C++ code switches on the
__FRC_ROBORIO__macro; Java has no preprocessor, so the simulation managers are always linked and only driven whenRobotBase.isSimulation()is true. SwerveBaseextendsSubsystemBase. C++ mixes the two in via multiple inheritance, which Java does not have, so the hierarchy isSubsystemBase→SwerveBase→SwerveChassis→ your drivetrain.- Standard deviations are
Matrix<N3, N1>(built withVecBuilder.fill) rather than the C++wpi::array<double, 3>, because that is what the WPILib pose estimator takes. LimelightHelpers.javais vendored from limelightlib-wpijava (v1.14). Only itspackagedeclaration and one malformed Javadoc tag were changed.
./gradlew build # Java only, the default
./gradlew build -PjavaOnly=false # Java and the whole native toolchainJava only is the default, set by javaOnly=true in gradle.properties, because the
library is being phased over to Java. It skips config.gradle, the native component and
the C++ publications, which also makes iteration on the Java sources much faster. Nothing
about the C++ build is removed, and -PjavaOnly=false is the way back to it.
The flag is read by value, not by presence. hasProperty alone is also true for
javaOnly=false, and a property set in gradle.properties cannot be unset from the
command line, so there would be no way back to a C++ build short of editing the file. A
bare -PjavaOnly still means Java only, which is what both CI workflows pass.
CI builds Java only as well, and the C++ jobs are commented out rather than deleted,
so released versions from here on ship the Java artifacts and nothing else.
OvertureLib.json declares an empty cppDependencies to match, because advertising
binaries that are never published makes every C++ platform 404 rather than just the
unbuilt ones.
To put C++ back: uncomment the build-docker and build-host jobs in both workflows, set
javaOnly=false in gradle.properties, and restore the cppDependencies block in
OvertureLib.json (see git history for the exact block).
By default the build resolves the latest WPILib development build. To build against the
last tagged release, add -PreleaseMode.
./gradlew testSome tests drive classes that talk to real WPILib devices — the LED strip, the duty cycle
encoder — so the test JVM brings up the simulation HAL. WPILib 2026 publishes no -jni
jars; the JNI shims live inside the -cpp zips, so extractTestNatives unpacks them into
build/testNatives and test puts that on java.library.path. This is the same thing
GradleRIO does with build/jni/release before a simulation, done by hand because this
project uses NativeUtils rather than GradleRIO.
Two constraints those tests run into, both inherited from the HAL:
- Only one
AddressableLEDmay exist per program, matching the roboRIO's single LED output. Every LED test therefore shares the strip built bySharedTestLeds, carved into disjoint slices so they cannot disturb each other. - A PWM channel stays claimed for the life of the JVM, so tests cannot each allocate their own.
./gradlew clean build in a single invocation fails in copyAllOutputs, because
vendordepJson is judged up to date against a snapshot taken before clean removed its
output. Run them as two invocations (./gradlew clean && ./gradlew build). This predates
the Java migration and does not affect CI, which never cleans.
Formatting is enforced by Spotless (googleJavaFormat for Java, eclipseCdt for C++):
./gradlew spotlessApplyJava vendor dependencies are read directly out of vendordeps/*.json at configuration
time, so the Java and C++ builds always consume the same vendor versions. Adding or
bumping a vendordep JSON is all that is needed — there is no second list to update.
Currently: WPILib New Commands, CTRE Phoenix 6, PathPlannerLib, PhotonLib and maple-sim.
OvertureLib.json declares only the OvertureLib artifact, so none of the vendor libraries
above come along with it. That has always been true: a robot project already installs
Phoenix 6, PathPlanner and PhotonLib of its own accord even though it reaches most of them
through this library rather than directly.
maple-sim is simply the newest entry on that list, and the one a robot set up before 2026
will not have. Without it, simulation fails immediately. A real robot most likely runs
anyway, because everything touching org.ironmaple sits behind a RobotBase.isSimulation()
check and the JVM resolves classes lazily — but that is how HotSpot happens to behave
rather than a guarantee, and it has not been tested.