Compare commits

...

956 Commits

Author SHA1 Message Date
Thad House
0662a78892 [sim] GUI: Fix buttons starting at 1 instead of 0 (#8987)
Closes #8986
2026-06-17 14:39:14 -06:00
Benjamin Hall
c35df58a81 [wpilibc] Change DriverStationSim to use wpi::hal::RobotMode (#8988)
The `RobotState::GetRobotMode()` API returns this enum class, but
`DriverStationSim` was using the `HAL_RobotMode` enum instead. This
commonizes the two APIs to return the same `RobotMode` enum class.

This difference in the APIs also affected Python, as the `hal.RobotMode`
and `hal._wpiHal._RobotMode` types are not compatible with each other.
2026-06-17 14:38:13 -06:00
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
d6fb871a26 [ci] Build bazel builds in docker (#8978)
Needed for mrclib, as mrclib is built on a trixie image.
2026-06-12 05:59:21 -07:00
Thad House
489b993e60 [hal,wpilib] Switch CANBusMap to Enum, use it for CAN API (#8977)
Will make it easier to solve
https://github.com/wpilibsuite/SystemcoreTesting/issues/286
2026-06-11 16:14:40 -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
025732093f [wpilib] Remove UserControls (#8973)
It was too complex, and we can solve it by figuring out how to make
singleton GenericHID objects, implemented in #8970.
2026-06-11 15:33:51 -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
Zach Harel
fe499ede4c [build] Update avaje to 3.14 (#8974)
This fixes inherited and generic fields and getters.

Signed-off-by: Zach Harel <zach@zharel.me>
2026-06-10 23:50:01 -07:00
Gold856
3f966aa7c6 Clean up unused includes (#8950) 2026-06-09 22:16:26 -07:00
Thad House
72d85be0c2 [ntcore] Add API to get and set user data on NT_Topic (#8962)
Theres many uses where we need to attach data to a topic, and doing it
this way can make it really easy and efficient.
2026-06-08 19:24:15 -07:00
PJ Reiniger
111130d8bb [copybara] Sync with robotpy (#8964)
GitOrigin-RevId: 9dff8f977401e78be0bb6f39cea2328320ab2d95
2026-06-08 19:22:48 -07:00
Thad House
0213ecf382 [build] Update native utils, to switch to new compilers (#8966) 2026-06-08 19:21:33 -07:00
Zach Harel
bdd45c7365 [cmd2] Move .cpp files to subproject source root (#8967)
This matches all of the other subprojects.

Signed-off-by: Zach Harel <zach@zharel.me>
2026-06-08 19:20:48 -07:00
David Vo
44501bf5eb [bazel] Update rules_cc with patches (#8969)
@AustinSchuh's `rules_cc` patches have all been merged upstream. This
updates `rules_cc` to include the relevant patches, removing the need to
patch it here.

This also squashes this warning on every build:

> WARNING: For repository 'rules_cc', the root module requires module
version rules_cc@0.2.13, but got rules_cc@0.2.14 in the resolved
dependency graph. Please update the version in your MODULE.bazel or set
--check_direct_dependencies=off
2026-06-08 19:20:03 -07:00
Thad House
1be5da5bde [wpiutil] Fix Handle.hpp not including cstddef (#8965) 2026-06-07 16:08:11 -07:00
Thad House
06fb36ba8e [hal] Switch IMU to mrclib (#8961) 2026-06-06 16:30:08 -07:00
Thad House
71ed28f768 [hal] Switch SmartIO to mrclib (#8960) 2026-06-06 14:54:49 -07:00
Peter Johnson
edf77fa007 [hal,sim] Add notifier generation counter to WaitForProgramStart (#8947)
This fixes simulation WaitForProgramStart(true) potentially advancing
due to a stale or pre-start notifier created before SetProgramStarted()
was called.
2026-06-06 12:17:14 -07:00
Thad House
6e5171cd8f [hal] Use MrcLib to talk to DS (#8858)
Using MrcLib on the robot is going to be the plan for the future, to
make things easier.

MrcLib is how sim is supported going forward. The desktop version of
mrclib can act as a robot server.

This is set up where the mrclib interface is in shared code. On robot,
that is the only backend used. On desktop, a default sim backend is
used. However, the sim plugin can switch that to the real robot backend,
so the robot code will exactly look like a real robot.
2026-06-06 12:15:17 -07:00
Peter Johnson
ddf9306264 [ntcore] Fix a couple of bugs in NetworkOutgoingQueue (#8953)
Fix SetPeriod() valuePos handling when an ID moves between period queues

In SendValue(), don't append older values, and fix the total size
accounting for the underflow case when a smaller value replaces a larger
value.

Add comprehensive unit tests.
2026-06-05 20:35:11 -07:00
Peter Johnson
88d8369751 [upstream_utils] Update catch2 to 3.15.0 (#8955) 2026-06-05 20:34:20 -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
Vasista Vovveti
d941be905e [ntcore] NetworkClient: Add IsLoopClosing() guard in deferred disconnect timer (#8936)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 15:01:44 -07:00
Peter Johnson
e085c3e8b3 [examples,cscore] Don't use assertTimeoutPreemptively in tests (#8951)
Particularly with short timeouts, this results in spurious failures
under high CPU load.
2026-06-05 07:28:51 -07:00
Sam Carlberg
98c03baf54 [javac] Add compiler check for integer division in floating-point contexts (#8885)
Useful for catching bad behavior when doing math or configuring ratios
with integers. Errors can be turned off with
`@SuppressWarnings("IntegerDivision")`

```java
double kV = 12 / 6000; // error: integer division in a floating-point context
double kV = 12. / 6000; // OK
double kV = 12 / 6000.; // OK

int kV = 12 / 6000; // OK, but evaluates to 0

double ratio = 42 / 12; // error: integer division in a floating-point context

@SuppressWarnings("IntegerDivision")
double ratio = 42 / 12; // OK, evaluates to 2
```

```
Execution failed for task ':developerRobot:compileJava'.
> Compilation failed; see the compiler output below.
  /Users/sam/code/wpilib/allwpilib/developerRobot/src/main/java/wpilib/robot/Robot.java:10: error: integer division in a floating-point context
    double kV = 12 / 6000;
                   ^
  1 error
```

Also adds the compiler plugin as a dependency to the developerRobot
project for dev testing
2026-06-04 21:56:22 -07:00
sciencewhiz
8353b95507 Add avahi license to ThirdPartyNotices (#8883) 2026-06-04 21:54:00 -07:00
Benjamin Hall
a41679854b [wpimath] Fix C++ Odometry ResetRotation missing a negation (#8949)
The original implementation was `m_gyroOffset + (rotation -
m_pose.Rotation())`, which means the first `RotateBy` should be using
`-m_pose.Rotation()` (see `ResetPose()`). Java is already correct. This
also adds new tests to catch this particular error.
2026-06-04 17:03:22 -07:00
PJ Reiniger
fdc6fd9cb1 [build][bazel] Combine remote setup CI actions (#8893)
When the bazel remote cache was switched from buildbuddy to a self
hosted server in #8342, I asked that the buildbuddy hooks be remain so
that I could still use their caching service for local builds.

The downside of this was that my forks builds aren't leveraging
buildbuddy, so if I'm fiddling with something heavy like a wpimath
robotpy thing, my CI builds never update a cache and never are warm when
I push fixups.


This PR combines the `setup-bazel-remote` and `setup-build-buddy`
actions which set up the bazel remote cache. Rather than having two
different version, the correct one will be choosen in the following
order:
1. Use wpi's server with write access if the `bazel_remote` information
is set (This basically would only happen on main branch in
`wpilibsuite/allwpilib` since secrets aren't accessible from builds
originating in forks)
2. Use buildbuddy if the key it is present (This would work for my fork
builds)
3. Fall back to the readonly version of wpi's server


As seen
[here](https://github.com/bzlmodRio/allwpilib/actions/runs/25777428163/job/75712863120#step:7:28)
the build in my fork will run with buildbuddy, and my PR's build here
should fall back to readonly mode.
2026-06-03 20:16:42 -07:00
PJ Reiniger
dca59147e1 [robotpy][examples] Split examples and snippets (#8944)
This also updates the bazel scripts to behave more like the C++ and Java
examples, and updates the copybara scripts to be able to sync up
`mostrobotpy`
2026-06-03 19:43:16 -07:00
Benjamin Hall
a734275cc5 [wpimath] Add const qualifier to C++ SwerveModuleVelocity Optimize and CosineScale (#8946)
These two functions were changed to return new objects instead of
modifying in-place, so the `const` qualifier should be added. Otherwise,
users with a const reference to a `SwerveModuleVelocity` need to make a
temporary copy first.
2026-06-03 19:42:05 -07:00
Peter Johnson
3f0d7bc2c4 [wpiutil,hal] Move C++ Handle wrapper to wpiutil (#8935)
Also move WPI_Handle typedef to its own header (util/Handle.h).
2026-06-01 14:57:25 -06:00
Vasista Vovveti
3d982f81dd [ntcore] Update period on added or removed, not XOR (#8941)
`added ^ removed` (XOR) is incorrect for the update guard.
Both `added` and `removed` can be true simultaneously (e.g. subscription
options change), and XOR would incorrectly skip the period update. Fixed
to `added || removed`.

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-01 14:56:23 -06:00
sciencewhiz
a3c18d24a7 [examples] Add mecanum drive snippets (#8931)
shows both polar, and cartesian
2026-05-29 23:10:42 -07:00
Peter Johnson
c597116f02 [hal] HALSIM_StepTiming: Avoid underflow (#8933)
Don't advance time if the only active timer is in the past; just wake up
any notifiers.
2026-05-29 23:10:02 -07:00
Peter Johnson
9adffd356d [hal] Update waitForProgramStart to optionally wait for first notifier (#8932)
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.
2026-05-29 23:09:25 -07:00
Thad House
635e971a02 [wpilib] Add a default deadband to all gamepads (#8897)
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.
2026-05-29 16:31:48 -07:00
sciencewhiz
40fdb779d8 [examples] Add differential drive snippets (#8927)
Shows tank, arcade, and curvature for wpilib-docs
2026-05-29 15:00:12 -07:00
Tyler Veness
e728ee27f2 [upstream_utils] Upgrade to Sleipnir 0.6.1 (#8930)
This fixes a memory leak on Windows.
2026-05-29 14:59:39 -07:00
Guinea Wheek
50fd29e697 [ntcore] Fix unbounded memory size tracker (#8929)
If a `ClientMessageQueue` is at a
memory limit, `ClientMessageQueueImpl::ClientSetValue` will still
increment `m_valueSize.size` even though no element has actually been
actually been added.

This quickly results in things like topics completely shutting down
under high load, as no new elements can be added as `m_valueSize.size`
explodes to infinity unless `ClearQueue()` is explicitly called. You can
see this pretty easily with the following code, be it in sim or on a
robot:

```cpp
#include "wpi/framework/TimedRobot.hpp"
#include "wpi/smartdashboard/SmartDashboard.hpp"
class Robot : public wpi::TimedRobot {
  public:
  // ...
  uint64_t value{0};
  /**
   * This function is called periodically during all modes
   */
  void RobotPeriodic() override {
    for (int i = 0; i < 1'000'000; i++) {
      value += 1;
      wpi::SmartDashboard::PutNumber("value", value);
    }
  }
}
```

Connecting via your favorite dashboard quickly reveals that no new
values get added after a while. However, with this patch implemented,
values do still continue to increment as updates gradually get serviced.
2026-05-29 11:01:13 -07:00
Sam Carlberg
4fa5dacfc4 [epilogue] Improve support for robot base classes in epilogue (#8886)
Generate an `update` method for any logged Robot class, not just
TimedRobot

Continue to generate a `bind` method for TimedRobot subclasses

Also removes unnecessary import statements for generated loggers, since
they're using fully-qualified names in the generated Epilogue class now.
2026-05-29 00:14:30 -04:00
sciencewhiz
1e12408a7d [examples] add motor safety and invert to motor snip (#8924) 2026-05-28 20:09:07 -07:00
sciencewhiz
14db070c2c [build] Add guard for missing arm64 msvc runtime (#8922) 2026-05-28 20:08:46 -07:00
sciencewhiz
5c3a474a58 Replace references of frc-docs with wpilib-docs (NFC) (#8926) 2026-05-28 09:01:11 -06:00
Tyler Veness
f1d95ee5f8 [upstream_utils] Upgrade to Sleipnir 0.6.0 (#8923) 2026-05-27 21:26:42 -07:00
Jonah Snider
7ff32d7756 [epilogue,ntcore,wpiunits] Use pattern matching switch expressions where possible (#8925)
Use [pattern matching switch
expressions](https://docs.oracle.com/en/java/javase/17/language/pattern-matching-switch.html)
where possible. This is a JVM 21+ feature which wasn't available until
recently.

If you look at the Java bytecode, this improves performance from an O(n)
runtime check of literally each of the `if (x instanceof y)` checks to
instead be an O(1) tableswitch.

---------

Signed-off-by: Jonah Snider <jonah@jonahsnider.com>
2026-05-27 18:06:15 -07:00
Tyler Veness
aedee56e22 [upstream_utils] Add cbegin()/cend()/crbegin()/crend() to SmallVector (#8918)
std::vector has these.
2026-05-26 21:55:50 -07:00
Peter Johnson
ac7a9524f8 [wpigui] Add stdint.h include to PFD (#8920)
Needed for uint8_t.
2026-05-26 21:55:22 -07:00
Thad House
b100586cab [wpilib] Finish gamepad face button rename (#8921) 2026-05-26 21:55:07 -07:00
Tyler Veness
254ca64106 [upstream_utils] Upgrade to LLVM 22.1.6 (#8919) 2026-05-26 16:25:29 -07:00
Peter Johnson
1392db4529 [romi] Fix Romi motor support (#8915)
Since Servo has been removed from WPILib, add a RomiServo to replace it
(similar to XRPServo).

For Romi, move allocation of PWM channels to OnBoardIO since Motor and
Servo share channels.
2026-05-23 17:38:36 -07:00
Peter Johnson
40f9a87e70 [xrp] Fix motor support (#8916)
The protocol layer got out of sync with the rename to throttle.
2026-05-23 17:37:38 -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
crueter
d86378d353 [wpimath,wpiunits] Add PoundSquareInches MOI unit, and improve KilogramMetersSquaredPerSecond definition (#8838)
As discussed in the discord. lb-in^2 is the common imperial MOI unit,
e.g. Onshape uses it.

Also, improved the Java docstring for `KilogramMetersSquaredPerSecond`
to explain what it represents.

---------

Co-authored-by: Benjamin Hall <bhall@ctr-electronics.com>
2026-05-23 16:41:35 -07:00
Gold856
ac41523eb4 [ci] Run wpilibc through asan (#8868) 2026-05-23 16:40:32 -07:00
David Vo
d48f1cd0e5 [bazel] Add mrclib dependency (#8873)
This pulls in the `mrclib` maven repository as shared libraries, as a
prereq for #8858.

Alternative to #8869, which avoids the unnecessary lockfile entry. This
should be a one-to-one replacement for that PR.

Closes #8869

---------

Co-authored-by: PJ Reiniger <pj.reiniger@gmail.com>
2026-05-23 16:39:47 -07:00
Gold856
e88729c67e [ci] Start avahi-daemon in sentinel builds (#8914)
This fixes the mDNS test failures in the sentinel builds.
2026-05-23 15:39:22 -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
Thad House
67b795057b [build] Add arm64 MSVC Runtime (#8840) 2026-05-15 00:06:18 -05:00
sciencewhiz
e4ae671b49 [ci] Add CI spelling check and fix spelling errors (#8882)
reviewdog/action-misspell is used on frc-docs. It has a dictionary of
commonly misspelled words, so it has less false positives then other
tools.
2026-05-14 21:55:02 -07:00
David Vo
f751ca88eb [bazel] Enforce up-to-date lock file in CI (#8860)
The Bazel lock file was missing a few dependencies. This adds a check in
CI that the lock file is up-to-date.
2026-05-14 21:54:04 -07:00
PJ Reiniger
6ba5734a94 [robotpy] Add wrapper for timestamp functions, like SetNowImpl (#8889)
`SetNowImpl` is used somewhat often in unit tests. It is a little bit
goofier to wrap because it takes a C function, so a little bit more work
has to be done to get that wrapped in pybind.

Claude helped.
2026-05-14 21:53:26 -07:00
PJ Reiniger
68d24bb29e [python] Improve robotpy generation (#8867)
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.
2026-05-14 21:52:39 -07:00
Thad House
3f1cf3cabe [wpilib] ExHub Follower Fixes (#8892)
A chunk of updates to followers on Expansion Hub

Fixes followers not implicitly enabling.
Allows followers to follow other followers
Throws exceptions on construction if a follower cycle is detected.
Allows reversing followers.

The enable thing will fix
https://github.com/wpilibsuite/SystemcoreTesting/discussions/259#discussioncomment-16886195

Closes #8843

Depends on https://github.com/wpilibsuite/scservices/pull/30
2026-05-14 21:50:38 -07:00
Jade
b91001f504 Add nix files to gitignore (#8894)
Based on discord comments I assume we don't want to support a Nix shell
or flake for use with building allwpilib so we should just ignore these
files so users can have their own
2026-05-14 21:49:01 -07:00
Thad House
ffd36eb091 [developerRobot] Add an OpModeRobot instance to DeveloperRobot (#8891)
You can switch to it just by switching Main.java
2026-05-14 21:48:09 -07:00
crueter
97c0b0c40a [upstream_utils] Patch LLVM SmallSetIterator for AppleClang 21 (#8877)
Signed-off-by: crueter <crueter@eden-emu.dev>
2026-05-08 12:49:47 -07:00
sciencewhiz
16fcf016de [examples] Update command template names with v2 to disambiguate (NFC) (#8875)
Partially addresses wpilibsuite/vscode-wpilib#876
2026-05-08 09:34:52 -07: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
Thad House
0af65ea787 [sim] Make HalSim DS extension a no-op (#8872)
This way this doesn't crash until we get real support added.
2026-05-07 20:04:37 -07:00
Gold856
8832d6a7c2 [sim] GUI: Fix game message string lifetime (#8874)
Fixes an issue where game data can't be set.
2026-05-07 20:03:28 -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
Charlotte Wilson
5964443038 [romi,xrp] Print IP and port of XRP/Romi (#8560)
Closes #6352
2026-05-07 11:10:01 -06:00
project516
8c5c535e1b [ci] bump sccache-action to v0.0.10 (#8839)
GitHub will force actions to run on node 24 on September 16th, 2026:
https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/

sccache-action v0.0.9 which is present does not support node 24

sccache-action v0.0.10 adds support:
https://github.com/Mozilla-Actions/sccache-action/releases/tag/v0.0.10
2026-05-07 11:03:09 -06:00
PJ Reiniger
4c07aedd91 [wpilib][sim] Add Onboard IMU Sim (#8855)
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
2026-05-07 11:01:26 -06:00
Peter Johnson
3d4cabfbc9 [ci] Update for merge from 2027 to main (#8857)
Keep -Pbuild2027 for combine for now.
2026-05-07 10:59:25 -06:00
Thad House
63a82dccb2 [wpilib] Don't do wait on init for ExHub in sim (#8865)
Closes #8859
2026-05-07 10:58:14 -06:00
crueter
b10bc0a674 [ci] Don't check matrix.os when runner.os suffices (#8863)
There's no real need to manually check the `runs-on`, as `runner.os`
provides a universally identifiable string for checking this anyways.

Signed-off-by: crueter <crueter@eden-emu.dev>
2026-05-06 17:30:50 -07:00
Gold856
e40ca392c3 [ci] Add missing labels and format labeler config (#8795) 2026-05-05 22:10:42 -07:00
Gold856
f97571fb1f [sim] GUI: fix memory corruption and incorrect POV count (#8853)
Fixes #8800 and fixes #8801.
2026-05-05 22:05:53 -07:00
Peter Johnson
d23c732d79 [upstream_utils] Update imgui to 2026-05-04 (#8849)
This fixes ImGuiInputTextFlags_EnterReturnsTrue.
2026-05-05 22:01:27 -07:00
Dan Katzuv
063ac7002f [ci] Remove 2027 from labeler configuration (#8852) 2026-05-05 16:51:52 -07:00
Peter Johnson
e76074d381 [hal] Initialize alert on Systemcore (#8848) 2026-05-05 13:44:01 -07:00
Tyler Veness
6f88066170 [ci] Update default branch to main (#8846)
This fixes the lint/format CI.
2026-05-03 12:14:27 -07:00
Gold856
3fddf71c47 [build] Remove Javadoc fonts (#8837)
Javadoc now includes 4 MB of fonts for every Javadoc JAR, which we have
18 of, which causes unnecessary bloat to the installer size. This
disables the inclusion of those fonts, using the built-in fallback
included in the Javadoc stylesheet. This also increases the default font
size by 10% after polling the FTC Discord resulted in people asking for
a bigger font.
2026-04-29 14:57:31 -07:00
Gold856
668124e0fd [build] Compress shared object debug info (#8835)
This saves a huge amount of space when they're unzipped for robot
projects, while not increasing artifact size.
2026-04-29 12:14:11 -07:00
Thad House
433c7f00ad [wpilib] Fix jar loading in folder with spaces (#8836) 2026-04-29 12:11:19 -07:00
Thad House
94443c8e84 [wpilib] Fix OpModeRobot initialization (#8834)
There were 3 cases failing before.

1. An OpModeRobot with no annotation.
2. An OpModeRobot with an annotation but a parameterless constructor.
3. An OpMode with a UserControls constructor

This PR solves both of these issues. The first one is solved by adding
the null check before setting the user controls instance. That one will
never have an opmode instance.

The second one is solved by falling back to a parameterless constructor
if one with a parameter is not found.

The 3rd one is solved by using the annotation type rather than the
instance for constructor lookup.

Also fixes ExpansionHubSample's missing annotations.
2026-04-28 12:54:10 -07:00
Gold856
3bf67edc34 [build] Refactor zip base name generation for consistency (#8831)
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`.
2026-04-27 11:46:11 -07:00
sciencewhiz
29beacbefe Fix some Test Mode references to Utility (NFC) (#8827) 2026-04-26 22:32:50 -07:00
Gold856
8d30131fce [build] Update native-utils, OpenCV, libssh (#8818) 2026-04-26 22:31:14 -07:00
Kevin Cooney
657d4d9b58 [ntcore,wpilib] Fix tsan errors in tests that add NT listeners (#8713) 2026-04-26 16:40:46 -07:00
Gold856
97d0b15f7d Add README files for some subprojects and update various other docs (#8640)
Adds a section on design philosophy so we have something to point to
when people suggest features that aren't compatible with the way WPILib
is designed. Fixes some missed reorg changes (although the native-utils
link intentionally points to main as to be up-to-date in the future) and
generally cleans up any outdated information. Also includes wording
about supporting FTC. Per discussion in Slack, the LabVIEW wording has
been removed, and anything to do with LabVIEW is going to have to be
NI's job. And pursuant to #2757 and #5331, additional (light) developer
documentation has been added to some subprojects, mostly being a quick
summary of the what the project does and what it's for (or not for).

---------

Co-authored-by: sciencewhiz <sciencewhiz@users.noreply.github.com>
Co-authored-by: Joseph Eng <91924258+KangarooKoala@users.noreply.github.com>
2026-04-26 16:39:26 -07:00
PJ Reiniger
a695865781 [bazel] Update copybara scripts (#8822)
I've been running my copybara syncs from this branch for a long time.
Finally deciding to PR it.

The biggest update was due to `mostrobotpy` absorbing the commands,
examples, and pyfrc libraries, but I also added in hooks to "enable" the
flakey `xfail` tests on the allwpilib side, and the ability to run
verbose or force push updates.
2026-04-26 15:14:58 -07:00
sciencewhiz
c511fcc160 Update a few misc FRC references (NFC) (#8824) 2026-04-26 15:09:14 -07:00
PJ Reiniger
e5980b46ef [copybara] Sync with mostrobotpy (#8820)
GitOrigin-RevId: f03f29e57af22a74b680873090028b9c9f5c8063
2026-04-26 08:25:15 -07:00
Tyler Veness
af7d68e993 [wpiutil] Use C++23 stacktrace library on Windows (#6839)
This lets us remove the unmaintained StackWalker library and its hacky
upstream_utils script.

@Gold856 reported that StackWalker gives blank stacktraces:
https://discord.com/channels/176186766946992128/368993897495527424/1261940029287301150.
They also reported an earlier version of this PR giving the following
stacktrace instead:
```
D:\allwpilib\developerRobot\src\main\native\cpp\Robot.cpp(18): developerRobotCpp!Robot::RobotInit+0xB6
D:\allwpilib\wpilibc\src\main\native\cpp\TimedRobot.cpp(22): wpilibcd!frc::TimedRobot::StartCompetition+0x4F
D:\allwpilib\wpilibc\src\main\native\include\frc\RobotBase.h(36): developerRobotCpp!frc::impl::RunRobot<Robot>+0xC8
D:\allwpilib\wpilibc\src\main\native\include\frc\RobotBase.h(106): developerRobotCpp!frc::StartRobot<Robot>+0x17E
D:\allwpilib\developerRobot\src\main\native\cpp\Robot.cpp(60): developerRobotCpp!main+0xB
D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(79): developerRobotCpp!invoke_main+0x39
D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(288): developerRobotCpp!__scrt_common_main_seh+0x132
D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl(331): developerRobotCpp!__scrt_common_main+0xE
D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp(17): developerRobotCpp!mainCRTStartup+0xE
KERNEL32!BaseThreadInitThunk+0x1D
ntdll!RtlUserThreadStart+0x28
```
2026-04-26 00:15:39 -07:00
sciencewhiz
880cfd60c4 Update vendordeps wpilibYear to alpha 5 (#8817) 2026-04-25 21:15:54 -07:00
Thad House
a3968faa57 [examples] Add an ExpansionHubSample example (#8810) 2026-04-25 15:43:24 -07:00
sciencewhiz
6aa1611959 [examples] Add a Hatchbot Commands v3 example (#8809)
This is adapted from the work that @Starlight220 did here:
https://github.com/SamCarlberg/allwpilib/pull/5

---------

Co-authored-by: Starlight220 <53231611+Starlight220@users.noreply.github.com>
2026-04-25 15:06:26 -07:00
Gold856
35e8abedeb Don't force public variables to use Hungarian notation (#8774)
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.
2026-04-25 11:32:08 -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
David Vo
2edef821f9 [bazel] Colocate Doxygen version declarations (#8806)
Since we currently have both a Bazel build and Gradle build, we need to
keep the Doxygen versions in sync between the two.


40188d9cc6/docs/build.gradle (L71)

It's awkward that these are in very disjoint parts of the repo. This
puts them in the same directory so it's more obvious it should be kept
in sync.
2026-04-24 20:06:15 -07:00
Zach Harel
3bf3060ff5 [wpilib] Separate ExpansionHubServo into separate Servo and CRServo classes (#8770)
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>
2026-04-24 20:03:24 -07:00
Alan Everett
ded1937fcf [build] Update QuickBuffers to 1.3.3 for Bazel builds (#8811)
Continuation of #6072, this fixes a cross-project bug in QuickBuffers.
Needed for #8776.
2026-04-24 19:21:19 -07:00
Zach Harel
a6425d3e1e [wpilib] DriverStation: Add usage reporting for opmodes (#8761) 2026-04-24 19:20:45 -07:00
PJ Reiniger
68a8ebfc81 [robotpy] Fixup problems during stubgen (#8781)
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.
2026-04-24 14:59:31 -07:00
Peter Johnson
d539e06b4f [wpinet] DsClient: Use new port which provides IP in dotted quad format (#8807) 2026-04-24 13:15:07 -07:00
David Vo
163cfaa027 [ci] Enable Bazel colored output (#8808) 2026-04-24 13:14:34 -07:00
Peter Johnson
40188d9cc6 [glass] Plot: Fix weight and marker settings (#8805)
Line weight needed to default to 1.0.
Marker added an "auto" setting and now starts at -2.

Fixes #8802.
2026-04-24 08:03:16 -07:00
Peter Johnson
a8b827af54 [wpigui] Rename ini setting from userScale to userScaling (#8804)
This avoids very small text resulting from an upgrade.
2026-04-24 08:02:56 -07:00
Peter Johnson
5703f608d7 [wpiutil] Struct: fix is_constexpr check in constexpr functions (#8798)
Capturing the info parameter pack explicitly is required for the
is_constexpr check to work.

Add some basic tests.

Fixes #8789.
2026-04-24 08:02:27 -07:00
Gold856
d893d44e37 [wpimath] Mark all geometry classes as final (#8790)
In Java, these are likely to become value classes in the future.

Make C++ final for consistency.
2026-04-23 22:55:54 -07:00
Gold856
1586dcf385 [wpimath] Fix incorrect C++ return docs in Pose3d and Translation3d (#8793) 2026-04-23 22:53:29 -07:00
Gold856
930340e8f0 [build] Always run Checkstyle after spotlessApply (#8794)
This avoids issues where Checkstyle will error on line length by having
Spotless run first and fix up line lengths before Checkstyle sees the
files.
2026-04-23 22:52:19 -07:00
Zach Harel
7fc8845424 [wpilib] separate expansion hub position and velocity constants (#8791)
this is because position and velocity control follow different rules;
see #8773

Signed-off-by: Zach Harel <zach@zharel.me>
2026-04-23 17:40:52 -07:00
Sam Carlberg
44b9545f30 [epilogue] Use full class names in static logger fields (#8786)
This prevents conflicts when multiple classes with the same simple name
exist in separate packages
2026-04-21 22:24:24 -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
Peter Johnson
14d14e4ebc [hal] Prefix all error #defines with HAL_ (#8780) 2026-04-19 16:12:18 -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
Sam Carlberg
3eaeac6150 [developerRobot] Add commands v3 (#8784) 2026-04-19 15:40:08 -07:00
Thad House
ab2aef2c29 [wpilib] Split DriverStation into smaller classes (#8628) 2026-04-18 19:56:45 -07:00
Tyler Veness
58ad633ae2 [build] Fix CMake add_source_jar() OUTPUT_DIR warnings (#8778)
```
CMake Warning (dev) at /usr/share/cmake/Modules/UseJava.cmake:716 (cmake_parse_arguments):
  The OUTPUT_DIR keyword was followed by an empty string or no value at all.
  Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  _add_jar_OUTPUT_DIR variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/CreateSourceJar.cmake:29:EVAL:1 (add_jar)
  cmake/modules/CreateSourceJar.cmake:29 (cmake_language)
  wpiannotations/CMakeLists.txt:29 (add_source_jar)
This warning is for project developers.  Use -Wno-dev to suppress it.

CMake Warning (dev) at /usr/share/cmake/Modules/UseJava.cmake:716 (cmake_parse_arguments):
  The OUTPUT_DIR keyword was followed by an empty string or no value at all.
  Policy CMP0174 is not set, so cmake_parse_arguments() will unset the
  _add_jar_OUTPUT_DIR variable rather than setting it to an empty string.
Call Stack (most recent call first):
  cmake/modules/CreateSourceJar.cmake:29:EVAL:1 (add_jar)
  cmake/modules/CreateSourceJar.cmake:29 (cmake_language)
  wpiunits/CMakeLists.txt:25 (add_source_jar)
This warning is for project developers.  Use -Wno-dev to suppress it.
```
2026-04-17 21:08:41 -07:00
Peter Johnson
a97214df43 [hal] Resource classes: Use expected, refactor errors (#8768)
Also revamp SetLastError et al; Instead of taking status by pointer,
take by value and return new status instead. Rename from SetLast to Make
to make this new usage obvious.

Also move declarations for the error functions from duplicated in the
per-target HALInternal.hpp to a common ErrorHandling.hpp.
2026-04-17 20:19:38 -07:00
Thad House
6cb6903780 [hal,wpilib] Remove a ton of things related to the FPGA (#7846)
Co-authored-by: Gold856 <117957790+Gold856@users.noreply.github.com>
2026-04-17 19:38:25 -07:00
crueter
fdb454a6b1 [fields] refactor: FTC/FRC separation, better naming scheme (#8034)
Closes #8018

- Adds the 2024-2025 and 2025-2026 FTC field image data
- Used a better naming scheme of `<year> F{R,T}C <gamename>`
  * Also removed generic `field` verbiage from PNG file names
- JSON and PNG files moved into respective `frc` and `ftc` directories
- Rotated fields for the new red-left scheme

Signed-off-by: crueter <swurl@swurl.xyz>
2026-04-17 19:36:38 -07:00
Gold856
056d7bcbbe [wpimath] Make swerve and differential kinematics functions immutable (#8274)
Originally started with just swerve, but expanded to diff and mecanum
(docs only) for parity across the drivetrains. Return value checks are
applied when possible to make migration easier and to error loudly if
people forget.

---------

Co-authored-by: Joseph Eng <91924258+KangarooKoala@users.noreply.github.com>
2026-04-16 21:23:32 -07:00
Thad House
8c80cdcf28 [hal] Add CAN Bus Map (#8765)
We will want a better API for higher level devices that expect to be on
motioncore, but for ones that are not expected to be, it'll be really
nice to have an API that can let us map the motioncore can bus to its
HAL index.
2026-04-16 21:03:39 -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
sciencewhiz
613c86d1d7 [cmd2] Flatten wpi::cmd::cmd to wpi::cmd (#8764)
Fixes #8763
2026-04-13 21:48:13 -07:00
Tyler Veness
f89cf297e4 [wpical] Fix linker errors (#8766)
```
mold: error: undefined symbol: wpi::fields::GetFields()
>>> referenced by Field2D.cpp
>>>               /home/tav/frc/wpilib/allwpilib/glass/build/libs/glass/static/linuxx86-64/debug/libglassd.a(Field2D.o):((anonymous namespace)::FieldInfo::DisplaySettings())
>>> referenced by Field2D.cpp
>>>               /home/tav/frc/wpilib/allwpilib/glass/build/libs/glass/static/linuxx86-64/debug/libglassd.a(Field2D.o):((anonymous namespace)::FieldInfo::LoadImage())
collect2: error: ld returned 1 exit status
```
The issue seems to stem from libglass linking to the shared version of
fields, whereas wpical requires static linkage.
2026-04-12 22:04:24 -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
Peter Johnson
476b9641c1 [upstream_utils] Update imgui and implot (#8762)
Not updating GLFW yet due to a likely future move to SDL.
2026-04-12 12:19:32 -07:00
Peter Johnson
d76486d885 [upstream_utils] Update googletest to HEAD (#8755)
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2026-04-11 16:53:55 -07:00
Tyler Veness
7e9138f8c1 [upstream_utils] Upgrade to Google Benchmark 1.9.5 (#8760) 2026-04-11 16:52:24 -07:00
Tricks1228
042567d0ba [wpimath] Prevent CoordinateSystem from accepting left-handed systems (#8750) 2026-04-11 13:53:36 -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
Alan Everett
9ea63c7fd6 [wpilibc] Return empty string instead of null for GetOpMode (#8754)
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.
2026-04-11 13:51:58 -07:00
Tyler Veness
8e72d17770 [upstream_utils] Upgrade to Catch2 3.14.0 (#8757) 2026-04-11 13:51:34 -07:00
Gold856
2102a543d1 Change Java JSON to Avaje Jsonb (#8721)
Jackson is a very heavy library; it supports loads of features that we
don't need, and historically has caused issues due to long class loading
times (a little over 2 seconds to load AprilTagFieldLayout). This often
manifests as a help request in the form of "my robot disables when I do
X, but doesn't disable when doing X in subsequent attempts until code
restart." While SC has brought down Jackson loading times significantly,
with AprilTagFieldLayout loads taking only 330 milliseconds, that's
still a rather long delay, and while libraries should handle any JSON
loading ahead of time to prevent delays in auto/teleop, it would still
be good to make the worst case better to reduce user frustration.
Benchmarks indicate using [Avaje
Jsonb](https://github.com/avaje/avaje-jsonb) to load AprilTagFieldLayout
only takes ~70 ms, a fair chunk of which isn't actually in Avaje Jsonb
(~4 ms is spent on using getResourceAsStream to retrieve the JSON file,
~8 ms is spent on just loading the AprilTag class and its dependencies).

Note that all times listed are end-to-end, meaning nothing else was done
except for the operation being benchmarked, and doing arithmetic on them
can be flawed due to some classes being loaded twice, i.e.,
getResourceAsStream and `new AprilTag()` likely load some of the same
JDK classes and so subtracting both from the Avaje Jsonb load time is
likely slightly incorrect because class loading is being double counted.
For our purposes, it's likely accurate enough and is mostly just for
contextualization.

Benchmarks were run on a Raspberry Pi CM5 with 2 GB of RAM. Source code
for the
[results](https://github.com/user-attachments/files/26471452/benchmark.txt)
can be found in the "Fastjson2" commit
(2456d15ca8ebd17635e607cd40bf8816e77869a1).

Avaje Jsonb uses code generation via annotation processors to generate
the classes needed to do JSON serde and uses service providers to find
them, which will require downstream changes in robot projects, as the
different service providers in each library must be merged together for
Avaje Jsonb to function. We will use the Gradle shadow plugin, as its
already used by the installer and therefore adds zero additional
dependencies.
2026-04-10 23:21:00 -07:00
Thad House
346cd9ed9c [build] Update native utils to fix new mac builds (#8752) 2026-04-10 21:12:18 -07:00
Tyler Veness
aedff82286 [ci] Escape upload-artifact path (#8748)
Asterisk prefixes are interpretted as YAML aliases, which resulted in a
parsing failure.
2026-04-10 17:11:48 -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
Zach Harel
a8c7f3e3c6 [wpilib] Change opmodes to purely periodic (#8652)
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>
2026-04-10 13:40:17 -07:00
Peter Johnson
84295180cd [wpinet] WebSocket: Mutex-protect static random device/engine (#8741) 2026-04-10 13:32:55 -07:00
Peter Johnson
bc984234e9 [cmd2] CommandScheduler::Cancel(): Don't mutate in for loop (#8743)
Erasing elements from a container while iterating over the container may
not be well-defined.
2026-04-10 12:30:00 -07:00
Peter Johnson
ea06f0b257 [wpilibj] Watchdog: handle callback throwing an exception (#8742)
Ensure mutex is re-locked.
2026-04-10 12:29:38 -07:00
Peter Johnson
3728bc3b5c [wpilibc] Notifier: Use atomic exchange in move constructor/assignment (#8740) 2026-04-10 12:28:54 -07:00
Peter Johnson
1671150521 [wpiutil] WPI_WaitForObjectTimeout: Add null check (#8739) 2026-04-10 12:28:34 -07:00
Peter Johnson
b7fe3dad46 [ntcore] WireDecodeBinary: Fix some mpack paths (#8738) 2026-04-10 12:28:17 -07:00
Peter Johnson
7e86c10a28 [wpiutil] Fix Semaphore backing vector usage (#8737)
The wrong backing vector was being used (eventIds).
2026-04-10 12:27:52 -07:00
Sam Freund
21f6bdbc1a [hal,wpilib] Remove alert level aliases (#8744) 2026-04-10 12:26:52 -07:00
Sam Freund
ce77e6022f [ci] Remove archival for lint patches (#8745)
When downloading a patch to fix linting errors, it's annoying to have to
unzip it, particularly when it's a single file. This PR updates the
`upload-artifact` action to v7, which allows for uploading an artifact
without zipping it. It also sets archive to false for all patches
generated by linting.
2026-04-10 12:26:13 -07:00
Tyler Veness
b6849a8da3 [wpilib] Rename MotorController setDutyCycle() to setThrottle() (#8720)
Fixes #8716.
2026-04-09 22:28:01 -07:00
Peter Johnson
a4e035ba64 Replace gmtime/localtime with std::chrono (#8735)
Fixes #8734.
2026-04-09 22:25:46 -07:00
Sam Freund
ece8001b1e [wpilib] Add AlertSim function to get only active alerts (#8732) 2026-04-09 22:25:26 -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
Tyler Veness
5a96685c86 [upstream_utils] Upgrade to Sleipnir 0.5.2
This fixes a bug in Sleipnir's Newton solver (the exit status was inaccurate because unconstrained optimization problems can't be infeasible).
2026-04-09 17:03:57 -07:00
Peter Johnson
9ca93fa190 Update for jart/json.cpp change 2026-04-08 08:28:28 -07:00
Peter Johnson
de3e211fdb [upstream_utils] Add jart/json.cpp 2026-04-08 08:28:28 -07:00
Peter Johnson
bfea2b7e1f [upstream_utils] Remove nlohmann JSON 2026-04-08 08:28:28 -07:00
Peter Johnson
3ac168f9d2 [upstream_utils] Add double-conversion to wpiutil 2026-04-08 08:28:28 -07:00
David Vo
44dcf9a3ca [wpilibc] Fix HSV to RGB conversion off-by-one error (#8722)
`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 :)
2026-04-08 08:18:12 -07:00
Tyler Veness
5b4769ea0a [upstream_utils] Upgrade to Sleipnir 0.5.1 (#8726)
There's changes to the diagnostic output and a performance improvement
for autodiff setup. I also updated Java's Options docs to more closely
match upstream.
2026-04-07 23:52:30 -07:00
Tyler Veness
719e9dddc0 [javac] Fix javadoc warnings (#8718)
```
> Task :javacPlugin:javadoc
/home/tav/frc/wpilib/allwpilib/javacPlugin/src/main/java/org/wpilib/javacplugin/OpModeAnnotationValidator.java:31: warning: invalid input: '<'
 *   <li>Name must be <= 32 characters
                      ^
/home/tav/frc/wpilib/allwpilib/javacPlugin/src/main/java/org/wpilib/javacplugin/OpModeAnnotationValidator.java:32: warning: invalid input: '<'
 *   <li>Group must be <= 12 characters
                       ^
/home/tav/frc/wpilib/allwpilib/javacPlugin/src/main/java/org/wpilib/javacplugin/OpModeAnnotationValidator.java:33: warning: invalid input: '<'
 *   <li>Description must be <= 64 characters
                             ^
3 warnings
```

These weren't caught by the `docs:generateJavaDocs` task because the
javacPlugin docs aren't included there.
2026-04-06 09:51:11 -06:00
Thad House
e4ef8a2515 [wpilib] Wait for expansion hub connected for up to half a second during boot (#8715)
Closes #8714
2026-04-06 09:50:47 -06:00
Tyler Veness
173ecd3d02 [hal] Refactor threads API (#8701)
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).
2026-04-06 09:49:43 -06:00
David Vo
cc56c42d4c [ci] Avoid duplicate Windows debug build Bazel actions (#8723)
Each Bazel Windows CI job is currently redundantly evaluating the build
actions for both the `opt` and `dbg` compilation modes.

If we group the debug artifact builds together (instead of grouping by
the shared/static library artifacts), the `dbg` compilation mode actions
no longer need to be executed across multiple CI jobs in the matrix.

(Yes, the CI jobs are sharing the Bazel cache, but there's still
overhead in checking the action cache for each action. It's also
possible that two jobs will race to execute the same action.)

| Total actions per job      | [Before] | After |
|----------------------------|---------:|------:|
| Windows x86-64             |    12277 | 10179 |
| Windows x86-64 Static      |    11947 | n/a   |
| Windows x86-64 Debug       |   n/a    |  9895 |
| Windows ARM64              |     5518 |  3420 |
| Windows ARM64 Static       |     5304 | n/a   |
| Windows ARM64 Debug        |   n/a    |  3272 |
| Windows System Core        |     4836 |  2916 |
| Windows System Core Static |     4576 | n/a   |
| Windows System Core Debug  |   n/a    |  2916 |

[Before]:
https://github.com/wpilibsuite/allwpilib/actions/runs/23781230818

This should hopefully translate to shorter wall-clock time Windows CI
jobs.
2026-04-06 09:47:13 -06:00
Thad House
dfc8098b9c [wpiutil] Switch PackCallback to take a range (#8709)
This way it no longer needs something that is contiguous
2026-03-30 21:58:15 -07:00
Thad House
bf218113db [wpiutil] Rename CreateEvent and CreateSemaphore to Make (#8710)
CreateEvent and CreateSemaphore are macros in Windows.h, which causes a
ton of trouble. Just rename the functions.

Closes #7303

Replaces #7336
2026-03-30 15:54:42 -07:00
Tyler Veness
d248c040bf [wpimath] Add Sleipnir Java bindings (#8236)
The wrapper includes reverse mode autodiff, the Problem DSL, and the
optimal control problem API. I wrote it by directly translating the
upstream
[API](https://github.com/SleipnirGroup/Sleipnir/tree/main/include/sleipnir)
and [tests](https://github.com/SleipnirGroup/Sleipnir/tree/main/test) to
Java (i.e., copy-paste-modify).

I replaced the ArmFeedforward and Ellipse2d JNIs with implementations
using the Sleipnir Java bindings. Switching dev binary JNIs to release
by default sped up wpimath test runs from several minutes to 7 seconds.
2026-03-29 22:34:21 -07:00
Thad House
3e821b9448 [hal] Add low level support for Motioncore CAN buses (#8707)
This way vendors can easily access them.
2026-03-29 20:42:25 -07:00
Matt Morley
db42c6cbba [wpinet] Add mDNS discovery tests and fix mDNS JNI bugs (#8682)
In https://github.com/wpilibsuite/allwpilib/issues/8681 we discovered
that multicast service types need to be valid (end with _tcp or _udp),
or else errors are silently swallowed. Let's make our C++ unit test use
a valid name and also check that it works. I think if we
should/shouldn't do this is up for debate still.

I also discovered two bugs in the JNI code that lead to incorrect
results being returned
- Return array index was always 0
- Use of JLocal for the return value seems to mean that the array will
always be NULL in java
2026-03-29 20:41:32 -07:00
sciencewhiz
ceb712b089 [docs] Change NewCommands to Commands v2 (NFC) (#8702) 2026-03-29 20:40:36 -07:00
Thad House
d74644283b [wpilibc] Fix GetUsbId on ExpansionHub in C++ (#8704) 2026-03-29 20:40:06 -07:00
Tyler Veness
f3757bdeae [upstream_utils] Upgrade to Sleipnir 0.5.0 (#8711) 2026-03-29 20:39:18 -07:00
Thad House
962168acf1 [wpinet] Fix port having incorrect endian on windows resolver
For some reason, ip is in network order, but port is in host order.
2026-03-29 16:26:18 -07:00
Peter Johnson
dc4a8d572d [wpilibc] Fix DriverStation comment (NFC) 2026-03-21 00:37:28 -07:00
Peter Johnson
1925cf0e1f [wpilib] Rename LEDPattern constants to all caps 2026-03-21 00:37:28 -07:00
Peter Johnson
d05d3b1c78 [wpilib] Remove PWM.Period enum
Replace it with just numeric values.
2026-03-21 00:37:28 -07:00
Peter Johnson
f2929af00f [wpilib] Rename ADXL345_I2C constants to all caps 2026-03-21 00:37:28 -07:00
Peter Johnson
ea32c247db [wpilib] Rename PneumaticsModuleType constants 2026-03-21 00:37:28 -07:00
Peter Johnson
f060c98992 [wpilib] Rename drivetrain sim enums to all caps 2026-03-21 00:37:28 -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
d86a745328 [wpilib] Rename DoubleSolenoid.Value constants to all caps 2026-03-21 00:37:28 -07:00
Peter Johnson
c5738fcbad [wpilib] Rename AddressableLED.ColorOrder constants to all caps 2026-03-21 00:37:28 -07:00
Peter Johnson
87e677d4af [wpilib] Rename MotorSafety constants to all caps 2026-03-21 00:37:28 -07:00
Peter Johnson
3776f8a1ef [wpilib] Rename OnboardIMU constants to all caps 2026-03-21 00:37:28 -07:00
Peter Johnson
e73e2e99f7 [wpilibj] SerialPort: update comments to track rename (NFC) 2026-03-21 00:37:28 -07:00
Peter Johnson
49065aa07f [wpilib] Rename CAN constants to all caps 2026-03-21 00:37:28 -07:00
Peter Johnson
38b9214e38 [wpilib] Rename PeriodicOpMode constants to all caps 2026-03-21 00:37:28 -07:00
Peter Johnson
09be21c319 [wpilib] Rename TimedRobot constants to all caps 2026-03-21 00:37:28 -07:00
Peter Johnson
48868020a9 [wpilib] Rename RobotDriveBase constants to all caps 2026-03-21 00:37:28 -07:00
Peter Johnson
7815248d62 [wpilib] Rename MotorType constants to all caps 2026-03-21 00:37:28 -07:00
Peter Johnson
6559d78658 [wpilib] Rename SysIdRoutineLog constants to all caps 2026-03-21 00:37:28 -07:00
Peter Johnson
8fa6976cb2 [wpilib] Rename EdgeConfiguration constants to all caps 2026-03-21 00:37:28 -07:00
Peter Johnson
5ec92df137 [wpilibj] Rename SensorUtil constants to all caps 2026-03-21 00:37:28 -07:00
Peter Johnson
8a802fd670 [wpilib] Rename private constants to all caps 2026-03-21 00:37:28 -07:00
Peter Johnson
b7122f0fda [hal] Rename HAL_kInvalidHandle to HAL_INVALID_HANDLE (#8698) 2026-03-21 00:34:46 -07:00
Peter Johnson
4e4ad9c498 [wpinet] Rename constants to all caps (#8696) 2026-03-20 23:02:21 -07:00
Gold856
0fc1f45324 [wpical] Remove tag ID limit (#8697)
It's annoying to have to update this, and we forgot for 2026.
2026-03-20 20:31:11 -07:00
Gold856
dba033eaee [hal] Clean up references to removed HAL features (#8695)
#7695, #7696, #7697, #7701, #7724, #7753, #7861 removed various features
from the HAL, but forgot to clean up the handles, the WS API, or both.
Additionally, since AnalogInput is the only remaining analog I/O,
AnalogJNI was renamed to the more specific AnalogInputJNI.
2026-03-20 16:50:02 -07:00
Gold856
f1aa84aecf [hal,wpilib] Remove MXP mentions in API docs (NFC) (#8694) 2026-03-20 16:48:53 -07:00
Thad House
fb4bcefabc [wpilibj] Allow passing DS Instance to Robot and OpModes (#8626)
Some discussion with the tech team showed that there were some real
advantages to being able to pass a 2nd type. It allows separating the DS
and Robot. Additionally, we can make the DriverStationBase class
actually usable instead of the existing DriverStation class which is
impossible to handle in intellisense because it has too much.

This won't fully be doable in C++, but we will need to implement
something similar in python.
2026-03-20 14:05:48 -06:00
Peter Johnson
b86204bf45 [wpiutil] Update Color.RGBChannel enum to all caps 2026-03-20 13:24:22 -06:00
Peter Johnson
410c11994e [wpiutil] Update MappedFileRegion MapMode enum to all caps 2026-03-20 13:24:22 -06:00
Peter Johnson
c5e32652f9 [wpiutil] Rename WPI_kInvalidFile to WPI_INVALID_FILE 2026-03-20 13:24:22 -06:00
Peter Johnson
4059797635 [hal,ntcore,cscore] Update Handle constants to all caps 2026-03-20 13:24:22 -06:00
Peter Johnson
aa88fa0fcf [wpiutil] Rename struct constants to all caps 2026-03-20 13:24:22 -06:00
Peter Johnson
c913b27a27 [wpiutil] Rename TimestampSource constants to all caps 2026-03-20 13:24:22 -06:00
Peter Johnson
9ce9918763 [wpiutil] Rename PixelFormat constants to all caps 2026-03-20 13:24:22 -06:00
Peter Johnson
e5107e7e00 [wpiutil] Rename Color constants to all caps 2026-03-20 13:24:22 -06:00
Joseph Eng
8af6bd354e [ntcore] Fix up constants renames (#8693)
Takes care of a few renames missed in #8676.
2026-03-19 23:35:59 -07:00
Peter Johnson
0665aed66b [hal] Fix Python CAN API types prefix (#8687) 2026-03-16 21:47:58 -07:00
Gold856
e81d47fb46 [hal,wpilib] Remove unused error/warning codes (#8684) 2026-03-16 20:26:43 -07:00
Peter Johnson
58e112480a [ntcore] Prefix log levels to avoid macro conflicts (#8686) 2026-03-16 20:24:23 -07:00
Peter Johnson
aad08b9ad1 [hal] Rename SimDevice constants to all caps
Also use enum class for SimDevice C++ wrapper.
2026-03-15 22:38:09 -07:00
Peter Johnson
70f77a1f8e [hal,wpilib] Rename SerialPort constants to all caps 2026-03-15 22:38:09 -07:00
Peter Johnson
68ca74c129 [hal,wpilib] Rename REVPH compressor constants to all caps 2026-03-15 22:38:09 -07:00
Peter Johnson
c18f811ea7 [hal,wpilib] Rename PowerDistribution constants to all caps 2026-03-15 22:38:09 -07:00
Peter Johnson
261a0ebbd7 [hal,wpilib] Rename I2C constants to all caps 2026-03-15 22:38:09 -07:00
Peter Johnson
b68fbb1adc [hal,wpilib] Rename Encoder constants to all caps 2026-03-15 22:38:09 -07:00
Peter Johnson
f6fdae3212 [hal,wpilib] Rename RuntimeType constants to all caps 2026-03-15 22:38:09 -07:00
Peter Johnson
227f01f3bd [hal,wpilib] Rename DriverStation constants to all caps 2026-03-15 22:38:09 -07:00
Peter Johnson
614eb1db18 [hal,wpilib] Rename CAN device and manufacturer types to all caps 2026-03-15 22:38:09 -07:00
Peter Johnson
fc3be46e6c [hal] Rename kAddressableLEDLength to all caps 2026-03-15 22:38:09 -07:00
Peter Johnson
ab7e4766f6 [ntcore] Rename constants to all caps style (#8676) 2026-03-15 20:44:45 -07:00
Tyler Veness
86dd3ca2b7 [hal] Simplify monotonic_clock (#8678)
The epoch() function, zero() function, and min_time member are all not
part of the std::chrono clock interface.

The default constructor of time_point is
[documented](https://en.cppreference.com/w/cpp/chrono/time_point/time_point.html)
to initialize to the clock's epoch.
2026-03-15 20:42:52 -07:00
Tyler Veness
14e2c1c4cf [ci] Fix all warnings from clang-tidy 22 (#8680)
I ran the following locally:
```bash
gradle generateCompileCommands
./.github/workflows/fix_compile_commands.py build/TargetedCompileCommands/linuxx86-64release/compile_commands.json
wpiformat -default-branch 2027 -no-format -tidy-all -compile-commands=build/TargetedCompileCommands/linuxx86-64release
```

The `HeaderFilterRegex` option is used to filter out warnings from
thirdparty headers.
2026-03-15 20:42:35 -07:00
Peter Johnson
e944ae9aca [hal,wpilib] Rename FPGA clock to monotonic clock (#8672)
- Remove status return from HAL level (clock getting should never fail)
- Remove 32-bit timestamp expand function
- Make monotonic_clock.hpp (formerly fpga_clock.hpp) header-only and
move to root hal include directory
2026-03-15 15:08:41 -07:00
Joseph Eng
1a5b023235 [wpiutil] Add WPI_String usage documentation (NFC) (#8675)
The description is adapted from the PR description in #6299.
2026-03-14 22:38:12 -07:00
Gold856
d1fba06851 Remove deprecated code (#8656) 2026-03-14 21:28:31 -07:00
Gold856
f1adce4cf7 [examples] Clean up examples (#8674)
Move various "examples" into snippets. Several examples that were less
than a full mechanism or robot were moved to snippets. `arcadedrive` and
`tankdrive` were removed in favor of their Gamepad variants. `hidrumble`
was removed due to being too simple. `potentiometerpid` was removed
because of low utility. `gyromecanum` replaced `mecanumdrive` for
deduplication and because very few teams run holonomic drivetrains
without gyros.
2026-03-14 14:13:45 -07:00
Gold856
62ce8944aa [bazel] Add Doxygen excludes for Gradle parity and silencing warnings (#8673) 2026-03-14 09:48:27 -07:00
Thad House
b2b111dc11 Rename FRC to WPILib (#8637) 2026-03-13 23:05:55 -07:00
Peter Johnson
6830c65a15 [hal] Rename HALBase.h to HAL.h (#8668) 2026-03-13 17:19:39 -07:00
Peter Johnson
ab4700854c [hal] Remove HAL.h single header include (#8667) 2026-03-13 15:53:24 -07:00
Peter Johnson
80647654c3 [hal] Add HAL_Status typedef (#8671) 2026-03-13 15:51:43 -07:00
Tyler Veness
907bf05607 [ci] Upgrade to wpiformat 2026.56 (#8666) 2026-03-13 13:15:01 -07:00
Joseph Eng
f196418297 [wpilib] Fixup alerts (#8663)
Makes Java `Alert.Level.ERROR`, `Alert.Level.WARNING`, and
`Alert.Level.INFO` proper aliases (instead of separate enum constants
with the same value).
Cleans up Python tests.
Makes the Alert tests more consistent between languages.
2026-03-09 23:03:00 -07:00
PJ Reiniger
c0f8159540 [copybara] Resync with mostrobotpy (#8662) 2026-03-08 21:38:21 -07:00
Tyler Veness
71cd434699 [wpimath] Don't clamp Rotation2d interpolation (#8661)
Extrapolation is also valid.
2026-03-07 15:58:48 -08:00
Peter Johnson
6910ff1362 [ntcore] PubSubOption: Use record approach for Java (#8659) 2026-03-06 22:26:31 -08:00
PJ Reiniger
ccfb3ab1cd [robotpy] Fixup errors missed in #8479 (#8660)
Looks like a race condition happened in the landing of the examples PR
and #8479 which caused some of the python examples to fail.
2026-03-06 21:21:43 -08:00
Tyler Veness
b29bde123f [wpimath] Implement Rotation3d interpolation as slerp instead of lerp (#8529)
Also replace arithmetic operators since they're not commutative, which
is confusing for users.
2026-03-06 15:15:00 -08:00
Sam Carlberg
28176f1062 [javac] Add @MaxLength annotation for limiting lengths of string parameters (#8493)
Useful for eg OpModes, where names have a maximum length

Also includes validations for values in opmode annotations like
`@Autonomous(name = "...")`; name, group, and description all have
maximum allowable lengths
2026-03-06 14:20:20 -08:00
Tyler Veness
9bd9656871 [wpimath] Replace Speeds with Velocities (#8479)
I left "free speed" alone since that's the technical term for it. In
general, velocity is a vector quantity, and speed is a magnitude (i.e.,
a strictly positive value).

This PR also replaces the speed verbiage in MotorController with duty
cycle.

Fixes #8423.
2026-03-06 14:19:15 -08:00
sciencewhiz
1e39f39128 [ci] Build docs with Java 25 (#8655) 2026-03-05 23:19:10 -08:00
PJ Reiniger
51a3876330 [robotpy] Build examples (#8629)
This hooks up the bazel build to the robotpyExamples. It can use the
(formly pyfrc or whatever) automatic unit tests for an example, as well
as exposing the ability to run the example in simulation, with or
without `halsim_gui` with a command such as `bazel run
//robotpyExamples:AddressableLED-sim`

This required building and using wheels instead of just a normal
`py_library`, so that things like `ENTRY_POINTS` can be used. I took a
bare bones approach to building and naming the wheels (for example the
native ones don't have the OS info or python version in them, so they
wouldn't be suitable publish to pypi, but that can always be updated
later.
2026-03-05 23:18:37 -08:00
Tyler Veness
26b2b08c8d [wpimath] Clean up KalmanFilter tests (#8651)
Also synchronize C++ and Java versions of tests.
2026-03-05 23:17:36 -08:00
Gold856
c8780950c0 [wpimath] Simplify LinearSystem#slice in Java (#8658)
Avoids boxing to reduce allocations, combines for loops as an
optimization, and removes massive switch statement because Java's
generics are type erased, so the different type parameters make no
difference.
2026-03-05 23:16:44 -08:00
Peter Johnson
e9d226491c [cscore] Split cscore classes into separate headers
Fixes #3713.
2026-03-04 22:09:40 -07:00
Peter Johnson
f08258f784 [wpiutil] Split C++ header files 2026-03-04 22:09:40 -07:00
Peter Johnson
a7f71c9434 [hal] Consistently use .hpp for C++ header content
Some headers were renamed, but others were split.
2026-03-04 22:09:40 -07:00
Gold856
ab45819f6f [ci] Specify exact OpenCV features in vcpkg manifest (#8653)
This allows us to skip building things we don't need, like the ML
libraries or QR code scanning. This cuts the vcpkg configure time down
by 50%.
2026-03-04 18:52:48 -08:00
Peter Johnson
733cfa4b07 [hal,wpilib] Move Alert to HAL (#8646)
SystemCore implementation is not yet connected to MRCComm.
2026-03-03 20:58:47 -08:00
Thad House
f4935a2ea9 [nanopb] Add function to get rest of buffer (#8650) 2026-03-02 10:46:23 -08:00
Gold856
06598f5436 [wpiunits] Remove deprecated divide and negate functions (#8645) 2026-02-28 10:30:04 -08:00
Peter Johnson
ba81d4b790 [cscore] Remove Axis camera (#8642)
Was a thin wrapper around HttpCamera and haven't been used by teams for
years.
2026-02-27 21:05:52 -08: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
Gold856
46a911d50c [docs] Fix various @see tags in Javadoc (#8644)
Most of these were leftovers from the reorg, the Commands v2 change is
from the recent merge from main and fixes our builds again.
2026-02-27 20:04:07 -08:00
Peter Johnson
c8c68329fa [build] Fix Robotpy pregeneration post-merge (#8641) 2026-02-27 15:14:47 -08:00
Matt Morley
4d0b67d293 [wpinet] Fix uv_tcp_keepalive to take seconds (#8639)
[Libuv docs](https://docs.libuv.org/en/v1.x/tcp.html) states:

> Enable / disable TCP keep-alive. delay is the initial delay in
seconds, ignored when enable is zero.

But we used std::milli, leading to being off by a factor of 1000.
2026-02-27 14:27:59 -08:00
Peter Johnson
b566814bae [wpilib] Remove LinearOpMode (#8638)
Linear OpModes have several major downsides with no obvious solutions:

- Some things stop working automatically--e.g. in a linear opmode,
simulation will not work out-of-the-box; the user must explicitly call
sim themselves.  there's a few other things we do periodically, but this
is the big one (it also forces some decisions on other parts of the
library—eg if we want Tunable to work in linear without the user
manually calling refresh, we have to run it on a background thread,
which means it must be thread safe throughout).  We can help in some
areas (e.g. have sleep functions call background things), but if the
user is writing a loop that waits to drive a certain distance with no
sleep, it's an easy footgun
- Writing code with no sleeps is easy to do, and can hog an entire
processing core easily--yes, there's more than one core, but it could
still easily impact e.g. vision processing
- Many people I've talked to want robot-level periodic and periodic sim
functions.  Given linear opmodes, we have two options, neither of which
is great: (1) don't provide robot-level periodic functions, and the
users who want those must set those up themselves and remember to call
them explicitly from every periodic opmode, or (2) provide them, but
only call them automatically from periodic opmodes, which could be
confusing for linear opmode users (they'd have to call them manually if
they wanted them).  Currently we do (1) but someone in the community
already opened a change to do (2).
- Restarting the robot program fixes the "stuck in auto for the rest of
the match" problem but still feels like an ugly hack because the startup
time is not unlikely to make the robot not immediately ready for teleop

Removing LinearOpMode resolves these issues by moving to a periodic-only
structure. We can address the few notable use cases of LinearOpMode
(e.g. very basic autonomous sequences) in other ways such as Blocks
generated code, better state machine tutorials/documentation, etc.
2026-02-27 14:26:27 -08:00
Peter Johnson
7513846c72 Merge branch 'main' into 2027 2026-02-27 14:24:41 -08:00
amsam0
7ca35e5678 [wpimath] Add limit setters to SlewRateLimiter (#8581)
This is just #7793 with requested changes applied.
2026-02-27 12:53:18 -08:00
Kevin Cooney
613bd88548 [wpilib] Make Preferences Listener not depend on mutable fields (#8607)
The Listener installed by Preferences was referencing m_typePublisher which could be modified by a future call to setNetworkTableInstance(). Instead, reference a local.

Also made Topic.m_handle final, to guarantee that Topic.equals() is thread-safe, and still work after the publisher has been closed.
2026-02-27 12:42:40 -08:00
Stephen Just
e311722637 [ntcore] Handle interrupted save in NetworkServer (#8630)
In NetworkServer::SavePersistent, if the save is interrupted (by robot
power loss, etc), the networktables.json file may be left in an
unhandled state where the file consumed by
NetworkServer::LoadPersistent is not found, but the backup file exists.
In this case, we should attempt to recover the backup file to avoid
losing all persistent data.
2026-02-27 12:39:05 -08:00
sciencewhiz
ae43b8b6dd [cmd] Fix WaitUntilCommand for match time counting down (#8632)
Fixes #8631
Documents that it will return immediately if FMS isn't attached or DS
isn't in practice mode.
Related to change in DS match time behavior that was documented in #8606
2026-02-23 17:11:59 -08:00
sciencewhiz
5ae8ee06dd [build] use local opencv docs element-list (#8633)
Fixes opencv cloudflare blocking gradle javadoc builds
2026-02-23 16:32:28 -08:00
DeltaDizzy
d9eba4bb22 [wpilib] Document zero angle in SingleJointedArmSim (NFC) (#7756)
Fixes #7752

---------

Co-authored-by: sciencewhiz <sciencewhiz@users.noreply.github.com>
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2026-02-21 14:36:36 -08:00
Thad House
44441daad7 [wpilib] Use reflection to load main class, remove main from templates (#8627)
#8626 needs to switch to using reflection to load the robot class. Do
that with this PR so it's separate.

Also, remove the duplicated main files from the template, and instead
fixup vscode to handle this properly.
2026-02-21 14:35:26 -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
PJ Reiniger
8f9fc4d1b6 [copybara] Import robotpy examples (#8608)
GitOrigin-RevId: 9ba4bc3040fa7e772f5a594039e78fc6c43d114e
2026-02-20 15:30:35 -08:00
Jordan Powers
9cd933fa14 [wpiunits] Fix incorrect magnitudes in some MutableMeasure mutations (#8620)
This PR fixes the magnitude units in `MutableMeasure#mut_acc` and
`MutableMeasure#mut_plus`.

Previously, both `mut_acc` and `mut_plus` were setting the base
magnitude using the unit-ed magnitude value. While this would work fine
for base units where `magnitude == baseUnitMagnitude`, this was creating
issues with derived units.

This PR also adds missing tests for the `MutableMeasure` class.
2026-02-20 15:29:53 -08:00
Gold856
1806cd2d78 [hal] Remove useless usage reporting return (#8625)
The value is not used anywhere and it also just returns 0 (was a value
from Netcomm in pre-2027).
2026-02-20 15:28:57 -08:00
Ryan Blue
0c44e63465 [wpilib] Make joystick unplugged warning better in cases of out of range axis/button (#8614)
Closes #8594 
Fixes #7700 
Also fixes DS HAL to zero out joysticks not received from DS.
2026-02-17 20:22:02 -08:00
Thad House
10fa2fced4 [wpinet] Switch macOS mDNSResolver to dispatch_queue (#8621)
The old thread based method had issues and occasionally segfaulted. And
was much more complex. This is much cleaner
2026-02-17 20:20:34 -08:00
Thad House
af01a72725 [wpilib] Enable ExpansionHub motors and servos on any set (#8619)
This more matches the existing FTC SDK. And removes the footgun of
needing to call set.
2026-02-17 20:19:52 -08:00
PJ Reiniger
1dbffb972f [robotpy] Fixup build after merge (#8618) 2026-02-15 10:22:58 -08:00
Peter Johnson
af865f8020 Merge branch 'main' into 2027 2026-02-15 00:51:21 -08:00
Ryan Blue
36c489247c [ntcore] Fix local client sending value updates before publish message (#8613)
Text frames were being queued while binary frames were sent immediately.
Change NetworkOutgoingQueue to send text frames immediately on local
connections. Add asserts since local connections should now not be
queueing at all.
2026-02-14 21:46:38 -08:00
sciencewhiz
77dfad97c6 [ci] Use wpilib docker-run-action fork (#8615) 2026-02-14 11:32:57 -08:00
Tyler Veness
245186cb15 Fix clangd #include warnings (#8565) 2026-02-11 12:15:02 -07:00
sciencewhiz
7ac0612397 [hal,wpilib] Update MatchTime docs for teleop and auto mode (NFC) (#8606)
Update Timer and JNI MatchTime functions to latest docs
2026-02-09 17:14:42 -08:00
Charlotte Wilson
1680e676b6 [wpimath, wpiutil] Use java_multiple_files for Protobuf (#8555)
Closes #8256
2026-02-09 17:11:57 -08:00
PJ Reiniger
227c89ab23 [copybara] Resync robotpy (#8585)
Project import generated by Copybara.
    
GitOrigin-RevId: fd000778e9b78c72cc7ca7b2ebe476129b78c6e0
2026-02-08 07:36:35 -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
sciencewhiz
19c61cc419 [upstream_utils] Update to SDL joystick mappings from 1-19-2026 (#8593)
Fixes #8103
2026-02-07 09:49:30 -08:00
Tyler Veness
2c5529d714 [wpimath] Speed up pose estimator correction computation (#8574)
In C++, we use a diagonal matrix to avoid an expensive matrix
multiplication. EJML doesn't have a diagonal matrix type, so in Java, we
use a double array and implement the multiplication manually.
2026-02-06 21:47:49 -08:00
Gavin P
7cd3790c7c [wpiunits] Make RPM an alias of RotationsPerMinute (#8595)
Currently the only name for this unit is `RPM`. This caused a bit of
confusion for a couple of my team members when we failed to find an RPM
unit, assuming it would be named `RotationsPerMinute` as is the standard
for almost all other units, such as `RotationsPerSecond`.

No corresponding changes have been made to wpilibc as it seems to
already work this way, with `rpm` being the abbreviation for
`revolutions_per_minute`.
2026-02-06 21:47:08 -08:00
PJ Reiniger
2d97cb928f [bazel] Upgrade hermetic python version to 3.13 (#8554)
Robotpy dropped support for 3.10 recently, so this updates to the next
lowest version. This will be helpful when the examples get merged into
`mostrobotpy`

There's not really a specific reason why I just jumped to 3.11 instead
of a newer version. If anybody suggests otherwise I will gladly bump it
higher.
2026-02-06 21:40:10 -08:00
NotTacos
664484306c [glass] Change match times for rebuilt (#8575)
The timer has changed for rebuilt's auto and teleop.
2026-02-06 21:39:12 -08:00
Thad House
85adbf990e [hal,wpilib] Switch to new game data (#8584)
Game data is now limited to 8 bytes, and comes through the UDP packets.
2026-02-06 21:38:15 -08:00
Thad House
ac45c694f3 [wpinet] Fix windows mDNS announcer long startup times (#8604)
The existing code takes 750ms to start per resolver. This is too long,
especially in mrccomm where we start 4 on initialize, and 3 any time the
team number changes.

Solve this by handling the async setup more correctly. Assuming it
returns pending, we're assuming the announcer is good. Then on stop(),
we cancel the register in case its still pending, wait for the callback,
and then deregister.
2026-02-06 21:37:11 -08:00
jpokornyiii
0a37317467 [examples] Adding XRP java and cpp examples for Timed Robot (#8599)
Adding an example (one C++ and one Java) for using TimedRobot with the
XRP.
2026-02-06 21:36:35 -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
Ryan Blue
77b2f9802e [ntcore] Fix local client behavior (#8588)
Fixes local clients receiving inconsistent data updates. Data was only
flushed to local clients on incoming websocket data (or when explicitly
flushed), so local clients on a quiet server would stop receiving
updates.

Revert some changes from #7997.
Instead of relying on periodic sends, always immediately send local data
updates to the wire for lower latency. This means that on local clients,
the periodic update rate and sendAll settings will be ignored, as all
data updates will be sent immediately.
2026-02-06 21:35:02 -08:00
FirstFox3
6b225bb1f1 [wpilib] Fix typo in TimedRobot.getLoopStartTime() docs (#8590)
Fixed a typo in the description of the getLoopStartTime function in both
C++ and Java TimedRobot class.

---------

Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2026-02-05 18:57:49 -07:00
Vasista Vovveti
3d92547d62 [cscore] Fix format specifier on Mac (#8602) 2026-02-05 18:56:52 -07:00
Thad House
a2a40b56d1 [bazel, gradle] Fix deprecation warnings for gradle 10 and Bazel build (#8597) 2026-01-31 16:36:41 -08:00
crueter
c89401250f [hal, wpilib] Usage Reporting: QFRCDashboard -> QDash (#8571) 2026-01-15 19:55:55 -07:00
Tyler Veness
8be7720a68 [sysid] Fix crash on partially empty raw data (#8572)
Fixes #8570.
2026-01-15 18:57:38 -07:00
Michael Lesirge
21b5389bbe [wpimath,cmd] Add multi tap boolean stream filter and multi tap trigger modifier (double tap detector) (#8307)
Add a simple tap counting filter for boolean streams. 

The filter activates when the input has risen (transitioned from false
to true, like when a button is tapped) the required number of times
within the time window after the first rising edge. Once activated, the
output remains true as long as the input is true. The tap count resets
when the time window expires or when the input goes false after
activation.

Example usage:
```java
    xbox.a()
      .multiPress(2, 0.2) // Detect a double tap within 0.2 seconds
      .onTrue(Commands.print("Double tapped A button"));
      
     xbox.y()
      .multiPress(2, 0.5) // Detect a double tap within 0.5 seconds
      .whileTrue(Commands.print("Y held after tap").repeatedly());
```

This is not a noise reduction and/or input smoothing filter, but it is
similar in usage to debounce, so I believe it could be considered a
filter, but am open to a better location.

I believe this would be a useful addition, as double/triple tapping a
button is a common control option in games, yet is not often utilized by
newer FRC teams. I believe adding it to WPILib in a standard way will
allow more teams to make the most out of their controls.
2026-01-14 20:22:07 -08:00
Joseph Eng
9e1258440b [wpimath] Fix Rotation3d interpolation and document extrinsic vs intrinsic (#8544)
Documents the extrinsic vs intrinsic semantics of `plus()` and
`minus()`. (`rotateBy()` was documented in [a previous
PR](https://github.com/wpilibsuite/allwpilib/pull/5508))
Fixes usage of `plus()` and `minus()` in `Rotation3d.interpolate()`.
(Fixes #8523)
Fixes incorrect usages of `plus()`, `minus()`, and `rotateBy()`
throughout `Odometry3d`.
Adds explanatory comments for some `plus()`, `minus()`, and `rotateBy()`
operations.
Fixes `TimeInterpolatableBuffer` not using twists for `Pose3d` (this was
just because I happened to notice it, it isn't really related to the PR)

To check all of our usages of `plus()`, `minus()`, and `rotateBy()`, I
marked them as deprecated, checked compile errors from `./gradlew
compileJava`, and then undeprecated them. You can see all of the spots
that showed up (at least on the Java side) by viewing the diff for
241109c.

I wanted to present this alternative to #8526 because the change has its
own quirks, there's little time before kickoff, and there would be no
code-side warning to teams (and mentors) already used to the current
behavior.
2026-01-14 20:16:24 -08:00
Austin Schuh
0001ddc7ec [bazel] Switch over to /DEBUG:FULL unconditionally (#8563)
This is faster everywhere.

Fixes #8517
2026-01-14 20:15:42 -08:00
PJ Reiniger
1cbc25bc36 [copybara] Resync commandsv2 (#8535)
This will be the last sync from the commandsv2
[repo](https://github.com/robotpy/robotpy-commands-v2), as it has now
been merged into
[mostrobotpy](https://github.com/robotpy/mostrobotpy/pull/226).

Doing this on its own to make the diffs smaller when doing a full
`mostrobotpy` sync, which will now have a lot of other new goodies
coming along for the ride.

---------

Co-authored-by: Default email <default@default.com>
2026-01-14 20:15:00 -08:00
Dave Oleksy
812a1b8e1a [hal] Add 2026 REV products for usage reporting (#8567)
Adding REV Easy Swerve and MAXSpline Encoder to usage reporting.

Co-authored-by: Dave Oleksy <dave.oleksy@revrobotics.com>
2026-01-14 20:14:20 -08:00
Tyler Veness
996af272e8 [wpilib] Fix C++ DCMotorSim constructor docs (#8568)
See
https://github.com/wpilibsuite/allwpilib/pull/8468#discussion_r2692411059.
2026-01-14 20:13:19 -08:00
PJ Reiniger
eccc2301ac [py] Add wpimath/kinematics tests (#8461)
Used Gemini to convert the C++ tests in wpimath/.../kinematics to
pytest. For ease of use required a better constructor for
`MecanumDriveWheelPositions`

I did this conversion months ago (before robotpy landed and before the
reorg), so new tests might be missing. At least its better than nothing
🤷

Broke the huge pr that does almost everything into parts so its easier
to review.

---------

Co-authored-by: David Vo <auscompgeek@users.noreply.github.com>
2026-01-12 19:14:14 -08:00
Peter Johnson
c2b339cfc9 [wpilib] OpModeRobot: set up notifier before calling observe starting (#8547)
This avoids a simulation race.
2026-01-12 19:11:58 -08:00
Ryan Blue
05225a29a7 [cmake] Fix datalog config file (#8546) 2026-01-12 19:11:35 -08:00
PJ Reiniger
762d1e8b93 [copybara] mostrobotpy to allwpilib (#8545)
Project import generated by Copybara.
GitOrigin-RevId: f10284b37498bb6a088891ca41f160793ec7fd90
2026-01-12 19:11:02 -08:00
Tyler Veness
7e1260b003 [wpilib] Replace unit .to<double>() with .value() (#8548)
This is consistent with the rest of the library. I left instances alone
which intended a specific typecast.
2026-01-12 19:10:10 -08:00
Tyler Veness
00fa8361dd [wpimath] Reorganize LinearSystem factories (#8468) 2026-01-12 19:09:35 -08:00
Tyler Veness
89d0759ef2 [wpimath] Remove unused #includes (#8549)
This is based on a filtered list of #includes clangd reported were
unused.
2026-01-12 19:08:21 -08:00
Kevin-OConnor
18249badc0 Add 2026 game specifics (#8558)
Co-authored-by: Peter Johnson <johnson.peter@gmail.com>
Co-authored-by: Gold856 <117957790+Gold856@users.noreply.github.com>
2026-01-12 19:07:51 -08:00
Austin Schuh
1724e59f8d [bazel] Move the easy pieces of the build over to bzlmod (#8542)
bzlmod is the future, and makes it easier to depend on AOS.

---------

Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2026-01-12 15:30:31 -07:00
Dustin Spicuzza
0fd8210b5a [ntcore] Release ListenerStorage mutex before stopping thread (#8562)
If the thread is still running then it will deadlock.
Fixes #8561
2026-01-11 02:29:49 -08:00
Tyler Veness
67ae589c11 [wpimath] Replace convolution operator with multiplication in derivations (NFC) (#8557) 2026-01-10 11:44:50 -08:00
sciencewhiz
b82d204525 Update vendordep frcYear to 2026 (#8552) 2026-01-06 16:29:45 -08:00
PJ Reiniger
6654627016 [bazel] Improve path resolution during pybind build file generation (#8522)
This anecdotally fixes a problem that occurs when building with bzlmod.
At least for me this fixes the problem, and now that there is a function
for it it can be easier to deal with any other special casing that needs
to happen (windows, remote execution, etc). It is still a bit naive, but
should fix the major problem at the moment.
2026-01-04 00:59:54 -08:00
PJ Reiniger
32cd2ddf8e [upstream_utils] Remove patch that results in building with NDEBUG causing ODR issues (#8539)
Semiwrap / meson / robotpy define `NDEBUG` when building their software
in all modes, while `allwplib` only does it when building debug. This
causes the size of `DenseMap` to differ between the shared libraries
built here, and the extension modules built in `mostrobotpy`, causing
segfaults when you try to execute code that uses `DenseMap`. This is not
a problem with the robotpy code in `allwpilib`, because bazel uses the
exact same compiler flags when building the shared libraries and
pybind11 extensions.
2026-01-03 13:32:16 -08:00
PJ Reiniger
ccb3266753 [upstream_utils] Remove patch that results in building with NDEBUG causing ODR issues (#8540) 2026-01-03 13:31:26 -08:00
PJ Reiniger
5a3f2ce13a [gradle] More gradle 9 codesign updates (#8536)
This replicates the fix in #8531 for other binaries that are still tripping up CI.
2026-01-02 13:33:00 -07:00
PJ Reiniger
8518b7014c [py] Add wpimath/geometry tests (#8460) 2026-01-02 09:10:02 -08:00
Charlotte
32fa124166 [upstream_utils] Upgrade JSON library to v3.12.0 (#8509)
Closes #7903.
2026-01-02 08:51:16 -08:00
sciencewhiz
44ca9e816d [build] Add LineLength suppression for generated version file (#8530)
I managed to get a length of 101 characters when building locally
2026-01-02 08:47:48 -08:00
sciencewhiz
d6b243fb46 [build] Update exec for Gradle 9 (#8531) 2026-01-02 08:47:25 -08:00
sciencewhiz
8efdab81fe [build] Preserve file permisions and timestamps in archives (#8532)
Fixes tools not being executable.
2026-01-02 08:47:10 -08:00
sciencewhiz
71a788e20b [docs] Update references to 2026 (#8534) 2026-01-02 08:46:22 -08:00
Ryan Blue
d3159c2554 [glass] Fix server mode (#8508) 2025-12-31 09:41:26 -08:00
sciencewhiz
699a0583fa [ci] Fix docs publishing after reorg (#8510) 2025-12-31 09:40:56 -08:00
Gold856
ae84f6d2c5 [wpical] Refactor to use WPILib libraries and modern C++ conventions and improve UX (#7796)
wpical was unable to use wpimath and its dependent libraries because
Ceres was compiled with a different version of Eigen. Now that the Ceres
build has been redone and shipped in #8151, we can now use wpimath and
our C++ apriltag wrapper in wpical, allowing for major refactors. This
includes:
* Using `to_json` and `from_json` specializations to concisely serialize
and deserialize all JSON files instead of manually handling JSON.
* Removal of the `Fieldmap` and `Pose` classes, which were duplicates of
the `AprilTagFieldLayout` and `Pose3d` classes respectively.
* Using `AprilTagDetector` instead of the raw libapriltag library.
* Using `Pose3d` instead of raw Eigen matrices.

In addition, several other refactors were made to make the code more
readable and to fix several UX issues and crashes. This includes:
* Eagerly parsing every JSON file when selected by the user. This means
JSON files are only parsed once on selection, instead of every time a
downstream function wants to use the data. This also means invalid JSON
can be detected upfront and a specific error shown immediately instead
of a catch all error when trying to calibrate.
* Using `std::optional` to indicate a calibration failed instead of
status codes.
* Processing videos on separate threads to not block the UI thread and
take advantage of parallelization for camera calibration. (2x speedup on
my laptop)
* Removing the OpenCV calibration option, since mrcal should be better
in every scenario.
* Showing a progress bar for camera calibration.
* Breaking up the massive `DisplayGui` function into separate functions
which contain code for different popups. This also allowed for better
organization and scoping of static variables.
* Renaming variables to make their purpose more clear.
* Displaying the tags present in a field layout when trying to combine
multiple field layouts.

Fixes #7722.
2025-12-31 09:28:51 -08:00
sciencewhiz
8fbaf4c2f5 [ci] Update github actions to use Node 24 versions (#8521)
https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/

Done on the 2027 branch since the force change to Node 24 should (tm)
happen after the last 2026 release. And in case it breaks something and
we do need to backport to 2026, the release timeline on 2027 is not as
strict
2025-12-31 09:13:01 -08:00
sciencewhiz
32fcf5bc27 [build] Add datalog project to docs build (#8511) 2025-12-31 09:11:56 -08:00
Charlotte Wilson
f395954d3c [ci] Update Android NDK version to R27D in CMake workflow (#8525)
https://github.com/android/ndk/wiki#release-schedule
2025-12-31 09:08:33 -08:00
PJ Reiniger
40fb9ff562 [copybara] mostrobotpy to allwpilib (#8503)
Resync with `mostrobotpy`

This mostly involves the big "ignore almost everything in the HAL
project" and some fixups for the Addressable LED classes.

Required two small hand fixes to get it building over here with bazel,
and with more compiler warnings on.

I also manually zeroed out the `repo_url` field in the toml files to
avoid unnecessary churn whenever it goes from a release build to a
development build. I already did this with `version` field in there, and
will do a follow up PR that updates the copybara script to do it
automatically.

---------

Co-authored-by: Default email <default@default.com>
2025-12-31 09:06:01 -08:00
PJ Reiniger
bdc9391738 [py] Fix opmodes (#8498)
Co-authored-by: David Vo <auscompgeek@users.noreply.github.com>
2025-12-31 09:05:00 -08:00
PJ Reiniger
1bbb284ad1 [py][wpiutil] Add type caster for WPI_String (#8500)
This adds a type caster for `WPI_String` so that pybind11 can more
easily auto-convert between that and strings. This helps remove the need
to do things like
[this](f1d77244c3)
in the opmodes fixup
2025-12-31 09:03:24 -08:00
Thad House
632eb0922d [build] Bump versioning plugin to ignore non-annotated tags (#8505) 2025-12-24 07:40:47 -06:00
PJ Reiniger
419ef31e30 [copybara] Zero out high churn 'repo_url' in .toml files (#8504)
This is a high churn change whenever `mostrobotpy` switches from
pointing to `release-2027` to `development-2027`. The value isn't used
by the bazel build scripts, so there is no reason to have a zero impact
change on ~11 files muddying up the synchronization diffs.

In the `allwpilib -> mostrobotpy` direction, we update [this
](https://github.com/robotpy/mostrobotpy/blob/main/rdev.toml) config
file and run
[this](https://github.com/robotpy/mostrobotpy/blob/main/rdev.sh) script
which updates it in that repo during.

I manually did this change in #8503, but this will do it automatically
in the future
2025-12-24 07:39:24 -06:00
Bryce Roethel
ab3af00d07 [wpimath] TrapezoidProfile.State implement StructSerializable (#8499)
Seems like this was missed in #8163
2025-12-21 10:08:32 -06:00
Tyler Veness
0349524f80 [wpilib] Remove MotorController::StopMotor() (#8483)
It does the same thing as Disable() in practice, and MotorSafety has its
own StopMotor() function.
2025-12-17 21:18:47 -08:00
PJ Reiniger
a38499dcd7 [py] Fixup new acceleration classes (#8459)
I tried to sync `mostrobotpy` with `allwpilib` and was getting a
compilation error I had not seen before when it tried to do the stub
generation (which `allwpilib` does not do).

Luckily, I was able to debug it here by writing some unit tests (i.e.,
having Gemini convert the C++ tests into python) that failed in a
similar way. The main problem was needing to write a custom constructor
for the class and adding a `force_type_casters`. I used `ChassisSpeed`
as my main example, but I did not copy all of the other custom code like
overriding the index operator, `__repr__` operator, feet helpers, etc. I
can gladly add those in.

In the future, we should start enforce a policy that if you add a C++ or
Java unit test, you also have to add a python test. That developer might
have gotten more stuck on the minutia of how to fix it, but this problem
would have at least been caught earlier before it landed.
2025-12-17 19:19:12 -08:00
Thad House
d6b54bbae2 [ntcore] SetServerTeam: Use Systemcore name/addresses (#8314) 2025-12-16 22:28:45 -08:00
Thad House
e2d492ac3f [ntcore] Add ability to announce mDNS for server (#8373)
We can use this as a new way of resolving addresses.
2025-12-16 22:26:56 -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
Thad House
5a22abb85b [hal] Explicitly wait for mrccomm server to be ready (#8490)
Avoids a race if robot ready happens before mrccomm is fully booted
2025-12-16 22:24:13 -08:00
Sam Carlberg
5bebaebcc0 [cmd3] Report incorrect coroutine usage on the variable use site (#8481)
This makes error messages point directly at the variable use, instead of
on the enclosing AST node:

```
error: `outerCoroutine` may not be in scope
    outerCoroutine.yield()
    ^

error: `outerCoroutine` may not be in scope
    consume(x, outerCoroutine);
               ^
```

instead of 

```
error: `outerCoroutine` may not be in scope
    outerCoroutine.yield()
                        ^

error: `outerCoroutine` may not be in scope
    consume(x, outerCoroutine);
           ^
```
2025-12-16 22:23:30 -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
Thad House
8b10a0546d [hal] Fix typo in NumOccurrences (#8487)
Closes #8439
2025-12-16 22:20:48 -08:00
Tyler Veness
718f2f7ccd [ci] Upgrade to wpiformat 2025.79 (#8491)
wpiformat now skips binary files matching a list of extensions.

https://github.com/wpilibsuite/styleguide/blob/main/wpiformat/wpiformat/__init__.py#L483-L504
2025-12-16 22:20:21 -08:00
sciencewhiz
f668e10197 [docs] Update Doxygen Awesome to 2.4.1 (#8494)
Supports Doxygen 1.14, and should be better with Doxygen 1.15 that we
use, compared to the current version.
Improves, but does not fix #8486. The sidebar now covers the search
results, rather then both bleeding through

<img width="1206" height="1969" alt="image"
src="https://github.com/user-attachments/assets/e8c0cefd-a72a-4c41-a5bf-c191752250f4"
/>
2025-12-16 22:19:47 -08:00
Tyler Veness
f9ee67e85f [wpilib] Move motor controller .cpp files to mirror headers (#8484) 2025-12-15 10:54:11 -07:00
Tyler Veness
1b2f051b4b [docs] Replace instance of PWMSpeedController (#8478) 2025-12-14 08:06:02 -08:00
Peter Johnson
f6ef155166 [wpilib] LinearOpMode: wait for mode change to return from OpModeRun (#8477)
We need to wait, or otherwise OpModeRobot will immediately reinstantiate
and re-run the opmode, which is generally undesirable (e.g. for
autonomous).

Fixes #8475.
2025-12-13 21:45:22 -08:00
PJ Reiniger
e2c9af862e [py] Fix maven coordinates for native downloads (#8474)
This got missed in the reorg, and these values aren't actually used for
anything when building in `allwpilb`, but we might as well fix them here
to make the copybara process easier.
2025-12-13 21:44:31 -08:00
Thad House
af0a3e9c2f [build] Update to gradle 9.2.0, use new reorged plugins (#8471) 2025-12-13 21:44:00 -08:00
Thad House
bcb5c5c16c [hal] Fix controldataproto SupportsOpModes (#8476)
It wasn't updated, so DS was always assumed to be NI DS
2025-12-13 16:07:23 -08:00
Benjamin Hall
3dc334c1ee [wpimath] Fix ResetTranslation and ResetRotation in PoseEstimator and PoseEstimator3d causing the robot to teleport (#8285)
Fixes https://github.com/wpilibsuite/allwpilib/issues/8284.

If we have vision updates at the time of the `Reset*` call, we can
correct the translation/rotation of the new odometry pose by adding a
new vision update where:
- `ResetTranslation`: the translation is hard-coded to the new
translation, and the rotation components are set to those of the latest
vision update (prior to clearing the map).
- `ResetRotation`: the rotation is hard-coded to the new rotation, and
the translation components are set to those of the latest vision update
(prior to clearing the map).
2025-12-13 15:53:53 -08:00
PJ Reiniger
ea71bdfba6 [py][cmd2] Fix opmodes merge (#8473)
Looks like a build failure got lost in the landing order of python
commands and the big opmode change. This makes it compile again, based
on the java / C++ changes from the opmode PR.
2025-12-13 12:11:29 -08:00
Peter Johnson
dacded37e5 [hal, wpilib] Add OpMode support (#7744)
User code:
- OpModeRobot used as the robot base class
- LinearOpMode and PeriodicOpMode are provided opmode base classes
- In Java, annotations can be used to automatically register opmode classes

Additional user code functionality:
- OpMode (string) is available in addition to the overall
auto/teleop/test robot mode
- OpMode does not indicate enable (enable/disable is still separate)
- The HAL API uses integer UIDs; these are exposed at the user API level
as well for faster checks
- User code creates opmodes on startup (these have name, category,
description, etc).

DS:
- DS will present opmode selection lists for auto and teleop for
match/practice. During a match, the DS will automatically activate the
selected opmode in the corresponding match period.
- For testing, an overall mode is selected (e.g. teleop/auto/test) and a
single opmode is selected

Future work:
- Command framework support/integration
- Python annotation support
- Unit tests (needs race-free DS sim updates)
- Porting of examples

Co-authored-by: Joseph Eng <91924258+KangarooKoala@users.noreply.github.com>
2025-12-12 20:25:57 -08:00
Peter Johnson
2a41b80e00 [wpilib] Fix Watchdog to always ack notifier (#8472) 2025-12-12 20:19:54 -08:00
PJ Reiniger
0049c6f23f [py] Add copybara scripts (#8368)
These are the scripts I've been using to sync between mostrobotpy and
here. I debated putting it in the "source of truth" that is
`mostrobotpy` , but I think it makes more sense here since it already
has bazel set up, and I've also recently added the ability to sync the
`commands-v2` repository, so having it all in one copybara script makes
sense.

This includes a helper python script to make it a little bit easier to
run.
2025-12-12 20:06:19 -08:00
PJ Reiniger
13abb3d332 [py][cmdv2] Add python commands-v2 to build system (#8380)
This hooks up the recently landed robotpy commands v2 to the build
system.

The swerve controller command was deleted to match #8119
2025-12-12 20:05:31 -08:00
Tyler Veness
cca035787c [upstream_utils] Upgrade to Sleipnir 0.3.3 (#8463) 2025-12-12 19:40:43 -08:00
Thad House
d830c41063 [wpinet] Add option to use directly linked Avahi from cmake (#8469) 2025-12-12 19:39:26 -08:00
Peter Johnson
cbe447aad7 [hal] Notifier: Reset signal object on ack (#8466)
This is needed to avoid spurious wakeups in WaitForObject due to a
previous alarm having set the signal object.
2025-12-11 22:31:49 -08:00
Peter Johnson
5aaf2d7138 [hal] Handle: free on operator= (#8462) 2025-12-11 22:31:30 -08:00
Peter Johnson
06a9a055b3 [hal] Notifier: simplify ack API (#8457)
Adding an ack parameter to both set and cancel is cleaner than adding
all the set alarm parameters to the ack function. It also provides an
ack-and-cancel method.
2025-12-09 19:28:15 -08:00
Zach Harel
936be71a7d [wpimath] Add ChassisAccelerations and drivetrain accelerations classes and add forward and inverse kinematics for accelerations to the interface (#8185)
ChassisAccelerations and the drivetrain acceleration types are added in
both Java and C++. `ChassisAccelerations` is basically just
`ChassisSpeeds` but for accelerations!
`DifferentialDriveWheelAccelerations`, `MecanumDriveWheelAccelerations`,
and `SwerveModuleAccelerations` are the acceleration equivalent of the
drivetrain speeds types.

In Java, the `Kinematics` interface now has an additional generic
parameter `A` which represents the accelerations, and
`toChassisAccelerations` and `toWheelAccelerations` methods, which are
implemented the same way as `toChassisSpeeds` and `toWheelSpeeds`.

Protobuf and struct classes were also added for all four classes in Java
and C++.

---------

Signed-off-by: Zach Harel <zach@zharel.me>
Co-authored-by: Joseph Eng <91924258+KangarooKoala@users.noreply.github.com>
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2025-12-08 17:25:07 -07: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
Joseph Eng
59edbdd3cc [halsim_gui, wpilibc/j] Fixups for joystick outputs (#8443)
#8385 changed gamepad types to follow SDL_GamepadType, so 20 and 21
(previously `kHIDJoystick` and `kHIDGamepad`, respectively) are no
longer valid constants. This meant that after leaving the disconnected
state of the sim GUI, `GamepadType.getGamepadType()` would return null
(since it didn't match any constants). Since there aren't analogous
generic joystick and gamepad constants anymore, this PR changes
GlfwSystemJoystick and KeyboardJoystick to both unconditionally report
as kStandard.

This also updates the GenericHID.SetRumble doc comment to reflect the
two new types of rumble and changes some switch labeled statement groups
to use switch rules instead. If we want to keep on using switch labeled
statement groups (e.g. for consistency with C++, though
GenericHID::SetRumble currently uses if-else), then I could drop the
last change- I just made it since GenericHID.setRumble() previously used
switch rules and general switch rules are nice since there's no risk of
fall-through.
2025-12-06 09:17:48 -08:00
Peter Johnson
baa6379267 [wpimath] Add usage reporting for state-space classes (#8453)
- LinearQuadraticRegulator
- Kalman filters
- Pose estimators
- LinearSystemLoop

Fixes #2925.
2025-12-06 09:17:02 -08:00
Peter Johnson
0d1dd84e86 [wpilib] LEDPattern: Add usage reporting (#8452) 2025-12-06 09:16:45 -08:00
sciencewhiz
8411314850 [build] Build examples with v3 commands & javacPlugin (#8456) 2025-12-05 22:53:14 -08:00
Levi
a61866912b [hal] Rename Lumen to Lumyn in usage reporting (#8455) 2025-12-05 19:13:39 -08:00
Thad House
0b44b8de4e [wpiutil] Fix cmake build on windows when only MulticastServiceAnnouncer is used (#8454)
The pragma lib was only in the resolver. But if you had a statically
linked library that only used the announcer, the import wouldn't get
resolved.
2025-12-05 17:30:21 -08:00
Peter Johnson
57c40a3dfc [hal] Add more usage reporting constants (#8451)
Fixes #7234 
Fixes #6919
Supports #2925
Supersedes #8212 
Supersedes #7708
2025-12-05 15:20:49 -08:00
Peter Johnson
6f86f533e5 [wpiutil] MemoryBuffer: Fix zero extending size_t warning on Win32 (#8450) 2025-12-05 10:55:28 -08:00
Peter Johnson
934f8d9c15 [hal,wpilib] Fix TimedRobot notifier race (#8445)
It was possible for the alarm to fire between the set alarm and ack,
resulting in a hang on next wait. It's not possible to ack before set
alarm due to a race in sim step timing, so the fix is to provide an
atomic ack and set alarm; the easiest way to implement this in the API
was to change ack to optionally also set the alarm again.
2025-12-04 09:59:59 -07:00
Austin Schuh
d1b1703c86 [bazel] Use lowercase repo name (#8441) 2025-12-03 18:14:34 -08:00
Tyler Veness
08784dc2d1 [upstream_utils] Upgrade to Sleipnir 0.3.2 (#8323)
Also includes a C++ benchmark, which has a Java counterpart in #8236.
2025-12-01 13:51:28 -07:00
Peter Johnson
feea24251f [wpilib] Move ExpansionHub to hardware/expansionhub (#8440)
These need to be moved out of the org.wpilib root for Java
modularization, and in general it's cleaner.
2025-12-01 13:47:01 -07:00
sciencewhiz
ccfbf5f5b3 [commands] Add conflicts for Commands v2 & v3 vendordeps (#8438) 2025-11-30 11:12:12 -08:00
Peter Johnson
42992953ed [wpiutil] Move Color and Color8Bit from wpilib to wpiutil (#8437)
Removes one of the org.wpilib.util package conflicts for modularization.

Only a few minor tweaks were required to remove the wpimath dependency.
2025-11-30 11:11:48 -08:00
sciencewhiz
e902a98601 [examples] Reorganize templates to use CommandsV2 (#8432)
Change Commandbased to Commandv2
Run example check on templates
2025-11-29 20:46:32 -08:00
sciencewhiz
5aa0b7afea Update DevelopmentBuilds for Alpha 3 (#8435)
wpimathVersion was removed in wpilibsuite/gradlerio#804
2025-11-29 20:45:05 -08:00
David Vo
5514a1285d [bazel] Remove unused rules_bzlmodrio_jdk (#8436)
This previously provided a Java 17 toolchain. We now use (and require)
Java 21.
2025-11-29 20:44:33 -08:00
Ryan Blue
ded6790bcd [cmake] Only add wpilibj to generated config if Java is enabled (#8434)
Fixes #8422
2025-11-29 20:44:02 -08:00
Tyler Veness
d87e109a4e [ci] Free disk space in Gradle and Bazel builds (#8405) 2025-11-29 17:13:29 -08:00
Tyler Veness
473f2a0aff [wpilibc] Fix compilation failure (#8431) 2025-11-29 13:59:29 -08:00
Peter Johnson
02c8d5c9db [hal] Revamp notifiers (#8424)
This changes the HAL notifier interface to:
- Use wpiutil signal objects. This means waiting is done through the
`WPI_WaitObject` API instead of a dedicated function and allows for
higher level code to simultaneously wait on notifiers and other events.
- Interval timers are supported at the HAL layer
- Handlers are now required to acknowledge notifications. This is
invisible to users unless they're directly using the HAL API.
- For interval timers, an overrun count is maintained to detect if the
handler didn't acknowledge

The underlying implementation still uses condition variables for the
actual waiting. In basic testing using this approach seemed to be lower
jitter than timerfd.

Currently, the simulation and systemcore implementations are nearly
identical except for a few additional sim hook bits. This could be
refactored, but keeping them separate may make sense to keep the
systemcore implementation easy to read and reason about, or if we ever
choose to use a different underlying timer implementation on systemcore.

The simulation side API is unchanged in form but does change in
function--waiting for notifiers now only waits for currently running (or
newly signaled) notifiers to acknowledge. To avoid a race condition in
sim stepTiming, users of the low level API must make any alarm updates
(especially for one-shot alarms) prior to acknowledging the previous
alarm.

The only current use of the interval timer feature is the `Notifier`
class. The `TimedRobot` implementation still uses a single notifier and
its own interval timing logic to ensure consistent callback order. Using
separate notifiers for each user-level interval would substantially
increase complexity. `Watchdog` also doesn't use the interval timer, as
it's looking for an amount of time since the last `set` call rather than
a recurring interval time.

To reduce flicker, the sim GUI uses a fade out when a timeout goes from
set to unset.

This fixes tsan for wpilib and commands, and also fixes some spurious
test failures.
2025-11-29 11:00:18 -08:00
Peter Johnson
704b6ccaee Merge branch 'main' into 2027 2025-11-29 10:41:16 -08:00
Tyler Veness
a79f86ade3 [wpimath] Refactor StateSpaceUtil into separate files (#8421)
* Moved makeWhiteNoiseVector() to random.Normal.normal()
* Moved isControllable() and isDetectable() to system.LinearSystemUtil
* Renamed makeCostMatrix() to costMatrix() (Java)
* Renamed makeCovarianceMatrix() to covarianceMatrix() (Java)
* Renamed MakeCostMatrix() to CostMatrix() (C++)
* Renamed MakeCovMatrix() to CovarianceMatrix() (C++)
* Removed deprecated poseTo3dVector(), poseTo4dVector(), poseToVector()
* Removed clampInputMaxMagnitude()
* We don't use it, and Eigen has this functionality built in via `u =
u.array().min(u_max.array()).max(u_min.array());`
* Simplified implementation of desaturateInputVector()
2025-11-29 10:28:38 -08:00
Tyler Veness
c8e6ce1ca4 [wpimath] Rename variables in Twist tests (#8420)
Exp() now returns a transform instead of a pose.
2025-11-29 10:26:32 -08:00
Peter Johnson
a4aad63dd4 [hal,tests] Use waitForProgramStart in tests (#8429)
Change setProgramStarted to accept a boolean so it can be set back to
false by tests. This allows properly waiting for program start in tests.
2025-11-29 10:10:01 -08:00
David Vo
32d3ec0218 [bazel] Remove unused bzlmodrio-ni dependencies (#8430) 2025-11-29 10:09:29 -08:00
Tyler Veness
b482fa02df Shorten wpiformat config (#8427) 2025-11-27 17:30:06 -08:00
Tyler Veness
a802855e0c [upstream_utils] Upgrade to Eigen 5.0.1 (#8428) 2025-11-27 17:29:44 -08:00
Tyler Veness
c9b989ac6a [ci] Upgrade to wpiformat 2025.77 (#8426)
This release associates .cpp and .hpp files as C++ files by default.
2025-11-27 11:45:18 -08:00
Keagan Kautzer
769ce5e9fa [wpiunits] Rename AngularMomentumUnit.mult to per (#8409)
Fixes #8408
2025-11-23 14:40:30 -08:00
Tyler Veness
cba939cf43 [wpimath] Remove redundant parentheses in TransformBy() (#8419) 2025-11-22 20:20:44 -08:00
DeltaDizzy
7fdb42b9d9 [bazel] Add datalog dev targets (#8418) 2025-11-22 13:41:20 -08:00
David Vo
6059cc8b79 [ci] Build only publish artifacts in Bazel cross-compile jobs (#8416)
#8363 split all the cross-compilation into separate jobs, however these
jobs are still also building the world (including the tests) targeting
the host.

Since `//:publish` and its dependencies are transitioned to target the
desired platforms for each artifact, `bazel build //:publish` in the CI
jobs that aren't running tests to only build what we actually care about
in these jobs.

This saves around 1 to 1.5 minutes for each cross-compile job with 100%
cache hit rates.
2025-11-22 08:36:17 -08:00
Ryan Blue
f6b4ad575b [ci] Pin docker-run-action and remove rm command (#8415)
The fix was made but has not been tagged.
2025-11-22 07:55:44 -08:00
Peter Johnson
e47b4a5c3b [wpilib] Color: Improve string support (#8403)
Now rgb() and color constants are supported.

Changed from constructor to fromString() factory function to enable
directly returning color constant values.
2025-11-21 16:41:05 -08:00
Thad House
32fc543dc8 [hal,wpilib] Add Touchpad support (#8401) 2025-11-21 13:57:11 -08:00
Peter Johnson
8546d301e3 [wpiutil] Constexprify parse_integer and kin (#8411)
Also use requires instead of enable_if.
2025-11-21 12:57:41 -08:00
David Vo
e2cbde2061 [ci] Use Java headers for macOS Bazel build (#8413)
I'm not entirely sure why Java header compilation is disabled for the
macOS build. But this option will be causing rebuilds to happen more
often than strictly necessary.

[Turbine](https://github.com/google/turbine) takes Java class sources
and spits out .class files with all method bodies, and private fields
and methods stripped. This provides a .jar with sufficient information
on the classpath to build dependent Java libraries without depending on
the implementation in the build graph.
2025-11-21 12:53:17 -08:00
David Vo
84aec2b8c1 [ci] Remove Java and deprecated Bazelisk setup from Bazel workflow (#8412)
We download the JDK in the workspace and tell Bazel to use it for all
Java actions in our config, so we don't need to download another one.


99af9d775c/.bazelrc (L12-L15)

The
[bazelbuild/setup-bazelisk](https://github.com/bazelbuild/setup-bazelisk)
action is deprecated, and is redundant with the
[bazel-contrib/setup-bazel](https://github.com/bazel-contrib/setup-bazel)
action we use after it.
2025-11-21 12:52:34 -08:00
DeltaDizzy
51190bcf64 [readme] Update Bazel resource-limiting commands (#8407)
`--local_ram_resources=value` and `--local_cpu_resources=value` have
been replaced by `--local_resources=[memory|cpu]=value`, so the Bazel
README is updated to recommend the new form.
2025-11-21 12:48:41 -08:00
Tyler Veness
99af9d775c Update wpiformat config filename in .gitattributes (#8406) 2025-11-20 20:33:04 -08:00
PJ Reiniger
fbabcc2022 [ci] Run robotpy gen steps in series instead of simultaneously (#8404)
The update yaml step _might_ cause changes that would affect the build
file generation. Since `bazel run //:write_robotpy_update_yaml_files`
runs them all at once, user that was using the github action to fix
their python stuff would end up having to run it twice.

By running the steps individually in series, this should be able to get
it in one swoop.
2025-11-18 21:30:26 -08:00
Thad House
148ed63499 [wpinet] Directly link to mDNS APIs on Windows (#8374)
These were added in Windows 10 1703. Technically Windows 10 in general
is out of support, but versions of Windows 10 older than that are _well_
out of support. And we do directly link to other APIs that are newer. So
no need to do the dynamic linking.
2025-11-18 17:15:15 -08:00
Ryan Blue
a5ccd1795e [wpilibc] Fix PWM Sendable accepting pulse time in ms (#8400) 2025-11-18 17:14:21 -08:00
Gold856
7cd0ef5bd9 [docs] Revert "Update readme to say Xcode is required" (#8397)
This reverts commit 49b4b064cf  (#7892).
2025-11-18 17:14:01 -08:00
Warren Reynolds
bd7a88a6d0 [examples] Fix order of Swerve Modules in Odometry Update (#8396)
The order of the Swerve Modules in the m_odometry.Update call needs to
match the order they are defined in the creation of the kDriveKinematics
object.
2025-11-18 17:13:27 -08:00
Gold856
8e8c657e12 Remove gfortran mention in README (#8398)
Accidentally dropped in merge commit
ed7982563b due to
3b7d0e7bf5 also modifying adjacent lines.
2025-11-18 17:12:55 -08:00
PJ Reiniger
9bfb030b46 [robotpy] Improve debug information failures that require running scan-header, update-yaml, and update-build-info (#8388)
Fixes #8386 

Was already working on this when more people started hitting issues so I
prioritized getting this PR up. This updates the wrapper script to look
for the 3 biggest categories of "everything should be fine if you run
this step first" tool failures.

Co-authored-by: Gold856 <117957790+Gold856@users.noreply.github.com>
Co-authored-by: David Vo <auscompgeek@users.noreply.github.com>
2025-11-17 15:37:41 -07:00
Tyler Veness
aba592bec0 [ci] Upgrade to wpiformat 2025.69 (#8394) 2025-11-17 15:36:32 -07:00
Thad House
ce6fd225a6 [hal,wpilib] Add support for joystick outputs (#8385)
Support joystick outputs, including Rumble and LEDs.

Also requires an update to Joystick descriptors, as that has also
changed in mrccomm to support showing what outputs are supported.
2025-11-17 15:36:14 -07:00
Keagan Kautzer
5db6d2f500 [cmd2] Revert wait back to waitSeconds (#8391)
Fixes #8272
2025-11-16 16:57:47 -08:00
Peter Johnson
0e621e8ec1 [ci] Remove command robotpy PR responder (#8392)
This is no longer required with the merge of Python commands.
2025-11-16 16:57:10 -08:00
David Vo
2cc46dd68c [bazel] Update rules_jvm_external to version 6.8 (#8389)
The commit we were pinned to
(3089931487)
ended up in a release.

https://github.com/bazel-contrib/rules_jvm_external/releases/tag/6.8
2025-11-16 14:22:18 -08:00
sciencewhiz
7b455e663c Update ThirdPartyNotices for 2027 reorg (NFC) (#8384) 2025-11-16 14:17:17 -08:00
Tyler Veness
b63743645f [wpimath] Only print Sleipnir diagnostics on test failure (#8382)
Bazel and CMake's CTest already do this by default since they run tests
in parallel, but Gradle doesn't.
2025-11-15 17:04:09 -08:00
sciencewhiz
34a72b71e1 [build] Fix 2027 java examples publishing (#8383) 2025-11-15 17:03:55 -08:00
David Vo
87c3c1fbc8 [bazel] Remove duplicate gson maven library (#8381)
Squashes the following warning:

```
DEBUG: /home/buildbuddy/workspace/output-base/external/rules_jvm_external/private/rules/coursier.bzl:775:18: 
Found duplicate artifact versions
    com.google.code.gson:gson has multiple versions 2.13.1, 2.10.1
Please remove duplicate artifacts from the artifact list so you do not get unexpected artifact versions
```
2025-11-15 08:32:39 -08:00
PJ Reiniger
1a99a348cb [robotpy] Mirror robotpy's commands-v2 (#8369)
Project import generated by Copybara.

GitOrigin-RevId: 715c8e8372d936f447f2937aab6b1a22dc619126
2025-11-13 21:55:54 -08:00
Tyler Veness
6e6f8dd7cc [cmd2] Fix include style of generated controller classes (#8372) 2025-11-13 21:32:45 -08:00
Benjamin Hall
95cb38e6df [wpimath] Fix ElevatorSim::GetCurrentDraw() in C++ (#8370)
The Kv calculation in C++ was missing a negative sign compared to the Java implementation.
2025-11-13 11:48:43 -07: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
Tyler Veness
23906ee2f7 [wpiutil] Add JNI array factories for more types (#8355)
The Sleipnir Java bindings needed these.
2025-11-11 18:06:55 -08:00
Tyler Veness
1705b2d61c Upgrade wpiformat and use clang-format's include sorting (#8350)
This PR also uses the newly added -default-branch flag to generate the list of changed files with respect to the correct branch (2027).
2025-11-11 18:05:12 -08:00
Austin Schuh
a0f4727179 [ci] Run each of the various bazel builds in a separate worker (#8363)
We are running out of disk space.  If we split the
build up more in parallel, that'll use less space in each build.

Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-11-11 18:03:47 -08:00
Ryan Blue
418b3814bc Change SystemCore to Systemcore (#8359) 2025-11-10 18:18:58 -08:00
Ryan Blue
e5f8aa2cf4 [cmd2] Rename vendordep (#8357) 2025-11-10 18:18:14 -08:00
PJ Reiniger
71eab3524e [ci] Add hal mrc comm to pregen (#8360) 2025-11-10 18:17:33 -08:00
PJ Reiniger
dc9e70ef05 [ci] Decrease CI verbosity (#8361)
Offline conversations have pointed out that the bazel output is very noisy upon a failure. The -k that was there for a while was recently deleted in another PR, and this one removes --verbose_failures. --verbose_failures prints all of the command line arguments, which can be quite lengthy and make it harder to find the actual compiler error.

This also removes the -vv from the clang-tidy step. I have found it very hard to find the actual errors when its printing out all of the debug information.
2025-11-10 18:16:56 -08:00
Ryan Blue
a9fd0c3845 [hal] Save NT listener handle (#8356) 2025-11-10 16:49:36 -08:00
Tyler Veness
83465c291a [wpimath] Port Sleipnir nonlinear problem tests (#8358)
This is a copy of Sleipnir's nonlinear problem tests ported to Google Test.
2025-11-10 13:53:15 -08:00
Tyler Veness
694a79579e [benchmark] Split benchmarks into separate files (#8351)
Also add Sleipnir cart-pole benchmark from #8323.
2025-11-10 11:36:21 -07:00
Tyler Veness
37d81d490b [build] Sort Doxygen suppressions (#8353) 2025-11-10 10:11:17 -07:00
Austin Schuh
00ff8b941d [bazel] Publish almost all artifacts (#8141)
This uses all the infrastructure we put together earlier to actually build and publish all the artifacts.

We might still want to adjust what is built by default to control CI times.

Signed-off-by: Austin Schuh <austin.linux@gmail.com>
Co-authored-by: PJ Reiniger <pj.reiniger@gmail.com>
Co-authored-by: David Vo <auscompgeek@users.noreply.github.com>
2025-11-10 10:10:49 -07:00
Austin Schuh
0167409858 [bazel] Upgrade build_bazel_apple_support (#8352)
This is finally a released version with some of my patches in it.

Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-11-10 10:08:57 -07:00
Austin Schuh
4529ef0ea6 [bazel] Use script based python bootstrapping (#8180)
This fixes issues found building AOS with import paths.
2025-11-10 10:03:11 -07:00
Austin Schuh
c2e0f381ce [bazel] Add integrity to pybind11 (#8354)
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-11-10 07:57:58 -08:00
Tyler Veness
603a59fbfe [wpimath] Add typedefs for LQR and Kalman filters (#8340)
These are industry-standard initialisms. The original class names were
left as is so they're more googleable, but I could be convinced
otherwise.
2025-11-09 10:34:04 -08:00
PJ Reiniger
892666fbbe [robotpy] Add build scripts for wpilib and dependencies (#8348)
This gets the majority of projects from mostrobotpy building in this mirror. Projects missing still are cscore and the halsim wrappers.
2025-11-09 10:32:58 -08:00
Charlotte
5636b8cd77 [wpilib] Remove deprecated MotorControllerGroup (#8349) 2025-11-09 10:31:26 -08:00
Peter Johnson
4ea584b64f [wpilibc] Move framework sources to framework directory (#8347) 2025-11-08 22:52:01 -08:00
Austin Schuh
04fb95a897 [bazel] Use the new gitlib-bazel.wpi.edu cache server (#8342)
This is owned by WPI, so we can make it as big or small as we want.
This lets us check in more of the bazel build.

Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-11-08 16:59:26 -08:00
Peter Johnson
5c9c45fadb [cscore, wpilibcExamples] Use double-quote includes for wpi/ (#8346)
Use ERR and WARN in cscore to avoid conflict with Windows headers.
2025-11-08 16:58:51 -08:00
Peter Johnson
fc4e922206 Use wpilib.robot instead of frc.robot (#8345) 2025-11-08 16:22:34 -08:00
Joseph Eng
ca206c5633 [build] Clean up spotbugs excludes (#8334) 2025-11-08 16:21:58 -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
Tyler Veness
aeedfa588c [build] Fix clang-tidy warnings (#8343) 2025-11-08 14:07:00 -08:00
Peter Johnson
161f8d107b Merge branch 'main' into 2027 2025-11-08 00:03:50 -08:00
PJ Reiniger
2109161534 SCRIPT: wpiformat 2025-11-07 23:09:21 -08:00
PJ Reiniger
ae6bdc9d25 SCRIPT: Spotless Apply 2025-11-07 23:09:21 -08:00
PJ Reiniger
09d46229c7 HAND FIX: Fixup robotpy yaml files 2025-11-07 23:09:21 -08:00
PJ Reiniger
844c7c38dd HAND FIXES: Fix ntcoreffi 2025-11-07 23:09:21 -08:00
PJ Reiniger
106bc774d4 HAND FIX: final java package changes 2025-11-07 23:09:21 -08:00
PJ Reiniger
67f2502b08 HAND FIX final frc:: replacements 2025-11-07 23:09:21 -08:00
PJ Reiniger
928ff20695 SCRIPT: FRC_ replacements 2025-11-07 23:09:21 -08:00
PJ Reiniger
824f36f63a SCRIPT: 'edu.wpi.first' replacements 2025-11-07 23:09:21 -08:00
PJ Reiniger
013a238994 HAND FIXES: Update maven info 2025-11-07 23:09:21 -08:00
PJ Reiniger
3f740894c9 HAND FIXES: Manual cleanup of namespaces 2025-11-07 23:09:21 -08:00
PJ Reiniger
ad138270a8 HAND FIXES: Update build scripts for namespaces 2025-11-07 23:09:21 -08:00
PJ Reiniger
07b60384d0 SCRIPT run upstream utils 2025-11-07 23:09:21 -08:00
PJ Reiniger
9aca8e0fd6 SCRIPT namespace replacements 2025-11-07 23:09:21 -08:00
PJ Reiniger
ae6c043632 HAND FIXES: Update upstream for namespace changes 2025-11-07 23:09:21 -08:00
PJ Reiniger
cf711a125e HAND FIX: Fix robotpy yaml files 2025-11-07 23:09:21 -08:00
PJ Reiniger
d3da30d53a HAND FIXES: Fixup remaining rename issues 2025-11-07 23:09:21 -08:00
PJ Reiniger
bf9da2cdea SCRIPT run upstream utils 2025-11-07 23:09:21 -08:00
PJ Reiniger
198771dde4 HAND FIXES: Fix upstream util scripts 2025-11-07 23:09:21 -08:00
PJ Reiniger
1e7604f81c SCRIPT: wpiformat 2025-11-07 23:09:21 -08:00
PJ Reiniger
c48b722dac SCRIPT: Spotless Apply 2025-11-07 23:09:21 -08:00
PJ Reiniger
c89910b7c6 HAND FIXES: Fixup gradle / cmake / styleguide 2025-11-07 23:09:21 -08:00
PJ Reiniger
105deaddb0 HAND FIXES: Fixup java and python compilation 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
7c6efa41ae SCRIPT Run cc include replacements 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
12823a003d SCRIPT Generic Renames 2025-11-07 23:09:21 -08:00
PJ Reiniger
c350c5f112 SCRIPT Move java files 2025-11-07 23:09:21 -08:00
PJ Reiniger
7ca1be9bae SCRIPT Move cc files 2025-11-07 23:09:21 -08:00
PJ Reiniger
10b4a0c971 SCRIPT fixup project rename 2025-11-07 23:09:21 -08:00
PJ Reiniger
a5492d30da SCRIPT Move subprojects 2025-11-07 23:09:21 -08:00
Joseph Eng
b8d6bc2eb1 [wpimath] Scale transforms instead of twists in PoseEstimator (#8333)
The spiraling issue occurs when the vision rotation standard deviation is very high relative to the odometry rotation standard deviation and the vision measurements have a large rotation error. (Scaling the rotation component of a twist without scaling the translation component causes the direction of overall translation to change, leading to spiraling around (either towards or away) the vision measurement instead of moving towards it.) Using a transform instead of a twist avoids this issue.

In general, scaling twist components is more mathematically correct than scaling transform components. However, although twists are correct for modeling uncertainty in an odometry-only pose estimate, they are not correct for the difference between the odometry-only pose estimate and a vision measurement. Since neither twists nor transforms are completely correct (and the pose estimator as a whole is not mathematically correct), but using transforms can guarantee that the pose estimate approaches the vision measurement (instead of potentially spiraling away), they are the least bad option.
2025-11-07 18:07:43 -08:00
Peter Johnson
688535298b [cscore] Add braces to match styleguide (NFC) (#8339) 2025-11-07 18:07:05 -08:00
Thad House
02252b58d7 [build] Update to 2026 Beta 1 (#8337) 2025-11-07 18:06:39 -08:00
PJ Reiniger
8cfc158790 [wpilibc] Remove declaration of removed function (#8336) 2025-11-07 10:09:26 -08:00
Joseph Eng
e207ca4880 [build] Clean up spotbugs excludes (#8332) 2025-11-07 10:07:56 -08:00
Tyler Veness
3bdaeac3e1 [build] Upgrade to Doxygen 1.15.0 (#8328) 2025-11-02 05:18:58 -08:00
Peter Johnson
5eb3140f69 [wpinet] Remove old resources (#8329)
These are out of date, and nothing uses them in allwpilib; wpilibpi used
them but a more major upgrade is needed there.

While we may in the future add integrated support for e.g. an integrated
NT viewer, it's unlikely we would use these versions.
2025-11-01 21:09:38 -07: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
Tyler Veness
bc44ced506 [upstream_utils] Upgrade to fmt 12.1.0 (#8312) 2025-11-01 16:19:37 -07:00
Tyler Veness
f4db88da9a [build] Document how to mirror new Doxygen versions (#8327) 2025-11-01 14:45:53 -07:00
Thad House
cb720048b8 [wpilib] Remove Jaguar (and other) motor controllers (#8299) 2025-11-01 14:45:19 -07:00
Peter Johnson
577dd48af7 [build] Fix bazel examples lists after merge (#8326) 2025-11-01 13:58:28 -07:00
PJ Reiniger
49e84c6b52 [robotpy] Sync robotpy (#8318)
Project import generated by Copybara.

GitOrigin-RevId: f6818c55dda55da1226e47a05a22d30f7cc477f1
2025-11-01 10:28:05 -07:00
Peter Johnson
3f88c287d6 [examples] Fix ProfiledPIDFeedForward after merge 2025-11-01 10:01:42 -07:00
Peter Johnson
cc043df07f Merge branch 'main' into 2027 2025-11-01 09:39:08 -07:00
Thad House
def7849909 [wpilib] Integrate support for ExpansionHub over USB (#8292) 2025-11-01 09:24:58 -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
Jade
e45aadc851 [sysid] Remove Phoenix5 CANcoder preset (#8316)
Signed-off-by: Jade Turner <spacey-sooty@proton.me>
2025-11-01 09:19:52 -07:00
Dalton Smith
fea6883d98 [wpimath] DCMotor: Add X44 and Minion (#8319) 2025-11-01 09:19:36 -07:00
Tyler Veness
b7fe5ef833 [build] Fix up grammar in docs/build.gradle (#8317) 2025-11-01 09:18:50 -07:00
Tyler Veness
cd237e57d4 [ci] Upgrade to macOS 15 runner image (#8321)
This fixes a compiler bug (rejecting out-of-line definitions of constrained members) newer versions of Sleipnir were encountering.
2025-11-01 09:17:09 -07:00
Murat65536
8b99ad82c3 [wpilib] Add a few unit overloads (#8231)
Co-authored-by: Sam Carlberg <sam@slfc.dev>
Co-authored-by: Joseph Eng <91924258+KangarooKoala@users.noreply.github.com>
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2025-10-28 20:18:55 -07:00
Thad House
58ba536351 [wpilib] Remove Jaguar (and other) motor controllers (#8298)
https://community.firstinspires.org/2025-robot-rules-preview-for-2026
2025-10-28 20:18:02 -07:00
Tyler Veness
4aef52a117 [ci] Upgrade to wpiformat 2025.36 (#8308)
clang-format 21 made some formatting changes. Since wpiformat's stdlib
task was removed, I removed NOLINT comments for it and removed some
std:: prefixes it added to comments.
2025-10-28 20:17:04 -07:00
Jason Daming
a6a4912a80 [snippets] Add ProfiledPIDController with feedforward snippets (#8280)
Adds snippets demonstrating ProfiledPIDController usage with
SimpleMotorFeedforward using the two-parameter calculate() method
(currentVelocity, nextVelocity).

These snippets will be used in frc-docs to document the recommended
feedforward pattern with ProfiledPIDController.

Co-authored-by: sciencewhiz <sciencewhiz@users.noreply.github.com>
2025-10-27 20:49:16 -06:00
Thad House
bd2cecbb1a [cmd3] Correct the groupId for commands v3 in the JSON (#8306) 2025-10-26 00:08:42 -07:00
Thad House
2e10f91e07 [hal,wpilib] Use new DS available API from mrccomm (#8302)
Instead of just having a max count for joystick values, there's an available mask of values. This is because in the future we're expecting there to be holes in the list of available buttons and axes. This updates everything to support that scenario.

Also, Joystick buttons, axes, and POVs all now start at 0 instead of 1.
2025-10-25 23:03:50 -07:00
Thad House
429698f508 [build] Fix deprecated gradle warning in catch2 publish.gradle (#8305) 2025-10-25 23:02:09 -07:00
Austin Schuh
51fbde777b [bazel] Package headers in ntcoreffi correctly (#8170)
* [bazel] Package headers in ntcoreffi correctly

The original package includes headers from ntcore and wpiutil, so
include those too.

* Merge in new 2027
2025-10-25 21:17:43 -07:00
Ryan Blue
873e960e93 [ci] Update tools workflow for 2026 (#8301) 2025-10-25 17:23:12 -07:00
Gold856
4f133c6aa1 [build][ci] Update vcpkg baseline (#8300) 2025-10-25 10:28:39 -07:00
Peter Johnson
b9bd3e5754 Merge branch 'main' into 2027 2025-10-23 22:33:14 -07:00
Edan Thomton
35dd61cde5 [build] Fix Eclipse annotation generation in wpilibjExamples (#8295) 2025-10-23 22:29:32 -07:00
PJ Reiniger
44b9cc1398 [robotpy] Mirror most other subprojects (#8208)
GitOrigin-RevId: ac60fd3cf4a24023184376687da28373d14b781a

This mirrors the robotpy files for the following projects:
- apriltag
- datalog
- hal
- ntcore
- romiVendordep
- wpilibc
- wpimath
- xrpVendordep

This excludes cscore and the halsim wrappers for at this time.

NOTE: This does not hook these projects up to the build system, just simply mirrors the files. The building will take place in a follow up PR to make it easier to review the changes necessary to build.
2025-10-23 22:28:04 -07:00
Jade
8992dcdc99 [wpilib] Remove Driverstation.waitForDsConnection (#8288)
Signed-off-by: Jade Turner <spacey-sooty@proton.me>
2025-10-22 18:43:29 -07:00
Peter Johnson
7a2a982e66 Merge branch 'main' into 2027 2025-10-11 23:54:41 -07:00
Michael Lesirge
9e85f3cf55 [wpimath] Rename 1D copySignPow to match 2D copyDirectionPow (#8286) 2025-10-11 09:24:10 -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
Michael Lesirge
2b43541b94 [wpimath] MathUtil: Add 2D variants of applyDeadband and copySignPow (#8057) 2025-10-10 13:44:12 -07:00
Ryan Blue
33f91589b4 [wpilib, examples] Remove AnalogGyro (#8205) 2025-10-10 12:44:39 -07:00
arbessette
4c4996e638 [docs] Remove Private Message language (#8202)
Removing private written message for safety of all users and contributors.
2025-10-10 12:43:02 -07:00
Sam Carlberg
cfbd7a5af2 [build] Fix doxygen builds on apple CPUs (#8282)
Caused by the doxygen gradle plugin attempting to download 1.10.0 (presumably its default version) from artifactory because the 1.12.0 config is only applied on x86_64 platforms. Just fixing that isn't enough, however; on mac, the plugin would fail to extract the dmg. We need to fall back to a global installation on the PATH for the plugin to find, preferentially using that instead of a failed attempt to download and extract the dmg.
2025-10-10 12:42:02 -07:00
Tyler Veness
f5990e8b40 [upstream_utils] Fix Eigen tag (#8283)
Upstream no longer seems to have the commit we were pointing to. We'll
just use the tag since that hasn't changed since the official release
announcement.
2025-10-09 21:50:55 -07:00
sciencewhiz
b56b843c8a Update frcYear in vendordeps (#8276) 2025-10-07 22:00:04 -07:00
Sam Carlberg
35e4a18e86 [cmd, build] Fix wpiannotation dependencies on commandsv2 (#8279) 2025-10-07 21:50:38 -07:00
Peter Johnson
7ff312bb69 Merge branch 'main' into 2027 2025-10-06 19:43:02 -07:00
sciencewhiz
2fb5271cc9 [build] Update native-utils to 2026 (#8277) 2025-10-05 14:22:53 -07:00
Gold856
b1aaabc1c6 [hal] Remove FPGA functions that won't exist on SC (#8273) 2025-10-04 15:58:12 -07:00
Peter Lilley
f1b9be551b [wpiutil] Add reverse/bidirectional iterators to wpi::circular_buffer (#8275)
Use std::reverse_iterator<> to create reverse iterators, make other
iterators bidirectional to allow for this. Added unit tests.
2025-10-03 23:13:55 -07:00
Sam Carlberg
3972b01c51 Add javac plugin for detecting common error cases at compile time (#8196)
Adds a `@NoDiscard` annotation that can be placed on methods to guarantee their return values are used and on types to guarantee that any method returning that type uses the return value.

Methods that call `@NoDiscard`-annotated functions can add a `@SuppressWarnings("NoDiscard")` or `@SuppressWarnings("all")` annotation (or annotation on the class declaring that method) to silence the compiler error warnings.
2025-10-03 17:42:47 -07:00
Austin Schuh
5c719ced5f [bazel] Put eigen in an external repo like bzlmod (#8169)
This sets us up to use AOS, which wants @eigen to resolve, without
introducing a second version or copy of eigen.
2025-10-03 12:32:40 -07:00
Thad House
7d34f43e44 [wpilib] Replace internal usages of Analog getAverageVoltage (#8271) 2025-10-02 22:40:45 -07:00
Thad House
e369c721ca [wpilib] Remove Servo Classes (#8270)
SystemCore doesn't directly support Servos. It would be possible to still use a Servo Power Module, but those are fairly rare, and we should probably use a different class for that case, so users don't attempt to hook a servo directly up to systemcore. That will depend on what happens with the rules in 2027.

Rev Servo Hubs are a current working replacement for systemcore users.
2025-10-02 22:39:55 -07:00
Joseph Eng
871769c815 [wpimath] Fix units overload resolution (#8267) 2025-10-02 17:36:30 -07:00
Peter Johnson
ca7718cb08 [glass] FMS: Fix reading past end of GSM buffer (#8268) 2025-10-02 17:35:50 -07:00
Joseph Eng
5e7e5306df [wpiutil] Update StructSerializable contract (NFC) (#7441)
Matches ProtobufSerializable.  This is necessary for generic types.
2025-09-30 14:57:42 -06:00
Gold856
6447011bc3 [ci] Consolidate docs jobs (#7910)
We build docs in three different places, which is annoying to deal with, and it means we build docs two more times than necessary. Now, docs are built just once in the main Gradle workflow, with warnings promoted to errors, eliminating the need for the separate job in lint-format.yml. The uploaded docs artifact is then unpacked and commited to the GitHub Pages repo like normal.
2025-09-29 18:02:42 -07:00
Tyler Veness
bb5ee73e46 [build] Build JNI and benchmarks as release by default (#8257)
It doesn't make sense to benchmark debug binaries. Also, wpimath JNI
performance in unit tests is drastically impacted by debug vs release.
2025-09-29 17:47:17 -07:00
PJ Reiniger
c46b54a523 [wpilibj] Use non-global NetworkTableInstance in alert test (#8265) 2025-09-29 17:45:37 -07:00
PJ Reiniger
7290766482 [epilogue-processor] Fix naive tests in prep for huge refactor (#8255) 2025-09-29 11:47:51 -07:00
Tyler Veness
bd5141e254 [upstream_utils] Upgrade to fmt 12.0.0 (#8263) 2025-09-29 11:45:15 -07:00
Jonah Bonner
e364087e99 [glass] Fix color order for sim GUI LEDs (#8264) 2025-09-29 11:44:27 -07:00
Gold856
0277759d44 [wpiunits] Remove redundant if statement and inaccurate comment (#8262) 2025-09-28 16:00:35 -07:00
Gold856
7aabc19977 [bazel] Update Bazel to 8.4.1 to fix Windows builds (#8258)
- Fix missing epilogue deps
- Compress debug info to save space in CI
2025-09-27 22:50:21 -07:00
Gold856
f9899eb73f [wpimath] Fix odd header path in BangBangController (#8261) 2025-09-27 22:48:00 -07:00
Peter Johnson
ef676aca70 Merge branch 'main' into 2027 2025-09-25 22:17:00 -07:00
Tyler Veness
6b8be313c7 [build] Fix Java 25 builds (#8245)
I'm able to use a local install of Gradle 9.1 that has Java 25 support,
but some plugin upgrades are needed as well.
2025-09-25 21:28:37 -07:00
Tyler Veness
ab53d51c6f Fix or suppress clang-tidy warnings (#8254) 2025-09-25 21:28:04 -07:00
Tyler Veness
5003939b64 [upstream_utils] Recopy Eigen source (#8251)
Upstream slid the tag (again).  Change to the SHA commit ID until things stabilize.
2025-09-24 09:03:16 -06:00
Tyler Veness
ab259c2e89 [build] Fix Gradle 9 archives deprecation warning (#8247)
The deprecation message was:
```
The `archives` configuration added by the `base` plugin has been
deprecated and will be removed in Gradle 10.0.0. Adding artifacts to the
`archives` configuration will now result in a deprecation warning. If
you want the artifact built when running the `assemble` task, you should
add the artifact (or the task that produces it) as a dependency of the
`assemble` task directly.

val specialJar = tasks.register<Jar>("specialJar") {
    archiveBaseName.set("special")
    from("build/special")
}
tasks.named("assemble") {
    dependsOn(specialJar)
}
```
2025-09-22 11:58:14 -06:00
Tyler Veness
8fb5a1985a [upstream_utils] Recopy Eigen source (#8249)
Upstream slid the tag.
2025-09-21 21:58:43 -07:00
Sam Carlberg
cf4f6ce4b6 Update maven_install.json to match maven artifacts list in WORKSPACE (#8248)
Use `REPIN=1 bazel run @maven//:pin` to regenerate. `REPIN=1` is necessary for the conflicting gson versions to be resolved.
2025-09-21 20:44:43 -04:00
sciencewhiz
1e50471d2c [build] Update gradle-jni to 1.2.0 for Gradle 9 support (#8246) 2025-09-21 08:14:37 -07:00
sciencewhiz
c575a23e8e [build] Fix wpical and sysid icons on macOS (#8243)
Fixes #8239
2025-09-20 20:30:44 -07:00
sciencewhiz
4522cca70f [build] Update to develocity plugin (#8242)
Gradle enterprise plugin has been replaced by develocity.
2025-09-20 20:30:05 -07:00
sciencewhiz
850a148aad [build] Fix gradle 9 deprecations in msvc runtime (#8244) 2025-09-20 17:59:29 -07:00
Tyler Veness
0a4e44ea06 [wpimath] Synchronize C++ and Java RK4 docs (NFC) (#8238) 2025-09-20 15:49:41 -07:00
Tyler Veness
a7e7f6912a [upstream_utils] Upgrade to Eigen 5.0.0 (#8240) 2025-09-20 15:49:23 -07:00
Caitlin Cai
76ee08e0b4 [readme] Add instructions for installing SystemCore toolchain (#8182) 2025-09-20 11:24:05 -07:00
Sam Carlberg
ee0a8a1e56 [epilogue] Support logging of protobuf-serializable types (#8229)
For parity with struct-serializable types.

Change struct serialization to only apply to types with a public static final <type> struct field, instead of relying only on the marker interface (which is not always followed). Doing this allows fallthrough to the protobuf handler for types with dynamic structs but static protobuf serializers.
2025-09-20 11:23:22 -07:00
Tyler Veness
f701132392 [wpimath] Refactor MathUtil.interpolate() and MathUtil.inverseInterpolate() to handle extrapolation (#8232) 2025-09-20 11:22:05 -07:00
Tyler Veness
3dbdfa1839 [upstream_utils] Upgrade Sleipnir (#8235) 2025-09-20 11:21:06 -07:00
Peter Johnson
1ce2854a1e Merge branch 'main' into 2027 2025-09-20 11:19:40 -07:00
Tyler Veness
ee3d55e848 [upstream_utils] Upgrade Eigen to latest (#8228) 2025-09-19 17:52:48 -06:00
Gold856
d59f1732bb [glass] Fix handling for optionals and empty arrays (#8227) 2025-09-14 07:46:51 -07:00
Peter Johnson
d5d67d874b [glass] NetworkTables: Show struct enum values (#8224)
Also change the format for both proto and struct enums to show other values as <N>, and not put quotes around the value.
2025-09-12 13:01:50 -07:00
Peter Johnson
8c20da44c8 [hal] Remove old netcomm types (#8225) 2025-09-12 07:29:05 -07:00
Peter Johnson
855ef10d58 [wpiutil] DynamicStruct: Make GetEnumValues() const (#8223)
Also remove unnecessary include.
2025-09-12 07:27:43 -07:00
Peter Johnson
90d90f334d [wpiutil] Add alloc_wpi_string() and copy_wpi_string() (#8222)
These are useful to allocate a WPI_String, rather than referencing existing data.
2025-09-12 07:27:09 -07:00
Sam Carlberg
909f8a1dc4 [build] Remove PMD.RedundantFieldInitializer rule (#8184)
Code readability is much more important than saving three bytes per redundantly-initialized field.
2025-09-08 21:19:00 -07:00
Tyler Veness
be72d543ad [wpilib] Remove robotInit() (#8199)
Fixes #6622.
2025-09-08 21:17:37 -07:00
Peter Johnson
f8ed2a4d92 [wpiutil] Synchronization: fix shutdown use-after-free (#8213)
Also in ntcore, join the notifier thread on shutdown.
This prevents tsan from reporting it as a leaked thread.
2025-09-08 21:15:00 -07:00
Tyler Veness
dbffe6e8ac [wpimath] Add readme (#8209) 2025-09-08 17:26:22 -07:00
Gold856
5cd97c6353 [upstream_utils] Add Catch2 (#8203) 2025-09-08 15:14:23 -06:00
Peter Johnson
e8490eb242 [ntcore] Disable assertions unit test (ValueDeathTest) (#8221)
This likes to hang on Windows.
2025-09-08 14:58:09 -06:00
Peter Johnson
e5b7613b78 [ntcore] Change ntcore_test to just exit on tsan error (#8220)
In shutdown situations, calling FAIL() can deadlock in tsan.
2025-09-08 14:57:32 -06:00
Ryan Blue
2639e0365b [ci] Update sentinel build with Windows FFI changes (#8218) 2025-09-07 21:33:19 -07:00
Ryan Blue
08f11488b0 [ci] Add 2027 development repo to cleanup task (#8217) 2025-09-07 06:16:26 -07:00
Tyler Veness
632749e6f3 [build] Upgrade Maven dependencies (#8173) 2025-09-01 08:13:46 -07:00
Jade
b0829356fa [wpimath] Fix sysid links (NFC) (#8204)
Signed-off-by: Jade Turner <spacey-sooty@proton.me>
2025-09-01 08:11:39 -07:00
Ryan Blue
ed904851eb [ci] Fix CMake Android build caching (#8206)
sccache was enabled but didn't have write credentials
2025-08-31 21:55:13 -07:00
Wispy
2cfd58f119 [commands] Add Subsystem.idle() (#7815) 2025-08-30 22:54:53 -07:00
Sam Carlberg
129cbbe11d [epilogue] Optimize time and memory usage of epilogue backends (#8190) 2025-08-30 20:15:22 -07:00
Ryan Shavell
45db0fd45e [epilogue] Use reflection to access non-public superclass fields (#7996)
Co-authored-by: Sam Carlberg <sam@slfc.dev>
2025-08-30 20:14:41 -07:00
PJ Reiniger
bd1dcc4358 [bazel][robotpy] Add mirror for robotpy's wpiuil and wpinet libraries (#8062)
Project import generated by Copybara.

GitOrigin-RevId: 92ea93d1b47a82667044bd0af05f7fdb34d2c2c2
2025-08-30 11:55:11 -07:00
ninjadrknss
96004f9bb5 [wpimath] Replace Pose2/3d.exp(Twist2/3d) with Pose2/3d.plus(Twist2/3d.exp()) (#8188)
This better matches math notation.
2025-08-30 11:37:09 -07:00
Kevin-OConnor
9fd4ccf95b [hal] Add CAN Mfgrs and Adjust Device Types (#8201) 2025-08-30 11:36:26 -07:00
sciencewhiz
4e6b9706ff [build] Explicitly set Documentation archiveVersion (#8192)
In the recent gradle or gradle dependencies update, the documentation
zips were being published as documentation-version-unspecified, where
the unspecified was coming from archiveVersion. It looks like we use a
different method of setting the version, so make sure that
archiveVersion is empty
2025-08-26 08:09:18 -06:00
Ryan Blue
55e52bc2b7 ThirdPartyNotices: Update location of Simd library (NFC) (#8193) 2025-08-25 16:38:37 -06:00
ninjadrknss
c280fce147 [wpimath] Replace MathUtil.clamp() with Java 21 Math.clamp() (#8186) 2025-08-23 09:01:51 -07:00
Gold856
183328384b [upstream_utils] Remove extra protobuf patch (#8181)
Missed in the rebase for #7988
2025-08-17 18:41:51 -07:00
Gold856
d4311d5a29 [wpiutil,glass,dlt] Replace libprotobuf with upb for dynamic decode (#7988)
libprotobuf is a very annoying dependency to deal with, and with the switch to nanopb for generated C++ code, libprotobuf is only used for dynamic decode in the GUI apps. libprotobuf has been swapped out with upb, a much smaller C-based library that supports reflection and can therefore do dynamic decode. This means we can remove the libprotobuf dependency and stop dealing with build issues because of it.
2025-08-16 22:56:32 -07:00
Ryan Blue
7f35104012 [hal] AddressableLED: Restore alternative color order support (#8130)
Unlike armv7, aarch64 doesn't have alignment assertions for SIMD instructions. The compiler output between the aligned and unaligned variants is the same.
2025-08-16 22:53:04 -07:00
Thad House
73c26dcf89 [hal] Enable CAN FD on bus when bus is configured for FD (#8175)
Without this, FD reads would not be supported, however FD writes would still work.
2025-08-16 22:51:45 -07:00
Tyler Veness
0d9e850e22 [wpimath] Fix dt type in C++ tests (#8179)
The UKF test was calling `.value()` on an implicit
`units::millisecond_t` type assuming it was `units::second_t`.

I normalized the rest of the dt declarations while I was at it.
2025-08-16 22:51:13 -07:00
sciencewhiz
46a3318324 [build] Fix processstarter publishing (#8171)
Artifacts weren't in OS and architecture subfolders in the zip like all the other
C++ tools
2025-08-11 20:52:10 -07:00
Daniel Chen
f209ecb0cb [wpimath] Add structs for TrapezoidProfile.State and ExponentialProfile.State (#8163) 2025-08-10 11:45:36 -07:00
Peter Johnson
f89cf2e441 Merge branch 'main' into 2027 2025-08-09 00:55:56 -07:00
Peter Johnson
3e4e9c9b01 Merge branch 'main' into 2027 2025-08-09 00:55:26 -07:00
Iris
78fa67099e [build] Small fixes to build on GCC 15 (#8148)
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2025-08-09 00:07:41 -07:00
Tyler Veness
9ac7e286f5 [build] Upgrade Gradle plugins (#8166)
I upgraded all plugins I could see except org.ysb33r.doxygen. 2.0 made
breaking changes, and I couldn't figure out how to migrate.

Most of the changes are for suppressing new linter purification rites.
2025-08-08 23:04:02 -07:00
Tyler Veness
5fd9e1e72a [build] Fix Gradle Task.project deprecation warning (#8167)
```
> Task :wpilibcExamples:checkCommands
Script '/home/tav/frc/wpilib/allwpilib/shared/examplecheck.gradle': line 135
Invocation of Task.project at execution time has been deprecated. This will fail with an error in Gradle 10.0. This API is incompatible with the configuration cache, which will become the only mode supported by Gradle in a future release. Consult the upgrading guide for further information: https://docs.gradle.org/8.14.3/userguide/upgrading_version_7.html#task_project
        at examplecheck_4wsg1s37eigy9vs5arzst20ga$_run_closure5$_closure16$_closure17.doCall$original(/home/tav/frc/wpilib/allwpilib/shared/examplecheck.gradle:135)
        (Run with --stacktrace to get the full stack trace of this deprecation warning.)
```

Moving the project access outside the doLast block makes it occur at
confguration time instead.
2025-08-08 22:48:11 -07:00
DeltaDizzy
94399dd7e0 [datalog] Overload DataLogReaderThread::GetEntry to accept an entry id (#8152)
It is useful when programmatically interacting with DataLogs to be able to retrieve an record's associated metadata (entry name, type, and metadata string), but the only reference to an entry that a record contains is the id. DataLogReaderThread already builds a map of id->DataLogReaderEntry, but it was unexposed until now.
2025-08-08 09:09:54 -06:00
Tyler Veness
0a0adebd89 [build] Upgrade to Gradle 8.14.3 (#8164)
This fixes local builds with JDK 24.

I fixed deprecation warnings from `./gradlew wrapper --warning-mode all`
as well.
2025-08-08 09:08:34 -06:00
Austin Schuh
6eba91bc04 [bazel] Build and test wpical with bazel (#8155)
This pulls down the prebuilt ceres libraries and uses them with Bazel to
build and test wpical.

Do note that bazel looks up artifacts used for testing differently than
the other build systems.  It wants you to use its runfiles API to find
the dependencies reliably.  Add a function to look up the paths for
files, and use runfiles only when building with Bazel to maintain
compatibility with other languages.

Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-08-06 22:56:42 -06:00
Austin Schuh
c01f0c3d46 [bazel] Use rules_jvm_external for opencv (#8158)
This makes it so rules_jvm_external also doesn't package up all the
opencv class files into the final published packages.  And is simpler to
maintain.

Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-08-06 22:16:44 -06:00
Austin Schuh
d203541b7b [bazel] Build wpilibj docs too (#8159)
We've got javadocs for each module, but wpilib has 1 for everything.
Build that too using rules_jvm_external.

Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-08-05 20:54:59 -06:00
Austin Schuh
13852760f6 [bazel] Build wpilibc docs with doxygen (#8157)
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-08-04 23:49:47 -06:00
Austin Schuh
dffa2542c9 [build] Fix wpiformat errors in 2027 (#8156)
Must have gotten introduced in a merge, let's fix them.
2025-08-03 21:36:05 -06:00
Peter Johnson
ed7982563b Merge branch 'main' into 2027 2025-08-03 11:51:25 -07:00
Gold856
2d11946d98 [wpical] Use updated thirdparty-ceres and move resource files (#8151) 2025-08-03 11:41:25 -07:00
Gold856
c42fde5d07 [ci] Make upstream_utils check error with a more clear message (#8153)
Now it links to the README in upstream_utils.
2025-08-03 11:37:40 -07:00
Austin Schuh
23f5725853 [bazel] Reduce number of windows builds in CI (#8145)
Windows is proving to be a *lot* slower than everything else.  I supect
this is because we are building both arm64 and x86 every time, which
ends up being twice the work.  Leave those builds in place, but skip
doing them in CI.  This should be a 2x speedup when building Windows
code.

Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-08-02 23:09:29 -07:00
James Kuszmaul
3b7d0e7bf5 [readme] Mention X11-dev dependency in developer README (#8150)
Tested a bazel build of //... on a (relatively) clean Debian system.

It feels like there is a more pricnipled list we could provide (e.g.,
libglfw3-dev), although I think most of those would also end up
installing more than necessarily required.
2025-08-02 23:08:58 -07:00
Austin Schuh
0dd77e55cb [bazel] Build and publish ntcoreffi too (#8147) 2025-08-02 21:59:50 -07:00
Austin Schuh
1ab705b354 [bazel] Publish ntcore + wpimath for real (#8144)
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-08-01 22:12:38 -07:00
Austin Schuh
dbf22c98b4 [bazel] Build processstarter with bazel too (#8143) 2025-08-01 22:12:16 -07:00
Austin Schuh
9c523f98f5 [bazel] Build and deploy binary tools (#8142)
This is a subset of the full publish review.
2025-08-01 17:20:43 -07:00
Austin Schuh
0089e518cb [bazel] Update configuration for which platforms to split debug symbols for (#8140)
I could have sworn that we were only splitting debug symbols on x86.
The most recent tests I have done suggest that is backwards.  This is
easy to reconfigure later if needed.

Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-08-01 13:00:13 -07:00
Austin Schuh
2f918900ff [bazel] Publish wpilib{c,j}examples (#8136)
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-08-01 12:59:52 -07:00
Austin Schuh
48077cdb91 [bazel] Add publishing rules for other package types (#8139)
This adds shortcuts for static only, shared only, and binary projects.
The end result is that it is pretty easy from here to publish all the
arifacts needed.
2025-08-01 12:59:25 -07:00
Austin Schuh
6e9ed8b7f1 [bazel] Rename imgui so it deploys correctly (#8137)
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-08-01 12:58:58 -07:00
Gold856
e0e774abde [commands, wpimath] Remove Mecanum/SwerveControllerCommand and HolonomicDriveController (#8119) 2025-07-31 23:05:42 -07:00
Austin Schuh
b251d16ef7 [bazel] Build simulation/halsim_ws_client shared+static libraries (#8138)
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-07-31 23:04:16 -07:00
Austin Schuh
76881e2940 [bazel] Rename liblibglass -> libglass (#8135)
The lib gets automatically added, don't add it by hand.
2025-07-31 23:03:19 -07:00
Austin Schuh
2245dccff6 [bazel] Link cscorestatic correctly (#8134)
Statically link opencv, and make it work on all the architectures.
2025-07-31 23:02:56 -07:00
Rain Heuer
b3aeee18c8 [wpimath] Add vector product and squared length operations to Translation2d/3d (#8133)
Adds methods to compute the dot and cross products between Translation2ds and Translation3ds, as well as methods to compute the square of Distance and Norm, which allows avoiding some calls to sqrt in many cases.

Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2025-07-31 21:05:39 -07:00
Tyler Veness
feee88f40d [wpimath] Remove redundant transposes on symmetric matrices (#8131)
This likely won't have a performance impact since it only affects matrix traversal order, but it does simplify the code.
2025-07-31 21:04:55 -07:00
Austin Schuh
12223ff188 [bazel] Implement cscore shared libraries (#8089)
Use all our fancy new linking code to link cscore properly. nm reports that the symbols look quite good.

Signed-off-by: Austin Schuh <austin.linux@gmail.com>
Co-authored-by: PJ Reiniger <pj.reiniger@gmail.com>
Co-authored-by: David Vo <auscompgeek@users.noreply.github.com>
2025-07-31 21:04:22 -07:00
Austin Schuh
79f6351073 [bazel] Link all third party apriltag symbols (#8132)
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-07-31 19:27:35 -07:00
Austin Schuh
ef95333a89 [bazel] Shorten the platform suffix for windows arm (#8129)
This needs to be short enough to fit in the windows path restriction.
The full name was too long for some targets.
2025-07-31 19:27:21 -07:00
Austin Schuh
343e748643 [bazel] Upgrade opencv and toolchains dependencies (#8128)
This sets us up to properly depend on opencv, by introducing the new
helpers, @rules_bzlmodrio_toolchains//cc:cc_shared_import.bzl to import
the shared libraries correctly from opencv.

Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-07-30 21:30:00 -07:00
Peter Johnson
0478176e47 [simgui] Add GUI context getter hooks (#8127)
This enables GUI libraries to be linked statically with shared context.
2025-07-30 21:29:24 -07:00
Austin Schuh
db95f55394 [bazel] Handle debug symbols and debug builds like gradle (#8118)
This follows the gradle build accurately.  Gradle copies debug symbols
into a second file (libfoo.so.debug) and links it back into the .so
file.  Disable this behavior when gradle doesn't do it today.

Also, name everything correctly.  When building debug builds, most
libraries get a 'd' at the end of them.  Do that here too.
2025-07-30 20:07:06 -07:00
Tyler Veness
e678a338b4 [ci] Upgrade wpiformat (#8124)
See https://github.com/wpilibsuite/styleguide/pull/312
2025-07-30 11:10:12 -06:00
Austin Schuh
3871cab6e8 [bazel] Use WPILIB_VERSION automatically for version template generation (#8117) 2025-07-26 15:10:15 -07:00
Gold856
22ed224035 [build] Clean up DataLog CMake build (#8116) 2025-07-26 14:48:58 -07:00
Sam Carlberg
8d36df671b [wpiunits] Make Java units immutable only (#8115)
Remove mutable implementations, as systemcore doesn't need mutability to keep performance under control.
2025-07-26 14:48:35 -07:00
Austin Schuh
373eedc77b [bazel] Generate a filtered .def file for windows for wpimath (#8113)
wpimath otherwise quickly gets too many symbols.  Instead, gradle
exports only some of the symbols from protobuf files automatically, and
then manually exports the math operations.  Do that here too.

Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-07-26 14:47:12 -07:00
Jade
e93c8cdb29 [build] Upgrade to Java 21 (#7547)
Signed-off-by: Jade Turner <spacey-sooty@proton.me>
Co-authored-by: sciencewhiz <sciencewhiz@users.noreply.github.com>
2025-07-25 15:45:40 -07:00
PJ Reiniger
c78bd942bb [bazel] Make publishers for c++ hdr / srcs, and java (#8114) 2025-07-24 09:11:09 -04:00
Austin Schuh
e2f901822c [bazel] Upgrade bazel to 8.3.1 and rules_cc to 0.1.4 (#8112) 2025-07-24 09:10:10 -04:00
Thad House
cd0e7fb7d7 [hal, wpilib] Fix LED key and byte order (#8110) 2025-07-22 17:45:10 -07:00
Austin Schuh
60098b0685 [bazel] Build a single maven artifact bundle (#8049)
Signed-off-by: Austin Schuh <austin.linux@gmail.com>
Co-authored-by: PJ Reiniger <pj.reiniger@gmail.com>
Co-authored-by: David Vo <auscompgeek@users.noreply.github.com>
2025-07-22 14:26:20 -06:00
Peter Johnson
f3af50fc8e [hal, wpilib] Update Addressable LED support (#8100) 2025-07-21 21:52:10 -07:00
Peter Johnson
8aa312fb6f Merge branch 'main' into 2027 2025-07-21 18:38:43 -07:00
Thad House
b66a66b693 [commands] Add systemcore to command vendor dep (#8108) 2025-07-21 18:38:14 -07:00
sciencewhiz
09680072ac [examples] Add Snippets for Accelerometers using OnboardIMU (#8087) 2025-07-20 22:19:14 -07:00
Tyler Veness
946ab9e98f [wpimath] Fix S3UKF tests (#8097)
They weren't actually instantiating S3UKF.
2025-07-20 22:18:31 -07:00
sciencewhiz
5905a3ba27 [hal] Clean up HAL ports (#8101)
Remove references to PWM/Digital/relay Headers.
Fix analog cnd digital hannels
Set SPI and relay channels to 0.
Fix typos and roboRIO references.
2025-07-20 22:17:19 -07:00
Austin Shalit
484cbabc06 [wpinet] Disable Uv FailedLookup test (#8105)
See https://github.com/wpilibsuite/allwpilib/discussions/8104. This test consistently fails when ISPs 'helpfully' resolve an invalid name.
2025-07-20 22:16:28 -07:00
sciencewhiz
b445d48033 [ci] Remove tools build (#8098) 2025-07-18 20:44:46 -07:00
Jonah Bonner
a6892b6cd5 [hal, wpilib] Add support for onboard IMU mount orientations with Euler angles (#8061) 2025-07-17 21:20:10 -07:00
Michael Lesirge
f308e9873a [wpimath] Add miles per hour conversation methods (#8026) 2025-07-17 21:19:32 -07:00
sciencewhiz
8799733838 [processstarter] Handle Elastic and AdvantageScope (#8068)
Since they are in different directories, they need to be special cased
This is needed to support wpilibsuite/WPILibInstaller-Avalonia#492,
since those are currently handled by special scripts.
2025-07-17 21:18:27 -07:00
Ryan Blue
fa65657746 [hal] Set publish options for SmartIO mode publisher (#8096) 2025-07-17 21:17:18 -07:00
PJ Reiniger
412d189507 [bazel] Set readonly api when building pull requests (#8094) 2025-07-16 20:45:14 -07:00
PJ Reiniger
b85a0d5cf3 [build] Add missing sources to published zip files (#8055)
Gradle publishing does not capture all of the source files that are used during a build. This should get most of them, and get it equivalent to what bazel pushes out.
2025-07-15 21:20:28 -07:00
sciencewhiz
2875fd7d7c [wpilib] Disambiguate HID Sendable names (#8081)
Fixes #7933
Add Axis to triggers sendable name
2025-07-15 21:19:03 -07:00
Thad House
24e2d2d676 [hal] Remove DS Data timeout (#8083) 2025-07-15 21:18:17 -07:00
Joseph Eng
1530fccbd0 [wpimath] Implement Scaled Spherical Simplex Filter (S3F) (#8091)
Adds S3SigmaPoints based on MerweScaledSigmaPoints. In addition, restructures UnscentedKalmanFilter to support different sigma point generators and provides MerweUKF and S3UKF for convenience when working with either kind of filter.

S3UKFTest is copied from MerweUKFTest (which is a rename of UnscentedKalmanFilterTest). Curiously, however, in Java the original tolerance used in MerweUKFTest.testDriveConvergence() for the final rotation was too low for S3UKFTest, so the tolerance is increased from 0.000005 (5e-6) radians to 0.00015 (1.5e-4) radians. However, the C++ version still uses the original tolerance. (This difference is probably because Java uses a final rotation of 5.846 degrees while C++ uses a final rotation of 5.846 radians)

Closes #8072.

Breaking changes:

- (C++) UnscentedKalmanFilter has a new template parameter for the sigma point generator type.
- (Java) UnscentedKalmanFilter has an additional parameter to every constructor providing an instance of a sigma point generator.
- (C++) int MerweScaledSigmaPoints.NumSigmas() has been replaced with constexpr int MerweScaledSigmaPoints::NumSigmas.
- (C++) The second parameter of SquareRootUnscentedTransform has been changed from States to NumSigmas.
2025-07-15 21:17:25 -07:00
Joseph Eng
2fc86a155d [benchmark] Add benchmark subproject (#8042) 2025-07-15 21:16:06 -07:00
sciencewhiz
f03df5388e [doc] Clarify mount orientation for SystemCore IMU (NFC) (#8088) 2025-07-14 23:47:59 -07:00
sciencewhiz
efedc5d69a [doc] Update Analog Input voltage to 3.3v (NFC) (#8085) 2025-07-14 23:47:30 -07:00
Thad House
8d248f61fd [hal] Various CAN fixes (#8043) 2025-07-14 23:46:57 -07:00
Thad House
3497a7d09f [hal] Add frequency support to DutyCycle (#8076) 2025-07-14 23:46:17 -07:00
Thad House
ef24c1df97 [hal] Implement HAL_GetSystemTimeValid on SystemCore (#8051) 2025-07-14 23:45:28 -07:00
PJ Reiniger
abeaa40e38 [ci] Install bazel on docker image builds (#8079)
Co-authored-by: David Vo <auscompgeek@users.noreply.github.com>
2025-07-13 22:12:45 -05:00
Peter Johnson
7c1a22376b Merge branch 'main' into 2027 2025-07-13 20:11:31 -07:00
sciencewhiz
8d7bed791c [ci] Revert Bazel artifactory caching (#8080)
* Revert "[bazel] Set remote cache header to prevent redirects (#8065)"

This reverts commit 082de35ad7.

* Revert "[ci] Add Bazel caching (#8006)"

This reverts commit c3b327d57b.
2025-07-13 21:56:00 -05:00
Ryan Blue
fa08679762 [wpiutil] Enable priority_mutex for systemcore (#8071) 2025-07-11 08:29:44 -05:00
Tyler Veness
69ecd02aec [upstream_utils] Add timestamps to commit hashes (#8078) 2025-07-10 17:01:15 -05:00
Kevin-OConnor
72d7a07635 [upstream_utils] Update fmt to recent commit (#8077)
Fixes crash seen in SystemCore Java debugging.
2025-07-10 17:00:25 -05:00
PJ Reiniger
d36b1d0dd9 [bazel] Update bazel toolchain, libssh, opencv (#8075) 2025-07-08 20:20:08 -07:00
Peter Johnson
7142fb1f5f Merge branch 'main' into 2027 2025-07-08 19:54:03 -07:00
Joseph Eng
6bac1cbc1a [docs] Add information about the development process (NFC) (#8012) 2025-07-08 00:21:23 -05:00
Austin Schuh
89c1fc156d [bazel] Switch build tag filters from no-roborio to target_compatible_with (#8067)
This uses platforms a lot better.

Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-07-07 23:44:08 -05:00
Jason Daming
708bf7d815 [wpilib] Add unit docs for return type of DCMotorSim getters (#8070)
We took away the units as part of the function name but didn't comment them back
2025-07-06 19:45:47 -07:00
Ryan Blue
082de35ad7 [bazel] Set remote cache header to prevent redirects (#8065)
Doesn’t fully fix the issue but improves things.
2025-07-06 08:28:56 -05:00
Austin Schuh
4b39853483 [build] Check results of subprocess.run in wpimath/generate_quickbuf.py (#8069)
The generator was calling a binary of the wrong architecture and failing
internally, but passing the build (incorrectly).  Explode right away.

Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-07-06 07:24:09 -05:00
Austin Schuh
d7550a02f7 [bazel] Upgrade and reorganize dependencies (#8063)
Pull in some of the fixes merged into the various dependencies.  While
we are here, move all the downloads up to the top of the file so they
download in parallel.

Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-07-05 18:59:22 -05:00
Thad House
f6558c4815 [hal] Update analog scaling for updated image (#8052) 2025-07-04 11:51:28 -07:00
Thad House
0304f50141 [wpiutil] Use steady_clock directly on SystemCore (#8053)
Don’t offset it from program start time.

This will make it much easier to coordinate timestamps across the system.

Closes #8041
2025-07-04 08:18:03 -05:00
Austin Schuh
44d42759a4 Work around gcc 12 overlap memory region warning (#8058)
Thad says this is a compiler bug, rather than fight it, let's use a new
code path through the compiler.

ERROR: /home/austin/local/allwpilib3/wpilibcExamples/BUILD.bazel:50:12: Compiling wpilibcExamples/src/main/cpp/examples/I2CCommunication/cpp/Robot.cpp failed: (Exit 1): gcc failed: error executing CppCompile command (from target //wpilibcExamples:I2CCommunication-test) /usr/bin/gcc -U_FORTIFY_SOURCE -fstack-protector -Wall -Wunused-but-set-parameter -Wno-free-nonheap-object -fno-omit-frame-pointer -g0 -O2 '-D_FORTIFY_SOURCE=1' -DNDEBUG -ffunction-sections ... (remaining 234 arguments skipped)

Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging
In file included from /usr/include/c++/12/ios:40,
                 from /usr/include/c++/12/istream:38,
                 from /usr/include/c++/12/sstream:38,
                 from /usr/include/c++/12/chrono:41,
                 from bazel-out/k8-opt/bin/wpilibc/_virtual_includes/wpilibc.static/frc/TimedRobot.h:7,
                 from bazel-out/k8-opt/bin/wpilibcExamples/_virtual_includes/I2CCommunication-examples-headers/Robot.h:10,
                 from wpilibcExamples/src/main/cpp/examples/I2CCommunication/cpp/Robot.cpp:5:
In static member function 'static constexpr std::char_traits<char>::char_type* std::char_traits<char>::copy(char_type*, const char_type*, std::size_t)',
    inlined from 'static constexpr void std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::_S_copy(_CharT*, const _CharT*, size_type) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]' at /usr/include/c++/12/bits/basic_string.h:423:21,
    inlined from 'static constexpr void std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::_S_copy(_CharT*, const _CharT*, size_type) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]' at /usr/include/c++/12/bits/basic_string.h:418:7,
    inlined from 'constexpr std::__cxx11::basic_string<_CharT, _Traits, _Allocator>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::_M_replace(size_type, size_type, const _CharT*, size_type) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]' at /usr/include/c++/12/bits/basic_string.tcc:532:22,
    inlined from 'constexpr std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::assign(const _CharT*) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]' at /usr/include/c++/12/bits/basic_string.h:1647:19,
    inlined from 'constexpr std::__cxx11::basic_string<_CharT, _Traits, _Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator=(const _CharT*) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]' at /usr/include/c++/12/bits/basic_string.h:815:28,
    inlined from 'virtual void Robot::RobotPeriodic()' at wpilibcExamples/src/main/cpp/examples/I2CCommunication/cpp/Robot.cpp:27:77:
/usr/include/c++/12/bits/char_traits.h:431:56: error: 'void* __builtin_memcpy(void*, const void*, long unsigned int)' accessing 9223372036854775810 or more bytes at offsets -4611686018427387902 and [-4611686018427387903, 4611686018427387904] may overlap up to 9223372036854775813 bytes at offset -3 [-Werror=restrict]
  431 |         return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
      |                                        ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~
cc1plus: all warnings being treated as errors
2025-07-03 22:58:47 -07:00
Gold856
c3b327d57b [ci] Add Bazel caching (#8006) 2025-07-03 23:15:18 -05:00
Gold856
26771e38fb [commands] Deprecate Command.schedule() (#7072)
It's only syntactic sugar over the CommandScheduler's schedule method and creates a footgun because it’s too obvious to try to use in incorrect places.

Co-authored-by: Starlight220 <53231611+Starlight220@users.noreply.github.com>
2025-07-02 13:46:59 -07:00
PJ Reiniger
1ccafdc13f [bazel] Simple shared library implementation (#8044) 2025-07-01 22:53:34 -07:00
crueter
6d92e2501d [wpimath] Remove unnecessary deprecation in ArmFeedForward (#8050)
Signed-off-by: crueter <swurl@swurl.xyz>
2025-06-30 21:13:54 -07:00
Peter Johnson
82ce317083 Merge branch 'main' into 2027 2025-06-30 20:21:11 -07:00
Gold856
a3ce880334 [ci] Update Homebrew protobuf version for CMake (#8045)
protobuf@3 will be deactivated July 1st, so it's been replaced with protobuf@29.
2025-06-30 00:10:37 -07:00
Nathan Karwel
e6bb29e2f1 [wpilib] Fix typos in notifier comments (NFC) (#8047) 2025-06-30 00:10:08 -07:00
Tyler Veness
633603dc3d [build] Fix Clang 20 warnings (#8048)
* `-Wfixed-enum-extension` was replaced with `-Wc23-extensions`
* Removed unused private variables in SysId
* Suppressed `-Wnontrivial-memcall` in imgui.h and imgui_internal.h
2025-06-30 00:09:41 -07:00
sciencewhiz
f2dd81c839 [build] Add checkstyle check for deprecation (#7738)
Ensures java deprecated notation is paired with javadoc and vice versa.
Adds javadoc deprecation for MecanumControllerCommand, ArmFeedForward,
ElevatorFeedforward, and MecanumDriveMotorVoltages
Fixes #7736
Supersedes #7737

Co-authored-by: Joseph Eng <91924258+KangarooKoala@users.noreply.github.com>
2025-06-30 00:09:02 -07:00
Joseph Eng
f55564729b [hal,wpilib,cmd] Update POVs to use enums (#7978) 2025-06-29 18:32:26 -07:00
PJ Reiniger
e13d237390 [bazel] Create better static libraries and add basic publishing (#8029) 2025-06-27 16:36:12 -07:00
Peter Johnson
ccc9740d56 [glass] Fix NT int64 value display (#8038) 2025-06-27 06:33:31 -07:00
ThePixelatedCat
ffe296892c [wpimath] Fix TrapezoidProfile limiting velocity incorrectly (#8030) 2025-06-24 22:36:53 -07:00
Gold856
22b58c1853 [upstream_utils] Upgrade to LLVM 20.1.7 (#8033)
Also removes xxhash, Hashing, and MapVector to reduce the size of the patches and to speed up compile times by a smidge.
2025-06-24 22:36:22 -07:00
Tyler Veness
ddc5220ed4 [upstream_utils] Remove memory library (#8035)
We added this in 2022. If we haven't used it by now, we probably never
will and it's just wasting space.
2025-06-24 22:35:30 -07:00
Jonah Bonner
a77441b78a [hal] Fix portrait yaw from onboard IMU (#8037) 2025-06-24 22:34:50 -07:00
Peter Johnson
676f2f84d7 [ntcore] Check id ranges in control messages (#7726) 2025-06-18 21:03:24 -07:00
Dustin Spicuzza
edde38a41a Restore original language from original contributor covenant (#7836)
- https://www.contributor-covenant.org/version/2/0/code_of_conduct/
2025-06-18 20:56:38 -07:00
Kevin Cooney
c655b7a893 [wpilibj] Add Preferences.getNetworkTable() (#7962) 2025-06-16 20:22:11 -07:00
Tyler Veness
057f5ddf81 [glass] Fix compilation errors from C++23 clang (#8008) 2025-06-16 19:01:00 -07:00
Thad House
2361959ff1 [hal] Fix I2C order on systemcore (#8024) 2025-06-16 18:41:02 -07:00
Austin Schuh
6cfa21364e [bazel] Upgrade bazel to 8.2.1 (#8023)
This necesitated some rules updates too, and a couple of flag changes.

Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-06-15 14:09:21 -07:00
Michael Lesirge
fb399eef3d [wpimath] Add copySignPow to MathUtil for joystick input shaping (#8013) 2025-06-15 14:08:41 -07:00
Michael Lesirge
e2517b7a21 [wpimath] Update parameter type from list to general collection (#8020) 2025-06-15 14:08:06 -07:00
Peter Johnson
3355383fe9 Merge branch 'main' into 2027 2025-06-13 22:26:09 -07:00
Thad House
fbee476fd2 [hal] Use new canbus names for systemcore (#8022)
The canbus names are changing to ensure stable ordering.
2025-06-13 21:30:42 -07:00
PJ Reiniger
fbbc4bc53c [bazel] Clean up bazel scripts (#7984) 2025-06-13 20:53:09 -07:00
Michael Lesirge
05c080328b [wpimath] Pass Translation2d by const reference instead of by value (#8021) 2025-06-13 18:50:05 -07:00
Michael Lesirge
c01e318370 [wpimath] Add Translation3d.nearest() (#8015) 2025-06-12 22:14:00 -07:00
Ryan Blue
5dfc664b93 [hal, wpilib] Add systemcore IMU (#8016) 2025-06-10 21:57:42 -07:00
Ryan Blue
89b97a21d8 [ntcore] Change 'null' to 'empty string' in NT StartServer docs (NFC) (#8017) 2025-06-10 21:55:51 -07:00
Michael Lesirge
075cc4a20f [wpimath] Add nearest() method to Pose3d (mirroring Pose2d) (#8010) 2025-06-05 22:11:49 -07:00
Peter Johnson
f99692f287 [ntcore] Minimize latency on localhost connections (#7997) 2025-06-02 16:43:18 -07:00
Thad House
2af8c59858 Replace /home/lvuser with /home/systemcore (#8002) 2025-06-02 16:42:56 -07:00
Thad House
4d74ea6278 [wpilib] Remove version writes (#8003)
This will use a much different mechanism in the future.
2025-06-02 16:41:47 -07:00
Thad House
a4cf2ea6ec [hal] Fix dutyCycle high time units (#8000)
The units are nanoseconds, not microseconds
2025-06-01 22:24:48 -07:00
Thad House
b205f3e1b4 [hal] Add temp value for HAL_GetUserVoltage3V3 (#8001)
Lots of higher level code in allwpilib depends on this, so we should return at least a valid and sane value, rather then erroring.
2025-06-01 22:23:51 -07:00
Thad House
be67432a5e [hal] Remove unnecessary print in CAN initialization (#8004) 2025-06-01 22:21:11 -07:00
DeltaDizzy
1955dcddb3 [wpimath] Fix SimpleMotorFeedforward no-accel overload returning negative voltage outputs (#7999)
SimpleMotorFeedforward::calculate(velocity) was not updated to account for the removal of calculate(velocity, acceleration), so it would pass currentVelocity = velocity and nextVelocity = 0, resulting in negative outputs in many scenarios.
2025-06-01 16:46:54 -07:00
Ryan Blue
e12d78a70a [ci] Deploy 2027 docs on tag (#7998) 2025-06-01 10:00:59 -07:00
Thad House
d3fbebc0a9 [hal] Add systemcore battery reading (#7995) 2025-05-31 10:53:11 -07:00
Thad House
1991af34a5 [hal] Update to new joystick protobuf definitions (#7991) 2025-05-31 10:52:27 -07:00
Ryan Shavell
7a3df6175e [epilogue] Add superclass field & method logging (#7993) 2025-05-31 06:38:51 -07:00
Peter Johnson
a6f601453a [examples] Fix up merge from main (#7994) 2025-05-30 17:36:53 -07:00
Peter Johnson
6c16e846fa Merge branch 'main' into 2027 2025-05-29 21:41:50 -07:00
Gold856
ca05ffa1b9 [upstream_utils] Use pathlib instead of os.path (#7983)
A noteworthy change is the replacement of the `dp.startswith(os.path.join(".", "subdir"))` pattern. pathlib doesn't offer something with similar semantics besides `match` and `full_match`, so there's now a helper function that replicates the behavior.

Other notable changes include the addition of type annotations to ensure code correctness, using == to check file names instead of `endswith` for clarity (`endswith` is still used to check extensions), manual walking and copying being refactored in googletest, json, memory, nanopb, protobuf, and sleipnir to use `walk_cwd_and_copy_if`, and matching functions being shortened to the point where they can just be inlined into the lambda.

Co-authored-by: Tyler Veness <calcmogul@gmail.com>
Co-authored-by: David Vo <auscompgeek@users.noreply.github.com>
2025-05-29 16:05:22 -06:00
Tyler Veness
de718f7ae5 [upstream_utils] Upgrade Sleipnir (#7973) 2025-05-27 08:24:15 -06:00
sciencewhiz
5368e8c6ed [ci] Disable RobotPy build (#7990)
Needs update for meson build
2025-05-27 08:19:39 -06:00
sciencewhiz
25eacfa226 Update frcYear to 2027_alpha1 for vendordeps (#7989) 2025-05-27 08:19:03 -06:00
Thad House
22d12d2345 [wpinet] Add callback for mDNS service resolver (#7986) 2025-05-23 15:22:59 -05:00
Phuc-Thanh Nguyen
abd312f3d0 [wpinet] http_parser: unset F_CHUNKED on new Transfer-Encoding (#7985) 2025-05-22 15:43:20 -06:00
Tyler Veness
b4823569a4 [upstream_utils] Upgrade Eigen to latest (#7982) 2025-05-19 14:26:53 -06:00
Thad House
0cb4df7e05 [hal] Fix joystick buttons not working on SC (#7980) 2025-05-18 07:03:52 -07:00
Thad House
231ec348fe [hal] Update DS API to new format (#7977) 2025-05-16 22:15:14 -07:00
Lucien Morey
d32e60233f [wpimath] Add dynamic size support for angle statistics (#7964) 2025-05-15 18:43:46 -07:00
sciencewhiz
1596e2fd7a [ci] Remove dispatch for tools not supported in 2027 (#7975) 2025-05-15 18:25:34 -07:00
sciencewhiz
79a9d7f987 [examples] Add Accelerometer filtering snippets 2025-05-13 22:03:22 -07:00
sciencewhiz
0877d130be [examples] Add Accelerometer collision detection snippets 2025-05-13 22:03:22 -07:00
sciencewhiz
89555383cc [examples] Add BuiltInAccelerometer Snippet 2025-05-13 22:03:22 -07:00
sciencewhiz
de315947e9 [examples] Add ADXL 345 and 362 snippets 2025-05-13 22:03:22 -07:00
sciencewhiz
b7cd03adc4 [examples] Add AnalogAccelerometer snippets
Delete AnalogAccelerometer comments about sensitivity and zero constants that don't exist
2025-05-13 22:03:22 -07:00
PJ Reiniger
6e3f48daeb [bazel] Add scripts to validate pregeneration tools (#7690) 2025-05-13 22:01:47 -07:00
PJ Reiniger
0e5a6f38d8 [bazel] MVP for building GUI related things with bazel (#7934)
Co-authored-by: David Vo <auscompgeek@users.noreply.github.com>
2025-05-12 08:24:41 -06:00
Tyler Veness
cc8eaf3ed7 [wpilib] Remove unhelpful comments from BooleanEvent (#7970)
These were apparently a meme about state being hard to manage rather
than a statement about the code itself. I spent a while trying to find
some complex logic this comment was alluding to that would indicate why
it's "a nightmare to manage".
2025-05-12 08:19:54 -06:00
Peter Johnson
dd6c830768 Revert "Added parity with C++ units. (#7965)" (#7968)
This reverts commit 3dee19a435.

This was merged without sufficient review or discussion as to whether these units are value-add for the Java units library.
2025-05-11 15:08:31 -07:00
T Grinch
3dee19a435 Added parity with C++ units. (#7965)
* Added parity with C++ units.

* Update Units.java

* Update Units.java

* Formatting

* Fixed formatting

---------

Co-authored-by: thenetworkgrinch <thenetworkgrinch@users.noreply.github.com>
2025-05-10 21:04:17 -04:00
sciencewhiz
55a97f0c11 [examples] Add Analog Potentiometer Snippets (#7957) 2025-05-10 07:18:19 -07:00
Yuhao
b1f7e6d6f2 [cscore] Resolve macOS camera freeze with specific devices (#7960)
Addresses an issue where certain USB cameras, specifically the ArduCam OV9281, would freeze when attempting to stream on macOS.

The previous logic started the AVCaptureSession (startRunning) before locking the device for configuration (lockForConfiguration). While this works for many cameras, it causes the OV9281 to become unresponsive.

Further investigation revealed:
- Moving startRunning to after unlockForConfiguration resulted in macOS overriding the custom format and frame rate settings applied within the lock.
- The reliable solution, inspired by findings shared in the community (e.g., Stack Overflow), is to lock the device, apply the configuration, start the session, and then unlock the device.

This commit reorders the operations within deviceStreamOn in UsbCameraImplObjc.mm to follow the sequence: lockForConfiguration -> apply settings -> startRunning -> unlockForConfiguration. This ensures the desired camera configuration is applied correctly without causing device freezes on problematic hardware like the OV9281.
2025-05-07 19:57:03 -07:00
Gold856
ca3137b291 [build] Remove statically linked JNI artifacts (#7553) 2025-05-05 22:10:07 -07:00
Lucien Morey
e1da917270 [wpimath] Add dynamic size support for numerical jacobian computation (#7959) 2025-05-05 21:55:51 -07:00
Peter Johnson
0a38400734 [datalog] Finish up a few missed moves from wpiutil split (#7956) 2025-05-04 11:21:29 -07:00
sciencewhiz
b96264f042 [examples] Misc fixes for snippets (#7952) 2025-05-04 00:13:46 -07:00
sciencewhiz
a15152712f [examples] Add AnalogInput snippets (#7951) 2025-05-04 00:13:20 -07:00
Eric
17cae787e7 [commands] Mark CommandPtr class as [[nodiscard]] (#7803)
This has the same effect but makes it so any user code returning CommandPtr can't discard a returned command.

Signed-off-by: Eric Ward <ezeward4@gmail.com>
2025-05-03 20:44:55 -07:00
Jade
02de5f710e [cscore] Fix memory leak in usbviewer example (#7922)
Signed-off-by: Jade Turner <spacey-sooty@proton.me>
2025-05-01 22:07:45 -07:00
sciencewhiz
e63899e63a [examples] Add snippets for Digital Input article (#7949) 2025-05-01 11:40:38 -06:00
Tyler Veness
ba37e7eb3c [wpimath] Fix warning false positive from GCC 15 (#7948)
```
In file included from /usr/include/c++/15.1.1/functional:61,
                 from /home/tav/frc/wpilib/allwpilib/thirdparty/googletest/include/gtest/gtest-matchers.h:43,
                 from /home/tav/frc/wpilib/allwpilib/thirdparty/googletest/include/gtest/internal/gtest-death-test-internal.h:47,
                 from /home/tav/frc/wpilib/allwpilib/thirdparty/googletest/include/gtest/gtest-death-test.h:43,
                 from /home/tav/frc/wpilib/allwpilib/thirdparty/googletest/include/gtest/gtest.h:65,
                 from /home/tav/frc/wpilib/allwpilib/wpimath/src/test/native/cpp/controller/ControlAffinePlantInversionFeedforwardTest.cpp:7:
In copy constructor ‘std::function<_Res(_ArgTypes ...)>::function(const std::function<_Res(_ArgTypes ...)>&) [with _Res = Eigen::Matrix<double, 2, 1>; _ArgTypes = {const Eigen::Matrix<double, 2, 1, 0, 2, 1>&, const Eigen::Matrix<double, 1, 1, 0, 1, 1>&}]’,
    inlined from ‘frc::ControlAffinePlantInversionFeedforward<States, Inputs>::ControlAffinePlantInversionFeedforward(std::function<Eigen::Matrix<double, Size, 1, (Eigen::AutoAlign | (((Size == 1) && (1 != 1)) ? Eigen::RowMajor : (((1 == 1) && (Size != 1)) ? Eigen::ColMajor :  Eigen::ColMajor))), Size, 1>(const Eigen::Matrix<double, Size, 1, (Eigen::AutoAlign | (((Size == 1) && (1 != 1)) ? Eigen::RowMajor : (((1 == 1) && (Size != 1)) ? Eigen::ColMajor :  Eigen::ColMajor))), Size, 1>&, const Eigen::Matrix<double, Cols, 1, (Eigen::AutoAlign | (((Cols == 1) && (1 != 1)) ? Eigen::RowMajor : (((1 == 1) && (Cols != 1)) ? Eigen::ColMajor :  Eigen::ColMajor))), Cols, 1>&)>, units::time::second_t) [with int States = 2; int Inputs = 1]’ at /home/tav/frc/wpilib/allwpilib/wpimath/src/main/native/include/frc/controller/ControlAffinePlantInversionFeedforward.h:59:19,
    inlined from ‘virtual void frc::ControlAffinePlantInversionFeedforwardTest_Calculate_Test::TestBody()’ at /home/tav/frc/wpilib/allwpilib/wpimath/src/test/native/cpp/controller/ControlAffinePlantInversionFeedforwardTest.cpp:29:70:
/usr/include/c++/15.1.1/bits/std_function.h:393:17: error: ‘<anonymous>’ may be used uninitialized [-Werror=maybe-uninitialized]
  393 |             __x._M_manager(_M_functor, __x._M_functor, __clone_functor);
      |             ~~~~^~~~~~~~~~
/usr/include/c++/15.1.1/bits/std_function.h: In member function ‘virtual void frc::ControlAffinePlantInversionFeedforwardTest_Calculate_Test::TestBody()’:
/usr/include/c++/15.1.1/bits/std_function.h:269:7: note: by argument 2 of type ‘const std::_Any_data&’ to ‘static bool std::_Function_handler<_Res(_ArgTypes ...), _Functor>::_M_manager(std::_Any_data&, const std::_Any_data&, std::_Manager_operation) [with _Res = Eigen::Matrix<double, 2, 1>; _Functor = frc::ControlAffinePlantInversionFeedforwardTest_Calculate_Test::TestBody()::<lambda(auto:45&, auto:46&)>; _ArgTypes = {const Eigen::Matrix<double, 2, 1, 0, 2, 1>&, const Eigen::Matrix<double, 1, 1, 0, 1, 1>&}]’ declared here
  269 |       _M_manager(_Any_data& __dest, const _Any_data& __source,
      |       ^~~~~~~~~~
/home/tav/frc/wpilib/allwpilib/wpimath/src/test/native/cpp/controller/ControlAffinePlantInversionFeedforwardTest.cpp:29:70: note: ‘<anonymous>’ declared here
   29 |                                                                 20_ms};
      |                                                                      ^
In copy constructor ‘std::function<_Res(_ArgTypes ...)>::function(const std::function<_Res(_ArgTypes ...)>&) [with _Res = Eigen::Matrix<double, 2, 1>; _ArgTypes = {const Eigen::Matrix<double, 2, 1, 0, 2, 1>&}]’,
    inlined from ‘frc::ControlAffinePlantInversionFeedforward<States, Inputs>::ControlAffinePlantInversionFeedforward(std::function<Eigen::Matrix<double, Size, 1, (Eigen::AutoAlign | (((Size == 1) && (1 != 1)) ? Eigen::RowMajor : (((1 == 1) && (Size != 1)) ? Eigen::ColMajor :  Eigen::ColMajor))), Size, 1>(const Eigen::Matrix<double, Size, 1, (Eigen::AutoAlign | (((Size == 1) && (1 != 1)) ? Eigen::RowMajor : (((1 == 1) && (Size != 1)) ? Eigen::ColMajor :  Eigen::ColMajor))), Size, 1>&)>, frc::Matrixd<Rows, Cols>&, units::time::second_t) [with int States = 2; int Inputs = 1]’ at /home/tav/frc/wpilib/allwpilib/wpimath/src/main/native/include/frc/controller/ControlAffinePlantInversionFeedforward.h:79:11,
    inlined from ‘virtual void frc::ControlAffinePlantInversionFeedforwardTest_CalculateState_Test::TestBody()’ at /home/tav/frc/wpilib/allwpilib/wpimath/src/test/native/cpp/controller/ControlAffinePlantInversionFeedforwardTest.cpp:45:73:
/usr/include/c++/15.1.1/bits/std_function.h:393:17: error: ‘<anonymous>’ may be used uninitialized [-Werror=maybe-uninitialized]
  393 |             __x._M_manager(_M_functor, __x._M_functor, __clone_functor);
      |             ~~~~^~~~~~~~~~
/usr/include/c++/15.1.1/bits/std_function.h: In member function ‘virtual void frc::ControlAffinePlantInversionFeedforwardTest_CalculateState_Test::TestBody()’:
/usr/include/c++/15.1.1/bits/std_function.h:269:7: note: by argument 2 of type ‘const std::_Any_data&’ to ‘static bool std::_Function_handler<_Res(_ArgTypes ...), _Functor>::_M_manager(std::_Any_data&, const std::_Any_data&, std::_Manager_operation) [with _Res = Eigen::Matrix<double, 2, 1>; _Functor = frc::ControlAffinePlantInversionFeedforwardTest_CalculateState_Test::TestBody()::<lambda(auto:47&)>; _ArgTypes = {const Eigen::Matrix<double, 2, 1, 0, 2, 1>&}]’ declared here
  269 |       _M_manager(_Any_data& __dest, const _Any_data& __source,
      |       ^~~~~~~~~~
/home/tav/frc/wpilib/allwpilib/wpimath/src/test/native/cpp/controller/ControlAffinePlantInversionFeedforwardTest.cpp:45:73: note: ‘<anonymous>’ declared here
   45 |                                                                 B, 20_ms};
      |                                                                         ^
```
2025-05-01 11:40:13 -06:00
Cory
7036bd509e [wpimath] Correct mil unit (#7950) 2025-05-01 11:28:02 -06:00
Yuhao
8fe3cfb325 [cscore] Add UVC Protocol Support for USB Camera Controls on macOS (#7926) 2025-04-30 08:02:59 -06:00
Jonah Snider
a4572a01b7 [wpiutil] Add nested struct schemas before parent schema (#7935)
When adding struct schemas, the current logic is to add the parent/outer schema, and then add the schemas for any nested inner schemas.  This reverses that order to make it easier for tools to process.

Matches C++ logic.
2025-04-29 20:52:27 -07:00
Lucien Morey
f14af97dc7 [wpimath] Support dynamic matrix sizes in StateSpaceUtil (#7942) 2025-04-29 11:58:28 -06:00
Jade
631521a980 [thirdparty] Set IMGUI_DEFINE_MATH_OPERATORS (#7899)
This avoids the need to define it early in the include order everywhere else.

Signed-off-by: Jade Turner <spacey-sooty@proton.me>
2025-04-29 08:44:17 -06:00
sciencewhiz
c49fc29046 [examples] Add Limit Switch snippets (#7946) 2025-04-29 08:42:32 -06:00
Nolan Barker
40ce42712f [wpimath] Fix coordinate frame docs in HolonomicDriveController (#7938) 2025-04-28 16:27:38 -07:00
sciencewhiz
659710a79a [examples] Add remaining Encoder snippets (#7936) 2025-04-28 16:25:49 -07:00
David Vo
d059cbc157 [bazel] Hide wpinet implementation headers (#7941)
The headers in wpinet/src/main/native/cpp/*.h aren't intended to be used by dependents, so they shouldn't get propagated.
2025-04-28 16:46:22 -06:00
Thad House
08297430b5 [hal,wpilib] Add support for second I2C port (#7878) 2025-04-28 09:29:01 -06:00
Thad House
85a8fc9943 [hal] Add SystemCore to Java runtime type (#7932) 2025-04-28 09:10:32 -06:00
Peter Johnson
36811211be Merge branch 'main' into 2027 2025-04-25 23:45:43 -07:00
Gold856
2f0990e9d2 [commands] Remove control commands and subsystems (#7921) 2025-04-25 22:06:26 -07:00
crueter
0695a4db89 [wpimath] Fix Debouncer type-changing behavior (#7870)
Closes #7867

Properly resets the baseline upon switching the debounce type, and adds
a test for such.

Signed-off-by: swurl <swurl@swurl.xyz>
2025-04-25 22:05:31 -07:00
me-it-is
3960045663 [wpimath] TrapezoidProfile: Fix null pointer when calling timeLeftUntil (#7894) 2025-04-25 21:58:05 -07:00
Tyler Veness
92010c175f Fix more emscripten compiler errors (#7895)
I ran the CMake configure with:
```bash
emcmake cmake -B build-wasm -S . \
  -DCMAKE_BUILD_TYPE=Release \
  -DBUILD_SHARED_LIBS=OFF \
  -DWITH_SIMULATION_MODULES=OFF \
  -DWITH_PROTOBUF=OFF \
  -DWITH_GUI=OFF \
  -DWITH_CSCORE=OFF
```

* Turned off simulation modules because they require shared libraries
* Turned off GUI because glfw requires libssh
* Turned off cscore because it requires OpenCV

I still get the following compiler errors:

```
/home/tav/frc/wpilib/allwpilib/wpinet/src/main/native/thirdparty/libuv/src/unix/linux.cpp:43:10: fatal error: 'sys/epoll.h' file not found
   43 | #include <sys/epoll.h>
      |          ^~~~~~~~~~~~~
```
```
/home/tav/frc/wpilib/allwpilib/wpinet/src/main/native/thirdparty/libuv/src/unix/stream.cpp:991:56: error: comparison of integers of different signs: 'unsigned long' and 'long' [-Werror,-Wsign-compare]
  991 |   for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) {
      |                                                        ^~~~~~~~~~~~~~~~~~~~~~
/home/tav/.cache/emscripten/sysroot/include/sys/socket.h:358:44: note: expanded from macro 'CMSG_NXTHDR'
  358 |         __CMSG_LEN(cmsg) + sizeof(struct cmsghdr) >= __MHDR_END(mhdr) - (unsigned char *)(cmsg) \
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
```
/home/tav/frc/wpilib/allwpilib/wpinet/src/main/native/thirdparty/libuv/src/unix/core.cpp:748:56: error: comparison of integers of different signs: 'unsigned long' and 'long' [-Werror,-Wsign-compare]
  748 |   for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg))
      |                                                        ^~~~~~~~~~~~~~~~~~~~~~
/home/tav/.cache/emscripten/sysroot/include/sys/socket.h:358:44: note: expanded from macro 'CMSG_NXTHDR'
  358 |         __CMSG_LEN(cmsg) + sizeof(struct cmsghdr) >= __MHDR_END(mhdr) - (unsigned char *)(cmsg) \
      |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
2025-04-25 21:56:26 -07:00
sciencewhiz
90ee11a9e0 [examples] Add DutyCycleEncoder Snippets (#7930) 2025-04-25 21:47:53 -07:00
David Vo
828199befb [ci] Use Bazel fastbuild compilation mode on Windows (#7925) 2025-04-25 21:46:40 -07:00
David Vo
d04e15b957 [bazel] Avoid globally linking macOS SDK frameworks (#7927) 2025-04-25 10:37:42 -07:00
Joseph Eng
d98ad815b1 [wpimath] Adjust applyDeadband logic (#7816)
Reduces nesting by returning when the value is within the deadband.

Adjusts the algorithm to handle large values of maxMagnitude naturally (instead of needing a separate check).

Reformats the math comments.
2025-04-23 08:41:03 -06:00
Austin Schuh
1c35a3a5ff [bazel] Make bazel work outside // (#7918)
The .bazelrc was doing a relative import, not an absolute one.

Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-04-23 08:31:43 -06:00
Gold856
b248663386 [ci] Upgrade sccache action (#7914) 2025-04-22 15:27:55 -06:00
Gold856
9c60da1319 [ci] Use sccache for RobotPy build (#7915)
Also uses Artifactory to store the caches.
2025-04-22 15:27:20 -06:00
sciencewhiz
21d921184a [examples] Add compilable code snippets (#7909)
This enables frc-docs to use RLIs for things that are currently in-line
code blocks, and ensures they compile, which is important with the 2027
breaking changes coming. They are kept separate from the examples to
ensure they don't polute the VSCode examples finder.

Adds the Encoder snippets used in the frc-docs Encoder article as the
first instance of this.
2025-04-22 15:26:26 -06:00
Yuhao
26e299115f [cscore] Fix USB video mode handling on macOS (#7904)
* fix: UsbCameraImpl on macOS

* fix: add back logs
2025-04-21 09:27:42 -07:00
Wispy
07192285f6 [wpiunits] Add InchesPerSecondPerSecond (#7905) 2025-04-17 19:00:14 -07:00
Tyler Veness
ed94e3af3e [ci] Upgrade sccache action (#7911) 2025-04-17 18:59:10 -07:00
Tyler Veness
3cd282d9b0 [ci] Upgrade to wpiformat 2025.33 (#7902) 2025-04-12 20:29:09 -07:00
Tyler Veness
49b4b064cf [docs] Update readme to say Xcode is required (#7892)
The command line tools are insufficient.
2025-04-08 08:11:15 -06:00
Tyler Veness
bd78215b43 [glass] Fix compilation error with protobuf 30.1 (#7890)
```
/home/tav/frc/wpilib/allwpilib/glass/src/libnt/native/cpp/NetworkTables.cpp: In function ‘void UpdateProtobufValueSource(glass::NetworkTablesModel&, glass::NetworkTablesModel::ValueSource*, const google::protobuf::Message&, std::string_view, int64_t)’:
/home/tav/frc/wpilib/allwpilib/glass/src/libnt/native/cpp/NetworkTables.cpp:363:27: error: no match for ‘operator+’ (operand types are ‘const char [7]’ and ‘google::protobuf::internal::DescriptorStringView’ {aka ‘std::basic_string_view<char>’})
  363 |   out->typeStr = "proto:" + desc->full_name();
      |                  ~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~
      |                  |                         |
      |                  const char [7]            google::protobuf::internal::DescriptorStringView {aka std::basic_string_view<char>}
```
2025-04-07 07:31:31 -06:00
Tyler Veness
c13b2f45c1 [wpimath] Update link to Ramsete controller derivation (#7887)
The derivation was moved from the Controls Engineering in FRC book to a
separate paper.
2025-03-30 16:25:08 -07:00
Jonah Snider
ea986427aa [wpiutil] Add Kaitai Struct definition for data log format (#7882)
Adds a Kaitai Struct definition for the WPILOG format. This can be used to generate code to read/write data log files without needing to build out a parser/serializer by hand. Or just an additional resource for readers to help understand the WPILOG format.
2025-03-27 16:51:13 -06:00
jpokornyiii
dcd397e007 [xrp] Update XRP for new SparkFun RP2350 Board (#7880)
Enables servos 3 and 4 usage on the new XRP board.
2025-03-26 08:50:09 -06:00
Thad House
e2cc9e0059 [hal, wpilib] PWM Rewrite (#7845)
The HAL will only contain the output period and the raw microseconds. Higher level things such as SimDevice can handle everything else.
2025-03-20 19:23:22 -07:00
Thad House
2e21a41f87 [hal] Set number of SmartIO and CAN buses (#7871) 2025-03-19 19:49:54 -07:00
Thad House
52b353fe57 [hal, wpilib] Remove power rails that don't exist on systemcore (#7861) 2025-03-14 10:16:08 -07:00
Jack Cammarata
1efaaefd78 [wpimath] Fix UnscentedKalmanFilter and improve math docs (#7850)
Throughout the code the state sqrt covariance S and innovation covariance Sy are maintained as upper triangular cholesky factors of those covariance matrices. The original paper defines P=S*S', so S should be lower triangular. The functions in the paper reflect this. In the code implementation, the sqrt covariance matrices are upper triangular, but the algorithm expects them to be lower triangular.

This bug was likely missed because the incorrect version of the filter is able to converge for some systems where all the states are observed, and the test case is set up such that all states are observed.

To fix the bug, a couple things needed to be changed:
all instances of rankUpdate() needed to be changed to use the lower triangular cholesky factor,
In the unscented transform, when S is found via QR decomposition, we need to take the transpose because R is upper triangular,
P() and SetP() functions need to be modified to be P=S*S' instead of P=S'*S, and P.llt().matrixL() instead of P.llt().matrixU() respectively.

Each part of the algorithm has also had the comments changed to clarify exactly which equation from the paper it implements.

Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2025-03-14 10:05:15 -07:00
Tyler Veness
71b6e8ec58 [wpiutil] Avoid including execinfo.h for Emscripten target (#7854) 2025-03-06 23:15:22 -08:00
Tyler Veness
1a835fec01 [wpimath] Fix singularities in Ellipse2d::Nearest() (#7851)
The problem was ill-conditioned if either semiaxis had zero length.
2025-03-04 18:52:17 -08:00
Tyler Veness
d3cc185382 [upstream_utils] Upgrade to fmt 11.1.4 (#7852) 2025-03-04 18:50:56 -08:00
crueter
0ad595c33c [wpimath] Add Debouncer type and time setters (#7839)
Signed-off-by: swurl <swurl@swurl.xyz>
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2025-03-03 17:21:38 -07:00
Tyler Veness
7cb29ce70b [datalog] Fix sorting of related header (#7832) 2025-03-02 10:47:48 -08:00
Thad House
93bf6c70ba [build] Remove sources from ceres-cpp (#7844) 2025-03-02 10:46:50 -08:00
arbessette
a7ae22d764 [docs] Update code of conduct (#7833) 2025-02-27 11:02:13 -08:00
Tyler Veness
822457d45b [wpimath] Fix feedforward returning NaN when kᵥ = 0 (#7790) 2025-02-25 19:07:51 -08:00
Thad House
baa20fa239 [hal, wpilib] Rewrite CAN APIs (#7798) 2025-02-25 19:07:01 -08:00
Adrien Bourdeaux
75321f1d84 [wpimath] Add Translation2d/Translation3d slew rate limiter (#7806)
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
Co-authored-by: Joseph Eng <91924258+KangarooKoala@users.noreply.github.com>
2025-02-25 19:06:00 -08:00
Tyler Veness
cd6fee7fea [sysid] Refactor feedback analysis (#7827) 2025-02-25 19:05:05 -08:00
Tyler Veness
517344fe80 [wpimath] Fix another infinite loop in ArmFeedforward (#7823) 2025-02-25 19:04:31 -08:00
Rain Heuer
b0e588fd49 [glass] Update Field2D default field to 2025 (#7820) 2025-02-25 19:04:16 -08:00
Tyler Veness
0f0e93722e [ci] Upgrade to Clang 17 sanitizers (#7819) 2025-02-25 19:01:41 -08:00
Gold856
b39744b562 [wpimath] Remove PathWeaver support (#7813)
Also rename file load type in glass to "Field Image JSON".
2025-02-21 07:43:45 -07:00
Thad House
72bba2491a [wpilib] Remove Nidec Brushless support (#7811) 2025-02-20 20:14:01 -08:00
sciencewhiz
f9307de04c [docs] Document that /format is disabled (#7810)
Add instructions for manual workarounds
2025-02-20 20:13:09 -08:00
sciencewhiz
15dcdebe21 [docs] Update contributing so breaking changes go to 2027 (#7809) 2025-02-20 20:12:48 -08:00
Peter Johnson
98f933eca5 Merge branch 'main' into 2027 2025-02-20 00:26:23 -08:00
Tyler Veness
0c3c2c1fda [sysid] Remove extra period from exception messages (#7805) 2025-02-19 21:08:39 -08:00
DeltaDizzy
da47f06d70 [datalog] Move all DataLog functionality to new datalog library (#7641)
Currently the major DataLog backend API (reading and writing) is split between wpiutil and glass. In the interest of allowing code that wants to use these APIs to not need to link to glass and declutter wpiutil, all of those APIs are moved to a new library named "datalog".

Signed-off-by: Jade Turner <spacey-sooty@proton.me>
Co-authored-by: Jade Turner <spacey-sooty@proton.me>
Co-authored-by: Gold856 <117957790+Gold856@users.noreply.github.com>
2025-02-19 21:08:17 -08:00
HarryXChen
c898853b4d [wpilib] LinearSystemSim.setState: calculate new output state (#7799)
Establishes the invariant that the state and measurement always match up, even immediately after construction.
2025-02-18 22:49:28 -08:00
Sam Carlberg
bd2211119f [epilogue] Make nonloggable type warnings configurable (#7792)
Now a flag at the class level controls whether warning messages are printed.

Defaults to false (no warning messages).
2025-02-18 21:48:51 -08:00
Tyler Veness
13626063dc [wpimath] Fix units typo (#7789) 2025-02-13 23:22:44 -08:00
Peter Johnson
7e6077c546 [wpimath] Fix up order and docs for Feedforward gain setters (#7788) 2025-02-13 23:20:08 -08:00
Jade
4d126b158c [wpimath] Add setters to Feedforward gains (#7784)
Signed-off-by: Jade Turner <spacey-sooty@proton.me>
2025-02-13 21:09:28 -08:00
Peter Johnson
e22f76ce73 [build] Bump native-utils to 2025.9.1 (#7783) 2025-02-13 20:23:07 -08:00
Jonah Bonner
e648b9c86d [wpinet] Serve index HTML file from WebServer if available (#7780) 2025-02-13 18:10:02 -08:00
Kevin-OConnor
23658a8c62 [apriltag] Split 2025 AprilTag Maps (#7781)
Splits maps for welded vs AndyMark field perimeters. More info about why and what fields are at what events will be in TU12.
2025-02-13 17:53:11 -08:00
Tyler Veness
155b3d45e7 [wpiutil] Remove broken StackWalker library (#7777)
A Discord user reported that StackWalker gives blank stacktraces.

MSVC's C++23 support is unstable, so we can't use std::stacktrace yet.
In the meantime, we can just return an empty string and remove the
unmaintained StackWalker library and its hacky upstream_utils script.
2025-02-12 22:54:41 -08:00
Austin Schuh
d62ab12855 [bazel] Add missing -ldl when building libuv in bazel (#7775)
I was getting:
external/arm_frc_linux_gnueabi_repo/bin/../arm-nilrt-linux-gnueabi/sysroot/usr/lib/gcc/arm-nilrt-linux-gnueabi/12/../../../../../../../arm-nilrt-linux-gnueabi/bin/ld: bazel-out/k8-opt--roborio/bin/external/com_github_wpilibsuite_allwpilib/wpinet/libwpinet.static.a(fs.o): undefined reference to symbol 'dlsym@@GLIBC_2.4'
external/arm_frc_linux_gnueabi_repo/bin/../arm-nilrt-linux-gnueabi/sysroot/usr/lib/gcc/arm-nilrt-linux-gnueabi/12/../../../../../../../arm-nilrt-linux-gnueabi/bin/ld: external/arm_frc_linux_gnueabi_repo/bin/../arm-nilrt-linux-gnueabi/sysroot/lib/libdl.so.2: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

This fixes that error for me.

Signed-off-by: Austin Schuh <austin.linux@gmail.com>
2025-02-12 16:17:11 -07:00
Dustin Spicuzza
1921d7b79a [wpilibc] Remove Alert magic static with map lookup (#7712)
The magic static adds yet another thing that needs to be reset if you
want to run a unit test with a completely reset wpilib state. Use the
existing Sendable static map to store the data instead.

This leaks memory if ResetSmartDashboardInstance is called.
2025-02-11 22:05:22 -08:00
Tyler Veness
ac1705ae2b [wpimath] Remove unit suffixes from variable names (#7529)
* Move units into API docs instead because suffixes make user code verbose and hard to read
* Rename trackWidth to trackwidth
* Make ultrasonic classes use meters instead of a mix of m, cm, mm, ft,
  and inches
2025-02-10 08:23:04 -07:00
Gold856
9dbb0c8c3d [ci] Turn on sync labels for the labeler (#7770)
This means PRs that had labels for certain changes will have those labels removed if those changes are removed.
2025-02-09 23:04:36 -08:00
Michael Fisher
b2584c6bdf [cmake] Use binary output dir for generated field images code (#7772) 2025-02-09 23:03:15 -08:00
Peter Johnson
53df127535 [cmake] Suppress enum warning on all clang, not just Apple (#7771) 2025-02-09 23:01:51 -08:00
Peter Johnson
d2611d4ad5 [hal] SPI: Remove byte limit on size in Java API (#7774)
The underlying Linux spidev supports up to page size length.
2025-02-09 23:01:01 -08:00
Peter Johnson
764ada9b66 [hal] Change usage reporting to string-based (#7763) 2025-02-07 13:37:23 -07:00
Ryan Blue
b60b2b64bd [hal, wpilib] AddressableLED: add support for other color orders (#7102)
Many LED strips use different color order (GRB in particular is common).

This makes the change at the HAL level. This solves 2 problems; first, no code needs to change in the high level drivers, which was challenging for C++, and second, simulation will behave properly as no conversion is needed. The HAL will accept an array of data objects in the same order no matter what the selected output order is, and will convert before sending it to the FPGA for output.

To accomplish this, NEON bulk load/interleave instructions are utilized. The low level implementation (load, store, and alignment functions) come from the Simd Library. The high level implementations are inspired by the image conversion functions in the simd library, but have diverged significantly.

Much of the implementation uses templates and inlined functions rather than runtime parameters; This is a trade off between the size of the generated code and the amount of function calls done at runtime. Currently, the entire conversion operation is inlined.
2025-02-07 13:36:41 -07:00
Ryan Blue
a0976a1fd9 [build] Update developerRobot JRE (#7764) 2025-02-07 11:24:30 -07:00
Peter Johnson
bfff891b5c [cameraserver] Remove Axis camera functions (#7767) 2025-02-05 20:33:32 -08:00
Peter Johnson
35aee1d78d [hal] Add ntcore to other libs in styleguide (NFC) (#7766) 2025-02-05 20:32:51 -08:00
DeltaDizzy
b3b515e1dd [sysid] Error on missing tests in loaded DataLog (#7747)
* add exception

* detect missing tests

* throw in analyzer

* define tests setter

* change to std::map

* alignas fail

* make missingTests parameter const&

* const& impl

* use set and naive comparison

* use default comparison

* add <utility>

* Revert "alignas fail"

This reverts commit 5e97940f34.

* indent validtests

* format
2025-02-04 18:12:00 -05:00
Joseph Eng
296986397b [wpimath] Document drift from desaturating discretized chassis speeds (NFC) (#7741) 2025-02-03 11:46:18 -07:00
DeltaDizzy
297f0d1b03 [wpiutil] Change kInvalidFile to macro (#7750)
This is needed on Windows because accessing global variables across shared library boundaries doesn’t work.
2025-01-30 20:01:35 -07:00
Thad House
ad29d45dfb [hal] Remove HAL_GetPort (#7754) 2025-01-30 19:59:34 -07:00
Thad House
6e704370b3 [hal, wpilib] Remove DigitalSource and AnalogTrigger (#7753) 2025-01-30 19:58:21 -07:00
Tyler Veness
7533b323d1 [upstream_utils] Upgrade to fmt 11.1.3 (#7629) 2025-01-30 13:35:33 -07:00
Sam Carlberg
18321e5551 [epilogue] Fix epilogue with package-info files (#7749) 2025-01-30 13:34:51 -07:00
Tyler Veness
b31fd17d05 [wpimath] Fix infinite loop in ArmFeedforward::Calculate(xₖ, vₖ, vₖ₊₁) (#7745)
Small values of kₐ make the iterative solver ill-conditioned. This
change reverts to the constant-acceleration feedforward in that case. It
gives _very_ bad results (hence why we added the iterative solver in the
first place), but it's better than hanging.

```
TEST(ArmFeedforwardTest, CalculateIllConditioned) {
  constexpr auto Ks = 0.5_V;
  constexpr auto Kv = 20_V / 1_rad_per_s;
  constexpr auto Ka = 1e-2_V / 1_rad_per_s_sq;
  constexpr auto Kg = 0_V;
  frc::ArmFeedforward armFF{Ks, Kg, Kv, Ka};

  // Calculate(currentAngle, currentVelocity, nextAngle, dt)
  CalculateAndSimulate(armFF, 0_rad, 0_rad_per_s, 2_rad_per_s, 20_ms);
}
```
This produces 1 V and doesn't accelerate the system at all. Using
nextVelocity instead of currentVelocity in the feedforward outputs 41 V
and still only accelerates to 0.4 rad/s of the requested 2 rad/s.

I picked the kₐ cutoff by increasing kₐ until the iterative solver
started converging.

Fixes #7743.
2025-01-30 13:33:39 -07:00
Thad House
48ce2dcc8d [hal, wpilib] Add initial systemcore counter implementation (#7723) 2025-01-28 09:58:34 -07:00
Thad House
b799b285b3 [hal, wpilib] Remove digital source from encoder (#7740) 2025-01-28 06:43:09 -07:00
PJ Reiniger
3b345fe218 [bazel] Add macros to build jni code and java tests (#7693) 2025-01-26 16:52:33 -08:00
Peter Johnson
eee30c49e2 [wpilib] Remove LiveWindow (#7733)
This will be replaced by a different mechanism, but removing it eases
the initial implementation burden of a new Telemetry/Sendable framework.
2025-01-25 10:52:19 -08:00
Peter Johnson
adbe95e610 [wpilib] Remove Shuffleboard API (#7730) 2025-01-24 23:47:42 -08:00
Peter Johnson
01e71e73ce [build] developerRobot: Fix link order (#7732)
ntcore now needs to be after hal.
2025-01-24 23:47:09 -08:00
Gold856
b44a80c07a [build] cmake: Install wpimath nanopb headers (#7731) 2025-01-24 23:26:09 -08:00
Gold856
25d11524e8 [ci] Re-enable Artifactory cleaner cron job (#7721)
The query now targets the local repo for extra safety.
2025-01-23 21:46:13 -08:00
Thad House
5898cdd5c3 [hal, wpilib] Remove interrupt (#7724) 2025-01-23 21:45:18 -08:00
Thad House
e2b6beb28a [hal, wpilib] Remove DigitalGlitchFilter (#7725) 2025-01-23 21:44:18 -08:00
Peter Johnson
d86a2ec83b [ci] Fix labeler indentation (#7716) 2025-01-21 12:51:48 -07:00
sciencewhiz
0690d3d832 [ci] Update labeler for wpical and usage reporting (#7710) 2025-01-20 09:14:27 -07:00
Ryan Blue
304b98c0c9 [wpilibc] Alert: Fix first alert in group not publishing data (#7711) 2025-01-20 09:10:03 -07:00
Joseph Eng
72541c10e6 [wpilib, commands] Improve HID direction documentation (NFC) (#7672) 2025-01-19 20:34:07 -08:00
sciencewhiz
00445f4f27 [hal] Add Kitbot framework usage reporting (#7709)
Used in FIRST's kitbot code
2025-01-18 15:02:41 -08:00
Matthew Wozniak
8fc3767b30 [wpimath] Fix macro name typo (#7707) 2025-01-17 22:19:21 -08:00
Peter Johnson
5ab0409c15 [wpilib] ADIS164xx: report product ID on mismatch (#7706) 2025-01-17 18:14:20 -08:00
Thad House
5a6c895b87 [hal, wpilib] Remove built in accelerometer (#7702) 2025-01-17 14:06:09 -08:00
Thad House
1600e773f4 [hal, wpilib] Remove DMA (#7701) 2025-01-17 14:05:34 -08:00
Peter Johnson
4caa16e254 [wpilibj] ADIS16470: Allow product ID of 16470 (#7704)
C++ allows either 16982 or 16470, do the same for Java.
2025-01-17 13:53:20 -08:00
Thad House
f80874dd4b [hal, wpilib] Remove analog accumulator and analog gyro (#7697)
The 2 high level classes were temporarily kept to keep the examples compiling. We will remove those when we have the interface into the built in IMU.
2025-01-17 12:58:31 -08:00
Thad House
92f0a3c961 [hal, wpilib] Remove SPI support (#7678) 2025-01-17 00:22:29 -08:00
Sam Carlberg
e52f400687 [wpiunits] Add Measure.per overloads for all known unit types (#7699)
Instead of only providing per(TimeUnit)

Useful for making conversion factors easier, eg `Inches.of(10).per(Rotation)` vs `Inches.of(10).per(Rotation.one())`

Update VelocityUnit.one() and VelocityUnit.zero() to return Velocity objects instead of generic Measure<? extends VelocityUnit<D>>; VelocityUnit is final, so the wildcard generic is unnecessary, and this makes the generated `per` functions possible for this type
2025-01-16 23:24:11 -08:00
Thad House
dc335ddedb [hal] Remove everything that references chipobject or VISA (#7698) 2025-01-16 23:21:40 -08:00
Thad House
ff1b2a205e [hal, wpilib] Remove analog output (#7696) 2025-01-16 23:20:44 -08:00
Thad House
5017393b3a [hal, wpilib] Remove relay (#7695) 2025-01-16 23:20:07 -08:00
Peter Johnson
d9f8fded09 Merge branch 'main' into 2027 2025-01-16 23:17:59 -08:00
PJ Reiniger
a9f3fc6b2c [bazel] Update toolchain to support systemcore (#7689) 2025-01-16 10:52:43 -07:00
Thad House
1cad4f64a4 [hal] Add high level way of getting systemserver NT instance (#7683) 2025-01-16 10:49:40 -07:00
Thad House
58cb395d76 [hal] Add systemcore duty cycle (#7682) 2025-01-15 12:57:31 -07:00
Thad House
24d6e87447 Remove CrossConn and Integration Tests (#7692) 2025-01-15 12:53:17 -07:00
Thad House
f81c42e700 [hal] Fix systemcore analog input scaling (#7691) 2025-01-15 12:52:57 -07:00
Thad House
fa71fb55a2 [wpilib] Remove I2C Warnings (#7677)
SystemCore won't have the I2C issues.
2025-01-14 12:31:47 -07:00
Thad House
45d7549ca9 [hal] Add systemcore analog input (#7681) 2025-01-14 12:30:44 -07:00
Thad House
afbaa43539 [wpiutil] Remove roboRIO-specific timestamp code (#7669) 2025-01-13 15:59:11 -07:00
David Racovan
a14545102f [wpimath] DifferentialDriveWheelPositions: tag as Proto/StructSerializable (#7622) 2025-01-13 14:52:40 -07:00
Tyler Veness
25e6549398 [wpimath] Fix various constexpr support bugs (#7676) 2025-01-13 14:44:55 -07:00
ハイドラント
cd92b07321 [wpimath] Add Pose2d and Pose3d rotateAround() (#7659) 2025-01-13 12:55:26 -07:00
Jason Daming
fc9e413ce1 [hal, wpilib] Add note about support for WS2815 (#7664) 2025-01-13 12:26:54 -07:00
Thad House
e41b33960a [rtns] Remove roboRIO team number setter (#7667)
It won't be needed in 2027.
2025-01-13 12:26:03 -07:00
Thad House
df77580a15 [hal] Remove athena hal folder (#7668)
Also remove roborio bazel target.
2025-01-13 12:25:28 -07:00
Thad House
09a6bc9a25 [build] Remove RoboRIO specializations from build system (#7670) 2025-01-13 12:23:54 -07:00
Tyler Veness
007526089e [wpimath] Fix LinearSystemId return type and docs (#7675)
Fixes #7674.
2025-01-13 12:22:53 -07:00
Thad House
666d1638ce [hal] Digital IO SystemCore implementation (#7621) 2025-01-12 16:58:46 -08:00
Sam Carlberg
c5f7a2b4ac [epilogue] Fix lazy logging of mutable arrays (#7665) 2025-01-11 10:25:47 -08:00
Peter Johnson
03d9e96877 [wpiutil] Change StringExtras split() to template (#7636)
It now calls back a function for each part rather than creating a SmallVector.
2025-01-05 20:53:43 -08:00
Peter Johnson
0f6693594c [glass] Split DataSource into type-specific variants (#7588) 2025-01-03 13:36:40 -08:00
Peter Johnson
148fcdca85 [wpiutil] DataLog: Move schema info to a separate map (#7626) 2025-01-03 13:28:50 -08:00
Peter Johnson
93521420c8 [wpinet] uv::AddrToName: Add StringAssignable constraint (#7627) 2025-01-03 13:28:29 -08:00
Peter Johnson
12a1475ee4 [wpiutil] Remove LEB128 (#7628)
This was only used for NT3.
2025-01-03 07:13:49 -08:00
Peter Johnson
1240ee1bf4 [ntcore] Remove NT3 support (#7625)
- Remove StartClient3
- Rename StartClient4 to StartClient
- Remove port3 parameter from StartServer
- Remove 3-suffix constants
- Remove 4 suffix from constants

Also remove Shuffleboard build from CI.
2025-01-02 23:05:13 -08:00
Peter Johnson
da90ffd24a [wpical] Disable systemcore target (#7620) 2025-01-01 16:30:23 -08:00
Peter Johnson
a931a6554f Merge branch 'main' into 2027 2024-12-29 18:22:39 -08:00
Peter Johnson
3232630a38 Merge branch 'main' into 2027 2024-12-27 19:40:43 -08:00
Tyler Veness
df244cd198 [wpimath] Clean up arm and elevator feedforward APIs (#7595) 2024-12-27 08:12:14 -06:00
Peter Johnson
2a757eaeb5 Merge branch 'main' into 2027 2024-12-26 18:55:43 -08:00
hjelstromboli
78b14c5204 [hal] Update SmartIO PWM implementation (#7571)
* Integer microsecond setters and getters
* Per-port subtables
2024-12-22 13:45:44 -06:00
Peter Johnson
529bab6ca1 Merge branch 'main' into 2027 2024-12-19 20:40:37 -08:00
Tyler Veness
03f0fc4dea [wpimath] Use immutable member functions in ChassisSpeeds (#7545) 2024-12-15 16:09:34 -08:00
Peter Johnson
945d416d07 Merge branch 'main' into 2027 2024-12-14 10:45:32 -08:00
Thad House
6ba7189373 [hal] Enable periodic CAN sends (#7530)
* Implement periodic can support

* Fix build
2024-12-08 22:29:01 -08:00
Thad House
31d1aa62c1 [hal] Fixes for making PWM drive (#7528)
* Increase connection timeout, fix ld path, properly initialize smart io.

* Also fix HAL_GetSystemTimeValid, so DataLogManager doesn't throw errors.
2024-12-08 22:08:05 -08:00
Thad House
b6ae9e9cc9 Merge branch 'main' into 2027 2024-12-08 12:04:23 -08:00
Thad House
f1e4eafaa0 [hal] Add initial PWM support for systemcore (#7525) 2024-12-08 12:02:22 -08:00
Thad House
41d4826694 [hal] Initial CAN implementation for SystemCore (#7514) 2024-12-08 12:01:28 -08:00
Tyler Veness
220f4e1ba4 [wpimath] Remove RamseteController and RamseteCommand (#7522) 2024-12-07 23:38:35 -08:00
Tyler Veness
ae44295024 Use std::bit_cast (#7492) 2024-12-07 23:02:09 -08:00
Tyler Veness
4910436b10 [wpimath] Remove LUTs from LTV controllers (#7521)
The Raspberry Pi 5 is fast enough that we no longer need it.
```
Running ./build/DAREBench
Run on (4 X 2400 MHz CPU s)
CPU Caches:
  L1 Data 64 KiB (x4)
  L1 Instruction 64 KiB (x4)
  L2 Unified 512 KiB (x4)
  L3 Unified 2048 KiB (x1)
Load Average: 0.47, 0.72, 0.45
***WARNING*** CPU scaling is enabled, the benchmark real time measurements may be noisy and will incur extra overhead.
-------------------------------------------------------------------------------
Benchmark                                     Time             CPU   Iterations
-------------------------------------------------------------------------------
DARE_WPIMath_Dynamic                       34.4 us         34.4 us        20315
DARE_WPIMath_NoPrecondChecks_Dynamic       21.7 us         21.7 us        32266
DARE_WPIMath_Static                        15.2 us         15.2 us        45878
DARE_WPIMath_NoPrecondChecks_Static        7.84 us         7.84 us        89316
DARE_SLICOT                                79.4 us         79.4 us         8789
DARE_Drake                                 34.9 us         34.9 us        20074
```
2024-12-07 23:00:15 -08:00
Tyler Veness
a7349f00ef [wpimath] Fix duplicate Rotation2d constructor (#7524) 2024-12-07 22:31:09 -08:00
Peter Johnson
e493da3486 Merge branch 'main' into 2027 2024-12-07 21:38:18 -08:00
Peter Johnson
32ba751e58 Merge branch 'main' into 2027 2024-12-07 21:30:28 -08:00
Tyler Veness
62a6a77bbf [wpimath] Add affine transformation constructors and getters to geometry API (#7509)
Fixes #7429.
2024-12-07 21:29:02 -08:00
Tyler Veness
c81bd0c909 [ci] Upgrade to Ubuntu 24.04 (#7496) 2024-12-07 21:20:48 -08:00
Tyler Veness
c497e4ec22 [wpimath] Fix SimpleFeedforward overload set (#7516) 2024-12-07 20:32:16 -08:00
Thad House
6dbff902fa [build] Remove athena completely from build (#7517) 2024-12-07 20:31:10 -08:00
Thad House
be72e0ecd8 Skip linux arm64 build on tools build (#7511) 2024-12-07 16:37:11 -08:00
Thad House
e69c5710b3 [hal] Add ErrorInfo support to systemcore DS (#7488) 2024-12-07 14:14:21 -08:00
Peter Johnson
52b33edcbd Merge branch 'main' into 2027 2024-12-07 14:11:47 -08:00
Thad House
c8900cadc3 Add SPARKmini to PWM support (#7504) 2024-12-07 00:48:20 -08:00
Thad House
5058b48dea [developerRobot] Switch to initial password and host for systemcore (#7503) 2024-12-06 23:19:48 -08:00
Tyler Veness
144e79a614 [wpimath] Remove Rotation2d value field (#7490)
It's not part of SO(2).
2024-12-06 21:00:09 -08:00
Thad House
38b09a6dfd [hal] Clean up systemcore notifier impl (#7487)
* Clean up systemcore notifier impl

* Formatting fixes

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-12-05 09:17:45 -08:00
Thad House
d7cd71589a [hal] Enable an I2C bus on systemcore (#7485) 2024-12-04 20:19:51 -08:00
Thad House
a954091ea2 [ci] Remove 32-bit Windows builds (#7475) 2024-12-01 17:45:04 -08:00
Thad House
bf653d9895 [hal] Add SystemServer DS support (#7466) 2024-12-01 17:05:07 -08:00
Thad House
5a9e0abe44 [ci] Build tools with systemcore image (#7472) 2024-12-01 17:03:51 -08:00
Peter Johnson
5cab27fdd5 Merge branch 'main' into 2027 2024-12-01 17:03:03 -08:00
Thad House
ce63770970 Merge branch 'main' into 2027 2024-12-01 12:40:50 -08:00
Thad House
c51f65bd4f [hal] Add initial SystemServer support (#7463) 2024-11-30 20:31:26 -08:00
Thad House
82132c3272 [hal] Initial SystemCore empty HAL (#7454) 2024-11-30 10:04:00 -08:00
Peter Johnson
847c3120d3 Merge branch 'main' into 2027 2024-11-30 00:35:00 -08:00
Peter Johnson
7ae4333c81 [ci] Publish on 2027 repositories 2024-11-29 23:52:22 -08:00
9690 changed files with 625675 additions and 623487 deletions

View File

@@ -6,12 +6,12 @@ apriltag/bin
cameraserver/bin
cameraserver/multiCameraServer/bin
cscore/bin
fieldImages/bin
fields/bin
hal/bin
developerRobot/bin
ntcore/bin
romiVendordep/bin
wpilibNewCommands/bin
commandsv2/bin
wpilibj/bin
wpimath/bin
wpinet/bin

View File

@@ -1,38 +1,54 @@
try-import %workspace%/bazel_auth.rc
try-import %workspace%/user.bazelrc
common --noenable_bzlmod
common --enable_bzlmod --enable_workspace
# Resolves to --config=linux on Linux, --config=macos on Mac, --windows on windows
common --enable_platform_specific_config
build --java_language_version=17
build --java_runtime_version=roboriojdk_17
build --tool_java_language_version=17
build --tool_java_runtime_version=remotejdk_17
# Make bazel 8 work for us.
common --enable_workspace
build --experimental_cc_static_library
build --experimental_cc_shared_library
build --java_language_version=25
build --java_runtime_version=remotejdk_25
build --tool_java_language_version=25
build --tool_java_runtime_version=remotejdk_25
test --test_output=errors
test --test_verbose_timeout_warnings
import shared/bazel/compiler_flags/sanitizers.rc
import shared/bazel/compiler_flags/base_linux_flags.rc
import shared/bazel/compiler_flags/linux_flags.rc
import shared/bazel/compiler_flags/osx_flags.rc
import shared/bazel/compiler_flags/roborio_flags.rc
import shared/bazel/compiler_flags/windows_flags.rc
import shared/bazel/compiler_flags/coverage_flags.rc
import %workspace%/shared/bazel/compiler_flags/sanitizers.rc
import %workspace%/shared/bazel/compiler_flags/linux_flags.rc
import %workspace%/shared/bazel/compiler_flags/osx_flags.rc
import %workspace%/shared/bazel/compiler_flags/roborio_flags.rc
import %workspace%/shared/bazel/compiler_flags/systemcore_flags.rc
import %workspace%/shared/bazel/compiler_flags/windows_flags.rc
import %workspace%/shared/bazel/compiler_flags/coverage_flags.rc
# Alias toolchain names to what wpilibsuite uses for CI/Artifact naming
build:athena --config=roborio
build:linuxarm32 --config=raspibookworm32
build:linuxarm64 --config=bookworm64
build:build_java --test_tag_filters=allwpilib-build-java --build_tag_filters=allwpilib-build-java
build:build_cpp --test_tag_filters=+allwpilib-build-cpp --build_tag_filters=+allwpilib-build-cpp
build:no_example --test_tag_filters=-wpi-example --build_tag_filters=-wpi-example
test:no_example --test_tag_filters=-wpi-example --build_tag_filters=-wpi-example
common:skip_robotpy --test_tag_filters=-robotpy --build_tag_filters=-robotpy
# Build Buddy BES Setup
build:build_buddy_bes --bes_results_url=https://app.buildbuddy.io/invocation/
build:build_buddy_bes --bes_backend=grpcs://remote.buildbuddy.io
# Common Cache Settings
build:common_cache --remote_timeout=3600
build:common_cache --remote_cache_compression
build:common_cache --experimental_remote_cache_compression_threshold=100
# Build Buddy Cache Setup
build:build_buddy --bes_results_url=https://app.buildbuddy.io/invocation/
build:build_buddy --bes_backend=grpcs://remote.buildbuddy.io
build:build_buddy --config=common_cache
build:build_buddy --config=build_buddy_bes
build:build_buddy --remote_cache=grpcs://remote.buildbuddy.io
build:build_buddy --remote_timeout=3600
# Additional suggestions from buildbuddy for speed
build:build_buddy --experimental_remote_cache_compression
build:build_buddy --experimental_remote_cache_compression_threshold=100
build:build_buddy --noslim_profile
build:build_buddy --experimental_profile_include_target_label
build:build_buddy --experimental_profile_include_primary_output
@@ -40,12 +56,36 @@ build:build_buddy --nolegacy_important_outputs
common:build_buddy_readonly --noremote_upload_local_results
# Bazel-remote cache setup
build:remote_cache --config=common_cache
build:remote_cache --remote_cache=grpcs://gitlib-bazel.wpi.edu
common:remote_cache_readonly --noremote_upload_local_results
# This config should be used locally. It downloads more than the CI version
build:remote_user --config=build_buddy
build:remote_user --config=build_buddy_readonly
build:remote_user --config=remote_cache
build:remote_user --config=remote_cache_readonly
build:remote_user --remote_download_toplevel
build:ci --config=build_buddy
common:ci --color=yes
build:ci --remote_download_minimal
build:ci --progress_report_interval=60 --show_progress_rate_limit=60
build --build_metadata=REPO_URL=https://github.com/wpilibsuite/allwpilib.git
common --define="WPILIB_VERSION=2025.424242.3.1-unknown"
common --define="ROBOTPY_VERSION=2025.424242.3.1"
# List of artifact types to build in CI.
# Anything else gets skipped to speed up CI.
common:ci --repo_env="WPI_PUBLISH_CLASSIFIER_FILTER=headers,sources,linuxsystemcore,linuxsystemcoredebug,linuxsystemcorestatic,linuxsystemcorestaticdebug,linuxx86-64,linuxx86-64debug,linuxx86-64static,linuxx86-64staticdebug,osxuniversal,osxuniversaldebug,osxuniversalstatic,osxuniversalstaticdebug,windowsarm64,windowsarm64debug,windowsarm64static,windowsarm64staticdebug,windowsx86-64,windowsx86-64debug,windowsx86-64static,windowsx86-64staticdebug"
# The 2 configurations for windows are very slow to build each time.
# Instead, skip the cross transition for ARM on x86, and the reverse on x86.
common:ci_windows_x86 --repo_env="WPI_PUBLISH_CLASSIFIER_FILTER=headers,sources,linuxsystemcore,linuxsystemcoredebug,linuxsystemcorestatic,linuxsystemcorestaticdebug,linuxx86-64,linuxx86-64debug,linuxx86-64static,linuxx86-64staticdebug,osxuniversal,osxuniversaldebug,osxuniversalstatic,osxuniversalstaticdebug,windowsx86-64,windowsx86-64debug,windowsx86-64static,windowsx86-64staticdebug"
common:ci_windows_arm --repo_env="WPI_PUBLISH_CLASSIFIER_FILTER=headers,sources,linuxsystemcore,linuxsystemcoredebug,linuxsystemcorestatic,linuxsystemcorestaticdebug,linuxx86-64,linuxx86-64debug,linuxx86-64static,linuxx86-64staticdebug,osxuniversal,osxuniversaldebug,osxuniversalstatic,osxuniversalstaticdebug,windowsarm64,windowsarm64debug,windowsarm64static,windowsarm64staticdebug"
build --@rules_python//python/config_settings:bootstrap_impl=script
build --@rules_python//python/config_settings:venvs_use_declare_symlink=no
try-import %workspace%/bazel_auth.rc

View File

@@ -1 +1 @@
7.3.1
8.5.0

View File

@@ -104,25 +104,52 @@ ForEachMacros:
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Regroup
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<ext/.*\.h>'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*\.h>'
Priority: 1
SortPriority: 0
CaseSensitive: false
- Regex: '^<.*'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 3
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '([-_](test|unittest))?$'
# C standard library headers
#
# https://en.cppreference.com/w/cpp/header:
# * C compatibility headers
# * Special C compatibility headers
# * Empty C headers
# * Meaningless C headers
# * Unsupported C headers
- Regex: '^<(assert\.h|ctype\.h|errno\.h|fenv\.h|float\.h|inttypes\.h|limits\.h|locale\.h|math\.h|setjmp\.h|signal\.h|stdarg\.h|stddef\.h|stdint\.h|stdio\.h|stdlib\.h|string\.h|time\.h|uchar\.h|wchar\.h|wctype\.h|stdatomic\.h|ccomplex|complex\.h|ctgmath|tgmath\.h|ciso646|cstdalign|cstdbool|iso646\.h|stdalign\.h|stdbool\.h|stdatomic\.h|stdnoreturn\.h|threads\.h)>'
Priority: 1
SortPriority: 0
# Linux system headers
- Regex: '^<((arpa\/|linux\/|net/|netinet\/|sys\/).*|arm_neon\.h|dirent\.h|dlfcn\.h|fcntl\.h|ifaddrs\.h|jni\.h|libgen\.h|poll\.h|spawn\.h|termios\.h|unistd\.h)>'
Priority: 1
SortPriority: 1
# winsock2.h
- Regex: '^<winsock2\.h>'
Priority: 1
SortPriority: 2
# windows.h
- Regex: '^<windows.\h>'
Priority: 1
SortPriority: 3
# Windows def.h headers
- Regex: '^<(comdef\.h|ws2def\.h|ws2ipdef\.h)>'
Priority: 1
SortPriority: 4
# Windows system headers
- Regex: '^<(dbghelp\.h|dbt\.h|delayimp\.h|dshow\.h|io\.h|iphlpapi\.h|ks\.h|ksmedia\.h|memoryapi\.h|mfapi\.h|mferror\.h|mfidl\.h|mfreadwrite\.h|netioapi\.h|ntstatus\.h|shellapi\.h|shlobj\.h|shlwapi\.h|sysinfoapi\.h|windns\.h|windowsx\.h|winternl\.h|ws2tcpip\.h)>'
Priority: 1
SortPriority: 5
# C++ standard library headers (lowercase and underscores with no .h suffix)
- Regex: '^<([a-z_]+|cxxabi\.h)>'
Priority: 2
SortPriority: 6
# Other library headers (angle brackets)
- Regex: '^<.*'
Priority: 3
SortPriority: 7
# Project headers (double quotes)
- Regex: '^".*'
Priority: 4
SortPriority: 8
IncludeIsMainRegex: '(Test|_bench|_test)?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseBlocks: false
@@ -213,7 +240,7 @@ RequiresClausePosition: OwnLine
RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SortIncludes: false
SortIncludes: true
SortJavaStaticImport: Before
SortUsingDeclarations: LexicographicNumeric
SpaceAfterCStyleCast: false

View File

@@ -45,6 +45,8 @@ Checks:
-clang-diagnostic-#warnings,
-clang-diagnostic-pedantic,
clang-analyzer-*,
-clang-analyzer-optin.cplusplus.UninitializedObject,
-clang-analyzer-security.FloatLoopCounter,
cppcoreguidelines-slicing,
google-build-namespaces,
google-explicit-constructor,
@@ -66,4 +68,8 @@ Checks:
modernize-use-override,
modernize-use-using,
readability-braces-around-statements'
CheckOptions:
- key: modernize-use-using.IgnoreExternC
value: 'true'
FormatStyle: file
HeaderFilterRegex: '^((?!thirdparty/).)*$'

View File

@@ -1,6 +1,4 @@
color: false
definitions: [cmake/modules]
line_length: 100
list_expansion: favour-inlining
quiet: false
unsafe: false

7
.gitattributes vendored
View File

@@ -1,8 +1,8 @@
*.adoc text eol=lf
*.c text eol=lf
*.cmake text eol=lf
*.clang-format text eol=lf
*.clang-tidy text eol=lf
*.cmake text eol=lf
*.cpp text eol=lf
*.gradle text eol=lf
*.groovy text eol=lf
@@ -20,11 +20,14 @@
*.plist text eol=lf
*.proto text eol=lf
*.py text eol=lf
*.styleguide text eol=lf
*.txt text eol=lf
*.wpiformat text eol=lf
*.wpiformat-license text eol=lf
*.xml text eol=lf
*.yaml text eol=lf
*.yml text eol=lf
# Generated files
*/src/generated/** linguist-generated
*/robotpy_native_build_info.bzl linguist-generated
*/robotpy_pybind_build_info.bzl linguist-generated

2
.github/CODEOWNERS vendored
View File

@@ -27,7 +27,7 @@
/simulation/ @wpilibsuite/simulation
/wpilibNewCommands/ @wpilibsuite/commandbased
/commandsv2/ @wpilibsuite/commandbased
/wpilibcExamples/ @wpilibsuite/wpilib @wpilibsuite/documentation

View File

@@ -5,7 +5,7 @@ runs:
using: "composite"
steps:
- name: Set up Python 3.12
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.12'
- name: Install jinja and protobuf
@@ -18,14 +18,15 @@ runs:
wget https://github.com/HebiRobotics/QuickBuffers/releases/download/1.3.3/protoc-gen-quickbuf-1.3.3-linux-x86_64.exe
chmod +x protoc-gen-quickbuf-1.3.3-linux-x86_64.exe
shell: bash
- name: Regenerate hal
run: ./hal/generate_usage_reporting.py
shell: bash
- name: Regenerate ntcore
run: ./ntcore/generate_topics.py
shell: bash
- name: Regenerate mrccomm
run: ./hal/generate_nanopb.py
shell: bash
- name: Regenerate imgui
run: |
./thirdparty/imgui_suite/generate_fonts.sh
@@ -36,7 +37,7 @@ runs:
run: |
./wpilibc/generate_hids.py
./wpilibj/generate_hids.py
./wpilibNewCommands/generate_hids.py
./commandsv2/generate_hids.py
shell: bash
- name: Regenerate PWM motor controllers
@@ -46,7 +47,7 @@ runs:
shell: bash
- name: Regenerate mrcal minimath
run: ./wpical/generate_mrcal.py
run: ./tools/wpical/generate_mrcal.py
shell: bash
- name: Regenerate wpimath
@@ -56,6 +57,11 @@ runs:
./wpimath/generate_quickbuf.py --quickbuf_plugin protoc-gen-quickbuf-1.3.3-linux-x86_64.exe
shell: bash
- name: Regenerate Commands v3
run: |
./commandsv3/generate_files.py --quickbuf_plugin protoc-gen-quickbuf-1.3.3-linux-x86_64.exe
shell: bash
- name: Regenerate wpiunits
run: ./wpiunits/generate_units.py
shell: bash

View File

@@ -0,0 +1,38 @@
name: 'Setup Bazel Cache'
description: 'Configures the Bazel remote cache. Prefers WPI bazel-remote (R/W), falls back to BuildBuddy, then readonly WPI cache.'
inputs:
bazel_remote_username:
description: 'WPI Bazel remote cache username'
bazel_remote_password:
description: 'WPI Bazel remote cache password'
bazel_remote_url:
description: 'WPI Bazel remote cache base URL (no credentials or protocol, e.g. gitlib-bazel.wpi.edu)'
default: 'gitlib-bazel.wpi.edu'
buildbuddy_token:
description: 'BuildBuddy API token'
runs:
using: "composite"
steps:
- name: Resolve Bazel cache configuration
env:
CACHE_USER: ${{ inputs.bazel_remote_username }}
CACHE_PASS: ${{ inputs.bazel_remote_password }}
REMOTE_URL: ${{ inputs.bazel_remote_url }}
BB_TOKEN: ${{ inputs.buildbuddy_token }}
shell: bash
run: |
if [ -n "${CACHE_USER}" ] && [ -n "${CACHE_PASS}" ]; then
echo "WPI bazel-remote credentials detected; configuring R/W access"
echo "build:remote_cache --remote_cache=grpcs://${CACHE_USER}:${CACHE_PASS}@${REMOTE_URL}" > bazel_auth.rc
echo "build:ci --config=remote_cache" >> bazel_auth.rc
elif [ -n "${BB_TOKEN}" ]; then
echo "BuildBuddy token detected; configuring BuildBuddy cache"
echo "build:build_buddy --remote_header=x-buildbuddy-api-key=${BB_TOKEN}" > bazel_auth.rc
echo "build:ci --config=build_buddy" >> bazel_auth.rc
else
echo "No cache credentials detected; falling back to readonly WPI cache"
echo "build:ci --config=remote_cache" > bazel_auth.rc
echo "build:ci --config=remote_cache_readonly" >> bazel_auth.rc
fi

View File

@@ -1,27 +0,0 @@
name: 'Setup BuildBuddy acache'
description: 'Sets up the build buddy cache to be readonly / writing based on the presence of environment variables'
inputs:
token:
description: 'Build Buddy API token'
runs:
using: "composite"
steps:
- name: Setup without key
env:
API_KEY: ${{ inputs.token }}
if: ${{ env.API_KEY == '' }}
shell: bash
run: |
echo "No API key secret detected, will setup readonly cache"
echo "build:ci --config=build_buddy_readonly" > bazel_auth.rc
- name: Set with key
env:
API_KEY: ${{ inputs.token }}
if: ${{ env.API_KEY != '' }}
shell: bash
run: |
echo "API Key detected!"
echo "build:build_buddy --remote_header=x-buildbuddy-api-key=${{ env.API_KEY }}" > bazel_auth.rc

152
.github/labeler.yml vendored
View File

@@ -1,56 +1,96 @@
'2027':
- base-branch: '2027'
'component: apriltag':
- changed-files:
- any-glob-to-any-file: apriltag/**
'component: command-based':
- changed-files:
- any-glob-to-any-file: wpilibNewCommands/**
'component: cscore':
- changed-files:
- any-glob-to-any-file: cscore/**
'component: datalogtool':
- changed-files:
- any-glob-to-any-file: datalogtool/**
'component: epilogue':
- changed-files:
- any-glob-to-any-file: epilogue-*/**
'component: examples':
- changed-files:
- any-glob-to-any-file: wpilib*Examples/**
'component: glass':
- changed-files:
- any-glob-to-any-file: glass/**
'component: hal':
- changed-files:
- any-glob-to-any-file: hal/**
'component: ntcore':
- changed-files:
- any-glob-to-any-file: ntcore/**
'component: outlineviewer':
- changed-files:
- any-glob-to-any-file: outlineviewer/**
'component: sysid':
- changed-files:
- any-glob-to-any-file: sysid/**
'component: teamnumbersetter':
- changed-files:
- any-glob-to-any-file: roborioteamnumbersetter/**
'component: wpilibc':
- changed-files:
- any-glob-to-any-file: wpilibc/**
'component: wpilibj':
- changed-files:
- any-glob-to-any-file: wpilibj/**
'component: wpimath':
- changed-files:
- any-glob-to-any-file: wpimath/**
'component: wpinet':
- changed-files:
- any-glob-to-any-file: wpinet/**
'component: wpiunits':
- changed-files:
- any-glob-to-any-file: wpiunits/**
'component: wpiutil':
- changed-files:
- any-glob-to-any-file: wpiutil/**
"build":
- changed-files:
- any-glob-to-any-file:
[
.github/actions/**,
.github/workflows/**,
cmake/*,
shared/**,
upstream_utils/**,
"**/*.bzl",
"**/*.cmake",
"**/*.gradle",
"**/CMakeLists.txt",
"**/BUILD.bazel",
]
"component: apriltag":
- changed-files:
- any-glob-to-any-file: apriltag/**
"component: command-based":
- changed-files:
- any-glob-to-any-file: commandsv2/**
"component: commands v3":
- changed-files:
- any-glob-to-any-file: commandsv3/**
"component: cscore":
- changed-files:
- any-glob-to-any-file: cscore/**
"component: datalogtool":
- changed-files:
- any-glob-to-any-file: tools/datalogtool/**
"component: epilogue":
- changed-files:
- any-glob-to-any-file: epilogue-*/**
"component: examples":
- changed-files:
- any-glob-to-any-file: wpilib*Examples/**
"component: glass":
- changed-files:
- any-glob-to-any-file: glass/**
"component: hal":
- changed-files:
- any-glob-to-any-file: hal/**
"component: javac plugin":
- changed-files:
- any-glob-to-any-file: javacPlugin/**
"component: ntcore":
- changed-files:
- any-glob-to-any-file: ntcore/**
"component: outlineviewer":
- changed-files:
- any-glob-to-any-file: tools/outlineviewer/**
"component: romi":
- changed-files:
- any-glob-to-any-file: romiVendordep/**
"component: sysid":
- changed-files:
- any-glob-to-any-file: tools/sysid/**
"component: wpiannotations":
- changed-files:
- any-glob-to-any-file: wpiannotations/**
"component: wpilibc":
- changed-files:
- any-glob-to-any-file: wpilibc/**
"component: wpilibj":
- changed-files:
- any-glob-to-any-file: wpilibj/**
"component: wpimath":
- changed-files:
- any-glob-to-any-file: wpimath/**
"component: wpinet":
- changed-files:
- any-glob-to-any-file: wpinet/**
"component: wpiunits":
- changed-files:
- any-glob-to-any-file: wpiunits/**
"component: wpiutil":
- changed-files:
- any-glob-to-any-file: wpiutil/**
"component: wpical":
- changed-files:
- any-glob-to-any-file: tools/wpical/**
"component: xrp":
- changed-files:
- any-glob-to-any-file: xrpVendordep/**
"component: usage reporting":
- changed-files:
- any-glob-to-any-file: hal/src/generate/**
"os: simulation":
- changed-files:
- any-glob-to-any-file: "**/simulation/**"
"robotpy":
- changed-files:
- any-glob-to-any-file: "**python/**"
"type: testing":
- changed-files:
- any-glob-to-any-file: "**/test/**"

View File

@@ -3,7 +3,10 @@
{
"aql": {
"items.find": {
"repo": "wpilib-mvn-development",
"$or":[
{ "repo": "wpilib-mvn-development-local" },
{ "repo": "wpilib-mvn-development-2027-local" }
],
"path": { "$nmatch":"*edu/wpi/first/thirdparty*" },
"$or":[
{

View File

@@ -2,13 +2,15 @@ name: Artifactory Nightly Cleanup
on:
workflow_dispatch:
schedule:
- cron: '15 2 * * *'
jobs:
wpilib-mvn-development_unused_cleanup:
runs-on: ubuntu-latest
if: github.repository == 'wpilibsuite/allwpilib' && github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: jfrog/setup-jfrog-cli@v4
@@ -21,7 +23,7 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'wpilibsuite/allwpilib' && github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: jfrog/setup-jfrog-cli@v4

View File

@@ -7,78 +7,115 @@ concurrency:
cancel-in-progress: true
jobs:
build-windows:
build:
strategy:
fail-fast: false
matrix:
include:
- { name: "Windows (native)", os: windows-2022, action: "test", config: "--config=windows", }
- { name: "Windows (arm)", os: windows-2022, action: "build", config: "--config=windows_arm", }
- { name: "Linux System Core", classifier: "linuxsystemcore", os: ubuntu-24.04, container: wpilib/debian-base:trixie, action: "build" }
- { name: "Linux System Core Debug", classifier: "linuxsystemcoredebug", os: ubuntu-24.04, container: wpilib/debian-base:trixie, action: "build" }
- { name: "Linux System Core Static", classifier: "linuxsystemcorestatic", os: ubuntu-24.04, container: wpilib/debian-base:trixie, action: "build" }
- { name: "Linux System Core Static Debug", classifier: "linuxsystemcorestaticdebug", os: ubuntu-24.04, container: wpilib/debian-base:trixie, action: "build" }
- { name: "Linux x86-64", classifier: "linuxx86-64,headers,sources", os: ubuntu-24.04, container: wpilib/debian-base:trixie, action: "test" }
- { name: "Linux x86-64 Debug", classifier: "linuxx86-64debug", os: ubuntu-24.04, container: wpilib/debian-base:trixie, action: "test" }
- { name: "Linux x86-64 Static", classifier: "linuxx86-64static", os: ubuntu-24.04, container: wpilib/debian-base:trixie, action: "test" }
- { name: "Linux x86-64 Static Debug", classifier: "linuxx86-64staticdebug", os: ubuntu-24.04, container: wpilib/debian-base:trixie, action: "test" }
name: "Build ${{ matrix.name }}"
- { name: "macOS", classifier: "osxuniversal,osxuniversaldebug,headers,sources,osxuniversalstatic,osxuniversalstaticdebug,linuxsystemcore,linuxsystemcoredebug,linuxsystemcorestatic,linuxsystemcorestaticdebug", os: macOS-15, container: "", action: "test" }
- { name: "Windows x86-64", classifier: "windowsx86-64,windowsx86-64static,headers,sources", os: windows-2022, container: "", action: "test" }
- { name: "Windows x86-64 Debug", classifier: "windowsx86-64debug,windowsx86-64staticdebug", os: windows-2022, container: "", action: "test" }
- { name: "Windows ARM64", classifier: "windowsarm64,windowsarm64static", os: windows-2022, container: "", action: "build" }
- { name: "Windows ARM64 Debug", classifier: "windowsarm64debug,windowsarm64staticdebug", os: windows-2022, container: "", action: "build" }
- { name: "Windows System Core", classifier: "linuxsystemcore,linuxsystemcorestatic", os: windows-2022, container: "", action: "build" }
- { name: "Windows System Core Debug", classifier: "linuxsystemcoredebug,linuxsystemcorestaticdebug", os: windows-2022, container: "", action: "build" }
name: "${{ matrix.action == 'test' && 'Test' || 'Build' }} ${{ matrix.name }}"
runs-on: ${{ matrix.os }}
container: ${{ matrix.container }}
steps:
- uses: actions/checkout@v4
- name: Check disk free space pre-cleanup
run: df -h
- name: Free disk space (Linux)
if: runner.os == 'Linux'
uses: jlumbroso/free-disk-space@main
with:
tool-cache: false
android: true
dotnet: true
haskell: true
large-packages: false
docker-images: false
swap-storage: false
- name: Free disk space (macOS)
if: runner.os == 'macOS'
# CodeQL: 5G
# go: 748M
# Android: 12G
run: |
rm -rf /Users/runner/hostedtoolcache/CodeQL
rm -rf /Users/runner/hostedtoolcache/go
rm -rf /Users/runner/Library/Android
- name: Check disk free space post-cleanup
run: df -h
- uses: actions/checkout@v6
with: { fetch-depth: 0 }
- uses: actions/setup-java@v4
with:
distribution: 'zulu'
java-version: 17
architecture: x64
- id: Setup_build_buddy
uses: ./.github/actions/setup-build-buddy
- id: Setup_bazel_cache
uses: ./.github/actions/setup-bazel-cache
with:
token: ${{ secrets.BUILDBUDDY_API_KEY }}
bazel_remote_username: ${{ secrets.BAZEL_CACHE_USERNAME }}
bazel_remote_password: ${{ secrets.BAZEL_CACHE_PASSWORD }}
buildbuddy_token: ${{ secrets.BUILDBUDDY_API_KEY }}
- name: Build Release
run: bazel --output_user_root=C:\\bazelroot ${{ matrix.action }} -k ... --config=ci -c opt ${{ matrix.config }} --verbose_failures
- name: Install apt dependencies
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y libgl1-mesa-dev libx11-dev libxcursor-dev libxi-dev libxinerama-dev libxrandr-dev avahi-daemon
- name: Setup avahi-daemon
if: runner.os == 'Linux'
run: |
sudo service dbus start
sudo avahi-daemon -D
- if: runner.os == 'Linux'
uses: bazel-contrib/setup-bazel@0.15.0
with:
bazelisk-cache: true
repository-cache: true
bazelisk-version: 1.x
- name: bazel ${{ matrix.action }}
run: |
ACTION='${{ matrix.action }}'
if [ "${ACTION}" = "build" ]; then
TARGETS=:publish
else
TARGETS=...
fi
if [ "${{ runner.os }}" = "Windows" ]; then
bazel --output_user_root=C:\\bazelroot ${ACTION} ${TARGETS} --config=ci -c opt --repo_env=WPI_PUBLISH_CLASSIFIER_FILTER='${{ matrix.classifier }}'
else
bazel ${ACTION} ${TARGETS} --config=ci -c opt --repo_env=WPI_PUBLISH_CLASSIFIER_FILTER='${{ matrix.classifier }}'
fi
shell: bash
build-mac:
name: "Mac"
runs-on: macos-14
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- id: Setup_build_buddy
uses: ./.github/actions/setup-build-buddy
with:
token: ${{ secrets.BUILDBUDDY_API_KEY }}
- name: Build Release
run: bazel test -k ... --config=ci -c opt --config=macos --nojava_header_compilation --verbose_failures
shell: bash
build-linux:
strategy:
fail-fast: false
matrix:
include:
- { name: "Linux (native)", os: ubuntu-22.04, action: "test", config: "--config=linux", }
- { name: "Linux (roborio)", os: ubuntu-22.04, action: "build", config: "--config=roborio", }
name: "${{ matrix.name }}"
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: bazelbuild/setup-bazelisk@v3
- id: Setup_build_buddy
uses: ./.github/actions/setup-build-buddy
with:
token: ${{ secrets.BUILDBUDDY_API_KEY }}
- name: Build and Test Release
run: bazel ${{ matrix.action }} ... --config=ci -c opt ${{ matrix.config }} -k --verbose_failures
- name: Check disk free space
if: always()
run: df -h
buildifier:
name: "buildifier"
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- name: Set up Go 1.15.x
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
cache: false
go-version: 1.15.x
@@ -89,7 +126,7 @@ jobs:
cd $(mktemp -d)
GO111MODULE=on go get github.com/bazelbuild/buildtools/buildifier@6.0.0
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with: { fetch-depth: 0 }
- name: Run buildifier
@@ -99,11 +136,100 @@ jobs:
run: git --no-pager diff --exit-code HEAD
- name: Generate diff
run: git diff HEAD > bazel-lint-fixes.patch
run: git diff HEAD > ${{ matrix.platform }}-bazel-lint-fixes.patch
if: ${{ failure() }}
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: ${{ matrix.platform }}-bazel-lint-fixes
path: bazel-lint-fixes.patch
archive: false
path: "*-bazel-lint-fixes.patch"
if: ${{ failure() }}
mod-lock:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
- name: Check lockfile
run: bazel mod deps --lockfile_mode=error
- run: bazel mod deps --lockfile_mode=update
if: ${{ failure() }}
- name: Generate diff
run: git diff HEAD > bazel-mod-lock-fixes.patch
if: ${{ failure() }}
- uses: actions/upload-artifact@v7
with:
archive: false
path: "bazel-mod-lock-fixes.patch"
if: ${{ failure() }}
non_robotpy_pregeneration:
name: "Non-RobotPy Pregen"
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
with: { fetch-depth: 0 }
- id: Setup_bazel_cache
uses: ./.github/actions/setup-bazel-cache
with:
bazel_remote_username: ${{ secrets.BAZEL_CACHE_USERNAME }}
bazel_remote_password: ${{ secrets.BAZEL_CACHE_PASSWORD }}
buildbuddy_token: ${{ secrets.BUILDBUDDY_API_KEY }}
- name: Run Non-RobotPy pregeneration
run: bazel run --config=ci //:write_pregenerated_files
- name: Check Output
run: git --no-pager diff --exit-code HEAD
- name: Generate diff
run: git diff HEAD > non-robotpy-pregeneration.patch
if: ${{ failure() }}
- uses: actions/upload-artifact@v6
with:
name: non-robotpy-pregeneration-fixes
path: non-robotpy-pregeneration.patch
if: ${{ failure() }}
robotpy_pregeneration:
name: "Robotpy Pregeneration"
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v6
with: { fetch-depth: 0 }
- id: Setup_bazel_cache
uses: ./.github/actions/setup-bazel-cache
with:
bazel_remote_username: ${{ secrets.BAZEL_CACHE_USERNAME }}
bazel_remote_password: ${{ secrets.BAZEL_CACHE_PASSWORD }}
buildbuddy_token: ${{ secrets.BUILDBUDDY_API_KEY }}
# You should ensure the headers are correct before trying to pregen files
- name: Test Scan Headers
run: bazel test --config=ci //... -k --test_tag_filters=robotpy_scan_headers --build_tests_only
shell: bash
- name: Run yaml file generation
run: bazel run --config=ci //:write_robotpy_update_yaml_files
- name: Run build file generation
run: bazel run --config=ci //:write_robotpy_generated_pybind_files
- name: Check Output
run: git --no-pager diff --exit-code HEAD
- name: Generate diff
run: git diff HEAD > robotpy-pregeneration.patch
if: ${{ failure() }}
- uses: actions/upload-artifact@v6
with:
name: robotpy-pregeneration-fixes
path: robotpy-pregeneration.patch
if: ${{ failure() }}

View File

@@ -16,36 +16,37 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-22.04
- os: ubuntu-24.04
name: Android Arm64
abi: arm64-v8a
- os: ubuntu-22.04
- os: ubuntu-24.04
name: Android X64
abi: "x86_64"
name: "Build - ${{ matrix.name }}"
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- uses: nttld/setup-ndk@v1
id: setup-ndk
with:
ndk-version: r27c
ndk-version: r27d
add-to-path: false
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17
- name: Install sccache
uses: mozilla-actions/sccache-action@v0.0.5
uses: mozilla-actions/sccache-action@v0.0.9
- name: Install dependencies
run: sudo apt-get update && sudo apt-get install -y ninja-build
- name: configure
run: cmake --preset with-sccache -DCMAKE_BUILD_TYPE=RelWithDebInfo -DWITH_WPILIB=OFF -DWITH_GUI=OFF -DWITH_CSCORE=OFF -DWITH_TESTS=OFF -DWITH_SIMULATION_MODULES=OFF -DWITH_PROTOBUF=OFF -DWITH_JAVA=ON -DBUILD_SHARED_LIBS=ON -DCMAKE_TOOLCHAIN_FILE=${{ steps.setup-ndk.outputs.ndk-path }}/build/cmake/android.toolchain.cmake -DANDROID_ABI="${{ matrix.abi }}" -DANDROID_PLATFORM=android-24
run: cmake --preset with-sccache -DCMAKE_BUILD_TYPE=RelWithDebInfo -DWITH_WPILIB=OFF -DWITH_GUI=OFF -DWITH_CSCORE=OFF -DWITH_TESTS=OFF -DWITH_SIMULATION_MODULES=OFF -DBUILD_SHARED_LIBS=ON -DCMAKE_TOOLCHAIN_FILE=${{ steps.setup-ndk.outputs.ndk-path }}/build/cmake/android.toolchain.cmake -DANDROID_ABI="${{ matrix.abi }}" -DANDROID_PLATFORM=android-24
env:
SCCACHE_WEBDAV_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
SCCACHE_WEBDAV_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
- name: build
run: cmake --build build-cmake --parallel $(nproc)
env:
SCCACHE_WEBDAV_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
SCCACHE_WEBDAV_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}

View File

@@ -16,15 +16,14 @@ jobs:
fail-fast: false
matrix:
include:
- os: ubuntu-22.04
- os: ubuntu-24.04
name: Linux
container: wpilib/roborio-cross-ubuntu:2025-22.04
flags: "--preset with-java-and-sccache -DCMAKE_BUILD_TYPE=Release -DWITH_EXAMPLES=ON"
- os: macOS-14
container: wpilib/systemcore-cross-debian:trixie
flags: "--preset with-sccache -DCMAKE_BUILD_TYPE=Release -DWITH_EXAMPLES=ON"
- os: macOS-15
name: macOS
container: ""
env: "PATH=\"/opt/homebrew/opt/protobuf@3/bin:$PATH\""
flags: "--preset with-sccache -DCMAKE_BUILD_TYPE=Release -DWITH_EXAMPLES=ON -DCMAKE_LIBRARY_PATH=/opt/homebrew/opt/protobuf@3/lib -DProtobuf_INCLUDE_DIR=/opt/homebrew/opt/protobuf@3/include -DProtobuf_PROTOC_EXECUTABLE=/opt/homebrew/opt/protobuf@3/bin/protoc"
flags: "--preset with-sccache -DCMAKE_BUILD_TYPE=Release -DWITH_EXAMPLES=ON"
- os: windows-2022
name: Windows
container: ""
@@ -36,11 +35,17 @@ jobs:
steps:
- name: Install dependencies (Linux)
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y libopencv-dev libopencv4.5-java libprotobuf-dev protobuf-compiler ninja-build
run: sudo apt-get update && sudo apt-get install -y libopencv-dev ninja-build
- name: Setup avahi-daemon
if: runner.os == 'Linux'
run: |
sudo service dbus start
sudo avahi-daemon -D
- name: Install dependencies (macOS)
if: runner.os == 'macOS'
run: brew install opencv protobuf@3 ninja
run: brew install opencv ninja
- uses: ilammy/msvc-dev-cmd@v1.13.0
if: runner.os == 'Windows'
@@ -50,16 +55,16 @@ jobs:
uses: lukka/get-cmake@v3.29.3
- name: Install sccache
uses: mozilla-actions/sccache-action@v0.0.5
uses: mozilla-actions/sccache-action@v0.0.10
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Run vcpkg (Windows only)
if: runner.os == 'Windows'
uses: lukka/run-vcpkg@v11.5
with:
vcpkgDirectory: ${{ runner.workspace }}/vcpkg
vcpkgGitCommitId: 37c3e63a1306562f7f59c4c3c8892ddd50fdf992 # HEAD on 2024-02-24
vcpkgGitCommitId: 74e6536215718009aae747d86d84b78376bf9e09 # HEAD on 2025-10-17
- name: configure
run: cmake ${{ matrix.flags }}

View File

@@ -1,27 +0,0 @@
name: Comment on PR for robotpy
on:
pull_request_target:
types:
- opened
paths:
- 'wpilibNewCommands/src/**/*.java'
jobs:
comment:
permissions:
pull-requests: write
runs-on: ubuntu-latest
steps:
- name: Comment on PR
if: github.repository == 'wpilibsuite/allwpilib'
uses: actions/github-script@v7
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: 'This PR modifies commands. Please open a corresponding PR in [Python Commands](https://github.com/robotpy/robotpy-commands-v2/) and include a link to this PR.'
})

View File

@@ -1,67 +0,0 @@
name: Documentation
on: [push, workflow_dispatch]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
BASE_PATH: allwpilib/docs
jobs:
publish:
name: "Documentation - Publish"
runs-on: ubuntu-22.04
if: github.repository == 'wpilibsuite/allwpilib' && (github.ref == 'refs/heads/main' || (startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '2027')))
concurrency: ci-docs-publish
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- uses: gradle/actions/wrapper-validation@v4
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17
- name: Set environment variables (Development)
run: |
echo "BRANCH=development" >> $GITHUB_ENV
if: github.ref == 'refs/heads/main'
- name: Set environment variables (Tag)
run: |
echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
echo "BRANCH=beta" >> $GITHUB_ENV
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '2027')
- name: Set environment variables (Release)
run: |
echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
echo "BRANCH=release" >> $GITHUB_ENV
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, 'alpha') && !contains(github.ref, 'beta') && !contains(github.ref, '2027')
- name: Build with Gradle
run: ./gradlew docs:generateJavaDocs docs:doxygen -PbuildServer ${{ env.EXTRA_GRADLE_ARGS }}
- name: Install SSH Client 🔑
uses: webfactory/ssh-agent@v0.9.0
with:
ssh-private-key: ${{ secrets.GH_DEPLOY_KEY }}
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@v4.6.1
with:
ssh-key: true
repository-name: wpilibsuite/wpilibsuite.github.io
branch: allwpilib-${{ env.BRANCH }}
clean: true
single-commit: true
folder: docs/build/docs
- name: Trigger Workflow
uses: actions/github-script@v7
with:
github-token: ${{ secrets.DISPATCH_PAT_TOKEN }}
script: |
github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: 'wpilibsuite.github.io',
workflow_id: 'static.yml',
ref: 'main',
})

View File

@@ -31,6 +31,9 @@ def main():
# Replace GCC warning argument with one Clang recognizes
elif arg == "-Wno-maybe-uninitialized":
out_args.append("-Wno-uninitialized")
# Skip GCC-specific warning argument
elif arg == "-Wno-error=restrict":
pass
else:
out_args.append(arg)

View File

@@ -11,31 +11,31 @@ jobs:
name: "Validation"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: gradle/actions/wrapper-validation@v4
- uses: actions/checkout@v6
- uses: gradle/actions/wrapper-validation@v5
build-docker:
strategy:
fail-fast: false
matrix:
include:
- container: wpilib/roborio-cross-ubuntu:2025-22.04
artifact-name: Athena
build-options: "-Ponlylinuxathena"
- container: wpilib/raspbian-cross-ubuntu:bookworm-22.04
artifact-name: Arm32
build-options: "-Ponlylinuxarm32"
- container: wpilib/aarch64-cross-ubuntu:bookworm-22.04
- container: wpilib/systemcore-cross-debian:trixie
artifact-name: Systemcore
build-options: "-Ponlylinuxsystemcore"
- container: wpilib/aarch64-cross-debian:trixie
artifact-name: Arm64
build-options: "-Ponlylinuxarm64"
- container: wpilib/ubuntu-base:22.04
- container: wpilib/systemcore-cross-debian:trixie
artifact-name: Linux
build-options: "-Ponlylinuxx86-64"
name: "Build - ${{ matrix.artifact-name }}"
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
needs: [validation]
steps:
- name: Free Disk Space
- name: Check disk free space pre-cleanup
run: df -h
- name: Free disk space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: false
@@ -45,28 +45,38 @@ jobs:
large-packages: false
docker-images: false
swap-storage: false
- uses: actions/checkout@v4
- name: Check disk free space post-cleanup
run: df -h
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set release environment variable
run: echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '2027')
if: startsWith(github.ref, 'refs/tags/v')
- name: Build with Gradle
uses: addnab/docker-run-action@v3
uses: wpilibsuite/docker-run-action@v4
with:
image: ${{ matrix.container }}
options: -v ${{ github.workspace }}:/work -w /work -e ARTIFACTORY_PUBLISH_USERNAME -e ARTIFACTORY_PUBLISH_PASSWORD -e GITHUB_REF -e CI
run: df . && rm -f semicolon_delimited_script && echo $GITHUB_REF && ./gradlew build --build-cache -PbuildServer -PskipJavaFormat ${{ matrix.build-options }} ${{ env.EXTRA_GRADLE_ARGS }}
# Start avahi-daemon and build
run: |
service dbus start
avahi-daemon -D
./gradlew build --build-cache -PbuildServer -PskipJavaFormat ${{ matrix.build-options }} ${{ env.EXTRA_GRADLE_ARGS }}
env:
ARTIFACTORY_PUBLISH_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
ARTIFACTORY_PUBLISH_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
- name: Check free disk space
run: df .
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: ${{ matrix.artifact-name }}
path: build/allOutputs
- name: Check disk free space
if: always()
run: df -h
build-host:
env:
MACOSX_DEPLOYMENT_TARGET: 13.3
@@ -98,17 +108,11 @@ jobs:
build-options: "-PciReleaseOnly -Pbuildwinarm64 -Ponlywindowsarm64"
task: "copyAllOutputs"
outputs: "build/allOutputs"
- os: macOS-14
- os: macOS-15
artifact-name: macOS
architecture: aarch64
task: "build"
outputs: "build/allOutputs"
- os: windows-2022
artifact-name: Win32FFI
architecture: x86
task: ":ntcoreffi:build"
build-options: "-Pntcoreffibuild \"-Dorg.gradle.jvmargs=-Xmx1096m\""
outputs: "ntcoreffi/build/outputs"
- os: windows-2022
artifact-name: Win64FFI
architecture: x64
@@ -119,42 +123,11 @@ jobs:
runs-on: ${{ matrix.os }}
needs: [validation]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 17
architecture: ${{ matrix.architecture }}
- name: Import Developer ID Certificate
uses: wpilibsuite/import-signing-certificate@v2
with:
certificate-data: ${{ secrets.APPLE_CERTIFICATE_DATA }}
certificate-passphrase: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
keychain-password: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }}
if: |
matrix.artifact-name == 'macOS' && (github.repository == 'wpilibsuite/allwpilib' &&
(github.ref == 'refs/heads/main' || (startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '2027'))))
- name: Set Keychain Lock Timeout
run: security set-keychain-settings -lut 21600
if: |
matrix.artifact-name == 'macOS' && (github.repository == 'wpilibsuite/allwpilib' &&
(github.ref == 'refs/heads/main' || (startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '2027'))))
- name: Set release environment variable
run: echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
shell: bash
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '2027')
- name: Set Java Heap Size
run: sed -i 's/-Xmx2g/-Xmx1g/g' gradle.properties
if: matrix.artifact-name == 'Win32'
- name: Check disk free space (Windows)
run: wmic logicaldisk get caption, freespace
if: matrix.os == 'windows-2022'
- name: Check disk free space pre-cleanup (macOS)
run: df -h .
if: matrix.os == 'macOS-14'
- name: Cleanup disk space
- name: Check disk free space pre-cleanup
run: df -h
- name: Free disk space (macOS)
if: runner.os == 'macOS'
# CodeQL: 5G
# go: 748M
# Android: 12G
@@ -162,10 +135,36 @@ jobs:
rm -rf /Users/runner/hostedtoolcache/CodeQL
rm -rf /Users/runner/hostedtoolcache/go
rm -rf /Users/runner/Library/Android
if: matrix.os == 'macOS-14'
- name: Check disk free space post-cleanup (macOS)
run: df -h .
if: matrix.os == 'macOS-14'
- name: Check disk free space post-cleanup
run: df -h
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: 25
architecture: ${{ matrix.architecture }}
- name: Import Developer ID Certificate
uses: wpilibsuite/import-signing-certificate@v3
with:
certificate-data: ${{ secrets.APPLE_CERTIFICATE_DATA }}
certificate-passphrase: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
keychain-password: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }}
if: |
matrix.artifact-name == 'macOS' && (github.repository == 'wpilibsuite/allwpilib' &&
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')))
- name: Set Keychain Lock Timeout
run: security set-keychain-settings -lut 21600
if: |
matrix.artifact-name == 'macOS' && (github.repository == 'wpilibsuite/allwpilib' &&
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')))
- name: Set release environment variable
run: echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
shell: bash
if: startsWith(github.ref, 'refs/tags/v')
- name: Build with Gradle
run: ./gradlew ${{ matrix.task }} --build-cache -PbuildServer -PskipJavaFormat ${{ matrix.build-options }} ${{ env.EXTRA_GRADLE_ARGS }}
env:
@@ -175,52 +174,112 @@ jobs:
run: ./gradlew copyAllOutputs --build-cache -PbuildServer -PskipJavaFormat -PdeveloperID=${{ secrets.APPLE_DEVELOPER_ID }} ${{ matrix.build-options }} ${{ env.EXTRA_GRADLE_ARGS }}
if: |
matrix.artifact-name == 'macOS' && (github.repository == 'wpilibsuite/allwpilib' &&
(github.ref == 'refs/heads/main' || (startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '2027'))))
- name: Check disk free space (Windows)
run: wmic logicaldisk get caption, freespace
if: matrix.os == 'windows-2022'
- name: Check disk free space (macOS)
run: df -h .
if: matrix.os == 'macOS-14'
- uses: actions/upload-artifact@v4
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')))
- uses: actions/upload-artifact@v7
with:
name: ${{ matrix.artifact-name }}
path: ${{ matrix.outputs }}
- name: Check disk free space
if: always()
run: df -h
build-documentation:
name: "Build - Documentation"
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
needs: [validation]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: actions/setup-java@v4
- uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: 17
java-version: 25
- name: Set release environment variable
run: echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '2027')
if: startsWith(github.ref, 'refs/tags/v')
- name: Build with Gradle
run: ./gradlew docs:zipDocs --build-cache -PbuildServer ${{ env.EXTRA_GRADLE_ARGS }}
run: ./gradlew docs:zipDocs --build-cache -PbuildServer -PdocWarningsAsErrors ${{ env.EXTRA_GRADLE_ARGS }}
env:
ARTIFACTORY_PUBLISH_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
ARTIFACTORY_PUBLISH_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: Documentation
path: docs/build/outputs
publish:
name: "Documentation - Publish"
runs-on: ubuntu-22.04
if: github.repository == 'wpilibsuite/allwpilib' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
needs: [build-documentation]
concurrency: ci-docs-publish
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 0
persist-credentials: false
- name: Download docs artifacts
uses: actions/download-artifact@v7
with:
name: Documentation
- name: Make output directories
run: |
mkdir -p docs/tmp/doxygen/html
mkdir -p docs/tmp/javadoc
- name: Extract docs
run: |
unzip _GROUP_org_wpilib_wpilibc_ID_documentation_CLS.zip -d docs/tmp/doxygen/html
unzip _GROUP_org_wpilib_wpilibj_ID_documentation_CLS.zip -d docs/tmp/javadoc
- name: Set environment variables (Development)
run: |
echo "BRANCH=development" >> $GITHUB_ENV
if: github.ref == 'refs/heads/main'
- name: Set environment variables (Tag)
run: |
echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
echo "BRANCH=beta" >> $GITHUB_ENV
if: startsWith(github.ref, 'refs/tags/v')
- name: Set environment variables (Release)
run: |
echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
echo "BRANCH=release" >> $GITHUB_ENV
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, 'alpha') && !contains(github.ref, 'beta')
- name: Install SSH Client 🔑
uses: webfactory/ssh-agent@v0.9.1
with:
ssh-private-key: ${{ secrets.GH_DEPLOY_KEY }}
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@v4.6.1
with:
ssh-key: true
repository-name: wpilibsuite/wpilibsuite.github.io
branch: allwpilib-${{ env.BRANCH }}
clean: true
single-commit: true
folder: docs/tmp
- name: Trigger Workflow
uses: actions/github-script@v8
with:
github-token: ${{ secrets.DISPATCH_PAT_TOKEN }}
script: |
github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: 'wpilibsuite.github.io',
workflow_id: 'static.yml',
ref: 'main',
})
combine:
name: Combine
needs: [build-docker, build-host, build-documentation]
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- name: Free Disk Space
- name: Free disk space
if: |
github.repository == 'wpilibsuite/allwpilib' &&
(github.ref == 'refs/heads/main' || (startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '2027')))
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
uses: jlumbroso/free-disk-space@main
with:
tool-cache: false
@@ -230,42 +289,43 @@ jobs:
large-packages: false
docker-images: false
swap-storage: false
- uses: actions/checkout@v4
- uses: actions/checkout@v6
if: |
github.repository == 'wpilibsuite/allwpilib' &&
(github.ref == 'refs/heads/main' || (startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '2027')))
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
with:
repository: wpilibsuite/build-tools
- uses: actions/download-artifact@v4
- uses: actions/download-artifact@v7
if: |
github.repository == 'wpilibsuite/allwpilib' &&
(github.ref == 'refs/heads/main' || (startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '2027')))
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
with:
path: combiner/products/build/allOutputs
- name: Flatten Artifacts
if: |
github.repository == 'wpilibsuite/allwpilib' &&
(github.ref == 'refs/heads/main' || (startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '2027')))
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
run: rsync -a --delete combiner/products/build/allOutputs/*/* combiner/products/build/allOutputs/
- name: Check version number exists
if: |
github.repository == 'wpilibsuite/allwpilib' &&
(github.ref == 'refs/heads/main' || (startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '2027')))
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
run: |
cat combiner/products/build/allOutputs/version.txt
test -s combiner/products/build/allOutputs/version.txt
- uses: actions/setup-java@v4
- uses: actions/setup-java@v5
if: |
github.repository == 'wpilibsuite/allwpilib' &&
(github.ref == 'refs/heads/main' || (startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '2027')))
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
with:
distribution: 'temurin'
java-version: 17
- name: Combine (Main)
java-version: 25
- name: Combine
if: |
github.repository == 'wpilibsuite/allwpilib' &&
github.ref == 'refs/heads/main'
run: cd combiner && ./gradlew publish -Pallwpilib
run: cd combiner && ./gradlew publish -Pallwpilib -Pbuild2027
env:
RUN_AZURE_ARTIFACTORY_RELEASE: "TRUE"
ARTIFACTORY_PUBLISH_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
@@ -273,34 +333,16 @@ jobs:
- name: Combine (Release)
if: |
github.repository == 'wpilibsuite/allwpilib' &&
startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '2027')
run: cd combiner && ./gradlew publish -Pallwpilib -PreleaseRepoPublish
startsWith(github.ref, 'refs/tags/v')
run: cd combiner && ./gradlew publish -Pallwpilib -PreleaseRepoPublish -Pbuild2027
env:
RUN_AZURE_ARTIFACTORY_RELEASE: "TRUE"
ARTIFACTORY_PUBLISH_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
ARTIFACTORY_PUBLISH_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
if: |
github.repository == 'wpilibsuite/allwpilib' &&
(github.ref == 'refs/heads/main' || (startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '2027')))
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
with:
name: Maven
path: ~/releases
dispatch:
name: dispatch
needs: [combine]
strategy:
matrix:
repo: ['SmartDashboard', 'PathWeaver', 'Shuffleboard', 'RobotBuilder']
runs-on: ubuntu-22.04
steps:
- uses: peter-evans/repository-dispatch@v3
if: |
github.repository == 'wpilibsuite/allwpilib' &&
startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '2027')
with:
token: ${{ secrets.TOOL_REPO_ACCESS_TOKEN }}
repository: wpilibsuite/${{ matrix.repo }}
event-type: tag
client-payload: '{"package_name": "allwpilib", "package_version": "${{ github.ref_name }}"}'

View File

@@ -1,6 +1,6 @@
name: "Pull Request Labeler"
on:
- pull_request_target
- pull_request_target
jobs:
labeler:
@@ -9,4 +9,6 @@ jobs:
pull-requests: write
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v5
- uses: actions/labeler@v6
with:
sync-labels: true

View File

@@ -15,14 +15,14 @@ jobs:
name: "Validation"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: gradle/actions/wrapper-validation@v4
- uses: actions/checkout@v6
- uses: gradle/actions/wrapper-validation@v5
wpiformat:
name: "wpiformat"
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Fetch all history and metadata
@@ -30,13 +30,13 @@ jobs:
git checkout -b pr
git branch -f main origin/main
- name: Set up Python 3.12
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.12'
- name: Install wpiformat
run: |
python -m venv ${{ runner.temp }}/wpiformat
${{ runner.temp }}/wpiformat/bin/pip3 install wpiformat==2024.51
${{ runner.temp }}/wpiformat/bin/pip3 install wpiformat==2026.57
- name: Run
run: ${{ runner.temp }}/wpiformat/bin/wpiformat
- name: Check output
@@ -44,9 +44,9 @@ jobs:
- name: Generate diff
run: git diff HEAD > wpiformat-fixes.patch
if: ${{ failure() }}
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: wpiformat fixes
archive: false
path: wpiformat-fixes.patch
if: ${{ failure() }}
- name: Write to job summary
@@ -59,11 +59,11 @@ jobs:
tidy:
name: "clang-tidy"
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
needs: [validation]
container: wpilib/ubuntu-base:22.04
container: wpilib/debian-base:trixie
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Fetch all history and metadata
@@ -72,13 +72,13 @@ jobs:
git checkout -b pr
git branch -f main origin/main
- name: Set up Python 3.12
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.12'
- name: Install wpiformat
run: |
python -m venv ${{ runner.temp }}/wpiformat
${{ runner.temp }}/wpiformat/bin/pip3 install wpiformat==2024.51
${{ runner.temp }}/wpiformat/bin/pip3 install wpiformat==2026.57
- name: Create compile_commands.json
run: |
./gradlew generateCompileCommands -Ptoolchain-optional-roboRio
@@ -87,16 +87,16 @@ jobs:
- name: List changed files
run: ${{ runner.temp }}/wpiformat/bin/wpiformat -list-changed-files
- name: Run clang-tidy release
run: ${{ runner.temp }}/wpiformat/bin/wpiformat -no-format -tidy-changed -compile-commands=build/TargetedCompileCommands/linuxx86-64release -vv
run: ${{ runner.temp }}/wpiformat/bin/wpiformat -no-format -tidy-changed -compile-commands=build/TargetedCompileCommands/linuxx86-64release
- name: Run clang-tidy debug
run: ${{ runner.temp }}/wpiformat/bin/wpiformat -no-format -tidy-changed -compile-commands=build/TargetedCompileCommands/linuxx86-64debug -vv
run: ${{ runner.temp }}/wpiformat/bin/wpiformat -no-format -tidy-changed -compile-commands=build/TargetedCompileCommands/linuxx86-64debug
javaformat:
name: "Java format"
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
needs: [validation]
container: wpilib/ubuntu-base:22.04
container: wpilib/debian-base:trixie
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Fetch all history and metadata
@@ -111,9 +111,9 @@ jobs:
- name: Generate diff
run: git diff HEAD > javaformat-fixes.patch
if: ${{ failure() }}
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: javaformat fixes
archive: false
path: javaformat-fixes.patch
if: ${{ failure() }}
- name: Write to job summary
@@ -124,17 +124,26 @@ jobs:
echo '```' >> $GITHUB_STEP_SUMMARY
if: ${{ failure() }}
documentation:
name: "Documentation"
runs-on: ubuntu-22.04
needs: [validation]
check-spelling:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: misspell
uses: reviewdog/action-misspell@v1
with:
fetch-depth: 0
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: 21
- name: Build with Gradle
run: ./gradlew docs:zipDocs -PbuildServer -PdocWarningsAsErrors ${{ env.EXTRA_GRADLE_ARGS }}
reporter: "github-check"
fail_level: "error"
exclude: |
**/*.svg
**/thirdparty/**
**/upstream_utils/**
**/generated/**
./wpigui/src/main/native/cpp/portable-file-dialogs.*
./wpimath/src/main/native/include/wpi/units/base.hpp
./wpinet/src/main/native/linux/AvahiClient.*
./wpinet/src/main/native/cpp/http_parser.cpp
./wpinet/src/main/native/include/wpi/net/http_parser.hpp
./wpiutil/src/main/native/include/wpi/util/FastQueue.hpp
./wpiutil/src/test/native/cpp/json/**
./wpiutil/src/test/native/cpp/llvm/**
./wpiutil/src/test/native/cpp/span/**

View File

@@ -13,9 +13,9 @@ concurrency:
jobs:
update:
name: "Update"
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Run pregen
@@ -27,8 +27,8 @@ jobs:
- name: Generate diff
run: git diff HEAD > pregenerated-files-fixes.patch
if: ${{ failure() }}
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: pregenerated-files-fixes
archive: false
path: pregenerated-files-fixes.patch
if: ${{ failure() }}

View File

@@ -19,33 +19,38 @@ jobs:
- name: asan
cmake-flags: "-DCMAKE_BUILD_TYPE=Asan"
ctest-env: ""
ctest-flags: "-E 'wpilibc'"
ctest-flags: ""
- name: tsan
cmake-flags: "-DCMAKE_BUILD_TYPE=Tsan"
ctest-env: "TSAN_OPTIONS=second_deadlock_stack=1"
ctest-flags: "-E 'cscore|cameraserver|wpilibc|wpilibNewCommands'"
ctest-env: "TSAN_OPTIONS=second_deadlock_stack=1:suppressions=$GITHUB_WORKSPACE/tsan_suppressions.txt"
ctest-flags: "-E 'cscore|cameraserver'"
- name: ubsan
cmake-flags: "-DCMAKE_BUILD_TYPE=Ubsan"
ctest-env: ""
ctest-flags: ""
name: "${{ matrix.name }}"
runs-on: ubuntu-22.04
container: wpilib/roborio-cross-ubuntu:2025-22.04
runs-on: ubuntu-24.04
container: wpilib/debian-base:trixie
steps:
- name: Install Dependencies
run: sudo apt-get update && sudo apt-get install -y libopencv-dev libopencv4.5-java clang-14 libprotobuf-dev protobuf-compiler ninja-build
run: sudo apt-get update && sudo apt-get install -y libopencv-dev clang-18 ninja-build avahi-daemon
- name: Install sccache
uses: mozilla-actions/sccache-action@v0.0.5
uses: mozilla-actions/sccache-action@v0.0.10
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: configure
run: mkdir build && cd build && cmake -G Ninja -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/clang-14 -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/clang++-14 -DWITH_JAVA=OFF ${{ matrix.cmake-flags }} ..
run: mkdir build && cd build && cmake -G Ninja -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/clang-18 -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/clang++-18 ${{ matrix.cmake-flags }} ..
env:
SCCACHE_WEBDAV_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
SCCACHE_WEBDAV_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
- name: Setup avahi-daemon
run: |
sudo service dbus start
sudo avahi-daemon -D
- name: build
working-directory: build
run: cmake --build . --parallel $(nproc)

View File

@@ -14,8 +14,8 @@ jobs:
name: "Validation"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: gradle/actions/wrapper-validation@v4
- uses: actions/checkout@v6
- uses: gradle/actions/wrapper-validation@v5
build-docker:
if: (github.repository_owner == 'wpilibsuite' && github.ref == 'refs/heads/main') || github.event_name != 'schedule'
@@ -23,20 +23,17 @@ jobs:
fail-fast: false
matrix:
include:
- container: wpilib/roborio-cross-ubuntu:2025-22.04
artifact-name: Athena
build-options: "-Ponlylinuxathena"
- container: wpilib/raspbian-cross-ubuntu:bookworm-22.04
artifact-name: Arm32
build-options: "-Ponlylinuxarm32"
- container: wpilib/aarch64-cross-ubuntu:bookworm-22.04
- container: wpilib/systemcore-cross-debian:trixie
artifact-name: Systemcore
build-options: "-Ponlylinuxsystemcore"
- container: wpilib/aarch64-cross-debian:trixie
artifact-name: Arm64
build-options: "-Ponlylinuxarm64"
- container: wpilib/ubuntu-base:22.04
- container: wpilib/systemcore-cross-debian:trixie
artifact-name: Linux
build-options: "-Ponlylinuxx86-64"
name: "Build - ${{ matrix.artifact-name }}"
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
needs: [validation]
steps:
- name: Free Disk Space
@@ -49,18 +46,22 @@ jobs:
large-packages: false
docker-images: false
swap-storage: false
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Build with Gradle
uses: addnab/docker-run-action@v3
uses: wpilibsuite/docker-run-action@v4
with:
image: ${{ matrix.container }}
options: -v ${{ github.workspace }}:/work -w /work -e GITHUB_REF -e CI
run: df . && rm -f semicolon_delimited_script && echo $GITHUB_REF && ./gradlew build -PbuildServer -PskipJavaFormat ${{ matrix.build-options }}
# Start avahi-daemon and build
run: |
service dbus start
avahi-daemon -D
./gradlew build -PbuildServer -PskipJavaFormat ${{ matrix.build-options }}
- name: Check free disk space
run: df .
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: ${{ matrix.artifact-name }}
path: build/allOutputs
@@ -97,30 +98,31 @@ jobs:
build-options: "-PciReleaseOnly -Pbuildwinarm64 -Ponlywindowsarm64"
task: "copyAllOutputs"
outputs: "build/allOutputs"
- os: macOS-14
- os: macOS-15
artifact-name: macOS
architecture: aarch64
task: "build"
outputs: "build/allOutputs"
- os: windows-2022
artifact-name: Win32
architecture: x86
artifact-name: Win64FFI
architecture: x64
task: ":ntcoreffi:build"
build-options: "-Pntcoreffibuild -Pbuildwinarm64"
outputs: "ntcoreffi/build/outputs"
name: "Build - ${{ matrix.artifact-name }}"
runs-on: ${{ matrix.os }}
needs: [validation]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: actions/setup-java@v4
- uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: 17
java-version: 25
architecture: ${{ matrix.architecture }}
- name: Import Developer ID Certificate
uses: wpilibsuite/import-signing-certificate@v2
uses: wpilibsuite/import-signing-certificate@v3
with:
certificate-data: ${{ secrets.APPLE_CERTIFICATE_DATA }}
certificate-passphrase: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
@@ -131,16 +133,14 @@ jobs:
run: security set-keychain-settings -lut 21600
if: |
matrix.artifact-name == 'macOS' && (github.repository_owner == 'wpilibsuite' && github.ref == 'refs/heads/main')
- name: Set Java Heap Size
run: sed -i 's/-Xmx2g/-Xmx1g/g' gradle.properties
if: matrix.artifact-name == 'Win32'
- name: Check disk free space (Windows)
if: runner.os == 'Windows'
run: wmic logicaldisk get caption, freespace
if: matrix.os == 'windows-2022'
- name: Check disk free space pre-cleanup (macOS)
if: runner.os == 'macOS'
run: df -h .
if: matrix.os == 'macOS-14'
- name: Cleanup disk space
if: runner.os == 'macOS'
# CodeQL: 5G
# go: 748M
# Android: 12G
@@ -148,10 +148,9 @@ jobs:
rm -rf /Users/runner/hostedtoolcache/CodeQL
rm -rf /Users/runner/hostedtoolcache/go
rm -rf /Users/runner/Library/Android
if: matrix.os == 'macOS-14'
- name: Check disk free space post-cleanup (macOS)
if: runner.os == 'macOS'
run: df -h .
if: matrix.os == 'macOS-14'
- name: Build with Gradle
run: ./gradlew ${{ matrix.task }} -PbuildServer -PskipJavaFormat ${{ matrix.build-options }}
- name: Sign Libraries with Developer ID
@@ -159,12 +158,12 @@ jobs:
if: |
matrix.artifact-name == 'macOS' && (github.repository_owner == 'wpilibsuite' && github.ref == 'refs/heads/main')
- name: Check disk free space (Windows)
if: runner.os == 'Windows'
run: wmic logicaldisk get caption, freespace
if: matrix.os == 'windows-2022'
- name: Check disk free space (macOS)
if: runner.os == 'macOS'
run: df -h .
if: matrix.os == 'macOS-14'
- uses: actions/upload-artifact@v4
- uses: actions/upload-artifact@v7
with:
name: ${{ matrix.artifact-name }}
path: ${{ matrix.outputs }}

View File

@@ -1,206 +0,0 @@
name: Tools
on: [pull_request, push]
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
env:
YEAR: 2025
jobs:
build-artifacts:
name: "Build - WPILib"
runs-on: ubuntu-22.04
env:
DISPLAY: ':10'
steps:
- name: Free Disk Space
uses: jlumbroso/free-disk-space@main
with:
tool-cache: false
android: true
dotnet: true
haskell: true
large-packages: false
docker-images: false
swap-storage: false
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: gradle/actions/wrapper-validation@v4
- name: Build WPILib with Gradle
uses: addnab/docker-run-action@v3
with:
image: wpilib/roborio-cross-ubuntu:2025-22.04
options: -v ${{ github.workspace }}:/work -w /work -e GITHUB_REF -e CI -e DISPLAY
run: df . && rm -f semicolon_delimited_script && ./gradlew :wpilibc:publish :wpilibj:publish :wpilibNewCommands:publish :hal:publish :cameraserver:publish :ntcore:publish :cscore:publish :wpimath:publish :wpinet:publish :wpiutil:publish :apriltag:publish :wpiunits:publish :simulation:halsim_gui:publish :simulation:halsim_ds_socket:publish :simulation:halsim_ws_server:publish :simulation:halsim_ws_client:publish :simulation:halsim_xrp:publish :fieldImages:publish :romiVendordep:publish :xrpVendordep:publish :epilogue-processor:publish :epilogue-runtime:publish :thirdparty:googletest:publish -x test -x Javadoc -x doxygen --build-cache && cp -r /root/releases/maven/development /work
- uses: actions/upload-artifact@v4
with:
name: MavenArtifacts
path: |
development
retention-days: 1
Robotbuilder:
name: "Build - RobotBuilder"
needs: [build-artifacts]
runs-on: ubuntu-22.04
env:
DISPLAY: ':10'
steps:
- uses: actions/checkout@v4
with:
repository: wpilibsuite/robotbuilder
fetch-depth: 0
- uses: actions/download-artifact@v4
with:
name: MavenArtifacts
- name: Patch RobotBuilder to use local development
run: cd src/main/resources/export && echo "wpi.maven.useLocal = false" >> java/build.gradle && echo "wpi.maven.useFrcMavenLocalDevelopment = true" >> java/build.gradle && echo "wpi.versions.wpilibVersion = '$YEAR.424242.+'" >> java/build.gradle && echo "wpi.versions.wpimathVersion = '$YEAR.424242.+'" >> java/build.gradle && echo "wpi.maven.useLocal = false" >> cpp/build.gradle && echo "wpi.maven.useFrcMavenLocalDevelopment = true" >> cpp/build.gradle && echo "wpi.versions.wpilibVersion = '$YEAR.424242.+'" >> cpp/build.gradle && echo "wpi.versions.wpimathVersion = '$YEAR.424242.+'" >> cpp/build.gradle
- name: Install and run xvfb
run: sudo apt-get update && sudo apt-get install -y xvfb && Xvfb $DISPLAY &
- name: Move artifacts
run: mkdir -p ~/releases/maven/development && cp -r edu ~/releases/maven/development
- uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'temurin'
- name: Build RobotBuilder with Gradle
run: ./gradlew build test --tests 'robotbuilder.exporters.*' -x htmlSanityCheck -PbuildServer -PreleaseMode ; cat build/test-results/test/TEST-robotbuilder.exporters.*.xml ;
- name: Summarize RobotBuilder Test Results
uses: EnricoMi/publish-unit-test-result-action@v2
if: always()
with:
files: |
build/test-results/test/TEST*.xml
check_run: false
comment_mode: off
- uses: actions/upload-artifact@v4
if: always()
with:
name: RobotBuilderTestResults
path: |
build/reports/
- uses: actions/upload-artifact@v4
with:
name: RobotBuilder Build
path: |
build/libs/
retention-days: 7
Shuffleboard:
name: "Build - Shuffleboard"
needs: [build-artifacts]
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
repository: wpilibsuite/shuffleboard
fetch-depth: 0
- name: Patch Shuffleboard to use local development
run: sed -i "s/wpilibTools.deps.wpilibVersion.*/wpilibTools.deps.wpilibVersion = \'$YEAR\.424242\.+\'/" app/app.gradle && sed -i "s/wpilibTools.deps.wpilibVersion.*/wpilibTools.deps.wpilibVersion = \'$YEAR\.424242\.+\'/" plugins/cameraserver/cameraserver.gradle && sed -i "s/wpilibTools.deps.wpilibVersion.*/wpilibTools.deps.wpilibVersion = \'$YEAR\.424242\.+\'/" plugins/networktables/networktables.gradle
- uses: actions/download-artifact@v4
with:
name: MavenArtifacts
- uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'temurin'
- name: Move artifacts
run: mkdir -p ~/releases/maven/development && cp -r edu ~/releases/maven/development
- name: Install dependencies
run: sudo apt-get install -y libgtk2.0-0
- name: Build with Gradle
run: ./gradlew build -x Javadoc
- uses: actions/upload-artifact@v4
with:
name: Shuffleboard Build
path: |
build/allOutputs/
retention-days: 7
PathWeaver:
name: "Build - PathWeaver"
needs: [build-artifacts]
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
repository: wpilibsuite/PathWeaver
fetch-depth: 0
- name: Patch PathWeaver to use local development
run: sed -i "s/wpilibTools.deps.wpilibVersion.*/wpilibTools.deps.wpilibVersion = \'$YEAR\.424242\.+\'/" dependencies.gradle
- uses: actions/download-artifact@v4
with:
name: MavenArtifacts
- uses: actions/setup-java@v4
with:
java-version: 17
distribution: 'temurin'
- name: Move artifacts
run: mkdir -p ~/releases/maven/development && cp -r edu ~/releases/maven/development
- name: Build with Gradle
run: ./gradlew build
- uses: actions/upload-artifact@v4
with:
name: PathWeaver Build
path: |
build/allOutputs/
retention-days: 7
Robotpy:
name: "Build - Robotpy"
needs: [build-artifacts]
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
repository: robotpy/mostrobotpy
fetch-depth: 0
- uses: actions/download-artifact@v4
with:
name: MavenArtifacts
- name: Move artifacts
run: mkdir -p ~/releases/maven/development && cp -r edu ~/releases/maven/development
- uses: actions/setup-python@v5
with:
python-version: 3.13
#
# Setup build caching
#
- name: Set ccache size
shell: bash
id: ccache
run: echo "MAX_SIZE=500M" >> $GITHUB_OUTPUT
- name: Setup ccache
# uses: hendrikmuhs/ccache-action@v1.2.10
uses: robotpy/ccache-action@fork
with:
key: ubuntu-22.04-3.13
variant: ccache
max-size: ${{ steps.ccache.outputs.max_size }}
- name: Install deps
shell: bash
run: |
python -m pip --disable-pip-version-check install -r rdev_requirements.txt
- name: Install numpy (needed for stubgen but broken in raspbian CI)
shell: bash
run: |
python -m pip --disable-pip-version-check install numpy
- name: Patch RobotPy rdev to use local development
run: git config user.name github-actions && git config user.email github-actions@github.com && set -- ~/releases/maven/development/edu/wpi/first/wpiutil/wpiutil-cpp/*/ ; wpilibversion=$(basename $1) && echo $wpilibversion && sed --regexp-extended -i 's@(wpilib_bin_url =).*@\1 \"file:\/\/'"$HOME"'\/releases\/maven\/development"@' rdev.toml && sed --regexp-extended -i 's/(wpilib_bin_version =).*/\1 \"'"$wpilibversion"'\"/' rdev.toml && ./rdev.sh update-pyproject --commit
- name: Build + test wheels
shell: bash
run: |
./rdev.sh ci run
env:
RPYBUILD_STRIP_LIBPYTHON: "1"
RPYBUILD_CC_LAUNCHER: ccache

View File

@@ -13,9 +13,9 @@ concurrency:
jobs:
update:
name: "Update"
runs-on: ubuntu-22.04
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Fetch all history and metadata
@@ -23,7 +23,7 @@ jobs:
git checkout -b pr
git branch -f main origin/main
- name: Set up Python 3.12
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.12'
- name: Configure committer identity
@@ -42,6 +42,18 @@ jobs:
./argparse_lib.py clone
./argparse_lib.py copy-src
./argparse_lib.py format-patch
- name: Run benchmark.py
run: |
cd upstream_utils
./benchmark.py clone
./benchmark.py copy-src
./benchmark.py format-patch
- name: Run double-conversion.py
run: |
cd upstream_utils
./double-conversion.py clone
./double-conversion.py copy-src
./double-conversion.py format-patch
- name: Run eigen.py
run: |
cd upstream_utils
@@ -120,24 +132,6 @@ jobs:
./mpack.py clone
./mpack.py copy-src
./mpack.py format-patch
- name: Run stack_walker.py
run: |
cd upstream_utils
./stack_walker.py clone
./stack_walker.py copy-src
./stack_walker.py format-patch
- name: Run memory.py
run: |
cd upstream_utils
./memory.py clone
./memory.py copy-src
./memory.py format-patch
- name: Run protobuf.py
run: |
cd upstream_utils
./protobuf.py clone
./protobuf.py copy-src
./protobuf.py format-patch
- name: Run sleipnir.py
run: |
cd upstream_utils
@@ -150,7 +144,20 @@ jobs:
./stb.py clone
./stb.py copy-src
./stb.py format-patch
- name: Run upb.py
run: |
cd upstream_utils
./upb.py clone
./upb.py copy-src
./upb.py format-patch
- name: Add untracked files to index so they count as changes
run: git add -A
- name: Check output
run: git --no-pager diff --exit-code HEAD ':!*.bazel'
run: |
set +e
git --no-pager diff --exit-code HEAD ':!*.bazel'
git_exit_code=$?
if test "$git_exit_code" -ne "0"; then
echo "::error ::upstream_utils check failed. This is usually caused by a bad script or the copied files differing from what the script outputs. You can learn more about using upstream_utils to modify thirdparty libraries at https://github.com/wpilibsuite/allwpilib/blob/main/upstream_utils/README.md"
exit $git_exit_code
fi

11
.gitignore vendored
View File

@@ -255,3 +255,14 @@ bazel_auth.rc
# ctest
/Testing/
# Meson
.meson-subproject*
# Copybara user config
shared/bazel/copybara/.copybara.json
# Nix files
shell.nix
flake.nix
flake.lock

View File

@@ -1,54 +0,0 @@
cppHeaderFileInclude {
\.h$
\.hpp$
\.inc$
\.inl$
}
cppSrcFileInclude {
\.cpp$
}
modifiableFileExclude {
cmake/toolchains/
thirdparty/
\.patch$
gradlew
}
generatedFileExclude {
FRCNetComm\.java$
simulation/gz_msgs/src/include/simulation/gz_msgs/msgs\.h$
fieldImages/src/main/native/resources/
apriltag/src/test/resources/
wpilibc/src/generated/
}
repoRootNameOverride {
wpilib
}
includeOtherLibs {
^Eigen/
^cameraserver/
^cscore
^fmt/
^glass/
^google/
^gtest/
^hal/
^imgui
^implot
^mockdata/
^networktables/
^ntcore
^opencv2/
^support/
^units/
^unsupported/
^vision/
^wpi/
^wpigui
^wpimath/
^wpinet/
}

44
.wpiformat Normal file
View File

@@ -0,0 +1,44 @@
cHeaderFileInclude {
_c\.h$
}
cppHeaderFileInclude {
(?<!_c)\.h$
\.inc$
\.inl$
}
generatedFileExclude {
assets/
docs/theme\.css$
generated/
hal/src/main/native/systemcore/rev/
python/
robotpyExamples/
resources/
thirdparty/
wpigui/src/main/native/cpp/portable-file-dialogs\.cpp$
wpigui/src/main/native/include/wpi/gui/portable-file-dialogs\.h$
wpimath/src/main/native/include/wpi/units/base\.hpp$
wpinet/src/main/native/cpp/http_parser\.cpp$
wpinet/src/main/native/include/wpi/net/http_parser\.hpp$
wpiutil/src/main/native/include/wpi/util/FastQueue\.hpp$
wpiutil/src/test/native/cpp/json/
wpiutil/src/test/native/cpp/llvm/
wpiutil/src/test/native/cpp/span/
}
modifiableFileExclude {
objcpp/
wpimath/src/test/native/cpp/UnitsTest\.cpp$
wpiutil/src/main/native/cpp/fs\.cpp$
wpiutil/src/main/native/include/wpi/util/fs\.hpp$
}
licenseUpdateExclude {
cscore/src/main/native/cpp/default_init_allocator\.hpp$
wpiutil/src/main/native/cpp/Base64\.cpp$
wpiutil/src/main/native/cpp/sha1\.cpp$
wpiutil/src/main/native/include/wpi/util/sha1\.hpp$
wpinet/src/main/native/linux/AvahiClient\.hpp$
}

283
BUILD.bazel Normal file
View File

@@ -0,0 +1,283 @@
load("@aspect_bazel_lib//lib:write_source_files.bzl", "write_source_files")
load("@rules_java//java:java_binary.bzl", "java_binary")
load("@rules_java//java:java_plugin.bzl", "java_plugin")
load("@rules_pkg//:mappings.bzl", "pkg_files")
load("@rules_python//python:pip.bzl", "compile_pip_requirements")
load("//shared/bazel/rules:publishing.bzl", "publish_all")
load("//shared/bazel/rules/robotpy:compatibility_select.bzl", "robotpy_compatibility_select")
java_plugin(
name = "avaje_jsonb_generator",
processor_class = "io.avaje.jsonb.generator.JsonbProcessor",
visibility = ["//visibility:public"],
deps = [
"@maven//:io_avaje_avaje_jsonb_generator",
],
)
exports_files([
"LICENSE.md",
"ThirdPartyNotices.txt",
])
pkg_files(
name = "license_pkg_files",
srcs = [
"LICENSE.md",
"ThirdPartyNotices.txt",
],
visibility = ["//visibility:public"],
)
# bazel build //:requirements.lock
compile_pip_requirements(
name = "requirements",
extra_args = ["--allow-unsafe"],
requirements_in = "requirements.txt",
requirements_txt = "requirements_lock.txt",
requirements_windows = "//:requirements_windows_lock.txt",
# compile_pip_requirements does not respect target_compatible_with for some of the targets it generates under the hood
tags = ["no-systemcore"],
)
alias(
name = "quickbuf_protoc",
actual = select({
"@platforms//os:windows": "@quickbuffer_protoc_windows//file",
"@rules_bzlmodrio_toolchains//conditions:osx_aarch64": "@quickbuffer_protoc_osx_aarch64//file",
"@rules_bzlmodrio_toolchains//conditions:osx_x86_64": "@quickbuffer_protoc_osx_x86-64//file",
"@rules_bzlmodrio_toolchains//constraints/combined:is_linux": "@quickbuffer_protoc_linux//file",
}),
tags = ["pregeneration"],
visibility = ["//visibility:public"],
)
java_binary(
name = "copybara",
main_class = "com.google.copybara.Main",
runtime_deps = ["@com_github_google_copybara//jar"],
)
# This is a helper to run all of the pregeneration scripts at once.
write_source_files(
name = "write_pregenerated_files",
additional_update_targets = [
"//hal:write_hal",
"//ntcore:write_ntcore",
"//wpilibc:write_wpilibc",
"//wpilibcExamples:write_example_project_list",
"//wpilibj:write_wpilibj",
"//wpilibjExamples:write_example_project_list",
"//commandsv2:write_wpilib_new_commands",
"//commandsv3:write_commandsv3",
"//wpimath:write_wpimath",
"//wpiunits:write_wpiunits",
"//wpiutil:write_wpiutil",
"//robotpyExamples:write_example_project_list",
],
tags = ["pregeneration"],
)
publish_all(
name = "publish",
targets = [
"//apriltag:apriltag-cpp_publish.publish",
"//apriltag:apriltag-java_publish.publish",
"//cameraserver:cameraserver-cpp_publish.publish",
"//cameraserver:cameraserver-java_publish.publish",
"//commandsv2:commandsv2-cpp_publish.publish",
"//commandsv2:commandsv2-java_publish.publish",
"//commandsv3:commandsv3-java_publish.publish",
"//cscore:cscore-cpp_publish.publish",
"//cscore:cscore-java_publish.publish",
"//cscore:cscorejnicvstatic-cpp_publish.publish",
"//datalog:datalog-cpp_publish.publish",
"//datalog:datalog-java_publish.publish",
"//docs:wpilibj_publish.publish",
"//epilogue-processor:processor-java_publish.publish",
"//epilogue-runtime:epilogue-java_publish.publish",
"//fields:fields-cpp_publish.publish",
"//fields:fields-java_publish.publish",
"//glass:glass-cpp_publish.publish",
"//glass:glassapp_publish.publish",
"//glass:glassnt-cpp_publish.publish",
"//hal:hal-java_publish.publish",
"//hal:wpiHal-cpp_publish.publish",
"//javacPlugin:javacPlugin_publish.publish",
"//ntcore:ntcore-cpp_publish.publish",
"//ntcore:ntcore-java_publish.publish",
"//ntcoreffi:ntcoreffi-cpp_publish.publish",
"//romiVendordep:romiVendordep-cpp_publish.publish",
"//romiVendordep:romiVendordep-java_publish.publish",
"//simulation/halsim_ds_socket:halsim_ds_socket-cpp_publish.publish",
"//simulation/halsim_gui:halsim_gui-cpp_publish.publish",
"//simulation/halsim_ws_client:halsim_ws_client-cpp_publish.publish",
"//simulation/halsim_ws_core:halsim_ws_core-cpp_publish.publish",
"//simulation/halsim_ws_server:halsim_ws_server-cpp_publish.publish",
"//simulation/halsim_xrp:halsim_xrp-cpp_publish.publish",
"//thirdparty/catch2:catch2-cpp_publish.publish",
"//thirdparty/googletest:googletest-cpp_publish.publish",
"//thirdparty/imgui_suite:imguiSuite-cpp_publish.publish",
"//tools/datalogtool:datalogtool_publish.publish",
"//tools/outlineviewer:outlineviewer_publish.publish",
"//tools/processstarter:processstarter_publish.publish",
"//tools/sysid:sysid_publish.publish",
"//tools/wpical:wpical_publish.publish",
"//wpiannotations:wpiannotations_publish.publish",
"//wpigui:wpigui-cpp_publish.publish",
"//wpilibc:wpilibc-cpp_publish.publish",
"//wpilibcExamples:commands_publish.publish",
"//wpilibcExamples:examples_publish.publish",
"//wpilibcExamples:templates_publish.publish",
"//wpilibj:wpilibj-java_publish.publish",
"//wpilibjExamples:commands_publish.publish",
"//wpilibjExamples:examples_publish.publish",
"//wpilibjExamples:templates_publish.publish",
"//wpimath:wpimath-cpp_publish.publish",
"//wpimath:wpimath-java_publish.publish",
"//wpinet:wpinet-cpp_publish.publish",
"//wpinet:wpinet-java_publish.publish",
"//wpiunits:wpiunits-java_publish.publish",
"//wpiutil:wpiutil-cpp_publish.publish",
"//wpiutil:wpiutil-java_publish.publish",
"//xrpVendordep:xrpVendordep-cpp_publish.publish",
"//xrpVendordep:xrpVendordep-java_publish.publish",
] + select({
"@platforms//cpu:x86_64": [
"//docs:wpilibc_publish.publish",
],
"//conditions:default": [],
}),
)
write_source_files(
name = "write_robotpy_generated_native_files",
additional_update_targets = [
"//apriltag:robotpy-native-apriltag-generator.generate_build_info",
"//datalog:robotpy-native-datalog-generator.generate_build_info",
"//hal:robotpy-native-wpihal-generator.generate_build_info",
"//ntcore:robotpy-native-ntcore-generator.generate_build_info",
"//romiVendordep:robotpy-native-xrp-generator.generate_build_info",
"//wpilibc:robotpy-native-wpilib-generator.generate_build_info",
"//wpinet:robotpy-native-wpinet-generator.generate_build_info",
"//wpimath:robotpy-native-wpimath-generator.generate_build_info",
"//wpiutil:robotpy-native-wpiutil-generator.generate_build_info",
"//xrpVendordep:robotpy-native-xrp-generator.generate_build_info",
],
tags = [
"pregeneration",
"robotpy",
],
target_compatible_with = robotpy_compatibility_select(),
)
write_source_files(
name = "write_robotpy_generated_pybind_files",
additional_update_targets = [
"//apriltag:robotpy-apriltag-generator.generate_build_info",
"//datalog:robotpy-datalog-generator.generate_build_info",
"//hal:robotpy-hal-generator.generate_build_info",
"//ntcore:pyntcore-generator.generate_build_info",
"//romiVendordep:robotpy-romi-generator.generate_build_info",
"//wpilibc:robotpy-wpilib-generator.generate_build_info",
"//wpinet:robotpy-wpinet-generator.generate_build_info",
"//wpimath:robotpy-wpimath-generator.generate_build_info",
"//wpimath:robotpy-wpimath_test-generator.generate_build_info",
"//wpiutil:robotpy-wpiutil-generator.generate_build_info",
"//xrpVendordep:robotpy-xrp-generator.generate_build_info",
],
tags = [
"pregeneration",
"robotpy",
],
target_compatible_with = robotpy_compatibility_select(),
)
write_source_files(
name = "write_robotpy_update_yaml_files",
additional_update_targets = [
"//apriltag:write_robotpy-apriltag-update-yaml",
"//datalog:write_robotpy-wpilog-update-yaml",
"//hal:write_robotpy-hal-update-yaml",
"//ntcore:write_pyntcore-update-yaml",
"//romiVendordep:write_robotpy-romi-update-yaml",
"//wpilibc:write_robotpy-wpilib-update-yaml",
"//wpinet:write_robotpy-wpinet-update-yaml",
"//wpimath:write_robotpy-wpimath-update-yaml",
"//wpimath:write_robotpy-wpimath-test-update-yaml",
"//wpiutil:write_robotpy-wpiutil-update-yaml",
"//xrpVendordep:write_robotpy-xrp-update-yaml",
],
tags = [
"manual",
"pregeneration",
"robotpy",
],
target_compatible_with = robotpy_compatibility_select(),
)
write_source_files(
name = "write_robotpy_create_imports",
additional_update_targets = [
"//apriltag:robotpy-apriltag-create-imports",
"//datalog:robotpy-wpilog-create-imports",
"//hal:robotpy-hal-create-imports",
"//ntcore:pyntcore-create-imports",
"//romiVendordep:robotpy-romi-create-imports",
"//wpilibc:robotpy-wpilib-create-imports",
"//wpinet:robotpy-wpinet-create-imports",
"//wpimath:robotpy-wpimath-create-imports",
"//wpimath:robotpy-wpimath-test-create-imports",
"//wpiutil:robotpy-wpiutil-create-imports",
"//xrpVendordep:robotpy-xrp-create-imports",
],
tags = [
"manual",
"pregeneration",
"robotpy",
],
target_compatible_with = robotpy_compatibility_select(),
)
write_source_files(
name = "write_robotpy_files",
additional_update_targets = [
":write_robotpy_generated_native_files",
":write_robotpy_generated_pybind_files",
":write_robotpy_update_yaml_files",
],
tags = [
"manual",
"pregeneration",
],
)
write_source_files(
name = "write_all",
additional_update_targets = [
":write_pregenerated_files",
":write_robotpy_files",
],
tags = [
"manual",
"pregeneration",
],
)
# Helper easily run the semiwrap parsing tools on all of the robotpy projects.
filegroup(
name = "robotpy_generated_files",
srcs = [
"//apriltag:robotpy-apriltag.generated_files",
"//datalog:robotpy-wpilog.generated_files",
"//hal:robotpy-hal.generated_files",
"//ntcore:pyntcore.generated_files",
"//wpilibc:robotpy-wpilib.generated_files",
"//wpimath:robotpy-wpimath.generated_files",
"//wpimath:robotpy-wpimath-test.generated_files",
"//wpinet:robotpy-wpinet.generated_files",
"//wpiutil:robotpy-wpiutil.generated_files",
],
tags = ["manual"],
target_compatible_with = robotpy_compatibility_select(),
)

View File

@@ -63,9 +63,7 @@ set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# Options for building certain parts of the repo. Everything is built by default.
option(BUILD_SHARED_LIBS "Build with shared libs (needed for JNI)" ON)
option(WITH_JAVA "Include Java and JNI in the build" OFF)
option(WITH_JAVA_SOURCE "Build Java source jars" ${WITH_JAVA})
option(BUILD_SHARED_LIBS "Build with shared libs" ON)
option(WITH_DOCS "Build Doxygen docs (needs Git for versioning)" OFF)
cmake_dependent_option(
DOCS_WARNINGS_AS_ERRORS
@@ -78,45 +76,22 @@ option(WITH_CSCORE "Build cscore (needs OpenCV)" ON)
option(WITH_NTCORE "Build ntcore" ON)
option(WITH_WPICAL "Build wpical" OFF)
option(WITH_WPIMATH "Build wpimath" ON)
cmake_dependent_option(
WITH_WPIUNITS
"Build wpiunits"
ON
WITH_JAVA
OFF
)
option(WITH_WPILIB "Build hal, wpilibc/j, and developerRobot (needs OpenCV)" ON)
option(WITH_EXAMPLES "Build examples" OFF)
option(WITH_TESTS "Build unit tests (requires internet connection)" ON)
option(WITH_GUI "Build GUI items" ON)
option(WITH_SIMULATION_MODULES "Build simulation modules" ON)
option(WITH_PROTOBUF "Build protobuf support" ON)
option(WITH_BENCHMARK "Build the benchmark project" ON)
# Options for using a package manager (e.g., vcpkg) for certain dependencies.
option(USE_SYSTEM_FMTLIB "Use system fmtlib" OFF)
option(USE_SYSTEM_LIBUV "Use system libuv" OFF)
option(USE_SYSTEM_EIGEN "Use system eigen" OFF)
# Options for location of OpenCV Java.
set(OPENCV_JAVA_INSTALL_DIR "" CACHE PATH "Location to search for the OpenCV jar file")
option(USE_LINKED_AVAHI "Use directly linked Avahi instead of loading at runtime" OFF)
# Options for compilation flags.
option(NO_WERROR "Disable -Werror flag during compilation" OFF)
if(NOT WITH_JAVA OR NOT WITH_CSCORE)
if(NOT "${OPENCV_JAVA_INSTALL_DIR}" STREQUAL "")
message(
WARNING
"
WARNING: OpenCV Java dir set but java is not enabled!
It will be ignored.
"
)
endif()
endif()
wpilib_config(OPTIONS WITH_JAVA REQUIRES BUILD_SHARED_LIBS)
wpilib_config(OPTIONS WITH_SIMULATION_MODULES REQUIRES BUILD_SHARED_LIBS WITH_WPILIB WITH_NTCORE)
wpilib_config(OPTIONS WITH_CSCORE REQUIRES WITH_NTCORE)
@@ -125,17 +100,7 @@ wpilib_config(OPTIONS WITH_GUI REQUIRES WITH_NTCORE WITH_WPIMATH)
wpilib_config(OPTIONS WITH_WPILIB REQUIRES WITH_NTCORE WITH_WPIMATH)
wpilib_config(OPTIONS WITH_WPIMATH WITH_JAVA REQUIRES WITH_WPIUNITS)
set(include_dest include)
set(java_lib_dest java)
if(WITH_JAVA OR WITH_JAVA_SOURCE)
set(CMAKE_JAVA_COMPILE_FLAGS "-encoding" "UTF8" "-Xlint:unchecked")
find_package(Java REQUIRED COMPONENTS Development)
if(NOT ANDROID)
find_package(JNI REQUIRED COMPONENTS JVM)
endif()
endif()
if(WITH_DOCS)
find_package(Doxygen REQUIRED)
@@ -150,14 +115,6 @@ endif()
find_package(LIBSSH CONFIG 0.7.1)
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
if(WITH_PROTOBUF)
set(protobuf_MODULE_COMPATIBLE ON CACHE BOOL "" FORCE)
find_package(Protobuf REQUIRED)
find_program(PROTOC_COMPILER protoc REQUIRED)
endif()
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG OFF)
get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(isMultiConfig)
@@ -275,6 +232,9 @@ if(WITH_TESTS)
enable_testing()
add_subdirectory(thirdparty/googletest)
include(GoogleTest)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/catch2/extras")
add_subdirectory(thirdparty/catch2)
include(Catch)
endif()
if(USE_SYSTEM_LIBUV)
@@ -287,10 +247,13 @@ endif()
set(FILENAME_DEP_REPLACE "get_filename_component(SELF_DIR \"$\{CMAKE_CURRENT_LIST_FILE\}\" PATH)")
set(SELF_DIR "$\{SELF_DIR\}")
set(WPIUNITS_DEP_REPLACE_IMPL "find_dependency(wpiunits)")
set(WPIUTIL_DEP_REPLACE "find_dependency(wpiutil)")
set(DATALOG_DEP_REPLACE "find_dependency(datalog)")
add_subdirectory(wpiutil)
add_subdirectory(datalog)
if(WITH_NTCORE)
set(NTCORE_DEP_REPLACE "find_dependency(ntcore)")
set(WPINET_DEP_REPLACE "find_dependency(wpinet)")
@@ -299,33 +262,22 @@ if(WITH_NTCORE)
endif()
if(WITH_WPIMATH)
if(WITH_JAVA)
set(WPIUNITS_DEP_REPLACE ${WPIUNITS_DEP_REPLACE_IMPL})
add_subdirectory(wpiunits)
endif()
set(WPIMATH_DEP_REPLACE "find_dependency(wpimath)")
add_subdirectory(wpimath)
endif()
if(WITH_WPIUNITS AND NOT WITH_WPIMATH)
# In case of building wpiunits standalone
set(WPIUNITS_DEP_REPLACE ${WPIUNITS_DEP_REPLACE_IMPL})
add_subdirectory(wpiunits)
endif()
if(WITH_GUI)
add_subdirectory(fieldImages)
add_subdirectory(fields)
add_subdirectory(thirdparty/imgui_suite)
add_subdirectory(wpigui)
add_subdirectory(glass)
add_subdirectory(outlineviewer)
add_subdirectory(sysid)
add_subdirectory(tools/outlineviewer)
add_subdirectory(tools/sysid)
if(WITH_WPICAL)
add_subdirectory(wpical)
add_subdirectory(tools/wpical)
endif()
if(LIBSSH_FOUND)
add_subdirectory(roborioteamnumbersetter)
add_subdirectory(datalogtool)
add_subdirectory(tools/datalogtool)
endif()
endif()
@@ -345,12 +297,10 @@ endif()
if(WITH_WPILIB)
set(APRILTAG_DEP_REPLACE "find_dependency(apriltag)")
set(WPILIBC_DEP_REPLACE "find_dependency(wpilibc)")
set(WPILIBJ_DEP_REPLACE "find_dependency(wpilibj)")
set(WPILIBNEWCOMMANDS_DEP_REPLACE "find_dependency(wpilibNewCommands)")
set(COMMAND_DEP_REPLACE "find_dependency(commandsv2)")
add_subdirectory(apriltag)
add_subdirectory(wpilibj)
add_subdirectory(wpilibc)
add_subdirectory(wpilibNewCommands)
add_subdirectory(commandsv2)
add_subdirectory(romiVendordep)
add_subdirectory(xrpVendordep)
if(WITH_EXAMPLES)
@@ -359,6 +309,10 @@ if(WITH_WPILIB)
add_subdirectory(developerRobot)
endif()
if(WITH_BENCHMARK)
add_subdirectory(benchmark)
endif()
if(WITH_SIMULATION_MODULES)
add_subdirectory(simulation)
endif()

View File

@@ -24,27 +24,6 @@
"CMAKE_C_COMPILER_LAUNCHER": "sccache",
"CMAKE_CXX_COMPILER_LAUNCHER": "sccache"
}
},
{
"name": "with-java",
"displayName": "",
"description": "Ninja config with Java",
"generator": "Ninja",
"binaryDir": "build-cmake",
"cacheVariables": {
"WITH_JAVA": "ON"
}
},
{
"name": "with-java-and-sccache",
"displayName": "",
"description": "Ninja config with Java and sccache",
"generator": "Ninja",
"inherits": "with-sccache",
"binaryDir": "build-cmake",
"cacheVariables": {
"WITH_JAVA": "ON"
}
}
]
}

View File

@@ -1,69 +1,46 @@
# Contributor Covenant Code of Conduct
# Contributor Community Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
As members, contributors, and leaders, we commit to fostering a community where everyone feels safe, respected, and valued. We are dedicated to ensuring that participation in this community is harassment-free, inclusive, and welcoming, regardless of age, body type, abilities (visible or invisible), ethnicity, gender identity or expression, sexual orientation, socioeconomic background, education, nationality, personal appearance, race, or religion.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
Positive and respectful behavior is essential to creating a thriving community. This includes:
* Exhibiting Gracious Professionalism® at all times. Gracious Professionalism
* Practicing **Gracious Professionalism®** at all times. Gracious Professionalism
is a way of doing things that encourages high-quality work, emphasizes the
value of others, and respects individuals and the community.
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
* Showing empathy, kindness, and patience.
* Respecting diverse perspectives and experiences.
* Giving and receiving constructive feedback with openness and humility.
* Owning mistakes, apologizing when necessary, and learning from them.
* Prioritizing the well-being and success of the entire community over individual interests.
Examples of unacceptable behavior include:
Unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Using sexualized language, imagery, or making inappropriate advances
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
* Harassment in any form, whether public or private.
* Sharing private information (e.g., email or physical addresses) without explicit consent.
* Any behavior that is unprofessional, harmful, or exclusionary.
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
Community leaders are responsible for maintaining these standards and will take appropriate action to address any behavior deemed harmful, threatening, or inappropriate. Actions may include removing content, issuing warnings, or, when necessary, banning individuals. Moderation decisions will be communicated transparently where appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
This Code of Conduct applies to all community spaces, events, and instances where individuals represent the community (e.g., official email accounts, social media posts, or in-person/virtual events).
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
[conduct@wpilib.org](mailto:conduct@wpilib.org).
[wpilib@wpi.edu](mailto:wpilib@wpi.edu).
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
@@ -79,7 +56,7 @@ the consequences for any action they deem in violation of this Code of Conduct:
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
**Consequence**: A warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
@@ -115,6 +92,9 @@ individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## A Note on Kindness
Building a community isnt just about rules—its about connection. Every interaction is an opportunity to be understanding, compassionate, and supportive. Being a good human is the key to our ethos.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],

View File

@@ -4,6 +4,8 @@ So you want to contribute your changes back to WPILib. Great! We have a few cont
- [General Contribution Rules](#general-contribution-rules)
- [What to Contribute](#what-to-contribute)
- [Design Philosophy](#design-philosophy)
- [Contribution Process](#contribution-process)
- [Coding Guidelines](#coding-guidelines)
- [Submitting Changes](#submitting-changes)
- [Pull Request Format](#pull-request-format)
@@ -12,75 +14,63 @@ So you want to contribute your changes back to WPILib. Great! We have a few cont
## General Contribution Rules
- Everything in the library must work for the 4000+ teams that will be using it.
- Everything in the library must work for the 14000+ teams that will be using it.
- We need to be able to maintain submitted changes, even if you are no longer working on the project.
- Tool suite changes must be generally useful to a broad range of teams
- Excluding bug fixes, changes in one language generally need to have corresponding changes in other languages.
- Some features, such the addition of C++23 for WPILibC or Functional Interfaces for WPILibJ, are specific to that version of WPILib only. New language features added to C++ must be wrappable in Python for [RobotPy](https://github.com/robotpy).
- Substantial changes often need to have corresponding LabVIEW changes. To do this, we will work with NI on these large changes.
- Some features, such the addition of C++26 for WPILibC or Functional Interfaces for WPILibJ, are specific to that version of WPILib only. New language features added to C++ must be wrappable in Python for [RobotPy](https://github.com/robotpy).
- Changes should have tests.
- Code should be well documented.
- This involves writing tutorials and/or usage guides for your submitted feature. These articles are then hosted on the [WPILib](https://docs.wpilib.org/) documentation website. See the [frc-docs repository](https://github.com/wpilibsuite/frc-docs) for more information.
- This involves writing tutorials and/or usage guides for your submitted feature. These articles are then hosted on the [WPILib](https://docs.wpilib.org/) documentation website. See the [wpilib-docs repository](https://github.com/wpilibsuite/wpilib-docs) for more information.
## What to Contribute
- Bug reports and fixes
- We will generally accept bug fixes without too much question. If they are only implemented for one language, we will implement them for any other necessary languages. Bug reports are also welcome, please submit them to our GitHub issue tracker.
- While we do welcome improvements to the API, there are a few important rules to consider:
- Features must be added to Java (WPILibJ), C++ (WPILibC), with rare exceptions.
- Most of Python (RobotPy) is created by wrapping WPILibC with pybind11 via robotpy-build. However, new features to the command framework should also be submitted to [robotpy-commands-v2](https://github.com/robotpy/robotpy-commands-v2) as the command framework is reimplemented in Python.
- During competition season, we will not merge any new feature additions. We want to ensure that the API is stable during the season to help minimize issues for teams.
- Ask about large changes before spending a bunch of time on them! You can create a new issue on our GitHub tracker for feature request/discussion and talk about it with us there.
- Features must be added to Java (WPILibJ), C++ (WPILibC), and Python with rare exceptions.
- Most of Python (RobotPy) is created by wrapping WPILibC with pybind11 via semiwrap. In general, new user-facing functions or classes should have the proper wrapper configs updated, typically located in a YAML file with the same name as the header. See the [in-repo RobotPy README](./README-RobotPy.md) for more info and how to partially auto-update the configs. However, the command framework is reimplemented in Python, and requires code to be ported instead of being wrapped via semiwrap.
- During competition season, we will not merge any new feature additions or removals. We want to ensure that the API is stable during the season to help minimize issues for teams.
- Ask about large changes before spending a bunch of time on them! See [Contribution Process](#contribution-process) for where to ask.
- Features that make it easier for teams with less experience to be more successful are more likely to be accepted.
- Features in WPILib should be broadly applicable to all teams. Anything that is team specific should not be submitted.
- As a rule, we are happy with the general structure of WPILib. We are not interested in major rewrites of all of WPILib. We are open to talking about ideas, but backwards compatibility is very important for WPILib, so be sure to keep this in mind when proposing major changes.
- Generally speaking, we do not accept code for specific sensors. We have to be able to test the sensor in hardware on the WPILib test bed. Additionally, hardware availability for teams is important. Therefore, as a general rule, the library only directly supports hardware that is in the Kit of Parts. If you are a company interested in getting a sensor into the Kit of Parts, please contact FIRST directly at frcparts@firstinspires.org.
- While the library may contain support for specific sensors, these are typically items contained in the FIRST Robotics Competition Kit of Parts or commonly used hardware identified by FIRST or core WPILib Developers. If you think a certain sensor should be supported in WPILib, you may submit an issue justifying the reasons why it should be supported and approval will be determined by FIRST or core WPILib Developers. If you are a company interested in getting a sensor into the Kit of Parts, please contact FIRST directly at frcparts@firstinspires.org.
## Design Philosophy
WPILib's general design philosophy strays far away from the traditional Object-Oriented Programming architectures dominant in enterprise codebases. The general points to follow for WPILib are as follows:
- Prefer functions and composition over inheritance. Inheritance is rigid and often prevents evolution, as adding or removing methods from an inherited class risks breakage. For similar reasons, functional interfaces (`std::function` in C++) are preferred over actual interfaces.
- Avoid opaque black-boxes of functionality. Classes like RamseteCommand or HolonomicDriveController (both removed in 2027) are good examples of this. While they look like a good abstraction that helps beginners, the black-box nature means they are [difficult to debug](https://github.com/wpilibsuite/allwpilib/issues/3350) and it's impossible to instrument the internals to figure out what's going on, or they are extremely clunky to use compared to composing the individual components (thus defeating the point of abstracting it away; SwerveControllerCommand construction was [a huge pile of opaque arguments glued together](https://github.com/wpilibsuite/allwpilib/blob/v2026.2.2/wpilibjExamples/src/main/java/edu/wpi/first/wpilibj/examples/swervecontrollercommand/RobotContainer.java#L104-L114)). Composition is strongly preferred, with strong documentation and examples describing how to do that composition.
- Error at compile time, not runtime. Despite our best efforts, there will always be people who don't read stack traces (understandable for beginner programmers). Compile time errors show up in builds and in an IDE, which is much easier and faster for people to pinpoint and debug. Use language features to make invalid code impossible to build.
- The Matrix class in Java is an example of this. While clunky due to Java's weak generics system, it enforces correct Matrix dimensions at compile time, with the MatBuilder factory method throwing if the array passed in is the wrong size, which leads to the next point:
- Try to only throw exceptions at code startup, and only for things that are obviously incorrect. Robots shouldn't quit, and it's a real "feels bad" moment when yours does, especially in a match. It's oftentimes better to have a robot continue running when it sees nonsensical state as opposed to outright crashing, since other components are often still functional. If you can't make invalid code a compile time error, throwing at the start of the robot program is the next best solution, but avoid throwing in functions likely to be called throughout a robot's runtime.
- Sometimes the behavior of functions are just incorrect if invalid data is passed in, and throwing is one of the only options. This is a judgement call, but if there are no other options, throwing can be okay.
- An alternative to throwing is logging an error, typically with [the Alerts framework](https://docs.wpilib.org/en/latest/docs/software/telemetry/persistent-alerts.html); this is a good choice for runtime errors. Also see https://github.com/wpilibsuite/allwpilib/issues/6766 for an example of not throwing exceptions, but simply logging an error on invalid data.
- Note that hardware configuration issues such as a sensor not existing isn't necessarily obviously incorrect; it could be that the wrong port was specified, but it could also be unplugged due to external factors. Throwing just because it's unplugged can make for a "feels bad" moment, and should be avoided.
## Contribution Process
Have an idea to make WPILib better? Here's some steps to go from idea to implementation:
1. (Optional) **Discuss it in the Discord.** The programming discussion channel in the [Unofficial FIRST Robotics Competition Discord Server](https://discord.com/invite/frc) is a popular choice for initial discussion about ideas because many WPILib developers are active there and the live messaging nature of the platform is well suited for initial discussion (particularly for smaller changes). Note that the unofficial Discord server is not a mandatory step in the development process and is not endorsed by FIRST®.
2. (Recommended) **Open a GitHub issue.** GitHub issues are another way to get initial feedback about an idea before working on an implementation. Compared to the unofficial Discord server, GitHub issues have much wider visibility and are better suited for serious discussions about major changes. Getting feedback about an idea (whether in the unofficial Discord server or in a GitHub issue) before working on the implementation is recommended to avoid working on a change that will be rejected, though some ideas are pretty safe.
3. (Rare) **Create a design document in GitHub.** Sometimes, a change is so large that a design document is necessary to fully flesh out the details (and get feedback on them) before starting on an implementation. This is done through a pull request that adds the design document (as a Markdown file) to the repository. This is extremely rare, and it is sometimes done concurrently with the implementation if the change doesn't need much debate but is large enough to require a design document.
4. (Mandatory) **Create a GitHub pull request.** This is how you implement the changes, and is the focus of most of the rest of this document.
## Coding Guidelines
WPILib uses modified Google style guides for both C++ and Java, which can be found in the [styleguide repository](https://github.com/wpilibsuite/styleguide). Autoformatters are available for many popular editors at https://github.com/google/styleguide. Running wpiformat is required for all contributions and is enforced by our continuous integration system.
While the library should be fully formatted according to the styles, additional elements of the style guide were not followed when the library was initially created. All new code should follow the guidelines. If you are looking for some easy ramp-up tasks, finding areas that don't follow the style guide and fixing them is very welcome.
### Math documentation
When writing math expressions in documentation, use https://www.unicodeit.net/ to convert LaTeX to a Unicode equivalent that's easier to read. Not all expressions will translate (e.g., superscripts of superscripts) so focus on making it readable by someone who isn't familiar with LaTeX. If content on multiple lines needs to be aligned in Doxygen/Javadoc comments (e.g., integration/summation limits, matrices packed with square brackets and superscripts for them), put them in @verbatim/@endverbatim blocks in Doxygen or `<pre>` tags in Javadoc so they render with monospace font.
The LaTeX to Unicode conversions can also be done locally via the unicodeit Python package. To install it, execute:
```bash
pip install --user unicodeit
```
Here's example usage:
```bash
$ python -m unicodeit.cli 'x_{k+1} = Ax_k + Bu_k'
xₖ₊₁ = Axₖ + Buₖ
```
On Linux, this process can be streamlined further by adding the following Bash function to your .bashrc (requires `wl-clipboard` on Wayland or `xclip` on X11):
```bash
# Converts LaTeX to Unicode, prints the result, and copies it to the clipboard
uc() {
if [ $WAYLAND_DISPLAY ]; then
python -m unicodeit.cli $@ | tee >(wl-copy -n)
else
python -m unicodeit.cli $@ | tee >(xclip -sel)
fi
}
```
Here's example usage:
```bash
$ uc 'x_{k+1} = Ax_k + Bu_k'
xₖ₊₁ = Axₖ + Buₖ
```
## Submitting Changes
### Pull Request Format
Changes should be submitted as a Pull Request against the main branch of WPILib. For most changes, commits will be squashed upon merge. For particularly large changes, multiple commits are ok, but assume one commit unless asked otherwise. We may ask you to break a PR into multiple standalone PRs or commits for rebase within one PR to separate unrelated changes. No change will be merged unless it is up to date with the current main branch. We do this to make sure that the git history isn't too cluttered.
During the build season, breaking changes or other changes intended for the next season can be created as a pull request against the development branch of WPILib. After the season is over, the changes in the development branch will be merged into main.
Particularly large and/or breaking changes should be targeted to the 2027 branch, which targets the [Systemcore Robot Controller](https://community.firstinspires.org/introducing-the-future-mobile-robot-controller). The intent is minimize changes for 2026, to allow development to focus on preparing for 2027.
### Merge Process

View File

@@ -13,13 +13,12 @@ This article contains instructions on building projects using a development buil
Development builds are the per-commit build hosted every time a commit is pushed to the [allwpilib](https://github.com/wpilibsuite/allwpilib/) repository. These builds are then hosted on [artifactory](https://frcmaven.wpi.edu/artifactory/webapp/#/home).
To build a project using a development build, find the build.gradle file and open it. Then, add the following code below the plugin section and replace YEAR with the year of the development version. It is also necessary to use a 2025 GradleRIO version, ie `2025.1.1-beta-1`
To build a project using a development build, find the build.gradle file and open it. Then, add the following code below the plugin section and replace YEAR with the year of the development version. It is also necessary to use a 2027 GradleRIO version, ie `2027.0.0-alpha-5`
```groovy
wpi.maven.useLocal = false
wpi.maven.useDevelopment = true
wpi.versions.wpilibVersion = 'YEAR.+'
wpi.versions.wpimathVersion = 'YEAR.+'
```
The top of your ``build.gradle`` file should now look similar to the code below. Ignore any differences in versions.
@@ -28,13 +27,12 @@ Java
```groovy
plugins {
id "java"
id "edu.wpi.first.GradleRIO" version "2025.1.1-beta-1"
id "org.wpilib.GradleRIO" version "2027.0.0-alpha-5"
}
wpi.maven.useLocal = false
wpi.maven.useDevelopment = true
wpi.versions.wpilibVersion = '2025.+'
wpi.versions.wpimathVersion = '2025.+'
wpi.versions.wpilibVersion = '2027.+'
```
C++
@@ -42,13 +40,12 @@ C++
plugins {
id "cpp"
id "google-test-test-suite"
id "edu.wpi.first.GradleRIO" version "2025.1.1-beta-1"
id "org.wpilib.GradleRIO" version "2027.0.0-alpha-5"
}
wpi.maven.useLocal = false
wpi.maven.useDevelopment = true
wpi.versions.wpilibVersion = '2025.+'
wpi.versions.wpimathVersion = '2025.+'
wpi.versions.wpilibVersion = '2027.+'
```
### Development Build Documentation
@@ -64,13 +61,12 @@ Java
```groovy
plugins {
id "java"
id "edu.wpi.first.GradleRIO" version "2025.1.1-beta-1"
id "org.wpilib.GradleRIO" version "2027.0.0-alpha-5"
}
wpi.maven.useLocal = false
wpi.maven.useFrcMavenLocalDevelopment = true
wpi.maven.useWpilibMavenLocalDevelopment = true
wpi.versions.wpilibVersion = 'YEAR.424242.+'
wpi.versions.wpimathVersion = 'YEAR.424242.+'
```
C++
@@ -78,15 +74,14 @@ C++
plugins {
id "cpp"
id "google-test-test-suite"
id "edu.wpi.first.GradleRIO" version "2025.1.1-beta-1"
id "org.wpilib.GradleRIO" version "2027.0.0-alpha-5"
}
wpi.maven.useLocal = false
wpi.maven.useFrcMavenLocalDevelopment = true
wpi.maven.useWpilibMavenLocalDevelopment = true
wpi.versions.wpilibVersion = 'YEAR.424242.+'
wpi.versions.wpimathVersion = 'YEAR.424242.+'
```
# roboRIO Development
# Systemcore Development
See the [developerRobot](developerRobot/README.md) subproject.

View File

@@ -6,9 +6,9 @@ The Python script used to generate a subproject's files will always be located i
The templates will be located under `subproject/src/generate/main`, and generated files will be located under `subproject/src/generated/main`.
If the generated file is for C++, the hierarchy should be symmetrical, so if a generated header is located under `subproject/src/generated/main/native/include/frc/header.h`, the template to generate it should be located under `subproject/src/generate/main/native/include/frc/template.h.jinja`. You should pretend like `subproject/src/generate/main` is just like `subproject/src/main`, in that the file hierarchy must make sense if the files weren't generated, e.g, headers that would go in `subproject/src/main/native/include/blah` should be in `subproject/src/generated/main/native/include/blah`.
If the generated file is for C++, the hierarchy should be symmetrical, so if a generated header is located under `subproject/src/generated/main/native/include/wpi/header.h`, the template to generate it should be located under `subproject/src/generate/main/native/include/wpi/template.h.jinja`. You should pretend like `subproject/src/generate/main` is just like `subproject/src/main`, in that the file hierarchy must make sense if the files weren't generated, e.g, headers that would go in `subproject/src/main/native/include/blah` should be in `subproject/src/generated/main/native/include/blah`.
If the generated file is for Java, templates should be located under `subproject/src/generate/main/java`, and the hierarchy for output files should reflect the declared package of the output Java files. For example, a Jinja template at `subproject/src/main/java/template.java.jinja` with the package `edu.wpi.first.wpilibj` would be used to generate Java files located at `subproject/src/generated/main/java/edu/wpi/first/wpilibj`
If the generated file is for Java, templates should be located under `subproject/src/generate/main/java`, and the hierarchy for output files should reflect the declared package of the output Java files. For example, a Jinja template at `subproject/src/main/java/template.java.jinja` with the package `org.wpilib.wpilibj` would be used to generate Java files located at `subproject/src/generated/main/java/org/wpilib/wpilibj`
The JSON files live under `subproject/src/generate` since they apply to both languages. One unique case is JSON files that are used by multiple subprojects, currently only JSON files shared by wpilibc and wpilibj. In that specific case, the JSON files will always be located in wpilibj since Java is the most used language.
@@ -23,3 +23,6 @@ To maintain consistency with other Python scripts, copy an existing `generate_*.
### (Re)Generating files and committing them
Once your Python script is complete, you can run `python generate_<thing>.py` to generate the files. Once you're finished with your files, commit these files to Git. If you regenerated the files and Git indicates the files have changed, but the diff doesn't show any changes, only the line endings have changed. If you expected changes to the generated code, you didn't correctly make changes. If you didn't expect changes, you can ignore this and discard the changes. Also ensure that you've marked the Python script as executable, since this is necessary for CI workflows to run your scripts. To add your script to the CI workflows, edit [.github/workflows/pregen_all.py](.github/workflows/pregen_all.py), and add your script alongside the rest of the scripts.
#### (Re)Generating QuickBuffers files
Regenerating QuickBuffers files requires the Protocol Buffers compiler (protoc), and the QuickBuffers plugin, which can be found on [their releases page](https://github.com/HebiRobotics/QuickBuffers/releases). Once you have both, you can pass their paths into the generation scripts with `--protoc` and `--quickbuf_plugin` and regenerate the files.

View File

@@ -1,4 +1,4 @@
Copyright (c) 2009-2025 FIRST and other WPILib contributors
Copyright (c) 2009-2026 FIRST and other WPILib contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@@ -1,23 +1,23 @@
## Publishing Third Party Dependencies
Currently the 3rd party deps are imgui, opencv, google test, libssh, and apriltaglib
Currently the 3rd party external deps are opencv, libssh, ceres, and gtsam.
For publishing these dependencies, the version needs to be manually updated in the publish.gradle file of their respective repository.
Then, in the azure build for the dependency you want to build for, manually start a pipeline build (As of current, this is the `Run Pipeline` button).
A variable needs to be added called `RUN_AZURE_ARTIFACTORY_RELEASE`, with a value of `true`. Then when the pipeline gets started, the final build outputs will be updated to artifactory.
Then, upload a new tag for the dependency you want to build for, which will automatically start a build.
The CI workflow should set `RUN_AZURE_ARTIFACTORY_RELEASE` to `true` on tagged runs. Then when the pipeline gets started, the final build outputs will be uploaded to artifactory.
To use newer versions of C++ dependencies, in `shared/config.gradle`, update the version related to the specific dependency.
For Java dependencies, there is likely a file related to the specific dependency in the shared folder. Update the version in there.
Note, changing artifact locations (This includes changing the artifact year currently, I have an issue open to change this) requires updating the `native-utils` plugin
Note, changing artifact locations requires updating the `native-utils` plugin; specifically, the `configureDependencies` method in the `WPINativeUtilsExtension` class.
## Publishing allwpilib
allwpilib publishes to the development repo on every push to main. To publish a release build, upload a new tag, and a release will automatically be built and published.
## Publishing desktop tools
Desktop tools publish to the development repo on every push to main. To publish a release build, upload a new tag, and a release will automatically be built and published.
### Adding a new robot code dependency/subproject
If a new subproject has been added that is meant for use from robot code, both GradleRIO and the `native-utils` plugin need to be updated. `native-utils` is updated in the same way as 3rd party dependencies. For GradleRIO, update the `WPIJavaDepsExtension` to contain your new subproject's artifacts.
## Publishing VS Code
Before publishing, make sure to update the gradlerio version in `vscode-wpilib/resources/gradle/version.txt` Also make sure the gradle wrapper version matches the wrapper required by gradlerio.
Before publishing, make sure to update the GradleRIO version in `vscode-wpilib/resources/gradle/version.txt`. Also make sure the Gradle Wrapper version matches the wrapper required by GradleRIO.
Upon pushing a tag, a release will be built, and the files will be uploaded to the releases on GitHub.
## Publishing GradleRIO

125
MODULE.bazel Normal file
View File

@@ -0,0 +1,125 @@
module(
name = "allwpilib",
version = "0.0.0",
)
include("//docs:doxygen.MODULE.bazel")
include("//shared/bazel/thirdparty/mrclib:mrclib.MODULE.bazel")
bazel_dep(name = "apple_support", version = "2.0.0", repo_name = "build_bazel_apple_support")
bazel_dep(name = "rules_cc", version = "0.2.17")
bazel_dep(name = "rules_pkg", version = "1.1.0")
bazel_dep(name = "bazel_features", version = "1.33.0")
bazel_dep(name = "aspect_bazel_lib", version = "2.14.0")
bazel_dep(name = "bazel_skylib", version = "1.8.2")
bazel_dep(name = "platforms", version = "1.0.0")
bazel_dep(name = "rules_java", version = "8.16.1")
bazel_dep(name = "rules_python", version = "1.7.0")
bazel_dep(name = "rules_pycross", version = "0.8.1")
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
python.toolchain(
python_version = "3.13",
)
use_repo(
python,
"python_3_13",
"python_3_13_x86_64-unknown-linux-gnu",
)
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
pip.parse(
hub_name = "allwpilib_pip_deps",
python_version = "3.13",
requirements_lock = "//:requirements_lock.txt",
requirements_windows = "//:requirements_windows_lock.txt",
)
use_repo(pip, "allwpilib_pip_deps")
bazel_dep(name = "rules_jvm_external", version = "6.8")
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
maven.install(
name = "maven",
artifacts = [
"org.ejml:ejml-simple:0.44.0",
"io.avaje:avaje-jsonb:3.14",
"io.avaje:avaje-jsonb-generator:3.14",
"us.hebi.quickbuf:quickbuf-runtime:1.4",
"com.google.code.gson:gson:2.13.1",
"org.wpilib.thirdparty.opencv:opencv-java:2027-4.13.0-1",
"org.junit.jupiter:junit-jupiter:5.10.1",
"org.junit.platform:junit-platform-console:1.10.1",
"org.junit.platform:junit-platform-launcher:1.10.1",
"org.junit.platform:junit-platform-reporting:1.10.1",
"org.hamcrest:hamcrest-all:1.3",
"com.googlecode.junit-toolbox:junit-toolbox:2.4",
"org.apache.ant:ant:1.10.12",
"org.apache.ant:ant-junit:1.10.12",
"org.mockito:mockito-core:4.1.0",
"com.google.testing.compile:compile-testing:0.21.0",
],
lock_file = "//:maven_install.json",
repositories = [
"https://repo1.maven.org/maven2",
"https://frcmaven.wpi.edu/artifactory/release/",
],
)
use_repo(maven, "maven", "unpinned_maven")
bazel_dep(name = "caseyduquettesc_rules_python_pytest", version = "1.1.1", repo_name = "rules_python_pytest")
bazel_dep(name = "eigen", version = "5.0.1")
local_path_override(
module_name = "eigen",
path = "wpimath/src/main/native/thirdparty/eigen/include",
)
bazel_dep(name = "rules_license", version = "1.0.0")
http_file = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
http_file(
name = "quickbuffer_protoc_linux",
executable = True,
sha256 = "02767f5f662720c121dfaaa9109aefa9b0b1e2415cbe1af9e4713a7b00663696",
urls = ["https://repo1.maven.org/maven2/us/hebi/quickbuf/protoc-gen-quickbuf/1.3.3/protoc-gen-quickbuf-1.3.3-linux-x86_64.exe"],
)
http_file(
name = "quickbuffer_protoc_osx_x86-64",
executable = True,
sha256 = "cdc0b4b188f944dddd4430bcd6f6266ca1aaf8c33940d7bee1ed63fc962d8525",
urls = ["https://repo1.maven.org/maven2/us/hebi/quickbuf/protoc-gen-quickbuf/1.3.3/protoc-gen-quickbuf-1.3.3-osx-x86_64.exe"],
)
http_file(
name = "quickbuffer_protoc_osx_aarch64",
executable = True,
sha256 = "95fa0a22ad2d9fa8f84a31cf3a0670b18c0ad954f73035f60cfb77c2814fb41c",
urls = ["https://repo1.maven.org/maven2/us/hebi/quickbuf/protoc-gen-quickbuf/1.3.3/protoc-gen-quickbuf-1.3.3-osx-aarch_64.exe"],
)
http_file(
name = "quickbuffer_protoc_windows",
executable = True,
sha256 = "8a30b2eaebefbedc3b592118670de1ab6ea1aa19dcf8cdab220e25485ccd4a0a",
urls = ["https://repo1.maven.org/maven2/us/hebi/quickbuf/protoc-gen-quickbuf/1.3.3/protoc-gen-quickbuf-1.3.3-windows-x86_64.exe"],
)
bazel_dep(name = "rules_bzlmodrio_toolchains", version = "2025-1.bcr6")
archive_override(
module_name = "rules_bzlmodrio_toolchains",
integrity = "sha256-ECtFB2KOlySwweRBcndiw0TkAXD2WsYFFhaBeOozqJo=",
urls = ["https://github.com/wpilibsuite/rules_bzlmodrio_toolchains/releases/download/2025-1.bcr6/rules_bzlmodrio_toolchains-2025-1.bcr6.tar.gz"],
)
bazel_dep(name = "protobuf", version = "32.1", repo_name = "com_google_protobuf")
http_jar = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar")
http_jar(
name = "com_github_google_copybara",
integrity = "sha256-IHW6y6WXJFjX9RYD+IwVAMwAbEo36fLqonIKR+FaqpQ=",
urls = ["https://github.com/google/copybara/releases/download/v20251027/copybara_deploy.jar"],
)

1168
MODULE.bazel.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -14,58 +14,31 @@ The development repository is where development releases of every commit to [mai
## Artifact classifiers
We provide two base types of artifacts.
The first types are Java artifacts. These are usually published as `jar` files. Usually, the actual jar file is published with no classifier. The sources are published with the `-sources` classifier, and the javadocs are published with the `-javadoc` classifier.
The second types are native artifacts. These are usually published as `zip` files (except for the `JNI` artifact types, which are `jar` files. See below for information on this). The `-sources` and `-headers` classifiers contain the sources and headers respectively for the library. Each artifact also contains a classifier for each platform we publish. This platform is in the format `{os}{arch}`. The platform artifact only contains the binaries for a specific platform. In addition, we provide a `-all` classifier. This classifier combines all of the platform artifacts into a single artifact. This is useful for tools that cannot determine what version to use during builds. However, we recommend using the platform specific classifier when possible. Note that the binary artifacts never contain the headers, you always need the `-headers` classifier to get those.
## Artifact Names
WPILib builds four different types of artifacts.
##### C++ Only Libraries
When we publish C++ only libraries, they are published with the base artifact name as their artifact name, with a `-cpp` extension. All dependencies for the library are linked as shared libraries to the binary.
The first types are Java artifacts. These are usually published as `jar` files. Usually, the actual jar file is published with no classifier. The sources are published with the `-sources` classifier, and the javadocs are published with the `-javadoc` classifier. These artifacts are published with the base artifact name as their artifact ID, with a `-java` extension.
Example:
```
edu.wpi.first.wpilibc:wpilibc-cpp:version:classifier@zip
org.wpilib.wpilibj:wpilibj-java:version
```
#### Java Only Libraries
When we publish Java only libraries, they are published with the base artifact name as their artifact name, with a `-java` extension.
The second types are native artifacts. These are usually published as `zip` files. The `-sources` and `-headers` classifiers contain the sources and headers respectively for the library. Each artifact also contains a classifier for each platform we publish. This platform is in the format `{os}{arch}`. The full list of supported platforms can be found in [native-utils in the Platforms nested class](https://github.com/wpilibsuite/native-utils/blob/main/src/main/java/org/wpilib/nativeutils/WPINativeUtilsExtension.java). If the library is built statically, it will have `static` appended to the classifier. Additionally, if the library was built in debug mode, `debug` will be appended to the classifier. The platform artifact only contains the binaries for a specific platform. Note that the binary artifacts never contain the headers, you always need the `-headers` classifier to get those.
If the library is Java and C++ and has a JNI component, the native artifact will have a shared library containing JNI entrypoints alongside the C++ shared library. This JNI shared library will have a `jni` suffix in the file name.
Native artifacts are published with the base artifact name as their artifact ID, with a `-cpp` extension.
Example:
```
edu.wpi.first.wpilibj:wpilibj-java:version
```
#### C++/Java Libraries without JNI
For libraries that are both C++ and Java, but without a JNI component, the C++ component is published with the `basename-cpp` artifact name, and the Java component is published with the `basename-java` artifact name.
Example:
```
edu.wpi.first.wpiutil:wpiutil-cpp:version:classifier@zip (C++)
edu.wpi.first.wpiutil:wpiutil-java:version (Java)
```
#### C++/Java Libraries with JNI
For libraries that are both C++ and Java with a JNI component there are three different artifact names. For Java, the component is published as `basename-java`. For C++, the `basename-cpp` artifact contains the C++ artifacts with all dependencies linked as shared libraries to the binary. These binaries DO contain the JNI entry points. The `basename-jni` artifact contains identical C++ binaries to the `-cpp` artifact, however all of its dependencies are statically linked, and only the JNI and C entry points are exported.
The `-jni` artifact should only be used in cases where you want to create a self contained Java application where the native artifacts are embedded in the jar. Note in an extraction scenario, extending off of the library is never supported, which is why the C++ entry points are not exposed. The name of the library is randomly generated during extraction. For pretty much all cases, and if you ever want to extend from a native library, you should use the `-cpp` artifacts. GradleRIO uses the `-cpp` artifacts for all platforms, even desktop, for this reason.
Example:
```
edu.wpi.first.ntcore:ntcore-cpp:version:classifier@zip (C++)
edu.wpi.first.ntcore:ntcore-jni:version:classifier (JNI jar library)
edu.wpi.first.ntcore:ntcore-java:version (Java)
org.wpilib.wpimath:wpimath-cpp:version:classifier@zip
org.wpilib.wpimath:wpimath-cpp:version:windowsx86-64staticdebug@zip
```
## Provided Artifacts
This repository provides the following artifacts. Below each artifact is its dependencies. Note if ever using the `-jni` artifacts, no dependencies are needed for native binaries.
This repository provides the following artifacts. Below each artifact is its dependencies.
For C++, if building with static dependencies, the listed order should be the link order in your linker.
All artifacts are based at `edu.wpi.first.artifactname` in the repository.
All artifacts are based at `org.wpilib.artifactname` in the repository.
* wpiutil
@@ -79,32 +52,33 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
* wpiutil
* ntcore
* wpiutil
* wpinet
* wpiutil
* glass/libglass
* wpiutil
* wpimath
* wpigui
* wpimath
* wpiutil
* glass/libglassnt
* wpiutil
* wpinet
* ntcore
* wpimath
* wpigui
* ntcore
* wpinet
* wpimath
* wpiutil
* hal
* ntcore
* wpiutil
* halsim
* wpiutil
* wpinet
* libglassnt
* libglass
* ntcore
* wpimath
* wpigui
* libglass
* libglassnt
* wpinet
* wpiutil
* cscore
* opencv
@@ -135,7 +109,7 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
* wpinet
* wpiutil
* wpilibNewCommands
* commandsv2
* wpilibc
* hal
* cameraserver
@@ -153,12 +127,16 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
### Third Party Artifacts
This repository provides the builds of the following third party software.
This repository provides the builds of the following third party software:
All artifacts are based at `edu.wpi.first.thirdparty.frcYEAR` in the repository.
* apriltaglib
* googletest
* imgui
* opencv
* libssh
Other software can be found in their corresponding GitHub repositories:
* ceres: https://github.com/wpilibsuite/thirdparty-ceres
* gtsam: https://github.com/wpilibsuite/thirdparty-gtsam
* opencv: https://github.com/wpilibsuite/thirdparty-opencv
* libssh: https://github.com/wpilibsuite/thirdparty-libssh
All artifacts are based at `org.wpilib.thirdparty` in the repository.

View File

@@ -1,10 +1,10 @@
# WPILib Bazel Support
WPILib is normally built with Gradle, but [Bazel](https://www.bazel.build/) can also be used to increase development speed due to the superior caching ability and the ability to use remote caching and remote execution (on select platforms)
WPILib is normally built with Gradle, but [Bazel](https://www.bazel.build/) can also be used to increase development speed due to the superior caching ability and the ability to use remote caching and remote execution (on select platforms).
## Prerequisites
- Install [Bazelisk](https://github.com/bazelbuild/bazelisk/releases) and add it to your path. Bazelisk is a wrapper that will download the correct version of bazel specified in the repository. Note: You can alias/rename the binary to `bazel` if you want to keep the familiar `bazel build` vs `bazelisk build` syntax.
- Install [Bazelisk](https://github.com/bazelbuild/bazelisk/releases) and add it to your path. Bazelisk is a wrapper that will download the correct version of Bazel specified in the repository. Note: You can alias/rename the binary to `bazel` if you want to keep the familiar `bazel build` vs `bazelisk build` syntax.
## Building
To build the entire repository, simply run `bazel build //...`. To run all of the unit tests, run `bazel test //...`
@@ -14,12 +14,42 @@ Other examples:
- `bazel coverage //wpiutil/...` - (*Nix only) - Runs a code coverage report for both C++ and Java on all the targets under wpiutil
## User settings
When invoking bazel, it will check if `user.bazelrc` exists for additional, user specified flags. You can use these settings to do things like always ignore buildin a specific folder, or limiting the CPU/RAM usage during a build.
When invoking Bazel, it will check if `user.bazelrc` exists for additional, user specified flags. You can use these settings to do things like always ignore builds in a specific folder, or limiting the CPU/RAM usage during a build.
Examples:
- `build --build_tag_filters=-wpi-example` - Do not build any targets tagged with `wpi-example` (Currently all of the targets in wpilibcExamples and wpilibjExamples contain this tag)
- `build -c opt` - Always build optimized targets. The default compiler flags were chosen to build as fast as possible, and thus don't contain many optimizations
- `build -k` - `-k` is analogous to the MAKE flag `--keep-going`, so the build will not stop on the first error.
- ```
build --local_ram_resources=HOST_RAM*.5 # Don't use more than half my RAM when building
build --local_cpu_resources=HOST_CPUS-1 # Leave one core alone
build --local_resources=memory=HOST_RAM*.5 # Don't use more than half my RAM when building
build --local_resources=cpu=HOST_CPUS-1 # Leave one core alone
```
Bazel's RAM usage estimation is simplistic and hardcoded, so limiting the allowed number of CPU cores is the best way to reduce memory usage if it becomes a problem.
The default settings build all the release artifact variants relevant for your platform. The overall list of options ends up being, essentially, all the variants of (linux, osx, windows) x (debug, release) x (static, shared) x (aarch64, x86). OSX and Windows are hard to compile for from any other OS, so we by default build for your local OS and the system core, with all the variants.
This can be a bit expensive. If you would like to build a subset, you can specify the repo environmental variable, `WPI_PUBLISH_CLASSIFIER_FILTER`, and pick what you build for. The default is, in the .bazelrc file,
```
common --repo_env="WPI_PUBLISH_CLASSIFIER_FILTER=headers,sources,linuxsystemcore,linuxsystemcoredebug,linuxsystemcorestatic,linuxsystemcorestaticdebug,linuxx86-64,linuxx86-64debug,linuxx86-64static,linuxx86-64staticdebug,osxuniversal,osxuniversaldebug,osxuniversalstatic,osxuniversalstaticdebug,windowsarm64,windowsarm64debug,windowsarm64static,windowsarm64staticdebug,windowsx86-64,windowsx86-64debug,windowsx86-64static,windowsx86-64staticdebug"
```
Modify this to your likings if you want to build less.
## Pregenerating Files
allwpilib uses extensive use of pre-generating files that are later used to build C++ / Java libraries that are tracked by version control. Quite often,
these pre-generation scripts use some configuration file to create multiple files inside of an output directory. While this process could be accomplished
with a `genrule` that would require an explicit listing of every output file, which would be tedious to maintain as well as potentially confusing to people
adding new features those libraries. Therefore, we use `@aspect_bazel_lib` and their `write_source_files` feature to generate these directories. In the event that the generation process creates more than a small handful of predictable files, a custom rule is written to generate the directory.
## Remote Caching
One of the huge benefits of Bazel is its remote caching ability. However, due to Bazel's strict build definitions, it is hard to share remote cache artifacts between different computers unless our toolchains are fully hermetic, which means you are unlikely to be able to reuse the cache artifacts published from the `main` branch on your local machine like you might be able to with the `gradle` or `cmake` caches. Luckily, the GitHub Actions CI machines are generally stable between runs and can reuse cache artifacts, and your local machine should remain stable, so if you set up a free buildbuddy account you can have your fork's CI actions be able to use a personalized cache, as well as your local machine.
For the main `allwpilib` upstream, the cache is only updated on the main branch; pull requests from forks will not be able to modify the cache. However, you can set up your fork to enable its own cache by following the steps below.
### Setting Up API keys
Follow the [buildbuddy authentication](https://www.buildbuddy.io/docs/guide-auth) guide to create keys. For your local machine, it is recommended that you place the following configuration line in either a `user.bazelrc` or `bazel_auth.rc` file in the repositories root directory.
```
build --remote_header=<your api key>
```
To get your forks CI actions using your own buildbuddy cache, follow [GitHub's](https://docs.github.com/en/actions/how-tos/security-for-github-actions/security-guides/using-secrets-in-github-actions) documentation for setting up a repository secret. The secrets key should be `BUILDBUDDY_API_KEY`, and the value should be your buildbuddy API key.

View File

@@ -1,22 +1,22 @@
# WPILib CMake Support
WPILib is normally built with Gradle, however for some systems, such as Linux based coprocessors, Gradle doesn't work correctly, especially if cscore is needed, which requires OpenCV. Furthermore, the CMake build can be used for C++ development because it provides better build caching compared to Gradle. We provide the CMake build for these cases. Although macOS is supported, these docs will only go over Linux and Windows builds, but should mostly work for macOS as well. If you are stuck, you can look at the GitHub workflows for any OS to see how it works.
WPILib is normally built with Gradle, however for some systems, such as Linux based coprocessors, Gradle doesn't work correctly, especially if cscore is needed, which requires OpenCV. Furthermore, the CMake build can be used for C++ development because it provides better build caching compared to Gradle. We provide the CMake build for these cases. Although macOS is supported, these docs will only go over Linux and Windows builds, but should mostly work for macOS as well. If you are stuck, you can look at the GitHub workflows for any OS to see how it works. The CMake build does not build Java or Python, only C++.
## Libraries that get built
* apriltag
* cameraserver
* commandsv2
* cscore
* fieldImages
* datalog
* fields
* hal (simulation HAL only)
* ntcore
* romiVendordep
* simulation extensions
* wpigui
* wpilib (wpilibc, wpilibj, and myRobot)
* wpilibNewCommands
* wpilib (wpilibc, wpilibj, and developerRobot)
* wpimath
* wpinet
* wpiunits
* wpiutil
* xrpVendordep
@@ -24,38 +24,28 @@ WPILib is normally built with Gradle, however for some systems, such as Linux ba
* datalogtool
* glass
* outlineviewer
* roborioteamnumbersetter
* sysid
* wpical
* halsim_gui (if simulation extensions are enabled)
By default, all libraries get built with a default CMake setup. The libraries are built as shared libraries, and include the JNI libraries as well as building the Java JARs. Data Log Tool and the roboRIO Team Number Setter are only built if libssh is available.
By default, all libraries get built with a default CMake setup. The libraries are built as shared libraries. Data Log Tool is only built if libssh is available.
## Prerequisites
The protobuf library and compiler are needed for protobuf generation.
OpenCV needs to be findable by CMake. On systems like the Jetson, this is installed by default. Otherwise, you will need to build OpenCV from source and install it.
If you want JNI and Java, you will need a JDK of at least version 17 installed. In addition, you need a `JAVA_HOME` environment variable set properly and set to the JDK directory.
If you are building with unit tests or simulation modules, you will also need an Internet connection for the initial setup process, as CMake will clone google-test and imgui from GitHub.
## Build Options
The following build options are available:
* `BUILD_SHARED_LIBS` (ON Default)
* This option will cause CMake to build static libraries instead of shared libraries. If this is off, `WITH_JAVA` must be off. Otherwise CMake will error.
* This option will cause CMake to build static libraries instead of shared libraries.
* `WITH_CSCORE` (ON Default)
* This option will cause cscore to be built. Turning this off will implicitly disable cameraserver. If this is off, the OpenCV build requirement is removed.
* `WITH_EXAMPLES` (OFF Default)
* This option will build C++ examples.
* `WITH_GUI` (ON Default)
* This option will build GUI items. If this is off, and `WITH_SIMULATION_MODULES` is on, the simulation GUI will not be built.
* `WITH_JAVA` (OFF Default)
* This option will enable Java and JNI builds. If this is on, `BUILD_SHARED_LIBS` must be on. Otherwise CMake will error.
* `WITH_JAVA_SOURCE` (`WITH_JAVA` Default)
* This option will build Java source JARs for each enabled Java library. This does not require `WITH_JAVA` to be on, allowing source JARs to be built without the compiled JARs if desired.
* `WITH_NTCORE` (ON Default)
* This option will cause ntcore to be built. Turning this off will implicitly disable wpinet, and will cause an error if `WITH_WPILIB` is enabled.
* `WITH_SIMULATION_MODULES` (ON Default)
@@ -63,15 +53,9 @@ The following build options are available:
* `WITH_TESTS` (ON Default)
* This option will build C++ unit tests. These can be run via `ctest -C <config>`, where `<config>` is the build configuration, e.g. `Debug` or `Release`.
* `WITH_WPILIB` (ON Default)
* This option will build the HAL and wpilibc/j during the build. The HAL is the simulation HAL, unless the external HAL options are used. The CMake build has no capability to build for the roboRIO.
* This option will build the HAL and wpilibc during the build. The HAL is the simulation HAL, unless the external HAL options are used. The CMake build has no capability to build for Systemcore.
* `WITH_WPIMATH` (ON Default)
* This option will build the wpimath library. This option must be on to build wpilib.
* `WITH_PROTOBUF` (ON Default)
* This option will build with the protobuf library.
* `WITH_WPIUNITS` (`WITH_JAVA` Default)
* This option will build the wpiunits library. This option must be on to build the Java wpimath library and requires `WITH_JAVA` to also be on.
* `OPENCV_JAVA_INSTALL_DIR`
* Set this option to the location of the archive of the OpenCV Java bindings (it should be called opencv-xxx.jar, with the x'es being version numbers). NOTE: set it to the LOCATION of the file, not the file itself!
* `NO_WERROR` (OFF Default)
* This option will disable the `-Werror` compilation flag for non-MSVC builds.
* `WPILIB_TARGET_WARNINGS`
@@ -91,15 +75,13 @@ If you want to change any of the options, add `-DOPTIONHERE=VALUE` to the `cmake
If you want, you can also use `ccmake` in order to visually set these properties as well. [Here](https://cmake.org/cmake/help/v3.0/manual/ccmake.1.html) is the link to the documentation for that program. On Windows, you can use `cmake-gui` instead.
Note that if you are cross-compiling, you will need to override the protobuf options manually to point to the libraries for the target platform. Leave the protoc binary location as the path to the binary for the host platform, since protoc needs to execute on the host platform.
## Presets
The WPILib CMake setup has a variety of presets for common configurations and options used. The default sets the generator to Ninja and build directory to `build-cmake`. The other presets are `with-java` (sets `WITH_JAVA=ON`), `sccache` (sets the C/C++ compiler launcher to sccache), and `with-java-sccache` (a comibination of `with-java` and `sccache`.
The WPILib CMake setup has a variety of presets for common configurations and options used. The default sets the generator to Ninja and build directory to `build-cmake`. The other preset is `sccache` (sets the C/C++ compiler launcher to sccache).
## Building
Once you have CMake setup. run `cmake --build .` from the directory you configured CMake in. This will build all libraries possible. We recommend running `cmake --build .` with multiple jobs. For allwpilib, a good rule of thumb is one worker for every 2 GB of available RAM. To run a multiple job build, run the following command with x being the number of jobs you want.
Once you have CMake setup. run `cmake --build .` from the directory you configured CMake in. This will build all libraries possible. We recommend running `cmake --build .` with multiple jobs. For allwpilib, a good rule of thumb is one worker for every 2 GB of available RAM. To run a multi-job build, run the following command with x being the number of jobs you want.
```
cmake --build . --parallel x
@@ -119,9 +101,9 @@ sudo cmake --build . --target install
## Preparing to use the installed libraries
On Windows, make sure the directories for the libraries you built are on PATH. For wpilib, the default install location is `C:\Program Files (x86)\allwpilib`. If you built other libraries like OpenCV and protobuf from source, install them, and add the install directories to PATH. This ensures CMake can locate the libraries.
On Windows, make sure the directories for the libraries you built are on PATH. For wpilib, the default install location is `C:\Program Files (x86)\allwpilib`. If you built other libraries like OpenCV from source, install them, and add the install directories to PATH. This ensures CMake can locate the libraries.
You will also want to add the directories where the DLLs are located (usually the `bin` subdirectory of the install directory) to PATH so they can be loaded by your program. If you are using OpenCV and Java, the `opencv_java` DLL is located in either the `lib` subdirectory if you built but didn't install OpenCV, or the `java` subdirectory if you did install OpenCV.
You will also want to add the directories where the DLLs are located (usually the `bin` subdirectory of the install directory) to PATH so they can be loaded by your program.
## Using the installed libraries for C++.
@@ -149,40 +131,9 @@ cmake /path/to/folder/containing/CMakeLists
After that, run `cmake --build .`. That will create your executable. Then you should be able to run `./my_vision_app` to run your application.
## Using the installed libraries for Java
Using the built JARs is more involved than using the C++ libraries, but the additional work involves providing the paths to various libraries and JARs when needed.
Create a new folder to contain your project. Add the following code below to a `CMakeLists.txt` file in that directory.
```cmake
cmake_minimum_required(VERSION 3.11)
project(robot)
find_package(Java REQUIRED COMPONENTS Development)
include(UseJava)
find_package(wpilib REQUIRED)
find_jar(opencvJar opencv-xxx PATHS ENV PATH) # Change to OpenCV version
file(GLOB_RECURSE JAVA_SOURCES *.java)
# If you want Gradle compatibility or you are using one of the templates/examples, comment out the above line and uncomment this line instead:
# file(GLOB_RECURSE JAVA_SOURCES src/main/java/*.java)
add_jar(robot ${JAVA_SOURCES}
INCLUDE_JARS apriltag_jar cscore_jar hal_jar ntcore_jar wpilibNewCommands_jar wpimath_jar wpinet_jar wpiutil_jar wpiunits_jar wpilibj_jar ${opencvJar})
export_jars(TARGETS robot FILE robot.jar)
```
This includes all the built JARs except for the vendordeps. If you are not using a JAR/library, you may remove it.
Add a `Main.java` file to contain your code, and create a build folder. Move into the build folder, and run
```
cmake /path/to/folder/containing/CMakeLists
```
After that, run `cmake --build .` to create your JAR file. To execute the JAR file, you need to include the wpilib JARs and your JAR in the classpath, and execute your Java program's entry point. If you are using cscore or cameraserver, you also need to include the path to the OpenCV JAR. If you built it from source, it will be in your OpenCV build directory. If it's installed on the system, CMake may find it from PATH, but you will likely need to locate the JAR and manually give CMake the JAR directory. If you are on Linux, you will also need to add the path of the libraries to `LD_LIBRARY_PATH`. This can be done by prepending `LD_LIBRARY_PATH=/path/to/libraries` to the Java command. If you need to add more paths, separate them with colons. The final command should look like `java -cp "robot.jar:/path/to/library_jars/*" main.package.Main`, using a semicolon to separate paths instead of a colon if you are on Windows. If you are on Linux, the final command should look more like `LD_LIBRARY_PATH=/path/to/libraries java -cp robot.jar:/path/to/library_jars/* main.package.Main`.
## Using vendordeps
Vendordeps are not included as part of the `wpilib` CMake package. However, if you want to use a vendordep, you need to use `find_package(VENDORDEP)`, where `VENDORDEP` is the name of the vendordep (case-sensitive), like `xrpVendordep` or `romiVendordep`. Note that wpilibNewCommands, while a vendordep in normal robot projects, is not built as a vendordep in CMake, and is instead included as part of the `wpilib` CMake package. After you used `find_package`, you can reference the vendordep library like normal, either by using `target_link_libraries` for C++ or `add_jar` for Java.
Vendordeps are not included as part of the `wpilib` CMake package. However, if you want to use a vendordep, you need to use `find_package(VENDORDEP)`, where `VENDORDEP` is the name of the vendordep (case-sensitive), like `xrpVendordep` or `romiVendordep`. Note that commandsv2, while a vendordep in normal robot projects, is not built as a vendordep in CMake, and is instead included as part of the `wpilib` CMake package. After you used `find_package`, you can reference the vendordep library like normal (using `target_link_libraries`).
## Troubleshooting
Below are some common issues that are run into when building.
@@ -210,31 +161,3 @@ CMake Error at cscore/CMakeLists.txt:3 (find_package):
```
If you get that, you need make sure OpenCV was installed, and then reattempt to configure. If that doesn't work, set the `OpenCV_DIR` variable to the directory where you built OpenCV.
#### Missing Java
If you are missing Java, you will get a message like the following.
```
CMake Error at /usr/share/cmake-3.5/Modules/FindPackageHandleStandardArgs.cmake:148 (message):
Could NOT find Java (missing: Java_JAVA_EXECUTABLE Java_JAR_EXECUTABLE
Java_JAVAC_EXECUTABLE Java_JAVAH_EXECUTABLE Java_JAVADOC_EXECUTABLE)
```
If this happens, make sure you have a JDK of at least version 8 installed, and that your JAVA_HOME variable is set properly to point to the JDK.
In addition, if you do not need Java, you can disable it with `-DWITH_JAVA=OFF`.
#### Java: Can't find dependent libraries
If one of the libraries can't be found, you will get an error similar to this one:
```
java.io.IOException: wpiHaljni could not be loaded from path or an embedded resource.
attempted to load for platform /windows/x86-64/
Last Load Error:
C:\Program Files (x86)\allwpilib\bin\wpiHaljni.dll: Can't find dependent libraries
```
If you get this error, that's usually an indication that not all your libraries are in your PATH. The two libraries that should be in your PATH are OpenCV and protobuf. If the error is coming from cscore, it's likely you're missing OpenCV. Otherwise, it's likely you're missing protobuf.
Note that Linux will not have this specific type of error, as it will usually tell you the dependent library you are missing. In that case, you most likely need to add the library to `LD_LIBRARY_PATH`.

96
README-RobotPy.md Normal file
View File

@@ -0,0 +1,96 @@
# robotpy in allwpilib
allwpilib hosts a mirror of RobotPy that can be built with Bazel on Linux. The intent of the mirror is to have breaking changes identified early and fixed by the PR creator so that when WPILib releases are made, there is much less work required to release a RobotPy version that wraps it. It is not a goal for allwpilib to replace the RobotPy repo; it will still be considered the "source of truth" for Python builds and will be responsible for building against all of the applicable architectures and multiple versions of Python.
## Build Process
The upstream RobotPy repository uses TOML configuration files and semiwrap to produce Meson build scripts. The allwpilib fork uses these TOML configuration files to auto-generate Bazel build scripts. In general, each project (wpiutil, wpimath, etc) defines two pybind extensions; one that simply wraps the native library, and another that adds extension(s) that and contains all of the Python files for the library. Both of these subprojects have auto-generated build files; a `robotpy_native_build_info.bzl` for the native wrapper and `robotpy_pybind_build_info.bzl` which defines the extensions and Python library.
## Disabling RobotPy builds
Building the RobotPy software on top of the standard C++/Java software can result in more than doubling the amount of time it takes to compile. To skip building the RobotPy tooling, you can add `--config=skip_robotpy` to the command line or to your `user.bazelrc`.
# Syncing with RobotPy
[Copybara](https://github.com/google/copybara) is used to maintain synchronization between the upstream RobotPy repositories and the allwpilib mirror. GitHub Actions can be manually run, which will create pull requests that will update all of the RobotPy files between the two repositories. The ideal process is that the allwpilib mirror is always building in CI, and once a release is created, the RobotPy team can run the `wpilib -> robotpy` Copybara task, make any fine tuned adjustments and create their release. In the event that additional changes are made on the RobotPy side, they can run the `robotpy -> wpilib` task to push the updates back to the mirror. However, the goal of the mirroring the software here is to be able to more rapidly test changes and will hopefully overwhelmingly eliminate the need for syncs in this direction.
## Creating a user config
The Copybara scripts needs to know information about what repositories it will be pushing the synced changes to. These can be specified on the command line, or you can create a `shared/bazel/copybara/.copybara.json` config file to save your personalized settings to avoid having to type things out every time. To run the full suite of migrations, you need a fork of [allwpilib](https://github.com/wpilibsuite/allwpilib), a fork of [mostrobotpy](https://github.com/robotpy/mostrobotpy), and a fork of RobotPy's [commands-v2](https://github.com/robotpy/robotpy-commands-v2). If you only wish to run a subset of commands (i.e. not sync the commands project), you do not need to include that in your user config.
Example config:
```json
{
"mostrobotpy_local_repo_path": "/home/<username>/git/robotpy/robotpy_monorepo/mostrobotpy",
"mostrobotpy_fork_repo": "https://github.com/<username>/mostrobotpy.git",
"allwpilib_fork_repo": "https://github.com/<username>/allwpilib.git",
"robotpy_commandsv2_fork_repo": "https://github.com/<username>/robotpy-commands-v2.git"
}
```
## Running syncs
- **Pulling changes from mostrobotpy**:
`python3 shared/bazel/copybara/run_copybara.py mostrobotpy_to_allwpilib`
- **Pulling changes from the commands library**:
`python3 shared/bazel/copybara/run_copybara.py commandsv2_to_allwpilib`
- **Pushing changes to the commands library**:
`python3 shared/bazel/copybara/run_copybara.py allwpilib_to_commandsv2`
- **Pushing changes to mostrobotpy**:
This process is slightly more complicated, because you will almost certainly also need to update the Maven artifacts that mostrobopy is using. Because of this, you must also specify the version number that has been published to WPILib's Maven repository. If you are trying to get an early, non-released development build pushed over, you can also add the `--development_build` flag:
`python3 shared/bazel/copybara/run_copybara.py allwpilib_to_mostrobotpy --wpilib_bin_version=2027.0.0-alpha-3-86-g418b381 --development_build -y`
# Debugging Build Errors
The build process is highly automated and automatically parses C++ header files to generate pybind11 bindings. Some of these steps here are considered "pregeneration" steps, and the Bazel build system will update build files as necessary. If a new header is added, or if the contents of a header file has changed, some of the pregeneration scripts might need to be run. If you encounter an error building `robotpy` code, it is recommended that you go through these steps to make sure everything is set up correctly. The examples are for `wpilibc`, but similar build tasks and tests exist for each wrapped project.
## 1. scan-headers
This can be the first source of problems if a new header file has been added. `semiwrap` will look through all of the headers for a library and notify you if a file is not covered by the projects `pyproject.toml` file. Bazel has a test case to ensure the files are up to date.
An example test failure when a new header being introduced. You can run the test with the following command:
bazel run //wpilibc:robotpy-wpilib-scan-headers
```
# wpi
ExpansionHub = "wpi/ExpansionHub.hpp"
ExpansionHubCRServo = "wpi/ExpansionHubCRServo.hpp"
ExpansionHubMotor = "wpi/ExpansionHubMotor.hpp"
ExpansionHubPidConstants = "wpi/ExpansionHubPidConstants.hpp"
ExpansionHubServo = "wpi/ExpansionHubServo.hpp"
```
To fix this, you can copy the lines from the console, and add them to the pyproject.toml file, located here `wpilibc/src/main/python/pyproject.toml`
## 2. update-yaml
This process parses all of the header files, and creates a representation of the classes / enums / etc in YAML. Occasionally, some functions might be ignored or need custom pybind code, which can be added to these files by the user.
There is a Bazel task that you can run to automatically update the files:
`bazel run //wpilibc:write_robotpy-wpilib-update-yaml`
## 3. generate-build-info
This step takes the yaml files, and auto-generates a Bazel build script for the library.
There is a Bazel task that you can run to automatically update the files:
`bazel run //wpilibc:robotpy-wpilib-generator.generate_build_info`
## semiwrap errors
If all of the above steps go smoothly and have their tests pass, but the generated cpp files still won't compile, it is possible that either an update needs to be made to the semiwrap tool to handle the new complex functionality, the new functionality can be ignored, or the new functionality might be better handled with a custom pybind11 implementation. In any case, it is best to reach out to the RobotPy team for guidance.
## Running multiple projects at once
Each project has its own `scan-headers` and various pregeneration tools, but you can run all of them at once with the following commands. Note: Sometimes if something in the dependency chain for a library fails, these amalgamation commands will also fail. If that happens, fix your way up the dependency chain project by project.
```
# Scan Headers
bazel test //... -k --test_tag_filters=robotpy_scan_headers --build_tests_only
# All pregen
bazel run //:write_robotpy_files
```

View File

@@ -3,8 +3,9 @@
[![Gradle](https://github.com/wpilibsuite/allwpilib/actions/workflows/gradle.yml/badge.svg?branch=main)](https://github.com/wpilibsuite/allwpilib/actions/workflows/gradle.yml)
[![C++ Documentation](https://img.shields.io/badge/documentation-c%2B%2B-blue)](https://github.wpilib.org/allwpilib/docs/development/cpp/)
[![Java Documentation](https://img.shields.io/badge/documentation-java-orange)](https://github.wpilib.org/allwpilib/docs/development/java/)
[![Python Documentation](https://img.shields.io/badge/documentation-python-blue)](https://robotpy.readthedocs.io/projects/robotpy/en/latest/)
Welcome to the WPILib project. This repository contains the HAL, WPILibJ, and WPILibC projects. These are the core libraries for creating robot programs for the roboRIO.
Welcome to the WPILib project. This repository contains the HAL, CameraServer, Commands (v2 and v3), NTCore, WPIMath, and WPILib projects. These are the core libraries for creating robot programs for Systemcore.
- [WPILib Project](#wpilib-project)
- [WPILib Mission](#wpilib-mission)
@@ -25,7 +26,7 @@ Welcome to the WPILib project. This repository contains the HAL, WPILibJ, and WP
## WPILib Mission
The WPILib Mission is to enable FIRST Robotics teams to focus on writing game-specific software rather than focusing on hardware details - "raise the floor, don't lower the ceiling". We work to enable teams with limited programming knowledge and/or mentor experience to be as successful as possible, while not hampering the abilities of teams with more advanced programming capabilities. We support Kit of Parts control system components directly in the library. We also strive to keep parity between major features of each language (Java, C++, Python, and NI's LabVIEW), so that teams aren't at a disadvantage for choosing a specific programming language. WPILib is an open source project, licensed under the BSD 3-clause license. You can find a copy of the license [here](LICENSE.md).
The WPILib Mission is to enable FIRST Robotics Competition (FRC) and FIRST Tech Challenge (FTC) teams to focus on writing game-specific software rather than focusing on hardware details - "raise the floor, don't lower the ceiling". We work to enable teams with limited programming knowledge and/or mentor experience to be as successful as possible, while not hampering the abilities of teams with more advanced programming capabilities. We support the FRC Kit of Parts/FTC control system components directly in the library. We also strive to keep parity between major features of each language (Java, C++, and Python), so that teams aren't at a disadvantage for choosing a specific programming language. WPILib is an open source project, licensed under the BSD 3-clause license. You can find a copy of the license [here](LICENSE.md).
# Quick Start
@@ -38,28 +39,28 @@ Below is a list of instructions that guide you through cloning, building, publis
# Building WPILib
Using Gradle makes building WPILib very straightforward. It only has a few dependencies on outside tools, such as the ARM cross compiler for creating roboRIO binaries.
Using Gradle makes building WPILib very straightforward. It only has a few dependencies on outside tools, such as the ARM cross compiler for creating Systemcore binaries.
## Requirements
- [JDK 17](https://adoptium.net/temurin/releases/?version=17)
- [JDK 25](https://adoptium.net/temurin/releases/?version=25)
- Note that the JRE is insufficient; the full JDK is required
- On Ubuntu, run `sudo apt install openjdk-17-jdk`
- On Windows, install the JDK 17 .msi from the link above
- On macOS, install the JDK 17 .pkg from the link above
- On Ubuntu, run `sudo apt install openjdk-25-jdk`
- On Windows, install the JDK 25 .msi from the link above
- On macOS, install the JDK 25 .pkg from the link above
- C++ compiler
- On Linux, install GCC 11 or greater
- On Windows, install [Visual Studio Community 2022](https://visualstudio.microsoft.com/vs/community/) and select the C++ programming language during installation (Gradle can't use the build tools for Visual Studio)
- On macOS, install the Xcode command-line build tools via `xcode-select --install`. Xcode 13 or later is required.
- ARM compiler toolchain
- Run `./gradlew installRoboRioToolchain` after cloning this repository
- If the WPILib installer was used, this toolchain is already installed
- On macOS, install the Xcode command-line build tools via `xcode-select --install`. Xcode 14 or later is required.
- Raspberry Pi toolchain (optional)
- Run `./gradlew installArm32Toolchain` after cloning this repository
- Run `./gradlew installArm64Toolchain` after cloning this repository
- Systemcore toolchain (required for Systemcore development)
- Run `./gradlew installSystemCoreToolchain` after cloning this repository
- If the WPILib installer was used, this toolchain is already installed
On macOS ARM, run `softwareupdate --install-rosetta`. This is necessary to be able to use the macOS x86 roboRIO toolchain on ARM.
On macOS ARM, run `softwareupdate --install-rosetta`. This is necessary to be able to use the macOS x86 Systemcore toolchain on ARM.
On linux, run `sudo apt install gfortran`. This is necessary to be able to build WPIcal on linux platforms.
On linux, run `sudo apt install libx11-dev libgl-dev libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev` to be able to build things depending on glfw.
## Setup
@@ -100,7 +101,7 @@ If opening from a fresh clone, generated java dependencies will not exist. Most
- `cscore`
- `hal`
- `ntcore`
- `wpilibNewCommands`
- `commandsv2`
- `wpimath`
- `wpinet`
- `wpiunits`
@@ -126,16 +127,19 @@ Please read the documentation available [here](DevelopmentBuilds.md)
### Custom toolchain location
If you have installed the FRC Toolchain to a directory other than the default, or if the Toolchain location is not on your System PATH, you can pass the `toolChainPath` property to specify where it is located. Example:
If you have installed the WPILib Toolchain to a directory other than the default, or if the Toolchain location is not on your System PATH, you can pass the `toolChainPath` property to specify where it is located. Example:
```bash
./gradlew build -PtoolChainPath=some/path/to/frc/toolchain/bin
./gradlew build -PtoolChainPath=some/path/to/wpilib/toolchain/bin
```
### Formatting/linting
Once a PR has been submitted, formatting can be run in CI by commenting `/format` on the PR. A new commit will be pushed with the formatting changes.
> [!NOTE]
> The `/format` action has been temporarily disabled. The individual formatting commands can be run locally as shown below. Alternately, the Lint and Format action for a PR will upload a patch file that can be downloaded and applied manually.
#### wpiformat
wpiformat can be executed anywhere in the repository via `py -3 -m wpiformat` on Windows or `python3 -m wpiformat` on other platforms.
@@ -177,15 +181,15 @@ If you are building to test with other dependencies or just want to export the b
- stable - Publishes to ~/releases/maven/stable.
- release - Publishes to ~/releases/maven/release.
The maven artifacts are described in [MavenArtifacts.md](MavenArtifacts.md)
The Maven artifacts are described in [MavenArtifacts.md](MavenArtifacts.md)
## Structure and Organization
The main WPILib code you're probably looking for is in WPILibJ and WPILibC. Those directories are split into shared, sim, and athena. Athena contains the WPILib code meant to run on your roboRIO. Sim is WPILib code meant to run on your computer, and shared is code shared between the two. Shared code must be platform-independent, since it will be compiled with both the ARM cross-compiler and whatever desktop compiler you are using (g++, msvc, etc...).
The main WPILib code you're probably looking for is in WPILibJ and WPILibC. Those directories contain the high-level hardware/robot classes used for interacting with hardware, the Driver Station, and contain the core framework that almost all robot projects use.
The integration test directories for C++ and Java contain test code that runs on our test-system. When you submit code for review, it is tested by those programs. If you add new functionality you should make sure to write tests for it so we don't break it in the future.
The src/test directories under each subproject for C++ and Java contain test code that runs on GitHub Actions. When you submit code for review, it is tested by GitHub Actions' runners. If you add new functionality you should make sure to write tests for it so we don't break it in the future.
The hal directory contains more C++ code meant to run on the roboRIO. HAL is an acronym for "Hardware Abstraction Layer", and it interfaces with the NI Libraries. The NI Libraries contain the low-level code for controlling devices on your robot. The NI Libraries are found in the [ni-libraries](https://github.com/wpilibsuite/ni-libraries) project.
The hal directory contains more C++ code meant to run on Systemcore. HAL is an acronym for "Hardware Abstraction Layer", and it interfaces with the robot controller to enable hardware interactions. The HAL is split into cpp, sim, and systemcore. The systemcore directory contains the WPILib code meant to run on your Systemcore. Sim is WPILib code meant to run on your computer, and cpp is code shared between the two. Code in the cpp directory must be platform-independent, since it will be compiled with both the ARM cross-compiler and whatever desktop compiler you are using (g++, MSVC, etc...).
The upstream_utils directory contains scripts for updating copies of thirdparty code in the repository.

View File

@@ -19,43 +19,39 @@ Google Test thirdparty/googletest/include
thirdparty/googletest/src
LLVM wpiutil/src/main/native/thirdparty/llvm
wpiutil/src/test/native/cpp/llvm/
JSON for Modern C++ wpiutil/src/main/native/thirdparty/json
wpiutil/src/test/native/cpp/json/
JSON for Classic C++ wpiutil/src/main/native/thirdparty/json
libuv wpinet/src/main/native/thirdparty/libuv/
fmtlib wpiutil/src/main/native/thirdparty/fmtlib/
sigslot wpiutil/src/main/native/thirdparty/sigslot
tcpsockets wpinet/src/main/native/thirdparty/tcpsockets
MPack wpiutil/src/main/native/thirdparty/mpack
Bootstrap wpinet/src/main/native/resources/bootstrap-*
CoreUI wpinet/src/main/native/resources/coreui-*
Feather Icons wpinet/src/main/native/resources/feather-*
jQuery wpinet/src/main/native/resources/jquery-*
popper.js wpinet/src/main/native/resources/popper-*
units wpimath/src/main/native/include/units/
units wpimath/src/main/native/include/wpi/units/
Eigen wpimath/src/main/native/thirdparty/eigen/include/
StackWalker wpiutil/src/main/native/windows/StackWalker.*
Team 254 Library wpimath/src/main/java/edu/wpi/first/math/spline/SplineParameterizer.java
wpimath/src/main/java/edu/wpi/first/math/trajectory/TrajectoryParameterizer.java
wpimath/src/main/native/include/frc/spline/SplineParameterizer.h
wpimath/src/main/native/include/frc/trajectory/TrajectoryParameterizer.h
Team 254 Library wpimath/src/main/java/org/wpilib/math/spline/SplineParameterizer.java
wpimath/src/main/java/org/wpilib/math/trajectory/TrajectoryParameterizer.java
wpimath/src/main/native/include/wpi/math/spline/SplineParameterizer.hpp
wpimath/src/main/native/include/wpi/math/trajectory/TrajectoryParameterizer.hpp
wpimath/src/main/native/cpp/trajectory/TrajectoryParameterizer.cpp
Portable File Dialogs wpigui/src/main/native/include/portable-file-dialogs.h
V8 export-template wpiutil/src/main/native/include/wpi/SymbolExports.h
Portable File Dialogs wpigui/src/main/native/include/wpi/gui/portable-file-dialogs.h
V8 export-template wpiutil/src/main/native/include/wpi/SymbolExports.hpp
GCEM wpimath/src/main/native/thirdparty/gcem/include/
Sleipnir wpimath/src/main/native/thirdparty/sleipnir
Debugging wpiutil/src/main/native/thirdparty/debugging
argparse wpiutil/src/main/native/thirdparty/argparse/include/wpi/argparse.h
double-conversion wpiutil/src/main/native/thirdparty/double-conversion
argparse wpiutil/src/main/native/thirdparty/argparse/include/wpi/util/argparse.hpp
apriltag apriltag/src/main/native/thirdparty/apriltag
glfw thirdparty/imgui_suite/glfw
Dear ImGui thirdparty/imgui_suite/imgui
implot thirdparty/imgui_suite/implot
memory wpiutil/src/main/native/thirdparty/memory
nanopb wpiutil/src/main/native/thirdparty/nanopb
protobuf wpiutil/src/main/native/thirdparty/protobuf
mrcal wpical/src/main/native/thirdparty/mrcal
libdogleg wpical/src/main/native/thirdparty/libdogleg
upb wpiutil/src/main/native/thirdparty/upb
mrcal tools/wpical/src/main/native/thirdparty/mrcal
libdogleg tools/wpical/src/main/native/thirdparty/libdogleg
Simd hal/src/main/native/systemcore/simd
AdvantageScope fields/src/main/native/resources/org/wpilib/fields/ftc
Avahi wpinet/src/main/native/linux/AvahiClient.hpp
Additionally, glfw, memory, and nanopb were all modified for use in WPILib.
Additionally, glfw and nanopb were modified for use in WPILib.
==============================================================================
Google Test License
@@ -370,35 +366,22 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.
==============================================================================
JSON for Modern C++ License
==============================================================================
============================
JSON for Classic C++ License
============================
Copyright 2024 Mozilla Foundation
__ _____ _____ _____
__| | __| | | | JSON for Modern C++
| | |__ | | | | | | version 2.1.1
|_____|_____|_____|_|___| https://github.com/nlohmann/json
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
Copyright (c) 2013-2017 Niels Lohmann <http://nlohmann.me>.
http://www.apache.org/licenses/LICENSE-2.0
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================
@@ -499,128 +482,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
==============================================================================
Bootstrap License
==============================================================================
Copyright (c) 2011-2018 Twitter, Inc.
Copyright (c) 2011-2018 The Bootstrap Authors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
==============================================================================
CoreUI License
==============================================================================
Copyright (c) 2018 creativeLabs tukasz Holeczek.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
==============================================================================
Feather Icons License
==============================================================================
Copyright (c) 2013-2017 Cole Bemis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
==============================================================================
jQuery License
==============================================================================
Copyright JS Foundation and other contributors, https://js.foundation/
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
==============================================================================
popper.js License
==============================================================================
Copyright (c) 2016 Federico Zivolo and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
=============
units License
=============
@@ -1025,35 +886,6 @@ Exhibit B - "Incompatible With Secondary Licenses" Notice
defined by the Mozilla Public License, v. 2.0.
===================
StackWalker License
===================
Copyright (c) 2005-2013, Jochen Kalmbach
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
Neither the name of Jochen Kalmbach nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================
Team 254 Library
================
@@ -1214,6 +1046,36 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
=========================
double-conversion License
=========================
Copyright 2006-2011, the V8 project authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================
argparse License
================
@@ -1360,31 +1222,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
==============
memory License
==============
Copyright (C) 2015-2023 Jonathan Müller and foonathan/memory contributors
This software is provided 'as-is', without any express or
implied warranty. In no event will the authors be held
liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute
it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented;
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but
is not required.
2. Altered source versions must be plainly marked as such,
and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any
source distribution.
==============
nanopb License
==============
@@ -1410,7 +1247,7 @@ redistribute it freely, subject to the following restrictions:
distribution.
================
protobuf License
upb License
================
Copyright 2008 Google Inc. All rights reserved.
@@ -1702,3 +1539,566 @@ This program is free software: you can redistribute it and/or modify it under th
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
The full text of the license is available at http://www.gnu.org/licenses
============
Simd License
============
MIT License
Copyright (c) 2011-2017 Ihar Yermalayeu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
============
AdvantageScope License
============
Copyright (c) 2021-2026 Littleton Robotics. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of Littleton Robotics, FRC 6328 ("Mechanical Advantage"),
AdvantageScope, nor the names of other AdvantageScope contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY LITTLETON ROBOTICS AND OTHER ADVANTAGESCOPE
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY NONINFRINGEMENT
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
LITTLETON ROBOTICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============
Avahi License
=============
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
<https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Moe Ghoul>, 1 April 1990
Moe Ghoul, President of Vice
That's all there is to it!

119
WORKSPACE
View File

@@ -1,119 +0,0 @@
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# Download Extra java rules
http_archive(
name = "rules_jvm_external",
sha256 = "08ea921df02ffe9924123b0686dc04fd0ff875710bfadb7ad42badb931b0fd50",
strip_prefix = "rules_jvm_external-6.1",
url = "https://github.com/bazelbuild/rules_jvm_external/releases/download/6.1/rules_jvm_external-6.1.tar.gz",
)
load("@rules_jvm_external//:repositories.bzl", "rules_jvm_external_deps")
rules_jvm_external_deps()
load("@rules_jvm_external//:defs.bzl", "maven_install")
maven_artifacts = [
"org.ejml:ejml-simple:0.43.1",
"com.fasterxml.jackson.core:jackson-annotations:2.15.2",
"com.fasterxml.jackson.core:jackson-core:2.15.2",
"com.fasterxml.jackson.core:jackson-databind:2.15.2",
"us.hebi.quickbuf:quickbuf-runtime:1.3.3",
"com.google.code.gson:gson:2.10.1",
]
maven_install(
name = "maven",
artifacts = maven_artifacts,
repositories = [
"https://repo1.maven.org/maven2",
"https://frcmaven.wpi.edu/artifactory/release/",
],
)
# Download toolchains
http_archive(
name = "rules_bzlmodrio_toolchains",
sha256 = "fe267e2af53c1def1e962700a9aeda9e8fdfa9fb46b72167c615ec0e25447dd6",
url = "https://github.com/wpilibsuite/rules_bzlmodRio_toolchains/releases/download/2025-1/rules_bzlmodRio_toolchains-2025-1.tar.gz",
)
load("@rules_bzlmodrio_toolchains//:maven_deps.bzl", "setup_legacy_setup_toolchains_dependencies")
setup_legacy_setup_toolchains_dependencies()
load("@rules_bzlmodrio_toolchains//toolchains:load_toolchains.bzl", "load_toolchains")
load_toolchains()
#
http_archive(
name = "rules_bzlmodrio_jdk",
sha256 = "a00d5fa971fbcad8a17b1968cdc5350688397035e90b0cb94e040d375ecd97b4",
url = "https://github.com/wpilibsuite/rules_bzlmodRio_jdk/releases/download/17.0.8.1-1/rules_bzlmodRio_jdk-17.0.8.1-1.tar.gz",
)
load("@rules_bzlmodrio_jdk//:maven_deps.bzl", "setup_legacy_setup_jdk_dependencies")
setup_legacy_setup_jdk_dependencies()
register_toolchains(
"@local_roborio//:macos",
"@local_roborio//:linux",
"@local_roborio//:windows",
"@local_raspi_32//:macos",
"@local_raspi_32//:linux",
"@local_raspi_32//:windows",
"@local_bullseye_32//:macos",
"@local_bullseye_32//:linux",
"@local_bullseye_32//:windows",
"@local_bullseye_64//:macos",
"@local_bullseye_64//:linux",
"@local_bullseye_64//:windows",
"@local_bookworm_32//:macos",
"@local_bookworm_32//:linux",
"@local_bookworm_32//:windows",
"@local_bookworm_64//:macos",
"@local_bookworm_64//:linux",
"@local_bookworm_64//:windows",
)
setup_legacy_setup_jdk_dependencies()
http_archive(
name = "bzlmodrio-ni",
sha256 = "197fceac88bf44fb8427d5e000b0083118d3346172dd2ad31eccf83a5e61b3ce",
url = "https://github.com/wpilibsuite/bzlmodRio-ni/releases/download/2025.0.0/bzlmodRio-ni-2025.0.0.tar.gz",
)
load("@bzlmodrio-ni//:maven_cpp_deps.bzl", "setup_legacy_bzlmodrio_ni_cpp_dependencies")
setup_legacy_bzlmodrio_ni_cpp_dependencies()
http_archive(
name = "bzlmodrio-opencv",
sha256 = "4f4a607956ca8555618736c3058dd96e09d02df19e95088c1e352d2319fd70c7",
url = "https://github.com/wpilibsuite/bzlmodRio-opencv/releases/download/2025.4.10.0-2/bzlmodRio-opencv-2025.4.10.0-2.tar.gz",
)
load("@bzlmodrio-opencv//:maven_cpp_deps.bzl", "setup_legacy_bzlmodrio_opencv_cpp_dependencies")
setup_legacy_bzlmodrio_opencv_cpp_dependencies()
load("@bzlmodrio-opencv//:maven_java_deps.bzl", "setup_legacy_bzlmodrio_opencv_java_dependencies")
setup_legacy_bzlmodrio_opencv_java_dependencies()
http_archive(
name = "build_bazel_apple_support",
sha256 = "c4bb2b7367c484382300aee75be598b92f847896fb31bbd22f3a2346adf66a80",
url = "https://github.com/bazelbuild/apple_support/releases/download/1.15.1/apple_support.1.15.1.tar.gz",
)
load(
"@build_bazel_apple_support//lib:repositories.bzl",
"apple_support_dependencies",
)
apple_support_dependencies()

47
WORKSPACE.bzlmod Normal file
View File

@@ -0,0 +1,47 @@
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("//thirdparty/ceres:repositories.bzl", "ceres_repositories")
ceres_repositories()
http_archive(
name = "pybind11_bazel",
integrity = "sha256-iwRj1wuX2pDS6t6DqiCfhIXisv4y+7CvxSJtZoSAzGw=",
strip_prefix = "pybind11_bazel-2b6082a4d9d163a52299718113fa41e4b7978db5",
urls = ["https://github.com/pybind/pybind11_bazel/archive/2b6082a4d9d163a52299718113fa41e4b7978db5.tar.gz"],
)
http_archive(
name = "pybind11",
build_file = "@pybind11_bazel//:pybind11-BUILD.bazel",
integrity = "sha256-LyCgrwuSGBXg4Wnqf+xjkJhpMjWBuJ194VU0aFU/ai0=",
strip_prefix = "pybind11-3.0.2",
url = "https://github.com/pybind/pybind11/archive/refs/tags/v3.0.2.tar.gz",
)
http_archive(
name = "bzlmodrio-opencv",
sha256 = "947df6f399593a54779b7706da8abaa43865769e02b15533519c800e23be419f",
url = "https://github.com/wpilibsuite/bzlmodRio-opencv/releases/download/2027.4.13.0-3/bzlmodRio-opencv-2027.4.13.0-3.tar.gz",
)
load("@bzlmodrio-opencv//:maven_cpp_deps.bzl", "setup_legacy_bzlmodrio_opencv_cpp_dependencies")
setup_legacy_bzlmodrio_opencv_cpp_dependencies()
http_archive(
name = "bzlmodrio-libssh",
sha256 = "f8fef627c7b393f7f6ed638e12b80ff90b2cfea11488b15214f25ce1e470723a",
url = "https://github.com/wpilibsuite/bzlmodRio-libssh/releases/download/2024.0.105-1.bcr1/bzlmodrio-libssh-2024.0.105-1.bcr1.tar.gz",
)
load("@bzlmodrio-libssh//:maven_cpp_deps.bzl", "setup_legacy_bzlmodrio_libssh_cpp_dependencies")
setup_legacy_bzlmodrio_libssh_cpp_dependencies()
# Capture the repository environmental variables which specify the filter list for what architectures to build in CI.
load("//shared/bazel/rules:publishing_rule.bzl", "publishing_repo")
publishing_repo(
name = "com_wpilib_allwpilib_publishing_config",
)

View File

@@ -1,21 +1,46 @@
load("@allwpilib_pip_deps//:requirements.bzl", "requirement")
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test")
load("@rules_java//java:defs.bzl", "java_binary", "java_library")
load("@rules_java//java:defs.bzl", "java_binary")
load("@rules_pkg//:mappings.bzl", "pkg_files")
load("@rules_python//python:defs.bzl", "py_binary")
load("//apriltag:robotpy_native_build_info.bzl", "define_native_wrapper")
load("//apriltag:robotpy_pybind_build_info.bzl", "apriltag_extension", "define_pybind_library")
load("//shared/bazel/rules:cc_rules.bzl", "wpilib_cc_library", "wpilib_cc_shared_library", "wpilib_cc_static_library")
load("//shared/bazel/rules:java_rules.bzl", "wpilib_java_junit5_test")
load("//shared/bazel/rules:jni_rules.bzl", "wpilib_jni_cc_library", "wpilib_jni_java_library")
load("//shared/bazel/rules:packaging.bzl", "package_default_jni_project")
load("//shared/bazel/rules/gen:gen-resources.bzl", "generate_resources")
load("//shared/bazel/rules/robotpy:build_info_gen.bzl", "generate_robotpy_native_wrapper_build_info", "generate_robotpy_pybind_build_info")
load("//shared/bazel/rules/robotpy:pytest_util.bzl", "robotpy_py_test")
filegroup(
name = "doxygen-files",
srcs = glob([
"src/main/native/include/**/*",
"src/main/native/thirdparty/apriltag/include/**/*",
]),
visibility = ["//visibility:public"],
)
pkg_files(
name = "thirdparty-apriltag-src-pkg",
srcs = glob(["src/main/native/thirdparty/apriltag/include/**"]),
strip_prefix = "src/main/native/thirdparty/apriltag/include",
)
cc_library(
name = "thirdparty-apriltag",
srcs = glob(["src/main/native/thirdparty/apriltag/src/**"]),
hdrs = glob(["src/main/native/thirdparty/apriltag/include/**"]),
copts = select({
"@bazel_tools//src/conditions:darwin": [
"@platforms//os:osx": [
"-Wno-format-nonliteral",
"-Wno-gnu-zero-variadic-macro-arguments",
"-Wno-uninitialized",
"-Wno-sign-compare",
"-Wno-type-limits",
],
"@bazel_tools//src/conditions:windows": [
"@platforms//os:windows": [
"/wd4005",
"/wd4018",
"/wd4244",
@@ -31,37 +56,93 @@ cc_library(
}),
includes = ["src/main/native/thirdparty/apriltag/include/common"],
strip_include_prefix = "src/main/native/thirdparty/apriltag/include",
visibility = ["//visibility:public"],
)
generate_resources(
name = "generate-resources",
namespace = "frc",
namespace = "wpi::apriltag",
prefix = "APRILTAG",
resource_files = glob(["src/main/native/resources/**"]),
visibility = ["//visibility:public"],
)
cc_library(
name = "apriltag.static",
wpilib_cc_library(
name = "apriltag",
srcs = [":generate-resources"] + glob(
["src/main/native/cpp/**"],
exclude = ["src/main/native/cpp/jni/**"],
),
hdrs = glob(["src/main/native/include/**/*"]),
defines = ["WPILIB_EXPORTS"],
extra_hdr_pkg_files = [":thirdparty-apriltag-src-pkg"],
extra_src_pkg_files = [":apriltag-java-jni-hdrs-pkg"],
local_defines = ["WPILIB_EXPORTS"],
strip_include_prefix = "src/main/native/include",
visibility = ["//visibility:public"],
deps = [
":thirdparty-apriltag",
"//wpimath:wpimath.static",
"//wpiutil:wpiutil.static",
"//wpimath",
"//wpiutil",
],
)
java_library(
wpilib_cc_shared_library(
name = "shared/apriltag",
auto_export_windows_symbols = False,
dynamic_deps = [
"//wpimath:shared/wpimath",
"//wpiutil:shared/wpiutil",
],
visibility = ["//visibility:public"],
deps = [
":apriltag",
":thirdparty-apriltag",
],
)
wpilib_cc_static_library(
name = "static/apriltag",
static_deps = [
"//wpimath:static/wpimath",
"//wpiutil:static/wpiutil",
],
visibility = ["//visibility:public"],
deps = [
":apriltag",
],
)
wpilib_jni_cc_library(
name = "apriltagjni",
srcs = glob(["src/main/native/cpp/jni/**"]),
java_dep = ":apriltag-java",
visibility = ["//visibility:public"],
deps = [
":apriltag",
],
)
wpilib_cc_shared_library(
name = "shared/apriltagjni",
auto_export_windows_symbols = False,
dynamic_deps = [
":shared/apriltag",
"//wpimath:shared/wpimath",
"//wpiutil:shared/wpiutil",
],
use_debug_name = False,
visibility = ["//visibility:public"],
deps = [":apriltagjni"],
)
wpilib_jni_java_library(
name = "apriltag-java",
srcs = glob(["src/main/java/**/*.java"]),
extra_source_pkgs = ["resources"],
maven_artifact_name = "apriltag-java",
maven_group_id = "org.wpilib.apriltag",
native_libs = [":apriltagjni"],
plugins = [
"//:avaje_jsonb_generator",
],
resource_strip_prefix = "apriltag/src/main/native/resources",
resources = glob(["src/main/native/resources/**"]),
visibility = ["//visibility:public"],
@@ -69,12 +150,17 @@ java_library(
"//wpimath:wpimath-java",
"//wpiutil:wpiutil-java",
"@bzlmodrio-opencv//libraries/java/opencv",
"@maven//:com_fasterxml_jackson_core_jackson_annotations",
"@maven//:com_fasterxml_jackson_core_jackson_core",
"@maven//:com_fasterxml_jackson_core_jackson_databind",
"@maven//:io_avaje_avaje_json_core",
"@maven//:io_avaje_avaje_jsonb",
],
)
pkg_files(
name = "resources",
srcs = glob(["src/main/native/resources/**"]),
strip_prefix = "src/main/native/resources/",
)
cc_test(
name = "apriltag-cpp-test",
size = "small",
@@ -83,8 +169,22 @@ cc_test(
"no-asan",
],
deps = [
":apriltag.static",
"//thirdparty/googletest:googletest.static",
":apriltag",
"//thirdparty/googletest",
],
)
wpilib_java_junit5_test(
name = "apriltag-java-test",
srcs = glob(["src/test/java/**/*.java"]),
resource_strip_prefix = "apriltag/src/test/resources",
resources = glob(["src/test/resources/**"]),
deps = [
":apriltag-java",
"//wpimath:wpimath-java",
"//wpiutil:wpiutil-java",
"@bzlmodrio-opencv//libraries/java/opencv",
"@maven//:io_avaje_avaje_jsonb",
],
)
@@ -92,14 +192,14 @@ cc_binary(
name = "DevMain-Cpp",
srcs = ["src/dev/native/cpp/main.cpp"],
deps = [
":apriltag.static",
":apriltag",
],
)
java_binary(
name = "DevMain-Java",
srcs = ["src/dev/java/edu/wpi/first/apriltag/DevMain.java"],
main_class = "edu.wpi.first.apriltag.DevMain",
srcs = ["src/dev/java/org/wpilib/vision/apriltag/DevMain.java"],
main_class = "org.wpilib.vision.apriltag.DevMain",
deps = [
":apriltag-java",
],
@@ -108,5 +208,67 @@ java_binary(
py_binary(
name = "convert_apriltag_layouts",
srcs = ["convert_apriltag_layouts.py"],
tags = ["manual"],
target_compatible_with = select({
"@rules_bzlmodrio_toolchains//constraints/is_systemcore:systemcore": ["@platforms//:incompatible"],
"//conditions:default": [],
}),
)
package_default_jni_project(
name = "apriltag",
maven_artifact_name = "apriltag-cpp",
maven_group_id = "org.wpilib.apriltag",
)
generate_robotpy_native_wrapper_build_info(
name = "robotpy-native-apriltag-generator",
pyproject_toml = "src/main/python/native-pyproject.toml",
third_party_dirs = ["apriltag"],
)
define_native_wrapper(
name = "robotpy-native-apriltag",
pyproject_toml = "src/main/python/native-pyproject.toml",
)
PYBIND_PKGCFG_DEPS = [
"//apriltag:native/apriltag/robotpy-native-apriltag.pc",
"//wpimath:native/wpimath/robotpy-native-wpimath.pc",
"//wpimath:robotpy-wpimath.generated_pkgcfg_files",
"//wpiutil:native/wpiutil/robotpy-native-wpiutil.pc",
"//wpiutil:robotpy-wpiutil.generated_pkgcfg_files",
]
generate_robotpy_pybind_build_info(
name = "robotpy-apriltag-generator",
additional_srcs = [":robotpy-native-apriltag.copy_headers"],
package_root_file = "src/main/python/robotpy_apriltag/__init__.py",
pkgcfgs = PYBIND_PKGCFG_DEPS,
yaml_files = glob(["src/main/python/semiwrap/*.yml"]),
)
apriltag_extension(
srcs = ["src/main/python/robotpy_apriltag/src/main.cpp"],
includes = [
"src/main/python/datalog/",
],
)
define_pybind_library(
name = "robotpy-apriltag",
pkgcfgs = PYBIND_PKGCFG_DEPS,
)
robotpy_py_test(
"python_tests",
srcs = glob(["src/test/python/**/*.py"]),
data = glob([
"src/test/python/*.png",
"src/test/python/*.jpg",
]),
deps = [
":robotpy-apriltag",
requirement("pytest"),
requirement("opencv-python"),
],
)

View File

@@ -31,86 +31,11 @@ else()
)
endif()
file(GLOB apriltag_jni_src src/main/native/cpp/jni/AprilTagJNI.cpp)
if(WITH_JAVA)
include(UseJava)
set(CMAKE_JNI_TARGET true)
file(GLOB EJML_JARS "${WPILIB_BINARY_DIR}/wpimath/thirdparty/ejml/*.jar")
file(GLOB JACKSON_JARS "${WPILIB_BINARY_DIR}/wpiutil/thirdparty/jackson/*.jar")
find_file(
OPENCV_JAR_FILE
NAMES opencv-${OpenCV_VERSION_MAJOR}${OpenCV_VERSION_MINOR}${OpenCV_VERSION_PATCH}.jar
PATHS
${OPENCV_JAVA_INSTALL_DIR}
${OpenCV_INSTALL_PATH}/bin
${OpenCV_INSTALL_PATH}/share/java
${OpenCV_INSTALL_PATH}/share/java/opencv4
${OpenCV_INSTALL_PATH}/share/OpenCV/java
NO_DEFAULT_PATH
)
file(GLOB_RECURSE JAVA_SOURCES src/main/java/*.java)
file(
GLOB_RECURSE JAVA_RESOURCES
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
src/main/native/resources/*.json
)
add_jar(
apriltag_jar
SOURCES ${JAVA_SOURCES}
RESOURCES
NAMESPACE "edu/wpi/first/apriltag" ${JAVA_RESOURCES}
INCLUDE_JARS
wpimath_jar
wpiunits_jar
wpiutil_jar
${EJML_JARS}
${OPENCV_JAR_FILE}
${JACKSON_JARS}
OUTPUT_NAME apriltag
OUTPUT_DIR ${WPILIB_BINARY_DIR}/${java_lib_dest}
GENERATE_NATIVE_HEADERS apriltag_jni_headers
)
set_property(TARGET apriltag_jar PROPERTY FOLDER "java")
install_jar(apriltag_jar DESTINATION ${java_lib_dest})
install_jar_exports(TARGETS apriltag_jar FILE apriltag_jar.cmake DESTINATION share/apriltag)
add_library(apriltagjni ${apriltag_jni_src} ${apriltaglib_src})
wpilib_target_warnings(apriltagjni)
target_link_libraries(apriltagjni PUBLIC apriltag)
set_property(TARGET apriltagjni PROPERTY FOLDER "libraries")
target_link_libraries(apriltagjni PRIVATE apriltag_jni_headers)
add_dependencies(apriltagjni apriltag_jar)
install(TARGETS apriltagjni EXPORT apriltagjni)
export(TARGETS apriltagjni FILE apriltagjni.cmake NAMESPACE apriltagjni::)
endif()
if(WITH_JAVA_SOURCE)
include(UseJava)
include(CreateSourceJar)
add_source_jar(
apriltag_src_jar
BASE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/src/main/java
OUTPUT_NAME apriltag-sources
OUTPUT_DIR ${WPILIB_BINARY_DIR}/${java_lib_dest}
)
set_property(TARGET apriltag_src_jar PROPERTY FOLDER "java")
install_jar(apriltag_src_jar DESTINATION ${java_lib_dest})
endif()
generate_resources(
src/main/native/resources/edu/wpi/first/apriltag
src/main/native/resources/org/wpilib/vision/apriltag
generated/main/cpp
APRILTAG
frc
wpi::apriltag
apriltag_resources_src
)
@@ -120,7 +45,7 @@ add_library(apriltag ${apriltag_native_src} ${apriltag_resources_src} ${apriltag
set_target_properties(apriltag PROPERTIES DEBUG_POSTFIX "d")
set_property(TARGET apriltag PROPERTY FOLDER "libraries")
target_compile_features(apriltag PUBLIC cxx_std_20)
target_compile_features(apriltag PUBLIC cxx_std_23)
wpilib_target_warnings(apriltag)
target_link_libraries(apriltag wpimath)

View File

@@ -1,10 +1,12 @@
# AprilTag
A C++ wrapper around the [University of Michigan's AprilTag detector](https://github.com/AprilRobotics/apriltag), alongside a vendored copy of their code with some patches (patches are located in [upstream_utils](../upstream_utils/apriltag_patches/)).
## Adding new field to AprilTagFields
### Adding field JSON
1. Add a field layout CSV file to `src/main/native/resources/edu/wpi/first/apriltag`
1. Add a field layout CSV file to `src/main/native/resources/org/wpilib/vision/apriltag`
1. See docstring in `convert_apriltag_layouts.py` for more
2. Run `convert_apriltag_layouts.py` in the same directory as this readme to generate the JSON
3. That script overwrites all generated JSONs, so undo undesired changes if necessary
@@ -14,15 +16,15 @@
### Java updates
1. Update `src/main/java/edu/wpi/first/apriltag/AprilTagFields.java`
1. Update `src/main/java/org/wpilib/vision/apriltag/AprilTagFields.java`
1. Add enum value for new field to `AprilTagFields`
2. Update `AprilTagFields.kDefaultField` if necessary
### C++ updates
1. Update `src/main/native/include/frc/apriltag/AprilTagFields.h`
1. Update `src/main/native/include/wpi/apriltag/AprilTagFields.hpp`
1. Add enum value for new field to `AprilTagFields`
2. Update `AprilTagFields::kDefaultField` if necessary
2. Update `src/main/native/cpp/AprilTagFields.cpp`
2. Update `src/main/native/cpp/AprilTagFieldLayout.cpp`
1. Add resource getter prototype like `std::string_view GetResource_2024_crescendo_json()`
2. Add case for new field to switch in `LoadAprilTagLayoutField()`
2. Add case for new field to switch in `LoadField(AprilTagField field)`

View File

@@ -5,6 +5,3 @@ include(CMakeFindDependencyMacro)
@FILENAME_DEP_REPLACE@
include(${SELF_DIR}/apriltag.cmake)
if(@WITH_JAVA@)
include(${SELF_DIR}/apriltag_jar.cmake)
endif()

View File

@@ -4,7 +4,7 @@ apply plugin: 'c'
ext {
nativeName = 'apriltag'
devMain = 'edu.wpi.first.apriltag.DevMain'
devMain = 'org.wpilib.vision.apriltag.DevMain'
useJava = true
useCpp = true
sharedCvConfigs = [
@@ -12,7 +12,7 @@ ext {
apriltagTest: []]
staticCvConfigs = []
def generateTask = createGenerateResourcesTask('main', 'APRILTAG', 'frc', project)
def generateTask = createGenerateResourcesTask('main', 'APRILTAG', 'wpi::apriltag', project)
tasks.withType(CppCompile) {
dependsOn generateTask
@@ -46,6 +46,7 @@ apply from: "${rootDir}/shared/opencv.gradle"
dependencies {
implementation project(':wpimath')
annotationProcessor libs.avaje.jsonb.generator
}
sourceSets {
@@ -103,14 +104,8 @@ model {
return
}
it.cppCompiler.define 'WPILIB_EXPORTS'
if (it.component.name == "${nativeName}JNI") {
lib project: ':wpimath', library: 'wpimath', linkage: 'static'
lib project: ':wpiutil', library: 'wpiutil', linkage: 'static'
} else {
lib project: ':wpimath', library: 'wpimath', linkage: 'shared'
lib project: ':wpiutil', library: 'wpiutil', linkage: 'shared'
}
lib project: ':wpimath', library: 'wpimath', linkage: 'shared'
lib project: ':wpiutil', library: 'wpiutil', linkage: 'shared'
}
}
tasks {

66
apriltag/robotpy_native_build_info.bzl generated Normal file
View File

@@ -0,0 +1,66 @@
# THIS FILE IS AUTO GENERATED
load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory")
load("//shared/bazel/rules/robotpy:robotpy_rules.bzl", "copy_native_file", "generate_native_files", "robotpy_library")
def define_native_wrapper(name, pyproject_toml = None):
pyproject_toml = pyproject_toml or "src/main/python/native-pyproject.toml"
copy_to_directory(
name = "{}.copy_headers".format(name),
srcs = native.glob(["src/main/native/include/**"]) + native.glob(["src/generated/main/native/include/**"], allow_empty = True) + native.glob([
"src/main/native/thirdparty/apriltag/include/**",
]),
out = "native/apriltag/include",
root_paths = ["src/main/native/include/"],
replace_prefixes = {
"apriltag/src/generated/main/native/include": "",
"apriltag/src/main/native/include": "",
"apriltag/src/main/native/thirdparty/apriltag/include": "",
},
verbose = False,
visibility = ["//visibility:public"],
)
libinit_files = ["native/apriltag/_init_robotpy_native_apriltag.py"]
generate_native_files(
name = name,
pyproject_toml = pyproject_toml,
pc_deps = [
"//wpimath:native/wpimath/robotpy-native-wpimath.pc",
"//wpiutil:native/wpiutil/robotpy-native-wpiutil.pc",
],
libinit_files = libinit_files,
pc_files = ["native/apriltag/robotpy-native-apriltag.pc"],
)
copy_native_file(
name = "apriltag",
library = "shared/apriltag",
base_path = "native/apriltag/",
)
robotpy_library(
name = name,
distribution = "robotpy-native-apriltag",
srcs = libinit_files,
data = [
name + ".pc_wrapper",
":apriltag.copy_lib",
"{}.copy_headers".format(name),
],
deps = [
"//wpimath:robotpy-native-wpimath",
"//wpiutil:robotpy-native-wpiutil",
],
summary = "WPILib AprilTag Library",
requires = ["robotpy-native-wpiutil==0.0.0", "robotpy-native-wpimath==0.0.0"],
python_requires = ">=3.11",
strip_path_prefixes = ["apriltag"],
entry_points = {
"pkg_config": [
"apriltag = native.apriltag",
],
},
)

252
apriltag/robotpy_pybind_build_info.bzl generated Normal file
View File

@@ -0,0 +1,252 @@
# THIS FILE IS AUTO GENERATED
load("//shared/bazel/rules/gen:gen-version-file.bzl", "generate_version_file")
load("//shared/bazel/rules/robotpy:robotpy_rules.bzl", "create_pybind_library", "robotpy_library")
load("//shared/bazel/rules/robotpy:semiwrap_helpers.bzl", "gen_libinit", "gen_modinit_hpp", "gen_pkgconf", "resolve_casters", "run_header_gen")
load("//shared/bazel/rules/robotpy:semiwrap_tool_helpers.bzl", "scan_headers", "update_yaml_files")
def apriltag_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includes = []):
APRILTAG_HEADER_GEN = [
struct(
class_name = "AprilTag",
yml_file = "semiwrap/AprilTag.yml",
header_root = "$(execpath :robotpy-native-apriltag.copy_headers)",
header_file = "$(execpath :robotpy-native-apriltag.copy_headers)/wpi/apriltag/AprilTag.hpp",
tmpl_class_names = [],
trampolines = [
("wpi::apriltag::AprilTag", "wpi__apriltag__AprilTag.hpp"),
],
),
struct(
class_name = "AprilTagDetection",
yml_file = "semiwrap/AprilTagDetection.yml",
header_root = "$(execpath :robotpy-native-apriltag.copy_headers)",
header_file = "$(execpath :robotpy-native-apriltag.copy_headers)/wpi/apriltag/AprilTagDetection.hpp",
tmpl_class_names = [],
trampolines = [
("wpi::apriltag::AprilTagDetection", "wpi__apriltag__AprilTagDetection.hpp"),
("wpi::apriltag::AprilTagDetection::Point", "wpi__apriltag__AprilTagDetection__Point.hpp"),
],
),
struct(
class_name = "AprilTagDetector",
yml_file = "semiwrap/AprilTagDetector.yml",
header_root = "$(execpath :robotpy-native-apriltag.copy_headers)",
header_file = "$(execpath :robotpy-native-apriltag.copy_headers)/wpi/apriltag/AprilTagDetector.hpp",
tmpl_class_names = [],
trampolines = [
("wpi::apriltag::AprilTagDetector", "wpi__apriltag__AprilTagDetector.hpp"),
("wpi::apriltag::AprilTagDetector::Config", "wpi__apriltag__AprilTagDetector__Config.hpp"),
("wpi::apriltag::AprilTagDetector::QuadThresholdParameters", "wpi__apriltag__AprilTagDetector__QuadThresholdParameters.hpp"),
("wpi::apriltag::AprilTagDetector::Results", "wpi__apriltag__AprilTagDetector__Results.hpp"),
],
),
struct(
class_name = "AprilTagFieldLayout",
yml_file = "semiwrap/AprilTagFieldLayout.yml",
header_root = "$(execpath :robotpy-native-apriltag.copy_headers)",
header_file = "$(execpath :robotpy-native-apriltag.copy_headers)/wpi/apriltag/AprilTagFieldLayout.hpp",
tmpl_class_names = [],
trampolines = [
("wpi::apriltag::AprilTagFieldLayout", "wpi__apriltag__AprilTagFieldLayout.hpp"),
],
),
struct(
class_name = "AprilTagFields",
yml_file = "semiwrap/AprilTagFields.yml",
header_root = "$(execpath :robotpy-native-apriltag.copy_headers)",
header_file = "$(execpath :robotpy-native-apriltag.copy_headers)/wpi/apriltag/AprilTagFields.hpp",
tmpl_class_names = [],
trampolines = [],
),
struct(
class_name = "AprilTagPoseEstimate",
yml_file = "semiwrap/AprilTagPoseEstimate.yml",
header_root = "$(execpath :robotpy-native-apriltag.copy_headers)",
header_file = "$(execpath :robotpy-native-apriltag.copy_headers)/wpi/apriltag/AprilTagPoseEstimate.hpp",
tmpl_class_names = [],
trampolines = [
("wpi::apriltag::AprilTagPoseEstimate", "wpi__apriltag__AprilTagPoseEstimate.hpp"),
],
),
struct(
class_name = "AprilTagPoseEstimator",
yml_file = "semiwrap/AprilTagPoseEstimator.yml",
header_root = "$(execpath :robotpy-native-apriltag.copy_headers)",
header_file = "$(execpath :robotpy-native-apriltag.copy_headers)/wpi/apriltag/AprilTagPoseEstimator.hpp",
tmpl_class_names = [],
trampolines = [
("wpi::apriltag::AprilTagPoseEstimator", "wpi__apriltag__AprilTagPoseEstimator.hpp"),
("wpi::apriltag::AprilTagPoseEstimator::Config", "wpi__apriltag__AprilTagPoseEstimator__Config.hpp"),
],
),
]
resolve_casters(
name = "apriltag.resolve_casters",
caster_deps = ["//wpimath:src/main/python/wpimath/wpimath-casters.pybind11.json", "//wpiutil:src/main/python/wpiutil/wpiutil-casters.pybind11.json"],
casters_pkl_file = "apriltag.casters.pkl",
dep_file = "apriltag.casters.d",
)
gen_libinit(
name = "apriltag.gen_lib_init",
output_file = "src/main/python/robotpy_apriltag/_init__apriltag.py",
modules = ["native.apriltag._init_robotpy_native_apriltag", "wpiutil._init__wpiutil", "wpimath._init__wpimath"],
)
gen_pkgconf(
name = "apriltag.gen_pkgconf",
libinit_py = "robotpy_apriltag._init__apriltag",
module_pkg_name = "robotpy_apriltag._apriltag",
output_file = "apriltag.pc",
pkg_name = "apriltag",
install_path = "src/main/python/robotpy_apriltag",
project_file = "src/main/python/pyproject.toml",
package_root = "src/main/python/robotpy_apriltag/__init__.py",
)
gen_modinit_hpp(
name = "apriltag.gen_modinit_hpp",
input_dats = [x.class_name for x in APRILTAG_HEADER_GEN],
libname = "_apriltag",
output_file = "semiwrap_init.robotpy_apriltag._apriltag.hpp",
)
run_header_gen(
name = "apriltag",
casters_pickle = "apriltag.casters.pkl",
header_gen_config = APRILTAG_HEADER_GEN,
trampoline_subpath = "src/main/python/robotpy_apriltag",
deps = header_to_dat_deps,
local_native_libraries = [
"//apriltag:robotpy-native-apriltag.copy_headers",
"//wpimath:robotpy-native-wpimath.copy_headers",
"//wpiutil:robotpy-native-wpiutil.copy_headers",
],
)
create_pybind_library(
name = "apriltag",
install_path = "src/main/python/robotpy_apriltag/",
extension_name = "_apriltag",
generated_srcs = [":apriltag.generated_srcs"],
semiwrap_header = [":apriltag.gen_modinit_hpp"],
deps = [
":apriltag.tmpl_hdrs",
":apriltag.trampoline_hdrs",
"//apriltag:apriltag",
"//wpimath:wpimath",
"//wpimath:wpimath_pybind_library",
"//wpiutil:wpiutil",
"//wpiutil:wpiutil_pybind_library",
],
dynamic_deps = [
"//apriltag:shared/apriltag",
"//wpimath:shared/wpimath",
"//wpiutil:shared/wpiutil",
],
extra_hdrs = extra_hdrs,
extra_srcs = srcs,
includes = includes,
)
native.filegroup(
name = "apriltag.generated_files",
srcs = [
"apriltag.gen_modinit_hpp.gen",
"apriltag.header_gen_files",
"apriltag.gen_pkgconf",
"apriltag.gen_lib_init",
],
tags = ["manual", "robotpy"],
)
def define_pybind_library(name, pkgcfgs = []):
# Helper used to generate all files with one target.
native.filegroup(
name = "{}.generated_files".format(name),
srcs = [
"apriltag.generated_files",
],
tags = ["manual", "robotpy"],
visibility = ["//visibility:public"],
)
# Files that will be included in the wheel as data deps
native.filegroup(
name = "{}.generated_pkgcfg_files".format(name),
srcs = [
"src/main/python/robotpy_apriltag/apriltag.pc",
],
tags = ["manual", "robotpy"],
visibility = ["//visibility:public"],
)
# Contains all of the non-python files that need to be included in the wheel
native.filegroup(
name = "{}.extra_files".format(name),
srcs = native.glob(["src/main/python/robotpy_apriltag/**"], exclude = ["src/main/python/robotpy_apriltag/**/*.py"], allow_empty = True),
tags = ["manual", "robotpy"],
)
generate_version_file(
name = "{}.generate_version".format(name),
output_file = "src/main/python/robotpy_apriltag/version.py",
template = "//shared/bazel/rules/robotpy:version_template.in",
)
robotpy_library(
name = name,
distribution = "robotpy-apriltag",
srcs = native.glob(["src/main/python/robotpy_apriltag/**/*.py"]) + [
"src/main/python/robotpy_apriltag/_init__apriltag.py",
"{}.generate_version".format(name),
],
data = [
"{}.generated_pkgcfg_files".format(name),
"{}.extra_files".format(name),
":src/main/python/robotpy_apriltag/_apriltag",
":apriltag.trampoline_hdr_files",
],
imports = ["src/main/python"],
deps = [
"//apriltag:robotpy-native-apriltag",
"//wpimath:robotpy-wpimath",
"//wpiutil:robotpy-wpiutil",
],
strip_path_prefixes = ["apriltag/src/main/python", "apriltag"],
summary = "RobotPy bindings for WPILib's AprilTag library",
project_urls = {"Source code": "https://github.com/robotpy/mostrobotpy"},
author_email = "RobotPy Development Team <robotpy@googlegroups.com>",
requires = ["robotpy-native-apriltag==0.0.0", "robotpy-wpiutil==0.0.0", "robotpy-wpimath==0.0.0"],
python_requires = ">=3.11",
entry_points = {
"pkg_config": ["apriltag = robotpy_apriltag"],
},
visibility = ["//visibility:public"],
)
update_yaml_files(
name = "{}-update-yaml".format(name),
yaml_output_directory = "src/main/python/semiwrap",
extra_hdrs = native.glob(["src/main/python/**/*.h"], allow_empty = True) + [
"//apriltag:robotpy-native-apriltag.copy_headers",
"//wpimath:robotpy-native-wpimath.copy_headers",
"//wpiutil:robotpy-native-wpiutil.copy_headers",
],
package_root_file = "src/main/python/robotpy_apriltag/__init__.py",
pkgcfgs = pkgcfgs,
pyproject_toml = "src/main/python/pyproject.toml",
yaml_files = native.glob(["src/main/python/semiwrap/**"]),
)
scan_headers(
name = "{}-scan-headers".format(name),
extra_hdrs = native.glob(["src/main/python/**/*.h"], allow_empty = True) + [
"//apriltag:robotpy-native-apriltag.copy_headers",
],
package_root_file = "src/main/python/robotpy_apriltag/__init__.py",
pkgcfgs = pkgcfgs,
pyproject_toml = "src/main/python/pyproject.toml",
)

View File

@@ -1,20 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.apriltag;
public final class DevMain {
/** Main entry point. */
public static void main(String[] args) {
System.out.println("Hello World!");
AprilTagDetector detector = new AprilTagDetector();
detector.addFamily("tag16h5");
AprilTagDetector.Config config = new AprilTagDetector.Config();
config.refineEdges = false;
detector.setConfig(config);
detector.close();
}
private DevMain() {}
}

View File

@@ -0,0 +1,20 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package org.wpilib.vision.apriltag;
public final class DevMain {
/** Main entry point. */
public static void main(String[] args) {
System.out.println("Hello World!");
AprilTagDetector detector = new AprilTagDetector();
detector.addFamily("tag16h5");
AprilTagDetector.Config config = new AprilTagDetector.Config();
config.refineEdges = false;
detector.setConfig(config);
detector.close();
}
private DevMain() {}
}

View File

@@ -2,10 +2,10 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include "frc/apriltag/AprilTagDetector.h"
#include "wpi/apriltag/AprilTagDetector.hpp"
int main() {
frc::AprilTagDetector detector;
wpi::apriltag::AprilTagDetector detector;
detector.AddFamily("tag16h5");
detector.SetConfig({.refineEdges = false});
}

View File

@@ -1,299 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.apriltag;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import edu.wpi.first.math.geometry.Pose3d;
import edu.wpi.first.math.geometry.Rotation3d;
import edu.wpi.first.math.geometry.Translation3d;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
/**
* Class for representing a layout of AprilTags on a field and reading them from a JSON format.
*
* <p>The JSON format contains two top-level objects, "tags" and "field". The "tags" object is a
* list of all AprilTags contained within a layout. Each AprilTag serializes to a JSON object
* containing an ID and a Pose3d. The "field" object is a descriptor of the size of the field in
* meters with "width" and "length" values. This is to account for arbitrary field sizes when
* transforming the poses.
*
* <p>Pose3ds in the JSON are measured using the normal FRC coordinate system, NWU with the origin
* at the bottom-right corner of the blue alliance wall. {@link #setOrigin(OriginPosition)} can be
* used to change the poses returned from {@link AprilTagFieldLayout#getTagPose(int)} to be from the
* perspective of a specific alliance.
*
* <p>Tag poses represent the center of the tag, with a zero rotation representing a tag that is
* upright and facing away from the (blue) alliance wall (that is, towards the opposing alliance).
*/
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE)
public class AprilTagFieldLayout {
/** Common origin positions for the AprilTag coordinate system. */
public enum OriginPosition {
/** Blue alliance wall, right side. */
kBlueAllianceWallRightSide,
/** Red alliance wall, right side. */
kRedAllianceWallRightSide,
}
private final Map<Integer, AprilTag> m_apriltags = new HashMap<>();
@JsonProperty(value = "field")
private FieldDimensions m_fieldDimensions;
private Pose3d m_origin;
/**
* Construct a new AprilTagFieldLayout with values imported from a JSON file.
*
* @param path Path of the JSON file to import from.
* @throws IOException If reading from the file fails.
*/
public AprilTagFieldLayout(String path) throws IOException {
this(Path.of(path));
}
/**
* Construct a new AprilTagFieldLayout with values imported from a JSON file.
*
* @param path Path of the JSON file to import from.
* @throws IOException If reading from the file fails.
*/
public AprilTagFieldLayout(Path path) throws IOException {
AprilTagFieldLayout layout =
new ObjectMapper().readValue(path.toFile(), AprilTagFieldLayout.class);
m_apriltags.putAll(layout.m_apriltags);
m_fieldDimensions = layout.m_fieldDimensions;
setOrigin(OriginPosition.kBlueAllianceWallRightSide);
}
/**
* Construct a new AprilTagFieldLayout from a list of {@link AprilTag} objects.
*
* @param apriltags List of {@link AprilTag}.
* @param fieldLength Length of the field the layout is representing in meters.
* @param fieldWidth Width of the field the layout is representing in meters.
*/
public AprilTagFieldLayout(List<AprilTag> apriltags, double fieldLength, double fieldWidth) {
this(apriltags, new FieldDimensions(fieldLength, fieldWidth));
}
@JsonCreator
private AprilTagFieldLayout(
@JsonProperty(required = true, value = "tags") List<AprilTag> apriltags,
@JsonProperty(required = true, value = "field") FieldDimensions fieldDimensions) {
// To ensure the underlying semantics don't change with what kind of list is passed in
for (AprilTag tag : apriltags) {
m_apriltags.put(tag.ID, tag);
}
m_fieldDimensions = fieldDimensions;
setOrigin(OriginPosition.kBlueAllianceWallRightSide);
}
/**
* Returns a List of the {@link AprilTag AprilTags} used in this layout.
*
* @return The {@link AprilTag AprilTags} used in this layout.
*/
@JsonProperty("tags")
public List<AprilTag> getTags() {
return new ArrayList<>(m_apriltags.values());
}
/**
* Returns the length of the field the layout is representing in meters.
*
* @return length, in meters
*/
@JsonIgnore
public double getFieldLength() {
return m_fieldDimensions.fieldLength;
}
/**
* Returns the length of the field the layout is representing in meters.
*
* @return width, in meters
*/
@JsonIgnore
public double getFieldWidth() {
return m_fieldDimensions.fieldWidth;
}
/**
* Sets the origin based on a predefined enumeration of coordinate frame origins. The origins are
* calculated from the field dimensions.
*
* <p>This transforms the Pose3d objects returned by {@link #getTagPose(int)} to return the
* correct pose relative to a predefined coordinate frame.
*
* @param origin The predefined origin
*/
@JsonIgnore
public final void setOrigin(OriginPosition origin) {
var pose =
switch (origin) {
case kBlueAllianceWallRightSide -> Pose3d.kZero;
case kRedAllianceWallRightSide -> new Pose3d(
new Translation3d(m_fieldDimensions.fieldLength, m_fieldDimensions.fieldWidth, 0),
new Rotation3d(0, 0, Math.PI));
};
setOrigin(pose);
}
/**
* Sets the origin for tag pose transformation.
*
* <p>This transforms the Pose3d objects returned by {@link #getTagPose(int)} to return the
* correct pose relative to the provided origin.
*
* @param origin The new origin for tag transformations
*/
@JsonIgnore
public final void setOrigin(Pose3d origin) {
m_origin = origin;
}
/**
* Returns the origin used for tag pose transformation.
*
* @return the origin
*/
@JsonIgnore
public Pose3d getOrigin() {
return m_origin;
}
/**
* Gets an AprilTag pose by its ID.
*
* @param ID The ID of the tag.
* @return The pose corresponding to the ID passed in or an empty optional if a tag with that ID
* was not found.
*/
@SuppressWarnings("ParameterName")
public Optional<Pose3d> getTagPose(int ID) {
AprilTag tag = m_apriltags.get(ID);
if (tag == null) {
return Optional.empty();
}
return Optional.of(tag.pose.relativeTo(m_origin));
}
/**
* Serializes a AprilTagFieldLayout to a JSON file.
*
* @param path The path to write to.
* @throws IOException If writing to the file fails.
*/
public void serialize(String path) throws IOException {
serialize(Path.of(path));
}
/**
* Serializes a AprilTagFieldLayout to a JSON file.
*
* @param path The path to write to.
* @throws IOException If writing to the file fails.
*/
public void serialize(Path path) throws IOException {
new ObjectMapper().writeValue(path.toFile(), this);
}
/**
* Get an official {@link AprilTagFieldLayout}.
*
* @param field The loadable AprilTag field layout.
* @return AprilTagFieldLayout of the field.
* @throws UncheckedIOException If the layout does not exist.
*/
public static AprilTagFieldLayout loadField(AprilTagFields field) {
if (field.m_fieldLayout == null) {
try {
field.m_fieldLayout = loadFromResource(field.m_resourceFile);
} catch (IOException e) {
throw new UncheckedIOException(
"Could not load AprilTagFieldLayout from " + field.m_resourceFile, e);
}
}
// Copy layout because the layout's origin is mutable
return new AprilTagFieldLayout(
field.m_fieldLayout.getTags(),
field.m_fieldLayout.getFieldLength(),
field.m_fieldLayout.getFieldWidth());
}
/**
* Deserializes a field layout from a resource within a internal jar file.
*
* <p>Users should use {@link AprilTagFields#loadAprilTagLayoutField()} to load official layouts
* and {@link #AprilTagFieldLayout(String)} for custom layouts.
*
* @param resourcePath The absolute path of the resource
* @return The deserialized layout
* @throws IOException If the resource could not be loaded
*/
public static AprilTagFieldLayout loadFromResource(String resourcePath) throws IOException {
InputStream stream = AprilTagFieldLayout.class.getResourceAsStream(resourcePath);
if (stream == null) {
// Class.getResourceAsStream() returns null if the resource does not exist.
throw new IOException("Could not locate resource: " + resourcePath);
}
InputStreamReader reader = new InputStreamReader(stream, StandardCharsets.UTF_8);
try {
return new ObjectMapper().readerFor(AprilTagFieldLayout.class).readValue(reader);
} catch (IOException e) {
throw new IOException("Failed to load AprilTagFieldLayout: " + resourcePath);
}
}
@Override
public boolean equals(Object obj) {
return obj instanceof AprilTagFieldLayout layout
&& m_apriltags.equals(layout.m_apriltags)
&& m_origin.equals(layout.m_origin);
}
@Override
public int hashCode() {
return Objects.hash(m_apriltags, m_origin);
}
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonAutoDetect(getterVisibility = JsonAutoDetect.Visibility.NONE)
private static class FieldDimensions {
@SuppressWarnings("MemberName")
@JsonProperty(value = "length")
public final double fieldLength;
@SuppressWarnings("MemberName")
@JsonProperty(value = "width")
public final double fieldWidth;
@JsonCreator()
FieldDimensions(
@JsonProperty(required = true, value = "length") double fieldLength,
@JsonProperty(required = true, value = "width") double fieldWidth) {
this.fieldLength = fieldLength;
this.fieldWidth = fieldWidth;
}
}
}

View File

@@ -1,46 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.apriltag;
import java.io.UncheckedIOException;
/** Loadable AprilTag field layouts. */
public enum AprilTagFields {
/** 2022 Rapid React. */
k2022RapidReact("2022-rapidreact.json"),
/** 2023 Charged Up. */
k2023ChargedUp("2023-chargedup.json"),
/** 2024 Crescendo. */
k2024Crescendo("2024-crescendo.json"),
/** 2025 Reefscape. */
k2025Reefscape("2025-reefscape.json");
/** Base resource directory. */
public static final String kBaseResourceDir = "/edu/wpi/first/apriltag/";
/** Alias to the current game. */
public static final AprilTagFields kDefaultField = k2025Reefscape;
/** Resource filename. */
public final String m_resourceFile;
AprilTagFieldLayout m_fieldLayout;
AprilTagFields(String resourceFile) {
m_resourceFile = kBaseResourceDir + resourceFile;
}
/**
* Get a {@link AprilTagFieldLayout} from the resource JSON.
*
* @return AprilTagFieldLayout of the field
* @throws UncheckedIOException If the layout does not exist
* @deprecated Use {@link AprilTagFieldLayout#loadField(AprilTagFields)} instead.
*/
@Deprecated(forRemoval = true, since = "2025")
public AprilTagFieldLayout loadAprilTagLayoutField() {
return AprilTagFieldLayout.loadField(this);
}
}

View File

@@ -2,24 +2,24 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.apriltag;
package org.wpilib.vision.apriltag;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import edu.wpi.first.apriltag.jni.AprilTagJNI;
import edu.wpi.first.math.geometry.Pose3d;
import edu.wpi.first.util.RawFrame;
import io.avaje.jsonb.Json;
import java.util.Objects;
import org.wpilib.math.geometry.Pose3d;
import org.wpilib.util.RawFrame;
import org.wpilib.vision.apriltag.jni.AprilTagJNI;
/** Represents an AprilTag's metadata. */
@SuppressWarnings("MemberName")
@Json
public class AprilTag {
/** The tag's ID. */
@JsonProperty(value = "ID")
@Json.Property("ID")
@SuppressWarnings("PMD.PublicFieldNamingConvention")
public int ID;
/** The tag's pose. */
@JsonProperty(value = "pose")
@Json.Property("pose")
public Pose3d pose;
/**
@@ -29,10 +29,8 @@ public class AprilTag {
* @param pose The tag's pose.
*/
@SuppressWarnings("ParameterName")
@JsonCreator
public AprilTag(
@JsonProperty(required = true, value = "ID") int ID,
@JsonProperty(required = true, value = "pose") Pose3d pose) {
@Json.Creator
public AprilTag(int ID, Pose3d pose) {
this.ID = ID;
this.pose = pose;
}

View File

@@ -2,13 +2,13 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.apriltag;
package org.wpilib.vision.apriltag;
import edu.wpi.first.math.MatBuilder;
import edu.wpi.first.math.Matrix;
import edu.wpi.first.math.Nat;
import edu.wpi.first.math.numbers.N3;
import java.util.Arrays;
import org.wpilib.math.linalg.MatBuilder;
import org.wpilib.math.linalg.Matrix;
import org.wpilib.math.numbers.N3;
import org.wpilib.math.util.Nat;
/** A detection of an AprilTag tag. */
public class AprilTagDetection {

View File

@@ -2,10 +2,10 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.apriltag;
package org.wpilib.vision.apriltag;
import edu.wpi.first.apriltag.jni.AprilTagJNI;
import org.opencv.core.Mat;
import org.wpilib.vision.apriltag.jni.AprilTagJNI;
/**
* An AprilTag detector engine. This is expensive to set up and tear down, so most use cases should
@@ -14,7 +14,6 @@ import org.opencv.core.Mat;
*/
public class AprilTagDetector implements AutoCloseable {
/** Detector configuration. */
@SuppressWarnings("MemberName")
public static class Config {
/**
* How many threads should be used for computation. Default is single-threaded operation (1
@@ -110,7 +109,6 @@ public class AprilTagDetector implements AutoCloseable {
}
/** Quad threshold parameters. */
@SuppressWarnings("MemberName")
public static class QuadThresholdParameters {
/** Threshold used to reject quads containing too few pixels. Default is 300 pixels. */
public int minClusterPixels = 300;

View File

@@ -0,0 +1,281 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package org.wpilib.vision.apriltag;
import io.avaje.jsonb.Json;
import io.avaje.jsonb.Jsonb;
import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import org.wpilib.math.geometry.Pose3d;
import org.wpilib.math.geometry.Rotation3d;
import org.wpilib.math.geometry.Translation3d;
/**
* Class for representing a layout of AprilTags on a field and reading them from a JSON format.
*
* <p>The JSON format contains two top-level objects, "tags" and "field". The "tags" object is a
* list of all AprilTags contained within a layout. Each AprilTag serializes to a JSON object
* containing an ID and a Pose3d. The "field" object is a descriptor of the size of the field in
* meters with "width" and "length" values. This is to account for arbitrary field sizes when
* transforming the poses.
*
* <p>Pose3ds in the JSON are measured using the normal FRC coordinate system, NWU with the origin
* at the bottom-right corner of the blue alliance wall. {@link #setOrigin(OriginPosition)} can be
* used to change the poses returned from {@link AprilTagFieldLayout#getTagPose(int)} to be from the
* perspective of a specific alliance.
*
* <p>Tag poses represent the center of the tag, with a zero rotation representing a tag that is
* upright and facing away from the (blue) alliance wall (that is, towards the opposing alliance).
*/
@Json
public class AprilTagFieldLayout {
/** Common origin positions for the AprilTag coordinate system. */
public enum OriginPosition {
/** Blue alliance wall, right side. */
kBlueAllianceWallRightSide,
/** Red alliance wall, right side. */
kRedAllianceWallRightSide,
}
@Json.Ignore private final Map<Integer, AprilTag> m_apriltags = new HashMap<>();
@Json.Property("field")
FieldDimensions m_fieldDimensions;
@Json.Ignore private Pose3d m_origin;
/**
* Construct a new AprilTagFieldLayout with values imported from a JSON file.
*
* @param path Path of the JSON file to import from.
* @throws IOException If reading from the file fails.
*/
public AprilTagFieldLayout(String path) throws IOException {
this(Path.of(path));
}
/**
* Construct a new AprilTagFieldLayout with values imported from a JSON file.
*
* @param path Path of the JSON file to import from.
* @throws IOException If reading from the file fails.
*/
public AprilTagFieldLayout(Path path) throws IOException {
AprilTagFieldLayout layout =
Jsonb.instance().type(AprilTagFieldLayout.class).fromJson(Files.newBufferedReader(path));
m_apriltags.putAll(layout.m_apriltags);
m_fieldDimensions = layout.m_fieldDimensions;
setOrigin(OriginPosition.kBlueAllianceWallRightSide);
}
/**
* Construct a new AprilTagFieldLayout from a list of {@link AprilTag} objects.
*
* @param apriltags List of {@link AprilTag}.
* @param fieldLength Length of the field the layout is representing in meters.
* @param fieldWidth Width of the field the layout is representing in meters.
*/
public AprilTagFieldLayout(List<AprilTag> apriltags, double fieldLength, double fieldWidth) {
this(apriltags, new FieldDimensions(fieldLength, fieldWidth));
}
@Json.Creator
AprilTagFieldLayout(
@Json.Alias("tags") List<AprilTag> apriltags,
@Json.Alias("field") FieldDimensions fieldDimensions) {
// To ensure the underlying semantics don't change with what kind of list is passed in
for (AprilTag tag : apriltags) {
m_apriltags.put(tag.ID, tag);
}
m_fieldDimensions = fieldDimensions;
setOrigin(OriginPosition.kBlueAllianceWallRightSide);
}
/**
* Returns a List of the {@link AprilTag AprilTags} used in this layout.
*
* @return The {@link AprilTag AprilTags} used in this layout.
*/
@Json.Property("tags")
public List<AprilTag> getTags() {
return new ArrayList<>(m_apriltags.values());
}
/**
* Returns the length of the field the layout is representing in meters.
*
* @return length, in meters
*/
public double getFieldLength() {
return m_fieldDimensions.fieldLength;
}
/**
* Returns the length of the field the layout is representing in meters.
*
* @return width, in meters
*/
public double getFieldWidth() {
return m_fieldDimensions.fieldWidth;
}
/**
* Sets the origin based on a predefined enumeration of coordinate frame origins. The origins are
* calculated from the field dimensions.
*
* <p>This transforms the Pose3d objects returned by {@link #getTagPose(int)} to return the
* correct pose relative to a predefined coordinate frame.
*
* @param origin The predefined origin
*/
public final void setOrigin(OriginPosition origin) {
var pose =
switch (origin) {
case kBlueAllianceWallRightSide -> Pose3d.kZero;
case kRedAllianceWallRightSide ->
new Pose3d(
new Translation3d(m_fieldDimensions.fieldLength, m_fieldDimensions.fieldWidth, 0),
new Rotation3d(0, 0, Math.PI));
};
setOrigin(pose);
}
/**
* Sets the origin for tag pose transformation.
*
* <p>This transforms the Pose3d objects returned by {@link #getTagPose(int)} to return the
* correct pose relative to the provided origin.
*
* @param origin The new origin for tag transformations
*/
public final void setOrigin(Pose3d origin) {
m_origin = origin;
}
/**
* Returns the origin used for tag pose transformation.
*
* @return the origin
*/
public Pose3d getOrigin() {
return m_origin;
}
/**
* Gets an AprilTag pose by its ID.
*
* @param ID The ID of the tag.
* @return The pose corresponding to the ID passed in or an empty optional if a tag with that ID
* was not found.
*/
@SuppressWarnings("ParameterName")
public Optional<Pose3d> getTagPose(int ID) {
AprilTag tag = m_apriltags.get(ID);
if (tag == null) {
return Optional.empty();
}
return Optional.of(tag.pose.relativeTo(m_origin));
}
/**
* Serializes a AprilTagFieldLayout to a JSON file.
*
* @param path The path to write to.
* @throws IOException If writing to the file fails.
*/
public void serialize(String path) throws IOException {
serialize(Path.of(path));
}
/**
* Serializes a AprilTagFieldLayout to a JSON file.
*
* @param path The path to write to.
* @throws IOException If writing to the file fails.
*/
public void serialize(Path path) throws IOException {
Jsonb.instance().type(AprilTagFieldLayout.class).toJson(this, Files.newBufferedWriter(path));
}
/**
* Get an official {@link AprilTagFieldLayout}.
*
* @param field The loadable AprilTag field layout.
* @return AprilTagFieldLayout of the field.
* @throws UncheckedIOException If the layout does not exist.
*/
public static AprilTagFieldLayout loadField(AprilTagFields field) {
if (field.fieldLayout == null) {
try {
field.fieldLayout = loadFromResource(field.resourceFile);
} catch (IOException e) {
throw new UncheckedIOException(
"Could not load AprilTagFieldLayout from " + field.resourceFile, e);
}
}
// Copy layout because the layout's origin is mutable
return new AprilTagFieldLayout(
field.fieldLayout.getTags(),
field.fieldLayout.getFieldLength(),
field.fieldLayout.getFieldWidth());
}
/**
* Deserializes a field layout from a resource within a internal jar file.
*
* <p>Users should use {@link #loadField(AprilTagFields)} to load official layouts and {@link
* #AprilTagFieldLayout(String)} for custom layouts.
*
* @param resourcePath The absolute path of the resource
* @return The deserialized layout
* @throws IOException If the resource could not be loaded
*/
public static AprilTagFieldLayout loadFromResource(String resourcePath) throws IOException {
try (InputStream stream = AprilTagFieldLayout.class.getResourceAsStream(resourcePath)) {
if (stream == null) {
// Class.getResourceAsStream() returns null if the resource does not exist.
throw new IOException("Could not locate resource: " + resourcePath);
}
return Jsonb.instance().type(AprilTagFieldLayout.class).fromJson(stream);
}
}
@Override
public boolean equals(Object obj) {
return obj instanceof AprilTagFieldLayout layout
&& m_apriltags.equals(layout.m_apriltags)
&& m_origin.equals(layout.m_origin);
}
@Override
public int hashCode() {
return Objects.hash(m_apriltags, m_origin);
}
static class FieldDimensions {
@Json.Property(value = "length")
public final double fieldLength;
@Json.Property(value = "width")
public final double fieldWidth;
@Json.Creator()
FieldDimensions(
@Json.Alias(value = "length") double fieldLength,
@Json.Alias(value = "width") double fieldWidth) {
this.fieldLength = fieldLength;
this.fieldWidth = fieldWidth;
}
}
}

View File

@@ -0,0 +1,38 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package org.wpilib.vision.apriltag;
/** Loadable AprilTag field layouts. */
public enum AprilTagFields {
/** 2022 Rapid React. */
k2022RapidReact("2022-rapidreact.json"),
/** 2023 Charged Up. */
k2023ChargedUp("2023-chargedup.json"),
/** 2024 Crescendo. */
k2024Crescendo("2024-crescendo.json"),
/** 2025 Reefscape Welded (see TU 12). */
k2025ReefscapeWelded("2025-reefscape-welded.json"),
/** 2025 Reefscape AndyMark (see TU 12). */
k2025ReefscapeAndyMark("2025-reefscape-andymark.json"),
/** 2026 Rebuilt Welded. */
k2026RebuiltWelded("2026-rebuilt-welded.json"),
/** 2026 Rebuilt AndyMark. */
k2026RebuiltAndymark("2026-rebuilt-andymark.json");
/** Base resource directory. */
public static final String kBaseResourceDir = "/org/wpilib/vision/apriltag/";
/** Alias to the current game. */
public static final AprilTagFields kDefaultField = k2026RebuiltWelded;
/** Resource filename. */
public final String resourceFile;
AprilTagFieldLayout fieldLayout;
AprilTagFields(String resourceFile) {
this.resourceFile = kBaseResourceDir + resourceFile;
}
}

View File

@@ -2,12 +2,11 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.apriltag;
package org.wpilib.vision.apriltag;
import edu.wpi.first.math.geometry.Transform3d;
import org.wpilib.math.geometry.Transform3d;
/** A pair of AprilTag pose estimates. */
@SuppressWarnings("MemberName")
public class AprilTagPoseEstimate {
/**
* Constructs a pose estimate.

View File

@@ -2,15 +2,14 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.apriltag;
package org.wpilib.vision.apriltag;
import edu.wpi.first.apriltag.jni.AprilTagJNI;
import edu.wpi.first.math.geometry.Transform3d;
import org.wpilib.math.geometry.Transform3d;
import org.wpilib.vision.apriltag.jni.AprilTagJNI;
/** Pose estimators for AprilTag tags. */
public class AprilTagPoseEstimator {
/** Configuration for the pose estimator. */
@SuppressWarnings("MemberName")
public static class Config {
/**
* Creates a pose estimator configuration.

View File

@@ -2,16 +2,16 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.apriltag.jni;
package org.wpilib.vision.apriltag.jni;
import edu.wpi.first.apriltag.AprilTagDetection;
import edu.wpi.first.apriltag.AprilTagDetector;
import edu.wpi.first.apriltag.AprilTagPoseEstimate;
import edu.wpi.first.math.geometry.Transform3d;
import edu.wpi.first.util.RawFrame;
import edu.wpi.first.util.RuntimeLoader;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;
import org.wpilib.math.geometry.Transform3d;
import org.wpilib.util.RawFrame;
import org.wpilib.util.runtime.RuntimeLoader;
import org.wpilib.vision.apriltag.AprilTagDetection;
import org.wpilib.vision.apriltag.AprilTagDetector;
import org.wpilib.vision.apriltag.AprilTagPoseEstimate;
/** AprilTag JNI. */
public class AprilTagJNI {

View File

@@ -2,11 +2,11 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include "frc/apriltag/AprilTag.h"
#include "wpi/apriltag/AprilTag.hpp"
#include <cstring>
#include <wpi/json.h>
#include "wpi/util/json.hpp"
#ifdef _WIN32
#pragma warning(disable : 4200)
@@ -20,9 +20,9 @@
#include "tag16h5.h"
#include "tag36h11.h"
using namespace frc;
using namespace wpi::apriltag;
static bool FamilyToImage(wpi::RawFrame* frame, apriltag_family_t* family,
static bool FamilyToImage(wpi::util::RawFrame* frame, apriltag_family_t* family,
int id) {
image_u8_t* image = apriltag_to_image(family, id);
size_t totalDataSize = image->height * image->stride;
@@ -37,25 +37,25 @@ static bool FamilyToImage(wpi::RawFrame* frame, apriltag_family_t* family,
return rv;
}
bool AprilTag::Generate36h11AprilTagImage(wpi::RawFrame* frame, int id) {
bool AprilTag::Generate36h11AprilTagImage(wpi::util::RawFrame* frame, int id) {
apriltag_family_t* tagFamily = tag36h11_create();
bool rv = FamilyToImage(frame, tagFamily, id);
tag36h11_destroy(tagFamily);
return rv;
}
bool AprilTag::Generate16h5AprilTagImage(wpi::RawFrame* frame, int id) {
bool AprilTag::Generate16h5AprilTagImage(wpi::util::RawFrame* frame, int id) {
apriltag_family_t* tagFamily = tag16h5_create();
bool rv = FamilyToImage(frame, tagFamily, id);
tag16h5_destroy(tagFamily);
return rv;
}
void frc::to_json(wpi::json& json, const AprilTag& apriltag) {
json = wpi::json{{"ID", apriltag.ID}, {"pose", apriltag.pose}};
void wpi::apriltag::to_json(wpi::util::json& json, const AprilTag& apriltag) {
json = wpi::util::json::object("ID", apriltag.ID, "pose", apriltag.pose);
}
void frc::from_json(const wpi::json& json, AprilTag& apriltag) {
apriltag.ID = json.at("ID").get<int>();
apriltag.pose = json.at("pose").get<Pose3d>();
void wpi::apriltag::from_json(const wpi::util::json& json, AprilTag& apriltag) {
apriltag.ID = json.at("ID").get_int();
apriltag.pose = json.at("pose").get<wpi::math::Pose3d>();
}

View File

@@ -2,7 +2,7 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include "frc/apriltag/AprilTagDetection.h"
#include "wpi/apriltag/AprilTagDetection.hpp"
#include <type_traits>
@@ -16,7 +16,7 @@
#include "apriltag.h"
using namespace frc;
using namespace wpi::apriltag;
static_assert(sizeof(AprilTagDetection) == sizeof(apriltag_detection_t),
"structure sizes don't match");

View File

@@ -2,7 +2,7 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include "frc/apriltag/AprilTagDetector.h"
#include "wpi/apriltag/AprilTagDetector.hpp"
#include <cmath>
#include <utility>
@@ -19,7 +19,7 @@
#include "tag16h5.h"
#include "tag36h11.h"
using namespace frc;
using namespace wpi::apriltag;
AprilTagDetector::Results::Results(void* impl, const private_init&)
: span{reinterpret_cast<AprilTagDetection**>(

View File

@@ -2,38 +2,41 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include "frc/apriltag/AprilTagFieldLayout.h"
#include "wpi/apriltag/AprilTagFieldLayout.hpp"
#include <system_error>
#include <utility>
#include <vector>
#include <units/angle.h>
#include <units/length.h>
#include <wpi/MemoryBuffer.h>
#include <wpi/json.h>
#include <wpi/raw_ostream.h>
#include "wpi/units/angle.hpp"
#include "wpi/units/length.hpp"
#include "wpi/util/MemoryBuffer.hpp"
#include "wpi/util/json.hpp"
#include "wpi/util/raw_ostream.hpp"
using namespace frc;
using namespace wpi::apriltag;
AprilTagFieldLayout::AprilTagFieldLayout(std::string_view path) {
auto fileBuffer = wpi::MemoryBuffer::GetFile(path);
auto fileBuffer = wpi::util::MemoryBuffer::GetFile(path);
if (!fileBuffer) {
throw std::runtime_error(fmt::format("Cannot open file: {}", path));
}
wpi::json json = wpi::json::parse(fileBuffer.value()->GetCharBuffer());
auto buf = fileBuffer.value()->GetCharBuffer();
auto json = wpi::util::json::parse_or_throw({buf.data(), buf.size()});
for (const auto& tag : json.at("tags").get<std::vector<AprilTag>>()) {
for (auto&& jtag : json.at("tags").get_array()) {
auto tag = jtag.get<AprilTag>();
m_apriltags[tag.ID] = tag;
}
m_fieldWidth = units::meter_t{json.at("field").at("width").get<double>()};
m_fieldLength = units::meter_t{json.at("field").at("length").get<double>()};
m_fieldWidth = wpi::units::meter_t{json.at("field").at("width").get_number()};
m_fieldLength =
wpi::units::meter_t{json.at("field").at("length").get_number()};
}
AprilTagFieldLayout::AprilTagFieldLayout(std::vector<AprilTag> apriltags,
units::meter_t fieldLength,
units::meter_t fieldWidth)
wpi::units::meter_t fieldLength,
wpi::units::meter_t fieldWidth)
: m_fieldLength(std::move(fieldLength)),
m_fieldWidth(std::move(fieldWidth)) {
for (const auto& tag : apriltags) {
@@ -41,11 +44,11 @@ AprilTagFieldLayout::AprilTagFieldLayout(std::vector<AprilTag> apriltags,
}
}
units::meter_t AprilTagFieldLayout::GetFieldLength() const {
wpi::units::meter_t AprilTagFieldLayout::GetFieldLength() const {
return m_fieldLength;
}
units::meter_t AprilTagFieldLayout::GetFieldWidth() const {
wpi::units::meter_t AprilTagFieldLayout::GetFieldWidth() const {
return m_fieldWidth;
}
@@ -61,26 +64,27 @@ std::vector<AprilTag> AprilTagFieldLayout::GetTags() const {
void AprilTagFieldLayout::SetOrigin(OriginPosition origin) {
switch (origin) {
case OriginPosition::kBlueAllianceWallRightSide:
SetOrigin(Pose3d{});
SetOrigin(wpi::math::Pose3d{});
break;
case OriginPosition::kRedAllianceWallRightSide:
SetOrigin(Pose3d{Translation3d{m_fieldLength, m_fieldWidth, 0_m},
Rotation3d{0_deg, 0_deg, 180_deg}});
SetOrigin(wpi::math::Pose3d{
wpi::math::Translation3d{m_fieldLength, m_fieldWidth, 0_m},
wpi::math::Rotation3d{0_deg, 0_deg, 180_deg}});
break;
default:
throw std::invalid_argument("Invalid origin");
}
}
void AprilTagFieldLayout::SetOrigin(const Pose3d& origin) {
void AprilTagFieldLayout::SetOrigin(const wpi::math::Pose3d& origin) {
m_origin = origin;
}
Pose3d AprilTagFieldLayout::GetOrigin() const {
wpi::math::Pose3d AprilTagFieldLayout::GetOrigin() const {
return m_origin;
}
std::optional<frc::Pose3d> AprilTagFieldLayout::GetTagPose(int ID) const {
std::optional<wpi::math::Pose3d> AprilTagFieldLayout::GetTagPose(int ID) const {
const auto& it = m_apriltags.find(ID);
if (it == m_apriltags.end()) {
return std::nullopt;
@@ -91,51 +95,57 @@ std::optional<frc::Pose3d> AprilTagFieldLayout::GetTagPose(int ID) const {
void AprilTagFieldLayout::Serialize(std::string_view path) {
std::error_code error_code;
wpi::raw_fd_ostream output{path, error_code};
wpi::util::raw_fd_ostream output{path, error_code};
if (error_code) {
throw std::runtime_error(fmt::format("Cannot open file: {}", path));
}
wpi::json json = *this;
wpi::util::json json = *this;
output << json;
output.flush();
}
void frc::to_json(wpi::json& json, const AprilTagFieldLayout& layout) {
void wpi::apriltag::to_json(wpi::util::json& json,
const AprilTagFieldLayout& layout) {
std::vector<AprilTag> tagVector;
tagVector.reserve(layout.m_apriltags.size());
for (const auto& pair : layout.m_apriltags) {
tagVector.push_back(pair.second);
}
json = wpi::json{{"field",
{{"length", layout.m_fieldLength.value()},
{"width", layout.m_fieldWidth.value()}}},
{"tags", tagVector}};
auto field = wpi::util::json::object("length", layout.m_fieldLength.value(),
"width", layout.m_fieldWidth.value());
json = wpi::util::json::object("field", std::move(field), "tags",
std::move(tagVector));
}
void frc::from_json(const wpi::json& json, AprilTagFieldLayout& layout) {
void wpi::apriltag::from_json(const wpi::util::json& json,
AprilTagFieldLayout& layout) {
layout.m_apriltags.clear();
for (const auto& tag : json.at("tags").get<std::vector<AprilTag>>()) {
for (auto&& jtag : json.at("tags").get_array()) {
auto tag = jtag.get<AprilTag>();
layout.m_apriltags[tag.ID] = tag;
}
layout.m_fieldLength =
units::meter_t{json.at("field").at("length").get<double>()};
wpi::units::meter_t{json.at("field").at("length").get_number()};
layout.m_fieldWidth =
units::meter_t{json.at("field").at("width").get<double>()};
wpi::units::meter_t{json.at("field").at("width").get_number()};
}
// Use namespace declaration for forward declaration
namespace frc {
namespace wpi::apriltag {
// C++ generated from resource files
std::string_view GetResource_2022_rapidreact_json();
std::string_view GetResource_2023_chargedup_json();
std::string_view GetResource_2024_crescendo_json();
std::string_view GetResource_2025_reefscape_json();
std::string_view GetResource_2025_reefscape_welded_json();
std::string_view GetResource_2025_reefscape_andymark_json();
std::string_view GetResource_2026_rebuilt_welded_json();
std::string_view GetResource_2026_rebuilt_andymark_json();
} // namespace frc
} // namespace wpi::apriltag
AprilTagFieldLayout AprilTagFieldLayout::LoadField(AprilTagField field) {
std::string_view fieldString;
@@ -149,17 +159,22 @@ AprilTagFieldLayout AprilTagFieldLayout::LoadField(AprilTagField field) {
case AprilTagField::k2024Crescendo:
fieldString = GetResource_2024_crescendo_json();
break;
case AprilTagField::k2025Reefscape:
fieldString = GetResource_2025_reefscape_json();
case AprilTagField::k2025ReefscapeWelded:
fieldString = GetResource_2025_reefscape_welded_json();
break;
case AprilTagField::k2025ReefscapeAndyMark:
fieldString = GetResource_2025_reefscape_andymark_json();
break;
case AprilTagField::k2026RebuiltWelded:
fieldString = GetResource_2026_rebuilt_welded_json();
break;
case AprilTagField::k2026RebuiltAndyMark:
fieldString = GetResource_2026_rebuilt_andymark_json();
break;
case AprilTagField::kNumFields:
throw std::invalid_argument("Invalid Field");
}
wpi::json json = wpi::json::parse(fieldString);
wpi::util::json json = wpi::util::json::parse_or_throw(fieldString);
return json.get<AprilTagFieldLayout>();
}
AprilTagFieldLayout frc::LoadAprilTagLayoutField(AprilTagField field) {
return AprilTagFieldLayout::LoadField(field);
}

View File

@@ -2,11 +2,11 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include "frc/apriltag/AprilTagPoseEstimate.h"
#include "wpi/apriltag/AprilTagPoseEstimate.hpp"
#include <algorithm>
using namespace frc;
using namespace wpi::apriltag;
double AprilTagPoseEstimate::GetAmbiguity() const {
auto min = (std::min)(error1, error2);

View File

@@ -2,11 +2,11 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include "frc/apriltag/AprilTagPoseEstimator.h"
#include "wpi/apriltag/AprilTagPoseEstimator.hpp"
#include <Eigen/QR>
#include "frc/apriltag/AprilTagDetection.h"
#include "wpi/apriltag/AprilTagDetection.hpp"
#ifdef _WIN32
#pragma warning(disable : 4200)
@@ -19,7 +19,7 @@
#include "apriltag.h"
#include "apriltag_pose.h"
using namespace frc;
using namespace wpi::apriltag;
static Eigen::Matrix3d OrthogonalizeRotationMatrix(
const Eigen::Matrix3d& input) {
@@ -42,14 +42,14 @@ static Eigen::Matrix3d OrthogonalizeRotationMatrix(
return Q;
}
static Transform3d MakePose(const apriltag_pose_t& pose) {
static wpi::math::Transform3d MakePose(const apriltag_pose_t& pose) {
if (!pose.R || !pose.t) {
return {};
}
return {Translation3d{units::meter_t{pose.t->data[0]},
units::meter_t{pose.t->data[1]},
units::meter_t{pose.t->data[2]}},
Rotation3d{OrthogonalizeRotationMatrix(
return {wpi::math::Translation3d{wpi::units::meter_t{pose.t->data[0]},
wpi::units::meter_t{pose.t->data[1]},
wpi::units::meter_t{pose.t->data[2]}},
wpi::math::Rotation3d{OrthogonalizeRotationMatrix(
Eigen::Map<Eigen::Matrix<double, 3, 3, Eigen::RowMajor>>{
pose.R->data})}};
}
@@ -80,7 +80,7 @@ static apriltag_detection_t MakeBasicDet(
return detection;
}
static Transform3d DoEstimateHomography(
static wpi::math::Transform3d DoEstimateHomography(
const apriltag_detection_t* detection,
const AprilTagPoseEstimator::Config& config) {
auto info = MakeDetectionInfo(detection, config);
@@ -89,13 +89,13 @@ static Transform3d DoEstimateHomography(
return MakePose(pose);
}
Transform3d AprilTagPoseEstimator::EstimateHomography(
wpi::math::Transform3d AprilTagPoseEstimator::EstimateHomography(
const AprilTagDetection& detection) const {
return DoEstimateHomography(
reinterpret_cast<const apriltag_detection_t*>(&detection), m_config);
}
Transform3d AprilTagPoseEstimator::EstimateHomography(
wpi::math::Transform3d AprilTagPoseEstimator::EstimateHomography(
std::span<const double, 9> homography) const {
auto detection = MakeBasicDet(homography, nullptr);
auto rv = DoEstimateHomography(&detection, m_config);
@@ -130,21 +130,22 @@ AprilTagPoseEstimate AprilTagPoseEstimator::EstimateOrthogonalIteration(
return rv;
}
static Transform3d DoEstimate(const apriltag_detection_t* detection,
const AprilTagPoseEstimator::Config& config) {
static wpi::math::Transform3d DoEstimate(
const apriltag_detection_t* detection,
const AprilTagPoseEstimator::Config& config) {
auto info = MakeDetectionInfo(detection, config);
apriltag_pose_t pose;
estimate_tag_pose(&info, &pose);
return MakePose(pose);
}
Transform3d AprilTagPoseEstimator::Estimate(
wpi::math::Transform3d AprilTagPoseEstimator::Estimate(
const AprilTagDetection& detection) const {
return DoEstimate(reinterpret_cast<const apriltag_detection_t*>(&detection),
m_config);
}
Transform3d AprilTagPoseEstimator::Estimate(
wpi::math::Transform3d AprilTagPoseEstimator::Estimate(
std::span<const double, 9> homography,
std::span<const double, 8> corners) const {
auto detection = MakeBasicDet(homography, &corners);

View File

@@ -8,16 +8,15 @@
#include <cstring>
#define WPI_RAWFRAME_JNI
#include <wpi/RawFrame.h>
#include <wpi/jni_util.h>
#include "org_wpilib_vision_apriltag_jni_AprilTagJNI.h"
#include "wpi/apriltag/AprilTag.hpp"
#include "wpi/apriltag/AprilTagDetector.hpp"
#include "wpi/apriltag/AprilTagPoseEstimator.hpp"
#include "wpi/util/RawFrame.h"
#include "wpi/util/jni_util.hpp"
#include "edu_wpi_first_apriltag_jni_AprilTagJNI.h"
#include "frc/apriltag/AprilTag.h"
#include "frc/apriltag/AprilTagDetector.h"
#include "frc/apriltag/AprilTagPoseEstimator.h"
using namespace frc;
using namespace wpi::java;
using namespace wpi::apriltag;
using namespace wpi::util::java;
static JavaVM* jvm = nullptr;
@@ -34,16 +33,16 @@ static JException illegalArgEx;
static JException nullPointerEx;
static const JClassInit classes[] = {
{"edu/wpi/first/apriltag/AprilTagDetection", &detectionCls},
{"edu/wpi/first/apriltag/AprilTagDetector$Config", &detectorConfigCls},
{"edu/wpi/first/apriltag/AprilTagDetector$QuadThresholdParameters",
{"org/wpilib/vision/apriltag/AprilTagDetection", &detectionCls},
{"org/wpilib/vision/apriltag/AprilTagDetector$Config", &detectorConfigCls},
{"org/wpilib/vision/apriltag/AprilTagDetector$QuadThresholdParameters",
&detectorQTPCls},
{"edu/wpi/first/apriltag/AprilTagPoseEstimate", &poseEstimateCls},
{"edu/wpi/first/math/geometry/Quaternion", &quaternionCls},
{"edu/wpi/first/math/geometry/Rotation3d", &rotation3dCls},
{"edu/wpi/first/math/geometry/Transform3d", &transform3dCls},
{"edu/wpi/first/math/geometry/Translation3d", &translation3dCls},
{"edu/wpi/first/util/RawFrame", &rawFrameCls}};
{"org/wpilib/vision/apriltag/AprilTagPoseEstimate", &poseEstimateCls},
{"org/wpilib/math/geometry/Quaternion", &quaternionCls},
{"org/wpilib/math/geometry/Rotation3d", &rotation3dCls},
{"org/wpilib/math/geometry/Transform3d", &transform3dCls},
{"org/wpilib/math/geometry/Translation3d", &translation3dCls},
{"org/wpilib/util/RawFrame", &rawFrameCls}};
static const JExceptionInit exceptions[] = {
{"java/lang/IllegalArgumentException", &illegalArgEx},
@@ -162,7 +161,7 @@ static AprilTagDetector::QuadThresholdParameters FromJavaDetectorQTP(
return {
FIELD(int, Int, minClusterPixels),
FIELD(int, Int, maxNumMaxima),
.criticalAngle = units::radian_t{static_cast<double>(
.criticalAngle = wpi::units::radian_t{static_cast<double>(
env->GetDoubleField(jparams, criticalAngleField))},
FIELD(float, Float, maxLineFitMSE),
FIELD(int, Int, minWhiteBlackDiff),
@@ -256,7 +255,7 @@ static jobject MakeJObject(
static_cast<jboolean>(params.deglitch));
}
static jobject MakeJObject(JNIEnv* env, const Translation3d& xlate) {
static jobject MakeJObject(JNIEnv* env, const wpi::math::Translation3d& xlate) {
static jmethodID constructor =
env->GetMethodID(translation3dCls, "<init>", "(DDD)V");
if (!constructor) {
@@ -268,7 +267,7 @@ static jobject MakeJObject(JNIEnv* env, const Translation3d& xlate) {
static_cast<jdouble>(xlate.Y()), static_cast<jdouble>(xlate.Z()));
}
static jobject MakeJObject(JNIEnv* env, const Quaternion& q) {
static jobject MakeJObject(JNIEnv* env, const wpi::math::Quaternion& q) {
static jmethodID constructor =
env->GetMethodID(quaternionCls, "<init>", "(DDDD)V");
if (!constructor) {
@@ -281,9 +280,9 @@ static jobject MakeJObject(JNIEnv* env, const Quaternion& q) {
static_cast<jdouble>(q.Z()));
}
static jobject MakeJObject(JNIEnv* env, const Rotation3d& rot) {
static jobject MakeJObject(JNIEnv* env, const wpi::math::Rotation3d& rot) {
static jmethodID constructor = env->GetMethodID(
rotation3dCls, "<init>", "(Ledu/wpi/first/math/geometry/Quaternion;)V");
rotation3dCls, "<init>", "(Lorg/wpilib/math/geometry/Quaternion;)V");
if (!constructor) {
return nullptr;
}
@@ -292,11 +291,11 @@ static jobject MakeJObject(JNIEnv* env, const Rotation3d& rot) {
return env->NewObject(rotation3dCls, constructor, q.obj());
}
static jobject MakeJObject(JNIEnv* env, const Transform3d& xform) {
static jobject MakeJObject(JNIEnv* env, const wpi::math::Transform3d& xform) {
static jmethodID constructor =
env->GetMethodID(transform3dCls, "<init>",
"(Ledu/wpi/first/math/geometry/Translation3d;"
"Ledu/wpi/first/math/geometry/Rotation3d;)V");
"(Lorg/wpilib/math/geometry/Translation3d;"
"Lorg/wpilib/math/geometry/Rotation3d;)V");
if (!constructor) {
return nullptr;
}
@@ -309,8 +308,8 @@ static jobject MakeJObject(JNIEnv* env, const Transform3d& xform) {
static jobject MakeJObject(JNIEnv* env, const AprilTagPoseEstimate& est) {
static jmethodID constructor =
env->GetMethodID(poseEstimateCls, "<init>",
"(Ledu/wpi/first/math/geometry/Transform3d;"
"Ledu/wpi/first/math/geometry/Transform3d;DD)V");
"(Lorg/wpilib/math/geometry/Transform3d;"
"Lorg/wpilib/math/geometry/Transform3d;DD)V");
if (!constructor) {
return nullptr;
}
@@ -325,36 +324,36 @@ static jobject MakeJObject(JNIEnv* env, const AprilTagPoseEstimate& est) {
extern "C" {
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Class: org_wpilib_vision_apriltag_jni_AprilTagJNI
* Method: createDetector
* Signature: ()J
*/
JNIEXPORT jlong JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_createDetector
Java_org_wpilib_vision_apriltag_jni_AprilTagJNI_createDetector
(JNIEnv* env, jclass)
{
return reinterpret_cast<jlong>(new AprilTagDetector);
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Class: org_wpilib_vision_apriltag_jni_AprilTagJNI
* Method: destroyDetector
* Signature: (J)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_destroyDetector
Java_org_wpilib_vision_apriltag_jni_AprilTagJNI_destroyDetector
(JNIEnv* env, jclass, jlong det)
{
delete reinterpret_cast<AprilTagDetector*>(det);
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Class: org_wpilib_vision_apriltag_jni_AprilTagJNI
* Method: setDetectorConfig
* Signature: (JLjava/lang/Object;)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_setDetectorConfig
Java_org_wpilib_vision_apriltag_jni_AprilTagJNI_setDetectorConfig
(JNIEnv* env, jclass, jlong det, jobject config)
{
if (det == 0) {
@@ -366,12 +365,12 @@ Java_edu_wpi_first_apriltag_jni_AprilTagJNI_setDetectorConfig
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Class: org_wpilib_vision_apriltag_jni_AprilTagJNI
* Method: getDetectorConfig
* Signature: (J)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_getDetectorConfig
Java_org_wpilib_vision_apriltag_jni_AprilTagJNI_getDetectorConfig
(JNIEnv* env, jclass, jlong det)
{
if (det == 0) {
@@ -383,12 +382,12 @@ Java_edu_wpi_first_apriltag_jni_AprilTagJNI_getDetectorConfig
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Class: org_wpilib_vision_apriltag_jni_AprilTagJNI
* Method: setDetectorQTP
* Signature: (JLjava/lang/Object;)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_setDetectorQTP
Java_org_wpilib_vision_apriltag_jni_AprilTagJNI_setDetectorQTP
(JNIEnv* env, jclass, jlong det, jobject params)
{
if (det == 0) {
@@ -400,12 +399,12 @@ Java_edu_wpi_first_apriltag_jni_AprilTagJNI_setDetectorQTP
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Class: org_wpilib_vision_apriltag_jni_AprilTagJNI
* Method: getDetectorQTP
* Signature: (J)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_getDetectorQTP
Java_org_wpilib_vision_apriltag_jni_AprilTagJNI_getDetectorQTP
(JNIEnv* env, jclass, jlong det)
{
if (det == 0) {
@@ -418,12 +417,12 @@ Java_edu_wpi_first_apriltag_jni_AprilTagJNI_getDetectorQTP
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Class: org_wpilib_vision_apriltag_jni_AprilTagJNI
* Method: addFamily
* Signature: (JLjava/lang/String;I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_addFamily
Java_org_wpilib_vision_apriltag_jni_AprilTagJNI_addFamily
(JNIEnv* env, jclass, jlong det, jstring fam, jint bitsCorrected)
{
if (det == 0) {
@@ -439,12 +438,12 @@ Java_edu_wpi_first_apriltag_jni_AprilTagJNI_addFamily
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Class: org_wpilib_vision_apriltag_jni_AprilTagJNI
* Method: removeFamily
* Signature: (JLjava/lang/String;)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_removeFamily
Java_org_wpilib_vision_apriltag_jni_AprilTagJNI_removeFamily
(JNIEnv* env, jclass, jlong det, jstring fam)
{
if (det == 0) {
@@ -459,12 +458,12 @@ Java_edu_wpi_first_apriltag_jni_AprilTagJNI_removeFamily
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Class: org_wpilib_vision_apriltag_jni_AprilTagJNI
* Method: clearFamilies
* Signature: (J)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_clearFamilies
Java_org_wpilib_vision_apriltag_jni_AprilTagJNI_clearFamilies
(JNIEnv* env, jclass, jlong det)
{
if (det == 0) {
@@ -475,12 +474,12 @@ Java_edu_wpi_first_apriltag_jni_AprilTagJNI_clearFamilies
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Class: org_wpilib_vision_apriltag_jni_AprilTagJNI
* Method: detect
* Signature: (JIIIJ)[Ljava/lang/Object;
*/
JNIEXPORT jobjectArray JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_detect
Java_org_wpilib_vision_apriltag_jni_AprilTagJNI_detect
(JNIEnv* env, jclass, jlong det, jint width, jint height, jint stride,
jlong bufAddr)
{
@@ -498,12 +497,12 @@ Java_edu_wpi_first_apriltag_jni_AprilTagJNI_detect
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Class: org_wpilib_vision_apriltag_jni_AprilTagJNI
* Method: estimatePoseHomography
* Signature: ([DDDDDD)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_estimatePoseHomography
Java_org_wpilib_vision_apriltag_jni_AprilTagJNI_estimatePoseHomography
(JNIEnv* env, jclass, jdoubleArray homography, jdouble tagSize, jdouble fx,
jdouble fy, jdouble cx, jdouble cy)
{
@@ -517,17 +516,18 @@ Java_edu_wpi_first_apriltag_jni_AprilTagJNI_estimatePoseHomography
return nullptr;
}
AprilTagPoseEstimator estimator({units::meter_t{tagSize}, fx, fy, cx, cy});
AprilTagPoseEstimator estimator(
{wpi::units::meter_t{tagSize}, fx, fy, cx, cy});
return MakeJObject(env, estimator.EstimateHomography(harr));
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Class: org_wpilib_vision_apriltag_jni_AprilTagJNI
* Method: estimatePoseOrthogonalIteration
* Signature: ([D[DDDDDDI)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_estimatePoseOrthogonalIteration
Java_org_wpilib_vision_apriltag_jni_AprilTagJNI_estimatePoseOrthogonalIteration
(JNIEnv* env, jclass, jdoubleArray homography, jdoubleArray corners,
jdouble tagSize, jdouble fx, jdouble fy, jdouble cx, jdouble cy, jint nIters)
{
@@ -553,18 +553,19 @@ Java_edu_wpi_first_apriltag_jni_AprilTagJNI_estimatePoseOrthogonalIteration
return nullptr;
}
AprilTagPoseEstimator estimator({units::meter_t{tagSize}, fx, fy, cx, cy});
AprilTagPoseEstimator estimator(
{wpi::units::meter_t{tagSize}, fx, fy, cx, cy});
return MakeJObject(env,
estimator.EstimateOrthogonalIteration(harr, carr, nIters));
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Class: org_wpilib_vision_apriltag_jni_AprilTagJNI
* Method: estimatePose
* Signature: ([D[DDDDDD)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_estimatePose
Java_org_wpilib_vision_apriltag_jni_AprilTagJNI_estimatePose
(JNIEnv* env, jclass, jdoubleArray homography, jdoubleArray corners,
jdouble tagSize, jdouble fx, jdouble fy, jdouble cx, jdouble cy)
{
@@ -590,45 +591,46 @@ Java_edu_wpi_first_apriltag_jni_AprilTagJNI_estimatePose
return nullptr;
}
AprilTagPoseEstimator estimator({units::meter_t{tagSize}, fx, fy, cx, cy});
AprilTagPoseEstimator estimator(
{wpi::units::meter_t{tagSize}, fx, fy, cx, cy});
return MakeJObject(env, estimator.Estimate(harr, carr));
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Class: org_wpilib_vision_apriltag_jni_AprilTagJNI
* Method: generate16h5AprilTagImage
* Signature: (Ljava/lang/Object;JI)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_generate16h5AprilTagImage
Java_org_wpilib_vision_apriltag_jni_AprilTagJNI_generate16h5AprilTagImage
(JNIEnv* env, jclass, jobject frameObj, jlong framePtr, jint id)
{
auto* frame = reinterpret_cast<wpi::RawFrame*>(framePtr);
auto* frame = reinterpret_cast<wpi::util::RawFrame*>(framePtr);
if (!frame) {
nullPointerEx.Throw(env, "frame is null");
return;
}
bool newData = AprilTag::Generate16h5AprilTagImage(frame, id);
wpi::SetFrameData(env, rawFrameCls, frameObj, *frame, newData);
wpi::util::SetFrameData(env, rawFrameCls, frameObj, *frame, newData);
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Class: org_wpilib_vision_apriltag_jni_AprilTagJNI
* Method: generate36h11AprilTagImage
* Signature: (Ljava/lang/Object;JI)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_generate36h11AprilTagImage
Java_org_wpilib_vision_apriltag_jni_AprilTagJNI_generate36h11AprilTagImage
(JNIEnv* env, jclass, jobject frameObj, jlong framePtr, jint id)
{
auto* frame = reinterpret_cast<wpi::RawFrame*>(framePtr);
auto* frame = reinterpret_cast<wpi::util::RawFrame*>(framePtr);
if (!frame) {
nullPointerEx.Throw(env, "frame is null");
return;
}
// function might reallocate
bool newData = AprilTag::Generate36h11AprilTagImage(frame, id);
wpi::SetFrameData(env, rawFrameCls, frameObj, *frame, newData);
wpi::util::SetFrameData(env, rawFrameCls, frameObj, *frame, newData);
}
} // extern "C"

View File

@@ -1,37 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <wpi/RawFrame.h>
#include <wpi/SymbolExports.h>
#include <wpi/json_fwd.h>
#include "frc/geometry/Pose3d.h"
namespace frc {
/**
* Represents an AprilTag's metadata.
*/
struct WPILIB_DLLEXPORT AprilTag {
/// The tag's ID.
int ID;
/// The tag's pose.
Pose3d pose;
bool operator==(const AprilTag&) const = default;
static bool Generate36h11AprilTagImage(wpi::RawFrame* frame, int id);
static bool Generate16h5AprilTagImage(wpi::RawFrame* frame, int id);
};
WPILIB_DLLEXPORT
void to_json(wpi::json& json, const AprilTag& apriltag);
WPILIB_DLLEXPORT
void from_json(const wpi::json& json, AprilTag& apriltag);
} // namespace frc

View File

@@ -1,160 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <stdint.h>
#include <span>
#include <string_view>
#include <Eigen/Core>
#include <wpi/SymbolExports.h>
namespace frc {
/**
* A detection of an AprilTag tag.
*/
class WPILIB_DLLEXPORT AprilTagDetection final {
public:
AprilTagDetection() = delete;
AprilTagDetection(const AprilTagDetection&) = delete;
AprilTagDetection& operator=(const AprilTagDetection&) = delete;
/** A point. Used for center and corner points. */
struct Point {
double x;
double y;
};
/**
* Gets the decoded tag's family name.
*
* @return Decoded family name
*/
std::string_view GetFamily() const;
/**
* Gets the decoded ID of the tag.
*
* @return Decoded ID
*/
int GetId() const { return id; }
/**
* Gets how many error bits were corrected. Note: accepting large numbers of
* corrected errors leads to greatly increased false positive rates.
* NOTE: As of this implementation, the detector cannot detect tags with
* a hamming distance greater than 2.
*
* @return Hamming distance (number of corrected error bits)
*/
int GetHamming() const { return hamming; }
/**
* Gets a measure of the quality of the binary decoding process: the
* average difference between the intensity of a data bit versus
* the decision threshold. Higher numbers roughly indicate better
* decodes. This is a reasonable measure of detection accuracy
* only for very small tags-- not effective for larger tags (where
* we could have sampled anywhere within a bit cell and still
* gotten a good detection.)
*
* @return Decision margin
*/
float GetDecisionMargin() const { return decision_margin; }
/**
* Gets the 3x3 homography matrix describing the projection from an
* "ideal" tag (with corners at (-1,1), (1,1), (1,-1), and (-1,
* -1)) to pixels in the image.
*
* @return Homography matrix data
*/
std::span<const double, 9> GetHomography() const;
/**
* Gets the 3x3 homography matrix describing the projection from an
* "ideal" tag (with corners at (-1,1), (1,1), (1,-1), and (-1,
* -1)) to pixels in the image.
*
* @return Homography matrix
*/
Eigen::Matrix3d GetHomographyMatrix() const;
/**
* Gets the center of the detection in image pixel coordinates.
*
* @return Center point
*/
const Point& GetCenter() const { return *reinterpret_cast<const Point*>(c); }
/**
* Gets a corner of the tag in image pixel coordinates. These always
* wrap counter-clock wise around the tag. Index 0 is the bottom left corner.
*
* @param ndx Corner index (range is 0-3, inclusive)
* @return Corner point
*/
const Point& GetCorner(int ndx) const {
return *reinterpret_cast<const Point*>(p[ndx]);
}
/**
* Gets the corners of the tag in image pixel coordinates. These always
* wrap counter-clock wise around the tag. The first set of corner coordinates
* are the coordinates for the bottom left corner.
*
* @param cornersBuf Corner point array (X and Y for each corner in order)
* @return Corner point array (copy of cornersBuf span)
*/
std::span<double, 8> GetCorners(std::span<double, 8> cornersBuf) const {
for (int i = 0; i < 4; i++) {
cornersBuf[i * 2] = p[i][0];
cornersBuf[i * 2 + 1] = p[i][1];
}
return cornersBuf;
}
private:
// This class *must* be standard-layout-compatible with apriltag_detection
// as we use reinterpret_cast from that structure. This means the below
// members must exactly match the contents of the apriltag_detection struct.
// The tag family.
void* family;
// The decoded ID of the tag.
int id;
// How many error bits were corrected? Note: accepting large numbers of
// corrected errors leads to greatly increased false positive rates.
// NOTE: As of this implementation, the detector cannot detect tags with
// a hamming distance greater than 2.
int hamming;
// A measure of the quality of the binary decoding process: the
// average difference between the intensity of a data bit versus
// the decision threshold. Higher numbers roughly indicate better
// decodes. This is a reasonable measure of detection accuracy
// only for very small tags-- not effective for larger tags (where
// we could have sampled anywhere within a bit cell and still
// gotten a good detection.)
float decision_margin;
// The 3x3 homography matrix describing the projection from an
// "ideal" tag (with corners at (-1,1), (1,1), (1,-1), and (-1,
// -1)) to pixels in the image.
void* H;
// The center of the detection in image pixel coordinates.
double c[2];
// The corners of the tag in image pixel coordinates. These always
// wrap counter-clock wise around the tag.
double p[4][2];
};
} // namespace frc

View File

@@ -1,262 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <stdint.h>
#include <memory>
#include <span>
#include <string_view>
#include <utility>
#include <units/angle.h>
#include <wpi/StringMap.h>
#include <wpi/SymbolExports.h>
#include "frc/apriltag/AprilTagDetection.h"
namespace frc {
/**
* An AprilTag detector engine. This is expensive to set up and tear down, so
* most use cases should only create one of these, add a family to it, set up
* any other configuration, and repeatedly call Detect().
*/
class WPILIB_DLLEXPORT AprilTagDetector {
public:
/** Detector configuration. */
struct Config {
bool operator==(const Config&) const = default;
/**
* How many threads should be used for computation. Default is
* single-threaded operation (1 thread).
*/
int numThreads = 1;
/**
* Quad decimation. Detection of quads can be done on a lower-resolution
* image, improving speed at a cost of pose accuracy and a slight decrease
* in detection rate. Decoding the binary payload is still done at full
* resolution. Default is 2.0.
*/
float quadDecimate = 2.0f;
/**
* What Gaussian blur should be applied to the segmented image (used for
* quad detection). Very noisy images benefit from non-zero values (e.g.
* 0.8). Default is 0.0.
*/
float quadSigma = 0.0f;
/**
* When true, the edges of the each quad are adjusted to "snap to" strong
* gradients nearby. This is useful when decimation is employed, as it can
* increase the quality of the initial quad estimate substantially.
* Generally recommended to be on (true). Default is true.
*
* Very computationally inexpensive. Option is ignored if
* quad_decimate = 1.
*/
bool refineEdges = true;
/**
* How much sharpening should be done to decoded images. This can help
* decode small tags but may or may not help in odd lighting conditions or
* low light conditions. Default is 0.25.
*/
double decodeSharpening = 0.25;
/**
* Debug mode. When true, the decoder writes a variety of debugging images
* to the current working directory at various stages through the detection
* process. This is slow and should *not* be used on space-limited systems
* such as the RoboRIO. Default is disabled (false).
*/
bool debug = false;
};
/** Quad threshold parameters. */
struct QuadThresholdParameters {
bool operator==(const QuadThresholdParameters&) const = default;
/**
* Threshold used to reject quads containing too few pixels. Default is 300
* pixels.
*/
int minClusterPixels = 300;
/**
* How many corner candidates to consider when segmenting a group of pixels
* into a quad. Default is 10.
*/
int maxNumMaxima = 10;
/**
* Critical angle. The detector will reject quads where pairs of edges have
* angles that are close to straight or close to 180 degrees. Zero means
* that no quads are rejected. Default is 45 degrees.
*/
units::radian_t criticalAngle = 45_deg;
/**
* When fitting lines to the contours, the maximum mean squared error
* allowed. This is useful in rejecting contours that are far from being
* quad shaped; rejecting these quads "early" saves expensive decoding
* processing. Default is 10.0.
*/
float maxLineFitMSE = 10.0f;
/**
* Minimum brightness offset. When we build our model of black & white
* pixels, we add an extra check that the white model must be (overall)
* brighter than the black model. How much brighter? (in pixel values,
* [0,255]). Default is 5.
*/
int minWhiteBlackDiff = 5;
/**
* Whether the thresholded image be should be deglitched. Only useful for
* very noisy images. Default is disabled (false).
*/
bool deglitch = false;
};
/**
* Array of detection results. Each array element is a pointer to an
* AprilTagDetection.
*/
class WPILIB_DLLEXPORT Results
: public std::span<AprilTagDetection const* const> {
struct private_init {};
friend class AprilTagDetector;
public:
Results() = default;
Results(void* impl, const private_init&);
~Results() { Destroy(); }
Results(const Results&) = delete;
Results& operator=(const Results&) = delete;
Results(Results&& rhs) : span{std::move(rhs)}, m_impl{rhs.m_impl} {
rhs.m_impl = nullptr;
}
Results& operator=(Results&& rhs);
private:
void Destroy();
void* m_impl = nullptr;
};
AprilTagDetector();
~AprilTagDetector() { Destroy(); }
AprilTagDetector(const AprilTagDetector&) = delete;
AprilTagDetector& operator=(const AprilTagDetector&) = delete;
AprilTagDetector(AprilTagDetector&& rhs)
: m_impl{rhs.m_impl},
m_families{std::move(rhs.m_families)},
m_qtpCriticalAngle{rhs.m_qtpCriticalAngle} {
rhs.m_impl = nullptr;
}
AprilTagDetector& operator=(AprilTagDetector&& rhs);
/**
* @{
* @name Configuration functions
*/
/**
* Sets detector configuration.
*
* @param config Configuration
*/
void SetConfig(const Config& config);
/**
* Gets detector configuration.
*
* @return Configuration
*/
Config GetConfig() const;
/**
* Sets quad threshold parameters.
*
* @param params Parameters
*/
void SetQuadThresholdParameters(const QuadThresholdParameters& params);
/**
* Gets quad threshold parameters.
*
* @return Parameters
*/
QuadThresholdParameters GetQuadThresholdParameters() const;
/** @} */
/**
* @{
* @name Tag family functions
*/
/**
* Adds a family of tags to be detected.
*
* @param fam Family name, e.g. "tag16h5"
* @param bitsCorrected Maximum number of bits to correct
* @return False if family can't be found
*/
bool AddFamily(std::string_view fam, int bitsCorrected = 2);
/**
* Removes a family of tags from the detector.
*
* @param fam Family name, e.g. "tag16h5"
*/
void RemoveFamily(std::string_view fam);
/**
* Unregister all families.
*/
void ClearFamilies();
/** @} */
/**
* Detect tags from an 8-bit image.
* The image must be grayscale.
*
* @param width width of the image
* @param height height of the image
* @param stride number of bytes between image rows (often the same as width)
* @param buf image buffer
* @return Results (array of AprilTagDetection pointers)
*/
Results Detect(int width, int height, int stride, uint8_t* buf);
/**
* Detect tags from an 8-bit image.
* The image must be grayscale.
*
* @param width width of the image
* @param height height of the image
* @param buf image buffer
* @return Results (array of AprilTagDetection pointers)
*/
Results Detect(int width, int height, uint8_t* buf) {
return Detect(width, height, width, buf);
}
private:
void Destroy();
void DestroyFamilies();
void DestroyFamily(std::string_view name, void* data);
void* m_impl;
wpi::StringMap<void*> m_families;
units::radian_t m_qtpCriticalAngle = 10_deg;
};
} // namespace frc

View File

@@ -1,18 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <opencv2/core/mat.hpp>
#include "frc/apriltag/AprilTagDetector.h"
namespace frc {
inline AprilTagDetector::Results AprilTagDetect(AprilTagDetector& detector,
cv::Mat& image) {
return detector.Detect(image.cols, image.rows, image.data);
}
} // namespace frc

View File

@@ -1,175 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <optional>
#include <string_view>
#include <unordered_map>
#include <vector>
#include <units/length.h>
#include <wpi/SymbolExports.h>
#include <wpi/json_fwd.h>
#include "frc/apriltag/AprilTag.h"
#include "frc/apriltag/AprilTagFields.h"
#include "frc/geometry/Pose3d.h"
namespace frc {
/**
* Class for representing a layout of AprilTags on a field and reading them from
* a JSON format.
*
* The JSON format contains two top-level objects, "tags" and "field".
* The "tags" object is a list of all AprilTags contained within a layout. Each
* AprilTag serializes to a JSON object containing an ID and a Pose3d. The
* "field" object is a descriptor of the size of the field in meters with
* "width" and "length" values. This is to account for arbitrary field sizes
* when transforming the poses.
*
* Pose3ds in the JSON are measured using the normal FRC coordinate system, NWU
* with the origin at the bottom-right corner of the blue alliance wall.
* SetOrigin(OriginPosition) can be used to change the poses returned from
* GetTagPose(int) to be from the perspective of a specific alliance.
*
* Tag poses represent the center of the tag, with a zero rotation representing
* a tag that is upright and facing away from the (blue) alliance wall (that is,
* towards the opposing alliance). */
class WPILIB_DLLEXPORT AprilTagFieldLayout {
public:
/**
* Common origin positions for the AprilTag coordinate system.
*/
enum class OriginPosition {
/// Blue alliance wall, right side.
kBlueAllianceWallRightSide,
/// Red alliance wall, right side.
kRedAllianceWallRightSide,
};
/**
* Loads an AprilTagFieldLayout from a predefined field
*
* @param field The predefined field
* @return AprilTagFieldLayout of the field
*/
static AprilTagFieldLayout LoadField(AprilTagField field);
AprilTagFieldLayout() = default;
/**
* Construct a new AprilTagFieldLayout with values imported from a JSON file.
*
* @param path Path of the JSON file to import from.
*/
explicit AprilTagFieldLayout(std::string_view path);
/**
* Construct a new AprilTagFieldLayout from a vector of AprilTag objects.
*
* @param apriltags Vector of AprilTags.
* @param fieldLength Length of field the layout is representing.
* @param fieldWidth Width of field the layout is representing.
*/
AprilTagFieldLayout(std::vector<AprilTag> apriltags,
units::meter_t fieldLength, units::meter_t fieldWidth);
/**
* Returns the length of the field the layout is representing.
* @return length
*/
units::meter_t GetFieldLength() const;
/**
* Returns the length of the field the layout is representing.
* @return width
*/
units::meter_t GetFieldWidth() const;
/**
* Returns a vector of all the april tags used in this layout.
* @return list of tags
*/
std::vector<AprilTag> GetTags() const;
/**
* Sets the origin based on a predefined enumeration of coordinate frame
* origins. The origins are calculated from the field dimensions.
*
* This transforms the Pose3ds returned by GetTagPose(int) to return the
* correct pose relative to a predefined coordinate frame.
*
* @param origin The predefined origin
*/
void SetOrigin(OriginPosition origin);
/**
* Sets the origin for tag pose transformation.
*
* This transforms the Pose3ds returned by GetTagPose(int) to return the
* correct pose relative to the provided origin.
*
* @param origin The new origin for tag transformations
*/
void SetOrigin(const Pose3d& origin);
/**
* Returns the origin used for tag pose transformation.
* @return the origin
*/
Pose3d GetOrigin() const;
/**
* Gets an AprilTag pose by its ID.
*
* @param ID The ID of the tag.
* @return The pose corresponding to the ID that was passed in or an empty
* optional if a tag with that ID is not found.
*/
std::optional<Pose3d> GetTagPose(int ID) const;
/**
* Serializes an AprilTagFieldLayout to a JSON file.
*
* @param path The path to write the JSON file to.
*/
void Serialize(std::string_view path);
/*
* Checks equality between this AprilTagFieldLayout and another object.
*/
bool operator==(const AprilTagFieldLayout&) const = default;
private:
std::unordered_map<int, AprilTag> m_apriltags;
units::meter_t m_fieldLength;
units::meter_t m_fieldWidth;
Pose3d m_origin;
friend WPILIB_DLLEXPORT void to_json(wpi::json& json,
const AprilTagFieldLayout& layout);
friend WPILIB_DLLEXPORT void from_json(const wpi::json& json,
AprilTagFieldLayout& layout);
};
WPILIB_DLLEXPORT
void to_json(wpi::json& json, const AprilTagFieldLayout& layout);
WPILIB_DLLEXPORT
void from_json(const wpi::json& json, AprilTagFieldLayout& layout);
/**
* Loads an AprilTagFieldLayout from a predefined field
*
* @param field The predefined field
* @return AprilTagFieldLayout of the field
* @deprecated Use AprilTagFieldLayout::LoadField() instead
*/
[[deprecated("Use AprilTagFieldLayout::LoadField() instead")]]
WPILIB_DLLEXPORT AprilTagFieldLayout
LoadAprilTagLayoutField(AprilTagField field);
} // namespace frc

View File

@@ -1,33 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <string_view>
#include <wpi/SymbolExports.h>
namespace frc {
/**
* Loadable AprilTag field layouts.
*/
enum class AprilTagField {
/// 2022 Rapid React.
k2022RapidReact,
/// 2023 Charged Up.
k2023ChargedUp,
/// 2024 Crescendo.
k2024Crescendo,
/// 2025 Reefscape.
k2025Reefscape,
/// Alias to the current game.
kDefaultField = k2025Reefscape,
// This is a placeholder for denoting the last supported field. This should
// always be the last entry in the enum and should not be used by users
kNumFields,
};
} // namespace frc

View File

@@ -1,36 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <wpi/SymbolExports.h>
#include "frc/geometry/Transform3d.h"
namespace frc {
/** A pair of AprilTag pose estimates. */
struct WPILIB_DLLEXPORT AprilTagPoseEstimate {
/** Pose 1. */
Transform3d pose1;
/** Pose 2. */
Transform3d pose2;
/** Object-space error of pose 1. */
double error1;
/** Object-space error of pose 2. */
double error2;
/**
* Gets the ratio of pose reprojection errors, called ambiguity. Numbers
* above 0.2 are likely to be ambiguous.
*
* @return The ratio of pose reprojection errors.
*/
double GetAmbiguity() const;
};
} // namespace frc

View File

@@ -1,145 +0,0 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <span>
#include <units/length.h>
#include <wpi/SymbolExports.h>
#include "frc/apriltag/AprilTagPoseEstimate.h"
#include "frc/geometry/Transform3d.h"
namespace frc {
class AprilTagDetection;
/** Pose estimators for AprilTag tags. */
class WPILIB_DLLEXPORT AprilTagPoseEstimator {
public:
/** Configuration for the pose estimator. */
struct Config {
bool operator==(const Config&) const = default;
/** The tag size. */
units::meter_t tagSize;
/** Camera horizontal focal length, in pixels. */
double fx;
/** Camera vertical focal length, in pixels. */
double fy;
/** Camera horizontal focal center, in pixels. */
double cx;
/** Camera vertical focal center, in pixels. */
double cy;
};
/**
* Creates estimator.
*
* @param config Configuration
*/
explicit AprilTagPoseEstimator(const Config& config) : m_config{config} {}
/**
* Sets estimator configuration.
*
* @param config Configuration
*/
void SetConfig(const Config& config) { m_config = config; }
/**
* Gets estimator configuration.
*
* @return Configuration
*/
const Config& GetConfig() const { return m_config; }
/**
* Estimates the pose of the tag using the homography method described in [1].
*
* @param detection Tag detection
* @return Pose estimate
*/
Transform3d EstimateHomography(const AprilTagDetection& detection) const;
/**
* Estimates the pose of the tag using the homography method described in [1].
*
* @param homography Homography 3x3 matrix data
* @return Pose estimate
*/
Transform3d EstimateHomography(std::span<const double, 9> homography) const;
/**
* Estimates the pose of the tag. This returns one or two possible poses for
* the tag, along with the object-space error of each.
*
* This uses the homography method described in [1] for the initial estimate.
* Then Orthogonal Iteration [2] is used to refine this estimate. Then [3] is
* used to find a potential second local minima and Orthogonal Iteration is
* used to refine this second estimate.
*
* [1]: E. Olson, “Apriltag: A robust and flexible visual fiducial system,” in
* 2011 IEEE International Conference on Robotics and Automation,
* May 2011, pp. 34003407.
* [2]: Lu, G. D. Hager and E. Mjolsness, "Fast and globally convergent pose
* estimation from video images," in IEEE Transactions on Pattern
* Analysis and Machine Intelligence, vol. 22, no. 6, pp. 610-622, June 2000.
* doi: 10.1109/34.862199
* [3]: Schweighofer and A. Pinz, "Robust Pose Estimation from a Planar
* Target," in IEEE Transactions on Pattern Analysis and Machine Intelligence,
* vol. 28, no. 12, pp. 2024-2030, Dec. 2006. doi: 10.1109/TPAMI.2006.252
*
* @param detection Tag detection
* @param nIters Number of iterations
* @return Initial and (possibly) second pose estimates
*/
AprilTagPoseEstimate EstimateOrthogonalIteration(
const AprilTagDetection& detection, int nIters) const;
/**
* Estimates the pose of the tag. This returns one or two possible poses for
* the tag, along with the object-space error of each.
*
* @param homography Homography 3x3 matrix data
* @param corners Corner point array (X and Y for each corner in order)
* @param nIters Number of iterations
* @return Initial and (possibly) second pose estimates
*/
AprilTagPoseEstimate EstimateOrthogonalIteration(
std::span<const double, 9> homography, std::span<const double, 8> corners,
int nIters) const;
/**
* Estimates tag pose. This method is an easier to use interface to
* EstimatePoseOrthogonalIteration(), running 50 iterations and returning the
* pose with the lower object-space error.
*
* @param detection Tag detection
* @return Pose estimate
*/
Transform3d Estimate(const AprilTagDetection& detection) const;
/**
* Estimates tag pose. This method is an easier to use interface to
* EstimatePoseOrthogonalIteration(), running 50 iterations and returning the
* pose with the lower object-space error.
*
* @param homography Homography 3x3 matrix data
* @param corners Corner point array (X and Y for each corner in order)
* @return Pose estimate
*/
Transform3d Estimate(std::span<const double, 9> homography,
std::span<const double, 8> corners) const;
private:
Config m_config;
};
} // namespace frc

View File

@@ -0,0 +1,39 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include "wpi/math/geometry/Pose3d.hpp"
#include "wpi/util/RawFrame.hpp"
#include "wpi/util/SymbolExports.hpp"
namespace wpi::util {
class json;
} // namespace wpi::util
namespace wpi::apriltag {
/**
* Represents an AprilTag's metadata.
*/
struct WPILIB_DLLEXPORT AprilTag {
/// The tag's ID.
int ID;
/// The tag's pose.
wpi::math::Pose3d pose;
bool operator==(const AprilTag&) const = default;
static bool Generate36h11AprilTagImage(wpi::util::RawFrame* frame, int id);
static bool Generate16h5AprilTagImage(wpi::util::RawFrame* frame, int id);
};
WPILIB_DLLEXPORT
void to_json(wpi::util::json& json, const AprilTag& apriltag);
WPILIB_DLLEXPORT
void from_json(const wpi::util::json& json, AprilTag& apriltag);
} // namespace wpi::apriltag

View File

@@ -0,0 +1,161 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <stdint.h>
#include <span>
#include <string_view>
#include <Eigen/Core>
#include "wpi/util/SymbolExports.hpp"
namespace wpi::apriltag {
/**
* A detection of an AprilTag tag.
*/
class WPILIB_DLLEXPORT AprilTagDetection final {
public:
AprilTagDetection() = delete;
AprilTagDetection(const AprilTagDetection&) = delete;
AprilTagDetection& operator=(const AprilTagDetection&) = delete;
/** A point. Used for center and corner points. */
struct Point {
double x;
double y;
};
/**
* Gets the decoded tag's family name.
*
* @return Decoded family name
*/
std::string_view GetFamily() const;
/**
* Gets the decoded ID of the tag.
*
* @return Decoded ID
*/
int GetId() const { return id; }
/**
* Gets how many error bits were corrected. Note: accepting large numbers of
* corrected errors leads to greatly increased false positive rates.
* NOTE: As of this implementation, the detector cannot detect tags with
* a hamming distance greater than 2.
*
* @return Hamming distance (number of corrected error bits)
*/
int GetHamming() const { return hamming; }
/**
* Gets a measure of the quality of the binary decoding process: the
* average difference between the intensity of a data bit versus
* the decision threshold. Higher numbers roughly indicate better
* decodes. This is a reasonable measure of detection accuracy
* only for very small tags-- not effective for larger tags (where
* we could have sampled anywhere within a bit cell and still
* gotten a good detection.)
*
* @return Decision margin
*/
float GetDecisionMargin() const { return decision_margin; }
/**
* Gets the 3x3 homography matrix describing the projection from an
* "ideal" tag (with corners at (-1,1), (1,1), (1,-1), and (-1,
* -1)) to pixels in the image.
*
* @return Homography matrix data
*/
std::span<const double, 9> GetHomography() const;
/**
* Gets the 3x3 homography matrix describing the projection from an
* "ideal" tag (with corners at (-1,1), (1,1), (1,-1), and (-1,
* -1)) to pixels in the image.
*
* @return Homography matrix
*/
Eigen::Matrix3d GetHomographyMatrix() const;
/**
* Gets the center of the detection in image pixel coordinates.
*
* @return Center point
*/
const Point& GetCenter() const { return *reinterpret_cast<const Point*>(c); }
/**
* Gets a corner of the tag in image pixel coordinates. These always
* wrap counter-clock wise around the tag. Index 0 is the bottom left corner.
*
* @param ndx Corner index (range is 0-3, inclusive)
* @return Corner point
*/
const Point& GetCorner(int ndx) const {
return *reinterpret_cast<const Point*>(p[ndx]);
}
/**
* Gets the corners of the tag in image pixel coordinates. These always
* wrap counter-clock wise around the tag. The first set of corner coordinates
* are the coordinates for the bottom left corner.
*
* @param cornersBuf Corner point array (X and Y for each corner in order)
* @return Corner point array (copy of cornersBuf span)
*/
std::span<double, 8> GetCorners(std::span<double, 8> cornersBuf) const {
for (int i = 0; i < 4; i++) {
cornersBuf[i * 2] = p[i][0];
cornersBuf[i * 2 + 1] = p[i][1];
}
return cornersBuf;
}
private:
// This class *must* be standard-layout-compatible with apriltag_detection
// as we use reinterpret_cast from that structure. This means the below
// members must exactly match the contents of the apriltag_detection struct.
// The tag family.
void* family;
// The decoded ID of the tag.
int id;
// How many error bits were corrected? Note: accepting large numbers of
// corrected errors leads to greatly increased false positive rates.
// NOTE: As of this implementation, the detector cannot detect tags with
// a hamming distance greater than 2.
int hamming;
// A measure of the quality of the binary decoding process: the
// average difference between the intensity of a data bit versus
// the decision threshold. Higher numbers roughly indicate better
// decodes. This is a reasonable measure of detection accuracy
// only for very small tags-- not effective for larger tags (where
// we could have sampled anywhere within a bit cell and still
// gotten a good detection.)
float decision_margin;
// The 3x3 homography matrix describing the projection from an
// "ideal" tag (with corners at (-1,1), (1,1), (1,-1), and (-1,
// -1)) to pixels in the image.
void* H;
// The center of the detection in image pixel coordinates.
double c[2];
// The corners of the tag in image pixel coordinates. These always
// wrap counter-clock wise around the tag.
double p[4][2];
};
} // namespace wpi::apriltag

View File

@@ -0,0 +1,261 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <stdint.h>
#include <memory>
#include <span>
#include <string_view>
#include <utility>
#include "wpi/apriltag/AprilTagDetection.hpp"
#include "wpi/units/angle.hpp"
#include "wpi/util/StringMap.hpp"
#include "wpi/util/SymbolExports.hpp"
namespace wpi::apriltag {
/**
* An AprilTag detector engine. This is expensive to set up and tear down, so
* most use cases should only create one of these, add a family to it, set up
* any other configuration, and repeatedly call Detect().
*/
class WPILIB_DLLEXPORT AprilTagDetector {
public:
/** Detector configuration. */
struct Config {
bool operator==(const Config&) const = default;
/**
* How many threads should be used for computation. Default is
* single-threaded operation (1 thread).
*/
int numThreads = 1;
/**
* Quad decimation. Detection of quads can be done on a lower-resolution
* image, improving speed at a cost of pose accuracy and a slight decrease
* in detection rate. Decoding the binary payload is still done at full
* resolution. Default is 2.0.
*/
float quadDecimate = 2.0f;
/**
* What Gaussian blur should be applied to the segmented image (used for
* quad detection). Very noisy images benefit from non-zero values (e.g.
* 0.8). Default is 0.0.
*/
float quadSigma = 0.0f;
/**
* When true, the edges of the each quad are adjusted to "snap to" strong
* gradients nearby. This is useful when decimation is employed, as it can
* increase the quality of the initial quad estimate substantially.
* Generally recommended to be on (true). Default is true.
*
* Very computationally inexpensive. Option is ignored if
* quad_decimate = 1.
*/
bool refineEdges = true;
/**
* How much sharpening should be done to decoded images. This can help
* decode small tags but may or may not help in odd lighting conditions or
* low light conditions. Default is 0.25.
*/
double decodeSharpening = 0.25;
/**
* Debug mode. When true, the decoder writes a variety of debugging images
* to the current working directory at various stages through the detection
* process. This is slow and should *not* be used on space-limited systems
* such as the RoboRIO. Default is disabled (false).
*/
bool debug = false;
};
/** Quad threshold parameters. */
struct QuadThresholdParameters {
bool operator==(const QuadThresholdParameters&) const = default;
/**
* Threshold used to reject quads containing too few pixels. Default is 300
* pixels.
*/
int minClusterPixels = 300;
/**
* How many corner candidates to consider when segmenting a group of pixels
* into a quad. Default is 10.
*/
int maxNumMaxima = 10;
/**
* Critical angle. The detector will reject quads where pairs of edges have
* angles that are close to straight or close to 180 degrees. Zero means
* that no quads are rejected. Default is 45 degrees.
*/
wpi::units::radian_t criticalAngle = 45_deg;
/**
* When fitting lines to the contours, the maximum mean squared error
* allowed. This is useful in rejecting contours that are far from being
* quad shaped; rejecting these quads "early" saves expensive decoding
* processing. Default is 10.0.
*/
float maxLineFitMSE = 10.0f;
/**
* Minimum brightness offset. When we build our model of black & white
* pixels, we add an extra check that the white model must be (overall)
* brighter than the black model. How much brighter? (in pixel values,
* [0,255]). Default is 5.
*/
int minWhiteBlackDiff = 5;
/**
* Whether the thresholded image be should be deglitched. Only useful for
* very noisy images. Default is disabled (false).
*/
bool deglitch = false;
};
/**
* Array of detection results. Each array element is a pointer to an
* AprilTagDetection.
*/
class WPILIB_DLLEXPORT Results
: public std::span<AprilTagDetection const* const> {
struct private_init {};
friend class AprilTagDetector;
public:
Results() = default;
Results(void* impl, const private_init&);
~Results() { Destroy(); }
Results(const Results&) = delete;
Results& operator=(const Results&) = delete;
Results(Results&& rhs) : span{std::move(rhs)}, m_impl{rhs.m_impl} {
rhs.m_impl = nullptr;
}
Results& operator=(Results&& rhs);
private:
void Destroy();
void* m_impl = nullptr;
};
AprilTagDetector();
~AprilTagDetector() { Destroy(); }
AprilTagDetector(const AprilTagDetector&) = delete;
AprilTagDetector& operator=(const AprilTagDetector&) = delete;
AprilTagDetector(AprilTagDetector&& rhs)
: m_impl{rhs.m_impl},
m_families{std::move(rhs.m_families)},
m_qtpCriticalAngle{rhs.m_qtpCriticalAngle} {
rhs.m_impl = nullptr;
}
AprilTagDetector& operator=(AprilTagDetector&& rhs);
/**
* @{
* @name Configuration functions
*/
/**
* Sets detector configuration.
*
* @param config Configuration
*/
void SetConfig(const Config& config);
/**
* Gets detector configuration.
*
* @return Configuration
*/
Config GetConfig() const;
/**
* Sets quad threshold parameters.
*
* @param params Parameters
*/
void SetQuadThresholdParameters(const QuadThresholdParameters& params);
/**
* Gets quad threshold parameters.
*
* @return Parameters
*/
QuadThresholdParameters GetQuadThresholdParameters() const;
/** @} */
/**
* @{
* @name Tag family functions
*/
/**
* Adds a family of tags to be detected.
*
* @param fam Family name, e.g. "tag16h5"
* @param bitsCorrected Maximum number of bits to correct
* @return False if family can't be found
*/
bool AddFamily(std::string_view fam, int bitsCorrected = 2);
/**
* Removes a family of tags from the detector.
*
* @param fam Family name, e.g. "tag16h5"
*/
void RemoveFamily(std::string_view fam);
/**
* Unregister all families.
*/
void ClearFamilies();
/** @} */
/**
* Detect tags from an 8-bit image.
* The image must be grayscale.
*
* @param width width of the image
* @param height height of the image
* @param stride number of bytes between image rows (often the same as width)
* @param buf image buffer
* @return Results (array of AprilTagDetection pointers)
*/
Results Detect(int width, int height, int stride, uint8_t* buf);
/**
* Detect tags from an 8-bit image.
* The image must be grayscale.
*
* @param width width of the image
* @param height height of the image
* @param buf image buffer
* @return Results (array of AprilTagDetection pointers)
*/
Results Detect(int width, int height, uint8_t* buf) {
return Detect(width, height, width, buf);
}
private:
void Destroy();
void DestroyFamilies();
void DestroyFamily(std::string_view name, void* data);
void* m_impl;
wpi::util::StringMap<void*> m_families;
wpi::units::radian_t m_qtpCriticalAngle = 10_deg;
};
} // namespace wpi::apriltag

View File

@@ -0,0 +1,18 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <opencv2/core/mat.hpp>
#include "wpi/apriltag/AprilTagDetector.hpp"
namespace wpi::apriltag {
inline AprilTagDetector::Results AprilTagDetect(AprilTagDetector& detector,
cv::Mat& image) {
return detector.Detect(image.cols, image.rows, image.data);
}
} // namespace wpi::apriltag

View File

@@ -0,0 +1,167 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <optional>
#include <string_view>
#include <unordered_map>
#include <vector>
#include "wpi/apriltag/AprilTag.hpp"
#include "wpi/apriltag/AprilTagFields.hpp"
#include "wpi/math/geometry/Pose3d.hpp"
#include "wpi/units/length.hpp"
#include "wpi/util/SymbolExports.hpp"
namespace wpi::util {
class json;
} // namespace wpi::util
namespace wpi::apriltag {
/**
* Class for representing a layout of AprilTags on a field and reading them from
* a JSON format.
*
* The JSON format contains two top-level objects, "tags" and "field".
* The "tags" object is a list of all AprilTags contained within a layout. Each
* AprilTag serializes to a JSON object containing an ID and a
* wpi::math::Pose3d. The "field" object is a descriptor of the size of the
* field in meters with "width" and "length" values. This is to account for
* arbitrary field sizes when transforming the poses.
*
* Pose3ds in the JSON are measured using the normal FRC coordinate system, NWU
* with the origin at the bottom-right corner of the blue alliance wall.
* SetOrigin(OriginPosition) can be used to change the poses returned from
* GetTagPose(int) to be from the perspective of a specific alliance.
*
* Tag poses represent the center of the tag, with a zero rotation representing
* a tag that is upright and facing away from the (blue) alliance wall (that is,
* towards the opposing alliance). */
class WPILIB_DLLEXPORT AprilTagFieldLayout {
public:
/**
* Common origin positions for the AprilTag coordinate system.
*/
enum class OriginPosition {
/// Blue alliance wall, right side.
kBlueAllianceWallRightSide,
/// Red alliance wall, right side.
kRedAllianceWallRightSide,
};
/**
* Loads an AprilTagFieldLayout from a predefined field
*
* @param field The predefined field
* @return AprilTagFieldLayout of the field
*/
static AprilTagFieldLayout LoadField(AprilTagField field);
AprilTagFieldLayout() = default;
/**
* Construct a new AprilTagFieldLayout with values imported from a JSON file.
*
* @param path Path of the JSON file to import from.
*/
explicit AprilTagFieldLayout(std::string_view path);
/**
* Construct a new AprilTagFieldLayout from a vector of AprilTag objects.
*
* @param apriltags Vector of AprilTags.
* @param fieldLength Length of field the layout is representing.
* @param fieldWidth Width of field the layout is representing.
*/
AprilTagFieldLayout(std::vector<AprilTag> apriltags,
wpi::units::meter_t fieldLength,
wpi::units::meter_t fieldWidth);
/**
* Returns the length of the field the layout is representing.
* @return length
*/
wpi::units::meter_t GetFieldLength() const;
/**
* Returns the length of the field the layout is representing.
* @return width
*/
wpi::units::meter_t GetFieldWidth() const;
/**
* Returns a vector of all the april tags used in this layout.
* @return list of tags
*/
std::vector<AprilTag> GetTags() const;
/**
* Sets the origin based on a predefined enumeration of coordinate frame
* origins. The origins are calculated from the field dimensions.
*
* This transforms the Pose3ds returned by GetTagPose(int) to return the
* correct pose relative to a predefined coordinate frame.
*
* @param origin The predefined origin
*/
void SetOrigin(OriginPosition origin);
/**
* Sets the origin for tag pose transformation.
*
* This transforms the Pose3ds returned by GetTagPose(int) to return the
* correct pose relative to the provided origin.
*
* @param origin The new origin for tag transformations
*/
void SetOrigin(const wpi::math::Pose3d& origin);
/**
* Returns the origin used for tag pose transformation.
* @return the origin
*/
wpi::math::Pose3d GetOrigin() const;
/**
* Gets an AprilTag pose by its ID.
*
* @param ID The ID of the tag.
* @return The pose corresponding to the ID that was passed in or an empty
* optional if a tag with that ID is not found.
*/
std::optional<wpi::math::Pose3d> GetTagPose(int ID) const;
/**
* Serializes an AprilTagFieldLayout to a JSON file.
*
* @param path The path to write the JSON file to.
*/
void Serialize(std::string_view path);
/*
* Checks equality between this AprilTagFieldLayout and another object.
*/
bool operator==(const AprilTagFieldLayout&) const = default;
private:
std::unordered_map<int, AprilTag> m_apriltags;
wpi::units::meter_t m_fieldLength;
wpi::units::meter_t m_fieldWidth;
wpi::math::Pose3d m_origin;
friend WPILIB_DLLEXPORT void to_json(wpi::util::json& json,
const AprilTagFieldLayout& layout);
friend WPILIB_DLLEXPORT void from_json(const wpi::util::json& json,
AprilTagFieldLayout& layout);
};
WPILIB_DLLEXPORT
void to_json(wpi::util::json& json, const AprilTagFieldLayout& layout);
WPILIB_DLLEXPORT
void from_json(const wpi::util::json& json, AprilTagFieldLayout& layout);
} // namespace wpi::apriltag

View File

@@ -0,0 +1,35 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
namespace wpi::apriltag {
/**
* Loadable AprilTag field layouts.
*/
enum class AprilTagField {
/// 2022 Rapid React.
k2022RapidReact,
/// 2023 Charged Up.
k2023ChargedUp,
/// 2024 Crescendo.
k2024Crescendo,
/// 2025 Reefscape AndyMark (see TU12).
k2025ReefscapeAndyMark,
/// 2025 Reefscape Welded (see TU12).
k2025ReefscapeWelded,
/// 2026 Rebuilt Andymark.
k2026RebuiltAndyMark,
/// 2026 Rebuilt Welded.
k2026RebuiltWelded,
/// Alias to the current game.
kDefaultField = k2026RebuiltWelded,
// This is a placeholder for denoting the last supported field. This should
// always be the last entry in the enum and should not be used by users
kNumFields,
};
} // namespace wpi::apriltag

View File

@@ -0,0 +1,35 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include "wpi/math/geometry/Transform3d.hpp"
#include "wpi/util/SymbolExports.hpp"
namespace wpi::apriltag {
/** A pair of AprilTag pose estimates. */
struct WPILIB_DLLEXPORT AprilTagPoseEstimate {
/** Pose 1. */
wpi::math::Transform3d pose1;
/** Pose 2. */
wpi::math::Transform3d pose2;
/** Object-space error of pose 1. */
double error1;
/** Object-space error of pose 2. */
double error2;
/**
* Gets the ratio of pose reprojection errors, called ambiguity. Numbers
* above 0.2 are likely to be ambiguous.
*
* @return The ratio of pose reprojection errors.
*/
double GetAmbiguity() const;
};
} // namespace wpi::apriltag

View File

@@ -0,0 +1,146 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <span>
#include "wpi/apriltag/AprilTagPoseEstimate.hpp"
#include "wpi/math/geometry/Transform3d.hpp"
#include "wpi/units/length.hpp"
#include "wpi/util/SymbolExports.hpp"
namespace wpi::apriltag {
class AprilTagDetection;
/** Pose estimators for AprilTag tags. */
class WPILIB_DLLEXPORT AprilTagPoseEstimator {
public:
/** Configuration for the pose estimator. */
struct Config {
bool operator==(const Config&) const = default;
/** The tag size. */
wpi::units::meter_t tagSize;
/** Camera horizontal focal length, in pixels. */
double fx;
/** Camera vertical focal length, in pixels. */
double fy;
/** Camera horizontal focal center, in pixels. */
double cx;
/** Camera vertical focal center, in pixels. */
double cy;
};
/**
* Creates estimator.
*
* @param config Configuration
*/
explicit AprilTagPoseEstimator(const Config& config) : m_config{config} {}
/**
* Sets estimator configuration.
*
* @param config Configuration
*/
void SetConfig(const Config& config) { m_config = config; }
/**
* Gets estimator configuration.
*
* @return Configuration
*/
const Config& GetConfig() const { return m_config; }
/**
* Estimates the pose of the tag using the homography method described in [1].
*
* @param detection Tag detection
* @return Pose estimate
*/
wpi::math::Transform3d EstimateHomography(
const AprilTagDetection& detection) const;
/**
* Estimates the pose of the tag using the homography method described in [1].
*
* @param homography Homography 3x3 matrix data
* @return Pose estimate
*/
wpi::math::Transform3d EstimateHomography(
std::span<const double, 9> homography) const;
/**
* Estimates the pose of the tag. This returns one or two possible poses for
* the tag, along with the object-space error of each.
*
* This uses the homography method described in [1] for the initial estimate.
* Then Orthogonal Iteration [2] is used to refine this estimate. Then [3] is
* used to find a potential second local minima and Orthogonal Iteration is
* used to refine this second estimate.
*
* [1]: E. Olson, “Apriltag: A robust and flexible visual fiducial system,” in
* 2011 IEEE International Conference on Robotics and Automation,
* May 2011, pp. 34003407.
* [2]: Lu, G. D. Hager and E. Mjolsness, "Fast and globally convergent pose
* estimation from video images," in IEEE Transactions on Pattern
* Analysis and Machine Intelligence, vol. 22, no. 6, pp. 610-622, June 2000.
* doi: 10.1109/34.862199
* [3]: Schweighofer and A. Pinz, "Robust Pose Estimation from a Planar
* Target," in IEEE Transactions on Pattern Analysis and Machine Intelligence,
* vol. 28, no. 12, pp. 2024-2030, Dec. 2006. doi: 10.1109/TPAMI.2006.252
*
* @param detection Tag detection
* @param nIters Number of iterations
* @return Initial and (possibly) second pose estimates
*/
AprilTagPoseEstimate EstimateOrthogonalIteration(
const AprilTagDetection& detection, int nIters) const;
/**
* Estimates the pose of the tag. This returns one or two possible poses for
* the tag, along with the object-space error of each.
*
* @param homography Homography 3x3 matrix data
* @param corners Corner point array (X and Y for each corner in order)
* @param nIters Number of iterations
* @return Initial and (possibly) second pose estimates
*/
AprilTagPoseEstimate EstimateOrthogonalIteration(
std::span<const double, 9> homography, std::span<const double, 8> corners,
int nIters) const;
/**
* Estimates tag pose. This method is an easier to use interface to
* EstimatePoseOrthogonalIteration(), running 50 iterations and returning the
* pose with the lower object-space error.
*
* @param detection Tag detection
* @return Pose estimate
*/
wpi::math::Transform3d Estimate(const AprilTagDetection& detection) const;
/**
* Estimates tag pose. This method is an easier to use interface to
* EstimatePoseOrthogonalIteration(), running 50 iterations and returning the
* pose with the lower object-space error.
*
* @param homography Homography 3x3 matrix data
* @param corners Corner point array (X and Y for each corner in order)
* @return Pose estimate
*/
wpi::math::Transform3d Estimate(std::span<const double, 9> homography,
std::span<const double, 8> corners) const;
private:
Config m_config;
};
} // namespace wpi::apriltag

View File

@@ -0,0 +1,23 @@
ID,X,Y,Z,Z-Rotation,X-Rotation
1,656.98,24.73,58.5,126,0
2,656.98,291.9,58.5,234,0
3,452.4,316.21,51.25,270,0
4,365.2,241.44,73.54,0,30
5,365.2,75.19,73.54,0,30
6,530.49,129.97,12.13,300,0
7,546.87,158.3,12.13,0,0
8,530.49,186.63,12.13,60,0
9,497.77,186.63,12.13,120,0
10,481.39,158.3,12.13,180,0
11,497.77,129.97,12.13,240,0
12,33.91,24.73,58.5,54,0
13,33.91,291.9,58.5,306,0
14,325.68,241.44,73.54,180,30
15,325.68,75.19,73.54,180,30
16,238.49,0.42,51.25,90,0
17,160.39,129.97,12.13,240,0
18,144,158.3,12.13,180,0
19,160.39,186.63,12.13,120,0
20,193.1,186.63,12.13,60,0
21,209.49,158.3,12.13,0,0
22,193.1,129.97,12.13,300,0
1 ID X Y Z Z-Rotation X-Rotation
2 1 656.98 24.73 58.5 126 0
3 2 656.98 291.9 58.5 234 0
4 3 452.4 316.21 51.25 270 0
5 4 365.2 241.44 73.54 0 30
6 5 365.2 75.19 73.54 0 30
7 6 530.49 129.97 12.13 300 0
8 7 546.87 158.3 12.13 0 0
9 8 530.49 186.63 12.13 60 0
10 9 497.77 186.63 12.13 120 0
11 10 481.39 158.3 12.13 180 0
12 11 497.77 129.97 12.13 240 0
13 12 33.91 24.73 58.5 54 0
14 13 33.91 291.9 58.5 306 0
15 14 325.68 241.44 73.54 180 30
16 15 325.68 75.19 73.54 180 30
17 16 238.49 0.42 51.25 90 0
18 17 160.39 129.97 12.13 240 0
19 18 144 158.3 12.13 180 0
20 19 160.39 186.63 12.13 120 0
21 20 193.1 186.63 12.13 60 0
22 21 209.49 158.3 12.13 0 0
23 22 193.1 129.97 12.13 300 0

View File

@@ -0,0 +1,404 @@
{
"tags": [
{
"ID": 1,
"pose": {
"translation": {
"x": 16.687292,
"y": 0.628142,
"z": 1.4859
},
"rotation": {
"quaternion": {
"W": 0.4539904997395468,
"X": 0.0,
"Y": 0.0,
"Z": 0.8910065241883678
}
}
}
},
{
"ID": 2,
"pose": {
"translation": {
"x": 16.687292,
"y": 7.414259999999999,
"z": 1.4859
},
"rotation": {
"quaternion": {
"W": -0.45399049973954675,
"X": -0.0,
"Y": 0.0,
"Z": 0.8910065241883679
}
}
}
},
{
"ID": 3,
"pose": {
"translation": {
"x": 11.49096,
"y": 8.031733999999998,
"z": 1.30175
},
"rotation": {
"quaternion": {
"W": -0.7071067811865475,
"X": -0.0,
"Y": 0.0,
"Z": 0.7071067811865476
}
}
}
},
{
"ID": 4,
"pose": {
"translation": {
"x": 9.276079999999999,
"y": 6.132575999999999,
"z": 1.8679160000000001
},
"rotation": {
"quaternion": {
"W": 0.9659258262890683,
"X": 0.0,
"Y": 0.25881904510252074,
"Z": 0.0
}
}
}
},
{
"ID": 5,
"pose": {
"translation": {
"x": 9.276079999999999,
"y": 1.9098259999999998,
"z": 1.8679160000000001
},
"rotation": {
"quaternion": {
"W": 0.9659258262890683,
"X": 0.0,
"Y": 0.25881904510252074,
"Z": 0.0
}
}
}
},
{
"ID": 6,
"pose": {
"translation": {
"x": 13.474446,
"y": 3.3012379999999997,
"z": 0.308102
},
"rotation": {
"quaternion": {
"W": -0.8660254037844387,
"X": -0.0,
"Y": 0.0,
"Z": 0.49999999999999994
}
}
}
},
{
"ID": 7,
"pose": {
"translation": {
"x": 13.890498,
"y": 4.0208200000000005,
"z": 0.308102
},
"rotation": {
"quaternion": {
"W": 1.0,
"X": 0.0,
"Y": 0.0,
"Z": 0.0
}
}
}
},
{
"ID": 8,
"pose": {
"translation": {
"x": 13.474446,
"y": 4.740402,
"z": 0.308102
},
"rotation": {
"quaternion": {
"W": 0.8660254037844387,
"X": 0.0,
"Y": 0.0,
"Z": 0.49999999999999994
}
}
}
},
{
"ID": 9,
"pose": {
"translation": {
"x": 12.643358,
"y": 4.740402,
"z": 0.308102
},
"rotation": {
"quaternion": {
"W": 0.5000000000000001,
"X": 0.0,
"Y": 0.0,
"Z": 0.8660254037844386
}
}
}
},
{
"ID": 10,
"pose": {
"translation": {
"x": 12.227305999999999,
"y": 4.0208200000000005,
"z": 0.308102
},
"rotation": {
"quaternion": {
"W": 6.123233995736766e-17,
"X": 0.0,
"Y": 0.0,
"Z": 1.0
}
}
}
},
{
"ID": 11,
"pose": {
"translation": {
"x": 12.643358,
"y": 3.3012379999999997,
"z": 0.308102
},
"rotation": {
"quaternion": {
"W": -0.4999999999999998,
"X": -0.0,
"Y": 0.0,
"Z": 0.8660254037844387
}
}
}
},
{
"ID": 12,
"pose": {
"translation": {
"x": 0.8613139999999999,
"y": 0.628142,
"z": 1.4859
},
"rotation": {
"quaternion": {
"W": 0.8910065241883679,
"X": 0.0,
"Y": 0.0,
"Z": 0.45399049973954675
}
}
}
},
{
"ID": 13,
"pose": {
"translation": {
"x": 0.8613139999999999,
"y": 7.414259999999999,
"z": 1.4859
},
"rotation": {
"quaternion": {
"W": -0.8910065241883678,
"X": -0.0,
"Y": 0.0,
"Z": 0.45399049973954686
}
}
}
},
{
"ID": 14,
"pose": {
"translation": {
"x": 8.272272,
"y": 6.132575999999999,
"z": 1.8679160000000001
},
"rotation": {
"quaternion": {
"W": 5.914589856893349e-17,
"X": -0.25881904510252074,
"Y": 1.5848095757158825e-17,
"Z": 0.9659258262890683
}
}
}
},
{
"ID": 15,
"pose": {
"translation": {
"x": 8.272272,
"y": 1.9098259999999998,
"z": 1.8679160000000001
},
"rotation": {
"quaternion": {
"W": 5.914589856893349e-17,
"X": -0.25881904510252074,
"Y": 1.5848095757158825e-17,
"Z": 0.9659258262890683
}
}
}
},
{
"ID": 16,
"pose": {
"translation": {
"x": 6.057646,
"y": 0.010667999999999999,
"z": 1.30175
},
"rotation": {
"quaternion": {
"W": 0.7071067811865476,
"X": 0.0,
"Y": 0.0,
"Z": 0.7071067811865476
}
}
}
},
{
"ID": 17,
"pose": {
"translation": {
"x": 4.073905999999999,
"y": 3.3012379999999997,
"z": 0.308102
},
"rotation": {
"quaternion": {
"W": -0.4999999999999998,
"X": -0.0,
"Y": 0.0,
"Z": 0.8660254037844387
}
}
}
},
{
"ID": 18,
"pose": {
"translation": {
"x": 3.6576,
"y": 4.0208200000000005,
"z": 0.308102
},
"rotation": {
"quaternion": {
"W": 6.123233995736766e-17,
"X": 0.0,
"Y": 0.0,
"Z": 1.0
}
}
}
},
{
"ID": 19,
"pose": {
"translation": {
"x": 4.073905999999999,
"y": 4.740402,
"z": 0.308102
},
"rotation": {
"quaternion": {
"W": 0.5000000000000001,
"X": 0.0,
"Y": 0.0,
"Z": 0.8660254037844386
}
}
}
},
{
"ID": 20,
"pose": {
"translation": {
"x": 4.904739999999999,
"y": 4.740402,
"z": 0.308102
},
"rotation": {
"quaternion": {
"W": 0.8660254037844387,
"X": 0.0,
"Y": 0.0,
"Z": 0.49999999999999994
}
}
}
},
{
"ID": 21,
"pose": {
"translation": {
"x": 5.321046,
"y": 4.0208200000000005,
"z": 0.308102
},
"rotation": {
"quaternion": {
"W": 1.0,
"X": 0.0,
"Y": 0.0,
"Z": 0.0
}
}
}
},
{
"ID": 22,
"pose": {
"translation": {
"x": 4.904739999999999,
"y": 3.3012379999999997,
"z": 0.308102
},
"rotation": {
"quaternion": {
"W": -0.8660254037844387,
"X": -0.0,
"Y": 0.0,
"Z": 0.49999999999999994
}
}
}
}
],
"field": {
"length": 17.548,
"width": 8.042
}
}

Some files were not shown because too many files have changed in this diff Show More