Releases: SleipnirGroup/Choreo
Choreo v2025.0.0
ARCHIVED.
The GUI is broken, but the vendordep is (to our knowledge) usable for building projects against WPILib's stable 2025 release.
These notes will be replaced by a larger announcement post soon. The below is meant for users upgrading from 2025 beta.
Use the vendor dependencies panel in VS Code (recommended) or the URL https://lib.choreo.autos/dep/ChoreoLib2025.json
Major Changes since Beta 9
- 2025 field
- Thanks to @mjansen4857 for giving us a copy of the PathPlanner field background to adapt for Choreo.
- Trajectories will be rotated around the field center, but retain a blue origin.
- If upgrading paths, note that the default Keep In Rectangle dimensions need to be updated manually. Use a width of
17.548 m
and a height of8.052 m
- Unitless values are no longer accepted and autofilled with a default unit in expression inputs.
- Variable names can be used without parentheses; a bugfix corrected this for
.x
,.y
, and.heading
inside pose variables. - In the list of paths, a generate button replaces the normal icon if the path is different than what was last generated.
- This mechanic is why the .traj files include a
snapshot
section.
- This mechanic is why the .traj files include a
- AutoBindings
- Removed from the AutoFactory constructor and made package-private.
- Use
AutoFactory.bind(String eventName, Command command)
instead, which now returns theAutoFactory
for chaining.
AutoTrajectory.resetOdometry()
is added, as a replacement toAutoRoutine.resetOdometry(AutoTrajectory)
, which no longer exists.- AutoChooser
- We intend to ensure that the command creator functions are only run when the alliance is correct. Thus:
- Changing alliance will re-run the creator.
- In simulation only, going directly from Disconnected to Autonomous for the first run will generate the command on
autonomousInit
. In real life, the auto will stop with a dashboard alert, since this is an unrealistic scenario.
- Many bugs with the library and the UI have been fixed.
What's Changed
- Clear .chor variables list when deserializaing by @shueja in #1055
- [trajoptlib] Reset differential cancellation flag by @calcmogul in #1058
- Rename LocalProgressUpdate::DiffTrajectory to DifferentialTrajectory, fixing mismatch with TS by @shueja in #1059
- Make rounding of trajectory sample fields normalize -0.0 to 0.0 by @shueja in #1062
- [ci] Upgrade to wpiformat 2024.51 by @calcmogul in #1064
- Simplify logic when receiving a successful generation in UI by @shueja in #1065
- [docs] Fix annotations in ChoreoLib Trajectory API documentation by @bryceroethel in #1069
- Add docs build instructions by @DeltaDizzy in #1052
- Remove numbers as valid input for dimensioned exprs by @shueja in #1067
- [docs] Update home page screenshot by @spacey-sooty in #1040
- [docs] Document Settings Improvements by @DeltaDizzy in #1068
- [docs] Fix requirements.txt by @bryceroethel in #1071
- [choreolib] AutoChooser Fixes and Sim behavior changes by @oh-yes-0-fps in #1057
- Fix controllers in getting started docs by @spacey-sooty in #1077
- [Choreolib] cleaned up various parts of the non-user facing code by @oh-yes-0-fps in #1048
- Add Python script for updating field dimensions across the project by @shueja in #1079
- Make AutoBindings package private by @spacey-sooty in #1076
- Clear undo history when opening a project. by @shueja in #1074
- [docs] Fix formatting of Auto Bindings section by @bryceroethel in #1083
- Use autogenerated field dimensions in default keep-in rectangle by @shueja in #1085
- [trajoptlib] Fix keep-out polygon distance by @calcmogul in #1086
- Remove dimension tooltips by @shueja in #1075
- Simpler ExpressionInput internals by always showing the same internal variable. by @shueja in #1073
- Directly depend on global variables store in expression stores by @shueja in #1084
- Add a way to clear the path list that properly sets activePath to default by @shueja in #1082
- [docs] Update saving page by @shueja in #1089
- [docs] Remove broken link to motor calculator docs by @shueja in #1091
- [docs] Update the view options page by @shueja in #1090
- [trajoptlib] Upgrade Sleipnir by @calcmogul in #1094
- Display a different icon if the trajectory is changed since being generated by @shueja in #1093
- Refactor path gradients and make them properly support diff drive by @calcmogul in #1095
- [trajoptlib] Clean up InputModulus() by @calcmogul in #1096
- [trajoptlib] Use direct collocation for diff drive dynamics constraints by @calcmogul in #1097
- [trajoptlib] Upgrade to fmt 11.1.1 by @calcmogul in #1098
- Remove file associations for STL headers by @calcmogul in #1100
- [trajoptlib] Normalize Rotation2d constructor arguments by @calcmogul in #1101
- [choreolib] Fix SwerveSample docs typo by @calcmogul in #1103
- [trajoptlib] Const-qualify solution passed to callback by @calcmogul in #1105
- [trajoptlib] Remove anti-tunneling constraint by @calcmogul in #1109
- Give AutoFactory.trajectoryCmd() an actual routine that runs by @shueja in #1110
- [trajoptlib] Hoist decision variables out of nested loops by @calcmogul in #1113
- [choreolib] Rename Alerts group to Choreo Alerts by @spacey-sooty in #1112
- Restore document from snapshot if project opening fails by @shueja in #1081
- Fix bug preventing "pose.x" from being transformed by @shueja in #1087
- Editing paths docs by @spacey-sooty in #1039
- 2025 Update: field and WPILib by @shueja in #1107
- Alert QoL + Docs updates by @Daniel1464 in #1111
- Update version to v2025.0.0 by @shueja in #1114
Full Changelog: v2025.0.0-beta-9...v2025.0.0
Choreo v2025.0.0-beta-9
This is a fix to the Choreo GUI only. It fixes an issue with Choreo exporting the wrong trajectory schema version.
ChoreoLib 2025.0.0-beta-9 is published, but is identical to beta 8.
Choreo v2025.0.0-beta-8
Choreo v2025.0.0-beta-8
Please read through the post entirely, since many breaking changes have been made.
This release focuses on internal infrastructure and breaking API improvements in ChoreoLib.
v2025.0.0-beta-8 is built for WPILib beta 3. It is likely mostly identical to the first full 2025 release of Choreo, which will be released after the WPILib full 2025 release.
NOTE: This changelog describes changes since beta-6.
https://choreo.autos : New Docs Domain
We recently registered the domain choreo.autos
to replace sleipnirgroup.github.io/Choreo
. We have set up the latter to redirect to the former. Documentation is still being updated over the coming weeks before kickoff.
Document Schemas and Auto Upgrade
The version control in the .chor and .traj schemas is no longer a semver string. It is now an integer, starting at 1, and is different for .traj and .chor. A string in the version
key is interpreted as version 0.
The Choreo app is able to automatically load non-current versions of both files (including existing files from beta-6) and upgrade them to the current schema. Usually, this will require regeneration, depending on the changes in the update.
This is a feature Choreo had in 2024, but it has been completely reimplemented.
For contributors, a guide to defining new schema versions has been added here.
The three ChoreoLib languages will not automatically upgrade old trajectories when reading them.
Removal of C++ AutoFactory API
Unfortunately, we found many severe bugs in our port of the Java AutoFactory API to C++, and decided to delete that attempt. We apologize for the inconvenience.
ChoreoLib Changes (Mostly Breaking)
See below for details on these changes.
General
- Changes to how Choreo handles alliance flipping. See below.
- Many bugs with the sample flipping algorithms have been fixed.
- ChoreoLib no longer reads the .chor file to know what sample type to expect, or what the differential track width is, as needed for
DifferentialSample.getChassisSpeeds()
. This information is now in the .traj file. Details below.
Raw API
Trajectory
- [Java]
Trajectory.getInitialSample()
,getFinalSample()
,getInitialPose()
,getFinalPose()
,sampleAt()
now returnOptional<Pose2d>
instead of a potentially nullPose2d
. This matches prior behavior of the other two languages (C++ withstd::optional
and Python with returningNone
) - [C++]
Trajectory::GetInitialState()
is nowGetInitialSample()
. - [Java, C++]
Trajectory.getInitialSample()/GetInitialSample()
andgetFinalSample()/GetFinalSample()
now take aboolean
parameter that is true if the sample should be returned flipped. This does not check the current alliance; if the parameter is true, the sample will be flipped. - [Java]
Trajectory.sampleArray()
has been removed due to causing runtime crashes and being type-unsafe.
ProjectFile
Removed, since it is no longer needed.
DifferentialSample
A new field omega
was added, instead of calculating angular velocity from vl
, vr
and the trackwidth from the robot config in the .chor file.
Java Auto API
- Driver Station warnings from ChoreoLib have moved to use the new Alerts API.
New Recommended Practices
- The
AutoRoutine.trajectory(String name)
has been added and is the new recommended way to loadAutoTrajectories
, instead ofAutoFactory.trajectory(String name, AutoRoutine routine)
. Trigger AutoRoutine.observe(BooleanSupplier condition)
has been added. This can be used to create Triggers that are part of theAutoRoutine
and will only be polled during the routine. It can also be used to "sanitize" Triggers that are used elsewhere. See below for details on why this is necessary.- To help handle odometry resetting when the start pose depends on alliance, AutoFactory and AutoTrajectory now have
resetOdometry
capability. More details in the changelog just below.
AutoLoop
choreo.auto.AutoLoop
is nowchoreo.auto.AutoRoutine
.AutoFactory.newLoop()
andvoidLoop()
were renamed tonewRoutine()
andvoidRoutine()
.
AutoRoutine.cmd()
will end immediately with a console warning if alliance flipping is enabled and the alliance is not known on command initialize.AutoLoop.enabled()
was replaces withAutoRoutine.active()
.AutoLoop.poll()
will return immediately if the alliance is needed for flipping and not known. This is the same behavior as ifpoll()
is called on a killed routine, or not while enabled and in autonomous.Trigger anyDone(AutoTrajectory... trajectories)
has been added, which creates a trigger that is true for one cycle when any of the input trajectories finishes. A variant also exists that applies a delay to the rising edge.Trigger anyActive(AutoTrajectory... trajectories)
creates a trigger that is true whenever any input trajectory is active.
AutoTrajectory
AutoTrajectory.done()
behavior has changed. The trigger will become true for one cycle when the trajectory completes without being interrupted. Previously, interrupted trajectories would still fire thedone()
trigger.AutoTrajectory.getInitialPose()
andgetFinalPose()
will now returnOptional.empty()
if alliance flipping is enabled and the alliance is not known.- Removed
AutoTrajectory.atTimeAndPlace()
. Usetrajectory.atTime(String eventName).and(trajectory.atPose(String eventName))
or similar. AutoTrajectory.atPose(...)
did not check the rotation portion of the pose.atPose(...)
now takes a rotation tolerance (default 3 degrees).- For the previous behavior of just checking the translation,
AutoTrajectory.atTranslation()
has been added, which is similar toatPose()
but acceptsTranslation2d
s. AutoTrajectory.atPose(...)
andatTranslation(..)
now properly flip the target pose/translation every time the Trigger is checked, based on the current alliance if alliance flipping is enabled. If the alliance is unknown and flipping is enabled, the Trigger will be false.AutoTrajectory.collectEventPoses
now returns anArrayList<Supplier<Optional<Pose2d>>>
of poses that flip based on the current alliance and flipping enabled status.
AutoFactory
- The Choreo controller function now only takes a
SwerveSample
orDifferentialSample
, not an additionalPose2d
for the current pose. AutoFactory.clearCache()
was replaced withAutoFactory.cache().clear()
since the user can now access the trajectory cache.- A new parameter
Consumer<Pose2d> resetOdometry
has been added. This is used withAutoTrajectory
to create aCommand
that calls theresetOdometry
callback with the first pose of trajectoryCommand()
has been renamed totrajectoryCmd()
trajectoryLogger
is no longer anOptional
. It is a no-op if left unspecified.
AutoChooser
-
AutoChooser
now implementsSendable
, so can be logged withSmartDashboard.putData()
or similar. -
The API to add options has changed.
- One option is to call
addRoutine(String name, Supplier<AutoRoutine> generator)
. - The other is to call
addCmd(String name, Supplier<Command> generator)
. - Both versions will call the given function when the option becomes selected.
- One option is to call
-
AutoChooser
's options are now functions that consume nothing and return anAutoRoutine
or aCommand
. It is expected that users will call to theirAutoFactory
instance like they would a subsystem, instead of having it passed into the function. -
The constructor is now
new AutoChooser()
, since the table name is handled by logging it like aSendable
, and the chooser does not need to pass a factory into the generator functions. -
AutoChooser.getSelectedAutoRoutine()
has been removed. -
To run the selected auto, use
Command selectedCommand()
orCommand selectedCommandScheduler()
.
- The former is the analogue to the
SendableChooser
approach of getting the selected command and directly scheduling it inautonomousInit()
. - The latter returns a deferred Command. Use this if binding autonomous commands to run on
autonomousInit()
withRobotModeTriggers.autonomous()
, since it does not evaluate the selected command as of the time of binding.
AutoChooser
will only update if the DriverStation is connected (so that the alliance is known).
Changes to alliance-based trajectory flipping
Several issues were identified with the way ChoreoLib, especially the Java higher-level API, handled alliance flipping, given that the alliance can change after auto routines are created, and the alliance can be unknown before the call of autonmousInit
.
- The higher-level API now uses
Optional<Pose2d>
andSupplier<Optional<Pose2d>>
instead ofPose2d
in many places, to better represent poses that depend on the currently selected alliance. AutoFactory
/Choreo.createAutoFactory
no longer take aBooleanSupplier mirrorTrajectory
that returns true when trajectories should be flipped. Instead they take aBooleanSupplier useAllianceFlipping
to enable alliance-based flipping in general and a separateSupplier<Optional<Alliance>>
that defaults toDriverStation::getAlliance()
. The BooleanSupplier was moved elsewhere in the parameter list to force a compiler error.
Trigger Sanitization
AutoRoutine.observe
was added to help prevent problems where a Trigger on the default CommandScheduler loop is used when creating an AutoRoutine
. This is especially easy to mess up when that Trigger is combined with a Trigger on the AutoRoutine
event loop, using decorators like .and()
, .or()
, etc.
Combined Triggers are polled on the first Trigger's loop. Thus if the default-loop Trigger is first in a combination, the combined trigger will be polled every loop, even if the auto routine is not running and has not been run.
Example:
Pose2d shotLocation = ...;
// trajec...
Choreo v2025.0.0-beta-6
What's Changed
- Document release process by @calcmogul in #873
- Expand docs for estimating moment of inertia with SysId by @calcmogul in #875
- [choreo] Change default dt to 0.05 s by @calcmogul in #878
- [choreolib] Remove unused libraries and upgrade to 2025 NI libraries by @calcmogul in #879
- [choreolib] Fix swerve module force mirroring by @calcmogul in #877
- [choreolib] Upgrade to GSON 2.11.0 by @calcmogul in #874
- Bump version to v2025.0.0-beta-6 by @calcmogul in #880
Full Changelog: v2025.0.0-beta-5...v2025.0.0-beta-6
Choreo v2025.0.0-beta-5
What's Changed
- Rename macOS standalone executable by @calcmogul in #870
- Bump version to v2025.0.0-beta-5 by @calcmogul in #871
Full Changelog: v2025.0.0-beta-4...v2025.0.0-beta-5
Choreo v2025.0.0-beta-4
This is the first release that requires the WPILib 2025 beta and 2025 roboRIO image.
What's Changed
- Update C++ Autonomous Functionality by @r4stered in #849
- [choreolib] Fix trajectory splitting for C++ by @r4stered in #866
- [ci] Zip standalone executables by @calcmogul in #868
- [choreolib] Upgrade to WPILib 2025 by @calcmogul in #865
- Bump version to v2025.0.0-beta-4 by @spacey-sooty in #869
Full Changelog: v2025.0.0-beta-3...v2025.0.0-beta-4
Choreo v2025.0.0-beta-3
This is the last release that supports WPILib 2024.
Event Markers
Event markers have now been added.
GUI-wise, they function just like in 2024, except that the default command type is now "None", since these markers are also used for ChoreoLib timestamped triggers, and that the offset and wait time fields are time expressions.
Keep In Lane Constraint
A new Keep In Lane constraint has been added to replace the Straight Line constraint.
Before:
After:
With variable tolerance:
Across multiple waypoints:
This constraints the center of the robot to be within the two parallel lines for the entire scope of the constraint. Note that other keep-in constraints apply to the bumpers, unlike this one. Also note that the boundary lines actually extend to infinity, but are only drawn between the two waypoints.
Opening Previous Project
The behavior of re-opening a prior project has been re-added. Choreo betas have already been tracking the last-opened project, but for some users upgrading from 2024 versions directly to this beta, the app may try to open a 2024 project and fail.
ChoreoLib Changes
Renames
choreo.auto.AutoFactory.ChoreoAutoBindings -> choreo.auto.AutoFactory.AutoBindings
choreo.Choreo.ChoreoTrajectoryCache -> choreo.Choreo.TrajectoryCache
Breaking Changes
The AutoFactory constructor previously took a (Pose2d currentPose, Sample currentSample)->ChassisSpeeds
and a separate (ChassisSpeeds speeds)->void
. This is unnecessarily constraining. Now it just takes a (Pose2d currentPose, Sample currentSample)->void
as a control function. The ChoreoControlFunction
type alias for this parameter is also gone.
Control Function
Many have asked what to put for the control function. We intentionally don't provide a pre-made one because the function is more about plumbing than algorithms. Here is an example of a (swerve) control function that would be pasted into the drive subsystem.
public void choreoController(Pose2d curPose, SwerveSample sample) {
ChassisSpeeds speeds = ChassisSpeeds.fromFieldRelativeSpeeds(
new ChassisSpeeds(
xController.calculate(curPose.getX(), sample.x) + sample.vx,
yController.calculate(curPose.getY(), sample.y) + sample.vy,
thetaController.calculate(curPose.getRotation().getRadians(), sample.heading) + sample.omega
), curPose.getRotation());
this.driveRobotRelative(speeds);
}
While the basic controller is shown here, our approach allows teams to add logging, implement additional control influences like heading override, and even use the module forces and higher-derivative components of the sample as their drivetrain code permits. The latter is a main reason why the controller needs to encompass more than just outputting ChassisSpeeds.
Markers in ChoreoLib
There are two main ways to integrate the markers into ChoreoLib's autonomous utilities. For all ChoreoLib uses, the name of the marker is used to reference the event in bindings. The command type selected in the GUI is still a PathPlanner-only integration feature, and is not read by ChoreoLib.
Consider this event as an example.
The AutoBindings class specifies global command bindings. It is recommended to set up the bindings class entirely, before passing it into the AutoFactory.
new AutoFactory.AutoBindings()
.bind("Marker", Commands.print("This message triggers on any marker with that name, in any trajectory."))
The other way to use markers is with AutoTrajectory
, where they can be used to create triggers
Command myAuto() {
var loop = factory.newLoop("myAuto");
AutoTrajectory trajectory = factory.trajectory("MyAutoTrajectory", loop);
trajectory.atTime("Marker").onTrue(
Commands.print("This message only prints during this specific trajectory, but for every marker of that name in the trajectory."));
loop.enabled().onTrue(trajectory.cmd());
return loop.cmd();
}
What's Changed
- [trajoptlib] Make GetIndex() usage consistent and fix GetIndex() by @bruingineer in #820
- [choreolib] Remove Choreo suffix from remaining classes by @calcmogul in #822
- [build] Fixup CMake presets a bit by @spacey-sooty in #827
- [choreo] [trajoptlib] Use more robust time estimates for intervals and initial dt decision variable by @bruingineer in #821
- [docs] Treat JavaDoc and Doxygen warnings as errors by @calcmogul in #819
- [choreolib] Merge control function and outputChassisSpeeds by @spacey-sooty in #829
- [choreolib] Remove unused return type from ControlFunction by @spacey-sooty in #831
- [ci] Build TrajoptLib Rust in CI by @spacey-sooty in #832
- [trajoptlib] Make constraints use current and next index by @calcmogul in #830
- [trajoptlib] Fix order of trackwidth in FFI by @spacey-sooty in #834
- [ci] Upgrade to wpiformat 2024.42 by @calcmogul in #837
- [trajoptlib] Sort constraint types lexicographically by @calcmogul in #838
- [trajoptlib] Fix Translation2d and Rotation2d equality operators by @calcmogul in #839
- [trajoptlib] Use more compact differential drive model by @calcmogul in #833
- [trajoptlib] Add lane constraint by @spacey-sooty in #836
- Remove bad scope-fixing in heading conflict checks by @shueja in #842
- Use std instead of core by @spacey-sooty in #843
- [trajoptlib] Expose lane constraint to Rust by @spacey-sooty in #844
- Sort C++ PathBuilder functions and remove PathBuilder Rust trait by @calcmogul in #846
- [trajoptlib] fix inputModulus by @bruingineer in #847
- [choreo] Add Lane Constraint to UI by @spacey-sooty in #845
- Upgrade Cargo and pnpm dependencies by @calcmogul in #850
- [choreolib] Remove Choreo prefix from typedef by @calcmogul in #851
- [choreolib] Remove controller function typedef by @calcmogul in #852
- [choreo] Event marker refactor by @shueja in #773
- [choreolib] Add "struct:" prefix to struct serialization by @calcmogul in #857
- Use marker name for triggers; change spec to prepare for timestamp-range markers. by @shueja in #856
- Make sure trajectories have at least one split section by @shueja in #858
- Apply max height to variables panel. by @shueja in #859
- Add null tolerance when parsing commands in app. by @shueja in #861
- Filter event markers with null timestamps or empty names by @shueja in #862
- Re-enable opening of last project by @shueja in #863
- Change version to 2025.0.0-beta-3 by @shueja in #860
Full Changelog: v2025.0.0-beta-2...v2025.0.0-beta-3
Choreo v2025.0.0-beta-2
This update fixes a critical issue with ChoreoLib Java, leading to trajectories unable to load.
It also removes a useless item that was being written to files but was unused, and should not have been in the v2025.0.0 spec.
FYI: Documentation improvement is underway and is visible in the below changelog, but the published documentation is not tied to releases.
What's Changed
- [docs] Upgrade to Doxygen Awesome 2.3.4 by @calcmogul in #809
- Run wpiformat on all files by @calcmogul in #810
- Fix typos by @spacey-sooty in #805
- [choreolib] Fix issue with using reader twice in Java project file by @shueja in #815
- Fix typos by @calcmogul in #814
- Remove forcesAvailable item accidentally included in beta1 by @shueja in #817
- [docs] Fix nav bar and update ChoreoLib usage docs by @calcmogul in #813
- Change version to 2025.0.0-beta-2 by @shueja in #818
Full Changelog: v2025.0.0-beta-1...v2025.0.0-beta-2
Choreo v2025.0.0-beta-1
Choreo 2025
The SleipnirGroup team of developers is ready to release the open beta of Choreo for the 2025 season.
Thank you to all the teams that used Choreo in 2024 and shared your needs, struggles, and suggestions for improvement. Our work for 2025 has focused on many issues and enhancements.
General
Math Expressions with Variable and Unit Support:
This feature addresses a few struggles in 2024 Choreo:
- Default units (SI, radians) being inflexible, unintuitive, and forcing the user to convert by hand.
- No good way to define field constants or waypoint locations that are shared among all trajectories.
- No good way to define robot configuration in terms of other constants (i.e. bumper size and module placement in terms of frame size.
To improve user experience, we have replaced almost every number input in the application with mathematical expression inputs, powered by mathJS. MathJS has full dimensional analysis awareness, allowing inputs to be specified in whichever unit you like, and rejecting inputs that are not dimensionally correct. Choreo will also save the expression as you typed it, instead of evaluating and discarding it at the moment of submission.
Furthermore, Choreo allows you to define a project-wide set of variables that can be substituted into any appropriate expression in the project. Variables can be defined as single numbers with a variety of dimensions, but Choreo also has aggregate variables to organize the x, y, and heading components of an important pose.
The expression and variable features open up a wide range of capabilities, similar to parametric sketches in a CAD program. We’re excited to see how teams use these new tools.
Robot Config
Support for non-centered/non-rectangular modules
Choreo 2024 asked for a wheelbase, track width, bumper length, and bumper width. This described many robots, but especially in 2024, many robots had intakes that made the bumpers not centered at the center of rotation, or they had module placement that was not centered or even rectangular. Choreo 2025 makes robot configuration more flexible, permitting and honoring these configurations.
NOTE: due to path mirroring, Choreo 2025 still only supports module and bumper dimensions that are symmetric across the robot x-axis (the front-back line, meaning left-right mirror symmetry). In robot configuration, users only edit the left side of the robot dimensions.
The user interface design for robot configuration is an area of planned improvement.
Generation
Command-Line Generation
Choreo now ships with a command-line tool that takes in a .chor file and one or more associated .traj, and generates the .traj files, modifying them in-place. Further details will be described in the docs.
Fix Inability to Cancel Generation
This issue was inherent to the architecture of Choreo, but through the architecture changes related to command-line generation, we were able to make generation individually cancelable at any point.
(Proper) Continuous Heading Support
Choreo 2025 modifies the internal logic of the solver to handle robot rotation as a unit vector instead of an angle number. This allows Choreo to take the fastest rotational movement, even if it would previously wrap -pi to pi. Therefore, heading initial guesses are not as important to manually tweak.
Waypoints
Heading Initial Guess
Choreo 2025 removes the ability to set the heading initial guess on translation and empty waypoints. Due to the above improvements to the solver, and other logic implemented to automatically calculate heading initial guesses, the feature was unnecessary, counterproductive, and cluttered the UI.
Remove Initial Guess Points
Choreo 2025 removes the (non-constrainable) initial guess point waypoint type and subsumes its functionality into the Empty Waypoint, whose location can be constrained using Keep-In or Keep-Out Zones. The Empty Waypoint can be the endpoint of a path, but not the start point.
Individual Sample Override
Instead of a default sample override being applied to an entire path, with the same number of samples for each waypoint, Choreo 2025 has a checkbox on each waypoint to specify an individual override between that waypoint and the next.
Constraints
Interactive Constraint Overlay
The user interface for adding and editing constraints has been revised. Previously, a click target for adding a constraint was at every waypoint and the midpoint of every segment. Now, click one waypoint, then click the other, without the UI clutter.
When a constraint is selected, the field highlights the range it applies to. For constraints with additional field points/lines to modify (currently Point At and Keep In/Out Zones), the field will also display draggable field objects tied to the constraint.
The display also shows when hovering over the constraint in the sidebar.
Keep-In Zones/Field Border Constraint
Choreo 2025 adds a new type of constraint, which is a zone (currently rectangle or circle) that the robot must stay entirely inside, including the bumpers, for the duration of the constraint scope. For the first beta, a Keep-In Rectangle the size of the field will be part of new paths. If and when arbitrary (convex) polygons are supported as Keep-In zones, functionality will be added to add a polygon that better fits the field border.
Obstacles (Keep-Out Zones) as Constraints
Obstacles have been changed to be part of the constraints system and renamed to Keep-Out zones for consistency. While the solver still struggles in some obstacle setups, the ability to apply the constraint to only a section of the path makes the problem more feasible.
Toggleable Constraints
Choreo 2025 adds a checkbox to each constraint that allows the constraint to be disabled without being deleted. This can be useful for comparing the effects of individual constraints.
Generation Pre-checks/Feedback
Choreo 2025 expands the additional checks on the trajectory, performed before starting the solver, which are intended to identify conflicting constraints and other causes of infeasibility. New checks include:
- Verifying that Pose waypoints under Point-At constraints are compliant
- Verifying that 0 Max Angular Velocity constraints do not conflict with Pose waypoints with differing headings
- More to come!
Path Splitting
Splitting Paths
Splitting paths was previously done through a project-wide switch that made every Stop Point constraint be a path splitting point. In 2025, the Stop Point constraint is entirely separate from splitting. Every waypoint except for path endpoints has a checkbox which can be used to mark a waypoint as a split point. NOTE: Choreo does not enforce stopping at split points, but for most usage, adding a Stop Point constraint is still advised.
Artifacts
The releases now have many more artifacts than last year.
We support Windows arm64 and x86_64, MacOS aarch64 and x86_64, and Linux x86_64.
Users should normally be downloading the -setup installers for Windows, the .dmg for MacOS, and the AppImage, .deb for Debian and Ubuntu, or .rpm for Fedora.
For each platform, there is a separate executable for command-line generation. We hope to find a way to put the command-line functionality into the main Choreo app.
Finally, we have standalone executables. These are generated for potential bundling with WPILib 2025 and are not the recommended way of installing Choreo.
Choreolib
ChoreoLib 2025 Beta is compatible with WPILib 2024.
Python
ChoreoLib 2025 officially supports Python at PyPI (sleipnirgroup-choreolib). This is new for 2025.
C++/Java
For C++ and Java, the vendordep link is specific ...
Choreo v2025.0.0-alpha-3
[ci] Fix release executable upload (#798)