Squashed 'third_party/allwpilib/' changes from 83f1860047..f1a82828fe
f1a82828fe [wpiutil] Add DataLog and DataLogManager Stop() (#5860)
2a04e12c6f [apriltag] AprilTagFieldLayout: Add accessors for origin and field dimensions (#5869)
33e0089afb Cleanup usages of std::function<void(void)> (#5864)
d06fa633d5 [build] Fix protobuf generation when building with make (#5867)
049732afb8 [cscore] Make camera connection logging clearer (#5866)
87f7c19f90 [wpimath] Make InterpolatingDoubleTreeMap constructor public (#5865)
6b53ef47cf [wpimath] Don't recreate TrapezoidProfile in ProfiledPIDController calculate() (#5863)
8a3a268ae6 [commands] Add finallyDo with zero-arg lambda (#5862)
1c35d42cd0 [wpilib] Pop diagnostic for deprecated function use (#5859)
ddc8db6c26 [wpimath] Add feedforward constant constructor to ElevatorSim (#5823)
c6aff2c431 [upstream_utils] Update to LLVM 17.0.4 (#5855)
a9c5b18a39 [build] Update OpenCV to 2024-4.8.0-2 (#5854)
9540b6922d [hal] Add CAN IDs for AndyMark and Vivid Hosting (#5852)
83a7d33c47 [glass] Improve display of protobuf/struct type strings (#5850)
a4a8ad9c75 [commands] Make Java SelectCommand generic (#5849)
9eecf2a456 [build] Add CMake option to build Java sources jars (#5768)
9536a311cb [wpilib] Add support for the PS5 DualSense controller (#5257)
8d5e6737fc [wpilibc] SolenoidSim: Add virtual destructor (#5848)
07e13d60a2 [ntcore] Fix write_impl (#5847)
1713386869 [wpiutil] ProtobufMessageDatabase: Fix out-of-order Add() rebuild (#5845)
35472f5fc9 [ntcore] Fix a use-after-free in client close (#5844)
ed168b522c [ntcore] Disable buf pool when asan is enabled (#5843)
3e7ba2cc6f [wpinet] WebSocket: Fix write behavior (#5841)
80c47da237 [sim] Disable the robot program when DS disconnects (#5818)
abe1cec90c [wpilib] Update Usage Reporting ResourceType from NI Libraries (#5842)
cdf981abba [glass] Fix position of data type in NT view (#5840)
04dcd80adb [build] Publish unit tests for examples (#5838)
49920234ac [build] Fix checkstyle rules to allow Windows paths (#5839)
366b715942 [wpilib] Fix SendableChooser test (#5835)
3ba501f947 [commands] Java: Fix CommandXboxController.leftTrigger() parameter order (#5831)
ec569a58ef [wpimath] Make KalmanTypeFilter interface public (#5830)
b91317fd36 [wpiutil] DataLog.addSchema(): Don't add into a set view (#5829)
2ab4fcbc24 [wpiutil] ProtobufMessageDatabase: Clear messages first (#5827)
98c14f1692 [wpimath] Add EKF/UKF u-y-R correct overload (#5832)
60bcdeded9 [ci] Disable java in sanitizer builds (#5833)
c87f8fd538 [commands] Add DeferredCommand (#5566)
ad80eb3a0b [ci] Update actions for comment-command (#5824)
c7d6ad5a0b [ntcore] WebSocketConnection: Use weak capture (#5822)
8a8e220792 [simgui] Add 'Invalid' option for AllianceStation (#5820)
cfc6a47f76 [sim] DS plugin: Fix off-by-one error when setting alliance station (#5819)
8efa586ace [ntcore] Don't check type string on publishing an entry (#5816)
23ea188e60 [glass] Add protobuf decode error log message (#5812)
928e87b4f4 [build] Add combined test meta-task (#5813)
63ef585d4b [wpiutil] Fix compilation of MathExtras.h on Windows with /sdl (#5809)
b03a7668f9 [build] Windows CMake/vcpkg fixes (#5807)
3f08bcde54 [hal] Fix HAL AllianceStation on rio (#5811)
196d963dc4 [ntcore] Fix off-by-one error in stream write (#5810)
f4cbcbc984 Fix typos (NFC) (#5804)
ec0f7fefb0 [myrobot] Update the myRobot JRE (#5805)
3d618bdbfd [wpiutil] Fix Java struct array unpacking (#5801)
1fa7445667 [ntcore] Check for valid client in incoming text and binary (#5799)
269b9647da [ci] Update JDK for combine step (#5794)
bee32f080e [docs] Add wpiunits to JavaDocs (#5793)
25dad5a531 [wpinet] TCPConnector_parallel: Don't use thread_local (#5791)
4a93581f1a [build] cmake: use default library type for libglassnt, libglass, wpigui, and imgui (#5797)
abb2857e03 [wpilib] Counter: Fix default distance per pulse, add distance and rate to C++ (#5796)
b14a61e1c0 [readme] Add link to QuickBuffers release page (#5795)
cf54d9ccb7 [wpiutil, ntcore] Add structured data support (#5391)
ecb7cfa9ef [wpimath] Add Exponential motion profile (#5720)
7c6fe56cf2 [ntcore] Fix crash on disconnect (#5788)
85147bf69e [wpinet] WebSocketSerializer: Fix UB (#5787)
244163acad [wpinet] uv::Stream::TryWrite(): Return 0 on EAGAIN (#5784)
820728503d [hal] Remove extra semicolon in RoboRioData (#5786)
45f307d87e [upstream_utils] Upgrade to LLVM 17.0.3 (#5785)
4ce4d63efc [wpilibj] Fix RobotBase.isSimulation() (#5783)
579007ceb3 [commands] Add requirements parameter to Commands.idle() (#5774)
3f3a169149 [wpilib] Make physics sim setState() functions public (#5779)
7501e4ac88 [wpilib] Close sim device in ADIS IMUs (#5776)
99630d2e78 [wpimath] Upgrade to EJML 0.43.1 (#5778)
02cbbc997d [wpimath] Make Vector-Vector binary operators return Vector (#5772)
ed93889e17 [examples] Fix typo in TimesliceRobot example name (#5773)
da70e4c262 [docs] Add jinja2 to CMake prerequisites (#5771)
e814595ea7 [wpimath] Add ChassisSpeeds.fromRobotRelativeSpeeds() (#5744)
f98c943445 [wpimath] LinearSystemId: Add DCMotorSystem overload (#5770)
b3eb64b0f7 [wpiutil] ct_string: Use inline namespace for literals (#5767)
7d9ba256c2 Revert "[build] Add CMake option to build Java source jars (#5756)" (#5766)
1f6492e3d8 [sysid] Update JSON library usage (#5765)
638f04f626 [wpiutil] Add protobuf to thirdparty sources (#5746)
210255bfff [wpiutil] Update json to 3.11.2 (#5680)
896772c750 [wpimath] Add DCMotor functions for Kraken X60 and Neo Vortex (#5759)
fd427f6c82 [wpimath] Fix hardcoded module count in SwerveDriveKinematics.resetHeading() (#5762)
c0b4c6cce6 [wpimath] Add overloads for Transform2d and Transform3d (#5757)
9a0aafd8ab [examples] Make swerve examples multiply desired module speeds by cosine of heading error (#5758)
1c724884ca [build] Add CMake option to build Java source jars (#5756)
5b0db6b93e [ci] Forward CI as well (#5755)
f8cbbbac12 [ci] Take 2 on passing GITHUB_REF (#5754)
b9944be09c [ci] Pass GITHUB_REF to docker container (#5753)
de5e4eda6c [build] Update apriltag, libssh, googletest for 2024 (#5752)
227e660e20 [upstream_utils] Upgrade to LLVM 17.0.2 (#5750)
36f94c9f21 [commands,romi,xrp] Add frcYear to vendordep (#5747)
741d166457 [glass] NT view: enhance array support (#5732)
1d23513945 [ntcore] Fix string array value comparison (#5745)
ff1849052e [commands] Make command scheduling order consistent (#5470)
58e8474368 [build] Disable armsimulation unit test (#5739)
fb07b0da49 [examples] Add XRP C++ Examples and Templates (#5743)
81893ad73d Run wpiformat with clang-format 17 (#5740)
faa1e665ba [wpimath] Add ElevatorFeedforward.calculate(currentV, nextV) overload (#5715)
a789632052 [build] Update to native utils 2024.3.1 (#5738)
8f60ab5182 [build] Update OpenCV to 2024-4.8.0-1 (#5737)
33243f982b [wpimath] Expand Quaternion class with additional operators (#5600)
420f2f7c80 [ntcore] Add RTT-only subprotocol (#5731)
2b63e35ded [ntcore] Fix moving outgoing queue to new period (#5735)
be939cb636 [ntcore] Fix notification of SetDefaultEntryValue (#5733)
69a54de202 [build] Update enterprise plugin (#5730)
fef03a3ff5 [commands] Clean up C++ includes after Requirements was added (#5719)
8b7c6852cf [ntcore] Networking improvements (#5659)
1d19e09ca9 [wpiutil] Set WPI_{UN}IGNORE_DEPRECATED to empty when all else fails (#5728)
58141d6eb5 [wpilib] Make BooleanEvent more consistent (#5436)
6576d9b474 [wpilib] SendableChooser: implement Sendable instead of NTSendable (#5718)
a4030c670f [build] Update to gradle 8.4, enable win arm builds (#5727)
0960f11eba [wpinet] Revert removal of uv_clock_gettime() (#5723)
cb1bd0a3be [wpiutil] Get more precise system time on Windows (#5722)
4831277ffe [wpigui] Fix loading a maximized window on second monitor (#5721)
3eb372c25a [wpiutil] SendableBuilder: Add PublishConst methods (#5158)
1fec8596a4 [ci] Fix -dirty version (#5716)
f7e47d03f3 [build] Remove unnecessary CMake config installs (#5714)
a331ed2374 [sysid] Add SysId (#5672)
8d2cbfce16 [wpiutil] DataLog: Stop logging if insufficient free space (#5699)
48facb9cef [ntcoreffi] Add DataLogManager (#5702)
aecbcb08fc [ntcore] Correctly start DataLog for existing publishers (#5703)
5e295dfbda [wpiutil] DataLog: Limit total buffer allocation (#5700)
c7c7e05d9d [ci] Unbreak combiner (#5698)
c92bad52cb [wpilib] DataLogManager: Use system time valid function (#5697)
d404af5f24 [wpilib] RobotController: Add isSystemTimeValid() (#5696)
e56f1a3632 [ci] Run combine but skip all steps (#5695)
8f5bcad244 [ci] Use sccache for cmake builds (#5692)
703dedc4a6 [ci] Upgrade get-cmake action to fix node12 deprecation warning (#5694)
c69a0d7504 [ci] Don't run example unit test that segfaults (#5693)
66358d103e Add menu items for online docs to GUI tools (#5689)
4be8384a76 [ci] Disable combine on PR builds (#5691)
90288f06a6 [ci] Fix Gradle disk space issues (#5688)
9e9583412e [wpigui] Make wpi::gui::OpenURL() fork the process first (#5687)
d4fcd80b7b [ci] Gradle: Use container only for build step (#5684)
7b70e66772 [outlineviewer] Fix thirdparty library include sorting (#5683)
5f651df5d5 [build] Clean up Gradle configs (#5685)
65b26738d5 Add CMakeSettings.json to gitignore (#5682)
d0305951ad Fix GitHub inline warnings (#5681)
e8d4a20331 [build][cmake] Fix windows tests and re-enable CI tests (#5674)
2b58bbde0b [xrp] Add Reflectance sensor and rangefinder classes (#5673)
dd5612fbee [json] Add forward definition header (#5676)
eab44534c3 [wpimath] Remove unused SmallString include (#5677)
5ab54ff760 Replace wpi::raw_istream with wpi::MemoryBuffer (#5675)
1b6ec5a95d [wpiutil] Upgrade to LLVM 17.0.1 (#5482)
07a0d22fe6 [build] Build examples in CMake CI (#5667)
97021f074a [build] Upgrade imgui and implot (#5668)
87ce1e3761 [build] Fix wpilibNewCommands CMake install (#5671)
6ef94de9b5 [wpimath] Add tests for ArmFeedforward and ElevatorFeedforward (#5663)
c395b29fb4 [wpinet] Add WebSocket::TrySendFrames() (#5607)
c4643ba047 [romi/xrp] Fix version typo in vendordep json (#5664)
51dcb8b55a [examples] Make Romi/XRP Examples use appropriate vendordeps (#5665)
daf7702007 [build] Test each example in a new environment (#5662)
e67df8c180 [wpilib] Const-qualify EncoderSim getters (#5660)
7be290147c [wpiutil] Refactor SpanMatcher and TestPrinters from ntcore (#5658)
9fe258427a [commands] Add proxy factory to Commands (#5603)
633c5a8a22 [commands] Add C++ Requirements struct (#5504)
b265a68eea [commands] Add interruptor parameter to onCommandInterrupt callbacks (#5461)
e93c233d60 [ntcore] Compute Value memory size when creating value (#5657)
5383589f99 [wpinet] uv::Request: Return shared_ptr from Release() (#5656)
40b552be4a [wpinet] uv::Stream: Return error from TryWrite() (#5655)
202a75fe08 [wpinet] RequestImpl: Avoid infinite loop in shared_from_this() (#5654)
8896515eb7 [wpinet] uv::Buffer: Add bytes() accessor (#5653)
ae59a2fba2 [wpinet] uv::Error: Change default error to 0 (#5652)
3b51ecc35b [wpiutil] SpanExtras: Add take_back and take_front (#5651)
17f1062885 Replace std::snprintf() with wpi::format_to_n_c_str() (#5645)
bb39900353 [romi/xrp] Add Romi and XRP Vendordeps (#5644)
cb99517838 [build] cmake: Use default install location on windows for dlls (#5580)
25b0622d4c [build] Add Windows CMake CI (#5516)
34e7849605 Add warning to development builds instructions (NFC) (#5646)
e9e611c9d8 [cameraserver] Remove CameraServer.SetSize() (#5650)
94f58cc536 [wpilib] Remove Compressor.Enabled() (#5649)
4da5aee88a [wpimath] Remove SlewRateLimiter 2 argument constructor (#5648)
2e3ddf5502 Update versions in development builds instructions to 2024 (#5647)
19a8850fb1 [examples] Add TimesliceRobot templates (#3683)
9047682202 [sim] Add XRP-specific plugin (#5631)
575348b81c [wpilib] Use IsSimulation() consistently (#3534)
12e2043b77 [wpilib] Clean up Notifier (#5630)
4bac4dd0f4 [wpimath] Move PIDController from frc2 to frc namespace (#5640)
494cfd78c1 [wpiutil] Fix deprecation warning in LLVM for C++23 (#5642)
43a727e868 [apriltag] Make loadAprilTagFieldLayout throw an unchecked exception instead (#5629)
ad4b017321 [ci] Use Ninja for faster builds (#5626)
4f2114d6f5 Fix warnings from GCC 13 release build (#5637)
e7e927fe26 [build] Also compress debug info for CMake RelWithDebInfo build type (#5638)
205a40c895 [build] Specify zlib for debug info compression (#5636)
707444f000 [apriltag] Suppress -Wtype-limits warning in asserts from GCC 13 (#5635)
3b79cb6ed3 [commands] Revert SubsystemBase deprecation/removal (#5634)
bc7f23a632 [build] Compress Linux debug info (#5633)
57b2d6f254 [build] Update to image 2024 v1.0 (#5625)
339ef1ea39 [wpilib] DataLogManager: Warn user if logging to RoboRIO 1 internal storage (#5617)
7a9a901a73 [build] Fix cmake config files (#5624)
298f8a6e33 [wpilib] Add Mechanism2d tests and make Java impl match C++ (#5527)
d7ef817bae [apriltag] Update apriltag library (#5619)
c3fb31fd0e [docs] Switch to Java 17 api docs (#5613)
bd64f81cf9 [build] Run Google tests in release mode in CI (#5615)
66e6bd81ea [wpimath] Cleanup wpimath/algorithms.md (NFC) (#5621)
4fa56fd884 [build] Add missing find_dependency call (#5623)
f63d958995 [build] Update to native utils 2024.2.0 (#5601)
a9ab08f48b [wpimath] Rename ChassisSpeeds.fromDiscreteSpeeds() to discretize() (#5616)
8e05983a4a [wpimath] Add math docs to plant inversion feedforward internals (NFC) (#5618)
3a33ce918b [ntcore] Add missing StringMap include (#5620)
a6157f184d [wpiutil] timestamp: Add ShutdownNowRio (#5610)
e9f612f581 [build] Guard policy setting for CMake versions below 3.24 (#5612)
1a6df6fec6 [wpimath] Fix DARE Q decomposition (#5611)
9b3f7fb548 [build] Exclude IntelliJ folders from spotless XML (#5602)
814f18c7f5 [wpimath] Fix computation of C for DARE (A, C) detectability check (#5609)
ac23f92451 [hal] Add GetTeamNumber (#5596)
a750bee54d [wpimath] Use std::norm() in IsStabilizable() (#5599)
8e2465f8a0 [wpimath] Add arithmetic functions to wheel speeds classes (#5465)
10d4f5b5df [wpimath] Clean up notation in DARE precondition docs (#5595)
b2dd59450b [hal] Fix unfinished/incorrect GetCPUTemp functions (#5598)
99f66b1e24 [wpimath] Replace frc/EigenCore.h typedefs with Eigen's where possible (#5597)
383289bc4b [build] Make custom CMake macros use lowercase (#5594)
45e7720ec1 [build] Add error message when downloading files in CMake (#5593)
4e0d785356 [wpimath] ChassisSpeeds: document that values aren't relative to the robot (NFC) (#5551)
3c04580a57 [commands] ProxyCommand: Use inner command name in unique_ptr constructor (#5570)
cf19102c4a [commands] SelectCommand: Fix leakage and multiple composition bug (#5571)
171375f440 [ntcoreffi] Link to NI libraries (#5589)
89add5d05b Disable flaky tests (#5591)
a8d4b162ab [ntcore] Remove RPC manual tests (#5590)
39a73b5b58 [commands] C++: Add CommandPtr supplier constructor to ProxyCommand (#5572)
36d514eae7 [commands] Refactor C++ ScheduleCommand to use SmallSet (#5568)
52297ffe29 [commands] Add idle command (#5555)
67043a8eeb [wpimath] Add angular jerk unit (#5582)
51b0fb1492 [wpimath] Fix incorrect header inclusion in angular_acceleration.h (#5587)
b7657a8e28 [wpimath] Split WPIMathJNI into logical chunks (#5552)
ea17f90f87 [build] Fix tool builds with multiple arm platforms installed (#5586)
f1d7b05723 [wpimath] Clean up unit formatter (#5584)
d7264ff597 Replace wpi::errs() usage with fmtlib (#5560)
ab3bf39e0e [wpiutil] Upgrade to fmt 10.1.1 (#5585)
165ebe4c79 Upgrade to fmt 10.1.0 (#5326)
8e2a7fd306 Include thirdparty libraries with angle brackets (#5578)
e322ab8e46 [wpimath] Fix docs for DARE ABQRN stabilizability check (NFC) (#5579)
360fb835f4 [upstream_utils] Handle edge case in filename matches (#5576)
9d86624c00 [build] Fix CMake configure warnings (#5577)
969979d6c7 [wpiutil] Update to foonathan memory 0.7-3 (#5573)
0d2d989e84 [wpimath] Update to gcem 1.17.0 (#5575)
cf86af7166 [wpiutil] Update to mpack 1.1.1 (#5574)
a0c029a35b [commands] Fix dangling SelectCommand documentation (NFC) (#5567)
349141b91b [upstream_utils] Document adding a patch (NFC) (#5432)
7889b35b67 [wpimath] Add RamseteController comparison to LTV controller docs (NFC) (#5559)
b3ef536677 [build] Ignore nt/sim json files in spotless (#5565)
ed895815b5 [build] Compile Java with UTF-8 encoding (#5564)
2e4ad35e36 [wpiutil] jni_util: Add JSpan and CriticalJSpan (#5554)
8f3d6a1d4b [wpimath] Remove discretizeAQTaylor() (#5562)
7c20fa1b18 [wpimath] Refactor DARE tests to reduce RAM usage at compile time (#5557)
89e738262c [ntcore] Limit buffer pool size to 64KB per connection (#5485)
96f7fa662e Upgrade Maven dependencies (#5553)
7a2d336d52 [wpinet] Leak multicast handles during windows shutdown (#5550)
f9e2757d8f [wpimath] Use JDoubleArrayRef in all JNI functions (#5546)
0cf6e37dc1 [wpimath] Make LTV controller constructors use faster DARE solver (#5543)
6953a303b3 [build] Fix the windows build with fmt (#5544)
7a37e3a496 [wpimath] Correct Rotation3d::RotateBy doc comment (NFC) (#5541)
186b409e16 [wpimath] Remove internal Eigen header include (#5539)
03764dfe93 [wpimath] Add static matrix support to DARE solver (#5536)
394cfeadbd [wpimath] Use SDA algorithm instead of SSCA for DARE solver (#5526)
a4b7fde767 [wpilib] Add mechanism specific SetState overloads to physics sims (#5534)
8121566258 [wpimath] Fix CoordinateSystem.convert() Transform3d overload (#5532)
b542e01a0b [glass] Fix array crash when clearing existing workspace (#5535)
e2e1b763b2 [wpigui] Fix PFD file dialogs not closing after window closing (#5530)
86d7bbc4e4 [examples] Add Java Examples and Templates for the XRP (#5529)
e8b5d44752 [wpimath] Make Java Quaternion use doubles instead of Vector (#5525)
38c198fa64 [myRobot] Add apriltags to myRobot build (#5528)
00450c3548 [wpimath] Upgrade to EJML 0.42 (#5531)
faf3cecd83 [wpimath] Don't copy Matrix and underlying storage in VecBuilder (#5524)
6b896a38dc [build] Don't enforce WITH_FLAT_INSTALL with MSVC (part 2) (#5517)
c01814b80e [wpiutil] Add C API for DataLog (#5509)
b5bd0771eb [wpimath] Document extrinsic vs intrinsic rotations (NFC) (#5508)
84ed8aec05 [build] Don't enforce WITH_FLAT_INSTALL with MSVC (#5515)
999f677d8c [ntcoreffi] Add WPI_Impl_SetupNowRio to exported symbols (#5510)
338f37d302 Fix header sorting of libssh (#5507)
75cbd9d6d0 [glass] Add background color selector to glass plots (#5506)
e2c190487b [examples] Add flywheel bang-bang controller example (#4071)
c52dad609e [wpinet] WebSocket: Send pong in response to ping (#5498)
e2d17a24a6 [hal] Expose power rail disable and cpu temp functionality (#5477)
3ad5d2e42d [hal,wpiutil] Use HMB for FPGA Timestamps (#5499)
b46a872494 [ntcore] Remove pImpl from implementation (#5480)
d8c59ccc71 [wpimath] Add tests for MathUtil clamp() and interpolate() (#5501)
0552c8621d [glass,ov] Improve Glass and OutlineViewer title bar message (#5502)
90e37a129f [wpiutil,wpimath] Add generic InterpolatingTreeMap (#5372)
d83a6edc20 [wpilib] Update GetMatchTime docs and units (#5232)
6db2c42966 [wpimath] Trajectory: Throw on empty lists of States (#5497)
21439b606c [wpimath] Disallow LTV controller max velocities above 15 m/s (#5495)
7496e0d208 [ntcore] Value: More efficiently store arrays (#5484)
0c93aded8a [wpimath] Change kinematics.ToTwist2d(end - start) to kinematics.ToTwist2d(start, end) (#5493)
815a8403e5 [wpimath] Give infeasible trajectory constraints a better exception message (#5492)
35a8b129d9 [wpimath] Add RotateBy() function to pose classes (#5491)
26d6e68c8f [upstream_utils] Add GCEM to CI (#5483)
6aa469ae45 [wpilib] Document how to create LinearSystem object for physics sim classes (NFC) (#5488)
a01b6467d3 [wpimath] Link to docs on LQR and KF tolerances (#5486)
d814f1d123 [wpimath] Fix copy-paste error from Pose2d docs (NFC) (#5490)
98f074b072 [wpimath] Add folder prefix to geometry includes (#5489)
e9858c10e9 [glass] Add tooltips for NT settings (#5476)
12dda24f06 [examples] Fix C robot template not correctly looping (#5474)
fc75d31755 [apriltag] Update apriltaglib (#5475)
a95994fff6 [wpiutil] timestamp: Call FPGA functions directly (#5235)
2ba8fbb6f4 [wpimath] Improve documentation for SwerveModulePosition::operator- (#5468)
b8cdf97621 [build] Prepare for Windows arm64 builds (#5390)
552f4b76b5 [wpimath] Add FOC-enabled Falcon constants to the DCMotor class (#5469)
1938251436 [examples] Add Feedforward to ElevatorProfiledPid (#5300)
873c2a6c10 [examples] Update ElevatorTrapezoidProfile example (#5466)
99b88be4f3 [wpilib] Reduce usage of NTSendable (#5434)
d125711023 [hal] Fix Java REVPH faults bitfield (take 2) (#5464)
c3fab7f1f2 [ntcore] Don't update timestamp when value is unchanged (#5356)
5ec7f18bdc [wpilib] EventLoop docs: Remove BooleanEvent references (NFC) (#5463)
c065ae1fcf [wpiunits] Add subproject for a Java typesafe unit system (#5371)
44acca7c00 [wpiutil] Add ClassPreloader (#5365)
88b11832ec [hal] Fix Java REVPH faults bitfield (#5148)
fb57d82e52 [ntcore] Enhance Java raw value support
3a6e40a44b [wpiutil] Enhance DataLog Java raw value support
8dae5af271 [wpiutil] Add compile-time string utilities (ct_string) (#5462)
fc56f8049a [wpilib] DriverStation: Change alliance station to use optional (#5229)
ef155438bd [build] Consume libuv via cmake config instead of via pkg-config (#5438)
86e91e6724 [wpimath] Refactor TrapezoidProfile API (#5457)
72a4543493 [wpilib] DutyCycleEncoderSim: Expand API (#5443)
657338715d [wpimath] Add ChassisSpeeds method to fix drifting during compound swerve drive maneuvers (#5425)
1af224c21b Add missing <functional> includes (#5459)
0b91ca6d5a [wpilib] SendableChooser: Add onChange listener (#5458)
6f7cdd460e [wpimath] Pose3d: Switch to JNI for exp and log (#5444)
c69e34c80c [wpimath] ChassisSpeeds: Add arithmetic functions (#5293)
335e7dd89d [wpilib] Simulation: Add ctor parameter to set starting state of mechanism sims (#5288)
14f30752ab [wpilib] Deprecate Accelerometer and Gyro interfaces (#5445)
70b60e3a74 [commands] Trigger: Fix method names in requireNonNullParam (#5454)
593767c8c7 [wpimath] Improve Euler angle calculations in gimbal lock (#5437)
daf022d3da [build] Make devImplementation inherit from implementation (#5450)
9b8d90b852 [examples] Convert the unitless joystick inputs to actual physical units (#5451)
1f6428ab63 [ntcore] Fix undefined comparison behavior when array is empty (#5448)
17eb9161cd Update code owners for removal of old commands (#5447)
3c4b58ae1e [wpinet] Upgrade to libuv 1.46.0 (#5446)
aaea85ff16 [commands] Merge CommandBase into Command and SubsystemBase into Subsystem (#5392)
7ac932996a [ci] Use PAT for workflow dispatch (#5442)
efe1987e8b [ci] Trigger pages repo workflow (#5441)
828bc5276f [wpiutil] Upgrade to LLVM 16.0.6 (#5435)
701df9eb87 [ci] Change documentation publish to single-commit (#5440)
e5452e3f69 [wpiutil] Add WPICleaner and an example how to use it (#4850)
7a099cb02a [commands] Remove deprecated classes and functions (#5409)
b250a03944 [wpilib] Add function to wait for DS Connection (#5230)
a6463ed761 [wpiutil] Fix unused variable warning in release build (#5430)
f031513470 [ntcore] NetworkTable::GetSubTables(): Remove duplicates (#5076)
f8e74e2f7c [hal] Unify PWM simulation Speed, Position, and Raw (#5277)
fd5699b240 Remove references to Drake (#5427)
e2d385d80a [build] cmake: Respect USE_SYSTEM_FMTLIB (#5429)
d37f990ce3 [hal] Fix HAL Relay/Main doc module (NFC) (#5422)
a7a8b874ac [docs] Expand HAL_ENUM in doxygen docs (#5421)
3a61deedde [wpimath] Rotation2d: Only use gcem::hypot when constexpr evaluated (#5419)
96145de7db [examples] Fix formatting (NFC) (#5420)
fffe6a7b9a [examples] Improve Pneumatics example coverage in Solenoid and RapidReactCmdBot examples (#4998)
6b5817836d [wpimath] Add tolerance for some tests (#5416)
3233883f3e [cscore] Fix warnings on macos arm (#5415)
c4fc21838f [commands] Add ConditionalCommand getInterruptionBehavior (#5161)
89fc51f0d4 Add tests for SendableChooser and Command Sendable functionality (#5179)
663bf25aaf [docs] Generate docs for symbols in __cplusplus (#5412)
fe32127ea8 [command] Clean up Command doc comments (NFC) (#5321)
c1a01569b4 [wpilib][hal] PWM Raw using microseconds (#5283)
1fca519fb4 [wpiutil] Remove remnants of ghc fs and tcb_span libraries (#5411)
90602cc135 [github] Update issue template to collect more project info (#5090)
34412ac57e [build] Exclude files in bin from Spotless (#5410)
61aa60f0e3 [wpilib] Add robot callback that is called when the DS is initially connected (#5231)
ebae341a91 [commands] Add test for subsystem registration and periodic (#5408)
5d3a133f9f Remove spaces in NOLINT comments (#5407)
3a0e484691 [wpimath] Fix clang-tidy warnings (#5403)
eb3810c765 [wpiutil] Fix clang-tidy warnings (#5406)
c4dc697192 [hal] WS Simulation: Add message filtering capability (#5395)
0eccc3f247 [ntcore] Fix clang-tidy warnings (#5405)
f4dda4bac0 [hal] Add javadocs for JNI (NFC) (#5298)
1c20c69793 [cscore] Fix clang-tidy warnings (#5404)
1501607e48 [commands] Fix clang-tidy warnings (#5402)
991f4b0f62 [wpimath] PIDController: Add IZone (#5315)
f5b0d1484b [wpimath] Add isNear method to MathUtil (#5353)
2ce248f66c [hal] Fix clang-tidy warnings (#5401)
5fc4aee2d2 [wpimath] SwerveDriveKinematics: Rename currentChassisSpeed to desiredChassisSpeed (#5393)
50b90ceb54 [wpimath] SwerveDriveKinematics: Add reset method (#5398)
316cd2a453 [commands] Notify DriverStationSim in CommandTestBaseWithParam (#5400)
d4ea5fa902 [cscore] VideoMode: Add equals override (Java) (#5397)
d6bd72d738 [wpimath] ProfiledPIDController: Add getConstraints (#5399)
25ad5017a9 [wpimath] Refactor kinematics, odometry, and pose estimator (#5355)
5c2addda0f [doc] Add missing pneumatics docs (NFC) (#5389)
c3e04a6ea2 Fix loading tests on macos 12 (#5388)
d5ed9fb859 [wpimath] Create separate archive with just units headers (#5383)
901ab693d4 [wpimath] Use UtilityClassTest for more utility classes (#5384)
9d53231b01 [wpilib] DataLogManager: Add warning for low storage space (#5364)
d466933963 [wpiutil] Group doxygen into MPack module (#5380)
652d1c44e3 [wpiutil] Upgrade to macOS 12 to remove concept shims (#5379)
6414be0e5d [wpimath] Group units doxygen modules (#5382)
7ab5800487 [wpiutil] Fix docs typo in SmallVector (#5381)
59905ea721 Replace WPI_DEPRECATED() macro with [[deprecated]] attribute (#5373)
753cb49a5e [ntcore] Fix doxygen module in generated C types (NFC) (#5374)
1c00a52b67 [hal] Expose CAN timestamp base clock (#5357)
91cbcea841 Replace SFINAE with concepts (#5361)
d57d1a4598 [wpimath] Remove unnecessary template argument from unit formatter (#5367)
5acc5e22aa [wpimath] Only compute eigenvalues with EigenSolvers (#5369)
d3c9316a97 extend shuffleboard test timeout (#5377)
1ea868081a [ci] Fix /format command (#5376)
5fac18ff4a Update formatting to clang-format 16 (#5370)
a94a998002 [wpimath] Generalize Eigen formatter (#5360)
125f6ea101 [wpimath] Make SwerveDriveKinematics::ToChassisSpeeds() take const-ref argument (#5363)
51066a5a8a [wpimath] Move unit formatters into units library (#5358)
282c032b60 [wpilibc] Add unit-aware Joystick.GetDirection() (#5319)
073d19cb69 [build] Fix CMake warning (#5359)
01490fc77b [wpiutil] DataLog: Add documentation for append methods (NFC) (#5348)
c9b612c986 [wpilibcExamples] Make C++ state-space elevator KF and LQR match Java (#5346)
eed1e6e3cb [wpimath] Replace DiscretizeAQTaylor() with DiscretizeAQ() (#5344)
c976f40364 [readme] Document how to run examples in simulation (#5340)
4d28bdc19e [ci] Update Github Pages deploy action parameters (#5343)
e0f851871f [ci] Fix github pages deploy version (#5342)
063c8cbedc Run wpiformat (NFC) (#5341)
96e41c0447 [ci] Update deploy and sshagent actions (#5338)
fd294bdd71 [build] Fix compilation with GCC 13 (#5322)
d223e4040b [dlt] Add delete without download functionality (#5329)
abc19bcb43 [upstream_utils] Zero out commit hashes and show 40 digits in index hashes (#5336)
e909f2e687 [build] Update gradle cache repo name (#5334)
52bd5b972d [wpimath] Rewrite DARE solver (#5328)
3876a2523a [wpimath] Remove unused MatrixImpl() function (#5330)
c82fcb1975 [wpiutil] Add reflection based cleanup helper (#4919)
15ba95df7e [wpiutil] Use std::filesystem (#4941)
77c2124fc5 [wpimath] Remove Eigen's custom STL types (#4945)
27fb47ab10 [glass] Field2D: Embed standard field images (#5159)
102e4f2566 [wpilib] Remove deprecated and broken SPI methods (#5249)
463a90f1df [wpilib, hal] Add function to read the RSL state (#5312)
7a90475eec [wpilib] Update RobotBase documentation (NFC) (#5320)
218cfea16b [wpilib] DutyCycleEncoder: Fix reset behavior (#5287)
91392823ff [build] Update to gradle 8.1 (#5303)
258b7cc48b [wpilibj] Filesystem.getDeployDirectory(): Strip JNI path from user.dir (#5317)
26cc43bee1 [wpilib] Add documentation to SPI mode enum (NFC) (#5324)
ac4da9b1cb [hal] Add HAL docs for Addressable LED (NFC) (#5304)
21d4244cf7 [wpimath] Fix DCMotor docs (NFC) (#5309)
1dff81bea7 [hal] Miscellaneous HAL doc fixes (NFC) (#5306)
7ce75574bf [wpimath] Upgrade to Drake v1.15.0 (#5310)
576bd646ae [hal] Add CANManufacturer for Redux Robotics (#5305)
ee3b4621e5 [commands] Add onlyWhile and onlyIf (#5291)
40ca094686 [commands] Fix RepeatCommand calling end() twice (#5261)
9cbeb841f5 [rtns] Match imaging tool capitalization (#5265)
a63d06ff77 [examples] Add constants to java gearsbot example (#5248)
b6c43322a3 [wpilibc] XboxController: Add return tag to docs (NFC) (#5246)
5162d0001c [hal] Fix and document addressable LED timings (#5272)
90fabe9651 [wpilibj] Use method references in drive class initSendable() (#5251)
24828afd11 [wpimath] Fix desaturateWheelSpeeds to account for negative speeds (#5269)
e099948a77 [wpimath] Clean up rank notation in docs (NFC) (#5274)
fd2d8cb9c1 [hal] Use std::log2() for base-2 logarithm (#5278)
ba8c64bcff [wpimath] Fix misspelled Javadoc parameters in pose estimators (NFC) (#5292)
f53c6813d5 [wpimath] Patch Eigen warnings (#5290)
663703d370 [gitattributes] Mark json files as lf text files (#5256)
aa34aacf6e [wpilib] Shuffleboard: Keep duplicates on SelectTab() (#5198)
63512bbbb8 [wpimath] Fix potential divide-by-zero in RKDP (#5242)
9227b2166e [wpilibj] DriverStation: Fix joystick data logs (#5240)
fbf92e9190 [wpinet] ParallelTcpConnector: don't connect to duplicate addresses (#5169)
2108a61362 [ntcore] NT4 client: close timed-out connections (#5175)
0a66479693 [ntcore] Optimize scan of outgoing messages (#5227)
b510c17ef6 [hal] Fix RobotController.getComments() mishandling quotes inside the comments string (#5197)
e7a7eb2e93 [commands] WaitCommand: Remove subclass doc note (NFC) (#5200)
a465f2d8f0 [examples] Shuffleboard: Correct parameter order (#5204)
a3364422fa LICENSE.md: Bump year to 2023 (#5195)
df3242a40a [wpimath] Fix NaN in C++ MakeCostMatrix() that takes an array (#5194)
00abb8c1e0 [commands] RamseteCommand: default-initialize m_prevSpeeds (#5188)
c886273fd7 [wpilibj] DutyCycleEncoder.setDistancePerRotation(): fix simulation (#5147)
53b5fd2ace [ntcore] Use int64 for datalog type string (#5186)
56b758320f [wpilib] DataLogManager: increase time for datetime to be valid (#5185)
08f298e4cd [wpimath] Fix Pose3d log returning Twist3d NaN for theta between 1E-8 and 1E-7 (#5168)
6d0c5b19db [commands] CommandScheduler.isComposed: Remove incorrect throws clause (NFC) (#5183)
0d22cf5ff7 [wpilib] Fix enableLiveWindowInTest crashing in disabled (#5173)
32ec5b3f75 [wpilib] Add isTestEnabled and minor docs cleanup (#5172)
e5c4c6b1a7 [wpimath] Fix invalid iterator access in TimeInterpolatableBuffer (#5138)
099d048d9e [wpimath] Fix Pose3d log returning Twist3d NaN for theta between 1E-9 and 1E-8 (#5143)
4af84a1c12 Fix Typos (NFC) (#5137)
ce3686b80d [wpimath] Check LTV controller max velocity precondition (#5142)
4b0eecaee0 [commands] Subsystem: Add default command removal method (#5064)
edf4ded412 [wpilib] PH: Revert to 5V rail being fixed 5V (#5122)
4c46b6aff9 [wpilibc] Fix DataLogManager crash on exit in sim (#5125)
490ca4a68a [wpilibc] Fix XboxController::GetBackButton doc (NFC) (#5131)
cbb5b0b802 [hal] Simulation: Fix REV PH solenoids 8+ (#5132)
bb7053d9ee [hal] Fix HAL_GetRuntimeType being slow on the roboRIO (#5130)
9efed9a533 Update .clang-format to c++20 (#5121)
dbbfe1aed2 [wpilib] Use PH voltage to calc Analog pressure switch threshold (#5115)
de65a135c3 [wpilib] DutyCycleEncoderSim: Add channel number constructor (#5118)
3e9788cdff [docs] Strip path from generated NT docs (#5119)
ecb072724d [ntcore] Client::Disconnect(): actually close connection (#5113)
0d462a4561 [glass] NT view: Change string/string array to quoted (#5111)
ba37986561 [ntcore] NetworkClient::Disconnect: Add null check (#5112)
25ab9cda92 [glass,ov] Provide menu item to create topic from root (#5110)
2f6251d4a6 [glass] Set default value when publishing new topic (#5109)
e9a7bed988 [wpimath] Add timestamp getter to MathShared (#5091)
9cc14bbb43 [ntcore] Add stress test to dev executable (#5107)
8068369542 [wpinet] uv: Stop creating handles when closing loop (#5102)
805c837a42 [ntcore] Fix use-after-free in server (#5101)
fd18577ba0 [commands] Improve documentation of addRequirements (NFC) (#5103)
74dea9f05e [wpimath] Fix exception for empty pose buffer in pose estimators (#5106)
9eef79d638 [wpilib] PneumaticHub: Document range of enableCompressorAnalog (NFC) (#5099)
843574a810 [ntcore] Use wpi::Now instead of loop time for transmit time
226ef35212 [wpinet] WebSocket: Reduce server send frame overhead
b30664d630 [ntcore] Reduce initial connection overhead
804e5ce236 [examples] MecanumDrive: Fix axis comment in C++ example (NFC) (#5096)
49af88f2bb [examples] ArmSimulation: Fix flaky test (#5093)
d56314f866 [wpiutil] Disable mock time on the Rio (#5092)
43975ac7cc [examples] ArmSimulation, ElevatorSimulation: Extract mechanism to class (#5052)
5483464158 [examples, templates] Improve descriptions (NFC) (#5051)
785e7dd85c [wpilibc] SendableChooser: static_assert copy- and default-constructibility (#5078)
e57ded8c39 [ntcore] Improve disconnect error reporting (#5085)
01f0394419 [wpinet] Revert WebSocket: When Close() is called, call closed immediately (#5084)
59be120982 [wpimath] Fix Pose3d exp()/log() and add rotation vector constructor to Rotation3d (#5072)
37f065032f [wpilib] Refactor TimedRobot tests (#5068)
22a170bee7 [wpilib] Add Notifier test (#5070)
2f310a748c [wpimath] Fix DCMotor.getSpeed() (#5061)
b43ec87f57 [wpilib] ElevatorSim: Fix WouldHitLimit methods (#5057)
19267bef0c [ntcore] Output warning on property set on unpublished topic (#5059)
84cbd48d84 [ntcore] Handle excludeSelf on SetDefault (#5058)
1f35750865 [cameraserver] Add GetInstance() to all functions (#5054)
8230fc631d [wpilib] Revert throw on nonexistent SimDevice name in SimDeviceSim (#5053)
b879a6f8c6 [wpinet] WebSocket: When Close() is called, call closed immediately (#5047)
49459d3e45 [ntcore] Change wire timeout to fixed 1 second (#5048)
4079eabe9b [wpimath] Discard stale pose estimates (#5045)
fe5d226a19 [glass] Fix option for debug-level NT logging (#5049)
b7535252c2 [ntcore] Don't leak buffers in rare WS shutdown case (#5046)
b61ac6db33 [ntcore] Add client disconnect function (#5022)
7b828ce84f [wpimath] Add nearest to Pose2d and Translation2d (#4882)
08a536291b [examples] Improvements to Elevator Simulation Example (#4937)
193a10d020 [wpigui] Limit frame rate to 120 fps by default (#5030)
7867bbde0e [wpilib] Clarify DS functions provided by FMS (NFC) (#5043)
fa7c01b598 [glass] Add option for debug-level NT logging (#5007)
2b81610248 [wpiutil] Add msgpack to datalog Python example (#5032)
a4a369b8da CONTRIBUTING.md: Add unicodeit CLI to math docs guidelines (#5031)
d991f6e435 [wpilib] Throw on nonexistent SimDevice name in SimDeviceSim constructor (#5041)
a27a047ae8 [hal] Check for null in getSimDeviceName JNI (#5038)
2f96cae31a [examples] Hatchbots: Add telemetry (#5011)
83ef8f9658 [simulation] GUI: Fix buffer overflow in joystick axes copy (#5036)
4054893669 [commands] Fix C++ Select() factory (#5024)
f75acd11ce [commands] Use Timer.restart() (#5023)
8bf67b1b33 [wpimath] PIDController::Calculate(double, double): update setpoint flag (#5021)
49bb1358d8 [wpiutil] MemoryBuffer: Fix GetMemoryBufferForStream (#5017)
9c4c07c0f9 [wpiutil] Remove NDEBUG check for debug-level logging (#5018)
1a47cc2e86 [ntcore] Use full handle when subscribing (#5013)
7cd30cffbc Ignore networktables.json (#5006)
92aecab2ef [commands] Command controllers are not subclasses (NFC) (#5000)
8785bba080 [ntcore] Special-case default timestamps (#5003)
9e5b7b8040 [ntcore] Handle topicsonly followed by value subscribe (#4991)
917906530a [wpilib] Add Timer::Restart() (#4963)
00aa66e4fd [wpimath] Remove extraneous assignments from DiscretizeAB() (#4967)
893320544a [examples] C++ RamseteCommand: Fix units (#4954)
b95d0e060d [wpilib] XboxController: Fix docs discrepancy (NFC) (#4993)
008232b43c [ntcore] Write empty persistent file if none found (#4996)
522be348f4 [examples] Rewrite tags (NFC) (#4961)
d48a83dee2 [wpimath] Update Wikipedia links for quaternion to Euler angle conversion (NFC) (#4995)
504fa22143 [wpimath] Workaround intellisense Eigen issue (#4992)
b2b25bf09f [commands] Fix docs inconsistency for toggleOnFalse(Command) (NFC) (#4978)
ce3dc4eb3b [hal] Properly use control word that is in sync with DS data (#4989)
1ea48caa7d [wpilib] Fix C++ ADXRS450 and Java SPI gyro defs (#4988)
fb101925a7 [build] Include wpimathjni in commands binaries (#4981)
657951f6dd [starter] Add a process starter for use by the installer for launching tools (#4931)
a60ca9d71c [examples] Update AprilTag field load API usage (#4975)
f8a45f1558 [wpimath] Remove print statements from tests (#4977)
ecba8b99a8 [examples] Fix swapped arguments in MecanumControllerCommand example (#4976)
e95e88fdf9 [examples] Add comment to drivedistanceoffboard example (#4877)
371d15dec3 [examples] Add Computer Vision Pose Estimation and Latency Compensation Example (#4901)
cb9b8938af [sim] Enable docking in the GUI (#4960)
3b084ecbe0 [apriltag] AprilTagFieldLayout: Improve API shape for loading builtin JSONs (#4949)
27ba096ea1 [wpilib] Fix MOI calculation error in SingleJointedArmSim (#4968)
42c997a3c4 [wpimath] Fix Pose3d exponential and clean up Pose3d logarithm (#4970)
5f1a025f27 [wpilibj] Fix typo in MecanumDrive docs (NFC) (#4969)
0ebf79b54c [wpimath] Fix typo in Pose3d::Exp() docs (NFC) (#4966)
a8c465f3fb [wpimath] HolonomicDriveController: Add getters for the controllers (#4948)
a7b1ab683d [wpilibc] Add unit test for fast deconstruction of GenericHID (#4953)
bd6479dc29 [build] Add Spotless for JSON (#4956)
5cb0340a8c [hal, wpilib] Load joystick values upon code initialization (#4950)
ab0e8c37a7 [readme] Update build requirements (NFC) (#4947)
b74ac1c645 [build] Add apriltag to C++ cmake example builds (#4944)
cf1a411acf [examples] Add example programs for AprilTags detection (#4932)
1e05b21ab5 [wpimath] Fix PID atSetpoint to not return true prematurely (#4906)
e5a6197633 [wpimath] Fix SwerveDriveKinematics not initializing a new array each time (#4942)
039edcc23f [ntcore] Queue current value on subscriber creation (#4938)
f7f19207e0 [wpimath] Allow multiple vision measurements from same timestamp (#4917)
befd12911c [commands] Delete UB-causing rvalue variants of CommandPtr methods (#4923)
34519de60a [commands] Fix spacing in command composition exception (#4924)
dc4355c031 [hal] Add handle constructor and name getters for sim devices (#4925)
53d8d33bca [hal, wpilibj] Add missing distance per pulse functions to EncoderSim (#4928)
530ae40614 [apriltag] Explain what April tag poses represent (NFC) (#4930)
79f565191e [examples] DigitalCommunication, I2CCommunication: Add tests (#4865)
2cd9be413f [wpilib, examples] Cleanup PotentiometerPID, Ultrasonic, UltrasonicPID examples (#4893)
babb0c1fcf [apriltag] Add 2023 field layout JSON (#4912)
330ba45f9c [wpimath] Fix swerve kinematics util classes equals function (#4907)
51272ef6b3 [fieldImages] Add 2023 field (#4915)
0d105ab771 [commands] Deduplicate command test utils (#4897)
cf4235ea36 [wpiutil] Guard MSVC pragma in SymbolExports.h (#4911)
2d4b7b9147 [build] Update opencv version in opencv.gradle (#4909)
aec6f3d506 [ntcore] Fix client flush behavior (#4903)
bfe346c76a [build] Fix cmake java resources (#4898)
Change-Id: Ia1dd90fe42c6cd5df281b8a5b710e136f54355f4
git-subtree-dir: third_party/allwpilib
git-subtree-split: f1a82828fed8950f9a3f1586c44327027627a0c8
Signed-off-by: James Kuszmaul <jabukuszmaul+collab@gmail.com>
diff --git a/wpilibcExamples/src/main/cpp/examples/AprilTagsVision/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/AprilTagsVision/cpp/Robot.cpp
new file mode 100644
index 0000000..0ed53fd
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/AprilTagsVision/cpp/Robot.cpp
@@ -0,0 +1,165 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include <cstdio>
+#include <span>
+#include <sstream>
+#include <string>
+#include <thread>
+
+#include <cameraserver/CameraServer.h>
+#include <fmt/format.h>
+#include <frc/TimedRobot.h>
+#include <frc/apriltag/AprilTagDetection.h>
+#include <frc/apriltag/AprilTagDetector.h>
+#include <frc/apriltag/AprilTagPoseEstimator.h>
+#include <frc/geometry/Transform3d.h>
+#include <networktables/IntegerArrayTopic.h>
+#include <networktables/NetworkTableInstance.h>
+#include <opencv2/core/core.hpp>
+#include <opencv2/core/types.hpp>
+#include <opencv2/imgproc/imgproc.hpp>
+#include <units/angle.h>
+#include <units/length.h>
+
+/**
+ * This is a demo program showing the detection of AprilTags.
+ * The image is acquired from the USB camera, then any detected AprilTags
+ * are marked up on the image and sent to the dashboard.
+ *
+ * Be aware that the performance on this is much worse than a coprocessor
+ * solution!
+ */
+class Robot : public frc::TimedRobot {
+#if defined(__linux__) || defined(_WIN32)
+
+ private:
+ static void VisionThread() {
+ frc::AprilTagDetector detector;
+ // look for tag16h5, don't correct any error bits
+ detector.AddFamily("tag16h5", 0);
+
+ // Set up Pose Estimator - parameters are for a Microsoft Lifecam HD-3000
+ // (https://www.chiefdelphi.com/t/wpilib-apriltagdetector-sample-code/421411/21)
+ frc::AprilTagPoseEstimator::Config poseEstConfig = {
+ .tagSize = units::length::inch_t(6.0),
+ .fx = 699.3778103158814,
+ .fy = 677.7161226393544,
+ .cx = 345.6059345433618,
+ .cy = 207.12741326228522};
+ frc::AprilTagPoseEstimator estimator(poseEstConfig);
+
+ // Get the USB camera from CameraServer
+ cs::UsbCamera camera = frc::CameraServer::StartAutomaticCapture();
+ // Set the resolution
+ camera.SetResolution(640, 480);
+
+ // Get a CvSink. This will capture Mats from the Camera
+ cs::CvSink cvSink = frc::CameraServer::GetVideo();
+ // Setup a CvSource. This will send images back to the Dashboard
+ cs::CvSource outputStream =
+ frc::CameraServer::PutVideo("Detected", 640, 480);
+
+ // Mats are very memory expensive. Lets reuse this Mat.
+ cv::Mat mat;
+ cv::Mat grayMat;
+
+ // Instantiate once
+ std::vector<int64_t> tags;
+ cv::Scalar outlineColor{0, 255, 0};
+ cv::Scalar crossColor{0, 0, 255};
+
+ // We'll output to NT
+ auto tagsTable =
+ nt::NetworkTableInstance::GetDefault().GetTable("apriltags");
+ auto pubTags = tagsTable->GetIntegerArrayTopic("tags").Publish();
+
+ while (true) {
+ // Tell the CvSink to grab a frame from the camera and
+ // put it in the source mat. If there is an error notify the
+ // output.
+ if (cvSink.GrabFrame(mat) == 0) {
+ // Send the output the error.
+ outputStream.NotifyError(cvSink.GetError());
+ // skip the rest of the current iteration
+ continue;
+ }
+
+ cv::cvtColor(mat, grayMat, cv::COLOR_BGR2GRAY);
+
+ cv::Size g_size = grayMat.size();
+ frc::AprilTagDetector::Results detections =
+ detector.Detect(g_size.width, g_size.height, grayMat.data);
+
+ // have not seen any tags yet
+ tags.clear();
+
+ for (const frc::AprilTagDetection* detection : detections) {
+ // remember we saw this tag
+ tags.push_back(detection->GetId());
+
+ // draw lines around the tag
+ for (int i = 0; i <= 3; i++) {
+ int j = (i + 1) % 4;
+ const frc::AprilTagDetection::Point pti = detection->GetCorner(i);
+ const frc::AprilTagDetection::Point ptj = detection->GetCorner(j);
+ line(mat, cv::Point(pti.x, pti.y), cv::Point(ptj.x, ptj.y),
+ outlineColor, 2);
+ }
+
+ // mark the center of the tag
+ const frc::AprilTagDetection::Point c = detection->GetCenter();
+ int ll = 10;
+ line(mat, cv::Point(c.x - ll, c.y), cv::Point(c.x + ll, c.y),
+ crossColor, 2);
+ line(mat, cv::Point(c.x, c.y - ll), cv::Point(c.x, c.y + ll),
+ crossColor, 2);
+
+ // identify the tag
+ putText(mat, std::to_string(detection->GetId()),
+ cv::Point(c.x + ll, c.y), cv::FONT_HERSHEY_SIMPLEX, 1,
+ crossColor, 3);
+
+ // determine pose
+ frc::Transform3d pose = estimator.Estimate(*detection);
+
+ // put pose into NT
+ frc::Rotation3d rotation = pose.Rotation();
+ tagsTable->GetEntry(fmt::format("pose_{}", detection->GetId()))
+ .SetDoubleArray(
+ {{ pose.X().value(),
+ pose.Y().value(),
+ pose.Z().value(),
+ rotation.X().value(),
+ rotation.Y().value(),
+ rotation.Z().value() }});
+ }
+
+ // put list of tags onto NT
+ pubTags.Set(tags);
+
+ // Give the output stream a new image to display
+ outputStream.PutFrame(mat);
+ }
+ }
+#endif
+
+ void RobotInit() override {
+ // We need to run our vision program in a separate thread. If not, our robot
+ // program will not run.
+#if defined(__linux__) || defined(_WIN32)
+ std::thread visionThread(VisionThread);
+ visionThread.detach();
+#else
+ std::fputs("Vision only available on Linux or Windows.\n", stderr);
+ std::fflush(stderr);
+#endif
+ }
+};
+
+#ifndef RUNNING_FRC_TESTS
+int main() {
+ return frc::StartRobot<Robot>();
+}
+#endif
diff --git a/wpilibcExamples/src/main/cpp/examples/ArmSimulation/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/ArmSimulation/cpp/Robot.cpp
index 2027d25..8641f4c 100644
--- a/wpilibcExamples/src/main/cpp/examples/ArmSimulation/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/ArmSimulation/cpp/Robot.cpp
@@ -2,151 +2,30 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
-#include <numbers>
+#include "Robot.h"
-#include <frc/Encoder.h>
-#include <frc/Joystick.h>
-#include <frc/Preferences.h>
-#include <frc/RobotController.h>
-#include <frc/TimedRobot.h>
-#include <frc/controller/PIDController.h>
-#include <frc/motorcontrol/PWMSparkMax.h>
-#include <frc/simulation/BatterySim.h>
-#include <frc/simulation/EncoderSim.h>
-#include <frc/simulation/RoboRioSim.h>
-#include <frc/simulation/SingleJointedArmSim.h>
-#include <frc/smartdashboard/Mechanism2d.h>
-#include <frc/smartdashboard/MechanismLigament2d.h>
-#include <frc/smartdashboard/MechanismRoot2d.h>
-#include <frc/smartdashboard/SmartDashboard.h>
-#include <frc/system/plant/LinearSystemId.h>
-#include <frc/util/Color.h>
-#include <frc/util/Color8Bit.h>
-#include <units/angle.h>
-#include <units/moment_of_inertia.h>
+void Robot::SimulationPeriodic() {
+ m_arm.SimulationPeriodic();
+}
-/**
- * This is a sample program to demonstrate how to use a state-space controller
- * to control an arm.
- */
-class Robot : public frc::TimedRobot {
- static constexpr int kMotorPort = 0;
- static constexpr int kEncoderAChannel = 0;
- static constexpr int kEncoderBChannel = 1;
- static constexpr int kJoystickPort = 0;
+void Robot::TeleopInit() {
+ m_arm.LoadPreferences();
+}
- static constexpr std::string_view kArmPositionKey = "ArmPosition";
- static constexpr std::string_view kArmPKey = "ArmP";
-
- // The P gain for the PID controller that drives this arm.
- double kArmKp = 50.0;
-
- units::degree_t armPosition = 75.0_deg;
-
- // distance per pulse = (angle per revolution) / (pulses per revolution)
- // = (2 * PI rads) / (4096 pulses)
- static constexpr double kArmEncoderDistPerPulse =
- 2.0 * std::numbers::pi / 4096.0;
-
- // The arm gearbox represents a gearbox containing two Vex 775pro motors.
- frc::DCMotor m_armGearbox = frc::DCMotor::Vex775Pro(2);
-
- // Standard classes for controlling our arm
- frc2::PIDController m_controller{kArmKp, 0, 0};
- frc::Encoder m_encoder{kEncoderAChannel, kEncoderBChannel};
- frc::PWMSparkMax m_motor{kMotorPort};
- frc::Joystick m_joystick{kJoystickPort};
-
- // Simulation classes help us simulate what's going on, including gravity.
- // This sim represents an arm with 2 775s, a 600:1 reduction, a mass of 5kg,
- // 30in overall arm length, range of motion in [-75, 255] degrees, and noise
- // with a standard deviation of 1 encoder tick.
- frc::sim::SingleJointedArmSim m_armSim{
- m_armGearbox,
- 600.0,
- frc::sim::SingleJointedArmSim::EstimateMOI(30_in, 5_kg),
- 30_in,
- -75_deg,
- 255_deg,
- 5_kg,
- true,
- {kArmEncoderDistPerPulse}};
- frc::sim::EncoderSim m_encoderSim{m_encoder};
-
- // Create a Mechanism2d display of an Arm
- frc::Mechanism2d m_mech2d{60, 60};
- frc::MechanismRoot2d* m_armBase = m_mech2d.GetRoot("ArmBase", 30, 30);
- frc::MechanismLigament2d* m_armTower =
- m_armBase->Append<frc::MechanismLigament2d>(
- "Arm Tower", 30, -90_deg, 6, frc::Color8Bit{frc::Color::kBlue});
- frc::MechanismLigament2d* m_arm = m_armBase->Append<frc::MechanismLigament2d>(
- "Arm", 30, m_armSim.GetAngle(), 6, frc::Color8Bit{frc::Color::kYellow});
-
- public:
- void RobotInit() override {
- m_encoder.SetDistancePerPulse(kArmEncoderDistPerPulse);
-
- // Put Mechanism 2d to SmartDashboard
- frc::SmartDashboard::PutData("Arm Sim", &m_mech2d);
-
- // Set the Arm position setpoint and P constant to Preferences if the keys
- // don't already exist
- if (!frc::Preferences::ContainsKey(kArmPositionKey)) {
- frc::Preferences::SetDouble(kArmPositionKey, armPosition.value());
- }
- if (!frc::Preferences::ContainsKey(kArmPKey)) {
- frc::Preferences::SetDouble(kArmPKey, kArmKp);
- }
+void Robot::TeleopPeriodic() {
+ if (m_joystick.GetTrigger()) {
+ // Here, we run PID control like normal.
+ m_arm.ReachSetpoint();
+ } else {
+ // Otherwise, we disable the motor.
+ m_arm.Stop();
}
+}
- void SimulationPeriodic() override {
- // In this method, we update our simulation of what our arm is doing
- // First, we set our "inputs" (voltages)
- m_armSim.SetInput(frc::Vectord<1>{m_motor.Get() *
- frc::RobotController::GetInputVoltage()});
-
- // Next, we update it. The standard loop time is 20ms.
- m_armSim.Update(20_ms);
-
- // Finally, we set our simulated encoder's readings and simulated battery
- // voltage
- m_encoderSim.SetDistance(m_armSim.GetAngle().value());
- // SimBattery estimates loaded battery voltages
- frc::sim::RoboRioSim::SetVInVoltage(
- frc::sim::BatterySim::Calculate({m_armSim.GetCurrentDraw()}));
-
- // Update the Mechanism Arm angle based on the simulated arm angle
- m_arm->SetAngle(m_armSim.GetAngle());
- }
-
- void TeleopInit() override {
- // Read Preferences for Arm setpoint and kP on entering Teleop
- armPosition = units::degree_t{
- frc::Preferences::GetDouble(kArmPositionKey, armPosition.value())};
- if (kArmKp != frc::Preferences::GetDouble(kArmPKey, kArmKp)) {
- kArmKp = frc::Preferences::GetDouble(kArmPKey, kArmKp);
- m_controller.SetP(kArmKp);
- }
- }
-
- void TeleopPeriodic() override {
- if (m_joystick.GetTrigger()) {
- // Here, we run PID control like normal, with a setpoint read from
- // preferences in degrees.
- double pidOutput = m_controller.Calculate(
- m_encoder.GetDistance(), (units::radian_t{armPosition}.value()));
- m_motor.SetVoltage(units::volt_t{pidOutput});
- } else {
- // Otherwise, we disable the motor.
- m_motor.Set(0.0);
- }
- }
-
- void DisabledInit() override {
- // This just makes sure that our simulation code knows that the motor's off.
- m_motor.Set(0.0);
- }
-};
+void Robot::DisabledInit() {
+ // This just makes sure that our simulation code knows that the motor's off.
+ m_arm.Stop();
+}
#ifndef RUNNING_FRC_TESTS
int main() {
diff --git a/wpilibcExamples/src/main/cpp/examples/ArmSimulation/cpp/subsystems/Arm.cpp b/wpilibcExamples/src/main/cpp/examples/ArmSimulation/cpp/subsystems/Arm.cpp
new file mode 100644
index 0000000..95934ce
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/ArmSimulation/cpp/subsystems/Arm.cpp
@@ -0,0 +1,64 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "subsystems/Arm.h"
+
+#include <frc/Preferences.h>
+#include <frc/RobotController.h>
+#include <frc/StateSpaceUtil.h>
+#include <frc/smartdashboard/SmartDashboard.h>
+
+Arm::Arm() {
+ m_encoder.SetDistancePerPulse(kArmEncoderDistPerPulse);
+
+ // Put Mechanism 2d to SmartDashboard
+ frc::SmartDashboard::PutData("Arm Sim", &m_mech2d);
+
+ // Set the Arm position setpoint and P constant to Preferences if the keys
+ // don't already exist
+ frc::Preferences::InitDouble(kArmPositionKey, m_armSetpoint.value());
+ frc::Preferences::InitDouble(kArmPKey, m_armKp);
+}
+
+void Arm::SimulationPeriodic() {
+ // In this method, we update our simulation of what our arm is doing
+ // First, we set our "inputs" (voltages)
+ m_armSim.SetInput(
+ frc::Vectord<1>{m_motor.Get() * frc::RobotController::GetInputVoltage()});
+
+ // Next, we update it. The standard loop time is 20ms.
+ m_armSim.Update(20_ms);
+
+ // Finally, we set our simulated encoder's readings and simulated battery
+ // voltage
+ m_encoderSim.SetDistance(m_armSim.GetAngle().value());
+ // SimBattery estimates loaded battery voltages
+ frc::sim::RoboRioSim::SetVInVoltage(
+ frc::sim::BatterySim::Calculate({m_armSim.GetCurrentDraw()}));
+
+ // Update the Mechanism Arm angle based on the simulated arm angle
+ m_arm->SetAngle(m_armSim.GetAngle());
+}
+
+void Arm::LoadPreferences() {
+ // Read Preferences for Arm setpoint and kP on entering Teleop
+ m_armSetpoint = units::degree_t{
+ frc::Preferences::GetDouble(kArmPositionKey, m_armSetpoint.value())};
+ if (m_armKp != frc::Preferences::GetDouble(kArmPKey, m_armKp)) {
+ m_armKp = frc::Preferences::GetDouble(kArmPKey, m_armKp);
+ m_controller.SetP(m_armKp);
+ }
+}
+
+void Arm::ReachSetpoint() {
+ // Here, we run PID control like normal, with a setpoint read from
+ // preferences in degrees.
+ double pidOutput = m_controller.Calculate(
+ m_encoder.GetDistance(), (units::radian_t{m_armSetpoint}.value()));
+ m_motor.SetVoltage(units::volt_t{pidOutput});
+}
+
+void Arm::Stop() {
+ m_motor.Set(0.0);
+}
diff --git a/wpilibcExamples/src/main/cpp/examples/ArmSimulation/include/Constants.h b/wpilibcExamples/src/main/cpp/examples/ArmSimulation/include/Constants.h
new file mode 100644
index 0000000..0018a8a
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/ArmSimulation/include/Constants.h
@@ -0,0 +1,46 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <numbers>
+
+#include <units/angle.h>
+#include <units/length.h>
+#include <units/mass.h>
+#include <units/time.h>
+#include <units/velocity.h>
+#include <units/voltage.h>
+
+/**
+ * The Constants header provides a convenient place for teams to hold robot-wide
+ * numerical or bool constants. This should not be used for any other purpose.
+ *
+ * It is generally a good idea to place constants into subsystem- or
+ * command-specific namespaces within this header, which can then be used where
+ * they are needed.
+ */
+
+static constexpr int kMotorPort = 0;
+static constexpr int kEncoderAChannel = 0;
+static constexpr int kEncoderBChannel = 1;
+static constexpr int kJoystickPort = 0;
+
+static constexpr std::string_view kArmPositionKey = "ArmPosition";
+static constexpr std::string_view kArmPKey = "ArmP";
+
+static constexpr double kDefaultArmKp = 50.0;
+static constexpr units::degree_t kDefaultArmSetpoint = 75.0_deg;
+
+static constexpr units::radian_t kMinAngle = -75.0_deg;
+static constexpr units::radian_t kMaxAngle = 255.0_deg;
+
+static constexpr double kArmReduction = 200.0;
+static constexpr units::kilogram_t kArmMass = 8.0_kg;
+static constexpr units::meter_t kArmLength = 30.0_in;
+
+// distance per pulse = (angle per revolution) / (pulses per revolution)
+// = (2 * PI rads) / (4096 pulses)
+static constexpr double kArmEncoderDistPerPulse =
+ 2.0 * std::numbers::pi / 4096.0;
diff --git a/wpilibcExamples/src/main/cpp/examples/ArmSimulation/include/Robot.h b/wpilibcExamples/src/main/cpp/examples/ArmSimulation/include/Robot.h
new file mode 100644
index 0000000..fdcb5ce
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/ArmSimulation/include/Robot.h
@@ -0,0 +1,26 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <frc/Joystick.h>
+#include <frc/TimedRobot.h>
+
+#include "subsystems/Arm.h"
+
+/**
+ * This is a sample program to demonstrate the use of arm simulation.
+ */
+class Robot : public frc::TimedRobot {
+ public:
+ void RobotInit() override {}
+ void SimulationPeriodic() override;
+ void TeleopInit() override;
+ void TeleopPeriodic() override;
+ void DisabledInit() override;
+
+ private:
+ frc::Joystick m_joystick{kJoystickPort};
+ Arm m_arm;
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/ArmSimulation/include/subsystems/Arm.h b/wpilibcExamples/src/main/cpp/examples/ArmSimulation/include/subsystems/Arm.h
new file mode 100644
index 0000000..6c7a3a7
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/ArmSimulation/include/subsystems/Arm.h
@@ -0,0 +1,68 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <frc/Encoder.h>
+#include <frc/controller/ArmFeedforward.h>
+#include <frc/controller/PIDController.h>
+#include <frc/motorcontrol/PWMSparkMax.h>
+#include <frc/simulation/BatterySim.h>
+#include <frc/simulation/EncoderSim.h>
+#include <frc/simulation/PWMSim.h>
+#include <frc/simulation/RoboRioSim.h>
+#include <frc/simulation/SingleJointedArmSim.h>
+#include <frc/smartdashboard/Mechanism2d.h>
+#include <frc/smartdashboard/MechanismLigament2d.h>
+#include <frc/smartdashboard/MechanismRoot2d.h>
+#include <units/length.h>
+
+#include "Constants.h"
+
+class Arm {
+ public:
+ Arm();
+ void SimulationPeriodic();
+ void LoadPreferences();
+ void ReachSetpoint();
+ void Stop();
+
+ private:
+ // The P gain for the PID controller that drives this arm.
+ double m_armKp = kDefaultArmKp;
+ units::degree_t m_armSetpoint = kDefaultArmSetpoint;
+
+ // The arm gearbox represents a gearbox containing two Vex 775pro motors.
+ frc::DCMotor m_armGearbox = frc::DCMotor::Vex775Pro(2);
+
+ // Standard classes for controlling our arm
+ frc::PIDController m_controller{m_armKp, 0, 0};
+ frc::Encoder m_encoder{kEncoderAChannel, kEncoderBChannel};
+ frc::PWMSparkMax m_motor{kMotorPort};
+
+ // Simulation classes help us simulate what's going on, including gravity.
+ // This sim represents an arm with 2 775s, a 600:1 reduction, a mass of 5kg,
+ // 30in overall arm length, range of motion in [-75, 255] degrees, and noise
+ // with a standard deviation of 1 encoder tick.
+ frc::sim::SingleJointedArmSim m_armSim{
+ m_armGearbox,
+ kArmReduction,
+ frc::sim::SingleJointedArmSim::EstimateMOI(kArmLength, kArmMass),
+ kArmLength,
+ kMinAngle,
+ kMaxAngle,
+ true,
+ 0_deg,
+ {kArmEncoderDistPerPulse}};
+ frc::sim::EncoderSim m_encoderSim{m_encoder};
+
+ // Create a Mechanism2d display of an Arm
+ frc::Mechanism2d m_mech2d{60, 60};
+ frc::MechanismRoot2d* m_armBase = m_mech2d.GetRoot("ArmBase", 30, 30);
+ frc::MechanismLigament2d* m_armTower =
+ m_armBase->Append<frc::MechanismLigament2d>(
+ "Arm Tower", 30, -90_deg, 6, frc::Color8Bit{frc::Color::kBlue});
+ frc::MechanismLigament2d* m_arm = m_armBase->Append<frc::MechanismLigament2d>(
+ "Arm", 30, m_armSim.GetAngle(), 6, frc::Color8Bit{frc::Color::kYellow});
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/DifferentialDriveBot/include/Drivetrain.h b/wpilibcExamples/src/main/cpp/examples/DifferentialDriveBot/include/Drivetrain.h
index b4ad1db..54b2e26 100644
--- a/wpilibcExamples/src/main/cpp/examples/DifferentialDriveBot/include/Drivetrain.h
+++ b/wpilibcExamples/src/main/cpp/examples/DifferentialDriveBot/include/Drivetrain.h
@@ -69,8 +69,8 @@
frc::Encoder m_leftEncoder{0, 1};
frc::Encoder m_rightEncoder{2, 3};
- frc2::PIDController m_leftPIDController{1.0, 0.0, 0.0};
- frc2::PIDController m_rightPIDController{1.0, 0.0, 0.0};
+ frc::PIDController m_leftPIDController{1.0, 0.0, 0.0};
+ frc::PIDController m_rightPIDController{1.0, 0.0, 0.0};
frc::AnalogGyro m_gyro{0};
diff --git a/wpilibcExamples/src/main/cpp/examples/DifferentialDrivePoseEstimator/cpp/Drivetrain.cpp b/wpilibcExamples/src/main/cpp/examples/DifferentialDrivePoseEstimator/cpp/Drivetrain.cpp
index 866d62d..725074a 100644
--- a/wpilibcExamples/src/main/cpp/examples/DifferentialDrivePoseEstimator/cpp/Drivetrain.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/DifferentialDrivePoseEstimator/cpp/Drivetrain.cpp
@@ -4,10 +4,31 @@
#include "Drivetrain.h"
-#include <frc/Timer.h>
-
#include "ExampleGlobalMeasurementSensor.h"
+Drivetrain::Drivetrain() {
+ // We need to invert one side of the drivetrain so that positive voltages
+ // result in both sides moving forward. Depending on how your robot's
+ // gearbox is constructed, you might have to invert the left side instead.
+ m_rightGroup.SetInverted(true);
+
+ m_gyro.Reset();
+
+ // Set the distance per pulse for the drive encoders. We can simply use the
+ // distance traveled for one rotation of the wheel divided by the encoder
+ // resolution.
+ m_leftEncoder.SetDistancePerPulse(
+ (2 * std::numbers::pi * kWheelRadius / kEncoderResolution).value());
+ m_rightEncoder.SetDistancePerPulse(
+ (2 * std::numbers::pi * kWheelRadius / kEncoderResolution).value());
+
+ m_leftEncoder.Reset();
+ m_rightEncoder.Reset();
+
+ frc::SmartDashboard::PutData("FieldSim", &m_fieldSim);
+ frc::SmartDashboard::PutData("Approximation", &m_fieldApproximation);
+}
+
void Drivetrain::SetSpeeds(const frc::DifferentialDriveWheelSpeeds& speeds) {
const auto leftFeedforward = m_feedforward.Calculate(speeds.left);
const auto rightFeedforward = m_feedforward.Calculate(speeds.right);
@@ -25,16 +46,86 @@
SetSpeeds(m_kinematics.ToWheelSpeeds({xSpeed, 0_mps, rot}));
}
+void Drivetrain::PublishCameraToObject(
+ frc::Pose3d objectInField, frc::Transform3d robotToCamera,
+ nt::DoubleArrayEntry& cameraToObjectEntry,
+ frc::sim::DifferentialDrivetrainSim drivetrainSimulator) {
+ frc::Pose3d robotInField{drivetrainSimulator.GetPose()};
+ frc::Pose3d cameraInField = robotInField + robotToCamera;
+ frc::Transform3d cameraToObject{cameraInField, objectInField};
+
+ // Publishes double array with Translation3D elements {x, y, z} and Rotation3D
+ // elements {w, x, y, z} which describe the cameraToObject transformation.
+ std::array<double, 7> val{cameraToObject.X().value(),
+ cameraToObject.Y().value(),
+ cameraToObject.Z().value(),
+ cameraToObject.Rotation().GetQuaternion().W(),
+ cameraToObject.Rotation().GetQuaternion().X(),
+ cameraToObject.Rotation().GetQuaternion().Y(),
+ cameraToObject.Rotation().GetQuaternion().Z()};
+ cameraToObjectEntry.Set(val);
+}
+
+frc::Pose3d Drivetrain::ObjectToRobotPose(
+ frc::Pose3d objectInField, frc::Transform3d robotToCamera,
+ nt::DoubleArrayEntry& cameraToObjectEntry) {
+ std::vector<double> val{cameraToObjectEntry.Get()};
+
+ // Reconstruct cameraToObject Transform3D from networktables.
+ frc::Translation3d translation{units::meter_t{val[0]}, units::meter_t{val[1]},
+ units::meter_t{val[2]}};
+ frc::Rotation3d rotation{frc::Quaternion{val[3], val[4], val[5], val[6]}};
+ frc::Transform3d cameraToObject{translation, rotation};
+
+ return frc::ObjectToRobotPose(objectInField, cameraToObject, robotToCamera);
+}
+
void Drivetrain::UpdateOdometry() {
m_poseEstimator.Update(m_gyro.GetRotation2d(),
units::meter_t{m_leftEncoder.GetDistance()},
units::meter_t{m_rightEncoder.GetDistance()});
- // Also apply vision measurements. We use 0.3 seconds in the past as an
- // example -- on a real robot, this must be calculated based either on latency
- // or timestamps.
- m_poseEstimator.AddVisionMeasurement(
- ExampleGlobalMeasurementSensor::GetEstimatedGlobalPose(
- m_poseEstimator.GetEstimatedPosition()),
- frc::Timer::GetFPGATimestamp() - 0.3_s);
+ // Publish cameraToObject transformation to networktables --this would
+ // normally be handled by the computer vision solution.
+ PublishCameraToObject(m_objectInField, m_robotToCamera,
+ m_cameraToObjectEntryRef, m_drivetrainSimulator);
+
+ // Compute the robot's field-relative position exclusively from vision
+ // measurements.
+ frc::Pose3d visionMeasurement3d = ObjectToRobotPose(
+ m_objectInField, m_robotToCamera, m_cameraToObjectEntryRef);
+
+ // Convert robot's pose from Pose3d to Pose2d needed to apply vision
+ // measurements.
+ frc::Pose2d visionMeasurement2d = visionMeasurement3d.ToPose2d();
+
+ // Apply vision measurements. For simulation purposes only, we don't input a
+ // latency delay -- on a real robot, this must be calculated based either on
+ // known latency or timestamps.
+ m_poseEstimator.AddVisionMeasurement(visionMeasurement2d,
+ frc::Timer::GetFPGATimestamp());
+}
+
+void Drivetrain::SimulationPeriodic() {
+ // To update our simulation, we set motor voltage inputs, update the
+ // simulation, and write the simulated positions and velocities to our
+ // simulated encoder and gyro.
+ m_drivetrainSimulator.SetInputs(units::volt_t{m_leftGroup.Get()} *
+ frc::RobotController::GetInputVoltage(),
+ units::volt_t{m_rightGroup.Get()} *
+ frc::RobotController::GetInputVoltage());
+ m_drivetrainSimulator.Update(20_ms);
+
+ m_leftEncoderSim.SetDistance(m_drivetrainSimulator.GetLeftPosition().value());
+ m_leftEncoderSim.SetRate(m_drivetrainSimulator.GetLeftVelocity().value());
+ m_rightEncoderSim.SetDistance(
+ m_drivetrainSimulator.GetRightPosition().value());
+ m_rightEncoderSim.SetRate(m_drivetrainSimulator.GetRightVelocity().value());
+ m_gyroSim.SetAngle(-m_drivetrainSimulator.GetHeading().Degrees().value());
+}
+
+void Drivetrain::Periodic() {
+ UpdateOdometry();
+ m_fieldSim.SetRobotPose(m_drivetrainSimulator.GetPose());
+ m_fieldApproximation.SetRobotPose(m_poseEstimator.GetEstimatedPosition());
}
diff --git a/wpilibcExamples/src/main/cpp/examples/DifferentialDrivePoseEstimator/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/DifferentialDrivePoseEstimator/cpp/Robot.cpp
index e9119c8..324e03f 100644
--- a/wpilibcExamples/src/main/cpp/examples/DifferentialDrivePoseEstimator/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/DifferentialDrivePoseEstimator/cpp/Robot.cpp
@@ -15,6 +15,8 @@
m_drive.UpdateOdometry();
}
+ void RobotPeriodic() override { m_drive.Periodic(); }
+
void TeleopPeriodic() override {
// Get the x speed. We are inverting this because Xbox controllers return
// negative values when we push forward.
@@ -31,6 +33,8 @@
m_drive.Drive(xSpeed, rot);
}
+ void SimulationPeriodic() override { m_drive.SimulationPeriodic(); }
+
private:
frc::XboxController m_controller{0};
diff --git a/wpilibcExamples/src/main/cpp/examples/DifferentialDrivePoseEstimator/include/Drivetrain.h b/wpilibcExamples/src/main/cpp/examples/DifferentialDrivePoseEstimator/include/Drivetrain.h
index 3001763..ac4de4c 100644
--- a/wpilibcExamples/src/main/cpp/examples/DifferentialDrivePoseEstimator/include/Drivetrain.h
+++ b/wpilibcExamples/src/main/cpp/examples/DifferentialDrivePoseEstimator/include/Drivetrain.h
@@ -7,13 +7,30 @@
#include <numbers>
#include <frc/AnalogGyro.h>
+#include <frc/ComputerVisionUtil.h>
#include <frc/Encoder.h>
+#include <frc/RobotController.h>
+#include <frc/Timer.h>
+#include <frc/apriltag/AprilTagFieldLayout.h>
+#include <frc/apriltag/AprilTagFields.h>
#include <frc/controller/PIDController.h>
#include <frc/controller/SimpleMotorFeedforward.h>
#include <frc/estimator/DifferentialDrivePoseEstimator.h>
+#include <frc/geometry/Pose2d.h>
+#include <frc/geometry/Pose3d.h>
+#include <frc/geometry/Quaternion.h>
+#include <frc/geometry/Transform3d.h>
#include <frc/kinematics/DifferentialDriveKinematics.h>
#include <frc/motorcontrol/MotorControllerGroup.h>
#include <frc/motorcontrol/PWMSparkMax.h>
+#include <frc/simulation/AnalogGyroSim.h>
+#include <frc/simulation/DifferentialDrivetrainSim.h>
+#include <frc/simulation/EncoderSim.h>
+#include <frc/smartdashboard/Field2d.h>
+#include <frc/smartdashboard/SmartDashboard.h>
+#include <frc/system/plant/LinearSystemId.h>
+#include <networktables/DoubleArrayTopic.h>
+#include <networktables/NetworkTableInstance.h>
#include <units/angle.h>
#include <units/angular_velocity.h>
#include <units/length.h>
@@ -24,40 +41,100 @@
*/
class Drivetrain {
public:
- Drivetrain() {
- // We need to invert one side of the drivetrain so that positive voltages
- // result in both sides moving forward. Depending on how your robot's
- // gearbox is constructed, you might have to invert the left side instead.
- m_rightGroup.SetInverted(true);
-
- m_gyro.Reset();
- // Set the distance per pulse for the drive encoders. We can simply use the
- // distance traveled for one rotation of the wheel divided by the encoder
- // resolution.
- m_leftEncoder.SetDistancePerPulse(
- 2 * std::numbers::pi * kWheelRadius.value() / kEncoderResolution);
- m_rightEncoder.SetDistancePerPulse(
- 2 * std::numbers::pi * kWheelRadius.value() / kEncoderResolution);
-
- m_leftEncoder.Reset();
- m_rightEncoder.Reset();
- }
+ Drivetrain();
static constexpr units::meters_per_second_t kMaxSpeed =
3.0_mps; // 3 meters per second
static constexpr units::radians_per_second_t kMaxAngularSpeed{
std::numbers::pi}; // 1/2 rotation per second
+ /**
+ * Sets the desired wheel speeds.
+ *
+ * @param speeds The desired wheel speeds.
+ */
void SetSpeeds(const frc::DifferentialDriveWheelSpeeds& speeds);
+
+ /** Drives the robot with the given linear velocity and angular velocity.
+ *
+ * @param xSpeed Linear velocity.
+ * @param rot Angular Velocity.
+ */
void Drive(units::meters_per_second_t xSpeed,
units::radians_per_second_t rot);
+
+ /**
+ * Updates the field-relative position.
+ */
void UpdateOdometry();
+ /**
+ * This function is called periodically during simulation. */
+ void SimulationPeriodic();
+
+ /** This function is called periodically, regardless of mode. */
+ void Periodic();
+
+ /**
+ * Computes and publishes to a networktables topic the transformation from
+ * the camera's pose to the object's pose. This function exists solely for the
+ * purposes of simulation, and this would normally be handled by computer
+ * vision.
+ *
+ * <p>The object could be a target or a fiducial marker.
+ *
+ * @param objectInField The object's field-relative position.
+ * @param robotToCamera The transformation from the robot's pose to the
+ * camera's pose.
+ * @param cameraToObjectEntry The networktables entry publishing and querying
+ * example computer vision measurements.
+ * @param drivetrainSimulation A DifferentialDrivetrainSim modeling the
+ * robot's drivetrain.
+ */
+ void PublishCameraToObject(
+ frc::Pose3d objectInField, frc::Transform3d robotToCamera,
+ nt::DoubleArrayEntry& cameraToObjectEntry,
+ frc::sim::DifferentialDrivetrainSim drivetrainSimulator);
+
+ /**
+ * Queries the camera-to-object transformation from networktables to compute
+ * the robot's field-relative pose from vision measurements.
+ *
+ * <p>The object could be a target or a fiducial marker.
+ *
+ * @param objectInField The object's field-relative position.
+ * @param robotToCamera The transformation from the robot's pose to the
+ * camera's pose.
+ * @param cameraToObjectEntry The networktables entry publishing and querying
+ * example computer vision measurements.
+ */
+ frc::Pose3d ObjectToRobotPose(frc::Pose3d objectInField,
+ frc::Transform3d robotToCamera,
+ nt::DoubleArrayEntry& cameraToObjectEntry);
+
private:
static constexpr units::meter_t kTrackWidth = 0.381_m * 2;
static constexpr units::meter_t kWheelRadius = 0.0508_m;
static constexpr int kEncoderResolution = 4096;
+ static constexpr std::array<double, 7> kDefaultVal{0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0};
+
+ frc::Transform3d m_robotToCamera{
+ frc::Translation3d{1_m, 1_m, 1_m},
+ frc::Rotation3d{0_rad, 0_rad, units::radian_t{std::numbers::pi / 2}}};
+
+ nt::NetworkTableInstance m_inst{nt::NetworkTableInstance::GetDefault()};
+ nt::DoubleArrayTopic m_cameraToObjectTopic{
+ m_inst.GetDoubleArrayTopic("m_cameraToObjectTopic")};
+ nt::DoubleArrayEntry m_cameraToObjectEntry =
+ m_cameraToObjectTopic.GetEntry(kDefaultVal);
+ nt::DoubleArrayEntry& m_cameraToObjectEntryRef = m_cameraToObjectEntry;
+
+ frc::AprilTagFieldLayout m_aprilTagFieldLayout{
+ frc::LoadAprilTagLayoutField(frc::AprilTagField::k2022RapidReact)};
+ frc::Pose3d m_objectInField{m_aprilTagFieldLayout.GetTagPose(0).value()};
+
frc::PWMSparkMax m_leftLeader{1};
frc::PWMSparkMax m_leftFollower{2};
frc::PWMSparkMax m_rightLeader{3};
@@ -69,8 +146,8 @@
frc::Encoder m_leftEncoder{0, 1};
frc::Encoder m_rightEncoder{2, 3};
- frc2::PIDController m_leftPIDController{1.0, 0.0, 0.0};
- frc2::PIDController m_rightPIDController{1.0, 0.0, 0.0};
+ frc::PIDController m_leftPIDController{1.0, 0.0, 0.0};
+ frc::PIDController m_rightPIDController{1.0, 0.0, 0.0};
frc::AnalogGyro m_gyro{0};
@@ -90,4 +167,16 @@
// Gains are for example purposes only - must be determined for your own
// robot!
frc::SimpleMotorFeedforward<units::meters> m_feedforward{1_V, 3_V / 1_mps};
+
+ // Simulation classes
+ frc::sim::AnalogGyroSim m_gyroSim{m_gyro};
+ frc::sim::EncoderSim m_leftEncoderSim{m_leftEncoder};
+ frc::sim::EncoderSim m_rightEncoderSim{m_rightEncoder};
+ frc::Field2d m_fieldSim;
+ frc::Field2d m_fieldApproximation;
+ frc::LinearSystem<2, 2, 2> m_drivetrainSystem =
+ frc::LinearSystemId::IdentifyDrivetrainSystem(
+ 1.98_V / 1_mps, 0.2_V / 1_mps_sq, 1.5_V / 1_mps, 0.3_V / 1_mps_sq);
+ frc::sim::DifferentialDrivetrainSim m_drivetrainSimulator{
+ m_drivetrainSystem, kTrackWidth, frc::DCMotor::CIM(2), 8, 2_in};
};
diff --git a/wpilibcExamples/src/main/cpp/examples/DigitalCommunication/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/DigitalCommunication/cpp/Robot.cpp
index 037fb1d..e95a0d7 100644
--- a/wpilibcExamples/src/main/cpp/examples/DigitalCommunication/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/DigitalCommunication/cpp/Robot.cpp
@@ -2,45 +2,28 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
-#include <frc/DigitalOutput.h>
+#include "Robot.h"
+
#include <frc/DriverStation.h>
-#include <frc/TimedRobot.h>
-/**
- * This is a sample program demonstrating how to communicate to a light
- * controller from the robot code using the roboRIO's DIO ports.
- */
-class Robot : public frc::TimedRobot {
- public:
- void RobotPeriodic() override {
- // pull alliance port high if on red alliance, pull low if on blue alliance
- m_allianceOutput.Set(frc::DriverStation::GetAlliance() ==
- frc::DriverStation::kRed);
+void Robot::RobotPeriodic() {
+ // pull alliance port high if on red alliance, pull low if on blue alliance
+ m_allianceOutput.Set(frc::DriverStation::GetAlliance() ==
+ frc::DriverStation::kRed);
- // pull enabled port high if enabled, low if disabled
- m_enabledOutput.Set(frc::DriverStation::IsEnabled());
+ // pull enabled port high if enabled, low if disabled
+ m_enabledOutput.Set(frc::DriverStation::IsEnabled());
- // pull auto port high if in autonomous, low if in teleop (or disabled)
- m_autonomousOutput.Set(frc::DriverStation::IsAutonomous());
+ // pull auto port high if in autonomous, low if in teleop (or disabled)
+ m_autonomousOutput.Set(frc::DriverStation::IsAutonomous());
- // pull alert port high if match time remaining is between 30 and 25 seconds
- auto matchTime = frc::DriverStation::GetMatchTime();
- m_alertOutput.Set(matchTime <= 30 && matchTime >= 25);
- }
+ // pull alert port high if match time remaining is between 30 and 25 seconds
+ auto matchTime = frc::DriverStation::GetMatchTime();
+ m_alertOutput.Set(matchTime <= 30_s && matchTime >= 25_s);
+}
- private:
- // define ports for communication with light controller
- static constexpr int kAlliancePort = 0;
- static constexpr int kEnabledPort = 1;
- static constexpr int kAutonomousPort = 2;
- static constexpr int kAlertPort = 3;
-
- frc::DigitalOutput m_allianceOutput{kAlliancePort};
- frc::DigitalOutput m_enabledOutput{kEnabledPort};
- frc::DigitalOutput m_autonomousOutput{kAutonomousPort};
- frc::DigitalOutput m_alertOutput{kAlertPort};
-};
-
+#ifndef RUNNING_FRC_TESTS
int main() {
return frc::StartRobot<Robot>();
}
+#endif
diff --git a/wpilibcExamples/src/main/cpp/examples/DigitalCommunication/include/Robot.h b/wpilibcExamples/src/main/cpp/examples/DigitalCommunication/include/Robot.h
new file mode 100644
index 0000000..17ec680
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/DigitalCommunication/include/Robot.h
@@ -0,0 +1,31 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <array>
+
+#include <frc/DigitalOutput.h>
+#include <frc/TimedRobot.h>
+
+/**
+ * This is a sample program demonstrating how to communicate to a light
+ * controller from the robot code using the roboRIO's DIO ports.
+ */
+class Robot : public frc::TimedRobot {
+ public:
+ // define ports for communication with light controller
+ static constexpr int kAlliancePort = 0;
+ static constexpr int kEnabledPort = 1;
+ static constexpr int kAutonomousPort = 2;
+ static constexpr int kAlertPort = 3;
+
+ void RobotPeriodic() override;
+
+ private:
+ frc::DigitalOutput m_allianceOutput{kAlliancePort};
+ frc::DigitalOutput m_enabledOutput{kEnabledPort};
+ frc::DigitalOutput m_autonomousOutput{kAutonomousPort};
+ frc::DigitalOutput m_alertOutput{kAlertPort};
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/DriveDistanceOffboard/cpp/RobotContainer.cpp b/wpilibcExamples/src/main/cpp/examples/DriveDistanceOffboard/cpp/RobotContainer.cpp
index 8c2423b..bcb7e73 100644
--- a/wpilibcExamples/src/main/cpp/examples/DriveDistanceOffboard/cpp/RobotContainer.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/DriveDistanceOffboard/cpp/RobotContainer.cpp
@@ -40,13 +40,17 @@
frc2::TrapezoidProfileCommand<units::meters>(
frc::TrapezoidProfile<units::meters>(
// Limit the max acceleration and velocity
- {DriveConstants::kMaxSpeed, DriveConstants::kMaxAcceleration},
- // End at desired position in meters; implicitly starts at 0
- {3_m, 0_mps}),
+ {DriveConstants::kMaxSpeed, DriveConstants::kMaxAcceleration}),
// Pipe the profile state to the drive
[this](auto setpointState) {
m_drive.SetDriveStates(setpointState, setpointState);
},
+ // End at desired position in meters; implicitly starts at 0
+ [] {
+ return frc::TrapezoidProfile<units::meters>::State{3_m, 0_mps};
+ },
+ // Current position
+ [] { return frc::TrapezoidProfile<units::meters>::State{}; },
// Require the drive
{&m_drive})
// Convert to CommandPtr
diff --git a/wpilibcExamples/src/main/cpp/examples/DriveDistanceOffboard/cpp/commands/DriveDistanceProfiled.cpp b/wpilibcExamples/src/main/cpp/examples/DriveDistanceOffboard/cpp/commands/DriveDistanceProfiled.cpp
index 6780c33..8d45c91 100644
--- a/wpilibcExamples/src/main/cpp/examples/DriveDistanceOffboard/cpp/commands/DriveDistanceProfiled.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/DriveDistanceOffboard/cpp/commands/DriveDistanceProfiled.cpp
@@ -13,13 +13,16 @@
: CommandHelper{
frc::TrapezoidProfile<units::meters>{
// Limit the max acceleration and velocity
- {kMaxSpeed, kMaxAcceleration},
- // End at desired position in meters; implicitly starts at 0
- {distance, 0_mps}},
+ {kMaxSpeed, kMaxAcceleration}},
// Pipe the profile state to the drive
[drive](auto setpointState) {
drive->SetDriveStates(setpointState, setpointState);
},
+ // End at desired position in meters; implicitly starts at 0
+ [distance] {
+ return frc::TrapezoidProfile<units::meters>::State{distance, 0_mps};
+ },
+ [] { return frc::TrapezoidProfile<units::meters>::State{}; },
// Require the drive
{drive}} {
// Reset drive encoders since we're starting at 0
diff --git a/wpilibcExamples/src/main/cpp/examples/ElevatorExponentialProfile/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/ElevatorExponentialProfile/cpp/Robot.cpp
new file mode 100644
index 0000000..5d65a5a
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/ElevatorExponentialProfile/cpp/Robot.cpp
@@ -0,0 +1,68 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include <numbers>
+
+#include <frc/Joystick.h>
+#include <frc/TimedRobot.h>
+#include <frc/controller/SimpleMotorFeedforward.h>
+#include <frc/trajectory/ExponentialProfile.h>
+#include <units/acceleration.h>
+#include <units/length.h>
+#include <units/time.h>
+#include <units/velocity.h>
+#include <units/voltage.h>
+
+#include "ExampleSmartMotorController.h"
+
+class Robot : public frc::TimedRobot {
+ public:
+ static constexpr units::second_t kDt = 20_ms;
+
+ Robot() {
+ // Note: These gains are fake, and will have to be tuned for your robot.
+ m_motor.SetPID(1.3, 0.0, 0.7);
+ }
+
+ void TeleopPeriodic() override {
+ if (m_joystick.GetRawButtonPressed(2)) {
+ m_goal = {5_m, 0_mps};
+ } else if (m_joystick.GetRawButtonPressed(3)) {
+ m_goal = {0_m, 0_mps};
+ }
+
+ // Retrieve the profiled setpoint for the next timestep. This setpoint moves
+ // toward the goal while obeying the constraints.
+ auto next = m_profile.Calculate(kDt, m_goal, m_setpoint);
+
+ // Send setpoint to offboard controller PID
+ m_motor.SetSetpoint(
+ ExampleSmartMotorController::PIDMode::kPosition,
+ m_setpoint.position.value(),
+ m_feedforward.Calculate(m_setpoint.velocity, next.velocity, kDt) /
+ 12_V);
+
+ m_setpoint = next;
+ }
+
+ private:
+ frc::Joystick m_joystick{1};
+ ExampleSmartMotorController m_motor{1};
+ frc::SimpleMotorFeedforward<units::meters> m_feedforward{
+ // Note: These gains are fake, and will have to be tuned for your robot.
+ 1_V, 1_V / 1_mps, 1_V / 1_mps_sq};
+
+ // Create a motion profile with the given maximum velocity and maximum
+ // acceleration constraints for the next setpoint.
+ frc::ExponentialProfile<units::meters, units::volts> m_profile{
+ {10_V, 1_V / 1_mps, 1_V / 1_mps_sq}};
+ frc::ExponentialProfile<units::meters, units::volts>::State m_goal;
+ frc::ExponentialProfile<units::meters, units::volts>::State m_setpoint;
+};
+
+#ifndef RUNNING_FRC_TESTS
+int main() {
+ return frc::StartRobot<Robot>();
+}
+#endif
diff --git a/wpilibcExamples/src/main/cpp/examples/ElevatorExponentialProfile/include/ExampleSmartMotorController.h b/wpilibcExamples/src/main/cpp/examples/ElevatorExponentialProfile/include/ExampleSmartMotorController.h
new file mode 100644
index 0000000..5d55839
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/ElevatorExponentialProfile/include/ExampleSmartMotorController.h
@@ -0,0 +1,82 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <frc/motorcontrol/MotorController.h>
+
+/**
+ * A simplified stub class that simulates the API of a common "smart" motor
+ * controller.
+ *
+ * <p>Has no actual functionality.
+ */
+class ExampleSmartMotorController : public frc::MotorController {
+ public:
+ enum PIDMode { kPosition, kVelocity, kMovementWitchcraft };
+
+ /**
+ * Creates a new ExampleSmartMotorController.
+ *
+ * @param port The port for the controller.
+ */
+ explicit ExampleSmartMotorController(int port) {}
+
+ /**
+ * Example method for setting the PID gains of the smart controller.
+ *
+ * @param kp The proportional gain.
+ * @param ki The integral gain.
+ * @param kd The derivative gain.
+ */
+ void SetPID(double kp, double ki, double kd) {}
+
+ /**
+ * Example method for setting the setpoint of the smart controller in PID
+ * mode.
+ *
+ * @param mode The mode of the PID controller.
+ * @param setpoint The controller setpoint.
+ * @param arbFeedforward An arbitrary feedforward output (from -1 to 1).
+ */
+ void SetSetpoint(PIDMode mode, double setpoint, double arbFeedforward) {}
+
+ /**
+ * Places this motor controller in follower mode.
+ *
+ * @param leader The leader to follow.
+ */
+ void Follow(ExampleSmartMotorController leader) {}
+
+ /**
+ * Returns the encoder distance.
+ *
+ * @return The current encoder distance.
+ */
+ double GetEncoderDistance() { return 0; }
+
+ /**
+ * Returns the encoder rate.
+ *
+ * @return The current encoder rate.
+ */
+ double GetEncoderRate() { return 0; }
+
+ /**
+ * Resets the encoder to zero distance.
+ */
+ void ResetEncoder() {}
+
+ void Set(double speed) override {}
+
+ double Get() const override { return 0; }
+
+ void SetInverted(bool isInverted) override {}
+
+ bool GetInverted() const override { return false; }
+
+ void Disable() override {}
+
+ void StopMotor() override {}
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/ElevatorExponentialSimulation/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/ElevatorExponentialSimulation/cpp/Robot.cpp
new file mode 100644
index 0000000..a6cb55d
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/ElevatorExponentialSimulation/cpp/Robot.cpp
@@ -0,0 +1,44 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "Robot.h"
+
+#include "Constants.h"
+
+void Robot::RobotPeriodic() {
+ // Update the telemetry, including mechanism visualization, regardless of
+ // mode.
+ m_elevator.UpdateTelemetry();
+}
+
+void Robot::SimulationPeriodic() {
+ // Update the simulation model.
+ m_elevator.SimulationPeriodic();
+}
+
+void Robot::TeleopInit() {
+ // This just makes sure that our simulation code knows that the motor's off.
+ m_elevator.Reset();
+}
+
+void Robot::TeleopPeriodic() {
+ if (m_joystick.GetTrigger()) {
+ // Here, we set the constant setpoint of 0.75 meters.
+ m_elevator.ReachGoal(Constants::kSetpoint);
+ } else {
+ // Otherwise, we update the setpoint to 0.
+ m_elevator.ReachGoal(Constants::kLowerSetpoint);
+ }
+}
+
+void Robot::DisabledInit() {
+ // This just makes sure that our simulation code knows that the motor's off.
+ m_elevator.Stop();
+}
+
+#ifndef RUNNING_FRC_TESTS
+int main() {
+ return frc::StartRobot<Robot>();
+}
+#endif
diff --git a/wpilibcExamples/src/main/cpp/examples/ElevatorExponentialSimulation/cpp/subsystems/Elevator.cpp b/wpilibcExamples/src/main/cpp/examples/ElevatorExponentialSimulation/cpp/subsystems/Elevator.cpp
new file mode 100644
index 0000000..27832a6
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/ElevatorExponentialSimulation/cpp/subsystems/Elevator.cpp
@@ -0,0 +1,64 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "subsystems/Elevator.h"
+
+#include <frc/RobotController.h>
+#include <frc/StateSpaceUtil.h>
+#include <frc/smartdashboard/SmartDashboard.h>
+
+Elevator::Elevator() {
+ m_encoder.SetDistancePerPulse(Constants::kArmEncoderDistPerPulse);
+
+ // Put Mechanism 2d to SmartDashboard
+ // To view the Elevator visualization, select Network Tables -> SmartDashboard
+ // -> Elevator Sim
+ frc::SmartDashboard::PutData("Elevator Sim", &m_mech2d);
+}
+
+void Elevator::SimulationPeriodic() {
+ // In this method, we update our simulation of what our elevator is doing
+ // First, we set our "inputs" (voltages)
+ m_elevatorSim.SetInput(frc::Vectord<1>{
+ m_motorSim.GetSpeed() * frc::RobotController::GetInputVoltage()});
+
+ // Next, we update it. The standard loop time is 20ms.
+ m_elevatorSim.Update(20_ms);
+
+ // Finally, we set our simulated encoder's readings and simulated battery
+ // voltage
+ m_encoderSim.SetDistance(m_elevatorSim.GetPosition().value());
+ // SimBattery estimates loaded battery voltages
+ frc::sim::RoboRioSim::SetVInVoltage(
+ frc::sim::BatterySim::Calculate({m_elevatorSim.GetCurrentDraw()}));
+}
+
+void Elevator::UpdateTelemetry() {
+ // Update the Elevator length based on the simulated elevator height
+ m_elevatorMech2d->SetLength(m_encoder.GetDistance());
+}
+
+void Elevator::ReachGoal(units::meter_t goal) {
+ frc::ExponentialProfile<units::meters, units::volts>::State goalState{goal,
+ 0_mps};
+
+ auto next = m_profile.Calculate(20_ms, m_setpoint, goalState);
+
+ auto pidOutput = m_controller.Calculate(m_encoder.GetDistance(),
+ m_setpoint.position / 1_m);
+ auto feedforwardOutput =
+ m_feedforward.Calculate(m_setpoint.velocity, next.velocity, 20_ms);
+
+ m_motor.SetVoltage(units::volt_t{pidOutput} + feedforwardOutput);
+
+ m_setpoint = next;
+}
+
+void Elevator::Reset() {
+ m_setpoint = {m_encoder.GetDistance() * 1_m, 0_mps};
+}
+
+void Elevator::Stop() {
+ m_motor.Set(0.0);
+}
diff --git a/wpilibcExamples/src/main/cpp/examples/ElevatorExponentialSimulation/include/Constants.h b/wpilibcExamples/src/main/cpp/examples/ElevatorExponentialSimulation/include/Constants.h
new file mode 100644
index 0000000..7c53018
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/ElevatorExponentialSimulation/include/Constants.h
@@ -0,0 +1,57 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <numbers>
+
+#include <units/acceleration.h>
+#include <units/angle.h>
+#include <units/length.h>
+#include <units/mass.h>
+#include <units/time.h>
+#include <units/velocity.h>
+#include <units/voltage.h>
+
+/**
+ * The Constants header provides a convenient place for teams to hold robot-wide
+ * numerical or bool constants. This should not be used for any other purpose.
+ *
+ * It is generally a good idea to place constants into subsystem- or
+ * command-specific namespaces within this header, which can then be used where
+ * they are needed.
+ */
+
+namespace Constants {
+
+static constexpr int kMotorPort = 0;
+static constexpr int kEncoderAChannel = 0;
+static constexpr int kEncoderBChannel = 1;
+static constexpr int kJoystickPort = 0;
+
+static constexpr double kElevatorKp = 0.75;
+static constexpr double kElevatorKi = 0.0;
+static constexpr double kElevatorKd = 0.0;
+
+static constexpr units::volt_t kElevatorMaxV = 10_V;
+static constexpr units::volt_t kElevatorkS = 0.0_V;
+static constexpr units::volt_t kElevatorkG = 0.62_V;
+static constexpr auto kElevatorkV = 3.9_V / 1_mps;
+static constexpr auto kElevatorkA = 0.06_V / 1_mps_sq;
+
+static constexpr double kElevatorGearing = 5.0;
+static constexpr units::meter_t kElevatorDrumRadius = 1_in;
+static constexpr units::kilogram_t kCarriageMass = 12_lb;
+
+static constexpr units::meter_t kSetpoint = 42.875_in;
+static constexpr units::meter_t kLowerSetpoint = 15_in;
+static constexpr units::meter_t kMinElevatorHeight = 0_cm;
+static constexpr units::meter_t kMaxElevatorHeight = 50_in;
+
+// distance per pulse = (distance per revolution) / (pulses per revolution)
+// = (Pi * D) / ppr
+static constexpr double kArmEncoderDistPerPulse =
+ 2.0 * std::numbers::pi * kElevatorDrumRadius.value() / 4096.0;
+
+} // namespace Constants
diff --git a/wpilibcExamples/src/main/cpp/examples/ElevatorExponentialSimulation/include/Robot.h b/wpilibcExamples/src/main/cpp/examples/ElevatorExponentialSimulation/include/Robot.h
new file mode 100644
index 0000000..f103104
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/ElevatorExponentialSimulation/include/Robot.h
@@ -0,0 +1,27 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <frc/Joystick.h>
+#include <frc/TimedRobot.h>
+
+#include "subsystems/Elevator.h"
+
+/**
+ * This is a sample program to demonstrate the use of elevator simulation.
+ */
+class Robot : public frc::TimedRobot {
+ public:
+ void RobotInit() override {}
+ void RobotPeriodic() override;
+ void SimulationPeriodic() override;
+ void TeleopInit() override;
+ void TeleopPeriodic() override;
+ void DisabledInit() override;
+
+ private:
+ frc::Joystick m_joystick{Constants::kJoystickPort};
+ Elevator m_elevator;
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/ElevatorExponentialSimulation/include/subsystems/Elevator.h b/wpilibcExamples/src/main/cpp/examples/ElevatorExponentialSimulation/include/subsystems/Elevator.h
new file mode 100644
index 0000000..afc5267
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/ElevatorExponentialSimulation/include/subsystems/Elevator.h
@@ -0,0 +1,74 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <frc/Encoder.h>
+#include <frc/controller/ElevatorFeedforward.h>
+#include <frc/controller/PIDController.h>
+#include <frc/motorcontrol/PWMSparkMax.h>
+#include <frc/simulation/BatterySim.h>
+#include <frc/simulation/ElevatorSim.h>
+#include <frc/simulation/EncoderSim.h>
+#include <frc/simulation/PWMSim.h>
+#include <frc/simulation/RoboRioSim.h>
+#include <frc/smartdashboard/Mechanism2d.h>
+#include <frc/smartdashboard/MechanismLigament2d.h>
+#include <frc/smartdashboard/MechanismRoot2d.h>
+#include <frc/trajectory/ExponentialProfile.h>
+#include <units/length.h>
+
+#include "Constants.h"
+
+class Elevator {
+ public:
+ Elevator();
+ void SimulationPeriodic();
+ void UpdateTelemetry();
+ void ReachGoal(units::meter_t goal);
+ void Reset();
+ void Stop();
+
+ private:
+ // This gearbox represents a gearbox containing 4 Vex 775pro motors.
+ frc::DCMotor m_elevatorGearbox = frc::DCMotor::NEO(2);
+
+ // Standard classes for controlling our elevator
+ frc::ExponentialProfile<units::meters, units::volts>::Constraints
+ m_constraints{Constants::kElevatorMaxV, Constants::kElevatorkV,
+ Constants::kElevatorkA};
+ frc::ExponentialProfile<units::meters, units::volts> m_profile{m_constraints};
+ frc::ExponentialProfile<units::meters, units::volts>::State m_setpoint;
+
+ frc::PIDController m_controller{
+ Constants::kElevatorKp, Constants::kElevatorKi, Constants::kElevatorKd};
+
+ frc::ElevatorFeedforward m_feedforward{
+ Constants::kElevatorkS, Constants::kElevatorkG, Constants::kElevatorkV,
+ Constants::kElevatorkA};
+ frc::Encoder m_encoder{Constants::kEncoderAChannel,
+ Constants::kEncoderBChannel};
+ frc::PWMSparkMax m_motor{Constants::kMotorPort};
+ frc::sim::PWMSim m_motorSim{m_motor};
+
+ // Simulation classes help us simulate what's going on, including gravity.
+ frc::sim::ElevatorSim m_elevatorSim{m_elevatorGearbox,
+ Constants::kElevatorGearing,
+ Constants::kCarriageMass,
+ Constants::kElevatorDrumRadius,
+ Constants::kMinElevatorHeight,
+ Constants::kMaxElevatorHeight,
+ true,
+ 0_m,
+ {0.005}};
+ frc::sim::EncoderSim m_encoderSim{m_encoder};
+
+ // Create a Mechanism2d display of an elevator
+ frc::Mechanism2d m_mech2d{10_in / 1_m, 51_in / 1_m};
+ frc::MechanismRoot2d* m_elevatorRoot =
+ m_mech2d.GetRoot("Elevator Root", 5_in / 1_m, 0.5_in / 1_m);
+ frc::MechanismLigament2d* m_elevatorMech2d =
+ m_elevatorRoot->Append<frc::MechanismLigament2d>(
+ "Elevator", m_elevatorSim.GetPosition().value(), 90_deg);
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/ElevatorProfiledPID/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/ElevatorProfiledPID/cpp/Robot.cpp
index 518114a..51fc29e 100644
--- a/wpilibcExamples/src/main/cpp/examples/ElevatorProfiledPID/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/ElevatorProfiledPID/cpp/Robot.cpp
@@ -7,6 +7,7 @@
#include <frc/Encoder.h>
#include <frc/Joystick.h>
#include <frc/TimedRobot.h>
+#include <frc/controller/ElevatorFeedforward.h>
#include <frc/controller/ProfiledPIDController.h>
#include <frc/motorcontrol/PWMSparkMax.h>
#include <frc/trajectory/TrapezoidProfile.h>
@@ -14,6 +15,7 @@
#include <units/length.h>
#include <units/time.h>
#include <units/velocity.h>
+#include <units/voltage.h>
class Robot : public frc::TimedRobot {
public:
@@ -31,21 +33,34 @@
}
// Run controller and update motor output
- m_motor.Set(
- m_controller.Calculate(units::meter_t{m_encoder.GetDistance()}));
+ m_motor.SetVoltage(
+ units::volt_t{
+ m_controller.Calculate(units::meter_t{m_encoder.GetDistance()})} +
+ m_feedforward.Calculate(m_controller.GetSetpoint().velocity));
}
private:
+ static constexpr units::meters_per_second_t kMaxVelocity = 1.75_mps;
+ static constexpr units::meters_per_second_squared_t kMaxAcceleration =
+ 0.75_mps_sq;
+ static constexpr double kP = 1.3;
+ static constexpr double kI = 0.0;
+ static constexpr double kD = 0.7;
+ static constexpr units::volt_t kS = 1.1_V;
+ static constexpr units::volt_t kG = 1.2_V;
+ static constexpr auto kV = 1.3_V / 1_mps;
+
frc::Joystick m_joystick{1};
frc::Encoder m_encoder{1, 2};
frc::PWMSparkMax m_motor{1};
// Create a PID controller whose setpoint's change is subject to maximum
// velocity and acceleration constraints.
- frc::TrapezoidProfile<units::meters>::Constraints m_constraints{1.75_mps,
- 0.75_mps_sq};
- frc::ProfiledPIDController<units::meters> m_controller{1.3, 0.0, 0.7,
+ frc::TrapezoidProfile<units::meters>::Constraints m_constraints{
+ kMaxVelocity, kMaxAcceleration};
+ frc::ProfiledPIDController<units::meters> m_controller{kP, kI, kD,
m_constraints, kDt};
+ frc::ElevatorFeedforward m_feedforward{kS, kG, kV};
};
#ifndef RUNNING_FRC_TESTS
diff --git a/wpilibcExamples/src/main/cpp/examples/ElevatorSimulation/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/ElevatorSimulation/cpp/Robot.cpp
index 039a499..1be347c 100644
--- a/wpilibcExamples/src/main/cpp/examples/ElevatorSimulation/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/ElevatorSimulation/cpp/Robot.cpp
@@ -2,130 +2,35 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
-#include <numbers>
+#include "Robot.h"
-#include <frc/Encoder.h>
-#include <frc/Joystick.h>
-#include <frc/RobotController.h>
-#include <frc/StateSpaceUtil.h>
-#include <frc/TimedRobot.h>
-#include <frc/controller/PIDController.h>
-#include <frc/motorcontrol/PWMSparkMax.h>
-#include <frc/simulation/BatterySim.h>
-#include <frc/simulation/ElevatorSim.h>
-#include <frc/simulation/EncoderSim.h>
-#include <frc/simulation/RoboRioSim.h>
-#include <frc/smartdashboard/Mechanism2d.h>
-#include <frc/smartdashboard/MechanismLigament2d.h>
-#include <frc/smartdashboard/MechanismRoot2d.h>
-#include <frc/smartdashboard/SmartDashboard.h>
-#include <frc/system/plant/LinearSystemId.h>
-#include <frc/util/Color.h>
-#include <frc/util/Color8Bit.h>
-#include <units/angle.h>
-#include <units/length.h>
-#include <units/moment_of_inertia.h>
+#include "Constants.h"
-/**
- * This is a sample program to demonstrate how to use a state-space controller
- * to control an arm.
- */
-class Robot : public frc::TimedRobot {
- static constexpr int kMotorPort = 0;
- static constexpr int kEncoderAChannel = 0;
- static constexpr int kEncoderBChannel = 1;
- static constexpr int kJoystickPort = 0;
+void Robot::RobotPeriodic() {
+ // Update the telemetry, including mechanism visualization, regardless of
+ // mode.
+ m_elevator.UpdateTelemetry();
+}
- static constexpr double kElevatorKp = 5.0;
- static constexpr double kElevatorGearing = 10.0;
- static constexpr units::meter_t kElevatorDrumRadius = 2_in;
- static constexpr units::kilogram_t kCarriageMass = 4.0_kg;
+void Robot::SimulationPeriodic() {
+ // Update the simulation model.
+ m_elevator.SimulationPeriodic();
+}
- static constexpr units::meter_t kMinElevatorHeight = 2_in;
- static constexpr units::meter_t kMaxElevatorHeight = 50_in;
-
- // distance per pulse = (distance per revolution) / (pulses per revolution)
- // = (Pi * D) / ppr
- static constexpr double kArmEncoderDistPerPulse =
- 2.0 * std::numbers::pi * kElevatorDrumRadius.value() / 4096.0;
-
- // This gearbox represents a gearbox containing 4 Vex 775pro motors.
- frc::DCMotor m_elevatorGearbox = frc::DCMotor::Vex775Pro(4);
-
- // Standard classes for controlling our elevator
- frc2::PIDController m_controller{kElevatorKp, 0, 0};
- frc::Encoder m_encoder{kEncoderAChannel, kEncoderBChannel};
- frc::PWMSparkMax m_motor{kMotorPort};
- frc::Joystick m_joystick{kJoystickPort};
-
- // Simulation classes help us simulate what's going on, including gravity.
- frc::sim::ElevatorSim m_elevatorSim{m_elevatorGearbox,
- kElevatorGearing,
- kCarriageMass,
- kElevatorDrumRadius,
- kMinElevatorHeight,
- kMaxElevatorHeight,
- true,
- {0.01}};
- frc::sim::EncoderSim m_encoderSim{m_encoder};
-
- // Create a Mechanism2d display of an elevator
- frc::Mechanism2d m_mech2d{20, 50};
- frc::MechanismRoot2d* m_elevatorRoot =
- m_mech2d.GetRoot("Elevator Root", 10, 0);
- frc::MechanismLigament2d* m_elevatorMech2d =
- m_elevatorRoot->Append<frc::MechanismLigament2d>(
- "Elevator", units::inch_t{m_elevatorSim.GetPosition()}.value(),
- 90_deg);
-
- public:
- void RobotInit() override {
- m_encoder.SetDistancePerPulse(kArmEncoderDistPerPulse);
-
- // Put Mechanism 2d to SmartDashboard
- // To view the Elevator Sim in the simulator, select Network Tables ->
- // SmartDashboard -> Elevator Sim
- frc::SmartDashboard::PutData("Elevator Sim", &m_mech2d);
+void Robot::TeleopPeriodic() {
+ if (m_joystick.GetTrigger()) {
+ // Here, we set the constant setpoint of 0.75 meters.
+ m_elevator.ReachGoal(Constants::kSetpoint);
+ } else {
+ // Otherwise, we update the setpoint to 0.
+ m_elevator.ReachGoal(0.0_m);
}
+}
- void SimulationPeriodic() override {
- // In this method, we update our simulation of what our elevator is doing
- // First, we set our "inputs" (voltages)
- m_elevatorSim.SetInput(frc::Vectord<1>{
- m_motor.Get() * frc::RobotController::GetInputVoltage()});
-
- // Next, we update it. The standard loop time is 20ms.
- m_elevatorSim.Update(20_ms);
-
- // Finally, we set our simulated encoder's readings and simulated battery
- // voltage
- m_encoderSim.SetDistance(m_elevatorSim.GetPosition().value());
- // SimBattery estimates loaded battery voltages
- frc::sim::RoboRioSim::SetVInVoltage(
- frc::sim::BatterySim::Calculate({m_elevatorSim.GetCurrentDraw()}));
-
- // Update the Elevator length based on the simulated elevator height
- m_elevatorMech2d->SetLength(
- units::inch_t{m_elevatorSim.GetPosition()}.value());
- }
-
- void TeleopPeriodic() override {
- if (m_joystick.GetTrigger()) {
- // Here, we run PID control like normal, with a constant setpoint of 30in.
- double pidOutput = m_controller.Calculate(m_encoder.GetDistance(),
- units::meter_t{30_in}.value());
- m_motor.SetVoltage(units::volt_t{pidOutput});
- } else {
- // Otherwise, we disable the motor.
- m_motor.Set(0.0);
- }
- }
-
- void DisabledInit() override {
- // This just makes sure that our simulation code knows that the motor's off.
- m_motor.Set(0.0);
- }
-};
+void Robot::DisabledInit() {
+ // This just makes sure that our simulation code knows that the motor's off.
+ m_elevator.Stop();
+}
#ifndef RUNNING_FRC_TESTS
int main() {
diff --git a/wpilibcExamples/src/main/cpp/examples/ElevatorSimulation/cpp/subsystems/Elevator.cpp b/wpilibcExamples/src/main/cpp/examples/ElevatorSimulation/cpp/subsystems/Elevator.cpp
new file mode 100644
index 0000000..35e11ff
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/ElevatorSimulation/cpp/subsystems/Elevator.cpp
@@ -0,0 +1,55 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "subsystems/Elevator.h"
+
+#include <frc/RobotController.h>
+#include <frc/StateSpaceUtil.h>
+#include <frc/smartdashboard/SmartDashboard.h>
+
+Elevator::Elevator() {
+ m_encoder.SetDistancePerPulse(Constants::kArmEncoderDistPerPulse);
+
+ // Put Mechanism 2d to SmartDashboard
+ // To view the Elevator visualization, select Network Tables -> SmartDashboard
+ // -> Elevator Sim
+ frc::SmartDashboard::PutData("Elevator Sim", &m_mech2d);
+}
+
+void Elevator::SimulationPeriodic() {
+ // In this method, we update our simulation of what our elevator is doing
+ // First, we set our "inputs" (voltages)
+ m_elevatorSim.SetInput(frc::Vectord<1>{
+ m_motorSim.GetSpeed() * frc::RobotController::GetInputVoltage()});
+
+ // Next, we update it. The standard loop time is 20ms.
+ m_elevatorSim.Update(20_ms);
+
+ // Finally, we set our simulated encoder's readings and simulated battery
+ // voltage
+ m_encoderSim.SetDistance(m_elevatorSim.GetPosition().value());
+ // SimBattery estimates loaded battery voltages
+ frc::sim::RoboRioSim::SetVInVoltage(
+ frc::sim::BatterySim::Calculate({m_elevatorSim.GetCurrentDraw()}));
+}
+
+void Elevator::UpdateTelemetry() {
+ // Update the Elevator length based on the simulated elevator height
+ m_elevatorMech2d->SetLength(m_encoder.GetDistance());
+}
+
+void Elevator::ReachGoal(units::meter_t goal) {
+ m_controller.SetGoal(goal);
+ // With the setpoint value we run PID control like normal
+ double pidOutput =
+ m_controller.Calculate(units::meter_t{m_encoder.GetDistance()});
+ units::volt_t feedforwardOutput =
+ m_feedforward.Calculate(m_controller.GetSetpoint().velocity);
+ m_motor.SetVoltage(units::volt_t{pidOutput} + feedforwardOutput);
+}
+
+void Elevator::Stop() {
+ m_controller.SetGoal(0.0_m);
+ m_motor.Set(0.0);
+}
diff --git a/wpilibcExamples/src/main/cpp/examples/ElevatorSimulation/include/Constants.h b/wpilibcExamples/src/main/cpp/examples/ElevatorSimulation/include/Constants.h
new file mode 100644
index 0000000..7be706f
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/ElevatorSimulation/include/Constants.h
@@ -0,0 +1,55 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <numbers>
+
+#include <units/acceleration.h>
+#include <units/angle.h>
+#include <units/length.h>
+#include <units/mass.h>
+#include <units/time.h>
+#include <units/velocity.h>
+#include <units/voltage.h>
+
+/**
+ * The Constants header provides a convenient place for teams to hold robot-wide
+ * numerical or bool constants. This should not be used for any other purpose.
+ *
+ * It is generally a good idea to place constants into subsystem- or
+ * command-specific namespaces within this header, which can then be used where
+ * they are needed.
+ */
+
+namespace Constants {
+
+static constexpr int kMotorPort = 0;
+static constexpr int kEncoderAChannel = 0;
+static constexpr int kEncoderBChannel = 1;
+static constexpr int kJoystickPort = 0;
+
+static constexpr double kElevatorKp = 5.0;
+static constexpr double kElevatorKi = 0.0;
+static constexpr double kElevatorKd = 0.0;
+
+static constexpr units::volt_t kElevatorkS = 0.0_V;
+static constexpr units::volt_t kElevatorkG = 0.762_V;
+static constexpr auto kElevatorkV = 0.762_V / 1_mps;
+static constexpr auto kElevatorkA = 0.0_V / 1_mps_sq;
+
+static constexpr double kElevatorGearing = 10.0;
+static constexpr units::meter_t kElevatorDrumRadius = 2_in;
+static constexpr units::kilogram_t kCarriageMass = 4.0_kg;
+
+static constexpr units::meter_t kSetpoint = 75_cm;
+static constexpr units::meter_t kMinElevatorHeight = 0_cm;
+static constexpr units::meter_t kMaxElevatorHeight = 1.25_m;
+
+// distance per pulse = (distance per revolution) / (pulses per revolution)
+// = (Pi * D) / ppr
+static constexpr double kArmEncoderDistPerPulse =
+ 2.0 * std::numbers::pi * kElevatorDrumRadius.value() / 4096.0;
+
+} // namespace Constants
diff --git a/wpilibcExamples/src/main/cpp/examples/ElevatorSimulation/include/Robot.h b/wpilibcExamples/src/main/cpp/examples/ElevatorSimulation/include/Robot.h
new file mode 100644
index 0000000..53f50ea
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/ElevatorSimulation/include/Robot.h
@@ -0,0 +1,26 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <frc/Joystick.h>
+#include <frc/TimedRobot.h>
+
+#include "subsystems/Elevator.h"
+
+/**
+ * This is a sample program to demonstrate the use of elevator simulation.
+ */
+class Robot : public frc::TimedRobot {
+ public:
+ void RobotInit() override {}
+ void RobotPeriodic() override;
+ void SimulationPeriodic() override;
+ void TeleopPeriodic() override;
+ void DisabledInit() override;
+
+ private:
+ frc::Joystick m_joystick{Constants::kJoystickPort};
+ Elevator m_elevator;
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/ElevatorSimulation/include/subsystems/Elevator.h b/wpilibcExamples/src/main/cpp/examples/ElevatorSimulation/include/subsystems/Elevator.h
new file mode 100644
index 0000000..4b07189
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/ElevatorSimulation/include/subsystems/Elevator.h
@@ -0,0 +1,70 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <frc/Encoder.h>
+#include <frc/controller/ElevatorFeedforward.h>
+#include <frc/controller/PIDController.h>
+#include <frc/controller/ProfiledPIDController.h>
+#include <frc/motorcontrol/PWMSparkMax.h>
+#include <frc/simulation/BatterySim.h>
+#include <frc/simulation/ElevatorSim.h>
+#include <frc/simulation/EncoderSim.h>
+#include <frc/simulation/PWMSim.h>
+#include <frc/simulation/RoboRioSim.h>
+#include <frc/smartdashboard/Mechanism2d.h>
+#include <frc/smartdashboard/MechanismLigament2d.h>
+#include <frc/smartdashboard/MechanismRoot2d.h>
+#include <units/length.h>
+
+#include "Constants.h"
+
+class Elevator {
+ public:
+ Elevator();
+ void SimulationPeriodic();
+ void UpdateTelemetry();
+ void ReachGoal(units::meter_t goal);
+ void Stop();
+
+ private:
+ // This gearbox represents a gearbox containing 4 Vex 775pro motors.
+ frc::DCMotor m_elevatorGearbox = frc::DCMotor::Vex775Pro(4);
+
+ // Standard classes for controlling our elevator
+ frc::TrapezoidProfile<units::meters>::Constraints m_constraints{2.45_mps,
+ 2.45_mps_sq};
+ frc::ProfiledPIDController<units::meters> m_controller{
+ Constants::kElevatorKp, Constants::kElevatorKi, Constants::kElevatorKd,
+ m_constraints};
+
+ frc::ElevatorFeedforward m_feedforward{
+ Constants::kElevatorkS, Constants::kElevatorkG, Constants::kElevatorkV,
+ Constants::kElevatorkA};
+ frc::Encoder m_encoder{Constants::kEncoderAChannel,
+ Constants::kEncoderBChannel};
+ frc::PWMSparkMax m_motor{Constants::kMotorPort};
+ frc::sim::PWMSim m_motorSim{m_motor};
+
+ // Simulation classes help us simulate what's going on, including gravity.
+ frc::sim::ElevatorSim m_elevatorSim{m_elevatorGearbox,
+ Constants::kElevatorGearing,
+ Constants::kCarriageMass,
+ Constants::kElevatorDrumRadius,
+ Constants::kMinElevatorHeight,
+ Constants::kMaxElevatorHeight,
+ true,
+ 0_m,
+ {0.01}};
+ frc::sim::EncoderSim m_encoderSim{m_encoder};
+
+ // Create a Mechanism2d display of an elevator
+ frc::Mechanism2d m_mech2d{20, 50};
+ frc::MechanismRoot2d* m_elevatorRoot =
+ m_mech2d.GetRoot("Elevator Root", 10, 0);
+ frc::MechanismLigament2d* m_elevatorMech2d =
+ m_elevatorRoot->Append<frc::MechanismLigament2d>(
+ "Elevator", m_elevatorSim.GetPosition().value(), 90_deg);
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/ElevatorTrapezoidProfile/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/ElevatorTrapezoidProfile/cpp/Robot.cpp
index f708143..fb3a70d 100644
--- a/wpilibcExamples/src/main/cpp/examples/ElevatorTrapezoidProfile/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/ElevatorTrapezoidProfile/cpp/Robot.cpp
@@ -32,15 +32,9 @@
m_goal = {0_m, 0_mps};
}
- // Create a motion profile with the given maximum velocity and maximum
- // acceleration constraints for the next setpoint, the desired goal, and the
- // current setpoint.
- frc::TrapezoidProfile<units::meters> profile{m_constraints, m_goal,
- m_setpoint};
-
// Retrieve the profiled setpoint for the next timestep. This setpoint moves
// toward the goal while obeying the constraints.
- m_setpoint = profile.Calculate(kDt);
+ m_setpoint = m_profile.Calculate(kDt, m_goal, m_setpoint);
// Send setpoint to offboard controller PID
m_motor.SetSetpoint(ExampleSmartMotorController::PIDMode::kPosition,
@@ -55,8 +49,9 @@
// Note: These gains are fake, and will have to be tuned for your robot.
1_V, 1.5_V * 1_s / 1_m};
- frc::TrapezoidProfile<units::meters>::Constraints m_constraints{1.75_mps,
- 0.75_mps_sq};
+ // Create a motion profile with the given maximum velocity and maximum
+ // acceleration constraints for the next setpoint.
+ frc::TrapezoidProfile<units::meters> m_profile{{1.75_mps, 0.75_mps_sq}};
frc::TrapezoidProfile<units::meters>::State m_goal;
frc::TrapezoidProfile<units::meters>::State m_setpoint;
};
diff --git a/wpilibcExamples/src/main/cpp/examples/FlywheelBangBangController/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/FlywheelBangBangController/cpp/Robot.cpp
new file mode 100644
index 0000000..86807e6
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/FlywheelBangBangController/cpp/Robot.cpp
@@ -0,0 +1,104 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include <frc/Encoder.h>
+#include <frc/Joystick.h>
+#include <frc/TimedRobot.h>
+#include <frc/controller/BangBangController.h>
+#include <frc/controller/SimpleMotorFeedforward.h>
+#include <frc/motorcontrol/PWMSparkMax.h>
+#include <frc/simulation/EncoderSim.h>
+#include <frc/simulation/FlywheelSim.h>
+#include <frc/smartdashboard/SmartDashboard.h>
+#include <units/moment_of_inertia.h>
+
+/**
+ * This is a sample program to demonstrate the use of a BangBangController with
+ * a flywheel to control speed.
+ */
+class Robot : public frc::TimedRobot {
+ public:
+ /**
+ * Controls flywheel to a set speed (RPM) controlled by a joystick.
+ */
+ void TeleopPeriodic() override {
+ // Scale setpoint value between 0 and maxSetpointValue
+ units::radians_per_second_t setpoint =
+ units::math::max(0_rpm, m_joystick.GetRawAxis(0) * kMaxSetpointValue);
+
+ // Set setpoint and measurement of the bang-bang controller
+ units::volt_t bangOutput =
+ m_bangBangControler.Calculate(m_encoder.GetRate(), setpoint.value()) *
+ 12_V;
+
+ // Controls a motor with the output of the BangBang controller and a
+ // feedforward. The feedforward is reduced slightly to avoid overspeeding
+ // the shooter.
+ m_flywheelMotor.SetVoltage(bangOutput +
+ 0.9 * m_feedforward.Calculate(setpoint));
+ }
+
+ void RobotInit() override {
+ // Add bang-bang controler to SmartDashboard and networktables.
+ frc::SmartDashboard::PutData("BangBangControler", &m_bangBangControler);
+ }
+
+ /**
+ * Update our simulation. This should be run every robot loop in simulation.
+ */
+ void SimulationPeriodic() override {
+ // To update our simulation, we set motor voltage inputs, update the
+ // simulation, and write the simulated velocities to our simulated encoder
+ m_flywheelSim.SetInputVoltage(
+ m_flywheelMotor.Get() *
+ units::volt_t{frc::RobotController::GetInputVoltage()});
+ m_flywheelSim.Update(0.02_s);
+ m_encoderSim.SetRate(m_flywheelSim.GetAngularVelocity().value());
+ }
+
+ private:
+ static constexpr int kMotorPort = 0;
+ static constexpr int kEncoderAChannel = 0;
+ static constexpr int kEncoderBChannel = 1;
+
+ // Max setpoint for joystick control
+ static constexpr units::radians_per_second_t kMaxSetpointValue = 6000_rpm;
+
+ // Joystick to control setpoint
+ frc::Joystick m_joystick{0};
+
+ frc::PWMSparkMax m_flywheelMotor{kMotorPort};
+ frc::Encoder m_encoder{kEncoderAChannel, kEncoderBChannel};
+
+ frc::BangBangController m_bangBangControler;
+
+ // Gains are for example purposes only - must be determined for your own
+ // robot!
+ static constexpr units::volt_t kFlywheelKs = 0.0001_V;
+ static constexpr decltype(1_V / 1_rad_per_s) kFlywheelKv = 0.000195_V / 1_rpm;
+ static constexpr decltype(1_V / 1_rad_per_s_sq) kFlywheelKa =
+ 0.0003_V / 1_rev_per_m_per_s;
+ frc::SimpleMotorFeedforward<units::radians> m_feedforward{
+ kFlywheelKs, kFlywheelKv, kFlywheelKa};
+
+ // Simulation classes help us simulate our robot
+
+ // Reduction between motors and encoder, as output over input. If the flywheel
+ // spins slower than the motors, this number should be greater than one.
+ static constexpr double kFlywheelGearing = 1.0;
+
+ // 1/2 MR²
+ static constexpr units::kilogram_square_meter_t kFlywheelMomentOfInertia =
+ 0.5 * 1.5_lb * 4_in * 4_in;
+
+ frc::sim::FlywheelSim m_flywheelSim{frc::DCMotor::NEO(1), kFlywheelGearing,
+ kFlywheelMomentOfInertia};
+ frc::sim::EncoderSim m_encoderSim{m_encoder};
+};
+
+#ifndef RUNNING_FRC_TESTS
+int main() {
+ return frc::StartRobot<Robot>();
+}
+#endif
diff --git a/wpilibcExamples/src/main/cpp/examples/Frisbeebot/cpp/subsystems/ShooterSubsystem.cpp b/wpilibcExamples/src/main/cpp/examples/Frisbeebot/cpp/subsystems/ShooterSubsystem.cpp
index aec84f1..cff73da 100644
--- a/wpilibcExamples/src/main/cpp/examples/Frisbeebot/cpp/subsystems/ShooterSubsystem.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/Frisbeebot/cpp/subsystems/ShooterSubsystem.cpp
@@ -11,7 +11,7 @@
using namespace ShooterConstants;
ShooterSubsystem::ShooterSubsystem()
- : PIDSubsystem{frc2::PIDController{kP, kI, kD}},
+ : PIDSubsystem{frc::PIDController{kP, kI, kD}},
m_shooterMotor(kShooterMotorPort),
m_feederMotor(kFeederMotorPort),
m_shooterEncoder(kEncoderPorts[0], kEncoderPorts[1]),
diff --git a/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/CloseClaw.cpp b/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/CloseClaw.cpp
index 75884a2..0b6b8b0 100644
--- a/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/CloseClaw.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/CloseClaw.cpp
@@ -8,7 +8,7 @@
CloseClaw::CloseClaw(Claw& claw) : m_claw(&claw) {
SetName("CloseClaw");
- AddRequirements({m_claw});
+ AddRequirements(m_claw);
}
// Called just before this Command runs the first time
diff --git a/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/DriveStraight.cpp b/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/DriveStraight.cpp
index c1f5d88..6325307 100644
--- a/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/DriveStraight.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/DriveStraight.cpp
@@ -10,7 +10,7 @@
DriveStraight::DriveStraight(double distance, Drivetrain& drivetrain)
: frc2::CommandHelper<frc2::PIDCommand, DriveStraight>{
- frc2::PIDController{4, 0, 0},
+ frc::PIDController{4, 0, 0},
[&drivetrain] { return drivetrain.GetDistance(); },
distance,
[&drivetrain](double output) { drivetrain.Drive(output, output); },
diff --git a/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/OpenClaw.cpp b/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/OpenClaw.cpp
index e5bab77..371ba85 100644
--- a/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/OpenClaw.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/OpenClaw.cpp
@@ -9,7 +9,7 @@
OpenClaw::OpenClaw(Claw& claw)
: frc2::CommandHelper<frc2::WaitCommand, OpenClaw>(1_s), m_claw(&claw) {
SetName("OpenClaw");
- AddRequirements({m_claw});
+ AddRequirements(m_claw);
}
// Called just before this Command runs the first time
diff --git a/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/SetDistanceToBox.cpp b/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/SetDistanceToBox.cpp
index de8f1e7..1ef5cbb 100644
--- a/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/SetDistanceToBox.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/SetDistanceToBox.cpp
@@ -10,7 +10,7 @@
SetDistanceToBox::SetDistanceToBox(double distance, Drivetrain& drivetrain)
: frc2::CommandHelper<frc2::PIDCommand, SetDistanceToBox>{
- frc2::PIDController{-2, 0, 0},
+ frc::PIDController{-2, 0, 0},
[&drivetrain] { return drivetrain.GetDistanceToObstacle(); },
distance,
[&drivetrain](double output) { drivetrain.Drive(output, output); },
diff --git a/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/SetElevatorSetpoint.cpp b/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/SetElevatorSetpoint.cpp
index 08343fe..d8a2f08 100644
--- a/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/SetElevatorSetpoint.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/SetElevatorSetpoint.cpp
@@ -11,7 +11,7 @@
SetElevatorSetpoint::SetElevatorSetpoint(double setpoint, Elevator& elevator)
: m_setpoint(setpoint), m_elevator(&elevator) {
SetName("SetElevatorSetpoint");
- AddRequirements({m_elevator});
+ AddRequirements(m_elevator);
}
// Called just before this Command runs the first time
diff --git a/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/SetWristSetpoint.cpp b/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/SetWristSetpoint.cpp
index 9697745..bed2ffe 100644
--- a/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/SetWristSetpoint.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/SetWristSetpoint.cpp
@@ -9,7 +9,7 @@
SetWristSetpoint::SetWristSetpoint(double setpoint, Wrist& wrist)
: m_setpoint(setpoint), m_wrist(&wrist) {
SetName("SetWristSetpoint");
- AddRequirements({m_wrist});
+ AddRequirements(m_wrist);
}
// Called just before this Command runs the first time
diff --git a/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/TankDrive.cpp b/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/TankDrive.cpp
index cc34e53..7021f9d 100644
--- a/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/TankDrive.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/commands/TankDrive.cpp
@@ -14,7 +14,7 @@
m_right(std::move(right)),
m_drivetrain(&drivetrain) {
SetName("TankDrive");
- AddRequirements({m_drivetrain});
+ AddRequirements(m_drivetrain);
}
// Called repeatedly when this Command is scheduled to run
diff --git a/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/subsystems/Elevator.cpp b/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/subsystems/Elevator.cpp
index c75c7bc..03db314 100644
--- a/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/subsystems/Elevator.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/subsystems/Elevator.cpp
@@ -9,7 +9,7 @@
#include <frc/smartdashboard/SmartDashboard.h>
Elevator::Elevator()
- : frc2::PIDSubsystem{frc2::PIDController{kP_real, kI_real, 0}} {
+ : frc2::PIDSubsystem{frc::PIDController{kP_real, kI_real, 0}} {
#ifdef SIMULATION // Check for simulation and update PID values
GetPIDController()->SetPID(kP_simulation, kI_simulation, 0, 0);
#endif
diff --git a/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/subsystems/Wrist.cpp b/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/subsystems/Wrist.cpp
index 8b24a7b..c0e06af 100644
--- a/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/subsystems/Wrist.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/GearsBot/cpp/subsystems/Wrist.cpp
@@ -7,7 +7,7 @@
#include <frc/controller/PIDController.h>
#include <frc/smartdashboard/SmartDashboard.h>
-Wrist::Wrist() : frc2::PIDSubsystem{frc2::PIDController{kP, 0, 0}} {
+Wrist::Wrist() : frc2::PIDSubsystem{frc::PIDController{kP, 0, 0}} {
m_controller.SetTolerance(2.5);
SetName("Wrist");
diff --git a/wpilibcExamples/src/main/cpp/examples/GearsBot/include/commands/CloseClaw.h b/wpilibcExamples/src/main/cpp/examples/GearsBot/include/commands/CloseClaw.h
index 0511604..31e2b92 100644
--- a/wpilibcExamples/src/main/cpp/examples/GearsBot/include/commands/CloseClaw.h
+++ b/wpilibcExamples/src/main/cpp/examples/GearsBot/include/commands/CloseClaw.h
@@ -4,7 +4,7 @@
#pragma once
-#include <frc2/command/CommandBase.h>
+#include <frc2/command/Command.h>
#include <frc2/command/CommandHelper.h>
#include "subsystems/Claw.h"
@@ -12,7 +12,7 @@
/**
* Closes the claw until the limit switch is tripped.
*/
-class CloseClaw : public frc2::CommandHelper<frc2::CommandBase, CloseClaw> {
+class CloseClaw : public frc2::CommandHelper<frc2::Command, CloseClaw> {
public:
explicit CloseClaw(Claw& claw);
void Initialize() override;
diff --git a/wpilibcExamples/src/main/cpp/examples/GearsBot/include/commands/SetElevatorSetpoint.h b/wpilibcExamples/src/main/cpp/examples/GearsBot/include/commands/SetElevatorSetpoint.h
index a106d62..3e8c18c 100644
--- a/wpilibcExamples/src/main/cpp/examples/GearsBot/include/commands/SetElevatorSetpoint.h
+++ b/wpilibcExamples/src/main/cpp/examples/GearsBot/include/commands/SetElevatorSetpoint.h
@@ -4,7 +4,7 @@
#pragma once
-#include <frc2/command/CommandBase.h>
+#include <frc2/command/Command.h>
#include <frc2/command/CommandHelper.h>
#include "subsystems/Elevator.h"
@@ -17,7 +17,7 @@
* commands using the elevator should make sure they disable PID!
*/
class SetElevatorSetpoint
- : public frc2::CommandHelper<frc2::CommandBase, SetElevatorSetpoint> {
+ : public frc2::CommandHelper<frc2::Command, SetElevatorSetpoint> {
public:
explicit SetElevatorSetpoint(double setpoint, Elevator& elevator);
void Initialize() override;
diff --git a/wpilibcExamples/src/main/cpp/examples/GearsBot/include/commands/SetWristSetpoint.h b/wpilibcExamples/src/main/cpp/examples/GearsBot/include/commands/SetWristSetpoint.h
index 2f6ca21..1494ad6 100644
--- a/wpilibcExamples/src/main/cpp/examples/GearsBot/include/commands/SetWristSetpoint.h
+++ b/wpilibcExamples/src/main/cpp/examples/GearsBot/include/commands/SetWristSetpoint.h
@@ -4,7 +4,7 @@
#pragma once
-#include <frc2/command/CommandBase.h>
+#include <frc2/command/Command.h>
#include <frc2/command/CommandHelper.h>
#include "subsystems/Wrist.h"
@@ -15,7 +15,7 @@
* Other commands using the wrist should make sure they disable PID!
*/
class SetWristSetpoint
- : public frc2::CommandHelper<frc2::CommandBase, SetWristSetpoint> {
+ : public frc2::CommandHelper<frc2::Command, SetWristSetpoint> {
public:
explicit SetWristSetpoint(double setpoint, Wrist& wrist);
void Initialize() override;
diff --git a/wpilibcExamples/src/main/cpp/examples/GearsBot/include/commands/TankDrive.h b/wpilibcExamples/src/main/cpp/examples/GearsBot/include/commands/TankDrive.h
index 5a81c11..932c427 100644
--- a/wpilibcExamples/src/main/cpp/examples/GearsBot/include/commands/TankDrive.h
+++ b/wpilibcExamples/src/main/cpp/examples/GearsBot/include/commands/TankDrive.h
@@ -4,7 +4,9 @@
#pragma once
-#include <frc2/command/CommandBase.h>
+#include <functional>
+
+#include <frc2/command/Command.h>
#include <frc2/command/CommandHelper.h>
#include "subsystems/Drivetrain.h"
@@ -12,7 +14,7 @@
/**
* Have the robot drive tank style using the PS3 Joystick until interrupted.
*/
-class TankDrive : public frc2::CommandHelper<frc2::CommandBase, TankDrive> {
+class TankDrive : public frc2::CommandHelper<frc2::Command, TankDrive> {
public:
TankDrive(std::function<double()> left, std::function<double()> right,
Drivetrain& drivetrain);
diff --git a/wpilibcExamples/src/main/cpp/examples/GettingStarted/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/GettingStarted/cpp/Robot.cpp
index a49d4f6..01b7210 100644
--- a/wpilibcExamples/src/main/cpp/examples/GettingStarted/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/GettingStarted/cpp/Robot.cpp
@@ -19,10 +19,7 @@
m_timer.Start();
}
- void AutonomousInit() override {
- m_timer.Reset();
- m_timer.Start();
- }
+ void AutonomousInit() override { m_timer.Restart(); }
void AutonomousPeriodic() override {
// Drive for 2 seconds
diff --git a/wpilibcExamples/src/main/cpp/examples/GyroDriveCommands/cpp/RobotContainer.cpp b/wpilibcExamples/src/main/cpp/examples/GyroDriveCommands/cpp/RobotContainer.cpp
index 3404b77..50b9900 100644
--- a/wpilibcExamples/src/main/cpp/examples/GyroDriveCommands/cpp/RobotContainer.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/GyroDriveCommands/cpp/RobotContainer.cpp
@@ -35,8 +35,8 @@
frc2::JoystickButton(&m_driverController, frc::PS4Controller::Button::kL1)
.WhileTrue(
frc2::PIDCommand(
- frc2::PIDController{dc::kStabilizationP, dc::kStabilizationI,
- dc::kStabilizationD},
+ frc::PIDController{dc::kStabilizationP, dc::kStabilizationI,
+ dc::kStabilizationD},
// Close the loop on the turn rate
[this] { return m_drive.GetTurnRate(); },
// Setpoint is 0
diff --git a/wpilibcExamples/src/main/cpp/examples/GyroDriveCommands/cpp/commands/TurnToAngle.cpp b/wpilibcExamples/src/main/cpp/examples/GyroDriveCommands/cpp/commands/TurnToAngle.cpp
index 3038f79..6d1272d 100644
--- a/wpilibcExamples/src/main/cpp/examples/GyroDriveCommands/cpp/commands/TurnToAngle.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/GyroDriveCommands/cpp/commands/TurnToAngle.cpp
@@ -9,7 +9,7 @@
using namespace DriveConstants;
TurnToAngle::TurnToAngle(units::degree_t target, DriveSubsystem* drive)
- : CommandHelper{frc2::PIDController{kTurnP, kTurnI, kTurnD},
+ : CommandHelper{frc::PIDController{kTurnP, kTurnI, kTurnD},
// Close loop on heading
[drive] { return drive->GetHeading().value(); },
// Set reference to target
@@ -25,7 +25,7 @@
// reference
m_controller.SetTolerance(kTurnTolerance.value(), kTurnRateTolerance.value());
- AddRequirements({drive});
+ AddRequirements(drive);
}
bool TurnToAngle::IsFinished() {
diff --git a/wpilibcExamples/src/main/cpp/examples/GyroDriveCommands/cpp/commands/TurnToAngleProfiled.cpp b/wpilibcExamples/src/main/cpp/examples/GyroDriveCommands/cpp/commands/TurnToAngleProfiled.cpp
index df4e355..464e0cf 100644
--- a/wpilibcExamples/src/main/cpp/examples/GyroDriveCommands/cpp/commands/TurnToAngleProfiled.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/GyroDriveCommands/cpp/commands/TurnToAngleProfiled.cpp
@@ -30,7 +30,7 @@
// reference
GetController().SetTolerance(kTurnTolerance, kTurnRateTolerance);
- AddRequirements({drive});
+ AddRequirements(drive);
}
bool TurnToAngleProfiled::IsFinished() {
diff --git a/wpilibcExamples/src/main/cpp/examples/HAL/c/Robot.c b/wpilibcExamples/src/main/cpp/examples/HAL/c/Robot.c
index b0905f9..a273e33 100644
--- a/wpilibcExamples/src/main/cpp/examples/HAL/c/Robot.c
+++ b/wpilibcExamples/src/main/cpp/examples/HAL/c/Robot.c
@@ -72,7 +72,7 @@
}
// Set PWM config to standard servo speeds
- HAL_SetPWMConfig(pwmPort, 2.0, 1.501, 1.5, 1.499, 1.0, &status);
+ HAL_SetPWMConfigMicroseconds(pwmPort, 2000, 1501, 1500, 1499, 1000, &status);
// Create an Input
status = 0;
@@ -87,7 +87,7 @@
return 1;
}
- WPI_EventHandle eventHandle = WPI_CreateEvent(1, 0);
+ WPI_EventHandle eventHandle = WPI_CreateEvent(0, 0);
HAL_ProvideNewDataEventHandle(eventHandle);
while (1) {
@@ -99,6 +99,8 @@
continue;
}
+ HAL_RefreshDSData();
+
enum DriverStationMode dsMode = getDSMode();
switch (dsMode) {
case DisabledMode:
diff --git a/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/cpp/Robot.cpp
index c7eab48..72efd40 100644
--- a/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/cpp/Robot.cpp
@@ -4,10 +4,19 @@
#include "Robot.h"
+#include <frc/DataLogManager.h>
+#include <frc/DriverStation.h>
#include <frc/smartdashboard/SmartDashboard.h>
#include <frc2/command/CommandScheduler.h>
-void Robot::RobotInit() {}
+void Robot::RobotInit() {
+ // Start recording to data log
+ frc::DataLogManager::Start();
+
+ // Record DS control and joystick data.
+ // Change to `false` to not record joystick data.
+ frc::DriverStation::StartDataLog(frc::DataLogManager::GetLog(), true);
+}
/**
* This function is called every 20 ms, no matter the mode. Use
diff --git a/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/cpp/RobotContainer.cpp b/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/cpp/RobotContainer.cpp
index 5a0cdad..76714d8 100644
--- a/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/cpp/RobotContainer.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/cpp/RobotContainer.cpp
@@ -16,6 +16,35 @@
// Put the chooser on the dashboard
frc::Shuffleboard::GetTab("Autonomous").Add(m_chooser);
+ // Put subsystems to dashboard.
+ frc::Shuffleboard::GetTab("Drivetrain").Add(m_drive);
+ frc::Shuffleboard::GetTab("HatchSubsystem").Add(m_hatch);
+
+ // Log Shuffleboard events for command initialize, execute, finish, interrupt
+ frc2::CommandScheduler::GetInstance().OnCommandInitialize(
+ [](const frc2::Command& command) {
+ frc::Shuffleboard::AddEventMarker(
+ "Command initialized", command.GetName(),
+ frc::ShuffleboardEventImportance::kNormal);
+ });
+ frc2::CommandScheduler::GetInstance().OnCommandExecute(
+ [](const frc2::Command& command) {
+ frc::Shuffleboard::AddEventMarker(
+ "Command executed", command.GetName(),
+ frc::ShuffleboardEventImportance::kNormal);
+ });
+ frc2::CommandScheduler::GetInstance().OnCommandFinish(
+ [](const frc2::Command& command) {
+ frc::Shuffleboard::AddEventMarker(
+ "Command finished", command.GetName(),
+ frc::ShuffleboardEventImportance::kNormal);
+ });
+ frc2::CommandScheduler::GetInstance().OnCommandInterrupt(
+ [](const frc2::Command& command) {
+ frc::Shuffleboard::AddEventMarker(
+ "Command interrupted", command.GetName(),
+ frc::ShuffleboardEventImportance::kNormal);
+ });
// Configure the button bindings
ConfigureButtonBindings();
diff --git a/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/cpp/subsystems/DriveSubsystem.cpp b/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/cpp/subsystems/DriveSubsystem.cpp
index bd94b68..3372a4d 100644
--- a/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/cpp/subsystems/DriveSubsystem.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/cpp/subsystems/DriveSubsystem.cpp
@@ -4,6 +4,8 @@
#include "subsystems/DriveSubsystem.h"
+#include <wpi/sendable/SendableBuilder.h>
+
using namespace DriveConstants;
DriveSubsystem::DriveSubsystem()
@@ -40,14 +42,17 @@
return (m_leftEncoder.GetDistance() + m_rightEncoder.GetDistance()) / 2.0;
}
-frc::Encoder& DriveSubsystem::GetLeftEncoder() {
- return m_leftEncoder;
-}
-
-frc::Encoder& DriveSubsystem::GetRightEncoder() {
- return m_rightEncoder;
-}
-
void DriveSubsystem::SetMaxOutput(double maxOutput) {
m_drive.SetMaxOutput(maxOutput);
}
+
+void DriveSubsystem::InitSendable(wpi::SendableBuilder& builder) {
+ SubsystemBase::InitSendable(builder);
+
+ // Publish encoder distances to telemetry.
+ builder.AddDoubleProperty(
+ "leftDistance", [this] { return m_leftEncoder.GetDistance(); }, nullptr);
+ builder.AddDoubleProperty(
+ "rightDistance", [this] { return m_rightEncoder.GetDistance(); },
+ nullptr);
+}
diff --git a/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/cpp/subsystems/HatchSubsystem.cpp b/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/cpp/subsystems/HatchSubsystem.cpp
index e766d43..449465b 100644
--- a/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/cpp/subsystems/HatchSubsystem.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/cpp/subsystems/HatchSubsystem.cpp
@@ -4,6 +4,8 @@
#include "subsystems/HatchSubsystem.h"
+#include <wpi/sendable/SendableBuilder.h>
+
using namespace HatchConstants;
HatchSubsystem::HatchSubsystem()
@@ -21,3 +23,13 @@
return this->RunOnce(
[this] { m_hatchSolenoid.Set(frc::DoubleSolenoid::kReverse); });
}
+
+void HatchSubsystem::InitSendable(wpi::SendableBuilder& builder) {
+ SubsystemBase::InitSendable(builder);
+
+ // Publish the solenoid state to telemetry.
+ builder.AddBooleanProperty(
+ "extended",
+ [this] { return m_hatchSolenoid.Get() == frc::DoubleSolenoid::kForward; },
+ nullptr);
+}
diff --git a/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/include/subsystems/DriveSubsystem.h b/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/include/subsystems/DriveSubsystem.h
index 47bf28e..5984a1a 100644
--- a/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/include/subsystems/DriveSubsystem.h
+++ b/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/include/subsystems/DriveSubsystem.h
@@ -44,20 +44,6 @@
double GetAverageEncoderDistance();
/**
- * Gets the left drive encoder.
- *
- * @return the left drive encoder
- */
- frc::Encoder& GetLeftEncoder();
-
- /**
- * Gets the right drive encoder.
- *
- * @return the right drive encoder
- */
- frc::Encoder& GetRightEncoder();
-
- /**
* Sets the max output of the drive. Useful for scaling the drive to drive
* more slowly.
*
@@ -65,6 +51,8 @@
*/
void SetMaxOutput(double maxOutput);
+ void InitSendable(wpi::SendableBuilder& builder) override;
+
private:
// Components (e.g. motor controllers and sensors) should generally be
// declared private and exposed only through public methods.
diff --git a/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/include/subsystems/HatchSubsystem.h b/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/include/subsystems/HatchSubsystem.h
index b21bb56..e81f3b2 100644
--- a/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/include/subsystems/HatchSubsystem.h
+++ b/wpilibcExamples/src/main/cpp/examples/HatchbotInlined/include/subsystems/HatchSubsystem.h
@@ -27,6 +27,8 @@
*/
frc2::CommandPtr ReleaseHatchCommand();
+ void InitSendable(wpi::SendableBuilder& builder) override;
+
private:
// Components (e.g. motor controllers and sensors) should generally be
// declared private and exposed only through public methods.
diff --git a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/Robot.cpp
index c7eab48..72efd40 100644
--- a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/Robot.cpp
@@ -4,10 +4,19 @@
#include "Robot.h"
+#include <frc/DataLogManager.h>
+#include <frc/DriverStation.h>
#include <frc/smartdashboard/SmartDashboard.h>
#include <frc2/command/CommandScheduler.h>
-void Robot::RobotInit() {}
+void Robot::RobotInit() {
+ // Start recording to data log
+ frc::DataLogManager::Start();
+
+ // Record DS control and joystick data.
+ // Change to `false` to not record joystick data.
+ frc::DriverStation::StartDataLog(frc::DataLogManager::GetLog(), true);
+}
/**
* This function is called every 20 ms, no matter the mode. Use
diff --git a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/RobotContainer.cpp b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/RobotContainer.cpp
index 876a984..faf9d1f 100644
--- a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/RobotContainer.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/RobotContainer.cpp
@@ -21,6 +21,35 @@
// Put the chooser on the dashboard
frc::Shuffleboard::GetTab("Autonomous").Add(m_chooser);
+ // Put subsystems to dashboard.
+ frc::Shuffleboard::GetTab("Drivetrain").Add(m_drive);
+ frc::Shuffleboard::GetTab("HatchSubsystem").Add(m_hatch);
+
+ // Log Shuffleboard events for command initialize, execute, finish, interrupt
+ frc2::CommandScheduler::GetInstance().OnCommandInitialize(
+ [](const frc2::Command& command) {
+ frc::Shuffleboard::AddEventMarker(
+ "Command initialized", command.GetName(),
+ frc::ShuffleboardEventImportance::kNormal);
+ });
+ frc2::CommandScheduler::GetInstance().OnCommandExecute(
+ [](const frc2::Command& command) {
+ frc::Shuffleboard::AddEventMarker(
+ "Command executed", command.GetName(),
+ frc::ShuffleboardEventImportance::kNormal);
+ });
+ frc2::CommandScheduler::GetInstance().OnCommandFinish(
+ [](const frc2::Command& command) {
+ frc::Shuffleboard::AddEventMarker(
+ "Command finished", command.GetName(),
+ frc::ShuffleboardEventImportance::kNormal);
+ });
+ frc2::CommandScheduler::GetInstance().OnCommandInterrupt(
+ [](const frc2::Command& command) {
+ frc::Shuffleboard::AddEventMarker(
+ "Command interrupted", command.GetName(),
+ frc::ShuffleboardEventImportance::kNormal);
+ });
// Configure the button bindings
ConfigureButtonBindings();
diff --git a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/commands/DefaultDrive.cpp b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/commands/DefaultDrive.cpp
index 7ef404e..4047596 100644
--- a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/commands/DefaultDrive.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/commands/DefaultDrive.cpp
@@ -12,7 +12,7 @@
: m_drive{subsystem},
m_forward{std::move(forward)},
m_rotation{std::move(rotation)} {
- AddRequirements({subsystem});
+ AddRequirements(subsystem);
}
void DefaultDrive::Execute() {
diff --git a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/commands/DriveDistance.cpp b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/commands/DriveDistance.cpp
index 7ee1b2c..9d9704d 100644
--- a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/commands/DriveDistance.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/commands/DriveDistance.cpp
@@ -9,7 +9,7 @@
DriveDistance::DriveDistance(double inches, double speed,
DriveSubsystem* subsystem)
: m_drive(subsystem), m_distance(inches), m_speed(speed) {
- AddRequirements({subsystem});
+ AddRequirements(subsystem);
}
void DriveDistance::Initialize() {
diff --git a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/commands/ReleaseHatch.cpp b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/commands/ReleaseHatch.cpp
index 7e6c9e8..12f36da 100644
--- a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/commands/ReleaseHatch.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/commands/ReleaseHatch.cpp
@@ -5,7 +5,7 @@
#include "commands/ReleaseHatch.h"
ReleaseHatch::ReleaseHatch(HatchSubsystem* subsystem) : m_hatch(subsystem) {
- AddRequirements({subsystem});
+ AddRequirements(subsystem);
}
void ReleaseHatch::Initialize() {
diff --git a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/subsystems/DriveSubsystem.cpp b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/subsystems/DriveSubsystem.cpp
index bd94b68..3372a4d 100644
--- a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/subsystems/DriveSubsystem.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/subsystems/DriveSubsystem.cpp
@@ -4,6 +4,8 @@
#include "subsystems/DriveSubsystem.h"
+#include <wpi/sendable/SendableBuilder.h>
+
using namespace DriveConstants;
DriveSubsystem::DriveSubsystem()
@@ -40,14 +42,17 @@
return (m_leftEncoder.GetDistance() + m_rightEncoder.GetDistance()) / 2.0;
}
-frc::Encoder& DriveSubsystem::GetLeftEncoder() {
- return m_leftEncoder;
-}
-
-frc::Encoder& DriveSubsystem::GetRightEncoder() {
- return m_rightEncoder;
-}
-
void DriveSubsystem::SetMaxOutput(double maxOutput) {
m_drive.SetMaxOutput(maxOutput);
}
+
+void DriveSubsystem::InitSendable(wpi::SendableBuilder& builder) {
+ SubsystemBase::InitSendable(builder);
+
+ // Publish encoder distances to telemetry.
+ builder.AddDoubleProperty(
+ "leftDistance", [this] { return m_leftEncoder.GetDistance(); }, nullptr);
+ builder.AddDoubleProperty(
+ "rightDistance", [this] { return m_rightEncoder.GetDistance(); },
+ nullptr);
+}
diff --git a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/subsystems/HatchSubsystem.cpp b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/subsystems/HatchSubsystem.cpp
index ba1c0dd..975141f 100644
--- a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/subsystems/HatchSubsystem.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/cpp/subsystems/HatchSubsystem.cpp
@@ -4,6 +4,8 @@
#include "subsystems/HatchSubsystem.h"
+#include <wpi/sendable/SendableBuilder.h>
+
using namespace HatchConstants;
HatchSubsystem::HatchSubsystem()
@@ -17,3 +19,13 @@
void HatchSubsystem::ReleaseHatch() {
m_hatchSolenoid.Set(frc::DoubleSolenoid::kReverse);
}
+
+void HatchSubsystem::InitSendable(wpi::SendableBuilder& builder) {
+ SubsystemBase::InitSendable(builder);
+
+ // Publish the solenoid state to telemetry.
+ builder.AddBooleanProperty(
+ "extended",
+ [this] { return m_hatchSolenoid.Get() == frc::DoubleSolenoid::kForward; },
+ nullptr);
+}
diff --git a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/commands/DefaultDrive.h b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/commands/DefaultDrive.h
index 2e7cac8..7d58f9e 100644
--- a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/commands/DefaultDrive.h
+++ b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/commands/DefaultDrive.h
@@ -4,7 +4,9 @@
#pragma once
-#include <frc2/command/CommandBase.h>
+#include <functional>
+
+#include <frc2/command/Command.h>
#include <frc2/command/CommandHelper.h>
#include "subsystems/DriveSubsystem.h"
@@ -16,8 +18,7 @@
*
* @see RunCommand
*/
-class DefaultDrive
- : public frc2::CommandHelper<frc2::CommandBase, DefaultDrive> {
+class DefaultDrive : public frc2::CommandHelper<frc2::Command, DefaultDrive> {
public:
/**
* Creates a new DefaultDrive.
diff --git a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/commands/DriveDistance.h b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/commands/DriveDistance.h
index 34d2577..5a0fad8 100644
--- a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/commands/DriveDistance.h
+++ b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/commands/DriveDistance.h
@@ -4,13 +4,12 @@
#pragma once
-#include <frc2/command/CommandBase.h>
+#include <frc2/command/Command.h>
#include <frc2/command/CommandHelper.h>
#include "subsystems/DriveSubsystem.h"
-class DriveDistance
- : public frc2::CommandHelper<frc2::CommandBase, DriveDistance> {
+class DriveDistance : public frc2::CommandHelper<frc2::Command, DriveDistance> {
public:
/**
* Creates a new DriveDistance.
diff --git a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/commands/GrabHatch.h b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/commands/GrabHatch.h
index 0cf5c5a..c8a36a4 100644
--- a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/commands/GrabHatch.h
+++ b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/commands/GrabHatch.h
@@ -4,7 +4,7 @@
#pragma once
-#include <frc2/command/CommandBase.h>
+#include <frc2/command/Command.h>
#include <frc2/command/CommandHelper.h>
#include "subsystems/HatchSubsystem.h"
@@ -16,7 +16,7 @@
*
* @see InstantCommand
*/
-class GrabHatch : public frc2::CommandHelper<frc2::CommandBase, GrabHatch> {
+class GrabHatch : public frc2::CommandHelper<frc2::Command, GrabHatch> {
public:
explicit GrabHatch(HatchSubsystem* subsystem);
diff --git a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/commands/HalveDriveSpeed.h b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/commands/HalveDriveSpeed.h
index efc572d..52d8281 100644
--- a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/commands/HalveDriveSpeed.h
+++ b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/commands/HalveDriveSpeed.h
@@ -4,13 +4,13 @@
#pragma once
-#include <frc2/command/CommandBase.h>
+#include <frc2/command/Command.h>
#include <frc2/command/CommandHelper.h>
#include "subsystems/DriveSubsystem.h"
class HalveDriveSpeed
- : public frc2::CommandHelper<frc2::CommandBase, HalveDriveSpeed> {
+ : public frc2::CommandHelper<frc2::Command, HalveDriveSpeed> {
public:
explicit HalveDriveSpeed(DriveSubsystem* subsystem);
diff --git a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/commands/ReleaseHatch.h b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/commands/ReleaseHatch.h
index e3628cf..0b4b953 100644
--- a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/commands/ReleaseHatch.h
+++ b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/commands/ReleaseHatch.h
@@ -4,7 +4,7 @@
#pragma once
-#include <frc2/command/CommandBase.h>
+#include <frc2/command/Command.h>
#include <frc2/command/CommandHelper.h>
#include "subsystems/HatchSubsystem.h"
@@ -16,8 +16,7 @@
*
* @see InstantCommand
*/
-class ReleaseHatch
- : public frc2::CommandHelper<frc2::CommandBase, ReleaseHatch> {
+class ReleaseHatch : public frc2::CommandHelper<frc2::Command, ReleaseHatch> {
public:
explicit ReleaseHatch(HatchSubsystem* subsystem);
diff --git a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/subsystems/DriveSubsystem.h b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/subsystems/DriveSubsystem.h
index 47bf28e..5984a1a 100644
--- a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/subsystems/DriveSubsystem.h
+++ b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/subsystems/DriveSubsystem.h
@@ -44,20 +44,6 @@
double GetAverageEncoderDistance();
/**
- * Gets the left drive encoder.
- *
- * @return the left drive encoder
- */
- frc::Encoder& GetLeftEncoder();
-
- /**
- * Gets the right drive encoder.
- *
- * @return the right drive encoder
- */
- frc::Encoder& GetRightEncoder();
-
- /**
* Sets the max output of the drive. Useful for scaling the drive to drive
* more slowly.
*
@@ -65,6 +51,8 @@
*/
void SetMaxOutput(double maxOutput);
+ void InitSendable(wpi::SendableBuilder& builder) override;
+
private:
// Components (e.g. motor controllers and sensors) should generally be
// declared private and exposed only through public methods.
diff --git a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/subsystems/HatchSubsystem.h b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/subsystems/HatchSubsystem.h
index bb06100..392e9b2 100644
--- a/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/subsystems/HatchSubsystem.h
+++ b/wpilibcExamples/src/main/cpp/examples/HatchbotTraditional/include/subsystems/HatchSubsystem.h
@@ -26,6 +26,8 @@
*/
void ReleaseHatch();
+ void InitSendable(wpi::SendableBuilder& builder) override;
+
private:
// Components (e.g. motor controllers and sensors) should generally be
// declared private and exposed only through public methods.
diff --git a/wpilibcExamples/src/main/cpp/examples/I2CCommunication/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/I2CCommunication/cpp/Robot.cpp
index fad7581..ecfb480 100644
--- a/wpilibcExamples/src/main/cpp/examples/I2CCommunication/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/I2CCommunication/cpp/Robot.cpp
@@ -2,45 +2,37 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
-#include <fmt/format.h>
+#include "Robot.h"
+#include <fmt/format.h>
#include <frc/DriverStation.h>
-#include <frc/I2C.h>
-#include <frc/TimedRobot.h>
#include <frc/Timer.h>
-/**
- * This is a sample program demonstrating how to communicate to a light
- * controller from the robot code using the roboRIO's I2C port.
- */
-class Robot : public frc::TimedRobot {
- public:
- void RobotPeriodic() override {
- // Creates a string to hold current robot state information, including
- // alliance, enabled state, operation mode, and match time. The message
- // is sent in format "AEM###" where A is the alliance color, (R)ed or
- // (B)lue, E is the enabled state, (E)nabled or (D)isabled, M is the
- // operation mode, (A)utonomous or (T)eleop, and ### is the zero-padded
- // time remaining in the match.
- //
- // For example, "RET043" would indicate that the robot is on the red
- // alliance, enabled in teleop mode, with 43 seconds left in the match.
- auto string = fmt::format(
- "{}{}{}{:03}",
- frc::DriverStation::GetAlliance() == frc::DriverStation::Alliance::kRed
- ? "R"
- : "B",
- frc::DriverStation::IsEnabled() ? "E" : "D",
- frc::DriverStation::IsAutonomous() ? "A" : "T",
- static_cast<int>(frc::Timer::GetMatchTime().value()));
+void Robot::RobotPeriodic() {
+ // Creates a string to hold current robot state information, including
+ // alliance, enabled state, operation mode, and match time. The message
+ // is sent in format "AEM###" where A is the alliance color, (R)ed or
+ // (B)lue, E is the enabled state, (E)nabled or (D)isabled, M is the
+ // operation mode, (A)utonomous or (T)eleop, and ### is the zero-padded
+ // time remaining in the match.
+ //
+ // For example, "RET043" would indicate that the robot is on the red
+ // alliance, enabled in teleop mode, with 43 seconds left in the match.
- arduino.WriteBulk(reinterpret_cast<uint8_t*>(string.data()), string.size());
+ std::string allianceString = "U";
+ auto alliance = frc::DriverStation::GetAlliance();
+ if (alliance.has_value()) {
+ allianceString = alliance == frc::DriverStation::Alliance::kRed ? "R" : "B";
}
- private:
- static constexpr int deviceAddress = 4;
- frc::I2C arduino{frc::I2C::Port::kOnboard, deviceAddress};
-};
+ auto string =
+ fmt::format("{}{}{}{:03}", allianceString,
+ frc::DriverStation::IsEnabled() ? "E" : "D",
+ frc::DriverStation::IsAutonomous() ? "A" : "T",
+ static_cast<int>(frc::Timer::GetMatchTime().value()));
+
+ arduino.WriteBulk(reinterpret_cast<uint8_t*>(string.data()), string.size());
+}
#ifndef RUNNING_FRC_TESTS
int main() {
diff --git a/wpilibcExamples/src/main/cpp/examples/I2CCommunication/include/Robot.h b/wpilibcExamples/src/main/cpp/examples/I2CCommunication/include/Robot.h
new file mode 100644
index 0000000..ede2624
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/I2CCommunication/include/Robot.h
@@ -0,0 +1,25 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <array>
+
+#include <frc/I2C.h>
+#include <frc/TimedRobot.h>
+
+/**
+ * This is a sample program demonstrating how to communicate to a light
+ * controller from the robot code using the roboRIO's I2C port.
+ */
+class Robot : public frc::TimedRobot {
+ public:
+ void RobotPeriodic() override;
+
+ static constexpr frc::I2C::Port kPort = frc::I2C::Port::kOnboard;
+
+ private:
+ static constexpr int deviceAddress = 4;
+ frc::I2C arduino{kPort, deviceAddress};
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/MecanumBot/cpp/Drivetrain.cpp b/wpilibcExamples/src/main/cpp/examples/MecanumBot/cpp/Drivetrain.cpp
index a59b758..94b5feb 100644
--- a/wpilibcExamples/src/main/cpp/examples/MecanumBot/cpp/Drivetrain.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/MecanumBot/cpp/Drivetrain.cpp
@@ -49,11 +49,13 @@
void Drivetrain::Drive(units::meters_per_second_t xSpeed,
units::meters_per_second_t ySpeed,
- units::radians_per_second_t rot, bool fieldRelative) {
- auto wheelSpeeds = m_kinematics.ToWheelSpeeds(
+ units::radians_per_second_t rot, bool fieldRelative,
+ units::second_t period) {
+ auto wheelSpeeds = m_kinematics.ToWheelSpeeds(frc::ChassisSpeeds::Discretize(
fieldRelative ? frc::ChassisSpeeds::FromFieldRelativeSpeeds(
xSpeed, ySpeed, rot, m_gyro.GetRotation2d())
- : frc::ChassisSpeeds{xSpeed, ySpeed, rot});
+ : frc::ChassisSpeeds{xSpeed, ySpeed, rot},
+ period));
wheelSpeeds.Desaturate(kMaxSpeed);
SetSpeeds(wheelSpeeds);
}
diff --git a/wpilibcExamples/src/main/cpp/examples/MecanumBot/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/MecanumBot/cpp/Robot.cpp
index 4943184..18955f2 100644
--- a/wpilibcExamples/src/main/cpp/examples/MecanumBot/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/MecanumBot/cpp/Robot.cpp
@@ -46,7 +46,7 @@
const auto rot = -m_rotLimiter.Calculate(m_controller.GetRightX()) *
Drivetrain::kMaxAngularSpeed;
- m_mecanum.Drive(xSpeed, ySpeed, rot, fieldRelative);
+ m_mecanum.Drive(xSpeed, ySpeed, rot, fieldRelative, GetPeriod());
}
};
diff --git a/wpilibcExamples/src/main/cpp/examples/MecanumBot/include/Drivetrain.h b/wpilibcExamples/src/main/cpp/examples/MecanumBot/include/Drivetrain.h
index fd4ae7a..971fe4c 100644
--- a/wpilibcExamples/src/main/cpp/examples/MecanumBot/include/Drivetrain.h
+++ b/wpilibcExamples/src/main/cpp/examples/MecanumBot/include/Drivetrain.h
@@ -35,7 +35,7 @@
void SetSpeeds(const frc::MecanumDriveWheelSpeeds& wheelSpeeds);
void Drive(units::meters_per_second_t xSpeed,
units::meters_per_second_t ySpeed, units::radians_per_second_t rot,
- bool fieldRelative);
+ bool fieldRelative, units::second_t period);
void UpdateOdometry();
static constexpr units::meters_per_second_t kMaxSpeed =
@@ -59,10 +59,10 @@
frc::Translation2d m_backLeftLocation{-0.381_m, 0.381_m};
frc::Translation2d m_backRightLocation{-0.381_m, -0.381_m};
- frc2::PIDController m_frontLeftPIDController{1.0, 0.0, 0.0};
- frc2::PIDController m_frontRightPIDController{1.0, 0.0, 0.0};
- frc2::PIDController m_backLeftPIDController{1.0, 0.0, 0.0};
- frc2::PIDController m_backRightPIDController{1.0, 0.0, 0.0};
+ frc::PIDController m_frontLeftPIDController{1.0, 0.0, 0.0};
+ frc::PIDController m_frontRightPIDController{1.0, 0.0, 0.0};
+ frc::PIDController m_backLeftPIDController{1.0, 0.0, 0.0};
+ frc::PIDController m_backRightPIDController{1.0, 0.0, 0.0};
frc::AnalogGyro m_gyro{0};
diff --git a/wpilibcExamples/src/main/cpp/examples/MecanumControllerCommand/cpp/RobotContainer.cpp b/wpilibcExamples/src/main/cpp/examples/MecanumControllerCommand/cpp/RobotContainer.cpp
index 1e9a9ae..0f691e0 100644
--- a/wpilibcExamples/src/main/cpp/examples/MecanumControllerCommand/cpp/RobotContainer.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/MecanumControllerCommand/cpp/RobotContainer.cpp
@@ -71,8 +71,8 @@
frc::SimpleMotorFeedforward<units::meters>(ks, kv, ka),
DriveConstants::kDriveKinematics,
- frc2::PIDController{AutoConstants::kPXController, 0, 0},
- frc2::PIDController{AutoConstants::kPYController, 0, 0},
+ frc::PIDController{AutoConstants::kPXController, 0, 0},
+ frc::PIDController{AutoConstants::kPYController, 0, 0},
frc::ProfiledPIDController<units::radians>(
AutoConstants::kPThetaController, 0, 0,
AutoConstants::kThetaControllerConstraints),
@@ -89,10 +89,10 @@
m_drive.GetRearRightEncoder().GetRate()}};
},
- frc2::PIDController{DriveConstants::kPFrontLeftVel, 0, 0},
- frc2::PIDController{DriveConstants::kPRearLeftVel, 0, 0},
- frc2::PIDController{DriveConstants::kPFrontRightVel, 0, 0},
- frc2::PIDController{DriveConstants::kPRearRightVel, 0, 0},
+ frc::PIDController{DriveConstants::kPFrontLeftVel, 0, 0},
+ frc::PIDController{DriveConstants::kPRearLeftVel, 0, 0},
+ frc::PIDController{DriveConstants::kPFrontRightVel, 0, 0},
+ frc::PIDController{DriveConstants::kPRearRightVel, 0, 0},
[this](units::volt_t frontLeft, units::volt_t rearLeft,
units::volt_t frontRight, units::volt_t rearRight) {
diff --git a/wpilibcExamples/src/main/cpp/examples/MecanumControllerCommand/cpp/subsystems/DriveSubsystem.cpp b/wpilibcExamples/src/main/cpp/examples/MecanumControllerCommand/cpp/subsystems/DriveSubsystem.cpp
index 9120fa6..292ad1f 100644
--- a/wpilibcExamples/src/main/cpp/examples/MecanumControllerCommand/cpp/subsystems/DriveSubsystem.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/MecanumControllerCommand/cpp/subsystems/DriveSubsystem.cpp
@@ -50,9 +50,9 @@
void DriveSubsystem::Drive(double xSpeed, double ySpeed, double rot,
bool fieldRelative) {
if (fieldRelative) {
- m_drive.DriveCartesian(ySpeed, xSpeed, rot, m_gyro.GetRotation2d());
+ m_drive.DriveCartesian(xSpeed, ySpeed, rot, m_gyro.GetRotation2d());
} else {
- m_drive.DriveCartesian(ySpeed, xSpeed, rot);
+ m_drive.DriveCartesian(xSpeed, ySpeed, rot);
}
}
diff --git a/wpilibcExamples/src/main/cpp/examples/MecanumDrive/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/MecanumDrive/cpp/Robot.cpp
index 2b57f3c..8d9d7ae 100644
--- a/wpilibcExamples/src/main/cpp/examples/MecanumDrive/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/MecanumDrive/cpp/Robot.cpp
@@ -21,7 +21,7 @@
}
void TeleopPeriodic() override {
- /* Use the joystick X axis for forward movement, Y axis for lateral
+ /* Use the joystick Y axis for forward movement, X axis for lateral
* movement, and Z axis for rotation.
*/
m_robotDrive.DriveCartesian(-m_stick.GetY(), -m_stick.GetX(),
diff --git a/wpilibcExamples/src/main/cpp/examples/MecanumDrivePoseEstimator/cpp/Drivetrain.cpp b/wpilibcExamples/src/main/cpp/examples/MecanumDrivePoseEstimator/cpp/Drivetrain.cpp
index c1046dd..9f1b12b 100644
--- a/wpilibcExamples/src/main/cpp/examples/MecanumDrivePoseEstimator/cpp/Drivetrain.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/MecanumDrivePoseEstimator/cpp/Drivetrain.cpp
@@ -24,7 +24,7 @@
void Drivetrain::SetSpeeds(const frc::MecanumDriveWheelSpeeds& wheelSpeeds) {
std::function<void(units::meters_per_second_t, const frc::Encoder&,
- frc2::PIDController&, frc::PWMSparkMax&)>
+ frc::PIDController&, frc::PWMSparkMax&)>
calcAndSetSpeeds = [&m_feedforward = m_feedforward](
units::meters_per_second_t speed,
const auto& encoder, auto& controller,
@@ -46,11 +46,13 @@
void Drivetrain::Drive(units::meters_per_second_t xSpeed,
units::meters_per_second_t ySpeed,
- units::radians_per_second_t rot, bool fieldRelative) {
- auto wheelSpeeds = m_kinematics.ToWheelSpeeds(
+ units::radians_per_second_t rot, bool fieldRelative,
+ units::second_t period) {
+ auto wheelSpeeds = m_kinematics.ToWheelSpeeds(frc::ChassisSpeeds::Discretize(
fieldRelative ? frc::ChassisSpeeds::FromFieldRelativeSpeeds(
xSpeed, ySpeed, rot, m_gyro.GetRotation2d())
- : frc::ChassisSpeeds{xSpeed, ySpeed, rot});
+ : frc::ChassisSpeeds{xSpeed, ySpeed, rot},
+ period));
wheelSpeeds.Desaturate(kMaxSpeed);
SetSpeeds(wheelSpeeds);
}
diff --git a/wpilibcExamples/src/main/cpp/examples/MecanumDrivePoseEstimator/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/MecanumDrivePoseEstimator/cpp/Robot.cpp
index 4943184..18955f2 100644
--- a/wpilibcExamples/src/main/cpp/examples/MecanumDrivePoseEstimator/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/MecanumDrivePoseEstimator/cpp/Robot.cpp
@@ -46,7 +46,7 @@
const auto rot = -m_rotLimiter.Calculate(m_controller.GetRightX()) *
Drivetrain::kMaxAngularSpeed;
- m_mecanum.Drive(xSpeed, ySpeed, rot, fieldRelative);
+ m_mecanum.Drive(xSpeed, ySpeed, rot, fieldRelative, GetPeriod());
}
};
diff --git a/wpilibcExamples/src/main/cpp/examples/MecanumDrivePoseEstimator/include/Drivetrain.h b/wpilibcExamples/src/main/cpp/examples/MecanumDrivePoseEstimator/include/Drivetrain.h
index eeaf7af..2dcc50c 100644
--- a/wpilibcExamples/src/main/cpp/examples/MecanumDrivePoseEstimator/include/Drivetrain.h
+++ b/wpilibcExamples/src/main/cpp/examples/MecanumDrivePoseEstimator/include/Drivetrain.h
@@ -36,7 +36,7 @@
void SetSpeeds(const frc::MecanumDriveWheelSpeeds& wheelSpeeds);
void Drive(units::meters_per_second_t xSpeed,
units::meters_per_second_t ySpeed, units::radians_per_second_t rot,
- bool fieldRelative);
+ bool fieldRelative, units::second_t period);
void UpdateOdometry();
static constexpr auto kMaxSpeed = 3.0_mps; // 3 meters per second
@@ -59,10 +59,10 @@
frc::Translation2d m_backLeftLocation{-0.381_m, 0.381_m};
frc::Translation2d m_backRightLocation{-0.381_m, -0.381_m};
- frc2::PIDController m_frontLeftPIDController{1.0, 0.0, 0.0};
- frc2::PIDController m_frontRightPIDController{1.0, 0.0, 0.0};
- frc2::PIDController m_backLeftPIDController{1.0, 0.0, 0.0};
- frc2::PIDController m_backRightPIDController{1.0, 0.0, 0.0};
+ frc::PIDController m_frontLeftPIDController{1.0, 0.0, 0.0};
+ frc::PIDController m_frontRightPIDController{1.0, 0.0, 0.0};
+ frc::PIDController m_backLeftPIDController{1.0, 0.0, 0.0};
+ frc::PIDController m_backRightPIDController{1.0, 0.0, 0.0};
frc::AnalogGyro m_gyro{0};
diff --git a/wpilibcExamples/src/main/cpp/examples/PotentiometerPID/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/PotentiometerPID/cpp/Robot.cpp
index 5b6b024..69cebaf 100644
--- a/wpilibcExamples/src/main/cpp/examples/PotentiometerPID/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/PotentiometerPID/cpp/Robot.cpp
@@ -2,72 +2,32 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
-#include <array>
+#include "Robot.h"
-#include <frc/AnalogInput.h>
-#include <frc/Joystick.h>
-#include <frc/TimedRobot.h>
-#include <frc/controller/PIDController.h>
-#include <frc/motorcontrol/PWMSparkMax.h>
+void Robot::TeleopInit() {
+ // Move to the bottom setpoint when teleop starts
+ m_index = 0;
+ m_pidController.SetSetpoint(kSetpoints[m_index].value());
+}
-/**
- * This is a sample program to demonstrate how to use a soft potentiometer and a
- * PID Controller to reach and maintain position setpoints on an elevator
- * mechanism.
- */
-class Robot : public frc::TimedRobot {
- public:
- void RobotInit() override {
- m_pidController.SetSetpoint(kSetPoints[m_index]);
+void Robot::TeleopPeriodic() {
+ // Read from the sensor
+ units::meter_t position = units::meter_t{m_potentiometer.Get()};
+
+ // Run the PID Controller
+ double pidOut = m_pidController.Calculate(position.value());
+
+ // Apply PID output
+ m_elevatorMotor.Set(pidOut);
+
+ // when the button is pressed once, the selected elevator setpoint is
+ // incremented
+ if (m_joystick.GetTriggerPressed()) {
+ // index of the elevator setpoint wraps around.
+ m_index = (m_index + 1) % kSetpoints.size();
+ m_pidController.SetSetpoint(kSetpoints[m_index].value());
}
-
- void TeleopPeriodic() override {
- // When the button is pressed once, the selected elevator setpoint is
- // incremented.
- bool currentButtonValue = m_joystick.GetTrigger();
- if (currentButtonValue && !m_previousButtonValue) {
- // Index of the elevator setpoint wraps around
- m_index = (m_index + 1) % (sizeof(kSetPoints) / 8);
- m_pidController.SetSetpoint(kSetPoints[m_index]);
- }
- m_previousButtonValue = currentButtonValue;
-
- double output =
- m_pidController.Calculate(m_potentiometer.GetAverageVoltage());
- m_elevatorMotor.Set(output);
- }
-
- private:
- static constexpr int kPotChannel = 1;
- static constexpr int kMotorChannel = 7;
- static constexpr int kJoystickChannel = 0;
-
- // Bottom, middle, and top elevator setpoints
- static constexpr std::array<double, 3> kSetPoints = {{1.0, 2.6, 4.3}};
-
- /* Proportional, integral, and derivative speed constants; motor inverted.
- *
- * DANGER: When tuning PID constants, high/inappropriate values for pGain,
- * iGain, and dGain may cause dangerous, uncontrollable, or undesired
- * behavior!
- *
- * These may need to be positive for a non-inverted motor.
- */
- static constexpr double kP = -5.0;
- static constexpr double kI = -0.02;
- static constexpr double kD = -2.0;
-
- int m_index = 0;
- bool m_previousButtonValue = false;
-
- frc::AnalogInput m_potentiometer{kPotChannel};
- frc::Joystick m_joystick{kJoystickChannel};
- frc::PWMSparkMax m_elevatorMotor{kMotorChannel};
-
- frc2::PIDController m_pidController{kP, kI, kD};
-};
-
-constexpr std::array<double, 3> Robot::kSetPoints;
+}
#ifndef RUNNING_FRC_TESTS
int main() {
diff --git a/wpilibcExamples/src/main/cpp/examples/PotentiometerPID/include/Robot.h b/wpilibcExamples/src/main/cpp/examples/PotentiometerPID/include/Robot.h
new file mode 100644
index 0000000..ab843a1
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/PotentiometerPID/include/Robot.h
@@ -0,0 +1,55 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <array>
+
+#include <frc/AnalogPotentiometer.h>
+#include <frc/Joystick.h>
+#include <frc/TimedRobot.h>
+#include <frc/controller/PIDController.h>
+#include <frc/motorcontrol/PWMSparkMax.h>
+#include <units/length.h>
+
+/**
+ * This is a sample program to demonstrate how to use a soft potentiometer and a
+ * PID controller to reach and maintain position setpoints on an elevator
+ * mechanism.
+ */
+class Robot : public frc::TimedRobot {
+ public:
+ void TeleopInit() override;
+ void TeleopPeriodic() override;
+
+ static constexpr int kPotChannel = 1;
+ static constexpr int kMotorChannel = 7;
+ static constexpr int kJoystickChannel = 3;
+
+ // The elevator can move 1.5 meters from top to bottom
+ static constexpr units::meter_t kFullHeight = 1.5_m;
+
+ // Bottom, middle, and top elevator setpoints
+ static constexpr std::array<units::meter_t, 3> kSetpoints = {
+ {0.2_m, 0.8_m, 1.4_m}};
+
+ private:
+ // proportional speed constant
+ // negative because applying positive voltage will bring us closer to the
+ // target
+ static constexpr double kP = 0.7;
+ // integral speed constant
+ static constexpr double kI = 0.35;
+ // derivative speed constant
+ static constexpr double kD = 0.25;
+
+ // Scaling is handled internally
+ frc::AnalogPotentiometer m_potentiometer{kPotChannel, kFullHeight.value()};
+
+ frc::PWMSparkMax m_elevatorMotor{kMotorChannel};
+ frc::PIDController m_pidController{kP, kI, kD};
+ frc::Joystick m_joystick{kJoystickChannel};
+
+ size_t m_index;
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/RamseteCommand/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/RamseteCommand/cpp/Robot.cpp
index c7eab48..c4c1661 100644
--- a/wpilibcExamples/src/main/cpp/examples/RamseteCommand/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/RamseteCommand/cpp/Robot.cpp
@@ -37,7 +37,7 @@
void Robot::AutonomousInit() {
m_autonomousCommand = m_container.GetAutonomousCommand();
- if (m_autonomousCommand != nullptr) {
+ if (m_autonomousCommand) {
m_autonomousCommand->Schedule();
}
}
@@ -49,9 +49,9 @@
// teleop starts running. If you want the autonomous to
// continue until interrupted by another command, remove
// this line or comment it out.
- if (m_autonomousCommand != nullptr) {
+ if (m_autonomousCommand) {
m_autonomousCommand->Cancel();
- m_autonomousCommand = nullptr;
+ m_autonomousCommand.reset();
}
}
diff --git a/wpilibcExamples/src/main/cpp/examples/RamseteCommand/cpp/RobotContainer.cpp b/wpilibcExamples/src/main/cpp/examples/RamseteCommand/cpp/RobotContainer.cpp
index a72b129..e880af2 100644
--- a/wpilibcExamples/src/main/cpp/examples/RamseteCommand/cpp/RobotContainer.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/RamseteCommand/cpp/RobotContainer.cpp
@@ -12,9 +12,8 @@
#include <frc/trajectory/Trajectory.h>
#include <frc/trajectory/TrajectoryGenerator.h>
#include <frc/trajectory/constraint/DifferentialDriveVoltageConstraint.h>
-#include <frc2/command/InstantCommand.h>
+#include <frc2/command/Commands.h>
#include <frc2/command/RamseteCommand.h>
-#include <frc2/command/SequentialCommandGroup.h>
#include <frc2/command/button/JoystickButton.h>
#include "Constants.h"
@@ -26,7 +25,7 @@
ConfigureButtonBindings();
// Set up default drive command
- m_drive.SetDefaultCommand(frc2::RunCommand(
+ m_drive.SetDefaultCommand(frc2::cmd::Run(
[this] {
m_drive.ArcadeDrive(-m_driverController.GetLeftY(),
-m_driverController.GetRightX());
@@ -43,7 +42,7 @@
.OnFalse(&m_driveFullSpeed);
}
-frc2::Command* RobotContainer::GetAutonomousCommand() {
+frc2::CommandPtr RobotContainer::GetAutonomousCommand() {
// Create a voltage constraint to ensure we don't accelerate too fast
frc::DifferentialDriveVoltageConstraint autoVoltageConstraint{
frc::SimpleMotorFeedforward<units::meters>{
@@ -69,25 +68,23 @@
// Pass the config
config);
- frc2::RamseteCommand ramseteCommand{
- exampleTrajectory,
- [this]() { return m_drive.GetPose(); },
+ frc2::CommandPtr ramseteCommand{frc2::RamseteCommand(
+ exampleTrajectory, [this] { return m_drive.GetPose(); },
frc::RamseteController{AutoConstants::kRamseteB,
AutoConstants::kRamseteZeta},
frc::SimpleMotorFeedforward<units::meters>{
DriveConstants::ks, DriveConstants::kv, DriveConstants::ka},
DriveConstants::kDriveKinematics,
[this] { return m_drive.GetWheelSpeeds(); },
- frc2::PIDController{DriveConstants::kPDriveVel, 0, 0},
- frc2::PIDController{DriveConstants::kPDriveVel, 0, 0},
+ frc::PIDController{DriveConstants::kPDriveVel, 0, 0},
+ frc::PIDController{DriveConstants::kPDriveVel, 0, 0},
[this](auto left, auto right) { m_drive.TankDriveVolts(left, right); },
- {&m_drive}};
+ {&m_drive})};
// Reset odometry to the starting pose of the trajectory.
m_drive.ResetOdometry(exampleTrajectory.InitialPose());
- // no auto
- return new frc2::SequentialCommandGroup(
- std::move(ramseteCommand),
- frc2::InstantCommand([this] { m_drive.TankDriveVolts(0_V, 0_V); }, {}));
+ return std::move(ramseteCommand)
+ .BeforeStarting(
+ frc2::cmd::RunOnce([this] { m_drive.TankDriveVolts(0_V, 0_V); }, {}));
}
diff --git a/wpilibcExamples/src/main/cpp/examples/RamseteCommand/cpp/subsystems/DriveSubsystem.cpp b/wpilibcExamples/src/main/cpp/examples/RamseteCommand/cpp/subsystems/DriveSubsystem.cpp
index f8ec1db..0bc598e 100644
--- a/wpilibcExamples/src/main/cpp/examples/RamseteCommand/cpp/subsystems/DriveSubsystem.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/RamseteCommand/cpp/subsystems/DriveSubsystem.cpp
@@ -23,8 +23,8 @@
m_rightMotors.SetInverted(true);
// Set the distance per pulse for the encoders
- m_leftEncoder.SetDistancePerPulse(kEncoderDistancePerPulse);
- m_rightEncoder.SetDistancePerPulse(kEncoderDistancePerPulse);
+ m_leftEncoder.SetDistancePerPulse(kEncoderDistancePerPulse.value());
+ m_rightEncoder.SetDistancePerPulse(kEncoderDistancePerPulse.value());
ResetEncoders();
}
diff --git a/wpilibcExamples/src/main/cpp/examples/RamseteCommand/include/Constants.h b/wpilibcExamples/src/main/cpp/examples/RamseteCommand/include/Constants.h
index 18747d4..f7a061a 100644
--- a/wpilibcExamples/src/main/cpp/examples/RamseteCommand/include/Constants.h
+++ b/wpilibcExamples/src/main/cpp/examples/RamseteCommand/include/Constants.h
@@ -39,11 +39,10 @@
extern const frc::DifferentialDriveKinematics kDriveKinematics;
constexpr int kEncoderCPR = 1024;
-constexpr double kWheelDiameterInches = 6;
-constexpr double kEncoderDistancePerPulse =
+constexpr units::meter_t kWheelDiameter = 6_in;
+constexpr auto kEncoderDistancePerPulse =
// Assumes the encoders are directly mounted on the wheel shafts
- (kWheelDiameterInches * std::numbers::pi) /
- static_cast<double>(kEncoderCPR);
+ (kWheelDiameter * std::numbers::pi) / static_cast<double>(kEncoderCPR);
// These are example values only - DO NOT USE THESE FOR YOUR OWN ROBOT!
// These characterization values MUST be determined either experimentally or
diff --git a/wpilibcExamples/src/main/cpp/examples/RamseteCommand/include/Robot.h b/wpilibcExamples/src/main/cpp/examples/RamseteCommand/include/Robot.h
index a82f2ac..889bfdf 100644
--- a/wpilibcExamples/src/main/cpp/examples/RamseteCommand/include/Robot.h
+++ b/wpilibcExamples/src/main/cpp/examples/RamseteCommand/include/Robot.h
@@ -4,8 +4,10 @@
#pragma once
+#include <optional>
+
#include <frc/TimedRobot.h>
-#include <frc2/command/Command.h>
+#include <frc2/command/CommandPtr.h>
#include "RobotContainer.h"
@@ -22,9 +24,8 @@
void TestPeriodic() override;
private:
- // Have it null by default so that if testing teleop it
- // doesn't have undefined behavior and potentially crash.
- frc2::Command* m_autonomousCommand = nullptr;
+ // Have it empty by default
+ std::optional<frc2::CommandPtr> m_autonomousCommand;
RobotContainer m_container;
};
diff --git a/wpilibcExamples/src/main/cpp/examples/RamseteCommand/include/RobotContainer.h b/wpilibcExamples/src/main/cpp/examples/RamseteCommand/include/RobotContainer.h
index 3d6a36f..b01e6e2 100644
--- a/wpilibcExamples/src/main/cpp/examples/RamseteCommand/include/RobotContainer.h
+++ b/wpilibcExamples/src/main/cpp/examples/RamseteCommand/include/RobotContainer.h
@@ -7,11 +7,8 @@
#include <frc/XboxController.h>
#include <frc/controller/PIDController.h>
#include <frc/smartdashboard/SendableChooser.h>
-#include <frc2/command/Command.h>
+#include <frc2/command/CommandPtr.h>
#include <frc2/command/InstantCommand.h>
-#include <frc2/command/PIDCommand.h>
-#include <frc2/command/ParallelRaceGroup.h>
-#include <frc2/command/RunCommand.h>
#include "Constants.h"
#include "subsystems/DriveSubsystem.h"
@@ -27,7 +24,7 @@
public:
RobotContainer();
- frc2::Command* GetAutonomousCommand();
+ frc2::CommandPtr GetAutonomousCommand();
private:
// The driver's controller
@@ -38,13 +35,11 @@
// The robot's subsystems
DriveSubsystem m_drive;
+ // RobotContainer-owned commands
frc2::InstantCommand m_driveHalfSpeed{[this] { m_drive.SetMaxOutput(0.5); },
{}};
frc2::InstantCommand m_driveFullSpeed{[this] { m_drive.SetMaxOutput(1); },
{}};
- // The chooser for the autonomous routines
- frc::SendableChooser<frc2::Command*> m_chooser;
-
void ConfigureButtonBindings();
};
diff --git a/wpilibcExamples/src/main/cpp/examples/RamseteController/include/Drivetrain.h b/wpilibcExamples/src/main/cpp/examples/RamseteController/include/Drivetrain.h
index 40cc715..341cd38 100644
--- a/wpilibcExamples/src/main/cpp/examples/RamseteController/include/Drivetrain.h
+++ b/wpilibcExamples/src/main/cpp/examples/RamseteController/include/Drivetrain.h
@@ -70,8 +70,8 @@
frc::Encoder m_leftEncoder{0, 1};
frc::Encoder m_rightEncoder{2, 3};
- frc2::PIDController m_leftPIDController{1.0, 0.0, 0.0};
- frc2::PIDController m_rightPIDController{1.0, 0.0, 0.0};
+ frc::PIDController m_leftPIDController{1.0, 0.0, 0.0};
+ frc::PIDController m_rightPIDController{1.0, 0.0, 0.0};
frc::AnalogGyro m_gyro{0};
diff --git a/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/cpp/RapidReactCommandBot.cpp b/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/cpp/RapidReactCommandBot.cpp
index c25f0e8..1b46aff 100644
--- a/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/cpp/RapidReactCommandBot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/cpp/RapidReactCommandBot.cpp
@@ -40,6 +40,10 @@
m_storage.RunCommand())
// Since we composed this inline we should give it a name
.WithName("Shoot"));
+
+ // Toggle compressor with the Start button
+ m_driverController.Start().ToggleOnTrue(
+ m_pneumatics.DisableCompressorCommand());
}
frc2::CommandPtr RapidReactCommandBot::GetAutonomousCommand() {
diff --git a/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/cpp/subsystems/Pneumatics.cpp b/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/cpp/subsystems/Pneumatics.cpp
new file mode 100644
index 0000000..e19040a
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/cpp/subsystems/Pneumatics.cpp
@@ -0,0 +1,27 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "subsystems/Pneumatics.h"
+
+Pneumatics::Pneumatics() {}
+
+frc2::CommandPtr Pneumatics::DisableCompressorCommand() {
+ return StartEnd(
+ [&] {
+ // Disable closed-loop mode on the compressor.
+ m_compressor.Disable();
+ },
+ [&] {
+ // Enable closed-loop mode based on the digital pressure switch
+ // connected to the PCM/PH. The switch is open when the pressure is over
+ // ~120 PSI.
+ m_compressor.EnableDigital();
+ });
+}
+
+units::pounds_per_square_inch_t Pneumatics::GetPressure() {
+ // Get the pressure (in PSI) from an analog pressure sensor connected to
+ // the RIO.
+ return units::pounds_per_square_inch_t{m_pressureTransducer.Get()};
+}
diff --git a/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/RapidReactCommandBot.h b/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/RapidReactCommandBot.h
index 4f733b7..0071a83 100644
--- a/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/RapidReactCommandBot.h
+++ b/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/RapidReactCommandBot.h
@@ -10,6 +10,7 @@
#include "Constants.h"
#include "subsystems/Drive.h"
#include "subsystems/Intake.h"
+#include "subsystems/Pneumatics.h"
#include "subsystems/Shooter.h"
#include "subsystems/Storage.h"
@@ -45,6 +46,7 @@
Intake m_intake;
Shooter m_shooter;
Storage m_storage;
+ Pneumatics m_pneumatics;
// The driver's controller
frc2::CommandXboxController m_driverController{
diff --git a/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/subsystems/Drive.h b/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/subsystems/Drive.h
index 9a39a14..ac96c52 100644
--- a/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/subsystems/Drive.h
+++ b/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/subsystems/Drive.h
@@ -25,8 +25,9 @@
* @param fwd the commanded forward movement
* @param rot the commanded rotation
*/
- [[nodiscard]] frc2::CommandPtr ArcadeDriveCommand(
- std::function<double()> fwd, std::function<double()> rot);
+ [[nodiscard]]
+ frc2::CommandPtr ArcadeDriveCommand(std::function<double()> fwd,
+ std::function<double()> rot);
/**
* Returns a command that drives the robot forward a specified distance at a
@@ -35,8 +36,8 @@
* @param distance The distance to drive forward in meters
* @param speed The fraction of max speed at which to drive
*/
- [[nodiscard]] frc2::CommandPtr DriveDistanceCommand(units::meter_t distance,
- double speed);
+ [[nodiscard]]
+ frc2::CommandPtr DriveDistanceCommand(units::meter_t distance, double speed);
private:
frc::PWMSparkMax m_leftLeader{DriveConstants::kLeftMotor1Port};
diff --git a/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/subsystems/Intake.h b/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/subsystems/Intake.h
index af8d39a..111353a 100644
--- a/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/subsystems/Intake.h
+++ b/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/subsystems/Intake.h
@@ -19,14 +19,18 @@
/** Returns a command that deploys the intake, and then runs the intake motor
* indefinitely. */
- [[nodiscard]] frc2::CommandPtr IntakeCommand();
+ [[nodiscard]]
+ frc2::CommandPtr IntakeCommand();
/** Returns a command that turns off and retracts the intake. */
- [[nodiscard]] frc2::CommandPtr RetractCommand();
+ [[nodiscard]]
+ frc2::CommandPtr RetractCommand();
private:
frc::PWMSparkMax m_motor{IntakeConstants::kMotorPort};
- frc::DoubleSolenoid m_piston{frc::PneumaticsModuleType::REVPH,
+
+ // Double solenoid connected to two channels of a PCM with the default CAN ID
+ frc::DoubleSolenoid m_piston{frc::PneumaticsModuleType::CTREPCM,
IntakeConstants::kSolenoidPorts[0],
IntakeConstants::kSolenoidPorts[1]};
};
diff --git a/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/subsystems/Pneumatics.h b/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/subsystems/Pneumatics.h
new file mode 100644
index 0000000..0c1fee9
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/subsystems/Pneumatics.h
@@ -0,0 +1,44 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <frc/AnalogPotentiometer.h>
+#include <frc/Compressor.h>
+#include <frc/PneumaticsControlModule.h>
+#include <frc2/command/CommandPtr.h>
+#include <frc2/command/SubsystemBase.h>
+#include <units/pressure.h>
+
+#include "Constants.h"
+
+class Pneumatics : frc2::SubsystemBase {
+ public:
+ Pneumatics();
+ /** Returns a command that disables the compressor indefinitely. */
+ [[nodiscard]]
+ frc2::CommandPtr DisableCompressorCommand();
+
+ /**
+ * Query the analog pressure sensor.
+ *
+ * @return the measured pressure, in PSI
+ */
+ units::pounds_per_square_inch_t GetPressure();
+
+ private:
+ // External analog pressure sensor
+ // product-specific voltage->pressure conversion, see product manual
+ // in this case, 250(V/5)-25
+ // the scale parameter in the AnalogPotentiometer constructor is scaled from
+ // 1 instead of 5, so if r is the raw AnalogPotentiometer output, the
+ // pressure is 250r-25
+ static constexpr double kScale = 250;
+ static constexpr double kOffset = -25;
+ frc::AnalogPotentiometer m_pressureTransducer{/* the AnalogIn port*/ 2,
+ kScale, kOffset};
+
+ // Compressor connected to a PH with a default CAN ID
+ frc::Compressor m_compressor{frc::PneumaticsModuleType::CTREPCM};
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/subsystems/Shooter.h b/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/subsystems/Shooter.h
index 5ab2a63..b311559 100644
--- a/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/subsystems/Shooter.h
+++ b/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/subsystems/Shooter.h
@@ -28,8 +28,8 @@
*
* @param setpointRotationsPerSecond The desired shooter velocity
*/
- [[nodiscard]] frc2::CommandPtr ShootCommand(
- units::turns_per_second_t setpoint);
+ [[nodiscard]]
+ frc2::CommandPtr ShootCommand(units::turns_per_second_t setpoint);
private:
frc::PWMSparkMax m_shooterMotor{ShooterConstants::kShooterMotorPort};
diff --git a/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/subsystems/Storage.h b/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/subsystems/Storage.h
index eab6da4..58694b3 100644
--- a/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/subsystems/Storage.h
+++ b/wpilibcExamples/src/main/cpp/examples/RapidReactCommandBot/include/subsystems/Storage.h
@@ -15,7 +15,8 @@
public:
Storage();
/** Returns a command that runs the storage motor indefinitely. */
- [[nodiscard]] frc2::CommandPtr RunCommand();
+ [[nodiscard]]
+ frc2::CommandPtr RunCommand();
/** Whether the ball storage is full. */
bool IsFull() const;
diff --git a/wpilibcExamples/src/main/cpp/examples/RomiReference/cpp/RobotContainer.cpp b/wpilibcExamples/src/main/cpp/examples/RomiReference/cpp/RobotContainer.cpp
index f6e1fa4..f068a7d 100644
--- a/wpilibcExamples/src/main/cpp/examples/RomiReference/cpp/RobotContainer.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/RomiReference/cpp/RobotContainer.cpp
@@ -6,7 +6,6 @@
#include <frc/smartdashboard/SmartDashboard.h>
#include <frc2/command/Commands.h>
-#include <frc2/command/button/Button.h>
#include "commands/TeleopArcadeDrive.h"
diff --git a/wpilibcExamples/src/main/cpp/examples/RomiReference/cpp/commands/TeleopArcadeDrive.cpp b/wpilibcExamples/src/main/cpp/examples/RomiReference/cpp/commands/TeleopArcadeDrive.cpp
index 0f58527..e457af9 100644
--- a/wpilibcExamples/src/main/cpp/examples/RomiReference/cpp/commands/TeleopArcadeDrive.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/RomiReference/cpp/commands/TeleopArcadeDrive.cpp
@@ -12,7 +12,7 @@
: m_drive{subsystem},
m_xaxisSpeedSupplier{xaxisSpeedSupplier},
m_zaxisRotateSupplier{zaxisRotateSuppplier} {
- AddRequirements({subsystem});
+ AddRequirements(subsystem);
}
void TeleopArcadeDrive::Execute() {
diff --git a/wpilibcExamples/src/main/cpp/examples/RomiReference/cpp/sensors/RomiGyro.cpp b/wpilibcExamples/src/main/cpp/examples/RomiReference/cpp/sensors/RomiGyro.cpp
deleted file mode 100644
index 08a537b..0000000
--- a/wpilibcExamples/src/main/cpp/examples/RomiReference/cpp/sensors/RomiGyro.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#include "sensors/RomiGyro.h"
-
-RomiGyro::RomiGyro() : m_simDevice("Gyro:RomiGyro") {
- if (m_simDevice) {
- m_simDevice.CreateBoolean("init", hal::SimDevice::kOutput, true);
- m_simRateX =
- m_simDevice.CreateDouble("rate_x", hal::SimDevice::kInput, 0.0);
- m_simRateY =
- m_simDevice.CreateDouble("rate_y", hal::SimDevice::kInput, 0.0);
- m_simRateZ =
- m_simDevice.CreateDouble("rate_z", hal::SimDevice::kInput, 0.0);
- m_simAngleX =
- m_simDevice.CreateDouble("angle_x", hal::SimDevice::kInput, 0.0);
- m_simAngleY =
- m_simDevice.CreateDouble("angle_y", hal::SimDevice::kInput, 0.0);
- m_simAngleZ =
- m_simDevice.CreateDouble("angle_z", hal::SimDevice::kInput, 0.0);
- }
-}
-
-double RomiGyro::GetRateX() {
- if (m_simRateX) {
- return m_simRateX.Get();
- }
-
- return 0.0;
-}
-
-double RomiGyro::GetRateY() {
- if (m_simRateY) {
- return m_simRateY.Get();
- }
-
- return 0.0;
-}
-
-double RomiGyro::GetRateZ() {
- if (m_simRateZ) {
- return m_simRateZ.Get();
- }
-
- return 0.0;
-}
-
-double RomiGyro::GetAngleX() {
- if (m_simAngleX) {
- return m_simAngleX.Get() - m_angleXOffset;
- }
-
- return 0.0;
-}
-
-double RomiGyro::GetAngleY() {
- if (m_simAngleY) {
- return m_simAngleY.Get() - m_angleYOffset;
- }
-
- return 0.0;
-}
-
-double RomiGyro::GetAngleZ() {
- if (m_simAngleZ) {
- return m_simAngleZ.Get() - m_angleZOffset;
- }
-
- return 0.0;
-}
-
-void RomiGyro::Reset() {
- if (m_simAngleX) {
- m_angleXOffset = m_simAngleX.Get();
- m_angleYOffset = m_simAngleY.Get();
- m_angleZOffset = m_simAngleZ.Get();
- }
-}
diff --git a/wpilibcExamples/src/main/cpp/examples/RomiReference/cpp/subsystems/OnBoardIO.cpp b/wpilibcExamples/src/main/cpp/examples/RomiReference/cpp/subsystems/OnBoardIO.cpp
deleted file mode 100644
index 1b76c74..0000000
--- a/wpilibcExamples/src/main/cpp/examples/RomiReference/cpp/subsystems/OnBoardIO.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#include "subsystems/OnBoardIO.h"
-
-#include <frc/DigitalInput.h>
-#include <frc/DigitalOutput.h>
-#include <frc/Errors.h>
-#include <frc/Timer.h>
-
-OnBoardIO::OnBoardIO(OnBoardIO::ChannelMode dio1, OnBoardIO::ChannelMode dio2) {
- if (dio1 == ChannelMode::INPUT) {
- m_buttonB = std::make_unique<frc::DigitalInput>(1);
- } else {
- m_greenLed = std::make_unique<frc::DigitalOutput>(1);
- }
- if (dio2 == ChannelMode::INPUT) {
- m_buttonC = std::make_unique<frc::DigitalInput>(2);
- } else {
- m_redLed = std::make_unique<frc::DigitalOutput>(2);
- }
-}
-
-bool OnBoardIO::GetButtonAPressed() {
- return m_buttonA.Get();
-}
-
-bool OnBoardIO::GetButtonBPressed() {
- if (m_buttonB) {
- return m_buttonB->Get();
- }
-
- auto currentTime = frc::Timer::GetFPGATimestamp();
- if (currentTime > m_nextMessageTime) {
- FRC_ReportError(frc::err::Error, "Button {} was not configured", "B");
- m_nextMessageTime = currentTime + kMessageInterval;
- }
- return false;
-}
-
-bool OnBoardIO::GetButtonCPressed() {
- if (m_buttonC) {
- return m_buttonC->Get();
- }
-
- auto currentTime = frc::Timer::GetFPGATimestamp();
- if (currentTime > m_nextMessageTime) {
- FRC_ReportError(frc::err::Error, "Button {} was not configured", "C");
- m_nextMessageTime = currentTime + kMessageInterval;
- }
- return false;
-}
-
-void OnBoardIO::SetGreenLed(bool value) {
- if (m_greenLed) {
- m_greenLed->Set(value);
- } else {
- auto currentTime = frc::Timer::GetFPGATimestamp();
- if (currentTime > m_nextMessageTime) {
- FRC_ReportError(frc::err::Error, "{} LED was not configured", "Green");
- m_nextMessageTime = currentTime + kMessageInterval;
- }
- }
-}
-
-void OnBoardIO::SetRedLed(bool value) {
- if (m_redLed) {
- m_redLed->Set(value);
- } else {
- auto currentTime = frc::Timer::GetFPGATimestamp();
- if (currentTime > m_nextMessageTime) {
- FRC_ReportError(frc::err::Error, "{} LED was not configured", "Red");
- m_nextMessageTime = currentTime + kMessageInterval;
- }
- }
-}
-
-void OnBoardIO::SetYellowLed(bool value) {
- m_yellowLed.Set(value);
-}
diff --git a/wpilibcExamples/src/main/cpp/examples/RomiReference/include/RobotContainer.h b/wpilibcExamples/src/main/cpp/examples/RomiReference/include/RobotContainer.h
index ab88b15..0a77614 100644
--- a/wpilibcExamples/src/main/cpp/examples/RomiReference/include/RobotContainer.h
+++ b/wpilibcExamples/src/main/cpp/examples/RomiReference/include/RobotContainer.h
@@ -5,16 +5,16 @@
#pragma once
#include <frc/Joystick.h>
+#include <frc/romi/OnBoardIO.h>
#include <frc/smartdashboard/SendableChooser.h>
#include <frc2/command/Command.h>
#include <frc2/command/CommandPtr.h>
-#include <frc2/command/button/Button.h>
+#include <frc2/command/button/Trigger.h>
#include "Constants.h"
#include "commands/AutonomousDistance.h"
#include "commands/AutonomousTime.h"
#include "subsystems/Drivetrain.h"
-#include "subsystems/OnBoardIO.h"
/**
* This class is where the bulk of the robot should be declared. Since
@@ -41,14 +41,14 @@
frc2::Command* GetAutonomousCommand();
private:
- // Assumes a gamepad plugged into channnel 0
+ // Assumes a gamepad plugged into channel 0
frc::Joystick m_controller{0};
frc::SendableChooser<frc2::Command*> m_chooser;
// The robot's subsystems
Drivetrain m_drive;
- OnBoardIO m_onboardIO{OnBoardIO::ChannelMode::INPUT,
- OnBoardIO::ChannelMode::INPUT};
+ frc::OnBoardIO m_onboardIO{frc::OnBoardIO::ChannelMode::INPUT,
+ frc::OnBoardIO::ChannelMode::INPUT};
// Example button
frc2::Trigger m_onboardButtonA{
diff --git a/wpilibcExamples/src/main/cpp/examples/RomiReference/include/commands/DriveDistance.h b/wpilibcExamples/src/main/cpp/examples/RomiReference/include/commands/DriveDistance.h
index 34a1e93..6011531 100644
--- a/wpilibcExamples/src/main/cpp/examples/RomiReference/include/commands/DriveDistance.h
+++ b/wpilibcExamples/src/main/cpp/examples/RomiReference/include/commands/DriveDistance.h
@@ -4,18 +4,17 @@
#pragma once
-#include <frc2/command/CommandBase.h>
+#include <frc2/command/Command.h>
#include <frc2/command/CommandHelper.h>
#include <units/length.h>
#include "subsystems/Drivetrain.h"
-class DriveDistance
- : public frc2::CommandHelper<frc2::CommandBase, DriveDistance> {
+class DriveDistance : public frc2::CommandHelper<frc2::Command, DriveDistance> {
public:
DriveDistance(double speed, units::meter_t distance, Drivetrain* drive)
: m_speed(speed), m_distance(distance), m_drive(drive) {
- AddRequirements({m_drive});
+ AddRequirements(m_drive);
}
void Initialize() override;
diff --git a/wpilibcExamples/src/main/cpp/examples/RomiReference/include/commands/DriveTime.h b/wpilibcExamples/src/main/cpp/examples/RomiReference/include/commands/DriveTime.h
index a0135e5..9dfd240 100644
--- a/wpilibcExamples/src/main/cpp/examples/RomiReference/include/commands/DriveTime.h
+++ b/wpilibcExamples/src/main/cpp/examples/RomiReference/include/commands/DriveTime.h
@@ -5,17 +5,17 @@
#pragma once
#include <frc/Timer.h>
-#include <frc2/command/CommandBase.h>
+#include <frc2/command/Command.h>
#include <frc2/command/CommandHelper.h>
#include <units/time.h>
#include "subsystems/Drivetrain.h"
-class DriveTime : public frc2::CommandHelper<frc2::CommandBase, DriveTime> {
+class DriveTime : public frc2::CommandHelper<frc2::Command, DriveTime> {
public:
DriveTime(double speed, units::second_t time, Drivetrain* drive)
: m_speed(speed), m_duration(time), m_drive(drive) {
- AddRequirements({m_drive});
+ AddRequirements(m_drive);
}
void Initialize() override;
diff --git a/wpilibcExamples/src/main/cpp/examples/RomiReference/include/commands/TeleopArcadeDrive.h b/wpilibcExamples/src/main/cpp/examples/RomiReference/include/commands/TeleopArcadeDrive.h
index 859b6b7..fe2e241 100644
--- a/wpilibcExamples/src/main/cpp/examples/RomiReference/include/commands/TeleopArcadeDrive.h
+++ b/wpilibcExamples/src/main/cpp/examples/RomiReference/include/commands/TeleopArcadeDrive.h
@@ -4,13 +4,15 @@
#pragma once
-#include <frc2/command/CommandBase.h>
+#include <functional>
+
+#include <frc2/command/Command.h>
#include <frc2/command/CommandHelper.h>
#include "subsystems/Drivetrain.h"
class TeleopArcadeDrive
- : public frc2::CommandHelper<frc2::CommandBase, TeleopArcadeDrive> {
+ : public frc2::CommandHelper<frc2::Command, TeleopArcadeDrive> {
public:
TeleopArcadeDrive(Drivetrain* subsystem,
std::function<double()> xaxisSpeedSupplier,
diff --git a/wpilibcExamples/src/main/cpp/examples/RomiReference/include/commands/TurnDegrees.h b/wpilibcExamples/src/main/cpp/examples/RomiReference/include/commands/TurnDegrees.h
index 7ce65df..c0f25b1 100644
--- a/wpilibcExamples/src/main/cpp/examples/RomiReference/include/commands/TurnDegrees.h
+++ b/wpilibcExamples/src/main/cpp/examples/RomiReference/include/commands/TurnDegrees.h
@@ -4,18 +4,18 @@
#pragma once
-#include <frc2/command/CommandBase.h>
+#include <frc2/command/Command.h>
#include <frc2/command/CommandHelper.h>
#include <units/angle.h>
#include <units/length.h>
#include "subsystems/Drivetrain.h"
-class TurnDegrees : public frc2::CommandHelper<frc2::CommandBase, TurnDegrees> {
+class TurnDegrees : public frc2::CommandHelper<frc2::Command, TurnDegrees> {
public:
TurnDegrees(double speed, units::degree_t angle, Drivetrain* drive)
: m_speed(speed), m_angle(angle), m_drive(drive) {
- AddRequirements({m_drive});
+ AddRequirements(m_drive);
}
void Initialize() override;
diff --git a/wpilibcExamples/src/main/cpp/examples/RomiReference/include/commands/TurnTime.h b/wpilibcExamples/src/main/cpp/examples/RomiReference/include/commands/TurnTime.h
index 395825d..3c478a8 100644
--- a/wpilibcExamples/src/main/cpp/examples/RomiReference/include/commands/TurnTime.h
+++ b/wpilibcExamples/src/main/cpp/examples/RomiReference/include/commands/TurnTime.h
@@ -5,17 +5,17 @@
#pragma once
#include <frc/Timer.h>
-#include <frc2/command/CommandBase.h>
+#include <frc2/command/Command.h>
#include <frc2/command/CommandHelper.h>
#include <units/time.h>
#include "subsystems/Drivetrain.h"
-class TurnTime : public frc2::CommandHelper<frc2::CommandBase, TurnTime> {
+class TurnTime : public frc2::CommandHelper<frc2::Command, TurnTime> {
public:
TurnTime(double speed, units::second_t time, Drivetrain* drive)
: m_speed(speed), m_duration(time), m_drive(drive) {
- AddRequirements({m_drive});
+ AddRequirements(m_drive);
}
void Initialize() override;
diff --git a/wpilibcExamples/src/main/cpp/examples/RomiReference/include/sensors/RomiGyro.h b/wpilibcExamples/src/main/cpp/examples/RomiReference/include/sensors/RomiGyro.h
deleted file mode 100644
index 0e93d48..0000000
--- a/wpilibcExamples/src/main/cpp/examples/RomiReference/include/sensors/RomiGyro.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#pragma once
-
-#include <hal/SimDevice.h>
-
-class RomiGyro {
- public:
- RomiGyro();
-
- /**
- * Gets the rate of turn in degrees-per-second around the X-axis
- */
- double GetRateX();
-
- /**
- * Gets the rate of turn in degrees-per-second around the Y-axis
- */
- double GetRateY();
-
- /**
- * Gets the rate of turn in degrees-per-second around the Z-axis
- */
- double GetRateZ();
-
- /**
- * Gets the currently reported angle around the X-axis
- */
- double GetAngleX();
-
- /**
- * Gets the currently reported angle around the X-axis
- */
- double GetAngleY();
-
- /**
- * Gets the currently reported angle around the X-axis
- */
- double GetAngleZ();
-
- /**
- * Resets the gyro
- */
- void Reset();
-
- private:
- hal::SimDevice m_simDevice;
- hal::SimDouble m_simRateX;
- hal::SimDouble m_simRateY;
- hal::SimDouble m_simRateZ;
- hal::SimDouble m_simAngleX;
- hal::SimDouble m_simAngleY;
- hal::SimDouble m_simAngleZ;
-
- double m_angleXOffset = 0;
- double m_angleYOffset = 0;
- double m_angleZOffset = 0;
-};
diff --git a/wpilibcExamples/src/main/cpp/examples/RomiReference/include/subsystems/Drivetrain.h b/wpilibcExamples/src/main/cpp/examples/RomiReference/include/subsystems/Drivetrain.h
index 98ae957..ace7d33 100644
--- a/wpilibcExamples/src/main/cpp/examples/RomiReference/include/subsystems/Drivetrain.h
+++ b/wpilibcExamples/src/main/cpp/examples/RomiReference/include/subsystems/Drivetrain.h
@@ -8,11 +8,10 @@
#include <frc/Encoder.h>
#include <frc/drive/DifferentialDrive.h>
#include <frc/motorcontrol/Spark.h>
+#include <frc/romi/RomiGyro.h>
#include <frc2/command/SubsystemBase.h>
#include <units/length.h>
-#include "sensors/RomiGyro.h"
-
class Drivetrain : public frc2::SubsystemBase {
public:
static constexpr double kCountsPerRevolution = 1440.0;
@@ -117,6 +116,6 @@
frc::DifferentialDrive m_drive{m_leftMotor, m_rightMotor};
- RomiGyro m_gyro;
+ frc::RomiGyro m_gyro;
frc::BuiltInAccelerometer m_accelerometer;
};
diff --git a/wpilibcExamples/src/main/cpp/examples/RomiReference/include/subsystems/OnBoardIO.h b/wpilibcExamples/src/main/cpp/examples/RomiReference/include/subsystems/OnBoardIO.h
deleted file mode 100644
index 0bb5225..0000000
--- a/wpilibcExamples/src/main/cpp/examples/RomiReference/include/subsystems/OnBoardIO.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#pragma once
-
-#include <memory>
-
-#include <frc/DigitalInput.h>
-#include <frc/DigitalOutput.h>
-#include <frc2/command/SubsystemBase.h>
-
-/**
- * This class represents the onboard IO of the Romi
- * reference robot. This includes the pushbuttons and
- * LEDs.
- *
- * <p>DIO 0 - Button A (input only)
- * DIO 1 - Button B (input) or Green LED (output)
- * DIO 2 - Button C (input) or Red LED (output)
- * DIO 3 - Yellow LED (output only)
- */
-class OnBoardIO : public frc2::SubsystemBase {
- public:
- enum ChannelMode { INPUT, OUTPUT };
- OnBoardIO(OnBoardIO::ChannelMode dio1, OnBoardIO::ChannelMode dio2);
-
- static constexpr auto kMessageInterval = 1_s;
- units::second_t m_nextMessageTime = 0_s;
-
- /**
- * Gets if the A button is pressed.
- */
- bool GetButtonAPressed();
-
- /**
- * Gets if the B button is pressed.
- */
- bool GetButtonBPressed();
-
- /**
- * Gets if the C button is pressed.
- */
- bool GetButtonCPressed();
-
- /**
- * Sets the green LED.
- */
- void SetGreenLed(bool value);
-
- /**
- * Sets the red LED.
- */
- void SetRedLed(bool value);
-
- /**
- * Sets the yellow LED.
- */
- void SetYellowLed(bool value);
-
- private:
- frc::DigitalInput m_buttonA{0};
- frc::DigitalOutput m_yellowLed{3};
-
- // DIO 1
- std::unique_ptr<frc::DigitalInput> m_buttonB;
- std::unique_ptr<frc::DigitalOutput> m_greenLed;
-
- // DIO 2
- std::unique_ptr<frc::DigitalInput> m_buttonC;
- std::unique_ptr<frc::DigitalOutput> m_redLed;
-};
diff --git a/wpilibcExamples/src/main/cpp/examples/SchedulerEventLogging/cpp/RobotContainer.cpp b/wpilibcExamples/src/main/cpp/examples/SchedulerEventLogging/cpp/RobotContainer.cpp
deleted file mode 100644
index e54c42f..0000000
--- a/wpilibcExamples/src/main/cpp/examples/SchedulerEventLogging/cpp/RobotContainer.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#include "RobotContainer.h"
-
-#include <frc/shuffleboard/Shuffleboard.h>
-#include <frc2/command/CommandScheduler.h>
-#include <frc2/command/button/JoystickButton.h>
-
-RobotContainer::RobotContainer() {
- // Initialize all of your commands and subsystems here
-
- // Set names of commands
- m_instantCommand1.SetName("Instant Command 1");
- m_instantCommand2.SetName("Instant Command 2");
- m_waitCommand.SetName("Wait 5 Seconds Command");
-
- // Set the scheduler to log Shuffleboard events for command initialize,
- // interrupt, finish
- frc2::CommandScheduler::GetInstance().OnCommandInitialize(
- [](const frc2::Command& command) {
- frc::Shuffleboard::AddEventMarker(
- "Command Initialized", command.GetName(),
- frc::ShuffleboardEventImportance::kNormal);
- });
- frc2::CommandScheduler::GetInstance().OnCommandInterrupt(
- [](const frc2::Command& command) {
- frc::Shuffleboard::AddEventMarker(
- "Command Interrupted", command.GetName(),
- frc::ShuffleboardEventImportance::kNormal);
- });
- frc2::CommandScheduler::GetInstance().OnCommandFinish(
- [](const frc2::Command& command) {
- frc::Shuffleboard::AddEventMarker(
- "Command Finished", command.GetName(),
- frc::ShuffleboardEventImportance::kNormal);
- });
-
- // Configure the button bindings
- ConfigureButtonBindings();
-}
-
-void RobotContainer::ConfigureButtonBindings() {
- // Configure your button bindings here
-
- // Run instant command 1 when the 'A' button is pressed
- frc2::JoystickButton(&m_driverController, frc::XboxController::Button::kA)
- .OnTrue(&m_instantCommand1);
- // Run instant command 2 when the 'X' button is pressed
- frc2::JoystickButton(&m_driverController, frc::XboxController::Button::kX)
- .OnTrue(&m_instantCommand2);
- // Run instant command 3 when the 'Y' button is held; release early to
- // interrupt
- frc2::JoystickButton(&m_driverController, frc::XboxController::Button::kY)
- .OnTrue(&m_waitCommand);
-}
-
-frc2::Command* RobotContainer::GetAutonomousCommand() {
- // no auto
- return nullptr;
-}
diff --git a/wpilibcExamples/src/main/cpp/examples/SchedulerEventLogging/include/RobotContainer.h b/wpilibcExamples/src/main/cpp/examples/SchedulerEventLogging/include/RobotContainer.h
deleted file mode 100644
index 715b9c5..0000000
--- a/wpilibcExamples/src/main/cpp/examples/SchedulerEventLogging/include/RobotContainer.h
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) FIRST and other WPILib contributors.
-// Open Source Software; you can modify and/or share it under the terms of
-// the WPILib BSD license file in the root directory of this project.
-
-#pragma once
-
-#include <frc/XboxController.h>
-#include <frc2/command/Command.h>
-#include <frc2/command/InstantCommand.h>
-#include <frc2/command/WaitCommand.h>
-
-#include "Constants.h"
-
-/**
- * This class is where the bulk of the robot should be declared. Since
- * Command-based is a "declarative" paradigm, very little robot logic should
- * actually be handled in the {@link Robot} periodic methods (other than the
- * scheduler calls). Instead, the structure of the robot (including subsystems,
- * commands, and button mappings) should be declared here.
- */
-class RobotContainer {
- public:
- RobotContainer();
-
- frc2::Command* GetAutonomousCommand();
-
- private:
- // The robot's subsystems and commands are defined here...
-
- // The driver's controller
- frc::XboxController m_driverController{OIConstants::kDriverControllerPort};
-
- // Three commands that do nothing; for demonstration purposes.
- frc2::InstantCommand m_instantCommand1;
- frc2::InstantCommand m_instantCommand2;
- frc2::WaitCommand m_waitCommand{5_s};
-
- void ConfigureButtonBindings();
-};
diff --git a/wpilibcExamples/src/main/cpp/examples/SelectCommand/cpp/RobotContainer.cpp b/wpilibcExamples/src/main/cpp/examples/SelectCommand/cpp/RobotContainer.cpp
index 573fcac..69895cb 100644
--- a/wpilibcExamples/src/main/cpp/examples/SelectCommand/cpp/RobotContainer.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/SelectCommand/cpp/RobotContainer.cpp
@@ -17,5 +17,5 @@
frc2::Command* RobotContainer::GetAutonomousCommand() {
// Run the select command in autonomous
- return &m_exampleSelectCommand;
+ return m_exampleSelectCommand.get();
}
diff --git a/wpilibcExamples/src/main/cpp/examples/SelectCommand/include/RobotContainer.h b/wpilibcExamples/src/main/cpp/examples/SelectCommand/include/RobotContainer.h
index 40eea33..a1a2c86 100644
--- a/wpilibcExamples/src/main/cpp/examples/SelectCommand/include/RobotContainer.h
+++ b/wpilibcExamples/src/main/cpp/examples/SelectCommand/include/RobotContainer.h
@@ -5,8 +5,7 @@
#pragma once
#include <frc2/command/Command.h>
-#include <frc2/command/PrintCommand.h>
-#include <frc2/command/SelectCommand.h>
+#include <frc2/command/Commands.h>
/**
* This class is where the bulk of the robot should be declared. Since
@@ -36,12 +35,12 @@
// value returned by the selector method at runtime. Note that selectcommand
// takes a generic type, so the selector does not have to be an enum; it could
// be any desired type (string, integer, boolean, double...)
- frc2::SelectCommand<CommandSelector> m_exampleSelectCommand{
+ frc2::CommandPtr m_exampleSelectCommand = frc2::cmd::Select<CommandSelector>(
[this] { return Select(); },
// Maps selector values to commands
- std::pair{ONE, frc2::PrintCommand{"Command one was selected!"}},
- std::pair{TWO, frc2::PrintCommand{"Command two was selected!"}},
- std::pair{THREE, frc2::PrintCommand{"Command three was selected!"}}};
+ std::pair{ONE, frc2::cmd::Print("Command one was selected!")},
+ std::pair{TWO, frc2::cmd::Print("Command two was selected!")},
+ std::pair{THREE, frc2::cmd::Print("Command three was selected!")});
void ConfigureButtonBindings();
};
diff --git a/wpilibcExamples/src/main/cpp/examples/ShuffleBoard/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/ShuffleBoard/cpp/Robot.cpp
index 1417801..b951f18 100644
--- a/wpilibcExamples/src/main/cpp/examples/ShuffleBoard/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/ShuffleBoard/cpp/Robot.cpp
@@ -42,7 +42,7 @@
// Put encoders in a list layout.
frc::ShuffleboardLayout& encoders =
- driveBaseTab.GetLayout("List Layout", "Encoders")
+ driveBaseTab.GetLayout("Encoders", frc::BuiltInLayouts::kList)
.WithPosition(0, 0)
.WithSize(2, 2);
encoders.Add("Left Encoder", m_leftEncoder);
diff --git a/wpilibcExamples/src/main/cpp/examples/SimpleDifferentialDriveSimulation/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/SimpleDifferentialDriveSimulation/cpp/Robot.cpp
index 7ea7b09..523bb7b 100644
--- a/wpilibcExamples/src/main/cpp/examples/SimpleDifferentialDriveSimulation/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/SimpleDifferentialDriveSimulation/cpp/Robot.cpp
@@ -22,8 +22,7 @@
void RobotPeriodic() override { m_drive.Periodic(); }
void AutonomousInit() override {
- m_timer.Reset();
- m_timer.Start();
+ m_timer.Restart();
m_drive.ResetOdometry(m_trajectory.InitialPose());
}
diff --git a/wpilibcExamples/src/main/cpp/examples/SimpleDifferentialDriveSimulation/include/Drivetrain.h b/wpilibcExamples/src/main/cpp/examples/SimpleDifferentialDriveSimulation/include/Drivetrain.h
index 80363b5..4c274fe 100644
--- a/wpilibcExamples/src/main/cpp/examples/SimpleDifferentialDriveSimulation/include/Drivetrain.h
+++ b/wpilibcExamples/src/main/cpp/examples/SimpleDifferentialDriveSimulation/include/Drivetrain.h
@@ -86,8 +86,8 @@
frc::Encoder m_leftEncoder{0, 1};
frc::Encoder m_rightEncoder{2, 3};
- frc2::PIDController m_leftPIDController{8.5, 0.0, 0.0};
- frc2::PIDController m_rightPIDController{8.5, 0.0, 0.0};
+ frc::PIDController m_leftPIDController{8.5, 0.0, 0.0};
+ frc::PIDController m_rightPIDController{8.5, 0.0, 0.0};
frc::AnalogGyro m_gyro{0};
diff --git a/wpilibcExamples/src/main/cpp/examples/Solenoid/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/Solenoid/cpp/Robot.cpp
index 82e481b..88a2dbf 100644
--- a/wpilibcExamples/src/main/cpp/examples/Solenoid/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/Solenoid/cpp/Robot.cpp
@@ -2,69 +2,96 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
-#include <frc/DoubleSolenoid.h>
-#include <frc/Joystick.h>
-#include <frc/PneumaticsControlModule.h>
-#include <frc/Solenoid.h>
-#include <frc/TimedRobot.h>
+#include "Robot.h"
-/**
- * This is a sample program showing the use of the solenoid classes during
- * operator control.
- *
- * Three buttons from a joystick will be used to control two solenoids: One
- * button to control the position of a single solenoid and the other two buttons
- * to control a double solenoid.
- *
- * Single solenoids can either be on or off, such that the air diverted through
- * them goes through either one channel or the other.
- *
- * Double solenoids have three states: Off, Forward, and Reverse. Forward and
- * Reverse divert the air through the two channels and correspond to the on and
- * off of a single solenoid, but a double solenoid can also be "off", where both
- * channels are diverted to exhaust such that there is no pressure in either
- * channel.
- *
- * Additionally, double solenoids take up two channels on your PCM whereas
- * single solenoids only take a single channel.
- */
-class Robot : public frc::TimedRobot {
- public:
- void TeleopPeriodic() override {
- /* The output of GetRawButton is true/false depending on whether the button
- * is pressed; Set takes a boolean for for whether to use the default
- * (false) channel or the other (true).
- */
- m_solenoid.Set(m_stick.GetRawButton(kSolenoidButton));
+#include <frc/shuffleboard/Shuffleboard.h>
+#include <units/pressure.h>
- /* In order to set the double solenoid, we will say that if neither button
- * is pressed, it is off, if just one button is pressed, set the solenoid to
- * correspond to that button, and if both are pressed, set the solenoid to
- * Forwards.
- */
- if (m_stick.GetRawButton(kDoubleSolenoidForward)) {
- m_doubleSolenoid.Set(frc::DoubleSolenoid::kForward);
- } else if (m_stick.GetRawButton(kDoubleSolenoidReverse)) {
- m_doubleSolenoid.Set(frc::DoubleSolenoid::kReverse);
- } else {
- m_doubleSolenoid.Set(frc::DoubleSolenoid::kOff);
- }
+void Robot::RobotInit() {
+ // Publish elements to shuffleboard.
+ frc::ShuffleboardTab& tab = frc::Shuffleboard::GetTab("Pneumatics");
+ tab.Add("Single Solenoid", m_solenoid);
+ tab.Add("Double Solenoid", m_doubleSolenoid);
+ tab.Add("Compressor", m_compressor);
+
+ // Also publish some raw data
+ tab.AddDouble("PH Pressure [PSI]", [&] {
+ // Get the pressure (in PSI) from the analog sensor connected to the PH.
+ // This function is supported only on the PH!
+ // On a PCM, this function will return 0.
+ units::pounds_per_square_inch_t pressure = m_compressor.GetPressure();
+ return pressure.value();
+ });
+ tab.AddDouble("Compressor Current", [&] {
+ // Get compressor current draw.
+ units::ampere_t compressorCurrent = m_compressor.GetCurrent();
+ return compressorCurrent.value();
+ });
+ tab.AddBoolean("Compressor Active", [&] {
+ // Get whether the compressor is active.
+ return m_compressor.IsEnabled();
+ });
+ tab.AddBoolean("Pressure Switch", [&] {
+ // Get the digital pressure switch connected to the PCM/PH.
+ // The switch is open when the pressure is over ~120 PSI.
+ return m_compressor.GetPressureSwitchValue();
+ });
+}
+
+void Robot::TeleopPeriodic() {
+ /*
+ * The output of GetRawButton is true/false depending on whether
+ * the button is pressed; Set takes a boolean for whether
+ * to retract the solenoid (false) or extend it (true).
+ */
+ m_solenoid.Set(m_stick.GetRawButton(kSolenoidButton));
+
+ /*
+ * GetRawButtonPressed will only return true once per press.
+ * If a button is pressed, set the solenoid to the respective channel.
+ */
+ if (m_stick.GetRawButtonPressed(kDoubleSolenoidForward)) {
+ m_doubleSolenoid.Set(frc::DoubleSolenoid::kForward);
+ } else if (m_stick.GetRawButtonPressed(kDoubleSolenoidReverse)) {
+ m_doubleSolenoid.Set(frc::DoubleSolenoid::kReverse);
}
- private:
- frc::Joystick m_stick{0};
-
- // Solenoid corresponds to a single solenoid.
- frc::Solenoid m_solenoid{frc::PneumaticsModuleType::CTREPCM, 0};
-
- // DoubleSolenoid corresponds to a double solenoid.
- frc::DoubleSolenoid m_doubleSolenoid{frc::PneumaticsModuleType::CTREPCM, 1,
- 2};
-
- static constexpr int kSolenoidButton = 1;
- static constexpr int kDoubleSolenoidForward = 2;
- static constexpr int kDoubleSolenoidReverse = 3;
-};
+ // On button press, toggle the compressor with the mode selected from the
+ // dashboard.
+ if (m_stick.GetRawButtonPressed(kCompressorButton)) {
+ // Check whether the compressor is currently enabled.
+ bool isCompressorEnabled = m_compressor.IsEnabled();
+ if (isCompressorEnabled) {
+ // Disable closed-loop mode on the compressor.
+ m_compressor.Disable();
+ } else {
+ // Change the if directives to select the closed-loop mode you want to
+ // use:
+#if 0
+ // Enable closed-loop mode based on the digital pressure switch
+ // connected to the PCM/PH.
+ m_compressor.EnableDigital();
+#endif
+#if 1
+ // Enable closed-loop mode based on the analog pressure sensor connected
+ // to the PH. The compressor will run while the pressure reported by the
+ // sensor is in the specified range ([70 PSI, 120 PSI] in this example).
+ // Analog mode exists only on the PH! On the PCM, this enables digital
+ // control.
+ m_compressor.EnableAnalog(70_psi, 120_psi);
+#endif
+#if 0
+ // Enable closed-loop mode based on both the digital pressure switch AND the analog
+ // pressure sensor connected to the PH.
+ // The compressor will run while the pressure reported by the analog sensor is in the
+ // specified range ([70 PSI, 120 PSI] in this example) AND the digital switch reports
+ // that the system is not full.
+ // Hybrid mode exists only on the PH! On the PCM, this enables digital control.
+ m_compressor.EnableHybrid(70_psi, 120_psi);
+#endif
+ }
+ }
+}
#ifndef RUNNING_FRC_TESTS
int main() {
diff --git a/wpilibcExamples/src/main/cpp/examples/Solenoid/include/Robot.h b/wpilibcExamples/src/main/cpp/examples/Solenoid/include/Robot.h
new file mode 100644
index 0000000..550e949
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/Solenoid/include/Robot.h
@@ -0,0 +1,61 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <frc/AnalogPotentiometer.h>
+#include <frc/Compressor.h>
+#include <frc/DoubleSolenoid.h>
+#include <frc/Joystick.h>
+#include <frc/PneumaticsControlModule.h>
+#include <frc/Solenoid.h>
+#include <frc/TimedRobot.h>
+
+/**
+ * This is a sample program showing the use of the solenoid classes during
+ * operator control.
+ *
+ * Three buttons from a joystick will be used to control two solenoids: One
+ * button to control the position of a single solenoid and the other two buttons
+ * to control a double solenoid.
+ *
+ * Single solenoids can either be on or off, such that the air diverted through
+ * them goes through either one channel or the other.
+ *
+ * Double solenoids have three states: Off, Forward, and Reverse. Forward and
+ * Reverse divert the air through the two channels and correspond to the on and
+ * off of a single solenoid, but a double solenoid can also be "off", where both
+ * channels are diverted to exhaust such that there is no pressure in either
+ * channel.
+ *
+ * Additionally, double solenoids take up two channels on your PCM whereas
+ * single solenoids only take a single channel.
+ */
+
+class Robot : public frc::TimedRobot {
+ public:
+ void RobotInit() override;
+ void TeleopPeriodic() override;
+
+ private:
+ frc::Joystick m_stick{0};
+
+ // Solenoid corresponds to a single solenoid.
+ // In this case, it's connected to channel 0 of a PH with the default CAN
+ // ID.
+ frc::Solenoid m_solenoid{frc::PneumaticsModuleType::REVPH, 0};
+
+ // DoubleSolenoid corresponds to a double solenoid.
+ // In this case, it's connected to channels 1 and 2 of a PH with the default
+ // CAN ID.
+ frc::DoubleSolenoid m_doubleSolenoid{frc::PneumaticsModuleType::REVPH, 1, 2};
+
+ // Compressor connected to a PH with a default CAN ID
+ frc::Compressor m_compressor{frc::PneumaticsModuleType::REVPH};
+
+ static constexpr int kSolenoidButton = 1;
+ static constexpr int kDoubleSolenoidForward = 2;
+ static constexpr int kDoubleSolenoidReverse = 3;
+ static constexpr int kCompressorButton = 4;
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/StateSpaceArm/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/StateSpaceArm/cpp/Robot.cpp
index aec9738..f6a9eea 100644
--- a/wpilibcExamples/src/main/cpp/examples/StateSpaceArm/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/StateSpaceArm/cpp/Robot.cpp
@@ -86,8 +86,8 @@
frc::PWMSparkMax m_motor{kMotorPort};
frc::XboxController m_joystick{kJoystickPort};
- frc::TrapezoidProfile<units::radians>::Constraints m_constraints{
- 45_deg_per_s, 90_deg_per_s / 1_s};
+ frc::TrapezoidProfile<units::radians> m_profile{
+ {45_deg_per_s, 90_deg_per_s / 1_s}};
frc::TrapezoidProfile<units::radians>::State m_lastProfiledReference;
@@ -117,9 +117,7 @@
goal = {kLoweredPosition, 0_rad_per_s};
}
m_lastProfiledReference =
- (frc::TrapezoidProfile<units::radians>(m_constraints, goal,
- m_lastProfiledReference))
- .Calculate(20_ms);
+ m_profile.Calculate(20_ms, goal, m_lastProfiledReference);
m_loop.SetNextR(frc::Vectord<2>{m_lastProfiledReference.position.value(),
m_lastProfiledReference.velocity.value()});
diff --git a/wpilibcExamples/src/main/cpp/examples/StateSpaceDifferentialDriveSimulation/cpp/RobotContainer.cpp b/wpilibcExamples/src/main/cpp/examples/StateSpaceDifferentialDriveSimulation/cpp/RobotContainer.cpp
index fec6de3..8c73dc8 100644
--- a/wpilibcExamples/src/main/cpp/examples/StateSpaceDifferentialDriveSimulation/cpp/RobotContainer.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/StateSpaceDifferentialDriveSimulation/cpp/RobotContainer.cpp
@@ -91,8 +91,8 @@
DriveConstants::ks, DriveConstants::kv, DriveConstants::ka),
DriveConstants::kDriveKinematics,
[this] { return m_drive.GetWheelSpeeds(); },
- frc2::PIDController{DriveConstants::kPDriveVel, 0, 0},
- frc2::PIDController{DriveConstants::kPDriveVel, 0, 0},
+ frc::PIDController{DriveConstants::kPDriveVel, 0, 0},
+ frc::PIDController{DriveConstants::kPDriveVel, 0, 0},
[this](auto left, auto right) { m_drive.TankDriveVolts(left, right); },
{&m_drive});
diff --git a/wpilibcExamples/src/main/cpp/examples/StateSpaceElevator/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/StateSpaceElevator/cpp/Robot.cpp
index 7decddd..3b83793 100644
--- a/wpilibcExamples/src/main/cpp/examples/StateSpaceElevator/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/StateSpaceElevator/cpp/Robot.cpp
@@ -50,8 +50,10 @@
// The observer fuses our encoder data and voltage inputs to reject noise.
frc::KalmanFilter<2, 1, 1> m_observer{
m_elevatorPlant,
- {0.0508, 0.5}, // How accurate we think our model is
- {0.001}, // How accurate we think our encoder position
+ {units::meter_t{2_in}.value(),
+ units::meters_per_second_t{40_in / 1_s}
+ .value()}, // How accurate we think our model is
+ {0.001}, // How accurate we think our encoder position
// data is. In this case we very highly trust our encoder position
// reading.
20_ms};
@@ -62,7 +64,8 @@
// qelms. State error tolerance, in meters and meters per second.
// Decrease this to more heavily penalize state excursion, or make the
// controller behave more aggressively.
- {0.0254, 0.254},
+ {units::meter_t{1_in}.value(),
+ units::meters_per_second_t{10_in / 1_s}.value()},
// relms. Control effort (voltage) tolerance. Decrease this to more
// heavily penalize control effort, or make the controller less
// aggressive. 12 is a good starting point because that is the
@@ -83,8 +86,7 @@
frc::PWMSparkMax m_motor{kMotorPort};
frc::XboxController m_joystick{kJoystickPort};
- frc::TrapezoidProfile<units::meters>::Constraints m_constraints{3_fps,
- 6_fps_sq};
+ frc::TrapezoidProfile<units::meters> m_profile{{3_fps, 6_fps_sq}};
frc::TrapezoidProfile<units::meters>::State m_lastProfiledReference;
@@ -115,9 +117,7 @@
goal = {kLoweredPosition, 0_fps};
}
m_lastProfiledReference =
- (frc::TrapezoidProfile<units::meters>(m_constraints, goal,
- m_lastProfiledReference))
- .Calculate(20_ms);
+ m_profile.Calculate(20_ms, goal, m_lastProfiledReference);
m_loop.SetNextR(frc::Vectord<2>{m_lastProfiledReference.position.value(),
m_lastProfiledReference.velocity.value()});
diff --git a/wpilibcExamples/src/main/cpp/examples/SwerveBot/cpp/Drivetrain.cpp b/wpilibcExamples/src/main/cpp/examples/SwerveBot/cpp/Drivetrain.cpp
index 537da53..03cc93b 100644
--- a/wpilibcExamples/src/main/cpp/examples/SwerveBot/cpp/Drivetrain.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/SwerveBot/cpp/Drivetrain.cpp
@@ -6,11 +6,14 @@
void Drivetrain::Drive(units::meters_per_second_t xSpeed,
units::meters_per_second_t ySpeed,
- units::radians_per_second_t rot, bool fieldRelative) {
- auto states = m_kinematics.ToSwerveModuleStates(
- fieldRelative ? frc::ChassisSpeeds::FromFieldRelativeSpeeds(
- xSpeed, ySpeed, rot, m_gyro.GetRotation2d())
- : frc::ChassisSpeeds{xSpeed, ySpeed, rot});
+ units::radians_per_second_t rot, bool fieldRelative,
+ units::second_t period) {
+ auto states =
+ m_kinematics.ToSwerveModuleStates(frc::ChassisSpeeds::Discretize(
+ fieldRelative ? frc::ChassisSpeeds::FromFieldRelativeSpeeds(
+ xSpeed, ySpeed, rot, m_gyro.GetRotation2d())
+ : frc::ChassisSpeeds{xSpeed, ySpeed, rot},
+ period));
m_kinematics.DesaturateWheelSpeeds(&states, kMaxSpeed);
diff --git a/wpilibcExamples/src/main/cpp/examples/SwerveBot/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/SwerveBot/cpp/Robot.cpp
index 39cfa14..b8edc6e 100644
--- a/wpilibcExamples/src/main/cpp/examples/SwerveBot/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/SwerveBot/cpp/Robot.cpp
@@ -50,7 +50,7 @@
frc::ApplyDeadband(m_controller.GetRightX(), 0.02)) *
Drivetrain::kMaxAngularSpeed;
- m_swerve.Drive(xSpeed, ySpeed, rot, fieldRelative);
+ m_swerve.Drive(xSpeed, ySpeed, rot, fieldRelative, GetPeriod());
}
};
diff --git a/wpilibcExamples/src/main/cpp/examples/SwerveBot/cpp/SwerveModule.cpp b/wpilibcExamples/src/main/cpp/examples/SwerveBot/cpp/SwerveModule.cpp
index 0f9e27e..380f8cb 100644
--- a/wpilibcExamples/src/main/cpp/examples/SwerveBot/cpp/SwerveModule.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/SwerveBot/cpp/SwerveModule.cpp
@@ -48,9 +48,17 @@
void SwerveModule::SetDesiredState(
const frc::SwerveModuleState& referenceState) {
+ frc::Rotation2d encoderRotation{
+ units::radian_t{m_turningEncoder.GetDistance()}};
+
// Optimize the reference state to avoid spinning further than 90 degrees
- const auto state = frc::SwerveModuleState::Optimize(
- referenceState, units::radian_t{m_turningEncoder.GetDistance()});
+ auto state =
+ frc::SwerveModuleState::Optimize(referenceState, encoderRotation);
+
+ // Scale speed by cosine of angle error. This scales down movement
+ // perpendicular to the desired direction of travel that can occur when
+ // modules change directions. This results in smoother driving.
+ state.speed *= (state.angle - encoderRotation).Cos();
// Calculate the drive output from the drive PID controller.
const auto driveOutput = m_drivePIDController.Calculate(
diff --git a/wpilibcExamples/src/main/cpp/examples/SwerveBot/include/Drivetrain.h b/wpilibcExamples/src/main/cpp/examples/SwerveBot/include/Drivetrain.h
index 87233d2..7f6f9cf 100644
--- a/wpilibcExamples/src/main/cpp/examples/SwerveBot/include/Drivetrain.h
+++ b/wpilibcExamples/src/main/cpp/examples/SwerveBot/include/Drivetrain.h
@@ -22,7 +22,7 @@
void Drive(units::meters_per_second_t xSpeed,
units::meters_per_second_t ySpeed, units::radians_per_second_t rot,
- bool fieldRelative);
+ bool fieldRelative, units::second_t period);
void UpdateOdometry();
static constexpr units::meters_per_second_t kMaxSpeed =
diff --git a/wpilibcExamples/src/main/cpp/examples/SwerveBot/include/SwerveModule.h b/wpilibcExamples/src/main/cpp/examples/SwerveBot/include/SwerveModule.h
index 1861498..3c2b2e4 100644
--- a/wpilibcExamples/src/main/cpp/examples/SwerveBot/include/SwerveModule.h
+++ b/wpilibcExamples/src/main/cpp/examples/SwerveBot/include/SwerveModule.h
@@ -42,7 +42,7 @@
frc::Encoder m_driveEncoder;
frc::Encoder m_turningEncoder;
- frc2::PIDController m_drivePIDController{1.0, 0, 0};
+ frc::PIDController m_drivePIDController{1.0, 0, 0};
frc::ProfiledPIDController<units::radians> m_turningPIDController{
1.0,
0.0,
diff --git a/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/cpp/RobotContainer.cpp b/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/cpp/RobotContainer.cpp
index 52b25b9..4bbbe0c 100644
--- a/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/cpp/RobotContainer.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/cpp/RobotContainer.cpp
@@ -35,9 +35,13 @@
m_drive.SetDefaultCommand(frc2::RunCommand(
[this] {
m_drive.Drive(
- units::meters_per_second_t{m_driverController.GetLeftY()},
- units::meters_per_second_t{m_driverController.GetLeftX()},
- units::radians_per_second_t{m_driverController.GetRightX()}, false);
+ // Multiply by max speed to map the joystick unitless inputs to
+ // actual units. This will map the [-1, 1] to [max speed backwards,
+ // max speed forwards], converting them to actual units.
+ m_driverController.GetLeftY() * AutoConstants::kMaxSpeed,
+ m_driverController.GetLeftX() * AutoConstants::kMaxSpeed,
+ m_driverController.GetRightX() * AutoConstants::kMaxAngularSpeed,
+ false);
},
{&m_drive}));
}
@@ -74,8 +78,8 @@
m_drive.kDriveKinematics,
- frc2::PIDController{AutoConstants::kPXController, 0, 0},
- frc2::PIDController{AutoConstants::kPYController, 0, 0}, thetaController,
+ frc::PIDController{AutoConstants::kPXController, 0, 0},
+ frc::PIDController{AutoConstants::kPYController, 0, 0}, thetaController,
[this](auto moduleStates) { m_drive.SetModuleStates(moduleStates); },
diff --git a/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/cpp/subsystems/DriveSubsystem.cpp b/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/cpp/subsystems/DriveSubsystem.cpp
index 4b60372..a6b810a 100644
--- a/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/cpp/subsystems/DriveSubsystem.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/cpp/subsystems/DriveSubsystem.cpp
@@ -51,12 +51,14 @@
void DriveSubsystem::Drive(units::meters_per_second_t xSpeed,
units::meters_per_second_t ySpeed,
- units::radians_per_second_t rot,
- bool fieldRelative) {
- auto states = kDriveKinematics.ToSwerveModuleStates(
- fieldRelative ? frc::ChassisSpeeds::FromFieldRelativeSpeeds(
- xSpeed, ySpeed, rot, m_gyro.GetRotation2d())
- : frc::ChassisSpeeds{xSpeed, ySpeed, rot});
+ units::radians_per_second_t rot, bool fieldRelative,
+ units::second_t period) {
+ auto states =
+ kDriveKinematics.ToSwerveModuleStates(frc::ChassisSpeeds::Discretize(
+ fieldRelative ? frc::ChassisSpeeds::FromFieldRelativeSpeeds(
+ xSpeed, ySpeed, rot, m_gyro.GetRotation2d())
+ : frc::ChassisSpeeds{xSpeed, ySpeed, rot},
+ period));
kDriveKinematics.DesaturateWheelSpeeds(&states, AutoConstants::kMaxSpeed);
diff --git a/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/cpp/subsystems/SwerveModule.cpp b/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/cpp/subsystems/SwerveModule.cpp
index bb0362e..dc1cdb0 100644
--- a/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/cpp/subsystems/SwerveModule.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/cpp/subsystems/SwerveModule.cpp
@@ -18,21 +18,25 @@
: m_driveMotor(driveMotorChannel),
m_turningMotor(turningMotorChannel),
m_driveEncoder(driveEncoderPorts[0], driveEncoderPorts[1]),
- m_turningEncoder(turningEncoderPorts[0], turningEncoderPorts[1]),
- m_reverseDriveEncoder(driveEncoderReversed),
- m_reverseTurningEncoder(turningEncoderReversed) {
+ m_turningEncoder(turningEncoderPorts[0], turningEncoderPorts[1]) {
// Set the distance per pulse for the drive encoder. We can simply use the
// distance traveled for one rotation of the wheel divided by the encoder
// resolution.
m_driveEncoder.SetDistancePerPulse(
ModuleConstants::kDriveEncoderDistancePerPulse);
+ // Set whether drive encoder should be reversed or not
+ m_driveEncoder.SetReverseDirection(driveEncoderReversed);
+
// Set the distance (in this case, angle) per pulse for the turning encoder.
// This is the the angle through an entire rotation (2 * std::numbers::pi)
// divided by the encoder resolution.
m_turningEncoder.SetDistancePerPulse(
ModuleConstants::kTurningEncoderDistancePerPulse);
+ // Set whether turning encoder should be reversed or not
+ m_turningEncoder.SetReverseDirection(turningEncoderReversed);
+
// Limit the PID Controller's input range between -pi and pi and set the input
// to be continuous.
m_turningPIDController.EnableContinuousInput(
@@ -51,9 +55,17 @@
void SwerveModule::SetDesiredState(
const frc::SwerveModuleState& referenceState) {
+ frc::Rotation2d encoderRotation{
+ units::radian_t{m_turningEncoder.GetDistance()}};
+
// Optimize the reference state to avoid spinning further than 90 degrees
- const auto state = frc::SwerveModuleState::Optimize(
- referenceState, units::radian_t{m_turningEncoder.GetDistance()});
+ auto state =
+ frc::SwerveModuleState::Optimize(referenceState, encoderRotation);
+
+ // Scale speed by cosine of angle error. This scales down movement
+ // perpendicular to the desired direction of travel that can occur when
+ // modules change directions. This results in smoother driving.
+ state.speed *= (state.angle - encoderRotation).Cos();
// Calculate the drive output from the drive PID controller.
const auto driveOutput = m_drivePIDController.Calculate(
diff --git a/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/include/Constants.h b/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/include/Constants.h
index cacab87..779927d 100644
--- a/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/include/Constants.h
+++ b/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/include/Constants.h
@@ -4,6 +4,7 @@
#include <numbers>
+#include <frc/TimedRobot.h>
#include <frc/geometry/Translation2d.h>
#include <frc/kinematics/SwerveDriveKinematics.h>
#include <frc/trajectory/TrapezoidProfile.h>
@@ -58,6 +59,10 @@
constexpr bool kFrontRightDriveEncoderReversed = false;
constexpr bool kRearRightDriveEncoderReversed = true;
+// If you call DriveSubsystem::Drive with a different period make sure to update
+// this.
+constexpr units::second_t kDrivePeriod = frc::TimedRobot::kDefaultPeriod;
+
// These are example values only - DO NOT USE THESE FOR YOUR OWN ROBOT!
// These characterization values MUST be determined either experimentally or
// theoretically for *your* robot's drive. The SysId tool provides a convenient
diff --git a/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/include/subsystems/DriveSubsystem.h b/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/include/subsystems/DriveSubsystem.h
index e9ed17b..b7b47fc 100644
--- a/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/include/subsystems/DriveSubsystem.h
+++ b/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/include/subsystems/DriveSubsystem.h
@@ -43,7 +43,8 @@
*/
void Drive(units::meters_per_second_t xSpeed,
units::meters_per_second_t ySpeed, units::radians_per_second_t rot,
- bool fieldRelative);
+ bool fieldRelative,
+ units::second_t period = DriveConstants::kDrivePeriod);
/**
* Resets the drive encoders to currently read a position of 0.
diff --git a/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/include/subsystems/SwerveModule.h b/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/include/subsystems/SwerveModule.h
index f0d5ede..8b9cfa3 100644
--- a/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/include/subsystems/SwerveModule.h
+++ b/wpilibcExamples/src/main/cpp/examples/SwerveControllerCommand/include/subsystems/SwerveModule.h
@@ -47,10 +47,7 @@
frc::Encoder m_driveEncoder;
frc::Encoder m_turningEncoder;
- bool m_reverseDriveEncoder;
- bool m_reverseTurningEncoder;
-
- frc2::PIDController m_drivePIDController{
+ frc::PIDController m_drivePIDController{
ModuleConstants::kPModuleDriveController, 0, 0};
frc::ProfiledPIDController<units::radians> m_turningPIDController{
ModuleConstants::kPModuleTurningController,
diff --git a/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/cpp/Drivetrain.cpp b/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/cpp/Drivetrain.cpp
index 5402e87..a365f7f 100644
--- a/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/cpp/Drivetrain.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/cpp/Drivetrain.cpp
@@ -10,11 +10,14 @@
void Drivetrain::Drive(units::meters_per_second_t xSpeed,
units::meters_per_second_t ySpeed,
- units::radians_per_second_t rot, bool fieldRelative) {
- auto states = m_kinematics.ToSwerveModuleStates(
- fieldRelative ? frc::ChassisSpeeds::FromFieldRelativeSpeeds(
- xSpeed, ySpeed, rot, m_gyro.GetRotation2d())
- : frc::ChassisSpeeds{xSpeed, ySpeed, rot});
+ units::radians_per_second_t rot, bool fieldRelative,
+ units::second_t period) {
+ auto states =
+ m_kinematics.ToSwerveModuleStates(frc::ChassisSpeeds::Discretize(
+ fieldRelative ? frc::ChassisSpeeds::FromFieldRelativeSpeeds(
+ xSpeed, ySpeed, rot, m_gyro.GetRotation2d())
+ : frc::ChassisSpeeds{xSpeed, ySpeed, rot},
+ period));
m_kinematics.DesaturateWheelSpeeds(&states, kMaxSpeed);
diff --git a/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/cpp/Robot.cpp
index 3f5f675..919dca6 100644
--- a/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/cpp/Robot.cpp
@@ -46,7 +46,7 @@
const auto rot = -m_rotLimiter.Calculate(m_controller.GetRightX()) *
Drivetrain::kMaxAngularSpeed;
- m_swerve.Drive(xSpeed, ySpeed, rot, fieldRelative);
+ m_swerve.Drive(xSpeed, ySpeed, rot, fieldRelative, GetPeriod());
}
};
diff --git a/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/cpp/SwerveModule.cpp b/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/cpp/SwerveModule.cpp
index c5a0839..2afaf55 100644
--- a/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/cpp/SwerveModule.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/cpp/SwerveModule.cpp
@@ -48,9 +48,17 @@
void SwerveModule::SetDesiredState(
const frc::SwerveModuleState& referenceState) {
+ frc::Rotation2d encoderRotation{
+ units::radian_t{m_turningEncoder.GetDistance()}};
+
// Optimize the reference state to avoid spinning further than 90 degrees
- const auto state = frc::SwerveModuleState::Optimize(
- referenceState, units::radian_t{m_turningEncoder.GetDistance()});
+ auto state =
+ frc::SwerveModuleState::Optimize(referenceState, encoderRotation);
+
+ // Scale speed by cosine of angle error. This scales down movement
+ // perpendicular to the desired direction of travel that can occur when
+ // modules change directions. This results in smoother driving.
+ state.speed *= (state.angle - encoderRotation).Cos();
// Calculate the drive output from the drive PID controller.
const auto driveOutput = m_drivePIDController.Calculate(
diff --git a/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/include/Drivetrain.h b/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/include/Drivetrain.h
index e042291..e71dc43 100644
--- a/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/include/Drivetrain.h
+++ b/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/include/Drivetrain.h
@@ -23,7 +23,7 @@
void Drive(units::meters_per_second_t xSpeed,
units::meters_per_second_t ySpeed, units::radians_per_second_t rot,
- bool fieldRelative);
+ bool fieldRelative, units::second_t period);
void UpdateOdometry();
static constexpr auto kMaxSpeed = 3.0_mps; // 3 meters per second
diff --git a/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/include/SwerveModule.h b/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/include/SwerveModule.h
index 049d507..a4adb2d 100644
--- a/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/include/SwerveModule.h
+++ b/wpilibcExamples/src/main/cpp/examples/SwerveDrivePoseEstimator/include/SwerveModule.h
@@ -42,7 +42,7 @@
frc::Encoder m_driveEncoder;
frc::Encoder m_turningEncoder;
- frc2::PIDController m_drivePIDController{1.0, 0, 0};
+ frc::PIDController m_drivePIDController{1.0, 0, 0};
frc::ProfiledPIDController<units::radians> m_turningPIDController{
1.0,
0.0,
diff --git a/wpilibcExamples/src/main/cpp/examples/Ultrasonic/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/Ultrasonic/cpp/Robot.cpp
index e8f805d..ac47856 100644
--- a/wpilibcExamples/src/main/cpp/examples/Ultrasonic/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/Ultrasonic/cpp/Robot.cpp
@@ -2,57 +2,54 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
-#include <frc/AnalogInput.h>
-#include <frc/TimedRobot.h>
-#include <frc/drive/DifferentialDrive.h>
-#include <frc/filter/MedianFilter.h>
-#include <frc/motorcontrol/PWMSparkMax.h>
+#include "Robot.h"
-/**
- * This is a sample program demonstrating how to use an ultrasonic sensor and
- * proportional control to maintain a set distance from an object.
- */
-class Robot : public frc::TimedRobot {
- public:
- /**
- * Tells the robot to drive to a set distance (in inches) from an object using
- * proportional control.
- */
- void TeleopPeriodic() override {
- // Sensor returns a value from 0-4095 that is scaled to inches
- // returned value is filtered with a rolling median filter, since
- // ultrasonics tend to be quite noisy and susceptible to sudden outliers
- double currentDistance =
- m_filter.Calculate(m_ultrasonic.GetVoltage()) * kValueToInches;
- // Convert distance error to a motor speed
- double currentSpeed = (kHoldDistance - currentDistance) * kP;
- // Drive robot
- m_robotDrive.ArcadeDrive(currentSpeed, 0);
+#include <frc/shuffleboard/Shuffleboard.h>
+#include <frc/smartdashboard/SmartDashboard.h>
+#include <units/length.h>
+
+void Robot::RobotInit() {
+ // Add the ultrasonic on the "Sensors" tab of the dashboard
+ // Data will update automatically
+ frc::Shuffleboard::GetTab("Sensors").Add(m_rangeFinder);
+}
+
+void Robot::TeleopPeriodic() {
+ // We can read the distance
+ units::meter_t distance = m_rangeFinder.GetRange();
+ // units auto-convert
+ units::millimeter_t distanceMillimeters = distance;
+ units::inch_t distanceInches = distance;
+
+ // We can also publish the data itself periodically
+ frc::SmartDashboard::PutNumber("Distance[mm]", distanceMillimeters.value());
+ frc::SmartDashboard::PutNumber("Distance[inch]", distanceInches.value());
+}
+
+void Robot::TestInit() {
+ // By default, the Ultrasonic class polls all ultrasonic sensors in a
+ // round-robin to prevent them from interfering from one another. However,
+ // manual polling is also possible -- note that this disables automatic mode!
+ m_rangeFinder.Ping();
+}
+
+void Robot::TestPeriodic() {
+ if (m_rangeFinder.IsRangeValid()) {
+ // Data is valid, publish it
+ units::millimeter_t distanceMillimeters = m_rangeFinder.GetRange();
+ units::inch_t distanceInches = m_rangeFinder.GetRange();
+ frc::SmartDashboard::PutNumber("Distance[mm]", distanceMillimeters.value());
+ frc::SmartDashboard::PutNumber("Distance[inch]", distanceInches.value());
+
+ // Ping for next measurement
+ m_rangeFinder.Ping();
}
+}
- private:
- // Distance in inches the robot wants to stay from an object
- static constexpr int kHoldDistance = 12;
-
- // Factor to convert sensor values to a distance in inches
- static constexpr double kValueToInches = 0.125;
-
- // Proportional speed constant
- static constexpr double kP = 0.05;
-
- static constexpr int kLeftMotorPort = 0;
- static constexpr int kRightMotorPort = 1;
- static constexpr int kUltrasonicPort = 0;
-
- // median filter to discard outliers; filters over 10 samples
- frc::MedianFilter<double> m_filter{10};
-
- frc::AnalogInput m_ultrasonic{kUltrasonicPort};
-
- frc::PWMSparkMax m_left{kLeftMotorPort};
- frc::PWMSparkMax m_right{kRightMotorPort};
- frc::DifferentialDrive m_robotDrive{m_left, m_right};
-};
+void Robot::TestExit() {
+ // Enable automatic mode
+ frc::Ultrasonic::SetAutomaticMode(true);
+}
#ifndef RUNNING_FRC_TESTS
int main() {
diff --git a/wpilibcExamples/src/main/cpp/examples/Ultrasonic/include/Robot.h b/wpilibcExamples/src/main/cpp/examples/Ultrasonic/include/Robot.h
new file mode 100644
index 0000000..2da0c6f
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/Ultrasonic/include/Robot.h
@@ -0,0 +1,25 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <frc/TimedRobot.h>
+#include <frc/Ultrasonic.h>
+
+/**
+ * This is a sample program demonstrating how to read from a ping-response
+ * ultrasonic sensor with the {@link Ultrasonic class}.
+ */
+class Robot : public frc::TimedRobot {
+ public:
+ void RobotInit() override;
+ void TeleopPeriodic() override;
+ void TestInit() override;
+ void TestPeriodic() override;
+ void TestExit() override;
+
+ private:
+ // Creates a ping-response Ultrasonic object on DIO 1 and 2.
+ frc::Ultrasonic m_rangeFinder{1, 2};
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/UltrasonicPID/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/UltrasonicPID/cpp/Robot.cpp
index 62d4106..9d2b5c2 100644
--- a/wpilibcExamples/src/main/cpp/examples/UltrasonicPID/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/UltrasonicPID/cpp/Robot.cpp
@@ -2,65 +2,21 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
-#include <frc/AnalogInput.h>
-#include <frc/TimedRobot.h>
-#include <frc/controller/PIDController.h>
-#include <frc/drive/DifferentialDrive.h>
-#include <frc/filter/MedianFilter.h>
-#include <frc/motorcontrol/PWMSparkMax.h>
+#include "Robot.h"
-/**
- * This is a sample program demonstrating how to use an ultrasonic sensor and
- * proportional control to maintain a set distance from an object.
- */
-class Robot : public frc::TimedRobot {
- public:
- /**
- * Drives the robot a set distance from an object using PID control and the
- * ultrasonic sensor.
- */
- void TeleopInit() override {
- // Set setpoint of the PID Controller
- m_pidController.SetSetpoint(kHoldDistance * kValueToInches);
- }
+void Robot::AutonomousInit() {
+ // Set setpoint of the pid controller
+ m_pidController.SetSetpoint(kHoldDistance.value());
+}
- void TeleopPeriodic() override {
- double output =
- m_pidController.Calculate(m_filter.Calculate(m_ultrasonic.GetValue()));
- m_robotDrive.ArcadeDrive(output, 0);
- }
+void Robot::AutonomousPeriodic() {
+ units::millimeter_t measurement = m_ultrasonic.GetRange();
+ units::millimeter_t filteredMeasurement = m_filter.Calculate(measurement);
+ double pidOutput = m_pidController.Calculate(filteredMeasurement.value());
- private:
- // Distance in inches the robot wants to stay from an object
- static constexpr int kHoldDistance = 12;
-
- // Factor to convert sensor values to a distance in inches
- static constexpr double kValueToInches = 0.125;
-
- // proportional speed constant
- static constexpr double kP = 7.0;
-
- // integral speed constant
- static constexpr double kI = 0.018;
-
- // derivative speed constant
- static constexpr double kD = 1.5;
-
- static constexpr int kLeftMotorPort = 0;
- static constexpr int kRightMotorPort = 1;
- static constexpr int kUltrasonicPort = 0;
-
- // median filter to discard outliers; filters over 5 samples
- frc::MedianFilter<double> m_filter{5};
-
- frc::AnalogInput m_ultrasonic{kUltrasonicPort};
-
- frc::PWMSparkMax m_left{kLeftMotorPort};
- frc::PWMSparkMax m_right{kRightMotorPort};
- frc::DifferentialDrive m_robotDrive{m_left, m_right};
-
- frc2::PIDController m_pidController{kP, kI, kD};
-};
+ // disable input squaring -- PID output is linear
+ m_robotDrive.ArcadeDrive(pidOutput, 0, false);
+}
#ifndef RUNNING_FRC_TESTS
int main() {
diff --git a/wpilibcExamples/src/main/cpp/examples/UltrasonicPID/include/Robot.h b/wpilibcExamples/src/main/cpp/examples/UltrasonicPID/include/Robot.h
new file mode 100644
index 0000000..4ff2700
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/UltrasonicPID/include/Robot.h
@@ -0,0 +1,51 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <frc/TimedRobot.h>
+#include <frc/Ultrasonic.h>
+#include <frc/controller/PIDController.h>
+#include <frc/drive/DifferentialDrive.h>
+#include <frc/filter/MedianFilter.h>
+#include <frc/motorcontrol/PWMSparkMax.h>
+#include <units/length.h>
+
+/**
+ * This is a sample program to demonstrate the use of a PIDController with an
+ * ultrasonic sensor to reach and maintain a set distance from an object.
+ */
+class Robot : public frc::TimedRobot {
+ public:
+ void AutonomousInit() override;
+ void AutonomousPeriodic() override;
+
+ // distance the robot wants to stay from an object
+ static constexpr units::millimeter_t kHoldDistance = 1_m;
+
+ static constexpr int kLeftMotorPort = 0;
+ static constexpr int kRightMotorPort = 1;
+ static constexpr int kUltrasonicPingPort = 0;
+ static constexpr int kUltrasonicEchoPort = 1;
+
+ private:
+ // proportional speed constant
+ // negative because applying positive voltage will bring us closer to the
+ // target
+ static constexpr double kP = -0.001;
+ // integral speed constant
+ static constexpr double kI = 0.0;
+ // derivative speed constant
+ static constexpr double kD = 0.0;
+
+ // Ultrasonic sensors tend to be quite noisy and susceptible to sudden
+ // outliers, so measurements are filtered with a 5-sample median filter
+ frc::MedianFilter<units::millimeter_t> m_filter{5};
+
+ frc::Ultrasonic m_ultrasonic{kUltrasonicPingPort, kUltrasonicEchoPort};
+ frc::PWMSparkMax m_left{kLeftMotorPort};
+ frc::PWMSparkMax m_right{kRightMotorPort};
+ frc::DifferentialDrive m_robotDrive{m_left, m_right};
+ frc::PIDController m_pidController{kP, kI, kD};
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/SchedulerEventLogging/cpp/Robot.cpp b/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/Robot.cpp
similarity index 97%
rename from wpilibcExamples/src/main/cpp/examples/SchedulerEventLogging/cpp/Robot.cpp
rename to wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/Robot.cpp
index c7eab48..e39a8fd 100644
--- a/wpilibcExamples/src/main/cpp/examples/SchedulerEventLogging/cpp/Robot.cpp
+++ b/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/Robot.cpp
@@ -4,7 +4,6 @@
#include "Robot.h"
-#include <frc/smartdashboard/SmartDashboard.h>
#include <frc2/command/CommandScheduler.h>
void Robot::RobotInit() {}
diff --git a/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/RobotContainer.cpp b/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/RobotContainer.cpp
new file mode 100644
index 0000000..2b6cfa2
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/RobotContainer.cpp
@@ -0,0 +1,44 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "RobotContainer.h"
+
+#include <frc/smartdashboard/SmartDashboard.h>
+#include <frc2/command/Commands.h>
+#include <frc2/command/button/JoystickButton.h>
+
+#include "commands/TeleopArcadeDrive.h"
+
+RobotContainer::RobotContainer() {
+ // Configure the button bindings
+ ConfigureButtonBindings();
+}
+
+void RobotContainer::ConfigureButtonBindings() {
+ // Also set default commands here
+ m_drive.SetDefaultCommand(TeleopArcadeDrive(
+ &m_drive, [this] { return -m_controller.GetRawAxis(1); },
+ [this] { return -m_controller.GetRawAxis(2); }));
+
+ // Example of how to use the onboard IO
+ m_userButton.OnTrue(frc2::cmd::Print("USER Button Pressed"))
+ .OnFalse(frc2::cmd::Print("USER Button Released"));
+
+ frc2::JoystickButton(&m_controller, 1)
+ .OnTrue(frc2::cmd::RunOnce([this] { m_arm.SetAngle(45.0); }, {}))
+ .OnFalse(frc2::cmd::RunOnce([this] { m_arm.SetAngle(0.0); }, {}));
+
+ frc2::JoystickButton(&m_controller, 2)
+ .OnTrue(frc2::cmd::RunOnce([this] { m_arm.SetAngle(90.0); }, {}))
+ .OnFalse(frc2::cmd::RunOnce([this] { m_arm.SetAngle(0.0); }, {}));
+
+ // Setup SmartDashboard options.
+ m_chooser.SetDefaultOption("Auto Routine Distance", &m_autoDistance);
+ m_chooser.AddOption("Auto Routine Time", &m_autoTime);
+ frc::SmartDashboard::PutData("Auto Selector", &m_chooser);
+}
+
+frc2::Command* RobotContainer::GetAutonomousCommand() {
+ return m_chooser.GetSelected();
+}
diff --git a/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/commands/DriveDistance.cpp b/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/commands/DriveDistance.cpp
new file mode 100644
index 0000000..dcb59e3
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/commands/DriveDistance.cpp
@@ -0,0 +1,24 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "commands/DriveDistance.h"
+
+#include <units/math.h>
+
+void DriveDistance::Initialize() {
+ m_drive->ArcadeDrive(0, 0);
+ m_drive->ResetEncoders();
+}
+
+void DriveDistance::Execute() {
+ m_drive->ArcadeDrive(m_speed, 0);
+}
+
+void DriveDistance::End(bool interrupted) {
+ m_drive->ArcadeDrive(0, 0);
+}
+
+bool DriveDistance::IsFinished() {
+ return units::math::abs(m_drive->GetAverageDistance()) >= m_distance;
+}
diff --git a/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/commands/DriveTime.cpp b/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/commands/DriveTime.cpp
new file mode 100644
index 0000000..52670a0
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/commands/DriveTime.cpp
@@ -0,0 +1,24 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "commands/DriveTime.h"
+
+void DriveTime::Initialize() {
+ m_timer.Start();
+ m_drive->ArcadeDrive(0, 0);
+}
+
+void DriveTime::Execute() {
+ m_drive->ArcadeDrive(m_speed, 0);
+}
+
+void DriveTime::End(bool interrupted) {
+ m_drive->ArcadeDrive(0, 0);
+ m_timer.Stop();
+ m_timer.Reset();
+}
+
+bool DriveTime::IsFinished() {
+ return m_timer.HasElapsed(m_duration);
+}
diff --git a/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/commands/TeleopArcadeDrive.cpp b/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/commands/TeleopArcadeDrive.cpp
new file mode 100644
index 0000000..e457af9
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/commands/TeleopArcadeDrive.cpp
@@ -0,0 +1,20 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "commands/TeleopArcadeDrive.h"
+
+#include "subsystems/Drivetrain.h"
+
+TeleopArcadeDrive::TeleopArcadeDrive(
+ Drivetrain* subsystem, std::function<double()> xaxisSpeedSupplier,
+ std::function<double()> zaxisRotateSuppplier)
+ : m_drive{subsystem},
+ m_xaxisSpeedSupplier{xaxisSpeedSupplier},
+ m_zaxisRotateSupplier{zaxisRotateSuppplier} {
+ AddRequirements(subsystem);
+}
+
+void TeleopArcadeDrive::Execute() {
+ m_drive->ArcadeDrive(m_xaxisSpeedSupplier(), m_zaxisRotateSupplier());
+}
diff --git a/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/commands/TurnDegrees.cpp b/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/commands/TurnDegrees.cpp
new file mode 100644
index 0000000..65fd255
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/commands/TurnDegrees.cpp
@@ -0,0 +1,40 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "commands/TurnDegrees.h"
+
+#include <numbers>
+
+#include <units/math.h>
+
+void TurnDegrees::Initialize() {
+ // Set motors to stop, read encoder values for starting point
+ m_drive->ArcadeDrive(0, 0);
+ m_drive->ResetEncoders();
+}
+
+void TurnDegrees::Execute() {
+ m_drive->ArcadeDrive(0, m_speed);
+}
+
+void TurnDegrees::End(bool interrupted) {
+ m_drive->ArcadeDrive(0, 0);
+}
+
+bool TurnDegrees::IsFinished() {
+ // Need to convert distance travelled to degrees. The Standard XRP Chassis
+ // found here https://www.sparkfun.com/products/22230, has a
+ // wheel placement diameter (163 mm) - width of the wheel (8 mm) = 155 mm
+ // or 6.102 inches. We then take into consideration the width of the tires.
+ static auto inchPerDegree = (6.102_in * std::numbers::pi) / 360_deg;
+
+ // Compare distance traveled from start to distance based on degree turn.
+ return GetAverageTurningDistance() >= inchPerDegree * m_angle;
+}
+
+units::meter_t TurnDegrees::GetAverageTurningDistance() {
+ auto l = units::math::abs(m_drive->GetLeftDistance());
+ auto r = units::math::abs(m_drive->GetRightDistance());
+ return (l + r) / 2;
+}
diff --git a/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/commands/TurnTime.cpp b/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/commands/TurnTime.cpp
new file mode 100644
index 0000000..80c4bd2
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/commands/TurnTime.cpp
@@ -0,0 +1,24 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "commands/TurnTime.h"
+
+void TurnTime::Initialize() {
+ m_timer.Start();
+ m_drive->ArcadeDrive(0, 0);
+}
+
+void TurnTime::Execute() {
+ m_drive->ArcadeDrive(0, m_speed);
+}
+
+void TurnTime::End(bool interrupted) {
+ m_drive->ArcadeDrive(0, 0);
+ m_timer.Stop();
+ m_timer.Reset();
+}
+
+bool TurnTime::IsFinished() {
+ return m_timer.HasElapsed(m_duration);
+}
diff --git a/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/subsystems/Arm.cpp b/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/subsystems/Arm.cpp
new file mode 100644
index 0000000..cf75e52
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/subsystems/Arm.cpp
@@ -0,0 +1,13 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "subsystems/Arm.h"
+
+void Arm::Periodic() {
+ // This method will be called once per scheduler run.
+}
+
+void Arm::SetAngle(double angleDeg) {
+ m_armServo.SetAngle(angleDeg);
+}
diff --git a/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/subsystems/Drivetrain.cpp b/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/subsystems/Drivetrain.cpp
new file mode 100644
index 0000000..bcec018
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/XRPReference/cpp/subsystems/Drivetrain.cpp
@@ -0,0 +1,89 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#include "subsystems/Drivetrain.h"
+
+#include <numbers>
+
+#include "Constants.h"
+
+using namespace DriveConstants;
+
+// The XRP has the left and right motors set to
+// PWM channels 0 and 1 respectively
+// The XRP has onboard encoders that are hardcoded
+// to use DIO pins 4/5 and 6/7 for the left and right
+Drivetrain::Drivetrain() {
+ // We need to invert one side of the drivetrain so that positive voltages
+ // result in both sides moving forward. Depending on how your robot's
+ // gearbox is constructed, you might have to invert the left side instead.
+ m_rightMotor.SetInverted(true);
+
+ m_leftEncoder.SetDistancePerPulse(std::numbers::pi * kWheelDiameter.value() /
+ kCountsPerRevolution);
+ m_rightEncoder.SetDistancePerPulse(std::numbers::pi * kWheelDiameter.value() /
+ kCountsPerRevolution);
+ ResetEncoders();
+}
+
+void Drivetrain::Periodic() {
+ // This method will be called once per scheduler run.
+}
+
+void Drivetrain::ArcadeDrive(double xaxisSpeed, double zaxisRotate) {
+ m_drive.ArcadeDrive(xaxisSpeed, zaxisRotate);
+}
+
+void Drivetrain::ResetEncoders() {
+ m_leftEncoder.Reset();
+ m_rightEncoder.Reset();
+}
+
+int Drivetrain::GetLeftEncoderCount() {
+ return m_leftEncoder.Get();
+}
+
+int Drivetrain::GetRightEncoderCount() {
+ return m_rightEncoder.Get();
+}
+
+units::meter_t Drivetrain::GetLeftDistance() {
+ return units::meter_t{m_leftEncoder.GetDistance()};
+}
+
+units::meter_t Drivetrain::GetRightDistance() {
+ return units::meter_t{m_rightEncoder.GetDistance()};
+}
+
+units::meter_t Drivetrain::GetAverageDistance() {
+ return (GetLeftDistance() + GetRightDistance()) / 2.0;
+}
+
+double Drivetrain::GetAccelX() {
+ return m_accelerometer.GetX();
+}
+
+double Drivetrain::GetAccelY() {
+ return m_accelerometer.GetY();
+}
+
+double Drivetrain::GetAccelZ() {
+ return m_accelerometer.GetZ();
+}
+
+double Drivetrain::GetGyroAngleX() {
+ return m_gyro.GetAngleX();
+}
+
+double Drivetrain::GetGyroAngleY() {
+ return m_gyro.GetAngleY();
+}
+
+double Drivetrain::GetGyroAngleZ() {
+ return m_gyro.GetAngleZ();
+}
+
+void Drivetrain::ResetGyro() {
+ m_gyro.Reset();
+}
diff --git a/wpilibcExamples/src/main/cpp/examples/SchedulerEventLogging/include/Constants.h b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/Constants.h
similarity index 67%
rename from wpilibcExamples/src/main/cpp/examples/SchedulerEventLogging/include/Constants.h
rename to wpilibcExamples/src/main/cpp/examples/XRPReference/include/Constants.h
index ae5d02d..e5cee33 100644
--- a/wpilibcExamples/src/main/cpp/examples/SchedulerEventLogging/include/Constants.h
+++ b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/Constants.h
@@ -6,14 +6,14 @@
/**
* The Constants header provides a convenient place for teams to hold robot-wide
- * numerical or boolean constants. This should not be used for any other
- * purpose.
+ * numerical or bool constants. This should not be used for any other purpose.
*
* It is generally a good idea to place constants into subsystem- or
* command-specific namespaces within this header, which can then be used where
* they are needed.
*/
-namespace OIConstants {
-constexpr int kDriverControllerPort = 0;
-} // namespace OIConstants
+namespace DriveConstants {
+constexpr double kCountsPerRevolution = 1440.0;
+constexpr double kWheelDiameterInch = 2.75;
+} // namespace DriveConstants
diff --git a/wpilibcExamples/src/main/cpp/examples/SchedulerEventLogging/include/Robot.h b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/Robot.h
similarity index 99%
rename from wpilibcExamples/src/main/cpp/examples/SchedulerEventLogging/include/Robot.h
rename to wpilibcExamples/src/main/cpp/examples/XRPReference/include/Robot.h
index a82f2ac..eb35fab 100644
--- a/wpilibcExamples/src/main/cpp/examples/SchedulerEventLogging/include/Robot.h
+++ b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/Robot.h
@@ -25,6 +25,5 @@
// Have it null by default so that if testing teleop it
// doesn't have undefined behavior and potentially crash.
frc2::Command* m_autonomousCommand = nullptr;
-
RobotContainer m_container;
};
diff --git a/wpilibcExamples/src/main/cpp/examples/XRPReference/include/RobotContainer.h b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/RobotContainer.h
new file mode 100644
index 0000000..51ea812
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/RobotContainer.h
@@ -0,0 +1,63 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <frc/Joystick.h>
+#include <frc/smartdashboard/SendableChooser.h>
+#include <frc/xrp/XRPOnBoardIO.h>
+#include <frc2/command/Command.h>
+#include <frc2/command/CommandPtr.h>
+#include <frc2/command/button/Trigger.h>
+
+#include "Constants.h"
+#include "commands/AutonomousDistance.h"
+#include "commands/AutonomousTime.h"
+#include "subsystems/Arm.h"
+#include "subsystems/Drivetrain.h"
+
+/**
+ * This class is where the bulk of the robot should be declared. Since
+ * Command-based is a "declarative" paradigm, very little robot logic should
+ * actually be handled in the {@link Robot} periodic methods (other than the
+ * scheduler calls). Instead, the structure of the robot (including subsystems,
+ * commands, and button mappings) should be declared here.
+ */
+class RobotContainer {
+ // NOTE: The I/O pin functionality of the 5 exposed I/O pins depends on the
+ // hardware "overlay"
+ // that is specified when launching the wpilib-ws server on the Romi raspberry
+ // pi. By default, the following are available (listed in order from inside of
+ // the board to outside):
+ // - DIO 8 (mapped to Arduino pin 11, closest to the inside of the board)
+ // - Analog In 0 (mapped to Analog Channel 6 / Arduino Pin 4)
+ // - Analog In 1 (mapped to Analog Channel 2 / Arduino Pin 20)
+ // - PWM 2 (mapped to Arduino Pin 21)
+ // - PWM 3 (mapped to Arduino Pin 22)
+ //
+ // Your subsystem configuration should take the overlays into account
+ public:
+ RobotContainer();
+ frc2::Command* GetAutonomousCommand();
+
+ private:
+ // Assumes a gamepad plugged into channel 0
+ frc::Joystick m_controller{0};
+ frc::SendableChooser<frc2::Command*> m_chooser;
+
+ // The robot's subsystems
+ Drivetrain m_drive;
+ Arm m_arm;
+ frc::XRPOnBoardIO m_onboardIO;
+
+ // Example button
+ frc2::Trigger m_userButton{
+ [this] { return m_onboardIO.GetUserButtonPressed(); }};
+
+ // Autonomous commands.
+ AutonomousDistance m_autoDistance{&m_drive};
+ AutonomousTime m_autoTime{&m_drive};
+
+ void ConfigureButtonBindings();
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/XRPReference/include/commands/AutonomousDistance.h b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/commands/AutonomousDistance.h
new file mode 100644
index 0000000..8991ce6
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/commands/AutonomousDistance.h
@@ -0,0 +1,23 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <frc2/command/CommandHelper.h>
+#include <frc2/command/SequentialCommandGroup.h>
+
+#include "commands/DriveDistance.h"
+#include "commands/TurnDegrees.h"
+#include "subsystems/Drivetrain.h"
+
+class AutonomousDistance
+ : public frc2::CommandHelper<frc2::SequentialCommandGroup,
+ AutonomousDistance> {
+ public:
+ explicit AutonomousDistance(Drivetrain* drive) {
+ AddCommands(
+ DriveDistance(-0.5, 10_in, drive), TurnDegrees(-0.5, 180_deg, drive),
+ DriveDistance(-0.5, 10_in, drive), TurnDegrees(0.5, 180_deg, drive));
+ }
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/XRPReference/include/commands/AutonomousTime.h b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/commands/AutonomousTime.h
new file mode 100644
index 0000000..e25e5ea
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/commands/AutonomousTime.h
@@ -0,0 +1,21 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <frc2/command/CommandHelper.h>
+#include <frc2/command/SequentialCommandGroup.h>
+
+#include "commands/DriveTime.h"
+#include "commands/TurnTime.h"
+#include "subsystems/Drivetrain.h"
+
+class AutonomousTime
+ : public frc2::CommandHelper<frc2::SequentialCommandGroup, AutonomousTime> {
+ public:
+ explicit AutonomousTime(Drivetrain* drive) {
+ AddCommands(DriveTime(-0.6, 2_s, drive), TurnTime(-0.5, 1.3_s, drive),
+ DriveTime(-0.6, 2_s, drive), TurnTime(0.5, 1.3_s, drive));
+ }
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/XRPReference/include/commands/DriveDistance.h b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/commands/DriveDistance.h
new file mode 100644
index 0000000..6011531
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/commands/DriveDistance.h
@@ -0,0 +1,29 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <frc2/command/Command.h>
+#include <frc2/command/CommandHelper.h>
+#include <units/length.h>
+
+#include "subsystems/Drivetrain.h"
+
+class DriveDistance : public frc2::CommandHelper<frc2::Command, DriveDistance> {
+ public:
+ DriveDistance(double speed, units::meter_t distance, Drivetrain* drive)
+ : m_speed(speed), m_distance(distance), m_drive(drive) {
+ AddRequirements(m_drive);
+ }
+
+ void Initialize() override;
+ void Execute() override;
+ void End(bool interrupted) override;
+ bool IsFinished() override;
+
+ private:
+ double m_speed;
+ units::meter_t m_distance;
+ Drivetrain* m_drive;
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/XRPReference/include/commands/DriveTime.h b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/commands/DriveTime.h
new file mode 100644
index 0000000..9dfd240
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/commands/DriveTime.h
@@ -0,0 +1,31 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <frc/Timer.h>
+#include <frc2/command/Command.h>
+#include <frc2/command/CommandHelper.h>
+#include <units/time.h>
+
+#include "subsystems/Drivetrain.h"
+
+class DriveTime : public frc2::CommandHelper<frc2::Command, DriveTime> {
+ public:
+ DriveTime(double speed, units::second_t time, Drivetrain* drive)
+ : m_speed(speed), m_duration(time), m_drive(drive) {
+ AddRequirements(m_drive);
+ }
+
+ void Initialize() override;
+ void Execute() override;
+ void End(bool interrupted) override;
+ bool IsFinished() override;
+
+ private:
+ double m_speed;
+ units::second_t m_duration;
+ Drivetrain* m_drive;
+ frc::Timer m_timer;
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/XRPReference/include/commands/TeleopArcadeDrive.h b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/commands/TeleopArcadeDrive.h
new file mode 100644
index 0000000..fe2e241
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/commands/TeleopArcadeDrive.h
@@ -0,0 +1,26 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <functional>
+
+#include <frc2/command/Command.h>
+#include <frc2/command/CommandHelper.h>
+
+#include "subsystems/Drivetrain.h"
+
+class TeleopArcadeDrive
+ : public frc2::CommandHelper<frc2::Command, TeleopArcadeDrive> {
+ public:
+ TeleopArcadeDrive(Drivetrain* subsystem,
+ std::function<double()> xaxisSpeedSupplier,
+ std::function<double()> zaxisRotateSupplier);
+ void Execute() override;
+
+ private:
+ Drivetrain* m_drive;
+ std::function<double()> m_xaxisSpeedSupplier;
+ std::function<double()> m_zaxisRotateSupplier;
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/XRPReference/include/commands/TurnDegrees.h b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/commands/TurnDegrees.h
new file mode 100644
index 0000000..c0f25b1
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/commands/TurnDegrees.h
@@ -0,0 +1,32 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <frc2/command/Command.h>
+#include <frc2/command/CommandHelper.h>
+#include <units/angle.h>
+#include <units/length.h>
+
+#include "subsystems/Drivetrain.h"
+
+class TurnDegrees : public frc2::CommandHelper<frc2::Command, TurnDegrees> {
+ public:
+ TurnDegrees(double speed, units::degree_t angle, Drivetrain* drive)
+ : m_speed(speed), m_angle(angle), m_drive(drive) {
+ AddRequirements(m_drive);
+ }
+
+ void Initialize() override;
+ void Execute() override;
+ void End(bool interrupted) override;
+ bool IsFinished() override;
+
+ private:
+ double m_speed;
+ units::degree_t m_angle;
+ Drivetrain* m_drive;
+
+ units::meter_t GetAverageTurningDistance();
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/XRPReference/include/commands/TurnTime.h b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/commands/TurnTime.h
new file mode 100644
index 0000000..3c478a8
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/commands/TurnTime.h
@@ -0,0 +1,31 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <frc/Timer.h>
+#include <frc2/command/Command.h>
+#include <frc2/command/CommandHelper.h>
+#include <units/time.h>
+
+#include "subsystems/Drivetrain.h"
+
+class TurnTime : public frc2::CommandHelper<frc2::Command, TurnTime> {
+ public:
+ TurnTime(double speed, units::second_t time, Drivetrain* drive)
+ : m_speed(speed), m_duration(time), m_drive(drive) {
+ AddRequirements(m_drive);
+ }
+
+ void Initialize() override;
+ void Execute() override;
+ void End(bool interrupted) override;
+ bool IsFinished() override;
+
+ private:
+ double m_speed;
+ units::second_t m_duration;
+ Drivetrain* m_drive;
+ frc::Timer m_timer;
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/XRPReference/include/subsystems/Arm.h b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/subsystems/Arm.h
new file mode 100644
index 0000000..aacb7c6
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/subsystems/Arm.h
@@ -0,0 +1,26 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <frc/xrp/XRPServo.h>
+#include <frc2/command/SubsystemBase.h>
+
+class Arm : public frc2::SubsystemBase {
+ public:
+ /**
+ * Will be called periodically whenever the CommandScheduler runs.
+ */
+ void Periodic() override;
+
+ /**
+ * Set the current angle of the arm (0 - 180 degrees).
+ *
+ * @param angleDeg the commanded angle
+ */
+ void SetAngle(double angleDeg);
+
+ private:
+ frc::XRPServo m_armServo{4};
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/XRPReference/include/subsystems/Drivetrain.h b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/subsystems/Drivetrain.h
new file mode 100644
index 0000000..e665601
--- /dev/null
+++ b/wpilibcExamples/src/main/cpp/examples/XRPReference/include/subsystems/Drivetrain.h
@@ -0,0 +1,125 @@
+// Copyright (c) FIRST and other WPILib contributors.
+// Open Source Software; you can modify and/or share it under the terms of
+// the WPILib BSD license file in the root directory of this project.
+
+#pragma once
+
+#include <frc/BuiltInAccelerometer.h>
+#include <frc/Encoder.h>
+#include <frc/drive/DifferentialDrive.h>
+#include <frc/xrp/XRPGyro.h>
+#include <frc/xrp/XRPMotor.h>
+#include <frc2/command/SubsystemBase.h>
+#include <units/length.h>
+
+class Drivetrain : public frc2::SubsystemBase {
+ public:
+ static constexpr double kGearRatio =
+ (30.0 / 14.0) * (28.0 / 16.0) * (36.0 / 9.0) * (26.0 / 8.0); // 48.75:1
+ static constexpr double kCountsPerMotorShaftRev = 12.0;
+ static constexpr double kCountsPerRevolution =
+ kCountsPerMotorShaftRev * kGearRatio; // 585.0
+ static constexpr units::meter_t kWheelDiameter = 60_mm;
+
+ Drivetrain();
+
+ /**
+ * Will be called periodically whenever the CommandScheduler runs.
+ */
+ void Periodic() override;
+
+ /**
+ * Drives the robot using arcade controls.
+ *
+ * @param xaxisSpeed the commanded forward movement
+ * @param zaxisRotate the commanded rotation
+ */
+ void ArcadeDrive(double xaxisSpeed, double zaxisRotate);
+
+ /**
+ * Resets the drive encoders to currently read a position of 0.
+ */
+ void ResetEncoders();
+
+ /**
+ * Gets the left drive encoder count.
+ *
+ * @return the left drive encoder count
+ */
+ int GetLeftEncoderCount();
+
+ /**
+ * Gets the right drive encoder count.
+ *
+ * @return the right drive encoder count
+ */
+ int GetRightEncoderCount();
+
+ /**
+ * Gets the left distance driven.
+ *
+ * @return the left-side distance driven
+ */
+ units::meter_t GetLeftDistance();
+
+ /**
+ * Gets the right distance driven.
+ *
+ * @return the right-side distance driven
+ */
+ units::meter_t GetRightDistance();
+
+ /**
+ * Returns the average distance traveled by the left and right encoders.
+ *
+ * @return The average distance traveled by the left and right encoders.
+ */
+ units::meter_t GetAverageDistance();
+
+ /**
+ * Returns the acceleration along the X-axis, in Gs.
+ */
+ double GetAccelX();
+
+ /**
+ * Returns the acceleration along the Y-axis, in Gs.
+ */
+ double GetAccelY();
+
+ /**
+ * Returns the acceleration along the Z-axis, in Gs.
+ */
+ double GetAccelZ();
+
+ /**
+ * Returns the current angle of the Romi around the X-axis, in degrees.
+ */
+ double GetGyroAngleX();
+
+ /**
+ * Returns the current angle of the Romi around the Y-axis, in degrees.
+ */
+ double GetGyroAngleY();
+
+ /**
+ * Returns the current angle of the Romi around the Z-axis, in degrees.
+ */
+ double GetGyroAngleZ();
+
+ /**
+ * Reset the gyro.
+ */
+ void ResetGyro();
+
+ private:
+ frc::XRPMotor m_leftMotor{0};
+ frc::XRPMotor m_rightMotor{1};
+
+ frc::Encoder m_leftEncoder{4, 5};
+ frc::Encoder m_rightEncoder{6, 7};
+
+ frc::DifferentialDrive m_drive{m_leftMotor, m_rightMotor};
+
+ frc::XRPGyro m_gyro;
+ frc::BuiltInAccelerometer m_accelerometer;
+};
diff --git a/wpilibcExamples/src/main/cpp/examples/examples.json b/wpilibcExamples/src/main/cpp/examples/examples.json
index aaec45d..8032909 100644
--- a/wpilibcExamples/src/main/cpp/examples/examples.json
+++ b/wpilibcExamples/src/main/cpp/examples/examples.json
@@ -1,14 +1,12 @@
[
{
"name": "Motor Control",
- "description": "Demonstrate controlling a single motor with a Joystick and displaying the net movement of the motor using an encoder.",
+ "description": "Control a single motor with a joystick, displaying the movement of the motor using an encoder.",
"tags": [
- "Robot and Motor",
- "Digital",
- "Sensors",
- "Actuators",
- "Joystick",
- "Complete List"
+ "Basic Robot",
+ "Encoder",
+ "SmartDashboard",
+ "Joystick"
],
"foldername": "MotorControl",
"gradlebase": "cpp",
@@ -16,11 +14,11 @@
},
{
"name": "Relay",
- "description": "Demonstrate controlling a Relay from Joystick buttons.",
+ "description": "Control a relay from joystick buttons.",
"tags": [
- "Actuators",
- "Joystick",
- "Complete List"
+ "Hardware",
+ "Relay",
+ "Joystick"
],
"foldername": "Relay",
"gradlebase": "cpp",
@@ -28,32 +26,40 @@
},
{
"name": "PDP CAN Monitoring",
- "description": "Demonstrate using CAN to monitor the voltage, current, and temperature in the Power Distribution Panel.",
+ "description": "Monitor Power Distribution data such as voltage, current, temperature, etc.",
"tags": [
- "Complete List",
- "CAN",
- "Sensors"
+ "Hardware",
+ "PDP",
+ "SmartDashboard"
],
"foldername": "CANPDP",
"gradlebase": "cpp",
"commandversion": 2
},
{
- "name":"Mechanism2d",
- "foldername":"Mechanism2d",
- "gradlebase":"cpp",
- "description":"An example usage of Mechanism2d to display mechanism states on a dashboard.",
- "tags":["Mechanism2d"],
+ "name": "Mechanism2d",
+ "foldername": "Mechanism2d",
+ "gradlebase": "cpp",
+ "description": "Display mechanism states on a dashboard with Mechanism2d.",
+ "tags": [
+ "Basic Robot",
+ "Elevator",
+ "Arm",
+ "Analog",
+ "Joystick",
+ "SmartDashboard",
+ "Mechanism2d"
+ ],
"commandversion": 2
},
{
"name": "Solenoids",
- "description": "Demonstrate controlling a single and double solenoid from Joystick buttons.",
+ "description": "Control a single and double solenoid from joystick buttons.",
"tags": [
- "Actuators",
+ "Hardware",
"Joystick",
- "Pneumatics",
- "Complete List"
+ "Shuffleboard",
+ "Pneumatics"
],
"foldername": "Solenoid",
"gradlebase": "cpp",
@@ -61,11 +67,11 @@
},
{
"name": "Encoder",
- "description": "Demonstrate displaying the value of a quadrature encoder on the SmartDashboard.",
+ "description": "View values from a quadrature encoder.",
"tags": [
- "Complete List",
- "Digital",
- "Sensors"
+ "Hardware",
+ "Encoder",
+ "SmartDashboard"
],
"foldername": "Encoder",
"gradlebase": "cpp",
@@ -73,8 +79,10 @@
},
{
"name": "EventLoop",
- "description": "Demonstrate managing a ball system using EventLoop and BooleanEvent.",
+ "description": "Manage a ball system using EventLoop and BooleanEvent.",
"tags": [
+ "Basic Robot",
+ "Flywheel",
"EventLoop"
],
"foldername": "EventLoop",
@@ -83,12 +91,11 @@
},
{
"name": "Arcade Drive",
- "description": "An example program which demonstrates the use of Arcade Drive with the DifferentialDrive class",
+ "description": "Control a differential drivetrain with single-joystick arcade drive in teleop.",
"tags": [
- "Getting Started with C++",
- "Robot and Motor",
- "Joystick",
- "Complete List"
+ "Basic Robot",
+ "Differential Drive",
+ "Joystick"
],
"foldername": "ArcadeDrive",
"gradlebase": "cpp",
@@ -96,12 +103,11 @@
},
{
"name": "Tank Drive",
- "description": "An example program which demonstrates the use of Tank Drive with the DifferentialDrive class",
+ "description": "Control a differential drive with twin-joystick tank drive in teleop.",
"tags": [
- "Getting Started with C++",
- "Robot and Motor",
- "Joystick",
- "Complete List"
+ "Basic Robot",
+ "Differential Drive",
+ "Joystick"
],
"foldername": "TankDrive",
"gradlebase": "cpp",
@@ -109,12 +115,11 @@
},
{
"name": "Mecanum Drive",
- "description": "An example program which demonstrates the use of Mecanum Drive with the MecanumDrive class",
+ "description": "Control a mecanum drivetrain with a joystick in teleop.",
"tags": [
- "Getting Started with C++",
- "Robot and Motor",
- "Joystick",
- "Complete List"
+ "Basic Robot",
+ "Mecanum Drive",
+ "Joystick"
],
"foldername": "MecanumDrive",
"gradlebase": "cpp",
@@ -122,12 +127,12 @@
},
{
"name": "Ultrasonic",
- "description": "Demonstrate maintaining a set distance using an ultrasonic sensor.",
+ "description": "View values from a ping-response ultrasonic sensor.",
"tags": [
- "Robot and Motor",
- "Complete List",
- "Sensors",
- "Analog"
+ "Hardware",
+ "Ultrasonic",
+ "SmartDashboard",
+ "Shuffleboard"
],
"foldername": "Ultrasonic",
"gradlebase": "cpp",
@@ -135,12 +140,12 @@
},
{
"name": "UltrasonicPID",
- "description": "Demonstrate maintaining a set distance using an ultrasonic sensor and PID control.",
+ "description": "Maintain a set distance from an obstacle with an ultrasonic sensor and PID control.",
"tags": [
- "Robot and Motor",
- "Complete List",
- "Sensors",
- "Analog"
+ "Basic Robot",
+ "Ultrasonic",
+ "PID",
+ "Differential Drive"
],
"foldername": "UltrasonicPID",
"gradlebase": "cpp",
@@ -148,11 +153,12 @@
},
{
"name": "Gyro",
- "description": "An example program showing how to drive straight with using a gyro sensor.",
+ "description": "Drive a differential drive straight with a gyro sensor.",
"tags": [
- "Robot and Motor",
- "Complete List",
- "Sensors",
+ "Basic Robot",
+ "Differential Drive",
+ "PID",
+ "Gyro",
"Analog",
"Joystick"
],
@@ -162,11 +168,11 @@
},
{
"name": "Gyro Mecanum",
- "description": "An example program showing how to perform mecanum drive with field oriented controls.",
+ "description": "Drive a mecanum drivetrain using field-oriented controls with a joystick.",
"tags": [
- "Robot and Motor",
- "Complete List",
- "Sensors",
+ "Basic Robot",
+ "Mecanum Drive",
+ "Gyro",
"Analog",
"Joystick"
],
@@ -176,9 +182,10 @@
},
{
"name": "HID Rumble",
- "description": "An example program showing how to make human interface devices rumble.",
+ "description": "Make human interface devices (HID) rumble.",
"tags": [
- "Joystick"
+ "Hardware",
+ "XboxController"
],
"foldername": "HidRumble",
"gradlebase": "cpp",
@@ -186,25 +193,40 @@
},
{
"name": "PotentiometerPID",
- "description": "An example to demonstrate the use of a potentiometer and PID control to reach elevator position setpoints.",
+ "description": "Maintain elevator position setpoints with a potentiometer and PID control.",
"tags": [
- "Joystick",
- "Actuators",
- "Complete List",
- "Sensors",
- "Analog"
+ "Basic Robot",
+ "Analog",
+ "Elevator",
+ "PID",
+ "Joystick"
],
"foldername": "PotentiometerPID",
"gradlebase": "cpp",
"commandversion": 2
},
{
- "name": "Elevator with trapezoid profiled PID",
- "description": "An example to demonstrate the use of an encoder and trapezoid profiled PID control to reach elevator position setpoints.",
+ "name": "Elevator with exponential profiled PID",
+ "description": "Reach elevator position setpoints with exponential profiles and smart motor controller PID.",
"tags": [
- "Digital",
- "Sensors",
- "Actuators",
+ "Basic Robot",
+ "Elevator",
+ "Exponential Profile",
+ "Smart Motor Controller",
+ "Joystick"
+ ],
+ "foldername": "ElevatorExponentialProfile",
+ "gradlebase": "cpp",
+ "commandversion": 2
+ },
+ {
+ "name": "Elevator with trapezoid profiled PID",
+ "description": "Reach elevator position setpoints with trapezoid profiles and smart motor controller PID.",
+ "tags": [
+ "Basic Robot",
+ "Elevator",
+ "Trapezoid Profile",
+ "Smart Motor Controller",
"Joystick"
],
"foldername": "ElevatorTrapezoidProfile",
@@ -213,11 +235,11 @@
},
{
"name": "Elevator with profiled PID controller",
- "description": "An example to demonstrate the use of an encoder and trapezoid profiled PID control to reach elevator position setpoints.",
+ "description": "Reach elevator position setpoints with an encoder and profiled PID control.",
"tags": [
- "Digital",
- "Sensors",
- "Actuators",
+ "Basic Robot",
+ "Elevator",
+ "Profiled PID",
"Joystick"
],
"foldername": "ElevatorProfiledPID",
@@ -226,10 +248,9 @@
},
{
"name": "Getting Started",
- "description": "An example program which demonstrates the simplest autonomous and teleoperated routines.",
+ "description": "A differential-drive robot with split-stick Xbox arcade drive with a simple time-based autonomous.",
"tags": [
- "Getting Started with C++",
- "Complete List"
+ "Basic Robot"
],
"foldername": "GettingStarted",
"gradlebase": "cpp",
@@ -237,10 +258,9 @@
},
{
"name": "Simple Vision",
- "description": "The minimal program to acquire images from an attached USB camera on the robot and send them to the dashboard.",
+ "description": "Use the CameraServer class to stream from a USB Webcam without processing the images.",
"tags": [
- "Vision",
- "Complete List"
+ "Vision"
],
"foldername": "QuickVision",
"gradlebase": "cpp",
@@ -248,19 +268,30 @@
},
{
"name": "Intermediate Vision",
- "description": "An example program that acquires images from an attached USB camera and adds some annotation to the image as you might do for showing operators the result of some image recognition, and sends it to the dashboard for display.",
+ "description": "Acquire images from an attached USB camera and add some annotation to the image (as you might do for showing operators the result of some image recognition) and send it to the dashboard for display.",
"tags": [
- "Vision",
- "Complete List"
+ "Vision"
],
"foldername": "IntermediateVision",
"gradlebase": "cpp",
"commandversion": 2
},
{
- "name": "I2C Communication",
- "description": "An example program that communicates with external devices (such as an Arduino) using the roboRIO's I2C port",
+ "name": "AprilTags Vision",
+ "description": "On-roboRIO detection of AprilTags using an attached USB camera.",
"tags": [
+ "Vision",
+ "AprilTags"
+ ],
+ "foldername": "AprilTagsVision",
+ "gradlebase": "cpp",
+ "commandversion": 2
+ },
+ {
+ "name": "I2C Communication",
+ "description": "Communicate with external devices (such as an Arduino) using the roboRIO's I2C port.",
+ "tags": [
+ "Hardware",
"I2C"
],
"foldername": "I2CCommunication",
@@ -269,21 +300,20 @@
},
{
"name": "Digital Communication Sample",
- "description": "An example program that communicates with external devices (such as an Arduino) using the roboRIO's DIO",
+ "description": "Communicates with external devices (such as an Arduino) using the roboRIO's DIO.",
"tags": [
- "Digital"
+ "Hardware",
+ "Digital Output"
],
"foldername": "DigitalCommunication",
"gradlebase": "cpp",
"commandversion": 2
},
-
{
"name": "Axis Camera Sample",
- "description": "An example program that acquires images from an Axis network camera and adds some annotation to the image as you might do for showing operators the result of some image recognition, and sends it to the dashboard for display. This demonstrates the use of the AxisCamera class.",
+ "description": "Acquire images from an Axis network camera and adds some annotation to the image (as you might do for showing operators the result of some image recognition), and sends it to the dashboard for display.",
"tags": [
- "Vision",
- "Complete List"
+ "Vision"
],
"foldername": "AxisCameraSample",
"gradlebase": "cpp",
@@ -291,10 +321,17 @@
},
{
"name": "GearsBot",
- "description": "A fully functional example CommandBased program for WPIs GearsBot robot, using the new command-based framework. This code can run on your computer if it supports simulation.",
+ "description": "A fully functional Command-Based program for WPI's GearsBot robot.",
"tags": [
- "CommandBased Robot",
- "Complete List"
+ "Complete Robot",
+ "Command-based",
+ "Differential Drive",
+ "Elevator",
+ "Arm",
+ "Analog",
+ "Digital Input",
+ "SmartDashboard",
+ "XboxController"
],
"foldername": "GearsBot",
"gradlebase": "cpp",
@@ -302,8 +339,9 @@
},
{
"name": "HAL",
- "description": "A program created using the HAL exclusively. This example is for advanced users",
+ "description": "Use the low-level HAL C functions. This example is for advanced users.",
"tags": [
+ "Basic Robot",
"HAL"
],
"foldername": "HAL",
@@ -311,10 +349,15 @@
"commandversion": 2
},
{
- "name": "ShuffleBoard",
- "description": "An example program that uses ShuffleBoard with its Widgets and Tabs.",
+ "name": "Shuffleboard",
+ "description": "Present various data via the Shuffleboard API.",
"tags": [
- "ShuffleBoard"
+ "Basic Robot",
+ "Differential Drive",
+ "Elevator",
+ "Analog",
+ "Encoder",
+ "Shuffleboard"
],
"foldername": "ShuffleBoard",
"gradlebase": "cpp",
@@ -322,10 +365,17 @@
},
{
"name": "'Traditional' Hatchbot",
- "description": "A fully-functional command-based hatchbot for the 2019 game using the new command framework. Written in the 'traditional' style, i.e. commands are given their own classes.",
+ "description": "A fully-functional command-based hatchbot for the 2019 game, written in the 'traditional' style, i.e. commands are given their own classes.",
"tags": [
- "Complete robot",
- "Command-based"
+ "Complete Robot",
+ "Command-based",
+ "Differential Drive",
+ "Encoder",
+ "Shuffleboard",
+ "Sendable",
+ "DataLog",
+ "Pneumatics",
+ "XboxController"
],
"foldername": "HatchbotTraditional",
"gradlebase": "cpp",
@@ -333,11 +383,17 @@
},
{
"name": "'Inlined' Hatchbot",
- "description": "A fully-functional command-based hatchbot for the 2019 game using the new command framework. Written in the 'inlined' style, i.e. many commands are defined inline with lambdas.",
+ "description": "A fully-functional command-based hatchbot for the 2019 game, written in the 'inlined' style, i.e. many commands are defined inline with lambdas.",
"tags": [
- "Complete robot",
+ "Complete Robot",
"Command-based",
- "Lambdas"
+ "Differential Drive",
+ "Encoder",
+ "Shuffleboard",
+ "Sendable",
+ "DataLog",
+ "Pneumatics",
+ "PS4Controller"
],
"foldername": "HatchbotInlined",
"gradlebase": "cpp",
@@ -345,11 +401,18 @@
},
{
"name": "Rapid React Command Bot",
- "description": "A fully-functional command-based fender bot for the 2022 game using the new command framework.",
+ "description": "A fully-functional command-based fender bot for the 2022 game, written in the 'inlined' style, i.e. many commands are defined inline with lambdas.",
"tags": [
- "Complete robot",
+ "Complete Robot",
"Command-based",
- "Lambdas"
+ "Differential Drive",
+ "Intake",
+ "Flywheel",
+ "Encoder",
+ "Pneumatics",
+ "Digital Input",
+ "PID",
+ "XboxController"
],
"foldername": "RapidReactCommandBot",
"gradlebase": "cpp",
@@ -357,7 +420,7 @@
},
{
"name": "Select Command Example",
- "description": "An example showing how to use the SelectCommand class from the new command framework.",
+ "description": "Use SelectCommand to select an autonomous routine.",
"tags": [
"Command-based"
],
@@ -366,21 +429,15 @@
"commandversion": 2
},
{
- "name": "Scheduler Event Logging",
- "description": "An example showing how to use Shuffleboard to log Command events from the CommandScheduler in the new command framework",
- "tags": [
- "Command-based",
- "Shuffleboard"
- ],
- "foldername": "SchedulerEventLogging",
- "gradlebase": "cpp",
- "commandversion": 2
- },
- {
"name": "Frisbeebot",
- "description": "An example robot project for a simple frisbee shooter for the 2013 FRC game, Ultimate Ascent, demonstrating use of PID functionality in the command framework",
+ "description": "A simple frisbee shooter for the 2013 game, demonstrating use of PIDSubsystem.",
"tags": [
+ "Complete Robot",
"Command-based",
+ "Differential Drive",
+ "Flywheel",
+ "Encoder",
+ "XboxController",
"PID"
],
"foldername": "Frisbeebot",
@@ -389,10 +446,14 @@
},
{
"name": "Gyro Drive Commands",
- "description": "An example command-based robot project demonstrating simple PID functionality utilizing a gyroscope to keep a robot driving straight and to turn to specified angles.",
+ "description": "Control a robot's angle with PID and a gyro, in command-based.",
"tags": [
"Command-based",
+ "Differential Drive",
+ "Encoder",
+ "PS4Controller",
"PID",
+ "Profiled PID",
"Gyro"
],
"foldername": "GyroDriveCommands",
@@ -401,9 +462,13 @@
},
{
"name": "SwerveBot",
- "description": "An example program for a swerve drive that uses swerve drive kinematics and odometry.",
+ "description": "Use kinematics and odometry with a swerve drive.",
"tags": [
- "SwerveBot"
+ "Swerve Drive",
+ "Odometry",
+ "XboxController",
+ "Gyro",
+ "Encoder"
],
"foldername": "SwerveBot",
"gradlebase": "cpp",
@@ -411,9 +476,13 @@
},
{
"name": "MecanumBot",
- "description": "An example program for a mecanum drive that uses mecanum drive kinematics and odometry.",
+ "description": "Use kinematics and odometry with a mecanum drive.",
"tags": [
- "MecanumBot"
+ "Mecanum Drive",
+ "Odometry",
+ "Encoder",
+ "Gyro",
+ "XboxController"
],
"foldername": "MecanumBot",
"gradlebase": "cpp",
@@ -421,9 +490,13 @@
},
{
"name": "DifferentialDriveBot",
- "description": "An example program for a differential drive that uses differential drive kinematics and odometry.",
+ "description": "Use kinematics and odometry with a differential drive.",
"tags": [
- "DifferentialDriveBot"
+ "Differential Drive",
+ "Odometry",
+ "Encoder",
+ "Gyro",
+ "XboxController"
],
"foldername": "DifferentialDriveBot",
"gradlebase": "cpp",
@@ -431,13 +504,17 @@
},
{
"name": "RamseteCommand",
- "description": "An example command-based robot demonstrating the use of a RamseteCommand to follow a pregenerated trajectory.",
+ "description": "Follow a pre-generated trajectory with a differential drive using RamseteCommand.",
"tags": [
- "RamseteCommand",
- "PID",
+ "Differential Drive",
+ "Command-based",
"Ramsete",
"Trajectory",
- "Path following"
+ "Path Following",
+ "Odometry",
+ "Encoder",
+ "Gyro",
+ "XboxController"
],
"foldername": "RamseteCommand",
"gradlebase": "cpp",
@@ -445,12 +522,11 @@
},
{
"name": "Arcade Drive Xbox Controller",
- "description": "An example program which demonstrates the use of Arcade Drive with the DifferentialDrive class and an Xbox Controller.",
+ "description": "Control a differential drive with split-stick arcade drive in teleop.",
"tags": [
- "Getting Started with C++",
- "Robot and Motor",
- "XboxController",
- "Complete List"
+ "Basic Robot",
+ "Differential Drive",
+ "XboxController"
],
"foldername": "ArcadeDriveXboxController",
"gradlebase": "cpp",
@@ -458,12 +534,11 @@
},
{
"name": "Tank Drive Xbox Controller",
- "description": "An example program which demonstrates the use of Tank Drive with the DifferentialDrive class and an Xbox Controller.",
+ "description": "Control a differential drive with Xbox tank drive in teleop.",
"tags": [
- "Getting Started with C++",
- "Robot and Motor",
- "XboxController",
- "Complete List"
+ "Basic Robot",
+ "Differential Drive",
+ "XboxController"
],
"foldername": "TankDriveXboxController",
"gradlebase": "cpp",
@@ -471,9 +546,12 @@
},
{
"name": "Duty Cycle Encoder",
- "description": "Demonstrates the use of the Duty Cycle Encoder class",
+ "description": "View values from a duty-cycle encoder.",
"tags": [
- "Getting Started with C++"
+ "Hardware",
+ "Duty Cycle",
+ "Encoder",
+ "SmartDashboard"
],
"foldername": "DutyCycleEncoder",
"gradlebase": "cpp",
@@ -481,9 +559,11 @@
},
{
"name": "Duty Cycle Input",
- "description": "Demonstrates the use of the Duty Cycle class",
+ "description": "View duty-cycle input.",
"tags": [
- "Getting Started with C++"
+ "Hardware",
+ "Duty Cycle",
+ "SmartDashboard"
],
"foldername": "DutyCycleInput",
"gradlebase": "cpp",
@@ -491,9 +571,11 @@
},
{
"name": "Addressable LED",
- "description": "Demonstrates the use of the Addressable LED class",
+ "description": "Display a rainbow pattern on an addressable LED strip.",
"tags": [
- "Getting Started with C++"
+ "Hardware",
+ "Basic Robot",
+ "AddressableLEDs"
],
"foldername": "AddressableLED",
"gradlebase": "cpp",
@@ -501,9 +583,11 @@
},
{
"name": "DMA",
- "description": "Demonstrates the use of the DMA class",
+ "description": "Read various sensors using DMA.",
"tags": [
- "Advanced C++"
+ "Hardware",
+ "DMA",
+ "SmartDashboard"
],
"foldername": "DMA",
"gradlebase": "cpp",
@@ -511,13 +595,16 @@
},
{
"name": "MecanumControllerCommand",
- "description": "An example command-based robot demonstrating the use of a MecanumControllerCommand to follow a pregenerated trajectory.",
+ "description": "Follow a pre-generated trajectory with a mecanum drive using MecanumControllerCommand.",
"tags": [
- "MecanumControllerCommand",
- "Mecanum",
- "PID",
+ "Command-based",
+ "Mecanum Drive",
+ "Gyro",
+ "Encoder",
+ "Odometry",
"Trajectory",
- "Path following"
+ "Path Following",
+ "XboxController"
],
"foldername": "MecanumControllerCommand",
"gradlebase": "cpp",
@@ -525,13 +612,16 @@
},
{
"name": "SwerveControllerCommand",
- "description": "An example command-based robot demonstrating the use of a SwerveControllerCommand to follow a pregenerated trajectory.",
+ "description": "Follow a pre-generated trajectory with a swerve drive using SwerveControllerCommand.",
"tags": [
- "SwerveControllerCommand",
- "Swerve",
- "PID",
+ "Command-based",
+ "Swerve Drive",
+ "Gyro",
+ "Encoder",
+ "Odometry",
"Trajectory",
- "Path following"
+ "Path Following",
+ "XboxController"
],
"foldername": "SwerveControllerCommand",
"gradlebase": "cpp",
@@ -539,11 +629,14 @@
},
{
"name": "ArmBot",
- "description": "An example command-based robot demonstrating the use of a ProfiledPIDSubsystem to control an arm.",
+ "description": "Control an arm with ProfiledPIDSubsystem.",
"tags": [
- "ArmBot",
- "PID",
- "Motion Profile"
+ "Command-based",
+ "Arm",
+ "Encoder",
+ "Profiled PID",
+ "XboxController",
+ "Differential Drive"
],
"foldername": "ArmBot",
"gradlebase": "cpp",
@@ -551,11 +644,14 @@
},
{
"name": "ArmBotOffboard",
- "description": "An example command-based robot demonstrating the use of a TrapezoidProfileSubsystem to control an arm with an offboard PID.",
+ "description": "Control an arm with TrapezoidProfileSubsystem and smart motor controller PID.",
"tags": [
- "ArmBotOffboard",
- "PID",
- "Motion Profile"
+ "Command-based",
+ "Arm",
+ "Smart Motor Controller",
+ "Trapezoid Profile",
+ "XboxController",
+ "Differential Drive"
],
"foldername": "ArmBotOffboard",
"gradlebase": "cpp",
@@ -563,11 +659,13 @@
},
{
"name": "DriveDistanceOffboard",
- "description": "An example command-based robot demonstrating the use of a TrapezoidProfileCommand to drive a robot a set distance with offboard PID on the drive.",
+ "description": "Drive a differential drivetrain a set distance using TrapezoidProfileCommand and smart motor controller PID.",
"tags": [
- "DriveDistance",
- "PID",
- "Motion Profile"
+ "Command-based",
+ "Differential Drive",
+ "Trapezoid Profile",
+ "Smart Motor Controller",
+ "XboxController"
],
"foldername": "DriveDistanceOffboard",
"gradlebase": "cpp",
@@ -575,9 +673,16 @@
},
{
"name": "RamseteController",
- "description": "An example robot demonstrating the use of RamseteController.",
+ "description": "Follow a pre-generated trajectory with a differential drive using RamseteController.",
"tags": [
- "RamseteController"
+ "Basic Robot",
+ "Differential Drive",
+ "Ramsete",
+ "PID",
+ "Odometry",
+ "Path Following",
+ "Trajectory",
+ "XboxController"
],
"foldername": "RamseteController",
"gradlebase": "cpp",
@@ -587,24 +692,45 @@
"name": "RomiReference",
"description": "An example command-based robot program that can be used with the Romi reference robot design.",
"tags": [
- "Drivetrain",
- "Romi"
+ "Romi",
+ "Command-based",
+ "Differential Drive",
+ "Digital Input",
+ "Joystick"
],
"foldername": "RomiReference",
"gradlebase": "cppromi",
- "commandversion": 2
+ "commandversion": 2,
+ "extravendordeps": [
+ "romi"
+ ]
+ },
+ {
+ "name": "XRP Reference",
+ "description": "An example command-based robot program that can be used with the XRP reference robot design.",
+ "tags": [
+ "XRP",
+ "Command-based",
+ "Differential Drive",
+ "Digital Input",
+ "Joystick"
+ ],
+ "foldername": "XRPReference",
+ "gradlebase": "cppxrp",
+ "commandversion": 2,
+ "extravendordeps": [
+ "xrp"
+ ]
},
{
"name": "StateSpaceFlywheel",
- "description": "An example state-space controller for a flywheel.",
+ "description": "Control a flywheel using a state-space model (based on values from CAD), with a Kalman Filter and LQR.",
"tags": [
- "StateSpaceFlywheel",
+ "Basic Robot",
"Flywheel",
- "State Space",
- "Model",
- "Digital",
- "Sensors",
- "Actuators",
+ "State-Space",
+ "LQR",
+ "Encoder",
"Joystick"
],
"foldername": "StateSpaceFlywheel",
@@ -613,16 +739,14 @@
},
{
"name": "StateSpaceFlywheelSysId",
- "description": "An example state-space controller demonstrating the use of FRC Characterization's System Identification for controlling a flywheel.",
+ "description": "Control a flywheel using a state-space model (based on values from SysId), with a Kalman Filter and LQR.",
"tags": [
- "StateSpaceFlywheelSysId",
- "FRC Characterization",
+ "Basic Robot",
"Flywheel",
- "Characterization",
- "State space",
- "Digital",
- "Sensors",
- "Actuators",
+ "SysId",
+ "State-Space",
+ "LQR",
+ "Encoder",
"Joystick"
],
"foldername": "StateSpaceFlywheelSysId",
@@ -631,13 +755,13 @@
},
{
"name": "StateSpaceElevator",
- "description": "An example state-space controller for controlling an elevator.",
+ "description": "Control an elevator using a state-space model (based on values from CAD), with a Kalman Filter and LQR.",
"tags": [
+ "Basic Robot",
"Elevator",
- "State Space",
- "Digital",
- "Sensors",
- "Actuators",
+ "State-Space",
+ "LQR",
+ "Encoder",
"Joystick"
],
"foldername": "StateSpaceElevator",
@@ -646,13 +770,13 @@
},
{
"name": "StateSpaceArm",
- "description": "An example state-space controller for controlling an arm.",
+ "description": "Control an arm using a state-space model (based on values from CAD), with a Kalman Filter and LQR.",
"tags": [
+ "Basic Robot",
"Arm",
- "State space",
- "Digital",
- "Sensors",
- "Actuators",
+ "State-Space",
+ "LQR",
+ "Encoder",
"Joystick"
],
"foldername": "StateSpaceArm",
@@ -661,30 +785,44 @@
},
{
"name": "ElevatorSimulation",
- "description": "Demonstrates the use of physics simulation with a simple elevator.",
+ "description": "Simulate an elevator.",
"tags": [
+ "Basic Robot",
"Elevator",
- "State space",
- "Digital",
- "Sensors",
+ "State-Space",
"Simulation",
- "Physics",
- "Mechanism2d"
+ "Mechanism2d",
+ "Profiled PID"
],
"foldername": "ElevatorSimulation",
"gradlebase": "cpp",
"commandversion": 2
},
{
- "name": "DifferentialDrivePoseEstimator",
- "description": "Demonstrates the use of the DifferentialDrivePoseEstimator as a replacement for differential drive odometry.",
+ "name": "Elevator Exponential Profile Simulation",
+ "description": "Simulate an elevator.",
"tags": [
- "Drivetrain",
- "State space",
+ "Basic Robot",
+ "Elevator",
+ "State-Space",
+ "Simulation",
+ "Mechanism2d",
+ "Profiled PID"
+ ],
+ "foldername": "ElevatorExponentialSimulation",
+ "gradlebase": "cpp",
+ "commandversion": 2
+ },
+ {
+ "name": "DifferentialDrivePoseEstimator",
+ "description": "Combine differential-drive odometry with vision data using DifferentialDrivePoseEstimator.",
+ "tags": [
+ "Differential Drive",
+ "State-Space",
+ "Pose Estimator",
"Vision",
- "Filter",
- "Odometry",
- "Pose"
+ "PID",
+ "XboxController"
],
"foldername": "DifferentialDrivePoseEstimator",
"gradlebase": "cpp",
@@ -692,14 +830,14 @@
},
{
"name": "MecanumDrivePoseEstimator",
- "description": "Demonstrates the use of the MecanumDrivePoseEstimator as a replacement for mecanum odometry.",
+ "description": "Combine mecanum-drive odometry with vision data using MecanumDrivePoseEstimator.",
"tags": [
- "Drivetrain",
- "State space",
+ "Mecanum Drive",
+ "State-Space",
+ "Pose Estimator",
"Vision",
- "Filter",
- "Odometry",
- "Pose"
+ "PID",
+ "XboxController"
],
"foldername": "MecanumDrivePoseEstimator",
"gradlebase": "cpp",
@@ -707,14 +845,12 @@
},
{
"name": "ArmSimulation",
- "description": "Demonstrates the use of physics simulation with a simple single-jointed arm.",
+ "description": "Simulate a single-jointed arm.",
"tags": [
+ "Basic Robot",
"Arm",
- "State space",
- "Digital",
- "Sensors",
+ "State-Space",
"Simulation",
- "Physics",
"Mechanism2d",
"Preferences"
],
@@ -724,26 +860,28 @@
},
{
"name": "UnitTesting",
- "description": "Demonstrates basic unit testing for a robot project.",
+ "description": "Test a robot project with basic unit tests in simulation.",
"tags": [
- "Testing"
+ "Intake",
+ "Pneumatics"
],
"foldername": "UnitTest",
"gradlebase": "cpp",
- "commandversion": 2
+ "commandversion": 2,
+ "hasunittests": true
},
{
"name": "SimpleDifferentialDriveSimulation",
- "description": "An example of a minimal drivetrain simulation project without the command-based library.",
+ "description": "Simulate a differential drivetrain and follow trajectories with RamseteController (non-command-based).",
"tags": [
"Differential Drive",
- "State space",
- "Digital",
- "Sensors",
- "Simulation",
- "Physics",
- "Drivetrain",
- "Field2d"
+ "State-Space",
+ "Ramsete",
+ "Path Following",
+ "Trajectory",
+ "Encoder",
+ "XboxController",
+ "Simulation"
],
"foldername": "SimpleDifferentialDriveSimulation",
"gradlebase": "cpp",
@@ -751,16 +889,13 @@
},
{
"name": "StateSpaceDriveSimulation",
- "description": "Demonstrates the use of physics simulation with a differential drivetrain and the Field2d class.",
+ "description": "Simulate a differential drivetrain and follow trajectories with RamseteCommand (command-based).",
"tags": [
+ "Command-based",
"Differential Drive",
- "State space",
- "Digital",
- "Sensors",
- "Simulation",
- "Physics",
- "Drivetrain",
- "Field2d"
+ "State-Space",
+ "XboxController",
+ "Simulation"
],
"foldername": "StateSpaceDifferentialDriveSimulation",
"gradlebase": "cpp",
@@ -768,18 +903,29 @@
},
{
"name": "SwerveDrivePoseEstimator",
- "description": "Demonstrates the use of the SwerveDrivePoseEstimator as a replacement for mecanum drive odometry.",
+ "description": "Combine swerve-drive odometry with vision data using SwerveDrivePoseEstimator.",
"tags": [
- "Drivetrain",
- "State space",
+ "Swerve Drive",
+ "State-Space",
+ "Pose Estimator",
"Vision",
- "Filter",
- "Odometry",
- "State",
- "Swerve"
+ "PID",
+ "XboxController"
],
"foldername": "SwerveDrivePoseEstimator",
"gradlebase": "cpp",
"commandversion": 2
+ },
+ {
+ "name": "Flywheel BangBangController",
+ "description": "A sample program to demonstrate the use of a BangBangController with a flywheel to control RPM",
+ "tags": [
+ "Flywheel",
+ "Simulation",
+ "Joystick"
+ ],
+ "foldername": "FlywheelBangBangController",
+ "gradlebase": "cpp",
+ "commandversion": 2
}
]