Compare commits

...

110 Commits

Author SHA1 Message Date
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
587 changed files with 19329 additions and 5738 deletions

View File

@@ -12,7 +12,7 @@ jobs:
name: Linux
container: wpilib/roborio-cross-ubuntu:2022-20.04
flags: ""
- os: macos-latest
- os: macOS-11
name: macOS
container: ""
flags: "-DWITH_JAVA=OFF"
@@ -43,7 +43,7 @@ jobs:
build-vcpkg:
name: "Build - Windows"
runs-on: windows-latest
runs-on: windows-2019
steps:
- uses: actions/checkout@v2
- name: Prepare vcpkg

View File

@@ -44,13 +44,13 @@ jobs:
fail-fast: false
matrix:
include:
- os: windows-latest
- os: windows-2019
artifact-name: Win64
architecture: x64
- os: windows-latest
- os: windows-2019
artifact-name: Win32
architecture: x86
- os: macos-latest
- os: macOS-11
artifact-name: macOS
architecture: x64
name: "Build - ${{ matrix.artifact-name }}"

View File

@@ -11,6 +11,7 @@ cppSrcFileInclude {
modifiableFileExclude {
\.patch$
gradlew
}
generatedFileExclude {

View File

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

View File

@@ -145,6 +145,8 @@ if (USE_VCPKG_EIGEN)
set (EIGEN_VCPKG_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(NTCORE_DEP_REPLACE "include($\{SELF_DIR\}/ntcore-config.cmake)")
@@ -245,7 +247,6 @@ if (WITH_TESTS)
include(GoogleTest)
endif()
add_subdirectory(fieldImages)
add_subdirectory(wpiutil)
add_subdirectory(ntcore)
@@ -254,10 +255,14 @@ if (WITH_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)
endif()
endif()
if (WITH_WPILIB OR WITH_SIMULATION_MODULES)

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

@@ -69,15 +69,36 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
* wpiutil
* wpigui
* imgui
* ntcore
* wpiutil
* wpimath
* wpiutil
* glass/libglass
* wpiutil
* wpimath
* wpigui
* glass/libglassnt
* wpiutil
* ntcore
* wpimath
* wpigui
* hal
* wpiutil
* halsim
* imgui
* wpiutil
* ntcore
* wpiutil
* ntcore
* wpimath
* wpigui
* libglass
* libglassnt
* cscore
* opencv
@@ -101,6 +122,7 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
* cameraserver
* ntcore
* cscore
* wpimath
* wpiutil
* wpilibNewCommands
@@ -109,9 +131,10 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
* cameraserver
* ntcore
* cscore
* wpimath
* wpiutil
* wpilibNewCommands
* wpilibOldCommands
* wpilibc
* hal
* cameraserver
@@ -119,6 +142,7 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
* cscore
* wpiutil
### Third Party Artifacts
This repository provides the builds of the following third party software.
@@ -128,3 +152,4 @@ All artifacts are based at `edu.wpi.first.thirdparty.frcYEAR` in the repository.
* googletest
* imgui
* opencv
* libssh

View File

@@ -11,6 +11,7 @@ Development builds are the per-commit build hosted everytime a commit is pushed
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.useLocal = false
wpi.maven.useDevelopment = true
wpi.versions.wpilibVersion = 'YEAR.+'
wpi.versions.wpimathVersion = 'YEAR.+

View File

@@ -39,7 +39,7 @@ Using Gradle makes building WPILib very straightforward. It only has a few depen
- On macOS, install the JDK 11 .pkg from the link above
- C++ compiler
- On Linux, install GCC 8 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 Windows, install [Visual Studio Community 2022 or 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)
- On macOS, install the Xcode command-line build tools via `xcode-select --install`
- ARM compiler toolchain
- Run `./gradlew installRoboRioToolchain` after cloning this repository
@@ -71,6 +71,8 @@ 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.

View File

@@ -5,7 +5,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.hubspot.jinjava:jinjava:2.5.8'
classpath 'com.hubspot.jinjava:jinjava:2.6.0'
}
}
@@ -15,13 +15,13 @@ plugins {
id 'edu.wpi.first.wpilib.repositories.WPILibRepositoriesPlugin' version '2020.2'
id 'edu.wpi.first.NativeUtils' apply false
id 'edu.wpi.first.GradleJni' version '1.0.0'
id 'edu.wpi.first.GradleVsCode' version '1.0.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' apply false
id 'com.github.spotbugs' version '5.0.0-beta.1' apply false
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.1.2' apply false
id 'com.github.spotbugs' version '5.0.4' apply false
}
wpilibVersioning.buildServerMode = project.hasProperty('buildServer')
@@ -147,5 +147,5 @@ ext.getCurrentArch = {
}
wrapper {
gradleVersion = '7.1.1'
gradleVersion = '7.3.3'
}

View File

@@ -5,5 +5,5 @@ repositories {
}
}
dependencies {
implementation "edu.wpi.first:native-utils:2022.3.1"
implementation "edu.wpi.first:native-utils:2022.7.1"
}

View File

@@ -27,7 +27,7 @@ repositories {
}
dependencies {
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.google.code.gson:gson:2.8.9'
implementation project(':wpiutil')
implementation project(':ntcore')

View File

@@ -56,9 +56,9 @@ public final class Main {
public JsonObject config;
}
static int team;
static boolean server;
static List<CameraConfig> cameras = new ArrayList<>();
private static int team;
private static boolean server;
private static List<CameraConfig> cameras = new ArrayList<>();
private Main() {}

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

@@ -14,7 +14,6 @@
#include <windowsx.h>
#include <cmath>
#include <codecvt>
#include <memory>
#include <string>
#include <vector>
@@ -25,7 +24,9 @@
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <wpi/ConvertUTF.h>
#include <wpi/MemAlloc.h>
#include <wpi/SmallString.h>
#include <wpi/StringExtras.h>
#include <wpi/timestamp.h>
@@ -72,8 +73,9 @@ UsbCameraImpl::UsbCameraImpl(std::string_view name, wpi::Logger& logger,
Notifier& notifier, Telemetry& telemetry,
std::string_view path)
: SourceImpl{name, logger, notifier, telemetry}, m_path{path} {
std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
m_widePath = utf8_conv.from_bytes(m_path.c_str());
wpi::SmallVector<wchar_t, 128> wideStorage;
wpi::sys::windows::UTF8ToUTF16(m_path, wideStorage);
m_widePath = std::wstring{wideStorage.data(), wideStorage.size()};
m_deviceId = -1;
StartMessagePump();
}
@@ -227,7 +229,7 @@ void UsbCameraImpl::PostRequestNewFrame() {
bool UsbCameraImpl::CheckDeviceChange(WPARAM wParam, DEV_BROADCAST_HDR* pHdr,
bool* connected) {
DEV_BROADCAST_DEVICEINTERFACE* pDi = NULL;
DEV_BROADCAST_DEVICEINTERFACE_A* pDi = NULL;
*connected = false;
@@ -240,9 +242,9 @@ bool UsbCameraImpl::CheckDeviceChange(WPARAM wParam, DEV_BROADCAST_HDR* pHdr,
// Compare the device name with the symbolic link.
pDi = reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(pHdr);
pDi = reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE_A*>(pHdr);
if (_stricmp(m_path.c_str(), pDi->dbcc_name) == 0) {
if (wpi::equals_lower(m_path, pDi->dbcc_name)) {
if (wParam == DBT_DEVICEARRIVAL) {
*connected = true;
return true;
@@ -411,11 +413,12 @@ LRESULT UsbCameraImpl::PumpMain(HWND hwnd, UINT uiMsg, WPARAM wParam,
// If has device ID, use the device ID from the event
// because of windows bug
auto&& device = devices[m_deviceId];
DEV_BROADCAST_DEVICEINTERFACE* pDi =
reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE*>(parameter);
DEV_BROADCAST_DEVICEINTERFACE_A* pDi =
reinterpret_cast<DEV_BROADCAST_DEVICEINTERFACE_A*>(parameter);
m_path = pDi->dbcc_name;
std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
m_widePath = utf8_conv.from_bytes(m_path.c_str());
wpi::SmallVector<wchar_t, 128> wideStorage;
wpi::sys::windows::UTF8ToUTF16(m_path, wideStorage);
m_widePath = std::wstring{wideStorage.data(), wideStorage.size()};
} else {
// This device not found
break;
@@ -482,9 +485,16 @@ bool UsbCameraImpl::DeviceConnect() {
const wchar_t* path = m_widePath.c_str();
m_mediaSource = CreateVideoCaptureDevice(path);
if (!m_mediaSource)
if (!m_mediaSource) {
return false;
m_imageCallback = CreateSourceReaderCB(shared_from_this(), m_mode);
}
auto weakThis = weak_from_this();
auto sharedThis = weakThis.lock();
if (sharedThis) {
m_imageCallback = CreateSourceReaderCB(sharedThis, m_mode);
} else {
return false;
}
m_sourceReader =
CreateSourceReader(m_mediaSource.Get(), m_imageCallback.Get());
@@ -747,8 +757,9 @@ CS_StatusValue UsbCameraImpl::DeviceProcessCommand(
{
std::scoped_lock lock(m_mutex);
m_path = msg->dataStr;
std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
m_widePath = utf8_conv.from_bytes(m_path.c_str());
wpi::SmallVector<wchar_t, 128> wideStorage;
wpi::sys::windows::UTF8ToUTF16(m_path, wideStorage);
m_widePath = std::wstring{wideStorage.data(), wideStorage.size()};
}
DeviceDisconnect();
DeviceConnect();
@@ -1048,7 +1059,8 @@ std::vector<UsbCameraInfo> EnumerateUsbCameras(CS_Status* status) {
// Ensure we are initialized by grabbing the message pump
// GetMessagePump();
std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8_conv;
wpi::SmallString<128> storage;
WCHAR buf[512];
ComPtr<IMFAttributes> pAttributes;
IMFActivate** ppDevices = nullptr;
UINT32 count = 0;
@@ -1080,14 +1092,19 @@ std::vector<UsbCameraInfo> EnumerateUsbCameras(CS_Status* status) {
for (UINT32 i = 0; i < count; i++) {
UsbCameraInfo info;
info.dev = i;
WCHAR buf[512];
UINT32 characters = 0;
ppDevices[i]->GetString(MF_DEVSOURCE_ATTRIBUTE_FRIENDLY_NAME, buf,
sizeof(buf) / sizeof(WCHAR), NULL);
info.name = utf8_conv.to_bytes(buf);
sizeof(buf) / sizeof(WCHAR), &characters);
storage.clear();
wpi::sys::windows::UTF16ToUTF8(buf, characters, storage);
info.name = storage.string();
ppDevices[i]->GetString(
MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_SYMBOLIC_LINK, buf,
sizeof(buf) / sizeof(WCHAR), NULL);
info.path = utf8_conv.to_bytes(buf);
sizeof(buf) / sizeof(WCHAR), &characters);
storage.clear();
wpi::sys::windows::UTF16ToUTF8(buf, characters, storage);
info.path = storage.string();
// Try to parse path from symbolic link
ParseVidAndPid(info.path, &info.productId, &info.vendorId);

View File

@@ -89,7 +89,7 @@ static std::shared_ptr<ClassHolder> GetClassHolder() {
WindowsMessagePump::WindowsMessagePump(
std::function<LRESULT(HWND, UINT, WPARAM, LPARAM)> callback) {
m_callback = callback;
auto handle = CreateEvent(NULL, true, false, NULL);
auto handle = CreateEventA(NULL, true, false, NULL);
m_mainThread = std::thread([=] { ThreadMain(handle); });
auto waitResult = WaitForSingleObject(handle, 1000);
if (waitResult == WAIT_OBJECT_0) {
@@ -98,7 +98,7 @@ WindowsMessagePump::WindowsMessagePump(
}
WindowsMessagePump::~WindowsMessagePump() {
auto res = SendMessage(hwnd, WM_CLOSE, NULL, NULL);
auto res = SendMessageA(hwnd, WM_CLOSE, NULL, NULL);
if (m_mainThread.joinable())
m_mainThread.join();
}
@@ -110,28 +110,28 @@ void WindowsMessagePump::ThreadMain(HANDLE eventHandle) {
MFStartup(MF_VERSION);
auto classHolder = GetClassHolder();
hwnd = CreateWindowEx(0, classHolder->class_name, "dummy_name", 0, 0, 0, 0, 0,
HWND_MESSAGE, NULL, NULL, this);
hwnd = CreateWindowExA(0, classHolder->class_name, "dummy_name", 0, 0, 0, 0,
0, HWND_MESSAGE, NULL, NULL, this);
// Register for device notifications
HDEVNOTIFY g_hdevnotify = NULL;
HDEVNOTIFY g_hdevnotify2 = NULL;
DEV_BROADCAST_DEVICEINTERFACE di = {0};
DEV_BROADCAST_DEVICEINTERFACE_A di = {0};
di.dbcc_size = sizeof(di);
di.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
di.dbcc_classguid = KSCATEGORY_CAPTURE;
g_hdevnotify =
RegisterDeviceNotification(hwnd, &di, DEVICE_NOTIFY_WINDOW_HANDLE);
RegisterDeviceNotificationA(hwnd, &di, DEVICE_NOTIFY_WINDOW_HANDLE);
DEV_BROADCAST_DEVICEINTERFACE di2 = {0};
DEV_BROADCAST_DEVICEINTERFACE_A di2 = {0};
di2.dbcc_size = sizeof(di2);
di2.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
di2.dbcc_classguid = KSCATEGORY_VIDEO_CAMERA;
g_hdevnotify2 =
RegisterDeviceNotification(hwnd, &di2, DEVICE_NOTIFY_WINDOW_HANDLE);
RegisterDeviceNotificationA(hwnd, &di2, DEVICE_NOTIFY_WINDOW_HANDLE);
SetEvent(eventHandle);

View File

@@ -15,10 +15,14 @@ if (!project.hasProperty('onlylinuxathena') && !project.hasProperty('onlylinuxra
ext {
nativeName = 'fieldImages'
baseId = nativeName
groupId = 'edu.wpi.first.fieldImages'
devMain = "edu.wpi.first.fieldImages.DevMain"
}
apply from: "${rootDir}/shared/resources.gradle"
apply from: "${rootDir}/shared/config.gradle"
apply from: "${rootDir}/shared/java/javacommon.gradle"
def generateTask = createGenerateResourcesTask('main', 'FIELDS', 'fields', project)

View File

@@ -1,14 +1,14 @@
apply plugin: 'maven-publish'
def baseArtifactId = 'fieldImages'
def artifactGroupId = 'edu.wpi.first.fieldImages'
def zipBaseName = '_GROUP_edu_wpi_first_field_images_ID_CLS'
def baseArtifactId = project.nativeName
def artifactGroupId = project.groupId
def cppZipBaseName = "_GROUP_edu_wpi_first_fieldIimages_ID_${baseArtifactId}-cpp_CLS"
def outputsFolder = file("$project.buildDir/outputs")
task cppSourcesZip(type: Zip) {
destinationDirectory = outputsFolder
archiveBaseName = zipBaseName
archiveBaseName = cppZipBaseName
classifier = "sources"
from(licenseFile) {
@@ -25,7 +25,7 @@ task cppSourcesZip(type: Zip) {
task cppHeadersZip(type: Zip) {
destinationDirectory = outputsFolder
archiveBaseName = zipBaseName
archiveBaseName = cppZipBaseName
classifier = "headers"
from(licenseFile) {
@@ -51,7 +51,7 @@ addTaskToCopyAllOutputs(cppSourcesZip)
model {
publishing {
def wpilibCTaskList = createComponentZipTasks($.components, ['fieldImages'], zipBaseName, Zip, project, includeStandardZipFormat)
def wpilibCTaskList = createComponentZipTasks($.components, ['fieldImages'], cppZipBaseName, Zip, project, includeStandardZipFormat)
publications {
cpp(MavenPublication) {
@@ -62,7 +62,7 @@ model {
artifact cppHeadersZip
artifact cppSourcesZip
artifactId = baseArtifactId
artifactId = "${baseArtifactId}-cpp"
groupId artifactGroupId
version wpilibVersioning.version.get()
}

View File

@@ -20,4 +20,6 @@ public class FieldImages {
public static final String k2021GalacticSearchBFieldConfig =
"/edu/wpi/first/fields/2021-galacticsearchb.json";
public static final String k2021SlalomFieldConfig = "/edu/wpi/first/fields/2021-slalompath.json";
public static final String k2022RapidReactFieldConfig =
"/edu/wpi/first/fields/2022-rapidreact.json";
}

View File

@@ -0,0 +1,12 @@
// 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>
namespace fields {
std::string_view GetResource_2022_rapidreact_json();
std::string_view GetResource_2022_field_png();
} // namespace fields

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

View File

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

View File

@@ -185,15 +185,18 @@ if (!project.hasProperty('onlylinuxathena') && !project.hasProperty('onlylinuxra
it.buildable = false
return
}
lib project: ':cscore', library: 'cscore', linkage: 'static'
lib library: 'glassnt', linkage: 'static'
lib library: nativeName, linkage: 'static'
lib project: ':ntcore', library: 'ntcore', linkage: 'static'
lib project: ':wpiutil', library: 'wpiutil', linkage: 'static'
lib project: ':wpimath', library: 'wpimath', linkage: 'static'
lib project: ':wpigui', library: 'wpigui', linkage: 'static'
nativeUtils.useRequiredLibrary(it, 'opencv_static')
nativeUtils.useRequiredLibrary(it, 'imgui_static')
if (it.targetPlatform.operatingSystem.isWindows()) {
it.linker.args << 'Gdi32.lib' << 'Shell32.lib' << 'd3d11.lib' << 'd3dcompiler.lib'
it.linker.args << '/DELAYLOAD:MF.dll' << '/DELAYLOAD:MFReadWrite.dll' << '/DELAYLOAD:MFPlat.dll' << '/delay:nobind'
} else if (it.targetPlatform.operatingSystem.isMacOsX()) {
it.linker.args << '-framework' << 'Metal' << '-framework' << 'MetalKit' << '-framework' << 'Cocoa' << '-framework' << 'IOKit' << '-framework' << 'CoreFoundation' << '-framework' << 'CoreVideo' << '-framework' << 'QuartzCore'
} else {

View File

@@ -0,0 +1,52 @@
// 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 "camerasupport.h"
#ifdef _WIN32
#include "Windows.h"
#include "delayimp.h"
#pragma comment(lib, "delayimp.lib")
static int CheckDelayException(int exception_value) {
if (exception_value ==
VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND) ||
exception_value ==
VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND)) {
// This example just executes the handler.
return EXCEPTION_EXECUTE_HANDLER;
}
// Don't attempt to handle other errors
return EXCEPTION_CONTINUE_SEARCH;
}
static bool TryDelayLoadAllImports(LPCSTR szDll) {
__try {
HRESULT hr = __HrLoadAllImportsForDll(szDll);
if (FAILED(hr)) {
return false;
}
} __except (CheckDelayException(GetExceptionCode())) {
return false;
}
return true;
}
namespace glass {
bool HasCameraSupport() {
bool hasCameraSupport = false;
hasCameraSupport = TryDelayLoadAllImports("MF.dll");
if (hasCameraSupport) {
hasCameraSupport = TryDelayLoadAllImports("MFPlat.dll");
}
if (hasCameraSupport) {
hasCameraSupport = TryDelayLoadAllImports("MFReadWrite.dll");
}
return hasCameraSupport;
}
} // namespace glass
#else
namespace glass {
bool HasCameraSupport() {
return true;
}
} // namespace glass
#endif

View File

@@ -0,0 +1,9 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
namespace glass {
bool HasCameraSupport();
} // namespace glass

View File

@@ -70,17 +70,17 @@ void glass::DisplayEncoder(EncoderModel* model) {
std::string& name = GetStorage().GetString("name");
char label[128];
if (!name.empty()) {
std::snprintf(label, sizeof(label), "%s [%d,%d]###name", name.c_str(), chA,
chB);
std::snprintf(label, sizeof(label), "%s [%d,%d]###header", name.c_str(),
chA, chB);
} else {
std::snprintf(label, sizeof(label), "Encoder[%d,%d]###name", chA, chB);
std::snprintf(label, sizeof(label), "Encoder[%d,%d]###header", chA, chB);
}
// header
bool open = CollapsingHeader(label);
// context menu to change name
if (PopupEditName("name", &name)) {
if (PopupEditName("header", &name)) {
model->SetName(name);
}

View File

@@ -46,15 +46,16 @@ bool glass::DisplayPCMSolenoids(PCMModel* model, int index,
std::string& name = GetStorage().GetString("name");
char label[128];
if (!name.empty()) {
std::snprintf(label, sizeof(label), "%s [%d]###name", name.c_str(), index);
std::snprintf(label, sizeof(label), "%s [%d]###header", name.c_str(),
index);
} else {
std::snprintf(label, sizeof(label), "PCM[%d]###name", index);
std::snprintf(label, sizeof(label), "PCM[%d]###header", index);
}
// header
bool open = CollapsingHeader(label);
PopupEditName("name", &name);
PopupEditName("header", &name);
ImGui::SetItemAllowOverlap();
ImGui::SameLine();

View File

@@ -53,11 +53,11 @@ bool glass::BeginDevice(const char* id, ImGuiTreeNodeFlags flags) {
// build label
std::string& name = GetStorage().GetString("name");
char label[128];
std::snprintf(label, sizeof(label), "%s###name",
std::snprintf(label, sizeof(label), "%s###header",
name.empty() ? id : name.c_str());
bool open = CollapsingHeader(label, flags);
PopupEditName("name", &name);
PopupEditName("header", &name);
if (!open) {
PopID();

View File

@@ -17,10 +17,15 @@
#include <fmt/format.h>
#if defined(__GNUC__)
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
#endif
#define IMGUI_DEFINE_MATH_OPERATORS
#include <imgui.h>
#include <imgui_stdlib.h>
#include <implot.h>
#include <implot_internal.h>
#include <wpi/Signal.h>
#include <wpi/SmallString.h>
#include <wpi/SmallVector.h>
@@ -36,6 +41,8 @@
using namespace glass;
static constexpr int kAxisCount = 3;
namespace {
class PlotView;
@@ -129,6 +136,7 @@ class Plot {
private:
void EmitSettingsLimits(int axis);
void DragDropAccept(PlotView& view, size_t i, int yAxis);
bool m_paused = false;
@@ -137,13 +145,19 @@ class Plot {
bool& m_showPause;
bool& m_lockPrevX;
bool& m_legend;
bool& m_legendOutside;
bool& m_legendHorizontal;
int& m_legendLocation;
bool& m_crosshairs;
bool& m_antialiased;
bool& m_mousePosition;
bool& m_yAxis2;
bool& m_yAxis3;
float& m_viewTime;
bool& m_autoHeight;
int& m_height;
struct PlotRange {
explicit PlotRange(Storage& storage);
struct PlotAxis {
PlotAxis(Storage& storage, int num);
std::string& label;
double& min;
@@ -151,8 +165,15 @@ class Plot {
bool& lockMin;
bool& lockMax;
bool apply = false;
bool& autoFit;
bool& logScale;
bool& invert;
bool& opposite;
bool& gridLines;
bool& tickMarks;
bool& tickLabels;
};
std::vector<PlotRange> m_axis;
std::vector<PlotAxis> m_axis;
ImPlotRange m_xaxisRange; // read from plot, used for lockPrevX
};
@@ -178,7 +199,7 @@ class PlotView : public View {
PlotSeries::PlotSeries(Storage& storage, int yAxis)
: m_id{storage.GetString("id")},
m_name{storage.GetString("name")},
m_yAxis{storage.GetInt("yAxis", yAxis)},
m_yAxis{storage.GetInt("yAxis", 0)},
m_color{storage.GetFloatArray("color", kDefaultColor)},
m_marker{storage.GetString("marker"),
0,
@@ -188,7 +209,9 @@ PlotSeries::PlotSeries(Storage& storage, int yAxis)
m_digital{
storage.GetString("digital"), kAuto, {"Auto", "Digital", "Analog"}},
m_digitalBitHeight{storage.GetInt("digitalBitHeight", 8)},
m_digitalBitGap{storage.GetInt("digitalBitGap", 4)} {}
m_digitalBitGap{storage.GetInt("digitalBitGap", 4)} {
m_yAxis = yAxis;
}
PlotSeries::PlotSeries(Storage& storage, std::string_view id)
: PlotSeries{storage, 0} {
@@ -288,7 +311,8 @@ PlotSeries::Action PlotSeries::EmitPlot(PlotView& view, double now, size_t i,
CheckSource();
char label[128];
std::snprintf(label, sizeof(label), "%s###name", GetName());
std::snprintf(label, sizeof(label), "%s###name%d_%d", GetName(),
static_cast<int>(i), static_cast<int>(plotIndex));
int size = m_size;
int offset = m_offset;
@@ -330,7 +354,11 @@ PlotSeries::Action PlotSeries::EmitPlot(PlotView& view, double now, size_t i,
ImPlot::PopStyleVar();
ImPlot::PopStyleVar();
} else {
ImPlot::SetPlotYAxis(m_yAxis);
if (ImPlot::GetCurrentPlot()->YAxis(m_yAxis).Enabled) {
ImPlot::SetAxis(ImAxis_Y1 + m_yAxis);
} else {
ImPlot::SetAxis(ImAxis_Y1);
}
ImPlot::SetNextMarkerStyle(m_marker.GetValue() - 1);
ImPlot::PlotLineG(label, getter, &getterData, size + 1);
}
@@ -433,12 +461,19 @@ void PlotSeries::EmitSettings(size_t i) {
}
}
Plot::PlotRange::PlotRange(Storage& storage)
Plot::PlotAxis::PlotAxis(Storage& storage, int num)
: label{storage.GetString("label")},
min{storage.GetDouble("min", 0)},
max{storage.GetDouble("max", 1)},
lockMin{storage.GetBool("lockMin", false)},
lockMax{storage.GetBool("lockMax", false)} {}
lockMax{storage.GetBool("lockMax", false)},
autoFit{storage.GetBool("autoFit", false)},
logScale{storage.GetBool("logScale", false)},
invert{storage.GetBool("invert", false)},
opposite{storage.GetBool("opposite", num != 0)},
gridLines{storage.GetBool("gridLines", num == 0)},
tickMarks{storage.GetBool("tickMarks", true)},
tickLabels{storage.GetBool("tickLabels", true)} {}
Plot::Plot(Storage& storage)
: m_seriesStorage{storage.GetChildArray("series")},
@@ -447,18 +482,25 @@ Plot::Plot(Storage& storage)
m_showPause{storage.GetBool("showPause", true)},
m_lockPrevX{storage.GetBool("lockPrevX", false)},
m_legend{storage.GetBool("legend", true)},
m_legendOutside{storage.GetBool("legendOutside", false)},
m_legendHorizontal{storage.GetBool("legendHorizontal", false)},
m_legendLocation{
storage.GetInt("legendLocation", ImPlotLocation_NorthWest)},
m_crosshairs{storage.GetBool("crosshairs", false)},
m_antialiased{storage.GetBool("antialiased", false)},
m_mousePosition{storage.GetBool("mousePosition", true)},
m_yAxis2{storage.GetBool("yaxis2", false)},
m_yAxis3{storage.GetBool("yaxis3", false)},
m_viewTime{storage.GetFloat("viewTime", 10)},
m_autoHeight{storage.GetBool("autoHeight", true)},
m_height{storage.GetInt("height", 300)} {
auto& axesStorage = storage.GetChildArray("axis");
axesStorage.resize(3);
for (auto&& axisStorage : axesStorage) {
if (!axisStorage) {
axisStorage = std::make_unique<Storage>();
axesStorage.resize(kAxisCount);
for (int i = 0; i < kAxisCount; ++i) {
if (!axesStorage[i]) {
axesStorage[i] = std::make_unique<Storage>();
}
m_axis.emplace_back(*axisStorage);
m_axis.emplace_back(*axesStorage[i], i);
}
// loop over series
@@ -468,20 +510,7 @@ Plot::Plot(Storage& storage)
}
}
void Plot::DragDropTarget(PlotView& view, size_t i, bool inPlot) {
if (!ImGui::BeginDragDropTarget()) {
return;
}
// handle dragging onto a specific Y axis
int yAxis = -1;
if (inPlot) {
for (int y = 0; y < 3; ++y) {
if (ImPlot::IsPlotYAxisHovered(y)) {
yAxis = y;
break;
}
}
}
void Plot::DragDropAccept(PlotView& view, size_t i, int yAxis) {
if (const ImGuiPayload* payload =
ImGui::AcceptDragDropPayload("DataSource")) {
auto source = *static_cast<DataSource**>(payload->Data);
@@ -508,6 +537,26 @@ void Plot::DragDropTarget(PlotView& view, size_t i, bool inPlot) {
}
}
void Plot::DragDropTarget(PlotView& view, size_t i, bool inPlot) {
if (inPlot) {
if (ImPlot::BeginDragDropTargetPlot() ||
ImPlot::BeginDragDropTargetLegend()) {
DragDropAccept(view, i, -1);
ImPlot::EndDragDropTarget();
}
for (int y = 0; y < kAxisCount; ++y) {
if (ImPlot::GetCurrentPlot()->YAxis(y).Enabled &&
ImPlot::BeginDragDropTargetAxis(ImAxis_Y1 + y)) {
DragDropAccept(view, i, y);
ImPlot::EndDragDropTarget();
}
}
} else if (ImGui::BeginDragDropTarget()) {
DragDropAccept(view, i, -1);
ImGui::EndDragDropTarget();
}
}
void Plot::EmitPlot(PlotView& view, double now, bool paused, size_t i) {
if (!m_visible) {
return;
@@ -520,49 +569,63 @@ void Plot::EmitPlot(PlotView& view, double now, bool paused, size_t i) {
}
char label[128];
std::snprintf(label, sizeof(label), "%s##plot", m_name.c_str());
if (lockX) {
ImPlot::SetNextPlotLimitsX(view.m_plots[i - 1]->m_xaxisRange.Min,
view.m_plots[i - 1]->m_xaxisRange.Max,
ImGuiCond_Always);
} else {
// also force-pause plots if overall timing is paused
double zeroTime = GetZeroTime() * 1.0e-6;
ImPlot::SetNextPlotLimitsX(
now - zeroTime - m_viewTime, now - zeroTime,
(paused || m_paused) ? ImGuiCond_Once : ImGuiCond_Always);
}
ImPlotAxisFlags yFlags[3] = {ImPlotAxisFlags_None,
ImPlotAxisFlags_NoGridLines,
ImPlotAxisFlags_NoGridLines};
for (int i = 0; i < 3; ++i) {
ImPlot::SetNextPlotLimitsY(
m_axis[i].min, m_axis[i].max,
m_axis[i].apply ? ImGuiCond_Always : ImGuiCond_Once, i);
m_axis[i].apply = false;
if (m_axis[i].lockMin) {
yFlags[i] |= ImPlotAxisFlags_LockMin;
}
if (m_axis[i].lockMax) {
yFlags[i] |= ImPlotAxisFlags_LockMax;
}
}
std::snprintf(label, sizeof(label), "%s###plot%d", m_name.c_str(),
static_cast<int>(i));
ImPlotFlags plotFlags = (m_legend ? 0 : ImPlotFlags_NoLegend) |
(m_yAxis2 ? ImPlotFlags_YAxis2 : 0) |
(m_yAxis3 ? ImPlotFlags_YAxis3 : 0);
(m_crosshairs ? ImPlotFlags_Crosshairs : 0) |
(m_antialiased ? ImPlotFlags_AntiAliased : 0) |
(m_mousePosition ? 0 : ImPlotFlags_NoMouseText);
if (ImPlot::BeginPlot(label, ImVec2(-1, m_height), plotFlags)) {
// setup legend
if (m_legend) {
ImPlotLegendFlags legendFlags =
(m_legendOutside ? ImPlotLegendFlags_Outside : 0) |
(m_legendHorizontal ? ImPlotLegendFlags_Horizontal : 0);
ImPlot::SetupLegend(m_legendLocation, legendFlags);
}
// setup x axis
ImPlot::SetupAxis(ImAxis_X1, nullptr, ImPlotAxisFlags_NoMenus);
if (lockX) {
ImPlot::SetupAxisLimits(ImAxis_X1, view.m_plots[i - 1]->m_xaxisRange.Min,
view.m_plots[i - 1]->m_xaxisRange.Max,
ImGuiCond_Always);
} else {
// also force-pause plots if overall timing is paused
double zeroTime = GetZeroTime() * 1.0e-6;
ImPlot::SetupAxisLimits(
ImAxis_X1, now - zeroTime - m_viewTime, now - zeroTime,
(paused || m_paused) ? ImGuiCond_Once : ImGuiCond_Always);
}
// setup y axes
for (int i = 0; i < kAxisCount; ++i) {
if ((i == 1 && !m_yAxis2) || (i == 2 && !m_yAxis3)) {
continue;
}
ImPlotAxisFlags flags =
(m_axis[i].lockMin ? ImPlotAxisFlags_LockMin : 0) |
(m_axis[i].lockMax ? ImPlotAxisFlags_LockMax : 0) |
(m_axis[i].autoFit ? ImPlotAxisFlags_AutoFit : 0) |
(m_axis[i].logScale ? ImPlotAxisFlags_AutoFit : 0) |
(m_axis[i].invert ? ImPlotAxisFlags_Invert : 0) |
(m_axis[i].opposite ? ImPlotAxisFlags_Opposite : 0) |
(m_axis[i].gridLines ? 0 : ImPlotAxisFlags_NoGridLines) |
(m_axis[i].tickMarks ? 0 : ImPlotAxisFlags_NoTickMarks) |
(m_axis[i].tickLabels ? 0 : ImPlotAxisFlags_NoTickLabels);
ImPlot::SetupAxis(
ImAxis_Y1 + i,
m_axis[i].label.empty() ? nullptr : m_axis[i].label.c_str(), flags);
ImPlot::SetupAxisLimits(
ImAxis_Y1 + i, m_axis[i].min, m_axis[i].max,
m_axis[i].apply ? ImGuiCond_Always : ImGuiCond_Once);
m_axis[i].apply = false;
}
ImPlot::SetupFinish();
if (ImPlot::BeginPlot(
label, nullptr,
m_axis[0].label.empty() ? nullptr : m_axis[0].label.c_str(),
ImVec2(-1, m_height), plotFlags, ImPlotAxisFlags_None, yFlags[0],
yFlags[1], yFlags[2],
m_axis[1].label.empty() ? nullptr : m_axis[1].label.c_str(),
m_axis[2].label.empty() ? nullptr : m_axis[2].label.c_str())) {
for (size_t j = 0; j < m_series.size(); ++j) {
ImGui::PushID(j);
switch (m_series[j]->EmitPlot(view, now, j, i)) {
case PlotSeries::kMoveUp:
if (j > 0) {
@@ -583,11 +646,38 @@ void Plot::EmitPlot(PlotView& view, double now, bool paused, size_t i) {
default:
break;
}
ImGui::PopID();
}
DragDropTarget(view, i, true);
m_xaxisRange = ImPlot::GetPlotLimits().X;
ImPlotPlot* plot = ImPlot::GetCurrentPlot();
ImPlot::EndPlot();
// copy plot settings back to storage
m_legend = (plot->Flags & ImPlotFlags_NoLegend) == 0;
m_crosshairs = (plot->Flags & ImPlotFlags_Crosshairs) != 0;
m_antialiased = (plot->Flags & ImPlotFlags_AntiAliased) != 0;
m_legendOutside =
(plot->Items.Legend.Flags & ImPlotLegendFlags_Outside) != 0;
m_legendHorizontal =
(plot->Items.Legend.Flags & ImPlotLegendFlags_Horizontal) != 0;
m_legendLocation = plot->Items.Legend.Location;
for (int i = 0; i < kAxisCount; ++i) {
if ((i == 1 && !m_yAxis2) || (i == 2 && !m_yAxis3)) {
continue;
}
auto flags = plot->Axes[ImAxis_Y1 + i].Flags;
m_axis[i].lockMin = (flags & ImPlotAxisFlags_LockMin) != 0;
m_axis[i].lockMax = (flags & ImPlotAxisFlags_LockMax) != 0;
m_axis[i].autoFit = (flags & ImPlotAxisFlags_AutoFit) != 0;
m_axis[i].logScale = (flags & ImPlotAxisFlags_LogScale) != 0;
m_axis[i].invert = (flags & ImPlotAxisFlags_Invert) != 0;
m_axis[i].opposite = (flags & ImPlotAxisFlags_Opposite) != 0;
m_axis[i].gridLines = (flags & ImPlotAxisFlags_NoGridLines) == 0;
m_axis[i].tickMarks = (flags & ImPlotAxisFlags_NoTickMarks) == 0;
m_axis[i].tickLabels = (flags & ImPlotAxisFlags_NoTickLabels) == 0;
}
}
}
@@ -622,7 +712,6 @@ void Plot::EmitSettings(size_t i) {
ImGui::InputText("##editname", &m_name);
ImGui::Checkbox("Visible", &m_visible);
ImGui::Checkbox("Show Pause Button", &m_showPause);
ImGui::Checkbox("Show Legend", &m_legend);
if (i != 0) {
ImGui::Checkbox("Lock X-axis to previous plot", &m_lockPrevX);
}

View File

@@ -160,17 +160,17 @@ bool DeleteButton(ImGuiID id, const ImVec2& pos) {
bool HeaderDeleteButton(const char* label) {
ImGuiWindow* window = ImGui::GetCurrentWindow();
ImGuiContext& g = *GImGui;
ImGuiLastItemDataBackup last_item_backup;
ImGuiLastItemData last_item_backup = g.LastItemData;
ImGuiID id = window->GetID(label);
float button_size = g.FontSize;
float button_x = ImMax(window->DC.LastItemRect.Min.x,
window->DC.LastItemRect.Max.x -
g.Style.FramePadding.x * 2.0f - button_size);
float button_y = window->DC.LastItemRect.Min.y;
float button_x = ImMax(
g.LastItemData.Rect.Min.x,
g.LastItemData.Rect.Max.x - g.Style.FramePadding.x * 2.0f - button_size);
float button_y = g.LastItemData.Rect.Min.y;
bool rv = DeleteButton(
window->GetID(reinterpret_cast<void*>(static_cast<intptr_t>(id) + 1)),
ImVec2(button_x, button_y));
last_item_backup.Restore();
g.LastItemData = last_item_backup;
return rv;
}

View File

@@ -1 +1,8 @@
org.gradle.jvmargs=-Xmx1g
# The --add-exports flags work around a bug with spotless and JDK 17
# https://github.com/diffplug/spotless/issues/834
org.gradle.jvmargs=-Xmx1g \
--add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
--add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

269
gradlew vendored
View File

@@ -1,7 +1,7 @@
#!/usr/bin/env sh
#!/bin/sh
#
# Copyright 2015 the original author or authors.
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,67 +17,101 @@
#
##############################################################################
##
## Gradle start up script for UN*X
##
#
# Gradle start up script for POSIX generated by Gradle.
#
# Important for running:
#
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
# noncompliant, but you have some other compliant shell such as ksh or
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
# ksh Gradle
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
# (2) This script targets any POSIX shell, so it avoids extensions provided
# by Bash, Ksh, etc; in particular arrays are avoided.
#
# The "traditional" practice of packing multiple parameters into a
# space-separated string is a well documented source of bugs and security
# problems, so this is (mostly) avoided, by progressively accumulating
# options in "$@", and eventually passing that to Java.
#
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
# see the in-line comments for details.
#
# There are tweaks for specific operating systems such as AIX, CygWin,
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
app_path=$0
# Need this for daisy-chained symlinks.
while
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
[ -h "$app_path" ]
do
ls=$( ls -ld "$app_path" )
link=${ls#*' -> '}
case $link in #(
/*) app_path=$link ;; #(
*) app_path=$APP_HOME$link ;;
esac
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
MAX_FD=maximum
warn () {
echo "$*"
}
} >&2
die () {
echo
echo "$*"
echo
exit 1
}
} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MSYS* | MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
case "$( uname )" in #(
CYGWIN* ) cygwin=true ;; #(
Darwin* ) darwin=true ;; #(
MSYS* | MINGW* ) msys=true ;; #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
JAVACMD=$JAVA_HOME/jre/sh/java
else
JAVACMD="$JAVA_HOME/bin/java"
JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
@@ -106,80 +140,95 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, stacking in reverse order:
# * args from the command line
# * the main class name
# * -classpath
# * -D...appname settings
# * --module-path (only if needed)
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" )
# Now convert the arguments - kludge to limit ourselves to /bin/sh
for arg do
if
case $arg in #(
-*) false ;; # don't mess with options #(
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
[ -e "$t" ] ;; #(
*) false ;;
esac
then
arg=$( cygpath --path --ignore --mixed "$arg" )
fi
# Roll the args list around exactly as many times as the number of
# args, so each arg winds up back in the position where it started, but
# possibly modified.
#
# NB: a `for` loop captures its iteration list before it begins, so
# changing the positional parameters here affects neither the number of
# iterations, nor the values presented in `arg`.
shift # remove old arg
set -- "$@" "$arg" # push replacement arg
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
# set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#
eval "set -- $(
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
xargs -n1 |
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"

View File

@@ -28,6 +28,20 @@ public class ControlWord {
m_dsAttached = dsAttached;
}
/**
* Updates from an existing word.
*
* @param word word to update from
*/
public void update(ControlWord word) {
m_enabled = word.m_enabled;
m_autonomous = word.m_autonomous;
m_test = word.m_test;
m_emergencyStop = word.m_emergencyStop;
m_fmsAttached = word.m_fmsAttached;
m_dsAttached = word.m_dsAttached;
}
public boolean getEnabled() {
return m_enabled;
}

View File

@@ -196,8 +196,8 @@ public final class HAL extends JNIWrapper {
@SuppressWarnings("MissingJavadocMethod")
public static native boolean waitForDSDataTimeout(double timeout);
public static int kMaxJoystickAxes = 12;
public static int kMaxJoystickPOVs = 12;
public static final int kMaxJoystickAxes = 12;
public static final int kMaxJoystickPOVs = 12;
public static native short getJoystickAxes(byte joystickNum, float[] axesArray);

View File

@@ -0,0 +1,123 @@
// 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.hal;
public class PowerDistributionFaults {
@SuppressWarnings("MemberName")
public final boolean Channel0BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel1BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel2BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel3BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel4BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel5BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel6BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel7BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel8BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel9BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel10BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel11BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel12BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel13BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel14BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel15BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel16BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel17BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel18BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel19BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel20BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel21BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel22BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel23BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Brownout;
@SuppressWarnings("MemberName")
public final boolean CanWarning;
@SuppressWarnings("MemberName")
public final boolean HardwareFault;
/**
* Constructs from a bitfield.
*
* @param faults faults
*/
public PowerDistributionFaults(int faults) {
Channel0BreakerFault = (faults & 0x1) != 0;
Channel1BreakerFault = (faults & 0x2) != 0;
Channel2BreakerFault = (faults & 0x4) != 0;
Channel3BreakerFault = (faults & 0x8) != 0;
Channel4BreakerFault = (faults & 0x10) != 0;
Channel5BreakerFault = (faults & 0x20) != 0;
Channel6BreakerFault = (faults & 0x40) != 0;
Channel7BreakerFault = (faults & 0x80) != 0;
Channel8BreakerFault = (faults & 0x100) != 0;
Channel9BreakerFault = (faults & 0x200) != 0;
Channel10BreakerFault = (faults & 0x400) != 0;
Channel11BreakerFault = (faults & 0x800) != 0;
Channel12BreakerFault = (faults & 0x1000) != 0;
Channel13BreakerFault = (faults & 0x2000) != 0;
Channel14BreakerFault = (faults & 0x4000) != 0;
Channel15BreakerFault = (faults & 0x8000) != 0;
Channel16BreakerFault = (faults & 0x10000) != 0;
Channel17BreakerFault = (faults & 0x20000) != 0;
Channel18BreakerFault = (faults & 0x40000) != 0;
Channel19BreakerFault = (faults & 0x80000) != 0;
Channel20BreakerFault = (faults & 0x100000) != 0;
Channel21BreakerFault = (faults & 0x200000) != 0;
Channel22BreakerFault = (faults & 0x400000) != 0;
Channel23BreakerFault = (faults & 0x800000) != 0;
Brownout = (faults & 0x1000000) != 0;
CanWarning = (faults & 0x2000000) != 0;
HardwareFault = (faults & 0x4000000) != 0;
}
}

View File

@@ -56,4 +56,18 @@ public class PowerDistributionJNI extends JNIWrapper {
public static native boolean getSwitchableChannelNoError(int handle);
public static native void setSwitchableChannelNoError(int handle, boolean enabled);
public static native int getFaultsNative(int handle);
public static PowerDistributionFaults getFaults(int handle) {
return new PowerDistributionFaults(getFaultsNative(handle));
}
public static native int getStickyFaultsNative(int handle);
public static PowerDistributionStickyFaults getStickyFaults(int handle) {
return new PowerDistributionStickyFaults(getStickyFaultsNative(handle));
}
public static native PowerDistributionVersion getVersion(int handle);
}

View File

@@ -0,0 +1,127 @@
// 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.hal;
public class PowerDistributionStickyFaults {
@SuppressWarnings("MemberName")
public final boolean Channel0BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel1BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel2BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel3BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel4BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel5BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel6BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel7BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel8BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel9BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel10BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel11BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel12BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel13BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel14BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel15BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel16BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel17BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel18BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel19BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel20BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel21BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel22BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Channel23BreakerFault;
@SuppressWarnings("MemberName")
public final boolean Brownout;
@SuppressWarnings("MemberName")
public final boolean CanWarning;
@SuppressWarnings("MemberName")
public final boolean CanBusOff;
@SuppressWarnings("MemberName")
public final boolean HasReset;
/**
* Constructs from a bitfield.
*
* @param faults faults
*/
public PowerDistributionStickyFaults(int faults) {
Channel0BreakerFault = (faults & 0x1) != 0;
Channel1BreakerFault = (faults & 0x2) != 0;
Channel2BreakerFault = (faults & 0x4) != 0;
Channel3BreakerFault = (faults & 0x8) != 0;
Channel4BreakerFault = (faults & 0x10) != 0;
Channel5BreakerFault = (faults & 0x20) != 0;
Channel6BreakerFault = (faults & 0x40) != 0;
Channel7BreakerFault = (faults & 0x80) != 0;
Channel8BreakerFault = (faults & 0x100) != 0;
Channel9BreakerFault = (faults & 0x200) != 0;
Channel10BreakerFault = (faults & 0x400) != 0;
Channel11BreakerFault = (faults & 0x800) != 0;
Channel12BreakerFault = (faults & 0x1000) != 0;
Channel13BreakerFault = (faults & 0x2000) != 0;
Channel14BreakerFault = (faults & 0x4000) != 0;
Channel15BreakerFault = (faults & 0x8000) != 0;
Channel16BreakerFault = (faults & 0x10000) != 0;
Channel17BreakerFault = (faults & 0x20000) != 0;
Channel18BreakerFault = (faults & 0x40000) != 0;
Channel19BreakerFault = (faults & 0x80000) != 0;
Channel20BreakerFault = (faults & 0x100000) != 0;
Channel21BreakerFault = (faults & 0x200000) != 0;
Channel22BreakerFault = (faults & 0x400000) != 0;
Channel23BreakerFault = (faults & 0x800000) != 0;
Brownout = (faults & 0x1000000) != 0;
CanWarning = (faults & 0x2000000) != 0;
CanBusOff = (faults & 0x4000000) != 0;
HasReset = (faults & 0x8000000) != 0;
}
}

View File

@@ -0,0 +1,50 @@
// 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.hal;
public class PowerDistributionVersion {
@SuppressWarnings("MemberName")
public final int firmwareMajor;
@SuppressWarnings("MemberName")
public final int firmwareMinor;
@SuppressWarnings("MemberName")
public final int firmwareFix;
@SuppressWarnings("MemberName")
public final int hardwareMinor;
@SuppressWarnings("MemberName")
public final int hardwareMajor;
@SuppressWarnings("MemberName")
public final int uniqueId;
/**
* Constructs a power distribution version (Called from the HAL).
*
* @param firmwareMajor firmware major
* @param firmwareMinor firmware minor
* @param firmwareFix firmware fix
* @param hardwareMinor hardware minor
* @param hardwareMajor hardware major
* @param uniqueId unique id
*/
public PowerDistributionVersion(
int firmwareMajor,
int firmwareMinor,
int firmwareFix,
int hardwareMinor,
int hardwareMajor,
int uniqueId) {
this.firmwareMajor = firmwareMajor;
this.firmwareMinor = firmwareMinor;
this.firmwareFix = firmwareFix;
this.hardwareMinor = hardwareMinor;
this.hardwareMajor = hardwareMajor;
this.uniqueId = uniqueId;
}
}

View File

@@ -0,0 +1,104 @@
// 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.hal;
@SuppressWarnings("AbbreviationAsWordInName")
public class REVPHFaults {
@SuppressWarnings("MemberName")
public final boolean Channel0Fault;
@SuppressWarnings("MemberName")
public final boolean Channel1Fault;
@SuppressWarnings("MemberName")
public final boolean Channel2Fault;
@SuppressWarnings("MemberName")
public final boolean Channel3Fault;
@SuppressWarnings("MemberName")
public final boolean Channel4Fault;
@SuppressWarnings("MemberName")
public final boolean Channel5Fault;
@SuppressWarnings("MemberName")
public final boolean Channel6Fault;
@SuppressWarnings("MemberName")
public final boolean Channel7Fault;
@SuppressWarnings("MemberName")
public final boolean Channel8Fault;
@SuppressWarnings("MemberName")
public final boolean Channel9Fault;
@SuppressWarnings("MemberName")
public final boolean Channel10Fault;
@SuppressWarnings("MemberName")
public final boolean Channel11Fault;
@SuppressWarnings("MemberName")
public final boolean Channel12Fault;
@SuppressWarnings("MemberName")
public final boolean Channel13Fault;
@SuppressWarnings("MemberName")
public final boolean Channel14Fault;
@SuppressWarnings("MemberName")
public final boolean Channel15Fault;
@SuppressWarnings("MemberName")
public final boolean CompressorOverCurrent;
@SuppressWarnings("MemberName")
public final boolean CompressorOpen;
@SuppressWarnings("MemberName")
public final boolean SolenoidOverCurrent;
@SuppressWarnings("MemberName")
public final boolean Brownout;
@SuppressWarnings("MemberName")
public final boolean CanWarning;
@SuppressWarnings("MemberName")
public final boolean HardwareFault;
/**
* Called from HAL to construct.
*
* @param faults the fault bitfields
*/
public REVPHFaults(int faults) {
Channel0Fault = (faults & 0x1) != 0;
Channel1Fault = (faults & 0x2) != 0;
Channel2Fault = (faults & 0x4) != 0;
Channel3Fault = (faults & 0x8) != 0;
Channel4Fault = (faults & 0x10) != 0;
Channel5Fault = (faults & 0x20) != 0;
Channel6Fault = (faults & 0x40) != 0;
Channel7Fault = (faults & 0x80) != 0;
Channel8Fault = (faults & 0x100) != 0;
Channel9Fault = (faults & 0x200) != 0;
Channel10Fault = (faults & 0x400) != 0;
Channel11Fault = (faults & 0x800) != 0;
Channel12Fault = (faults & 0x1000) != 0;
Channel13Fault = (faults & 0x2000) != 0;
Channel14Fault = (faults & 0x4000) != 0;
Channel15Fault = (faults & 0x8000) != 0;
CompressorOverCurrent = (faults & 0x8000) != 0;
CompressorOpen = (faults & 0x10000) != 0;
SolenoidOverCurrent = (faults & 0x20000) != 0;
Brownout = (faults & 0x40000) != 0;
CanWarning = (faults & 0x80000) != 0;
HardwareFault = (faults & 0x100000) != 0;
}
}

View File

@@ -40,7 +40,7 @@ public class REVPHJNI extends JNIWrapper {
public static native boolean getPressureSwitch(int handle);
public static native double getAnalogPressure(int handle, int channel);
public static native double getAnalogVoltage(int handle, int channel);
public static native double getCompressorCurrent(int handle);
@@ -49,4 +49,28 @@ public class REVPHJNI extends JNIWrapper {
public static native void setSolenoids(int handle, int mask, int values);
public static native void fireOneShot(int handle, int index, int durMs);
public static native void clearStickyFaults(int handle);
public static native double getInputVoltage(int handle);
public static native double get5VVoltage(int handle);
public static native double getSolenoidCurrent(int handle);
public static native double getSolenoidVoltage(int handle);
public static native int getStickyFaultsNative(int handle);
public static REVPHStickyFaults getStickyFaults(int handle) {
return new REVPHStickyFaults(getStickyFaultsNative(handle));
}
public static native int getFaultsNative(int handle);
public static REVPHFaults getFaults(int handle) {
return new REVPHFaults(getFaultsNative(handle));
}
public static native REVPHVersion getVersion(int handle);
}

View File

@@ -0,0 +1,44 @@
// 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.hal;
@SuppressWarnings("AbbreviationAsWordInName")
public class REVPHStickyFaults {
@SuppressWarnings("MemberName")
public final boolean CompressorOverCurrent;
@SuppressWarnings("MemberName")
public final boolean CompressorOpen;
@SuppressWarnings("MemberName")
public final boolean SolenoidOverCurrent;
@SuppressWarnings("MemberName")
public final boolean Brownout;
@SuppressWarnings("MemberName")
public final boolean CanWarning;
@SuppressWarnings("MemberName")
public final boolean CanBusOff;
@SuppressWarnings("MemberName")
public final boolean HasReset;
/**
* Called from HAL.
*
* @param faults sticky fault bit mask
*/
public REVPHStickyFaults(int faults) {
CompressorOverCurrent = (faults & 0x1) != 0;
CompressorOpen = (faults & 0x2) != 0;
SolenoidOverCurrent = (faults & 0x4) != 0;
Brownout = (faults & 0x8) != 0;
CanWarning = (faults & 0x10) != 0;
CanBusOff = (faults & 0x20) != 0;
HasReset = (faults & 0x40) != 0;
}
}

View File

@@ -0,0 +1,51 @@
// 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.hal;
@SuppressWarnings("AbbreviationAsWordInName")
public class REVPHVersion {
@SuppressWarnings("MemberName")
public final int firmwareMajor;
@SuppressWarnings("MemberName")
public final int firmwareMinor;
@SuppressWarnings("MemberName")
public final int firmwareFix;
@SuppressWarnings("MemberName")
public final int hardwareMinor;
@SuppressWarnings("MemberName")
public final int hardwareMajor;
@SuppressWarnings("MemberName")
public final int uniqueId;
/**
* Constructs a revph version (Called from the HAL).
*
* @param firmwareMajor firmware major
* @param firmwareMinor firmware minor
* @param firmwareFix firmware fix
* @param hardwareMinor hardware minor
* @param hardwareMajor hardware major
* @param uniqueId unique id
*/
public REVPHVersion(
int firmwareMajor,
int firmwareMinor,
int firmwareFix,
int hardwareMinor,
int hardwareMajor,
int uniqueId) {
this.firmwareMajor = firmwareMajor;
this.firmwareMinor = firmwareMinor;
this.firmwareFix = firmwareFix;
this.hardwareMinor = hardwareMinor;
this.hardwareMajor = hardwareMajor;
this.uniqueId = uniqueId;
}
}

View File

@@ -14,10 +14,17 @@ public final class CANExceptionFactory {
static final int ERR_CANSessionMux_NotAllowed = -44088;
static final int ERR_CANSessionMux_NotInitialized = -44089;
@SuppressWarnings("MissingJavadocMethod")
public static void checkStatus(int status, int messageID)
throws CANInvalidBufferException, CANMessageNotAllowedException, CANNotInitializedException,
UncleanStatusException {
/**
* Checks the status of a CAN message with the given message ID.
*
* @param status The CAN status.
* @param messageID The CAN message ID.
* @throws CANInvalidBufferException if the buffer is invalid.
* @throws CANMessageNotAllowedException if the message isn't allowed.
* @throws CANNotInitializedException if the CAN bus isn't initialized.
* @throws UncleanStatusException if the status code passed in reports an error.
*/
public static void checkStatus(int status, int messageID) {
switch (status) {
case NIRioStatus.kRioStatusSuccess:
// Everything is ok... don't throw.

View File

@@ -54,6 +54,10 @@ void HAL_InitializeI2C(HAL_I2CPort port, int32_t* status) {
}
if (port == HAL_I2C_kOnboard) {
HAL_SendError(0, 0, 0,
"Onboard I2C port is subject to system lockups. See Known "
"Issues page for details",
"", "", true);
std::scoped_lock lock(digitalI2COnBoardMutex);
i2COnboardObjCount++;
if (i2COnboardObjCount > 1) {

View File

@@ -4,6 +4,7 @@
#include "hal/PowerDistribution.h"
#include <cstring>
#include <thread>
#include "CTREPDP.h"
@@ -55,7 +56,7 @@ HAL_PowerDistributionHandle HAL_InitializePowerDistribution(
HAL_CleanPDP(pdpHandle);
}
*status = 0;
auto pdhHandle = HAL_REV_InitializePDH(1, allocationLocation, status);
auto pdhHandle = HAL_InitializeREVPDH(1, allocationLocation, status);
return static_cast<HAL_PowerDistributionHandle>(pdhHandle);
}
@@ -70,7 +71,7 @@ HAL_PowerDistributionHandle HAL_InitializePowerDistribution(
moduleNumber = 1;
}
return static_cast<HAL_PowerDistributionHandle>(
HAL_REV_InitializePDH(moduleNumber, allocationLocation, status));
HAL_InitializeREVPDH(moduleNumber, allocationLocation, status));
}
}
@@ -80,7 +81,7 @@ void HAL_CleanPowerDistribution(HAL_PowerDistributionHandle handle) {
if (IsCtre(handle)) {
HAL_CleanPDP(handle);
} else {
HAL_REV_FreePDH(handle);
HAL_FreeREVPDH(handle);
}
}
@@ -89,7 +90,7 @@ int32_t HAL_GetPowerDistributionModuleNumber(HAL_PowerDistributionHandle handle,
if (IsCtre(handle)) {
return HAL_GetPDPModuleNumber(handle, status);
} else {
return HAL_REV_GetPDHModuleNumber(handle, status);
return HAL_GetREVPDHModuleNumber(handle, status);
}
}
@@ -98,7 +99,7 @@ HAL_Bool HAL_CheckPowerDistributionChannel(HAL_PowerDistributionHandle handle,
if (IsCtre(handle)) {
return HAL_CheckPDPChannel(channel);
} else {
return HAL_REV_CheckPDHChannelNumber(channel);
return HAL_CheckREVPDHChannelNumber(channel);
}
}
@@ -107,7 +108,7 @@ HAL_Bool HAL_CheckPowerDistributionModule(int32_t module,
if (type == HAL_PowerDistributionType::HAL_PowerDistributionType_kCTRE) {
return HAL_CheckPDPModule(module);
} else {
return HAL_REV_CheckPDHModuleNumber(module);
return HAL_CheckREVPDHModuleNumber(module);
}
}
@@ -142,7 +143,7 @@ double HAL_GetPowerDistributionVoltage(HAL_PowerDistributionHandle handle,
if (IsCtre(handle)) {
return HAL_GetPDPVoltage(handle, status);
} else {
return HAL_REV_GetPDHSupplyVoltage(handle, status);
return HAL_GetREVPDHVoltage(handle, status);
}
}
@@ -151,7 +152,7 @@ double HAL_GetPowerDistributionChannelCurrent(
if (IsCtre(handle)) {
return HAL_GetPDPChannelCurrent(handle, channel, status);
} else {
return HAL_REV_GetPDHChannelCurrent(handle, channel, status);
return HAL_GetREVPDHChannelCurrent(handle, channel, status);
}
}
@@ -171,7 +172,7 @@ void HAL_GetPowerDistributionAllChannelCurrents(
SetLastError(status, "Output array not large enough");
return;
}
return HAL_REV_GetPDHAllChannelCurrents(handle, currents, status);
return HAL_GetREVPDHAllChannelCurrents(handle, currents, status);
}
}
@@ -180,7 +181,7 @@ double HAL_GetPowerDistributionTotalCurrent(HAL_PowerDistributionHandle handle,
if (IsCtre(handle)) {
return HAL_GetPDPTotalCurrent(handle, status);
} else {
return HAL_REV_GetPDHTotalCurrent(handle, status);
return HAL_GetREVPDHTotalCurrent(handle, status);
}
}
@@ -218,7 +219,7 @@ void HAL_ClearPowerDistributionStickyFaults(HAL_PowerDistributionHandle handle,
if (IsCtre(handle)) {
HAL_ClearPDPStickyFaults(handle, status);
} else {
HAL_REV_ClearPDHFaults(handle, status);
HAL_ClearREVPDHStickyFaults(handle, status);
}
}
@@ -228,7 +229,7 @@ void HAL_SetPowerDistributionSwitchableChannel(
// No-op on CTRE
return;
} else {
HAL_REV_SetPDHSwitchableChannel(handle, enabled, status);
HAL_SetREVPDHSwitchableChannel(handle, enabled, status);
}
}
@@ -238,7 +239,37 @@ HAL_Bool HAL_GetPowerDistributionSwitchableChannel(
// No-op on CTRE
return false;
} else {
return HAL_REV_GetPDHSwitchableChannelState(handle, status);
return HAL_GetREVPDHSwitchableChannelState(handle, status);
}
}
void HAL_GetPowerDistributionVersion(HAL_PowerDistributionHandle handle,
HAL_PowerDistributionVersion* version,
int32_t* status) {
if (IsCtre(handle)) {
std::memset(version, 0, sizeof(*version));
} else {
HAL_GetREVPDHVersion(handle, version, status);
}
}
void HAL_GetPowerDistributionFaults(HAL_PowerDistributionHandle handle,
HAL_PowerDistributionFaults* faults,
int32_t* status) {
if (IsCtre(handle)) {
std::memset(faults, 0, sizeof(*faults));
} else {
HAL_GetREVPDHFaults(handle, faults, status);
}
}
void HAL_GetPowerDistributionStickyFaults(
HAL_PowerDistributionHandle handle,
HAL_PowerDistributionStickyFaults* stickyFaults, int32_t* status) {
if (IsCtre(handle)) {
std::memset(stickyFaults, 0, sizeof(*stickyFaults));
} else {
HAL_GetREVPDHStickyFaults(handle, stickyFaults, status);
}
}

View File

@@ -11,6 +11,7 @@
#include <hal/handles/IndexedHandleResource.h>
#include <cstring>
#include <thread>
#include <fmt/format.h>
@@ -35,6 +36,7 @@ struct REV_PDHObj {
int32_t controlPeriod;
HAL_CANHandle hcan;
std::string previousAllocation;
HAL_PowerDistributionVersion versionInfo;
};
} // namespace
@@ -43,32 +45,26 @@ static constexpr uint32_t APIFromExtId(uint32_t extId) {
return (extId >> 6) & 0x3FF;
}
static constexpr uint32_t PDH_SWITCH_CHANNEL_SET_FRAME_API =
APIFromExtId(PDH_SWITCH_CHANNEL_SET_FRAME_ID);
static constexpr uint32_t PDH_SET_SWITCH_CHANNEL_FRAME_API =
APIFromExtId(PDH_SET_SWITCH_CHANNEL_FRAME_ID);
static constexpr uint32_t PDH_STATUS0_FRAME_API =
APIFromExtId(PDH_STATUS0_FRAME_ID);
static constexpr uint32_t PDH_STATUS1_FRAME_API =
APIFromExtId(PDH_STATUS1_FRAME_ID);
static constexpr uint32_t PDH_STATUS2_FRAME_API =
APIFromExtId(PDH_STATUS2_FRAME_ID);
static constexpr uint32_t PDH_STATUS3_FRAME_API =
APIFromExtId(PDH_STATUS3_FRAME_ID);
static constexpr uint32_t PDH_STATUS4_FRAME_API =
APIFromExtId(PDH_STATUS4_FRAME_ID);
static constexpr uint32_t PDH_STATUS_0_FRAME_API =
APIFromExtId(PDH_STATUS_0_FRAME_ID);
static constexpr uint32_t PDH_STATUS_1_FRAME_API =
APIFromExtId(PDH_STATUS_1_FRAME_ID);
static constexpr uint32_t PDH_STATUS_2_FRAME_API =
APIFromExtId(PDH_STATUS_2_FRAME_ID);
static constexpr uint32_t PDH_STATUS_3_FRAME_API =
APIFromExtId(PDH_STATUS_3_FRAME_ID);
static constexpr uint32_t PDH_STATUS_4_FRAME_API =
APIFromExtId(PDH_STATUS_4_FRAME_ID);
static constexpr uint32_t PDH_CLEAR_FAULTS_FRAME_API =
APIFromExtId(PDH_CLEAR_FAULTS_FRAME_ID);
static constexpr uint32_t PDH_IDENTIFY_FRAME_API =
APIFromExtId(PDH_IDENTIFY_FRAME_ID);
static constexpr uint32_t PDH_VERSION_FRAME_API =
APIFromExtId(PDH_VERSION_FRAME_ID);
static constexpr uint32_t PDH_CONFIGURE_HR_CHANNEL_FRAME_API =
APIFromExtId(PDH_CONFIGURE_HR_CHANNEL_FRAME_ID);
static constexpr int32_t kPDHFrameStatus0Timeout = 20;
static constexpr int32_t kPDHFrameStatus1Timeout = 20;
static constexpr int32_t kPDHFrameStatus2Timeout = 20;
@@ -89,97 +85,97 @@ void InitializeREVPDH() {
extern "C" {
static PDH_status0_t HAL_REV_ReadPDHStatus0(HAL_CANHandle hcan,
static PDH_status_0_t HAL_ReadREVPDHStatus0(HAL_CANHandle hcan,
int32_t* status) {
uint8_t packedData[8] = {0};
int32_t length = 0;
uint64_t timestamp = 0;
PDH_status0_t result = {};
PDH_status_0_t result = {};
HAL_ReadCANPacketTimeout(hcan, PDH_STATUS0_FRAME_API, packedData, &length,
HAL_ReadCANPacketTimeout(hcan, PDH_STATUS_0_FRAME_API, packedData, &length,
&timestamp, kPDHFrameStatus0Timeout * 2, status);
if (*status != 0) {
return result;
}
PDH_status0_unpack(&result, packedData, PDH_STATUS0_LENGTH);
PDH_status_0_unpack(&result, packedData, PDH_STATUS_0_LENGTH);
return result;
}
static PDH_status1_t HAL_REV_ReadPDHStatus1(HAL_CANHandle hcan,
static PDH_status_1_t HAL_ReadREVPDHStatus1(HAL_CANHandle hcan,
int32_t* status) {
uint8_t packedData[8] = {0};
int32_t length = 0;
uint64_t timestamp = 0;
PDH_status1_t result = {};
PDH_status_1_t result = {};
HAL_ReadCANPacketTimeout(hcan, PDH_STATUS1_FRAME_API, packedData, &length,
HAL_ReadCANPacketTimeout(hcan, PDH_STATUS_1_FRAME_API, packedData, &length,
&timestamp, kPDHFrameStatus1Timeout * 2, status);
if (*status != 0) {
return result;
}
PDH_status1_unpack(&result, packedData, PDH_STATUS1_LENGTH);
PDH_status_1_unpack(&result, packedData, PDH_STATUS_1_LENGTH);
return result;
}
static PDH_status2_t HAL_REV_ReadPDHStatus2(HAL_CANHandle hcan,
static PDH_status_2_t HAL_ReadREVPDHStatus2(HAL_CANHandle hcan,
int32_t* status) {
uint8_t packedData[8] = {0};
int32_t length = 0;
uint64_t timestamp = 0;
PDH_status2_t result = {};
PDH_status_2_t result = {};
HAL_ReadCANPacketTimeout(hcan, PDH_STATUS2_FRAME_API, packedData, &length,
HAL_ReadCANPacketTimeout(hcan, PDH_STATUS_2_FRAME_API, packedData, &length,
&timestamp, kPDHFrameStatus2Timeout * 2, status);
if (*status != 0) {
return result;
}
PDH_status2_unpack(&result, packedData, PDH_STATUS2_LENGTH);
PDH_status_2_unpack(&result, packedData, PDH_STATUS_2_LENGTH);
return result;
}
static PDH_status3_t HAL_REV_ReadPDHStatus3(HAL_CANHandle hcan,
static PDH_status_3_t HAL_ReadREVPDHStatus3(HAL_CANHandle hcan,
int32_t* status) {
uint8_t packedData[8] = {0};
int32_t length = 0;
uint64_t timestamp = 0;
PDH_status3_t result = {};
PDH_status_3_t result = {};
HAL_ReadCANPacketTimeout(hcan, PDH_STATUS3_FRAME_API, packedData, &length,
HAL_ReadCANPacketTimeout(hcan, PDH_STATUS_3_FRAME_API, packedData, &length,
&timestamp, kPDHFrameStatus3Timeout * 2, status);
if (*status != 0) {
return result;
}
PDH_status3_unpack(&result, packedData, PDH_STATUS3_LENGTH);
PDH_status_3_unpack(&result, packedData, PDH_STATUS_3_LENGTH);
return result;
}
static PDH_status4_t HAL_REV_ReadPDHStatus4(HAL_CANHandle hcan,
static PDH_status_4_t HAL_ReadREVPDHStatus4(HAL_CANHandle hcan,
int32_t* status) {
uint8_t packedData[8] = {0};
int32_t length = 0;
uint64_t timestamp = 0;
PDH_status4_t result = {};
PDH_status_4_t result = {};
HAL_ReadCANPacketTimeout(hcan, PDH_STATUS4_FRAME_API, packedData, &length,
HAL_ReadCANPacketTimeout(hcan, PDH_STATUS_4_FRAME_API, packedData, &length,
&timestamp, kPDHFrameStatus4Timeout * 2, status);
if (*status != 0) {
return result;
}
PDH_status4_unpack(&result, packedData, PDH_STATUS4_LENGTH);
PDH_status_4_unpack(&result, packedData, PDH_STATUS_4_LENGTH);
return result;
}
@@ -187,23 +183,23 @@ static PDH_status4_t HAL_REV_ReadPDHStatus4(HAL_CANHandle hcan,
/**
* Helper function for the individual getter functions for status 4
*/
PDH_status4_t HAL_REV_GetPDHStatus4(HAL_REVPDHHandle handle, int32_t* status) {
PDH_status4_t statusFrame = {};
PDH_status_4_t HAL_GetREVPDHStatus4(HAL_REVPDHHandle handle, int32_t* status) {
PDH_status_4_t statusFrame = {};
auto hpdh = REVPDHHandles->Get(handle);
if (hpdh == nullptr) {
*status = HAL_HANDLE_ERROR;
return statusFrame;
}
statusFrame = HAL_REV_ReadPDHStatus4(hpdh->hcan, status);
statusFrame = HAL_ReadREVPDHStatus4(hpdh->hcan, status);
return statusFrame;
}
HAL_REVPDHHandle HAL_REV_InitializePDH(int32_t module,
const char* allocationLocation,
int32_t* status) {
HAL_REVPDHHandle HAL_InitializeREVPDH(int32_t module,
const char* allocationLocation,
int32_t* status) {
hal::init::CheckInit();
if (!HAL_REV_CheckPDHModuleNumber(module)) {
if (!HAL_CheckREVPDHModuleNumber(module)) {
*status = RESOURCE_OUT_OF_RANGE;
return HAL_kInvalidHandle;
}
@@ -232,11 +228,12 @@ HAL_REVPDHHandle HAL_REV_InitializePDH(int32_t module,
hpdh->previousAllocation = allocationLocation ? allocationLocation : "";
hpdh->hcan = hcan;
hpdh->controlPeriod = kDefaultControlPeriod;
std::memset(&hpdh->versionInfo, 0, sizeof(hpdh->versionInfo));
return handle;
}
void HAL_REV_FreePDH(HAL_REVPDHHandle handle) {
void HAL_FreeREVPDH(HAL_REVPDHHandle handle) {
auto hpdh = REVPDHHandles->Get(handle);
if (hpdh == nullptr) {
return;
@@ -247,27 +244,27 @@ void HAL_REV_FreePDH(HAL_REVPDHHandle handle) {
REVPDHHandles->Free(handle);
}
int32_t HAL_REV_GetPDHModuleNumber(HAL_REVPDHHandle handle, int32_t* status) {
int32_t HAL_GetREVPDHModuleNumber(HAL_REVPDHHandle handle, int32_t* status) {
return hal::getHandleIndex(handle);
}
HAL_Bool HAL_REV_CheckPDHModuleNumber(int32_t module) {
HAL_Bool HAL_CheckREVPDHModuleNumber(int32_t module) {
return ((module >= 1) && (module < kNumREVPDHModules)) ? 1 : 0;
}
HAL_Bool HAL_REV_CheckPDHChannelNumber(int32_t channel) {
HAL_Bool HAL_CheckREVPDHChannelNumber(int32_t channel) {
return ((channel >= 0) && (channel < kNumREVPDHChannels)) ? 1 : 0;
}
double HAL_REV_GetPDHChannelCurrent(HAL_REVPDHHandle handle, int32_t channel,
int32_t* status) {
double HAL_GetREVPDHChannelCurrent(HAL_REVPDHHandle handle, int32_t channel,
int32_t* status) {
auto hpdh = REVPDHHandles->Get(handle);
if (hpdh == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
}
if (!HAL_REV_CheckPDHChannelNumber(channel)) {
if (!HAL_CheckREVPDHChannelNumber(channel)) {
*status = RESOURCE_OUT_OF_RANGE;
return 0;
}
@@ -275,174 +272,101 @@ double HAL_REV_GetPDHChannelCurrent(HAL_REVPDHHandle handle, int32_t channel,
// Determine what periodic status the channel is in
if (channel < 6) {
// Periodic status 0
PDH_status0_t statusFrame = HAL_REV_ReadPDHStatus0(hpdh->hcan, status);
PDH_status_0_t statusFrame = HAL_ReadREVPDHStatus0(hpdh->hcan, status);
switch (channel) {
case 0:
return PDH_status0_channel_0_current_decode(
return PDH_status_0_channel_0_current_decode(
statusFrame.channel_0_current);
case 1:
return PDH_status0_channel_1_current_decode(
return PDH_status_0_channel_1_current_decode(
statusFrame.channel_1_current);
case 2:
return PDH_status0_channel_2_current_decode(
return PDH_status_0_channel_2_current_decode(
statusFrame.channel_2_current);
case 3:
return PDH_status0_channel_3_current_decode(
return PDH_status_0_channel_3_current_decode(
statusFrame.channel_3_current);
case 4:
return PDH_status0_channel_4_current_decode(
return PDH_status_0_channel_4_current_decode(
statusFrame.channel_4_current);
case 5:
return PDH_status0_channel_5_current_decode(
return PDH_status_0_channel_5_current_decode(
statusFrame.channel_5_current);
}
} else if (channel < 12) {
// Periodic status 1
PDH_status1_t statusFrame = HAL_REV_ReadPDHStatus1(hpdh->hcan, status);
PDH_status_1_t statusFrame = HAL_ReadREVPDHStatus1(hpdh->hcan, status);
switch (channel) {
case 6:
return PDH_status1_channel_6_current_decode(
return PDH_status_1_channel_6_current_decode(
statusFrame.channel_6_current);
case 7:
return PDH_status1_channel_7_current_decode(
return PDH_status_1_channel_7_current_decode(
statusFrame.channel_7_current);
case 8:
return PDH_status1_channel_8_current_decode(
return PDH_status_1_channel_8_current_decode(
statusFrame.channel_8_current);
case 9:
return PDH_status1_channel_9_current_decode(
return PDH_status_1_channel_9_current_decode(
statusFrame.channel_9_current);
case 10:
return PDH_status1_channel_10_current_decode(
return PDH_status_1_channel_10_current_decode(
statusFrame.channel_10_current);
case 11:
return PDH_status1_channel_11_current_decode(
return PDH_status_1_channel_11_current_decode(
statusFrame.channel_11_current);
}
} else if (channel < 18) {
// Periodic status 2
PDH_status2_t statusFrame = HAL_REV_ReadPDHStatus2(hpdh->hcan, status);
PDH_status_2_t statusFrame = HAL_ReadREVPDHStatus2(hpdh->hcan, status);
switch (channel) {
case 12:
return PDH_status2_channel_12_current_decode(
return PDH_status_2_channel_12_current_decode(
statusFrame.channel_12_current);
case 13:
return PDH_status2_channel_13_current_decode(
return PDH_status_2_channel_13_current_decode(
statusFrame.channel_13_current);
case 14:
return PDH_status2_channel_14_current_decode(
return PDH_status_2_channel_14_current_decode(
statusFrame.channel_14_current);
case 15:
return PDH_status2_channel_15_current_decode(
return PDH_status_2_channel_15_current_decode(
statusFrame.channel_15_current);
case 16:
return PDH_status2_channel_16_current_decode(
return PDH_status_2_channel_16_current_decode(
statusFrame.channel_16_current);
case 17:
return PDH_status2_channel_17_current_decode(
return PDH_status_2_channel_17_current_decode(
statusFrame.channel_17_current);
}
} else if (channel < 24) {
// Periodic status 3
PDH_status3_t statusFrame = HAL_REV_ReadPDHStatus3(hpdh->hcan, status);
PDH_status_3_t statusFrame = HAL_ReadREVPDHStatus3(hpdh->hcan, status);
switch (channel) {
case 18:
return PDH_status3_channel_18_current_decode(
return PDH_status_3_channel_18_current_decode(
statusFrame.channel_18_current);
case 19:
return PDH_status3_channel_19_current_decode(
return PDH_status_3_channel_19_current_decode(
statusFrame.channel_19_current);
case 20:
return PDH_status3_channel_20_current_decode(
return PDH_status_3_channel_20_current_decode(
statusFrame.channel_20_current);
case 21:
return PDH_status3_channel_21_current_decode(
return PDH_status_3_channel_21_current_decode(
statusFrame.channel_21_current);
case 22:
return PDH_status3_channel_22_current_decode(
return PDH_status_3_channel_22_current_decode(
statusFrame.channel_22_current);
case 23:
return PDH_status3_channel_23_current_decode(
return PDH_status_3_channel_23_current_decode(
statusFrame.channel_23_current);
}
}
return 0;
}
void HAL_REV_GetPDHAllChannelCurrents(HAL_REVPDHHandle handle, double* currents,
int32_t* status) {
auto hpdh = REVPDHHandles->Get(handle);
if (hpdh == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
PDH_status0_t statusFrame0 = HAL_REV_ReadPDHStatus0(hpdh->hcan, status);
PDH_status1_t statusFrame1 = HAL_REV_ReadPDHStatus1(hpdh->hcan, status);
PDH_status2_t statusFrame2 = HAL_REV_ReadPDHStatus2(hpdh->hcan, status);
PDH_status3_t statusFrame3 = HAL_REV_ReadPDHStatus3(hpdh->hcan, status);
currents[0] =
PDH_status0_channel_0_current_decode(statusFrame0.channel_0_current);
currents[1] =
PDH_status0_channel_1_current_decode(statusFrame0.channel_1_current);
currents[2] =
PDH_status0_channel_2_current_decode(statusFrame0.channel_2_current);
currents[3] =
PDH_status0_channel_3_current_decode(statusFrame0.channel_3_current);
currents[4] =
PDH_status0_channel_4_current_decode(statusFrame0.channel_4_current);
currents[5] =
PDH_status0_channel_5_current_decode(statusFrame0.channel_5_current);
currents[6] =
PDH_status1_channel_6_current_decode(statusFrame1.channel_6_current);
currents[7] =
PDH_status1_channel_7_current_decode(statusFrame1.channel_7_current);
currents[8] =
PDH_status1_channel_8_current_decode(statusFrame1.channel_8_current);
currents[9] =
PDH_status1_channel_9_current_decode(statusFrame1.channel_9_current);
currents[10] =
PDH_status1_channel_10_current_decode(statusFrame1.channel_10_current);
currents[11] =
PDH_status1_channel_11_current_decode(statusFrame1.channel_11_current);
currents[12] =
PDH_status2_channel_12_current_decode(statusFrame2.channel_12_current);
currents[13] =
PDH_status2_channel_13_current_decode(statusFrame2.channel_13_current);
currents[14] =
PDH_status2_channel_14_current_decode(statusFrame2.channel_14_current);
currents[15] =
PDH_status2_channel_15_current_decode(statusFrame2.channel_15_current);
currents[16] =
PDH_status2_channel_16_current_decode(statusFrame2.channel_16_current);
currents[17] =
PDH_status2_channel_17_current_decode(statusFrame2.channel_17_current);
currents[18] =
PDH_status3_channel_18_current_decode(statusFrame3.channel_18_current);
currents[19] =
PDH_status3_channel_19_current_decode(statusFrame3.channel_19_current);
currents[20] =
PDH_status3_channel_20_current_decode(statusFrame3.channel_20_current);
currents[21] =
PDH_status3_channel_21_current_decode(statusFrame3.channel_21_current);
currents[22] =
PDH_status3_channel_22_current_decode(statusFrame3.channel_22_current);
currents[23] =
PDH_status3_channel_23_current_decode(statusFrame3.channel_23_current);
}
uint16_t HAL_REV_GetPDHTotalCurrent(HAL_REVPDHHandle handle, int32_t* status) {
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
if (*status != 0) {
return 0;
}
return PDH_status4_total_current_decode(statusFrame.total_current);
}
void HAL_REV_SetPDHSwitchableChannel(HAL_REVPDHHandle handle, HAL_Bool enabled,
void HAL_GetREVPDHAllChannelCurrents(HAL_REVPDHHandle handle, double* currents,
int32_t* status) {
auto hpdh = REVPDHHandles->Get(handle);
if (hpdh == nullptr) {
@@ -450,291 +374,115 @@ void HAL_REV_SetPDHSwitchableChannel(HAL_REVPDHHandle handle, HAL_Bool enabled,
return;
}
uint8_t packedData[8] = {0};
PDH_switch_channel_set_t frame;
frame.output_set_value = enabled;
frame.use_system_enable = false;
PDH_switch_channel_set_pack(packedData, &frame, 1);
PDH_status_0_t statusFrame0 = HAL_ReadREVPDHStatus0(hpdh->hcan, status);
PDH_status_1_t statusFrame1 = HAL_ReadREVPDHStatus1(hpdh->hcan, status);
PDH_status_2_t statusFrame2 = HAL_ReadREVPDHStatus2(hpdh->hcan, status);
PDH_status_3_t statusFrame3 = HAL_ReadREVPDHStatus3(hpdh->hcan, status);
HAL_WriteCANPacket(hpdh->hcan, packedData, PDH_SWITCH_CHANNEL_SET_LENGTH,
PDH_SWITCH_CHANNEL_SET_FRAME_API, status);
currents[0] =
PDH_status_0_channel_0_current_decode(statusFrame0.channel_0_current);
currents[1] =
PDH_status_0_channel_1_current_decode(statusFrame0.channel_1_current);
currents[2] =
PDH_status_0_channel_2_current_decode(statusFrame0.channel_2_current);
currents[3] =
PDH_status_0_channel_3_current_decode(statusFrame0.channel_3_current);
currents[4] =
PDH_status_0_channel_4_current_decode(statusFrame0.channel_4_current);
currents[5] =
PDH_status_0_channel_5_current_decode(statusFrame0.channel_5_current);
currents[6] =
PDH_status_1_channel_6_current_decode(statusFrame1.channel_6_current);
currents[7] =
PDH_status_1_channel_7_current_decode(statusFrame1.channel_7_current);
currents[8] =
PDH_status_1_channel_8_current_decode(statusFrame1.channel_8_current);
currents[9] =
PDH_status_1_channel_9_current_decode(statusFrame1.channel_9_current);
currents[10] =
PDH_status_1_channel_10_current_decode(statusFrame1.channel_10_current);
currents[11] =
PDH_status_1_channel_11_current_decode(statusFrame1.channel_11_current);
currents[12] =
PDH_status_2_channel_12_current_decode(statusFrame2.channel_12_current);
currents[13] =
PDH_status_2_channel_13_current_decode(statusFrame2.channel_13_current);
currents[14] =
PDH_status_2_channel_14_current_decode(statusFrame2.channel_14_current);
currents[15] =
PDH_status_2_channel_15_current_decode(statusFrame2.channel_15_current);
currents[16] =
PDH_status_2_channel_16_current_decode(statusFrame2.channel_16_current);
currents[17] =
PDH_status_2_channel_17_current_decode(statusFrame2.channel_17_current);
currents[18] =
PDH_status_3_channel_18_current_decode(statusFrame3.channel_18_current);
currents[19] =
PDH_status_3_channel_19_current_decode(statusFrame3.channel_19_current);
currents[20] =
PDH_status_3_channel_20_current_decode(statusFrame3.channel_20_current);
currents[21] =
PDH_status_3_channel_21_current_decode(statusFrame3.channel_21_current);
currents[22] =
PDH_status_3_channel_22_current_decode(statusFrame3.channel_22_current);
currents[23] =
PDH_status_3_channel_23_current_decode(statusFrame3.channel_23_current);
}
HAL_Bool HAL_REV_GetPDHSwitchableChannelState(HAL_REVPDHHandle handle,
int32_t* status) {
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
uint16_t HAL_GetREVPDHTotalCurrent(HAL_REVPDHHandle handle, int32_t* status) {
PDH_status_4_t statusFrame = HAL_GetREVPDHStatus4(handle, status);
if (*status != 0) {
return 0.0;
return 0;
}
return PDH_status4_sw_state_decode(statusFrame.sw_state);
return PDH_status_4_total_current_decode(statusFrame.total_current);
}
HAL_Bool HAL_REV_CheckPDHChannelBrownout(HAL_REVPDHHandle handle,
int32_t channel, int32_t* status) {
void HAL_SetREVPDHSwitchableChannel(HAL_REVPDHHandle handle, HAL_Bool enabled,
int32_t* status) {
auto hpdh = REVPDHHandles->Get(handle);
if (hpdh == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
return;
}
if (!HAL_REV_CheckPDHChannelNumber(channel)) {
*status = RESOURCE_OUT_OF_RANGE;
return 0;
}
uint8_t packedData[8] = {0};
PDH_set_switch_channel_t frame;
frame.output_set_value = enabled;
PDH_set_switch_channel_pack(packedData, &frame,
PDH_SET_SWITCH_CHANNEL_LENGTH);
// Determine what periodic status the channel is in
if (channel < 4) {
// Periodic status 0
PDH_status0_t statusFrame = HAL_REV_ReadPDHStatus0(hpdh->hcan, status);
switch (channel) {
case 0:
return PDH_status0_channel_0_brownout_decode(
statusFrame.channel_0_brownout);
case 1:
return PDH_status0_channel_1_brownout_decode(
statusFrame.channel_1_brownout);
case 2:
return PDH_status0_channel_2_brownout_decode(
statusFrame.channel_2_brownout);
case 3:
return PDH_status0_channel_3_brownout_decode(
statusFrame.channel_3_brownout);
}
} else if (channel < 8) {
// Periodic status 1
PDH_status1_t statusFrame = HAL_REV_ReadPDHStatus1(hpdh->hcan, status);
switch (channel) {
case 4:
return PDH_status1_channel_4_brownout_decode(
statusFrame.channel_4_brownout);
case 5:
return PDH_status1_channel_5_brownout_decode(
statusFrame.channel_5_brownout);
case 6:
return PDH_status1_channel_6_brownout_decode(
statusFrame.channel_6_brownout);
case 7:
return PDH_status1_channel_7_brownout_decode(
statusFrame.channel_7_brownout);
}
} else if (channel < 12) {
// Periodic status 2
PDH_status2_t statusFrame = HAL_REV_ReadPDHStatus2(hpdh->hcan, status);
switch (channel) {
case 8:
return PDH_status2_channel_8_brownout_decode(
statusFrame.channel_8_brownout);
case 9:
return PDH_status2_channel_9_brownout_decode(
statusFrame.channel_9_brownout);
case 10:
return PDH_status2_channel_10_brownout_decode(
statusFrame.channel_10_brownout);
case 11:
return PDH_status2_channel_11_brownout_decode(
statusFrame.channel_11_brownout);
}
} else if (channel < 24) {
// Periodic status 3
PDH_status3_t statusFrame = HAL_REV_ReadPDHStatus3(hpdh->hcan, status);
switch (channel) {
case 12:
return PDH_status3_channel_12_brownout_decode(
statusFrame.channel_12_brownout);
case 13:
return PDH_status3_channel_13_brownout_decode(
statusFrame.channel_13_brownout);
case 14:
return PDH_status3_channel_14_brownout_decode(
statusFrame.channel_14_brownout);
case 15:
return PDH_status3_channel_15_brownout_decode(
statusFrame.channel_15_brownout);
case 16:
return PDH_status3_channel_16_brownout_decode(
statusFrame.channel_16_brownout);
case 17:
return PDH_status3_channel_17_brownout_decode(
statusFrame.channel_17_brownout);
case 18:
return PDH_status3_channel_18_brownout_decode(
statusFrame.channel_18_brownout);
case 19:
return PDH_status3_channel_19_brownout_decode(
statusFrame.channel_19_brownout);
case 20:
return PDH_status3_channel_20_brownout_decode(
statusFrame.channel_20_brownout);
case 21:
return PDH_status3_channel_21_brownout_decode(
statusFrame.channel_21_brownout);
case 22:
return PDH_status3_channel_22_brownout_decode(
statusFrame.channel_22_brownout);
case 23:
return PDH_status3_channel_23_brownout_decode(
statusFrame.channel_23_brownout);
}
}
return 0;
HAL_WriteCANPacket(hpdh->hcan, packedData, PDH_SET_SWITCH_CHANNEL_LENGTH,
PDH_SET_SWITCH_CHANNEL_FRAME_API, status);
}
double HAL_REV_GetPDHSupplyVoltage(HAL_REVPDHHandle handle, int32_t* status) {
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
if (*status != 0) {
return 0.0;
}
return PDH_status4_v_bus_decode(statusFrame.v_bus);
}
HAL_Bool HAL_REV_IsPDHEnabled(HAL_REVPDHHandle handle, int32_t* status) {
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
if (*status != 0) {
return false;
}
return PDH_status4_system_enable_decode(statusFrame.system_enable);
}
HAL_Bool HAL_REV_CheckPDHBrownout(HAL_REVPDHHandle handle, int32_t* status) {
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
if (*status != 0) {
return false;
}
return PDH_status4_brownout_decode(statusFrame.brownout);
}
HAL_Bool HAL_REV_CheckPDHCANWarning(HAL_REVPDHHandle handle, int32_t* status) {
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
if (*status != 0) {
return 0.0;
}
return PDH_status4_can_warning_decode(statusFrame.can_warning);
}
HAL_Bool HAL_REV_CheckPDHHardwareFault(HAL_REVPDHHandle handle,
int32_t* status) {
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
if (*status != 0) {
return 0.0;
}
return PDH_status4_hardware_fault_decode(statusFrame.hardware_fault);
}
HAL_Bool HAL_REV_CheckPDHStickyBrownout(HAL_REVPDHHandle handle,
int32_t* status) {
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
if (*status != 0) {
return 0.0;
}
return PDH_status4_sticky_brownout_decode(statusFrame.sticky_brownout);
}
HAL_Bool HAL_REV_CheckPDHStickyCANWarning(HAL_REVPDHHandle handle,
int32_t* status) {
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
if (*status != 0) {
return 0.0;
}
return PDH_status4_sticky_can_warning_decode(statusFrame.sticky_can_warning);
}
HAL_Bool HAL_REV_CheckPDHStickyCANBusOff(HAL_REVPDHHandle handle,
int32_t* status) {
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
if (*status != 0) {
return 0.0;
}
return PDH_status4_sticky_can_bus_off_decode(statusFrame.sticky_can_bus_off);
}
HAL_Bool HAL_REV_CheckPDHStickyHardwareFault(HAL_REVPDHHandle handle,
HAL_Bool HAL_GetREVPDHSwitchableChannelState(HAL_REVPDHHandle handle,
int32_t* status) {
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
PDH_status_4_t statusFrame = HAL_GetREVPDHStatus4(handle, status);
if (*status != 0) {
return 0.0;
}
return PDH_status4_sticky_hardware_fault_decode(
statusFrame.sticky_hardware_fault);
return PDH_status_4_switch_channel_state_decode(
statusFrame.switch_channel_state);
}
HAL_Bool HAL_REV_CheckPDHStickyFirmwareFault(HAL_REVPDHHandle handle,
int32_t* status) {
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
double HAL_GetREVPDHVoltage(HAL_REVPDHHandle handle, int32_t* status) {
PDH_status_4_t statusFrame = HAL_GetREVPDHStatus4(handle, status);
if (*status != 0) {
return 0.0;
}
return PDH_status4_sticky_firmware_fault_decode(
statusFrame.sticky_firmware_fault);
return PDH_status_4_v_bus_decode(statusFrame.v_bus);
}
HAL_Bool HAL_REV_CheckPDHStickyChannelBrownout(HAL_REVPDHHandle handle,
int32_t channel,
int32_t* status) {
if (channel < 20 || channel > 23) {
*status = RESOURCE_OUT_OF_RANGE;
return 0.0;
}
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
if (*status != 0) {
return 0.0;
}
switch (channel) {
case 20:
return PDH_status4_sticky_ch20_brownout_decode(
statusFrame.sticky_ch20_brownout);
case 21:
return PDH_status4_sticky_ch21_brownout_decode(
statusFrame.sticky_ch21_brownout);
case 22:
return PDH_status4_sticky_ch22_brownout_decode(
statusFrame.sticky_ch22_brownout);
case 23:
return PDH_status4_sticky_ch23_brownout_decode(
statusFrame.sticky_ch23_brownout);
}
return 0;
}
HAL_Bool HAL_REV_CheckPDHStickyHasReset(HAL_REVPDHHandle handle,
int32_t* status) {
PDH_status4_t statusFrame = HAL_REV_GetPDHStatus4(handle, status);
if (*status != 0) {
return 0.0;
}
return PDH_status4_sticky_has_reset_decode(statusFrame.sticky_has_reset);
}
REV_PDH_Version HAL_REV_GetPDHVersion(HAL_REVPDHHandle handle,
int32_t* status) {
REV_PDH_Version version;
std::memset(&version, 0, sizeof(version));
void HAL_GetREVPDHVersion(HAL_REVPDHHandle handle,
HAL_PowerDistributionVersion* version,
int32_t* status) {
std::memset(version, 0, sizeof(*version));
uint8_t packedData[8] = {0};
int32_t length = 0;
uint64_t timestamp = 0;
@@ -742,36 +490,141 @@ REV_PDH_Version HAL_REV_GetPDHVersion(HAL_REVPDHHandle handle,
auto hpdh = REVPDHHandles->Get(handle);
if (hpdh == nullptr) {
*status = HAL_HANDLE_ERROR;
return version;
return;
}
if (hpdh->versionInfo.firmwareMajor > 0) {
version->firmwareMajor = hpdh->versionInfo.firmwareMajor;
version->firmwareMinor = hpdh->versionInfo.firmwareMinor;
version->firmwareFix = hpdh->versionInfo.firmwareFix;
version->hardwareMajor = hpdh->versionInfo.hardwareMajor;
version->hardwareMinor = hpdh->versionInfo.hardwareMinor;
version->uniqueId = hpdh->versionInfo.uniqueId;
*status = 0;
return;
}
HAL_WriteCANRTRFrame(hpdh->hcan, PDH_VERSION_LENGTH, PDH_VERSION_FRAME_API,
status);
if (*status != 0) {
return version;
return;
}
HAL_ReadCANPacketTimeout(hpdh->hcan, PDH_VERSION_FRAME_API, packedData,
&length, &timestamp, kDefaultControlPeriod * 2,
status);
uint32_t timeoutMs = 100;
for (uint32_t i = 0; i <= timeoutMs; i++) {
HAL_ReadCANPacketNew(hpdh->hcan, PDH_VERSION_FRAME_API, packedData, &length,
&timestamp, status);
if (*status == 0) {
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
if (*status != 0) {
return version;
return;
}
PDH_version_unpack(&result, packedData, PDH_VERSION_LENGTH);
version.firmwareMajor = result.firmware_year;
version.firmwareMinor = result.firmware_minor;
version.firmwareFix = result.firmware_fix;
version.hardwareRev = result.hardware_code;
version.uniqueId = result.unique_id;
version->firmwareMajor = result.firmware_year;
version->firmwareMinor = result.firmware_minor;
version->firmwareFix = result.firmware_fix;
version->hardwareMinor = result.hardware_minor;
version->hardwareMajor = result.hardware_major;
version->uniqueId = result.unique_id;
return version;
hpdh->versionInfo = *version;
}
void HAL_REV_ClearPDHFaults(HAL_REVPDHHandle handle, int32_t* status) {
void HAL_GetREVPDHFaults(HAL_REVPDHHandle handle,
HAL_PowerDistributionFaults* faults, int32_t* status) {
std::memset(faults, 0, sizeof(*faults));
auto hpdh = REVPDHHandles->Get(handle);
if (hpdh == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
PDH_status_0_t status0 = HAL_ReadREVPDHStatus0(hpdh->hcan, status);
PDH_status_1_t status1 = HAL_ReadREVPDHStatus1(hpdh->hcan, status);
PDH_status_2_t status2 = HAL_ReadREVPDHStatus2(hpdh->hcan, status);
PDH_status_3_t status3 = HAL_ReadREVPDHStatus3(hpdh->hcan, status);
PDH_status_4_t status4 = HAL_ReadREVPDHStatus4(hpdh->hcan, status);
faults->channel0BreakerFault = status0.channel_0_breaker_fault;
faults->channel1BreakerFault = status0.channel_1_breaker_fault;
faults->channel2BreakerFault = status0.channel_2_breaker_fault;
faults->channel3BreakerFault = status0.channel_3_breaker_fault;
faults->channel4BreakerFault = status1.channel_4_breaker_fault;
faults->channel5BreakerFault = status1.channel_5_breaker_fault;
faults->channel6BreakerFault = status1.channel_6_breaker_fault;
faults->channel7BreakerFault = status1.channel_7_breaker_fault;
faults->channel8BreakerFault = status2.channel_8_breaker_fault;
faults->channel9BreakerFault = status2.channel_9_breaker_fault;
faults->channel10BreakerFault = status2.channel_10_breaker_fault;
faults->channel11BreakerFault = status2.channel_11_breaker_fault;
faults->channel12BreakerFault = status3.channel_12_breaker_fault;
faults->channel13BreakerFault = status3.channel_13_breaker_fault;
faults->channel14BreakerFault = status3.channel_14_breaker_fault;
faults->channel15BreakerFault = status3.channel_15_breaker_fault;
faults->channel16BreakerFault = status3.channel_16_breaker_fault;
faults->channel17BreakerFault = status3.channel_17_breaker_fault;
faults->channel18BreakerFault = status3.channel_18_breaker_fault;
faults->channel19BreakerFault = status3.channel_19_breaker_fault;
faults->channel20BreakerFault = status3.channel_20_breaker_fault;
faults->channel21BreakerFault = status3.channel_21_breaker_fault;
faults->channel22BreakerFault = status3.channel_22_breaker_fault;
faults->channel23BreakerFault = status3.channel_23_breaker_fault;
faults->brownout = status4.brownout_fault;
faults->canWarning = status4.can_warning_fault;
faults->hardwareFault = status4.hardware_fault;
}
void HAL_GetREVPDHStickyFaults(HAL_REVPDHHandle handle,
HAL_PowerDistributionStickyFaults* stickyFaults,
int32_t* status) {
std::memset(stickyFaults, 0, sizeof(*stickyFaults));
auto hpdh = REVPDHHandles->Get(handle);
if (hpdh == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
PDH_status_4_t status4 = HAL_ReadREVPDHStatus4(hpdh->hcan, status);
stickyFaults->channel0BreakerFault = status4.sticky_ch0_breaker_fault;
stickyFaults->channel1BreakerFault = status4.sticky_ch1_breaker_fault;
stickyFaults->channel2BreakerFault = status4.sticky_ch2_breaker_fault;
stickyFaults->channel3BreakerFault = status4.sticky_ch3_breaker_fault;
stickyFaults->channel4BreakerFault = status4.sticky_ch4_breaker_fault;
stickyFaults->channel5BreakerFault = status4.sticky_ch5_breaker_fault;
stickyFaults->channel6BreakerFault = status4.sticky_ch6_breaker_fault;
stickyFaults->channel7BreakerFault = status4.sticky_ch7_breaker_fault;
stickyFaults->channel8BreakerFault = status4.sticky_ch8_breaker_fault;
stickyFaults->channel9BreakerFault = status4.sticky_ch9_breaker_fault;
stickyFaults->channel10BreakerFault = status4.sticky_ch10_breaker_fault;
stickyFaults->channel11BreakerFault = status4.sticky_ch11_breaker_fault;
stickyFaults->channel12BreakerFault = status4.sticky_ch12_breaker_fault;
stickyFaults->channel13BreakerFault = status4.sticky_ch13_breaker_fault;
stickyFaults->channel14BreakerFault = status4.sticky_ch14_breaker_fault;
stickyFaults->channel15BreakerFault = status4.sticky_ch15_breaker_fault;
stickyFaults->channel16BreakerFault = status4.sticky_ch16_breaker_fault;
stickyFaults->channel17BreakerFault = status4.sticky_ch17_breaker_fault;
stickyFaults->channel18BreakerFault = status4.sticky_ch18_breaker_fault;
stickyFaults->channel19BreakerFault = status4.sticky_ch19_breaker_fault;
stickyFaults->channel20BreakerFault = status4.sticky_ch20_breaker_fault;
stickyFaults->channel21BreakerFault = status4.sticky_ch21_breaker_fault;
stickyFaults->channel22BreakerFault = status4.sticky_ch22_breaker_fault;
stickyFaults->channel23BreakerFault = status4.sticky_ch23_breaker_fault;
stickyFaults->brownout = status4.sticky_brownout_fault;
stickyFaults->canWarning = status4.sticky_can_warning_fault;
stickyFaults->canBusOff = status4.sticky_can_bus_off_fault;
stickyFaults->hasReset = status4.sticky_has_reset_fault;
}
void HAL_ClearREVPDHStickyFaults(HAL_REVPDHHandle handle, int32_t* status) {
auto hpdh = REVPDHHandles->Get(handle);
if (hpdh == nullptr) {
*status = HAL_HANDLE_ERROR;
@@ -783,16 +636,4 @@ void HAL_REV_ClearPDHFaults(HAL_REVPDHHandle handle, int32_t* status) {
PDH_CLEAR_FAULTS_FRAME_API, status);
}
void HAL_REV_IdentifyPDH(HAL_REVPDHHandle handle, int32_t* status) {
auto hpdh = REVPDHHandles->Get(handle);
if (hpdh == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
uint8_t packedData[8] = {0};
HAL_WriteCANPacket(hpdh->hcan, packedData, PDH_IDENTIFY_LENGTH,
PDH_IDENTIFY_FRAME_API, status);
}
} // extern "C"

View File

@@ -6,6 +6,7 @@
#include <stdint.h>
#include "hal/PowerDistribution.h"
#include "hal/Types.h"
/**
@@ -14,14 +15,6 @@
* @{
*/
struct REV_PDH_Version {
uint32_t firmwareMajor;
uint32_t firmwareMinor;
uint32_t firmwareFix;
uint32_t hardwareRev;
uint32_t uniqueId;
};
#ifdef __cplusplus
extern "C" {
#endif
@@ -32,21 +25,21 @@ extern "C" {
* @param module the device CAN ID (1 .. 63)
* @return the created PDH handle
*/
HAL_REVPDHHandle HAL_REV_InitializePDH(int32_t module,
const char* allocationLocation,
int32_t* status);
HAL_REVPDHHandle HAL_InitializeREVPDH(int32_t module,
const char* allocationLocation,
int32_t* status);
/**
* Frees a PDH device handle.
*
* @param handle the previously created PDH handle
*/
void HAL_REV_FreePDH(HAL_REVPDHHandle handle);
void HAL_FreeREVPDH(HAL_REVPDHHandle handle);
/**
* Gets the module number for a pdh.
*/
int32_t HAL_REV_GetPDHModuleNumber(HAL_REVPDHHandle handle, int32_t* status);
int32_t HAL_GetREVPDHModuleNumber(HAL_REVPDHHandle handle, int32_t* status);
/**
* Checks if a PDH module number is valid.
@@ -56,34 +49,34 @@ int32_t HAL_REV_GetPDHModuleNumber(HAL_REVPDHHandle handle, int32_t* status);
* @param module module number (1 .. 63)
* @return 1 if the module number is valid; 0 otherwise
*/
HAL_Bool HAL_REV_CheckPDHModuleNumber(int32_t module);
HAL_Bool HAL_CheckREVPDHModuleNumber(int32_t module);
/**
* Checks if a PDH channel number is valid.
*
* @param module channel number (0 .. HAL_REV_PDH_NUM_CHANNELS)
* @param module channel number (0 .. kNumREVPDHChannels)
* @return 1 if the channel number is valid; 0 otherwise
*/
HAL_Bool HAL_REV_CheckPDHChannelNumber(int32_t channel);
HAL_Bool HAL_CheckREVPDHChannelNumber(int32_t channel);
/**
* Gets the current of a PDH channel in Amps.
*
* @param handle PDH handle
* @param channel the channel to retrieve the current of (0 ..
* HAL_REV_PDH_NUM_CHANNELS)
* kNumREVPDHChannels)
*
* @return the current of the PDH channel in Amps
*/
double HAL_REV_GetPDHChannelCurrent(HAL_REVPDHHandle handle, int32_t channel,
int32_t* status);
double HAL_GetREVPDHChannelCurrent(HAL_REVPDHHandle handle, int32_t channel,
int32_t* status);
/**
* @param handle PDH handle
* @param currents array of currents
*/
void HAL_REV_GetPDHAllChannelCurrents(HAL_REVPDHHandle handle, double* currents,
int32_t* status);
void HAL_GetREVPDHAllChannelCurrents(HAL_REVPDHHandle handle, double* currents,
int32_t* status);
/**
* Gets the total current of the PDH in Amps, measured to the nearest even
@@ -93,7 +86,7 @@ void HAL_REV_GetPDHAllChannelCurrents(HAL_REVPDHHandle handle, double* currents,
*
* @return the total current of the PDH in Amps
*/
uint16_t HAL_REV_GetPDHTotalCurrent(HAL_REVPDHHandle handle, int32_t* status);
uint16_t HAL_GetREVPDHTotalCurrent(HAL_REVPDHHandle handle, int32_t* status);
/**
* Sets the state of the switchable channel on a PDH device.
@@ -102,8 +95,8 @@ uint16_t HAL_REV_GetPDHTotalCurrent(HAL_REVPDHHandle handle, int32_t* status);
* @param enabled 1 if the switchable channel should be enabled; 0
* otherwise
*/
void HAL_REV_SetPDHSwitchableChannel(HAL_REVPDHHandle handle, HAL_Bool enabled,
int32_t* status);
void HAL_SetREVPDHSwitchableChannel(HAL_REVPDHHandle handle, HAL_Bool enabled,
int32_t* status);
/**
* Gets the current state of the switchable channel on a PDH device.
@@ -114,174 +107,9 @@ void HAL_REV_SetPDHSwitchableChannel(HAL_REVPDHHandle handle, HAL_Bool enabled,
* @param handle PDH handle
* @return 1 if the switchable channel is enabled; 0 otherwise
*/
HAL_Bool HAL_REV_GetPDHSwitchableChannelState(HAL_REVPDHHandle handle,
int32_t* status);
/**
* Checks if a PDH channel is currently experiencing a brownout condition.
*
* NOTE: Not implemented in firmware as of 2021-04-23.
*
* @param handle PDH handle
* @param channel the channel to retrieve the brownout status of
*
* @return 1 if the channel is experiencing a brownout; 0 otherwise
*/
HAL_Bool HAL_REV_CheckPDHChannelBrownout(HAL_REVPDHHandle handle,
int32_t channel, int32_t* status);
/**
* Gets the voltage being supplied to a PDH device.
*
* @param handle PDH handle
*
* @return the voltage at the input of the PDH in Volts
*/
double HAL_REV_GetPDHSupplyVoltage(HAL_REVPDHHandle handle, int32_t* status);
/**
* Checks if a PDH device is currently enabled.
*
* @param handle PDH handle
*
* @return 1 if the PDH is enabled; 0 otherwise
*/
HAL_Bool HAL_REV_IsPDHEnabled(HAL_REVPDHHandle handle, int32_t* status);
/**
* Checks if the input voltage on a PDH device is currently below the minimum
* voltage.
*
* NOTE: Not implemented in firmware as of 2021-04-23.
*
* @param handle PDH handle
*
* @return 1 if the PDH is experiencing a brownout; 0 otherwise
*/
HAL_Bool HAL_REV_CheckPDHBrownout(HAL_REVPDHHandle handle, int32_t* status);
/**
* Checks if the CAN RX or TX error levels on a PDH device have exceeded the
* warning threshold.
*
* NOTE: Not implemented in firmware as of 2021-04-23.
*
* @param handle PDH handle
*
* @return 1 if the device has exceeded the warning threshold; 0
* otherwise
*/
HAL_Bool HAL_REV_CheckPDHCANWarning(HAL_REVPDHHandle handle, int32_t* status);
/**
* Checks if a PDH device is currently malfunctioning.
*
* NOTE: Not implemented in firmware as of 2021-04-23.
*
* @param handle PDH handle
*
* @return 1 if the device is in a hardware fault state; 0
* otherwise
*/
HAL_Bool HAL_REV_CheckPDHHardwareFault(HAL_REVPDHHandle handle,
int32_t* status);
/**
* Checks if the input voltage on a PDH device has gone below the specified
* minimum voltage.
*
* NOTE: Not implemented in firmware as of 2021-04-23.
*
* @param handle PDH handle
*
* @return 1 if the device has had a brownout; 0 otherwise
*/
HAL_Bool HAL_REV_CheckPDHStickyBrownout(HAL_REVPDHHandle handle,
int32_t* status);
/**
* Checks if the CAN RX or TX error levels on a PDH device have exceeded the
* warning threshold.
*
* NOTE: Not implemented in firmware as of 2021-04-23.
*
* @param handle PDH handle
*
* @return 1 if the device has exceeded the CAN warning threshold;
* 0 otherwise
*/
HAL_Bool HAL_REV_CheckPDHStickyCANWarning(HAL_REVPDHHandle handle,
int32_t* status);
/**
* Checks if the CAN bus on a PDH device has previously experienced a 'Bus Off'
* event.
*
* NOTE: Not implemented in firmware as of 2021-04-23.
*
* @param handle PDH handle
*
* @return 1 if the device has experienced a 'Bus Off' event; 0
* otherwise
*/
HAL_Bool HAL_REV_CheckPDHStickyCANBusOff(HAL_REVPDHHandle handle,
int32_t* status);
/**
* Checks if a PDH device has malfunctioned.
*
* NOTE: Not implemented in firmware as of 2021-04-23.
*
* @param handle PDH handle
*
* @return 1 if the device has had a malfunction; 0 otherwise
*/
HAL_Bool HAL_REV_CheckPDHStickyHardwareFault(HAL_REVPDHHandle handle,
HAL_Bool HAL_GetREVPDHSwitchableChannelState(HAL_REVPDHHandle handle,
int32_t* status);
/**
* Checks if the firmware on a PDH device has malfunctioned and reset during
* operation.
*
* NOTE: Not implemented in firmware as of 2021-04-23.
*
* @param handle PDH handle
*
* @return 1 if the device has had a malfunction and reset; 0
* otherwise
*/
HAL_Bool HAL_REV_CheckPDHStickyFirmwareFault(HAL_REVPDHHandle handle,
int32_t* status);
/**
* Checks if a brownout has happened on channels 20-23 of a PDH device while it
* was enabled.
*
* NOTE: Not implemented in firmware as of 2021-04-23.
*
* @param handle PDH handle
* @param channel PDH channel to retrieve sticky brownout status (20 ..
* 23)
*
*
* @return 1 if the channel has had a brownout; 0 otherwise
*/
HAL_Bool HAL_REV_CheckPDHStickyChannelBrownout(HAL_REVPDHHandle handle,
int32_t channel,
int32_t* status);
/**
* Checks if a PDH device has reset.
*
* NOTE: Not implemented in firmware as of 2021-04-23.
*
* @param handle PDH handle
*
* @return 1 if the device has reset; 0 otherwise
*/
HAL_Bool HAL_REV_CheckPDHStickyHasReset(HAL_REVPDHHandle handle,
int32_t* status);
/**
* Gets the firmware and hardware versions of a PDH device.
*
@@ -289,25 +117,46 @@ HAL_Bool HAL_REV_CheckPDHStickyHasReset(HAL_REVPDHHandle handle,
*
* @return version information
*/
REV_PDH_Version HAL_REV_GetPDHVersion(HAL_REVPDHHandle handle, int32_t* status);
void HAL_GetREVPDHVersion(HAL_REVPDHHandle handle,
HAL_PowerDistributionVersion* version,
int32_t* status);
/**
* Gets the voltage being supplied to a PDH device.
*
* @param handle PDH handle
*
* @return the voltage at the input of the PDH in Volts
*/
double HAL_GetREVPDHVoltage(HAL_REVPDHHandle handle, int32_t* status);
/**
* Gets the faults of a PDH device.
*
* @param handle PDH handle
*
* @return the faults of the PDH
*/
void HAL_GetREVPDHFaults(HAL_REVPDHHandle handle,
HAL_PowerDistributionFaults* faults, int32_t* status);
/**
* Gets the sticky faults of a PDH device.
*
* @param handle PDH handle
*
* @return the sticky faults of the PDH
*/
void HAL_GetREVPDHStickyFaults(HAL_REVPDHHandle handle,
HAL_PowerDistributionStickyFaults* stickyFaults,
int32_t* status);
/**
* Clears the sticky faults on a PDH device.
*
* NOTE: Not implemented in firmware as of 2021-04-23.
*
* @param handle PDH handle
*/
void HAL_REV_ClearPDHFaults(HAL_REVPDHHandle handle, int32_t* status);
/**
* Identifies a PDH device by blinking its LED.
*
* NOTE: Not implemented in firmware as of 2021-04-23.
*
* @param handle PDH handle
*/
void HAL_REV_IdentifyPDH(HAL_REVPDHHandle handle, int32_t* status);
void HAL_ClearREVPDHStickyFaults(HAL_REVPDHHandle handle, int32_t* status);
#ifdef __cplusplus
} // extern "C"

View File

@@ -4,6 +4,8 @@
#include "hal/REVPH.h"
#include <thread>
#include <fmt/format.h>
#include "HALInitializer.h"
@@ -23,30 +25,34 @@ static constexpr HAL_CANDeviceType deviceType =
HAL_CANDeviceType::HAL_CAN_Dev_kPneumatics;
static constexpr int32_t kDefaultControlPeriod = 20;
// static constexpr uint8_t kDefaultSensorMask = (1 <<
// HAL_REV_PHSENSOR_DIGITAL);
static constexpr uint8_t kDefaultCompressorDuty = 255;
static constexpr uint8_t kDefaultPressureTarget = 120;
static constexpr uint8_t kDefaultPressureHysteresis = 60;
#define HAL_REV_MAX_PULSE_TIME 65534
#define HAL_REV_MAX_PRESSURE_TARGET 120
#define HAL_REV_MAX_PRESSURE_HYSTERESIS HAL_REV_MAX_PRESSURE_TARGET
#define HAL_REVPH_MAX_PULSE_TIME 65534
static constexpr uint32_t APIFromExtId(uint32_t extId) {
return (extId >> 6) & 0x3FF;
}
static constexpr uint32_t PH_STATUS_0_FRAME_API =
APIFromExtId(PH_STATUS_0_FRAME_ID);
static constexpr uint32_t PH_STATUS_1_FRAME_API =
APIFromExtId(PH_STATUS_1_FRAME_ID);
static constexpr uint32_t PH_SET_ALL_FRAME_API =
APIFromExtId(PH_SET_ALL_FRAME_ID);
static constexpr uint32_t PH_PULSE_ONCE_FRAME_API =
APIFromExtId(PH_PULSE_ONCE_FRAME_ID);
static constexpr uint32_t PH_COMPRESSOR_CONFIG_API =
APIFromExtId(PH_COMPRESSOR_CONFIG_FRAME_ID);
static constexpr uint32_t PH_STATUS0_FRAME_API =
APIFromExtId(PH_STATUS0_FRAME_ID);
static constexpr uint32_t PH_STATUS1_FRAME_API =
APIFromExtId(PH_STATUS1_FRAME_ID);
static constexpr uint32_t PH_CLEAR_FAULTS_FRAME_API =
APIFromExtId(PH_CLEAR_FAULTS_FRAME_ID);
static constexpr uint32_t PH_VERSION_FRAME_API =
APIFromExtId(PH_VERSION_FRAME_ID);
static constexpr int32_t kPHFrameStatus0Timeout = 50;
static constexpr int32_t kPHFrameStatus1Timeout = 50;
@@ -59,6 +65,7 @@ struct REV_PHObj {
wpi::mutex solenoidLock;
HAL_CANHandle hcan;
std::string previousAllocation;
HAL_REVPHVersion versionInfo;
};
} // namespace
@@ -75,38 +82,38 @@ void InitializeREVPH() {
}
} // namespace hal::init
static PH_status0_t HAL_REV_ReadPHStatus0(HAL_CANHandle hcan, int32_t* status) {
static PH_status_0_t HAL_ReadREVPHStatus0(HAL_CANHandle hcan, int32_t* status) {
uint8_t packedData[8] = {0};
int32_t length = 0;
uint64_t timestamp = 0;
PH_status0_t result = {};
PH_status_0_t result = {};
HAL_ReadCANPacketTimeout(hcan, PH_STATUS0_FRAME_API, packedData, &length,
HAL_ReadCANPacketTimeout(hcan, PH_STATUS_0_FRAME_API, packedData, &length,
&timestamp, kPHFrameStatus0Timeout * 2, status);
if (*status != 0) {
return result;
}
PH_status0_unpack(&result, packedData, PH_STATUS0_LENGTH);
PH_status_0_unpack(&result, packedData, PH_STATUS_0_LENGTH);
return result;
}
static PH_status1_t HAL_REV_ReadPHStatus1(HAL_CANHandle hcan, int32_t* status) {
static PH_status_1_t HAL_ReadREVPHStatus1(HAL_CANHandle hcan, int32_t* status) {
uint8_t packedData[8] = {0};
int32_t length = 0;
uint64_t timestamp = 0;
PH_status1_t result = {};
PH_status_1_t result = {};
HAL_ReadCANPacketTimeout(hcan, PH_STATUS1_FRAME_API, packedData, &length,
HAL_ReadCANPacketTimeout(hcan, PH_STATUS_1_FRAME_API, packedData, &length,
&timestamp, kPHFrameStatus1Timeout * 2, status);
if (*status != 0) {
return result;
}
PH_status1_unpack(&result, packedData, PH_STATUS1_LENGTH);
PH_status_1_unpack(&result, packedData, PH_STATUS_1_LENGTH);
return result;
}
@@ -117,9 +124,9 @@ enum REV_SolenoidState {
kSolenoidControlledViaPulse
};
static void HAL_REV_UpdateDesiredPHSolenoidState(REV_PHObj* hph,
int32_t solenoid,
REV_SolenoidState state) {
static void HAL_UpdateDesiredREVPHSolenoidState(REV_PHObj* hph,
int32_t solenoid,
REV_SolenoidState state) {
switch (solenoid) {
case 0:
hph->desiredSolenoidsState.channel_0 = state;
@@ -172,15 +179,15 @@ static void HAL_REV_UpdateDesiredPHSolenoidState(REV_PHObj* hph,
}
}
static void HAL_REV_SendSolenoidsState(REV_PHObj* hph, int32_t* status) {
static void HAL_SendREVPHSolenoidsState(REV_PHObj* hph, int32_t* status) {
uint8_t packedData[PH_SET_ALL_LENGTH] = {0};
PH_set_all_pack(packedData, &(hph->desiredSolenoidsState), PH_SET_ALL_LENGTH);
HAL_WriteCANPacketRepeating(hph->hcan, packedData, PH_SET_ALL_LENGTH,
PH_SET_ALL_FRAME_API, hph->controlPeriod, status);
}
static HAL_Bool HAL_REV_CheckPHPulseTime(int32_t time) {
return ((time > 0) && (time <= HAL_REV_MAX_PULSE_TIME)) ? 1 : 0;
static HAL_Bool HAL_CheckREVPHPulseTime(int32_t time) {
return ((time > 0) && (time <= HAL_REVPH_MAX_PULSE_TIME)) ? 1 : 0;
}
HAL_REVPHHandle HAL_InitializeREVPH(int32_t module,
@@ -217,9 +224,12 @@ HAL_REVPHHandle HAL_InitializeREVPH(int32_t module,
hph->previousAllocation = allocationLocation ? allocationLocation : "";
hph->hcan = hcan;
hph->controlPeriod = kDefaultControlPeriod;
std::memset(&hph->desiredSolenoidsState, 0,
sizeof(hph->desiredSolenoidsState));
std::memset(&hph->versionInfo, 0, sizeof(hph->versionInfo));
// Start closed-loop compressor control by starting solenoid state updates
HAL_REV_SendSolenoidsState(hph.get(), status);
HAL_SendREVPHSolenoidsState(hph.get(), status);
return handle;
}
@@ -249,7 +259,7 @@ HAL_Bool HAL_GetREVPHCompressor(HAL_REVPHHandle handle, int32_t* status) {
return false;
}
PH_status0_t status0 = HAL_REV_ReadPHStatus0(ph->hcan, status);
PH_status_0_t status0 = HAL_ReadREVPHStatus0(ph->hcan, status);
if (*status != 0) {
return false;
@@ -331,7 +341,7 @@ HAL_REVPHCompressorConfigType HAL_GetREVPHCompressorConfig(
return HAL_REVPHCompressorConfigType_kDisabled;
}
PH_status0_t status0 = HAL_REV_ReadPHStatus0(ph->hcan, status);
PH_status_0_t status0 = HAL_ReadREVPHStatus0(ph->hcan, status);
if (*status != 0) {
return HAL_REVPHCompressorConfigType_kDisabled;
@@ -347,7 +357,7 @@ HAL_Bool HAL_GetREVPHPressureSwitch(HAL_REVPHHandle handle, int32_t* status) {
return false;
}
PH_status0_t status0 = HAL_REV_ReadPHStatus0(ph->hcan, status);
PH_status_0_t status0 = HAL_ReadREVPHStatus0(ph->hcan, status);
if (*status != 0) {
return false;
@@ -363,17 +373,17 @@ double HAL_GetREVPHCompressorCurrent(HAL_REVPHHandle handle, int32_t* status) {
return 0;
}
PH_status1_t status1 = HAL_REV_ReadPHStatus1(ph->hcan, status);
PH_status_1_t status1 = HAL_ReadREVPHStatus1(ph->hcan, status);
if (*status != 0) {
return 0;
}
return PH_status1_compressor_current_decode(status1.compressor_current);
return PH_status_1_compressor_current_decode(status1.compressor_current);
}
double HAL_GetREVPHAnalogPressure(HAL_REVPHHandle handle, int32_t channel,
int32_t* status) {
double HAL_GetREVPHAnalogVoltage(HAL_REVPHHandle handle, int32_t channel,
int32_t* status) {
auto ph = REVPHHandles->Get(handle);
if (ph == nullptr) {
*status = HAL_HANDLE_ERROR;
@@ -387,16 +397,138 @@ double HAL_GetREVPHAnalogPressure(HAL_REVPHHandle handle, int32_t channel,
return 0;
}
PH_status0_t status0 = HAL_REV_ReadPHStatus0(ph->hcan, status);
PH_status_0_t status0 = HAL_ReadREVPHStatus0(ph->hcan, status);
if (*status != 0) {
return 0;
}
if (channel == 0) {
return PH_status0_analog_0_decode(status0.analog_0);
return PH_status_0_analog_0_decode(status0.analog_0);
}
return PH_status0_analog_1_decode(status0.analog_1);
return PH_status_0_analog_1_decode(status0.analog_1);
}
double HAL_GetREVPHVoltage(HAL_REVPHHandle handle, int32_t* status) {
auto ph = REVPHHandles->Get(handle);
if (ph == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
}
PH_status_1_t status1 = HAL_ReadREVPHStatus1(ph->hcan, status);
if (*status != 0) {
return 0;
}
return PH_status_1_v_bus_decode(status1.v_bus);
}
double HAL_GetREVPH5VVoltage(HAL_REVPHHandle handle, int32_t* status) {
auto ph = REVPHHandles->Get(handle);
if (ph == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
}
PH_status_1_t status1 = HAL_ReadREVPHStatus1(ph->hcan, status);
if (*status != 0) {
return 0;
}
return PH_status_1_supply_voltage_5_v_decode(status1.supply_voltage_5_v);
}
double HAL_GetREVPHSolenoidCurrent(HAL_REVPHHandle handle, int32_t* status) {
auto ph = REVPHHandles->Get(handle);
if (ph == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
}
PH_status_1_t status1 = HAL_ReadREVPHStatus1(ph->hcan, status);
if (*status != 0) {
return 0;
}
return PH_status_1_solenoid_current_decode(status1.solenoid_current);
}
double HAL_GetREVPHSolenoidVoltage(HAL_REVPHHandle handle, int32_t* status) {
auto ph = REVPHHandles->Get(handle);
if (ph == nullptr) {
*status = HAL_HANDLE_ERROR;
return 0;
}
PH_status_1_t status1 = HAL_ReadREVPHStatus1(ph->hcan, status);
if (*status != 0) {
return 0;
}
return PH_status_1_solenoid_voltage_decode(status1.solenoid_voltage);
}
void HAL_GetREVPHVersion(HAL_REVPHHandle handle, HAL_REVPHVersion* version,
int32_t* status) {
std::memset(version, 0, sizeof(*version));
uint8_t packedData[8] = {0};
int32_t length = 0;
uint64_t timestamp = 0;
PH_version_t result = {};
auto ph = REVPHHandles->Get(handle);
if (ph == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
if (ph->versionInfo.firmwareMajor > 0) {
version->firmwareMajor = ph->versionInfo.firmwareMajor;
version->firmwareMinor = ph->versionInfo.firmwareMinor;
version->firmwareFix = ph->versionInfo.firmwareFix;
version->hardwareMajor = ph->versionInfo.hardwareMajor;
version->hardwareMinor = ph->versionInfo.hardwareMinor;
version->uniqueId = ph->versionInfo.uniqueId;
*status = 0;
return;
}
HAL_WriteCANRTRFrame(ph->hcan, PH_VERSION_LENGTH, PH_VERSION_FRAME_API,
status);
if (*status != 0) {
return;
}
uint32_t timeoutMs = 100;
for (uint32_t i = 0; i <= timeoutMs; i++) {
HAL_ReadCANPacketNew(ph->hcan, PH_VERSION_FRAME_API, packedData, &length,
&timestamp, status);
if (*status == 0) {
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
if (*status != 0) {
return;
}
PH_version_unpack(&result, packedData, PH_VERSION_LENGTH);
version->firmwareMajor = result.firmware_year;
version->firmwareMinor = result.firmware_minor;
version->firmwareFix = result.firmware_fix;
version->hardwareMinor = result.hardware_minor;
version->hardwareMajor = result.hardware_major;
version->uniqueId = result.unique_id;
ph->versionInfo = *version;
}
int32_t HAL_GetREVPHSolenoids(HAL_REVPHHandle handle, int32_t* status) {
@@ -406,7 +538,7 @@ int32_t HAL_GetREVPHSolenoids(HAL_REVPHHandle handle, int32_t* status) {
return 0;
}
PH_status0_t status0 = HAL_REV_ReadPHStatus0(ph->hcan, status);
PH_status_0_t status0 = HAL_ReadREVPHStatus0(ph->hcan, status);
if (*status != 0) {
return 0;
@@ -446,11 +578,11 @@ void HAL_SetREVPHSolenoids(HAL_REVPHHandle handle, int32_t mask, int32_t values,
// The mask bit for the solenoid is set, so we update the solenoid state
REV_SolenoidState desiredSolenoidState =
values & (1 << solenoid) ? kSolenoidEnabled : kSolenoidDisabled;
HAL_REV_UpdateDesiredPHSolenoidState(ph.get(), solenoid,
desiredSolenoidState);
HAL_UpdateDesiredREVPHSolenoidState(ph.get(), solenoid,
desiredSolenoidState);
}
}
HAL_REV_SendSolenoidsState(ph.get(), status);
HAL_SendREVPHSolenoidsState(ph.get(), status);
}
void HAL_FireREVPHOneShot(HAL_REVPHHandle handle, int32_t index, int32_t durMs,
@@ -469,7 +601,7 @@ void HAL_FireREVPHOneShot(HAL_REVPHHandle handle, int32_t index, int32_t durMs,
return;
}
if (!HAL_REV_CheckPHPulseTime(durMs)) {
if (!HAL_CheckREVPHPulseTime(durMs)) {
*status = PARAMETER_OUT_OF_RANGE;
hal::SetLastError(
status,
@@ -480,9 +612,9 @@ void HAL_FireREVPHOneShot(HAL_REVPHHandle handle, int32_t index, int32_t durMs,
{
std::scoped_lock lock{ph->solenoidLock};
HAL_REV_UpdateDesiredPHSolenoidState(ph.get(), index,
kSolenoidControlledViaPulse);
HAL_REV_SendSolenoidsState(ph.get(), status);
HAL_UpdateDesiredREVPHSolenoidState(ph.get(), index,
kSolenoidControlledViaPulse);
HAL_SendREVPHSolenoidsState(ph.get(), status);
}
if (*status != 0) {
@@ -553,58 +685,68 @@ void HAL_FireREVPHOneShot(HAL_REVPHHandle handle, int32_t index, int32_t durMs,
PH_PULSE_ONCE_FRAME_API, status);
}
HAL_REVPHFaults HAL_GetREVPHFaults(HAL_REVPHHandle handle, int32_t* status) {
HAL_REVPHFaults faults = {};
void HAL_GetREVPHFaults(HAL_REVPHHandle handle, HAL_REVPHFaults* faults,
int32_t* status) {
std::memset(faults, 0, sizeof(*faults));
auto ph = REVPHHandles->Get(handle);
if (ph == nullptr) {
*status = HAL_HANDLE_ERROR;
return faults;
return;
}
PH_status0_t status0 = HAL_REV_ReadPHStatus0(ph->hcan, status);
faults.channel0Fault = status0.channel_0_fault;
faults.channel1Fault = status0.channel_1_fault;
faults.channel2Fault = status0.channel_2_fault;
faults.channel3Fault = status0.channel_3_fault;
faults.channel4Fault = status0.channel_4_fault;
faults.channel5Fault = status0.channel_5_fault;
faults.channel6Fault = status0.channel_6_fault;
faults.channel7Fault = status0.channel_7_fault;
faults.channel8Fault = status0.channel_8_fault;
faults.channel9Fault = status0.channel_9_fault;
faults.channel10Fault = status0.channel_10_fault;
faults.channel11Fault = status0.channel_11_fault;
faults.channel12Fault = status0.channel_12_fault;
faults.channel13Fault = status0.channel_13_fault;
faults.channel14Fault = status0.channel_14_fault;
faults.channel15Fault = status0.channel_15_fault;
faults.compressorOverCurrent = status0.compressor_oc;
faults.compressorOpen = status0.compressor_open;
faults.solenoidOverCurrent = status0.solenoid_oc;
faults.brownout = status0.brownout;
faults.canWarning = status0.can_warning;
faults.hardwareFault = status0.hardware_fault;
return faults;
PH_status_0_t status0 = HAL_ReadREVPHStatus0(ph->hcan, status);
faults->channel0Fault = status0.channel_0_fault;
faults->channel1Fault = status0.channel_1_fault;
faults->channel2Fault = status0.channel_2_fault;
faults->channel3Fault = status0.channel_3_fault;
faults->channel4Fault = status0.channel_4_fault;
faults->channel5Fault = status0.channel_5_fault;
faults->channel6Fault = status0.channel_6_fault;
faults->channel7Fault = status0.channel_7_fault;
faults->channel8Fault = status0.channel_8_fault;
faults->channel9Fault = status0.channel_9_fault;
faults->channel10Fault = status0.channel_10_fault;
faults->channel11Fault = status0.channel_11_fault;
faults->channel12Fault = status0.channel_12_fault;
faults->channel13Fault = status0.channel_13_fault;
faults->channel14Fault = status0.channel_14_fault;
faults->channel15Fault = status0.channel_15_fault;
faults->compressorOverCurrent = status0.compressor_oc_fault;
faults->compressorOpen = status0.compressor_open_fault;
faults->solenoidOverCurrent = status0.solenoid_oc_fault;
faults->brownout = status0.brownout_fault;
faults->canWarning = status0.can_warning_fault;
faults->hardwareFault = status0.hardware_fault;
}
HAL_REVPHStickyFaults HAL_GetREVPHStickyFaults(HAL_REVPHHandle handle,
int32_t* status) {
HAL_REVPHStickyFaults stickyFaults = {};
void HAL_GetREVPHStickyFaults(HAL_REVPHHandle handle,
HAL_REVPHStickyFaults* stickyFaults,
int32_t* status) {
std::memset(stickyFaults, 0, sizeof(*stickyFaults));
auto ph = REVPHHandles->Get(handle);
if (ph == nullptr) {
*status = HAL_HANDLE_ERROR;
return stickyFaults;
return;
}
PH_status1_t status1 = HAL_REV_ReadPHStatus1(ph->hcan, status);
stickyFaults.compressorOverCurrent = status1.sticky_compressor_over_current;
stickyFaults.compressorOpen = status1.sticky_compressor_not_present;
stickyFaults.solenoidOverCurrent = status1.sticky_solenoid_over_current;
stickyFaults.brownout = status1.sticky_brownout;
stickyFaults.canWarning = status1.sticky_can_warning;
stickyFaults.canBusOff = status1.sticky_can_bus_off;
stickyFaults.hasReset = status1.sticky_has_reset;
return stickyFaults;
PH_status_1_t status1 = HAL_ReadREVPHStatus1(ph->hcan, status);
stickyFaults->compressorOverCurrent = status1.sticky_compressor_oc_fault;
stickyFaults->compressorOpen = status1.sticky_compressor_open_fault;
stickyFaults->solenoidOverCurrent = status1.sticky_solenoid_oc_fault;
stickyFaults->brownout = status1.sticky_brownout_fault;
stickyFaults->canWarning = status1.sticky_can_warning_fault;
stickyFaults->canBusOff = status1.sticky_can_bus_off_fault;
stickyFaults->hasReset = status1.sticky_has_reset_fault;
}
void HAL_ClearREVPHStickyFaults(HAL_REVPHHandle handle, int32_t* status) {
auto ph = REVPHHandles->Get(handle);
if (ph == nullptr) {
*status = HAL_HANDLE_ERROR;
return;
}
uint8_t packedData[8] = {0};
HAL_WriteCANPacket(ph->hcan, packedData, PH_CLEAR_FAULTS_LENGTH,
PH_CLEAR_FAULTS_FRAME_API, status);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -46,6 +46,7 @@ static JException canMessageNotFoundExCls;
static JException canMessageNotAllowedExCls;
static JException canNotInitializedExCls;
static JException uncleanStatusExCls;
static JClass powerDistributionVersionCls;
static JClass pwmConfigDataResultCls;
static JClass canStatusCls;
static JClass matchInfoDataCls;
@@ -53,15 +54,19 @@ static JClass accumulatorResultCls;
static JClass canDataCls;
static JClass halValueCls;
static JClass baseStoreCls;
static JClass revPHVersionCls;
static const JClassInit classes[] = {
{"edu/wpi/first/hal/PowerDistributionVersion",
&powerDistributionVersionCls},
{"edu/wpi/first/hal/PWMConfigDataResult", &pwmConfigDataResultCls},
{"edu/wpi/first/hal/can/CANStatus", &canStatusCls},
{"edu/wpi/first/hal/MatchInfoData", &matchInfoDataCls},
{"edu/wpi/first/hal/AccumulatorResult", &accumulatorResultCls},
{"edu/wpi/first/hal/CANData", &canDataCls},
{"edu/wpi/first/hal/HALValue", &halValueCls},
{"edu/wpi/first/hal/DMAJNISample$BaseStore", &baseStoreCls}};
{"edu/wpi/first/hal/DMAJNISample$BaseStore", &baseStoreCls},
{"edu/wpi/first/hal/REVPHVersion", &revPHVersionCls}};
static const JExceptionInit exceptions[] = {
{"java/lang/IllegalArgumentException", &illegalArgExCls},
@@ -238,6 +243,19 @@ jobject CreatePWMConfigDataResult(JNIEnv* env, int32_t maxPwm,
static_cast<jint>(deadbandMinPwm), static_cast<jint>(minPwm));
}
jobject CreateREVPHVersion(JNIEnv* env, uint32_t firmwareMajor,
uint32_t firmwareMinor, uint32_t firmwareFix,
uint32_t hardwareMinor, uint32_t hardwareMajor,
uint32_t uniqueId) {
static jmethodID constructor =
env->GetMethodID(revPHVersionCls, "<init>", "(IIIIII)V");
return env->NewObject(
revPHVersionCls, constructor, static_cast<jint>(firmwareMajor),
static_cast<jint>(firmwareMinor), static_cast<jint>(firmwareFix),
static_cast<jint>(hardwareMinor), static_cast<jint>(hardwareMajor),
static_cast<jint>(uniqueId));
}
void SetCanStatusObject(JNIEnv* env, jobject canStatus,
float percentBusUtilization, uint32_t busOffCount,
uint32_t txFullCount, uint32_t receiveErrorCount,
@@ -318,6 +336,21 @@ jobject CreateDMABaseStore(JNIEnv* env, jint valueType, jint index) {
return env->NewObject(baseStoreCls, ctor, valueType, index);
}
jobject CreatePowerDistributionVersion(JNIEnv* env, uint32_t firmwareMajor,
uint32_t firmwareMinor,
uint32_t firmwareFix,
uint32_t hardwareMinor,
uint32_t hardwareMajor,
uint32_t uniqueId) {
static jmethodID constructor =
env->GetMethodID(powerDistributionVersionCls, "<init>", "(IIIIII)V");
return env->NewObject(
powerDistributionVersionCls, constructor,
static_cast<jint>(firmwareMajor), static_cast<jint>(firmwareMinor),
static_cast<jint>(firmwareFix), static_cast<jint>(hardwareMinor),
static_cast<jint>(hardwareMajor), static_cast<jint>(uniqueId));
}
JavaVM* GetJVM() {
return jvm;
}

View File

@@ -59,6 +59,11 @@ jobject CreatePWMConfigDataResult(JNIEnv* env, int32_t maxPwm,
int32_t deadbandMaxPwm, int32_t centerPwm,
int32_t deadbandMinPwm, int32_t minPwm);
jobject CreateREVPHVersion(JNIEnv* env, uint32_t firmwareMajor,
uint32_t firmwareMinor, uint32_t firmwareFix,
uint32_t hardwareMinor, uint32_t hardwareMajor,
uint32_t uniqueId);
void SetCanStatusObject(JNIEnv* env, jobject canStatus,
float percentBusUtilization, uint32_t busOffCount,
uint32_t txFullCount, uint32_t receiveErrorCount,
@@ -77,6 +82,13 @@ jobject CreateHALValue(JNIEnv* env, const HAL_Value& value);
jobject CreateDMABaseStore(JNIEnv* env, jint valueType, jint index);
jobject CreatePowerDistributionVersion(JNIEnv* env, uint32_t firmwareMajor,
uint32_t firmwareMinor,
uint32_t firmwareFix,
uint32_t hardwareMinor,
uint32_t hardwareMajor,
uint32_t uniqueId);
JavaVM* GetJVM();
} // namespace hal

View File

@@ -362,4 +362,63 @@ Java_edu_wpi_first_hal_PowerDistributionJNI_getSwitchableChannelNoError
return state;
}
/*
* Class: edu_wpi_first_hal_PowerDistributionJNI
* Method: getStickyFaultsNative
* Signature: (I)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_PowerDistributionJNI_getStickyFaultsNative
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
HAL_PowerDistributionStickyFaults halFaults;
std::memset(&halFaults, 0, sizeof(halFaults));
HAL_GetPowerDistributionStickyFaults(handle, &halFaults, &status);
CheckStatus(env, status, false);
jint faults;
static_assert(sizeof(faults) == sizeof(halFaults));
std::memcpy(&faults, &halFaults, sizeof(faults));
return faults;
}
/*
* Class: edu_wpi_first_hal_PowerDistributionJNI
* Method: getFaultsNative
* Signature: (I)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_PowerDistributionJNI_getFaultsNative
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
HAL_PowerDistributionFaults halFaults;
std::memset(&halFaults, 0, sizeof(halFaults));
HAL_GetPowerDistributionFaults(handle, &halFaults, &status);
CheckStatus(env, status, false);
jint faults;
static_assert(sizeof(faults) == sizeof(halFaults));
std::memcpy(&faults, &halFaults, sizeof(faults));
return faults;
}
/*
* Class: edu_wpi_first_hal_PowerDistributionJNI
* Method: getVersion
* Signature: (I)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL
Java_edu_wpi_first_hal_PowerDistributionJNI_getVersion
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
HAL_PowerDistributionVersion version;
std::memset(&version, 0, sizeof(version));
HAL_GetPowerDistributionVersion(handle, &version, &status);
CheckStatus(env, status, false);
return CreatePowerDistributionVersion(
env, version.firmwareMajor, version.firmwareMinor, version.firmwareFix,
version.hardwareMinor, version.hardwareMajor, version.uniqueId);
}
} // extern "C"

View File

@@ -196,15 +196,15 @@ Java_edu_wpi_first_hal_REVPHJNI_getPressureSwitch
/*
* Class: edu_wpi_first_hal_REVPHJNI
* Method: getAnalogPressure
* Method: getAnalogVoltage
* Signature: (II)D
*/
JNIEXPORT jdouble JNICALL
Java_edu_wpi_first_hal_REVPHJNI_getAnalogPressure
Java_edu_wpi_first_hal_REVPHJNI_getAnalogVoltage
(JNIEnv* env, jclass, jint handle, jint channel)
{
int32_t status = 0;
auto result = HAL_GetREVPHAnalogPressure(handle, channel, &status);
auto result = HAL_GetREVPHAnalogVoltage(handle, channel, &status);
CheckStatus(env, status, false);
return result;
}
@@ -267,4 +267,137 @@ Java_edu_wpi_first_hal_REVPHJNI_fireOneShot
CheckStatus(env, status, false);
}
/*
* Class: edu_wpi_first_hal_REVPHJNI
* Method: clearStickyFaults
* Signature: (I)V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_REVPHJNI_clearStickyFaults
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
HAL_ClearREVPHStickyFaults(handle, &status);
CheckStatus(env, status, false);
}
/*
* Class: edu_wpi_first_hal_REVPHJNI
* Method: getInputVoltage
* Signature: (I)D
*/
JNIEXPORT jdouble JNICALL
Java_edu_wpi_first_hal_REVPHJNI_getInputVoltage
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
auto voltage = HAL_GetREVPHVoltage(handle, &status);
CheckStatus(env, status, false);
return voltage;
}
/*
* Class: edu_wpi_first_hal_REVPHJNI
* Method: get5VVoltage
* Signature: (I)D
*/
JNIEXPORT jdouble JNICALL
Java_edu_wpi_first_hal_REVPHJNI_get5VVoltage
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
auto voltage = HAL_GetREVPH5VVoltage(handle, &status);
CheckStatus(env, status, false);
return voltage;
}
/*
* Class: edu_wpi_first_hal_REVPHJNI
* Method: getSolenoidCurrent
* Signature: (I)D
*/
JNIEXPORT jdouble JNICALL
Java_edu_wpi_first_hal_REVPHJNI_getSolenoidCurrent
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
auto voltage = HAL_GetREVPHSolenoidCurrent(handle, &status);
CheckStatus(env, status, false);
return voltage;
}
/*
* Class: edu_wpi_first_hal_REVPHJNI
* Method: getSolenoidVoltage
* Signature: (I)D
*/
JNIEXPORT jdouble JNICALL
Java_edu_wpi_first_hal_REVPHJNI_getSolenoidVoltage
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
auto voltage = HAL_GetREVPHSolenoidVoltage(handle, &status);
CheckStatus(env, status, false);
return voltage;
}
/*
* Class: edu_wpi_first_hal_REVPHJNI
* Method: getStickyFaultsNative
* Signature: (I)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_REVPHJNI_getStickyFaultsNative
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
HAL_REVPHStickyFaults halFaults;
std::memset(&halFaults, 0, sizeof(halFaults));
HAL_GetREVPHStickyFaults(handle, &halFaults, &status);
CheckStatus(env, status, false);
jint faults;
static_assert(sizeof(faults) == sizeof(halFaults));
std::memcpy(&faults, &halFaults, sizeof(faults));
return faults;
}
/*
* Class: edu_wpi_first_hal_REVPHJNI
* Method: getFaultsNative
* Signature: (I)I
*/
JNIEXPORT jint JNICALL
Java_edu_wpi_first_hal_REVPHJNI_getFaultsNative
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
HAL_REVPHFaults halFaults;
std::memset(&halFaults, 0, sizeof(halFaults));
HAL_GetREVPHFaults(handle, &halFaults, &status);
CheckStatus(env, status, false);
jint faults;
static_assert(sizeof(faults) == sizeof(halFaults));
std::memcpy(&faults, &halFaults, sizeof(faults));
return faults;
}
/*
* Class: edu_wpi_first_hal_REVPHJNI
* Method: getVersion
* Signature: (I)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL
Java_edu_wpi_first_hal_REVPHJNI_getVersion
(JNIEnv* env, jclass, jint handle)
{
int32_t status = 0;
HAL_REVPHVersion version;
std::memset(&version, 0, sizeof(version));
HAL_GetREVPHVersion(handle, &version, &status);
CheckStatus(env, status, false);
return CreateREVPHVersion(env, version.firmwareMajor, version.firmwareMinor,
version.firmwareFix, version.hardwareMinor,
version.hardwareMajor, version.uniqueId);
}
} // extern "C"

View File

@@ -218,6 +218,89 @@ void HAL_SetPowerDistributionSwitchableChannel(
HAL_Bool HAL_GetPowerDistributionSwitchableChannel(
HAL_PowerDistributionHandle handle, int32_t* status);
struct HAL_PowerDistributionVersion {
uint32_t firmwareMajor;
uint32_t firmwareMinor;
uint32_t firmwareFix;
uint32_t hardwareMinor;
uint32_t hardwareMajor;
uint32_t uniqueId;
};
struct HAL_PowerDistributionFaults {
uint32_t channel0BreakerFault : 1;
uint32_t channel1BreakerFault : 1;
uint32_t channel2BreakerFault : 1;
uint32_t channel3BreakerFault : 1;
uint32_t channel4BreakerFault : 1;
uint32_t channel5BreakerFault : 1;
uint32_t channel6BreakerFault : 1;
uint32_t channel7BreakerFault : 1;
uint32_t channel8BreakerFault : 1;
uint32_t channel9BreakerFault : 1;
uint32_t channel10BreakerFault : 1;
uint32_t channel11BreakerFault : 1;
uint32_t channel12BreakerFault : 1;
uint32_t channel13BreakerFault : 1;
uint32_t channel14BreakerFault : 1;
uint32_t channel15BreakerFault : 1;
uint32_t channel16BreakerFault : 1;
uint32_t channel17BreakerFault : 1;
uint32_t channel18BreakerFault : 1;
uint32_t channel19BreakerFault : 1;
uint32_t channel20BreakerFault : 1;
uint32_t channel21BreakerFault : 1;
uint32_t channel22BreakerFault : 1;
uint32_t channel23BreakerFault : 1;
uint32_t brownout : 1;
uint32_t canWarning : 1;
uint32_t hardwareFault : 1;
};
/**
* Storage for REV PDH Sticky Faults
*/
struct HAL_PowerDistributionStickyFaults {
uint32_t channel0BreakerFault : 1;
uint32_t channel1BreakerFault : 1;
uint32_t channel2BreakerFault : 1;
uint32_t channel3BreakerFault : 1;
uint32_t channel4BreakerFault : 1;
uint32_t channel5BreakerFault : 1;
uint32_t channel6BreakerFault : 1;
uint32_t channel7BreakerFault : 1;
uint32_t channel8BreakerFault : 1;
uint32_t channel9BreakerFault : 1;
uint32_t channel10BreakerFault : 1;
uint32_t channel11BreakerFault : 1;
uint32_t channel12BreakerFault : 1;
uint32_t channel13BreakerFault : 1;
uint32_t channel14BreakerFault : 1;
uint32_t channel15BreakerFault : 1;
uint32_t channel16BreakerFault : 1;
uint32_t channel17BreakerFault : 1;
uint32_t channel18BreakerFault : 1;
uint32_t channel19BreakerFault : 1;
uint32_t channel20BreakerFault : 1;
uint32_t channel21BreakerFault : 1;
uint32_t channel22BreakerFault : 1;
uint32_t channel23BreakerFault : 1;
uint32_t brownout : 1;
uint32_t canWarning : 1;
uint32_t canBusOff : 1;
uint32_t hasReset : 1;
};
void HAL_GetPowerDistributionVersion(HAL_PowerDistributionHandle handle,
HAL_PowerDistributionVersion* version,
int32_t* status);
void HAL_GetPowerDistributionFaults(HAL_PowerDistributionHandle handle,
HAL_PowerDistributionFaults* faults,
int32_t* status);
void HAL_GetPowerDistributionStickyFaults(
HAL_PowerDistributionHandle handle,
HAL_PowerDistributionStickyFaults* stickyFaults, int32_t* status);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@@ -24,6 +24,18 @@ HAL_ENUM(HAL_REVPHCompressorConfigType){
HAL_REVPHCompressorConfigType_kHybrid = 3,
};
/**
* Storage for REV PH Version
*/
struct HAL_REVPHVersion {
uint32_t firmwareMajor;
uint32_t firmwareMinor;
uint32_t firmwareFix;
uint32_t hardwareMinor;
uint32_t hardwareMajor;
uint32_t uniqueId;
};
/**
* Storage for compressor config
*/
@@ -108,8 +120,14 @@ HAL_REVPHCompressorConfigType HAL_GetREVPHCompressorConfig(
HAL_REVPHHandle handle, int32_t* status);
HAL_Bool HAL_GetREVPHPressureSwitch(HAL_REVPHHandle handle, int32_t* status);
double HAL_GetREVPHCompressorCurrent(HAL_REVPHHandle handle, int32_t* status);
double HAL_GetREVPHAnalogPressure(HAL_REVPHHandle handle, int32_t channel,
int32_t* status);
double HAL_GetREVPHAnalogVoltage(HAL_REVPHHandle handle, int32_t channel,
int32_t* status);
double HAL_GetREVPHVoltage(HAL_REVPHHandle handle, int32_t* status);
double HAL_GetREVPH5VVoltage(HAL_REVPHHandle handle, int32_t* status);
double HAL_GetREVPHSolenoidCurrent(HAL_REVPHHandle handle, int32_t* status);
double HAL_GetREVPHSolenoidVoltage(HAL_REVPHHandle handle, int32_t* status);
void HAL_GetREVPHVersion(HAL_REVPHHandle handle, HAL_REVPHVersion* version,
int32_t* status);
int32_t HAL_GetREVPHSolenoids(HAL_REVPHHandle handle, int32_t* status);
void HAL_SetREVPHSolenoids(HAL_REVPHHandle handle, int32_t mask, int32_t values,
@@ -118,10 +136,14 @@ void HAL_SetREVPHSolenoids(HAL_REVPHHandle handle, int32_t mask, int32_t values,
void HAL_FireREVPHOneShot(HAL_REVPHHandle handle, int32_t index, int32_t durMs,
int32_t* status);
HAL_REVPHFaults HAL_GetREVPHFaults(HAL_REVPHHandle handle, int32_t* status);
void HAL_GetREVPHFaults(HAL_REVPHHandle handle, HAL_REVPHFaults* faults,
int32_t* status);
HAL_REVPHStickyFaults HAL_GetREVPHStickyFaults(HAL_REVPHHandle handle,
int32_t* status);
void HAL_GetREVPHStickyFaults(HAL_REVPHHandle handle,
HAL_REVPHStickyFaults* stickyFaults,
int32_t* status);
void HAL_ClearREVPHStickyFaults(HAL_REVPHHandle handle, int32_t* status);
#ifdef __cplusplus
} // extern "C"

View File

@@ -74,6 +74,11 @@ typedef int32_t HAL_Bool;
#ifdef __cplusplus
#define HAL_ENUM(name) enum name : int32_t
#elif defined(__clang__)
#define HAL_ENUM(name) \
enum name : int32_t; \
typedef enum name name; \
enum name : int32_t
#else
#define HAL_ENUM(name) \
typedef int32_t name; \

View File

@@ -320,7 +320,7 @@ int32_t HALSIM_GetNotifierInfo(struct HALSIM_NotifierInfo* arr, int32_t size) {
static_cast<int>(getHandleIndex(handle)));
} else {
std::strncpy(arr[num].name, notifier->name.c_str(),
sizeof(arr[num].name));
sizeof(arr[num].name) - 1);
arr[num].name[sizeof(arr[num].name) - 1] = '\0';
}
arr[num].timeout = notifier->waitTime;

View File

@@ -168,4 +168,16 @@ HAL_Bool HAL_GetPowerDistributionSwitchableChannel(
HAL_PowerDistributionHandle handle, int32_t* status) {
return false;
}
void HAL_GetPowerDistributionVersion(HAL_PowerDistributionHandle handle,
HAL_PowerDistributionVersion* version,
int32_t* status) {}
void HAL_GetPowerDistributionFaults(HAL_PowerDistributionHandle handle,
HAL_PowerDistributionFaults* faults,
int32_t* status) {}
void HAL_GetPowerDistributionStickyFaults(
HAL_PowerDistributionHandle handle,
HAL_PowerDistributionStickyFaults* stickyFaults, int32_t* status) {}
} // extern "C"

View File

@@ -177,8 +177,8 @@ HAL_Bool HAL_GetREVPHPressureSwitch(HAL_REVPHHandle handle, int32_t* status) {
return SimREVPHData[pcm->module].pressureSwitch;
}
double HAL_GetREVPHAnalogPressure(HAL_REVPHHandle handle, int32_t channel,
int32_t* status) {
double HAL_GetREVPHAnalogVoltage(HAL_REVPHHandle handle, int32_t channel,
int32_t* status) {
return 0;
}
@@ -227,3 +227,31 @@ void HAL_SetREVPHSolenoids(HAL_REVPHHandle handle, int32_t mask, int32_t values,
void HAL_FireREVPHOneShot(HAL_REVPHHandle handle, int32_t index, int32_t durMs,
int32_t* status) {}
double HAL_GetREVPHVoltage(HAL_REVPHHandle handle, int32_t* status) {
return 0;
}
double HAL_GetREVPH5VVoltage(HAL_REVPHHandle handle, int32_t* status) {
return 0;
}
double HAL_GetREVPHSolenoidCurrent(HAL_REVPHHandle handle, int32_t* status) {
return 0;
}
double HAL_GetREVPHSolenoidVoltage(HAL_REVPHHandle handle, int32_t* status) {
return 0;
}
void HAL_GetREVPHVersion(HAL_REVPHHandle handle, HAL_REVPHVersion* version,
int32_t* status) {}
void HAL_GetREVPHFaults(HAL_REVPHHandle handle, HAL_REVPHFaults* faults,
int32_t* status) {}
void HAL_GetREVPHStickyFaults(HAL_REVPHHandle handle,
HAL_REVPHStickyFaults* stickyFaults,
int32_t* status) {}
void HAL_ClearREVPHStickyFaults(HAL_REVPHHandle handle, int32_t* status) {}

View File

@@ -5,7 +5,7 @@ project(imgui-download NONE)
include(ExternalProject)
ExternalProject_Add(glfw3
GIT_REPOSITORY https://github.com/glfw/glfw.git
GIT_TAG 3.3.4
GIT_TAG 3.3.6
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/glfw-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/glfw-build"
CONFIGURE_COMMAND ""
@@ -15,7 +15,7 @@ ExternalProject_Add(glfw3
)
ExternalProject_Add(gl3w
GIT_REPOSITORY https://github.com/skaslev/gl3w
GIT_TAG 8418c1b38d195edbd3b20a8f13ec91de6c8c570c
GIT_TAG 3755745085ac2e865fd22270cfe9169c26640f70
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/gl3w-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/gl3w-build"
INSTALL_COMMAND ""
@@ -23,7 +23,7 @@ ExternalProject_Add(gl3w
)
ExternalProject_Add(imgui
GIT_REPOSITORY https://github.com/ocornut/imgui.git
GIT_TAG v1.82
GIT_TAG v1.86
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/imgui-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/imgui-build"
CONFIGURE_COMMAND ""
@@ -33,7 +33,7 @@ ExternalProject_Add(imgui
)
ExternalProject_Add(implot
GIT_REPOSITORY https://github.com/epezent/implot.git
GIT_TAG 555ff688a8134bc0c602123149abe9c17d577475
GIT_TAG 4fcc6e01aca406ef17d5a2dabdcbc9e1bd962c0d
SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/implot-src"
BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/implot-build"
CONFIGURE_COMMAND ""

View File

@@ -162,14 +162,16 @@ model {
lib project: ':wpilibNewCommands', library: 'wpilibNewCommands', linkage: 'shared'
lib project: ':wpilibc', library: 'wpilibc', linkage: 'shared'
lib project: ':wpimath', library: 'wpimath', linkage: 'shared'
lib project: ':cameraserver', library: 'cameraserver', linkage: 'shared'
lib project: ':ntcore', library: 'ntcore', linkage: 'shared'
lib project: ':cscore', library: 'cscore', linkage: 'shared'
lib project: ':ntcore', library: 'ntcoreJNIShared', linkage: 'shared'
lib project: ':cscore', library: 'cscoreJNIShared', linkage: 'shared'
lib project: ':wpimath', library: 'wpimathJNIShared', linkage: 'shared'
lib project: ':wpiutil', library: 'wpiutilJNIShared', linkage: 'shared'
project(':hal').addHalDependency(binary, 'shared')
project(':hal').addHalJniDependency(binary)
lib project: ':wpiutil', library: 'wpiutil', linkage: 'shared'
lib project: ':cameraserver', library: 'cameraserver', linkage: 'shared'
if (binary.targetPlatform.name == nativeUtils.wpi.platforms.roborio) {
nativeUtils.useRequiredLibrary(binary, 'ni_link_libraries', 'ni_runtime_libraries')
} else {
@@ -207,11 +209,11 @@ model {
lib project: ':wpilibNewCommands', library: 'wpilibNewCommands', linkage: 'static'
lib project: ':wpilibc', library: 'wpilibc', linkage: 'static'
lib project: ':wpimath', library: 'wpimath', linkage: 'static'
lib project: ':cameraserver', library: 'cameraserver', linkage: 'static'
lib project: ':ntcore', library: 'ntcore', linkage: 'static'
lib project: ':cscore', library: 'cscore', linkage: 'static'
project(':hal').addHalDependency(binary, 'static')
lib project: ':wpiutil', library: 'wpiutil', linkage: 'static'
lib project: ':cameraserver', library: 'cameraserver', linkage: 'static'
if (binary.targetPlatform.name == nativeUtils.wpi.platforms.roborio) {
nativeUtils.useRequiredLibrary(binary, 'ni_link_libraries', 'ni_runtime_libraries')
}

View File

@@ -0,0 +1,28 @@
cppHeaderFileInclude {
\.h$
\.inc$
\.inl$
}
cppSrcFileInclude {
\.cpp$
}
generatedFileExclude {
src/main/native/resources/
src/main/native/win/roborioteamnumbersetter.ico
src/main/native/mac/rtns.icns
}
repoRootNameOverride {
roborioteamnumbersetter
}
includeOtherLibs {
^GLFW
^fmt/
^imgui
^ntcore
^wpi/
^wpigui
}

View File

@@ -0,0 +1,29 @@
project(roborioteamnumbersetter)
include(CompileWarnings)
include(GenResources)
include(LinkMacOSGUI)
configure_file(src/main/generate/WPILibVersion.cpp.in WPILibVersion.cpp)
GENERATE_RESOURCES(src/main/native/resources generated/main/cpp RTNS rtns rtns_resources_src)
file(GLOB rtns_src src/main/native/cpp/*.cpp ${CMAKE_CURRENT_BINARY_DIR}/WPILibVersion.cpp)
if (WIN32)
set(rtns_rc src/main/native/win/roborioteamnumbersetter.rc)
elseif(APPLE)
set(MACOSX_BUNDLE_ICON_FILE glass.icns)
set(APP_ICON_MACOSX src/main/native/mac/rtns.icns)
set_source_files_properties(${APP_ICON_MACOSX} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
endif()
add_executable(roborioteamnumbersetter ${rtns_src} ${rtns_resources_src} ${rtns_rc} ${APP_ICON_MACOSX})
wpilib_link_macos_gui(roborioteamnumbersetter)
target_link_libraries(roborioteamnumbersetter libglass ${LIBSSH_LIBRARIES})
target_include_directories(roborioteamnumbersetter PRIVATE ${LIBSSH_INCLUDE_DIRS})
if (WIN32)
set_target_properties(roborioteamnumbersetter PROPERTIES WIN32_EXECUTABLE YES)
elseif(APPLE)
set_target_properties(roborioteamnumbersetter PROPERTIES MACOSX_BUNDLE YES OUTPUT_NAME "roborioTeamNumberSetter")
endif()

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleName</key>
<string>roboRIOTeamNumberSetter</string>
<key>CFBundleExecutable</key>
<string>roborioteamnumbersetter</string>
<key>CFBundleDisplayName</key>
<string>roboRIOTeamNumberSetter</string>
<key>CFBundleIdentifier</key>
<string>edu.wpi.first.tools.roboRIOTeamNumberSetter</string>
<key>CFBundleIconFile</key>
<string>rtns.icns</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>MacOSX</string>
</array>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleShortVersionString</key>
<string>2021</string>
<key>CFBundleVersion</key>
<string>2021</string>
<key>LSMinimumSystemVersion</key>
<string>10.11</string>
<key>NSHighResolutionCapable</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,134 @@
import org.gradle.internal.os.OperatingSystem
if (!project.hasProperty('onlylinuxathena') && !project.hasProperty('onlylinuxraspbian') && !project.hasProperty('onlylinuxaarch64bionic')) {
description = "roboRIO Team Number Setter"
apply plugin: 'cpp'
apply plugin: 'c'
apply plugin: 'google-test-test-suite'
apply plugin: 'visual-studio'
apply plugin: 'edu.wpi.first.NativeUtils'
if (OperatingSystem.current().isWindows()) {
apply plugin: 'windows-resources'
}
ext {
nativeName = 'roborioteamnumbersetter'
}
apply from: "${rootDir}/shared/resources.gradle"
apply from: "${rootDir}/shared/config.gradle"
def wpilibVersionFileInput = file("src/main/generate/WPILibVersion.cpp.in")
def wpilibVersionFileOutput = file("$buildDir/generated/main/cpp/WPILibVersion.cpp")
nativeUtils {
nativeDependencyContainer {
libssh(getNativeDependencyTypeClass('WPIStaticMavenDependency')) {
groupId = "edu.wpi.first.thirdparty.frc2022"
artifactId = "libssh"
headerClassifier = "headers"
sourceClassifier = "sources"
ext = "zip"
version = '0.95-1'
targetPlatforms.addAll(nativeUtils.wpi.platforms.desktopPlatforms)
}
}
}
task generateCppVersion() {
description = 'Generates the wpilib version class'
group = 'WPILib'
outputs.file wpilibVersionFileOutput
inputs.file wpilibVersionFileInput
if (wpilibVersioning.releaseMode) {
outputs.upToDateWhen { false }
}
// We follow a simple set of checks to determine whether we should generate a new version file:
// 1. If the release type is not development, we generate a new version file
// 2. If there is no generated version number, we generate a new version file
// 3. If there is a generated build number, and the release type is development, then we will
// only generate if the publish task is run.
doLast {
def version = wpilibVersioning.version.get()
println "Writing version ${version} to $wpilibVersionFileOutput"
if (wpilibVersionFileOutput.exists()) {
wpilibVersionFileOutput.delete()
}
def read = wpilibVersionFileInput.text.replace('${wpilib_version}', version)
wpilibVersionFileOutput.write(read)
}
}
gradle.taskGraph.addTaskExecutionGraphListener { graph ->
def willPublish = graph.hasTask(publish)
if (willPublish) {
generateCppVersion.outputs.upToDateWhen { false }
}
}
def generateTask = createGenerateResourcesTask('main', 'RTNS', 'rtns', project)
project(':').libraryBuild.dependsOn build
tasks.withType(CppCompile) {
dependsOn generateTask
dependsOn generateCppVersion
}
model {
components {
// By default, a development executable will be generated. This is to help the case of
// testing specific functionality of the library.
"${nativeName}"(NativeExecutableSpec) {
baseName = 'roborioteamnumbersetter'
sources {
cpp {
source {
srcDirs 'src/main/native/cpp', "$buildDir/generated/main/cpp"
include '**/*.cpp'
}
exportedHeaders {
srcDirs 'src/main/native/include'
}
}
if (OperatingSystem.current().isWindows()) {
rc {
source {
srcDirs 'src/main/native/win'
include '*.rc'
}
}
}
}
binaries.all {
if (it.targetPlatform.name == nativeUtils.wpi.platforms.roborio || it.targetPlatform.name == nativeUtils.wpi.platforms.raspbian || it.targetPlatform.name == nativeUtils.wpi.platforms.aarch64bionic) {
it.buildable = false
return
}
it.cppCompiler.define("LIBSSH_STATIC")
lib project: ':glass', library: 'glass', linkage: 'static'
lib project: ':wpiutil', library: 'wpiutil', linkage: 'static'
lib project: ':wpigui', library: 'wpigui', linkage: 'static'
nativeUtils.useRequiredLibrary(it, 'imgui_static', 'libssh')
if (it.targetPlatform.operatingSystem.isWindows()) {
it.linker.args << 'Gdi32.lib' << 'Shell32.lib' << 'd3d11.lib' << 'd3dcompiler.lib'
it.linker.args << 'ws2_32.lib' << 'advapi32.lib' << 'crypt32.lib' << 'user32.lib'
} else if (it.targetPlatform.operatingSystem.isMacOsX()) {
it.linker.args << '-framework' << 'Metal' << '-framework' << 'MetalKit' << '-framework' << 'Cocoa' << '-framework' << 'IOKit' << '-framework' << 'CoreFoundation' << '-framework' << 'CoreVideo' << '-framework' << 'QuartzCore'
it.linker.args << '-framework' << 'Kerberos'
} else {
it.linker.args << '-lX11'
}
}
}
}
}
apply from: 'publish.gradle'
}

View File

@@ -0,0 +1,107 @@
apply plugin: 'maven-publish'
def baseArtifactId = 'roboRIOTeamNumberSetter'
def artifactGroupId = 'edu.wpi.first.tools'
def zipBaseName = '_GROUP_edu_wpi_first_tools_ID_roboRIOTeamNumberSetter_CLS'
def outputsFolder = file("$project.buildDir/outputs")
model {
tasks {
// Create the run task.
$.components.roborioteamnumbersetter.binaries.each { bin ->
if (bin.buildable && bin.name.toLowerCase().contains("debug")) {
Task run = project.tasks.create("run", Exec) {
commandLine bin.tasks.install.runScriptFile.get().asFile.toString()
}
run.dependsOn bin.tasks.install
}
}
}
publishing {
def roboRIOTeamNumberSetterTaskList = []
$.components.each { component ->
component.binaries.each { binary ->
if (binary in NativeExecutableBinarySpec && binary.component.name.contains("roborioteamnumbersetter")) {
if (binary.buildable && binary.name.contains("Release")) {
// We are now in the binary that we want.
// This is the default application path for the ZIP task.
def applicationPath = binary.executable.file
def icon = file("$project.projectDir/src/main/native/mac/rtns.icns")
// Create the macOS bundle.
def bundleTask = project.tasks.create("bundleroboRIOTeamNumberSetterOsxApp", Copy) {
description("Creates a macOS application bundle for roboRIO Team Number Setter")
from(file("$project.projectDir/Info.plist"))
into(file("$project.buildDir/outputs/bundles/roboRIOTeamNumberSetter.app/Contents"))
into("MacOS") { with copySpec { from binary.executable.file } }
into("Resources") { with copySpec { from icon } }
doLast {
if (project.hasProperty("developerID")) {
// Get path to binary.
exec {
workingDir rootDir
def args = [
"sh",
"-c",
"codesign --force --strict --deep " +
"--timestamp --options=runtime " +
"--verbose -s ${project.findProperty("developerID")} " +
"$project.buildDir/outputs/bundles/roboRIOTeamNumberSetter.app/"
]
commandLine args
}
}
}
}
// Reset the application path if we are creating a bundle.
if (binary.targetPlatform.operatingSystem.isMacOsX()) {
applicationPath = file("$project.buildDir/outputs/bundles")
project.build.dependsOn bundleTask
}
// Create the ZIP.
def task = project.tasks.create("copyroboRIOTeamNumberSetterExecutable", Zip) {
description("Copies the roboRIOTeamNumberSetter executable to the outputs directory.")
destinationDirectory = outputsFolder
archiveBaseName = '_M_' + zipBaseName
duplicatesStrategy = 'exclude'
classifier = nativeUtils.getPublishClassifier(binary)
from(licenseFile) {
into '/'
}
from(applicationPath)
into(nativeUtils.getPlatformPath(binary))
}
if (binary.targetPlatform.operatingSystem.isMacOsX()) {
bundleTask.dependsOn binary.tasks.link
task.dependsOn(bundleTask)
}
task.dependsOn binary.tasks.link
roboRIOTeamNumberSetterTaskList.add(task)
project.build.dependsOn task
project.artifacts { task }
addTaskToCopyAllOutputs(task)
}
}
}
}
publications {
roborioteamnumbersetter(MavenPublication) {
roboRIOTeamNumberSetterTaskList.each { artifact it }
artifactId = baseArtifactId
groupId = artifactGroupId
version wpilibVersioning.version.get()
}
}
}
}

View File

@@ -0,0 +1,7 @@
/*
* Autogenerated file! Do not manually edit this file. This version is regenerated
* any time the publish task is run, or when this file is deleted.
*/
const char* GetWPILibVersion() {
return "${wpilib_version}";
}

View File

@@ -0,0 +1,265 @@
// 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 <memory>
#include <string_view>
#ifndef _WIN32
#include <arpa/inet.h>
#endif
#include <fmt/format.h>
#include <glass/MainMenuBar.h>
#include <glass/Context.h>
#include <glass/Storage.h>
#include <glass/Window.h>
#include <glass/WindowManager.h>
#include <glass/other/Log.h>
#include <imgui.h>
#include <libssh/libssh.h>
#include <wpi/Logger.h>
#include <wpi/fs.h>
#include <wpigui.h>
#include <unordered_map>
#include <mutex>
#include "wpi/SmallString.h"
#include "DeploySession.h"
#include "wpi/MulticastServiceResolver.h"
namespace gui = wpi::gui;
const char* GetWPILibVersion();
#define GLFWAPI extern "C"
GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
#define GLFW_DONT_CARE -1
GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth,
int minheight, int maxwidth,
int maxheight);
GLFWAPI void glfwSetWindowSize(GLFWwindow* window, int width, int height);
struct TeamNumberRefHolder {
explicit TeamNumberRefHolder(glass::Storage& storage)
: teamNumber{storage.GetInt("TeamNumber", 0)} {}
int& teamNumber;
};
static std::unique_ptr<TeamNumberRefHolder> teamNumberRef;
static std::unordered_map<std::string, std::pair<unsigned int, std::string>>
foundDevices;
static wpi::Logger logger;
static sysid::DeploySession deploySession{logger};
static std::unique_ptr<wpi::MulticastServiceResolver> multicastResolver;
static glass::MainMenuBar gMainMenu;
static void FindDevices() {
WPI_EventHandle resolveEvent = multicastResolver->GetEventHandle();
bool timedOut = 0;
if (wpi::WaitForObject(resolveEvent, 0, &timedOut)) {
auto allData = multicastResolver->GetData();
for (auto&& data : allData) {
// search for MAC
auto macKey =
std::find_if(data.txt.begin(), data.txt.end(),
[](const auto& a) { return a.first == "MAC"; });
if (macKey != data.txt.end()) {
auto& mac = macKey->second;
foundDevices[mac] = std::make_pair(data.ipv4Address, data.hostName);
}
}
}
}
static int minWidth = 400;
static void DisplayGui() {
int& teamNumber = teamNumberRef->teamNumber;
FindDevices();
ImGui::GetStyle().WindowRounding = 0;
// fill entire OS window with this window
ImGui::SetNextWindowPos(ImVec2(0, 0));
int width, height;
glfwGetWindowSize(gui::GetSystemWindow(), &width, &height);
ImGui::SetNextWindowSize(ImVec2(width, height));
ImGui::Begin("Entries", nullptr,
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_MenuBar |
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoCollapse);
ImGui::BeginMenuBar();
gMainMenu.WorkspaceMenu();
gui::EmitViewMenu();
bool about = false;
if (ImGui::BeginMenu("Info")) {
if (ImGui::MenuItem("About")) {
about = true;
}
ImGui::EndMenu();
}
ImGui::EndMenuBar();
if (about) {
ImGui::OpenPopup("About");
}
if (ImGui::BeginPopupModal("About")) {
ImGui::Text("roboRIO Team Number Setter");
ImGui::Separator();
ImGui::Text("v%s", GetWPILibVersion());
ImGui::Separator();
ImGui::Text("Has mDNS Implementation: %d",
static_cast<int>(multicastResolver->HasImplementation()));
ImGui::Separator();
ImGui::Text("Save location: %s", glass::GetStorageDir().c_str());
if (ImGui::Button("Close")) {
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
if (multicastResolver->HasImplementation()) {
ImGui::InputInt("Team Number", &teamNumber);
if (teamNumber < 0) {
teamNumber = 0;
}
int nameWidth = ImGui::CalcTextSize("roboRIO2-0000-FRC.local. ").x;
int macWidth = ImGui::CalcTextSize("88:88:88:88:88:88").x;
int ipAddressWidth = ImGui::CalcTextSize("255.255.255.255").x;
int setWidth = ImGui::CalcTextSize(" Set Team To 99999 ").x;
int blinkWidth = ImGui::CalcTextSize(" Blink ").x;
int rebootWidth = ImGui::CalcTextSize(" Reboot ").x;
minWidth = nameWidth + macWidth + ipAddressWidth + setWidth + blinkWidth +
rebootWidth + 100;
std::string setString = fmt::format("Set team to {}", teamNumber);
if (ImGui::BeginTable("Table", 6)) {
ImGui::TableSetupColumn(
"Name",
ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthFixed,
nameWidth);
ImGui::TableSetupColumn(
"MAC Address",
ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthFixed,
macWidth);
ImGui::TableSetupColumn(
"IP Address",
ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthFixed,
ipAddressWidth);
ImGui::TableSetupColumn(
"Set",
ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthFixed,
setWidth);
ImGui::TableSetupColumn(
"Blink",
ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthFixed,
blinkWidth);
ImGui::TableSetupColumn(
"Reboot",
ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthFixed,
rebootWidth);
ImGui::TableHeadersRow();
for (auto&& i : foundDevices) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("%s", i.second.second.c_str());
ImGui::TableNextColumn();
ImGui::Text("%s", i.first.c_str());
ImGui::TableNextColumn();
struct in_addr in;
in.s_addr = i.second.first;
ImGui::Text("%s", inet_ntoa(in));
ImGui::TableNextColumn();
std::future<int>* future = deploySession.GetFuture(i.first);
ImGui::PushID(i.first.c_str());
if (future) {
ImGui::Button("Deploying");
ImGui::TableNextColumn();
ImGui::TableNextColumn();
const auto fs = future->wait_for(std::chrono::seconds(0));
if (fs == std::future_status::ready) {
deploySession.DestroyFuture(i.first);
}
} else {
if (ImGui::Button(setString.c_str())) {
deploySession.ChangeTeamNumber(i.first, teamNumber, i.second.first);
}
ImGui::TableNextColumn();
if (ImGui::Button("Blink")) {
deploySession.Blink(i.first, i.second.first);
}
ImGui::TableNextColumn();
if (ImGui::Button("Reboot")) {
deploySession.Reboot(i.first, i.second.first);
}
}
ImGui::PopID();
}
ImGui::EndTable();
}
ImGui::Columns(6, "Devices");
// TODO make columns better
} else {
// Missing MDNS Implementation
ImGui::Text("mDNS Implementation is missing.");
#ifdef _WIN32
ImGui::Text("Windows 10 1809 or newer is required for this tool");
#else
ImGui::Text("avahi-client 3 and avahi-core 3 are required for this tool");
ImGui::Text(
"Install libavahi-client3 and libavahi-core3 from your package "
"manager");
#endif
}
ImGui::Columns();
ImGui::End();
glfwSetWindowSizeLimits(gui::GetSystemWindow(), minWidth, 200, GLFW_DONT_CARE,
GLFW_DONT_CARE);
if (width < minWidth) {
width = minWidth;
glfwSetWindowSize(gui::GetSystemWindow(), width, height);
}
}
void Application(std::string_view saveDir) {
gui::CreateContext();
glass::CreateContext();
glass::SetStorageName("roborioteamnumbersetter");
glass::SetStorageDir(saveDir.empty() ? gui::GetPlatformSaveFileDir()
: saveDir);
ssh_init();
teamNumberRef =
std::make_unique<TeamNumberRefHolder>(glass::GetStorageRoot());
multicastResolver =
std::make_unique<wpi::MulticastServiceResolver>("_ni._tcp");
multicastResolver->Start();
gui::AddLateExecute(DisplayGui);
gui::Initialize("roboRIO Team Number Setter", 600, 400);
gui::Main();
multicastResolver->Stop();
multicastResolver = nullptr;
glass::DestroyContext();
gui::DestroyContext();
}

View File

@@ -0,0 +1,186 @@
// 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 "DeploySession.h"
#include <memory>
#include <mutex>
#include <string_view>
#include <unordered_map>
#include <fmt/core.h>
#include <wpi/SmallString.h>
#include <wpi/StringExtras.h>
#include <wpi/uv/Error.h>
#include <wpi/uv/GetAddrInfo.h>
#include <wpi/uv/Work.h>
#include <wpi/uv/util.h>
#include "SshSession.h"
using namespace sysid;
#ifdef ERROR
#undef ERROR
#endif
// Macros to make logging easier.
#define INFO(fmt, ...) WPI_INFO(m_logger, fmt, __VA_ARGS__)
#define DEBUG(fmt, ...) WPI_DEBUG(m_logger, fmt, __VA_ARGS__)
#define ERROR(fmt, ...) WPI_DEBUG(m_logger, fmt, __VA_ARGS__)
#define SUCCESS(fmt, ...) WPI_LOG(m_logger, kLogSuccess, fmt, __VA_ARGS__)
// roboRIO SSH constants.
static constexpr int kPort = 22;
static constexpr std::string_view kUsername = "admin";
static constexpr std::string_view kPassword = "";
std::unordered_map<std::string, std::future<int>> s_outstanding;
DeploySession::DeploySession(wpi::Logger& logger) : m_logger{logger} {}
template <typename T>
struct SafeDeleter {
explicit SafeDeleter(T d) : deleter(d) {}
~SafeDeleter() noexcept { deleter(); }
T deleter;
};
std::future<int>* DeploySession::GetFuture(const std::string& macAddress) {
auto itr = s_outstanding.find(macAddress);
if (itr == s_outstanding.end()) {
return nullptr;
}
return &itr->second;
}
void DeploySession::DestroyFuture(const std::string& macAddress) {
s_outstanding.erase(macAddress);
}
bool DeploySession::ChangeTeamNumber(const std::string& macAddress,
int teamNumber, unsigned int ipAddress) {
auto itr = s_outstanding.find(macAddress);
if (itr != s_outstanding.end()) {
return false;
}
std::future<int> future = std::async(
std::launch::async, [this, ipAddress, teamNumber, mac = macAddress]() {
// Convert to IP address.
wpi::SmallString<16> ip;
in_addr addr;
addr.s_addr = ipAddress;
wpi::uv::AddrToName(addr, &ip);
DEBUG("Trying to establish SSH connection to {}.", ip);
try {
SshSession session{ip.str(), kPort, kUsername, kPassword, m_logger};
session.Open();
DEBUG("SSH connection to {} was successful.", ip);
SUCCESS("{}", "roboRIO Connected!");
try {
session.Execute(fmt::format(
"/usr/local/natinst/bin/nirtcfg "
"--file=/etc/natinst/share/ni-rt.ini --set "
"section=systemsettings,token=host_name,value=roborio-{"
"}-FRC ; sync",
teamNumber));
} catch (const SshSession::SshException& e) {
ERROR("An exception occurred: {}", e.what());
throw e;
}
} catch (const SshSession::SshException& e) {
DEBUG("SSH connection to {} failed with {}.", ip, e.what());
throw e;
}
return 0;
});
s_outstanding[macAddress] = std::move(future);
return true;
}
bool DeploySession::Reboot(const std::string& macAddress,
unsigned int ipAddress) {
auto itr = s_outstanding.find(macAddress);
if (itr != s_outstanding.end()) {
return false;
}
std::future<int> future =
std::async(std::launch::async, [this, ipAddress, mac = macAddress]() {
// Convert to IP address.
wpi::SmallString<16> ip;
in_addr addr;
addr.s_addr = ipAddress;
wpi::uv::AddrToName(addr, &ip);
DEBUG("Trying to establish SSH connection to {}.", ip);
try {
SshSession session{ip.str(), kPort, kUsername, kPassword, m_logger};
session.Open();
DEBUG("SSH connection to {} was successful.", ip);
SUCCESS("{}", "roboRIO Connected!");
try {
session.Execute(fmt::format("sync ; shutdown -r now"));
} catch (const SshSession::SshException& e) {
ERROR("An exception occurred: {}", e.what());
throw e;
}
} catch (const SshSession::SshException& e) {
DEBUG("SSH connection to {} failed with {}.", ip, e.what());
throw e;
}
return 0;
});
s_outstanding[macAddress] = std::move(future);
return true;
}
bool DeploySession::Blink(const std::string& macAddress,
unsigned int ipAddress) {
auto itr = s_outstanding.find(macAddress);
if (itr != s_outstanding.end()) {
return false;
}
std::future<int> future =
std::async(std::launch::async, [this, ipAddress, mac = macAddress]() {
// Convert to IP address.
wpi::SmallString<16> ip;
in_addr addr;
addr.s_addr = ipAddress;
wpi::uv::AddrToName(addr, &ip);
DEBUG("Trying to establish SSH connection to {}.", ip);
try {
SshSession session{ip.str(), kPort, kUsername, kPassword, m_logger};
session.Open();
DEBUG("SSH connection to {} was successful.", ip);
SUCCESS("{}", "roboRIO Connected!");
try {
session.Execute(fmt::format(
"for i in 1 2 3 4 5 ; do ` echo 255 > "
"/sys/class/leds/nilrt:wifi:primary/brightness; sleep 0.5; "
"echo 0 > /sys/class/leds/nilrt:wifi:primary/brightness; sleep "
"0.5 ` ; done"));
} catch (const SshSession::SshException& e) {
ERROR("An exception occurred: {}", e.what());
throw e;
}
} catch (const SshSession::SshException& e) {
DEBUG("SSH connection to {} failed with {}.", ip, e.what());
throw e;
}
return 0;
});
s_outstanding[macAddress] = std::move(future);
return true;
}

View File

@@ -0,0 +1,70 @@
// 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 <atomic>
#include <future>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include <wpi/Logger.h>
namespace sysid {
// Define an integer for a successful message in the log (shown in green on the
// GUI).
static constexpr unsigned int kLogSuccess = 31;
/**
* Represents a single deploy session.
*
* An instance of this class must be kept alive in memory until GetStatus()
* returns kDiscoveryFailure or kDone. Otherwise, the deploy will fail!
*/
class DeploySession {
public:
/** Represents the status of the deploy session. */
enum class Status { kInProgress, kDiscoveryFailure, kDone };
/**
* Constructs an instance of the deploy session.
*
* @param team The team number (or an IP address/hostname).
* @param drive Whether the drive program should be deployed to the roboRIO.
* If this is set to false, the mechanism project will be
* deployed.
* @param config The generation configuration file to be sent to the roboRIO.
* @param logger A reference to a logger where log messages should be sent.
*/
explicit DeploySession(wpi::Logger& logger);
/**
* Executes the deploy. This can be called from any thread.
*/
bool ChangeTeamNumber(const std::string& macAddress, int team,
unsigned int ipAddress);
bool Blink(const std::string& macAddress, unsigned int ipAddress);
bool Reboot(const std::string& macAddress, unsigned int ipAddress);
std::future<int>* GetFuture(const std::string& macAddress);
void DestroyFuture(const std::string& macAddress);
/**
* Returns the state of the deploy session.
*/
Status GetStatus() const;
private:
// Logger reference where log messages will be sent.
wpi::Logger& m_logger;
// The number of hostnames that have completed their resolution/connection
// attempts.
std::atomic_int m_visited = 0;
};
} // namespace sysid

View File

@@ -0,0 +1,143 @@
// 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 "SshSession.h"
#include <fcntl.h>
#include <libssh/libssh.h>
#include <libssh/sftp.h>
#include <stdint.h>
#include <sys/stat.h>
#include <algorithm>
#include <iostream>
#include <stdexcept>
#include <fmt/format.h>
#include <wpi/Logger.h>
using namespace sysid;
#define INFO(fmt, ...) WPI_INFO(m_logger, fmt, __VA_ARGS__)
SshSession::SshSession(std::string_view host, int port, std::string_view user,
std::string_view pass, wpi::Logger& logger)
: m_host{host},
m_port{port},
m_username{user},
m_password{pass},
m_logger{logger} {
// Create a new SSH session.
m_session = ssh_new();
if (!m_session) {
throw SshException("The SSH session could not be allocated.");
}
// Set the host, user, and port.
ssh_options_set(m_session, SSH_OPTIONS_HOST, m_host.c_str());
ssh_options_set(m_session, SSH_OPTIONS_USER, m_username.c_str());
ssh_options_set(m_session, SSH_OPTIONS_PORT, &m_port);
// Set timeout to 3 seconds.
int64_t timeout = 3L;
ssh_options_set(m_session, SSH_OPTIONS_TIMEOUT, &timeout);
// Set other miscellaneous options.
ssh_options_set(m_session, SSH_OPTIONS_STRICTHOSTKEYCHECK, "no");
}
SshSession::~SshSession() {
ssh_disconnect(m_session);
ssh_free(m_session);
}
void SshSession::Open() {
// Connect to the server.
int rc = ssh_connect(m_session);
if (rc != SSH_OK) {
throw SshException(ssh_get_error(m_session));
}
// Authenticate with password.
rc = ssh_userauth_password(m_session, nullptr, m_password.c_str());
if (rc != SSH_AUTH_SUCCESS) {
throw SshException(ssh_get_error(m_session));
}
}
void SshSession::Execute(std::string_view cmd) {
// Allocate a new channel.
ssh_channel channel = ssh_channel_new(m_session);
if (!channel) {
throw SshException(ssh_get_error(m_session));
}
// Open the channel.
int rc = ssh_channel_open_session(channel);
if (rc != SSH_OK) {
throw SshException(ssh_get_error(m_session));
}
// Execute the command.
std::string command{cmd};
rc = ssh_channel_request_exec(channel, command.c_str());
if (rc != SSH_OK) {
ssh_channel_close(channel);
ssh_channel_free(channel);
throw SshException(ssh_get_error(m_session));
}
INFO("{}", cmd);
// Log output.
char buf[512];
int read = ssh_channel_read(channel, buf, sizeof(buf), 0);
if (read != 0) {
INFO("{}", cmd);
}
// Close and free channel.
ssh_channel_close(channel);
ssh_channel_free(channel);
}
void SshSession::Put(std::string_view path, std::string_view contents) {
// Allocate the SFTP session.
sftp_session sftp = sftp_new(m_session);
if (!sftp) {
throw SshException(ssh_get_error(m_session));
}
// Initialize.
int rc = sftp_init(sftp);
if (rc != SSH_OK) {
sftp_free(sftp);
throw SshException(ssh_get_error(m_session));
}
// Copy.
sftp_file file =
sftp_open(sftp, path.data(), O_WRONLY | O_CREAT | O_TRUNC, S_IFMT);
if (!file) {
sftp_free(sftp);
throw SshException(ssh_get_error(m_session));
}
// Send 150K at a time.
static constexpr size_t kChunkSize = 150000;
for (size_t i = 0; i < contents.size(); i += kChunkSize) {
size_t len = (std::min)(kChunkSize, contents.size() - i);
size_t written = sftp_write(file, contents.data() + i, len);
if (written != len) {
sftp_close(file);
sftp_free(sftp);
throw SshException(ssh_get_error(m_session));
}
}
INFO("[SFTP] Deployed {}!", path);
// Close file, free memory.
sftp_close(file);
sftp_free(sftp);
}

View File

@@ -0,0 +1,81 @@
// 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 <libssh/libssh.h>
#include <stdexcept>
#include <string>
#include <string_view>
#include <wpi/Logger.h>
namespace sysid {
/**
* This class is a C++ implementation of the SshSessionController in
* wpilibsuite/deploy-utils. It handles connecting to an SSH server, running
* commands, and transferring files.
*/
class SshSession {
public:
/**
* This is the exception that will be thrown by any of the methods in this
* class if something goes wrong.
*/
class SshException : public std::runtime_error {
public:
explicit SshException(const char* msg) : runtime_error(msg) {}
};
/**
* Constructs a new session controller.
*
* @param host The hostname of the server to connect to.
* @param port The port that the sshd server is operating on.
* @param user The username to login as.
* @param pass The password for the given username.
* @param logger A reference to a logger to log messages to.
*/
SshSession(std::string_view host, int port, std::string_view user,
std::string_view pass, wpi::Logger& logger);
/**
* Destroys the controller object. This also disconnects the session from the
* server.
*/
~SshSession();
/**
* Opens the SSH connection to the given host.
*/
void Open();
/**
* Executes a command and logs the output (if there is any).
*
* @param cmd The command to execute on the server.
*/
void Execute(std::string_view cmd);
/**
* Puts a file on the server using SFTP.
*
* @param path The path to the file to put (on the server).
* @param contents The contents of the file.
*/
void Put(std::string_view path, std::string_view contents);
private:
ssh_session m_session;
std::string m_host;
int m_port;
std::string m_username;
std::string m_password;
wpi::Logger& m_logger;
};
} // namespace sysid

View File

@@ -0,0 +1,25 @@
// 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 <string_view>
void Application(std::string_view saveDir);
#ifdef _WIN32
int __stdcall WinMain(void* hInstance, void* hPrevInstance, char* pCmdLine,
int nCmdShow) {
int argc = __argc;
char** argv = __argv;
#else
int main(int argc, char** argv) {
#endif
std::string_view saveDir;
if (argc == 2) {
saveDir = argv[1];
}
Application(saveDir);
return 0;
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 951 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 974 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

View File

@@ -0,0 +1 @@
IDI_ICON1 ICON "roborioteamnumbersetter.ico"

View File

@@ -32,6 +32,7 @@ include 'crossConnIntegrationTests'
include 'fieldImages'
include 'glass'
include 'outlineviewer'
include 'roborioteamnumbersetter'
include 'simulation:gz_msgs'
include 'simulation:frc_gazebo_plugins'
include 'simulation:halsim_gazebo'

View File

@@ -13,7 +13,7 @@ nativeUtils {
niLibVersion = "2022.2.3"
opencvVersion = "4.5.2-1"
googleTestVersion = "1.9.0-5-437e100-1"
imguiVersion = "1.82-1"
imguiVersion = "1.86-1"
wpimathVersion = "-1"
}
}

View File

@@ -104,9 +104,9 @@ tasks.withType(JavaCompile).configureEach {
}
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.4.2'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.4.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.4.2'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.2'
testImplementation 'org.junit.jupiter:junit-jupiter-params:5.8.2'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
devImplementation sourceSets.main.output
}
@@ -120,7 +120,7 @@ task run(type: JavaExec) {
build.dependsOn devClasses
jacoco {
toolVersion = "0.8.4"
toolVersion = "0.8.7"
}
jacocoTestReport {

View File

@@ -2,7 +2,7 @@ if (!project.hasProperty('skipJavaFormat')) {
apply plugin: 'checkstyle'
checkstyle {
toolVersion = "8.38"
toolVersion = "9.2"
configDirectory = file("${project.rootDir}/styleguide")
config = resources.text.fromFile(new File(configDirectory.get().getAsFile(), "checkstyle.xml"))
}
@@ -10,7 +10,7 @@ if (!project.hasProperty('skipJavaFormat')) {
apply plugin: 'pmd'
pmd {
toolVersion = '6.7.0'
toolVersion = '6.41.0'
consoleOutput = true
reportsDir = file("$project.buildDir/reports/pmd")
ruleSetFiles = files(new File(rootDir, "styleguide/pmd-ruleset.xml"))

View File

@@ -24,6 +24,8 @@ try {
} catch(Exception ex) {
}
ext.skip_gz_msgs = false
if (project.hasProperty("forceGazebo")) {
if (!protobuf_version?.trim()) {
println "Protobuf is not available. (pkg-config --modversion protobuf failed)"
@@ -38,9 +40,11 @@ tasks.whenTaskAdded { task ->
task.onlyIf { !project.hasProperty('skip_gz_msgs') }
}
dependencies {
implementation "com.google.protobuf:protobuf-java:${protobuf_version}"
implementation "com.google.protobuf:protoc:${protobuf_version}"
if (!ext.skip_gz_msgs) {
dependencies {
implementation "com.google.protobuf:protobuf-java:${protobuf_version}"
implementation "com.google.protobuf:protoc:${protobuf_version}"
}
}
/* There is a nice gradle plugin for protobuf, and the protoc tool

View File

@@ -266,7 +266,7 @@ module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF" />
</module>
<module name="JavadocMethod">
<property name="scope" value="public" />
<property name="accessModifiers" value="public" />
<property name="allowMissingParamTags" value="true" />
<property name="allowMissingReturnTag" value="true" />
<property name="allowedAnnotations" value="Override, Test" />

View File

@@ -37,6 +37,7 @@
<rule ref="category/java/design.xml">
<exclude name="AvoidThrowingRawExceptionTypes" />
<exclude name="CognitiveComplexity" />
<exclude name="CyclomaticComplexity" />
<exclude name="DataClass" />
<exclude name="ExcessiveClassLength" />
@@ -60,9 +61,10 @@
<exclude name="AvoidDuplicateLiterals" />
<exclude name="AvoidLiteralsInIfCondition" />
<exclude name="BeanMembersShouldSerialize" />
<exclude name="CloseResource" />
<exclude name="ConstructorCallsOverridableMethod" />
<exclude name="DataflowAnomalyAnalysis" />
<exclude name="DoNotCallSystemExit" />
<exclude name="DoNotTerminateVM" />
<exclude name="FinalizeDoesNotCallSuperFinalize" />
<exclude name="JUnitSpelling" />
<exclude name="MissingSerialVersionUID" />
@@ -83,8 +85,8 @@
<rule name="UnnecessaryCastRule" language="java"
message="Avoid unnecessary casts"
class="net.sourceforge.pmd.lang.java.rule.migrating.UnnecessaryCastRule"
externalInfoUrl="https://github.com/pmd/pmd/blob/master/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/migrating/UnnecessaryCastRule.java" />
class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryCastRule"
externalInfoUrl="https://github.com/pmd/pmd/blob/master/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/rule/codestyle/UnnecessaryCastRule.java" />
<!-- Custom Rules -->
<rule name="UseRequireNonNull"

View File

@@ -1,5 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
<Match>
<Bug pattern="DCN_NULLPOINTER_EXCEPTION" />
<Class name="edu.wpi.first.wpilibj.test.TestSuite" />
</Match>
<Match>
<Bug pattern="DM_DEFAULT_ENCODING" />
</Match>
@@ -15,6 +19,10 @@
<Match>
<Bug pattern="EI_EXPOSE_REP2" />
</Match>
<Match>
<Bug pattern="IS2_INCONSISTENT_SYNC" />
<Source name="MechanismLigament2d.java" />
</Match>
<Match>
<Bug pattern="MS_CANNOT_BE_FINAL" />
<Class name="edu.wpi.first.wpilibj.examples.pacgoat.Robot" />
@@ -72,6 +80,14 @@
<Bug pattern="UC_USELESS_VOID_METHOD" />
<Class name="edu.wpi.first.wpilibj.templates.timed.Robot" />
</Match>
<Match>
<Bug pattern="URF_UNREAD_FIELD" />
<Class name="edu.wpi.first.wpilibj.ADIS16448_IMU" />
</Match>
<Match>
<Bug pattern="URF_UNREAD_FIELD" />
<Class name="edu.wpi.first.wpilibj.ADIS16470_IMU" />
</Match>
<Match>
<Bug pattern="URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD" />
</Match>

View File

@@ -0,0 +1,42 @@
diff --git a/wpiutil/src/main/native/fmtlib/include/fmt/format-inl.h b/wpiutil/src/main/native/fmtlib/include/fmt/format-inl.h
index 2c51c50ae..cc89abdd3 100644
--- a/wpiutil/src/main/native/fmtlib/include/fmt/format-inl.h
+++ b/wpiutil/src/main/native/fmtlib/include/fmt/format-inl.h
@@ -92,8 +92,7 @@ FMT_FUNC void report_error(format_func func, int error_code,
// A wrapper around fwrite that throws on error.
inline void fwrite_fully(const void* ptr, size_t size, size_t count,
FILE* stream) {
- size_t written = std::fwrite(ptr, size, count, stream);
- if (written < count) FMT_THROW(system_error(errno, "cannot write to file"));
+ std::fwrite(ptr, size, count, stream);
}
#ifndef FMT_STATIC_THOUSANDS_SEPARATOR
diff --git a/wpiutil/src/main/native/fmtlib/include/fmt/xchar.h b/wpiutil/src/main/native/fmtlib/include/fmt/xchar.h
index 55825077f..9acb893fa 100644
--- a/wpiutil/src/main/native/fmtlib/include/fmt/xchar.h
+++ b/wpiutil/src/main/native/fmtlib/include/fmt/xchar.h
@@ -207,8 +207,7 @@ inline void vprint(std::FILE* f, wstring_view fmt, wformat_args args) {
wmemory_buffer buffer;
detail::vformat_to(buffer, fmt, args);
buffer.push_back(L'\0');
- if (std::fputws(buffer.data(), f) == -1)
- FMT_THROW(system_error(errno, FMT_STRING("cannot write to file")));
+ std::fputws(buffer.data(), f);
}
inline void vprint(wstring_view fmt, wformat_args args) {
diff --git a/wpiutil/src/main/native/fmtlib/src/os.cpp b/wpiutil/src/main/native/fmtlib/src/os.cpp
index 04b4dc506..4eb3e1fdd 100644
--- a/wpiutil/src/main/native/fmtlib/src/os.cpp
+++ b/wpiutil/src/main/native/fmtlib/src/os.cpp
@@ -277,8 +277,7 @@ std::size_t file::read(void* buffer, std::size_t count) {
std::size_t file::write(const void* buffer, std::size_t count) {
rwresult result = 0;
FMT_RETRY(result, FMT_POSIX_CALL(write(fd_, buffer, convert_rwcount(count))));
- if (result < 0) FMT_THROW(system_error(errno, "cannot write to file"));
- return detail::to_unsigned(result);
+ return count;
}
file file::dup(int fd) {

View File

@@ -8,7 +8,7 @@ from upstream_utils import setup_upstream_repo, comment_out_invalid_includes, wa
def main():
root, repo = setup_upstream_repo("https://github.com/RobotLocomotion/drake",
"v0.36.0")
"v0.37.0")
wpimath = os.path.join(root, "wpimath")
# Delete old install

View File

@@ -3,11 +3,11 @@
import os
import shutil
from upstream_utils import setup_upstream_repo, comment_out_invalid_includes, walk_cwd_and_copy_if
from upstream_utils import setup_upstream_repo, comment_out_invalid_includes, walk_cwd_and_copy_if, apply_patches
def main():
root, repo = setup_upstream_repo("https://github.com/fmtlib/fmt", "8.0.1")
root, repo = setup_upstream_repo("https://github.com/fmtlib/fmt", "8.1.1")
wpiutil = os.path.join(root, "wpiutil")
# Delete old install
@@ -31,6 +31,9 @@ def main():
comment_out_invalid_includes(
f, [os.path.join(wpiutil, "src/main/native/fmtlib/include")])
apply_patches(root,
["upstream_utils/fmt-dont-throw-on-write-failure.patch"])
if __name__ == "__main__":
main()

View File

@@ -27,5 +27,4 @@ includeOtherLibs {
^imgui
^implot
^stb
^wpi/
}

View File

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

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