This can catch breaking changes earlier.
- Builds linux only for speed
- Builds and publishes artifacts in this file as it was actually faster
then reusing the artifacts from the gradle file as those need the
combiner run on them. It uploads the artifacts to Actions with a 1 day
retention, because that allows the tools to be built in parallel, which
overall sped things up. This also only allows relevant tasks in wpilib
to be run
- The tool builds are uploaded with a shorter retention time in case
someone wants to do more extensive tests.
Add LEDReader and LEDWriter helper interfaces to facilitate composing simple patterns into more complex ones, e.g. LEDPattern.solid(Color.kBlue).breathe(Seconds.of(0.75)). Pattern composition relies on changing out the write behavior; for example, offsetBy increments the indexes to write to; while blink will switch between playing a base pattern and turning off all the LEDs.
Add a view class for splitting a single large buffer into smaller distinct sections, which is useful for dealing with long chained LED strips mounted on different parts of a robot. Views cannot be written directly to an LED strip (in fact, trying to do so won't even compile).
Adds some utility methods to the Color class for interpolating between two colors, and support color representations with 32-bit integers to avoid object allocations.
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
Uses enhanced instanceof (and simplify equals methods)
Uses switch expressions and arrow labels
Seal and finalize some Shuffleboard classes
Co-authored-by: Sam Carlberg <sam@slfc.dev>
This is to allow 3rd party sim providers (eg vendors) to subclass this class so that the register methods of their sim classes can return CallbackStores like the builtin sims.
Although it was already possible to create such a subclass but passing dummy parameters to one of the other constructors, this eliminates the need to pass such dummy parameters and makes it clearer that subclassing is allowed.
This is a cleanup of the FlywheelSim class with a few added features.
- One FlywheelSim constructor that takes a plant, DCMotor, and a optional number of measurementStdDevs. The documentation now states how to construct the plant either through LinearSystemId.createFlywheelSystem or identifyVelocitySystem.
- The gearbox, gearing and moment of Inertia (J) are now private final fields. The gearing is determined from the plant in the constructor as well as the moment of inertia. There are getter methods that allow the flywheelSim to return the gearbox, gearing, and moment of inertia.
- The getCurrentDrawAmps function now uses m_x instead of getAngularVelocityRadPerSec in accordance with more accuracy and matches the patter in other sims.
- Added getter methods for the InputVoltage, angularAcceleration and torque
- (Java only) A third getter method for returning the AngularVelocity of the flywheel using a MutableMeasure as a backing field that is set when getAngularVelocity is called. This summarily returns the angularVelocity as just a Measure object. This allows the user of this class to handle unit conversions with less numerical manipulation. Alterations in C++ for this feature were not needed.
Previously, the overload took a span<double>. However, m_inputs and m_outputs store type T, so the function could not be called for any T that does not have an implicit constructor from double.
Modified Java constructors to take a variable number of measurement std devs argument with checks in place to make sure the right amount (or none) are passed into the constructor. All changes passed down to classes utilizing LinearSystemSim.
Removed excess constructors
Removed Java and C++ CurrentDrawAmps method as it doesn't belong in a generic (non electrical) linear system. Kept a non override version in all derived electrical classes.
Also LinearSystemSim has now been made agnostic to electrical systems. Inputs don't have to be voltage. BatteryVoltage clamp function has been pushed down to electrical subclasses.
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
Currently in the entire C API of WPILib we have ~8 different ways of handling strings. The C API actually isn't built for pure C callers (We don't actually have any of those). Instead, they're built for interop between languages like LabVIEW and C# which can talk to C API's directly.
For output parameters, the choice was fairly obvious. An output struct containing a const string pointer and a length makes the most sense. Its easy to use these from most other languages, and doesn't require special null termination handling. Freeing these is also easy, as if you ever receive one of these string structures, theres just a single function call to free it.
Input parameters are a bit more complex. To be used from pure C, and from LabVIEW, a null terminated string is the best in most cases. However, null terminated strings in general have a lot of downsides. Additionally, from LabVIEW there are other considerations around encoding that having a wrapper struct helps make a bit easier. From a language like C#, a wrapper struct is by far the easiest, as custom marshalling can make it trivial to marshal both UTF8 and UTF16 strings down.
The final consideration is its nice to have an identical concept for both input and output. It makes the rules fairly easy to understand.
WPILib will not have any APIs that manipulate a string allocated externally. This means WPI_String can be const, as across the boundary it is always const.
If a WPILib API takes a const WPI_String*, WPILib will not manipulate or attempt to free that string, and that string is treated as an input. It is up to the caller to handle that memory, WPILib will never hold onto that memory longer than the call.
If a WPILib API takes a WPI_String*, that string is an output. WPILib will allocate that API with WPI_AllocateString(), fill in the string, and return to the caller. When the caller is done with the string, they must free it with WPI_FreeString().
If an output struct contains a WPI_String member, that member is considered read only, and should not be explicitly freed. The caller should call the free function for that struct.
If an array of WPI_Strings are returned, each individual string is considered read only, and should not be explicitly freed. The free function for that array should be called by the caller.
If an input struct containing a WPI_String, or an input array of WPI_Strings is passed to WPILib, the individual strings will not be manipulated or freed by WPILib, and the caller owns and should free that memory.
Callbacks also follow these rules. The most common is a callback either getting passed a const WPI_String* or a struct containing a WPI_String. In both of these cases, the callback target should consider these strings read only, and not attempt to free them or manipulate them.
DataLog is now a base class, with DataLogBackgroundWriter being the
background thread version and DataLogWriter being a non-threaded version.
Also split the C header into a separate file to make it more wpiformat friendly.
We now use a wrapper (wpi::print) to catch exceptions since we can't patch
std::print() to not throw when we ultimately migrate to it.
fmtlib and std format/print throw the same exceptions and always have. We previously patched fmt::print() to not throw a write failure exception, but we can't do that for std::print(); wpi::print() is the migration plan.
Unit objects now have a reference to the base unit from which they're derived. Constructing a unit object without specifying a base unit implicitly signifies that it's its own base unit, eg new Angle(null, 1, "Radian", "rad") would be the base angle unit of radians, while new Angle(Radians, 2 * PI, "Rotation", "R") would be a new angle unit based on radians.
This fixes much of the hacky code surrounding the derived unit types Velocity, Per, and Mult, but is a breaking change for any user code that defines custom unit classes or uses the anonymous unit type.
C++ doesn't need this because it supports value types, which are much
cheaper to construct. constexpr is also available to make construction
zero-cost.
Flattens parameter from a `std::optional<std::function<...>>` to just a `std::function<...>`. This is a breaking change but a trivial one for teams to fix.
LTVUnicycleController is a drop-in replacement with better tuning knobs.
The RamseteCommand examples were removed instead of retrofitted with
LTVUnicycleController because we're planning on removing the command
controller classes anyway, so it would be wasted effort. The
SimpleDifferentialDriveSimulation example shows direct
LTVUnicycleController usage.
Uses getUsableSpace in Java, matching how C++ determines available space (C++ calls it available, but they mean the same thing.) This fixes a bug where logs wouldn't get deleted due to incorrect available space detection.
The DataLog thread now also checks if the state was marked as stopped after a call to StartLogFile.
When low on space, a log file won't be created. This is detected as a "deletion", and the DataLog thread will continously try to create a log, fail to do so because of low space, detect it as a "deletion", and do so in a loop.
If there's not enough space, the DataLog will be marked as stopped, preventing this infinite loop. Calls to start() will hit this code path and mark it as stopped again.
LinearSystemId's linear system factories throw on negative feedforward
gains, but SysId can compute the feedback gains just fine in that case.
Now we construct the system manually instead.
Fixes#6423.
On Rio, we simply want to restart the robot program as quickly as possible,
and don't want to risk a hang somewhere that will keep that from happening.
The main downside of this is it won't wait for threads to finish (e.g. data logs won't get a final flush).
Eventually we want to get to a point where we can remove OpenCV from the internals of cscore. The start to doing that is converting the existing CvSource and CvSink methods to RawFrame.
For CvSource, this is 100% a free operation. We can do everything the existing code could have done (with one small exception we can fairly easily fix).
For CvSink, by defaut this change would incur one extra copy, but no extra allocations. A set of direct methods were added to CvSink to add a method to avoid this extra copy.
* Reorder functions so they match between languages
* Copy more complete JavaDocs to C++
* Fix incorrect description for time parameter of
TrapezoidProfile.calculate()
Previously, this used mechanism.m_subsystem.getName(), instead of mechanism.m_name, meaning differently named SysId routines from the same subsystem would clobber each other when logged.
The default state for the DS in the simulated HAL is changed to disconnected.
The FMS view is now only editable in DS disconnected state.
This enables more robot and field-like testing of robot code, as the
alliance color and other parameters start in invalid states and are
only set when the DS connects.
Due to something weird in the FPGA, calling strobeLoad() with a string length of 0 causes both CPUs to spin at 100%, basically shutting down everything else on the robot.
If a 0 length string happens to be passed, just bail out early.
Add "remote close:" to messages coming from the remote end.
Previously it was impossible to tell if the error was on the local side
or communicated by the remote side.
Dynamic structs had a few major issues.
In C++, if the string was the last definition in the schema, attempting to set a string would trigger an assertion. This has been fixed
Setting a string value could truncate the string actually stored in the struct, if the definition was shorter than the string to set.
There was no way to detect if this case occurred. The set string function now returns a bool if the string was fully written or not.
Reading a string that had a value shorter than the schema definition would result in embedded trailing nulls in the string. This would make comparing string equality basically impossible, as those embedded nulls count for the length of the string.
The above truncating didn't take into account UTF8 code points. This means a truncation could happen in the middle of a unicode character. Depending on the language this had different behavior, but unpaired code points are problematic to detect in any case. On the decoding side, detect if a split UTF8 code point has occurred by the writer, and if so just ignore it and treat it as not part of the string. Doing this on the receive side means a newer receive side is all that is needed to fix this, which is generally a better option then requiring all senders to update.
Actual DynamicStruct instances have 0 units tests for them. Added a bunch of unit tests around strings to ensure things work properly.
Currently the analysis portion only supports quasistatic and dynamic,
forward and reverse. Check for anything not matching and remove it,
along with providing diagnostics of what is being loaded.
This avoids needing add redundant JavaDocs to them, and better reflects
how we design our modern classes (the classes modified here were around
with minimal changes since 2008 or so).
This does not deprecate any current functionality, but prepares the way for future deprecation.
The drive classes now accept void(double) functions, which makes them more flexible.
The C++ API ended up a bit more verbose, but the Java API is really concise with method references, which is >80% of our userbase. For example:
`DifferentialDrive drive = new DifferentialDrive(m_leftMotor::set, m_rightMotor::set);`
Lambdas can be passed to interoperate with vendor motor controller APIs that don't have e.g., set(double), so CTRE doesn't have to maintain their WPI_ classes anymore.
MotorControllerGroup was replaced with PWMMotorController.addFollower() for PWM motor controllers. Users of CAN motor controllers should use their vendor's follower functionality.
These are the warnings being disabled:
```
== clang-tidy /__w/allwpilib/allwpilib/wpimath/src/test/native/cpp/DARETest.cpp ==
/__w/allwpilib/allwpilib/wpimath/src/test/native/cpp/DARETest.cpp:51:16: warning: avoid using "_" in test name "NonInvertibleA_ABQR" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
51 | TEST(DARETest, NonInvertibleA_ABQR) {
| ^
/__w/allwpilib/allwpilib/wpimath/src/test/native/cpp/DARETest.cpp:67:16: warning: avoid using "_" in test name "NonInvertibleA_ABQRN" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
67 | TEST(DARETest, NonInvertibleA_ABQRN) {
| ^
/__w/allwpilib/allwpilib/wpimath/src/test/native/cpp/DARETest.cpp:89:16: warning: avoid using "_" in test name "InvertibleA_ABQR" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
89 | TEST(DARETest, InvertibleA_ABQR) {
| ^
/__w/allwpilib/allwpilib/wpimath/src/test/native/cpp/DARETest.cpp:101:16: warning: avoid using "_" in test name "InvertibleA_ABQRN" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
101 | TEST(DARETest, InvertibleA_ABQRN) {
| ^
/__w/allwpilib/allwpilib/wpimath/src/test/native/cpp/DARETest.cpp:118:16: warning: avoid using "_" in test name "FirstGeneralizedEigenvalueOfSTIsStable_ABQR" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
118 | TEST(DARETest, FirstGeneralizedEigenvalueOfSTIsStable_ABQR) {
| ^
/__w/allwpilib/allwpilib/wpimath/src/test/native/cpp/DARETest.cpp:132:16: warning: avoid using "_" in test name "FirstGeneralizedEigenvalueOfSTIsStable_ABQRN" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
132 | TEST(DARETest, FirstGeneralizedEigenvalueOfSTIsStable_ABQRN) {
| ^
/__w/allwpilib/allwpilib/wpimath/src/test/native/cpp/DARETest.cpp:151:16: warning: avoid using "_" in test name "IdentitySystem_ABQR" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
151 | TEST(DARETest, IdentitySystem_ABQR) {
| ^
/__w/allwpilib/allwpilib/wpimath/src/test/native/cpp/DARETest.cpp:163:16: warning: avoid using "_" in test name "IdentitySystem_ABQRN" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
163 | TEST(DARETest, IdentitySystem_ABQRN) {
| ^
/__w/allwpilib/allwpilib/wpimath/src/test/native/cpp/DARETest.cpp:176:16: warning: avoid using "_" in test name "MoreInputsThanStates_ABQR" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
176 | TEST(DARETest, MoreInputsThanStates_ABQR) {
| ^
/__w/allwpilib/allwpilib/wpimath/src/test/native/cpp/DARETest.cpp:188:16: warning: avoid using "_" in test name "MoreInputsThanStates_ABQRN" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
188 | TEST(DARETest, MoreInputsThanStates_ABQRN) {
| ^
/__w/allwpilib/allwpilib/wpimath/src/test/native/cpp/DARETest.cpp:201:16: warning: avoid using "_" in test name "QNotSymmetricPositiveSemidefinite_ABQR" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
201 | TEST(DARETest, QNotSymmetricPositiveSemidefinite_ABQR) {
| ^
/__w/allwpilib/allwpilib/wpimath/src/test/native/cpp/DARETest.cpp:210:16: warning: avoid using "_" in test name "QNotSymmetricPositiveSemidefinite_ABQRN" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
210 | TEST(DARETest, QNotSymmetricPositiveSemidefinite_ABQRN) {
| ^
/__w/allwpilib/allwpilib/wpimath/src/test/native/cpp/DARETest.cpp:220:16: warning: avoid using "_" in test name "RNotSymmetricPositiveDefinite_ABQR" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
220 | TEST(DARETest, RNotSymmetricPositiveDefinite_ABQR) {
| ^
/__w/allwpilib/allwpilib/wpimath/src/test/native/cpp/DARETest.cpp:232:16: warning: avoid using "_" in test name "RNotSymmetricPositiveDefinite_ABQRN" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
232 | TEST(DARETest, RNotSymmetricPositiveDefinite_ABQRN) {
| ^
/__w/allwpilib/allwpilib/wpimath/src/test/native/cpp/DARETest.cpp:245:16: warning: avoid using "_" in test name "ABNotStabilizable_ABQR" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
245 | TEST(DARETest, ABNotStabilizable_ABQR) {
| ^
/__w/allwpilib/allwpilib/wpimath/src/test/native/cpp/DARETest.cpp:254:16: warning: avoid using "_" in test name "ABNotStabilizable_ABQRN" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
254 | TEST(DARETest, ABNotStabilizable_ABQRN) {
| ^
/__w/allwpilib/allwpilib/wpimath/src/test/native/cpp/DARETest.cpp:264:16: warning: avoid using "_" in test name "ACNotDetectable_ABQR" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
264 | TEST(DARETest, ACNotDetectable_ABQR) {
| ^
/__w/allwpilib/allwpilib/wpimath/src/test/native/cpp/DARETest.cpp:273:16: warning: avoid using "_" in test name "ACNotDetectable_ABQRN" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name]
273 | TEST(DARETest, ACNotDetectable_ABQRN) {
| ^
```
This removes a build dependency on the quickbuf generator being available for the build platform.
It's safe to generate Java because the quickbuf version is defined by the project.
C++ protobufs can't be committed because the protoc version must
match the library version (this is a particular issue for cmake builds).
There hasn't been a release in 2.5 years.
There's performance improvements for some NEON instructions, UB fixes, a lot of internal cleanup with the jump from C++11 to C++14, and more constexpr.
This required changing the constant values (e.g. kSize) into functions
(e.g. GetSize()).
Fixed implementations of ForEachNested to be inline (as these are actually
templates).
Also added a ntcore Struct test.
This implements de/serialization for the types that aren't templated (SwerveDriveKinematics) in C++ or where there is no trivial way to go round-trip (Splines) for the messages.
To reduce the need for users to manually perform unit conversions, this allows Measure objects from wpiunits to be passed into most places in wpimath that currently expect doubles in terms of SI units like meters.
For example, users would need to know that unit conversion is required - and what the correct units are. Using units would be more difficult to write code for than just hardcoding a value or using Units.inchesToMeters.
Now, using units has no more developer overhead than using raw numbers.
ProfiledPIDController and ExponentialProfile use current, then goal.
This isn't a breaking change because this overload of calculate() is
new for 2024.
Restarting a stopped log results in creating a new log file with fresh copies of the same start records and schema data records.
Also check to see if the file has been deleted or if the log file exceeds 1.8 GB, and start a new one.
The previous fix didn't handle all cases correctly. Instead, add a new
function to raw_ostream (SetNumBytesInBuffer) to allow always using the
full buffer size, and revamp write_impl to more cleanly handle all
cases.
On Windows, TryWrite will always return 0 if there is a Write in progress. The previous behavior for SendFrames and SendControl just used a normal Write, which caused issues with code that combined these with TrySendFrames. Instead, have SendFrames and SendControl also use TryWrite under the hood if possible, and create write requests if not. The implementation preserves the priority of SendControl against an existing write request with multiple frames.
- Add builtin registry baseline (fixes building locally with msvc builtin vcpkg)
- Add protobuf as an explicit dependency (previously was installed as a dependency of opencv)
- In windows CI, checkout repository before running vcpkg (silences warning that vcpkg.json was not found)
This adds support for two serialization formats for complex data types:
- Protobuf for complex objects with variable length internals that need forward and backward wire compatibility (lower speed, more flexible)
- Raw struct (ByteBuffer-style) for fixed-length objects (higher speed, less flexible)
Deserialization can be done either by creating a new object (for immutable objects) or overwriting the contents of an existing object (for mutable objects).
Implementing classes should provide inner classes that implement the Protobuf or Struct interface (in Java) or specialize the wpi::Protobuf or wpi::Struct struct (in C++). It is possible for classes to implement both. If the class itself does not implement serialization, it's possible for third parties/users to provide an implementation instead.
Uses the Google protobuf implementation for C++ and the QuickBuffers alternative protobuf implementation for Java.
The object was being destroyed due to the error handling path.
Instead, defer to the next loop cycle using a one-shot timer.
Properly handle error return values from Send functions.
Fix UB in accessing one past the end of a vector.
The goal of this addition is to allow LinearSystemId.createDCMotorSystem to use kV and KA instead of the moment of inertia, DCMotor object, and gearing.
Adds overloads for Transform2d() constructor to accept x, y, and heading and for Transform3d() to accept x, y, z and rotation as a shorthand for the normal constructors.
std::remove_if() is destructive--it can assume the removed elements are
not used, but NetworkOutgoingQueue needs them to stay intact to be moved
to a different queue. Use std::stable_partition() instead.
- Utilize TrySend to properly backpressure network traffic
- Split updates into reasonable sized frames using WS fragmentation
- Use WS pings for network aliveness (requires 4.1 protocol revision)
- Measure RTT only at start of connection, rather than periodically
(this avoids them being affected by other network traffic)
- Refactor network queue
- Refactor network ping, ping from server as well
- Improve meta topic performance
- Implement unified approach for network value updates (currently client and server use very different approaches) that respects requested subscriber update frequency
This adds a new protocol version (4.1) due to WS bugs in prior versions.
It takes 30 minutes, and the artifacts aren't used. The combine step
changes so infrequently that it's unlikely to break in PRs, so it's a
net benefit to speed up PR builds.
Putting an early exit if statement at the top instead of wrapping the
whole file contents unbreaks unit test configs, as was discovered for
SysId. It reduces nesting as well.
Unused plugins were removed from the beginnings of files as well.
This takes advantage of the underlying byte-level TryWrite() functionality to minimize blocking behavior and enable higher layers to do things smartly when the network blocks.
Also:
- Fix handling of control packets in middle of fragmented
- Clean up debugging features
In C++ each example is a separate source set, but in Java they were one source set and tested as one with the test task. Example-specific test tasks exist for Java, but they weren't used.
This modifies the test task to exclude the example tests, instead depending on each example's test task. The advantage of this is that each example is tested in a separate environment, so leftover state from one example isn't carried over.
fmtlib uses consteval format string processing, which makes it more
efficient than std::snprintf().
snprintf()s in libuv, mpack, processstarter, and wpigui were left alone.
processstarter uses stdlib only, and wpigui only depends on imgui.
fmt::format_to_n() is analogous to std::format_to_n()
(https://en.cppreference.com/w/cpp/utility/format/format_to_n)
wpi::format_to_n_c_str() is a wrapper which adds the trailing NUL.
Provides an implementation of a XRP-specific plugin that sends binary messages over UDP (to account for the less performant hardware on the XRP).
This plugin leverages the work already done for the WebSocket protocol and does a translation to/from JSON/binary.
CMake's file(DOWNLOAD) function fails silently, leading to an error occurring due to a missing file later in the build. This fails quickly and produces a better error message.
endswith() leaves files out from subdirectories, which means projects
that add new subdirectories won't have those files included when they
probably should be.
FetchContent requires CMake 3.11 (released Mar 28, 2018).
Fixed this warning:
```
CMake Warning (dev) at /usr/share/cmake/Modules/FetchContent.cmake:1316 (message):
The DOWNLOAD_EXTRACT_TIMESTAMP option was not given and policy CMP0135 is
not set. The policy's OLD behavior will be used. When using a URL
download, the timestamps of extracted files should preferably be that of
the time of extraction, otherwise code that depends on the extracted
contents might not be rebuilt if the URL changes. The OLD behavior
preserves the timestamps from the archive instead, but this is usually not
what you want. Update your project to the NEW behavior or specify the
DOWNLOAD_EXTRACT_TIMESTAMP option with a value of true to avoid this
robustness issue.
Call Stack (most recent call first):
imgui/CMakeLists.txt:23 (FetchContent_Declare)
```
Previously this was unlimited, which could result in holding on to a
large amount of memory if the connection got backlogged or a burst of
data transmission occurred.
The following source code changes were required:
* Whitespace changes from spotless
* PMD warning suppressions for utility class tests
* PMD warning rename from "BeanMembersShouldSerialize" to
"NonSerializableClass"
* Declared more class members as final
Destructing either of the multicast objects during process shutdown will result in a crash due to attempting to start a task on the non-existent thread pool.
Solve this by just leaking all the handles upon destruction of the static multicast manager. This won't solve the case where the user statically allocates the object, but solves Java and C access, and most cases wouldn't be statically allocating the service announcer anyway in C++.
Made JNI modifications to expose the faster function, made the API use
the typesafe Matrix API, and synchronized the documentation with C++.
Sped up C++ LTV diff drive test from 20 ms to 15 ms.
Sped up C++ LTV unicycle test from 15 ms to 10 ms.
Both seem to work, but the SDA algorithm is specifically recommended for
solving DAREs as opposed to P-DAREs.
The QR decomposition was replaced with a partial pivoting LU
decomposition at the recommendation of section 2.4 of the paper.
More tests and a separate JNI function for each DARE solver variant were
added.
This avoids allocation overhead on construction. times() was also
rewritten to not allocate any temporary objects.
Getter calls in the C++ Quaternion class were modified for parity.
Current timestamp read code uses FPGA register reads. Through testing,
this read was slower then clock_gettime by about 4-5x. However, another
method of reading the FPGA time is available, using HMB. HMB
is memory mapped IO from RAM to the FPGA. So to code side,
reading the value is just a memory barrier and a memory read.
There is some latency on the write side, so a very small artifical delay
(5us) is added to avoid register reads such as interrupts being ahead
of current timestamps, which could cause issues.
Below is read times for 1000 calls to clock_gettime, register reads and
hmb reads.
```
Clock: Rise 1.72939400 s Fall 1.72990700 s Delta 0.00051300 s
FPGA : Rise 1.72999000 s Fall 1.73429300 s Delta 0.00430300 s
HMB : Rise 1.73466800 s Fall 1.73481900 s Delta 0.00015100 s
```
Also add full HMB struct to HAL for future usage.
15 m/s is about 50 ft/s, which is way above what FRC robots should be
able to achieve. This limit lets us catch user errors from bad unit
conversions immediately instead of the LUT generation in the LTV
controllers hanging for a really long time.
Fixes#5027.
This works around an exit race with wpi::Now() on Rio; it was overridden
to call HAL_GetFPGATime(), which calls chipobject, but on exit, because
there was not a library dependency, the chipobject could be destroyed
prior to wpiutil/wpinet being shut down.
# Background
Unit safety has always been a problem in WPILib. Any value corresponding to a physical measurement, such as current draw or distance traveled, is represented by a bare number with no unit tied to it; it's up to the programmer to know what units they're working and take care to remember that while working on their robot program. This leads to bugs when programmers accidentally mix units without knowing, or measure something (such as a wheel diameter) in one unit and program using another. `wpiunits` is intended to eliminate that class of bugs.
Another source of friction is the controllers and models in `wpimath` that expect all inputs to be in terms of SI units (meter, kilogram, and so on), while most FRC teams are US-based and most commonly use imperial units. wpimath does a good job of noting unit types in method names and argument names; however, it still relies on users properly converting values (and knowing they even have to do so).
# API
There are really only two core classes in this library: `Unit` and `Measure`. A `Unit` represents some dimension like distance or time. `Unit` is subclassed to define specific dimensions (eg `Distance` and `Time`) and those subclasses are instantiated to defined particular units in those dimensions, such as `Meters` and `Feet` being instances of the `Distance` class.
A `Measure` is a value tied to a particular dimension like distance and knows what unit that value is tied to. `Measure` has two implementations - one immutable and one mutable. The `Measure` interface only defines *read-only* operations; any API working with measurements should use the interface. The default implementation is `ImmutableMeasure`, which only implements those read-only operations and is useful for tracking constants. `MutableMeasure` also adds some methods that will allow for mutation of its internal state; this class is intended for use for things like sensors and controllers that track internal state and don't want to allocate new `Measure` objects every time something like `myEncoder.getDistance()` is called. However, the APIs for those methods should still only expose the read-only `Measure` interface so users can't (without casting or reflection) change the internal values.
A `Units` class provides convenient definitions for most of the commonly used unit types, such as `Meters`, `Feet`, and `Milliseconds`. I recommend static importing these units eg `import static edu.wpi.first.units.Units.Meters`) so they can be used like `Meters.of(1.234)` instead of `Units.Meters.of(1.234)`
# Examples
These examples are admittedly contrived. Users shouldn't be interacting much with measure objects themselves, since wpimath and wpilibj classes will be updated to support working with them; users will often just have to take a `Measure` output from one place (such as an encoder) and feed it as input to something else (such as a PID controller or kinematics model)
```java
// Using raw units
Encoder encoder = ...
int kPulsesPerRev = 2048;
double kWheelDiameterMeters = Units.inchesToMeters(6);
double kGearRatio = 10.86;
// always have to remember this encoder will output in meters!
encoder.setDistancePerPulse(kWheelDiameterMeters * Math.PI / (kGearRatio * kPulsesPerRev));
Command driveDistance(double distance) {
// have to know the distance argument needs to be in meters!
return run(this::driveStraight).until(() -> encoder.getDistance() >= distance);
}
// Oops! This will go 16 feet, not 5!
Command driveFiveFeet = driveDistance(5);
Command driveOneMeter = driveDistance(1);
```
```java
// Using wpiunits
Encoder encoder = ...
int kPulsesPerRev = 2048;
Measure<Distance> kWheelDiameter = Inches.of(6);
double kGearRatio = 10.86;
encoder.setDistancePerPulse(kWheelDiameter.times(Math.PI).divide(kGearRatio * kPulsesPerRev));
Command driveDistance(Measure<Distance> distance) {
// Measure#gte automatically handles unit conversions
return run(this::driveStraight).until(() -> encoder.getDistance().gte(distance));
}
// Users HAVE to be explicit about their units
Command driveFiveFeet = driveDistance(Feet.of(5));
Command driveOneMeter = driveDistance(Meters.of(1));
```
```java
SmartDashboard.putNumber("Temperature (C)", pdp.getTemperature().in(Celsius));
SmartDashboard.putNumber("Temperature (F)", pdp.getTemperature().in(Fahrenheit));
```
```java
var InchSecond = Inch.mult(Second); // new combined unit types can be user-defined
var InchPerSecond = Inch.per(Second);
PIDController<Distance, ElectricPotential> heightController = new PIDController<>(
/* kP */ Volts.of(0.2).per(Inch),
/* kI */ Volts.of(0.002).per(InchSecond),
/* kD */ Volts.of(0.008).per(InchPerSecond)
);
var elevatorTop = Feet.of(4).plus(Inches.of(6.125));
elevatorMotor.setVoltage(heightController.calculate(encoder.getDistance(), elevatorTop));
```
Many teams have issues trying to read the DS too early. By switching to an optional, we cause teams to check 2 things. Either 1) they explicitly check, and their code is correct, or 2) they just read .value() and their code reboots in a loop. However, because the DS will eventually connect, this 2nd case is ok, and should theoretically be undetectable on the field.
The problem is that you have to use a different pkg-config file if you want to use a static variant of libuv, but the buildsystem should not care which variant of libuv should be used. This is not a problem with the cmake config.
Accelerometer is hyper-specific to ADXL accelerometers, and Gyro is
less useful now that 3D IMUs are prevalent, and if those IMUs want to
support the Gyro interface, they also need to provide a way to set the
axis used for the Gyro interface, which is confusing. Higher-order
functions (e.g., lambdas) are a more flexible interface boundary than
interfaces, but they didn't exist when these interfaces were
created.
Taking the joystick inputs from -1 to 1, multiply them by the max speed (as defined in Constants.java) to get the target speed, rather than using the unitless raw joystick inputs.
Moves all CommandBase functionality into Command and deprecates CommandBase for removal.
Moves all SubsystemBase functionality into Subsystem and deprecates SubsystemBase for removal.
Adds a function to CommandScheduler to remove all registered Subsystems.
Setting one will set the others, like it does in real hardware.
Add tests for boundary conditions and conversions.
Update PWM sendable implementation to include all forms.
Fixes#5264Fixes#3606
This method is used to check if the given value matches an expected value within a certain tolerance.
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
Co-authored-by: Ryan Blue <ryanzblue@gmail.com>
Adds a reset method where teams can pass in module headings for the kinematics object to use if it gets an all-zero ChassisSpeeds while converting ChassisSpeeds to module states. Also removes internal states array, replacing it with an internal headings array.
```
CMake Warning (dev) at CMakeLists.txt:14 (project):
cmake_minimum_required() should be called prior to this top-level project()
call. Please see the cmake-commands(7) manual for usage documentation of
both commands.
This warning is for project developers. Use -Wno-dev to suppress it.
```
I timed the DARE unit tests, and the new solver is 0 to 100% faster in
all cases (that is, it's at least as fast as Drake's and up to 2x faster
in some cases).
The new solver is also much simpler, takes less time to compile, and
drops the libwpimath.so size from 325 MB to 301 MB.
I think most of the compilation time is coming from the eigenvalue
decompositions used to enforce argument preconditions.
HAL_SetAddressableLEDBitTiming swapped high and low timings for whatever
was written to it. This fixes that bug.
Additionally, the API has been updated to take high time first, and then
low time. This is due to this being the physical data format, so having
the API match is clearer.
Additionally, update the docs with the defaults.
Was logging relative to cached value rather than previously logged value.
Was also logging cached value instead of current loop value.
C++ implementation is correct.
There can be duplicate addresses coming out of name resolution; if we
already started connecting to an address, don't start another connection
attempt.
The algorithm being used for scanning outgoing messages was O(n^2)
because it did a full linear search and then appended. This scan is
performed for each client. If there is a burst of outgoing changes, the
outgoing queue can get quite deep all at once and this scan can be very
slow. Replacing with a map fixes this.
Previously, the comment would end at any quote, escaped or unescaped. This allows UnescapeCString to handle the unescaping of quotes and properly end the string.
There's a spec difference between NT4 and datalog for integers; NT4 uses
"int", datalog uses "int64". We were using "int" for datalog as well.
Also add backwards compatibility support to datalogtool for treating
"int" as "int64".
There's no signal from NetComm as to when it is valid, and 1 second
seems to be marginal. Increase to 6 seconds for just DS, 5 seconds for
FMS attached.
HAL_GetRuntimeType used to be a free call before the roboRIO2 was added. However, nLoadOut::getTargetClass() is not a free call, and it may hit the IPC layer. Cache this value so it is not called every time.
This makes it possible to mock the timestamp for wpimath without affecting the rest of the library.
Co-authored-by: Peter Johnson <johnson.peter@gmail.com>
@@ -15,6 +15,8 @@ Steps to reproduce the behavior:
1. ...
2. ...
- Link to code:
**Expected behavior**
A clear and concise description of what you expected to happen.
@@ -22,10 +24,8 @@ A clear and concise description of what you expected to happen.
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- WPILib Version: [e.g. 2021.3.1]
- OS: [e.g. Windows 11]
-Java version [e.g. 1.10.2]
- C++ version [e.g. 17]
-Project Information: [In Visual Studio Code, press the WPILib button and choose WPILib: Open Project Information. Press the copy button and paste the data here. If not using VS Code, please include WPILib version, Gradle version, Java version, C++ version (if applicable), and any third party libraries and versions]
body: 'This PR modifies commands. Please open a corresponding PR in [Python Commands](https://github.com/robotpy/robotpy-commands-v2/) and include a link to this PR.'
@@ -12,11 +12,11 @@ So you want to contribute your changes back to WPILib. Great! We have a few cont
## General Contribution Rules
- Everything in the library must work for the 3000+ teams that will be using it.
- Everything in the library must work for the 4000+ teams that will be using it.
- We need to be able to maintain submitted changes, even if you are no longer working on the project.
- Tool suite changes must be generally useful to a broad range of teams
- Excluding bug fixes, changes in one language generally need to have corresponding changes in other languages.
- Some features, such the addition of C++11 for WPILibC or Functional Interfaces for WPILibJ, are specific to that version of WPILib only.
- Some features, such the addition of C++23 for WPILibC or Functional Interfaces for WPILibJ, are specific to that version of WPILib only. New language features added to C++ must be wrappable in Python for [RobotPy](https://github.com/robotpy).
- Substantial changes often need to have corresponding LabVIEW changes. To do this, we will work with NI on these large changes.
- Changes should have tests.
- Code should be well documented.
@@ -27,7 +27,8 @@ So you want to contribute your changes back to WPILib. Great! We have a few cont
- Bug reports and fixes
- We will generally accept bug fixes without too much question. If they are only implemented for one language, we will implement them for any other necessary languages. Bug reports are also welcome, please submit them to our GitHub issue tracker.
- While we do welcome improvements to the API, there are a few important rules to consider:
- Features must be added to both WPILibC and WPILibJ, with rare exceptions.
- Features must be added to Java (WPILibJ), C++ (WPILibC), with rare exceptions.
- Most of Python (RobotPy) is created by wrapping WPILibC with pybind11 via robotpy-build. However, new features to the command framework should also be submitted to [robotpy-commands-v2](https://github.com/robotpy/robotpy-commands-v2) as the command framework is reimplemented in Python.
- During competition season, we will not merge any new feature additions. We want to ensure that the API is stable during the season to help minimize issues for teams.
- Ask about large changes before spending a bunch of time on them! You can create a new issue on our GitHub tracker for feature request/discussion and talk about it with us there.
- Features that make it easier for teams with less experience to be more successful are more likely to be accepted.
@@ -79,6 +80,8 @@ xₖ₊₁ = Axₖ + Buₖ
Changes should be submitted as a Pull Request against the main branch of WPILib. For most changes, commits will be squashed upon merge. For particularly large changes, multiple commits are ok, but assume one commit unless asked otherwise. We may ask you to break a PR into multiple standalone PRs or commits for rebase within one PR to separate unrelated changes. No change will be merged unless it is up to date with the current main branch. We do this to make sure that the git history isn't too cluttered.
During the build season, breaking changes or other changes intended for the next season can be created as a pull request against the development branch of WPILib. After the season is over, the changes in the development branch will be merged into main.
### Merge Process
When you first submit changes, GitHub Actions will attempt to run `./gradlew check` on your change. If this fails, you will need to fix any issues that it sees. Once Actions passes, we will begin the review process in more earnest. One or more WPILib team members will review your change. This will be a back-and-forth process with the WPILib team and the greater community. Once we are satisfied that your change is ready, we will allow our hosted instance to test it. This will run the full gamut of checks, including integration tests on actual hardware. Once all tests have passed and the team is satisfied, we will merge your change into the WPILib repository.
@@ -4,17 +4,22 @@ This article contains instructions on building projects using a development buil
**Note:** This only applies to Java/C++ teams.
> [!WARNING]
> **There are no stability or compatibility guarantees for builds outside of [tagged releases](https://github.com/wpilibsuite/allwpilib/releases). Changes may not be fully documented. Use them at your own risk!**
>
> Development builds may be non-functional between the end of the season and the start of beta testing. Development builds are also likely to be incompatible with vendor libraries during this time.
## Development Build
Development builds are the per-commit build hosted every time a commit is pushed to the [allwpilib](https://github.com/wpilibsuite/allwpilib/) repository. These builds are then hosted on [artifactory](https://frcmaven.wpi.edu/artifactory/webapp/#/home).
To build a project using a development build, find the build.gradle file and open it. Then, add the following code below the plugin section and replace YEAR with the year of the development version. It is also necessary to use a 2023 GradleRIO version, ie `2023.0.0-alpha-1`
To build a project using a development build, find the build.gradle file and open it. Then, add the following code below the plugin section and replace YEAR with the year of the development version. It is also necessary to use a 2024 GradleRIO version, ie `2024.0.0-alpha-1`
```groovy
wpi.maven.useLocal=false
wpi.maven.useDevelopment=true
wpi.versions.wpilibVersion='YEAR.+'
wpi.versions.wpimathVersion='YEAR.+
wpi.versions.wpimathVersion='YEAR.+'
```
The top of your ``build.gradle`` file should now look similar to the code below. Ignore any differences in versions.
@@ -23,13 +28,13 @@ Java
```groovy
plugins {
id "java"
id "edu.wpi.first.GradleRIO" version "2023.0.0-alpha-1"
id "edu.wpi.first.GradleRIO" version "2024.0.0-alpha-1"
}
wpi.maven.useLocal = false
wpi.maven.useDevelopment = true
wpi.versions.wpilibVersion = '2023.+'
wpi.versions.wpimathVersion = '2023.+'
wpi.versions.wpilibVersion = '2024.+'
wpi.versions.wpimathVersion = '2024.+'
```
C++
@@ -37,13 +42,13 @@ C++
plugins {
id "cpp"
id "google-test-test-suite"
id "edu.wpi.first.GradleRIO" version "2023.0.0-alpha-1"
id "edu.wpi.first.GradleRIO" version "2024.0.0-alpha-1"
}
wpi.maven.useLocal = false
wpi.maven.useDevelopment = true
wpi.versions.wpilibVersion = '2023.+'
wpi.versions.wpimathVersion = '2023.+'
wpi.versions.wpilibVersion = '2024.+'
wpi.versions.wpimathVersion = '2024.+'
```
### Development Build Documentation
@@ -59,7 +64,7 @@ Java
```groovy
plugins {
id "java"
id "edu.wpi.first.GradleRIO" version "2023.0.0-alpha-1"
id "edu.wpi.first.GradleRIO" version "2024.0.0-alpha-1"
}
wpi.maven.useLocal = false
@@ -73,7 +78,7 @@ C++
plugins {
id "cpp"
id "google-test-test-suite"
id "edu.wpi.first.GradleRIO" version "2023.0.0-alpha-1"
id "edu.wpi.first.GradleRIO" version "2024.0.0-alpha-1"
This repo contains a myRobot project built in way to do full project development without needing to do a full publish into GradleRIO. These also only require building the minimum amount of binaries for the roboRIO, so the builds are much faster as well.
The setup only works if the roboRIO is USB connected. If an alternate IP address is preferred, the `address` block in myRobot\build.gradle can be changed to point to another address.
The following 3 tasks can be used for deployment:
* `:myRobot:deployShared` deploys the C++ project using shared dependencies. Prefer this one for most C++ development.
* `:myRobot:deployStatic` deploys the C++ project with all dependencies statically linked.
* `:myRobot:deployJava` deploys the Java project and all required dependencies. Also installs the JRE if not currently installed.
Deploying any of these to the roboRIO will disable the current startup project until it is redeployed.
From here, ssh into the roboRIO using the `lvuser` account and run `frcRunRobot.sh` (It's in path).
See the [developerRobot](developerRobot/README.md) subproject.
Currently the 3rd party deps are imgui, opencv, and google test
Currently the 3rd party deps are imgui, opencv, google test, libssh, and apriltaglib
For publishing these dependencies, the version needs to be manually updated in the publish.gradle file of their respective repository.
Then, in the azure build for the dependency you want to build for, manually start a pipeline build (As of current, this is the `Run Pipeline` button).
@@ -18,10 +18,10 @@ Desktop tools publish to the development repo on every push to main. To publish
## Publishing VS Code
Before publishing, make sure to update the gradlerio version in `vscode-wpilib/resources/gradle/version.txt` Also make sure the gradle wrapper version matches the wrapper required by gradlerio.
Upon pushing a tag, a release will be built, and the files will be uploaded to the releases on GitHub. For publishing to the marketplace, you need a Microsoft account and to be added as a maintainer.
Upon pushing a tag, a release will be built, and the files will be uploaded to the releases on GitHub.
## Publishing GradleRIO
Before publishing, make sure to update the version in build.gradle. Publishing must happen locally, using the command `./gradlew publishPlugin`. This does require your API key for publishing to be set.
## Building the installer
Update the GradleRIO version in gradle.properties, and in the scripts folder in vscode, update the vscode extension. Then push, it will build the installer on azure.
Update the GradleRIO version in gradle.properties, and in the scripts folder in vscode, update the vscode extension. To publish a release build, upload a new tag, and a release will automatically be built and published to artifactory and cloudflare.
@@ -16,7 +16,7 @@ We provide two base types of artifacts.
The first types are Java artifacts. These are usually published as `jar` files. Usually, the actual jar file is published with no classifier. The sources are published with the `-sources` classifier, and the javadocs are published with the `-javadoc` classifier.
The second types are native artifacts. These are usually published as `zip` files (except for the `JNI` artifact types, which are `jar` files. See below for information on this). The `-sources` and `-headers` classifiers contain the sources and headers respecively for the library. Each artifact also contains a classifier for each platform we publish. This platform is in the format `{os}{arch}`. The platform artifact only contains the binaries for a specific platform. In addition, we provide a `-all` classifier. This classifer combines all of the platform artifacts into a single artifact. This is useful for tools that cannot determine what version to use during builds. However, we recommend using the platform specific classifier when possible. Note that the binary artifacts never contain the headers, you always need the `-headers` classifier to get those.
The second types are native artifacts. These are usually published as `zip` files (except for the `JNI` artifact types, which are `jar` files. See below for information on this). The `-sources` and `-headers` classifiers contain the sources and headers respectively for the library. Each artifact also contains a classifier for each platform we publish. This platform is in the format `{os}{arch}`. The platform artifact only contains the binaries for a specific platform. In addition, we provide a `-all` classifier. This classifier combines all of the platform artifacts into a single artifact. This is useful for tools that cannot determine what version to use during builds. However, we recommend using the platform specific classifier when possible. Note that the binary artifacts never contain the headers, you always need the `-headers` classifier to get those.
## Artifact Names
@@ -145,6 +145,11 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
* wpinet
* wpiutil
* wpiunits
* apriltag
* wpiutil
* wpimath
### Third Party Artifacts
@@ -152,6 +157,7 @@ This repository provides the builds of the following third party software.
All artifacts are based at `edu.wpi.first.thirdparty.frcYEAR` in the repository.
WPILib is normally built with Gradle, however for some systems, such as Linux based coprocessors, Gradle doesn't work correctly, especially if cscore is needed, which requires OpenCV. Furthermore, the CMake build can be used for C++ development because it provides better build caching compared to Gradle. We provide the CMake build for these cases. Although it is supported on Windows, these docs will only go over Linux builds.
WPILib is normally built with Gradle, however for some systems, such as Linux based coprocessors, Gradle doesn't work correctly, especially if cscore is needed, which requires OpenCV. Furthermore, the CMake build can be used for C++ development because it provides better build caching compared to Gradle. We provide the CMake build for these cases. Although macOS is supported, these docs will only go over Linux and Windows builds, but should mostly work for macOS as well. If you are stuck, you can look at the GitHub workflows for any OS to see how it works.
## Libraries that get built
*wpiutil
* ntcore
* cscore
*apriltag
* cameraserver
*hal
*wpilib
*halsim
*cscore
*hal (simulation HAL only)
*ntcore
* romiVendordep
* simulation extensions
* wpigui
* wpilib (wpilibc, wpilibj, and myRobot)
* wpilibNewCommands
* wpimath
* wpinet
* wpiunits
* wpiutil
* xrpVendordep
By default, all libraries except for the HAL and WPILib get built with a default CMake setup. The libraries are built as shared libraries, and include the JNI libraries as well as building the Java JARs.
## GUI apps that get built
* datalogtool
* glass
* outlineviewer
* roborioteamnumbersetter
* sysid
* halsim_gui (if simulation extensions are enabled)
By default, all libraries get built with a default CMake setup. The libraries are built as shared libraries, and include the JNI libraries as well as building the Java JARs. Data Log Tool and the roboRIO Team Number Setter are only built if libssh is available.
## Prerequisites
The most common prerequisite is going to be OpenCV. OpenCV needs to be findable by CMake. On systems like the Jetson, this is installed by default. Otherwise, you will need tobuild OpenCV from source and install it.
The protobuf library and compiler are needed for protobuf generation.
In addition, if you want JNI and Java, you will need a JDK of at least version 11 installed. In addition, you need a `JAVA_HOME` environment variable set properly and set to the JDK directory.
OpenCV needs to be findable by CMake. On systems like the Jetson, this is installed by default. Otherwise, you will need to build OpenCV from source and install it.
If you want JNI and Java, you will need a JDK of at least version 17 installed. In addition, you need a `JAVA_HOME` environment variable set properly and set to the JDK directory.
If you are building with unit tests or simulation modules, you will also need an Internet connection for the initial setup process, as CMake will clone google-test and imgui from GitHub.
@@ -27,32 +43,38 @@ If you are building with unit tests or simulation modules, you will also need an
The following build options are available:
*`WITH_JAVA` (ON Default)
* This option will enable Java and JNI builds. If this is on, `WITH_SHARED_LIBS` must be on. Otherwise CMake will error.
*`WITH_SHARED_LIBS` (ON Default)
* This option will cause cmake to build static libraries instead of shared libraries. If this is off, `WITH_JAVA` must be off. Otherwise CMake will error.
*`BUILD_SHARED_LIBS` (ON Default)
* This option will cause CMake to build static libraries instead of shared libraries. If this is off, `WITH_JAVA` must be off. Otherwise CMake will error.
*`WITH_CSCORE` (ON Default)
* This option will cause cscore to be built. Turning this off will implicitly disable cameraserver, the hal and wpilib as well, irrespective of their specific options. If this is off, the OpenCV build requirement is removed.
* This option will cause cscore to be built. Turning this off will implicitly disable cameraserver. If this is off, the OpenCV build requirement is removed.
*`WITH_EXAMPLES` (OFF Default)
* This option will build C++ examples.
*`WITH_GUI` (ON Default)
* This option will build GUI items. If this is off, and `WITH_SIMULATION_MODULES` is on, the simulation GUI will not be built.
*`WITH_JAVA` (ON Default)
* This option will enable Java and JNI builds. If this is on, `BUILD_SHARED_LIBS` must be on. Otherwise CMake will error.
*`WITH_JAVA_SOURCE` (`WITH_JAVA` Default)
* This option will build Java source JARs for each enabled Java library. This does not require `WITH_JAVA` to be on, allowing source JARs to be built without the compiled JARs if desired.
*`WITH_NTCORE` (ON Default)
* This option will cause ntcore to be built. Turning this off will implicitly disable wpinet and wpilib as well, irrespective of their specific options.
* This option will cause ntcore to be built. Turning this off will implicitly disable wpinet, and will cause an error if `WITH_WPILIB` is enabled.
*`WITH_SIMULATION_MODULES` (ON Default)
* This option will build simulation modules.
*`WITH_TESTS` (ON Default)
* This option will build C++ unit tests. These can be run via `ctest -C <config>`, where `<config>` is the build configuration, e.g. `Debug` or `Release`.
*`WITH_WPILIB` (ON Default)
* This option will build the HAL and wpilibc/j during the build. The HAL is the simulation HAL, unless the external HAL options are used. The CMake build has no capability to build for the roboRIO.
*`WITH_WPIMATH` (ON Default)
* This option will build the wpimath library. This option must be on to build wpilib.
*`WITH_WPILIB` (ON Default)
* This option will build the hal and wpilibc/j during the build. The HAL is the simulator hal, unless the external hal options are used. The cmake build has no capability to build for the RoboRIO.
*`WITH_EXAMPLES` (ON Default)
* This option will build C++ examples.
*`WITH_TESTS` (ON Default)
* This option will build C++ unit tests. These can be run via `make test`.
*`WITH_GUI` (ON Default)
* This option will build GUI items.
*`WITH_SIMULATION_MODULES` (ON Default)
* This option will build simulation modules, including wpigui and the HALSim plugins.
*`WITH_WPIUNITS` (ON Default)
* This option will build the wpiunits library. This option must be on to build the Java wpimath library and requires `WITH_JAVA` to also be on.
*`WITH_EXTERNAL_HAL` (OFF Default)
* TODO
* This option will build wpilib with an externally built HAL.
*`EXTERNAL_HAL_FILE`
*TODO
*Set this option to the CMake File of the externally built HAL. NOTE: set it to the file itself, not the folder the file is located in!
*`OPENCV_JAVA_INSTALL_DIR`
* Set this option to the location of the archive of the OpenCV Java bindings (it should be called opencv-xxx.jar, with the x'es being version numbers). NOTE: set it to the LOCATION of the file, not the file itself!
*`NO_WERROR` (OFF Default)
* This option will disable the `-Werror` compilation flag for non-MSVC builds.
## Build Setup
@@ -66,24 +88,28 @@ cmake path/to/allwpilib/root
If you want to change any of the options, add `-DOPTIONHERE=VALUE` to the `cmake` command. This will check for any dependencies. If everything works properly this will succeed. If not, please check out the troubleshooting section for help.
If you want, you can also use `ccmake` in order to visually set these properties as well. [Here](https://cmake.org/cmake/help/v3.0/manual/ccmake.1.html) is the link to the documentation for that program.
If you want, you can also use `ccmake` in order to visually set these properties as well. [Here](https://cmake.org/cmake/help/v3.0/manual/ccmake.1.html) is the link to the documentation for that program. On Windows, you can use `cmake-gui` instead.
Note that if you are cross-compiling, you will need to override the protobuf options manually to point to the libraries for the target platform. Leave the protoc binary location as the path to the binary for the host platform, since protoc needs to execute on the host platform.
## Building
Once you have cmake setup. run `make` from the directory you configured CMake in. This will build all libraries possible. If you have a multicore system, we recommend running `make` with multiple jobs. The usual rule of thumb is 1.5x the number of cores you have. To run a multiple job build, run the following command with x being the number of jobs you want.
Once you have CMake setup. run `cmake --build .` from the directory you configured CMake in. This will build all libraries possible. We recommend running `cmake --build .` with multiple jobs. For allwpilib, a good rule of thumb is one worker for every 2 GB of available RAM. To run a multiple job build, run the following command with x being the number of jobs you want.
```
make -jx
cmake --build . --parallel x
```
The `ninja` generator is also supported, and can be enabled by passing `-GNinja` to the initial `cmake` command.
Note: wpimath takes gigabytes of RAM to compile. Because of this, the compilers may crash while building due to a lack of memory and your computer may slow down. If you have less than 16 GB of RAM available, you may want to consider building it separately first by adding `--target wpimath` and running it with ~3 jobs to prevent crashes from running out of memory.
To build with a certain configuration, like `Debug` or `Release`, add `--config <config>`, where `<config>` is the name of the configuration you want to build with.
## Installing
After build, the easiest way to use the libraries is to install them. Run the following command to install the libraries. This will install them so that they can be used from external cmake projects.
After build, the easiest way to use the libraries is to install them. Run the following command to install the libraries. This will install them so that they can be used from external CMake projects.
```
sudo make install
sudo cmake --build . --target install
```
## Using the installed libraries for C++.
@@ -92,8 +118,8 @@ Using the libraries from C++ is the easiest way to use the built libraries.
To do so, create a new folder to contain your project. Add the following code below to a `CMakeLists.txt` file in that directory.
```
cmake_minimum_required(VERSION 3.5)
```cmake
cmake_minimum_required(VERSION 3.11)
project(vision_app)# Project Name Here
find_package(wpilibREQUIRED)
@@ -102,7 +128,7 @@ add_executable(my_vision_app main.cpp) # executable name as first parameter
If you are using them, `wpilibc` and `hal` should be added before the `cameraserver` declaration in the `target_link_libraries` function.
If you want to use other libraries or are building a robot program, `wpilibc` and `hal` should be added in the `target_link_libraries` function, along with any other libraries you plan on using, e.g. `wpimath`.
Add a `main.cpp` file to contain your code, and create a build folder. Move into the build folder, and run
@@ -110,11 +136,43 @@ Add a `main.cpp` file to contain your code, and create a build folder. Move into
cmake /path/to/folder/containing/CMakeLists
```
After that, run `make`. That will create your executable. Then you should be able to run `./my_vision_app` to run your application.
After that, run `cmake --build .`. That will create your executable. Then you should be able to run `./my_vision_app` to run your application.
## Using the installed libraries for Java
TODO
Using the built JARs is move involved than using the C++ libraries, but mostly consists of adding the correct directories to PATH.
Add the directory where the JARs are located (e.g, `/usr/local/java`) to PATH. If you are on Windows, you also need to add the `lib`, `bin`, and `share` directories to PATH. Then, create a new folder to contain your project. Add the following code below to a `CMakeLists.txt` file in that directory.
```cmake
cmake_minimum_required(VERSION3.11)
project(robot)
find_package(JavaREQUIREDCOMPONENTSDevelopment)
include(UseJava)
find_package(wpilibREQUIRED)
find_jar(opencvJaropencv-xxxPATHSENVPATH)# Change to OpenCV version
file(GLOB_RECURSEJAVA_SOURCES*.java)
# If you want Gradle compatibility or you are using one of the templates/examples, comment out the above line and uncomment this line instead:
This includes all the built JARs except for the vendordeps. If you are not using a JAR/library, you may remove it.
Add a `Main.java` file to contain your code, and create a build folder. Move into the build folder, and run
```
cmake /path/to/folder/containing/CMakeLists
```
After that, run `cmake --build .` to create your JAR file. To execute the JAR file, you need to include the wpilib JARs and your JAR in the classpath, and execute your Java program's entry point. If you are using cscore or cameraserver, you also need to include the path to the OpenCV JAR. If you built it from source, it will be in your OpenCV build directory. If it's installed on the system, CMake may find it from PATH, but you will likely need to locate the JAR and manually give CMake the JAR directory. If you are on Linux, you will also need to add the path of the libraries to `LD_LIBRARY_PATH`. This can be done by prepending `LD_LIBRARY_PATH=/path/to/libraries` to the Java command. If you need to add more paths, separate them with colons. The final command should look like `java -cp "robot.jar:/path/to/library_jars/*" main.package.Main`, using a semicolon to separate paths instead of a colon if you are on Windows. If you are on Linux, the final command should look more like `LD_LIBRARY_PATH=/path/to/libraries java -cp robot.jar:/path/to/library_jars/* main.package.Main`.
## Using vendordeps
Vendordeps are not included as part of the `wpilib` CMake package. However, if you want to use a vendordep, you need to use `find_package(VENDORDEP)`, where `VENDORDEP` is the name of the vendordep (case-sensitive), like `xrpVendordep` or `romiVenderdep`. Note that wpilibNewCommands, while a vendordep in normal robot projects, is not built as a vendordep in CMake, and is instead included as part of the `wpilib` CMake package. After you used `find_package`, you can reference the vendordep library like normal, either by using `target_link_libraries` for C++ or `add_jar` for Java.
## Troubleshooting
Below are some common issues that are run into when building.
@@ -141,7 +199,7 @@ CMake Error at cscore/CMakeLists.txt:3 (find_package):
installed.
```
If you get that, you need make sure opencv was installed, and then reattempt to configure. If that doesn't work, set the `OpenCV_DIR` variable to the directory where you built OpenCV.
If you get that, you need make sure OpenCV was installed, and then reattempt to configure. If that doesn't work, set the `OpenCV_DIR` variable to the directory where you built OpenCV.
#### Missing Java
@@ -155,3 +213,18 @@ CMake Error at /usr/share/cmake-3.5/Modules/FindPackageHandleStandardArgs.cmake:
If this happens, make sure you have a JDK of at least version 8 installed, and that your JAVA_HOME variable is set properly to point to the JDK.
In addition, if you do not need Java, you can disable it with `-DWITH_JAVA=OFF`.
#### Java: Can't find dependent libraries
If one of the libraries can't be found, you will get an error similar to this one:
```
java.io.IOException: wpiHaljni could not be loaded from path or an embedded resource.
If you get this error, that's usually an indication that not all your libraries are in your PATH. The two libraries that should be in your PATH are OpenCV and protobuf. If the error is coming from cscore, it's likely you're missing OpenCV. Otherwise, it's likely you're missing protobuf.
Note that Linux will not have this specific type of error, as it will usually tell you the dependent library you are missing. In that case, you most likely need to add the library to `LD_LIBRARY_PATH`.
- [Running examples in simulation](#running-examples-in-simulation)
- [Publishing](#publishing)
- [Structure and Organization](#structure-and-organization)
- [Contributing to WPILib](#contributing-to-wpilib)
- [Contributing to WPILib](./CONTRIBUTING.md)
## WPILib Mission
The WPILib Mission is to enable FIRST Robotics teams to focus on writing game-specific software rather than focusing on hardware details - "raise the floor, don't lower the ceiling". We work to enable teams with limited programming knowledge and/or mentor experience to be as successful as possible, while not hampering the abilities of teams with more advanced programming capabilities. We support Kit of Parts control system components directly in the library. We also strive to keep parity between major features of each language (Java, C++, and NI's LabVIEW), so that teams aren't at a disadvantage for choosing a specific programming language. WPILib is an open source project, licensed under the BSD 3-clause license. You can find a copy of the license [here](LICENSE.md).
The WPILib Mission is to enable FIRST Robotics teams to focus on writing game-specific software rather than focusing on hardware details - "raise the floor, don't lower the ceiling". We work to enable teams with limited programming knowledge and/or mentor experience to be as successful as possible, while not hampering the abilities of teams with more advanced programming capabilities. We support Kit of Parts control system components directly in the library. We also strive to keep parity between major features of each language (Java, C++, Python, and NI's LabVIEW), so that teams aren't at a disadvantage for choosing a specific programming language. WPILib is an open source project, licensed under the BSD 3-clause license. You can find a copy of the license [here](LICENSE.md).
# Quick Start
@@ -40,11 +41,11 @@ Using Gradle makes building WPILib very straightforward. It only has a few depen
- Note that the JRE is insufficient; the full JDK is required
- On Ubuntu, run `sudo apt install openjdk-11-jdk`
- On Windows, install the JDK 11 .msi from the link above
- On macOS, install the JDK 11 .pkg from the link above
- On Ubuntu, run `sudo apt install openjdk-17-jdk`
- On Windows, install the JDK 17 .msi from the link above
- On macOS, install the JDK 17 .pkg from the link above
- C++ compiler
- On Linux, install GCC 11 or greater
- On Windows, install [Visual Studio Community 2022](https://visualstudio.microsoft.com/vs/community/) and select the C++ programming language during installation (Gradle can't use the build tools for Visual Studio)
@@ -59,9 +60,9 @@ On macOS ARM, run `softwareupdate --install-rosetta`. This is necessary to be ab
## Setup
Clone the WPILib repository and follow the instructions above for installing any required tooling.
Clone the WPILib repository and follow the instructions above for installing any required tooling. The build process uses versioning information from git. Downloading the source is not sufficient to run the build.
See the [styleguide README](https://github.com/wpilibsuite/styleguide/blob/main/README.md) for wpiformat setup instructions. We use clang-format 14.
See the [styleguide README](https://github.com/wpilibsuite/styleguide/blob/main/README.md) for wpiformat setup instructions.
## Building
@@ -87,9 +88,24 @@ If opening from a fresh clone, generated java dependencies will not exist. Most
`./gradlew build` builds _everything_, which includes debug and release builds for desktop and all installed cross compilers. Many developers don't need or want to build all of this. Therefore, common tasks have shortcuts to only build necessary components for common development and testing tasks.
`./gradlew testDesktopCpp` and `./gradlew testDesktopJava` will build and run the tests for `wpilibc` and `wpilibj` respectively. They will only build the minimum components required to run the tests.
`./gradlew testDesktopCpp` and `./gradlew testDesktopJava` will build and run the tests for `wpilibc` and `wpilibj` respectively. They will only build the minimum components required to run the tests.`./gradlew testDesktop` will run both `testDesktopJava` and `testDesktopCpp`.
`testDesktopCpp` and`testDesktopJava` tasks also exist for the projects `wpiutil`, `ntcore`, `cscore`, `hal``wpilibNewCommands` and `cameraserver`. These can be ran with `./gradlew :projectName:task`.
`testDesktopCpp`,`testDesktopJava`, and `testDesktop` tasks also exist for the following projects:
-`apriltag`
-`cameraserver`
-`cscore`
-`hal`
-`ntcore`
-`wpilibNewCommands`
-`wpimath`
-`wpinet`
-`wpiunits`
-`wpiutil`
-`romiVendordep`
-`xrpVendordep`
These can be ran with `./gradlew :projectName:task`.
`./gradlew buildDesktopCpp` and `./gradlew buildDesktopJava` will compile `wpilibcExamples` and `wpilibjExamples` respectively. The results can't be ran, but they can compile.
@@ -119,7 +135,7 @@ Once a PR has been submitted, formatting can be run in CI by commenting `/format
#### wpiformat
wpiformat can be executed anywhere in the repository via `py -3 -m wpiformat -clang 14` on Windows or `python3 -m wpiformat -clang 14` on other platforms.
wpiformat can be executed anywhere in the repository via `py -3 -m wpiformat` on Windows or `python3 -m wpiformat` on other platforms.
#### Java Code Quality Tools
@@ -131,6 +147,16 @@ If you only want to run the Java autoformatter, run `./gradlew spotlessApply`.
CMake is also supported for building. See [README-CMAKE.md](README-CMAKE.md).
## Running examples in simulation
Examples can be run in simulation with the following command:
```bash
./gradlew wpilibcExamples:runExample
./gradlew wpilibjExamples:runExample
```
where `Example` is the example's folder name.
## Publishing
If you are building to test with other dependencies or just want to export the build as a Maven-style dependency, simply run the `publish` task. This task will publish all available packages to ~/releases/maven/development. If you need to publish the project to a different repo, you can specify it with `-Prepo=repo_name`. Valid options are:
@@ -153,7 +179,3 @@ The hal directory contains more C++ code meant to run on the roboRIO. HAL is an
The upstream_utils directory contains scripts for updating copies of thirdparty code in the repository.
The [styleguide repository](https://github.com/wpilibsuite/styleguide) contains our style guides for C++ and Java code. Anything submitted to the WPILib project needs to follow the code style guides outlined in there. For details about the style, please see the contributors document [here](CONTRIBUTING.md#coding-guidelines).
@@ -1069,41 +1067,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
=============
Drake Library
=============
All components of Drake are licensed under the BSD 3-Clause License
shown below. Where noted in the source code, some portions may
be subject to other permissive, non-viral licenses.
Copyright 2012-2016 Robot Locomotion Group @ CSAIL
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer. Redistributions
in binary form must reproduce the above copyright notice, this list of
conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution. Neither the name of
the Massachusetts Institute of Technology nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=====================
Portable File Dialogs
=====================
@@ -1242,3 +1205,23 @@ distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================
2024 Field Image
================
2024 Field Image from MikLast: https://www.chiefdelphi.com/t/2024-crescendo-top-down-field-renders/447764
================
Sleipnir License
================
Copyright (c) Sleipnir contributors
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -27,7 +28,7 @@ class TestEnvironment : public testing::Environment {
m_alreadySetUp=true;
if(!HAL_Initialize(500,0)){
fmt::print(stderr,"FATAL ERROR: HAL could not be initialized\n");
wpi::print(stderr,"FATAL ERROR: HAL could not be initialized\n");
std::exit(-1);
}
@@ -39,7 +40,7 @@ class TestEnvironment : public testing::Environment {
// able to run on the hardware.
HAL_ObserveUserProgramStarting();
fmt::print("Started coms\n");
wpi::print("Started coms\n");
intenableCounter=0;
@@ -54,13 +55,13 @@ class TestEnvironment : public testing::Environment {
if(enableCounter>50){
// Robot did not enable properly after 5 seconds.
// Force exit
fmt::print(stderr," Failed to enable. Aborting\n");
wpi::print(stderr," Failed to enable. Aborting\n");
std::terminate();
}
std::this_thread::sleep_for(100ms);
fmt::print("Waiting for enable: {}\n",enableCounter++);
wpi::print("Waiting for enable: {}\n",enableCounter++);
HAL_RefreshDSData();
}
std::this_thread::sleep_for(500ms);
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.