Compare commits

...

254 Commits

Author SHA1 Message Date
Tyler Veness
96f7fa662e Upgrade Maven dependencies (#5553)
The following source code changes were required:

* Whitespace changes from spotless
* PMD warning suppressions for utility class tests
* PMD warning rename from "BeanMembersShouldSerialize" to
  "NonSerializableClass"
* Declared more class members as final
2023-08-18 19:18:33 -07:00
Thad House
7a2d336d52 [wpinet] Leak multicast handles during windows shutdown (#5550)
Destructing either of the multicast objects during process shutdown will result in a crash due to attempting to start a task on the non-existent thread pool.

Solve this by just leaking all the handles upon destruction of the static multicast manager. This won't solve the case where the user statically allocates the object, but solves Java and C access, and most cases wouldn't be statically allocating the service announcer anyway in C++.
2023-08-18 19:15:16 -07:00
Tyler Veness
f9e2757d8f [wpimath] Use JDoubleArrayRef in all JNI functions (#5546) 2023-08-17 13:57:06 -07:00
Tyler Veness
0cf6e37dc1 [wpimath] Make LTV controller constructors use faster DARE solver (#5543)
Made JNI modifications to expose the faster function, made the API use
the typesafe Matrix API, and synchronized the documentation with C++.

Sped up C++ LTV diff drive test from 20 ms to 15 ms.
Sped up C++ LTV unicycle test from 15 ms to 10 ms.
2023-08-17 13:56:15 -07:00
autoantwort
6953a303b3 [build] Fix the windows build with fmt (#5544) 2023-08-16 17:07:23 -07:00
Joseph Eng
7a37e3a496 [wpimath] Correct Rotation3d::RotateBy doc comment (NFC) (#5541)
Improve transform doc comment consistency
2023-08-15 13:12:09 -07:00
Tyler Veness
186b409e16 [wpimath] Remove internal Eigen header include (#5539) 2023-08-15 08:47:48 -07:00
Tyler Veness
03764dfe93 [wpimath] Add static matrix support to DARE solver (#5536)
Using static matrices where possible results in a 2x performance
improvement.
2023-08-14 09:15:58 -07:00
Tyler Veness
394cfeadbd [wpimath] Use SDA algorithm instead of SSCA for DARE solver (#5526)
Both seem to work, but the SDA algorithm is specifically recommended for
solving DAREs as opposed to P-DAREs.

The QR decomposition was replaced with a partial pivoting LU
decomposition at the recommendation of section 2.4 of the paper.

More tests and a separate JNI function for each DARE solver variant were
added.
2023-08-12 19:45:45 -07:00
Ryan Blue
a4b7fde767 [wpilib] Add mechanism specific SetState overloads to physics sims (#5534) 2023-08-12 15:21:07 -07:00
amquake
8121566258 [wpimath] Fix CoordinateSystem.convert() Transform3d overload (#5532) 2023-08-12 15:20:22 -07:00
Peter Johnson
b542e01a0b [glass] Fix array crash when clearing existing workspace (#5535) 2023-08-12 15:17:43 -07:00
Oliver
e2e1b763b2 [wpigui] Fix PFD file dialogs not closing after window closing (#5530)
Also applies samhocevar/portable-file-dialogs#91 to properly retrieve the HWND on Windows.
2023-08-12 09:07:35 -07:00
Zhiquan Yeo
86d7bbc4e4 [examples] Add Java Examples and Templates for the XRP (#5529) 2023-08-11 23:31:35 -07:00
Tyler Veness
e8b5d44752 [wpimath] Make Java Quaternion use doubles instead of Vector (#5525)
This avoids allocation overhead on construction. times() was also
rewritten to not allocate any temporary objects.

Getter calls in the C++ Quaternion class were modified for parity.
2023-08-11 23:27:29 -07:00
Ryan Blue
38c198fa64 [myRobot] Add apriltags to myRobot build (#5528) 2023-08-11 23:26:05 -07:00
Tyler Veness
00450c3548 [wpimath] Upgrade to EJML 0.42 (#5531) 2023-08-11 23:25:43 -07:00
Joseph Eng
faf3cecd83 [wpimath] Don't copy Matrix and underlying storage in VecBuilder (#5524) 2023-08-09 22:15:39 -07:00
autoantwort
6b896a38dc [build] Don't enforce WITH_FLAT_INSTALL with MSVC (part 2) (#5517) 2023-08-07 08:57:34 -07:00
Peter Johnson
c01814b80e [wpiutil] Add C API for DataLog (#5509) 2023-08-06 20:18:50 -07:00
Joseph Eng
b5bd0771eb [wpimath] Document extrinsic vs intrinsic rotations (NFC) (#5508) 2023-08-06 19:59:42 -07:00
autoantwort
84ed8aec05 [build] Don't enforce WITH_FLAT_INSTALL with MSVC (#5515) 2023-08-06 19:58:41 -07:00
Peter Johnson
999f677d8c [ntcoreffi] Add WPI_Impl_SetupNowRio to exported symbols (#5510) 2023-08-05 20:18:27 -07:00
Tyler Veness
338f37d302 Fix header sorting of libssh (#5507) 2023-08-05 14:16:55 -07:00
Ryan Blue
75cbd9d6d0 [glass] Add background color selector to glass plots (#5506) 2023-08-05 14:16:04 -07:00
m10653
e2c190487b [examples] Add flywheel bang-bang controller example (#4071)
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2023-08-05 14:15:05 -07:00
Peter Johnson
c52dad609e [wpinet] WebSocket: Send pong in response to ping (#5498)
This is required by the spec (RFC 6455 section 5.5.2).
2023-08-04 16:27:08 -07:00
Ryan Blue
e2d17a24a6 [hal] Expose power rail disable and cpu temp functionality (#5477) 2023-08-03 23:48:29 -07:00
Thad House
3ad5d2e42d [hal,wpiutil] Use HMB for FPGA Timestamps (#5499)
Current timestamp read code uses FPGA register reads. Through testing,
this read was slower then clock_gettime by about 4-5x. However, another
method of reading the FPGA time is available, using HMB. HMB
is memory mapped IO from RAM to the FPGA. So to code side,
reading the value is just a memory barrier and a memory read.

There is some latency on the write side, so a very small artifical delay
(5us) is added to avoid register reads such as interrupts being ahead
of current timestamps, which could cause issues.

Below is read times for 1000 calls to clock_gettime, register reads and
hmb reads.
```
Clock: Rise 1.72939400 s Fall 1.72990700 s Delta 0.00051300 s
FPGA : Rise 1.72999000 s Fall 1.73429300 s Delta 0.00430300 s
HMB  : Rise 1.73466800 s Fall 1.73481900 s Delta 0.00015100 s
```

Also add full HMB struct to HAL for future usage.
2023-08-03 23:46:55 -07:00
Peter Johnson
b46a872494 [ntcore] Remove pImpl from implementation (#5480)
Also change Timestamped into a template.
2023-08-03 23:43:55 -07:00
Tyler Veness
d8c59ccc71 [wpimath] Add tests for MathUtil clamp() and interpolate() (#5501) 2023-08-03 23:43:20 -07:00
Ryan Blue
0552c8621d [glass,ov] Improve Glass and OutlineViewer title bar message (#5502)
Detect changes to mode and update based on mode change and connection events.
2023-08-03 23:43:03 -07:00
Ryan Blue
90e37a129f [wpiutil,wpimath] Add generic InterpolatingTreeMap (#5372) 2023-08-03 21:46:17 -07:00
Thad House
d83a6edc20 [wpilib] Update GetMatchTime docs and units (#5232) 2023-08-03 21:45:26 -07:00
Tyler Veness
6db2c42966 [wpimath] Trajectory: Throw on empty lists of States (#5497)
Fixes #4141.
2023-08-03 08:24:20 -07:00
Tyler Veness
21439b606c [wpimath] Disallow LTV controller max velocities above 15 m/s (#5495)
15 m/s is about 50 ft/s, which is way above what FRC robots should be
able to achieve. This limit lets us catch user errors from bad unit
conversions immediately instead of the LUT generation in the LTV
controllers hanging for a really long time.

Fixes #5027.
2023-08-02 23:37:49 -07:00
Peter Johnson
7496e0d208 [ntcore] Value: More efficiently store arrays (#5484) 2023-08-01 22:26:36 -07:00
Joseph Eng
0c93aded8a [wpimath] Change kinematics.ToTwist2d(end - start) to kinematics.ToTwist2d(start, end) (#5493) 2023-08-01 22:25:26 -07:00
Tyler Veness
815a8403e5 [wpimath] Give infeasible trajectory constraints a better exception message (#5492)
Fixes #3146.
2023-07-31 21:43:22 -07:00
Tyler Veness
35a8b129d9 [wpimath] Add RotateBy() function to pose classes (#5491)
Fixes #5472.
2023-07-31 21:16:44 -07:00
Tyler Veness
26d6e68c8f [upstream_utils] Add GCEM to CI (#5483) 2023-07-31 19:18:32 -07:00
Tyler Veness
6aa469ae45 [wpilib] Document how to create LinearSystem object for physics sim classes (NFC) (#5488)
Fixes #4372.
2023-07-31 19:18:17 -07:00
Tyler Veness
a01b6467d3 [wpimath] Link to docs on LQR and KF tolerances (#5486)
Fixes #4151.
2023-07-31 19:17:44 -07:00
Tyler Veness
d814f1d123 [wpimath] Fix copy-paste error from Pose2d docs (NFC) (#5490) 2023-07-31 19:17:17 -07:00
Tyler Veness
98f074b072 [wpimath] Add folder prefix to geometry includes (#5489) 2023-07-31 19:17:02 -07:00
Ryan Blue
e9858c10e9 [glass] Add tooltips for NT settings (#5476) 2023-07-28 16:32:07 -07:00
Thad House
12dda24f06 [examples] Fix C robot template not correctly looping (#5474)
- The event wouldn't reset, causing infinite looping
- Refresh ds data was missing
2023-07-27 08:46:51 -07:00
Peter Johnson
fc75d31755 [apriltag] Update apriltaglib (#5475) 2023-07-26 22:48:09 -07:00
Peter Johnson
a95994fff6 [wpiutil] timestamp: Call FPGA functions directly (#5235)
This works around an exit race with wpi::Now() on Rio; it was overridden
to call HAL_GetFPGATime(), which calls chipobject, but on exit, because
there was not a library dependency, the chipobject could be destroyed
prior to wpiutil/wpinet being shut down.
2023-07-24 23:03:28 -07:00
Joseph Eng
2ba8fbb6f4 [wpimath] Improve documentation for SwerveModulePosition::operator- (#5468) 2023-07-24 22:46:59 -07:00
Thad House
b8cdf97621 [build] Prepare for Windows arm64 builds (#5390)
Builds aren't actually enabled yet due to a bug in Gradle.
2023-07-24 22:46:25 -07:00
Mihir Patankar
552f4b76b5 [wpimath] Add FOC-enabled Falcon constants to the DCMotor class (#5469) 2023-07-24 20:16:48 -07:00
Joseph Ruan
1938251436 [examples] Add Feedforward to ElevatorProfiledPid (#5300)
Co-authored-by: Ryan Blue <ryanzblue@gmail.com>
2023-07-23 21:40:34 -07:00
Gold856
873c2a6c10 [examples] Update ElevatorTrapezoidProfile example (#5466) 2023-07-23 21:36:47 -07:00
Gold856
99b88be4f3 [wpilib] Reduce usage of NTSendable (#5434) 2023-07-23 21:34:49 -07:00
Peter Johnson
d125711023 [hal] Fix Java REVPH faults bitfield (take 2) (#5464)
The previous PR had a typo in one of the bitmasks.
Change to using 1 << N.
2023-07-23 17:37:27 -07:00
Carl Hauser
c3fab7f1f2 [ntcore] Don't update timestamp when value is unchanged (#5356)
This fixes an issue with commands run/cancel.
2023-07-23 17:36:26 -07:00
Gold856
5ec7f18bdc [wpilib] EventLoop docs: Remove BooleanEvent references (NFC) (#5463) 2023-07-23 14:22:04 -07:00
Sam Carlberg
c065ae1fcf [wpiunits] Add subproject for a Java typesafe unit system (#5371)
# Background

Unit safety has always been a problem in WPILib. Any value corresponding to a physical measurement, such as current draw or distance traveled, is represented by a bare number with no unit tied to it; it's up to the programmer to know what units they're working and take care to remember that while working on their robot program. This leads to bugs when programmers accidentally mix units without knowing, or measure something (such as a wheel diameter) in one unit and program using another. `wpiunits` is intended to eliminate that class of bugs.

Another source of friction is the controllers and models in `wpimath` that expect all inputs to be in terms of SI units (meter, kilogram, and so on), while most FRC teams are US-based and most commonly use imperial units. wpimath does a good job of noting unit types in method names and argument names; however, it still relies on users properly converting values (and knowing they even have to do so).

# API

There are really only two core classes in this library: `Unit` and `Measure`. A `Unit` represents some dimension like distance or time. `Unit` is subclassed to define specific dimensions (eg `Distance` and `Time`) and those subclasses are instantiated to defined particular units in those dimensions, such as `Meters` and `Feet` being instances of the `Distance` class.

A `Measure` is a value tied to a particular dimension like distance and knows what unit that value is tied to. `Measure` has two implementations - one immutable and one mutable. The `Measure` interface only defines *read-only* operations; any API working with measurements should use the interface. The default implementation is `ImmutableMeasure`, which only implements those read-only operations and is useful for tracking constants. `MutableMeasure` also adds some methods that will allow for mutation of its internal state; this class is intended for use for things like sensors and controllers that track internal state and don't want to allocate new `Measure` objects every time something like `myEncoder.getDistance()` is called. However, the APIs for those methods should still only expose the read-only `Measure` interface so users can't (without casting or reflection) change the internal values.

A `Units` class provides convenient definitions for most of the commonly used unit types, such as `Meters`, `Feet`, and `Milliseconds`. I recommend static importing these units eg `import static edu.wpi.first.units.Units.Meters`) so they can be used like `Meters.of(1.234)` instead of `Units.Meters.of(1.234)`


# Examples

These examples are admittedly contrived. Users shouldn't be interacting much with measure objects themselves, since wpimath and wpilibj classes will be updated to support working with them; users will often just have to take a `Measure` output from one place (such as an encoder) and feed it as input to something else (such as a PID controller or kinematics model)

```java
// Using raw units
Encoder encoder = ...

int kPulsesPerRev = 2048;
double kWheelDiameterMeters = Units.inchesToMeters(6);
double kGearRatio = 10.86;
 // always have to remember this encoder will output in meters!
encoder.setDistancePerPulse(kWheelDiameterMeters * Math.PI / (kGearRatio * kPulsesPerRev));

Command driveDistance(double distance) {
  // have to know the distance argument needs to be in meters!
  return run(this::driveStraight).until(() -> encoder.getDistance() >= distance);
}

// Oops! This will go 16 feet, not 5!
Command driveFiveFeet = driveDistance(5);
Command driveOneMeter = driveDistance(1);
```
```java
// Using wpiunits

Encoder encoder = ...

int kPulsesPerRev = 2048;
Measure<Distance> kWheelDiameter = Inches.of(6);
double kGearRatio = 10.86;
encoder.setDistancePerPulse(kWheelDiameter.times(Math.PI).divide(kGearRatio * kPulsesPerRev));

Command driveDistance(Measure<Distance> distance) {
  // Measure#gte automatically handles unit conversions
  return run(this::driveStraight).until(() -> encoder.getDistance().gte(distance));
}

// Users HAVE to be explicit about their units
Command driveFiveFeet = driveDistance(Feet.of(5));
Command driveOneMeter = driveDistance(Meters.of(1));
```

```java
SmartDashboard.putNumber("Temperature (C)", pdp.getTemperature().in(Celsius));
SmartDashboard.putNumber("Temperature (F)", pdp.getTemperature().in(Fahrenheit));
```

```java
var InchSecond = Inch.mult(Second); // new combined unit types can be user-defined
var InchPerSecond = Inch.per(Second);

PIDController<Distance, ElectricPotential> heightController = new PIDController<>(
  /* kP */ Volts.of(0.2).per(Inch),
  /* kI */ Volts.of(0.002).per(InchSecond),
  /* kD */ Volts.of(0.008).per(InchPerSecond)
);

var elevatorTop = Feet.of(4).plus(Inches.of(6.125));
elevatorMotor.setVoltage(heightController.calculate(encoder.getDistance(), elevatorTop));
```
2023-07-23 14:18:17 -07:00
Peter Johnson
44acca7c00 [wpiutil] Add ClassPreloader (#5365)
This provides an easy-to-use way to preload classes by name at startup to
avoid later delays due to lazy classloading.
2023-07-23 11:18:38 -07:00
Starlight220
88b11832ec [hal] Fix Java REVPH faults bitfield (#5148) 2023-07-22 17:20:48 -07:00
Peter Johnson
fb57d82e52 [ntcore] Enhance Java raw value support
Add support for start, length, and ByteBuffers
2023-07-22 17:17:52 -07:00
Peter Johnson
3a6e40a44b [wpiutil] Enhance DataLog Java raw value support
Add support for start, length, and ByteBuffers
2023-07-22 17:17:52 -07:00
Peter Johnson
8dae5af271 [wpiutil] Add compile-time string utilities (ct_string) (#5462) 2023-07-22 17:16:37 -07:00
Thad House
fc56f8049a [wpilib] DriverStation: Change alliance station to use optional (#5229)
Many teams have issues trying to read the DS too early. By switching to an optional, we cause teams to check 2 things. Either 1) they explicitly check, and their code is correct, or 2) they just read .value() and their code reboots in a loop. However, because the DS will eventually connect, this 2nd case is ok, and should theoretically be undetectable on the field.
2023-07-22 15:19:28 -07:00
autoantwort
ef155438bd [build] Consume libuv via cmake config instead of via pkg-config (#5438)
The problem is that you have to use a different pkg-config file if you want to use a static variant of libuv, but the buildsystem should not care which variant of libuv should be used. This is not a problem with the cmake config.
2023-07-20 00:30:56 -07:00
Gold856
86e91e6724 [wpimath] Refactor TrapezoidProfile API (#5457) 2023-07-19 17:25:10 -07:00
Gold856
72a4543493 [wpilib] DutyCycleEncoderSim: Expand API (#5443) 2023-07-19 17:24:09 -07:00
Joseph Eng
657338715d [wpimath] Add ChassisSpeeds method to fix drifting during compound swerve drive maneuvers (#5425) 2023-07-18 21:19:55 -07:00
Tyler Veness
1af224c21b Add missing <functional> includes (#5459) 2023-07-18 21:18:32 -07:00
Gold856
0b91ca6d5a [wpilib] SendableChooser: Add onChange listener (#5458) 2023-07-18 16:33:45 -07:00
Joseph Eng
6f7cdd460e [wpimath] Pose3d: Switch to JNI for exp and log (#5444)
The pure Java implementations allocate a lot of temporary objects, and the JNI implementation is substantially more performant.
2023-07-18 16:32:11 -07:00
camaj
c69e34c80c [wpimath] ChassisSpeeds: Add arithmetic functions (#5293)
Co-authored-by: Ryan Blue <ryanzblue@gmail.com>
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2023-07-18 16:30:21 -07:00
Sriman Achanta
335e7dd89d [wpilib] Simulation: Add ctor parameter to set starting state of mechanism sims (#5288)
- Add a constructor parameter to configure the initial angle of the arm
- Also reorganizes cascading constructors for Java
2023-07-18 13:00:27 -07:00
Tyler Veness
14f30752ab [wpilib] Deprecate Accelerometer and Gyro interfaces (#5445)
Accelerometer is hyper-specific to ADXL accelerometers, and Gyro is
less useful now that 3D IMUs are prevalent, and if those IMUs want to
support the Gyro interface, they also need to provide a way to set the
axis used for the Gyro interface, which is confusing. Higher-order
functions (e.g., lambdas) are a more flexible interface boundary than
interfaces, but they didn't exist when these interfaces were
created.
2023-07-18 12:52:43 -07:00
Gold856
70b60e3a74 [commands] Trigger: Fix method names in requireNonNullParam (#5454) 2023-07-18 08:12:50 -07:00
Joseph Eng
593767c8c7 [wpimath] Improve Euler angle calculations in gimbal lock (#5437) 2023-07-17 17:19:42 -07:00
Joseph Eng
daf022d3da [build] Make devImplementation inherit from implementation (#5450)
Remove manually adding dependencies to devImplementation.
Fix wpilibNewCommands devMain package.
2023-07-17 17:19:03 -07:00
Jason
9b8d90b852 [examples] Convert the unitless joystick inputs to actual physical units (#5451)
Taking the joystick inputs from -1 to 1, multiply them by the max speed (as defined in Constants.java) to get the target speed, rather than using the unitless raw joystick inputs.
2023-07-17 17:18:34 -07:00
Gold856
1f6428ab63 [ntcore] Fix undefined comparison behavior when array is empty (#5448)
If both arrays are empty, it returns true, avoiding UB with memcmp potentially getting a nullptr.
2023-07-17 17:16:54 -07:00
sciencewhiz
17eb9161cd Update code owners for removal of old commands (#5447) 2023-07-14 21:18:38 -07:00
Tyler Veness
3c4b58ae1e [wpinet] Upgrade to libuv 1.46.0 (#5446) 2023-07-14 18:55:32 -07:00
Ryan Blue
aaea85ff16 [commands] Merge CommandBase into Command and SubsystemBase into Subsystem (#5392)
Moves all CommandBase functionality into Command and deprecates CommandBase for removal.
Moves all SubsystemBase functionality into Subsystem and deprecates SubsystemBase for removal.
Adds a function to CommandScheduler to remove all registered Subsystems.
2023-07-13 22:12:01 -07:00
Peter Johnson
7ac932996a [ci] Use PAT for workflow dispatch (#5442) 2023-07-12 23:53:21 -07:00
Peter Johnson
efe1987e8b [ci] Trigger pages repo workflow (#5441) 2023-07-12 23:29:56 -07:00
Tyler Veness
828bc5276f [wpiutil] Upgrade to LLVM 16.0.6 (#5435)
Fixes #5332.
2023-07-12 22:50:13 -07:00
Peter Johnson
701df9eb87 [ci] Change documentation publish to single-commit (#5440)
Push to different branches for beta/release/development.
The pages repo workflow will do the combine for publishing.
2023-07-12 22:20:22 -07:00
Thad House
e5452e3f69 [wpiutil] Add WPICleaner and an example how to use it (#4850) 2023-07-10 09:59:36 -07:00
Ryan Blue
7a099cb02a [commands] Remove deprecated classes and functions (#5409)
Removes:
- PerpetualCommand
- Command.perpetually()
- CommandGroupBase
- Command.IsGrouped() (C++ only)
- Command.SetGrouped() (C++ only)
- Command.withInterrupt()
- ProxyScheduleCommand
- Button
- InternalButton, JoystickButton, NetworkButton and POVButton now subclass Trigger
- Old style Trigger functions:
    - Trigger.whenActive
    - Trigger.whileActiveOnce
    - Trigger.whileActiveContinuous
    - Trigger.whenInactive
    - Trigger.toggleWhenActive
    - Trigger.cancelWhenActive
- CommandScheduler.clearButtons()
- CommandScheduler.addButtons() (Java only)
- Command supplier constructor of SelectCommand
2023-07-10 09:56:18 -07:00
Thad House
b250a03944 [wpilib] Add function to wait for DS Connection (#5230) 2023-07-10 09:53:16 -07:00
autoantwort
a6463ed761 [wpiutil] Fix unused variable warning in release build (#5430) 2023-07-10 09:48:51 -07:00
Peter Johnson
f031513470 [ntcore] NetworkTable::GetSubTables(): Remove duplicates (#5076)
In Java, a set is used. Use a two-stage approach in C++ to achieve the
same result.
2023-07-09 21:31:58 -07:00
sciencewhiz
f8e74e2f7c [hal] Unify PWM simulation Speed, Position, and Raw (#5277)
Setting one will set the others, like it does in real hardware.
Add tests for boundary conditions and conversions.
Update PWM sendable implementation to include all forms.
Fixes #5264
Fixes #3606
2023-07-09 21:28:50 -07:00
Tyler Veness
fd5699b240 Remove references to Drake (#5427)
Fixes #5426.
2023-07-09 21:25:14 -07:00
autoantwort
e2d385d80a [build] cmake: Respect USE_SYSTEM_FMTLIB (#5429) 2023-07-09 21:24:46 -07:00
Ryan Blue
d37f990ce3 [hal] Fix HAL Relay/Main doc module (NFC) (#5422) 2023-07-05 21:21:59 -07:00
Ryan Blue
a7a8b874ac [docs] Expand HAL_ENUM in doxygen docs (#5421) 2023-07-05 21:20:21 -07:00
Peter Johnson
3a61deedde [wpimath] Rotation2d: Only use gcem::hypot when constexpr evaluated (#5419) 2023-07-04 12:05:55 -06:00
Peter Johnson
96145de7db [examples] Fix formatting (NFC) (#5420) 2023-07-04 07:14:06 -07:00
Starlight220
fffe6a7b9a [examples] Improve Pneumatics example coverage in Solenoid and RapidReactCmdBot examples (#4998) 2023-07-03 21:23:18 -07:00
Vasista Vovveti
6b5817836d [wpimath] Add tolerance for some tests (#5416) 2023-06-27 14:22:46 -07:00
Vasista Vovveti
3233883f3e [cscore] Fix warnings on macos arm (#5415) 2023-06-27 14:22:19 -07:00
Starlight220
c4fc21838f [commands] Add ConditionalCommand getInterruptionBehavior (#5161) 2023-06-23 08:21:05 -07:00
Starlight220
89fc51f0d4 Add tests for SendableChooser and Command Sendable functionality (#5179) 2023-06-23 08:18:38 -07:00
Ryan Blue
663bf25aaf [docs] Generate docs for symbols in __cplusplus (#5412) 2023-06-22 20:58:38 -07:00
Joseph Eng
fe32127ea8 [command] Clean up Command doc comments (NFC) (#5321) 2023-06-22 19:43:51 -07:00
Thad House
c1a01569b4 [wpilib][hal] PWM Raw using microseconds (#5283)
Co-authored-by: Joe <sciencewhiz@users.noreply.github.com>
2023-06-22 19:43:16 -07:00
Ryan Blue
1fca519fb4 [wpiutil] Remove remnants of ghc fs and tcb_span libraries (#5411) 2023-06-22 19:42:44 -07:00
sciencewhiz
90602cc135 [github] Update issue template to collect more project info (#5090) 2023-06-22 15:26:22 -07:00
sciencewhiz
34412ac57e [build] Exclude files in bin from Spotless (#5410)
Was causing failures in fieldImages.
2023-06-22 15:25:01 -07:00
Thad House
61aa60f0e3 [wpilib] Add robot callback that is called when the DS is initially connected (#5231) 2023-06-21 14:53:34 -07:00
Ryan Blue
ebae341a91 [commands] Add test for subsystem registration and periodic (#5408) 2023-06-20 20:29:59 -07:00
Tyler Veness
5d3a133f9f Remove spaces in NOLINT comments (#5407)
clang-tidy ignores the category filter if there's a space. wpiformat now
ignores categories it doesn't understand, so we can remove the spaces.
2023-06-20 20:29:23 -07:00
Tyler Veness
3a0e484691 [wpimath] Fix clang-tidy warnings (#5403) 2023-06-20 11:35:15 -07:00
Tyler Veness
eb3810c765 [wpiutil] Fix clang-tidy warnings (#5406) 2023-06-20 10:55:05 -07:00
Zhiquan Yeo
c4dc697192 [hal] WS Simulation: Add message filtering capability (#5395) 2023-06-20 08:26:03 -07:00
Tyler Veness
0eccc3f247 [ntcore] Fix clang-tidy warnings (#5405) 2023-06-20 08:21:44 -07:00
sciencewhiz
f4dda4bac0 [hal] Add javadocs for JNI (NFC) (#5298)
Docs are copied from the HAL and add references to the HAL files/methods
to aid discoverability.
2023-06-19 23:36:56 -07:00
Tyler Veness
1c20c69793 [cscore] Fix clang-tidy warnings (#5404) 2023-06-19 23:35:13 -07:00
Tyler Veness
1501607e48 [commands] Fix clang-tidy warnings (#5402) 2023-06-19 23:01:46 -07:00
Gold856
991f4b0f62 [wpimath] PIDController: Add IZone (#5315)
Co-authored-by: Ryan Blue <ryanzblue@gmail.com>
2023-06-19 23:01:01 -07:00
Gold856
f5b0d1484b [wpimath] Add isNear method to MathUtil (#5353)
This method is used to check if the given value matches an expected value within a certain tolerance.

Co-authored-by: Tyler Veness <calcmogul@gmail.com>
Co-authored-by: Ryan Blue <ryanzblue@gmail.com>
2023-06-19 23:00:07 -07:00
Tyler Veness
2ce248f66c [hal] Fix clang-tidy warnings (#5401) 2023-06-19 22:59:07 -07:00
Gold856
5fc4aee2d2 [wpimath] SwerveDriveKinematics: Rename currentChassisSpeed to desiredChassisSpeed (#5393) 2023-06-19 22:58:38 -07:00
Gold856
50b90ceb54 [wpimath] SwerveDriveKinematics: Add reset method (#5398)
Adds a reset method where teams can pass in module headings for the kinematics object to use if it gets an all-zero ChassisSpeeds while converting ChassisSpeeds to module states. Also removes internal states array, replacing it with an internal headings array.
2023-06-19 22:57:55 -07:00
Joseph Eng
316cd2a453 [commands] Notify DriverStationSim in CommandTestBaseWithParam (#5400) 2023-06-19 22:56:56 -07:00
Sriman Achanta
d4ea5fa902 [cscore] VideoMode: Add equals override (Java) (#5397) 2023-06-19 17:12:07 -07:00
Ryan Blue
d6bd72d738 [wpimath] ProfiledPIDController: Add getConstraints (#5399) 2023-06-19 17:11:20 -07:00
Joseph Eng
25ad5017a9 [wpimath] Refactor kinematics, odometry, and pose estimator (#5355) 2023-06-19 17:10:39 -07:00
sciencewhiz
5c2addda0f [doc] Add missing pneumatics docs (NFC) (#5389)
Add missing HAL docs for PCM and PH
Fix references to PCM
Document different one shot durations for PCM and PH
2023-06-15 08:14:35 -07:00
Thad House
c3e04a6ea2 Fix loading tests on macos 12 (#5388) 2023-06-09 23:40:20 -07:00
Thad House
d5ed9fb859 [wpimath] Create separate archive with just units headers (#5383)
This will allow very low level deps to use the same units library we ship with wpilib
2023-06-08 21:11:51 -07:00
Ryan Blue
901ab693d4 [wpimath] Use UtilityClassTest for more utility classes (#5384) 2023-06-08 21:11:26 -07:00
Gold856
9d53231b01 [wpilib] DataLogManager: Add warning for low storage space (#5364) 2023-06-08 20:02:21 -07:00
Ryan Blue
d466933963 [wpiutil] Group doxygen into MPack module (#5380) 2023-06-08 20:00:16 -07:00
Tyler Veness
652d1c44e3 [wpiutil] Upgrade to macOS 12 to remove concept shims (#5379)
The macOS deployment target has been upgraded from 10.15 to 11. Also, a
deprecation warning for sprintf() in libuv was suppressed.
2023-06-08 19:59:54 -07:00
Ryan Blue
6414be0e5d [wpimath] Group units doxygen modules (#5382) 2023-06-08 19:58:55 -07:00
Ryan Blue
7ab5800487 [wpiutil] Fix docs typo in SmallVector (#5381) 2023-06-08 19:58:21 -07:00
Tyler Veness
59905ea721 Replace WPI_DEPRECATED() macro with [[deprecated]] attribute (#5373)
Continue to use WPI_DEPRECATED macro for constructors until clang-format is fixed.
2023-06-08 00:01:06 -07:00
Ryan Blue
753cb49a5e [ntcore] Fix doxygen module in generated C types (NFC) (#5374) 2023-06-07 09:56:20 -07:00
Ryan Blue
1c00a52b67 [hal] Expose CAN timestamp base clock (#5357) 2023-06-07 09:54:03 -07:00
Tyler Veness
91cbcea841 Replace SFINAE with concepts (#5361)
Concepts are cleaner to use and result in much better error messages for incorrect template use.
2023-06-07 09:50:09 -07:00
Tyler Veness
d57d1a4598 [wpimath] Remove unnecessary template argument from unit formatter (#5367) 2023-06-07 09:47:46 -07:00
Tyler Veness
5acc5e22aa [wpimath] Only compute eigenvalues with EigenSolvers (#5369)
We don't need the eigenvectors, so we're doing a lot of extra work we
don't need to.
2023-06-07 09:47:09 -07:00
Ryan Blue
d3c9316a97 extend shuffleboard test timeout (#5377) 2023-06-03 06:47:08 -07:00
Gold856
1ea868081a [ci] Fix /format command (#5376) 2023-06-03 06:43:08 -07:00
Tyler Veness
5fac18ff4a Update formatting to clang-format 16 (#5370) 2023-05-31 22:10:53 -07:00
Tyler Veness
a94a998002 [wpimath] Generalize Eigen formatter (#5360) 2023-05-30 23:35:15 -07:00
Tyler Veness
125f6ea101 [wpimath] Make SwerveDriveKinematics::ToChassisSpeeds() take const-ref argument (#5363) 2023-05-30 23:34:39 -07:00
Tyler Veness
51066a5a8a [wpimath] Move unit formatters into units library (#5358) 2023-05-26 01:05:27 -07:00
Ryan Blue
282c032b60 [wpilibc] Add unit-aware Joystick.GetDirection() (#5319) 2023-05-25 21:43:52 -07:00
Tyler Veness
073d19cb69 [build] Fix CMake warning (#5359)
```
CMake Warning (dev) at CMakeLists.txt:14 (project):
  cmake_minimum_required() should be called prior to this top-level project()
  call.  Please see the cmake-commands(7) manual for usage documentation of
  both commands.
This warning is for project developers.  Use -Wno-dev to suppress it.
```
2023-05-25 21:39:35 -07:00
Gold856
01490fc77b [wpiutil] DataLog: Add documentation for append methods (NFC) (#5348) 2023-05-18 21:56:21 -07:00
Tyler Veness
c9b612c986 [wpilibcExamples] Make C++ state-space elevator KF and LQR match Java (#5346) 2023-05-18 10:09:48 -07:00
Tyler Veness
eed1e6e3cb [wpimath] Replace DiscretizeAQTaylor() with DiscretizeAQ() (#5344)
Until #5339 is fixed, we have to use the slower, more accurate version.
2023-05-18 07:13:20 -07:00
Tyler Veness
c976f40364 [readme] Document how to run examples in simulation (#5340) 2023-05-17 21:09:22 -07:00
Ryan Blue
4d28bdc19e [ci] Update Github Pages deploy action parameters (#5343) 2023-05-17 21:02:43 -07:00
Ryan Blue
e0f851871f [ci] Fix github pages deploy version (#5342) 2023-05-17 20:42:52 -07:00
Tyler Veness
063c8cbedc Run wpiformat (NFC) (#5341) 2023-05-17 18:00:26 -07:00
sciencewhiz
96e41c0447 [ci] Update deploy and sshagent actions (#5338)
Fixes node deprecations
2023-05-16 20:50:03 -07:00
Tyler Veness
fd294bdd71 [build] Fix compilation with GCC 13 (#5322) 2023-05-16 13:31:58 -07:00
Peter Johnson
d223e4040b [dlt] Add delete without download functionality (#5329) 2023-05-16 09:42:06 -07:00
Tyler Veness
abc19bcb43 [upstream_utils] Zero out commit hashes and show 40 digits in index hashes (#5336) 2023-05-16 09:41:46 -07:00
Austin Shalit
e909f2e687 [build] Update gradle cache repo name (#5334)
Artifactory now does not allow repos that end in -cache. Update virtual repo naming to track this new limitation
2023-05-16 00:47:34 -07:00
Tyler Veness
52bd5b972d [wpimath] Rewrite DARE solver (#5328)
I timed the DARE unit tests, and the new solver is 0 to 100% faster in
all cases (that is, it's at least as fast as Drake's and up to 2x faster
in some cases).

The new solver is also much simpler, takes less time to compile, and
drops the libwpimath.so size from 325 MB to 301 MB.

I think most of the compilation time is coming from the eigenvalue
decompositions used to enforce argument preconditions.
2023-05-14 22:23:00 -07:00
Tyler Veness
3876a2523a [wpimath] Remove unused MatrixImpl() function (#5330)
It's an implementation detail left over from MakeMatrix().
2023-05-14 22:22:28 -07:00
Thad House
c82fcb1975 [wpiutil] Add reflection based cleanup helper (#4919)
Co-authored-by: Starlight220 <53231611+Starlight220@users.noreply.github.com>
2023-05-12 21:35:39 -07:00
Tyler Veness
15ba95df7e [wpiutil] Use std::filesystem (#4941) 2023-05-12 21:34:09 -07:00
Tyler Veness
77c2124fc5 [wpimath] Remove Eigen's custom STL types (#4945)
In C++20, overaligned types are handled properly, so Eigen's STL types
with custom allocators are no longer needed.
2023-05-12 21:32:58 -07:00
Peter Johnson
27fb47ab10 [glass] Field2D: Embed standard field images (#5159) 2023-05-12 21:31:38 -07:00
sciencewhiz
102e4f2566 [wpilib] Remove deprecated and broken SPI methods (#5249) 2023-05-12 21:30:53 -07:00
Ryan Blue
463a90f1df [wpilib, hal] Add function to read the RSL state (#5312) 2023-05-12 21:30:19 -07:00
Ryan Blue
7a90475eec [wpilib] Update RobotBase documentation (NFC) (#5320) 2023-05-12 21:29:39 -07:00
Ryan Blue
218cfea16b [wpilib] DutyCycleEncoder: Fix reset behavior (#5287)
reset should set the offset to the properly scaled position provided by getAbsolutePosition, not the raw duty cycle.
2023-05-12 21:28:32 -07:00
Thad House
91392823ff [build] Update to gradle 8.1 (#5303) 2023-05-12 21:27:31 -07:00
sciencewhiz
258b7cc48b [wpilibj] Filesystem.getDeployDirectory(): Strip JNI path from user.dir (#5317)
Fixes
https://www.chiefdelphi.com/t/filesystem-getdeploydirectory-returning-wrong-location-how-to-fix/427292
when unit tests are run with VS Code's java test runner due to VS Code
extension setting working directory which changes user.dir.
2023-05-12 21:26:52 -07:00
Ryan Blue
26cc43bee1 [wpilib] Add documentation to SPI mode enum (NFC) (#5324) 2023-05-12 21:26:10 -07:00
sciencewhiz
ac4da9b1cb [hal] Add HAL docs for Addressable LED (NFC) (#5304) 2023-05-07 22:56:40 -07:00
Tyler Veness
21d4244cf7 [wpimath] Fix DCMotor docs (NFC) (#5309) 2023-05-07 22:56:05 -07:00
sciencewhiz
1dff81bea7 [hal] Miscellaneous HAL doc fixes (NFC) (#5306) 2023-05-07 22:55:48 -07:00
Tyler Veness
7ce75574bf [wpimath] Upgrade to Drake v1.15.0 (#5310) 2023-05-07 22:54:58 -07:00
sciencewhiz
576bd646ae [hal] Add CANManufacturer for Redux Robotics (#5305)
Matches wpilibsuite/frc-docs#2225
2023-05-07 22:53:57 -07:00
Joseph Eng
ee3b4621e5 [commands] Add onlyWhile and onlyIf (#5291) 2023-04-30 14:09:02 -07:00
Joseph Eng
40ca094686 [commands] Fix RepeatCommand calling end() twice (#5261) 2023-04-28 20:57:33 -07:00
Cory
9cbeb841f5 [rtns] Match imaging tool capitalization (#5265) 2023-04-28 20:57:12 -07:00
Josiah Hamm
a63d06ff77 [examples] Add constants to java gearsbot example (#5248) 2023-04-28 20:56:14 -07:00
wmgrove
b6c43322a3 [wpilibc] XboxController: Add return tag to docs (NFC) (#5246) 2023-04-28 20:55:39 -07:00
Thad House
5162d0001c [hal] Fix and document addressable LED timings (#5272)
HAL_SetAddressableLEDBitTiming swapped high and low timings for whatever
was written to it. This fixes that bug.

Additionally, the API has been updated to take high time first, and then
low time. This is due to this being the physical data format, so having
the API match is clearer.

Additionally, update the docs with the defaults.
2023-04-28 20:54:58 -07:00
Tyler Veness
90fabe9651 [wpilibj] Use method references in drive class initSendable() (#5251) 2023-04-28 20:53:42 -07:00
Gold856
24828afd11 [wpimath] Fix desaturateWheelSpeeds to account for negative speeds (#5269) 2023-04-28 20:53:20 -07:00
Tyler Veness
e099948a77 [wpimath] Clean up rank notation in docs (NFC) (#5274) 2023-04-28 20:52:29 -07:00
Tyler Veness
fd2d8cb9c1 [hal] Use std::log2() for base-2 logarithm (#5278) 2023-04-28 20:52:03 -07:00
Sriman Achanta
ba8c64bcff [wpimath] Fix misspelled Javadoc parameters in pose estimators (NFC) (#5292) 2023-04-28 20:51:47 -07:00
Tyler Veness
f53c6813d5 [wpimath] Patch Eigen warnings (#5290) 2023-04-28 20:51:22 -07:00
Thad House
663703d370 [gitattributes] Mark json files as lf text files (#5256)
* Mark json files as lf text files

Otherwise spotless complains

* Formatting
2023-04-06 18:46:18 -07:00
Starlight220
aa34aacf6e [wpilib] Shuffleboard: Keep duplicates on SelectTab() (#5198) 2023-03-26 20:12:55 -07:00
Tyler Veness
63512bbbb8 [wpimath] Fix potential divide-by-zero in RKDP (#5242)
If f(x, u) has no dynamics, the truncation error can be zero.
2023-03-26 17:00:09 -07:00
Peter Johnson
9227b2166e [wpilibj] DriverStation: Fix joystick data logs (#5240)
Was logging relative to cached value rather than previously logged value.
Was also logging cached value instead of current loop value.
C++ implementation is correct.
2023-03-26 16:17:13 -07:00
Peter Johnson
fbf92e9190 [wpinet] ParallelTcpConnector: don't connect to duplicate addresses (#5169)
There can be duplicate addresses coming out of name resolution; if we
already started connecting to an address, don't start another connection
attempt.
2023-03-25 16:28:39 -07:00
Peter Johnson
2108a61362 [ntcore] NT4 client: close timed-out connections (#5175)
Pings are sent every 3 seconds.  If we don't see a response to the last
ping before it's time to send the next one, close the connection.
2023-03-25 16:27:40 -07:00
Peter Johnson
0a66479693 [ntcore] Optimize scan of outgoing messages (#5227)
The algorithm being used for scanning outgoing messages was O(n^2)
because it did a full linear search and then appended. This scan is
performed for each client. If there is a burst of outgoing changes, the
outgoing queue can get quite deep all at once and this scan can be very
slow. Replacing with a map fixes this.
2023-03-25 15:20:22 -07:00
Ryan Blue
b510c17ef6 [hal] Fix RobotController.getComments() mishandling quotes inside the comments string (#5197)
Previously, the comment would end at any quote, escaped or unescaped. This allows UnescapeCString to handle the unescaping of quotes and properly end the string.
2023-03-20 13:50:25 -07:00
Starlight220
e7a7eb2e93 [commands] WaitCommand: Remove subclass doc note (NFC) (#5200) 2023-03-20 13:46:26 -07:00
Starlight220
a465f2d8f0 [examples] Shuffleboard: Correct parameter order (#5204) 2023-03-20 13:45:34 -07:00
Mansour Quddus
a3364422fa LICENSE.md: Bump year to 2023 (#5195) 2023-03-18 07:12:08 -07:00
Tyler Veness
df3242a40a [wpimath] Fix NaN in C++ MakeCostMatrix() that takes an array (#5194)
Java's makeCostMatrix() and the C++ MakeCostMatrix() overload that takes
a parameter pack already do the right thing.
2023-03-17 07:05:28 -07:00
Peter Johnson
00abb8c1e0 [commands] RamseteCommand: default-initialize m_prevSpeeds (#5188) 2023-03-13 23:12:17 -07:00
Ryan Blue
c886273fd7 [wpilibj] DutyCycleEncoder.setDistancePerRotation(): fix simulation (#5147) 2023-03-13 21:28:55 -07:00
Peter Johnson
53b5fd2ace [ntcore] Use int64 for datalog type string (#5186)
There's a spec difference between NT4 and datalog for integers; NT4 uses
"int", datalog uses "int64". We were using "int" for datalog as well.

Also add backwards compatibility support to datalogtool for treating
"int" as "int64".
2023-03-13 21:28:07 -07:00
Peter Johnson
56b758320f [wpilib] DataLogManager: increase time for datetime to be valid (#5185)
There's no signal from NetComm as to when it is valid, and 1 second
seems to be marginal.  Increase to 6 seconds for just DS, 5 seconds for
FMS attached.
2023-03-13 21:27:52 -07:00
nt
08f298e4cd [wpimath] Fix Pose3d log returning Twist3d NaN for theta between 1E-8 and 1E-7 (#5168) 2023-03-13 21:27:32 -07:00
Jeffrey Morris
6d0c5b19db [commands] CommandScheduler.isComposed: Remove incorrect throws clause (NFC) (#5183) 2023-03-13 21:27:08 -07:00
Ryan Blue
0d22cf5ff7 [wpilib] Fix enableLiveWindowInTest crashing in disabled (#5173) 2023-03-10 19:24:40 -08:00
Ryan Blue
32ec5b3f75 [wpilib] Add isTestEnabled and minor docs cleanup (#5172) 2023-03-10 19:23:57 -08:00
Dustin Spicuzza
e5c4c6b1a7 [wpimath] Fix invalid iterator access in TimeInterpolatableBuffer (#5138) 2023-02-26 16:42:24 -08:00
nt
099d048d9e [wpimath] Fix Pose3d log returning Twist3d NaN for theta between 1E-9 and 1E-8 (#5143)
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2023-02-26 16:41:36 -08:00
sciencewhiz
4af84a1c12 Fix Typos (NFC) (#5137) 2023-02-26 15:06:37 -08:00
Tyler Veness
ce3686b80d [wpimath] Check LTV controller max velocity precondition (#5142) 2023-02-26 15:05:41 -08:00
Colin Wong
4b0eecaee0 [commands] Subsystem: Add default command removal method (#5064) 2023-02-24 19:58:53 -08:00
Noah Andrews
edf4ded412 [wpilib] PH: Revert to 5V rail being fixed 5V (#5122) 2023-02-24 19:55:50 -08:00
Gabor Szita
4c46b6aff9 [wpilibc] Fix DataLogManager crash on exit in sim (#5125) 2023-02-23 20:13:20 -08:00
David Vo
490ca4a68a [wpilibc] Fix XboxController::GetBackButton doc (NFC) (#5131) 2023-02-23 20:11:10 -08:00
superpenguin612
cbb5b0b802 [hal] Simulation: Fix REV PH solenoids 8+ (#5132) 2023-02-23 20:10:44 -08:00
Thad House
bb7053d9ee [hal] Fix HAL_GetRuntimeType being slow on the roboRIO (#5130)
HAL_GetRuntimeType used to be a free call before the roboRIO2 was added. However, nLoadOut::getTargetClass() is not a free call, and it may hit the IPC layer. Cache this value so it is not called every time.
2023-02-23 00:59:59 -08:00
sciencewhiz
9efed9a533 Update .clang-format to c++20 (#5121)
This does not result in any reformatting
2023-02-20 10:54:55 -08:00
sciencewhiz
dbbfe1aed2 [wpilib] Use PH voltage to calc Analog pressure switch threshold (#5115)
The calculated trigger voltages were calculated with a hard coded 5v.
This introduces error when the 5V provided to the Analog pressure
sensor is not exactly 5v, as the pressure is a ratio of the analog
voltage and provided voltage.

This should improve
https://www.chiefdelphi.com/t/rev-pressure-sensor-enablecompressoranalog-not-reaching-configured-pressure/426868
where the 5v voltage was 4.92 volts, which introduces ~8 PSI of error.
2023-02-19 23:13:22 -08:00
Ryan Blue
de65a135c3 [wpilib] DutyCycleEncoderSim: Add channel number constructor (#5118) 2023-02-19 23:12:48 -08:00
sciencewhiz
3e9788cdff [docs] Strip path from generated NT docs (#5119)
Fixes #5117
2023-02-19 23:12:05 -08:00
Peter Johnson
ecb072724d [ntcore] Client::Disconnect(): actually close connection (#5113) 2023-02-17 23:56:49 -08:00
Peter Johnson
0d462a4561 [glass] NT view: Change string/string array to quoted (#5111) 2023-02-17 18:01:54 -08:00
Peter Johnson
ba37986561 [ntcore] NetworkClient::Disconnect: Add null check (#5112) 2023-02-17 16:48:34 -08:00
Peter Johnson
25ab9cda92 [glass,ov] Provide menu item to create topic from root (#5110) 2023-02-17 16:46:02 -08:00
Peter Johnson
2f6251d4a6 [glass] Set default value when publishing new topic (#5109) 2023-02-17 16:45:38 -08:00
Jonah
e9a7bed988 [wpimath] Add timestamp getter to MathShared (#5091)
This makes it possible to mock the timestamp for wpimath without affecting the rest of the library.

Co-authored-by: Peter Johnson <johnson.peter@gmail.com>
2023-02-17 14:53:17 -08:00
Peter Johnson
9cc14bbb43 [ntcore] Add stress test to dev executable (#5107) 2023-02-16 22:49:36 -08:00
Peter Johnson
8068369542 [wpinet] uv: Stop creating handles when closing loop (#5102)
This prevents EventLoopRunner::Stop() from hanging in the case when
new handles are created after the async walk closes all the handles.
2023-02-16 22:49:14 -08:00
Peter Johnson
805c837a42 [ntcore] Fix use-after-free in server (#5101)
The client name deduplication didn't properly deduplicate.  Instead,
always append the client index to guarantee a unique name.
2023-02-16 22:45:50 -08:00
bovlb
fd18577ba0 [commands] Improve documentation of addRequirements (NFC) (#5103) 2023-02-16 22:08:46 -08:00
Tyler Veness
74dea9f05e [wpimath] Fix exception for empty pose buffer in pose estimators (#5106)
Fixes #5100.
2023-02-16 22:00:21 -08:00
sciencewhiz
9eef79d638 [wpilib] PneumaticHub: Document range of enableCompressorAnalog (NFC) (#5099) 2023-02-15 20:25:12 -08:00
Peter Johnson
843574a810 [ntcore] Use wpi::Now instead of loop time for transmit time
As the send function is called after local processing, there can be a
substantial delay between the loop time and the actual send.
2023-02-13 23:00:03 -08:00
Peter Johnson
226ef35212 [wpinet] WebSocket: Reduce server send frame overhead
Avoid allocating 4K buffer to send a 10-byte header per frame.
2023-02-13 23:00:03 -08:00
Peter Johnson
b30664d630 [ntcore] Reduce initial connection overhead
Mixing the announce and value messages causes significant downstream
inefficiency in both time and space.
2023-02-13 23:00:03 -08:00
sciencewhiz
804e5ce236 [examples] MecanumDrive: Fix axis comment in C++ example (NFC) (#5096) 2023-02-13 22:18:23 -08:00
Starlight220
49af88f2bb [examples] ArmSimulation: Fix flaky test (#5093) 2023-02-13 12:59:27 -08:00
Peter Johnson
d56314f866 [wpiutil] Disable mock time on the Rio (#5092) 2023-02-12 22:38:34 -08:00
Starlight220
43975ac7cc [examples] ArmSimulation, ElevatorSimulation: Extract mechanism to class (#5052) 2023-02-12 06:50:57 -08:00
Starlight220
5483464158 [examples, templates] Improve descriptions (NFC) (#5051) 2023-02-12 06:49:20 -08:00
Starlight220
785e7dd85c [wpilibc] SendableChooser: static_assert copy- and default-constructibility (#5078)
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2023-02-12 06:24:00 -08:00
Peter Johnson
e57ded8c39 [ntcore] Improve disconnect error reporting (#5085)
Also fix memory leak in WebSocketConnection destructor.
2023-02-11 22:56:29 -08:00
Peter Johnson
01f0394419 [wpinet] Revert WebSocket: When Close() is called, call closed immediately (#5084)
This caused crashes in ntcore.

This reverts commit b879a6f8c6 (#5047).
2023-02-11 22:56:01 -08:00
Jordan McMichael
59be120982 [wpimath] Fix Pose3d exp()/log() and add rotation vector constructor to Rotation3d (#5072)
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2023-02-08 21:31:03 -08:00
Tyler Veness
37f065032f [wpilib] Refactor TimedRobot tests (#5068) 2023-02-07 23:00:46 -08:00
Ryan Blue
22a170bee7 [wpilib] Add Notifier test (#5070) 2023-02-07 23:00:17 -08:00
1363 changed files with 45350 additions and 29922 deletions

View File

@@ -1,111 +1,171 @@
---
Language: Cpp
BasedOnStyle: Google
AccessModifierOffset: -1
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignArrayOfStructures: None
AlignConsecutiveAssignments:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: true
AlignConsecutiveBitFields:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignConsecutiveDeclarations:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignConsecutiveMacros:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: true
AlignOperands: Align
AlignTrailingComments:
Kind: Always
OverEmptyLines: 0
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: Inline
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
AttributeMacros:
- __capability
BinPackArguments: true
BinPackParameters: true
BitFieldColonSpacing: Both
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: false
AfterControlStatement: Never
AfterEnum: false
AfterExternBlock: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterAttributes: Always
BreakAfterJavaFieldAnnotations: false
BreakArrays: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: Always
BreakBeforeBraces: Attach
BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
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))?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseBlocks: false
IndentCaseLabels: true
IndentExternBlock: AfterExternBlock
IndentGotoLabels: true
IndentPPDirectives: None
IndentRequiresClause: true
IndentWidth: 2
IndentWrappedFunctionNames: false
InsertBraces: false
InsertNewlineAtEOF: false
InsertTrailingCommas: None
IntegerLiteralSeparator:
Binary: 0
BinaryMinDigits: 0
Decimal: 0
DecimalMinDigits: 0
Hex: 0
HexMinDigits: 0
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
LambdaBodyIndentation: Signature
LineEnding: DeriveLF
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Never
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PackConstructorInitializers: NextLine
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyIndentedWhitespace: 0
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
PPIndentWidth: -1
QualifierAlignment: Leave
RawStringFormats:
- Language: Cpp
Delimiters:
@@ -132,34 +192,65 @@ RawStringFormats:
- PARSE_TEXT_PROTO
- ParseTextOrDie
- ParseTextProtoOrDie
CanonicalDelimiter: ''
- ParseTestProto
- ParsePartialTestProto
CanonicalDelimiter: pb
BasedOnStyle: google
ReferenceAlignment: Pointer
ReflowComments: true
RemoveBracesLLVM: false
RemoveSemicolon: false
RequiresClausePosition: OwnLine
RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SortIncludes: false
SortUsingDeclarations: true
SortJavaStaticImport: Before
SortUsingDeclarations: LexicographicNumeric
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterOverloadedOperator: false
AfterRequiresInClause: false
AfterRequiresInExpression: false
BeforeNonEmptyParentheses: false
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInAngles: Never
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: c++17
Standard: c++20
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseTab: Never
WhitespaceSensitiveMacros:
- BOOST_PP_STRINGIZE
- CF_SWIFT_NAME
- NS_SWIFT_NAME
- PP_STRINGIZE
- STRINGIZE
...

View File

@@ -35,7 +35,6 @@ Checks:
bugprone-unhandled-self-assignment,
bugprone-unused-raii,
bugprone-virtual-near-miss,
cert-dcl58-cpp,
cert-err52-cpp,
cert-err60-cpp,
cert-mem57-cpp,

1
.gitattributes vendored
View File

@@ -1,4 +1,5 @@
*.gradle text eol=lf
*.java text eol=lf
*.json text eol=lf
*.md text eol=lf
*.xml text eol=lf

2
.github/CODEOWNERS vendored
View File

@@ -29,8 +29,6 @@
/wpilibNewCommands/ @wpilibsuite/commandbased
/wpilibOldCommands/ @wpilibsuite/commandbased
/wpilibcExamples/ @wpilibsuite/wpilib @wpilibsuite/documentation
/wpilibjExamples/ @wpilibsuite/wpilib @wpilibsuite/documentation

View File

@@ -15,6 +15,8 @@ Steps to reproduce the behavior:
1. ...
2. ...
- Link to code:
**Expected behavior**
A clear and concise description of what you expected to happen.
@@ -22,10 +24,8 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- WPILib Version: [e.g. 2021.3.1]
- OS: [e.g. Windows 11]
- Java version [e.g. 1.10.2]
- C++ version [e.g. 17]
- Project Information: [In Visual Studio Code, press the WPILib button and choose WPILib: Open Project Information. Press the copy button and paste the data here. If not using VS Code, please include WPILib version, Gradle version, Java version, C++ version (if applicable), and any third party libraries and versions]
**Additional context**
Add any other context about the problem here.

View File

@@ -16,7 +16,7 @@ jobs:
name: Linux
container: wpilib/roborio-cross-ubuntu:2023-22.04
flags: ""
- os: macOS-11
- os: macOS-12
name: macOS
container: ""
flags: "-DWITH_JAVA=OFF"

View File

@@ -42,16 +42,10 @@ jobs:
with:
distribution: 'zulu'
java-version: 11
- name: Install clang-format
run: |
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo sh -c "echo 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-14 main' >> /etc/apt/sources.list.d/proposed-repositories.list"
sudo apt-get update -q
sudo apt-get install -y clang-format-14
- name: Install wpiformat
run: pip3 install wpiformat
- name: Run wpiformat
run: wpiformat -clang 14
run: wpiformat
- name: Run spotlessApply
run: ./gradlew spotlessApply
- name: Commit

View File

@@ -26,39 +26,41 @@ jobs:
java-version: 13
- name: Set environment variables (Development)
run: |
echo "TARGET_FOLDER=$BASE_PATH/development" >> $GITHUB_ENV
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 "TARGET_FOLDER=$BASE_PATH/beta" >> $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 "TARGET_FOLDER=$BASE_PATH/release" >> $GITHUB_ENV
echo "BRANCH=release" >> $GITHUB_ENV
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, 'alpha') && !contains(github.ref, 'beta')
- name: Build with Gradle
run: ./gradlew docs:generateJavaDocs docs:doxygen -PbuildServer ${{ env.EXTRA_GRADLE_ARGS }}
- name: Install SSH Client 🔑
uses: webfactory/ssh-agent@v0.7.0
uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.GH_DEPLOY_KEY }}
- name: Deploy Java 🚀
uses: JamesIves/github-pages-deploy-action@3.7.1
- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@v4.4.1
with:
SSH: true
REPOSITORY_NAME: wpilibsuite/wpilibsuite.github.io
BRANCH: main
CLEAN: true
FOLDER: docs/build/docs/javadoc
TARGET_FOLDER: ${{ env.TARGET_FOLDER }}/java
- name: Deploy C++ 🚀
uses: JamesIves/github-pages-deploy-action@3.7.1
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@v6
with:
SSH: true
REPOSITORY_NAME: wpilibsuite/wpilibsuite.github.io
BRANCH: main
CLEAN: true
FOLDER: docs/build/docs/doxygen/html
TARGET_FOLDER: ${{ env.TARGET_FOLDER }}/cpp
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

@@ -46,7 +46,7 @@ jobs:
build-host:
env:
MACOSX_DEPLOYMENT_TARGET: 10.15
MACOSX_DEPLOYMENT_TARGET: 11
strategy:
fail-fast: false
matrix:
@@ -63,7 +63,19 @@ jobs:
build-options: "-PciReleaseOnly --max-workers 1"
task: "copyAllOutputs"
outputs: "build/allOutputs"
- os: macOS-11
# - os: windows-2022
# artifact-name: WinArm64Debug
# architecture: x64
# task: "build"
# build-options: "-PciDebugOnly -Pbuildwinarm64 -Ponlywindowsarm64 --max-workers 1"
# outputs: "build/allOutputs"
# - os: windows-2022
# artifact-name: WinArm64Release
# architecture: x64
# build-options: "-PciReleaseOnly -Pbuildwinarm64 -Ponlywindowsarm64 --max-workers 1"
# task: "copyAllOutputs"
# outputs: "build/allOutputs"
- os: macOS-12
artifact-name: macOS
architecture: x64
task: "build"

View File

@@ -26,16 +26,10 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Install clang-format
run: |
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo sh -c "echo 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-14 main' >> /etc/apt/sources.list.d/proposed-repositories.list"
sudo apt-get update -q
sudo apt-get install -y clang-format-14
- name: Install wpiformat
run: pip3 install wpiformat
- name: Run
run: wpiformat -clang 14
run: wpiformat
- name: Check output
run: git --no-pager diff --exit-code HEAD
- name: Generate diff
@@ -70,12 +64,6 @@ jobs:
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Install clang-tidy
run: |
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo sh -c "echo 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-14 main' >> /etc/apt/sources.list.d/proposed-repositories.list"
sudo apt-get update -q
sudo apt-get install -y clang-tidy-14 clang-format-14
- name: Install wpiformat
run: pip3 install wpiformat
- name: Create compile_commands.json
@@ -83,7 +71,7 @@ jobs:
- name: List changed files
run: wpiformat -list-changed-files
- name: Run clang-tidy
run: wpiformat -clang 14 -no-format -tidy-changed -compile-commands=build/compile_commands/linuxx86-64 -vv
run: wpiformat -no-format -tidy-changed -compile-commands=build/compile_commands/linuxx86-64 -vv
javaformat:
name: "Java format"
runs-on: ubuntu-22.04

View File

@@ -29,10 +29,6 @@ jobs:
run: |
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
- name: Run update_drake.py
run: |
cd upstream_utils
./update_drake.py
- name: Run update_eigen.py
run: |
cd upstream_utils
@@ -41,6 +37,10 @@ jobs:
run: |
cd upstream_utils
./update_fmt.py
- name: Run update_gcem.py
run: |
cd upstream_utils
./update_gcem.py
- name: Run update_libuv.py
run: |
cd upstream_utils

View File

@@ -11,8 +11,8 @@ if ("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows")
set(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION 10.0.18362.0 CACHE STRING INTERNAL FORCE)
endif()
project(allwpilib)
cmake_minimum_required(VERSION 3.3.0)
project(allwpilib)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
message(STATUS "Platform version: ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}")
@@ -81,11 +81,6 @@ if (NOT CMAKE_BUILD_TYPE)
set (CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING "" FORCE)
endif()
# We always want flat install with MSVC.
if (MSVC)
set(WITH_FLAT_INSTALL ON)
endif()
if (WITH_JAVA AND NOT BUILD_SHARED_LIBS)
message(FATAL_ERROR "
FATAL: Cannot build static libs with Java enabled.
@@ -167,8 +162,7 @@ endif()
if (USE_SYSTEM_LIBUV)
set (LIBUV_SYSTEM_REPLACE "
find_package(PkgConfig REQUIRED)
pkg_check_modules(libuv REQUIRED IMPORTED_TARGET libuv)
find_dependency(libuv CONFIG)
")
endif()

View File

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

View File

@@ -16,7 +16,7 @@ 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 respecively 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 classifer 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.
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

View File

@@ -17,6 +17,7 @@ Welcome to the WPILib project. This repository contains the HAL, WPILibJ, and WP
- [Custom toolchain location](#custom-toolchain-location)
- [Formatting/Linting](#formattinglinting)
- [CMake](#cmake)
- [Running examples in simulation](#running-examples-in-simulation)
- [Publishing](#publishing)
- [Structure and Organization](#structure-and-organization)
- [Contributing to WPILib](#contributing-to-wpilib)
@@ -61,7 +62,7 @@ On macOS ARM, run `softwareupdate --install-rosetta`. This is necessary to be ab
Clone the WPILib repository and follow the instructions above for installing any required tooling.
See the [styleguide README](https://github.com/wpilibsuite/styleguide/blob/main/README.md) for wpiformat setup instructions. We use clang-format 14.
See the [styleguide README](https://github.com/wpilibsuite/styleguide/blob/main/README.md) for wpiformat setup instructions.
## Building
@@ -119,7 +120,7 @@ Once a PR has been submitted, formatting can be run in CI by commenting `/format
#### wpiformat
wpiformat can be executed anywhere in the repository via `py -3 -m wpiformat -clang 14` on Windows or `python3 -m wpiformat -clang 14` on other platforms.
wpiformat can be executed anywhere in the repository via `py -3 -m wpiformat` on Windows or `python3 -m wpiformat` on other platforms.
#### Java Code Quality Tools
@@ -131,6 +132,16 @@ If you only want to run the Java autoformatter, run `./gradlew spotlessApply`.
CMake is also supported for building. See [README-CMAKE.md](README-CMAKE.md).
## Running examples in simulation
Examples can be run in simulation with the following command:
```bash
./gradlew wpilibcExamples:runExample
./gradlew wpilibjExamples:runExample
```
where `Example` is the example's folder name.
## Publishing
If you are building to test with other dependencies or just want to export the build as a Maven-style dependency, simply run the `publish` task. This task will publish all available packages to ~/releases/maven/development. If you need to publish the project to a different repo, you can specify it with `-Prepo=repo_name`. Valid options are:

View File

@@ -41,9 +41,6 @@ Team 254 Library wpilibj/src/main/java/edu/wpi/first/wpilibj/spline/SplineP
wpilibc/src/main/native/include/trajectory/TrajectoryParameterizer.h
wpilibc/src/main/native/cpp/trajectory/TrajectoryParameterizer.cpp
Portable File Dialogs wpigui/src/main/native/include/portable-file-dialogs.h
Drake wpimath/src/main/native/thirdparty/drake/
wpimath/src/test/native/cpp/drake/
wpimath/src/test/native/include/drake/
V8 export-template wpiutil/src/main/native/include/wpi/SymbolExports.h
GCEM wpimath/src/main/native/thirdparty/gcem/include/
@@ -1069,41 +1066,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.
=============
Drake Library
=============
All components of Drake are licensed under the BSD 3-Clause License
shown below. Where noted in the source code, some portions may
be subject to other permissive, non-viral licenses.
Copyright 2012-2016 Robot Locomotion Group @ CSAIL
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
the Massachusetts Institute of Technology 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
HOLDER 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.
=====================
Portable File Dialogs
=====================

View File

@@ -7,7 +7,7 @@ include(FetchContent)
FetchContent_Declare(
apriltaglib
GIT_REPOSITORY https://github.com/wpilibsuite/apriltag.git
GIT_TAG ad31e33d20f9782b7239cb15cde57c56c91383ad
GIT_TAG e55b751f2465bd40a880d9acb87d24289e2af89e
)
# Don't use apriltag's CMakeLists.txt due to conflicting naming and JNI

View File

@@ -35,7 +35,6 @@ apply from: "${rootDir}/shared/opencv.gradle"
dependencies {
implementation project(':wpimath')
devImplementation project(':wpimath')
}
sourceSets {

View File

@@ -110,7 +110,7 @@ static AprilTagPoseEstimate DoEstimateOrthogonalIteration(
apriltag_pose_t pose1, pose2;
double err1, err2;
estimate_tag_pose_orthogonal_iteration(&info, &err1, &pose1, &err2, &pose2,
nIters);
nIters, 1e-7);
return {MakePose(pose1), MakePose(pose2), err1, err2};
}

View File

@@ -79,7 +79,7 @@ class WPILIB_DLLEXPORT AprilTagFieldLayout {
/**
* Sets the origin for tag pose transformation.
*
* This tranforms the Pose3ds returned by GetTagPose(int) to return the
* 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

View File

@@ -157,7 +157,7 @@ class AprilTagDetectorTest {
var estimator =
new AprilTagPoseEstimator(new AprilTagPoseEstimator.Config(0.2, 500, 500, 320, 240));
AprilTagPoseEstimate est = estimator.estimateOrthogonalIteration(results[0], 50);
AprilTagPoseEstimate est = estimator.estimateOrthogonalIteration(results[0], 200);
assertEquals(new Transform3d(), est.pose2);
Transform3d pose = estimator.estimate(results[0]);
assertEquals(est.pose1, pose);
@@ -189,7 +189,7 @@ class AprilTagDetectorTest {
new AprilTagPoseEstimator(
new AprilTagPoseEstimator.Config(
0.2, 500, 500, image.cols() / 2.0, image.rows() / 2.0));
AprilTagPoseEstimate est = estimator.estimateOrthogonalIteration(results[0], 50);
AprilTagPoseEstimate est = estimator.estimateOrthogonalIteration(results[0], 200);
assertEquals(Units.degreesToRadians(45), est.pose1.getRotation().getX(), 0.1);
assertEquals(Units.degreesToRadians(0), est.pose1.getRotation().getY(), 0.1);
@@ -222,7 +222,7 @@ class AprilTagDetectorTest {
new AprilTagPoseEstimator(
new AprilTagPoseEstimator.Config(
0.2, 500, 500, image.cols() / 2.0, image.rows() / 2.0));
AprilTagPoseEstimate est = estimator.estimateOrthogonalIteration(results[0], 50);
AprilTagPoseEstimate est = estimator.estimateOrthogonalIteration(results[0], 200);
assertEquals(Units.degreesToRadians(0), est.pose1.getRotation().getX(), 0.1);
assertEquals(Units.degreesToRadians(45), est.pose1.getRotation().getY(), 0.1);
@@ -252,7 +252,7 @@ class AprilTagDetectorTest {
new AprilTagPoseEstimator(
new AprilTagPoseEstimator.Config(
0.2, 500, 500, image.cols() / 2.0, image.rows() / 2.0));
AprilTagPoseEstimate est = estimator.estimateOrthogonalIteration(results[0], 50);
AprilTagPoseEstimate est = estimator.estimateOrthogonalIteration(results[0], 200);
assertEquals(Units.degreesToRadians(0), est.pose1.getRotation().getX(), 0.1);
assertEquals(Units.degreesToRadians(0), est.pose1.getRotation().getY(), 0.1);

View File

@@ -7,7 +7,7 @@ buildscript {
}
}
dependencies {
classpath 'com.hubspot.jinjava:jinjava:2.6.0'
classpath 'com.hubspot.jinjava:jinjava:2.7.1'
}
}
@@ -20,10 +20,10 @@ plugins {
id 'edu.wpi.first.GradleVsCode'
id 'idea'
id 'visual-studio'
id 'net.ltgt.errorprone' version '2.0.2' apply false
id 'com.github.johnrengelman.shadow' version '7.1.2' apply false
id 'com.diffplug.spotless' version '6.12.0' apply false
id 'com.github.spotbugs' version '5.0.8' apply false
id 'net.ltgt.errorprone' version '3.1.0' apply false
id 'com.github.johnrengelman.shadow' version '8.1.1' apply false
id 'com.diffplug.spotless' version '6.20.0' apply false
id 'com.github.spotbugs' version '5.1.3' apply false
}
wpilibVersioning.buildServerMode = project.hasProperty('buildServer')
@@ -94,8 +94,8 @@ ext.addTaskToCopyAllOutputs = { task ->
return
}
copyAllOutputs.dependsOn task
copyAllOutputs.inputs.file task.archivePath
copyAllOutputs.from task.archivePath
copyAllOutputs.inputs.file task.archiveFile
copyAllOutputs.from task.archiveFile
}
subprojects {
@@ -167,5 +167,5 @@ ext.getCurrentArch = {
}
wrapper {
gradleVersion = '7.5.1'
gradleVersion = '8.1'
}

View File

@@ -9,5 +9,5 @@ repositories {
}
}
dependencies {
implementation "edu.wpi.first:native-utils:2023.11.1"
implementation "edu.wpi.first:native-utils:2024.0.0"
}

View File

@@ -14,10 +14,6 @@ dependencies {
implementation project(':wpinet')
implementation project(':ntcore')
implementation project(':cscore')
devImplementation project(':wpiutil')
devImplementation project(':wpinet')
devImplementation project(':ntcore')
devImplementation project(':cscore')
}
ext {

View File

@@ -29,7 +29,7 @@ repositories {
}
dependencies {
implementation 'com.google.code.gson:gson:2.8.9'
implementation 'com.google.code.gson:gson:2.10.1'
implementation project(':wpiutil')
implementation project(':wpinet')
@@ -59,6 +59,9 @@ model {
lib project: ':cscore', library: 'cscore', linkage: 'static'
lib project: ':wpinet', library: 'wpinet', linkage: 'static'
lib project: ':wpiutil', library: 'wpiutil', linkage: 'static'
if (binary.targetPlatform.name == nativeUtils.wpi.platforms.roborio) {
nativeUtils.useRequiredLibrary(binary, 'ni_link_libraries', 'ni_runtime_libraries')
}
}
}
}

View File

@@ -4,6 +4,8 @@
#pragma once
#include <functional>
#include "vision/VisionRunner.h"
namespace frc {

View File

@@ -21,10 +21,10 @@ TEST_P(DutyCycleTest, DutyCycle) {
ASSERT_EQ(0, status);
// Ensure our PWM is disabled, and set up properly
HAL_SetPWMRaw(pwmHandle, 0, &status);
HAL_SetPWMPulseTimeMicroseconds(pwmHandle, 0, &status);
ASSERT_EQ(0, status);
HAL_SetPWMConfig(pwmHandle, 2.0, 1.0, 1.0, 0, 0, &status);
HAL_SetPWMConfig(pwmHandle, 5.05, 2.525, 2.525, 2.525, 0, &status);
HAL_SetPWMConfigMicroseconds(pwmHandle, 2000, 1000, 1000, 0, 0, &status);
HAL_SetPWMConfigMicroseconds(pwmHandle, 5050, 2525, 2525, 2525, 0, &status);
ASSERT_EQ(0, status);
HAL_SetPWMPeriodScale(pwmHandle, 0, &status);
ASSERT_EQ(0, status);
@@ -41,8 +41,9 @@ TEST_P(DutyCycleTest, DutyCycle) {
// Sleep enough time for the frequency to converge
usleep(3500000);
ASSERT_NEAR(1000 / 5.05,
(double)HAL_GetDutyCycleFrequency(dutyCycle, &status), 1);
ASSERT_NEAR(
1000 / 5.05,
static_cast<double>(HAL_GetDutyCycleFrequency(dutyCycle, &status)), 1);
// TODO measure output
}

View File

@@ -32,8 +32,8 @@ void TestTimingDMA(int squelch, std::pair<int, int> param) {
ASSERT_EQ(0, status);
// Ensure our PWM is disabled, and set up properly
HAL_SetPWMRaw(pwmHandle, 0, &status);
HAL_SetPWMConfig(pwmHandle, 2.0, 1.0, 1.0, 0, 0, &status);
HAL_SetPWMPulseTimeMicroseconds(pwmHandle, 0, &status);
HAL_SetPWMConfigMicroseconds(pwmHandle, 2000, 1000, 1000, 0, 0, &status);
HAL_SetPWMPeriodScale(pwmHandle, squelch, &status);
unsigned int checkPeriod = 0;
@@ -163,8 +163,8 @@ void TestTiming(int squelch, std::pair<int, int> param) {
ASSERT_NE(pwmHandle, HAL_kInvalidHandle);
// Ensure our PWM is disabled, and set up properly
HAL_SetPWMRaw(pwmHandle, 0, &status);
HAL_SetPWMConfig(pwmHandle, 2.0, 1.0, 1.0, 0, 0, &status);
HAL_SetPWMPulseTimeMicroseconds(pwmHandle, 0, &status);
HAL_SetPWMConfigMicroseconds(pwmHandle, 2000, 1000, 1000, 0, 0, &status);
HAL_SetPWMPeriodScale(pwmHandle, squelch, &status);
unsigned int checkPeriod = 0;
@@ -251,7 +251,7 @@ void TestTiming(int squelch, std::pair<int, int> param) {
}
}
HAL_SetPWMRaw(pwmHandle, 0, &status);
HAL_SetPWMPulseTimeMicroseconds(pwmHandle, 0, &status);
// Ensure our interrupts have the proper counts
ASSERT_EQ(interruptData.risingStamps.size(),

View File

@@ -36,7 +36,6 @@ model {
srcDir 'src/main/native/include'
include '**/*.h'
}
}
}
binaries.all {
@@ -216,6 +215,9 @@ model {
it.linker.args << '-lGL'
}
}
if (it.targetPlatform.name == nativeUtils.wpi.platforms.roborio) {
nativeUtils.useRequiredLibrary(it, 'ni_link_libraries', 'ni_runtime_libraries')
}
}
sources {
cpp {
@@ -234,6 +236,9 @@ model {
lib project: ':wpiutil', library: 'wpiutil', linkage: 'shared'
lib project: ':wpinet', library: 'wpinet', linkage: 'shared'
lib library: 'cscore', linkage: 'shared'
if (it.targetPlatform.name == nativeUtils.wpi.platforms.roborio) {
nativeUtils.useRequiredLibrary(it, 'ni_link_libraries', 'ni_runtime_libraries')
}
}
sources {
cpp {

View File

@@ -65,6 +65,7 @@ public class CameraServerCvJNI {
public static native void putSourceFrame(int source, long imageNativeObj);
public static native int createCvSink(String name);
// public static native int createCvSinkCallback(String name,
// void (*processFrame)(long time));

View File

@@ -143,7 +143,7 @@ public class CameraServerJNI {
public static native void releaseSource(int source);
//
// Camera Source Common Property Fuctions
// Camera Source Common Property Functions
//
public static native void setCameraBrightness(int source, int brightness);

View File

@@ -4,6 +4,8 @@
package edu.wpi.first.cscore;
import java.util.Objects;
/** Video mode. */
@SuppressWarnings("MemberName")
public class VideoMode {
@@ -75,4 +77,28 @@ public class VideoMode {
/** Frames per second. */
public int fps;
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (other == null) {
return false;
}
if (getClass() != other.getClass()) {
return false;
}
VideoMode mode = (VideoMode) other;
return pixelFormat == mode.pixelFormat
&& width == mode.width
&& height == mode.height
&& fps == mode.fps;
}
@Override
public int hashCode() {
return Objects.hash(pixelFormat, width, height, fps);
}
}

View File

@@ -22,9 +22,7 @@ class Image {
public:
#ifndef __linux__
explicit Image(size_t capacity) {
m_data.reserve(capacity);
}
explicit Image(size_t capacity) { m_data.reserve(capacity); }
#else
explicit Image(size_t capacity)
: m_data{capacity, default_init_allocator<uchar>{}} {
@@ -39,35 +37,19 @@ class Image {
operator std::string_view() const { // NOLINT
return str();
}
std::string_view str() const {
return {data(), size()};
}
size_t capacity() const {
return m_data.capacity();
}
std::string_view str() const { return {data(), size()}; }
size_t capacity() const { return m_data.capacity(); }
const char* data() const {
return reinterpret_cast<const char*>(m_data.data());
}
char* data() {
return reinterpret_cast<char*>(m_data.data());
}
size_t size() const {
return m_data.size();
}
char* data() { return reinterpret_cast<char*>(m_data.data()); }
size_t size() const { return m_data.size(); }
const std::vector<uchar>& vec() const {
return m_data;
}
std::vector<uchar>& vec() {
return m_data;
}
const std::vector<uchar>& vec() const { return m_data; }
std::vector<uchar>& vec() { return m_data; }
void resize(size_t size) {
m_data.resize(size);
}
void SetSize(size_t size) {
m_data.resize(size);
}
void resize(size_t size) { m_data.resize(size); }
void SetSize(size_t size) { m_data.resize(size); }
cv::Mat AsMat() {
int type;
@@ -90,9 +72,7 @@ class Image {
return cv::Mat{height, width, type, m_data.data()};
}
cv::_InputArray AsInputArray() {
return cv::_InputArray{m_data};
}
cv::_InputArray AsInputArray() { return cv::_InputArray{m_data}; }
bool Is(int width_, int height_) {
return width == width_ && height == height_;
@@ -114,12 +94,8 @@ class Image {
bool IsLarger(const Image& oth) {
return width >= oth.width && height >= oth.height;
}
bool IsSmaller(int width_, int height_) {
return !IsLarger(width_, height_);
}
bool IsSmaller(const Image& oth) {
return !IsLarger(oth);
}
bool IsSmaller(int width_, int height_) { return !IsLarger(width_, height_); }
bool IsSmaller(const Image& oth) { return !IsLarger(oth); }
private:
std::vector<uchar> m_data;

View File

@@ -16,7 +16,7 @@
namespace cs {
// The UnlimitedHandleResource class is a way to track handles. This version
// allows an unlimted number of handles that are allocated sequentially. When
// allows an unlimited number of handles that are allocated sequentially. When
// possible, indices are reused to save memory usage and keep the array length
// down.
// However, automatic array management has not been implemented, but might be in

View File

@@ -516,7 +516,7 @@ void CS_FreeEnumeratedVideoModes(CS_VideoMode* modes, int count) {
std::free(modes);
}
char* CS_GetHostname() {
char* CS_GetHostname(void) {
return cs::ConvertToC(cs::GetHostname());
}

View File

@@ -439,7 +439,7 @@ void ReleaseSource(CS_Source source, CS_Status* status) {
}
//
// Camera Source Common Property Fuctions
// Camera Source Common Property Functions
//
void SetCameraBrightness(CS_Source source, int brightness, CS_Status* status) {

View File

@@ -323,7 +323,7 @@ void CS_ReleaseSource(CS_Source source, CS_Status* status);
/** @} */
/**
* @defgroup cscore_source_prop_cfunc Camera Source Common Property Fuctions
* @defgroup cscore_source_prop_cfunc Camera Source Common Property Functions
* @{
*/
void CS_SetCameraBrightness(CS_Source source, int brightness,
@@ -504,7 +504,7 @@ void CS_FreeHttpCameraUrls(char** urls, int count);
void CS_FreeEnumeratedProperties(CS_Property* properties, int count);
void CS_FreeEnumeratedVideoModes(CS_VideoMode* modes, int count);
char* CS_GetHostname();
char* CS_GetHostname(void);
char** CS_GetNetworkInterfaces(int* count);
void CS_FreeNetworkInterfaces(char** interfaces, int count);

View File

@@ -262,7 +262,7 @@ void ReleaseSource(CS_Source source, CS_Status* status);
/** @} */
/**
* @defgroup cscore_camera_property_func Camera Source Common Property Fuctions
* @defgroup cscore_camera_property_func Camera Source Common Property Functions
* @{
*/
void SetCameraBrightness(CS_Source source, int brightness, CS_Status* status);

View File

@@ -5,6 +5,8 @@
#ifndef CSCORE_CSCORE_CV_H_
#define CSCORE_CSCORE_CV_H_
#include <functional>
#include "cscore_c.h"
#ifdef CSCORE_CSCORE_RAW_CV_H_
@@ -152,8 +154,8 @@ class CvSink : public ImageSink {
* message); the frame time is in the same time base as wpi::Now(),
* and is in 1 us increments.
*/
[[nodiscard]] uint64_t GrabFrame(cv::Mat& image,
double timeout = 0.225) const;
[[nodiscard]]
uint64_t GrabFrame(cv::Mat& image, double timeout = 0.225) const;
/**
* Wait for the next frame and get the image. May block forever.
@@ -163,7 +165,8 @@ class CvSink : public ImageSink {
* message); the frame time is in the same time base as wpi::Now(),
* and is in 1 us increments.
*/
[[nodiscard]] uint64_t GrabFrameNoTimeout(cv::Mat& image) const;
[[nodiscard]]
uint64_t GrabFrameNoTimeout(cv::Mat& image) const;
};
inline CvSource::CvSource(std::string_view name, const VideoMode& mode) {

View File

@@ -5,6 +5,7 @@
#ifndef CSCORE_CSCORE_OO_H_
#define CSCORE_CSCORE_OO_H_
#include <functional>
#include <initializer_list>
#include <span>
#include <string>

View File

@@ -5,6 +5,7 @@
#ifndef CSCORE_CSCORE_OO_INC_
#define CSCORE_CSCORE_OO_INC_
#include <functional>
#include <string>
#include <string_view>
#include <utility>

View File

@@ -5,6 +5,8 @@
#ifndef CSCORE_CSCORE_RAW_H_
#define CSCORE_CSCORE_RAW_H_
#include <functional>
#include "cscore_c.h"
#ifdef __cplusplus
@@ -174,8 +176,8 @@ class RawSink : public ImageSink {
* message); the frame time is in the same time base as wpi::Now(),
* and is in 1 us increments.
*/
[[nodiscard]] uint64_t GrabFrame(RawFrame& image,
double timeout = 0.225) const;
[[nodiscard]]
uint64_t GrabFrame(RawFrame& image, double timeout = 0.225) const;
/**
* Wait for the next frame and get the image. May block forever.
@@ -185,7 +187,8 @@ class RawSink : public ImageSink {
* message); the frame time is in the same time base as wpi::Now(),
* and is in 1 us increments.
*/
[[nodiscard]] uint64_t GrabFrameNoTimeout(RawFrame& image) const;
[[nodiscard]]
uint64_t GrabFrameNoTimeout(RawFrame& image) const;
};
inline RawSource::RawSource(std::string_view name, const VideoMode& mode) {

View File

@@ -9,6 +9,8 @@
#error "Cannot include both cscore_cv.h and cscore_raw_cv.h in the same file"
#endif
#include <functional>
#include <opencv2/core/mat.hpp>
#include "cscore_raw.h"
@@ -111,7 +113,8 @@ class RawCvSink : public RawSink {
* message); the frame time is in the same time base as wpi::Now(),
* and is in 1 us increments.
*/
[[nodiscard]] uint64_t GrabFrame(cv::Mat& image, double timeout = 0.225);
[[nodiscard]]
uint64_t GrabFrame(cv::Mat& image, double timeout = 0.225);
/**
* Wait for the next frame and get the image. May block forever.
@@ -121,7 +124,8 @@ class RawCvSink : public RawSink {
* message); the frame time is in the same time base as wpi::Now(),
* and is in 1 us increments.
*/
[[nodiscard]] uint64_t GrabFrameNoTimeout(cv::Mat& image);
[[nodiscard]]
uint64_t GrabFrameNoTimeout(cv::Mat& image);
/**
* Wait for the next frame and get the image.
@@ -132,8 +136,8 @@ class RawCvSink : public RawSink {
* message); the frame time is in the same time base as wpi::Now(),
* and is in 1 us increments.
*/
[[nodiscard]] uint64_t GrabFrameDirect(cv::Mat& image,
double timeout = 0.225);
[[nodiscard]]
uint64_t GrabFrameDirect(cv::Mat& image, double timeout = 0.225);
/**
* Wait for the next frame and get the image. May block forever.
@@ -143,7 +147,8 @@ class RawCvSink : public RawSink {
* message); the frame time is in the same time base as wpi::Now(),
* and is in 1 us increments.
*/
[[nodiscard]] uint64_t GrabFrameNoTimeoutDirect(cv::Mat& image);
[[nodiscard]]
uint64_t GrabFrameNoTimeoutDirect(cv::Mat& image);
private:
RawFrame rawFrame;

View File

@@ -79,7 +79,7 @@ using namespace cs;
default:
OBJCERROR(
"Camera access explicitly blocked for application. No cameras are "
"accessable");
"accessible");
self.isAuthorized = false;
// TODO log
break;
@@ -328,8 +328,6 @@ static cs::VideoMode::PixelFormat FourCCToPixelFormat(FourCharCode fourcc) {
@autoreleasepool {
NSArray<AVCaptureDeviceFormat*>* formats = self.videoDevice.formats;
int count = 0;
for (AVCaptureDeviceFormat* format in formats) {
CMFormatDescriptionRef cmformat = format.formatDescription;
CMVideoDimensions s1 = CMVideoFormatDescriptionGetDimensions(cmformat);
@@ -363,7 +361,6 @@ static cs::VideoMode::PixelFormat FourCCToPixelFormat(FourCharCode fourcc) {
modes.emplace_back(store.mode);
platformModes.emplace_back(store);
count++;
}
}
@@ -524,7 +521,7 @@ static cs::VideoMode::PixelFormat FourCCToPixelFormat(FourCharCode fourcc) {
if (!self.isAuthorized) {
OBJCERROR(
"Camera access not authorized for application. No cameras are "
"accessable");
"accessible");
return false;
}

View File

@@ -78,7 +78,7 @@ STDMETHODIMP SourceReaderCB::OnReadSample(HRESULT hrStatus, DWORD dwStreamIndex,
return S_OK;
if (SUCCEEDED(hrStatus)) {
if (pSample) {
// Prcoess sample
// Process sample
source->ProcessFrame(pSample, m_mode);
// DO NOT release the frame
}

View File

@@ -270,8 +270,9 @@ void UsbCameraImpl::DeviceDisconnect() {
}
static bool IsPercentageProperty(std::string_view name) {
if (wpi::starts_with(name, "raw_"))
if (wpi::starts_with(name, "raw_")) {
name = wpi::substr(name, 4);
}
return name == "Brightness" || name == "Contrast" || name == "Saturation" ||
name == "Hue" || name == "Sharpness" || name == "Gain" ||
name == "Exposure";

View File

@@ -24,7 +24,7 @@ class UsbCameraTest {
static class ConnectVerbose {
@Test
void setConnectVerboseEnabledTest() {
try (UsbCamera camera = new UsbCamera("Nonexistant Camera", getNonexistentCameraDev())) {
try (UsbCamera camera = new UsbCamera("Nonexistent Camera", getNonexistentCameraDev())) {
camera.setConnectVerbose(1);
CompletableFuture<String> result = new CompletableFuture<>();
@@ -38,7 +38,7 @@ class UsbCameraTest {
@Test
void setConnectVerboseDisabledTest() {
try (UsbCamera camera = new UsbCamera("Nonexistant Camera", getNonexistentCameraDev())) {
try (UsbCamera camera = new UsbCamera("Nonexistent Camera", getNonexistentCameraDev())) {
camera.setConnectVerbose(0);
CompletableFuture<String> result = new CompletableFuture<>();

View File

@@ -0,0 +1,21 @@
// 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.cscore;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import org.junit.jupiter.api.Test;
class VideoModeTest {
@Test
void equalityTest() {
VideoMode a = new VideoMode(VideoMode.PixelFormat.kMJPEG, 1920, 1080, 30);
VideoMode b = new VideoMode(VideoMode.PixelFormat.kMJPEG, 1920, 1080, 30);
assertEquals(a, b);
assertNotEquals(a, null);
}
}

View File

@@ -23,6 +23,7 @@ includeOtherLibs {
^fmt/
^glass/
^imgui
^libssh/
^portable-file-dialog
^wpi/
^wpigui

View File

@@ -34,8 +34,16 @@ model {
description("Creates a macOS application bundle for DataLogTool")
from(file("$project.projectDir/Info.plist"))
into(file("$project.buildDir/outputs/bundles/$binary.targetPlatform.architecture.name/DataLogTool.app/Contents"))
into("MacOS") { with copySpec { from binary.executable.file } }
into("Resources") { with copySpec { from icon } }
into("MacOS") {
with copySpec {
from binary.executable.file
}
}
into("Resources") {
with copySpec {
from icon
}
}
inputs.property "HasDeveloperId", project.hasProperty("developerID")
@@ -71,7 +79,7 @@ model {
archiveBaseName = '_M_' + zipBaseName
duplicatesStrategy = 'exclude'
classifier = nativeUtils.getPublishClassifier(binary)
archiveClassifier = nativeUtils.getPublishClassifier(binary)
from(licenseFile) {
into '/'

View File

@@ -4,11 +4,11 @@
#include "App.h"
#include <libssh/libssh.h>
#include <memory>
#include <string_view>
#include <libssh/libssh.h>
#define IMGUI_DEFINE_MATH_OPERATORS
#include <glass/Context.h>

View File

@@ -4,8 +4,6 @@
#include "Downloader.h"
#include <libssh/sftp.h>
#ifdef _WIN32
#include <fcntl.h>
#include <io.h>
@@ -20,6 +18,7 @@
#include <glass/Storage.h>
#include <imgui.h>
#include <imgui_stdlib.h>
#include <libssh/sftp.h>
#include <portable-file-dialogs.h>
#include <wpi/StringExtras.h>
#include <wpi/fs.h>
@@ -77,15 +76,15 @@ void Downloader::DisplayRemoteDirSelector() {
ImGui::SameLine();
if (ImGui::Button("Deselect All")) {
for (auto&& download : m_downloadList) {
download.enabled = false;
for (auto&& download : m_fileList) {
download.selected = false;
}
}
ImGui::SameLine();
if (ImGui::Button("Select All")) {
for (auto&& download : m_downloadList) {
download.enabled = true;
for (auto&& download : m_fileList) {
download.selected = true;
}
}
@@ -138,6 +137,27 @@ void Downloader::DisplayLocalDirSelector() {
m_cv.notify_all();
}
}
ImGui::PushStyleColor(ImGuiCol_Button, IM_COL32(180, 0, 0, 255));
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, IM_COL32(210, 0, 0, 255));
ImGui::PushStyleColor(ImGuiCol_ButtonActive, IM_COL32(255, 0, 0, 255));
if (ImGui::Button("Delete WITHOUT Downloading")) {
ImGui::OpenPopup("DeleteConfirm");
}
ImGui::PopStyleColor(3);
if (ImGui::BeginPopup("DeleteConfirm")) {
ImGui::TextUnformatted("Are you sure? This will NOT download the files");
if (ImGui::Button("DELETE")) {
m_state = kDelete;
m_cv.notify_all();
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
if (ImGui::Button("Cancel")) {
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}
size_t Downloader::DisplayFiles() {
@@ -148,11 +168,15 @@ size_t Downloader::DisplayFiles() {
ImGuiTableFlags_Borders | ImGuiTableFlags_SizingStretchProp)) {
ImGui::TableSetupColumn("File");
ImGui::TableSetupColumn("Size");
ImGui::TableSetupColumn("Download");
ImGui::TableSetupColumn((m_state == kDownload || m_state == kDownloadDone ||
m_state == kDelete || m_state == kDeleteDone)
? "Status"
: "Selected");
ImGui::TableHeadersRow();
for (auto&& download : m_downloadList) {
if ((m_state == kDownload || m_state == kDownloadDone) &&
!download.enabled) {
for (auto&& file : m_fileList) {
if ((m_state == kDownload || m_state == kDownloadDone ||
m_state == kDelete || m_state == kDeleteDone) &&
!file.selected) {
continue;
}
@@ -160,20 +184,24 @@ size_t Downloader::DisplayFiles() {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::TextUnformatted(download.name.c_str());
ImGui::TextUnformatted(file.name.c_str());
ImGui::TableNextColumn();
auto sizeText = fmt::format("{}", download.size);
auto sizeText = fmt::format("{}", file.size);
ImGui::TextUnformatted(sizeText.c_str());
ImGui::TableNextColumn();
if (m_state == kDownload || m_state == kDownloadDone) {
if (!download.status.empty()) {
ImGui::TextUnformatted(download.status.c_str());
if (!file.status.empty()) {
ImGui::TextUnformatted(file.status.c_str());
} else {
ImGui::ProgressBar(download.complete);
ImGui::ProgressBar(file.complete);
}
} else if (m_state == kDelete || m_state == kDeleteDone) {
if (!file.status.empty()) {
ImGui::TextUnformatted(file.status.c_str());
}
} else {
auto checkboxLabel = fmt::format("##{}", download.name);
ImGui::Checkbox(checkboxLabel.c_str(), &download.enabled);
auto checkboxLabel = fmt::format("##{}", file.name);
ImGui::Checkbox(checkboxLabel.c_str(), &file.selected);
}
}
ImGui::EndTable();
@@ -224,6 +252,17 @@ void Downloader::Display() {
}
}
break;
case kDelete:
case kDeleteDone:
DisplayDisconnectButton();
DisplayFiles();
if (m_state == kDeleteDone) {
if (ImGui::Button("Deletion complete!")) {
m_state = kGetFiles;
m_cv.notify_all();
}
}
break;
default:
break;
}
@@ -274,7 +313,7 @@ void Downloader::ThreadMain() {
}
m_error = ex.what();
m_dirList.clear();
m_downloadList.clear();
m_fileList.clear();
m_state = kConnected;
break;
}
@@ -284,7 +323,7 @@ void Downloader::ThreadMain() {
lock.lock();
m_dirList.clear();
m_downloadList.clear();
m_fileList.clear();
for (auto&& attr : fileList) {
if (attr.type == SSH_FILEXFER_TYPE_DIRECTORY) {
if (attr.name != ".") {
@@ -293,7 +332,7 @@ void Downloader::ThreadMain() {
} else if (attr.type == SSH_FILEXFER_TYPE_REGULAR &&
(attr.flags & SSH_FILEXFER_ATTR_SIZE) != 0 &&
wpi::ends_with(attr.name, ".wpilog")) {
m_downloadList.emplace_back(attr.name, attr.size);
m_fileList.emplace_back(attr.name, attr.size);
}
}
@@ -305,20 +344,20 @@ void Downloader::ThreadMain() {
m_state = kDisconnected;
break;
case kDownload: {
for (auto&& download : m_downloadList) {
for (auto&& file : m_fileList) {
if (m_state != kDownload) {
// user aborted
break;
}
if (!download.enabled) {
if (!file.selected) {
continue;
}
auto remoteFilename = fmt::format(
"{}{}{}", m_remoteDir,
wpi::ends_with(m_remoteDir, '/') ? "" : "/", download.name);
auto localFilename = fs::path{m_localDir} / download.name;
uint64_t fileSize = download.size;
wpi::ends_with(m_remoteDir, '/') ? "" : "/", file.name);
auto localFilename = fs::path{m_localDir} / file.name;
uint64_t fileSize = file.size;
lock.unlock();
@@ -329,14 +368,14 @@ void Downloader::ThreadMain() {
if (ec) {
// failed to open
lock.lock();
download.status = ec.message();
file.status = ec.message();
continue;
}
int ofd = fs::FileToFd(of, ec, fs::OF_None);
if (ofd == -1 || ec) {
// failed to convert to fd
lock.lock();
download.status = ec.message();
file.status = ec.message();
continue;
}
@@ -356,12 +395,12 @@ void Downloader::ThreadMain() {
close(ofd);
fs::remove(localFilename, ec);
lock.lock();
download.status = "error writing local file";
file.status = "error writing local file";
goto err;
}
total += copied;
lock.lock();
download.complete = static_cast<float>(total) / fileSize;
file.complete = static_cast<float>(total) / fileSize;
lock.unlock();
}
@@ -381,7 +420,7 @@ void Downloader::ThreadMain() {
fs::remove(localFilename, ec);
}
lock.lock();
download.status = ex.what();
file.status = ex.what();
if (ex.err == SSH_FX_OK || ex.err == SSH_FX_CONNECTION_LOST) {
throw;
}
@@ -395,6 +434,39 @@ void Downloader::ThreadMain() {
}
break;
}
case kDelete: {
for (auto&& file : m_fileList) {
if (m_state != kDelete) {
// user aborted
break;
}
if (!file.selected) {
continue;
}
auto remoteFilename = fmt::format(
"{}{}{}", m_remoteDir,
wpi::ends_with(m_remoteDir, '/') ? "" : "/", file.name);
lock.unlock();
try {
session->Unlink(remoteFilename);
} catch (sftp::Exception& ex) {
lock.lock();
file.status = ex.what();
if (ex.err == SSH_FX_OK || ex.err == SSH_FX_CONNECTION_LOST) {
throw;
}
continue;
}
lock.lock();
file.status = "Deleted";
}
if (m_state == kDelete) {
m_state = kDeleteDone;
}
break;
}
default:
break;
}

View File

@@ -45,6 +45,8 @@ class Downloader {
kGetFiles,
kDownload,
kDownloadDone,
kDelete,
kDeleteDone,
kExit
} m_state = kDisconnected;
std::condition_variable m_cv;
@@ -60,17 +62,16 @@ class Downloader {
bool& m_deleteAfter;
std::vector<std::string> m_dirList;
struct DownloadState {
DownloadState(std::string_view name, uint64_t size)
: name{name}, size{size} {}
struct FileState {
FileState(std::string_view name, uint64_t size) : name{name}, size{size} {}
std::string name;
uint64_t size;
bool enabled = true;
bool selected = true;
float complete = 0.0;
std::string status;
};
std::vector<DownloadState> m_downloadList;
std::vector<FileState> m_fileList;
std::string m_error;

View File

@@ -466,7 +466,8 @@ static void ValueToCsv(wpi::raw_ostream& os, const Entry& entry,
fmt::print(os, "{}", val);
return;
}
} else if (entry.type == "int64") {
} else if (entry.type == "int64" || entry.type == "int") {
// support "int" for compatibility with old NT4 datalogs
int64_t val;
if (record.GetInteger(&val)) {
fmt::print(os, "{}", val);

View File

@@ -4,15 +4,15 @@
#pragma once
#include <libssh/libssh.h>
#include <libssh/sftp.h>
#include <span>
#include <stdexcept>
#include <string>
#include <string_view>
#include <vector>
#include <libssh/libssh.h>
#include <libssh/sftp.h>
namespace sftp {
struct Attributes {

View File

@@ -13,6 +13,7 @@ evaluationDependsOn(':wpilibc')
evaluationDependsOn(':wpilibj')
evaluationDependsOn(':wpimath')
evaluationDependsOn(':wpinet')
evaluationDependsOn(':wpiunits')
evaluationDependsOn(':wpiutil')
def baseArtifactIdCpp = 'documentation'
@@ -64,20 +65,16 @@ doxygen {
cppIncludeRoots.add(it.absolutePath)
}
}
cppIncludeRoots << '../ntcore/build/generated/main/native/include/'
if (project.hasProperty('docWarningsAsErrors')) {
// C++20 shims
exclude 'wpi/ghc/filesystem.hpp'
// Drake
exclude 'drake/common/**'
// Eigen
exclude 'Eigen/**'
exclude 'unsupported/**'
// LLVM
exclude 'wpi/AlignOf.h'
exclude 'wpi/Casting.h'
exclude 'wpi/Chrono.h'
exclude 'wpi/Compiler.h'
exclude 'wpi/ConvertUTF.h'
@@ -88,6 +85,7 @@ doxygen {
exclude 'wpi/Errc.h'
exclude 'wpi/Errno.h'
exclude 'wpi/ErrorHandling.h'
exclude 'wpi/bit.h'
exclude 'wpi/fs.h'
exclude 'wpi/FunctionExtras.h'
exclude 'wpi/function_ref.h'
@@ -174,7 +172,9 @@ doxygen {
enable_preprocessing true
macro_expansion true
expand_only_predef true
predefined "WPI_DEPRECATED(x)=[[deprecated(x)]]"
predefined "WPI_DEPRECATED(x)=[[deprecated(x)]]\"\\\n" +
"\"__cplusplus\"\\\n" +
"\"HAL_ENUM(name)=enum name : int32_t"
if (project.hasProperty('docWarningsAsErrors')) {
warn_as_error 'FAIL_ON_WARNINGS'
@@ -238,7 +238,7 @@ task generateJavaDocs(type: Javadoc) {
if (JavaVersion.current().isJava8Compatible() && project.hasProperty('docWarningsAsErrors')) {
// Treat javadoc warnings as errors.
//
// The second argument '-quiet' is a hack. The one paramater
// The second argument '-quiet' is a hack. The one parameter
// addStringOption() doesn't work, so we add '-quiet', which is added
// anyway by gradle. See https://github.com/gradle/gradle/issues/2354.
//

View File

@@ -151,7 +151,7 @@ html {
--side-nav-arrow-opacity: 0;
--side-nav-arrow-hover-opacity: 0.9;
/* height of an item in any tree / collapsable table */
/* height of an item in any tree / collapsible table */
--tree-item-height: 30px;
--darkmode-toggle-button-icon: "☀️";
@@ -1615,7 +1615,7 @@ SOFTWARE.
html {
/* side nav width. MUST be = `TREEVIEW_WIDTH`.
* Make sure it is wide enought to contain the page title (logo + title + version)
* Make sure it is wide enough to contain the page title (logo + title + version)
*/
--side-nav-fixed-width: 340px;
--menu-display: none;

View File

@@ -25,7 +25,7 @@ endif()
GENERATE_RESOURCES(src/main/native/resources/edu/wpi/first/fields generated/main/cpp FIELDS fields field_images_resources_src)
add_library(fieldImages ${field_images_resources_src})
add_library(fieldImages src/main/native/cpp/fields.cpp ${field_images_resources_src})
set_target_properties(fieldImages PROPERTIES DEBUG_POSTFIX "d")
set_property(TARGET fieldImages PROPERTY FOLDER "libraries")

View File

@@ -14,9 +14,9 @@ if (!project.hasProperty('onlylinuxathena')) {
}
dependencies {
implementation "com.fasterxml.jackson.core:jackson-annotations:2.12.4"
implementation "com.fasterxml.jackson.core:jackson-core:2.12.4"
implementation "com.fasterxml.jackson.core:jackson-databind:2.12.4"
implementation "com.fasterxml.jackson.core:jackson-annotations:2.15.2"
implementation "com.fasterxml.jackson.core:jackson-core:2.15.2"
implementation "com.fasterxml.jackson.core:jackson-databind:2.15.2"
}
ext {
@@ -52,7 +52,7 @@ if (!project.hasProperty('onlylinuxathena')) {
sources {
cpp {
source {
srcDirs "$buildDir/generated/main/cpp"
srcDirs 'src/main/native/cpp', "$buildDir/generated/main/cpp"
include '**/*.cpp'
}
exportedHeaders {

View File

@@ -9,7 +9,7 @@ def outputsFolder = file("$project.buildDir/outputs")
task cppSourcesZip(type: Zip) {
destinationDirectory = outputsFolder
archiveBaseName = cppZipBaseName
classifier = "sources"
archiveClassifier = "sources"
from(licenseFile) {
into '/'
@@ -26,7 +26,7 @@ task cppSourcesZip(type: Zip) {
task cppHeadersZip(type: Zip) {
destinationDirectory = outputsFolder
archiveBaseName = cppZipBaseName
classifier = "headers"
archiveClassifier = "headers"
from(licenseFile) {
into '/'

View File

@@ -79,7 +79,7 @@ public class FieldConfig {
*
* @param resourcePath The path to the resource file
* @return The field configuration
* @throws IOException Throws if the resoure could not be loaded
* @throws IOException Throws if the resource could not be loaded
*/
public static FieldConfig loadFromResource(String resourcePath) throws IOException {
try (InputStream stream = FieldConfig.class.getResourceAsStream(resourcePath);

View File

@@ -0,0 +1,48 @@
// 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.
#include "fields/fields.h"
#include "fields/2018-powerup.h"
#include "fields/2019-deepspace.h"
#include "fields/2020-infiniterecharge.h"
#include "fields/2021-barrel.h"
#include "fields/2021-bounce.h"
#include "fields/2021-galacticsearcha.h"
#include "fields/2021-galacticsearchb.h"
#include "fields/2021-infiniterecharge.h"
#include "fields/2021-slalom.h"
#include "fields/2022-rapidreact.h"
#include "fields/2023-chargedup.h"
using namespace fields;
static const Field kFields[] = {
{"2023 Charged Up", GetResource_2023_chargedup_json,
GetResource_2023_field_png},
{"2022 Rapid React", GetResource_2022_rapidreact_json,
GetResource_2022_field_png},
{"2021 Barrel Racing Path", GetResource_2021_barrelracingpath_json,
GetResource_2021_barrel_png},
{"2021 Bounce Path", GetResource_2021_bouncepath_json,
GetResource_2021_bounce_png},
{"2021 Galactic Search A", GetResource_2021_galacticsearcha_json,
GetResource_2021_galacticsearcha_png},
{"2021 Galactic Search B", GetResource_2021_galacticsearchb_json,
GetResource_2021_galacticsearchb_png},
{"2021 Infinite Recharge", GetResource_2021_infiniterecharge_json,
GetResource_2021_field_png},
{"2021 Slalom Path", GetResource_2021_slalompath_json,
GetResource_2021_slalom_png},
{"2020 Infinite Recharge", GetResource_2020_infiniterecharge_json,
GetResource_2020_field_png},
{"2019 Destination: Deep Space", GetResource_2019_deepspace_json,
GetResource_2019_field_jpg},
{"2018 Power Up", GetResource_2018_powerup_json,
GetResource_2018_field_jpg},
};
std::span<const Field> fields::GetFields() {
return kFields;
}

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.
#pragma once
#include <span>
#include <string_view>
namespace fields {
struct Field {
const char* name;
std::string_view (*getJson)();
std::string_view (*getImage)();
};
std::span<const Field> GetFields();
} // namespace fields

View File

@@ -22,6 +22,7 @@ includeOtherLibs {
^GLFW
^cscore
^fmt/
^fields/
^frc/
^imgui
^networktables/

View File

@@ -16,7 +16,7 @@ set_property(TARGET libglass PROPERTY POSITION_INDEPENDENT_CODE ON)
set_property(TARGET libglass PROPERTY FOLDER "libraries")
wpilib_target_warnings(libglass)
target_link_libraries(libglass PUBLIC wpigui wpimath wpiutil)
target_link_libraries(libglass PUBLIC wpigui wpimath wpiutil fieldImages)
target_include_directories(libglass PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/lib/native/include>

View File

@@ -113,6 +113,7 @@ if (!project.hasProperty('onlylinuxathena')) {
lib project: ':wpiutil', library: 'wpiutil', linkage: 'shared'
lib project: ':wpimath', library: 'wpimath', linkage: 'shared'
lib project: ':wpigui', library: 'wpigui', linkage: 'static'
lib project: ':fieldImages', library: 'fieldImages', linkage: 'shared'
nativeUtils.useRequiredLibrary(it, 'imgui')
}
appendDebugPathToBinaries(binaries)
@@ -144,6 +145,7 @@ if (!project.hasProperty('onlylinuxathena')) {
lib project: ':wpiutil', library: 'wpiutil', linkage: 'shared'
lib project: ':wpimath', library: 'wpimath', linkage: 'shared'
lib project: ':wpigui', library: 'wpigui', linkage: 'static'
lib project: ':fieldImages', library: 'fieldImages', linkage: 'shared'
nativeUtils.useRequiredLibrary(it, 'imgui')
}
appendDebugPathToBinaries(binaries)
@@ -183,6 +185,7 @@ if (!project.hasProperty('onlylinuxathena')) {
lib project: ':wpiutil', library: 'wpiutil', linkage: 'static'
lib project: ':wpimath', library: 'wpimath', linkage: 'static'
lib project: ':wpigui', library: 'wpigui', linkage: 'static'
lib project: ':fieldImages', library: 'fieldImages', linkage: 'static'
nativeUtils.useRequiredLibrary(it, 'opencv_static')
nativeUtils.useRequiredLibrary(it, 'imgui')
if (it.targetPlatform.operatingSystem.isWindows()) {

View File

@@ -17,7 +17,7 @@ def outputsFolder = file("$project.buildDir/outputs")
task libCppSourcesZip(type: Zip) {
destinationDirectory = outputsFolder
archiveBaseName = libZipBaseName
classifier = "sources"
archiveClassifier = "sources"
from(licenseFile) { into '/' }
from('src/lib/native/cpp') { into '/' }
@@ -26,7 +26,7 @@ task libCppSourcesZip(type: Zip) {
task libCppHeadersZip(type: Zip) {
destinationDirectory = outputsFolder
archiveBaseName = libZipBaseName
classifier = "headers"
archiveClassifier = "headers"
from(licenseFile) { into '/' }
from('src/lib/native/include') { into '/' }
@@ -35,7 +35,7 @@ task libCppHeadersZip(type: Zip) {
task libntCppSourcesZip(type: Zip) {
destinationDirectory = outputsFolder
archiveBaseName = libntZipBaseName
classifier = "sources"
archiveClassifier = "sources"
from(licenseFile) { into '/' }
from('src/libnt/native/cpp') { into '/' }
@@ -44,7 +44,7 @@ task libntCppSourcesZip(type: Zip) {
task libntCppHeadersZip(type: Zip) {
destinationDirectory = outputsFolder
archiveBaseName = libntZipBaseName
classifier = "headers"
archiveClassifier = "headers"
from(licenseFile) { into '/' }
from('src/libnt/native/include') { into '/' }
@@ -89,8 +89,16 @@ model {
description("Creates a macOS application bundle for Glass")
from(file("$project.projectDir/Info.plist"))
into(file("$project.buildDir/outputs/bundles/$binary.targetPlatform.architecture.name/Glass.app/Contents"))
into("MacOS") { with copySpec { from binary.executable.file } }
into("Resources") { with copySpec { from icon } }
into("MacOS") {
with copySpec {
from binary.executable.file
}
}
into("Resources") {
with copySpec {
from icon
}
}
inputs.property "HasDeveloperId", project.hasProperty("developerID")
@@ -126,7 +134,7 @@ model {
archiveBaseName = '_M_' + zipBaseName
duplicatesStrategy = 'exclude'
classifier = nativeUtils.getPublishClassifier(binary)
archiveClassifier = nativeUtils.getPublishClassifier(binary)
from(licenseFile) {
into '/'

View File

@@ -53,6 +53,7 @@ static bool gKeyEdit = false;
static int* gEnterKey;
static void (*gPrevKeyCallback)(GLFWwindow*, int, int, int, int);
static bool gNetworkTablesDebugLog = false;
static unsigned int gPrevMode = NT_NET_MODE_NONE;
static void RemapEnterKeyCallback(GLFWwindow* window, int key, int scancode,
int action, int mods) {
@@ -70,26 +71,46 @@ static void RemapEnterKeyCallback(GLFWwindow* window, int key, int scancode,
}
}
/**
* Generates the proper title bar title based on current instance state and
* event.
*/
static std::string MakeTitle(NT_Inst inst, nt::Event event) {
auto mode = nt::GetNetworkMode(inst);
if (mode & NT_NET_MODE_SERVER) {
auto numClients = nt::GetConnections(inst).size();
return fmt::format("Glass - {} Client{} Connected", numClients,
(numClients == 1 ? "" : "s"));
} else if (mode & NT_NET_MODE_CLIENT3 || mode & NT_NET_MODE_CLIENT4) {
if (event.Is(NT_EVENT_CONNECTED)) {
return fmt::format("Glass - Connected ({})",
event.GetConnectionInfo()->remote_ip);
}
}
return "Glass - DISCONNECTED";
}
static void NtInitialize() {
auto inst = nt::GetDefaultInstance();
auto poller = nt::CreateListenerPoller(inst);
nt::AddPolledListener(poller, inst, NT_EVENT_CONNECTION | NT_EVENT_IMMEDIATE);
nt::AddPolledLogger(poller, 0, 100);
gui::AddEarlyExecute([poller] {
gui::AddEarlyExecute([inst, poller] {
auto win = gui::GetSystemWindow();
if (!win) {
return;
}
bool updateTitle = false;
nt::Event connectionEvent;
if (nt::GetNetworkMode(inst) != gPrevMode) {
gPrevMode = nt::GetNetworkMode(inst);
updateTitle = true;
}
for (auto&& event : nt::ReadListenerQueue(poller)) {
if (auto connInfo = event.GetConnectionInfo()) {
// update window title when connection status changes
if ((event.flags & NT_EVENT_CONNECTED) != 0) {
glfwSetWindowTitle(
win, fmt::format("Glass - Connected ({})", connInfo->remote_ip)
.c_str());
} else {
glfwSetWindowTitle(win, "Glass - DISCONNECTED");
}
if (event.Is(NT_EVENT_CONNECTION)) {
updateTitle = true;
connectionEvent = event;
} else if (auto msg = event.GetLogMessage()) {
const char* level = "";
if (msg->level >= NT_LOG_CRITICAL) {
@@ -105,6 +126,10 @@ static void NtInitialize() {
"{}{} ({}:{})\n", level, msg->message, msg->filename, msg->line));
}
}
if (updateTitle) {
glfwSetWindowTitle(win, MakeTitle(inst, connectionEvent).c_str());
}
});
gNetworkTablesLogWindow = std::make_unique<glass::Window>(

View File

@@ -4,7 +4,7 @@
#include "glass/Storage.h"
#include <type_traits>
#include <concepts>
#include <imgui.h>
#include <wpi/StringExtras.h>
@@ -14,7 +14,7 @@ using namespace glass;
template <typename To>
bool ConvertFromString(To* out, std::string_view str) {
if constexpr (std::is_same_v<To, bool>) {
if constexpr (std::same_as<To, bool>) {
if (str == "true") {
*out = true;
} else if (str == "false") {
@@ -24,7 +24,7 @@ bool ConvertFromString(To* out, std::string_view str) {
} else {
return false;
}
} else if constexpr (std::is_floating_point_v<To>) {
} else if constexpr (std::floating_point<To>) {
if (auto val = wpi::parse_float<To>(str)) {
*out = val.value();
} else {
@@ -95,10 +95,14 @@ static inline bool ConvertString(Storage::Value* value) {
template <typename From, typename To>
static void ConvertArray(std::vector<To>** outPtr, std::vector<From>** inPtr) {
if (*inPtr) {
std::vector<To>* tmp;
tmp = new std::vector<To>{(*inPtr)->begin(), (*inPtr)->end()};
delete *inPtr;
*outPtr = tmp;
if (*outPtr) {
(*outPtr)->assign((*inPtr)->begin(), (*inPtr)->end());
} else {
std::vector<To>* tmp;
tmp = new std::vector<To>{(*inPtr)->begin(), (*inPtr)->end()};
delete *inPtr;
*outPtr = tmp;
}
} else {
*outPtr = nullptr;
}
@@ -300,7 +304,7 @@ Storage& Storage::GetChild(std::string_view label_id) {
childPtr = std::make_unique<Value>();
}
if (childPtr->type != Value::kChild) {
childPtr->type = Value::kChild;
childPtr->Reset(Value::kChild);
childPtr->child = new Storage;
}
return *childPtr->child;
@@ -630,22 +634,46 @@ void Storage::ClearValues() {
value.stringVal = value.stringDefault;
break;
case Value::kIntArray:
*value.intArray = *value.intArrayDefault;
if (value.intArrayDefault) {
*value.intArray = *value.intArrayDefault;
} else {
value.intArray->clear();
}
break;
case Value::kInt64Array:
*value.int64Array = *value.int64ArrayDefault;
if (value.int64ArrayDefault) {
*value.int64Array = *value.int64ArrayDefault;
} else {
value.int64Array->clear();
}
break;
case Value::kBoolArray:
*value.boolArray = *value.boolArrayDefault;
if (value.boolArrayDefault) {
*value.boolArray = *value.boolArrayDefault;
} else {
value.boolArray->clear();
}
break;
case Value::kFloatArray:
*value.floatArray = *value.floatArrayDefault;
if (value.floatArrayDefault) {
*value.floatArray = *value.floatArrayDefault;
} else {
value.floatArray->clear();
}
break;
case Value::kDoubleArray:
*value.doubleArray = *value.doubleArrayDefault;
if (value.doubleArrayDefault) {
*value.doubleArray = *value.doubleArrayDefault;
} else {
value.doubleArray->clear();
}
break;
case Value::kStringArray:
*value.stringArray = *value.stringArrayDefault;
if (value.stringArrayDefault) {
*value.stringArray = *value.stringArrayDefault;
} else {
value.stringArray->clear();
}
break;
case Value::kChild:
value.child->Clear();

View File

@@ -11,6 +11,7 @@
#include <string_view>
#include <utility>
#include <fields/fields.h>
#include <fmt/format.h>
#include <frc/geometry/Pose2d.h>
#include <frc/geometry/Rotation2d.h>
@@ -237,10 +238,12 @@ class FieldInfo {
private:
void Reset();
bool LoadImageImpl(const std::string& fn);
void LoadJson(std::string_view jsonfile);
bool LoadJson(wpi::raw_istream& is, std::string_view filename);
void LoadJsonFile(std::string_view jsonfile);
std::unique_ptr<pfd::open_file> m_fileOpener;
std::string& m_builtin;
std::string& m_filename;
gui::Texture m_texture;
@@ -340,7 +343,8 @@ static bool InputPose(frc::Pose2d* pose) {
}
FieldInfo::FieldInfo(Storage& storage)
: m_filename{storage.GetString("image")},
: m_builtin{storage.GetString("builtin")},
m_filename{storage.GetString("image")},
m_width{storage.GetFloat("width", kDefaultWidth.to<float>())},
m_height{storage.GetFloat("height", kDefaultHeight.to<float>())},
m_top{storage.GetInt("top", 0)},
@@ -349,7 +353,25 @@ FieldInfo::FieldInfo(Storage& storage)
m_right{storage.GetInt("right", -1)} {}
void FieldInfo::DisplaySettings() {
if (ImGui::Button("Choose image...")) {
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 10);
if (ImGui::BeginCombo("Image",
m_builtin.empty() ? "Custom" : m_builtin.c_str())) {
if (ImGui::Selectable("Custom", m_builtin.empty())) {
Reset();
}
for (auto&& field : fields::GetFields()) {
bool selected = field.name == m_builtin;
if (ImGui::Selectable(field.name, selected)) {
Reset();
m_builtin = field.name;
}
if (selected) {
ImGui::SetItemDefaultFocus();
}
}
ImGui::EndCombo();
}
if (m_builtin.empty() && ImGui::Button("Load image...")) {
m_fileOpener = std::make_unique<pfd::open_file>(
"Choose field image", "",
std::vector<std::string>{"Image File",
@@ -370,6 +392,7 @@ void FieldInfo::DisplaySettings() {
void FieldInfo::Reset() {
m_texture = gui::Texture{};
m_builtin.clear();
m_filename.clear();
m_imageWidth = 0;
m_imageHeight = 0;
@@ -384,7 +407,7 @@ void FieldInfo::LoadImage() {
auto result = m_fileOpener->result();
if (!result.empty()) {
if (wpi::ends_with(result[0], ".json")) {
LoadJson(result[0]);
LoadJsonFile(result[0]);
} else {
LoadImageImpl(result[0].c_str());
m_top = 0;
@@ -395,33 +418,47 @@ void FieldInfo::LoadImage() {
}
m_fileOpener.reset();
}
if (!m_texture && !m_filename.empty()) {
if (!LoadImageImpl(m_filename)) {
m_filename.clear();
if (!m_texture) {
if (!m_builtin.empty()) {
for (auto&& field : fields::GetFields()) {
if (field.name == m_builtin) {
auto jsonstr = field.getJson();
wpi::raw_mem_istream is{jsonstr.data(), jsonstr.size()};
auto imagedata = field.getImage();
auto texture = gui::Texture::CreateFromImage(
reinterpret_cast<const unsigned char*>(imagedata.data()),
imagedata.size());
if (texture && LoadJson(is, {})) {
m_texture = std::move(texture);
m_imageWidth = m_texture.GetWidth();
m_imageHeight = m_texture.GetHeight();
} else {
m_builtin.clear();
}
}
}
} else if (!m_filename.empty()) {
if (!LoadImageImpl(m_filename)) {
m_filename.clear();
}
}
}
}
void FieldInfo::LoadJson(std::string_view jsonfile) {
std::error_code ec;
wpi::raw_fd_istream f(jsonfile, ec);
if (ec) {
std::fputs("GUI: could not open field JSON file\n", stderr);
return;
}
bool FieldInfo::LoadJson(wpi::raw_istream& is, std::string_view filename) {
// parse file
wpi::json j;
try {
j = wpi::json::parse(f);
j = wpi::json::parse(is);
} catch (const wpi::json::parse_error& e) {
fmt::print(stderr, "GUI: JSON: could not parse: {}\n", e.what());
return false;
}
// top level must be an object
if (!j.is_object()) {
std::fputs("GUI: JSON: does not contain a top object\n", stderr);
return;
return false;
}
// image filename
@@ -430,7 +467,7 @@ void FieldInfo::LoadJson(std::string_view jsonfile) {
image = j.at("field-image").get<std::string>();
} catch (const wpi::json::exception& e) {
fmt::print(stderr, "GUI: JSON: could not read field-image: {}\n", e.what());
return;
return false;
}
// corners
@@ -443,7 +480,7 @@ void FieldInfo::LoadJson(std::string_view jsonfile) {
} catch (const wpi::json::exception& e) {
fmt::print(stderr, "GUI: JSON: could not read field-corners: {}\n",
e.what());
return;
return false;
}
// size
@@ -454,7 +491,7 @@ void FieldInfo::LoadJson(std::string_view jsonfile) {
height = j.at("field-size").at(1).get<float>();
} catch (const wpi::json::exception& e) {
fmt::print(stderr, "GUI: JSON: could not read field-size: {}\n", e.what());
return;
return false;
}
// units for size
@@ -463,7 +500,7 @@ void FieldInfo::LoadJson(std::string_view jsonfile) {
unit = j.at("field-unit").get<std::string>();
} catch (const wpi::json::exception& e) {
fmt::print(stderr, "GUI: JSON: could not read field-unit: {}\n", e.what());
return;
return false;
}
// convert size units to meters
@@ -472,22 +509,35 @@ void FieldInfo::LoadJson(std::string_view jsonfile) {
height = units::convert<units::feet, units::meters>(height);
}
// the image filename is relative to the json file
auto pathname = fs::path{jsonfile}.replace_filename(image).string();
if (!filename.empty()) {
// the image filename is relative to the json file
auto pathname = fs::path{filename}.replace_filename(image).string();
// load field image
if (!LoadImageImpl(pathname.c_str())) {
return;
// load field image
if (!LoadImageImpl(pathname.c_str())) {
return false;
}
m_filename = pathname;
}
// save to field info
m_filename = pathname;
m_top = top;
m_left = left;
m_bottom = bottom;
m_right = right;
m_width = width;
m_height = height;
return true;
}
void FieldInfo::LoadJsonFile(std::string_view jsonfile) {
std::error_code ec;
wpi::raw_fd_istream f(jsonfile, ec);
if (ec) {
std::fputs("GUI: could not open field JSON file\n", stderr);
return;
}
LoadJson(f, jsonfile);
}
bool FieldInfo::LoadImageImpl(const std::string& fn) {

View File

@@ -135,6 +135,8 @@ class Plot {
}
}
void SetColor(const ImVec4& color) { m_backgroundColor.SetColor(color); }
private:
void EmitSettingsLimits(int axis);
void DragDropAccept(PlotView& view, size_t i, int yAxis);
@@ -143,6 +145,9 @@ class Plot {
std::string& m_name;
bool& m_visible;
static constexpr float kDefaultBackgroundColor[4] = {0.0, 0.0, 0.0,
IMPLOT_AUTO};
ColorSetting m_backgroundColor;
bool& m_showPause;
bool& m_lockPrevX;
bool& m_legend;
@@ -484,6 +489,8 @@ Plot::Plot(Storage& storage)
: m_seriesStorage{storage.GetChildArray("series")},
m_name{storage.GetString("name")},
m_visible{storage.GetBool("visible", true)},
m_backgroundColor{
storage.GetFloatArray("backgroundColor", kDefaultBackgroundColor)},
m_showPause{storage.GetBool("showPause", true)},
m_lockPrevX{storage.GetBool("lockPrevX", false)},
m_legend{storage.GetBool("legend", true)},
@@ -580,6 +587,11 @@ void Plot::EmitPlot(PlotView& view, double now, bool paused, size_t i) {
(m_mousePosition ? 0 : ImPlotFlags_NoMouseText);
if (ImPlot::BeginPlot(label, ImVec2(-1, m_height), plotFlags)) {
if (m_backgroundColor.GetColorFloat()[3] == IMPLOT_AUTO) {
SetColor(ImGui::GetStyleColorVec4(ImGuiCol_WindowBg));
}
ImPlot::PushStyleColor(ImPlotCol_PlotBg, m_backgroundColor.GetColor());
// setup legend
if (m_legend) {
ImPlotLegendFlags legendFlags =
@@ -656,6 +668,8 @@ void Plot::EmitPlot(PlotView& view, double now, bool paused, size_t i) {
m_xaxisRange = ImPlot::GetPlotLimits().X;
ImPlotPlot* plot = ImPlot::GetCurrentPlot();
ImPlot::PopStyleColor();
ImPlot::EndPlot();
// copy plot settings back to storage
@@ -715,6 +729,12 @@ void Plot::EmitSettings(size_t i) {
ImGui::Text("Edit plot name:");
ImGui::InputText("##editname", &m_name);
ImGui::Checkbox("Visible", &m_visible);
m_backgroundColor.ColorEdit3("Background color",
ImGuiColorEditFlags_NoInputs);
ImGui::SameLine();
if (ImGui::Button("Default")) {
SetColor(ImGui::GetStyleColorVec4(ImGuiCol_WindowBg));
}
ImGui::Checkbox("Show Pause Button", &m_showPause);
if (i != 0) {
ImGui::Checkbox("Lock X-axis to previous plot", &m_lockPrevX);

View File

@@ -4,6 +4,8 @@
#pragma once
#include <stdint.h>
#include <functional>
#include <string>
#include <string_view>

View File

@@ -5,6 +5,7 @@
#include "glass/networktables/NetworkTables.h"
#include <cinttypes>
#include <concepts>
#include <cstdio>
#include <cstring>
#include <initializer_list>
@@ -82,9 +83,8 @@ static std::string IntegerArrayToString(std::span<const int64_t> in) {
return fmt::format("[{:d}]", fmt::join(in, ","));
}
template <typename T>
template <std::floating_point T>
static std::string FloatArrayToString(std::span<const T> in) {
static_assert(std::is_same_v<T, float> || std::is_same_v<T, double>);
return fmt::format("[{:.6f}]", fmt::join(in, ","));
}
@@ -400,6 +400,11 @@ void NetworkTablesModel::ValueSource::UpdateFromValue(
}
} else {
valueChildren.clear();
valueStr.clear();
wpi::raw_string_ostream os{valueStr};
os << '"';
os.write_escaped(value.GetString());
os << '"';
}
break;
case NT_RAW:
@@ -724,9 +729,8 @@ static bool StringToIntegerArray(std::string_view in,
return true;
}
template <typename T>
template <std::floating_point T>
static bool StringToFloatArray(std::string_view in, std::vector<T>* out) {
static_assert(std::is_same_v<T, float> || std::is_same_v<T, double>);
in = wpi::trim(in);
if (in.empty()) {
return false;
@@ -769,25 +773,32 @@ static bool StringToStringArray(std::string_view in,
}
in = wpi::trim(in);
wpi::SmallVector<std::string_view, 16> inSplit;
wpi::SmallString<32> buf;
wpi::split(in, inSplit, ',', -1, false);
for (auto val : inSplit) {
val = wpi::trim(val);
if (val.empty()) {
continue;
}
if (val.front() != '"' || val.back() != '"') {
fmt::print(stderr,
"GUI: NetworkTables: Could not understand value '{}'\n", val);
while (!in.empty()) {
if (in.front() != '"') {
fmt::print(stderr, "GUI: NetworkTables: Expected '\"'");
return false;
}
val.remove_prefix(1);
val.remove_suffix(1);
out->emplace_back(wpi::UnescapeCString(val, buf).first);
in.remove_prefix(1);
wpi::SmallString<128> buf;
std::string_view val;
std::tie(val, in) = wpi::UnescapeCString(in, buf);
out->emplace_back(val);
if (!in.empty()) {
if (in.front() != '"') {
fmt::print(stderr, "GUI: NetworkTables: Error escaping string");
return false;
}
in.remove_prefix(1);
in = wpi::ltrim(in);
}
if (!in.empty()) {
if (in.front() != ',') {
fmt::print(stderr, "GUI: NetworkTables: Expected ','");
return false;
}
in.remove_prefix(1);
}
}
return true;
}
@@ -826,9 +837,8 @@ static void EmitEntryValueReadonly(const NetworkTablesModel::ValueSource& entry,
break;
}
case NT_STRING: {
// GetString() comes from a std::string, so it's null terminated
ImGui::LabelText(typeStr ? typeStr : "string", "%s",
val.GetString().data());
entry.valueStr.c_str());
break;
}
case NT_BOOLEAN_ARRAY:
@@ -938,13 +948,18 @@ static void EmitEntryValueEditable(NetworkTablesModel::Entry& entry,
break;
}
case NT_STRING: {
char* v = GetTextBuffer(val.GetString());
char* v = GetTextBuffer(entry.valueStr);
if (ImGui::InputText(typeStr ? typeStr : "string", v, kTextBufferSize,
ImGuiInputTextFlags_EnterReturnsTrue)) {
if (entry.publisher == 0) {
entry.publisher = nt::Publish(entry.info.topic, NT_STRING, "string");
if (v[0] == '"') {
if (entry.publisher == 0) {
entry.publisher =
nt::Publish(entry.info.topic, NT_STRING, "string");
}
wpi::SmallString<128> buf;
nt::SetString(entry.publisher,
wpi::UnescapeCString(v + 1, buf).first);
}
nt::SetString(entry.publisher, v);
}
break;
}
@@ -1045,58 +1060,97 @@ static void CreateTopicMenuItem(NetworkTablesModel* model,
model->AddEntry(nt::GetTopic(model->GetInstance().GetHandle(), path));
if (entry->publisher == 0) {
entry->publisher = nt::Publish(entry->info.topic, type, typeStr);
// publish a default value so it's editable
switch (type) {
case NT_BOOLEAN:
nt::SetDefaultBoolean(entry->publisher, false);
break;
case NT_INTEGER:
nt::SetDefaultInteger(entry->publisher, 0);
break;
case NT_FLOAT:
nt::SetDefaultFloat(entry->publisher, 0.0);
break;
case NT_DOUBLE:
nt::SetDefaultDouble(entry->publisher, 0.0);
break;
case NT_STRING:
nt::SetDefaultString(entry->publisher, "");
break;
case NT_BOOLEAN_ARRAY:
nt::SetDefaultBooleanArray(entry->publisher, {});
break;
case NT_INTEGER_ARRAY:
nt::SetDefaultIntegerArray(entry->publisher, {});
break;
case NT_FLOAT_ARRAY:
nt::SetDefaultFloatArray(entry->publisher, {});
break;
case NT_DOUBLE_ARRAY:
nt::SetDefaultDoubleArray(entry->publisher, {});
break;
case NT_STRING_ARRAY:
nt::SetDefaultStringArray(entry->publisher, {});
break;
default:
break;
}
}
}
}
void glass::DisplayNetworkTablesAddMenu(NetworkTablesModel* model,
std::string_view path,
NetworkTablesFlags flags) {
static char nameBuffer[kTextBufferSize];
if (ImGui::BeginMenu("Add new...")) {
if (ImGui::IsWindowAppearing()) {
nameBuffer[0] = '\0';
}
ImGui::InputTextWithHint("New item name", "example", nameBuffer,
kTextBufferSize);
std::string fullNewPath;
if (path == "/") {
path = "";
}
fullNewPath = fmt::format("{}/{}", path, nameBuffer);
ImGui::Text("Adding: %s", fullNewPath.c_str());
ImGui::Separator();
auto entry = model->GetEntry(fullNewPath);
bool exists = entry && entry->info.type != NT_Type::NT_UNASSIGNED;
bool enabled = (flags & NetworkTablesFlags_CreateNoncanonicalKeys ||
nameBuffer[0] != '\0') &&
!exists;
CreateTopicMenuItem(model, fullNewPath, NT_STRING, "string", enabled);
CreateTopicMenuItem(model, fullNewPath, NT_INTEGER, "int", enabled);
CreateTopicMenuItem(model, fullNewPath, NT_FLOAT, "float", enabled);
CreateTopicMenuItem(model, fullNewPath, NT_DOUBLE, "double", enabled);
CreateTopicMenuItem(model, fullNewPath, NT_BOOLEAN, "boolean", enabled);
CreateTopicMenuItem(model, fullNewPath, NT_STRING_ARRAY, "string[]",
enabled);
CreateTopicMenuItem(model, fullNewPath, NT_INTEGER_ARRAY, "int[]", enabled);
CreateTopicMenuItem(model, fullNewPath, NT_FLOAT_ARRAY, "float[]", enabled);
CreateTopicMenuItem(model, fullNewPath, NT_DOUBLE_ARRAY, "double[]",
enabled);
CreateTopicMenuItem(model, fullNewPath, NT_BOOLEAN_ARRAY, "boolean[]",
enabled);
ImGui::EndMenu();
}
}
static void EmitParentContextMenu(NetworkTablesModel* model,
const std::string& path,
NetworkTablesFlags flags) {
static char nameBuffer[kTextBufferSize];
if (ImGui::BeginPopupContextItem(path.c_str())) {
ImGui::Text("%s", path.c_str());
ImGui::Separator();
if (ImGui::BeginMenu("Add new...")) {
if (ImGui::IsWindowAppearing()) {
nameBuffer[0] = '\0';
}
ImGui::InputTextWithHint("New item name", "example", nameBuffer,
kTextBufferSize);
std::string fullNewPath;
if (path == "/") {
fullNewPath = path + nameBuffer;
} else {
fullNewPath = fmt::format("{}/{}", path, nameBuffer);
}
ImGui::Text("Adding: %s", fullNewPath.c_str());
ImGui::Separator();
auto entry = model->GetEntry(fullNewPath);
bool exists = entry && entry->info.type != NT_Type::NT_UNASSIGNED;
bool enabled = (flags & NetworkTablesFlags_CreateNoncanonicalKeys ||
nameBuffer[0] != '\0') &&
!exists;
CreateTopicMenuItem(model, fullNewPath, NT_STRING, "string", enabled);
CreateTopicMenuItem(model, fullNewPath, NT_INTEGER, "int", enabled);
CreateTopicMenuItem(model, fullNewPath, NT_FLOAT, "float", enabled);
CreateTopicMenuItem(model, fullNewPath, NT_DOUBLE, "double", enabled);
CreateTopicMenuItem(model, fullNewPath, NT_BOOLEAN, "boolean", enabled);
CreateTopicMenuItem(model, fullNewPath, NT_STRING_ARRAY, "string[]",
enabled);
CreateTopicMenuItem(model, fullNewPath, NT_INTEGER_ARRAY, "int[]",
enabled);
CreateTopicMenuItem(model, fullNewPath, NT_FLOAT_ARRAY, "float[]",
enabled);
CreateTopicMenuItem(model, fullNewPath, NT_DOUBLE_ARRAY, "double[]",
enabled);
CreateTopicMenuItem(model, fullNewPath, NT_BOOLEAN_ARRAY, "boolean[]",
enabled);
ImGui::EndMenu();
}
DisplayNetworkTablesAddMenu(model, path, flags);
ImGui::EndPopup();
}
@@ -1280,7 +1334,6 @@ static void DisplayTable(NetworkTablesModel* model,
}
ImGui::TableHeadersRow();
// EmitParentContextMenu(model, "/", flags);
if (flags & NetworkTablesFlags_TreeView) {
switch (category) {
case ShowPersistent:
@@ -1511,6 +1564,7 @@ void NetworkTablesView::Display() {
void NetworkTablesView::Settings() {
m_flags.DisplayMenu();
DisplayNetworkTablesAddMenu(m_model, {}, m_flags.GetFlags());
}
bool NetworkTablesView::HasSettings() {

View File

@@ -141,23 +141,45 @@ bool NetworkTablesSettings::Display() {
case 1:
case 2: {
ImGui::InputText("Team/IP", &m_serverTeam);
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal)) {
ImGui::SetTooltip("Team number or IP/MDNS address of server");
}
int* port = m_mode.GetValue() == 1 ? &m_port4 : &m_port3;
if (ImGui::InputInt("Port", port)) {
LimitPortRange(port);
}
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal)) {
ImGui::SetTooltip("TCP Port - leave this at the default");
}
ImGui::SameLine();
if (ImGui::SmallButton("Default")) {
*port = m_mode.GetValue() == 1 ? NT_DEFAULT_PORT4 : NT_DEFAULT_PORT3;
}
ImGui::InputText("Network Identity", &m_clientName);
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal)) {
ImGui::SetTooltip(
"Arbitrary name used to identify clients on the network. Must not "
"be blank.");
}
ImGui::Checkbox("Get Address from DS", &m_dsClient);
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal)) {
ImGui::SetTooltip("Attempt to fetch server IP from Driver Station");
}
break;
}
case 3:
ImGui::InputText("Listen Address", &m_listenAddress);
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal)) {
ImGui::SetTooltip(
"Address for server to listen on. Leave blank to listen on all "
"interfaces.");
}
if (ImGui::InputInt("NT3 port", &m_port3)) {
LimitPortRange(&m_port3);
}
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal)) {
ImGui::SetTooltip("TCP Port for NT3. Leave at default if unsure.");
}
ImGui::SameLine();
if (ImGui::SmallButton("Default##default3")) {
m_port3 = NT_DEFAULT_PORT3;
@@ -165,11 +187,17 @@ bool NetworkTablesSettings::Display() {
if (ImGui::InputInt("NT4 port", &m_port4)) {
LimitPortRange(&m_port4);
}
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal)) {
ImGui::SetTooltip("TCP Port for NT4. Leave at default if unsure.");
}
ImGui::SameLine();
if (ImGui::SmallButton("Default##default4")) {
m_port4 = NT_DEFAULT_PORT4;
}
ImGui::InputText("Persistent Filename", &m_persistentFilename);
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayNormal)) {
ImGui::SetTooltip("File for storage of persistent entries");
}
break;
default:
break;

View File

@@ -194,6 +194,10 @@ void DisplayNetworkTables(
NetworkTablesModel* model,
NetworkTablesFlags flags = NetworkTablesFlags_Default);
void DisplayNetworkTablesAddMenu(
NetworkTablesModel* model, std::string_view path = {},
NetworkTablesFlags flags = NetworkTablesFlags_Default);
class NetworkTablesFlagsSettings {
public:
explicit NetworkTablesFlagsSettings(

Binary file not shown.

View File

@@ -1,5 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

19
gradlew vendored
View File

@@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -80,13 +80,10 @@ do
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -143,12 +140,16 @@ fi
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@@ -193,6 +194,10 @@ if "$cygwin" || "$msys" ; then
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in

1
gradlew.bat vendored
View File

@@ -26,6 +26,7 @@ if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

View File

@@ -4,14 +4,59 @@
package edu.wpi.first.hal;
/**
* Accelerometer HAL JNI methods.
*
* @see "hal/Accelerometer.h"
*/
public class AccelerometerJNI extends JNIWrapper {
/**
* Sets the accelerometer to active or standby mode.
*
* <p>It must be in standby mode to change any configuration.
*
* @see "HAL_SetAccelerometerActive"
* @param active true to set to active, false for standby
*/
public static native void setAccelerometerActive(boolean active);
/**
* Sets the range of values that can be measured (either 2, 4, or 8 g-forces).
*
* <p>The accelerometer should be in standby mode when this is called.
*
* @see "HAL_SetAccelerometerRange(int range)"
* @param range the accelerometer range
*/
public static native void setAccelerometerRange(int range);
/**
* Gets the x-axis acceleration.
*
* <p>This is a floating point value in units of 1 g-force.
*
* @see "HAL_GetAccelerometerX()"
* @return the X acceleration
*/
public static native double getAccelerometerX();
/**
* Gets the y-axis acceleration.
*
* <p>This is a floating point value in units of 1 g-force.
*
* @see "HAL_GetAccelerometerY()"
* @return the Y acceleration
*/
public static native double getAccelerometerY();
/**
* Gets the z-axis acceleration.
*
* <p>This is a floating point value in units of 1 g-force.
*
* @see "HAL_GetAccelerometerZ()"
* @return the Z acceleration
*/
public static native double getAccelerometerZ();
}

View File

@@ -9,6 +9,7 @@ package edu.wpi.first.hal;
public class AccumulatorResult {
/** The total value accumulated. */
public long value;
/** The number of sample value was accumulated over. */
public long count;

View File

@@ -4,21 +4,97 @@
package edu.wpi.first.hal;
/**
* Addressable LED HAL JNI Methods.
*
* @see "hal/AdressableLED.h"
*/
public class AddressableLEDJNI extends JNIWrapper {
/**
* Initialize Addressable LED using a PWM Digital handle.
*
* @param pwmHandle handle of the digital port for PWM
* @return Addressable LED handle
* @see "HAL_InitializeAddressableLED"
*/
public static native int initialize(int pwmHandle);
/**
* Free the Addressable LED Handle.
*
* @param handle the Addressable LED handle to free
* @see "HAL_FreeAddressableLED"
*/
public static native void free(int handle);
/**
* Sets the length of the LED strip.
*
* <p>The max length is 5460 LEDs.
*
* @param handle the Addressable LED handle
* @param length the strip length
* @see "HAL_SetAddressableLEDLength"
*/
public static native void setLength(int handle, int length);
/**
* Sets the led output data.
*
* <p>If the output is enabled, this will start writing the next data cycle. It is safe to call,
* even while output is enabled.
*
* @param handle the Addressable LED handle
* @param data the buffer to write
* @see "HAL_WriteAddressableLEDData"
*/
public static native void setData(int handle, byte[] data);
/**
* Sets the bit timing.
*
* <p>By default, the driver is set up to drive WS2812Bs, so nothing needs to be set for those.
*
* @param handle the Addressable LED handle
* @param highTime0NanoSeconds high time for 0 bit (default 400ns)
* @param lowTime0NanoSeconds low time for 0 bit (default 900ns)
* @param highTime1NanoSeconds high time for 1 bit (default 900ns)
* @param lowTime1NanoSeconds low time for 1 bit (default 600ns)
* @see "HAL_SetAddressableLEDBitTiming"
*/
public static native void setBitTiming(
int handle, int lowTime0, int highTime0, int lowTime1, int highTime1);
int handle,
int highTime0NanoSeconds,
int lowTime0NanoSeconds,
int highTime1NanoSeconds,
int lowTime1NanoSeconds);
public static native void setSyncTime(int handle, int syncTime);
/**
* Sets the sync time.
*
* <p>The sync time is the time to hold output so LEDs enable. Default set for WS2812B.
*
* @param handle the Addressable LED handle
* @param syncTimeMicroSeconds the sync time (default 280us)
* @see "HAL_SetAddressableLEDSyncTime"
*/
public static native void setSyncTime(int handle, int syncTimeMicroSeconds);
/**
* Starts the output.
*
* <p>The output writes continuously.
*
* @param handle the Addressable LED handle
* @see "HAL_StartAddressableLEDOutput"
*/
public static native void start(int handle);
/**
* Stops the output.
*
* @param handle the Addressable LED handle
* @see "HAL_StopAddressableLEDOutput"
*/
public static native void stop(int handle);
}

View File

@@ -5,6 +5,7 @@
package edu.wpi.first.hal;
public enum AllianceStationID {
Unknown,
Red1,
Red2,
Red3,

View File

@@ -4,30 +4,126 @@
package edu.wpi.first.hal;
/**
* Analog Gyro JNI Functions.
*
* @see "hal/AnalogGyro.h"
*/
public class AnalogGyroJNI extends JNIWrapper {
/**
* Initializes an analog gyro.
*
* @param halAnalogInputHandle handle to the analog input port
* @return the initialized gyro handle
* @see "HAL_InitializeAnalogGyro"
*/
public static native int initializeAnalogGyro(int halAnalogInputHandle);
/**
* Sets up an analog gyro with the proper offsets and settings for the KOP analog gyro.
*
* @param handle the gyro handle
* @see "HAL_SetupAnalogGyro"
*/
public static native void setupAnalogGyro(int handle);
/**
* Frees an analog gyro.
*
* @param handle the gyro handle
* @see "HAL_FreeAnalogGyro"
*/
public static native void freeAnalogGyro(int handle);
/**
* Sets the analog gyro parameters to the specified values.
*
* <p>This is meant to be used if you want to reuse the values from a previous calibration.
*
* @param handle the gyro handle
* @param voltsPerDegreePerSecond the gyro volts scaling
* @param offset the gyro offset
* @param center the gyro center
* @see "HAL_SetAnalogGyroParameters"
*/
public static native void setAnalogGyroParameters(
int handle, double voltsPerDegreePerSecond, double offset, int center);
/**
* Sets the analog gyro volts per degrees per second scaling.
*
* @param handle the gyro handle
* @param voltsPerDegreePerSecond the gyro volts scaling
* @see "HAL_SetAnalogGyroVoltsPerDegreePerSecond"
*/
public static native void setAnalogGyroVoltsPerDegreePerSecond(
int handle, double voltsPerDegreePerSecond);
/**
* Resets the analog gyro value to 0.
*
* @param handle the gyro handle
* @see "HAL_ResetAnalogGyro"
*/
public static native void resetAnalogGyro(int handle);
/**
* Calibrates the analog gyro.
*
* <p>This happens by calculating the average value of the gyro over 5 seconds, and setting that
* as the center. Note that this call blocks for 5 seconds to perform this.
*
* @param handle the gyro handle
* @see "HAL_CalibrateAnalogGyro"
*/
public static native void calibrateAnalogGyro(int handle);
/**
* Sets the deadband of the analog gyro.
*
* @param handle the gyro handle
* @param volts the voltage deadband
* @see "HAL_SetAnalogGyroDeadband"
*/
public static native void setAnalogGyroDeadband(int handle, double volts);
/**
* Gets the gyro angle in degrees.
*
* @param handle the gyro handle
* @return the gyro angle in degrees
* @see "HAL_GetAnalogGyroAngle"
*/
public static native double getAnalogGyroAngle(int handle);
/**
* Gets the gyro rate in degrees/second.
*
* @param handle the gyro handle
* @return the gyro rate in degrees/second
* @see "HAL_GetAnalogGyroRate"
*/
public static native double getAnalogGyroRate(int handle);
/**
* Gets the calibrated gyro offset.
*
* <p>Can be used to not repeat a calibration but reconstruct the gyro object.
*
* @param handle the gyro handle
* @return the gryo offset
* @see "HAL_GetAnalogGyroOffset"
*/
public static native double getAnalogGyroOffset(int handle);
/**
* Gets the calibrated gyro center.
*
* <p>Can be used to not repeat a calibration but reconstruct the gyro object.
*
* @param handle the gyro handle
* @return the gyro center
* @see "HAL_GetAnalogGyroCenter"
*/
public static native int getAnalogGyroCenter(int handle);
}

View File

@@ -4,6 +4,14 @@
package edu.wpi.first.hal;
/**
* Analog Input / Output / Accumulator / Trigger JNI Functions.
*
* @see "hal/AnalogInput.h"
* @see "hal/AnalogOutput.h"
* @see "hal/AnalogAccumulator.h"
* @see "hal/AnalogTrigger.h"
*/
public class AnalogJNI extends JNIWrapper {
/**
* <i>native declaration : AthenaJava\target\native\include\HAL\Analog.h:58</i><br>
@@ -12,104 +20,481 @@ public class AnalogJNI extends JNIWrapper {
public interface AnalogTriggerType {
/** <i>native declaration : AthenaJava\target\native\include\HAL\Analog.h:54</i> */
int kInWindow = 0;
/** <i>native declaration : AthenaJava\target\native\include\HAL\Analog.h:55</i> */
int kState = 1;
/** <i>native declaration : AthenaJava\target\native\include\HAL\Analog.h:56</i> */
int kRisingPulse = 2;
/** <i>native declaration : AthenaJava\target\native\include\HAL\Analog.h:57</i> */
int kFallingPulse = 3;
}
/**
* Initializes the analog input port using the given port object.
*
* @param halPortHandle Handle to the port to initialize.
* @return the created analog input handle
* @see "HAL_InitializeAnalogInputPort"
*/
public static native int initializeAnalogInputPort(int halPortHandle);
/**
* Frees an analog input port.
*
* @param portHandle Handle to the analog port.
* @see "HAL_FreeAnalogInputPort"
*/
public static native void freeAnalogInputPort(int portHandle);
/**
* Initializes the analog output port using the given port object.
*
* @param halPortHandle handle to the port
* @return the created analog output handle
* @see "HAL_InitializeAnalogOutputPort"
*/
public static native int initializeAnalogOutputPort(int halPortHandle);
/**
* Frees an analog output port.
*
* @param portHandle the analog output handle
* @see "HAL_FreeAnalogOutputPort"
*/
public static native void freeAnalogOutputPort(int portHandle);
/**
* Checks that the analog module number is valid.
*
* @param module The analog module number.
* @return Analog module is valid and present
* @see "HAL_CheckAnalogModule"
*/
public static native boolean checkAnalogModule(byte module);
/**
* Checks that the analog output channel number is valid. Verifies that the analog channel number
* is one of the legal channel numbers. Channel numbers are 0-based.
*
* @param channel The analog output channel number.
* @return Analog channel is valid
* @see "HAL_CheckAnalogInputChannel"
*/
public static native boolean checkAnalogInputChannel(int channel);
public static native boolean checkAnalogOutputChannel(int channel);
/**
* Indicates the analog input is used by a simulated device.
*
* @param handle the analog input handle
* @param device simulated device handle
* @see "HAL_SetAnalogInputSimDevice"
*/
public static native void setAnalogInputSimDevice(int handle, int device);
public static native void setAnalogOutput(int portHandle, double voltage);
public static native double getAnalogOutput(int portHandle);
/**
* Sets the sample rate.
*
* <p>This is a global setting for the Athena and effects all channels.
*
* @param samplesPerSecond The number of samples per channel per second.
* @see "HAL_SetAnalogSampleRate"
*/
public static native void setAnalogSampleRate(double samplesPerSecond);
/**
* Gets the current sample rate.
*
* <p>This assumes one entry in the scan list. This is a global setting for the Athena and effects
* all channels.
*
* @return Sample rate.
* @see "HAL_GetAnalogSampleRate"
*/
public static native double getAnalogSampleRate();
/**
* Sets the number of averaging bits.
*
* <p>This sets the number of averaging bits. The actual number of averaged samples is 2**bits.
* Use averaging to improve the stability of your measurement at the expense of sampling rate. The
* averaging is done automatically in the FPGA.
*
* @param analogPortHandle Handle to the analog port to configure.
* @param bits Number of bits to average.
* @see "HAL_SetAnalogAverageBits"
*/
public static native void setAnalogAverageBits(int analogPortHandle, int bits);
/**
* Gets the number of averaging bits.
*
* <p>This gets the number of averaging bits from the FPGA. The actual number of averaged samples
* is 2**bits. The averaging is done automatically in the FPGA.
*
* @param analogPortHandle Handle to the analog port to use.
* @return Bits to average.
* @see "HAL_GetAnalogAverageBits"
*/
public static native int getAnalogAverageBits(int analogPortHandle);
/**
* Sets the number of oversample bits.
*
* <p>This sets the number of oversample bits. The actual number of oversampled values is 2**bits.
* Use oversampling to improve the resolution of your measurements at the expense of sampling
* rate. The oversampling is done automatically in the FPGA.
*
* @param analogPortHandle Handle to the analog port to use.
* @param bits Number of bits to oversample.
* @see "HAL_SetAnalogOversampleBits"
*/
public static native void setAnalogOversampleBits(int analogPortHandle, int bits);
/**
* Gets the number of oversample bits.
*
* <p>This gets the number of oversample bits from the FPGA. The actual number of oversampled
* values is 2**bits. The oversampling is done automatically in the FPGA.
*
* @param analogPortHandle Handle to the analog port to use.
* @return Bits to oversample.
* @see "HAL_GetAnalogOversampleBits"
*/
public static native int getAnalogOversampleBits(int analogPortHandle);
/**
* Gets a sample straight from the channel on this module.
*
* <p>The sample is a 12-bit value representing the 0V to 5V range of the A/D converter in the
* module. The units are in A/D converter codes. Use GetVoltage() to get the analog value in
* calibrated units.
*
* @param analogPortHandle Handle to the analog port to use.
* @return A sample straight from the channel on this module.
* @see "HAL_GetAnalogValue"
*/
public static native short getAnalogValue(int analogPortHandle);
/**
* Gets a sample from the output of the oversample and average engine for the channel.
*
* <p>The sample is 12-bit + the value configured in SetOversampleBits(). The value configured in
* SetAverageBits() will cause this value to be averaged 2**bits number of samples. This is not a
* sliding window. The sample will not change until 2**(OversampleBits + AverageBits) samples have
* been acquired from the module on this channel. Use GetAverageVoltage() to get the analog value
* in calibrated units.
*
* @param analogPortHandle Handle to the analog port to use.
* @return A sample from the oversample and average engine for the channel.
* @see "HAL_GetAnalogAverageValue"
*/
public static native int getAnalogAverageValue(int analogPortHandle);
/**
* Converts a voltage to a raw value for a specified channel.
*
* <p>This process depends on the calibration of each channel, so the channel must be specified.
*
* <p>todo This assumes raw values. Oversampling not supported as is.
*
* @param analogPortHandle Handle to the analog port to use.
* @param voltage The voltage to convert.
* @return The raw value for the channel.
* @see "HAL_GetAnalogVoltsToValue"
*/
public static native int getAnalogVoltsToValue(int analogPortHandle, double voltage);
/**
* Get the analog voltage from a raw value.
*
* @param analogPortHandle Handle to the analog port the values were read from.
* @param value The raw analog value
* @return The voltage relating to the value
* @see "HAL_GetAnalogValueToVolts"
*/
public static native double getAnalogValueToVolts(int analogPortHandle, int value);
/**
* Gets a scaled sample straight from the channel on this module.
*
* <p>The value is scaled to units of Volts using the calibrated scaling data from GetLSBWeight()
* and GetOffset().
*
* @param analogPortHandle Handle to the analog port to use.
* @return A scaled sample straight from the channel on this module.
* @see "HAL_GetAnalogVoltage"
*/
public static native double getAnalogVoltage(int analogPortHandle);
/**
* Gets a scaled sample from the output of the oversample and average engine for the channel.
*
* <p>The value is scaled to units of Volts using the calibrated scaling data from GetLSBWeight()
* and GetOffset(). Using oversampling will cause this value to be higher resolution, but it will
* update more slowly. Using averaging will cause this value to be more stable, but it will update
* more slowly.
*
* @param analogPortHandle Handle to the analog port to use.
* @return A scaled sample from the output of the oversample and average engine for the channel.
* @see "HAL_GetAnalogAverageVoltage"
*/
public static native double getAnalogAverageVoltage(int analogPortHandle);
/**
* Gets the factory scaling least significant bit weight constant. The least significant bit
* weight constant for the channel that was calibrated in manufacturing and stored in an eeprom in
* the module.
*
* <p>Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
*
* @param analogPortHandle Handle to the analog port to use.
* @return Least significant bit weight.
* @see "HAL_GetAnalogLSBWeight"
*/
public static native int getAnalogLSBWeight(int analogPortHandle);
/**
* Gets the factory scaling offset constant. The offset constant for the channel that was
* calibrated in manufacturing and stored in an eeprom in the module.
*
* <p>Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
*
* @param analogPortHandle Handle to the analog port to use.
* @return Offset constant.
* @see "HAL_GetAnalogOffset"
*/
public static native int getAnalogOffset(int analogPortHandle);
/**
* Is the channel attached to an accumulator.
*
* @param analogPortHandle Handle to the analog port.
* @return The analog channel is attached to an accumulator.
* @see "HAL_IsAccumulatorChannel"
*/
public static native boolean isAccumulatorChannel(int analogPortHandle);
/**
* Initialize the accumulator.
*
* @param analogPortHandle Handle to the analog port.
* @see "HAL_InitAccumulator"
*/
public static native void initAccumulator(int analogPortHandle);
/**
* Resets the accumulator to the initial value.
*
* @param analogPortHandle Handle to the analog port.
* @see "HAL_ResetAccumulator"
*/
public static native void resetAccumulator(int analogPortHandle);
/**
* Set the center value of the accumulator.
*
* <p>The center value is subtracted from each A/D value before it is added to the accumulator.
* This is used for the center value of devices like gyros and accelerometers to make integration
* work and to take the device offset into account when integrating.
*
* <p>This center value is based on the output of the oversampled and averaged source from channel
* 1. Because of this, any non-zero oversample bits will affect the size of the value for this
* field.
*
* @param analogPortHandle Handle to the analog port.
* @param center The center value of the accumulator.
* @see "HAL_SetAccumulatorCenter"
*/
public static native void setAccumulatorCenter(int analogPortHandle, int center);
/**
* Set the accumulator's deadband.
*
* @param analogPortHandle Handle to the analog port.
* @param deadband The deadband of the accumulator.
* @see "HAL_SetAccumulatorDeadband"
*/
public static native void setAccumulatorDeadband(int analogPortHandle, int deadband);
/**
* Read the accumulated value.
*
* <p>Read the value that has been accumulating on channel 1. The accumulator is attached after
* the oversample and average engine.
*
* @param analogPortHandle Handle to the analog port.
* @return The 64-bit value accumulated since the last Reset().
* @see "HAL_GetAccumulatorValue"
*/
public static native long getAccumulatorValue(int analogPortHandle);
/**
* Read the number of accumulated values.
*
* <p>Read the count of the accumulated values since the accumulator was last Reset().
*
* @param analogPortHandle Handle to the analog port.
* @return The number of times samples from the channel were accumulated.
* @see "HAL_GetAccumulatorCount"
*/
public static native int getAccumulatorCount(int analogPortHandle);
/**
* Read the accumulated value and the number of accumulated values atomically.
*
* <p>This function reads the value and count from the FPGA atomically. This can be used for
* averaging.
*
* @param analogPortHandle Handle to the analog port.
* @param result Accumulator result.
* @see "HAL_GetAccumulatorOutput"
*/
public static native void getAccumulatorOutput(int analogPortHandle, AccumulatorResult result);
/**
* Initializes an analog trigger.
*
* @param analogInputHandle the analog input to use for triggering
* @return the created analog trigger handle
* @see "HAL_InitializeAnalogTrigger"
*/
public static native int initializeAnalogTrigger(int analogInputHandle);
/**
* Initializes an analog trigger with a Duty Cycle input.
*
* @param dutyCycleHandle the analog input to use for duty cycle
* @return tbe created analog trigger handle
* @see "HAL_InitializeAnalogTriggerDutyCycle"
*/
public static native int initializeAnalogTriggerDutyCycle(int dutyCycleHandle);
/**
* Frees an analog trigger.
*
* @param analogTriggerHandle the trigger handle
* @see "HAL_CleanAnalogTrigger"
*/
public static native void cleanAnalogTrigger(int analogTriggerHandle);
/**
* Sets the raw ADC upper and lower limits of the analog trigger.
*
* <p>HAL_SetAnalogTriggerLimitsVoltage or HAL_SetAnalogTriggerLimitsDutyCycle is likely better in
* most cases.
*
* @param analogTriggerHandle the trigger handle
* @param lower the lower ADC value
* @param upper the upper ADC value
* @see "HAL_SetAnalogTriggerLimitsRaw"
*/
public static native void setAnalogTriggerLimitsRaw(
int analogTriggerHandle, int lower, int upper);
/**
* Sets the upper and lower limits of the analog trigger.
*
* <p>The limits are given as floating point duty cycle values.
*
* @param analogTriggerHandle the trigger handle
* @param lower the lower duty cycle value
* @param higher the upper duty cycle value
* @see "HAL_SetAnalogTriggerLimitsDutyCycle"
*/
public static native void setAnalogTriggerLimitsDutyCycle(
int analogTriggerHandle, double lower, double higher);
/**
* Sets the upper and lower limits of the analog trigger.
*
* <p>The limits are given as floating point voltage values.
*
* @param analogTriggerHandle the trigger handle
* @param lower the lower voltage value
* @param upper the upper voltage value
* @see "HAL_SetAnalogTriggerLimitsVoltage"
*/
public static native void setAnalogTriggerLimitsVoltage(
int analogTriggerHandle, double lower, double upper);
/**
* Configures the analog trigger to use the averaged vs. raw values.
*
* <p>If the value is true, then the averaged value is selected for the analog trigger, otherwise
* the immediate value is used.
*
* <p>This is not allowed to be used if filtered mode is set. This is not allowed to be used with
* Duty Cycle based inputs.
*
* @param analogTriggerHandle the trigger handle
* @param useAveragedValue true to use averaged values, false for raw
* @see "HAL_SetAnalogTriggerAveraged"
*/
public static native void setAnalogTriggerAveraged(
int analogTriggerHandle, boolean useAveragedValue);
/**
* Configures the analog trigger to use a filtered value.
*
* <p>The analog trigger will operate with a 3 point average rejection filter. This is designed to
* help with 360 degree pot applications for the period where the pot crosses through zero.
*
* <p>This is not allowed to be used if averaged mode is set.
*
* @param analogTriggerHandle the trigger handle
* @param useFilteredValue true to use filtered values, false for average or raw
* @see "HAL_SetAnalogTriggerFiltered"
*/
public static native void setAnalogTriggerFiltered(
int analogTriggerHandle, boolean useFilteredValue);
/**
* Returns the InWindow output of the analog trigger.
*
* <p>True if the analog input is between the upper and lower limits.
*
* @param analogTriggerHandle the trigger handle
* @return the InWindow output of the analog trigger
* @see "HAL_GetAnalogTriggerInWindow"
*/
public static native boolean getAnalogTriggerInWindow(int analogTriggerHandle);
/**
* Returns the TriggerState output of the analog trigger.
*
* <p>True if above upper limit. False if below lower limit. If in Hysteresis, maintain previous
* state.
*
* @param analogTriggerHandle the trigger handle
* @return the TriggerState output of the analog trigger
* @see "HAL_GetAnalogTriggerTriggerState"
*/
public static native boolean getAnalogTriggerTriggerState(int analogTriggerHandle);
/**
* Gets the state of the analog trigger output.
*
* @param analogTriggerHandle the trigger handle
* @param type the type of trigger to trigger on
* @return the state of the analog trigger output
* @see "HAL_GetAnalogTriggerOutput"
*/
public static native boolean getAnalogTriggerOutput(int analogTriggerHandle, int type);
/**
* Get the FPGA index for the AnlogTrigger.
*
* @param analogTriggerHandle the trigger handle
* @return the FPGA index
* @see "HAL_GetAnalogTriggerFPGAIndex"
*/
public static native int getAnalogTriggerFPGAIndex(int analogTriggerHandle);
}

View File

@@ -4,31 +4,177 @@
package edu.wpi.first.hal;
/**
* CAN API HAL JNI Functions.
*
* @see "hal/CANAPI.h"
*/
public class CANAPIJNI extends JNIWrapper {
/**
* Reads the current value of the millisecond-resolution timer that the CAN API functions use as a
* time base.
*
* @return Current value of timer used as a base time by the CAN API in milliseconds.
* @see "HAL_GetCANPacketBaseTime"
*/
public static native long getCANPacketBaseTime();
/**
* Initializes a CAN device.
*
* <p>These follow the FIRST standard CAN layout.
* https://docs.wpilib.org/en/stable/docs/software/can-devices/can-addressing.html
*
* @param manufacturer the can manufacturer
* @param deviceId the device ID (0-63)
* @param deviceType the device type
* @return the created CAN handle
* @see "HAL_InitializeCAN"
*/
public static native int initializeCAN(int manufacturer, int deviceId, int deviceType);
/**
* Frees a CAN device.
*
* @param handle the CAN handle
* @see "HAL_CleanCAN"
*/
public static native void cleanCAN(int handle);
/**
* Writes a packet to the CAN device with a specific ID.
*
* <p>This ID is 10 bits.
*
* @param handle the CAN handle
* @param data the data to write (0-8 bytes)
* @param apiId the ID to write (0-1023 bits)
* @see "HAL_WriteCANPacket"
*/
public static native void writeCANPacket(int handle, byte[] data, int apiId);
/**
* Writes a repeating packet to the CAN device with a specific ID.
*
* <p>This ID is 10 bits.
*
* <p>The RoboRIO will automatically repeat the packet at the specified interval
*
* @param handle the CAN handle
* @param data the data to write (0-8 bytes)
* @param apiId the ID to write (0-1023)
* @param repeatMs the period to repeat in ms
* @see "HAL_WriteCANPacketRepeating"
*/
public static native void writeCANPacketRepeating(
int handle, byte[] data, int apiId, int repeatMs);
/**
* Writes an RTR frame of the specified length to the CAN device with the specific ID.
*
* <p>By spec, the length must be equal to the length sent by the other device, otherwise behavior
* is unspecified.
*
* @param handle the CAN handle
* @param length the length of data to request (0-8)
* @param apiId the ID to write (0-1023)
* @see "HAL_WriteCANRTRFrame"
*/
public static native void writeCANRTRFrame(int handle, int length, int apiId);
/**
* Writes a packet to the CAN device with a specific ID without throwing on error.
*
* <p>This ID is 10 bits.
*
* @param handle the CAN handle
* @param data the data to write (0-8 bytes)
* @param apiId the ID to write (0-1023 bits)
* @return Error status variable. 0 on success.
* @see "HAL_WriteCANPacket"
*/
public static native int writeCANPacketNoThrow(int handle, byte[] data, int apiId);
/**
* Writes a repeating packet to the CAN device with a specific ID without throwing on error.
*
* <p>This ID is 10 bits.
*
* <p>The RoboRIO will automatically repeat the packet at the specified interval
*
* @param handle the CAN handle
* @param data the data to write (0-8 bytes)
* @param apiId the ID to write (0-1023)
* @param repeatMs the period to repeat in ms
* @return Error status variable. 0 on success.
* @see "HAL_WriteCANPacketRepeating"
*/
public static native int writeCANPacketRepeatingNoThrow(
int handle, byte[] data, int apiId, int repeatMs);
/**
* Writes an RTR frame of the specified length to the CAN device with the specific ID without
* throwing on error.
*
* <p>By spec, the length must be equal to the length sent by the other device, otherwise behavior
* is unspecified.
*
* @param handle the CAN handle
* @param length the length of data to request (0-8)
* @param apiId the ID to write (0-1023)
* @return Error status variable. 0 on success.
* @see "HAL_WriteCANRTRFrame"
*/
public static native int writeCANRTRFrameNoThrow(int handle, int length, int apiId);
/**
* Stops a repeating packet with a specific ID.
*
* <p>This ID is 10 bits.
*
* @param handle the CAN handle
* @param apiId the ID to stop repeating (0-1023)
* @see "HAL_StopCANPacketRepeating"
*/
public static native void stopCANPacketRepeating(int handle, int apiId);
/**
* Reads a new CAN packet.
*
* <p>This will only return properly once per packet received. Multiple calls without receiving
* another packet will return false.
*
* @param handle the CAN handle
* @param apiId the ID to read (0-1023)
* @param data the packet data (8 bytes)
* @return true on success, false on error
* @see "HAL_ReadCANPacketNew"
*/
public static native boolean readCANPacketNew(int handle, int apiId, CANData data);
/**
* Reads a CAN packet. The will continuously return the last packet received, without accounting
* for packet age.
*
* @param handle the CAN handle
* @param apiId the ID to read (0-1023)
* @param data the packet data (8 bytes)
* @return true on success, false on error
* @see "HAL_ReadCANPacketLatest"
*/
public static native boolean readCANPacketLatest(int handle, int apiId, CANData data);
/**
* Reads a CAN packet. The will return the last packet received until the packet is older then the
* requested timeout. Then it will return false.
*
* @param handle the CAN handle
* @param apiId the ID to read (0-1023)
* @param timeoutMs the timeout time for the packet
* @param data the packet data (8 bytes)
* @return true on success, false on error
* @see "HAL_ReadCANPacketTimeout"
*/
public static native boolean readCANPacketTimeout(
int handle, int apiId, int timeoutMs, CANData data);
}

View File

@@ -6,16 +6,21 @@ package edu.wpi.first.hal;
@SuppressWarnings("MemberName")
public class CANData {
/** Contents of the CAN frame. */
public final byte[] data = new byte[8];
/** Length of the frame in bytes. */
public int length;
/** CAN frame timestamp in milliseconds. */
public long timestamp;
/**
* API used from JNI to set the data.
*
* @param length Length of packet in bytes.
* @param timestamp CAN frame timestamp in microseconds.
* @return Buffer containing CAN frame.
* @param timestamp CAN frame timestamp in milliseconds.
* @return Buffer to place CAN frame data in.
*/
@SuppressWarnings("PMD.MethodReturnsInternalArray")
public byte[] setData(int length, long timestamp) {

View File

@@ -4,48 +4,221 @@
package edu.wpi.first.hal;
/**
* CTRE Pneumatic Control Module (PCM) Functions.
*
* @see "CTREPCM.h"
*/
public class CTREPCMJNI extends JNIWrapper {
/**
* Initializes a PCM.
*
* @param module the CAN ID to initialize
* @return the created PH handle
* @see "HAL_InitializeCTREPCM"
*/
public static native int initialize(int module);
/**
* Frees a PCM handle.
*
* @param handle the PCMhandle
* @see "HAL_FreeCTREPCM"
*/
public static native void free(int handle);
/**
* Checks if a solenoid channel number is valid.
*
* @param channel the channel to check
* @return true if the channel is valid, otherwise false
*/
public static native boolean checkSolenoidChannel(int channel);
/**
* Get whether compressor is turned on.
*
* @param handle the PCM handle
* @return true if the compressor is turned on
* @see "HAL_GetCTREPCMCompressor"
*/
public static native boolean getCompressor(int handle);
/**
* Enables the compressor closed loop control using the digital pressure switch. The compressor
* will turn on when the pressure switch indicates that the system is not full, and will turn off
* when the pressure switch indicates that the system is full.
*
* @param handle the PCM handle
* @param enabled true to enable closed loop control
* @see "HAL_SetCTREPCMClosedLoopControl"
*/
public static native void setClosedLoopControl(int handle, boolean enabled);
/**
* Get whether the PCM closed loop control is enabled.
*
* @param handle the PCM handle
* @return True if closed loop control is enabled, otherwise false.
*/
public static native boolean getClosedLoopControl(int handle);
/**
* Returns the state of the pressure switch.
*
* @param handle the PCM handle
* @return True if pressure switch indicates that the system is full, otherwise false.
* @see "HAL_GetCTREPCMPressureSwitch"
*/
public static native boolean getPressureSwitch(int handle);
/**
* Returns the current drawn by the compressor.
*
* @param handle the PCM handle
* @return The current drawn by the compressor in amps.
* @see "HAL_GetCTREPCMCompressorCurrent"
*/
public static native double getCompressorCurrent(int handle);
/**
* Return whether the compressor current is currently too high.
*
* @param handle the PCM handle
* @return True if the compressor current is too high, otherwise false.
* @see getCompressorCurrentTooHighStickyFault
* @see "HAL_GetCTREPCMCompressorCurrentTooHighFault"
*/
public static native boolean getCompressorCurrentTooHighFault(int handle);
/**
* Returns whether the compressor current has been too high since sticky faults were last cleared.
* This fault is persistent and can be cleared by clearAllStickyFaults()
*
* @param handle the PCM handle
* @return True if the compressor current has been too high since sticky faults were last cleared.
* @see getCompressorCurrentTooHighFault
* @see "HAL_GetCTREPCMCompressorCurrentTooHighStickyFault("
*/
public static native boolean getCompressorCurrentTooHighStickyFault(int handle);
/**
* Returns whether the compressor is currently shorted.
*
* @param handle the PCM handle
* @return True if the compressor is currently shorted, otherwise false.
* @see getCompressorCurrentTooHighStickyFault
* @see "HAL_GetCTREPCMCompressorShortedStickyFault"
*/
public static native boolean getCompressorShortedFault(int handle);
/**
* Returns whether the compressor has been shorted since sticky faults were last cleared. This
* fault is persistent and can be cleared by clearAllStickyFaults()
*
* @param handle the PCM handle
* @return True if the compressor has been shorted since sticky faults were last cleared,
* otherwise false.
* @see getCompressorShortedFault
* @see "HAL_GetCTREPCMCompressorShortedFault"
*/
public static native boolean getCompressorShortedStickyFault(int handle);
/**
* Returns whether the compressor is currently disconnected.
*
* @param handle the PCM handle
* @return True if compressor is currently disconnected, otherwise false.
* @see getCompressorShortedStickyFault
* @see "HAL_GetCTREPCMCompressorNotConnectedFault"
*/
public static native boolean getCompressorNotConnectedFault(int handle);
/**
* Returns whether the compressor has been disconnected since sticky faults were last cleared.
* This fault is persistent and can be cleared by clearAllStickyFaults()
*
* @param handle the PCM handle
* @return True if the compressor has been disconnected since sticky faults were last cleared,
* otherwise false.
* @see getCompressorNotConnectedFault
* @see "HAL_GetCTREPCMCompressorNotConnectedStickyFault"
*/
public static native boolean getCompressorNotConnectedStickyFault(int handle);
/**
* Gets a bitmask of solenoid values.
*
* @param handle the PCM handle
* @return solenoid values
* @see "HAL_GetCTREPCMSolenoids"
*/
public static native int getSolenoids(int handle);
/**
* Sets solenoids on a pneumatics module.
*
* @param handle the PCM handle
* @param mask bitmask to set
* @param values solenoid values
* @see "HAL_SetCTREPCMSolenoids"
*/
public static native void setSolenoids(int handle, int mask, int values);
/**
* Get a bitmask of disabled solenoids.
*
* @param handle the PCM handle
* @return bitmask of disabled solenoids
* @see "HAL_GetCTREPCMSolenoidDisabledList"
*/
public static native int getSolenoidDisabledList(int handle);
/**
* Returns whether the solenoid is currently reporting a voltage fault.
*
* @param handle the PCM handle
* @return True if solenoid is reporting a fault, otherwise false.
* @see getSolenoidVoltageStickyFault
* @see "HAL_GetCTREPCMSolenoidVoltageFault"
*/
public static native boolean getSolenoidVoltageFault(int handle);
/**
* Returns whether the solenoid has reported a voltage fault since sticky faults were last
* cleared. This fault is persistent and can be cleared by clearAllStickyFaults()
*
* @param handle the PCM handle
* @return True if solenoid is reporting a fault, otherwise false.
* @see getSolenoidVoltageFault
* @see "HAL_GetCTREPCMSolenoidVoltageStickyFault"
*/
public static native boolean getSolenoidVoltageStickyFault(int handle);
/**
* Clears all sticky faults on this device.
*
* @param handle the PCM handle
* @see "HAL_ClearAllCTREPCMStickyFaults"
*/
public static native void clearAllStickyFaults(int handle);
/**
* Fire a single solenoid shot.
*
* @param handle the PCM handle
* @param index solenoid index
* @see "HAL_FireCTREPCMOneShot"
*/
public static native void fireOneShot(int handle, int index);
/**
* Set the duration for a single solenoid shot.
*
* @param handle the PCM handle
* @param index solenoid index
* @param durMs shot duration in ms
* @see "HAL_SetCTREPCMOneShotDuration"
*/
public static native void setOneShotDuration(int handle, int index, int durMs);
}

View File

@@ -4,6 +4,17 @@
package edu.wpi.first.hal;
/**
* Constants HAL JNI functions.
*
* @see "hal/Constants.h"
*/
public class ConstantsJNI extends JNIWrapper {
/**
* Gets the number of FPGA system clock ticks per microsecond.
*
* @return the number of clock ticks per microsecond
* @see "HAL_GetSystemClockTicksPerMicrosecond"
*/
public static native int getSystemClockTicksPerMicrosecond();
}

View File

@@ -6,59 +6,277 @@ package edu.wpi.first.hal;
import java.nio.IntBuffer;
/**
* Counter HAL JNI functions.
*
* @see "hal/Counter.h"
*/
public class CounterJNI extends JNIWrapper {
public static final int TWO_PULSE = 0;
public static final int SEMI_PERIOD = 1;
public static final int PULSE_LENGTH = 2;
public static final int EXTERNAL_DIRECTION = 3;
/**
* Initializes a counter.
*
* @param mode the counter mode
* @param index the compressor index (output)
* @return the created handle
* @see "HAL_InitializeCounter"
*/
public static native int initializeCounter(int mode, IntBuffer index);
/**
* Frees a counter.
*
* @param counterHandle the counter handle
* @see "HAL_FreeCounter"
*/
public static native void freeCounter(int counterHandle);
/**
* Sets the average sample size of a counter.
*
* @param counterHandle the counter handle
* @param size the size of samples to average
* @see "HAL_SetCounterAverageSize"
*/
public static native void setCounterAverageSize(int counterHandle, int size);
/**
* Sets the source object that causes the counter to count up.
*
* @param counterHandle the counter handle
* @param digitalSourceHandle the digital source handle (either a HAL_AnalogTriggerHandle or a
* HAL_DigitalHandle)
* @param analogTriggerType the analog trigger type if the source is an analog trigger
* @see "HAL_SetCounterUpSource"
*/
public static native void setCounterUpSource(
int counterHandle, int digitalSourceHandle, int analogTriggerType);
/**
* Sets the up source to either detect rising edges or falling edges.
*
* <p>Note that both are allowed to be set true at the same time without issues.
*
* @param counterHandle the counter handle
* @param risingEdge true to trigger on rising
* @param fallingEdge true to trigger on falling
* @see "HAL_SetCounterUpSourceEdge"
*/
public static native void setCounterUpSourceEdge(
int counterHandle, boolean risingEdge, boolean fallingEdge);
/**
* Disables the up counting source to the counter.
*
* @param counterHandle the counter handle
* @see "HAL_ClearCounterUpSource"
*/
public static native void clearCounterUpSource(int counterHandle);
/**
* Sets the source object that causes the counter to count down.
*
* @param counterHandle the counter handle
* @param digitalSourceHandle the digital source handle (either a HAL_AnalogTriggerHandle or a
* HAL_DigitalHandle)
* @param analogTriggerType the analog trigger type if the source is an analog trigger
* @see "HAL_SetCounterDownSource"
*/
public static native void setCounterDownSource(
int counterHandle, int digitalSourceHandle, int analogTriggerType);
/**
* Sets the down source to either detect rising edges or falling edges. Note that both are allowed
* to be set true at the same time without issues.
*
* @param counterHandle the counter handle
* @param risingEdge true to trigger on rising
* @param fallingEdge true to trigger on falling
* @see "HAL_SetCounterDownSourceEdge"
*/
public static native void setCounterDownSourceEdge(
int counterHandle, boolean risingEdge, boolean fallingEdge);
/**
* Disables the down counting source to the counter.
*
* @param counterHandle the counter handle
* @see "HAL_ClearCounterDownSource"
*/
public static native void clearCounterDownSource(int counterHandle);
/**
* Sets standard up / down counting mode on this counter.
*
* <p>Up and down counts are sourced independently from two inputs.
*
* @param counterHandle the counter handle
* @see "HAL_SetCounterUpDownMode"
*/
public static native void setCounterUpDownMode(int counterHandle);
/**
* Sets directional counting mode on this counter.
*
* <p>The direction is determined by the B input, with counting happening with the A input.
*
* @param counterHandle the counter handle
* @see "HAL_SetCounterExternalDirectionMode"
*/
public static native void setCounterExternalDirectionMode(int counterHandle);
/**
* Sets Semi-period mode on this counter.
*
* <p>The counter counts up based on the time the input is triggered. High or Low depends on the
* highSemiPeriod parameter.
*
* @param counterHandle the counter handle
* @param highSemiPeriod true for counting when the input is high, false for low
* @see "HAL_SetCounterSemiPeriodMode"
*/
public static native void setCounterSemiPeriodMode(int counterHandle, boolean highSemiPeriod);
/**
* Configures the counter to count in up or down based on the length of the input pulse.
*
* <p>This mode is most useful for direction sensitive gear tooth sensors.
*
* @param counterHandle the counter handle
* @param threshold The pulse length beyond which the counter counts the opposite direction
* (seconds)
* @see "HAL_SetCounterPulseLengthMode"
*/
public static native void setCounterPulseLengthMode(int counterHandle, double threshold);
/**
* Gets the Samples to Average which specifies the number of samples of the timer to average when
* calculating the period. Perform averaging to account for mechanical imperfections or as
* oversampling to increase resolution.
*
* @param counterHandle the counter handle
* @return SamplesToAverage The number of samples being averaged (from 1 to 127)
* @see "HAL_GetCounterSamplesToAverage"
*/
public static native int getCounterSamplesToAverage(int counterHandle);
/**
* Sets the Samples to Average which specifies the number of samples of the timer to average when
* calculating the period. Perform averaging to account for mechanical imperfections or as
* oversampling to increase resolution.
*
* @param counterHandle the counter handle
* @param samplesToAverage The number of samples to average from 1 to 127
* @see "HAL_SetCounterSamplesToAverage"
*/
public static native void setCounterSamplesToAverage(int counterHandle, int samplesToAverage);
/**
* Resets the Counter to zero.
*
* <p>Sets the counter value to zero. This does not effect the running state of the counter, just
* sets the current value to zero.
*
* @param counterHandle the counter handle
* @see "HAL_ResetCounter"
*/
public static native void resetCounter(int counterHandle);
/**
* Reads the current counter value.
*
* <p>Reads the value at this instant. It may still be running, so it reflects the current value.
* Next time it is read, it might have a different value.
*
* @param counterHandle the counter handle
* @return the current counter value
* @see "HAL_GetCounter"
*/
public static native int getCounter(int counterHandle);
/**
* Gets the Period of the most recent count.
*
* <p>Returns the time interval of the most recent count. This can be used for velocity
* calculations to determine shaft speed.
*
* @param counterHandle the counter handle
* @return the period of the last two pulses in units of seconds
* @see "HAL_GetCounterPeriod"
*/
public static native double getCounterPeriod(int counterHandle);
/**
* Sets the maximum period where the device is still considered "moving".
*
* <p>Sets the maximum period where the device is considered moving. This value is used to
* determine the "stopped" state of the counter using the HAL_GetCounterStopped method.
*
* @param counterHandle the counter handle
* @param maxPeriod the maximum period where the counted device is considered moving in seconds
* @see "HAL_SetCounterMaxPeriod"
*/
public static native void setCounterMaxPeriod(int counterHandle, double maxPeriod);
/**
* Selects whether you want to continue updating the event timer output when there are no samples
* captured.
*
* <p>The output of the event timer has a buffer of periods that are averaged and posted to a
* register on the FPGA. When the timer detects that the event source has stopped (based on the
* MaxPeriod) the buffer of samples to be averaged is emptied.
*
* <p>If you enable the update when empty, you will be notified of the stopped source and the
* event time will report 0 samples.
*
* <p>If you disable update when empty, the most recent average will remain on the output until a
* new sample is acquired.
*
* <p>You will never see 0 samples output (except when there have been no events since an FPGA
* reset) and you will likely not see the stopped bit become true (since it is updated at the end
* of an average and there are no samples to average).
*
* @param counterHandle the counter handle
* @param enabled true to enable counter updating with no samples
* @see "HAL_SetCounterUpdateWhenEmpty"
*/
public static native void setCounterUpdateWhenEmpty(int counterHandle, boolean enabled);
/**
* Determines if the clock is stopped.
*
* <p>Determine if the clocked input is stopped based on the MaxPeriod value set using the
* SetMaxPeriod method. If the clock exceeds the MaxPeriod, then the device (and counter) are
* assumed to be stopped and it returns true.
*
* @param counterHandle the counter handle
* @return true if the most recent counter period exceeds the MaxPeriod value set by SetMaxPeriod
* @see "HAL_GetCounterStopped"
*/
public static native boolean getCounterStopped(int counterHandle);
/**
* Gets the last direction the counter value changed.
*
* @param counterHandle the counter handle
* @return the last direction the counter value changed
* @see "HAL_GetCounterDirection"
*/
public static native boolean getCounterDirection(int counterHandle);
/**
* Sets the Counter to return reversed sensing on the direction.
*
* <p>This allows counters to change the direction they are counting in the case of 1X and 2X
* quadrature encoding only. Any other counter mode isn't supported.
*
* @param counterHandle the counter handle
* @param reverseDirection true if the value counted should be negated.
* @see "HAL_SetCounterReverseDirection"
*/
public static native void setCounterReverseDirection(int counterHandle, boolean reverseDirection);
}

View File

@@ -4,42 +4,178 @@
package edu.wpi.first.hal;
/**
* Digital Input/Output (IO) JNI Functions.
*
* @see "hal/DIO.h"
*/
public class DIOJNI extends JNIWrapper {
/**
* Creates a new instance of a digital port.
*
* @param halPortHandle the port handle to create from
* @param input true for input, false for output
* @return the created digital handle
* @see "HAL_InitializeDIOPort"
*/
public static native int initializeDIOPort(int halPortHandle, boolean input);
/**
* Checks if a DIO channel is valid.
*
* @param channel the channel number to check
* @return true if the channel is valid, otherwise false
* @see "HAL_CheckDIOChannel"
*/
public static native boolean checkDIOChannel(int channel);
/**
* Frees a DIO port.
*
* @param dioPortHandle the DIO channel handle
* @see "HAL_FreeDIOPort"
*/
public static native void freeDIOPort(int dioPortHandle);
/**
* Indicates the DIO channel is used by a simulated device.
*
* @param handle the DIO channel handle
* @param device simulated device handle
* @see "HAL_SetDIOSimDevice"
*/
public static native void setDIOSimDevice(int handle, int device);
/**
* Writes a digital value to a DIO channel.
*
* @param dioPortHandle the digital port handle
* @param value the state to set the digital channel (if it is configured as an output)
* @see "HAL_SetDIO"
*/
public static native void setDIO(int dioPortHandle, boolean value);
/**
* Sets the direction of a DIO channel.
*
* @param dioPortHandle the digital port handle
* @param input true to set input, false for output
* @see "HAL_SetDIODirection"
*/
public static native void setDIODirection(int dioPortHandle, boolean input);
/**
* Reads a digital value from a DIO channel.
*
* @param dioPortHandle the digital port handle
* @return the state of the specified channel
* @see "HAL_GetDIO"
*/
public static native boolean getDIO(int dioPortHandle);
/**
* Reads the direction of a DIO channel.
*
* @param dioPortHandle the digital port handle
* @return true for input, false for output
* @see "HAL_GetDIODirection"
*/
public static native boolean getDIODirection(int dioPortHandle);
/**
* Generates a single digital pulse.
*
* <p>Write a pulse to the specified digital output channel. There can only be a single pulse
* going at any time.
*
* @param dioPortHandle the digital port handle
* @param pulseLengthSeconds the active length of the pulse (in seconds)
* @see "HAL_Pulse"
*/
public static native void pulse(int dioPortHandle, double pulseLengthSeconds);
/**
* Generates a single digital pulse on multiple channels.
*
* <p>Write a pulse to the channels enabled by the mask. There can only be a single pulse going at
* any time.
*
* @param channelMask the channel mask
* @param pulseLengthSeconds the active length of the pulse (in seconds)
* @see "HAL_PulseMultiple"
*/
public static native void pulseMultiple(long channelMask, double pulseLengthSeconds);
/**
* Checks a DIO line to see if it is currently generating a pulse.
*
* @param dioPortHandle the digital port handle
* @return true if a pulse is in progress, otherwise false
* @see "HAL_IsPulsing"
*/
public static native boolean isPulsing(int dioPortHandle);
/**
* Checks if any DIO line is currently generating a pulse.
*
* @return true if a pulse on some line is in progress
* @see "HAL_IsAnyPulsing"
*/
public static native boolean isAnyPulsing();
public static native short getLoopTiming();
/**
* Allocates a DO PWM Generator.
*
* @return the allocated digital PWM handle
*/
public static native int allocateDigitalPWM();
/**
* Frees the resource associated with a DO PWM generator.
*
* @param pwmGenerator the digital PWM handle
* @see "HAL_FreeDigitalPWM"
*/
public static native void freeDigitalPWM(int pwmGenerator);
/**
* Changes the frequency of the DO PWM generator.
*
* <p>The valid range is from 0.6 Hz to 19 kHz.
*
* <p>The frequency resolution is logarithmic.
*
* @param rate the frequency to output all digital output PWM signals
* @see "HAL_SetDigitalPWMRate"
*/
public static native void setDigitalPWMRate(double rate);
/**
* Configures the duty-cycle of the PWM generator.
*
* @param pwmGenerator the digital PWM handle
* @param dutyCycle the percent duty cycle to output [0..1]
* @see "HAL_SetDigitalPWMDutyCycle"
*/
public static native void setDigitalPWMDutyCycle(int pwmGenerator, double dutyCycle);
/**
* Configures the digital PWM to be a PPS signal with specified duty cycle.
*
* @param pwmGenerator the digital PWM handle
* @param dutyCycle the percent duty cycle to output [0..1]
* @see "HAL_SetDigitalPWMPPS"
*/
public static native void setDigitalPWMPPS(int pwmGenerator, double dutyCycle);
/**
* Configures which DO channel the PWM signal is output on.
*
* @param pwmGenerator the digital PWM handle
* @param channel the channel to output on
* @see "HAL_SetDigitalPWMOutputChannel"
*/
public static native void setDigitalPWMOutputChannel(int pwmGenerator, int channel);
}

View File

@@ -4,53 +4,245 @@
package edu.wpi.first.hal;
/**
* DMA HAL JNI functions.
*
* @see "hal/DHA.h"
*/
public class DMAJNI extends JNIWrapper {
/**
* Initializes an object for performing DMA transfers.
*
* @return the created dma handle
* @see "HAL_InitializeDMA"
*/
public static native int initialize();
/**
* Frees a DMA object.
*
* @param handle the dma handle
* @see "HAL_FreeDMA"
*/
public static native void free(int handle);
/**
* Pauses or unpauses a DMA transfer.
*
* <p>This can only be called while DMA is running.
*
* @param handle the dma handle
* @param pause true to pause transfers, false to resume.
* @see "HAL_SetDMAPause"
*/
public static native void setPause(int handle, boolean pause);
/**
* Sets DMA transfers to occur at a specific timed interval.
*
* <p>This will remove any external triggers. Only timed or external is supported.
*
* <p>Only 1 timed period is supported.
*
* <p>This can only be called if DMA is not started.
*
* @param handle the dma handle
* @param periodSeconds the period to trigger in seconds
* @see "HAL_SetDMATimedTrigger"
*/
public static native void setTimedTrigger(int handle, double periodSeconds);
/**
* Sets DMA transfers to occur at a specific timed interval in FPGA cycles.
*
* <p>This will remove any external triggers. Only timed or external is supported.
*
* <p>Only 1 timed period is supported
*
* <p>The FPGA currently runs at 40 MHz, but this can change.
* HAL_GetSystemClockTicksPerMicrosecond can be used to get a computable value for this.
*
* <p>This can only be called if DMA is not started.
*
* @param handle the dma handle
* @param cycles the period to trigger in FPGA cycles
* @see "HAL_SetDMATimedTriggerCycles"
*/
public static native void setTimedTriggerCycles(int handle, int cycles);
/**
* Adds position data for an encoder to be collected by DMA.
*
* <p>This can only be called if DMA is not started.
*
* @param handle the dma handle
* @param encoderHandle the encoder to add
* @see "HAL_AddDMAEncoder"
*/
public static native void addEncoder(int handle, int encoderHandle);
/**
* Adds timer data for an encoder to be collected by DMA.
*
* <p>This can only be called if DMA is not started.
*
* @param handle the dma handle
* @param encoderHandle the encoder to add
* @see "HAL_AddDMAEncoderPeriod"
*/
public static native void addEncoderPeriod(int handle, int encoderHandle);
/**
* Adds position data for an counter to be collected by DMA.
*
* <p>This can only be called if DMA is not started.
*
* @param handle the dma handle
* @param counterHandle the counter to add
* @see "HAL_AddDMACounter"
*/
public static native void addCounter(int handle, int counterHandle);
/**
* Adds timer data for an counter to be collected by DMA.
*
* @param handle the dma handle
* @param counterHandle the counter to add
* @see "HAL_AddDMACounterPeriod"
*/
public static native void addCounterPeriod(int handle, int counterHandle);
/**
* Adds a digital source to be collected by DMA.
*
* <p>This can only be called if DMA is not started.
*
* @param handle the dma handle
* @param digitalSourceHandle the digital source to add
* @see "HAL_AddDMADigitalSource"
*/
public static native void addDigitalSource(int handle, int digitalSourceHandle);
/**
* Adds a duty cycle input to be collected by DMA.
*
* <p>This can only be called if DMA is not started.
*
* @param handle the dma handle
* @param dutyCycleHandle the duty cycle input to add
* @see "HAL_AddDMADutyCycle"
*/
public static native void addDutyCycle(int handle, int dutyCycleHandle);
/**
* Adds an analog input to be collected by DMA.
*
* <p>This can only be called if DMA is not started.
*
* @param handle the dma handle
* @param analogInputHandle the analog input to add
* @see "HAL_AddDMAAnalogInput"
*/
public static native void addAnalogInput(int handle, int analogInputHandle);
/**
* Adds averaged data of an analog input to be collected by DMA.
*
* <p>This can only be called if DMA is not started.
*
* @param handle the dma handle
* @param analogInputHandle the analog input to add
* @see "HAL_AddDMAAveragedAnalogInput"
*/
public static native void addAveragedAnalogInput(int handle, int analogInputHandle);
/**
* Adds accumulator data of an analog input to be collected by DMA.
*
* <p>This can only be called if DMA is not started.
*
* @param handle the dma handle
* @param analogInputHandle the analog input to add
* @see "HAL_AddDMAAnalogAccumulator"
*/
public static native void addAnalogAccumulator(int handle, int analogInputHandle);
/**
* Sets DMA transfers to occur on an external trigger.
*
* <p>This will remove any timed trigger set. Only timed or external is supported.
*
* <p>Up to 8 external triggers are currently supported.
*
* <p>This can only be called if DMA is not started.
*
* @param handle the dma handle
* @param digitalSourceHandle the digital source handle (either a HAL_AnalogTriggerHandle or a
* HAL_DigitalHandle)
* @param analogTriggerType the analog trigger type if the source is an analog trigger
* @param rising true to trigger on rising edge
* @param falling true to trigger on falling edge
* @return the index of the trigger
* @see "HAL_SetDMAExternalTrigger"
*/
public static native int setExternalTrigger(
int handle, int digitalSourceHandle, int analogTriggerType, boolean rising, boolean falling);
/**
* Clear all sensors from the DMA collection list.
*
* <p>This can only be called if DMA is not started.
*
* @param handle the dma handle
* @see "HAL_ClearDMASensors"
*/
public static native void clearSensors(int handle);
/**
* Clear all external triggers from the DMA trigger list.
*
* <p>This can only be called if DMA is not started.
*
* @param handle the dma handle
* @see "HAL_ClearDMAExternalTriggers"
*/
public static native void clearExternalTriggers(int handle);
/**
* Starts DMA Collection.
*
* @param handle the dma handle
* @param queueDepth the number of objects to be able to queue
* @see "HAL_StartDMA"
*/
public static native void startDMA(int handle, int queueDepth);
/**
* Stops DMA Collection.
*
* @param handle the dma handle
* @see "HAL_StopDMA"
*/
public static native void stopDMA(int handle);
// 0-21 channelOffsets
// 22: capture size
// 23: triggerChannels (bitflags)
// 24: remaining
// 25: read status
/**
* Reads a DMA sample from the queue.
*
* @param handle the dma handle
* @param timeoutSeconds the time to wait for data to be queued before timing out
* @param buffer the sample object to place data into
* @param sampleStore index 0-21 channelOffsets, index 22: capture size, index 23: triggerChannels
* (bitflags), index 24: remaining, index 25: read status
* @return timestamp of the DMA Sample
*/
public static native long readDMA(
int handle, double timeoutSeconds, int[] buffer, int[] sampleStore);
/**
* Get the sensor DMA sample.
*
* @param handle the dma handle
* @return The DMA sample
*/
public static native DMAJNISample.BaseStore getSensorReadData(int handle);
}

View File

@@ -4,12 +4,59 @@
package edu.wpi.first.hal;
/**
* Digital Glitch Filter JNI functions.
*
* @see "hal/DIO.h"
*/
public class DigitalGlitchFilterJNI extends JNIWrapper {
/**
* Writes the filter index from the FPGA.
*
* <p>Set the filter index used to filter out short pulses.
*
* @param digitalPortHandle the digital port handle
* @param filterIndex the filter index (Must be in the range 0 - 3, where 0 means "none" and 1 - 3
* means filter # filterIndex - 1)
* @see "HAL_SetFilterSelect"
*/
public static native void setFilterSelect(int digitalPortHandle, int filterIndex);
/**
* Reads the filter index from the FPGA.
*
* <p>Gets the filter index used to filter out short pulses.
*
* @param digitalPortHandle the digital port handle
* @return the filter index (Must be in the range 0 - 3, where 0 means "none" and 1 - 3 means
* filter # filterIndex - 1)
* @see "HAL_GetFilterSelect"
*/
public static native int getFilterSelect(int digitalPortHandle);
/**
* Sets the filter period for the specified filter index.
*
* <p>Sets the filter period in FPGA cycles. Even though there are 2 different filter index
* domains (MXP vs HDR), ignore that distinction for now since it complicates the interface. That
* can be changed later.
*
* @param filterIndex the filter index, 0 - 2
* @param fpgaCycles the number of cycles that the signal must not transition to be counted as a
* transition.
* @see "HAL_SetFilterPeriod"
*/
public static native void setFilterPeriod(int filterIndex, int fpgaCycles);
/**
* Gets the filter period for the specified filter index.
*
* <p>Gets the filter period in FPGA cycles. Even though there are 2 different filter index
* domains (MXP vs HDR), ignore that distinction for now since it complicates the interface.
*
* @param filterIndex the filter index, 0 - 2
* @return The number of FPGA cycles of the filter period.
* @see "HAL_GetFilterPeriod"
*/
public static native int getFilterPeriod(int filterIndex);
}

View File

@@ -6,21 +6,88 @@ package edu.wpi.first.hal;
import java.nio.ByteBuffer;
/**
* Driver Station JNI Functions.
*
* @see "hal/DriverStation.h"
* @see "hal/FRCUsageReporting.h"
*/
public class DriverStationJNI extends JNIWrapper {
/**
* Sets the program starting flag in the DS.
*
* <p>This is what changes the DS to showing robot code ready.
*
* @see "HAL_ObserveUserProgramStarting"
*/
public static native void observeUserProgramStarting();
/**
* Sets the disabled flag in the DS.
*
* <p>This is used for the DS to ensure the robot is properly responding to its state request.
* Ensure this gets called about every 50ms, or the robot will be disabled by the DS.
*
* @see "HAL_ObserveUserProgramDisabled"
*/
public static native void observeUserProgramDisabled();
/**
* Sets the autonomous enabled flag in the DS.
*
* <p>This is used for the DS to ensure the robot is properly responding to its state request.
* Ensure this gets called about every 50ms, or the robot will be disabled by the DS.
*
* @see "HAL_ObserveUserProgramAutonomous"
*/
public static native void observeUserProgramAutonomous();
/**
* Sets the teleoperated enabled flag in the DS.
*
* <p>This is used for the DS to ensure the robot is properly responding to its state request.
* Ensure this gets called about every 50ms, or the robot will be disabled by the DS.
*
* @see "HAL_ObserveUserProgramTeleop"
*/
public static native void observeUserProgramTeleop();
/**
* Sets the test mode flag in the DS.
*
* <p>This is used for the DS to ensure the robot is properly responding to its state request.
* Ensure this gets called about every 50ms, or the robot will be disabled by the DS.
*
* @see "HAL_ObserveUserProgramTest"
*/
public static native void observeUserProgramTest();
/**
* Report the usage of a resource of interest.
*
* <p>Original signature: <code>uint32_t report(tResourceType, uint8_t, uint8_t, const
* char*)</code>
*
* @param resource one of the values in the tResourceType above.
* @param instanceNumber an index that identifies the resource instance.
* @see "HAL_Report"
*/
public static void report(int resource, int instanceNumber) {
report(resource, instanceNumber, 0, "");
}
/**
* Report the usage of a resource of interest.
*
* <p>Original signature: <code>uint32_t report(tResourceType, uint8_t, uint8_t, const
* char*)</code>
*
* @param resource one of the values in the tResourceType above.
* @param instanceNumber an index that identifies the resource instance.
* @param context an optional additional context number for some cases (such as module number).
* Set to 0 to omit.
* @see "HAL_Report"
*/
public static void report(int resource, int instanceNumber, int context) {
report(resource, instanceNumber, context, "");
}
@@ -31,19 +98,36 @@ public class DriverStationJNI extends JNIWrapper {
* <p>Original signature: <code>uint32_t report(tResourceType, uint8_t, uint8_t, const
* char*)</code>
*
* @param resource one of the values in the tResourceType above (max value 51).
* @param resource one of the values in the tResourceType above.
* @param instanceNumber an index that identifies the resource instance.
* @param context an optional additional context number for some cases (such as module number).
* Set to 0 to omit.
* @param feature a string to be included describing features in use on a specific resource.
* Setting the same resource more than once allows you to change the feature string.
* @return TODO
* @return the index of the added value in NetComm
* @see "HAL_Report"
*/
public static native int report(int resource, int instanceNumber, int context, String feature);
/**
* Gets the current control word of the driver station.
*
* <p>The control word contains the robot state.
*
* @return the control word
* @see "HAL_GetControlWord"
* @see getControlWord for a version easier to parse
*/
public static native int nativeGetControlWord();
@SuppressWarnings("MissingJavadocMethod")
/**
* Gets the current control word of the driver station.
*
* <p>The control work contains the robot state.
*
* @param controlWord the ControlWord to update
* @see "HAL_GetControlWord"
*/
public static void getControlWord(ControlWord controlWord) {
int word = nativeGetControlWord();
controlWord.update(
@@ -55,18 +139,32 @@ public class DriverStationJNI extends JNIWrapper {
((word >> 5) & 1) != 0);
}
/**
* Gets the current alliance station ID.
*
* @return the alliance station ID int
* @see "HAL_GetAllianceStation"
*/
private static native int nativeGetAllianceStation();
public static final int kRed1AllianceStation = 0;
public static final int kRed2AllianceStation = 1;
public static final int kRed3AllianceStation = 2;
public static final int kBlue1AllianceStation = 3;
public static final int kBlue2AllianceStation = 4;
public static final int kBlue3AllianceStation = 5;
public static final int kUnknownAllianceStation = 0;
public static final int kRed1AllianceStation = 1;
public static final int kRed2AllianceStation = 2;
public static final int kRed3AllianceStation = 3;
public static final int kBlue1AllianceStation = 4;
public static final int kBlue2AllianceStation = 5;
public static final int kBlue3AllianceStation = 6;
@SuppressWarnings("MissingJavadocMethod")
/**
* Gets the current alliance station ID.
*
* @return the alliance station ID as AllianceStationID
* @see "HAL_GetAllianceStation"
*/
public static AllianceStationID getAllianceStation() {
switch (nativeGetAllianceStation()) {
case kUnknownAllianceStation:
return AllianceStationID.Unknown;
case kRed1AllianceStation:
return AllianceStationID.Red1;
case kRed2AllianceStation:
@@ -88,32 +186,156 @@ public class DriverStationJNI extends JNIWrapper {
public static final int kMaxJoystickPOVs = 12;
public static final int kMaxJoysticks = 6;
/**
* Gets the axes of a specific joystick.
*
* @param joystickNum the joystick number
* @param axesArray the axes values
* @return number of joystick axes, or 0 for error
* @see "HAL_GetJoystickAxes"
*/
public static native int getJoystickAxes(byte joystickNum, float[] axesArray);
/**
* Gets the axes of a specific joystick.
*
* @param joystickNum the joystick number
* @param rawAxesArray the raw int axes values (0-255)
* @return number of joystick axes, or 0 for error
* @see "HAL_GetJoystickAxes"
*/
public static native int getJoystickAxesRaw(byte joystickNum, int[] rawAxesArray);
/**
* Gets the POVs of a specific joystick.
*
* @param joystickNum the joystick number
* @param povsArray the POV values
* @return number of POVs, or 0 for error
* @see "HAL_GetJoystickPOVs"
*/
public static native int getJoystickPOVs(byte joystickNum, short[] povsArray);
/**
* Gets the buttons of a specific joystick.
*
* @param joystickNum the joystick number
* @param count the count of buttons
* @return The joystick button values
* @see "HAL_GetJoystickButtons"
*/
public static native int getJoystickButtons(byte joystickNum, ByteBuffer count);
/**
* Get all joystick data.
*
* @param axesArray all joystick axes
* @param rawAxesArray all joystick axes as int
* @param povsArray all povs
* @param buttonsAndMetadata array of long joystick axes count, long joystick povs count, long
* jostick buttons count, long joystick buttons values
* @see "HAL_GetAllJoystickData"
*/
public static native void getAllJoystickData(
float[] axesArray, byte[] rawAxesArray, short[] povsArray, long[] buttonsAndMetadata);
/**
* Set joystick outputs.
*
* @param joystickNum the joystick number
* @param outputs bitmask of outputs, 1 for on 0 for off
* @param leftRumble the left rumble value (0-FFFF)
* @param rightRumble the right rumble value (0-FFFF)
* @return the error code, or 0 for success
* @see "HAL_SetJoystickOutputs"
*/
public static native int setJoystickOutputs(
byte joystickNum, int outputs, short leftRumble, short rightRumble);
/**
* Gets whether a specific joystick is considered to be an XBox controller.
*
* @param joystickNum the joystick number
* @return 1 if xbox, 0 otherwise
* @see "HAL_GetJoystickIsXbox"
*/
public static native int getJoystickIsXbox(byte joystickNum);
/**
* Gets the type of joystick connected.
*
* <p>This is device specific, and different depending on what system input type the joystick
* uses.
*
* @param joystickNum the joystick number
* @return the enumerated joystick type
* @see "HAL_GetJoystickType"
*/
public static native int getJoystickType(byte joystickNum);
/**
* Gets the name of a joystick.
*
* <p>The returned array must be freed with HAL_FreeJoystickName.
*
* @param joystickNum the joystick number
* @return the joystick name
* @see "HAL_GetJoystickName"
*/
public static native String getJoystickName(byte joystickNum);
/**
* Gets the type of a specific joystick axis.
*
* <p>This is device specific, and different depending on what system input type the joystick
* uses.
*
* @param joystickNum the joystick number
* @param axis the axis number
* @return the enumerated axis type
* @see "HAL_GetJoystickAxisType"
*/
public static native int getJoystickAxisType(byte joystickNum, byte axis);
/**
* Returns the approximate match time.
*
* <p>The FMS does not send an official match time to the robots, but does send an approximate
* match time. The value will count down the time remaining in the current period (auto or
* teleop).
*
* <p>Warning: This is not an official time (so it cannot be used to dispute ref calls or
* guarantee that a function will trigger before the match ends).
*
* <p>The Practice Match function of the DS approximates the behavior seen on the field.
*
* @return time remaining in current match period (auto or teleop)
* @see "HAL_GetMatchTime"
*/
public static native double getMatchTime();
/**
* Gets info about a specific match.
*
* @param info the match info to populate
* @return the error code, or 0 for success
* @see "HAL_GetMatchInfo"
*/
public static native int getMatchInfo(MatchInfoData info);
/**
* Sends an error to the driver station.
*
* @param isError true for error, false for warning
* @param errorCode the error code
* @param isLVCode true for a LV error code, false for a standard error code
* @param details the details of the error
* @param location the file location of the error
* @param callStack the callstack of the error
* @param printMsg true to print the error message to stdout as well as to the DS
* @return the error code, or 0 for success
* @see "HAL_SendError"
*/
public static native int sendError(
boolean isError,
int errorCode,
@@ -123,14 +345,31 @@ public class DriverStationJNI extends JNIWrapper {
String callStack,
boolean printMsg);
/**
* Sends a line to the driver station console.
*
* @param line the line to send
* @return the error code, or 0 for success
*/
public static native int sendConsoleLine(String line);
/**
* Refresh the DS control word.
*
* @return true if updated
* @see "HAL_RefreshDSData"
*/
public static native boolean refreshDSData();
public static native void provideNewDataEventHandle(int handle);
public static native void removeNewDataEventHandle(int handle);
/**
* Gets if outputs are enabled by the control system.
*
* @return true if outputs are enabled
*/
public static native boolean getOutputsActive();
private DriverStationJNI() {}

View File

@@ -4,18 +4,78 @@
package edu.wpi.first.hal;
/**
* DutyCycle HAL JNI functions.
*
* @see "DutyCycle.h"
*/
public class DutyCycleJNI extends JNIWrapper {
/**
* Initialize a DutyCycle input.
*
* @param digitalSourceHandle the digital source to use (either a Digital Handle or a
* AnalogTrigger Handle)
* @param analogTriggerType the analog trigger type of the source if it is an analog trigger
* @return the created duty cycle handle
* @see "HAL_InitializeDutyCycle"
*/
public static native int initialize(int digitalSourceHandle, int analogTriggerType);
/**
* Free a DutyCycle.
*
* @param handle the duty cycle handle
* @see "HAL_FreeDutyCycle"
*/
public static native void free(int handle);
/**
* Get the frequency of the duty cycle signal.
*
* @param handle the duty cycle handle
* @return frequency in Hertz
* @see "HAL_GetDutyCycleFrequency"
*/
public static native int getFrequency(int handle);
/**
* Get the output ratio of the duty cycle signal.
*
* <p>0 means always low, 1 means always high.
*
* @param handle the duty cycle handle
* @return output ratio between 0 and 1
* @see "HAL_GetDutyCycleOutput"
*/
public static native double getOutput(int handle);
/**
* Get the raw high time of the duty cycle signal.
*
* @param handle the duty cycle handle
* @return high time of last pulse in nanoseconds
* @see "HAL_GetDutyCycleHighTime"
*/
public static native int getHighTime(int handle);
/**
* Get the scale factor of the output.
*
* <p>An output equal to this value is always high, and then linearly scales down to 0. Divide a
* raw result by this in order to get the percentage between 0 and 1. Used by DMA.
*
* @param handle the duty cycle handle
* @return the output scale factor
* @see "HAL_GetDutyCycleOutputScaleFactor"
*/
public static native int getOutputScaleFactor(int handle);
/**
* Get the FPGA index for the DutyCycle.
*
* @param handle the duty cycle handle
* @return the FPGA index
* @see "HAL_GetDutyCycleFPGAIndex"
*/
public static native int getFPGAIndex(int handle);
}

View File

@@ -4,7 +4,24 @@
package edu.wpi.first.hal;
/**
* Encoder JNI Functions.
*
* @see "hal/Encoder.h"
*/
public class EncoderJNI extends JNIWrapper {
/**
* Initializes an encoder.
*
* @param digitalSourceHandleA the A source handle (either a digital or analog trigger)
* @param analogTriggerTypeA the analog trigger type of the A source if it is an analog trigger
* @param digitalSourceHandleB the B source handle (either a digital or analog trigger)
* @param analogTriggerTypeB the analog trigger type of the B source if it is an analog trigger
* @param reverseDirection true to reverse the counting direction from standard, otherwise false
* @param encodingType the encoding type
* @return the created encoder handle
* @see "HAL_InitializeEncoder"
*/
public static native int initializeEncoder(
int digitalSourceHandleA,
int analogTriggerTypeA,
@@ -13,50 +30,249 @@ public class EncoderJNI extends JNIWrapper {
boolean reverseDirection,
int encodingType);
/**
* Frees an encoder.
*
* @param encoderHandle the encoder handle
* @see "HAL_FreeEncoder"
*/
public static native void freeEncoder(int encoderHandle);
/**
* Indicates the encoder is used by a simulated device.
*
* @param handle the encoder handle
* @param device simulated device handle
* @see "HAL_SetEncoderSimDevice"
*/
public static native void setEncoderSimDevice(int handle, int device);
/**
* Gets the current counts of the encoder after encoding type scaling.
*
* <p>This is scaled by the value passed during initialization to encodingType.
*
* @param encoderHandle the encoder handle
* @return the current scaled count
* @see "HAL_GetEncoder"
*/
public static native int getEncoder(int encoderHandle);
/**
* Gets the raw counts of the encoder.
*
* <p>This is not scaled by any values.
*
* @param encoderHandle the encoder handle
* @return the raw encoder count
* @see "HAL_GetEncoderRaw"
*/
public static native int getEncoderRaw(int encoderHandle);
/**
* Gets the encoder scale value.
*
* <p>This is set by the value passed during initialization to encodingType.
*
* @param encoderHandle the encoder handle
* @return the encoder scale value
* @see "HAL_GetEncoderEncodingScale"
*/
public static native int getEncodingScaleFactor(int encoderHandle);
/**
* Reads the current encoder value.
*
* <p>Read the value at this instant. It may still be running, so it reflects the current value.
* Next time it is read, it might have a different value.
*
* @param encoderHandle the encoder handle
* @see "HAL_ResetEncoder"
*/
public static native void resetEncoder(int encoderHandle);
/**
* Gets the Period of the most recent count.
*
* <p>Returns the time interval of the most recent count. This can be used for velocity
* calculations to determine shaft speed.
*
* @param encoderHandle the encoder handle
* @return the period of the last two pulses in units of seconds
* @see "HAL_GetEncoderPeriod"
*/
public static native double getEncoderPeriod(int encoderHandle);
/**
* Sets the maximum period where the device is still considered "moving".
*
* <p>Sets the maximum period where the device is considered moving. This value is used to
* determine the "stopped" state of the encoder using the getEncoderStopped method.
*
* @param encoderHandle the encoder handle
* @param maxPeriod the maximum period where the counted device is considered moving in seconds
* @see "HAL_SetEncoderMaxPeriod"
*/
public static native void setEncoderMaxPeriod(int encoderHandle, double maxPeriod);
/**
* Determines if the clock is stopped.
*
* <p>Determines if the clocked input is stopped based on the MaxPeriod value set using the
* SetMaxPeriod method. If the clock exceeds the MaxPeriod, then the device (and encoder) are
* assumed to be stopped and it returns true.
*
* @param encoderHandle the encoder handle
* @return true if the most recent encoder period exceeds the MaxPeriod value set by SetMaxPeriod
* @see "HAL_GetEncoderStopped"
*/
public static native boolean getEncoderStopped(int encoderHandle);
/**
* Gets the last direction the encoder value changed.
*
* @param encoderHandle the encoder handle
* @return the last direction the encoder value changed
* @see "HAL_GetEncoderDirection"
*/
public static native boolean getEncoderDirection(int encoderHandle);
/**
* Gets the current distance traveled by the encoder.
*
* <p>This is the encoder count scaled by the distance per pulse set for the encoder.
*
* @param encoderHandle the encoder handle
* @return the encoder distance (units are determined by the units passed to
* setEncoderDistancePerPulse)
* @see "HAL_GetEncoderDistance"
*/
public static native double getEncoderDistance(int encoderHandle);
/**
* Gets the current rate of the encoder.
*
* <p>This is the encoder period scaled by the distance per pulse set for the encoder.
*
* @param encoderHandle the encoder handle
* @return the encoder rate (units are determined by the units passed to
* setEncoderDistancePerPulse, time value is seconds)
* @see "HAL_GetEncoderRate"
*/
public static native double getEncoderRate(int encoderHandle);
/**
* Sets the minimum rate to be considered moving by the encoder.
*
* <p>Units need to match what is set by setEncoderDistancePerPulse, with time as seconds.
*
* @param encoderHandle the encoder handle
* @param minRate the minimum rate to be considered moving (units are determined by the units
* passed to setEncoderDistancePerPulse, time value is seconds)
* @see "HAL_SetEncoderMinRate"
*/
public static native void setEncoderMinRate(int encoderHandle, double minRate);
/**
* Sets the distance traveled per encoder pulse. This is used as a scaling factor for the rate and
* distance calls.
*
* @param encoderHandle the encoder handle
* @param distancePerPulse the distance traveled per encoder pulse (units user defined)
* @see "HAL_SetEncoderDistancePerPulse"
*/
public static native void setEncoderDistancePerPulse(int encoderHandle, double distancePerPulse);
/**
* Sets if to reverse the direction of the encoder.
*
* <p>Note that this is not a toggle. It is an absolute set.
*
* @param encoderHandle the encoder handle
* @param reverseDirection true to reverse the direction, false to not.
* @see "HAL_SetEncoderReverseDirection"
*/
public static native void setEncoderReverseDirection(int encoderHandle, boolean reverseDirection);
/**
* Sets the number of encoder samples to average when calculating encoder rate.
*
* @param encoderHandle the encoder handle
* @param samplesToAverage the number of samples to average
* @see "HAL_SetEncoderSamplesToAverage"
*/
public static native void setEncoderSamplesToAverage(int encoderHandle, int samplesToAverage);
/**
* Gets the current samples to average value.
*
* @param encoderHandle the encoder handle
* @return the current samples to average value
* @see "HAL_GetEncoderSamplesToAverage"
*/
public static native int getEncoderSamplesToAverage(int encoderHandle);
/**
* Sets the source for an index pulse on the encoder.
*
* <p>The index pulse can be used to cause an encoder to reset based on an external input.
*
* @param encoderHandle the encoder handle
* @param digitalSourceHandle the index source handle (either a HAL_AnalogTriggerHandle or a
* HAL_DigitalHandle)
* @param analogTriggerType the analog trigger type if the source is an analog trigger
* @param indexingType the index triggering type
* @see "HAL_SetEncoderIndexSource"
*/
public static native void setEncoderIndexSource(
int encoderHandle, int digitalSourceHandle, int analogTriggerType, int indexingType);
/**
* Gets the FPGA index of the encoder.
*
* @param encoderHandle the encoder handle
* @return the FPGA index of the encoder
* @see "HAL_GetEncoderFPGAIndex"
*/
public static native int getEncoderFPGAIndex(int encoderHandle);
/**
* Gets the encoder scale value.
*
* <p>This is set by the value passed during initialization to encodingType.
*
* @param encoderHandle the encoder handle
* @return the encoder scale value
* @see "HAL_GetEncoderEncodingScale"
*/
public static native int getEncoderEncodingScale(int encoderHandle);
/**
* Gets the decoding scale factor of the encoder.
*
* <p>This is used to perform the scaling from raw to type scaled values.
*
* @param encoderHandle the encoder handle
* @return the scale value for the encoder
* @see "HAL_GetEncoderDecodingScaleFactor"
*/
public static native double getEncoderDecodingScaleFactor(int encoderHandle);
/**
* Gets the user set distance per pulse of the encoder.
*
* @param encoderHandle the encoder handle
* @return the set distance per pulse
* @see "HAL_GetEncoderDistancePerPulse"
*/
public static native double getEncoderDistancePerPulse(int encoderHandle);
/**
* Gets the encoding type of the encoder.
*
* @param encoderHandle the encoder handle
* @return the encoding type
* @see "HAL_GetEncoderEncodingType"
*/
public static native int getEncoderEncodingType(int encoderHandle);
}

View File

@@ -8,18 +8,71 @@ import java.util.ArrayList;
import java.util.List;
/**
* JNI Wrapper for HAL<br>
* .
* JNI Wrapper for Hardware Abstraction Layer (HAL).
*
* @see "hal/HALBase.h"
* @see "hal/Main.h"
* @see "hal/FRCUsageReporting.h"
*/
public final class HAL extends JNIWrapper {
/**
* Call this to start up HAL. This is required for robot programs.
*
* <p>This must be called before any other HAL functions. Failure to do so will result in
* undefined behavior, and likely segmentation faults. This means that any statically initialized
* variables in a program MUST call this function in their constructors if they want to use other
* HAL calls.
*
* <p>The common parameters are 500 for timeout and 0 for mode.
*
* <p>This function is safe to call from any thread, and as many times as you wish. It internally
* guards from any reentrancy.
*
* <p>The applicable modes are: 0: Try to kill an existing HAL from another program, if not
* successful, error. 1: Force kill a HAL from another program. 2: Just warn if another hal exists
* and cannot be killed. Will likely result in undefined behavior.
*
* @param timeout the initialization timeout (ms)
* @param mode the initialization mode (see remarks)
* @return true if initialization was successful, otherwise false.
* @see "HAL_Initialize"
*/
public static native boolean initialize(int timeout, int mode);
/**
* Call this to shut down HAL.
*
* <p>This must be called at termination of the robot program to avoid potential segmentation
* faults with simulation extensions at exit.
*
* @see "HAL_Shutdown"
*/
public static native void shutdown();
/**
* Returns true if HAL_SetMain() has been called.
*
* @return True if HAL_SetMain() has been called, false otherwise.
* @see "HAL_HasMain"
*/
public static native boolean hasMain();
/**
* Runs the main function provided to HAL_SetMain().
*
* <p>If HAL_SetMain() has not been called, simply sleeps until exitMain() is called.
*
* @see "HAL_RunMain"
*/
public static native void runMain();
/**
* Causes HAL_RunMain() to exit.
*
* <p>If HAL_SetMain() has been called, this calls the exit function provided to that function.
*
* @see "HAL_ExitMain"
*/
public static native void exitMain();
private static native void simPeriodicBeforeNative();
@@ -113,22 +166,100 @@ public final class HAL extends JNIWrapper {
}
}
/**
* Gets if the system is in a browned out state.
*
* @return true if the system is in a low voltage brown out, false otherwise
* @see "HAL_GetBrownedOut"
*/
public static native boolean getBrownedOut();
/**
* Gets if the system outputs are currently active.
*
* @return true if the system outputs are active, false if disabled
* @see "HAL_GetSystemActive"
*/
public static native boolean getSystemActive();
/**
* Gets the current state of the Robot Signal Light (RSL).
*
* @return The current state of the RSL- true if on, false if off
* @see "HAL_GetRSLState"
*/
public static native boolean getRSLState();
/**
* Gets a port handle for a specific channel and module.
*
* <p>This is expected to be used for PCMs, as the roboRIO does not work with modules anymore.
*
* <p>The created handle does not need to be freed.
*
* @param module the module number
* @param channel the channel number
* @return the created port
* @see "HAL_GetPortWithModule"
*/
public static native int getPortWithModule(byte module, byte channel);
/**
* Gets a port handle for a specific channel.
*
* <p>The created handle does not need to be freed.
*
* @param channel the channel number
* @return the created port
* @see "HAL_GetPort"
*/
public static native int getPort(byte channel);
/**
* Report the usage of a resource of interest.
*
* <p>Original signature: <code>uint32_t report(tResourceType, uint8_t, uint8_t, const
* char*)</code>
*
* @param resource one of the values in the tResourceType above.
* @param instanceNumber an index that identifies the resource instance.
* @see "HAL_Report"
*/
public static void report(int resource, int instanceNumber) {
report(resource, instanceNumber, 0, "");
}
/**
* Report the usage of a resource of interest.
*
* <p>Original signature: <code>uint32_t report(tResourceType, uint8_t, uint8_t, const
* char*)</code>
*
* @param resource one of the values in the tResourceType above.
* @param instanceNumber an index that identifies the resource instance.
* @param context an optional additional context number for some cases (such as module number).
* Set to 0 to omit.
* @see "HAL_Report"
*/
public static void report(int resource, int instanceNumber, int context) {
report(resource, instanceNumber, context, "");
}
/**
* Report the usage of a resource of interest.
*
* <p>Original signature: <code>uint32_t report(tResourceType, uint8_t, uint8_t, const
* char*)</code>
*
* @param resource one of the values in the tResourceType above.
* @param instanceNumber an index that identifies the resource instance.
* @param context an optional additional context number for some cases (such as module number).
* Set to 0 to omit.
* @param feature a string to be included describing features in use on a specific resource.
* Setting the same resource more than once allows you to change the feature string.
* @return the index of the added value in NetComm
* @see "HAL_Report"
*/
public static int report(int resource, int instanceNumber, int context, String feature) {
return DriverStationJNI.report(resource, instanceNumber, context, feature);
}

View File

@@ -4,6 +4,11 @@
package edu.wpi.first.hal;
/**
* Hardware Abstraction Layer (HAL) Utilities JNI Functions.
*
* @see "hal/HALBase.h"
*/
public final class HALUtil extends JNIWrapper {
public static final int NULL_PARAMETER = -1005;
public static final int SAMPLE_RATE_TOO_HIGH = 1001;
@@ -18,26 +23,100 @@ public final class HALUtil extends JNIWrapper {
public static final int RUNTIME_ROBORIO2 = 1;
public static final int RUNTIME_SIMULATION = 2;
/**
* Returns the FPGA Version number.
*
* <p>For now, expect this to be competition year.
*
* @return FPGA Version number.
* @see "HAL_GetFPGAVersion"
*/
public static native short getFPGAVersion();
/**
* Returns the FPGA Revision number.
*
* <p>The format of the revision is 3 numbers. The 12 most significant bits are the Major
* Revision. the next 8 bits are the Minor Revision. The 12 least significant bits are the Build
* Number.
*
* @return FPGA Revision number.
* @see "HAL_GetFPGARevision"
*/
public static native int getFPGARevision();
/**
* Returns the roboRIO serial number.
*
* @return The roboRIO serial number.
* @see "HAL_GetSerialNumber"
*/
public static native String getSerialNumber();
/**
* Returns the comments from the roboRIO web interface.
*
* @return The comments string.
* @see "HAL_GetComments"
*/
public static native String getComments();
/**
* Reads the microsecond-resolution timer on the FPGA.
*
* @return The current time in microseconds according to the FPGA (since FPGA reset).
*/
public static native long getFPGATime();
/**
* Returns the runtime type of the HAL.
*
* @return HAL Runtime Type
* @see RUNTIME_ROBORIO
* @see RUNTIME_ROBORIO2
* @see RUNTIME_SIMULATION
* @see "HAL_GetRuntimeType"
*/
public static native int getHALRuntimeType();
/**
* Gets the state of the "USER" button on the roboRIO.
*
* @return true if the button is currently pressed down
* @see "HAL_GetFPGAButton"
*/
public static native boolean getFPGAButton();
/**
* Gets the error message for a specific status code.
*
* @param code the status code
* @return the error message for the code. This does not need to be freed.
* @see "HAL_GetErrorMessage"
*/
public static native String getHALErrorMessage(int code);
/**
* Get the last HAL error code.
*
* @return error code
*/
public static native int getHALErrno();
/**
* Returns the textual description of the system error code.
*
* @param errno errno to get description of
* @return description of errno
* @see "std:strerror"
*/
public static native String getHALstrerror(int errno);
/**
* Gets the error message for the last HAL error.
*
* @return the error message for the code.
*/
public static String getHALstrerror() {
return getHALstrerror(getHALErrno());
}

View File

@@ -6,9 +6,38 @@ package edu.wpi.first.hal;
import java.nio.ByteBuffer;
/**
* I2C HAL JNI functions.
*
* @see "I2C.h"
*/
public class I2CJNI extends JNIWrapper {
/**
* Initializes the I2C port.
*
* <p>Opens the port if necessary and saves the handle. If opening the MXP port, also sets up the
* channel functions appropriately.
*
* @param port The port to open, 0 for the on-board, 1 for the MXP.
* @see "HAL_InitializeI2C"
*/
public static native void i2CInitialize(int port);
/**
* Generic I2C read/write transaction.
*
* <p>This is a lower-level interface to the I2C hardware giving you more control over each
* transaction.
*
* @param port The I2C port, 0 for the on-board, 1 for the MXP.
* @param address The address of the register on the device to be read/written.
* @param dataToSend Buffer of data to send as part of the transaction.
* @param sendSize Number of bytes to send as part of the transaction.
* @param dataReceived Buffer to read data into.
* @param receiveSize Number of bytes to read from the device.
* @return &gt;= 0 on success or -1 on transfer abort.
* @see "HAL_TransactionI2C"
*/
public static native int i2CTransaction(
int port,
byte address,
@@ -17,6 +46,21 @@ public class I2CJNI extends JNIWrapper {
ByteBuffer dataReceived,
byte receiveSize);
/**
* Generic I2C read/write transaction.
*
* <p>This is a lower-level interface to the I2C hardware giving you more control over each
* transaction.
*
* @param port The I2C port, 0 for the on-board, 1 for the MXP.
* @param address The address of the register on the device to be read/written.
* @param dataToSend Buffer of data to send as part of the transaction.
* @param sendSize Number of bytes to send as part of the transaction.
* @param dataReceived Buffer to read data into.
* @param receiveSize Number of bytes to read from the device.
* @return &gt;= 0 on success or -1 on transfer abort.
* @see "HAL_TransactionI2C"
*/
public static native int i2CTransactionB(
int port,
byte address,
@@ -25,14 +69,70 @@ public class I2CJNI extends JNIWrapper {
byte[] dataReceived,
byte receiveSize);
/**
* Executes a write transaction with the device.
*
* <p>Writes a single byte to a register on a device and wait until the transaction is complete.
*
* @param port The I2C port, 0 for the on-board, 1 for the MXP.
* @param address The address of the register on the device to be written.
* @param dataToSend The byte to write to the register on the device.
* @param sendSize Number of bytes to send.
* @return &gt;= 0 on success or -1 on transfer abort.
* @see "HAL_WriteI2C"
*/
public static native int i2CWrite(int port, byte address, ByteBuffer dataToSend, byte sendSize);
/**
* Executes a write transaction with the device.
*
* <p>Writes a single byte to a register on a device and wait until the transaction is complete.
*
* @param port The I2C port, 0 for the on-board, 1 for the MXP.
* @param address The address of the register on the device to be written.
* @param dataToSend The byte to write to the register on the device.
* @param sendSize Number of bytes to send.
* @return &gt;= 0 on success or -1 on transfer abort.
* @see "HAL_WriteI2C"
*/
public static native int i2CWriteB(int port, byte address, byte[] dataToSend, byte sendSize);
/**
* Executes a read transaction with the device.
*
* <p>Reads bytes from a device. Most I2C devices will auto-increment the register pointer
* internally allowing you to read consecutive registers on a device in a single transaction.
*
* @param port The I2C port, 0 for the on-board, 1 for the MXP.
* @param address The register to read first in the transaction.
* @param dataReceived A ByteBuffer to store the data read from the device.
* @param receiveSize The number of bytes to read in the transaction.
* @return &gt;= 0 on success or -1 on transfer abort.
* @see "HAL_ReadI2C"
*/
public static native int i2CRead(
int port, byte address, ByteBuffer dataReceived, byte receiveSize);
/**
* Executes a read transaction with the device.
*
* <p>Reads bytes from a device. Most I2C devices will auto-increment the register pointer
* internally allowing you to read consecutive registers on a device in a single transaction.
*
* @param port The I2C port, 0 for the on-board, 1 for the MXP.
* @param address The register to read first in the transaction.
* @param dataReceived A byte array to store the data read from the device.
* @param receiveSize The number of bytes to read in the transaction.
* @return &gt;= 0 on success or -1 on transfer abort.
* @see "HAL_ReadI2C"
*/
public static native int i2CReadB(int port, byte address, byte[] dataReceived, byte receiveSize);
/**
* Closes an I2C port.
*
* @param port The I2C port, 0 for the on-board, 1 for the MXP.
* @see "HAL_CloseI2C"
*/
public static native void i2CClose(int port);
}

View File

@@ -4,28 +4,113 @@
package edu.wpi.first.hal;
/**
* Interrupt HAL JNI functions.
*
* @see "hal/Interrupts.h"
*/
public class InterruptJNI extends JNIWrapper {
public static final int HalInvalidHandle = 0;
/**
* Initializes an interrupt.
*
* @return the created interrupt handle
* @see "HAL_InitializeInterrupts"
*/
public static native int initializeInterrupts();
/**
* Frees an interrupt.
*
* @param interruptHandle the interrupt handle
* @see "HAL_CleanInterrupts"
*/
public static native void cleanInterrupts(int interruptHandle);
/**
* Waits for the defined interrupt to occur.
*
* @param interruptHandle the interrupt handle
* @param timeout timeout in seconds
* @param ignorePrevious if true, ignore interrupts that happened before waitForInterrupt was
* called
* @return the mask of interrupts that fired
* @see "HAL_WaitForInterrupt"
*/
public static native long waitForInterrupt(
int interruptHandle, double timeout, boolean ignorePrevious);
/**
* Waits for any interrupt covered by the mask to occur.
*
* @param interruptHandle the interrupt handle to use for the context
* @param mask the mask of interrupts to wait for
* @param timeout timeout in seconds
* @param ignorePrevious if true, ignore interrupts that happened before waitForInterrupt was
* called
* @return the mask of interrupts that fired
* @see "HAL_WaitForMultipleInterrupts"
*/
public static native long waitForMultipleInterrupts(
int interruptHandle, long mask, double timeout, boolean ignorePrevious);
/**
* Returns the timestamp for the rising interrupt that occurred most recently.
*
* <p>This is in the same time domain as getFPGATime(). It only contains the bottom 32 bits of the
* timestamp. If your robot has been running for over 1 hour, you will need to fill in the upper
* 32 bits yourself.
*
* @param interruptHandle the interrupt handle
* @return timestamp in microseconds since FPGA Initialization
*/
public static native long readInterruptRisingTimestamp(int interruptHandle);
/**
* Returns the timestamp for the falling interrupt that occurred most recently.
*
* <p>This is in the same time domain as getFPGATime(). It only contains the bottom 32 bits of the
* timestamp. If your robot has been running for over 1 hour, you will need to fill in the upper
* 32 bits yourself.
*
* @param interruptHandle the interrupt handle
* @return timestamp in microseconds since FPGA Initialization
*/
public static native long readInterruptFallingTimestamp(int interruptHandle);
/**
* Requests interrupts on a specific digital source.
*
* @param interruptHandle the interrupt handle
* @param digitalSourceHandle the digital source handle (either a HAL_AnalogTriggerHandle or a
* HAL_DigitalHandle)
* @param analogTriggerType the trigger type if the source is an AnalogTrigger
* @see "HAL_RequestInterrupts"
*/
public static native void requestInterrupts(
int interruptHandle, int digitalSourceHandle, int analogTriggerType);
/**
* Sets the edges to trigger the interrupt on.
*
* <p>Note that both edges triggered is a valid configuration.
*
* @param interruptHandle the interrupt handle
* @param risingEdge true for triggering on rising edge
* @param fallingEdge true for triggering on falling edge
* @see "HAL_SetInterruptUpSourceEdge"
*/
public static native void setInterruptUpSourceEdge(
int interruptHandle, boolean risingEdge, boolean fallingEdge);
/**
* Releases a waiting interrupt.
*
* <p>This will release both rising and falling waiters.
*
* @param interruptHandle the interrupt handle to release
* @see "HAL_ReleaseWaitingInterrupt"
*/
public static native void releaseWaitingInterrupt(int interruptHandle);
}

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