[wpilib] Deprecate Accelerometer and Gyro interfaces (#5445)

Accelerometer is hyper-specific to ADXL accelerometers, and Gyro is
less useful now that 3D IMUs are prevalent, and if those IMUs want to
support the Gyro interface, they also need to provide a way to set the
axis used for the Gyro interface, which is confusing. Higher-order
functions (e.g., lambdas) are a more flexible interface boundary than
interfaces, but they didn't exist when these interfaces were
created.
This commit is contained in:
Tyler Veness
2023-07-18 12:52:43 -07:00
committed by GitHub
parent 70b60e3a74
commit 14f30752ab
32 changed files with 426 additions and 152 deletions

View File

@@ -93,7 +93,6 @@ void ADXL362::SetRange(Range range) {
m_gsPerLSB = 0.002;
break;
case kRange_8G:
case kRange_16G: // 16G not supported; treat as 8G
m_gsPerLSB = 0.004;
break;
}

View File

@@ -140,6 +140,10 @@ void ADXRS450_Gyro::Calibrate() {
m_spi.ResetAccumulator();
}
Rotation2d ADXRS450_Gyro::GetRotation2d() const {
return units::degree_t{-GetAngle()};
}
int ADXRS450_Gyro::GetPort() const {
return m_port;
}

View File

@@ -133,6 +133,10 @@ void AnalogGyro::Calibrate() {
FRC_CheckErrorStatus(status, "Channel {}", m_analog->GetChannel());
}
Rotation2d AnalogGyro::GetRotation2d() const {
return units::degree_t{-GetAngle()};
}
std::shared_ptr<AnalogInput> AnalogGyro::GetAnalogInput() const {
return m_analog;
}

View File

@@ -22,11 +22,6 @@ BuiltInAccelerometer::BuiltInAccelerometer(Range range) {
}
void BuiltInAccelerometer::SetRange(Range range) {
if (range == kRange_16G) {
throw FRC_MakeError(err::ParameterOutOfRange,
"16G range not supported (use k2G, k4G, or k8G)");
}
HAL_SetAccelerometerActive(false);
HAL_SetAccelerometerRange(static_cast<HAL_AccelerometerRange>(range));
HAL_SetAccelerometerActive(true);

View File

@@ -9,7 +9,6 @@
#include <wpi/sendable/SendableHelper.h>
#include "frc/I2C.h"
#include "frc/interfaces/Accelerometer.h"
namespace frc {
@@ -24,10 +23,11 @@ namespace frc {
* href="https://docs.wpilib.org/en/stable/docs/yearly-overview/known-issues.html#onboard-i2c-causing-system-lockups">
* WPILib Known Issues</a> page for details.
*/
class ADXL345_I2C : public Accelerometer,
public nt::NTSendable,
class ADXL345_I2C : public nt::NTSendable,
public wpi::SendableHelper<ADXL345_I2C> {
public:
enum Range { kRange_2G = 0, kRange_4G = 1, kRange_8G = 2, kRange_16G = 3 };
enum Axes { kAxis_X = 0x00, kAxis_Y = 0x02, kAxis_Z = 0x04 };
struct AllAxes {
@@ -53,11 +53,34 @@ class ADXL345_I2C : public Accelerometer,
I2C::Port GetI2CPort() const;
int GetI2CDeviceAddress() const;
// Accelerometer interface
void SetRange(Range range) final;
double GetX() override;
double GetY() override;
double GetZ() override;
/**
* Set the measuring range of the accelerometer.
*
* @param range The maximum acceleration, positive or negative, that the
* accelerometer will measure.
*/
void SetRange(Range range);
/**
* Returns the acceleration along the X axis in g-forces.
*
* @return The acceleration along the X axis in g-forces.
*/
double GetX();
/**
* Returns the acceleration along the Y axis in g-forces.
*
* @return The acceleration along the Y axis in g-forces.
*/
double GetY();
/**
* Returns the acceleration along the Z axis in g-forces.
*
* @return The acceleration along the Z axis in g-forces.
*/
double GetZ();
/**
* Get the acceleration of one axis in Gs.

View File

@@ -9,7 +9,6 @@
#include <wpi/sendable/SendableHelper.h>
#include "frc/SPI.h"
#include "frc/interfaces/Accelerometer.h"
namespace frc {
@@ -19,10 +18,11 @@ namespace frc {
* This class allows access to an Analog Devices ADXL345 3-axis accelerometer
* via SPI. This class assumes the sensor is wired in 4-wire SPI mode.
*/
class ADXL345_SPI : public Accelerometer,
public nt::NTSendable,
class ADXL345_SPI : public nt::NTSendable,
public wpi::SendableHelper<ADXL345_SPI> {
public:
enum Range { kRange_2G = 0, kRange_4G = 1, kRange_8G = 2, kRange_16G = 3 };
enum Axes { kAxis_X = 0x00, kAxis_Y = 0x02, kAxis_Z = 0x04 };
struct AllAxes {
@@ -46,11 +46,34 @@ class ADXL345_SPI : public Accelerometer,
SPI::Port GetSpiPort() const;
// Accelerometer interface
void SetRange(Range range) final;
double GetX() override;
double GetY() override;
double GetZ() override;
/**
* Set the measuring range of the accelerometer.
*
* @param range The maximum acceleration, positive or negative, that the
* accelerometer will measure.
*/
void SetRange(Range range);
/**
* Returns the acceleration along the X axis in g-forces.
*
* @return The acceleration along the X axis in g-forces.
*/
double GetX();
/**
* Returns the acceleration along the Y axis in g-forces.
*
* @return The acceleration along the Y axis in g-forces.
*/
double GetY();
/**
* Returns the acceleration along the Z axis in g-forces.
*
* @return The acceleration along the Z axis in g-forces.
*/
double GetZ();
/**
* Get the acceleration of one axis in Gs.

View File

@@ -9,7 +9,6 @@
#include <wpi/sendable/SendableHelper.h>
#include "frc/SPI.h"
#include "frc/interfaces/Accelerometer.h"
namespace frc {
@@ -18,10 +17,10 @@ namespace frc {
*
* This class allows access to an Analog Devices ADXL362 3-axis accelerometer.
*/
class ADXL362 : public Accelerometer,
public nt::NTSendable,
public wpi::SendableHelper<ADXL362> {
class ADXL362 : public nt::NTSendable, public wpi::SendableHelper<ADXL362> {
public:
enum Range { kRange_2G = 0, kRange_4G = 1, kRange_8G = 2 };
enum Axes { kAxis_X = 0x00, kAxis_Y = 0x02, kAxis_Z = 0x04 };
struct AllAxes {
double XAxis;
@@ -52,11 +51,34 @@ class ADXL362 : public Accelerometer,
SPI::Port GetSpiPort() const;
// Accelerometer interface
void SetRange(Range range) final;
double GetX() override;
double GetY() override;
double GetZ() override;
/**
* Set the measuring range of the accelerometer.
*
* @param range The maximum acceleration, positive or negative, that the
* accelerometer will measure.
*/
void SetRange(Range range);
/**
* Returns the acceleration along the X axis in g-forces.
*
* @return The acceleration along the X axis in g-forces.
*/
double GetX();
/**
* Returns the acceleration along the Y axis in g-forces.
*
* @return The acceleration along the Y axis in g-forces.
*/
double GetY();
/**
* Returns the acceleration along the Z axis in g-forces.
*
* @return The acceleration along the Z axis in g-forces.
*/
double GetZ();
/**
* Get the acceleration of one axis in Gs.

View File

@@ -11,7 +11,7 @@
#include <wpi/sendable/SendableHelper.h>
#include "frc/SPI.h"
#include "frc/interfaces/Gyro.h"
#include "frc/geometry/Rotation2d.h"
namespace frc {
@@ -28,8 +28,7 @@ namespace frc {
* This class is for the digital ADXRS450 gyro sensor that connects via SPI.
* Only one instance of an ADXRS %Gyro is supported.
*/
class ADXRS450_Gyro : public Gyro,
public wpi::Sendable,
class ADXRS450_Gyro : public wpi::Sendable,
public wpi::SendableHelper<ADXRS450_Gyro> {
public:
/**
@@ -61,7 +60,7 @@ class ADXRS450_Gyro : public Gyro,
*
* @return the current heading of the robot in degrees.
*/
double GetAngle() const override;
double GetAngle() const;
/**
* Return the rate of rotation of the gyro
@@ -70,7 +69,7 @@ class ADXRS450_Gyro : public Gyro,
*
* @return the current rate in degrees per second
*/
double GetRate() const override;
double GetRate() const;
/**
* Reset the gyro.
@@ -79,11 +78,9 @@ class ADXRS450_Gyro : public Gyro,
* significant drift in the gyro and it needs to be recalibrated after it has
* been running.
*/
void Reset() override;
void Reset();
/**
* Initialize the gyro.
*
* Calibrate the gyro by running for a number of samples and computing the
* center value. Then use the center value as the Accumulator center value for
* subsequent measurements.
@@ -93,7 +90,22 @@ class ADXRS450_Gyro : public Gyro,
* robot is first turned on while it's sitting at rest before the competition
* starts.
*/
void Calibrate() final;
void Calibrate();
/**
* Return the heading of the robot as a Rotation2d.
*
* The angle is continuous, that is it will continue from 360 to 361 degrees.
* This allows algorithms that wouldn't want to see a discontinuity in the
* gyro output as it sweeps past from 360 to 0 on the second time around.
*
* The angle is expected to increase as the gyro turns counterclockwise when
* looked at from the top. It needs to follow the NWU axis convention.
*
* @return the current heading of the robot as a Rotation2d. This heading is
* based on integration of the returned rate from the gyro.
*/
Rotation2d GetRotation2d() const;
/**
* Get the SPI port number.

View File

@@ -10,7 +10,7 @@
#include <wpi/sendable/Sendable.h>
#include <wpi/sendable/SendableHelper.h>
#include "frc/interfaces/Gyro.h"
#include "frc/geometry/Rotation2d.h"
namespace frc {
@@ -29,8 +29,7 @@ class AnalogInput;
*
* This class is for gyro sensors that connect to an analog input.
*/
class AnalogGyro : public Gyro,
public wpi::Sendable,
class AnalogGyro : public wpi::Sendable,
public wpi::SendableHelper<AnalogGyro> {
public:
static constexpr int kOversampleBits = 10;
@@ -118,7 +117,7 @@ class AnalogGyro : public Gyro,
* @return The current heading of the robot in degrees. This heading is based
* on integration of the returned rate from the gyro.
*/
double GetAngle() const override;
double GetAngle() const;
/**
* Return the rate of rotation of the gyro
@@ -127,7 +126,7 @@ class AnalogGyro : public Gyro,
*
* @return the current rate in degrees per second
*/
double GetRate() const override;
double GetRate() const;
/**
* Return the gyro center value. If run after calibration,
@@ -174,7 +173,7 @@ class AnalogGyro : public Gyro,
* significant drift in the gyro and it needs to be recalibrated after it has
* been running.
*/
void Reset() final;
void Reset();
/**
* Initialize the gyro.
@@ -183,7 +182,32 @@ class AnalogGyro : public Gyro,
*/
void InitGyro();
void Calibrate() final;
/**
* Calibrate the gyro by running for a number of samples and computing the
* center value. Then use the center value as the Accumulator center value for
* subsequent measurements.
*
* It's important to make sure that the robot is not moving while the
* centering calculations are in progress, this is typically done when the
* robot is first turned on while it's sitting at rest before the competition
* starts.
*/
void Calibrate();
/**
* Return the heading of the robot as a Rotation2d.
*
* The angle is continuous, that is it will continue from 360 to 361 degrees.
* This allows algorithms that wouldn't want to see a discontinuity in the
* gyro output as it sweeps past from 360 to 0 on the second time around.
*
* The angle is expected to increase as the gyro turns counterclockwise when
* looked at from the top. It needs to follow the NWU axis convention.
*
* @return the current heading of the robot as a Rotation2d. This heading is
* based on integration of the returned rate from the gyro.
*/
Rotation2d GetRotation2d() const;
/**
* Gets the analog input for the gyro.

View File

@@ -7,8 +7,6 @@
#include <wpi/sendable/Sendable.h>
#include <wpi/sendable/SendableHelper.h>
#include "frc/interfaces/Accelerometer.h"
namespace frc {
/**
@@ -16,10 +14,11 @@ namespace frc {
*
* This class allows access to the roboRIO's internal accelerometer.
*/
class BuiltInAccelerometer : public Accelerometer,
public wpi::Sendable,
class BuiltInAccelerometer : public wpi::Sendable,
public wpi::SendableHelper<BuiltInAccelerometer> {
public:
enum Range { kRange_2G = 0, kRange_4G = 1, kRange_8G = 2 };
/**
* Constructor.
*
@@ -30,30 +29,28 @@ class BuiltInAccelerometer : public Accelerometer,
BuiltInAccelerometer(BuiltInAccelerometer&&) = default;
BuiltInAccelerometer& operator=(BuiltInAccelerometer&&) = default;
// Accelerometer interface
/**
* Set the measuring range of the accelerometer.
*
* @param range The maximum acceleration, positive or negative, that the
* accelerometer will measure. Not all accelerometers support all
* ranges.
* accelerometer will measure.
*/
void SetRange(Range range) final;
void SetRange(Range range);
/**
* @return The acceleration of the roboRIO along the X axis in g-forces
*/
double GetX() override;
double GetX();
/**
* @return The acceleration of the roboRIO along the Y axis in g-forces
*/
double GetY() override;
double GetY();
/**
* @return The acceleration of the roboRIO along the Z axis in g-forces
*/
double GetZ() override;
double GetZ();
void InitSendable(wpi::SendableBuilder& builder) override;
};

View File

@@ -8,8 +8,11 @@ namespace frc {
/**
* Interface for 3-axis accelerometers.
*
* @deprecated This interface is being removed with no replacement.
*/
class Accelerometer {
class [[deprecated(
"This interface is being removed with no replacement.")]] Accelerometer {
public:
Accelerometer() = default;
virtual ~Accelerometer() = default;

View File

@@ -12,8 +12,11 @@ namespace frc {
/**
* Interface for yaw rate gyros.
*
* @deprecated This interface is being removed with no replacement.
*/
class Gyro {
class [[deprecated(
"This interface is being removed with no replacement.")]] Gyro {
public:
Gyro() = default;
virtual ~Gyro() = default;

View File

@@ -15,7 +15,7 @@ namespace frc::sim {
TEST(ADXL345SimTest, SetSpiAttributes) {
HAL_Initialize(500, 0);
ADXL345_SPI accel(SPI::kMXP, Accelerometer::kRange_2G);
ADXL345_SPI accel(SPI::kMXP, ADXL345_SPI::kRange_2G);
ADXL345Sim sim(accel);
EXPECT_EQ(0, accel.GetX());

View File

@@ -14,7 +14,7 @@ namespace frc::sim {
TEST(ADXL362SimTest, SetAttributes) {
HAL_Initialize(500, 0);
ADXL362 accel(SPI::kMXP, Accelerometer::kRange_2G);
ADXL362 accel(SPI::kMXP, ADXL362::kRange_2G);
ADXL362Sim sim(accel);
EXPECT_EQ(0, accel.GetX());

View File

@@ -99,7 +99,7 @@ TEST(AcclerometerSimTest, SetRange) {
EnumCallback callback;
Accelerometer::Range range = Accelerometer::kRange_4G;
BuiltInAccelerometer::Range range = BuiltInAccelerometer::kRange_4G;
auto cb = sim.RegisterRangeCallback(callback.GetCallback(), false);
BuiltInAccelerometer accel(range);
EXPECT_TRUE(callback.WasTriggered());
@@ -108,7 +108,7 @@ TEST(AcclerometerSimTest, SetRange) {
// 2G
callback.Reset();
range = Accelerometer::kRange_2G;
range = BuiltInAccelerometer::kRange_2G;
accel.SetRange(range);
EXPECT_TRUE(callback.WasTriggered());
EXPECT_EQ(static_cast<int>(range), sim.GetRange());
@@ -116,7 +116,7 @@ TEST(AcclerometerSimTest, SetRange) {
// 4G
callback.Reset();
range = Accelerometer::kRange_4G;
range = BuiltInAccelerometer::kRange_4G;
accel.SetRange(range);
EXPECT_TRUE(callback.WasTriggered());
EXPECT_EQ(static_cast<int>(range), sim.GetRange());
@@ -124,15 +124,10 @@ TEST(AcclerometerSimTest, SetRange) {
// 8G
callback.Reset();
range = Accelerometer::kRange_8G;
range = BuiltInAccelerometer::kRange_8G;
accel.SetRange(range);
EXPECT_TRUE(callback.WasTriggered());
EXPECT_EQ(static_cast<int>(range), sim.GetRange());
EXPECT_EQ(static_cast<int>(range), callback.GetLastValue());
// 16G - Not supported
callback.Reset();
EXPECT_THROW(accel.SetRange(Accelerometer::kRange_16G), std::runtime_error);
EXPECT_FALSE(callback.WasTriggered());
}
} // namespace frc::sim

View File

@@ -15,7 +15,6 @@ import edu.wpi.first.networktables.DoubleTopic;
import edu.wpi.first.networktables.NTSendable;
import edu.wpi.first.networktables.NTSendableBuilder;
import edu.wpi.first.util.sendable.SendableRegistry;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -27,7 +26,7 @@ import java.nio.ByteOrder;
* WPILib Known Issues</a> page for details.
*/
@SuppressWarnings({"TypeName", "PMD.UnusedPrivateField"})
public class ADXL345_I2C implements Accelerometer, NTSendable, AutoCloseable {
public class ADXL345_I2C implements NTSendable, AutoCloseable {
private static final byte kAddress = 0x1D;
private static final byte kPowerCtlRegister = 0x2D;
private static final byte kDataFormatRegister = 0x31;
@@ -44,6 +43,13 @@ public class ADXL345_I2C implements Accelerometer, NTSendable, AutoCloseable {
private static final byte kDataFormat_FullRes = 0x08;
private static final byte kDataFormat_Justify = 0x04;
public enum Range {
k2G,
k4G,
k8G,
k16G
}
public enum Axes {
kX((byte) 0x00),
kY((byte) 0x02),
@@ -137,10 +143,14 @@ public class ADXL345_I2C implements Accelerometer, NTSendable, AutoCloseable {
}
}
@Override
/**
* Set the measuring range of the accelerometer.
*
* @param range The maximum acceleration, positive or negative, that the accelerometer will
* measure.
*/
public void setRange(Range range) {
final byte value;
switch (range) {
case k2G:
value = 0;
@@ -155,7 +165,7 @@ public class ADXL345_I2C implements Accelerometer, NTSendable, AutoCloseable {
value = 3;
break;
default:
throw new IllegalArgumentException(range + " unsupported range type");
throw new IllegalArgumentException("Missing case for range type " + range);
}
// Specify the data format to read
@@ -166,17 +176,29 @@ public class ADXL345_I2C implements Accelerometer, NTSendable, AutoCloseable {
}
}
@Override
/**
* Returns the acceleration along the X axis in g-forces.
*
* @return The acceleration along the X axis in g-forces.
*/
public double getX() {
return getAcceleration(Axes.kX);
}
@Override
/**
* Returns the acceleration along the Y axis in g-forces.
*
* @return The acceleration along the Y axis in g-forces.
*/
public double getY() {
return getAcceleration(Axes.kY);
}
@Override
/**
* Returns the acceleration along the Z axis in g-forces.
*
* @return The acceleration along the Z axis in g-forces.
*/
public double getZ() {
return getAcceleration(Axes.kZ);
}

View File

@@ -15,13 +15,12 @@ import edu.wpi.first.networktables.DoubleTopic;
import edu.wpi.first.networktables.NTSendable;
import edu.wpi.first.networktables.NTSendableBuilder;
import edu.wpi.first.util.sendable.SendableRegistry;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/** ADXL345 SPI Accelerometer. */
@SuppressWarnings({"TypeName", "PMD.UnusedPrivateField"})
public class ADXL345_SPI implements Accelerometer, NTSendable, AutoCloseable {
public class ADXL345_SPI implements NTSendable, AutoCloseable {
private static final int kPowerCtlRegister = 0x2D;
private static final int kDataFormatRegister = 0x31;
private static final int kDataRegister = 0x32;
@@ -41,6 +40,13 @@ public class ADXL345_SPI implements Accelerometer, NTSendable, AutoCloseable {
private static final int kDataFormat_FullRes = 0x08;
private static final int kDataFormat_Justify = 0x04;
public enum Range {
k2G,
k4G,
k8G,
k16G
}
public enum Axes {
kX((byte) 0x00),
kY((byte) 0x02),
@@ -133,10 +139,14 @@ public class ADXL345_SPI implements Accelerometer, NTSendable, AutoCloseable {
HAL.report(tResourceType.kResourceType_ADXL345, tInstances.kADXL345_SPI);
}
@Override
/**
* Set the measuring range of the accelerometer.
*
* @param range The maximum acceleration, positive or negative, that the accelerometer will
* measure.
*/
public void setRange(Range range) {
final byte value;
switch (range) {
case k2G:
value = 0;
@@ -151,7 +161,7 @@ public class ADXL345_SPI implements Accelerometer, NTSendable, AutoCloseable {
value = 3;
break;
default:
throw new IllegalArgumentException(range + " unsupported");
throw new IllegalArgumentException("Missing case for range type " + range);
}
// Specify the data format to read
@@ -163,17 +173,29 @@ public class ADXL345_SPI implements Accelerometer, NTSendable, AutoCloseable {
}
}
@Override
/**
* Returns the acceleration along the X axis in g-forces.
*
* @return The acceleration along the X axis in g-forces.
*/
public double getX() {
return getAcceleration(Axes.kX);
}
@Override
/**
* Returns the acceleration along the Y axis in g-forces.
*
* @return The acceleration along the Y axis in g-forces.
*/
public double getY() {
return getAcceleration(Axes.kY);
}
@Override
/**
* Returns the acceleration along the Z axis in g-forces.
*
* @return The acceleration along the Z axis in g-forces.
*/
public double getZ() {
return getAcceleration(Axes.kZ);
}

View File

@@ -14,7 +14,6 @@ import edu.wpi.first.networktables.DoubleTopic;
import edu.wpi.first.networktables.NTSendable;
import edu.wpi.first.networktables.NTSendableBuilder;
import edu.wpi.first.util.sendable.SendableRegistry;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -23,7 +22,7 @@ import java.nio.ByteOrder;
*
* <p>This class allows access to an Analog Devices ADXL362 3-axis accelerometer.
*/
public class ADXL362 implements Accelerometer, NTSendable, AutoCloseable {
public class ADXL362 implements NTSendable, AutoCloseable {
private static final byte kRegWrite = 0x0A;
private static final byte kRegRead = 0x0B;
@@ -44,6 +43,12 @@ public class ADXL362 implements Accelerometer, NTSendable, AutoCloseable {
private static final byte kPowerCtl_Measure = 0x02;
public enum Range {
k2G,
k4G,
k8G
}
public enum Axes {
kX((byte) 0x00),
kY((byte) 0x02),
@@ -153,7 +158,12 @@ public class ADXL362 implements Accelerometer, NTSendable, AutoCloseable {
}
}
@Override
/**
* Set the measuring range of the accelerometer.
*
* @param range The maximum acceleration, positive or negative, that the accelerometer will
* measure.
*/
public void setRange(Range range) {
if (m_spi == null) {
return;
@@ -170,12 +180,11 @@ public class ADXL362 implements Accelerometer, NTSendable, AutoCloseable {
m_gsPerLSB = 0.002;
break;
case k8G:
case k16G: // 16G not supported; treat as 8G
value = kFilterCtl_Range8G;
m_gsPerLSB = 0.004;
break;
default:
throw new IllegalArgumentException(range + " unsupported");
throw new IllegalArgumentException("Missing case for range type " + range);
}
// Specify the data format to read
@@ -188,17 +197,29 @@ public class ADXL362 implements Accelerometer, NTSendable, AutoCloseable {
}
}
@Override
/**
* Returns the acceleration along the X axis in g-forces.
*
* @return The acceleration along the X axis in g-forces.
*/
public double getX() {
return getAcceleration(Axes.kX);
}
@Override
/**
* Returns the acceleration along the Y axis in g-forces.
*
* @return The acceleration along the Y axis in g-forces.
*/
public double getY() {
return getAcceleration(Axes.kY);
}
@Override
/**
* Returns the acceleration along the Z axis in g-forces.
*
* @return The acceleration along the Z axis in g-forces.
*/
public double getZ() {
return getAcceleration(Axes.kZ);
}

View File

@@ -9,10 +9,10 @@ import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.SimBoolean;
import edu.wpi.first.hal.SimDevice;
import edu.wpi.first.hal.SimDouble;
import edu.wpi.first.math.geometry.Rotation2d;
import edu.wpi.first.util.sendable.Sendable;
import edu.wpi.first.util.sendable.SendableBuilder;
import edu.wpi.first.util.sendable.SendableRegistry;
import edu.wpi.first.wpilibj.interfaces.Gyro;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -27,7 +27,7 @@ import java.nio.ByteOrder;
* an ADXRS Gyro is supported.
*/
@SuppressWarnings({"TypeName", "PMD.UnusedPrivateField"})
public class ADXRS450_Gyro implements Gyro, Sendable {
public class ADXRS450_Gyro implements Sendable, AutoCloseable {
private static final double kSamplePeriod = 0.0005;
private static final double kCalibrationSampleTime = 5.0;
private static final double kDegreePerSecondPerLSB = 0.0125;
@@ -105,7 +105,14 @@ public class ADXRS450_Gyro implements Gyro, Sendable {
return m_spi != null;
}
@Override
/**
* Calibrate the gyro by running for a number of samples and computing the center value. Then use
* the center value as the Accumulator center value for subsequent measurements.
*
* <p>It's important to make sure that the robot is not moving while the centering calculations
* are in progress, this is typically done when the robot is first turned on while it's sitting at
* rest before the competition starts.
*/
public void calibrate() {
if (m_spi == null) {
return;
@@ -160,7 +167,12 @@ public class ADXRS450_Gyro implements Gyro, Sendable {
return (buf.getInt(0) >> 5) & 0xffff;
}
@Override
/**
* Reset the gyro.
*
* <p>Resets the gyro to a heading of zero. This can be used if there is significant drift in the
* gyro, and it needs to be recalibrated after it has been running.
*/
public void reset() {
if (m_simAngle != null) {
m_simAngle.reset();
@@ -184,7 +196,20 @@ public class ADXRS450_Gyro implements Gyro, Sendable {
}
}
@Override
/**
* Return the heading of the robot in degrees.
*
* <p>The angle is continuous, that is it will continue from 360 to 361 degrees. This allows
* algorithms that wouldn't want to see a discontinuity in the gyro output as it sweeps past from
* 360 to 0 on the second time around.
*
* <p>The angle is expected to increase as the gyro turns clockwise when looked at from the top.
* It needs to follow the NED axis convention.
*
* <p>This heading is based on integration of the returned rate from the gyro.
*
* @return the current heading of the robot in degrees.
*/
public double getAngle() {
if (m_simAngle != null) {
return m_simAngle.get();
@@ -195,7 +220,16 @@ public class ADXRS450_Gyro implements Gyro, Sendable {
return m_spi.getAccumulatorIntegratedValue() * kDegreePerSecondPerLSB;
}
@Override
/**
* Return the rate of rotation of the gyro.
*
* <p>The rate is based on the most recent reading of the gyro analog value
*
* <p>The rate is expected to be positive as the gyro turns clockwise when looked at from the top.
* It needs to follow the NED axis convention.
*
* @return the current rate in degrees per second
*/
public double getRate() {
if (m_simRate != null) {
return m_simRate.get();
@@ -206,6 +240,24 @@ public class ADXRS450_Gyro implements Gyro, Sendable {
return m_spi.getAccumulatorLastValue() * kDegreePerSecondPerLSB;
}
/**
* Return the heading of the robot as a {@link edu.wpi.first.math.geometry.Rotation2d}.
*
* <p>The angle is continuous, that is it will continue from 360 to 361 degrees. This allows
* algorithms that wouldn't want to see a discontinuity in the gyro output as it sweeps past from
* 360 to 0 on the second time around.
*
* <p>The angle is expected to increase as the gyro turns counterclockwise when looked at from the
* top. It needs to follow the NWU axis convention.
*
* <p>This heading is based on integration of the returned rate from the gyro.
*
* @return the current heading of the robot as a {@link edu.wpi.first.math.geometry.Rotation2d}.
*/
public Rotation2d getRotation2d() {
return Rotation2d.fromDegrees(-getAngle());
}
@Override
public void initSendable(SendableBuilder builder) {
builder.setSmartDashboardType("Gyro");

View File

@@ -9,10 +9,10 @@ import static edu.wpi.first.util.ErrorMessages.requireNonNullParam;
import edu.wpi.first.hal.AnalogGyroJNI;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.math.geometry.Rotation2d;
import edu.wpi.first.util.sendable.Sendable;
import edu.wpi.first.util.sendable.SendableBuilder;
import edu.wpi.first.util.sendable.SendableRegistry;
import edu.wpi.first.wpilibj.interfaces.Gyro;
/**
* Use a rate gyro to return the robots heading relative to a starting position. The Gyro class
@@ -23,7 +23,7 @@ import edu.wpi.first.wpilibj.interfaces.Gyro;
*
* <p>This class is for gyro sensors that connect to an analog input.
*/
public class AnalogGyro implements Gyro, Sendable {
public class AnalogGyro implements Sendable, AutoCloseable {
private static final double kDefaultVoltsPerDegreePerSecond = 0.007;
protected AnalogInput m_analog;
private boolean m_channelAllocated;
@@ -42,11 +42,36 @@ public class AnalogGyro implements Gyro, Sendable {
SendableRegistry.addLW(this, "AnalogGyro", m_analog.getChannel());
}
@Override
/**
* Calibrate the gyro by running for a number of samples and computing the center value. Then use
* the center value as the Accumulator center value for subsequent measurements.
*
* <p>It's important to make sure that the robot is not moving while the centering calculations
* are in progress, this is typically done when the robot is first turned on while it's sitting at
* rest before the competition starts.
*/
public void calibrate() {
AnalogGyroJNI.calibrateAnalogGyro(m_gyroHandle);
}
/**
* Return the heading of the robot as a {@link edu.wpi.first.math.geometry.Rotation2d}.
*
* <p>The angle is continuous, that is it will continue from 360 to 361 degrees. This allows
* algorithms that wouldn't want to see a discontinuity in the gyro output as it sweeps past from
* 360 to 0 on the second time around.
*
* <p>The angle is expected to increase as the gyro turns counterclockwise when looked at from the
* top. It needs to follow the NWU axis convention.
*
* <p>This heading is based on integration of the returned rate from the gyro.
*
* @return the current heading of the robot as a {@link edu.wpi.first.math.geometry.Rotation2d}.
*/
public Rotation2d getRotation2d() {
return Rotation2d.fromDegrees(-getAngle());
}
/**
* Gyro constructor using the channel number.
*
@@ -109,7 +134,12 @@ public class AnalogGyro implements Gyro, Sendable {
reset();
}
@Override
/**
* Reset the gyro.
*
* <p>Resets the gyro to a heading of zero. This can be used if there is significant drift in the
* gyro, and it needs to be recalibrated after it has been running.
*/
public void reset() {
AnalogGyroJNI.resetAnalogGyro(m_gyroHandle);
}
@@ -125,7 +155,20 @@ public class AnalogGyro implements Gyro, Sendable {
AnalogGyroJNI.freeAnalogGyro(m_gyroHandle);
}
@Override
/**
* Return the heading of the robot in degrees.
*
* <p>The angle is continuous, that is it will continue from 360 to 361 degrees. This allows
* algorithms that wouldn't want to see a discontinuity in the gyro output as it sweeps past from
* 360 to 0 on the second time around.
*
* <p>The angle is expected to increase as the gyro turns clockwise when looked at from the top.
* It needs to follow the NED axis convention.
*
* <p>This heading is based on integration of the returned rate from the gyro.
*
* @return the current heading of the robot in degrees.
*/
public double getAngle() {
if (m_analog == null) {
return 0.0;
@@ -134,7 +177,16 @@ public class AnalogGyro implements Gyro, Sendable {
}
}
@Override
/**
* Return the rate of rotation of the gyro.
*
* <p>The rate is based on the most recent reading of the gyro analog value
*
* <p>The rate is expected to be positive as the gyro turns clockwise when looked at from the top.
* It needs to follow the NED axis convention.
*
* @return the current rate in degrees per second
*/
public double getRate() {
if (m_analog == null) {
return 0.0;

View File

@@ -10,14 +10,19 @@ import edu.wpi.first.hal.HAL;
import edu.wpi.first.util.sendable.Sendable;
import edu.wpi.first.util.sendable.SendableBuilder;
import edu.wpi.first.util.sendable.SendableRegistry;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
/**
* Built-in accelerometer.
*
* <p>This class allows access to the roboRIO's internal accelerometer.
*/
public class BuiltInAccelerometer implements Accelerometer, Sendable, AutoCloseable {
public class BuiltInAccelerometer implements Sendable, AutoCloseable {
public enum Range {
k2G,
k4G,
k8G
}
/**
* Constructor.
*
@@ -39,7 +44,12 @@ public class BuiltInAccelerometer implements Accelerometer, Sendable, AutoClosea
SendableRegistry.remove(this);
}
@Override
/**
* Set the measuring range of the accelerometer.
*
* @param range The maximum acceleration, positive or negative, that the accelerometer will
* measure.
*/
public void setRange(Range range) {
AccelerometerJNI.setAccelerometerActive(false);
@@ -53,9 +63,8 @@ public class BuiltInAccelerometer implements Accelerometer, Sendable, AutoClosea
case k8G:
AccelerometerJNI.setAccelerometerRange(2);
break;
case k16G:
default:
throw new IllegalArgumentException(range + " range not supported (use k2G, k4G, or k8G)");
throw new IllegalArgumentException("Missing case for range type " + range);
}
AccelerometerJNI.setAccelerometerActive(true);
@@ -66,7 +75,6 @@ public class BuiltInAccelerometer implements Accelerometer, Sendable, AutoClosea
*
* @return The acceleration of the roboRIO along the X axis in g-forces
*/
@Override
public double getX() {
return AccelerometerJNI.getAccelerometerX();
}
@@ -76,7 +84,6 @@ public class BuiltInAccelerometer implements Accelerometer, Sendable, AutoClosea
*
* @return The acceleration of the roboRIO along the Y axis in g-forces
*/
@Override
public double getY() {
return AccelerometerJNI.getAccelerometerY();
}
@@ -86,7 +93,6 @@ public class BuiltInAccelerometer implements Accelerometer, Sendable, AutoClosea
*
* @return The acceleration of the roboRIO along the Z axis in g-forces
*/
@Override
public double getZ() {
return AccelerometerJNI.getAccelerometerZ();
}

View File

@@ -4,7 +4,12 @@
package edu.wpi.first.wpilibj.interfaces;
/** Interface for 3-axis accelerometers. */
/**
* Interface for 3-axis accelerometers.
*
* @deprecated This interface is being removed with no replacement.
*/
@Deprecated(since = "2024", forRemoval = true)
public interface Accelerometer {
enum Range {
k2G,

View File

@@ -6,7 +6,12 @@ package edu.wpi.first.wpilibj.interfaces;
import edu.wpi.first.math.geometry.Rotation2d;
/** Interface for yaw rate gyros. */
/**
* Interface for yaw rate gyros.
*
* @deprecated This interface is being removed with no replacement.
*/
@Deprecated(since = "2024", forRemoval = true)
public interface Gyro extends AutoCloseable {
/**
* Calibrate the gyro. It's important to make sure that the robot is not moving while the

View File

@@ -4,8 +4,6 @@
package edu.wpi.first.wpilibj.shuffleboard;
import edu.wpi.first.wpilibj.interfaces.Accelerometer.Range;
/**
* The types of the widgets bundled with Shuffleboard.
*
@@ -362,7 +360,6 @@ public enum BuiltInWidgets implements WidgetType {
*
* <table>
* <tr><th>Name</th><th>Type</th><th>Default Value</th><th>Notes</th></tr>
* <tr><td>Range</td><td>{@link Range}</td><td>k16G</td><td>The accelerometer range</td></tr>
* <tr><td>Show value</td><td>Boolean</td><td>true</td>
* <td>Show or hide the acceleration values</td></tr>
* <tr><td>Precision</td><td>Number</td><td>2</td>

View File

@@ -11,14 +11,13 @@ import edu.wpi.first.wpilibj.ADXL345_I2C;
import edu.wpi.first.wpilibj.ADXL345_SPI;
import edu.wpi.first.wpilibj.I2C;
import edu.wpi.first.wpilibj.SPI;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
class ADXL345SimTest {
@ParameterizedTest
@EnumSource(Accelerometer.Range.class)
void testInitI2C(Accelerometer.Range range) {
@EnumSource(ADXL345_I2C.Range.class)
void testInitI2C(ADXL345_I2C.Range range) {
HAL.initialize(500, 0);
try (ADXL345_I2C accel = new ADXL345_I2C(I2C.Port.kMXP, range)) {
@@ -40,8 +39,8 @@ class ADXL345SimTest {
}
@ParameterizedTest
@EnumSource(Accelerometer.Range.class)
void testInitSPi(Accelerometer.Range range) {
@EnumSource(ADXL345_SPI.Range.class)
void testInitSPi(ADXL345_SPI.Range range) {
HAL.initialize(500, 0);
try (ADXL345_SPI accel = new ADXL345_SPI(SPI.Port.kMXP, range)) {

View File

@@ -9,14 +9,13 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.ADXL362;
import edu.wpi.first.wpilibj.SPI;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
class ADXL362SimTest {
@ParameterizedTest
@EnumSource(Accelerometer.Range.class)
void testAccel(Accelerometer.Range range) {
@EnumSource(ADXL362.Range.class)
void testAccel(ADXL362.Range range) {
HAL.initialize(500, 0);
try (ADXL362 accel = new ADXL362(SPI.Port.kMXP, range)) {

View File

@@ -6,12 +6,10 @@ package edu.wpi.first.wpilibj.simulation;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.BuiltInAccelerometer;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
import edu.wpi.first.wpilibj.simulation.testutils.BooleanCallback;
import edu.wpi.first.wpilibj.simulation.testutils.DoubleCallback;
import edu.wpi.first.wpilibj.simulation.testutils.EnumCallback;
@@ -102,7 +100,7 @@ class AccelerometerSimTest {
EnumCallback callback = new EnumCallback();
Accelerometer.Range range = Accelerometer.Range.k4G;
BuiltInAccelerometer.Range range = BuiltInAccelerometer.Range.k4G;
try (CallbackStore cb = sim.registerRangeCallback(callback, false);
BuiltInAccelerometer accel = new BuiltInAccelerometer(range)) {
assertTrue(callback.wasTriggered());
@@ -111,7 +109,7 @@ class AccelerometerSimTest {
// 2G
callback.reset();
range = Accelerometer.Range.k2G;
range = BuiltInAccelerometer.Range.k2G;
accel.setRange(range);
assertTrue(callback.wasTriggered());
assertEquals(range.ordinal(), sim.getRange());
@@ -119,7 +117,7 @@ class AccelerometerSimTest {
// 4G
callback.reset();
range = Accelerometer.Range.k4G;
range = BuiltInAccelerometer.Range.k4G;
accel.setRange(range);
assertTrue(callback.wasTriggered());
assertEquals(range.ordinal(), sim.getRange());
@@ -127,16 +125,11 @@ class AccelerometerSimTest {
// 8G
callback.reset();
range = Accelerometer.Range.k8G;
range = BuiltInAccelerometer.Range.k8G;
accel.setRange(range);
assertTrue(callback.wasTriggered());
assertEquals(range.ordinal(), sim.getRange());
assertEquals(range.ordinal(), callback.getSetValue());
// 16G - Not supported
callback.reset();
assertThrows(IllegalArgumentException.class, () -> accel.setRange(Accelerometer.Range.k16G));
assertFalse(callback.wasTriggered());
}
}
}

View File

@@ -8,7 +8,6 @@ import edu.wpi.first.wpilibj.ADXRS450_Gyro;
import edu.wpi.first.wpilibj.Encoder;
import edu.wpi.first.wpilibj.drive.DifferentialDrive;
import edu.wpi.first.wpilibj.examples.gyrodrivecommands.Constants.DriveConstants;
import edu.wpi.first.wpilibj.interfaces.Gyro;
import edu.wpi.first.wpilibj.motorcontrol.MotorControllerGroup;
import edu.wpi.first.wpilibj.motorcontrol.PWMSparkMax;
import edu.wpi.first.wpilibj2.command.Subsystem;
@@ -44,7 +43,7 @@ public class DriveSubsystem extends Subsystem {
DriveConstants.kRightEncoderReversed);
// The gyro sensor
private final Gyro m_gyro = new ADXRS450_Gyro();
private final ADXRS450_Gyro m_gyro = new ADXRS450_Gyro();
/** Creates a new DriveSubsystem. */
public DriveSubsystem() {

View File

@@ -13,7 +13,6 @@ import edu.wpi.first.wpilibj.ADXRS450_Gyro;
import edu.wpi.first.wpilibj.Encoder;
import edu.wpi.first.wpilibj.drive.MecanumDrive;
import edu.wpi.first.wpilibj.examples.mecanumcontrollercommand.Constants.DriveConstants;
import edu.wpi.first.wpilibj.interfaces.Gyro;
import edu.wpi.first.wpilibj.motorcontrol.PWMSparkMax;
import edu.wpi.first.wpilibj2.command.Subsystem;
@@ -55,7 +54,7 @@ public class DriveSubsystem extends Subsystem {
DriveConstants.kRearRightEncoderReversed);
// The gyro sensor
private final Gyro m_gyro = new ADXRS450_Gyro();
private final ADXRS450_Gyro m_gyro = new ADXRS450_Gyro();
// Odometry class for tracking robot pose
MecanumDriveOdometry m_odometry =

View File

@@ -11,7 +11,6 @@ import edu.wpi.first.wpilibj.ADXRS450_Gyro;
import edu.wpi.first.wpilibj.Encoder;
import edu.wpi.first.wpilibj.drive.DifferentialDrive;
import edu.wpi.first.wpilibj.examples.ramsetecommand.Constants.DriveConstants;
import edu.wpi.first.wpilibj.interfaces.Gyro;
import edu.wpi.first.wpilibj.motorcontrol.MotorControllerGroup;
import edu.wpi.first.wpilibj.motorcontrol.PWMSparkMax;
import edu.wpi.first.wpilibj2.command.Subsystem;
@@ -47,7 +46,7 @@ public class DriveSubsystem extends Subsystem {
DriveConstants.kRightEncoderReversed);
// The gyro sensor
private final Gyro m_gyro = new ADXRS450_Gyro();
private final ADXRS450_Gyro m_gyro = new ADXRS450_Gyro();
// Odometry class for tracking robot pose
private final DifferentialDriveOdometry m_odometry;

View File

@@ -12,7 +12,6 @@ import edu.wpi.first.math.kinematics.SwerveModulePosition;
import edu.wpi.first.math.kinematics.SwerveModuleState;
import edu.wpi.first.wpilibj.ADXRS450_Gyro;
import edu.wpi.first.wpilibj.examples.swervecontrollercommand.Constants.DriveConstants;
import edu.wpi.first.wpilibj.interfaces.Gyro;
import edu.wpi.first.wpilibj2.command.Subsystem;
public class DriveSubsystem extends Subsystem {
@@ -54,7 +53,7 @@ public class DriveSubsystem extends Subsystem {
DriveConstants.kRearRightTurningEncoderReversed);
// The gyro sensor
private final Gyro m_gyro = new ADXRS450_Gyro();
private final ADXRS450_Gyro m_gyro = new ADXRS450_Gyro();
// Odometry class for tracking robot pose
SwerveDriveOdometry m_odometry =

View File

@@ -6,7 +6,6 @@ package edu.wpi.first.wpilibj;
import static org.junit.Assert.assertEquals;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
import edu.wpi.first.wpilibj.test.AbstractComsSetup;
import java.util.Arrays;
import java.util.Collection;
@@ -23,7 +22,7 @@ public class BuiltInAccelerometerTest extends AbstractComsSetup {
private static final double kAccelerationTolerance = 0.1;
private final BuiltInAccelerometer m_accelerometer;
public BuiltInAccelerometerTest(Accelerometer.Range range) {
public BuiltInAccelerometerTest(BuiltInAccelerometer.Range range) {
m_accelerometer = new BuiltInAccelerometer(range);
}
@@ -38,10 +37,12 @@ public class BuiltInAccelerometerTest extends AbstractComsSetup {
/** Test with all valid ranges to make sure unpacking is always done correctly. */
@Parameters
public static Collection<Accelerometer.Range[]> generateData() {
public static Collection<BuiltInAccelerometer.Range[]> generateData() {
return Arrays.asList(
new Accelerometer.Range[][] {
{Accelerometer.Range.k2G}, {Accelerometer.Range.k4G}, {Accelerometer.Range.k8G}
new BuiltInAccelerometer.Range[][] {
{BuiltInAccelerometer.Range.k2G},
{BuiltInAccelerometer.Range.k4G},
{BuiltInAccelerometer.Range.k8G}
});
}