Compare commits

...

1259 Commits

Author SHA1 Message Date
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
Doug Wegscheid
cf1a411acf [examples] Add example programs for AprilTags detection (#4932)
Co-authored-by: Peter Johnson <johnson.peter@gmail.com>
2023-01-13 23:08:45 -08:00
sciencewhiz
1e05b21ab5 [wpimath] Fix PID atSetpoint to not return true prematurely (#4906)
Wait until setpoint and measurement have been set.
2023-01-13 22:26:30 -08:00
ohowe
e5a6197633 [wpimath] Fix SwerveDriveKinematics not initializing a new array each time (#4942)
This is problematic if you call it twice before utilizing the result.
2023-01-13 20:16:50 -08:00
Peter Johnson
039edcc23f [ntcore] Queue current value on subscriber creation (#4938)
This fixes a potential race condition in code that only uses readQueue.
2023-01-13 20:07:24 -08:00
Matt
f7f19207e0 [wpimath] Allow multiple vision measurements from same timestamp (#4917)
Co-authored-by: Jordan McMichael <jlmcmchl@gmail.com>
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2023-01-11 23:04:30 -08:00
Starlight220
befd12911c [commands] Delete UB-causing rvalue variants of CommandPtr methods (#4923)
Co-authored-by: Ryan Blue <ryanzblue@gmail.com>
2023-01-11 22:53:04 -08:00
superpenguin612
34519de60a [commands] Fix spacing in command composition exception (#4924) 2023-01-11 11:46:33 -08:00
Ryan Blue
dc4355c031 [hal] Add handle constructor and name getters for sim devices (#4925) 2023-01-11 11:45:15 -08:00
Ryan Blue
53d8d33bca [hal, wpilibj] Add missing distance per pulse functions to EncoderSim (#4928)
Also fix C++ and Java EncoderSim.setDistancePerPulse() not propagating value to SimEncoderData.
2023-01-11 11:43:56 -08:00
bovlb
530ae40614 [apriltag] Explain what April tag poses represent (NFC) (#4930) 2023-01-11 11:42:30 -08:00
Starlight220
79f565191e [examples] DigitalCommunication, I2CCommunication: Add tests (#4865) 2023-01-08 16:33:53 -08:00
Starlight220
2cd9be413f [wpilib, examples] Cleanup PotentiometerPID, Ultrasonic, UltrasonicPID examples (#4893)
Fix C++ Ultrasonic to return correct units.
2023-01-08 16:33:07 -08:00
Matt
babb0c1fcf [apriltag] Add 2023 field layout JSON (#4912) 2023-01-08 16:30:45 -08:00
ohowe
330ba45f9c [wpimath] Fix swerve kinematics util classes equals function (#4907)
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2023-01-08 16:29:35 -08:00
sciencewhiz
51272ef6b3 [fieldImages] Add 2023 field (#4915) 2023-01-08 16:28:25 -08:00
Starlight220
0d105ab771 [commands] Deduplicate command test utils (#4897) 2023-01-08 07:44:53 -08:00
Tyler Veness
cf4235ea36 [wpiutil] Guard MSVC pragma in SymbolExports.h (#4911)
MinGW gives an unknown pragma warning on Windows.
2023-01-07 16:41:40 -08:00
Ryan Blue
2d4b7b9147 [build] Update opencv version in opencv.gradle (#4909) 2023-01-06 18:09:58 -08:00
Peter Johnson
aec6f3d506 [ntcore] Fix client flush behavior (#4903)
We need to ignore per-publisher send periods when flushing.

Also fix NT4 client to use flush async's (same as NT3 client).
2023-01-04 23:36:26 -08:00
Peter Johnson
bfe346c76a [build] Fix cmake java resources (#4898)
These need to be relative paths, but GLOB generates absolute paths by
default.
2023-01-04 08:16:47 -08:00
Ryan Blue
83f1860047 [wpilib] Add/update documentation to PneumaticBase and subclasses (NFC) (#4881)
Co-authored-by: Starlight220 <53231611+Starlight220@users.noreply.github.com>
2023-01-02 10:23:59 -08:00
Dustin Spicuzza
9872e676d8 [commands] Make Subsystem destructor virtual (#4892)
C++ best practice if there are other functions that are virtual.
2023-01-02 07:59:12 -08:00
Dustin Spicuzza
25db20e49d [hal] Fix segfault in various HAL functions (#4891) 2023-01-01 23:19:04 -08:00
ohowe
b0c6724eed [glass] Add hamburger menu icon to titlebars (#4874)
This does the same thing as right clicking, but provides a visual indicator.
The icon disappears if the window is too small or docked (right click keeps working).
2023-01-01 20:05:09 -08:00
Tyler Veness
f0fa8205ac Add missing compiler flags and fix warnings (#4889)
This makes the build fail on warnings. It caught two out-of-bounds reads
and a deprecation warning.
2023-01-01 08:14:19 -08:00
Dustin Spicuzza
42fc4cb6bc [wpiutil] SafeThread: Provide start/stop hooks (#4880)
Co-authored-by: David Vo <auscompgeek@users.noreply.github.com>
2022-12-31 15:40:45 -08:00
Sriman Achanta
cc166c98d2 [templates] Add Command-based skeleton template (#4861)
Co-authored-by: Starlight220 <53231611+Starlight220@users.noreply.github.com>
2022-12-31 13:18:43 -08:00
Thad House
3f51f10ad3 [build] Update to 2023v3 image (#4886) 2022-12-31 13:16:41 -08:00
Peter Johnson
1562eae74a [ntcore] Refactor meta-topic decoding from glass (#4809) 2022-12-31 12:01:51 -08:00
Thad House
b632b288a3 Fix usages of std::min and std::max to be windows safe (#4887) 2022-12-31 12:00:45 -08:00
Dustin Spicuzza
c11bd2720f [wpilibc] Add internal function to reset Shuffleboard instance (#4884)
Needed for RobotPy test framework.
2022-12-31 10:43:48 -08:00
Peter Johnson
f1151d375f [ntcore] Add method to get server time offset (#4847)
Also exposes this as an event signaled when the offset is updated due to
a ping response from the server.
2022-12-30 20:15:57 -08:00
Ryan Blue
fe1b62647f [hal,wpilib] Update documentation for getComments (NFC) (#4879) 2022-12-30 04:15:37 -08:00
Thad House
c49a45abbd [build] Fix examples linking in incorrect jni library (#4873) 2022-12-29 08:07:59 -06:00
Griffin Della Grotte
bc3d01a721 [build] Add platform check to doxygen plugin (#4862)
This allows the build to work on aarch64 and other platforms without downloadable doxygen binaries.
2022-12-27 22:43:21 -06:00
Ryan Blue
bc473240ae Add Jetbrains Fleet folder to .gitignore (#4872) 2022-12-27 22:41:13 -06:00
Tyler Veness
2121bd5fb8 [wpimath] Remove RKF45 (#4870)
RKDP is strictly better in terms of accuracy per unit of work. We used
RKF45 for sim physics in the 2021 season, but we transitioned to RKDP
before the 2022 season.
2022-12-27 19:29:59 -06:00
Griffin Della Grotte
835f8470d6 [build] Fix roborio cross-compiler on arm hosts (#4864) 2022-12-27 10:26:53 -08:00
Peter Johnson
6cfe5de00d [ntcore] Don't deadlock server on early destroy (#4863)
It was possible to deadlock on instance destroy if the server had started
but had not yet fully initialized its handles.
2022-12-27 10:25:48 -08:00
Ryan Blue
2ac41f3edc [hal, wpilib] Add RobotController.getComments() (#4463) 2022-12-26 11:39:51 -08:00
Sriman Achanta
26bdbf3d41 Java optimization and formatting fixes (#4857) 2022-12-26 11:37:53 -08:00
Sriman Achanta
92149efa11 Spelling and grammar cleanups (#4849) 2022-12-26 11:32:13 -08:00
Ryan Blue
176fddeb4c [commands] Add functions to HID classes to allow use of axes as BooleanEvents/Triggers (#4762) 2022-12-26 11:29:14 -08:00
Starlight220
87a34af367 [templates] Add bindings to command-based template (#4838) 2022-12-26 11:28:06 -08:00
Starlight220
4534e75787 [examples] Remove redundant MotorControl example (#4837)
The MotorControlEncoder had the exact same content, with the addition of an encoder. No point in having both examples.
2022-12-26 11:27:20 -08:00
Griffin Della Grotte
1cbebaa2f7 [commands] Remove final semicolon from test macro definition (#4859) 2022-12-26 00:14:59 -06:00
Ryan Blue
6efb9ee405 [commands] Add constructor for SwerveControllerCommand that takes a HolonomicDriveController (#4785)
Also adds copy and move constructors to HolonomicDriveController.
2022-12-25 18:48:27 -08:00
Thad House
1e7fcd5637 [cscore] Change run loop functions to not be mac specific (#4854) 2022-12-25 13:37:59 -06:00
Peter Johnson
1f940e2b60 [apriltag] Add C++ wrappers, rewrite Java/JNI to match (#4842)
This provides a consistent class-based interface to the underlying C
library from both C++ and Java.

Co-authored-by: Matt <matthew.morley.ca@gmail.com>
2022-12-25 08:15:43 -08:00
Starlight220
a6d127aedf [build] Add missing task dependency in wpilibjExamples (#4852) 2022-12-25 07:37:10 -08:00
Thad House
b893b3d6d3 [cscore] Add support for USB cameras on macOS (#4846)
The main restriction is there must be an event loop running on the main thread.
No special action is required for GUI applications, but for non-GUI applications, a
RunOsxRunLoop() function is provided that needs to be called from the main thread.
2022-12-25 07:36:00 -08:00
Peter Johnson
1696a490fa [glass] Add support for alternate NT ports (#4848) 2022-12-24 20:18:07 -06:00
Peter Johnson
40a22d69bc [glass] Add support for alternate NT ports (#4848) 2022-12-24 20:17:45 -06:00
Sriman Achanta
e84dbfede0 [wpilib] GenericHID: Add rumble both option (#4843) 2022-12-24 11:28:52 -08:00
CarloWoolsey
8aa9dbfa90 [examples] Link apriltag package in examples build.gradle (#4845) 2022-12-23 20:04:59 -06:00
Ryan Blue
eda2fa8a17 [build] Update Spotless (#4840)
Removes JVM args workaround needed for old version of spotless to run on JDK 17.

2 files had formatting updates.
2022-12-21 08:54:41 -06:00
sciencewhiz
d20594db0d Fix typos (#4839) 2022-12-21 08:53:00 -06:00
Ryan Blue
dd8ecfdd54 [commands] Fix typo in waitUntil docs (NFC) (#4841) 2022-12-21 08:24:25 -06:00
Thad House
17ceebfff4 [apriltag] Clean up apriltag JNI (#4823) 2022-12-19 21:06:36 -08:00
Ryan Blue
8b74ab389d [examples] RapidReactCommandBot: Fix array indices (#4833) 2022-12-18 16:54:37 -06:00
David Vo
1aad3489c2 [sim] Implement PD total current and power (#4830) 2022-12-18 08:00:31 -06:00
Ashray._.g
2744991771 [wpimath] Fix docs in SwerveModulePosition (#4825)
Changed m/s and speeds to m and distance.
2022-12-16 05:48:20 -08:00
Peter Johnson
ffbf6a1fa2 [commands] Disable regularly failing unit test (#4824) 2022-12-15 21:53:08 -08:00
Starlight220
fbabd0ef15 [commands] Enhance Command Sendable implementations (#4822) 2022-12-15 18:28:52 -08:00
Thad House
7713f68772 [hal] Use atomic rather then mutex for DS Data updates (#4787)
Using an atomic here means we are never going against a lock that is touchable from user code. That should make reading the DS data from the DS callback even safer.
2022-12-15 18:27:52 -08:00
Starlight220
701995d6cc [examples] Update Command-based starter project (#4778) 2022-12-15 09:40:14 -08:00
Thad House
bf7068ac27 [wpilibc] Add missing PPS implementation for C++ (#4821) 2022-12-15 09:28:42 -08:00
Peter Johnson
aae0f52ca6 [ntcore] NetworkTable: fix visibility of get/set value (#4820) 2022-12-14 19:43:53 -08:00
Thad House
ee02fb7ba7 [hal] Add support for Pulse-Per-Second signal (#4819) 2022-12-14 18:15:34 -08:00
Thad House
518916ba02 [wpilib] Fix DS mode thread event being manual reset accidentally (#4818)
These need to be automatic reset.
2022-12-14 10:17:13 -08:00
Thad House
3997c6635b [hal] Update to new image, use new TCP notify callback and new duty cycle API (#4774) 2022-12-13 22:37:42 -08:00
Michael Leong
cc8675a4e5 [examples] Add comment on how to view elevator sim (NFC) (#4482) 2022-12-13 22:34:00 -08:00
Peter Johnson
fb2c170b6e [ntcore] Simplify local startup (#4803)
The current approach was slightly more efficient but didn't correctly
handle meta-topic publishing for topics published before the server was
started.
2022-12-13 22:31:44 -08:00
shueja-personal
7ba8a9ee1f [wpimath] ProfiledPIDController: Add to SendableRegistry (#4656)
Co-authored-by: Ryan Blue <ryanzblue@gmail.com>
2022-12-13 22:31:06 -08:00
Sriman Achanta
c569d8e523 [wpilib] Joystick.getMagnitude(): use hypot() function (#4816) 2022-12-13 22:29:09 -08:00
bovlb
2a5e89fa97 [apriltag] Improve description of pose coordinates (NFC) (#4810)
The "bottom-left" language appears to be based on [a 2-D diagram  on another page](https://docs.wpilib.org/en/stable/docs/software/advanced-controls/geometry/coordinate-systems.html) and doesn't seem very helpful here.
2022-12-13 22:27:43 -08:00
Drew Williams
cc003c6c38 [apriltag] Fix AprilTagFieldLayout JSON name (#4814) 2022-12-13 22:27:08 -08:00
Sriman Achanta
5522916123 [commands] CommandXBoxController bumper documentation fix (NFC) (#4815) 2022-12-13 22:26:35 -08:00
Peter Johnson
967b30de3a [glass] Fix NT view UpdateClients() bug (#4808)
If UpdateClients() was called in the same update batch as an entry
removal, it could crash in GetEntry() due to a null entry caused by
deletion before a removal erase pass was made.
2022-12-12 23:38:36 -08:00
Tyler Veness
3270d4fc86 [wpimath] Rewrite pose estimator docs (#4807) 2022-12-12 20:30:52 -08:00
Thad House
be39678447 [apriltag] Add test to ensure apriltagjni loads (#4805) 2022-12-12 20:30:25 -08:00
Starlight220
61c75deb2a [commands] Test no-op behavior of scheduling a scheduled command (#4806) 2022-12-12 20:29:47 -08:00
Peter Johnson
a865f48e96 [ntcore] Pass pub/sub options as a unified PubSubOptions struct (#4794)
In Java, PubSubOption is still used for passing options, but this
simplifies C++ use substantially, as it allows aggregate construction.
2022-12-12 19:28:15 -08:00
Ryan Blue
f66a667321 [commands] Fix incorrect Trigger docs (NFC) (#4792) 2022-12-12 15:38:29 -08:00
Peter Johnson
f8d4e9866e [ntcore] Clean up ntcore_test.h (#4804)
The RPC functions are no longer implemented.

Also make header C-safe.
2022-12-12 15:36:54 -08:00
Tyler Veness
7e84ea891f [wpimath] Fix ComputerVisionUtil transform example in parameter docs (NFC) (#4800) 2022-12-11 22:44:08 -08:00
Charlie
da3ec1be10 [wpimath] Change terminology for ArmFeedforward gravity gain (NFC) (#4791) 2022-12-11 22:43:44 -08:00
Ryan Blue
944dd7265d [wpilibc] Add C++ Notifier error handling, update java notifier error message (#4795) 2022-12-11 22:42:22 -08:00
Ryan Blue
6948cea67a [wpiutil] Fix MemoryBuffer initialization (#4797)
Dereferencing an end iterator is undefined behavior and causes a failed assertion when running in Windows debug.
2022-12-11 07:39:04 -08:00
Ryan Blue
a31459bce6 [wpiutil] Fix UnescapeCString overflow when inputSize < 2 (#4796)
Add tests for empty, small, and string without escapes.
2022-12-11 07:36:38 -08:00
ohowe
4a0ad6b48c [wpimath] Rotation2d: Add reference to angleModulus in docs (NFC) (#4786) 2022-12-09 23:35:15 -08:00
Peter Johnson
e6552d272e [ntcore] Remove table multi-subscriber (#4789)
This wasn't well thought out, and leaks horribly in Java.

Reverts part of #4640.
2022-12-09 21:25:29 -08:00
Ryan Blue
bde383f763 [hal] Replace const char* with std::string_view in Driver Station sim functions (#4532) 2022-12-09 13:10:23 -08:00
Ryan Blue
5a52b51443 [hal] Add RobotController.getSerialNumber() (#4783) 2022-12-08 21:58:55 -08:00
Thad House
69a66ec5ec [wpilib] Fix multiple motor safety issues (#4784)
Java was missing the motor safety thread entirely
C++ accidentally used a manual reset event, causing the motor safety thread to spin.
C++ PWMMotorController would not feed the watch kitty.
Both languages would call feed() from the StopMotor call, causing some ping ponging.
2022-12-08 19:47:47 -08:00
sciencewhiz
989c9fb29a [wpimath] Revert Rotation2D change that limits angles (#4781)
Reverts "[wpimath] Constrain Rotation2d range to -pi to pi (#4611)"
This reverts commit d1d458db2b.

This broke multiple teams code in beta. It is also easier to limit the angle externally, then reconstruct a larger angle that got limited. This additionally adds comments to clarify the behavior and retains tests that were added in the reverted commit, and fixes a javadoc comment angle reference.
2022-12-08 18:10:44 -08:00
Peter Johnson
0f5b08ec69 [wpigui] Update imgui to 1.89.1+ (#4780) 2022-12-08 00:24:27 -08:00
Starlight220
fba191099c [examples] AddressableLED: Add unit test (#4779) 2022-12-07 21:47:47 -08:00
Peter Johnson
b390cad095 [wpilibj] Consistently use ErrorMessages.requireNonNullParam (#4776)
Also remove wpilibj version of ErrorMessages and consistently use static import.
2022-12-07 21:46:26 -08:00
Peter Johnson
b9772214d9 [wpilib] Sendable: Don't call setter for getter changes 2022-12-07 21:29:51 -08:00
Peter Johnson
342c375a71 [ntcore] Add subscriber option to exclude single publisher
This enables limited self-exclusion for entries seeing their own changes
or similarly with a pub/sub pair.
2022-12-07 21:29:51 -08:00
Peter Johnson
b0e4053087 [ntcore] Use int for options instead of double
Periodic time is stored in milliseconds.
2022-12-07 21:29:51 -08:00
Peter Johnson
f3e666b7bb [cscore] Convert YUYV and UYVY directly to grayscale (#4777)
This is significantly more efficient than converting by way of BGR.
2022-12-07 10:36:40 -08:00
William Toth
b300518bd1 [hal] Add CAN Stream API to Java through JNI bindings (#4193)
The CAN Stream API allows defining an buffer to receive an
arbitrary set of CAN messages, based on an ID and a mask. Messages
are added to this queue separate of other CAN APIs. This means the
messages can be receive without impacting other APIs such as
vendor APIs.

This enables things like detection of what devices are on the
bus, or custom decoding, without using vendor APIs.

Co-authored-by: Thad House <thadhouse1@gmail.com>
2022-12-06 21:58:09 -08:00
Peter Johnson
be27171236 [wpilibj] Shuffleboard: Check for null sendable (#4772)
Adding a null sendable to a container could result in a delayed NullPointerException.
2022-12-06 21:14:09 -08:00
Starlight220
4bbdbdfb48 [commands] Move GroupedCommands to CommandScheduler (#4728)
Move the command group checking functionality from CommandGroupBase into CommandScheduler.
Update references to grouping as composition for clarity (because explicitly grouping isn't the only way to do it).
Deprecate the static factory methods parallel, race, and deadline in CommandGroupBase in favor of the identical ones in Commands.
2022-12-06 21:13:31 -08:00
Tyler Veness
f18fd41ac3 [wpimath] Remove broken and obsoleted ComputerVisionUtil functions (#4775)
The ComputerVisionUtil class was added before AprilTag support was
announced. Now that it has, the functions for estimating a pose from
range and yaw are no longer needed; it's just better to get the pose
directly from the AprilTag.

The coordinate system on some function arguments was confusing or didn't
match the NWU convention the rest of the library uses. It's easier to
remove the functions now and add them back after they're fixed since the
fixes aren't trivial.

The range function was removed because it uses pitch and yaw in the
camera's spherical coordinate system, which is obsoleted by AprilTags.
AprilTags give you a 6DOF pose directly, so range can be obtained via
Pose2d.getTranslation().getDistance().

Fixes #4757.
2022-12-06 21:11:27 -08:00
Peter Johnson
2d0faecf4f [glass] DataSource: Add spinlock to protect value (#4771)
A lock is needed here due to HAL async callbacks.
2022-12-06 21:09:14 -08:00
Peter Johnson
348bd107fc [hal] Add CANManufacturer for The Thrifty Bot (#4773) 2022-12-06 21:08:45 -08:00
Starlight220
3149dc64b8 [examples] HatchbotInlined: Use Subsystem factories (#4765) 2022-12-06 15:10:39 -08:00
Jordan McMichael
8618dd4160 [glass, wpilib] Replace remaining references to Speed Controller with Motor Controller (#4769) 2022-12-05 20:06:43 -08:00
Peter Johnson
72e21a1ed1 [apriltag] Use wpilibsuite fork of apriltag (#4764) 2022-12-05 19:59:24 -08:00
Ryan Blue
eab0d929e6 [commands] CommandGenericHID POV methods: Fix docs (NFC) (#4760) 2022-12-05 13:46:46 -08:00
Ryan Blue
6789869663 [wpilib] Call set(0) rather than disable for stopMotor (#4763)
For PWM motor controllers, this is going to be the fastest way to stop the motor,
as disabling the PWM output will have a small delay due to the motor controller
needing to detect the missing signal.

Note Set(0) is not a safe approach for CAN motor controllers, which may have closed
loop operation, non-% output set() calls, etc.
2022-12-05 13:33:54 -08:00
Dustin Spicuzza
c9dea2968d [cscore] Emit warning that USB Camera isn't supported on OSX (#4766)
Reduces user confusion, as right now there's really no indication that something is wrong other than there's no camera,
2022-12-05 13:30:13 -08:00
sciencewhiz
8f402645f5 [commands] Fix PIDSubsystem setSetpoint behavior (#4759)
No longer stores a temporary setpoint in PIDSubsystem, instead
immediately sending to PIDController. This fixes an issue where the
setpoint didn't take effect until the Subsystem Periodic method ran, and
could cause commands to finish early if they were scheduled after the
subsystem periodic method ran because it used the old setpoint.
2022-12-03 11:32:46 -08:00
Tyler Veness
f24ad1d715 [build] Upgrade to googletest 1.12.1 (#4752)
This fixes GCC 12 warnings for googletest internals.
2022-12-03 11:32:08 -08:00
Jaci Brunning
ff88756864 [wpimath] Add new DCMotor functions for alternative calculations and reduction calculation (#4749) 2022-12-03 09:47:16 -08:00
superpenguin612
f58873db8e [wpimath] Remove extra terms in matrix for pose estimator docs (#4756) 2022-12-03 09:46:34 -08:00
superpenguin612
37e969b41a [wpimath] Add constructors to pose estimators with default standard deviations (#4754) 2022-12-03 09:46:10 -08:00
Tyler Veness
13cdc29382 [ci] Rename comment command from "/wpiformat" to "/format" (#4755)
It now runs more than just wpiformat.
2022-12-02 18:24:06 -08:00
Tyler Veness
6e23985ae6 [examples] Add main include directory to test builds (#4751)
This fixes the following compilation errors:
```
/home/tav/frc/wpilib/allwpilib/wpilibcExamples/src/main/cpp/examples/UnitTest/cpp/subsystems/Intake.cpp:5:10: fatal error: subsystems/Intake.h: No such file or directory
    5 | #include "subsystems/Intake.h"
      |          ^~~~~~~~~~~~~~~~~~~~~

/home/tav/frc/wpilib/allwpilib/wpilibcExamples/src/test/cpp/examples/UnitTest/cpp/subsystems/IntakeTest.cpp:11:10: fatal error: Constants.h: No such file or directory
   11 | #include "Constants.h"
      |          ^~~~~~~~~~~~~
```
2022-12-02 10:37:49 -08:00
Starlight220
66bb0ffb2c [examples] Add unit testing infrastructure (#4646) 2022-12-02 08:40:14 -08:00
Tyler Veness
74cc86c4c5 [wpimath] Make transform tests use pose/transform equality operators (#4675)
Also add more nonzeros to Transform3d tests to make them more
comprehensive.
2022-12-02 08:36:57 -08:00
Jordan McMichael
e22d8cc343 [wpimath] Use Odometry for internal state in Pose Estimation (#4668)
This effectively replaces the Unscented Kalman Filter used for Pose Estimation with the Odometry model, and uses a recalculable Kalman gain matrix to update pose estimations whenever a vision measurement is added.

Notably, this change removes the need for the confusing generics used in Java, and the C++ implementation got quite a bit less complex as well.

Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2022-12-02 08:36:10 -08:00
Ryan Blue
68dba92630 [ci] Update mac and windows builds to Java 17 (#4750) 2022-12-02 08:31:38 -08:00
Tyler Veness
23bfc2d9ab [sim] Remove unmaintained Gazebo support (#4736) 2022-12-01 20:46:47 -08:00
Starlight220
1f1461e254 [wpilib] Add method to enable/disable LiveWindow in test mode (#4678) 2022-12-01 13:28:06 -08:00
Tyler Veness
eae68fc165 [wpimath] Add tolerance for Rotation3d rotation matrix special orthogonality (#4744) 2022-11-30 19:51:31 -08:00
Tyler Veness
4c4545fb4b [apriltag] Suppress warning (#4743) 2022-11-30 19:51:18 -08:00
Tyler Veness
16ffaa754d [docs] Generate docs for apriltag subproject (#4745) 2022-11-30 19:50:52 -08:00
Thad House
5e74ff26d8 [apriltag, build] Update native utils, add apriltag impl and JNI (#4733)
Co-authored-by: Peter Johnson <johnson.peter@gmail.com>
2022-11-30 00:16:29 -08:00
Dustin Spicuzza
53875419a1 [hal] Allow overriding stderr printing by HAL_SendError (#4742) 2022-11-29 23:19:15 -08:00
Peter Johnson
aa6499e920 [ntcore] Fix special topic multi-subscriber handling (#4740)
It now matches server behavior, where "" doesn't match special topics.

Also fixes duplicate notification that could occur in some cases.
2022-11-29 21:58:57 -08:00
Peter Johnson
df70351107 [build] Fix cmake install of thirdparty includes (#4741) 2022-11-29 21:58:38 -08:00
Peter Johnson
e9bd50ff9b [glass] NT view: clear meta-topic info on disconnect (#4732) 2022-11-29 21:57:48 -08:00
Peter Johnson
9b319fd56b [ntcore] Add sub option for local vs remote changes (#4731)
This is the subscriber readQueue version of the local value listener flag.
2022-11-29 21:57:20 -08:00
Peter Johnson
18d28ec5e3 [ntcore] Remove duplicate value checking from ClientImpl
This is no longer required with the duplicate value checking in
LocalStorage.
2022-11-29 09:49:47 -08:00
Peter Johnson
bdfb625211 [ntcore] Send duplicate values to network if necessary
Essentially this separates duplicate value detection between network and
local.
2022-11-29 09:49:47 -08:00
Ryan Blue
21003e34eb [commands] Update Subsystem factories and example to return CommandBase (#4729)
Also update rapidreactcommandbot example factories to fit this convention (as in #4655).

C++ does not need an update as CommandPtr already uses CommandBase (#4677).
2022-11-28 19:47:18 -08:00
Starlight220
70080457d5 [commands] Refactor ProxyScheduleCommand, SelectCommand into ProxyCommand (#4534) 2022-11-28 14:43:10 -08:00
Colin Wong
e82cd5147b [wpilib] Tweak Color HSV formula and use in AddressableLED (#4724)
The Color algorithm was tweaked to:
a) not produce incorrect values if the user happens to input a hue outside the [0, 180) range, and
b) more accurately convert the hue remainder from range 0-30 to 0-255. The current conversion vastly overshoots the multiplier (converts 0-30 to 0-270) and relies on clamping the value when constructing the Color object to produce a slightly incorrect result.
2022-11-28 14:42:22 -08:00
Colin Wong
ec124bb662 [commands] Allow unsetting a subsystem's default command (#4621) 2022-11-28 14:03:14 -08:00
Ryan Blue
2b2aa8eef7 [examples] Update all examples to use NWU coordinate conventions (#4725) 2022-11-28 13:49:49 -08:00
Starlight220
cb38bacfe8 [commands] Revert to original Trigger implementation (#4673)
Trigger was refactored to use BooleanEvent when it was introduced in #4104.
This reverts to the original implementation until edge-based BooleanEvents can be fixed.
2022-11-28 13:48:48 -08:00
Starlight220
15561338d5 [commands] Remove one more default command isFinished check (#4727) 2022-11-28 13:44:37 -08:00
Ryan Blue
ca35a2e097 Add simgui files to .gitignore (#4726) 2022-11-28 08:57:57 -08:00
Starlight220
20dbae0cee [examples] Renovate command-based examples (#4409)
Refactor some examples to use newer features, such as HID factories, library-provided command factories, CommandPtr (C++), as well as new idioms such as static/instance command factories.
2022-11-28 08:55:13 -08:00
Eli Barnett
1a59737f40 [commands] Add convenience factories (#4460)
Co-authored-by: Starlight220 <53231611+Starlight220@users.noreply.github.com>
2022-11-28 07:41:25 -08:00
Tyler Veness
42b6d4e3f7 Use defaulted comparison operators in C++ (#4723)
Comparison operators which compared against every class member variable
now use C++20's default comparison operators.

Also remove operator!= that in C++20 is now auto-generated from operator==.
2022-11-27 21:01:01 -08:00
Peter Johnson
135c13958f [wpigui] Add FontAwesome (#4713) 2022-11-27 20:00:17 -08:00
Peter Johnson
ffbfc61532 [ntcore] Add NetworkTable table-specific listeners (#4640)
These are similar, but not quite identical to, the NT3 NetworkTable
table listeners.

Also add table topic-only multi-subscriber to ensure functions like
getKeys() work properly regardless of other subscriptions.
2022-11-27 19:46:34 -08:00
Starlight220
8958b2a4da [commands] Add property tests for command compositions (#4715) 2022-11-27 16:23:56 -08:00
Starlight220
e4ac09077c [wpilib] Add link to MotorSafety article (#4720) 2022-11-27 16:23:06 -08:00
Starlight220
f40de0c120 [commands] Add C++ factory templates (#4686) 2022-11-27 11:27:44 -08:00
Peter Johnson
51fa3e851f [build] cmake: Use FetchContent instead of ExternalProject (#4714)
Also switch to using thirdparty-fonts instead of generating them.
2022-11-26 23:05:41 -08:00
Peter Johnson
1da84b2255 [wpigui] Reload fonts to scale rather than preloading (#4712) 2022-11-26 22:30:38 -08:00
Peter Johnson
e43e2fbc84 [wpiutil] StringExtras: Add UnescapeCString (#4707)
Based on implementation in glass but enhanced for generic use.
2022-11-26 18:21:45 -08:00
Peter Johnson
5804d8fa84 [ntcore] Server: Properly handle multiple subscribers (#4717)
Previously, only the first subscriber was actually matched to a topic
when a topic was created; this was a problem when later publishing
values as a client could have both a topic-only subscriber and a normal
subscriber, and only the first one would end up being subscribed to the
topic.
2022-11-26 17:02:22 -08:00
Peter Johnson
169ef5fabf [glass] Update NT view for topicsOnly and sendAll changes (#4718) 2022-11-26 17:01:40 -08:00
Starlight220
148759ef54 [examples] CANPDP: Expand properties shown (#4687) 2022-11-25 23:51:15 -08:00
Starlight220
58ed112b51 [commands] RepeatCommand: restart on following iteration (#4706)
This fixes InstantCommand.repeatedly().
2022-11-25 23:50:42 -08:00
Ryan Blue
dd1da77d20 [readme] Fix broken CI badge (#4710) 2022-11-25 23:49:47 -08:00
Ryan Blue
7cda85df20 [build] Check Gradle plugin repo last to fix CI (#4711) 2022-11-25 23:48:18 -08:00
Thad House
7ed9b13277 [build] Bump version plugin to fix null tag (#4705) 2022-11-24 22:10:59 -08:00
Tyler Veness
6b4f26225d [apriltag] Fix pluralization of apriltag artifacts (#4671) 2022-11-24 09:06:38 -08:00
Peter Johnson
b2d2924b72 [cscore] Add Y16 image support (#4702) 2022-11-24 09:06:06 -08:00
Peter Johnson
34ec89c041 [wpilibc] Shuffleboard SimpleWidget: Return pointer instead of reference (#4703)
Based on beta test feedback, returning a pointer is more intuitive, as
typically the return value is late bound to an instance variable.
2022-11-24 09:05:37 -08:00
Peter Johnson
e15200068d [ci] Disable HW testbench runs (#4704)
These are currently broken with no timetable to fix.
2022-11-24 09:04:57 -08:00
Starlight220
d5200db6cd [wpimath] Rename HolonomicDriveController.calculate params (#4683) 2022-11-23 23:13:50 -08:00
Tyler Veness
2ee3d86de4 [wpimath] Clarify Rotation3d roll-pitch-yaw direction (#4699) 2022-11-23 23:12:59 -08:00
Peter Johnson
9f0a8b930f [cscore] Use MFVideoFormat_L8 for Gray on Windows (#4701) 2022-11-23 22:15:56 -08:00
Peter Johnson
2bca43779e [cscore] Add UYVY image support (#4700) 2022-11-23 22:00:31 -08:00
ohowe
4307d0ee8b [glass] Plot: allow for more than 11 plots (#4685)
Since m_windows is sorted using the ascii, when "Plot <10>" is reached it will be before "Plot <2>" in `m_windows` which makes it so it will not add a new plot after the id 10 is reached. This also fixes a potential issue of someone manually changing an id in the file, which would break adding a new plot in some circumstances.
2022-11-23 13:57:29 -08:00
Starlight220
3fe8d355a1 [examples] StateSpaceDifferentialDriveSimulation: Use encoder reversed constants (#4682)
This matches the Java example.
2022-11-22 10:29:40 -08:00
Peter Johnson
b44034dadc [ntcore] Allow duplicate client IDs on server (#4676)
Currently, the server rejects duplicate client IDs. As we want to make
the client implementation as simple as possible, instead deduplicate the
name on the server side by appending "@" and a count.

NT4 spec has been updated for this change.
2022-11-22 10:27:49 -08:00
Starlight220
52d2c53888 [commands] Rename Java factory wait() to waitSeconds() (#4684)
This is needed to avoid a conflict with Object.wait() when using static imports.
C++ doesn't have this issue, and has units, so Wait() still makes sense there.
2022-11-22 10:16:27 -08:00
Thad House
76e918f71e [build] Fix JNI artifacts linking to incorrect libraries (#4680) 2022-11-21 20:33:46 -08:00
Starlight220
0bee875aff [commands] Change C++ CommandPtr to use CommandBase (#4677) 2022-11-21 09:45:50 -08:00
Peter Johnson
98e922313b [glass] Don't check IsConnected for NT widgets (#4674)
Checking this isn't required, and prevented these widgets from working
in the simulation GUI without another NT client connected.
2022-11-20 17:27:28 -08:00
amquake
9a36373b8f [apriltag] Switch 2022 apriltag layout length and width values (#4670) 2022-11-19 09:11:08 -08:00
Peter Johnson
cf8faa9e67 [wpilib] Update values on controllable sendables (#4667) 2022-11-18 23:50:41 -08:00
Peter Johnson
5ec067c1f8 [ntcore] Implement keep duplicates pub/sub flag (#4666)
Also don't save duplicate NT sets to data log (unless publish keep duplicates flag is set).
2022-11-18 23:50:08 -08:00
Peter Johnson
e962fd2916 [ntcore] Allow numeric-compatible value sets (#4620)
Also fix entry publishing behavior to allow numerically compatible set
default publish following a subscribe.
2022-11-18 22:46:24 -08:00
Ryan Blue
88bd67e7de [ci] Update clang repositories to jammy (#4665) 2022-11-18 20:42:55 -08:00
Jordan McMichael
902e8686d3 [wpimath] Rework odometry APIs to improve feature parity (#4645)
Co-authored-by: Ryan Blue <ryanzblue@gmail.com>
2022-11-18 20:42:00 -08:00
Thad House
e2d49181da Update to native utils 2023.8.0 (#4664) 2022-11-18 19:01:26 -08:00
Peter Johnson
149bac55b1 [cscore] Add Arducam OV9281 exposure quirk (#4663)
Reports exposure range as 1-5000 but real range is 1-75.
2022-11-18 14:15:30 -08:00
amquake
88f7a3ccb9 [wpimath] Fix Pose relativeTo documentation (#4661) 2022-11-18 14:07:50 -08:00
sciencewhiz
8acce443f0 [examples] Fix swerve examples to use getDistance for turning encoder (#4652) 2022-11-18 14:06:21 -08:00
Peter Johnson
295a1f8f3b [ntcore] Fix WaitForListenerQueue (#4662) 2022-11-18 14:01:52 -08:00
Dustin Spicuzza
388e7a4265 [ntcore] Provide mechanism to reset internals of NT instance (#4653) 2022-11-18 10:21:05 -08:00
Tyler Veness
13aceea8dc [apriltag] Fix FieldDimensions argument order (#4659) 2022-11-17 22:15:55 -08:00
Ryan Blue
c203f3f0a9 [apriltag] Fix documentation for AprilTagFieldLayout (#4657) 2022-11-17 19:40:51 -08:00
Thad House
f54d495c90 Fix non initialized hal functionality during motor safety init (#4658) 2022-11-17 18:54:45 -08:00
Starlight220
e6392a1570 [cmd] Change factories return type to CommandBase (#4655) 2022-11-17 15:44:16 -08:00
PJ Reiniger
53904e7cf4 [apriltag] Split AprilTag functionality to a separate library (#4578)
Add AprilTagFieldLayout JSON file and move class to edu.wpi.first.apriltag.

Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2022-11-17 14:29:29 -08:00
Drew Williams
2e88a496c2 [wpimath] Add support for swerve joystick normalization (#4516) 2022-11-17 10:53:49 -08:00
Jordan McMichael
ce4c45df13 [wpimath] Rework function signatures for Pose Estimation / Odometry (#4642)
Forcing the use of SwerveModulePostition[] and wpi::array<SwerveModulePosition, len> in place of variadic function signatures.
2022-11-17 10:36:33 -08:00
sciencewhiz
0401597d3b [readme] Add wpinet to MavenArtifacts.md (#4651)
Fixes #4639
2022-11-17 10:35:27 -08:00
Jordan McMichael
2e5f9e45bb [wpimath] Remove encoder reset comments on Swerve, Mecanum Odometry and Pose Estimation (#4643)
In both of these cases, encoder resets are not required for normal use.
2022-11-16 15:20:05 -08:00
sciencewhiz
e4b5795fc7 [docs] Disable Doxygen for memory to fix search (#4636) 2022-11-14 20:19:44 -08:00
Peter Johnson
03d0ea188c [build] cmake: Add missing wpinet to installed config file (#4637) 2022-11-14 20:19:13 -08:00
Thad House
3082bd236b [build] Move version file to its own source set (#4638) 2022-11-14 20:19:00 -08:00
Thad House
b7ca860417 [build] Use build cache for sign step (#4635)
The signing step does not get passed the username and password to the server, so it will just read from the build cache. Then to make sure the tasks are all updated correctly, use if developerid exists as a property to all sign tasks, so it will see the new variable value, and relink. Additionally only update the archives during signing, which will speed up signing.
2022-11-14 19:23:13 -08:00
Starlight220
64838e6367 [commands] Remove unsafe default command isFinished check (#4411) 2022-11-14 14:28:30 -08:00
Peter Johnson
1269d2b901 [myRobot] Disable spotbugs (#4565) 2022-11-14 14:26:41 -08:00
Tyler Veness
14d8506b72 [wpimath] Fix units docs for LinearSystemId::IdentifyDrivetrainSystem() (#4600) 2022-11-14 14:26:16 -08:00
ohowe
d1d458db2b [wpimath] Constrain Rotation2d range to -pi to pi (#4611)
Co-authored-by: Ryan Blue <ryanzblue@gmail.com>
2022-11-14 14:25:15 -08:00
Tyler Veness
f656e99245 [readme] Add links to development build documentation (#4481)
* Add links to development build documentation
* Use GitHub dev docs links in readme badges
2022-11-14 14:23:47 -08:00
Starlight220
6dd937cef7 [commands] Fix Trigger API docs (NFC) (#4599) 2022-11-14 14:21:35 -08:00
Starlight220
49047c85b9 [commands] Report error on C++ CommandPtr use-after-move (#4575) 2022-11-14 14:20:52 -08:00
Tyler Veness
d07267fed1 [ci] Upgrade containers to Ubuntu 22.04 and remove libclang installation (#4633) 2022-11-14 14:20:08 -08:00
Thad House
b53ce1d3f0 [build, wpiutil] Switch macos to universal binaries (#4628) 2022-11-14 10:36:33 -08:00
Ege Akman
5a320c326b [upstream_util, wpiutil] Refactor python scripts (#4614)
Co-authored-by: Sourcery AI <>
Co-authored-by: Vasista Vovveti <vasistavovveti@gmail.com>
Co-authored-by: David Vo <auscompgeek@users.noreply.github.com>
2022-11-13 23:11:54 -08:00
Peter Johnson
c4e526d315 [glass] Fix NT Mechanism2D (#4626) 2022-11-13 23:09:23 -08:00
Ryan Blue
d122e4254f [ci] Run spotlessApply after wpiformat in comment command (#4623) 2022-11-13 14:07:26 -08:00
Peter Johnson
5a1e7ea036 [wpilibj] FieldObject2d: Add null check to close() (#4619) 2022-11-12 16:51:41 -08:00
Peter Johnson
179f569113 [ntcore] Notify locally on SetDefault (#4617)
This is necessary for the simulation GUI to pick up default publishes.
2022-11-12 06:33:10 -08:00
Peter Johnson
b0f6dc199d [wpilibc] ShuffleboardComponent.WithProperties: Update type (#4615)
ShuffleboardComponentBase::m_properties is now a StringMap<nt::Value>.
2022-11-11 15:08:05 -08:00
Tyler Veness
7836f661cd [wpimath] Add missing open curly brace to units/base.h (#4613) 2022-11-11 13:06:42 -08:00
CarloWoolsey
dbcc1de37f [wpimath] Add DifferentialDriveFeedforward classes which wrap LinearPlantInversionFeedforward (#4598)
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2022-11-10 16:54:51 -08:00
Cory
93890c528b [wpimath] Add additional angular acceleration units (#4610)
Added Turns per second squared
Added Revolutions per minute squared
Added Revolutions per minute per second
2022-11-10 16:47:55 -08:00
Tyler Veness
3d8d5936f9 [wpimath] Add macro for disabling units fmt support (#4609) 2022-11-10 14:12:07 -08:00
Tyler Veness
2b04159dec [wpimath] Update units/base.h license header (#4608) 2022-11-10 14:11:44 -08:00
Thad House
2764004fad [wpinet] Fix incorrect jni definitions (#4605)
Also re-enables the check task that would have caught this.
2022-11-10 09:42:02 -08:00
Thad House
85f1bb8f2b [wpiutil] Reenable jni check task (#4606)
New option was added to JNI plugin to allow skipping specific symbols. This let us generally reenable the check task in wpiutil.
2022-11-10 09:33:26 -08:00
ohowe
231ae2c353 [glass] Plot: Fix Y-axis not being saved (#4594) 2022-11-08 21:33:02 -08:00
Tyler Veness
e92b6dd5f9 [wpilib] Fix AprilTagFieldLayout JSON property name typos (#4597) 2022-11-08 13:27:21 -08:00
Thad House
2a8e0e1cc8 Update all dependencies that use grgit (#4596) 2022-11-08 10:20:16 -08:00
Starlight220
7d06e517e9 [commands] Move SelectCommand factory impl to header (#4581)
It's templated, so it needs to be in the header.
2022-11-07 15:49:36 -08:00
Tyler Veness
323524fed6 [wpimath] Remove deprecated units/units.h header (#4572) 2022-11-07 10:18:36 -08:00
Starlight220
d426873ed1 [commands] Add missing PS4 triangle methods (#4576) 2022-11-07 10:15:54 -08:00
PJ Reiniger
5be5869b2f [apriltags] Use map as internal data model (#4577)
This leaves the file format as a list, but internally will transform the collection of tags into a map on de/serialization. The serialization will probably happen once on startup, but the tag lookup can happen 100s of times a second. This honestly probably doesn't make too much of a performance hit since N is small, but this is a simple O(n) -> O(1) change for lookups.
2022-11-07 10:09:06 -08:00
Griffin Della Grotte
b1b4c1e9e7 [wpimath] Fix Pose3d transformBy rotation type (#4545)
Co-authored-by: Ryan Blue <ryanzblue@gmail.com>
2022-11-07 09:57:33 -08:00
Dustin Spicuzza
a4054d702f [commands] Allow composing two triggers directly (#4580)
For backwards compatibility reasons.
2022-11-07 09:55:28 -08:00
Dustin Spicuzza
0190301e09 [wpilibc] Explicitly mark EventLoop as non-copyable/non-movable (#4579)
It's already not movable because m_bindings isn't copyable, but pybind11
isn't able to detect that
2022-11-07 09:30:03 -08:00
Peter Johnson
9d1ce6a6d9 [ntcore] Catch file open error when saving preferences (#4571) 2022-11-05 21:16:39 -07:00
Peter Johnson
5005e2ca04 [ntcore] Change Java event mask to EnumSet (#4564)
Also convert NetworkTableInstance.getNetworkMode() to return EnumSet.
2022-11-04 20:25:37 -07:00
PJ Reiniger
fa44a07938 [upstream-utils][mpack] Add upstream util for mpack (#4500) 2022-11-04 20:03:49 -07:00
Peter Johnson
4ba16db645 [ntcore] Various fixes and cleanups (#4544)
* NetworkTableInstance: set handle to 0 after destroy
* Fix multiple notifications of local values
* Detect mismatch between handles
* Server: fix setting min period when no topics
* Limit maximum number of subscribers/publishers/listeners
   This helps find resource leaks and prevents them from causing excessive
   slowdowns/crashes.  The limit on each is currently set to 512.
* Don't use std::swap in move operation
2022-11-04 20:01:21 -07:00
Thad House
837415abfd [hal] Fix joysticks either crashing or returning 0 (#4570) 2022-11-04 19:03:11 -07:00
amquake
2c20fd0d09 [wpilib] SingleJointedArmSim: Check angle equals limit on wouldHit (#4567) 2022-11-04 17:14:46 -07:00
Alex Ryker
64a7136e08 [wpimath] SwerveDrivePoseEstimator: Restore comment about encoder reset (#4569) 2022-11-04 15:03:49 -07:00
Brennen Puth
b2b473b24a [wpilib] Add AprilTag and AprilTagFieldLayout (#4421)
This is an API for looking up a Pose3d from a tag id, and includes functionality to load that map from a JSON file.

This also adds JSON support to Pose3d, Rotation3d. Translation3d, and Quaternion.

Co-authored-by: Tyler Veness <calcmogul@gmail.com>
Co-authored-by: AMereBagatelle <themerebagatelle@gmail.com>
2022-11-04 09:56:22 -07:00
Thad House
7aab8fa93a [build] Update to Native Utils 2023.6.0 (#4563) 2022-11-03 20:57:04 -07:00
Starlight220
12c2851856 [commands] WrapperCommand: inherit from CommandBase (#4561)
This makes WrapperCommand Sendable.
Only Java had this issue.
2022-11-03 06:27:23 -07:00
Tyler Veness
0da169dd84 [wpimath] Remove template argument from ElevatorFeedforward (#4554) 2022-11-02 22:54:32 -07:00
Tyler Veness
2416827c25 [wpimath] Fix docs for pose estimator local measurement models (#4558) 2022-11-02 22:53:21 -07:00
Michael Jansen
1177a3522e [wpilib] Fix Xbox/PS4 POV sim for port number constructors (#4548) 2022-11-02 22:52:26 -07:00
ohowe
102344e27a [commands] HID classes: Add missing methods, tweak return types (#4557)
- Make return type of getHID reflect the specific class
- Add getX and getY to CommandJoystick
2022-11-02 22:51:53 -07:00
Peter Johnson
1831ef3e19 [wpilib] Fix Shuffleboard SuppliedValueWidget (#4559)
It was creating duplicate publishers.
2022-11-02 22:49:52 -07:00
Starlight220
a9606ce870 [wpilib] Fix Xbox/PS4 POV sim (#4546) 2022-11-02 10:52:15 -07:00
Tyler Veness
6c80d5eab3 [wpimath] Remove unused SymbolExports.h include from units/base.h (#4541) 2022-11-01 17:18:24 -07:00
Peter Johnson
b114006543 [ntcore] Unify listeners (#4536)
This combines all 4 NT listener APIs (topic, value, connection, and
logging) into a single unified listener API.
2022-10-31 21:52:14 -07:00
Peter Johnson
32fbfb7da6 [build] cmake: Install ntcore generated include files (#4540) 2022-10-31 21:45:24 -07:00
Thad House
02465920fb [build] Update native utils to 2023.4.0 (#4539)
This has some decent changes to the toolchain plugin, so allwpilib is a great way to make sure nothing breaks.
2022-10-31 19:17:42 -07:00
David K Turner
3a5a376465 [wpimath] Increase constexpr support in geometry data types (#4231)
This uses std::is_constant_evaluated() to conditionally use the gcem library for constexpr calculations.
2022-10-31 09:17:00 -07:00
Peter Johnson
1c3c86e9f1 [ntcore] Cache GetEntry(name) values (#4531)
These are typically cached at higher levels anyway, but cache at lowest
C++ layer as well for consistency with NT3.
2022-10-27 23:34:58 -07:00
Starlight220
dcda09f90a [command] Rename trigger methods (#4210)
Motivation

Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following:
- duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them.
- the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge.
- the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled".
- whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing.

Solution

Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive.

After consideration, deprecation of Button's subclasses was decided against:

- NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API.
- JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable.

At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger.

Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here:

- onTrue (replaces whenActive): schedule on rising edge.
- whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge.
- toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled.

Two binding types are completely deprecated:

- cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()).
- whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive.

Notes

It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
2022-10-27 22:03:28 -07:00
Tyler Veness
66157397c1 [wpilib] Make drive classes follow NWU axes convention (#4079)
All trigonometric functions and vector classes assume North-West-Up axes
convention, so using North-East-Down convention with them is really
error-prone. We've broken something every time we touched the drive
classes.

We originally used North-East-Down to match the joystick convention, but
the volume of long-lived bugs has made this not worth it in retrospect.

The rest of WPILib also uses North-West-Up, so this makes things
consistent.

KilloughDrive was removed since no one uses it.
2022-10-27 21:59:11 -07:00
Peter Johnson
9e22ffbebf [ntcore] Fix null deref in NT3 client (#4530) 2022-10-27 21:56:15 -07:00
Thad House
648ab6115c [wpigui,dlt,glass,ov] Support arm in GUI tools (#4527) 2022-10-26 23:16:23 -07:00
Tyler Veness
8bc3b04f5b [wpimath] Make ComputerVisionUtil use 3D geometry classes (#4528)
Closes #4189.
2022-10-26 22:20:08 -07:00
Peter Johnson
cfb84a6083 [wpilibc] Don't hang waiting for NT server to start (#4524)
This matches Java behavior.
2022-10-26 10:29:56 -07:00
Tyler Veness
02c47726e1 [wpimath] Remove unused odometry instance from DifferentialDrivePoseEstimator test (#4522) 2022-10-25 22:19:44 -07:00
Peter Johnson
b2a0093294 [ci] Revert upgrade of github-pages-deploy-action (#4521)
It broke publishing
2022-10-25 19:20:30 -07:00
Justin
2a98d6b5d7 [wpimath] PIDController: Add getters for position & velocity tolerances (#4458) 2022-10-25 16:10:19 -07:00
Starlight220
9f36301dc8 [ci] Write wpiformat patch to job summary (#4519) 2022-10-25 12:30:43 -07:00
Jordan McMichael
901fc555f4 [wpimath] Position Delta Odometry for Mecanum (#4514) 2022-10-25 12:28:59 -07:00
Jordan McMichael
4170ec6107 [wpimath] Position Delta Odometry for Swerve (#4493) 2022-10-25 12:28:36 -07:00
sciencewhiz
fe400f68c5 [docs] Add wpinet to docs build (#4517)
Excludes libuv and libuv wrappers.
2022-10-25 08:47:28 -07:00
Peter Johnson
794669b346 [ntcore] Revamp listeners (#4511)
- In both C++ and Java, add listener functions to Instance class (same as NT3 provided)
- Add WaitForListenerQueue functions (same as NT3 provided)
- Move Java non-poller implementation to Instance (previously only handled single instance)
- Change C++ listeners to take non-const references for subscribers etc to help avoid footguns from use of temporary objects (also add doc comment)
- Fix Preferences making .type persistent
2022-10-24 23:27:24 -07:00
Peter Johnson
dcfa85a5d5 [ci] Build sanitizers with clang-14 (#4518) 2022-10-24 22:44:20 -07:00
Peter Johnson
15ad855f1d [ntcore] Add UnitTopic<T> (C++ only) (#4497)
This avoids the need for explicit value() calls (as compared to using
DoubleTopic).  The unit name is published as the "unit" property.

Implementation note: the test needs to be in wpilibc because ntcore does
not depend on wpimath.
2022-10-24 20:07:44 -07:00
Thad House
11244a49d9 [wpilib] Add IsConnected function to all gyros (#4465) 2022-10-24 20:04:16 -07:00
Thad House
1d2e8eb153 [build] Update myRobot deployment (#4515) 2022-10-24 20:03:39 -07:00
Thad House
ad53fb19b4 [hal] Use new HMB api for addressable LED (#4479)
Theres is now a built in HMB api, but you have to dlopen it to access it. Moved our existing infrastructure for this to its own class, added the new functions, then updated interrupts and LEDs to use it.
2022-10-24 18:26:07 -07:00
Thad House
ba850bac3b [hal] Add more shutdown checks and motor safety shutdown (#4510) 2022-10-23 21:59:04 -07:00
Peter Johnson
023a5989f8 [ntcore] Fix typo in NetworkServer client connect message (#4512) 2022-10-23 20:45:01 -07:00
sciencewhiz
c970011ccc [docs] Add Doxygen aliases used by Foonathan memory (#4509) 2022-10-23 18:12:24 -07:00
sciencewhiz
07a43c3d9a [readme] Document clang-format version and /wpiformat (#4503) 2022-10-23 15:59:33 -07:00
sciencewhiz
a05b212b04 [ci] Revert changes to wpiformat task from #4501 (#4508) 2022-10-23 15:49:59 -07:00
Starlight220
09faf31b67 [commands] Replace Command HID inheritance with delegation (#4470) 2022-10-23 12:09:44 -07:00
Starlight220
9e1f9c1133 [commands] Add command factories (#4476)
Co-authored-by: oblarg <emichaelbarnett@gmail.com>
2022-10-23 12:08:22 -07:00
Tyler Veness
f19d2b9b84 [ci] Add NUMBER environment variable to comment command commit script (#4507) 2022-10-23 11:34:03 -07:00
Tyler Veness
a28f93863c [ci] Push comment command commit directly to PR (#4506) 2022-10-23 11:17:52 -07:00
Tyler Veness
c9f61669b8 [ci] Fix comment command commit push (#4505) 2022-10-23 10:47:15 -07:00
Tyler Veness
dcce5ad3b3 [ci] Update github-script API usage (#4504) 2022-10-23 10:15:42 -07:00
Thad House
6836e5923d [wpilibc] Restore get duty cycle scale factor (#4502) 2022-10-23 07:05:09 -07:00
Peter Johnson
335188c652 [dlt] Add deselect/select all buttons to download view (#4499) 2022-10-22 22:12:47 -07:00
Peter Johnson
60a29dcb99 [glass] Field2D: Add "hidden" option for objects (#4498) 2022-10-22 22:12:25 -07:00
PJ Reiniger
b55d5b3034 [ci] Update deprecated github actions (#4501) 2022-10-22 21:09:44 -07:00
Peter Johnson
10ed4b3969 [ntcore] Various NT4 fixes (#4474)
* TopicListener: Fix Add() return values
* Update PubSubOption poll storage documentation
* Update NetworkTableEntry::GetValue() doc
* Add documentation regarding asynchronous callbacks
* Unpublish entry: set publisher to nullptr
* Implement ValueListenerPoller default constructor
* Remove SetNetworkIdentity, make parameter to StartClient
* URI-escape client ID, improve error message
* Add connected message with client id; also improve disconnected message a bit
* Handle SetServers either before or after StartClient
* Fix client use-after-free; also delay reconnect after disconnect to rate limit
* Don't re-announce to already subscribed client; we especially don't want to send the last value again
* Always accept in-order sets, only use timestamp for tiebreak
* Fix LocalStorage::StartNetwork race
* Remove unused/unimplemented function

Also:
* [glass] Remove debug print
* [glass] Fix mpack string decoding
* [cameraserver] Fix up startclient
2022-10-21 22:04:14 -07:00
Thad House
4a401b89d7 [hal, wpilib] New DS thread model and implementation (#3787)
The current DS thread model has some pretty major issues. It makes it difficult to know if all data is from the same remote packet, and if the data changes while the robot loop is running. Additionally, the DS thread is used for a few other things (MotorSafety and State Tracking for EducationalRobot). This also makes sim difficult, as user code has to wait for the thread to know it has new data.

This change completely rethinks how threading works in the driver station model.

First, the DS HAL system receives a new data callback, either from Netcomm or DriverStationSim. Inside the context of this callback, all the low latency data is read and put into a cache. Doing some investigation on the robot side, this is perfectly safe to do, and also ensures a ds packet will not be parsed before we finish reading the current packet data.

After all data is read, the cache is swapped with a 2nd buffer. This buffer just stores the data, none of the HAL DS calls read from this buffer. An event is then fired, stating there is new data ready to go.

Robot code calls HAL_UpdateDSData(). This swaps the 2nd buffer with a 3rd buffer, which always contains the current data. This data will not be updated until HAL_UpdateDSData is called again. Which solves the state problem.

The high level driver station classes have. an updateData() call, which calls HAL_UpdateDSData, and then update button state variables, then data log and update the NT FMS data table (Java also caches across the JNI boundary here, but that could trivially be removed). An extra event provider is provided, allowing other threads to know when this call has been completed.

IterativeRobotBase calls DS.updateData() at the beginning of each loop, and only once per loop. This means all commands will always have the same state.

All of this means there is no longer a DS thread. Everything happens synchronously. This means Sim and testing is easier, as you can just call DriverStationSim.NotifyNewData(), and then DriverStation.UpdateData(), and you can guarantee that all the DriverStation.*** data is up to date.

As for Motor Safety and Educational Robot State Handling, those can all be handled by their own threads. The Educational Thread only needs to run under EducationalRobot, and MotorSafety will only be started if there is a motor safety object enabled.
2022-10-21 22:01:55 -07:00
Tyler Veness
c195b4fc46 [wpimath] Clean up PoseEstimator nominal dt docs (#4496) 2022-10-21 19:53:58 -07:00
Tyler Veness
8f2e34c6a3 [build] Remove wpilib prefix from CMake flat install (#4492)
For system installs, `DESTDIR=/usr cmake --install buildfolder` installs
libraries to `/usr/lib` with the correct rpath. Example structure:
```
/usr/include/wpimath/frc/controller/LinearQuadraticRegulator.h
/usr/lib/libwpimath.so
```

Users need to provide `-I/usr/include/wpimath` in their projects. This
is an artifact of the install() commands being in the subdirectory CMake
files.

For other locations, `DESTDIR=/opt/wpilib cmake --install buildfolder`
installs libraries to `/opt/wpilib/lib`. Example structure:
```
/opt/wpilib/include/wpimath/frc/controller/LinearQuadraticRegulator.h
/opt/wpilib/lib/libwpimath.so
```
2022-10-21 19:23:56 -07:00
Tyler Veness
150d692df7 [wpimath] Remove unused private PoseEstimator function (#4495) 2022-10-21 19:22:37 -07:00
shueja-personal
3e5bfff1b5 [wpimath] FromFieldRelativeSpeeds: Add ChassisSpeeds overload (#4494) 2022-10-21 18:58:23 -07:00
Starlight220
9c7e66a27d [commands] C++: Add CommandPtr overload for SetDefaultCommand (#4488) 2022-10-21 06:35:58 -07:00
Tyler Veness
0ca274866b [build] Fix CMake system library opt-ins (#4487)
-DUSE_SYSTEM_EIGEN now only removes include paths for Eigen instead of
drake as well.

The USE_VCPKG flags were renamed to USE_SYSTEM since they seem general
enough for that to work (the find_package() commands work the same way
on Arch).

The system libuv CMake build now works with Linux libuv as well.
2022-10-20 19:47:12 -07:00
Starlight220
dc037f8d41 [commands] Remove EndlessCommand (#4483) 2022-10-20 17:24:54 -07:00
Tyler Veness
16cdc741cf [wpimath] Add Pose3d(Pose2d) constructor (#4485) 2022-10-20 17:23:00 -07:00
Tyler Veness
9d5055176d [build] cmake: Allow disabling ntcore build (#4486) 2022-10-20 17:21:31 -07:00
Thad House
d1e66e1296 [build] Compile all java code with inline string concatenation (#4490)
Workaround identified in https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8278540
2022-10-20 17:20:36 -07:00
Tyler Veness
1fc098e696 Enable log macros to work with no args (#4475)
This is enabled by the C++20 __VA_OPT__ feature.
Uses of "{}" format string were updated.
Some warning suppressions were required for older clang versions.
Also improve codegen of wpi::Logger::Log(), frc::ReportError(), and frc::MakeError();
these generate better and less redundant code if they use fmt::string_view for the
format string instead of templating on it.
2022-10-19 10:49:27 -07:00
Peter Johnson
878cc8defb [wpilib] LiveWindow: Add enableAllTelemetry() (#4480) 2022-10-17 14:39:57 -07:00
Thad House
8153911160 [build] Fix MSVC runtime archiver to grab default runtime (#4478) 2022-10-16 15:37:13 -07:00
Tyler Veness
fbdc810887 Upgrade to C++20 (#4239)
* Use explicit this capture required by C++20
* Use C++20 span
* Replace wpi::numbers with std::numbers
* Fix C++20 clang-tidy warning false positive in fmt
* Remove ciso646 include since C++20 removed that header
* Fix global-buffer-overflow asan warnings in ntcore tests
* Add DIOSetProxy constructor to HAL

* Upgrade MSVC compiler to 2022
* Bump native-utils to 2023.2.7 (changes to std=c++20)

Co-authored-by: Peter Johnson <johnson.peter@gmail.com>
2022-10-15 16:33:14 -07:00
Thad House
396143004c [ntcore] Add ntcoreffi binary (#4471)
Co-authored-by: Peter Johnson <johnson.peter@gmail.com>
2022-10-15 01:02:38 -07:00
Peter Johnson
1f45732700 [build] Update to 2023.2.4 native-utils and new dependencies (#4473)
* Disable class-memaccess warning in Eigen
* Shim NiFpga_OpenHostMemoryBuffer
* Don't deploy .debug files in integration tests
2022-10-14 23:36:47 -07:00
Peter Johnson
574cb41c18 [ntcore] Various fixes (#4469)
* Fix C++ Publisher and Subscriber move assignment 
* Fix Publisher comment typo.
* Publish: check that properties is an object.
Print a warning, but still publish, just with empty properties.
Add error print for unassigned type publish.
* Return boolean from SetProperties
* Document exception-throw in Java for invalid JSON.
2022-10-14 20:50:55 -07:00
Thad House
d9d6c425e7 [build] Force Java 11 source compatibility (#4472)
We want to have the option of falling back to a Java 11 runtime, at least for this year.
2022-10-14 19:39:54 -07:00
Thad House
58b6484dbe Switch away from NI interrupt manager to custom implementation (#3705)
* Switch away from NI interrupt manager to custom implementation

* Formatting

* Fix tidy

* Formatting

* Fix loading

* Make interrupt api public

* Add multiple wait api

* Formatting

* Fix build

* Fix review comments

* wpiformat

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2022-10-13 17:25:54 -07:00
Tyler Veness
ca43fe2798 [wpimath] Use Units conversions in ComputerVisionUtil docs (NFC) (#4464) 2022-10-12 13:54:15 -07:00
Thad House
87a64ccedc [hal] Convert DutyCycle Raw output to be a high time measurement (#4466)
The existing raw time has an issue where it jumps around, as in the FPGA if the frequency is not a multiple or divisor of 25 Mhz it jumps around by 1 every second. While waiting on an FPGA change, update the API to make raw output give nanoseconds rather then a scaled value. This does a longer read cycle to get the correct value, but in the future if a fast FPGA function is added this can be easily changed.
2022-10-12 10:15:09 -07:00
Starlight220
89a3d00297 [commands] Add FinallyDo and HandleInterrupt decorators (#4412) 2022-10-11 09:53:27 -07:00
Starlight220
1497665f96 [commands] Add C++ versions of Java-only decorators (#4457) 2022-10-10 09:00:11 -07:00
Ryan Blue
27b173374e [wpimath] Add minLinearAccel parameter to DifferentialDriveAccelerationLimiter (#4422) 2022-10-10 08:57:37 -07:00
Ryan Blue
2a13dba8ac [wpilib] TrajectoryUtil: Fix ambiguous documentation (NFC) (#4461) 2022-10-10 08:56:40 -07:00
Peter Johnson
77301b126c [ntcore] NetworkTables 4 (#3217) 2022-10-08 10:01:31 -07:00
Peter Johnson
90cfa00115 [build] cmake: Fix libssh include directory order (#4459)
This broke the build if the directory where libssh was installed also
contained a system libuv install.
2022-10-07 22:53:22 -07:00
Starlight220
5cf961edb9 [commands] Refactor lambda-based commands to inherit FunctionalCommand (#4451) 2022-10-06 17:49:27 -05:00
Starlight220
b2276e47de [wpimath] Enable continuous angle input for HolonomicDriveController (#4453) 2022-10-06 17:46:22 -05:00
PJ Reiniger
893b46139a [fieldImages] Add utilities to simplify loading of fields (#4456) 2022-10-06 17:45:07 -05:00
Starlight220
60e29627c0 [commands] C++ unique_ptr migration (#4319)
Add a CommandPtr with an internal unique_ptr to enable not needing to move the underlying classes, which is error-prone due to the potential for lambda captures.
2022-10-05 17:19:28 -05:00
Starlight220
3b81cf6c35 [wpilib] Improve Color.toString (#4450) 2022-10-04 14:36:51 -05:00
Peter Johnson
5c067d30a0 [wpinet] WebSocket: Add SendFrames() (#4445) 2022-10-03 08:04:08 -05:00
Peter Johnson
ceaf493811 [wpiutil] MakeJByteArray: Use span<uint8> instead of string_view (#4446) 2022-10-02 08:28:50 -05:00
Starlight220
10e04e2b13 [examples] FrisbeeBot: Fix reference capture (#4449)
The parameter should be passed by value.
2022-10-02 08:18:43 -05:00
Peter Johnson
726f67c64b [build] Add exeSplitSetup (#4444) 2022-10-02 08:13:08 -05:00
Peter Johnson
c7b7624c1c [wpiutil] Add MessagePack utility functions (#4448)
Also add mpack to srcDirs.
2022-10-02 08:11:42 -05:00
Peter Johnson
d600529ec0 [wpinet] uv::Async: Add UnsafeSend() (#4447)
This version assumes the loop still exists, avoiding some overhead.
2022-10-02 08:10:54 -05:00
Tyler Veness
b53b3526a2 [wpimath] Add CoordinateSystem conversion for Transform3d (#4443)
I also refactored Pose3d's conversion implementation to use the
Translation3d and Rotation3d conversions, thereby giving Translation3d
and Rotation3d test coverage. No changes were made to the expected
values of the Pose3d conversion tests.

The expected values of the Transform3d conversion tests were copied from
the Pose3d conversion tests without modification.
2022-10-01 21:09:04 -07:00
Tyler Veness
38bb23eb18 [wpimath] Add scalar multiply and divide operators to all geometry classes (#4438)
Closes #4435.
2022-09-28 21:34:29 -07:00
Tyler Veness
3937ff8221 [wpilib] Remove deprecated Controller class (#4440)
Now that old command-based has been removed, this base class can be
removed too.
2022-09-28 21:33:55 -07:00
Oliver W
abbfe244b5 [wpilib] Improve Color FromHSV (#4439) 2022-09-28 21:33:33 -07:00
Dustin Spicuzza
4ddb8aa0dd [sim] Provide function that resets all simulation data (#4016)
Fixes #3867
2022-09-26 14:38:38 -07:00
Tyler Veness
a791470de7 Clean up Java warning suppressions (#4433)
Checkstyle naming conventions were changed to allow most of what's in
wpimath. Naming rules were disabled completely in wpimath since almost
all suppressions are for math notation.
2022-09-24 00:13:55 -07:00
Thad House
17f504f548 [hal,wpilib] Fix SPI Mode Setting (#4434)
SPI Mode setting was very broken. MSB and LSB sets did not work (MSB is the only one supported)
and if LSB was set (which was the default) the ioct to set clock phase would fail. This
deprecates all the individual functions, the LSB/MSB functions, and adds an SPI mode selection
function. This is usually more understandable, and shows up in a lot more documentation
2022-09-24 00:11:37 -07:00
Tyler Veness
773198537c [wpiutil] Add wpi::scope_exit (#4432)
This is based on std::scope_exit in the C++ library fundamentals TS v3.
2022-09-23 14:48:59 -07:00
Peter Johnson
5ac658c8f0 [wpiutil] Logger: Conditionalize around WPI_LOG (#4431)
The FMT_STRING() call used in the macro does formatter initialization,
overhead that's not required if Log() is not going to be called.
2022-09-22 23:14:46 -07:00
Peter Johnson
8767e4a941 [wpiutil] DataLog: Fix SetMetadata output (#4430) 2022-09-22 21:54:55 -07:00
Peter Johnson
8c4af073f4 [wpiutil] Synchronization: shutdown race protection (#4429) 2022-09-22 21:53:51 -07:00
Thad House
c79f38584a [build] Fix Java integration tests (#4428)
The new jni libraries for the libraries were never added, so they never get deployed.
2022-09-21 23:15:35 -07:00
Starlight220
36c08dd97c [build] Fix cmake install of fmtlib (#4426) 2022-09-20 09:48:44 -07:00
Peter Johnson
69b7b3dd7d [ci] Remove the Windows cmake job (#4425)
This currently is running into space issues due to vcpkg that are
difficult to fix.
2022-09-18 18:24:55 -07:00
Ryan Blue
738c75fed8 [readme] Fix formatting/linting link (#4423) 2022-09-18 15:12:28 -07:00
Tyler Veness
4eb1d03fb3 [wpimath] Document C++ LinearFilter exception (#4417) 2022-09-17 00:24:35 -07:00
Tyler Veness
ba4ec6c967 [build] Fix clang-tidy false positive on Linux (#4406)
* Fix clang-tidy false positive on Linux

```
== clang-tidy /home/tav/frc/wpilib/allwpilib/wpiutil/src/main/native/windows/StackTrace.cpp ==
/home/tav/frc/wpilib/allwpilib/wpiutil/src/main/native/windows/StackTrace.cpp:12:33: error: expected class name [clang-diagnostic-error]
class StackTraceWalker : public StackWalker {
                                ^
/home/tav/frc/wpilib/allwpilib/wpiutil/src/main/native/windows/StackTrace.cpp:16:17: error: unknown type name 'LPCTSTR' [clang-diagnostic-error]
  void OnOutput(LPCTSTR szText) override;
                ^
/home/tav/frc/wpilib/allwpilib/wpiutil/src/main/native/windows/StackTrace.cpp:23:33: error: unknown type name 'LPCTSTR' [clang-diagnostic-error]
void StackTraceWalker::OnOutput(LPCTSTR szText) {
                                ^
```

* Fix false positives for macOS code
2022-09-17 00:23:59 -07:00
Ryan Blue
97836f0e55 [commands] Fix ProfiledPIDSubsystem setGoal behavior (#4414)
Remove m_goal from ProfiledPIDSubsystem

Delegate setGoal to backing controller
2022-09-17 00:22:45 -07:00
Tyler Veness
fdfb85f695 [wpimath] Remove Java LQR constructor that takes a controller gain matrix (#4419)
The controller gain matrix K should be computed from the solution to the
DARE, but this constructor does not do that. It effectively violates a
postcondition enforced by the other constructors by letting the user
throw in a controller gain matrix that didn't come from an LQR.

Removing this constructor is a breaking change, but it never should have
been included in the class in the first place. There's also no valid
reason to use it. I assume it was originally added for debugging the
class internals.

This constructor does not exist in C++.
2022-09-17 00:18:08 -07:00
Tyler Veness
ab1baf4832 [wpimath] Add rotation matrix constructor to Rotation3d (#4413) 2022-09-17 00:17:30 -07:00
Tyler Veness
9730032866 [wpimath] Document LQR and KalmanFilter exceptions (#4418) 2022-09-17 00:16:40 -07:00
Brandon Parsons
5b656eecf6 [wpimath] Fix HTML5 entity (#4420)
Replace &top; with \u22a4, since Unicode references are supported
but HTML5 entities are not. Should be fixed if JDK is ever
moved forward.

Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2022-09-17 00:15:40 -07:00
Starlight220
9ae38eaa7c [commands] Add owning overload to ProxyScheduleCommand (#4405) 2022-09-13 18:33:19 -07:00
Starlight220
cb33bd71df [commands] deprecate withInterrupt decorator (#4407)
until() was recently added as a more intuitive alias for this. At this point, keeping this decorator will just cause confusion, given the functionally-equivalent until() alias and the similarly-named getInterruptionBehavior/withInterruptBehavior
2022-09-11 10:37:55 -07:00
Starlight220
d9b4e7b8bf [commands] Revert "Change grouping decorator impl to flatten nested group structures (#3335)" (#4402)
This reverts commit ef4ea84cb5.
2022-09-07 09:04:21 -07:00
T Grinch
0389bf5214 [hal] REVPH: Improve handling of disconnected CAN Bus (#4169)
Force the status to be 0 (no error) upon initialization of the REV PneumaticHub.
This prevents a program crash in the case of a robot code restart with no CAN Bus present.
2022-09-07 09:01:55 -07:00
T Grinch
4267fa08d1 [wpilibc] ADIS IMUs: Fix memory leak (#4170) 2022-09-06 13:10:33 -07:00
Peter Johnson
65c8fbd452 [wpilib] MotorControllerGroup: Override setVoltage (#4403)
This causes setVoltage to be called on the lower level motor contollers,
which is benefical in cases when they are smart motor controllers.
Previously, the default implementation (using the bus voltage and
calling set()) was used in this case.

This does slightly pessimize the case when the lower level motor
controllers use the default setVoltage implementation, but given the
prevalence of smart motor controllers, this seems like an overall win.
2022-09-06 08:18:33 -07:00
Tyler Veness
f36162fddc [wpimath] Improve Discretization internal docs (#4400) 2022-09-04 17:24:38 -07:00
Tyler Veness
5149f7d894 [wpimath] Add two-vector Rotation3d constructor (#4398)
This is useful for turning a 3D vector into an orientation relative a
coordinate system vector.
2022-09-04 13:16:29 -07:00
Tyler Veness
20b5bed1cb [wpimath] Clean up Java Quaternion class (#4399)
Vector.norm() and Vector.dot() were added to make the implementation
simpler and match the C++ version more closely.
2022-09-04 09:45:02 -07:00
Peter Johnson
f18dd1905d [build] Include all thirdparty sources in distribution (#4397)
Was missing several.
2022-09-03 09:23:51 -07:00
Peter Johnson
aa9d7f1cdc [wpiutil] Import foonathan memory (#4306) 2022-09-02 20:32:21 -07:00
Peter Johnson
2742662254 [ci] Remove a couple of obsolete clang-tidy checks (#4396)
We no longer use LLVM StringRef or Twine.
2022-09-02 20:31:27 -07:00
Thad House
a5df391166 [hal, wpilib] Fix up DIO pulse API (#4387)
The FPGA API takes microseconds directly, instead of a scaled value. Also add a new HAL level API to trigger multiple DIOs with the same pulse at once.
2022-09-02 16:49:42 -07:00
Peter Johnson
59e6706b75 [glass] Turn on docking by default
This uses a full-viewport dockspace and shift to enable docking.
2022-09-02 15:43:54 -07:00
Peter Johnson
8461bb1e03 [glass] Add support for saving docking info 2022-09-02 15:43:54 -07:00
Peter Johnson
b873e208b4 [wpigui] Add support for imgui config flags 2022-09-02 15:43:54 -07:00
Peter Johnson
873e72df8c [build] Update imgui to 1.88 docking branch 2022-09-02 15:43:54 -07:00
Peter Johnson
c8bd6fc5b4 [ci] Fix comment-command (take 2) (#4395) 2022-09-02 08:51:07 -07:00
Peter Johnson
fed68b83b4 [ci] Fix comment-command action not running runners (#4393)
Triggering runners from a push from a runner requires use of a PAT.
https://stackoverflow.com/questions/67550727/push-event-doesnt-trigger-workflow-on-push-paths-github-actions
2022-09-02 08:16:31 -07:00
Tyler Veness
0ef8a4e1df [wpimath] Support formatting more Eigen types (#4391)
Added an Eigen::SparseMatrix formatter.

Also modified the Eigen::Matrix formatter to support Eigen::MatrixXd.
Eigen::MatrixXd sets both dimension template arguments to -1, so they
can't be used for iteration. rows() and cols() are now used instead.

rows() and cols() are constexpr for statically sized matrices, so
there's no performance loss there.
2022-09-02 01:00:05 -07:00
Thad House
c393b3b367 [build] Update to native utils 2023.1.0 and Gradle 7.5.1 (#4392) 2022-09-02 00:59:47 -07:00
ohowe
b5a17f762c [wpimath] Add direction to slew rate limiter (#4377) 2022-09-01 14:46:46 -07:00
Tyler Veness
fafc81ed1a [wpiutil] Upgrade to fmt 9.1.0 (#4389) 2022-09-01 14:45:18 -07:00
Peter Johnson
cc56bdc787 [wpiutil] SafeThread: Add Synchronization object variant (#4382)
This enables use of SafeThread with Synchronization's WaitForObjects() blocking.
2022-08-31 11:29:57 -07:00
Starlight220
4254438d8d [commands] Mark command group lifecycle methods as final (#4385)
This prevents accidental footguns due to overriding of command group lifecycle methods.
2022-08-31 09:15:28 -07:00
CarloWoolsey
97c15af238 [wpimath] LinearSystemId: Fix docs, move C++ impls out of header (#4388)
- Fix inaccuracies and inconsistencies in Java & C++ LinearSystemId documentation.
- Move LinearSystemId function definitions to LinearSystemId.cpp
2022-08-31 09:12:48 -07:00
Peter Johnson
d22ff8a158 [wpiutil] Add JNI access to C++ stderr (#4381)
This is useful in some debugging scenarios.  System.err is separately buffered, so when e.g. debugging test cases it doesn't interleave correctly with the C++ stdout/stderr logging. Even using flush() doesn't seem to help, I think because Gradle does its own buffering.
2022-08-30 20:40:16 -07:00
Peter Johnson
fdb5a2791f [wpiutil] jni_util: Add Mac-friendly MakeJLongArray/JArrayRef (#4383)
Mac has jlong == long long and int64_t = long, so the types are
incompatible despite being the same size.
2022-08-30 20:39:42 -07:00
Starlight220
c3a93fb995 [commands] Revamp Interruptible (#4192) 2022-08-29 21:53:47 -07:00
OmegaMetor
f2a8d38d2a [commands] Rename Command.repeat to repeatedly (#4379) 2022-08-29 15:20:17 -07:00
Peter Johnson
9e24c6eac0 [wpiutil] Logger: paren-protect instance usage in macro (#4384) 2022-08-29 13:25:53 -07:00
Tyler Veness
fe4d12ce22 [wpimath] Add LTV controller derivations and make enums private (#4380)
The LTV differential drive controller derivation wasn't included inline
because it's too long.
2022-08-28 23:04:52 -07:00
Brandon Parsons
eb08486039 [build] Fix MacOS binary rpath generation (#4376)
For RPATH on MacOS use '@loader_path' instead of '$ORIGIN' to reference the directory where the executable is located. The latter is the mechanism used on Linux.

I think this was exposed due to newer OS X ignoring $DYLD_LIBRARY_PATH for security reasons.
2022-08-25 18:17:16 -07:00
Tyler Veness
ccf83c634a [build] Use native-utils platform names instead of raw strings (#4375) 2022-08-25 12:54:11 -07:00
Peter Johnson
3fd69749e7 [docs] Upgrade to doxygen 1.9.4 (#4370)
Doxygen 1.9.2 requires libclang-9, which is no longer available on
Ubuntu 22.04.
2022-08-21 18:49:04 -07:00
Peter Johnson
594df5fc08 [wpinet] uv/util.h: Pull in ws2_32.lib on Windows for ntohs (#4371) 2022-08-21 18:48:49 -07:00
Tyler Veness
539070820d [ci] Enable asan for wpinet and wpiutil (#4369) 2022-08-21 14:59:07 -07:00
Peter Johnson
564a56d99b [wpinet] Fix memory leak in WorkerThreadTest (#4368) 2022-08-21 10:29:31 -07:00
Tyler Veness
5adf50d93c [upstream_utils] Refactor upstream_utils scripts (#4367)
* Root folder variable names are now more descriptive
* clone_repo() now restores the current working directory
* Removed setup_upstream_repo() since it's now identical to clone_repo()
* Moved am_patches()'s for loop into user scripts so the filename prefix
  doesn't need to be included in every patch filename
* Renamed am_patches() to git_am() since its only job now is to run "git am"
* Removed unused apply_patches() function
* Fixed typo in git_am()'s ignore_whitespace arg name
2022-08-20 07:26:34 -07:00
Tyler Veness
d80e8039d7 [wpiutil] Suppress fmtlib clang-tidy warning in C++20 consteval contexts (#4364) 2022-08-19 23:52:19 -07:00
Tyler Veness
0e6d67b23b [upstream_utils] Remove yapf format disable comment (#4366) 2022-08-19 23:51:57 -07:00
Tyler Veness
be5270697a [build] Suppress enum-enum deprecation warning in OpenCV (#4365) 2022-08-19 23:51:43 -07:00
Tyler Veness
8d28851263 Add Rosetta install command to build requirements (#4363) 2022-08-18 19:58:43 -07:00
Tyler Veness
3d2115c93e [wpinet] include-what-you-use in MulticastTest (#4360)
This fixes an MSVC compilation error with C++20.
2022-08-18 14:03:55 -07:00
Tyler Veness
91002ae3cc [wpimath] Upgrade to Drake 1.6.0 (#4361) 2022-08-18 14:03:28 -07:00
Tyler Veness
148c18e658 [wpinet] Upgrade to libuv 1.44.2 (#4362) 2022-08-18 13:57:49 -07:00
Tyler Veness
a2a5c926b6 Fix clang-tidy warnings (#4359)
The warnings included recommendations of braces for if statement
readability, a recommendation for default initialization of an int
array, and include-what-you-use (indirectly through clang-tidy reporting
undefined symbols).
2022-08-17 19:53:56 -07:00
Tyler Veness
ea6b1d8449 [wpiutil] Remove unused ManagedStatic class (#4358)
We migrated to magic statics for lazy construction like the following:
```cpp
class Singleton {
  static Singleton& GetSingleton() {
    static Singleton instance;
    return instance;
  }
};
```
2022-08-17 18:04:42 -07:00
Tyler Veness
ac9be78e27 Use stricter C++ type conversions (#4357)
Now, implicit narrowing conversions are only used with wpi::Now(). This
also fixes clang-tidy warnings about C-style casts. For example:
```
== clang-tidy /__w/allwpilib/allwpilib/wpilibNewCommands/src/main/native/include/frc2/command/SwerveControllerCommand.inc ==
/__w/allwpilib/allwpilib/wpilibNewCommands/src/main/native/include/frc2/command/SwerveControllerCommand.inc:95:18: warning: C-style casts are discouraged; use static_cast/const_cast/reinterpret_cast [google-readability-casting]
  auto curTime = units::second_t(m_timer.Get());
                 ^
```
In that case at least, the cast was removed entirely since Get() already
returns a units::second_t.
2022-08-17 13:42:36 -07:00
Tyler Veness
151dabb2af [wpiutil] Upgrade to fmt 9.0.0 (#4337)
fmt removed fmt::make_args_checked since it's no longer needed for
constexpr format string checks.

fmt deprecated implicit conversions from enums to integers in format
arguments, so I added explicit static casts.
2022-08-16 15:35:26 -07:00
Tyler Veness
340465c929 [ci] Upgrade to clang-format and clang-tidy 14 (NFC) (#4347) 2022-08-16 15:25:04 -07:00
Michael Leong
d45bcddd15 [examples] Add comments to StateSpaceDifferentialDrive (#4341) 2022-08-15 06:26:20 -07:00
Tyler Veness
0e0786331a Update LLVM libraries to 14.0.6 (#4350)
The main noticeable change is the SmallString conversion operator to std::string is now explicit instead of implicit.
2022-08-15 05:38:15 -07:00
Tyler Veness
c5db23f296 [wpimath] Add Eigen sparse matrix and iterative solver support (#4349)
These are useful for efficiently solving huge, but sparse systems of
equations that occur often in optimization problems.
2022-08-13 18:32:02 -07:00
Tyler Veness
44abc8dfa6 [upstream_utils] Remove git version from upstream patches (#4351)
This reduces commit noise when other git versions are used. The version
was removed by passing `--no-signature` to `git format-patch` which is
now documented in the readme.
2022-08-13 18:31:26 -07:00
Tyler Veness
3fdb2f767d [wpimath] Add comments with Ramsete equations (#4348) 2022-08-11 07:09:16 -07:00
Tyler Veness
0485f05da9 [wpilibjExamples] Upgrade jacoco to match allwpilib (#4346) 2022-08-05 10:21:40 -07:00
Thad House
0a5eb65231 [wpinet] Handle empty txt block for mdns announcer (#4072) 2022-08-03 11:15:56 -07:00
sciencewhiz
19ffebaf3e [wpilib] Add reference to I2C Lockup to API Docs (NFC) (#4340) 2022-07-29 21:01:21 -07:00
Tyler Veness
ce1a90d639 [hal] Replace SerialHelper "goto done" with continue (#4342)
The logic is already correct for closing all the objects. So we should just be continuing on error.
2022-07-27 14:37:32 -07:00
Tyler Veness
d25af48797 [ci] Make upstream_utils CI fail on untracked files (#4339)
This catches issues like update scripts putting new files in a different
directory from the old ones.
2022-07-24 19:34:16 -07:00
Jeffrey Morris
ebb836dacb [examples] Fix negations in event loop examples (#4334) 2022-07-24 19:33:52 -07:00
Tyler Veness
d83e202f00 [upstream_utils] Update paths in update_fmt.py (#4338) 2022-07-22 18:08:36 -07:00
Tyler Veness
3ccf806064 [wpimath] Remove redundant LinearFilter.finiteDifference() argument (#4335)
The number of samples is already determined by the length of the stencil
list.
2022-07-22 12:50:30 -05:00
Tyler Veness
6f1e01f8bd [wpimath] Document example of online filtering for LinearFilter.finiteDifference() (#4336) 2022-07-22 12:46:33 -05:00
sciencewhiz
1023c34b1c [readme] Update location of ni-libraries (#4333)
Fixes #4321
2022-07-09 17:44:03 -05:00
Tyler Veness
faa29d596c [wpilib] Improve Notifier docs (NFC) (#4326) 2022-07-01 06:45:00 -07:00
Tyler Veness
add00a96ed [wpimath] Improve DifferentialDriveAccelerationLimiter docs (NFC) (#4323)
Defined trackwidth, added skipped steps to the algorithm's internal
proof, and grouped the algorithm steps more logically with blank lines.
2022-07-01 06:43:57 -07:00
Tyler Veness
82fac41244 [wpimath] Better document trackwidth parameters (NFC) (#4324) 2022-07-01 06:42:49 -07:00
Tyler Veness
5eb44e22a9 Format Python scripts with black (NFC) (#4325) 2022-07-01 06:41:44 -07:00
Peter Johnson
2e09fa7325 [build] Fix mpack cmake (#4322) 2022-06-24 19:35:13 -07:00
Starlight220
fe3c24b1ee [command] Add ignoringDisable decorator (#4305) 2022-06-24 10:52:53 -07:00
Thad House
aa221597bc [build] Add M1 builds, change arm name, update to 2023 deps (#4315) 2022-06-20 12:28:46 -06:00
Tyler Veness
579a8ee229 [ci] Use one worker for Windows release Gradle build (#4318)
It was running out of heap space.
2022-06-18 22:45:12 -07:00
Justus
5105c5eab6 [wpilibj] Change "final" to "exit" in the IterativeRobotBase JavaDoc (NFC) (#4317)
"exit" is used in every other instance.
2022-06-18 15:02:36 -07:00
PJ Reiniger
787fe6e7a5 [wpiutil] Separate third party libraries (#4190) 2022-06-18 08:08:31 -07:00
ohowe
6671f8d099 [wpigui] Update portable file dialogs (#4316)
All commits from March 16, 2022 to June 1, 2022
This fixes the save button in sysid on macOS.
2022-06-17 22:47:22 -07:00
Starlight220
9ac9b69aa2 [command] Reorder Scheduler operations (#4261)
Fixes several cases where calling scheduler operations from a command callback could result in NPEs or other issues.

Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2022-06-15 23:32:16 -07:00
Tyler Veness
e61028cb18 [build] halsim_gui: Add wpinet dependency (#4313) 2022-06-15 23:14:31 -07:00
ohowe
661d23eaf5 [glass] Add precision setting for NetworkTable view (#4311) 2022-06-15 21:21:52 -07:00
Tyler Veness
666040e3e5 [hal] Throw exceptions for invalid sizes in I2C and SPI JNI (#4312)
GCC's static analyzer is correctly reporting that resize() requires an
unsigned integer, but the argument provided in the JNI function could be
negative since it's a signed byte. Throwing an exception if the argument
is negative fixes the warning.
2022-06-15 21:20:52 -07:00
Tyler Veness
aebc272449 [build] Upgrade to spotbugs Gradle plugin 5.0.8 (#4310)
This fixes a SecurityManager deprecation warning generated by spotbugs.
2022-06-14 20:26:53 -07:00
Starlight220
fd884581e4 [wpilib] Add BooleanEvent/Trigger factories on HID classes (#4247) 2022-06-13 22:48:16 -07:00
Tyler Veness
9b1bf5c7f1 [wpimath] Move Drake and Eigen to thirdparty folders (#4307) 2022-06-11 21:07:15 -07:00
Starlight220
c9e620a920 [wpilibc] Change EventLoop data structure to vector (#4304) 2022-06-10 05:38:54 -07:00
Peter Johnson
41d40dd62f [wpinet] Fix libuv unused variable warning on Mac (#4299) 2022-06-09 23:30:16 -07:00
PJ Reiniger
30f5b68264 [wpinet] Fix JNI loading error (#4295) 2022-06-08 22:21:22 -07:00
DeltaDizzy
f7b3f4b90e [examples] Getting Started: Change Joystick to XboxController (#4194) 2022-06-08 22:20:33 -07:00
Connor Worley
a99c11c14c [wpimath] Replace UKF implementation with square root form (#4168)
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2022-06-08 22:19:01 -07:00
Starlight220
45b7fc445b [wpilib] Add EventLoop (#4104)
This is a generic expansion of the command-based Trigger framework.
2022-06-08 22:16:51 -07:00
Peter Johnson
16a4888c52 [wpilib] Default off LiveWindow telemetry (#4301)
The original idea of LiveWindow telemetry was to automatically make
telemetry data visible to users.  This has proved increasingly
problematic in recent years due to the "spooky action at a distance"
of telemetry happening for objects that are only constructed but not
used, and blocking or slow object reads resulting in hard-to-debug
loop overrun conditions.
2022-06-08 22:13:00 -07:00
Thad House
17752f1337 [ci] Split debug and release Windows builds (#4277)
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2022-06-06 17:25:02 -07:00
Starlight220
abb45a68db [commands] Remove custom test wrappers (#4296)
Use AtomicBoolean and AtomicInteger instead of
custom ConditionHolder and Counter classes.
2022-06-06 17:13:11 -07:00
Peter Johnson
1280a54ef3 [upstream_utils]: Make work with Python 3.8 (#4298)
str.removesuffix() is only available in Python 3.9, which is not in many
Linux installations.
2022-06-06 17:07:16 -07:00
Starlight220
f2d243fa68 [build] Change defaults for Java lints (#4300)
Removes the need to individually suppress the "serial" warning.
2022-06-06 17:06:43 -07:00
sciencewhiz
a4787130f4 Update using development build to work with 2023 gradlerio (#4294) 2022-06-04 13:58:51 -07:00
Prateek Machiraju
af7985e46c [wpiutil] Use invoke_result_t instead of result_of in future.h (#4293)
std::result_of is deprecated in C++17.
2022-06-02 23:04:20 -07:00
Tyler Veness
e9d1b5c2d0 [hal] Remove deprecated SimDevice functions (#4209) 2022-06-02 22:53:02 -07:00
Prateek Machiraju
45b598d236 [wpilibj] Add toString() methods to Color and Color8Bit (#4286) 2022-06-02 21:23:11 -07:00
Prateek Machiraju
fc37265da5 [wpimath] Add angle measurement convention to ArmFeedforward docs (NFC) (#4285) 2022-06-02 21:22:47 -07:00
Prateek Machiraju
a4ec13eb0e [wpilibjexamples] Remove unnecessary voltage desaturation 2022-06-02 21:22:19 -07:00
Prateek Machiraju
2fa52007af [wpilibc] Use GetBatteryVoltage() in MotorController::SetVoltage
This avoids having to cast to units::voltage_t
2022-06-02 21:22:19 -07:00
Prateek Machiraju
d9f9cd1140 [wpimath] Reset prev_time on pose estimator reset (#4283) 2022-06-02 21:21:42 -07:00
truher
8b6df88783 [wpilibj] Tachometer.getFrequency(): Fix bug (#4281)
Now it returns 1/period (like Tachometer.cpp); before it just returned period.
2022-06-01 10:13:19 -07:00
Tyler Veness
345cff08c0 [wpiutil] Make wpi::array constexpr (#4278) 2022-05-31 20:21:29 -07:00
Tyler Veness
57428112ac [wpimath] Upgrade to Drake v1.3.0 (#4279) 2022-05-31 20:20:01 -07:00
Thad House
a18d4ff154 [build] Fix tools not being copied when built with -Ponly* (#4276) 2022-05-29 22:09:00 -07:00
Peter Johnson
d1cd07b9f3 [wpigui] Add OpenURL (#4273)
This function opens a URL using the default browser.
2022-05-29 18:45:39 -07:00
Peter Johnson
e67f8e917a [glass] Use glfwSetKeyCallback for Enter key remap (#4275)
The imgui internals methods break with imgui >= 0.87.
2022-05-29 18:44:52 -07:00
Tyler Veness
be2fedfe50 [wpimath] Add stdexcept include for std::invalid_argument (IWYU) (#4274) 2022-05-29 15:33:19 -07:00
Peter Johnson
7ad2be172e [build] Update native-utils to 2023.0.1 (#4272)
Also remove x86 build bits.
2022-05-28 11:12:59 -07:00
Peter Johnson
abc605c9c9 [ci] Update workflows to 20.04 base image (#4271) 2022-05-27 23:33:33 -07:00
PJ Reiniger
3e94805220 [wpiutil] Reduce llvm collections patches (#4268) 2022-05-27 13:41:28 -07:00
Tyler Veness
db2e1d170e [upstream_utils] Document how to update thirdparty libraries (#4253)
Also, add a CI job to ensure the sources in the repo are consistent with
the update scripts.
2022-05-26 09:02:32 -07:00
Tyler Veness
96ebdcaf16 [wpimath] Remove unused Eigen AutoDiff module (#4267)
Drake's tests used to include it, but it's commented out since it's not
used.
2022-05-26 09:01:45 -07:00
PJ Reiniger
553b2a3b12 [upstream_utils] Fix stackwalker (#4265) 2022-05-24 21:51:32 -07:00
Tyler Veness
3e13ef42eb [wpilibc] Add missing std::array #include (include-what-you-use) (#4266) 2022-05-24 21:49:22 -07:00
Tyler Veness
d651a1fcec Fix internal deprecation warnings (#4257)
This allows us to error out on deprecation warnings for thirdparty
libraries and standard library features.

Co-authored-by: Starlight220 <53231611+Starlight220@users.noreply.github.com>
2022-05-24 13:56:48 -07:00
ohowe
b193b318c1 [commands] Add unless() decorator (#4244) 2022-05-24 09:22:19 -07:00
bovlb
ef3714223b [commands] Remove docs reference to obsolete interrupted() method (NFC) (#4262) 2022-05-24 09:19:38 -07:00
Dalton Smith
3d8dbbbac3 [readme] Add quickstart (#4225) 2022-05-22 20:19:50 -07:00
Peter Johnson
013efdde25 [wpinet] Wrap a number of newer libuv features (#4260) 2022-05-22 20:18:23 -07:00
Starlight220
816aa4e465 [wpilib] Add Pneumatics sim classes (#4033) 2022-05-22 07:21:40 -07:00
Tyler Veness
046c2c8972 [wpilibc] Rename SpeedControllerGroupTest.cpp (#4258)
Also move motor controller test files into motorcontrol folder to match
Java.
2022-05-21 16:20:26 -07:00
Tyler Veness
d80e9cdf64 [upstream_utils] Use shallow clones for thirdparty repos (#4255)
This makes update_llvm.py in particular much faster because the full
repo requires fetching 2 GB.
2022-05-20 18:59:33 -07:00
Tyler Veness
7576136b4a [upstream_utils] Make update_llvm.py executable (#4254) 2022-05-20 17:16:19 -07:00
PJ Reiniger
c3b223ce60 [wpiutil] Vendor llvm and update to 13.0.0 (#4224) 2022-05-20 15:59:53 -07:00
Tyler Veness
5aa67f56e6 [wpimath] Clean up math comments (#4252) 2022-05-20 15:16:56 -07:00
Tyler Veness
fff4d1f44e [wpimath] Extend Eigen warning suppression to GCC 12 (#4251)
It originally only applied to GCC 11. The CMake build passed without
this change, but not the Gradle build.
2022-05-19 18:50:29 -07:00
Tyler Veness
0d9956273c [wpimath] Add CoordinateSystem.convert() translation and rotation overloads (#4227) 2022-05-18 20:41:15 -07:00
Tyler Veness
3fada4e0b4 [wpinet] Update to libuv 1.44.1 (#4232) 2022-05-18 20:40:27 -07:00
Tyler Veness
65b23ac45e [wpilibc] Fix return value of DriverStation::GetJoystickAxisType() (#4230)
It was returning a pointer to the axis type array cast to a bool (always
1) instead of returning the desired axis type.
2022-05-18 14:36:11 -07:00
Tyler Veness
4ac34c0141 [upstream_utils] Cleanup update_libuv.py (#4249) 2022-05-18 14:34:34 -07:00
Tyler Veness
8bd614bb1e [upstream_utils] Use "git am" instead of "git apply" for patches (#4248)
This creates actual commits in the thirdparty repo, which makes rebasing
them onto new versions much easier.
2022-05-18 12:23:15 -07:00
Tyler Veness
4253d6d5f0 [upstream_utils] Apply "git am" patches individually (#4250)
Also, giving am_patches() zero patches isn't an error. The function will
just be a no-op.
2022-05-18 12:22:31 -07:00
Tyler Veness
6a4752dcdc Fix GCC 12.1 warning false positives (#4246) 2022-05-18 12:22:10 -07:00
Tyler Veness
5876b40f08 [wpimath] Memoize CoordinateSystem and CoordinateAxis statics (#4241) 2022-05-18 10:47:46 -07:00
Tyler Veness
5983434a70 [cameraserver] Replace IterativeRobot in comment sample code with TimedRobot (#4238) 2022-05-15 20:47:50 -07:00
Max Gordon
a3d44a1e69 [wpimath] Add Translation2d.getAngle() (#4217)
Co-authored-by: Max Gordon <tonald.drump2.0@gamil.com>
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2022-05-14 21:22:00 -07:00
Tyler Veness
d364bbd5a7 [upstream_utils] Give vendor update scripts execute permissions (#4226) 2022-05-14 15:31:51 -07:00
Tyler Veness
f341e1b2be [wpimath] Document standard coordinate systems better (NFC) (#4228) 2022-05-14 15:31:06 -07:00
Peter Johnson
9af389b200 [wpinet] AddrToName: Initialize name (#4229) 2022-05-14 06:55:22 -07:00
Austin Shalit
2ae4adf2d7 [ci] Add wpiformat command to PRs (#4223) 2022-05-11 22:06:11 -07:00
sciencewhiz
178b2a1e88 Contributing.md: Correct version of clang-format used (#4222) 2022-05-10 23:48:08 -07:00
PJ Reiniger
18db343cdc [wpiutil, wpinet] Vendor libuv, stack walker (#4219) 2022-05-08 22:21:54 -07:00
Austin Shalit
f0c821282a [build] Use artifactory mirror (#4220) 2022-05-08 13:59:58 -07:00
Peter Johnson
d673ead481 [wpinet] Move network portions of wpiutil into new wpinet library (#4077) 2022-05-07 10:54:14 -07:00
Tyler Veness
b33715db15 [wpimath] Add CoordinateSystem class (#4214) 2022-05-07 10:25:19 -07:00
Dustin Spicuzza
99424ad562 [sim] Allow creating a PWMSim object from a PWMMotorController (#4039) 2022-05-06 08:44:59 -07:00
Tommy Beadle
dc6f641fd2 [wpimath] PIDController: Reset position and velocity error when reset() is called. (#4064)
In addition to m_prevError and m_totalError, m_positionError and
m_velocityError need to be reset to 0 when reset() is called.
Otherwise, the next time calculate() is called, the old values will be
used as the previous error, but this is inaccurate since the caller
wanted to reset the state of the PID controller.
2022-05-06 08:44:08 -07:00
Tyler Veness
f20a20f3f1 [wpimath] Add 3D geometry classes (#4175)
Also clean up 2D geometry documentation.
2022-05-06 08:41:23 -07:00
Kaitlyn Kenwell
708a4bc3bc [wpimath] Conserve previously calculated swerve module angles when updating states for stationary ChassisSpeeds (#4208)
* Calculated swerve module states now stored in a member variable
* If ChassisSpeeds(0, 0, 0) is converted to module speeds, the
previously calculated module angle will be conserved, with forward speed
set to 0
* New tests added
2022-05-06 08:38:20 -07:00
chen perach
ef7ed21a9d [wpimath] Improve accuracy of ComputerVisionUtil.calculateDistanceToTarget() (#4215) 2022-05-06 08:36:58 -07:00
Tyler Veness
b1abf455c1 [wpimath] LTVUnicycleController: Use LUT, provide default hyperparameters (#4213) 2022-05-04 22:04:08 -07:00
Tyler Veness
d5456cf278 [wpimath] LTVDifferentialDriveController: Remove unused variable (#4212) 2022-05-04 22:03:15 -07:00
Tyler Veness
99343d40ba [command] Remove old command-based framework (#4211) 2022-05-04 22:02:53 -07:00
Tyler Veness
ee03a7ad3b Remove most 2022 deprecations (#4205)
Excludes "old" commands and SimDevice functions.
2022-05-04 20:37:27 -07:00
Tyler Veness
ce1a7d698a [wpimath] Refactor WheelVoltages inner class to a separate file (#4203) 2022-05-01 11:01:20 -07:00
Tyler Veness
87bf70fa8e [wpimath] Add LTV controllers (#4094)
This adds a unicycle controller that's a drop-in replacement for Ramsete
and a differential drive controller that controls the full pose and
outputs voltages. The main benefit is LQR-like tuning knobs using a
system model.
2022-04-30 22:54:22 -07:00
Tyler Veness
ebd2a303bf [wpimath] Remove deprecated MakeMatrix() function (#4202) 2022-04-30 22:52:05 -07:00
Peter Johnson
e28776d361 [wpimath] LinearSystemLoop: Add extern templates for common cases 2022-04-30 20:38:55 -07:00
Peter Johnson
dac1429aa9 [wpimath] LQR: Use extern template instead of Impl class 2022-04-30 20:38:55 -07:00
Peter Johnson
e767605e94 [wpimath] Add typedefs for common types
This makes complex code significantly easier to read.

frc::Vectord<Size> = Eigen::Vector<double, Size>
frc::Matrixd<Rows, Cols> = Eigen::Matrix<double, Rows, Cols>
2022-04-30 20:38:55 -07:00
Peter Johnson
97c493241f [wpimath] UnscentedKalmanFilter: Move implementation out-of-line 2022-04-30 20:38:55 -07:00
Peter Johnson
8ea90d8bc9 [wpimath] ExtendedKalmanFilter: Move implementation out-of-line 2022-04-30 20:38:55 -07:00
Peter Johnson
ae7b1851ec [wpimath] KalmanFilter: Use extern template instead of Impl class 2022-04-30 20:38:55 -07:00
Peter Johnson
e3d62c22d3 [wpimath] Add extern templates for common cases
This helps reduce compile times and memory usage.
2022-04-30 20:38:55 -07:00
Peter Johnson
7200c4951d [wpiutil] SymbolExports: Add WPILIB_IMPORTS for dllimport 2022-04-30 20:38:55 -07:00
Peter Johnson
84056c9347 [wpiutil] SymbolExports: Add EXPORT_TEMPLATE_DECLARE/DEFINE 2022-04-30 20:38:55 -07:00
Oblarg
09cf6eeecb [wpimath] ApplyDeadband: add a scale param (#3865)
Also templates it in C++ so it can work with both doubles and units.
2022-04-30 20:29:48 -07:00
Austin Shalit
03230fc842 [build,ci] Enable artifactory build cache (#4200) 2022-04-30 20:27:23 -07:00
Jason Daming
63cf3aaa3f [examples] Don't square ArcadeDrive inputs in auto (#4201) 2022-04-30 20:19:32 -07:00
Starlight220
18ff694f02 [wpimath] Add Rotation2d.fromRadians factory (#4178) 2022-04-30 00:19:29 -07:00
Tyler Veness
4f79ceedd9 [wpilibc] Add missing #include (#4198) 2022-04-30 00:07:37 -07:00
Starlight220
f7ca72fb41 [command] Rename PerpetualCommand to EndlessCommand (#4177) 2022-04-28 09:38:38 -07:00
bovlb
a06b3f0307 [hal] Correct documentation on updateNotifierAlarm (#4156)
The previous documentation suggested that `triggerTime` is the interval until the next alarm, but the implementation is that it is the absolute alarm time.
2022-04-26 21:53:30 -07:00
Tyler Veness
d926dd1610 [wpimath] Fix pose estimator performance (#4111)
Fixes #4087.
2022-04-26 18:43:59 -07:00
ysthakur
51bc893bc5 [wpiutil] CircularBuffer: Change Java package-private methods to public (#4181)
The `size`, `getFirst`, `getLast`, and `resize` methods were all package-private.

Also make `size` return an `int` instead of a `double`.
2022-04-25 14:58:12 -07:00
Tyler Veness
fbe761f7f6 [build] Increase Gradle JVM heap size (#4172)
wpimath artifact publishing was running out of heap
2022-04-24 23:13:57 -07:00
Tyler Veness
5ebe911933 [wpimath] Add DifferentialDriveAccelerationLimiter (#4091) 2022-04-24 07:21:40 -07:00
Tyler Veness
3919250da2 [wpilibj] Remove finalizers (#4158)
They were deprecated for removal in Java 18 because they're error-prone.
Prefer AutoCloseable and Cleaner instead.

https://openjdk.java.net/jeps/421
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/ref/Cleaner.html
2022-04-24 07:21:08 -07:00
ohowe
b3aee28388 [commands] Allow BooleanSupplier for Trigger operations (#4103) 2022-04-24 07:20:46 -07:00
Tyler Veness
9d20ab3024 [wpilib] Allow disabling ElevatorSim gravity (#4145)
Closes #4144.
2022-04-24 07:19:18 -07:00
Peter Johnson
aaa69f6717 [ci] Remove 32-bit Windows builds (#4078) 2022-04-24 07:18:49 -07:00
Tyler Veness
355a11a414 Update Java linters and fix new PMD errors (#4157)
PMD requires that variables only initialized in the constructor be
final. The compiler errors if those final variables aren't guaranteed to
be initialized, so extra else branches were added to ensure that.

PMD also requires that classes with only private constructors be final.
The equivalent C++ classes were finalized as well, except for
TimeInterpolatableBuffer because it doesn't expose factory functions.
2022-04-24 07:18:05 -07:00
Jason Daming
ffc69d406c [examples] Reduce suggested acceleration in Ramsete example (#4171)
This value mirrors the update to the documentation in wpilibsuite/frc-docs#1792.
2022-04-19 17:10:11 -07:00
camaj
922d50079a [wpimath] Units: fix comment in degreesToRotations (NFC) (#4159) 2022-04-13 22:32:55 -07:00
Jonah Snider
dd163b62ae [wpimath] Rotation2d: Add factory method that uses rotations (#4166)
Rotation2d.fromRotations(1).equals(new Rotation2d(2 * Math.PI)); // true

Also adds a member method to get the value of the Rotation2d in rotations.
2022-04-13 22:31:43 -07:00
Tyler Veness
bd80e220b9 [ci] Upgrade CMake actions (#4161) 2022-04-12 19:00:00 -07:00
Tyler Veness
aef4b16d4c [wpimath] Remove unnecessary NOLINT in LinearPlantInversionFeedforward (NFC) (#4155) 2022-04-08 21:31:42 -07:00
Spud
975171609e [wpilib] Compressor: Rename enabled to isEnabled (#4147)
This is a less confusing name, as enabled() can imply it enables the compressor.
2022-04-08 21:31:08 -07:00
Tyler Veness
5bf46a9093 [wpimath] Add ComputerVisionUtil (#4124)
Closes #4108.
2022-04-08 21:20:53 -07:00
ohowe
f27a1f9bfb [commands] Fix JoystickButton.getAsBoolean (#4131)
This previously always returned false; the get method it inherited was not used in the getAsBoolean defined in the Trigger class. The fix is to swap get() and getAsBoolean() implementations in the Trigger class.
2022-04-08 21:20:23 -07:00
Excalibur FRC | 6738
1b26e2d5da [commands] Add RepeatCommand (#4009)
Co-authored-by: Starlight220 <53231611+Starlight220@users.noreply.github.com>
2022-04-07 22:02:08 -07:00
apple
88222daa3d [hal] Fix misspelling in AnalogInput/Output docs (NFC) (#4153)
value -> valid
(NFC)
2022-04-07 21:57:01 -07:00
Tyler Veness
81c5b41ce1 [wpilibj] Document MechanismLigament2d angle unit (NFC) (#4142) 2022-03-31 00:29:44 -07:00
Peter Johnson
9650e6733e [wpiutil] DataLog: Document finish and thread safety (NFC) (#4140) 2022-03-29 12:28:59 -07:00
Tyler Veness
c8905ec29a [wpimath] Remove ImplicitModelFollower dt argument (#4119)
The math works just fine without model discretization.
2022-03-29 11:29:06 -07:00
Tyler Veness
b4620f01f9 [wpimath] Fix Rotation2d interpolation in Java (#4125)
Fixes #4112.
2022-03-29 08:42:43 -07:00
Tyler Veness
2e462a19d3 [wpimath] Constexprify units unary operators (#4138)
Fixes #4137.
2022-03-29 08:42:08 -07:00
Peter Johnson
069f932e59 [build] Fix gl3w cmake build (#4139) 2022-03-28 22:31:51 -07:00
Tyler Veness
126e3de91a [wpilibc] Remove unused SetPriority() call from Ultrasonic (#4123) 2022-03-24 07:24:12 -07:00
Tyler Veness
ba0dccaae4 [wpimath] Fix reference to Rotation2d.fromRadians() (#4118)
Rotation2d.fromRadians() doesn't exist. The constructor should be used
instead.
2022-03-20 21:57:03 -07:00
sciencewhiz
e1b6e5f212 [wpilib] Improve MotorSafety documentation (NFC) (#4120)
Remove OBE RobotDrive porting guide from MecanumDrive
2022-03-20 21:54:43 -07:00
Tyler Veness
8d79dc8738 [wpimath] Add ImplicitModelFollower (#4056) 2022-03-20 00:36:12 -07:00
Tyler Veness
78108c2aba [wpimath] Fix PIDController having incorrect error after calling SetSetpoint() (#4070) 2022-03-19 23:59:00 -07:00
Tyler Veness
cdafc723fb [examples] Remove unused LinearPlantInversionFeedforward includes (#4069) 2022-03-19 20:47:09 -07:00
Ashray._.g
0d70884dce [wpimath] Add InterpolatedTreeMap (#4073)
- Add InterpolatedTreeMap for Java from team 254's 2016 MIT licensed code
- Add InterpolatedMap for C++ from team 3512's code with @calcmogul (original author) permission

Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2022-03-19 20:46:42 -07:00
Tyler Veness
765efa325e [wpimath] Remove redundant column index from vectors (#4116) 2022-03-19 20:44:14 -07:00
Tyler Veness
89ffcbbe41 [wpimath] Update TrapezoidProfile class name in comment (NFC) (#4107) 2022-03-19 20:41:53 -07:00
Tyler Veness
95ae23b0e7 [wpimath] Improve EKF numerical stability (#4093)
The Joseph form of the error covariance update equation is more
numerically stable when the Kalman gain isn't optimal. Numerical
instability and filter divergence can occur if the user goes long time
periods between updates and the error covariance becomes ill-conditioned
(the ratio between the largest and smallest eigenvalue gets too large).
2022-03-19 20:41:28 -07:00
Tyler Veness
d5cb6fed67 [wpimath] Support zero cost entries in MakeCostMatrix() (#4100)
The existing implementation will produce a cost of NaN if a tolerance of
infinity is entered, but the limit approaches zero. Being able to
specify that a state has no cost is useful, so this change adds support for
that.
2022-03-19 20:40:26 -07:00
Tyler Veness
d0fef18378 [wpimath] Remove redundant this. from ExtendedKalmanFilter.java (#4115) 2022-03-19 20:39:10 -07:00
Tyler Veness
d640c0f41f [wpimath] Fix pose estimator local measurement standard deviation docs (NFC) (#4113) 2022-03-19 20:38:32 -07:00
Dustin Spicuzza
a2fa5e3ff7 [wpilibc] BatterySim: Provide non-initializer list versions of Calculate (#4076) 2022-03-14 10:09:55 -07:00
sciencewhiz
a3eea9958e [hal] Add link to FRC CAN Spec (NFC) (#4086) 2022-03-14 10:07:44 -07:00
Tyler Veness
db27331d7b [wpilib] Update DifferentialDrive docs (NFC) (#4085)
Fixes #4084.
2022-03-14 10:07:06 -07:00
Peter Johnson
fdfb31f164 [dlt] Export boolean[] values (#4082) 2022-03-14 10:05:50 -07:00
Dustin Spicuzza
f93c3331b3 [wpigui] disable changing directory when initializing on MacOS (#4092)
- Seems to be intended for resource bundles in MacOS apps, which we don't use
2022-03-14 10:05:22 -07:00
Thad House
ab7ac4fbb9 [build] Fix various warnings in cmake builds (#4081) 2022-03-07 22:36:42 -08:00
Thad House
bc39a1a293 [wpilibc] Fix moved pneumatics objects not destructing properly (#4068) 2022-03-01 11:10:45 -08:00
Tyler Veness
2668130e70 [wpimath] Remove SwerveDrivePoseEstimator encoder reset warning (#4066)
SwerveDrivePoseEstimator uses velocities, so position resets aren't
needed.

Closes #4065.
2022-02-28 17:40:25 -08:00
Austin Shalit
d27ed3722b [ci] Set actions workflow concurrency (#4060)
This sets the workflow concurrency to 1 for all workflows. For PRs this means if you push an additional commit older jobs will be cancelled.

The documentation workflow already only runs on tags or merges to main. For this, we cancel previous runs if they are to the same destination (tag or main) but still prevent 2 jobs from running at once if they are spawned from different refs.
2022-02-27 20:13:58 -08:00
shueja-personal
dae18308c9 [wpimath] Minor fixes to Rotation2d docs (NFC) (#4055)
Fixed incorrect examples on .plus(), and a missing word.

Make example code snippets closer to actual use.
2022-02-27 16:56:56 -08:00
Peter Johnson
d66555e42f [datalogtool] Add datalogtool
This is a support tool for datalog file conversion (and eventually
download/remote datalog file management).
2022-02-26 09:49:34 -08:00
Peter Johnson
9f52d8a3b1 [wpilib] DriverStation: Add DataLog support for modes and joystick data 2022-02-26 09:49:34 -08:00
Peter Johnson
757ea91932 [wpilib] Add DataLogManager
This creates a default log file that captures NT changes and
automatically renames the log file based on time and match info.

DriverStation joystick logging will be implemented by the DriverStation
class instead.
2022-02-26 09:49:34 -08:00
Peter Johnson
02a804f1c5 [ntcore] Add DataLog support 2022-02-26 09:49:34 -08:00
Peter Johnson
9b500df0d9 [wpiutil] Add high speed data logging 2022-02-26 09:49:34 -08:00
Peter Johnson
5a89575b3a [wpiutil] Import customized LLVM MemoryBuffer 2022-02-26 09:49:34 -08:00
Peter Johnson
b8c4d7527b [wpiutil] Add MappedFileRegion 2022-02-26 09:49:34 -08:00
Alberto Jahuey Moncada
ac5d46cfa7 [wpilibc] Fix ProfiledPID SetTolerance default velocity value (#4054)
When trying to set the tolerance of a ProfiledPID, it fails if you don't give it a velocity value. It was missing a conversion from double to the appropiate unit.
2022-02-25 20:27:56 -08:00
Thad House
bc9e96e86f [wpilib] Absolute Encoder API and behavior fixes (#4052)
SetPositionOffset was added. Been requested multiple times, and easy to implement.

The javadocs mentioned GetPositionInRotation. It has tripped up many people how to get the absolute position from the encoder (You currently have to have precreated the DutyCycle object). Add this method (as GetAbsolutePostition) to make this easier to do.

The checks for making sure a matching set of values was read was doing direct double comparisions. This worked ok in the DutyCycle case, but has problems in the analog case. Solve this by using an epsilon comparison.

And finally, scale AnalogEncoders analog input to 0-1 instead of 0-5. This was reported a few years ago, but the issue was missed. This caused the encoder to count from 0-5, then 1-6, then 2-7 etc. This is solved and now works correctly.

Closes #3188
Closes #4046
Closes #4051

And fixes the following issue on CD
https://www.chiefdelphi.com/t/wpilib-analogencoder-java/372649
2022-02-24 22:45:15 -08:00
Dustin Spicuzza
f88c435dd0 [hal] Add mechanism to cancel all periodic callbacks (#4049) 2022-02-23 09:46:01 -08:00
Leonard Abbas
e4b91005cf [examples] Update SwerveModule constructor doc (NFC) (#4042)
Renamed "port" to "channel" for consistency.
2022-02-22 09:26:16 -08:00
Leonard Abbas
a260bfd83b [examples] Remove "this" keyword from SwerveModule (#4043) 2022-02-21 09:27:00 -08:00
Leonard Abbas
18e262a100 [examples] Fix multiple doc typos in SwerveControllerCommand example (NFC) (#4044) 2022-02-21 09:26:20 -08:00
Dustin Spicuzza
4bd1f526ab [wpilibc] Prevent StopMotor from terminating robot during MotorSafety check (#4038)
- Nothing else in that function can throw, so protecting StopMotor should be sufficient
- Fixes #4036
2022-02-19 20:42:10 -08:00
Dustin Spicuzza
27847d7eb2 [sim] Expose GUI control functions via HAL_RegisterExtension (#4034) 2022-02-19 20:40:25 -08:00
Dustin Spicuzza
b2a8d3f0f3 [wpilibc] Add mechanism to reset MotorSafety list (#4037) 2022-02-19 20:38:30 -08:00
Tyler Veness
49adac9564 [wpilib] Check for signedness in ArcadeDriveIK() (#4028)
If xSpeed == -0.0 and zRotation > 0, the algorithm assumes it's in the
third quadrant instead of the first since +0.0 == -0.0.

Also added tests for inverse kinematic functions, fixed some
MecanumDrive test bugs, and added Java MecanumDrive.driveCartesianIK()
and KilloughDrive.driveCartesianIK() overloads with defaulted gyro angle
that C++ already had.

Fixes #4022.
2022-02-17 18:03:59 -08:00
Peter Johnson
a19d1133b1 [wpiutil] libuv: Fix sign compare warnings in gcc 11.2 (#4031) 2022-02-13 16:56:53 -08:00
Peter Johnson
dde91717e4 [build] cmake: Add ability to customize target warnings (#4032) 2022-02-13 16:53:55 -08:00
Peter Johnson
e9050afd67 [sim] Update sim match time to match real robot (#4024)
The real robot has match time set to -1.0 until it's enabled, and then
counts down. Disabling the robot sets the time to -1.0.

The sim GUI has been updated to add preset buttons for auto and teleop
match times. The enable match timing checkbox has been removed as it's
no longer required.

The DS socket plugin has also been fixed to properly initialize
matchTime to -1.0 and reset it to -1.0 on disable.
2022-02-12 22:31:10 -08:00
sciencewhiz
165d2837cf [wpilib] Preferences: Set Persistent in Init methods (#4025)
Fixes #4018
2022-02-12 22:30:02 -08:00
Peter Johnson
ac7549edca [glass] Fix snprintf truncation warning (#4029) 2022-02-12 22:29:26 -08:00
Jonah Snider
4d96bc72e0 [wpilibj] Fix typos in error messages for non-null assertions (#4014) 2022-02-11 18:11:15 -08:00
Dustin Spicuzza
3411eee20f [hal] Replace hardcoded sim array sizes with constants (#4015) 2022-02-10 00:12:07 -08:00
Dustin Spicuzza
74de97eeca [wpilibc] Add mechanism to reset various global structures (#4007) 2022-02-09 22:14:12 -08:00
sciencewhiz
4e3cc25012 [examples] Fix periodic function rate comment (NFC) (#4013)
Fixes #3979
2022-02-08 13:19:31 -08:00
Dustin Spicuzza
90c1db393e [sim] Add exported functions to control the sim GUI (#3995) 2022-02-07 00:39:45 -08:00
sciencewhiz
2f43274aa4 [wpilibj] MechanismRoot2d: Add flush to setPosition (#4011)
Fixes #4010.
2022-02-06 22:47:33 -08:00
Peter Johnson
aeca09db09 [glass] Support remapping of Enter key (#3994)
This is useful for editing of values without disabling the DS.
2022-02-06 00:11:37 -08:00
Peter Johnson
c107f22c67 [sim] Sim GUI: don't force-show Timing and Other Devices (#4001)
Instead preserve their saved visible state.
2022-02-06 00:11:12 -08:00
Peter Johnson
68fe51e8da [wpigui] Update PFD to latest, fix kdialog multiselect (#4005) 2022-02-06 00:10:43 -08:00
modelmat
8d08d67cf1 [wpigui] PFD: Add console warning if file chooser unavailable (#4003)
Also remove iostream use.
2022-02-06 00:10:20 -08:00
Dustin Spicuzza
4f1782f66e [wpilibc] Only call HAL_Report when initializing SmartDashboard (#4006) 2022-02-06 00:07:55 -08:00
Tyler Veness
3f77725cd3 Remove uses of iostream (#4004)
Most of these were unused, the IMU ones were just debug messages.

The only one that wasn't removed is in portable-file-dialogs.cpp since
the replacement looks less trivial.
2022-02-05 23:00:31 -08:00
Peter Johnson
5635f33a32 [glass] Increase plot depth to 20K points (#3993)
2K was sufficient for simulation because it's possible to pause time,
but isn't quite enough for looking at real robot data. 20K points
is 400 seconds at 50 Hz which should make pausing plots much more
useful.

As every point is looped over, this does increase CPU utilization
somewhat but doesn't seem to have much of an impact for typical
use cases. Increasing this further will necessitate some greater
optimizations (e.g. an initial cull using binary search).
2022-02-04 22:20:38 -08:00
Peter Johnson
bca4b7111b [glass] Fix PlotSeries::SetSource() (#3991)
This can be called in a delayed manner, so it's possible for
m_size to already be at maximum, which results in writing past
the end of the array. Instead, just call AppendValue().
2022-02-04 20:47:11 -08:00
Oblarg
6a6366b0d6 [commands] Add until() as alias for withInterrupt() (#3981)
This is a clearer description for the functionality.
Will deprecate withInterrupt next year.
2022-02-03 22:14:52 -08:00
Thad House
16bf2c70c5 [wpilib] Fix joystick out of range error messages (#3988) 2022-02-03 22:10:44 -08:00
Thad House
4b3edb742c [wpilib] Fix ADIS16448 IMU default constructor not working in Java (#3989)
Also fixes a few related uninitialized variables in C++.
2022-02-03 22:09:12 -08:00
Thad House
fcf23fc9e9 [hal] Fix potential gamedata out of bounds read (#3983)
The size was uninitialized.  If the size is smaller than the data,
NetComm just updates the size and does not initialize the data.
2022-02-01 22:22:48 -08:00
Jan-Felix Abellera
af5ef510c5 [wpilibc] Fix REV PH pulse duration units (#3982) 2022-02-01 20:28:48 -08:00
Jan-Felix Abellera
05401e2b81 [wpilib] Write REV PH firmware version to roboRIO to display on driver station (#3977) 2022-02-01 20:27:43 -08:00
Thad House
9fde0110b6 Update to 2022 v4.0 image (#3944) 2022-01-31 23:26:05 -08:00
sciencewhiz
b03f8ddb2e [examples] fix incorrect variable in Arm Simulation Pref (#3980) 2022-01-31 22:01:31 -08:00
sciencewhiz
a26df2a022 [examples] Update ArmSimulation example to use Preferences (#3976)
This shows more real world usage then hardcoding the setpoint and PID
gains. There were no current examples using Preferences. This will also
be used to update frc-docs article for Preferences.
2022-01-31 00:17:04 -08:00
Oblarg
d68d6674e8 [examples] Armbot: rename kCos to kG (#3975) 2022-01-31 00:16:26 -08:00
sciencewhiz
a8f0f6bb90 [wpilibj] Fix ADIS16448 getRate to return rate instead of angle (#3974) 2022-01-29 20:17:57 -08:00
Thad House
dd9c92d5bf [build] Remove debug info from examples (#3971)
They take up a LOT of disk space.
2022-01-27 20:59:13 -08:00
Thad House
84df14dd70 [rtns] Fix icons (#3972) 2022-01-27 20:58:07 -08:00
sciencewhiz
560094ad92 [examples] Correct Mecanum example axes (#3955) 2022-01-27 20:57:41 -08:00
Jan-Felix Abellera
7ea1be9c01 [wpilibc] Fix typo in hardware version for REV PDH (#3969) 2022-01-27 17:54:38 -08:00
Jan-Felix Abellera
700f13bffd [wpilibj] Make methods public for Java REV PDH (#3970) 2022-01-27 17:54:14 -08:00
Jan-Felix Abellera
b6aa7c1aa9 [wpilibj] Make methods public for Java REVPH (#3968) 2022-01-27 17:53:45 -08:00
Tyler Veness
eb4d183e48 [wpimath] Fix clang-tidy bugprone-integer-division warning (#3966)
The integer conversion is deliberate.
2022-01-26 18:38:45 -08:00
Thad House
77e4e81e1e [wpilib] Add Field widget to BuiltInWidgets in shuffleboard (#3961) 2022-01-24 20:33:11 -08:00
Thad House
88f5cb6eb0 [build] Publish PDBs with C++ tools (#3960) 2022-01-24 20:32:17 -08:00
Tyler Veness
efae552f3e [wpimath] Remove DifferentialDriveKinematics include from odometry (#3958) 2022-01-24 16:02:00 -08:00
sciencewhiz
46b277421a [glass] Update Speed Controller Type name for 2022 WPILib (#3952) 2022-01-21 21:30:44 -08:00
modelmat
42908126b9 [wpilib] Add DCMotorSim (#3910) 2022-01-21 20:42:06 -08:00
Peter Johnson
a467392cbd [wpiutil] StackTrace: Add ability to override default implementation (#3951) 2022-01-21 17:22:41 -08:00
modelmat
78d0bcf49d [templates] Add SimulationInit()/SimulationPeriodic() to robot templates (#3943) 2022-01-21 16:23:46 -08:00
sciencewhiz
02a0ced9b0 [wpilib] MecanumDrive: update docs for axis to match implementation (NFC) (#3942)
Added note that implementation may change in the future, #3930.
2022-01-21 16:22:17 -08:00
shueja-personal
4ccfe1c9f2 [wpilib] Added docs clarification on units for drive class WheelSpeeds (NFC) (#3939) 2022-01-21 15:51:28 -08:00
Peter Johnson
830c0c5c2f [wpilib] MechanismLigament2d: Add getters for color and line weight (#3947)
Also add missing locking in C++.
2022-01-21 15:47:44 -08:00
Peter Johnson
5548a37465 [wpilib] PowerDistribution: Add module type getter (#3948) 2022-01-21 15:46:44 -08:00
Thad House
2f9a600de2 [hal] Fix PCM one shot (#3949) 2022-01-21 15:46:08 -08:00
Thad House
559db11a20 [myRobot] Skip deploying debug libraries for myRobot deploys (#3950) 2022-01-21 15:45:47 -08:00
Lenny Abbas
76c78e295b [examples] Reorder SwerveModules in SwerveControllerCommand example odometry update (#3934) 2022-01-21 11:04:43 -08:00
sciencewhiz
debbd5ff4b [wpilib] Improve PowerDistribution docs (NFC) (#3925)
Add docs for switchable channel.
Use PDP/PDH appropriately and clarify differences.
Fix typos.
2022-01-20 23:33:01 -08:00
Tyler Veness
841174f302 [commands] Change command vendordep JSON version number to 1.0.0 (#3938)
While the number doesn't matter, it being old is confusing a lot of
people.  We never increment the internal vendordep versions, so using a year
version number was a poor choice.

Closes #3921.
2022-01-20 23:32:02 -08:00
sciencewhiz
8c55844f91 [wpilib] Remove comment about Mecanum right side inverted (NFC) (#3929) 2022-01-18 01:00:55 -08:00
Thad House
0b990bf0f5 [hal] Fix PCM sticky faults clear function crashing (#3932)
A call to the PCM clear function was using the wrong handle passed down to the CAN layer, causing an error.
2022-01-18 00:59:51 -08:00
Thad House
104d7e2abc [hal] Don't throw exceptions in PCM JNI (#3933)
Since the CAN bus can easily become disconnected, we don't want this to crash. Instead, we just want this to report errors. This matches previous behavior.
2022-01-18 00:58:26 -08:00
Lenny Abbas
5ba69e1af1 [examples] Updated type in Java SwerveModule (#3928)
Changed turnOutput from var to double in SwerveModule. It doesn't make sense for driveOutput and turnOutput to have different types so they should both be doubles.
2022-01-17 12:20:55 -08:00
Chirag Kaushik
f3a0b5c7d7 [wpimath] Fix Java SimpleMotorFeedforward Docs (NFC) (#3926) 2022-01-17 09:59:04 -08:00
Tyler Veness
7f4265facc [wpimath] Add LinearFilter::FiniteDifference() (#3900)
This allows making more general finite difference filters, like central
finite difference. SysId uses this for acceleration filtering.
2022-01-15 20:18:11 -08:00
Tyler Veness
63d1fb3bed [wpiutil] Modify fmt to not throw on write failure (#3919)
This was causing issues with tools, as the launchers would close stdout/stderr, resulting in write failures.
2022-01-15 20:10:32 -08:00
Tyler Veness
36af6d25a5 [wpimath] Fix input vector in pose estimator docs (NFC) (#3923) 2022-01-15 20:03:39 -08:00
Thad House
8f387f7255 [wpilibj] Switch ControlWord mutex to actual reentrant mutex (#3922)
It seems like the JVM does not handle recursive calls to object monitor based locks correctly. A few bugs in the past have been reported to have caused deadlocks if this occurs. It looks like the version of Java we use is fixed, but there could be other bugs, and it seems like this area of the code isn't tested much. Based on the stacks reported in #3896, it really seems like this is occurring. So we're going to attempt to switch to explicit mutex based classes, which shouldn't have bugs like this, and we will see if that fixes the issue.
2022-01-15 15:24:06 -08:00
David Vo
792e735e08 [wpimath] Move TrajectoryGenerator::SetErrorHandler definition to .cpp (#3920)
Otherwise this function causes linking errors when used on Windows.
2022-01-15 08:58:49 -08:00
Tyler Veness
3b76de83eb [commands] Fix ProfiledPIDCommand use-after-free (#3904)
Fixes #3903.
2022-01-14 23:56:48 -08:00
PJ Reiniger
ad9f738cfa [fieldimages] Fix maven publishing (#3897) 2022-01-14 23:55:10 -08:00
modelmat
49455199e5 [examples] Use left/rightGroup.Get() for simulator inputs to fix inversions (#3908) 2022-01-14 23:54:20 -08:00
modelmat
64426502ea [wpimath] Fix arm -> flywheel typo (NFC) (#3911) 2022-01-14 23:53:45 -08:00
Tyler Veness
8cc112d196 [wpiutil] Fix wpi::array for move-only types (#3917)
Fixes #3916.
2022-01-14 23:53:12 -08:00
Tyler Veness
e78cd49861 [build] Upgrade Java formatter plugins (#3894) 2022-01-11 22:24:16 -08:00
Tyler Veness
cfb4f756d6 [build] Upgrade to shadow 7.1.2 (#3893) 2022-01-11 21:10:15 -08:00
Tyler Veness
ba0908216c [wpimath] Fix crash in KF latency compensator (#3888)
It would crash in C++ if the global measurement was sooner than all the
snapshots.

Align Java with the changes and better document computation approach.
2022-01-09 23:01:04 -08:00
Peter Johnson
a3a0334fad [build] cmake: Move fieldImages to WITH_GUI (#3885)
This will only ever be used by GUI applications, and the jar build
method it uses can misbehave in some cross-compile scenarios.
2022-01-09 20:26:54 -08:00
sciencewhiz
cf7460c3a8 [fieldImages] Add 2022 field (#3883) 2022-01-08 23:24:24 -08:00
Tyler Veness
db0fbb6448 [wpimath] Fix LQR matrix constructor overload for Q, R, and N (#3884)
It was using the continuous B matrix to compute the feedback gain
instead of the discrete B matrix.

Tests were added for the matrix constructor overloads.
2022-01-08 23:23:53 -08:00
sciencewhiz
8ac45f20bb [commands] Update Command documentation (NFC) (#3881)
Add reference to which VendorDep the class is included in.
Add missing OldCommands C++ Documentation (copied from Java).
2022-01-08 11:11:34 -08:00
Tyler Veness
b3707cca0b [wpiutil] Upgrade to fmt 8.1.1 (#3879)
The changes to PneumaticsBase.cpp were to fix errors like the following
from enum classes not being formattable:
```
allwpilib/wpilibc/src/main/native/cpp/PneumaticsBase.cpp:36:9:   required from here
allwpilib/wpiutil/src/main/native/fmtlib/include/fmt/core.h:2672:12: error: use of deleted function ‘fmt::v8::detail::fallback_formatter<T, Char, Enable>::fallback_formatter() [with T = frc::PneumaticsModuleType; Char = char; Enable = void]’
 2672 |   auto f = conditional_t<has_formatter<mapped_type, context>::value,
      |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 2673 |                          formatter<mapped_type, char_type>,
      |                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 2674 |                          fallback_formatter<T, char_type>>();
      |                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
2022-01-08 11:10:42 -08:00
Tyler Veness
a69ee3ece9 [wpimath] Const-qualify Twist2d scalar multiply (#3882)
Fixes #3880.
2022-01-08 11:09:29 -08:00
Drew Williams
750d9a30c9 [examples] Fix Eigen out of range error when running example (#3877)
Simple typo fix.
2022-01-08 00:15:26 -08:00
Peter Johnson
41c5b2b5ac [rtns] Add cmake build (#3866)
This needs libssh to build, so on Linux systems it's necessary to
install libssh-dev.
2022-01-08 00:14:48 -08:00
Tyler Veness
6cf3f9b28e [build] Upgrade to Gradle 7.3.3 (#3878)
This is the same version robot projects currently use.
2022-01-08 00:14:27 -08:00
Starlight220
269cf03472 [examples] Add communication examples (e.g. arduino) (#2500)
Co-authored-by: Andrew Dassonville <dassonville.andrew@gmail.com>
2022-01-06 18:08:57 -08:00
sciencewhiz
5ccfc4adbd [oldcommands] Deprecate PIDWrappers, since they use deprecated interfaces (#3868) 2022-01-06 18:05:24 -08:00
Peter Johnson
b6f44f98be [hal] Add warning about onboard I2C (#3871)
Adds HAL layer warning for #3842. This is needed in the case when a
vendor uses the HAL directly rather than using the WPILib I2C class.

This should not result in a duplicate warning for WPILib I2C users due
to the duplicate message checking performed in HAL_SendError().

We don't want to remove the WPILib I2C warning because it gives stack
trace information while the HAL layer one can't.
2022-01-06 17:44:27 -08:00
Peter Johnson
0dca57e9ec [templates] romieducational: Invert drivetrain and disable motor safety (#3869) 2022-01-06 11:29:15 -08:00
Tyler Veness
22c4da152e [wpilib] Add GetRate() to ADIS classes (#3864)
The angular rate is treated somewhat like an angle during calibration,
but the datasheet says it's angular rate. The variables were renamed to
make this clearer.
2022-01-04 22:26:23 -08:00
Peter Johnson
05d66f862d [templates] Change the template ordering to put command based first (#3863)
Previously it was a bit buried.
2022-01-04 21:23:57 -08:00
Dustin Spicuzza
b09f5b2cf2 [wpilibc] Add virtual dtor for LinearSystemSim (#3861) 2022-01-03 21:25:02 -08:00
Tyler Veness
a2510aaa0e [wpilib] Make ADIS IMU classes unit-safe (#3860)
The gyro rate getters were removed since that data isn't available.
2022-01-03 20:00:53 -08:00
Tyler Veness
947f589916 [wpilibc] Rename ADIS_16470_IMU.cpp to match class name (#3859) 2022-01-03 17:53:57 -08:00
Peter Johnson
bbd8980a20 [myRobot] Fix cameraserver library order (#3858) 2022-01-03 11:59:29 -08:00
Tyler Veness
831052f118 [wpilib] Add simulation support to ADIS classes (#3857) 2022-01-03 11:44:12 -08:00
Noah Andrews
c137569f91 [wpilib] Throw exception if the REV Pneumatic Hub firmware version is older than 22.0.0 (#3853) 2022-01-03 11:09:30 -08:00
sciencewhiz
dae61226fa Fix Maven Artifacts readme (#3856)
Add wpiutil to wpimath
Add wpimath to wpilibj and wpilibc
2022-01-03 10:18:49 -08:00
sciencewhiz
3ad4594a88 Update Maven artifacts readme for 2022 (#3855) 2022-01-01 13:28:36 -08:00
Matteo Kimura
112acb9a62 [wpilibc] Move ADIS IMU constants to inside class (#3852) 2022-01-01 11:40:28 -08:00
Peter Johnson
ecee224e81 [wpilib] Allow SendableCameraWrappers to take arbitrary URLs (#3850)
Useful for adding cameras that are streamed from a coprocessor

Co-authored-by: Peter Johnson <johnson.peter@gmail.com>
Co-authored-by: Sam Carlberg <sam.carlberg@gmail.com>
2022-01-01 10:10:37 -08:00
Peter Johnson
a3645dea34 LICENSE: Bump year range to include 2022 (#3854) 2022-01-01 00:00:16 -08:00
Jan-Felix Abellera
7c09f44898 [wpilib] Use PSI for compressor config and sensor reading (#3847)
This adds the REV Analog Pressure Sensor PSI to volt (and vice versa) conversion to allow setting the compressor config in PSI and getting the sensor reading in PSI. Also adds input validation for pressure values at the higher level.

Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2021-12-31 21:04:56 -08:00
Peter Johnson
f401ea9aae [wpigui] Remove wpiutil linkage (#3851)
It was only being used for fs::remove() (added in #3463), which is easily
replaced by std::remove().

The code change does not affect the WPILib tools, as this code is not used when JSON save files are used.
2021-12-31 07:56:31 -08:00
Peter Johnson
bf8517f1e6 [wpimath] TimeInterpolatableBufferTest: Fix lint warnings (#3849) 2021-12-31 00:06:08 -08:00
David Vo
528087e308 [hal] Use enums with fixed underlying type in clang C (#3297)
This will allow static analysis tools that use clang to always determine the correct intended parameter types for HAL functions.
2021-12-30 21:20:05 -08:00
Thad House
1f59ff72f9 [wpilib] Add ADIS IMUs (#3777)
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
Co-authored-by: Matteo Kimura <mateus.sakata@gmail.com>
2021-12-30 19:43:53 -08:00
Matt
315be873c4 [wpimath] Add TimeInterpolatableBuffer (#2695)
These classes are useful for storing previous robot positions to use in conjunction with the upcoming pose estimators.

Co-authored-by: Prateek Machiraju <prateek.machiraju@gmail.com>
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
Co-authored-by: cttew <cttewari@gmail.com>
2021-12-30 19:08:05 -08:00
Oblarg
b8d019cdb4 [wpilib] Rename NormalizeWheelSpeeds to DesaturateWheelSpeeds (#3791) 2021-12-30 18:30:08 -08:00
Peter Johnson
102f23bbdb [wpilibj] DriverStation: Set thread interrupted state (#3846)
This is a Java best practice when catching InterruptedException.
2021-12-30 13:13:52 -08:00
Kevin-OConnor
b85c24a79c [wpilib] Add warning about onboard I2C (#3842) 2021-12-30 13:13:03 -08:00
Oblarg
eee29daaf9 [newCommands] Trigger: Allow override of debounce type (#3845)
Previously Trigger could only be debounced on rising edges.
This change preserves the default behavior but adds the capability to override it.
2021-12-29 16:10:43 -08:00
Oblarg
aa9dfabde2 [wpimath] Move debouncer to filters (#3838) 2021-12-28 09:49:41 -08:00
Peter Johnson
5999a26fba [wpiutil] Add GetSystemTime() (#3840)
This portably gets the time in microseconds since the Unix epoch.
2021-12-27 23:06:31 -08:00
sciencewhiz
1e82595ffb [examples] Fix arcade inversions (#3841)
Accounts for differences between ArcadeDrive and the methods used
in some other examples.
2021-12-27 23:05:42 -08:00
Peter Johnson
e373fa476b [wpiutil] Add disableMockTime to JNI (#3839)
This exposes the equivalent of SetNowImpl(nullptr) to Java.
2021-12-27 09:51:32 -08:00
sciencewhiz
dceb5364f4 [examples] Ensure right side motors are inverted (#3836)
Fixes #3827
Adds MotorController inversion for right side, removes inversion in
setVoltage methods.

Also fixes various XboxController negations (was inconsistent throughout examples).
2021-12-26 19:25:26 -08:00
Oblarg
baacbc8e24 [wpilib] Tachometer: Add function to return RPS (#3833) 2021-12-26 15:52:18 -08:00
Austin Shalit
84b15f0883 [templates] Add Java Romi Educational template (#3837)
This is a combination of a Romi Gradle project and Educational robot (added in #3309)
2021-12-26 15:46:22 -08:00
Dalton Smith
c0da9d2d35 [examples] Invert Right Motor in Romi Java examples (#3828) 2021-12-26 15:42:53 -08:00
sciencewhiz
0fe0be2733 [build] Change project year to intellisense (#3835)
This means VSCode won't prompt to upgrade (added in beta 4)
2021-12-25 20:50:06 -06:00
Tyler Veness
eafa947338 [wpimath] Make copies of trajectory constraint arguments (#3832)
This avoids stack-use-after-scope bugs in code like the following when
the original argument goes out of scope:
```cpp
frc2::Command* RobotContainer::GetAutonomousCommand() {
  // Create a voltage constraint to ensure we don't accelerate too fast
  frc::DifferentialDriveVoltageConstraint autoVoltageConstraint(
      frc::SimpleMotorFeedforward<units::meters>(
          DriveConstants::ks, DriveConstants::kv, DriveConstants::ka),
      DriveConstants::kDriveKinematics, 10_V);
```
2021-12-25 07:19:43 -06:00
sciencewhiz
9d13ae8d01 [wpilib] Add notes for Servo get that it only returns cmd (NFC) (#3820)
Co-authored-by: Peter Johnson <johnson.peter@gmail.com>
2021-12-23 22:22:18 -08:00
Tyler Veness
2a64e4bae5 [wpimath] Give drivetrain a more realistic width in TrajectoryJsonTest.java (#3822)
Fixes #3819.
2021-12-22 22:28:23 -08:00
Tyler Veness
c3fd20db59 [wpilib] Fix trajectory sampling in DifferentialDriveSim test (#3821)
Also rename C++ test file to match class name.

Fixes #3818.
2021-12-22 22:27:51 -08:00
WarrenReynolds
6f91f37cd0 [examples] Fix SwerveControllerCommand order of Module States (#3815)
DriveSubsystem::SetModulesStates applies module state to incorrect modules.

Fixes #3814.
2021-12-22 12:26:02 -08:00
Peter Johnson
5158730b81 [wpigui] Upgrade to imgui 1.86, GLFW 3.3.6 (#3817)
The GLFW upgrade fixes gamepads not being mapped at startup.
2021-12-22 12:24:36 -08:00
Thad House
2ad2d2ca96 [wpiutil] MulticastServiceResolver: Fix C array returning functions (#3816) 2021-12-22 09:52:57 -08:00
Starlight220
b5fd29774f [wpilibj] Trigger: implement BooleanSupplier interface (#3811) 2021-12-21 11:33:16 -08:00
sciencewhiz
9f8f330e96 [wpilib] Fix Mecanum and SwerveControllerCommand when desired rotation passed (#3808) 2021-12-19 20:08:28 -08:00
Tyler Veness
1ad3b1b333 [hal] Don't copy byte to where null terminator goes (#3807)
Fixes the following compiler warning:
```
/__w/allwpilib/allwpilib/hal/src/main/native/sim/Notifier.cpp:323:21: error: 'char* strncpy(char*, const char*, size_t)' specified bound 64 equals destination size [-Werror=stringop-truncation]
         std::strncpy(arr[num].name, notifier->name.c_str(),
         ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                      sizeof(arr[num].name));
                      ~~~~~~~~~~~~~~~~~~~~~~
```
2021-12-19 16:46:12 -08:00
Thad House
dfc24425c3 [build] Fix gazebo gradle IDE warnings (#3806)
Also add note on how to generate all files for the IDE.
2021-12-19 14:20:08 -08:00
Thad House
c02577bb51 [glass] Configure delay loading for windows camera server support (#3803)
We don't currently support cameras in glass, but it's something we want to do in the future. However, when we do this, glass will completely stop working on N builds of windows, and it would fail to load at all with no messages. To solve this, we can delayload the media foundation dlls that are missing. The executable will then launch even without the dlls present, and we can attempt to load them at runtime and dynamically disable camera support.

When we get around to implementing it, we can just call HasCameraSupport, and dynamically hide all camera related code behind that flag.
2021-12-19 14:19:24 -08:00
sciencewhiz
c9e6a96a61 [wpilib] Document range of Servo angle (NFC) (#3796) 2021-12-19 13:53:31 -08:00
Thad House
9778626f34 [wpilib, hal] Add support for getting faults and versions from power distribution (#3794) 2021-12-19 13:42:49 -08:00
Thad House
34b2d0dae1 [wpilib, hal] High Level REV PH changes (#3792)
More functionality was implemented at the HAL level, so expose that to the wpilib level.

This also does units changes for all the PH related functionality.
2021-12-19 13:41:35 -08:00
Thad House
59a7528fd6 [cscore] Fix crash when usbcamera is deleted before message pump thread fully starts (#3804)
shared_from_this will assert if the shared pointer is in the middle of being destructed. Because we access shared_from_this in the message pump, this can easily occur. The solution is to grab the weak pointer, manually attempt to lock it, and only continue if that succeeds. The message pump is already synchronized to the usb camera being destructed, so this is a fine behavior.
2021-12-19 13:39:23 -08:00
Thad House
11d9859ef1 [build] Update plugins to remove log4j vulnerabilities (#3805) 2021-12-19 13:38:48 -08:00
Peter Johnson
e44ed752ad [glass] Fix CollapsingHeader in Encoder, PCM, and DeviceTree (#3797)
The new storage approach was attempting to save both the name and the
open status to the same storage key.
2021-12-19 07:35:12 -08:00
Thad House
52b2dd5b89 [build] Bump native utils to remove log4j (#3802) 2021-12-19 07:33:12 -08:00
sciencewhiz
c46636f218 [wpilib] Improve new counter classes documentation (NFC) (#3801) 2021-12-18 21:40:03 -08:00
sciencewhiz
dc531462e1 [build] Update to gradle 7.3.2 (#3800) 2021-12-18 21:34:35 -08:00
Tyler Veness
92ba98621c [wpimath] Add helper variable templates for units type traits (#3790) 2021-12-18 11:32:32 -08:00
sciencewhiz
d41d051f1b [wpilibc] Fix Mecanum & Swerve ControllerCommand lambda capture (#3795)
Fixes #3765
Also fixes SwerveControllerCommand example calling command twice.
2021-12-18 11:30:57 -08:00
sciencewhiz
c5ae0effac OtherVersions.md: Add one missing case of useLocal (#3788) 2021-12-15 20:30:34 -08:00
Tyler Veness
b3974c6ed3 [wpimath] Upgrade to Drake v0.37.0 (#3786) 2021-12-14 06:41:38 -08:00
Peter Johnson
589a00e379 [wpilibc] Start DriverStation thread from RobotBase (#3785)
With the change from GetInstance to static functions, many functions
don't call DriverStation::GetInstance(), so the DS thread wasn't
getting started by default.  Call InDisabled() to make sure this
happens.
2021-12-12 22:23:13 -08:00
Tyler Veness
8d9836ca02 [wpilib] Improve curvature drive documentation (NFC) (#3783) 2021-12-12 17:59:04 -08:00
Peter Johnson
8b5bf8632e [myRobot] Add wpimath and wpiutil JNI (#3784) 2021-12-12 17:57:52 -08:00
sciencewhiz
1846114491 [examples] Update references from characterization to SysId (NFC) (#3782) 2021-12-11 21:25:43 -08:00
Thad House
2c461c794e [build] Update to gradle 7.3 (#3778) 2021-12-10 21:26:28 -08:00
Jan-Felix Abellera
109363daa4 [hal] Add remaining driver functions for REVPH (#3776)
Add the remaining HAL functions needed to fully support the Pneumatic Hub and its latest firmware.

- Clear sticky faults
- Get device voltage
- Get 5v supply voltage (used for analog to PSI calculation)
- Get solenoid voltage
- Get solenoid current
- Get device firmware and hardware version

Some minor refactoring was done for naming of some internal functions for consistency purposes.
2021-12-09 12:29:09 -08:00
Jan-Felix Abellera
41d26bee8d [hal] Refactor REV PDH (#3775)
Refactors retrieving the faults from the device to match the implementation that we have for the Pneumatic Hub. Instead of having a getter function for each fault, there is a single function to get all faults (sticky or normal) for use with the higher level API

Renames functions to be consistent

Removes some functions that don't need to be included in wpilib:
- Identify device - this just flashes the module LED on the device and has no use in wpilib
- Is PDH enabled - the PDH does not change state depending on robot enabled state

PDH frame and signal names were updated in our DBC, and this PR makes use of the newly generated CAN frame helper functions
2021-12-09 12:27:06 -08:00
Tyler Veness
7269a170fb Upgrade maven deps to latest versions and fix new linter errors (#3772)
This also makes the Gradle build work with JDK 17.

The extra JVM args in gradle.properties works around a bug with spotless
and JDK 17: https://github.com/diffplug/spotless/issues/834

PMD.CloseResource was ignored because it's almost always a false
positive, and there are many of them.
2021-12-09 12:20:08 -08:00
Thad House
441f2ed9b0 [build] actions: use fixed image versions instead latest (#3761) 2021-12-09 12:12:59 -08:00
Modelmat
15275433d4 [examples] Fix duplicate port allocations in C++ SwerveBot/SwerveDrivePoseEstimator/RomiReference (#3773)
- Remove duplicate motor port (2) from C++ SwerveBot/SwerveDrivePoseEstimator

Java has the correct motor ports.

- Fix duplicate port allocation in C++ RomiReference by correcting if/else check

Java logic was already correct, and confirms this change.
2021-12-06 21:08:34 -08:00
Jason Daming
1ac02d2f58 [examples] Fix drive Joystick axes in several examples (#3769) 2021-12-06 16:40:10 -08:00
Jason Daming
8ee6257e92 [wpilib] DifferentialDrivetrainSim.KitbotMotor: Add NEO and Falcon 500 (#3762) 2021-12-06 14:46:58 -08:00
Prateek Machiraju
d81ef2bc5c [wpilib] Fix deadlocks in Mechanism2d et al. (#3770)
UpdateEntries() and Flush() are called from methods that lock the mutex,
so locking it again will cause deadlocks. This also updates the Java
code to make MechanismObject2d::update synchronized like in the C++
version.
2021-12-06 14:42:02 -08:00
Tyler Veness
acb64dff97 [wpimath] Make RamseteController::Calculate() more concise (#3763) 2021-12-06 12:57:42 -08:00
Jan-Felix Abellera
3f6cf76a8c [hal] Refactor REV PH CAN frames (#3756) 2021-12-06 10:08:57 -08:00
Peter Johnson
3ef2dab465 [wpilib] DutyCycleEncoder: add setting of duty cycle range (#3759)
As the sensor needs to maintain an actual duty cycle, it can't go all
the way from 0-100, so provide a way to set the min and max and linearly
map between the two.
2021-12-05 14:28:08 -08:00
sciencewhiz
a5a56dd067 Readme: Add Visual Studio 2022 (#3760) 2021-12-05 14:27:37 -08:00
Tyler Veness
04957a6d30 [wpimath] Fix units of RamseteController's b and zeta (#3757)
Fixes #3755.
2021-12-03 18:21:30 -08:00
Peter Johnson
5da54888f8 [glass] Upgrade imgui to 0.85, implot to HEAD, glfw to 3.3.5 (#3754)
This in particular upgrades the plot widget with a few new features
and makes more plot configuration persistent.
2021-12-03 17:23:18 -08:00
Thad House
6c93365b0f [wpiutil] MulticastService cleanup (#3750)
Fix duplicated constructors, and also use simpler utf conversion API on windows.
2021-12-02 21:06:55 -08:00
Thad House
1c4a8bfb66 [cscore] Cleanup Windows USB camera impl (#3751)
- Use wpiutil string conversion rather than codecvt (which is deprecated).
- Force A function types.
2021-12-02 13:48:03 -08:00
Thad House
d51a1d3b3d [rtns] Fix icon (#3749) 2021-11-30 21:58:58 -08:00
Thad House
aced2e7da6 Add roboRIO Team Number Setter tool (#3744) 2021-11-30 11:17:30 -08:00
Thad House
fa1ceca83a [wpilibj] Use DS cache for iterative robot control word cache (#3748)
The root cause of #3747 is CommandScheduler's ds state checks are behind iterative robots checks. This means that the iterative robot state could return enabled, but the DS cache could still be reporting disabled. This results in a race in the Disabled -> Enabled transition, which manifests in commands not running.

Previously, iterative robot base pulled from the DS cache. This meant that the ds cache was always updated before an iterative robot base loop could run. This still had a race, but this could only occur on the Enabled -> Disable transition, which is much less noticeable and would usually just result in a command running for an extra loop.

We can move back to the old behavior by grabbing the new iterative robot base check variables to use the DS cache.
2021-11-29 20:56:58 -08:00
sciencewhiz
0ea05d34e6 [build] Update to gradle 7.2 (#3746) 2021-11-29 20:53:26 -08:00
Thad House
09db4f672b [build] Update to native utils 2022.6.1 (#3745) 2021-11-29 13:04:08 -08:00
Thad House
4ba80a3a8c [wpigui] Don't recursively render frames in size callback (#3743)
WindowSizeCallback can sometimes be called while doing a render. If this occurs, imgui asserts. Avoid this case.
2021-11-28 01:03:40 -08:00
Peter Johnson
ae208d2b17 [wpiutil] StringExtras: Add substr() (#3742)
Unlike std::string and std::string_view, this substr() allows a start
greater than the length of the string, in which case an empty string
is returned.  This matches llvm::StringRef behavior.
2021-11-27 21:31:40 -08:00
Thad House
6f51cb3b98 [wpiutil] MulticastResolver: make event manual reset, change to multiple read (#3736) 2021-11-27 11:16:24 -08:00
Peter Johnson
f6159ee1a2 [glass] Fix Drive widget handling of negative rotation (#3739)
This would crash in debug mode due to an imgui assertion in PathArcTo.
2021-11-27 10:58:45 -08:00
Thad House
7f401ae895 [build] Update NI libraries to 2022.2.3 (#3738) 2021-11-27 09:43:07 -08:00
Peter Johnson
0587b7043a [glass] Use JSON files for storage instead of imgui ini
Storage is now nested.

Separate "roots" can be configured which save to separate files.
In particular, this is used to save wpigui and ImGui window position
to a -window.json file.

ImGui's ini (for window position) is mapped to JSON.

You can optionally specify a directory to load from on the command line.
If one isn't provided, it uses the global system directory.
Any changes made are automatically saved here.

Workspace | Open: select directory, the current layout is replaced with that
workspace, and future auto-saves also switch to that location. The main
window size/location is not changed, only the contents.

Workspace | Save As: select directory, the current layout is saved there,
and future auto-saves also switch to that location.

Workspace | Reset: window locations are preserved, but all other settings
are reset to default (including e.g. removing plot windows). This will also
end up clearing the current save file. as with load, the main window
size/location is not changed.

Workspace | Save As Global: "save as" to the global system location

Notably, the main window size/location is only loaded at startup, but is
auto-saved as part of the current workspace.
2021-11-27 00:12:13 -08:00
Peter Johnson
0bbf51d566 [wpigui] Change maximized to bool 2021-11-27 00:12:13 -08:00
Peter Johnson
92c6eae6b0 [wpigui] PFD: Add explicit to constructors 2021-11-27 00:12:13 -08:00
Peter Johnson
141354cd79 [wpigui] Add hooks for custom load/save settings
Add GetPlatformSaveFileDir().
2021-11-27 00:12:13 -08:00
Thad House
f6e9fc7d71 [wpiutil] Handle multicast service collision on linux (#3734) 2021-11-26 23:20:54 -08:00
Peter Johnson
d8418be7d1 [glass, outlineviewer] Return 0 from WinMain (#3735)
While this is implicit in main(), WinMain() requires an explicit return.
2021-11-26 23:19:45 -08:00
Thad House
82066946e5 [wpiutil] Add mDNS resolver and announcer (#3733) 2021-11-25 22:08:26 -08:00
Thad House
4b1defc8d8 [wpilib] Remove automatic PD type from module type enum (#3732)
Using automatic type doesn't work with any module number, so the API was confusing.
2021-11-23 23:03:45 -08:00
Oblarg
da90c1cd2c [wpilib] Add bang-bang controller (#3676)
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2021-11-23 20:34:46 -08:00
Thad House
3aa54fa027 [wpilib] Add new counter implementations (#2447) 2021-11-23 20:33:36 -08:00
Thad House
b156db400d [hal, wpilib] Incorporate pneumatic control type into wpilibc/j (#3728) 2021-11-23 20:32:02 -08:00
sciencewhiz
9aba2b7583 [oldCommands] Add wrappers for WPILib objects to work with old PID Controller (#3710) 2021-11-23 20:30:30 -08:00
Jan-Felix Abellera
a9931223f0 [hal] Add REV PH faults (#3729) 2021-11-22 21:15:32 -08:00
Tyler Veness
aacf9442e4 [wpimath] Fix units typo in LinearSystemId source comment (#3730) 2021-11-22 21:14:38 -08:00
Tyler Veness
7db10ecf00 [wpilibc] Make SPI destructor virtual since SPI contains virtual functions (#3727) 2021-11-20 11:21:02 -08:00
Tyler Veness
a0a5b2aea5 [wpimath] Upgrade to EJML 0.41 (#3726) 2021-11-20 01:02:37 -08:00
Jan-Felix Abellera
eb835598a4 [hal] Add HAL functions for compressor config modes on REV PH (#3724) 2021-11-20 01:02:23 -08:00
Tyler Veness
f0ab6df5b6 [wpimath] Upgrade to Drake v0.36.0 (#3722) 2021-11-16 14:37:29 -08:00
sciencewhiz
075144faa3 [docs] Parse files without extensions with Doxygen (#3721)
Fixes inclusion of wpi::numbers and some Eigen files
2021-11-16 11:22:34 -08:00
Thad House
32468a40cb [hal] Remove use of getDmaDescriptor from autospi (#3717)
It’s not necessary, as the index equals the channel.
2021-11-13 08:55:21 -08:00
Vasista Vovveti
38611e9dd7 [hal] Fix REVPH Analog Pressure channel selection (#3716) 2021-11-10 18:22:18 -08:00
sciencewhiz
4d78def31e [wpilib] Add DeadbandElimination forwarding to PWMMotorController (#3714) 2021-11-09 21:24:47 -08:00
Tyler Veness
3be0c1217a [wpilibcExamples] Make GearsBot use idiomatic C++ (#3711)
Replace pointer constructor arguments with references, and const qualify
getters where possible.

Also remove redundant simulation P gain.

Fixes #1146.
2021-11-09 20:11:50 -08:00
Tyler Veness
42d3a50aa2 [hal] Check error codes during serial port initialization (#3712)
Throw if serial port init fails.

Fixes #2036.
2021-11-09 20:10:48 -08:00
PJ Reiniger
52f1464029 Add project with field images and their json config files (#3668) 2021-11-08 22:48:16 -08:00
Thad House
68ce62e2e9 [hal] Add autodetect for power modules (#3706)
Default autodetect to REV if no devices are found, as only the REV devices have control functionality (the switchable output).
2021-11-07 13:53:38 -08:00
Thad House
3dd41c0d37 [wpilib] Don't print PD errors for LiveWindow reads (#3708)
If something happens with the PD connection, these would have spammed messages continuously.
This wasn't the case previously, and we don't want this behavior now.
2021-11-07 13:45:28 -08:00
Thad House
7699a1f827 [hal] Fix sim not working with automatic PD type and default module (#3707) 2021-11-05 23:30:10 -07:00
Peter Johnson
e473a00f97 [wpiutil] Base64: Add unsigned span/vector variants (#3702) 2021-11-01 07:48:26 -07:00
Peter Johnson
52f2d580eb [wpiutil] raw_uv_ostream: Add reset() (#3701)
This enables reuse of a raw_uv_ostream object.
2021-11-01 07:47:13 -07:00
Peter Johnson
d7b1e3576f [wpiutil] WebSocket: move std::function (#3700) 2021-11-01 07:46:15 -07:00
sciencewhiz
93799fbe9d [examples] Fix description of TrapezoidProfileSubsystem (#3699) 2021-11-01 00:08:53 -07:00
Tyler Veness
b84644740d [wpimath] Document pose estimator states, inputs, and outputs (#3698)
Fixes #3244.
2021-10-29 17:37:13 -07:00
Tyler Veness
2dc35c1399 [wpimath] Fix classpaths for JNI class loads (#3697)
Found by inspecting the results of the following rg commands:
`rg --multiline 'FindClass\(\s*"'`
`rg 'JClass' -A 1`

Fixes #3660.
2021-10-29 16:23:46 -07:00
Tyler Veness
2cb171f6f5 [docs] Set Doxygen extract_all to true and fix Doxygen failures (#3695)
The template argument order for UnscentedTransform was reversed to match
all the other UKF classes. Since UnscentedTransform is intended as a
class for internal use only, this shouldn't cause much breakage.
2021-10-29 15:07:05 -07:00
Tyler Veness
a939cd9c89 [wpimath] Print uncontrollable/unobservable models in LQR and KF (#3694)
IsDetectable() was added to make the code easier to read.
2021-10-29 00:03:02 -07:00
Tyler Veness
d5270d113b [wpimath] Clean up C++ StateSpaceUtil tests (#3692) 2021-10-29 00:02:03 -07:00
Tyler Veness
b20903960b [wpimath] Remove redundant discretization tests from StateSpaceUtilTest (#3689)
DiscretizationTest already does these.
2021-10-29 00:01:41 -07:00
Tyler Veness
c0cb545b41 [wpilibc] Add deprecated Doxygen attribute to SpeedController (#3691)
Fixes #3690.
2021-10-29 00:01:04 -07:00
Tyler Veness
35c9f66a75 [wpilib] Rename PneumaticsHub to PneumaticHub (#3686)
Fixes #3684.
2021-10-29 00:00:31 -07:00
Tyler Veness
796d03d105 [wpiutil] Remove unused LLVM header (#3688) 2021-10-28 00:18:26 -07:00
Tyler Veness
8723caf78d [wpilibj] Make Java TrapezoidProfile.Constraints an immutable class (#3687) 2021-10-28 00:17:36 -07:00
Tyler Veness
187f50a344 [wpimath] Catch incorrect parameters to state-space models earlier (#3680)
This allows giving more descriptive exceptions than if they are thrown
later in KalmanFilter, for example.

Fixes #3678.
2021-10-27 20:18:57 -07:00
Tyler Veness
8d04606c4d Replace instances of frc-characterization with SysId (NFC) (#3681) 2021-10-27 06:40:17 -07:00
Peter Johnson
b82d4f6e58 [hal, cscore, ntcore] Use WPI common handle type base 2021-10-26 23:39:11 -07:00
Peter Johnson
87e34967ef [wpiutil] Add synchronization primitives
These enable more consistent use of synchronization across the
native libraries.  Users can create Event and Semaphore primitives, but
in addition, libraries can set up any handle as an Event-type signal.
2021-10-26 23:39:11 -07:00
Peter Johnson
e32499c546 [wpiutil] Add ParallelTcpConnector (#3655)
This is a libuv-based parallel, repeating TCP connector for making
multiple parallel DNS resolution and TCP connection attempts to a
network server.
2021-10-26 23:37:58 -07:00
Tyler Veness
aa0b49228d [wpilib] Remove redundant "quick turn" docs for curvature drive (NFC) (#3674)
The parameter docs for allowTurnInPlace say the same thing, and it's no
longer called "quick turn".
2021-10-26 23:37:11 -07:00
Noah Andrews
57301a7f9c [hal] REVPH: Start closed-loop compressor control on init (#3673)
Similar to the PCM, we're going to make the PH not do anything with the compressor until the PH HAL object has been initialized. The mechanism we're going to use to signal to the PH that that has happened is to begin sending the state of the solenoids (which will all be set to off at this point).
2021-10-26 23:36:47 -07:00
sciencewhiz
d1842ea8fb [wpilib] Improve interrupt docs (NFC) (#3679) 2021-10-26 23:35:01 -07:00
Peter Johnson
558151061e [wpiutil] Add DsClient (#3654)
This is a libuv-based implementation of the Driver Station client
for getting robot IPs from the Driver Station port 1742 server.
2021-10-26 23:34:27 -07:00
Tyler Veness
181723e573 Replace .to<double>() and .template to<double>() with .value() (#3667)
It's a less verbose way to do the same thing.
2021-10-25 08:58:12 -07:00
sciencewhiz
6bc1db44bc [commands] Add pointer overload of AddRequirements (artf6003) (#3669)
Also update documentation in CommandBase.
2021-10-25 08:57:22 -07:00
Tyler Veness
737b57ed5f [wpimath] Update to drake v0.35.0 (#3665) 2021-10-22 23:02:08 -07:00
Austin Shalit
4d287d1ae2 [build] Upgrade WPIJREArtifact to JRE 2022-11.0.12u5 (#3666) 2021-10-22 23:01:09 -07:00
apple
f26eb5ada4 [hal] Fix another typo (get -> gets) (NFC) (#3663) 2021-10-22 11:49:21 -07:00
apple
94ed275ba6 [hal] Fix misspelling (numer -> number) (NFC) (#3662) 2021-10-22 07:23:13 -07:00
Peter Johnson
ac2f44da33 [wpiutil] uv: use move for std::function (#3653)
Also use function_ref for Loop::Walk().
2021-10-20 23:24:59 -07:00
Peter Johnson
75fa1fbfbf [wpiutil] json::serializer: Optimize construction (#3647)
Remove unused locale pointer.
2021-10-20 21:09:04 -07:00
Peter Johnson
5e689faea8 [wpiutil] Import MessagePack implementation (mpack) (#3650) 2021-10-20 21:08:31 -07:00
Peter Johnson
649a50b401 [wpiutil] Add LEB128 byte-by-byte reader (#3652)
This is needed for compatibility with streaming data (e.g. libuv) where partial data
may be received.  Also add raw_ostream writer.
2021-10-20 18:50:20 -07:00
Peter Johnson
e94397a97d [wpiutil] Move json_serializer.h to public headers (#3646)
This makes it possible to do "manual" JSON-compliant serialization more efficiently
(e.g. without needing to construct a full json object).
2021-10-20 11:18:13 -07:00
Peter Johnson
4ec58724d7 [wpiutil] uv::Tcp: Clarify SetNoDelay documentation (#3649) 2021-10-20 08:46:44 -07:00
Peter Johnson
8cb294aa4a [wpiutil] WebSocket: Make Shutdown() public (#3651) 2021-10-20 08:45:58 -07:00
Peter Johnson
2b3a9a52b3 [wpiutil] json: Fix map iterator key() for std::string_view (#3645) 2021-10-20 08:45:16 -07:00
Peter Johnson
138cbb94b2 [wpiutil] uv::Async: Add direct call for no-parameter specialization (#3648) 2021-10-20 08:44:33 -07:00
sciencewhiz
e56d6dea81 [ci] Update testbench pool image to ubuntu-latest (#3643) 2021-10-18 21:39:43 -07:00
sciencewhiz
43f30e44e4 [build] Enable comments in doxygen source files (#3644) 2021-10-18 21:39:22 -07:00
sciencewhiz
9e6db17ef4 [build] Enable doxygen preprocessor expansion of WPI_DEPRECATED (#3642)
This fixes documentation for SpeedController and SpeedControllerGroup
2021-10-18 21:29:23 -07:00
sciencewhiz
0e631ad2f2 Add WPILib version to issue template (#3641) 2021-10-18 09:09:57 -07:00
Austin Shalit
6229d8d2ff [build] Docs: set case_sense_names to false (#3392)
This means the output will be consistent for all 3 major os and prevent case issues when sharing files.
2021-10-15 00:37:59 -07:00
Tyler Veness
4647d09b50 [docs] Fix Doxygen warnings, add CI docs lint job (#3639)
The CI docs lint build is configured to fail on Doxygen warnings.
2021-10-14 18:09:38 -07:00
sciencewhiz
4ad3a54026 [hal] Fix PWM allocation channel (#3637)
Previously it showed 31 when 0 was doubly allocated
2021-10-14 07:28:49 -07:00
sciencewhiz
05e5feac41 [docs] Fix brownout docs (NFC) (#3638) 2021-10-14 07:28:21 -07:00
Prateek Machiraju
67df469c58 [examples] Remove old command-based templates and examples (#3263)
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2021-10-13 19:17:58 -07:00
Thad House
689e9ccfb5 [hal, wpilib] Add brownout voltage configuration (#3632) 2021-10-13 19:14:27 -07:00
sciencewhiz
9cd4bc407a [docs] Add useLocal to avoid using installer artifacts (#3634) 2021-10-13 10:38:33 -07:00
Peter Johnson
61996c2bbf [cscore] Fix Java direct callback notifications (#3631)
These relied on the OnStart and OnExit callbacks which were not present
in the wpiutil common CallbackManager code.  Add support for these and
fix up other use cases.

Also fixes notifications to correctly filter on event kind.

This fixes a breakage caused by #3133.
2021-10-13 08:46:07 -07:00
Thad House
6d3dd99eb2 [build] Update to newest native-utils (#3633) 2021-10-13 07:47:10 -07:00
Tyler Veness
f0b484892c [wpiutil] Fix StringMap iterator equality check (#3629)
This fixes the following warning.
The member function operator== only works in C++17, and the friend operator== only works in C++20.

```
 /Users/runner/.gradle/caches/transforms-2/files-2.1/c671f5a5dff922b8870f4eb33f4c8e2a/wpiutil-cpp-2022.1.1-alpha-3-1-g4e3fd7d-headers/wpi/json.h:1847:46: warning: ISO C++20 considers use of overloaded operator '==' (with operand types 'const typename json::object_t::iterator' (aka 'const StringMapIterator<wpi::json>') and 'const typename json::object_t::iterator') to be ambiguous despite there being a unique best viable function [-Wambiguous-reversed-operator]
                return (m_it.object_iterator == other.m_it.object_iterator);
                        ~~~~~~~~~~~~~~~~~~~~ ^  ~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/runner/.gradle/caches/transforms-2/files-2.1/c671f5a5dff922b8870f4eb33f4c8e2a/wpiutil-cpp-2022.1.1-alpha-3-1-g4e3fd7d-headers/wpi/json.h:1863:20: note: in instantiation of member function 'wpi::detail::iter_impl<const wpi::json>::operator==' requested here
        return not operator==(other);
                   ^
/Users/runner/.gradle/caches/transforms-2/files-2.1/c671f5a5dff922b8870f4eb33f4c8e2a/wpiutil-cpp-2022.1.1-alpha-3-1-g4e3fd7d-headers/wpi/json.h:5008:20: note: in instantiation of member function 'wpi::detail::iter_impl<const wpi::json>::operator!=' requested here
            if (it != end())
                   ^
/Users/runner/.gradle/caches/transforms-2/files-2.1/c671f5a5dff922b8870f4eb33f4c8e2a/wpiutil-cpp-2022.1.1-alpha-3-1-g4e3fd7d-headers/wpi/json.h:5025:16: note: in instantiation of function template specialization 'wpi::json::value<std::basic_string<char>, 0>' requested here
        return value(key, std::string(default_value));
               ^
/Users/runner/.gradle/caches/transforms-2/files-2.1/c671f5a5dff922b8870f4eb33f4c8e2a/wpiutil-cpp-2022.1.1-alpha-3-1-g4e3fd7d-headers/wpi/StringMap.h:442:8: note: ambiguity is between a regular call to this operator and a call with the argument order reversed
  bool operator==(const DerivedTy &RHS) const { return Ptr == RHS.Ptr; }
       ^
```
2021-10-12 23:28:26 -07:00
Lucas
8352cbb7a3 Update development build instructions for 2022 (#3616)
Updates the instructions for development and local WPILib builds as per the GradleRIO 2022 updates.
2021-10-12 22:47:16 -07:00
sciencewhiz
6da08b71dc [examples] Fix Intermediate Vision Java Example description (#3628)
Copy from C++
2021-10-11 22:55:33 -07:00
Peter Johnson
5d99059bf9 [wpiutil] Remove optional.h (#3627)
This has been replaced fully by std::optional and deprecated for a year.
2021-10-11 22:54:33 -07:00
Tyler Veness
fa41b106ab [glass, wpiutil] Add missing format args (#3626)
These were caught by compile-time format string parsing in C++20.
2021-10-11 22:54:20 -07:00
Thad House
4e3fd7d420 [build] Enable Zc:__cplusplus for Windows (#3625)
This makes the version actually be correct.
2021-10-11 20:30:22 -07:00
Starlight220
791d8354da [build] Suppress deprecation/removal warnings for old commands (#3618) 2021-10-10 20:07:12 -07:00
Thad House
10f19e6fc3 [hal, wpilib] Add REV PneumaticsHub (#3600) 2021-10-10 20:04:50 -07:00
Peter Johnson
4c61a13057 [ntcore] Revert to per-element copy for toNative() (#3621)
arraycopy() does not unbox values, so throws an exception.

This was broken in #3419 due to a false positive in PMD
(see https://sourceforge.net/p/pmd/bugs/804/).
2021-10-10 15:53:35 -07:00
Peter Johnson
7b3f62244f [wpiutil] SendableRegistry: Print exception stacktrace (#3620) 2021-10-10 15:53:11 -07:00
Thad House
d347928e4d [hal] Use better error for when console out is enabled while attempting to use onboard serial port (#3622) 2021-10-10 15:52:50 -07:00
Tyler Veness
cc31079a11 [hal] Use setcap instead of setuid for setting thread priorities (#3613)
We originally moved to setuid admin so user programs could do other
things requiring admin if they wanted. However, these things, like
setting RT priorities of other processes, can usually be done instead as
admin during the GradleRIO 2022 deploy process, or adding commands to
the robotCommand script. By going back to setcap, we can simplify the
HAL code.
2021-10-04 09:49:34 -07:00
Tyler Veness
4676648b78 [wpimath] Upgrade to Drake v0.34.0 (#3607) 2021-09-29 15:39:47 -07:00
Thad House
c7594c9111 [build] Allow building wpilibc in cmake without cscore and opencv (#3605)
The hard dependency on cscore was removed a while ago in gradle, so make it not a hard requirement in cmake.
2021-09-27 21:37:04 -07:00
Tyler Veness
173cb7359d [wpilib] Add TimesliceRobot (#3502) 2021-09-26 13:56:33 -07:00
Tyler Veness
af295879fb [hal] Set error status for I2C port out of range (#3603)
Closes #1369.
2021-09-26 10:38:17 -07:00
Tyler Veness
95dd20a151 [build] Enable spotbugs (#3601)
Benign spotbugs warnings were suppressed, and all others were fixed. Bug
descriptions are documented here:
https://spotbugs.readthedocs.io/en/stable/bugDescriptions.html

Co-authored-by: Austin Shalit <austinshalit@gmail.com>
2021-09-24 16:04:02 -07:00
Tyler Veness
b65fce86bf [wpilib] Remove Timer lock in wpilibj and update docs (#3602)
Timer reports a negative duration if the sim timing is restarted. This
can be worked around by calling Reset(). Other options included:

1. Have RestartTiming() call Timer::Reset() on a list of instantiated
   Timers.
2. Have Timer::Get() reset the timer if it notices time went backwards.
   This requires dropping const qualification though, which is a
   breaking change that only fixes a minor edge case.

Closes #2732.
2021-09-24 16:01:13 -07:00
Tyler Veness
3b8d3bbcbf Remove unused and add missing deprecated.h includes (#3599)
I generated lists of includes and uses via
`rg -l deprecated.h | sort -u` and `rg -l WPI_DEPRECATED | sort -u`
respectively. If a file was in the first list but not the second, the
include was unused. If a file was in the second list but not the first,
the include needed to be added.
2021-09-22 18:29:57 -07:00
Tyler Veness
f9e976467f [examples] Rename DriveTrain classes to Drivetrain (#3594)
Drivetrain is one word, not two.
2021-09-22 13:27:26 -07:00
Tyler Veness
118a27be2f [wpilib] Add Timer tests (#3595) 2021-09-22 13:26:58 -07:00
Tyler Veness
59c89428e5 [wpilib] Deprecate Timer::HasPeriodPassed() (#3598)
AdvanceIfElapsed() is safer to use, as it has less surprising side effects.
2021-09-22 13:01:37 -07:00
Tyler Veness
202ca5e782 Force C++17 in .clang-format (#3597) 2021-09-22 10:04:03 -07:00
Tyler Veness
d6f185d8e5 Rename tests for consistency (#3592)
I started with the output of styleguide#217, then renamed a few classes
to fix compilation.

ntcore's StorageTest needed some manual renaming since it put the Test
word in the middle instead of at the end.

One limitation of wpiformat is test cases that were only named "Test"
were unmodified, and an error was generated. These test cases were
manually given more descriptive names:

* TimedRobotTest mode test cases had "Mode" appended to the name. Java
  tests were renamed to match.
* UvAsyncTest and UvAsyncFunctionTest cases were given alternate names
2021-09-21 06:12:50 -07:00
Tyler Veness
54ca474dba [ci] Enable asan and tsan in CI for tests that pass (#3591)
ctest's -E flag skips tests that match a regular expression.
2021-09-19 20:03:40 -07:00
Tyler Veness
1ca383b23b Add Debouncer (#3590)
Supersedes #2358 with updates and cleanups.

Closes #2482 and closes #2487 because we shouldn't support both
time-based and count-based debouncing approaches.

Co-authored-by: oblarg <emichaelbarnett@gmail.com>
2021-09-19 19:58:16 -07:00
Thad House
179fde3a7b [build] Update to 2022 native utils and gradle 7 (#3588) 2021-09-19 17:59:14 -07:00
sciencewhiz
50198ffcf1 [examples] Add Mechanism2d visualization to Elevator Sim (#3587) 2021-09-18 22:06:14 -07:00
sciencewhiz
a446c25598 [examples] Synchronize C++ and Java Mechanism2d examples (#3589)
- Synchronize dimensions
- Make both joints different colors for clarity
2021-09-18 22:05:35 -07:00
Tyler Veness
a7fb831035 [ci] clang-tidy: Generate compilation commands DB with Gradle (#3585) 2021-09-18 10:19:34 -07:00
sciencewhiz
4f5e0c9f85 [examples] Update ArmSimulation example to use Mechanism2d (#3572)
- Correct several comments that referenced elevator
- Changed noise to be 1 encoder tick instead of half a degree
- Changed gear ratio and PID value to be better tuned
- Updated bounds to be similar to a single jointed arm
2021-09-17 22:55:31 -07:00
Tyler Veness
8164b91dc4 [CI] Print CMake test output on failure (#3583) 2021-09-17 22:54:47 -07:00
sciencewhiz
4d5fca27ef [wpilib] Impove Mechanism2D documentation (NFC) (#3584) 2021-09-17 22:54:10 -07:00
Tyler Veness
fe59e4b9fe Make C++ test names more consistent (#3586)
Inconsistent names were found using the following regular expressions.

* `rg "TEST(_F|_P)?\(\w+,\s+\w+Test\)"`
* `rg "TEST(_F|_P)?\(\w+,\s+Test\w+\)"`
* `rg "TEST(_F|_P)?\(\w+Tests,\s+\w+\)"`

Fixes #3495.
2021-09-17 22:51:51 -07:00
sciencewhiz
5c88685495 [wpilibc] Fix C++ MechanisimRoot2D to use same NT entries as Java/Glass (#3582)
Fixes #3578
2021-09-17 12:13:36 -07:00
Tyler Veness
9359431bad [wpimath] Clean up Eigen usage
* Replace Matrix<> with Vector<> where vectors are explicitly intended.
  I found these via `rg "Eigen::Matrix<double, \w+, 1>"`.
* Pass all Eigen matrices by const reference. I found these via `rg
  "\(Eigen"` on main (the initializer list constructors make more false
  positives).
* Replace MakeMatrix() and operator<< usage with initializer list
  constructors. I found these via `rg MakeMatrix` and `rg "<<"`
  respectively.
* Deprecate MakeMatrix()
2021-09-17 12:12:19 -07:00
Tyler Veness
72716f51ce [wpimath] Upgrade to Eigen 3.4 2021-09-17 12:12:19 -07:00
Thad House
382deef750 [wpimath] Explicitly export wpimath symbols
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2021-09-17 12:12:19 -07:00
Peter Johnson
161e211734 [ntcore] Match standard handle layout, only allow 16 instances (#3577)
Now that there are only 16 instances, store them all statically.

Make tests more reliable by using different ports for each connection in listener tests.
2021-09-17 12:11:00 -07:00
Peter Johnson
263a248119 [wpimath] Use jinja for codegen (#3574)
While not really needed for wpimath, it will make more complex codegen
in the future significantly easier.
2021-09-17 00:10:29 -07:00
Tyler Veness
725251d294 [wpilib] Increase tolerances of DifferentialDriveSimTest (#3581) 2021-09-16 23:42:46 -07:00
Tyler Veness
4dff873013 [wpimath] Make LinearFilter::Factorial() constexpr (#3579)
Since BackwardFiniteDifference() gives it a compile-time constant, it
can be evaluated in a constexpr context.
2021-09-16 20:45:24 -07:00
Thad House
60ede67abd [hal, wpilib] Switch PCM to be a single object that is allowed to be duplicated (#3475)
Having PCM as a singleton is a problem, as multiple things need to use it, and that gets really ugly. This changes PCM's to be a reference counted object, that can be passed around and constructed from multiple places.

In Java, this is using a map to hold a data store with a ref count, and allocating new objects any time a duplicate is requested.

In C++, this uses a trick constructor to store a PCM instance in the data store itself. This instance can then be passed to base objects using std::shared_ptr's aliasing constructor, which means constructing a solenoid from a PCM is not allocating after the 1st one.

This did require removing sendable from PCM. A compressor class was added back in to act as sendable for the PCM.

After this change is finished, the only change RobotBuilder and Team Code would require is passing a module type to solenoid constructors.

Co-authored-by: sciencewhiz <sciencewhiz@users.noreply.github.com>
2021-09-16 18:50:27 -07:00
Tyler Veness
906bfc8464 [build] Add CMake build support for sanitizers (#3576)
* Address sanitizer uses -DCMAKE_BUILD_TYPE=Asan
* Thread sanitizer uses -DCMAKE_BUILD_TYPE=Tsan
* Undefined behavior sanitizer uses -DCMAKE_BUILD_TYPE=Ubsan

Only ubsan is enabled in CI for now because asan and tsan report
failures.
2021-09-16 18:48:41 -07:00
Ryan Hirasaki
0d4f08ad9c [hal] Simplify string copy of joystick name (#3575) 2021-09-16 09:32:57 -07:00
Peter Johnson
a52bf87b7d [wpiutil] Add Java function package (#3570)
The standard Java package is missing BooleanConsumer as well as Float classes.

Update SendableBuilder to use it instead of internal BooleanConsumer
interface.
2021-09-15 21:36:11 -07:00
Peter Johnson
40c7645d6e [wpiutil] UidVector: Return old object from erase() (#3571)
This makes it possible to erase and then do additional cleanup (e.g. on a unique_ptr).
2021-09-15 21:35:20 -07:00
Peter Johnson
5b886a23fd [wpiutil] jni_util: Add size, operator[] to JArrayRef (#3569)
These make it usable more like a standard container.
2021-09-15 21:34:16 -07:00
Tyler Veness
65797caa7b [sim] Fix halsim_ds_socket stringop overflow warning from GCC 10 (#3568)
Fixes #3567.
2021-09-14 20:49:02 -07:00
Thad House
66abb39880 [hal] Update runtime enum to allow selecting roborio 2 (#3565)
In some cases, knowing roborio 2 might be useful. This also creates a higher level enum that might be usable later for the discussion on more complex runtime types.
2021-09-13 22:05:38 -07:00
Thad House
95a12e0ee8 [hal] UidSetter: Don't revert euid if its already current value (#3566)
When running from admin account, this hangs for 5-10 seconds.

Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2021-09-13 21:08:39 -07:00
Tyler Veness
27951442b8 [wpimath] Use external Eigen headers only (#3564)
Internal headers are no longer allowed as of
https://gitlab.com/libeigen/eigen/-/merge_requests/631. Based on
benchmarking I conducted in that thread, there doesn't seem to be a
performance penalty for including the full headers anymore.
2021-09-13 14:31:01 -07:00
Austin Shalit
c42e053ae9 [docs] Update to doxygen 1.9.2 (#3562) 2021-09-12 15:19:04 -07:00
sciencewhiz
e7048c8c8b [docs] Disable doxygen linking for common words that are also classes (#3563)
Add % in front of name in order to suppress doxygen link creation. https://www.doxygen.nl/manual/autolink.html
2021-09-12 15:18:45 -07:00
Thad House
d8e0b6c977 [wpilibj] Fix java async interrupts (#3559) 2021-09-11 09:21:02 -07:00
Thad House
5e6c34c61c Update to 2022 roborio image (#3537) 2021-09-10 13:00:58 -07:00
Tyler Veness
828f073ebd [wpiutil] Fix uv::Buffer memory leaks caught by asan (#3555) 2021-09-09 23:14:10 -07:00
Tyler Veness
2dd5701ac0 [cscore] Fix mutex use-after-free in cscore test (#3557)
Fixes #3546.
2021-09-09 23:13:56 -07:00
Tyler Veness
531439198e [ntcore] Fix NetworkTables memory leaks caught by asan (#3556)
Closes #3543.
2021-09-09 23:13:36 -07:00
Tyler Veness
3d9a4d585e [wpilibc] Fix AnalogTriggerOutput memory leak reported by asan (#3554)
Fixes #3542.

Co-authored-by: Peter Johnson <johnson.peter@gmail.com>
2021-09-09 19:32:00 -07:00
Tyler Veness
54eda59286 [wpiutil] Ignore ubsan vptr upcast warning in SendableHelper moves (#3553)
The move ctor is trying to cast from e.g. SendableHelper to PIDController before PIDController has been constructed, which is potentially UB. We don't actually use anything in PIDController though, so it's OK in our case.
2021-09-09 12:33:50 -07:00
sciencewhiz
5a4f75c9f8 [wpilib] Replace Speed controller comments with motor controller (NFC) (#3551)
Makes comments consistent with #3302
2021-09-08 22:09:08 -07:00
Tyler Veness
7810f665f1 [wpiutil] Fix bug in uleb128 (#3540)
Caused by UB in left shift; identified by ubsan.
2021-09-08 16:24:28 -07:00
sciencewhiz
697e2dd330 [wpilib] Fix errant jaguar reference in comments (NFC) (#3550) 2021-09-08 14:18:37 -07:00
sciencewhiz
936c64ff51 [docs] Enable -linksource for javadocs (#3549)
Embeds source in javadocs.
Fixes #3547
2021-09-07 22:46:09 -07:00
Tyler Veness
1ea6549548 [build] Upgrade CMake build to googletest 1.11.0 (#3548)
This upgrade uncovered two issues:

ntcore wasn't forcing C++17, which caused a linker error with googletest
Matcher symbols:
```
undefined reference to `testing::Matcher<std::basic_string_view<char, std::char_traits<char> > >::Matcher(std::basic_string_view<char, std::char_traits<char> >)'
```

test_span.cpp wasn't including <algorithm> to use std::sort() and
std::is_sorted().
2021-09-07 13:29:31 -07:00
Tyler Veness
32d9949e4d [wpimath] Move controller tests to wpimath (#3541) 2021-09-06 17:00:13 -07:00
Ryan Hirasaki
01ba56a8a6 [hal] Replace strncpy with memcpy (#3539) 2021-09-05 20:47:40 -07:00
Tyler Veness
e109c42515 [build] Rename makeSim flag to forceGazebo to better describe what it does (#3535) 2021-09-05 17:40:54 -07:00
Noam Zaks
e4c7091647 [docs] Use a doxygen theme and add logo (#3533) 2021-09-02 21:59:16 -07:00
Tyler Veness
960b6e5897 [wpimath] Fix Javadoc warning (#3532) 2021-08-28 22:43:38 -07:00
Jan-Felix Abellera
82eef8d5ee [hal] Remove over current fault HAL functions from REV PDH (#3526) 2021-08-28 20:52:46 -07:00
Tyler Veness
aa3848b2c8 [wpimath] Move RobotDriveBase::ApplyDeadband() to MathUtil (#3529)
It's a useful function outside of the drive classes.

For backwards compatibility, deprecate (rather than remove) RobotDriveBase.applyDeadband()
2021-08-28 20:52:05 -07:00
Tyler Veness
3b5d0d141a [wpimath] Add LinearFilter::BackwardFiniteDifference() (#3528)
This is an alternative to #2344 that handles arbitrary order derivatives
of arbitrary precision. The downside is that since it's part of
LinearFilter, it can't utilize the units type system in the same way to
make Calculate()'s input type different from its output type.
2021-08-28 20:50:18 -07:00
Tyler Veness
c8fc715fe2 [wpimath] Upgrade drake files to v0.33.0 (#3531) 2021-08-28 20:49:19 -07:00
Tyler Veness
e5fe3a8e16 [build] Treat javadoc warnings as errors in CI and fix warnings (#3530) 2021-08-28 20:48:47 -07:00
Tyler Veness
e0c6cd3dcc [wpimath] Add an operator for composing two Transform2ds (#3527) 2021-08-23 20:22:48 -07:00
PJ Reiniger
2edd510ab7 [sim] Add sim wrappers for sensors that use SimDevice (#3517) 2021-08-20 23:19:59 -07:00
Tyler Veness
2b3e2ebc11 [hal] Fix HAL Notifier thread priority setting (#3522)
The HAL Notifier thread is started when the first Notifier is created
and stopped when the last Notifier is destroyed. Currently,
HAL_SetNotifierThreadPriority() will cause a segfault if the Notifier thread
hasn't been started yet (that is, if no Notifier have been created yet).

This change makes HAL_SetNotifierThreadPriority() store the RT and
priority setting. If the thread has already been started, it will set
the priority immediately. If it hasn't, HAL_InitializeNotifier() will
set the priority when it starts the thread.
2021-08-20 23:19:25 -07:00
PJ Reiniger
ab4cb59326 [gitignore] Update gitignore to ignore bazel / clion files (#3524) 2021-08-20 23:18:37 -07:00
PJ Reiniger
57c8615af3 [build] Generate spotless patch on failure (#3523) 2021-08-20 23:18:10 -07:00
Tyler Veness
b903173211 Replace std::cout and std::cerr with fmt::print() (#3519) 2021-08-19 20:31:14 -07:00
Thad House
10cc8b89c4 [hal] [wpilib] Add initial support for the REV PDH (#3503) 2021-08-14 11:44:56 -07:00
Tyler Veness
5d9ae3cdb4 [hal] Set HAL Notifier thread as RT by default (#3482)
This PR gives the Notifier HAL thread RT priority 40 in RobotBase after
HAL initialization and before the user code is run. This drastically
improves scheduling jitter for TimedRobot's AddPeriodic() functions (in
3512's experience).

It's too risky to set user code as RT because badly behaved code
will lock up the Rio (potentially requiring safe mode to recover).

This needs the user program to be setuid admin to succeed.
2021-08-14 11:42:35 -07:00
Tyler Veness
192d251ee8 [wpilibcIntegrationTests] Properly disable DMA integration tests (#3514)
"DISABLED_" must be a prefix, not a suffix.
2021-08-14 10:01:12 -07:00
Starlight220
031962608b [wpilib] Add PS4Controller, remove Hand from GenericHID/XboxController (#3345)
- GenericHID is now concrete, and has only getRawAxis/Button(int) functionality
- getXxx() has been moved into Joystick as that's the only place where it makes sense
- Hand (and therefore getXxx(Hand)) has been removed, replaced by specific getLeft/RightXxx() methods in XboxController and the new PS4Controller class
- C++ ::Button:: and ::Axis:: enums have been converted to identically-namespaced static constexpr ints
2021-08-14 10:00:46 -07:00
Tyler Veness
25f6f478a5 [wpilib] Rename DriverStation::IsOperatorControl() to IsTeleop() (#3505) 2021-08-11 23:04:43 -07:00
PJ Reiniger
e80f09f849 [wpilibj] Add unit tests (#3501) 2021-08-11 23:04:14 -07:00
Tyler Veness
c159f91f06 [wpilib] Only read DS control word once in IterativeRobotBase (#3504) 2021-08-11 18:05:07 -07:00
Thad House
eb790a74d2 Add rio development docs documenting myRobot deploy tasks (#3508)
Co-authored-by: sciencewhiz <sciencewhiz@users.noreply.github.com>
2021-08-11 18:04:20 -07:00
Matteo Kimura
e47451f5a0 [wpimath] Replace auto with Eigen types (#3511)
This fixes a bug regarding temporary Eigen values caused by the usage of auto.
2021-08-11 06:58:19 -07:00
Tyler Veness
252b8c83bf Remove Java formatting from build task in CI (#3507)
This saves time in CI spent performing the same source-level checks in
every build job. Checkstyle, PMD, and Spotless are now run once in the
"Lint and Format" job.

The -PskipPMD flag was replaced with a -PskipJavaFormat flag that
disables Checkstyle, PMD, and Spotless.
2021-08-07 20:39:14 -07:00
Tyler Veness
09666ff294 Shorten Gazebo CI build (#3506)
Only build the Gazebo simulation projects instead of all of WPILib.
2021-08-07 20:37:57 -07:00
sciencewhiz
baf2e501dc Update myRobot to use 2021 java (#3509) 2021-08-07 20:36:11 -07:00
Tyler Veness
5ac60f0a20 [wpilib] Remove IterativeRobotBase mode init prints (#3500)
They don't provide much utility for the end user. A print at the call to
HAL_ObserveUserProgramStarting() was added in their place so it's still
clear when constructors have finished running.
2021-08-05 23:54:50 -07:00
Tyler Veness
fb2ee8ec34 [wpilib] Add TimedRobot functions for running code on mode exit (#3499)
Currently, we have functions like TeleopInit() for running code on mode
entry, but no such functions for running code on mode exit, and it's
cumbersome to add those in user code without making a custom robot
class. This PR adds exit functions to TimedRobot.

Some example use cases include DisabledExit() for operations when the
robot enables (whether that be into teleop, autonomous, or test) and
AutonomousExit() for disabling feedback controllers.
2021-08-05 19:08:29 -07:00
PJ Reiniger
94e0db7963 [wpilibc] Add more unit tests (#3494) 2021-08-05 19:04:51 -07:00
sciencewhiz
b253246959 [wpilibj] Add units to parameter names (NFC) (#3497) 2021-08-05 18:04:20 -07:00
Thad House
1ac73a247e [hal] Rename PowerDistributionPanel to PowerDistribution (#3466)
Makes HAL more generic for the PDP, to enable the Rev PDH in the future.
2021-08-04 20:31:17 -07:00
sciencewhiz
2014115bca [examples] frisbeebot: Fix typo and reflow comments (NFC) (#3498) 2021-08-01 07:17:51 -07:00
liorsagy
4a944dc397 [examples] Consistently use 0 for controller port (#3496) 2021-07-31 20:39:50 -07:00
Tyler Veness
3838cc4ec4 Use unicode characters in docs equations (#3487)
javac and javadoc needed the encoding set to UTF-8.
2021-07-29 22:42:43 -07:00
Aditya Tomar
85748f2e6f [examples] Add C++ TankDrive example (#3493)
This is a basic C++ example that demonstrates a simple differential drive implementation using “tank”-style controls through the DifferentialDrive class and an ordinary joystick.
2021-07-28 21:52:14 -07:00
Tyler Veness
d7b8aa56dc [wpilibj] Rename DriverStation In[Mode] functions to follow style guide (#3488) 2021-07-26 07:29:54 -07:00
Tyler Veness
16e096cf86 [build] Fix CMake Windows CI (#3490) 2021-07-26 07:28:52 -07:00
Tyler Veness
50af74c38f [wpimath] Clean up NumericalIntegration and add Discretization tests (#3489)
* Rename Butcher tableau sections in NumericalIntegration such that
  top-left is c, top-right is A, and bottom-right is b
* Move edu.wpi.first.math.Discretization to
  edu.wpi.first.math.system.Discretization
* Sort Java Discretization to match C++ function order
* Add tests for Java Discretization
  * Required adding Runge-Kutta time-varying impl to tests
* Move C++ Runge-Kutta time-varying impl to tests only
  * Users don't need it
2021-07-25 07:42:59 -07:00
Tyler Veness
bfc209b120 Automate fmt update (#3486)
Also refactored upstream_utils to make writing and maintaining new
upstream repo extractions easier.
2021-07-23 09:01:44 -07:00
Austin Shalit
e7f9331e4b [build] Update to Doxygen 1.9.1 (#3008) 2021-07-22 18:33:15 -07:00
Tyler Veness
ab8e8aa2a1 [wpimath] Update drake with upstream (#3484)
Our patches for the DARE and [[noreturn]] attributes were merged
upstream. We missed their monthly release window by a day, so we'll use
a commit hash for now.
2021-07-22 17:48:48 -07:00
Lucas
1ef826d1da [wpimath] Fix IOException path in WPIMath JNI (#3485)
The current 2021.3.1 release refers to `java/lang/IOException` which causes the following exception when using `toPathweaverJson` or `fromPathweaverJson`:

```
java.lang.NoClassDefFoundError: java/lang/IOException
    at edu.wpi.first.math.WPIMathJNI.fromPathweaverJson(Native Method)
    at edu.wpi.first.wpilibj.trajectory.TrajectoryUtil.fromPathweaverJson(TrajectoryUtil.java:79)
```
2021-07-22 17:48:33 -07:00
Tyler Veness
52bddaa97b [wpimath] Disable iostream support for units and enable fmtlib (#3481)
Supersedes #2497.
2021-07-13 13:41:07 -05:00
Tyler Veness
e4dc3908bb [wpiutil] Upgrade to fmtlib 8.0.1 (#3483) 2021-07-13 13:39:14 -05:00
Tyler Veness
1daadb812f [wpimath] Implement Dormand-Prince integration method (#3476)
Also refactored RKF45 implementation to match the new style, which is
easier to read.

The tests were switched from RKF45 to RKDP since it's more accurate.
2021-07-11 09:42:33 -05:00
Tyler Veness
9c2723391b [cscore] Add [[nodiscard]] to GrabFrame functions (#3479)
Closes #3086.
2021-07-11 09:41:12 -05:00
Tyler Veness
7a8796414c [wpilib] Add Notifier integration tests (#3480)
Closes #2610.
2021-07-11 09:39:42 -05:00
Tyler Veness
f8f13c536f [wpilibcExamples] Prefix decimal numbers with 0 (#3478) 2021-07-11 09:38:13 -05:00
Tyler Veness
1adb69c0fd [ntcore] Use "NetworkTables" instead of "Network Tables" in NT specs (#3477)
Closes #3280.
2021-07-11 09:37:27 -05:00
Tyler Veness
5f5830b960 Upload wpiformat diff if one exists (#3474)
This means users will be able to apply it locally with "git apply".
2021-07-09 21:42:20 -05:00
Tyler Veness
9fb4f35bb6 [wpimath] Add tests for DARE overload with Q, R, and N matrices (#3472)
The autodiff headers weren't used by the tests, so they were removed.
2021-07-09 21:41:33 -05:00
Tyler Veness
c002e6f926 Run wpiformat (#3473)
A recent PR had an earlier version of wpiformat ran on it with more
lenient rules.
2021-07-09 20:49:13 -05:00
Thad House
c154e5262e [wpilib] Make solenoids exclusive use, PCM act like old sendable compressor (#3464) 2021-07-09 15:11:12 -07:00
Thad House
6ddef1cca6 [hal] JNI setDIO: use a boolean and not a short (#3469) 2021-07-08 23:42:31 -05:00
Tyler Veness
9d68d95825 Remove extra newlines after open curly braces (NFC) (#3471) 2021-07-08 23:41:30 -05:00
Tyler Veness
a4233e1a16 [wpimath] Add script for updating Drake (#3470)
Common functionality between the Drake and Eigen update scripts was
refactored into a library.
2021-07-08 22:36:01 -05:00
Prateek Machiraju
39373c6d2d Update README.md for new GCC version requirement (#3467) 2021-07-02 19:06:30 -07:00
Prateek Machiraju
d29acc90a2 [wpigui] Add option to reset UI on exit (#3463)
Also add wpiutil as a dependency for wpigui.
2021-06-26 22:48:54 -07:00
Peter Johnson
a371235b0d [ntcore] Fix dangling pointer in logger (#3465)
This is a breaking change (it changes LogMessage::filename from const
char* to std::string) but there should be few users of it.
2021-06-26 22:47:52 -07:00
Tyler Veness
53b4891a5e [wpilibcintegrationtests] Fix deprecated Preferences usage (#3461) 2021-06-23 21:58:27 -07:00
Prateek Machiraju
646ded9123 [wpimath] Remove incorrect discretization in pose estimators (#3460) 2021-06-23 21:57:52 -07:00
Peter Johnson
ea0b8f48e6 Fix some deprecation warnings due to fmtlib upgrade (#3459) 2021-06-23 21:57:32 -07:00
Prateek Machiraju
2067d7e300 [wpilibjexamples] Add wpimathjni, wpiutiljni to library path (#3455) 2021-06-22 06:33:24 -07:00
Tyler Veness
866571ab41 [wpiutil] Upgrade to fmtlib 8.0.0 (#3457) 2021-06-21 20:57:42 -07:00
Thad House
4e1fa03087 [build] Skip PDB copy on windows build servers (#3458) 2021-06-21 20:56:42 -07:00
Peter Johnson
b45572167d [build] Change CI back to 18.04 docker images (#3456)
This reverts commit d068fb321f (#3420).

The 18.04 docker images now use GCC 8, which was the original reason for
updating.  20.04 uses a much more recent libc, so staying with 18.04
enables more Linux platforms to use the binaries.
2021-06-20 23:03:29 -07:00
Tyler Veness
57a160f1b3 [wpilibc] Fix LiveWindow deprecation warning in RobotBase skeleton template (#3454) 2021-06-19 20:45:56 -07:00
Thad House
29ae8640d9 [HLT] Implement duty cycle cross connect tests (#3453) 2021-06-19 20:11:52 -07:00
Thad House
ee6377e54b [HLT] Add relay and analog cross connects (#3452) 2021-06-19 13:03:58 -07:00
Peter Johnson
b0f1ae7ea3 [build] CMake: Build the HAL even if WITH_CSCORE=OFF (#3449)
Also handle the case of WITH_WPILIB=OFF WITH_SIMULATION_MODULES=ON.
2021-06-19 09:30:49 -07:00
Tyler Veness
7aae2b72dc Replace std::to_string() with fmt::format() (#3451) 2021-06-19 09:30:01 -07:00
Thad House
73fcbbd748 [HLT] Add relay digital cross connect tests (#3450) 2021-06-19 01:21:56 -07:00
Thad House
e7bedde835 [HLT] Add PWM tests that use DMA as the back end (#3447)
Both a decent DMA test, and slightly more reliable PWM test.
2021-06-19 01:21:07 -07:00
Peter Johnson
7253edb1e1 [wpilibc] Timer: Fix deprecated warning (#3446) 2021-06-18 21:00:26 -07:00
Tyler Veness
efa28125c6 [wpilibc] Add message to RobotBase on how to read stacktrace (#3444)
Also make stacktrace info an error instead of a warning in both C++ and Java.
2021-06-17 23:52:48 -07:00
Thad House
9832fcfe14 [hal] Fix DIO direction getter (#3445)
Unset means input, where the code was assuming set means input.
2021-06-17 23:03:00 -07:00
Ryan Hirasaki
49c71f9f2d [wpilibj] Clarify robot quit message (#3364)
Co-authored-by: David Vo <auscompgeek@users.noreply.github.com>
2021-06-16 13:24:06 -07:00
Noam Zaks
791770cf6e [wpimath] Move controller from wpilibj to wpimath (#3439) 2021-06-16 07:45:51 -07:00
Noam Zaks
9ce9188ff6 [wpimath] Add ReportWarning to MathShared (#3441) 2021-06-16 00:52:24 -07:00
Peter Johnson
362066a9b7 [wpilib] Deprecate getInstance() in favor of static functions (#3440)
Co-authored-by: Noam Zaks <imnoamzaks@gmail.com>
2021-06-15 23:06:03 -07:00
Thad House
26ff9371d9 Initial commit of cross connect integration test project (#3434)
Adding as a separate project so current integration tests stay working.
2021-06-14 20:08:11 -07:00
Thad House
4a36f86c81 [hal] Add support for DMA to Java (#3158) 2021-06-14 19:56:42 -07:00
Peter Johnson
85144e47ff [commands] Unbreak build (#3438) 2021-06-14 07:35:21 -07:00
Peter Johnson
b417d961ec Split Sendable into NT and non-NT portions (#3432)
The non-NT portion has been moved to wpiutil.
The NT portion has been moved to ntcore (as NTSendable).

SendableBuilder similarly split and moved.

SendableRegistry moved to wpiutil.

In C++, SendableHelper also moved to wpiutil.

This enables use of Sendable from wpimath and also enables
moving several classes from wpilib to wpimath.
2021-06-13 16:38:05 -07:00
Starlight220
ef4ea84cb5 [commands] Change grouping decorator impl to flatten nested group structures (#3335) 2021-06-13 16:05:14 -07:00
Prateek Machiraju
b422665a3c [examples] Invert right side of drive subsystems (#3437)
The right motors of a DifferentialDrive are no longer automatically
inverted (#3340) so it needs to be done explicitly.
2021-06-13 15:43:16 -07:00
Thad House
186dadf14d [hal] Error if attempting to set DIO output on an input port (#3436) 2021-06-13 15:00:43 -07:00
Tyler Veness
04e64db945 Remove redundant C++ lambda parentheses (NFC) (#3433) 2021-06-12 08:06:45 -07:00
Peter Johnson
f60994ad24 [wpiutil] Rename Java package to edu.wpi.first.util (#3431)
This is more consistent with wpimath being edu.wpi.first.math.
2021-06-12 01:17:09 -07:00
Peter Johnson
cfa1ca96f2 [wpilibc] Make ShuffleboardValue non-copyable (#3430)
This avoids the possibility of it being accidentally sliced by users.
2021-06-11 20:16:35 -07:00
Tyler Veness
4d9ff76433 Fix documentation warnings generated by JavaDoc (NFC) (#3428)
Some C++ Doxygen comments were updated to reflect any wording changes.

See `rg "(@return|@param \w+) TODO" | less` for list of incomplete docs.
2021-06-10 20:46:47 -07:00
Peter Johnson
9e1b7e0464 [build] Fix clang-tidy and clang-format (#3429)
Use the official ubuntu packages on 20.04; don't use ubuntu-latest.
2021-06-10 20:46:21 -07:00
Tyler Veness
a77c6ff3a2 [build] Upgrade clang-format and clang-tidy (NFC) (#3422) 2021-06-10 11:13:09 -07:00
Tyler Veness
099fde97d5 [wpilib] Improve PDP comments (NFC) (#3427)
Also remove HAL doxygen comments from sources;
these functions already had more descriptive comments in their
corresponding headers.
2021-06-10 00:02:51 -07:00
Tyler Veness
f8fc2463ee [wpilibc, wpiutil] Clean up includes (NFC) (#3426) 2021-06-10 00:00:06 -07:00
Tyler Veness
e246b78846 [wpimath] Clean up member initialization in feedforward classes (#3425) 2021-06-09 23:59:31 -07:00
Tyler Veness
c1e128bd5a Disable frivolous PMD warnings and enable PMD in ntcore (#3419)
Some valid warnings like throwing NullPointerException or using a for
loop instead of System.arraycopy() were fixed.

Abstract classes marked with PMD.AbstractClassWithoutAbstractMethod were
made concrete because they already had protected constructors.

Fixes #1697.
2021-06-09 07:01:00 -07:00
Tyler Veness
8284075ee4 Run "Lint and Format" CI job on push as well as pull request (#3412)
This makes the formatter run when pushing to local forks before a pull
request is made.

This is not run on the main branch.
2021-06-08 23:22:40 -07:00
Tyler Veness
f7db09a128 [wpimath] Move C++ filters into filter folder to match Java (#3417) 2021-06-08 21:21:01 -07:00
Tyler Veness
f9c3d54bd1 [wpimath] Reset error covariance in pose estimator ResetPosition() (#3418)
This also fixes a member function name inconsistency between languages
and adds missing documentation to C++'s KalmanFilterLatencyCompensator.

Fixes #3229.
2021-06-08 21:20:43 -07:00
Tyler Veness
0773f4033e [hal] Ensure HAL status variables are initialized to zero (#3421)
HAL functions don't set the status variable on success, so it's possible
to use the status variable in an uninitialized state.
2021-06-08 21:18:59 -07:00
Peter Johnson
d068fb321f [build] Upgrade CI to use 20.04 docker images (#3420) 2021-06-08 12:27:22 -07:00
Peter Johnson
8d054c940c [wpiutil] Remove STLExtras.h
This is a very inefficient header, and it's good to remove to discourage
its use.  Only a handful of use cases remained, and of only array_lengthof.
2021-06-06 21:35:50 -07:00
Peter Johnson
80f1d79218 [wpiutil] Split function_ref to a separate header 2021-06-06 21:35:50 -07:00
Peter Johnson
64f5413253 Use wpi::span instead of wpi::ArrayRef across all libraries (#3414)
- Remove ArrayRef.h
- Add SpanExtras.h for a couple of convenience functions
2021-06-06 19:51:14 -07:00
Peter Johnson
2abbbd9e70 [build] clang-tidy: Remove bugprone-exception-escape (#3415)
This generates warnings for using fmt::print() in main(), which is a
case we're okay with.
2021-06-06 17:47:14 -07:00
Tyler Veness
a5c471af7e [wpimath] Add LQR template specialization for 2x2 system
A differential drive has this dimensionality (2 velocity states and 2
voltage inputs).
2021-06-06 16:45:12 -07:00
Tyler Veness
edd2f0232c [wpimath] Add DARE solver for Q, R, and N with LQR ctor overloads
This is useful for implementing implicit model following.
2021-06-06 16:45:12 -07:00
Peter Johnson
b2c3b2dd8e Use std::string_view and fmtlib across all libraries (#3402)
- Twine, StringRef, Format, and NativeFormatting have been removed
- Logging now uses fmtlib style formatting
- Nearly all uses of wpi::outs/errs have been replaced with fmt::print() or
std::puts()/std::fputs() (for unformatted strings).
- A wpi/fmt/raw_ostream.h header has been added to enable
fmt::print() with wpi::raw_ostream
2021-06-06 16:13:58 -07:00
Peter Johnson
4f1cecb8e7 [wpiutil] Remove Path.h (#3413)
This was missed in the std::filesystem change.
2021-06-06 15:50:28 -07:00
Prateek Machiraju
b336eac343 [build] Publish halsim_ws_core to Maven 2021-06-06 15:04:25 -07:00
Prateek Machiraju
2a09f6fa45 [build] Also build sim modules as static libraries
This allows sim modules to be statically linked into an executable to
create a "perfectly static" simulated desktop program. The entry point
was changed to be unique when building static libraries to avoid symbol
collisions.
2021-06-06 15:04:25 -07:00
Thad House
0e702eb799 [hal] Add a unified PCM object (#3331) 2021-06-05 22:36:39 -07:00
Tyler Veness
dea841103d [wpimath] Add fmtlib formatter overloads for Eigen::Matrix and units (#3409)
This allows using Eigen matrices or units natively with fmt::format() or
fmt::print().
2021-06-05 21:10:41 -07:00
Tyler Veness
82856cf816 [wpiutil] Improve wpi::circular_buffer iterators (#3410)
The implementation of wpi::circular_buffer has been effectively replaced
with a dynamically sized copy of wpi::static_circular_buffer with a
resize() member function.
2021-06-05 21:08:12 -07:00
Tyler Veness
8aecda03ed [wpilib] Fix a documentation typo (#3408)
"indicated" was misspelled.
2021-06-05 13:35:03 -07:00
Thad House
5c817082a0 [wpilib] Remove InterruptableSensorBase and replace with interrupt classes (#2410) 2021-06-05 11:25:21 -07:00
Tyler Veness
15c521a7fe [wpimath] Fix drivetrain system identification (#3406)
The units for angular Kv and Ka were inconsistent with the derivation. A
second factory function overload was added for angular units that uses a
trackwidth to convert to the other form.

Notice how section 15.2 of https://file.tavsys.net/control/controls-engineering-in-frc.pdf
defines the angular feedforward as u = Kv,angular v instead of u = Kv,angular + omega.
The units cancel for elements of A but not B, so just the B matrix was incorrect in our code.

This breaks existing C++ code since the units are part of the function
signature.
2021-06-05 11:22:05 -07:00
Thad House
989de4a1bf [build] Force all linker warnings to be fatal for rio builds (#3407)
This will make sure we catch any bugs for missing runtime dependencies before they become bigger problems.
2021-06-05 11:20:09 -07:00
Tyler Veness
d9eeb45b03 [wpilibc] Add units to Ultrasonic class API (#3403) 2021-06-01 21:54:56 -07:00
Peter Johnson
fe570e000c [wpiutil] Replace llvm filesystem with C++17 filesystem (#3401)
Use ghc::filesystem as fill on older GCC (e.g. RoboRIO).
This can be removed once all GCC platforms have upgraded to 8.1 or later.

File open functionality has been retained from LLVM but moved to "fs" namespace
and tweaked for improved consistency with std::filesystem (e.g. error_code is
passed by reference instead of returned).

Also update WPILibC's Filesystem functions to return std::string.
2021-06-01 21:50:35 -07:00
Tyler Veness
01dc0249de [wpimath] Move SlewRateLimiter from wpilib to wpimath (#3399)
Timer was replaced with wpi::Now() to avoid a dependency on other wpilib
classes.
2021-05-31 10:35:54 -07:00
Tyler Veness
93523d572e [wpilibc] Clean up integration tests (#3400)
The command and shuffleboard integration tests were removed because
their unit tests counterparts already provide adequate coverage. Java
already removed these.
2021-05-31 10:21:34 -07:00
Peter Johnson
4f7a4464df [wpiutil] Rewrite StringExtras for std::string_view (#3394)
Remove unused functions and add StringRef-like convenience functions.
Minimize header dependencies.
2021-05-28 23:42:58 -07:00
Tyler Veness
e09293a15e [wpilibc] Transition C++ classes to units::second_t (#3396)
A lot of these are breaking changes. frc::Timer was replaced with the
contents of frc2::Timer. The others were in-place argument changes or
removing deprecated non-unit overloads.
2021-05-28 22:06:59 -07:00
Prateek Machiraju
827b17a52b [build] Create run tasks for Glass and OutlineViewer (#3397) 2021-05-28 22:04:58 -07:00
Peter Johnson
a610379965 [wpiutil] Avoid MSVC warning on span include (#3393) 2021-05-26 23:14:04 -07:00
Peter Johnson
4e2c3051be [wpilibc] Use std::string_view instead of Twine (#3380)
Use fmtlib where needed for string formatting into std::string_view.
2021-05-26 17:44:18 -07:00
Peter Johnson
50915cb7ed [wpilibc] MotorSafety::GetDescription(): Return std::string (#3390)
This is only called in an error condition, so it's not necessary to over
optimize it.
2021-05-26 07:25:32 -07:00
Tyler Veness
f4e2d26d58 [wpilibc] Move NullDeleter from frc/Base.h to wpi/NullDeleter.h (#3387)
frc/Base.h was also deleted because it's now empty.
2021-05-26 07:24:53 -07:00
Peter Johnson
cb0051ae60 [wpilibc] SimDeviceSim: use fmtlib (#3389)
Also clean up several sim classes to use the channel constructor.
2021-05-26 07:23:13 -07:00
Tyler Veness
a238cec12b [wpiutil] Deprecate wpi::math constants in favor of wpi::numbers (#3383)
The constants were moved from std::math to std::numbers before
ratification in C++20.
2021-05-26 00:09:36 -07:00
Tyler Veness
393bf23c0c [ntcore, cscore, wpiutil] Standardize template impl files on .inc extension (NFC) (#3124) 2021-05-25 22:19:30 -07:00
Tyler Veness
e7d9ba135c [sim] Disable flaky web server integration tests (#3388)
The digital output test sometimes fails on Linux and the digital input
test sometimes fails on macOS.
2021-05-25 20:56:35 -07:00
Tyler Veness
0a0003c110 [wpilibjExamples] Fix name of Java swerve drive pose estimator example (#3382) 2021-05-25 20:55:24 -07:00
Tyler Veness
7e1b27554c [wpilibc] Use default copies and moves when possible (#3381)
The removal of ErrorBase allowed the defaults to be used in more places.
2021-05-25 20:54:39 -07:00
Tyler Veness
fb2a56e2d6 [wpilibc] Remove START_ROBOT_CLASS macro (#3384) 2021-05-25 20:53:26 -07:00
Tyler Veness
84218bfb45 [wpilibc] Remove frc namespace shim (#3385) 2021-05-25 20:52:50 -07:00
Tyler Veness
dd78243406 [wpilibc] Remove C++ compiler version static asserts (#3386)
frc/Base.h isn't the first header included basically anywhere, so the
compiler will fail on C++17 things before the asserts in this header are
processed.
2021-05-25 20:52:23 -07:00
Tyler Veness
484cf9c0e8 [wpimath] Suppress the -Wmaybe-uninitialized warning in Eigen (#3378)
GCC 11 emits a false positive when compiling Eigen and breaks the
build.

Fixes #3363.
2021-05-25 10:05:41 -07:00
Peter Johnson
a04d1b4f97 [wpilibc] DriverStation: Remove ReportError and ReportWarning
Change use cases to directly call FRC_ReportError.
2021-05-25 10:04:32 -07:00
Peter Johnson
831c10bdfc [wpilibc] Errors: Use fmtlib 2021-05-25 10:04:32 -07:00
Peter Johnson
87603e400d [wpiutil] Import fmtlib (#3375)
HEAD as of 5/23/2021 (dd8f38fcbbb6eedecd4d451b03ca7d817e8ae67d).
2021-05-24 23:59:35 -07:00
Peter Johnson
4426216725 [wpiutil] Add ArrayRef/std::span/wpi::span implicit conversions 2021-05-23 15:27:40 -07:00
Peter Johnson
bc15b953b4 [wpiutil] Add std::span implementation
Imported from https://github.com/tcbrindle/span with ifdef's removed
(as we require C++17).
2021-05-23 15:27:40 -07:00
Peter Johnson
6d20b12043 [wpiutil] StringRef, Twine, raw_ostream: Add std::string_view support (#3373) 2021-05-23 15:26:28 -07:00
Peter Johnson
2385c2a430 [wpilibc] Remove Utility.h (#3376)
Change last 2 uses of wpi_assert to throw error instead.
2021-05-23 15:25:08 -07:00
Tyler Veness
87384ea684 [wpilib] Fix PIDController continuous range error calculations (#3170)
The inputs should all be errors, so the range should be symmetric.

Fixes #3168.
Fixes #3304.
2021-05-21 23:52:30 -07:00
Tyler Veness
04dae799a2 [wpimath] Add SimpleMotorFeedforward::Calculate(velocity, nextVelocity) overload (#3183)
This is often more convenient than using the overload with velocity and
acceleration.

Fixes #3160.
2021-05-21 23:44:10 -07:00
Tyler Veness
0768c39036 [wpilib] DifferentialDrive: Remove right side inversion (#3340)
Also refactor drive inverse kinematics into separate functions.
This allows composing them with operations separate from the drive
class.
2021-05-21 22:34:16 -07:00
Tyler Veness
8dd8d4d2d4 [wpimath] Fix redundant nested math package introduced by #3316 (#3368) 2021-05-21 22:29:52 -07:00
Dalton Smith
49b06beedf [examples] Add Field2d to RamseteController example (#3371) 2021-05-21 22:28:29 -07:00
Tyler Veness
4c562a4457 [wpimath] Fix typo in comment of update_eigen.py (#3369)
NonMPL2.h clearly doesn't contain MPL2 code.
2021-05-21 21:39:33 -07:00
Tyler Veness
fdbbf11887 [wpimath] Add script for updating Eigen 2021-05-20 18:52:11 -07:00
Tyler Veness
f1e64b349a [wpimath] Move Eigen unsupported folder into eigeninclude
This fixes relative includes in development versions of Eigen.
2021-05-20 18:52:11 -07:00
Ryan Hirasaki
224f3a05cf [sim] Fix build error when building with GCC 11.1 (#3361) 2021-05-19 14:39:18 -07:00
Peter Johnson
ff56d6861d [wpilibj] Fix SpeedController deprecated warnings (#3360)
set() and other functions also need to be repeated on the MotorController
interface to avoid deprecation warnings from vscode.
2021-05-16 19:13:54 -07:00
sciencewhiz
1873fbefba [examples] Fix Swerve and Mecanum examples (#3359)
Fix encoder allocation and default command.
Fixes #3349
2021-05-15 21:39:00 -07:00
sciencewhiz
80b479e502 [examples] Fix SwerveBot example to use unique encoder ports (#3358)
Fixes #3089
2021-05-15 14:15:18 -07:00
PJ Reiniger
1f7c9adeeb [wpilibjExamples] Fix pose estimator examples (#3356) 2021-05-14 11:10:47 -07:00
Peter Johnson
9ebc3b058d [outlineviewer] Change default size to 600x400 (#3353) 2021-05-11 23:34:16 -07:00
Prateek Machiraju
e21b443a45 [build] Gradle: Make C++ examples runnable (#3348) 2021-05-11 19:54:53 -07:00
Peter Johnson
da590120c4 [wpilibj] Add MotorController.setVoltage default (#3347)
This avoids a vscode deprecation warning.
2021-05-11 19:53:55 -07:00
Peter Johnson
561d53885e [build] Update opencv to 4.5.2, imgui/implot to latest (#3344)
Also update native-utils to 2022.0.0 to start pulling 2022 artifacts.
2021-05-10 18:59:14 -07:00
Peter Johnson
44ad67ca8c [wpilibj] Preferences: Add missing Deprecated annotation (#3343) 2021-05-09 18:20:42 -07:00
Peter Johnson
3fe8fc75aa [wpilibc] Revert "Return reference from GetInstance" (#3342)
This reverts commit a79faace1b.

This change will be superseded in a non-breaking way by changing to static functions and deprecating GetInstance() entirely.
2021-05-09 18:16:07 -07:00
Peter Johnson
3cc2da3328 Merge branch '2022' 2021-05-09 14:15:40 -07:00
Tyler Veness
a3cd90dd71 [wpimath] Fix classpath used by generate_numbers.py (#3339) 2021-05-09 00:01:03 -07:00
Noam Zaks
d6cfdd3bae [wpilib] Preferences: Deprecate Put* in favor of Set* (#3337)
This naming is more consistent with other APIs.

Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2021-05-06 08:25:37 -07:00
Tyler Veness
ba08baabb9 [wpimath] Update Drake DARE solver to v0.29.0 (#3336)
This version incorporated the patch we were manually applying, so we're
synced back up with upstream now except for some minor #include changes
to reduce header bloat.
2021-05-05 09:16:55 -07:00
Tyler Veness
497b712f67 [wpilib] Make IterativeRobotBase::m_period private with getter 2021-05-04 13:41:36 -07:00
Tyler Veness
f00dfed7ac [wpilib] Remove IterativeRobot base class
TimedRobot supersedes it (see commit 81498e6 for reasoning).
2021-05-04 13:41:36 -07:00
Thad House
3c08461685 [hal] Use last error reporting instead of PARAMETER_OUT_OF_RANGE (#3328)
Makes the error messages much more specific to each error.
2021-05-01 13:22:08 -07:00
Tyler Veness
5ef2b4fdc0 [wpilibj] Fix @deprecated warning for SerialPort constructor (#3329)
The javadoc @deprecated tag didn't have corresponding @Deprecated
attribute.
2021-05-01 13:20:53 -07:00
Thad House
23d2326d1d [hal] Report previous allocation location for indexed resource duplicates (#3322) 2021-05-01 10:28:30 -07:00
Thad House
e338f9f190 [build] Fix wpilibc runCpp task (#3327) 2021-05-01 10:26:33 -07:00
Noam Zaks
c8ff626fe2 [wpimath] Move Java classes to edu.wpi.first.math (#3316) 2021-05-01 08:53:30 -07:00
Noam Zaks
4e424d51f4 [wpilibj] DifferentialDrivetrainSim: Rename constants to match the style guide (#3312) 2021-05-01 07:09:23 -07:00
Thad House
6b50323b07 [cscore] Use Lock2DSize if possible for Windows USB cameras (#3326)
Can remove a memory copy in many cases. This also fixes a bug where any mjpeg cameras on windows wouldn't work if the fast path was taken.
2021-05-01 07:07:37 -07:00
Tyler Veness
65c148536d [wpilibc] Fix "control reaches end of non-void function" warning (#3324) 2021-05-01 07:05:21 -07:00
Peter Johnson
f99f62bee4 [wpiutil] uv Handle: Use malloc/free instead of new/delete (#3325)
This avoids asan warnings for deleting a different pointer type.
2021-05-01 07:04:14 -07:00
Tyler Veness
365f5449ca [wpimath] Fix MecanumDriveKinematics (#3266) 2021-04-30 15:50:16 -07:00
Starlight220
ff52f207cc [glass, wpilib] Rewrite Mechanism2d (#3281)
Substantially improves Mechanism2d by moving it to NetworkTables and adding
a robot API to create the mechanism elements, instead of requiring a JSON file.

Co-authored-by: Peter Johnson <johnson.peter@gmail.com>
2021-04-30 13:43:59 -07:00
Tyler Veness
ee0eed143a [wpimath] Add DCMotor factory function for Romi motors (#3319) 2021-04-29 09:59:35 -07:00
Thad House
5127380727 [hal] Add HAL_GetLastError to enable better error messages from HAL calls (#3320)
This uses thread local storage so a full error string can be provided, not just an error code.
2021-04-29 09:56:54 -07:00
Noam Zaks
ced654880c [glass, outlineviewer] Update Mac icons to macOS 11 style (#3313) 2021-04-25 17:30:45 -07:00
Peter Johnson
936d3b9f83 [templates] Add Java template for educational robot (#3309)
Educational robot is a very minimal template designed for educational use
(rather than competition).
2021-04-24 20:22:39 -07:00
Jeff Hutchison
6e31230adc [examples] Fix odometry update in SwerveControllerCommand example (#3310)
The Drive Subsystem was supplying an incorrectly constructed
Rotation2d to the odometry update method. Rotation2d constructor
was being called with heading in degrees, not radians as required.
2021-04-24 20:07:04 -07:00
Peter Johnson
05ebe93180 Merge branch 'main' into 2022 2021-04-19 18:45:31 -07:00
Prateek Machiraju
aaf24e2552 [wpilib] Fix initial heading behavior in HolonomicDriveController (#3290) 2021-04-18 21:00:11 -07:00
Peter Johnson
8d961dfd25 [wpilibc] Remove ErrorBase (#3306)
Replace with new exception-based error reporting, consistent with Java.
This also builds stacktraces into the reporting/exceptions.
2021-04-18 20:35:29 -07:00
Peter Johnson
659b37ef9d [wpiutil] StackTrace: Include offset on Linux (#3305) 2021-04-18 20:34:39 -07:00
Peter Johnson
0abf6c9045 [wpilib] Move motor controllers to motorcontrol package (#3302)
Also deprecate SpeedController in favor of motorcontrol.MotorController and
SpeedControllerGroup in favor of motorcontrol.MotorControllerGroup.

The MotorController interface is derived from the SpeedController interface
so that code such as SpeedController x = new VictorSP(1) continues to
compile (just with a warning).

SpeedControllerGroup and MotorControllerGroup are independent classes;
both implement the MotorController interface.
2021-04-17 11:27:16 -07:00
Tyler Veness
4630191fa4 [wpiutil] circular_buffer: Use value initialization instead of passing zero (#3303)
This enables use of types that have a no-args constructor rather than one that takes an explicit zero value.
For numeric types, value initialization will result in a zero value, so this is not a functional change.
2021-04-15 11:50:07 -07:00
Peter Johnson
b7b178f49c [wpilib] Remove Potentiometer interface 2021-04-13 22:40:55 -07:00
Peter Johnson
687066af3d [wpilib] Remove GyroBase 2021-04-13 22:40:55 -07:00
Peter Johnson
6b168ab0c8 [wpilib] Remove PIDController, PIDOutput, PIDSource
Move them to the old commands vendordep so that PIDCommand and PIDSubsystem
continue to work.

This also removes Filter and LinearDigitalFilter.
2021-04-13 22:40:55 -07:00
Tyler Veness
948625de9d [wpimath] Document conversion from filter cutoff frequency to time constant (#3299) 2021-04-12 11:12:52 -07:00
Modelmat
3848eb8b16 [wpilibc] Fix flywhel -> flywheel typo in FlywheelSim (#3298) 2021-04-12 11:12:04 -07:00
Peter Johnson
3abe0b9d49 [cscore] Move java package to edu.wpi.first.cscore (#3294)
This is more consistent with the other Java packages, and also is more
correct, as we own the first.wpi.edu domain but not the full wpi.edu domain.
2021-04-10 11:42:41 -07:00
Peter Johnson
d7fabe81fe [wpilib] Remove RobotDrive (#3295)
This has been deprecated for several years, and its functionality has been
completely superseded by other drive classes (DifferentialDrive et al).
2021-04-10 10:28:32 -07:00
Peter Johnson
1dc81669c2 [wpilib] Remove GearTooth (#3293)
This sensor has had zero usage for many years and was last in the KOP
over a decade ago.  There are much better rotation sensors available,
and it's no longer worth maintaining this class.
2021-04-10 10:28:05 -07:00
Peter Johnson
01d0e12603 [wpilib] Revert move of RomiGyro into main wpilibc/j (#3296)
This reverts commit 69e8d0b65d (#3143).

We haven't released a version with this yet, and plan to make a vendor
library instead.
2021-04-10 10:27:44 -07:00
Peter Johnson
397e569aaf [ntcore] Remove "using wpi" from nt namespace
This removes the nt::ArrayRef, nt::StringRef, and nt::Twine aliases.
2021-04-08 22:35:28 -07:00
Peter Johnson
79267f9e60 [ntcore] Remove NetworkTable -> nt::NetworkTable shim 2021-04-08 22:35:28 -07:00
Peter Johnson
48ebe5736a [ntcore] Remove deprecated Java interfaces and classes 2021-04-08 22:35:28 -07:00
Peter Johnson
c2064c78b2 [ntcore] Remove deprecated ITable interfaces 2021-04-08 22:35:28 -07:00
Peter Johnson
36608a283b [ntcore] Remove deprecated C++ APIs 2021-04-08 22:35:28 -07:00
Starlight220
a1c87e1e15 [glass] LogView: Add "copy to clipboard" button (#3274) 2021-04-06 13:19:49 -07:00
Prateek Machiraju
fa7240a501 [wpimath] Fix typo in quintic spline basis matrix 2021-04-03 16:03:38 -07:00
Prateek Machiraju
ffb4d38e24 [wpimath] Add derivation for spline basis matrices 2021-04-03 16:03:38 -07:00
Starlight220
f57c188f2e [wpilib] Add AnalogEncoder(int) ctor (#3273) 2021-04-02 08:26:41 -07:00
Prateek Machiraju
8471c4fb26 [wpilib] FieldObject2d: Add setTrajectory() method (#3277) 2021-04-01 22:08:07 -07:00
Peter Johnson
c97acd18e7 [glass] Field2d enhancements (#3234)
- Add raw support for pose lists > 255/3 in length
- Improve drag selection, especially with closely overlapping objects
- Drag selection of corner also highlights center of object with smaller circle
- Multiple styles (box, line, closed line, track)
- Configurable line and arrow settings (color, weight)
- Add tooltip for object name, index, x, y, rotation
- Context menu for pose edit/add/remove
- View/edit in feet or inches as well as meters
- Configurable object selectability

Implementation: use vector of Pose2d internally, use units
2021-03-27 13:34:44 -07:00
Prateek Machiraju
ffb590bfcc [wpilib] Fix Compressor sendable properties (#3269) 2021-03-26 21:20:54 -07:00
Peter Johnson
6137f98eb5 [hal] Rename SimValueCallback2 to SimValueCallback (#3212) 2021-03-21 23:22:04 -07:00
Peter Johnson
a6f6539691 [hal] Move registerSimPeriodic functions to HAL package (#3211)
This enables the static lists to be private.
2021-03-21 23:21:47 -07:00
Peter Johnson
10c038d9bf [glass] Plot: Fix window creation after removal (#3264)
Previously the following sequence was broken:
- Add two plot windows (creates Plot<0> and Plot<1>)
- Delete Plot<0>
- Try to create a plot window

This failed because it would try to create Plot<1>, which already existed.
It was necessary to also destroy Plot<1> before another plot could be added.

This change fixes this case by trying all 0-N cases.
2021-03-21 18:06:18 -07:00
Peter Johnson
2d2eaa3eff [wpigui] Ensure window will be initially visible (#3256)
Only set the initial window position if the window X/Y postion is within one
of the connected monitor work areas.
2021-03-21 12:39:33 -07:00
Prateek Machiraju
4d28b1f0cd [wpimath] Use JNI for trajectory serialization (#3257) 2021-03-21 12:38:23 -07:00
Peter Johnson
3de800a607 [wpimath] TrajectoryUtil.h: Comment formatting (NFC) (#3262) 2021-03-21 11:40:15 -07:00
Peter Johnson
eff5923778 [glass] Plot: Don't overwrite series ID (#3260) 2021-03-21 11:14:25 -07:00
Peter Johnson
a79faace1b [wpilibc] Return reference from GetInstance (#3247)
Improves consistency across all classes.

Affects Preferences, LiveWindow, and CameraServer.

Old commands Scheduler::GetInstance() was not updated as this is already
deprecated.
2021-03-21 11:13:49 -07:00
Peter Johnson
9550777b9d [wpilib] PWMSpeedController: Use PWM by composition (#3248)
This cleans up the user experience by removing lower-level functions from the
interface.

Also remove MotorSafety from "raw" PWM.
2021-03-21 11:12:49 -07:00
Peter Johnson
c8521a3c33 [glass] Plot: Set reasonable default window size (#3261) 2021-03-21 10:50:41 -07:00
Peter Johnson
d71eb2cf39 [glass] Plot: Show full source name as tooltip and in popup (#3255) 2021-03-20 20:59:31 -07:00
Peter Johnson
160fb740f4 [hal] Use std::lround() instead of adding 0.5 and truncating (#3012) 2021-03-19 14:24:46 -07:00
Peter Johnson
48e9f39513 [wpilibj] Remove wpilibj package CameraServer (#3213) 2021-03-19 13:51:53 -07:00
Peter Johnson
8afa596fdf [wpilib] Remove deprecated Sendable functions and SendableBase (#3210) 2021-03-19 13:41:11 -07:00
Prateek Machiraju
d3e45c297c [wpimath] Make C++ geometry classes immutable (#3249) 2021-03-19 13:38:54 -07:00
Peter Johnson
2c98939c18 [glass] StringChooser: Don't call SameLine() at end 2021-03-19 13:15:26 -07:00
Peter Johnson
a18a7409fb [glass] NTStringChooser: Clear value of deleted entries 2021-03-19 13:15:26 -07:00
Peter Johnson
2f19cf4524 [glass] NetworkTablesHelper: listen to delete events 2021-03-19 13:15:26 -07:00
Peter Johnson
da96707dca Merge branch 'main' into 2022 2021-03-19 09:22:02 -07:00
Peter Johnson
c3a8bdc240 [build] Fix clang-tidy action (#3246)
Manually install python3.8, as actions/setup-python now needs Ubuntu 20.04.
2021-03-19 08:59:14 -07:00
Peter Johnson
21624ef273 Add ImGui OutlineViewer (#3220) 2021-03-16 22:05:41 -07:00
Peter Johnson
1032c9b917 [wpiutil] Unbreak wpi::Format on Windows (#3242)
This function relies on the behavior of snprintf returning an error value
when the buffer is too small.  By default, _snprintf_s aborts on Windows
instead of returning an error value.

This caused Glass to fail when trying to print a large NT value to a string.
2021-03-16 22:04:55 -07:00
Peter Johnson
2e07902d76 [glass] NTField2D: Fix name lookup (#3233)
This was causing incorrect detection of duplicate names.
2021-03-12 16:54:26 -08:00
Peter Johnson
6e23e1840a [wpilibc] Remove WPILib.h (#3235)
It's been deprecated for several years, is often broken as it's not tested
frequently, and dramatically increases compile times.
2021-03-12 15:58:47 -08:00
Prateek Machiraju
3e22e45066 [wpilib] Make KoP drivetrain simulation weight 60 lbs (#3228) 2021-03-07 22:54:40 -08:00
Peter Johnson
79d1bd6c8f [glass] NetworkTablesSetting: Allow disable of server option (#3227) 2021-03-07 21:24:59 -08:00
Prateek Machiraju
fe341a16f5 [examples] Use more logical elevator setpoints in GearsBot (#3198) 2021-03-07 16:00:00 -08:00
Peter Johnson
62abf46b3f [glass] NetworkTablesSettings: Don't block GUI (#3226)
On some systems, StopClient et al can take a long time to execute.
Instead run these on a separate thread to avoid blocking the GUI.

Also add option to get IP from DS (default on).
2021-03-07 15:40:05 -08:00
Peter Johnson
a95a5e0d9b [glass] Move NetworkTablesSettings to libglassnt (#3224) 2021-03-06 22:19:00 -08:00
Prateek Machiraju
d6f6ceaba5 [build] Run Spotless formatter (NFC) (#3221)
The original PR (#2934) was created before we moved to Spotless so the
formatting check was never run.
2021-03-04 08:24:05 -08:00
Blake Bourque
0922f8af59 [commands] CommandScheduler.requiring(): Note return can be null (NFC) (#2934) 2021-03-03 23:56:57 -08:00
Prateek Machiraju
6812302ff9 [examples] Make DriveDistanceOffboard example work in sim (#3199)
Adds some basic functionality to the ExampleMotorController so that
controller inputs show up in LiveWindow widgets in simulation.
2021-03-03 23:38:13 -08:00
Prateek Machiraju
f3f86b8e78 [wpimath] Add pose estimator overload for vision + std dev measurement (#3200) 2021-03-03 23:37:18 -08:00
Matt Soucy
1a2680b9e5 [wpilibj] Change CommandBase.withName() to return CommandBase (#3209)
Doing this retains the Sendable portion of the type.
2021-03-03 23:35:37 -08:00
Starlight220
435bbb6a8c [command] RamseteCommand: Output 0 if interrupted (#3216) 2021-02-28 22:06:34 -08:00
Tyler Veness
3cf44e0a53 [hal] Add function for changing HAL Notifier thread priority (#3218) 2021-02-28 22:05:26 -08:00
Prateek Machiraju
40b367513f [wpimath] Units.java: Add kg-lb conversions (#3203) 2021-02-27 10:12:41 -08:00
Prateek Machiraju
9f563d584a [glass] NT: Fix return value in StringToDoubleArray (#3208) 2021-02-26 08:43:12 -08:00
Peter Johnson
af4adf5379 [glass] Auto-size plots to fit window (#3193)
Plots can still be set to have a fixed height, in which case the remaining
space is distributed amongst the auto-sized plots.
2021-02-21 16:38:06 -08:00
Peter Johnson
2560146da3 [sim] GUI: Add option to show prefix in Other Devices (#3186)
Also disable rename popup for this window.
2021-02-21 16:35:49 -08:00
Peter Johnson
eae3a6397a gitignore: Ignore .cache directory (#3196)
This is used by newer clangd versions.
2021-02-21 16:35:01 -08:00
Starlight220
959611420b [wpilib] Require non-zero positive value for PIDController.period (#3175) 2021-02-16 18:07:29 -08:00
Prateek Machiraju
9522f2e8c7 [wpimath] Add methods to concatenate trajectories (#3139)
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
2021-02-16 18:06:36 -08:00
Zachary Orr
e42a0b6cf0 [wpimath] Rotation2d comment formatting (NFC) (#3162) 2021-02-16 18:06:01 -08:00
Claudius Tewari
d1c7032dec [wpimath] Fix order of setting gyro offset in pose estimators (#3176)
The gyro offset should be determined from the desired initial pose, not the current pose. This fix reflects the behavior of the odometry classes and the C++ holonomic pose estimators.
2021-02-16 18:04:38 -08:00
Starlight220
d241bc81ae [sim] Add DoubleSolenoidSim and SolenoidSim classes (#3177) 2021-02-16 18:03:57 -08:00
Tyler Veness
cb7f39afa1 [wpilibc] Add RobotController::GetBatteryVoltage() to C++ (#3179)
This function already exists in Java.
2021-02-16 18:03:25 -08:00
Thad House
99b5ad9ebb [wpilibj] Fix warnings that are not unused variables or deprecation (#3161)
Fix all warnings given by intellisense that are not unused variables or deprecation.
2021-02-12 22:22:11 -08:00
Thad House
c14b237757 [build] Fixup doxygen generated include dirs to match what users would need (#3154) 2021-02-12 22:17:39 -08:00
Starlight220
d447c7dc32 [sim] Add SimDeviceSim ctor overloads (#3134)
Better parallelism with SimDevice.create(), so teams don't have to mess with concatenating the index/channel themselves.
2021-02-12 22:17:13 -08:00
Austin Shalit
247420c9c1 [build] Remove jcenter repo (#3157) 2021-02-12 22:15:52 -08:00
Peter Johnson
04b112e004 [build] Include debug info in plugin published artifacts (#3149) 2021-02-12 22:15:16 -08:00
Prateek Machiraju
be0ce99007 [examples] Use PWMSparkMax instead of PWMVictorSPX (#3156)
This accurately reflects the motor controllers that are distributed in
the Kit of Parts.
2021-02-12 22:14:56 -08:00
Zhiquan Yeo
69e8d0b65d [wpilib] Move RomiGyro into main wpilibc/j (#3143) 2021-02-12 22:14:29 -08:00
Tyler Veness
94e685e1bd [wpimath] Add custom residual support to EKF (#3148)
Fixes #3145.

Co-authored-by: Declan Freeman-Gleason <declanfreemangleason@gmail.com>
2021-02-12 22:13:36 -08:00
Peter Johnson
5899f3dd28 [sim] GUI: Make keyboard settings loading more robust (#3167)
Check values during load and operation to avoid potential crashes due to
ini file errors or corruption.
2021-02-12 22:12:20 -08:00
Prateek Machiraju
f82aa1d564 [wpilib] Fix HolonomicDriveController atReference() behavior (#3163)
The atReference() method previously used the rotation error between the
desired trajectory state and the current pose. This was a bug because we
allow teams to use custom rotation setpoints and that wasn't being taken
into account.
2021-02-12 22:11:57 -08:00
Tyler Veness
fe5c2cf4b7 [wpimath] Remove ControllerUtil.java (#3169)
This was already removed from C++ in the offseason and replaced with
MathUtil.inputModulus(). We just neglected to do that for Java; it was
never intended to see a season release. Its implementation is incorrect
compared to inputModulus() as well.

See https://github.com/wpilibsuite/allwpilib/issues/3168 for discussion.
2021-02-12 22:10:58 -08:00
Thad House
43d40c6e9e [wpiutil] Suppress unchecked cast in CombinedRuntimeLoader (#3155)
Because of Java's type system, it is actually literally impossible to check for this cast at runtime. So instead, the only option is to suppress it. Only suppressed for the specific function.
2021-02-07 08:20:33 -08:00
Tyler Veness
3d44d8f79c [wpimath] Fix argument order in UKF docs (NFC) (#3147) 2021-02-01 23:36:32 -08:00
Peter Johnson
ba6fe8ff2e [cscore] Add USB camera change event (#3123) 2021-01-31 18:52:48 -08:00
Peter Johnson
5337258888 [build] Tweak OpenCV cmake search paths to work better on Linux (#3144)
With this change, cmake finds OpenCV Java on Ubuntu with no additional search options.
2021-01-31 18:52:21 -08:00
Peter Johnson
29bf9d6ef1 [cscore] Add polled support to listener
Change Java VideoListener to use polling.
2021-01-31 17:06:37 -08:00
Peter Johnson
483beb6361 [ntcore] Move CallbackManager to wpiutil 2021-01-31 17:06:37 -08:00
Prateek Machiraju
fdaec77594 [examples] Instantiate m_ramseteController in example (#3142) 2021-01-31 17:04:16 -08:00
Peter Johnson
8494a5761b Rename default branch to main (#3140) 2021-01-30 13:46:56 -08:00
4573 changed files with 390276 additions and 189311 deletions

View File

@@ -1,5 +1,4 @@
---
Language: Cpp
BasedOnStyle: Google
AccessModifierOffset: -1
AlignAfterOpenBracket: Align
@@ -157,7 +156,7 @@ SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: Auto
Standard: c++17
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION

View File

@@ -4,7 +4,6 @@ Checks:
bugprone-copy-constructor-init,
bugprone-dangling-handle,
bugprone-dynamic-static-initializers,
bugprone-exception-escape,
bugprone-forward-declaration-namespace,
bugprone-forwarding-reference-overload,
bugprone-inaccurate-erase,
@@ -54,7 +53,6 @@ Checks:
google-readability-avoid-underscore-in-googletest-name,
google-readability-casting,
google-runtime-operator,
llvm-twine-local,
misc-definitions-in-headers,
misc-misplaced-const,
misc-new-delete-overloads,
@@ -71,6 +69,3 @@ Checks:
modernize-use-using,
readability-braces-around-statements'
FormatStyle: file
CheckOptions:
- key: bugprone-dangling-handle
value: 'wpi::StringRef;wpi::Twine'

View File

@@ -22,7 +22,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):**
- OS: [e.g. Windows]
- WPILib Version: [e.g. 2021.3.1]
- OS: [e.g. Windows 11]
- Java version [e.g. 1.10.2]
- C++ version [e.g. 17]

View File

@@ -2,58 +2,55 @@ name: CMake
on: [pull_request, push]
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
- os: ubuntu-22.04
name: Linux
container: wpilib/roborio-cross-ubuntu:2020-18.04
container: wpilib/roborio-cross-ubuntu:2023-22.04
flags: ""
- os: macos-latest
- os: macOS-11
name: macOS
container: ""
flags: "-DWITH_JAVA=OFF"
name: "Build - ${{ matrix.name }}"
runs-on: ${{ matrix.os }}
container: ${{ matrix.container }}
steps:
- uses: actions/checkout@v2
- name: Install Dependencies
run: |
if [ "$RUNNER_OS" == "macOS" ]; then
brew install opencv
fi
- uses: actions/checkout@v3
- name: Install dependencies (Linux)
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y libopencv-dev libopencv4.5-java python-is-python3
- name: Install opencv (macOS)
run: brew install opencv
if: runner.os == 'macOS'
- name: Set up Python 3.8 (macOS)
if: runner.os == 'macOS'
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Install jinja
run: python -m pip install jinja2
- name: configure
run: mkdir build && cd build && cmake ${{ matrix.flags }} ..
- name: build
working-directory: build
run: make -j3
run: cmake --build . --parallel $(nproc)
- name: test
working-directory: build
run: make test
build-vcpkg:
name: "Build - Windows"
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
- name: Prepare vcpkg
uses: lukka/run-vcpkg@v4
with:
vcpkgArguments: opencv
vcpkgDirectory: ${{ runner.workspace }}/vcpkg/
vcpkgGitCommitId: 544f8e4593764f78faa94bac2adb81cca5232943
vcpkgTriplet: x64-windows
- name: Configure & Build
uses: lukka/run-cmake@v3
with:
buildDirectory: ${{ runner.workspace }}/build/
cmakeAppendedArgs: -DWITH_JAVA=OFF
cmakeListsOrSettingsJson: CMakeListsTxtAdvanced
useVcpkgToolchainFile: true
- name: Run Tests
run: ctest -C "Debug"
working-directory: ${{ runner.workspace }}/build/
run: ctest --output-on-failure

64
.github/workflows/comment-command.yml vendored Normal file
View File

@@ -0,0 +1,64 @@
name: Comment Commands
on:
issue_comment:
types: [ created ]
jobs:
format:
if: github.event.issue.pull_request && startsWith(github.event.comment.body, '/format')
runs-on: ubuntu-22.04
steps:
- name: React Rocket
uses: actions/github-script@v4
with:
script: |
const {owner, repo} = context.issue
github.reactions.createForIssueComment({
owner,
repo,
comment_id: context.payload.comment.id,
content: "rocket",
});
- uses: actions/checkout@v3
with:
token: ${{ secrets.COMMENT_COMMAND_PAT_TOKEN }}
- name: Fetch all history and metadata
run: |
git fetch --prune --unshallow
git checkout -b pr
git branch -f main origin/main
- name: Checkout PR
run: |
gh pr checkout $NUMBER
env:
GITHUB_TOKEN: "${{ secrets.COMMENT_COMMAND_PAT_TOKEN }}"
NUMBER: ${{ github.event.issue.number }}
- name: Set up Python 3.8
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Setup Java
uses: actions/setup-java@v3
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
- name: Run spotlessApply
run: ./gradlew spotlessApply
- name: Commit
run: |
# Set credentials
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
# Commit
git commit -am "Formatting fixes"
git push

View File

@@ -2,26 +2,32 @@ name: Documentation
on: [push, workflow_dispatch]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
BASE_PATH: allwpilib/docs
jobs:
publish:
name: "Documentation - Publish"
runs-on: ubuntu-latest
if: github.repository_owner == 'wpilibsuite' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v'))
runs-on: ubuntu-22.04
if: github.repository_owner == 'wpilibsuite' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
concurrency: ci-docs-publish
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0
persist-credentials: false
- uses: actions/setup-java@v1
- uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: 13
- name: Set environment variables (Development)
run: |
echo "TARGET_FOLDER=$BASE_PATH/development" >> $GITHUB_ENV
if: github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/main'
- name: Set environment variables (Tag)
run: |
echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
@@ -35,7 +41,7 @@ jobs:
- name: Build with Gradle
run: ./gradlew docs:generateJavaDocs docs:doxygen -PbuildServer ${{ env.EXTRA_GRADLE_ARGS }}
- name: Install SSH Client 🔑
uses: webfactory/ssh-agent@v0.4.1
uses: webfactory/ssh-agent@v0.7.0
with:
ssh-private-key: ${{ secrets.GH_DEPLOY_KEY }}
- name: Deploy Java 🚀

View File

@@ -1,15 +0,0 @@
name: Gazebo
on: [pull_request, push]
jobs:
build:
name: "Build"
runs-on: ubuntu-latest
container: wpilib/gazebo-ubuntu:18.04
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Build with Gradle
run: ./gradlew build -PbuildServer -PmakeSim -Dorg.gradle.jvmargs=-Xmx2g

View File

@@ -1,10 +1,14 @@
name: "Validate Gradle Wrapper"
on: [push, pull_request]
on: [pull_request, push]
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
jobs:
validation:
name: "Validation"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: gradle/wrapper-validation-action@v1

View File

@@ -2,66 +2,87 @@ name: Gradle
on: [pull_request, push]
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
jobs:
build-docker:
strategy:
fail-fast: false
matrix:
include:
- container: wpilib/roborio-cross-ubuntu:2021-18.04
- container: wpilib/roborio-cross-ubuntu:2023-22.04
artifact-name: Athena
build-options: "-Ponlylinuxathena"
- container: wpilib/raspbian-cross-ubuntu:10-18.04
artifact-name: Raspbian
build-options: "-Ponlylinuxraspbian"
- container: wpilib/aarch64-cross-ubuntu:bionic-18.04
artifact-name: Aarch64
build-options: "-Ponlylinuxaarch64bionic"
- container: wpilib/ubuntu-base:18.04
- container: wpilib/raspbian-cross-ubuntu:bullseye-22.04
artifact-name: Arm32
build-options: "-Ponlylinuxarm32"
- container: wpilib/aarch64-cross-ubuntu:bullseye-22.04
artifact-name: Arm64
build-options: "-Ponlylinuxarm64"
- container: wpilib/ubuntu-base:22.04
artifact-name: Linux
build-options: "-Dorg.gradle.jvmargs=-Xmx2g"
build-options: "-Ponlylinuxx86-64"
name: "Build - ${{ matrix.artifact-name }}"
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
container: ${{ matrix.container }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set release environment variable
run: echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
if: startsWith(github.ref, 'refs/tags/v')
- name: Build with Gradle
run: ./gradlew build -PbuildServer ${{ matrix.build-options }} ${{ env.EXTRA_GRADLE_ARGS }}
- uses: actions/upload-artifact@v2
run: ./gradlew build --build-cache -PbuildServer -PskipJavaFormat ${{ matrix.build-options }} ${{ env.EXTRA_GRADLE_ARGS }}
env:
ARTIFACTORY_PUBLISH_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
ARTIFACTORY_PUBLISH_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
- uses: actions/upload-artifact@v3
with:
name: ${{ matrix.artifact-name }}
path: build/allOutputs
build-host:
env:
MACOSX_DEPLOYMENT_TARGET: 10.14
MACOSX_DEPLOYMENT_TARGET: 10.15
strategy:
fail-fast: false
matrix:
include:
- os: windows-latest
artifact-name: Win64
- os: windows-2022
artifact-name: Win64Debug
architecture: x64
- os: windows-latest
artifact-name: Win32
architecture: x86
- os: macos-latest
task: "build"
build-options: "-PciDebugOnly --max-workers 1"
outputs: "build/allOutputs"
- os: windows-2022
artifact-name: Win64Release
architecture: x64
build-options: "-PciReleaseOnly --max-workers 1"
task: "copyAllOutputs"
outputs: "build/allOutputs"
- os: macOS-11
artifact-name: macOS
architecture: x64
task: "build"
outputs: "build/allOutputs"
- os: windows-2022
artifact-name: Win32
architecture: x86
task: ":ntcoreffi:build"
outputs: "ntcoreffi/build/outputs"
name: "Build - ${{ matrix.artifact-name }}"
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-java@v1
- uses: actions/setup-java@v3
with:
java-version: 11
distribution: 'zulu'
java-version: 17
architecture: ${{ matrix.architecture }}
- name: Import Developer ID Certificate
uses: wpilibsuite/import-signing-certificate@v1
@@ -71,44 +92,54 @@ jobs:
keychain-password: ${{ secrets.APPLE_KEYCHAIN_PASSWORD }}
if: |
matrix.artifact-name == 'macOS' && (github.repository_owner == 'wpilibsuite' &&
(github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v')))
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')))
- name: Set Keychain Lock Timeout
run: security set-keychain-settings -lut 3600
if: |
matrix.artifact-name == 'macOS' && (github.repository_owner == 'wpilibsuite' &&
(github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v')))
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')))
- name: Set release environment variable
run: echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
shell: bash
if: startsWith(github.ref, 'refs/tags/v')
- name: Set Java Heap Size
run: sed -i 's/-Xmx2g/-Xmx1g/g' gradle.properties
if: matrix.artifact-name == 'Win32'
- name: Build with Gradle
run: ./gradlew build -PbuildServer ${{ env.EXTRA_GRADLE_ARGS }}
run: ./gradlew ${{ matrix.task }} --build-cache -PbuildServer -PskipJavaFormat ${{ matrix.build-options }} ${{ env.EXTRA_GRADLE_ARGS }}
env:
ARTIFACTORY_PUBLISH_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
ARTIFACTORY_PUBLISH_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
- name: Sign Libraries with Developer ID
run: ./gradlew build -PbuildServer -PdeveloperID=${{ secrets.APPLE_DEVELOPER_ID }} ${{ env.EXTRA_GRADLE_ARGS }}
run: ./gradlew copyAllOutputs --build-cache -PbuildServer -PskipJavaFormat -PdeveloperID=${{ secrets.APPLE_DEVELOPER_ID }} ${{ matrix.build-options }} ${{ env.EXTRA_GRADLE_ARGS }}
if: |
matrix.artifact-name == 'macOS' && (github.repository_owner == 'wpilibsuite' &&
(github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v')))
- uses: actions/upload-artifact@v2
(github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')))
- uses: actions/upload-artifact@v3
with:
name: ${{ matrix.artifact-name }}
path: build/allOutputs
path: ${{ matrix.outputs }}
build-documentation:
name: "Build - Documentation"
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-java@v1
- uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: 13
- name: Set release environment variable
run: echo "EXTRA_GRADLE_ARGS=-PreleaseMode" >> $GITHUB_ENV
if: startsWith(github.ref, 'refs/tags/v')
- name: Build with Gradle
run: ./gradlew docs:zipDocs -PbuildServer ${{ env.EXTRA_GRADLE_ARGS }}
- uses: actions/upload-artifact@v2
run: ./gradlew docs:zipDocs --build-cache -PbuildServer ${{ env.EXTRA_GRADLE_ARGS }}
env:
ARTIFACTORY_PUBLISH_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
ARTIFACTORY_PUBLISH_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
- uses: actions/upload-artifact@v3
with:
name: Documentation
path: docs/build/outputs
@@ -116,12 +147,12 @@ jobs:
combine:
name: Combine
needs: [build-docker, build-host, build-documentation]
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
repository: wpilibsuite/build-tools
- uses: actions/download-artifact@v2
- uses: actions/download-artifact@v3
with:
path: combiner/products/build/allOutputs
- name: Flatten Artifacts
@@ -130,18 +161,19 @@ jobs:
run: |
cat combiner/products/build/allOutputs/version.txt
test -s combiner/products/build/allOutputs/version.txt
- uses: actions/setup-java@v1
- uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: 11
- name: Combine
if: |
!startsWith(github.ref, 'refs/tags/v') &&
github.ref != 'refs/heads/master'
github.ref != 'refs/heads/main'
run: cd combiner && ./gradlew publish -Pallwpilib
- name: Combine (Master)
if: |
github.repository_owner == 'wpilibsuite' &&
github.ref == 'refs/heads/master'
github.ref == 'refs/heads/main'
run: cd combiner && ./gradlew publish -Pallwpilib
env:
RUN_AZURE_ARTIFACTORY_RELEASE: "TRUE"
@@ -156,7 +188,7 @@ jobs:
RUN_AZURE_ARTIFACTORY_RELEASE: "TRUE"
ARTIFACTORY_PUBLISH_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
ARTIFACTORY_PUBLISH_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
- uses: actions/upload-artifact@v2
- uses: actions/upload-artifact@v3
with:
name: Maven
path: ~/releases

View File

@@ -1,52 +1,118 @@
name: Lint and Format
on: [pull_request]
on:
pull_request:
push:
branches-ignore:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
jobs:
wpiformat:
name: "wpiformat"
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Fetch all history and metadata
run: |
git config --global --add safe.directory /__w/allwpilib/allwpilib
git fetch --prune --unshallow
git checkout -b pr
git branch -f master origin/master
git branch -f main origin/main
- name: Set up Python 3.8
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Install clang-format
run: sudo apt-get update -q && sudo apt-get install -y clang-format-10
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 10
- name: Check Output
run: wpiformat -clang 14
- name: Check output
run: git --no-pager diff --exit-code HEAD
- name: Generate diff
run: git diff HEAD > wpiformat-fixes.patch
if: ${{ failure() }}
- uses: actions/upload-artifact@v3
with:
name: wpiformat fixes
path: wpiformat-fixes.patch
if: ${{ failure() }}
- name: Write to job summary
run: |
echo '```diff' >> $GITHUB_STEP_SUMMARY
cat wpiformat-fixes.patch >> $GITHUB_STEP_SUMMARY
echo '' >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
if: ${{ failure() }}
tidy:
name: "clang-tidy"
runs-on: ubuntu-latest
container: wpilib/roborio-cross-ubuntu:2020-18.04
runs-on: ubuntu-22.04
container: wpilib/roborio-cross-ubuntu:2023-22.04
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Fetch all history and metadata
run: |
git config --global --add safe.directory /__w/allwpilib/allwpilib
git fetch --prune --unshallow
git checkout -b pr
git branch -f master origin/master
git branch -f main origin/main
- name: Set up Python 3.8
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Install clang-format and clang-tidy
run: sudo apt-get update -q && sudo apt-get install -y clang-format-10 clang-tidy-10
- 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
run: mkdir build-cmake && cd build-cmake && cmake -DWITH_OLD_COMMANDS=ON -DWITH_EXAMPLES=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=YES ..
run: ./gradlew generateCompileCommands -Ptoolchain-optional-roboRio
- name: List changed files
run: wpiformat -list-changed-files
- name: Run clang-tidy
run: wpiformat -clang 10 -no-format -tidy-changed -compile-commands=build-cmake
run: wpiformat -clang 14 -no-format -tidy-changed -compile-commands=build/compile_commands/linuxx86-64 -vv
javaformat:
name: "Java format"
runs-on: ubuntu-22.04
container: wpilib/ubuntu-base:22.04
steps:
- uses: actions/checkout@v3
- name: Fetch all history and metadata
run: |
git config --global --add safe.directory /__w/allwpilib/allwpilib
git fetch --prune --unshallow
git checkout -b pr
git branch -f main origin/main
- name: Run Java format
run: ./gradlew javaFormat spotbugsMain spotbugsTest spotbugsDev
- name: Check output
run: git --no-pager diff --exit-code HEAD
- name: Generate diff
run: git diff HEAD > javaformat-fixes.patch
if: ${{ failure() }}
documentation:
name: "Documentation"
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: 13
- name: Build with Gradle
run: ./gradlew docs:zipDocs -PbuildServer -PdocWarningsAsErrors ${{ env.EXTRA_GRADLE_ARGS }}

48
.github/workflows/sanitizers.yml vendored Normal file
View File

@@ -0,0 +1,48 @@
name: Sanitizers
on: [pull_request, push]
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- name: asan
cmake-flags: "-DCMAKE_BUILD_TYPE=Asan"
ctest-env: ""
ctest-flags: "-E 'wpilibc'"
- name: tsan
cmake-flags: "-DCMAKE_BUILD_TYPE=Tsan"
ctest-env: "TSAN_OPTIONS=second_deadlock_stack=1"
ctest-flags: "-E 'cscore|cameraserver|wpilibc|wpilibNewCommands'"
- name: ubsan
cmake-flags: "-DCMAKE_BUILD_TYPE=Ubsan"
ctest-env: ""
ctest-flags: ""
name: "${{ matrix.name }}"
runs-on: ubuntu-22.04
container: wpilib/roborio-cross-ubuntu:2023-22.04
steps:
- uses: actions/checkout@v3
- name: Install Dependencies
run: sudo apt-get update && sudo apt-get install -y libopencv-dev libopencv4.5-java python-is-python3 clang-14
- name: Install jinja
run: python -m pip install jinja2
- name: configure
run: mkdir build && cd build && cmake -DCMAKE_C_COMPILER:FILEPATH=/usr/bin/clang-14 -DCMAKE_CXX_COMPILER:FILEPATH=/usr/bin/clang++-14 ${{ matrix.cmake-flags }} ..
- name: build
working-directory: build
run: cmake --build . --parallel $(nproc)
- name: test
working-directory: build
run: ${{ matrix.ctest-env }} ctest --output-on-failure ${{ matrix.ctest-flags }}

67
.github/workflows/upstream-utils.yml vendored Normal file
View File

@@ -0,0 +1,67 @@
name: Upstream utils
on:
pull_request:
push:
branches-ignore:
- main
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: true
jobs:
update:
name: "Update"
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Fetch all history and metadata
run: |
git fetch --prune --unshallow
git checkout -b pr
git branch -f main origin/main
- name: Set up Python 3.9
uses: actions/setup-python@v4
with:
python-version: 3.9
- name: Configure committer identity
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
./update_eigen.py
- name: Run update_fmt.py
run: |
cd upstream_utils
./update_fmt.py
- name: Run update_libuv.py
run: |
cd upstream_utils
./update_libuv.py
- name: Run update_llvm.py
run: |
cd upstream_utils
./update_llvm.py
- name: Run update_mpack.py
run: |
cd upstream_utils
./update_mpack.py
- name: Run update_stack_walker.py
run: |
cd upstream_utils
./update_stack_walker.py
- name: Run update_memory.py
run: |
cd upstream_utils
./update_memory.py
- name: Add untracked files to index so they count as changes
run: git add -A
- name: Check output
run: git --no-pager diff --exit-code HEAD

16
.gitignore vendored
View File

@@ -5,6 +5,12 @@ doxygen.log
build*/
!buildSrc/
simgui-ds.json
simgui-window.json
simgui.json
networktables.json
# Created by the jenkins test script
test-reports
@@ -15,6 +21,9 @@ test-reports
.idea/
out/
# Fleet
.fleet
# Created by http://www.gitignore.io
### Linux ###
@@ -222,5 +231,12 @@ compile_commands.json
# clang configuration and clangd cache
.clang
.clangd/
.cache/
imgui.ini
# Bazel
/.ijwb/
/bazel-*
user.bazelrc
coverage_report/

View File

@@ -9,9 +9,16 @@ cppSrcFileInclude {
\.cpp$
}
modifiableFileExclude {
\.patch$
gradlew
}
generatedFileExclude {
FRCNetComm\.java$
simulation/gz_msgs/src/include/simulation/gz_msgs/msgs\.h$
fieldImages/src/main/native/resources/
apriltag/src/test/resources/
}
repoRootNameOverride {
@@ -23,6 +30,7 @@ includeOtherLibs {
^cameraserver/
^cscore
^drake/
^fmt/
^hal/
^imgui
^implot
@@ -37,4 +45,5 @@ includeOtherLibs {
^wpi/
^wpigui
^wpimath/
^wpinet/
}

View File

@@ -1,6 +1,6 @@
{
"enableCppIntellisense": true,
"currentLanguage": "cpp",
"projectYear": "2021",
"projectYear": "intellisense",
"teamNumber": 0
}

View File

@@ -6,11 +6,17 @@ FATAL: In-source builds are not allowed.
")
endif()
if ("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows")
set(CMAKE_SYSTEM_VERSION 10.0.18362.0 CACHE STRING INTERNAL FORCE)
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)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
message(STATUS "Platform version: ${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}")
set(WPILIB_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
INCLUDE(CPack)
@@ -30,25 +36,25 @@ SET(CMAKE_SKIP_BUILD_RPATH FALSE)
# (but later on when installing)
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/wpilib/lib")
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
# add the automatically determined parts of the RPATH
# which point to directories outside the build tree to the install RPATH
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# the RPATH to be used when installing, but only if it's not a system directory
LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/wpilib/lib" isSystemDir)
LIST(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir)
IF("${isSystemDir}" STREQUAL "-1")
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/wpilib/lib")
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
ENDIF("${isSystemDir}" STREQUAL "-1")
# Options for building certain parts of the repo. Everything is built by default.
option(BUILD_SHARED_LIBS "Build with shared libs (needed for JNI)" ON)
option(WITH_JAVA "Include java and JNI in the build" ON)
option(WITH_CSCORE "Build cscore (needs OpenCV)" ON)
option(WITH_NTCORE "Build ntcore" ON)
option(WITH_WPIMATH "Build wpimath" ON)
option(WITH_WPILIB "Build hal, wpilibc/j, and myRobot (needs OpenCV)" ON)
option(WITH_OLD_COMMANDS "Build old commands" OFF)
option(WITH_EXAMPLES "Build examples" OFF)
option(WITH_TESTS "Build unit tests (requires internet connection)" ON)
option(WITH_GUI "Build GUI items" ON)
@@ -58,9 +64,10 @@ option(WITH_SIMULATION_MODULES "Build simulation modules" ON)
option(WITH_EXTERNAL_HAL "Use a separately built HAL" OFF)
set(EXTERNAL_HAL_FILE "" CACHE FILEPATH "Location to look for an external HAL CMake File")
# Options for using a package manager (vcpkg) for certain dependencies.
option(USE_VCPKG_LIBUV "Use vcpkg libuv" OFF)
option(USE_VCPKG_EIGEN "Use vcpkg eigen" OFF)
# Options for using a package manager (e.g., vcpkg) for certain dependencies.
option(USE_SYSTEM_FMTLIB "Use system fmtlib" OFF)
option(USE_SYSTEM_LIBUV "Use system libuv" OFF)
option(USE_SYSTEM_EIGEN "Use system eigen" OFF)
# Options for installation.
option(WITH_FLAT_INSTALL "Use a flat install directory" OFF)
@@ -111,6 +118,34 @@ FATAL: Cannot build simulation modules with wpilib disabled.
")
endif()
if (NOT WITH_NTCORE AND WITH_CSCORE)
message(FATAL_ERROR "
FATAL: Cannot build cameraserver without ntcore.
Enable ntcore by setting WITH_NTCORE=ON
")
endif()
if (NOT WITH_NTCORE AND WITH_GUI)
message(FATAL_ERROR "
FATAL: Cannot build GUI modules without ntcore.
Enable ntcore by setting WITH_NTCORE=ON
")
endif()
if (NOT WITH_NTCORE AND WITH_SIMULATION_MODULES)
message(FATAL_ERROR "
FATAL: Cannot build simulation modules without ntcore.
Enable ntcore by setting WITH_NTCORE=ON
")
endif()
if (NOT WITH_NTCORE AND WITH_WPILIB)
message(FATAL_ERROR "
FATAL: Cannot build wpilib without ntcore.
Enable ntcore by setting WITH_NTCORE=ON
")
endif()
if (NOT WITH_WPIMATH AND WITH_WPILIB)
message(FATAL_ERROR "
FATAL: Cannot build wpilib without wpimath.
@@ -118,18 +153,11 @@ FATAL: Cannot build wpilib without wpimath.
")
endif()
if (NOT WITH_OLD_COMMANDS AND WITH_EXAMPLES)
message(FATAL_ERROR "
FATAL: Cannot build examples with old commands disabled.
Enable old commands by setting WITH_OLD_COMMANDS=ON
")
endif()
set( wpilib_dest wpilib)
set( include_dest wpilib/include )
set( main_lib_dest wpilib/lib )
set( java_lib_dest wpilib/java )
set( jni_lib_dest wpilib/jni )
set( wpilib_dest "")
set( include_dest include )
set( main_lib_dest lib )
set( java_lib_dest java )
set( jni_lib_dest jni )
if (WITH_FLAT_INSTALL)
set (wpilib_config_dir ${wpilib_dest})
@@ -137,16 +165,22 @@ else()
set (wpilib_config_dir share/wpilib)
endif()
if (USE_VCPKG_LIBUV)
set (LIBUV_VCPKG_REPLACE "find_package(unofficial-libuv CONFIG)")
if (USE_SYSTEM_LIBUV)
set (LIBUV_SYSTEM_REPLACE "
find_package(PkgConfig REQUIRED)
pkg_check_modules(libuv REQUIRED IMPORTED_TARGET libuv)
")
endif()
if (USE_VCPKG_EIGEN)
set (EIGEN_VCPKG_REPLACE "find_package(Eigen3 CONFIG)")
if (USE_SYSTEM_EIGEN)
set (EIGEN_SYSTEM_REPLACE "find_package(Eigen3 CONFIG)")
endif()
find_package(LIBSSH 0.7.1)
if (WITH_FLAT_INSTALL)
set(WPIUTIL_DEP_REPLACE "include($\{SELF_DIR\}/wpiutil-config.cmake)")
set(WPINET_DEP_REPLACE "include($\{SELF_DIR\}/wpinet-config.cmake)")
set(NTCORE_DEP_REPLACE "include($\{SELF_DIR\}/ntcore-config.cmake)")
set(CSCORE_DEP_REPLACE_IMPL "include(\${SELF_DIR}/cscore-config.cmake)")
set(CAMERASERVER_DEP_REPLACE_IMPL "include(\${SELF_DIR}/cameraserver-config.cmake)")
@@ -154,9 +188,9 @@ set(HAL_DEP_REPLACE_IMPL "include(\${SELF_DIR}/hal-config.cmake)")
set(WPIMATH_DEP_REPLACE "include($\{SELF_DIR\}/wpimath-config.cmake)")
set(WPILIBC_DEP_REPLACE_IMPL "include(\${SELF_DIR}/wpilibc-config.cmake)")
set(WPILIBNEWCOMMANDS_DEP_REPLACE "include(\${SELF_DIR}/wpilibNewcommands-config.cmake)")
set(WPILIBOLDCOMMANDS_DEP_REPLACE "include(\${SELF_DIR}/wpilibOldcommands-config.cmake)")
else()
set(WPIUTIL_DEP_REPLACE "find_dependency(wpiutil)")
set(WPINET_DEP_REPLACE "find_dependency(wpinet)")
set(NTCORE_DEP_REPLACE "find_dependency(ntcore)")
set(CSCORE_DEP_REPLACE_IMPL "find_dependency(cscore)")
set(CAMERASERVER_DEP_REPLACE_IMPL "find_dependency(cameraserver)")
@@ -164,12 +198,80 @@ set(HAL_DEP_REPLACE_IMPL "find_dependency(hal)")
set(WPIMATH_DEP_REPLACE "find_dependency(wpimath)")
set(WPILIBC_DEP_REPLACE_IMPL "find_dependency(wpilibc)")
set(WPILIBNEWCOMMANDS_DEP_REPLACE "find_dependency(wpilibNewCommands)")
set(WPILIBOLDCOMMANDS_DEP_REPLACE "find_dependency(wpilibOldCommands)")
endif()
set(FILENAME_DEP_REPLACE "get_filename_component(SELF_DIR \"$\{CMAKE_CURRENT_LIST_FILE\}\" PATH)")
set(SELF_DIR "$\{SELF_DIR\}")
get_property(isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(isMultiConfig)
if(NOT "Asan" IN_LIST CMAKE_CONFIGURATION_TYPES)
list(APPEND CMAKE_CONFIGURATION_TYPES Asan)
endif()
if(NOT "Tsan" IN_LIST CMAKE_CONFIGURATION_TYPES)
list(APPEND CMAKE_CONFIGURATION_TYPES Tsan)
endif()
if(NOT "Ubsan" IN_LIST CMAKE_CONFIGURATION_TYPES)
list(APPEND CMAKE_CONFIGURATION_TYPES Ubsan)
endif()
else()
set(allowedBuildTypes Asan Tsan Ubsan Debug Release RelWithDebInfo MinSizeRel)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "${allowedBuildTypes}")
if(CMAKE_BUILD_TYPE AND NOT CMAKE_BUILD_TYPE IN_LIST allowedBuildTypes)
message(FATAL_ERROR "Invalid build type: ${CMAKE_BUILD_TYPE}")
endif()
endif()
set(CMAKE_C_FLAGS_ASAN
"${CMAKE_C_FLAGS_DEBUG} -fsanitize=address -fno-omit-frame-pointer" CACHE STRING
"Flags used by the C compiler for Asan build type or configuration." FORCE)
set(CMAKE_CXX_FLAGS_ASAN
"${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address -fno-omit-frame-pointer" CACHE STRING
"Flags used by the C++ compiler for Asan build type or configuration." FORCE)
set(CMAKE_EXE_LINKER_FLAGS_ASAN
"${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fsanitize=address" CACHE STRING
"Linker flags to be used to create executables for Asan build type." FORCE)
set(CMAKE_SHARED_LINKER_FLAGS_ASAN
"${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fsanitize=address" CACHE STRING
"Linker lags to be used to create shared libraries for Asan build type." FORCE)
set(CMAKE_C_FLAGS_TSAN
"${CMAKE_C_FLAGS_DEBUG} -fsanitize=thread -fno-omit-frame-pointer" CACHE STRING
"Flags used by the C compiler for Tsan build type or configuration." FORCE)
set(CMAKE_CXX_FLAGS_TSAN
"${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=thread -fno-omit-frame-pointer" CACHE STRING
"Flags used by the C++ compiler for Tsan build type or configuration." FORCE)
set(CMAKE_EXE_LINKER_FLAGS_TSAN
"${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fsanitize=thread" CACHE STRING
"Linker flags to be used to create executables for Tsan build type." FORCE)
set(CMAKE_SHARED_LINKER_FLAGS_TSAN
"${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fsanitize=thread" CACHE STRING
"Linker lags to be used to create shared libraries for Tsan build type." FORCE)
set(CMAKE_C_FLAGS_UBSAN
"${CMAKE_C_FLAGS_DEBUG} -fsanitize=undefined -fno-sanitize-recover=all -fno-omit-frame-pointer" CACHE STRING
"Flags used by the C compiler for Ubsan build type or configuration." FORCE)
set(CMAKE_CXX_FLAGS_UBSAN
"${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=undefined -fno-sanitize-recover=all -fno-omit-frame-pointer" CACHE STRING
"Flags used by the C++ compiler for Ubsan build type or configuration." FORCE)
set(CMAKE_EXE_LINKER_FLAGS_UBSAN
"${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fsanitize=undefined -fno-sanitize-recover=all" CACHE STRING
"Linker flags to be used to create executables for Ubsan build type." FORCE)
set(CMAKE_SHARED_LINKER_FLAGS_UBSAN
"${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fsanitize=undefined" CACHE STRING
"Linker lags to be used to create shared libraries for Ubsan build type." FORCE)
if (WITH_TESTS)
enable_testing()
add_subdirectory(googletest)
@@ -177,16 +279,31 @@ if (WITH_TESTS)
endif()
add_subdirectory(wpiutil)
add_subdirectory(ntcore)
if (WITH_NTCORE)
add_subdirectory(wpinet)
add_subdirectory(ntcore)
endif()
if (WITH_WPIMATH)
add_subdirectory(wpimath)
endif()
if (WITH_GUI)
add_subdirectory(fieldImages)
add_subdirectory(imgui)
add_subdirectory(wpigui)
add_subdirectory(glass)
add_subdirectory(outlineviewer)
if (LIBSSH_FOUND)
add_subdirectory(roborioteamnumbersetter)
add_subdirectory(datalogtool)
endif()
endif()
if (WITH_WPILIB OR WITH_SIMULATION_MODULES)
set(HAL_DEP_REPLACE ${HAL_DEP_REPLACE_IMPL})
add_subdirectory(hal)
endif()
if (WITH_CSCORE)
@@ -194,21 +311,18 @@ if (WITH_CSCORE)
set(CAMERASERVER_DEP_REPLACE ${CAMERASERVER_DEP_REPLACE_IMPL})
add_subdirectory(cscore)
add_subdirectory(cameraserver)
if (WITH_WPILIB)
set(HAL_DEP_REPLACE ${HAL_DEP_REPLACE_IMPL})
set(WPILIBC_DEP_REPLACE ${WPILIBC_DEP_REPLACE_IMPL})
add_subdirectory(hal)
add_subdirectory(wpilibj)
add_subdirectory(wpilibc)
add_subdirectory(wpilibNewCommands)
if (WITH_OLD_COMMANDS)
add_subdirectory(wpilibOldCommands)
endif()
if (WITH_EXAMPLES)
add_subdirectory(wpilibcExamples)
endif()
add_subdirectory(myRobot)
endif()
if (WITH_WPILIB)
set(WPILIBC_DEP_REPLACE ${WPILIBC_DEP_REPLACE_IMPL})
add_subdirectory(apriltag)
add_subdirectory(wpilibj)
add_subdirectory(wpilibc)
add_subdirectory(wpilibNewCommands)
if (WITH_EXAMPLES)
add_subdirectory(wpilibcExamples)
endif()
add_subdirectory(myRobot)
endif()
if (WITH_SIMULATION_MODULES AND NOT WITH_EXTERNAL_HAL)

View File

@@ -1,6 +1,6 @@
# Contributing to WPILib
So you want to contribute your changes back to WPILib. Great! We have a few contributing rules that will help you make sure your changes will be accepted into the project. Please remember to follow the rules in the [code of conduct](https://github.com/wpilibsuite/allwpilib/blob/master/CODE_OF_CONDUCT.md), and behave with Gracious Professionalism.
So you want to contribute your changes back to WPILib. Great! We have a few contributing rules that will help you make sure your changes will be accepted into the project. Please remember to follow the rules in the [code of conduct](https://github.com/wpilibsuite/allwpilib/blob/main/CODE_OF_CONDUCT.md), and behave with Gracious Professionalism.
- [General Contribution Rules](#general-contribution-rules)
- [What to Contribute](#what-to-contribute)
@@ -37,15 +37,47 @@ So you want to contribute your changes back to WPILib. Great! We have a few cont
## Coding Guidelines
WPILib uses modified Google style guides for both C++ and Java, which can be found in the [styleguide repository](https://github.com/wpilibsuite/styleguide). Autoformatters are available for many popular editors at https://github.com/google/styleguide. Running wpiformat is required for all contributions and is enforced by our continuous integration system. We currently use clang-format 10.0 with wpiformat.
WPILib uses modified Google style guides for both C++ and Java, which can be found in the [styleguide repository](https://github.com/wpilibsuite/styleguide). Autoformatters are available for many popular editors at https://github.com/google/styleguide. Running wpiformat is required for all contributions and is enforced by our continuous integration system.
While the library should be fully formatted according to the styles, additional elements of the style guide were not followed when the library was initially created. All new code should follow the guidelines. If you are looking for some easy ramp-up tasks, finding areas that don't follow the style guide and fixing them is very welcome.
### Math documentation
When writing math expressions in documentation, use https://www.unicodeit.net/ to convert LaTeX to a Unicode equivalent that's easier to read. Not all expressions will translate (e.g., superscripts of superscripts) so focus on making it readable by someone who isn't familiar with LaTeX. If content on multiple lines needs to be aligned in Doxygen/Javadoc comments (e.g., integration/summation limits, matrices packed with square brackets and superscripts for them), put them in @verbatim/@endverbatim blocks in Doxygen or `<pre>` tags in Javadoc so they render with monospace font.
The LaTeX to Unicode conversions can also be done locally via the unicodeit Python package. To install it, execute:
```bash
pip install --user unicodeit
```
Here's example usage:
```bash
$ python -m unicodeit.cli 'x_{k+1} = Ax_k + Bu_k'
xₖ₊₁ = Axₖ + Buₖ
```
On Linux, this process can be streamlined further by adding the following Bash function to your .bashrc (requires `wl-clipboard` on Wayland or `xclip` on X11):
```bash
# Converts LaTeX to Unicode, prints the result, and copies it to the clipboard
uc() {
if [ $WAYLAND_DISPLAY ]; then
python -m unicodeit.cli $@ | tee >(wl-copy -n)
else
python -m unicodeit.cli $@ | tee >(xclip -sel)
fi
}
```
Here's example usage:
```bash
$ uc 'x_{k+1} = Ax_k + Bu_k'
xₖ₊₁ = Axₖ + Buₖ
```
## Submitting Changes
### Pull Request Format
Changes should be submitted as a Pull Request against the master branch of WPILib. For most changes, commits will be squashed upon merge. For particularly large changes, multiple commits are ok, but assume one commit unless asked otherwise. We may ask you to break a PR into multiple standalone PRs or commits for rebase within one PR to separate unrelated changes. No change will be merged unless it is up to date with the current master. We do this to make sure that the git history isn't too cluttered.
Changes should be submitted as a Pull Request against the main branch of WPILib. For most changes, commits will be squashed upon merge. For particularly large changes, multiple commits are ok, but assume one commit unless asked otherwise. We may ask you to break a PR into multiple standalone PRs or commits for rebase within one PR to separate unrelated changes. No change will be merged unless it is up to date with the current main branch. We do this to make sure that the git history isn't too cluttered.
### Merge Process

98
DevelopmentBuilds.md Normal file
View File

@@ -0,0 +1,98 @@
# Installing Development Builds
This article contains instructions on building projects using a development build and a local WPILib build.
**Note:** This only applies to Java/C++ teams.
## Development Build
Development builds are the per-commit build hosted every time a commit is pushed to the [allwpilib](https://github.com/wpilibsuite/allwpilib/) repository. These builds are then hosted on [artifactory](https://frcmaven.wpi.edu/artifactory/webapp/#/home).
To build a project using a development build, find the build.gradle file and open it. Then, add the following code below the plugin section and replace YEAR with the year of the development version. It is also necessary to use a 2023 GradleRIO version, ie `2023.0.0-alpha-1`
```groovy
wpi.maven.useLocal = false
wpi.maven.useDevelopment = true
wpi.versions.wpilibVersion = 'YEAR.+'
wpi.versions.wpimathVersion = 'YEAR.+
```
The top of your ``build.gradle`` file should now look similar to the code below. Ignore any differences in versions.
Java
```groovy
plugins {
id "java"
id "edu.wpi.first.GradleRIO" version "2023.0.0-alpha-1"
}
wpi.maven.useLocal = false
wpi.maven.useDevelopment = true
wpi.versions.wpilibVersion = '2023.+'
wpi.versions.wpimathVersion = '2023.+'
```
C++
```groovy
plugins {
id "cpp"
id "google-test-test-suite"
id "edu.wpi.first.GradleRIO" version "2023.0.0-alpha-1"
}
wpi.maven.useLocal = false
wpi.maven.useDevelopment = true
wpi.versions.wpilibVersion = '2023.+'
wpi.versions.wpimathVersion = '2023.+'
```
### Development Build Documentation
* C++: https://github.wpilib.org/allwpilib/docs/development/cpp/
* Java: https://github.wpilib.org/allwpilib/docs/development/java/
## Local Build
Building with a local build is very similar to building with a development build. Ensure you have built and published WPILib by following the instructions attached [here](https://github.com/wpilibsuite/allwpilib#building-wpilib). Next, find the ``build.gradle`` file in your robot project and open it. Then, add the following code below the plugin section and replace ``YEAR`` with the year of the local version.
Java
```groovy
plugins {
id "java"
id "edu.wpi.first.GradleRIO" version "2023.0.0-alpha-1"
}
wpi.maven.useLocal = false
wpi.maven.useFrcMavenLocalDevelopment = true
wpi.versions.wpilibVersion = 'YEAR.424242.+'
wpi.versions.wpimathVersion = 'YEAR.424242.+'
```
C++
```groovy
plugins {
id "cpp"
id "google-test-test-suite"
id "edu.wpi.first.GradleRIO" version "2023.0.0-alpha-1"
}
wpi.maven.useLocal = false
wpi.maven.useFrcMavenLocalDevelopment = true
wpi.versions.wpilibVersion = 'YEAR.424242.+'
wpi.versions.wpimathVersion = 'YEAR.424242.+'
```
# roboRIO Development
This repo contains a myRobot project built in way to do full project development without needing to do a full publish into GradleRIO. These also only require building the minimum amount of binaries for the roboRIO, so the builds are much faster as well.
The setup only works if the roboRIO is USB connected. If an alternate IP address is preferred, the `address` block in myRobot\build.gradle can be changed to point to another address.
The following 3 tasks can be used for deployment:
* `:myRobot:deployShared` deploys the C++ project using shared dependencies. Prefer this one for most C++ development.
* `:myRobot:deployStatic` deploys the C++ project with all dependencies statically linked.
* `:myRobot:deployJava` deploys the Java project and all required dependencies. Also installs the JRE if not currently installed.
Deploying any of these to the roboRIO will disable the current startup project until it is redeployed.
From here, ssh into the roboRIO using the `lvuser` account and run `frcRunRobot.sh` (It's in path).

View File

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

View File

@@ -11,10 +11,10 @@ For Java dependencies, there is likely a file related to the specific dependency
Note, changing artifact locations (This includes changing the artifact year currently, I have an issue open to change this) requires updating the `native-utils` plugin
## Publishing allwpilib
allwpilib publishes to the development repo on every push to master. To publish a release build, upload a new tag, and a release will automatically be built and published.
allwpilib publishes to the development repo on every push to main. To publish a release build, upload a new tag, and a release will automatically be built and published.
## Publishing desktop tools
Desktop tools publish to the development repo on every push to master. To publish a release build, upload a new tag, and a release will automatically be built and published.
Desktop tools publish to the development repo on every push to main. To publish a release build, upload a new tag, and a release will automatically be built and published.
## Publishing VS Code
Before publishing, make sure to update the gradlerio version in `vscode-wpilib/resources/gradle/version.txt` Also make sure the gradle wrapper version matches the wrapper required by gradlerio.

View File

@@ -9,7 +9,7 @@ We provide two repositories. These repositories are:
* (Development) https://frcmaven.wpi.edu/artifactory/development/
The release repository is where official WPILib releases are pushed.
The development repository is where development releases of every commit to [master](https://github.com/wpilibsuite/allwpilib/tree/master) is pushed.
The development repository is where development releases of every commit to [main](https://github.com/wpilibsuite/allwpilib/tree/main) is pushed.
## Artifact classifiers
We provide two base types of artifacts.
@@ -69,24 +69,53 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
* wpiutil
* hal
* wpigui
* imgui
* wpimath
* wpiutil
* halsim
* imgui
* wpinet
* wpiutil
* ntcore
* wpiutil
* wpinet
* glass/libglass
* wpiutil
* wpimath
* wpigui
* glass/libglassnt
* wpiutil
* wpinet
* ntcore
* wpimath
* wpigui
* hal
* wpiutil
* halsim
* wpiutil
* wpinet
* ntcore
* wpimath
* wpigui
* libglass
* libglassnt
* cscore
* opencv
* wpinet
* wpiutil
* cameraserver
* ntcore
* cscore
* opencv
* wpinet
* wpiutil
* wpilibj
@@ -94,6 +123,7 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
* cameraserver
* ntcore
* cscore
* wpinet
* wpiutil
* wpilibc
@@ -101,6 +131,8 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
* cameraserver
* ntcore
* cscore
* wpimath
* wpinet
* wpiutil
* wpilibNewCommands
@@ -109,15 +141,10 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
* cameraserver
* ntcore
* cscore
* wpimath
* wpinet
* wpiutil
* wpilibNewCommands
* wpilibc
* hal
* cameraserver
* ntcore
* cscore
* wpiutil
### Third Party Artifacts
@@ -128,3 +155,4 @@ All artifacts are based at `edu.wpi.first.thirdparty.frcYEAR` in the repository.
* googletest
* imgui
* opencv
* libssh

View File

@@ -1,73 +0,0 @@
# Installing Development Builds
This article contains instructions on building projects using a development build and a local WPILib build.
**Note:** This only applies to Java/C++ teams.
## Development Build
Development builds are the per-commit build hosted everytime a commit is pushed to the [allwpilib](https://github.com/wpilibsuite/allwpilib/) repository. These builds are then hosted on [artifactory](https://frcmaven.wpi.edu/artifactory/webapp/#/home).
In order to build a project using a development build, find the build.gradle file and open it. Then, add the following code below the plugin section and replace YEAR with the year of the development version.
```groovy
wpi.maven.useDevelopment = true
wpi.wpilibVersion = 'YEAR.+'
wpi.wpimathVersion = 'YEAR.+
```
The top of your ``build.gradle`` file should now look similar to the code below. Ignore any differences in versions.
Java
```groovy
plugins {
id "java"
id "edu.wpi.first.GradleRIO" version "2020.3.2"
}
wpi.maven.useDevelopment = true
wpi.wpilibVersion = '2021.+'
wpi.wpimathVersion = '2021.+'
```
C++
```groovy
plugins {
id "cpp"
id "google-test-test-suite"
id "edu.wpi.first.GradleRIO" version "2020.3.2"
}
wpi.maven.useDevelopment = true
wpi.wpilibVersion = '2021.+'
wpi.wpimathVersion = '2021.+'
```
## Local Build
Building with a local build is very similar to building with a development build. Ensure you have built and published WPILib by following the instructions attached [here](https://github.com/wpilibsuite/allwpilib#building-wpilib). Next, find the ``build.gradle`` file in your robot project and open it. Then, add the following code below the plugin section and replace ``YEAR`` with the year of the local version.
Java
```groovy
plugins {
id "java"
id "edu.wpi.first.GradleRIO" version "2020.3.2"
}
wpi.maven.useFrcMavenLocalDevelopment = true
wpi.wpilibVersion = 'YEAR.424242.+'
wpi.wpimathVersion = 'YEAR.424242.+'
```
C++
```groovy
plugins {
id "cpp"
id "google-test-test-suite"
id "edu.wpi.first.GradleRIO" version "2020.3.2"
}
wpi.maven.useFrcMavenLocalDevelopment = true
wpi.wpilibVersion = 'YEAR.424242.+'
wpi.wpimathVersion = 'YEAR.424242.+'
```

View File

@@ -31,14 +31,20 @@ The following build options are available:
* This option will enable Java and JNI builds. If this is on, `WITH_SHARED_LIBS` must be on. Otherwise CMake will error.
* `WITH_SHARED_LIBS` (ON Default)
* This option will cause cmake to build static libraries instead of shared libraries. If this is off, `WITH_JAVA` must be off. Otherwise CMake will error.
* `WITH_TESTS` (ON Default)
* This option will build C++ unit tests. These can be run via `make test`.
* `WITH_CSCORE` (ON Default)
* This option will cause cscore to be built. Turning this off will implicitly disable cameraserver, the hal and wpilib as well, irrespective of their specific options. If this is off, the OpenCV build requirement is removed.
* `WITH_NTCORE` (ON Default)
* This option will cause ntcore to be built. Turning this off will implicitly disable wpinet and wpilib as well, irrespective of their specific options.
* `WITH_WPIMATH` (ON Default)
* This option will build the wpimath library. This option must be on to build wpilib.
* `WITH_WPILIB` (ON Default)
* This option will build the hal and wpilibc/j during the build. The HAL is the simulator hal, unless the external hal options are used. The cmake build has no capability to build for the RoboRIO.
* `WITH_EXAMPLES` (ON Default)
* This option will build C++ examples.
* `WITH_TESTS` (ON Default)
* This option will build C++ unit tests. These can be run via `make test`.
* `WITH_GUI` (ON Default)
* This option will build GUI items.
* `WITH_SIMULATION_MODULES` (ON Default)
* This option will build simulation modules, including wpigui and the HALSim plugins.
* `WITH_EXTERNAL_HAL` (OFF Default)

View File

@@ -1,8 +1,8 @@
# WPILib Project
![CI](https://github.com/wpilibsuite/allwpilib/workflows/CI/badge.svg)
[![C++ Documentation](https://img.shields.io/badge/documentation-c%2B%2B-blue)](https://first.wpi.edu/wpilib/allwpilib/docs/development/cpp/)
[![Java Documentation](https://img.shields.io/badge/documentation-java-orange)](https://first.wpi.edu/wpilib/allwpilib/docs/development/java/)
[![Gradle](https://github.com/wpilibsuite/allwpilib/actions/workflows/gradle.yml/badge.svg?branch=main)](https://github.com/wpilibsuite/allwpilib/actions/workflows/gradle.yml)
[![C++ Documentation](https://img.shields.io/badge/documentation-c%2B%2B-blue)](https://github.wpilib.org/allwpilib/docs/development/cpp/)
[![Java Documentation](https://img.shields.io/badge/documentation-java-orange)](https://github.wpilib.org/allwpilib/docs/development/java/)
Welcome to the WPILib project. This repository contains the HAL, WPILibJ, and WPILibC projects. These are the core libraries for creating robot programs for the roboRIO.
@@ -15,8 +15,7 @@ Welcome to the WPILib project. This repository contains the HAL, WPILibJ, and WP
- [Faster builds](#faster-builds)
- [Using Development Builds](#using-development-builds)
- [Custom toolchain location](#custom-toolchain-location)
- [Gazebo simulation](#gazebo-simulation)
- [Formatting/linting with wpiformat](#formattinglinting-with-wpiformat)
- [Formatting/Linting](#formattinglinting)
- [CMake](#cmake)
- [Publishing](#publishing)
- [Structure and Organization](#structure-and-organization)
@@ -26,32 +25,43 @@ Welcome to the WPILib project. This repository contains the HAL, WPILibJ, and WP
The WPILib Mission is to enable FIRST Robotics teams to focus on writing game-specific software rather than focusing on hardware details - "raise the floor, don't lower the ceiling". We work to enable teams with limited programming knowledge and/or mentor experience to be as successful as possible, while not hampering the abilities of teams with more advanced programming capabilities. We support Kit of Parts control system components directly in the library. We also strive to keep parity between major features of each language (Java, C++, and NI's LabVIEW), so that teams aren't at a disadvantage for choosing a specific programming language. WPILib is an open source project, licensed under the BSD 3-clause license. You can find a copy of the license [here](LICENSE.md).
# Quick Start
Below is a list of instructions that guide you through cloning, building, publishing and using local allwpilib binaries in a robot project. This quick start is not intended as a replacement for the information further listed in this document.
1. Clone the repository with `git clone https://github.com/wpilibsuite/allwpilib.git`
2. Build the repository with `./gradlew build` or `./gradlew build --build-cache` if you have an internet connection
3. Publish the artifacts locally by running `./gradlew publish`
4. [Update your](DevelopmentBuilds.md) `build.gradle` [to use the artifacts](DevelopmentBuilds.md)
# Building WPILib
Using Gradle makes building WPILib very straightforward. It only has a few dependencies on outside tools, such as the ARM cross compiler for creating roboRIO binaries.
## 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
- On macOS, install the JDK 11 .pkg from the link above
- C++ compiler
- On Linux, install GCC 7 or greater
- On Windows, install [Visual Studio Community 2019](https://visualstudio.microsoft.com/vs/community/) and select the C++ programming language during installation (Gradle can't use the build tools for Visual Studio 2019)
- On macOS, install the Xcode command-line build tools via `xcode-select --install`
- On Linux, install GCC 11 or greater
- On Windows, install [Visual Studio Community 2022](https://visualstudio.microsoft.com/vs/community/) and select the C++ programming language during installation (Gradle can't use the build tools for Visual Studio)
- On macOS, install the Xcode command-line build tools via `xcode-select --install`. Xcode 13 or later is required.
- ARM compiler toolchain
- Run `./gradlew installRoboRioToolchain` after cloning this repository
- If the WPILib installer was used, this toolchain is already installed
- Raspberry Pi toolchain (optional)
- Run `./gradlew installRaspbianToolchain` after cloning this repository
- Run `./gradlew installArm32Toolchain` after cloning this repository
On macOS ARM, run `softwareupdate --install-rosetta`. This is necessary to be able to use the macOS x86 roboRIO toolchain on ARM.
## Setup
Clone the WPILib repository and follow the instructions above for installing any required tooling.
See the [styleguide README](https://github.com/wpilibsuite/styleguide/blob/master/README.md) for wpiformat setup instructions.
See the [styleguide README](https://github.com/wpilibsuite/styleguide/blob/main/README.md) for wpiformat setup instructions. We use clang-format 14.
## Building
@@ -71,19 +81,29 @@ The gradlew wrapper only exists in the root of the main project, so be sure to r
There are a few tasks other than `build` available. To see them, run the meta-task `tasks`. This will print a list of all available tasks, with a description of each task.
If opening from a fresh clone, generated java dependencies will not exist. Most IDEs will not run the generation tasks, which will cause lots of IDE errors. Manually run `./gradlew compileJava` from a terminal to run all the compile tasks, and then refresh your IDE's configuration (In VS Code open settings.gradle and save).
### Faster builds
`./gradlew build` builds _everything_, which includes debug and release builds for desktop and all installed cross compilers. Many developers don't need or want to build all of this. Therefore, common tasks have shortcuts to only build necessary components for common development and testing tasks.
`./gradlew testDesktopCpp` and `./gradlew testDesktopJava` will build and run the tests for `wpilibc` and `wpilibj` respectively. They will only build the minimum components required to run the tests.
`testDesktopCpp` and `testDesktopJava` tasks also exist for the projects `wpiutil`, `ntcore`, `cscore`, `hal` `wpilibOldCommands`, `wpilibNewCommands` and `cameraserver`. These can be ran with `./gradlew :projectName:task`.
`testDesktopCpp` and `testDesktopJava` tasks also exist for the projects `wpiutil`, `ntcore`, `cscore`, `hal` `wpilibNewCommands` and `cameraserver`. These can be ran with `./gradlew :projectName:task`.
`./gradlew buildDesktopCpp` and `./gradlew buildDesktopJava` will compile `wpilibcExamples` and `wpilibjExamples` respectively. The results can't be ran, but they can compile.
### Build Cache
Run with `--build-cache` on the command-line to use the shared [build cache](https://docs.gradle.org/current/userguide/build_cache.html) artifacts generated by the continuous integration server. Example:
```bash
./gradlew build --build-cache
```
### Using Development Builds
Please read the documentation available [here](OtherVersions.md)
Please read the documentation available [here](DevelopmentBuilds.md)
### Custom toolchain location
@@ -93,34 +113,19 @@ If you have installed the FRC Toolchain to a directory other than the default, o
./gradlew build -PtoolChainPath=some/path/to/frc/toolchain/bin
```
### Gazebo simulation
If you also want simulation to be built, add -PmakeSim. This requires gazebo_transport. We have tested on 14.04 and 15.05, but any correct install of Gazebo should work, even on Windows if you build Gazebo from source. Correct means CMake needs to be able to find gazebo-config.cmake. See [The Gazebo website](https://gazebosim.org/) for installation instructions.
```bash
./gradlew build -PmakeSim
```
If you prefer to use CMake directly, the you can still do so.
The common CMake tasks are wpilibcSim, frc_gazebo_plugins, and gz_msgs
```bash
mkdir build #run this in the root of allwpilib
cd build
cmake ..
make
```
### Formatting/linting
Once a PR has been submitted, formatting can be run in CI by commenting `/format` on the PR. A new commit will be pushed with the formatting changes.
#### wpiformat
wpiformat can be executed anywhere in the repository via `py -3 -m wpiformat` on Windows or `python3 -m wpiformat` on other platforms.
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.
#### Java Code Quality Tools
The Java code quality tools (checkstyle, pmd, etc.) can be run with the `./gradlew javaFormat` task.
The Java code quality tools Checkstyle, PMD, and Spotless can be run via `./gradlew javaFormat`. SpotBugs can be run via the `spotbugsMain`, `spotbugsTest`, and `spotbugsDev` tasks. These tools will all be run automatically by the `build` task. To disable this behavior, pass the `-PskipJavaFormat` flag.
If you only want to run the Java autoformatter, run `./gradlew spotlessApply`.
### CMake
@@ -139,13 +144,13 @@ The maven artifacts are described in [MavenArtifacts.md](MavenArtifacts.md)
## Structure and Organization
The main WPILib code you're probably looking for is in WPILibJ and WPILibC. Those directories are split into shared, sim, and athena. Athena contains the WPILib code meant to run on your roboRIO. Sim is WPILib code meant to run on your computer with Gazebo, and shared is code shared between the two. Shared code must be platform-independent, since it will be compiled with both the ARM cross-compiler and whatever desktop compiler you are using (g++, msvc, etc...).
The Simulation directory contains extra simulation tools and libraries, such as gz_msgs and JavaGazebo. See sub-directories for more information.
The main WPILib code you're probably looking for is in WPILibJ and WPILibC. Those directories are split into shared, sim, and athena. Athena contains the WPILib code meant to run on your roboRIO. Sim is WPILib code meant to run on your computer, and shared is code shared between the two. Shared code must be platform-independent, since it will be compiled with both the ARM cross-compiler and whatever desktop compiler you are using (g++, msvc, etc...).
The integration test directories for C++ and Java contain test code that runs on our test-system. When you submit code for review, it is tested by those programs. If you add new functionality you should make sure to write tests for it so we don't break it in the future.
The hal directory contains more C++ code meant to run on the roboRIO. HAL is an acronym for "Hardware Abstraction Layer", and it interfaces with the NI Libraries. The NI Libraries contain the low-level code for controlling devices on your robot. The NI Libraries are found in the ni-libraries folder.
The hal directory contains more C++ code meant to run on the roboRIO. HAL is an acronym for "Hardware Abstraction Layer", and it interfaces with the NI Libraries. The NI Libraries contain the low-level code for controlling devices on your robot. The NI Libraries are found in the [ni-libraries](https://github.com/wpilibsuite/ni-libraries) project.
The upstream_utils directory contains scripts for updating copies of thirdparty code in the repository.
The [styleguide repository](https://github.com/wpilibsuite/styleguide) contains our style guides for C++ and Java code. Anything submitted to the WPILib project needs to follow the code style guides outlined in there. For details about the style, please see the contributors document [here](CONTRIBUTING.md#coding-guidelines).

View File

@@ -17,38 +17,35 @@ Program Locations
------- ---------
RoboRIO Libraries ni-libraries
Google Test gtest
LLVM wpiutil/src/main/native/include/wpi/{various files}
wpiutil/src/main/native/cpp/llvm/
wpiutil/src/main/native/cpp/leb128.cpp
wpiutil/src/test/native/cpp/leb128Test.cpp
JSON for Modern C++ wpiutil/src/main/native/include/wpi/json.h
wpiutil/src/main/native/cpp/json_*.cpp
LLVM wpiutil/src/main/native/thirdparty/llvm
wpiutil/src/test/native/cpp/llvm/
JSON for Modern C++ wpiutil/src/main/native/thirdparty/json
wpiutil/src/test/native/cpp/json/
libuv wpiutil/src/main/native/include/uv.h
wpiutil/src/main/native/include/uv/
wpiutil/src/main/native/libuv/
sigslot wpiutil/src/main/native/include/wpi/Signal.h
wpiutil/src/test/native/cpp/sigslot/
tcpsockets wpiutil/src/main/native/cpp/TCP{Stream,Connector,Acceptor}.cpp
wpiutil/src/main/native/include/wpi/TCP*.h
Bootstrap wpiutil/src/main/native/resources/bootstrap-*
CoreUI wpiutil/src/main/native/resources/coreui-*
Feather Icons wpiutil/src/main/native/resources/feather-*
jQuery wpiutil/src/main/native/resources/jquery-*
popper.js wpiutil/src/main/native/resources/popper-*
libuv wpinet/src/main/native/thirdparty/libuv/
fmtlib wpiutil/src/main/native/thirdparty/fmtlib/
sigslot wpiutil/src/main/native/thirdparty/sigslot
tcpsockets wpinet/src/main/native/thirdparty/tcpsockets
MPack wpiutil/src/main/native/thirdparty/mpack
Bootstrap wpinet/src/main/native/resources/bootstrap-*
CoreUI wpinet/src/main/native/resources/coreui-*
Feather Icons wpinet/src/main/native/resources/feather-*
jQuery wpinet/src/main/native/resources/jquery-*
popper.js wpinet/src/main/native/resources/popper-*
units wpimath/src/main/native/include/units/
Eigen wpimath/src/main/native/eigeninclude/
wpimath/src/main/native/include/unsupported/
Eigen wpimath/src/main/native/thirdparty/eigen/include/
StackWalker wpiutil/src/main/native/windows/StackWalker.*
GHC filesystem wpiutil/src/main/native/thirdparty/include/wpi/ghc/
Team 254 Library wpilibj/src/main/java/edu/wpi/first/wpilibj/spline/SplineParameterizer.java
wpilibj/src/main/java/edu/wpi/first/wpilibj/trajectory/TrajectoryParameterizer.java
wpilibc/src/main/native/include/spline/SplineParameterizer.h
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/cpp/drake/common/drake_assert_and_throw.cpp
wpimath/src/main/native/cpp/drake/math/discrete_algebraic_riccati_equation.cpp
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/
==============================================================================
Google Test License
@@ -84,12 +81,247 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
==============================================================================
LLVM Release License
The LLVM Project is under the Apache License v2.0 with LLVM Exceptions:
==============================================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
---- LLVM Exceptions to the Apache 2.0 License ----
As an exception, if, as a result of your compiling your source code, portions
of this Software are embedded into an Object form of such source code, you
may redistribute such embedded portions in such Object form without complying
with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
In addition, if you combine or link compiled forms of this Software with
software that is licensed under the GPLv2 ("Combined Software") and if a
court of competent jurisdiction determines that the patent provision (Section
3), the indemnity provision (Section 9) or other Section of the License
conflicts with the conditions of the GPLv2, you may retroactively and
prospectively choose to deem waived or otherwise exclude such Section(s) of
the License, but only in their entirety and only with respect to the Combined
Software.
==============================================================================
Software from third parties included in the LLVM Project:
==============================================================================
The LLVM Project contains third party software which is under different license
terms. All such code will be identified clearly using at least one of two
mechanisms:
1) It will be in a separate directory tree with its own `LICENSE.txt` or
`LICENSE` file at the top containing the specific license and restrictions
which apply to that software, or
2) It will contain specific license and restriction terms at the top of every
file.
==============================================================================
Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy):
==============================================================================
University of Illinois/NCSA
Open Source License
Copyright (c) 2003-2017 University of Illinois at Urbana-Champaign.
Copyright (c) 2003-2019 University of Illinois at Urbana-Champaign.
All rights reserved.
Developed by:
@@ -231,6 +463,32 @@ See the License for the specific language governing permissions and
limitations under the License.
==============================================================================
MPacks License
==============================================================================
The MIT License (MIT)
Copyright (c) 2015-2021 Nicholas Fraser and the MPack authors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
==============================================================================
Bootstrap License
==============================================================================
@@ -856,3 +1114,131 @@ the extent permitted by applicable law. You can redistribute it
and/or modify it under the terms of the Do What the **** You Want
to Public License, Version 2, as published by the WTFPL Task Force.
See http://www.wtfpl.net/ for more details.
======================
Boost Software License
======================
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
======
fmtlib
======
Copyright (c) 2012 - present, Victor Zverovich
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--- Optional exception to the license ---
As an exception, if, as a result of your compiling your source code, portions
of this Software are embedded into a machine-executable object form of such
source code, you may redistribute such embedded portions in such object form
without including the above copyright and permission notices.
==============
GHC filesystem
==============
Copyright (c) 2018, Steffen Schümann <s.schuemann@pobox.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
==================
V8 export-template
==================
Copyright 2014, the V8 project authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
============
GCEM License
============
Copyright 2022 - ktholer (https://github.com/kthohr/gcem)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

118
apriltag/CMakeLists.txt Normal file
View File

@@ -0,0 +1,118 @@
project(apriltag)
include(CompileWarnings)
include(GenResources)
include(FetchContent)
FetchContent_Declare(
apriltaglib
GIT_REPOSITORY https://github.com/wpilibsuite/apriltag.git
GIT_TAG ad31e33d20f9782b7239cb15cde57c56c91383ad
)
# Don't use apriltag's CMakeLists.txt due to conflicting naming and JNI
FetchContent_GetProperties(apriltaglib)
if(NOT apriltaglib_POPULATED)
FetchContent_Populate(apriltaglib)
endif()
aux_source_directory(${apriltaglib_SOURCE_DIR}/common APRILTAGLIB_COMMON_SRC)
file(GLOB TAG_FILES ${apriltaglib_SOURCE_DIR}/tag*.c)
set(APRILTAGLIB_SRCS ${apriltaglib_SOURCE_DIR}/apriltag.c ${apriltaglib_SOURCE_DIR}/apriltag_pose.c ${apriltaglib_SOURCE_DIR}/apriltag_quad_thresh.c)
file(GLOB apriltag_jni_src src/main/native/cpp/jni/AprilTagJNI.cpp)
if (WITH_JAVA)
find_package(Java REQUIRED)
find_package(JNI REQUIRED)
include(UseJava)
set(CMAKE_JAVA_COMPILE_FLAGS "-encoding" "UTF8" "-Xlint:unchecked")
set(CMAKE_JNI_TARGET true)
file(GLOB EJML_JARS "${WPILIB_BINARY_DIR}/wpimath/thirdparty/ejml/*.jar")
file(GLOB JACKSON_JARS "${WPILIB_BINARY_DIR}/wpiutil/thirdparty/jackson/*.jar")
find_file(OPENCV_JAR_FILE
NAMES opencv-${OpenCV_VERSION_MAJOR}${OpenCV_VERSION_MINOR}${OpenCV_VERSION_PATCH}.jar
PATHS ${OPENCV_JAVA_INSTALL_DIR} ${OpenCV_INSTALL_PATH}/bin ${OpenCV_INSTALL_PATH}/share/java
NO_DEFAULT_PATH)
set(CMAKE_JAVA_INCLUDE_PATH apriltag.jar ${EJML_JARS} ${JACKSON_JARS})
file(GLOB_RECURSE JAVA_SOURCES src/main/java/*.java)
file(GLOB_RECURSE JAVA_RESOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} src/main/native/resources/*.json)
add_jar(apriltag_jar
SOURCES ${JAVA_SOURCES}
RESOURCES NAMESPACE "edu/wpi/first/apriltag" ${JAVA_RESOURCES}
INCLUDE_JARS wpimath_jar ${EJML_JARS} wpiutil_jar ${OPENCV_JAR_FILE}
OUTPUT_NAME apriltag
GENERATE_NATIVE_HEADERS apriltag_jni_headers)
get_property(APRILTAG_JAR_FILE TARGET apriltag_jar PROPERTY JAR_FILE)
install(FILES ${APRILTAG_JAR_FILE} DESTINATION "${java_lib_dest}")
set_property(TARGET apriltag_jar PROPERTY FOLDER "java")
add_library(apriltagjni ${apriltag_jni_src})
wpilib_target_warnings(apriltagjni)
target_link_libraries(apriltagjni PUBLIC apriltag)
set_property(TARGET apriltagjni PROPERTY FOLDER "libraries")
target_link_libraries(apriltagjni PRIVATE apriltag_jni_headers)
add_dependencies(apriltagjni apriltag_jar)
if (MSVC)
install(TARGETS apriltagjni RUNTIME DESTINATION "${jni_lib_dest}" COMPONENT Runtime)
endif()
install(TARGETS apriltagjni EXPORT apriltagjni DESTINATION "${main_lib_dest}")
endif()
GENERATE_RESOURCES(src/main/native/resources/edu/wpi/first/apriltag generated/main/cpp APRILTAG frc apriltag_resources_src)
file(GLOB apriltag_native_src src/main/native/cpp/*.cpp)
add_library(apriltag ${apriltag_native_src} ${apriltag_resources_src} ${APRILTAGLIB_SRCS} ${APRILTAGLIB_COMMON_SRC} ${TAG_FILES})
set_target_properties(apriltag PROPERTIES DEBUG_POSTFIX "d")
set_property(TARGET apriltag PROPERTY FOLDER "libraries")
target_compile_features(apriltag PUBLIC cxx_std_20)
wpilib_target_warnings(apriltag)
# disable warnings that apriltaglib can't handle
if (MSVC)
target_compile_options(apriltag PRIVATE /wd4018)
else()
target_compile_options(apriltag PRIVATE -Wno-sign-compare -Wno-gnu-zero-variadic-macro-arguments)
endif()
target_link_libraries(apriltag wpimath)
target_include_directories(apriltag PUBLIC
$<BUILD_INTERFACE:${apriltaglib_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/main/native/include>
$<INSTALL_INTERFACE:${include_dest}/apriltag>)
install(TARGETS apriltag EXPORT apriltag DESTINATION "${main_lib_dest}")
install(DIRECTORY src/main/native/include/ DESTINATION "${include_dest}/apriltag")
if (WITH_JAVA AND MSVC)
install(TARGETS apriltag RUNTIME DESTINATION "${jni_lib_dest}" COMPONENT Runtime)
endif()
if (WITH_FLAT_INSTALL)
set (apriltag_config_dir ${wpilib_dest})
else()
set (apriltag_config_dir share/apriltag)
endif()
configure_file(apriltag-config.cmake.in ${WPILIB_BINARY_DIR}/apriltag-config.cmake )
install(FILES ${WPILIB_BINARY_DIR}/apriltag-config.cmake DESTINATION ${apriltag_config_dir})
install(EXPORT apriltag DESTINATION ${apriltag_config_dir})
if (WITH_TESTS)
wpilib_add_test(apriltag src/test/native/cpp)
target_include_directories(apriltag_test PRIVATE src/test/native/include)
target_link_libraries(apriltag_test apriltag gmock_main)
endif()

View File

@@ -0,0 +1,7 @@
include(CMakeFindDependencyMacro)
@FILENAME_DEP_REPLACE@
@WPIMATH_DEP_REPLACE@
@WPIUTIL_DEP_REPLACE@
@FILENAME_DEP_REPLACE@
include(${SELF_DIR}/apriltag.cmake)

88
apriltag/build.gradle Normal file
View File

@@ -0,0 +1,88 @@
apply from: "${rootDir}/shared/resources.gradle"
ext {
nativeName = 'apriltag'
devMain = 'edu.wpi.first.apriltag.DevMain'
useJava = true
useCpp = true
sharedCvConfigs = [
apriltagDev : [],
apriltagTest: []]
staticCvConfigs = []
def generateTask = createGenerateResourcesTask('main', 'APRILTAG', 'frc', project)
tasks.withType(CppCompile) {
dependsOn generateTask
}
splitSetup = {
it.sources {
resourcesCpp(CppSourceSet) {
source {
srcDirs "$buildDir/generated/main/cpp", "$rootDir/shared/singlelib"
include '*.cpp'
}
}
}
}
}
evaluationDependsOn(':wpimath')
apply from: "${rootDir}/shared/jni/setupBuild.gradle"
apply from: "${rootDir}/shared/apriltaglib.gradle"
apply from: "${rootDir}/shared/opencv.gradle"
dependencies {
implementation project(':wpimath')
devImplementation project(':wpimath')
}
sourceSets {
main {
resources {
srcDirs 'src/main/native/resources'
}
}
}
model {
components {}
binaries {
all {
if (!it.buildable || !(it instanceof NativeBinarySpec)) {
return
}
it.cppCompiler.define 'WPILIB_EXPORTS'
if (it.component.name == "${nativeName}JNI") {
lib project: ':wpimath', library: 'wpimath', linkage: 'static'
lib project: ':wpiutil', library: 'wpiutil', linkage: 'static'
} else {
lib project: ':wpimath', library: 'wpimath', linkage: 'shared'
lib project: ':wpiutil', library: 'wpiutil', linkage: 'shared'
}
nativeUtils.useRequiredLibrary(it, 'apriltaglib')
}
}
tasks {
def c = $.components
def found = false
def systemArch = getCurrentArch()
c.each {
if (it in NativeExecutableSpec && it.name == "${nativeName}Dev") {
it.binaries.each {
if (!found) {
def arch = it.targetPlatform.name
if (arch == systemArch) {
def filePath = it.tasks.install.installDirectory.get().toString() + File.separatorChar + 'lib'
found = true
}
}
}
}
}
}
}

View File

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

View File

@@ -0,0 +1,11 @@
// 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 "frc/apriltag/AprilTagDetector.h"
int main() {
frc::AprilTagDetector detector;
detector.AddFamily("tag16h5");
detector.SetConfig({.refineEdges = false});
}

View File

@@ -0,0 +1,47 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.apriltag;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import edu.wpi.first.math.geometry.Pose3d;
import java.util.Objects;
@SuppressWarnings("MemberName")
public class AprilTag {
@JsonProperty(value = "ID")
public int ID;
@JsonProperty(value = "pose")
public Pose3d pose;
@SuppressWarnings("ParameterName")
@JsonCreator
public AprilTag(
@JsonProperty(required = true, value = "ID") int ID,
@JsonProperty(required = true, value = "pose") Pose3d pose) {
this.ID = ID;
this.pose = pose;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof AprilTag) {
var other = (AprilTag) obj;
return ID == other.ID && pose.equals(other.pose);
}
return false;
}
@Override
public int hashCode() {
return Objects.hash(ID, pose);
}
@Override
public String toString() {
return "AprilTag(ID: " + ID + ", pose: " + pose + ")";
}
}

View File

@@ -0,0 +1,190 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.apriltag;
import edu.wpi.first.math.MatBuilder;
import edu.wpi.first.math.Matrix;
import edu.wpi.first.math.Nat;
import edu.wpi.first.math.numbers.N3;
import java.util.Arrays;
/** A detection of an AprilTag tag. */
public class AprilTagDetection {
/**
* Gets the decoded tag's family name.
*
* @return Decoded family name
*/
public String getFamily() {
return m_family;
}
/**
* Gets the decoded ID of the tag.
*
* @return Decoded ID
*/
public int getId() {
return m_id;
}
/**
* Gets how many error bits were corrected. Note: accepting large numbers of corrected errors
* leads to greatly increased false positive rates. NOTE: As of this implementation, the detector
* cannot detect tags with a hamming distance greater than 2.
*
* @return Hamming distance (number of corrected error bits)
*/
public int getHamming() {
return m_hamming;
}
/**
* Gets a measure of the quality of the binary decoding process: the average difference between
* the intensity of a data bit versus the decision threshold. Higher numbers roughly indicate
* better decodes. This is a reasonable measure of detection accuracy only for very small tags--
* not effective for larger tags (where we could have sampled anywhere within a bit cell and still
* gotten a good detection.)
*
* @return Decision margin
*/
public float getDecisionMargin() {
return m_decisionMargin;
}
/**
* Gets the 3x3 homography matrix describing the projection from an "ideal" tag (with corners at
* (-1,1), (1,1), (1,-1), and (-1, -1)) to pixels in the image.
*
* @return Homography matrix data
*/
@SuppressWarnings("PMD.MethodReturnsInternalArray")
public double[] getHomography() {
return m_homography;
}
/**
* Gets the 3x3 homography matrix describing the projection from an "ideal" tag (with corners at
* (-1,1), (1,1), (1,-1), and (-1, -1)) to pixels in the image.
*
* @return Homography matrix
*/
public Matrix<N3, N3> getHomographyMatrix() {
return new MatBuilder<>(Nat.N3(), Nat.N3()).fill(m_homography);
}
/**
* Gets the center of the detection in image pixel coordinates.
*
* @return Center point X coordinate
*/
public double getCenterX() {
return m_centerX;
}
/**
* Gets the center of the detection in image pixel coordinates.
*
* @return Center point Y coordinate
*/
public double getCenterY() {
return m_centerY;
}
/**
* Gets a corner of the tag in image pixel coordinates. These always wrap counter-clock wise
* around the tag.
*
* @param ndx Corner index (range is 0-3, inclusive)
* @return Corner point X coordinate
*/
public double getCornerX(int ndx) {
return m_corners[ndx * 2];
}
/**
* Gets a corner of the tag in image pixel coordinates. These always wrap counter-clock wise
* around the tag.
*
* @param ndx Corner index (range is 0-3, inclusive)
* @return Corner point Y coordinate
*/
public double getCornerY(int ndx) {
return m_corners[ndx * 2 + 1];
}
/**
* Gets the corners of the tag in image pixel coordinates. These always wrap counter-clock wise
* around the tag.
*
* @return Corner point array (X and Y for each corner in order)
*/
@SuppressWarnings("PMD.MethodReturnsInternalArray")
public double[] getCorners() {
return m_corners;
}
private final String m_family;
private final int m_id;
private final int m_hamming;
private final float m_decisionMargin;
private final double[] m_homography;
private final double m_centerX;
private final double m_centerY;
private final double[] m_corners;
/**
* Constructs a new detection result. Used from JNI.
*
* @param family family
* @param id id
* @param hamming hamming
* @param decisionMargin dm
* @param homography homography
* @param centerX centerX
* @param centerY centerY
* @param corners corners
*/
@SuppressWarnings("PMD.ArrayIsStoredDirectly")
public AprilTagDetection(
String family,
int id,
int hamming,
float decisionMargin,
double[] homography,
double centerX,
double centerY,
double[] corners) {
m_family = family;
m_id = id;
m_hamming = hamming;
m_decisionMargin = decisionMargin;
m_homography = homography;
m_centerX = centerX;
m_centerY = centerY;
m_corners = corners;
}
@Override
public String toString() {
return "DetectionResult [centerX="
+ m_centerX
+ ", centerY="
+ m_centerY
+ ", corners="
+ Arrays.toString(m_corners)
+ ", decisionMargin="
+ m_decisionMargin
+ ", hamming="
+ m_hamming
+ ", homography="
+ Arrays.toString(m_homography)
+ ", family="
+ m_family
+ ", id="
+ m_id
+ "]";
}
}

View File

@@ -0,0 +1,281 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.apriltag;
import edu.wpi.first.apriltag.jni.AprilTagJNI;
import org.opencv.core.Mat;
/**
* An AprilTag detector engine. This is expensive to set up and tear down, so most use cases should
* only create one of these, add a family to it, set up any other configuration, and repeatedly call
* Detect().
*/
public class AprilTagDetector implements AutoCloseable {
/** Detector configuration. */
@SuppressWarnings("MemberName")
public static class Config {
/**
* How many threads should be used for computation. Default is single-threaded operation (1
* thread).
*/
public int numThreads = 1;
/**
* Quad decimation. Detection of quads can be done on a lower-resolution image, improving speed
* at a cost of pose accuracy and a slight decrease in detection rate. Decoding the binary
* payload is still done at full resolution. Default is 2.0.
*/
public float quadDecimate = 2.0f;
/**
* What Gaussian blur should be applied to the segmented image (used for quad detection). Very
* noisy images benefit from non-zero values (e.g. 0.8). Default is 0.0.
*/
public float quadSigma;
/**
* When true, the edges of the each quad are adjusted to "snap to" strong gradients nearby. This
* is useful when decimation is employed, as it can increase the quality of the initial quad
* estimate substantially. Generally recommended to be on (true). Default is true.
*
* <p>Very computationally inexpensive. Option is ignored if quad_decimate = 1.
*/
public boolean refineEdges = true;
/**
* How much sharpening should be done to decoded images. This can help decode small tags but may
* or may not help in odd lighting conditions or low light conditions. Default is 0.25.
*/
public double decodeSharpening = 0.25;
/**
* Debug mode. When true, the decoder writes a variety of debugging images to the current
* working directory at various stages through the detection process. This is slow and should
* *not* be used on space-limited systems such as the RoboRIO. Default is disabled (false).
*/
public boolean debug;
public Config() {}
Config(
int numThreads,
float quadDecimate,
float quadSigma,
boolean refineEdges,
double decodeSharpening,
boolean debug) {
this.numThreads = numThreads;
this.quadDecimate = quadDecimate;
this.quadSigma = quadSigma;
this.refineEdges = refineEdges;
this.decodeSharpening = decodeSharpening;
this.debug = debug;
}
@Override
public int hashCode() {
return numThreads
+ Float.hashCode(quadDecimate)
+ Float.hashCode(quadSigma)
+ Boolean.hashCode(refineEdges)
+ Double.hashCode(decodeSharpening)
+ Boolean.hashCode(debug);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Config)) {
return false;
}
Config other = (Config) obj;
return numThreads == other.numThreads
&& quadDecimate == other.quadDecimate
&& quadSigma == other.quadSigma
&& refineEdges == other.refineEdges
&& decodeSharpening == other.decodeSharpening
&& debug == other.debug;
}
}
/** Quad threshold parameters. */
@SuppressWarnings("MemberName")
public static class QuadThresholdParameters {
/** Threshold used to reject quads containing too few pixels. Default is 5 pixels. */
public int minClusterPixels = 5;
/**
* How many corner candidates to consider when segmenting a group of pixels into a quad. Default
* is 10.
*/
public int maxNumMaxima = 10;
/**
* Critical angle, in radians. The detector will reject quads where pairs of edges have angles
* that are close to straight or close to 180 degrees. Zero means that no quads are rejected.
* Default is 10 degrees.
*/
public double criticalAngle = 10 * Math.PI / 180.0;
/**
* When fitting lines to the contours, the maximum mean squared error allowed. This is useful in
* rejecting contours that are far from being quad shaped; rejecting these quads "early" saves
* expensive decoding processing. Default is 10.0.
*/
public float maxLineFitMSE = 10.0f;
/**
* Minimum brightness offset. When we build our model of black &amp; white pixels, we add an
* extra check that the white model must be (overall) brighter than the black model. How much
* brighter? (in pixel values, [0,255]). Default is 5.
*/
public int minWhiteBlackDiff = 5;
/**
* Whether the thresholded image be should be deglitched. Only useful for very noisy images.
* Default is disabled (false).
*/
public boolean deglitch;
public QuadThresholdParameters() {}
QuadThresholdParameters(
int minClusterPixels,
int maxNumMaxima,
double criticalAngle,
float maxLineFitMSE,
int minWhiteBlackDiff,
boolean deglitch) {
this.minClusterPixels = minClusterPixels;
this.maxNumMaxima = maxNumMaxima;
this.criticalAngle = criticalAngle;
this.maxLineFitMSE = maxLineFitMSE;
this.minWhiteBlackDiff = minWhiteBlackDiff;
this.deglitch = deglitch;
}
@Override
public int hashCode() {
return minClusterPixels
+ maxNumMaxima
+ Double.hashCode(criticalAngle)
+ Float.hashCode(maxLineFitMSE)
+ minWhiteBlackDiff
+ Boolean.hashCode(deglitch);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof QuadThresholdParameters)) {
return false;
}
QuadThresholdParameters other = (QuadThresholdParameters) obj;
return minClusterPixels == other.minClusterPixels
&& maxNumMaxima == other.maxNumMaxima
&& criticalAngle == other.criticalAngle
&& maxLineFitMSE == other.maxLineFitMSE
&& minWhiteBlackDiff == other.minWhiteBlackDiff
&& deglitch == other.deglitch;
}
}
public AprilTagDetector() {
m_native = AprilTagJNI.createDetector();
}
@Override
public void close() {
if (m_native != 0) {
AprilTagJNI.destroyDetector(m_native);
}
m_native = 0;
}
/**
* Sets detector configuration.
*
* @param config Configuration
*/
public void setConfig(Config config) {
AprilTagJNI.setDetectorConfig(m_native, config);
}
/**
* Gets detector configuration.
*
* @return Configuration
*/
public Config getConfig() {
return AprilTagJNI.getDetectorConfig(m_native);
}
/**
* Sets quad threshold parameters.
*
* @param params Parameters
*/
public void setQuadThresholdParameters(QuadThresholdParameters params) {
AprilTagJNI.setDetectorQTP(m_native, params);
}
/**
* Gets quad threshold parameters.
*
* @return Parameters
*/
public QuadThresholdParameters getQuadThresholdParameters() {
return AprilTagJNI.getDetectorQTP(m_native);
}
/**
* Adds a family of tags to be detected.
*
* @param fam Family name, e.g. "tag16h5"
* @throws IllegalArgumentException if family name not recognized
*/
public void addFamily(String fam) {
addFamily(fam, 2);
}
/**
* Adds a family of tags to be detected.
*
* @param fam Family name, e.g. "tag16h5"
* @param bitsCorrected maximum number of bits to correct
* @throws IllegalArgumentException if family name not recognized
*/
public void addFamily(String fam, int bitsCorrected) {
if (!AprilTagJNI.addFamily(m_native, fam, bitsCorrected)) {
throw new IllegalArgumentException("unknown family name '" + fam + "'");
}
}
/**
* Removes a family of tags from the detector.
*
* @param fam Family name, e.g. "tag16h5"
*/
public void removeFamily(String fam) {
AprilTagJNI.removeFamily(m_native, fam);
}
/** Unregister all families. */
public void clearFamilies() {
AprilTagJNI.clearFamilies(m_native);
}
/**
* Detect tags from an 8-bit image.
*
* @param img 8-bit OpenCV Mat image
* @return Results (array of AprilTagDetection)
*/
public AprilTagDetection[] detect(Mat img) {
return AprilTagJNI.detect(m_native, img.cols(), img.rows(), img.cols(), img.dataAddr());
}
private long m_native;
}

View File

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

View File

@@ -0,0 +1,33 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.apriltag;
import java.io.IOException;
public enum AprilTagFields {
k2022RapidReact("2022-rapidreact.json"),
k2023ChargedUp("2023-chargedup.json");
public static final String kBaseResourceDir = "/edu/wpi/first/apriltag/";
/** Alias to the current game. */
public static final AprilTagFields kDefaultField = k2023ChargedUp;
public final String m_resourceFile;
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

@@ -0,0 +1,55 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.apriltag;
import edu.wpi.first.math.geometry.Transform3d;
/** A pair of AprilTag pose estimates. */
@SuppressWarnings("MemberName")
public class AprilTagPoseEstimate {
/**
* Constructs a pose estimate.
*
* @param pose1 first pose
* @param pose2 second pose
* @param error1 error of first pose
* @param error2 error of second pose
*/
public AprilTagPoseEstimate(Transform3d pose1, Transform3d pose2, double error1, double error2) {
this.pose1 = pose1;
this.pose2 = pose2;
this.error1 = error1;
this.error2 = error2;
}
/**
* Get the ratio of pose reprojection errors, called ambiguity. Numbers above 0.2 are likely to be
* ambiguous.
*
* @return The ratio of pose reprojection errors.
*/
public double getAmbiguity() {
double min = Math.min(error1, error2);
double max = Math.max(error1, error2);
if (max > 0) {
return min / max;
} else {
return -1;
}
}
/** Pose 1. */
public final Transform3d pose1;
/** Pose 2. */
public final Transform3d pose2;
/** Object-space error of pose 1. */
public final double error1;
/** Object-space error of pose 2. */
public final double error2;
}

View File

@@ -0,0 +1,190 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.apriltag;
import edu.wpi.first.apriltag.jni.AprilTagJNI;
import edu.wpi.first.math.geometry.Transform3d;
/** Pose estimators for AprilTag tags. */
public class AprilTagPoseEstimator {
/** Configuration for the pose estimator. */
@SuppressWarnings("MemberName")
public static class Config {
/**
* Creates a pose estimator configuration.
*
* @param tagSize tag size, in meters
* @param fx camera horizontal focal length, in pixels
* @param fy camera vertical focal length, in pixels
* @param cx camera horizontal focal center, in pixels
* @param cy camera vertical focal center, in pixels
*/
public Config(double tagSize, double fx, double fy, double cx, double cy) {
this.tagSize = tagSize;
this.fx = fx;
this.fy = fy;
this.cx = cx;
this.cy = cy;
}
public double tagSize;
public double fx;
public double fy;
public double cx;
public double cy;
@Override
public int hashCode() {
return Double.hashCode(tagSize)
+ Double.hashCode(fx)
+ Double.hashCode(fy)
+ Double.hashCode(cx)
+ Double.hashCode(cy);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Config)) {
return false;
}
Config other = (Config) obj;
return tagSize == other.tagSize
&& fx == other.fx
&& fy == other.fy
&& cx == other.cx
&& cy == other.cy;
}
}
/**
* Creates estimator.
*
* @param config Configuration
*/
public AprilTagPoseEstimator(Config config) {
m_config = new Config(config.tagSize, config.fx, config.fy, config.cx, config.cy);
}
/**
* Sets estimator configuration.
*
* @param config Configuration
*/
public void setConfig(Config config) {
m_config.tagSize = config.tagSize;
m_config.fx = config.fx;
m_config.fy = config.fy;
m_config.cx = config.cx;
m_config.cy = config.cy;
}
/**
* Gets estimator configuration.
*
* @return Configuration
*/
public Config getConfig() {
return new Config(m_config.tagSize, m_config.fx, m_config.fy, m_config.cx, m_config.cy);
}
/**
* Estimates the pose of the tag using the homography method described in [1].
*
* @param detection Tag detection
* @return Pose estimate
*/
public Transform3d estimateHomography(AprilTagDetection detection) {
return estimateHomography(detection.getHomography());
}
/**
* Estimates the pose of the tag using the homography method described in [1].
*
* @param homography Homography 3x3 matrix data
* @return Pose estimate
*/
public Transform3d estimateHomography(double[] homography) {
return AprilTagJNI.estimatePoseHomography(
homography, m_config.tagSize, m_config.fx, m_config.fy, m_config.cx, m_config.cy);
}
/**
* Estimates the pose of the tag. This returns one or two possible poses for the tag, along with
* the object-space error of each.
*
* <p>This uses the homography method described in [1] for the initial estimate. Then Orthogonal
* Iteration [2] is used to refine this estimate. Then [3] is used to find a potential second
* local minima and Orthogonal Iteration is used to refine this second estimate.
*
* <p>[1]: E. Olson, “Apriltag: A robust and flexible visual fiducial system,” in 2011 IEEE
* International Conference on Robotics and Automation, May 2011, pp. 34003407.
*
* <p>[2]: Lu, G. D. Hager and E. Mjolsness, "Fast and globally convergent pose estimation from
* video images," in IEEE Transactions on Pattern Analysis and Machine Intelligence, vol. 22, no.
* 6, pp. 610-622, June 2000. doi: 10.1109/34.862199
*
* <p>[3]: Schweighofer and A. Pinz, "Robust Pose Estimation from a Planar Target," in IEEE
* Transactions on Pattern Analysis and Machine Intelligence, vol. 28, no. 12, pp. 2024-2030, Dec.
* 2006. doi: 10.1109/TPAMI.2006.252
*
* @param detection Tag detection
* @param nIters Number of iterations
* @return Initial and (possibly) second pose estimates
*/
public AprilTagPoseEstimate estimateOrthogonalIteration(AprilTagDetection detection, int nIters) {
return estimateOrthogonalIteration(detection.getHomography(), detection.getCorners(), nIters);
}
/**
* Estimates the pose of the tag. This returns one or two possible poses for the tag, along with
* the object-space error of each.
*
* @param homography Homography 3x3 matrix data
* @param corners Corner point array (X and Y for each corner in order)
* @param nIters Number of iterations
* @return Initial and (possibly) second pose estimates
*/
public AprilTagPoseEstimate estimateOrthogonalIteration(
double[] homography, double[] corners, int nIters) {
return AprilTagJNI.estimatePoseOrthogonalIteration(
homography,
corners,
m_config.tagSize,
m_config.fx,
m_config.fy,
m_config.cx,
m_config.cy,
nIters);
}
/**
* Estimates tag pose. This method is an easier to use interface to
* EstimatePoseOrthogonalIteration(), running 50 iterations and returning the pose with the lower
* object-space error.
*
* @param detection Tag detection
* @return Pose estimate
*/
public Transform3d estimate(AprilTagDetection detection) {
return estimate(detection.getHomography(), detection.getCorners());
}
/**
* Estimates tag pose. This method is an easier to use interface to
* EstimatePoseOrthogonalIteration(), running 50 iterations and returning the pose with the lower
* object-space error.
*
* @param homography Homography 3x3 matrix data
* @param corners Corner point array (X and Y for each corner in order)
* @return Pose estimate
*/
public Transform3d estimate(double[] homography, double[] corners) {
return AprilTagJNI.estimatePose(
homography, corners, m_config.tagSize, m_config.fx, m_config.fy, m_config.cx, m_config.cy);
}
private final Config m_config;
}

View File

@@ -0,0 +1,90 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.apriltag.jni;
import edu.wpi.first.apriltag.AprilTagDetection;
import edu.wpi.first.apriltag.AprilTagDetector;
import edu.wpi.first.apriltag.AprilTagPoseEstimate;
import edu.wpi.first.math.geometry.Transform3d;
import edu.wpi.first.util.RuntimeLoader;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicBoolean;
public class AprilTagJNI {
static boolean libraryLoaded = false;
static RuntimeLoader<AprilTagJNI> loader = null;
public static class Helper {
private static AtomicBoolean extractOnStaticLoad = new AtomicBoolean(true);
public static boolean getExtractOnStaticLoad() {
return extractOnStaticLoad.get();
}
public static void setExtractOnStaticLoad(boolean load) {
extractOnStaticLoad.set(load);
}
}
static {
if (Helper.getExtractOnStaticLoad()) {
try {
loader =
new RuntimeLoader<>(
"apriltagjni", RuntimeLoader.getDefaultExtractionRoot(), AprilTagJNI.class);
loader.loadLibrary();
} catch (IOException ex) {
ex.printStackTrace();
System.exit(1);
}
libraryLoaded = true;
}
}
public static native long createDetector();
public static native void destroyDetector(long det);
public static native void setDetectorConfig(long det, AprilTagDetector.Config config);
public static native AprilTagDetector.Config getDetectorConfig(long det);
public static native void setDetectorQTP(
long det, AprilTagDetector.QuadThresholdParameters params);
public static native AprilTagDetector.QuadThresholdParameters getDetectorQTP(long det);
public static native boolean addFamily(long det, String fam, int bitsCorrected);
public static native void removeFamily(long det, String fam);
public static native void clearFamilies(long det);
public static native AprilTagDetection[] detect(
long det, int width, int height, int stride, long bufAddr);
public static native Transform3d estimatePoseHomography(
double[] homography, double tagSize, double fx, double fy, double cx, double cy);
public static native AprilTagPoseEstimate estimatePoseOrthogonalIteration(
double[] homography,
double[] corners,
double tagSize,
double fx,
double fy,
double cx,
double cy,
int nIters);
public static native Transform3d estimatePose(
double[] homography,
double[] corners,
double tagSize,
double fx,
double fy,
double cx,
double cy);
}

View File

@@ -0,0 +1,18 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include "frc/apriltag/AprilTag.h"
#include <wpi/json.h>
using namespace frc;
void frc::to_json(wpi::json& json, const AprilTag& apriltag) {
json = wpi::json{{"ID", apriltag.ID}, {"pose", apriltag.pose}};
}
void frc::from_json(const wpi::json& json, AprilTag& apriltag) {
apriltag.ID = json.at("ID").get<int>();
apriltag.pose = json.at("pose").get<Pose3d>();
}

View File

@@ -0,0 +1,37 @@
// 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 "frc/apriltag/AprilTagDetection.h"
#include <type_traits>
#ifdef _WIN32
#pragma warning(disable : 4200)
#elif defined(__clang__)
#pragma clang diagnostic ignored "-Wc99-extensions"
#elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
#include "apriltag.h"
using namespace frc;
static_assert(sizeof(AprilTagDetection) == sizeof(apriltag_detection_t),
"structure sizes don't match");
static_assert(std::is_standard_layout_v<AprilTagDetection>,
"AprilTagDetection is not standard layout?");
std::string_view AprilTagDetection::GetFamily() const {
return static_cast<const apriltag_family_t*>(family)->name;
}
std::span<const double, 9> AprilTagDetection::GetHomography() const {
return std::span<const double, 9>{static_cast<matd_t*>(H)->data, 9};
}
Eigen::Matrix3d AprilTagDetection::GetHomographyMatrix() const {
return Eigen::Map<Eigen::Matrix<double, 3, 3, Eigen::RowMajor>>{
static_cast<matd_t*>(H)->data};
}

View File

@@ -0,0 +1,200 @@
// 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 "frc/apriltag/AprilTagDetector.h"
#include <cmath>
#include <numbers>
#ifdef _WIN32
#pragma warning(disable : 4200)
#elif defined(__clang__)
#pragma clang diagnostic ignored "-Wc99-extensions"
#elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
#include "apriltag.h"
#include "tag16h5.h"
#include "tag25h9.h"
#include "tag36h11.h"
#include "tagCircle21h7.h"
#include "tagCircle49h12.h"
#include "tagCustom48h12.h"
#include "tagStandard41h12.h"
#include "tagStandard52h13.h"
using namespace frc;
AprilTagDetector::Results::Results(void* impl, const private_init&)
: span{reinterpret_cast<AprilTagDetection**>(
static_cast<zarray_t*>(impl)->data),
static_cast<size_t>(static_cast<zarray_t*>(impl)->size)},
m_impl{impl} {}
AprilTagDetector::Results& AprilTagDetector::Results::operator=(Results&& rhs) {
Destroy();
m_impl = rhs.m_impl;
rhs.m_impl = nullptr;
return *this;
}
void AprilTagDetector::Results::Destroy() {
if (m_impl) {
apriltag_detections_destroy(static_cast<zarray_t*>(m_impl));
}
}
AprilTagDetector::AprilTagDetector() : m_impl{apriltag_detector_create()} {}
AprilTagDetector& AprilTagDetector::operator=(AprilTagDetector&& rhs) {
Destroy();
m_impl = rhs.m_impl;
rhs.m_impl = nullptr;
m_families = std::move(rhs.m_families);
rhs.m_families.clear();
m_qtpCriticalAngle = rhs.m_qtpCriticalAngle;
return *this;
}
void AprilTagDetector::SetConfig(const Config& config) {
auto& impl = *static_cast<apriltag_detector_t*>(m_impl);
impl.nthreads = config.numThreads;
impl.quad_decimate = config.quadDecimate;
impl.quad_sigma = config.quadSigma;
impl.refine_edges = config.refineEdges;
impl.decode_sharpening = config.decodeSharpening;
impl.debug = config.debug;
}
AprilTagDetector::Config AprilTagDetector::GetConfig() const {
auto& impl = *static_cast<apriltag_detector_t*>(m_impl);
return {
.numThreads = impl.nthreads,
.quadDecimate = impl.quad_decimate,
.quadSigma = impl.quad_sigma,
.refineEdges = impl.refine_edges,
.decodeSharpening = impl.decode_sharpening,
.debug = impl.debug,
};
}
void AprilTagDetector::SetQuadThresholdParameters(
const QuadThresholdParameters& params) {
auto& qtp = static_cast<apriltag_detector_t*>(m_impl)->qtp;
qtp.min_cluster_pixels = params.minClusterPixels;
qtp.max_nmaxima = params.maxNumMaxima;
qtp.critical_rad = params.criticalAngle.value();
qtp.cos_critical_rad = std::cos(params.criticalAngle.value());
qtp.max_line_fit_mse = params.maxLineFitMSE;
qtp.min_white_black_diff = params.minWhiteBlackDiff;
qtp.deglitch = params.deglitch;
m_qtpCriticalAngle = params.criticalAngle;
}
AprilTagDetector::QuadThresholdParameters
AprilTagDetector::GetQuadThresholdParameters() const {
auto& qtp = static_cast<apriltag_detector_t*>(m_impl)->qtp;
return {
.minClusterPixels = qtp.min_cluster_pixels,
.maxNumMaxima = qtp.max_nmaxima,
.criticalAngle = m_qtpCriticalAngle,
.maxLineFitMSE = qtp.max_line_fit_mse,
.minWhiteBlackDiff = qtp.min_white_black_diff,
.deglitch = qtp.deglitch != 0,
};
}
bool AprilTagDetector::AddFamily(std::string_view fam, int bitsCorrected) {
auto& data = m_families[fam];
if (data) {
return true; // already detecting
}
// create the family
if (fam == "tag16h5") {
data = tag16h5_create();
} else if (fam == "tag25h9") {
data = tag25h9_create();
} else if (fam == "tag36h11") {
data = tag36h11_create();
} else if (fam == "tagCircle21h7") {
data = tagCircle21h7_create();
} else if (fam == "tagCircle49h12") {
data = tagCircle49h12_create();
} else if (fam == "tagStandard41h12") {
data = tagStandard41h12_create();
} else if (fam == "tagStandard52h13") {
data = tagStandard52h13_create();
} else if (fam == "tagCustom48h12") {
data = tagCustom48h12_create();
}
if (!data) {
m_families.erase(fam); // don't keep null value
return false; // can't add
}
apriltag_detector_add_family_bits(static_cast<apriltag_detector_t*>(m_impl),
static_cast<apriltag_family_t*>(data),
bitsCorrected);
return true;
}
void AprilTagDetector::RemoveFamily(std::string_view fam) {
auto it = m_families.find(fam);
if (it != m_families.end()) {
apriltag_detector_remove_family(
static_cast<apriltag_detector_t*>(m_impl),
static_cast<apriltag_family_t*>(it->second));
DestroyFamily(it->getKey(), it->second);
m_families.erase(it);
}
}
void AprilTagDetector::ClearFamilies() {
apriltag_detector_clear_families(static_cast<apriltag_detector_t*>(m_impl));
DestroyFamilies();
m_families.clear();
}
AprilTagDetector::Results AprilTagDetector::Detect(int width, int height,
int stride, uint8_t* buf) {
image_u8_t img{width, height, stride, buf};
return {
apriltag_detector_detect(static_cast<apriltag_detector_t*>(m_impl), &img),
Results::private_init{}};
}
void AprilTagDetector::Destroy() {
if (m_impl) {
apriltag_detector_destroy(static_cast<apriltag_detector_t*>(m_impl));
}
DestroyFamilies();
}
void AprilTagDetector::DestroyFamilies() {
for (auto&& entry : m_families) {
DestroyFamily(entry.getKey(), entry.second);
}
}
void AprilTagDetector::DestroyFamily(std::string_view name, void* data) {
auto fam = static_cast<apriltag_family_t*>(data);
if (name == "tag16h5") {
tag16h5_destroy(fam);
} else if (name == "tag25h9") {
tag25h9_destroy(fam);
} else if (name == "tag36h11") {
tag36h11_destroy(fam);
} else if (name == "tagCircle21h7") {
tagCircle21h7_destroy(fam);
} else if (name == "tagCircle49h12") {
tagCircle49h12_destroy(fam);
} else if (name == "tagStandard41h12") {
tagStandard41h12_destroy(fam);
} else if (name == "tagStandard52h13") {
tagStandard52h13_destroy(fam);
} else if (name == "tagCustom48h12") {
tagCustom48h12_destroy(fam);
}
}

View File

@@ -0,0 +1,107 @@
// 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 "frc/apriltag/AprilTagFieldLayout.h"
#include <system_error>
#include <units/angle.h>
#include <units/length.h>
#include <wpi/json.h>
#include <wpi/raw_istream.h>
#include <wpi/raw_ostream.h>
using namespace frc;
AprilTagFieldLayout::AprilTagFieldLayout(std::string_view path) {
std::error_code error_code;
wpi::raw_fd_istream input{path, error_code};
if (error_code) {
throw std::runtime_error(fmt::format("Cannot open file: {}", path));
}
wpi::json json;
input >> json;
for (const auto& tag : json.at("tags").get<std::vector<AprilTag>>()) {
m_apriltags[tag.ID] = tag;
}
m_fieldWidth = units::meter_t{json.at("field").at("width").get<double>()};
m_fieldLength = units::meter_t{json.at("field").at("length").get<double>()};
}
AprilTagFieldLayout::AprilTagFieldLayout(std::vector<AprilTag> apriltags,
units::meter_t fieldLength,
units::meter_t fieldWidth)
: m_fieldLength(std::move(fieldLength)),
m_fieldWidth(std::move(fieldWidth)) {
for (const auto& tag : apriltags) {
m_apriltags[tag.ID] = tag;
}
}
void AprilTagFieldLayout::SetOrigin(OriginPosition origin) {
switch (origin) {
case OriginPosition::kBlueAllianceWallRightSide:
SetOrigin(Pose3d{});
break;
case OriginPosition::kRedAllianceWallRightSide:
SetOrigin(Pose3d{Translation3d{m_fieldLength, m_fieldWidth, 0_m},
Rotation3d{0_deg, 0_deg, 180_deg}});
break;
default:
throw std::invalid_argument("Invalid origin");
}
}
void AprilTagFieldLayout::SetOrigin(const Pose3d& origin) {
m_origin = origin;
}
std::optional<frc::Pose3d> AprilTagFieldLayout::GetTagPose(int ID) const {
const auto& it = m_apriltags.find(ID);
if (it == m_apriltags.end()) {
return std::nullopt;
}
return it->second.pose.RelativeTo(m_origin);
}
void AprilTagFieldLayout::Serialize(std::string_view path) {
std::error_code error_code;
wpi::raw_fd_ostream output{path, error_code};
if (error_code) {
throw std::runtime_error(fmt::format("Cannot open file: {}", path));
}
wpi::json json = *this;
output << json;
output.flush();
}
void frc::to_json(wpi::json& json, const AprilTagFieldLayout& layout) {
std::vector<AprilTag> tagVector;
tagVector.reserve(layout.m_apriltags.size());
for (const auto& pair : layout.m_apriltags) {
tagVector.push_back(pair.second);
}
json = wpi::json{{"field",
{{"length", layout.m_fieldLength.value()},
{"width", layout.m_fieldWidth.value()}}},
{"tags", tagVector}};
}
void frc::from_json(const wpi::json& json, AprilTagFieldLayout& layout) {
layout.m_apriltags.clear();
for (const auto& tag : json.at("tags").get<std::vector<AprilTag>>()) {
layout.m_apriltags[tag.ID] = tag;
}
layout.m_fieldLength =
units::meter_t{json.at("field").at("length").get<double>()};
layout.m_fieldWidth =
units::meter_t{json.at("field").at("width").get<double>()};
}

View File

@@ -0,0 +1,32 @@
// 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 "frc/apriltag/AprilTagFields.h"
#include <wpi/json.h>
namespace frc {
// C++ generated from resource files
std::string_view GetResource_2022_rapidreact_json();
std::string_view GetResource_2023_chargedup_json();
AprilTagFieldLayout LoadAprilTagLayoutField(AprilTagField field) {
std::string_view fieldString;
switch (field) {
case AprilTagField::k2022RapidReact:
fieldString = GetResource_2022_rapidreact_json();
break;
case AprilTagField::k2023ChargedUp:
fieldString = GetResource_2023_chargedup_json();
break;
case AprilTagField::kNumFields:
throw std::invalid_argument("Invalid Field");
}
wpi::json json = wpi::json::parse(fieldString);
return json.get<AprilTagFieldLayout>();
}
} // namespace frc

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.
#include "frc/apriltag/AprilTagPoseEstimate.h"
#include <algorithm>
using namespace frc;
double AprilTagPoseEstimate::GetAmbiguity() const {
auto min = (std::min)(error1, error2);
auto max = (std::max)(error1, error2);
if (max > 0) {
return min / max;
} else {
return -1;
}
}

View File

@@ -0,0 +1,154 @@
// 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 "frc/apriltag/AprilTagPoseEstimator.h"
#include <Eigen/QR>
#include "frc/apriltag/AprilTagDetection.h"
#ifdef _WIN32
#pragma warning(disable : 4200)
#elif defined(__clang__)
#pragma clang diagnostic ignored "-Wc99-extensions"
#elif defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wpedantic"
#endif
#include "apriltag.h"
#include "apriltag_pose.h"
using namespace frc;
static Eigen::Matrix3d OrthogonalizeRotationMatrix(
const Eigen::Matrix3d& input) {
Eigen::HouseholderQR<Eigen::Matrix3d> qr{input};
Eigen::Matrix3d Q = qr.householderQ();
Eigen::Matrix3d R = qr.matrixQR().triangularView<Eigen::Upper>();
// Fix signs in R if they're < 0 so it's close to an identity matrix
// (our QR decomposition implementation sometimes flips the signs of
// columns)
for (int colR = 0; colR < 3; ++colR) {
if (R(colR, colR) < 0) {
for (int rowQ = 0; rowQ < 3; ++rowQ) {
Q(rowQ, colR) = -Q(rowQ, colR);
}
}
}
return Q;
}
static Transform3d MakePose(const apriltag_pose_t& pose) {
if (!pose.R || !pose.t) {
return {};
}
return {Translation3d{units::meter_t{pose.t->data[0]},
units::meter_t{pose.t->data[1]},
units::meter_t{pose.t->data[2]}},
Rotation3d{OrthogonalizeRotationMatrix(
Eigen::Map<Eigen::Matrix<double, 3, 3, Eigen::RowMajor>>{
pose.R->data})}};
}
static apriltag_detection_info_t MakeDetectionInfo(
const apriltag_detection_t* det,
const AprilTagPoseEstimator::Config& config) {
return {const_cast<apriltag_detection_t*>(det),
config.tagSize.value(),
config.fx,
config.fy,
config.cx,
config.cy};
}
static apriltag_detection_t MakeBasicDet(
std::span<const double, 9> homography,
const std::span<const double, 8>* corners) {
apriltag_detection_t detection;
detection.H = matd_create(3, 3);
std::memcpy(detection.H->data, homography.data(), 9 * sizeof(double));
if (corners) {
for (int i = 0; i < 4; i++) {
detection.p[i][0] = (*corners)[i * 2];
detection.p[i][1] = (*corners)[i * 2 + 1];
}
}
return detection;
}
static Transform3d DoEstimateHomography(
const apriltag_detection_t* detection,
const AprilTagPoseEstimator::Config& config) {
auto info = MakeDetectionInfo(detection, config);
apriltag_pose_t pose;
estimate_pose_for_tag_homography(&info, &pose);
return MakePose(pose);
}
Transform3d AprilTagPoseEstimator::EstimateHomography(
const AprilTagDetection& detection) const {
return DoEstimateHomography(
reinterpret_cast<const apriltag_detection_t*>(&detection), m_config);
}
Transform3d AprilTagPoseEstimator::EstimateHomography(
std::span<const double, 9> homography) const {
auto detection = MakeBasicDet(homography, nullptr);
auto rv = DoEstimateHomography(&detection, m_config);
matd_destroy(detection.H);
return rv;
}
static AprilTagPoseEstimate DoEstimateOrthogonalIteration(
const apriltag_detection_t* detection,
const AprilTagPoseEstimator::Config& config, int nIters) {
auto info = MakeDetectionInfo(detection, config);
apriltag_pose_t pose1, pose2;
double err1, err2;
estimate_tag_pose_orthogonal_iteration(&info, &err1, &pose1, &err2, &pose2,
nIters);
return {MakePose(pose1), MakePose(pose2), err1, err2};
}
AprilTagPoseEstimate AprilTagPoseEstimator::EstimateOrthogonalIteration(
const AprilTagDetection& detection, int nIters) const {
return DoEstimateOrthogonalIteration(
reinterpret_cast<const apriltag_detection_t*>(&detection), m_config,
nIters);
}
AprilTagPoseEstimate AprilTagPoseEstimator::EstimateOrthogonalIteration(
std::span<const double, 9> homography, std::span<const double, 8> corners,
int nIters) const {
auto detection = MakeBasicDet(homography, &corners);
auto rv = DoEstimateOrthogonalIteration(&detection, m_config, nIters);
matd_destroy(detection.H);
return rv;
}
static Transform3d DoEstimate(const apriltag_detection_t* detection,
const AprilTagPoseEstimator::Config& config) {
auto info = MakeDetectionInfo(detection, config);
apriltag_pose_t pose;
estimate_tag_pose(&info, &pose);
return MakePose(pose);
}
Transform3d AprilTagPoseEstimator::Estimate(
const AprilTagDetection& detection) const {
return DoEstimate(reinterpret_cast<const apriltag_detection_t*>(&detection),
m_config);
}
Transform3d AprilTagPoseEstimator::Estimate(
std::span<const double, 9> homography,
std::span<const double, 8> corners) const {
auto detection = MakeBasicDet(homography, &corners);
auto rv = DoEstimate(&detection, m_config);
matd_destroy(detection.H);
return rv;
}

View File

@@ -0,0 +1,595 @@
// 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 <cstdio>
#include <cstring>
#include <wpi/jni_util.h>
#include "edu_wpi_first_apriltag_jni_AprilTagJNI.h"
#include "frc/apriltag/AprilTagDetector.h"
#include "frc/apriltag/AprilTagPoseEstimator.h"
using namespace frc;
using namespace wpi::java;
static JavaVM* jvm = nullptr;
static JClass detectionCls;
static JClass detectorConfigCls;
static JClass detectorQTPCls;
static JClass poseEstimateCls;
static JClass quaternionCls;
static JClass rotation3dCls;
static JClass transform3dCls;
static JClass translation3dCls;
static JException illegalArgEx;
static JException nullPointerEx;
static const JClassInit classes[] = {
{"edu/wpi/first/apriltag/AprilTagDetection", &detectionCls},
{"edu/wpi/first/apriltag/AprilTagDetector$Config", &detectorConfigCls},
{"edu/wpi/first/apriltag/AprilTagDetector$QuadThresholdParameters",
&detectorQTPCls},
{"edu/wpi/first/apriltag/AprilTagPoseEstimate", &poseEstimateCls},
{"edu/wpi/first/math/geometry/Quaternion", &quaternionCls},
{"edu/wpi/first/math/geometry/Rotation3d", &rotation3dCls},
{"edu/wpi/first/math/geometry/Transform3d", &transform3dCls},
{"edu/wpi/first/math/geometry/Translation3d", &translation3dCls}};
static const JExceptionInit exceptions[] = {
{"java/lang/IllegalArgumentException", &illegalArgEx},
{"java/lang/NullPointerException", &nullPointerEx}};
extern "C" {
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
jvm = vm;
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return JNI_ERR;
}
// Cache references to classes
for (auto& c : classes) {
*c.cls = JClass(env, c.name);
if (!*c.cls) {
std::fprintf(stderr, "could not load class %s\n", c.name);
return JNI_ERR;
}
}
for (auto& c : exceptions) {
*c.cls = JException(env, c.name);
if (!*c.cls) {
std::fprintf(stderr, "could not load exception %s\n", c.name);
return JNI_ERR;
}
}
return JNI_VERSION_1_6;
}
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved) {
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return;
}
// Delete global references
for (auto& c : classes) {
c.cls->free(env);
}
for (auto& c : exceptions) {
c.cls->free(env);
}
jvm = nullptr;
}
} // extern "C"
//
// Conversions from Java to C++ objects
//
static AprilTagDetector::Config FromJavaDetectorConfig(JNIEnv* env,
jobject jconfig) {
if (!jconfig) {
return {};
}
#define FIELD(name, sig) \
static jfieldID name##Field = nullptr; \
if (!name##Field) { \
name##Field = env->GetFieldID(detectorConfigCls, #name, sig); \
}
FIELD(numThreads, "I");
FIELD(quadDecimate, "F");
FIELD(quadSigma, "F");
FIELD(refineEdges, "Z");
FIELD(decodeSharpening, "D");
FIELD(debug, "Z");
#undef FIELD
#define FIELD(ctype, jtype, name) \
.name = static_cast<ctype>(env->Get##jtype##Field(jconfig, name##Field))
return {
FIELD(int, Int, numThreads),
FIELD(float, Float, quadDecimate),
FIELD(float, Float, quadSigma),
FIELD(bool, Boolean, refineEdges),
FIELD(double, Double, decodeSharpening),
FIELD(bool, Boolean, debug),
};
#undef GET
#undef FIELD
}
static AprilTagDetector::QuadThresholdParameters FromJavaDetectorQTP(
JNIEnv* env, jobject jparams) {
if (!jparams) {
return {};
}
#define FIELD(name, sig) \
static jfieldID name##Field = nullptr; \
if (!name##Field) { \
name##Field = env->GetFieldID(detectorQTPCls, #name, sig); \
}
FIELD(minClusterPixels, "I");
FIELD(maxNumMaxima, "I");
FIELD(criticalAngle, "D");
FIELD(maxLineFitMSE, "F");
FIELD(minWhiteBlackDiff, "I");
FIELD(deglitch, "Z");
#undef FIELD
#define FIELD(ctype, jtype, name) \
.name = static_cast<ctype>(env->Get##jtype##Field(jparams, name##Field))
return {
FIELD(int, Int, minClusterPixels),
FIELD(int, Int, maxNumMaxima),
.criticalAngle = units::radian_t{static_cast<double>(
env->GetDoubleField(jparams, criticalAngleField))},
FIELD(float, Float, maxLineFitMSE),
FIELD(int, Int, minWhiteBlackDiff),
FIELD(bool, Boolean, deglitch),
};
#undef GET
#undef FIELD
}
//
// Conversions from C++ to Java objects
//
static jobject MakeJObject(JNIEnv* env, const AprilTagDetection& detect) {
static jmethodID constructor = env->GetMethodID(
detectionCls, "<init>", "(Ljava/lang/String;IIF[DDD[D)V");
if (!constructor) {
return nullptr;
}
JLocal<jstring> fam{env, MakeJString(env, detect.GetFamily())};
auto homography = detect.GetHomography();
JLocal<jdoubleArray> harr{
env, MakeJDoubleArray(
env, {reinterpret_cast<const jdouble*>(homography.data()),
homography.size()})};
double cornersBuf[8];
auto corners = detect.GetCorners(cornersBuf);
JLocal<jdoubleArray> carr{
env,
MakeJDoubleArray(env, {reinterpret_cast<const jdouble*>(corners.data()),
corners.size()})};
auto center = detect.GetCenter();
return env->NewObject(detectionCls, constructor, fam.obj(),
static_cast<jint>(detect.GetId()),
static_cast<jint>(detect.GetHamming()),
static_cast<jfloat>(detect.GetDecisionMargin()),
harr.obj(), static_cast<jdouble>(center.x),
static_cast<jdouble>(center.y), carr.obj());
}
static jobjectArray MakeJObject(JNIEnv* env,
std::span<const AprilTagDetection* const> arr) {
jobjectArray jarr = env->NewObjectArray(arr.size(), detectionCls, nullptr);
if (!jarr) {
return nullptr;
}
for (size_t i = 0; i < arr.size(); ++i) {
JLocal<jobject> elem{env, MakeJObject(env, *arr[i])};
env->SetObjectArrayElement(jarr, i, elem.obj());
}
return jarr;
}
static jobject MakeJObject(JNIEnv* env,
const AprilTagDetector::Config& config) {
static jmethodID constructor =
env->GetMethodID(detectorConfigCls, "<init>", "(IFFZDZ)V");
if (!constructor) {
return nullptr;
}
return env->NewObject(detectorConfigCls, constructor,
static_cast<jint>(config.numThreads),
static_cast<jfloat>(config.quadDecimate),
static_cast<jfloat>(config.quadSigma),
static_cast<jboolean>(config.refineEdges),
static_cast<jdouble>(config.decodeSharpening),
static_cast<jboolean>(config.debug));
}
static jobject MakeJObject(
JNIEnv* env, const AprilTagDetector::QuadThresholdParameters& params) {
static jmethodID constructor =
env->GetMethodID(detectorQTPCls, "<init>", "(IIDFIZ)V");
if (!constructor) {
return nullptr;
}
return env->NewObject(detectorQTPCls, constructor,
static_cast<jint>(params.minClusterPixels),
static_cast<jint>(params.maxNumMaxima),
static_cast<jdouble>(params.criticalAngle),
static_cast<jfloat>(params.maxLineFitMSE),
static_cast<jint>(params.minWhiteBlackDiff),
static_cast<jboolean>(params.deglitch));
}
static jobject MakeJObject(JNIEnv* env, const Translation3d& xlate) {
static jmethodID constructor =
env->GetMethodID(translation3dCls, "<init>", "(DDD)V");
if (!constructor) {
return nullptr;
}
return env->NewObject(
translation3dCls, constructor, static_cast<jdouble>(xlate.X()),
static_cast<jdouble>(xlate.Y()), static_cast<jdouble>(xlate.Z()));
}
static jobject MakeJObject(JNIEnv* env, const Quaternion& q) {
static jmethodID constructor =
env->GetMethodID(quaternionCls, "<init>", "(DDDD)V");
if (!constructor) {
return nullptr;
}
return env->NewObject(quaternionCls, constructor, static_cast<jdouble>(q.W()),
static_cast<jdouble>(q.X()),
static_cast<jdouble>(q.Y()),
static_cast<jdouble>(q.Z()));
}
static jobject MakeJObject(JNIEnv* env, const Rotation3d& rot) {
static jmethodID constructor = env->GetMethodID(
rotation3dCls, "<init>", "(Ledu/wpi/first/math/geometry/Quaternion;)V");
if (!constructor) {
return nullptr;
}
JLocal<jobject> q{env, MakeJObject(env, rot.GetQuaternion())};
return env->NewObject(rotation3dCls, constructor, q.obj());
}
static jobject MakeJObject(JNIEnv* env, const Transform3d& xform) {
static jmethodID constructor =
env->GetMethodID(transform3dCls, "<init>",
"(Ledu/wpi/first/math/geometry/Translation3d;"
"Ledu/wpi/first/math/geometry/Rotation3d;)V");
if (!constructor) {
return nullptr;
}
JLocal<jobject> xlate{env, MakeJObject(env, xform.Translation())};
JLocal<jobject> rot{env, MakeJObject(env, xform.Rotation())};
return env->NewObject(transform3dCls, constructor, xlate.obj(), rot.obj());
}
static jobject MakeJObject(JNIEnv* env, const AprilTagPoseEstimate& est) {
static jmethodID constructor =
env->GetMethodID(poseEstimateCls, "<init>",
"(Ledu/wpi/first/math/geometry/Transform3d;"
"Ledu/wpi/first/math/geometry/Transform3d;DD)V");
if (!constructor) {
return nullptr;
}
JLocal<jobject> pose1{env, MakeJObject(env, est.pose1)};
JLocal<jobject> pose2{env, MakeJObject(env, est.pose2)};
return env->NewObject(poseEstimateCls, constructor, pose1.obj(), pose2.obj(),
static_cast<jdouble>(est.error1),
static_cast<jdouble>(est.error2));
}
extern "C" {
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Method: createDetector
* Signature: ()J
*/
JNIEXPORT jlong JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_createDetector
(JNIEnv* env, jclass)
{
return reinterpret_cast<jlong>(new AprilTagDetector);
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Method: destroyDetector
* Signature: (J)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_destroyDetector
(JNIEnv* env, jclass, jlong det)
{
delete reinterpret_cast<AprilTagDetector*>(det);
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Method: setDetectorConfig
* Signature: (JLjava/lang/Object;)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_setDetectorConfig
(JNIEnv* env, jclass, jlong det, jobject config)
{
if (det == 0) {
nullPointerEx.Throw(env, "det cannot be null");
return;
}
reinterpret_cast<AprilTagDetector*>(det)->SetConfig(
FromJavaDetectorConfig(env, config));
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Method: getDetectorConfig
* Signature: (J)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_getDetectorConfig
(JNIEnv* env, jclass, jlong det)
{
if (det == 0) {
nullPointerEx.Throw(env, "det cannot be null");
return nullptr;
}
return MakeJObject(env,
reinterpret_cast<AprilTagDetector*>(det)->GetConfig());
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Method: setDetectorQTP
* Signature: (JLjava/lang/Object;)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_setDetectorQTP
(JNIEnv* env, jclass, jlong det, jobject params)
{
if (det == 0) {
nullPointerEx.Throw(env, "det cannot be null");
return;
}
reinterpret_cast<AprilTagDetector*>(det)->SetQuadThresholdParameters(
FromJavaDetectorQTP(env, params));
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Method: getDetectorQTP
* Signature: (J)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_getDetectorQTP
(JNIEnv* env, jclass, jlong det)
{
if (det == 0) {
nullPointerEx.Throw(env, "det cannot be null");
return nullptr;
}
return MakeJObject(
env,
reinterpret_cast<AprilTagDetector*>(det)->GetQuadThresholdParameters());
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Method: addFamily
* Signature: (JLjava/lang/String;I)Z
*/
JNIEXPORT jboolean JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_addFamily
(JNIEnv* env, jclass, jlong det, jstring fam, jint bitsCorrected)
{
if (det == 0) {
nullPointerEx.Throw(env, "det cannot be null");
return false;
}
if (!fam) {
nullPointerEx.Throw(env, "fam cannot be null");
return false;
}
return reinterpret_cast<AprilTagDetector*>(det)->AddFamily(
JStringRef{env, fam}, bitsCorrected);
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Method: removeFamily
* Signature: (JLjava/lang/String;)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_removeFamily
(JNIEnv* env, jclass, jlong det, jstring fam)
{
if (det == 0) {
nullPointerEx.Throw(env, "det cannot be null");
return;
}
if (!fam) {
nullPointerEx.Throw(env, "fam cannot be null");
return;
}
reinterpret_cast<AprilTagDetector*>(det)->RemoveFamily(JStringRef{env, fam});
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Method: clearFamilies
* Signature: (J)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_clearFamilies
(JNIEnv* env, jclass, jlong det)
{
if (det == 0) {
nullPointerEx.Throw(env, "det cannot be null");
return;
}
reinterpret_cast<AprilTagDetector*>(det)->ClearFamilies();
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Method: detect
* Signature: (JIIIJ)[Ljava/lang/Object;
*/
JNIEXPORT jobjectArray JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_detect
(JNIEnv* env, jclass, jlong det, jint width, jint height, jint stride,
jlong bufAddr)
{
if (det == 0) {
nullPointerEx.Throw(env, "det cannot be null");
return nullptr;
}
if (bufAddr == 0) {
nullPointerEx.Throw(env, "bufAddr cannot be null");
return nullptr;
}
return MakeJObject(
env, reinterpret_cast<AprilTagDetector*>(det)->Detect(
width, height, stride, reinterpret_cast<uint8_t*>(bufAddr)));
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Method: estimatePoseHomography
* Signature: ([DDDDDD)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_estimatePoseHomography
(JNIEnv* env, jclass, jdoubleArray homography, jdouble tagSize, jdouble fx,
jdouble fy, jdouble cx, jdouble cy)
{
if (!homography) {
nullPointerEx.Throw(env, "homography cannot be null");
return nullptr;
}
JDoubleArrayRef harr{env, homography};
if (harr.size() != 9) {
illegalArgEx.Throw(env, "homography array must be size 9");
return nullptr;
}
AprilTagPoseEstimator estimator({units::meter_t{tagSize}, fx, fy, cx, cy});
return MakeJObject(env, estimator.EstimateHomography(
std::span<const double, 9>{harr.array()}));
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Method: estimatePoseOrthogonalIteration
* Signature: ([D[DDDDDDI)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_estimatePoseOrthogonalIteration
(JNIEnv* env, jclass, jdoubleArray homography, jdoubleArray corners,
jdouble tagSize, jdouble fx, jdouble fy, jdouble cx, jdouble cy, jint nIters)
{
// homography
if (!homography) {
nullPointerEx.Throw(env, "homography cannot be null");
return nullptr;
}
JDoubleArrayRef harr{env, homography};
if (harr.size() != 9) {
illegalArgEx.Throw(env, "homography array must be size 9");
return nullptr;
}
// corners
if (!corners) {
nullPointerEx.Throw(env, "corners cannot be null");
return nullptr;
}
JDoubleArrayRef carr{env, corners};
if (carr.size() != 8) {
illegalArgEx.Throw(env, "corners array must be size 8");
return nullptr;
}
AprilTagPoseEstimator estimator({units::meter_t{tagSize}, fx, fy, cx, cy});
return MakeJObject(env,
estimator.EstimateOrthogonalIteration(
std::span<const double, 9>{harr.array()},
std::span<const double, 8>{carr.array()}, nIters));
}
/*
* Class: edu_wpi_first_apriltag_jni_AprilTagJNI
* Method: estimatePose
* Signature: ([D[DDDDDD)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL
Java_edu_wpi_first_apriltag_jni_AprilTagJNI_estimatePose
(JNIEnv* env, jclass, jdoubleArray homography, jdoubleArray corners,
jdouble tagSize, jdouble fx, jdouble fy, jdouble cx, jdouble cy)
{
// homography
if (!homography) {
nullPointerEx.Throw(env, "homography cannot be null");
return nullptr;
}
JDoubleArrayRef harr{env, homography};
if (harr.size() != 9) {
illegalArgEx.Throw(env, "homography array must be size 9");
return nullptr;
}
// corners
if (!corners) {
nullPointerEx.Throw(env, "corners cannot be null");
return nullptr;
}
JDoubleArrayRef carr{env, corners};
if (carr.size() != 8) {
illegalArgEx.Throw(env, "corners array must be size 8");
return nullptr;
}
AprilTagPoseEstimator estimator({units::meter_t{tagSize}, fx, fy, cx, cy});
return MakeJObject(
env, estimator.Estimate(std::span<const double, 9>{harr.array()},
std::span<const double, 8>{carr.array()}));
}
} // extern "C"

View File

@@ -0,0 +1,34 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <wpi/SymbolExports.h>
#include "frc/geometry/Pose3d.h"
namespace wpi {
class json;
} // namespace wpi
namespace frc {
struct WPILIB_DLLEXPORT AprilTag {
int ID;
Pose3d pose;
/**
* Checks equality between this AprilTag and another object.
*/
bool operator==(const AprilTag&) const = default;
};
WPILIB_DLLEXPORT
void to_json(wpi::json& json, const AprilTag& apriltag);
WPILIB_DLLEXPORT
void from_json(const wpi::json& json, AprilTag& apriltag);
} // namespace frc

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,32 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <string_view>
#include <wpi/SymbolExports.h>
#include "frc/apriltag/AprilTagFieldLayout.h"
namespace frc {
enum class AprilTagField {
k2022RapidReact,
k2023ChargedUp,
// This is a placeholder for denoting the last supported field. This should
// always be the last entry in the enum and should not be used by users
kNumFields,
};
/**
* Loads an AprilTagFieldLayout from a predefined field
*
* @param field The predefined field
*/
WPILIB_DLLEXPORT AprilTagFieldLayout
LoadAprilTagLayoutField(AprilTagField field);
} // namespace frc

View File

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

View File

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

View File

@@ -0,0 +1,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
}
}
}
},
{
"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
}
}

View File

@@ -0,0 +1,152 @@
{
"tags": [
{
"ID": 1,
"pose": {
"translation": {
"x": 15.513558,
"y": 1.071626,
"z": 0.462788
},
"rotation": {
"quaternion": {
"W": 0.0,
"X": 0.0,
"Y": 0.0,
"Z": 1.0
}
}
}
},
{
"ID": 2,
"pose": {
"translation": {
"x": 15.513558,
"y": 2.748026,
"z": 0.462788
},
"rotation": {
"quaternion": {
"W": 0.0,
"X": 0.0,
"Y": 0.0,
"Z": 1.0
}
}
}
},
{
"ID": 3,
"pose": {
"translation": {
"x": 15.513558,
"y": 4.424426,
"z": 0.462788
},
"rotation": {
"quaternion": {
"W": 0.0,
"X": 0.0,
"Y": 0.0,
"Z": 1.0
}
}
}
},
{
"ID": 4,
"pose": {
"translation": {
"x": 16.178784,
"y": 6.749796,
"z": 0.695452
},
"rotation": {
"quaternion": {
"W": 0.0,
"X": 0.0,
"Y": 0.0,
"Z": 1.0
}
}
}
},
{
"ID": 5,
"pose": {
"translation": {
"x": 0.36195,
"y": 6.749796,
"z": 0.695452
},
"rotation": {
"quaternion": {
"W": 1.0,
"X": 0.0,
"Y": 0.0,
"Z": 0.0
}
}
}
},
{
"ID": 6,
"pose": {
"translation": {
"x": 1.02743,
"y": 4.424426,
"z": 0.462788
},
"rotation": {
"quaternion": {
"W": 1.0,
"X": 0.0,
"Y": 0.0,
"Z": 0.0
}
}
}
},
{
"ID": 7,
"pose": {
"translation": {
"x": 1.02743,
"y": 2.748026,
"z": 0.462788
},
"rotation": {
"quaternion": {
"W": 1.0,
"X": 0.0,
"Y": 0.0,
"Z": 0.0
}
}
}
},
{
"ID": 8,
"pose": {
"translation": {
"x": 1.02743,
"y": 1.071626,
"z": 0.462788
},
"rotation": {
"quaternion": {
"W": 1.0,
"X": 0.0,
"Y": 0.0,
"Z": 0.0
}
}
}
}
],
"field": {
"length": 16.54175,
"width": 8.0137
}
}

View File

@@ -0,0 +1,264 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.apriltag;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import edu.wpi.first.math.geometry.Transform3d;
import edu.wpi.first.math.util.Units;
import edu.wpi.first.util.RuntimeLoader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
@SuppressWarnings("PMD.MutableStaticState")
class AprilTagDetectorTest {
@SuppressWarnings("MemberName")
AprilTagDetector detector;
static RuntimeLoader<Core> loader;
@BeforeAll
static void beforeAll() {
try {
loader =
new RuntimeLoader<>(
Core.NATIVE_LIBRARY_NAME, RuntimeLoader.getDefaultExtractionRoot(), Core.class);
loader.loadLibrary();
} catch (IOException ex) {
fail(ex);
}
}
@BeforeEach
void beforeEach() {
detector = new AprilTagDetector();
}
@AfterEach
void afterEach() {
detector.close();
}
@Test
void testConfigDefaults() {
var config = detector.getConfig();
assertEquals(new AprilTagDetector.Config(), config);
}
@Test
void testQtpDefaults() {
var params = detector.getQuadThresholdParameters();
assertEquals(new AprilTagDetector.QuadThresholdParameters(), params);
}
@Test
void testSetConfigNumThreads() {
var newConfig = new AprilTagDetector.Config();
newConfig.numThreads = 2;
detector.setConfig(newConfig);
var config = detector.getConfig();
assertEquals(2, config.numThreads);
}
@Test
void testQtpMinClusterPixels() {
var newParams = new AprilTagDetector.QuadThresholdParameters();
newParams.minClusterPixels = 8;
detector.setQuadThresholdParameters(newParams);
var params = detector.getQuadThresholdParameters();
assertEquals(8, params.minClusterPixels);
}
@Test
void testAdd16h5() {
assertDoesNotThrow(() -> detector.addFamily("tag16h5"));
// duplicate addition is also okay
assertDoesNotThrow(() -> detector.addFamily("tag16h5"));
}
@Test
void testAdd25h9() {
assertDoesNotThrow(() -> detector.addFamily("tag25h9"));
}
@Test
void testAdd36h11() {
assertDoesNotThrow(() -> detector.addFamily("tag36h11"));
}
@Test
void testAddMultiple() {
assertDoesNotThrow(() -> detector.addFamily("tag16h5"));
assertDoesNotThrow(() -> detector.addFamily("tag36h11"));
}
@Test
void testRemoveFamily() {
// okay to remove non-existent family
detector.removeFamily("tag16h5");
// add and remove
detector.addFamily("tag16h5");
detector.removeFamily("tag16h5");
}
@SuppressWarnings("PMD.AssignmentInOperand")
public Mat loadImage(String resource) throws IOException {
Mat encoded;
try (InputStream is = getClass().getResource(resource).openStream()) {
try (ByteArrayOutputStream os = new ByteArrayOutputStream(is.available())) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
encoded = new Mat(1, os.size(), CvType.CV_8U);
encoded.put(0, 0, os.toByteArray());
}
}
Mat image = Imgcodecs.imdecode(encoded, Imgcodecs.IMREAD_COLOR);
encoded.release();
Imgproc.cvtColor(image, image, Imgproc.COLOR_BGR2GRAY);
return image;
}
@Test
void testDecodeAndPose() {
detector.addFamily("tag16h5");
detector.addFamily("tag36h11");
Mat image;
try {
image = loadImage("tag1_640_480.jpg");
} catch (IOException ex) {
fail(ex);
return;
}
try {
AprilTagDetection[] results = detector.detect(image);
assertEquals(1, results.length);
assertEquals("tag36h11", results[0].getFamily());
assertEquals(1, results[0].getId());
assertEquals(0, results[0].getHamming());
var estimator =
new AprilTagPoseEstimator(new AprilTagPoseEstimator.Config(0.2, 500, 500, 320, 240));
AprilTagPoseEstimate est = estimator.estimateOrthogonalIteration(results[0], 50);
assertEquals(new Transform3d(), est.pose2);
Transform3d pose = estimator.estimate(results[0]);
assertEquals(est.pose1, pose);
} finally {
image.release();
}
}
/**
* This tag is rotated such that the top is closer to the camera than the bottom. In the camera
* frame, with +x to the right, this is a rotation about +X by 45 degrees.
*/
@Test
void testPoseRotatedX() {
detector.addFamily("tag16h5");
Mat image;
try {
image = loadImage("tag2_45deg_X.png");
} catch (IOException ex) {
fail(ex);
return;
}
try {
AprilTagDetection[] results = detector.detect(image);
assertEquals(1, results.length);
var estimator =
new AprilTagPoseEstimator(
new AprilTagPoseEstimator.Config(
0.2, 500, 500, image.cols() / 2.0, image.rows() / 2.0));
AprilTagPoseEstimate est = estimator.estimateOrthogonalIteration(results[0], 50);
assertEquals(Units.degreesToRadians(45), est.pose1.getRotation().getX(), 0.1);
assertEquals(Units.degreesToRadians(0), est.pose1.getRotation().getY(), 0.1);
assertEquals(Units.degreesToRadians(0), est.pose1.getRotation().getZ(), 0.1);
} finally {
image.release();
}
}
/**
* This tag is rotated such that the right is closer to the camera than the left. In the camera
* frame, with +y down, this is a rotation of 45 degrees about +y.
*/
@Test
void testPoseRotatedY() {
detector.addFamily("tag16h5");
Mat image;
try {
image = loadImage("tag2_45deg_y.png");
} catch (IOException ex) {
fail(ex);
return;
}
try {
AprilTagDetection[] results = detector.detect(image);
assertEquals(1, results.length);
var estimator =
new AprilTagPoseEstimator(
new AprilTagPoseEstimator.Config(
0.2, 500, 500, image.cols() / 2.0, image.rows() / 2.0));
AprilTagPoseEstimate est = estimator.estimateOrthogonalIteration(results[0], 50);
assertEquals(Units.degreesToRadians(0), est.pose1.getRotation().getX(), 0.1);
assertEquals(Units.degreesToRadians(45), est.pose1.getRotation().getY(), 0.1);
assertEquals(Units.degreesToRadians(0), est.pose1.getRotation().getZ(), 0.1);
} finally {
image.release();
}
}
/** This tag is facing right at the camera -- no rotation should be observed. */
@Test
void testPoseStraightOn() {
detector.addFamily("tag16h5");
Mat image;
try {
image = loadImage("tag2_16h5_straight.png");
} catch (IOException ex) {
fail(ex);
return;
}
try {
AprilTagDetection[] results = detector.detect(image);
assertEquals(1, results.length);
var estimator =
new AprilTagPoseEstimator(
new AprilTagPoseEstimator.Config(
0.2, 500, 500, image.cols() / 2.0, image.rows() / 2.0));
AprilTagPoseEstimate est = estimator.estimateOrthogonalIteration(results[0], 50);
assertEquals(Units.degreesToRadians(0), est.pose1.getRotation().getX(), 0.1);
assertEquals(Units.degreesToRadians(0), est.pose1.getRotation().getY(), 0.1);
assertEquals(Units.degreesToRadians(0), est.pose1.getRotation().getZ(), 0.1);
} finally {
image.release();
}
}
}

View File

@@ -0,0 +1,46 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.apriltag;
import static org.junit.jupiter.api.Assertions.assertEquals;
import edu.wpi.first.math.geometry.Pose3d;
import edu.wpi.first.math.geometry.Rotation3d;
import edu.wpi.first.math.geometry.Translation3d;
import edu.wpi.first.math.util.Units;
import java.util.List;
import org.junit.jupiter.api.Test;
class AprilTagPoseSetOriginTest {
@Test
void transformationMatches() {
var layout =
new AprilTagFieldLayout(
List.of(
new AprilTag(1, new Pose3d(new Translation3d(0, 0, 0), new Rotation3d(0, 0, 0))),
new AprilTag(
2,
new Pose3d(
new Translation3d(
Units.feetToMeters(4.0), Units.feetToMeters(4), Units.feetToMeters(4)),
new Rotation3d(0, 0, Units.degreesToRadians(180))))),
Units.feetToMeters(54.0),
Units.feetToMeters(27.0));
layout.setOrigin(AprilTagFieldLayout.OriginPosition.kRedAllianceWallRightSide);
assertEquals(
new Pose3d(
new Translation3d(Units.feetToMeters(54.0), Units.feetToMeters(27.0), 0.0),
new Rotation3d(0.0, 0.0, Units.degreesToRadians(180.0))),
layout.getTagPose(1).orElse(null));
assertEquals(
new Pose3d(
new Translation3d(
Units.feetToMeters(50.0), Units.feetToMeters(23.0), Units.feetToMeters(4)),
new Rotation3d(0.0, 0.0, 0)),
layout.getTagPose(2).orElse(null));
}
}

View File

@@ -0,0 +1,38 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.apriltag;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.fasterxml.jackson.databind.ObjectMapper;
import edu.wpi.first.math.geometry.Pose3d;
import edu.wpi.first.math.geometry.Rotation3d;
import edu.wpi.first.math.util.Units;
import java.util.List;
import org.junit.jupiter.api.Test;
class AprilTagSerializationTest {
@Test
void deserializeMatches() {
var layout =
new AprilTagFieldLayout(
List.of(
new AprilTag(1, new Pose3d(0, 0, 0, new Rotation3d(0, 0, 0))),
new AprilTag(3, new Pose3d(0, 1, 0, new Rotation3d(0, 0, 0)))),
Units.feetToMeters(54.0),
Units.feetToMeters(27.0));
var objectMapper = new ObjectMapper();
var deserialized =
assertDoesNotThrow(
() ->
objectMapper.readValue(
objectMapper.writeValueAsString(layout), AprilTagFieldLayout.class));
assertEquals(layout, deserialized);
}
}

View File

@@ -0,0 +1,71 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.apriltag;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import edu.wpi.first.math.geometry.Pose3d;
import edu.wpi.first.math.geometry.Rotation3d;
import edu.wpi.first.math.util.Units;
import java.io.IOException;
import java.util.Optional;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
class LoadConfigTest {
@ParameterizedTest
@EnumSource(AprilTagFields.class)
void testLoad(AprilTagFields field) {
AprilTagFieldLayout layout = Assertions.assertDoesNotThrow(field::loadAprilTagLayoutField);
assertNotNull(layout);
}
@Test
void test2022RapidReact() throws IOException {
AprilTagFieldLayout layout = AprilTagFields.k2022RapidReact.loadAprilTagLayoutField();
// Blue Hangar Truss - Hub
Pose3d expectedPose =
new Pose3d(
Units.inchesToMeters(127.272),
Units.inchesToMeters(216.01),
Units.inchesToMeters(67.932),
new Rotation3d(0, 0, 0));
Optional<Pose3d> maybePose = layout.getTagPose(1);
assertTrue(maybePose.isPresent());
assertEquals(expectedPose, maybePose.get());
// Blue Terminal Near Station
expectedPose =
new Pose3d(
Units.inchesToMeters(4.768),
Units.inchesToMeters(67.631),
Units.inchesToMeters(35.063),
new Rotation3d(0, 0, Math.toRadians(46.25)));
maybePose = layout.getTagPose(5);
assertTrue(maybePose.isPresent());
assertEquals(expectedPose, maybePose.get());
// Upper Hub Blue-Near
expectedPose =
new Pose3d(
Units.inchesToMeters(332.321),
Units.inchesToMeters(183.676),
Units.inchesToMeters(95.186),
new Rotation3d(0, Math.toRadians(26.75), Math.toRadians(69)));
maybePose = layout.getTagPose(53);
assertTrue(maybePose.isPresent());
assertEquals(expectedPose, maybePose.get());
// Doesn't exist
maybePose = layout.getTagPose(54);
assertFalse(maybePose.isPresent());
}
}

View File

@@ -0,0 +1,67 @@
// 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 "frc/apriltag/AprilTagDetector.h"
#include "gtest/gtest.h"
using namespace frc;
TEST(AprilTagDetectorTest, ConfigDefaults) {
AprilTagDetector detector;
auto config = detector.GetConfig();
ASSERT_EQ(config, AprilTagDetector::Config{});
}
TEST(AprilTagDetectorTest, QtpDefaults) {
AprilTagDetector detector;
auto params = detector.GetQuadThresholdParameters();
ASSERT_EQ(params, AprilTagDetector::QuadThresholdParameters{});
}
TEST(AprilTagDetectorTest, SetConfigNumThreads) {
AprilTagDetector detector;
detector.SetConfig({.numThreads = 2});
auto config = detector.GetConfig();
ASSERT_EQ(config.numThreads, 2);
}
TEST(AprilTagDetectorTest, QtpMinClusterPixels) {
AprilTagDetector detector;
detector.SetQuadThresholdParameters({.minClusterPixels = 8});
auto params = detector.GetQuadThresholdParameters();
ASSERT_EQ(params.minClusterPixels, 8);
}
TEST(AprilTagDetectorTest, Add16h5) {
AprilTagDetector detector;
ASSERT_TRUE(detector.AddFamily("tag16h5"));
// duplicate addition is also okay
ASSERT_TRUE(detector.AddFamily("tag16h5"));
}
TEST(AprilTagDetectorTest, Add25h9) {
AprilTagDetector detector;
ASSERT_TRUE(detector.AddFamily("tag25h9"));
}
TEST(AprilTagDetectorTest, Add36h11) {
AprilTagDetector detector;
ASSERT_TRUE(detector.AddFamily("tag36h11"));
}
TEST(AprilTagDetectorTest, AddMultiple) {
AprilTagDetector detector;
ASSERT_TRUE(detector.AddFamily("tag16h5"));
ASSERT_TRUE(detector.AddFamily("tag36h11"));
}
TEST(AprilTagDetectorTest, RemoveFamily) {
AprilTagDetector detector;
// okay to remove non-existent family
detector.RemoveFamily("tag16h5");
// add and remove
detector.AddFamily("tag16h5");
detector.RemoveFamily("tag16h5");
}

View File

@@ -0,0 +1,27 @@
// 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 <vector>
#include <wpi/json.h>
#include "frc/apriltag/AprilTag.h"
#include "frc/apriltag/AprilTagFieldLayout.h"
#include "frc/geometry/Pose3d.h"
#include "gtest/gtest.h"
using namespace frc;
TEST(AprilTagJsonTest, DeserializeMatches) {
auto layout = AprilTagFieldLayout{
std::vector{
AprilTag{1, Pose3d{}},
AprilTag{3, Pose3d{0_m, 1_m, 0_m, Rotation3d{0_deg, 0_deg, 0_deg}}}},
54_ft, 27_ft};
AprilTagFieldLayout deserialized;
wpi::json json = layout;
EXPECT_NO_THROW(deserialized = json.get<AprilTagFieldLayout>());
EXPECT_EQ(layout, deserialized);
}

View File

@@ -0,0 +1,33 @@
// 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 <vector>
#include <wpi/json.h>
#include "frc/apriltag/AprilTag.h"
#include "frc/apriltag/AprilTagFieldLayout.h"
#include "frc/geometry/Pose3d.h"
#include "gtest/gtest.h"
using namespace frc;
TEST(AprilTagPoseSetOriginTest, TransformationMatches) {
auto layout = AprilTagFieldLayout{
std::vector<AprilTag>{
AprilTag{1,
Pose3d{0_ft, 0_ft, 0_ft, Rotation3d{0_deg, 0_deg, 0_deg}}},
AprilTag{
2, Pose3d{4_ft, 4_ft, 4_ft, Rotation3d{0_deg, 0_deg, 180_deg}}}},
54_ft, 27_ft};
layout.SetOrigin(
AprilTagFieldLayout::OriginPosition::kRedAllianceWallRightSide);
auto mirrorPose =
Pose3d{54_ft, 27_ft, 0_ft, Rotation3d{0_deg, 0_deg, 180_deg}};
EXPECT_EQ(mirrorPose, *layout.GetTagPose(1));
mirrorPose = Pose3d{50_ft, 23_ft, 4_ft, Rotation3d{0_deg, 0_deg, 0_deg}};
EXPECT_EQ(mirrorPose, *layout.GetTagPose(2));
}

View File

@@ -0,0 +1,61 @@
// 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 "frc/apriltag/AprilTagFields.h"
#include "gtest/gtest.h"
namespace frc {
std::vector<AprilTagField> GetAllFields() {
std::vector<AprilTagField> output;
for (int i = 0; i < static_cast<int>(AprilTagField::kNumFields); ++i) {
output.push_back(static_cast<AprilTagField>(i));
}
return output;
}
TEST(AprilTagFieldsTest, TestLoad2022RapidReact) {
AprilTagFieldLayout layout =
LoadAprilTagLayoutField(AprilTagField::k2022RapidReact);
// Blue Hangar Truss - Hub
auto expectedPose =
Pose3d{127.272_in, 216.01_in, 67.932_in, Rotation3d{0_deg, 0_deg, 0_deg}};
auto maybePose = layout.GetTagPose(1);
EXPECT_TRUE(maybePose);
EXPECT_EQ(expectedPose, *maybePose);
// Blue Terminal Near Station
expectedPose = Pose3d{4.768_in, 67.631_in, 35.063_in,
Rotation3d{0_deg, 0_deg, 46.25_deg}};
maybePose = layout.GetTagPose(5);
EXPECT_TRUE(maybePose);
EXPECT_EQ(expectedPose, *maybePose);
// Upper Hub Blue-Near
expectedPose = Pose3d{332.321_in, 183.676_in, 95.186_in,
Rotation3d{0_deg, 26.75_deg, 69_deg}};
maybePose = layout.GetTagPose(53);
EXPECT_TRUE(maybePose);
EXPECT_EQ(expectedPose, *maybePose);
// Doesn't exist
maybePose = layout.GetTagPose(54);
EXPECT_FALSE(maybePose);
}
// Test all of the fields in the enum
class AllFieldsFixtureTest : public ::testing::TestWithParam<AprilTagField> {};
TEST_P(AllFieldsFixtureTest, CheckEntireEnum) {
AprilTagField field = GetParam();
EXPECT_NO_THROW(LoadAprilTagLayoutField(field));
}
INSTANTIATE_TEST_SUITE_P(ValuesEnumTestInstTests, AllFieldsFixtureTest,
::testing::ValuesIn(GetAllFields()));
} // namespace frc

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -12,10 +12,10 @@ stages:
- job: IntegrationTests
displayName: Integration Tests
pool:
vmImage: "Ubuntu 16.04"
vmImage: 'ubuntu-latest'
container:
image: wpilib/roborio-cross-ubuntu:2021-18.04
image: wpilib/roborio-cross-ubuntu:2023-22.04
timeoutInMinutes: 0
@@ -29,7 +29,7 @@ stages:
publishJUnitResults: false
testResultsFiles: "**/TEST-*.xml"
tasks: "copyWpilibJIntegrationTestJarToOutput copyWpilibCTestLibrariesToOutput"
options: "-Ponlylinuxathena -PbuildServer"
options: "-Ponlylinuxathena -PbuildServer -PskipJavaFormat"
- task: PublishPipelineArtifact@0
inputs:
@@ -38,6 +38,7 @@ stages:
- stage: TestBench
displayName: Test Bench
condition: false
jobs:
- job: Cpp
displayName: C++

View File

@@ -1,17 +1,29 @@
import edu.wpi.first.toolchain.*
buildscript {
repositories {
maven {
url = 'https://frcmaven.wpi.edu/artifactory/ex-mvn'
}
}
dependencies {
classpath 'com.hubspot.jinjava:jinjava:2.6.0'
}
}
plugins {
id 'base'
id 'edu.wpi.first.wpilib.versioning.WPILibVersioningPlugin' version '4.1.0'
id 'edu.wpi.first.wpilib.versioning.WPILibVersioningPlugin' version '2023.0.1'
id 'edu.wpi.first.wpilib.repositories.WPILibRepositoriesPlugin' version '2020.2'
id 'edu.wpi.first.NativeUtils' apply false
id 'edu.wpi.first.GradleJni' version '0.10.1'
id 'edu.wpi.first.GradleVsCode' version '0.11.0'
id 'edu.wpi.first.GradleJni' version '1.1.0'
id 'edu.wpi.first.GradleVsCode'
id 'idea'
id 'visual-studio'
id 'net.ltgt.errorprone' version '1.1.1' apply false
id 'com.github.johnrengelman.shadow' version '5.2.0' apply false
id 'com.diffplug.spotless' version '5.5.0'
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
}
wpilibVersioning.buildServerMode = project.hasProperty('buildServer')
@@ -19,7 +31,9 @@ wpilibVersioning.releaseMode = project.hasProperty('releaseMode')
allprojects {
repositories {
mavenCentral()
maven {
url = 'https://frcmaven.wpi.edu/artifactory/ex-mvn'
}
}
if (project.hasProperty('releaseMode')) {
wpilibRepositories.addAllReleaseRepositories(it)
@@ -73,7 +87,12 @@ task copyAllOutputs(type: Copy) {
build.dependsOn copyAllOutputs
copyAllOutputs.dependsOn outputVersions
def copyReleaseOnly = project.hasProperty('ciReleaseOnly')
ext.addTaskToCopyAllOutputs = { task ->
if (copyReleaseOnly && task.name.contains('debug')) {
return
}
copyAllOutputs.dependsOn task
copyAllOutputs.inputs.file task.archivePath
copyAllOutputs.from task.archivePath
@@ -89,6 +108,11 @@ subprojects {
subproj.apply plugin: MultiBuilds
}
plugins.withType(JavaPlugin) {
sourceCompatibility = 11
targetCompatibility = 11
}
apply from: "${rootDir}/shared/java/javastyle.gradle"
// Disables doclint in java 8.
@@ -100,9 +124,22 @@ subprojects {
}
}
tasks.withType(JavaCompile) {
options.compilerArgs.add '-XDstringConcat=inline'
}
// Enables UTF-8 support in Javadoc
tasks.withType(Javadoc) {
options.addStringOption("charset", "utf-8")
options.addStringOption("docencoding", "utf-8")
options.addStringOption("encoding", "utf-8")
}
// Sign outputs with Developer ID
if (project.hasProperty("developerID")) {
tasks.withType(AbstractLinkTask) { task ->
tasks.withType(AbstractLinkTask) { task ->
task.inputs.property "HasDeveloperId", project.hasProperty("developerID")
if (project.hasProperty("developerID")) {
// Don't sign any executables because codesign complains
// about relative rpath.
if (!(task instanceof LinkExecutable)) {
@@ -129,49 +166,6 @@ ext.getCurrentArch = {
return NativePlatforms.desktop
}
spotless {
java {
target fileTree('.') {
include '**/*.java'
exclude '**/build/**', '**/build-*/**'
}
toggleOffOn()
googleJavaFormat()
removeUnusedImports()
trimTrailingWhitespace()
endWithNewline()
}
groovyGradle {
target fileTree('.') {
include '**/*.gradle'
exclude '**/build/**', '**/build-*/**'
}
greclipse()
indentWithSpaces(4)
trimTrailingWhitespace()
endWithNewline()
}
format 'xml', {
target fileTree('.') {
include '**/*.xml'
exclude '**/build/**', '**/build-*/**'
}
eclipseWtp('xml')
trimTrailingWhitespace()
indentWithSpaces(2)
endWithNewline()
}
format 'misc', {
target fileTree('.') {
include '**/*.md', '**/.gitignore'
exclude '**/build/**', '**/build-*/**'
}
trimTrailingWhitespace()
indentWithSpaces(2)
endWithNewline()
}
}
wrapper {
gradleVersion = '6.0.1'
gradleVersion = '7.5.1'
}

View File

@@ -1,9 +1,13 @@
repositories {
maven {
url "https://plugins.gradle.org/m2/"
mavenLocal()
maven {
url = 'https://frcmaven.wpi.edu/artifactory/ex-gradle'
}
mavenCentral()
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
implementation "edu.wpi.first:native-utils:2021.1.1"
implementation "edu.wpi.first:native-utils:2023.11.1"
}

View File

@@ -1,48 +0,0 @@
import groovy.transform.CompileStatic
import javax.inject.Inject
import jaci.gradle.deploy.artifact.MavenArtifact
import jaci.gradle.deploy.context.DeployContext
import org.gradle.api.Project
import jaci.gradle.ActionWrapper
import java.util.function.Function
@CompileStatic
class JREArtifact extends MavenArtifact {
Function<DeployContext, Boolean> buildRequiresJre = (Function<DeployContext, Boolean>){ true }
void setJreDependency(String dep) {
dependency = project.dependencies.add(configuration(), dep)
}
@Inject
JREArtifact(String name, Project project) {
super(name, project)
configuration = project.configurations.create(configuration())
onlyIf = { DeployContext ctx ->
(buildRequiresJre.apply(ctx) && jreMissing(ctx)) || project.hasProperty("force-redeploy-jre")
}
predeploy << new ActionWrapper({ DeployContext ctx ->
ctx.logger.log('Deploying RoboRIO JRE (this will take a while)...')
})
directory = '/tmp'
filename = 'frcjre.ipk'
postdeploy << new ActionWrapper({ DeployContext ctx ->
ctx.logger.log('Installing JRE...')
ctx.execute('opkg remove frc2020-openjdk*; opkg install /tmp/frcjre.ipk; rm /tmp/frcjre.ipk')
ctx.logger.log('JRE Deployed!')
})
}
String configuration() {
return name + 'frcjre'
}
boolean jreMissing(DeployContext ctx) {
return ctx.execute('if [[ -f "/usr/local/frc/JRE/bin/java" ]]; then echo OK; else echo MISSING; fi').result.contains("MISSING")
}
}

View File

@@ -46,7 +46,7 @@ import org.gradle.platform.base.ComponentType;
import org.gradle.platform.base.TypeBuilder;
import org.gradle.nativeplatform.tasks.ObjectFilesToBinary;
import groovy.transform.CompileStatic;
import edu.wpi.first.nativeutils.tasks.ExportsGenerationTask
import edu.wpi.first.nativeutils.exports.ExportsGenerationTask
@CompileStatic
class SingleNativeBuild implements Plugin<Project> {

View File

@@ -0,0 +1,77 @@
import groovy.transform.CompileStatic;
import javax.inject.Inject;
import org.gradle.api.Project;
import edu.wpi.first.deployutils.deploy.CommandDeployResult;
import edu.wpi.first.deployutils.deploy.artifact.MavenArtifact;
import edu.wpi.first.deployutils.deploy.context.DeployContext;
import edu.wpi.first.deployutils.deploy.target.RemoteTarget;
import edu.wpi.first.deployutils.PredicateWrapper;
import edu.wpi.first.deployutils.ActionWrapper;
@CompileStatic
public class WPIJREArtifact extends MavenArtifact {
private final String configName;
public String getConfigName() {
return configName;
}
public boolean isCheckJreVersion() {
return checkJreVersion;
}
public void setCheckJreVersion(boolean checkJreVersion) {
this.checkJreVersion = checkJreVersion;
}
private boolean checkJreVersion = true;
private final String artifactLocation = "edu.wpi.first.jdk:roborio-2023:17.0.5u7-1"
@Inject
public WPIJREArtifact(String name, RemoteTarget target) {
super(name, target);
String configName = name + "frcjre";
this.configName = configName;
Project project = target.getProject();
getConfiguration().set(project.getConfigurations().create(configName));
getDependency().set(project.getDependencies().add(configName, artifactLocation));
setOnlyIf(new PredicateWrapper({ DeployContext ctx ->
return jreMissing(ctx) || jreOutOfDate(ctx) || project.hasProperty("force-redeploy-jre");
}));
getDirectory().set("/tmp");
getFilename().set("frcjre.ipk");
getPostdeploy().add(new ActionWrapper({ DeployContext ctx ->
ctx.getLogger().log("Installing JRE...");
ctx.execute("opkg remove frc*-openjdk*; opkg install /tmp/frcjre.ipk; rm /tmp/frcjre.ipk");
ctx.getLogger().log("JRE Deployed!");
}));
}
private boolean jreMissing(DeployContext ctx) {
return ctx.execute("if [[ -f \"/usr/local/frc/JRE/bin/java\" ]]; then echo OK; else echo MISSING; fi").getResult().contains("MISSING");
}
private boolean jreOutOfDate(DeployContext ctx) {
if (!checkJreVersion) {
return false;
}
String version = getDependency().get().getVersion();
CommandDeployResult cmdResult = ctx.execute("opkg list-installed | grep openjdk");
if (cmdResult.getExitCode() != 0) {
ctx.getLogger().log("JRE not found");
return false;
}
String result = cmdResult.getResult().trim();
ctx.getLogger().log("Searching for JRE " + version);
ctx.getLogger().log("Found JRE " + result);
boolean matches = result.contains(version);
ctx.getLogger().log(matches ? "JRE Is Correct Version" : "JRE is mismatched. Reinstalling");
return !matches;
}
}

View File

@@ -12,6 +12,7 @@ repoRootNameOverride {
}
includeOtherLibs {
^fmt/
^hal/
^networktables/
^opencv2/

View File

@@ -9,7 +9,7 @@ find_package( OpenCV REQUIRED )
if (WITH_JAVA)
find_package(Java REQUIRED)
include(UseJava)
set(CMAKE_JAVA_COMPILE_FLAGS "-Xlint:unchecked")
set(CMAKE_JAVA_COMPILE_FLAGS "-encoding" "UTF8" "-Xlint:unchecked")
#find java files, copy them locally

View File

@@ -11,9 +11,11 @@ apply from: "${rootDir}/shared/javacpp/setupBuild.gradle"
dependencies {
implementation project(':wpiutil')
implementation project(':wpinet')
implementation project(':ntcore')
implementation project(':cscore')
devImplementation project(':wpiutil')
devImplementation project(':wpinet')
devImplementation project(':ntcore')
devImplementation project(':cscore')
}
@@ -32,19 +34,6 @@ apply from: "${rootDir}/shared/opencv.gradle"
nativeUtils.exportsConfigs {
cameraserver {
x86ExcludeSymbols = [
'_CT??_R0?AV_System_error',
'_CT??_R0?AVexception',
'_CT??_R0?AVfailure',
'_CT??_R0?AVruntime_error',
'_CT??_R0?AVsystem_error',
'_CTA5?AVfailure',
'_TI5?AVfailure',
'_CT??_R0?AVout_of_range',
'_CTA3?AVout_of_range',
'_TI3?AVout_of_range',
'_CT??_R0?AVbad_cast'
]
x64ExcludeSymbols = [
'_CT??_R0?AV_System_error',
'_CT??_R0?AVexception',
@@ -68,8 +57,9 @@ model {
if (!it.buildable || !(it instanceof NativeBinarySpec)) {
return
}
lib project: ':ntcore', library: 'ntcore', linkage: 'shared'
project(':ntcore').addNtcoreDependency(it, 'shared')
lib project: ':cscore', library: 'cscore', linkage: 'shared'
lib project: ':wpinet', library: 'wpinet', linkage: 'shared'
lib project: ':wpiutil', library: 'wpiutil', linkage: 'shared'
}
}

View File

@@ -23,13 +23,16 @@ mainClassName = 'edu.wpi.Main'
apply plugin: 'com.github.johnrengelman.shadow'
repositories {
mavenCentral()
maven {
url = 'https://frcmaven.wpi.edu/artifactory/ex-mvn'
}
}
dependencies {
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.google.code.gson:gson:2.8.9'
implementation project(':wpiutil')
implementation project(':wpinet')
implementation project(':ntcore')
implementation project(':cscore')
implementation project(':cameraserver')
@@ -38,7 +41,6 @@ dependencies {
model {
components {
multiCameraServerCpp(NativeExecutableSpec) {
targetBuildTypes 'release'
sources {
cpp {
source {
@@ -53,8 +55,9 @@ model {
}
binaries.all { binary ->
lib project: ':cameraserver', library: 'cameraserver', linkage: 'static'
lib project: ':ntcore', library: 'ntcore', linkage: 'static'
project(':ntcore').addNtcoreDependency(binary, 'static')
lib project: ':cscore', library: 'cscore', linkage: 'static'
lib project: ':wpinet', library: 'wpinet', linkage: 'static'
lib project: ':wpiutil', library: 'wpiutil', linkage: 'static'
}
}

View File

@@ -10,8 +10,8 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import edu.wpi.cscore.VideoSource;
import edu.wpi.first.cameraserver.CameraServer;
import edu.wpi.first.cscore.VideoSource;
import edu.wpi.first.networktables.NetworkTableInstance;
import java.io.IOException;
import java.nio.file.Files;
@@ -56,9 +56,9 @@ public final class Main {
public JsonObject config;
}
public static int team;
public static boolean server;
public static List<CameraConfig> cameras = new ArrayList<>();
private static int team;
private static boolean server;
private static List<CameraConfig> cameras = new ArrayList<>();
private Main() {}
@@ -94,7 +94,6 @@ public final class Main {
}
/** Read configuration file. */
@SuppressWarnings("PMD.CyclomaticComplexity")
public static boolean readConfig() {
// parse file
JsonElement top;
@@ -151,7 +150,7 @@ public final class Main {
/** Start running the camera. */
public static void startCamera(CameraConfig config) {
System.out.println("Starting camera '" + config.name + "' on " + config.path);
VideoSource camera = CameraServer.getInstance().startAutomaticCapture(config.name, config.path);
VideoSource camera = CameraServer.startAutomaticCapture(config.name, config.path);
Gson gson = new GsonBuilder().create();
@@ -176,7 +175,8 @@ public final class Main {
ntinst.startServer();
} else {
System.out.println("Setting up NetworkTables client for team " + team);
ntinst.startClientTeam(team);
ntinst.setServerTeam(team);
ntinst.startClient4("multicameraserver");
}
// start cameras

View File

@@ -4,10 +4,13 @@
#include <cstdio>
#include <string>
#include <string_view>
#include <thread>
#include <vector>
#include <networktables/NetworkTableInstance.h>
#include <wpi/StringRef.h>
#include <wpi/StringExtras.h>
#include <wpi/fmt/raw_ostream.h>
#include <wpi/json.h>
#include <wpi/raw_istream.h>
#include <wpi/raw_ostream.h>
@@ -105,7 +108,7 @@ bool ReadConfig() {
try {
j = wpi::json::parse(is);
} catch (const wpi::json::parse_error& e) {
ParseError() << "byte " << e.byte << ": " << e.what() << '\n';
fmt::print(ParseError(), "byte {}: {}\n", e.byte, e.what());
return false;
}
@@ -127,10 +130,9 @@ bool ReadConfig() {
if (j.count("ntmode") != 0) {
try {
auto str = j.at("ntmode").get<std::string>();
wpi::StringRef s(str);
if (s.equals_lower("client")) {
if (wpi::equals_lower(str, "client")) {
server = false;
} else if (s.equals_lower("server")) {
} else if (wpi::equals_lower(str, "server")) {
server = true;
} else {
ParseError() << "could not understand ntmode value '" << str << "'\n";
@@ -156,10 +158,9 @@ bool ReadConfig() {
}
void StartCamera(const CameraConfig& config) {
wpi::outs() << "Starting camera '" << config.name << "' on " << config.path
<< '\n';
auto camera = frc::CameraServer::GetInstance()->StartAutomaticCapture(
config.name, config.path);
fmt::print("Starting camera '{}' on {}\n", config.name, config.path);
auto camera =
frc::CameraServer::StartAutomaticCapture(config.name, config.path);
camera.SetConfigJson(config.config);
}
@@ -178,11 +179,12 @@ int main(int argc, char* argv[]) {
// start NetworkTables
auto ntinst = nt::NetworkTableInstance::GetDefault();
if (server) {
wpi::outs() << "Setting up NetworkTables server\n";
std::puts("Setting up NetworkTables server");
ntinst.StartServer();
} else {
wpi::outs() << "Setting up NetworkTables client for team " << team << '\n';
ntinst.StartClientTeam(team);
fmt::print("Setting up NetworkTables client for team {}\n", team);
ntinst.StartClient4("multicameraserver");
ntinst.SetServerTeam(team);
}
// start cameras

View File

@@ -9,12 +9,15 @@ public final class CameraServerSharedStore {
private CameraServerSharedStore() {}
/** get the CameraServerShared object. */
/**
* Get the CameraServerShared object.
*
* @return The CameraServerSharedObject
*/
public static synchronized CameraServerShared getCameraServerShared() {
if (cameraServerShared == null) {
cameraServerShared =
new CameraServerShared() {
@Override
public void reportVideoServer(int id) {}
@@ -36,7 +39,11 @@ public final class CameraServerSharedStore {
return cameraServerShared;
}
/** set the CameraServerShared object. */
/**
* Set the CameraServerShared object.
*
* @param shared The CameraServerShared object.
*/
public static synchronized void setCameraServerShared(CameraServerShared shared) {
cameraServerShared = shared;
}

View File

@@ -17,6 +17,8 @@ public interface VisionPipeline {
/**
* Processes the image input and sets the result objects. Implementations should make these
* objects accessible.
*
* @param image The image to process.
*/
void process(Mat image);
}

View File

@@ -4,9 +4,9 @@
package edu.wpi.first.vision;
import edu.wpi.cscore.CvSink;
import edu.wpi.cscore.VideoSource;
import edu.wpi.first.cameraserver.CameraServerSharedStore;
import edu.wpi.first.cscore.CvSink;
import edu.wpi.first.cscore.VideoSource;
import org.opencv.core.Mat;
/**

View File

@@ -4,7 +4,7 @@
package edu.wpi.first.vision;
import edu.wpi.cscore.VideoSource;
import edu.wpi.first.cscore.VideoSource;
/**
* A vision thread is a special thread that runs a vision pipeline. It is a <i>daemon</i> thread; it

View File

@@ -9,11 +9,11 @@
* <p>An example use case for grabbing a yellow tote from 2015 in autonomous: <br>
*
* <pre><code>
* public class Robot extends IterativeRobot
* public class Robot extends TimedRobot
* implements VisionRunner.Listener&lt;MyFindTotePipeline&gt; {
*
* // A USB camera connected to the roboRIO.
* private {@link edu.wpi.cscore.VideoSource VideoSource} usbCamera;
* private {@link edu.wpi.first.cscore.VideoSource VideoSource} usbCamera;
*
* // A vision pipeline. This could be handwritten or generated by GRIP.
* // This has to implement {@link edu.wpi.first.vision.VisionPipeline}.
@@ -44,7 +44,7 @@
*
* {@literal @}Override
* public void robotInit() {
* usbCamera = CameraServer.getInstance().startAutomaticCapture(0);
* usbCamera = CameraServer.startAutomaticCapture(0);
* findTotePipeline = new MyFindTotePipeline();
* findToteThread = new VisionThread(usbCamera, findTotePipeline, this);
* }

View File

@@ -7,14 +7,18 @@
#include <atomic>
#include <vector>
#include <fmt/format.h>
#include <networktables/BooleanTopic.h>
#include <networktables/IntegerTopic.h>
#include <networktables/NetworkTable.h>
#include <networktables/NetworkTableInstance.h>
#include <networktables/StringArrayTopic.h>
#include <networktables/StringTopic.h>
#include <wpi/DenseMap.h>
#include <wpi/ManagedStatic.h>
#include <wpi/SmallString.h>
#include <wpi/StringExtras.h>
#include <wpi/StringMap.h>
#include <wpi/mutex.h>
#include <wpi/raw_ostream.h>
#include "cameraserver/CameraServerShared.h"
#include "ntcore_cpp.h"
@@ -23,9 +27,43 @@ using namespace frc;
static constexpr char const* kPublishName = "/CameraPublisher";
struct CameraServer::Impl {
Impl();
std::shared_ptr<nt::NetworkTable> GetSourceTable(CS_Source source);
namespace {
struct Instance;
struct PropertyPublisher {
PropertyPublisher(nt::NetworkTable& table, const cs::VideoEvent& event);
void Update(const cs::VideoEvent& event);
nt::BooleanEntry booleanValueEntry;
nt::IntegerEntry integerValueEntry;
nt::StringEntry stringValueEntry;
nt::IntegerPublisher minPublisher;
nt::IntegerPublisher maxPublisher;
nt::IntegerPublisher stepPublisher;
nt::IntegerPublisher defaultPublisher;
nt::StringArrayTopic choicesTopic;
nt::StringArrayPublisher choicesPublisher;
};
struct SourcePublisher {
SourcePublisher(Instance& inst, std::shared_ptr<nt::NetworkTable> table,
CS_Source source);
std::shared_ptr<nt::NetworkTable> table;
nt::StringPublisher sourcePublisher;
nt::StringPublisher descriptionPublisher;
nt::BooleanPublisher connectedPublisher;
nt::StringArrayPublisher streamsPublisher;
nt::StringEntry modeEntry;
nt::StringArrayPublisher modesPublisher;
wpi::DenseMap<CS_Property, PropertyPublisher> properties;
};
struct Instance {
Instance();
SourcePublisher* GetPublisher(CS_Source source);
std::vector<std::string> GetSinkStreamValues(CS_Sink sink);
std::vector<std::string> GetSourceStreamValues(CS_Source source);
void UpdateStreamValues();
@@ -36,40 +74,36 @@ struct CameraServer::Impl {
wpi::StringMap<cs::VideoSource> m_sources;
wpi::StringMap<cs::VideoSink> m_sinks;
wpi::DenseMap<CS_Sink, CS_Source> m_fixedSources;
wpi::DenseMap<CS_Source, std::shared_ptr<nt::NetworkTable>> m_tables;
wpi::DenseMap<CS_Source, SourcePublisher> m_publishers;
std::shared_ptr<nt::NetworkTable> m_publishTable{
nt::NetworkTableInstance::GetDefault().GetTable(kPublishName)};
cs::VideoListener m_videoListener;
int m_tableListener;
int m_nextPort;
int m_nextPort{CameraServer::kBasePort};
std::vector<std::string> m_addresses;
};
CameraServer* CameraServer::GetInstance() {
struct Creator {
static void* call() { return new CameraServer{}; }
};
struct Deleter {
static void call(void* ptr) { delete static_cast<CameraServer*>(ptr); }
};
static wpi::ManagedStatic<CameraServer, Creator, Deleter> instance;
return &(*instance);
} // namespace
static Instance& GetInstance() {
static Instance instance;
return instance;
}
static wpi::StringRef MakeSourceValue(CS_Source source,
wpi::SmallVectorImpl<char>& buf) {
static std::string_view MakeSourceValue(CS_Source source,
wpi::SmallVectorImpl<char>& buf) {
CS_Status status = 0;
buf.clear();
switch (cs::GetSourceKind(source, &status)) {
case CS_SOURCE_USB: {
wpi::StringRef prefix{"usb:"};
std::string_view prefix{"usb:"};
buf.append(prefix.begin(), prefix.end());
auto path = cs::GetUsbCameraPath(source, &status);
buf.append(path.begin(), path.end());
break;
}
case CS_SOURCE_HTTP: {
wpi::StringRef prefix{"ip:"};
std::string_view prefix{"ip:"};
buf.append(prefix.begin(), prefix.end());
auto urls = cs::GetHttpCameraUrls(source, &status);
if (!urls.empty()) {
@@ -83,22 +117,23 @@ static wpi::StringRef MakeSourceValue(CS_Source source,
return "unknown:";
}
return wpi::StringRef{buf.begin(), buf.size()};
return {buf.begin(), buf.size()};
}
static std::string MakeStreamValue(const wpi::Twine& address, int port) {
return ("mjpg:http://" + address + wpi::Twine(':') + wpi::Twine(port) +
"/?action=stream")
.str();
static std::string MakeStreamValue(std::string_view address, int port) {
return fmt::format("mjpg:http://{}:{}/?action=stream", address, port);
}
std::shared_ptr<nt::NetworkTable> CameraServer::Impl::GetSourceTable(
CS_Source source) {
std::scoped_lock lock(m_mutex);
return m_tables.lookup(source);
SourcePublisher* Instance::GetPublisher(CS_Source source) {
auto it = m_publishers.find(source);
if (it != m_publishers.end()) {
return &it->second;
} else {
return nullptr;
}
}
std::vector<std::string> CameraServer::Impl::GetSinkStreamValues(CS_Sink sink) {
std::vector<std::string> Instance::GetSinkStreamValues(CS_Sink sink) {
CS_Status status = 0;
// Ignore all but MjpegServer
@@ -130,8 +165,7 @@ std::vector<std::string> CameraServer::Impl::GetSinkStreamValues(CS_Sink sink) {
return values;
}
std::vector<std::string> CameraServer::Impl::GetSourceStreamValues(
CS_Source source) {
std::vector<std::string> Instance::GetSourceStreamValues(CS_Source source) {
CS_Status status = 0;
// Ignore all but HttpCamera
@@ -165,8 +199,7 @@ std::vector<std::string> CameraServer::Impl::GetSourceStreamValues(
return values;
}
void CameraServer::Impl::UpdateStreamValues() {
std::scoped_lock lock(m_mutex);
void Instance::UpdateStreamValues() {
// Over all the sinks...
for (const auto& i : m_sinks) {
CS_Status status = 0;
@@ -180,8 +213,7 @@ void CameraServer::Impl::UpdateStreamValues() {
if (source == 0) {
continue;
}
auto table = m_tables.lookup(source);
if (table) {
if (auto publisher = GetPublisher(source)) {
// Don't set stream values if this is a HttpCamera passthrough
if (cs::GetSourceKind(source, &status) == CS_SOURCE_HTTP) {
continue;
@@ -190,7 +222,7 @@ void CameraServer::Impl::UpdateStreamValues() {
// Set table value
auto values = GetSinkStreamValues(sink);
if (!values.empty()) {
table->GetEntry("streams").SetStringArray(values);
publisher->streamsPublisher.Set(values);
}
}
}
@@ -200,12 +232,11 @@ void CameraServer::Impl::UpdateStreamValues() {
CS_Source source = i.second.GetHandle();
// Get the source's subtable (if none exists, we're done)
auto table = m_tables.lookup(source);
if (table) {
if (auto publisher = GetPublisher(source)) {
// Set table value
auto values = GetSourceStreamValues(source);
if (!values.empty()) {
table->GetEntry("streams").SetStringArray(values);
publisher->streamsPublisher.Set(values);
}
}
}
@@ -229,12 +260,8 @@ static std::string PixelFormatToString(int pixelFormat) {
}
static std::string VideoModeToString(const cs::VideoMode& mode) {
std::string rv;
wpi::raw_string_ostream oss{rv};
oss << mode.width << "x" << mode.height;
oss << " " << PixelFormatToString(mode.pixelFormat) << " ";
oss << mode.fps << " fps";
return oss.str();
return fmt::format("{}x{} {} {} fps", mode.width, mode.height,
PixelFormatToString(mode.pixelFormat), mode.fps);
}
static std::vector<std::string> GetSourceModeValues(int source) {
@@ -246,54 +273,71 @@ static std::vector<std::string> GetSourceModeValues(int source) {
return rv;
}
static void PutSourcePropertyValue(nt::NetworkTable* table,
const cs::VideoEvent& event, bool isNew) {
wpi::SmallString<64> name;
wpi::SmallString<64> infoName;
if (wpi::StringRef{event.name}.startswith("raw_")) {
name = "RawProperty/";
name += event.name;
infoName = "RawPropertyInfo/";
infoName += event.name;
PropertyPublisher::PropertyPublisher(nt::NetworkTable& table,
const cs::VideoEvent& event) {
std::string name;
std::string infoName;
if (wpi::starts_with(event.name, "raw_")) {
name = fmt::format("RawProperty/{}", event.name);
infoName = fmt::format("RawPropertyInfo/{}", event.name);
} else {
name = "Property/";
name += event.name;
infoName = "PropertyInfo/";
infoName += event.name;
name = fmt::format("Property/{}", event.name);
infoName = fmt::format("PropertyInfo/{}", event.name);
}
wpi::SmallString<64> buf;
CS_Status status = 0;
nt::NetworkTableEntry entry = table->GetEntry(name);
switch (event.propertyKind) {
case CS_PROP_BOOLEAN:
if (isNew) {
entry.SetDefaultBoolean(event.value != 0);
} else {
entry.SetBoolean(event.value != 0);
booleanValueEntry = table.GetBooleanTopic(name).GetEntry(false);
booleanValueEntry.SetDefault(event.value != 0);
break;
case CS_PROP_ENUM:
choicesTopic =
table.GetStringArrayTopic(fmt::format("{}/choices", infoName));
[[fallthrough]];
case CS_PROP_INTEGER:
integerValueEntry = table.GetIntegerTopic(name).GetEntry(0);
minPublisher =
table.GetIntegerTopic(fmt::format("{}/min", infoName)).Publish();
maxPublisher =
table.GetIntegerTopic(fmt::format("{}/max", infoName)).Publish();
stepPublisher =
table.GetIntegerTopic(fmt::format("{}/step", infoName)).Publish();
defaultPublisher =
table.GetIntegerTopic(fmt::format("{}/default", infoName)).Publish();
integerValueEntry.SetDefault(event.value);
minPublisher.Set(cs::GetPropertyMin(event.propertyHandle, &status));
maxPublisher.Set(cs::GetPropertyMax(event.propertyHandle, &status));
stepPublisher.Set(cs::GetPropertyStep(event.propertyHandle, &status));
defaultPublisher.Set(
cs::GetPropertyDefault(event.propertyHandle, &status));
break;
case CS_PROP_STRING:
stringValueEntry = table.GetStringTopic(name).GetEntry("");
stringValueEntry.SetDefault(event.valueStr);
break;
default:
break;
}
}
void PropertyPublisher::Update(const cs::VideoEvent& event) {
switch (event.propertyKind) {
case CS_PROP_BOOLEAN:
if (booleanValueEntry) {
booleanValueEntry.Set(event.value != 0);
}
break;
case CS_PROP_INTEGER:
case CS_PROP_ENUM:
if (isNew) {
entry.SetDefaultDouble(event.value);
table->GetEntry(infoName + "/min")
.SetDouble(cs::GetPropertyMin(event.propertyHandle, &status));
table->GetEntry(infoName + "/max")
.SetDouble(cs::GetPropertyMax(event.propertyHandle, &status));
table->GetEntry(infoName + "/step")
.SetDouble(cs::GetPropertyStep(event.propertyHandle, &status));
table->GetEntry(infoName + "/default")
.SetDouble(cs::GetPropertyDefault(event.propertyHandle, &status));
} else {
entry.SetDouble(event.value);
if (integerValueEntry) {
integerValueEntry.Set(event.value);
}
break;
case CS_PROP_STRING:
if (isNew) {
entry.SetDefaultString(event.valueStr);
} else {
entry.SetString(event.valueStr);
if (stringValueEntry) {
stringValueEntry.Set(event.valueStr);
}
break;
default:
@@ -301,7 +345,29 @@ static void PutSourcePropertyValue(nt::NetworkTable* table,
}
}
CameraServer::Impl::Impl() : m_nextPort(kBasePort) {
SourcePublisher::SourcePublisher(Instance& inst,
std::shared_ptr<nt::NetworkTable> table,
CS_Source source)
: table{table},
sourcePublisher{table->GetStringTopic("source").Publish()},
descriptionPublisher{table->GetStringTopic("description").Publish()},
connectedPublisher{table->GetBooleanTopic("connected").Publish()},
streamsPublisher{table->GetStringArrayTopic("streams").Publish()},
modeEntry{table->GetStringTopic("mode").GetEntry("")},
modesPublisher{table->GetStringArrayTopic("modes").Publish()} {
CS_Status status = 0;
wpi::SmallString<64> buf;
sourcePublisher.Set(MakeSourceValue(source, buf));
wpi::SmallString<64> descBuf;
descriptionPublisher.Set(cs::GetSourceDescription(source, descBuf, &status));
connectedPublisher.Set(cs::IsSourceConnected(source, &status));
streamsPublisher.Set(inst.GetSourceStreamValues(source));
auto mode = cs::GetSourceVideoMode(source, &status);
modeEntry.SetDefault(VideoModeToString(mode));
modesPublisher.Set(GetSourceModeValues(source));
}
Instance::Instance() {
// We publish sources to NetworkTables using the following structure:
// "/CameraPublisher/{Source.Name}/" - root
// - "source" (string): Descriptive, prefixed with type (e.g. "usb:0")
@@ -315,201 +381,110 @@ CameraServer::Impl::Impl() : m_nextPort(kBasePort) {
// Listener for video events
m_videoListener = cs::VideoListener{
[=](const cs::VideoEvent& event) {
[=, this](const cs::VideoEvent& event) {
std::scoped_lock lock(m_mutex);
CS_Status status = 0;
switch (event.kind) {
case cs::VideoEvent::kSourceCreated: {
// Create subtable for the camera
auto table = m_publishTable->GetSubTable(event.name);
{
std::scoped_lock lock(m_mutex);
m_tables.insert(std::make_pair(event.sourceHandle, table));
}
wpi::SmallString<64> buf;
table->GetEntry("source").SetString(
MakeSourceValue(event.sourceHandle, buf));
wpi::SmallString<64> descBuf;
table->GetEntry("description")
.SetString(cs::GetSourceDescription(event.sourceHandle, descBuf,
&status));
table->GetEntry("connected")
.SetBoolean(cs::IsSourceConnected(event.sourceHandle, &status));
table->GetEntry("streams").SetStringArray(
GetSourceStreamValues(event.sourceHandle));
auto mode = cs::GetSourceVideoMode(event.sourceHandle, &status);
table->GetEntry("mode").SetDefaultString(VideoModeToString(mode));
table->GetEntry("modes").SetStringArray(
GetSourceModeValues(event.sourceHandle));
m_publishers.insert(
{event.sourceHandle,
SourcePublisher{*this, table, event.sourceHandle}});
break;
}
case cs::VideoEvent::kSourceDestroyed: {
auto table = GetSourceTable(event.sourceHandle);
if (table) {
table->GetEntry("source").SetString("");
table->GetEntry("streams").SetStringArray(
std::vector<std::string>{});
table->GetEntry("modes").SetStringArray(
std::vector<std::string>{});
}
case cs::VideoEvent::kSourceDestroyed:
m_publishers.erase(event.sourceHandle);
break;
}
case cs::VideoEvent::kSourceConnected: {
auto table = GetSourceTable(event.sourceHandle);
if (table) {
case cs::VideoEvent::kSourceConnected:
if (auto publisher = GetPublisher(event.sourceHandle)) {
// update the description too (as it may have changed)
wpi::SmallString<64> descBuf;
table->GetEntry("description")
.SetString(cs::GetSourceDescription(event.sourceHandle,
descBuf, &status));
table->GetEntry("connected").SetBoolean(true);
publisher->descriptionPublisher.Set(cs::GetSourceDescription(
event.sourceHandle, descBuf, &status));
publisher->connectedPublisher.Set(true);
}
break;
}
case cs::VideoEvent::kSourceDisconnected: {
auto table = GetSourceTable(event.sourceHandle);
if (table) {
table->GetEntry("connected").SetBoolean(false);
case cs::VideoEvent::kSourceDisconnected:
if (auto publisher = GetPublisher(event.sourceHandle)) {
publisher->connectedPublisher.Set(false);
}
break;
}
case cs::VideoEvent::kSourceVideoModesUpdated: {
auto table = GetSourceTable(event.sourceHandle);
if (table) {
table->GetEntry("modes").SetStringArray(
case cs::VideoEvent::kSourceVideoModesUpdated:
if (auto publisher = GetPublisher(event.sourceHandle)) {
publisher->modesPublisher.Set(
GetSourceModeValues(event.sourceHandle));
}
break;
}
case cs::VideoEvent::kSourceVideoModeChanged: {
auto table = GetSourceTable(event.sourceHandle);
if (table) {
table->GetEntry("mode").SetString(VideoModeToString(event.mode));
case cs::VideoEvent::kSourceVideoModeChanged:
if (auto publisher = GetPublisher(event.sourceHandle)) {
publisher->modeEntry.Set(VideoModeToString(event.mode));
}
break;
}
case cs::VideoEvent::kSourcePropertyCreated: {
auto table = GetSourceTable(event.sourceHandle);
if (table) {
PutSourcePropertyValue(table.get(), event, true);
case cs::VideoEvent::kSourcePropertyCreated:
if (auto publisher = GetPublisher(event.sourceHandle)) {
publisher->properties.insert(
{event.propertyHandle,
PropertyPublisher{*publisher->table, event}});
}
break;
}
case cs::VideoEvent::kSourcePropertyValueUpdated: {
auto table = GetSourceTable(event.sourceHandle);
if (table) {
PutSourcePropertyValue(table.get(), event, false);
case cs::VideoEvent::kSourcePropertyValueUpdated:
if (auto publisher = GetPublisher(event.sourceHandle)) {
auto ppIt = publisher->properties.find(event.propertyHandle);
if (ppIt != publisher->properties.end()) {
ppIt->second.Update(event);
}
}
break;
}
case cs::VideoEvent::kSourcePropertyChoicesUpdated: {
auto table = GetSourceTable(event.sourceHandle);
if (table) {
wpi::SmallString<64> name{"PropertyInfo/"};
name += event.name;
name += "/choices";
auto choices =
cs::GetEnumPropertyChoices(event.propertyHandle, &status);
table->GetEntry(name).SetStringArray(choices);
case cs::VideoEvent::kSourcePropertyChoicesUpdated:
if (auto publisher = GetPublisher(event.sourceHandle)) {
auto ppIt = publisher->properties.find(event.propertyHandle);
if (ppIt != publisher->properties.end() &&
ppIt->second.choicesTopic) {
auto choices =
cs::GetEnumPropertyChoices(event.propertyHandle, &status);
if (!ppIt->second.choicesPublisher) {
ppIt->second.choicesPublisher =
ppIt->second.choicesTopic.Publish();
}
ppIt->second.choicesPublisher.Set(choices);
}
}
break;
}
case cs::VideoEvent::kSinkSourceChanged:
case cs::VideoEvent::kSinkCreated:
case cs::VideoEvent::kSinkDestroyed:
case cs::VideoEvent::kNetworkInterfacesChanged: {
case cs::VideoEvent::kNetworkInterfacesChanged:
m_addresses = cs::GetNetworkInterfaces();
UpdateStreamValues();
break;
}
default:
break;
}
},
0x4fff, true};
// Listener for NetworkTable events
// We don't currently support changing settings via NT due to
// synchronization issues, so just update to current setting if someone
// else tries to change it.
wpi::SmallString<64> buf;
m_tableListener = nt::NetworkTableInstance::GetDefault().AddEntryListener(
kPublishName + wpi::Twine('/'),
[=](const nt::EntryNotification& event) {
wpi::StringRef relativeKey =
event.name.substr(wpi::StringRef(kPublishName).size() + 1);
// get source (sourceName/...)
auto subKeyIndex = relativeKey.find('/');
if (subKeyIndex == wpi::StringRef::npos) {
return;
}
wpi::StringRef sourceName = relativeKey.slice(0, subKeyIndex);
auto sourceIt = m_sources.find(sourceName);
if (sourceIt == m_sources.end()) {
return;
}
// get subkey
relativeKey = relativeKey.substr(subKeyIndex + 1);
// handle standard names
wpi::StringRef propName;
nt::NetworkTableEntry entry{event.entry};
if (relativeKey == "mode") {
// reset to current mode
entry.SetString(VideoModeToString(sourceIt->second.GetVideoMode()));
return;
} else if (relativeKey.startswith("Property/")) {
propName = relativeKey.substr(9);
} else if (relativeKey.startswith("RawProperty/")) {
propName = relativeKey.substr(12);
} else {
return; // ignore
}
// everything else is a property
auto property = sourceIt->second.GetProperty(propName);
switch (property.GetKind()) {
case cs::VideoProperty::kNone:
return;
case cs::VideoProperty::kBoolean:
entry.SetBoolean(property.Get() != 0);
return;
case cs::VideoProperty::kInteger:
case cs::VideoProperty::kEnum:
entry.SetDouble(property.Get());
return;
case cs::VideoProperty::kString:
entry.SetString(property.GetString());
return;
default:
return;
}
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_UPDATE);
}
CameraServer::CameraServer() : m_impl(new Impl) {}
CameraServer::~CameraServer() = default;
cs::UsbCamera CameraServer::StartAutomaticCapture() {
cs::UsbCamera camera = StartAutomaticCapture(m_impl->m_defaultUsbDevice++);
cs::UsbCamera camera =
StartAutomaticCapture(::GetInstance().m_defaultUsbDevice++);
auto csShared = GetCameraServerShared();
csShared->ReportUsbCamera(camera.GetHandle());
return camera;
}
cs::UsbCamera CameraServer::StartAutomaticCapture(int dev) {
cs::UsbCamera camera{"USB Camera " + wpi::Twine(dev), dev};
::GetInstance();
cs::UsbCamera camera{fmt::format("USB Camera {}", dev), dev};
StartAutomaticCapture(camera);
auto csShared = GetCameraServerShared();
csShared->ReportUsbCamera(camera.GetHandle());
return camera;
}
cs::UsbCamera CameraServer::StartAutomaticCapture(const wpi::Twine& name,
cs::UsbCamera CameraServer::StartAutomaticCapture(std::string_view name,
int dev) {
::GetInstance();
cs::UsbCamera camera{name, dev};
StartAutomaticCapture(camera);
auto csShared = GetCameraServerShared();
@@ -517,8 +492,9 @@ cs::UsbCamera CameraServer::StartAutomaticCapture(const wpi::Twine& name,
return camera;
}
cs::UsbCamera CameraServer::StartAutomaticCapture(const wpi::Twine& name,
const wpi::Twine& path) {
cs::UsbCamera CameraServer::StartAutomaticCapture(std::string_view name,
std::string_view path) {
::GetInstance();
cs::UsbCamera camera{name, path};
StartAutomaticCapture(camera);
auto csShared = GetCameraServerShared();
@@ -526,7 +502,7 @@ cs::UsbCamera CameraServer::StartAutomaticCapture(const wpi::Twine& name,
return camera;
}
cs::AxisCamera CameraServer::AddAxisCamera(const wpi::Twine& host) {
cs::AxisCamera CameraServer::AddAxisCamera(std::string_view host) {
return AddAxisCamera("Axis Camera", host);
}
@@ -538,12 +514,13 @@ cs::AxisCamera CameraServer::AddAxisCamera(const std::string& host) {
return AddAxisCamera("Axis Camera", host);
}
cs::AxisCamera CameraServer::AddAxisCamera(wpi::ArrayRef<std::string> hosts) {
cs::AxisCamera CameraServer::AddAxisCamera(std::span<const std::string> hosts) {
return AddAxisCamera("Axis Camera", hosts);
}
cs::AxisCamera CameraServer::AddAxisCamera(const wpi::Twine& name,
const wpi::Twine& host) {
cs::AxisCamera CameraServer::AddAxisCamera(std::string_view name,
std::string_view host) {
::GetInstance();
cs::AxisCamera camera{name, host};
StartAutomaticCapture(camera);
auto csShared = GetCameraServerShared();
@@ -551,8 +528,9 @@ cs::AxisCamera CameraServer::AddAxisCamera(const wpi::Twine& name,
return camera;
}
cs::AxisCamera CameraServer::AddAxisCamera(const wpi::Twine& name,
cs::AxisCamera CameraServer::AddAxisCamera(std::string_view name,
const char* host) {
::GetInstance();
cs::AxisCamera camera{name, host};
StartAutomaticCapture(camera);
auto csShared = GetCameraServerShared();
@@ -560,8 +538,9 @@ cs::AxisCamera CameraServer::AddAxisCamera(const wpi::Twine& name,
return camera;
}
cs::AxisCamera CameraServer::AddAxisCamera(const wpi::Twine& name,
cs::AxisCamera CameraServer::AddAxisCamera(std::string_view name,
const std::string& host) {
::GetInstance();
cs::AxisCamera camera{name, host};
StartAutomaticCapture(camera);
auto csShared = GetCameraServerShared();
@@ -569,8 +548,9 @@ cs::AxisCamera CameraServer::AddAxisCamera(const wpi::Twine& name,
return camera;
}
cs::AxisCamera CameraServer::AddAxisCamera(const wpi::Twine& name,
wpi::ArrayRef<std::string> hosts) {
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();
@@ -578,11 +558,12 @@ cs::AxisCamera CameraServer::AddAxisCamera(const wpi::Twine& name,
return camera;
}
cs::MjpegServer CameraServer::AddSwitchedCamera(const wpi::Twine& 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);
m_impl->m_fixedSources[server.GetHandle()] = source.GetHandle();
inst.m_fixedSources[server.GetHandle()] = source.GetHandle();
return server;
}
@@ -590,22 +571,23 @@ cs::MjpegServer CameraServer::AddSwitchedCamera(const wpi::Twine& name) {
cs::MjpegServer CameraServer::StartAutomaticCapture(
const cs::VideoSource& camera) {
AddCamera(camera);
auto server = AddServer(wpi::Twine("serve_") + camera.GetName());
auto server = AddServer(fmt::format("serve_{}", camera.GetName()));
server.SetSource(camera);
return server;
}
cs::CvSink CameraServer::GetVideo() {
auto& inst = ::GetInstance();
cs::VideoSource source;
{
auto csShared = GetCameraServerShared();
std::scoped_lock lock(m_impl->m_mutex);
if (m_impl->m_primarySourceName.empty()) {
std::scoped_lock lock(inst.m_mutex);
if (inst.m_primarySourceName.empty()) {
csShared->SetCameraServerError("no camera available");
return cs::CvSink{};
}
auto it = m_impl->m_sources.find(m_impl->m_primarySourceName);
if (it == m_impl->m_sources.end()) {
auto it = inst.m_sources.find(inst.m_primarySourceName);
if (it == inst.m_sources.end()) {
csShared->SetCameraServerError("no camera available");
return cs::CvSink{};
}
@@ -615,40 +597,40 @@ cs::CvSink CameraServer::GetVideo() {
}
cs::CvSink CameraServer::GetVideo(const cs::VideoSource& camera) {
auto& inst = ::GetInstance();
wpi::SmallString<64> name{"opencv_"};
name += camera.GetName();
{
std::scoped_lock lock(m_impl->m_mutex);
auto it = m_impl->m_sinks.find(name);
if (it != m_impl->m_sinks.end()) {
std::scoped_lock lock(inst.m_mutex);
auto it = inst.m_sinks.find(name);
if (it != inst.m_sinks.end()) {
auto kind = it->second.GetKind();
if (kind != cs::VideoSink::kCv) {
auto csShared = GetCameraServerShared();
csShared->SetCameraServerError("expected OpenCV sink, but got " +
wpi::Twine(kind));
csShared->SetCameraServerError("expected OpenCV sink, but got {}",
static_cast<int>(kind));
return cs::CvSink{};
}
return *static_cast<cs::CvSink*>(&it->second);
}
}
cs::CvSink newsink{name};
cs::CvSink newsink{name.str()};
newsink.SetSource(camera);
AddServer(newsink);
return newsink;
}
cs::CvSink CameraServer::GetVideo(const wpi::Twine& name) {
wpi::SmallString<64> nameBuf;
wpi::StringRef nameStr = name.toStringRef(nameBuf);
cs::CvSink CameraServer::GetVideo(std::string_view name) {
auto& inst = ::GetInstance();
cs::VideoSource source;
{
std::scoped_lock lock(m_impl->m_mutex);
auto it = m_impl->m_sources.find(nameStr);
if (it == m_impl->m_sources.end()) {
std::scoped_lock lock(inst.m_mutex);
auto it = inst.m_sources.find(name);
if (it == inst.m_sources.end()) {
auto csShared = GetCameraServerShared();
csShared->SetCameraServerError("could not find camera " + nameStr);
csShared->SetCameraServerError("could not find camera {}", name);
return cs::CvSink{};
}
source = it->second;
@@ -656,89 +638,94 @@ cs::CvSink CameraServer::GetVideo(const wpi::Twine& name) {
return GetVideo(source);
}
cs::CvSource CameraServer::PutVideo(const wpi::Twine& name, int width,
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;
}
cs::MjpegServer CameraServer::AddServer(const wpi::Twine& name) {
cs::MjpegServer CameraServer::AddServer(std::string_view name) {
auto& inst = ::GetInstance();
int port;
{
std::scoped_lock lock(m_impl->m_mutex);
port = m_impl->m_nextPort++;
std::scoped_lock lock(inst.m_mutex);
port = inst.m_nextPort++;
}
return AddServer(name, port);
}
cs::MjpegServer CameraServer::AddServer(const wpi::Twine& name, int port) {
cs::MjpegServer CameraServer::AddServer(std::string_view name, int port) {
::GetInstance();
cs::MjpegServer server{name, port};
AddServer(server);
return server;
}
void CameraServer::AddServer(const cs::VideoSink& server) {
std::scoped_lock lock(m_impl->m_mutex);
m_impl->m_sinks.try_emplace(server.GetName(), server);
auto& inst = ::GetInstance();
std::scoped_lock lock(inst.m_mutex);
inst.m_sinks.try_emplace(server.GetName(), server);
}
void CameraServer::RemoveServer(const wpi::Twine& name) {
std::scoped_lock lock(m_impl->m_mutex);
wpi::SmallString<64> nameBuf;
m_impl->m_sinks.erase(name.toStringRef(nameBuf));
void CameraServer::RemoveServer(std::string_view name) {
auto& inst = ::GetInstance();
std::scoped_lock lock(inst.m_mutex);
inst.m_sinks.erase(name);
}
cs::VideoSink CameraServer::GetServer() {
wpi::SmallString<64> name;
auto& inst = ::GetInstance();
std::string name;
{
std::scoped_lock lock(m_impl->m_mutex);
if (m_impl->m_primarySourceName.empty()) {
std::scoped_lock lock(inst.m_mutex);
if (inst.m_primarySourceName.empty()) {
auto csShared = GetCameraServerShared();
csShared->SetCameraServerError("no camera available");
return cs::VideoSink{};
}
name = "serve_";
name += m_impl->m_primarySourceName;
name = fmt::format("serve_{}", inst.m_primarySourceName);
}
return GetServer(name);
}
cs::VideoSink CameraServer::GetServer(const wpi::Twine& name) {
wpi::SmallString<64> nameBuf;
wpi::StringRef nameStr = name.toStringRef(nameBuf);
std::scoped_lock lock(m_impl->m_mutex);
auto it = m_impl->m_sinks.find(nameStr);
if (it == m_impl->m_sinks.end()) {
cs::VideoSink CameraServer::GetServer(std::string_view name) {
auto& inst = ::GetInstance();
std::scoped_lock lock(inst.m_mutex);
auto it = inst.m_sinks.find(name);
if (it == inst.m_sinks.end()) {
auto csShared = GetCameraServerShared();
csShared->SetCameraServerError("could not find server " + nameStr);
csShared->SetCameraServerError("could not find server {}", name);
return cs::VideoSink{};
}
return it->second;
}
void CameraServer::AddCamera(const cs::VideoSource& camera) {
auto& inst = ::GetInstance();
std::string name = camera.GetName();
std::scoped_lock lock(m_impl->m_mutex);
if (m_impl->m_primarySourceName.empty()) {
m_impl->m_primarySourceName = name;
std::scoped_lock lock(inst.m_mutex);
if (inst.m_primarySourceName.empty()) {
inst.m_primarySourceName = name;
}
m_impl->m_sources.try_emplace(name, camera);
inst.m_sources.try_emplace(name, camera);
}
void CameraServer::RemoveCamera(const wpi::Twine& name) {
std::scoped_lock lock(m_impl->m_mutex);
wpi::SmallString<64> nameBuf;
m_impl->m_sources.erase(name.toStringRef(nameBuf));
void CameraServer::RemoveCamera(std::string_view name) {
auto& inst = ::GetInstance();
std::scoped_lock lock(inst.m_mutex);
inst.m_sources.erase(name);
}
void CameraServer::SetSize(int size) {
std::scoped_lock lock(m_impl->m_mutex);
if (m_impl->m_primarySourceName.empty()) {
auto& inst = ::GetInstance();
std::scoped_lock lock(inst.m_mutex);
if (inst.m_primarySourceName.empty()) {
return;
}
auto it = m_impl->m_sources.find(m_impl->m_primarySourceName);
if (it == m_impl->m_sources.end()) {
auto it = inst.m_sources.find(inst.m_primarySourceName);
if (it == inst.m_sources.end()) {
return;
}
if (size == kSize160x120) {

View File

@@ -12,9 +12,12 @@ class DefaultCameraServerShared : public frc::CameraServerShared {
void ReportUsbCamera(int id) override {}
void ReportAxisCamera(int id) override {}
void ReportVideoServer(int id) override {}
void SetCameraServerError(const wpi::Twine& error) override {}
void SetVisionRunnerError(const wpi::Twine& error) override {}
void ReportDriverStationError(const wpi::Twine& error) override {}
void SetCameraServerErrorV(fmt::string_view format,
fmt::format_args args) override {}
void SetVisionRunnerErrorV(fmt::string_view format,
fmt::format_args args) override {}
void ReportDriverStationErrorV(fmt::string_view format,
fmt::format_args args) override {}
std::pair<std::thread::id, bool> GetRobotMainThreadId() const override {
return std::make_pair(std::thread::id(), false);
}

View File

@@ -33,7 +33,7 @@ void VisionRunnerBase::RunOnce() {
auto frameTime = m_cvSink.GrabFrame(*m_image);
if (frameTime == 0) {
auto error = m_cvSink.GetError();
csShared->ReportDriverStationError(error);
csShared->ReportDriverStationError(error.c_str());
} else {
DoProcess(*m_image);
}

View File

@@ -6,11 +6,9 @@
#include <stdint.h>
#include <memory>
#include <span>
#include <string>
#include <wpi/ArrayRef.h>
#include <wpi/Twine.h>
#include <string_view>
#include "cscore.h"
#include "cscore_cv.h"
@@ -29,11 +27,6 @@ class CameraServer {
static constexpr int kSize320x240 = 1;
static constexpr int kSize160x120 = 2;
/**
* Get the CameraServer instance.
*/
static CameraServer* GetInstance();
/**
* Start automatically capturing images to send to the dashboard.
*
@@ -45,7 +38,7 @@ class CameraServer {
* with device 0, creating a camera named "USB Camera 0". Subsequent calls
* increment the device number (e.g. 1, 2, etc).
*/
cs::UsbCamera StartAutomaticCapture();
static cs::UsbCamera StartAutomaticCapture();
/**
* Start automatically capturing images to send to the dashboard.
@@ -55,7 +48,7 @@ class CameraServer {
*
* @param dev The device number of the camera interface
*/
cs::UsbCamera StartAutomaticCapture(int dev);
static cs::UsbCamera StartAutomaticCapture(int dev);
/**
* Start automatically capturing images to send to the dashboard.
@@ -63,7 +56,7 @@ class CameraServer {
* @param name The name to give the camera
* @param dev The device number of the camera interface
*/
cs::UsbCamera StartAutomaticCapture(const wpi::Twine& name, int dev);
static cs::UsbCamera StartAutomaticCapture(std::string_view name, int dev);
/**
* Start automatically capturing images to send to the dashboard.
@@ -71,8 +64,8 @@ class CameraServer {
* @param name The name to give the camera
* @param path The device path (e.g. "/dev/video0") of the camera
*/
cs::UsbCamera StartAutomaticCapture(const wpi::Twine& name,
const wpi::Twine& path);
static cs::UsbCamera StartAutomaticCapture(std::string_view name,
std::string_view path);
/**
* Start automatically capturing images to send to the dashboard from
@@ -80,7 +73,7 @@ class CameraServer {
*
* @param camera Camera
*/
cs::MjpegServer StartAutomaticCapture(const cs::VideoSource& camera);
static cs::MjpegServer StartAutomaticCapture(const cs::VideoSource& camera);
/**
* Adds an Axis IP camera.
@@ -89,7 +82,7 @@ class CameraServer {
*
* @param host Camera host IP or DNS name (e.g. "10.x.y.11")
*/
cs::AxisCamera AddAxisCamera(const wpi::Twine& host);
static cs::AxisCamera AddAxisCamera(std::string_view host);
/**
* Adds an Axis IP camera.
@@ -98,7 +91,7 @@ class CameraServer {
*
* @param host Camera host IP or DNS name (e.g. "10.x.y.11")
*/
cs::AxisCamera AddAxisCamera(const char* host);
static cs::AxisCamera AddAxisCamera(const char* host);
/**
* Adds an Axis IP camera.
@@ -107,7 +100,7 @@ class CameraServer {
*
* @param host Camera host IP or DNS name (e.g. "10.x.y.11")
*/
cs::AxisCamera AddAxisCamera(const std::string& host);
static cs::AxisCamera AddAxisCamera(const std::string& host);
/**
* Adds an Axis IP camera.
@@ -116,7 +109,7 @@ class CameraServer {
*
* @param hosts Array of Camera host IPs/DNS names
*/
cs::AxisCamera AddAxisCamera(wpi::ArrayRef<std::string> hosts);
static cs::AxisCamera AddAxisCamera(std::span<const std::string> hosts);
/**
* Adds an Axis IP camera.
@@ -126,7 +119,7 @@ class CameraServer {
* @param hosts Array of Camera host IPs/DNS names
*/
template <typename T>
cs::AxisCamera AddAxisCamera(std::initializer_list<T> hosts);
static cs::AxisCamera AddAxisCamera(std::initializer_list<T> hosts);
/**
* Adds an Axis IP camera.
@@ -134,7 +127,8 @@ class CameraServer {
* @param name The name to give the camera
* @param host Camera host IP or DNS name (e.g. "10.x.y.11")
*/
cs::AxisCamera AddAxisCamera(const wpi::Twine& name, const wpi::Twine& host);
static cs::AxisCamera AddAxisCamera(std::string_view name,
std::string_view host);
/**
* Adds an Axis IP camera.
@@ -142,7 +136,7 @@ class CameraServer {
* @param name The name to give the camera
* @param host Camera host IP or DNS name (e.g. "10.x.y.11")
*/
cs::AxisCamera AddAxisCamera(const wpi::Twine& name, const char* host);
static cs::AxisCamera AddAxisCamera(std::string_view name, const char* host);
/**
* Adds an Axis IP camera.
@@ -150,7 +144,8 @@ class CameraServer {
* @param name The name to give the camera
* @param host Camera host IP or DNS name (e.g. "10.x.y.11")
*/
cs::AxisCamera AddAxisCamera(const wpi::Twine& name, const std::string& host);
static cs::AxisCamera AddAxisCamera(std::string_view name,
const std::string& host);
/**
* Adds an Axis IP camera.
@@ -158,8 +153,8 @@ class CameraServer {
* @param name The name to give the camera
* @param hosts Array of Camera host IPs/DNS names
*/
cs::AxisCamera AddAxisCamera(const wpi::Twine& name,
wpi::ArrayRef<std::string> hosts);
static cs::AxisCamera AddAxisCamera(std::string_view name,
std::span<const std::string> hosts);
/**
* Adds an Axis IP camera.
@@ -168,8 +163,8 @@ class CameraServer {
* @param hosts Array of Camera host IPs/DNS names
*/
template <typename T>
cs::AxisCamera AddAxisCamera(const wpi::Twine& name,
std::initializer_list<T> hosts);
static cs::AxisCamera AddAxisCamera(std::string_view name,
std::initializer_list<T> hosts);
/**
* Adds a virtual camera for switching between two streams. Unlike the
@@ -177,7 +172,7 @@ class CameraServer {
* VideoSource. Calling SetSource() on the returned object can be used
* to switch the actual source of the stream.
*/
cs::MjpegServer AddSwitchedCamera(const wpi::Twine& name);
static cs::MjpegServer AddSwitchedCamera(std::string_view name);
/**
* Get OpenCV access to the primary camera feed. This allows you to
@@ -186,7 +181,7 @@ class CameraServer {
* <p>This is only valid to call after a camera feed has been added
* with startAutomaticCapture() or addServer().
*/
cs::CvSink GetVideo();
static cs::CvSink GetVideo();
/**
* Get OpenCV access to the specified camera. This allows you to get
@@ -194,7 +189,7 @@ class CameraServer {
*
* @param camera Camera (e.g. as returned by startAutomaticCapture).
*/
cs::CvSink GetVideo(const cs::VideoSource& camera);
static cs::CvSink GetVideo(const cs::VideoSource& camera);
/**
* Get OpenCV access to the specified camera. This allows you to get
@@ -202,7 +197,7 @@ class CameraServer {
*
* @param name Camera name
*/
cs::CvSink GetVideo(const wpi::Twine& name);
static cs::CvSink GetVideo(std::string_view name);
/**
* Create a MJPEG stream with OpenCV input. This can be called to pass custom
@@ -212,35 +207,36 @@ class CameraServer {
* @param width Width of the image being sent
* @param height Height of the image being sent
*/
cs::CvSource PutVideo(const wpi::Twine& name, int width, int height);
static cs::CvSource PutVideo(std::string_view name, int width, int height);
/**
* Adds a MJPEG server at the next available port.
*
* @param name Server name
*/
cs::MjpegServer AddServer(const wpi::Twine& name);
static cs::MjpegServer AddServer(std::string_view name);
/**
* Adds a MJPEG server.
*
* @param name Server name
* @param port Port number
*/
cs::MjpegServer AddServer(const wpi::Twine& name, int port);
static cs::MjpegServer AddServer(std::string_view name, int port);
/**
* Adds an already created server.
*
* @param server Server
*/
void AddServer(const cs::VideoSink& server);
static void AddServer(const cs::VideoSink& server);
/**
* Removes a server by name.
*
* @param name Server name
*/
void RemoveServer(const wpi::Twine& name);
static void RemoveServer(std::string_view name);
/**
* Get server for the primary camera feed.
@@ -248,28 +244,28 @@ class CameraServer {
* This is only valid to call after a camera feed has been added with
* StartAutomaticCapture() or AddServer().
*/
cs::VideoSink GetServer();
static cs::VideoSink GetServer();
/**
* Gets a server by name.
*
* @param name Server name
*/
cs::VideoSink GetServer(const wpi::Twine& name);
static cs::VideoSink GetServer(std::string_view name);
/**
* Adds an already created camera.
*
* @param camera Camera
*/
void AddCamera(const cs::VideoSource& camera);
static void AddCamera(const cs::VideoSource& camera);
/**
* Removes a camera by name.
*
* @param name Camera name
*/
void RemoveCamera(const wpi::Twine& name);
static void RemoveCamera(std::string_view name);
/**
* Sets the size of the image to use. Use the public kSize constants to set
@@ -280,14 +276,10 @@ class CameraServer {
* StartAutomaticCapture() instead.
* @param size The size to use
*/
void SetSize(int size);
static void SetSize(int size);
private:
CameraServer();
~CameraServer();
struct Impl;
std::unique_ptr<Impl> m_impl;
CameraServer() = default;
};
} // namespace frc

View File

@@ -19,7 +19,7 @@ inline cs::AxisCamera CameraServer::AddAxisCamera(
template <typename T>
inline cs::AxisCamera CameraServer::AddAxisCamera(
const wpi::Twine& name, std::initializer_list<T> hosts) {
std::string_view name, std::initializer_list<T> hosts) {
std::vector<std::string> vec;
vec.reserve(hosts.size());
for (const auto& host : hosts) {

View File

@@ -8,7 +8,7 @@
#include <thread>
#include <utility>
#include <wpi/Twine.h>
#include <fmt/format.h>
namespace frc {
class CameraServerShared {
@@ -17,10 +17,28 @@ class CameraServerShared {
virtual void ReportUsbCamera(int id) = 0;
virtual void ReportAxisCamera(int id) = 0;
virtual void ReportVideoServer(int id) = 0;
virtual void SetCameraServerError(const wpi::Twine& error) = 0;
virtual void SetVisionRunnerError(const wpi::Twine& error) = 0;
virtual void ReportDriverStationError(const wpi::Twine& error) = 0;
virtual void SetCameraServerErrorV(fmt::string_view format,
fmt::format_args args) = 0;
virtual void SetVisionRunnerErrorV(fmt::string_view format,
fmt::format_args args) = 0;
virtual void ReportDriverStationErrorV(fmt::string_view format,
fmt::format_args args) = 0;
virtual std::pair<std::thread::id, bool> GetRobotMainThreadId() const = 0;
template <typename S, typename... Args>
inline void SetCameraServerError(const S& format, Args&&... args) {
SetCameraServerErrorV(format, fmt::make_format_args(args...));
}
template <typename S, typename... Args>
inline void SetVisionRunnerError(const S& format, Args&&... args) {
SetVisionRunnerErrorV(format, fmt::make_format_args(args...));
}
template <typename S, typename... Args>
inline void ReportDriverStationError(const S& format, Args&&... args) {
ReportDriverStationErrorV(format, fmt::make_format_args(args...));
}
};
CameraServerShared* GetCameraServerShared();

View File

@@ -44,14 +44,14 @@ class VisionRunnerBase {
*
* <p>This method is exposed to allow teams to add additional functionality or
* have their own ways to run the pipeline. Most teams, however, should just
* use {@link #runForever} in its own thread using a std::thread.</p>
* use RunForever() in its own thread using a std::thread.</p>
*/
void RunOnce();
/**
* A convenience method that calls {@link #runOnce()} in an infinite loop.
* This must be run in a dedicated thread, and cannot be used in the main
* robot thread because it will freeze the robot program.
* A convenience method that calls runOnce() in an infinite loop. This must be
* run in a dedicated thread, and cannot be used in the main robot thread
* because it will freeze the robot program.
*
* <strong>Do not call this method directly from the main thread.</strong>
*/

View File

@@ -8,7 +8,7 @@ macro(wpilib_add_test name srcdir)
target_compile_definitions(${name}_test PRIVATE -DGTEST_LINKED_AS_SHARED_LIBRARY)
endif()
if (MSVC)
target_compile_options(${name}_test PRIVATE /wd4251 /wd4101)
target_compile_options(${name}_test PRIVATE /wd4101 /wd4251)
endif()
add_test(NAME ${name} COMMAND ${name}_test)
endmacro()

View File

@@ -1,7 +1,15 @@
macro(wpilib_target_warnings target)
if(NOT MSVC)
target_compile_options(${target} PRIVATE -Wall -pedantic -Wextra -Werror -Wno-unused-parameter -Wno-error=deprecated-declarations)
target_compile_options(${target} PRIVATE -Wall -pedantic -Wextra -Werror -Wno-unused-parameter ${WPILIB_TARGET_WARNINGS})
else()
target_compile_options(${target} PRIVATE /wd4244 /wd4267 /wd4146 /WX /wd4996)
target_compile_options(${target} PRIVATE /wd4146 /wd4244 /wd4251 /wd4267 /WX /D_CRT_SECURE_NO_WARNINGS ${WPILIB_TARGET_WARNINGS})
endif()
# Suppress C++-specific OpenCV warning; C compiler rejects it with an error
# https://github.com/opencv/opencv/issues/20269
if(UNIX AND NOT APPLE)
target_compile_options(${target} PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-Wno-deprecated-enum-enum-conversion>)
elseif(UNIX AND APPLE)
target_compile_options(${target} PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-Wno-deprecated-anon-enum-enum-conversion>)
endif()
endmacro()

View File

@@ -0,0 +1,116 @@
# - Try to find LibSSH
# Once done this will define
#
# LIBSSH_FOUND - system has LibSSH
# LIBSSH_INCLUDE_DIRS - the LibSSH include directory
# LIBSSH_LIBRARIES - link these to use LibSSH
# LIBSSH_VERSION -
#
# Author Michal Vasko <mvasko@cesnet.cz>
# Copyright (c) 2020 CESNET, z.s.p.o.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1. Redistributions of source code must retain the copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
#
include(FindPackageHandleStandardArgs)
if(LIBSSH_LIBRARIES AND LIBSSH_INCLUDE_DIRS)
# in cache already
set(LIBSSH_FOUND TRUE)
else()
find_path(LIBSSH_INCLUDE_DIR
NAMES
libssh/libssh.h
PATHS
/usr/include
/usr/local/include
/opt/local/include
/sw/include
${CMAKE_INCLUDE_PATH}
${CMAKE_INSTALL_PREFIX}/include
)
find_library(LIBSSH_LIBRARY
NAMES
ssh.so
libssh.so
libssh.dylib
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
/sw/lib
${CMAKE_LIBRARY_PATH}
${CMAKE_INSTALL_PREFIX}/lib
)
if(LIBSSH_INCLUDE_DIR AND LIBSSH_LIBRARY)
# learn libssh version
if(EXISTS ${LIBSSH_INCLUDE_DIR}/libssh/libssh_version.h)
set(LIBSSH_HEADER_PATH ${LIBSSH_INCLUDE_DIR}/libssh/libssh_version.h)
else()
set(LIBSSH_HEADER_PATH ${LIBSSH_INCLUDE_DIR}/libssh/libssh.h)
endif()
file(STRINGS ${LIBSSH_HEADER_PATH} LIBSSH_VERSION_MAJOR
REGEX "#define[ ]+LIBSSH_VERSION_MAJOR[ ]+[0-9]+")
if(NOT LIBSSH_VERSION_MAJOR)
message(STATUS "LIBSSH_VERSION_MAJOR not found, assuming libssh is too old and cannot be used!")
set(LIBSSH_INCLUDE_DIR "LIBSSH_INCLUDE_DIR-NOTFOUND")
set(LIBSSH_LIBRARY "LIBSSH_LIBRARY-NOTFOUND")
else()
string(REGEX MATCH "[0-9]+" LIBSSH_VERSION_MAJOR ${LIBSSH_VERSION_MAJOR})
file(STRINGS ${LIBSSH_HEADER_PATH} LIBSSH_VERSION_MINOR
REGEX "#define[ ]+LIBSSH_VERSION_MINOR[ ]+[0-9]+")
string(REGEX MATCH "[0-9]+" LIBSSH_VERSION_MINOR ${LIBSSH_VERSION_MINOR})
file(STRINGS ${LIBSSH_HEADER_PATH} LIBSSH_VERSION_PATCH
REGEX "#define[ ]+LIBSSH_VERSION_MICRO[ ]+[0-9]+")
string(REGEX MATCH "[0-9]+" LIBSSH_VERSION_PATCH ${LIBSSH_VERSION_PATCH})
set(LIBSSH_VERSION ${LIBSSH_VERSION_MAJOR}.${LIBSSH_VERSION_MINOR}.${LIBSSH_VERSION_PATCH})
if(LIBSSH_VERSION VERSION_LESS 0.8.0)
# libssh_threads also needs to be linked for these versions
string(REPLACE "libssh.so" "libssh_threads.so"
LIBSSH_THREADS_LIBRARY
${LIBSSH_LIBRARY}
)
string(REPLACE "libssh.dylib" "libssh_threads.dylib"
LIBSSH_THREADS_LIBRARY
${LIBSSH_THREADS_LIBRARY}
)
string(REPLACE "ssh.so" "ssh_threads.so"
LIBSSH_THREADS_LIBRARY
${LIBSSH_THREADS_LIBRARY}
)
endif()
endif()
endif()
set(LIBSSH_INCLUDE_DIRS ${LIBSSH_INCLUDE_DIR})
set(LIBSSH_LIBRARIES ${LIBSSH_LIBRARY} ${LIBSSH_THREADS_LIBRARY})
mark_as_advanced(LIBSSH_INCLUDE_DIRS LIBSSH_LIBRARIES)
find_package_handle_standard_args(LIBSSH FOUND_VAR LIBSSH_FOUND
REQUIRED_VARS LIBSSH_INCLUDE_DIRS LIBSSH_LIBRARIES
VERSION_VAR LIBSSH_VERSION)
endif()

View File

@@ -7,7 +7,7 @@ GET_FILENAME_COMPONENT(inputBase ${input} NAME)
STRING(REGEX REPLACE "[^a-zA-Z0-9]" "_" funcName "${inputBase}")
SET(funcName "GetResource_${funcName}")
FILE(WRITE "${output}" "#include <stddef.h>\n#include <wpi/StringRef.h>\nextern \"C\" {\nstatic const unsigned char contents[] = {")
FILE(WRITE "${output}" "#include <stddef.h>\n#include <string_view>\nextern \"C\" {\nstatic const unsigned char contents[] = {")
STRING(REGEX MATCHALL ".." outputData "${fileHex}")
STRING(REGEX REPLACE ";" ", 0x" outputData "${outputData}")
@@ -17,7 +17,7 @@ FILE(APPEND "${output}" "const unsigned char* ${prefix}${funcName}(size_t* len)
IF(NOT namespace STREQUAL "")
FILE(APPEND "${output}" "namespace ${namespace} {\n")
ENDIF()
FILE(APPEND "${output}" "wpi::StringRef ${funcName}() {\n return wpi::StringRef(reinterpret_cast<const char*>(contents), ${fileSize});\n}\n")
FILE(APPEND "${output}" "std::string_view ${funcName}() {\n return std::string_view(reinterpret_cast<const char*>(contents), ${fileSize});\n}\n")
IF(NOT namespace STREQUAL "")
FILE(APPEND "${output}" "}\n")
ENDIF()

View File

@@ -1,4 +1,4 @@
set(GCC_COMPILER_VERSION "" CACHE STRING "GCC Compiler version")
set(GNU_MACHINE "arm-frc2021-linux-gnueabi" CACHE STRING "GNU compiler triple")
set(GNU_MACHINE "arm-frc2022-linux-gnueabi" CACHE STRING "GNU compiler triple")
set(SOFTFP yes)
include("${CMAKE_CURRENT_LIST_DIR}/arm.toolchain.cmake")

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 2.8)
cmake_minimum_required(VERSION 3.3.0)
# load settings in case of "try compile"
set(TOOLCHAIN_CONFIG_FILE "${WPILIB_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/toolchain.config.cmake")

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