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>
GetInstance() is required to start the event listener that creates the
network table entries.
This is a C++ only change; Java uses static's and thus doesn't need this.
The right fix is to implement cscore's AddListener() immediate notification,
but that's much too invasive of a change to do this year.
This fixes the common use cases, but doesn't fix all cases, as e.g. creating
a UsbCamera manually before calling any CameraServer functions will still
have the issue, but there's an easy workaround--call
CameraServer::SetSize() prior to creating any cameras.
This provides the closed callback with the real reason for the
connection being closed. Keep closed from being called twice by adding
a check in SetClosed().
Previously the timeout was 10 times the update rate, so with low update
rates it could be as small as 50 ms, causing spurious disconnects when
large or many topics were published.
Limiting with vsync is apparently unreliable on a number of systems;
this resulted in high CPU/GPU usage.
Also add current actual frame rate to about dialog of GUI tools.
This would previously just write past the end of the buffer, smashing
the stack. It's only called in the case when a non-file or block device
is used as the file.
Previously, a setDefault() on the server could override a client doing a
real set() if the time offset between client and server was negative,
resulting in a negative timestamp from the client. This is a not
uncommon situation with robot code, as the robot code always starts at
time 0, so any clients that set values earlier (in real time) would have
negative timestamps.
Also improve special casing of 0 in the transmit side to make sure a
normal timestamp will never get sent as 0.
Previously this wouldn't send the last value on the value subscribe if a
topics only subscription already existed.
Also start adding server implementation unit tests.
This avoids the warning appearing on every startup when persistent
values aren't used.
Also add note to message saying it can be ignored if persistent values
aren't expected.
This PR updates the existing differentialdriveposeestimator example to include computer vision pose estimation and latency compensation.
The example generates a simulated cameraToTarget transformation, which is then fed into ComputerVisionUtil.objectToRobotPose() to compute the robot's field-relative position exclusively from vision measurements. The vision measurements are applied through DifferentialDrivePoseEstimator.addVisionMeasurement().
The updated example constructs an AprilTagFieldLayout from JSON. This requires a deploy directory, something which isn't currently supported in wpilibjExamples and wpilibcExamples.
During HAL_Initialize, wait up to 100ms for a DS packet to be received. Then in RobotBase, right after calling HAL_Initialize, call each language's RefreshData function to force a high level DS update. If the DS is connected, will get joystick data. If there is no data, nothing different will happen, but in that case there's no joysticks anyway.
This does the same thing as right clicking, but provides a visual indicator.
The icon disappears if the window is too small or docked (right click keeps working).
RKDP is strictly better in terms of accuracy per unit of work. We used
RKF45 for sim physics in the 2021 season, but we transitioned to RKDP
before the 2022 season.
This provides a consistent class-based interface to the underlying C
library from both C++ and Java.
Co-authored-by: Matt <matthew.morley.ca@gmail.com>
The main restriction is there must be an event loop running on the main thread.
No special action is required for GUI applications, but for non-GUI applications, a
RunOsxRunLoop() function is provided that needs to be called from the main thread.
Using an atomic here means we are never going against a lock that is touchable from user code. That should make reading the DS data from the DS callback even safer.
If UpdateClients() was called in the same update batch as an entry
removal, it could crash in GetEntry() due to a null entry caused by
deletion before a removal erase pass was made.
Java was missing the motor safety thread entirely
C++ accidentally used a manual reset event, causing the motor safety thread to spin.
C++ PWMMotorController would not feed the watch kitty.
Both languages would call feed() from the StopMotor call, causing some ping ponging.
Reverts "[wpimath] Constrain Rotation2d range to -pi to pi (#4611)"
This reverts commit d1d458db2b.
This broke multiple teams code in beta. It is also easier to limit the angle externally, then reconstruct a larger angle that got limited. This additionally adds comments to clarify the behavior and retains tests that were added in the reverted commit, and fixes a javadoc comment angle reference.
The CAN Stream API allows defining an buffer to receive an
arbitrary set of CAN messages, based on an ID and a mask. Messages
are added to this queue separate of other CAN APIs. This means the
messages can be receive without impacting other APIs such as
vendor APIs.
This enables things like detection of what devices are on the
bus, or custom decoding, without using vendor APIs.
Co-authored-by: Thad House <thadhouse1@gmail.com>
Move the command group checking functionality from CommandGroupBase into CommandScheduler.
Update references to grouping as composition for clarity (because explicitly grouping isn't the only way to do it).
Deprecate the static factory methods parallel, race, and deadline in CommandGroupBase in favor of the identical ones in Commands.
The ComputerVisionUtil class was added before AprilTag support was
announced. Now that it has, the functions for estimating a pose from
range and yaw are no longer needed; it's just better to get the pose
directly from the AprilTag.
The coordinate system on some function arguments was confusing or didn't
match the NWU convention the rest of the library uses. It's easier to
remove the functions now and add them back after they're fixed since the
fixes aren't trivial.
The range function was removed because it uses pitch and yaw in the
camera's spherical coordinate system, which is obsoleted by AprilTags.
AprilTags give you a 6DOF pose directly, so range can be obtained via
Pose2d.getTranslation().getDistance().
Fixes#4757.
For PWM motor controllers, this is going to be the fastest way to stop the motor,
as disabling the PWM output will have a small delay due to the motor controller
needing to detect the missing signal.
Note Set(0) is not a safe approach for CAN motor controllers, which may have closed
loop operation, non-% output set() calls, etc.
No longer stores a temporary setpoint in PIDSubsystem, instead
immediately sending to PIDController. This fixes an issue where the
setpoint didn't take effect until the Subsystem Periodic method ran, and
could cause commands to finish early if they were scheduled after the
subsystem periodic method ran because it used the old setpoint.
This fixes the following compilation errors:
```
/home/tav/frc/wpilib/allwpilib/wpilibcExamples/src/main/cpp/examples/UnitTest/cpp/subsystems/Intake.cpp:5:10: fatal error: subsystems/Intake.h: No such file or directory
5 | #include "subsystems/Intake.h"
| ^~~~~~~~~~~~~~~~~~~~~
/home/tav/frc/wpilib/allwpilib/wpilibcExamples/src/test/cpp/examples/UnitTest/cpp/subsystems/IntakeTest.cpp:11:10: fatal error: Constants.h: No such file or directory
11 | #include "Constants.h"
| ^~~~~~~~~~~~~
```
This effectively replaces the Unscented Kalman Filter used for Pose Estimation with the Odometry model, and uses a recalculable Kalman gain matrix to update pose estimations whenever a vision measurement is added.
Notably, this change removes the need for the confusing generics used in Java, and the C++ implementation got quite a bit less complex as well.
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
Also update rapidreactcommandbot example factories to fit this convention (as in #4655).
C++ does not need an update as CommandPtr already uses CommandBase (#4677).
The Color algorithm was tweaked to:
a) not produce incorrect values if the user happens to input a hue outside the [0, 180) range, and
b) more accurately convert the hue remainder from range 0-30 to 0-255. The current conversion vastly overshoots the multiplier (converts 0-30 to 0-270) and relies on clamping the value when constructing the Color object to produce a slightly incorrect result.
Trigger was refactored to use BooleanEvent when it was introduced in #4104.
This reverts to the original implementation until edge-based BooleanEvents can be fixed.
Refactor some examples to use newer features, such as HID factories, library-provided command factories, CommandPtr (C++), as well as new idioms such as static/instance command factories.
Comparison operators which compared against every class member variable
now use C++20's default comparison operators.
Also remove operator!= that in C++20 is now auto-generated from operator==.
These are similar, but not quite identical to, the NT3 NetworkTable
table listeners.
Also add table topic-only multi-subscriber to ensure functions like
getKeys() work properly regardless of other subscriptions.
Previously, only the first subscriber was actually matched to a topic
when a topic was created; this was a problem when later publishing
values as a client could have both a topic-only subscriber and a normal
subscriber, and only the first one would end up being subscribed to the
topic.
Since m_windows is sorted using the ascii, when "Plot <10>" is reached it will be before "Plot <2>" in `m_windows` which makes it so it will not add a new plot after the id 10 is reached. This also fixes a potential issue of someone manually changing an id in the file, which would break adding a new plot in some circumstances.
Currently, the server rejects duplicate client IDs. As we want to make
the client implementation as simple as possible, instead deduplicate the
name on the server side by appending "@" and a count.
NT4 spec has been updated for this change.
This is needed to avoid a conflict with Object.wait() when using static imports.
C++ doesn't have this issue, and has units, so Wait() still makes sense there.
The signing step does not get passed the username and password to the server, so it will just read from the build cache. Then to make sure the tasks are all updated correctly, use if developerid exists as a property to all sign tasks, so it will see the new variable value, and relink. Additionally only update the archives during signing, which will speed up signing.
This leaves the file format as a list, but internally will transform the collection of tags into a map on de/serialization. The serialization will probably happen once on startup, but the tag lookup can happen 100s of times a second. This honestly probably doesn't make too much of a performance hit since N is small, but this is a simple O(n) -> O(1) change for lookups.
* NetworkTableInstance: set handle to 0 after destroy
* Fix multiple notifications of local values
* Detect mismatch between handles
* Server: fix setting min period when no topics
* Limit maximum number of subscribers/publishers/listeners
This helps find resource leaks and prevents them from causing excessive
slowdowns/crashes. The limit on each is currently set to 512.
* Don't use std::swap in move operation
This is an API for looking up a Pose3d from a tag id, and includes functionality to load that map from a JSON file.
This also adds JSON support to Pose3d, Rotation3d. Translation3d, and Quaternion.
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
Co-authored-by: AMereBagatelle <themerebagatelle@gmail.com>
Motivation
Feedback from 2022 showed that the Trigger API is rather confusing, mostly due to the following:
- duplicate Trigger and Button APIs were available; users were confused searching for a nonexistent difference between them.
- the when terminology was ambiguous and unclear whether it refers to the high state or specifically the rising edge.
- the Active terminology didn't unambiguously refer to the high state; it wasn't unintuitive to understand it as "when the binding is active/polled".
- whileHeld vs whenHeld was very confusing, and the difference between them wasn't obvious. The parallel Trigger verbs, whileActiveContinuously and whileActiveOnce are much less confusing.
Solution
Deprecating Button and its binding methods. The rationale for deprecating Button (and not Trigger) is because Button uses terminology that is needlessly more specific and restricting to the button use case, making the use case of arbitrary trigger conditions unintuitive.
After consideration, deprecation of Button's subclasses was decided against:
- NetworkButton (a trigger condition based on a boolean NT entry/topic) is a use case that is not necessarily intuitive for teams to implement themselves, so it is an abstraction that should be provided in the library. A parallel class for the BooleanEvent level, NetworkBooleanEvent, was also added as part of NT4. NT listeners were considered as a alternative solution, but they require attention to thread safety, and aren't interoperable with the EventLoop API.
- JoystickButton/POVButton provide abstractions around HID buttons. The new Trigger-returning factories on the HID classes are an equal (if not more concise) alternative, but there is no reason not to keep them for those who find their use preferable.
At a later date in the deprecation cycle (perhaps for 2024), when Button is removed, these subclasses should be changed to inherit directly from Trigger.
Trigger's bindings are changed to use True/False terminology, as it should be unambiguous. Each binding type has both True and False variants; for brevity, only the True variants are listed here:
- onTrue (replaces whenActive): schedule on rising edge.
- whileTrue (replaces whileActiveOnce): schedule on rising edge, cancel on falling edge.
- toggleOnTrue (replaces toggleWhenActive): on rising edge, schedule if unscheduled and cancel if scheduled.
Two binding types are completely deprecated:
- cancelWhenActive: this is a fairly niche use case which is better described as having the trigger's rising edge (Trigger.rising()) as an end condition for the command (using Command.until()).
- whileActiveContinuously: however common, this relied on the no-op behavior of scheduling an already-scheduled command. The more correct way to repeat the command if it ends before the falling edge is using Command.repeatedly/RepeatCommand or a RunCommand -- the only difference is if the command is interrupted, but that is more likely to result in two commands perpetually canceling each other than achieve the desired behavior. Manually implementing a blindly-scheduling binding like whileActiveContinuously is still possible, though might not be intuitive.
Notes
It was considered to share BooleanEvent's digital signal terminology; however, once it was decided that Trigger should not inherit from BooleanEvent (due to overload incompatibility) the common terminology was not worth the unintuitiveness stemming from users' unfamiliarity with the signal processing terms.
All trigonometric functions and vector classes assume North-West-Up axes
convention, so using North-East-Down convention with them is really
error-prone. We've broken something every time we touched the drive
classes.
We originally used North-East-Down to match the joystick convention, but
the volume of long-lived bugs has made this not worth it in retrospect.
The rest of WPILib also uses North-West-Up, so this makes things
consistent.
KilloughDrive was removed since no one uses it.
- In both C++ and Java, add listener functions to Instance class (same as NT3 provided)
- Add WaitForListenerQueue functions (same as NT3 provided)
- Move Java non-poller implementation to Instance (previously only handled single instance)
- Change C++ listeners to take non-const references for subscribers etc to help avoid footguns from use of temporary objects (also add doc comment)
- Fix Preferences making .type persistent
This avoids the need for explicit value() calls (as compared to using
DoubleTopic). The unit name is published as the "unit" property.
Implementation note: the test needs to be in wpilibc because ntcore does
not depend on wpimath.
Theres is now a built in HMB api, but you have to dlopen it to access it. Moved our existing infrastructure for this to its own class, added the new functions, then updated interrupts and LEDs to use it.
* TopicListener: Fix Add() return values
* Update PubSubOption poll storage documentation
* Update NetworkTableEntry::GetValue() doc
* Add documentation regarding asynchronous callbacks
* Unpublish entry: set publisher to nullptr
* Implement ValueListenerPoller default constructor
* Remove SetNetworkIdentity, make parameter to StartClient
* URI-escape client ID, improve error message
* Add connected message with client id; also improve disconnected message a bit
* Handle SetServers either before or after StartClient
* Fix client use-after-free; also delay reconnect after disconnect to rate limit
* Don't re-announce to already subscribed client; we especially don't want to send the last value again
* Always accept in-order sets, only use timestamp for tiebreak
* Fix LocalStorage::StartNetwork race
* Remove unused/unimplemented function
Also:
* [glass] Remove debug print
* [glass] Fix mpack string decoding
* [cameraserver] Fix up startclient
The current DS thread model has some pretty major issues. It makes it difficult to know if all data is from the same remote packet, and if the data changes while the robot loop is running. Additionally, the DS thread is used for a few other things (MotorSafety and State Tracking for EducationalRobot). This also makes sim difficult, as user code has to wait for the thread to know it has new data.
This change completely rethinks how threading works in the driver station model.
First, the DS HAL system receives a new data callback, either from Netcomm or DriverStationSim. Inside the context of this callback, all the low latency data is read and put into a cache. Doing some investigation on the robot side, this is perfectly safe to do, and also ensures a ds packet will not be parsed before we finish reading the current packet data.
After all data is read, the cache is swapped with a 2nd buffer. This buffer just stores the data, none of the HAL DS calls read from this buffer. An event is then fired, stating there is new data ready to go.
Robot code calls HAL_UpdateDSData(). This swaps the 2nd buffer with a 3rd buffer, which always contains the current data. This data will not be updated until HAL_UpdateDSData is called again. Which solves the state problem.
The high level driver station classes have. an updateData() call, which calls HAL_UpdateDSData, and then update button state variables, then data log and update the NT FMS data table (Java also caches across the JNI boundary here, but that could trivially be removed). An extra event provider is provided, allowing other threads to know when this call has been completed.
IterativeRobotBase calls DS.updateData() at the beginning of each loop, and only once per loop. This means all commands will always have the same state.
All of this means there is no longer a DS thread. Everything happens synchronously. This means Sim and testing is easier, as you can just call DriverStationSim.NotifyNewData(), and then DriverStation.UpdateData(), and you can guarantee that all the DriverStation.*** data is up to date.
As for Motor Safety and Educational Robot State Handling, those can all be handled by their own threads. The Educational Thread only needs to run under EducationalRobot, and MotorSafety will only be started if there is a motor safety object enabled.
For system installs, `DESTDIR=/usr cmake --install buildfolder` installs
libraries to `/usr/lib` with the correct rpath. Example structure:
```
/usr/include/wpimath/frc/controller/LinearQuadraticRegulator.h
/usr/lib/libwpimath.so
```
Users need to provide `-I/usr/include/wpimath` in their projects. This
is an artifact of the install() commands being in the subdirectory CMake
files.
For other locations, `DESTDIR=/opt/wpilib cmake --install buildfolder`
installs libraries to `/opt/wpilib/lib`. Example structure:
```
/opt/wpilib/include/wpimath/frc/controller/LinearQuadraticRegulator.h
/opt/wpilib/lib/libwpimath.so
```
-DUSE_SYSTEM_EIGEN now only removes include paths for Eigen instead of
drake as well.
The USE_VCPKG flags were renamed to USE_SYSTEM since they seem general
enough for that to work (the find_package() commands work the same way
on Arch).
The system libuv CMake build now works with Linux libuv as well.
This is enabled by the C++20 __VA_OPT__ feature.
Uses of "{}" format string were updated.
Some warning suppressions were required for older clang versions.
Also improve codegen of wpi::Logger::Log(), frc::ReportError(), and frc::MakeError();
these generate better and less redundant code if they use fmt::string_view for the
format string instead of templating on it.
* Use explicit this capture required by C++20
* Use C++20 span
* Replace wpi::numbers with std::numbers
* Fix C++20 clang-tidy warning false positive in fmt
* Remove ciso646 include since C++20 removed that header
* Fix global-buffer-overflow asan warnings in ntcore tests
* Add DIOSetProxy constructor to HAL
* Upgrade MSVC compiler to 2022
* Bump native-utils to 2023.2.7 (changes to std=c++20)
Co-authored-by: Peter Johnson <johnson.peter@gmail.com>
* Fix C++ Publisher and Subscriber move assignment
* Fix Publisher comment typo.
* Publish: check that properties is an object.
Print a warning, but still publish, just with empty properties.
Add error print for unassigned type publish.
* Return boolean from SetProperties
* Document exception-throw in Java for invalid JSON.
The existing raw time has an issue where it jumps around, as in the FPGA if the frequency is not a multiple or divisor of 25 Mhz it jumps around by 1 every second. While waiting on an FPGA change, update the API to make raw output give nanoseconds rather then a scaled value. This does a longer read cycle to get the correct value, but in the future if a fast FPGA function is added this can be easily changed.
Add a CommandPtr with an internal unique_ptr to enable not needing to move the underlying classes, which is error-prone due to the potential for lambda captures.
I also refactored Pose3d's conversion implementation to use the
Translation3d and Rotation3d conversions, thereby giving Translation3d
and Rotation3d test coverage. No changes were made to the expected
values of the Pose3d conversion tests.
The expected values of the Transform3d conversion tests were copied from
the Pose3d conversion tests without modification.
Checkstyle naming conventions were changed to allow most of what's in
wpimath. Naming rules were disabled completely in wpimath since almost
all suppressions are for math notation.
SPI Mode setting was very broken. MSB and LSB sets did not work (MSB is the only one supported)
and if LSB was set (which was the default) the ioct to set clock phase would fail. This
deprecates all the individual functions, the LSB/MSB functions, and adds an SPI mode selection
function. This is usually more understandable, and shows up in a lot more documentation
The controller gain matrix K should be computed from the solution to the
DARE, but this constructor does not do that. It effectively violates a
postcondition enforced by the other constructors by letting the user
throw in a controller gain matrix that didn't come from an LQR.
Removing this constructor is a breaking change, but it never should have
been included in the class in the first place. There's also no valid
reason to use it. I assume it was originally added for debugging the
class internals.
This constructor does not exist in C++.
Replace ⊤ with \u22a4, since Unicode references are supported
but HTML5 entities are not. Should be fixed if JDK is ever
moved forward.
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
until() was recently added as a more intuitive alias for this. At this point, keeping this decorator will just cause confusion, given the functionally-equivalent until() alias and the similarly-named getInterruptionBehavior/withInterruptBehavior
Force the status to be 0 (no error) upon initialization of the REV PneumaticHub.
This prevents a program crash in the case of a robot code restart with no CAN Bus present.
This causes setVoltage to be called on the lower level motor contollers,
which is benefical in cases when they are smart motor controllers.
Previously, the default implementation (using the bus voltage and
calling set()) was used in this case.
This does slightly pessimize the case when the lower level motor
controllers use the default setVoltage implementation, but given the
prevalence of smart motor controllers, this seems like an overall win.
The FPGA API takes microseconds directly, instead of a scaled value. Also add a new HAL level API to trigger multiple DIOs with the same pulse at once.
Added an Eigen::SparseMatrix formatter.
Also modified the Eigen::Matrix formatter to support Eigen::MatrixXd.
Eigen::MatrixXd sets both dimension template arguments to -1, so they
can't be used for iteration. rows() and cols() are now used instead.
rows() and cols() are constexpr for statically sized matrices, so
there's no performance loss there.
This is useful in some debugging scenarios. System.err is separately buffered, so when e.g. debugging test cases it doesn't interleave correctly with the C++ stdout/stderr logging. Even using flush() doesn't seem to help, I think because Gradle does its own buffering.
For RPATH on MacOS use '@loader_path' instead of '$ORIGIN' to reference the directory where the executable is located. The latter is the mechanism used on Linux.
I think this was exposed due to newer OS X ignoring $DYLD_LIBRARY_PATH for security reasons.
* Root folder variable names are now more descriptive
* clone_repo() now restores the current working directory
* Removed setup_upstream_repo() since it's now identical to clone_repo()
* Moved am_patches()'s for loop into user scripts so the filename prefix
doesn't need to be included in every patch filename
* Renamed am_patches() to git_am() since its only job now is to run "git am"
* Removed unused apply_patches() function
* Fixed typo in git_am()'s ignore_whitespace arg name
The warnings included recommendations of braces for if statement
readability, a recommendation for default initialization of an int
array, and include-what-you-use (indirectly through clang-tidy reporting
undefined symbols).
We migrated to magic statics for lazy construction like the following:
```cpp
class Singleton {
static Singleton& GetSingleton() {
static Singleton instance;
return instance;
}
};
```
Now, implicit narrowing conversions are only used with wpi::Now(). This
also fixes clang-tidy warnings about C-style casts. For example:
```
== clang-tidy /__w/allwpilib/allwpilib/wpilibNewCommands/src/main/native/include/frc2/command/SwerveControllerCommand.inc ==
/__w/allwpilib/allwpilib/wpilibNewCommands/src/main/native/include/frc2/command/SwerveControllerCommand.inc:95:18: warning: C-style casts are discouraged; use static_cast/const_cast/reinterpret_cast [google-readability-casting]
auto curTime = units::second_t(m_timer.Get());
^
```
In that case at least, the cast was removed entirely since Get() already
returns a units::second_t.
fmt removed fmt::make_args_checked since it's no longer needed for
constexpr format string checks.
fmt deprecated implicit conversions from enums to integers in format
arguments, so I added explicit static casts.
This reduces commit noise when other git versions are used. The version
was removed by passing `--no-signature` to `git format-patch` which is
now documented in the readme.
Fixes several cases where calling scheduler operations from a command callback could result in NPEs or other issues.
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
GCC's static analyzer is correctly reporting that resize() requires an
unsigned integer, but the argument provided in the JNI function could be
negative since it's a signed byte. Throwing an exception if the argument
is negative fixes the warning.
The original idea of LiveWindow telemetry was to automatically make
telemetry data visible to users. This has proved increasingly
problematic in recent years due to the "spooky action at a distance"
of telemetry happening for objects that are only constructed but not
used, and blocking or slow object reads resulting in hard-to-debug
loop overrun conditions.
This allows us to error out on deprecation warnings for thirdparty
libraries and standard library features.
Co-authored-by: Starlight220 <53231611+Starlight220@users.noreply.github.com>
In addition to m_prevError and m_totalError, m_positionError and
m_velocityError need to be reset to 0 when reset() is called.
Otherwise, the next time calculate() is called, the old values will be
used as the previous error, but this is inaccurate since the caller
wanted to reset the state of the PID controller.
* Calculated swerve module states now stored in a member variable
* If ChassisSpeeds(0, 0, 0) is converted to module speeds, the
previously calculated module angle will be conserved, with forward speed
set to 0
* New tests added
This adds a unicycle controller that's a drop-in replacement for Ramsete
and a differential drive controller that controls the full pose and
outputs voltages. The main benefit is LQR-like tuning knobs using a
system model.
The previous documentation suggested that `triggerTime` is the interval until the next alarm, but the implementation is that it is the absolute alarm time.
PMD requires that variables only initialized in the constructor be
final. The compiler errors if those final variables aren't guaranteed to
be initialized, so extra else branches were added to ensure that.
PMD also requires that classes with only private constructors be final.
The equivalent C++ classes were finalized as well, except for
TimeInterpolatableBuffer because it doesn't expose factory functions.
This previously always returned false; the get method it inherited was not used in the getAsBoolean defined in the Trigger class. The fix is to swap get() and getAsBoolean() implementations in the Trigger class.
- Add InterpolatedTreeMap for Java from team 254's 2016 MIT licensed code
- Add InterpolatedMap for C++ from team 3512's code with @calcmogul (original author) permission
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
The Joseph form of the error covariance update equation is more
numerically stable when the Kalman gain isn't optimal. Numerical
instability and filter divergence can occur if the user goes long time
periods between updates and the error covariance becomes ill-conditioned
(the ratio between the largest and smallest eigenvalue gets too large).
The existing implementation will produce a cost of NaN if a tolerance of
infinity is entered, but the limit approaches zero. Being able to
specify that a state has no cost is useful, so this change adds support for
that.
This sets the workflow concurrency to 1 for all workflows. For PRs this means if you push an additional commit older jobs will be cancelled.
The documentation workflow already only runs on tags or merges to main. For this, we cancel previous runs if they are to the same destination (tag or main) but still prevent 2 jobs from running at once if they are spawned from different refs.
This creates a default log file that captures NT changes and
automatically renames the log file based on time and match info.
DriverStation joystick logging will be implemented by the DriverStation
class instead.
When trying to set the tolerance of a ProfiledPID, it fails if you don't give it a velocity value. It was missing a conversion from double to the appropiate unit.
SetPositionOffset was added. Been requested multiple times, and easy to implement.
The javadocs mentioned GetPositionInRotation. It has tripped up many people how to get the absolute position from the encoder (You currently have to have precreated the DutyCycle object). Add this method (as GetAbsolutePostition) to make this easier to do.
The checks for making sure a matching set of values was read was doing direct double comparisions. This worked ok in the DutyCycle case, but has problems in the analog case. Solve this by using an epsilon comparison.
And finally, scale AnalogEncoders analog input to 0-1 instead of 0-5. This was reported a few years ago, but the issue was missed. This caused the encoder to count from 0-5, then 1-6, then 2-7 etc. This is solved and now works correctly.
Closes#3188Closes#4046Closes#4051
And fixes the following issue on CD
https://www.chiefdelphi.com/t/wpilib-analogencoder-java/372649
If xSpeed == -0.0 and zRotation > 0, the algorithm assumes it's in the
third quadrant instead of the first since +0.0 == -0.0.
Also added tests for inverse kinematic functions, fixed some
MecanumDrive test bugs, and added Java MecanumDrive.driveCartesianIK()
and KilloughDrive.driveCartesianIK() overloads with defaulted gyro angle
that C++ already had.
Fixes#4022.
The real robot has match time set to -1.0 until it's enabled, and then
counts down. Disabling the robot sets the time to -1.0.
The sim GUI has been updated to add preset buttons for auto and teleop
match times. The enable match timing checkbox has been removed as it's
no longer required.
The DS socket plugin has also been fixed to properly initialize
matchTime to -1.0 and reset it to -1.0 on disable.
Most of these were unused, the IMU ones were just debug messages.
The only one that wasn't removed is in portable-file-dialogs.cpp since
the replacement looks less trivial.
2K was sufficient for simulation because it's possible to pause time,
but isn't quite enough for looking at real robot data. 20K points
is 400 seconds at 50 Hz which should make pausing plots much more
useful.
As every point is looped over, this does increase CPU utilization
somewhat but doesn't seem to have much of an impact for typical
use cases. Increasing this further will necessitate some greater
optimizations (e.g. an initial cull using binary search).
This can be called in a delayed manner, so it's possible for
m_size to already be at maximum, which results in writing past
the end of the array. Instead, just call AppendValue().
This shows more real world usage then hardcoding the setpoint and PID
gains. There were no current examples using Preferences. This will also
be used to update frc-docs article for Preferences.
While the number doesn't matter, it being old is confusing a lot of
people. We never increment the internal vendordep versions, so using a year
version number was a poor choice.
Closes#3921.
Since the CAN bus can easily become disconnected, we don't want this to crash. Instead, we just want this to report errors. This matches previous behavior.
Changed turnOutput from var to double in SwerveModule. It doesn't make sense for driveOutput and turnOutput to have different types so they should both be doubles.
It seems like the JVM does not handle recursive calls to object monitor based locks correctly. A few bugs in the past have been reported to have caused deadlocks if this occurs. It looks like the version of Java we use is fixed, but there could be other bugs, and it seems like this area of the code isn't tested much. Based on the stacks reported in #3896, it really seems like this is occurring. So we're going to attempt to switch to explicit mutex based classes, which shouldn't have bugs like this, and we will see if that fixes the issue.
It would crash in C++ if the global measurement was sooner than all the
snapshots.
Align Java with the changes and better document computation approach.
It was using the continuous B matrix to compute the feedback gain
instead of the discrete B matrix.
Tests were added for the matrix constructor overloads.
The changes to PneumaticsBase.cpp were to fix errors like the following
from enum classes not being formattable:
```
allwpilib/wpilibc/src/main/native/cpp/PneumaticsBase.cpp:36:9: required from here
allwpilib/wpiutil/src/main/native/fmtlib/include/fmt/core.h:2672:12: error: use of deleted function ‘fmt::v8::detail::fallback_formatter<T, Char, Enable>::fallback_formatter() [with T = frc::PneumaticsModuleType; Char = char; Enable = void]’
2672 | auto f = conditional_t<has_formatter<mapped_type, context>::value,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2673 | formatter<mapped_type, char_type>,
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2674 | fallback_formatter<T, char_type>>();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
Adds HAL layer warning for #3842. This is needed in the case when a
vendor uses the HAL directly rather than using the WPILib I2C class.
This should not result in a duplicate warning for WPILib I2C users due
to the duplicate message checking performed in HAL_SendError().
We don't want to remove the WPILib I2C warning because it gives stack
trace information while the HAL layer one can't.
The angular rate is treated somewhat like an angle during calibration,
but the datasheet says it's angular rate. The variables were renamed to
make this clearer.
This adds the REV Analog Pressure Sensor PSI to volt (and vice versa) conversion to allow setting the compressor config in PSI and getting the sensor reading in PSI. Also adds input validation for pressure values at the higher level.
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
It was only being used for fs::remove() (added in #3463), which is easily
replaced by std::remove().
The code change does not affect the WPILib tools, as this code is not used when JSON save files are used.
These classes are useful for storing previous robot positions to use in conjunction with the upcoming pose estimators.
Co-authored-by: Prateek Machiraju <prateek.machiraju@gmail.com>
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
Co-authored-by: cttew <cttewari@gmail.com>
Fixes#3827
Adds MotorController inversion for right side, removes inversion in
setVoltage methods.
Also fixes various XboxController negations (was inconsistent throughout examples).
This avoids stack-use-after-scope bugs in code like the following when
the original argument goes out of scope:
```cpp
frc2::Command* RobotContainer::GetAutonomousCommand() {
// Create a voltage constraint to ensure we don't accelerate too fast
frc::DifferentialDriveVoltageConstraint autoVoltageConstraint(
frc::SimpleMotorFeedforward<units::meters>(
DriveConstants::ks, DriveConstants::kv, DriveConstants::ka),
DriveConstants::kDriveKinematics, 10_V);
```
We don't currently support cameras in glass, but it's something we want to do in the future. However, when we do this, glass will completely stop working on N builds of windows, and it would fail to load at all with no messages. To solve this, we can delayload the media foundation dlls that are missing. The executable will then launch even without the dlls present, and we can attempt to load them at runtime and dynamically disable camera support.
When we get around to implementing it, we can just call HasCameraSupport, and dynamically hide all camera related code behind that flag.
More functionality was implemented at the HAL level, so expose that to the wpilib level.
This also does units changes for all the PH related functionality.
shared_from_this will assert if the shared pointer is in the middle of being destructed. Because we access shared_from_this in the message pump, this can easily occur. The solution is to grab the weak pointer, manually attempt to lock it, and only continue if that succeeds. The message pump is already synchronized to the usb camera being destructed, so this is a fine behavior.
With the change from GetInstance to static functions, many functions
don't call DriverStation::GetInstance(), so the DS thread wasn't
getting started by default. Call InDisabled() to make sure this
happens.
Add the remaining HAL functions needed to fully support the Pneumatic Hub and its latest firmware.
- Clear sticky faults
- Get device voltage
- Get 5v supply voltage (used for analog to PSI calculation)
- Get solenoid voltage
- Get solenoid current
- Get device firmware and hardware version
Some minor refactoring was done for naming of some internal functions for consistency purposes.
Refactors retrieving the faults from the device to match the implementation that we have for the Pneumatic Hub. Instead of having a getter function for each fault, there is a single function to get all faults (sticky or normal) for use with the higher level API
Renames functions to be consistent
Removes some functions that don't need to be included in wpilib:
- Identify device - this just flashes the module LED on the device and has no use in wpilib
- Is PDH enabled - the PDH does not change state depending on robot enabled state
PDH frame and signal names were updated in our DBC, and this PR makes use of the newly generated CAN frame helper functions
This also makes the Gradle build work with JDK 17.
The extra JVM args in gradle.properties works around a bug with spotless
and JDK 17: https://github.com/diffplug/spotless/issues/834
PMD.CloseResource was ignored because it's almost always a false
positive, and there are many of them.
- Remove duplicate motor port (2) from C++ SwerveBot/SwerveDrivePoseEstimator
Java has the correct motor ports.
- Fix duplicate port allocation in C++ RomiReference by correcting if/else check
Java logic was already correct, and confirms this change.
UpdateEntries() and Flush() are called from methods that lock the mutex,
so locking it again will cause deadlocks. This also updates the Java
code to make MechanismObject2d::update synchronized like in the C++
version.
As the sensor needs to maintain an actual duty cycle, it can't go all
the way from 0-100, so provide a way to set the min and max and linearly
map between the two.
The root cause of #3747 is CommandScheduler's ds state checks are behind iterative robots checks. This means that the iterative robot state could return enabled, but the DS cache could still be reporting disabled. This results in a race in the Disabled -> Enabled transition, which manifests in commands not running.
Previously, iterative robot base pulled from the DS cache. This meant that the ds cache was always updated before an iterative robot base loop could run. This still had a race, but this could only occur on the Enabled -> Disable transition, which is much less noticeable and would usually just result in a command running for an extra loop.
We can move back to the old behavior by grabbing the new iterative robot base check variables to use the DS cache.
Unlike std::string and std::string_view, this substr() allows a start
greater than the length of the string, in which case an empty string
is returned. This matches llvm::StringRef behavior.
Storage is now nested.
Separate "roots" can be configured which save to separate files.
In particular, this is used to save wpigui and ImGui window position
to a -window.json file.
ImGui's ini (for window position) is mapped to JSON.
You can optionally specify a directory to load from on the command line.
If one isn't provided, it uses the global system directory.
Any changes made are automatically saved here.
Workspace | Open: select directory, the current layout is replaced with that
workspace, and future auto-saves also switch to that location. The main
window size/location is not changed, only the contents.
Workspace | Save As: select directory, the current layout is saved there,
and future auto-saves also switch to that location.
Workspace | Reset: window locations are preserved, but all other settings
are reset to default (including e.g. removing plot windows). This will also
end up clearing the current save file. as with load, the main window
size/location is not changed.
Workspace | Save As Global: "save as" to the global system location
Notably, the main window size/location is only loaded at startup, but is
auto-saved as part of the current workspace.
If something happens with the PD connection, these would have spammed messages continuously.
This wasn't the case previously, and we don't want this behavior now.
The template argument order for UnscentedTransform was reversed to match
all the other UKF classes. Since UnscentedTransform is intended as a
class for internal use only, this shouldn't cause much breakage.
These enable more consistent use of synchronization across the
native libraries. Users can create Event and Semaphore primitives, but
in addition, libraries can set up any handle as an Event-type signal.
Similar to the PCM, we're going to make the PH not do anything with the compressor until the PH HAL object has been initialized. The mechanism we're going to use to signal to the PH that that has happened is to begin sending the state of the solenoids (which will all be set to off at this point).
These relied on the OnStart and OnExit callbacks which were not present
in the wpiutil common CallbackManager code. Add support for these and
fix up other use cases.
Also fixes notifications to correctly filter on event kind.
This fixes a breakage caused by #3133.
This fixes the following warning.
The member function operator== only works in C++17, and the friend operator== only works in C++20.
```
/Users/runner/.gradle/caches/transforms-2/files-2.1/c671f5a5dff922b8870f4eb33f4c8e2a/wpiutil-cpp-2022.1.1-alpha-3-1-g4e3fd7d-headers/wpi/json.h:1847:46: warning: ISO C++20 considers use of overloaded operator '==' (with operand types 'const typename json::object_t::iterator' (aka 'const StringMapIterator<wpi::json>') and 'const typename json::object_t::iterator') to be ambiguous despite there being a unique best viable function [-Wambiguous-reversed-operator]
return (m_it.object_iterator == other.m_it.object_iterator);
~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/runner/.gradle/caches/transforms-2/files-2.1/c671f5a5dff922b8870f4eb33f4c8e2a/wpiutil-cpp-2022.1.1-alpha-3-1-g4e3fd7d-headers/wpi/json.h:1863:20: note: in instantiation of member function 'wpi::detail::iter_impl<const wpi::json>::operator==' requested here
return not operator==(other);
^
/Users/runner/.gradle/caches/transforms-2/files-2.1/c671f5a5dff922b8870f4eb33f4c8e2a/wpiutil-cpp-2022.1.1-alpha-3-1-g4e3fd7d-headers/wpi/json.h:5008:20: note: in instantiation of member function 'wpi::detail::iter_impl<const wpi::json>::operator!=' requested here
if (it != end())
^
/Users/runner/.gradle/caches/transforms-2/files-2.1/c671f5a5dff922b8870f4eb33f4c8e2a/wpiutil-cpp-2022.1.1-alpha-3-1-g4e3fd7d-headers/wpi/json.h:5025:16: note: in instantiation of function template specialization 'wpi::json::value<std::basic_string<char>, 0>' requested here
return value(key, std::string(default_value));
^
/Users/runner/.gradle/caches/transforms-2/files-2.1/c671f5a5dff922b8870f4eb33f4c8e2a/wpiutil-cpp-2022.1.1-alpha-3-1-g4e3fd7d-headers/wpi/StringMap.h:442:8: note: ambiguity is between a regular call to this operator and a call with the argument order reversed
bool operator==(const DerivedTy &RHS) const { return Ptr == RHS.Ptr; }
^
```
We originally moved to setuid admin so user programs could do other
things requiring admin if they wanted. However, these things, like
setting RT priorities of other processes, can usually be done instead as
admin during the GradleRIO 2022 deploy process, or adding commands to
the robotCommand script. By going back to setcap, we can simplify the
HAL code.
Timer reports a negative duration if the sim timing is restarted. This
can be worked around by calling Reset(). Other options included:
1. Have RestartTiming() call Timer::Reset() on a list of instantiated
Timers.
2. Have Timer::Get() reset the timer if it notices time went backwards.
This requires dropping const qualification though, which is a
breaking change that only fixes a minor edge case.
Closes#2732.
I generated lists of includes and uses via
`rg -l deprecated.h | sort -u` and `rg -l WPI_DEPRECATED | sort -u`
respectively. If a file was in the first list but not the second, the
include was unused. If a file was in the second list but not the first,
the include needed to be added.
I started with the output of styleguide#217, then renamed a few classes
to fix compilation.
ntcore's StorageTest needed some manual renaming since it put the Test
word in the middle instead of at the end.
One limitation of wpiformat is test cases that were only named "Test"
were unmodified, and an error was generated. These test cases were
manually given more descriptive names:
* TimedRobotTest mode test cases had "Mode" appended to the name. Java
tests were renamed to match.
* UvAsyncTest and UvAsyncFunctionTest cases were given alternate names
Supersedes #2358 with updates and cleanups.
Closes#2482 and closes#2487 because we shouldn't support both
time-based and count-based debouncing approaches.
Co-authored-by: oblarg <emichaelbarnett@gmail.com>
- Correct several comments that referenced elevator
- Changed noise to be 1 encoder tick instead of half a degree
- Changed gear ratio and PID value to be better tuned
- Updated bounds to be similar to a single jointed arm
Inconsistent names were found using the following regular expressions.
* `rg "TEST(_F|_P)?\(\w+,\s+\w+Test\)"`
* `rg "TEST(_F|_P)?\(\w+,\s+Test\w+\)"`
* `rg "TEST(_F|_P)?\(\w+Tests,\s+\w+\)"`
Fixes#3495.
* Replace Matrix<> with Vector<> where vectors are explicitly intended.
I found these via `rg "Eigen::Matrix<double, \w+, 1>"`.
* Pass all Eigen matrices by const reference. I found these via `rg
"\(Eigen"` on main (the initializer list constructors make more false
positives).
* Replace MakeMatrix() and operator<< usage with initializer list
constructors. I found these via `rg MakeMatrix` and `rg "<<"`
respectively.
* Deprecate MakeMatrix()
Now that there are only 16 instances, store them all statically.
Make tests more reliable by using different ports for each connection in listener tests.
Having PCM as a singleton is a problem, as multiple things need to use it, and that gets really ugly. This changes PCM's to be a reference counted object, that can be passed around and constructed from multiple places.
In Java, this is using a map to hold a data store with a ref count, and allocating new objects any time a duplicate is requested.
In C++, this uses a trick constructor to store a PCM instance in the data store itself. This instance can then be passed to base objects using std::shared_ptr's aliasing constructor, which means constructing a solenoid from a PCM is not allocating after the 1st one.
This did require removing sendable from PCM. A compressor class was added back in to act as sendable for the PCM.
After this change is finished, the only change RobotBuilder and Team Code would require is passing a module type to solenoid constructors.
Co-authored-by: sciencewhiz <sciencewhiz@users.noreply.github.com>
* Address sanitizer uses -DCMAKE_BUILD_TYPE=Asan
* Thread sanitizer uses -DCMAKE_BUILD_TYPE=Tsan
* Undefined behavior sanitizer uses -DCMAKE_BUILD_TYPE=Ubsan
Only ubsan is enabled in CI for now because asan and tsan report
failures.
The standard Java package is missing BooleanConsumer as well as Float classes.
Update SendableBuilder to use it instead of internal BooleanConsumer
interface.
In some cases, knowing roborio 2 might be useful. This also creates a higher level enum that might be usable later for the discussion on more complex runtime types.
Internal headers are no longer allowed as of
https://gitlab.com/libeigen/eigen/-/merge_requests/631. Based on
benchmarking I conducted in that thread, there doesn't seem to be a
performance penalty for including the full headers anymore.
The move ctor is trying to cast from e.g. SendableHelper to PIDController before PIDController has been constructed, which is potentially UB. We don't actually use anything in PIDController though, so it's OK in our case.
This upgrade uncovered two issues:
ntcore wasn't forcing C++17, which caused a linker error with googletest
Matcher symbols:
```
undefined reference to `testing::Matcher<std::basic_string_view<char, std::char_traits<char> > >::Matcher(std::basic_string_view<char, std::char_traits<char> >)'
```
test_span.cpp wasn't including <algorithm> to use std::sort() and
std::is_sorted().
This is an alternative to #2344 that handles arbitrary order derivatives
of arbitrary precision. The downside is that since it's part of
LinearFilter, it can't utilize the units type system in the same way to
make Calculate()'s input type different from its output type.
The HAL Notifier thread is started when the first Notifier is created
and stopped when the last Notifier is destroyed. Currently,
HAL_SetNotifierThreadPriority() will cause a segfault if the Notifier thread
hasn't been started yet (that is, if no Notifier have been created yet).
This change makes HAL_SetNotifierThreadPriority() store the RT and
priority setting. If the thread has already been started, it will set
the priority immediately. If it hasn't, HAL_InitializeNotifier() will
set the priority when it starts the thread.
This PR gives the Notifier HAL thread RT priority 40 in RobotBase after
HAL initialization and before the user code is run. This drastically
improves scheduling jitter for TimedRobot's AddPeriodic() functions (in
3512's experience).
It's too risky to set user code as RT because badly behaved code
will lock up the Rio (potentially requiring safe mode to recover).
This needs the user program to be setuid admin to succeed.
- GenericHID is now concrete, and has only getRawAxis/Button(int) functionality
- getXxx() has been moved into Joystick as that's the only place where it makes sense
- Hand (and therefore getXxx(Hand)) has been removed, replaced by specific getLeft/RightXxx() methods in XboxController and the new PS4Controller class
- C++ ::Button:: and ::Axis:: enums have been converted to identically-namespaced static constexpr ints
This saves time in CI spent performing the same source-level checks in
every build job. Checkstyle, PMD, and Spotless are now run once in the
"Lint and Format" job.
The -PskipPMD flag was replaced with a -PskipJavaFormat flag that
disables Checkstyle, PMD, and Spotless.
They don't provide much utility for the end user. A print at the call to
HAL_ObserveUserProgramStarting() was added in their place so it's still
clear when constructors have finished running.
Currently, we have functions like TeleopInit() for running code on mode
entry, but no such functions for running code on mode exit, and it's
cumbersome to add those in user code without making a custom robot
class. This PR adds exit functions to TimedRobot.
Some example use cases include DisabledExit() for operations when the
robot enables (whether that be into teleop, autonomous, or test) and
AutonomousExit() for disabling feedback controllers.
This is a basic C++ example that demonstrates a simple differential drive implementation using “tank”-style controls through the DifferentialDrive class and an ordinary joystick.
* Rename Butcher tableau sections in NumericalIntegration such that
top-left is c, top-right is A, and bottom-right is b
* Move edu.wpi.first.math.Discretization to
edu.wpi.first.math.system.Discretization
* Sort Java Discretization to match C++ function order
* Add tests for Java Discretization
* Required adding Runge-Kutta time-varying impl to tests
* Move C++ Runge-Kutta time-varying impl to tests only
* Users don't need it
Our patches for the DARE and [[noreturn]] attributes were merged
upstream. We missed their monthly release window by a day, so we'll use
a commit hash for now.
The current 2021.3.1 release refers to `java/lang/IOException` which causes the following exception when using `toPathweaverJson` or `fromPathweaverJson`:
```
java.lang.NoClassDefFoundError: java/lang/IOException
at edu.wpi.first.math.WPIMathJNI.fromPathweaverJson(Native Method)
at edu.wpi.first.wpilibj.trajectory.TrajectoryUtil.fromPathweaverJson(TrajectoryUtil.java:79)
```
Also refactored RKF45 implementation to match the new style, which is
easier to read.
The tests were switched from RKF45 to RKDP since it's more accurate.
This reverts commit d068fb321f (#3420).
The 18.04 docker images now use GCC 8, which was the original reason for
updating. 20.04 uses a much more recent libc, so staying with 18.04
enables more Linux platforms to use the binaries.
The non-NT portion has been moved to wpiutil.
The NT portion has been moved to ntcore (as NTSendable).
SendableBuilder similarly split and moved.
SendableRegistry moved to wpiutil.
In C++, SendableHelper also moved to wpiutil.
This enables use of Sendable from wpimath and also enables
moving several classes from wpilib to wpimath.
Some valid warnings like throwing NullPointerException or using a for
loop instead of System.arraycopy() were fixed.
Abstract classes marked with PMD.AbstractClassWithoutAbstractMethod were
made concrete because they already had protected constructors.
Fixes#1697.
This also fixes a member function name inconsistency between languages
and adds missing documentation to C++'s KalmanFilterLatencyCompensator.
Fixes#3229.
- Twine, StringRef, Format, and NativeFormatting have been removed
- Logging now uses fmtlib style formatting
- Nearly all uses of wpi::outs/errs have been replaced with fmt::print() or
std::puts()/std::fputs() (for unformatted strings).
- A wpi/fmt/raw_ostream.h header has been added to enable
fmt::print() with wpi::raw_ostream
This allows sim modules to be statically linked into an executable to
create a "perfectly static" simulated desktop program. The entry point
was changed to be unique when building static libraries to avoid symbol
collisions.
The implementation of wpi::circular_buffer has been effectively replaced
with a dynamically sized copy of wpi::static_circular_buffer with a
resize() member function.
The units for angular Kv and Ka were inconsistent with the derivation. A
second factory function overload was added for angular units that uses a
trackwidth to convert to the other form.
Notice how section 15.2 of https://file.tavsys.net/control/controls-engineering-in-frc.pdf
defines the angular feedforward as u = Kv,angular v instead of u = Kv,angular + omega.
The units cancel for elements of A but not B, so just the B matrix was incorrect in our code.
This breaks existing C++ code since the units are part of the function
signature.
Use ghc::filesystem as fill on older GCC (e.g. RoboRIO).
This can be removed once all GCC platforms have upgraded to 8.1 or later.
File open functionality has been retained from LLVM but moved to "fs" namespace
and tweaked for improved consistency with std::filesystem (e.g. error_code is
passed by reference instead of returned).
Also update WPILibC's Filesystem functions to return std::string.
The command and shuffleboard integration tests were removed because
their unit tests counterparts already provide adequate coverage. Java
already removed these.
A lot of these are breaking changes. frc::Timer was replaced with the
contents of frc2::Timer. The others were in-place argument changes or
removing deprecated non-unit overloads.
frc/Base.h isn't the first header included basically anywhere, so the
compiler will fail on C++17 things before the asserts in this header are
processed.
This reverts commit a79faace1b.
This change will be superseded in a non-breaking way by changing to static functions and deprecating GetInstance() entirely.
This version incorporated the patch we were manually applying, so we're
synced back up with upstream now except for some minor #include changes
to reduce header bloat.
Substantially improves Mechanism2d by moving it to NetworkTables and adding
a robot API to create the mechanism elements, instead of requiring a JSON file.
Co-authored-by: Peter Johnson <johnson.peter@gmail.com>
The Drive Subsystem was supplying an incorrectly constructed
Rotation2d to the odometry update method. Rotation2d constructor
was being called with heading in degrees, not radians as required.
Also deprecate SpeedController in favor of motorcontrol.MotorController and
SpeedControllerGroup in favor of motorcontrol.MotorControllerGroup.
The MotorController interface is derived from the SpeedController interface
so that code such as SpeedController x = new VictorSP(1) continues to
compile (just with a warning).
SpeedControllerGroup and MotorControllerGroup are independent classes;
both implement the MotorController interface.
This enables use of types that have a no-args constructor rather than one that takes an explicit zero value.
For numeric types, value initialization will result in a zero value, so this is not a functional change.
This sensor has had zero usage for many years and was last in the KOP
over a decade ago. There are much better rotation sensors available,
and it's no longer worth maintaining this class.
- Add raw support for pose lists > 255/3 in length
- Improve drag selection, especially with closely overlapping objects
- Drag selection of corner also highlights center of object with smaller circle
- Multiple styles (box, line, closed line, track)
- Configurable line and arrow settings (color, weight)
- Add tooltip for object name, index, x, y, rotation
- Context menu for pose edit/add/remove
- View/edit in feet or inches as well as meters
- Configurable object selectability
Implementation: use vector of Pose2d internally, use units
Previously the following sequence was broken:
- Add two plot windows (creates Plot<0> and Plot<1>)
- Delete Plot<0>
- Try to create a plot window
This failed because it would try to create Plot<1>, which already existed.
It was necessary to also destroy Plot<1> before another plot could be added.
This change fixes this case by trying all 0-N cases.
Improves consistency across all classes.
Affects Preferences, LiveWindow, and CameraServer.
Old commands Scheduler::GetInstance() was not updated as this is already
deprecated.
This function relies on the behavior of snprintf returning an error value
when the buffer is too small. By default, _snprintf_s aborts on Windows
instead of returning an error value.
This caused Glass to fail when trying to print a large NT value to a string.
On some systems, StopClient et al can take a long time to execute.
Instead run these on a separate thread to avoid blocking the GUI.
Also add option to get IP from DS (default on).
The gyro offset should be determined from the desired initial pose, not the current pose. This fix reflects the behavior of the odometry classes and the C++ holonomic pose estimators.
The atReference() method previously used the rotation error between the
desired trajectory state and the current pose. This was a bug because we
allow teams to use custom rotation setpoints and that wasn't being taken
into account.
This was already removed from C++ in the offseason and replaced with
MathUtil.inputModulus(). We just neglected to do that for Java; it was
never intended to see a season release. Its implementation is incorrect
compared to inputModulus() as well.
See https://github.com/wpilibsuite/allwpilib/issues/3168 for discussion.
Because of Java's type system, it is actually literally impossible to check for this cast at runtime. So instead, the only option is to suppress it. Only suppressed for the specific function.
@@ -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,9 +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):**
- OS: [e.g. Windows]
-Java version [e.g. 1.10.2]
- C++ version [e.g. 17]
- OS: [e.g. Windows 11]
-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]
So you want to contribute your changes back to WPILib. Great! We have a few contributing rules that will help you make sure your changes will be accepted into the project. Please remember to follow the rules in the [code of conduct](https://github.com/wpilibsuite/allwpilib/blob/master/CODE_OF_CONDUCT.md), and behave with Gracious Professionalism.
So you want to contribute your changes back to WPILib. Great! We have a few contributing rules that will help you make sure your changes will be accepted into the project. Please remember to follow the rules in the [code of conduct](https://github.com/wpilibsuite/allwpilib/blob/main/CODE_OF_CONDUCT.md), and behave with Gracious Professionalism.
@@ -37,15 +37,47 @@ So you want to contribute your changes back to WPILib. Great! We have a few cont
## Coding Guidelines
WPILib uses modified Google style guides for both C++ and Java, which can be found in the [styleguide repository](https://github.com/wpilibsuite/styleguide). Autoformatters are available for many popular editors at https://github.com/google/styleguide. Running wpiformat is required for all contributions and is enforced by our continuous integration system. We currently use clang-format 10.0 with wpiformat.
WPILib uses modified Google style guides for both C++ and Java, which can be found in the [styleguide repository](https://github.com/wpilibsuite/styleguide). Autoformatters are available for many popular editors at https://github.com/google/styleguide. Running wpiformat is required for all contributions and is enforced by our continuous integration system.
While the library should be fully formatted according to the styles, additional elements of the style guide were not followed when the library was initially created. All new code should follow the guidelines. If you are looking for some easy ramp-up tasks, finding areas that don't follow the style guide and fixing them is very welcome.
### Math documentation
When writing math expressions in documentation, use https://www.unicodeit.net/ to convert LaTeX to a Unicode equivalent that's easier to read. Not all expressions will translate (e.g., superscripts of superscripts) so focus on making it readable by someone who isn't familiar with LaTeX. If content on multiple lines needs to be aligned in Doxygen/Javadoc comments (e.g., integration/summation limits, matrices packed with square brackets and superscripts for them), put them in @verbatim/@endverbatim blocks in Doxygen or `<pre>` tags in Javadoc so they render with monospace font.
The LaTeX to Unicode conversions can also be done locally via the unicodeit Python package. To install it, execute:
```bash
pip install --user unicodeit
```
Here's example usage:
```bash
$ python -m unicodeit.cli 'x_{k+1} = Ax_k + Bu_k'
xₖ₊₁ = Axₖ + Buₖ
```
On Linux, this process can be streamlined further by adding the following Bash function to your .bashrc (requires `wl-clipboard` on Wayland or `xclip` on X11):
```bash
# Converts LaTeX to Unicode, prints the result, and copies it to the clipboard
uc(){
if[$WAYLAND_DISPLAY];then
python -m unicodeit.cli $@| tee >(wl-copy -n)
else
python -m unicodeit.cli $@| tee >(xclip -sel)
fi
}
```
Here's example usage:
```bash
$ uc 'x_{k+1} = Ax_k + Bu_k'
xₖ₊₁ = Axₖ + Buₖ
```
## Submitting Changes
### Pull Request Format
Changes should be submitted as a Pull Request against the master branch of WPILib. For most changes, commits will be squashed upon merge. For particularly large changes, multiple commits are ok, but assume one commit unless asked otherwise. We may ask you to break a PR into multiple standalone PRs or commits for rebase within one PR to separate unrelated changes. No change will be merged unless it is up to date with the current master. We do this to make sure that the git history isn't too cluttered.
Changes should be submitted as a Pull Request against the main branch of WPILib. For most changes, commits will be squashed upon merge. For particularly large changes, multiple commits are ok, but assume one commit unless asked otherwise. We may ask you to break a PR into multiple standalone PRs or commits for rebase within one PR to separate unrelated changes. No change will be merged unless it is up to date with the current main branch. We do this to make sure that the git history isn't too cluttered.
This article contains instructions on building projects using a development build and a local WPILib build.
**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 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.+
```
The top of your ``build.gradle`` file should now look similar to the code below. Ignore any differences in versions.
Java
```groovy
plugins {
id "java"
id "edu.wpi.first.GradleRIO" version "2024.0.0-alpha-1"
}
wpi.maven.useLocal = false
wpi.maven.useDevelopment = true
wpi.versions.wpilibVersion = '2024.+'
wpi.versions.wpimathVersion = '2024.+'
```
C++
```groovy
plugins {
id "cpp"
id "google-test-test-suite"
id "edu.wpi.first.GradleRIO" version "2024.0.0-alpha-1"
Building with a local build is very similar to building with a development build. Ensure you have built and published WPILib by following the instructions attached [here](https://github.com/wpilibsuite/allwpilib#building-wpilib). Next, find the ``build.gradle`` file in your robot project and open it. Then, add the following code below the plugin section and replace ``YEAR`` with the year of the local version.
Java
```groovy
plugins {
id "java"
id "edu.wpi.first.GradleRIO" version "2024.0.0-alpha-1"
}
wpi.maven.useLocal = false
wpi.maven.useFrcMavenLocalDevelopment = true
wpi.versions.wpilibVersion = 'YEAR.424242.+'
wpi.versions.wpimathVersion = 'YEAR.424242.+'
```
C++
```groovy
plugins {
id "cpp"
id "google-test-test-suite"
id "edu.wpi.first.GradleRIO" version "2024.0.0-alpha-1"
}
wpi.maven.useLocal = false
wpi.maven.useFrcMavenLocalDevelopment = true
wpi.versions.wpilibVersion = 'YEAR.424242.+'
wpi.versions.wpimathVersion = 'YEAR.424242.+'
```
# roboRIO Development
This repo contains a myRobot project built in way to do full project development without needing to do a full publish into GradleRIO. These also only require building the minimum amount of binaries for the roboRIO, so the builds are much faster as well.
The setup only works if the roboRIO is USB connected. If an alternate IP address is preferred, the `address` block in myRobot\build.gradle can be changed to point to another address.
The following 3 tasks can be used for deployment:
* `:myRobot:deployShared` deploys the C++ project using shared dependencies. Prefer this one for most C++ development.
* `:myRobot:deployStatic` deploys the C++ project with all dependencies statically linked.
* `:myRobot:deployJava` deploys the Java project and all required dependencies. Also installs the JRE if not currently installed.
Deploying any of these to the roboRIO will disable the current startup project until it is redeployed.
From here, ssh into the roboRIO using the `lvuser` account and run `frcRunRobot.sh` (It's in path).
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).
@@ -11,10 +11,10 @@ For Java dependencies, there is likely a file related to the specific dependency
Note, changing artifact locations (This includes changing the artifact year currently, I have an issue open to change this) requires updating the `native-utils` plugin
## Publishing allwpilib
allwpilib publishes to the development repo on every push to master. To publish a release build, upload a new tag, and a release will automatically be built and published.
allwpilib publishes to the development repo on every push to main. To publish a release build, upload a new tag, and a release will automatically be built and published.
## Publishing desktop tools
Desktop tools publish to the development repo on every push to master. To publish a release build, upload a new tag, and a release will automatically be built and published.
Desktop tools publish to the development repo on every push to main. To publish a release build, upload a new tag, and a release will automatically be built and published.
## Publishing VS Code
Before publishing, make sure to update the gradlerio version in `vscode-wpilib/resources/gradle/version.txt` Also make sure the gradle wrapper version matches the wrapper required by gradlerio.
@@ -24,4 +24,4 @@ Upon pushing a tag, a release will be built, and the files will be uploaded to t
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.
The release repository is where official WPILib releases are pushed.
The development repository is where development releases of every commit to [master](https://github.com/wpilibsuite/allwpilib/tree/master) is pushed.
The development repository is where development releases of every commit to [main](https://github.com/wpilibsuite/allwpilib/tree/main) is pushed.
## Artifact classifiers
We provide two base types of artifacts.
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
@@ -69,24 +69,53 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
* wpiutil
*hal
*wpigui
* imgui
* wpimath
* wpiutil
*halsim
* imgui
*wpinet
* wpiutil
* ntcore
* wpiutil
* wpinet
* glass/libglass
* wpiutil
* wpimath
* wpigui
* glass/libglassnt
* wpiutil
* wpinet
* ntcore
* wpimath
* wpigui
* hal
* wpiutil
* halsim
* wpiutil
* wpinet
* ntcore
* wpimath
* wpigui
* libglass
* libglassnt
* cscore
* opencv
* wpinet
* wpiutil
* cameraserver
* ntcore
* cscore
* opencv
* wpinet
* wpiutil
* wpilibj
@@ -94,6 +123,7 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
* cameraserver
* ntcore
* cscore
* wpinet
* wpiutil
* wpilibc
@@ -101,6 +131,8 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
* cameraserver
* ntcore
* cscore
* wpimath
* wpinet
* wpiutil
* wpilibNewCommands
@@ -109,15 +141,15 @@ All artifacts are based at `edu.wpi.first.artifactname` in the repository.
* cameraserver
* ntcore
* cscore
* wpimath
* wpinet
* wpiutil
* wpilibNewCommands
* wpilibc
*hal
* cameraserver
* ntcore
* cscore
* wpiunits
*apriltag
* wpiutil
* wpimath
### Third Party Artifacts
@@ -125,6 +157,8 @@ This repository provides the builds of the following third party software.
All artifacts are based at `edu.wpi.first.thirdparty.frcYEAR` in the repository.
This article contains instructions on building projects using a development build and a local WPILib build.
**Note:** This only applies to Java/C++ teams.
## Development Build
Development builds are the per-commit build hosted everytime a commit is pushed to the [allwpilib](https://github.com/wpilibsuite/allwpilib/) repository. These builds are then hosted on [artifactory](https://frcmaven.wpi.edu/artifactory/webapp/#/home).
In order to build a project using a development build, find the build.gradle file and open it. Then, add the following code below the plugin section and replace YEAR with the year of the development version.
```groovy
wpi.maven.useDevelopment=true
wpi.wpilibVersion='YEAR.+'
wpi.wpimathVersion='YEAR.+
```
The top of your ``build.gradle`` file should now look similar to the code below. Ignore any differences in versions.
Java
```groovy
plugins {
id "java"
id "edu.wpi.first.GradleRIO" version "2020.3.2"
}
wpi.maven.useDevelopment = true
wpi.wpilibVersion = '2021.+'
wpi.wpimathVersion = '2021.+'
```
C++
```groovy
plugins {
id "cpp"
id "google-test-test-suite"
id "edu.wpi.first.GradleRIO" version "2020.3.2"
}
wpi.maven.useDevelopment = true
wpi.wpilibVersion = '2021.+'
wpi.wpimathVersion = '2021.+'
```
## Local Build
Building with a local build is very similar to building with a development build. Ensure you have built and published WPILib by following the instructions attached [here](https://github.com/wpilibsuite/allwpilib#building-wpilib). Next, find the ``build.gradle`` file in your robot project and open it. Then, add the following code below the plugin section and replace ``YEAR`` with the year of the local version.
@@ -12,14 +12,20 @@ WPILib is normally built with Gradle, however for some systems, such as Linux ba
* halsim
* wpigui
* wpimath
* wpiunits
* wpilibNewCommands
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.
## 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 to build OpenCV from source and install it.
The jinja2 pip package is needed to generate classes for NT4's pubsub.
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.
The protobuf library and compiler are needed for protobuf generation. The QuickBuffers protoc-gen package is also required when Java is being built; this can be obtained from https://github.com/HebiRobotics/QuickBuffers/releases/.
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 11 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.
@@ -29,16 +35,26 @@ 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_JAVA_SOURCE` (ON 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_SHARED_LIBS` (ON Default)
* This option will cause cmake to build static libraries instead of shared libraries. If this is off, `WITH_JAVA` must be off. Otherwise CMake will error.
*`WITH_TESTS` (ON Default)
* This option will build C++ unit tests. These can be run via `make test`.
*`WITH_CSCORE` (ON Default)
* This option will cause cscore to be built. Turning this off will implicitly disable cameraserver, the hal and wpilib as well, irrespective of their specific options. If this is off, the OpenCV build requirement is removed.
*`WITH_NTCORE` (ON Default)
* This option will cause ntcore to be built. Turning this off will implicitly disable wpinet and wpilib as well, irrespective of their specific options.
*`WITH_WPIMATH` (ON Default)
* This option will build the wpimath library. This option must be on to build wpilib.
*`WITH_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_WPILIB` (ON Default)
* This option will build the hal and wpilibc/j during the build. The HAL is the simulator hal, unless the external hal options are used. The cmake build has no capability to build for the RoboRIO.
*`WITH_EXAMPLES` (ON Default)
* This option will build C++ examples.
*`WITH_TESTS` (ON Default)
* This option will build C++ unit tests. These can be run via `make test`.
*`WITH_GUI` (ON Default)
* This option will build GUI items.
*`WITH_SIMULATION_MODULES` (ON Default)
* This option will build simulation modules, including wpigui and the HALSim plugins.
*`WITH_EXTERNAL_HAL` (OFF Default)
@@ -47,6 +63,8 @@ The following build options are available:
* TODO
*`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
@@ -87,7 +105,7 @@ 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.
Welcome to the WPILib project. This repository contains the HAL, WPILibJ, and WPILibC projects. These are the core libraries for creating robot programs for the roboRIO.
@@ -15,9 +15,9 @@ Welcome to the WPILib project. This repository contains the HAL, WPILibJ, and WP
- [Faster builds](#faster-builds)
- [Using Development Builds](#using-development-builds)
- [Formatting/linting with wpiformat](#formattinglinting-with-wpiformat)
- [Formatting/Linting](#formattinglinting)
- [CMake](#cmake)
- [Running examples in simulation](#running-examples-in-simulation)
- [Publishing](#publishing)
- [Structure and Organization](#structure-and-organization)
- [Contributing to WPILib](#contributing-to-wpilib)
@@ -26,32 +26,43 @@ Welcome to the WPILib project. This repository contains the HAL, WPILibJ, and WP
The WPILib Mission is to enable FIRST Robotics teams to focus on writing game-specific software rather than focusing on hardware details - "raise the floor, don't lower the ceiling". We work to enable teams with limited programming knowledge and/or mentor experience to be as successful as possible, while not hampering the abilities of teams with more advanced programming capabilities. We support Kit of Parts control system components directly in the library. We also strive to keep parity between major features of each language (Java, C++, and NI's LabVIEW), so that teams aren't at a disadvantage for choosing a specific programming language. WPILib is an open source project, licensed under the BSD 3-clause license. You can find a copy of the license [here](LICENSE.md).
# Quick Start
Below is a list of instructions that guide you through cloning, building, publishing and using local allwpilib binaries in a robot project. This quick start is not intended as a replacement for the information further listed in this document.
1. Clone the repository with `git clone https://github.com/wpilibsuite/allwpilib.git`
2. Build the repository with `./gradlew build` or `./gradlew build --build-cache` if you have an internet connection
3. Publish the artifacts locally by running `./gradlew publish`
4. [Update your](DevelopmentBuilds.md) `build.gradle` [to use the artifacts](DevelopmentBuilds.md)
# Building WPILib
Using Gradle makes building WPILib very straightforward. It only has a few dependencies on outside tools, such as the ARM cross compiler for creating roboRIO binaries.
- Note that the JRE is insufficient; the full JDK is required
- On Ubuntu, run `sudo apt install openjdk-11-jdk`
- On Windows, install the JDK 11 .msi from the link above
- On macOS, install the JDK 11 .pkg from the link above
- C++ compiler
- On Linux, install GCC 7 or greater
- On Windows, install [Visual Studio Community 2019](https://visualstudio.microsoft.com/vs/community/) and select the C++ programming language during installation (Gradle can't use the build tools for Visual Studio 2019)
- On macOS, install the Xcode command-line build tools via `xcode-select --install`
- On Linux, install GCC 11 or greater
- On Windows, install [Visual Studio Community 2022](https://visualstudio.microsoft.com/vs/community/) and select the C++ programming language during installation (Gradle can't use the build tools for Visual Studio)
- On macOS, install the Xcode command-line build tools via `xcode-select --install`. Xcode 13 or later is required.
- ARM compiler toolchain
- Run `./gradlew installRoboRioToolchain` after cloning this repository
- If the WPILib installer was used, this toolchain is already installed
- Raspberry Pi toolchain (optional)
- Run `./gradlew installRaspbianToolchain` after cloning this repository
- Run `./gradlew installArm32Toolchain` after cloning this repository
On macOS ARM, run `softwareupdate --install-rosetta`. This is necessary to be able to use the macOS x86 roboRIO toolchain on ARM.
## Setup
Clone the WPILib repository and follow the instructions above for installing any required tooling.
See the [styleguide README](https://github.com/wpilibsuite/styleguide/blob/master/README.md) for wpiformat setup instructions.
See the [styleguide README](https://github.com/wpilibsuite/styleguide/blob/main/README.md) for wpiformat setup instructions.
## Building
@@ -71,19 +82,44 @@ The gradlew wrapper only exists in the root of the main project, so be sure to r
There are a few tasks other than `build` available. To see them, run the meta-task `tasks`. This will print a list of all available tasks, with a description of each task.
If opening from a fresh clone, generated java dependencies will not exist. Most IDEs will not run the generation tasks, which will cause lots of IDE errors. Manually run `./gradlew compileJava` from a terminal to run all the compile tasks, and then refresh your IDE's configuration (In VS Code open settings.gradle and save).
### Faster builds
`./gradlew build` builds _everything_, which includes debug and release builds for desktop and all installed cross compilers. Many developers don't need or want to build all of this. Therefore, common tasks have shortcuts to only build necessary components for common development and testing tasks.
`./gradlew testDesktopCpp` and `./gradlew testDesktopJava` will build and run the tests for `wpilibc` and `wpilibj` respectively. They will only build the minimum components required to run the tests.
`./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``wpilibOldCommands`, `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.
### Build Cache
Run with `--build-cache` on the command-line to use the shared [build cache](https://docs.gradle.org/current/userguide/build_cache.html) artifacts generated by the continuous integration server. Example:
```bash
./gradlew build --build-cache
```
### Using Development Builds
Please read the documentation available [here](OtherVersions.md)
Please read the documentation available [here](DevelopmentBuilds.md)
### Custom toolchain location
@@ -93,39 +129,34 @@ If you have installed the FRC Toolchain to a directory other than the default, o
If you also want simulation to be built, add -PmakeSim. This requires gazebo_transport. We have tested on 14.04 and 15.05, but any correct install of Gazebo should work, even on Windows if you build Gazebo from source. Correct means CMake needs to be able to find gazebo-config.cmake. See [The Gazebo website](https://gazebosim.org/) for installation instructions.
```bash
./gradlew build -PmakeSim
```
If you prefer to use CMake directly, the you can still do so.
The common CMake tasks are wpilibcSim, frc_gazebo_plugins, and gz_msgs
```bash
mkdir build #run this in the root of allwpilib
cd build
cmake ..
make
```
### Formatting/linting
Once a PR has been submitted, formatting can be run in CI by commenting `/format` on the PR. A new commit will be pushed with the formatting changes.
#### wpiformat
wpiformat can be executed anywhere in the repository via `py -3 -m wpiformat` on Windows or `python3 -m wpiformat` on other platforms.
#### Java Code Quality Tools
The Java code quality tools (checkstyle, pmd, etc.) can be run with the`./gradlew javaFormat` task.
The Java code quality tools Checkstyle, PMD, and Spotless can be run via`./gradlew javaFormat`. SpotBugs can be run via the `spotbugsMain`, `spotbugsTest`, and `spotbugsDev` tasks. These tools will all be run automatically by the `build` task. To disable this behavior, pass the `-PskipJavaFormat` flag.
If you only want to run the Java autoformatter, run `./gradlew spotlessApply`.
### CMake
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:
@@ -139,13 +170,13 @@ The maven artifacts are described in [MavenArtifacts.md](MavenArtifacts.md)
## Structure and Organization
The main WPILib code you're probably looking for is in WPILibJ and WPILibC. Those directories are split into shared, sim, and athena. Athena contains the WPILib code meant to run on your roboRIO. Sim is WPILib code meant to run on your computer with Gazebo, and shared is code shared between the two. Shared code must be platform-independent, since it will be compiled with both the ARM cross-compiler and whatever desktop compiler you are using (g++, msvc, etc...).
The Simulation directory contains extra simulation tools and libraries, such as gz_msgs and JavaGazebo. See sub-directories for more information.
The main WPILib code you're probably looking for is in WPILibJ and WPILibC. Those directories are split into shared, sim, and athena. Athena contains the WPILib code meant to run on your roboRIO. Sim is WPILib code meant to run on your computer, and shared is code shared between the two. Shared code must be platform-independent, since it will be compiled with both the ARM cross-compiler and whatever desktop compiler you are using (g++, msvc, etc...).
The integration test directories for C++ and Java contain test code that runs on our test-system. When you submit code for review, it is tested by those programs. If you add new functionality you should make sure to write tests for it so we don't break it in the future.
The hal directory contains more C++ code meant to run on the roboRIO. HAL is an acronym for "Hardware Abstraction Layer", and it interfaces with the NI Libraries. The NI Libraries contain the low-level code for controlling devices on your robot. The NI Libraries are found in the ni-libraries folder.
The hal directory contains more C++ code meant to run on the roboRIO. HAL is an acronym for "Hardware Abstraction Layer", and it interfaces with the NI Libraries. The NI Libraries contain the low-level code for controlling devices on your robot. The NI Libraries are found in the [ni-libraries](https://github.com/wpilibsuite/ni-libraries) project.
The upstream_utils directory contains scripts for updating copies of thirdparty code in the repository.
The [styleguide repository](https://github.com/wpilibsuite/styleguide) contains our style guides for C++ and Java code. Anything submitted to the WPILib project needs to follow the code style guides outlined in there. For details about the style, please see the contributors document [here](CONTRIBUTING.md#coding-guidelines).
* findToteThread = new VisionThread(usbCamera, findTotePipeline, this);
* }
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.