[build] Apply spotless for java formatting (#1768)

Update checkstyle config to be compatible with spotless.

Co-authored-by: Austin Shalit <austinshalit@gmail.com>
This commit is contained in:
Peter Johnson
2020-12-29 22:45:16 -08:00
committed by GitHub
parent e563a0b7db
commit a751fa22d2
883 changed files with 16526 additions and 17751 deletions

View File

@@ -4,9 +4,6 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.hal.FRCNetComm.tInstances;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
@@ -17,10 +14,10 @@ import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/**
* ADXL345 I2C Accelerometer.
*/
/** ADXL345 I2C Accelerometer. */
@SuppressWarnings({"TypeName", "PMD.UnusedPrivateField"})
public class ADXL345_I2C implements Accelerometer, Sendable, AutoCloseable {
private static final byte kAddress = 0x1D;
@@ -44,9 +41,7 @@ public class ADXL345_I2C implements Accelerometer, Sendable, AutoCloseable {
kY((byte) 0x02),
kZ((byte) 0x04);
/**
* The integer value representing this enumeration.
*/
/** The integer value representing this enumeration. */
@SuppressWarnings("MemberName")
public final byte value;
@@ -73,7 +68,7 @@ public class ADXL345_I2C implements Accelerometer, Sendable, AutoCloseable {
/**
* Constructs the ADXL345 Accelerometer with I2C address 0x1D.
*
* @param port The I2C port the accelerometer is attached to
* @param port The I2C port the accelerometer is attached to
* @param range The range (+ or -) that the accelerometer will measure.
*/
public ADXL345_I2C(I2C.Port port, Range range) {
@@ -83,8 +78,8 @@ public class ADXL345_I2C implements Accelerometer, Sendable, AutoCloseable {
/**
* Constructs the ADXL345 Accelerometer over I2C.
*
* @param port The I2C port the accelerometer is attached to
* @param range The range (+ or -) that the accelerometer will measure.
* @param port The I2C port the accelerometer is attached to
* @param range The range (+ or -) that the accelerometer will measure.
* @param deviceAddress I2C address of the accelerometer (0x1D or 0x53)
*/
public ADXL345_I2C(I2C.Port port, Range range, int deviceAddress) {
@@ -93,8 +88,13 @@ public class ADXL345_I2C implements Accelerometer, Sendable, AutoCloseable {
// simulation
m_simDevice = SimDevice.create("Accel:ADXL345_I2C", port.value, deviceAddress);
if (m_simDevice != null) {
m_simRange = m_simDevice.createEnumDouble("range", SimDevice.Direction.kOutput,
new String[] {"2G", "4G", "8G", "16G"}, new double[] {2.0, 4.0, 8.0, 16.0}, 0);
m_simRange =
m_simDevice.createEnumDouble(
"range",
SimDevice.Direction.kOutput,
new String[] {"2G", "4G", "8G", "16G"},
new double[] {2.0, 4.0, 8.0, 16.0},
0);
m_simX = m_simDevice.createDouble("x", SimDevice.Direction.kInput, 0.0);
m_simY = m_simDevice.createDouble("y", SimDevice.Direction.kInput, 0.0);
m_simZ = m_simDevice.createDouble("z", SimDevice.Direction.kInput, 0.0);
@@ -220,11 +220,12 @@ public class ADXL345_I2C implements Accelerometer, Sendable, AutoCloseable {
NetworkTableEntry entryX = builder.getEntry("X");
NetworkTableEntry entryY = builder.getEntry("Y");
NetworkTableEntry entryZ = builder.getEntry("Z");
builder.setUpdateTable(() -> {
AllAxes data = getAccelerations();
entryX.setDouble(data.XAxis);
entryY.setDouble(data.YAxis);
entryZ.setDouble(data.ZAxis);
});
builder.setUpdateTable(
() -> {
AllAxes data = getAccelerations();
entryX.setDouble(data.XAxis);
entryY.setDouble(data.YAxis);
entryZ.setDouble(data.ZAxis);
});
}
}

View File

@@ -4,9 +4,6 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.hal.FRCNetComm.tInstances;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
@@ -17,10 +14,10 @@ import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/**
* ADXL345 SPI Accelerometer.
*/
/** ADXL345 SPI Accelerometer. */
@SuppressWarnings({"TypeName", "PMD.UnusedPrivateField"})
public class ADXL345_SPI implements Accelerometer, Sendable, AutoCloseable {
private static final int kPowerCtlRegister = 0x2D;
@@ -47,9 +44,7 @@ public class ADXL345_SPI implements Accelerometer, Sendable, AutoCloseable {
kY((byte) 0x02),
kZ((byte) 0x04);
/**
* The integer value representing this enumeration.
*/
/** The integer value representing this enumeration. */
public final byte value;
Axes(byte value) {
@@ -75,7 +70,7 @@ public class ADXL345_SPI implements Accelerometer, Sendable, AutoCloseable {
/**
* Constructor.
*
* @param port The SPI port that the accelerometer is connected to
* @param port The SPI port that the accelerometer is connected to
* @param range The range (+ or -) that the accelerometer will measure.
*/
public ADXL345_SPI(SPI.Port port, Range range) {
@@ -83,8 +78,13 @@ public class ADXL345_SPI implements Accelerometer, Sendable, AutoCloseable {
// simulation
m_simDevice = SimDevice.create("Accel:ADXL345_SPI", port.value);
if (m_simDevice != null) {
m_simRange = m_simDevice.createEnumDouble("range", SimDevice.Direction.kOutput,
new String[] {"2G", "4G", "8G", "16G"}, new double[] {2.0, 4.0, 8.0, 16.0}, 0);
m_simRange =
m_simDevice.createEnumDouble(
"range",
SimDevice.Direction.kOutput,
new String[] {"2G", "4G", "8G", "16G"},
new double[] {2.0, 4.0, 8.0, 16.0},
0);
m_simX = m_simDevice.createDouble("x", SimDevice.Direction.kInput, 0.0);
m_simY = m_simDevice.createDouble("y", SimDevice.Direction.kInput, 0.0);
m_simZ = m_simDevice.createDouble("z", SimDevice.Direction.kInput, 0.0);
@@ -151,7 +151,7 @@ public class ADXL345_SPI implements Accelerometer, Sendable, AutoCloseable {
}
// Specify the data format to read
byte[] commands = new byte[]{kDataFormatRegister, (byte) (kDataFormat_FullRes | value)};
byte[] commands = new byte[] {kDataFormatRegister, (byte) (kDataFormat_FullRes | value)};
m_spi.write(commands, commands.length);
if (m_simRange != null) {
@@ -191,8 +191,8 @@ public class ADXL345_SPI implements Accelerometer, Sendable, AutoCloseable {
return m_simZ.get();
}
ByteBuffer transferBuffer = ByteBuffer.allocate(3);
transferBuffer.put(0,
(byte) ((kAddress_Read | kAddress_MultiByte | kDataRegister) + axis.value));
transferBuffer.put(
0, (byte) ((kAddress_Read | kAddress_MultiByte | kDataRegister) + axis.value));
m_spi.transaction(transferBuffer, transferBuffer, 3);
// Sensor is little endian
transferBuffer.order(ByteOrder.LITTLE_ENDIAN);
@@ -234,11 +234,12 @@ public class ADXL345_SPI implements Accelerometer, Sendable, AutoCloseable {
NetworkTableEntry entryX = builder.getEntry("X");
NetworkTableEntry entryY = builder.getEntry("Y");
NetworkTableEntry entryZ = builder.getEntry("Z");
builder.setUpdateTable(() -> {
AllAxes data = getAccelerations();
entryX.setDouble(data.XAxis);
entryY.setDouble(data.YAxis);
entryZ.setDouble(data.ZAxis);
});
builder.setUpdateTable(
() -> {
AllAxes data = getAccelerations();
entryX.setDouble(data.XAxis);
entryY.setDouble(data.YAxis);
entryZ.setDouble(data.ZAxis);
});
}
}

View File

@@ -4,9 +4,6 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.SimDevice;
@@ -16,6 +13,8 @@ import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/**
* ADXL362 SPI Accelerometer.
@@ -71,7 +70,7 @@ public class ADXL362 implements Accelerometer, Sendable, AutoCloseable {
private double m_gsPerLSB;
/**
* Constructor. Uses the onboard CS1.
* Constructor. Uses the onboard CS1.
*
* @param range The range (+ or -) that the accelerometer will measure.
*/
@@ -82,7 +81,7 @@ public class ADXL362 implements Accelerometer, Sendable, AutoCloseable {
/**
* Constructor.
*
* @param port The SPI port that the accelerometer is connected to
* @param port The SPI port that the accelerometer is connected to
* @param range The range (+ or -) that the accelerometer will measure.
*/
public ADXL362(SPI.Port port, Range range) {
@@ -91,8 +90,13 @@ public class ADXL362 implements Accelerometer, Sendable, AutoCloseable {
// simulation
m_simDevice = SimDevice.create("Accel:ADXL362", port.value);
if (m_simDevice != null) {
m_simRange = m_simDevice.createEnumDouble("range", SimDevice.Direction.kOutput,
new String[] {"2G", "4G", "8G", "16G"}, new double[] {2.0, 4.0, 8.0, 16.0}, 0);
m_simRange =
m_simDevice.createEnumDouble(
"range",
SimDevice.Direction.kOutput,
new String[] {"2G", "4G", "8G", "16G"},
new double[] {2.0, 4.0, 8.0, 16.0},
0);
m_simX = m_simDevice.createDouble("x", SimDevice.Direction.kInput, 0.0);
m_simY = m_simDevice.createDouble("y", SimDevice.Direction.kInput, 0.0);
m_simZ = m_simDevice.createDouble("z", SimDevice.Direction.kInput, 0.0);
@@ -160,18 +164,17 @@ public class ADXL362 implements Accelerometer, Sendable, AutoCloseable {
m_gsPerLSB = 0.002;
break;
case k8G:
case k16G: // 16G not supported; treat as 8G
case k16G: // 16G not supported; treat as 8G
value = kFilterCtl_Range8G;
m_gsPerLSB = 0.004;
break;
default:
throw new IllegalArgumentException(range + " unsupported");
}
// Specify the data format to read
byte[] commands = new byte[]{kRegWrite, kFilterCtlRegister, (byte) (kFilterCtl_ODR_100Hz
| value)};
byte[] commands =
new byte[] {kRegWrite, kFilterCtlRegister, (byte) (kFilterCtl_ODR_100Hz | value)};
m_spi.write(commands, commands.length);
if (m_simRange != null) {
@@ -179,7 +182,6 @@ public class ADXL362 implements Accelerometer, Sendable, AutoCloseable {
}
}
@Override
public double getX() {
return getAcceleration(Axes.kX);
@@ -259,11 +261,12 @@ public class ADXL362 implements Accelerometer, Sendable, AutoCloseable {
NetworkTableEntry entryX = builder.getEntry("X");
NetworkTableEntry entryY = builder.getEntry("Y");
NetworkTableEntry entryZ = builder.getEntry("Z");
builder.setUpdateTable(() -> {
AllAxes data = getAccelerations();
entryX.setDouble(data.XAxis);
entryY.setDouble(data.YAxis);
entryZ.setDouble(data.ZAxis);
});
builder.setUpdateTable(
() -> {
AllAxes data = getAccelerations();
entryX.setDouble(data.XAxis);
entryY.setDouble(data.YAxis);
entryZ.setDouble(data.ZAxis);
});
}
}

View File

@@ -4,9 +4,6 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.SimBoolean;
@@ -14,6 +11,8 @@ import edu.wpi.first.hal.SimDevice;
import edu.wpi.first.hal.SimDouble;
import edu.wpi.first.wpilibj.interfaces.Gyro;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/**
* Use a rate gyro to return the robots heading relative to a starting position. The Gyro class
@@ -49,9 +48,7 @@ public class ADXRS450_Gyro extends GyroBase implements Gyro, PIDSource, Sendable
private SimDouble m_simAngle;
private SimDouble m_simRate;
/**
* Constructor. Uses the onboard CS0.
*/
/** Constructor. Uses the onboard CS0. */
public ADXRS450_Gyro() {
this(SPI.Port.kOnboardCS0);
}
@@ -84,13 +81,12 @@ public class ADXRS450_Gyro extends GyroBase implements Gyro, PIDSource, Sendable
if ((readRegister(kPIDRegister) & 0xff00) != 0x5200) {
m_spi.close();
m_spi = null;
DriverStation.reportError("could not find ADXRS450 gyro on SPI port " + port.value,
false);
DriverStation.reportError("could not find ADXRS450 gyro on SPI port " + port.value, false);
return;
}
m_spi.initAccumulator(kSamplePeriod, 0x20000000, 4, 0x0c00000e, 0x04000000, 10, 16,
true, true);
m_spi.initAccumulator(
kSamplePeriod, 0x20000000, 4, 0x0c00000e, 0x04000000, 10, 16, true, true);
calibrate();
}
@@ -161,7 +157,7 @@ public class ADXRS450_Gyro extends GyroBase implements Gyro, PIDSource, Sendable
m_spi.read(false, buf, 4);
if ((buf.get(0) & 0xe0) == 0) {
return 0; // error, return 0
return 0; // error, return 0
}
return (buf.getInt(0) >> 5) & 0xffff;
}
@@ -179,9 +175,7 @@ public class ADXRS450_Gyro extends GyroBase implements Gyro, PIDSource, Sendable
}
}
/**
* Delete (free) the spi port used for the gyro and stop accumulating.
*/
/** Delete (free) the spi port used for the gyro and stop accumulating. */
@Override
public void close() {
SendableRegistry.remove(this);

View File

@@ -55,8 +55,8 @@ public class AddressableLED implements AutoCloseable {
/**
* Sets the led output data.
*
* <p>If the output is enabled, this will start writing the next data cycle.
* It is safe to call, even while output is enabled.
* <p>If the output is enabled, this will start writing the next data cycle. It is safe to call,
* even while output is enabled.
*
* @param buffer the buffer to write
*/
@@ -74,10 +74,16 @@ public class AddressableLED implements AutoCloseable {
* @param lowTime1NanoSeconds low time for 1 bit
* @param highTime1NanoSeconds high time for 1 bit
*/
public void setBitTiming(int lowTime0NanoSeconds, int highTime0NanoSeconds,
int lowTime1NanoSeconds, int highTime1NanoSeconds) {
AddressableLEDJNI.setBitTiming(m_handle, lowTime0NanoSeconds,
highTime0NanoSeconds, lowTime1NanoSeconds,
public void setBitTiming(
int lowTime0NanoSeconds,
int highTime0NanoSeconds,
int lowTime1NanoSeconds,
int highTime1NanoSeconds) {
AddressableLEDJNI.setBitTiming(
m_handle,
lowTime0NanoSeconds,
highTime0NanoSeconds,
lowTime1NanoSeconds,
highTime1NanoSeconds);
}
@@ -101,9 +107,7 @@ public class AddressableLED implements AutoCloseable {
AddressableLEDJNI.start(m_handle);
}
/**
* Stops the output.
*/
/** Stops the output. */
public void stop() {
AddressableLEDJNI.stop(m_handle);
}

View File

@@ -7,9 +7,7 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.util.Color;
import edu.wpi.first.wpilibj.util.Color8Bit;
/**
* Buffer storage for Addressable LEDs.
*/
/** Buffer storage for Addressable LEDs. */
public class AddressableLEDBuffer {
byte[] m_buffer;
@@ -26,9 +24,9 @@ public class AddressableLEDBuffer {
* Sets a specific led in the buffer.
*
* @param index the index to write
* @param r the r value [0-255]
* @param g the g value [0-255]
* @param b the b value [0-255]
* @param r the r value [0-255]
* @param g the g value [0-255]
* @param b the b value [0-255]
*/
@SuppressWarnings("ParameterName")
public void setRGB(int index, int r, int g, int b) {
@@ -42,9 +40,9 @@ public class AddressableLEDBuffer {
* Sets a specific led in the buffer.
*
* @param index the index to write
* @param h the h value [0-180]
* @param s the s value [0-255]
* @param v the v value [0-255]
* @param h the h value [0-180]
* @param s the s value [0-255]
* @param v the v value [0-255]
*/
@SuppressWarnings("ParameterName")
public void setHSV(final int index, final int h, final int s, final int v) {
@@ -89,10 +87,7 @@ public class AddressableLEDBuffer {
* @param color The color of the LED
*/
public void setLED(int index, Color color) {
setRGB(index,
(int) (color.red * 255),
(int) (color.green * 255),
(int) (color.blue * 255));
setRGB(index, (int) (color.red * 255), (int) (color.green * 255), (int) (color.blue * 255));
}
/**
@@ -121,8 +116,8 @@ public class AddressableLEDBuffer {
* @return the LED color at the specified index
*/
public Color8Bit getLED8Bit(int index) {
return new Color8Bit(m_buffer[index * 4 + 2] & 0xFF, m_buffer[index * 4 + 1] & 0xFF,
m_buffer[index * 4] & 0xFF);
return new Color8Bit(
m_buffer[index * 4 + 2] & 0xFF, m_buffer[index * 4 + 1] & 0xFF, m_buffer[index * 4] & 0xFF);
}
/**
@@ -132,9 +127,9 @@ public class AddressableLEDBuffer {
* @return the LED color at the specified index
*/
public Color getLED(int index) {
return new Color((m_buffer[index * 4 + 2] & 0xFF) / 255.0,
(m_buffer[index * 4 + 1] & 0xFF) / 255.0,
(m_buffer[index * 4] & 0xFF) / 255.0);
return new Color(
(m_buffer[index * 4 + 2] & 0xFF) / 255.0,
(m_buffer[index * 4 + 1] & 0xFF) / 255.0,
(m_buffer[index * 4] & 0xFF) / 255.0);
}
}

View File

@@ -4,13 +4,13 @@
package edu.wpi.first.wpilibj;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
/**
* Handle operation of an analog accelerometer. The accelerometer reads acceleration directly
* through the sensor. Many sensors have multiple axis and can be treated as multiple devices. Each
@@ -23,12 +23,9 @@ public class AnalogAccelerometer implements PIDSource, Sendable, AutoCloseable {
private final boolean m_allocatedChannel;
protected PIDSourceType m_pidSource = PIDSourceType.kDisplacement;
/**
* Common initialization.
*/
/** Common initialization. */
private void initAccelerometer() {
HAL.report(tResourceType.kResourceType_Accelerometer,
m_analogChannel.getChannel() + 1);
HAL.report(tResourceType.kResourceType_Accelerometer, m_analogChannel.getChannel() + 1);
SendableRegistry.addLW(this, "Accelerometer", m_analogChannel.getChannel());
}
@@ -50,7 +47,7 @@ public class AnalogAccelerometer implements PIDSource, Sendable, AutoCloseable {
* read as an analog channel as well as through the Accelerometer class.
*
* @param channel The existing AnalogInput object for the analog input the accelerometer is
* connected to
* connected to
*/
public AnalogAccelerometer(final AnalogInput channel) {
this(channel, false);
@@ -63,9 +60,7 @@ public class AnalogAccelerometer implements PIDSource, Sendable, AutoCloseable {
initAccelerometer();
}
/**
* Delete the analog components used for the accelerometer.
*/
/** Delete the analog components used for the accelerometer. */
@Override
public void close() {
SendableRegistry.remove(this);

View File

@@ -10,9 +10,7 @@ import edu.wpi.first.wpilibj.AnalogTriggerOutput.AnalogTriggerType;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Class for supporting continuous analog encoders, such as the US Digital MA3.
*/
/** Class for supporting continuous analog encoders, such as the US Digital MA3. */
public class AnalogEncoder implements Sendable, AutoCloseable {
private final AnalogInput m_analogInput;
private AnalogTrigger m_analogTrigger;
@@ -86,9 +84,9 @@ public class AnalogEncoder implements Sendable, AutoCloseable {
/**
* Get the offset of position relative to the last reset.
*
* <p>getPositionInRotation() - getPositionOffset() will give an encoder absolute
* position relative to the last reset. This could potentially be negative,
* which needs to be accounted for.
* <p>getPositionInRotation() - getPositionOffset() will give an encoder absolute position
* relative to the last reset. This could potentially be negative, which needs to be accounted
* for.
*
* @return the position offset
*/
@@ -97,11 +95,10 @@ public class AnalogEncoder implements Sendable, AutoCloseable {
}
/**
* Set the distance per rotation of the encoder. This sets the multiplier used
* to determine the distance driven based on the rotation value from the
* encoder. Set this value based on the how far the mechanism travels in 1
* rotation of the encoder, and factor in gearing reductions following the
* encoder shaft. This distance can be in any units you like, linear or angular.
* Set the distance per rotation of the encoder. This sets the multiplier used to determine the
* distance driven based on the rotation value from the encoder. Set this value based on the how
* far the mechanism travels in 1 rotation of the encoder, and factor in gearing reductions
* following the encoder shaft. This distance can be in any units you like, linear or angular.
*
* @param distancePerRotation the distance per rotation of the encoder
*/
@@ -112,16 +109,15 @@ public class AnalogEncoder implements Sendable, AutoCloseable {
/**
* Get the distance per rotation for this encoder.
*
* @return The scale factor that will be used to convert rotation to useful
* units.
* @return The scale factor that will be used to convert rotation to useful units.
*/
public double getDistancePerRotation() {
return m_distancePerRotation;
}
/**
* Get the distance the sensor has driven since the last reset as scaled by the
* value from {@link #setDistancePerRotation(double)}.
* Get the distance the sensor has driven since the last reset as scaled by the value from {@link
* #setDistancePerRotation(double)}.
*
* @return The distance driven since the last reset
*/
@@ -138,9 +134,7 @@ public class AnalogEncoder implements Sendable, AutoCloseable {
return m_analogInput.getChannel();
}
/**
* Reset the Encoder distance to zero.
*/
/** Reset the Encoder distance to zero. */
public void reset() {
m_counter.reset();
m_positionOffset = m_analogInput.getVoltage();

View File

@@ -4,14 +4,14 @@
package edu.wpi.first.wpilibj;
import static edu.wpi.first.wpilibj.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.wpilibj.interfaces.Gyro;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
/**
* Use a rate gyro to return the robots heading relative to a starting position. The Gyro class
* tracks the robots heading based on the starting position. As the robot rotates the new heading is
@@ -28,9 +28,7 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, Sendable, A
private int m_gyroHandle;
/**
* Initialize the gyro. Calibration is handled by calibrate().
*/
/** Initialize the gyro. Calibration is handled by calibrate(). */
public void initGyro() {
if (m_gyroHandle == 0) {
m_gyroHandle = AnalogGyroJNI.initializeAnalogGyro(m_analog.m_port);
@@ -51,7 +49,7 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, Sendable, A
* Gyro constructor using the channel number.
*
* @param channel The analog channel the gyro is connected to. Gyros can only be used on on-board
* channels 0-1.
* channels 0-1.
*/
public AnalogGyro(int channel) {
this(new AnalogInput(channel));
@@ -64,7 +62,7 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, Sendable, A
* channel needs to be shared.
*
* @param channel The AnalogInput object that the gyro is connected to. Gyros can only be used on
* on-board channels 0-1.
* on-board channels 0-1.
*/
public AnalogGyro(AnalogInput channel) {
requireNonNullParam(channel, "channel", "AnalogGyro");
@@ -79,9 +77,9 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, Sendable, A
* offset values. Bypasses calibration.
*
* @param channel The analog channel the gyro is connected to. Gyros can only be used on on-board
* channels 0-1.
* @param center Preset uncalibrated value to use as the accumulator center value.
* @param offset Preset uncalibrated value to use as the gyro offset.
* channels 0-1.
* @param center Preset uncalibrated value to use as the accumulator center value.
* @param offset Preset uncalibrated value to use as the gyro offset.
*/
public AnalogGyro(int channel, int center, double offset) {
this(new AnalogInput(channel), center, offset);
@@ -94,17 +92,18 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, Sendable, A
* the center and offset values. Bypasses calibration.
*
* @param channel The analog channel the gyro is connected to. Gyros can only be used on on-board
* channels 0-1.
* @param center Preset uncalibrated value to use as the accumulator center value.
* @param offset Preset uncalibrated value to use as the gyro offset.
* channels 0-1.
* @param center Preset uncalibrated value to use as the accumulator center value.
* @param offset Preset uncalibrated value to use as the gyro offset.
*/
public AnalogGyro(AnalogInput channel, int center, double offset) {
requireNonNullParam(channel, "channel", "AnalogGyro");
m_analog = channel;
initGyro();
AnalogGyroJNI.setAnalogGyroParameters(m_gyroHandle, kDefaultVoltsPerDegreePerSecond,
offset, center);
AnalogGyroJNI.setAnalogGyroParameters(
m_gyroHandle, kDefaultVoltsPerDegreePerSecond,
offset, center);
reset();
}
@@ -113,9 +112,7 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, Sendable, A
AnalogGyroJNI.resetAnalogGyro(m_gyroHandle);
}
/**
* Delete (free) the accumulator and the analog components used for the gyro.
*/
/** Delete (free) the accumulator and the analog components used for the gyro. */
@Override
public void close() {
SendableRegistry.remove(this);
@@ -170,8 +167,7 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, Sendable, A
* @param voltsPerDegreePerSecond The sensitivity in Volts/degree/second.
*/
public void setSensitivity(double voltsPerDegreePerSecond) {
AnalogGyroJNI.setAnalogGyroVoltsPerDegreePerSecond(m_gyroHandle,
voltsPerDegreePerSecond);
AnalogGyroJNI.setAnalogGyroVoltsPerDegreePerSecond(m_gyroHandle, voltsPerDegreePerSecond);
}
/**

View File

@@ -180,13 +180,16 @@ public class AnalogInput implements PIDSource, Sendable, AutoCloseable {
return AnalogJNI.getAnalogOversampleBits(m_port);
}
/**
* Initialize the accumulator.
*/
/** Initialize the accumulator. */
public void initAccumulator() {
if (!isAccumulatorChannel()) {
throw new AllocationException("Accumulators are only available on slot " + kAccumulatorSlot
+ " on channels " + kAccumulatorChannels[0] + ", " + kAccumulatorChannels[1]);
throw new AllocationException(
"Accumulators are only available on slot "
+ kAccumulatorSlot
+ " on channels "
+ kAccumulatorChannels[0]
+ ", "
+ kAccumulatorChannels[1]);
}
m_accumulatorOffset = 0;
AnalogJNI.initAccumulator(m_port);
@@ -203,9 +206,7 @@ public class AnalogInput implements PIDSource, Sendable, AutoCloseable {
m_accumulatorOffset = initialValue;
}
/**
* Resets the accumulator to the initial value.
*/
/** Resets the accumulator to the initial value. */
public void resetAccumulator() {
AnalogJNI.resetAccumulator(m_port);
@@ -215,7 +216,6 @@ public class AnalogInput implements PIDSource, Sendable, AutoCloseable {
final double overSamples = 1 << getOversampleBits();
final double averageSamples = 1 << getAverageBits();
Timer.delay(sampleTime * overSamples * averageSamples);
}
/**

View File

@@ -10,9 +10,7 @@ import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Analog output class.
*/
/** Analog output class. */
public class AnalogOutput implements Sendable, AutoCloseable {
private int m_port;
private int m_channel;
@@ -41,9 +39,7 @@ public class AnalogOutput implements Sendable, AutoCloseable {
m_channel = 0;
}
/**
* Get the channel of this AnalogOutput.
*/
/** Get the channel of this AnalogOutput. */
public int getChannel() {
return m_channel;
}

View File

@@ -26,13 +26,13 @@ public class AnalogPotentiometer implements Potentiometer, Sendable, AutoCloseab
* <p>Use the fullRange and offset values so that the output produces meaningful values. I.E: you
* have a 270 degree potentiometer and you want the output to be degrees with the halfway point as
* 0 degrees. The fullRange value is 270.0(degrees) and the offset is -135.0 since the halfway
* point after scaling is 135 degrees. This will calculate the result from the fullRange times
* the fraction of the supply voltage, plus the offset.
* point after scaling is 135 degrees. This will calculate the result from the fullRange times the
* fraction of the supply voltage, plus the offset.
*
* @param channel The analog input channel this potentiometer is plugged into. 0-3 are
* on-board and 4-7 are on the MXP port.
* @param channel The analog input channel this potentiometer is plugged into. 0-3 are on-board
* and 4-7 are on the MXP port.
* @param fullRange The scaling to multiply the fraction by to get a meaningful unit.
* @param offset The offset to add to the scaled value for controlling the zero value
* @param offset The offset to add to the scaled value for controlling the zero value
*/
public AnalogPotentiometer(final int channel, double fullRange, double offset) {
this(new AnalogInput(channel), fullRange, offset);
@@ -44,16 +44,15 @@ public class AnalogPotentiometer implements Potentiometer, Sendable, AutoCloseab
* AnalogPotentiometer constructor.
*
* <p>Use the fullRange and offset values so that the output produces meaningful values. I.E: you
* have a 270 degree potentiometer and you want the output to be degrees with the halfway point
* as 0 degrees. The fullRange value is 270.0(degrees) and the offset is -135.0 since the halfway
* point after scaling is 135 degrees. This will calculate the result from the fullRange times
* the fraction of the supply voltage, plus the offset.
* have a 270 degree potentiometer and you want the output to be degrees with the halfway point as
* 0 degrees. The fullRange value is 270.0(degrees) and the offset is -135.0 since the halfway
* point after scaling is 135 degrees. This will calculate the result from the fullRange times the
* fraction of the supply voltage, plus the offset.
*
* @param input The {@link AnalogInput} this potentiometer is plugged into.
* @param fullRange The angular value (in desired units) representing the full
* 0-5V range of the input.
* @param offset The angular value (in desired units) representing the
* angular output at 0V.
* @param input The {@link AnalogInput} this potentiometer is plugged into.
* @param fullRange The angular value (in desired units) representing the full 0-5V range of the
* input.
* @param offset The angular value (in desired units) representing the angular output at 0V.
*/
public AnalogPotentiometer(final AnalogInput input, double fullRange, double offset) {
SendableRegistry.addLW(this, "AnalogPotentiometer", input.getChannel());
@@ -67,13 +66,13 @@ public class AnalogPotentiometer implements Potentiometer, Sendable, AutoCloseab
/**
* AnalogPotentiometer constructor.
*
* <p>Use the scale value so that the output produces meaningful values. I.E: you
* have a 270 degree potentiometer and you want the output to be degrees with the starting point
* as 0 degrees. The scale value is 270.0(degrees).
* <p>Use the scale value so that the output produces meaningful values. I.E: you have a 270
* degree potentiometer and you want the output to be degrees with the starting point as 0
* degrees. The scale value is 270.0(degrees).
*
* @param channel The analog input channel this potentiometer is plugged into. 0-3 are
* on-board and 4-7 are on the MXP port.
* @param scale The scaling to multiply the voltage by to get a meaningful unit.
* @param channel The analog input channel this potentiometer is plugged into. 0-3 are on-board
* and 4-7 are on the MXP port.
* @param scale The scaling to multiply the voltage by to get a meaningful unit.
*/
public AnalogPotentiometer(final int channel, double scale) {
this(channel, scale, 0);
@@ -98,8 +97,8 @@ public class AnalogPotentiometer implements Potentiometer, Sendable, AutoCloseab
*
* <p>The potentiometer will return a value between 0 and 1.0.
*
* @param channel The analog input channel this potentiometer is plugged into. 0-3 are
* on-board and 4-7 are on the MXP port.
* @param channel The analog input channel this potentiometer is plugged into. 0-3 are on-board
* and 4-7 are on the MXP port.
*/
public AnalogPotentiometer(final int channel) {
this(channel, 1, 0);
@@ -126,8 +125,8 @@ public class AnalogPotentiometer implements Potentiometer, Sendable, AutoCloseab
if (m_analogInput == null) {
return m_offset;
}
return (m_analogInput.getAverageVoltage() / RobotController.getVoltage5V())
* m_fullRange + m_offset;
return (m_analogInput.getAverageVoltage() / RobotController.getVoltage5V()) * m_fullRange
+ m_offset;
}
@Override

View File

@@ -12,14 +12,9 @@ import edu.wpi.first.wpilibj.AnalogTriggerOutput.AnalogTriggerType;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Class for creating and configuring Analog Triggers.
*/
/** Class for creating and configuring Analog Triggers. */
public class AnalogTrigger implements Sendable, AutoCloseable {
/**
* Exceptions dealing with improper operation of the Analog trigger.
*/
/** Exceptions dealing with improper operation of the Analog trigger. */
@SuppressWarnings("serial")
public static class AnalogTriggerException extends RuntimeException {
/**
@@ -30,13 +25,11 @@ public class AnalogTrigger implements Sendable, AutoCloseable {
public AnalogTriggerException(String message) {
super(message);
}
}
/**
* Where the analog trigger is attached.
*/
/** Where the analog trigger is attached. */
protected int m_port;
protected AnalogInput m_analogInput;
protected DutyCycle m_dutyCycle;
protected boolean m_ownsAnalog;
@@ -159,8 +152,7 @@ public class AnalogTrigger implements Sendable, AutoCloseable {
}
/**
* Return the index of the analog trigger. This is the FPGA index of this analog trigger
* instance.
* Return the index of the analog trigger. This is the FPGA index of this analog trigger instance.
*
* @return The index of the analog trigger.
*/

View File

@@ -4,13 +4,13 @@
package edu.wpi.first.wpilibj;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
import edu.wpi.first.hal.AnalogJNI;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
/**
* Class to represent a specific output from an analog trigger. This class is used to get the
* current output value and also as a DigitalSource to provide routing of an output to digital
@@ -38,9 +38,7 @@ import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
* limited.
*/
public class AnalogTriggerOutput extends DigitalSource implements Sendable {
/**
* Exceptions dealing with improper operation of the Analog trigger output.
*/
/** Exceptions dealing with improper operation of the Analog trigger output. */
@SuppressWarnings("serial")
public static class AnalogTriggerOutputException extends RuntimeException {
/**
@@ -62,7 +60,7 @@ public class AnalogTriggerOutput extends DigitalSource implements Sendable {
* <p>Because this class derives from DigitalSource, it can be passed into routing functions for
* Counter, Encoder, etc.
*
* @param trigger The trigger for which this is an output.
* @param trigger The trigger for which this is an output.
* @param outputType An enum that specifies the output on the trigger to represent.
*/
public AnalogTriggerOutput(AnalogTrigger trigger, final AnalogTriggerType outputType) {
@@ -71,8 +69,10 @@ public class AnalogTriggerOutput extends DigitalSource implements Sendable {
m_trigger = trigger;
m_outputType = outputType;
HAL.report(tResourceType.kResourceType_AnalogTriggerOutput,
trigger.getIndex() + 1, outputType.value + 1);
HAL.report(
tResourceType.kResourceType_AnalogTriggerOutput,
trigger.getIndex() + 1,
outputType.value + 1);
}
/**
@@ -104,11 +104,10 @@ public class AnalogTriggerOutput extends DigitalSource implements Sendable {
return true;
}
/**
* Defines the state in which the AnalogTrigger triggers.
*/
/** Defines the state in which the AnalogTrigger triggers. */
public enum AnalogTriggerType {
kInWindow(AnalogJNI.AnalogTriggerType.kInWindow), kState(AnalogJNI.AnalogTriggerType.kState),
kInWindow(AnalogJNI.AnalogTriggerType.kInWindow),
kState(AnalogJNI.AnalogTriggerType.kState),
kRisingPulse(AnalogJNI.AnalogTriggerType.kRisingPulse),
kFallingPulse(AnalogJNI.AnalogTriggerType.kFallingPulse);
@@ -120,6 +119,5 @@ public class AnalogTriggerOutput extends DigitalSource implements Sendable {
}
@Override
public void initSendable(SendableBuilder builder) {
}
public void initSendable(SendableBuilder builder) {}
}

View File

@@ -28,9 +28,7 @@ public class BuiltInAccelerometer implements Accelerometer, Sendable, AutoClosea
SendableRegistry.addLW(this, "BuiltInAccel", 0);
}
/**
* Constructor. The accelerometer will measure +/-8 g-forces
*/
/** Constructor. The accelerometer will measure +/-8 g-forces */
public BuiltInAccelerometer() {
this(Range.k8G);
}
@@ -57,7 +55,6 @@ public class BuiltInAccelerometer implements Accelerometer, Sendable, AutoClosea
case k16G:
default:
throw new IllegalArgumentException(range + " range not supported (use k2G, k4G, or k8G)");
}
AccelerometerJNI.setAccelerometerActive(true);

View File

@@ -4,23 +4,21 @@
package edu.wpi.first.wpilibj;
import java.io.Closeable;
import edu.wpi.first.hal.CANAPIJNI;
import edu.wpi.first.hal.CANData;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import java.io.Closeable;
/**
* High level class for interfacing with CAN devices conforming to
* the standard CAN spec.
* High level class for interfacing with CAN devices conforming to the standard CAN spec.
*
* <p>No packets that can be sent gets blocked by the RoboRIO, so all methods
* work identically in all robot modes.
* <p>No packets that can be sent gets blocked by the RoboRIO, so all methods work identically in
* all robot modes.
*
* <p>All methods are thread safe, however the CANData object passed into the
* read methods and the byte[] passed into the write methods need to not
* be modified for the duration of their respective calls.
* <p>All methods are thread safe, however the CANData object passed into the read methods and the
* byte[] passed into the write methods need to not be modified for the duration of their respective
* calls.
*/
public class CAN implements Closeable {
public static final int kTeamManufacturer = 8;
@@ -29,9 +27,8 @@ public class CAN implements Closeable {
private final int m_handle;
/**
* Create a new CAN communication interface with the specific device ID.
* This uses the team manufacturer and device types.
* The device ID is 6 bits (0-63).
* Create a new CAN communication interface with the specific device ID. This uses the team
* manufacturer and device types. The device ID is 6 bits (0-63).
*
* @param deviceId The device id
*/
@@ -41,22 +38,19 @@ public class CAN implements Closeable {
}
/**
* Create a new CAN communication interface with a specific device ID,
* manufacturer and device type. The device ID is 6 bits, the
* manufacturer is 8 bits, and the device type is 5 bits.
* Create a new CAN communication interface with a specific device ID, manufacturer and device
* type. The device ID is 6 bits, the manufacturer is 8 bits, and the device type is 5 bits.
*
* @param deviceId The device ID
* @param deviceId The device ID
* @param deviceManufacturer The device manufacturer
* @param deviceType The device type
* @param deviceType The device type
*/
public CAN(int deviceId, int deviceManufacturer, int deviceType) {
m_handle = CANAPIJNI.initializeCAN(deviceManufacturer, deviceId, deviceType);
HAL.report(tResourceType.kResourceType_CAN, deviceId + 1);
}
/**
* Closes the CAN communication.
*/
/** Closes the CAN communication. */
@Override
public void close() {
if (m_handle != 0) {
@@ -75,8 +69,8 @@ public class CAN implements Closeable {
}
/**
* Write a repeating packet to the CAN device with a specific ID. This ID is 10 bits.
* The RoboRIO will automatically repeat the packet at the specified interval
* Write a repeating packet to the CAN device with a specific ID. This ID is 10 bits. The RoboRIO
* will automatically repeat the packet at the specified interval
*
* @param data The data to write (8 bytes max)
* @param apiId The API ID to write.
@@ -87,8 +81,8 @@ public class CAN implements Closeable {
}
/**
* Write an RTR frame to the CAN device with a specific ID. This ID is 10 bits.
* The length by spec must match what is returned by the responding device
* Write an RTR frame to the CAN device with a specific ID. This ID is 10 bits. The length by spec
* must match what is returned by the responding device
*
* @param length The length to request (0 to 8)
* @param apiId The API ID to write.
@@ -108,8 +102,8 @@ public class CAN implements Closeable {
}
/**
* Write a repeating packet to the CAN device with a specific ID. This ID is 10 bits.
* The RoboRIO will automatically repeat the packet at the specified interval
* Write a repeating packet to the CAN device with a specific ID. This ID is 10 bits. The RoboRIO
* will automatically repeat the packet at the specified interval
*
* @param data The data to write (8 bytes max)
* @param apiId The API ID to write.
@@ -120,8 +114,8 @@ public class CAN implements Closeable {
}
/**
* Write an RTR frame to the CAN device with a specific ID. This ID is 10 bits.
* The length by spec must match what is returned by the responding device
* Write an RTR frame to the CAN device with a specific ID. This ID is 10 bits. The length by spec
* must match what is returned by the responding device
*
* @param length The length to request (0 to 8)
* @param apiId The API ID to write.
@@ -140,8 +134,8 @@ public class CAN implements Closeable {
}
/**
* Read a new CAN packet. This will only return properly once per packet
* received. Multiple calls without receiving another packet will return false.
* Read a new CAN packet. This will only return properly once per packet received. Multiple calls
* without receiving another packet will return false.
*
* @param apiId The API ID to read.
* @param data Storage for the received data.
@@ -152,8 +146,8 @@ public class CAN implements Closeable {
}
/**
* Read a CAN packet. The will continuously return the last packet received,
* without accounting for packet age.
* Read a CAN packet. The will continuously return the last packet received, without accounting
* for packet age.
*
* @param apiId The API ID to read.
* @param data Storage for the received data.
@@ -164,8 +158,8 @@ public class CAN implements Closeable {
}
/**
* Read a CAN packet. The will return the last packet received until the
* packet is older then the requested timeout. Then it will return false.
* Read a CAN packet. The will return the last packet received until the packet is older then the
* requested timeout. Then it will return false.
*
* @param apiId The API ID to read.
* @param timeoutMs The timeout time for the packet

View File

@@ -4,12 +4,6 @@
package edu.wpi.first.wpilibj;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import edu.wpi.cscore.AxisCamera;
import edu.wpi.cscore.CameraServerJNI;
import edu.wpi.cscore.CvSink;
@@ -29,10 +23,15 @@ import edu.wpi.first.networktables.EntryListenerFlags;
import edu.wpi.first.networktables.NetworkTable;
import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.networktables.NetworkTableInstance;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Hashtable;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Singleton class for creating and keeping camera servers.
* Also publishes camera information to NetworkTables.
* Singleton class for creating and keeping camera servers. Also publishes camera information to
* NetworkTables.
*
* @deprecated Replaced with edu.wpi.first.cameraserver.CameraServer
*/
@@ -40,19 +39,14 @@ import edu.wpi.first.networktables.NetworkTableInstance;
public final class CameraServer {
public static final int kBasePort = 1181;
@Deprecated
public static final int kSize640x480 = 0;
@Deprecated
public static final int kSize320x240 = 1;
@Deprecated
public static final int kSize160x120 = 2;
@Deprecated public static final int kSize640x480 = 0;
@Deprecated public static final int kSize320x240 = 1;
@Deprecated public static final int kSize160x120 = 2;
private static final String kPublishName = "/CameraPublisher";
private static CameraServer server;
/**
* Get the CameraServer instance.
*/
/** Get the CameraServer instance. */
public static synchronized CameraServer getInstance() {
if (server == null) {
server = new CameraServer();
@@ -64,10 +58,10 @@ public final class CameraServer {
private String m_primarySourceName;
private final Map<String, VideoSource> m_sources;
private final Map<String, VideoSink> m_sinks;
private final Map<Integer, NetworkTable> m_tables; // indexed by source handle
private final Map<Integer, NetworkTable> m_tables; // indexed by source handle
private final NetworkTable m_publishTable;
private final VideoListener m_videoListener; //NOPMD
private final int m_tableListener; //NOPMD
private final VideoListener m_videoListener; // NOPMD
private final int m_tableListener; // NOPMD
private int m_nextPort;
private String[] m_addresses;
@@ -76,14 +70,15 @@ public final class CameraServer {
switch (VideoSource.getKindFromInt(CameraServerJNI.getSourceKind(source))) {
case kUsb:
return "usb:" + CameraServerJNI.getUsbCameraPath(source);
case kHttp: {
String[] urls = CameraServerJNI.getHttpCameraUrls(source);
if (urls.length > 0) {
return "ip:" + urls[0];
} else {
return "ip:";
case kHttp:
{
String[] urls = CameraServerJNI.getHttpCameraUrls(source);
if (urls.length > 0) {
return "ip:" + urls[0];
} else {
return "ip:";
}
}
}
case kCv:
// FIXME: Should be "cv:", but LabVIEW dashboard requires "usb:".
// https://github.com/wpilibsuite/allwpilib/issues/407
@@ -119,7 +114,7 @@ public final class CameraServer {
values.add(makeStreamValue(CameraServerJNI.getHostname() + ".local", port));
for (String addr : m_addresses) {
if ("127.0.0.1".equals(addr)) {
continue; // ignore localhost
continue; // ignore localhost
}
values.add(makeStreamValue(addr, port));
}
@@ -132,7 +127,7 @@ public final class CameraServer {
private synchronized String[] getSourceStreamValues(int source) {
// Ignore all but HttpCamera
if (VideoSource.getKindFromInt(CameraServerJNI.getSourceKind(source))
!= VideoSource.Kind.kHttp) {
!= VideoSource.Kind.kHttp) {
return new String[0];
}
@@ -150,7 +145,7 @@ public final class CameraServer {
int sinkSource = CameraServerJNI.getSinkSource(sink);
if (source == sinkSource
&& VideoSink.getKindFromInt(CameraServerJNI.getSinkKind(sink))
== VideoSink.Kind.kMjpeg) {
== VideoSink.Kind.kMjpeg) {
// Add USB-only passthrough
String[] finalValues = Arrays.copyOf(values, values.length + 1);
int port = CameraServerJNI.getMjpegServerPort(sink);
@@ -228,8 +223,14 @@ public final class CameraServer {
/// The returned string is "{width}x{height} {format} {fps} fps".
@SuppressWarnings("MissingJavadocMethod")
private static String videoModeToString(VideoMode mode) {
return mode.width + "x" + mode.height + " " + pixelFormatToString(mode.pixelFormat)
+ " " + mode.fps + " fps";
return mode.width
+ "x"
+ mode.height
+ " "
+ pixelFormatToString(mode.pixelFormat)
+ " "
+ mode.fps
+ " fps";
}
@SuppressWarnings("MissingJavadocMethod")
@@ -268,14 +269,18 @@ public final class CameraServer {
case kEnum:
if (isNew) {
entry.setDefaultDouble(event.value);
table.getEntry(infoName + "/min").setDouble(
CameraServerJNI.getPropertyMin(event.propertyHandle));
table.getEntry(infoName + "/max").setDouble(
CameraServerJNI.getPropertyMax(event.propertyHandle));
table.getEntry(infoName + "/step").setDouble(
CameraServerJNI.getPropertyStep(event.propertyHandle));
table.getEntry(infoName + "/default").setDouble(
CameraServerJNI.getPropertyDefault(event.propertyHandle));
table
.getEntry(infoName + "/min")
.setDouble(CameraServerJNI.getPropertyMin(event.propertyHandle));
table
.getEntry(infoName + "/max")
.setDouble(CameraServerJNI.getPropertyMax(event.propertyHandle));
table
.getEntry(infoName + "/step")
.setDouble(CameraServerJNI.getPropertyStep(event.propertyHandle));
table
.getEntry(infoName + "/default")
.setDouble(CameraServerJNI.getPropertyDefault(event.propertyHandle));
} else {
entry.setDouble(event.value);
}
@@ -295,8 +300,12 @@ public final class CameraServer {
}
}
@SuppressWarnings({"MissingJavadocMethod", "PMD.UnusedLocalVariable", "PMD.ExcessiveMethodLength",
"PMD.NPathComplexity"})
@SuppressWarnings({
"MissingJavadocMethod",
"PMD.UnusedLocalVariable",
"PMD.ExcessiveMethodLength",
"PMD.NPathComplexity"
})
private CameraServer() {
m_defaultUsbDevice = new AtomicInteger();
m_sources = new Hashtable<>();
@@ -318,176 +327,204 @@ public final class CameraServer {
// - "PropertyInfo/{Property}" - Property supporting information
// Listener for video events
m_videoListener = new VideoListener(event -> {
switch (event.kind) {
case kSourceCreated: {
// Create subtable for the camera
NetworkTable table = m_publishTable.getSubTable(event.name);
m_tables.put(event.sourceHandle, table);
table.getEntry("source").setString(makeSourceValue(event.sourceHandle));
table.getEntry("description").setString(
CameraServerJNI.getSourceDescription(event.sourceHandle));
table.getEntry("connected").setBoolean(
CameraServerJNI.isSourceConnected(event.sourceHandle));
table.getEntry("streams").setStringArray(getSourceStreamValues(event.sourceHandle));
try {
VideoMode mode = CameraServerJNI.getSourceVideoMode(event.sourceHandle);
table.getEntry("mode").setDefaultString(videoModeToString(mode));
table.getEntry("modes").setStringArray(getSourceModeValues(event.sourceHandle));
} catch (VideoException ignored) {
// Do nothing. Let the other event handlers update this if there is an error.
}
break;
}
case kSourceDestroyed: {
NetworkTable table = m_tables.get(event.sourceHandle);
if (table != null) {
table.getEntry("source").setString("");
table.getEntry("streams").setStringArray(new String[0]);
table.getEntry("modes").setStringArray(new String[0]);
}
break;
}
case kSourceConnected: {
NetworkTable table = m_tables.get(event.sourceHandle);
if (table != null) {
// update the description too (as it may have changed)
table.getEntry("description").setString(
CameraServerJNI.getSourceDescription(event.sourceHandle));
table.getEntry("connected").setBoolean(true);
}
break;
}
case kSourceDisconnected: {
NetworkTable table = m_tables.get(event.sourceHandle);
if (table != null) {
table.getEntry("connected").setBoolean(false);
}
break;
}
case kSourceVideoModesUpdated: {
NetworkTable table = m_tables.get(event.sourceHandle);
if (table != null) {
table.getEntry("modes").setStringArray(getSourceModeValues(event.sourceHandle));
}
break;
}
case kSourceVideoModeChanged: {
NetworkTable table = m_tables.get(event.sourceHandle);
if (table != null) {
table.getEntry("mode").setString(videoModeToString(event.mode));
}
break;
}
case kSourcePropertyCreated: {
NetworkTable table = m_tables.get(event.sourceHandle);
if (table != null) {
putSourcePropertyValue(table, event, true);
}
break;
}
case kSourcePropertyValueUpdated: {
NetworkTable table = m_tables.get(event.sourceHandle);
if (table != null) {
putSourcePropertyValue(table, event, false);
}
break;
}
case kSourcePropertyChoicesUpdated: {
NetworkTable table = m_tables.get(event.sourceHandle);
if (table != null) {
try {
String[] choices = CameraServerJNI.getEnumPropertyChoices(event.propertyHandle);
table.getEntry("PropertyInfo/" + event.name + "/choices").setStringArray(choices);
} catch (VideoException ignored) {
// ignore
}
}
break;
}
case kSinkSourceChanged:
case kSinkCreated:
case kSinkDestroyed:
case kNetworkInterfacesChanged: {
m_addresses = CameraServerJNI.getNetworkInterfaces();
updateStreamValues();
break;
}
default:
break;
}
}, 0x4fff, true);
m_videoListener =
new VideoListener(
event -> {
switch (event.kind) {
case kSourceCreated:
{
// Create subtable for the camera
NetworkTable table = m_publishTable.getSubTable(event.name);
m_tables.put(event.sourceHandle, table);
table.getEntry("source").setString(makeSourceValue(event.sourceHandle));
table
.getEntry("description")
.setString(CameraServerJNI.getSourceDescription(event.sourceHandle));
table
.getEntry("connected")
.setBoolean(CameraServerJNI.isSourceConnected(event.sourceHandle));
table
.getEntry("streams")
.setStringArray(getSourceStreamValues(event.sourceHandle));
try {
VideoMode mode = CameraServerJNI.getSourceVideoMode(event.sourceHandle);
table.getEntry("mode").setDefaultString(videoModeToString(mode));
table
.getEntry("modes")
.setStringArray(getSourceModeValues(event.sourceHandle));
} catch (VideoException ignored) {
// Do nothing. Let the other event handlers update this if there is an error.
}
break;
}
case kSourceDestroyed:
{
NetworkTable table = m_tables.get(event.sourceHandle);
if (table != null) {
table.getEntry("source").setString("");
table.getEntry("streams").setStringArray(new String[0]);
table.getEntry("modes").setStringArray(new String[0]);
}
break;
}
case kSourceConnected:
{
NetworkTable table = m_tables.get(event.sourceHandle);
if (table != null) {
// update the description too (as it may have changed)
table
.getEntry("description")
.setString(CameraServerJNI.getSourceDescription(event.sourceHandle));
table.getEntry("connected").setBoolean(true);
}
break;
}
case kSourceDisconnected:
{
NetworkTable table = m_tables.get(event.sourceHandle);
if (table != null) {
table.getEntry("connected").setBoolean(false);
}
break;
}
case kSourceVideoModesUpdated:
{
NetworkTable table = m_tables.get(event.sourceHandle);
if (table != null) {
table
.getEntry("modes")
.setStringArray(getSourceModeValues(event.sourceHandle));
}
break;
}
case kSourceVideoModeChanged:
{
NetworkTable table = m_tables.get(event.sourceHandle);
if (table != null) {
table.getEntry("mode").setString(videoModeToString(event.mode));
}
break;
}
case kSourcePropertyCreated:
{
NetworkTable table = m_tables.get(event.sourceHandle);
if (table != null) {
putSourcePropertyValue(table, event, true);
}
break;
}
case kSourcePropertyValueUpdated:
{
NetworkTable table = m_tables.get(event.sourceHandle);
if (table != null) {
putSourcePropertyValue(table, event, false);
}
break;
}
case kSourcePropertyChoicesUpdated:
{
NetworkTable table = m_tables.get(event.sourceHandle);
if (table != null) {
try {
String[] choices =
CameraServerJNI.getEnumPropertyChoices(event.propertyHandle);
table
.getEntry("PropertyInfo/" + event.name + "/choices")
.setStringArray(choices);
} catch (VideoException ignored) {
// ignore
}
}
break;
}
case kSinkSourceChanged:
case kSinkCreated:
case kSinkDestroyed:
case kNetworkInterfacesChanged:
{
m_addresses = CameraServerJNI.getNetworkInterfaces();
updateStreamValues();
break;
}
default:
break;
}
},
0x4fff,
true);
// Listener for NetworkTable events
// We don't currently support changing settings via NT due to
// synchronization issues, so just update to current setting if someone
// else tries to change it.
m_tableListener = NetworkTableInstance.getDefault().addEntryListener(kPublishName + "/",
event -> {
String relativeKey = event.name.substring(kPublishName.length() + 1);
m_tableListener =
NetworkTableInstance.getDefault()
.addEntryListener(
kPublishName + "/",
event -> {
String relativeKey = event.name.substring(kPublishName.length() + 1);
// get source (sourceName/...)
int subKeyIndex = relativeKey.indexOf('/');
if (subKeyIndex == -1) {
return;
}
String sourceName = relativeKey.substring(0, subKeyIndex);
VideoSource source = m_sources.get(sourceName);
if (source == null) {
return;
}
// get source (sourceName/...)
int subKeyIndex = relativeKey.indexOf('/');
if (subKeyIndex == -1) {
return;
}
String sourceName = relativeKey.substring(0, subKeyIndex);
VideoSource source = m_sources.get(sourceName);
if (source == null) {
return;
}
// get subkey
relativeKey = relativeKey.substring(subKeyIndex + 1);
// get subkey
relativeKey = relativeKey.substring(subKeyIndex + 1);
// handle standard names
String propName;
if ("mode".equals(relativeKey)) {
// reset to current mode
event.getEntry().setString(videoModeToString(source.getVideoMode()));
return;
} else if (relativeKey.startsWith("Property/")) {
propName = relativeKey.substring(9);
} else if (relativeKey.startsWith("RawProperty/")) {
propName = relativeKey.substring(12);
} else {
return; // ignore
}
// handle standard names
String propName;
if ("mode".equals(relativeKey)) {
// reset to current mode
event.getEntry().setString(videoModeToString(source.getVideoMode()));
return;
} else if (relativeKey.startsWith("Property/")) {
propName = relativeKey.substring(9);
} else if (relativeKey.startsWith("RawProperty/")) {
propName = relativeKey.substring(12);
} else {
return; // ignore
}
// everything else is a property
VideoProperty property = source.getProperty(propName);
switch (property.getKind()) {
case kNone:
return;
case kBoolean:
// reset to current setting
event.getEntry().setBoolean(property.get() != 0);
return;
case kInteger:
case kEnum:
// reset to current setting
event.getEntry().setDouble(property.get());
return;
case kString:
// reset to current setting
event.getEntry().setString(property.getString());
return;
default:
return;
}
}, EntryListenerFlags.kImmediate | EntryListenerFlags.kUpdate);
// everything else is a property
VideoProperty property = source.getProperty(propName);
switch (property.getKind()) {
case kNone:
return;
case kBoolean:
// reset to current setting
event.getEntry().setBoolean(property.get() != 0);
return;
case kInteger:
case kEnum:
// reset to current setting
event.getEntry().setDouble(property.get());
return;
case kString:
// reset to current setting
event.getEntry().setString(property.getString());
return;
default:
return;
}
},
EntryListenerFlags.kImmediate | EntryListenerFlags.kUpdate);
}
/**
* Start automatically capturing images to send to the dashboard.
*
* <p>You should call this method to see a camera feed on the dashboard.
* If you also want to perform vision processing on the roboRIO, use
* getVideo() to get access to the camera images.
* <p>You should call this method to see a camera feed on the dashboard. If you also want to
* perform vision processing on the roboRIO, use getVideo() to get access to the camera images.
*
* <p>The first time this overload is called, it calls
* {@link #startAutomaticCapture(int)} with device 0, creating a camera
* named "USB Camera 0". Subsequent calls increment the device number
* <p>The first time this overload is called, it calls {@link #startAutomaticCapture(int)} with
* device 0, creating a camera named "USB Camera 0". Subsequent calls increment the device number
* (e.g. 1, 2, etc).
*/
public UsbCamera startAutomaticCapture() {
@@ -499,8 +536,8 @@ public final class CameraServer {
/**
* Start automatically capturing images to send to the dashboard.
*
* <p>This overload calls {@link #startAutomaticCapture(String, int)} with
* a name of "USB Camera {dev}".
* <p>This overload calls {@link #startAutomaticCapture(String, int)} with a name of "USB Camera
* {dev}".
*
* @param dev The device number of the camera interface
*/
@@ -538,8 +575,7 @@ public final class CameraServer {
}
/**
* Start automatically capturing images to send to the dashboard from
* an existing camera.
* Start automatically capturing images to send to the dashboard from an existing camera.
*
* @param camera Camera
*/
@@ -552,8 +588,7 @@ public final class CameraServer {
/**
* Adds an Axis IP camera.
*
* <p>This overload calls {@link #addAxisCamera(String, String)} with
* name "Axis Camera".
* <p>This overload calls {@link #addAxisCamera(String, String)} with name "Axis Camera".
*
* @param host Camera host IP or DNS name (e.g. "10.x.y.11")
*/
@@ -564,8 +599,7 @@ public final class CameraServer {
/**
* Adds an Axis IP camera.
*
* <p>This overload calls {@link #addAxisCamera(String, String[])} with
* name "Axis Camera".
* <p>This overload calls {@link #addAxisCamera(String, String[])} with name "Axis Camera".
*
* @param hosts Array of Camera host IPs/DNS names
*/
@@ -602,11 +636,11 @@ public final class CameraServer {
}
/**
* Get OpenCV access to the primary camera feed. This allows you to
* get images from the camera for image processing on the roboRIO.
* Get OpenCV access to the primary camera feed. This allows you to get images from the camera for
* image processing on the roboRIO.
*
* <p>This is only valid to call after a camera feed has been added
* with startAutomaticCapture() or addServer().
* <p>This is only valid to call after a camera feed has been added with startAutomaticCapture()
* or addServer().
*/
public CvSink getVideo() {
VideoSource source;
@@ -623,8 +657,8 @@ public final class CameraServer {
}
/**
* Get OpenCV access to the specified camera. This allows you to get
* images from the camera for image processing on the roboRIO.
* Get OpenCV access to the specified camera. This allows you to get images from the camera for
* image processing on the roboRIO.
*
* @param camera Camera (e.g. as returned by startAutomaticCapture).
*/
@@ -649,8 +683,8 @@ public final class CameraServer {
}
/**
* Get OpenCV access to the specified camera. This allows you to get
* images from the camera for image processing on the roboRIO.
* Get OpenCV access to the specified camera. This allows you to get images from the camera for
* image processing on the roboRIO.
*
* @param name Camera name
*/
@@ -666,8 +700,8 @@ public final class CameraServer {
}
/**
* Create a MJPEG stream with OpenCV input. This can be called to pass custom
* annotated images to the dashboard.
* Create a MJPEG stream with OpenCV input. This can be called to pass custom annotated images to
* the dashboard.
*
* @param name Name to give the stream
* @param width Width of the image being sent
@@ -729,8 +763,8 @@ public final class CameraServer {
/**
* Get server for the primary camera feed.
*
* <p>This is only valid to call after a camera feed has been added
* with startAutomaticCapture() or addServer().
* <p>This is only valid to call after a camera feed has been added with startAutomaticCapture()
* or addServer().
*/
public VideoSink getServer() {
synchronized (this) {

View File

@@ -26,7 +26,7 @@ public class Compressor implements Sendable, AutoCloseable {
private byte m_module;
/**
* Makes a new instance of the compressor using the provided CAN device ID. Use this constructor
* Makes a new instance of the compressor using the provided CAN device ID. Use this constructor
* when you have more than one PCM.
*
* @param module The PCM CAN device ID (0 - 62 inclusive)
@@ -133,8 +133,7 @@ public class Compressor implements Sendable, AutoCloseable {
}
/**
* If PCM sticky fault is set : Compressor is disabled due to compressor current being too
* high.
* If PCM sticky fault is set : Compressor is disabled due to compressor current being too high.
*
* @return true if PCM sticky fault is set.
*/
@@ -184,8 +183,8 @@ public class Compressor implements Sendable, AutoCloseable {
* Clear ALL sticky faults inside PCM that Compressor is wired to.
*
* <p>If a sticky fault is set, then it will be persistently cleared. The compressor might
* momentarily disable while the flags are being cleared. Doo not call this method too
* frequently, otherwise normal compressor functionality may be prevented.
* momentarily disable while the flags are being cleared. Doo not call this method too frequently,
* otherwise normal compressor functionality may be prevented.
*
* <p>If no sticky faults are set then this call will have no effect.
*/
@@ -205,13 +204,16 @@ public class Compressor implements Sendable, AutoCloseable {
@Override
public void initSendable(SendableBuilder builder) {
builder.setSmartDashboardType("Compressor");
builder.addBooleanProperty("Enabled", this::enabled, value -> {
if (value) {
start();
} else {
stop();
}
});
builder.addBooleanProperty(
"Enabled",
this::enabled,
value -> {
if (value) {
start();
} else {
stop();
}
});
builder.addBooleanProperty("Pressure switch", this::getPressureSwitchValue, null);
}
}

View File

@@ -13,9 +13,7 @@ package edu.wpi.first.wpilibj;
*/
@Deprecated(since = "2020", forRemoval = true)
public interface Controller {
/**
* Allows the control loop to run.
*/
/** Allows the control loop to run. */
void enable();
/**

View File

@@ -4,8 +4,8 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
import static java.util.Objects.requireNonNull;
import edu.wpi.first.hal.CounterJNI;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
@@ -13,40 +13,29 @@ import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.AnalogTriggerOutput.AnalogTriggerType;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
import static java.util.Objects.requireNonNull;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/**
* Class for counting the number of ticks on a digital input channel.
*
* <p>This is a general purpose class for counting repetitive events. It can return the number of
* counts, the period of the most recent cycle, and detect when the signal being counted has
* stopped by supplying a maximum cycle time.
* counts, the period of the most recent cycle, and detect when the signal being counted has stopped
* by supplying a maximum cycle time.
*
* <p>All counters will immediately start counting - reset() them if you need them to be zeroed
* before use.
*/
public class Counter implements CounterBase, PIDSource, Sendable, AutoCloseable {
/**
* Mode determines how and what the counter counts.
*/
/** Mode determines how and what the counter counts. */
public enum Mode {
/**
* mode: two pulse.
*/
/** mode: two pulse. */
kTwoPulse(0),
/**
* mode: semi period.
*/
/** mode: semi period. */
kSemiperiod(1),
/**
* mode: pulse length.
*/
/** mode: pulse length. */
kPulseLength(2),
/**
* mode: external direction.
*/
/** mode: external direction. */
kExternalDirection(3);
public final int value;
@@ -65,9 +54,7 @@ public class Counter implements CounterBase, PIDSource, Sendable, AutoCloseable
private PIDSourceType m_pidSource;
private double m_distancePerPulse; // distance of travel for each tick
/**
* Create an instance of a counter with the given mode.
*/
/** Create an instance of a counter with the given mode. */
public Counter(final Mode mode) {
ByteBuffer index = ByteBuffer.allocateDirect(4);
// set the byte order
@@ -131,12 +118,15 @@ public class Counter implements CounterBase, PIDSource, Sendable, AutoCloseable
* <p>The counter will start counting immediately.
*
* @param encodingType which edges to count
* @param upSource first source to count
* @param downSource second source for direction
* @param inverted true to invert the count
* @param upSource first source to count
* @param downSource second source for direction
* @param inverted true to invert the count
*/
public Counter(EncodingType encodingType, DigitalSource upSource, DigitalSource downSource,
boolean inverted) {
public Counter(
EncodingType encodingType,
DigitalSource upSource,
DigitalSource downSource,
boolean inverted) {
this(Mode.kExternalDirection);
requireNonNullParam(encodingType, "encodingType", "Counter");
@@ -225,15 +215,15 @@ public class Counter implements CounterBase, PIDSource, Sendable, AutoCloseable
m_allocatedUpSource = false;
}
m_upSource = source;
CounterJNI.setCounterUpSource(m_counter, source.getPortHandleForRouting(),
source.getAnalogTriggerTypeForRouting());
CounterJNI.setCounterUpSource(
m_counter, source.getPortHandleForRouting(), source.getAnalogTriggerTypeForRouting());
}
/**
* Set the up counting source to be an analog trigger.
*
* @param analogTrigger The analog trigger object that is used for the Up Source
* @param triggerType The analog trigger output that will trigger the counter.
* @param triggerType The analog trigger output that will trigger the counter.
*/
public void setUpSource(AnalogTrigger analogTrigger, AnalogTriggerType triggerType) {
requireNonNullParam(analogTrigger, "analogTrigger", "setUpSource");
@@ -247,7 +237,7 @@ public class Counter implements CounterBase, PIDSource, Sendable, AutoCloseable
* Set the edge sensitivity on an up counting source. Set the up source to either detect rising
* edges or falling edges.
*
* @param risingEdge true to count rising edge
* @param risingEdge true to count rising edge
* @param fallingEdge true to count falling edge
*/
public void setUpSourceEdge(boolean risingEdge, boolean fallingEdge) {
@@ -257,9 +247,7 @@ public class Counter implements CounterBase, PIDSource, Sendable, AutoCloseable
CounterJNI.setCounterUpSourceEdge(m_counter, risingEdge, fallingEdge);
}
/**
* Disable the up counting source to the counter.
*/
/** Disable the up counting source to the counter. */
public void clearUpSource() {
if (m_upSource != null && m_allocatedUpSource) {
m_upSource.close();
@@ -294,8 +282,8 @@ public class Counter implements CounterBase, PIDSource, Sendable, AutoCloseable
m_downSource.close();
m_allocatedDownSource = false;
}
CounterJNI.setCounterDownSource(m_counter, source.getPortHandleForRouting(),
source.getAnalogTriggerTypeForRouting());
CounterJNI.setCounterDownSource(
m_counter, source.getPortHandleForRouting(), source.getAnalogTriggerTypeForRouting());
m_downSource = source;
}
@@ -303,7 +291,7 @@ public class Counter implements CounterBase, PIDSource, Sendable, AutoCloseable
* Set the down counting source to be an analog trigger.
*
* @param analogTrigger The analog trigger object that is used for the Down Source
* @param triggerType The analog trigger output that will trigger the counter.
* @param triggerType The analog trigger output that will trigger the counter.
*/
public void setDownSource(AnalogTrigger analogTrigger, AnalogTriggerType triggerType) {
requireNonNullParam(analogTrigger, "analogTrigger", "setDownSource");
@@ -317,7 +305,7 @@ public class Counter implements CounterBase, PIDSource, Sendable, AutoCloseable
* Set the edge sensitivity on a down counting source. Set the down source to either detect rising
* edges or falling edges.
*
* @param risingEdge true to count the rising edge
* @param risingEdge true to count the rising edge
* @param fallingEdge true to count the falling edge
*/
public void setDownSourceEdge(boolean risingEdge, boolean fallingEdge) {
@@ -326,9 +314,7 @@ public class Counter implements CounterBase, PIDSource, Sendable, AutoCloseable
CounterJNI.setCounterDownSourceEdge(m_counter, risingEdge, fallingEdge);
}
/**
* Disable the down counting source to the counter.
*/
/** Disable the down counting source to the counter. */
public void clearDownSource() {
if (m_downSource != null && m_allocatedDownSource) {
m_downSource.close();
@@ -369,7 +355,7 @@ public class Counter implements CounterBase, PIDSource, Sendable, AutoCloseable
* is most useful for direction sensitive gear tooth sensors.
*
* @param threshold The pulse length beyond which the counter counts the opposite direction. Units
* are seconds.
* are seconds.
*/
public void setPulseLengthMode(double threshold) {
CounterJNI.setCounterPulseLengthMode(m_counter, threshold);

View File

@@ -13,21 +13,13 @@ package edu.wpi.first.wpilibj;
* before use.
*/
public interface CounterBase {
/**
* The number of edges for the counterbase to increment or decrement on.
*/
/** The number of edges for the counterbase to increment or decrement on. */
enum EncodingType {
/**
* Count only the rising edge.
*/
/** Count only the rising edge. */
k1X(0),
/**
* Count both the rising and falling edge.
*/
/** Count both the rising and falling edge. */
k2X(1),
/**
* Count rising and falling on both channels.
*/
/** Count rising and falling on both channels. */
k4X(2);
public final int value;
@@ -44,9 +36,7 @@ public interface CounterBase {
*/
int get();
/**
* Reset the count to zero.
*/
/** Reset the count to zero. */
void reset();
/**

View File

@@ -12,25 +12,25 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
* Digilent DMC 60 Speed Controller.
*
* <p>Note that the DMC uses the following bounds for PWM values. These values should work
* reasonably well for most controllers, but if users experience issues such as asymmetric
* behavior around the deadband or inability to saturate the controller in either direction,
* calibration is recommended. The calibration procedure can be found in the DMC 60 User Manual
* available from Digilent.
* reasonably well for most controllers, but if users experience issues such as asymmetric behavior
* around the deadband or inability to saturate the controller in either direction, calibration is
* recommended. The calibration procedure can be found in the DMC 60 User Manual available from
* Digilent.
*
* <p><ul>
* <li>2.004ms = full "forward"
* <li>1.520ms = the "high end" of the deadband range
* <li>1.500ms = center of the deadband range (off)
* <li>1.480ms = the "low end" of the deadband range
* <li>0.997ms = full "reverse"
* <ul>
* <li>2.004ms = full "forward"
* <li>1.520ms = the "high end" of the deadband range
* <li>1.500ms = center of the deadband range (off)
* <li>1.480ms = the "low end" of the deadband range
* <li>0.997ms = full "reverse"
* </ul>
*/
public class DMC60 extends PWMSpeedController {
/**
* Constructor.
*
* @param channel The PWM channel that the DMC60 is attached to. 0-9 are
* on-board, 10-19 are on the MXP port
* @param channel The PWM channel that the DMC60 is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
public DMC60(final int channel) {
super(channel);

View File

@@ -4,14 +4,13 @@
package edu.wpi.first.wpilibj;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import edu.wpi.first.hal.DigitalGlitchFilterJNI;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Class to enable glitch filtering on a set of digital inputs. This class will manage adding and
@@ -19,9 +18,7 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
* that an input must remain high or low before it is classified as high or low.
*/
public class DigitalGlitchFilter implements Sendable, AutoCloseable {
/**
* Configures the Digital Glitch Filter to its default settings.
*/
/** Configures the Digital Glitch Filter to its default settings. */
public DigitalGlitchFilter() {
synchronized (m_mutex) {
int index = 0;
@@ -31,8 +28,7 @@ public class DigitalGlitchFilter implements Sendable, AutoCloseable {
if (index != m_filterAllocated.length) {
m_channelIndex = index;
m_filterAllocated[index] = true;
HAL.report(tResourceType.kResourceType_DigitalGlitchFilter,
m_channelIndex + 1, 0);
HAL.report(tResourceType.kResourceType_DigitalGlitchFilter, m_channelIndex + 1, 0);
SendableRegistry.addLW(this, "DigitalGlitchFilter", index);
}
}
@@ -59,8 +55,8 @@ public class DigitalGlitchFilter implements Sendable, AutoCloseable {
int selected = DigitalGlitchFilterJNI.getFilterSelect(input.getPortHandleForRouting());
if (selected != channelIndex) {
throw new IllegalStateException("DigitalGlitchFilterJNI.setFilterSelect("
+ channelIndex + ") failed -> " + selected);
throw new IllegalStateException(
"DigitalGlitchFilterJNI.setFilterSelect(" + channelIndex + ") failed -> " + selected);
}
}
}
@@ -140,8 +136,7 @@ public class DigitalGlitchFilter implements Sendable, AutoCloseable {
* @param nanoseconds The number of nanoseconds.
*/
public void setPeriodNanoSeconds(long nanoseconds) {
int fpgaCycles = (int) (nanoseconds * SensorUtil.kSystemClockTicksPerMicrosecond / 4
/ 1000);
int fpgaCycles = (int) (nanoseconds * SensorUtil.kSystemClockTicksPerMicrosecond / 4 / 1000);
setPeriodCycles(fpgaCycles);
}
@@ -164,14 +159,12 @@ public class DigitalGlitchFilter implements Sendable, AutoCloseable {
public long getPeriodNanoSeconds() {
int fpgaCycles = getPeriodCycles();
return (long) fpgaCycles * 1000L
/ (long) (SensorUtil.kSystemClockTicksPerMicrosecond / 4);
return (long) fpgaCycles * 1000L / (long) (SensorUtil.kSystemClockTicksPerMicrosecond / 4);
}
@Override
@SuppressWarnings("PMD.UnusedFormalParameter")
public void initSendable(SendableBuilder builder) {
}
public void initSendable(SendableBuilder builder) {}
private int m_channelIndex = -1;
private static final Lock m_mutex = new ReentrantLock(true);

View File

@@ -23,11 +23,10 @@ public class DigitalOutput extends DigitalSource implements Sendable, AutoClosea
private int m_handle;
/**
* Create an instance of a digital output. Create an instance of a digital output given a
* channel.
* Create an instance of a digital output. Create an instance of a digital output given a channel.
*
* @param channel the DIO channel to use for the digital output. 0-9 are on-board, 10-25 are on
* the MXP
* the MXP
*/
public DigitalOutput(int channel) {
SensorUtil.checkDigitalChannel(channel);
@@ -150,8 +149,7 @@ public class DigitalOutput extends DigitalSource implements Sendable, AutoClosea
* Change the duty-cycle that is being generated on the line.
*
* <p>The resolution of the duty cycle is 8-bit for low frequencies (1kHz or less) but is reduced
* the
* higher the frequency of the PWM signal is.
* the higher the frequency of the PWM signal is.
*
* @param dutyCycle The duty-cycle to change to. [0..1]
*/

View File

@@ -18,9 +18,7 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
* controlled by two separate channels.
*/
public class DoubleSolenoid extends SolenoidBase implements Sendable, AutoCloseable {
/**
* Possible values for a DoubleSolenoid.
*/
/** Possible values for a DoubleSolenoid. */
public enum Value {
kOff,
kForward,
@@ -45,12 +43,12 @@ public class DoubleSolenoid extends SolenoidBase implements Sendable, AutoClosea
/**
* Constructor.
*
* @param moduleNumber The module number of the solenoid module to use.
* @param moduleNumber The module number of the solenoid module to use.
* @param forwardChannel The forward channel on the module to control (0..7).
* @param reverseChannel The reverse channel on the module to control (0..7).
*/
public DoubleSolenoid(final int moduleNumber, final int forwardChannel,
final int reverseChannel) {
public DoubleSolenoid(
final int moduleNumber, final int forwardChannel, final int reverseChannel) {
super(moduleNumber);
SensorUtil.checkSolenoidModule(m_moduleNumber);
@@ -74,10 +72,8 @@ public class DoubleSolenoid extends SolenoidBase implements Sendable, AutoClosea
m_forwardMask = (byte) (1 << forwardChannel);
m_reverseMask = (byte) (1 << reverseChannel);
HAL.report(tResourceType.kResourceType_Solenoid, forwardChannel + 1,
m_moduleNumber + 1);
HAL.report(tResourceType.kResourceType_Solenoid, reverseChannel + 1,
m_moduleNumber + 1);
HAL.report(tResourceType.kResourceType_Solenoid, forwardChannel + 1, m_moduleNumber + 1);
HAL.report(tResourceType.kResourceType_Solenoid, reverseChannel + 1, m_moduleNumber + 1);
SendableRegistry.addLW(this, "DoubleSolenoid", m_moduleNumber, forwardChannel);
}
@@ -112,7 +108,6 @@ public class DoubleSolenoid extends SolenoidBase implements Sendable, AutoClosea
break;
default:
throw new AssertionError("Illegal value: " + value);
}
SolenoidJNI.setSolenoid(m_forwardHandle, forward);
@@ -182,14 +177,17 @@ public class DoubleSolenoid extends SolenoidBase implements Sendable, AutoClosea
builder.setSmartDashboardType("Double Solenoid");
builder.setActuator(true);
builder.setSafeState(() -> set(Value.kOff));
builder.addStringProperty("Value", () -> get().name().substring(1), value -> {
if ("Forward".equals(value)) {
set(Value.kForward);
} else if ("Reverse".equals(value)) {
set(Value.kReverse);
} else {
set(Value.kOff);
}
});
builder.addStringProperty(
"Value",
() -> get().name().substring(1),
value -> {
if ("Forward".equals(value)) {
set(Value.kForward);
} else if ("Reverse".equals(value)) {
set(Value.kReverse);
} else {
set(Value.kOff);
}
});
}
}

View File

@@ -4,12 +4,6 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteBuffer;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import edu.wpi.first.hal.AllianceStationID;
import edu.wpi.first.hal.ControlWord;
import edu.wpi.first.hal.HAL;
@@ -17,16 +11,22 @@ import edu.wpi.first.hal.MatchInfoData;
import edu.wpi.first.networktables.NetworkTable;
import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.networktables.NetworkTableInstance;
import java.nio.ByteBuffer;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Provide access to the network communication data to / from the Driver Station.
*/
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.ExcessiveClassLength",
"PMD.ExcessivePublicCount", "PMD.GodClass", "PMD.TooManyFields"})
/** Provide access to the network communication data to / from the Driver Station. */
@SuppressWarnings({
"PMD.CyclomaticComplexity",
"PMD.ExcessiveClassLength",
"PMD.ExcessivePublicCount",
"PMD.GodClass",
"PMD.TooManyFields"
})
public class DriverStation {
/**
* Number of Joystick Ports.
*/
/** Number of Joystick Ports. */
public static final int kJoystickPorts = 6;
private static class HALJoystickButtons {
@@ -55,15 +55,18 @@ public class DriverStation {
}
}
/**
* The robot alliance that the robot is a part of.
*/
/** The robot alliance that the robot is a part of. */
public enum Alliance {
Red, Blue, Invalid
Red,
Blue,
Invalid
}
public enum MatchType {
None, Practice, Qualification, Elimination
None,
Practice,
Qualification,
Elimination
}
private static final double JOYSTICK_UNPLUGGED_MESSAGE_INTERVAL = 1.0;
@@ -85,39 +88,55 @@ public class DriverStation {
private static class MatchDataSender {
@SuppressWarnings("MemberName")
NetworkTable table;
@SuppressWarnings("MemberName")
NetworkTableEntry typeMetadata;
@SuppressWarnings("MemberName")
NetworkTableEntry gameSpecificMessage;
@SuppressWarnings("MemberName")
NetworkTableEntry eventName;
@SuppressWarnings("MemberName")
NetworkTableEntry matchNumber;
@SuppressWarnings("MemberName")
NetworkTableEntry replayNumber;
@SuppressWarnings("MemberName")
NetworkTableEntry matchType;
@SuppressWarnings("MemberName")
NetworkTableEntry alliance;
@SuppressWarnings("MemberName")
NetworkTableEntry station;
@SuppressWarnings("MemberName")
NetworkTableEntry controlWord;
@SuppressWarnings("MemberName")
boolean oldIsRedAlliance = true;
@SuppressWarnings("MemberName")
int oldStationNumber = 1;
@SuppressWarnings("MemberName")
String oldEventName = "";
@SuppressWarnings("MemberName")
String oldGameSpecificMessage = "";
@SuppressWarnings("MemberName")
int oldMatchNumber;
@SuppressWarnings("MemberName")
int oldReplayNumber;
@SuppressWarnings("MemberName")
int oldMatchType;
@SuppressWarnings("MemberName")
int oldControlWord;
@@ -251,6 +270,7 @@ public class DriverStation {
// Internal Driver Station thread
@SuppressWarnings("PMD.SingularField")
private final Thread m_thread;
private volatile boolean m_threadKeepAlive = true;
private final ReentrantLock m_cacheDataMutex = new ReentrantLock();
@@ -317,16 +337,13 @@ public class DriverStation {
m_thread.start();
}
/**
* Kill the thread.
*/
/** Kill the thread. */
public void release() {
m_threadKeepAlive = false;
}
/**
* Report error to Driver Station. Optionally appends Stack trace
* to error message.
* Report error to Driver Station. Optionally appends Stack trace to error message.
*
* @param printTrace If true, append stack trace to error string
*/
@@ -335,8 +352,7 @@ public class DriverStation {
}
/**
* Report error to Driver Station. Appends provided stack trace
* to error message.
* Report error to Driver Station. Appends provided stack trace to error message.
*
* @param stackTrace The stack trace to append
*/
@@ -345,8 +361,7 @@ public class DriverStation {
}
/**
* Report warning to Driver Station. Optionally appends Stack
* trace to warning message.
* Report warning to Driver Station. Optionally appends Stack trace to warning message.
*
* @param printTrace If true, append stack trace to warning string
*/
@@ -355,8 +370,7 @@ public class DriverStation {
}
/**
* Report warning to Driver Station. Appends provided stack
* trace to warning message.
* Report warning to Driver Station. Appends provided stack trace to warning message.
*
* @param stackTrace The stack trace to append
*/
@@ -364,18 +378,22 @@ public class DriverStation {
reportErrorImpl(false, 1, error, stackTrace);
}
private static void reportErrorImpl(boolean isError, int code, String error, boolean
printTrace) {
private static void reportErrorImpl(boolean isError, int code, String error, boolean printTrace) {
reportErrorImpl(isError, code, error, printTrace, Thread.currentThread().getStackTrace(), 3);
}
private static void reportErrorImpl(boolean isError, int code, String error,
StackTraceElement[] stackTrace) {
private static void reportErrorImpl(
boolean isError, int code, String error, StackTraceElement[] stackTrace) {
reportErrorImpl(isError, code, error, true, stackTrace, 0);
}
private static void reportErrorImpl(boolean isError, int code, String error,
boolean printTrace, StackTraceElement[] stackTrace, int stackTraceFirst) {
private static void reportErrorImpl(
boolean isError,
int code,
String error,
boolean printTrace,
StackTraceElement[] stackTrace,
int stackTraceFirst) {
String locString;
if (stackTrace.length >= stackTraceFirst + 1) {
locString = stackTrace[stackTraceFirst].toString();
@@ -401,7 +419,7 @@ public class DriverStation {
/**
* The state of one joystick button. Button indexes begin at 1.
*
* @param stick The joystick to read.
* @param stick The joystick to read.
* @param button The button index, beginning at 1.
* @return The state of the joystick button.
*/
@@ -423,15 +441,19 @@ public class DriverStation {
m_cacheDataMutex.unlock();
}
reportJoystickUnpluggedWarning("Joystick Button " + button + " on port " + stick
+ " not available, check if controller is plugged in");
reportJoystickUnpluggedWarning(
"Joystick Button "
+ button
+ " on port "
+ stick
+ " not available, check if controller is plugged in");
return false;
}
/**
* Whether one joystick button was pressed since the last check. Button indexes begin at 1.
*
* @param stick The joystick to read.
* @param stick The joystick to read.
* @param button The button index, beginning at 1.
* @return Whether the joystick button was pressed since the last check.
*/
@@ -459,16 +481,19 @@ public class DriverStation {
m_cacheDataMutex.unlock();
}
reportJoystickUnpluggedWarning("Joystick Button " + button + " on port " + stick
+ " not available, check if controller is plugged in");
reportJoystickUnpluggedWarning(
"Joystick Button "
+ button
+ " on port "
+ stick
+ " not available, check if controller is plugged in");
return false;
}
/**
* Whether one joystick button was released since the last check. Button indexes
* begin at 1.
* Whether one joystick button was released since the last check. Button indexes begin at 1.
*
* @param stick The joystick to read.
* @param stick The joystick to read.
* @param button The button index, beginning at 1.
* @return Whether the joystick button was released since the last check.
*/
@@ -496,8 +521,12 @@ public class DriverStation {
m_cacheDataMutex.unlock();
}
reportJoystickUnpluggedWarning("Joystick Button " + button + " on port " + stick
+ " not available, check if controller is plugged in");
reportJoystickUnpluggedWarning(
"Joystick Button "
+ button
+ " on port "
+ stick
+ " not available, check if controller is plugged in");
return false;
}
@@ -506,7 +535,7 @@ public class DriverStation {
* to the specified port.
*
* @param stick The joystick to read.
* @param axis The analog axis value to read from the joystick.
* @param axis The analog axis value to read from the joystick.
* @return The value of the axis on the joystick.
*/
public double getStickAxis(int stick, int axis) {
@@ -526,8 +555,12 @@ public class DriverStation {
m_cacheDataMutex.unlock();
}
reportJoystickUnpluggedWarning("Joystick axis " + axis + " on port " + stick
+ " not available, check if controller is plugged in");
reportJoystickUnpluggedWarning(
"Joystick axis "
+ axis
+ " on port "
+ stick
+ " not available, check if controller is plugged in");
return 0.0;
}
@@ -553,8 +586,12 @@ public class DriverStation {
m_cacheDataMutex.unlock();
}
reportJoystickUnpluggedWarning("Joystick POV " + pov + " on port " + stick
+ " not available, check if controller is plugged in");
reportJoystickUnpluggedWarning(
"Joystick POV "
+ pov
+ " on port "
+ stick
+ " not available, check if controller is plugged in");
return -1;
}
@@ -694,16 +731,16 @@ public class DriverStation {
/**
* Returns if a joystick is connected to the Driver Station.
*
* <p>This makes a best effort guess by looking at the reported number of axis,
* buttons, and POVs attached.
* <p>This makes a best effort guess by looking at the reported number of axis, buttons, and POVs
* attached.
*
* @param stick The joystick port number
* @return true if a joystick is connected
*/
public boolean isJoystickConnected(int stick) {
return getStickAxisCount(stick) > 0
|| getStickButtonCount(stick) > 0
|| getStickPOVCount(stick) > 0;
|| getStickButtonCount(stick) > 0
|| getStickPOVCount(stick) > 0;
}
/**
@@ -784,7 +821,8 @@ public class DriverStation {
public boolean isOperatorControlEnabled() {
synchronized (m_controlWordMutex) {
updateControlWord(false);
return !m_controlWordCache.getAutonomous() && !m_controlWordCache.getTest()
return !m_controlWordCache.getAutonomous()
&& !m_controlWordCache.getTest()
&& m_controlWordCache.getEnabled();
}
}
@@ -985,8 +1023,8 @@ public class DriverStation {
/**
* Wait for new data from the driver station.
*
* <p>Checks if new control data has arrived since the last waitForData call
* on the current thread. If new data has not arrived, returns immediately.
* <p>Checks if new control data has arrived since the last waitForData call on the current
* thread. If new data has not arrived, returns immediately.
*/
public void waitForData() {
waitForData(0);
@@ -996,8 +1034,8 @@ public class DriverStation {
* Wait for new data or for timeout, which ever comes first. If timeout is 0, wait for new data
* only.
*
* <p>Checks if new control data has arrived since the last waitForData call
* on the current thread. If new data has not arrived, returns immediately.
* <p>Checks if new control data has arrived since the last waitForData call on the current
* thread. If new data has not arrived, returns immediately.
*
* @param timeout The maximum time in seconds to wait.
* @return true if there is new data, otherwise false
@@ -1017,8 +1055,8 @@ public class DriverStation {
long now = RobotController.getFPGATime();
if (now < startTime + timeoutMicros) {
// We still have time to wait
boolean signaled = m_waitForDataCond.await(startTime + timeoutMicros - now,
TimeUnit.MICROSECONDS);
boolean signaled =
m_waitForDataCond.await(startTime + timeoutMicros - now, TimeUnit.MICROSECONDS);
if (!signaled) {
// Return false if a timeout happened
return false;
@@ -1046,8 +1084,8 @@ public class DriverStation {
* Return the approximate match time. The FMS does not send an official match time to the robots,
* but does send an approximate match time. The value will count down the time remaining in the
* current period (auto or teleop). Warning: This is not an official time (so it cannot be used to
* dispute ref calls or guarantee that a function will trigger before the match ends) The
* Practice Match function of the DS approximates the behavior seen on the field.
* dispute ref calls or guarantee that a function will trigger before the match ends) The Practice
* Match function of the DS approximates the behavior seen on the field.
*
* @return Time remaining in current match period (auto or teleop) in seconds
*/
@@ -1099,9 +1137,7 @@ public class DriverStation {
m_userInTest = entering;
}
/**
* Forces waitForData() to return immediately.
*/
/** Forces waitForData() to return immediately. */
public void wakeupWaitForData() {
m_waitForDataMutex.lock();
m_waitForDataCount++;
@@ -1110,9 +1146,9 @@ public class DriverStation {
}
/**
* Allows the user to specify whether they want joystick connection warnings
* to be printed to the console. This setting is ignored when the FMS is
* connected -- warnings will always be on in that scenario.
* Allows the user to specify whether they want joystick connection warnings to be printed to the
* console. This setting is ignored when the FMS is connected -- warnings will always be on in
* that scenario.
*
* @param silence Whether warning messages should be silenced.
*/
@@ -1121,8 +1157,8 @@ public class DriverStation {
}
/**
* Returns whether joystick connection warnings are silenced. This will
* always return false when connected to the FMS.
* Returns whether joystick connection warnings are silenced. This will always return false when
* connected to the FMS.
*
* @return Whether joystick connection warnings are silenced.
*/
@@ -1213,9 +1249,7 @@ public class DriverStation {
}
}
/**
* Provides the service routine for the DS polling m_thread.
*/
/** Provides the service routine for the DS polling m_thread. */
private void run() {
int safetyCounter = 0;
while (m_threadKeepAlive) {
@@ -1247,8 +1281,8 @@ public class DriverStation {
}
/**
* Updates the data in the control word cache. Updates if the force parameter is set, or if
* 50ms have passed since the last update.
* Updates the data in the control word cache. Updates if the force parameter is set, or if 50ms
* have passed since the last update.
*
* @param force True to force an update to the cache, otherwise update if 50ms have passed.
*/

View File

@@ -13,13 +13,11 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Class to read a duty cycle PWM input.
*
* <p>PWM input signals are specified with a frequency and a ratio of high to low
* in that frequency. There are 8 of these in the roboRIO, and they can be
* attached to any {@link DigitalSource}.
*
* <p>These can be combined as the input of an AnalogTrigger to a Counter in order
* to implement rollover checking.
* <p>PWM input signals are specified with a frequency and a ratio of high to low in that frequency.
* There are 8 of these in the roboRIO, and they can be attached to any {@link DigitalSource}.
*
* <p>These can be combined as the input of an AnalogTrigger to a Counter in order to implement
* rollover checking.
*/
public class DutyCycle implements Sendable, AutoCloseable {
// Explicitly package private
@@ -35,8 +33,10 @@ public class DutyCycle implements Sendable, AutoCloseable {
* @param digitalSource The DigitalSource to use.
*/
public DutyCycle(DigitalSource digitalSource) {
m_handle = DutyCycleJNI.initialize(digitalSource.getPortHandleForRouting(),
digitalSource.getAnalogTriggerTypeForRouting());
m_handle =
DutyCycleJNI.initialize(
digitalSource.getPortHandleForRouting(),
digitalSource.getAnalogTriggerTypeForRouting());
m_source = digitalSource;
int index = getFPGAIndex();
@@ -44,9 +44,7 @@ public class DutyCycle implements Sendable, AutoCloseable {
SendableRegistry.addLW(this, "Duty Cycle", index);
}
/**
* Close the DutyCycle and free all resources.
*/
/** Close the DutyCycle and free all resources. */
@Override
public void close() {
DutyCycleJNI.free(m_handle);
@@ -75,8 +73,7 @@ public class DutyCycle implements Sendable, AutoCloseable {
/**
* Get the raw output ratio of the duty cycle signal.
*
* <p>0 means always low, an output equal to getOutputScaleFactor() means always
* high.
* <p>0 means always low, an output equal to getOutputScaleFactor() means always high.
*
* @return output ratio in raw units
*/
@@ -87,9 +84,8 @@ public class DutyCycle implements Sendable, AutoCloseable {
/**
* Get the scale factor of the output.
*
* <p>An output equal to this value is always high, and then linearly scales down
* to 0. Divide the result of getOutputRaw by this in order to get the
* percentage between 0 and 1.
* <p>An output equal to this value is always high, and then linearly scales down to 0. Divide the
* result of getOutputRaw by this in order to get the percentage between 0 and 1.
*
* @return the output scale factor
*/
@@ -116,6 +112,5 @@ public class DutyCycle implements Sendable, AutoCloseable {
builder.setSmartDashboardType("Duty Cycle");
builder.addDoubleProperty("Frequency", this::getFrequency, null);
builder.addDoubleProperty("Output", this::getOutput, null);
}
}

View File

@@ -12,9 +12,8 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Class for supporting duty cycle/PWM encoders, such as the US Digital MA3 with
* PWM Output, the CTRE Mag Encoder, the Rev Hex Encoder, and the AM Mag
* Encoder.
* Class for supporting duty cycle/PWM encoders, such as the US Digital MA3 with PWM Output, the
* CTRE Mag Encoder, the Rev Hex Encoder, and the AM Mag Encoder.
*/
public class DutyCycleEncoder implements Sendable, AutoCloseable {
private final DutyCycle m_dutyCycle;
@@ -70,8 +69,8 @@ public class DutyCycleEncoder implements Sendable, AutoCloseable {
if (m_simDevice != null) {
m_simPosition = m_simDevice.createDouble("position", SimDevice.Direction.kInput, 0.0);
m_simDistancePerRotation = m_simDevice.createDouble("distance_per_rot",
SimDevice.Direction.kOutput, 1.0);
m_simDistancePerRotation =
m_simDevice.createDouble("distance_per_rot", SimDevice.Direction.kOutput, 1.0);
m_simIsConnected = m_simDevice.createBoolean("connected", SimDevice.Direction.kInput, true);
} else {
m_counter = new Counter();
@@ -119,9 +118,9 @@ public class DutyCycleEncoder implements Sendable, AutoCloseable {
/**
* Get the offset of position relative to the last reset.
*
* <p>getPositionInRotation() - getPositionOffset() will give an encoder absolute
* position relative to the last reset. This could potentially be negative,
* which needs to be accounted for.
* <p>getPositionInRotation() - getPositionOffset() will give an encoder absolute position
* relative to the last reset. This could potentially be negative, which needs to be accounted
* for.
*
* @return the position offset
*/
@@ -130,11 +129,10 @@ public class DutyCycleEncoder implements Sendable, AutoCloseable {
}
/**
* Set the distance per rotation of the encoder. This sets the multiplier used
* to determine the distance driven based on the rotation value from the
* encoder. Set this value based on the how far the mechanism travels in 1
* rotation of the encoder, and factor in gearing reductions following the
* encoder shaft. This distance can be in any units you like, linear or angular.
* Set the distance per rotation of the encoder. This sets the multiplier used to determine the
* distance driven based on the rotation value from the encoder. Set this value based on the how
* far the mechanism travels in 1 rotation of the encoder, and factor in gearing reductions
* following the encoder shaft. This distance can be in any units you like, linear or angular.
*
* @param distancePerRotation the distance per rotation of the encoder
*/
@@ -145,16 +143,15 @@ public class DutyCycleEncoder implements Sendable, AutoCloseable {
/**
* Get the distance per rotation for this encoder.
*
* @return The scale factor that will be used to convert rotation to useful
* units.
* @return The scale factor that will be used to convert rotation to useful units.
*/
public double getDistancePerRotation() {
return m_distancePerRotation;
}
/**
* Get the distance the sensor has driven since the last reset as scaled by the
* value from {@link #setDistancePerRotation(double)}.
* Get the distance the sensor has driven since the last reset as scaled by the value from {@link
* #setDistancePerRotation(double)}.
*
* @return The distance driven since the last reset
*/
@@ -171,9 +168,7 @@ public class DutyCycleEncoder implements Sendable, AutoCloseable {
return m_dutyCycle.getFrequency();
}
/**
* Reset the Encoder distance to zero.
*/
/** Reset the Encoder distance to zero. */
public void reset() {
if (m_counter != null) {
m_counter.reset();
@@ -184,9 +179,9 @@ public class DutyCycleEncoder implements Sendable, AutoCloseable {
/**
* Get if the sensor is connected
*
* <p>This uses the duty cycle frequency to determine if the sensor is connected.
* By default, a value of 100 Hz is used as the threshold, and this value can be
* changed with {@link #setConnectedFrequencyThreshold(int)}.
* <p>This uses the duty cycle frequency to determine if the sensor is connected. By default, a
* value of 100 Hz is used as the threshold, and this value can be changed with {@link
* #setConnectedFrequencyThreshold(int)}.
*
* @return true if the sensor is connected
*/
@@ -198,8 +193,7 @@ public class DutyCycleEncoder implements Sendable, AutoCloseable {
}
/**
* Change the frequency threshold for detecting connection used by
* {@link #isConnected()}.
* Change the frequency threshold for detecting connection used by {@link #isConnected()}.
*
* @param frequency the minimum frequency in Hz.
*/

View File

@@ -4,6 +4,8 @@
package edu.wpi.first.wpilibj;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
import edu.wpi.first.hal.EncoderJNI;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
@@ -12,8 +14,6 @@ import edu.wpi.first.hal.util.AllocationException;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
/**
* Class to read quadrature encoders.
*
@@ -29,7 +29,10 @@ import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
*/
public class Encoder implements CounterBase, PIDSource, Sendable, AutoCloseable {
public enum IndexingType {
kResetWhileHigh(0), kResetWhileLow(1), kResetOnFallingEdge(2), kResetOnRisingEdge(3);
kResetWhileHigh(0),
kResetWhileLow(1),
kResetOnFallingEdge(2),
kResetOnRisingEdge(3);
public final int value;
@@ -38,18 +41,13 @@ public class Encoder implements CounterBase, PIDSource, Sendable, AutoCloseable
}
}
/**
* The a source.
*/
/** The a source. */
protected DigitalSource m_aSource; // the A phase of the quad encoder
/**
* The b source.
*/
/** The b source. */
protected DigitalSource m_bSource; // the B phase of the quad encoder
/**
* The index source.
*/
/** The index source. */
protected DigitalSource m_indexSource; // Index on some encoders
private boolean m_allocatedA;
private boolean m_allocatedB;
private boolean m_allocatedI;
@@ -57,7 +55,6 @@ public class Encoder implements CounterBase, PIDSource, Sendable, AutoCloseable
private int m_encoder; // the HAL encoder object
/**
* Common initialization code for Encoders. This code allocates resources for Encoders and is
* common to all constructors.
@@ -67,9 +64,14 @@ public class Encoder implements CounterBase, PIDSource, Sendable, AutoCloseable
* @param reverseDirection If true, counts down instead of up (this is all relative)
*/
private void initEncoder(boolean reverseDirection, final EncodingType type) {
m_encoder = EncoderJNI.initializeEncoder(m_aSource.getPortHandleForRouting(),
m_aSource.getAnalogTriggerTypeForRouting(), m_bSource.getPortHandleForRouting(),
m_bSource.getAnalogTriggerTypeForRouting(), reverseDirection, type.value);
m_encoder =
EncoderJNI.initializeEncoder(
m_aSource.getPortHandleForRouting(),
m_aSource.getAnalogTriggerTypeForRouting(),
m_bSource.getPortHandleForRouting(),
m_bSource.getAnalogTriggerTypeForRouting(),
reverseDirection,
type.value);
m_pidSource = PIDSourceType.kDisplacement;
@@ -83,10 +85,10 @@ public class Encoder implements CounterBase, PIDSource, Sendable, AutoCloseable
*
* <p>The encoder will start counting immediately.
*
* @param channelA The a channel DIO channel. 0-9 are on-board, 10-25 are on the MXP port
* @param channelB The b channel DIO channel. 0-9 are on-board, 10-25 are on the MXP port
* @param channelA The a channel DIO channel. 0-9 are on-board, 10-25 are on the MXP port
* @param channelB The b channel DIO channel. 0-9 are on-board, 10-25 are on the MXP port
* @param reverseDirection represents the orientation of the encoder and inverts the output values
* if necessary so forward represents positive values.
* if necessary so forward represents positive values.
*/
public Encoder(final int channelA, final int channelB, boolean reverseDirection) {
this(channelA, channelB, reverseDirection, EncodingType.k4X);
@@ -109,19 +111,21 @@ public class Encoder implements CounterBase, PIDSource, Sendable, AutoCloseable
*
* <p>The encoder will start counting immediately.
*
* @param channelA The a channel digital input channel.
* @param channelB The b channel digital input channel.
* @param channelA The a channel digital input channel.
* @param channelB The b channel digital input channel.
* @param reverseDirection represents the orientation of the encoder and inverts the output values
* if necessary so forward represents positive values.
* @param encodingType either k1X, k2X, or k4X to indicate 1X, 2X or 4X decoding. If 4X is
* selected, then an encoder FPGA object is used and the returned counts
* will be 4x the encoder spec'd value since all rising and falling edges
* are counted. If 1X or 2X are selected then a m_counter object will be
* used and the returned value will either exactly match the spec'd count
* or be double (2x) the spec'd count.
* if necessary so forward represents positive values.
* @param encodingType either k1X, k2X, or k4X to indicate 1X, 2X or 4X decoding. If 4X is
* selected, then an encoder FPGA object is used and the returned counts will be 4x the
* encoder spec'd value since all rising and falling edges are counted. If 1X or 2X are
* selected then a m_counter object will be used and the returned value will either exactly
* match the spec'd count or be double (2x) the spec'd count.
*/
public Encoder(final int channelA, final int channelB, boolean reverseDirection,
final EncodingType encodingType) {
public Encoder(
final int channelA,
final int channelB,
boolean reverseDirection,
final EncodingType encodingType) {
requireNonNullParam(encodingType, "encodingType", "Encoder");
m_allocatedA = true;
@@ -140,14 +144,14 @@ public class Encoder implements CounterBase, PIDSource, Sendable, AutoCloseable
*
* <p>The encoder will start counting immediately.
*
* @param channelA The a channel digital input channel.
* @param channelB The b channel digital input channel.
* @param indexChannel The index channel digital input channel.
* @param channelA The a channel digital input channel.
* @param channelB The b channel digital input channel.
* @param indexChannel The index channel digital input channel.
* @param reverseDirection represents the orientation of the encoder and inverts the output values
* if necessary so forward represents positive values.
* if necessary so forward represents positive values.
*/
public Encoder(final int channelA, final int channelB, final int indexChannel,
boolean reverseDirection) {
public Encoder(
final int channelA, final int channelB, final int indexChannel, boolean reverseDirection) {
this(channelA, channelB, reverseDirection);
m_allocatedI = true;
m_indexSource = new DigitalInput(indexChannel);
@@ -161,8 +165,8 @@ public class Encoder implements CounterBase, PIDSource, Sendable, AutoCloseable
*
* <p>The encoder will start counting immediately.
*
* @param channelA The a channel digital input channel.
* @param channelB The b channel digital input channel.
* @param channelA The a channel digital input channel.
* @param channelB The b channel digital input channel.
* @param indexChannel The index channel digital input channel.
*/
public Encoder(final int channelA, final int channelB, final int indexChannel) {
@@ -176,10 +180,10 @@ public class Encoder implements CounterBase, PIDSource, Sendable, AutoCloseable
*
* <p>The encoder will start counting immediately.
*
* @param sourceA The source that should be used for the a channel.
* @param sourceB the source that should be used for the b channel.
* @param sourceA The source that should be used for the a channel.
* @param sourceB the source that should be used for the b channel.
* @param reverseDirection represents the orientation of the encoder and inverts the output values
* if necessary so forward represents positive values.
* if necessary so forward represents positive values.
*/
public Encoder(DigitalSource sourceA, DigitalSource sourceB, boolean reverseDirection) {
this(sourceA, sourceB, reverseDirection, EncodingType.k4X);
@@ -206,19 +210,21 @@ public class Encoder implements CounterBase, PIDSource, Sendable, AutoCloseable
*
* <p>The encoder will start counting immediately.
*
* @param sourceA The source that should be used for the a channel.
* @param sourceB the source that should be used for the b channel.
* @param sourceA The source that should be used for the a channel.
* @param sourceB the source that should be used for the b channel.
* @param reverseDirection represents the orientation of the encoder and inverts the output values
* if necessary so forward represents positive values.
* @param encodingType either k1X, k2X, or k4X to indicate 1X, 2X or 4X decoding. If 4X is
* selected, then an encoder FPGA object is used and the returned counts
* will be 4x the encoder spec'd value since all rising and falling edges
* are counted. If 1X or 2X are selected then a m_counter object will be
* used and the returned value will either exactly match the spec'd count
* or be double (2x) the spec'd count.
* if necessary so forward represents positive values.
* @param encodingType either k1X, k2X, or k4X to indicate 1X, 2X or 4X decoding. If 4X is
* selected, then an encoder FPGA object is used and the returned counts will be 4x the
* encoder spec'd value since all rising and falling edges are counted. If 1X or 2X are
* selected then a m_counter object will be used and the returned value will either exactly
* match the spec'd count or be double (2x) the spec'd count.
*/
public Encoder(DigitalSource sourceA, DigitalSource sourceB, boolean reverseDirection,
final EncodingType encodingType) {
public Encoder(
DigitalSource sourceA,
DigitalSource sourceB,
boolean reverseDirection,
final EncodingType encodingType) {
requireNonNullParam(sourceA, "sourceA", "Encoder");
requireNonNullParam(sourceB, "sourceB", "Encoder");
requireNonNullParam(encodingType, "encodingType", "Encoder");
@@ -238,14 +244,17 @@ public class Encoder implements CounterBase, PIDSource, Sendable, AutoCloseable
*
* <p>The encoder will start counting immediately.
*
* @param sourceA The source that should be used for the a channel.
* @param sourceB the source that should be used for the b channel.
* @param indexSource the source that should be used for the index channel.
* @param sourceA The source that should be used for the a channel.
* @param sourceB the source that should be used for the b channel.
* @param indexSource the source that should be used for the index channel.
* @param reverseDirection represents the orientation of the encoder and inverts the output values
* if necessary so forward represents positive values.
* if necessary so forward represents positive values.
*/
public Encoder(DigitalSource sourceA, DigitalSource sourceB, DigitalSource indexSource,
boolean reverseDirection) {
public Encoder(
DigitalSource sourceA,
DigitalSource sourceB,
DigitalSource indexSource,
boolean reverseDirection) {
this(sourceA, sourceB, reverseDirection);
m_allocatedI = false;
m_indexSource = indexSource;
@@ -259,8 +268,8 @@ public class Encoder implements CounterBase, PIDSource, Sendable, AutoCloseable
*
* <p>The encoder will start counting immediately.
*
* @param sourceA The source that should be used for the a channel.
* @param sourceB the source that should be used for the b channel.
* @param sourceA The source that should be used for the a channel.
* @param sourceB the source that should be used for the b channel.
* @param indexSource the source that should be used for the index channel.
*/
public Encoder(DigitalSource sourceA, DigitalSource sourceB, DigitalSource indexSource) {
@@ -330,9 +339,7 @@ public class Encoder implements CounterBase, PIDSource, Sendable, AutoCloseable
return EncoderJNI.getEncoder(m_encoder);
}
/**
* Reset the Encoder distance to zero. Resets the current count to zero on the encoder.
*/
/** Reset the Encoder distance to zero. Resets the current count to zero on the encoder. */
@Override
public void reset() {
EncoderJNI.resetEncoder(m_encoder);
@@ -361,7 +368,7 @@ public class Encoder implements CounterBase, PIDSource, Sendable, AutoCloseable
* compensates for the decoding type.
*
* @param maxPeriod The maximum time between rising and falling edges before the FPGA will report
* the device stopped. This is expressed in seconds.
* the device stopped. This is expressed in seconds.
*/
@Override
public void setMaxPeriod(double maxPeriod) {
@@ -414,7 +421,7 @@ public class Encoder implements CounterBase, PIDSource, Sendable, AutoCloseable
* Set the minimum rate of the device before the hardware reports it stopped.
*
* @param minRate The minimum rate. The units are in distance per second as scaled by the value
* from setDistancePerPulse().
* from setDistancePerPulse().
*/
public void setMinRate(double minRate) {
EncoderJNI.setEncoderMinRate(m_encoder, minRate);
@@ -532,7 +539,7 @@ public class Encoder implements CounterBase, PIDSource, Sendable, AutoCloseable
* resets.
*
* @param channel A DIO channel to set as the encoder index
* @param type The state that will cause the encoder to reset
* @param type The state that will cause the encoder to reset
*/
public void setIndexSource(int channel, IndexingType type) {
if (m_allocatedI) {
@@ -549,11 +556,14 @@ public class Encoder implements CounterBase, PIDSource, Sendable, AutoCloseable
* resets.
*
* @param source A digital source to set as the encoder index
* @param type The state that will cause the encoder to reset
* @param type The state that will cause the encoder to reset
*/
public void setIndexSource(DigitalSource source, IndexingType type) {
EncoderJNI.setEncoderIndexSource(m_encoder, source.getPortHandleForRouting(),
source.getAnalogTriggerTypeForRouting(), type.value);
EncoderJNI.setEncoderIndexSource(
m_encoder,
source.getPortHandleForRouting(),
source.getAnalogTriggerTypeForRouting(),
type.value);
}
/**

View File

@@ -7,18 +7,18 @@ package edu.wpi.first.wpilibj;
import java.io.File;
/**
* Class for interacting with the Filesystem, particularly, interacting with
* FRC-related paths on the system, such as the launch and deploy directories.
* Class for interacting with the Filesystem, particularly, interacting with FRC-related paths on
* the system, such as the launch and deploy directories.
*
* <p>This class is primarily used for obtaining resources in src/main/deploy, and
* the RoboRIO path /home/lvuser in a simulation-compatible way.</p>
* <p>This class is primarily used for obtaining resources in src/main/deploy, and the RoboRIO path
* /home/lvuser in a simulation-compatible way.
*/
public final class Filesystem {
private Filesystem() {}
/**
* Obtains the current working path that the program was launched with.
* This is analogous to the `pwd` command on unix.
* Obtains the current working path that the program was launched with. This is analogous to the
* `pwd` command on unix.
*
* @return The current working directory (launch directory)
*/
@@ -27,9 +27,8 @@ public final class Filesystem {
}
/**
* Obtains the operating directory of the program. On the roboRIO, this is
* /home/lvuser. In simulation, it is where the simulation was launched from
* (`pwd`).
* Obtains the operating directory of the program. On the roboRIO, this is /home/lvuser. In
* simulation, it is where the simulation was launched from (`pwd`).
*
* @return The operating directory
*/
@@ -42,10 +41,10 @@ public final class Filesystem {
}
/**
* Obtains the deploy directory of the program, which is the remote location
* src/main/deploy is deployed to by default. On the roboRIO, this is
* /home/lvuser/deploy. In simulation, it is where the simulation was launched
* from, in the subdirectory "src/main/deploy" (`pwd`/src/main/deploy).
* Obtains the deploy directory of the program, which is the remote location src/main/deploy is
* deployed to by default. On the roboRIO, this is /home/lvuser/deploy. In simulation, it is where
* the simulation was launched from, in the subdirectory "src/main/deploy"
* (`pwd`/src/main/deploy).
*
* @return The deploy directory
*/
@@ -53,8 +52,8 @@ public final class Filesystem {
if (RobotBase.isReal()) {
return new File(getOperatingDirectory(), "deploy");
} else {
return new File(getOperatingDirectory(), "src" + File.separator + "main"
+ File.separator + "deploy");
return new File(
getOperatingDirectory(), "src" + File.separator + "main" + File.separator + "deploy");
}
}
}

View File

@@ -15,15 +15,13 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
* timing in the FPGA to sense direction.
*
* @deprecated The only sensor this works with is no longer available and no teams use it according
* to FMS usage reporting.
* to FMS usage reporting.
*/
@Deprecated(since = "2020", forRemoval = true)
public class GearTooth extends Counter {
private static final double kGearToothThreshold = 55e-6;
/**
* Common code called by the constructors.
*/
/** Common code called by the constructors. */
public void enableDirectionSensing(boolean directionSensitive) {
if (directionSensitive) {
setPulseLengthMode(kGearToothThreshold);
@@ -44,10 +42,10 @@ public class GearTooth extends Counter {
/**
* Construct a GearTooth sensor given a channel.
*
* @param channel The DIO channel that the sensor is connected to. 0-9 are on-board,
* 10-25 are on the MXP port
* @param channel The DIO channel that the sensor is connected to. 0-9 are on-board, 10-25 are on
* the MXP port
* @param directionSensitive True to enable the pulse length decoding in hardware to specify count
* direction.
* direction.
*/
public GearTooth(final int channel, boolean directionSensitive) {
super(channel);
@@ -64,9 +62,9 @@ public class GearTooth extends Counter {
* Construct a GearTooth sensor given a digital input. This should be used when sharing digital
* inputs.
*
* @param source An existing DigitalSource object (such as a DigitalInput)
* @param source An existing DigitalSource object (such as a DigitalInput)
* @param directionSensitive True to enable the pulse length decoding in hardware to specify count
* direction.
* direction.
*/
public GearTooth(DigitalSource source, boolean directionSensitive) {
super(source);

View File

@@ -4,20 +4,16 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.HAL;
import java.util.HashMap;
import java.util.Map;
import edu.wpi.first.hal.HAL;
/**
* GenericHID Interface.
*/
/** GenericHID Interface. */
public abstract class GenericHID {
/**
* Represents a rumble output on the JoyStick.
*/
/** Represents a rumble output on the JoyStick. */
public enum RumbleType {
kLeftRumble, kRightRumble
kLeftRumble,
kRightRumble
}
public enum HIDType {
@@ -40,6 +36,7 @@ public abstract class GenericHID {
kHID1stPerson(24);
public final int value;
@SuppressWarnings("PMD.UseConcurrentHashMap")
private static final Map<Integer, HIDType> map = new HashMap<>();
@@ -58,11 +55,10 @@ public abstract class GenericHID {
}
}
/**
* Which hand the Human Interface Device is associated with.
*/
/** Which hand the Human Interface Device is associated with. */
public enum Hand {
kLeft(0), kRight(1);
kLeft(0),
kRight(1);
public final int value;
@@ -122,8 +118,8 @@ public abstract class GenericHID {
* <p>The buttons are returned in a single 16 bit value with one bit representing the state of
* each button. The appropriate button is returned as a boolean value.
*
* <p>This method returns true if the button is being held down at the time
* that this method is being called.
* <p>This method returns true if the button is being held down at the time that this method is
* being called.
*
* @param button The button number to be read (starting at 1)
* @return The state of the button.
@@ -133,12 +129,11 @@ public abstract class GenericHID {
}
/**
* Whether the button was pressed since the last check. Button indexes begin at
* 1.
* Whether the button was pressed since the last check. Button indexes begin at 1.
*
* <p>This method returns true if the button went from not pressed to held down
* since the last time this method was called. This is useful if you only
* want to call a function once when you press the button.
* <p>This method returns true if the button went from not pressed to held down since the last
* time this method was called. This is useful if you only want to call a function once when you
* press the button.
*
* @param button The button index, beginning at 1.
* @return Whether the button was pressed since the last check.
@@ -148,12 +143,11 @@ public abstract class GenericHID {
}
/**
* Whether the button was released since the last check. Button indexes begin at
* 1.
* Whether the button was released since the last check. Button indexes begin at 1.
*
* <p>This method returns true if the button went from held down to not pressed
* since the last time this method was called. This is useful if you only
* want to call a function once when you release the button.
* <p>This method returns true if the button went from held down to not pressed since the last
* time this method was called. This is useful if you only want to call a function once when you
* release the button.
*
* @param button The button index, beginning at 1.
* @return Whether the button was released since the last check.
@@ -198,16 +192,12 @@ public abstract class GenericHID {
return m_ds.getStickAxisCount(m_port);
}
/**
* For the current HID, return the number of POVs.
*/
/** For the current HID, return the number of POVs. */
public int getPOVCount() {
return m_ds.getStickPOVCount(m_port);
}
/**
* For the current HID, return the number of buttons.
*/
/** For the current HID, return the number of buttons. */
public int getButtonCount() {
return m_ds.getStickButtonCount(m_port);
}
@@ -261,7 +251,7 @@ public abstract class GenericHID {
* Set a single HID output value for the HID.
*
* @param outputNumber The index of the output to set (1-32)
* @param value The value to set the output to
* @param value The value to set the output to
*/
public void setOutput(int outputNumber, boolean value) {
m_outputs = (m_outputs & ~(1 << (outputNumber - 1))) | ((value ? 1 : 0) << (outputNumber - 1));
@@ -282,7 +272,7 @@ public abstract class GenericHID {
* Set the rumble output for the HID. The DS currently supports 2 rumble values, left rumble and
* right rumble.
*
* @param type Which rumble value to set
* @param type Which rumble value to set
* @param value The normalized value (0 to 1) to set the rumble to
*/
public void setRumble(RumbleType type, double value) {

View File

@@ -7,9 +7,7 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.interfaces.Gyro;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
/**
* GyroBase is the common base class for Gyro implementations such as AnalogGyro.
*/
/** GyroBase is the common base class for Gyro implementations such as AnalogGyro. */
public abstract class GyroBase implements Gyro, PIDSource, Sendable {
private PIDSourceType m_pidSource = PIDSourceType.kDisplacement;

View File

@@ -4,14 +4,13 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteBuffer;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.I2CJNI;
import edu.wpi.first.hal.util.BoundaryException;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
import java.nio.ByteBuffer;
/**
* I2C bus interface class.
@@ -22,7 +21,8 @@ import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
@SuppressWarnings("PMD.GodClass")
public class I2C implements AutoCloseable {
public enum Port {
kOnboard(0), kMXP(1);
kOnboard(0),
kMXP(1);
public final int value;
@@ -37,7 +37,7 @@ public class I2C implements AutoCloseable {
/**
* Constructor.
*
* @param port The I2C port the device is connected to.
* @param port The I2C port the device is connected to.
* @param deviceAddress The address of the device on the I2C bus.
*/
public I2C(Port port, int deviceAddress) {
@@ -58,18 +58,18 @@ public class I2C implements AutoCloseable {
* Generic transaction.
*
* <p>This is a lower-level interface to the I2C hardware giving you more control over each
* transaction. If you intend to write multiple bytes in the same transaction and do not
* plan to receive anything back, use writeBulk() instead. Calling this with a receiveSize
* of 0 will result in an error.
* transaction. If you intend to write multiple bytes in the same transaction and do not plan to
* receive anything back, use writeBulk() instead. Calling this with a receiveSize of 0 will
* result in an error.
*
* @param dataToSend Buffer of data to send as part of the transaction.
* @param sendSize Number of bytes to send as part of the transaction.
* @param dataToSend Buffer of data to send as part of the transaction.
* @param sendSize Number of bytes to send as part of the transaction.
* @param dataReceived Buffer to read data into.
* @param receiveSize Number of bytes to read from the device.
* @param receiveSize Number of bytes to read from the device.
* @return Transfer Aborted... false for success, true for aborted.
*/
public synchronized boolean transaction(byte[] dataToSend, int sendSize,
byte[] dataReceived, int receiveSize) {
public synchronized boolean transaction(
byte[] dataToSend, int sendSize, byte[] dataReceived, int receiveSize) {
if (dataToSend.length < sendSize) {
throw new IllegalArgumentException("dataToSend is too small, must be at least " + sendSize);
}
@@ -77,8 +77,14 @@ public class I2C implements AutoCloseable {
throw new IllegalArgumentException(
"dataReceived is too small, must be at least " + receiveSize);
}
return I2CJNI.i2CTransactionB(m_port, (byte) m_deviceAddress, dataToSend,
(byte) sendSize, dataReceived, (byte) receiveSize) < 0;
return I2CJNI.i2CTransactionB(
m_port,
(byte) m_deviceAddress,
dataToSend,
(byte) sendSize,
dataReceived,
(byte) receiveSize)
< 0;
}
/**
@@ -87,15 +93,15 @@ public class I2C implements AutoCloseable {
* <p>This is a lower-level interface to the I2C hardware giving you more control over each
* transaction.
*
* @param dataToSend Buffer of data to send as part of the transaction.
* @param sendSize Number of bytes to send as part of the transaction.
* @param dataToSend Buffer of data to send as part of the transaction.
* @param sendSize Number of bytes to send as part of the transaction.
* @param dataReceived Buffer to read data into.
* @param receiveSize Number of bytes to read from the device.
* @param receiveSize Number of bytes to read from the device.
* @return Transfer Aborted... false for success, true for aborted.
*/
@SuppressWarnings({"PMD.CyclomaticComplexity", "ByteBufferBackingArray"})
public synchronized boolean transaction(ByteBuffer dataToSend, int sendSize,
ByteBuffer dataReceived, int receiveSize) {
public synchronized boolean transaction(
ByteBuffer dataToSend, int sendSize, ByteBuffer dataReceived, int receiveSize) {
if (dataToSend.hasArray() && dataReceived.hasArray()) {
return transaction(dataToSend.array(), sendSize, dataReceived.array(), receiveSize);
}
@@ -113,8 +119,14 @@ public class I2C implements AutoCloseable {
"dataReceived is too small, must be at least " + receiveSize);
}
return I2CJNI.i2CTransaction(m_port, (byte) m_deviceAddress, dataToSend,
(byte) sendSize, dataReceived, (byte) receiveSize) < 0;
return I2CJNI.i2CTransaction(
m_port,
(byte) m_deviceAddress,
dataToSend,
(byte) sendSize,
dataReceived,
(byte) receiveSize)
< 0;
}
/**
@@ -135,15 +147,14 @@ public class I2C implements AutoCloseable {
* <p>Write a single byte to a register on a device and wait until the transaction is complete.
*
* @param registerAddress The address of the register on the device to be written.
* @param data The byte to write to the register on the device.
* @param data The byte to write to the register on the device.
* @return Transfer Aborted... false for success, true for aborted.
*/
public synchronized boolean write(int registerAddress, int data) {
byte[] buffer = new byte[2];
buffer[0] = (byte) registerAddress;
buffer[1] = (byte) data;
return I2CJNI.i2CWriteB(m_port, (byte) m_deviceAddress, buffer,
(byte) buffer.length) < 0;
return I2CJNI.i2CWriteB(m_port, (byte) m_deviceAddress, buffer, (byte) buffer.length) < 0;
}
/**
@@ -169,8 +180,7 @@ public class I2C implements AutoCloseable {
*/
public synchronized boolean writeBulk(byte[] data, int size) {
if (data.length < size) {
throw new IllegalArgumentException(
"buffer is too small, must be at least " + size);
throw new IllegalArgumentException("buffer is too small, must be at least " + size);
}
return I2CJNI.i2CWriteB(m_port, (byte) m_deviceAddress, data, (byte) size) < 0;
}
@@ -193,8 +203,7 @@ public class I2C implements AutoCloseable {
throw new IllegalArgumentException("must be a direct buffer");
}
if (data.capacity() < size) {
throw new IllegalArgumentException(
"buffer is too small, must be at least " + size);
throw new IllegalArgumentException("buffer is too small, must be at least " + size);
}
return I2CJNI.i2CWrite(m_port, (byte) m_deviceAddress, data, (byte) size) < 0;
@@ -207,8 +216,8 @@ public class I2C implements AutoCloseable {
* internally allowing you to read consecutive registers on a device in a single transaction.
*
* @param registerAddress The register to read first in the transaction.
* @param count The number of bytes to read in the transaction.
* @param buffer A pointer to the array of bytes to store the data read from the device.
* @param count The number of bytes to read in the transaction.
* @param buffer A pointer to the array of bytes to store the data read from the device.
* @return Transfer Aborted... false for success, true for aborted.
*/
public boolean read(int registerAddress, int count, byte[] buffer) {
@@ -236,8 +245,8 @@ public class I2C implements AutoCloseable {
* internally allowing you to read consecutive registers on a device in a single transaction.
*
* @param registerAddress The register to read first in the transaction.
* @param count The number of bytes to read in the transaction.
* @param buffer A buffer to store the data read from the device.
* @param count The number of bytes to read in the transaction.
* @param buffer A buffer to store the data read from the device.
* @return Transfer Aborted... false for success, true for aborted.
*/
@SuppressWarnings("ByteBufferBackingArray")
@@ -273,7 +282,7 @@ public class I2C implements AutoCloseable {
* <p>Read bytes from a device. This method does not write any data to prompt the device.
*
* @param buffer A pointer to the array of bytes to store the data read from the device.
* @param count The number of bytes to read in the transaction.
* @param count The number of bytes to read in the transaction.
* @return Transfer Aborted... false for success, true for aborted.
*/
public boolean readOnly(byte[] buffer, int count) {
@@ -285,8 +294,7 @@ public class I2C implements AutoCloseable {
throw new IllegalArgumentException("buffer is too small, must be at least " + count);
}
return I2CJNI.i2CReadB(m_port, (byte) m_deviceAddress, buffer,
(byte) count) < 0;
return I2CJNI.i2CReadB(m_port, (byte) m_deviceAddress, buffer, (byte) count) < 0;
}
/**
@@ -295,14 +303,13 @@ public class I2C implements AutoCloseable {
* <p>Read bytes from a device. This method does not write any data to prompt the device.
*
* @param buffer A pointer to the array of bytes to store the data read from the device.
* @param count The number of bytes to read in the transaction.
* @param count The number of bytes to read in the transaction.
* @return Transfer Aborted... false for success, true for aborted.
*/
@SuppressWarnings("ByteBufferBackingArray")
public boolean readOnly(ByteBuffer buffer, int count) {
if (count < 1) {
throw new BoundaryException("Value must be at least 1, " + count
+ " given");
throw new BoundaryException("Value must be at least 1, " + count + " given");
}
if (buffer.hasArray()) {
@@ -316,8 +323,7 @@ public class I2C implements AutoCloseable {
throw new IllegalArgumentException("buffer is too small, must be at least " + count);
}
return I2CJNI.i2CRead(m_port, (byte) m_deviceAddress, buffer, (byte) count)
< 0;
return I2CJNI.i2CRead(m_port, (byte) m_deviceAddress, buffer, (byte) count) < 0;
}
/*
@@ -339,13 +345,12 @@ public class I2C implements AutoCloseable {
* expected value.
*
* @param registerAddress The base register to start reading from the device.
* @param count The size of the field to be verified.
* @param expected A buffer containing the values expected from the device.
* @param count The size of the field to be verified.
* @param expected A buffer containing the values expected from the device.
* @return true if the sensor was verified to be connected
* @pre The device must support and be configured to use register auto-increment.
*/
public boolean verifySensor(int registerAddress, int count,
byte[] expected) {
public boolean verifySensor(int registerAddress, int count, byte[] expected) {
// TODO: Make use of all 7 read bytes
byte[] dataToSend = new byte[1];

View File

@@ -6,13 +6,12 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.InterruptJNI.InterruptJNIHandlerFunction;
/**
* It is recommended that you use this class in conjunction with classes from {@link
* java.util.concurrent.atomic} as these objects are all thread safe.
*
* @param <T> The type of the parameter that should be returned to the the method {@link
* #interruptFired(int, Object)}
* #interruptFired(int, Object)}
*/
public abstract class InterruptHandlerFunction<T> {
/**
@@ -34,12 +33,10 @@ public abstract class InterruptHandlerFunction<T> {
* This method is run every time an interrupt is fired.
*
* @param interruptAssertedMask Interrupt Mask
* @param param The parameter provided by overriding the {@link
* #overridableParameter()} method.
* @param param The parameter provided by overriding the {@link #overridableParameter()} method.
*/
public abstract void interruptFired(int interruptAssertedMask, T param);
/**
* Override this method if you would like to pass a specific parameter to the {@link
* #interruptFired(int, Object)} when it is fired by the interrupt. This method is called once

View File

@@ -4,19 +4,18 @@
package edu.wpi.first.wpilibj;
import java.util.function.Consumer;
import edu.wpi.first.hal.InterruptJNI;
import edu.wpi.first.hal.util.AllocationException;
import java.util.function.Consumer;
/**
* Base for sensors to be used with interrupts.
*/
/** Base for sensors to be used with interrupts. */
public abstract class InterruptableSensorBase implements AutoCloseable {
@SuppressWarnings("MissingJavadocMethod")
public enum WaitResult {
kTimeout(0x0), kRisingEdge(0x1), kFallingEdge(0x100), kBoth(0x101);
kTimeout(0x0),
kRisingEdge(0x1),
kFallingEdge(0x100),
kBoth(0x101);
public final int value;
@@ -37,19 +36,13 @@ public abstract class InterruptableSensorBase implements AutoCloseable {
}
}
/**
* The interrupt resource.
*/
/** The interrupt resource. */
protected int m_interrupt = InterruptJNI.HalInvalidHandle;
/**
* Flags if the interrupt being allocated is synchronous.
*/
/** Flags if the interrupt being allocated is synchronous. */
protected boolean m_isSynchronousInterrupt;
/**
* Create a new InterrupatableSensorBase.
*/
/** Create a new InterrupatableSensorBase. */
public InterruptableSensorBase() {
m_interrupt = 0;
}
@@ -79,9 +72,8 @@ public abstract class InterruptableSensorBase implements AutoCloseable {
* Request one of the 8 interrupts asynchronously on this digital input.
*
* @param handler The {@link Consumer} that will be called whenever there is an interrupt on this
* device. Request interrupts in synchronous mode where the user program interrupt
* handler will be called when an interrupt occurs. The default is interrupt on
* rising edges only.
* device. Request interrupts in synchronous mode where the user program interrupt handler
* will be called when an interrupt occurs. The default is interrupt on rising edges only.
*/
public void requestInterrupts(Consumer<WaitResult> handler) {
if (m_interrupt != 0) {
@@ -92,26 +84,29 @@ public abstract class InterruptableSensorBase implements AutoCloseable {
assert m_interrupt != 0;
InterruptJNI.requestInterrupts(m_interrupt, getPortHandleForRouting(),
getAnalogTriggerTypeForRouting());
InterruptJNI.requestInterrupts(
m_interrupt, getPortHandleForRouting(), getAnalogTriggerTypeForRouting());
setUpSourceEdge(true, false);
InterruptJNI.attachInterruptHandler(m_interrupt, (mask, obj) -> {
// Rising edge result is the interrupt bit set in the byte 0xFF
// Falling edge result is the interrupt bit set in the byte 0xFF00
boolean rising = (mask & 0xFF) != 0;
boolean falling = (mask & 0xFF00) != 0;
handler.accept(WaitResult.getValue(rising, falling));
}, null);
InterruptJNI.attachInterruptHandler(
m_interrupt,
(mask, obj) -> {
// Rising edge result is the interrupt bit set in the byte 0xFF
// Falling edge result is the interrupt bit set in the byte 0xFF00
boolean rising = (mask & 0xFF) != 0;
boolean falling = (mask & 0xFF00) != 0;
handler.accept(WaitResult.getValue(rising, falling));
},
null);
}
/**
* Request one of the 8 interrupts asynchronously on this digital input.
*
* @param handler The {@link InterruptHandlerFunction} that contains the method {@link
* InterruptHandlerFunction#interruptFired(int, Object)} that will be called
* whenever there is an interrupt on this device. Request interrupts in synchronous
* mode where the user program interrupt handler will be called when an interrupt
* occurs. The default is interrupt on rising edges only.
* InterruptHandlerFunction#interruptFired(int, Object)} that will be called whenever there is
* an interrupt on this device. Request interrupts in synchronous mode where the user program
* interrupt handler will be called when an interrupt occurs. The default is interrupt on
* rising edges only.
*/
public void requestInterrupts(InterruptHandlerFunction<?> handler) {
if (m_interrupt != 0) {
@@ -122,11 +117,11 @@ public abstract class InterruptableSensorBase implements AutoCloseable {
assert m_interrupt != 0;
InterruptJNI.requestInterrupts(m_interrupt, getPortHandleForRouting(),
getAnalogTriggerTypeForRouting());
InterruptJNI.requestInterrupts(
m_interrupt, getPortHandleForRouting(), getAnalogTriggerTypeForRouting());
setUpSourceEdge(true, false);
InterruptJNI.attachInterruptHandler(m_interrupt, handler.m_function,
handler.overridableParameter());
InterruptJNI.attachInterruptHandler(
m_interrupt, handler.m_function, handler.overridableParameter());
}
/**
@@ -143,17 +138,16 @@ public abstract class InterruptableSensorBase implements AutoCloseable {
assert m_interrupt != 0;
InterruptJNI.requestInterrupts(m_interrupt, getPortHandleForRouting(),
getAnalogTriggerTypeForRouting());
InterruptJNI.requestInterrupts(
m_interrupt, getPortHandleForRouting(), getAnalogTriggerTypeForRouting());
setUpSourceEdge(true, false);
}
/**
* Allocate the interrupt.
*
* @param watcher true if the interrupt should be in synchronous mode where the user program will
* have to explicitly wait for the interrupt to occur.
* have to explicitly wait for the interrupt to occur.
*/
protected void allocateInterrupts(boolean watcher) {
m_isSynchronousInterrupt = watcher;
@@ -176,9 +170,9 @@ public abstract class InterruptableSensorBase implements AutoCloseable {
/**
* In synchronous mode, wait for the defined interrupt to occur.
*
* @param timeout Timeout in seconds
* @param timeout Timeout in seconds
* @param ignorePrevious If true, ignore interrupts that happened before waitForInterrupt was
* called.
* called.
* @return Result of the wait.
*/
public WaitResult waitForInterrupt(double timeout, boolean ignorePrevious) {
@@ -221,9 +215,7 @@ public abstract class InterruptableSensorBase implements AutoCloseable {
InterruptJNI.enableInterrupts(m_interrupt);
}
/**
* Disable Interrupts without without deallocating structures.
*/
/** Disable Interrupts without without deallocating structures. */
public void disableInterrupts() {
if (m_interrupt == 0) {
throw new IllegalStateException("The interrupt is not allocated.");
@@ -265,13 +257,12 @@ public abstract class InterruptableSensorBase implements AutoCloseable {
/**
* Set which edge to trigger interrupts on.
*
* @param risingEdge true to interrupt on rising edge
* @param risingEdge true to interrupt on rising edge
* @param fallingEdge true to interrupt on falling edge
*/
public void setUpSourceEdge(boolean risingEdge, boolean fallingEdge) {
if (m_interrupt != 0) {
InterruptJNI.setInterruptUpSourceEdge(m_interrupt, risingEdge,
fallingEdge);
InterruptJNI.setInterruptUpSourceEdge(m_interrupt, risingEdge, fallingEdge);
} else {
throw new IllegalArgumentException("You must call RequestInterrupts before setUpSourceEdge");
}

View File

@@ -24,18 +24,14 @@ public class IterativeRobot extends IterativeRobotBase {
private static final double kPacketPeriod = 0.02;
private volatile boolean m_exit;
/**
* Create a new IterativeRobot.
*/
/** Create a new IterativeRobot. */
public IterativeRobot() {
super(kPacketPeriod);
HAL.report(tResourceType.kResourceType_Framework, tInstances.kFramework_Iterative);
}
/**
* Provide an alternate "main loop" via startCompetition().
*/
/** Provide an alternate "main loop" via startCompetition(). */
@Override
public void startCompetition() {
robotInit();
@@ -59,9 +55,7 @@ public class IterativeRobot extends IterativeRobotBase {
}
}
/**
* Ends the main loop in startCompetition().
*/
/** Ends the main loop in startCompetition(). */
@Override
public void endCompetition() {
m_exit = true;

View File

@@ -22,23 +22,14 @@ import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
*
* <p>robotInit() -- provide for initialization at robot power-on
*
* <p>init() functions -- each of the following functions is called once when the
* appropriate mode is entered:
* - disabledInit() -- called each and every time disabled is entered from
* another mode
* - autonomousInit() -- called each and every time autonomous is entered from
* another mode
* - teleopInit() -- called each and every time teleop is entered from
* another mode
* - testInit() -- called each and every time test is entered from
* another mode
* <p>init() functions -- each of the following functions is called once when the appropriate mode
* is entered: - disabledInit() -- called each and every time disabled is entered from another mode
* - autonomousInit() -- called each and every time autonomous is entered from another mode -
* teleopInit() -- called each and every time teleop is entered from another mode - testInit() --
* called each and every time test is entered from another mode
*
* <p>periodic() functions -- each of these functions is called on an interval:
* - robotPeriodic()
* - disabledPeriodic()
* - autonomousPeriodic()
* - teleopPeriodic()
* - testPeriodic()
* <p>periodic() functions -- each of these functions is called on an interval: - robotPeriodic() -
* disabledPeriodic() - autonomousPeriodic() - teleopPeriodic() - testPeriodic()
*/
public abstract class IterativeRobotBase extends RobotBase {
protected double m_period;
@@ -65,9 +56,7 @@ public abstract class IterativeRobotBase extends RobotBase {
m_watchdog = new Watchdog(period, this::printLoopOverrunMessage);
}
/**
* Provide an alternate "main loop" via startCompetition().
*/
/** Provide an alternate "main loop" via startCompetition(). */
@Override
public abstract void startCompetition();
@@ -90,10 +79,9 @@ public abstract class IterativeRobotBase extends RobotBase {
/**
* Robot-wide simulation initialization code should go here.
*
* <p>Users should override this method for default Robot-wide simulation
* related initialization which will be called when the robot is first
* started. It will be called exactly one time after RobotInit is called
* only when the robot is in simulation.
* <p>Users should override this method for default Robot-wide simulation related initialization
* which will be called when the robot is first started. It will be called exactly one time after
* RobotInit is called only when the robot is in simulation.
*/
public void simulationInit() {
System.out.println("Default simulationInit() method... Override me!");
@@ -144,9 +132,7 @@ public abstract class IterativeRobotBase extends RobotBase {
private boolean m_rpFirstRun = true;
/**
* Periodic code for all robot modes should go here.
*/
/** Periodic code for all robot modes should go here. */
public void robotPeriodic() {
if (m_rpFirstRun) {
System.out.println("Default robotPeriodic() method... Override me!");
@@ -170,9 +156,7 @@ public abstract class IterativeRobotBase extends RobotBase {
private boolean m_dpFirstRun = true;
/**
* Periodic code for disabled mode should go here.
*/
/** Periodic code for disabled mode should go here. */
public void disabledPeriodic() {
if (m_dpFirstRun) {
System.out.println("Default disabledPeriodic() method... Override me!");
@@ -182,9 +166,7 @@ public abstract class IterativeRobotBase extends RobotBase {
private boolean m_apFirstRun = true;
/**
* Periodic code for autonomous mode should go here.
*/
/** Periodic code for autonomous mode should go here. */
public void autonomousPeriodic() {
if (m_apFirstRun) {
System.out.println("Default autonomousPeriodic() method... Override me!");
@@ -194,9 +176,7 @@ public abstract class IterativeRobotBase extends RobotBase {
private boolean m_tpFirstRun = true;
/**
* Periodic code for teleop mode should go here.
*/
/** Periodic code for teleop mode should go here. */
public void teleopPeriodic() {
if (m_tpFirstRun) {
System.out.println("Default teleopPeriodic() method... Override me!");
@@ -206,9 +186,7 @@ public abstract class IterativeRobotBase extends RobotBase {
private boolean m_tmpFirstRun = true;
/**
* Periodic code for test mode should go here.
*/
/** Periodic code for test mode should go here. */
@SuppressWarnings("PMD.JUnit4TestShouldUseTestAnnotation")
public void testPeriodic() {
if (m_tmpFirstRun) {
@@ -218,8 +196,7 @@ public abstract class IterativeRobotBase extends RobotBase {
}
/**
* Enables or disables flushing NetworkTables every loop iteration.
* By default, this is disabled.
* Enables or disables flushing NetworkTables every loop iteration. By default, this is disabled.
*
* @param enabled True to enable, false to disable
*/

View File

@@ -12,17 +12,16 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
* Texas Instruments / Vex Robotics Jaguar Speed Controller as a PWM device.
*
* <p>Note that the Jaguar uses the following bounds for PWM values. These values should work
* reasonably well for most controllers, but if users experience issues such as asymmetric
* behavior around the deadband or inability to saturate the controller in either direction,
* calibration is recommended. The calibration procedure can be found in the Jaguar User Manual
* available from Vex.
* reasonably well for most controllers, but if users experience issues such as asymmetric behavior
* around the deadband or inability to saturate the controller in either direction, calibration is
* recommended. The calibration procedure can be found in the Jaguar User Manual available from Vex.
*
* <p><ul>
* <li>2.310ms = full "forward"
* <li>1.550ms = the "high end" of the deadband range
* <li>1.507ms = center of the deadband range (off)
* <li>1.454ms = the "low end" of the deadband range
* <li>0.697ms = full "reverse"
* <ul>
* <li>2.310ms = full "forward"
* <li>1.550ms = the "high end" of the deadband range
* <li>1.507ms = center of the deadband range (off)
* <li>1.454ms = the "low end" of the deadband range
* <li>0.697ms = full "reverse"
* </ul>
*/
public class Jaguar extends PWMSpeedController {
@@ -30,7 +29,7 @@ public class Jaguar extends PWMSpeedController {
* Constructor.
*
* @param channel The PWM channel that the Jaguar is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
* the MXP port
*/
public Jaguar(final int channel) {
super(channel);

View File

@@ -21,11 +21,13 @@ public class Joystick extends GenericHID {
public static final byte kDefaultTwistChannel = 2;
public static final byte kDefaultThrottleChannel = 3;
/**
* Represents an analog axis on a joystick.
*/
/** Represents an analog axis on a joystick. */
public enum AxisType {
kX(0), kY(1), kZ(2), kTwist(3), kThrottle(4);
kX(0),
kY(1),
kZ(2),
kTwist(3),
kThrottle(4);
public final int value;
@@ -34,11 +36,10 @@ public class Joystick extends GenericHID {
}
}
/**
* Represents a digital button on a joystick.
*/
/** Represents a digital button on a joystick. */
public enum ButtonType {
kTrigger(1), kTop(2);
kTrigger(1),
kTop(2);
public final int value;
@@ -47,11 +48,10 @@ public class Joystick extends GenericHID {
}
}
/**
* Represents a digital button on a joystick.
*/
/** Represents a digital button on a joystick. */
private enum Button {
kTrigger(1), kTop(2);
kTrigger(1),
kTop(2);
public final int value;
@@ -60,11 +60,14 @@ public class Joystick extends GenericHID {
}
}
/**
* Represents an analog axis on a joystick.
*/
/** Represents an analog axis on a joystick. */
private enum Axis {
kX(0), kY(1), kZ(2), kTwist(3), kThrottle(4), kNumAxes(5);
kX(0),
kY(1),
kZ(2),
kTwist(3),
kThrottle(4),
kNumAxes(5);
public final int value;
@@ -76,8 +79,7 @@ public class Joystick extends GenericHID {
private final byte[] m_axes = new byte[Axis.kNumAxes.value];
/**
* Construct an instance of a joystick. The joystick index is the USB port on the drivers
* station.
* Construct an instance of a joystick. The joystick index is the USB port on the drivers station.
*
* @param port The port on the Driver Station that the joystick is plugged into.
*/

View File

@@ -8,8 +8,8 @@ import java.util.LinkedHashSet;
import java.util.Set;
/**
* This base class runs a watchdog timer and calls the subclass's StopMotor()
* function if the timeout expires.
* This base class runs a watchdog timer and calls the subclass's StopMotor() function if the
* timeout expires.
*
* <p>The subclass should call feed() whenever the motor value is updated.
*/
@@ -23,9 +23,7 @@ public abstract class MotorSafety {
private static final Set<MotorSafety> m_instanceList = new LinkedHashSet<>();
private static final Object m_listMutex = new Object();
/**
* MotorSafety constructor.
*/
/** MotorSafety constructor. */
public MotorSafety() {
synchronized (m_listMutex) {
m_instanceList.add(this);

View File

@@ -9,11 +9,9 @@ import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Nidec Brushless Motor.
*/
public class NidecBrushless extends MotorSafety implements SpeedController, Sendable,
AutoCloseable {
/** Nidec Brushless Motor. */
public class NidecBrushless extends MotorSafety
implements SpeedController, Sendable, AutoCloseable {
private boolean m_isInverted;
private final DigitalOutput m_dio;
private final PWM m_pwm;
@@ -23,10 +21,10 @@ public class NidecBrushless extends MotorSafety implements SpeedController, Send
/**
* Constructor.
*
* @param pwmChannel The PWM channel that the Nidec Brushless controller is attached to.
* 0-9 are on-board, 10-19 are on the MXP port
* @param dioChannel The DIO channel that the Nidec Brushless controller is attached to.
* 0-9 are on-board, 10-25 are on the MXP port
* @param pwmChannel The PWM channel that the Nidec Brushless controller is attached to. 0-9 are
* on-board, 10-19 are on the MXP port
* @param dioChannel The DIO channel that the Nidec Brushless controller is attached to. 0-9 are
* on-board, 10-25 are on the MXP port
*/
public NidecBrushless(final int pwmChannel, final int dioChannel) {
setSafetyEnabled(false);
@@ -116,10 +114,7 @@ public class NidecBrushless extends MotorSafety implements SpeedController, Send
return "Nidec " + getChannel();
}
/**
* Disable the motor. The enable() function must be called to re-enable
* the motor.
*/
/** Disable the motor. The enable() function must be called to re-enable the motor. */
@Override
public void disable() {
m_disabled = true;
@@ -128,8 +123,8 @@ public class NidecBrushless extends MotorSafety implements SpeedController, Send
}
/**
* Re-enable the motor after disable() has been called. The set()
* function must be called to set a new motor speed.
* Re-enable the motor after disable() has been called. The set() function must be called to set a
* new motor speed.
*/
public void enable() {
m_disabled = false;

View File

@@ -4,12 +4,11 @@
package edu.wpi.first.wpilibj;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
import static java.util.Objects.requireNonNull;
import edu.wpi.first.hal.NotifierJNI;
import static java.util.Objects.requireNonNull;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
public class Notifier implements AutoCloseable {
// The thread waiting on the HAL alarm.
@@ -70,9 +69,7 @@ public class Notifier implements AutoCloseable {
NotifierJNI.updateNotifierAlarm(notifier, triggerTime);
}
/**
* Update the alarm hardware to reflect the next alarm.
*/
/** Update the alarm hardware to reflect the next alarm. */
private void updateAlarm() {
updateAlarm((long) (m_expirationTime * 1e6));
}
@@ -80,8 +77,8 @@ public class Notifier implements AutoCloseable {
/**
* Create a Notifier for timer event notification.
*
* @param run The handler that is called at the notification time which is set
* using StartSingle or StartPeriodic.
* @param run The handler that is called at the notification time which is set using StartSingle
* or StartPeriodic.
*/
public Notifier(Runnable run) {
requireNonNull(run);
@@ -89,54 +86,59 @@ public class Notifier implements AutoCloseable {
m_handler = run;
m_notifier.set(NotifierJNI.initializeNotifier());
m_thread = new Thread(() -> {
while (!Thread.interrupted()) {
int notifier = m_notifier.get();
if (notifier == 0) {
break;
}
long curTime = NotifierJNI.waitForNotifierAlarm(notifier);
if (curTime == 0) {
break;
}
m_thread =
new Thread(
() -> {
while (!Thread.interrupted()) {
int notifier = m_notifier.get();
if (notifier == 0) {
break;
}
long curTime = NotifierJNI.waitForNotifierAlarm(notifier);
if (curTime == 0) {
break;
}
Runnable handler = null;
m_processLock.lock();
try {
handler = m_handler;
if (m_periodic) {
m_expirationTime += m_period;
updateAlarm();
} else {
// need to update the alarm to cause it to wait again
updateAlarm((long) -1);
}
} finally {
m_processLock.unlock();
}
Runnable handler = null;
m_processLock.lock();
try {
handler = m_handler;
if (m_periodic) {
m_expirationTime += m_period;
updateAlarm();
} else {
// need to update the alarm to cause it to wait again
updateAlarm((long) -1);
}
} finally {
m_processLock.unlock();
}
if (handler != null) {
handler.run();
}
}
});
if (handler != null) {
handler.run();
}
}
});
m_thread.setName("Notifier");
m_thread.setDaemon(true);
m_thread.setUncaughtExceptionHandler((thread, error) -> {
Throwable cause = error.getCause();
if (cause != null) {
error = cause;
}
DriverStation.reportError("Unhandled exception: " + error.toString(), error.getStackTrace());
DriverStation.reportError(
"The loopFunc() method (or methods called by it) should have handled "
+ "the exception above.", false);
});
m_thread.setUncaughtExceptionHandler(
(thread, error) -> {
Throwable cause = error.getCause();
if (cause != null) {
error = cause;
}
DriverStation.reportError(
"Unhandled exception: " + error.toString(), error.getStackTrace());
DriverStation.reportError(
"The loopFunc() method (or methods called by it) should have handled "
+ "the exception above.",
false);
});
m_thread.start();
}
/**
* Sets the name of the notifier. Used for debugging purposes only.
* Sets the name of the notifier. Used for debugging purposes only.
*
* @param name Name
*/
@@ -160,8 +162,8 @@ public class Notifier implements AutoCloseable {
}
/**
* Register for single event notification. A timer event is queued for a single
* event after the specified delay.
* Register for single event notification. A timer event is queued for a single event after the
* specified delay.
*
* @param delay Seconds to wait before the handler is called.
*/
@@ -178,12 +180,12 @@ public class Notifier implements AutoCloseable {
}
/**
* Register for periodic event notification. A timer event is queued for
* periodic event notification. Each time the interrupt occurs, the event will
* be immediately requeued for the same time interval.
* Register for periodic event notification. A timer event is queued for periodic event
* notification. Each time the interrupt occurs, the event will be immediately requeued for the
* same time interval.
*
* @param period Period in seconds to call the handler starting one period after
* the call to this method.
* @param period Period in seconds to call the handler starting one period after the call to this
* method.
*/
public void startPeriodic(double period) {
m_processLock.lock();
@@ -198,10 +200,9 @@ public class Notifier implements AutoCloseable {
}
/**
* Stop timer events from occurring. Stop any repeating timer events from
* occurring. This will also remove any single notification events from the
* queue. If a timer-based call to the registered handler is in progress, this
* function will block until the handler call is complete.
* Stop timer events from occurring. Stop any repeating timer events from occurring. This will
* also remove any single notification events from the queue. If a timer-based call to the
* registered handler is in progress, this function will block until the handler call is complete.
*/
public void stop() {
m_processLock.lock();

View File

@@ -4,15 +4,14 @@
package edu.wpi.first.wpilibj;
import java.util.concurrent.locks.ReentrantLock;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.util.BoundaryException;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
import java.util.concurrent.locks.ReentrantLock;
/**
* Class implements a PID Control Loop.
@@ -80,8 +79,10 @@ public class PIDBase implements PIDInterface, PIDOutput, Sendable, AutoCloseable
private double m_setpoint;
private double m_prevSetpoint;
@SuppressWarnings("PMD.UnusedPrivateField")
private double m_error;
private double m_result;
private LinearFilter m_filter;
@@ -106,9 +107,7 @@ public class PIDBase implements PIDInterface, PIDOutput, Sendable, AutoCloseable
boolean onTarget();
}
/**
* Used internally for when Tolerance hasn't been set.
*/
/** Used internally for when Tolerance hasn't been set. */
public static class NullTolerance implements Tolerance {
@Override
public boolean onTarget() {
@@ -145,16 +144,15 @@ public class PIDBase implements PIDInterface, PIDOutput, Sendable, AutoCloseable
/**
* Allocate a PID object with the given constants for P, I, D, and F.
*
* @param Kp the proportional coefficient
* @param Ki the integral coefficient
* @param Kd the derivative coefficient
* @param Kf the feed forward term
* @param Kp the proportional coefficient
* @param Ki the integral coefficient
* @param Kd the derivative coefficient
* @param Kf the feed forward term
* @param source The PIDSource object that is used to get values
* @param output The PIDOutput object that is set to the output percentage
*/
@SuppressWarnings("ParameterName")
public PIDBase(double Kp, double Ki, double Kd, double Kf, PIDSource source,
PIDOutput output) {
public PIDBase(double Kp, double Ki, double Kd, double Kf, PIDSource source, PIDOutput output) {
requireNonNullParam(source, "PIDSource", "PIDBase");
requireNonNullParam(output, "output", "PIDBase");
@@ -180,9 +178,9 @@ public class PIDBase implements PIDInterface, PIDOutput, Sendable, AutoCloseable
/**
* Allocate a PID object with the given constants for P, I, and D.
*
* @param Kp the proportional coefficient
* @param Ki the integral coefficient
* @param Kd the derivative coefficient
* @param Kp the proportional coefficient
* @param Ki the integral coefficient
* @param Kd the derivative coefficient
* @param source the PIDSource object that is used to get values
* @param output the PIDOutput object that is set to the output percentage
*/
@@ -255,19 +253,16 @@ public class PIDBase implements PIDInterface, PIDOutput, Sendable, AutoCloseable
if (pidSourceType.equals(PIDSourceType.kRate)) {
if (P != 0) {
totalError = clamp(totalError + error, minimumOutput / P,
maximumOutput / P);
totalError = clamp(totalError + error, minimumOutput / P, maximumOutput / P);
}
result = P * totalError + D * error + feedForward;
} else {
if (I != 0) {
totalError = clamp(totalError + error, minimumOutput / I,
maximumOutput / I);
totalError = clamp(totalError + error, minimumOutput / I, maximumOutput / I);
}
result = P * error + I * totalError + D * (error - prevError)
+ feedForward;
result = P * error + I * totalError + D * (error - prevError) + feedForward;
}
result = clamp(result, minimumOutput, maximumOutput);
@@ -308,9 +303,9 @@ public class PIDBase implements PIDInterface, PIDOutput, Sendable, AutoCloseable
* Calculate the feed forward term.
*
* <p>Both of the provided feed forward calculations are velocity feed forwards. If a different
* feed forward calculation is desired, the user can override this function and provide his or
* her own. This function does no synchronization because the PIDController class only calls it
* in synchronized code, so be careful if calling it oneself.
* feed forward calculation is desired, the user can override this function and provide his or her
* own. This function does no synchronization because the PIDController class only calls it in
* synchronized code, so be careful if calling it oneself.
*
* <p>If a velocity PID controller is being used, the F term should be set to 1 over the maximum
* setpoint for the output. If a position PID controller is being used, the F term should be set
@@ -649,7 +644,7 @@ public class PIDBase implements PIDInterface, PIDOutput, Sendable, AutoCloseable
* used for the onTarget() function.
*
* @deprecated Use getError(), which is now already filtered.
* @return the current average of the error
* @return the current average of the error
*/
@Deprecated
public double getAvgError() {
@@ -685,9 +680,9 @@ public class PIDBase implements PIDInterface, PIDOutput, Sendable, AutoCloseable
* object. Use it by creating the type of tolerance that you want to use: setTolerance(new
* PIDController.AbsoluteTolerance(0.1))
*
* @deprecated Use setPercentTolerance() instead.
* @deprecated Use setPercentTolerance() instead.
* @param tolerance A tolerance object of the right type, e.g. PercentTolerance or
* AbsoluteTolerance
* AbsoluteTolerance
*/
@Deprecated
public void setTolerance(Tolerance tolerance) {
@@ -730,7 +725,7 @@ public class PIDBase implements PIDInterface, PIDOutput, Sendable, AutoCloseable
* erroneous measurements when the mechanism is on target. However, the mechanism will not
* register as on target for at least the specified bufLength cycles.
*
* @deprecated Use a LinearFilter as the input.
* @deprecated Use a LinearFilter as the input.
* @param bufLength Number of previous cycles to average.
*/
@Deprecated
@@ -758,9 +753,7 @@ public class PIDBase implements PIDInterface, PIDOutput, Sendable, AutoCloseable
}
}
/**
* Reset the previous error, the integral term, and disable the controller.
*/
/** Reset the previous error, the integral term, and disable the controller. */
@Override
public void reset() {
m_thisMutex.lock();

View File

@@ -25,20 +25,24 @@ public class PIDController extends PIDBase implements Controller, AutoCloseable
/**
* Allocate a PID object with the given constants for P, I, D, and F.
*
* @param Kp the proportional coefficient
* @param Ki the integral coefficient
* @param Kd the derivative coefficient
* @param Kf the feed forward term
* @param Kp the proportional coefficient
* @param Ki the integral coefficient
* @param Kd the derivative coefficient
* @param Kf the feed forward term
* @param source The PIDSource object that is used to get values
* @param output The PIDOutput object that is set to the output percentage
* @param period the loop time for doing calculations in seconds.
* This particularly affects calculations of
* the integral and differential terms.
* The default is 0.05 (50ms).
* @param period the loop time for doing calculations in seconds. This particularly affects
* calculations of the integral and differential terms. The default is 0.05 (50ms).
*/
@SuppressWarnings("ParameterName")
public PIDController(double Kp, double Ki, double Kd, double Kf, PIDSource source,
PIDOutput output, double period) {
public PIDController(
double Kp,
double Ki,
double Kd,
double Kf,
PIDSource source,
PIDOutput output,
double period) {
super(Kp, Ki, Kd, Kf, source, output);
m_controlLoop.startPeriodic(period);
}
@@ -46,28 +50,26 @@ public class PIDController extends PIDBase implements Controller, AutoCloseable
/**
* Allocate a PID object with the given constants for P, I, D and period.
*
* @param Kp the proportional coefficient
* @param Ki the integral coefficient
* @param Kd the derivative coefficient
* @param Kp the proportional coefficient
* @param Ki the integral coefficient
* @param Kd the derivative coefficient
* @param source the PIDSource object that is used to get values
* @param output the PIDOutput object that is set to the output percentage
* @param period the loop time for doing calculations in seconds.
* This particularly affects calculations of
* the integral and differential terms.
* The default is 0.05 (50ms).
* @param period the loop time for doing calculations in seconds. This particularly affects
* calculations of the integral and differential terms. The default is 0.05 (50ms).
*/
@SuppressWarnings("ParameterName")
public PIDController(double Kp, double Ki, double Kd, PIDSource source, PIDOutput output,
double period) {
public PIDController(
double Kp, double Ki, double Kd, PIDSource source, PIDOutput output, double period) {
this(Kp, Ki, Kd, 0.0, source, output, period);
}
/**
* Allocate a PID object with the given constants for P, I, D, using a 50ms period.
*
* @param Kp the proportional coefficient
* @param Ki the integral coefficient
* @param Kd the derivative coefficient
* @param Kp the proportional coefficient
* @param Ki the integral coefficient
* @param Kd the derivative coefficient
* @param source The PIDSource object that is used to get values
* @param output The PIDOutput object that is set to the output percentage
*/
@@ -79,16 +81,16 @@ public class PIDController extends PIDBase implements Controller, AutoCloseable
/**
* Allocate a PID object with the given constants for P, I, D, using a 50ms period.
*
* @param Kp the proportional coefficient
* @param Ki the integral coefficient
* @param Kd the derivative coefficient
* @param Kf the feed forward term
* @param Kp the proportional coefficient
* @param Ki the integral coefficient
* @param Kd the derivative coefficient
* @param Kf the feed forward term
* @param source The PIDSource object that is used to get values
* @param output The PIDOutput object that is set to the output percentage
*/
@SuppressWarnings("ParameterName")
public PIDController(double Kp, double Ki, double Kd, double Kf, PIDSource source,
PIDOutput output) {
public PIDController(
double Kp, double Ki, double Kd, double Kf, PIDSource source, PIDOutput output) {
this(Kp, Ki, Kd, Kf, source, output, kDefaultPeriod);
}
@@ -105,9 +107,7 @@ public class PIDController extends PIDBase implements Controller, AutoCloseable
}
}
/**
* Begin running the PIDController.
*/
/** Begin running the PIDController. */
@Override
public void enable() {
m_thisMutex.lock();
@@ -118,9 +118,7 @@ public class PIDController extends PIDBase implements Controller, AutoCloseable
}
}
/**
* Stop running the PIDController, this sets the output to zero before stopping.
*/
/** Stop running the PIDController, this sets the output to zero before stopping. */
@Override
public void disable() {
// Ensures m_enabled check and pidWrite() call occur atomically
@@ -139,9 +137,7 @@ public class PIDController extends PIDBase implements Controller, AutoCloseable
}
}
/**
* Set the enabled state of the PIDController.
*/
/** Set the enabled state of the PIDController. */
public void setEnabled(boolean enable) {
if (enable) {
enable();
@@ -150,9 +146,7 @@ public class PIDController extends PIDBase implements Controller, AutoCloseable
}
}
/**
* Return true if PIDController is enabled.
*/
/** Return true if PIDController is enabled. */
public boolean isEnabled() {
m_thisMutex.lock();
try {
@@ -162,9 +156,7 @@ public class PIDController extends PIDBase implements Controller, AutoCloseable
}
}
/**
* Reset the previous error, the integral term, and disable the controller.
*/
/** Reset the previous error, the integral term, and disable the controller. */
@Override
public void reset() {
disable();

View File

@@ -4,9 +4,7 @@
package edu.wpi.first.wpilibj;
/**
* A description for the type of output value to provide to a PIDController.
*/
/** A description for the type of output value to provide to a PIDController. */
@Deprecated(since = "2020", forRemoval = true)
public enum PIDSourceType {
kDisplacement,

View File

@@ -24,21 +24,13 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
* width (currently .5ms) - 0 = disabled (i.e. PWM output is held low)
*/
public class PWM extends MotorSafety implements Sendable, AutoCloseable {
/**
* Represents the amount to multiply the minimum servo-pulse pwm period by.
*/
/** Represents the amount to multiply the minimum servo-pulse pwm period by. */
public enum PeriodMultiplier {
/**
* Period Multiplier: don't skip pulses. PWM pulses occur every 5.005 ms
*/
/** Period Multiplier: don't skip pulses. PWM pulses occur every 5.005 ms */
k1X,
/**
* Period Multiplier: skip every other pulse. PWM pulses occur every 10.010 ms
*/
/** Period Multiplier: skip every other pulse. PWM pulses occur every 10.010 ms */
k2X,
/**
* Period Multiplier: skip three out of four pulses. PWM pulses occur every 20.020 ms
*/
/** Period Multiplier: skip three out of four pulses. PWM pulses occur every 20.020 ms */
k4X
}
@@ -68,9 +60,7 @@ public class PWM extends MotorSafety implements Sendable, AutoCloseable {
setSafetyEnabled(false);
}
/**
* Free the resource associated with the PWM channel and set the value to 0.
*/
/** Free the resource associated with the PWM channel and set the value to 0. */
@Override
public void close() {
SendableRegistry.remove(this);
@@ -96,8 +86,7 @@ public class PWM extends MotorSafety implements Sendable, AutoCloseable {
* Optionally eliminate the deadband from a speed controller.
*
* @param eliminateDeadband If true, set the motor curve on the Jaguar to eliminate the deadband
* in the middle of the range. Otherwise, keep the full range without
* modifying any values.
* in the middle of the range. Otherwise, keep the full range without modifying any values.
*/
public void enableDeadbandElimination(boolean eliminateDeadband) {
PWMJNI.setPWMEliminateDeadband(m_handle, eliminateDeadband);
@@ -108,21 +97,21 @@ public class PWM extends MotorSafety implements Sendable, AutoCloseable {
* type of controller. The values determine the upper and lower speeds as well as the deadband
* bracket.
*
* @param max The max PWM pulse width in ms
* @param max The max PWM pulse width in ms
* @param deadbandMax The high end of the deadband range pulse width in ms
* @param center The center (off) pulse width in ms
* @param center The center (off) pulse width in ms
* @param deadbandMin The low end of the deadband pulse width in ms
* @param min The minimum pulse width in ms
* @param min The minimum pulse width in ms
*/
public void setBounds(double max, double deadbandMax, double center, double deadbandMin,
double min) {
public void setBounds(
double max, double deadbandMax, double center, double deadbandMin, double min) {
PWMJNI.setPWMConfig(m_handle, max, deadbandMax, center, deadbandMin, min);
}
/**
* Gets the bounds on the PWM pulse widths. This Gets the bounds on the PWM values for a
* particular type of controller. The values determine the upper and lower speeds as well
* as the deadband bracket.
* particular type of controller. The values determine the upper and lower speeds as well as the
* deadband bracket.
*/
public PWMConfigDataResult getRawBounds() {
return PWMJNI.getPWMConfigRaw(m_handle);
@@ -216,10 +205,7 @@ public class PWM extends MotorSafety implements Sendable, AutoCloseable {
return PWMJNI.getPWMRaw(m_handle);
}
/**
* Temporarily disables the PWM output. The next set call will reenable
* the output.
*/
/** Temporarily disables the PWM output. The next set call will reenable the output. */
public void setDisabled() {
PWMJNI.setPWMDisabled(m_handle);
}

View File

@@ -11,25 +11,22 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* REV Robotics SPARK MAX Speed Controller with PWM control.
*
* <P>Note that the SPARK MAX uses the following bounds for PWM values. These values should work
* reasonably well for most controllers, but if users experience issues such as asymmetric
* behavior around the deadband or inability to saturate the controller in either direction,
* calibration is recommended. The calibration procedure can be found in the SPARK MAX User Manual
* available from REV Robotics.
* <p>Note that the SPARK MAX uses the following bounds for PWM values. These values should work
* reasonably well for most controllers, but if users experience issues such as asymmetric behavior
* around the deadband or inability to saturate the controller in either direction, calibration is
* recommended. The calibration procedure can be found in the SPARK MAX User Manual available from
* REV Robotics.
*
* <p><ul>
* <li> 2.003ms = full "forward"
* <li> 1.550ms = the "high end" of the deadband range
* <li> 1.500ms = center of the deadband range (off)
* <li> 1.460ms = the "low end" of the deadband range
* <li> 0.999ms = full "reverse"
* <ul>
* <li>2.003ms = full "forward"
* <li>1.550ms = the "high end" of the deadband range
* <li>1.500ms = center of the deadband range (off)
* <li>1.460ms = the "low end" of the deadband range
* <li>0.999ms = full "reverse"
* </ul>
*/
public class PWMSparkMax extends PWMSpeedController {
/**
* Common initialization code called by all constructors.
*
*/
/** Common initialization code called by all constructors. */
public PWMSparkMax(final int channel) {
super(channel);

View File

@@ -6,9 +6,7 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
/**
* Common base class for all PWM Speed Controllers.
*/
/** Common base class for all PWM Speed Controllers. */
public abstract class PWMSpeedController extends PWM implements SpeedController {
private boolean m_isInverted;
@@ -16,7 +14,7 @@ public abstract class PWMSpeedController extends PWM implements SpeedController
* Constructor.
*
* @param channel The PWM channel that the controller is attached to. 0-9 are on-board, 10-19 are
* on the MXP port
* on the MXP port
*/
protected PWMSpeedController(int channel) {
super(channel);

View File

@@ -12,25 +12,25 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
* Cross the Road Electronics (CTRE) Talon FX Speed Controller with PWM control.
*
* <p>Note that the TalonFX uses the following bounds for PWM values. These values should work
* reasonably well for most controllers, but if users experience issues such as asymmetric
* behavior around the deadband or inability to saturate the controller in either direction,
* calibration is recommended. The calibration procedure can be found in the TalonFX User Manual
* available from CTRE.
* reasonably well for most controllers, but if users experience issues such as asymmetric behavior
* around the deadband or inability to saturate the controller in either direction, calibration is
* recommended. The calibration procedure can be found in the TalonFX User Manual available from
* CTRE.
*
* <p><ul>
* <li>2.004ms = full "forward"
* <li>1.520ms = the "high end" of the deadband range
* <li>1.500ms = center of the deadband range (off)
* <li>1.480ms = the "low end" of the deadband range
* <li>0.997ms = full "reverse"
* <ul>
* <li>2.004ms = full "forward"
* <li>1.520ms = the "high end" of the deadband range
* <li>1.500ms = center of the deadband range (off)
* <li>1.480ms = the "low end" of the deadband range
* <li>0.997ms = full "reverse"
* </ul>
*/
public class PWMTalonFX extends PWMSpeedController {
/**
* Constructor for a TalonFX connected via PWM.
*
* @param channel The PWM channel that the Talon FX is attached to. 0-9 are on-board, 10-19 are
* on the MXP port
* @param channel The PWM channel that the Talon FX is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
public PWMTalonFX(final int channel) {
super(channel);

View File

@@ -12,17 +12,17 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
* Cross the Road Electronics (CTRE) Talon SRX Speed Controller with PWM control.
*
* <p>Note that the TalonSRX uses the following bounds for PWM values. These values should work
* reasonably well for most controllers, but if users experience issues such as asymmetric
* behavior around the deadband or inability to saturate the controller in either direction,
* calibration is recommended. The calibration procedure can be found in the TalonSRX User Manual
* available from CTRE.
* reasonably well for most controllers, but if users experience issues such as asymmetric behavior
* around the deadband or inability to saturate the controller in either direction, calibration is
* recommended. The calibration procedure can be found in the TalonSRX User Manual available from
* CTRE.
*
* <p><ul>
* <li>2.004ms = full "forward"
* <li>1.520ms = the "high end" of the deadband range
* <li>1.500ms = center of the deadband range (off)
* <li>1.480ms = the "low end" of the deadband range
* <li>0.997ms = full "reverse"
* <ul>
* <li>2.004ms = full "forward"
* <li>1.520ms = the "high end" of the deadband range
* <li>1.500ms = center of the deadband range (off)
* <li>1.480ms = the "low end" of the deadband range
* <li>0.997ms = full "reverse"
* </ul>
*/
public class PWMTalonSRX extends PWMSpeedController {
@@ -30,7 +30,7 @@ public class PWMTalonSRX extends PWMSpeedController {
* Constructor for a TalonSRX connected via PWM.
*
* @param channel The PWM channel that the Talon SRX is attached to. 0-9 are on-board, 10-19 are
* on the MXP port
* on the MXP port
*/
public PWMTalonSRX(final int channel) {
super(channel);

View File

@@ -12,24 +12,24 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
* Playing with Fusion Venom Smart Motor with PWM control.
*
* <p>Note that the Venom uses the following bounds for PWM values. These values should work
* reasonably well for most controllers, but if users experience issues such as asymmetric
* behavior around the deadband or inability to saturate the controller in either direction,
* calibration is recommended.
* reasonably well for most controllers, but if users experience issues such as asymmetric behavior
* around the deadband or inability to saturate the controller in either direction, calibration is
* recommended.
*
* <p><ul>
* <li>2.004ms = full "forward"
* <li>1.520ms = the "high end" of the deadband range
* <li>1.500ms = center of the deadband range (off)
* <li>1.480ms = the "low end" of the deadband range
* <li>0.997ms = full "reverse"
* <ul>
* <li>2.004ms = full "forward"
* <li>1.520ms = the "high end" of the deadband range
* <li>1.500ms = center of the deadband range (off)
* <li>1.480ms = the "low end" of the deadband range
* <li>0.997ms = full "reverse"
* </ul>
*/
public class PWMVenom extends PWMSpeedController {
/**
* Constructor for a Venom connected via PWM.
*
* @param channel The PWM channel that the Venom is attached to. 0-9 are on-board, 10-19 are
* on the MXP port
* @param channel The PWM channel that the Venom is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
public PWMVenom(final int channel) {
super(channel);

View File

@@ -11,18 +11,18 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Cross the Road Electronics (CTRE) Victor SPX Speed Controller with PWM control.
*
* <p>Note that the Victor SPX uses the following bounds for PWM values. These values should
* work reasonably well for most controllers, but if users experience issues such as asymmetric
* behavior around the deadband or inability to saturate the controller in either direction,
* calibration is recommended. The calibration procedure can be found in the Victor SPX User
* Manual available from CTRE.
* <p>Note that the Victor SPX uses the following bounds for PWM values. These values should work
* reasonably well for most controllers, but if users experience issues such as asymmetric behavior
* around the deadband or inability to saturate the controller in either direction, calibration is
* recommended. The calibration procedure can be found in the Victor SPX User Manual available from
* CTRE.
*
* <p><ul>
* <li>2.004ms = full "forward"
* <li>1.520ms = the "high end" of the deadband range
* <li>1.500ms = center of the deadband range (off)
* <li>1.480ms = the "low end" of the deadband range
* <li>0.997ms = full "reverse"
* <ul>
* <li>2.004ms = full "forward"
* <li>1.520ms = the "high end" of the deadband range
* <li>1.500ms = center of the deadband range (off)
* <li>1.480ms = the "low end" of the deadband range
* <li>0.997ms = full "reverse"
* </ul>
*/
public class PWMVictorSPX extends PWMSpeedController {
@@ -30,7 +30,7 @@ public class PWMVictorSPX extends PWMSpeedController {
* Constructor for a Victor SPX connected via PWM.
*
* @param channel The PWM channel that the PWMVictorSPX is attached to. 0-9 are on-board, 10-19
* are on the MXP port
* are on the MXP port
*/
public PWMVictorSPX(final int channel) {
super(channel);

View File

@@ -32,9 +32,7 @@ public class PowerDistributionPanel implements Sendable, AutoCloseable {
SendableRegistry.addLW(this, "PowerDistributionPanel", module);
}
/**
* Constructor. Uses the default CAN ID (0).
*/
/** Constructor. Uses the default CAN ID (0). */
public PowerDistributionPanel() {
this(0);
}
@@ -102,23 +100,17 @@ public class PowerDistributionPanel implements Sendable, AutoCloseable {
return PDPJNI.getPDPTotalEnergy(m_handle);
}
/**
* Reset the total energy to 0.
*/
/** Reset the total energy to 0. */
public void resetTotalEnergy() {
PDPJNI.resetPDPTotalEnergy(m_handle);
}
/**
* Clear all PDP sticky faults.
*/
/** Clear all PDP sticky faults. */
public void clearStickyFaults() {
PDPJNI.clearPDPStickyFaults(m_handle);
}
/**
* Gets module number (CAN ID).
*/
/** Gets module number (CAN ID). */
public int getModule() {
return m_module;
}

View File

@@ -4,7 +4,7 @@
package edu.wpi.first.wpilibj;
import java.util.Collection;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
@@ -12,34 +12,27 @@ import edu.wpi.first.networktables.EntryListenerFlags;
import edu.wpi.first.networktables.NetworkTable;
import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.networktables.NetworkTableInstance;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
import java.util.Collection;
/**
* The preferences class provides a relatively simple way to save important values to the roboRIO to
* access the next time the roboRIO is booted.
*
* <p> This class loads and saves from a file inside the roboRIO. The user can not access the file
* <p>This class loads and saves from a file inside the roboRIO. The user can not access the file
* directly, but may modify values at specific fields which will then be automatically saved to the
* file by the NetworkTables server. </p>
* file by the NetworkTables server.
*
* <p> This class is thread safe. </p>
* <p>This class is thread safe.
*
* <p> This will also interact with {@link NetworkTable} by creating a table called "Preferences"
* with all the key-value pairs. </p>
* <p>This will also interact with {@link NetworkTable} by creating a table called "Preferences"
* with all the key-value pairs.
*/
public final class Preferences {
/**
* The Preferences table name.
*/
/** The Preferences table name. */
private static final String TABLE_NAME = "Preferences";
/**
* The singleton instance.
*/
/** The singleton instance. */
private static Preferences instance;
/**
* The network table.
*/
/** The network table. */
private final NetworkTable m_table;
/**
@@ -54,9 +47,7 @@ public final class Preferences {
return instance;
}
/**
* Creates a preference class.
*/
/** Creates a preference class. */
private Preferences() {
m_table = NetworkTableInstance.getDefault().getTable(TABLE_NAME);
m_table.getEntry(".type").setString("RobotPreferences");
@@ -70,6 +61,7 @@ public final class Preferences {
/**
* Gets the preferences keys.
*
* @return a collection of the keys
*/
public Collection<String> getKeys() {
@@ -79,7 +71,7 @@ public final class Preferences {
/**
* Puts the given string into the preferences table.
*
* @param key the key
* @param key the key
* @param value the value
* @throws NullPointerException if value is null
*/
@@ -94,7 +86,7 @@ public final class Preferences {
/**
* Puts the given string into the preferences table if it doesn't already exist.
*
* @param key The key
* @param key The key
* @param value The value
*/
public void initString(String key, String value) {
@@ -105,7 +97,7 @@ public final class Preferences {
/**
* Puts the given int into the preferences table.
*
* @param key the key
* @param key the key
* @param value the value
*/
public void putInt(String key, int value) {
@@ -117,7 +109,7 @@ public final class Preferences {
/**
* Puts the given int into the preferences table if it doesn't already exist.
*
* @param key The key
* @param key The key
* @param value The value
*/
public void initInt(String key, int value) {
@@ -128,7 +120,7 @@ public final class Preferences {
/**
* Puts the given double into the preferences table.
*
* @param key the key
* @param key the key
* @param value the value
*/
public void putDouble(String key, double value) {
@@ -140,7 +132,7 @@ public final class Preferences {
/**
* Puts the given double into the preferences table if it doesn't already exist.
*
* @param key The key
* @param key The key
* @param value The value
*/
public void initDouble(String key, double value) {
@@ -151,7 +143,7 @@ public final class Preferences {
/**
* Puts the given float into the preferences table.
*
* @param key the key
* @param key the key
* @param value the value
*/
public void putFloat(String key, float value) {
@@ -163,7 +155,7 @@ public final class Preferences {
/**
* Puts the given float into the preferences table if it doesn't already exist.
*
* @param key The key
* @param key The key
* @param value The value
*/
public void initFloat(String key, float value) {
@@ -174,7 +166,7 @@ public final class Preferences {
/**
* Puts the given boolean into the preferences table.
*
* @param key the key
* @param key the key
* @param value the value
*/
public void putBoolean(String key, boolean value) {
@@ -186,7 +178,7 @@ public final class Preferences {
/**
* Puts the given boolean into the preferences table if it doesn't already exist.
*
* @param key The key
* @param key The key
* @param value The value
*/
public void initBoolean(String key, boolean value) {
@@ -197,7 +189,7 @@ public final class Preferences {
/**
* Puts the given long into the preferences table.
*
* @param key the key
* @param key the key
* @param value the value
*/
public void putLong(String key, long value) {
@@ -209,7 +201,7 @@ public final class Preferences {
/**
* Puts the given long into the preferences table if it doesn't already exist.
*
* @param key The key
* @param key The key
* @param value The value
*/
public void initLong(String key, long value) {
@@ -236,9 +228,7 @@ public final class Preferences {
m_table.delete(key);
}
/**
* Remove all preferences.
*/
/** Remove all preferences. */
public void removeAll() {
for (String key : m_table.getKeys()) {
if (!".type".equals(key)) {
@@ -251,7 +241,7 @@ public final class Preferences {
* Returns the string at the given key. If this table does not have a value for that position,
* then the given backup value will be returned.
*
* @param key the key
* @param key the key
* @param backup the value to return if none exists in the table
* @return either the value in the table, or the backup
*/
@@ -263,7 +253,7 @@ public final class Preferences {
* Returns the int at the given key. If this table does not have a value for that position, then
* the given backup value will be returned.
*
* @param key the key
* @param key the key
* @param backup the value to return if none exists in the table
* @return either the value in the table, or the backup
*/
@@ -275,7 +265,7 @@ public final class Preferences {
* Returns the double at the given key. If this table does not have a value for that position,
* then the given backup value will be returned.
*
* @param key the key
* @param key the key
* @param backup the value to return if none exists in the table
* @return either the value in the table, or the backup
*/
@@ -287,7 +277,7 @@ public final class Preferences {
* Returns the boolean at the given key. If this table does not have a value for that position,
* then the given backup value will be returned.
*
* @param key the key
* @param key the key
* @param backup the value to return if none exists in the table
* @return either the value in the table, or the backup
*/
@@ -299,7 +289,7 @@ public final class Preferences {
* Returns the float at the given key. If this table does not have a value for that position, then
* the given backup value will be returned.
*
* @param key the key
* @param key the key
* @param backup the value to return if none exists in the table
* @return either the value in the table, or the backup
*/
@@ -311,7 +301,7 @@ public final class Preferences {
* Returns the long at the given key. If this table does not have a value for that position, then
* the given backup value will be returned.
*
* @param key the key
* @param key the key
* @param backup the value to return if none exists in the table
* @return either the value in the table, or the backup
*/

View File

@@ -4,8 +4,7 @@
package edu.wpi.first.wpilibj;
import java.util.Arrays;
import java.util.Optional;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
@@ -13,17 +12,17 @@ import edu.wpi.first.hal.RelayJNI;
import edu.wpi.first.hal.util.UncleanStatusException;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
import java.util.Arrays;
import java.util.Optional;
/**
* Class for VEX Robotics Spike style relay outputs. Relays are intended to be connected to Spikes
* or similar relays. The relay channels controls a pair of channels that are either both off, one
* on, the other on, or both on. This translates into two Spike outputs at 0v, one at 12v and one
* at 0v, one at 0v and the other at 12v, or two Spike outputs at 12V. This allows off, full
* forward, or full reverse control of motors without variable speed. It also allows the two
* channels (forward and reverse) to be used independently for something that does not care about
* voltage polarity (like a solenoid).
* on, the other on, or both on. This translates into two Spike outputs at 0v, one at 12v and one at
* 0v, one at 0v and the other at 12v, or two Spike outputs at 12V. This allows off, full forward,
* or full reverse control of motors without variable speed. It also allows the two channels
* (forward and reverse) to be used independently for something that does not care about voltage
* polarity (like a solenoid).
*/
public class Relay extends MotorSafety implements Sendable, AutoCloseable {
/**
@@ -42,9 +41,7 @@ public class Relay extends MotorSafety implements Sendable, AutoCloseable {
}
}
/**
* The state to drive a Relay to.
*/
/** The state to drive a Relay to. */
public enum Value {
kOff("Off"),
kOn("On"),
@@ -66,22 +63,13 @@ public class Relay extends MotorSafety implements Sendable, AutoCloseable {
}
}
/**
* The Direction(s) that a relay is configured to operate in.
*/
/** The Direction(s) that a relay is configured to operate in. */
public enum Direction {
/**
* direction: both directions are valid.
*/
/** direction: both directions are valid. */
kBoth,
/**
* direction: Only forward is valid.
*/
/** direction: Only forward is valid. */
kForward,
/**
* direction: only reverse is valid.
*/
/** direction: only reverse is valid. */
kReverse
}
@@ -196,8 +184,8 @@ public class Relay extends MotorSafety implements Sendable, AutoCloseable {
break;
case kForward:
if (m_direction == Direction.kReverse) {
throw new InvalidValueException("A relay configured for reverse cannot be set to "
+ "forward");
throw new InvalidValueException(
"A relay configured for reverse cannot be set to " + "forward");
}
if (m_direction == Direction.kBoth || m_direction == Direction.kForward) {
RelayJNI.setRelay(m_forwardHandle, true);
@@ -208,8 +196,8 @@ public class Relay extends MotorSafety implements Sendable, AutoCloseable {
break;
case kReverse:
if (m_direction == Direction.kForward) {
throw new InvalidValueException("A relay configured for forward cannot be set to "
+ "reverse");
throw new InvalidValueException(
"A relay configured for forward cannot be set to " + "reverse");
}
if (m_direction == Direction.kBoth) {
RelayJNI.setRelay(m_forwardHandle, false);
@@ -307,7 +295,9 @@ public class Relay extends MotorSafety implements Sendable, AutoCloseable {
builder.setSmartDashboardType("Relay");
builder.setActuator(true);
builder.setSafeState(() -> set(Value.kOff));
builder.addStringProperty("Value", () -> get().getPrettyValue(),
builder.addStringProperty(
"Value",
() -> get().getPrettyValue(),
value -> set(Value.getValueOf(value).orElse(Value.kOff)));
}
}

View File

@@ -26,9 +26,7 @@ public final class Resource {
private final int m_size;
private final Resource m_nextResource;
/**
* Clears all allocated resources.
*/
/** Clears all allocated resources. */
public static void restartProgram() {
for (Resource r = Resource.resourceList; r != null; r = r.m_nextResource) {
for (int i = 0; i < r.m_size; i++) {
@@ -39,8 +37,8 @@ public final class Resource {
/**
* Allocate storage for a new instance of Resource. Allocate a bool array of values that will get
* initialized to indicate that no resources have been allocated yet. The indices of the
* resources are 0..size-1.
* initialized to indicate that no resources have been allocated yet. The indices of the resources
* are 0..size-1.
*
* @param size The number of blocks to allocate
*/
@@ -103,5 +101,4 @@ public final class Resource {
}
m_numAllocated[index] = false;
}
}

View File

@@ -4,14 +4,6 @@
package edu.wpi.first.wpilibj;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Supplier;
import edu.wpi.cscore.CameraServerJNI;
import edu.wpi.first.cameraserver.CameraServerShared;
import edu.wpi.first.cameraserver.CameraServerSharedStore;
@@ -26,6 +18,13 @@ import edu.wpi.first.networktables.NetworkTableInstance;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
import edu.wpi.first.wpilibj.shuffleboard.Shuffleboard;
import edu.wpi.first.wpilibj.util.WPILibVersion;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Supplier;
/**
* Implement a Robot Program framework. The RobotBase class is intended to be subclassed by a user
@@ -35,94 +34,93 @@ import edu.wpi.first.wpilibj.util.WPILibVersion;
* might be spawned as a task, then killed at the end of the Autonomous period.
*/
public abstract class RobotBase implements AutoCloseable {
/**
* The ID of the main Java thread.
*/
/** The ID of the main Java thread. */
// This is usually 1, but it is best to make sure
private static long m_threadId = -1;
private static void setupCameraServerShared() {
CameraServerShared shared = new CameraServerShared() {
CameraServerShared shared =
new CameraServerShared() {
@Override
public void reportVideoServer(int id) {
HAL.report(tResourceType.kResourceType_PCVideoServer, id + 1);
}
@Override
public void reportVideoServer(int id) {
HAL.report(tResourceType.kResourceType_PCVideoServer, id + 1);
}
@Override
public void reportUsbCamera(int id) {
HAL.report(tResourceType.kResourceType_UsbCamera, id + 1);
}
@Override
public void reportUsbCamera(int id) {
HAL.report(tResourceType.kResourceType_UsbCamera, id + 1);
}
@Override
public void reportDriverStationError(String error) {
DriverStation.reportError(error, true);
}
@Override
public void reportDriverStationError(String error) {
DriverStation.reportError(error, true);
}
@Override
public void reportAxisCamera(int id) {
HAL.report(tResourceType.kResourceType_AxisCamera, id + 1);
}
@Override
public void reportAxisCamera(int id) {
HAL.report(tResourceType.kResourceType_AxisCamera, id + 1);
}
@Override
public Long getRobotMainThreadId() {
return RobotBase.getMainThreadId();
}
@Override
public Long getRobotMainThreadId() {
return RobotBase.getMainThreadId();
}
@Override
public boolean isRoboRIO() {
return RobotBase.isReal();
}
};
@Override
public boolean isRoboRIO() {
return RobotBase.isReal();
}
};
CameraServerSharedStore.setCameraServerShared(shared);
}
private static void setupMathShared() {
MathSharedStore.setMathShared(new MathShared() {
@Override
public void reportError(String error, StackTraceElement[] stackTrace) {
DriverStation.reportError(error, stackTrace);
}
MathSharedStore.setMathShared(
new MathShared() {
@Override
public void reportError(String error, StackTraceElement[] stackTrace) {
DriverStation.reportError(error, stackTrace);
}
@Override
public void reportUsage(MathUsageId id, int count) {
switch (id) {
case kKinematics_DifferentialDrive:
HAL.report(tResourceType.kResourceType_Kinematics,
tInstances.kKinematics_DifferentialDrive);
break;
case kKinematics_MecanumDrive:
HAL.report(tResourceType.kResourceType_Kinematics,
tInstances.kKinematics_MecanumDrive);
break;
case kKinematics_SwerveDrive:
HAL.report(tResourceType.kResourceType_Kinematics,
tInstances.kKinematics_SwerveDrive);
break;
case kTrajectory_TrapezoidProfile:
HAL.report(tResourceType.kResourceType_TrapezoidProfile, count);
break;
case kFilter_Linear:
HAL.report(tResourceType.kResourceType_LinearFilter, count);
break;
case kOdometry_DifferentialDrive:
HAL.report(tResourceType.kResourceType_Odometry,
tInstances.kOdometry_DifferentialDrive);
break;
case kOdometry_SwerveDrive:
HAL.report(tResourceType.kResourceType_Odometry,
tInstances.kOdometry_SwerveDrive);
break;
case kOdometry_MecanumDrive:
HAL.report(tResourceType.kResourceType_Odometry,
tInstances.kOdometry_MecanumDrive);
break;
default:
break;
}
}
});
@Override
public void reportUsage(MathUsageId id, int count) {
switch (id) {
case kKinematics_DifferentialDrive:
HAL.report(
tResourceType.kResourceType_Kinematics,
tInstances.kKinematics_DifferentialDrive);
break;
case kKinematics_MecanumDrive:
HAL.report(
tResourceType.kResourceType_Kinematics, tInstances.kKinematics_MecanumDrive);
break;
case kKinematics_SwerveDrive:
HAL.report(
tResourceType.kResourceType_Kinematics, tInstances.kKinematics_SwerveDrive);
break;
case kTrajectory_TrapezoidProfile:
HAL.report(tResourceType.kResourceType_TrapezoidProfile, count);
break;
case kFilter_Linear:
HAL.report(tResourceType.kResourceType_LinearFilter, count);
break;
case kOdometry_DifferentialDrive:
HAL.report(
tResourceType.kResourceType_Odometry, tInstances.kOdometry_DifferentialDrive);
break;
case kOdometry_SwerveDrive:
HAL.report(tResourceType.kResourceType_Odometry, tInstances.kOdometry_SwerveDrive);
break;
case kOdometry_MecanumDrive:
HAL.report(tResourceType.kResourceType_Odometry, tInstances.kOdometry_MecanumDrive);
break;
default:
break;
}
}
});
}
protected final DriverStation m_ds;
@@ -133,8 +131,7 @@ public abstract class RobotBase implements AutoCloseable {
* completion before Autonomous is entered.
*
* <p>This must be used to ensure that the communications code starts. In the future it would be
* nice
* to put this code into it's own task that loads on boot so ensure that it runs.
* nice to put this code into it's own task that loads on boot so ensure that it runs.
*/
protected RobotBase() {
final NetworkTableInstance inst = NetworkTableInstance.getDefault();
@@ -159,8 +156,7 @@ public abstract class RobotBase implements AutoCloseable {
}
@Override
public void close() {
}
public void close() {}
/**
* Get if the robot is a simulation.
@@ -199,8 +195,7 @@ public abstract class RobotBase implements AutoCloseable {
}
/**
* Determine if the robot is currently in Autonomous mode as determined by the field
* controls.
* Determine if the robot is currently in Autonomous mode as determined by the field controls.
*
* @return True if the robot is currently operating Autonomously.
*/
@@ -209,8 +204,8 @@ public abstract class RobotBase implements AutoCloseable {
}
/**
* Determine if the robot is current in Autonomous mode and enabled as determined by
* the field controls.
* Determine if the robot is current in Autonomous mode and enabled as determined by the field
* controls.
*
* @return True if the robot is currently operating autonomously while enabled.
*/
@@ -219,8 +214,7 @@ public abstract class RobotBase implements AutoCloseable {
}
/**
* Determine if the robot is currently in Test mode as determined by the driver
* station.
* Determine if the robot is currently in Test mode as determined by the driver station.
*
* @return True if the robot is currently operating in Test mode.
*/
@@ -239,8 +233,8 @@ public abstract class RobotBase implements AutoCloseable {
}
/**
* Determine if the robot is current in Operator Control mode and enabled as determined by
* the field controls.
* Determine if the robot is current in Operator Control mode and enabled as determined by the
* field controls.
*
* @return True if the robot is currently operating in Tele-Op mode while enabled.
*/
@@ -257,14 +251,10 @@ public abstract class RobotBase implements AutoCloseable {
return m_ds.isNewControlData();
}
/**
* Provide an alternate "main loop" via startCompetition().
*/
/** Provide an alternate "main loop" via startCompetition(). */
public abstract void startCompetition();
/**
* Ends the main loop in startCompetition().
*/
/** Ends the main loop in startCompetition(). */
public abstract void endCompetition();
@SuppressWarnings("MissingJavadocMethod")
@@ -286,11 +276,11 @@ public abstract class RobotBase implements AutoCloseable {
private static RobotBase m_robotCopy;
private static boolean m_suppressExitWarning;
/**
* Run the robot main loop.
*/
@SuppressWarnings({"PMD.AvoidInstantiatingObjectsInLoops", "PMD.AvoidCatchingThrowable",
"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
/** Run the robot main loop. */
@SuppressWarnings({
"PMD.AvoidInstantiatingObjectsInLoops", "PMD.AvoidCatchingThrowable",
"PMD.CyclomaticComplexity", "PMD.NPathComplexity"
})
private static <T extends RobotBase> void runRobot(Supplier<T> robotSupplier) {
System.out.println("********** Robot program starting **********");
@@ -307,8 +297,9 @@ public abstract class RobotBase implements AutoCloseable {
if (elements.length > 0) {
robotName = elements[0].getClassName();
}
DriverStation.reportError("Unhandled exception instantiating robot " + robotName + " "
+ throwable.toString(), elements);
DriverStation.reportError(
"Unhandled exception instantiating robot " + robotName + " " + throwable.toString(),
elements);
DriverStation.reportWarning("Robots should not quit, but yours did!", false);
DriverStation.reportError("Could not instantiate robot " + robotName + "!", false);
return;
@@ -334,8 +325,8 @@ public abstract class RobotBase implements AutoCloseable {
}
} catch (IOException ex) {
DriverStation.reportError("Could not write FRC_Lib_Version.ini: " + ex.toString(),
ex.getStackTrace());
DriverStation.reportError(
"Could not write FRC_Lib_Version.ini: " + ex.toString(), ex.getStackTrace());
}
}
@@ -347,8 +338,8 @@ public abstract class RobotBase implements AutoCloseable {
if (cause != null) {
throwable = cause;
}
DriverStation.reportError("Unhandled exception: " + throwable.toString(),
throwable.getStackTrace());
DriverStation.reportError(
"Unhandled exception: " + throwable.toString(), throwable.getStackTrace());
errorOnExit = true;
} finally {
m_runMutex.lock();
@@ -360,7 +351,8 @@ public abstract class RobotBase implements AutoCloseable {
if (errorOnExit) {
DriverStation.reportError(
"The startCompetition() method (or methods called by it) should have "
+ "handled the exception above.", false);
+ "handled the exception above.",
false);
} else {
DriverStation.reportError("Unexpected return from startCompetition() method.", false);
}
@@ -368,18 +360,14 @@ public abstract class RobotBase implements AutoCloseable {
}
}
/**
* Suppress the "Robots should not quit" message.
*/
/** Suppress the "Robots should not quit" message. */
public static void suppressExitWarning(boolean value) {
m_runMutex.lock();
m_suppressExitWarning = value;
m_runMutex.unlock();
}
/**
* Starting point for the applications.
*/
/** Starting point for the applications. */
public static <T extends RobotBase> void startRobot(Supplier<T> robotSupplier) {
if (!HAL.initialize(500, 0)) {
throw new IllegalStateException("Failed to initialize. Terminating");
@@ -389,14 +377,17 @@ public abstract class RobotBase implements AutoCloseable {
// Needed because all the OpenCV JNI functions don't have built in loading
CameraServerJNI.enumerateSinks();
HAL.report(tResourceType.kResourceType_Language, tInstances.kLanguage_Java, 0,
WPILibVersion.Version);
HAL.report(
tResourceType.kResourceType_Language, tInstances.kLanguage_Java, 0, WPILibVersion.Version);
if (HAL.hasMain()) {
Thread thread = new Thread(() -> {
runRobot(robotSupplier);
HAL.exitMain();
}, "robot main");
Thread thread =
new Thread(
() -> {
runRobot(robotSupplier);
HAL.exitMain();
},
"robot main");
thread.setDaemon(true);
thread.start();
HAL.runMain();

View File

@@ -10,17 +10,14 @@ import edu.wpi.first.hal.PowerJNI;
import edu.wpi.first.hal.can.CANJNI;
import edu.wpi.first.hal.can.CANStatus;
/**
* Contains functions for roboRIO functionality.
*/
/** Contains functions for roboRIO functionality. */
public final class RobotController {
private RobotController() {
throw new UnsupportedOperationException("This is a utility class!");
}
/**
* Return the FPGA Version number. For now, expect this to be the current
* year.
* Return the FPGA Version number. For now, expect this to be the current year.
*
* @return FPGA Version number.
*/

View File

@@ -4,12 +4,12 @@
package edu.wpi.first.wpilibj;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
import edu.wpi.first.hal.FRCNetComm.tInstances;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
/**
* Utility class for handling Robot drive based on a definition of the motor configuration. The
* robot drive class handles basic driving for a robot. Currently, 2 and 4 motor tank and mecanum
@@ -18,17 +18,18 @@ import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
* function (intended for hand created drive code, such as autonomous) or with the Tank/Arcade
* functions intended to be used for Operator Control driving.
*
* @deprecated Use {@link edu.wpi.first.wpilibj.drive.DifferentialDrive}
* or {@link edu.wpi.first.wpilibj.drive.MecanumDrive} classes instead.
* @deprecated Use {@link edu.wpi.first.wpilibj.drive.DifferentialDrive} or {@link
* edu.wpi.first.wpilibj.drive.MecanumDrive} classes instead.
*/
@Deprecated
@SuppressWarnings("PMD.GodClass")
public class RobotDrive extends MotorSafety implements AutoCloseable {
/**
* The location of a motor on the robot for the purpose of driving.
*/
/** The location of a motor on the robot for the purpose of driving. */
public enum MotorType {
kFrontLeft(0), kFrontRight(1), kRearLeft(2), kRearRight(3);
kFrontLeft(0),
kFrontRight(1),
kRearLeft(2),
kRearRight(3);
public final int value;
@@ -59,7 +60,7 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
* a two wheel drive system where the left and right motor pwm channels are specified in the call.
* This call assumes Talons for controlling the motors.
*
* @param leftMotorChannel The PWM channel number that drives the left motor.
* @param leftMotorChannel The PWM channel number that drives the left motor.
* @param rightMotorChannel The PWM channel number that drives the right motor.
*/
public RobotDrive(final int leftMotorChannel, final int rightMotorChannel) {
@@ -79,13 +80,16 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
* a four wheel drive system where all four motor pwm channels are specified in the call. This
* call assumes Talons for controlling the motors.
*
* @param frontLeftMotor Front left motor channel number
* @param rearLeftMotor Rear Left motor channel number
* @param frontLeftMotor Front left motor channel number
* @param rearLeftMotor Rear Left motor channel number
* @param frontRightMotor Front right motor channel number
* @param rearRightMotor Rear Right motor channel number
* @param rearRightMotor Rear Right motor channel number
*/
public RobotDrive(final int frontLeftMotor, final int rearLeftMotor, final int frontRightMotor,
final int rearRightMotor) {
public RobotDrive(
final int frontLeftMotor,
final int rearLeftMotor,
final int frontRightMotor,
final int rearRightMotor) {
m_sensitivity = kDefaultSensitivity;
m_maxOutput = kDefaultMaxOutput;
m_rearLeftMotor = new Talon(rearLeftMotor);
@@ -103,7 +107,7 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
* subclasses of the SpeedController objects, for example, versions with ramping or reshaping of
* the curve to suit motor bias or dead-band elimination.
*
* @param leftMotor The left SpeedController object used to drive the robot.
* @param leftMotor The left SpeedController object used to drive the robot.
* @param rightMotor the right SpeedController object used to drive the robot.
*/
public RobotDrive(SpeedController leftMotor, SpeedController rightMotor) {
@@ -125,13 +129,16 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
* Constructor for RobotDrive with 4 motors specified as SpeedController objects. Speed controller
* input version of RobotDrive (see previous comments).
*
* @param frontLeftMotor The front left SpeedController object used to drive the robot
* @param rearLeftMotor The back left SpeedController object used to drive the robot.
* @param frontLeftMotor The front left SpeedController object used to drive the robot
* @param rearLeftMotor The back left SpeedController object used to drive the robot.
* @param frontRightMotor The front right SpeedController object used to drive the robot.
* @param rearRightMotor The back right SpeedController object used to drive the robot.
* @param rearRightMotor The back right SpeedController object used to drive the robot.
*/
public RobotDrive(SpeedController frontLeftMotor, SpeedController rearLeftMotor,
SpeedController frontRightMotor, SpeedController rearRightMotor) {
public RobotDrive(
SpeedController frontLeftMotor,
SpeedController rearLeftMotor,
SpeedController frontRightMotor,
SpeedController rearRightMotor) {
m_frontLeftMotor = requireNonNullParam(frontLeftMotor, "frontLeftMotor", "RobotDrive");
m_rearLeftMotor = requireNonNullParam(rearLeftMotor, "rearLeftMotor", "RobotDrive");
m_frontRightMotor = requireNonNullParam(frontRightMotor, "frontRightMotor", "RobotDrive");
@@ -154,19 +161,20 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
* <p>This function will most likely be used in an autonomous routine.
*
* @param outputMagnitude The speed setting for the outside wheel in a turn, forward or backwards,
* +1 to -1.
* @param curve The rate of turn, constant for different forward speeds. Set {@literal
* curve < 0 for left turn or curve > 0 for right turn.} Set curve =
* e^(-r/w) to get a turn radius r for wheelbase w of your robot.
* Conversely, turn radius r = -ln(curve)*w for a given value of curve and
* wheelbase w.
* +1 to -1.
* @param curve The rate of turn, constant for different forward speeds. Set {@literal curve < 0
* for left turn or curve > 0 for right turn.} Set curve = e^(-r/w) to get a turn radius r for
* wheelbase w of your robot. Conversely, turn radius r = -ln(curve)*w for a given value of
* curve and wheelbase w.
*/
public void drive(double outputMagnitude, double curve) {
final double leftOutput;
final double rightOutput;
if (!kArcadeRatioCurve_Reported) {
HAL.report(tResourceType.kResourceType_RobotDrive, tInstances.kRobotDrive_ArcadeRatioCurve,
HAL.report(
tResourceType.kResourceType_RobotDrive,
tInstances.kRobotDrive_ArcadeRatioCurve,
getNumMotors());
kArcadeRatioCurve_Reported = true;
}
@@ -198,7 +206,7 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
* inputs. The Y-axis will be selected from each Joystick object. The calculated values will be
* squared to decrease sensitivity at low speeds.
*
* @param leftStick The joystick to control the left side of the robot.
* @param leftStick The joystick to control the left side of the robot.
* @param rightStick The joystick to control the right side of the robot.
*/
public void tankDrive(GenericHID leftStick, GenericHID rightStick) {
@@ -212,8 +220,8 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
* Provide tank steering using the stored robot configuration. drive the robot using two joystick
* inputs. The Y-axis will be selected from each Joystick object.
*
* @param leftStick The joystick to control the left side of the robot.
* @param rightStick The joystick to control the right side of the robot.
* @param leftStick The joystick to control the left side of the robot.
* @param rightStick The joystick to control the right side of the robot.
* @param squaredInputs Setting this parameter to true decreases the sensitivity at lower speeds
*/
public void tankDrive(GenericHID leftStick, GenericHID rightStick, boolean squaredInputs) {
@@ -228,13 +236,13 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
* axis to be used on each Joystick object for the left and right sides of the robot. The
* calculated values will be squared to decrease sensitivity at low speeds.
*
* @param leftStick The Joystick object to use for the left side of the robot.
* @param leftAxis The axis to select on the left side Joystick object.
* @param leftStick The Joystick object to use for the left side of the robot.
* @param leftAxis The axis to select on the left side Joystick object.
* @param rightStick The Joystick object to use for the right side of the robot.
* @param rightAxis The axis to select on the right side Joystick object.
* @param rightAxis The axis to select on the right side Joystick object.
*/
public void tankDrive(GenericHID leftStick, final int leftAxis, GenericHID rightStick,
final int rightAxis) {
public void tankDrive(
GenericHID leftStick, final int leftAxis, GenericHID rightStick, final int rightAxis) {
requireNonNullParam(leftStick, "leftStick", "tankDrive");
requireNonNullParam(rightStick, "rightStick", "tankDrive");
@@ -245,14 +253,18 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
* Provide tank steering using the stored robot configuration. This function lets you pick the
* axis to be used on each Joystick object for the left and right sides of the robot.
*
* @param leftStick The Joystick object to use for the left side of the robot.
* @param leftAxis The axis to select on the left side Joystick object.
* @param rightStick The Joystick object to use for the right side of the robot.
* @param rightAxis The axis to select on the right side Joystick object.
* @param leftStick The Joystick object to use for the left side of the robot.
* @param leftAxis The axis to select on the left side Joystick object.
* @param rightStick The Joystick object to use for the right side of the robot.
* @param rightAxis The axis to select on the right side Joystick object.
* @param squaredInputs Setting this parameter to true decreases the sensitivity at lower speeds
*/
public void tankDrive(GenericHID leftStick, final int leftAxis, GenericHID rightStick,
final int rightAxis, boolean squaredInputs) {
public void tankDrive(
GenericHID leftStick,
final int leftAxis,
GenericHID rightStick,
final int rightAxis,
boolean squaredInputs) {
requireNonNullParam(leftStick, "leftStick", "tankDrive");
requireNonNullParam(rightStick, "rightStick", "tankDrive");
@@ -263,14 +275,14 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
* Provide tank steering using the stored robot configuration. This function lets you directly
* provide joystick values from any source.
*
* @param leftValue The value of the left stick.
* @param rightValue The value of the right stick.
* @param leftValue The value of the left stick.
* @param rightValue The value of the right stick.
* @param squaredInputs Setting this parameter to true decreases the sensitivity at lower speeds
*/
public void tankDrive(double leftValue, double rightValue, boolean squaredInputs) {
if (!kTank_Reported) {
HAL.report(tResourceType.kResourceType_RobotDrive, tInstances.kRobotDrive_Tank,
getNumMotors());
HAL.report(
tResourceType.kResourceType_RobotDrive, tInstances.kRobotDrive_Tank, getNumMotors());
kTank_Reported = true;
}
@@ -291,7 +303,7 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
* provide joystick values from any source. The calculated values will be squared to decrease
* sensitivity at low speeds.
*
* @param leftValue The value of the left stick.
* @param leftValue The value of the left stick.
* @param rightValue The value of the right stick.
*/
public void tankDrive(double leftValue, double rightValue) {
@@ -303,9 +315,8 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
* axis for the move value and the X axis for the rotate value. (Should add more information here
* regarding the way that arcade drive works.)
*
* @param stick The joystick to use for Arcade single-stick driving. The Y-axis will be
* selected for forwards/backwards and the X-axis will be selected for
* rotation rate.
* @param stick The joystick to use for Arcade single-stick driving. The Y-axis will be selected
* for forwards/backwards and the X-axis will be selected for rotation rate.
* @param squaredInputs If true, the sensitivity will be decreased for small values
*/
public void arcadeDrive(GenericHID stick, boolean squaredInputs) {
@@ -320,7 +331,7 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
* sensitivity at low speeds.
*
* @param stick The joystick to use for Arcade single-stick driving. The Y-axis will be selected
* for forwards/backwards and the X-axis will be selected for rotation rate.
* for forwards/backwards and the X-axis will be selected for rotation rate.
*/
public void arcadeDrive(GenericHID stick) {
arcadeDrive(stick, true);
@@ -330,16 +341,20 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
* Arcade drive implements single stick driving. Given two joystick instances and two axis,
* compute the values to send to either two or four motors.
*
* @param moveStick The Joystick object that represents the forward/backward direction
* @param moveAxis The axis on the moveStick object to use for forwards/backwards (typically
* Y_AXIS)
* @param rotateStick The Joystick object that represents the rotation value
* @param rotateAxis The axis on the rotation object to use for the rotate right/left
* (typically X_AXIS)
* @param moveStick The Joystick object that represents the forward/backward direction
* @param moveAxis The axis on the moveStick object to use for forwards/backwards (typically
* Y_AXIS)
* @param rotateStick The Joystick object that represents the rotation value
* @param rotateAxis The axis on the rotation object to use for the rotate right/left (typically
* X_AXIS)
* @param squaredInputs Setting this parameter to true decreases the sensitivity at lower speeds
*/
public void arcadeDrive(GenericHID moveStick, final int moveAxis, GenericHID rotateStick,
final int rotateAxis, boolean squaredInputs) {
public void arcadeDrive(
GenericHID moveStick,
final int moveAxis,
GenericHID rotateStick,
final int rotateAxis,
boolean squaredInputs) {
double moveValue = moveStick.getRawAxis(moveAxis);
double rotateValue = rotateStick.getRawAxis(rotateAxis);
@@ -348,33 +363,35 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
/**
* Arcade drive implements single stick driving. Given two joystick instances and two axis,
* compute the values to send to either two or four motors. The calculated values will be
* squared to decrease sensitivity at low speeds.
* compute the values to send to either two or four motors. The calculated values will be squared
* to decrease sensitivity at low speeds.
*
* @param moveStick The Joystick object that represents the forward/backward direction
* @param moveAxis The axis on the moveStick object to use for forwards/backwards (typically
* Y_AXIS)
* @param moveStick The Joystick object that represents the forward/backward direction
* @param moveAxis The axis on the moveStick object to use for forwards/backwards (typically
* Y_AXIS)
* @param rotateStick The Joystick object that represents the rotation value
* @param rotateAxis The axis on the rotation object to use for the rotate right/left (typically
* X_AXIS)
* @param rotateAxis The axis on the rotation object to use for the rotate right/left (typically
* X_AXIS)
*/
public void arcadeDrive(GenericHID moveStick, final int moveAxis, GenericHID rotateStick,
final int rotateAxis) {
public void arcadeDrive(
GenericHID moveStick, final int moveAxis, GenericHID rotateStick, final int rotateAxis) {
arcadeDrive(moveStick, moveAxis, rotateStick, rotateAxis, true);
}
/**
* Arcade drive implements single stick driving. This function lets you directly provide
* joystick values from any source.
* Arcade drive implements single stick driving. This function lets you directly provide joystick
* values from any source.
*
* @param moveValue The value to use for forwards/backwards
* @param rotateValue The value to use for the rotate right/left
* @param moveValue The value to use for forwards/backwards
* @param rotateValue The value to use for the rotate right/left
* @param squaredInputs If set, decreases the sensitivity at low speeds
*/
public void arcadeDrive(double moveValue, double rotateValue, boolean squaredInputs) {
// local variables to hold the computed PWM values for the motors
if (!kArcadeStandard_Reported) {
HAL.report(tResourceType.kResourceType_RobotDrive, tInstances.kRobotDrive_ArcadeStandard,
HAL.report(
tResourceType.kResourceType_RobotDrive,
tInstances.kRobotDrive_ArcadeStandard,
getNumMotors());
kArcadeStandard_Reported = true;
}
@@ -416,11 +433,11 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
}
/**
* Arcade drive implements single stick driving. This function lets you directly provide
* joystick values from any source. The calculated values will be squared to decrease
* sensitivity at low speeds.
* Arcade drive implements single stick driving. This function lets you directly provide joystick
* values from any source. The calculated values will be squared to decrease sensitivity at low
* speeds.
*
* @param moveValue The value to use for forwards/backwards
* @param moveValue The value to use for forwards/backwards
* @param rotateValue The value to use for the rotate right/left
*/
public void arcadeDrive(double moveValue, double rotateValue) {
@@ -436,17 +453,19 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
*
* <p>This is designed to be directly driven by joystick axes.
*
* @param x The speed that the robot should drive in the X direction. [-1.0..1.0]
* @param y The speed that the robot should drive in the Y direction. This input is
* inverted to match the forward == -1.0 that joysticks produce. [-1.0..1.0]
* @param rotation The rate of rotation for the robot that is completely independent of the
* translation. [-1.0..1.0]
* @param x The speed that the robot should drive in the X direction. [-1.0..1.0]
* @param y The speed that the robot should drive in the Y direction. This input is inverted to
* match the forward == -1.0 that joysticks produce. [-1.0..1.0]
* @param rotation The rate of rotation for the robot that is completely independent of the
* translation. [-1.0..1.0]
* @param gyroAngle The current angle reading from the gyro. Use this to implement field-oriented
* controls.
* controls.
*/
public void mecanumDrive_Cartesian(double x, double y, double rotation, double gyroAngle) {
if (!kMecanumCartesian_Reported) {
HAL.report(tResourceType.kResourceType_RobotDrive, tInstances.kRobotDrive_MecanumCartesian,
HAL.report(
tResourceType.kResourceType_RobotDrive,
tInstances.kRobotDrive_MecanumCartesian,
getNumMotors());
kMecanumCartesian_Reported = true;
}
@@ -480,14 +499,16 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
* top, the roller axles should form an X across the robot.
*
* @param magnitude The speed that the robot should drive in a given direction. [-1.0..1.0]
* @param direction The angle the robot should drive in degrees. The direction and magnitude
* are independent of the rotation rate. [-180.0..180.0]
* @param rotation The rate of rotation for the robot that is completely independent of the
* magnitude or direction. [-1.0..1.0]
* @param direction The angle the robot should drive in degrees. The direction and magnitude are
* independent of the rotation rate. [-180.0..180.0]
* @param rotation The rate of rotation for the robot that is completely independent of the
* magnitude or direction. [-1.0..1.0]
*/
public void mecanumDrive_Polar(double magnitude, double direction, double rotation) {
if (!kMecanumPolar_Reported) {
HAL.report(tResourceType.kResourceType_RobotDrive, tInstances.kRobotDrive_MecanumPolar,
HAL.report(
tResourceType.kResourceType_RobotDrive,
tInstances.kRobotDrive_MecanumPolar,
getNumMotors());
kMecanumPolar_Reported = true;
}
@@ -521,9 +542,9 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
*
* @param magnitude The speed that the robot should drive in a given direction. [-1.0..1.0]
* @param direction The direction the robot should drive. The direction and maginitude are
* independent of the rotation rate.
* @param rotation The rate of rotation for the robot that is completely independent of the
* magnitute or direction. [-1.0..1.0]
* independent of the rotation rate.
* @param rotation The rate of rotation for the robot that is completely independent of the
* magnitute or direction. [-1.0..1.0]
*/
void holonomicDrive(double magnitude, double direction, double rotation) {
mecanumDrive_Polar(magnitude, direction, rotation);
@@ -531,10 +552,10 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
/**
* Set the speed of the right and left motors. This is used once an appropriate drive setup
* function is called such as twoWheelDrive(). The motors are set to "leftSpeed" and
* "rightSpeed" and includes flipping the direction of one side for opposing motors.
* function is called such as twoWheelDrive(). The motors are set to "leftSpeed" and "rightSpeed"
* and includes flipping the direction of one side for opposing motors.
*
* @param leftOutput The speed to send to the left side of the robot.
* @param leftOutput The speed to send to the left side of the robot.
* @param rightOutput The speed to send to the right side of the robot.
*/
public void setLeftRightMotorOutputs(double leftOutput, double rightOutput) {
@@ -552,9 +573,7 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
feed();
}
/**
* Limit motor values to the -1.0 to +1.0 range.
*/
/** Limit motor values to the -1.0 to +1.0 range. */
protected static double limit(double number) {
if (number > 1.0) {
return 1.0;
@@ -565,9 +584,7 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
return number;
}
/**
* Normalize all wheel speeds if the magnitude of any wheel is greater than 1.0.
*/
/** Normalize all wheel speeds if the magnitude of any wheel is greater than 1.0. */
protected static void normalize(double[] wheelSpeeds) {
double maxMagnitude = Math.abs(wheelSpeeds[0]);
for (int i = 1; i < kMaxNumberOfMotors; i++) {
@@ -583,9 +600,7 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
}
}
/**
* Rotate a vector in Cartesian space.
*/
/** Rotate a vector in Cartesian space. */
protected static double[] rotateVector(double x, double y, double angle) {
double cosA = Math.cos(angle * (Math.PI / 180.0));
double sinA = Math.sin(angle * (Math.PI / 180.0));
@@ -600,7 +615,7 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
* drive code would normally run it. Motors that are direct drive would be inverted, the drive
* code assumes that the motors are geared with one reversal.
*
* @param motor The motor index to invert.
* @param motor The motor index to invert.
* @param isInverted True if the motor should be inverted when operated.
*/
public void setInvertedMotor(MotorType motor, boolean isInverted) {
@@ -643,9 +658,7 @@ public class RobotDrive extends MotorSafety implements AutoCloseable {
m_maxOutput = maxOutput;
}
/**
* Free the speed controllers if they were allocated locally.
*/
/** Free the speed controllers if they were allocated locally. */
@Override
public void close() {
if (m_allocatedSpeedControllers) {

View File

@@ -30,6 +30,5 @@ public final class RobotState {
return DriverStation.getInstance().isTest();
}
private RobotState() {
}
private RobotState() {}
}

View File

@@ -12,23 +12,21 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
* Mindsensors SD540 Speed Controller.
*
* <p>Note that the SD540 uses the following bounds for PWM values. These values should work
* reasonably well for most controllers, but if users experience issues such as asymmetric
* behavior around the deadband or inability to saturate the controller in either direction,
* calibration is recommended. The calibration procedure can be found in the SD540 User Manual
* available from Mindsensors.
* reasonably well for most controllers, but if users experience issues such as asymmetric behavior
* around the deadband or inability to saturate the controller in either direction, calibration is
* recommended. The calibration procedure can be found in the SD540 User Manual available from
* Mindsensors.
*
* <p><ul>
* <li>2.05ms = full "forward"
* <li>1.55ms = the "high end" of the deadband range
* <li>1.50ms = center of the deadband range (off)
* <li>1.44ms = the "low end" of the deadband range
* <li>0.94ms = full "reverse"
* <ul>
* <li>2.05ms = full "forward"
* <li>1.55ms = the "high end" of the deadband range
* <li>1.50ms = center of the deadband range (off)
* <li>1.44ms = the "low end" of the deadband range
* <li>0.94ms = full "reverse"
* </ul>
*/
public class SD540 extends PWMSpeedController {
/**
* Common initialization code called by all constructors.
*/
/** Common initialization code called by all constructors. */
protected void initSD540() {
setBounds(2.05, 1.55, 1.50, 1.44, 0.94);
setPeriodMultiplier(PeriodMultiplier.k1X);
@@ -43,7 +41,7 @@ public class SD540 extends PWMSpeedController {
* Constructor.
*
* @param channel The PWM channel that the SD540 is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
* the MXP port
*/
public SD540(final int channel) {
super(channel);

View File

@@ -4,22 +4,23 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import edu.wpi.first.hal.AccumulatorResult;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.SPIJNI;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
/**
* Represents a SPI bus port.
*/
/** Represents a SPI bus port. */
@SuppressWarnings("PMD.CyclomaticComplexity")
public class SPI implements AutoCloseable {
public enum Port {
kOnboardCS0(0), kOnboardCS1(1), kOnboardCS2(2), kOnboardCS3(3), kMXP(4);
kOnboardCS0(0),
kOnboardCS1(1),
kOnboardCS2(2),
kOnboardCS3(3),
kMXP(4);
public final int value;
@@ -122,6 +123,7 @@ public class SPI implements AutoCloseable {
/**
* Configure that the data is stable on the falling edge and the data changes on the rising edge.
* Note this gets reversed is setClockActiveLow is set.
*
* @deprecated use {@link #setSampleDataOnTrailingEdge()} in most cases.
*/
@Deprecated
@@ -133,6 +135,7 @@ public class SPI implements AutoCloseable {
/**
* Configure that the data is stable on the rising edge and the data changes on the falling edge.
* Note this gets reversed is setClockActiveLow is set.
*
* @deprecated use {@link #setSampleDataOnLeadingEdge()} in most cases.
*/
@Deprecated
@@ -141,18 +144,12 @@ public class SPI implements AutoCloseable {
SPIJNI.spiSetOpts(m_port, m_msbFirst, m_sampleOnTrailing, m_clockIdleHigh);
}
/**
* Configure the chip select line to be active high.
*/
/** Configure the chip select line to be active high. */
public final void setChipSelectActiveHigh() {
SPIJNI.spiSetChipSelectActiveHigh(m_port);
}
/**
* Configure the chip select line to be active low.
*/
/** Configure the chip select line to be active low. */
public final void setChipSelectActiveLow() {
SPIJNI.spiSetChipSelectActiveLow(m_port);
}
@@ -200,8 +197,8 @@ public class SPI implements AutoCloseable {
* <p>If the receive FIFO is empty, there is no active transfer, and initiate is false, errors.
*
* @param initiate If true, this function pushes "0" into the transmit buffer and initiates a
* transfer. If false, this function assumes that data is already in the receive
* FIFO from a previous write.
* transfer. If false, this function assumes that data is already in the receive FIFO from a
* previous write.
*/
public int read(boolean initiate, byte[] dataReceived, int size) {
if (dataReceived.length < size) {
@@ -217,11 +214,11 @@ public class SPI implements AutoCloseable {
*
* <p>If the receive FIFO is empty, there is no active transfer, and initiate is false, errors.
*
* @param initiate If true, this function pushes "0" into the transmit buffer and initiates
* a transfer. If false, this function assumes that data is already in the
* receive FIFO from a previous write.
* @param initiate If true, this function pushes "0" into the transmit buffer and initiates a
* transfer. If false, this function assumes that data is already in the receive FIFO from a
* previous write.
* @param dataReceived The buffer to be filled with the received data.
* @param size The length of the transaction, in bytes
* @param size The length of the transaction, in bytes
*/
@SuppressWarnings("ByteBufferBackingArray")
public int read(boolean initiate, ByteBuffer dataReceived, int size) {
@@ -240,9 +237,9 @@ public class SPI implements AutoCloseable {
/**
* Perform a simultaneous read/write transaction with the device.
*
* @param dataToSend The data to be written out to the device
* @param dataToSend The data to be written out to the device
* @param dataReceived Buffer to receive data from the device
* @param size The length of the transaction, in bytes
* @param size The length of the transaction, in bytes
*/
public int transaction(byte[] dataToSend, byte[] dataReceived, int size) {
if (dataToSend.length < size) {
@@ -257,9 +254,9 @@ public class SPI implements AutoCloseable {
/**
* Perform a simultaneous read/write transaction with the device.
*
* @param dataToSend The data to be written out to the device.
* @param dataToSend The data to be written out to the device.
* @param dataReceived Buffer to receive data from the device.
* @param size The length of the transaction, in bytes
* @param size The length of the transaction, in bytes
*/
@SuppressWarnings({"PMD.CyclomaticComplexity", "ByteBufferBackingArray"})
public int transaction(ByteBuffer dataToSend, ByteBuffer dataReceived, int size) {
@@ -284,8 +281,8 @@ public class SPI implements AutoCloseable {
/**
* Initialize automatic SPI transfer engine.
*
* <p>Only a single engine is available, and use of it blocks use of all other
* chip select usage on the same physical SPI port while it is running.
* <p>Only a single engine is available, and use of it blocks use of all other chip select usage
* on the same physical SPI port while it is running.
*
* @param bufferSize buffer size in bytes
*/
@@ -293,9 +290,7 @@ public class SPI implements AutoCloseable {
SPIJNI.spiInitAuto(m_port, bufferSize);
}
/**
* Frees the automatic SPI transfer engine.
*/
/** Frees the automatic SPI transfer engine. */
public void freeAuto() {
SPIJNI.spiFreeAuto(m_port);
}
@@ -303,8 +298,7 @@ public class SPI implements AutoCloseable {
/**
* Set the data to be transmitted by the engine.
*
* <p>Up to 16 bytes are configurable, and may be followed by up to 127 zero
* bytes.
* <p>Up to 16 bytes are configurable, and may be followed by up to 127 zero bytes.
*
* @param dataToSend data to send (maximum 16 bytes)
* @param zeroSize number of zeros to send after the data
@@ -316,8 +310,8 @@ public class SPI implements AutoCloseable {
/**
* Start running the automatic SPI transfer engine at a periodic rate.
*
* <p>{@link #initAuto(int)} and {@link #setAutoTransmitData(byte[], int)} must
* be called before calling this function.
* <p>{@link #initAuto(int)} and {@link #setAutoTransmitData(byte[], int)} must be called before
* calling this function.
*
* @param period period between transfers, in seconds (us resolution)
*/
@@ -328,28 +322,28 @@ public class SPI implements AutoCloseable {
/**
* Start running the automatic SPI transfer engine when a trigger occurs.
*
* <p>{@link #initAuto(int)} and {@link #setAutoTransmitData(byte[], int)} must
* be called before calling this function.
* <p>{@link #initAuto(int)} and {@link #setAutoTransmitData(byte[], int)} must be called before
* calling this function.
*
* @param source digital source for the trigger (may be an analog trigger)
* @param rising trigger on the rising edge
* @param falling trigger on the falling edge
*/
public void startAutoTrigger(DigitalSource source, boolean rising, boolean falling) {
SPIJNI.spiStartAutoTrigger(m_port, source.getPortHandleForRouting(),
source.getAnalogTriggerTypeForRouting(), rising, falling);
SPIJNI.spiStartAutoTrigger(
m_port,
source.getPortHandleForRouting(),
source.getAnalogTriggerTypeForRouting(),
rising,
falling);
}
/**
* Stop running the automatic SPI transfer engine.
*/
/** Stop running the automatic SPI transfer engine. */
public void stopAuto() {
SPIJNI.spiStopAuto(m_port);
}
/**
* Force the engine to make a single transfer.
*/
/** Force the engine to make a single transfer. */
public void forceAutoRead() {
SPIJNI.spiForceAutoRead(m_port);
}
@@ -357,16 +351,15 @@ public class SPI implements AutoCloseable {
/**
* Read data that has been transferred by the automatic SPI transfer engine.
*
* <p>Transfers may be made a byte at a time, so it's necessary for the caller
* to handle cases where an entire transfer has not been completed.
* <p>Transfers may be made a byte at a time, so it's necessary for the caller to handle cases
* where an entire transfer has not been completed.
*
* <p>Each received data sequence consists of a timestamp followed by the
* received data bytes, one byte per word (in the least significant byte).
* The length of each received data sequence is the same as the combined
* size of the data and zeroSize set in setAutoTransmitData().
* <p>Each received data sequence consists of a timestamp followed by the received data bytes, one
* byte per word (in the least significant byte). The length of each received data sequence is the
* same as the combined size of the data and zeroSize set in setAutoTransmitData().
*
* <p>Blocks until numToRead words have been read or timeout expires.
* May be called with numToRead=0 to retrieve how many words are available.
* <p>Blocks until numToRead words have been read or timeout expires. May be called with
* numToRead=0 to retrieve how many words are available.
*
* @param buffer buffer where read words are stored
* @param numToRead number of words to read
@@ -378,8 +371,8 @@ public class SPI implements AutoCloseable {
throw new IllegalArgumentException("must be a direct buffer");
}
if (buffer.capacity() < numToRead * 4) {
throw new IllegalArgumentException("buffer is too small, must be at least "
+ (numToRead * 4));
throw new IllegalArgumentException(
"buffer is too small, must be at least " + (numToRead * 4));
}
return SPIJNI.spiReadAutoReceivedData(m_port, buffer, numToRead, timeout);
}
@@ -387,16 +380,15 @@ public class SPI implements AutoCloseable {
/**
* Read data that has been transferred by the automatic SPI transfer engine.
*
* <p>Transfers may be made a byte at a time, so it's necessary for the caller
* to handle cases where an entire transfer has not been completed.
* <p>Transfers may be made a byte at a time, so it's necessary for the caller to handle cases
* where an entire transfer has not been completed.
*
* <p>Each received data sequence consists of a timestamp followed by the
* received data bytes, one byte per word (in the least significant byte).
* The length of each received data sequence is the same as the combined
* size of the data and zeroSize set in setAutoTransmitData().
* <p>Each received data sequence consists of a timestamp followed by the received data bytes, one
* byte per word (in the least significant byte). The length of each received data sequence is the
* same as the combined size of the data and zeroSize set in setAutoTransmitData().
*
* <p>Blocks until numToRead words have been read or timeout expires.
* May be called with numToRead=0 to retrieve how many words are available.
* <p>Blocks until numToRead words have been read or timeout expires. May be called with
* numToRead=0 to retrieve how many words are available.
*
* @param buffer array where read words are stored
* @param numToRead number of words to read
@@ -411,8 +403,8 @@ public class SPI implements AutoCloseable {
}
/**
* Get the number of bytes dropped by the automatic SPI transfer engine due
* to the receive buffer being full.
* Get the number of bytes dropped by the automatic SPI transfer engine due to the receive buffer
* being full.
*
* @return Number of bytes dropped
*/
@@ -435,13 +427,21 @@ public class SPI implements AutoCloseable {
@SuppressWarnings("PMD.TooManyFields")
private static class Accumulator implements AutoCloseable {
Accumulator(int port, int xferSize, int validMask, int validValue, int dataShift,
int dataSize, boolean isSigned, boolean bigEndian) {
Accumulator(
int port,
int xferSize,
int validMask,
int validValue,
int dataShift,
int dataSize,
boolean isSigned,
boolean bigEndian) {
m_notifier = new Notifier(this::update);
m_buf = ByteBuffer.allocateDirect((xferSize + 1) * kAccumulateDepth * 4)
.order(ByteOrder.nativeOrder());
m_buf =
ByteBuffer.allocateDirect((xferSize + 1) * kAccumulateDepth * 4)
.order(ByteOrder.nativeOrder());
m_intBuf = m_buf.asIntBuffer();
m_xferSize = xferSize + 1; // +1 for timestamp
m_xferSize = xferSize + 1; // +1 for timestamp
m_validMask = validMask;
m_validValue = validValue;
m_dataShift = dataShift;
@@ -474,12 +474,12 @@ public class SPI implements AutoCloseable {
final int m_validMask;
final int m_validValue;
final int m_dataMax; // one more than max data value
final int m_dataMsbMask; // data field MSB mask (for signed)
final int m_dataShift; // data field shift right amount, in bits
final int m_xferSize; // SPI transfer size, in bytes
final boolean m_isSigned; // is data field signed?
final boolean m_bigEndian; // is response big endian?
final int m_dataMax; // one more than max data value
final int m_dataMsbMask; // data field MSB mask (for signed)
final int m_dataShift; // data field shift right amount, in bits
final int m_xferSize; // SPI transfer size, in bytes
final boolean m_isSigned; // is data field signed?
final boolean m_bigEndian; // is response big endian?
final int m_port;
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
@@ -499,7 +499,7 @@ public class SPI implements AutoCloseable {
done = false;
}
if (numToRead == 0) {
return; // no samples
return; // no samples
}
// read buffered data
@@ -542,11 +542,12 @@ public class SPI implements AutoCloseable {
if (m_count != 0) {
// timestamps use the 1us FPGA clock; also handle rollover
if (timestamp >= m_lastTimestamp) {
m_integratedValue += dataNoCenter * (timestamp - m_lastTimestamp)
* 1e-6 - m_integratedCenter;
m_integratedValue +=
dataNoCenter * (timestamp - m_lastTimestamp) * 1e-6 - m_integratedCenter;
} else {
m_integratedValue += dataNoCenter * ((1L << 32) - m_lastTimestamp + timestamp)
* 1e-6 - m_integratedCenter;
m_integratedValue +=
dataNoCenter * ((1L << 32) - m_lastTimestamp + timestamp) * 1e-6
- m_integratedCenter;
}
}
}
@@ -568,20 +569,26 @@ public class SPI implements AutoCloseable {
/**
* Initialize the accumulator.
*
* @param period Time between reads
* @param cmd SPI command to send to request data
* @param xferSize SPI transfer size, in bytes
* @param validMask Mask to apply to received data for validity checking
* @param period Time between reads
* @param cmd SPI command to send to request data
* @param xferSize SPI transfer size, in bytes
* @param validMask Mask to apply to received data for validity checking
* @param validValue After validMask is applied, required matching value for validity checking
* @param dataShift Bit shift to apply to received data to get actual data value
* @param dataSize Size (in bits) of data field
* @param isSigned Is data field signed?
* @param bigEndian Is device big endian?
* @param dataShift Bit shift to apply to received data to get actual data value
* @param dataSize Size (in bits) of data field
* @param isSigned Is data field signed?
* @param bigEndian Is device big endian?
*/
public void initAccumulator(double period, int cmd, int xferSize,
int validMask, int validValue,
int dataShift, int dataSize,
boolean isSigned, boolean bigEndian) {
public void initAccumulator(
double period,
int cmd,
int xferSize,
int validMask,
int validValue,
int dataShift,
int dataSize,
boolean isSigned,
boolean bigEndian) {
initAuto(xferSize * 2048);
byte[] cmdBytes = new byte[] {0, 0, 0, 0};
if (bigEndian) {
@@ -601,14 +608,13 @@ public class SPI implements AutoCloseable {
setAutoTransmitData(cmdBytes, xferSize - 4);
startAutoRate(period);
m_accum = new Accumulator(m_port, xferSize, validMask, validValue, dataShift, dataSize,
isSigned, bigEndian);
m_accum =
new Accumulator(
m_port, xferSize, validMask, validValue, dataShift, dataSize, isSigned, bigEndian);
m_accum.m_notifier.startPeriodic(period * 1024);
}
/**
* Frees the accumulator.
*/
/** Frees the accumulator. */
public void freeAccumulator() {
if (m_accum != null) {
m_accum.close();
@@ -617,9 +623,7 @@ public class SPI implements AutoCloseable {
freeAuto();
}
/**
* Resets the accumulator to zero.
*/
/** Resets the accumulator to zero. */
public void resetAccumulator() {
if (m_accum == null) {
return;
@@ -649,9 +653,7 @@ public class SPI implements AutoCloseable {
}
}
/**
* Set the accumulator's deadband.
*/
/** Set the accumulator's deadband. */
public void setAccumulatorDeadband(int deadband) {
if (m_accum == null) {
return;
@@ -661,9 +663,7 @@ public class SPI implements AutoCloseable {
}
}
/**
* Read the last value read by the accumulator engine.
*/
/** Read the last value read by the accumulator engine. */
public int getAccumulatorLastValue() {
if (m_accum == null) {
return 0;
@@ -750,9 +750,9 @@ public class SPI implements AutoCloseable {
/**
* Set the center value of the accumulator integrator.
*
* <p>The center value is subtracted from each value*dt before it is added to the
* integrated value. This is used for the center value of devices like gyros
* and accelerometers to take the device offset into account when integrating.
* <p>The center value is subtracted from each value*dt before it is added to the integrated
* value. This is used for the center value of devices like gyros and accelerometers to take the
* device offset into account when integrating.
*/
public void setAccumulatorIntegratedCenter(double center) {
if (m_accum == null) {
@@ -764,8 +764,7 @@ public class SPI implements AutoCloseable {
}
/**
* Read the integrated value. This is the sum of (each value * time between
* values).
* Read the integrated value. This is the sum of (each value * time between values).
*
* @return The integrated value accumulated since the last Reset().
*/
@@ -780,11 +779,10 @@ public class SPI implements AutoCloseable {
}
/**
* Read the average of the integrated value. This is the sum of (each value
* times the time between values), divided by the count.
* Read the average of the integrated value. This is the sum of (each value times the time between
* values), divided by the count.
*
* @return The average of the integrated value accumulated since the last
* Reset().
* @return The average of the integrated value accumulated since the last Reset().
*/
public double getAccumulatorIntegratedAverage() {
if (m_accum == null) {

View File

@@ -7,10 +7,7 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* The base interface for objects that can be sent over the network through network tables.
*/
/** The base interface for objects that can be sent over the network through network tables. */
public interface Sendable {
/**
* Gets the name of this {@link Sendable} object.
@@ -50,7 +47,7 @@ public interface Sendable {
* Sets the name of the sensor with a channel number.
*
* @param moduleType A string that defines the module name in the label for the value
* @param channel The channel number the device is plugged into
* @param channel The channel number the device is plugged into
* @deprecated Use SendableRegistry.setName()
*/
@Deprecated(since = "2020", forRemoval = true)
@@ -61,9 +58,9 @@ public interface Sendable {
/**
* Sets the name of the sensor with a module and channel number.
*
* @param moduleType A string that defines the module name in the label for the value
* @param moduleType A string that defines the module name in the label for the value
* @param moduleNumber The number of the particular module type
* @param channel The channel number the device is plugged into (usually PWM)
* @param channel The channel number the device is plugged into (usually PWM)
* @deprecated Use SendableRegistry.setName()
*/
@Deprecated(since = "2020", forRemoval = true)

View File

@@ -9,13 +9,12 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Base class for all sensors. Stores most recent status information as well as containing utility
* functions for checking channels and error processing.
*
* @deprecated Use Sendable and SendableRegistry
*/
@Deprecated(since = "2020", forRemoval = true)
public abstract class SendableBase implements Sendable, AutoCloseable {
/**
* Creates an instance of the sensor base.
*/
/** Creates an instance of the sensor base. */
public SendableBase() {
this(true);
}

View File

@@ -18,55 +18,35 @@ import edu.wpi.first.hal.SolenoidJNI;
* channels and error processing.
*/
public final class SensorUtil {
/**
* Ticks per microsecond.
*/
public static final int kSystemClockTicksPerMicrosecond
= ConstantsJNI.getSystemClockTicksPerMicrosecond();
/** Ticks per microsecond. */
public static final int kSystemClockTicksPerMicrosecond =
ConstantsJNI.getSystemClockTicksPerMicrosecond();
/**
* Number of digital channels per roboRIO.
*/
/** Number of digital channels per roboRIO. */
public static final int kDigitalChannels = PortsJNI.getNumDigitalChannels();
/**
* Number of analog input channels per roboRIO.
*/
/** Number of analog input channels per roboRIO. */
public static final int kAnalogInputChannels = PortsJNI.getNumAnalogInputs();
/**
* Number of analog output channels per roboRIO.
*/
/** Number of analog output channels per roboRIO. */
public static final int kAnalogOutputChannels = PortsJNI.getNumAnalogOutputs();
/**
* Number of solenoid channels per module.
*/
/** Number of solenoid channels per module. */
public static final int kSolenoidChannels = PortsJNI.getNumSolenoidChannels();
/**
* Number of PWM channels per roboRIO.
*/
/** Number of PWM channels per roboRIO. */
public static final int kPwmChannels = PortsJNI.getNumPWMChannels();
/**
* Number of relay channels per roboRIO.
*/
/** Number of relay channels per roboRIO. */
public static final int kRelayChannels = PortsJNI.getNumRelayHeaders();
/**
* Number of power distribution channels per PDP.
*/
/** Number of power distribution channels per PDP. */
public static final int kPDPChannels = PortsJNI.getNumPDPChannels();
/**
* Number of power distribution modules per PDP.
*/
/** Number of power distribution modules per PDP. */
public static final int kPDPModules = PortsJNI.getNumPDPModules();
/**
* Number of PCM Modules.
*/
/** Number of PCM Modules. */
public static final int kPCMModules = PortsJNI.getNumPCMModules();
/**
@@ -228,6 +208,5 @@ public final class SensorUtil {
return 0;
}
private SensorUtil() {
}
private SensorUtil() {}
}

View File

@@ -4,20 +4,21 @@
package edu.wpi.first.wpilibj;
import java.nio.charset.StandardCharsets;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.SerialPortJNI;
import java.nio.charset.StandardCharsets;
/**
* Driver for the serial ports (USB, MXP, Onboard) on the roboRIO.
*/
/** Driver for the serial ports (USB, MXP, Onboard) on the roboRIO. */
public class SerialPort implements AutoCloseable {
private int m_portHandle;
public enum Port {
kOnboard(0), kMXP(1), kUSB(2), kUSB1(2), kUSB2(3);
kOnboard(0),
kMXP(1),
kUSB(2),
kUSB1(2),
kUSB2(3);
public final int value;
@@ -26,11 +27,13 @@ public class SerialPort implements AutoCloseable {
}
}
/**
* Represents the parity to use for serial communications.
*/
/** Represents the parity to use for serial communications. */
public enum Parity {
kNone(0), kOdd(1), kEven(2), kMark(3), kSpace(4);
kNone(0),
kOdd(1),
kEven(2),
kMark(3),
kSpace(4);
public final int value;
@@ -39,11 +42,11 @@ public class SerialPort implements AutoCloseable {
}
}
/**
* Represents the number of stop bits to use for Serial Communication.
*/
/** Represents the number of stop bits to use for Serial Communication. */
public enum StopBits {
kOne(10), kOnePointFive(15), kTwo(20);
kOne(10),
kOnePointFive(15),
kTwo(20);
public final int value;
@@ -52,11 +55,12 @@ public class SerialPort implements AutoCloseable {
}
}
/**
* Represents what type of flow control to use for serial communication.
*/
/** Represents what type of flow control to use for serial communication. */
public enum FlowControl {
kNone(0), kXonXoff(1), kRtsCts(2), kDtsDsr(4);
kNone(0),
kXonXoff(1),
kRtsCts(2),
kDtsDsr(4);
public final int value;
@@ -65,11 +69,10 @@ public class SerialPort implements AutoCloseable {
}
}
/**
* Represents which type of buffer mode to use when writing to a serial port.
*/
/** Represents which type of buffer mode to use when writing to a serial port. */
public enum WriteBufferMode {
kFlushOnAccess(1), kFlushWhenFull(2);
kFlushOnAccess(1),
kFlushWhenFull(2);
public final int value;
@@ -81,19 +84,24 @@ public class SerialPort implements AutoCloseable {
/**
* Create an instance of a Serial Port class.
*
* <p>Prefer to use the constructor that doesn't take a port name, but in some
* cases the automatic detection might not work correctly.
* <p>Prefer to use the constructor that doesn't take a port name, but in some cases the automatic
* detection might not work correctly.
*
* @param baudRate The baud rate to configure the serial port.
* @param port The Serial port to use
* @param port The Serial port to use
* @param portName The direct portName to use
* @param dataBits The number of data bits per transfer. Valid values are between 5 and 8 bits.
* @param parity Select the type of parity checking to use.
* @param parity Select the type of parity checking to use.
* @param stopBits The number of stop bits to use as defined by the enum StopBits.
* @deprecated Will be removed for 2019
* @deprecated Will be removed for 2019
*/
public SerialPort(final int baudRate, String portName, Port port, final int dataBits,
Parity parity, StopBits stopBits) {
public SerialPort(
final int baudRate,
String portName,
Port port,
final int dataBits,
Parity parity,
StopBits stopBits) {
m_portHandle = SerialPortJNI.serialInitializePortDirect((byte) port.value, portName);
SerialPortJNI.serialSetBaudRate(m_portHandle, baudRate);
SerialPortJNI.serialSetDataBits(m_portHandle, (byte) dataBits);
@@ -118,13 +126,13 @@ public class SerialPort implements AutoCloseable {
* Create an instance of a Serial Port class.
*
* @param baudRate The baud rate to configure the serial port.
* @param port The Serial port to use
* @param port The Serial port to use
* @param dataBits The number of data bits per transfer. Valid values are between 5 and 8 bits.
* @param parity Select the type of parity checking to use.
* @param parity Select the type of parity checking to use.
* @param stopBits The number of stop bits to use as defined by the enum StopBits.
*/
public SerialPort(final int baudRate, Port port, final int dataBits, Parity parity,
StopBits stopBits) {
public SerialPort(
final int baudRate, Port port, final int dataBits, Parity parity, StopBits stopBits) {
m_portHandle = SerialPortJNI.serialInitializePort((byte) port.value);
SerialPortJNI.serialSetBaudRate(m_portHandle, baudRate);
SerialPortJNI.serialSetDataBits(m_portHandle, (byte) dataBits);
@@ -150,7 +158,7 @@ public class SerialPort implements AutoCloseable {
*
* @param baudRate The baud rate to configure the serial port.
* @param dataBits The number of data bits per transfer. Valid values are between 5 and 8 bits.
* @param parity Select the type of parity checking to use.
* @param parity Select the type of parity checking to use.
*/
public SerialPort(final int baudRate, Port port, final int dataBits, Parity parity) {
this(baudRate, port, dataBits, parity, StopBits.kOne);
@@ -167,8 +175,7 @@ public class SerialPort implements AutoCloseable {
}
/**
* Create an instance of a Serial Port class. Defaults to 8 databits, no parity, and one stop
* bit.
* Create an instance of a Serial Port class. Defaults to 8 databits, no parity, and one stop bit.
*
* @param baudRate The baud rate to configure the serial port.
*/
@@ -218,9 +225,7 @@ public class SerialPort implements AutoCloseable {
enableTermination('\n');
}
/**
* Disable termination behavior.
*/
/** Disable termination behavior. */
public void disableTermination() {
SerialPortJNI.serialDisableTermination(m_portHandle);
}
@@ -275,7 +280,7 @@ public class SerialPort implements AutoCloseable {
* Write raw bytes to the serial port.
*
* @param buffer The buffer of bytes to write.
* @param count The maximum number of bytes to write.
* @param count The maximum number of bytes to write.
* @return The number of bytes actually written into the port.
*/
public int write(byte[] buffer, int count) {
@@ -336,11 +341,11 @@ public class SerialPort implements AutoCloseable {
/**
* Specify the flushing behavior of the output buffer.
*
* <p>When set to kFlushOnAccess, data is synchronously written to the serial port after each
* call to either print() or write().
* <p>When set to kFlushOnAccess, data is synchronously written to the serial port after each call
* to either print() or write().
*
* <p>When set to kFlushWhenFull, data will only be written to the serial port when the buffer
* is full or when flush() is called.
* <p>When set to kFlushWhenFull, data will only be written to the serial port when the buffer is
* full or when flush() is called.
*
* @param mode The write buffer mode.
*/

View File

@@ -25,11 +25,11 @@ public class Servo extends PWM {
/**
* Constructor.<br>
*
* <p>By default {@value #kDefaultMaxServoPWM} ms is used as the maxPWM value<br> By default
* {@value #kDefaultMinServoPWM} ms is used as the minPWM value<br>
* <p>By default {@value #kDefaultMaxServoPWM} ms is used as the maxPWM value<br>
* By default {@value #kDefaultMinServoPWM} ms is used as the minPWM value<br>
*
* @param channel The PWM channel to which the servo is attached. 0-9 are on-board, 10-19 are on
* the MXP port
* the MXP port
*/
public Servo(final int channel) {
super(channel);
@@ -40,7 +40,6 @@ public class Servo extends PWM {
SendableRegistry.setName(this, "Servo", getChannel());
}
/**
* Set the servo position.
*

View File

@@ -7,10 +7,10 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.wpiutil.math.MathUtil;
/**
* A class that limits the rate of change of an input value. Useful for implementing voltage,
* setpoint, and/or output ramps. A slew-rate limit is most appropriate when the quantity being
* controlled is a velocity or a voltage; when controlling a position, consider using a
* {@link edu.wpi.first.wpilibj.trajectory.TrapezoidProfile} instead.
* A class that limits the rate of change of an input value. Useful for implementing voltage,
* setpoint, and/or output ramps. A slew-rate limit is most appropriate when the quantity being
* controlled is a velocity or a voltage; when controlling a position, consider using a {@link
* edu.wpi.first.wpilibj.trajectory.TrapezoidProfile} instead.
*/
public class SlewRateLimiter {
private final double m_rateLimit;
@@ -47,9 +47,8 @@ public class SlewRateLimiter {
public double calculate(double input) {
double currentTime = Timer.getFPGATimestamp();
double elapsedTime = currentTime - m_prevTime;
m_prevVal += MathUtil.clamp(input - m_prevVal,
-m_rateLimit * elapsedTime,
m_rateLimit * elapsedTime);
m_prevVal +=
MathUtil.clamp(input - m_prevVal, -m_rateLimit * elapsedTime, m_rateLimit * elapsedTime);
m_prevTime = currentTime;
return m_prevVal;
}

View File

@@ -13,8 +13,8 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Solenoid class for running high voltage Digital Output on the PCM.
*
* <p>The Solenoid class is typically used for pneumatic solenoids, but could be used for any
* device within the current spec of the PCM.
* <p>The Solenoid class is typically used for pneumatic solenoids, but could be used for any device
* within the current spec of the PCM.
*/
public class Solenoid extends SolenoidBase implements Sendable, AutoCloseable {
private final int m_channel; // The channel to control.
@@ -33,7 +33,7 @@ public class Solenoid extends SolenoidBase implements Sendable, AutoCloseable {
* Constructor.
*
* @param moduleNumber The CAN ID of the PCM the solenoid is attached to.
* @param channel The channel on the PCM to control (0..7).
* @param channel The channel on the PCM to control (0..7).
*/
public Solenoid(final int moduleNumber, final int channel) {
super(moduleNumber);
@@ -97,12 +97,11 @@ public class Solenoid extends SolenoidBase implements Sendable, AutoCloseable {
}
/**
* Set the pulse duration in the PCM. This is used in conjunction with
* the startPulse method to allow the PCM to control the timing of a pulse.
* The timing can be controlled in 0.01 second increments.
* Set the pulse duration in the PCM. This is used in conjunction with the startPulse method to
* allow the PCM to control the timing of a pulse. The timing can be controlled in 0.01 second
* increments.
*
* @param durationSeconds The duration of the pulse, from 0.01 to 2.55 seconds.
*
* @see #startPulse()
*/
public void setPulseDuration(double durationSeconds) {
@@ -111,8 +110,7 @@ public class Solenoid extends SolenoidBase implements Sendable, AutoCloseable {
}
/**
* Trigger the PCM to generate a pulse of the duration set in
* setPulseDuration.
* Trigger the PCM to generate a pulse of the duration set in setPulseDuration.
*
* @see #setPulseDuration(double)
*/

View File

@@ -12,23 +12,21 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
* REV Robotics SPARK Speed Controller.
*
* <p>Note that the SPARK uses the following bounds for PWM values. These values should work
* reasonably well for most controllers, but if users experience issues such as asymmetric
* behavior around the deadband or inability to saturate the controller in either direction,
* calibration is recommended. The calibration procedure can be found in the Spark User Manual
* available from REV Robotics.
* reasonably well for most controllers, but if users experience issues such as asymmetric behavior
* around the deadband or inability to saturate the controller in either direction, calibration is
* recommended. The calibration procedure can be found in the Spark User Manual available from REV
* Robotics.
*
* <p><ul>
* <li>2.003ms = full "forward"
* <li>1.550ms = the "high end" of the deadband range
* <li>1.500ms = center of the deadband range (off)
* <li>1.460ms = the "low end" of the deadband range
* <li>0.999ms = full "reverse"
* <ul>
* <li>2.003ms = full "forward"
* <li>1.550ms = the "high end" of the deadband range
* <li>1.500ms = center of the deadband range (off)
* <li>1.460ms = the "low end" of the deadband range
* <li>0.999ms = full "reverse"
* </ul>
*/
public class Spark extends PWMSpeedController {
/**
* Common initialization code called by all constructors.
*/
/** Common initialization code called by all constructors. */
protected void initSpark() {
setBounds(2.003, 1.55, 1.50, 1.46, 0.999);
setPeriodMultiplier(PeriodMultiplier.k1X);
@@ -43,7 +41,7 @@ public class Spark extends PWMSpeedController {
* Constructor.
*
* @param channel The PWM channel that the SPARK is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
* the MXP port
*/
public Spark(final int channel) {
super(channel);

View File

@@ -4,9 +4,7 @@
package edu.wpi.first.wpilibj;
/**
* Interface for speed controlling devices.
*/
/** Interface for speed controlling devices. */
public interface SpeedController extends PIDOutput {
/**
* Common interface for setting the speed of a speed controller.
@@ -16,10 +14,10 @@ public interface SpeedController extends PIDOutput {
void set(double speed);
/**
* Sets the voltage output of the SpeedController. Compensates for the current bus
* voltage to ensure that the desired voltage is output even if the battery voltage is below
* 12V - highly useful when the voltage outputs are "meaningful" (e.g. they come from a
* feedforward calculation).
* Sets the voltage output of the SpeedController. Compensates for the current bus voltage to
* ensure that the desired voltage is output even if the battery voltage is below 12V - highly
* useful when the voltage outputs are "meaningful" (e.g. they come from a feedforward
* calculation).
*
* <p>NOTE: This function *must* be called regularly in order for voltage compensation to work
* properly - unlike the ordinary set function, it is not "set it and forget it."
@@ -51,9 +49,7 @@ public interface SpeedController extends PIDOutput {
*/
boolean getInverted();
/**
* Disable the speed controller.
*/
/** Disable the speed controller. */
void disable();
/**

View File

@@ -4,14 +4,11 @@
package edu.wpi.first.wpilibj;
import java.util.Arrays;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import java.util.Arrays;
/**
* Allows multiple {@link SpeedController} objects to be linked together.
*/
/** Allows multiple {@link SpeedController} objects to be linked together. */
public class SpeedControllerGroup implements SpeedController, Sendable, AutoCloseable {
private boolean m_isInverted;
private final SpeedController[] m_speedControllers;
@@ -23,8 +20,8 @@ public class SpeedControllerGroup implements SpeedController, Sendable, AutoClos
* @param speedControllers The SpeedControllers to add
*/
@SuppressWarnings("PMD.AvoidArrayLoops")
public SpeedControllerGroup(SpeedController speedController,
SpeedController... speedControllers) {
public SpeedControllerGroup(
SpeedController speedController, SpeedController... speedControllers) {
m_speedControllers = new SpeedController[speedControllers.length + 1];
m_speedControllers[0] = speedController;
for (int i = 0; i < speedControllers.length; i++) {

View File

@@ -12,17 +12,16 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
* Cross the Road Electronics (CTRE) Talon and Talon SR Speed Controller.
*
* <p>Note that the Talon uses the following bounds for PWM values. These values should work
* reasonably well for most controllers, but if users experience issues such as asymmetric
* behavior around the deadband or inability to saturate the controller in either direction,
* calibration is recommended. The calibration procedure can be found in the Talon User Manual
* available from CTRE.
* reasonably well for most controllers, but if users experience issues such as asymmetric behavior
* around the deadband or inability to saturate the controller in either direction, calibration is
* recommended. The calibration procedure can be found in the Talon User Manual available from CTRE.
*
* <p><ul>
* <li>2.037ms = full "forward"
* <li>1.539ms = the "high end" of the deadband range
* <li>1.513ms = center of the deadband range (off)
* <li>1.487ms = the "low end" of the deadband range
* <li>0.989ms = full "reverse"
* <ul>
* <li>2.037ms = full "forward"
* <li>1.539ms = the "high end" of the deadband range
* <li>1.513ms = center of the deadband range (off)
* <li>1.487ms = the "low end" of the deadband range
* <li>0.989ms = full "reverse"
* </ul>
*/
public class Talon extends PWMSpeedController {
@@ -30,7 +29,7 @@ public class Talon extends PWMSpeedController {
* Constructor for a Talon (original or Talon SR).
*
* @param channel The PWM channel that the Talon is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
* the MXP port
*/
public Talon(final int channel) {
super(channel);

View File

@@ -8,35 +8,34 @@ import edu.wpi.first.hal.ThreadsJNI;
public final class Threads {
/**
* Get the thread priority for the current thread.
* @return The current thread priority. Scaled 1-99.
*/
* Get the thread priority for the current thread.
*
* @return The current thread priority. Scaled 1-99.
*/
public static int getCurrentThreadPriority() {
return ThreadsJNI.getCurrentThreadPriority();
}
/**
* Get if the current thread is realtime.
* @return If the current thread is realtime
*/
* Get if the current thread is realtime.
*
* @return If the current thread is realtime
*/
public static boolean getCurrentThreadIsRealTime() {
return ThreadsJNI.getCurrentThreadIsRealTime();
}
/**
* Sets the thread priority for the current thread.
*
* @param realTime Set to true to set a realtime priority, false for standard
* priority
* @param priority Priority to set the thread to. Scaled 1-99, with 1 being
* highest. On RoboRIO, priority is ignored for non realtime setting
*
* @return The success state of setting the priority
*/
* Sets the thread priority for the current thread.
*
* @param realTime Set to true to set a realtime priority, false for standard priority
* @param priority Priority to set the thread to. Scaled 1-99, with 1 being highest. On RoboRIO,
* priority is ignored for non realtime setting
* @return The success state of setting the priority
*/
public static boolean setCurrentThreadPriority(boolean realTime, int priority) {
return ThreadsJNI.setCurrentThreadPriority(realTime, priority);
}
private Threads() {
}
private Threads() {}
}

View File

@@ -4,12 +4,11 @@
package edu.wpi.first.wpilibj;
import java.util.PriorityQueue;
import edu.wpi.first.hal.FRCNetComm.tInstances;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.NotifierJNI;
import java.util.PriorityQueue;
/**
* TimedRobot implements the IterativeRobotBase robot program framework.
@@ -28,20 +27,20 @@ public class TimedRobot extends IterativeRobotBase {
/**
* Construct a callback container.
*
* @param func The callback to run.
* @param startTimeSeconds The common starting point for all callback
* scheduling in seconds.
* @param periodSeconds The period at which to run the callback in
* seconds.
* @param offsetSeconds The offset from the common starting time in
* seconds.
* @param func The callback to run.
* @param startTimeSeconds The common starting point for all callback scheduling in seconds.
* @param periodSeconds The period at which to run the callback in seconds.
* @param offsetSeconds The offset from the common starting time in seconds.
*/
Callback(Runnable func, double startTimeSeconds, double periodSeconds, double offsetSeconds) {
this.func = func;
this.period = periodSeconds;
this.expirationTime = startTimeSeconds + offsetSeconds
+ Math.floor((Timer.getFPGATimestamp() - startTimeSeconds)
/ this.period) * this.period + this.period;
this.expirationTime =
startTimeSeconds
+ offsetSeconds
+ Math.floor((Timer.getFPGATimestamp() - startTimeSeconds) / this.period)
* this.period
+ this.period;
}
@Override
@@ -62,9 +61,7 @@ public class TimedRobot extends IterativeRobotBase {
private final PriorityQueue<Callback> m_callbacks = new PriorityQueue<>();
/**
* Constructor for TimedRobot.
*/
/** Constructor for TimedRobot. */
protected TimedRobot() {
this(kDefaultPeriod);
}
@@ -90,9 +87,7 @@ public class TimedRobot extends IterativeRobotBase {
NotifierJNI.cleanNotifier(m_notifier);
}
/**
* Provide an alternate "main loop" via startCompetition().
*/
/** Provide an alternate "main loop" via startCompetition(). */
@Override
@SuppressWarnings("UnsafeFinalization")
public void startCompetition() {
@@ -136,17 +131,13 @@ public class TimedRobot extends IterativeRobotBase {
}
}
/**
* Ends the main loop in startCompetition().
*/
/** Ends the main loop in startCompetition(). */
@Override
public void endCompetition() {
NotifierJNI.stopNotifier(m_notifier);
}
/**
* Get time period between calls to Periodic() functions.
*/
/** Get time period between calls to Periodic() functions. */
public double getPeriod() {
return m_period;
}
@@ -157,7 +148,7 @@ public class TimedRobot extends IterativeRobotBase {
* <p>This is scheduled on TimedRobot's Notifier, so TimedRobot and the callback run
* synchronously. Interactions between them are thread-safe.
*
* @param callback The callback to run.
* @param callback The callback to run.
* @param periodSeconds The period at which to run the callback in seconds.
*/
public void addPeriodic(Runnable callback, double periodSeconds) {
@@ -170,11 +161,10 @@ public class TimedRobot extends IterativeRobotBase {
* <p>This is scheduled on TimedRobot's Notifier, so TimedRobot and the callback run
* synchronously. Interactions between them are thread-safe.
*
* @param callback The callback to run.
* @param callback The callback to run.
* @param periodSeconds The period at which to run the callback in seconds.
* @param offsetSeconds The offset from the common starting time in seconds.
* This is useful for scheduling a callback in a
* different timeslot relative to TimedRobot.
* @param offsetSeconds The offset from the common starting time in seconds. This is useful for
* scheduling a callback in a different timeslot relative to TimedRobot.
*/
public void addPeriodic(Runnable callback, double periodSeconds, double offsetSeconds) {
m_callbacks.add(new Callback(callback, m_startTime, periodSeconds, offsetSeconds));

View File

@@ -20,8 +20,8 @@ public class Timer {
* Return the approximate match time. The FMS does not send an official match time to the robots,
* but does send an approximate match time. The value will count down the time remaining in the
* current period (auto or teleop). Warning: This is not an official time (so it cannot be used to
* dispute ref calls or guarantee that a function will trigger before the match ends) The
* Practice Match function of the DS approximates the behavior seen on the field.
* dispute ref calls or guarantee that a function will trigger before the match ends) The Practice
* Match function of the DS approximates the behavior seen on the field.
*
* @return Time remaining in current match period (auto or teleop) in seconds
*/
@@ -49,9 +49,7 @@ public class Timer {
private double m_accumulatedTime;
private boolean m_running;
/**
* Lock for synchronization.
*/
/** Lock for synchronization. */
private final Object m_lock = new Object();
@SuppressWarnings("MissingJavadocMethod")

View File

@@ -9,12 +9,12 @@ import java.util.Map;
import java.util.function.Consumer;
/**
* A class for keeping track of how much time it takes for different parts of code to execute.
* This is done with epochs, that are added by calls to {@link #addEpoch(String)},
* and can be printed with a call to {@link #printEpochs()}.
* A class for keeping track of how much time it takes for different parts of code to execute. This
* is done with epochs, that are added by calls to {@link #addEpoch(String)}, and can be printed
* with a call to {@link #printEpochs()}.
*
* <p>Epochs are a way to partition the time elapsed so that when overruns occur, one can
* determine which parts of an operation consumed the most time.
* <p>Epochs are a way to partition the time elapsed so that when overruns occur, one can determine
* which parts of an operation consumed the most time.
*/
public class Tracer {
private static final long kMinPrintPeriod = 1000000; // microseconds
@@ -25,24 +25,18 @@ public class Tracer {
@SuppressWarnings("PMD.UseConcurrentHashMap")
private final Map<String, Long> m_epochs = new HashMap<>(); // microseconds
/**
* Tracer constructor.
*/
/** Tracer constructor. */
public Tracer() {
resetTimer();
}
/**
* Clears all epochs.
*/
/** Clears all epochs. */
public void clearEpochs() {
m_epochs.clear();
resetTimer();
}
/**
* Restarts the epoch timer.
*/
/** Restarts the epoch timer. */
public void resetTimer() {
m_startTime = RobotController.getFPGATime();
}
@@ -53,8 +47,8 @@ public class Tracer {
* <p>Epochs are a way to partition the time elapsed so that when overruns occur, one can
* determine which parts of an operation consumed the most time.
*
* <p>This should be called immediately after execution has finished,
* with a call to this method or {@link #resetTimer()} before execution.
* <p>This should be called immediately after execution has finished, with a call to this method
* or {@link #resetTimer()} before execution.
*
* @param epochName The name to associate with the epoch.
*/
@@ -64,9 +58,7 @@ public class Tracer {
m_startTime = currentTime;
}
/**
* Prints list of epochs added so far and their times to the DriverStation.
*/
/** Prints list of epochs added so far and their times to the DriverStation. */
public void printEpochs() {
printEpochs(out -> DriverStation.reportWarning(out, false));
}
@@ -83,9 +75,10 @@ public class Tracer {
if (now - m_lastEpochsPrintTime > kMinPrintPeriod) {
StringBuilder sb = new StringBuilder();
m_lastEpochsPrintTime = now;
m_epochs.forEach((key, value) -> {
sb.append(String.format("\t%s: %.6fs\n", key, value / 1.0e6));
});
m_epochs.forEach(
(key, value) -> {
sb.append(String.format("\t%s: %.6fs\n", key, value / 1.0e6));
});
if (sb.length() > 0) {
output.accept(sb.toString());
}

View File

@@ -4,8 +4,7 @@
package edu.wpi.first.wpilibj;
import java.util.ArrayList;
import java.util.List;
import static java.util.Objects.requireNonNull;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
@@ -14,8 +13,8 @@ import edu.wpi.first.hal.SimDevice;
import edu.wpi.first.hal.SimDouble;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import static java.util.Objects.requireNonNull;
import java.util.ArrayList;
import java.util.List;
/**
* Ultrasonic rangefinder class. The Ultrasonic rangefinder measures absolute distance based on the
@@ -27,17 +26,11 @@ import static java.util.Objects.requireNonNull;
* flight).
*/
public class Ultrasonic implements PIDSource, Sendable, AutoCloseable {
/**
* The units to return when PIDGet is called.
*/
/** The units to return when PIDGet is called. */
public enum Unit {
/**
* Use inches for PIDGet.
*/
/** Use inches for PIDGet. */
kInches,
/**
* Use millimeters for PIDGet.
*/
/** Use millimeters for PIDGet. */
kMillimeters
}
@@ -76,16 +69,16 @@ public class Ultrasonic implements PIDSource, Sendable, AutoCloseable {
@Override
public synchronized void run() {
while (m_automaticEnabled) {
for (Ultrasonic sensor: m_sensors) {
for (Ultrasonic sensor : m_sensors) {
if (!m_automaticEnabled) {
break;
}
if (sensor.isEnabled()) {
sensor.m_pingChannel.pulse(kPingTime); // do the ping
sensor.m_pingChannel.pulse(kPingTime); // do the ping
}
Timer.delay(0.1); // wait for ping to return
Timer.delay(0.1); // wait for ping to return
}
}
}
@@ -131,11 +124,10 @@ public class Ultrasonic implements PIDSource, Sendable, AutoCloseable {
* and Vex ultrasonic sensors.
*
* @param pingChannel The digital output channel that sends the pulse to initiate the sensor
* sending the ping.
* sending the ping.
* @param echoChannel The digital input channel that receives the echo. The length of time that
* the echo is high represents the round trip time of the ping, and the
* distance.
* @param units The units returned in either kInches or kMilliMeters
* the echo is high represents the round trip time of the ping, and the distance.
* @param units The units returned in either kInches or kMilliMeters
*/
public Ultrasonic(final int pingChannel, final int echoChannel, Unit units) {
m_pingChannel = new DigitalOutput(pingChannel);
@@ -152,10 +144,9 @@ public class Ultrasonic implements PIDSource, Sendable, AutoCloseable {
* and Vex ultrasonic sensors. Default unit is inches.
*
* @param pingChannel The digital output channel that sends the pulse to initiate the sensor
* sending the ping.
* sending the ping.
* @param echoChannel The digital input channel that receives the echo. The length of time that
* the echo is high represents the round trip time of the ping, and the
* distance.
* the echo is high represents the round trip time of the ping, and the distance.
*/
public Ultrasonic(final int pingChannel, final int echoChannel) {
this(pingChannel, echoChannel, Unit.kInches);
@@ -166,10 +157,9 @@ public class Ultrasonic implements PIDSource, Sendable, AutoCloseable {
* DigitalOutput for the ping channel.
*
* @param pingChannel The digital output object that starts the sensor doing a ping. Requires a
* 10uS pulse to start.
* @param echoChannel The digital input object that times the return pulse to determine the
* range.
* @param units The units returned in either kInches or kMilliMeters
* 10uS pulse to start.
* @param echoChannel The digital input object that times the return pulse to determine the range.
* @param units The units returned in either kInches or kMilliMeters
*/
public Ultrasonic(DigitalOutput pingChannel, DigitalInput echoChannel, Unit units) {
requireNonNull(pingChannel, "Provided ping channel was null");
@@ -187,9 +177,8 @@ public class Ultrasonic implements PIDSource, Sendable, AutoCloseable {
* DigitalOutput for the ping channel. Default unit is inches.
*
* @param pingChannel The digital output object that starts the sensor doing a ping. Requires a
* 10uS pulse to start.
* @param echoChannel The digital input object that times the return pulse to determine the
* range.
* 10uS pulse to start.
* @param echoChannel The digital input object that times the return pulse to determine the range.
*/
public Ultrasonic(DigitalOutput pingChannel, DigitalInput echoChannel) {
this(pingChannel, echoChannel, Unit.kInches);
@@ -242,10 +231,9 @@ public class Ultrasonic implements PIDSource, Sendable, AutoCloseable {
* each sensor.
*
* @param enabling Set to true if round robin scheduling should start for all the ultrasonic
* sensors. This scheduling method assures that the sensors are non-interfering
* because no two sensors fire at the same time. If another scheduling algorithm
* is preferred, it can be implemented by pinging the sensors manually and waiting
* for the results to come back.
* sensors. This scheduling method assures that the sensors are non-interfering because no two
* sensors fire at the same time. If another scheduling algorithm is preferred, it can be
* implemented by pinging the sensors manually and waiting for the results to come back.
*/
public static void setAutomaticMode(boolean enabling) {
if (enabling == m_automaticEnabled) {

View File

@@ -9,30 +9,30 @@ import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* VEX Robotics Victor 888 Speed Controller The Vex Robotics Victor 884 Speed Controller can also
* be used with this class but may need to be calibrated per the Victor 884 user manual.
* VEX Robotics Victor 888 Speed Controller The Vex Robotics Victor 884 Speed Controller can also be
* used with this class but may need to be calibrated per the Victor 884 user manual.
*
* <p>Note that the Victor uses the following bounds for PWM values. These values were determined
* empirically and optimized for the Victor 888. These values should work reasonably well for
* Victor 884 controllers also but if users experience issues such as asymmetric behavior around
* the deadband or inability to saturate the controller in either direction, calibration is
* recommended. The calibration procedure can be found in the Victor 884 User Manual available
* from VEX Robotics: http://content.vexrobotics.com/docs/ifi-v884-users-manual-9-25-06.pdf
* empirically and optimized for the Victor 888. These values should work reasonably well for Victor
* 884 controllers also but if users experience issues such as asymmetric behavior around the
* deadband or inability to saturate the controller in either direction, calibration is recommended.
* The calibration procedure can be found in the Victor 884 User Manual available from VEX Robotics:
* http://content.vexrobotics.com/docs/ifi-v884-users-manual-9-25-06.pdf
*
* <p><ul>
* <li>2.027ms = full "forward"
* <li>1.525ms = the "high end" of the deadband range
* <li>1.507ms = center of the deadband range (off)
* <li>1.490ms = the "low end" of the deadband range
* <li>1.026ms = full "reverse"
* <ul>
* <li>2.027ms = full "forward"
* <li>1.525ms = the "high end" of the deadband range
* <li>1.507ms = center of the deadband range (off)
* <li>1.490ms = the "low end" of the deadband range
* <li>1.026ms = full "reverse"
* </ul>
*/
public class Victor extends PWMSpeedController {
/**
* Constructor.
*
* @param channel The PWM channel that the Victor is attached to. 0-9 are
* on-board, 10-19 are on the MXP port
* @param channel The PWM channel that the Victor is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
public Victor(final int channel) {
super(channel);

View File

@@ -12,25 +12,25 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
* VEX Robotics Victor SP Speed Controller.
*
* <p>Note that the VictorSP uses the following bounds for PWM values. These values should work
* reasonably well for most controllers, but if users experience issues such as asymmetric
* behavior around the deadband or inability to saturate the controller in either direction,
* calibration is recommended. The calibration procedure can be found in the VictorSP User Manual
* available from CTRE.
* reasonably well for most controllers, but if users experience issues such as asymmetric behavior
* around the deadband or inability to saturate the controller in either direction, calibration is
* recommended. The calibration procedure can be found in the VictorSP User Manual available from
* CTRE.
*
* <p><ul>
* <li>2.004ms = full "forward"
* <li>1.520ms = the "high end" of the deadband range
* <li>1.500ms = center of the deadband range (off)
* <li>1.480ms = the "low end" of the deadband range
* <li>0.997ms = full "reverse"
* <ul>
* <li>2.004ms = full "forward"
* <li>1.520ms = the "high end" of the deadband range
* <li>1.500ms = center of the deadband range (off)
* <li>1.480ms = the "low end" of the deadband range
* <li>0.997ms = full "reverse"
* </ul>
*/
public class VictorSP extends PWMSpeedController {
/**
* Constructor.
*
* @param channel The PWM channel that the VictorSP is attached to. 0-9 are
* on-board, 10-19 are on the MXP port
* @param channel The PWM channel that the VictorSP is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
public VictorSP(final int channel) {
super(channel);

View File

@@ -4,12 +4,11 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.NotifierJNI;
import java.io.Closeable;
import java.util.PriorityQueue;
import java.util.concurrent.locks.ReentrantLock;
import edu.wpi.first.hal.NotifierJNI;
/**
* A class that's a wrapper around a watchdog timer.
*
@@ -47,7 +46,7 @@ public class Watchdog implements Closeable, Comparable<Watchdog> {
/**
* Watchdog constructor.
*
* @param timeout The watchdog's timeout in seconds with microsecond resolution.
* @param timeout The watchdog's timeout in seconds with microsecond resolution.
* @param callback This function is called when the timeout expires.
*/
public Watchdog(double timeout, Runnable callback) {
@@ -82,9 +81,7 @@ public class Watchdog implements Closeable, Comparable<Watchdog> {
return Double.hashCode(m_expirationTime);
}
/**
* Returns the time in seconds since the watchdog was last fed.
*/
/** Returns the time in seconds since the watchdog was last fed. */
public double getTime() {
return Timer.getFPGATimestamp() - m_startTime;
}
@@ -92,8 +89,7 @@ public class Watchdog implements Closeable, Comparable<Watchdog> {
/**
* Sets the watchdog's timeout.
*
* @param timeout The watchdog's timeout in seconds with microsecond
* resolution.
* @param timeout The watchdog's timeout in seconds with microsecond resolution.
*/
public void setTimeout(double timeout) {
m_startTime = Timer.getFPGATimestamp();
@@ -113,9 +109,7 @@ public class Watchdog implements Closeable, Comparable<Watchdog> {
}
}
/**
* Returns the watchdog's timeout in seconds.
*/
/** Returns the watchdog's timeout in seconds. */
public double getTimeout() {
m_queueMutex.lock();
try {
@@ -125,9 +119,7 @@ public class Watchdog implements Closeable, Comparable<Watchdog> {
}
}
/**
* Returns true if the watchdog timer has expired.
*/
/** Returns true if the watchdog timer has expired. */
public boolean isExpired() {
m_queueMutex.lock();
try {
@@ -141,7 +133,6 @@ public class Watchdog implements Closeable, Comparable<Watchdog> {
* Adds time since last epoch to the list printed by printEpochs().
*
* @see Tracer#addEpoch(String)
*
* @param epochName The name to associate with the epoch.
*/
public void addEpoch(String epochName) {
@@ -150,6 +141,7 @@ public class Watchdog implements Closeable, Comparable<Watchdog> {
/**
* Prints list of epochs added so far and their times.
*
* @see Tracer#printEpochs()
*/
public void printEpochs() {
@@ -165,9 +157,7 @@ public class Watchdog implements Closeable, Comparable<Watchdog> {
enable();
}
/**
* Enables the watchdog timer.
*/
/** Enables the watchdog timer. */
public void enable() {
m_startTime = Timer.getFPGATimestamp();
m_tracer.clearEpochs();
@@ -185,9 +175,7 @@ public class Watchdog implements Closeable, Comparable<Watchdog> {
}
}
/**
* Disables the watchdog timer.
*/
/** Disables the watchdog timer. */
public void disable() {
m_queueMutex.lock();
try {
@@ -213,8 +201,8 @@ public class Watchdog implements Closeable, Comparable<Watchdog> {
if (m_watchdogs.size() == 0) {
NotifierJNI.cancelNotifierAlarm(m_notifier);
} else {
NotifierJNI.updateNotifierAlarm(m_notifier,
(long) (m_watchdogs.peek().m_expirationTime * 1e6));
NotifierJNI.updateNotifierAlarm(
m_notifier, (long) (m_watchdogs.peek().m_expirationTime * 1e6));
}
}
@@ -248,8 +236,7 @@ public class Watchdog implements Closeable, Comparable<Watchdog> {
watchdog.m_lastTimeoutPrintTime = now;
if (!watchdog.m_suppressTimeoutMessage) {
DriverStation.reportWarning(
String.format("Watchdog not fed within %.6fs\n", watchdog.m_timeout),
false);
String.format("Watchdog not fed within %.6fs\n", watchdog.m_timeout), false);
}
}

View File

@@ -15,9 +15,7 @@ import edu.wpi.first.hal.HAL;
* and the mapping of ports to hardware buttons depends on the code in the Driver Station.
*/
public class XboxController extends GenericHID {
/**
* Represents a digital button on an XboxController.
*/
/** Represents a digital button on an XboxController. */
public enum Button {
kBumperLeft(5),
kBumperRight(6),
@@ -38,9 +36,7 @@ public class XboxController extends GenericHID {
}
}
/**
* Represents an axis on an XboxController.
*/
/** Represents an axis on an XboxController. */
public enum Axis {
kLeftX(0),
kRightX(4),
@@ -58,8 +54,7 @@ public class XboxController extends GenericHID {
}
/**
* Construct an instance of a joystick. The joystick index is the USB port on the drivers
* station.
* Construct an instance of a joystick. The joystick index is the USB port on the drivers station.
*
* @param port The port on the Driver Station that the joystick is plugged into.
*/

View File

@@ -6,16 +6,15 @@ package edu.wpi.first.wpilibj.controller;
public final class ControllerUtil {
/**
* Returns modulus of error where error is the difference between the reference
* and a measurement.
* Returns modulus of error where error is the difference between the reference and a measurement.
*
* @param reference Reference input of a controller.
* @param measurement The current measurement.
* @param minimumInput The minimum value expected from the input.
* @param maximumInput The maximum value expected from the input.
*/
public static double getModulusError(double reference, double measurement, double minimumInput,
double maximumInput) {
public static double getModulusError(
double reference, double measurement, double minimumInput, double maximumInput) {
double error = reference - measurement;
double modulus = maximumInput - minimumInput;
@@ -30,6 +29,5 @@ public final class ControllerUtil {
return error;
}
private ControllerUtil() {
}
private ControllerUtil() {}
}

View File

@@ -10,15 +10,15 @@ import edu.wpi.first.wpilibj.kinematics.ChassisSpeeds;
import edu.wpi.first.wpilibj.trajectory.Trajectory;
/**
* This holonomic drive controller can be used to follow trajectories using a
* holonomic drive train (i.e. swerve or mecanum). Holonomic trajectory following
* is a much simpler problem to solve compared to skid-steer style drivetrains because
* it is possible to individually control forward, sideways, and angular velocity.
* This holonomic drive controller can be used to follow trajectories using a holonomic drive train
* (i.e. swerve or mecanum). Holonomic trajectory following is a much simpler problem to solve
* compared to skid-steer style drivetrains because it is possible to individually control forward,
* sideways, and angular velocity.
*
* <p>The holonomic drive controller takes in one PID controller for each direction, forward
* and sideways, and one profiled PID controller for the angular direction. Because the
* heading dynamics are decoupled from translations, users can specify a custom heading
* that the drivetrain should point toward. This heading reference is profiled for smoothness.
* <p>The holonomic drive controller takes in one PID controller for each direction, forward and
* sideways, and one profiled PID controller for the angular direction. Because the heading dynamics
* are decoupled from translations, users can specify a custom heading that the drivetrain should
* point toward. This heading reference is profiled for smoothness.
*/
@SuppressWarnings("MemberName")
public class HolonomicDriveController {
@@ -33,14 +33,13 @@ public class HolonomicDriveController {
/**
* Constructs a holonomic drive controller.
*
* @param xController A PID Controller to respond to error in the field-relative x direction.
* @param yController A PID Controller to respond to error in the field-relative y direction.
* @param xController A PID Controller to respond to error in the field-relative x direction.
* @param yController A PID Controller to respond to error in the field-relative y direction.
* @param thetaController A profiled PID controller to respond to error in angle.
*/
@SuppressWarnings("ParameterName")
public HolonomicDriveController(PIDController xController,
PIDController yController,
ProfiledPIDController thetaController) {
public HolonomicDriveController(
PIDController xController, PIDController yController, ProfiledPIDController thetaController) {
m_xController = xController;
m_yController = yController;
m_thetaController = thetaController;
@@ -73,22 +72,20 @@ public class HolonomicDriveController {
/**
* Returns the next output of the holonomic drive controller.
*
* @param currentPose The current pose.
* @param poseRef The desired pose.
* @param currentPose The current pose.
* @param poseRef The desired pose.
* @param linearVelocityRefMeters The linear velocity reference.
* @param angleRef The angular reference.
* @param angleRef The angular reference.
* @return The next output of the holonomic drive controller.
*/
@SuppressWarnings("LocalVariableName")
public ChassisSpeeds calculate(Pose2d currentPose,
Pose2d poseRef,
double linearVelocityRefMeters,
Rotation2d angleRef) {
public ChassisSpeeds calculate(
Pose2d currentPose, Pose2d poseRef, double linearVelocityRefMeters, Rotation2d angleRef) {
// Calculate feedforward velocities (field-relative).
double xFF = linearVelocityRefMeters * poseRef.getRotation().getCos();
double yFF = linearVelocityRefMeters * poseRef.getRotation().getSin();
double thetaFF = m_thetaController.calculate(currentPose.getRotation().getRadians(),
angleRef.getRadians());
double thetaFF =
m_thetaController.calculate(currentPose.getRotation().getRadians(), angleRef.getRadians());
m_poseError = poseRef.relativeTo(currentPose);
@@ -101,27 +98,27 @@ public class HolonomicDriveController {
double yFeedback = m_yController.calculate(currentPose.getY(), poseRef.getY());
// Return next output.
return ChassisSpeeds.fromFieldRelativeSpeeds(xFF + xFeedback,
yFF + yFeedback, thetaFF, currentPose.getRotation());
return ChassisSpeeds.fromFieldRelativeSpeeds(
xFF + xFeedback, yFF + yFeedback, thetaFF, currentPose.getRotation());
}
/**
* Returns the next output of the holonomic drive controller.
*
* @param currentPose The current pose.
* @param currentPose The current pose.
* @param desiredState The desired trajectory state.
* @param angleRef The desired end-angle.
* @param angleRef The desired end-angle.
* @return The next output of the holonomic drive controller.
*/
public ChassisSpeeds calculate(Pose2d currentPose, Trajectory.State desiredState,
Rotation2d angleRef) {
return calculate(currentPose, desiredState.poseMeters, desiredState.velocityMetersPerSecond,
angleRef);
public ChassisSpeeds calculate(
Pose2d currentPose, Trajectory.State desiredState, Rotation2d angleRef) {
return calculate(
currentPose, desiredState.poseMeters, desiredState.velocityMetersPerSecond, angleRef);
}
/**
* Enables and disables the controller for troubleshooting problems. When calculate()
* is called on a disabled controller, only feedforward values are returned.
* Enables and disables the controller for troubleshooting problems. When calculate() is called on
* a disabled controller, only feedforward values are returned.
*
* @param enabled If the controller is enabled or not.
*/

View File

@@ -11,9 +11,7 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import edu.wpi.first.wpiutil.math.MathUtil;
/**
* Implements a PID control loop.
*/
/** Implements a PID control loop. */
@SuppressWarnings("PMD.TooManyFields")
public class PIDController implements Sendable, AutoCloseable {
private static int instances;
@@ -73,9 +71,9 @@ public class PIDController implements Sendable, AutoCloseable {
/**
* Allocates a PIDController with the given constants for kp, ki, and kd.
*
* @param kp The proportional coefficient.
* @param ki The integral coefficient.
* @param kd The derivative coefficient.
* @param kp The proportional coefficient.
* @param ki The integral coefficient.
* @param kd The derivative coefficient.
* @param period The period between controller updates in seconds.
*/
public PIDController(double kp, double ki, double kd, double period) {
@@ -202,8 +200,8 @@ public class PIDController implements Sendable, AutoCloseable {
public boolean atSetpoint() {
double positionError;
if (m_continuous) {
positionError = ControllerUtil.getModulusError(m_setpoint, m_measurement, m_minimumInput,
m_maximumInput);
positionError =
ControllerUtil.getModulusError(m_setpoint, m_measurement, m_minimumInput, m_maximumInput);
} else {
positionError = m_setpoint - m_measurement;
}
@@ -217,9 +215,8 @@ public class PIDController implements Sendable, AutoCloseable {
/**
* Enables continuous input.
*
* <p>Rather then using the max and min input range as constraints, it considers
* them to be the same point and automatically calculates the shortest route
* to the setpoint.
* <p>Rather then using the max and min input range as constraints, it considers them to be the
* same point and automatically calculates the shortest route to the setpoint.
*
* @param minimumInput The minimum value expected from the input.
* @param maximumInput The maximum value expected from the input.
@@ -230,16 +227,12 @@ public class PIDController implements Sendable, AutoCloseable {
m_maximumInput = maximumInput;
}
/**
* Disables continuous input.
*/
/** Disables continuous input. */
public void disableContinuousInput() {
m_continuous = false;
}
/**
* Returns true if continuous input is enabled.
*/
/** Returns true if continuous input is enabled. */
public boolean isContinuousInputEnabled() {
return m_continuous;
}
@@ -247,8 +240,8 @@ public class PIDController implements Sendable, AutoCloseable {
/**
* Sets the minimum and maximum values for the integrator.
*
* <p>When the cap is reached, the integrator value is added to the controller
* output rather than the integrator value times the integral gain.
* <p>When the cap is reached, the integrator value is added to the controller output rather than
* the integrator value times the integral gain.
*
* @param minimumIntegral The minimum value of the integrator.
* @param maximumIntegral The maximum value of the integrator.
@@ -287,9 +280,7 @@ public class PIDController implements Sendable, AutoCloseable {
return m_positionError;
}
/**
* Returns the velocity error.
*/
/** Returns the velocity error. */
public double getVelocityError() {
return m_velocityError;
}
@@ -298,7 +289,7 @@ public class PIDController implements Sendable, AutoCloseable {
* Returns the next output of the PID controller.
*
* @param measurement The current measurement of the process variable.
* @param setpoint The new setpoint of the controller.
* @param setpoint The new setpoint of the controller.
*/
public double calculate(double measurement, double setpoint) {
// Set setpoint to provided value
@@ -316,8 +307,8 @@ public class PIDController implements Sendable, AutoCloseable {
m_prevError = m_positionError;
if (m_continuous) {
m_positionError = ControllerUtil.getModulusError(m_setpoint, measurement, m_minimumInput,
m_maximumInput);
m_positionError =
ControllerUtil.getModulusError(m_setpoint, measurement, m_minimumInput, m_maximumInput);
} else {
m_positionError = m_setpoint - measurement;
}
@@ -325,16 +316,17 @@ public class PIDController implements Sendable, AutoCloseable {
m_velocityError = (m_positionError - m_prevError) / m_period;
if (m_ki != 0) {
m_totalError = MathUtil.clamp(m_totalError + m_positionError * m_period,
m_minimumIntegral / m_ki, m_maximumIntegral / m_ki);
m_totalError =
MathUtil.clamp(
m_totalError + m_positionError * m_period,
m_minimumIntegral / m_ki,
m_maximumIntegral / m_ki);
}
return m_kp * m_positionError + m_ki * m_totalError + m_kd * m_velocityError;
}
/**
* Resets the previous error and the integral term.
*/
/** Resets the previous error and the integral term. */
public void reset() {
m_prevError = 0;
m_totalError = 0;

View File

@@ -11,9 +11,8 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.trajectory.TrapezoidProfile;
/**
* Implements a PID control loop whose setpoint is constrained by a trapezoid
* profile. Users should call reset() when they first start running the controller
* to avoid unwanted behavior.
* Implements a PID control loop whose setpoint is constrained by a trapezoid profile. Users should
* call reset() when they first start running the controller to avoid unwanted behavior.
*/
public class ProfiledPIDController implements Sendable {
private static int instances;
@@ -26,35 +25,31 @@ public class ProfiledPIDController implements Sendable {
private TrapezoidProfile.Constraints m_constraints;
/**
* Allocates a ProfiledPIDController with the given constants for Kp, Ki, and
* Kd.
* Allocates a ProfiledPIDController with the given constants for Kp, Ki, and Kd.
*
* @param Kp The proportional coefficient.
* @param Ki The integral coefficient.
* @param Kd The derivative coefficient.
* @param Kp The proportional coefficient.
* @param Ki The integral coefficient.
* @param Kd The derivative coefficient.
* @param constraints Velocity and acceleration constraints for goal.
*/
@SuppressWarnings("ParameterName")
public ProfiledPIDController(double Kp, double Ki, double Kd,
TrapezoidProfile.Constraints constraints) {
public ProfiledPIDController(
double Kp, double Ki, double Kd, TrapezoidProfile.Constraints constraints) {
this(Kp, Ki, Kd, constraints, 0.02);
}
/**
* Allocates a ProfiledPIDController with the given constants for Kp, Ki, and
* Kd.
* Allocates a ProfiledPIDController with the given constants for Kp, Ki, and Kd.
*
* @param Kp The proportional coefficient.
* @param Ki The integral coefficient.
* @param Kd The derivative coefficient.
* @param Kp The proportional coefficient.
* @param Ki The integral coefficient.
* @param Kd The derivative coefficient.
* @param constraints Velocity and acceleration constraints for goal.
* @param period The period between controller updates in seconds. The
* default is 0.02 seconds.
* @param period The period between controller updates in seconds. The default is 0.02 seconds.
*/
@SuppressWarnings("ParameterName")
public ProfiledPIDController(double Kp, double Ki, double Kd,
TrapezoidProfile.Constraints constraints,
double period) {
public ProfiledPIDController(
double Kp, double Ki, double Kd, TrapezoidProfile.Constraints constraints, double period) {
m_controller = new PIDController(Kp, Ki, Kd, period);
m_constraints = constraints;
instances++;
@@ -159,9 +154,7 @@ public class ProfiledPIDController implements Sendable {
m_goal = new TrapezoidProfile.State(goal, 0);
}
/**
* Gets the goal for the ProfiledPIDController.
*/
/** Gets the goal for the ProfiledPIDController. */
public TrapezoidProfile.State getGoal() {
return m_goal;
}
@@ -205,9 +198,8 @@ public class ProfiledPIDController implements Sendable {
/**
* Enables continuous input.
*
* <p>Rather then using the max and min input range as constraints, it considers
* them to be the same point and automatically calculates the shortest route
* to the setpoint.
* <p>Rather then using the max and min input range as constraints, it considers them to be the
* same point and automatically calculates the shortest route to the setpoint.
*
* @param minimumInput The minimum value expected from the input.
* @param maximumInput The maximum value expected from the input.
@@ -218,9 +210,7 @@ public class ProfiledPIDController implements Sendable {
m_maximumInput = maximumInput;
}
/**
* Disables continuous input.
*/
/** Disables continuous input. */
public void disableContinuousInput() {
m_controller.disableContinuousInput();
}
@@ -228,8 +218,8 @@ public class ProfiledPIDController implements Sendable {
/**
* Sets the minimum and maximum values for the integrator.
*
* <p>When the cap is reached, the integrator value is added to the controller
* output rather than the integrator value times the integral gain.
* <p>When the cap is reached, the integrator value is added to the controller output rather than
* the integrator value times the integral gain.
*
* @param minimumIntegral The minimum value of the integrator.
* @param maximumIntegral The maximum value of the integrator.
@@ -266,9 +256,7 @@ public class ProfiledPIDController implements Sendable {
return m_controller.getPositionError();
}
/**
* Returns the change in error per second.
*/
/** Returns the change in error per second. */
public double getVelocityError() {
return m_controller.getVelocityError();
}
@@ -281,10 +269,12 @@ public class ProfiledPIDController implements Sendable {
public double calculate(double measurement) {
if (m_controller.isContinuousInputEnabled()) {
// Get error which is smallest distance between goal and measurement
double goalMinDistance = ControllerUtil.getModulusError(m_goal.position, measurement,
m_minimumInput, m_maximumInput);
double setpointMinDistance = ControllerUtil.getModulusError(m_setpoint.position, measurement,
m_minimumInput, m_maximumInput);
double goalMinDistance =
ControllerUtil.getModulusError(
m_goal.position, measurement, m_minimumInput, m_maximumInput);
double setpointMinDistance =
ControllerUtil.getModulusError(
m_setpoint.position, measurement, m_minimumInput, m_maximumInput);
// Recompute the profile goal with the smallest error, thus giving the shortest path. The goal
// may be outside the input range after this operation, but that's OK because the controller
@@ -325,11 +315,11 @@ public class ProfiledPIDController implements Sendable {
* Returns the next output of the PID controller.
*
* @param measurement The current measurement of the process variable.
* @param goal The new goal of the controller.
* @param goal The new goal of the controller.
* @param constraints Velocity and acceleration constraints for goal.
*/
public double calculate(double measurement, TrapezoidProfile.State goal,
TrapezoidProfile.Constraints constraints) {
public double calculate(
double measurement, TrapezoidProfile.State goal, TrapezoidProfile.Constraints constraints) {
setConstraints(constraints);
return calculate(measurement, goal);
}
@@ -357,8 +347,8 @@ public class ProfiledPIDController implements Sendable {
/**
* Reset the previous error and the integral term.
*
* @param measuredPosition The current measured position of the system. The velocity is
* assumed to be zero.
* @param measuredPosition The current measured position of the system. The velocity is assumed to
* be zero.
*/
public void reset(double measuredPosition) {
reset(measuredPosition, 0.0);

View File

@@ -9,37 +9,33 @@ import edu.wpi.first.wpilibj.kinematics.ChassisSpeeds;
import edu.wpi.first.wpilibj.trajectory.Trajectory;
/**
* Ramsete is a nonlinear time-varying feedback controller for unicycle models
* that drives the model to a desired pose along a two-dimensional trajectory.
* Why would we need a nonlinear control law in addition to the linear ones we
* have used so far like PID? If we use the original approach with PID
* controllers for left and right position and velocity states, the controllers
* only deal with the local pose. If the robot deviates from the path, there is
* no way for the controllers to correct and the robot may not reach the desired
* global pose. This is due to multiple endpoints existing for the robot which
* have the same encoder path arc lengths.
* Ramsete is a nonlinear time-varying feedback controller for unicycle models that drives the model
* to a desired pose along a two-dimensional trajectory. Why would we need a nonlinear control law
* in addition to the linear ones we have used so far like PID? If we use the original approach with
* PID controllers for left and right position and velocity states, the controllers only deal with
* the local pose. If the robot deviates from the path, there is no way for the controllers to
* correct and the robot may not reach the desired global pose. This is due to multiple endpoints
* existing for the robot which have the same encoder path arc lengths.
*
* <p>Instead of using wheel path arc lengths (which are in the robot's local
* coordinate frame), nonlinear controllers like pure pursuit and Ramsete use
* global pose. The controller uses this extra information to guide a linear
* reference tracker like the PID controllers back in by adjusting the
* references of the PID controllers.
* <p>Instead of using wheel path arc lengths (which are in the robot's local coordinate frame),
* nonlinear controllers like pure pursuit and Ramsete use global pose. The controller uses this
* extra information to guide a linear reference tracker like the PID controllers back in by
* adjusting the references of the PID controllers.
*
* <p>The paper "Control of Wheeled Mobile Robots: An Experimental Overview"
* describes a nonlinear controller for a wheeled vehicle with unicycle-like
* kinematics; a global pose consisting of x, y, and theta; and a desired pose
* consisting of x_d, y_d, and theta_d. We call it Ramsete because that's the
* acronym for the title of the book it came from in Italian ("Robotica
* Articolata e Mobile per i SErvizi e le TEcnologie").
* <p>The paper "Control of Wheeled Mobile Robots: An Experimental Overview" describes a nonlinear
* controller for a wheeled vehicle with unicycle-like kinematics; a global pose consisting of x, y,
* and theta; and a desired pose consisting of x_d, y_d, and theta_d. We call it Ramsete because
* that's the acronym for the title of the book it came from in Italian ("Robotica Articolata e
* Mobile per i SErvizi e le TEcnologie").
*
* <p>See
* <a href="https://file.tavsys.net/control/controls-engineering-in-frc.pdf">
* Controls Engineering in the FIRST Robotics Competition</a> section on Ramsete
* unicycle controller for a derivation and analysis.
* <p>See <a href="https://file.tavsys.net/control/controls-engineering-in-frc.pdf">Controls
* Engineering in the FIRST Robotics Competition</a> section on Ramsete unicycle controller for a
* derivation and analysis.
*/
public class RamseteController {
@SuppressWarnings("MemberName")
private final double m_b;
@SuppressWarnings("MemberName")
private final double m_zeta;
@@ -50,10 +46,10 @@ public class RamseteController {
/**
* Construct a Ramsete unicycle controller.
*
* @param b Tuning parameter (b &gt; 0) for which larger values make convergence more
* aggressive like a proportional term.
* @param b Tuning parameter (b &gt; 0) for which larger values make convergence more aggressive
* like a proportional term.
* @param zeta Tuning parameter (0 &lt; zeta &lt; 1) for which larger values provide more damping
* in response.
* in response.
*/
@SuppressWarnings("ParameterName")
public RamseteController(double b, double zeta) {
@@ -62,30 +58,26 @@ public class RamseteController {
}
/**
* Construct a Ramsete unicycle controller. The default arguments for
* b and zeta of 2.0 and 0.7 have been well-tested to produce desirable
* results.
* Construct a Ramsete unicycle controller. The default arguments for b and zeta of 2.0 and 0.7
* have been well-tested to produce desirable results.
*/
public RamseteController() {
this(2.0, 0.7);
}
/**
* Returns true if the pose error is within tolerance of the reference.
*/
/** Returns true if the pose error is within tolerance of the reference. */
public boolean atReference() {
final var eTranslate = m_poseError.getTranslation();
final var eRotate = m_poseError.getRotation();
final var tolTranslate = m_poseTolerance.getTranslation();
final var tolRotate = m_poseTolerance.getRotation();
return Math.abs(eTranslate.getX()) < tolTranslate.getX()
&& Math.abs(eTranslate.getY()) < tolTranslate.getY()
&& Math.abs(eRotate.getRadians()) < tolRotate.getRadians();
&& Math.abs(eTranslate.getY()) < tolTranslate.getY()
&& Math.abs(eRotate.getRadians()) < tolRotate.getRadians();
}
/**
* Sets the pose error which is considered tolerable for use with
* atReference().
* Sets the pose error which is considered tolerable for use with atReference().
*
* @param poseTolerance Pose error which is tolerable.
*/
@@ -96,19 +88,20 @@ public class RamseteController {
/**
* Returns the next output of the Ramsete controller.
*
* <p>The reference pose, linear velocity, and angular velocity should come
* from a drivetrain trajectory.
* <p>The reference pose, linear velocity, and angular velocity should come from a drivetrain
* trajectory.
*
* @param currentPose The current pose.
* @param poseRef The desired pose.
* @param linearVelocityRefMeters The desired linear velocity in meters per second.
* @param currentPose The current pose.
* @param poseRef The desired pose.
* @param linearVelocityRefMeters The desired linear velocity in meters per second.
* @param angularVelocityRefRadiansPerSecond The desired angular velocity in radians per second.
*/
@SuppressWarnings("LocalVariableName")
public ChassisSpeeds calculate(Pose2d currentPose,
Pose2d poseRef,
double linearVelocityRefMeters,
double angularVelocityRefRadiansPerSecond) {
public ChassisSpeeds calculate(
Pose2d currentPose,
Pose2d poseRef,
double linearVelocityRefMeters,
double angularVelocityRefRadiansPerSecond) {
if (!m_enabled) {
return new ChassisSpeeds(linearVelocityRefMeters, 0.0, angularVelocityRefRadiansPerSecond);
}
@@ -124,24 +117,27 @@ public class RamseteController {
double k = 2.0 * m_zeta * Math.sqrt(Math.pow(omegaRef, 2) + m_b * Math.pow(vRef, 2));
return new ChassisSpeeds(vRef * m_poseError.getRotation().getCos() + k * eX,
0.0,
omegaRef + k * eTheta + m_b * vRef * sinc(eTheta) * eY);
return new ChassisSpeeds(
vRef * m_poseError.getRotation().getCos() + k * eX,
0.0,
omegaRef + k * eTheta + m_b * vRef * sinc(eTheta) * eY);
}
/**
* Returns the next output of the Ramsete controller.
*
* <p>The reference pose, linear velocity, and angular velocity should come
* from a drivetrain trajectory.
* <p>The reference pose, linear velocity, and angular velocity should come from a drivetrain
* trajectory.
*
* @param currentPose The current pose.
* @param desiredState The desired pose, linear velocity, and angular velocity
* from a trajectory.
* @param currentPose The current pose.
* @param desiredState The desired pose, linear velocity, and angular velocity from a trajectory.
*/
@SuppressWarnings("LocalVariableName")
public ChassisSpeeds calculate(Pose2d currentPose, Trajectory.State desiredState) {
return calculate(currentPose, desiredState.poseMeters, desiredState.velocityMetersPerSecond,
return calculate(
currentPose,
desiredState.poseMeters,
desiredState.velocityMetersPerSecond,
desiredState.velocityMetersPerSecond * desiredState.curvatureRadPerMeter);
}

View File

@@ -4,8 +4,6 @@
package edu.wpi.first.wpilibj.drive;
import java.util.StringJoiner;
import edu.wpi.first.hal.FRCNetComm.tInstances;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
@@ -15,17 +13,19 @@ import edu.wpi.first.wpilibj.SpeedControllerGroup;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import edu.wpi.first.wpiutil.math.MathUtil;
import java.util.StringJoiner;
/**
* A class for driving differential drive/skid-steer drive platforms such as the Kit of Parts drive
* base, "tank drive", or West Coast Drive.
*
* <p>These drive bases typically have drop-center / skid-steer with two or more wheels per side
* (e.g., 6WD or 8WD). This class takes a SpeedController per side. For four and
* six motor drivetrains, construct and pass in {@link edu.wpi.first.wpilibj.SpeedControllerGroup}
* instances as follows.
* (e.g., 6WD or 8WD). This class takes a SpeedController per side. For four and six motor
* drivetrains, construct and pass in {@link edu.wpi.first.wpilibj.SpeedControllerGroup} instances
* as follows.
*
* <p>Four motor drivetrain:
*
* <pre><code>
* public class Robot {
* SpeedController m_frontLeft = new PWMVictorSPX(1);
@@ -41,6 +41,7 @@ import edu.wpi.first.wpiutil.math.MathUtil;
* </code></pre>
*
* <p>Six motor drivetrain:
*
* <pre><code>
* public class Robot {
* SpeedController m_frontLeft = new PWMVictorSPX(1);
@@ -60,6 +61,7 @@ import edu.wpi.first.wpiutil.math.MathUtil;
* <p>A differential drive robot has left and right wheels separated by an arbitrary width.
*
* <p>Drive base diagram:
*
* <pre>
* |_______|
* | | | |
@@ -80,18 +82,18 @@ import edu.wpi.first.wpiutil.math.MathUtil;
* positive.
*
* <p>Inputs smaller then {@value edu.wpi.first.wpilibj.drive.RobotDriveBase#kDefaultDeadband} will
* be set to 0, and larger values will be scaled so that the full range is still used. This
* deadband value can be changed with {@link #setDeadband}.
* be set to 0, and larger values will be scaled so that the full range is still used. This deadband
* value can be changed with {@link #setDeadband}.
*
* <p>RobotDrive porting guide:
* <br>{@link #tankDrive(double, double)} is equivalent to
* {@link edu.wpi.first.wpilibj.RobotDrive#tankDrive(double, double)} if a deadband of 0 is used.
* <br>{@link #arcadeDrive(double, double)} is equivalent to
* {@link edu.wpi.first.wpilibj.RobotDrive#arcadeDrive(double, double)} if a deadband of 0 is used
* and the the rotation input is inverted eg arcadeDrive(y, -rotation)
* <br>{@link #curvatureDrive(double, double, boolean)} is similar in concept to
* {@link edu.wpi.first.wpilibj.RobotDrive#drive(double, double)} with the addition of a quick turn
* mode. However, it is not designed to give exactly the same response.
* <p>RobotDrive porting guide: <br>
* {@link #tankDrive(double, double)} is equivalent to {@link
* edu.wpi.first.wpilibj.RobotDrive#tankDrive(double, double)} if a deadband of 0 is used. <br>
* {@link #arcadeDrive(double, double)} is equivalent to {@link
* edu.wpi.first.wpilibj.RobotDrive#arcadeDrive(double, double)} if a deadband of 0 is used and the
* the rotation input is inverted eg arcadeDrive(y, -rotation) <br>
* {@link #curvatureDrive(double, double, boolean)} is similar in concept to {@link
* edu.wpi.first.wpilibj.RobotDrive#drive(double, double)} with the addition of a quick turn mode.
* However, it is not designed to give exactly the same response.
*/
public class DifferentialDrive extends RobotDriveBase implements Sendable, AutoCloseable {
public static final double kDefaultQuickStopThreshold = 0.2;
@@ -130,10 +132,10 @@ public class DifferentialDrive extends RobotDriveBase implements Sendable, AutoC
}
/**
* Verifies that all motors are nonnull, throwing a NullPointerException if any of them are.
* The exception's error message will specify all null motors, e.g. {@code
* NullPointerException("leftMotor, rightMotor")}, to give as much information as possible to
* the programmer.
* Verifies that all motors are nonnull, throwing a NullPointerException if any of them are. The
* exception's error message will specify all null motors, e.g. {@code
* NullPointerException("leftMotor, rightMotor")}, to give as much information as possible to the
* programmer.
*
* @throws NullPointerException if any of the given motors are null
*/
@@ -153,12 +155,12 @@ public class DifferentialDrive extends RobotDriveBase implements Sendable, AutoC
}
/**
* Arcade drive method for differential drive platform.
* The calculated values will be squared to decrease sensitivity at low speeds.
* Arcade drive method for differential drive platform. The calculated values will be squared to
* decrease sensitivity at low speeds.
*
* @param xSpeed The robot's speed along the X axis [-1.0..1.0]. Forward is positive.
* @param xSpeed The robot's speed along the X axis [-1.0..1.0]. Forward is positive.
* @param zRotation The robot's rotation rate around the Z axis [-1.0..1.0]. Clockwise is
* positive.
* positive.
*/
@SuppressWarnings("ParameterName")
public void arcadeDrive(double xSpeed, double zRotation) {
@@ -168,16 +170,16 @@ public class DifferentialDrive extends RobotDriveBase implements Sendable, AutoC
/**
* Arcade drive method for differential drive platform.
*
* @param xSpeed The robot's speed along the X axis [-1.0..1.0]. Forward is positive.
* @param zRotation The robot's rotation rate around the Z axis [-1.0..1.0]. Clockwise is
* positive.
* @param xSpeed The robot's speed along the X axis [-1.0..1.0]. Forward is positive.
* @param zRotation The robot's rotation rate around the Z axis [-1.0..1.0]. Clockwise is
* positive.
* @param squareInputs If set, decreases the input sensitivity at low speeds.
*/
@SuppressWarnings("ParameterName")
public void arcadeDrive(double xSpeed, double zRotation, boolean squareInputs) {
if (!m_reported) {
HAL.report(tResourceType.kResourceType_RobotDrive,
tInstances.kRobotDrive2_DifferentialArcade, 2);
HAL.report(
tResourceType.kResourceType_RobotDrive, tInstances.kRobotDrive2_DifferentialArcade, 2);
m_reported = true;
}
@@ -230,21 +232,20 @@ public class DifferentialDrive extends RobotDriveBase implements Sendable, AutoC
* Curvature drive method for differential drive platform.
*
* <p>The rotation argument controls the curvature of the robot's path rather than its rate of
* heading change. This makes the robot more controllable at high speeds. Also handles the
* robot's quick turn functionality - "quick turn" overrides constant-curvature turning for
* turn-in-place maneuvers.
* heading change. This makes the robot more controllable at high speeds. Also handles the robot's
* quick turn functionality - "quick turn" overrides constant-curvature turning for turn-in-place
* maneuvers.
*
* @param xSpeed The robot's speed along the X axis [-1.0..1.0]. Forward is positive.
* @param zRotation The robot's rotation rate around the Z axis [-1.0..1.0]. Clockwise is
* positive.
* @param isQuickTurn If set, overrides constant-curvature turning for
* turn-in-place maneuvers.
* @param xSpeed The robot's speed along the X axis [-1.0..1.0]. Forward is positive.
* @param zRotation The robot's rotation rate around the Z axis [-1.0..1.0]. Clockwise is
* positive.
* @param isQuickTurn If set, overrides constant-curvature turning for turn-in-place maneuvers.
*/
@SuppressWarnings({"ParameterName", "PMD.CyclomaticComplexity"})
public void curvatureDrive(double xSpeed, double zRotation, boolean isQuickTurn) {
if (!m_reported) {
HAL.report(tResourceType.kResourceType_RobotDrive,
tInstances.kRobotDrive2_DifferentialCurvature, 2);
HAL.report(
tResourceType.kResourceType_RobotDrive, tInstances.kRobotDrive2_DifferentialCurvature, 2);
m_reported = true;
}
@@ -259,8 +260,9 @@ public class DifferentialDrive extends RobotDriveBase implements Sendable, AutoC
if (isQuickTurn) {
if (Math.abs(xSpeed) < m_quickStopThreshold) {
m_quickStopAccumulator = (1 - m_quickStopAlpha) * m_quickStopAccumulator
+ m_quickStopAlpha * MathUtil.clamp(zRotation, -1.0, 1.0) * 2;
m_quickStopAccumulator =
(1 - m_quickStopAlpha) * m_quickStopAccumulator
+ m_quickStopAlpha * MathUtil.clamp(zRotation, -1.0, 1.0) * 2;
}
overPower = true;
angularPower = zRotation;
@@ -311,13 +313,12 @@ public class DifferentialDrive extends RobotDriveBase implements Sendable, AutoC
}
/**
* Tank drive method for differential drive platform.
* The calculated values will be squared to decrease sensitivity at low speeds.
* Tank drive method for differential drive platform. The calculated values will be squared to
* decrease sensitivity at low speeds.
*
* @param leftSpeed The robot's left side speed along the X axis [-1.0..1.0]. Forward is
* positive.
* @param leftSpeed The robot's left side speed along the X axis [-1.0..1.0]. Forward is positive.
* @param rightSpeed The robot's right side speed along the X axis [-1.0..1.0]. Forward is
* positive.
* positive.
*/
public void tankDrive(double leftSpeed, double rightSpeed) {
tankDrive(leftSpeed, rightSpeed, true);
@@ -326,16 +327,15 @@ public class DifferentialDrive extends RobotDriveBase implements Sendable, AutoC
/**
* Tank drive method for differential drive platform.
*
* @param leftSpeed The robot left side's speed along the X axis [-1.0..1.0]. Forward is
* positive.
* @param rightSpeed The robot right side's speed along the X axis [-1.0..1.0]. Forward is
* positive.
* @param leftSpeed The robot left side's speed along the X axis [-1.0..1.0]. Forward is positive.
* @param rightSpeed The robot right side's speed along the X axis [-1.0..1.0]. Forward is
* positive.
* @param squareInputs If set, decreases the input sensitivity at low speeds.
*/
public void tankDrive(double leftSpeed, double rightSpeed, boolean squareInputs) {
if (!m_reported) {
HAL.report(tResourceType.kResourceType_RobotDrive,
tInstances.kRobotDrive2_DifferentialTank, 2);
HAL.report(
tResourceType.kResourceType_RobotDrive, tInstances.kRobotDrive2_DifferentialTank, 2);
m_reported = true;
}
@@ -369,7 +369,7 @@ public class DifferentialDrive extends RobotDriveBase implements Sendable, AutoC
* angular power request to slow the robot's rotation.
*
* @param threshold X speed below which quick stop accumulator will receive rotation rate values
* [0..1.0].
* [0..1.0].
*/
public void setQuickStopThreshold(double threshold) {
m_quickStopThreshold = threshold;
@@ -382,8 +382,8 @@ public class DifferentialDrive extends RobotDriveBase implements Sendable, AutoC
* changes.
*
* @param alpha Low-pass filter gain [0.0..2.0]. Smaller values result in slower output changes.
* Values between 1.0 and 2.0 result in output oscillation. Values below 0.0 and
* above 2.0 are unstable.
* Values between 1.0 and 2.0 result in output oscillation. Values below 0.0 and above 2.0 are
* unstable.
*/
public void setQuickStopAlpha(double alpha) {
m_quickStopAlpha = alpha;

View File

@@ -4,8 +4,6 @@
package edu.wpi.first.wpilibj.drive;
import java.util.StringJoiner;
import edu.wpi.first.hal.FRCNetComm.tInstances;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
@@ -14,6 +12,7 @@ import edu.wpi.first.wpilibj.SpeedController;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import edu.wpi.first.wpiutil.math.MathUtil;
import java.util.StringJoiner;
/**
* A class for driving Killough drive platforms.
@@ -21,6 +20,7 @@ import edu.wpi.first.wpiutil.math.MathUtil;
* <p>Killough drives are triangular with one omni wheel on each corner.
*
* <p>Drive base diagram:
*
* <pre>
* /_____\
* / \ / \
@@ -64,13 +64,18 @@ public class KilloughDrive extends RobotDriveBase implements Sendable, AutoClose
*
* <p>If a motor needs to be inverted, do so before passing it in.
*
* @param leftMotor The motor on the left corner.
* @param leftMotor The motor on the left corner.
* @param rightMotor The motor on the right corner.
* @param backMotor The motor on the back corner.
* @param backMotor The motor on the back corner.
*/
public KilloughDrive(SpeedController leftMotor, SpeedController rightMotor,
SpeedController backMotor) {
this(leftMotor, rightMotor, backMotor, kDefaultLeftMotorAngle, kDefaultRightMotorAngle,
public KilloughDrive(
SpeedController leftMotor, SpeedController rightMotor, SpeedController backMotor) {
this(
leftMotor,
rightMotor,
backMotor,
kDefaultLeftMotorAngle,
kDefaultRightMotorAngle,
kDefaultBackMotorAngle);
}
@@ -79,26 +84,36 @@ public class KilloughDrive extends RobotDriveBase implements Sendable, AutoClose
*
* <p>Angles are measured in degrees clockwise from the positive X axis.
*
* @param leftMotor The motor on the left corner.
* @param rightMotor The motor on the right corner.
* @param backMotor The motor on the back corner.
* @param leftMotorAngle The angle of the left wheel's forward direction of travel.
* @param leftMotor The motor on the left corner.
* @param rightMotor The motor on the right corner.
* @param backMotor The motor on the back corner.
* @param leftMotorAngle The angle of the left wheel's forward direction of travel.
* @param rightMotorAngle The angle of the right wheel's forward direction of travel.
* @param backMotorAngle The angle of the back wheel's forward direction of travel.
* @param backMotorAngle The angle of the back wheel's forward direction of travel.
*/
public KilloughDrive(SpeedController leftMotor, SpeedController rightMotor,
SpeedController backMotor, double leftMotorAngle, double rightMotorAngle,
double backMotorAngle) {
public KilloughDrive(
SpeedController leftMotor,
SpeedController rightMotor,
SpeedController backMotor,
double leftMotorAngle,
double rightMotorAngle,
double backMotorAngle) {
verify(leftMotor, rightMotor, backMotor);
m_leftMotor = leftMotor;
m_rightMotor = rightMotor;
m_backMotor = backMotor;
m_leftVec = new Vector2d(Math.cos(leftMotorAngle * (Math.PI / 180.0)),
Math.sin(leftMotorAngle * (Math.PI / 180.0)));
m_rightVec = new Vector2d(Math.cos(rightMotorAngle * (Math.PI / 180.0)),
Math.sin(rightMotorAngle * (Math.PI / 180.0)));
m_backVec = new Vector2d(Math.cos(backMotorAngle * (Math.PI / 180.0)),
Math.sin(backMotorAngle * (Math.PI / 180.0)));
m_leftVec =
new Vector2d(
Math.cos(leftMotorAngle * (Math.PI / 180.0)),
Math.sin(leftMotorAngle * (Math.PI / 180.0)));
m_rightVec =
new Vector2d(
Math.cos(rightMotorAngle * (Math.PI / 180.0)),
Math.sin(rightMotorAngle * (Math.PI / 180.0)));
m_backVec =
new Vector2d(
Math.cos(backMotorAngle * (Math.PI / 180.0)),
Math.sin(backMotorAngle * (Math.PI / 180.0)));
SendableRegistry.addChild(this, m_leftMotor);
SendableRegistry.addChild(this, m_rightMotor);
SendableRegistry.addChild(this, m_backMotor);
@@ -112,16 +127,16 @@ public class KilloughDrive extends RobotDriveBase implements Sendable, AutoClose
}
/**
* Verifies that all motors are nonnull, throwing a NullPointerException if any of them are.
* The exception's error message will specify all null motors, e.g. {@code
* NullPointerException("leftMotor, rightMotor")}, to give as much information as possible to
* the programmer.
* Verifies that all motors are nonnull, throwing a NullPointerException if any of them are. The
* exception's error message will specify all null motors, e.g. {@code
* NullPointerException("leftMotor, rightMotor")}, to give as much information as possible to the
* programmer.
*
* @throws NullPointerException if any of the given motors are null
*/
@SuppressWarnings("PMD.AvoidThrowingNullPointerException")
private void verify(SpeedController leftMotor, SpeedController rightMotor,
SpeedController backMotor) {
private void verify(
SpeedController leftMotor, SpeedController rightMotor, SpeedController backMotor) {
if (leftMotor != null && rightMotor != null && backMotor != null) {
return;
}
@@ -144,10 +159,10 @@ public class KilloughDrive extends RobotDriveBase implements Sendable, AutoClose
* <p>Angles are measured clockwise from the positive X axis. The robot's speed is independent
* from its angle or rotation rate.
*
* @param ySpeed The robot's speed along the Y axis [-1.0..1.0]. Right is positive.
* @param xSpeed The robot's speed along the X axis [-1.0..1.0]. Forward is positive.
* @param ySpeed The robot's speed along the Y axis [-1.0..1.0]. Right is positive.
* @param xSpeed The robot's speed along the X axis [-1.0..1.0]. Forward is positive.
* @param zRotation The robot's rotation rate around the Z axis [-1.0..1.0]. Clockwise is
* positive.
* positive.
*/
@SuppressWarnings("ParameterName")
public void driveCartesian(double ySpeed, double xSpeed, double zRotation) {
@@ -160,19 +175,18 @@ public class KilloughDrive extends RobotDriveBase implements Sendable, AutoClose
* <p>Angles are measured clockwise from the positive X axis. The robot's speed is independent
* from its angle or rotation rate.
*
* @param ySpeed The robot's speed along the Y axis [-1.0..1.0]. Right is positive.
* @param xSpeed The robot's speed along the X axis [-1.0..1.0]. Forward is positive.
* @param ySpeed The robot's speed along the Y axis [-1.0..1.0]. Right is positive.
* @param xSpeed The robot's speed along the X axis [-1.0..1.0]. Forward is positive.
* @param zRotation The robot's rotation rate around the Z axis [-1.0..1.0]. Clockwise is
* positive.
* @param gyroAngle The current angle reading from the gyro in degrees around the Z axis. Use
* this to implement field-oriented controls.
* positive.
* @param gyroAngle The current angle reading from the gyro in degrees around the Z axis. Use this
* to implement field-oriented controls.
*/
@SuppressWarnings("ParameterName")
public void driveCartesian(double ySpeed, double xSpeed, double zRotation,
double gyroAngle) {
public void driveCartesian(double ySpeed, double xSpeed, double zRotation, double gyroAngle) {
if (!m_reported) {
HAL.report(tResourceType.kResourceType_RobotDrive,
tInstances.kRobotDrive2_KilloughCartesian, 3);
HAL.report(
tResourceType.kResourceType_RobotDrive, tInstances.kRobotDrive2_KilloughCartesian, 3);
m_reported = true;
}
@@ -207,20 +221,22 @@ public class KilloughDrive extends RobotDriveBase implements Sendable, AutoClose
* drives (translation) is independent from its angle or rotation rate.
*
* @param magnitude The robot's speed at a given angle [-1.0..1.0]. Forward is positive.
* @param angle The angle around the Z axis at which the robot drives in degrees [-180..180].
* @param angle The angle around the Z axis at which the robot drives in degrees [-180..180].
* @param zRotation The robot's rotation rate around the Z axis [-1.0..1.0]. Clockwise is
* positive.
* positive.
*/
@SuppressWarnings("ParameterName")
public void drivePolar(double magnitude, double angle, double zRotation) {
if (!m_reported) {
HAL.report(tResourceType.kResourceType_RobotDrive,
tInstances.kRobotDrive2_KilloughPolar, 3);
HAL.report(tResourceType.kResourceType_RobotDrive, tInstances.kRobotDrive2_KilloughPolar, 3);
m_reported = true;
}
driveCartesian(magnitude * Math.sin(angle * (Math.PI / 180.0)),
magnitude * Math.cos(angle * (Math.PI / 180.0)), zRotation, 0.0);
driveCartesian(
magnitude * Math.sin(angle * (Math.PI / 180.0)),
magnitude * Math.cos(angle * (Math.PI / 180.0)),
zRotation,
0.0);
}
@Override

View File

@@ -4,8 +4,6 @@
package edu.wpi.first.wpilibj.drive;
import java.util.StringJoiner;
import edu.wpi.first.hal.FRCNetComm.tInstances;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
@@ -14,6 +12,7 @@ import edu.wpi.first.wpilibj.SpeedController;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import edu.wpi.first.wpiutil.math.MathUtil;
import java.util.StringJoiner;
/**
* A class for driving Mecanum drive platforms.
@@ -24,6 +23,7 @@ import edu.wpi.first.wpiutil.math.MathUtil;
* relations for a Mecanum drive robot.
*
* <p>Drive base diagram:
*
* <pre>
* \\_______/
* \\ | | /
@@ -44,19 +44,19 @@ import edu.wpi.first.wpiutil.math.MathUtil;
* positive.
*
* <p>Inputs smaller then {@value edu.wpi.first.wpilibj.drive.RobotDriveBase#kDefaultDeadband} will
* be set to 0, and larger values will be scaled so that the full range is still used. This
* deadband value can be changed with {@link #setDeadband}.
* be set to 0, and larger values will be scaled so that the full range is still used. This deadband
* value can be changed with {@link #setDeadband}.
*
* <p>RobotDrive porting guide:
* <br>In MecanumDrive, the right side speed controllers are automatically inverted, while in
* RobotDrive, no speed controllers are automatically inverted.
* <br>{@link #driveCartesian(double, double, double, double)} is equivalent to
* {@link edu.wpi.first.wpilibj.RobotDrive#mecanumDrive_Cartesian(double, double, double, double)}
* if a deadband of 0 is used, and the ySpeed and gyroAngle values are inverted compared to
* RobotDrive (eg driveCartesian(xSpeed, -ySpeed, zRotation, -gyroAngle).
* <br>{@link #drivePolar(double, double, double)} is equivalent to
* {@link edu.wpi.first.wpilibj.RobotDrive#mecanumDrive_Polar(double, double, double)} if a
* deadband of 0 is used.
* <p>RobotDrive porting guide: <br>
* In MecanumDrive, the right side speed controllers are automatically inverted, while in
* RobotDrive, no speed controllers are automatically inverted. <br>
* {@link #driveCartesian(double, double, double, double)} is equivalent to {@link
* edu.wpi.first.wpilibj.RobotDrive#mecanumDrive_Cartesian(double, double, double, double)} if a
* deadband of 0 is used, and the ySpeed and gyroAngle values are inverted compared to RobotDrive
* (eg driveCartesian(xSpeed, -ySpeed, zRotation, -gyroAngle). <br>
* {@link #drivePolar(double, double, double)} is equivalent to {@link
* edu.wpi.first.wpilibj.RobotDrive#mecanumDrive_Polar(double, double, double)} if a deadband of 0
* is used.
*/
public class MecanumDrive extends RobotDriveBase implements Sendable, AutoCloseable {
private static int instances;
@@ -74,8 +74,11 @@ public class MecanumDrive extends RobotDriveBase implements Sendable, AutoClosea
*
* <p>If a motor needs to be inverted, do so before passing it in.
*/
public MecanumDrive(SpeedController frontLeftMotor, SpeedController rearLeftMotor,
SpeedController frontRightMotor, SpeedController rearRightMotor) {
public MecanumDrive(
SpeedController frontLeftMotor,
SpeedController rearLeftMotor,
SpeedController frontRightMotor,
SpeedController rearRightMotor) {
verify(frontLeftMotor, rearLeftMotor, frontRightMotor, rearRightMotor);
m_frontLeftMotor = frontLeftMotor;
m_rearLeftMotor = rearLeftMotor;
@@ -95,16 +98,19 @@ public class MecanumDrive extends RobotDriveBase implements Sendable, AutoClosea
}
/**
* Verifies that all motors are nonnull, throwing a NullPointerException if any of them are.
* The exception's error message will specify all null motors, e.g. {@code
* Verifies that all motors are nonnull, throwing a NullPointerException if any of them are. The
* exception's error message will specify all null motors, e.g. {@code
* NullPointerException("frontLeftMotor, rearRightMotor")}, to give as much information as
* possible to the programmer.
*
* @throws NullPointerException if any of the given motors are null
*/
@SuppressWarnings({"PMD.AvoidThrowingNullPointerException", "PMD.CyclomaticComplexity"})
private void verify(SpeedController frontLeft, SpeedController rearLeft,
SpeedController frontRight, SpeedController rearRightMotor) {
private void verify(
SpeedController frontLeft,
SpeedController rearLeft,
SpeedController frontRight,
SpeedController rearRightMotor) {
if (frontLeft != null && rearLeft != null && frontRight != null && rearRightMotor != null) {
return;
}
@@ -130,10 +136,10 @@ public class MecanumDrive extends RobotDriveBase implements Sendable, AutoClosea
* <p>Angles are measured clockwise from the positive X axis. The robot's speed is independent
* from its angle or rotation rate.
*
* @param ySpeed The robot's speed along the Y axis [-1.0..1.0]. Right is positive.
* @param xSpeed The robot's speed along the X axis [-1.0..1.0]. Forward is positive.
* @param ySpeed The robot's speed along the Y axis [-1.0..1.0]. Right is positive.
* @param xSpeed The robot's speed along the X axis [-1.0..1.0]. Forward is positive.
* @param zRotation The robot's rotation rate around the Z axis [-1.0..1.0]. Clockwise is
* positive.
* positive.
*/
@SuppressWarnings("ParameterName")
public void driveCartesian(double ySpeed, double xSpeed, double zRotation) {
@@ -146,18 +152,18 @@ public class MecanumDrive extends RobotDriveBase implements Sendable, AutoClosea
* <p>Angles are measured clockwise from the positive X axis. The robot's speed is independent
* from its angle or rotation rate.
*
* @param ySpeed The robot's speed along the Y axis [-1.0..1.0]. Right is positive.
* @param xSpeed The robot's speed along the X axis [-1.0..1.0]. Forward is positive.
* @param ySpeed The robot's speed along the Y axis [-1.0..1.0]. Right is positive.
* @param xSpeed The robot's speed along the X axis [-1.0..1.0]. Forward is positive.
* @param zRotation The robot's rotation rate around the Z axis [-1.0..1.0]. Clockwise is
* positive.
* @param gyroAngle The current angle reading from the gyro in degrees around the Z axis. Use
* this to implement field-oriented controls.
* positive.
* @param gyroAngle The current angle reading from the gyro in degrees around the Z axis. Use this
* to implement field-oriented controls.
*/
@SuppressWarnings("ParameterName")
public void driveCartesian(double ySpeed, double xSpeed, double zRotation, double gyroAngle) {
if (!m_reported) {
HAL.report(tResourceType.kResourceType_RobotDrive,
tInstances.kRobotDrive2_MecanumCartesian, 4);
HAL.report(
tResourceType.kResourceType_RobotDrive, tInstances.kRobotDrive2_MecanumCartesian, 4);
m_reported = true;
}
@@ -180,11 +186,11 @@ public class MecanumDrive extends RobotDriveBase implements Sendable, AutoClosea
normalize(wheelSpeeds);
m_frontLeftMotor.set(wheelSpeeds[MotorType.kFrontLeft.value] * m_maxOutput);
m_frontRightMotor.set(wheelSpeeds[MotorType.kFrontRight.value] * m_maxOutput
* m_rightSideInvertMultiplier);
m_frontRightMotor.set(
wheelSpeeds[MotorType.kFrontRight.value] * m_maxOutput * m_rightSideInvertMultiplier);
m_rearLeftMotor.set(wheelSpeeds[MotorType.kRearLeft.value] * m_maxOutput);
m_rearRightMotor.set(wheelSpeeds[MotorType.kRearRight.value] * m_maxOutput
* m_rightSideInvertMultiplier);
m_rearRightMotor.set(
wheelSpeeds[MotorType.kRearRight.value] * m_maxOutput * m_rightSideInvertMultiplier);
feed();
}
@@ -196,9 +202,9 @@ public class MecanumDrive extends RobotDriveBase implements Sendable, AutoClosea
* drives (translation) is independent from its angle or rotation rate.
*
* @param magnitude The robot's speed at a given angle [-1.0..1.0]. Forward is positive.
* @param angle The angle around the Z axis at which the robot drives in degrees [-180..180].
* @param angle The angle around the Z axis at which the robot drives in degrees [-180..180].
* @param zRotation The robot's rotation rate around the Z axis [-1.0..1.0]. Clockwise is
* positive.
* positive.
*/
@SuppressWarnings("ParameterName")
public void drivePolar(double magnitude, double angle, double zRotation) {
@@ -207,8 +213,11 @@ public class MecanumDrive extends RobotDriveBase implements Sendable, AutoClosea
m_reported = true;
}
driveCartesian(magnitude * Math.sin(angle * (Math.PI / 180.0)),
magnitude * Math.cos(angle * (Math.PI / 180.0)), zRotation, 0.0);
driveCartesian(
magnitude * Math.sin(angle * (Math.PI / 180.0)),
magnitude * Math.cos(angle * (Math.PI / 180.0)),
zRotation,
0.0);
}
/**
@@ -248,16 +257,15 @@ public class MecanumDrive extends RobotDriveBase implements Sendable, AutoClosea
builder.setSmartDashboardType("MecanumDrive");
builder.setActuator(true);
builder.setSafeState(this::stopMotor);
builder.addDoubleProperty("Front Left Motor Speed",
m_frontLeftMotor::get,
m_frontLeftMotor::set);
builder.addDoubleProperty("Front Right Motor Speed",
builder.addDoubleProperty(
"Front Left Motor Speed", m_frontLeftMotor::get, m_frontLeftMotor::set);
builder.addDoubleProperty(
"Front Right Motor Speed",
() -> m_frontRightMotor.get() * m_rightSideInvertMultiplier,
value -> m_frontRightMotor.set(value * m_rightSideInvertMultiplier));
builder.addDoubleProperty("Rear Left Motor Speed",
m_rearLeftMotor::get,
m_rearLeftMotor::set);
builder.addDoubleProperty("Rear Right Motor Speed",
builder.addDoubleProperty("Rear Left Motor Speed", m_rearLeftMotor::get, m_rearLeftMotor::set);
builder.addDoubleProperty(
"Rear Right Motor Speed",
() -> m_rearRightMotor.get() * m_rightSideInvertMultiplier,
value -> m_rearRightMotor.set(value * m_rightSideInvertMultiplier));
}

View File

@@ -6,9 +6,7 @@ package edu.wpi.first.wpilibj.drive;
import edu.wpi.first.wpilibj.MotorSafety;
/**
* Common base class for drive platforms.
*/
/** Common base class for drive platforms. */
public abstract class RobotDriveBase extends MotorSafety {
public static final double kDefaultDeadband = 0.02;
public static final double kDefaultMaxOutput = 1.0;
@@ -16,12 +14,15 @@ public abstract class RobotDriveBase extends MotorSafety {
protected double m_deadband = kDefaultDeadband;
protected double m_maxOutput = kDefaultMaxOutput;
/**
* The location of a motor on the robot for the purpose of driving.
*/
/** The location of a motor on the robot for the purpose of driving. */
public enum MotorType {
kFrontLeft(0), kFrontRight(1), kRearLeft(2), kRearRight(3), kLeft(0),
kRight(1), kBack(2);
kFrontLeft(0),
kFrontRight(1),
kRearLeft(2),
kRearRight(3),
kLeft(0),
kRight(1),
kBack(2);
public final int value;
@@ -30,9 +31,7 @@ public abstract class RobotDriveBase extends MotorSafety {
}
}
/**
* RobotDriveBase constructor.
*/
/** RobotDriveBase constructor. */
public RobotDriveBase() {
setSafetyEnabled(true);
}
@@ -41,8 +40,8 @@ public abstract class RobotDriveBase extends MotorSafety {
* Sets the deadband applied to the drive inputs (e.g., joystick values).
*
* <p>The default value is {@value #kDefaultDeadband}. Inputs smaller than the deadband are set to
* 0.0 while inputs larger than the deadband are scaled from 0.0 to 1.0. See
* {@link #applyDeadband}.
* 0.0 while inputs larger than the deadband are scaled from 0.0 to 1.0. See {@link
* #applyDeadband}.
*
* @param deadband The deadband to set.
*/
@@ -81,7 +80,7 @@ public abstract class RobotDriveBase extends MotorSafety {
* Returns 0.0 if the given value is within the specified range around zero. The remaining range
* between the deadband and 1.0 is scaled from 0.0 to 1.0.
*
* @param value value to clip
* @param value value to clip
* @param deadband range around zero
*/
protected double applyDeadband(double value, double deadband) {
@@ -96,9 +95,7 @@ public abstract class RobotDriveBase extends MotorSafety {
}
}
/**
* Normalize all wheel speeds if the magnitude of any wheel is greater than 1.0.
*/
/** Normalize all wheel speeds if the magnitude of any wheel is greater than 1.0. */
protected void normalize(double[] wheelSpeeds) {
double maxMagnitude = Math.abs(wheelSpeeds[0]);
for (int i = 1; i < wheelSpeeds.length; i++) {

View File

@@ -4,12 +4,11 @@
package edu.wpi.first.wpilibj.drive;
/**
* This is a 2D vector struct that supports basic vector operations.
*/
/** This is a 2D vector struct that supports basic vector operations. */
public class Vector2d {
@SuppressWarnings("MemberName")
public double x;
@SuppressWarnings("MemberName")
public double y;
@@ -44,9 +43,7 @@ public class Vector2d {
return x * vec.x + y * vec.y;
}
/**
* Returns magnitude of vector.
*/
/** Returns magnitude of vector. */
public double magnitude() {
return Math.sqrt(x * x + y * y);
}

View File

@@ -40,9 +40,7 @@ public abstract class Filter implements PIDSource {
*/
public abstract double get();
/**
* Reset the filter state.
*/
/** Reset the filter state. */
public abstract void reset();
/**

View File

@@ -4,12 +4,11 @@
package edu.wpi.first.wpilibj.filters;
import java.util.Arrays;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.PIDSource;
import edu.wpi.first.wpiutil.CircularBuffer;
import java.util.Arrays;
/**
* This class implements a linear, digital filter. All types of FIR and IIR filters are supported.
@@ -26,8 +25,8 @@ import edu.wpi.first.wpiutil.CircularBuffer;
* <p>What can linear filters do? Basically, they can filter, or diminish, the effects of
* undesirable input frequencies. High frequencies, or rapid changes, can be indicative of sensor
* noise or be otherwise undesirable. A "low pass" filter smooths out the signal, reducing the
* impact of these high frequency components. Likewise, a "high pass" filter gets rid of
* slow-moving signal components, letting you detect large changes more easily.
* impact of these high frequency components. Likewise, a "high pass" filter gets rid of slow-moving
* signal components, letting you detect large changes more easily.
*
* <p>Example FRC applications of filters: - Getting rid of noise from an analog sensor input (note:
* the roboRIO's FPGA can do this faster in hardware) - Smoothing out joystick input to prevent the
@@ -62,12 +61,11 @@ public class LinearDigitalFilter extends Filter {
/**
* Create a linear FIR or IIR filter.
*
* @param source The PIDSource object that is used to get values
* @param source The PIDSource object that is used to get values
* @param ffGains The "feed forward" or FIR gains
* @param fbGains The "feed back" or IIR gains
*/
public LinearDigitalFilter(PIDSource source, double[] ffGains,
double[] fbGains) {
public LinearDigitalFilter(PIDSource source, double[] ffGains, double[] fbGains) {
super(source);
m_inputs = new CircularBuffer(ffGains.length);
m_outputs = new CircularBuffer(fbGains.length);
@@ -84,13 +82,12 @@ public class LinearDigitalFilter extends Filter {
*
* <p>This filter is stable for time constants greater than zero.
*
* @param source The PIDSource object that is used to get values
* @param source The PIDSource object that is used to get values
* @param timeConstant The discrete-time time constant in seconds
* @param period The period in seconds between samples taken by the user
* @param period The period in seconds between samples taken by the user
*/
public static LinearDigitalFilter singlePoleIIR(PIDSource source,
double timeConstant,
double period) {
public static LinearDigitalFilter singlePoleIIR(
PIDSource source, double timeConstant, double period) {
double gain = Math.exp(-period / timeConstant);
double[] ffGains = {1.0 - gain};
double[] fbGains = {-gain};
@@ -104,13 +101,11 @@ public class LinearDigitalFilter extends Filter {
*
* <p>This filter is stable for time constants greater than zero.
*
* @param source The PIDSource object that is used to get values
* @param source The PIDSource object that is used to get values
* @param timeConstant The discrete-time time constant in seconds
* @param period The period in seconds between samples taken by the user
* @param period The period in seconds between samples taken by the user
*/
public static LinearDigitalFilter highPass(PIDSource source,
double timeConstant,
double period) {
public static LinearDigitalFilter highPass(PIDSource source, double timeConstant, double period) {
double gain = Math.exp(-period / timeConstant);
double[] ffGains = {gain, -gain};
double[] fbGains = {-gain};
@@ -125,7 +120,7 @@ public class LinearDigitalFilter extends Filter {
* <p>This filter is always stable.
*
* @param source The PIDSource object that is used to get values
* @param taps The number of samples to average over. Higher = smoother but slower
* @param taps The number of samples to average over. Higher = smoother but slower
* @throws IllegalArgumentException if number of taps is less than 1
*/
public static LinearDigitalFilter movingAverage(PIDSource source, int taps) {

View File

@@ -4,19 +4,20 @@
package edu.wpi.first.wpilibj.interfaces;
/**
* Interface for 3-axis accelerometers.
*/
/** Interface for 3-axis accelerometers. */
public interface Accelerometer {
enum Range {
k2G, k4G, k8G, k16G
k2G,
k4G,
k8G,
k16G
}
/**
* Common interface for setting the measuring range of an accelerometer.
*
* @param range The maximum acceleration, positive or negative, that the accelerometer will
* measure. Not all accelerometers support all ranges.
* measure. Not all accelerometers support all ranges.
*/
void setRange(Range range);

View File

@@ -6,14 +6,12 @@ package edu.wpi.first.wpilibj.interfaces;
import edu.wpi.first.wpilibj.geometry.Rotation2d;
/**
* Interface for yaw rate gyros.
*/
/** Interface for yaw rate gyros. */
public interface Gyro extends AutoCloseable {
/**
* Calibrate the gyro. It's important to make sure that the robot is not moving while the
* calibration is in progress, this is typically done when the robot is first turned on while
* it's sitting at rest before the match starts.
* calibration is in progress, this is typically done when the robot is first turned on while it's
* sitting at rest before the match starts.
*/
void calibrate();
@@ -27,11 +25,11 @@ public interface Gyro extends AutoCloseable {
* 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.
* 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>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.
*
@@ -44,8 +42,8 @@ public interface Gyro extends AutoCloseable {
*
* <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.
* <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
*/
@@ -55,16 +53,16 @@ public interface Gyro extends AutoCloseable {
* Return the heading of the robot as a {@link edu.wpi.first.wpilibj.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.
* 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>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.wpilibj.geometry.Rotation2d}.
* @return the current heading of the robot as a {@link
* edu.wpi.first.wpilibj.geometry.Rotation2d}.
*/
default Rotation2d getRotation2d() {
return Rotation2d.fromDegrees(-getAngle());

View File

@@ -6,9 +6,7 @@ package edu.wpi.first.wpilibj.interfaces;
import edu.wpi.first.wpilibj.PIDSource;
/**
* Interface for a Potentiometer.
*/
/** Interface for a Potentiometer. */
public interface Potentiometer extends PIDSource {
double get();
}

View File

@@ -10,10 +10,8 @@ import edu.wpi.first.networktables.NetworkTableInstance;
import edu.wpi.first.wpilibj.Sendable;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* The LiveWindow class is the public interface for putting sensors and actuators on the
* LiveWindow.
* The LiveWindow class is the public interface for putting sensors and actuators on the LiveWindow.
*/
public class LiveWindow {
private static class Component {
@@ -78,9 +76,11 @@ public class LiveWindow {
}
} else {
System.out.println("stopping live window mode.");
SendableRegistry.foreachLiveWindow(dataHandle, cbdata -> {
cbdata.builder.stopLiveWindowMode();
});
SendableRegistry.foreachLiveWindow(
dataHandle,
cbdata -> {
cbdata.builder.stopLiveWindowMode();
});
if (disabledListener != null) {
disabledListener.run();
}
@@ -109,24 +109,24 @@ public class LiveWindow {
getOrAdd(sendable).m_telemetryEnabled = false;
}
/**
* Disable ALL telemetry.
*/
/** Disable ALL telemetry. */
public static synchronized void disableAllTelemetry() {
telemetryEnabled = false;
SendableRegistry.foreachLiveWindow(dataHandle, cbdata -> {
if (cbdata.data == null) {
cbdata.data = new Component();
}
((Component) cbdata.data).m_telemetryEnabled = false;
});
SendableRegistry.foreachLiveWindow(
dataHandle,
cbdata -> {
if (cbdata.data == null) {
cbdata.data = new Component();
}
((Component) cbdata.data).m_telemetryEnabled = false;
});
}
/**
* Tell all the sensors to update (send) their values.
*
* <p>Actuators are handled through callbacks on their value changing from the
* SmartDashboard widgets.
* <p>Actuators are handled through callbacks on their value changing from the SmartDashboard
* widgets.
*/
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
public static synchronized void updateValues() {
@@ -135,50 +135,52 @@ public class LiveWindow {
return;
}
SendableRegistry.foreachLiveWindow(dataHandle, cbdata -> {
if (cbdata.sendable == null || cbdata.parent != null) {
return;
}
SendableRegistry.foreachLiveWindow(
dataHandle,
cbdata -> {
if (cbdata.sendable == null || cbdata.parent != null) {
return;
}
if (cbdata.data == null) {
cbdata.data = new Component();
}
if (cbdata.data == null) {
cbdata.data = new Component();
}
Component component = (Component) cbdata.data;
Component component = (Component) cbdata.data;
if (!liveWindowEnabled && !component.m_telemetryEnabled) {
return;
}
if (!liveWindowEnabled && !component.m_telemetryEnabled) {
return;
}
if (component.m_firstTime) {
// By holding off creating the NetworkTable entries, it allows the
// components to be redefined. This allows default sensor and actuator
// values to be created that are replaced with the custom names from
// users calling setName.
if (cbdata.name.isEmpty()) {
return;
}
NetworkTable ssTable = liveWindowTable.getSubTable(cbdata.subsystem);
NetworkTable table;
// Treat name==subsystem as top level of subsystem
if (cbdata.name.equals(cbdata.subsystem)) {
table = ssTable;
} else {
table = ssTable.getSubTable(cbdata.name);
}
table.getEntry(".name").setString(cbdata.name);
cbdata.builder.setTable(table);
cbdata.sendable.initSendable(cbdata.builder);
ssTable.getEntry(".type").setString("LW Subsystem");
if (component.m_firstTime) {
// By holding off creating the NetworkTable entries, it allows the
// components to be redefined. This allows default sensor and actuator
// values to be created that are replaced with the custom names from
// users calling setName.
if (cbdata.name.isEmpty()) {
return;
}
NetworkTable ssTable = liveWindowTable.getSubTable(cbdata.subsystem);
NetworkTable table;
// Treat name==subsystem as top level of subsystem
if (cbdata.name.equals(cbdata.subsystem)) {
table = ssTable;
} else {
table = ssTable.getSubTable(cbdata.name);
}
table.getEntry(".name").setString(cbdata.name);
cbdata.builder.setTable(table);
cbdata.sendable.initSendable(cbdata.builder);
ssTable.getEntry(".type").setString("LW Subsystem");
component.m_firstTime = false;
}
component.m_firstTime = false;
}
if (startLiveWindow) {
cbdata.builder.startLiveWindowMode();
}
cbdata.builder.updateTable();
});
if (startLiveWindow) {
cbdata.builder.startLiveWindowMode();
}
cbdata.builder.updateTable();
});
startLiveWindow = false;
}

View File

@@ -15,8 +15,9 @@ package edu.wpi.first.wpilibj.shuffleboard;
public enum BuiltInLayouts implements LayoutType {
/**
* Groups components in a vertical list. New widgets added to the layout will be placed at the
* bottom of the list.
* <br>Custom properties:
* bottom of the list. <br>
* Custom properties:
*
* <table>
* <tr><th>Name</th><th>Type</th><th>Default Value</th><th>Notes</th></tr>
* <tr><td>Label position</td><td>String</td><td>"BOTTOM"</td>
@@ -27,8 +28,9 @@ public enum BuiltInLayouts implements LayoutType {
kList("List Layout"),
/**
* Groups components in an <i>n</i> x <i>m</i> grid. Grid layouts default to 3x3.
* <br>Custom properties:
* Groups components in an <i>n</i> x <i>m</i> grid. Grid layouts default to 3x3. <br>
* Custom properties:
*
* <table>
* <tr><th>Name</th><th>Type</th><th>Default Value</th><th>Notes</th></tr>
* <tr><td>Number of columns</td><td>Number</td><td>3</td><td>Must be in the range [1,15]</td>

Some files were not shown because too many files have changed in this diff Show More