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.
This fixes an issue with scaling on Retina displays where the frame
buffer size was double that of the window size, resulting in a content
scale factor of 2. This scale factor caused elements to appear too
large, even on the smallest zoom setting.
This change does not affect external monitors on macOS because the
reported content scale was 1 anyway.
The ranges and which value was specified as highest were incorrect on
some of them. On Linux, the range is 1 to 99 with 99 being highest.
From `man 7 sched`:
```
Processes scheduled under one of the real-time policies (SCHED_FIFO,
SCHED_RR) have a sched_priority value in the range 1 (low) to 99 (high).
```
Also clean up the relevant javadoc and doxygen comments.
Instead of "/SmartDashboard/name" they now default to "name (SmartDashboard)".
This allows for smaller windows while preserving the name without requiring
user customization.
The wpimath APIs use std::array, which doesn't do size checking. Passing
an array with the wrong size can result in uninitialized elements
instead of a compilation error.
This is a breaking change but is worthwhile to avoid hard-to-debug errors.
- Remove sim checkstyle suppression
- Add [[nodiscard]] to C++ register callback functions
- Add a couple of missing sim functions
Co-authored-by: Peter Johnson <johnson.peter@gmail.com>
Co-authored-by: Starlight220 <yotamshlomi@gmail.com>
This also shifts the trajectory up and to the right so that the robot is
always visible in the Field GUI during traversal. Some drive constants
and trajectory constraints were also synced between the two languages.
This modifies the mecanum drive, differential drive, speed controller,
and PID controller widgets to only be writeable when .controllable is
set to true.
The stall torque, stall current, and free current are now multiplied by
the number of motors instead of just the stall torque. This produces the
same values for Kt and Kv regardless of the number of motors; the motor
resistance still affects the system response.
For an elevator model, the response should be the same as before since a
factor of "number of motors" shows up in the same place in the
acceleration calculation, but the current calculation will also be
correct now.
Using the plant output means that measurement noise can be incorporated.
SingleJointedArmSim (in C++ and Java) and ElevatorSim (in C++) used the
state instead of the measurement.
Closes#3042
Flip the TeleopArcadeDrive axis directions so that positive
values for x-axis speed result in the Romi driving forward (in the
direction of the Raspberry Pi USB ports).
frc::NormalizeAngle(), units::math::NormalizeAngle(), and
frc::GetModulusError() were replaced with frc::InputModulus() and
frc::AngleModulus().
They were placed in wpimath/src/main/native/include/frc/MathUtil.h for
C++ and wpimath/src/main/java/edu/wpi/first/wpiutil/math/MathUtil.java
for Java.
* Add .clang-tidy configuration.
* A separate .clang-tidy is used for hal includes to suppress modernize-use-using
(as these are C headers).
* Add NOLINT where necessary for a clean run.
* Add clang-tidy job to lint-format workflow. This workflow is now only run on PRs.
To reduce runtime, clang-tidy is only run on files changed in the PR.
Two wpilibc changes; both are unlikely to break user code:
* BuiltInAccelerometer: Make SetRange() final
* Counter: Make SetMaxPeriod() final
After these cleanups, the only file that does not run cleanly is
cscore_raw_cv.h due to it not being standalone.
Updated the RomiReference example to have autonomous example.
Updated RomiReference and both Romi templates to use Encoder.getDistance().
Removed motor inversion.
A few virtual functions are called by constructors or destructors, which is
dangerous in C++ (as an overridden virtual impl won't be called, only the
one in the current class). Fix by either marking the function final or
not calling at all (if possible).
Also update Checkstyle to 8.38.
Google changed their style guide from the last time we imported it. This PR brings in those naming changes. The change they made is allowing single letter member, parameter, and local variable names. They also added a lambda naming scheme and I thought it would be good to bring that in too.
This makes code easier to read and more consistent between C++ and Java.
Also update clang-format settings to always add a line break (even if no braces are used).
This adds an overload of UnscentedKalmanFilter::Correct() that takes a
custom measurement covariance but uses default mean and residual
calculation functions.
Closes#2965.
This is a breaking change to the WebSockets layer to align it with
recent specification documentation work.
To support this, HAL SimValue changed readonly to a direction enum.
This allows specifying bidirectional in addition to input and output.
The SimValue change is specifically designed to avoid API and ABI breakage.
This is completely transparent in C++; in Java a new callback class was added,
and the old readonly functions have been marked deprecated.
A new SimValue creation function for enums allows specifying double values
for each enum value, not just strings. This allows mapping enum values to
doubles in the WebSockets layer.
A ":" in the SimDevice name now maps it to different WebSocket types (e.g.
"Accel:Name" becomes type "Accel", device "Name"). The type is hidden
in the GUI.
Other WebSockets changes:
* Implemented match_time and game_data
* Added joystick rumble data
* Added builtin accelerometer support
* SimValue enums are mapped to string and double value on WS interface
* Added WebSockets protocol specification
* Added READMEs
If the strncpy() bound is equal to the destination size and the source
string is longer than 256 bytes, strncpy() won't write a null terminator
for the destination string.
This allows joystick testing without a physical joystick.
Comes with a default set of keyboard mappings, but these are fully customizable by the user.
Up to 4 virtual joysticks are supported.
Default keyboard mappings:
Joystick 0: axis 0: AD, axis 1: WS, axis 2: ER, buttons ZXCV, POV on numeric keypad
Joystick 1: axis 0: JL, axis 1: IK, buttons M,./
Joystick 2: axis 0: left/right arrow, axis 1: up/down arrow, buttons insert/home/pgup/del/end/pgdn
Also adds support for DS-style hotkeys of []\ enable, Enter disable, and spacebar disable.
All of these are disabled by default and must be explicitly enabled by the user.
Currently, Encoder.reset() must make a round trip to the sensor and back
in order for the count to be updated for the user program. As the sim layer
also resets the internal encoder count, this creates a race condition (a WS
message with a new count can be "in flight" during a reset and update the
count).
This changes the WS layer to not put reset on the wire, but instead keep an
offset count internal to the robot program. The value on the wire is not
reset, but rather all sends and receives are adjusted as necessary to the
internal robot count.
This approach is straightforward, but does result in the value on the wire
not matching the value in the user program. A future improvement will fix
this, but this change fixes the immediate race condition problem.
The change to SendableBuilder to add GetTable() added a virtual function
early in the class definition. This is an ABI break for vendor libraries.
Attempt to workaround this breakage by moving GetTable() to the end of the
class definition.
This will make is so we can get the right artifact to the installer, and we can do it automatically and its guaranteed to match what built the artifacts.
This reuses many pieces of the current simulation GUI. The common pieces have
been refactored into the libglass library.
The libglass library is designed to be usable for other standalone data
visualization applications (e.g. viewing data logs).
The name "glass" comes from "glass cockpit", as the application features
several multi-function displays that can be adjusted to display robot
information as needed.
Pose and state estimators can filter latency-compensated global measurements and fuse them with state-space drivetrain model information to estimate robot position. They are drop-in replacements for the existing odometry classes.
Co-authored-by: Declan Freeman-Gleason <declanfreemangleason@gmail.com>
Co-authored-by: Prateek Machiraju <prateek.machiraju@gmail.com>
Co-authored-by: Claudius Tewari <cttewari@gmail.com>
Co-authored-by: Matt <matthew.morley.ca@gmail.com>
This makes AtSetpoint() return false after the setpoint is changed with
SetSetpoint().
Closes#2821.
Co-authored-by: Prateek Machiraju <prateek.machiraju@gmail.com>
This fixes an issue with some commands not correctly requiring their
subsytems. Furthermore, an execute() method was added to the
DriveDistance command to continuously update the voltage command.
Also deletes object files.
Both of these things are only done on the build server (-PbuildServer flag).
This will remove all test folders, which removes lots of copies of dependencies.
This also fixes an issue where gtest exectubables were installed for cross builds, even though they should not have been.
This bumps the version number of thirdparty-imgui in Gradle and adds
imgui_stdlib.cpp into the sources in CMake, as well as adding a new
include directory.
This issue only existed on the initial iteration. When timing is paused and stepped,
initialize() and execute() get called with the same timestamp the first time, which
would result in a divide by zero. All subsequent steps advance timing and only
call execute() so the time deltas are all set correctly.
There were three options for where to put this function:
1. A free function in LinearQuadraticRegulator.h. Returning a K matrix
means the user can't use the LinearQuadraticRegulator in a loop
anymore.
2. A default argument added to ctors in LinearQuadraticRegulator for a
time delay (default of 0). This has the smallest API footprint from
the user perspective, but it bloats the already substantial
constructor overload set of LinearQuadraticRegulator.
3. A member function in LinearQuadraticRegulator that modifies the
internal K. This would still have to take in a LinearSystem or (A, B)
pair because the ctor doesn't store it. Storing it internally feels
like paying for what we don't use most of the time.
I went with option 3.
I verified the tests's expected values in Python with
scipy.linalg.fractional_matrix_power().
Closes#2877.
If a Sendable like SendableChooser is destroyed and recreated, it leaves
a stale object in the Sendable registry. Using this object results in a
crash. This patch avoids using the stale object.
We should remove stale objects from the global registry upon object
destruction, but this fixes the crashing issue for now.
Closes#2818.
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
Previously this sent just the raw analog value; the scaled value is likely what users expect.
Co-authored-by: Corey Applegate <coreya@centralmcgowan.com>
- Add link to code of conduct
- Update clang version used to 10 to match CI
- Update pull request format to match current practice
- Change Azure references to Actions
This address some problems with the LinearSystemLoop class that were discovered through testing.
The initial state estimate of the observer was set to the provided initial state rather than zero as previously, a non zero initial state passed into reset() would lead to a discrepancy between the current state estimate and the actual system state.
The CMake enable/disable flags as currently structured are a confusing mix of
WITH, WITHOUT, and USE with odd defaults. This changes the flags to consistently
use WITH and default the build options to everything enabled.
Currently, StepTiming() advances the time by the given delta, then runs
any Notifiers that expired within that timeframe until their expiration
times are in the future. This doesn't reflect how the Notifiers would
actually run on a real robot. For example, if a Notifier measures the
time between calls for state-space model advancement, it would measure
a large jump in time once, then zero for subsequent runs until the
Notifier was caught up to the current time.
With this change, the time is incremented by the full delta or until the
soonest Notifier, whichever has the smaller delta, then Notifiers set to
expire at that time are run. This is repeated until the time has been
advanced by the full delta. For the state-space model Notifier situation
mentioned before, it would measure multiple small time jumps instead of
one big one.
Currently, teams have to make a Notifier to run feedback controllers
more often than the TimedRobot loop period of 20ms (running TimedRobot
more often than this is not advised). This lets users add callbacks to
the main robot loop that run at a user-defined period. This allows
running feedback controllers more often, but does so synchronously with
TimedRobot so there aren't any thread safety issues.
To make the tests reliable, the synchronization in simulation Notifiers
had to be reworked. StepTiming() now waits for all Notifiers to reach
HAL_WaitForNotifierAlarm(), then steps the time, then lets any expired
Notifiers run.
While there, we made some variable names more descriptive and added more
comments.
There were three bugs:
1. The input range variables used in ProfiledPIDController::Calculate()
weren't being updated
2. The modulus error calculation was incorrect.
3. The setpoint wasn't being wrapped like the goal, so the invariant
that the error remains less than half the input range was violated.
(Thanks to @CptJJ for pointing this out and suggesting a fix.)
By storing the previous dt, it can be moved into Correct() where it is
actually used. This lets us take the continuous R as an argument in the
user-provided R overload.
This does not introduce any breaking changes for teams that used the TrajectoryGenerator API for
quintic splines with poses.
The GetQuinticControlVectorsFromWaypoints() method was removed because it is not possible for us (or
would require breaking changes to the shape of the splines) to generate only one quintic control vector
per Pose2d. Users who actually have control vectors directly (i.e. not from Pose2d objects, but a
dashboard such as PathWeaver) should have the number of control vectors correspond to the number of
"waypoints" and can call GetQuinticSplinesFromControlVectors() directly.
Based on run of include-what-you-use.org to identify unused include files in various .h and .cpp files.
The changes mostly fall into 3 categories:
- Actually unused includes - copy-paste errors, not removing includes after cleaning up code, etc
- A too-broad include used where a more specific (and hopefully smaller) header will do
- Interface .h files including headers only needed by the .cpp implementation - moving from .h to .cpp
will mean that code which uses the .h doesn't pay the price of processing the header file they don't need
Old behavior is available via StepTimingAsync.
This makes it significantly easier to use simulation timing with notifiers.
Also update tests to use simulation framework. This also speeds up the
timing-dependent tests by using simulation timing. ResourceLock is used
in the Java tests to prevent parallel execution.
While we're here, tweak HAL Notifier implementation:
- Use wait_for instead of wait_until in WaitForNotifierAlarm
- Check for triggerTime = UINT64_MAX in UpdateNotifierAlarm
If the model is unstable, it will almost always diverge within 10
seconds, and the results are rather dramatic. We're also reducing the
threshold to 100 meters because the drivetrain is moving in a small
circle. The translation norm is also used for this reason; the X
component alone regularly crosses zero since the drivetrain moves in a
circle.
This isn't appropriate for a RAII class. In particular, it can cause
foot-shooting in simulation mode if the result of
HALSIM_GetSimDeviceHandle is passed instead of HAL_CreateSimDevice.
Some vestigial functions were never removed, and C++ single-jointed arm
sim was missing a flag for disabling gravity simulation. This is useful
for mechanisms like turrets.
Fixes#2738.
The Gradle heap size is currently set to 1G, and that's becoming too
small for our Linux build.
Developers who want to override this without editing the project's
build.gradle can override these settings with gradle.properties in
GRADLE_USER_HOME (see
https://docs.gradle.org/current/userguide/build_environment.html for
details).
In the second constructor, a new LinearSystem is created and set to
m_plant. This takes a const ref though, so it's storing a reference to a
temporary object. After the constructor finishes, m_plant points to an
invalid object. When Update() is called, it will crash with a
segmentation fault.
This patch fixes the use-after-free by making m_plant a LinearSystem
value type. The first constructor will generate a copy, but that only
happens once.
This includes physics simulation support for arms/elevator models, as well as differential drivetrains.
Swerve might be added at a later date.
Co-authored-by: Claudius Tewari <cttewari@gmail.com>
Co-authored-by: Prateek Machiraju <prateek.machiraju@gmail.com>
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
This helps reduce compilation overhead. I tried slimming down includes
of <Eigen/QR>, but the householderQr() function we use from there
requires including dependency headers from Eigen that don't fit with
lexographic ordering. It didn't seem worth the effort to work around.
This won't affect user code at all since all the Eigen feature usage
here is internal only; users generally only need <Eigen/Core>.
It was added as part of Bryson's rule described in
https://file.tavsys.net/control/controls-engineering-in-frc.pdf. It
doesn't really simplify usage though, and the same thing can be
replicated by multiplying the elements of Q by rho manually. It's easier
to do it that way, it's how 3512 has been doing controller debugging for
a while, and it's probably what other teams will do as well instead of
using the "more structured" way.
Removing these unhelpful overloads also simplifies the LQR interface.
The uid was getting incremented by 1 during registration but not decremented
by 1 during cancellation, so cancellation didn't work correctly.
As the underlying registration ensures a non-zero result, don't increment
the result.
I didn't notice a performance difference between the original
implementation and this one for a flywheel simulation, so this
simplifies a lot of internals.
This class can no longer implement KalmanTypeFilter because that class
allows setting the error covariance for use in the
KalmanFilterLatencyCompensator class. This won't impact the holonomic pose
estimators that use KalmanFilterLatencyCompensator because they all use an EKF.
The platform-specific code now only has create, update, and delete texture.
Image reading functions have been moved to common code.
Also add pixel data functions and image data functions in addition to image
file loading.
SourceLink embeds the git repo and hash into the pdbs, which allows VS to get the source files exactly matching a pdb directly from github.
Only VS and WinDbg are supported currently, but there are issues in the vscode tools repo to enable it there.
This avoids users having to call both IsOperatorControl() and IsEnabled() to figure out if their robot is
enabled and in the teleop state. The expression above involves calling two methods that each have their
own lock.
These new methods should only involve locking one mutex, since only one call is made to HAL_GetControlWord().
These hide the platform specifics behind a common C++ API. Platforms:
- Windows: DirectX 11 (with 10 backwards compatibility)
- Linux: OpenGL 3
- Mac: Metal
This allows access to HAL-level simulation data via a WebSocket connection.
The server additionally serves local files.
The following environment variables can be used for configuration:
HALSIMWS_USERROOT (server) - local directory to use for file serving for /user/ URIs, defaults to ./sim/user
HALSIMWS_SYSROOT (server) - local directory to use for file serving for all other URIs, defaults to ./sim
HALSIMWS_URI (client or server) - WebSocket URI, defaults to /wpilibws
HALSIMWS_PORT (client or server) - port number, defaults to 8080
HALSIMWS_HOST (client) - host to connect to, defaults to localhost
Co-authored-by: Zhiquan Yeo <zyeo8@bloomberg.net>
Co-authored-by: Peter Johnson <johnson.peter@gmail.com>
Co-authored-by: jpokornyiii <jpokornyiii@gmail.com>
Testing Actions
use home env variable
Use ~ instead of home
update upload-artifact to v2
Do not specifiy branch glob
Fix architecture typo
Simplify on block
Add apt-get update step
Revert tolerance increase
Add publishing
Add vcpkg
The wpimath library is a new library designed to separate the reusable math functionality
from the common utility library (wpiutil) and the hardware-dependent library (wpilibc/j).
Package names / include file names were NOT changed to minimize breakage. In a future year
it would be good to revamp these for a more uniform user experience and to reduce the risk
of accidental naming conflicts.
While theoretically all of this functionality could be placed into wpiutil, several pieces
of this library (e.g. DARE) are very time-consuming to compile, so it's nice to avoid this
expense for users who only want cscore or ntcore. It also allows for easy future separation
of build tasks vs number of workers on memory-constrained machines.
This moves the following functionality from wpiutil into wpimath:
- Eigen
- ejml
- Drake
- DARE
- wpiutil.math package (Matrix etc)
- units
And the following functionality from wpilibc/j into wpimath:
- Geometry
- Kinematics
- Spline
- Trajectory
- LinearFilter
- MedianFilter
- Feed-forward controllers
Drake is a collection of tools for analyzing robot dynamics and building control systems.
See https://drake.mit.edu/ for details.
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
The Gradle heap size default is 512M, and that's becoming too small for our builds.
Developers who want to override this without editing the project's build.gradle can
override these settings with gradle.properties in GRADLE_USER_HOME (see
https://docs.gradle.org/current/userguide/build_environment.html for details).
Currently, these two tests take several seconds to complete and fail
intermittently in Windows CI. This is caused by relying on wall clock
time.
Sampling the trajectory with wall clock time means the simulation must
run for several seconds to reach the end of the trajectory. Also, the
controller can become unstable when Windows CI experiences process
scheduling delays of several hundred milliseconds. Feedback controllers
don't cope well with large delays on systems with fast dynamics.
This patch uses the mocking functionality of frc::Timer to advance the
clock by 5ms at every timestep instead of using the wall clock time.
This has two benefits:
1. The tests complete much faster because the simulation can step
forward faster than real time.
2. The controller is more stable because the sample period is uniform,
which should fix the occasional failures.
Remove WaitForCachedData as it's no longer required.
Also properly handle caching / transition detection logic that occurs at the
WPILib level.
This also changes DriverStation::IsNewControlData() to check for WPILib-level
caching instead of wrapping the HAL function.
The new getRotation2d() method in the Gyro interface was passing
an angle in degrees to a constructor that accepts radians.
Use fromDegrees() factory function instead.
Using GetAverageVoltage will reduce the noise in potentiometer reading. Potentiometers are unlikely to be used where the minimal lag averaging introduces would impact control loop stability.
This makes it much more user-friendly to use simulation classes without needing
to ifdef for C++ to avoid linker errors or be very careful about construction
to avoid runtime errors in Java.
This is a derived class of HttpServerConnection that implements the
WebSocket upgrade pieces. This combination is pretty common so is
worth refactoring here.
When not direct mapped, make index constructors private and add factory
functions for channel and index.
Co-authored-by: GabrielDeml <gabrielddeml@gmail.com>
This allows disabling/enabling SimDevices via prefix matching. This can be
used to force devices that normally use SimDevice in simulation mode to
instead talk directly to the hardware as in normal operation.
pose.Translation().X() and pose.Translation.Y() are common operations,
so shortening them to pose.X() and pose.Y() would be convenient.
Java uses the getX() convention so that is used instead of X() for Java.
We already have predefined linear acceleration units and angular
velocity units. This makes defining acceleration constraints for angular
trapezoid profiles more convenient.
No tests were added for this because the base unit conversions are
already tested. Angular acceleration just adds another time dimension.
With the new extraction method, we would need to provide an opencv. However, all of our tools that use opencv use an alternate version of OpenCV, so that would interfere.
This adds an artifact where opencv is statically linked into cscore, but wpiutil is a shared dependency. This solves some shared state hacks, and the extraction works so much better, so its worth making this change to allow that
Also move some things in HAL for consistency.
WAS:
C++:
- C APIs: #include "mockdata/AccelerometerData.h"
- User side class: #include "simulation/AccelerometerSim.h"
Java:
- JNI APIs: hal.sim.mockdata.AccelerometerData (and a few classes in hal.sim)
- User side classes: hal.sim.AccelerometerSim
IS:
C++:
- C APIs: #include "hal/simulation/AccelerometerData.h"
- C++ class: #include "frc/simulation/AccelerometerSim.h"
Java:
- JNI APIs: hal.simulation.AccelerometerData
- User side class: wpilibj.simulation.AccelerometerSim
* Add new combined native class loader
Allows us to extract a list of binaries that depend on each other, and load them successfully
It is correct that there is no implementation in wpiutil for the new native method. That is a requirement, because its needed to load the libraries, and we cant load the wpiutiljni native library since it depends on wpiutil. Instead we have a separate library built with the tools plugin that handles everything
Previously this would list ALL /dev/video* devices. In recent versions of
Linux this leads to listing duplicate devices, as many USB cameras provide
both a video device and a metadata device, and only the video device can
actually be used for streaming.
The most common mistake users (including contributors to WPILib) seem to make while creating new constraints is ignoring some sort of edge case that causes the calculated minimum acceleration to be greater than the calculated maximum acceleration.
This specialized exception, with its detailed error message, should make it easier and quicker for said users to debug and fix bugs within their constraints.
Co-authored-by: Tyler Veness <calcmogul@gmail.com>
If the 64 bit FPGA timer rolls over, a 32 bit value is added for
the rollover, an artifact of when it was a 32 bit timer.
The 64 bit microsecond timer won't rollover for 500k years so remove the
check for simplicity.
Fixes#2504
Valgrind caught this one. If you default initialize a Trajectory, it
doesn't initialize m_totalTime. This means a subsequent call to
Trajectory::TotalTime() returns the value of an uninitialized variable.
3512's software was using 0_s as a sentinel value for when a trajectory
was empty. We didn't notice a problem before because Linux zero-inits
memory.
Using this overload makes the thread backing the Notifier run at
real-time priority. This improves scheduling jitter substantially (5ms
+- 2ms down to 5ms +- 1ms).
A version isn't provided for Java because making threads real-time can
cause GC deadlocks.
This is an inline decorator for setting the name of a command
(equivalent to calling setName()).
It's not possible to implement this for C++, as it would slice the derived
class to return it by value.
The DutyCycleEncoder class initializes AnalogTrigger, which is not supported in simulation.
To avoid this, do not use AnalogTrigger (or Counter) in simulation mode.
Fixes#2367
Co-authored-by: Peter Johnson <johnson.peter@gmail.com>
This was caused by m_epochs storing the timestamps as nanoseconds while
the epoch printing code expects microseconds. Adding a duration cast
fixes this.
Java stores the epoch timestamps in a double as microseconds, so it
doesn't exhibit this bug. The comments were updated to make this more
obvious.
Fixes#2392.
Previously, it could take the long way around. This recomputes the
profile goal with the shortest error, thus taking the shortest path.
Also removed the setpoint clamping from PIDController::SetSetpoint()
because it's unnecessary to make PIDController behave correctly for
a modular arithmetic input, and it breaks the setpoint calculation in
ProfiledPIDController otherwise.
Fixes#2277.
This is useful for undoing transformations. One application my FRC team
found was converting perspective n-point data from a "camera to target"
coordinate frame transformation to a "target to camera" coordinate frame
transformation.
A typedef for units::dimensionless::dimensionless is defined, which
conflicted with the namespace when we added "using namespace
dimensionless". This patch reverts the "using namespace" directive.
"using" directives were added to pull three of the four relevant
typedefs but avoid the "dimensionless" type conflict.
This issue was first introduced in #2301.
What would happen is the Stop() call would happen between the notifier loop being triggered and calling UpdateAlarm(). This would cause the Update to overwrite the stop.
The CMake option OPENCV_JAVA_INSTALL_DIR can be set to the location
to search for the jar file. Note that the file name cannot be
changed, as, after checking several Linux package repositories,
that seems to be constant across all of them.
Fixes#2346.
The current hasPeriodPassed() function is confusing. In preparation for deprecating it,
add new advanceIfElapsed() function with same functionality and hasElapsed() function
which only checks that the time period has elapsed and does not advance the timer.
Also fix a couple of incorrect usages of hasPeriodPassed().
The field image and robot image can be loaded or just a wireframe used.
The robot can be moved and rotated with a mouse click + drag.
The robot position is settable in robot code via the Field2d class.
This allows users to right click on just about any name in the GUI (e.g. "PWM[0]") and rename it (e.g. "Left Motor [0]"). The index portion is not editable. The name is saved into imgui.ini so it's persistent.
C++ JoystickButton and POVButton were both nonfunctional due to slicing when trigger passes itself by value to the button scheduler it creates.
Fix is to remove the virtual Get() method entirely and use only the m_isActive functor; since the subclass now passes the button condition back as a functor to the base class, in which it's stored as a member, it will now still work after being sliced.
This PR changes the spline parameterizer to use an explicit stack instead of recursion. This is motivated by the fact that splines with adjacent waypoints with approximately opposite headings will never parameterize. In this case the parameterizer subdivides these malformed splines fine for a while, and then gets stuck parameterizing infinitely on some interval. In the recursive approach, this would lead to a stack overflow. We could implement a recursion depth counter (this is what my team did on our similar trajectory code last season), but it's hard to choose a good number for max depth because the initial amount of stack used varies based on how the user calls Parameterize.
A good solution for this is converting the recursion to an "explicit stack," which basically simulates recursion, but allows us to have a much larger maximum stack size. Because we avoid the stack overflow, we can instead throws a more informative MalformedSplineException. If the user is using the TrajectoryGenerator instead of the SplineParameterizer directly then the TrajectoryGenerator will go ahead and catch the exception, return a harmless empty trajectory, and report and error to the driver station.
Both floating point and 8-bit integer classes are included, as well as a wide selection of color constants.
Co-authored-by: Austin Shalit <austinshalit@gmail.com>
Add a Sendable* overload so pointers to sendable objects work appropriately.
Otherwise an AddLW(this) in a child (which is a Sendable*) could be a
different pointer than a void* to the same object.
For example:
AnalogInput constructor calls AddLW(this)
AnalogPotentiometer constructor calls AddChild(analog input pointer)
Also add handling for the child object moving (if it's Sendable).
This is extremely useful for implementing various "ramping" functions
(such as voltage ramps, setpoint ramps, etc). Usage is straightforward;
it behaves like all of our other filter classes. C++ version is unit-safe.
This is to allow suppressing an ugly stack trace/error message in a unit test in #2197. It doesn't support the full HALSIM_SetSendError callback stuff (i.e. you can only suppress, not intercept, stack traces with this).
- new CommandScheduler
- kinematics and odometry classes
- new PIDController
- ProfiledPIDController
- TrapezoidProfile (reported in Constraints class)
Also update instances.txt to match latest NI version.
One side effect is that a couple of classes are no longer constexpr.
With the addition of stall configuration, its not very clear how it works, and seems like it would be different
per use. So adding ways to manually get them, so the functionality can be figured out how to be used.
* Attempt to build testbench tests online inorder to improve speed
* Fix contianer reference
* Start to remove jenkins shell script
* Change job names
* Remove sshpass
* Remove teststand code
* Copy test results back
* Fix build by using athena container
* Fail if any command fails
* Remove jenkins test script
* Remove name argument
* Fix param count
* Add build display name
* Fix scp to copy into dir
* Update display names
* Update stage name
* Fix test results scp
* Create local test report dir
* Remove commented out old code
* Remove force pseudo-terminal allocation
* Remove extra variables
* Update readme
* Remove old test runs
* Update license header
LED displays connect the LEDs in various ways (column major vs row major,
different starting locations, serpentine connection order), so add
configuration parameters for these options.
It doesn't make sense to continue to provide a less accurate method of performing odometry
when a more accurate method using distances exists.
This also removes the need to pass DifferentialDriveKinematics to the constructor.
This kind of filter is extremely useful for signals that are susceptible to sudden
outliers - ultrasonics, 1-D LIDAR, and results from vision processing are all
good use-cases.
This also modifies the existing ultrasonic examples accordingly.
Improves the APIs for various prebuilt subsystems (PIDSubsystem, TrapezoidProfileSubsystem, ProfiledPIDSubsystem). Addresses #2128, and also changes the rather cumbersome getSetpoint API to a more intuitive setSetpoint one. Updates examples to match.
The odometry classes previously took in the robot angle as an argument, meaning that users had to take care of offsetting the gyro themselves to accurately report the robot angle. This change will make it so that users will not have to worry about resetting gyros and adding offsets themselves, as this will be handled by the odometry classes.
This shows the FPGA time and notifier timing, and has buttons to
start/pause/step the simulation.
The GUI also pauses DS new data notifications when paused. This could be
done globally instead by blocking NotifyNewData at the HAL level?
Calling HALSIM_PauseTiming pauses the FPGA clock and notifiers.
Calling HALSIM_ResumeTiming resumes the FPGA clock and notifiers.
Calling HALSIM_StepTiming steps the FPGA clock and runs applicable notifiers.
This will effectively pause TimedRobot and any other notifier-based events,
but of course will not pause user threads that do not use the notifier (e.g.
image processing).
This changes the C++ HALUsageReporting enums to have an
explicit type which matches the HAL_Report parameter
types. In practice this shouldn't change much except
for tooling that might be parsing this header.
Assorted improvements to the ergonomics of declaring requirements in the new
command framework. C++ requirements list parameters have been defaulted
to an empty list, some missing C++ requirements list parameters have been
added, and both C++ and Java have been given requirements list params in
various InstantCommand wrapper methods (#2049), whose value is
forwarded to the command.
This is useful for both cleanly exiting from simulation and for unit testing
at a framework level.
This change required removing move constructor/assignment from IterativeRobot.
- Remove use of std::set. The only place std::set was actually used was in ParallelRaceGroup,
but this was of minimal utility as ParallelRaceGroup checked for duplicate subsystem
requirements, so it would be very unusual to end up with duplicate commands
in any case; replaced it with a vector.
- Remove use of std::unordered_map except for SelectCommand. Replaced with vector.
- Use pImpl idiom for CommandScheduler
- Minimize include files (remove unnecessary ones)
- Reformat include file order for consistency
Add a voltage-compensated setVoltage method to SpeedController, which is sorely needed to help teams use feedforward-based controls effectively. Also uses correct units on the cpp side.
Also update relevant examples.
Changes Command decorators to return actual implementation classes rather than Commands. Previously, decorated commands were not Sendable, which was a problem. Also, there's no real reason not to expose the implementation details here, as we're extremely unlikely to change the implementations in the future.
Add user setting for scaling on top of DPI scaling.
Add user setting for visual style (light/dark/normal).
Save window position, size, maximized state, scale, and style to ini file.
These were incorrect and exhibited as warnings on more recent versions of
clang (notably on Mac).
- Use pointers instead of references internally in GenericHID and *Drive
- Leave PIDBase, PIDController, and Resource non-moveable
- Remove the atomic from m_disabled in NidecBrushless
- Make Timer and Trigger copyable as well as moveable
- Implement custom move constructor/assignment for SendableChooserBase
Also comment out some unused variables that caused clang warnings.
Add an overload for the generateTrajectory method that accepts a DifferentialDriveKinematics instance instead of a list of constraints. This instance is used to automatically create a DifferentialDriveKinematicsConstraint behind the scenes, saving the user some verbosity.
Passing command groups as lvalue-references to other command groups should be illegal, as their copy constructors have been deleted. However, copy constructors are const-qualified. This led to a very obscure bug where passing a command group by lvalue to another command group would result in a valid template expansion 'looking like' a copy constructor, and being preferred to the deleted copy constructor. This would result in constructor recursion (the expanded constructor would, in an attempt to call the copy constructor, call itself), and an eventual segfault when the stack inevitably overflowed.
This fixes the problem by explicitly deleting the problematic constructor signature - attempting to do this now (correctly) generates a compilation error.
The current index would be set to -1 by the execute method of ParallelRaceGroup,
and then an index out of bounds exception would be thrown by the end() method of
SequentialCommandGroup. This change bound checks the current command index as well
as only calls end at the end of parallel race group rather than during execute.
This uses Dear Imgui to provide a cross-platform integrated GUI for robot
simulation. The GUI provides fully integrated DS and joystick support so it's
not necessary to run the official DS.
This allows high-level library classes to implement enhanced simulation
support even if no low-level corresponding simulation library exists, and
avoids the need for bit-banging complex interfaces like SPI or CAN.
Default behavior is still to run the robot main loop in the main thread.
The ability to run the robot main loop in a separate thread and add a hook
for running a different function in the main thread is needed for simulation
GUI support on some platforms.
This class provides an easy way to forward local ports to another host/port.
This is primarily useful to provide a way to access Ethernet-connected devices
from a computer tethered to the RoboRIO USB port.
The most natural spot to put the shared implementation of this class was into
wpiutil, so a wpiutilJNI library has been added.
This removes the name and subsystem from individual objects, and instead
puts this data into a new singleton class, SendableRegistry. Much of
LiveWindow has been refactored into SendableRegistry.
In C++, a new CRTP helper class, SendableHelper, has been added to provide
move and destruction functionality.
Shims for GetName, SetName, GetSubsystem, and SetSubsystem have been added
to Command and Subsystem (both old and new), and also to SendableHelper to
prevent code breakage.
This deprecates SendableBase in preparation for future removal.
It only works with a specific sensor that isn't available anymore, the
class is a trivial wrapper around a Counter, and no one uses this class
according to FMS usage reporting.
If users are attempting to use the output range to limit the controller
action, they should use ProfiledPIDController instead. If they actually
intended to clamp the output, they should use std::clamp().
It breaks the unit system badly; the tolerance member variable has
different units depending on percent vs absolute. Absolute tolerance is
a lot more natural than percent tolerance anyway.
Since there is a new version of GearsBot using the new command-based
API, the old GearsBot is just removed.
PR #1842 is being included to verify this PR is correct.
This is the C++ version of #1682.
The old command framework is still available, but will be deprecated.
Due to name conflicts, the new framework is in the frc2 namespace.
Eventually (after the old command framework is removed in a future year)
it will be moved into the main frc namespace.
A templated hal::Handle class is used to wrap handles to make them move-only.
This eliminates a lot of boilerplate move constructor/assignment code
in the main WPILib classes. HAL_SPIPort and HAL_I2CPort are also wrapped.
The wrapper class does not implement destruction. This would require the
wrapper class to be handle-specific (rather than generic) and would result
in more code added than it removed, plus would add header dependencies on
more HAL headers. In addition, some HAL handle release functions are more
complex (e.g. have return values) and can't be easily mapped to a destructor.
The old command framework is still available, but will be deprecated.
Due to name conflicts, the new framework is in the wpilibj2 package.
Eventually (after the old command framework is removed in a future year)
it will be moved into the main wpilibj package.
This adds a wrapper over EJML's SimpleMatrix that uses generated classes representing numbers to encode the dimensions of each matrix at compile time, and to check operations between matrices for validity at compile time, rather than failing with an exception at runtime. This is required for the Java implementation of state-space control.
Additions to the wpiutil gradle script, and a python script at the wpiutil root are used to generate numeric types from a template at build time for both gradle and cmake. Users will be able to access types through functions on the Nat class.
Add unit-taking overloads to the following classes:
- IterativeRobotBase
- LinearFilter
- Notifier
- TimedRobot
- Timer (HasPeriodPassed only)
- frc2::PIDController
The corresponding non-units-taking functions have been deprecated.
The return value of TimedRobot::GetPeriod() was updated.
This is a breaking change, users should use to<double> to get the value in seconds.
Other return values, e.g. Timer::Get(), have NOT been updated due to much wider use.
Was only there for mac usb cam support, but we likely won't get to it this summer anyway,
and its causing a breakage in the backing libraries with cross builds
Teams that wish to use it asynchronously may still do so - they simply need to handle the thread safety themselves (it is not that difficult, and can be done more cleanly in the calling code anyway).
The main change in OpenCV 4 was removing its C APIs from OpenCV 1. If
the user has OpenCV 4, they have no way of obtaining the correct
arguments for cscore functions that require the C API. Therefore, we can
fix the build by just not compiling in functions reliant on the C API if
OpenCV 4 is being used.
OpenCV 3 builds should continue to work with this change.
Instead of being called asynchronously by NetworkTables, they are now called by updateValues() synchronously with the main loop, just like the getters.
The mutexes in PIDControllerRunner are declared after the Notifier, and
when the PIDControllerRunner object is destructed, the member object
destructors are called in the reverse order in which they are declared.
The mutexes are destructed first, then the Notifier destructor is called
which stops the Notifier.
There's a window between those destructor calls during which the
Notifier can run the callable and attempt to lock a mutex that no longer
exists.
Declaring the Notifier after all the variables its callable uses fixes
this issue, as it ensures the Notifier is destructed first.
Add EJML as the Java library for linear algebra for use in wpilib. This is equivalent to Eigen for C++.
The EJML dependency is downloaded in cmake and pulled in via maven in the gradle build.
It drastically increases compile times and is bad style. C++ users
should be including what they use. We don't necessarily have to remove
WPILib.h, but it should at least be deprecated.
This imports Eigen 3.3.7, which will be used by the wpilibc implementation of
state-space control and mecanum/swerve forward kinematics (the forward
kinematics requires least-squares solutions via a matrix pseudoinverse).
While Eigen has parts licensed under BSD, MINPACK, and MPL2, the files we need
are only MPL2.
These classes introduce ways to represent poses and provide easy ways to transform, rotate, and translate poses across 2d space. This classes will be especially useful for a planned odometry and kinematics suite.
Furthermore, these classes can also be used to simply represent waypoints on a field, do superstructure motion planning, etc.
Using std::function<void()> directly makes it much clearer to the user
what kind of function Notifier expects. The Doxygen comments already say
what the function is used for, so the typedef just discards useful
information.
This is a move-only variant of std::function to support move-only captures.
Imported from LLVM with some small tweaks (changed to 4 pointer internal storage, warnings fixes).
SampleRobot provides no benefits over RobotBase to advanced teams and
TimedRobot is recommended for everyone else.
A skeleton template for RobotBase was added.
std::scoped_lock was introduced in C++17 and is strictly better than
std::lock_guard as it supports locking any number of mutexes safely.
It's also easier to use than std::lock for locking multiple mutexes at
once.
Timer didn't have working move semantics because mutexes aren't
moveable, meaning the default implementations were ill-formed.
MotorSafety wasn't locking its mutex.
Originally, PIDController used PIDSource with its "PIDSourceType" to
determine whether a class should return position or velocity to the
controller. However, the supported languages have changed a lot over 10
years and now support lambdas. Instead of using PIDSource and PIDOutput,
users can pass in doubles to the Calculate() function synchronously.
This makes the controller much more flexible for team's needs as they no
longer have to make a separate PIDSource-inheriting class just to
provide a custom input.
The built-in feedforward was removed. Since PIDController is synchronous
now, they can add their own feedforward on top of what Calculate()
returns.
To facilitate running the controller asynchronously, there is a
PIDControllerRunner class that handles that. By separating the loop from
the control law, PIDController can now be composed with others and be
used to control a drivetrain (a multiple input, multiple output system
that requires summing the results from two controllers) much easier.
Also, motion profiling can be used to set the reference over time.
All the classes related to the old PIDController are now deprecated. The
new classes are in an experimental namespace to avoid name conflicts.
While this is a large change, I think it is a necessary one for growth.
The old PIDController design was created in a time when languages only
supported OOP, and we have more tools at our disposal now to solve
problems. This more versatile implementation can be used in more places
like as a replacement for Pathfinder's "EncoderFollower" class.
There has been hesitation to add lambda support to WPILib for a while
now out of concerns for requiring teams to learn more features of C++ or
Java. In my opinion, this change makes PIDController easier to use, not
harder. The concept of a function is a building block of OOP and should
be learned before classes. The ability to store functions as first-class
objects and invoke them just like variables is rather natural.
Note that PID constants for the new controller will be different from
the old one. The original controller didn't take the discretization
period into account. To fix this, teams should just have to divide their
Ki gain by 0.05 and multiply their Kd gain by 0.05 where 0.05 is the
original default period.
This can be dangerous as it refers to a temporary, and GCC 9.0 warns about
its use. Instead add std::initializer_list overloads to common places it
was used in an initializer_list sense.
* Renamed LinearDigitalFilter to LinearFilter
* Filter base class removed since it wasn't useful
* C++: std::shared_ptr<> replaced with double parameter
* ErrorBase: Use magic static singleton for globals
* ErrorBase: Add testability features for global errors
* Make WPIError definitions inline functions
(This works around cross-DLL variable issues on Windows)
Fixes#1726.
The current versions of the RoboRIO and Raspbian compilers support the flag but have
minimal actual C++17 support. Changing the flag is the first step.
* Update MSVC arguments
* Fix json allocator
* Fix simulation diamond
* Bump gtest
* Remove empty varargs in unit tests
* Replace test case with test suite
* Remove deprecation warning in optional
* Remove need for NOMIXMAX to be defined in wpilib headers
In some cases, we don't want the cv requirement to get an image, for instance interop with other versions of opencv
This enables getting a raw image, and handling conversions from the user side.
The functions in Threads.h are in the frc namespace. `using namespace frc;` in
Threads.cpp doesn't put their implementations in the frc namespace, so linker
errors occur when attempting to use them in robot programs.
To fix this, one can either wrap them in a namespace block or prepend
`frc::` to the implementation's signature. Based on past discussion, I
opted for the namespace block.
LabView only accepts %20 instead of + for parameters, only sends '\n' at the boundaries,
and includes the -- when sending the initial boundary. This solves those parts.
This is not fully enough to fix shuffleboard and others, as the NT format for paths is not the correct path.
This adds a new function "addSwitchedCamera" that creates and publishes a
virtual camera where the published stream information is consistent even if
the mjpeg server source is switched to a different camera.
Previously, changing the source of the mjpeg server resulted in updating the
stream information published for that source.
* Fix C++ ShuffleboardComponent template type
* Fix `WithWidget(WidgetType&)`not being properly capitalized
* Fix data members across dll boundaries by using enum for built in types
When there is more than one ultrasonic sensor, only the last sensor
instantiated would work due to incorrect array index management. This
replaces the previous approach with range-based for loops like the C++
implementation.
Supersedes #1589.
Resetting the flag should only occur in Enable() and Reset().
IterativeRobotBase needs the flag to remain set to print epochs after
disabling the Watchdog.
This is primarily for use on Linux to get by-id or by-path device names.
This information is now part of UsbCameraInfo.
A new entry point was added to UsbCamera to get that camera's UsbCameraInfo.
The alternate paths are also returned in EnumerateUsbCameras.
Add a Sendable wrapper for VideoSource objects.
Add convenience methods for adding video sources directly to containers
so users won't have to manually wrap video sources.
HAL_GetFPGATime returns 0 if it starts with a non zero status.
Always use monotonic clock for CAN times, rather then trying to sync FPGA.
Change timeout from 50 ms to 100 ms.
Otherwise, it is required to be set manually, which isn't obvious.
This is because the HighLevel DS classes check that the ds is attached before enabling
This function is intended for use when the content is a static const variable.
It allows gzipped static data, but doesn't provide the functionality to ungzip
it if the client doesn't support gzip. This is because it would add a
dependency on zlib and basically all clients support gzip.
Change extraHeader on all Send functions to include the final newline,
this makes it easier to build up extra headers incrementally.
Expose sig::Connection for messageComplete and headerConn to allow them to
be disconnected by users of the class. This is commonly needed for things
like WebSocket upgrades.
The 2019 FPGA image switched the output of auto SPI from plain bytes to a
sequence of 32-bit words (timestamp, then words with the byte values in the
least significant byte of each word).
In addition to changing the HAL and simulators to reflect this, add piecewise
integration support to wpilibc/wpilibj SPI to take advantage of the timestamps
and use it in the ADXRS450 gyro.
Adds debug stripping to executables.
Copies .debug and .pdb files to install directories to ease debugging.
Update to v0.5 of doxygen, which fixes the download location.
Notifier has one thread per instance because the callbacks must be
asynchronous. Watchdog callbacks can be synchronous, so this overhead
can be done away with via a scheduler thread akin to what the HAL
Notifier does.
The size of the directory_entry was different between translation units.
This was caused by the FILE_OFFSET_BITS macro when building wpiutil.
Removing that fixes the issue.
Should fix NavX USB issues.
Imported from https://github.com/akrzemi1/Optional with minor changes:
- Compiler conditional simplifications (we only use recent versions)
- Move from std::experimental to wpi namespace
- Change tests to integrate with Google Test
Update LLVM use cases.
Most of the MotorSafety implementation was moved into the MotorSafety base
class. SafePWM's inheritance of MotorSafety was moved into PWM to
eliminate Java needing a helper class.
In Java, a helper class for Sendable (SendableImpl) was added due to
lack of multiple inheritance.
HAL_ReadInterruptRisingTimestamp and HAL_ReadInterruptFallingTimestamp
return time as a double. Instead, keep the raw integer count and move the
double conversion into the C++ and Java code. This enables comparison of the
time with other timers.
PR #1300 supersedes it, but won't be merged until the 2020 season. Since
SynchronousPID hasn't been used during a season, it would be best to
just remove it to avoid breakage when we deprecate and remove it again.
This allows save and restore of camera settings. The restore is a bit
smarter than the save.
* Fix mime types in mjpeg server
* wpiutil: WPI_LOG: Make sure level is an unsigned int
This is set to the FPGA clock by HAL_Initialize. Note this change means
that libuv loops should not be started until after HAL_Initialize is called (on the Rio).
Non-Rio functionality is unchanged.
Static destruction order is not well defined, so it was possible for outs()
or errs() return value to be destroyed even while other code was running,
resulting in a crash. Instead dynamically allocate the static so the
destructor never runs. While this technically leaks, valgrind generally
supresses such leaks as the data is still "reachable" from the static pointer.
This avoids a number of shutdown use-after-free races by controlling the
destruction order. It also is a prerequisite to making the internal
interfaces mockable for unit testing.
The static condition variable was getting destroyed before the DS thread exited,
resulting in a deadlock on program exit when the DS thread tried to notify it.
This change moves the condition variable into the DS thread to avoid the race.
The next line adds a null terminator, but it's cleaner to just do a
std::memcpy() since the code already assumes a null terminator exists in
the source string.
- Build both debug and release binaries
- Append "d" to debug libraries in the style of opencv
- Split shared and static classifiers
- Add raspbian support
Originally, the command was restarted every time the scheduler was
executed if the button was pressed. #1340 changed this behavior in a
breaking manner.
Other handles can only be used within the loop itself, but Async is intended
to be used from another thread. This introduces the possibility of a race
condition between the loop being destroyed and the Async being destroyed.
Change Async to keep a weak reference to a loop and check it before performing
libuv operations.
This allows the called function to pass along the promise to another
asynchronous callback.
To avoid memory allocations, add a home-rolled, simplified, non-allocating
version of std::promise and std::future as wpi::promise and wpi::future.
Since https://github.com/wpilibsuite/allwpilib/issues/786 has been
closed as not a legitimate concern, there is now no reason to use
IterativeRobot over TimedRobot. It's a drop-in replacement that's
strictly an improvement in terms of execution jitter.
To migrate, one simply has to replace the IterativeRobot subclass in
their robot code with TimedRobot.
Make wpi::condition_variable typedef to std::condition_variable_any if
wpi::mutex typedefs to priority_mutex.
priority_condition_variable was originally intended as a copy of
std::condition_variable_any that also returned the internal handle like
std::condition_variable. This was needed because NetComm required a
pthread_cond_t. We no longer use it anywhere.
Its args were specialized for priority_mutex, but
std::condition_variable_any supports this and more through
templatization.
This is necessary for modularization.
Move the wpilibj CameraServer classes to the cameraserver package.
Move the edu.wpi.first.wpilibj.vision package to edu.wpi.first.vision.
To avoid code breakage, add deprecated copies of the wpilibj classes to the wpilibj jar.
This allows HAL_CloseI2C() and HAL_CloseSPI() to be noops, which makes
enabling move semantics in the I2C and SPI wpilibc classes easier and
cleaner.
Fixes#1328.
This makes callback registration completely thread safe.
This patch also uses templates and macros to dramatically reduce the amount of
manual boilerplate.
Makes configuration easier when you can associate the items with a name
instead of just a port number. Important if there is a GUI added at some
point.
This is a breaking change as it makes Async a template (e.g. Async<> must
be used instead of just Async). When data parameters are provided, an
internal mutex and vector is used to hold the parameter packs until the loop
runs.
By default, sources automatically manage their connection based on whether
any sinks are connected. This change allows the user to keep a connection
open or force it closed regardless of the number of connected sinks.
This fixes two real bugs:
- TimedRobot had a m_period that was hiding the IterativeRobotBase m_period
and was not getting initialized.
- PDPSim was swapping two parameters to getCurrent()
A hash is stored for each native library with the name libraryName.hash.
If the library is not found on the system search path, it is extracted to a cache directory.
Extracted libraries are named with the hash appended, so the library will not be
re-extracted if one with the same hash already exists.
Hashing without the hash file requires double traversing if the file is not in the cache,
but it is still faster than creating a new file in most cases. This won't be needed
after opencv is updated to provide a hash as well.
JavaDoc cannot handle redirects so HTTP link does not work anymore.
It also looks like javadoc.options was the wrong thing to set.
Options properly connects external docs to ours.
Re-enabled warnings so these things will pop out if they turn up again.
SendableBuilder.setActuator() sets the .actuator key in the network table
so dashboards can change behavior on the client side if desired, and also
sets a local flag (retrievable via isActuator()).
Both make drive bases actuators and call setSafeState on them.
This echos back the "selected" value to the "active" key to enable dashboards
to display positive feedback to the user that the value is actually set on
the robot side.
Also fixes SendableChooser so it can be safely added to multiple tables.
Changes to "selected" in any table will result in all "active" values being
updated.
Now that adding SendableChooser to multiple tables is supported, an ".instance"
key enables dashboards to treat the same SendableChooser as a common instance
if desired.
This indicates whether or not the Sendable listeners are installed.
It is set to true when SendableBuilder.startListeners() starts the listeners,
and set to false when SendableBuilder.stopListeners() stops the listeners.
This allows dashboards to choose to change their widget display based on
whether or not the value is actually controllable.
This allows two streams with different compression levels, and also allows
a stream to receive a different compression level than provided by a JPEG
camera (decompress and recompress).
Some cameras will accept a different resolution as the mode but then provide
JPEG images of a different size. Trust the JPEG image size if available.
This also validates the JPEG image is actually JPEG.
The old headers were moved into folders because doing so avoids polluting
the system include directories.
Folder names were also normalized to lowercase.
This implements enough of the UDP and TCP protocol used by the FRC
driver station to allow us to talk to either QDriverStation or to the
real Driver Station.
This was inspired by a similar function in Toast by Jaci, and also
uses a lot of the research found in the QDriverStation project.
* Fix bugs in PacGoat Java example that prevent it from working.
We have conflicting ports in use, each of which causes a crash
at startup. These changes fix those issues.
* Change to avoid a crash in Visual C++ when running simulated code.
Without this change, we would get a crash in SendableRobotBase when
constructing a Twine from the 'kOptions' constant string;
we'd get an unable to access memory exception.
Also switch eventName and gameSpecificData to fixed 64-byte arrays to avoid mallocs and
extra NetComm calls. This behavior matches 2018 LabView.
The DS caching is kept in Java to avoid JNI and/or massive amounts of allocations.
This does not increase latency because Java still only hits NetComm once.
Moving the DS caching benefits all languages other than Java, because it avoids the need
for individual implementations. If caching is ever added to NetComm, it will then only be
necessary to remove it from the HAL and Java rather than all languages.
It is much more reliable than the old approach, as it no longer depends on a magic string
in a manifest file, and if the user changes their main class, or makes it not import from
something RobotBase, it will fail to compile instead of failing at runtime.
With requiring an importer, we should be able to automate this in the importer.
4.9 will be needed for some things being added to a few of our plugins. It adds the new lazy configuration tasks which help a good amount in some cases.
I don't have a good way to ensure this always works, so this is going to be a documentation issue.
But initializeHardwareConfiguration is now reentrant, so we can just have all tests call it.
Also fix the return type of HAL_IsNewControlData() and HAL_MatchType's type.
Since UsageReporting is intended to be namespaced, it is hidden when this is being used in C.
Fixes: #476Closes: #535
Ref: #1122
The models and meshes are not included. We will need
to find an alternate way to reintegrate these and use them.
* Add simulation/gz_msgs back, and build with Gradle.
* Add back in the frc simulation plugins for gazebo.
* Add a new shared library, halsim_gazebo.
This library will become the interface between the
HAL sim layer and gazebo.
* Preserve the first channel number used in created Encoders in the Sim MockData.
This allows us to use the DIO channel number to connect with simulated encoders.
* Have the HAL Simulator set the reverse direction on creation.
This enables a simulator to be aware of the direction.
* Add a drive_motor plugin.
This is a bit of a 'magic' motor, which allows us to build robot
models that drive in a more realistic fashion. It does this
by apply forces directly to the chassis, rather than relying on
the complex motion dynamics of a driven wheel.
This in turn allows the model to reduce wheel friction,
reducing scrub, and allowing for a more natural driving experience.
This optimizes the common case of a single simple callback (e.g. std::function
or lambda) so no additional allocation is required. As a Connection return
value is not possible in this case, provide a separate connect_connection()
function to provide that.
Imported from https://github.com/palacaze/sigslot
Classes were renamed from lowercase_me to UppercaseMe style, primarily
to avoid conflicting with the C standard library "signal" function. They
were also moved to the "wpi::sig" namespace.
The implementation of ConvertToC for arrays was broken. Also change it
to be templated on the returned array type, rather than passing the array.
This makes the uses a bit more clean.
In order for this to properly work, we need to remove the main code.
Then the test component will actually have the main in it. Example tests will be added later.
Making Travis run wpilibj_frcnetcomm.py will help avoid bitrot in
FRCNetComm.java in the future. Formatting was also enabled on Python
source files and FRCNetComm.java was added back to the generated files
list.
Also checks that all items in the json file have a matching example
One was missing from C++, that example was added (The one in eclipse was completely wrong)
Instead of defining NAMESPACED_WPILIB to remove the "using namespace frc"
shim in Base.h, instead require NO_NAMESPACED_WPILIB be defined to add it.
Fix up various examples to use correct namespacing.
Also change header guards to WPI header guards.
Remove StringRef::c_str() customization, replacing the handful of uses with Twine or SmallString.
TCPStream: Include errno.h and make Windows includes lowercase for consistency.
Upstream LLVM version: eb4186cca7924fb1706357545311a2fa3de40c59
This fixes DriverStation in WPILibJ to check the existence of buttons and hold the data mutex in getStickButtonPressed() and getStickButtonReleased(), as the corresponding methods in WPILibC do.
For mac, 32 bit will never be supported. Apple has dropped all support.
For 32 bit linux, vscode explicitly does not support it, and it is difficult to find anybody using a 32 bit os.
The anonymous namespace was renamed due to -Wsubobject-linkage complaining
about a field created in a GTest template class (CborRoundtripTestParam)
being defined in an anonymous namespace. See
https://stackoverflow.com/a/37723265.
These generate a warning when included, then include the old header.
Note for GCC, #warning is used; this requires -std=gnu++14 instead of
-std=c++14 (otherwise the warning is treated as an error because #warning is
a GNU extension). On MSVC, #pragma message is used, which is a bit
unsatisfactory as the message doesn't say where it was included from.
The llvm shim headers also include a llvm namespace shim.
During shared library loading, a different libLLVM can be pulled in, causing
llvm symbols from dependent libraries to resolve to that library instead of
this one. This has been seen in the wild with the Mesa OpenGL implementation
in JavaFX applications (see wpilibsuite/shuffleboard#361).
This is clearly a very breaking change. For some level of backwards
compatibility, a namespace alias from llvm to wpi is performed in the "llvm"
headers. Unfortunately, forward declarations of llvm classes will still break,
but compilers seem to generate clear error messages in those cases
("namespace alias 'llvm' not allowed here, assuming 'wpi'").
This change also moves all the wpiutil headers to a single "wpi" subdirectory
from the previously split "llvm", "support", "tcpsockets", and "udpsockets".
Shim headers will be added for backwards compatibility in a later commit.
It was using array indexing to map the return value of
DriverStation.getJoystickType() to HIDType when the enum should instead be
constructed from the int value. C++ already does this.
Fixes#968.
Previously these functions ignored SOF if they came immediately after
the SOI (e.g. bytes 2 and 3 of the file). A handful of cameras generate
images like this.
SendableChooser::InitSendable() is written such that it saves the table
being used in an instance variable. This doesn't work if the chooser is
added to both LiveWindow and SmartDashboard. Normally it is not added to
LiveWindow because the name is empty, but if setName() is called this could
still happen. Note adding the same SendableChooser to SmartDashboard with
two different names is also not currently supported, for the same reason.
The correct solution will be to remove the instance variable, but this is
too high risk to implement mid-season, so instead just remove from LiveWindow.
Reset() is the only function without a null check around it. We call the function on startup, which means if it is unplugged the robot crashes.
Also added an accessor for checking if it is connected, as some teams (us) would like to handle the case where it was not connected on startup.
Both could occur if a client and server write to the same key and the server
disconnects/reconnects (or restarts).
Bug 1: the client did not properly update the sequence number in this case,
so later server updates could be ignored until the sequence number wrapped.
Bug 2: the client did not properly set the id and sequence number for the
update message back to the server, so the server would ignore the message.
This normalizes within -1..1 to avoid clipping and maintain the ratio between
wheel speeds, since that ratio determines the center of rotation.
Fixes#923.
Also provide wpi::mutex and wpi::condition_variable as wrappers for these
on Linux (where they're available), and for std::mutex and
std::condition_variable on other platforms.
The original synchronization behavior was troublesome for two reasons:
- It had unpredictable behavior for updated values
- It brought back to life deleted values
Instead of relying on the server to inform the client regarding reconnections,
the client keeps track of what values have been modified by user code on the
client. When the client connects to the server, the following occurs.
For entries that have been modified by user code on the client:
- If the entry is not persistent, the server value is overwritten with the
client value
- If the entry does not exist on the server, the client sends an assignment
to the server to recreate it on the server
For entries that have not been modified by user code on the client:
- The client value is overwritten with the server value
- If the entry does not exist on the server, the client deletes the entry
Fixes#8.
Previously, most of the classes were implemented as singletons so only one
instance was possible.
This change adds an instance handle-based API. In Java, this API is located
in a different package than the old API (edu.wpi.first.networktables).
Backwards compatibility with ITable and the old NetworkTable API is largely
maintained, but a handful of classes have moved to the new package in Java
(ConnectionInfo and PersistentException), and the old JNI has been completed
replaced.
Also:
- Move SetTeam implementation to Dispatcher.
- Consistently pass time through Java and C++ Value API.
- Rename nt_Value.h to NetworkTableValue.h for consistency with Java.
- Improve documentation
- Make C++ and Java APIs more consistent
- Document RPC functions and support RPC in Java.
- Add polling features for entry and connection listeners and use them to
move callback threads to Java level.
- Remove thread start and stop hooks (as polling is available).
- Make Notifiers, RpcServer, Dispatcher, and Storage mockable.
- Set NOTIFY_NEW on immediate entry notifications.
- Make GetTable("/") and GetTable("") equivalent.
- Generate local notification for flags update when loading persistent file.
And many unit test updates/changes:
- Use InitGoogleMock instead of InitGoogleTest in test main.
- Move test printers to TestPrinter.h/cpp.
- Provide printers for StringRef, EntryNotifier, and Handle.
- StorageTest: Check notifications.
- Add entry notifier unit tests.
- Storage: Add test for incoming entry assignment.
- Update connection listener tests.
- Add entry listener unit tests.
Fixes#11, #140, #189, #190, #192, #193, #221
This keeps indexes from being instantly reused and reduces the risk of
accidentally using an old index.
Also change erase and emplace_back to return 0-based instead of 1-based
indexes.
This is a breaking change, but a noisy one due to the template parameter
change.
The Frame destructor calls back into SourceImpl, locking m_poolMutex, so
it's necessary to destroy m_frame before m_poolMutex. Reverse destruction
order to member definition order is guaranteed by the C++ standard.
Better then the old desktop zips because it will include all artifacts
built, not just specifically the desktop ones. Also, the individual
artifacts are published as well so users can decide which artifacts they
specifically want, and can help decrease download sizes. The cpp plugin
will continue using the individual artifacts.
Better then the old desktop zips because it will include all artifacts
built, not just specifically the desktop ones. Also, the individual
artifacts are published as well so users can decide which artifacts they
specifically want, and can help decrease download sizes. The cpp plugin
will continue using the individual artifacts.
This is a modified version of https://github.com/nlohmann/json.
It's been moved into the wpi namespace as many of the changes are not
compatible. The amount of template code has been significantly reduced,
enabling many functions to be moved out-of-line, and for the result to
build on older compiler versions (in particular GCC 4.8).
Gradle needs to produce a platform path of "Linux/i386" when targeting a Linux 32-bit Intel platform. Otherwise, it doesn't match Java's os.name/os.arch when loading the ntcore library in NetworkTablesJNI.java. Windows uses "x86" but Linux uses "i386". (http://lopica.sourceforge.net/os.html)
MjpegServer uses the timeout to generate keep-alives to any clients
(which helps detect disconnects and avoid stale client threads).
CvSink GrabFrame now defaults to a timeout, but the timeout can be
changed by the user, or the old no-timeout version is now available
as GrabFrameNoTimeout.
When the page is loaded, if properties can be found they will
automatically be created on screen. They are currently not auto
updating. Raw values are currently disabled because of this.
Currently if using a separate compiler prefix, it would get published to
the arm classifier. This modifies so the output suffix can now be
specified (e.g. "hf" for armhf).
Currently if using a separate compiler prefix, it would still get published
to the arm classifier. This modifies so a classifier suffix can be used to
disambiguate arm from armhf.
This makes them available for both UsbCamera and HttpCamera / AxisCamera.
To avoid virtual functions in the public-facing interface, move the
implementation of the camera settings functions to the core library.
Similarly, use InetPton rather than WSAStringToAddress.
The WSAAddressToString function is intended to provide a user-readable
string and thus includes the port number. This breaks some use cases
on Windows which expect to get just the IP address.
Note: The InetPton and InetNtop functions are available only in Vista or above.
Similarly, use InetPton rather than WSAStringToAddress.
The WSAAddressToString function is intended to provide a user-readable
string and thus includes the port number. This breaks some use cases
on Windows which expect to get just the IP address.
Note: The InetPton and InetNtop functions are available only in Vista or above.
This takes hosts (IP or DNS name) rather than URLs, making it easier
to use.
Also add more overloads to resolve ambiguities encountered when using
std::string and const char*, and also add overloads for
std::initializer_list<T> so braced initializer lists can be used.
The Frame constructor calls back into SourceImpl (the passed this reference),
and when in-place constructed in the SourceImpl constructor, SourceImpl
is only partially constructed.
The code now automatically resizes as required.
This change also disconnects camera resolution settings from MJPEG
stream connections; setting the camera resolution can now only be done
via code.
Also add checking for "would block" errors in send() and receive().
Check for set nonblocking failures in TCPConnector as well (generate warnings rather than errors)
Also add checking for "would block" errors in send() and receive().
Check for set nonblocking failures in TCPConnector as well (generate warnings rather than errors)
Also take CS_EventKind rather than RawEvent::Kind.
Still provide the handle methods for the basic events (this is particularly
useful for create and destroy events).
This makes these functions easier to use from within the implementation.
The StringRef class does not ensure the string is null terminated. As there is
no defined way to actually check for a null terminator, we determine
if it is null terminated based on the constructor type. Then if on c_str
it is not known to be null terminated, we use a passed in buffer to copy
the string and ensure null termination.
The StringRef class does not ensure the string is null terminated. As there is
no defined way to actually check for a null terminator, we determine
if it is null terminated based on the constructor type. Then if on c_str
it is not known to be null terminated, we use a passed in buffer to copy
the string and ensure null termination.
The 2017 FRC Driver Station supports getting the robot IP via a TCP
connection that returns JSON. Use this to support overriding the
server IP address used for client connections.
Default to using this approach for client connections in the NetworkTable
interfaces.
Add support for setting the server address without stopping and
restarting the client.
SetTeam now also round-robins by default.
Previously once the client fell back once to NT2, it would never try
connecting as NT3 even if the server was replaced with a NT3-capable
one.
Fixes#142.
During testing, I was seeing a lot of unnecessary code (and allocations
in Java/C#) when appending the path separator to the base path. That
technically is a constant, so this computes this constant during class
construction.
This is a breaking change to dependencies that use the static ntcore
library. Unless the wpiutil library is also linked, linker errors will
result. This does not affect the shared ntcore library.
This is a breaking change to dependencies that use the static ntcore
library. Unless the wpiutil library is also linked, linker errors will
result. This does not affect the shared ntcore library.
* Revert "Fully asigns the ConnectionInfo struct (#113)"
This reverts commit 9a3100b221.
* Revert "Passes the ConnectionInfo of the Rpc client on server callback (#112)"
This reverts commit 7e9754acff.
For functions where a SmallVector is passed to be used as a stack buffer for
the return value, have the return value be the appropriate StringRef or
ArrayRef type. This allows for both more natural usage and enables directly
returning (rather than copying) a permanently stored or constant string.
This will allow dependencies such as wpilibc to update to use wpiutil
without breaking "normal" ntcore static library use in the meantime.
This commit also restructures the gradle files by creating a new
(placeholder) wpiutil project, and moving the ntcore project into
a separate gradle file. Added toolchains/native.gradle (refactored from
ntcore).
Also fixes ntcore skipJava on Windows by providing an alternate .def file
for this case.
This will allow dependencies such as wpilibc to update to use wpiutil
without breaking "normal" ntcore static library use in the meantime.
This commit also restructures the gradle files by creating a new
(placeholder) wpiutil project, and moving the ntcore project into
a separate gradle file. Added toolchains/native.gradle (refactored from
ntcore).
Also fixes ntcore skipJava on Windows by providing an alternate .def file
for this case.
Moving these headers from src to include enables other libraries to use the
functionality provided.
* tcpsockets
* atomic_static
* raw_istream
* timestamp
* SafeThread
* Base64
* LEB128
* ConcurrentQueue
The classes have been moved into the wpi namespace as they're generic.
There was no way to atomically check for a key in the table,
and then setting if it if non existant. Back before persistent
this was not a problem, however now it is, as its possible for
values to be added before team's robot programs start. This makes
the old method of calling Put*** methods in RobotInit invalid.
This adds SetDefault methods, which do this atomically.
Without a GCC installation that can build both 32 and 64 bit executables, the native build will fail on 64 bit Linux machines with an error about unsigned __int128 being undefined. GCC does not support __int128 on 32 bit targets, and GCC was using it via a standard library implementation header intended for 64 bit machines.
Instances of "arm" were replaced with "ARM" where the acronym was intended.
Since we now get ConnectionInfo when setting a connection listener,
there is some good information in there that teams could use.
Implemented using default interface methods, so teams should see no
change if they don't implement the Ex methods.
I noticed that the connection listener methods don't exist at all in
C++, so they did not get added there.
There's a lot of buzz going around the internet about people trying to
get ntcore working on other devices. One of the things that makes it
harder is having to have a separate jar for each platform. What this
change does is if the loading of the extracted library fails, it will
attempt to load ntcore from the path. This means that a program like
GRIP can just provide the libntcore.so and not have to worry about
compiling different versions for different platforms.
Trying to build with the android standalone compiler, and these 2 things
were causing errors. I don't know what an equivalent to basename would
be, because I don't really know what it does.
For consistency with Java NetworkTable; also makes these data types easier
to use (although they are less efficient as they require a memory allocation
and data copy).
JavaGlobal was unconditionally attaching to (okay) and detaching from (bad)
the current thread during destruction. We don't want to do this if the
destructor gets called from an attached thread. Instead, use GetEnv to
first try to get the environment, and only attach and detach if it returns
an error saying the thread is detached.
Also, make sure notifier callbacks appropriately free Java locals to avoid
running out of local variable space.
During JVM shutdown, some JNI calls may not return, so it's not possible to
reliably perform a join() during static variable destruction (which occurs
as the JVM unloads the JNI module).
Also, due to static variable destruction, it's not safe to use any members
of a static class instance from a separate thread of execution.
SafeThread is a templated thread class and a related owner class that's
designed for safe operation and shutdown of threads in the presence of
callbacks that may not return. It also passes ownership of variables from
the static instance to the thread, so the thread can safely operate until
it exits (the last operation of the thread being to destroy its instance).
Notifiers, RpcServer, and Logger now use SafeThread to ensure race-free
destruction in both C++ and Java.
All Java callback threads are now marked as Java daemon threads so they
don't keep the JVM running after main() terminates.
All Java callback threads are now named so their purpose is more easily
identified in a debugger.
Add SetRpcServerOnStart and SetRpcServerOnExit (similar to Listener).
The previous use of a timeout resulting in thread detach instead of thread
join resulted in a race condition on Mac between destruction and thread
closeout. This commit removes the detach functionality and uses dup2() to
on Linux/Mac and connecting to itself on Windows to try to ensure accept()
exits.
Each call to AttachCurrentThread results in a new Java thread object being
created. This is inefficient and also causes debugging issues with Eclipse
due to constant creation and removal of threads. Now AttachCurrentThread is
only called once for (all) listeners and once for logging (if used).
Previously this would always return false due to how explicit bool is
evaluated in a return context.
Also add a test for this function.
Reported by: jcreigh
This is safe because of the way writes are performed: for each transmission,
all outgoing messages are concatenated in memory and only a single write()
syscall is made.
These are good to have for backwards compatibility, but discouraged for new
development (default-taking functions should be used instead). The reason
is that the exceptions must be explicitly handled and may initially work but
then fail at an inopportune moment.
Mark the similar Java functions as deprecated as well for the same reason.
Update all the docs for consistency.
Mark overridden functions as such in both C++ and Java.
Make IsPersistent and GetFlags const in C++.
no-unused-private-field for Mac builds. Gradle also now works
with the classifier-based dependency system, rather than having
separate repos for every level.
Change-Id: I2eb87391181e91b5675e3e982e4d915be83e14ea
The Value::MakeStringArray methods were not setting the size of the
arr_string. This was causing the NT_Value struct called from the C
entry listener callback to not have the array size, which would then
cause the GetValueStringArray method to fail the malloc.
current platform by default, and only builds tests when building for the
current platform. Mac builds and VS2015 builds are fixed.
The other big change in this update is the introduction of Debug and
Release builds. Debug builds are built with -O0 and -g. Release builds are
built with -O2 and -g. For GCC-based builds, the resulting shared object
is copied, stripped of debug information, and a debug link is set up to
the copied shared object. This allows the release build to clock in at
around 600 KB. On Windows, the debug info is already stored in a separate
PDB file, so this copy and strip is not necessary.
ntcore is being separated out from the rest of allwpilib. All other
builds will consume a published maven dependency from this project.
There are 4 possible publishing targets now: release, stable, beta, and
development. These are specified on the command line via -Prepo=<repo
name>.
Change-Id: Ie8cb21f910953e09b80a5192317033eb0866cb70
Under certain situations (notably JNI shutdown), it's possible to get
deadlock when using thread join(). To avoid this, implement a timeout.
Normally we try to simply join the thread, but if it times out, we
detach the thread instead.
This enables listeners to be notified of not only value updates, but also flag
changes and deletions by using a bitmask to specify what notifications are
desired. The old API (which only provided a new/not new) flag is still
supported. This also subsumes the feature to listen to local changes (that's
one of the bitmask options).
Before the server has assigned the id, the client doesn't generate flags
update messages. This behavior is correct, but the client must then send
the appropriate flags update message when the id is finally assigned by
the server.
The default behavior is to only notify remote changes, but for some
applications (e.g. GUI's) it's advantageous to know about local
changes as well.
This is (slightly) optimized in that local changes only result in
additional resources being consumed if (any) local listeners have been
created.
This matches the implementation provided by Java NetworkTable, with the
exception that the subtable is not provided (because it's not a value).
The listener still can get access to the subtable by calling
source->getSubTable(key).
- Ignore no-op calls to setServerMode() / setClientMode().
- Duplicate calls to initialize() act as a restart.
- shutdown() silently does nothing if not running.
The JVM doesn't always do a good job of telling JNI modules that the JVM
is going away, which results in a crash in the JavaGlobal and/or
JavaWeakGlobal destructors as they try to delete the associated references
after the JVM has already gone away.
To protect against this, the Notifier now has a static variable that's set
when the Notifier instance (a singleton) is destroyed. This is used by
JavaGlobal and JavaWeakGlobal to detect when a process exit is in process.
vs2015 is detecting, and printing an error that actually makes sense if it
is not. Finally, added a .gitreview file, so that git-review will be able
to autodetect the host and project for ntcore automatically.
Change-Id: I3cb9910d03d4742619770c91c06e3d5d1ee0f031
Previously they returned references to the strings/arrays within the passed
NT_Value, which is different from the GetEntry* functions and risks
double-frees.
Starting to add Getters, Setters, and Allocators to the C interface
Because of the union in the NT_Value structure, some languages would
have a difficult time with the interop. This commit adds individual
getters and setters to the C interface to make interop easier.
In addition, some languages cannot allocate native memory in the same
heap that the C code would use. This adds allocation functions to make
sure that all our memory is allocated and can be freed properly from the
same heap.
The reason the getters are not individual get functions are because that
would require the calling code to first get the type, and then call the
specific getter for that type. Doing combined get functions causes
interop code to only have to cross interop boundaries once to get the
value instead of twice, for a light performance increase. However, this
could be changed without much work.
NT getters and setters round 2
Fixed some of the code based on the comments in the pull request.
Creates individual getters.
Should work better then 1 single getter.
Fixes end of file new line, and fixes function nameing
SetNTValue... made less sense then SetEntry... Matches the getter
naming.
Fixed methods to be less leaky.
Fixed Formatting, Fixed return values on Bool and Double. Added Contains Key
Changed ContainsKey to GetType. Also renamed Arr to Array
In public functions, I think I like Array better then Arr. Also, make
the getters that use value check for a null value, which should prevent
segfaults.
Fixes C++ Type functions to work properly
NTString Set functions still do not work properly though. I need some
help on there. Error message is in the pull request.
Changes Get functions to return status and have pointer to data passed in to be set.
Fixes NT_Strings
Added new functions to ntcore.def
Fixes NT_PostRpcResponse in the def file
Was NT_PostRpcRepsonse, which was failing the build.
Removed unused parameter from setters
Since we were forcing exports in the cmake build, they were seen in
windows, but since the header didnt match the implementation they
wouldn't export on linux. So fixed that. Linux builds now work properly,
tested on a physical RIO.
Added a DisposeEntryInfoArray method.
There was no way to free the array returned from GetEntryInfo
Adds NT_DisposeEntryInfoArray to the def file.
Implement automatic persistent saves.
Also loads persistent file on server start.
Update TODO.
raw_istream and kin: a few cleanups.
anchor() doesn't seem to change compiler output in current compilers, so
remove it. Use default where appropriate rather than empty bodies.
Clean up trailing whitespace.
Dispatcher: Move several fixed initial values to header.
Uninline constructors to reduce GetInstance() inlined code size.
Logger: Move m_min_level init to header.
Replaced time.h with std::chrono
This implementation returns the same values as the previous one on both a Linux machine and the roboRIO.
Value: Use variant of enable_if to fix MakeString/MakeRaw in GCC.
Tested on GCC 4.8, GCC 4.9, and clang 3.6.
Don't dispose in ConvertToC for NT_String and NT_Value.
Fixes#16.
Fixed Gradle build to actually export proper functions
Finishes fixes in pull request
Changes array setters to be const
To build RPC, needed a way to allocate a Char Array
Since after the callback, the C code explicitly frees, a way to make
sure to allocate the callback return string from the same heap was
needed.
Adds const to NTString setters.
Removes Const from NTString setters
The JNI bindings are built directly into the shared library. In the gradle
build, all built shared libraries are embedded into the generated jar.
Java bindings may be disabled via -DWITHOUT_JAVA (cmake) or -PskipJava=true
(gradle).
TODO:
- getEntryInfo() and RPC are not yet implemented.
- The cmake build doesn't integrate the built objects into the jar.
- The Java client and server tests are not built (but have been manually
tested).
This has not yet been tested on Windows.
Also only perform immediate notification to the callback actually
requesting the notification, not all existing callbacks.
Offset returned uids by 1 so uid=0 can be used to indicate immediate
notification.
Windows returns WSAEWOULDBLOCK on a connect() attempt on a nonblocking socket.
Also wrap socket error handling so errors are correctly reported on Windows.
Fixes#19.
- Missing header file callouts in some cases (library deltas)
- Lack of support for auto parameters in lambdas
- Defining of ERROR by windows.h
- Dispatcher::Connection needs a move constructor (default not generated)
- Need explicit enable_if on std::string move template in Value to avoid trying to move const char[] (string literal)
- Compile flags
This makes it difficult to test. Instead, store reference as member variable,
and populate it at constuction (with an alternate constructor available for
test purposes).
Updates are merged or themselves updated as user code changes. This avoids
the need for the dispatcher to do this and also avoids the need for disabling
updates when the dispatcher isn't running, because there's no risk of memory
usage piling up.
Previously, setters were locally but not globally atomic because they
used GetEntry() (globally atomic) in conjunction with locally atomic
gets/sets to the StorageEntry. To support synchronizing network handshakes
they need to be globally atomic.
GetEntry() has been removed due to this issue, so a helper was added to
StorageTest instead.
On the callback function, is_new indicates the value is newly added.
On adding a callback function, immediate_notify indicates the callback
should be called once (with is_new=true) for each matching entry that
already exists.
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 written here, 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.
@@ -20,7 +20,7 @@ So you want to contribute your changes back to WPILib. Great! We have a few cont
- Substantial changes often need to have corresponding LabVIEW changes. To do this, we will work with NI on these large changes.
- Changes should have tests.
- Code should be well documented.
- This often involves ScreenSteps. To add content to ScreenSteps, we will work with you to get the appropriate articles written.
- This involves writing tutorials and/or usage guides for your submitted feature. These articles are then hosted on the [WPILib](https://docs.wpilib.org/) documentation website. See the [frc-docs repository](https://github.com/wpilibsuite/frc-docs) for more information.
## What to Contribute
@@ -38,19 +38,51 @@ 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.
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, we ask that you squash your changes down to a single commit. For particularly large changes, multiple commits are ok, but assume one commit unless asked otherwise. No change will be merged unless it is up to date with the current master. We will also not merge any changes with merge commits in them; please rebase off of master before submitting a pull request. 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.
### Merge Process
When you first submit changes, Travis-CI will attempt to run `./gradlew check` on your change. If this fails, you will need to fix any issues that it sees. Once Travis passes, we will begin the review process in more earnest. One or more WPILib team members will review your change. This will be a back-and-forth process with the WPILib team and the greater community. Once we are satisfied that your change is ready, we will allow our Jenkins instance to test it. This will run the full gamut of checks, including integration tests on actual hardware. Once all tests have passed and the team is satisfied, we will merge your change into the WPILib repository.
When you first submit changes, GitHub Actions will attempt to run `./gradlew check` on your change. If this fails, you will need to fix any issues that it sees. Once Actions passes, we will begin the review process in more earnest. One or more WPILib team members will review your change. This will be a back-and-forth process with the WPILib team and the greater community. Once we are satisfied that your change is ready, we will allow our hosted instance to test it. This will run the full gamut of checks, including integration tests on actual hardware. Once all tests have passed and the team is satisfied, we will merge your change into the WPILib repository.
## Licensing
By contributing to WPILib, you agree that your code will be distributed with WPILib, and licensed under the license for the WPILib project. You should not contribute code that you do not have permission to relicense in this manner. This includes code that is licensed under the GPL that you do not have permission to relicense, as WPILib is not released under a copyleft license. Our license is the 3-clause BSD license, which you can find [here](license.txt).
By contributing to WPILib, you agree that your code will be distributed with WPILib, and licensed under the license for the WPILib project. You should not contribute code that you do not have permission to relicense in this manner. This includes code that is licensed under the GPL that you do not have permission to relicense, as WPILib is not released under a copyleft license. Our license is the 3-clause BSD license, which you can find [here](LICENSE.md).
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 every time a commit is pushed to the [allwpilib](https://github.com/wpilibsuite/allwpilib/) repository. These builds are then hosted on [artifactory](https://frcmaven.wpi.edu/artifactory/webapp/#/home).
To build a project using a development build, find the build.gradle file and open it. Then, add the following code below the plugin section and replace YEAR with the year of the development version. It is also necessary to use a 2023 GradleRIO version, ie `2023.0.0-alpha-1`
```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 "2023.0.0-alpha-1"
}
wpi.maven.useLocal = false
wpi.maven.useDevelopment = true
wpi.versions.wpilibVersion = '2023.+'
wpi.versions.wpimathVersion = '2023.+'
```
C++
```groovy
plugins {
id "cpp"
id "google-test-test-suite"
id "edu.wpi.first.GradleRIO" version "2023.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 "2023.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 "2023.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
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).
A variable needs to be added called `RUN_AZURE_ARTIFACTORY_RELEASE`, with a value of `true`. Then when the pipeline gets started, the final build outputs will be updated to artifactory.
To use newer versions of C++ dependencies, in `shared/config.gradle`, update the version related to the specific dependency.
For Java dependencies, there is likely a file related to the specific dependency in the shared folder. Update the version in there.
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 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 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.
Upon pushing a tag, a release will be built, and the files will be uploaded to the releases on GitHub. For publishing to the marketplace, you need a Microsoft account and to be added as a maintainer.
## Publishing GradleRIO
Before publishing, make sure to update the version in build.gradle. Publishing must happen locally, using the command `./gradlew publishPlugin`. This does require your API key for publishing to be set.
## Building the installer
Update the GradleRIO version in gradle.properties, and in the scripts folder in vscode, update the vscode extension. Then push, it will build the installer on azure.
WPILib publishes its built artifacts to our Maven server for use by downstream projects. This document explains these locations, and the meanings of artifact names, classifiers, and versions.
## Repositories
We provide two repositories. These repositories are:
The release repository is where official WPILib releases are 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.
## Artifact Names
WPILib builds four different types of artifacts.
##### C++ Only Libraries
When we publish C++ only libraries, they are published with the base artifact name as their artifact name, with a `-cpp` extension. All dependencies for the library are linked as shared libraries to the binary.
When we publish Java only libraries, they are published with the base artifact name as their artifact name, with a `-java` extension.
Example:
```
edu.wpi.first.wpilibj:wpilibj-java:version
```
#### C++/Java Libraries without JNI
For libraries that are both C++ and Java, but without a JNI component, the C++ component is published with the `basename-cpp` artifact name, and the Java component is published with the `basename-java` artifact name.
For libraries that are both C++ and Java with a JNI component there are three different artifact names. For Java, the component is published as `basename-java`. For C++, the `basename-cpp` artifact contains the C++ artifacts with all dependencies linked as shared libraries to the binary. These binaries DO contain the JNI entry points. The `basename-jni` artifact contains identical C++ binaries to the `-cpp` artifact, however all of its dependencies are statically linked, and only the JNI and C entry points are exported.
The `-jni` artifact should only be used in cases where you want to create a self contained Java application where the native artifacts are embedded in the jar. Note in an extraction scenario, extending off of the library is never supported, which is why the C++ entry points are not exposed. The name of the library is randomly generated during extraction. For pretty much all cases, and if you ever want to extend from a native library, you should use the `-cpp` artifacts. GradleRIO uses the `-cpp` artifacts for all platforms, even desktop, for this reason.
edu.wpi.first.ntcore:ntcore-jni:version:classifier (JNI jar library)
edu.wpi.first.ntcore:ntcore-java:version (Java)
```
## Provided Artifacts
This repository provides the following artifacts. Below each artifact is its dependencies. Note if ever using the `-jni` artifacts, no dependencies are needed for native binaries.
For C++, if building with static dependencies, the listed order should be the link order in your linker.
All artifacts are based at `edu.wpi.first.artifactname` in the repository.
* wpiutil
* wpigui
* imgui
* wpimath
* wpiutil
* 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
* hal
* cameraserver
* ntcore
* cscore
* wpinet
* wpiutil
* wpilibc
* hal
* cameraserver
* ntcore
* cscore
* wpimath
* wpinet
* wpiutil
* wpilibNewCommands
* wpilibc
* hal
* cameraserver
* ntcore
* cscore
* wpimath
* wpinet
* wpiutil
### Third Party Artifacts
This repository provides the builds of the following third party software.
All artifacts are based at `edu.wpi.first.thirdparty.frcYEAR` in the repository.
WPILib is normally built with Gradle, however for some systems, such as Linux based coprocessors, Gradle doesn't work correctly, especially if cscore is needed, which requires OpenCV. Furthermore, the CMake build can be used for C++ development because it provides better build caching compared to Gradle. We provide the CMake build for these cases. Although it is supported on Windows, these docs will only go over Linux builds.
## Libraries that get built
* wpiutil
* ntcore
* cscore
* cameraserver
* hal
* wpilib
* halsim
* wpigui
* wpimath
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.
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.
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.
## Build Options
The following build options are available:
*`WITH_JAVA` (ON Default)
* This option will enable Java and JNI builds. If this is on, `WITH_SHARED_LIBS` must be on. Otherwise CMake will error.
*`WITH_SHARED_LIBS` (ON Default)
* This option will cause cmake to build static libraries instead of shared libraries. If this is off, `WITH_JAVA` must be off. Otherwise CMake will error.
*`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_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)
* TODO
*`EXTERNAL_HAL_FILE`
* 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!
## Build Setup
The WPILib CMake build does not allow in source builds. Because the `build` directory is used by Gradle, we recommend a `build-cmake` directory in the root. This folder is included in the gitignore.
Once you have a build folder, run CMake configuration in that build directory with the following command.
```
cmake path/to/allwpilib/root
```
If you want to change any of the options, add `-DOPTIONHERE=VALUE` to the `cmake` command. This will check for any dependencies. If everything works properly this will succeed. If not, please check out the troubleshooting section for help.
If you want, you can also use `ccmake` in order to visually set these properties as well. [Here](https://cmake.org/cmake/help/v3.0/manual/ccmake.1.html) is the link to the documentation for that program.
## Building
Once you have cmake setup. run `make` from the directory you configured CMake in. This will build all libraries possible. If you have a multicore system, we recommend running `make` with multiple jobs. The usual rule of thumb is 1.5x the number of cores you have. To run a multiple job build, run the following command with x being the number of jobs you want.
```
make -jx
```
The `ninja` generator is also supported, and can be enabled by passing `-GNinja` to the initial `cmake` command.
## Installing
After build, the easiest way to use the libraries is to install them. Run the following command to install the libraries. This will install them so that they can be used from external cmake projects.
```
sudo make install
```
## Using the installed libraries for C++.
Using the libraries from C++ is the easiest way to use the built libraries.
To do so, create a new folder to contain your project. Add the following code below to a `CMakeLists.txt` file in that directory.
```
cmake_minimum_required(VERSION 3.5)
project(vision_app) # Project Name Here
find_package(wpilib REQUIRED)
add_executable(my_vision_app main.cpp) # executable name as first parameter
If you are using them, `wpilibc` and `hal` should be added before the `cameraserver` declaration in the `target_link_libraries` function.
Add a `main.cpp` file to contain your code, and create a build folder. Move into the build folder, and run
```
cmake /path/to/folder/containing/CMakeLists
```
After that, run `make`. That will create your executable. Then you should be able to run `./my_vision_app` to run your application.
## Using the installed libraries for Java
TODO
## Troubleshooting
Below are some common issues that are run into when building.
#### Missing OpenCV
If you are missing OpenCV, you will get an error message similar to this.
```
CMake Error at cscore/CMakeLists.txt:3 (find_package):
By not providing "FindOpenCV.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "OpenCV", but
CMake did not find one.
Could not find a package configuration file provided by "OpenCV" with any
of the following names:
OpenCVConfig.cmake
opencv-config.cmake
Add the installation prefix of "OpenCV" to CMAKE_PREFIX_PATH or set
"OpenCV_DIR" to a directory containing one of the above files. If "OpenCV"
provides a separate development package or SDK, be sure it has been
installed.
```
If you get that, you need make sure opencv was installed, and then reattempt to configure. If that doesn't work, set the `OpenCV_DIR` variable to the directory where you built OpenCV.
#### Missing Java
If you are missing Java, you will get a message like the following.
```
CMake Error at /usr/share/cmake-3.5/Modules/FindPackageHandleStandardArgs.cmake:148 (message):
Could NOT find Java (missing: Java_JAVA_EXECUTABLE Java_JAR_EXECUTABLE
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.
- [WPILib Mission](#wpilib-mission)
- [WPILib Project](#wpilib-project)
- [WPILib Mission](#wpilib-mission)
- [Building WPILib](#building-wpilib)
- [Requirements](#requirements)
- [Setup](#setup)
- [Building](#building)
- [Publishing](#publishing)
- [Structure and Organization](#structure-and-organization)
- [Requirements](#requirements)
- [Setup](#setup)
- [Building](#building)
- [Faster builds](#faster-builds)
- [Using Development Builds](#using-development-builds)
- [Structure and Organization](#structure-and-organization)
- [Contributing to WPILib](#contributing-to-wpilib)
## WPILib Mission
The WPILib Mission is to enable FIRST Robotics teams to focus on writing game-specific software rather than focussing 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.txt).
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
@@ -23,19 +40,28 @@ Using Gradle makes building WPILib very straightforward. It only has a few depen
## Requirements
-A C++ compiler
-On Linux, gcc works fine
- On Windows, you need Visual Studio 2015 (the free community edition works fine).
Make sure to select the C++ Programming Language for installation
-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 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 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. If the toolchains are not installed, install them, and make sure they are available on the system PATH.
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. We use clang-format 14.
## Building
@@ -51,61 +77,80 @@ To build a specific subproject, such as WPILibC, you must access the subproject
./gradlew :wpilibc:build
```
The gradlew wrapper only exists in the root of the main project, so be sure to run all commands from there. All of the subprojects have build tasks that can be run. Gradle automatically determines and rebuilds dependencies, so if you make a change in the HAL and then run `./gradlew :wpilibc:build`, the HAL will be rebuilt, then WPILibC.
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.
`testDesktopCpp` and `testDesktopJava` tasks also exist for the projects `wpiutil`, `ntcore`, `cscore`, `hal``wpilibNewCommands` and `cameraserver`. 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](DevelopmentBuilds.md)
### Custom toolchain location
If you have installed the FRC Toolchain to a directory other than the default, or if the Toolchain location is not on your System PATH, you can pass the `toolChainPath` property to specify where it is located. Example:
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.
### Formatting/linting
```bash
./gradlew build -PmakeSim
```
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.
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
#### wpiformat
```bash
mkdir build #run this in the root of allwpilib
cd build
cmake ..
make
```
wpiformat can be executed anywhere in the repository via `py -3 -m wpiformat -clang 14` on Windows or `python3 -m wpiformat -clang 14` on other platforms.
The gradlew wrapper only exists in the root of the main project, so be sure to run all commands from there. All of the subprojects have build tasks that can be run. Gradle automatically determines and rebuilds dependencies, so if you make a change in the HAL and then run `./gradlew :wpilibc:build`, the HAL will be rebuilt, then WPILibC.
#### Java Code Quality Tools
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.
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.
wpiformat can be executed anywhere in the repository via `py -3 -m wpiformat` on Windows or `python3 -m wpiformat` on other platforms.
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).
## Publishing
If you are building to test with the Eclipse plugins 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:
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:
- development - The default repo.
- beta - Publishes to ~/releases/maven/beta.
- stable - Publishes to ~/releases/maven/stable.
- release - Publishes to ~/releases/maven/release.
The following maven targets a published by this task:
- edu.wpi.first.wpilib.cmake:cpp-root:1.0.0 - roboRIO C++
- edu.wpi.first.wpilibc.simulation:WPILibCSim:0.1.0 - Simulation C++
- edu.wpi.first.wpilibj.simulation:SimDS:0.1.0-SNAPSHOT - The driverstation for controlling simulation.
- org.gazebosim:JavaGazebo:0.1.0-SNAPSHOT - Gazebo protocol for Java.
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).
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.