Compare commits

...

18 Commits

Author SHA1 Message Date
Dean Brettle
3116f790ea [sysid] Fix wrong position Kd with unnormalized time (#6433) 2024-03-12 21:49:28 -07:00
Tyler Veness
0e013dc021 [sysid] Fix "Sample" docs typo (NFC) (#6435) 2024-03-11 20:23:03 -07:00
sciencewhiz
f74f6f1d42 [docs] Add docs for features not supported on PDH (NFC) (#6436) 2024-03-11 20:22:33 -07:00
Peter Johnson
11c60df3e0 [hal] Use SIGKILL instead of SIGILL (#6431)
Fix typo.
2024-03-11 09:43:33 -07:00
Peter Johnson
3d9152a461 [hal] Raise SIGKILL instead of calling abort() (#6427)
We don't need to generate a core dump here if core dumps are enabled.
2024-03-10 20:32:54 -07:00
Peter Johnson
fbd239d15e [sim] GUI: Use shift to enable docking features (#6429) 2024-03-10 20:29:20 -07:00
Tyler Veness
7cd4a75323 [sysid] Fix crash on negative feedforward gains (#6425)
LinearSystemId's linear system factories throw on negative feedforward
gains, but SysId can compute the feedback gains just fine in that case.
Now we construct the system manually instead.

Fixes #6423.
2024-03-10 17:43:02 -07:00
Tyler Veness
973bb55e66 [wpimath] LinearSystemId: Don't throw if Kv = 0 (#6424)
That's just a system with no back-EMF.
2024-03-10 08:11:18 -07:00
DeltaDizzy
7bd8c44570 [wpimath] Add structured data support for DifferentialDriveWheelPositions (#6412) 2024-03-09 10:09:02 -08:00
Peter Johnson
18e57f7872 [wpilibj] Call abort() on Rio on caught Java exception (#6420)
On Rio, we simply want to restart the robot program as quickly as possible,
and don't want to risk a hang somewhere that will keep that from happening.

The main downside of this is it won't wait for threads to finish (e.g. data logs won't get a final flush).
2024-03-09 09:55:49 -08:00
Tyler Veness
ccb4cbed63 [sysid] Fix arm characterization crash (#6422)
Fixes #6421.
2024-03-09 09:54:37 -08:00
Thad House
c19ee8b0fe [wpiutil, hal] Crash on failure for SetupNowRio() and wpi::Now() when not configured (#6417)
This is an unrecoverable condition, so always terminate.
2024-03-08 00:26:53 -08:00
Tyler Veness
e64c20346d [examples] Remove unused private variables (#6403) 2024-02-28 19:58:15 -08:00
Peter Johnson
f1a1ffd7fc [wpiutil] Rate-limit FPGA error from Now() (#6394) 2024-02-25 11:25:46 -08:00
Peter Johnson
c27ddf5ef9 [ci] Windows cmake: update vcpkg version (#6397)
We need fmtlib 10.2.1 to work around a compiler bug.

Also, reducing the number of jobs is no longer required with Actions runner upgrades.
2024-02-24 18:55:10 -08:00
Dean Brettle
8b669330eb [sysid] Fix position feedback latency compensation (#6392) 2024-02-23 14:13:43 -08:00
Tyler Veness
ca6e307ea5 [ci] Upgrade wpiformat (#6395) 2024-02-23 14:12:28 -08:00
DeltaDizzy
607682b687 [wpiunits] Fix Distance class javadocs to state the correct dimension (NFC) (#6363) 2024-02-19 12:58:56 -08:00
35 changed files with 851 additions and 129 deletions

View File

@@ -88,28 +88,13 @@ jobs:
uses: lukka/run-vcpkg@v11.1
with:
vcpkgDirectory: ${{ runner.workspace }}/vcpkg
vcpkgGitCommitId: 78b61582c9e093fda56a01ebb654be15a0033897 # HEAD on 2023-08-6
vcpkgGitCommitId: 37c3e63a1306562f7f59c4c3c8892ddd50fdf992 # HEAD on 2024-02-24
- name: configure
run: cmake -S . -B build -G "Ninja" -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache -DCMAKE_BUILD_TYPE=Release -DWITH_JAVA=OFF -DWITH_EXAMPLES=ON -DUSE_SYSTEM_FMTLIB=ON -DUSE_SYSTEM_LIBUV=ON -DUSE_SYSTEM_EIGEN=OFF -DCMAKE_TOOLCHAIN_FILE=${{ runner.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_INSTALL_OPTIONS=--clean-after-build -DVCPKG_TARGET_TRIPLET=x64-windows-release -DVCPKG_HOST_TRIPLET=x64-windows-release
env:
SCCACHE_GHA_ENABLED: "true"
# Build wpiutil at full speed, wpimath depends on wpiutil
- name: build wpiutil
working-directory: build
run: cmake --build . --parallel $(nproc) --target wpiutil/all
env:
SCCACHE_GHA_ENABLED: "true"
# Build wpimath slow to prevent OOM
- name: build wpimath
working-directory: build
run: cmake --build . --parallel 1 --target wpimath/all
env:
SCCACHE_GHA_ENABLED: "true"
# Build everything else fast
- name: build
working-directory: build
run: cmake --build . --parallel $(nproc)

View File

@@ -27,7 +27,7 @@ jobs:
with:
python-version: 3.8
- name: Install wpiformat
run: pip3 install wpiformat==2023.36
run: pip3 install wpiformat==2024.32
- name: Run
run: wpiformat
- name: Check output

View File

@@ -75,6 +75,9 @@ public final class HAL extends JNIWrapper {
*/
public static native void exitMain();
/** Terminates the executable (at the native level). Does nothing in simulation. */
public static native void terminate();
private static native void simPeriodicBeforeNative();
private static final List<Runnable> s_simPeriodicBefore = new ArrayList<>();

View File

@@ -83,6 +83,8 @@ public class PowerDistributionJNI extends JNIWrapper {
/**
* Gets the temperature of the PowerDistribution.
*
* <p>Not supported on the Rev PDH and returns 0.
*
* @param handle the module handle
* @return the module temperature (celsius)
* @see "HAL_GetPowerDistributionTemperature"
@@ -129,7 +131,9 @@ public class PowerDistributionJNI extends JNIWrapper {
public static native double getTotalCurrent(int handle);
/**
* Gets the total power of the PowerDistribution.
* Gets the total power of the Power Distribution Panel.
*
* <p>Not supported on the Rev PDH and returns 0.
*
* @param handle the module handle
* @return the total power (watts)
@@ -138,7 +142,9 @@ public class PowerDistributionJNI extends JNIWrapper {
public static native double getTotalPower(int handle);
/**
* Gets the total energy of the PowerDistribution.
* Gets the total energy of the Power Distribution Panel.
*
* <p>Not supported on the Rev PDH and does nothing.
*
* @param handle the module handle
* @return the total energy (joules)
@@ -147,7 +153,9 @@ public class PowerDistributionJNI extends JNIWrapper {
public static native double getTotalEnergy(int handle);
/**
* Resets the PowerDistribution accumulated energy.
* Resets the Power Distribution Panel accumulated energy.
*
* <p>Not supported on the Rev PDH and returns 0.
*
* @param handle the module handle
* @see "HAL_ClearPowerDistributionStickyFaults"

View File

@@ -594,6 +594,14 @@ HAL_Bool HAL_Initialize(int32_t timeout, int32_t mode) {
});
if (!SetupNowRio()) {
fmt::print(stderr,
"Failed to run SetupNowRio(). This is a fatal error. The "
"process is being terminated.\n");
std::fflush(stderr);
// Attempt to force a segfault to get a better java log
*reinterpret_cast<int*>(0) = 0;
// If that fails, terminate
std::terminate();
return false;
}

View File

@@ -6,6 +6,10 @@
#include <jni.h>
#ifdef __FRC_ROBORIO__
#include <signal.h>
#endif
#include <cassert>
#include <cstring>
@@ -82,6 +86,20 @@ Java_edu_wpi_first_hal_HAL_exitMain
HAL_ExitMain();
}
/*
* Class: edu_wpi_first_hal_HAL
* Method: terminate
* Signature: ()V
*/
JNIEXPORT void JNICALL
Java_edu_wpi_first_hal_HAL_terminate
(JNIEnv*, jclass)
{
#ifdef __FRC_ROBORIO__
::raise(SIGKILL);
#endif
}
/*
* Class: edu_wpi_first_hal_HAL
* Method: simPeriodicBeforeNative

View File

@@ -101,7 +101,9 @@ int32_t HAL_GetPowerDistributionNumChannels(HAL_PowerDistributionHandle handle,
int32_t* status);
/**
* Gets the temperature of the PowerDistribution.
* Gets the temperature of the Power Distribution Panel.
*
* Not supported on the Rev PDH and returns 0.
*
* @param[in] handle the module handle
* @param[out] status Error status variable. 0 on success.
@@ -156,7 +158,9 @@ double HAL_GetPowerDistributionTotalCurrent(HAL_PowerDistributionHandle handle,
int32_t* status);
/**
* Gets the total power of the PowerDistribution.
* Gets the total power of the Power Distribution Panel.
*
* Not supported on the Rev PDH and returns 0.
*
* @param[in] handle the module handle
* @param[out] status Error status variable. 0 on success.
@@ -166,7 +170,9 @@ double HAL_GetPowerDistributionTotalPower(HAL_PowerDistributionHandle handle,
int32_t* status);
/**
* Gets the total energy of the PowerDistribution.
* Gets the total energy of the Power Distribution Panel.
*
* Not supported on the Rev PDH and returns 0.
*
* @param[in] handle the module handle
* @param[out] status Error status variable. 0 on success.
@@ -178,6 +184,8 @@ double HAL_GetPowerDistributionTotalEnergy(HAL_PowerDistributionHandle handle,
/**
* Resets the PowerDistribution accumulated energy.
*
* Not supported on the Rev PDH and does nothing.
*
* @param[in] handle the module handle
* @param[out] status Error status variable. 0 on success.
*/

View File

@@ -51,6 +51,8 @@ __declspec(dllexport)
glass::SetStorageName("simgui");
gui::AddInit([] { ImGui::GetIO().ConfigDockingWithShift = true; });
HAL_RegisterExtension(HALSIMGUI_EXT_ADDGUIINIT,
reinterpret_cast<void*>((AddGuiInitFn)&AddGuiInit));
HAL_RegisterExtension(

View File

@@ -4,9 +4,10 @@
#include "sysid/analysis/FeedbackAnalysis.h"
#include <cmath>
#include <frc/controller/LinearQuadraticRegulator.h>
#include <frc/system/LinearSystem.h>
#include <frc/system/plant/LinearSystemId.h>
#include <units/acceleration.h>
#include <units/velocity.h>
#include <units/voltage.h>
@@ -21,22 +22,30 @@ using Ka_t = decltype(1_V / 1_mps_sq);
FeedbackGains sysid::CalculatePositionFeedbackGains(
const FeedbackControllerPreset& preset, const LQRParameters& params,
double Kv, double Ka) {
if (!std::isfinite(Kv) || !std::isfinite(Ka)) {
return {0.0, 0.0};
}
// If acceleration requires no effort, velocity becomes an input for position
// control. We choose an appropriate model in this case to avoid numerical
// instabilities in the LQR.
if (Ka > 1E-7) {
// Create a position system from our feedforward gains.
auto system = frc::LinearSystemId::IdentifyPositionSystem<units::meter>(
Kv_t(Kv), Ka_t(Ka));
frc::LinearSystem<2, 1, 1> system{
frc::Matrixd<2, 2>{{0.0, 1.0}, {0.0, -Kv / Ka}},
frc::Matrixd<2, 1>{0.0, 1.0 / Ka}, frc::Matrixd<1, 2>{1.0, 0.0},
frc::Matrixd<1, 1>{0.0}};
// Create an LQR with 2 states to control -- position and velocity.
frc::LinearQuadraticRegulator<2, 1> controller{
system, {params.qp, params.qv}, {params.r}, preset.period};
// Compensate for any latency from sensor measurements, filtering, etc.
controller.LatencyCompensate(system, preset.period, 0.0_s);
controller.LatencyCompensate(system, preset.period,
preset.measurementDelay);
return {controller.K(0, 0) * preset.outputConversionFactor,
controller.K(0, 1) * preset.outputConversionFactor /
(preset.normalized ? 1 : preset.period.value())};
return {
controller.K(0, 0) * preset.outputConversionFactor,
controller.K(0, 1) * preset.outputConversionFactor /
(preset.normalized ? 1 : units::second_t{preset.period}.value())};
}
// This is our special model to avoid instabilities in the LQR.
@@ -47,7 +56,7 @@ FeedbackGains sysid::CalculatePositionFeedbackGains(
frc::LinearQuadraticRegulator<1, 1> controller{
system, {params.qp}, {params.r}, preset.period};
// Compensate for any latency from sensor measurements, filtering, etc.
controller.LatencyCompensate(system, preset.period, 0.0_s);
controller.LatencyCompensate(system, preset.period, preset.measurementDelay);
return {Kv * controller.K(0, 0) * preset.outputConversionFactor, 0.0};
}
@@ -55,6 +64,10 @@ FeedbackGains sysid::CalculatePositionFeedbackGains(
FeedbackGains sysid::CalculateVelocityFeedbackGains(
const FeedbackControllerPreset& preset, const LQRParameters& params,
double Kv, double Ka, double encFactor) {
if (!std::isfinite(Kv) || !std::isfinite(Ka)) {
return {0.0, 0.0};
}
// If acceleration for velocity control requires no effort, the feedback
// control gains approach zero. We special-case it here because numerical
// instabilities arise in LQR otherwise.
@@ -63,8 +76,9 @@ FeedbackGains sysid::CalculateVelocityFeedbackGains(
}
// Create a velocity system from our feedforward gains.
auto system = frc::LinearSystemId::IdentifyVelocitySystem<units::meter>(
Kv_t(Kv), Ka_t(Ka));
frc::LinearSystem<1, 1, 1> system{
frc::Matrixd<1, 1>{-Kv / Ka}, frc::Matrixd<1, 1>{1.0 / Ka},
frc::Matrixd<1, 1>{1.0}, frc::Matrixd<1, 1>{0.0}};
// Create an LQR controller with 1 state -- velocity.
frc::LinearQuadraticRegulator<1, 1> controller{
system, {params.qv}, {params.r}, preset.period};

View File

@@ -33,7 +33,7 @@ class ArmSim {
* forward dt seconds.
*
* @param voltage Voltage to apply over the timestep.
* @param dt Sammple period.
* @param dt Sample period.
*/
void Update(units::volt_t voltage, units::second_t dt);

View File

@@ -31,7 +31,7 @@ class ElevatorSim {
* dt seconds.
*
* @param voltage Voltage to apply over the timestep.
* @param dt Sammple period.
* @param dt Sample period.
*/
void Update(units::volt_t voltage, units::second_t dt);

View File

@@ -30,7 +30,7 @@ class SimpleMotorSim {
* seconds.
*
* @param voltage Voltage to apply over the timestep.
* @param dt Sammple period.
* @param dt Sample period.
*/
void Update(units::volt_t voltage, units::second_t dt);

View File

@@ -103,3 +103,43 @@ TEST(FeedbackAnalysisTest, VelocityREVConversion) {
EXPECT_NEAR(Kp, 0.00241 / 3, 0.005);
EXPECT_NEAR(Kd, 0.00, 0.05);
}
TEST(FeedbackAnalysisTest, Position) {
auto Kv = 3.060;
auto Ka = 0.327;
sysid::LQRParameters params{1, 1.5, 7};
auto [Kp, Kd] = sysid::CalculatePositionFeedbackGains(
sysid::presets::kDefault, params, Kv, Ka);
EXPECT_NEAR(Kp, 6.41, 0.05);
EXPECT_NEAR(Kd, 2.48, 0.05);
}
TEST(FeedbackAnalysisTest, PositionWithLatencyCompensation) {
auto Kv = 3.060;
auto Ka = 0.327;
sysid::LQRParameters params{1, 1.5, 7};
sysid::FeedbackControllerPreset preset{sysid::presets::kDefault};
preset.measurementDelay = 10_ms;
auto [Kp, Kd] = sysid::CalculatePositionFeedbackGains(preset, params, Kv, Ka);
EXPECT_NEAR(Kp, 5.92, 0.05);
EXPECT_NEAR(Kd, 2.12, 0.05);
}
TEST(FeedbackAnalysisTest, PositionREV) {
auto Kv = 3.060;
auto Ka = 0.327;
sysid::LQRParameters params{1, 1.5, 7};
auto [Kp, Kd] = sysid::CalculatePositionFeedbackGains(
sysid::presets::kREVNEOBuiltIn, params, Kv, Ka);
EXPECT_NEAR(Kp, 0.30202, 0.05);
EXPECT_NEAR(Kd, 48.518, 0.05);
}

View File

@@ -7,5 +7,5 @@
"libuv",
"protobuf"
],
"builtin-baseline": "78b61582c9e093fda56a01ebb654be15a0033897"
"builtin-baseline": "37c3e63a1306562f7f59c4c3c8892ddd50fdf992"
}

View File

@@ -58,7 +58,10 @@ class PowerDistribution : public wpi::Sendable,
double GetVoltage() const;
/**
* Query the temperature of the PDP/PDH.
* Query the temperature of the PDP.
*
* Not supported on the Rev PDH and returns 0.
*
*
* @return The temperature in degrees Celsius
*/
@@ -80,21 +83,27 @@ class PowerDistribution : public wpi::Sendable,
double GetTotalCurrent() const;
/**
* Query the total power drawn from all monitored PDP/PDH channels.
* Query the total power drawn from all monitored PDP channels.
*
* Not supported on the Rev PDH and returns 0.
*
* @return The total power drawn in Watts
*/
double GetTotalPower() const;
/**
* Query the total energy drawn from the monitored PDP/PDH channels.
* Query the total energy drawn from the monitored PDP channels.
*
* Not supported on the Rev PDH and returns 0.
*
* @return The total energy drawn in Joules
*/
double GetTotalEnergy() const;
/**
* Reset the total energy drawn from the PDP/PDH.
* Reset the total energy drawn from the PDP.
*
* Not supported on the Rev PDH and does nothing.
*
* @see PowerDistribution#GetTotalEnergy
*/

View File

@@ -44,7 +44,6 @@ class Elevator : public frc2::PIDSubsystem {
private:
frc::PWMSparkMax m_motor{5};
double m_setpoint = 0;
// Conversion value of potentiometer varies between the real world and
// simulation

View File

@@ -41,7 +41,6 @@ class Wrist : public frc2::PIDSubsystem {
private:
frc::PWMSparkMax m_motor{6};
double m_setpoint = 0;
// Conversion value of potentiometer varies between the real world and
// simulation

View File

@@ -93,7 +93,9 @@ public class PowerDistribution implements Sendable, AutoCloseable {
}
/**
* Query the temperature of the PDP/PDH.
* Query the temperature of the PDP.
*
* <p>Not supported on the Rev PDH and returns 0.
*
* @return The temperature in degrees Celsius
*/
@@ -121,7 +123,9 @@ public class PowerDistribution implements Sendable, AutoCloseable {
}
/**
* Query the total power drawn from the monitored channels.
* Query the total power drawn from the monitored channels of the PDP.
*
* <p>Not supported on the Rev PDH and returns 0.
*
* @return the total power in Watts
*/
@@ -130,7 +134,9 @@ public class PowerDistribution implements Sendable, AutoCloseable {
}
/**
* Query the total energy drawn from the monitored channels.
* Query the total energy drawn from the monitored channels of the PDP.
*
* <p>Not supported on the Rev PDH and returns 0.
*
* @return the total energy in Joules
*/
@@ -138,7 +144,11 @@ public class PowerDistribution implements Sendable, AutoCloseable {
return PowerDistributionJNI.getTotalEnergy(m_handle);
}
/** Reset the total energy to 0. */
/**
* Reset the total energy to 0 of the PDP.
*
* <p>Not supported on the Rev PDH and does nothing.
*/
public void resetTotalEnergy() {
PowerDistributionJNI.resetTotalEnergy(m_handle);
}

View File

@@ -453,6 +453,11 @@ public abstract class RobotBase implements AutoCloseable {
runRobot(robotSupplier);
}
// On RIO, this will just terminate rather than shutting down cleanly (it's a no-op in sim).
// It's not worth the risk of hanging on shutdown when we want the code to restart as quickly
// as possible.
HAL.terminate();
HAL.shutdown();
System.exit(0);

View File

@@ -19,61 +19,65 @@ import us.hebi.quickbuf.RepeatedByte;
import us.hebi.quickbuf.RepeatedMessage;
public final class Kinematics {
private static final RepeatedByte descriptorData = ProtoUtil.decodeBase64(3208,
private static final RepeatedByte descriptorData = ProtoUtil.decodeBase64(3427,
"ChBraW5lbWF0aWNzLnByb3RvEgl3cGkucHJvdG8aEGdlb21ldHJ5MmQucHJvdG8iTQoVUHJvdG9idWZD" +
"aGFzc2lzU3BlZWRzEg4KAnZ4GAEgASgBUgJ2eBIOCgJ2eRgCIAEoAVICdnkSFAoFb21lZ2EYAyABKAFS" +
"BW9tZWdhIkYKI1Byb3RvYnVmRGlmZmVyZW50aWFsRHJpdmVLaW5lbWF0aWNzEh8KC3RyYWNrX3dpZHRo" +
"GAEgASgBUgp0cmFja1dpZHRoIlAKJFByb3RvYnVmRGlmZmVyZW50aWFsRHJpdmVXaGVlbFNwZWVkcxIS" +
"CgRsZWZ0GAEgASgBUgRsZWZ0EhQKBXJpZ2h0GAIgASgBUgVyaWdodCKkAgoeUHJvdG9idWZNZWNhbnVt" +
"RHJpdmVLaW5lbWF0aWNzEj8KCmZyb250X2xlZnQYASABKAsyIC53cGkucHJvdG8uUHJvdG9idWZUcmFu" +
"c2xhdGlvbjJkUglmcm9udExlZnQSQQoLZnJvbnRfcmlnaHQYAiABKAsyIC53cGkucHJvdG8uUHJvdG9i" +
"dWZUcmFuc2xhdGlvbjJkUgpmcm9udFJpZ2h0Ej0KCXJlYXJfbGVmdBgDIAEoCzIgLndwaS5wcm90by5Q" +
"cm90b2J1ZlRyYW5zbGF0aW9uMmRSCHJlYXJMZWZ0Ej8KCnJlYXJfcmlnaHQYBCABKAsyIC53cGkucHJv" +
"dG8uUHJvdG9idWZUcmFuc2xhdGlvbjJkUglyZWFyUmlnaHQinwEKIVByb3RvYnVmTWVjYW51bURyaXZl" +
"TW90b3JWb2x0YWdlcxIdCgpmcm9udF9sZWZ0GAEgASgBUglmcm9udExlZnQSHwoLZnJvbnRfcmlnaHQY" +
"AiABKAFSCmZyb250UmlnaHQSGwoJcmVhcl9sZWZ0GAMgASgBUghyZWFyTGVmdBIdCgpyZWFyX3JpZ2h0" +
"GAQgASgBUglyZWFyUmlnaHQioAEKIlByb3RvYnVmTWVjYW51bURyaXZlV2hlZWxQb3NpdGlvbnMSHQoK" +
"ZnJvbnRfbGVmdBgBIAEoAVIJZnJvbnRMZWZ0Eh8KC2Zyb250X3JpZ2h0GAIgASgBUgpmcm9udFJpZ2h0" +
"EhsKCXJlYXJfbGVmdBgDIAEoAVIIcmVhckxlZnQSHQoKcmVhcl9yaWdodBgEIAEoAVIJcmVhclJpZ2h0" +
"Ip0BCh9Qcm90b2J1Zk1lY2FudW1Ecml2ZVdoZWVsU3BlZWRzEh0KCmZyb250X2xlZnQYASABKAFSCWZy" +
"b250TGVmdBIfCgtmcm9udF9yaWdodBgCIAEoAVIKZnJvbnRSaWdodBIbCglyZWFyX2xlZnQYAyABKAFS" +
"CHJlYXJMZWZ0Eh0KCnJlYXJfcmlnaHQYBCABKAFSCXJlYXJSaWdodCJbCh1Qcm90b2J1ZlN3ZXJ2ZURy" +
"aXZlS2luZW1hdGljcxI6Cgdtb2R1bGVzGAEgAygLMiAud3BpLnByb3RvLlByb3RvYnVmVHJhbnNsYXRp" +
"b24yZFIHbW9kdWxlcyJvChxQcm90b2J1ZlN3ZXJ2ZU1vZHVsZVBvc2l0aW9uEhoKCGRpc3RhbmNlGAEg",
"ASgBUghkaXN0YW5jZRIzCgVhbmdsZRgCIAEoCzIdLndwaS5wcm90by5Qcm90b2J1ZlJvdGF0aW9uMmRS" +
"BWFuZ2xlImYKGVByb3RvYnVmU3dlcnZlTW9kdWxlU3RhdGUSFAoFc3BlZWQYASABKAFSBXNwZWVkEjMK" +
"BWFuZ2xlGAIgASgLMh0ud3BpLnByb3RvLlByb3RvYnVmUm90YXRpb24yZFIFYW5nbGVCGgoYZWR1Lndw" +
"aS5maXJzdC5tYXRoLnByb3RvSocOCgYSBAAAPwEKCAoBDBIDAAASCggKAQISAwIAEgoJCgIDABIDBAAa" +
"CggKAQgSAwYAMQoJCgIIARIDBgAxCgoKAgQAEgQIAAwBCgoKAwQAARIDCAgdCgsKBAQAAgASAwkCEAoM" +
"CgUEAAIABRIDCQIICgwKBQQAAgABEgMJCQsKDAoFBAACAAMSAwkODwoLCgQEAAIBEgMKAhAKDAoFBAAC" +
"AQUSAwoCCAoMCgUEAAIBARIDCgkLCgwKBQQAAgEDEgMKDg8KCwoEBAACAhIDCwITCgwKBQQAAgIFEgML" +
"AggKDAoFBAACAgESAwsJDgoMCgUEAAICAxIDCxESCgoKAgQBEgQOABABCgoKAwQBARIDDggrCgsKBAQB" +
"AgASAw8CGQoMCgUEAQIABRIDDwIICgwKBQQBAgABEgMPCRQKDAoFBAECAAMSAw8XGAoKCgIEAhIEEgAV" +
"AQoKCgMEAgESAxIILAoLCgQEAgIAEgMTAhIKDAoFBAICAAUSAxMCCAoMCgUEAgIAARIDEwkNCgwKBQQC" +
"AgADEgMTEBEKCwoEBAICARIDFAITCgwKBQQCAgEFEgMUAggKDAoFBAICAQESAxQJDgoMCgUEAgIBAxID" +
"FBESCgoKAgQDEgQXABwBCgoKAwQDARIDFwgmCgsKBAQDAgASAxgCJwoMCgUEAwIABhIDGAIXCgwKBQQD" +
"AgABEgMYGCIKDAoFBAMCAAMSAxglJgoLCgQEAwIBEgMZAigKDAoFBAMCAQYSAxkCFwoMCgUEAwIBARID" +
"GRgjCgwKBQQDAgEDEgMZJicKCwoEBAMCAhIDGgImCgwKBQQDAgIGEgMaAhcKDAoFBAMCAgESAxoYIQoM" +
"CgUEAwICAxIDGiQlCgsKBAQDAgMSAxsCJwoMCgUEAwIDBhIDGwIXCgwKBQQDAgMBEgMbGCIKDAoFBAMC" +
"AwMSAxslJgoKCgIEBBIEHgAjAQoKCgMEBAESAx4IKQoLCgQEBAIAEgMfAhgKDAoFBAQCAAUSAx8CCAoM" +
"CgUEBAIAARIDHwkTCgwKBQQEAgADEgMfFhcKCwoEBAQCARIDIAIZCgwKBQQEAgEFEgMgAggKDAoFBAQC" +
"AQESAyAJFAoMCgUEBAIBAxIDIBcYCgsKBAQEAgISAyECFwoMCgUEBAICBRIDIQIICgwKBQQEAgIBEgMh" +
"CRIKDAoFBAQCAgMSAyEVFgoLCgQEBAIDEgMiAhgKDAoFBAQCAwUSAyICCAoMCgUEBAIDARIDIgkTCgwK" +
"BQQEAgMDEgMiFhcKCgoCBAUSBCUAKgEKCgoDBAUBEgMlCCoKCwoEBAUCABIDJgIYCgwKBQQFAgAFEgMm",
"AggKDAoFBAUCAAESAyYJEwoMCgUEBQIAAxIDJhYXCgsKBAQFAgESAycCGQoMCgUEBQIBBRIDJwIICgwK" +
"BQQFAgEBEgMnCRQKDAoFBAUCAQMSAycXGAoLCgQEBQICEgMoAhcKDAoFBAUCAgUSAygCCAoMCgUEBQIC" +
"ARIDKAkSCgwKBQQFAgIDEgMoFRYKCwoEBAUCAxIDKQIYCgwKBQQFAgMFEgMpAggKDAoFBAUCAwESAykJ" +
"EwoMCgUEBQIDAxIDKRYXCgoKAgQGEgQsADEBCgoKAwQGARIDLAgnCgsKBAQGAgASAy0CGAoMCgUEBgIA" +
"BRIDLQIICgwKBQQGAgABEgMtCRMKDAoFBAYCAAMSAy0WFwoLCgQEBgIBEgMuAhkKDAoFBAYCAQUSAy4C" +
"CAoMCgUEBgIBARIDLgkUCgwKBQQGAgEDEgMuFxgKCwoEBAYCAhIDLwIXCgwKBQQGAgIFEgMvAggKDAoF" +
"BAYCAgESAy8JEgoMCgUEBgICAxIDLxUWCgsKBAQGAgMSAzACGAoMCgUEBgIDBRIDMAIICgwKBQQGAgMB" +
"EgMwCRMKDAoFBAYCAwMSAzAWFwoKCgIEBxIEMwA1AQoKCgMEBwESAzMIJQoLCgQEBwIAEgM0Ai0KDAoF" +
"BAcCAAQSAzQCCgoMCgUEBwIABhIDNAsgCgwKBQQHAgABEgM0ISgKDAoFBAcCAAMSAzQrLAoKCgIECBIE" +
"NwA6AQoKCgMECAESAzcIJAoLCgQECAIAEgM4AhYKDAoFBAgCAAUSAzgCCAoMCgUECAIAARIDOAkRCgwK" +
"BQQIAgADEgM4FBUKCwoEBAgCARIDOQIfCgwKBQQIAgEGEgM5AhQKDAoFBAgCAQESAzkVGgoMCgUECAIB" +
"AxIDOR0eCgoKAgQJEgQ8AD8BCgoKAwQJARIDPAghCgsKBAQJAgASAz0CEwoMCgUECQIABRIDPQIICgwK" +
"BQQJAgABEgM9CQ4KDAoFBAkCAAMSAz0REgoLCgQECQIBEgM+Ah8KDAoFBAkCAQYSAz4CFAoMCgUECQIB" +
"ARIDPhUaCgwKBQQJAgEDEgM+HR5iBnByb3RvMw==");
"CgRsZWZ0GAEgASgBUgRsZWZ0EhQKBXJpZ2h0GAIgASgBUgVyaWdodCJTCidQcm90b2J1ZkRpZmZlcmVu" +
"dGlhbERyaXZlV2hlZWxQb3NpdGlvbnMSEgoEbGVmdBgBIAEoAVIEbGVmdBIUCgVyaWdodBgCIAEoAVIF" +
"cmlnaHQipAIKHlByb3RvYnVmTWVjYW51bURyaXZlS2luZW1hdGljcxI/Cgpmcm9udF9sZWZ0GAEgASgL" +
"MiAud3BpLnByb3RvLlByb3RvYnVmVHJhbnNsYXRpb24yZFIJZnJvbnRMZWZ0EkEKC2Zyb250X3JpZ2h0" +
"GAIgASgLMiAud3BpLnByb3RvLlByb3RvYnVmVHJhbnNsYXRpb24yZFIKZnJvbnRSaWdodBI9CglyZWFy" +
"X2xlZnQYAyABKAsyIC53cGkucHJvdG8uUHJvdG9idWZUcmFuc2xhdGlvbjJkUghyZWFyTGVmdBI/Cgpy" +
"ZWFyX3JpZ2h0GAQgASgLMiAud3BpLnByb3RvLlByb3RvYnVmVHJhbnNsYXRpb24yZFIJcmVhclJpZ2h0" +
"Ip8BCiFQcm90b2J1Zk1lY2FudW1Ecml2ZU1vdG9yVm9sdGFnZXMSHQoKZnJvbnRfbGVmdBgBIAEoAVIJ" +
"ZnJvbnRMZWZ0Eh8KC2Zyb250X3JpZ2h0GAIgASgBUgpmcm9udFJpZ2h0EhsKCXJlYXJfbGVmdBgDIAEo" +
"AVIIcmVhckxlZnQSHQoKcmVhcl9yaWdodBgEIAEoAVIJcmVhclJpZ2h0IqABCiJQcm90b2J1Zk1lY2Fu" +
"dW1Ecml2ZVdoZWVsUG9zaXRpb25zEh0KCmZyb250X2xlZnQYASABKAFSCWZyb250TGVmdBIfCgtmcm9u" +
"dF9yaWdodBgCIAEoAVIKZnJvbnRSaWdodBIbCglyZWFyX2xlZnQYAyABKAFSCHJlYXJMZWZ0Eh0KCnJl" +
"YXJfcmlnaHQYBCABKAFSCXJlYXJSaWdodCKdAQofUHJvdG9idWZNZWNhbnVtRHJpdmVXaGVlbFNwZWVk" +
"cxIdCgpmcm9udF9sZWZ0GAEgASgBUglmcm9udExlZnQSHwoLZnJvbnRfcmlnaHQYAiABKAFSCmZyb250" +
"UmlnaHQSGwoJcmVhcl9sZWZ0GAMgASgBUghyZWFyTGVmdBIdCgpyZWFyX3JpZ2h0GAQgASgBUglyZWFy" +
"UmlnaHQiWwodUHJvdG9idWZTd2VydmVEcml2ZUtpbmVtYXRpY3MSOgoHbW9kdWxlcxgBIAMoCzIgLndw",
"aS5wcm90by5Qcm90b2J1ZlRyYW5zbGF0aW9uMmRSB21vZHVsZXMibwocUHJvdG9idWZTd2VydmVNb2R1" +
"bGVQb3NpdGlvbhIaCghkaXN0YW5jZRgBIAEoAVIIZGlzdGFuY2USMwoFYW5nbGUYAiABKAsyHS53cGku" +
"cHJvdG8uUHJvdG9idWZSb3RhdGlvbjJkUgVhbmdsZSJmChlQcm90b2J1ZlN3ZXJ2ZU1vZHVsZVN0YXRl" +
"EhQKBXNwZWVkGAEgASgBUgVzcGVlZBIzCgVhbmdsZRgCIAEoCzIdLndwaS5wcm90by5Qcm90b2J1ZlJv" +
"dGF0aW9uMmRSBWFuZ2xlQhoKGGVkdS53cGkuZmlyc3QubWF0aC5wcm90b0qNDwoGEgQAAEQBCggKAQwS" +
"AwAAEgoICgECEgMCABIKCQoCAwASAwQAGgoICgEIEgMGADEKCQoCCAESAwYAMQoKCgIEABIECAAMAQoK" +
"CgMEAAESAwgIHQoLCgQEAAIAEgMJAhAKDAoFBAACAAUSAwkCCAoMCgUEAAIAARIDCQkLCgwKBQQAAgAD" +
"EgMJDg8KCwoEBAACARIDCgIQCgwKBQQAAgEFEgMKAggKDAoFBAACAQESAwoJCwoMCgUEAAIBAxIDCg4P" +
"CgsKBAQAAgISAwsCEwoMCgUEAAICBRIDCwIICgwKBQQAAgIBEgMLCQ4KDAoFBAACAgMSAwsREgoKCgIE" +
"ARIEDgAQAQoKCgMEAQESAw4IKwoLCgQEAQIAEgMPAhkKDAoFBAECAAUSAw8CCAoMCgUEAQIAARIDDwkU" +
"CgwKBQQBAgADEgMPFxgKCgoCBAISBBIAFQEKCgoDBAIBEgMSCCwKCwoEBAICABIDEwISCgwKBQQCAgAF" +
"EgMTAggKDAoFBAICAAESAxMJDQoMCgUEAgIAAxIDExARCgsKBAQCAgESAxQCEwoMCgUEAgIBBRIDFAII" +
"CgwKBQQCAgEBEgMUCQ4KDAoFBAICAQMSAxQREgoKCgIEAxIEFwAaAQoKCgMEAwESAxcILwoLCgQEAwIA" +
"EgMYAhIKDAoFBAMCAAUSAxgCCAoMCgUEAwIAARIDGAkNCgwKBQQDAgADEgMYEBEKCwoEBAMCARIDGQIT" +
"CgwKBQQDAgEFEgMZAggKDAoFBAMCAQESAxkJDgoMCgUEAwIBAxIDGRESCgoKAgQEEgQcACEBCgoKAwQE" +
"ARIDHAgmCgsKBAQEAgASAx0CJwoMCgUEBAIABhIDHQIXCgwKBQQEAgABEgMdGCIKDAoFBAQCAAMSAx0l" +
"JgoLCgQEBAIBEgMeAigKDAoFBAQCAQYSAx4CFwoMCgUEBAIBARIDHhgjCgwKBQQEAgEDEgMeJicKCwoE" +
"BAQCAhIDHwImCgwKBQQEAgIGEgMfAhcKDAoFBAQCAgESAx8YIQoMCgUEBAICAxIDHyQlCgsKBAQEAgMS" +
"AyACJwoMCgUEBAIDBhIDIAIXCgwKBQQEAgMBEgMgGCIKDAoFBAQCAwMSAyAlJgoKCgIEBRIEIwAoAQoK" +
"CgMEBQESAyMIKQoLCgQEBQIAEgMkAhgKDAoFBAUCAAUSAyQCCAoMCgUEBQIAARIDJAkTCgwKBQQFAgAD",
"EgMkFhcKCwoEBAUCARIDJQIZCgwKBQQFAgEFEgMlAggKDAoFBAUCAQESAyUJFAoMCgUEBQIBAxIDJRcY" +
"CgsKBAQFAgISAyYCFwoMCgUEBQICBRIDJgIICgwKBQQFAgIBEgMmCRIKDAoFBAUCAgMSAyYVFgoLCgQE" +
"BQIDEgMnAhgKDAoFBAUCAwUSAycCCAoMCgUEBQIDARIDJwkTCgwKBQQFAgMDEgMnFhcKCgoCBAYSBCoA" +
"LwEKCgoDBAYBEgMqCCoKCwoEBAYCABIDKwIYCgwKBQQGAgAFEgMrAggKDAoFBAYCAAESAysJEwoMCgUE" +
"BgIAAxIDKxYXCgsKBAQGAgESAywCGQoMCgUEBgIBBRIDLAIICgwKBQQGAgEBEgMsCRQKDAoFBAYCAQMS" +
"AywXGAoLCgQEBgICEgMtAhcKDAoFBAYCAgUSAy0CCAoMCgUEBgICARIDLQkSCgwKBQQGAgIDEgMtFRYK" +
"CwoEBAYCAxIDLgIYCgwKBQQGAgMFEgMuAggKDAoFBAYCAwESAy4JEwoMCgUEBgIDAxIDLhYXCgoKAgQH" +
"EgQxADYBCgoKAwQHARIDMQgnCgsKBAQHAgASAzICGAoMCgUEBwIABRIDMgIICgwKBQQHAgABEgMyCRMK" +
"DAoFBAcCAAMSAzIWFwoLCgQEBwIBEgMzAhkKDAoFBAcCAQUSAzMCCAoMCgUEBwIBARIDMwkUCgwKBQQH" +
"AgEDEgMzFxgKCwoEBAcCAhIDNAIXCgwKBQQHAgIFEgM0AggKDAoFBAcCAgESAzQJEgoMCgUEBwICAxID" +
"NBUWCgsKBAQHAgMSAzUCGAoMCgUEBwIDBRIDNQIICgwKBQQHAgMBEgM1CRMKDAoFBAcCAwMSAzUWFwoK" +
"CgIECBIEOAA6AQoKCgMECAESAzgIJQoLCgQECAIAEgM5Ai0KDAoFBAgCAAQSAzkCCgoMCgUECAIABhID" +
"OQsgCgwKBQQIAgABEgM5ISgKDAoFBAgCAAMSAzkrLAoKCgIECRIEPAA/AQoKCgMECQESAzwIJAoLCgQE" +
"CQIAEgM9AhYKDAoFBAkCAAUSAz0CCAoMCgUECQIAARIDPQkRCgwKBQQJAgADEgM9FBUKCwoEBAkCARID" +
"PgIfCgwKBQQJAgEGEgM+AhQKDAoFBAkCAQESAz4VGgoMCgUECQIBAxIDPh0eCgoKAgQKEgRBAEQBCgoK" +
"AwQKARIDQQghCgsKBAQKAgASA0ICEwoMCgUECgIABRIDQgIICgwKBQQKAgABEgNCCQ4KDAoFBAoCAAMS" +
"A0IREgoLCgQECgIBEgNDAh8KDAoFBAoCAQYSA0MCFAoMCgUECgIBARIDQxUaCgwKBQQKAgEDEgNDHR5i" +
"BnByb3RvMw==");
static final Descriptors.FileDescriptor descriptor = Descriptors.FileDescriptor.internalBuildGeneratedFileFrom("kinematics.proto", "wpi.proto", descriptorData, Geometry2D.getDescriptor());
@@ -83,19 +87,21 @@ public final class Kinematics {
static final Descriptors.Descriptor wpi_proto_ProtobufDifferentialDriveWheelSpeeds_descriptor = descriptor.internalContainedType(200, 80, "ProtobufDifferentialDriveWheelSpeeds", "wpi.proto.ProtobufDifferentialDriveWheelSpeeds");
static final Descriptors.Descriptor wpi_proto_ProtobufMecanumDriveKinematics_descriptor = descriptor.internalContainedType(283, 292, "ProtobufMecanumDriveKinematics", "wpi.proto.ProtobufMecanumDriveKinematics");
static final Descriptors.Descriptor wpi_proto_ProtobufDifferentialDriveWheelPositions_descriptor = descriptor.internalContainedType(282, 83, "ProtobufDifferentialDriveWheelPositions", "wpi.proto.ProtobufDifferentialDriveWheelPositions");
static final Descriptors.Descriptor wpi_proto_ProtobufMecanumDriveMotorVoltages_descriptor = descriptor.internalContainedType(578, 159, "ProtobufMecanumDriveMotorVoltages", "wpi.proto.ProtobufMecanumDriveMotorVoltages");
static final Descriptors.Descriptor wpi_proto_ProtobufMecanumDriveKinematics_descriptor = descriptor.internalContainedType(368, 292, "ProtobufMecanumDriveKinematics", "wpi.proto.ProtobufMecanumDriveKinematics");
static final Descriptors.Descriptor wpi_proto_ProtobufMecanumDriveWheelPositions_descriptor = descriptor.internalContainedType(740, 160, "ProtobufMecanumDriveWheelPositions", "wpi.proto.ProtobufMecanumDriveWheelPositions");
static final Descriptors.Descriptor wpi_proto_ProtobufMecanumDriveMotorVoltages_descriptor = descriptor.internalContainedType(663, 159, "ProtobufMecanumDriveMotorVoltages", "wpi.proto.ProtobufMecanumDriveMotorVoltages");
static final Descriptors.Descriptor wpi_proto_ProtobufMecanumDriveWheelSpeeds_descriptor = descriptor.internalContainedType(903, 157, "ProtobufMecanumDriveWheelSpeeds", "wpi.proto.ProtobufMecanumDriveWheelSpeeds");
static final Descriptors.Descriptor wpi_proto_ProtobufMecanumDriveWheelPositions_descriptor = descriptor.internalContainedType(825, 160, "ProtobufMecanumDriveWheelPositions", "wpi.proto.ProtobufMecanumDriveWheelPositions");
static final Descriptors.Descriptor wpi_proto_ProtobufSwerveDriveKinematics_descriptor = descriptor.internalContainedType(1062, 91, "ProtobufSwerveDriveKinematics", "wpi.proto.ProtobufSwerveDriveKinematics");
static final Descriptors.Descriptor wpi_proto_ProtobufMecanumDriveWheelSpeeds_descriptor = descriptor.internalContainedType(988, 157, "ProtobufMecanumDriveWheelSpeeds", "wpi.proto.ProtobufMecanumDriveWheelSpeeds");
static final Descriptors.Descriptor wpi_proto_ProtobufSwerveModulePosition_descriptor = descriptor.internalContainedType(1155, 111, "ProtobufSwerveModulePosition", "wpi.proto.ProtobufSwerveModulePosition");
static final Descriptors.Descriptor wpi_proto_ProtobufSwerveDriveKinematics_descriptor = descriptor.internalContainedType(1147, 91, "ProtobufSwerveDriveKinematics", "wpi.proto.ProtobufSwerveDriveKinematics");
static final Descriptors.Descriptor wpi_proto_ProtobufSwerveModuleState_descriptor = descriptor.internalContainedType(1268, 102, "ProtobufSwerveModuleState", "wpi.proto.ProtobufSwerveModuleState");
static final Descriptors.Descriptor wpi_proto_ProtobufSwerveModulePosition_descriptor = descriptor.internalContainedType(1240, 111, "ProtobufSwerveModulePosition", "wpi.proto.ProtobufSwerveModulePosition");
static final Descriptors.Descriptor wpi_proto_ProtobufSwerveModuleState_descriptor = descriptor.internalContainedType(1353, 102, "ProtobufSwerveModuleState", "wpi.proto.ProtobufSwerveModuleState");
/**
* @return this proto file's descriptor.
@@ -1113,6 +1119,344 @@ public final class Kinematics {
}
}
/**
* Protobuf type {@code ProtobufDifferentialDriveWheelPositions}
*/
public static final class ProtobufDifferentialDriveWheelPositions extends ProtoMessage<ProtobufDifferentialDriveWheelPositions> implements Cloneable {
private static final long serialVersionUID = 0L;
/**
* <code>optional double left = 1;</code>
*/
private double left;
/**
* <code>optional double right = 2;</code>
*/
private double right;
private ProtobufDifferentialDriveWheelPositions() {
}
/**
* @return a new empty instance of {@code ProtobufDifferentialDriveWheelPositions}
*/
public static ProtobufDifferentialDriveWheelPositions newInstance() {
return new ProtobufDifferentialDriveWheelPositions();
}
/**
* <code>optional double left = 1;</code>
* @return whether the left field is set
*/
public boolean hasLeft() {
return (bitField0_ & 0x00000001) != 0;
}
/**
* <code>optional double left = 1;</code>
* @return this
*/
public ProtobufDifferentialDriveWheelPositions clearLeft() {
bitField0_ &= ~0x00000001;
left = 0D;
return this;
}
/**
* <code>optional double left = 1;</code>
* @return the left
*/
public double getLeft() {
return left;
}
/**
* <code>optional double left = 1;</code>
* @param value the left to set
* @return this
*/
public ProtobufDifferentialDriveWheelPositions setLeft(final double value) {
bitField0_ |= 0x00000001;
left = value;
return this;
}
/**
* <code>optional double right = 2;</code>
* @return whether the right field is set
*/
public boolean hasRight() {
return (bitField0_ & 0x00000002) != 0;
}
/**
* <code>optional double right = 2;</code>
* @return this
*/
public ProtobufDifferentialDriveWheelPositions clearRight() {
bitField0_ &= ~0x00000002;
right = 0D;
return this;
}
/**
* <code>optional double right = 2;</code>
* @return the right
*/
public double getRight() {
return right;
}
/**
* <code>optional double right = 2;</code>
* @param value the right to set
* @return this
*/
public ProtobufDifferentialDriveWheelPositions setRight(final double value) {
bitField0_ |= 0x00000002;
right = value;
return this;
}
@Override
public ProtobufDifferentialDriveWheelPositions copyFrom(
final ProtobufDifferentialDriveWheelPositions other) {
cachedSize = other.cachedSize;
if ((bitField0_ | other.bitField0_) != 0) {
bitField0_ = other.bitField0_;
left = other.left;
right = other.right;
}
return this;
}
@Override
public ProtobufDifferentialDriveWheelPositions mergeFrom(
final ProtobufDifferentialDriveWheelPositions other) {
if (other.isEmpty()) {
return this;
}
cachedSize = -1;
if (other.hasLeft()) {
setLeft(other.left);
}
if (other.hasRight()) {
setRight(other.right);
}
return this;
}
@Override
public ProtobufDifferentialDriveWheelPositions clear() {
if (isEmpty()) {
return this;
}
cachedSize = -1;
bitField0_ = 0;
left = 0D;
right = 0D;
return this;
}
@Override
public ProtobufDifferentialDriveWheelPositions clearQuick() {
if (isEmpty()) {
return this;
}
cachedSize = -1;
bitField0_ = 0;
return this;
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof ProtobufDifferentialDriveWheelPositions)) {
return false;
}
ProtobufDifferentialDriveWheelPositions other = (ProtobufDifferentialDriveWheelPositions) o;
return bitField0_ == other.bitField0_
&& (!hasLeft() || ProtoUtil.isEqual(left, other.left))
&& (!hasRight() || ProtoUtil.isEqual(right, other.right));
}
@Override
public void writeTo(final ProtoSink output) throws IOException {
if ((bitField0_ & 0x00000001) != 0) {
output.writeRawByte((byte) 9);
output.writeDoubleNoTag(left);
}
if ((bitField0_ & 0x00000002) != 0) {
output.writeRawByte((byte) 17);
output.writeDoubleNoTag(right);
}
}
@Override
protected int computeSerializedSize() {
int size = 0;
if ((bitField0_ & 0x00000001) != 0) {
size += 9;
}
if ((bitField0_ & 0x00000002) != 0) {
size += 9;
}
return size;
}
@Override
@SuppressWarnings("fallthrough")
public ProtobufDifferentialDriveWheelPositions mergeFrom(final ProtoSource input) throws
IOException {
// Enabled Fall-Through Optimization (QuickBuffers)
int tag = input.readTag();
while (true) {
switch (tag) {
case 9: {
// left
left = input.readDouble();
bitField0_ |= 0x00000001;
tag = input.readTag();
if (tag != 17) {
break;
}
}
case 17: {
// right
right = input.readDouble();
bitField0_ |= 0x00000002;
tag = input.readTag();
if (tag != 0) {
break;
}
}
case 0: {
return this;
}
default: {
if (!input.skipField(tag)) {
return this;
}
tag = input.readTag();
break;
}
}
}
}
@Override
public void writeTo(final JsonSink output) throws IOException {
output.beginObject();
if ((bitField0_ & 0x00000001) != 0) {
output.writeDouble(FieldNames.left, left);
}
if ((bitField0_ & 0x00000002) != 0) {
output.writeDouble(FieldNames.right, right);
}
output.endObject();
}
@Override
public ProtobufDifferentialDriveWheelPositions mergeFrom(final JsonSource input) throws
IOException {
if (!input.beginObject()) {
return this;
}
while (!input.isAtEnd()) {
switch (input.readFieldHash()) {
case 3317767: {
if (input.isAtField(FieldNames.left)) {
if (!input.trySkipNullValue()) {
left = input.readDouble();
bitField0_ |= 0x00000001;
}
} else {
input.skipUnknownField();
}
break;
}
case 108511772: {
if (input.isAtField(FieldNames.right)) {
if (!input.trySkipNullValue()) {
right = input.readDouble();
bitField0_ |= 0x00000002;
}
} else {
input.skipUnknownField();
}
break;
}
default: {
input.skipUnknownField();
break;
}
}
}
input.endObject();
return this;
}
@Override
public ProtobufDifferentialDriveWheelPositions clone() {
return new ProtobufDifferentialDriveWheelPositions().copyFrom(this);
}
@Override
public boolean isEmpty() {
return ((bitField0_) == 0);
}
public static ProtobufDifferentialDriveWheelPositions parseFrom(final byte[] data) throws
InvalidProtocolBufferException {
return ProtoMessage.mergeFrom(new ProtobufDifferentialDriveWheelPositions(), data).checkInitialized();
}
public static ProtobufDifferentialDriveWheelPositions parseFrom(final ProtoSource input) throws
IOException {
return ProtoMessage.mergeFrom(new ProtobufDifferentialDriveWheelPositions(), input).checkInitialized();
}
public static ProtobufDifferentialDriveWheelPositions parseFrom(final JsonSource input) throws
IOException {
return ProtoMessage.mergeFrom(new ProtobufDifferentialDriveWheelPositions(), input).checkInitialized();
}
/**
* @return factory for creating ProtobufDifferentialDriveWheelPositions messages
*/
public static MessageFactory<ProtobufDifferentialDriveWheelPositions> getFactory() {
return ProtobufDifferentialDriveWheelPositionsFactory.INSTANCE;
}
/**
* @return this type's descriptor.
*/
public static Descriptors.Descriptor getDescriptor() {
return Kinematics.wpi_proto_ProtobufDifferentialDriveWheelPositions_descriptor;
}
private enum ProtobufDifferentialDriveWheelPositionsFactory implements MessageFactory<ProtobufDifferentialDriveWheelPositions> {
INSTANCE;
@Override
public ProtobufDifferentialDriveWheelPositions create() {
return ProtobufDifferentialDriveWheelPositions.newInstance();
}
}
/**
* Contains name constants used for serializing JSON
*/
static class FieldNames {
static final FieldName left = FieldName.forField("left");
static final FieldName right = FieldName.forField("right");
}
}
/**
* Protobuf type {@code ProtobufMecanumDriveKinematics}
*/

View File

@@ -7,6 +7,8 @@ package edu.wpi.first.math.kinematics;
import static edu.wpi.first.units.Units.Meters;
import edu.wpi.first.math.MathUtil;
import edu.wpi.first.math.kinematics.proto.DifferentialDriveWheelPositionsProto;
import edu.wpi.first.math.kinematics.struct.DifferentialDriveWheelPositionsStruct;
import edu.wpi.first.units.Distance;
import edu.wpi.first.units.Measure;
import java.util.Objects;
@@ -20,6 +22,14 @@ public class DifferentialDriveWheelPositions
/** Distance measured by the right side. */
public double rightMeters;
/** DifferentialDriveWheelPostions struct for serialization. */
public static final DifferentialDriveWheelPositionsStruct struct =
new DifferentialDriveWheelPositionsStruct();
/** DifferentialDriveWheelPostions struct for serialization. */
public static final DifferentialDriveWheelPositionsProto proto =
new DifferentialDriveWheelPositionsProto();
/**
* Constructs a DifferentialDriveWheelPositions.
*

View File

@@ -0,0 +1,40 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.math.kinematics.proto;
import edu.wpi.first.math.kinematics.DifferentialDriveWheelPositions;
import edu.wpi.first.math.proto.Kinematics.ProtobufDifferentialDriveWheelPositions;
import edu.wpi.first.util.protobuf.Protobuf;
import us.hebi.quickbuf.Descriptors.Descriptor;
public class DifferentialDriveWheelPositionsProto
implements Protobuf<DifferentialDriveWheelPositions, ProtobufDifferentialDriveWheelPositions> {
@Override
public Class<DifferentialDriveWheelPositions> getTypeClass() {
return DifferentialDriveWheelPositions.class;
}
@Override
public Descriptor getDescriptor() {
return ProtobufDifferentialDriveWheelPositions.getDescriptor();
}
@Override
public ProtobufDifferentialDriveWheelPositions createMessage() {
return ProtobufDifferentialDriveWheelPositions.newInstance();
}
@Override
public DifferentialDriveWheelPositions unpack(ProtobufDifferentialDriveWheelPositions msg) {
return new DifferentialDriveWheelPositions(msg.getLeft(), msg.getRight());
}
@Override
public void pack(
ProtobufDifferentialDriveWheelPositions msg, DifferentialDriveWheelPositions value) {
msg.setLeft(value.leftMeters);
msg.setRight(value.rightMeters);
}
}

View File

@@ -0,0 +1,45 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.math.kinematics.struct;
import edu.wpi.first.math.kinematics.DifferentialDriveWheelPositions;
import edu.wpi.first.util.struct.Struct;
import java.nio.ByteBuffer;
public class DifferentialDriveWheelPositionsStruct
implements Struct<DifferentialDriveWheelPositions> {
@Override
public Class<DifferentialDriveWheelPositions> getTypeClass() {
return DifferentialDriveWheelPositions.class;
}
@Override
public String getTypeString() {
return "struct:DifferentialDriveWheelPositions";
}
@Override
public int getSize() {
return kSizeDouble * 2;
}
@Override
public String getSchema() {
return "double left;double right";
}
@Override
public DifferentialDriveWheelPositions unpack(ByteBuffer bb) {
double left = bb.getDouble();
double right = bb.getDouble();
return new DifferentialDriveWheelPositions(left, right);
}
@Override
public void pack(ByteBuffer bb, DifferentialDriveWheelPositions value) {
bb.putDouble(value.leftMeters);
bb.putDouble(value.rightMeters);
}
}

View File

@@ -135,14 +135,14 @@ public final class LinearSystemId {
* <p>u = K_v v + K_a a
*
* @param kV The velocity gain, in volts/(unit/sec)
* @param kA The acceleration gain, in volts/(unit/sec^2)
* @param kA The acceleration gain, in volts/(unit/sec²)
* @return A LinearSystem representing the given characterized constants.
* @throws IllegalArgumentException if kV &lt;= 0 or kA &lt;= 0.
* @throws IllegalArgumentException if kV &lt; 0 or kA &lt;= 0.
* @see <a href="https://github.com/wpilibsuite/sysid">https://github.com/wpilibsuite/sysid</a>
*/
public static LinearSystem<N2, N1, N2> createDCMotorSystem(double kV, double kA) {
if (kV <= 0.0) {
throw new IllegalArgumentException("Kv must be greater than zero.");
if (kV < 0.0) {
throw new IllegalArgumentException("Kv must be greater than or equal to zero.");
}
if (kA <= 0.0) {
throw new IllegalArgumentException("Ka must be greater than zero.");
@@ -256,14 +256,14 @@ public final class LinearSystemId {
* <p>u = K_v v + K_a a
*
* @param kV The velocity gain, in volts/(unit/sec)
* @param kA The acceleration gain, in volts/(unit/sec^2)
* @param kA The acceleration gain, in volts/(unit/sec²)
* @return A LinearSystem representing the given characterized constants.
* @throws IllegalArgumentException if kV &lt;= 0 or kA &lt;= 0.
* @throws IllegalArgumentException if kV &lt; 0 or kA &lt;= 0.
* @see <a href="https://github.com/wpilibsuite/sysid">https://github.com/wpilibsuite/sysid</a>
*/
public static LinearSystem<N1, N1, N1> identifyVelocitySystem(double kV, double kA) {
if (kV <= 0.0) {
throw new IllegalArgumentException("Kv must be greater than zero.");
throw new IllegalArgumentException("Kv must be greater than or equal to zero.");
}
if (kA <= 0.0) {
throw new IllegalArgumentException("Ka must be greater than zero.");
@@ -291,12 +291,12 @@ public final class LinearSystemId {
* @param kV The velocity gain, in volts/(unit/sec)
* @param kA The acceleration gain, in volts/(unit/sec²)
* @return A LinearSystem representing the given characterized constants.
* @throws IllegalArgumentException if kV &lt;= 0 or kA &lt;= 0.
* @throws IllegalArgumentException if kV &lt; 0 or kA &lt;= 0.
* @see <a href="https://github.com/wpilibsuite/sysid">https://github.com/wpilibsuite/sysid</a>
*/
public static LinearSystem<N2, N1, N1> identifyPositionSystem(double kV, double kA) {
if (kV <= 0.0) {
throw new IllegalArgumentException("Kv must be greater than zero.");
throw new IllegalArgumentException("Kv must be greater than or equal to zero.");
}
if (kA <= 0.0) {
throw new IllegalArgumentException("Ka must be greater than zero.");

View File

@@ -0,0 +1,34 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include "frc/kinematics/proto/DifferentialDriveWheelPositionsProto.h"
#include "kinematics.pb.h"
google::protobuf::Message* wpi::Protobuf<
frc::DifferentialDriveWheelPositions>::New(google::protobuf::Arena* arena) {
return google::protobuf::Arena::CreateMessage<
wpi::proto::ProtobufDifferentialDriveWheelPositions>(arena);
}
frc::DifferentialDriveWheelPositions
wpi::Protobuf<frc::DifferentialDriveWheelPositions>::Unpack(
const google::protobuf::Message& msg) {
auto m =
static_cast<const wpi::proto::ProtobufDifferentialDriveWheelPositions*>(
&msg);
return frc::DifferentialDriveWheelPositions{
units::meter_t{m->left()},
units::meter_t{m->right()},
};
}
void wpi::Protobuf<frc::DifferentialDriveWheelPositions>::Pack(
google::protobuf::Message* msg,
const frc::DifferentialDriveWheelPositions& value) {
auto m =
static_cast<wpi::proto::ProtobufDifferentialDriveWheelPositions*>(msg);
m->set_left(value.left.value());
m->set_right(value.right.value());
}

View File

@@ -0,0 +1,26 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include "frc/kinematics/struct/DifferentialDriveWheelPositionsStruct.h"
namespace {
constexpr size_t kLeftOff = 0;
constexpr size_t kRightOff = kLeftOff + 8;
} // namespace
using StructType = wpi::Struct<frc::DifferentialDriveWheelPositions>;
frc::DifferentialDriveWheelPositions StructType::Unpack(
std::span<const uint8_t> data) {
return frc::DifferentialDriveWheelPositions{
units::meter_t{wpi::UnpackStruct<double, kLeftOff>(data)},
units::meter_t{wpi::UnpackStruct<double, kRightOff>(data)},
};
}
void StructType::Pack(std::span<uint8_t> data,
const frc::DifferentialDriveWheelPositions& value) {
wpi::PackStruct<kLeftOff>(data, value.left.value());
wpi::PackStruct<kRightOff>(data, value.right.value());
}

View File

@@ -49,3 +49,6 @@ struct WPILIB_DLLEXPORT DifferentialDriveWheelPositions {
}
};
} // namespace frc
#include "frc/kinematics/proto/DifferentialDriveWheelPositionsProto.h"
#include "frc/kinematics/struct/DifferentialDriveWheelPositionsStruct.h"

View File

@@ -0,0 +1,19 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <wpi/SymbolExports.h>
#include <wpi/protobuf/Protobuf.h>
#include "frc/kinematics/DifferentialDriveWheelPositions.h"
template <>
struct WPILIB_DLLEXPORT wpi::Protobuf<frc::DifferentialDriveWheelPositions> {
static google::protobuf::Message* New(google::protobuf::Arena* arena);
static frc::DifferentialDriveWheelPositions Unpack(
const google::protobuf::Message& msg);
static void Pack(google::protobuf::Message* msg,
const frc::DifferentialDriveWheelPositions& value);
};

View File

@@ -0,0 +1,28 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#pragma once
#include <wpi/SymbolExports.h>
#include <wpi/struct/Struct.h>
#include "frc/kinematics/DifferentialDriveWheelPositions.h"
template <>
struct WPILIB_DLLEXPORT wpi::Struct<frc::DifferentialDriveWheelPositions> {
static constexpr std::string_view GetTypeString() {
return "struct:DifferentialDriveWheelPositions";
}
static constexpr size_t GetSize() { return 16; }
static constexpr std::string_view GetSchema() {
return "double left;double right";
}
static frc::DifferentialDriveWheelPositions Unpack(
std::span<const uint8_t> data);
static void Pack(std::span<uint8_t> data,
const frc::DifferentialDriveWheelPositions& value);
};
static_assert(wpi::StructSerializable<frc::DifferentialDriveWheelPositions>);

View File

@@ -79,7 +79,7 @@ class WPILIB_DLLEXPORT LinearSystemId {
*
* @param kV The velocity gain, in volts/(unit/sec).
* @param kA The acceleration gain, in volts/(unit/sec²).
* @throws std::domain_error if kV <= 0 or kA <= 0.
* @throws std::domain_error if kV < 0 or kA <= 0.
* @see <a
* href="https://github.com/wpilibsuite/sysid">https://github.com/wpilibsuite/sysid</a>
*/
@@ -89,8 +89,8 @@ class WPILIB_DLLEXPORT LinearSystemId {
static LinearSystem<1, 1, 1> IdentifyVelocitySystem(
decltype(1_V / Velocity_t<Distance>(1)) kV,
decltype(1_V / Acceleration_t<Distance>(1)) kA) {
if (kV <= decltype(kV){0}) {
throw std::domain_error("Kv must be greater than zero.");
if (kV < decltype(kV){0}) {
throw std::domain_error("Kv must be greater than or equal to zero.");
}
if (kA <= decltype(kA){0}) {
throw std::domain_error("Ka must be greater than zero.");
@@ -122,7 +122,7 @@ class WPILIB_DLLEXPORT LinearSystemId {
* @param kV The velocity gain, in volts/(unit/sec).
* @param kA The acceleration gain, in volts/(unit/sec²).
*
* @throws std::domain_error if kV <= 0 or kA <= 0.
* @throws std::domain_error if kV < 0 or kA <= 0.
* @see <a
* href="https://github.com/wpilibsuite/sysid">https://github.com/wpilibsuite/sysid</a>
*/
@@ -132,8 +132,8 @@ class WPILIB_DLLEXPORT LinearSystemId {
static LinearSystem<2, 1, 1> IdentifyPositionSystem(
decltype(1_V / Velocity_t<Distance>(1)) kV,
decltype(1_V / Acceleration_t<Distance>(1)) kA) {
if (kV <= decltype(kV){0}) {
throw std::domain_error("Kv must be greater than zero.");
if (kV < decltype(kV){0}) {
throw std::domain_error("Kv must be greater than or equal to zero.");
}
if (kA <= decltype(kA){0}) {
throw std::domain_error("Ka must be greater than zero.");
@@ -251,7 +251,7 @@ class WPILIB_DLLEXPORT LinearSystemId {
* @param kV The velocity gain, in volts/(unit/sec).
* @param kA The acceleration gain, in volts/(unit/sec²).
*
* @throws std::domain_error if kV <= 0 or kA <= 0.
* @throws std::domain_error if kV < 0 or kA <= 0.
*/
template <typename Distance>
requires std::same_as<units::meter, Distance> ||
@@ -259,8 +259,8 @@ class WPILIB_DLLEXPORT LinearSystemId {
static LinearSystem<2, 1, 2> DCMotorSystem(
decltype(1_V / Velocity_t<Distance>(1)) kV,
decltype(1_V / Acceleration_t<Distance>(1)) kA) {
if (kV <= decltype(kV){0}) {
throw std::domain_error("Kv must be greater than zero.");
if (kV < decltype(kV){0}) {
throw std::domain_error("Kv must be greater than or equal to zero.");
}
if (kA <= decltype(kA){0}) {
throw std::domain_error("Ka must be greater than zero.");

View File

@@ -21,6 +21,11 @@ message ProtobufDifferentialDriveWheelSpeeds {
double right = 2;
}
message ProtobufDifferentialDriveWheelPositions {
double left = 1;
double right = 2;
}
message ProtobufMecanumDriveKinematics {
ProtobufTranslation2d front_left = 1;
ProtobufTranslation2d front_right = 2;

View File

@@ -0,0 +1,29 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
package edu.wpi.first.math.kinematics.struct;
import static org.junit.jupiter.api.Assertions.assertEquals;
import edu.wpi.first.math.kinematics.DifferentialDriveWheelPositions;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import org.junit.jupiter.api.Test;
class DifferentialDriveWheelPositionsStructTest {
private static final DifferentialDriveWheelPositions DATA =
new DifferentialDriveWheelPositions(1.74, 35.04);
@Test
void testRoundtrip() {
ByteBuffer buffer = ByteBuffer.allocate(DifferentialDriveWheelPositions.struct.getSize());
buffer.order(ByteOrder.LITTLE_ENDIAN);
DifferentialDriveWheelPositions.struct.pack(buffer, DATA);
buffer.rewind();
DifferentialDriveWheelPositions data = DifferentialDriveWheelPositions.struct.unpack(buffer);
assertEquals(DATA.leftMeters, data.leftMeters);
assertEquals(DATA.rightMeters, data.rightMeters);
}
}

View File

@@ -0,0 +1,27 @@
// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include <gtest/gtest.h>
#include "frc/kinematics/DifferentialDriveWheelPositions.h"
using namespace frc;
namespace {
using StructType = wpi::Struct<frc::DifferentialDriveWheelPositions>;
const DifferentialDriveWheelPositions kExpectedData{
DifferentialDriveWheelPositions{1.74_m, 35.04_m}};
} // namespace
TEST(DifferentialDriveWheelPositionsStructTest, Roundtrip) {
uint8_t buffer[StructType::GetSize()];
std::memset(buffer, 0, StructType::GetSize());
StructType::Pack(buffer, kExpectedData);
DifferentialDriveWheelPositions unpacked_data = StructType::Unpack(buffer);
EXPECT_EQ(kExpectedData.left.value(), unpacked_data.left.value());
EXPECT_EQ(kExpectedData.right.value(), unpacked_data.right.value());
}

View File

@@ -5,10 +5,10 @@
package edu.wpi.first.units;
/**
* Unit of angular dimension.
* Unit of linear dimension.
*
* <p>This is the base type for units of distance dimension. It is also used to specify the
* dimension for {@link Measure}: <code>Measure&lt;Distance&gt;</code>.
* <p>This is the base type for units of linear dimension. It is also used to specify the dimension
* for {@link Measure}: <code>Measure&lt;Distance&gt;</code>.
*
* <p>Actual units (such as {@link Units#Meters} and {@link Units#Inches}) can be found in the
* {@link Units} class.

View File

@@ -273,10 +273,14 @@ uint64_t wpi::Now() {
if (nowUseDefaultOnFailure.test()) {
return timestamp() - offset_val;
} else {
fmt::print(
stderr,
"FPGA not yet configured in wpi::Now(). Time will not be correct.\n");
fmt::print(stderr,
"FPGA not yet configured in wpi::Now(). This is a fatal "
"error. The process is being terminated.\n");
std::fflush(stderr);
// Attempt to force a segfault to get a better java log
*reinterpret_cast<int*>(0) = 0;
// If that fails, terminate
std::terminate();
return 1;
}
}