Squashed 'third_party/allwpilib/' changes from f1a82828fe..ce550705d7
ce550705d7 [ntcore] Fix client "received unknown id -1" (#6186)
3989617bde [ntcore] NetworkTable::GetStruct: Add I template param (#6183)
f1836e1321 [fieldImages] Fix 2024 field json (#6179)
d05f179a9a [build] Fix running apriltagsvision Java example (#6173)
b1b03bed85 [wpilib] Update MotorControllerGroup deprecation message (#6171)
fa63fbf446 LICENSE.md: Bump year to 2024 (#6169)
4809f3d0fc [apriltag] Add 2024 AprilTag locations (#6168)
dd90965362 [wpiutil] Fix RawFrame.setInfo() NPE (#6167)
8659372d08 [fieldImages] Add 2024 field image (#6166)
a2e4d0b15d [docs] Fix docs for SysID routine (#6164)
0a46a3a618 [wpilib] Make ADXL345 default I2C address public (#6163)
7c26bc70ab [sysid] Load DataLog files directly for analysis (#6103)
f94e3d81b9 [docs] Fix SysId routine JavaDoc warnings (#6159)
6bed82a18e [wpilibc] Clean up C++ SysId routine (#6160)
4595f84719 [wpilib] Report LiveWindow-enabled-in-test (#6158)
707cb06105 [wpilib] Add SysIdRoutine logging utility and command factory (#6033)
3e40b9e5da [wpilib] Correct SmartDashboard usage reporting (#6157)
106518c3f8 [docs] Fix wpilibj JavaDoc warnings (#6154)
19cb2a8eb4 [wpilibj] Make class variables private to match C++ (#6153)
13f4460e00 [docs] Add missing docs to enum fields (NFC) (#6150)
4210f5635d [docs] Fix warnings about undocumented default constructors (#6151)
0f060afb55 [ntcore] Disable WebSocket fragmentation (#6149)
f29a7d2e50 [docs] Add missing JavaDocs (#6146)
6e58db398d [commands] Make Java fields private (#6148)
4ac0720385 [build] Clean up CMake files (#6141)
44db3e0ac0 [sysid] Make constexpr variables outside class scope inline (#6145)
73c7d87db7 [glass] NTStringChooser: Properly set retained (#6144)
25636b712f [build] Remove unnecessary native dependencies in wpilibjExamples (#6143)
01fb98baaa [docs] Add Missing JNI docs from C++ (NFC) (#6139)
5c424248c4 [wpilibj] Remove unused AnalogTriggerException (#6142)
c486972c55 [wpimath] Make ExponentialProfile.State mutable (#6138)
783acb9b72 [wpilibj] Store long preferences as integers (#6136)
99ab836894 [wpiutil] Add missing JavaDocs (NFC) (#6132)
ad0859a8c9 [docs] Add missing JavaDocs (#6125)
5579219716 [docs] Exclude quickbuf files and proto/struct packages from doclint (#6128)
98f06911c7 [sysid] Use eigenvector component instead of eigenvalue for fit quality check (#6131)
e1d49b975c [wpimath] Add LinearFilter reset() overload to initialize input and output buffers (#6133)
8a0bf2b7a4 [hal] Add CANAPITypes to java (#6121)
91d8837c11 [wpilib] Make protected fields in accelerometers/gyros private (#6134)
e7c9f27683 [wpilib] Add functional interface equivalents to MotorController (#6053)
8aca706217 [glass] Add type information to SmartDashboard menu (#6117)
7d3e4ddba9 [docs] Add warning about using user button to docs (NFC) (#6129)
ec3cb3dcba [build] Disable clang-tidy warning about test case names (#6127)
495585b25d [examples] Update april tag family to 36h11 (#6126)
f9aabc5ab2 [wpilib] Throw early when EventLoop is modified while running (#6115)
c16946c0ec [hal] Add CANJNI docs (NFC) (#6120)
b7f4eb2811 [doc] Update maven artifacts for units and apriltags (NFC) (#6123)
f419a62b38 [doc] Update maintainers.md (NFC) (#6124)
938bf45fd9 [wpiutil] Remove type param from ProtobufSerializable and StructSerializable (#6122)
c34debe012 [docs] Link to external OpenCV docs (#6119)
07183765de [hal] Fix formatting of HAL_ENUM enums (NFC) (#6114)
af46034b7f [wpilib] Document only first party controllers are guaranteed to have correct mapping (#6112)
636ef58d94 [hal] Properly error check readCANStreamSession (#6108)
cc631d2a69 [build] Fix generated source set location in the HAL (#6113)
09f76b32c2 [wpimath] Compile with UTF-8 encoding (#6111)
47c5fd8620 [sysid] Check data quality before OLS (#6110)
24a76be694 [hal] Add method to detect if the CAN Stream has overflowed (#6105)
9333951736 [hal] Allocate CANStreamMessage in JNI if null (#6107)
6a2d3c30a6 [wpiutil] Struct: Add info template parameter pack (#6086)
e07de37e64 [commands] Mark ParallelDeadlineGroup.setDeadline() final (#6102)
141241d2d6 [wpilib] Fix usage reporting for static classes (#6090)
f2c2bab7dc [sysid] Fix adjusted R² calculation (#6101)
5659038443 [wpiutil,cscore,apriltag] Fix RawFrame (#6098)
8aeee03626 [commands] Improve error message when composing commands twice in same composition (#6091)
55508706ff [wpiutil,cscore] Move VideoMode.PixelFormat to wpiutil (#6097)
ab78b930e9 [wpilib] ADIS16470: Add access to all 3 axes (#6074)
795d4be9fd [wpilib] Fix precision issue in Color round-and-clamp (#6100)
7aa9ad44b8 [commands] Deprecate C++ TransferOwnership() (#6095)
92c81d0791 [ci] Update pregenerate workflow to actions/checkout@v4 (#6094)
1ce617be07 [ci] Update artifact actions to v4 (#6092)
2441b57156 [wpilib] Add PWMSparkFlex MotorController (#6089)
21d1972d7a [wpiutil] DataLog: Ensure file is written on shutdown (#6087)
c29e8c66cf [wpiutil] DataLog: Fix UB in AppendImpl (#6088)
ab309e34ef [glass] Fix order of loading window settings (#6056)
22a322c9f3 [wpimath] Report error on negative PID gains (#6055)
1dba26c937 [wpilib] Add method to get breaker fault at a specific channel in PowerDistribution[Sticky]Faults (#5521)
ef1cb3f41e [commands] Fix compose-while-scheduled issue and test all compositions (#5581)
aeb1a4aa33 [wpiutil] Add serializable marker interfaces (#6060)
c1178d5add [wpilib] Add StadiaController and command wrapper (#6083)
4e4a468d4d [wpimath] Make feedforward classes throw exceptions for negative Kv or Ka (#6084)
d1793f077d [build] cmake: Add NO_WERROR option to disable -Werror (#6071)
43fb6e9f87 [glass] Add Profiled PID controller support & IZone Support (#5959)
bcef6c5398 [apriltag] Fix Java generation functions (#6063)
4059e0cd9f [hal,wpilib] Add function to control "Radio" LED (#6073)
0b2cfb3abc [dlt] Change datalogtool default folder to logs folder (#6079)
df5e439b0c [wpilib] PS4Controller: enable usage reporting (#6081)
0ff7478968 [cscore] Fix RawFrame class not being loaded in JNI (#6077)
6f23d32fe1 [wpilib] AddressableLED: Update warning about single driver (NFC) (#6069)
35a1c52788 [build] Upgrade quickbuf to 1.3.3 (#6072)
e4e2bafdb1 [sysid] Document timestamp units (#6065)
3d201c71f7 [ntcore] Fix overlapping subscriber handling (#6067)
f02984159f [glass] Check for null entries when updating struct/proto (#6059)
a004c9e05f [commands] SubsystemBase: allow setting name in constructor (#6052)
0b4c6a1546 [wpimath] Add more docs to SimulatedAnnealing (NFC) (#6054)
ab15dae887 [wpilib] ArcadeDrive: Fix max output handling (#6051)
9599c1f56f [hal] Add usage reporting ids from 2024v2 image (#6041)
f87c64af8a [wpimath] MecanumDriveWheelSpeeds: Fix desaturate() (#6040)
8798700cec [wpilibcExamples] Add inline specifier to constexpr constants (#6049)
85c9ae6eff [wpilib] Fix PS5 Controller mappings (#6050)
7c8b7a97ad [wpiutil] Zero out roborio system timestamp (#6042)
d9b504bc84 [wpilib] DataLogManager: Change sim location to logs subdir (#6039)
906b810136 [build] cmake: Fix ntcore generated header install (#6038)
56e5b404d1 Update to final 2024 V2 image (#6034)
8723ee5c39 [ntcore] Add cached topic property (#5494)
192a28af47 Fix JDK 21 warnings (#6028)
d40bdd70ba [build] Upgrade to spotbugs Gradle plugin 6.0.2 (#6027)
7bfadf32e5 [wpilibj] Joystick: make remainder of get axis methods final (#6024)
a770110438 [commands] CommandCompositionError: Include stacktrace of original composition (#5984)
54a55b8b53 [wpiutil,hal] Update image; init Rio Now() HMB with a FPGA session (#6016)
7d4e515a6b [wpimath] Simplify calculation of C for DARE precondition (#6022)
5200316c14 [ntcore] Update transmit period on topic add/remove (#6021)
ddf79a25d4 [wpiunits] Overload Measure.per(Time) to return Measure<Velocity> (#6018)
a71adef316 [wpiutil] Clean up circular_buffer iterator syntax (#6020)
39a0bf4b98 [examples] Call resetOdometry() when controller command is executed (#5905)
f5fc101fda [build] cmake: Export jars and clean up jar installs (#6014)
38bf024c96 [build] Update to Gradle 8.5 (#6007)
9d11544c18 [wpimath] Rotate traveling salesman solution so input and solution have same initial pose (#6015)
28deba20f5 [wpimath] Commit generated quickbuf Java files (#5994)
c2971c0bb3 [build] cmake: Export apriltag and wpimath (#6012)
41cfc961e4 gitattributes: Add linguist-generated locations (#6004)
14c3ade155 [wpimath] Struct cleanup (#6011)
90757b9e90 [wpilib] Make Color::HexString() constexpr (#5985)
2676b77873 Fix compilation issues that occur when building with bazel (#6008)
d32c10487c [examples] Update C++ examples to use CommandPtr (#5988)
9bc5fcf886 [build] cmake: Default WITH_JAVA_SOURCE to WITH_JAVA (#6005)
d431abba3b [upstream_utils] Fix GCEM namespace usage and add hypot(x, y, z) (#6002)
2bb1409b82 Clean up Java style (#5990)
66172ab288 Remove submodule (#6003)
e8f8c0ceb0 [upstream_utils] Update to latest Eigen HEAD (#5996)
890992a849 [hal] Commit generated usage reporting files (#5993)
a583ca01e1 [wpiutil] Change Struct to allow non-constexpr implementation (#5992)
ca272de400 [build] Fix Gradle compile_commands.json and clang-tidy warnings (#5977)
76ae090570 [wpiutil] type_traits: Add is_constexpr() (#5997)
5172ab8fd0 [commands] C++ CommandPtr: Prevent null initialization (#5991)
96914143ba [build] Bump native-utils to fix compile_commands.json (#5989)
464e6121ef [ci] Report failed status to Azure on failed tests (#2654)
5dad46cd45 [wpimath] Commit generated files (#5986)
54ab65a63a [ntcore] Commit generated files (#5962)
7ed900ae3a [wpilib] Add hex string constructor to Color and Color8Bit (#5063)
74b85b76a9 [wpimath] Make gcem call std functions if not constant-evaluated (#5983)
30816111db [wpimath] Fix TimeInterpolatableBuffer crash (#5972)
5cc923de33 [wpilib] DataLogManager: Use logs subdirectory on USB drives (#5975)
1144115da0 [commands] Add GetName to Subsystem, use in Scheduler tracer epochs (#5836)
ac7d726ac3 [wpimath] Add simulated annealing (#5961)
e09be72ee0 [wpimath] Remove unused SimpleMatrixUtils class (#5979)
0f9ebe92d9 [wpimath] Add generic circular buffer class to Java (#5969)
9fa28eb07a [ci] Bump actions/checkout to v4 (#5736)
ca684ac207 [hal] Add capability to read power distribution data as a stream (#4983)
51eecef2bd [wpimath] Optimize 2nd derivative of quintic splines (#3292)
4fcf0b25a1 [build] Apply a formatter for CMake files (#5973)
9b8011aa67 [build] Pin wpiformat version (#5982)
e00a0e84c1 [build] cmake: fix protobuf dependency finding for certain distributions (#5981)
23dd591394 [upstream_utils] Remove libuv patch that adjusts whitespace (#5976)
b0719942f0 [wpiutil] Timestamp: Report errors on Rio HMB init failure (#5974)
7bc89c4322 [wpilib] Update getAlliance() docs (NFC) (#5971)
841ea682d1 [upstream_utils] Upgrade to LLVM 17.0.5 (#5970)
a74db52dae [cameraserver] Add getVideo() pixelFormat overload (#5966)
a7eb422662 [build] Update native utils for new compile commands files (#5968)
544b231d4d [sysid] Add missing cassert include (#5967)
31cd015970 [wpimath] Add SysId doc links to LinearSystemId in C++ (NFC) (#5960)
9280054eab Revert "[build] Export wpimath protobuf symbols (#5952)"
2aba97c610 Export pb files from wpimath
c80b2d2017 [build] Export wpimath protobuf symbols (#5952)
3c0652c18a [cscore] Replace CS_PixelFormat with WPI_PixelFormat (#5954)
95716eb0cb [wpiunits] Documentation improvements (#5932)
423fd75fa8 [wpilib] Default LiveWindowEnabledInTest to false (#5950)
dfdea9c992 [wpimath] Make KalmanFilter variant for asymmetric updates (#5951)
ca81ced409 [wpiutil] Move RawFrame to wpiutil; add generation of RawFrame for AprilTags (#5923)
437cc91af5 [cscore] CvSink: Allow specifying output PixelFormat (#5943)
25b7dca46b [build] Remove CMake flat install option (#5944)
bb05e20247 [wpimath] Add protobuf/struct for trivial types (#5935)
35744a036e [wpimath] Move struct/proto classes to separate files (#5918)
80d7ad58ea [build] Declare platform launcher dependency explicitly (#5909)
f8d983b154 [ntcore] Protobuf/Struct: Use atomic_bool instead of atomic_flag (#5946)
4a44210ee3 [ntcore] NetworkTableInstance: Suppress unused lambda capture warning (#5947)
bdc8620d55 [upstream_utils] Fix fmt compilation errors on Windows (#5948)
0ca1e9b5f9 [wpimath] Add basic wpiunits support (#5821)
cc30824409 [ntcore] Increase client meta-topic decoding limit (#5934)
b1fad062f7 [wpilib] Use RKDP in DifferentialDrivetrainSim (#5931)
ead9ae5a69 [build] Add generateProto dependency to test and dev (#5933)
cfbff32185 [wpiutil] timestamp: Fix startup race on Rio (#5930)
7d90d0bcc3 [wpimath] Clean up StateSpaceUtil (#5891)
7755e45aac [build] Add generated protobuf headers to C++ test include path (#5926)
3985c031da [ntcore] ProtobufSubscriber: Fix typos (#5928)
7a87fe4b60 [ntcore] ProtobufSubscriber: Make mutex and msg mutable (#5927)
09f3ed6a5f [commands] Add static Trigger factories for robot mode changes (#5902)
79dd795bc0 [wpimath] Clean up VecBuilder and MatBuilder (#5906)
e117274a67 [wpilib] Change default Rio log dir from /home/lvuser to /home/lvuser/logs (#5899)
a8b80ca256 [upstream_utils] Update to libuv 1.47.0 (#5889)
b3a9c3e96b [build] Bump macOS deployment target to 12 (#5890)
0f8129677b [build] Distribute wpimath protobuf headers (#5925)
d105f9e3e9 [wpiutil] ProtobufBuffer: Fix buffer reallocation (#5924)
c5f2f6a0fb [fieldImages] Fix typo in field images artifact name (#5922)
c1a57e422a [commands] Clean up make_vector.h (#5917)
78ebc6e9ec [wpimath] change G to gearing in LinearSystemId factories (#5834)
9ada181866 [hal] DriverStation.h: Add stddef.h include (#5897)
95fa5ec72f [wpilibc,ntcoreffi] DataLogManager: join on Stop() call (#5910)
b6f2d3cc14 [build] Remove usage of Version.parse (#5911)
cc2cbeb04c [examples] Replace gyro rotation with poseEstimator rotation (#5900)
fa6b171e1c [wpiutil] Suppress protobuf warning false positives on GCC 13 (#5907)
d504639bbe [apriltag] Improve AprilTag docs (#5895)
3a1194be40 Replace static_cast<void>() with [[maybe_unused]] attribute (#5892)
70392cbbcb [build] cmake: Add protobuf dependency to wpiutil-config (#5886)
17c1bd5a83 [ntcore] Use json_fwd (#5881)
e69a9efeba [wpilibcExamples] Match array parameter bounds (#5880)
14dcd0d26f Use char instead of uint8_t for json::parse (#5877)
ec1d261984 [hal] Fix garbage data for match info before DS connection (#5879)
63dbf5c614 [wpiutil] MemoryBuffer: Fix normal read and file type check (#5875)
b2e7be9250 [ntcore] Only datalog meta-topics if specifically requested (#5873)
201a42a3cd [wpimath] Reorder TrapezoidProfile.calculate() arguments (#5874)
04a781b4d7 [apriltag] Add GetTags to C++ version of AprilTagFieldLayout (#5872)
87a8a1ced4 [docs] Exclude eigen and protobuf from doxygen (#5871)
git-subtree-dir: third_party/allwpilib
git-subtree-split: ce550705d7cdab117c0153a202973fc026a81274
Signed-off-by: Maxwell Henderson <mxwhenderson@gmail.com>
Change-Id: Ic8645d0551d62b411b0a816c493f0f33291896a1
diff --git a/wpilibj/CMakeLists.txt b/wpilibj/CMakeLists.txt
index 5924f4d..624e87a 100644
--- a/wpilibj/CMakeLists.txt
+++ b/wpilibj/CMakeLists.txt
@@ -1,15 +1,20 @@
-project (wpilibj)
+project(wpilibj)
# Java bindings
-if (WITH_JAVA)
- find_package( OpenCV REQUIRED )
+if(WITH_JAVA)
+ find_package(OpenCV REQUIRED)
find_package(Java REQUIRED)
include(UseJava)
set(CMAKE_JAVA_COMPILE_FLAGS "-encoding" "UTF8" "-Xlint:unchecked")
set(OPENCV_JAVA_INSTALL_DIR ${OpenCV_INSTALL_PATH}/share/OpenCV/java/)
- find_file(OPENCV_JAR_FILE NAMES opencv-${OpenCV_VERSION_MAJOR}${OpenCV_VERSION_MINOR}${OpenCV_VERSION_PATCH}.jar PATHS ${OPENCV_JAVA_INSTALL_DIR} ${OpenCV_INSTALL_PATH}/bin NO_DEFAULT_PATH)
+ find_file(
+ OPENCV_JAR_FILE
+ NAMES opencv-${OpenCV_VERSION_MAJOR}${OpenCV_VERSION_MINOR}${OpenCV_VERSION_PATCH}.jar
+ PATHS ${OPENCV_JAVA_INSTALL_DIR} ${OpenCV_INSTALL_PATH}/bin
+ NO_DEFAULT_PATH
+ )
configure_file(src/generate/WPILibVersion.java.in WPILibVersion.java)
@@ -17,23 +22,31 @@
file(GLOB EJML_JARS "${WPILIB_BINARY_DIR}/wpimath/thirdparty/ejml/*.jar")
file(GLOB JACKSON_JARS "${WPILIB_BINARY_DIR}/wpiutil/thirdparty/jackson/*.jar")
- add_jar(wpilibj_jar ${JAVA_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/WPILibVersion.java INCLUDE_JARS hal_jar ntcore_jar ${EJML_JARS} ${JACKSON_JARS} ${OPENCV_JAR_FILE} cscore_jar cameraserver_jar wpimath_jar wpiutil_jar OUTPUT_NAME wpilibj)
+ add_jar(
+ wpilibj_jar
+ ${JAVA_SOURCES}
+ ${CMAKE_CURRENT_BINARY_DIR}/WPILibVersion.java
+ INCLUDE_JARS
+ hal_jar
+ ntcore_jar
+ ${EJML_JARS}
+ ${JACKSON_JARS}
+ ${OPENCV_JAR_FILE}
+ cscore_jar
+ cameraserver_jar
+ wpimath_jar
+ wpiunits_jar
+ wpiutil_jar
+ OUTPUT_NAME wpilibj
+ )
- get_property(WPILIBJ_JAR_FILE TARGET wpilibj_jar PROPERTY JAR_FILE)
- install(FILES ${WPILIBJ_JAR_FILE} DESTINATION "${java_lib_dest}")
+ install_jar(wpilibj_jar DESTINATION ${java_lib_dest})
+ install_jar_exports(TARGETS wpilibj_jar FILE wpilibj.cmake DESTINATION share/wpilibj)
- set_property(TARGET wpilibj_jar PROPERTY FOLDER "java")
-
- if (WITH_FLAT_INSTALL)
- set (wpilibj_config_dir ${wpilib_dest})
- else()
- set (wpilibj_config_dir share/wpilibj)
- endif()
-
- install(FILES wpilibj-config.cmake DESTINATION ${wpilibj_config_dir})
+ install(FILES wpilibj-config.cmake DESTINATION share/wpilibj)
endif()
-if (WITH_JAVA_SOURCE)
+if(WITH_JAVA_SOURCE)
find_package(Java REQUIRED)
include(UseJava)
file(GLOB WPILIBJ_SOURCES src/main/java/edu/wpi/first/wpilibj/*.java)
@@ -45,21 +58,32 @@
file(GLOB WPILIBJ_SHUFFLEBOARD_SOURCES src/main/java/edu/wpi/first/wpilibj/shuffleboard*.java)
file(GLOB WPILIBJ_SIMULATION_SOURCES src/main/java/edu/wpi/first/wpilibj/simulation*.java)
file(GLOB WPILIBJ_SMARTDASHBOARD_SOURCES src/main/java/edu/wpi/first/wpilibj/*.java)
- file(GLOB WPILIBJ_UTIL_SOURCES src/main/java/edu/wpi/first/wpilibj/*.java ${CMAKE_CURRENT_BINARY_DIR}/WPILibVersion.java)
- add_jar(wpilibj_src_jar
- RESOURCES NAMESPACE "edu/wpi/first/wpilibj" ${WPILIBJ_SOURCES}
- NAMESPACE "edu/wpi/first/wpilibj/counter" ${WPILIBJ_COUNTER_SOURCES}
- NAMESPACE "edu/wpi/first/wpilibj/drive" ${WPILIBJ_DRIVE_SOURCES}
- NAMESPACE "edu/wpi/first/wpilibj/event" ${WPILIBJ_EVENT_SOURCES}
- NAMESPACE "edu/wpi/first/wpilibj/interfaces" ${WPILIBJ_INTERFACES_SOURCES}
- NAMESPACE "edu/wpi/first/wpilibj/internal" src/main/java/edu/wpi/first/wpilibj/internal/DriverStationModeThread.java
- NAMESPACE "edu/wpi/first/wpilibj/livewindow" src/main/java/edu/wpi/first/wpilibj/livewindow/LiveWindow.java
- NAMESPACE "edu/wpi/first/wpilibj/motorcontrol" ${WPILIBJ_MOTORCONTROL_SOURCES}
- NAMESPACE "edu/wpi/first/wpilibj/shuffleboard" ${WPILIBJ_SHUFFLEBOARD_SOURCES}
- NAMESPACE "edu/wpi/first/wpilibj/simulation" ${WPILIBJ_SIMULATION_SOURCES}
- NAMESPACE "edu/wpi/first/wpilibj/smartdashboard" ${WPILIBJ_SMARTDASHBOARD_SOURCES}
- NAMESPACE "edu/wpi/first/wpilibj/util" ${WPILIBJ_UTIL_SOURCES}
- OUTPUT_NAME wpilibj-sources)
+ file(
+ GLOB WPILIBJ_UTIL_SOURCES
+ src/main/java/edu/wpi/first/wpilibj/*.java
+ ${CMAKE_CURRENT_BINARY_DIR}/WPILibVersion.java
+ )
+ add_jar(
+ wpilibj_src_jar
+ RESOURCES
+ NAMESPACE "edu/wpi/first/wpilibj" ${WPILIBJ_SOURCES}
+ NAMESPACE "edu/wpi/first/wpilibj/counter" ${WPILIBJ_COUNTER_SOURCES}
+ NAMESPACE "edu/wpi/first/wpilibj/drive" ${WPILIBJ_DRIVE_SOURCES}
+ NAMESPACE "edu/wpi/first/wpilibj/event" ${WPILIBJ_EVENT_SOURCES}
+ NAMESPACE "edu/wpi/first/wpilibj/interfaces" ${WPILIBJ_INTERFACES_SOURCES}
+ NAMESPACE
+ "edu/wpi/first/wpilibj/internal"
+ src/main/java/edu/wpi/first/wpilibj/internal/DriverStationModeThread.java
+ NAMESPACE
+ "edu/wpi/first/wpilibj/livewindow"
+ src/main/java/edu/wpi/first/wpilibj/livewindow/LiveWindow.java
+ NAMESPACE "edu/wpi/first/wpilibj/motorcontrol" ${WPILIBJ_MOTORCONTROL_SOURCES}
+ NAMESPACE "edu/wpi/first/wpilibj/shuffleboard" ${WPILIBJ_SHUFFLEBOARD_SOURCES}
+ NAMESPACE "edu/wpi/first/wpilibj/simulation" ${WPILIBJ_SIMULATION_SOURCES}
+ NAMESPACE "edu/wpi/first/wpilibj/smartdashboard" ${WPILIBJ_SMARTDASHBOARD_SOURCES}
+ NAMESPACE "edu/wpi/first/wpilibj/util" ${WPILIBJ_UTIL_SOURCES}
+ OUTPUT_NAME wpilibj-sources
+ )
get_property(WPILIBJ_SRC_JAR_FILE TARGET wpilibj_src_jar PROPERTY JAR_FILE)
install(FILES ${WPILIBJ_SRC_JAR_FILE} DESTINATION "${java_lib_dest}")
diff --git a/wpilibj/src/generate/WPILibVersion.java.in b/wpilibj/src/generate/WPILibVersion.java.in
index cc5e6b0..f38d1b0 100644
--- a/wpilibj/src/generate/WPILibVersion.java.in
+++ b/wpilibj/src/generate/WPILibVersion.java.in
@@ -1,10 +1,13 @@
package edu.wpi.first.wpilibj.util;
-/*
+/**
* 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.
*/
-
public final class WPILibVersion {
+ /** The version number. */
public static final String Version = "${wpilib_version}";
+
+ /** Utility class. */
+ private WPILibVersion() {}
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADIS16448_IMU.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADIS16448_IMU.java
index 2eddf64..0b55105 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADIS16448_IMU.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADIS16448_IMU.java
@@ -94,30 +94,47 @@
private static final int PROD_ID = 0x56; // Product identifier
private static final int SERIAL_NUM = 0x58; // Lot-specific serial number
+ /** ADIS16448 calibration times. */
public enum CalibrationTime {
+ /** 32 ms calibration time */
_32ms(0),
+ /** 64 ms calibration time */
_64ms(1),
+ /** 128 ms calibration time */
_128ms(2),
+ /** 256 ms calibration time */
_256ms(3),
+ /** 512 ms calibration time */
_512ms(4),
+ /** 1 s calibration time */
_1s(5),
+ /** 2 s calibration time */
_2s(6),
+ /** 4 s calibration time */
_4s(7),
+ /** 8 s calibration time */
_8s(8),
+ /** 16 s calibration time */
_16s(9),
+ /** 32 s calibration time */
_32s(10),
+ /** 64 s calibration time */
_64s(11);
- private int value;
+ private final int value;
- private CalibrationTime(int value) {
+ CalibrationTime(int value) {
this.value = value;
}
}
+ /** IMU axes. */
public enum IMUAxis {
+ /** The IMU's X axis. */
kX,
+ /** The IMU's Y axis. */
kY,
+ /** The IMU's Z axis. */
kZ
}
@@ -130,9 +147,9 @@
private IMUAxis m_yaw_axis;
/* Offset data storage */
- private double m_offset_data_gyro_rate_x[];
- private double m_offset_data_gyro_rate_y[];
- private double m_offset_data_gyro_rate_z[];
+ private double[] m_offset_data_gyro_rate_x;
+ private double[] m_offset_data_gyro_rate_y;
+ private double[] m_offset_data_gyro_rate_z;
/* Instant raw output variables */
private double m_gyro_rate_x = 0.0;
@@ -199,7 +216,7 @@
private SimDouble m_simAccelZ;
/* CRC-16 Look-Up Table */
- int adiscrc[] =
+ int[] adiscrc =
new int[] {
0x0000, 0x17CE, 0x0FDF, 0x1811, 0x1FBE, 0x0870, 0x1061, 0x07AF,
0x1F3F, 0x08F1, 0x10E0, 0x072E, 0x0081, 0x174F, 0x0F5E, 0x1890,
@@ -248,15 +265,19 @@
}
}
+ /** Creates a new ADIS16448_IMU object. */
public ADIS16448_IMU() {
this(IMUAxis.kZ, SPI.Port.kMXP, CalibrationTime._512ms);
}
/**
+ * Creates a new ADIS16448_IMU object.
+ *
* @param yaw_axis The axis that measures the yaw
* @param port The SPI Port the gyro is plugged into
* @param cal_time Calibration time
*/
+ @SuppressWarnings("this-escape")
public ADIS16448_IMU(final IMUAxis yaw_axis, SPI.Port port, CalibrationTime cal_time) {
m_yaw_axis = yaw_axis;
m_spi_port = port;
@@ -331,6 +352,11 @@
m_connected = true;
}
+ /**
+ * Checks the connection status of the IMU.
+ *
+ * @return True if the IMU is connected, false otherwise.
+ */
public boolean isConnected() {
if (m_simConnected != null) {
return m_simConnected.get();
@@ -338,7 +364,6 @@
return m_connected;
}
- /** */
private static int toUShort(byte[] buf) {
return (((buf[0] & 0xFF) << 8) + ((buf[1] & 0xFF) << 0));
}
@@ -347,7 +372,7 @@
return (buf[0] & 0xFF);
}
- public static int toUShort(int... buf) {
+ private static int toUShort(int... buf) {
return (((buf[0] & 0xFF) << 8) + (buf[1] & 0xFF));
}
@@ -358,7 +383,7 @@
/** */
private static int toShort(int... buf) {
- return (short) (((buf[0] & 0xFF) << 8) + ((buf[1] & 0xFF) << 0));
+ return (short) (((buf[0] & 0xFF) << 8) + ((buf[1] & 0xFF)));
}
/** */
@@ -480,8 +505,19 @@
return true;
}
- public int configDecRate(int m_decRate) {
- int writeValue = m_decRate;
+ /**
+ * Configures the decimation rate of the IMU.
+ *
+ * @param decimationRate The new decimation value.
+ * @return 0 if success, 1 if no change, 2 if error.
+ */
+ public int configDecRate(int decimationRate) {
+ // Switches the active SPI port to standard SPI mode, writes a new value to
+ // the DECIMATE register in the IMU, and re-enables auto SPI.
+ //
+ // This function enters standard SPI mode, writes a new DECIMATE setting to
+ // the IMU, adjusts the sample scale factor, and re-enters auto SPI mode.
+ int writeValue;
int readbackValue;
if (!switchToStandardSPI()) {
DriverStation.reportError("Failed to configure/reconfigure standard SPI.", false);
@@ -489,19 +525,19 @@
}
/* Check max */
- if (m_decRate > 9) {
+ if (decimationRate > 9) {
DriverStation.reportError(
"Attempted to write an invalid decimation value. Capping at 9", false);
- m_decRate = 9;
+ decimationRate = 9;
}
- if (m_decRate < 0) {
+ if (decimationRate < 0) {
DriverStation.reportError(
"Attempted to write an invalid decimation value. Capping at 0", false);
- m_decRate = 0;
+ decimationRate = 0;
}
/* Shift decimation setting to correct position and select internal sync */
- writeValue = (m_decRate << 8) | 0x1;
+ writeValue = (decimationRate << 8) | 0x1;
/* Apply to IMU */
writeRegister(SMPL_PRD, writeValue);
@@ -527,7 +563,7 @@
* @param new_cal_time New calibration time
* @return 1 if the new calibration time is the same as the current one else 0
*/
- public int configCalTime(CalibrationTime new_cal_time) {
+ public final int configCalTime(CalibrationTime new_cal_time) {
if (m_calibration_time == new_cal_time) {
return 1;
} else {
@@ -623,6 +659,12 @@
m_spi.write(buf, 2);
}
+ /**
+ * Reset the gyro.
+ *
+ * <p>Resets the gyro accumulations to a heading of zero. This can be used if there is significant
+ * drift in the gyro and it needs to be recalibrated after running.
+ */
public void reset() {
synchronized (this) {
m_integ_gyro_angle_x = 0.0;
@@ -956,7 +998,9 @@
}
/**
- * @return Yaw axis angle in degrees (CCW positive)
+ * Returns the yaw axis angle in degrees (CCW positive).
+ *
+ * @return Yaw axis angle in degrees (CCW positive).
*/
public synchronized double getAngle() {
switch (m_yaw_axis) {
@@ -972,7 +1016,9 @@
}
/**
- * @return Yaw axis angular rate in degrees per second (CCW positive)
+ * Returns the yaw axis angular rate in degrees per second (CCW positive).
+ *
+ * @return Yaw axis angular rate in degrees per second (CCW positive).
*/
public synchronized double getRate() {
switch (m_yaw_axis) {
@@ -988,14 +1034,18 @@
}
/**
- * @return Yaw Axis
+ * Returns which axis, kX, kY, or kZ, is set to the yaw axis.
+ *
+ * @return IMUAxis Yaw Axis
*/
public IMUAxis getYawAxis() {
return m_yaw_axis;
}
/**
- * @return accumulated gyro angle in the X axis in degrees
+ * Returns the accumulated gyro angle in the X axis in degrees.
+ *
+ * @return The accumulated gyro angle in the X axis in degrees.
*/
public synchronized double getGyroAngleX() {
if (m_simGyroAngleX != null) {
@@ -1005,7 +1055,9 @@
}
/**
- * @return accumulated gyro angle in the Y axis in degrees
+ * Returns the accumulated gyro angle in the Y axis in degrees.
+ *
+ * @return The accumulated gyro angle in the Y axis in degrees.
*/
public synchronized double getGyroAngleY() {
if (m_simGyroAngleY != null) {
@@ -1015,7 +1067,9 @@
}
/**
- * @return accumulated gyro angle in the Z axis in degrees
+ * Returns the accumulated gyro angle in the Z axis in degrees.
+ *
+ * @return The accumulated gyro angle in the Z axis in degrees.
*/
public synchronized double getGyroAngleZ() {
if (m_simGyroAngleZ != null) {
@@ -1025,7 +1079,9 @@
}
/**
- * @return gyro angular rate in the X axis in degrees per second
+ * Returns the gyro angular rate in the X axis in degrees per second.
+ *
+ * @return The gyro angular rate in the X axis in degrees per second.
*/
public synchronized double getGyroRateX() {
if (m_simGyroRateX != null) {
@@ -1035,7 +1091,9 @@
}
/**
- * @return gyro angular rate in the Y axis in degrees per second
+ * Returns the gyro angular rate in the Y axis in degrees per second.
+ *
+ * @return The gyro angular rate in the Y axis in degrees per second.
*/
public synchronized double getGyroRateY() {
if (m_simGyroRateY != null) {
@@ -1045,7 +1103,9 @@
}
/**
- * @return gyro angular rate in the Z axis in degrees per second
+ * Returns the gyro angular rate in the Z axis in degrees per second.
+ *
+ * @return The gyro angular rate in the Z axis in degrees per second.
*/
public synchronized double getGyroRateZ() {
if (m_simGyroRateZ != null) {
@@ -1055,7 +1115,9 @@
}
/**
- * @return urrent acceleration in the X axis in meters per second squared
+ * Returns the acceleration in the X axis in meters per second squared.
+ *
+ * @return The acceleration in the X axis in meters per second squared.
*/
public synchronized double getAccelX() {
if (m_simAccelX != null) {
@@ -1065,7 +1127,9 @@
}
/**
- * @return current acceleration in the Y axis in meters per second squared
+ * Returns the acceleration in the Y axis in meters per second squared.
+ *
+ * @return The acceleration in the Y axis in meters per second squared.
*/
public synchronized double getAccelY() {
if (m_simAccelY != null) {
@@ -1075,7 +1139,9 @@
}
/**
- * @return current acceleration in the Z axis in meters per second squared
+ * Returns the acceleration in the Z axis in meters per second squared.
+ *
+ * @return The acceleration in the Z axis in meters per second squared.
*/
public synchronized double getAccelZ() {
if (m_simAccelZ != null) {
@@ -1085,7 +1151,9 @@
}
/**
- * @return Magnetic field strength in the X axis in Tesla
+ * Returns the magnetic field strength in the X axis in Tesla.
+ *
+ * @return The magnetic field strength in the X axis in Tesla.
*/
public synchronized double getMagneticFieldX() {
// mG to T
@@ -1093,7 +1161,9 @@
}
/**
- * @return Magnetic field strength in the Y axis in Tesla
+ * Returns the magnetic field strength in the Y axis in Tesla.
+ *
+ * @return The magnetic field strength in the Y axis in Tesla.
*/
public synchronized double getMagneticFieldY() {
// mG to T
@@ -1101,7 +1171,9 @@
}
/**
- * @return Magnetic field strength in the Z axis in Tesla
+ * Returns the magnetic field strength in the Z axis in Tesla.
+ *
+ * @return The magnetic field strength in the Z axis in Tesla.
*/
public synchronized double getMagneticFieldZ() {
// mG to T
@@ -1109,35 +1181,47 @@
}
/**
- * @return X-axis complementary angle in degrees
+ * Returns the complementary angle around the X axis computed from accelerometer and gyro rate
+ * measurements.
+ *
+ * @return The X-axis complementary angle in degrees.
*/
public synchronized double getXComplementaryAngle() {
return m_compAngleX;
}
/**
- * @return Y-axis complementary angle in degrees
+ * Returns the complementary angle around the Y axis computed from accelerometer and gyro rate
+ * measurements.
+ *
+ * @return The Y-axis complementary angle in degrees.
*/
public synchronized double getYComplementaryAngle() {
return m_compAngleY;
}
/**
- * @return X-axis filtered acceleration angle in degrees
+ * Returns the X-axis filtered acceleration angle in degrees.
+ *
+ * @return The X-axis filtered acceleration angle in degrees.
*/
public synchronized double getXFilteredAccelAngle() {
return m_accelAngleX;
}
/**
- * @return Y-axis filtered acceleration angle in degrees
+ * Returns the Y-axis filtered acceleration angle in degrees.
+ *
+ * @return The Y-axis filtered acceleration angle in degrees.
*/
public synchronized double getYFilteredAccelAngle() {
return m_accelAngleY;
}
/**
- * @return Barometric Pressure in PSI
+ * Returns the barometric pressure in PSI.
+ *
+ * @return The barometric pressure in PSI.
*/
public synchronized double getBarometricPressure() {
// mbar to PSI conversion
@@ -1145,7 +1229,9 @@
}
/**
- * @return Temperature in degrees Celsius
+ * Returns the temperature in degrees Celsius.
+ *
+ * @return The temperature in degrees Celsius.
*/
public synchronized double getTemperature() {
return m_temp;
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADIS16470_IMU.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADIS16470_IMU.java
index 2fad3f3..b7236a5 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADIS16470_IMU.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADIS16470_IMU.java
@@ -122,45 +122,21 @@
private static final int FLSHCNT_LOW = 0x7C; // Flash update count, lower word
private static final int FLSHCNT_HIGH = 0x7E; // Flash update count, upper word
- private static final byte[] m_autospi_x_packet = {
+ // Weight between the previous and current gyro angles represents 1 second for the timestamp,
+ // this is the point at which we ignore the previous angle because it is too old to be of use.
+ // The IMU timestamp conversion is 1 = 49.02us, the value 1_000_000 is the number of microseconds
+ // we average over.
+ private static final double AVERAGE_RATE_SCALING_FACTOR = 49.02 / 1_000_000;
+
+ private static final byte[] m_autospi_allAngle_packet = {
X_DELTANG_OUT,
FLASH_CNT,
X_DELTANG_LOW,
FLASH_CNT,
- X_GYRO_OUT,
- FLASH_CNT,
- Y_GYRO_OUT,
- FLASH_CNT,
- Z_GYRO_OUT,
- FLASH_CNT,
- X_ACCL_OUT,
- FLASH_CNT,
- Y_ACCL_OUT,
- FLASH_CNT,
- Z_ACCL_OUT,
- FLASH_CNT
- };
-
- private static final byte[] m_autospi_y_packet = {
Y_DELTANG_OUT,
FLASH_CNT,
Y_DELTANG_LOW,
FLASH_CNT,
- X_GYRO_OUT,
- FLASH_CNT,
- Y_GYRO_OUT,
- FLASH_CNT,
- Z_GYRO_OUT,
- FLASH_CNT,
- X_ACCL_OUT,
- FLASH_CNT,
- Y_ACCL_OUT,
- FLASH_CNT,
- Z_ACCL_OUT,
- FLASH_CNT
- };
-
- private static final byte[] m_autospi_z_packet = {
Z_DELTANG_OUT,
FLASH_CNT,
Z_DELTANG_LOW,
@@ -179,31 +155,59 @@
FLASH_CNT
};
+ /** ADIS16470 calibration times. */
public enum CalibrationTime {
+ /** 32 ms calibration time */
_32ms(0),
+ /** 64 ms calibration time */
_64ms(1),
+ /** 128 ms calibration time */
_128ms(2),
+ /** 256 ms calibration time */
_256ms(3),
+ /** 512 ms calibration time */
_512ms(4),
+ /** 1 s calibration time */
_1s(5),
+ /** 2 s calibration time */
_2s(6),
+ /** 4 s calibration time */
_4s(7),
+ /** 8 s calibration time */
_8s(8),
+ /** 16 s calibration time */
_16s(9),
+ /** 32 s calibration time */
_32s(10),
+ /** 64 s calibration time */
_64s(11);
- private int value;
+ private final int value;
- private CalibrationTime(int value) {
+ CalibrationTime(int value) {
this.value = value;
}
}
+ /**
+ * IMU axes.
+ *
+ * <p>kX, kY, and kZ refer to the IMU's X, Y, and Z axes respectively. kYaw, kPitch, and kRoll are
+ * configured by the user to refer to an X, Y, or Z axis.
+ */
public enum IMUAxis {
+ /** The IMU's X axis */
kX,
+ /** The IMU's Y axis */
kY,
- kZ
+ /** The IMU's Z axis */
+ kZ,
+ /** The user-configured yaw axis */
+ kYaw,
+ /** The user-configured pitch axis */
+ kPitch,
+ /** The user-configured roll axis */
+ kRoll,
}
// Static Constants
@@ -212,19 +216,26 @@
private static final double deg_to_rad = 0.0174532;
private static final double grav = 9.81;
- // User-specified yaw axis
+ // User-specified axes
private IMUAxis m_yaw_axis;
+ private IMUAxis m_pitch_axis;
+ private IMUAxis m_roll_axis;
// Instant raw outputs
private double m_gyro_rate_x = 0.0;
private double m_gyro_rate_y = 0.0;
private double m_gyro_rate_z = 0.0;
+ private double m_average_gyro_rate_x = 0.0;
+ private double m_average_gyro_rate_y = 0.0;
+ private double m_average_gyro_rate_z = 0.0;
private double m_accel_x = 0.0;
private double m_accel_y = 0.0;
private double m_accel_z = 0.0;
// Integrated gyro angle
- private double m_integ_angle = 0.0;
+ private double m_integ_angle_x = 0.0;
+ private double m_integ_angle_y = 0.0;
+ private double m_integ_angle_z = 0.0;
// Complementary filter variables
private double m_dt = 0.0;
@@ -278,17 +289,74 @@
}
}
+ /**
+ * Creates a new ADIS16740 IMU object.
+ *
+ * <p>The default setup is the onboard SPI port with a calibration time of 4 seconds. Yaw, pitch,
+ * and roll are kZ, kX, and kY respectively.
+ */
public ADIS16470_IMU() {
- this(IMUAxis.kZ, SPI.Port.kOnboardCS0, CalibrationTime._4s);
+ this(IMUAxis.kZ, IMUAxis.kX, IMUAxis.kY, SPI.Port.kOnboardCS0, CalibrationTime._4s);
}
/**
+ * Creates a new ADIS16740 IMU object.
+ *
+ * <p>The default setup is the onboard SPI port with a calibration time of 4 seconds.
+ *
+ * <p><b><i>Input axes limited to kX, kY and kZ. Specifying kYaw, kPitch,or kRoll will result in
+ * an error.</i></b>
+ *
* @param yaw_axis The axis that measures the yaw
+ * @param pitch_axis The axis that measures the pitch
+ * @param roll_axis The axis that measures the roll
+ */
+ public ADIS16470_IMU(IMUAxis yaw_axis, IMUAxis pitch_axis, IMUAxis roll_axis) {
+ this(yaw_axis, pitch_axis, roll_axis, SPI.Port.kOnboardCS0, CalibrationTime._4s);
+ }
+
+ /**
+ * Creates a new ADIS16740 IMU object.
+ *
+ * <p><b><i>Input axes limited to kX, kY and kZ. Specifying kYaw, kPitch,or kRoll will result in
+ * an error.</i></b>
+ *
+ * @param yaw_axis The axis that measures the yaw
+ * @param pitch_axis The axis that measures the pitch
+ * @param roll_axis The axis that measures the roll
* @param port The SPI Port the gyro is plugged into
* @param cal_time Calibration time
*/
- public ADIS16470_IMU(IMUAxis yaw_axis, SPI.Port port, CalibrationTime cal_time) {
+ @SuppressWarnings("this-escape")
+ public ADIS16470_IMU(
+ IMUAxis yaw_axis,
+ IMUAxis pitch_axis,
+ IMUAxis roll_axis,
+ SPI.Port port,
+ CalibrationTime cal_time) {
+ if (yaw_axis == IMUAxis.kYaw
+ || yaw_axis == IMUAxis.kPitch
+ || yaw_axis == IMUAxis.kRoll
+ || pitch_axis == IMUAxis.kYaw
+ || pitch_axis == IMUAxis.kPitch
+ || pitch_axis == IMUAxis.kRoll
+ || roll_axis == IMUAxis.kYaw
+ || roll_axis == IMUAxis.kPitch
+ || roll_axis == IMUAxis.kRoll) {
+ DriverStation.reportError(
+ "ADIS16470 constructor only allows IMUAxis.kX, IMUAxis.kY or IMUAxis.kZ as arguments.",
+ false);
+ DriverStation.reportError(
+ "Constructing ADIS with default axes. (IMUAxis.kZ is defined as Yaw)", false);
+ yaw_axis = IMUAxis.kZ;
+ pitch_axis = IMUAxis.kY;
+ roll_axis = IMUAxis.kX;
+ }
+
m_yaw_axis = yaw_axis;
+ m_pitch_axis = pitch_axis;
+ m_roll_axis = roll_axis;
+
m_calibration_time = cal_time.value;
m_spi_port = port;
@@ -368,6 +436,11 @@
m_connected = true;
}
+ /**
+ * Checks the connection status of the IMU.
+ *
+ * @return True if the IMU is connected, false otherwise.
+ */
public boolean isConnected() {
if (m_simConnected != null) {
return m_simConnected.get();
@@ -396,7 +469,7 @@
* @return
*/
private static int toShort(int... buf) {
- return (short) (((buf[0] & 0xFF) << 8) + ((buf[1] & 0xFF) << 0));
+ return (short) (((buf[0] & 0xFF) << 8) + ((buf[1] & 0xFF)));
}
/**
@@ -410,7 +483,7 @@
/**
* Switch to standard SPI mode.
*
- * @return
+ * @return True if successful, false otherwise.
*/
private boolean switchToStandardSPI() {
// Check to see whether the acquire thread is active. If so, wait for it to stop
@@ -476,7 +549,9 @@
}
/**
- * @return
+ * Switch to auto SPI mode.
+ *
+ * @return True if successful, false otherwise.
*/
boolean switchToAutoSPI() {
// No SPI port has been set up. Go set one up first.
@@ -498,17 +573,7 @@
m_auto_configured = true;
}
// Do we need to change auto SPI settings?
- switch (m_yaw_axis) {
- case kX:
- m_spi.setAutoTransmitData(m_autospi_x_packet, 2);
- break;
- case kY:
- m_spi.setAutoTransmitData(m_autospi_y_packet, 2);
- break;
- default:
- m_spi.setAutoTransmitData(m_autospi_z_packet, 2);
- break;
- }
+ m_spi.setAutoTransmitData(m_autospi_allAngle_packet, 2);
// Configure auto stall time
m_spi.configureAutoStall(5, 1000, 1);
// Kick off auto SPI (Note: Device configuration impossible after auto SPI is
@@ -560,18 +625,28 @@
return 0;
}
- public int configDecRate(int reg) {
- int m_reg = reg;
+ /**
+ * Configures the decimation rate of the IMU.
+ *
+ * @param decimationRate The new decimation value.
+ * @return 0 if success, 1 if no change, 2 if error.
+ */
+ public int configDecRate(int decimationRate) {
+ // Switches the active SPI port to standard SPI mode, writes a new value to
+ // the DECIMATE register in the IMU, and re-enables auto SPI.
+ //
+ // This function enters standard SPI mode, writes a new DECIMATE setting to
+ // the IMU, adjusts the sample scale factor, and re-enters auto SPI mode.
if (!switchToStandardSPI()) {
DriverStation.reportError("Failed to configure/reconfigure standard SPI.", false);
return 2;
}
- if (m_reg > 1999) {
- DriverStation.reportError("Attempted to write an invalid deimation value.", false);
- m_reg = 1999;
+ if (decimationRate > 1999) {
+ DriverStation.reportError("Attempted to write an invalid decimation value.", false);
+ decimationRate = 1999;
}
- m_scaled_sample_rate = (((m_reg + 1.0) / 2000.0) * 1000000.0);
- writeRegister(DEC_RATE, m_reg);
+ m_scaled_sample_rate = (((decimationRate + 1.0) / 2000.0) * 1000000.0);
+ writeRegister(DEC_RATE, decimationRate);
System.out.println("Decimation register: " + readRegister(DEC_RATE));
if (!switchToAutoSPI()) {
DriverStation.reportError("Failed to configure/reconfigure auto SPI.", false);
@@ -593,29 +668,6 @@
if (!switchToAutoSPI()) {
DriverStation.reportError("Failed to configure/reconfigure auto SPI.", false);
}
- ;
- }
-
- /**
- * Sets the yaw axis
- *
- * @param yaw_axis The new yaw axis to use
- * @return 1 if the new yaw axis is the same as the current one, 2 if the switch to Standard SPI
- * failed, else 0.
- */
- public int setYawAxis(IMUAxis yaw_axis) {
- if (m_yaw_axis == yaw_axis) {
- return 1;
- }
- if (!switchToStandardSPI()) {
- DriverStation.reportError("Failed to configure/reconfigure standard SPI.", false);
- return 2;
- }
- m_yaw_axis = yaw_axis;
- if (!switchToAutoSPI()) {
- DriverStation.reportError("Failed to configure/reconfigure auto SPI.", false);
- }
- return 0;
}
/**
@@ -650,12 +702,6 @@
m_spi.write(buf, 2);
}
- public void reset() {
- synchronized (this) {
- m_integ_angle = 0.0;
- }
- }
-
/** Delete (free) the spi port used for the IMU. */
@Override
public void close() {
@@ -691,7 +737,7 @@
/** */
private void acquire() {
// Set data packet length
- final int dataset_len = 19; // 18 data points + timestamp
+ final int dataset_len = 27; // 26 data points + timestamp
final int BUFFER_SIZE = 4000;
// Set up buffers and variables
@@ -700,7 +746,9 @@
int data_remainder = 0;
int data_to_read = 0;
double previous_timestamp = 0.0;
- double delta_angle = 0.0;
+ double delta_angle_x = 0.0;
+ double delta_angle_y = 0.0;
+ double delta_angle_z = 0.0;
double gyro_rate_x = 0.0;
double gyro_rate_y = 0.0;
double gyro_rate_z = 0.0;
@@ -730,8 +778,8 @@
data_count =
m_spi.readAutoReceivedData(
- buffer, 0, 0); // Read number of bytes currently stored in the
- // buffer
+ buffer, 0, 0); // Read number of bytes currently stored in the buffer
+
data_remainder =
data_count % dataset_len; // Check if frame is incomplete. Add 1 because of timestamp
data_to_read = data_count - data_remainder; // Remove incomplete data from read count
@@ -772,18 +820,27 @@
*/
/*
- * Get delta angle value for selected yaw axis and scale by the elapsed time
+ * Get delta angle value for all 3 axes and scale by the elapsed time
* (based on timestamp)
*/
- delta_angle =
+ delta_angle_x =
(toInt(buffer[i + 3], buffer[i + 4], buffer[i + 5], buffer[i + 6]) * delta_angle_sf)
/ (m_scaled_sample_rate / (buffer[i] - previous_timestamp));
- gyro_rate_x = (toShort(buffer[i + 7], buffer[i + 8]) / 10.0);
- gyro_rate_y = (toShort(buffer[i + 9], buffer[i + 10]) / 10.0);
- gyro_rate_z = (toShort(buffer[i + 11], buffer[i + 12]) / 10.0);
- accel_x = (toShort(buffer[i + 13], buffer[i + 14]) / 800.0);
- accel_y = (toShort(buffer[i + 15], buffer[i + 16]) / 800.0);
- accel_z = (toShort(buffer[i + 17], buffer[i + 18]) / 800.0);
+ delta_angle_y =
+ (toInt(buffer[i + 7], buffer[i + 8], buffer[i + 9], buffer[i + 10]) * delta_angle_sf)
+ / (m_scaled_sample_rate / (buffer[i] - previous_timestamp));
+ delta_angle_z =
+ (toInt(buffer[i + 11], buffer[i + 12], buffer[i + 13], buffer[i + 14])
+ * delta_angle_sf)
+ / (m_scaled_sample_rate / (buffer[i] - previous_timestamp));
+
+ gyro_rate_x = (toShort(buffer[i + 15], buffer[i + 16]) / 10.0);
+ gyro_rate_y = (toShort(buffer[i + 17], buffer[i + 18]) / 10.0);
+ gyro_rate_z = (toShort(buffer[i + 19], buffer[i + 20]) / 10.0);
+
+ accel_x = (toShort(buffer[i + 21], buffer[i + 22]) / 800.0);
+ accel_y = (toShort(buffer[i + 23], buffer[i + 24]) / 800.0);
+ accel_z = (toShort(buffer[i + 25], buffer[i + 26]) / 800.0);
// Convert scaled sensor data to SI units (for tilt calculations)
// TODO: Should the unit outputs be selectable?
@@ -809,6 +866,10 @@
accel_y_si, Math.sqrt((accel_x_si * accel_x_si) + (accel_z_si * accel_z_si)));
compAngleX = accelAngleX;
compAngleY = accelAngleY;
+
+ m_average_gyro_rate_x = 0.0;
+ m_average_gyro_rate_y = 0.0;
+ m_average_gyro_rate_z = 0.0;
} else {
// Run inclinometer calculations
accelAngleX =
@@ -830,9 +891,13 @@
* Don't accumulate first run. previous_timestamp will be "very" old and the
* integration will end up way off
*/
- m_integ_angle = 0.0;
+ m_integ_angle_x = 0.0;
+ m_integ_angle_y = 0.0;
+ m_integ_angle_z = 0.0;
} else {
- m_integ_angle += delta_angle;
+ m_integ_angle_x += delta_angle_x;
+ m_integ_angle_y += delta_angle_y;
+ m_integ_angle_z += delta_angle_z;
}
m_gyro_rate_x = gyro_rate_x;
m_gyro_rate_y = gyro_rate_y;
@@ -844,16 +909,28 @@
m_compAngleY = compAngleY * rad_to_deg;
m_accelAngleX = accelAngleX * rad_to_deg;
m_accelAngleY = accelAngleY * rad_to_deg;
+ m_average_gyro_rate_x += gyro_rate_x;
+ m_average_gyro_rate_y += gyro_rate_y;
+ m_average_gyro_rate_z += gyro_rate_z;
}
m_first_run = false;
}
+
+ // The inverse of data to read divided by dataset length, his is the number of iterations
+ // of the for loop inverted (so multiplication can be used instead of division)
+ double invTotalIterations = (double) dataset_len / data_to_read;
+ m_average_gyro_rate_x *= invTotalIterations;
+ m_average_gyro_rate_y *= invTotalIterations;
+ m_average_gyro_rate_z *= invTotalIterations;
} else {
m_thread_idle = true;
data_count = 0;
data_remainder = 0;
data_to_read = 0;
previous_timestamp = 0.0;
- delta_angle = 0.0;
+ delta_angle_x = 0.0;
+ delta_angle_y = 0.0;
+ delta_angle_z = 0.0;
gyro_rate_x = 0.0;
gyro_rate_y = 0.0;
gyro_rate_z = 0.0;
@@ -933,111 +1010,267 @@
}
/**
- * @return Yaw axis angle in degrees (CCW positive)
+ * Reset the gyro.
+ *
+ * <p>Resets the gyro accumulations to a heading of zero. This can be used if there is significant
+ * drift in the gyro and it needs to be recalibrated after running.
*/
- public synchronized double getAngle() {
- switch (m_yaw_axis) {
+ public void reset() {
+ synchronized (this) {
+ m_integ_angle_x = 0.0;
+ m_integ_angle_y = 0.0;
+ m_integ_angle_z = 0.0;
+ }
+ }
+
+ /**
+ * Allow the designated gyro angle to be set to a given value. This may happen with unread values
+ * in the buffer, it is suggested that the IMU is not moving when this method is run.
+ *
+ * @param axis IMUAxis that will be changed
+ * @param angle A double in degrees (CCW positive)
+ */
+ public void setGyroAngle(IMUAxis axis, double angle) {
+ switch (axis) {
+ case kYaw:
+ axis = m_yaw_axis;
+ break;
+ case kPitch:
+ axis = m_pitch_axis;
+ break;
+ case kRoll:
+ axis = m_roll_axis;
+ break;
+ default:
+ }
+
+ switch (axis) {
+ case kX:
+ this.setGyroAngleX(angle);
+ break;
+ case kY:
+ this.setGyroAngleY(angle);
+ break;
+ case kZ:
+ this.setGyroAngleZ(angle);
+ break;
+ default:
+ }
+ }
+
+ /**
+ * Allow the gyro angle X to be set to a given value. This may happen with unread values in the
+ * buffer, it is suggested that the IMU is not moving when this method is run.
+ *
+ * @param angle A double in degrees (CCW positive)
+ */
+ public void setGyroAngleX(double angle) {
+ synchronized (this) {
+ m_integ_angle_x = angle;
+ }
+ }
+
+ /**
+ * Allow the gyro angle Y to be set to a given value. This may happen with unread values in the
+ * buffer, it is suggested that the IMU is not moving when this method is run.
+ *
+ * @param angle A double in degrees (CCW positive)
+ */
+ public void setGyroAngleY(double angle) {
+ synchronized (this) {
+ m_integ_angle_y = angle;
+ }
+ }
+
+ /**
+ * Allow the gyro angle Z to be set to a given value. This may happen with unread values in the
+ * buffer, it is suggested that the IMU is not moving when this method is run.
+ *
+ * @param angle A double in degrees (CCW positive)
+ */
+ public void setGyroAngleZ(double angle) {
+ synchronized (this) {
+ m_integ_angle_z = angle;
+ }
+ }
+
+ /**
+ * Returns the axis angle in degrees (CCW positive).
+ *
+ * @param axis The IMUAxis whose angle to return.
+ * @return The axis angle in degrees (CCW positive).
+ */
+ public synchronized double getAngle(IMUAxis axis) {
+ switch (axis) {
+ case kYaw:
+ axis = m_yaw_axis;
+ break;
+ case kPitch:
+ axis = m_pitch_axis;
+ break;
+ case kRoll:
+ axis = m_roll_axis;
+ break;
+ default:
+ }
+
+ switch (axis) {
case kX:
if (m_simGyroAngleX != null) {
return m_simGyroAngleX.get();
}
- break;
+ return m_integ_angle_x;
case kY:
if (m_simGyroAngleY != null) {
return m_simGyroAngleY.get();
}
- break;
+ return m_integ_angle_y;
case kZ:
if (m_simGyroAngleZ != null) {
return m_simGyroAngleZ.get();
}
- break;
+ return m_integ_angle_z;
+ default:
}
- return m_integ_angle;
+
+ return 0.0;
}
/**
- * @return Yaw axis angular rate in degrees per second (CCW positive)
+ * Returns the axis angular rate in degrees per second (CCW positive).
+ *
+ * @param axis The IMUAxis whose rate to return.
+ * @return Axis angular rate in degrees per second (CCW positive).
*/
- public synchronized double getRate() {
- if (m_yaw_axis == IMUAxis.kX) {
- if (m_simGyroRateX != null) {
- return m_simGyroRateX.get();
- }
- return m_gyro_rate_x;
- } else if (m_yaw_axis == IMUAxis.kY) {
- if (m_simGyroRateY != null) {
- return m_simGyroRateY.get();
- }
- return m_gyro_rate_y;
- } else if (m_yaw_axis == IMUAxis.kZ) {
- if (m_simGyroRateZ != null) {
- return m_simGyroRateZ.get();
- }
- return m_gyro_rate_z;
- } else {
- return 0.0;
+ public synchronized double getRate(IMUAxis axis) {
+ switch (axis) {
+ case kYaw:
+ axis = m_yaw_axis;
+ break;
+ case kPitch:
+ axis = m_pitch_axis;
+ break;
+ case kRoll:
+ axis = m_roll_axis;
+ break;
+ default:
}
+
+ switch (axis) {
+ case kX:
+ if (m_simGyroRateX != null) {
+ return m_simGyroRateX.get();
+ }
+ return m_gyro_rate_x;
+ case kY:
+ if (m_simGyroRateY != null) {
+ return m_simGyroRateY.get();
+ }
+ return m_gyro_rate_y;
+ case kZ:
+ if (m_simGyroRateZ != null) {
+ return m_simGyroRateZ.get();
+ }
+ return m_gyro_rate_z;
+ default:
+ }
+ return 0.0;
}
/**
- * @return Yaw Axis
+ * Returns which axis, kX, kY, or kZ, is set to the yaw axis.
+ *
+ * @return IMUAxis Yaw Axis
*/
public IMUAxis getYawAxis() {
return m_yaw_axis;
}
/**
- * @return current acceleration in the X axis
+ * Returns which axis, kX, kY, or kZ, is set to the pitch axis.
+ *
+ * @return IMUAxis Pitch Axis
+ */
+ public IMUAxis getPitchAxis() {
+ return m_pitch_axis;
+ }
+
+ /**
+ * Returns which axis, kX, kY, or kZ, is set to the roll axis.
+ *
+ * @return IMUAxis Roll Axis
+ */
+ public IMUAxis getRollAxis() {
+ return m_roll_axis;
+ }
+
+ /**
+ * Returns the acceleration in the X axis in meters per second squared.
+ *
+ * @return The acceleration in the X axis in meters per second squared.
*/
public synchronized double getAccelX() {
return m_accel_x * 9.81;
}
/**
- * @return current acceleration in the Y axis
+ * Returns the acceleration in the Y axis in meters per second squared.
+ *
+ * @return The acceleration in the Y axis in meters per second squared.
*/
public synchronized double getAccelY() {
return m_accel_y * 9.81;
}
/**
- * @return current acceleration in the Z axis
+ * Returns the acceleration in the Z axis in meters per second squared.
+ *
+ * @return The acceleration in the Z axis in meters per second squared.
*/
public synchronized double getAccelZ() {
return m_accel_z * 9.81;
}
/**
- * @return X-axis complementary angle
+ * Returns the complementary angle around the X axis computed from accelerometer and gyro rate
+ * measurements.
+ *
+ * @return The X-axis complementary angle in degrees.
*/
public synchronized double getXComplementaryAngle() {
return m_compAngleX;
}
/**
- * @return Y-axis complementary angle
+ * Returns the complementary angle around the Y axis computed from accelerometer and gyro rate
+ * measurements.
+ *
+ * @return The Y-axis complementary angle in degrees.
*/
public synchronized double getYComplementaryAngle() {
return m_compAngleY;
}
/**
- * @return X-axis filtered acceleration angle
+ * Returns the X-axis filtered acceleration angle in degrees.
+ *
+ * @return The X-axis filtered acceleration angle in degrees.
*/
public synchronized double getXFilteredAccelAngle() {
return m_accelAngleX;
}
/**
- * @return Y-axis filtered acceleration angle
+ * Returns the Y-axis filtered acceleration angle in degrees.
+ *
+ * @return The Y-axis filtered acceleration angle in degrees.
*/
public synchronized double getYFilteredAccelAngle() {
return m_accelAngleY;
}
/**
- * Get the SPI port number.
+ * Gets the SPI port number.
*
* @return The SPI port number.
*/
@@ -1048,6 +1281,6 @@
@Override
public void initSendable(SendableBuilder builder) {
builder.setSmartDashboardType("Gyro");
- builder.addDoubleProperty("Value", this::getAngle, null);
+ builder.addDoubleProperty("Value", () -> getAngle(m_yaw_axis), null);
}
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADXL345_I2C.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADXL345_I2C.java
index 7ceff95..4f6803d 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADXL345_I2C.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADXL345_I2C.java
@@ -27,7 +27,9 @@
*/
@SuppressWarnings({"TypeName", "PMD.UnusedPrivateField"})
public class ADXL345_I2C implements NTSendable, AutoCloseable {
- private static final byte kAddress = 0x1D;
+ /** Default I2C device address. */
+ public static final byte kAddress = 0x1D;
+
private static final byte kPowerCtlRegister = 0x2D;
private static final byte kDataFormatRegister = 0x31;
private static final byte kDataRegister = 0x32;
@@ -43,16 +45,25 @@
private static final byte kDataFormat_FullRes = 0x08;
private static final byte kDataFormat_Justify = 0x04;
+ /** Accelerometer range. */
public enum Range {
+ /** 2 Gs max. */
k2G,
+ /** 4 Gs max. */
k4G,
+ /** 8 Gs max. */
k8G,
+ /** 16 Gs max. */
k16G
}
+ /** Accelerometer axes. */
public enum Axes {
+ /** X axis. */
kX((byte) 0x00),
+ /** Y axis. */
kY((byte) 0x02),
+ /** Z axis. */
kZ((byte) 0x04);
/** The integer value representing this enumeration. */
@@ -63,20 +74,29 @@
}
}
+ /** Container type for accelerations from all axes. */
@SuppressWarnings("MemberName")
public static class AllAxes {
+ /** Acceleration along the X axis in g-forces. */
public double XAxis;
+
+ /** Acceleration along the Y axis in g-forces. */
public double YAxis;
+
+ /** Acceleration along the Z axis in g-forces. */
public double ZAxis;
+
+ /** Default constructor. */
+ public AllAxes() {}
}
- protected I2C m_i2c;
+ private I2C m_i2c;
- protected SimDevice m_simDevice;
- protected SimEnum m_simRange;
- protected SimDouble m_simX;
- protected SimDouble m_simY;
- protected SimDouble m_simZ;
+ private SimDevice m_simDevice;
+ private SimEnum m_simRange;
+ private SimDouble m_simX;
+ private SimDouble m_simY;
+ private SimDouble m_simZ;
/**
* Constructs the ADXL345 Accelerometer with I2C address 0x1D.
@@ -95,6 +115,7 @@
* @param range The range (+ or -) that the accelerometer will measure.
* @param deviceAddress I2C address of the accelerometer (0x1D or 0x53)
*/
+ @SuppressWarnings("this-escape")
public ADXL345_I2C(I2C.Port port, Range range, int deviceAddress) {
m_i2c = new I2C(port, deviceAddress);
@@ -122,10 +143,20 @@
SendableRegistry.addLW(this, "ADXL345_I2C", port.value);
}
+ /**
+ * Returns the I2C port.
+ *
+ * @return The I2C port.
+ */
public int getPort() {
return m_i2c.getPort();
}
+ /**
+ * Returns the I2C device address.
+ *
+ * @return The I2C device address.
+ */
public int getDeviceAddress() {
return m_i2c.getDeviceAddress();
}
@@ -149,7 +180,7 @@
* @param range The maximum acceleration, positive or negative, that the accelerometer will
* measure.
*/
- public void setRange(Range range) {
+ public final void setRange(Range range) {
final byte value;
switch (range) {
case k2G:
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADXL345_SPI.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADXL345_SPI.java
index 7291443..4c8435a 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADXL345_SPI.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADXL345_SPI.java
@@ -40,16 +40,25 @@
private static final int kDataFormat_FullRes = 0x08;
private static final int kDataFormat_Justify = 0x04;
+ /** Accelerometer range. */
public enum Range {
+ /** 2 Gs max. */
k2G,
+ /** 4 Gs max. */
k4G,
+ /** 8 Gs max. */
k8G,
+ /** 16 Gs max. */
k16G
}
+ /** Accelerometer axes. */
public enum Axes {
+ /** X axis. */
kX((byte) 0x00),
+ /** Y axis. */
kY((byte) 0x02),
+ /** Z axis. */
kZ((byte) 0x04);
/** The integer value representing this enumeration. */
@@ -60,20 +69,29 @@
}
}
+ /** Container type for accelerations from all axes. */
@SuppressWarnings("MemberName")
public static class AllAxes {
+ /** Acceleration along the X axis in g-forces. */
public double XAxis;
+
+ /** Acceleration along the Y axis in g-forces. */
public double YAxis;
+
+ /** Acceleration along the Z axis in g-forces. */
public double ZAxis;
+
+ /** Default constructor. */
+ public AllAxes() {}
}
- protected SPI m_spi;
+ private SPI m_spi;
- protected SimDevice m_simDevice;
- protected SimEnum m_simRange;
- protected SimDouble m_simX;
- protected SimDouble m_simY;
- protected SimDouble m_simZ;
+ private SimDevice m_simDevice;
+ private SimEnum m_simRange;
+ private SimDouble m_simX;
+ private SimDouble m_simY;
+ private SimDouble m_simZ;
/**
* Constructor.
@@ -81,6 +99,7 @@
* @param port The SPI port that the accelerometer is connected to
* @param range The range (+ or -) that the accelerometer will measure.
*/
+ @SuppressWarnings("this-escape")
public ADXL345_SPI(SPI.Port port, Range range) {
m_spi = new SPI(port);
// simulation
@@ -101,6 +120,11 @@
SendableRegistry.addLW(this, "ADXL345_SPI", port.value);
}
+ /**
+ * Returns the SPI port.
+ *
+ * @return The SPI port.
+ */
public int getPort() {
return m_spi.getPort();
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADXL362.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADXL362.java
index b094be3..c3de6dd 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADXL362.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADXL362.java
@@ -43,17 +43,26 @@
private static final byte kPowerCtl_Measure = 0x02;
+ /** Accelerometer range. */
public enum Range {
+ /** 2 Gs max. */
k2G,
+ /** 4 Gs max. */
k4G,
+ /** 8 Gs max. */
k8G
}
+ /** Accelerometer axes. */
public enum Axes {
+ /** X axis. */
kX((byte) 0x00),
+ /** Y axis. */
kY((byte) 0x02),
+ /** Z axis. */
kZ((byte) 0x04);
+ /** Axis value. */
public final byte value;
Axes(byte value) {
@@ -61,11 +70,20 @@
}
}
+ /** Container type for accelerations from all axes. */
@SuppressWarnings("MemberName")
public static class AllAxes {
+ /** Acceleration along the X axis in g-forces. */
public double XAxis;
+
+ /** Acceleration along the Y axis in g-forces. */
public double YAxis;
+
+ /** Acceleration along the Z axis in g-forces. */
public double ZAxis;
+
+ /** Default constructor. */
+ public AllAxes() {}
}
private SPI m_spi;
@@ -93,6 +111,7 @@
* @param port The SPI port that the accelerometer is connected to
* @param range The range (+ or -) that the accelerometer will measure.
*/
+ @SuppressWarnings("this-escape")
public ADXL362(SPI.Port port, Range range) {
m_spi = new SPI(port);
@@ -141,6 +160,11 @@
SendableRegistry.addLW(this, "ADXL362", port.value);
}
+ /**
+ * Returns the SPI port.
+ *
+ * @return The SPI port.
+ */
public int getPort() {
return m_spi.getPort();
}
@@ -164,7 +188,7 @@
* @param range The maximum acceleration, positive or negative, that the accelerometer will
* measure.
*/
- public void setRange(Range range) {
+ public final void setRange(Range range) {
if (m_spi == null) {
return;
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADXRS450_Gyro.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADXRS450_Gyro.java
index cbe34c8..799d432 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADXRS450_Gyro.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/ADXRS450_Gyro.java
@@ -59,6 +59,7 @@
*
* @param port The SPI port that the gyro is connected to
*/
+ @SuppressWarnings("this-escape")
public ADXRS450_Gyro(SPI.Port port) {
m_spi = new SPI(port);
@@ -113,7 +114,7 @@
* are in progress, this is typically done when the robot is first turned on while it's sitting at
* rest before the competition starts.
*/
- public void calibrate() {
+ public final void calibrate() {
if (m_spi == null) {
return;
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/AddressableLED.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/AddressableLED.java
index 61a2fa6..bb097ab 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/AddressableLED.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/AddressableLED.java
@@ -14,7 +14,8 @@
*
* <p>By default, the timing supports WS2812B LEDs, but is configurable using setBitTiming()
*
- * <p>Only 1 LED driver is currently supported by the roboRIO.
+ * <p>Only 1 LED driver is currently supported by the roboRIO. However, multiple LED strips can be
+ * connected in series and controlled from the single driver.
*/
public class AddressableLED implements AutoCloseable {
private final int m_pwmHandle;
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogAccelerometer.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogAccelerometer.java
index 3ea9ef7..0bdb2ff 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogAccelerometer.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogAccelerometer.java
@@ -36,6 +36,7 @@
*
* @param channel The channel number for the analog input the accelerometer is connected to
*/
+ @SuppressWarnings("this-escape")
public AnalogAccelerometer(final int channel) {
this(new AnalogInput(channel), true);
SendableRegistry.addChild(this, m_analogChannel);
@@ -49,10 +50,12 @@
* @param channel The existing AnalogInput object for the analog input the accelerometer is
* connected to
*/
+ @SuppressWarnings("this-escape")
public AnalogAccelerometer(final AnalogInput channel) {
this(channel, false);
}
+ @SuppressWarnings("this-escape")
private AnalogAccelerometer(final AnalogInput channel, final boolean allocatedChannel) {
requireNonNullParam(channel, "channel", "AnalogAccelerometer");
m_allocatedChannel = allocatedChannel;
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogEncoder.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogEncoder.java
index 8e45869..727ad2c 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogEncoder.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogEncoder.java
@@ -22,9 +22,9 @@
private double m_distancePerRotation = 1.0;
private double m_lastPosition;
- protected SimDevice m_simDevice;
- protected SimDouble m_simPosition;
- protected SimDouble m_simAbsolutePosition;
+ private SimDevice m_simDevice;
+ private SimDouble m_simPosition;
+ private SimDouble m_simAbsolutePosition;
/**
* Construct a new AnalogEncoder attached to a specific AnalogIn channel.
@@ -40,6 +40,7 @@
*
* @param analogInput the analog input to attach to
*/
+ @SuppressWarnings("this-escape")
public AnalogEncoder(AnalogInput analogInput) {
m_analogInput = analogInput;
init();
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogGyro.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogGyro.java
index f5be4ad..29a17bb 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogGyro.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogGyro.java
@@ -25,13 +25,13 @@
*/
public class AnalogGyro implements Sendable, AutoCloseable {
private static final double kDefaultVoltsPerDegreePerSecond = 0.007;
- protected AnalogInput m_analog;
+ private AnalogInput m_analog;
private boolean m_channelAllocated;
private int m_gyroHandle;
/** Initialize the gyro. Calibration is handled by calibrate(). */
- public void initGyro() {
+ private void initGyro() {
if (m_gyroHandle == 0) {
m_gyroHandle = AnalogGyroJNI.initializeAnalogGyro(m_analog.m_port);
}
@@ -78,6 +78,7 @@
* @param channel The analog channel the gyro is connected to. Gyros can only be used on on-board
* channels 0-1.
*/
+ @SuppressWarnings("this-escape")
public AnalogGyro(int channel) {
this(new AnalogInput(channel));
m_channelAllocated = true;
@@ -91,6 +92,7 @@
* @param channel The AnalogInput object that the gyro is connected to. Gyros can only be used on
* on-board channels 0-1.
*/
+ @SuppressWarnings("this-escape")
public AnalogGyro(AnalogInput channel) {
requireNonNullParam(channel, "channel", "AnalogGyro");
@@ -108,6 +110,7 @@
* @param center Preset uncalibrated value to use as the accumulator center value.
* @param offset Preset uncalibrated value to use as the gyro offset.
*/
+ @SuppressWarnings("this-escape")
public AnalogGyro(int channel, int center, double offset) {
this(new AnalogInput(channel), center, offset);
m_channelAllocated = true;
@@ -123,6 +126,7 @@
* @param center Preset uncalibrated value to use as the accumulator center value.
* @param offset Preset uncalibrated value to use as the gyro offset.
*/
+ @SuppressWarnings("this-escape")
public AnalogGyro(AnalogInput channel, int center, double offset) {
requireNonNullParam(channel, "channel", "AnalogGyro");
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogInput.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogInput.java
index e90bfd2..3c6458b 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogInput.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogInput.java
@@ -38,6 +38,7 @@
*
* @param channel The channel number to represent. 0-3 are on-board 4-7 are on the MXP port.
*/
+ @SuppressWarnings("this-escape")
public AnalogInput(final int channel) {
AnalogJNI.checkAnalogInputChannel(channel);
m_channel = channel;
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogOutput.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogOutput.java
index 299d89c..354cedc 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogOutput.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogOutput.java
@@ -21,6 +21,7 @@
*
* @param channel The channel number to represent.
*/
+ @SuppressWarnings("this-escape")
public AnalogOutput(final int channel) {
SensorUtil.checkAnalogOutputChannel(channel);
m_channel = channel;
@@ -49,10 +50,20 @@
return m_channel;
}
+ /**
+ * Set the value of the analog output.
+ *
+ * @param voltage The output value in Volts, from 0.0 to +5.0.
+ */
public void setVoltage(double voltage) {
AnalogJNI.setAnalogOutput(m_port, voltage);
}
+ /**
+ * Get the voltage of the analog output.
+ *
+ * @return The value in Volts, from 0.0 to +5.0.
+ */
public double getVoltage() {
return AnalogJNI.getAnalogOutput(m_port);
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogPotentiometer.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogPotentiometer.java
index 7d58585..1547349 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogPotentiometer.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogPotentiometer.java
@@ -33,6 +33,7 @@
* @param fullRange The scaling to multiply the fraction by to get a meaningful unit.
* @param offset The offset to add to the scaled value for controlling the zero value
*/
+ @SuppressWarnings("this-escape")
public AnalogPotentiometer(final int channel, double fullRange, double offset) {
this(new AnalogInput(channel), fullRange, offset);
m_initAnalogInput = true;
@@ -53,6 +54,7 @@
* input.
* @param offset The angular value (in desired units) representing the angular output at 0V.
*/
+ @SuppressWarnings("this-escape")
public AnalogPotentiometer(final AnalogInput input, double fullRange, double offset) {
SendableRegistry.addLW(this, "AnalogPotentiometer", input.getChannel());
m_analogInput = input;
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogTrigger.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogTrigger.java
index 8baa508..ac25fbb 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogTrigger.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogTrigger.java
@@ -15,30 +15,22 @@
/** Class for creating and configuring Analog Triggers. */
public class AnalogTrigger implements Sendable, AutoCloseable {
- /** Exceptions dealing with improper operation of the Analog trigger. */
- public static class AnalogTriggerException extends RuntimeException {
- /**
- * Create a new exception with the given message.
- *
- * @param message the message to pass with the exception
- */
- public AnalogTriggerException(String message) {
- super(message);
- }
- }
-
/** Where the analog trigger is attached. */
protected int m_port;
- protected AnalogInput m_analogInput;
- protected DutyCycle m_dutyCycle;
- protected boolean m_ownsAnalog;
+ private AnalogInput m_analogInput;
+
+ @SuppressWarnings({"PMD.SingularField", "PMD.UnusedPrivateField"})
+ private DutyCycle m_dutyCycle;
+
+ private boolean m_ownsAnalog;
/**
* Constructor for an analog trigger given a channel number.
*
* @param channel the port to use for the analog trigger
*/
+ @SuppressWarnings("this-escape")
public AnalogTrigger(final int channel) {
this(new AnalogInput(channel));
m_ownsAnalog = true;
@@ -51,6 +43,7 @@
*
* @param channel the AnalogInput to use for the analog trigger
*/
+ @SuppressWarnings("this-escape")
public AnalogTrigger(AnalogInput channel) {
m_analogInput = channel;
@@ -67,6 +60,7 @@
*
* @param input the DutyCycle to use for the analog trigger
*/
+ @SuppressWarnings("this-escape")
public AnalogTrigger(DutyCycle input) {
m_dutyCycle = input;
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogTriggerOutput.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogTriggerOutput.java
index c80179b..4d459fc 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogTriggerOutput.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/AnalogTriggerOutput.java
@@ -106,9 +106,13 @@
/** Defines the state in which the AnalogTrigger triggers. */
public enum AnalogTriggerType {
+ /** In window. */
kInWindow(AnalogJNI.AnalogTriggerType.kInWindow),
+ /** State. */
kState(AnalogJNI.AnalogTriggerType.kState),
+ /** Rising pulse. */
kRisingPulse(AnalogJNI.AnalogTriggerType.kRisingPulse),
+ /** Falling pulse. */
kFallingPulse(AnalogJNI.AnalogTriggerType.kFallingPulse);
private final int value;
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/BuiltInAccelerometer.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/BuiltInAccelerometer.java
index 1a6b103..522ab88 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/BuiltInAccelerometer.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/BuiltInAccelerometer.java
@@ -17,9 +17,13 @@
* <p>This class allows access to the roboRIO's internal accelerometer.
*/
public class BuiltInAccelerometer implements Sendable, AutoCloseable {
+ /** Accelerometer range. */
public enum Range {
+ /** 2 Gs max. */
k2G,
+ /** 4 Gs max. */
k4G,
+ /** 8 Gs max. */
k8G
}
@@ -28,6 +32,7 @@
*
* @param range The range the accelerometer will measure
*/
+ @SuppressWarnings("this-escape")
public BuiltInAccelerometer(Range range) {
setRange(range);
HAL.report(tResourceType.kResourceType_Accelerometer, 0, 0, "Built-in accelerometer");
@@ -50,7 +55,7 @@
* @param range The maximum acceleration, positive or negative, that the accelerometer will
* measure.
*/
- public void setRange(Range range) {
+ public final void setRange(Range range) {
AccelerometerJNI.setAccelerometerActive(false);
switch (range) {
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/CAN.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/CAN.java
index 8808a4b..df0be48 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/CAN.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/CAN.java
@@ -5,6 +5,7 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.CANAPIJNI;
+import edu.wpi.first.hal.CANAPITypes;
import edu.wpi.first.hal.CANData;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
@@ -21,8 +22,11 @@
* calls.
*/
public class CAN implements Closeable {
- public static final int kTeamManufacturer = 8;
- public static final int kTeamDeviceType = 10;
+ /** Team manufacturer. */
+ public static final int kTeamManufacturer = CANAPITypes.CANManufacturer.kTeamUse.id;
+
+ /** Team device type. */
+ public static final int kTeamDeviceType = CANAPITypes.CANDeviceType.kMiscellaneous.id;
private final int m_handle;
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Compressor.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Compressor.java
index f2cfeb3..e7a14bd 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Compressor.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Compressor.java
@@ -31,6 +31,7 @@
* @param module The module ID to use.
* @param moduleType The module type to use.
*/
+ @SuppressWarnings("this-escape")
public Compressor(int module, PneumaticsModuleType moduleType) {
m_module = PneumaticsBase.getForType(module, moduleType);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/CompressorConfigType.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/CompressorConfigType.java
index 48bb81f..7735cdd 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/CompressorConfigType.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/CompressorConfigType.java
@@ -6,12 +6,18 @@
import edu.wpi.first.hal.REVPHJNI;
+/** Compressor config type. */
public enum CompressorConfigType {
+ /** Disabled. */
Disabled(REVPHJNI.COMPRESSOR_CONFIG_TYPE_DISABLED),
+ /** Digital. */
Digital(REVPHJNI.COMPRESSOR_CONFIG_TYPE_DIGITAL),
+ /** Analog. */
Analog(REVPHJNI.COMPRESSOR_CONFIG_TYPE_ANALOG),
+ /** Hybrid. */
Hybrid(REVPHJNI.COMPRESSOR_CONFIG_TYPE_HYBRID);
+ /** CompressorConfigType value. */
public final int value;
CompressorConfigType(int value) {
@@ -37,6 +43,11 @@
}
}
+ /**
+ * Returns the CompressorConfigType's value.
+ *
+ * @return The CompressorConfigType's value.
+ */
public int getValue() {
return value;
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Counter.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Counter.java
index d8c5015..eca3dd5 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Counter.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Counter.java
@@ -38,6 +38,7 @@
/** mode: external direction. */
kExternalDirection(3);
+ /** Mode value. */
public final int value;
Mode(int value) {
@@ -45,19 +46,30 @@
}
}
- protected DigitalSource m_upSource; // /< What makes the counter count up.
- protected DigitalSource m_downSource; // /< What makes the counter count down.
+ /** What makes the counter count up. */
+ protected DigitalSource m_upSource;
+
+ /** What makes the counter count down. */
+ protected DigitalSource m_downSource;
+
private boolean m_allocatedUpSource;
private boolean m_allocatedDownSource;
- int m_counter; // /< The FPGA counter object.
- private int m_index; // /< The index of this counter.
- private double m_distancePerPulse = 1; // distance of travel for each tick
+
+ /** The FPGA counter object. */
+ int m_counter;
+
+ /** The index of this counter. */
+ private int m_index;
+
+ /** Distance of travel for each tick. */
+ private double m_distancePerPulse = 1;
/**
* Create an instance of a counter with the given mode.
*
* @param mode The counter mode.
*/
+ @SuppressWarnings("this-escape")
public Counter(final Mode mode) {
ByteBuffer index = ByteBuffer.allocateDirect(4);
// set the byte order
@@ -95,6 +107,7 @@
*
* @param source the digital source to count
*/
+ @SuppressWarnings("this-escape")
public Counter(DigitalSource source) {
this();
@@ -109,6 +122,7 @@
*
* @param channel the DIO channel to use as the up source. 0-9 are on-board, 10-25 are on the MXP
*/
+ @SuppressWarnings("this-escape")
public Counter(int channel) {
this();
setUpSource(channel);
@@ -125,6 +139,7 @@
* @param downSource second source for direction
* @param inverted true to invert the count
*/
+ @SuppressWarnings("this-escape")
public Counter(
EncodingType encodingType,
DigitalSource upSource,
@@ -162,6 +177,7 @@
*
* @param trigger the analog trigger to count
*/
+ @SuppressWarnings("this-escape")
public Counter(AnalogTrigger trigger) {
this();
@@ -200,7 +216,7 @@
*
* @param channel the DIO channel to count 0-9 are on-board, 10-25 are on the MXP
*/
- public void setUpSource(int channel) {
+ public final void setUpSource(int channel) {
setUpSource(new DigitalInput(channel));
m_allocatedUpSource = true;
SendableRegistry.addChild(this, m_upSource);
@@ -401,7 +417,7 @@
* @param maxPeriod The maximum period where the counted device is considered moving in seconds.
*/
@Override
- public void setMaxPeriod(double maxPeriod) {
+ public final void setMaxPeriod(double maxPeriod) {
CounterJNI.setCounterMaxPeriod(m_counter, maxPeriod);
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/CounterBase.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/CounterBase.java
index 60d5690..6e03b72 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/CounterBase.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/CounterBase.java
@@ -22,6 +22,7 @@
/** Count rising and falling on both channels. */
k4X(2);
+ /** EncodingType value. */
public final int value;
EncodingType(int value) {
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DMA.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DMA.java
index a919da5..bd26a7b 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DMA.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DMA.java
@@ -7,9 +7,11 @@
import edu.wpi.first.hal.DMAJNI;
import edu.wpi.first.wpilibj.motorcontrol.PWMMotorController;
+/** Class for configuring Direct Memory Access (DMA) of FPGA inputs. */
public class DMA implements AutoCloseable {
final int m_dmaHandle;
+ /** Default constructor. */
public DMA() {
m_dmaHandle = DMAJNI.initialize();
}
@@ -19,50 +21,128 @@
DMAJNI.free(m_dmaHandle);
}
+ /**
+ * Sets whether DMA is paused.
+ *
+ * @param pause True pauses DMA.
+ */
public void setPause(boolean pause) {
DMAJNI.setPause(m_dmaHandle, pause);
}
+ /**
+ * Sets DMA to trigger at an interval.
+ *
+ * @param periodSeconds Period at which to trigger DMA in seconds.
+ */
public void setTimedTrigger(double periodSeconds) {
DMAJNI.setTimedTrigger(m_dmaHandle, periodSeconds);
}
+ /**
+ * Sets number of DMA cycles to trigger.
+ *
+ * @param cycles Number of cycles.
+ */
public void setTimedTriggerCycles(int cycles) {
DMAJNI.setTimedTriggerCycles(m_dmaHandle, cycles);
}
+ /**
+ * Adds position data for an encoder to be collected by DMA.
+ *
+ * <p>This can only be called if DMA is not started.
+ *
+ * @param encoder Encoder to add to DMA.
+ */
public void addEncoder(Encoder encoder) {
DMAJNI.addEncoder(m_dmaHandle, encoder.m_encoder);
}
+ /**
+ * Adds timer data for an encoder to be collected by DMA.
+ *
+ * <p>This can only be called if DMA is not started.
+ *
+ * @param encoder Encoder to add to DMA.
+ */
public void addEncoderPeriod(Encoder encoder) {
DMAJNI.addEncoderPeriod(m_dmaHandle, encoder.m_encoder);
}
+ /**
+ * Adds position data for an counter to be collected by DMA.
+ *
+ * <p>This can only be called if DMA is not started.
+ *
+ * @param counter Counter to add to DMA.
+ */
public void addCounter(Counter counter) {
DMAJNI.addCounter(m_dmaHandle, counter.m_counter);
}
+ /**
+ * Adds timer data for an counter to be collected by DMA.
+ *
+ * <p>This can only be called if DMA is not started.
+ *
+ * @param counter Counter to add to DMA.
+ */
public void addCounterPeriod(Counter counter) {
DMAJNI.addCounterPeriod(m_dmaHandle, counter.m_counter);
}
+ /**
+ * Adds a digital source to be collected by DMA.
+ *
+ * <p>This can only be called if DMA is not started.
+ *
+ * @param digitalSource DigitalSource to add to DMA.
+ */
public void addDigitalSource(DigitalSource digitalSource) {
DMAJNI.addDigitalSource(m_dmaHandle, digitalSource.getPortHandleForRouting());
}
+ /**
+ * Adds a duty cycle input to be collected by DMA.
+ *
+ * <p>This can only be called if DMA is not started.
+ *
+ * @param dutyCycle DutyCycle to add to DMA.
+ */
public void addDutyCycle(DutyCycle dutyCycle) {
DMAJNI.addDutyCycle(m_dmaHandle, dutyCycle.m_handle);
}
+ /**
+ * Adds an analog input to be collected by DMA.
+ *
+ * <p>This can only be called if DMA is not started.
+ *
+ * @param analogInput AnalogInput to add to DMA.
+ */
public void addAnalogInput(AnalogInput analogInput) {
DMAJNI.addAnalogInput(m_dmaHandle, analogInput.m_port);
}
+ /**
+ * Adds averaged data of an analog input to be collected by DMA.
+ *
+ * <p>This can only be called if DMA is not started.
+ *
+ * @param analogInput AnalogInput to add to DMA.
+ */
public void addAveragedAnalogInput(AnalogInput analogInput) {
DMAJNI.addAveragedAnalogInput(m_dmaHandle, analogInput.m_port);
}
+ /**
+ * Adds accumulator data of an analog input to be collected by DMA.
+ *
+ * <p>This can only be called if DMA is not started.
+ *
+ * @param analogInput AnalogInput to add to DMA.
+ */
public void addAnalogAccumulator(AnalogInput analogInput) {
DMAJNI.addAnalogAccumulator(m_dmaHandle, analogInput.m_port);
}
@@ -84,26 +164,58 @@
falling);
}
- public int setPwmEdgeTrigger(PWMMotorController pwm, boolean rising, boolean falling) {
- return DMAJNI.setExternalTrigger(m_dmaHandle, pwm.getPwmHandle(), 0, rising, falling);
- }
-
+ /**
+ * Sets a DMA PWM edge trigger.
+ *
+ * @param pwm the PWM to trigger from.
+ * @param rising trigger on rising edge.
+ * @param falling trigger on falling edge.
+ * @return the index of the trigger
+ */
public int setPwmEdgeTrigger(PWM pwm, boolean rising, boolean falling) {
return DMAJNI.setExternalTrigger(m_dmaHandle, pwm.getHandle(), 0, rising, falling);
}
+ /**
+ * Sets a DMA PWMMotorController edge trigger.
+ *
+ * @param pwm the PWMMotorController to trigger from.
+ * @param rising trigger on rising edge.
+ * @param falling trigger on falling edge.
+ * @return the index of the trigger
+ */
+ public int setPwmEdgeTrigger(PWMMotorController pwm, boolean rising, boolean falling) {
+ return DMAJNI.setExternalTrigger(m_dmaHandle, pwm.getPwmHandle(), 0, rising, falling);
+ }
+
+ /**
+ * Clear all sensors from the DMA collection list.
+ *
+ * <p>This can only be called if DMA is not started.
+ */
public void clearSensors() {
DMAJNI.clearSensors(m_dmaHandle);
}
+ /**
+ * Clear all external triggers from the DMA trigger list.
+ *
+ * <p>This can only be called if DMA is not started.
+ */
public void clearExternalTriggers() {
DMAJNI.clearExternalTriggers(m_dmaHandle);
}
+ /**
+ * Starts DMA Collection.
+ *
+ * @param queueDepth The number of objects to be able to queue.
+ */
public void start(int queueDepth) {
DMAJNI.startDMA(m_dmaHandle, queueDepth);
}
+ /** Stops DMA Collection. */
public void stop() {
DMAJNI.stopDMA(m_dmaHandle);
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DMASample.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DMASample.java
index 1055dbc..1435cd3 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DMASample.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DMASample.java
@@ -7,10 +7,15 @@
import edu.wpi.first.hal.AnalogJNI;
import edu.wpi.first.hal.DMAJNISample;
+/** DMA sample. */
public class DMASample {
+ /** DMA read status. */
public enum DMAReadStatus {
+ /** OK status. */
kOk(1),
+ /** Timeout status. */
kTimeout(2),
+ /** Error status. */
kError(3);
private final int value;
@@ -19,6 +24,11 @@
this.value = value;
}
+ /**
+ * Returns the DMAReadStatus value.
+ *
+ * @return The DMAReadStatus value.
+ */
public int getValue() {
return value;
}
@@ -41,39 +51,80 @@
private final DMAJNISample m_dmaSample = new DMAJNISample();
+ /** Default constructor. */
+ public DMASample() {}
+
+ /**
+ * Retrieves a new DMA sample.
+ *
+ * @param dma DMA object.
+ * @param timeoutSeconds Timeout in seconds for retrieval.
+ * @return DMA read status.
+ */
public DMAReadStatus update(DMA dma, double timeoutSeconds) {
return DMAReadStatus.getValue(m_dmaSample.update(dma.m_dmaHandle, timeoutSeconds));
}
- public int getCaptureSize() {
- return m_dmaSample.getCaptureSize();
- }
-
- public int getTriggerChannels() {
- return m_dmaSample.getTriggerChannels();
- }
-
- public int getRemaining() {
- return m_dmaSample.getRemaining();
- }
-
+ /**
+ * Returns the DMA sample time in microseconds.
+ *
+ * @return The DMA sample time in microseconds.
+ */
public long getTime() {
return m_dmaSample.getTime();
}
+ /**
+ * Returns the DMA sample timestamp in seconds.
+ *
+ * @return The DMA sample timestamp in seconds.
+ */
public double getTimeStamp() {
return getTime() * 1.0e-6;
}
+ /**
+ * Returns the DMA sample capture size.
+ *
+ * @return The DMA sample capture size.
+ */
+ public int getCaptureSize() {
+ return m_dmaSample.getCaptureSize();
+ }
+
+ /**
+ * Returns the number of DMA trigger channels.
+ *
+ * @return The number of DMA trigger channels.
+ */
+ public int getTriggerChannels() {
+ return m_dmaSample.getTriggerChannels();
+ }
+
+ /**
+ * Returns the number of remaining samples.
+ *
+ * @return The number of remaining samples.
+ */
+ public int getRemaining() {
+ return m_dmaSample.getRemaining();
+ }
+
+ /**
+ * Returns raw encoder value from DMA.
+ *
+ * @param encoder Encoder used for DMA.
+ * @return Raw encoder value from DMA.
+ */
public int getEncoderRaw(Encoder encoder) {
return m_dmaSample.getEncoder(encoder.m_encoder);
}
/**
- * Gets the scaled encoder distance for this sample.
+ * Returns encoder distance from DMA.
*
- * @param encoder the encoder to use to read
- * @return the distance
+ * @param encoder Encoder used for DMA.
+ * @return Encoder distance from DMA.
*/
public double getEncoderDistance(Encoder encoder) {
double val = getEncoderRaw(encoder);
@@ -82,43 +133,103 @@
return val;
}
+ /**
+ * Returns raw encoder period from DMA.
+ *
+ * @param encoder Encoder used for DMA.
+ * @return Raw encoder period from DMA.
+ */
public int getEncoderPeriodRaw(Encoder encoder) {
return m_dmaSample.getEncoderPeriod(encoder.m_encoder);
}
+ /**
+ * Returns counter value from DMA.
+ *
+ * @param counter Counter used for DMA.
+ * @return Counter value from DMA.
+ */
public int getCounter(Counter counter) {
return m_dmaSample.getCounter(counter.m_counter);
}
+ /**
+ * Returns counter period from DMA.
+ *
+ * @param counter Counter used for DMA.
+ * @return Counter period from DMA.
+ */
public int getCounterPeriod(Counter counter) {
return m_dmaSample.getCounterPeriod(counter.m_counter);
}
+ /**
+ * Returns digital source value from DMA.
+ *
+ * @param digitalSource DigitalSource used for DMA.
+ * @return DigitalSource value from DMA.
+ */
public boolean getDigitalSource(DigitalSource digitalSource) {
return m_dmaSample.getDigitalSource(digitalSource.getPortHandleForRouting());
}
+ /**
+ * Returns raw analog input value from DMA.
+ *
+ * @param analogInput AnalogInput used for DMA.
+ * @return Raw analog input value from DMA.
+ */
public int getAnalogInputRaw(AnalogInput analogInput) {
return m_dmaSample.getAnalogInput(analogInput.m_port);
}
+ /**
+ * Returns analog input voltage from DMA.
+ *
+ * @param analogInput AnalogInput used for DMA.
+ * @return Analog input voltage from DMA.
+ */
public double getAnalogInputVoltage(AnalogInput analogInput) {
return AnalogJNI.getAnalogValueToVolts(analogInput.m_port, getAnalogInputRaw(analogInput));
}
+ /**
+ * Returns averaged raw analog input value from DMA.
+ *
+ * @param analogInput AnalogInput used for DMA.
+ * @return Averaged raw analog input value from DMA.
+ */
public int getAveragedAnalogInputRaw(AnalogInput analogInput) {
return m_dmaSample.getAnalogInputAveraged(analogInput.m_port);
}
+ /**
+ * Returns averaged analog input voltage from DMA.
+ *
+ * @param analogInput AnalogInput used for DMA.
+ * @return Averaged analog input voltage from DMA.
+ */
public double getAveragedAnalogInputVoltage(AnalogInput analogInput) {
return AnalogJNI.getAnalogValueToVolts(
analogInput.m_port, getAveragedAnalogInputRaw(analogInput));
}
+ /**
+ * Returns raw duty cycle output from DMA.
+ *
+ * @param dutyCycle DutyCycle used for DMA.
+ * @return Raw duty cycle output from DMA.
+ */
public int getDutyCycleOutputRaw(DutyCycle dutyCycle) {
return m_dmaSample.getDutyCycleOutput(dutyCycle.m_handle);
}
+ /**
+ * Returns duty cycle output (0-1) from DMA.
+ *
+ * @param dutyCycle DutyCycle used for DMA.
+ * @return Duty cycle output (0-1) from DMA.
+ */
public double getDutyCycleOutput(DutyCycle dutyCycle) {
return m_dmaSample.getDutyCycleOutput(dutyCycle.m_handle)
/ (double) dutyCycle.getOutputScaleFactor();
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DSControlWord.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DSControlWord.java
index 8837d41..a656d9c 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DSControlWord.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DSControlWord.java
@@ -20,7 +20,7 @@
}
/** Update internal Driver Station control word. */
- public void refresh() {
+ public final void refresh() {
DriverStation.refreshControlWordFromCache(m_controlWord);
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DataLogManager.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DataLogManager.java
index 8098ae9..d4ec796 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DataLogManager.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DataLogManager.java
@@ -25,8 +25,8 @@
/**
* Centralized data log that provides automatic data log file management. It automatically cleans up
* old files when disk space is low and renames the file based either on current date/time or (if
- * available) competition match number. The deta file will be saved to a USB flash drive if one is
- * attached, or to /home/lvuser otherwise.
+ * available) competition match number. The data file will be saved to a USB flash drive in a folder
+ * named "logs" if one is attached, or to /home/lvuser/logs otherwise.
*
* <p>Log files are initially named "FRC_TBD_{random}.wpilog" until the DS connects. After the DS
* connects, the log file is renamed to "FRC_yyyyMMdd_HHmmss.wpilog" (where the date/time is UTC).
@@ -214,7 +214,10 @@
// prefer a mounted USB drive if one is accessible
Path usbDir = Paths.get("/u").toRealPath();
if (Files.isWritable(usbDir)) {
- return usbDir.toString();
+ if (!new File("/u/logs").mkdir()) {
+ // ignored
+ }
+ return "/u/logs";
}
} catch (IOException ex) {
// ignored
@@ -225,8 +228,16 @@
+ " Plug in a FAT32 formatted flash drive!",
false);
}
+ if (!new File("/home/lvuser/logs").mkdir()) {
+ // ignored
+ }
+ return "/home/lvuser/logs";
}
- return Filesystem.getOperatingDirectory().getAbsolutePath();
+ String logDir = Filesystem.getOperatingDirectory().getAbsolutePath() + "/logs";
+ if (!new File(logDir).mkdir()) {
+ // ignored
+ }
+ return logDir;
}
private static String makeLogFilename(String filenameOverride) {
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DigitalGlitchFilter.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DigitalGlitchFilter.java
index 3422d34..2fcc9dd 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DigitalGlitchFilter.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DigitalGlitchFilter.java
@@ -20,6 +20,7 @@
*/
public class DigitalGlitchFilter implements Sendable, AutoCloseable {
/** Configures the Digital Glitch Filter to its default settings. */
+ @SuppressWarnings("this-escape")
public DigitalGlitchFilter() {
m_mutex.lock();
try {
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DigitalInput.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DigitalInput.java
index 5b4cf5e..ab3d5e5 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DigitalInput.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DigitalInput.java
@@ -27,6 +27,7 @@
*
* @param channel the DIO channel for the digital input 0-9 are on-board, 10-25 are on the MXP
*/
+ @SuppressWarnings("this-escape")
public DigitalInput(int channel) {
SensorUtil.checkDigitalChannel(channel);
m_channel = channel;
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DigitalOutput.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DigitalOutput.java
index 78e8bed..a7446f6 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DigitalOutput.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DigitalOutput.java
@@ -29,6 +29,7 @@
* @param channel the DIO channel to use for the digital output. 0-9 are on-board, 10-25 are on
* the MXP
*/
+ @SuppressWarnings("this-escape")
public DigitalOutput(int channel) {
SensorUtil.checkDigitalChannel(channel);
m_channel = channel;
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DigitalSource.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DigitalSource.java
index cb8b024..494efe9 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DigitalSource.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DigitalSource.java
@@ -11,8 +11,21 @@
* source. The source can either be a digital input or analog trigger but not both.
*/
public abstract class DigitalSource implements AutoCloseable {
+ /** Default constructor. */
+ public DigitalSource() {}
+
+ /**
+ * Returns true if this DigitalSource is an AnalogTrigger.
+ *
+ * @return True if this DigitalSource is an AnalogTrigger.
+ */
public abstract boolean isAnalogTrigger();
+ /**
+ * The DigitalSource channel.
+ *
+ * @return The DigitalSource channel.
+ */
public abstract int getChannel();
/**
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DoubleSolenoid.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DoubleSolenoid.java
index d749ccc..de0697c 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DoubleSolenoid.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DoubleSolenoid.java
@@ -21,8 +21,11 @@
public class DoubleSolenoid implements Sendable, AutoCloseable {
/** Possible values for a DoubleSolenoid. */
public enum Value {
+ /** Off position. */
kOff,
+ /** Forward position. */
kForward,
+ /** Reverse position. */
kReverse
}
@@ -53,7 +56,7 @@
* @param forwardChannel The forward channel on the module to control.
* @param reverseChannel The reverse channel on the module to control.
*/
- @SuppressWarnings("PMD.UseTryWithResources")
+ @SuppressWarnings({"PMD.UseTryWithResources", "this-escape"})
public DoubleSolenoid(
final int module,
final PneumaticsModuleType moduleType,
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DriverStation.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DriverStation.java
index ce3a3e0..4ee656b 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DriverStation.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DriverStation.java
@@ -29,7 +29,7 @@
/** Provide access to the network communication data to / from the Driver Station. */
public final class DriverStation {
- /** Number of Joystick Ports. */
+ /** Number of Joystick ports. */
public static final int kJoystickPorts = 6;
private static class HALJoystickButtons {
@@ -69,14 +69,21 @@
/** The robot alliance that the robot is a part of. */
public enum Alliance {
+ /** Red alliance. */
Red,
+ /** Blue alliance. */
Blue
}
+ /** The type of robot match that the robot is part of. */
public enum MatchType {
+ /** None. */
None,
+ /** Practice. */
Practice,
+ /** Qualification. */
Qualification,
+ /** Elimination. */
Elimination
}
@@ -239,6 +246,7 @@
for (int i = 0; i < count; i++) {
if (axes.m_axes[i] != m_prevAxes.m_axes[i]) {
needToLog = true;
+ break;
}
}
}
@@ -255,6 +263,7 @@
for (int i = 0; i < count; i++) {
if (povs.m_povs[i] != m_prevPOVs.m_povs[i]) {
needToLog = true;
+ break;
}
}
}
@@ -1113,7 +1122,7 @@
*
* <p>If the FMS is not connected, it is set from the team alliance setting on the driver station.
*
- * @return the current alliance
+ * @return The alliance (red or blue) or an empty optional if the alliance is invalid
*/
public static Optional<Alliance> getAlliance() {
AllianceStationID allianceStationID = DriverStationJNI.getAllianceStation();
@@ -1312,10 +1321,20 @@
}
}
+ /**
+ * Registers the given handle for DS data refresh notifications.
+ *
+ * @param handle The event handle.
+ */
public static void provideRefreshedDataEventHandle(int handle) {
m_refreshEvents.add(handle);
}
+ /**
+ * Unregisters the given handle from DS data refresh notifications.
+ *
+ * @param handle The event handle.
+ */
public static void removeRefreshedDataEventHandle(int handle) {
m_refreshEvents.remove(handle);
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DutyCycle.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DutyCycle.java
index d500ba7..8c26d55 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DutyCycle.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DutyCycle.java
@@ -33,6 +33,7 @@
*
* @param digitalSource The DigitalSource to use.
*/
+ @SuppressWarnings("this-escape")
public DutyCycle(DigitalSource digitalSource) {
m_handle =
DutyCycleJNI.initialize(
@@ -102,6 +103,11 @@
return DutyCycleJNI.getFPGAIndex(m_handle);
}
+ /**
+ * Get the channel of the source.
+ *
+ * @return the source channel
+ */
public int getSourceChannel() {
return m_source.getChannel();
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DutyCycleEncoder.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DutyCycleEncoder.java
index afdcb3f..a0858ce 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/DutyCycleEncoder.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/DutyCycleEncoder.java
@@ -30,17 +30,18 @@
private double m_sensorMin;
private double m_sensorMax = 1.0;
- protected SimDevice m_simDevice;
- protected SimDouble m_simPosition;
- protected SimDouble m_simAbsolutePosition;
- protected SimDouble m_simDistancePerRotation;
- protected SimBoolean m_simIsConnected;
+ private SimDevice m_simDevice;
+ private SimDouble m_simPosition;
+ private SimDouble m_simAbsolutePosition;
+ private SimDouble m_simDistancePerRotation;
+ private SimBoolean m_simIsConnected;
/**
* Construct a new DutyCycleEncoder on a specific channel.
*
* @param channel the channel to attach to
*/
+ @SuppressWarnings("this-escape")
public DutyCycleEncoder(int channel) {
m_digitalInput = new DigitalInput(channel);
m_ownsDutyCycle = true;
@@ -53,6 +54,7 @@
*
* @param dutyCycle the duty cycle to attach to
*/
+ @SuppressWarnings("this-escape")
public DutyCycleEncoder(DutyCycle dutyCycle) {
m_dutyCycle = dutyCycle;
init();
@@ -63,6 +65,7 @@
*
* @param source the digital source to attach to
*/
+ @SuppressWarnings("this-escape")
public DutyCycleEncoder(DigitalSource source) {
m_ownsDutyCycle = true;
m_dutyCycle = new DutyCycle(source);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Encoder.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Encoder.java
index 2cbb5c7..0aa667e 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Encoder.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Encoder.java
@@ -29,12 +29,18 @@
* before use.
*/
public class Encoder implements CounterBase, Sendable, AutoCloseable {
+ /** Encoder indexing types. */
public enum IndexingType {
+ /** Reset while the signal is high. */
kResetWhileHigh(0),
+ /** Reset while the signal is low. */
kResetWhileLow(1),
+ /** Reset on falling edge of the signal. */
kResetOnFallingEdge(2),
+ /** Reset on rising edge of the signal. */
kResetOnRisingEdge(3);
+ /** IndexingType value. */
public final int value;
IndexingType(int value) {
@@ -122,6 +128,7 @@
* selected, then a counter object will be used and the returned value will either exactly
* match the spec'd count or be double (2x) the spec'd count.
*/
+ @SuppressWarnings("this-escape")
public Encoder(
final int channelA,
final int channelB,
@@ -152,6 +159,7 @@
* @param reverseDirection represents the orientation of the encoder and inverts the output values
* if necessary so forward represents positive values.
*/
+ @SuppressWarnings("this-escape")
public Encoder(
final int channelA, final int channelB, final int indexChannel, boolean reverseDirection) {
this(channelA, channelB, reverseDirection);
@@ -222,6 +230,7 @@
* selected then a counter object will be used and the returned value will either exactly
* match the spec'd count or be double (2x) the spec'd count.
*/
+ @SuppressWarnings("this-escape")
public Encoder(
DigitalSource sourceA,
DigitalSource sourceB,
@@ -492,7 +501,7 @@
*
* @param channel A DIO channel to set as the encoder index
*/
- public void setIndexSource(int channel) {
+ public final void setIndexSource(int channel) {
setIndexSource(channel, IndexingType.kResetOnRisingEdge);
}
@@ -502,7 +511,7 @@
*
* @param source A digital source to set as the encoder index
*/
- public void setIndexSource(DigitalSource source) {
+ public final void setIndexSource(DigitalSource source) {
setIndexSource(source, IndexingType.kResetOnRisingEdge);
}
@@ -513,7 +522,7 @@
* @param channel A DIO channel to set as the encoder index
* @param type The state that will cause the encoder to reset
*/
- public void setIndexSource(int channel, IndexingType type) {
+ public final void setIndexSource(int channel, IndexingType type) {
if (m_allocatedI) {
throw new AllocationException("Digital Input for Indexing already allocated");
}
@@ -530,7 +539,7 @@
* @param source A digital source to set as the encoder index
* @param type The state that will cause the encoder to reset
*/
- public void setIndexSource(DigitalSource source, IndexingType type) {
+ public final void setIndexSource(DigitalSource source, IndexingType type) {
EncoderJNI.setEncoderIndexSource(
m_encoder,
source.getPortHandleForRouting(),
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/GenericHID.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/GenericHID.java
index 58e55f0..e112e95 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/GenericHID.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/GenericHID.java
@@ -19,32 +19,54 @@
* the mapping of ports to hardware buttons depends on the code in the Driver Station.
*/
public class GenericHID {
- /** Represents a rumble output on the JoyStick. */
+ /** Represents a rumble output on the Joystick. */
public enum RumbleType {
+ /** Left rumble motor. */
kLeftRumble,
+ /** Right rumble motor. */
kRightRumble,
+ /** Both left and right rumble motors. */
kBothRumble
}
+ /** USB HID interface type. */
public enum HIDType {
+ /** Unknown. */
kUnknown(-1),
+ /** XInputUnknown. */
kXInputUnknown(0),
+ /** XInputGamepad. */
kXInputGamepad(1),
+ /** XInputWheel. */
kXInputWheel(2),
+ /** XInputArcadeStick. */
kXInputArcadeStick(3),
+ /** XInputFlightStick. */
kXInputFlightStick(4),
+ /** XInputDancePad. */
kXInputDancePad(5),
+ /** XInputGuitar. */
kXInputGuitar(6),
+ /** XInputGuitar2. */
kXInputGuitar2(7),
+ /** XInputDrumKit. */
kXInputDrumKit(8),
+ /** XInputGuitar3. */
kXInputGuitar3(11),
+ /** XInputArcadePad. */
kXInputArcadePad(19),
+ /** HIDJoystick. */
kHIDJoystick(20),
+ /** HIDGamepad. */
kHIDGamepad(21),
+ /** HIDDriving. */
kHIDDriving(22),
+ /** HIDFlight. */
kHIDFlight(23),
+ /** HID1stPerson. */
kHID1stPerson(24);
+ /** HIDType value. */
public final int value;
@SuppressWarnings("PMD.UseConcurrentHashMap")
@@ -60,6 +82,12 @@
}
}
+ /**
+ * Creates an HIDType with the given value.
+ *
+ * @param value HIDType's value.
+ * @return HIDType with the given value.
+ */
public static HIDType of(int value) {
return map.get(value);
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/I2C.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/I2C.java
index 1c37ecf..1ed131b 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/I2C.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/I2C.java
@@ -23,10 +23,14 @@
* WPILib Known Issues</a> page for details.
*/
public class I2C implements AutoCloseable {
+ /** I2C connection ports. */
public enum Port {
+ /** Onboard I2C port. */
kOnboard(0),
+ /** MXP (roboRIO MXP) I2C port. */
kMXP(1);
+ /** Port value. */
public final int value;
Port(int value) {
@@ -58,10 +62,20 @@
HAL.report(tResourceType.kResourceType_I2C, deviceAddress);
}
+ /**
+ * Returns I2C port.
+ *
+ * @return I2C port.
+ */
public int getPort() {
return m_port;
}
+ /**
+ * Returns I2C device address.
+ *
+ * @return I2C device address.
+ */
public int getDeviceAddress() {
return m_deviceAddress;
}
@@ -369,7 +383,7 @@
byte[] deviceData = new byte[4];
for (int i = 0; i < count; i += 4) {
- int toRead = count - i < 4 ? count - i : 4;
+ int toRead = Math.min(count - i, 4);
// Read the chunk of data. Return false if the sensor does not
// respond.
dataToSend[0] = (byte) (registerAddress + i);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/IterativeRobotBase.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/IterativeRobotBase.java
index 4afece4..1243393 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/IterativeRobotBase.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/IterativeRobotBase.java
@@ -5,6 +5,8 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.DriverStationJNI;
+import edu.wpi.first.hal.FRCNetComm.tInstances;
+import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.networktables.NetworkTableInstance;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
@@ -70,7 +72,7 @@
private final double m_period;
private final Watchdog m_watchdog;
private boolean m_ntFlushEnabled = true;
- private boolean m_lwEnabledInTest = true;
+ private boolean m_lwEnabledInTest;
private boolean m_calledDsConnected;
/**
@@ -257,16 +259,22 @@
m_ntFlushEnabled = enabled;
}
+ private boolean m_reportedLw;
+
/**
* Sets whether LiveWindow operation is enabled during test mode. Calling
*
- * @param testLW True to enable, false to disable. Defaults to true.
+ * @param testLW True to enable, false to disable. Defaults to false.
* @throws ConcurrentModificationException if this is called during test mode.
*/
public void enableLiveWindowInTest(boolean testLW) {
if (isTestEnabled()) {
throw new ConcurrentModificationException("Can't configure test mode while in test mode!");
}
+ if (!m_reportedLw && testLW) {
+ HAL.report(tResourceType.kResourceType_SmartDashboard, tInstances.kSmartDashboard_LiveWindow);
+ m_reportedLw = true;
+ }
m_lwEnabledInTest = testLW;
}
@@ -288,6 +296,7 @@
return m_period;
}
+ /** Loop function. */
protected void loopFunc() {
DriverStation.refreshData();
m_watchdog.reset();
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Joystick.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Joystick.java
index d73b7bb..5536009 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Joystick.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Joystick.java
@@ -17,20 +17,35 @@
* and the mapping of ports to hardware buttons depends on the code in the Driver Station.
*/
public class Joystick extends GenericHID {
+ /** Default X axis channel. */
public static final byte kDefaultXChannel = 0;
+
+ /** Default Y axis channel. */
public static final byte kDefaultYChannel = 1;
+
+ /** Default Z axis channel. */
public static final byte kDefaultZChannel = 2;
+
+ /** Default twist axis channel. */
public static final byte kDefaultTwistChannel = 2;
+
+ /** Default throttle axis channel. */
public static final byte kDefaultThrottleChannel = 3;
/** Represents an analog axis on a joystick. */
public enum AxisType {
+ /** X axis. */
kX(0),
+ /** Y axis. */
kY(1),
+ /** Z axis. */
kZ(2),
+ /** Twist axis. */
kTwist(3),
+ /** Throttle axis. */
kThrottle(4);
+ /** AxisType value. */
public final int value;
AxisType(int value) {
@@ -40,9 +55,12 @@
/** Represents a digital button on a joystick. */
public enum ButtonType {
+ /** kTrigger. */
kTrigger(1),
+ /** kTop. */
kTop(2);
+ /** ButtonType value. */
public final int value;
ButtonType(int value) {
@@ -184,7 +202,7 @@
*
* @return the z position
*/
- public double getZ() {
+ public final double getZ() {
return getRawAxis(m_axes[AxisType.kZ.value]);
}
@@ -194,7 +212,7 @@
*
* @return The Twist value of the joystick.
*/
- public double getTwist() {
+ public final double getTwist() {
return getRawAxis(m_axes[AxisType.kTwist.value]);
}
@@ -204,7 +222,7 @@
*
* @return The Throttle value of the joystick.
*/
- public double getThrottle() {
+ public final double getThrottle() {
return getRawAxis(m_axes[AxisType.kThrottle.value]);
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/MotorSafety.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/MotorSafety.java
index c1bf04b..dc969a9 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/MotorSafety.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/MotorSafety.java
@@ -62,11 +62,12 @@
}
/** MotorSafety constructor. */
+ @SuppressWarnings("this-escape")
public MotorSafety() {
synchronized (m_listMutex) {
m_instanceList.add(this);
if (m_safetyThread == null) {
- m_safetyThread = new Thread(() -> threadMain(), "MotorSafety Thread");
+ m_safetyThread = new Thread(MotorSafety::threadMain, "MotorSafety Thread");
m_safetyThread.setDaemon(true);
m_safetyThread.start();
}
@@ -185,7 +186,13 @@
}
}
+ /** Called to stop the motor when the timeout expires. */
public abstract void stopMotor();
+ /**
+ * Returns a description to print when an error occurs.
+ *
+ * @return Description to print when an error occurs.
+ */
public abstract String getDescription();
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Notifier.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Notifier.java
index 7ed6162..8f381a0 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Notifier.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Notifier.java
@@ -113,7 +113,7 @@
updateAlarm();
} else {
// Need to update the alarm to cause it to wait again
- updateAlarm((long) -1);
+ updateAlarm(-1);
}
} finally {
m_processLock.unlock();
@@ -134,7 +134,7 @@
error = cause;
}
DriverStation.reportError(
- "Unhandled exception in Notifier thread: " + error.toString(), error.getStackTrace());
+ "Unhandled exception in Notifier thread: " + error, error.getStackTrace());
DriverStation.reportError(
"The Runnable for this Notifier (or methods called by it) should have handled "
+ "the exception above.\n"
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PS4Controller.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PS4Controller.java
index 2359b7b..e000c6f 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PS4Controller.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PS4Controller.java
@@ -4,6 +4,8 @@
package edu.wpi.first.wpilibj;
+import edu.wpi.first.hal.FRCNetComm.tResourceType;
+import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.event.BooleanEvent;
import edu.wpi.first.wpilibj.event.EventLoop;
@@ -13,6 +15,10 @@
* <p>This class handles PS4 input that comes from the Driver Station. Each time a value is
* requested the most recent value is returned. There is a single class instance for each controller
* and the mapping of ports to hardware buttons depends on the code in the Driver Station.
+ *
+ * <p>Only first party controllers from Sony are guaranteed to have the correct mapping, and only
+ * through the official NI DS. Sim is not guaranteed to have the same mapping, as well as any 3rd
+ * party controllers.
*/
public class PS4Controller extends GenericHID {
/**
@@ -23,27 +29,41 @@
public PS4Controller(int port) {
super(port);
- // re-enable when PS4Controller is added to Usage Reporting
- // HAL.report(tResourceType.kResourceType_PS4Controller, port + 1); /
+ HAL.report(tResourceType.kResourceType_PS4Controller, port + 1);
}
/** Represents a digital button on a PS4Controller. */
public enum Button {
+ /** Square button. */
kSquare(1),
+ /** X button. */
kCross(2),
+ /** Circle button. */
kCircle(3),
+ /** Triangle button. */
kTriangle(4),
+ /** Left Trigger 1 button. */
kL1(5),
+ /** Right Trigger 1 button. */
kR1(6),
+ /** Left Trigger 2 button. */
kL2(7),
+ /** Right Trigger 2 button. */
kR2(8),
+ /** Share button. */
kShare(9),
+ /** Option button. */
kOptions(10),
+ /** Left stick button. */
kL3(11),
+ /** Right stick button. */
kR3(12),
+ /** PlayStation button. */
kPS(13),
+ /** Touchpad click button. */
kTouchpad(14);
+ /** Button value. */
public final int value;
Button(int index) {
@@ -70,13 +90,20 @@
/** Represents an axis on a PS4Controller. */
public enum Axis {
+ /** Left X axis. */
kLeftX(0),
+ /** Left Y axis. */
kLeftY(1),
+ /** Right X axis. */
kRightX(2),
+ /** Right Y axis. */
kRightY(5),
+ /** Left Trigger 2. */
kL2(3),
+ /** Right Trigger 2. */
kR2(4);
+ /** Axis value. */
public final int value;
Axis(int index) {
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PS5Controller.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PS5Controller.java
index 8af98a5..18cb738 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PS5Controller.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PS5Controller.java
@@ -13,6 +13,10 @@
* <p>This class handles PS5 input that comes from the Driver Station. Each time a value is
* requested the most recent value is returned. There is a single class instance for each controller
* and the mapping of ports to hardware buttons depends on the code in the Driver Station.
+ *
+ * <p>Only first party controllers from Sony are guaranteed to have the correct mapping, and only
+ * through the official NI DS. Sim is not guaranteed to have the same mapping, as well as any 3rd
+ * party controllers.
*/
public class PS5Controller extends GenericHID {
/**
@@ -27,21 +31,36 @@
/** Represents a digital button on a PS5Controller. */
public enum Button {
- kCross(1),
- kCircle(2),
- kSquare(3),
+ /** Square button. */
+ kSquare(1),
+ /** X button. */
+ kCross(2),
+ /** Circle button. */
+ kCircle(3),
+ /** Triangle button. */
kTriangle(4),
+ /** Left trigger 1 button. */
kL1(5),
+ /** Right trigger 1 button. */
kR1(6),
+ /** Left trigger 2 button. */
kL2(7),
+ /** Right trigger 2 button. */
kR2(8),
+ /** Create button. */
kCreate(9),
+ /** Options button. */
kOptions(10),
- kPS(11),
- kL3(12),
- kR3(13),
+ /** Left stick button. */
+ kL3(11),
+ /** Right stick button. */
+ kR3(12),
+ /** PlayStation button. */
+ kPS(13),
+ /** Touchpad click button. */
kTouchpad(14);
+ /** Button value. */
public final int value;
Button(int index) {
@@ -68,13 +87,20 @@
/** Represents an axis on a PS5Controller. */
public enum Axis {
+ /** Left X axis. */
kLeftX(0),
+ /** Left Y axis. */
kLeftY(1),
- kL2(2),
- kRightX(3),
- kRightY(4),
- kR2(5);
+ /** Right X axis. */
+ kRightX(2),
+ /** Right Y axis. */
+ kRightY(5),
+ /** Left Trigger 2. */
+ kL2(3),
+ /** Right Trigger 2. */
+ kR2(4);
+ /** Axis value. */
public final int value;
Axis(int index) {
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PWM.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PWM.java
index b0b3810..af600ec 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PWM.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PWM.java
@@ -54,6 +54,7 @@
* @param channel The PWM channel number. 0-9 are on-board, 10-19 are on the MXP port
* @param registerSendable If true, adds this instance to SendableRegistry and LiveWindow
*/
+ @SuppressWarnings("this-escape")
public PWM(final int channel, final boolean registerSendable) {
SensorUtil.checkPWMChannel(channel);
m_channel = channel;
@@ -200,7 +201,7 @@
}
/** Temporarily disables the PWM output. The next set call will re-enable the output. */
- public void setDisabled() {
+ public final void setDisabled() {
PWMJNI.setPWMDisabled(m_handle);
}
@@ -228,6 +229,7 @@
}
}
+ /** Latches PWM to zero. */
public void setZeroLatch() {
PWMJNI.latchPWMZero(m_handle);
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PneumaticHub.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PneumaticHub.java
index b7df47f..32d2ec5 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PneumaticHub.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PneumaticHub.java
@@ -59,8 +59,7 @@
output.write(("currentVersion=" + fwVersion).getBytes(StandardCharsets.UTF_8));
}
} catch (IOException ex) {
- DriverStation.reportError(
- "Could not write " + fileName + ": " + ex.toString(), ex.getStackTrace());
+ DriverStation.reportError("Could not write " + fileName + ": " + ex, ex.getStackTrace());
}
}
@@ -115,14 +114,12 @@
/** Converts volts to PSI per the REV Analog Pressure Sensor datasheet. */
private static double voltsToPsi(double sensorVoltage, double supplyVoltage) {
- double pressure = 250 * (sensorVoltage / supplyVoltage) - 25;
- return pressure;
+ return 250 * (sensorVoltage / supplyVoltage) - 25;
}
/** Converts PSI to volts per the REV Analog Pressure Sensor datasheet. */
private static double psiToVolts(double pressure, double supplyVoltage) {
- double voltage = supplyVoltage * (0.004 * pressure + 0.1);
- return voltage;
+ return supplyVoltage * (0.004 * pressure + 0.1);
}
private final DataStore m_dataStore;
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PneumaticsBase.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PneumaticsBase.java
index d9b493b..90f49f5 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PneumaticsBase.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PneumaticsBase.java
@@ -4,6 +4,7 @@
package edu.wpi.first.wpilibj;
+/** Interface for pneumatics devices. */
public interface PneumaticsBase extends AutoCloseable {
/**
* For internal use to get a module for a specific type.
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PneumaticsControlModule.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PneumaticsControlModule.java
index aac16a3..4f1d70c 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PneumaticsControlModule.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PneumaticsControlModule.java
@@ -186,10 +186,23 @@
return CTREPCMJNI.getSolenoidDisabledList(m_handle);
}
+ /**
+ * Returns whether the solenoid is currently reporting a voltage fault.
+ *
+ * @return True if solenoid is reporting a fault, otherwise false.
+ * @see #getSolenoidVoltageStickyFault()
+ */
public boolean getSolenoidVoltageFault() {
return CTREPCMJNI.getSolenoidVoltageFault(m_handle);
}
+ /**
+ * Returns whether the solenoid has reported a voltage fault since sticky faults were last
+ * cleared. This fault is persistent and can be cleared by ClearAllStickyFaults()
+ *
+ * @return True if solenoid is reporting a fault, otherwise false.
+ * @see #getSolenoidVoltageFault()
+ */
public boolean getSolenoidVoltageStickyFault() {
return CTREPCMJNI.getSolenoidVoltageStickyFault(m_handle);
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PneumaticsModuleType.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PneumaticsModuleType.java
index a7951e8..e1525c3 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PneumaticsModuleType.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PneumaticsModuleType.java
@@ -4,7 +4,10 @@
package edu.wpi.first.wpilibj;
+/** Pneumatics module type. */
public enum PneumaticsModuleType {
+ /** CTRE PCM. */
CTREPCM,
- REVPH;
+ /** REV PH. */
+ REVPH
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PowerDistribution.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PowerDistribution.java
index a0c2104..57709b7 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/PowerDistribution.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/PowerDistribution.java
@@ -22,12 +22,17 @@
private final int m_handle;
private final int m_module;
+ /** Default module number. */
public static final int kDefaultModule = PowerDistributionJNI.DEFAULT_MODULE;
+ /** Power distribution module type. */
public enum ModuleType {
+ /** CTRE (Cross The Road Electronics) CTRE Power Distribution Panel (PDP). */
kCTRE(PowerDistributionJNI.CTRE_TYPE),
+ /** REV Power Distribution Hub (PDH). */
kRev(PowerDistributionJNI.REV_TYPE);
+ /** ModuleType value. */
public final int value;
ModuleType(int value) {
@@ -41,6 +46,7 @@
* @param module The CAN ID of the PDP/PDH.
* @param moduleType Module type (CTRE or REV).
*/
+ @SuppressWarnings("this-escape")
public PowerDistribution(int module, ModuleType moduleType) {
m_handle = PowerDistributionJNI.initialize(module, moduleType.value);
m_module = PowerDistributionJNI.getModuleNumber(m_handle);
@@ -54,6 +60,7 @@
*
* <p>Detects the connected PDP/PDH using the default CAN ID (0 for CTRE and 1 for REV).
*/
+ @SuppressWarnings("this-escape")
public PowerDistribution() {
m_handle = PowerDistributionJNI.initialize(kDefaultModule, PowerDistributionJNI.AUTOMATIC_TYPE);
m_module = PowerDistributionJNI.getModuleNumber(m_handle);
@@ -101,9 +108,7 @@
* @return The current of the channel in Amperes
*/
public double getCurrent(int channel) {
- double current = PowerDistributionJNI.getChannelCurrent(m_handle, channel);
-
- return current;
+ return PowerDistributionJNI.getChannelCurrent(m_handle, channel);
}
/**
@@ -184,14 +189,29 @@
PowerDistributionJNI.setSwitchableChannel(m_handle, enabled);
}
+ /**
+ * Returns the power distribution version number.
+ *
+ * @return The power distribution version number.
+ */
public PowerDistributionVersion getVersion() {
return PowerDistributionJNI.getVersion(m_handle);
}
+ /**
+ * Returns the power distribution faults.
+ *
+ * @return The power distribution faults.
+ */
public PowerDistributionFaults getFaults() {
return PowerDistributionJNI.getFaults(m_handle);
}
+ /**
+ * Returns the power distribution sticky faults.
+ *
+ * @return The power distribution sticky faults.
+ */
public PowerDistributionStickyFaults getStickyFaults() {
return PowerDistributionJNI.getStickyFaults(m_handle);
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Preferences.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Preferences.java
index 087c156..69d0fb3 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Preferences.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Preferences.java
@@ -230,7 +230,7 @@
*/
public static void setLong(String key, long value) {
NetworkTableEntry entry = m_table.getEntry(key);
- entry.setDouble(value);
+ entry.setInteger(value);
entry.setPersistent();
}
@@ -242,7 +242,7 @@
*/
public static void initLong(String key, long value) {
NetworkTableEntry entry = m_table.getEntry(key);
- entry.setDefaultDouble(value);
+ entry.setDefaultInteger(value);
entry.setPersistent();
}
@@ -345,6 +345,6 @@
* @return either the value in the table, or the backup
*/
public static long getLong(String key, long backup) {
- return (long) m_table.getEntry(key).getDouble(backup);
+ return m_table.getEntry(key).getInteger(backup);
}
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Relay.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Relay.java
index a2a58d3..dce3096 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Relay.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Relay.java
@@ -44,9 +44,13 @@
/** The state to drive a Relay to. */
public enum Value {
+ /** Off. */
kOff("Off"),
+ /** On. */
kOn("On"),
+ /** Forward. */
kForward("Forward"),
+ /** Reverse. */
kReverse("Reverse");
private final String m_prettyValue;
@@ -55,10 +59,21 @@
m_prettyValue = prettyValue;
}
+ /**
+ * Returns the pretty string representation of the value.
+ *
+ * @return The pretty string representation of the value.
+ */
public String getPrettyValue() {
return m_prettyValue;
}
+ /**
+ * Returns the value for a given pretty string.
+ *
+ * @param value The pretty string.
+ * @return The value or an empty optional if there is no corresponding value.
+ */
public static Optional<Value> getValueOf(String value) {
return Arrays.stream(Value.values()).filter(v -> v.m_prettyValue.equals(value)).findFirst();
}
@@ -66,11 +81,11 @@
/** The Direction(s) that a relay is configured to operate in. */
public enum Direction {
- /** direction: both directions are valid. */
+ /** Both directions are valid. */
kBoth,
- /** direction: Only forward is valid. */
+ /** Only forward is valid. */
kForward,
- /** direction: only reverse is valid. */
+ /** Only reverse is valid. */
kReverse
}
@@ -110,6 +125,7 @@
* @param channel The channel number for this relay (0 - 3).
* @param direction The direction that the Relay object will control.
*/
+ @SuppressWarnings("this-escape")
public Relay(final int channel, Direction direction) {
m_channel = channel;
m_direction = requireNonNullParam(direction, "direction", "Relay");
@@ -279,6 +295,7 @@
*
* @param direction The direction for the relay to operate in
*/
+ @SuppressWarnings("this-escape")
public void setDirection(Direction direction) {
requireNonNullParam(direction, "direction", "setDirection");
if (m_direction == direction) {
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/RobotBase.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/RobotBase.java
index 2f59a3d..855b118 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/RobotBase.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/RobotBase.java
@@ -178,6 +178,11 @@
Shuffleboard.disableActuatorWidgets();
}
+ /**
+ * Returns the main thread ID.
+ *
+ * @return The main thread ID.
+ */
public static long getMainThreadId() {
return m_threadId;
}
@@ -321,8 +326,7 @@
robotName = elements[0].getClassName();
}
DriverStation.reportError(
- "Unhandled exception instantiating robot " + robotName + " " + throwable.toString(),
- elements);
+ "Unhandled exception instantiating robot " + robotName + " " + throwable, elements);
DriverStation.reportError(
"The robot program quit unexpectedly."
+ " This is usually due to a code error.\n"
@@ -353,8 +357,7 @@
output.write(WPILibVersion.Version.getBytes(StandardCharsets.UTF_8));
}
} catch (IOException ex) {
- DriverStation.reportError(
- "Could not write FRC_Lib_Version.ini: " + ex.toString(), ex.getStackTrace());
+ DriverStation.reportError("Could not write FRC_Lib_Version.ini: " + ex, ex.getStackTrace());
}
}
@@ -366,8 +369,7 @@
if (cause != null) {
throwable = cause;
}
- DriverStation.reportError(
- "Unhandled exception: " + throwable.toString(), throwable.getStackTrace());
+ DriverStation.reportError("Unhandled exception: " + throwable, throwable.getStackTrace());
errorOnExit = true;
} finally {
m_runMutex.lock();
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/RobotController.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/RobotController.java
index 29bcad8..d8faafa 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/RobotController.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/RobotController.java
@@ -6,6 +6,7 @@
import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.HALUtil;
+import edu.wpi.first.hal.LEDJNI;
import edu.wpi.first.hal.PowerJNI;
import edu.wpi.first.hal.can.CANJNI;
import edu.wpi.first.hal.can.CANStatus;
@@ -33,7 +34,7 @@
* @return FPGA Revision number.
*/
public static long getFPGARevision() {
- return (long) HALUtil.getFPGARevision();
+ return HALUtil.getFPGARevision();
}
/**
@@ -78,6 +79,10 @@
/**
* Get the state of the "USER" button on the roboRIO.
*
+ * <p>Warning: the User Button is used to stop user programs from automatically loading if it is
+ * held for more then 5 seconds. Because of this, it's not recommended to be used by teams for any
+ * other purpose.
+ *
* @return true if the button is currently pressed down
*/
public static boolean getUserButton() {
@@ -315,6 +320,66 @@
return PowerJNI.getCPUTemp();
}
+ /** State for the radio led. */
+ public enum RadioLEDState {
+ /** Off. */
+ kOff(LEDJNI.RADIO_LED_STATE_OFF),
+ /** Green. */
+ kGreen(LEDJNI.RADIO_LED_STATE_GREEN),
+ /** Red. */
+ kRed(LEDJNI.RADIO_LED_STATE_RED),
+ /** Orange. */
+ kOrange(LEDJNI.RADIO_LED_STATE_ORANGE);
+
+ /** The native value for this state. */
+ public final int value;
+
+ RadioLEDState(int value) {
+ this.value = value;
+ }
+
+ /**
+ * Gets a state from an int value.
+ *
+ * @param value int value
+ * @return state
+ */
+ public static RadioLEDState fromValue(int value) {
+ switch (value) {
+ case LEDJNI.RADIO_LED_STATE_OFF:
+ return RadioLEDState.kOff;
+ case LEDJNI.RADIO_LED_STATE_GREEN:
+ return RadioLEDState.kGreen;
+ case LEDJNI.RADIO_LED_STATE_RED:
+ return RadioLEDState.kRed;
+ case LEDJNI.RADIO_LED_STATE_ORANGE:
+ return RadioLEDState.kOrange;
+ default:
+ return RadioLEDState.kOff;
+ }
+ }
+ }
+
+ /**
+ * Set the state of the "Radio" LED. On the RoboRIO, this writes to sysfs, so this function should
+ * not be called multiple times per loop cycle to avoid overruns.
+ *
+ * @param state The state to set the LED to.
+ */
+ public static void setRadioLEDState(RadioLEDState state) {
+ LEDJNI.setRadioLEDState(state.value);
+ }
+
+ /**
+ * Get the state of the "Radio" LED. On the RoboRIO, this reads from sysfs, so this function
+ * should not be called multiple times per loop cycle to avoid overruns.
+ *
+ * @return The state of the LED.
+ */
+ public static RadioLEDState getRadioLEDState() {
+ return RadioLEDState.fromValue(LEDJNI.getRadioLEDState());
+ }
+
/**
* Get the current status of the CAN bus.
*
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/RobotState.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/RobotState.java
index 44198df..405dfc4 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/RobotState.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/RobotState.java
@@ -4,6 +4,7 @@
package edu.wpi.first.wpilibj;
+/** Robot state utility functions. */
public final class RobotState {
/**
* Returns true if the robot is disabled.
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/RuntimeType.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/RuntimeType.java
index e7af118..cad1c51 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/RuntimeType.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/RuntimeType.java
@@ -6,11 +6,16 @@
import edu.wpi.first.hal.HALUtil;
+/** Runtime type. */
public enum RuntimeType {
+ /** roboRIO 1.0. */
kRoboRIO(HALUtil.RUNTIME_ROBORIO),
+ /** roboRIO 2.0. */
kRoboRIO2(HALUtil.RUNTIME_ROBORIO2),
+ /** Simulation runtime. */
kSimulation(HALUtil.RUNTIME_SIMULATION);
+ /** RuntimeType value. */
public final int value;
RuntimeType(int value) {
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/SPI.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/SPI.java
index 632770c..1a3bb34 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/SPI.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/SPI.java
@@ -14,13 +14,20 @@
/** Represents an SPI bus port. */
public class SPI implements AutoCloseable {
+ /** SPI port. */
public enum Port {
+ /** Onboard SPI bus port CS0. */
kOnboardCS0(SPIJNI.ONBOARD_CS0_PORT),
+ /** Onboard SPI bus port CS1. */
kOnboardCS1(SPIJNI.ONBOARD_CS1_PORT),
+ /** Onboard SPI bus port CS2. */
kOnboardCS2(SPIJNI.ONBOARD_CS2_PORT),
+ /** Onboard SPI bus port CS3. */
kOnboardCS3(SPIJNI.ONBOARD_CS3_PORT),
+ /** MXP (roboRIO MXP) SPI bus port. */
kMXP(SPIJNI.MXP_PORT);
+ /** SPI port value. */
public final int value;
Port(int value) {
@@ -28,6 +35,7 @@
}
}
+ /** SPI mode. */
public enum Mode {
/** Clock idle low, data sampled on rising edge. */
kMode0(SPIJNI.SPI_MODE0),
@@ -38,6 +46,7 @@
/** Clock idle high, data sampled on rising edge. */
kMode3(SPIJNI.SPI_MODE3);
+ /** SPI mode value. */
public final int value;
Mode(int value) {
@@ -64,6 +73,11 @@
HAL.report(tResourceType.kResourceType_SPI, port.value + 1);
}
+ /**
+ * Returns the SPI port value.
+ *
+ * @return SPI port value.
+ */
public int getPort() {
return m_port;
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/SensorUtil.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/SensorUtil.java
index bcedd81..258fbc7 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/SensorUtil.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/SensorUtil.java
@@ -47,8 +47,10 @@
/** Number of PCM Modules. */
public static final int kCTREPCMModules = PortsJNI.getNumCTREPCMModules();
+ /** Number of power distribution channels per PH. */
public static final int kREVPHChannels = PortsJNI.getNumREVPHChannels();
+ /** Number of PH modules. */
public static final int kREVPHModules = PortsJNI.getNumREVPHModules();
/**
@@ -59,12 +61,12 @@
*/
public static void checkDigitalChannel(final int channel) {
if (!DIOJNI.checkDIOChannel(channel)) {
- StringBuilder buf = new StringBuilder();
- buf.append("Requested DIO channel is out of range. Minimum: 0, Maximum: ")
- .append(kDigitalChannels)
- .append(", Requested: ")
- .append(channel);
- throw new IllegalArgumentException(buf.toString());
+ String buf =
+ "Requested DIO channel is out of range. Minimum: 0, Maximum: "
+ + kDigitalChannels
+ + ", Requested: "
+ + channel;
+ throw new IllegalArgumentException(buf);
}
}
@@ -76,12 +78,12 @@
*/
public static void checkRelayChannel(final int channel) {
if (!RelayJNI.checkRelayChannel(channel)) {
- StringBuilder buf = new StringBuilder();
- buf.append("Requested relay channel is out of range. Minimum: 0, Maximum: ")
- .append(kRelayChannels)
- .append(", Requested: ")
- .append(channel);
- throw new IllegalArgumentException(buf.toString());
+ String buf =
+ "Requested relay channel is out of range. Minimum: 0, Maximum: "
+ + kRelayChannels
+ + ", Requested: "
+ + channel;
+ throw new IllegalArgumentException(buf);
}
}
@@ -93,12 +95,12 @@
*/
public static void checkPWMChannel(final int channel) {
if (!PWMJNI.checkPWMChannel(channel)) {
- StringBuilder buf = new StringBuilder();
- buf.append("Requested PWM channel is out of range. Minimum: 0, Maximum: ")
- .append(kPwmChannels)
- .append(", Requested: ")
- .append(channel);
- throw new IllegalArgumentException(buf.toString());
+ String buf =
+ "Requested PWM channel is out of range. Minimum: 0, Maximum: "
+ + kPwmChannels
+ + ", Requested: "
+ + channel;
+ throw new IllegalArgumentException(buf);
}
}
@@ -110,12 +112,12 @@
*/
public static void checkAnalogInputChannel(final int channel) {
if (!AnalogJNI.checkAnalogInputChannel(channel)) {
- StringBuilder buf = new StringBuilder();
- buf.append("Requested analog input channel is out of range. Minimum: 0, Maximum: ")
- .append(kAnalogInputChannels)
- .append(", Requested: ")
- .append(channel);
- throw new IllegalArgumentException(buf.toString());
+ String buf =
+ "Requested analog input channel is out of range. Minimum: 0, Maximum: "
+ + kAnalogInputChannels
+ + ", Requested: "
+ + channel;
+ throw new IllegalArgumentException(buf);
}
}
@@ -127,12 +129,12 @@
*/
public static void checkAnalogOutputChannel(final int channel) {
if (!AnalogJNI.checkAnalogOutputChannel(channel)) {
- StringBuilder buf = new StringBuilder();
- buf.append("Requested analog output channel is out of range. Minimum: 0, Maximum: ")
- .append(kAnalogOutputChannels)
- .append(", Requested: ")
- .append(channel);
- throw new IllegalArgumentException(buf.toString());
+ String buf =
+ "Requested analog output channel is out of range. Minimum: 0, Maximum: "
+ + kAnalogOutputChannels
+ + ", Requested: "
+ + channel;
+ throw new IllegalArgumentException(buf);
}
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/SerialPort.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/SerialPort.java
index 1a05c8a..d978d78 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/SerialPort.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/SerialPort.java
@@ -13,13 +13,20 @@
public class SerialPort implements AutoCloseable {
private int m_portHandle;
+ /** Serial port. */
public enum Port {
+ /** Onboard serial port on the roboRIO. */
kOnboard(0),
+ /** MXP (roboRIO MXP) serial port. */
kMXP(1),
+ /** USB serial port (same as KUSB1). */
kUSB(2),
+ /** USB serial port 1. */
kUSB1(2),
+ /** USB serial port 2. */
kUSB2(3);
+ /** Port value. */
public final int value;
Port(int value) {
@@ -29,12 +36,18 @@
/** Represents the parity to use for serial communications. */
public enum Parity {
+ /** No parity. */
kNone(0),
+ /** Odd parity. */
kOdd(1),
+ /** Even parity. */
kEven(2),
+ /** Parity bit always on. */
kMark(3),
+ /** Parity bit always off. */
kSpace(4);
+ /** Parity value. */
public final int value;
Parity(int value) {
@@ -44,10 +57,14 @@
/** Represents the number of stop bits to use for Serial Communication. */
public enum StopBits {
+ /** One stop bit. */
kOne(10),
+ /** One and a half stop bits. */
kOnePointFive(15),
+ /** Two stop bits. */
kTwo(20);
+ /** StopBits value. */
public final int value;
StopBits(int value) {
@@ -57,11 +74,16 @@
/** Represents what type of flow control to use for serial communication. */
public enum FlowControl {
+ /** No flow control. */
kNone(0),
+ /** XON/XOFF flow control. */
kXonXoff(1),
+ /** RTS/CTS flow control. */
kRtsCts(2),
+ /** DTS/DSR flow control. */
kDtsDsr(4);
+ /** FlowControl value. */
public final int value;
FlowControl(int value) {
@@ -71,9 +93,12 @@
/** Represents which type of buffer mode to use when writing to a serial port. */
public enum WriteBufferMode {
+ /** Flush the buffer on each access. */
kFlushOnAccess(1),
+ /** Flush the buffer when it is full. */
kFlushWhenFull(2);
+ /** WriteBufferMode value. */
public final int value;
WriteBufferMode(int value) {
@@ -186,7 +211,7 @@
}
/** Disable termination behavior. */
- public void disableTermination() {
+ public final void disableTermination() {
SerialPortJNI.serialDisableTermination(m_portHandle);
}
@@ -216,7 +241,7 @@
*/
public String readString(int count) {
byte[] out = read(count);
- return new String(out, 0, out.length, StandardCharsets.US_ASCII);
+ return new String(out, StandardCharsets.US_ASCII);
}
/**
@@ -268,7 +293,7 @@
*
* @param timeout The number of seconds to wait for I/O.
*/
- public void setTimeout(double timeout) {
+ public final void setTimeout(double timeout) {
SerialPortJNI.serialSetTimeout(m_portHandle, timeout);
}
@@ -283,7 +308,7 @@
*
* @param size The read buffer size.
*/
- public void setReadBufferSize(int size) {
+ public final void setReadBufferSize(int size) {
SerialPortJNI.serialSetReadBufferSize(m_portHandle, size);
}
@@ -309,7 +334,7 @@
*
* @param mode The write buffer mode.
*/
- public void setWriteBufferMode(WriteBufferMode mode) {
+ public final void setWriteBufferMode(WriteBufferMode mode) {
SerialPortJNI.serialSetWriteMode(m_portHandle, (byte) mode.value);
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Servo.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Servo.java
index 1f1c747..ebd2a8b 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Servo.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Servo.java
@@ -19,18 +19,19 @@
private static final double kMaxServoAngle = 180.0;
private static final double kMinServoAngle = 0.0;
- protected static final int kDefaultMaxServoPWM = 2400;
- protected static final int kDefaultMinServoPWM = 600;
+ private static final int kDefaultMaxServoPWM = 2400;
+ private static final int kDefaultMinServoPWM = 600;
/**
- * Constructor.<br>
+ * Constructor.
*
- * <p>By default {@value #kDefaultMaxServoPWM} ms is used as the maxPWM value<br>
- * By default {@value #kDefaultMinServoPWM} ms is used as the minPWM value<br>
+ * <p>By default, {@value #kDefaultMaxServoPWM} ms is used as the max PWM value and {@value
+ * #kDefaultMinServoPWM} ms is used as the minPWM value.
*
* @param channel The PWM channel to which the servo is attached. 0-9 are on-board, 10-19 are on
* the MXP port
*/
+ @SuppressWarnings("this-escape")
public Servo(final int channel) {
super(channel);
setBoundsMicroseconds(kDefaultMaxServoPWM, 0, 0, 0, kDefaultMinServoPWM);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Solenoid.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Solenoid.java
index be87444..9c516da 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Solenoid.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Solenoid.java
@@ -39,6 +39,7 @@
* @param moduleType The module type to use.
* @param channel The channel the solenoid is on.
*/
+ @SuppressWarnings("this-escape")
public Solenoid(final int module, final PneumaticsModuleType moduleType, final int channel) {
m_module = PneumaticsBase.getForType(module, moduleType);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/StadiaController.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/StadiaController.java
new file mode 100644
index 0000000..d092d8b
--- /dev/null
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/StadiaController.java
@@ -0,0 +1,737 @@
+// 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.wpilibj;
+
+// import edu.wpi.first.hal.FRCNetComm.tResourceType;
+// import edu.wpi.first.hal.HAL;
+import edu.wpi.first.wpilibj.event.BooleanEvent;
+import edu.wpi.first.wpilibj.event.EventLoop;
+
+/**
+ * Handle input from Stadia controllers connected to the Driver Station.
+ *
+ * <p>This class handles Stadia input that comes from the Driver Station. Each time a value is
+ * requested the most recent value is returned. There is a single class instance for each controller
+ * and the mapping of ports to hardware buttons depends on the code in the Driver Station.
+ */
+public class StadiaController extends GenericHID {
+ /** Represents a digital button on a StadiaController. */
+ public enum Button {
+ /** A button. */
+ kA(1),
+ /** B button. */
+ kB(2),
+ /** X Button. */
+ kX(3),
+ /** Y Button. */
+ kY(4),
+ /** Left bumper button. */
+ kLeftBumper(5),
+ /** Right bumper button. */
+ kRightBumper(6),
+ /** Left stick button. */
+ kLeftStick(7),
+ /** Right stick button. */
+ kRightStick(8),
+ /** Ellipses button. */
+ kEllipses(9),
+ /** Hamburger button. */
+ kHamburger(10),
+ /** Stadia button. */
+ kStadia(11),
+ /** Right trigger button. */
+ kRightTrigger(12),
+ /** Left trigger button. */
+ kLeftTrigger(13),
+ /** Google button. */
+ kGoogle(14),
+ /** Frame button. */
+ kFrame(15);
+
+ /** Button value. */
+ public final int value;
+
+ Button(int value) {
+ this.value = value;
+ }
+
+ /**
+ * Get the human-friendly name of the button, matching the relevant methods. This is done by
+ * stripping the leading `k`, and if not a Bumper button append `Button`.
+ *
+ * <p>Primarily used for automated unit tests.
+ *
+ * @return the human-friendly name of the button.
+ */
+ @Override
+ public String toString() {
+ var name = this.name().substring(1); // Remove leading `k`
+ if (name.endsWith("Bumper")) {
+ return name;
+ }
+ return name + "Button";
+ }
+ }
+
+ /** Represents an axis on a StadiaController. */
+ public enum Axis {
+ /** Left X axis. */
+ kLeftX(0),
+ /** Right X axis. */
+ kRightX(3),
+ /** Left Y axis. */
+ kLeftY(1),
+ /** Right Y axis. */
+ kRightY(4);
+
+ /** Axis value. */
+ public final int value;
+
+ Axis(int value) {
+ this.value = value;
+ }
+
+ /**
+ * Get the human-friendly name of the axis, matching the relevant methods. This is done by
+ * stripping the leading `k`, and if a trigger axis append `Axis`.
+ *
+ * <p>Primarily used for automated unit tests.
+ *
+ * @return the human-friendly name of the axis.
+ */
+ @Override
+ public String toString() {
+ var name = this.name().substring(1); // Remove leading `k`
+ if (name.endsWith("Trigger")) {
+ return name + "Axis";
+ }
+ return name;
+ }
+ }
+
+ /**
+ * Construct an instance of a controller.
+ *
+ * @param port The port index on the Driver Station that the controller is plugged into.
+ */
+ public StadiaController(final int port) {
+ super(port);
+ // re-enable when StadiaController is added to Usage Reporting
+ // HAL.report(tResourceType.kResourceType_Joystick, port + 1);
+ }
+
+ /**
+ * Get the X axis value of left side of the controller.
+ *
+ * @return The axis value.
+ */
+ public double getLeftX() {
+ return getRawAxis(Axis.kLeftX.value);
+ }
+
+ /**
+ * Get the X axis value of right side of the controller.
+ *
+ * @return The axis value.
+ */
+ public double getRightX() {
+ return getRawAxis(Axis.kRightX.value);
+ }
+
+ /**
+ * Get the Y axis value of left side of the controller.
+ *
+ * @return The axis value.
+ */
+ public double getLeftY() {
+ return getRawAxis(Axis.kLeftY.value);
+ }
+
+ /**
+ * Get the Y axis value of right side of the controller.
+ *
+ * @return The axis value.
+ */
+ public double getRightY() {
+ return getRawAxis(Axis.kRightY.value);
+ }
+
+ /**
+ * Read the value of the left bumper (LB) button on the controller.
+ *
+ * @return The state of the button.
+ */
+ public boolean getLeftBumper() {
+ return getRawButton(Button.kLeftBumper.value);
+ }
+
+ /**
+ * Read the value of the right bumper (RB) button on the controller.
+ *
+ * @return The state of the button.
+ */
+ public boolean getRightBumper() {
+ return getRawButton(Button.kRightBumper.value);
+ }
+
+ /**
+ * Whether the left bumper (LB) was pressed since the last check.
+ *
+ * @return Whether the button was pressed since the last check.
+ */
+ public boolean getLeftBumperPressed() {
+ return getRawButtonPressed(Button.kLeftBumper.value);
+ }
+
+ /**
+ * Whether the right bumper (RB) was pressed since the last check.
+ *
+ * @return Whether the button was pressed since the last check.
+ */
+ public boolean getRightBumperPressed() {
+ return getRawButtonPressed(Button.kRightBumper.value);
+ }
+
+ /**
+ * Whether the left bumper (LB) was released since the last check.
+ *
+ * @return Whether the button was released since the last check.
+ */
+ public boolean getLeftBumperReleased() {
+ return getRawButtonReleased(Button.kLeftBumper.value);
+ }
+
+ /**
+ * Whether the right bumper (RB) was released since the last check.
+ *
+ * @return Whether the button was released since the last check.
+ */
+ public boolean getRightBumperReleased() {
+ return getRawButtonReleased(Button.kRightBumper.value);
+ }
+
+ /**
+ * Constructs an event instance around the right bumper's digital signal.
+ *
+ * @param loop the event loop instance to attach the event to.
+ * @return an event instance representing the right bumper's digital signal attached to the given
+ * loop.
+ */
+ public BooleanEvent leftBumper(EventLoop loop) {
+ return new BooleanEvent(loop, this::getLeftBumper);
+ }
+
+ /**
+ * Constructs an event instance around the left bumper's digital signal.
+ *
+ * @param loop the event loop instance to attach the event to.
+ * @return an event instance representing the left bumper's digital signal attached to the given
+ * loop.
+ */
+ public BooleanEvent rightBumper(EventLoop loop) {
+ return new BooleanEvent(loop, this::getRightBumper);
+ }
+
+ /**
+ * Read the value of the left stick button (LSB) on the controller.
+ *
+ * @return The state of the button.
+ */
+ public boolean getLeftStickButton() {
+ return getRawButton(Button.kLeftStick.value);
+ }
+
+ /**
+ * Read the value of the right stick button (RSB) on the controller.
+ *
+ * @return The state of the button.
+ */
+ public boolean getRightStickButton() {
+ return getRawButton(Button.kRightStick.value);
+ }
+
+ /**
+ * Whether the left stick button (LSB) was pressed since the last check.
+ *
+ * @return Whether the button was pressed since the last check.
+ */
+ public boolean getLeftStickButtonPressed() {
+ return getRawButtonPressed(Button.kLeftStick.value);
+ }
+
+ /**
+ * Whether the right stick button (RSB) was pressed since the last check.
+ *
+ * @return Whether the button was pressed since the last check.
+ */
+ public boolean getRightStickButtonPressed() {
+ return getRawButtonPressed(Button.kRightStick.value);
+ }
+
+ /**
+ * Whether the left stick button (LSB) was released since the last check.
+ *
+ * @return Whether the button was released since the last check.
+ */
+ public boolean getLeftStickButtonReleased() {
+ return getRawButtonReleased(Button.kLeftStick.value);
+ }
+
+ /**
+ * Whether the right stick (RSB) button was released since the last check.
+ *
+ * @return Whether the button was released since the last check.
+ */
+ public boolean getRightStickButtonReleased() {
+ return getRawButtonReleased(Button.kRightStick.value);
+ }
+
+ /**
+ * Constructs an event instance around the left stick button's digital signal.
+ *
+ * @param loop the event loop instance to attach the event to.
+ * @return an event instance representing the left stick button's digital signal attached to the
+ * given loop.
+ */
+ public BooleanEvent leftStick(EventLoop loop) {
+ return new BooleanEvent(loop, this::getLeftStickButton);
+ }
+
+ /**
+ * Constructs an event instance around the right stick button's digital signal.
+ *
+ * @param loop the event loop instance to attach the event to.
+ * @return an event instance representing the right stick button's digital signal attached to the
+ * given loop.
+ */
+ public BooleanEvent rightStick(EventLoop loop) {
+ return new BooleanEvent(loop, this::getRightStickButton);
+ }
+
+ /**
+ * Read the value of the left trigger button (LTB) on the controller.
+ *
+ * @return The state of the button.
+ */
+ public boolean getLeftTriggerButton() {
+ return getRawButton(Button.kLeftTrigger.value);
+ }
+
+ /**
+ * Read the value of the right trigger button (RTB) on the controller.
+ *
+ * @return The state of the button.
+ */
+ public boolean getRightTriggerButton() {
+ return getRawButton(Button.kRightTrigger.value);
+ }
+
+ /**
+ * Whether the left trigger button (LTB) was pressed since the last check.
+ *
+ * @return Whether the button was pressed since the last check.
+ */
+ public boolean getLeftTriggerButtonPressed() {
+ return getRawButtonPressed(Button.kLeftTrigger.value);
+ }
+
+ /**
+ * Whether the right trigger button (RTB) was pressed since the last check.
+ *
+ * @return Whether the button was pressed since the last check.
+ */
+ public boolean getRightTriggerButtonPressed() {
+ return getRawButtonPressed(Button.kRightTrigger.value);
+ }
+
+ /**
+ * Whether the left trigger button (LTB) was released since the last check.
+ *
+ * @return Whether the button was released since the last check.
+ */
+ public boolean getLeftTriggerButtonReleased() {
+ return getRawButtonReleased(Button.kLeftTrigger.value);
+ }
+
+ /**
+ * Whether the right trigger (RTB) button was released since the last check.
+ *
+ * @return Whether the button was released since the last check.
+ */
+ public boolean getRightTriggerButtonReleased() {
+ return getRawButtonReleased(Button.kRightTrigger.value);
+ }
+
+ /**
+ * Constructs an event instance around the left trigger button's digital signal.
+ *
+ * @param loop the event loop instance to attach the event to.
+ * @return an event instance representing the left trigger button's digital signal attached to the
+ * given loop.
+ */
+ public BooleanEvent leftTrigger(EventLoop loop) {
+ return new BooleanEvent(loop, this::getLeftTriggerButton);
+ }
+
+ /**
+ * Constructs an event instance around the right trigger button's digital signal.
+ *
+ * @param loop the event loop instance to attach the event to.
+ * @return an event instance representing the right trigger button's digital signal attached to
+ * the given loop.
+ */
+ public BooleanEvent rightTrigger(EventLoop loop) {
+ return new BooleanEvent(loop, this::getRightTriggerButton);
+ }
+
+ /**
+ * Read the value of the A button on the controller.
+ *
+ * @return The state of the button.
+ */
+ public boolean getAButton() {
+ return getRawButton(Button.kA.value);
+ }
+
+ /**
+ * Whether the A button was pressed since the last check.
+ *
+ * @return Whether the button was pressed since the last check.
+ */
+ public boolean getAButtonPressed() {
+ return getRawButtonPressed(Button.kA.value);
+ }
+
+ /**
+ * Whether the A button was released since the last check.
+ *
+ * @return Whether the button was released since the last check.
+ */
+ public boolean getAButtonReleased() {
+ return getRawButtonReleased(Button.kA.value);
+ }
+
+ /**
+ * Constructs an event instance around the A button's digital signal.
+ *
+ * @param loop the event loop instance to attach the event to.
+ * @return an event instance representing the A button's digital signal attached to the given
+ * loop.
+ */
+ @SuppressWarnings("MethodName")
+ public BooleanEvent a(EventLoop loop) {
+ return new BooleanEvent(loop, this::getAButton);
+ }
+
+ /**
+ * Read the value of the B button on the controller.
+ *
+ * @return The state of the button.
+ */
+ public boolean getBButton() {
+ return getRawButton(Button.kB.value);
+ }
+
+ /**
+ * Whether the B button was pressed since the last check.
+ *
+ * @return Whether the button was pressed since the last check.
+ */
+ public boolean getBButtonPressed() {
+ return getRawButtonPressed(Button.kB.value);
+ }
+
+ /**
+ * Whether the B button was released since the last check.
+ *
+ * @return Whether the button was released since the last check.
+ */
+ public boolean getBButtonReleased() {
+ return getRawButtonReleased(Button.kB.value);
+ }
+
+ /**
+ * Constructs an event instance around the B button's digital signal.
+ *
+ * @param loop the event loop instance to attach the event to.
+ * @return an event instance representing the B button's digital signal attached to the given
+ * loop.
+ */
+ @SuppressWarnings("MethodName")
+ public BooleanEvent b(EventLoop loop) {
+ return new BooleanEvent(loop, this::getBButton);
+ }
+
+ /**
+ * Read the value of the X button on the controller.
+ *
+ * @return The state of the button.
+ */
+ public boolean getXButton() {
+ return getRawButton(Button.kX.value);
+ }
+
+ /**
+ * Whether the X button was pressed since the last check.
+ *
+ * @return Whether the button was pressed since the last check.
+ */
+ public boolean getXButtonPressed() {
+ return getRawButtonPressed(Button.kX.value);
+ }
+
+ /**
+ * Whether the X button was released since the last check.
+ *
+ * @return Whether the button was released since the last check.
+ */
+ public boolean getXButtonReleased() {
+ return getRawButtonReleased(Button.kX.value);
+ }
+
+ /**
+ * Constructs an event instance around the X button's digital signal.
+ *
+ * @param loop the event loop instance to attach the event to.
+ * @return an event instance representing the X button's digital signal attached to the given
+ * loop.
+ */
+ @SuppressWarnings("MethodName")
+ public BooleanEvent x(EventLoop loop) {
+ return new BooleanEvent(loop, this::getXButton);
+ }
+
+ /**
+ * Read the value of the Y button on the controller.
+ *
+ * @return The state of the button.
+ */
+ public boolean getYButton() {
+ return getRawButton(Button.kY.value);
+ }
+
+ /**
+ * Whether the Y button was pressed since the last check.
+ *
+ * @return Whether the button was pressed since the last check.
+ */
+ public boolean getYButtonPressed() {
+ return getRawButtonPressed(Button.kY.value);
+ }
+
+ /**
+ * Whether the Y button was released since the last check.
+ *
+ * @return Whether the button was released since the last check.
+ */
+ public boolean getYButtonReleased() {
+ return getRawButtonReleased(Button.kY.value);
+ }
+
+ /**
+ * Constructs an event instance around the Y button's digital signal.
+ *
+ * @param loop the event loop instance to attach the event to.
+ * @return an event instance representing the Y button's digital signal attached to the given
+ * loop.
+ */
+ @SuppressWarnings("MethodName")
+ public BooleanEvent y(EventLoop loop) {
+ return new BooleanEvent(loop, this::getYButton);
+ }
+
+ /**
+ * Read the value of the ellipses button on the controller.
+ *
+ * @return The state of the button.
+ */
+ public boolean getEllipsesButton() {
+ return getRawButton(Button.kEllipses.value);
+ }
+
+ /**
+ * Whether the ellipses button was pressed since the last check.
+ *
+ * @return Whether the button was pressed since the last check.
+ */
+ public boolean getEllipsesButtonPressed() {
+ return getRawButtonPressed(Button.kEllipses.value);
+ }
+
+ /**
+ * Whether the ellipses button was released since the last check.
+ *
+ * @return Whether the button was released since the last check.
+ */
+ public boolean getEllipsesButtonReleased() {
+ return getRawButtonReleased(Button.kEllipses.value);
+ }
+
+ /**
+ * Constructs an event instance around the ellipses button's digital signal.
+ *
+ * @param loop the event loop instance to attach the event to.
+ * @return an event instance representing the ellipses button's digital signal attached to the
+ * given loop.
+ */
+ public BooleanEvent ellipses(EventLoop loop) {
+ return new BooleanEvent(loop, this::getEllipsesButton);
+ }
+
+ /**
+ * Read the value of the hamburger button on the controller.
+ *
+ * @return The state of the button.
+ */
+ public boolean getHamburgerButton() {
+ return getRawButton(Button.kHamburger.value);
+ }
+
+ /**
+ * Whether the hamburger button was pressed since the last check.
+ *
+ * @return Whether the button was pressed since the last check.
+ */
+ public boolean getHamburgerButtonPressed() {
+ return getRawButtonPressed(Button.kHamburger.value);
+ }
+
+ /**
+ * Whether the hamburger button was released since the last check.
+ *
+ * @return Whether the button was released since the last check.
+ */
+ public boolean getHamburgerButtonReleased() {
+ return getRawButtonReleased(Button.kHamburger.value);
+ }
+
+ /**
+ * Constructs an event instance around the hamburger button's digital signal.
+ *
+ * @param loop the event loop instance to attach the event to.
+ * @return an event instance representing the hamburger button's digital signal attached to the
+ * given loop.
+ */
+ public BooleanEvent hamburger(EventLoop loop) {
+ return new BooleanEvent(loop, this::getHamburgerButton);
+ }
+
+ /**
+ * Read the value of the stadia button on the controller.
+ *
+ * @return The state of the button.
+ */
+ public boolean getStadiaButton() {
+ return getRawButton(Button.kStadia.value);
+ }
+
+ /**
+ * Whether the stadia button was pressed since the last check.
+ *
+ * @return Whether the button was pressed since the last check.
+ */
+ public boolean getStadiaButtonPressed() {
+ return getRawButtonPressed(Button.kStadia.value);
+ }
+
+ /**
+ * Whether the stadia button was released since the last check.
+ *
+ * @return Whether the button was released since the last check.
+ */
+ public boolean getStadiaButtonReleased() {
+ return getRawButtonReleased(Button.kStadia.value);
+ }
+
+ /**
+ * Constructs an event instance around the stadia button's digital signal.
+ *
+ * @param loop the event loop instance to attach the event to.
+ * @return an event instance representing the stadia button's digital signal attached to the given
+ * loop.
+ */
+ @SuppressWarnings("MethodName")
+ public BooleanEvent stadia(EventLoop loop) {
+ return new BooleanEvent(loop, this::getStadiaButton);
+ }
+
+ /**
+ * Read the value of the google button on the controller.
+ *
+ * @return The state of the button.
+ */
+ public boolean getGoogleButton() {
+ return getRawButton(Button.kGoogle.value);
+ }
+
+ /**
+ * Whether the google button was pressed since the last check.
+ *
+ * @return Whether the button was pressed since the last check.
+ */
+ public boolean getGoogleButtonPressed() {
+ return getRawButtonPressed(Button.kGoogle.value);
+ }
+
+ /**
+ * Whether the google button was released since the last check.
+ *
+ * @return Whether the button was released since the last check.
+ */
+ public boolean getGoogleButtonReleased() {
+ return getRawButtonReleased(Button.kGoogle.value);
+ }
+
+ /**
+ * Constructs an event instance around the google button's digital signal.
+ *
+ * @param loop the event loop instance to attach the event to.
+ * @return an event instance representing the google button's digital signal attached to the given
+ * loop.
+ */
+ @SuppressWarnings("MethodName")
+ public BooleanEvent google(EventLoop loop) {
+ return new BooleanEvent(loop, this::getGoogleButton);
+ }
+
+ /**
+ * Read the value of the frame button on the controller.
+ *
+ * @return The state of the button.
+ */
+ public boolean getFrameButton() {
+ return getRawButton(Button.kFrame.value);
+ }
+
+ /**
+ * Whether the frame button was pressed since the last check.
+ *
+ * @return Whether the button was pressed since the last check.
+ */
+ public boolean getFrameButtonPressed() {
+ return getRawButtonPressed(Button.kFrame.value);
+ }
+
+ /**
+ * Whether the frame button was released since the last check.
+ *
+ * @return Whether the button was released since the last check.
+ */
+ public boolean getFrameButtonReleased() {
+ return getRawButtonReleased(Button.kFrame.value);
+ }
+
+ /**
+ * Constructs an event instance around the frame button's digital signal.
+ *
+ * @param loop the event loop instance to attach the event to.
+ * @return an event instance representing the frame button's digital signal attached to the given
+ * loop.
+ */
+ @SuppressWarnings("MethodName")
+ public BooleanEvent frame(EventLoop loop) {
+ return new BooleanEvent(loop, this::getFrameButton);
+ }
+}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/SynchronousInterrupt.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/SynchronousInterrupt.java
index 705d6b1..8f78865 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/SynchronousInterrupt.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/SynchronousInterrupt.java
@@ -23,11 +23,16 @@
/** Event trigger combinations for a synchronous interrupt. */
public enum WaitResult {
+ /** Timeout event. */
kTimeout(0x0),
+ /** Rising edge event. */
kRisingEdge(0x1),
+ /** Falling edge event. */
kFallingEdge(0x100),
+ /** Both rising and falling edge events. */
kBoth(0x101);
+ /** WaitResult value. */
public final int value;
WaitResult(int value) {
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Threads.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Threads.java
index 8b0d167..5ff0540 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Threads.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Threads.java
@@ -6,6 +6,7 @@
import edu.wpi.first.hal.ThreadsJNI;
+/** Thread utility functions. */
public final class Threads {
/**
* Get the thread priority for the current thread.
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/TimedRobot.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/TimedRobot.java
index 5a53b14..12346c4 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/TimedRobot.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/TimedRobot.java
@@ -65,6 +65,7 @@
}
}
+ /** Default loop period. */
public static final double kDefaultPeriod = 0.02;
// The C pointer to the notifier object. We don't use it directly, it is
@@ -159,7 +160,7 @@
* @param callback The callback to run.
* @param periodSeconds The period at which to run the callback in seconds.
*/
- public void addPeriodic(Runnable callback, double periodSeconds) {
+ public final void addPeriodic(Runnable callback, double periodSeconds) {
m_callbacks.add(new Callback(callback, m_startTime, periodSeconds, 0.0));
}
@@ -174,7 +175,7 @@
* @param offsetSeconds The offset from the common starting time in seconds. This is useful for
* scheduling a callback in a different timeslot relative to TimedRobot.
*/
- public void addPeriodic(Runnable callback, double periodSeconds, double offsetSeconds) {
+ public final void addPeriodic(Runnable callback, double periodSeconds, double offsetSeconds) {
m_callbacks.add(new Callback(callback, m_startTime, periodSeconds, offsetSeconds));
}
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Timer.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Timer.java
index 4f948f5..63e5ed4 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Timer.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Timer.java
@@ -83,7 +83,7 @@
*
* <p>Make the timer startTime the current time so new requests will be relative now.
*/
- public void reset() {
+ public final void reset() {
m_accumulatedTime = 0;
m_startTime = getMsClock();
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Tracer.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Tracer.java
index 2415079..15ca7ff 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Tracer.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Tracer.java
@@ -36,7 +36,7 @@
}
/** Restarts the epoch timer. */
- public void resetTimer() {
+ public final void resetTimer() {
m_startTime = RobotController.getFPGATime();
}
@@ -75,9 +75,7 @@
StringBuilder sb = new StringBuilder();
m_lastEpochsPrintTime = now;
m_epochs.forEach(
- (key, value) -> {
- sb.append(String.format("\t%s: %.6fs\n", key, value / 1.0e6));
- });
+ (key, value) -> sb.append(String.format("\t%s: %.6fs\n", key, value / 1.0e6)));
if (sb.length() > 0) {
output.accept(sb.toString());
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Ultrasonic.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Ultrasonic.java
index fd2b05b..a7b5e71 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Ultrasonic.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Ultrasonic.java
@@ -108,6 +108,11 @@
SendableRegistry.addLW(this, "Ultrasonic", m_echoChannel.getChannel());
}
+ /**
+ * Returns the echo channel.
+ *
+ * @return The echo channel.
+ */
public int getEchoChannel() {
return m_echoChannel.getChannel();
}
@@ -121,6 +126,7 @@
* @param echoChannel The digital input channel that receives the echo. The length of time that
* the echo is high represents the round trip time of the ping, and the distance.
*/
+ @SuppressWarnings("this-escape")
public Ultrasonic(final int pingChannel, final int echoChannel) {
m_pingChannel = new DigitalOutput(pingChannel);
m_echoChannel = new DigitalInput(echoChannel);
@@ -138,6 +144,7 @@
* 10uS pulse to start.
* @param echoChannel The digital input object that times the return pulse to determine the range.
*/
+ @SuppressWarnings("this-escape")
public Ultrasonic(DigitalOutput pingChannel, DigitalInput echoChannel) {
requireNonNullParam(pingChannel, "pingChannel", "Ultrasonic");
requireNonNullParam(echoChannel, "echoChannel", "Ultrasonic");
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Watchdog.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Watchdog.java
index f7bf85b..18d4b64 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/Watchdog.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/Watchdog.java
@@ -209,7 +209,7 @@
}
private static void updateAlarm() {
- if (m_watchdogs.size() == 0) {
+ if (m_watchdogs.isEmpty()) {
NotifierJNI.cancelNotifierAlarm(m_notifier);
} else {
NotifierJNI.updateNotifierAlarm(
@@ -233,7 +233,7 @@
m_queueMutex.lock();
try {
- if (m_watchdogs.size() == 0) {
+ if (m_watchdogs.isEmpty()) {
continue;
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/XboxController.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/XboxController.java
index c346ae3..5bd7a01 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/XboxController.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/XboxController.java
@@ -15,21 +15,36 @@
* <p>This class handles Xbox input that comes from the Driver Station. Each time a value is
* requested the most recent value is returned. There is a single class instance for each controller
* and the mapping of ports to hardware buttons depends on the code in the Driver Station.
+ *
+ * <p>Only first party controllers from Microsoft are guaranteed to have the correct mapping, and
+ * only through the official NI DS. Sim is not guaranteed to have the same mapping, as well as any
+ * 3rd party controllers.
*/
public class XboxController extends GenericHID {
/** Represents a digital button on an XboxController. */
public enum Button {
+ /** Left bumper. */
kLeftBumper(5),
+ /** Right bumper. */
kRightBumper(6),
+ /** Left stick. */
kLeftStick(9),
+ /** Right stick. */
kRightStick(10),
+ /** A. */
kA(1),
+ /** B. */
kB(2),
+ /** X. */
kX(3),
+ /** Y. */
kY(4),
+ /** Back. */
kBack(7),
+ /** Start. */
kStart(8);
+ /** Button value. */
public final int value;
Button(int value) {
@@ -56,13 +71,20 @@
/** Represents an axis on an XboxController. */
public enum Axis {
+ /** Left X. */
kLeftX(0),
+ /** Right X. */
kRightX(4),
+ /** Left Y. */
kLeftY(1),
+ /** Right Y. */
kRightY(5),
+ /** Left trigger. */
kLeftTrigger(2),
+ /** Right trigger. */
kRightTrigger(3);
+ /** Axis value. */
public final int value;
Axis(int value) {
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/counter/EdgeConfiguration.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/counter/EdgeConfiguration.java
index 9d58fbf..c969249 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/counter/EdgeConfiguration.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/counter/EdgeConfiguration.java
@@ -4,15 +4,22 @@
package edu.wpi.first.wpilibj.counter;
+/** Edge configuration. */
public enum EdgeConfiguration {
+ /** No edge configuration (neither rising nor falling). */
kNone(false, false),
+ /** Rising edge configuration. */
kRisingEdge(true, false),
+ /** Falling edge configuration. */
kFallingEdge(false, true),
+ /** Both rising and falling edge configuration. */
kBoth(true, true);
+ /** True if triggering on rising edge. */
@SuppressWarnings("MemberName")
public final boolean rising;
+ /** True if triggering on falling edge. */
@SuppressWarnings("MemberName")
public final boolean falling;
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/counter/ExternalDirectionCounter.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/counter/ExternalDirectionCounter.java
index 6828b9a..97fbf5b 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/counter/ExternalDirectionCounter.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/counter/ExternalDirectionCounter.java
@@ -34,6 +34,7 @@
* @param countSource The source for counting.
* @param directionSource The source for selecting count direction.
*/
+ @SuppressWarnings("this-escape")
public ExternalDirectionCounter(DigitalSource countSource, DigitalSource directionSource) {
m_countSource = requireNonNullParam(countSource, "countSource", "ExternalDirectionCounter");
m_directionSource =
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/counter/Tachometer.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/counter/Tachometer.java
index 5bd8e7e..6bef24d 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/counter/Tachometer.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/counter/Tachometer.java
@@ -34,6 +34,7 @@
*
* @param source The DigitalSource (e.g. DigitalInput) of the Tachometer.
*/
+ @SuppressWarnings("this-escape")
public Tachometer(DigitalSource source) {
m_source = requireNonNullParam(source, "source", "Tachometer");
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/counter/UpDownCounter.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/counter/UpDownCounter.java
index c89c118..ed9f35e 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/counter/UpDownCounter.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/counter/UpDownCounter.java
@@ -32,6 +32,7 @@
* @param upSource The up count source (can be null).
* @param downSource The down count source (can be null).
*/
+ @SuppressWarnings("this-escape")
public UpDownCounter(DigitalSource upSource, DigitalSource downSource) {
ByteBuffer index = ByteBuffer.allocateDirect(4);
// set the byte order
@@ -92,7 +93,7 @@
}
/** Resets the current count. */
- public void reset() {
+ public final void reset() {
CounterJNI.resetCounter(m_handle);
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/drive/DifferentialDrive.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/drive/DifferentialDrive.java
index 9a1f2ba..2199aa8 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/drive/DifferentialDrive.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/drive/DifferentialDrive.java
@@ -14,49 +14,16 @@
import edu.wpi.first.util.sendable.SendableBuilder;
import edu.wpi.first.util.sendable.SendableRegistry;
import edu.wpi.first.wpilibj.motorcontrol.MotorController;
+import java.util.function.DoubleConsumer;
/**
* A class for driving differential drive/skid-steer drive platforms such as the Kit of Parts drive
* base, "tank drive", or West Coast Drive.
*
* <p>These drive bases typically have drop-center / skid-steer with two or more wheels per side
- * (e.g., 6WD or 8WD). This class takes a MotorController per side. For four and six motor
- * drivetrains, construct and pass in {@link
- * edu.wpi.first.wpilibj.motorcontrol.MotorControllerGroup} instances as follows.
- *
- * <p>Four motor drivetrain:
- *
- * <pre><code>
- * public class Robot {
- * MotorController m_frontLeft = new PWMVictorSPX(1);
- * MotorController m_rearLeft = new PWMVictorSPX(2);
- * MotorControllerGroup m_left = new MotorControllerGroup(m_frontLeft, m_rearLeft);
- *
- * MotorController m_frontRight = new PWMVictorSPX(3);
- * MotorController m_rearRight = new PWMVictorSPX(4);
- * MotorControllerGroup m_right = new MotorControllerGroup(m_frontRight, m_rearRight);
- *
- * DifferentialDrive m_drive = new DifferentialDrive(m_left, m_right);
- * }
- * </code></pre>
- *
- * <p>Six motor drivetrain:
- *
- * <pre><code>
- * public class Robot {
- * MotorController m_frontLeft = new PWMVictorSPX(1);
- * MotorController m_midLeft = new PWMVictorSPX(2);
- * MotorController m_rearLeft = new PWMVictorSPX(3);
- * MotorControllerGroup m_left = new MotorControllerGroup(m_frontLeft, m_midLeft, m_rearLeft);
- *
- * MotorController m_frontRight = new PWMVictorSPX(4);
- * MotorController m_midRight = new PWMVictorSPX(5);
- * MotorController m_rearRight = new PWMVictorSPX(6);
- * MotorControllerGroup m_right = new MotorControllerGroup(m_frontRight, m_midRight, m_rearRight);
- *
- * DifferentialDrive m_drive = new DifferentialDrive(m_left, m_right);
- * }
- * </code></pre>
+ * (e.g., 6WD or 8WD). This class takes a setter per side. For four and six motor drivetrains, use
+ * CAN motor controller followers or {@link
+ * edu.wpi.first.wpilibj.motorcontrol.PWMMotorController#addFollower(PWMMotorController)}.
*
* <p>A differential drive robot has left and right wheels separated by an arbitrary width.
*
@@ -88,8 +55,12 @@
public class DifferentialDrive extends RobotDriveBase implements Sendable, AutoCloseable {
private static int instances;
- private final MotorController m_leftMotor;
- private final MotorController m_rightMotor;
+ private final DoubleConsumer m_leftMotor;
+ private final DoubleConsumer m_rightMotor;
+
+ // Used for Sendable property getters
+ private double m_leftOutput;
+ private double m_rightOutput;
private boolean m_reported;
@@ -100,7 +71,10 @@
*/
@SuppressWarnings("MemberName")
public static class WheelSpeeds {
+ /** Left wheel speed. */
public double left;
+
+ /** Right wheel speed. */
public double right;
/** Constructs a WheelSpeeds with zeroes for left and right speeds. */
@@ -128,14 +102,30 @@
* @param leftMotor Left motor.
* @param rightMotor Right motor.
*/
+ @SuppressWarnings({"removal", "this-escape"})
public DifferentialDrive(MotorController leftMotor, MotorController rightMotor) {
+ this((double output) -> leftMotor.set(output), (double output) -> rightMotor.set(output));
+ SendableRegistry.addChild(this, leftMotor);
+ SendableRegistry.addChild(this, rightMotor);
+ }
+
+ /**
+ * Construct a DifferentialDrive.
+ *
+ * <p>To pass multiple motors per side, use CAN motor controller followers or {@link
+ * edu.wpi.first.wpilibj.motorcontrol.PWMMotorController#addFollower(PWMMotorController)}. If a
+ * motor needs to be inverted, do so before passing it in.
+ *
+ * @param leftMotor Left motor setter.
+ * @param rightMotor Right motor setter.
+ */
+ @SuppressWarnings("this-escape")
+ public DifferentialDrive(DoubleConsumer leftMotor, DoubleConsumer rightMotor) {
requireNonNullParam(leftMotor, "leftMotor", "DifferentialDrive");
requireNonNullParam(rightMotor, "rightMotor", "DifferentialDrive");
m_leftMotor = leftMotor;
m_rightMotor = rightMotor;
- SendableRegistry.addChild(this, m_leftMotor);
- SendableRegistry.addChild(this, m_rightMotor);
instances++;
SendableRegistry.addLW(this, "DifferentialDrive", instances);
}
@@ -177,8 +167,11 @@
var speeds = arcadeDriveIK(xSpeed, zRotation, squareInputs);
- m_leftMotor.set(speeds.left * m_maxOutput);
- m_rightMotor.set(speeds.right * m_maxOutput);
+ m_leftOutput = speeds.left * m_maxOutput;
+ m_rightOutput = speeds.right * m_maxOutput;
+
+ m_leftMotor.accept(m_leftOutput);
+ m_rightMotor.accept(m_rightOutput);
feed();
}
@@ -206,8 +199,11 @@
var speeds = curvatureDriveIK(xSpeed, zRotation, allowTurnInPlace);
- m_leftMotor.set(speeds.left * m_maxOutput);
- m_rightMotor.set(speeds.right * m_maxOutput);
+ m_leftOutput = speeds.left * m_maxOutput;
+ m_rightOutput = speeds.right * m_maxOutput;
+
+ m_leftMotor.accept(m_leftOutput);
+ m_rightMotor.accept(m_rightOutput);
feed();
}
@@ -244,8 +240,11 @@
var speeds = tankDriveIK(leftSpeed, rightSpeed, squareInputs);
- m_leftMotor.set(speeds.left * m_maxOutput);
- m_rightMotor.set(speeds.right * m_maxOutput);
+ m_leftOutput = speeds.left * m_maxOutput;
+ m_rightOutput = speeds.right * m_maxOutput;
+
+ m_leftMotor.accept(m_leftOutput);
+ m_rightMotor.accept(m_rightOutput);
feed();
}
@@ -350,8 +349,12 @@
@Override
public void stopMotor() {
- m_leftMotor.stopMotor();
- m_rightMotor.stopMotor();
+ m_leftOutput = 0.0;
+ m_rightOutput = 0.0;
+
+ m_leftMotor.accept(0.0);
+ m_rightMotor.accept(0.0);
+
feed();
}
@@ -365,7 +368,7 @@
builder.setSmartDashboardType("DifferentialDrive");
builder.setActuator(true);
builder.setSafeState(this::stopMotor);
- builder.addDoubleProperty("Left Motor Speed", m_leftMotor::get, m_leftMotor::set);
- builder.addDoubleProperty("Right Motor Speed", m_rightMotor::get, m_rightMotor::set);
+ builder.addDoubleProperty("Left Motor Speed", () -> m_leftOutput, m_leftMotor::accept);
+ builder.addDoubleProperty("Right Motor Speed", () -> m_rightOutput, m_rightMotor::accept);
}
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/drive/MecanumDrive.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/drive/MecanumDrive.java
index 181e275..236a4fb 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/drive/MecanumDrive.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/drive/MecanumDrive.java
@@ -16,6 +16,7 @@
import edu.wpi.first.util.sendable.SendableBuilder;
import edu.wpi.first.util.sendable.SendableRegistry;
import edu.wpi.first.wpilibj.motorcontrol.MotorController;
+import java.util.function.DoubleConsumer;
/**
* A class for driving Mecanum drive platforms.
@@ -56,10 +57,16 @@
public class MecanumDrive extends RobotDriveBase implements Sendable, AutoCloseable {
private static int instances;
- private final MotorController m_frontLeftMotor;
- private final MotorController m_rearLeftMotor;
- private final MotorController m_frontRightMotor;
- private final MotorController m_rearRightMotor;
+ private final DoubleConsumer m_frontLeftMotor;
+ private final DoubleConsumer m_rearLeftMotor;
+ private final DoubleConsumer m_frontRightMotor;
+ private final DoubleConsumer m_rearRightMotor;
+
+ // Used for Sendable property getters
+ private double m_frontLeftOutput;
+ private double m_rearLeftOutput;
+ private double m_frontRightOutput;
+ private double m_rearRightOutput;
private boolean m_reported;
@@ -70,9 +77,16 @@
*/
@SuppressWarnings("MemberName")
public static class WheelSpeeds {
+ /** Front-left wheel speed. */
public double frontLeft;
+
+ /** Front-right wheel speed. */
public double frontRight;
+
+ /** Rear-left wheel speed. */
public double rearLeft;
+
+ /** Rear-right wheel speed. */
public double rearRight;
/** Constructs a WheelSpeeds with zeroes for all four speeds. */
@@ -104,11 +118,39 @@
* @param frontRightMotor The motor on the front-right corner.
* @param rearRightMotor The motor on the rear-right corner.
*/
+ @SuppressWarnings({"removal", "this-escape"})
public MecanumDrive(
MotorController frontLeftMotor,
MotorController rearLeftMotor,
MotorController frontRightMotor,
MotorController rearRightMotor) {
+ this(
+ (double output) -> frontLeftMotor.set(output),
+ (double output) -> rearLeftMotor.set(output),
+ (double output) -> frontRightMotor.set(output),
+ (double output) -> rearRightMotor.set(output));
+ SendableRegistry.addChild(this, frontLeftMotor);
+ SendableRegistry.addChild(this, rearLeftMotor);
+ SendableRegistry.addChild(this, frontRightMotor);
+ SendableRegistry.addChild(this, rearRightMotor);
+ }
+
+ /**
+ * Construct a MecanumDrive.
+ *
+ * <p>If a motor needs to be inverted, do so before passing it in.
+ *
+ * @param frontLeftMotor The setter for the motor on the front-left corner.
+ * @param rearLeftMotor The setter for the motor on the rear-left corner.
+ * @param frontRightMotor The setter for the motor on the front-right corner.
+ * @param rearRightMotor The setter for the motor on the rear-right corner.
+ */
+ @SuppressWarnings("this-escape")
+ public MecanumDrive(
+ DoubleConsumer frontLeftMotor,
+ DoubleConsumer rearLeftMotor,
+ DoubleConsumer frontRightMotor,
+ DoubleConsumer rearRightMotor) {
requireNonNullParam(frontLeftMotor, "frontLeftMotor", "MecanumDrive");
requireNonNullParam(rearLeftMotor, "rearLeftMotor", "MecanumDrive");
requireNonNullParam(frontRightMotor, "frontRightMotor", "MecanumDrive");
@@ -118,10 +160,6 @@
m_rearLeftMotor = rearLeftMotor;
m_frontRightMotor = frontRightMotor;
m_rearRightMotor = rearRightMotor;
- SendableRegistry.addChild(this, m_frontLeftMotor);
- SendableRegistry.addChild(this, m_rearLeftMotor);
- SendableRegistry.addChild(this, m_frontRightMotor);
- SendableRegistry.addChild(this, m_rearRightMotor);
instances++;
SendableRegistry.addLW(this, "MecanumDrive", instances);
}
@@ -171,10 +209,15 @@
var speeds = driveCartesianIK(xSpeed, ySpeed, zRotation, gyroAngle);
- m_frontLeftMotor.set(speeds.frontLeft * m_maxOutput);
- m_frontRightMotor.set(speeds.frontRight * m_maxOutput);
- m_rearLeftMotor.set(speeds.rearLeft * m_maxOutput);
- m_rearRightMotor.set(speeds.rearRight * m_maxOutput);
+ m_frontLeftOutput = speeds.frontLeft * m_maxOutput;
+ m_rearLeftOutput = speeds.rearLeft * m_maxOutput;
+ m_frontRightOutput = speeds.frontRight * m_maxOutput;
+ m_rearRightOutput = speeds.rearRight * m_maxOutput;
+
+ m_frontLeftMotor.accept(m_frontLeftOutput);
+ m_frontRightMotor.accept(m_frontRightOutput);
+ m_rearLeftMotor.accept(m_rearLeftOutput);
+ m_rearRightMotor.accept(m_rearRightOutput);
feed();
}
@@ -255,10 +298,16 @@
@Override
public void stopMotor() {
- m_frontLeftMotor.stopMotor();
- m_frontRightMotor.stopMotor();
- m_rearLeftMotor.stopMotor();
- m_rearRightMotor.stopMotor();
+ m_frontLeftOutput = 0.0;
+ m_frontRightOutput = 0.0;
+ m_rearLeftOutput = 0.0;
+ m_rearRightOutput = 0.0;
+
+ m_frontLeftMotor.accept(0.0);
+ m_frontRightMotor.accept(0.0);
+ m_rearLeftMotor.accept(0.0);
+ m_rearRightMotor.accept(0.0);
+
feed();
}
@@ -273,11 +322,12 @@
builder.setActuator(true);
builder.setSafeState(this::stopMotor);
builder.addDoubleProperty(
- "Front Left Motor Speed", m_frontLeftMotor::get, m_frontLeftMotor::set);
+ "Front Left Motor Speed", () -> m_frontLeftOutput, m_frontLeftMotor::accept);
builder.addDoubleProperty(
- "Front Right Motor Speed", m_frontRightMotor::get, m_frontRightMotor::set);
- builder.addDoubleProperty("Rear Left Motor Speed", m_rearLeftMotor::get, m_rearLeftMotor::set);
+ "Front Right Motor Speed", () -> m_frontRightOutput, m_frontRightMotor::accept);
builder.addDoubleProperty(
- "Rear Right Motor Speed", m_rearRightMotor::get, m_rearRightMotor::set);
+ "Rear Left Motor Speed", () -> m_rearLeftOutput, m_rearLeftMotor::accept);
+ builder.addDoubleProperty(
+ "Rear Right Motor Speed", () -> m_rearRightOutput, m_rearRightMotor::accept);
}
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/drive/RobotDriveBase.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/drive/RobotDriveBase.java
index c4e931d..a952b2e 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/drive/RobotDriveBase.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/drive/RobotDriveBase.java
@@ -12,22 +12,36 @@
* <p>{@link edu.wpi.first.wpilibj.MotorSafety} is enabled by default.
*/
public abstract class RobotDriveBase extends MotorSafety {
+ /** Default input deadband. */
public static final double kDefaultDeadband = 0.02;
+
+ /** Default maximum output. */
public static final double kDefaultMaxOutput = 1.0;
+ /** Input deadband. */
protected double m_deadband = kDefaultDeadband;
+
+ /** Maximum output. */
protected double m_maxOutput = kDefaultMaxOutput;
/** The location of a motor on the robot for the purpose of driving. */
public enum MotorType {
+ /** Front left motor. */
kFrontLeft(0),
+ /** Front right motor. */
kFrontRight(1),
+ /** Rear left motor. */
kRearLeft(2),
+ /** Reat right motor. */
kRearRight(3),
+ /** Left motor. */
kLeft(0),
+ /** Right motor. */
kRight(1),
+ /** Back motor. */
kBack(2);
+ /** MotorType value. */
public final int value;
MotorType(int value) {
@@ -36,6 +50,7 @@
}
/** RobotDriveBase constructor. */
+ @SuppressWarnings("this-escape")
public RobotDriveBase() {
setSafetyEnabled(true);
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/event/EventLoop.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/event/EventLoop.java
index 3e220e0..38d21cd 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/event/EventLoop.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/event/EventLoop.java
@@ -5,6 +5,7 @@
package edu.wpi.first.wpilibj.event;
import java.util.Collection;
+import java.util.ConcurrentModificationException;
import java.util.LinkedHashSet;
/**
@@ -12,6 +13,10 @@
*/
public final class EventLoop {
private final Collection<Runnable> m_bindings = new LinkedHashSet<>();
+ private boolean m_running;
+
+ /** Default constructor. */
+ public EventLoop() {}
/**
* Bind a new action to run when the loop is polled.
@@ -19,16 +24,27 @@
* @param action the action to run.
*/
public void bind(Runnable action) {
+ if (m_running) {
+ throw new ConcurrentModificationException("Cannot bind EventLoop while it is running");
+ }
m_bindings.add(action);
}
/** Poll all bindings. */
public void poll() {
- m_bindings.forEach(Runnable::run);
+ try {
+ m_running = true;
+ m_bindings.forEach(Runnable::run);
+ } finally {
+ m_running = false;
+ }
}
/** Clear all bindings. */
public void clear() {
+ if (m_running) {
+ throw new ConcurrentModificationException("Cannot clear EventLoop while it is running");
+ }
m_bindings.clear();
}
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/interfaces/Accelerometer.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/interfaces/Accelerometer.java
index d33b7ae..630d45c 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/interfaces/Accelerometer.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/interfaces/Accelerometer.java
@@ -11,10 +11,15 @@
*/
@Deprecated(since = "2024", forRemoval = true)
public interface Accelerometer {
+ /** Accelerometer range. */
enum Range {
+ /** 2 Gs max. */
k2G,
+ /** 4 Gs max. */
k4G,
+ /** 8 Gs max. */
k8G,
+ /** 16 Gs max. */
k16G
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/internal/DriverStationModeThread.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/internal/DriverStationModeThread.java
index 03d6397..57c6bf7 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/internal/DriverStationModeThread.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/internal/DriverStationModeThread.java
@@ -9,9 +9,7 @@
import edu.wpi.first.wpilibj.DriverStation;
import java.util.concurrent.atomic.AtomicBoolean;
-/*
- * For internal use only.
- */
+/** For internal use only. */
public class DriverStationModeThread implements AutoCloseable {
private final AtomicBoolean m_keepAlive = new AtomicBoolean();
private final Thread m_thread;
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/livewindow/LiveWindow.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/livewindow/LiveWindow.java
index ac8ef1d..1b9d1ea 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/livewindow/LiveWindow.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/livewindow/LiveWindow.java
@@ -50,7 +50,7 @@
private static Runnable disabledListener;
static {
- SendableRegistry.setLiveWindowBuilderFactory(() -> new SendableBuilderImpl());
+ SendableRegistry.setLiveWindowBuilderFactory(SendableBuilderImpl::new);
enabledPub.set(false);
}
@@ -67,14 +67,29 @@
throw new UnsupportedOperationException("This is a utility class!");
}
+ /**
+ * Sets function to be called when LiveWindow is enabled.
+ *
+ * @param runnable function (or null for none)
+ */
public static synchronized void setEnabledListener(Runnable runnable) {
enabledListener = runnable;
}
+ /**
+ * Sets function to be called when LiveWindow is disabled.
+ *
+ * @param runnable function (or null for none)
+ */
public static synchronized void setDisabledListener(Runnable runnable) {
disabledListener = runnable;
}
+ /**
+ * Returns true if LiveWindow is enabled.
+ *
+ * @return True if LiveWindow is enabled.
+ */
public static synchronized boolean isEnabled() {
return liveWindowEnabled;
}
@@ -105,10 +120,7 @@
} else {
System.out.println("stopping live window mode.");
SendableRegistry.foreachLiveWindow(
- dataHandle,
- cbdata -> {
- ((SendableBuilderImpl) cbdata.builder).stopLiveWindowMode();
- });
+ dataHandle, cbdata -> ((SendableBuilderImpl) cbdata.builder).stopLiveWindowMode());
if (disabledListener != null) {
disabledListener.run();
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/DMC60.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/DMC60.java
index 5f0f26b..9d66907 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/DMC60.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/DMC60.java
@@ -32,6 +32,7 @@
* @param channel The PWM channel that the DMC60 is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
+ @SuppressWarnings("this-escape")
public DMC60(final int channel) {
super("DMC60", channel);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/Jaguar.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/Jaguar.java
index f072067..4a0ac85 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/Jaguar.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/Jaguar.java
@@ -31,6 +31,7 @@
* @param channel The PWM channel that the Jaguar is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
+ @SuppressWarnings("this-escape")
public Jaguar(final int channel) {
super("Jaguar", channel);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/MotorControllerGroup.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/MotorControllerGroup.java
index d9da3c8..c56496c 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/MotorControllerGroup.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/MotorControllerGroup.java
@@ -9,7 +9,14 @@
import edu.wpi.first.util.sendable.SendableRegistry;
import java.util.Arrays;
-/** Allows multiple {@link MotorController} objects to be linked together. */
+/**
+ * Allows multiple {@link MotorController} objects to be linked together.
+ *
+ * @deprecated Use {@link PWMMotorController#addFollower(PWMMotorController)} or if using CAN motor
+ * controllers, use their method of following.
+ */
+@SuppressWarnings("removal")
+@Deprecated(forRemoval = true, since = "2024")
public class MotorControllerGroup implements MotorController, Sendable, AutoCloseable {
private boolean m_isInverted;
private final MotorController[] m_motorControllers;
@@ -21,6 +28,7 @@
* @param motorController The first MotorController to add
* @param motorControllers The MotorControllers to add
*/
+ @SuppressWarnings("this-escape")
public MotorControllerGroup(
MotorController motorController, MotorController... motorControllers) {
m_motorControllers = new MotorController[motorControllers.length + 1];
@@ -29,6 +37,12 @@
init();
}
+ /**
+ * Create a new MotorControllerGroup with the provided MotorControllers.
+ *
+ * @param motorControllers The MotorControllers to add.
+ */
+ @SuppressWarnings("this-escape")
public MotorControllerGroup(MotorController[] motorControllers) {
m_motorControllers = Arrays.copyOf(motorControllers, motorControllers.length);
init();
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/NidecBrushless.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/NidecBrushless.java
index 25c29ac..01af765 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/NidecBrushless.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/NidecBrushless.java
@@ -14,6 +14,7 @@
import edu.wpi.first.wpilibj.PWM;
/** Nidec Brushless Motor. */
+@SuppressWarnings("removal")
public class NidecBrushless extends MotorSafety
implements MotorController, Sendable, AutoCloseable {
private boolean m_isInverted;
@@ -30,6 +31,7 @@
* @param dioChannel The DIO channel that the Nidec Brushless controller is attached to. 0-9 are
* on-board, 10-25 are on the MXP port
*/
+ @SuppressWarnings("this-escape")
public NidecBrushless(final int pwmChannel, final int dioChannel) {
setSafetyEnabled(false);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMMotorController.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMMotorController.java
index 68817a1..b72cee3 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMMotorController.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMMotorController.java
@@ -9,11 +9,16 @@
import edu.wpi.first.util.sendable.SendableRegistry;
import edu.wpi.first.wpilibj.MotorSafety;
import edu.wpi.first.wpilibj.PWM;
+import java.util.ArrayList;
/** Common base class for all PWM Motor Controllers. */
+@SuppressWarnings("removal")
public abstract class PWMMotorController extends MotorSafety
implements MotorController, Sendable, AutoCloseable {
private boolean m_isInverted;
+ private final ArrayList<PWMMotorController> m_followers = new ArrayList<>();
+
+ /** PWM instances for motor controller. */
protected PWM m_pwm;
/**
@@ -23,6 +28,7 @@
* @param channel The PWM channel that the controller is attached to. 0-9 are on-board, 10-19 are
* on the MXP port
*/
+ @SuppressWarnings("this-escape")
protected PWMMotorController(final String name, final int channel) {
m_pwm = new PWM(channel, false);
SendableRegistry.addLW(this, name, channel);
@@ -45,7 +51,15 @@
*/
@Override
public void set(double speed) {
- m_pwm.setSpeed(m_isInverted ? -speed : speed);
+ if (m_isInverted) {
+ speed = -speed;
+ }
+ m_pwm.setSpeed(speed);
+
+ for (var follower : m_followers) {
+ follower.set(speed);
+ }
+
feed();
}
@@ -116,6 +130,15 @@
m_pwm.enableDeadbandElimination(eliminateDeadband);
}
+ /**
+ * Make the given PWM motor controller follow the output of this one.
+ *
+ * @param follower The motor controller follower.
+ */
+ public void addFollower(PWMMotorController follower) {
+ m_followers.add(follower);
+ }
+
@Override
public void initSendable(SendableBuilder builder) {
builder.setSmartDashboardType("Motor Controller");
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMSparkFlex.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMSparkFlex.java
new file mode 100644
index 0000000..059b18a
--- /dev/null
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMSparkFlex.java
@@ -0,0 +1,45 @@
+// 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.wpilibj.motorcontrol;
+
+import edu.wpi.first.hal.FRCNetComm.tResourceType;
+import edu.wpi.first.hal.HAL;
+import edu.wpi.first.wpilibj.PWM;
+
+/**
+ * REV Robotics SPARK Flex Motor Controller with PWM control.
+ *
+ * <p>Note that the SPARK Flex uses the following bounds for PWM values. These values should work
+ * reasonably well for most controllers, but if users experience issues such as asymmetric behavior
+ * around the deadband or inability to saturate the controller in either direction, calibration is
+ * recommended. The calibration procedure can be found in the SPARK Flex User Manual available from
+ * REV Robotics.
+ *
+ * <ul>
+ * <li>2.003ms = full "forward"
+ * <li>1.550ms = the "high end" of the deadband range
+ * <li>1.500ms = center of the deadband range (off)
+ * <li>1.460ms = the "low end" of the deadband range
+ * <li>0.999ms = full "reverse"
+ * </ul>
+ */
+public class PWMSparkFlex extends PWMMotorController {
+ /**
+ * Common initialization code called by all constructors.
+ *
+ * @param channel The PWM channel number. 0-9 are on-board, 10-19 are on the MXP port
+ */
+ @SuppressWarnings("this-escape")
+ public PWMSparkFlex(final int channel) {
+ super("PWMSparkFlex", channel);
+
+ m_pwm.setBoundsMicroseconds(2003, 1550, 1500, 1460, 999);
+ m_pwm.setPeriodMultiplier(PWM.PeriodMultiplier.k1X);
+ m_pwm.setSpeed(0.0);
+ m_pwm.setZeroLatch();
+
+ HAL.report(tResourceType.kResourceType_RevSparkFlexPWM, getChannel() + 1);
+ }
+}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMSparkMax.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMSparkMax.java
index ede5f5d..205d70a 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMSparkMax.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMSparkMax.java
@@ -31,6 +31,7 @@
*
* @param channel The PWM channel number. 0-9 are on-board, 10-19 are on the MXP port
*/
+ @SuppressWarnings("this-escape")
public PWMSparkMax(final int channel) {
super("PWMSparkMax", channel);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMTalonFX.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMTalonFX.java
index 29ac766..2211fa5 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMTalonFX.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMTalonFX.java
@@ -32,6 +32,7 @@
* @param channel The PWM channel that the Talon FX is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
+ @SuppressWarnings("this-escape")
public PWMTalonFX(final int channel) {
super("PWMTalonFX", channel);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMTalonSRX.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMTalonSRX.java
index 085cd86..4677627 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMTalonSRX.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMTalonSRX.java
@@ -32,6 +32,7 @@
* @param channel The PWM channel that the Talon SRX is attached to. 0-9 are on-board, 10-19 are
* on the MXP port
*/
+ @SuppressWarnings("this-escape")
public PWMTalonSRX(final int channel) {
super("PWMTalonSRX", channel);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMVenom.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMVenom.java
index a38e936..f9960b0 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMVenom.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMVenom.java
@@ -31,6 +31,7 @@
* @param channel The PWM channel that the Venom is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
+ @SuppressWarnings("this-escape")
public PWMVenom(final int channel) {
super("PWMVenom", channel);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMVictorSPX.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMVictorSPX.java
index 555614a..daa70f3 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMVictorSPX.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/PWMVictorSPX.java
@@ -32,6 +32,7 @@
* @param channel The PWM channel that the PWMVictorSPX is attached to. 0-9 are on-board, 10-19
* are on the MXP port
*/
+ @SuppressWarnings("this-escape")
public PWMVictorSPX(final int channel) {
super("PWMVictorSPX", channel);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/SD540.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/SD540.java
index 7cdb035..31246bc 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/SD540.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/SD540.java
@@ -32,6 +32,7 @@
* @param channel The PWM channel that the SD540 is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
+ @SuppressWarnings("this-escape")
public SD540(final int channel) {
super("SD540", channel);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/Spark.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/Spark.java
index cc92621..d57b626 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/Spark.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/Spark.java
@@ -32,6 +32,7 @@
* @param channel The PWM channel that the SPARK is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
+ @SuppressWarnings("this-escape")
public Spark(final int channel) {
super("Spark", channel);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/Talon.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/Talon.java
index dd9e473..bcbad60 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/Talon.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/Talon.java
@@ -31,6 +31,7 @@
* @param channel The PWM channel that the Talon is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
+ @SuppressWarnings("this-escape")
public Talon(final int channel) {
super("Talon", channel);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/Victor.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/Victor.java
index 5265a8e..1a816ad 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/Victor.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/Victor.java
@@ -17,7 +17,8 @@
* 884 controllers also but if users experience issues such as asymmetric behavior around the
* deadband or inability to saturate the controller in either direction, calibration is recommended.
* The calibration procedure can be found in the Victor 884 User Manual available from VEX Robotics:
- * http://content.vexrobotics.com/docs/ifi-v884-users-manual-9-25-06.pdf
+ * <a
+ * href="http://content.vexrobotics.com/docs/ifi-v884-users-manual-9-25-06.pdf">http://content.vexrobotics.com/docs/ifi-v884-users-manual-9-25-06.pdf</a>
*
* <ul>
* <li>2.027ms = full "forward"
@@ -34,6 +35,7 @@
* @param channel The PWM channel that the Victor is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
+ @SuppressWarnings("this-escape")
public Victor(final int channel) {
super("Victor", channel);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/VictorSP.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/VictorSP.java
index aa262d0..09ba3c6 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/VictorSP.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/motorcontrol/VictorSP.java
@@ -32,6 +32,7 @@
* @param channel The PWM channel that the VictorSP is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
+ @SuppressWarnings("this-escape")
public VictorSP(final int channel) {
super("VictorSP", channel);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/shuffleboard/EventImportance.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/shuffleboard/EventImportance.java
index 4d64efe..0d85ce6 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/shuffleboard/EventImportance.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/shuffleboard/EventImportance.java
@@ -38,6 +38,11 @@
m_simpleName = simpleName;
}
+ /**
+ * Returns name of the given enum.
+ *
+ * @return Name of the given enum.
+ */
public String getSimpleName() {
return m_simpleName;
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/shuffleboard/SendableCameraWrapper.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/shuffleboard/SendableCameraWrapper.java
index 150f0db..bd428cd 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/shuffleboard/SendableCameraWrapper.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/shuffleboard/SendableCameraWrapper.java
@@ -74,7 +74,7 @@
}
}
- /*
+ /**
* Sets NetworkTable instance used for camera publisher entries.
*
* @param inst NetworkTable instance
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/shuffleboard/ShuffleboardComponent.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/shuffleboard/ShuffleboardComponent.java
index 39078f4..3e1f75a 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/shuffleboard/ShuffleboardComponent.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/shuffleboard/ShuffleboardComponent.java
@@ -26,25 +26,53 @@
private int m_width = -1;
private int m_height = -1;
+ /**
+ * Constructs a ShuffleboardComponent.
+ *
+ * @param parent The parent container.
+ * @param title The component title.
+ * @param type The component type.
+ */
protected ShuffleboardComponent(ShuffleboardContainer parent, String title, String type) {
m_parent = requireNonNullParam(parent, "parent", "ShuffleboardComponent");
m_title = requireNonNullParam(title, "title", "ShuffleboardComponent");
m_type = type;
}
+ /**
+ * Constructs a ShuffleboardComponent.
+ *
+ * @param parent The parent container.
+ * @param title The component title.
+ */
protected ShuffleboardComponent(ShuffleboardContainer parent, String title) {
this(parent, title, null);
}
+ /**
+ * Returns the parent container.
+ *
+ * @return The parent container.
+ */
public final ShuffleboardContainer getParent() {
return m_parent;
}
+ /**
+ * Sets the component type.
+ *
+ * @param type The component type.
+ */
protected final void setType(String type) {
m_type = type;
m_metadataDirty = true;
}
+ /**
+ * Returns the component type.
+ *
+ * @return The component type.
+ */
public final String getType() {
return m_type;
}
@@ -109,6 +137,11 @@
return (C) this;
}
+ /**
+ * Builds NT metadata.
+ *
+ * @param metaTable The NT metadata table.
+ */
protected final void buildMetadata(NetworkTable metaTable) {
if (!m_metadataDirty) {
return;
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/shuffleboard/ShuffleboardInstance.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/shuffleboard/ShuffleboardInstance.java
index df2f117..88e1e49 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/shuffleboard/ShuffleboardInstance.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/shuffleboard/ShuffleboardInstance.java
@@ -18,7 +18,7 @@
final class ShuffleboardInstance implements ShuffleboardRoot {
private final Map<String, ShuffleboardTab> m_tabs = new LinkedHashMap<>();
-
+ private boolean m_reported = false; // NOPMD redundant field initializer
private boolean m_tabsChanged = false; // NOPMD redundant field initializer
private final NetworkTable m_rootTable;
private final NetworkTable m_rootMetaTable;
@@ -35,12 +35,15 @@
m_rootMetaTable = m_rootTable.getSubTable(".metadata");
m_selectedTabPub =
m_rootMetaTable.getStringTopic("Selected").publish(PubSubOption.keepDuplicates(true));
- HAL.report(tResourceType.kResourceType_Shuffleboard, 0);
}
@Override
public ShuffleboardTab getTab(String title) {
requireNonNullParam(title, "title", "getTab");
+ if (!m_reported) {
+ HAL.report(tResourceType.kResourceType_Shuffleboard, 0);
+ m_reported = true;
+ }
if (!m_tabs.containsKey(title)) {
m_tabs.put(title, new ShuffleboardTab(this, title));
m_tabsChanged = true;
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/ADXL345Sim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/ADXL345Sim.java
index c50c2f8..bcbf3e2 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/ADXL345Sim.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/ADXL345Sim.java
@@ -9,10 +9,11 @@
import edu.wpi.first.wpilibj.ADXL345_SPI;
import java.util.Objects;
+/** Class to control a simulated ADXL345. */
public class ADXL345Sim {
- protected SimDouble m_simX;
- protected SimDouble m_simY;
- protected SimDouble m_simZ;
+ private SimDouble m_simX;
+ private SimDouble m_simY;
+ private SimDouble m_simZ;
/**
* Constructor.
@@ -48,15 +49,30 @@
Objects.requireNonNull(m_simZ);
}
- public void setX(double x) {
- m_simX.set(x);
+ /**
+ * Sets the X acceleration.
+ *
+ * @param accel The X acceleration.
+ */
+ public void setX(double accel) {
+ m_simX.set(accel);
}
- public void setY(double y) {
- m_simY.set(y);
+ /**
+ * Sets the Y acceleration.
+ *
+ * @param accel The Y acceleration.
+ */
+ public void setY(double accel) {
+ m_simY.set(accel);
}
- public void setZ(double z) {
- m_simZ.set(z);
+ /**
+ * Sets the Z acceleration.
+ *
+ * @param accel The Z acceleration.
+ */
+ public void setZ(double accel) {
+ m_simZ.set(accel);
}
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/ADXL362Sim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/ADXL362Sim.java
index 76df8bd..148f914 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/ADXL362Sim.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/ADXL362Sim.java
@@ -8,10 +8,11 @@
import edu.wpi.first.wpilibj.ADXL362;
import java.util.Objects;
+/** Class to control a simulated ADXL362. */
public class ADXL362Sim {
- protected SimDouble m_simX;
- protected SimDouble m_simY;
- protected SimDouble m_simZ;
+ private SimDouble m_simX;
+ private SimDouble m_simY;
+ private SimDouble m_simZ;
/**
* Constructor.
@@ -34,15 +35,30 @@
Objects.requireNonNull(m_simZ);
}
- public void setX(double x) {
- m_simX.set(x);
+ /**
+ * Sets the X acceleration.
+ *
+ * @param accel The X acceleration.
+ */
+ public void setX(double accel) {
+ m_simX.set(accel);
}
- public void setY(double y) {
- m_simY.set(y);
+ /**
+ * Sets the Y acceleration.
+ *
+ * @param accel The Y acceleration.
+ */
+ public void setY(double accel) {
+ m_simY.set(accel);
}
- public void setZ(double z) {
- m_simZ.set(z);
+ /**
+ * Sets the Z acceleration.
+ *
+ * @param accel The Z acceleration.
+ */
+ public void setZ(double accel) {
+ m_simZ.set(accel);
}
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/DifferentialDrivetrainSim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/DifferentialDrivetrainSim.java
index 94db6f6..a121659 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/DifferentialDrivetrainSim.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/DifferentialDrivetrainSim.java
@@ -148,8 +148,7 @@
* @param dtSeconds the time difference
*/
public void update(double dtSeconds) {
- // Update state estimate with RK4
- m_x = NumericalIntegration.rk4(this::getDynamics, m_x, m_u, dtSeconds);
+ m_x = NumericalIntegration.rkdp(this::getDynamics, m_x, m_u, dtSeconds);
m_y = m_x;
if (m_measurementStdDevs != null) {
m_y = m_y.plus(StateSpaceUtil.makeWhiteNoiseVector(m_measurementStdDevs));
@@ -237,12 +236,9 @@
* @return the drivetrain's left side current draw, in amps
*/
public double getLeftCurrentDrawAmps() {
- var loadIleft =
- m_motor.getCurrent(
- getState(State.kLeftVelocity) * m_currentGearing / m_wheelRadiusMeters,
- m_u.get(0, 0))
- * Math.signum(m_u.get(0, 0));
- return loadIleft;
+ return m_motor.getCurrent(
+ getState(State.kLeftVelocity) * m_currentGearing / m_wheelRadiusMeters, m_u.get(0, 0))
+ * Math.signum(m_u.get(0, 0));
}
/**
@@ -251,13 +247,9 @@
* @return the drivetrain's right side current draw, in amps
*/
public double getRightCurrentDrawAmps() {
- var loadIright =
- m_motor.getCurrent(
- getState(State.kRightVelocity) * m_currentGearing / m_wheelRadiusMeters,
- m_u.get(1, 0))
- * Math.signum(m_u.get(1, 0));
-
- return loadIright;
+ return m_motor.getCurrent(
+ getState(State.kRightVelocity) * m_currentGearing / m_wheelRadiusMeters, m_u.get(1, 0))
+ * Math.signum(m_u.get(1, 0));
}
/**
@@ -309,6 +301,13 @@
m_x.set(State.kRightPosition.value, 0, 0);
}
+ /**
+ * The differential drive dynamics function.
+ *
+ * @param x The state.
+ * @param u The input.
+ * @return The state derivative with respect to time.
+ */
protected Matrix<N7, N1> getDynamics(Matrix<N7, N1> x, Matrix<N2, N1> u) {
// Because G can be factored out of B, we can divide by the old ratio and multiply
// by the new ratio to get a new drivetrain model.
@@ -377,12 +376,18 @@
* and 16:48 8.45:1 -- 14:50 and 19:45 7.31:1 -- 14:50 and 21:43 5.95:1 -- 14:50 and 24:40
*/
public enum KitbotGearing {
+ /** Gear ratio of 12.75:1. */
k12p75(12.75),
+ /** Gear ratio of 10.71:1. */
k10p71(10.71),
+ /** Gear ratio of 8.45:1. */
k8p45(8.45),
+ /** Gear ratio of 7.31:1. */
k7p31(7.31),
+ /** Gear ratio of 5.95:1. */
k5p95(5.95);
+ /** KitbotGearing value. */
public final double value;
KitbotGearing(double i) {
@@ -392,15 +397,24 @@
/** Represents common motor layouts of the kit drivetrain. */
public enum KitbotMotor {
+ /** One CIM motor per drive side. */
kSingleCIMPerSide(DCMotor.getCIM(1)),
+ /** Two CIM motors per drive side. */
kDualCIMPerSide(DCMotor.getCIM(2)),
+ /** One Mini CIM motor per drive side. */
kSingleMiniCIMPerSide(DCMotor.getMiniCIM(1)),
+ /** Two Mini CIM motors per drive side. */
kDualMiniCIMPerSide(DCMotor.getMiniCIM(2)),
+ /** One Falcon 500 motor per drive side. */
kSingleFalcon500PerSide(DCMotor.getFalcon500(1)),
+ /** Two Falcon 500 motors per drive side. */
kDoubleFalcon500PerSide(DCMotor.getFalcon500(2)),
+ /** One NEO motor per drive side. */
kSingleNEOPerSide(DCMotor.getNEO(1)),
+ /** Two NEO motors per drive side. */
kDoubleNEOPerSide(DCMotor.getNEO(2));
+ /** KitbotMotor value. */
public final DCMotor value;
KitbotMotor(DCMotor i) {
@@ -410,10 +424,14 @@
/** Represents common wheel sizes of the kit drivetrain. */
public enum KitbotWheelSize {
+ /** Six inch diameter wheels. */
kSixInch(Units.inchesToMeters(6)),
+ /** Eight inch diameter wheels. */
kEightInch(Units.inchesToMeters(8)),
+ /** Ten inch diameter wheels. */
kTenInch(Units.inchesToMeters(10));
+ /** KitbotWheelSize value. */
public final double value;
KitbotWheelSize(double i) {
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/ElevatorSim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/ElevatorSim.java
index 322d897..6ec8002 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/ElevatorSim.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/ElevatorSim.java
@@ -41,6 +41,7 @@
* @param startingHeightMeters The starting height of the elevator.
* @param measurementStdDevs The standard deviations of the measurements.
*/
+ @SuppressWarnings("this-escape")
public ElevatorSim(
LinearSystem<N2, N1, N1> plant,
DCMotor gearbox,
@@ -221,7 +222,7 @@
* @param positionMeters The new position in meters.
* @param velocityMetersPerSecond New velocity in meters per second.
*/
- public void setState(double positionMeters, double velocityMetersPerSecond) {
+ public final void setState(double positionMeters, double velocityMetersPerSecond) {
setState(
VecBuilder.fill(
MathUtil.clamp(positionMeters, m_minHeight, m_maxHeight), velocityMetersPerSecond));
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/GenericHIDSim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/GenericHIDSim.java
index 8a81f53..9c81be8 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/GenericHIDSim.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/GenericHIDSim.java
@@ -8,6 +8,7 @@
/** Class to control a simulated generic joystick. */
public class GenericHIDSim {
+ /** GenericHID port. */
protected final int m_port;
/**
@@ -135,7 +136,7 @@
*/
public boolean getOutput(int outputNumber) {
long outputs = getOutputs();
- return (outputs & (1 << (outputNumber - 1))) != 0;
+ return (outputs & (1L << (outputNumber - 1))) != 0;
}
/**
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/JoystickSim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/JoystickSim.java
index f55b038..b6f21e3 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/JoystickSim.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/JoystickSim.java
@@ -15,6 +15,7 @@
*
* @param joystick joystick to simulate
*/
+ @SuppressWarnings("this-escape")
public JoystickSim(Joystick joystick) {
super(joystick);
m_joystick = joystick;
@@ -29,6 +30,7 @@
*
* @param port port number
*/
+ @SuppressWarnings("this-escape")
public JoystickSim(int port) {
super(port);
// default to a reasonable joystick configuration
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/LinearSystemSim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/LinearSystemSim.java
index 73b1170..cc4db9c 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/LinearSystemSim.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/LinearSystemSim.java
@@ -23,21 +23,24 @@
*
* <p>Set simulated sensor readings with the simulated positions in {@link #getOutput()}
*
- * @param <States> The number of states of the system.
- * @param <Inputs> The number of inputs to the system.
- * @param <Outputs> The number of outputs of the system.
+ * @param <States> Number of states of the system.
+ * @param <Inputs> Number of inputs to the system.
+ * @param <Outputs> Number of outputs of the system.
*/
public class LinearSystemSim<States extends Num, Inputs extends Num, Outputs extends Num> {
- // The plant that represents the linear system.
+ /** The plant that represents the linear system. */
protected final LinearSystem<States, Inputs, Outputs> m_plant;
- // Variables for state, output, and input.
+ /** State vector. */
protected Matrix<States, N1> m_x;
- protected Matrix<Outputs, N1> m_y;
+
+ /** Input vector. */
protected Matrix<Inputs, N1> m_u;
- // The standard deviations of measurements, used for adding noise
- // to the measurements.
+ /** Output vector. */
+ protected Matrix<Outputs, N1> m_y;
+
+ /** The standard deviations of measurements, used for adding noise to the measurements. */
protected final Matrix<Outputs, N1> m_measurementStdDevs;
/**
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/PS4ControllerSim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/PS4ControllerSim.java
index fa19760..822b1db 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/PS4ControllerSim.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/PS4ControllerSim.java
@@ -13,6 +13,7 @@
*
* @param joystick controller to simulate
*/
+ @SuppressWarnings("this-escape")
public PS4ControllerSim(PS4Controller joystick) {
super(joystick);
setAxisCount(6);
@@ -25,6 +26,7 @@
*
* @param port port number
*/
+ @SuppressWarnings("this-escape")
public PS4ControllerSim(int port) {
super(port);
setAxisCount(6);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/PS5ControllerSim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/PS5ControllerSim.java
index d886bd6..e11cdd0 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/PS5ControllerSim.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/PS5ControllerSim.java
@@ -13,6 +13,7 @@
*
* @param joystick controller to simulate
*/
+ @SuppressWarnings("this-escape")
public PS5ControllerSim(PS5Controller joystick) {
super(joystick);
setAxisCount(6);
@@ -25,6 +26,7 @@
*
* @param port port number
*/
+ @SuppressWarnings("this-escape")
public PS5ControllerSim(int port) {
super(port);
setAxisCount(6);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/PneumaticsBaseSim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/PneumaticsBaseSim.java
index 156562b..dde69c1 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/PneumaticsBaseSim.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/PneumaticsBaseSim.java
@@ -10,6 +10,7 @@
/** Common base class for pneumatics module simulation classes. */
public abstract class PneumaticsBaseSim {
+ /** PneumaticsBase index. */
protected final int m_index;
/**
@@ -30,10 +31,20 @@
}
}
+ /**
+ * Constructs a PneumaticsBaseSim with the given index.
+ *
+ * @param index The index.
+ */
protected PneumaticsBaseSim(int index) {
m_index = index;
}
+ /**
+ * Constructs a PneumaticsBaseSim for the given module.
+ *
+ * @param module The module.
+ */
protected PneumaticsBaseSim(PneumaticsBase module) {
this(module.getModuleNumber());
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/RoboRioSim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/RoboRioSim.java
index 8b28b6d..e2bc895 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/RoboRioSim.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/RoboRioSim.java
@@ -6,6 +6,8 @@
import edu.wpi.first.hal.simulation.NotifyCallback;
import edu.wpi.first.hal.simulation.RoboRioDataJNI;
+import edu.wpi.first.wpilibj.RobotController;
+import edu.wpi.first.wpilibj.RobotController.RadioLEDState;
/** A utility class to control a simulated RoboRIO. */
public final class RoboRioSim {
@@ -625,6 +627,38 @@
RoboRioDataJNI.setComments(comments);
}
+ /**
+ * Register a callback to be run whenever the Radio led state changes.
+ *
+ * @param callback the callback
+ * @param initialNotify whether to call the callback with the initial state
+ * @return the {@link CallbackStore} object associated with this callback. Save a reference to
+ * this object so GC doesn't cancel the callback.
+ */
+ public static CallbackStore registerRadioLEDStateCallback(
+ NotifyCallback callback, boolean initialNotify) {
+ int uid = RoboRioDataJNI.registerRadioLEDStateCallback(callback, initialNotify);
+ return new CallbackStore(uid, RoboRioDataJNI::cancelRadioLEDStateCallback);
+ }
+
+ /**
+ * Get the state of the radio led.
+ *
+ * @return The state of the radio led.
+ */
+ public static RadioLEDState getRadioLEDState() {
+ return RadioLEDState.fromValue(RoboRioDataJNI.getRadioLEDState());
+ }
+
+ /**
+ * Set the state of the radio led.
+ *
+ * @param state The state of the radio led.
+ */
+ public static void setRadioLEDState(RobotController.RadioLEDState state) {
+ RoboRioDataJNI.setRadioLEDState(state.value);
+ }
+
/** Reset all simulation data. */
public static void resetData() {
RoboRioDataJNI.resetData();
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/SPISim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/SPISim.java
index 6c0b9e9..8ce9554 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/SPISim.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/SPISim.java
@@ -74,6 +74,13 @@
return new CallbackStore(m_index, uid, SPIDataJNI::cancelWriteCallback);
}
+ /**
+ * Register a callback to be run whenever an auto receive buffer is received.
+ *
+ * @param callback the callback
+ * @return the {@link CallbackStore} object associated with this callback. Save a reference to
+ * this object so GC doesn't cancel the callback.
+ */
public CallbackStore registerReadAutoReceiveBufferCallback(
SpiReadAutoReceiveBufferCallback callback) {
int uid = SPIDataJNI.registerReadAutoReceiveBufferCallback(m_index, callback);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/SimHooks.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/SimHooks.java
index 1664081..f637b01 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/SimHooks.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/SimHooks.java
@@ -6,6 +6,7 @@
import edu.wpi.first.hal.simulation.SimulatorJNI;
+/** Simulation hooks. */
public final class SimHooks {
private SimHooks() {}
@@ -18,14 +19,21 @@
SimulatorJNI.setRuntimeType(type);
}
+ /** Waits until the user program has started. */
public static void waitForProgramStart() {
SimulatorJNI.waitForProgramStart();
}
+ /** Sets that the user program has started. */
public static void setProgramStarted() {
SimulatorJNI.setProgramStarted();
}
+ /**
+ * Returns true if the user program has started.
+ *
+ * @return True if the user program has started.
+ */
public static boolean getProgramStarted() {
return SimulatorJNI.getProgramStarted();
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/SingleJointedArmSim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/SingleJointedArmSim.java
index af2ee85..46e0441 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/SingleJointedArmSim.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/SingleJointedArmSim.java
@@ -49,6 +49,7 @@
* @param startingAngleRads The initial position of the Arm simulation in radians.
* @param measurementStdDevs The standard deviations of the measurements.
*/
+ @SuppressWarnings("this-escape")
public SingleJointedArmSim(
LinearSystem<N2, N1, N1> plant,
DCMotor gearbox,
@@ -180,7 +181,7 @@
* @param angleRadians The new angle in radians.
* @param velocityRadPerSec The new angular velocity in radians per second.
*/
- public void setState(double angleRadians, double velocityRadPerSec) {
+ public final void setState(double angleRadians, double velocityRadPerSec) {
setState(
VecBuilder.fill(MathUtil.clamp(angleRadians, m_minAngle, m_maxAngle), velocityRadPerSec));
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/UltrasonicSim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/UltrasonicSim.java
index dc4ebaa..2ad42e7 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/UltrasonicSim.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/UltrasonicSim.java
@@ -36,14 +36,29 @@
m_simRange = simDevice.getDouble("Range (in)");
}
+ /**
+ * Sets if the range measurement is valid.
+ *
+ * @param valid True if valid
+ */
public void setRangeValid(boolean valid) {
m_simRangeValid.set(valid);
}
+ /**
+ * Sets the range measurement.
+ *
+ * @param inches The range in inches.
+ */
public void setRangeInches(double inches) {
m_simRange.set(inches);
}
+ /**
+ * Sets the range measurement.
+ *
+ * @param meters The range in meters.
+ */
public void setRangeMeters(double meters) {
m_simRange.set(Units.metersToInches(meters));
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/XboxControllerSim.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/XboxControllerSim.java
index 41d200e..37e0bda 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/XboxControllerSim.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/simulation/XboxControllerSim.java
@@ -13,6 +13,7 @@
*
* @param joystick controller to simulate
*/
+ @SuppressWarnings("this-escape")
public XboxControllerSim(XboxController joystick) {
super(joystick);
setAxisCount(6);
@@ -25,6 +26,7 @@
*
* @param port port number
*/
+ @SuppressWarnings("this-escape")
public XboxControllerSim(int port) {
super(port);
setAxisCount(6);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/Field2d.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/Field2d.java
index bfacb42..4b02c4f 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/Field2d.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/Field2d.java
@@ -31,6 +31,7 @@
*/
public class Field2d implements NTSendable, AutoCloseable {
/** Constructor. */
+ @SuppressWarnings("this-escape")
public Field2d() {
FieldObject2d obj = new FieldObject2d("Robot");
obj.setPose(new Pose2d());
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/FieldObject2d.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/FieldObject2d.java
index 9ffccde..0fecbb6 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/FieldObject2d.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/FieldObject2d.java
@@ -10,6 +10,7 @@
import edu.wpi.first.math.trajectory.Trajectory;
import edu.wpi.first.networktables.DoubleArrayEntry;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
/** Game field object on a Field2d. */
@@ -70,9 +71,7 @@
*/
public synchronized void setPoses(List<Pose2d> poses) {
m_poses.clear();
- for (Pose2d pose : poses) {
- m_poses.add(pose);
- }
+ m_poses.addAll(poses);
updateEntry();
}
@@ -83,9 +82,7 @@
*/
public synchronized void setPoses(Pose2d... poses) {
m_poses.clear();
- for (Pose2d pose : poses) {
- m_poses.add(pose);
- }
+ Collections.addAll(m_poses, poses);
updateEntry();
}
@@ -109,7 +106,7 @@
*/
public synchronized List<Pose2d> getPoses() {
updateFromEntry();
- return new ArrayList<Pose2d>(m_poses);
+ return new ArrayList<>(m_poses);
}
void updateEntry() {
@@ -143,7 +140,7 @@
return;
}
- double[] arr = m_entry.get((double[]) null);
+ double[] arr = m_entry.get(null);
if (arr != null) {
if ((arr.length % 3) != 0) {
return;
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/ListenerExecutor.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/ListenerExecutor.java
index 19a3fc1..9d0efa2 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/ListenerExecutor.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/ListenerExecutor.java
@@ -31,9 +31,9 @@
/** Runs all posted tasks. Called periodically from main thread. */
public void runListenerTasks() {
// Locally copy tasks from internal list; minimizes blocking time
- Collection<Runnable> tasks = new ArrayList<>();
+ Collection<Runnable> tasks;
synchronized (m_lock) {
- tasks.addAll(m_tasks);
+ tasks = new ArrayList<>(m_tasks);
m_tasks.clear();
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/MechanismLigament2d.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/MechanismLigament2d.java
index 28484a3..ea7fda3 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/MechanismLigament2d.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/MechanismLigament2d.java
@@ -82,7 +82,7 @@
*
* @param degrees the angle in degrees
*/
- public synchronized void setAngle(double degrees) {
+ public final synchronized void setAngle(double degrees) {
m_angle = degrees;
if (m_angleEntry != null) {
m_angleEntry.set(degrees);
@@ -115,7 +115,7 @@
*
* @param length the line length
*/
- public synchronized void setLength(double length) {
+ public final synchronized void setLength(double length) {
m_length = length;
if (m_lengthEntry != null) {
m_lengthEntry.set(length);
@@ -139,7 +139,7 @@
*
* @param color the color of the line
*/
- public synchronized void setColor(Color8Bit color) {
+ public final synchronized void setColor(Color8Bit color) {
m_color = String.format("#%02X%02X%02X", color.red, color.green, color.blue);
if (m_colorEntry != null) {
m_colorEntry.set(m_color);
@@ -177,7 +177,7 @@
*
* @param weight the line thickness
*/
- public synchronized void setLineWeight(double weight) {
+ public final synchronized void setLineWeight(double weight) {
m_weight = weight;
if (m_weightEntry != null) {
m_weightEntry.set(weight);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/MechanismObject2d.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/MechanismObject2d.java
index 754bd92..3dbcf5c 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/MechanismObject2d.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/MechanismObject2d.java
@@ -74,6 +74,11 @@
*/
protected abstract void updateEntries(NetworkTable table);
+ /**
+ * Retrieve the object's name.
+ *
+ * @return the object's name relative to its parent.
+ */
public final String getName() {
return m_name;
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/SendableBuilderImpl.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/SendableBuilderImpl.java
index 2c409e8..f15198f 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/SendableBuilderImpl.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/SendableBuilderImpl.java
@@ -57,6 +57,7 @@
import java.util.function.LongSupplier;
import java.util.function.Supplier;
+/** Implementation detail for SendableBuilder. */
@SuppressWarnings("PMD.CompareObjectsWithEquals")
public class SendableBuilderImpl implements NTSendableBuilder {
@FunctionalInterface
@@ -109,6 +110,9 @@
private final List<AutoCloseable> m_closeables = new ArrayList<>();
+ /** Default constructor. */
+ public SendableBuilderImpl() {}
+
@Override
@SuppressWarnings("PMD.AvoidCatchingGenericException")
public void close() {
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/SendableChooser.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/SendableChooser.java
index 7f3b93c..e905ebc 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/SendableChooser.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/SendableChooser.java
@@ -53,6 +53,7 @@
private static final AtomicInteger s_instances = new AtomicInteger();
/** Instantiates a {@link SendableChooser}. */
+ @SuppressWarnings("this-escape")
public SendableChooser() {
m_instance = s_instances.getAndIncrement();
SendableRegistry.add(this, "SendableChooser", m_instance);
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/SmartDashboard.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/SmartDashboard.java
index 8a8f147..7da170b 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/SmartDashboard.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/smartdashboard/SmartDashboard.java
@@ -4,6 +4,7 @@
package edu.wpi.first.wpilibj.smartdashboard;
+import edu.wpi.first.hal.FRCNetComm.tInstances;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.networktables.NetworkTable;
@@ -35,9 +36,10 @@
/** The executor for listener tasks; calls listener tasks synchronously from main thread. */
private static final ListenerExecutor listenerExecutor = new ListenerExecutor();
+ private static boolean m_reported = false; // NOPMD redundant field initializer
+
static {
setNetworkTableInstance(NetworkTableInstance.getDefault());
- HAL.report(tResourceType.kResourceType_SmartDashboard, 0);
}
private SmartDashboard() {
@@ -64,6 +66,10 @@
*/
@SuppressWarnings("PMD.CompareObjectsWithEquals")
public static synchronized void putData(String key, Sendable data) {
+ if (!m_reported) {
+ HAL.report(tResourceType.kResourceType_SmartDashboard, tInstances.kSmartDashboard_Instance);
+ m_reported = true;
+ }
Sendable sddata = tablesToData.get(key);
if (sddata == null || sddata != data) {
tablesToData.put(key, data);
@@ -114,6 +120,10 @@
* @return Network table entry.
*/
public static NetworkTableEntry getEntry(String key) {
+ if (!m_reported) {
+ HAL.report(tResourceType.kResourceType_SmartDashboard, tInstances.kSmartDashboard_Instance);
+ m_reported = true;
+ }
return table.getEntry(key);
}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/sysid/SysIdRoutineLog.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/sysid/SysIdRoutineLog.java
new file mode 100644
index 0000000..38bc46f
--- /dev/null
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/sysid/SysIdRoutineLog.java
@@ -0,0 +1,220 @@
+// 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.wpilibj.sysid;
+
+import static edu.wpi.first.units.Units.Amps;
+import static edu.wpi.first.units.Units.Meters;
+import static edu.wpi.first.units.Units.MetersPerSecond;
+import static edu.wpi.first.units.Units.Rotations;
+import static edu.wpi.first.units.Units.RotationsPerSecond;
+import static edu.wpi.first.units.Units.Second;
+import static edu.wpi.first.units.Units.Volts;
+
+import edu.wpi.first.units.Angle;
+import edu.wpi.first.units.Current;
+import edu.wpi.first.units.Distance;
+import edu.wpi.first.units.Measure;
+import edu.wpi.first.units.Velocity;
+import edu.wpi.first.units.Voltage;
+import edu.wpi.first.util.datalog.DoubleLogEntry;
+import edu.wpi.first.util.datalog.StringLogEntry;
+import edu.wpi.first.wpilibj.DataLogManager;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Utility for logging data from a SysId test routine. Each complete routine (quasistatic and
+ * dynamic, forward and reverse) should have its own SysIdRoutineLog instance, with a unique log
+ * name.
+ */
+public class SysIdRoutineLog {
+ private final Map<String, Map<String, DoubleLogEntry>> m_logEntries = new HashMap<>();
+ private final String m_logName;
+ private final StringLogEntry m_state;
+
+ /**
+ * Create a new logging utility for a SysId test routine.
+ *
+ * @param logName The name for the test routine in the log. Should be unique between complete test
+ * routines (quasistatic and dynamic, forward and reverse). The current state of this test
+ * (e.g. "quasistatic-forward") will appear in WPILog under the "sysid-test-state-logName"
+ * entry.
+ */
+ public SysIdRoutineLog(String logName) {
+ m_logName = logName;
+ m_state = new StringLogEntry(DataLogManager.getLog(), "sysid-test-state-" + logName);
+ m_state.append(State.kNone.toString());
+ }
+
+ /** Possible state of a SysId routine. */
+ public enum State {
+ /** Quasistatic forward test. */
+ kQuasistaticForward("quasistatic-forward"),
+ /** Quasistatic reverse test. */
+ kQuasistaticReverse("quasistatic-reverse"),
+ /** Dynamic forward test. */
+ kDynamicForward("dynamic-forward"),
+ /** Dynamic reverse test. */
+ kDynamicReverse("dynamic-reverse"),
+ /** No test. */
+ kNone("none");
+
+ private final String m_state;
+
+ State(String state) {
+ m_state = state;
+ }
+
+ @Override
+ public String toString() {
+ return m_state;
+ }
+ }
+
+ /** Logs data from a single motor during a SysIdRoutine. */
+ public class MotorLog {
+ private final String m_motorName;
+
+ /**
+ * Create a new SysId motor log handle.
+ *
+ * @param motorName The name of the motor whose data is being logged.
+ */
+ private MotorLog(String motorName) {
+ m_motorName = motorName;
+ m_logEntries.put(motorName, new HashMap<>());
+ }
+
+ /**
+ * Log a generic data value from the motor.
+ *
+ * @param name The name of the data field being recorded.
+ * @param value The numeric value of the data field.
+ * @param unit The unit string of the data field.
+ * @return The motor log (for call chaining).
+ */
+ public MotorLog value(String name, double value, String unit) {
+ var motorEntries = m_logEntries.get(m_motorName);
+ var entry = motorEntries.get(name);
+
+ if (entry == null) {
+ var log = DataLogManager.getLog();
+
+ entry = new DoubleLogEntry(log, name + "-" + m_motorName + "-" + m_logName, unit);
+ motorEntries.put(name, entry);
+ }
+
+ entry.append(value);
+ return this;
+ }
+
+ /**
+ * Log the voltage applied to the motor.
+ *
+ * @param voltage The voltage to record.
+ * @return The motor log (for call chaining).
+ */
+ public MotorLog voltage(Measure<Voltage> voltage) {
+ return value("voltage", voltage.in(Volts), Volts.name());
+ }
+
+ /**
+ * Log the linear position of the motor.
+ *
+ * @param position The linear position to record.
+ * @return The motor log (for call chaining).
+ */
+ public MotorLog linearPosition(Measure<Distance> position) {
+ return value("position", position.in(Meters), Meters.name());
+ }
+
+ /**
+ * Log the angular position of the motor.
+ *
+ * @param position The angular position to record.
+ * @return The motor log (for call chaining).
+ */
+ public MotorLog angularPosition(Measure<Angle> position) {
+ return value("position", position.in(Rotations), Rotations.name());
+ }
+
+ /**
+ * Log the linear velocity of the motor.
+ *
+ * @param velocity The linear velocity to record.
+ * @return The motor log (for call chaining).
+ */
+ public MotorLog linearVelocity(Measure<Velocity<Distance>> velocity) {
+ return value("velocity", velocity.in(MetersPerSecond), MetersPerSecond.name());
+ }
+
+ /**
+ * Log the angular velocity of the motor.
+ *
+ * @param velocity The angular velocity to record.
+ * @return The motor log (for call chaining).
+ */
+ public MotorLog angularVelocity(Measure<Velocity<Angle>> velocity) {
+ return value("velocity", velocity.in(RotationsPerSecond), RotationsPerSecond.name());
+ }
+
+ /**
+ * Log the linear acceleration of the motor.
+ *
+ * @param acceleration The linear acceleration to record.
+ * @return The motor log (for call chaining).
+ */
+ public MotorLog linearAcceleration(Measure<Velocity<Velocity<Distance>>> acceleration) {
+ return value(
+ "position",
+ acceleration.in(MetersPerSecond.per(Second)),
+ MetersPerSecond.per(Second).name());
+ }
+
+ /**
+ * Log the angular acceleration of the motor.
+ *
+ * @param acceleration The angular acceleration to record.
+ * @return The motor log (for call chaining).
+ */
+ public MotorLog angularAcceleration(Measure<Velocity<Velocity<Angle>>> acceleration) {
+ return value(
+ "position",
+ acceleration.in(RotationsPerSecond.per(Second)),
+ RotationsPerSecond.per(Second).name());
+ }
+
+ /**
+ * Log the current applied to the motor.
+ *
+ * @param current The current to record.
+ * @return The motor log (for call chaining).
+ */
+ public MotorLog current(Measure<Current> current) {
+ value("current", current.in(Amps), Amps.name());
+ return this;
+ }
+ }
+
+ /**
+ * Log data from a motor during a SysId routine.
+ *
+ * @param motorName The name of the motor.
+ * @return Handle with chainable callbacks to log individual data fields.
+ */
+ public MotorLog motor(String motorName) {
+ return new MotorLog(motorName);
+ }
+
+ /**
+ * Records the current state of the SysId test routine. Should be called once per iteration during
+ * tests with the type of the current test, and once upon test end with state `none`.
+ *
+ * @param state The current state of the SysId test routine.
+ */
+ public void recordState(State state) {
+ m_state.append(state.toString());
+ }
+}
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/util/Color.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/util/Color.java
index 2defbd8..5060567 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/util/Color.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/util/Color.java
@@ -14,13 +14,24 @@
*/
@SuppressWarnings("MemberName")
public class Color {
- private static final double kPrecision = Math.pow(2, -12);
-
+ /** Red component (0-1). */
public final double red;
+
+ /** Green component (0-1). */
public final double green;
+
+ /** Blue component (0-1). */
public final double blue;
+
private String m_name;
+ /** Constructs a default color (black). */
+ public Color() {
+ red = 0.0;
+ green = 0.0;
+ blue = 0.0;
+ }
+
/**
* Constructs a Color from doubles.
*
@@ -70,6 +81,22 @@
}
/**
+ * Constructs a Color from a hex string.
+ *
+ * @param hexString a string of the format <code>#RRGGBB</code>
+ * @throws IllegalArgumentException if the hex string is invalid.
+ */
+ public Color(String hexString) {
+ if (hexString.length() != 7 || !hexString.startsWith("#")) {
+ throw new IllegalArgumentException("Invalid hex string \"" + hexString + "\"");
+ }
+
+ this.red = Integer.valueOf(hexString.substring(1, 3), 16) / 255.0;
+ this.green = Integer.valueOf(hexString.substring(3, 5), 16) / 255.0;
+ this.blue = Integer.valueOf(hexString.substring(5, 7), 16) / 255.0;
+ }
+
+ /**
* Creates a Color from HSV values.
*
* @param h The h value [0-180)
@@ -155,8 +182,7 @@
}
private static double roundAndClamp(double value) {
- final var rounded = Math.round((value + kPrecision / 2) / kPrecision) * kPrecision;
- return MathUtil.clamp(rounded, 0.0, 1.0);
+ return MathUtil.clamp(Math.ceil(value * (1 << 12)) / (1 << 12), 0.0, 1.0);
}
/*
diff --git a/wpilibj/src/main/java/edu/wpi/first/wpilibj/util/Color8Bit.java b/wpilibj/src/main/java/edu/wpi/first/wpilibj/util/Color8Bit.java
index 3260673..132ea64 100644
--- a/wpilibj/src/main/java/edu/wpi/first/wpilibj/util/Color8Bit.java
+++ b/wpilibj/src/main/java/edu/wpi/first/wpilibj/util/Color8Bit.java
@@ -10,10 +10,22 @@
/** Represents colors with 8 bits of precision. */
@SuppressWarnings("MemberName")
public class Color8Bit {
+ /** Red component (0-255). */
public final int red;
+
+ /** Green component (0-255). */
public final int green;
+
+ /** Blue component (0-255). */
public final int blue;
+ /** Constructs a default color (black). */
+ public Color8Bit() {
+ red = 0;
+ green = 0;
+ blue = 0;
+ }
+
/**
* Constructs a Color8Bit.
*
@@ -36,6 +48,22 @@
this((int) (color.red * 255), (int) (color.green * 255), (int) (color.blue * 255));
}
+ /**
+ * Constructs a Color8Bit from a hex string.
+ *
+ * @param hexString a string of the format <code>#RRGGBB</code>
+ * @throws IllegalArgumentException if the hex string is invalid.
+ */
+ public Color8Bit(String hexString) {
+ if (hexString.length() != 7 || !hexString.startsWith("#")) {
+ throw new IllegalArgumentException("Invalid hex string \"" + hexString + "\"");
+ }
+
+ this.red = Integer.valueOf(hexString.substring(1, 3), 16);
+ this.green = Integer.valueOf(hexString.substring(3, 5), 16);
+ this.blue = Integer.valueOf(hexString.substring(5, 7), 16);
+ }
+
@Override
public boolean equals(Object other) {
if (this == other) {
diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/TimedRobotTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/TimedRobotTest.java
index c1c5f3c..920fb54 100644
--- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/TimedRobotTest.java
+++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/TimedRobotTest.java
@@ -144,11 +144,7 @@
void disabledModeTest() {
MockRobot robot = new MockRobot();
- Thread robotThread =
- new Thread(
- () -> {
- robot.startCompetition();
- });
+ Thread robotThread = new Thread(robot::startCompetition);
robotThread.start();
DriverStationSim.setEnabled(false);
@@ -231,11 +227,7 @@
void autonomousModeTest() {
MockRobot robot = new MockRobot();
- Thread robotThread =
- new Thread(
- () -> {
- robot.startCompetition();
- });
+ Thread robotThread = new Thread(robot::startCompetition);
robotThread.start();
DriverStationSim.setEnabled(true);
@@ -320,11 +312,7 @@
void teleopModeTest() {
MockRobot robot = new MockRobot();
- Thread robotThread =
- new Thread(
- () -> {
- robot.startCompetition();
- });
+ Thread robotThread = new Thread(robot::startCompetition);
robotThread.start();
DriverStationSim.setEnabled(true);
@@ -411,11 +399,7 @@
MockRobot robot = new MockRobot();
robot.enableLiveWindowInTest(isLW);
- Thread robotThread =
- new Thread(
- () -> {
- robot.startCompetition();
- });
+ Thread robotThread = new Thread(robot::startCompetition);
robotThread.start();
DriverStationSim.setEnabled(true);
@@ -531,11 +515,7 @@
void modeChangeTest() {
MockRobot robot = new MockRobot();
- Thread robotThread =
- new Thread(
- () -> {
- robot.startCompetition();
- });
+ Thread robotThread = new Thread(robot::startCompetition);
robotThread.start();
// Start in disabled
@@ -655,17 +635,9 @@
MockRobot robot = new MockRobot();
final AtomicInteger callbackCount = new AtomicInteger(0);
- robot.addPeriodic(
- () -> {
- callbackCount.addAndGet(1);
- },
- kPeriod / 2.0);
+ robot.addPeriodic(() -> callbackCount.addAndGet(1), kPeriod / 2.0);
- Thread robotThread =
- new Thread(
- () -> {
- robot.startCompetition();
- });
+ Thread robotThread = new Thread(robot::startCompetition);
robotThread.start();
DriverStationSim.setEnabled(false);
@@ -704,12 +676,7 @@
MockRobot robot = new MockRobot();
final AtomicInteger callbackCount = new AtomicInteger(0);
- robot.addPeriodic(
- () -> {
- callbackCount.addAndGet(1);
- },
- kPeriod / 2.0,
- kPeriod / 4.0);
+ robot.addPeriodic(() -> callbackCount.addAndGet(1), kPeriod / 2.0, kPeriod / 4.0);
// Expirations in this test (ms)
//
@@ -720,11 +687,7 @@
// p | 0.75p
// 2p | 1.25p
- Thread robotThread =
- new Thread(
- () -> {
- robot.startCompetition();
- });
+ Thread robotThread = new Thread(robot::startCompetition);
robotThread.start();
DriverStationSim.setEnabled(false);
diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/TimesliceRobotTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/TimesliceRobotTest.java
index ee4860d..5cff0d0 100644
--- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/TimesliceRobotTest.java
+++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/TimesliceRobotTest.java
@@ -54,22 +54,10 @@
// | RobotPeriodic() | 0 | 2 |
// | Callback 1 | 2 | 0.5 |
// | Callback 2 | 2.5 | 1 |
- robot.schedule(
- () -> {
- callbackCount1.addAndGet(1);
- },
- 0.0005);
- robot.schedule(
- () -> {
- callbackCount2.addAndGet(1);
- },
- 0.001);
+ robot.schedule(() -> callbackCount1.addAndGet(1), 0.0005);
+ robot.schedule(() -> callbackCount2.addAndGet(1), 0.001);
- Thread robotThread =
- new Thread(
- () -> {
- robot.startCompetition();
- });
+ Thread robotThread = new Thread(robot::startCompetition);
robotThread.start();
DriverStationSim.setEnabled(false);
diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/WatchdogTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/WatchdogTest.java
index c1676e0..5e9e122 100644
--- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/WatchdogTest.java
+++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/WatchdogTest.java
@@ -33,12 +33,7 @@
void enableDisableTest() {
final AtomicInteger watchdogCounter = new AtomicInteger(0);
- try (Watchdog watchdog =
- new Watchdog(
- 0.4,
- () -> {
- watchdogCounter.addAndGet(1);
- })) {
+ try (Watchdog watchdog = new Watchdog(0.4, () -> watchdogCounter.addAndGet(1))) {
// Run 1
watchdog.enable();
SimHooks.stepTiming(0.2);
@@ -71,12 +66,7 @@
void resetTest() {
final AtomicInteger watchdogCounter = new AtomicInteger(0);
- try (Watchdog watchdog =
- new Watchdog(
- 0.4,
- () -> {
- watchdogCounter.addAndGet(1);
- })) {
+ try (Watchdog watchdog = new Watchdog(0.4, () -> watchdogCounter.addAndGet(1))) {
watchdog.enable();
SimHooks.stepTiming(0.2);
watchdog.reset();
@@ -92,12 +82,7 @@
void setTimeoutTest() {
final AtomicInteger watchdogCounter = new AtomicInteger(0);
- try (Watchdog watchdog =
- new Watchdog(
- 1.0,
- () -> {
- watchdogCounter.addAndGet(1);
- })) {
+ try (Watchdog watchdog = new Watchdog(1.0, () -> watchdogCounter.addAndGet(1))) {
watchdog.enable();
SimHooks.stepTiming(0.2);
watchdog.setTimeout(0.2);
@@ -137,12 +122,7 @@
void epochsTest() {
final AtomicInteger watchdogCounter = new AtomicInteger(0);
- try (Watchdog watchdog =
- new Watchdog(
- 0.4,
- () -> {
- watchdogCounter.addAndGet(1);
- })) {
+ try (Watchdog watchdog = new Watchdog(0.4, () -> watchdogCounter.addAndGet(1))) {
// Run 1
watchdog.enable();
watchdog.addEpoch("Epoch 1");
@@ -173,18 +153,8 @@
final AtomicInteger watchdogCounter1 = new AtomicInteger(0);
final AtomicInteger watchdogCounter2 = new AtomicInteger(0);
- try (Watchdog watchdog1 =
- new Watchdog(
- 0.2,
- () -> {
- watchdogCounter1.addAndGet(1);
- });
- Watchdog watchdog2 =
- new Watchdog(
- 0.6,
- () -> {
- watchdogCounter2.addAndGet(1);
- })) {
+ try (Watchdog watchdog1 = new Watchdog(0.2, () -> watchdogCounter1.addAndGet(1));
+ Watchdog watchdog2 = new Watchdog(0.6, () -> watchdogCounter2.addAndGet(1))) {
watchdog2.enable();
SimHooks.stepTiming(0.25);
assertEquals(0, watchdogCounter1.get(), "Watchdog triggered early");
diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/drive/DifferentialDriveTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/drive/DifferentialDriveTest.java
index 4675a7f..474dc89 100644
--- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/drive/DifferentialDriveTest.java
+++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/drive/DifferentialDriveTest.java
@@ -6,7 +6,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
-import edu.wpi.first.wpilibj.motorcontrol.MockMotorController;
+import edu.wpi.first.wpilibj.motorcontrol.MockPWMMotorController;
import org.junit.jupiter.api.Test;
class DifferentialDriveTest {
@@ -250,9 +250,9 @@
@Test
void testArcadeDrive() {
- var left = new MockMotorController();
- var right = new MockMotorController();
- var drive = new DifferentialDrive(left, right);
+ var left = new MockPWMMotorController();
+ var right = new MockPWMMotorController();
+ var drive = new DifferentialDrive(left::set, right::set);
drive.setDeadband(0.0);
// Forward
@@ -288,9 +288,9 @@
@Test
void testArcadeDriveSquared() {
- var left = new MockMotorController();
- var right = new MockMotorController();
- var drive = new DifferentialDrive(left, right);
+ var left = new MockPWMMotorController();
+ var right = new MockPWMMotorController();
+ var drive = new DifferentialDrive(left::set, right::set);
drive.setDeadband(0.0);
// Forward
@@ -326,9 +326,9 @@
@Test
void testCurvatureDrive() {
- var left = new MockMotorController();
- var right = new MockMotorController();
- var drive = new DifferentialDrive(left, right);
+ var left = new MockPWMMotorController();
+ var right = new MockPWMMotorController();
+ var drive = new DifferentialDrive(left::set, right::set);
drive.setDeadband(0.0);
// Forward
@@ -364,9 +364,9 @@
@Test
void testCurvatureDriveTurnInPlace() {
- var left = new MockMotorController();
- var right = new MockMotorController();
- var drive = new DifferentialDrive(left, right);
+ var left = new MockPWMMotorController();
+ var right = new MockPWMMotorController();
+ var drive = new DifferentialDrive(left::set, right::set);
drive.setDeadband(0.0);
// Forward
@@ -402,9 +402,9 @@
@Test
void testTankDrive() {
- var left = new MockMotorController();
- var right = new MockMotorController();
- var drive = new DifferentialDrive(left, right);
+ var left = new MockPWMMotorController();
+ var right = new MockPWMMotorController();
+ var drive = new DifferentialDrive(left::set, right::set);
drive.setDeadband(0.0);
// Forward
@@ -440,9 +440,9 @@
@Test
void testTankDriveSquared() {
- var left = new MockMotorController();
- var right = new MockMotorController();
- var drive = new DifferentialDrive(left, right);
+ var left = new MockPWMMotorController();
+ var right = new MockPWMMotorController();
+ var drive = new DifferentialDrive(left::set, right::set);
drive.setDeadband(0.0);
// Forward
diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/drive/MecanumDriveTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/drive/MecanumDriveTest.java
index 034ba10..a1017d5 100644
--- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/drive/MecanumDriveTest.java
+++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/drive/MecanumDriveTest.java
@@ -7,7 +7,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import edu.wpi.first.math.geometry.Rotation2d;
-import edu.wpi.first.wpilibj.motorcontrol.MockMotorController;
+import edu.wpi.first.wpilibj.motorcontrol.MockPWMMotorController;
import org.junit.jupiter.api.Test;
class MecanumDriveTest {
@@ -89,11 +89,11 @@
@Test
void testCartesian() {
- var fl = new MockMotorController();
- var fr = new MockMotorController();
- var rl = new MockMotorController();
- var rr = new MockMotorController();
- var drive = new MecanumDrive(fl, rl, fr, rr);
+ var fl = new MockPWMMotorController();
+ var rl = new MockPWMMotorController();
+ var fr = new MockPWMMotorController();
+ var rr = new MockPWMMotorController();
+ var drive = new MecanumDrive(fl::set, rl::set, fr::set, rr::set);
drive.setDeadband(0.0);
// Forward
@@ -134,11 +134,11 @@
@Test
void testCartesianGyro90CW() {
- var fl = new MockMotorController();
- var fr = new MockMotorController();
- var rl = new MockMotorController();
- var rr = new MockMotorController();
- var drive = new MecanumDrive(fl, rl, fr, rr);
+ var fl = new MockPWMMotorController();
+ var rl = new MockPWMMotorController();
+ var fr = new MockPWMMotorController();
+ var rr = new MockPWMMotorController();
+ var drive = new MecanumDrive(fl::set, rl::set, fr::set, rr::set);
drive.setDeadband(0.0);
// Forward in global frame; left in robot frame
@@ -179,11 +179,11 @@
@Test
void testPolar() {
- var fl = new MockMotorController();
- var fr = new MockMotorController();
- var rl = new MockMotorController();
- var rr = new MockMotorController();
- var drive = new MecanumDrive(fl, rl, fr, rr);
+ var fl = new MockPWMMotorController();
+ var rl = new MockPWMMotorController();
+ var fr = new MockPWMMotorController();
+ var rr = new MockPWMMotorController();
+ var drive = new MecanumDrive(fl::set, rl::set, fr::set, rr::set);
drive.setDeadband(0.0);
// Forward
diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/event/EventLoopTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/event/EventLoopTest.java
index ea3c569..644c18e 100644
--- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/event/EventLoopTest.java
+++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/event/EventLoopTest.java
@@ -5,7 +5,9 @@
package edu.wpi.first.wpilibj.event;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import java.util.ConcurrentModificationException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.jupiter.api.Test;
@@ -58,4 +60,33 @@
// shouldn't change
assertEquals(1, counter.get());
}
+
+ @Test
+ void testConcurrentModification() {
+ var loop = new EventLoop();
+
+ loop.bind(
+ () -> {
+ assertThrows(
+ ConcurrentModificationException.class,
+ () -> {
+ loop.bind(() -> {});
+ });
+ });
+
+ loop.poll();
+
+ loop.clear();
+
+ loop.bind(
+ () -> {
+ assertThrows(
+ ConcurrentModificationException.class,
+ () -> {
+ loop.clear();
+ });
+ });
+
+ loop.poll();
+ }
}
diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/motorcontrol/MockMotorController.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/motorcontrol/MockMotorController.java
index e7a6b8e..4ac3dc8 100644
--- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/motorcontrol/MockMotorController.java
+++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/motorcontrol/MockMotorController.java
@@ -4,6 +4,7 @@
package edu.wpi.first.wpilibj.motorcontrol;
+@SuppressWarnings("removal")
public class MockMotorController implements MotorController {
private double m_speed;
private boolean m_isInverted;
diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/motorcontrol/MockPWMMotorController.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/motorcontrol/MockPWMMotorController.java
new file mode 100644
index 0000000..bf2c287
--- /dev/null
+++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/motorcontrol/MockPWMMotorController.java
@@ -0,0 +1,34 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+package edu.wpi.first.wpilibj.motorcontrol;
+
+public class MockPWMMotorController {
+ private double m_speed;
+ private boolean m_isInverted;
+
+ public void set(double speed) {
+ m_speed = m_isInverted ? -speed : speed;
+ }
+
+ public double get() {
+ return m_speed;
+ }
+
+ public void setInverted(boolean isInverted) {
+ m_isInverted = isInverted;
+ }
+
+ public boolean getInverted() {
+ return m_isInverted;
+ }
+
+ public void disable() {
+ m_speed = 0;
+ }
+
+ public void stopMotor() {
+ disable();
+ }
+}
diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/motorcontrol/MotorControllerGroupTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/motorcontrol/MotorControllerGroupTest.java
index 6efb3de..a8f71f6 100644
--- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/motorcontrol/MotorControllerGroupTest.java
+++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/motorcontrol/MotorControllerGroupTest.java
@@ -15,6 +15,7 @@
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
+@SuppressWarnings("removal")
class MotorControllerGroupTest {
private static Stream<Arguments> motorControllerArguments() {
return IntStream.of(1, 2, 3)
diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/shuffleboard/MockActuatorSendable.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/shuffleboard/MockActuatorSendable.java
index 04397c2..a630c3e 100644
--- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/shuffleboard/MockActuatorSendable.java
+++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/shuffleboard/MockActuatorSendable.java
@@ -10,6 +10,7 @@
/** A mock sendable that marks itself as an actuator. */
public class MockActuatorSendable implements Sendable {
+ @SuppressWarnings("this-escape")
public MockActuatorSendable(String name) {
SendableRegistry.add(this, name);
}
diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/shuffleboard/ShuffleboardInstanceTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/shuffleboard/ShuffleboardInstanceTest.java
index 6283c68..25b545b 100644
--- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/shuffleboard/ShuffleboardInstanceTest.java
+++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/shuffleboard/ShuffleboardInstanceTest.java
@@ -136,7 +136,7 @@
try (StringSubscriber subscriber =
m_ntInstance
.getStringTopic("/Shuffleboard/.metadata/Selected")
- .subscribe("", PubSubOption.keepDuplicates(true)); ) {
+ .subscribe("", PubSubOption.keepDuplicates(true))) {
listener =
m_ntInstance.addListener(
subscriber,
diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/AddressableLEDSimTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/AddressableLEDSimTest.java
index 096f77e..4ddadf1 100644
--- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/AddressableLEDSimTest.java
+++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/AddressableLEDSimTest.java
@@ -79,7 +79,7 @@
BufferCallback callback = new BufferCallback();
try (AddressableLED led = new AddressableLED(0);
- CallbackStore cb = sim.registerDataCallback(callback); ) {
+ CallbackStore cb = sim.registerDataCallback(callback)) {
assertFalse(sim.getRunning());
assertEquals(1, sim.getLength()); // Defaults to 1 led
diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/DCMotorSimTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/DCMotorSimTest.java
index fbe3af0..681e6b4 100644
--- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/DCMotorSimTest.java
+++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/DCMotorSimTest.java
@@ -63,7 +63,7 @@
try (var motor = new PWMVictorSPX(0);
var encoder = new Encoder(0, 1);
- var controller = new PIDController(0.04, 0.0, 0.001); ) {
+ var controller = new PIDController(0.04, 0.0, 0.001)) {
var encoderSim = new EncoderSim(encoder);
encoderSim.resetData();
diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/DifferentialDrivetrainSimTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/DifferentialDrivetrainSimTest.java
index 5baed3a..cbb8d18 100644
--- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/DifferentialDrivetrainSimTest.java
+++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/DifferentialDrivetrainSimTest.java
@@ -76,11 +76,11 @@
sim.update(0.020);
// Update our ground truth
- groundTruthX = NumericalIntegration.rk4(sim::getDynamics, groundTruthX, voltages, 0.020);
+ groundTruthX = NumericalIntegration.rkdp(sim::getDynamics, groundTruthX, voltages, 0.020);
}
// 2 inch tolerance is OK since our ground truth is an approximation of the
- // ODE solution using RK4 anyway
+ // ODE solution using RKDP anyway
assertEquals(
groundTruthX.get(DifferentialDrivetrainSim.State.kX.value, 0),
sim.getState(DifferentialDrivetrainSim.State.kX),
diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/DigitalPWMSimTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/DigitalPWMSimTest.java
index 9f29aac..8a0fc7c 100644
--- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/DigitalPWMSimTest.java
+++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/DigitalPWMSimTest.java
@@ -25,7 +25,7 @@
BooleanCallback initializeCallback = new BooleanCallback();
DoubleCallback dutyCycleCallback = new DoubleCallback();
try (CallbackStore initCb = sim.registerInitializedCallback(initializeCallback, false);
- CallbackStore dutyCycleCb = sim.registerDutyCycleCallback(dutyCycleCallback, false); ) {
+ CallbackStore dutyCycleCb = sim.registerDutyCycleCallback(dutyCycleCallback, false)) {
final double kTestDutyCycle = 0.191;
output.enablePWM(kTestDutyCycle);
diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/RelaySimTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/RelaySimTest.java
index 3918361..c7538cc 100644
--- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/RelaySimTest.java
+++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/RelaySimTest.java
@@ -58,7 +58,7 @@
try (CallbackStore fwdCb = sim.registerInitializedForwardCallback(forwardCallback, false);
CallbackStore revCb = sim.registerInitializedReverseCallback(reverseCallback, false);
- Relay relay = new Relay(0, Relay.Direction.kForward); ) {
+ Relay relay = new Relay(0, Relay.Direction.kForward)) {
assertTrue(sim.getInitializedForward());
assertFalse(sim.getInitializedReverse());
@@ -84,7 +84,7 @@
try (CallbackStore fwdCb = sim.registerInitializedForwardCallback(forwardCallback, false);
CallbackStore revCb = sim.registerInitializedReverseCallback(reverseCallback, false);
- Relay relay = new Relay(0, Relay.Direction.kReverse); ) {
+ Relay relay = new Relay(0, Relay.Direction.kReverse)) {
assertFalse(sim.getInitializedForward());
assertTrue(sim.getInitializedReverse());
diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/RoboRioSimTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/RoboRioSimTest.java
index c016ec4..01029cd 100644
--- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/RoboRioSimTest.java
+++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/RoboRioSimTest.java
@@ -10,8 +10,10 @@
import edu.wpi.first.hal.HALUtil;
import edu.wpi.first.wpilibj.RobotController;
+import edu.wpi.first.wpilibj.RobotController.RadioLEDState;
import edu.wpi.first.wpilibj.simulation.testutils.BooleanCallback;
import edu.wpi.first.wpilibj.simulation.testutils.DoubleCallback;
+import edu.wpi.first.wpilibj.simulation.testutils.EnumCallback;
import edu.wpi.first.wpilibj.simulation.testutils.IntCallback;
import org.junit.jupiter.api.Test;
@@ -279,4 +281,26 @@
assertEquals(kCommentsTruncated, RoboRioSim.getComments());
assertEquals(kCommentsTruncated, RobotController.getComments());
}
+
+ @Test
+ void testRadioLEDState() {
+ RoboRioSim.resetData();
+
+ EnumCallback callback = new EnumCallback();
+ try (CallbackStore cb = RoboRioSim.registerRadioLEDStateCallback(callback, false)) {
+ RobotController.setRadioLEDState(RadioLEDState.kGreen);
+ assertTrue(callback.wasTriggered());
+ assertEquals(RadioLEDState.kGreen.value, callback.getSetValue());
+ assertEquals(RadioLEDState.kGreen, RoboRioSim.getRadioLEDState());
+ assertEquals(RadioLEDState.kGreen, RobotController.getRadioLEDState());
+
+ callback.reset();
+
+ RoboRioSim.setRadioLEDState(RadioLEDState.kOrange);
+ assertTrue(callback.wasTriggered());
+ assertEquals(RadioLEDState.kOrange.value, callback.getSetValue());
+ assertEquals(RadioLEDState.kOrange, RoboRioSim.getRadioLEDState());
+ assertEquals(RadioLEDState.kOrange, RobotController.getRadioLEDState());
+ }
+ }
}
diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/SimDeviceSimTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/SimDeviceSimTest.java
index 62a24d1..89b4333 100644
--- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/SimDeviceSimTest.java
+++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/simulation/SimDeviceSimTest.java
@@ -41,18 +41,10 @@
SimDevice dev1 = SimDevice.create("testDC1")) {
try (CallbackStore callback1 =
SimDeviceSim.registerDeviceCreatedCallback(
- "testDC",
- (name, handle) -> {
- callback1Counter.addAndGet(1);
- },
- false);
+ "testDC", (name, handle) -> callback1Counter.addAndGet(1), false);
CallbackStore callback2 =
SimDeviceSim.registerDeviceCreatedCallback(
- "testDC",
- (name, handle) -> {
- callback2Counter.addAndGet(1);
- },
- true)) {
+ "testDC", (name, handle) -> callback2Counter.addAndGet(1), true)) {
assertEquals(0, callback1Counter.get(), "Callback 1 called early");
assertEquals(
1,
@@ -82,11 +74,7 @@
SimDevice dev1 = SimDevice.create("testDF1");
try (CallbackStore callback =
SimDeviceSim.registerDeviceFreedCallback(
- "testDF",
- (name, handle) -> {
- counter.addAndGet(1);
- },
- false)) {
+ "testDF", (name, handle) -> counter.addAndGet(1), false)) {
assertEquals(0, counter.get(), "Callback called early");
dev1.close();
assertEquals(1, counter.get(), "Callback called either more than once or not at all");
@@ -108,16 +96,10 @@
SimDeviceSim sim = new SimDeviceSim("testVM1");
try (CallbackStore callback1 =
sim.registerValueCreatedCallback(
- (name, handle, readonly, value) -> {
- callback1Counter.addAndGet(1);
- },
- false);
+ (name, handle, readonly, value) -> callback1Counter.addAndGet(1), false);
CallbackStore callback2 =
sim.registerValueCreatedCallback(
- (name, handle, readonly, value) -> {
- callback2Counter.addAndGet(1);
- },
- true)) {
+ (name, handle, readonly, value) -> callback2Counter.addAndGet(1), true)) {
assertEquals(0, callback1Counter.get(), "Callback 1 called early");
assertEquals(
1,
@@ -148,18 +130,10 @@
SimValue simVal = sim.getValue("v1");
try (CallbackStore callback1 =
sim.registerValueChangedCallback(
- simVal,
- (name, handle, readonly, value) -> {
- callback1Counter.addAndGet(1);
- },
- false);
+ simVal, (name, handle, readonly, value) -> callback1Counter.addAndGet(1), false);
CallbackStore callback2 =
sim.registerValueChangedCallback(
- simVal,
- (name, handle, readonly, value) -> {
- callback2Counter.addAndGet(1);
- },
- true)) {
+ simVal, (name, handle, readonly, value) -> callback2Counter.addAndGet(1), true)) {
assertEquals(0, callback1Counter.get(), "Callback 1 called early");
assertEquals(
1,
diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/smartdashboard/SendableChooserTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/smartdashboard/SendableChooserTest.java
index 07f09af..d97d54c 100644
--- a/wpilibj/src/test/java/edu/wpi/first/wpilibj/smartdashboard/SendableChooserTest.java
+++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/smartdashboard/SendableChooserTest.java
@@ -75,7 +75,7 @@
chooser.addOption(String.valueOf(i), i);
}
AtomicInteger currentVal = new AtomicInteger();
- chooser.onChange(val -> currentVal.set(val));
+ chooser.onChange(currentVal::set);
SmartDashboard.putData("changeListenerChooser", chooser);
SmartDashboard.updateValues();
diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/util/Color8BitTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/util/Color8BitTest.java
new file mode 100644
index 0000000..499ecbd
--- /dev/null
+++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/util/Color8BitTest.java
@@ -0,0 +1,65 @@
+// 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.wpilibj.util;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+
+class Color8BitTest {
+ @Test
+ void testConstructDefault() {
+ var color = new Color8Bit();
+
+ assertEquals(0, color.red);
+ assertEquals(0, color.green);
+ assertEquals(0, color.blue);
+ }
+
+ @Test
+ void testConstructFromInts() {
+ var color = new Color8Bit(255, 128, 64);
+
+ assertEquals(255, color.red);
+ assertEquals(128, color.green);
+ assertEquals(64, color.blue);
+ }
+
+ @Test
+ void testConstructFromColor() {
+ var color = new Color8Bit(new Color(255, 128, 64));
+
+ assertEquals(255, color.red);
+ assertEquals(128, color.green);
+ assertEquals(64, color.blue);
+ }
+
+ @Test
+ void testConstructFromHexString() {
+ var color = new Color8Bit("#FF8040");
+
+ assertEquals(255, color.red);
+ assertEquals(128, color.green);
+ assertEquals(64, color.blue);
+
+ // No leading #
+ assertThrows(IllegalArgumentException.class, () -> new Color8Bit("112233"));
+
+ // Too long
+ assertThrows(IllegalArgumentException.class, () -> new Color8Bit("#11223344"));
+
+ // Invalid hex characters
+ assertThrows(IllegalArgumentException.class, () -> new Color8Bit("#$$$$$$"));
+ }
+
+ @Test
+ void testToHexString() {
+ var color = new Color8Bit(255, 128, 64);
+
+ assertEquals("#FF8040", color.toHexString());
+ assertEquals("#FF8040", color.toString());
+ }
+}
diff --git a/wpilibj/src/test/java/edu/wpi/first/wpilibj/util/ColorTest.java b/wpilibj/src/test/java/edu/wpi/first/wpilibj/util/ColorTest.java
new file mode 100644
index 0000000..1b32afd
--- /dev/null
+++ b/wpilibj/src/test/java/edu/wpi/first/wpilibj/util/ColorTest.java
@@ -0,0 +1,85 @@
+// 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.wpilibj.util;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.junit.jupiter.api.Test;
+
+class ColorTest {
+ @Test
+ void testConstructDefault() {
+ var color = new Color();
+
+ assertEquals(0.0, color.red);
+ assertEquals(0.0, color.green);
+ assertEquals(0.0, color.blue);
+ }
+
+ @Test
+ void testConstructFromDoubles() {
+ {
+ var color = new Color(1.0, 0.5, 0.25);
+
+ assertEquals(1.0, color.red, 1e-2);
+ assertEquals(0.5, color.green, 1e-2);
+ assertEquals(0.25, color.blue, 1e-2);
+ }
+
+ {
+ var color = new Color(1.0, 0.0, 0.0);
+
+ // Check for exact match to ensure round-and-clamp is correct
+ assertEquals(1.0, color.red);
+ assertEquals(0.0, color.green);
+ assertEquals(0.0, color.blue);
+ }
+ }
+
+ @Test
+ void testConstructFromInts() {
+ var color = new Color(255, 128, 64);
+
+ assertEquals(1.0, color.red, 1e-2);
+ assertEquals(0.5, color.green, 1e-2);
+ assertEquals(0.25, color.blue, 1e-2);
+ }
+
+ @Test
+ void testConstructFromHexString() {
+ var color = new Color("#FF8040");
+
+ assertEquals(1.0, color.red, 1e-2);
+ assertEquals(0.5, color.green, 1e-2);
+ assertEquals(0.25, color.blue, 1e-2);
+
+ // No leading #
+ assertThrows(IllegalArgumentException.class, () -> new Color("112233"));
+
+ // Too long
+ assertThrows(IllegalArgumentException.class, () -> new Color("#11223344"));
+
+ // Invalid hex characters
+ assertThrows(IllegalArgumentException.class, () -> new Color("#$$$$$$"));
+ }
+
+ @Test
+ void testFromHSV() {
+ var color = Color.fromHSV(90, 128, 64);
+
+ assertEquals(0.125732421875, color.red);
+ assertEquals(0.251220703125, color.green);
+ assertEquals(0.251220703125, color.blue);
+ }
+
+ @Test
+ void testToHexString() {
+ var color = new Color(255, 128, 64);
+
+ assertEquals("#FF8040", color.toHexString());
+ assertEquals("#FF8040", color.toString());
+ }
+}