This addresses a race condition caused by TimedRobot and other
frameworks not creating their first notifier alarm until after signaling
program start.
Default this to true because it's the most common desired use case when
combined with TimedRobot.
The FTC DS had a deadband. Additionally, the FRC one had an implicit
deadband due to the only 8 bit resolution. We need a deadband by default
now with the high resolution gamepads.
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>
The initial build file generation for robotpy projects was relatively
naive and purpose built to get `allwpilib` compiling, without supporting
all the available features.
This modifies the generation scripts to be able to support multiple
embedded libraries, which will be necessary for #8858, since `mrclib.so`
will need to be bundled along with the hal libraries. In addition some
cleanup was done to get the wheels looking more like what is in pypi.
This provides the ability to simulate parts of the Onboard IMU at the
HAL level. This allows team to use and simulate the IMU in code, and a
follow up PR could be made to the halsim_gui to add a new widget to view
and modify the data graphically.
Since the C++ IMU uses radians for angles that is what I did for the
simulator.
Partially deals with #8845
Right now, the `zipBaseName` variable in various publish.gradle files
contains the group ID and artifact ID for use by the combiner, however,
they are also duplicated in `artifactGroupId` and `baseArtifactId`,
leading to potential mistakes if they aren't updated together. This
fixes that by adding a new utility function `makeZipBaseName` to
automatically create the right name given a group ID and artifact ID.
This also fixes publishing for thirdparty subprojects, which didn't
update `zipBaseName`.
People generally have expressed a dislike for the Hungarian notation
used in member variables, especially in examples/templates, and our
styleguide shouldn't be forced on downstream consumers, so this removes
all Hungarian notation from the examples/templates.
There are _some_ benefits to Hungarian for private member variables
(like knowing what's a member vs. local in a PR review) so we'll keep
private member variables the same for now, but public variables should
no longer use Hungarian notation, since it looks much worse. A new PMD
XPath rule has been added to accomplish this goal. Some other
non-compliant variables were fixed for the new rule.
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.
This removes the confusion of the `ExpansionHubServo` class serving both
purposes, and thus having a `set` method that functions as `setPosition`
when in servo mode and `setThrottle` when not in continuous mode. It
also removes the `setContinuousRotationMethod` which could be confused
for a method that switches the actual servo firmware itself from servo
to continuous mode, which is not a thing that is physically possible I
think.
---------
Signed-off-by: Zach Harel <zach@zharel.me>
Part of the `semiwrap` process that hasn't been ported over yet is
generating pyi stubs. It is possible to not have your semiwrap setup
correctly and "leak" native types into the generated python docstrings,
which causes the process to
[fail](https://github.com/pjreiniger/mostrobotpy/actions/runs/24618640845/job/71985311682#step:12:3652).
semiwrap also has a tool you can run, 'create-imports' that will read
the symbols from a build pybind library and automatically create and
sort the imports in the `__init__.py` file. This step is not enforced by
CI, which is why it hasn't been failing in `mostrobotpy` land.
This PR fixes the stubgen problems and runs reorganizes the imports. I
will have a follow up PR that can bring these automatically into the
build system after this lands. I'd do a fancy new `gh stack` but I can't
figure out if it works on forks.
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.
Clang 21 catches returning `0` from `GetOpMode` as returning `null`.
Since this state is very momentary and all comparisons inside WPILib are
done against `GetOpModeId` instead, I changed it to return an empty
string.
1. Make the OpMode interface itself periodic; this means the only
differences between `OpMode` and `PeriodicOpMode` are the latter's
methods to add sideloaded periodic callbacks
2. Make OpModeRobot process callbacks in a similar fashion to TimedRobot
and
3. Add some lifecycle functions (discussed below)
4. Pull the callback priority queue from TimedRobot to a new class
called `PeriodicPriorityQueue` so that `TimedRobot` and `OpModeRobot`
have less duplication
5. Fix a typo in the DriverStationJNI class that causes a memory leak
when certain driver station sim calls
6. Port the C++ OpModeRobot tests to Java
`OpModeRobot` now possesses some `IterativeRobotBase`-stye lifecycle
functions; these functions
1. `robotPeriodic`
2. `simulationInit` and `simulationPeriodic`
3. `disabledInit`, `disabledPeriodic`, and `disabledExit`
(note that `simulationInit` and `disabledInit` may be renamed to match
wpilibsuite#8719)
`OpModeRobot` also now processes `OpMode` changes (by the Driver
Station) in its `loopFunc` method, similar to
`IterativeRobotBase.loopFunc` processing game mode changes; `loopFunc`
is, similarly to `TimedRobot`, provided as a default `Callback`
---------
Signed-off-by: Zach Harel <zach@zharel.me>
Co-authored-by: Joseph Eng <91924258+KangarooKoala@users.noreply.github.com>
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();
}
}
```
`Color::FromHSV` didn't match the Java `Color.fromHSV` in some saturated
edge cases, introducing an off-by-one error when the HSV color should
correspond complete saturation of one or two of the primary colors.
Example:
- Java: `Color.fromHSV(0, 255, 255) -> (255, 0, 0)`
- C++: `Color::FromHSV(0, 255, 255) -> (255, 1, 1)`
This also means the following methods are also transitively affected:
- `AddressableLED::LEDData::SetHSV`
- `LEDPattern::Rainbow`
This off-by-one error is introduced by a rounding error from the chroma
calculation, which was dividing by 256 rather than the appropriate
maximum value of 255 like in Java:
7ca35e5678/wpilibj/src/main/java/edu/wpi/first/wpilibj/util/Color.java (L176-L177)
Also port appropriate tests from Java to C++ to catch this bug.
I found this bug when I tried to port `AddressableLEDBuffer` to RobotPy.
Codex found the root cause :)
Since sched_setscheduler() requires non-RT priorities to be 0, we can
use that as a sentinel value for disabling RT and condense the Java API
to just two functions with fewer parameters. The thread priority setter
is deprecated since only experts should use it.
The HAL Notifier thread priority setter was replaced with setting the
priority in the thread itself.
The C++ Notifier non-RT and RT constructors were deduplicated.
The real-time scheduler was changed from SCHED_FIFO to SCHED_RR, which
is SCHED_FIFO with threads allowed to run for a maximum time quantum
before yielding (100 ms by default).