46 Commits

Author SHA1 Message Date
Thad House
5a7d7d50ee [wpilib,cmd] Remove Axis from Gamepad Triggers (#8956)
It's a bit confusing, especially since some controllers will have this be
a 0:1 button rather than axis.
2026-06-12 06:42:06 -07:00
Thad House
97381549e6 [wpilib,cmd] Add new generation for gamepads (#8957)
SDL makes these schemas much simpler, so its easier to support more
controllers.
2026-06-11 16:06:45 -07:00
Thad House
c647e67de0 [wpilib,cmd] Cache HID wrappers (#8970)
Store DriverStation-owned GenericHID and Gamepad instances in Java and
C++, and expose the cached objects to Python bindings.

Move hand-written command gamepad and joystick wrappers to compose
cached CommandGenericHID instances plus typed HID wrappers, including a
Python CommandGamepad.

This will let us remove UserControls, while helping ensure that we don't
have state smashing between GenericHID objects.

Another bonus is without inheritance, intellisense will no longer show a
bunch of annoying methods, and instead just what actually exists.

---------

Co-authored-by: Peter Johnson <johnson.peter@gmail.com>
2026-06-11 09:42:39 -07:00
Peter Johnson
96fb033deb [build] Remove cmake Java support (#8952)
This is increasingly difficult to maintain, and has very limited
benefit. Modern coprocessors with enough horsepower to run Java
applications can use the Gradle or Bazel build systems instead.
2026-06-05 15:05:09 -07:00
Thad House
b100586cab [wpilib] Finish gamepad face button rename (#8921) 2026-05-26 21:55:07 -07:00
Sam Carlberg
94fda36e04 [cmd3] Add trigger multi press and continuous bindings (#8901)
`Trigger.multiPress(N, T)` creates a trigger that fires when there are
at least N rising edges within the last T timespan, eg `multiPress(3,
Seconds.of(1.25))` for 3 rising edges within the last 1.25 seconds.

`Trigger.retryWhileTrue` and `retryWhileFalse` will continuously attempt
to schedule a command while the binding condition is met. This is
similar to `whileTrue` and `whileFalse`, but will reschedule the command
if it ends or is canceled while the binding condition is still met,
rather than requiring a new rising edge to reschedule it.
2026-05-23 16:51:45 -07:00
Sam Carlberg
f217dfe747 [cmd3] Make sideload functions scoped and improve docs (#8900)
Notably, this removes the ability to escape command scoping by using a
sideloaded function to schedule another command
2026-05-23 16:50:46 -07:00
Daniel Chen
e35ca772fd [cmd3] Make Mechanism an interface (#8303)
Since there is no longer a requirement for Subsystems/Mechanisms to be
registered to the command scheduler via a register() call, Mechanism can
be changed to an interface instead to allow for more flexible
inheritance structures.

Specifically, this would allow compatibility with CTRE swerve (which
previously required implementing Subsystem so that it could extend
CTRE's base class).
2026-05-18 19:30:12 -05:00
Thad House
fa24446ce3 [wpilib,cmd] Rename gamepad face-button trigger APIs to directional names (faceUp/Down/Left/Right) (#8896)
This updates gamepad trigger naming from cardinal-style face buttons
(`northFace/southFace/eastFace/westFace` and
`NorthFace/SouthFace/EastFace/WestFace`) to directional naming
(`faceUp/faceDown/faceRight/faceLeft` and
`FaceUp/FaceDown/FaceRight/FaceLeft`) to match the requested API shape.
The change is applied across Java and C++ HID/command layers, along with
related examples and binding metadata.

- **API surface updates (Java)**
  - Renamed trigger/event methods in:
    - `wpilibj` `Gamepad`
    - `commandsv2` `CommandGamepad`
    - `commandsv3` `CommandGamepad`
  - Mapping preserved:
    - `southFace` → `faceDown`
    - `eastFace` → `faceRight`
    - `westFace` → `faceLeft`
    - `northFace` → `faceUp`

- **API surface updates (C++)**
  - Renamed trigger/event methods in:
    - `wpilibc` `Gamepad`
    - `commandsv2` `CommandGamepad`
  - Mapping preserved:
    - `SouthFace` → `FaceDown`
    - `EastFace` → `FaceRight`
    - `WestFace` → `FaceLeft`
    - `NorthFace` → `FaceUp`

- **Python semiwrap updates**
- Updated `wpilibc/src/main/python/semiwrap/Gamepad.yml` method mappings
to the renamed C++ method names (`FaceDown/FaceRight/FaceLeft/FaceUp`).

- **Callsite migration**
- Updated Java examples/template code and C++ examples/template code to
use the new method names so samples remain aligned with the API rename.

- **Docs/comments alignment**
- Updated related Javadoc/reference text and example comments to use
directional terminology.

```java
// Before
driverController.southFace().onTrue(command);
driverController.eastFace().onTrue(command);

// After
driverController.faceDown().onTrue(command);
driverController.faceRight().onTrue(command);
```

```cpp
// Before
driverController.SouthFace().OnTrue(command);
driverController.EastFace().OnTrue(command);

// After
driverController.FaceDown().OnTrue(command);
driverController.FaceRight().OnTrue(command);
```

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ThadHouse <7727148+ThadHouse@users.noreply.github.com>
2026-05-15 00:08:57 -05:00
Ryan Blue
878da3d54c [cmd3] Fix StateMachineTest (#8876) 2026-05-07 21:42:16 -07:00
Sam Carlberg
1021ff88a9 [cmd3] Add a declarative state machine API on top of commands v3 (#8297)
This provides an API for writing a finite state machine compatible with
the commands v3 framework. Individual states in the state machine are
wrappers around command objects (which may themselves be state
machines). Transitions between states are defined with a staged builder
DSL similar to command builders, and uses `@NoDiscard` to catch
partially configured transitions.

The FSM API is meant to handle highly complex cases that the fluent
command chaining DSL and coroutine-based imperative commands cannot
easily represent; specifically, where a command sequence may want to go
back to an arbitrary previous state or skip forward to an arbitrary
future state.

Here's an example from the design doc for a command that will drive to a
known scoring location, aim at a scoring target, and repeatedly shoot
balls until a storage hopper is empty. It also has conditions to stop
shooting and move back to the scoring location if it's jostled away, and
then automatically resume firing.

```java
public Command autoWithStateMachine() {
  // Declare the state machine
  StateMachine stateMachine = new StateMachine("Auto With State Machine");

  // Define states
  State getInPosition = stateMachine.addState(drivetrain.driveToScoringLocation());
  State aiming = stateMachine.addState(turret.aimAtGoal());
  State scoring = stateMachine.addState(shooter.fireOnce());
  State celebrating = stateMachine.addState(leds.celebrate());

  // Set the initial state. Neglecting this will cause a runtime exception when the state machine starts.
  // Teams using the WPILib compiler plugin will get a compiler error if they do not set this
  stateMachine.setInitialState(getInPosition);

  // Switch to aiming when we reach the scoring location.
  getInPosition.switchTo(aiming).whenComplete();
  // Set the swerve wheels in an X shape after reaching the scoring location to resist being pushed away.
  getInPosition.onExit(() -> Scheduler.getDefault().fork(drivetrain.setX()));

  // Then start scoring once the turret is aimed at the goal.
  aiming.switchTo(scoring).when(turret::aimedAtGoal);

  // Loop the scoring state as long as the hopper has a ball.
  scoring.switchTo(scoring).whenCompleteAnd(() -> hopper.hasBall());

  // Automatically interrupt any part of the aiming or scoring sequence if
  // the robot is moved away from the scoring location and move back into position.
  stateMachine.switchFromAny(aiming, scoring).to(getInPosition).when(atScoringLocation.negate());

  // Start celebrating once the final ball has been scored.
  scoring.switchTo(celebrating).whenCompleteAnd(() -> !hopper.hasBall());

  return stateMachine;
}
```

A compiler check is added to detect object construction that's not
followed by post-construction initializer methods (as defined by the
class by placing `@PostConstructionInitializer` on such methods).
`StateMachine.setInitialState` uses this to detect team code that
creates a state machine but does not set its initial state.
2026-05-07 20:08:09 -07:00
Sam Carlberg
62e0bc515c [cmd3] Add rising and falling edge trigger factories (#8366)
`Trigger.getAsBoolean()` behavior has been changed from passing through
the underlying boolean supplier to returning the latest cached signal as
determined by the most recent call to `poll()`. This allows rising and
falling edge triggers to have a consistent return value over an entire
polling cycle, rather than only being high for the _first_ check in a
cycle.

Closes #8309
2026-05-07 16:32:34 -07:00
sciencewhiz
880cfd60c4 Update vendordeps wpilibYear to alpha 5 (#8817) 2026-04-25 21:15:54 -07:00
PJ Reiniger
e7e51c9c05 [bazel][ci] Add CI action to generate pregen patch (#8816)
There were complaints about no patch files being created from CI when
the examples pre-gen fails for people who don't build with bazel. This
adds a new action step to run just the non-robotpy pregen.

I also added an argument to the diff tests to make it a unified diff,
which might make it easier to hand fix.
2026-04-25 11:06:02 -07:00
Peter Johnson
ab00aac960 [hal,wpilib] Rename "Test" robot mode to "Utility" (#8782)
The "Utility" name better matches its intended generic use case and
avoids overloaded terminology with unit testing (e.g. the need to name
the opmode annotation `@TestOpMode`).

The driver station will also be updated to reflect this change.
2026-04-20 20:29:25 -07:00
Sam Carlberg
b7df267687 [cmd3] Change Command.noRequirements to accept a command implementation (#8783)
This is more ergonomic than `Command.noRequirements().executing(...)`
2026-04-19 15:40:50 -07:00
Thad House
ab2aef2c29 [wpilib] Split DriverStation into smaller classes (#8628) 2026-04-18 19:56:45 -07:00
Sam Carlberg
628ba1458f [build] Java 25 support (#8775)
Commands v3 had a few changes due to the upgrade:
- Java 24 removed the Pinned: MONITOR IllegalStateException when
yielding in a synchronized block, so we no longer need to special case
for it
- Lambda method name generation was tweaked, requiring tests to be
updated
- Bazel java_rules needed to be bumped to support Java 25

Closes #8425
2026-04-16 21:02:17 -07:00
Gold856
f96ded6909 Fix various typos (#8769) 2026-04-13 21:51:36 -07:00
Tyler Veness
7af3ac579b [build] Upgrade Gradle wrapper and plugins (#8767)
This fixes builds on JDK 26 for me.
2026-04-12 22:03:50 -07:00
PJ Reiniger
c6f54e963c [build] Fixup maven publishing (#8753)
This primarily fixes up the bazel publishing to match the gradle
publishing again, as some new libraries were added but not hooked up to
the maven publishing.

During the process, I noticed that the 3rd party libraries (googletest,
catch2, and imgui_suite) were still getting published on the old
`edu.wpi` namespace. I tried to clean up all the other references to
that that I could. Note: opencv and libssh are handled outside
`allwpilib` so they need to be updated separately.
2026-04-11 13:52:43 -07:00
Joseph Eng
d8df358e6a [cmd3] Update Scheduler class doc description of run() (NFC) (#8747)
#8705 updated the `run()` doc comment but missed the class doc comment.
2026-04-10 16:14:54 -07:00
Sam Carlberg
02c6030251 [cmd3] Enforce command lifetimes across all opmode and command scopes (#8705)
Commands are no longer able to outlive their schedule-site's scope,
regardless of how they were scheduled (set as a default command, bound
to a trigger, or manually scheduled)

As a consequence, default commands need better tracking so the default
command setting can be released when their scope exits and the next-most
appropriate default command can be rescheduled (eg, an opmode sets a
default command, then the globally-scoped default is restored when the
opmode exits). Some complexity is required here to make it work well for
edge cases.

Like `schedule()`, `setDefaultCommand()` will immediately start the new
default command if called inside of another command to avoid 1-loop
delays. However, this does not apply when called by the _current_
default command, as it would result in attempting to cancel the default
command while it's mounted (which is impossible and would throw an
exception)

```java
class Robot extends OpModeRobot {
  final Drive drive = new Drive();
  final CommandXboxController controller = new CommandXboxController(1);

  public Robot() {
    // global default command, active unless overridden in an opmode or command
    drive.setDefaultCommand(drive.stop());

    // global trigger binding, always active
    controller.rightBumper().onTrue(drive.setX());
  }
}

@Teleop
class ExampleOpMode extends PeriodicOpMode {
  public ExampleOpMode(Robot robot) {
    // opmode-specific default command
    robot.drive.setDefaultCommand(robot.drive.operatorControl(robot.controller));

    // opmode-specific binding
    robot.controller.leftBumper().whileTrue(robot.drive.stop());

    // opmode-specific binding that takes precedence over the global binding
    // because it happens last; it "wins out" over the `setX()` binding
    robot.controller.rightBumper().onTrue(robot.drive.selfTest());
  }

  @Override
  public void periodic() {
    Scheduler.getDefault().run();
  }
}
```
2026-04-09 17:05:42 -07:00
Peter Johnson
a57d658ef1 [wpilib] Rename GenericHID and Gamepad enums to all caps
GenericHID.getSupportedOutputs(): Return EnumSet
Gamepad: Add Button-taking accessors
2026-03-21 00:37:28 -07:00
Peter Johnson
227f01f3bd [hal,wpilib] Rename DriverStation constants to all caps 2026-03-15 22:38:09 -07:00
Thad House
b2b111dc11 Rename FRC to WPILib (#8637) 2026-03-13 23:05:55 -07:00
Thad House
880ffe94f2 [wpiutil] Remove CombinedRuntimeLoader (#8623)
It was only ever for Java tools, which we do not support anymore.
2026-02-27 20:15:17 -08:00
Sam Carlberg
793b0a3187 [build] Migrate to Gradle version catalogs (#8524)
Also fixes the google compile-testing library to 0.23.0 (the latest
available at time of writing) instead of a wildcard

Jackson versions were inconsistent across projects; most were on 2.19.2,
but the fields subproject was on 2.15.2. All projects are now on 2.19.2
for consistency
2026-02-20 15:31:33 -08:00
Thad House
4aa21e947d [wpilib,cmd] Rename gamepad shoulder to bumper (#8573)
Both programs used bumper, so we shouldn't rename it. There's no reason
to change it, and we don't need to match SDL.
2026-02-07 10:39:22 -08:00
Thad House
5c5d5222f4 [wpilib] Prefix all NI DS specific controller classes (#8596)
Easier then the last one that put everything in a sub namespace. By
prefixing the name less things break, and intellisense will be less
confusing to new users during the transition.
2026-02-06 21:36:01 -08:00
Sam Carlberg
7cb58962c5 [cmd3] Scope scheduled commands to the running opmode, if one exists (#8492)
This prevents commands from outliving the opmodes in which they were
scheduled
2025-12-16 22:24:58 -08:00
Sam Carlberg
6ef55654f6 [cmd3] Fix commandv3 builders and add tests (#8482)
Sequential group builder had an inverted if condition causing NPEs

Parallel group builder was building parallel groups using an old ctor
signature and creating groups that didn't match what was specified in
the builder

Test coverage has been added for both builder types
2025-12-16 22:23:04 -08:00
Sam Carlberg
44cf645632 [epilogue] Fix v3 scheduler incompatibility with epilogue (#8458)
Was caused by checking assignability like`Protobuf<Scheduler,
ProtoMessage>` instead of `Protobuf<Scheduler, ? extends
ProtoMessage<?>>`

This epilogue bug would have also applied to other protobuf-serializable
types
2025-12-06 22:38:10 -08:00
sciencewhiz
ccfbf5f5b3 [commands] Add conflicts for Commands v2 & v3 vendordeps (#8438) 2025-11-30 11:12:12 -08:00
Tyler Veness
7a04d6a6a2 Merge wpiformat configs (#8365)
After replacing the remaining include guards with `#pragma once`, I was
able to merge all the wpiformat configs into one file in the repo root.
This should make the config easier to reason about and maintain in the
future.
2025-11-11 22:00:42 -08:00
Peter Johnson
18efd1e534 Move robot base classes from opmode to framework (#8344)
Having these in opmode will be confusing to users when opmodes are added.
2025-11-08 15:08:38 -08:00
PJ Reiniger
c48b722dac SCRIPT: Spotless Apply 2025-11-07 23:09:21 -08:00
PJ Reiniger
108a8c0f9b SCRIPT: Pregenerate files 2025-11-07 23:09:21 -08:00
PJ Reiniger
e0320a942a HAND FIX - Fixup pregen files 2025-11-07 23:09:21 -08:00
PJ Reiniger
6b69aab44e HAND FIX - Fixup bazel files 2025-11-07 23:09:21 -08:00
PJ Reiniger
f0a3c64121 SCRIPT Run java package replacements 2025-11-07 23:09:21 -08:00
PJ Reiniger
c350c5f112 SCRIPT Move java files 2025-11-07 23:09:21 -08:00
Sam Carlberg
8992cf7081 [javac plugin] Add compile-time checks for unsafe or incorrect coroutine usage (#8289)
CoroutineYieldInLoopDetector

This checks for while loops where coroutines are in scope but without calling a blocking method on at least one of those coroutines:

```
drivetrain.run(theCoroutine -> {
  while (drivetrain.getDistance() < 10) { // ERROR: "Missing call to `theCoroutine.yield()` inside loop"
    drivetrain.setSpeed(1);
  }
});
```

Note that, because we assume most looping constructs in commands will use while loops, we don't check for-loops, for-each loops, or do-while loops.

This check can be disabled with `@SuppressWarnings("CoroutineYieldInLoop")`

CodeAfterCoroutineParkDetector

Essentially acts like the Java compiler's check for code after a while (true) loop, but for coroutine.park():

```
drivetrain.run(theCoroutine -> {
  drivetrain.setSpeed(1.0);
  theCoroutine.park();
  drivetrain.setSpeed(0.0); // ERROR: "Unreachable statement: `theCoroutine.park()` will never exit"
});
```

This check can be disabled with `@SuppressWarnings("CodeAfterCoroutinePark")`

IncorrectCoroutineUseDetector

Checks for usage of captured (outer) coroutine parameters and assignments to fields.

```
drivetrain.run(outer -> {
  outer.await(arm.run(inner -> {
    outer.yield(); // ERROR: "Coroutine `outer` may not be in scope. Consider using `inner`"
  }))
});
```

This check can be disabled with `@SuppressWarnings("CoroutineMayNotBeInScope")`

```
private Coroutine coroutineField;
drivetrain.run(co -> coroutineField = co); // ERROR: "Captured coroutines may not be stored in fields"
```

This check can be disabled with `@SuppressWarnings("CoroutineCapture")`
2025-11-01 17:27:08 -07:00
Thad House
4da2511638 [cmd3,wpilib] Add CommandGamepad for V3 commands (#8311)
Also fix typo.

Co-authored-by: Dan Katzuv <31829093+katzuv@users.noreply.github.com>
2025-11-01 09:24:22 -07:00
Thad House
bd2cecbb1a [cmd3] Correct the groupId for commands v3 in the JSON (#8306) 2025-10-26 00:08:42 -07:00
Sam Carlberg
b37e2d9343 [commands] Add Commands v3 framework (#6518)
The framework fundamentally relies on the continuation API added in Java 21 (which is currently internal to the JDK). Continuations allow for call stacks to be saved to the heap and resumed later.

The async framework allows command bodies to be written in an imperative style. However, an async command will need to be actively cooperative and periodically call coroutine.yield() in loops to yield control back to the command scheduler to let it process other commands.

There are also some other additions like priority levels (as opposed to a blanket yes/no for ignoring incoming commands), factories requiring names be provided for commands, and the scheduler tracking all running commands and not just the highest-level groups. However, those changes aren't unique to an async framework, and could just as easily be used in a traditional command framework.
2025-10-10 13:47:22 -07:00