Skip to content

Releases: SleipnirGroup/Choreo

Choreo v2025.0.2

22 Jan 19:12
ef22708
Compare
Choose a tag to compare

This release brings critical fixes to ChoreoLib in all three languages and usability improvements in the UI. We also now build the UI and CLI for Linux aarch64.

New Tips and Tricks

  • Disable or delete the default field border Keep In Rect constraint on any paths that do not need it. Especially on simpler paths, it has been shown to significantly affect generation time. In this update, the constraint is disabled by default.

ChoreoLib Python

BREAKING: .chor files need to be saved in [project root]/deploy/choreo now. Docs here have been updated to match.

  • Fixed a bug with load_trajectory() requiring absolute paths. After doing the above file move, use the trajectory name alone, such as choreo.load_trajectory("testPath") to load [project root]/deploy/choreo/testPath.traj.

ChoreoLib C++

  • Fixed several compilation errors, so the C++ library is usable now.

ChoreoLib Java

  • Fixed behavior of AutoFactory.trajectoryCmd(...). It is now a command that requires the drivetrain, so can be used in sequence with resetOdometry as intended.
  • Fixed an issue with the AutoTrajectory.done() Trigger where it would sometimes not switch true at the end of the trajectory, especially when running the trajectory a second time.

Choreo GUI

  • Fixed a bug where a zero-max-angular-velocity constraint between a pose and translation waypoint would fail in a way that required manual correction beyond undoing that setup.
  • Fixed an issue with two identical waypoints in sequence, which would cause an error about "nonfinite cost or constraints". Both waypoints now constrain the same sample in the path. This situation is not recommended, but is intended to at least generate if the constraints are compatible.
  • Fixed an issue with variables that depend on other variables. This would cause a UI crash if the dependency variable was deleted. Now it shows the depending variable as an invalid input.
  • Variables in the variable panel are now visually sorted alphabetically, but still separated between standalone variables and pose variables.
  • Fixed an issue with the icons in the path list, where trajectories would be incorrectly shown as out-of-date upon opening a project.
  • Added a Generate All Outdated button above of the path list, next to the Add Path and Duplicate Path buttons.
  • The Keep In Rect constraint for the field borders is disabled in new paths. For paths that do not get near the wall, the constraint is an unnecessary performance hit.

File Format

No breaking changes. However, the .chor variables section is now always saved in alphabetical order by variable name. Previously it was nondeterministic and changed almost every time a variable was modified. This change should reduce lines changed in source control diffs.

What's Changed

New Contributors

Full Changelog: v2025.0.1...v2025.0.2

Choreo v2025.0.1

09 Jan 03:55
284d827
Compare
Choose a tag to compare

These notes will be replaced by a larger announcement post soon. The below is meant for users upgrading from 2025 beta.

ChoreoLib

ChoreoLib is now in the WPILib vendor dependencies panel, which is now the recommended way to install it. The vendordep URL https://lib.choreo.autos/dep/ChoreoLib2025.json.

There are no ChoreoLib changes between 2025.0.0 and 2025.0.1.

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 of 8.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.
  • AutoBindings
    • Removed from the AutoFactory constructor and made package-private.
    • Use AutoFactory.bind(String eventName, Command command) instead, which now returns the AutoFactory for chaining.
  • AutoTrajectory.resetOdometry() is added, as a replacement to AutoRoutine.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.

Choreo v2025.0.0

06 Jan 05:29
97962cb
Compare
Choose a tag to compare
Choreo v2025.0.0 Pre-release
Pre-release

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 of 8.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.
  • AutoBindings
    • Removed from the AutoFactory constructor and made package-private.
    • Use AutoFactory.bind(String eventName, Command command) instead, which now returns the AutoFactory for chaining.
  • AutoTrajectory.resetOdometry() is added, as a replacement to AutoRoutine.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

Full Changelog: v2025.0.0-beta-9...v2025.0.0

Choreo v2025.0.0-beta-9

20 Dec 05:29
4edab1b
Compare
Choose a tag to compare
Pre-release

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

19 Dec 07:14
2a73934
Compare
Choose a tag to compare
Pre-release

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 return Optional<Pose2d> instead of a potentially null Pose2d. This matches prior behavior of the other two languages (C++ with std::optional and Python with returning None)
  • [C++] Trajectory::GetInitialState() is now GetInitialSample().
  • [Java, C++] Trajectory.getInitialSample()/GetInitialSample() and getFinalSample()/GetFinalSample() now take a boolean 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 load AutoTrajectories, instead of AutoFactory.trajectory(String name, AutoRoutine routine).
  • Trigger AutoRoutine.observe(BooleanSupplier condition) has been added. This can be used to create Triggers that are part of the AutoRoutine 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 now choreo.auto.AutoRoutine.
    • AutoFactory.newLoop() and voidLoop() were renamed to newRoutine() and voidRoutine().
  • 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 with AutoRoutine.active().
  • AutoLoop.poll() will return immediately if the alliance is needed for flipping and not known. This is the same behavior as if poll() 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 the done() trigger.
  • AutoTrajectory.getInitialPose() and getFinalPose() will now return Optional.empty() if alliance flipping is enabled and the alliance is not known.
  • Removed AutoTrajectory.atTimeAndPlace(). Use trajectory.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 to atPose() but accepts Translation2ds.
  • AutoTrajectory.atPose(...) and atTranslation(..) 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 an ArrayList<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 or DifferentialSample, not an additional Pose2d for the current pose.
  • AutoFactory.clearCache() was replaced with AutoFactory.cache().clear() since the user can now access the trajectory cache.
  • A new parameter Consumer<Pose2d> resetOdometry has been added. This is used with AutoTrajectory to create a Command that calls the resetOdometry callback with the first pose of
  • trajectoryCommand() has been renamed to trajectoryCmd()
  • trajectoryLogger is no longer an Optional. It is a no-op if left unspecified.

AutoChooser

  • AutoChooser now implements Sendable, so can be logged with SmartDashboard.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.
  • AutoChooser's options are now functions that consume nothing and return an AutoRoutine or a Command. It is expected that users will call to their AutoFactory 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 a Sendable, 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() or Command selectedCommandScheduler().

  • The former is the analogue to the SendableChooser approach of getting the selected command and directly scheduling it in autonomousInit().
  • The latter returns a deferred Command. Use this if binding autonomous commands to run on autonomousInit() with RobotModeTriggers.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> and Supplier<Optional<Pose2d>> instead of Pose2d in many places, to better represent poses that depend on the currently selected alliance.
  • AutoFactory/Choreo.createAutoFactory no longer take a BooleanSupplier mirrorTrajectory that returns true when trajectories should be flipped. Instead they take a BooleanSupplier useAllianceFlipping to enable alliance-based flipping in general and a separate Supplier<Optional<Alliance>> that defaults to DriverStation::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...
Read more

Choreo v2025.0.0-beta-6

19 Oct 02:27
5c8d164
Compare
Choose a tag to compare
Pre-release

What's Changed

Full Changelog: v2025.0.0-beta-5...v2025.0.0-beta-6

Choreo v2025.0.0-beta-5

15 Oct 18:17
9d2c6e5
Compare
Choose a tag to compare
Pre-release

What's Changed

Full Changelog: v2025.0.0-beta-4...v2025.0.0-beta-5

Choreo v2025.0.0-beta-4

15 Oct 03:38
c0ae10b
Compare
Choose a tag to compare
Pre-release

This is the first release that requires the WPILib 2025 beta and 2025 roboRIO image.

What's Changed

Full Changelog: v2025.0.0-beta-3...v2025.0.0-beta-4

Choreo v2025.0.0-beta-3

12 Oct 06:44
6b63ad6
Compare
Choose a tag to compare
Pre-release

This is the last release that supports WPILib 2024.

Event Markers

Event markers have now been added.
image
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:
image
After:
image
With variable tolerance:
image
Across multiple waypoints:
image

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.
image

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.

image

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

02 Oct 21:54
721ea59
Compare
Choose a tag to compare
Pre-release

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

Full Changelog: v2025.0.0-beta-1...v2025.0.0-beta-2