mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-24 01:31:46 +00:00
[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:
@@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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) {}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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]
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -30,6 +30,5 @@ public final class RobotState {
|
||||
return DriverStation.getInstance().isTest();
|
||||
}
|
||||
|
||||
private RobotState() {
|
||||
}
|
||||
private RobotState() {}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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() {}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
/**
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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() {}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 > 0) for which larger values make convergence more
|
||||
* aggressive like a proportional term.
|
||||
* @param b Tuning parameter (b > 0) for which larger values make convergence more aggressive
|
||||
* like a proportional term.
|
||||
* @param zeta Tuning parameter (0 < zeta < 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
/**
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user