Compare commits

...

317 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
Tyler Veness
2f310a748c [wpimath] Fix DCMotor.getSpeed() (#5061)
This bug didn't occur in C++ because the units system caught it at
compile time.
2023-02-05 13:21:16 -08:00
Nick Hadley
b43ec87f57 [wpilib] ElevatorSim: Fix WouldHitLimit methods (#5057) 2023-02-05 11:58:53 -08:00
Peter Johnson
19267bef0c [ntcore] Output warning on property set on unpublished topic (#5059)
Previously this was a debug-level message. This can primarily impact
users who call SetPersistent() on an entry before calling SetDefault().
2023-02-05 11:57:29 -08:00
Peter Johnson
84cbd48d84 [ntcore] Handle excludeSelf on SetDefault (#5058) 2023-02-05 11:57:09 -08:00
Peter Johnson
1f35750865 [cameraserver] Add GetInstance() to all functions (#5054)
GetInstance() is required to start the event listener that creates the
network table entries.

This is a C++ only change; Java uses static's and thus doesn't need this.

The right fix is to implement cscore's AddListener() immediate notification,
but that's much too invasive of a change to do this year.

This fixes the common use cases, but doesn't fix all cases, as e.g. creating
a UsbCamera manually before calling any CameraServer functions will still
have the issue, but there's an easy workaround--call
CameraServer::SetSize() prior to creating any cameras.
2023-02-05 11:28:53 -08:00
Peter Johnson
8230fc631d [wpilib] Revert throw on nonexistent SimDevice name in SimDeviceSim (#5053)
This breaks current vendor use of SimDeviceSim.

This reverts commit d991f6e435 (#5041).
2023-02-05 11:27:55 -08:00
Peter Johnson
b879a6f8c6 [wpinet] WebSocket: When Close() is called, call closed immediately (#5047)
This provides the closed callback with the real reason for the
connection being closed.  Keep closed from being called twice by adding
a check in SetClosed().
2023-02-03 22:59:19 -08:00
Peter Johnson
49459d3e45 [ntcore] Change wire timeout to fixed 1 second (#5048)
Previously the timeout was 10 times the update rate, so with low update
rates it could be as small as 50 ms, causing spurious disconnects when
large or many topics were published.
2023-02-03 22:05:41 -08:00
Jordan McMichael
4079eabe9b [wpimath] Discard stale pose estimates (#5045)
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2023-02-03 22:04:30 -08:00
Peter Johnson
fe5d226a19 [glass] Fix option for debug-level NT logging (#5049) 2023-02-03 22:03:45 -08:00
Peter Johnson
b7535252c2 [ntcore] Don't leak buffers in rare WS shutdown case (#5046)
If the request called the callback after the WebSocket had been
destroyed, the buffers were leaked.
2023-02-03 21:56:35 -08:00
Peter Johnson
b61ac6db33 [ntcore] Add client disconnect function (#5022)
As setServer doesn't disconnect, it's useful to have a function that
disconnects without needing to completely stop the client.
2023-02-03 15:28:00 -08:00
Ryan Blue
7b828ce84f [wpimath] Add nearest to Pose2d and Translation2d (#4882)
Co-authored-by: David Vo <auscompgeek@users.noreply.github.com>
2023-02-03 15:27:16 -08:00
Michael Leong
08a536291b [examples] Improvements to Elevator Simulation Example (#4937)
Co-authored-by: Abhay Shukla <105139789+aboombadev@users.noreply.github.com>
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
Co-authored-by: Ryan Blue <ryanzblue@gmail.com>
2023-02-03 15:23:06 -08:00
Peter Johnson
193a10d020 [wpigui] Limit frame rate to 120 fps by default (#5030)
Limiting with vsync is apparently unreliable on a number of systems;
this resulted in high CPU/GPU usage.

Also add current actual frame rate to about dialog of GUI tools.
2023-02-03 15:21:52 -08:00
sciencewhiz
7867bbde0e [wpilib] Clarify DS functions provided by FMS (NFC) (#5043) 2023-02-03 15:21:12 -08:00
Peter Johnson
fa7c01b598 [glass] Add option for debug-level NT logging (#5007) 2023-02-03 15:20:03 -08:00
truher
2b81610248 [wpiutil] Add msgpack to datalog Python example (#5032) 2023-02-03 15:19:44 -08:00
Tyler Veness
a4a369b8da CONTRIBUTING.md: Add unicodeit CLI to math docs guidelines (#5031) 2023-02-03 15:19:01 -08:00
Ryan Blue
d991f6e435 [wpilib] Throw on nonexistent SimDevice name in SimDeviceSim constructor (#5041)
Previously this would just create a object that was otherwise non-functional.
2023-02-03 15:18:31 -08:00
Peter Johnson
a27a047ae8 [hal] Check for null in getSimDeviceName JNI (#5038) 2023-02-01 23:25:55 -08:00
Starlight220
2f96cae31a [examples] Hatchbots: Add telemetry (#5011) 2023-01-31 23:44:18 -08:00
Peter Johnson
83ef8f9658 [simulation] GUI: Fix buffer overflow in joystick axes copy (#5036)
This was using an incorrect sizeof which would copy excessive data and
overwrite the button data.
2023-01-31 23:40:22 -08:00
Starlight220
4054893669 [commands] Fix C++ Select() factory (#5024)
Update example to use it.
2023-01-29 07:23:12 -08:00
Sriman Achanta
f75acd11ce [commands] Use Timer.restart() (#5023) 2023-01-29 07:21:07 -08:00
Tyler Veness
8bf67b1b33 [wpimath] PIDController::Calculate(double, double): update setpoint flag (#5021)
Fixes #5020.
2023-01-29 07:18:48 -08:00
Peter Johnson
49bb1358d8 [wpiutil] MemoryBuffer: Fix GetMemoryBufferForStream (#5017)
This would previously just write past the end of the buffer, smashing
the stack.  It's only called in the case when a non-file or block device
is used as the file.
2023-01-28 22:38:34 -08:00
Peter Johnson
9c4c07c0f9 [wpiutil] Remove NDEBUG check for debug-level logging (#5018)
This adds minimal overhead but is useful when debugging release
binaries.
2023-01-28 14:13:58 -08:00
Peter Johnson
1a47cc2e86 [ntcore] Use full handle when subscribing (#5013)
Just using the index is insufficient because of Subscriber overlap with
MultiSubscriber.
2023-01-27 09:14:38 -08:00
Ryan Blue
7cd30cffbc Ignore networktables.json (#5006) 2023-01-26 09:21:58 -08:00
DeltaDizzy
92aecab2ef [commands] Command controllers are not subclasses (NFC) (#5000) 2023-01-25 15:20:29 -08:00
Peter Johnson
8785bba080 [ntcore] Special-case default timestamps (#5003)
Previously, a setDefault() on the server could override a client doing a
real set() if the time offset between client and server was negative,
resulting in a negative timestamp from the client.  This is a not
uncommon situation with robot code, as the robot code always starts at
time 0, so any clients that set values earlier (in real time) would have
negative timestamps.

Also improve special casing of 0 in the transmit side to make sure a
normal timestamp will never get sent as 0.
2023-01-25 11:36:13 -08:00
Peter Johnson
9e5b7b8040 [ntcore] Handle topicsonly followed by value subscribe (#4991)
Previously this wouldn't send the last value on the value subscribe if a
topics only subscription already existed.

Also start adding server implementation unit tests.
2023-01-24 21:50:38 -08:00
Sriman Achanta
917906530a [wpilib] Add Timer::Restart() (#4963) 2023-01-23 14:50:46 -08:00
Tyler Veness
00aa66e4fd [wpimath] Remove extraneous assignments from DiscretizeAB() (#4967) 2023-01-23 09:46:12 -08:00
Starlight220
893320544a [examples] C++ RamseteCommand: Fix units (#4954)
Also fix the memory leak in the command-based auto.
2023-01-22 11:20:35 -08:00
Evan
b95d0e060d [wpilib] XboxController: Fix docs discrepancy (NFC) (#4993)
Comments for leftTrigger said they attach to the right trigger of the controller.
2023-01-21 22:09:55 -08:00
Peter Johnson
008232b43c [ntcore] Write empty persistent file if none found (#4996)
This avoids the warning appearing on every startup when persistent
values aren't used.

Also add note to message saying it can be ignored if persistent values
aren't expected.
2023-01-21 22:09:24 -08:00
Starlight220
522be348f4 [examples] Rewrite tags (NFC) (#4961) 2023-01-21 15:24:10 -08:00
Tyler Veness
d48a83dee2 [wpimath] Update Wikipedia links for quaternion to Euler angle conversion (NFC) (#4995) 2023-01-21 15:16:35 -08:00
Peter Johnson
504fa22143 [wpimath] Workaround intellisense Eigen issue (#4992)
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2023-01-21 15:16:12 -08:00
Brady Schindler
b2b25bf09f [commands] Fix docs inconsistency for toggleOnFalse(Command) (NFC) (#4978) 2023-01-20 23:47:37 -08:00
Thad House
ce3dc4eb3b [hal] Properly use control word that is in sync with DS data (#4989) 2023-01-20 23:46:56 -08:00
Thad House
1ea48caa7d [wpilib] Fix C++ ADXRS450 and Java SPI gyro defs (#4988) 2023-01-20 13:25:13 -08:00
Thad House
fb101925a7 [build] Include wpimathjni in commands binaries (#4981) 2023-01-19 22:05:32 -08:00
Thad House
657951f6dd [starter] Add a process starter for use by the installer for launching tools (#4931) 2023-01-19 20:09:35 -08:00
Tyler Veness
a60ca9d71c [examples] Update AprilTag field load API usage (#4975) 2023-01-19 17:01:17 -08:00
Tyler Veness
f8a45f1558 [wpimath] Remove print statements from tests (#4977) 2023-01-19 17:00:35 -08:00
sciencewhiz
ecba8b99a8 [examples] Fix swapped arguments in MecanumControllerCommand example (#4976) 2023-01-18 21:25:49 -08:00
Berke Sinan Yetkin
e95e88fdf9 [examples] Add comment to drivedistanceoffboard example (#4877)
Co-authored-by: Ryan Blue <ryanzblue@gmail.com>
2023-01-18 20:46:41 -08:00
CarloWoolsey
371d15dec3 [examples] Add Computer Vision Pose Estimation and Latency Compensation Example (#4901)
This PR updates the existing differentialdriveposeestimator example to include computer vision pose estimation and latency compensation.

The example generates a simulated cameraToTarget transformation, which is then fed into ComputerVisionUtil.objectToRobotPose() to compute the robot's field-relative position exclusively from vision measurements. The vision measurements are applied through DifferentialDrivePoseEstimator.addVisionMeasurement().

The updated example constructs an AprilTagFieldLayout from JSON. This requires a deploy directory, something which isn't currently supported in wpilibjExamples and wpilibcExamples.
2023-01-18 20:46:05 -08:00
Peter Johnson
cb9b8938af [sim] Enable docking in the GUI (#4960) 2023-01-18 20:42:58 -08:00
Brennen Puth
3b084ecbe0 [apriltag] AprilTagFieldLayout: Improve API shape for loading builtin JSONs (#4949) 2023-01-18 20:42:39 -08:00
Matt
27ba096ea1 [wpilib] Fix MOI calculation error in SingleJointedArmSim (#4968)
Previous calculation derivation mixed up length and distance to CG.
2023-01-18 20:40:39 -08:00
Jordan McMichael
42c997a3c4 [wpimath] Fix Pose3d exponential and clean up Pose3d logarithm (#4970)
Implementation based on this paper: https://ethaneade.org/lie.pdf
2023-01-18 20:38:03 -08:00
Tyler Veness
5f1a025f27 [wpilibj] Fix typo in MecanumDrive docs (NFC) (#4969) 2023-01-18 13:47:27 -08:00
Tyler Veness
0ebf79b54c [wpimath] Fix typo in Pose3d::Exp() docs (NFC) (#4966) 2023-01-18 13:46:45 -08:00
Oliver W
a8c465f3fb [wpimath] HolonomicDriveController: Add getters for the controllers (#4948) 2023-01-16 08:33:15 -08:00
Starlight220
a7b1ab683d [wpilibc] Add unit test for fast deconstruction of GenericHID (#4953) 2023-01-16 08:28:06 -08:00
Starlight220
bd6479dc29 [build] Add Spotless for JSON (#4956) 2023-01-16 08:26:46 -08:00
Thad House
5cb0340a8c [hal, wpilib] Load joystick values upon code initialization (#4950)
During HAL_Initialize, wait up to 100ms for a DS packet to be received. Then in RobotBase, right after calling HAL_Initialize, call each language's RefreshData function to force a high level DS update. If the DS is connected, will get joystick data. If there is no data, nothing different will happen, but in that case there's no joysticks anyway.
2023-01-15 16:36:44 -08:00
sciencewhiz
ab0e8c37a7 [readme] Update build requirements (NFC) (#4947)
Change to adoptium, and add Xcode min version
2023-01-15 15:19:24 -08:00
Tyler Veness
b74ac1c645 [build] Add apriltag to C++ cmake example builds (#4944)
This fixes compilation of the apriltag vision example on my machine.
2023-01-13 23:24:14 -08:00
1466 changed files with 49439 additions and 31859 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

2
.gitignore vendored
View File

@@ -9,6 +9,8 @@ simgui-ds.json
simgui-window.json
simgui.json
networktables.json
# Created by the jenkins test script
test-reports

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

@@ -40,8 +40,39 @@ So you want to contribute your changes back to WPILib. Great! We have a few cont
WPILib uses modified Google style guides for both C++ and Java, which can be found in the [styleguide repository](https://github.com/wpilibsuite/styleguide). Autoformatters are available for many popular editors at https://github.com/google/styleguide. Running wpiformat is required for all contributions and is enforced by our continuous integration system.
While the library should be fully formatted according to the styles, additional elements of the style guide were not followed when the library was initially created. All new code should follow the guidelines. If you are looking for some easy ramp-up tasks, finding areas that don't follow the style guide and fixing them is very welcome.
### Math documentation
When writing math expressions in documentation, use https://www.unicodeit.net/ to convert LaTeX to a Unicode equivalent that's easier to read. Not all expressions will translate (e.g., superscripts of superscripts) so focus on making it readable by someone who isn't familiar with LaTeX. If content on multiple lines needs to be aligned in Doxygen/Javadoc comments (e.g., integration/summation limits, matrices packed with square brackets and superscripts for them), put them in @verbatim/@endverbatim blocks in Doxygen or `<pre>` tags in Javadoc so they render with monospace font.
The LaTeX to Unicode conversions can also be done locally via the unicodeit Python package. To install it, execute:
```bash
pip install --user unicodeit
```
Here's example usage:
```bash
$ python -m unicodeit.cli 'x_{k+1} = Ax_k + Bu_k'
xₖ₊₁ = Axₖ + Buₖ
```
On Linux, this process can be streamlined further by adding the following Bash function to your .bashrc (requires `wl-clipboard` on Wayland or `xclip` on X11):
```bash
# Converts LaTeX to Unicode, prints the result, and copies it to the clipboard
uc() {
if [ $WAYLAND_DISPLAY ]; then
python -m unicodeit.cli $@ | tee >(wl-copy -n)
else
python -m unicodeit.cli $@ | tee >(xclip -sel)
fi
}
```
Here's example usage:
```bash
$ uc 'x_{k+1} = Ax_k + Bu_k'
xₖ₊₁ = Axₖ + Buₖ
```
## Submitting Changes
### Pull Request Format

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)
@@ -40,7 +41,7 @@ Using Gradle makes building WPILib very straightforward. It only has a few depen
## Requirements
- [JDK 11](https://adoptopenjdk.net/)
- [JDK 11](https://adoptium.net/temurin/releases/?version=11)
- Note that the JRE is insufficient; the full JDK is required
- On Ubuntu, run `sudo apt install openjdk-11-jdk`
- On Windows, install the JDK 11 .msi from the link above
@@ -48,7 +49,7 @@ Using Gradle makes building WPILib very straightforward. It only has a few depen
- C++ compiler
- On Linux, install GCC 11 or greater
- On Windows, install [Visual Studio Community 2022](https://visualstudio.microsoft.com/vs/community/) and select the C++ programming language during installation (Gradle can't use the build tools for Visual Studio)
- On macOS, install the Xcode command-line build tools via `xcode-select --install`
- On macOS, install the Xcode command-line build tools via `xcode-select --install`. Xcode 13 or later is required.
- ARM compiler toolchain
- Run `./gradlew installRoboRioToolchain` after cloning this repository
- If the WPILib installer was used, this toolchain is already installed
@@ -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

@@ -189,7 +189,10 @@ public class AprilTagFieldLayout {
}
/**
* Deserializes a field layout from a resource within a jar file.
* Deserializes a field layout from a resource within a internal jar file.
*
* <p>Users should use {@link AprilTagFields#loadAprilTagLayoutField()} to load official layouts
* and {@link #AprilTagFieldLayout(String)} for custom layouts.
*
* @param resourcePath The absolute path of the resource
* @return The deserialized layout

View File

@@ -4,6 +4,8 @@
package edu.wpi.first.apriltag;
import java.io.IOException;
public enum AprilTagFields {
k2022RapidReact("2022-rapidreact.json"),
k2023ChargedUp("2023-chargedup.json");
@@ -18,4 +20,14 @@ public enum AprilTagFields {
AprilTagFields(String resourceFile) {
m_resourceFile = kBaseResourceDir + resourceFile;
}
/**
* Get a {@link AprilTagFieldLayout} from the resource JSON.
*
* @return AprilTagFieldLayout of the field
* @throws IOException If the layout does not exist
*/
public AprilTagFieldLayout loadAprilTagLayoutField() throws IOException {
return AprilTagFieldLayout.loadFromResource(m_resourceFile);
}
}

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

@@ -1,415 +1,440 @@
{
"tags" : [ {
"ID" : 0,
"pose" : {
"translation" : {
"x" : -0.0035306,
"y" : 7.578928199999999,
"z" : 0.8858503999999999
},
"rotation" : {
"quaternion" : {
"W" : 1.0,
"X" : 0.0,
"Y" : 0.0,
"Z" : 0.0
"tags": [
{
"ID": 0,
"pose": {
"translation": {
"x": -0.0035306,
"y": 7.578928199999999,
"z": 0.8858503999999999
},
"rotation": {
"quaternion": {
"W": 1.0,
"X": 0.0,
"Y": 0.0,
"Z": 0.0
}
}
}
},
{
"ID": 1,
"pose": {
"translation": {
"x": 3.2327088,
"y": 5.486654,
"z": 1.7254728
},
"rotation": {
"quaternion": {
"W": 1.0,
"X": 0.0,
"Y": 0.0,
"Z": 0.0
}
}
}
},
{
"ID": 2,
"pose": {
"translation": {
"x": 3.067812,
"y": 5.3305202,
"z": 1.3762228
},
"rotation": {
"quaternion": {
"W": 0.7071067811865476,
"X": 0.0,
"Y": 0.0,
"Z": -0.7071067811865475
}
}
}
},
{
"ID": 3,
"pose": {
"translation": {
"x": 0.0039878,
"y": 5.058536999999999,
"z": 0.80645
},
"rotation": {
"quaternion": {
"W": 1.0,
"X": 0.0,
"Y": 0.0,
"Z": 0.0
}
}
}
},
{
"ID": 4,
"pose": {
"translation": {
"x": 0.0039878,
"y": 3.5124898,
"z": 0.80645
},
"rotation": {
"quaternion": {
"W": 1.0,
"X": 0.0,
"Y": 0.0,
"Z": 0.0
}
}
}
},
{
"ID": 5,
"pose": {
"translation": {
"x": 0.12110719999999998,
"y": 1.7178274,
"z": 0.8906002000000001
},
"rotation": {
"quaternion": {
"W": 0.9196502204050923,
"X": 0.0,
"Y": 0.0,
"Z": 0.39273842708457407
}
}
}
},
{
"ID": 6,
"pose": {
"translation": {
"x": 0.8733027999999999,
"y": 0.9412985999999999,
"z": 0.8906002000000001
},
"rotation": {
"quaternion": {
"W": 0.9196502204050923,
"X": 0.0,
"Y": 0.0,
"Z": 0.39273842708457407
}
}
}
},
{
"ID": 7,
"pose": {
"translation": {
"x": 1.6150844,
"y": 0.15725139999999999,
"z": 0.8906002000000001
},
"rotation": {
"quaternion": {
"W": 0.9196502204050923,
"X": 0.0,
"Y": 0.0,
"Z": 0.39273842708457407
}
}
}
},
{
"ID": 10,
"pose": {
"translation": {
"x": 16.4627306,
"y": 0.6506718,
"z": 0.8858503999999999
},
"rotation": {
"quaternion": {
"W": 6.123233995736766E-17,
"X": 0.0,
"Y": 0.0,
"Z": 1.0
}
}
}
},
{
"ID": 11,
"pose": {
"translation": {
"x": 13.2350002,
"y": 2.743454,
"z": 1.7254728
},
"rotation": {
"quaternion": {
"W": 6.123233995736766E-17,
"X": 0.0,
"Y": 0.0,
"Z": 1.0
}
}
}
},
{
"ID": 12,
"pose": {
"translation": {
"x": 13.391388000000001,
"y": 2.8998418,
"z": 1.3762228
},
"rotation": {
"quaternion": {
"W": 0.7071067811865476,
"X": 0.0,
"Y": 0.0,
"Z": 0.7071067811865475
}
}
}
},
{
"ID": 13,
"pose": {
"translation": {
"x": 16.4552122,
"y": 3.1755079999999998,
"z": 0.80645
},
"rotation": {
"quaternion": {
"W": 6.123233995736766E-17,
"X": 0.0,
"Y": 0.0,
"Z": 1.0
}
}
}
},
{
"ID": 14,
"pose": {
"translation": {
"x": 16.4552122,
"y": 4.7171356,
"z": 0.80645
},
"rotation": {
"quaternion": {
"W": 6.123233995736766E-17,
"X": 0.0,
"Y": 0.0,
"Z": 1.0
}
}
}
},
{
"ID": 15,
"pose": {
"translation": {
"x": 16.3350194,
"y": 6.5149729999999995,
"z": 0.8937752
},
"rotation": {
"quaternion": {
"W": -0.37298778257580906,
"X": -0.0,
"Y": 0.0,
"Z": 0.9278362538989199
}
}
}
},
{
"ID": 16,
"pose": {
"translation": {
"x": 15.5904946,
"y": 7.292695599999999,
"z": 0.8906002000000001
},
"rotation": {
"quaternion": {
"W": -0.37298778257580906,
"X": -0.0,
"Y": 0.0,
"Z": 0.9278362538989199
}
}
}
},
{
"ID": 17,
"pose": {
"translation": {
"x": 14.847188999999998,
"y": 8.0691228,
"z": 0.8906002000000001
},
"rotation": {
"quaternion": {
"W": -0.37298778257580906,
"X": -0.0,
"Y": 0.0,
"Z": 0.9278362538989199
}
}
}
},
{
"ID": 40,
"pose": {
"translation": {
"x": 7.874127,
"y": 4.9131728,
"z": 0.7032752
},
"rotation": {
"quaternion": {
"W": 0.5446390350150271,
"X": 0.0,
"Y": 0.0,
"Z": 0.838670567945424
}
}
}
},
{
"ID": 41,
"pose": {
"translation": {
"x": 7.4312271999999995,
"y": 3.759327,
"z": 0.7032752
},
"rotation": {
"quaternion": {
"W": -0.20791169081775934,
"X": -0.0,
"Y": 0.0,
"Z": 0.9781476007338057
}
}
}
},
{
"ID": 42,
"pose": {
"translation": {
"x": 8.585073,
"y": 3.3164272,
"z": 0.7032752
},
"rotation": {
"quaternion": {
"W": 0.838670567945424,
"X": 0.0,
"Y": 0.0,
"Z": -0.5446390350150271
}
}
}
},
{
"ID": 43,
"pose": {
"translation": {
"x": 9.0279728,
"y": 4.470273,
"z": 0.7032752
},
"rotation": {
"quaternion": {
"W": 0.9781476007338057,
"X": 0.0,
"Y": 0.0,
"Z": 0.20791169081775934
}
}
}
},
{
"ID": 50,
"pose": {
"translation": {
"x": 7.6790296,
"y": 4.3261534,
"z": 2.4177244
},
"rotation": {
"quaternion": {
"W": 0.17729273396782605,
"X": -0.22744989571511945,
"Y": 0.04215534644161733,
"Z": 0.9565859910053995
}
}
}
},
{
"ID": 51,
"pose": {
"translation": {
"x": 8.0182466,
"y": 3.5642296,
"z": 2.4177244
},
"rotation": {
"quaternion": {
"W": -0.5510435465842192,
"X": -0.19063969497246985,
"Y": -0.13102303230819815,
"Z": 0.8017733354717242
}
}
}
},
{
"ID": 52,
"pose": {
"translation": {
"x": 8.7801704,
"y": 3.9034466,
"z": 2.4177244
},
"rotation": {
"quaternion": {
"W": -0.9565859910053994,
"X": -0.04215534644161739,
"Y": -0.22744989571511942,
"Z": 0.17729273396782633
}
}
}
},
{
"ID": 53,
"pose": {
"translation": {
"x": 8.4409534,
"y": 4.6653704,
"z": 2.4177244
},
"rotation": {
"quaternion": {
"W": 0.8017733354717241,
"X": -0.1310230323081982,
"Y": 0.19063969497246983,
"Z": 0.5510435465842194
}
}
}
}
}, {
"ID" : 1,
"pose" : {
"translation" : {
"x" : 3.2327088,
"y" : 5.486654,
"z" : 1.7254728
},
"rotation" : {
"quaternion" : {
"W" : 1.0,
"X" : 0.0,
"Y" : 0.0,
"Z" : 0.0
}
}
}
}, {
"ID" : 2,
"pose" : {
"translation" : {
"x" : 3.067812,
"y" : 5.3305202,
"z" : 1.3762228
},
"rotation" : {
"quaternion" : {
"W" : 0.7071067811865476,
"X" : 0.0,
"Y" : 0.0,
"Z" : -0.7071067811865475
}
}
}
}, {
"ID" : 3,
"pose" : {
"translation" : {
"x" : 0.0039878,
"y" : 5.058536999999999,
"z" : 0.80645
},
"rotation" : {
"quaternion" : {
"W" : 1.0,
"X" : 0.0,
"Y" : 0.0,
"Z" : 0.0
}
}
}
}, {
"ID" : 4,
"pose" : {
"translation" : {
"x" : 0.0039878,
"y" : 3.5124898,
"z" : 0.80645
},
"rotation" : {
"quaternion" : {
"W" : 1.0,
"X" : 0.0,
"Y" : 0.0,
"Z" : 0.0
}
}
}
}, {
"ID" : 5,
"pose" : {
"translation" : {
"x" : 0.12110719999999998,
"y" : 1.7178274,
"z" : 0.8906002000000001
},
"rotation" : {
"quaternion" : {
"W" : 0.9196502204050923,
"X" : 0.0,
"Y" : 0.0,
"Z" : 0.39273842708457407
}
}
}
}, {
"ID" : 6,
"pose" : {
"translation" : {
"x" : 0.8733027999999999,
"y" : 0.9412985999999999,
"z" : 0.8906002000000001
},
"rotation" : {
"quaternion" : {
"W" : 0.9196502204050923,
"X" : 0.0,
"Y" : 0.0,
"Z" : 0.39273842708457407
}
}
}
}, {
"ID" : 7,
"pose" : {
"translation" : {
"x" : 1.6150844,
"y" : 0.15725139999999999,
"z" : 0.8906002000000001
},
"rotation" : {
"quaternion" : {
"W" : 0.9196502204050923,
"X" : 0.0,
"Y" : 0.0,
"Z" : 0.39273842708457407
}
}
}
}, {
"ID" : 10,
"pose" : {
"translation" : {
"x" : 16.4627306,
"y" : 0.6506718,
"z" : 0.8858503999999999
},
"rotation" : {
"quaternion" : {
"W" : 6.123233995736766E-17,
"X" : 0.0,
"Y" : 0.0,
"Z" : 1.0
}
}
}
}, {
"ID" : 11,
"pose" : {
"translation" : {
"x" : 13.2350002,
"y" : 2.743454,
"z" : 1.7254728
},
"rotation" : {
"quaternion" : {
"W" : 6.123233995736766E-17,
"X" : 0.0,
"Y" : 0.0,
"Z" : 1.0
}
}
}
}, {
"ID" : 12,
"pose" : {
"translation" : {
"x" : 13.391388000000001,
"y" : 2.8998418,
"z" : 1.3762228
},
"rotation" : {
"quaternion" : {
"W" : 0.7071067811865476,
"X" : 0.0,
"Y" : 0.0,
"Z" : 0.7071067811865475
}
}
}
}, {
"ID" : 13,
"pose" : {
"translation" : {
"x" : 16.4552122,
"y" : 3.1755079999999998,
"z" : 0.80645
},
"rotation" : {
"quaternion" : {
"W" : 6.123233995736766E-17,
"X" : 0.0,
"Y" : 0.0,
"Z" : 1.0
}
}
}
}, {
"ID" : 14,
"pose" : {
"translation" : {
"x" : 16.4552122,
"y" : 4.7171356,
"z" : 0.80645
},
"rotation" : {
"quaternion" : {
"W" : 6.123233995736766E-17,
"X" : 0.0,
"Y" : 0.0,
"Z" : 1.0
}
}
}
}, {
"ID" : 15,
"pose" : {
"translation" : {
"x" : 16.3350194,
"y" : 6.5149729999999995,
"z" : 0.8937752
},
"rotation" : {
"quaternion" : {
"W" : -0.37298778257580906,
"X" : -0.0,
"Y" : 0.0,
"Z" : 0.9278362538989199
}
}
}
}, {
"ID" : 16,
"pose" : {
"translation" : {
"x" : 15.5904946,
"y" : 7.292695599999999,
"z" : 0.8906002000000001
},
"rotation" : {
"quaternion" : {
"W" : -0.37298778257580906,
"X" : -0.0,
"Y" : 0.0,
"Z" : 0.9278362538989199
}
}
}
}, {
"ID" : 17,
"pose" : {
"translation" : {
"x" : 14.847188999999998,
"y" : 8.0691228,
"z" : 0.8906002000000001
},
"rotation" : {
"quaternion" : {
"W" : -0.37298778257580906,
"X" : -0.0,
"Y" : 0.0,
"Z" : 0.9278362538989199
}
}
}
}, {
"ID" : 40,
"pose" : {
"translation" : {
"x" : 7.874127,
"y" : 4.9131728,
"z" : 0.7032752
},
"rotation" : {
"quaternion" : {
"W" : 0.5446390350150271,
"X" : 0.0,
"Y" : 0.0,
"Z" : 0.838670567945424
}
}
}
}, {
"ID" : 41,
"pose" : {
"translation" : {
"x" : 7.4312271999999995,
"y" : 3.759327,
"z" : 0.7032752
},
"rotation" : {
"quaternion" : {
"W" : -0.20791169081775934,
"X" : -0.0,
"Y" : 0.0,
"Z" : 0.9781476007338057
}
}
}
}, {
"ID" : 42,
"pose" : {
"translation" : {
"x" : 8.585073,
"y" : 3.3164272,
"z" : 0.7032752
},
"rotation" : {
"quaternion" : {
"W" : 0.838670567945424,
"X" : 0.0,
"Y" : 0.0,
"Z" : -0.5446390350150271
}
}
}
}, {
"ID" : 43,
"pose" : {
"translation" : {
"x" : 9.0279728,
"y" : 4.470273,
"z" : 0.7032752
},
"rotation" : {
"quaternion" : {
"W" : 0.9781476007338057,
"X" : 0.0,
"Y" : 0.0,
"Z" : 0.20791169081775934
}
}
}
}, {
"ID" : 50,
"pose" : {
"translation" : {
"x" : 7.6790296,
"y" : 4.3261534,
"z" : 2.4177244
},
"rotation" : {
"quaternion" : {
"W" : 0.17729273396782605,
"X" : -0.22744989571511945,
"Y" : 0.04215534644161733,
"Z" : 0.9565859910053995
}
}
}
}, {
"ID" : 51,
"pose" : {
"translation" : {
"x" : 8.0182466,
"y" : 3.5642296,
"z" : 2.4177244
},
"rotation" : {
"quaternion" : {
"W" : -0.5510435465842192,
"X" : -0.19063969497246985,
"Y" : -0.13102303230819815,
"Z" : 0.8017733354717242
}
}
}
}, {
"ID" : 52,
"pose" : {
"translation" : {
"x" : 8.7801704,
"y" : 3.9034466,
"z" : 2.4177244
},
"rotation" : {
"quaternion" : {
"W" : -0.9565859910053994,
"X" : -0.04215534644161739,
"Y" : -0.22744989571511942,
"Z" : 0.17729273396782633
}
}
}
}, {
"ID" : 53,
"pose" : {
"translation" : {
"x" : 8.4409534,
"y" : 4.6653704,
"z" : 2.4177244
},
"rotation" : {
"quaternion" : {
"W" : 0.8017733354717241,
"X" : -0.1310230323081982,
"Y" : 0.19063969497246983,
"Z" : 0.5510435465842194
}
}
}
} ],
"field" : {
"length" : 16.4592,
"width" : 8.2296
],
"field": {
"length": 16.4592,
"width": 8.2296
}
}

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

@@ -23,16 +23,13 @@ class LoadConfigTest {
@ParameterizedTest
@EnumSource(AprilTagFields.class)
void testLoad(AprilTagFields field) {
AprilTagFieldLayout layout =
Assertions.assertDoesNotThrow(
() -> AprilTagFieldLayout.loadFromResource(field.m_resourceFile));
AprilTagFieldLayout layout = Assertions.assertDoesNotThrow(field::loadAprilTagLayoutField);
assertNotNull(layout);
}
@Test
void test2022RapidReact() throws IOException {
AprilTagFieldLayout layout =
AprilTagFieldLayout.loadFromResource(AprilTagFields.k2022RapidReact.m_resourceFile);
AprilTagFieldLayout layout = AprilTagFields.k2022RapidReact.loadAprilTagLayoutField();
// Blue Hangar Truss - Hub
Pose3d expectedPose =

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

@@ -474,6 +474,7 @@ cs::UsbCamera CameraServer::StartAutomaticCapture() {
}
cs::UsbCamera CameraServer::StartAutomaticCapture(int dev) {
::GetInstance();
cs::UsbCamera camera{fmt::format("USB Camera {}", dev), dev};
StartAutomaticCapture(camera);
auto csShared = GetCameraServerShared();
@@ -483,6 +484,7 @@ cs::UsbCamera CameraServer::StartAutomaticCapture(int dev) {
cs::UsbCamera CameraServer::StartAutomaticCapture(std::string_view name,
int dev) {
::GetInstance();
cs::UsbCamera camera{name, dev};
StartAutomaticCapture(camera);
auto csShared = GetCameraServerShared();
@@ -492,6 +494,7 @@ cs::UsbCamera CameraServer::StartAutomaticCapture(std::string_view name,
cs::UsbCamera CameraServer::StartAutomaticCapture(std::string_view name,
std::string_view path) {
::GetInstance();
cs::UsbCamera camera{name, path};
StartAutomaticCapture(camera);
auto csShared = GetCameraServerShared();
@@ -517,6 +520,7 @@ cs::AxisCamera CameraServer::AddAxisCamera(std::span<const std::string> hosts) {
cs::AxisCamera CameraServer::AddAxisCamera(std::string_view name,
std::string_view host) {
::GetInstance();
cs::AxisCamera camera{name, host};
StartAutomaticCapture(camera);
auto csShared = GetCameraServerShared();
@@ -526,6 +530,7 @@ cs::AxisCamera CameraServer::AddAxisCamera(std::string_view name,
cs::AxisCamera CameraServer::AddAxisCamera(std::string_view name,
const char* host) {
::GetInstance();
cs::AxisCamera camera{name, host};
StartAutomaticCapture(camera);
auto csShared = GetCameraServerShared();
@@ -535,6 +540,7 @@ cs::AxisCamera CameraServer::AddAxisCamera(std::string_view name,
cs::AxisCamera CameraServer::AddAxisCamera(std::string_view name,
const std::string& host) {
::GetInstance();
cs::AxisCamera camera{name, host};
StartAutomaticCapture(camera);
auto csShared = GetCameraServerShared();
@@ -544,6 +550,7 @@ cs::AxisCamera CameraServer::AddAxisCamera(std::string_view name,
cs::AxisCamera CameraServer::AddAxisCamera(std::string_view name,
std::span<const std::string> hosts) {
::GetInstance();
cs::AxisCamera camera{name, hosts};
StartAutomaticCapture(camera);
auto csShared = GetCameraServerShared();
@@ -552,10 +559,11 @@ cs::AxisCamera CameraServer::AddAxisCamera(std::string_view name,
}
cs::MjpegServer CameraServer::AddSwitchedCamera(std::string_view name) {
auto& inst = ::GetInstance();
// create a dummy CvSource
cs::CvSource source{name, cs::VideoMode::PixelFormat::kMJPEG, 160, 120, 30};
cs::MjpegServer server = StartAutomaticCapture(source);
::GetInstance().m_fixedSources[server.GetHandle()] = source.GetHandle();
inst.m_fixedSources[server.GetHandle()] = source.GetHandle();
return server;
}
@@ -632,6 +640,7 @@ cs::CvSink CameraServer::GetVideo(std::string_view name) {
cs::CvSource CameraServer::PutVideo(std::string_view name, int width,
int height) {
::GetInstance();
cs::CvSource source{name, cs::VideoMode::kMJPEG, width, height, 30};
StartAutomaticCapture(source);
return source;
@@ -648,6 +657,7 @@ cs::MjpegServer CameraServer::AddServer(std::string_view name) {
}
cs::MjpegServer CameraServer::AddServer(std::string_view name, int port) {
::GetInstance();
cs::MjpegServer server{name, port};
AddServer(server);
return server;

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>
@@ -104,6 +104,8 @@ static void DisplayMainMenu() {
ImGui::Text("v%s", GetWPILibVersion());
ImGui::Separator();
ImGui::Text("Save location: %s", glass::GetStorageDir().c_str());
ImGui::Text("%.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate,
ImGui::GetIO().Framerate);
if (ImGui::Button("Close")) {
ImGui::CloseCurrentPopup();
}

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

@@ -2,9 +2,18 @@
"game": "FIRST Power Up",
"field-image": "2018-field.jpg",
"field-corners": {
"top-left": [125, 20],
"bottom-right": [827, 370]
"top-left": [
125,
20
],
"bottom-right": [
827,
370
]
},
"field-size": [54, 27],
"field-size": [
54,
27
],
"field-unit": "feet"
}

View File

@@ -1,10 +1,19 @@
{
"game" : "Destination: Deep Space",
"field-image" : "2019-field.jpg",
"field-corners": {
"top-left" : [217, 40],
"bottom-right" : [1372, 615]
},
"field-size" : [54, 27],
"field-unit" : "foot"
"game": "Destination: Deep Space",
"field-image": "2019-field.jpg",
"field-corners": {
"top-left": [
217,
40
],
"bottom-right": [
1372,
615
]
},
"field-size": [
54,
27
],
"field-unit": "foot"
}

View File

@@ -1,10 +1,19 @@
{
"game" : "Infinite Recharge",
"field-image" : "2020-field.png",
"field-corners": {
"top-left" : [96, 25],
"bottom-right" : [1040, 514]
},
"field-size" : [52.4375, 26.9375],
"field-unit" : "foot"
}
"game": "Infinite Recharge",
"field-image": "2020-field.png",
"field-corners": {
"top-left": [
96,
25
],
"bottom-right": [
1040,
514
]
},
"field-size": [
52.4375,
26.9375
],
"field-unit": "foot"
}

View File

@@ -1,10 +1,19 @@
{
"game": "Barrel Racing Path",
"field-image": "2021-barrel.png",
"field-corners": {
"top-left": [20, 20],
"bottom-right": [780, 400]
},
"field-size": [30, 15],
"field-unit": "feet"
}
"game": "Barrel Racing Path",
"field-image": "2021-barrel.png",
"field-corners": {
"top-left": [
20,
20
],
"bottom-right": [
780,
400
]
},
"field-size": [
30,
15
],
"field-unit": "feet"
}

View File

@@ -1,10 +1,19 @@
{
"game": "Bounce Path",
"field-image": "2021-bounce.png",
"field-corners": {
"top-left": [20, 20],
"bottom-right": [780, 400]
},
"field-size": [30, 15],
"field-unit": "feet"
}
"game": "Bounce Path",
"field-image": "2021-bounce.png",
"field-corners": {
"top-left": [
20,
20
],
"bottom-right": [
780,
400
]
},
"field-size": [
30,
15
],
"field-unit": "feet"
}

View File

@@ -1,10 +1,19 @@
{
"game": "Galactic Search A",
"field-image": "2021-galacticsearcha.png",
"field-corners": {
"top-left": [20, 20],
"bottom-right": [780, 400]
},
"field-size": [30, 15],
"field-unit": "feet"
}
"game": "Galactic Search A",
"field-image": "2021-galacticsearcha.png",
"field-corners": {
"top-left": [
20,
20
],
"bottom-right": [
780,
400
]
},
"field-size": [
30,
15
],
"field-unit": "feet"
}

View File

@@ -1,10 +1,19 @@
{
"game": "Galactic Search B",
"field-image": "2021-galacticsearchb.png",
"field-corners": {
"top-left": [20, 20],
"bottom-right": [780, 400]
},
"field-size": [30, 15],
"field-unit": "feet"
}
"game": "Galactic Search B",
"field-image": "2021-galacticsearchb.png",
"field-corners": {
"top-left": [
20,
20
],
"bottom-right": [
780,
400
]
},
"field-size": [
30,
15
],
"field-unit": "feet"
}

View File

@@ -1,10 +1,19 @@
{
"game": "Infinite Recharge 2021",
"field-image": "2021-field.png",
"field-corners": {
"top-left": [127, 34],
"bottom-right": [1323, 649]
},
"field-size": [52.4375, 26.9375],
"field-unit": "foot"
}
"game": "Infinite Recharge 2021",
"field-image": "2021-field.png",
"field-corners": {
"top-left": [
127,
34
],
"bottom-right": [
1323,
649
]
},
"field-size": [
52.4375,
26.9375
],
"field-unit": "foot"
}

View File

@@ -1,10 +1,19 @@
{
"game": "Slalom Path",
"field-image": "2021-slalom.png",
"field-corners": {
"top-left": [20, 20],
"bottom-right": [780, 400]
},
"field-size": [30, 15],
"field-unit": "feet"
}
"game": "Slalom Path",
"field-image": "2021-slalom.png",
"field-corners": {
"top-left": [
20,
20
],
"bottom-right": [
780,
400
]
},
"field-size": [
30,
15
],
"field-unit": "feet"
}

View File

@@ -1,10 +1,19 @@
{
"game": "Rapid React",
"field-image": "2022-field.png",
"field-corners": {
"top-left": [74, 50],
"bottom-right": [1774, 900]
},
"field-size": [54, 27],
"field-unit": "foot"
}
"game": "Rapid React",
"field-image": "2022-field.png",
"field-corners": {
"top-left": [
74,
50
],
"bottom-right": [
1774,
900
]
},
"field-size": [
54,
27
],
"field-unit": "foot"
}

View File

@@ -1,10 +1,19 @@
{
"game": "Charged Up",
"field-image": "2023-field.png",
"field-corners": {
"top-left": [46, 36],
"bottom-right": [1088, 544]
},
"field-size": [54.27083, 26.2916],
"field-unit": "foot"
}
"game": "Charged Up",
"field-image": "2023-field.png",
"field-corners": {
"top-left": [
46,
36
],
"bottom-right": [
1088,
544
]
},
"field-size": [
54.27083,
26.2916
],
"field-unit": "foot"
}

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

@@ -52,6 +52,8 @@ static bool gSetEnterKey = false;
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) {
@@ -69,27 +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_EVENT_LOGMESSAGE);
gui::AddEarlyExecute([poller] {
nt::AddPolledListener(poller, inst, NT_EVENT_CONNECTION | NT_EVENT_IMMEDIATE);
nt::AddPolledLogger(poller, 0, 100);
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) {
@@ -98,11 +119,17 @@ static void NtInitialize() {
level = "ERROR: ";
} else if (msg->level >= NT_LOG_WARNING) {
level = "WARNING: ";
} else if (msg->level < NT_LOG_INFO && !gNetworkTablesDebugLog) {
continue;
}
gNetworkTablesLog.Append(fmt::format(
"{}{} ({}:{})\n", level, msg->message, msg->filename, msg->line));
}
}
if (updateTitle) {
glfwSetWindowTitle(win, MakeTitle(inst, connectionEvent).c_str());
}
});
gNetworkTablesLogWindow = std::make_unique<glass::Window>(
@@ -232,6 +259,8 @@ int main(int argc, char** argv) {
if (gNetworkTablesLogWindow) {
gNetworkTablesLogWindow->DisplayMenuItem("NetworkTables Log");
}
ImGui::MenuItem("NetworkTables Debug Logging", nullptr,
&gNetworkTablesDebugLog);
ImGui::Separator();
gNtProvider->DisplayMenu();
ImGui::EndMenu();
@@ -265,6 +294,8 @@ int main(int argc, char** argv) {
ImGui::Text("v%s", GetWPILibVersion());
ImGui::Separator();
ImGui::Text("Save location: %s", glass::GetStorageDir().c_str());
ImGui::Text("%.3f ms/frame (%.1f FPS)",
1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
if (ImGui::Button("Close")) {
ImGui::CloseCurrentPopup();
}

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);
}

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