[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

@@ -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>