Applies Google Styleguide to Java parts of the library (#23)

This was partially applied to simulation but
simulation is a bit of a mess and has a lot of duplicated code.
This commit is contained in:
Jonathan Leitschuh
2016-05-20 12:07:40 -04:00
committed by Peter Johnson
parent 64ab6e51fe
commit a834fff7b2
266 changed files with 15574 additions and 14718 deletions

View File

@@ -7,8 +7,8 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteOrder;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tInstances;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
@@ -19,9 +19,11 @@ import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
/**
* ADXL345 I2C Accelerometer.
*
* @author dtjones
*/
@SuppressWarnings("TypeName")
public class ADXL345_I2C extends SensorBase implements Accelerometer, LiveWindowSendable {
private static final byte kAddress = 0x1D;
@@ -29,26 +31,34 @@ public class ADXL345_I2C extends SensorBase implements Accelerometer, LiveWindow
private static final byte kDataFormatRegister = 0x31;
private static final byte kDataRegister = 0x32;
private static final double kGsPerLSB = 0.00390625;
private static final byte kPowerCtl_Link = 0x20, kPowerCtl_AutoSleep = 0x10,
kPowerCtl_Measure = 0x08, kPowerCtl_Sleep = 0x04;
private static final byte kDataFormat_SelfTest = (byte) 0x80, kDataFormat_SPI = 0x40,
kDataFormat_IntInvert = 0x20, kDataFormat_FullRes = 0x08, kDataFormat_Justify = 0x04;
private static final byte kPowerCtl_Link = 0x20;
private static final byte kPowerCtl_AutoSleep = 0x10;
private static final byte kPowerCtl_Measure = 0x08;
private static final byte kPowerCtl_Sleep = 0x04;
public static enum Axes {
private static final byte kDataFormat_SelfTest = (byte) 0x80;
private static final byte kDataFormat_SPI = 0x40;
private static final byte kDataFormat_IntInvert = 0x20;
private static final byte kDataFormat_FullRes = 0x08;
private static final byte kDataFormat_Justify = 0x04;
public enum Axes {
kX((byte) 0x00),
kY((byte) 0x02),
kZ((byte) 0x04);
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final byte value;
private Axes(byte value) {
Axes(byte value) {
this.value = value;
}
}
@SuppressWarnings("MemberName")
public static class AllAxes {
public double XAxis;
@@ -60,8 +70,8 @@ public class ADXL345_I2C extends SensorBase implements Accelerometer, LiveWindow
/**
* 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) {
@@ -70,10 +80,10 @@ public class ADXL345_I2C extends SensorBase implements Accelerometer, LiveWindow
/**
* 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 the I2C address of the accelerometer (0x1D or 0x53)
*
* @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) {
m_i2c = new I2C(port, deviceAddress);
@@ -87,10 +97,10 @@ public class ADXL345_I2C extends SensorBase implements Accelerometer, LiveWindow
LiveWindow.addSensor("ADXL345_I2C", port.getValue(), this);
}
/** {inheritdoc} */
@Override
public void setRange(Range range) {
byte value = 0;
final byte value;
switch (range) {
case k2G:
@@ -105,25 +115,24 @@ public class ADXL345_I2C extends SensorBase implements Accelerometer, LiveWindow
case k16G:
value = 3;
break;
default:
throw new IllegalArgumentException(range + " unsupported range type");
}
// Specify the data format to read
m_i2c.write(kDataFormatRegister, kDataFormat_FullRes | value);
}
/** {@inheritDoc} */
@Override
public double getX() {
return getAcceleration(Axes.kX);
}
/** {@inheritDoc} */
@Override
public double getY() {
return getAcceleration(Axes.kY);
}
/** {@inheritDoc} */
@Override
public double getZ() {
return getAcceleration(Axes.kZ);
@@ -147,8 +156,7 @@ public class ADXL345_I2C extends SensorBase implements Accelerometer, LiveWindow
/**
* Get the acceleration of all axes in Gs.
*
* @return An object containing the acceleration measured on each axis of the
* ADXL345 in Gs.
* @return An object containing the acceleration measured on each axis of the ADXL345 in Gs.
*/
public AllAxes getAccelerations() {
AllAxes data = new AllAxes();
@@ -163,19 +171,20 @@ public class ADXL345_I2C extends SensorBase implements Accelerometer, LiveWindow
return data;
}
@Override
public String getSmartDashboardType() {
return "3AxisAccelerometer";
}
private ITable m_table;
/** {@inheritDoc} */
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/** {@inheritDoc} */
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("X", getX());
@@ -184,12 +193,16 @@ public class ADXL345_I2C extends SensorBase implements Accelerometer, LiveWindow
}
}
/** {@inheritDoc} */
@Override
public ITable getTable() {
return m_table;
}
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
public void stopLiveWindowMode() {}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -7,8 +7,8 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteOrder;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tInstances;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
@@ -19,10 +19,12 @@ import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
/**
* ADXL345 SPI Accelerometer.
*
* @author dtjones
* @author mwills
*/
@SuppressWarnings({"TypeName"})
public class ADXL345_SPI extends SensorBase implements Accelerometer, LiveWindowSendable {
private static final int kPowerCtlRegister = 0x2D;
private static final int kDataFormatRegister = 0x31;
@@ -43,21 +45,23 @@ public class ADXL345_SPI extends SensorBase implements Accelerometer, LiveWindow
private static final int kDataFormat_FullRes = 0x08;
private static final int kDataFormat_Justify = 0x04;
public static enum Axes {
public enum Axes {
kX((byte) 0x00),
kY((byte) 0x02),
kZ((byte) 0x04);
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final byte value;
private Axes(byte value) {
Axes(byte value) {
this.value = value;
}
}
@SuppressWarnings("MemberName")
public static class AllAxes {
public double XAxis;
@@ -70,7 +74,7 @@ public class ADXL345_SPI extends SensorBase implements Accelerometer, LiveWindow
/**
* 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) {
@@ -84,7 +88,7 @@ public class ADXL345_SPI extends SensorBase implements Accelerometer, LiveWindow
}
/**
* Set SPI bus parameters, bring device out of sleep and set format
* Set SPI bus parameters, bring device out of sleep and set format.
*
* @param range The range (+ or -) that the accelerometer will measure.
*/
@@ -106,10 +110,9 @@ public class ADXL345_SPI extends SensorBase implements Accelerometer, LiveWindow
UsageReporting.report(tResourceType.kResourceType_ADXL345, tInstances.kADXL345_SPI);
}
/** {inheritdoc} */
@Override
public void setRange(Range range) {
byte value = 0;
final byte value;
switch (range) {
case k2G:
@@ -124,26 +127,25 @@ public class ADXL345_SPI extends SensorBase implements Accelerometer, LiveWindow
case k16G:
value = 3;
break;
default:
throw new IllegalArgumentException(range + " unsupported");
}
// 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);
}
/** {@inheritDoc} */
@Override
public double getX() {
return getAcceleration(Axes.kX);
}
/** {@inheritDoc} */
@Override
public double getY() {
return getAcceleration(Axes.kY);
}
/** {@inheritDoc} */
@Override
public double getZ() {
return getAcceleration(Axes.kZ);
@@ -157,7 +159,8 @@ public class ADXL345_SPI extends SensorBase implements Accelerometer, LiveWindow
*/
public double getAcceleration(ADXL345_SPI.Axes axis) {
ByteBuffer transferBuffer = ByteBuffer.allocateDirect(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);
@@ -168,8 +171,7 @@ public class ADXL345_SPI extends SensorBase implements Accelerometer, LiveWindow
/**
* Get the acceleration of all axes in Gs.
*
* @return An object containing the acceleration measured on each axis of the
* ADXL345 in Gs.
* @return An object containing the acceleration measured on each axis of the ADXL345 in Gs.
*/
public ADXL345_SPI.AllAxes getAccelerations() {
ADXL345_SPI.AllAxes data = new ADXL345_SPI.AllAxes();
@@ -188,19 +190,20 @@ public class ADXL345_SPI extends SensorBase implements Accelerometer, LiveWindow
return data;
}
@Override
public String getSmartDashboardType() {
return "3AxisAccelerometer";
}
private ITable m_table;
/** {@inheritDoc} */
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/** {@inheritDoc} */
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("X", getX());
@@ -209,12 +212,16 @@ public class ADXL345_SPI extends SensorBase implements Accelerometer, LiveWindow
}
}
/** {@inheritDoc} */
@Override
public ITable getTable() {
return m_table;
}
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
public void stopLiveWindowMode() {}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -7,10 +7,9 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteOrder;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tInstances;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
@@ -21,7 +20,7 @@ import edu.wpi.first.wpilibj.tables.ITable;
/**
* ADXL362 SPI Accelerometer.
*
* This class allows access to an Analog Devices ADXL362 3-axis accelerometer.
* <p>This class allows access to an Analog Devices ADXL362 3-axis accelerometer.
*/
public class ADXL362 extends SensorBase implements Accelerometer, LiveWindowSendable {
private static final byte kRegWrite = 0x0A;
@@ -41,21 +40,23 @@ public class ADXL362 extends SensorBase implements Accelerometer, LiveWindowSend
private static final byte kPowerCtl_AutoSleep = 0x04;
private static final byte kPowerCtl_Measure = 0x02;
public static enum Axes {
public enum Axes {
kX((byte) 0x00),
kY((byte) 0x02),
kZ((byte) 0x04);
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final byte value;
private Axes(byte value) {
Axes(byte value) {
this.value = value;
}
}
@SuppressWarnings("MemberName")
public static class AllAxes {
public double XAxis;
@@ -78,7 +79,7 @@ public class ADXL362 extends SensorBase implements Accelerometer, LiveWindowSend
/**
* 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) {
@@ -94,7 +95,7 @@ public class ADXL362 extends SensorBase implements Accelerometer, LiveWindowSend
transferBuffer.put(0, kRegRead);
transferBuffer.put(1, kPartIdRegister);
m_spi.transaction(transferBuffer, transferBuffer, 3);
if (transferBuffer.get(2) != (byte)0xF2) {
if (transferBuffer.get(2) != (byte) 0xF2) {
m_spi.free();
m_spi = null;
DriverStation.reportError("could not find ADXL362 on SPI port " + port.getValue(), false);
@@ -117,45 +118,46 @@ public class ADXL362 extends SensorBase implements Accelerometer, LiveWindowSend
m_spi.free();
}
/** {inheritdoc} */
@Override
public void setRange(Range range) {
byte value = 0;
final byte value;
switch (range) {
case k2G:
value = kFilterCtl_Range2G;
m_gsPerLSB = 0.001;
m_gsPerLSB = 0.001;
break;
case k4G:
value = kFilterCtl_Range4G;
m_gsPerLSB = 0.002;
m_gsPerLSB = 0.002;
break;
case k8G:
case k16G: // 16G not supported; treat as 8G
value = kFilterCtl_Range8G;
m_gsPerLSB = 0.004;
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);
}
/** {@inheritDoc} */
@Override
public double getX() {
return getAcceleration(Axes.kX);
}
/** {@inheritDoc} */
@Override
public double getY() {
return getAcceleration(Axes.kY);
}
/** {@inheritDoc} */
@Override
public double getZ() {
return getAcceleration(Axes.kZ);
@@ -168,8 +170,9 @@ public class ADXL362 extends SensorBase implements Accelerometer, LiveWindowSend
* @return Acceleration of the ADXL362 in Gs.
*/
public double getAcceleration(ADXL362.Axes axis) {
if (m_spi == null)
if (m_spi == null) {
return 0.0;
}
ByteBuffer transferBuffer = ByteBuffer.allocateDirect(4);
transferBuffer.put(0, kRegRead);
transferBuffer.put(1, (byte) (kDataRegister + axis.value));
@@ -183,8 +186,7 @@ public class ADXL362 extends SensorBase implements Accelerometer, LiveWindowSend
/**
* Get the acceleration of all axes in Gs.
*
* @return An object containing the acceleration measured on each axis of the
* ADXL362 in Gs.
* @return An object containing the acceleration measured on each axis of the ADXL362 in Gs.
*/
public ADXL362.AllAxes getAccelerations() {
ADXL362.AllAxes data = new ADXL362.AllAxes();
@@ -204,19 +206,20 @@ public class ADXL362 extends SensorBase implements Accelerometer, LiveWindowSend
return data;
}
@Override
public String getSmartDashboardType() {
return "3AxisAccelerometer";
}
private ITable m_table;
/** {@inheritDoc} */
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/** {@inheritDoc} */
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("X", getX());
@@ -225,12 +228,16 @@ public class ADXL362 extends SensorBase implements Accelerometer, LiveWindowSend
}
}
/** {@inheritDoc} */
@Override
public ITable getTable() {
return m_table;
}
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
public void stopLiveWindowMode() {}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -7,28 +7,25 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteOrder;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tInstances;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.interfaces.Gyro;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
/**
* 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 computed by integrating the rate of
* rotation returned by the sensor. When the class is instantiated, it does a
* short calibration routine where it samples the gyro while at rest to
* determine the default offset. This is subtracted from each sample to
* determine the heading.
* 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
* computed by integrating the rate of rotation returned by the sensor. When the class is
* instantiated, it does a short calibration routine where it samples the gyro while at rest to
* determine the default offset. This is subtracted from each sample to determine the heading.
*
* This class is for the digital ADXRS450 gyro sensor that connects via SPI.
* <p>This class is for the digital ADXRS450 gyro sensor that connects via SPI.
*/
@SuppressWarnings({"TypeName", "AbbreviationAsWordInName"})
public class ADXRS450_Gyro extends GyroBase implements Gyro, PIDSource, LiveWindowSendable {
private static final double kSamplePeriod = 0.001;
private static final double kCalibrationSampleTime = 5.0;
@@ -70,7 +67,8 @@ public class ADXRS450_Gyro extends GyroBase implements Gyro, PIDSource, LiveWind
if ((readRegister(kPIDRegister) & 0xff00) != 0x5200) {
m_spi.free();
m_spi = null;
DriverStation.reportError("could not find ADXRS450 gyro on SPI port " + port.getValue(), false);
DriverStation.reportError("could not find ADXRS450 gyro on SPI port " + port.getValue(),
false);
return;
}
@@ -83,12 +81,11 @@ public class ADXRS450_Gyro extends GyroBase implements Gyro, PIDSource, LiveWind
LiveWindow.addSensor("ADXRS450_Gyro", port.getValue(), this);
}
/**
* {@inheritDoc}
*/
@Override
public void calibrate() {
if (m_spi == null) return;
if (m_spi == null) {
return;
}
Timer.delay(0.1);
@@ -97,15 +94,15 @@ public class ADXRS450_Gyro extends GyroBase implements Gyro, PIDSource, LiveWind
Timer.delay(kCalibrationSampleTime);
m_spi.setAccumulatorCenter((int)m_spi.getAccumulatorAverage());
m_spi.setAccumulatorCenter((int) m_spi.getAccumulatorAverage());
m_spi.resetAccumulator();
}
private boolean calcParity(int v) {
private boolean calcParity(int value) {
boolean parity = false;
while (v != 0) {
while (value != 0) {
parity = !parity;
v = v & (v - 1);
value = value & (value - 1);
}
return parity;
}
@@ -130,9 +127,7 @@ public class ADXRS450_Gyro extends GyroBase implements Gyro, PIDSource, LiveWind
return (buf.getInt(0) >> 5) & 0xffff;
}
/**
* {@inheritDoc}
*/
@Override
public void reset() {
m_spi.resetAccumulator();
}
@@ -148,19 +143,19 @@ public class ADXRS450_Gyro extends GyroBase implements Gyro, PIDSource, LiveWind
}
}
/**
* {@inheritDoc}
*/
@Override
public double getAngle() {
if (m_spi == null) return 0.0;
if (m_spi == null) {
return 0.0;
}
return m_spi.getAccumulatorValue() * kDegreePerSecondPerLSB * kSamplePeriod;
}
/**
* {@inheritDoc}
*/
@Override
public double getRate() {
if (m_spi == null) return 0.0;
if (m_spi == null) {
return 0.0;
}
return m_spi.getAccumulatorLastValue() * kDegreePerSecondPerLSB;
}
}

View File

@@ -8,18 +8,20 @@
package edu.wpi.first.wpilibj;
/**
* Structure for holding the values stored in an accumulator
*$
* Structure for holding the values stored in an accumulator.
*
* @author brad
*/
public class AccumulatorResult {
/**
* The total value accumulated
* The total value accumulated.
*/
@SuppressWarnings("MemberName")
public long value;
/**
* The number of sample vaule was accumulated over
* The number of sample vaule was accumulated over.
*/
@SuppressWarnings("MemberName")
public long count;
}

View File

@@ -15,10 +15,9 @@ import edu.wpi.first.wpilibj.tables.ITable;
/**
* 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 is calibrated by finding the center
* value over a period of time.
* 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
* is calibrated by finding the center value over a period of time.
*/
public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWindowSendable {
@@ -29,7 +28,7 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
protected PIDSourceType m_pidSource = PIDSourceType.kDisplacement;
/**
* Common initialization
* Common initialization.
*/
private void initAccelerometer() {
UsageReporting.report(tResourceType.kResourceType_Accelerometer, m_analogChannel.getChannel());
@@ -39,10 +38,9 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
/**
* Create a new instance of an accelerometer.
*
* The constructor allocates desired analog channel.
*$
* @param channel The channel number for the analog input the accelerometer is
* connected to
* <p>The constructor allocates desired analog channel.
*
* @param channel The channel number for the analog input the accelerometer is connected to
*/
public AnalogAccelerometer(final int channel) {
m_allocatedChannel = true;
@@ -51,18 +49,18 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
}
/**
* Create a new instance of Accelerometer from an existing AnalogChannel. Make
* a new instance of accelerometer given an AnalogChannel. This is
* particularly useful if the port is going to be 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
* Create a new instance of Accelerometer from an existing AnalogChannel. Make a new instance of
* accelerometer given an AnalogChannel. This is particularly useful if the port is going to be
* 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
*/
public AnalogAccelerometer(AnalogInput channel) {
m_allocatedChannel = false;
if (channel == null)
if (channel == null) {
throw new NullPointerException("Analog Channel given was null");
}
m_analogChannel = channel;
initAccelerometer();
}
@@ -70,6 +68,7 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
/**
* Delete the analog components used for the accelerometer.
*/
@Override
public void free() {
if (m_analogChannel != null && m_allocatedChannel) {
m_analogChannel.free();
@@ -80,7 +79,7 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
/**
* Return the acceleration in Gs.
*
* The acceleration is returned units of Gs.
* <p>The acceleration is returned units of Gs.
*
* @return The current acceleration of the sensor in Gs.
*/
@@ -91,9 +90,8 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
/**
* Set the accelerometer sensitivity.
*
* This sets the sensitivity of the accelerometer used for calculating the
* acceleration. The sensitivity varies by accelerometer model. There are
* constants defined for various models.
* <p>This sets the sensitivity of the accelerometer used for calculating the acceleration. The
* sensitivity varies by accelerometer model. There are constants defined for various models.
*
* @param sensitivity The sensitivity of accelerometer in Volts per G.
*/
@@ -104,8 +102,8 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
/**
* Set the voltage that corresponds to 0 G.
*
* The zero G voltage varies by accelerometer model. There are constants
* defined for various models.
* <p>The zero G voltage varies by accelerometer model. There are constants defined for various
* models.
*
* @param zero The zero G voltage.
*/
@@ -113,16 +111,12 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
m_zeroGVoltage = zero;
}
/**
* {@inheritDoc}
*/
@Override
public void setPIDSourceType(PIDSourceType pidSource) {
m_pidSource = pidSource;
}
/**
* {@inheritDoc}
*/
@Override
public PIDSourceType getPIDSourceType() {
return m_pidSource;
}
@@ -132,10 +126,12 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
*
* @return The current acceleration in Gs.
*/
@Override
public double pidGet() {
return getAcceleration();
}
@Override
public String getSmartDashboardType() {
return "Accelerometer";
}
@@ -145,24 +141,18 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
*/
private ITable m_table;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("Value", getAcceleration());
@@ -170,14 +160,16 @@ public class AnalogAccelerometer extends SensorBase implements PIDSource, LiveWi
}
/**
* Analog Channels don't have to do anything special when entering the
* LiveWindow. {@inheritDoc}
* Analog Channels don't have to do anything special when entering the LiveWindow. {@inheritDoc}
*/
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
/**
* Analog Channels don't have to do anything special when exiting the
* LiveWindow. {@inheritDoc}
* Analog Channels don't have to do anything special when exiting the LiveWindow. {@inheritDoc}
*/
public void stopLiveWindowMode() {}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -12,39 +12,35 @@ import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.interfaces.Gyro;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
/**
* 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 computed by integrating the rate of
* rotation returned by the sensor. When the class is instantiated, it does a
* short calibration routine where it samples the gyro while at rest to
* determine the default offset. This is subtracted from each sample to
* determine the heading.
* 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
* computed by integrating the rate of rotation returned by the sensor. When the class is
* instantiated, it does a short calibration routine where it samples the gyro while at rest to
* determine the default offset. This is subtracted from each sample to determine the heading.
*
* This class is for gyro sensors that connect to an analog input.
* <p>This class is for gyro sensors that connect to an analog input.
*/
public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowSendable {
static final int kOversampleBits = 10;
static final int kAverageBits = 0;
static final double kSamplesPerSecond = 50.0;
static final double kCalibrationSampleTime = 5.0;
static final double kDefaultVoltsPerDegreePerSecond = 0.007;
private static final int kOversampleBits = 10;
private static final int kAverageBits = 0;
private static final double kSamplesPerSecond = 50.0;
private static final double kCalibrationSampleTime = 5.0;
private static final double kDefaultVoltsPerDegreePerSecond = 0.007;
protected AnalogInput m_analog;
double m_voltsPerDegreePerSecond;
double m_offset;
int m_center;
boolean m_channelAllocated = false;
AccumulatorResult result;
private PIDSourceType m_pidSource;
private double m_voltsPerDegreePerSecond;
private double m_offset;
private int m_center;
private boolean m_channelAllocated = false;
private AccumulatorResult m_result;
/**
* Initialize the gyro. Calibration is handled by calibrate().
*/
public void initGyro() {
result = new AccumulatorResult();
m_result = new AccumulatorResult();
m_voltsPerDegreePerSecond = kDefaultVoltsPerDegreePerSecond;
m_analog.setAverageBits(kAverageBits);
@@ -61,20 +57,18 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
LiveWindow.addSensor("AnalogGyro", m_analog.getChannel(), this);
}
/**
* {@inheritDoc}
*/
@Override
public void calibrate() {
m_analog.initAccumulator();
m_analog.resetAccumulator();
Timer.delay(kCalibrationSampleTime);
m_analog.getAccumulatorOutput(result);
m_analog.getAccumulatorOutput(m_result);
m_center = (int) ((double) result.value / (double) result.count + .5);
m_center = (int) ((double) m_result.value / (double) m_result.count + .5);
m_offset = ((double) result.value / (double) result.count) - m_center;
m_offset = ((double) m_result.value / (double) m_result.count) - m_center;
m_analog.setAccumulatorCenter(m_center);
m_analog.resetAccumulator();
@@ -83,8 +77,8 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
/**
* 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.
* @param channel The analog channel the gyro is connected to. Gyros can only be used on on-board
* channels 0-1.
*/
public AnalogGyro(int channel) {
this(new AnalogInput(channel));
@@ -92,11 +86,11 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
}
/**
* Gyro constructor with a precreated analog channel object. Use this
* constructor when the analog channel needs to be shared.
* Gyro constructor with a precreated analog channel object. Use this constructor when the analog
* 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.
* @param channel The AnalogInput object that the gyro is connected to. Gyros can only be used on
* on-board channels 0-1.
*/
public AnalogGyro(AnalogInput channel) {
m_analog = channel;
@@ -108,12 +102,13 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
}
/**
* Gyro constructor using the channel number along with parameters for
* presetting 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.
* Gyro constructor using the channel number along with parameters for presetting 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.
*/
public AnalogGyro(int channel, int center, double offset) {
this(new AnalogInput(channel), center, offset);
@@ -121,13 +116,13 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
}
/**
* Gyro constructor with a precreated analog channel object along with
* parameters for presetting 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.
* Gyro constructor with a precreated analog channel object along with parameters for presetting
* 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.
*/
public AnalogGyro(AnalogInput channel, int center, double offset) {
m_analog = channel;
@@ -142,9 +137,7 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
m_analog.resetAccumulator();
}
/**
* {@inheritDoc}
*/
@Override
public void reset() {
if (m_analog != null) {
m_analog.resetAccumulator();
@@ -162,16 +155,14 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
m_analog = null;
}
/**
* {@inheritDoc}
*/
@Override
public synchronized double getAngle() {
if (m_analog == null) {
return 0.0;
} else {
m_analog.getAccumulatorOutput(result);
m_analog.getAccumulatorOutput(m_result);
long value = result.value - (long) (result.count * m_offset);
long value = m_result.value - (long) (m_result.count * m_offset);
double scaledValue =
value * 1e-9 * m_analog.getLSBWeight() * (1 << m_analog.getAverageBits())
@@ -181,9 +172,7 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
}
}
/**
* {@inheritDoc}
*/
@Override
public double getRate() {
if (m_analog == null) {
return 0.0;
@@ -194,8 +183,7 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
}
/**
* Return the gyro offset value set during calibration to
* use as a future preset
* Return the gyro offset value set during calibration to use as a future preset.
*
* @return the current offset value
*/
@@ -204,8 +192,7 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
}
/**
* Return the gyro center value set during calibration to
* use as a future preset
* Return the gyro center value set during calibration to use as a future preset.
*
* @return the current center value
*/
@@ -214,10 +201,9 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
}
/**
* Set the gyro sensitivity. This takes the number of volts/degree/second
* sensitivity of the gyro and uses it in subsequent calculations to allow the
* code to work with multiple gyros. This value is typically found in the gyro
* datasheet.
* Set the gyro sensitivity. This takes the number of volts/degree/second sensitivity of the gyro
* and uses it in subsequent calculations to allow the code to work with multiple gyros. This
* value is typically found in the gyro datasheet.
*
* @param voltsPerDegreePerSecond The sensitivity in Volts/degree/second.
*/
@@ -226,10 +212,9 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, LiveWindowS
}
/**
* Set the size of the neutral zone. Any voltage from the gyro less than this
* amount from the center is considered stationary. Setting a deadband will
* decrease the amount of drift when the gyro isn't rotating, but will make it
* less accurate.
* Set the size of the neutral zone. Any voltage from the gyro less than this amount from the
* center is considered stationary. Setting a deadband will decrease the amount of drift when the
* gyro isn't rotating, but will make it less accurate.
*
* @param volts The size of the deadband in volts
*/

View File

@@ -7,12 +7,8 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ByteBuffer;
// import com.sun.jna.Pointer;
import java.nio.ByteOrder;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
@@ -26,17 +22,14 @@ import edu.wpi.first.wpilibj.util.CheckedAllocationException;
/**
* Analog channel class.
*
* Each analog channel is read from hardware as a 12-bit number representing 0V
* to 5V.
* <p>Each analog channel is read from hardware as a 12-bit number representing 0V to 5V.
*
* Connected to each analog channel is an averaging and oversampling engine.
* This engine accumulates the specified ( by setAverageBits() and
* setOversampleBits() ) number of samples before returning a new value. This is
* not a sliding window average. The only difference between the oversampled
* samples and the averaged samples is that the oversampled samples are simply
* accumulated effectively increasing the resolution, while the averaged samples
* are divided by the number of samples to retain the resolution, but get more
* stable values.
* <p>Connected to each analog channel is an averaging and oversampling engine. This engine
* accumulates the specified ( by setAverageBits() and setOversampleBits() ) number of samples
* before returning a new value. This is not a sliding window average. The only difference between
* the oversampled samples and the averaged samples is that the oversampled samples are simply
* accumulated effectively increasing the resolution, while the averaged samples are divided by the
* number of samples to retain the resolution, but get more stable values.
*/
public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSendable {
@@ -51,8 +44,7 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
/**
* Construct an analog channel.
*
* @param channel The channel number to represent. 0-3 are on-board 4-7 are on
* the MXP port.
* @param channel The channel number to represent. 0-3 are on-board 4-7 are on the MXP port.
*/
public AnalogInput(final int channel) {
m_channel = channel;
@@ -63,12 +55,12 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
}
try {
channels.allocate(channel);
} catch (CheckedAllocationException e) {
} catch (CheckedAllocationException ex) {
throw new AllocationException("Analog input channel " + m_channel + " is already allocated");
}
long port_pointer = AnalogJNI.getPort((byte) channel);
m_port = AnalogJNI.initializeAnalogInputPort(port_pointer);
final long portPointer = AnalogJNI.getPort((byte) channel);
m_port = AnalogJNI.initializeAnalogInputPort(portPointer);
LiveWindow.addSensor("AnalogInput", channel, this);
UsageReporting.report(tResourceType.kResourceType_AnalogChannel, channel);
@@ -86,10 +78,9 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
}
/**
* Get a sample straight from this channel. The sample is a 12-bit value
* representing the 0V to 5V range of the A/D converter. The units are in A/D
* converter codes. Use GetVoltage() to get the analog value in calibrated
* units.
* Get a sample straight from this channel. The sample is a 12-bit value representing the 0V to 5V
* range of the A/D converter. The units are in A/D converter codes. Use GetVoltage() to get the
* analog value in calibrated units.
*
* @return A sample straight from this channel.
*/
@@ -98,13 +89,12 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
}
/**
* Get a sample from the output of the oversample and average engine for this
* channel. The sample is 12-bit + the bits configured in SetOversampleBits().
* The value configured in setAverageBits() will cause this value to be
* averaged 2^bits number of samples. This is not a sliding window. The sample
* will not change until 2^(OversampleBits + AverageBits) samples have been
* acquired from this channel. Use getAverageVoltage() to get the analog value
* in calibrated units.
* Get a sample from the output of the oversample and average engine for this channel. The sample
* is 12-bit + the bits configured in SetOversampleBits(). The value configured in
* setAverageBits() will cause this value to be averaged 2^bits number of samples. This is not a
* sliding window. The sample will not change until 2^(OversampleBits + AverageBits) samples have
* been acquired from this channel. Use getAverageVoltage() to get the analog value in calibrated
* units.
*
* @return A sample from the oversample and average engine for this channel.
*/
@@ -113,9 +103,8 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
}
/**
* Get a scaled sample straight from this channel. The value is scaled to
* units of Volts using the calibrated scaling data from getLSBWeight() and
* getOffset().
* Get a scaled sample straight from this channel. The value is scaled to units of Volts using the
* calibrated scaling data from getLSBWeight() and getOffset().
*
* @return A scaled sample straight from this channel.
*/
@@ -124,26 +113,23 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
}
/**
* Get a scaled sample from the output of the oversample and average engine
* for this channel. The value is scaled to units of Volts using the
* calibrated scaling data from getLSBWeight() and getOffset(). Using
* oversampling will cause this value to be higher resolution, but it will
* update more slowly. Using averaging will cause this value to be more
* stable, but it will update more slowly.
* Get a scaled sample from the output of the oversample and average engine for this channel. The
* value is scaled to units of Volts using the calibrated scaling data from getLSBWeight() and
* getOffset(). Using oversampling will cause this value to be higher resolution, but it will
* update more slowly. Using averaging will cause this value to be more stable, but it will update
* more slowly.
*
* @return A scaled sample from the output of the oversample and average
* engine for this channel.
* @return A scaled sample from the output of the oversample and average engine for this channel.
*/
public double getAverageVoltage() {
return AnalogJNI.getAnalogAverageVoltage(m_port);
}
/**
* Get the factory scaling least significant bit weight constant. The least
* significant bit weight constant for the channel that was calibrated in
* manufacturing and stored in an eeprom.
* Get the factory scaling least significant bit weight constant. The least significant bit weight
* constant for the channel that was calibrated in manufacturing and stored in an eeprom.
*
* Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
* <p>Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
*
* @return Least significant bit weight.
*/
@@ -152,10 +138,10 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
}
/**
* Get the factory scaling offset constant. The offset constant for the
* channel that was calibrated in manufacturing and stored in an eeprom.
* Get the factory scaling offset constant. The offset constant for the channel that was
* calibrated in manufacturing and stored in an eeprom.
*
* Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
* <p>Volts = ((LSB_Weight * 1e-9) * raw) - (Offset * 1e-9)
*
* @return Offset constant.
*/
@@ -173,9 +159,8 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
}
/**
* Set the number of averaging bits. This sets the number of averaging bits.
* The actual number of averaged samples is 2^bits. The averaging is done
* automatically in the FPGA.
* Set the number of averaging bits. This sets the number of averaging bits. The actual number of
* averaged samples is 2^bits. The averaging is done automatically in the FPGA.
*
* @param bits The number of averaging bits.
*/
@@ -184,9 +169,8 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
}
/**
* Get the number of averaging bits. This gets the number of averaging bits
* from the FPGA. The actual number of averaged samples is 2^bits. The
* averaging is done automatically in the FPGA.
* Get the number of averaging bits. This gets the number of averaging bits from the FPGA. The
* actual number of averaged samples is 2^bits. The averaging is done automatically in the FPGA.
*
* @return The number of averaging bits.
*/
@@ -195,9 +179,8 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
}
/**
* Set the number of oversample bits. This sets the number of oversample bits.
* The actual number of oversampled values is 2^bits. The oversampling is done
* automatically in the FPGA.
* Set the number of oversample bits. This sets the number of oversample bits. The actual number
* of oversampled values is 2^bits. The oversampling is done automatically in the FPGA.
*
* @param bits The number of oversample bits.
*/
@@ -206,9 +189,9 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
}
/**
* Get the number of oversample bits. This gets the number of oversample bits
* from the FPGA. The actual number of oversampled values is 2^bits. The
* oversampling is done automatically in the FPGA.
* Get the number of oversample bits. This gets the number of oversample bits from the FPGA. The
* actual number of oversampled values is 2^bits. The oversampling is done automatically in the
* FPGA.
*
* @return The number of oversample bits.
*/
@@ -231,10 +214,9 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
/**
* Set an initial value for the accumulator.
*
* This will be added to all values returned to the user.
* <p>This will be added to all values returned to the user.
*
* @param initialValue The value that the accumulator should start from when
* reset.
* @param initialValue The value that the accumulator should start from when reset.
*/
public void setAccumulatorInitialValue(long initialValue) {
m_accumulatorOffset = initialValue;
@@ -258,13 +240,13 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
/**
* Set the center value of the accumulator.
*
* The center value is subtracted from each A/D value before it is added to
* the accumulator. 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 A/D value before it is added to the accumulator.
* This is used for the center value of devices like gyros and accelerometers to take the device
* offset into account when integrating.
*
* This center value is based on the output of the oversampled and averaged
* source the accumulator channel. Because of this, any non-zero oversample
* bits will affect the size of the value for this field.
* <p>This center value is based on the output of the oversampled and averaged source the
* accumulator channel. Because of this, any non-zero oversample bits will affect the size of the
* value for this field.
*/
public void setAccumulatorCenter(int center) {
AnalogJNI.setAccumulatorCenter(m_port, center);
@@ -272,7 +254,7 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
/**
* Set the accumulator's deadband.
*$
*
* @param deadband The deadband size in ADC codes (12-bit value)
*/
public void setAccumulatorDeadband(int deadband) {
@@ -282,8 +264,8 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
/**
* Read the accumulated value.
*
* Read the value that has been accumulating. The accumulator is attached
* after the oversample and average engine.
* <p>Read the value that has been accumulating. The accumulator is attached after the oversample
* and average engine.
*
* @return The 64-bit value accumulated since the last Reset().
*/
@@ -294,8 +276,7 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
/**
* Read the number of accumulated values.
*
* Read the count of the accumulated values since the accumulator was last
* Reset().
* <p>Read the count of the accumulated values since the accumulator was last Reset().
*
* @return The number of times samples from the channel were accumulated.
*/
@@ -306,8 +287,8 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
/**
* Read the accumulated value and the number of accumulated values atomically.
*
* This function reads the value and count from the FPGA atomically. This can
* be used for averaging.
* <p>This function reads the value and count from the FPGA atomically. This can be used for
* averaging.
*
* @param result AccumulatorResult object to store the results in.
*/
@@ -316,7 +297,8 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
throw new IllegalArgumentException("Null parameter `result'");
}
if (!isAccumulatorChannel()) {
throw new IllegalArgumentException("Channel " + m_channel + " is not an accumulator channel.");
throw new IllegalArgumentException(
"Channel " + m_channel + " is not an accumulator channel.");
}
ByteBuffer value = ByteBuffer.allocateDirect(8);
// set the byte order
@@ -346,10 +328,9 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
/**
* Set the sample rate per channel.
*
* This is a global setting for all channels. The maximum rate is 500kS/s
* divided by the number of channels in use. This is 62500 samples/s per
* channel if all 8 channels are used.
*$
* <p>This is a global setting for all channels. The maximum rate is 500kS/s divided by the number
* of channels in use. This is 62500 samples/s per channel if all 8 channels are used.
*
* @param samplesPerSecond The number of samples per second.
*/
public static void setGlobalSampleRate(final double samplesPerSecond) {
@@ -359,8 +340,7 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
/**
* Get the current sample rate.
*
* This assumes one entry in the scan list. This is a global setting for all
* channels.
* <p>This assumes one entry in the scan list. This is a global setting for all channels.
*
* @return Sample rate.
*/
@@ -368,25 +348,22 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
return AnalogJNI.getAnalogSampleRate();
}
/**
* {@inheritDoc}
*/
@Override
public void setPIDSourceType(PIDSourceType pidSource) {
m_pidSource = pidSource;
}
/**
* {@inheritDoc}
*/
@Override
public PIDSourceType getPIDSourceType() {
return m_pidSource;
}
/**
* Get the average voltage for use with PIDController
* Get the average voltage for use with PIDController.
*
* @return the average voltage
*/
@Override
public double pidGet() {
return getAverageVoltage();
}
@@ -394,45 +371,42 @@ public class AnalogInput extends SensorBase implements PIDSource, LiveWindowSend
/**
* Live Window code, only does anything if live window is activated.
*/
@Override
public String getSmartDashboardType() {
return "Analog Input";
}
private ITable m_table;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("Value", getAverageVoltage());
}
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* Analog Channels don't have to do anything special when entering the
* LiveWindow. {@inheritDoc}
* Analog Channels don't have to do anything special when entering the LiveWindow. {@inheritDoc}
*/
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
/**
* Analog Channels don't have to do anything special when exiting the
* LiveWindow. {@inheritDoc}
* Analog Channels don't have to do anything special when exiting the LiveWindow. {@inheritDoc}
*/
public void stopLiveWindowMode() {}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -38,12 +38,12 @@ public class AnalogOutput extends SensorBase implements LiveWindowSendable {
}
try {
channels.allocate(channel);
} catch (CheckedAllocationException e) {
} catch (CheckedAllocationException ex) {
throw new AllocationException("Analog output channel " + m_channel + " is already allocated");
}
long port_pointer = AnalogJNI.getPort((byte) channel);
m_port = AnalogJNI.initializeAnalogOutputPort(port_pointer);
final long portPointer = AnalogJNI.getPort((byte) channel);
m_port = AnalogJNI.initializeAnalogOutputPort(portPointer);
LiveWindow.addSensor("AnalogOutput", channel, this);
UsageReporting.report(tResourceType.kResourceType_AnalogOutput, channel);
@@ -70,45 +70,42 @@ public class AnalogOutput extends SensorBase implements LiveWindowSendable {
/*
* Live Window code, only does anything if live window is activated.
*/
@Override
public String getSmartDashboardType() {
return "Analog Output";
}
private ITable m_table;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("Value", getVoltage());
}
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* Analog Channels don't have to do anything special when entering the
* LiveWindow. {@inheritDoc}
* Analog Channels don't have to do anything special when entering the LiveWindow. {@inheritDoc}
*/
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
/**
* Analog Channels don't have to do anything special when exiting the
* LiveWindow. {@inheritDoc}
* Analog Channels don't have to do anything special when exiting the LiveWindow. {@inheritDoc}
*/
public void stopLiveWindowMode() {}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -7,104 +7,85 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import edu.wpi.first.wpilibj.hal.HALUtil;
import edu.wpi.first.wpilibj.hal.PowerJNI;
import edu.wpi.first.wpilibj.interfaces.Potentiometer;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
/**
* Class for reading analog potentiometers. Analog potentiometers read in an
* analog voltage that corresponds to a position. The position is in whichever
* units you choose, by way of the scaling and offset constants passed to the
* constructor.
* Class for reading analog potentiometers. Analog potentiometers read in an analog voltage that
* corresponds to a position. The position is in whichever units you choose, by way of the scaling
* and offset constants passed to the constructor.
*
* @author Alex Henning
* @author Colby Skeggs (rail voltage)
*/
public class AnalogPotentiometer implements Potentiometer, LiveWindowSendable {
private double m_fullRange, m_offset;
private AnalogInput m_analog_input;
private boolean m_init_analog_input;
private double m_fullRange;
private double m_offset;
private AnalogInput m_analogInput;
private boolean m_initAnalogInput;
protected PIDSourceType m_pidSource = PIDSourceType.kDisplacement;
/**
* Common initialization code called by all constructors.
*$
* @param input The {@link AnalogInput} this potentiometer is plugged into.
* @param fullRange The scaling to multiply the voltage by to get a meaningful
* unit.
* @param offset The offset to add to the scaled value for controlling the
* zero value
*
* @param input The {@link AnalogInput} this potentiometer is plugged into.
* @param fullRange The scaling to multiply the voltage by to get a meaningful unit.
* @param offset The offset to add to the scaled value for controlling the zero value
*/
private void initPot(final AnalogInput input, double fullRange, double offset) {
this.m_fullRange = fullRange;
this.m_offset = offset;
m_analog_input = input;
m_fullRange = fullRange;
m_offset = offset;
m_analogInput = input;
}
/**
* AnalogPotentiometer constructor.
*
* 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.
* <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.
*
* @param channel The analog channel this potentiometer is plugged into.
* @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 channel The analog channel this potentiometer is plugged into.
* @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
*/
public AnalogPotentiometer(final int channel, double fullRange, double offset) {
AnalogInput input = new AnalogInput(channel);
m_init_analog_input = true;
m_initAnalogInput = true;
initPot(input, fullRange, offset);
}
/**
* AnalogPotentiometer constructor.
*
* 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.
* <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.
*
* @param input The {@link AnalogInput} this potentiometer is plugged into.
* @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 input The {@link AnalogInput} this potentiometer is plugged into.
* @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
*/
public AnalogPotentiometer(final AnalogInput input, double fullRange, double offset) {
m_init_analog_input = false;
m_initAnalogInput = false;
initPot(input, fullRange, offset);
}
/**
* AnalogPotentiometer constructor.
*
* 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.
* <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.
*
* @param channel The analog channel this potentiometer is plugged into.
* @param scale The scaling to multiply the voltage by to get a meaningful
* unit.
* @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);
@@ -113,15 +94,13 @@ public class AnalogPotentiometer implements Potentiometer, LiveWindowSendable {
/**
* AnalogPotentiometer constructor.
*
* 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.
* <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.
*
* @param input The {@link AnalogInput} this potentiometer is plugged into.
* @param scale The scaling to multiply the voltage by to get a meaningful
* unit.
* @param scale The scaling to multiply the voltage by to get a meaningful unit.
*/
public AnalogPotentiometer(final AnalogInput input, double scale) {
this(input, scale, 0);
@@ -150,13 +129,12 @@ public class AnalogPotentiometer implements Potentiometer, LiveWindowSendable {
*
* @return The current position of the potentiometer.
*/
@Override
public double get() {
return (m_analog_input.getVoltage() / ControllerPower.getVoltage5V()) * m_fullRange + m_offset;
return (m_analogInput.getVoltage() / ControllerPower.getVoltage5V()) * m_fullRange + m_offset;
}
/**
* {@inheritDoc}
*/
@Override
public void setPIDSourceType(PIDSourceType pidSource) {
if (!pidSource.equals(PIDSourceType.kDisplacement)) {
throw new IllegalArgumentException("Only displacement PID is allowed for potentiometers.");
@@ -164,9 +142,7 @@ public class AnalogPotentiometer implements Potentiometer, LiveWindowSendable {
m_pidSource = pidSource;
}
/**
* {@inheritDoc}
*/
@Override
public PIDSourceType getPIDSourceType() {
return m_pidSource;
}
@@ -176,6 +152,7 @@ public class AnalogPotentiometer implements Potentiometer, LiveWindowSendable {
*
* @return The current reading.
*/
@Override
public double pidGet() {
return get();
}
@@ -184,53 +161,53 @@ public class AnalogPotentiometer implements Potentiometer, LiveWindowSendable {
/**
* Live Window code, only does anything if live window is activated.
*/
@Override
public String getSmartDashboardType() {
return "Analog Input";
}
private ITable m_table;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("Value", get());
}
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* Frees this resource.
*/
public void free() {
if (m_init_analog_input) {
m_analog_input.free();
m_analog_input = null;
m_init_analog_input = false;
if (m_initAnalogInput) {
m_analogInput.free();
m_analogInput = null;
m_initAnalogInput = false;
}
}
/**
* Analog Channels don't have to do anything special when entering the
* LiveWindow. {@inheritDoc}
* Analog Channels don't have to do anything special when entering the LiveWindow. {@inheritDoc}
*/
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
/**
* Analog Channels don't have to do anything special when exiting the
* LiveWindow. {@inheritDoc}
* Analog Channels don't have to do anything special when exiting the LiveWindow. {@inheritDoc}
*/
public void stopLiveWindowMode() {}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -7,32 +7,31 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.wpilibj.AnalogTriggerOutput.AnalogTriggerType;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.hal.AnalogJNI;
import edu.wpi.first.wpilibj.util.BoundaryException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.IntBuffer;
// import com.sun.jna.Pointer;
/**
* Class for creating and configuring Analog Triggers
* Class for creating and configuring Analog Triggers.
*
* @author dtjones
*/
public class AnalogTrigger {
/**
* Exceptions dealing with improper operation of the Analog trigger
* Exceptions dealing with improper operation of the Analog trigger.
*/
public class AnalogTriggerException extends RuntimeException {
/**
* Create a new exception with the given message
* Create a new exception with the given message.
*
* @param message the message to pass with the exception
*/
@@ -43,7 +42,7 @@ public class AnalogTrigger {
}
/**
* Where the analog trigger is attached
* Where the analog trigger is attached.
*/
protected long m_port;
protected int m_index;
@@ -54,12 +53,12 @@ public class AnalogTrigger {
* @param channel the port to use for the analog trigger
*/
protected void initTrigger(final int channel) {
long port_pointer = AnalogJNI.getPort((byte) channel);
final long portPointer = AnalogJNI.getPort((byte) channel);
ByteBuffer index = ByteBuffer.allocateDirect(4);
index.order(ByteOrder.LITTLE_ENDIAN);
m_port =
AnalogJNI.initializeAnalogTrigger(port_pointer, index.asIntBuffer());
AnalogJNI.initializeAnalogTrigger(portPointer, index.asIntBuffer());
m_index = index.asIntBuffer().get(0);
UsageReporting.report(tResourceType.kResourceType_AnalogTrigger, channel);
@@ -68,17 +67,16 @@ public class AnalogTrigger {
/**
* Constructor for an analog trigger given a channel number.
*
* @param channel the port to use for the analog trigger 0-3 are on-board, 4-7
* are on the MXP port
* @param channel the port to use for the analog trigger 0-3 are on-board, 4-7 are on the MXP
* port
*/
public AnalogTrigger(final int channel) {
initTrigger(channel);
}
/**
* Construct an analog trigger given an analog channel. This should be used in
* the case of sharing an analog channel between the trigger and an analog
* input object.
* Construct an analog trigger given an analog channel. This should be used in the case of sharing
* an analog channel between the trigger and an analog input object.
*
* @param channel the AnalogInput to use for the analog trigger
*/
@@ -90,7 +88,7 @@ public class AnalogTrigger {
}
/**
* Release the resources used by this object
* Release the resources used by this object.
*/
public void free() {
AnalogJNI.cleanAnalogTrigger(m_port);
@@ -98,9 +96,8 @@ public class AnalogTrigger {
}
/**
* Set the upper and lower limits of the analog trigger. The limits are given
* in ADC codes. If oversampling is used, the units must be scaled
* appropriately.
* Set the upper and lower limits of the analog trigger. The limits are given in ADC codes. If
* oversampling is used, the units must be scaled appropriately.
*
* @param lower the lower raw limit
* @param upper the upper raw limit
@@ -113,8 +110,8 @@ public class AnalogTrigger {
}
/**
* Set the upper and lower limits of the analog trigger. The limits are given
* as floating point voltage values.
* Set the upper and lower limits of the analog trigger. The limits are given as floating point
* voltage values.
*
* @param lower the lower voltage limit
* @param upper the upper voltage limit
@@ -127,9 +124,8 @@ public class AnalogTrigger {
}
/**
* Configure the analog trigger to use the averaged vs. raw values. If the
* value is true, then the averaged value is selected for the analog trigger,
* otherwise the immediate value is used.
* Configure the analog trigger to use the averaged vs. raw values. If the value is true, then the
* averaged value is selected for the analog trigger, otherwise the immediate value is used.
*
* @param useAveragedValue true to use an averaged value, false otherwise
*/
@@ -138,10 +134,9 @@ public class AnalogTrigger {
}
/**
* Configure the analog trigger to use a filtered value. The analog trigger
* will operate with a 3 point average rejection filter. This is designed to
* help with 360 degree pot applications for the period where the pot crosses
* through zero.
* Configure the analog trigger to use a filtered value. The analog trigger will operate with a 3
* point average rejection filter. This is designed to help with 360 degree pot applications for
* the period where the pot crosses through zero.
*
* @param useFilteredValue true to use a filterd value, false otherwise
*/
@@ -150,8 +145,8 @@ public class AnalogTrigger {
}
/**
* 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.
*/
@@ -160,8 +155,8 @@ public class AnalogTrigger {
}
/**
* Return the InWindow output of the analog trigger. True if the analog input
* is between the upper and lower limits.
* Return the InWindow output of the analog trigger. True if the analog input is between the upper
* and lower limits.
*
* @return The InWindow output of the analog trigger.
*/
@@ -170,9 +165,8 @@ public class AnalogTrigger {
}
/**
* Return the TriggerState output of the analog trigger. True if above upper
* limit. False if below lower limit. If in Hysteresis, maintain previous
* state.
* Return the TriggerState output of the analog trigger. True if above upper limit. False if below
* lower limit. If in Hysteresis, maintain previous state.
*
* @return The TriggerState output of the analog trigger.
*/
@@ -181,9 +175,8 @@ public class AnalogTrigger {
}
/**
* Creates an AnalogTriggerOutput object. Gets an output object that can be
* used for routing. Caller is responsible for deleting the
* AnalogTriggerOutput object.
* Creates an AnalogTriggerOutput object. Gets an output object that can be used for routing.
* Caller is responsible for deleting the AnalogTriggerOutput object.
*
* @param type An enum of the type of output object to create.
* @return A pointer to a new AnalogTriggerOutput object.

View File

@@ -11,47 +11,41 @@ import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tReso
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.hal.AnalogJNI;
import java.nio.IntBuffer;
/**
* 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 subsystems on the FPGA such as Counter,
* Encoder, and Interrupt.
* 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
* subsystems on the FPGA such as Counter, Encoder, and Interrupt.
*
* The TriggerState output indicates the primary output value of the trigger. If
* the analog signal is less than the lower limit, the output is false. If the
* analog value is greater than the upper limit, then the output is true. If the
* analog value is in between, then the trigger output state maintains its most
* recent value.
* <p>The TriggerState output indicates the primary output value of the trigger. If the analog
* signal is less than the lower limit, the output is false. If the analog value is greater than the
* upper limit, then the output is true. If the analog value is in between, then the trigger output
* state maintains its most recent value.
*
* The InWindow output indicates whether or not the analog signal is inside the
* range defined by the limits.
* <p>The InWindow output indicates whether or not the analog signal is inside the range defined by
* the limits.
*
* The RisingPulse and FallingPulse outputs detect an instantaneous transition
* from above the upper limit to below the lower limit, and vise versa. These
* pulses represent a rollover condition of a sensor and can be routed to an up
* / down couter or to interrupts. Because the outputs generate a pulse, they
* cannot be read directly. To help ensure that a rollover condition is not
* missed, there is an average rejection filter available that operates on the
* upper 8 bits of a 12 bit number and selects the nearest outlyer of 3 samples.
* This will reject a sample that is (due to averaging or sampling) errantly
* between the two limits. This filter will fail if more than one sample in a
* row is errantly in between the two limits. You may see this problem if
* attempting to use this feature with a mechanical rollover sensor, such as a
* 360 degree no-stop potentiometer without signal conditioning, because the
* rollover transition is not sharp / clean enough. Using the averaging engine
* may help with this, but rotational speeds of the sensor will then be limited.
* <p>The RisingPulse and FallingPulse outputs detect an instantaneous transition from above the
* upper limit to below the lower limit, and vise versa. These pulses represent a rollover condition
* of a sensor and can be routed to an up / down couter or to interrupts. Because the outputs
* generate a pulse, they cannot be read directly. To help ensure that a rollover condition is not
* missed, there is an average rejection filter available that operates on the upper 8 bits of a 12
* bit number and selects the nearest outlyer of 3 samples. This will reject a sample that is (due
* to averaging or sampling) errantly between the two limits. This filter will fail if more than one
* sample in a row is errantly in between the two limits. You may see this problem if attempting to
* use this feature with a mechanical rollover sensor, such as a 360 degree no-stop potentiometer
* without signal conditioning, because the rollover transition is not sharp / clean enough. Using
* the averaging engine may help with this, but rotational speeds of the sensor will then be
* limited.
*/
public class AnalogTriggerOutput extends DigitalSource {
/**
* Exceptions dealing with improper operation of the Analog trigger output
* Exceptions dealing with improper operation of the Analog trigger output.
*/
public class AnalogTriggerOutputException extends RuntimeException {
/**
* Create a new exception with the given message
* Create a new exception with the given message.
*
* @param message the message to pass with the exception
*/
@@ -65,26 +59,26 @@ public class AnalogTriggerOutput extends DigitalSource {
private final AnalogTriggerType m_outputType;
/**
* Create an object that represents one of the four outputs from an analog
* trigger.
* Create an object that represents one of the four outputs from an analog trigger.
*
* Because this class derives from DigitalSource, it can be passed into
* routing functions for Counter, Encoder, etc.
* <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 outputType An enum that specifies the output on the trigger to
* represent.
* @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) {
if (trigger == null)
if (trigger == null) {
throw new NullPointerException("Analog Trigger given was null");
if (outputType == null)
}
if (outputType == null) {
throw new NullPointerException("Analog Trigger Type given was null");
}
m_trigger = trigger;
m_outputType = outputType;
UsageReporting.report(tResourceType.kResourceType_AnalogTriggerOutput, trigger.getIndex(),
outputType.value);
outputType.m_value);
}
@Override
@@ -98,12 +92,12 @@ public class AnalogTriggerOutput extends DigitalSource {
* @return The state of the analog trigger output.
*/
public boolean get() {
return AnalogJNI.getAnalogTriggerOutput(m_trigger.m_port, m_outputType.value);
return AnalogJNI.getAnalogTriggerOutput(m_trigger.m_port, m_outputType.m_value);
}
@Override
public int getChannelForRouting() {
return (m_trigger.m_index << 2) + m_outputType.value;
return (m_trigger.m_index << 2) + m_outputType.m_value;
}
@Override
@@ -117,19 +111,19 @@ public class AnalogTriggerOutput extends DigitalSource {
}
/**
* Defines the state in which the AnalogTrigger triggers
*$
* Defines the state in which the AnalogTrigger triggers.
*
* @author jonathanleitschuh
*/
public enum AnalogTriggerType {
kInWindow(AnalogJNI.AnalogTriggerType.kInWindow), kState(AnalogJNI.AnalogTriggerType.kState), kRisingPulse(
AnalogJNI.AnalogTriggerType.kRisingPulse), kFallingPulse(
AnalogJNI.AnalogTriggerType.kFallingPulse);
kInWindow(AnalogJNI.AnalogTriggerType.kInWindow), kState(AnalogJNI.AnalogTriggerType.kState),
kRisingPulse(AnalogJNI.AnalogTriggerType.kRisingPulse),
kFallingPulse(AnalogJNI.AnalogTriggerType.kFallingPulse);
private final int value;
private final int m_value;
private AnalogTriggerType(int value) {
this.value = value;
AnalogTriggerType(int value) {
m_value = value;
}
}
}

View File

@@ -7,10 +7,10 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
import edu.wpi.first.wpilibj.hal.AccelerometerJNI;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.hal.AccelerometerJNI;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
@@ -18,12 +18,12 @@ import edu.wpi.first.wpilibj.tables.ITable;
/**
* Built-in accelerometer.
*
* This class allows access to the RoboRIO's internal accelerometer.
* <p>This class allows access to the RoboRIO's internal accelerometer.
*/
public class BuiltInAccelerometer implements Accelerometer, LiveWindowSendable {
/**
* Constructor.
*$
*
* @param range The range the accelerometer will measure
*/
public BuiltInAccelerometer(Range range) {
@@ -40,7 +40,6 @@ public class BuiltInAccelerometer implements Accelerometer, LiveWindowSendable {
this(Range.k8G);
}
/** {inheritdoc} */
@Override
public void setRange(Range range) {
AccelerometerJNI.setAccelerometerActive(false);
@@ -56,13 +55,17 @@ public class BuiltInAccelerometer implements Accelerometer, LiveWindowSendable {
AccelerometerJNI.setAccelerometerRange(2);
break;
case k16G:
throw new RuntimeException("16G range not supported (use k2G, k4G, or k8G)");
default:
throw new IllegalArgumentException(range + " range not supported (use k2G, k4G, or k8G)");
}
AccelerometerJNI.setAccelerometerActive(true);
}
/**
* The acceleration in the X axis.
*
* @return The acceleration of the RoboRIO along the X axis in g-forces
*/
@Override
@@ -71,6 +74,8 @@ public class BuiltInAccelerometer implements Accelerometer, LiveWindowSendable {
}
/**
* The acceleration in the Y axis.
*
* @return The acceleration of the RoboRIO along the Y axis in g-forces
*/
@Override
@@ -79,6 +84,8 @@ public class BuiltInAccelerometer implements Accelerometer, LiveWindowSendable {
}
/**
* The acceleration in the Z axis.
*
* @return The acceleration of the RoboRIO along the Z axis in g-forces
*/
@Override
@@ -86,19 +93,20 @@ public class BuiltInAccelerometer implements Accelerometer, LiveWindowSendable {
return AccelerometerJNI.getAccelerometerZ();
}
@Override
public String getSmartDashboardType() {
return "3AxisAccelerometer";
}
private ITable m_table;
/** {@inheritDoc} */
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/** {@inheritDoc} */
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("X", getX());
@@ -107,12 +115,16 @@ public class BuiltInAccelerometer implements Accelerometer, LiveWindowSendable {
}
}
/** {@inheritDoc} */
@Override
public ITable getTable() {
return m_table;
}
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
public void stopLiveWindowMode() {}
};
@Override
public void stopLiveWindowMode() {
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -13,28 +13,27 @@ import edu.wpi.first.wpilibj.tables.ITableListener;
public interface CANSpeedController extends SpeedController, PIDInterface, LiveWindowSendable {
/**
* Mode determines how the motor is controlled, used internally. This is meant
* to be subclassed by enums
* (see {@link CANTalon.TalonControlMode CANTalon.TalonControlMode}).
* Mode determines how the motor is controlled, used internally. This is meant to be subclassed by
* enums (see {@link CANTalon.TalonControlMode CANTalon.TalonControlMode}).
*
*
* Note that the Jaguar does not support follower mode.
* <p>Note that the Jaguar does not support follower mode.
*/
public interface ControlMode {
/**
* Gets the name of this control mode. Since this interface should only be
* subclassed by enumerations, this will be overridden by the builtin
* name() method.
*/
public String name();
/**
* Checks if this control mode is PID-compatible.
*/
public boolean isPID();
/**
* Gets the integer value of this control mode.
*/
public int getValue();
interface ControlMode {
/**
* Gets the name of this control mode. Since this interface should only be subclassed by
* enumerations, this will be overridden by the builtin name() method.
*/
String name();
/**
* Checks if this control mode is PID-compatible.
*/
boolean isPID();
/**
* Gets the integer value of this control mode.
*/
int getValue();
}
/**
@@ -42,42 +41,46 @@ public interface CANSpeedController extends SpeedController, PIDInterface, LiveW
*
* @return the current control mode
*/
public ControlMode getControlMode();
ControlMode getControlMode();
/**
* Sets the control mode of this speed controller.
*
* @param mode the the new mode
*/
public void setControlMode(int mode);
void setControlMode(int mode);
/**
* Set the proportional PID constant.
*/
public void setP(double p);
@SuppressWarnings("ParameterName")
void setP(double p);
/**
* Set the integral PID constant.
*/
public void setI(double i);
@SuppressWarnings("ParameterName")
void setI(double i);
/**
* Set the derivative PID constant.
*/
public void setD(double d);
@SuppressWarnings("ParameterName")
void setD(double d);
/**
* Set the feed-forward PID constant. This method is optional to implement.
*/
public default void setF(double f) {
@SuppressWarnings("ParameterName")
default void setF(double f) {
}
/**
* Gets the feed-forward PID constant. This method is optional to implement.
* If a subclass does not implement this, it will always return zero.
* Gets the feed-forward PID constant. This method is optional to implement. If a subclass does
* not implement this, it will always return zero.
*/
public default double getF() {
return 0.0;
default double getF() {
return 0.0;
}
/**
@@ -85,55 +88,53 @@ public interface CANSpeedController extends SpeedController, PIDInterface, LiveW
*
* @return the input voltage to the controller (in Volts).
*/
public double getBusVoltage();
double getBusVoltage();
/**
* Get the current output voltage.
*
* @return the output voltage to the motor in volts.
*/
public double getOutputVoltage();
double getOutputVoltage();
/**
* Get the current being applied to the motor.
*
* @return the current motor current (in Amperes).
*/
public double getOutputCurrent();
double getOutputCurrent();
/**
* Get the current temperature of the controller.
*
* @return the current temperature of the controller, in degrees Celsius.
*/
public double getTemperature();
double getTemperature();
/**
* Return the current position of whatever the current selected sensor is.
*
* See specific implementations for more information on selecting feedback
* sensors.
* <p>See specific implementations for more information on selecting feedback sensors.
*
* @return the current sensor position.
*/
public double getPosition();
double getPosition();
/**
* Return the current velocity of whatever the current selected sensor is.
*
* See specific implementations for more information on selecting feedback
* sensors.
* <p>See specific implementations for more information on selecting feedback sensors.
*
* @return the current sensor velocity.
*/
public double getSpeed();
double getSpeed();
/**
* Set the maximum rate of change of the output voltage.
*
* @param rampRate the maximum rate of change of the votlage, in Volts / sec.
*/
public void setVoltageRampRate(double rampRate);
void setVoltageRampRate(double rampRate);
/**
* All CAN Speed Controllers have the same SmartDashboard type: "CANSpeedController".
@@ -141,56 +142,71 @@ public interface CANSpeedController extends SpeedController, PIDInterface, LiveW
String SMART_DASHBOARD_TYPE = "CANSpeedController";
@Override
public default void updateTable() {
ITable table = getTable();
if(table != null) {
table.putString("~TYPE~", SMART_DASHBOARD_TYPE);
table.putString("Type", getClass().getSimpleName()); // "CANTalon", "CANJaguar"
table.putNumber("Mode", getControlMode().getValue());
if (getControlMode().isPID()) {
// CANJaguar throws an exception if you try to get its PID constants
// when it's not in a PID-compatible mode
table.putNumber("p", getP());
table.putNumber("i", getI());
table.putNumber("d", getD());
table.putNumber("f", getF());
}
table.putBoolean("Enabled", isEnabled());
table.putNumber("Value", get());
default void updateTable() {
ITable table = getTable();
if (table != null) {
table.putString("~TYPE~", SMART_DASHBOARD_TYPE);
table.putString("Type", getClass().getSimpleName()); // "CANTalon", "CANJaguar"
table.putNumber("Mode", getControlMode().getValue());
if (getControlMode().isPID()) {
// CANJaguar throws an exception if you try to get its PID constants
// when it's not in a PID-compatible mode
table.putNumber("p", getP());
table.putNumber("i", getI());
table.putNumber("d", getD());
table.putNumber("f", getF());
}
table.putBoolean("Enabled", isEnabled());
table.putNumber("Value", get());
}
}
@Override
public default String getSmartDashboardType() {
return SMART_DASHBOARD_TYPE;
default String getSmartDashboardType() {
return SMART_DASHBOARD_TYPE;
}
/**
* Creates an ITableListener for the LiveWindow table for this CAN speed
* controller.
* Creates an ITableListener for the LiveWindow table for this CAN speed controller.
*/
public default ITableListener createTableListener() {
return (table, key, value, isNew) -> {
switch(key) {
case "Enabled":
if ((Boolean) value) {
enable();
} else {
disable();
}
break;
case "Value": set((Double) value); break;
case "Mode": setControlMode(((Double) value).intValue()); break;
default ITableListener createTableListener() {
return (table, key, value, isNew) -> {
switch (key) {
case "Enabled":
if ((Boolean) value) {
enable();
} else {
disable();
}
if(getControlMode().isPID()) {
switch(key) {
case "p": setP((Double) value); break;
case "i": setI((Double) value); break;
case "d": setD((Double) value); break;
case "f": setF((Double) value); break;
}
}
};
break;
case "Value":
set((Double) value);
break;
case "Mode":
setControlMode(((Double) value).intValue());
break;
default:
break;
}
if (getControlMode().isPID()) {
switch (key) {
case "p":
setP((Double) value);
break;
case "i":
setI((Double) value);
break;
case "d":
setD((Double) value);
break;
case "f":
setF((Double) value);
break;
default:
break;
}
}
};
}

File diff suppressed because it is too large Load Diff

View File

@@ -7,29 +7,21 @@
package edu.wpi.first.wpilibj;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.concurrent.atomic.AtomicBoolean;
import com.ni.vision.NIVision;
import com.ni.vision.NIVision.Image;
import com.ni.vision.NIVision.RawData;
import com.ni.vision.VisionException;
import edu.wpi.first.wpilibj.DriverStation;
import edu.wpi.first.wpilibj.Timer;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.util.ArrayDeque;
import java.util.Deque;
import edu.wpi.first.wpilibj.vision.USBCamera;
// replicates CameraServer.cpp in java lib
@@ -46,6 +38,7 @@ public class CameraServer {
private static final int kMaxImageSize = 200000;
private static CameraServer server;
@SuppressWarnings("JavadocMethod")
public static CameraServer getInstance() {
if (server == null) {
server = new CameraServer();
@@ -53,7 +46,6 @@ public class CameraServer {
return server;
}
private Thread serverThread;
private int m_quality;
private boolean m_autoCaptureStarted;
private boolean m_hwClient = true;
@@ -61,16 +53,20 @@ public class CameraServer {
private CameraData m_imageData;
private Deque<ByteBuffer> m_imageDataPool;
private class CameraData {
RawData data;
int start;
@SuppressWarnings("JavadocMethod")
private final class CameraData {
@SuppressWarnings("MemberName")
private final RawData data;
@SuppressWarnings("MemberName")
private final int start;
public CameraData(RawData d, int s) {
data = d;
start = s;
CameraData(RawData data, int start) {
this.data = data;
this.start = start;
}
}
@SuppressWarnings("JavadocMethod")
private CameraServer() {
m_quality = 50;
m_camera = null;
@@ -79,14 +75,14 @@ public class CameraServer {
for (int i = 0; i < 3; i++) {
m_imageDataPool.addLast(ByteBuffer.allocateDirect(kMaxImageSize));
}
serverThread = new Thread(new Runnable() {
final Thread serverThread = new Thread(new Runnable() {
public void run() {
try {
serve();
} catch (IOException e) {
// do stuff here
} catch (InterruptedException e) {
} catch (IOException ex) {
// do stuff here
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
});
@@ -94,11 +90,13 @@ public class CameraServer {
serverThread.start();
}
@SuppressWarnings("JavadocMethod")
private synchronized void setImageData(RawData data, int start) {
if (m_imageData != null && m_imageData.data != null) {
m_imageData.data.free();
if (m_imageData.data.getBuffer() != null)
if (m_imageData.data.getBuffer() != null) {
m_imageDataPool.addLast(m_imageData.data.getBuffer());
}
m_imageData = null;
}
m_imageData = new CameraData(data, start);
@@ -106,12 +104,11 @@ public class CameraServer {
}
/**
* Manually change the image that is served by the MJPEG stream. This can be
* called to pass custom annotated images to the dashboard. Note that, for
* 640x480 video, this method could take between 40 and 50 milliseconds to
* complete.
* Manually change the image that is served by the MJPEG stream. This can be called to pass custom
* annotated images to the dashboard. Note that, for 640x480 video, this method could take between
* 40 and 50 milliseconds to complete.
*
* This shouldn't be called if {@link #startAutomaticCapture} is called.
* <p>This shouldn't be called if {@link #startAutomaticCapture} is called.
*
* @param image The IMAQ image to show on the dashboard
*/
@@ -134,25 +131,26 @@ public class CameraServer {
int index = 0;
if (hwClient) {
while (index < buffer.limit() - 1) {
if ((buffer.get(index) & 0xff) == 0xFF && (buffer.get(index + 1) & 0xff) == 0xD8)
if ((buffer.get(index) & 0xff) == 0xFF && (buffer.get(index + 1) & 0xff) == 0xD8) {
break;
}
index++;
}
}
if (buffer.limit() - index - 1 <= 2) {
throw new VisionException("data size of flattened image is less than 2. Try another camera! ");
throw new VisionException("data size of flattened image is less than 2. Try another "
+ "camera!");
}
setImageData(data, index);
}
/**
* Start automatically capturing images to send to the dashboard. You should
* call this method to just see a camera feed on the dashboard without doing
* any vision processing on the roboRIO. {@link #setImage} shouldn't be called
* after this is called. This overload calles
* {@link #startAutomaticCapture(String)} with the default camera name
* Start automatically capturing images to send to the dashboard. You should call this method to
* just see a camera feed on the dashboard without doing any vision processing on the roboRIO.
* {@link #setImage} shouldn't be called after this is called. This overload calles {@link
* #startAutomaticCapture(String)} with the default camera name
*/
public void startAutomaticCapture() {
startAutomaticCapture(USBCamera.kDefaultCameraName);
@@ -161,9 +159,8 @@ public class CameraServer {
/**
* Start automatically capturing images to send to the dashboard.
*
* You should call this method to just see a camera feed on the dashboard
* without doing any vision processing on the roboRIO. {@link #setImage}
* shouldn't be called after this is called.
* <p>You should call this method to just see a camera feed on the dashboard without doing any
* vision processing on the roboRIO. {@link #setImage} shouldn't be called after this is called.
*
* @param cameraName The name of the camera interface (e.g. "cam1")
*/
@@ -178,9 +175,11 @@ public class CameraServer {
}
}
@SuppressWarnings("JavadocMethod")
public synchronized void startAutomaticCapture(USBCamera camera) {
if (m_autoCaptureStarted)
if (m_autoCaptureStarted) {
return;
}
m_autoCaptureStarted = true;
m_camera = camera;
@@ -232,25 +231,23 @@ public class CameraServer {
}
/**
* check if auto capture is started
*
* Check if auto capture is started.
*/
public synchronized boolean isAutoCaptureStarted() {
return m_autoCaptureStarted;
}
/**
* Sets the size of the image to use. Use the public kSize constants to set
* the correct mode, or set it directory on a camera and call the appropriate
* autoCapture method
*$
* Sets the size of the image to use. Use the public kSize constants to set the correct mode, or
* set it directory on a camera and call the appropriate autoCapture method.
*
* @param size The size to use
*/
public synchronized void setSize(int size) {
if (m_camera == null)
if (m_camera == null) {
return;
}
switch (size) {
case kSize640x480:
m_camera.setSize(640, 480);
@@ -261,11 +258,13 @@ public class CameraServer {
case kSize160x120:
m_camera.setSize(160, 120);
break;
default:
throw new IllegalArgumentException("Unsupported size: " + size);
}
}
/**
* Set the quality of the compressed image sent to the dashboard
* Set the quality of the compressed image sent to the dashboard.
*
* @param quality The quality of the JPEG image, from 0 to 100
*/
@@ -274,7 +273,7 @@ public class CameraServer {
}
/**
* Get the quality of the compressed image sent to the dashboard
* Get the quality of the compressed image sent to the dashboard.
*
* @return The quality, from 0 to 100
*/
@@ -285,10 +284,10 @@ public class CameraServer {
/**
* Run the M-JPEG server.
*
* This function listens for a connection from the dashboard in a background
* thread, then sends back the M-JPEG stream.
* <p>This function listens for a connection from the dashboard in a background thread, then
* sends back the M-JPEG stream.
*
* @throws IOException if the Socket connection fails
* @throws IOException if the Socket connection fails
* @throws InterruptedException if the sleep is interrupted
*/
protected void serve() throws IOException, InterruptedException {
@@ -300,10 +299,10 @@ public class CameraServer {
while (true) {
try {
Socket s = socket.accept();
Socket socket1 = socket.accept();
DataInputStream is = new DataInputStream(s.getInputStream());
DataOutputStream os = new DataOutputStream(s.getOutputStream());
DataInputStream is = new DataInputStream(socket1.getInputStream());
DataOutputStream os = new DataOutputStream(socket1.getOutputStream());
int fps = is.readInt();
int compression = is.readInt();
@@ -311,35 +310,38 @@ public class CameraServer {
if (compression != kHardwareCompression) {
DriverStation.reportError("Choose \"USB Camera HW\" on the dashboard", false);
s.close();
socket1.close();
continue;
}
// Wait for the camera
synchronized (this) {
System.out.println("Camera not yet ready, awaiting image");
if (m_camera == null)
if (m_camera == null) {
wait();
}
m_hwClient = compression == kHardwareCompression;
if (!m_hwClient)
if (!m_hwClient) {
setQuality(100 - compression);
else if (m_camera != null)
} else if (m_camera != null) {
m_camera.setFPS(fps);
}
setSize(size);
}
long period = (long) (1000 / (1.0 * fps));
while (true) {
long t0 = System.currentTimeMillis();
CameraData imageData = null;
final CameraData imageData;
synchronized (this) {
wait();
imageData = m_imageData;
m_imageData = null;
}
if (imageData == null)
if (imageData == null) {
continue;
}
// Set the buffer position to the start of the data,
// and then create a new wrapper for the data at
// exactly that position

View File

@@ -7,41 +7,38 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.SensorBase;
import edu.wpi.first.wpilibj.hal.CompressorJNI;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
/**
* Class for operating the PCM (Pneumatics compressor module) The PCM
* automatically will run in close-loop mode by default whenever a Solenoid
* object is created. For most cases the Compressor object does not need to be
* instantiated or used in a robot program.
*$
* This class is only required in cases where more detailed status or to
* enable/disable closed loop control. Note: you cannot operate the compressor
* directly from this class as doing so would circumvent the safety provided in
* using the pressure switch and closed loop control. You can only turn off
* closed loop control, thereby stopping the compressor from operating.
* Class for operating the PCM (Pneumatics compressor module) The PCM automatically will run in
* close-loop mode by default whenever a Solenoid object is created. For most cases the Compressor
* object does not need to be instantiated or used in a robot program. This class is only required
* in cases where more detailed status or to enable/disable closed loop control. Note: you cannot
* operate the compressor directly from this class as doing so would circumvent the safety provided
* in using the pressure switch and closed loop control. You can only turn off closed loop control,
* thereby stopping the compressor from operating.
*/
public class Compressor extends SensorBase implements LiveWindowSendable {
private long m_pcm;
/**
* Create an instance of the Compressor
*$
* @param pcmId The PCM CAN device ID. Most robots that use PCM will have a
* single module. Use this for supporting a second module other than
* the default.
* Create an instance of the Compressor.
*
* <p>Most robots that use PCM will have a single module. Use this for supporting a second module
* other than the default.
*
* @param pcmId The PCM CAN device ID.
*/
public Compressor(int pcmId) {
initCompressor(pcmId);
}
/**
* Create an instance of the Compressor Makes a new instance of the compressor
* using the default PCM ID (0). Additional modules can be supported by making
* a new instance and specifying the CAN ID
* Create an instance of the Compressor Makes a new instance of the compressor using the default
* PCM ID (0). Additional modules can be supported by making a new instance and specifying the CAN
* ID.
*/
public Compressor() {
initCompressor(getDefaultSolenoidModule());
@@ -54,28 +51,26 @@ public class Compressor extends SensorBase implements LiveWindowSendable {
}
/**
* Start the compressor running in closed loop control mode Use the method in
* cases where you would like to manually stop and start the compressor for
* applications such as conserving battery or making sure that the compressor
* motor doesn't start during critical operations.
* Start the compressor running in closed loop control mode Use the method in cases where you
* would like to manually stop and start the compressor for applications such as conserving
* battery or making sure that the compressor motor doesn't start during critical operations.
*/
public void start() {
setClosedLoopControl(true);
}
/**
* Stop the compressor from running in closed loop control mode. Use the
* method in cases where you would like to manually stop and start the
* compressor for applications such as conserving battery or making sure that
* the compressor motor doesn't start during critical operations.
* Stop the compressor from running in closed loop control mode. Use the method in cases where you
* would like to manually stop and start the compressor for applications such as conserving
* battery or making sure that the compressor motor doesn't start during critical operations.
*/
public void stop() {
setClosedLoopControl(false);
}
/**
* Get the enabled status of the compressor
*$
* Get the enabled status of the compressor.
*
* @return true if the compressor is on
*/
public boolean enabled() {
@@ -83,18 +78,17 @@ public class Compressor extends SensorBase implements LiveWindowSendable {
}
/**
* Get the current pressure switch value
*$
* @return true if the pressure is low by reading the pressure switch that is
* plugged into the PCM
* Get the current pressure switch value.
*
* @return true if the pressure is low by reading the pressure switch that is plugged into the PCM
*/
public boolean getPressureSwitchValue() {
return CompressorJNI.getPressureSwitch(m_pcm);
}
/**
* Get the current being used by the compressor
*$
* Get the current being used by the compressor.
*
* @return current consumed in amps for the compressor motor
*/
public float getCompressorCurrent() {
@@ -102,68 +96,73 @@ public class Compressor extends SensorBase implements LiveWindowSendable {
}
/**
* Set the PCM in closed loop control mode
*$
* @param on If true sets the compressor to be in closed loop control mode
* otherwise normal operation of the compressor is disabled.
* Set the PCM in closed loop control mode.
*
* @param on If true sets the compressor to be in closed loop control mode otherwise normal
* operation of the compressor is disabled.
*/
public void setClosedLoopControl(boolean on) {
CompressorJNI.setClosedLoopControl(m_pcm, on);
}
/**
* Gets the current operating mode of the PCM
*$
* @return true if compressor is operating on closed-loop mode, otherwise
* return false.
* Gets the current operating mode of the PCM.
*
* @return true if compressor is operating on closed-loop mode, otherwise return false.
*/
public boolean getClosedLoopControl() {
return CompressorJNI.getClosedLoopControl(m_pcm);
}
/**
* @return true if PCM is in fault state : Compressor Drive is disabled due to
* compressor current being too high.
* If PCM is in fault state : Compressor Drive is disabled due to compressor current being too
* high.
*
* @return true if PCM is in fault state.
*/
public boolean getCompressorCurrentTooHighFault() {
return CompressorJNI.getCompressorCurrentTooHighFault(m_pcm);
}
/**
* @return true if PCM sticky fault is set : Compressor Drive is disabled due
* to compressor current being too high.
* If PCM sticky fault is set : Compressor Drive is disabled due to compressor current being too
* high.
*
* @return true if PCM sticky fault is set.
*/
public boolean getCompressorCurrentTooHighStickyFault() {
return CompressorJNI.getCompressorCurrentTooHighStickyFault(m_pcm);
}
/**
* @return true if PCM sticky fault is set : Compressor output appears to be
* shorted.
* @return true if PCM sticky fault is set : Compressor output appears to be shorted.
*/
public boolean getCompressorShortedStickyFault() {
return CompressorJNI.getCompressorShortedStickyFault(m_pcm);
}
/**
* @return true if PCM is in fault state : Compressor output appears to be
* shorted.
* @return true if PCM is in fault state : Compressor output appears to be shorted.
*/
public boolean getCompressorShortedFault() {
return CompressorJNI.getCompressorShortedFault(m_pcm);
}
/**
* @return true if PCM sticky fault is set : Compressor does not appear to be
* wired, i.e. compressor is not drawing enough current.
* If PCM sticky fault is set : Compressor does not appear to be wired, i.e. compressor is not
* drawing enough current.
*
* @return true if PCM sticky fault is set.
*/
public boolean getCompressorNotConnectedStickyFault() {
return CompressorJNI.getCompressorNotConnectedStickyFault(m_pcm);
}
/**
* @return true if PCM is in fault state : Compressor does not appear to be
* wired, i.e. compressor is not drawing enough current.
* If PCM is in fault state : Compressor does not appear to be wired, i.e. compressor is not
* drawing enough current.
*
* @return true if PCM is in fault state.
*/
public boolean getCompressorNotConnectedFault() {
return CompressorJNI.getCompressorNotConnectedFault(m_pcm);
@@ -172,22 +171,23 @@ public class Compressor extends SensorBase implements LiveWindowSendable {
/**
* Clear ALL sticky faults inside PCM that Compressor is wired to.
*
* If a sticky fault is set, then it will be persistently cleared. Compressor
* drive maybe momentarily disable while flags are being cleared. Care should
* be taken to not call this too frequently, otherwise normal compressor
* functionality may be prevented.
* <p>If a sticky fault is set, then it will be persistently cleared. Compressor drive maybe
* momentarily disable while flags are being cleared. Care should be taken to not call this too
* frequently, otherwise normal compressor functionality may be prevented.
*
* If no sticky faults are set then this call will have no effect.
* <p>If no sticky faults are set then this call will have no effect.
*/
public void clearAllPCMStickyFaults() {
CompressorJNI.clearAllPCMStickyFaults(m_pcm);
}
@Override
public void startLiveWindowMode() {}
public void startLiveWindowMode() {
}
@Override
public void stopLiveWindowMode() {}
public void stopLiveWindowMode() {
}
@Override
public String getSmartDashboardType() {

View File

@@ -11,8 +11,8 @@ import edu.wpi.first.wpilibj.hal.PowerJNI;
public class ControllerPower {
/**
* Get the input voltage to the robot controller
*$
* Get the input voltage to the robot controller.
*
* @return The controller input voltage value in Volts
*/
public static double getInputVoltage() {
@@ -20,8 +20,8 @@ public class ControllerPower {
}
/**
* Get the input current to the robot controller
*$
* Get the input current to the robot controller.
*
* @return The controller input current value in Amps
*/
public static double getInputCurrent() {
@@ -29,8 +29,8 @@ public class ControllerPower {
}
/**
* Get the voltage of the 3.3V rail
*$
* Get the voltage of the 3.3V rail.
*
* @return The controller 3.3V rail voltage value in Volts
*/
public static double getVoltage3V3() {
@@ -38,8 +38,8 @@ public class ControllerPower {
}
/**
* Get the current output of the 3.3V rail
*$
* Get the current output of the 3.3V rail.
*
* @return The controller 3.3V rail output current value in Volts
*/
public static double getCurrent3V3() {
@@ -47,10 +47,9 @@ public class ControllerPower {
}
/**
* Get the enabled state of the 3.3V rail. The rail may be disabled due to a
* controller brownout, a short circuit on the rail, or controller
* over-voltage
*$
* Get the enabled state of the 3.3V rail. The rail may be disabled due to a controller brownout,
* a short circuit on the rail, or controller over-voltage.
*
* @return The controller 3.3V rail enabled value
*/
public static boolean getEnabled3V3() {
@@ -58,9 +57,8 @@ public class ControllerPower {
}
/**
* Get the count of the total current faults on the 3.3V rail since the
* controller has booted
*$
* Get the count of the total current faults on the 3.3V rail since the controller has booted.
*
* @return The number of faults
*/
public static int getFaultCount3V3() {
@@ -68,8 +66,8 @@ public class ControllerPower {
}
/**
* Get the voltage of the 5V rail
*$
* Get the voltage of the 5V rail.
*
* @return The controller 5V rail voltage value in Volts
*/
public static double getVoltage5V() {
@@ -77,8 +75,8 @@ public class ControllerPower {
}
/**
* Get the current output of the 5V rail
*$
* Get the current output of the 5V rail.
*
* @return The controller 5V rail output current value in Amps
*/
public static double getCurrent5V() {
@@ -86,10 +84,9 @@ public class ControllerPower {
}
/**
* Get the enabled state of the 5V rail. The rail may be disabled due to a
* controller brownout, a short circuit on the rail, or controller
* over-voltage
*$
* Get the enabled state of the 5V rail. The rail may be disabled due to a controller brownout, a
* short circuit on the rail, or controller over-voltage.
*
* @return The controller 5V rail enabled value
*/
public static boolean getEnabled5V() {
@@ -97,9 +94,8 @@ public class ControllerPower {
}
/**
* Get the count of the total current faults on the 5V rail since the
* controller has booted
*$
* Get the count of the total current faults on the 5V rail since the controller has booted.
*
* @return The number of faults
*/
public static int getFaultCount5V() {
@@ -107,8 +103,8 @@ public class ControllerPower {
}
/**
* Get the voltage of the 6V rail
*$
* Get the voltage of the 6V rail.
*
* @return The controller 6V rail voltage value in Volts
*/
public static double getVoltage6V() {
@@ -116,8 +112,8 @@ public class ControllerPower {
}
/**
* Get the current output of the 6V rail
*$
* Get the current output of the 6V rail.
*
* @return The controller 6V rail output current value in Amps
*/
public static double getCurrent6V() {
@@ -125,10 +121,9 @@ public class ControllerPower {
}
/**
* Get the enabled state of the 6V rail. The rail may be disabled due to a
* controller brownout, a short circuit on the rail, or controller
* over-voltage
*$
* Get the enabled state of the 6V rail. The rail may be disabled due to a controller brownout, a
* short circuit on the rail, or controller over-voltage.
*
* @return The controller 6V rail enabled value
*/
public static boolean getEnabled6V() {
@@ -136,9 +131,8 @@ public class ControllerPower {
}
/**
* Get the count of the total current faults on the 6V rail since the
* controller has booted
*$
* Get the count of the total current faults on the 6V rail since the controller has booted.
*
* @return The number of faults
*/
public static int getFaultCount6V() {

View File

@@ -19,43 +19,44 @@ import edu.wpi.first.wpilibj.tables.ITable;
import edu.wpi.first.wpilibj.util.BoundaryException;
/**
* Class for counting the number of ticks on a digital input channel. 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.
* Class for counting the number of ticks on a digital input channel. 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.
*
* All counters will immediately start counting - reset() them if you need them
* to be zeroed before use.
* <p>All counters will immediately start counting - reset() them if you need them to be zeroed
* before use.
*/
public class Counter extends SensorBase implements CounterBase, LiveWindowSendable, PIDSource {
/**
* Mode determines how and what the counter counts
* Mode determines how and what the counter counts.
*/
public static enum Mode {
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);
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
private Mode(int value) {
Mode(int value) {
this.value = value;
}
}
@@ -87,41 +88,38 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Create an instance of a counter where no sources are selected. Then they
* all must be selected by calling functions to specify the upsource and the
* downsource independently.
* Create an instance of a counter where no sources are selected. Then they all must be selected
* by calling functions to specify the upsource and the downsource independently.
*
* The counter will start counting immediately.
* <p>The counter will start counting immediately.
*/
public Counter() {
initCounter(Mode.kTwoPulse);
}
/**
* Create an instance of a counter from a Digital Input. This is used if an
* existing digital input is to be shared by multiple other objects such as
* encoders or if the Digital Source is not a DIO channel (such as an Analog
* Trigger)
* Create an instance of a counter from a Digital Input. This is used if an existing digital input
* is to be shared by multiple other objects such as encoders or if the Digital Source is not a
* DIO channel (such as an Analog Trigger)
*
* The counter will start counting immediately.
* <p>The counter will start counting immediately.
*
* @param source the digital source to count
*/
public Counter(DigitalSource source) {
if (source == null)
if (source == null) {
throw new NullPointerException("Digital Source given was null");
}
initCounter(Mode.kTwoPulse);
setUpSource(source);
}
/**
* Create an instance of a Counter object. Create an up-Counter instance given
* a channel.
* Create an instance of a Counter object. Create an up-Counter instance given a channel.
*
* The counter will start counting immediately.
* <p>The counter will start counting immediately.
*
* @param channel the DIO channel to use as the up source. 0-9 are on-board,
* 10-25 are on the MXP
* @param channel the DIO channel to use as the up source. 0-9 are on-board, 10-25 are on the MXP
*/
public Counter(int channel) {
initCounter(Mode.kTwoPulse);
@@ -129,33 +127,35 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Create an instance of a Counter object. Create an instance of a simple
* up-Counter given an analog trigger. Use the trigger state output from the
* analog trigger.
* Create an instance of a Counter object. Create an instance of a simple up-Counter given an
* analog trigger. Use the trigger state output from the analog trigger.
*
* The counter will start counting immediately.
* <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) {
boolean inverted) {
initCounter(Mode.kExternalDirection);
if (encodingType == null) {
throw new NullPointerException("Encoding type given was null");
}
if (encodingType != EncodingType.k1X && encodingType != EncodingType.k2X) {
throw new RuntimeException("Counters only support 1X and 2X quadreature decoding!");
}
if (upSource == null)
if (upSource == null) {
throw new NullPointerException("Up Source given was null");
}
setUpSource(upSource);
if (downSource == null)
if (downSource == null) {
throw new NullPointerException("Down Source given was null");
}
setDownSource(downSource);
if (encodingType == null)
throw new NullPointerException("Encoding type given was null");
if (encodingType == EncodingType.k1X) {
setUpSourceEdge(true, false);
CounterJNI.setCounterAverageSize(m_counter, 1);
@@ -168,11 +168,10 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Create an instance of a Counter object. Create an instance of a simple
* up-Counter given an analog trigger. Use the trigger state output from the
* analog trigger.
* Create an instance of a Counter object. Create an instance of a simple up-Counter given an
* analog trigger. Use the trigger state output from the analog trigger.
*
* The counter will start counting immediately.
* <p>The counter will start counting immediately.
*
* @param trigger the analog trigger to count
*/
@@ -199,8 +198,11 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* The counter's FPGA index.
*
* @return the Counter's FPGA index
*/
@SuppressWarnings("AbbreviationAsWordInName")
public int getFPGAIndex() {
return m_index;
}
@@ -208,8 +210,7 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
/**
* Set the upsource for the counter as a digital input channel.
*
* @param channel the DIO channel to count 0-9 are on-board, 10-25 are on the
* MXP
* @param channel the DIO channel to count 0-9 are on-board, 10-25 are on the MXP
*/
public void setUpSource(int channel) {
setUpSource(new DigitalInput(channel));
@@ -217,8 +218,7 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Set the source object that causes the counter to count up. Set the up
* counting DigitalSource.
* Set the source object that causes the counter to count up. Set the up counting DigitalSource.
*
* @param source the digital source to count
*/
@@ -235,9 +235,8 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
/**
* 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 analogTrigger The analog trigger object that is used for the Up Source
* @param triggerType The analog trigger output that will trigger the counter.
*/
public void setUpSource(AnalogTrigger analogTrigger, AnalogTriggerType triggerType) {
if (analogTrigger == null) {
@@ -251,15 +250,16 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Set the edge sensitivity on an up counting source. Set the up source to
* either detect rising edges or falling edges.
* 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) {
if (m_upSource == null)
if (m_upSource == null) {
throw new RuntimeException("Up Source must be set before setting the edge!");
}
CounterJNI.setCounterUpSourceEdge(m_counter, risingEdge, fallingEdge);
}
@@ -279,8 +279,7 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
/**
* Set the down counting source to be a digital input channel.
*
* @param channel the DIO channel to count 0-9 are on-board, 10-25 are on the
* MXP
* @param channel the DIO channel to count 0-9 are on-board, 10-25 are on the MXP
*/
public void setDownSource(int channel) {
setDownSource(new DigitalInput(channel));
@@ -288,8 +287,8 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Set the source object that causes the counter to count down. Set the down
* counting DigitalSource.
* Set the source object that causes the counter to count down. Set the down counting
* DigitalSource.
*
* @param source the digital source to count
*/
@@ -310,9 +309,8 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
/**
* 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 analogTrigger The analog trigger object that is used for the Down Source
* @param triggerType The analog trigger output that will trigger the counter.
*/
public void setDownSource(AnalogTrigger analogTrigger, AnalogTriggerType triggerType) {
if (analogTrigger == null) {
@@ -327,15 +325,16 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Set the edge sensitivity on a down counting source. Set the down source to
* either detect rising edges or falling edges.
* 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) {
if (m_downSource == null)
if (m_downSource == null) {
throw new RuntimeException(" Down Source must be set before setting the edge!");
}
CounterJNI.setCounterDownSourceEdge(m_counter, risingEdge, fallingEdge);
}
@@ -353,24 +352,23 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Set standard up / down counting mode on this counter. Up and down counts
* are sourced independently from two inputs.
* Set standard up / down counting mode on this counter. Up and down counts are sourced
* independently from two inputs.
*/
public void setUpDownCounterMode() {
CounterJNI.setCounterUpDownMode(m_counter);
}
/**
* Set external direction mode on this counter. Counts are sourced on the Up
* counter input. The Down counter input represents the direction to count.
* Set external direction mode on this counter. Counts are sourced on the Up counter input. The
* Down counter input represents the direction to count.
*/
public void setExternalDirectionMode() {
CounterJNI.setCounterExternalDirectionMode(m_counter);
}
/**
* Set Semi-period mode on this counter. Counts up on both rising and falling
* edges.
* Set Semi-period mode on this counter. Counts up on both rising and falling edges.
*
* @param highSemiPeriod true to count up on both rising and falling
*/
@@ -379,21 +377,19 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Configure the counter to count in up or down based on the length of the
* input pulse. This mode is most useful for direction sensitive gear tooth
* sensors.
* Configure the counter to count in up or down based on the length of the input pulse. This mode
* 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.
* @param threshold The pulse length beyond which the counter counts the opposite direction. Units
* are seconds.
*/
public void setPulseLengthMode(double threshold) {
CounterJNI.setCounterPulseLengthMode(m_counter, threshold);
}
/**
* Read the current counter value. Read the value at this instant. It may
* still be running, so it reflects the current value. Next time it is read,
* it might have a different value.
* Read the current counter value. Read the value at this instant. It may still be running, so it
* reflects the current value. Next time it is read, it might have a different value.
*/
@Override
public int get() {
@@ -401,8 +397,8 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Read the current scaled counter value. Read the value at this instant,
* scaled by the distance per pulse (defaults to 1).
* Read the current scaled counter value. Read the value at this instant, scaled by the distance
* per pulse (defaults to 1).
*
* @return The distance since the last reset
*/
@@ -411,9 +407,8 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Reset the Counter to zero. Set the counter value to zero. This doesn't
* effect the running state of the counter, just sets the current value to
* zero.
* Reset the Counter to zero. Set the counter value to zero. This doesn't effect the running state
* of the counter, just sets the current value to zero.
*/
@Override
public void reset() {
@@ -421,13 +416,11 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Set the maximum period where the device is still considered "moving". Sets
* the maximum period where the device is considered moving. This value is
* used to determine the "stopped" state of the counter using the GetStopped
* method.
* Set the maximum period where the device is still considered "moving". Sets the maximum period
* where the device is considered moving. This value is used to determine the "stopped" state of
* the counter using the GetStopped method.
*
* @param maxPeriod The maximum period where the counted device is considered
* moving in seconds.
* @param maxPeriod The maximum period where the counted device is considered moving in seconds.
*/
@Override
public void setMaxPeriod(double maxPeriod) {
@@ -435,18 +428,15 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Select whether you want to continue updating the event timer output when
* there are no samples captured. The output of the event timer has a buffer
* of periods that are averaged and posted to a register on the FPGA. When the
* timer detects that the event source has stopped (based on the MaxPeriod)
* the buffer of samples to be averaged is emptied. If you enable the update
* when empty, you will be notified of the stopped source and the event time
* will report 0 samples. If you disable update when empty, the most recent
* average will remain on the output until a new sample is acquired. You will
* never see 0 samples output (except when there have been no events since an
* FPGA reset) and you will likely not see the stopped bit become true (since
* it is updated at the end of an average and there are no samples to
* average).
* Select whether you want to continue updating the event timer output when there are no samples
* captured. The output of the event timer has a buffer of periods that are averaged and posted to
* a register on the FPGA. When the timer detects that the event source has stopped (based on the
* MaxPeriod) the buffer of samples to be averaged is emptied. If you enable the update when
* empty, you will be notified of the stopped source and the event time will report 0 samples. If
* you disable update when empty, the most recent average will remain on the output until a new
* sample is acquired. You will never see 0 samples output (except when there have been no events
* since an FPGA reset) and you will likely not see the stopped bit become true (since it is
* updated at the end of an average and there are no samples to average).
*
* @param enabled true to continue updating
*/
@@ -455,13 +445,11 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Determine if the clock is stopped. Determine if the clocked input is
* stopped based on the MaxPeriod value set using the SetMaxPeriod method. If
* the clock exceeds the MaxPeriod, then the device (and counter) are assumed
* to be stopped and it returns true.
* Determine if the clock is stopped. Determine if the clocked input is stopped based on the
* MaxPeriod value set using the SetMaxPeriod method. If the clock exceeds the MaxPeriod, then the
* device (and counter) are assumed to be stopped and it returns true.
*
* @return Returns true if the most recent counter period exceeds the
* MaxPeriod value set by SetMaxPeriod.
* @return true if the most recent counter period exceeds the MaxPeriod value set by SetMaxPeriod.
*/
@Override
public boolean getStopped() {
@@ -479,9 +467,9 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Set the Counter to return reversed sensing on the direction. This allows
* counters to change the direction they are counting in the case of 1X and 2X
* quadrature encoding only. Any other counter mode isn't supported.
* Set the Counter to return reversed sensing on the direction. This allows counters to change the
* direction they are counting in the case of 1X and 2X quadrature encoding only. Any other
* counter mode isn't supported.
*
* @param reverseDirection true if the value counted should be negated.
*/
@@ -490,9 +478,8 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Get the Period of the most recent count. Returns the time interval of the
* most recent count. This can be used for velocity calculations to determine
* shaft speed.
* Get the Period of the most recent count. Returns the time interval of the most recent count.
* This can be used for velocity calculations to determine shaft speed.
*
* @return The period of the last two pulses in units of seconds.
*/
@@ -502,9 +489,9 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Get the current rate of the Counter. Read the current rate of the counter
* accounting for the distance per pulse value. The default value for distance
* per pulse (1) yields units of pulses per second.
* Get the current rate of the Counter. Read the current rate of the counter accounting for the
* distance per pulse value. The default value for distance per pulse (1) yields units of pulses
* per second.
*
* @return The rate in units/sec
*/
@@ -513,9 +500,9 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Set the Samples to Average which specifies the number of samples of the
* timer to average when calculating the period. Perform averaging to account
* for mechanical imperfections or as oversampling to increase resolution.
* Set the Samples to Average which specifies the number of samples of the timer to average when
* calculating the period. Perform averaging to account for mechanical imperfections or as
* oversampling to increase resolution.
*
* @param samplesToAverage The number of samples to average from 1 to 127.
*/
@@ -524,33 +511,31 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
/**
* Get the Samples to Average which specifies the number of samples of the
* timer to average when calculating the period. Perform averaging to account
* for mechanical imperfections or as oversampling to increase resolution.
* Get the Samples to Average which specifies the number of samples of the timer to average when
* calculating the period. Perform averaging to account for mechanical imperfections or as
* oversampling to increase resolution.
*
* @return SamplesToAverage The number of samples being averaged (from 1 to
* 127)
* @return SamplesToAverage The number of samples being averaged (from 1 to 127)
*/
public int getSamplesToAverage() {
return CounterJNI.getCounterSamplesToAverage(m_counter);
}
/**
* Set the distance per pulse for this counter. This sets the multiplier used
* to determine the distance driven based on the count value from the encoder.
* Set this value based on the Pulses per Revolution and factor in any gearing
* reductions. This distance can be in any units you like, linear or angular.
* Set the distance per pulse for this counter. This sets the multiplier used to determine the
* distance driven based on the count value from the encoder. Set this value based on the Pulses
* per Revolution and factor in any gearing reductions. This distance can be in any units you
* like, linear or angular.
*
* @param distancePerPulse The scale factor that will be used to convert
* pulses to useful units.
* @param distancePerPulse The scale factor that will be used to convert pulses to useful units.
*/
public void setDistancePerPulse(double distancePerPulse) {
m_distancePerPulse = distancePerPulse;
}
/**
* Set which parameter of the encoder you are using as a process control
* variable. The counter class supports the rate and distance parameters.
* Set which parameter of the encoder you are using as a process control variable. The counter
* class supports the rate and distance parameters.
*
* @param pidSource An enum to select the parameter.
*/
@@ -562,9 +547,6 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
m_pidSource = pidSource;
}
/**
* {@inheritDoc}
*/
public PIDSourceType getPIDSourceType() {
return m_pidSource;
}
@@ -581,9 +563,6 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
}
/**
* Live Window code, only does anything if live window is activated.
*/
@Override
public String getSmartDashboardType() {
return "Counter";
@@ -591,26 +570,17 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
private ITable m_table;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
@@ -618,15 +588,11 @@ public class Counter extends SensorBase implements CounterBase, LiveWindowSendab
}
}
/**
* {@inheritDoc}
*/
@Override
public void startLiveWindowMode() {}
public void startLiveWindowMode() {
}
/**
* {@inheritDoc}
*/
@Override
public void stopLiveWindowMode() {}
public void stopLiveWindowMode() {
}
}

View File

@@ -8,78 +8,79 @@
package edu.wpi.first.wpilibj;
/**
* Interface for counting the number of ticks on a digital input channel.
* Encoders, Gear tooth sensors, and counters should all subclass this so it can
* be used to build more advanced classes for control and driving.
* Interface for counting the number of ticks on a digital input channel. Encoders, Gear tooth
* sensors, and counters should all subclass this so it can be used to build more advanced classes
* for control and driving.
*
* All counters will immediately start counting - reset() them if you need them
* to be zeroed before use.
* <p>All counters will immediately start counting - reset() them if you need them to be zeroed
* 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.
*/
public enum EncodingType {
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);
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
private EncodingType(int value) {
EncodingType(int value) {
this.value = value;
}
}
/**
* Get the count
*$
* Get the count.
*
* @return the count
*/
int get();
/**
* Reset the count to zero
* Reset the count to zero.
*/
void reset();
/**
* Get the time between the last two edges counted
*$
* Get the time between the last two edges counted.
*
* @return the time beteween the last two ticks in seconds
*/
double getPeriod();
/**
* Set the maximum time between edges to be considered stalled
*$
* Set the maximum time between edges to be considered stalled.
*
* @param maxPeriod the maximum period in seconds
*/
void setMaxPeriod(double maxPeriod);
/**
* Determine if the counter is not moving
*$
* Determine if the counter is not moving.
*
* @return true if the counter has not changed for the max period
*/
boolean getStopped();
/**
* Determine which direction the counter is going
*$
* Determine which direction the counter is going.
*
* @return true for one direction, false for the other
*/
boolean getDirection();

View File

@@ -10,40 +10,41 @@ package edu.wpi.first.wpilibj;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import edu.wpi.first.wpilibj.DigitalSource;
import edu.wpi.first.wpilibj.Encoder;
import edu.wpi.first.wpilibj.Counter;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.hal.DigitalGlitchFilterJNI;
/**
* Class to enable glitch filtering on a set of digital inputs.
* This class will manage adding and removing digital inputs from a FPGA glitch
* filter. The filter lets the user configure the time that an input must remain
* high or low before it is classified as high or low.
* Class to enable glitch filtering on a set of digital inputs. This class will manage adding and
* removing digital inputs from a FPGA glitch filter. The filter lets the user configure the time
* that an input must remain high or low before it is classified as high or low.
*/
public class DigitalGlitchFilter extends SensorBase {
/**
* Configures the Digital Glitch Filter to its default settings.
*/
public DigitalGlitchFilter() {
synchronized(m_mutex) {
int i = 0;
while (m_filterAllocated[i] != false && i < m_filterAllocated.length) {
i++;
synchronized (m_mutex) {
int index = 0;
while (m_filterAllocated[index] != false && index < m_filterAllocated.length) {
index++;
}
if (i != m_filterAllocated.length) {
m_channelIndex = i;
m_filterAllocated[i] = true;
if (index != m_filterAllocated.length) {
m_channelIndex = index;
m_filterAllocated[index] = true;
UsageReporting.report(tResourceType.kResourceType_DigitalFilter,
m_channelIndex, 0);
m_channelIndex, 0);
}
}
}
/**
* Free the resources used by this object.
*/
public void free() {
if (m_channelIndex >= 0) {
synchronized(m_mutex) {
synchronized (m_mutex) {
m_filterAllocated[m_channelIndex] = false;
}
m_channelIndex = -1;
@@ -121,30 +122,30 @@ public class DigitalGlitchFilter extends SensorBase {
}
/**
* Sets the number of FPGA cycles that the input must hold steady to pass
* through this glitch filter.
* Sets the number of FPGA cycles that the input must hold steady to pass through this glitch
* filter.
*
* @param fpga_cycles The number of FPGA cycles.
* @param fpgaCycles The number of FPGA cycles.
*/
public void setPeriodCycles(int fpga_cycles) {
DigitalGlitchFilterJNI.setFilterPeriod(m_channelIndex, fpga_cycles);
public void setPeriodCycles(int fpgaCycles) {
DigitalGlitchFilterJNI.setFilterPeriod(m_channelIndex, fpgaCycles);
}
/**
* Sets the number of nanoseconds that the input must hold steady to pass
* through this glitch filter.
* Sets the number of nanoseconds that the input must hold steady to pass through this glitch
* filter.
*
* @param nanoseconds The number of nanoseconds.
*/
public void setPeriodNanoSeconds(long nanoseconds) {
int fpga_cycles = (int) (nanoseconds * kSystemClockTicksPerMicrosecond / 4 /
1000);
setPeriodCycles(fpga_cycles);
int fpgaCycles = (int) (nanoseconds * kSystemClockTicksPerMicrosecond / 4
/ 1000);
setPeriodCycles(fpgaCycles);
}
/**
* Gets the number of FPGA cycles that the input must hold steady to pass
* through this glitch filter.
* Gets the number of FPGA cycles that the input must hold steady to pass through this glitch
* filter.
*
* @return The number of cycles.
*/
@@ -153,19 +154,19 @@ public class DigitalGlitchFilter extends SensorBase {
}
/**
* Gets the number of nanoseconds that the input must hold steady to pass
* through this glitch filter.
* Gets the number of nanoseconds that the input must hold steady to pass through this glitch
* filter.
*
* @return The number of nanoseconds.
*/
public long getPeriodNanoSeconds() {
int fpga_cycles = getPeriodCycles();
int fpgaCycles = getPeriodCycles();
return (long) fpga_cycles * 1000L /
(long) (kSystemClockTicksPerMicrosecond / 4);
return (long) fpgaCycles * 1000L
/ (long) (kSystemClockTicksPerMicrosecond / 4);
}
private int m_channelIndex = -1;
private static final Lock m_mutex = new ReentrantLock(true);
private static final boolean[] m_filterAllocated = new boolean[3];
};
}

View File

@@ -15,20 +15,17 @@ import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
/**
* Class to read a digital input. This class will read digital inputs and return
* the current value on the channel. Other devices such as encoders, gear tooth
* sensors, etc. that are implemented elsewhere will automatically allocate
* digital inputs and outputs as required. This class is only for devices like
* switches etc. that aren't implemented anywhere else.
* Class to read a digital input. This class will read digital inputs and return the current value
* on the channel. Other devices such as encoders, gear tooth sensors, etc. that are implemented
* elsewhere will automatically allocate digital inputs and outputs as required. This class is only
* for devices like switches etc. that aren't implemented anywhere else.
*/
public class DigitalInput extends DigitalSource implements LiveWindowSendable {
/**
* Create an instance of a Digital Input class. Creates a digital input given
* a channel.
* Create an instance of a Digital Input class. Creates a digital input given a channel.
*
* @param channel the DIO channel for the digital input 0-9 are on-board,
* 10-25 are on the MXP
* @param channel the DIO channel for the digital input 0-9 are on-board, 10-25 are on the MXP
*/
public DigitalInput(int channel) {
initDigitalPort(channel, true);
@@ -38,13 +35,13 @@ public class DigitalInput extends DigitalSource implements LiveWindowSendable {
}
/**
* Get the value from a digital input channel. Retrieve the value of a single
* digital input channel from the FPGA.
* Get the value from a digital input channel. Retrieve the value of a single digital input
* channel from the FPGA.
*
* @return the status of the digital input
*/
public boolean get() {
return DIOJNI.getDIO(m_port);
return DIOJNI.getDIO(super.m_port);
}
/**
@@ -53,7 +50,7 @@ public class DigitalInput extends DigitalSource implements LiveWindowSendable {
* @return The GPIO channel number that this object represents.
*/
public int getChannel() {
return m_channel;
return super.m_channel;
}
@Override
@@ -61,9 +58,7 @@ public class DigitalInput extends DigitalSource implements LiveWindowSendable {
return false;
}
/*
* Live Window code, only does anything if live window is activated.
*/
@Override
public String getSmartDashboardType() {
return "Digital Input";
@@ -71,18 +66,14 @@ public class DigitalInput extends DigitalSource implements LiveWindowSendable {
private ITable m_table;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
@@ -90,23 +81,19 @@ public class DigitalInput extends DigitalSource implements LiveWindowSendable {
}
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void startLiveWindowMode() {}
/**
* {@inheritDoc}
*/
@Override
public void stopLiveWindowMode() {}
public void startLiveWindowMode() {
}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -7,18 +7,17 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.hal.DIOJNI;
import edu.wpi.first.wpilibj.hal.PWMJNI;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
import edu.wpi.first.wpilibj.tables.ITableListener;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
/**
* Class to write digital outputs. This class will write digital outputs. Other
* devices that are implemented elsewhere will automatically allocate digital
* inputs and outputs as required.
* Class to write digital outputs. This class will write digital outputs. Other devices that are
* implemented elsewhere will automatically allocate digital inputs and outputs as required.
*/
public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
@@ -27,11 +26,11 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
private long m_pwmGenerator = invalidPwmGenerator;
/**
* 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
* @param channel the DIO channel to use for the digital output. 0-9 are on-board, 10-25 are on
* the MXP
*/
public DigitalOutput(int channel) {
initDigitalPort(channel, false);
@@ -57,34 +56,32 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
* @param value true is on, off is false
*/
public void set(boolean value) {
DIOJNI.setDIO(m_port, (short) (value ? 1 : 0));
DIOJNI.setDIO(super.m_port, (short) (value ? 1 : 0));
}
/**
* @return The GPIO channel number that this object represents.
*/
public int getChannel() {
return m_channel;
return super.m_channel;
}
/**
* Generate a single pulse. Write a pulse to the specified digital output
* channel. There can only be a single pulse going at any time.
* Generate a single pulse. Write a pulse to the specified digital output channel. There can only
* be a single pulse going at any time.
*
* @param channel The channel to pulse.
* @param channel The channel to pulse.
* @param pulseLength The length of the pulse.
*/
public void pulse(final int channel, final float pulseLength) {
DIOJNI.pulse(m_port, pulseLength);
DIOJNI.pulse(super.m_port, pulseLength);
}
/**
* @deprecated Generate a single pulse. Write a pulse to the specified digital
* output channel. There can only be a single pulse going at any
* time.
*
* @param channel The channel to pulse.
* @param channel The channel to pulse.
* @param pulseLength The length of the pulse.
* @deprecated Generate a single pulse. Write a pulse to the specified digital output channel.
* There can only be a single pulse going at any time.
*/
@Deprecated
public void pulse(final int channel, final int pulseLength) {
@@ -92,26 +89,24 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
(float) (pulseLength / 1.0e9 * (DIOJNI.getLoopTiming() * 25));
System.err
.println("You should use the float version of pulse for portability. This is deprecated");
DIOJNI.pulse(m_port, convertedPulse);
DIOJNI.pulse(super.m_port, convertedPulse);
}
/**
* Determine if the pulse is still going. Determine if a previously started
* pulse is still going.
* Determine if the pulse is still going. Determine if a previously started pulse is still going.
*
* @return true if pulsing
*/
public boolean isPulsing() {
return DIOJNI.isPulsing(m_port);
return DIOJNI.isPulsing(super.m_port);
}
/**
* Change the PWM frequency of the PWM output on a Digital Output line.
*
* The valid range is from 0.6 Hz to 19 kHz. The frequency resolution is
* logarithmic.
* <p>The valid range is from 0.6 Hz to 19 kHz. The frequency resolution is logarithmic.
*
* There is only one PWM frequency for all channnels.
* <p>There is only one PWM frequency for all channnels.
*
* @param rate The frequency to output all digital output PWM signals.
*/
@@ -122,19 +117,19 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
/**
* Enable a PWM Output on this line.
*
* Allocate one of the 6 DO PWM generator resources.
* <p>Allocate one of the 6 DO PWM generator resources.
*
* Supply the initial duty-cycle to output so as to avoid a glitch when first
* starting.
* <p>Supply the initial duty-cycle to output so as to avoid a glitch when first starting.
*
* 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.
* <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.
*
* @param initialDutyCycle The duty-cycle to start generating. [0..1]
*/
public void enablePWM(double initialDutyCycle) {
if (m_pwmGenerator != invalidPwmGenerator)
if (m_pwmGenerator != invalidPwmGenerator) {
return;
}
m_pwmGenerator = PWMJNI.allocatePWM();
PWMJNI.setPWMDutyCycle(m_pwmGenerator, initialDutyCycle);
PWMJNI.setPWMOutputChannel(m_pwmGenerator, m_channel);
@@ -143,11 +138,12 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
/**
* Change this line from a PWM output back to a static Digital Output line.
*
* Free up one of the 6 DO PWM generator resources that were in use.
* <p>Free up one of the 6 DO PWM generator resources that were in use.
*/
public void disablePWM() {
if (m_pwmGenerator == invalidPwmGenerator)
if (m_pwmGenerator == invalidPwmGenerator) {
return;
}
// Disable the output by routing to a dead bit.
PWMJNI.setPWMOutputChannel(m_pwmGenerator, kDigitalChannels);
PWMJNI.freePWM(m_pwmGenerator);
@@ -157,14 +153,16 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
/**
* Change the duty-cycle that is being generated on the line.
*
* 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.
* <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.
*
* @param dutyCycle The duty-cycle to change to. [0..1]
*/
public void updateDutyCycle(double dutyCycle) {
if (m_pwmGenerator == invalidPwmGenerator)
if (m_pwmGenerator == invalidPwmGenerator) {
return;
}
PWMJNI.setPWMDutyCycle(m_pwmGenerator, dutyCycle);
}
@@ -177,53 +175,43 @@ public class DigitalOutput extends DigitalSource implements LiveWindowSendable {
}
private ITable m_table;
private ITableListener m_table_listener;
private ITableListener m_tableListener;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
// TODO: Put current value.
}
/**
* {@inheritDoc}
*/
@Override
public void startLiveWindowMode() {
m_table_listener = new ITableListener() {
m_tableListener = new ITableListener() {
@Override
public void valueChanged(ITable itable, String key, Object value, boolean bln) {
set(((Boolean) value).booleanValue());
set((Boolean) value);
}
};
m_table.addTableListener("Value", m_table_listener, true);
m_table.addTableListener("Value", m_tableListener, true);
}
/**
* {@inheritDoc}
*/
@Override
public void stopLiveWindowMode() {
// TODO: Broken, should only remove the listener from "Value" only.
m_table.removeTableListener(m_table_listener);
m_table.removeTableListener(m_tableListener);
}
}

View File

@@ -12,11 +12,10 @@ import edu.wpi.first.wpilibj.util.AllocationException;
import edu.wpi.first.wpilibj.util.CheckedAllocationException;
/**
* DigitalSource Interface. The DigitalSource represents all the possible inputs
* for a counter or a quadrature encoder. The source may be either a digital
* input or an analog input. If the caller just provides a channel, then a
* digital input will be constructed and freed when finished for the source. The
* source can either be a digital input or analog trigger but not both.
* DigitalSource Interface. The DigitalSource represents all the possible inputs for a counter or a
* quadrature encoder. The source may be either a digital input or an analog input. If the caller
* just provides a channel, then a digital input will be constructed and freed when finished for the
* source. The source can either be a digital input or analog trigger but not both.
*/
public abstract class DigitalSource extends InterruptableSensorBase {
@@ -36,8 +35,8 @@ public abstract class DigitalSource extends InterruptableSensorBase {
throw new AllocationException("Digital input " + m_channel + " is already allocated");
}
long port_pointer = DIOJNI.getPort((byte) channel);
m_port = DIOJNI.initializeDigitalPort(port_pointer);
long portPointer = DIOJNI.getPort((byte) channel);
m_port = DIOJNI.initializeDigitalPort(portPointer);
DIOJNI.allocateDIO(m_port, input);
}
@@ -51,7 +50,7 @@ public abstract class DigitalSource extends InterruptableSensorBase {
}
/**
* Get the channel routing number
* Get the channel routing number.
*
* @return channel routing number
*/
@@ -61,7 +60,7 @@ public abstract class DigitalSource extends InterruptableSensorBase {
}
/**
* Get the module routing number
* Get the module routing number.
*
* @return 0
*/
@@ -71,8 +70,8 @@ public abstract class DigitalSource extends InterruptableSensorBase {
}
/**
* Is this an analog trigger
*$
* Is this an analog trigger.
*
* @return true if this is an analog trigger
*/
@Override

View File

@@ -19,24 +19,22 @@ import edu.wpi.first.wpilibj.util.CheckedAllocationException;
/**
* DoubleSolenoid class for running 2 channels of high voltage Digital Output.
*
* The DoubleSolenoid class is typically used for pneumatics solenoids that have
* two positions controlled by two separate channels.
* <p>The DoubleSolenoid class is typically used for pneumatics solenoids that have two positions
* controlled by two separate channels.
*/
public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
/**
* Possible values for a DoubleSolenoid
* Possible values for a DoubleSolenoid.
*/
public static enum Value {
public enum Value {
kOff,
kForward,
kReverse
}
private int m_forwardChannel; // /< The forward channel on the module to
// control.
private int m_reverseChannel; // /< The reverse channel on the module to
// control.
private int m_forwardChannel; // /< The forward channel on the module to control.
private int m_reverseChannel; // /< The reverse channel on the module to control.
private byte m_forwardMask; // /< The mask for the forward channel.
private byte m_reverseMask; // /< The mask for the reverse channel.
@@ -49,14 +47,14 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
checkSolenoidChannel(m_reverseChannel);
try {
m_allocated.allocate(m_moduleNumber * kSolenoidChannels + m_forwardChannel);
} catch (CheckedAllocationException e) {
allocated.allocate(m_moduleNumber * kSolenoidChannels + m_forwardChannel);
} catch (CheckedAllocationException exception) {
throw new AllocationException("Solenoid channel " + m_forwardChannel + " on module "
+ m_moduleNumber + " is already allocated");
}
try {
m_allocated.allocate(m_moduleNumber * kSolenoidChannels + m_reverseChannel);
} catch (CheckedAllocationException e) {
allocated.allocate(m_moduleNumber * kSolenoidChannels + m_reverseChannel);
} catch (CheckedAllocationException exception) {
throw new AllocationException("Solenoid channel " + m_reverseChannel + " on module "
+ m_moduleNumber + " is already allocated");
}
@@ -69,8 +67,8 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
}
/**
* Constructor. Uses the default PCM ID of 0
*$
* Constructor. Uses the default PCM ID of 0.
*
* @param forwardChannel The forward channel number on the PCM (0..7).
* @param reverseChannel The reverse channel number on the PCM (0..7).
*/
@@ -84,11 +82,12 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
/**
* 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);
m_forwardChannel = forwardChannel;
m_reverseChannel = reverseChannel;
@@ -99,8 +98,8 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
* Destructor.
*/
public synchronized void free() {
m_allocated.free(m_moduleNumber * kSolenoidChannels + m_forwardChannel);
m_allocated.free(m_moduleNumber * kSolenoidChannels + m_reverseChannel);
allocated.free(m_moduleNumber * kSolenoidChannels + m_forwardChannel);
allocated.free(m_moduleNumber * kSolenoidChannels + m_reverseChannel);
super.free();
}
@@ -110,7 +109,7 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
* @param value The value to set (Off, Forward, Reverse)
*/
public void set(final Value value) {
byte rawValue = 0;
final byte rawValue;
switch (value) {
case kOff:
@@ -122,6 +121,9 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
case kReverse:
rawValue = m_reverseMask;
break;
default:
throw new AssertionError("Illegal value: " + value);
}
set(rawValue, m_forwardMask | m_reverseMask);
@@ -135,21 +137,21 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
public Value get() {
byte value = getAll();
if ((value & m_forwardMask) != 0)
if ((value & m_forwardMask) != 0) {
return Value.kForward;
if ((value & m_reverseMask) != 0)
}
if ((value & m_reverseMask) != 0) {
return Value.kReverse;
}
return Value.kOff;
}
/**
* Check if the forward solenoid is blacklisted. If a solenoid is shorted, it
* is added to the blacklist and disabled until power cycle, or until faults
* are cleared.
*
* @see #clearAllPCMStickyFaults()
* Check if the forward solenoid is blacklisted. If a solenoid is shorted, it is added to the
* blacklist and disabled until power cycle, or until faults are cleared.
*
* @return If solenoid is disabled due to short.
* @see #clearAllPCMStickyFaults()
*/
public boolean isFwdSolenoidBlackListed() {
int blackList = getPCMSolenoidBlackList();
@@ -157,13 +159,11 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
}
/**
* Check if the reverse solenoid is blacklisted. If a solenoid is shorted, it
* is added to the blacklist and disabled until power cycle, or until faults
* are cleared.
*
* @see #clearAllPCMStickyFaults()
* Check if the reverse solenoid is blacklisted. If a solenoid is shorted, it is added to the
* blacklist and disabled until power cycle, or until faults are cleared.
*
* @return If solenoid is disabled due to short.
* @see #clearAllPCMStickyFaults()
*/
public boolean isRevSolenoidBlackListed() {
int blackList = getPCMSolenoidBlackList();
@@ -178,26 +178,20 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
}
private ITable m_table;
private ITableListener m_table_listener;
private ITableListener m_tableListener;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
// TODO: this is bad
@@ -206,31 +200,28 @@ public class DoubleSolenoid extends SolenoidBase implements LiveWindowSendable {
}
}
/**
* {@inheritDoc}
*/
@Override
public void startLiveWindowMode() {
set(Value.kOff); // Stop for safety
m_table_listener = new ITableListener() {
m_tableListener = new ITableListener() {
public void valueChanged(ITable itable, String key, Object value, boolean bln) {
// TODO: this is bad also
if (value.toString().equals("Reverse"))
if (value.toString().equals("Reverse")) {
set(Value.kReverse);
else if (value.toString().equals("Forward"))
} else if (value.toString().equals("Forward")) {
set(Value.kForward);
else
} else {
set(Value.kOff);
}
}
};
m_table.addTableListener("Value", m_table_listener, true);
m_table.addTableListener("Value", m_tableListener, true);
}
/**
* {@inheritDoc}
*/
@Override
public void stopLiveWindowMode() {
set(Value.kOff); // Stop for safety
// TODO: Broken, should only remove the listener from "Value" only.
m_table.removeTableListener(m_table_listener);
m_table.removeTableListener(m_tableListener);
}
}

View File

@@ -10,29 +10,28 @@ package edu.wpi.first.wpilibj;
import java.nio.ByteBuffer;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary;
import edu.wpi.first.wpilibj.communication.HALControlWord;
import edu.wpi.first.wpilibj.communication.HALAllianceStationID;
import edu.wpi.first.wpilibj.communication.HALControlWord;
import edu.wpi.first.wpilibj.hal.HALUtil;
import edu.wpi.first.wpilibj.hal.PowerJNI;
/**
* Provide access to the network communication data to / from the Driver
* Station.
* Provide access to the network communication data to / from the Driver Station.
*/
public class DriverStation implements RobotState.Interface {
/**
* Number of Joystick Ports
* Number of Joystick Ports.
*/
public static final int kJoystickPorts = 6;
private class HALJoystickButtons {
public int buttons;
public byte count;
public int m_buttons;
public byte m_count;
}
/**
* 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
@@ -69,7 +68,7 @@ public class DriverStation implements RobotState.Interface {
private Thread m_thread;
private final Object m_dataSem;
private volatile boolean m_thread_keepalive = true;
private volatile boolean m_threadKeepAlive = true;
private boolean m_userInDisabled = false;
private boolean m_userInAutonomous = false;
private boolean m_userInTeleop = false;
@@ -90,8 +89,8 @@ public class DriverStation implements RobotState.Interface {
/**
* DriverStation constructor.
*
* The single DriverStation instance is created statically with the instance
* static member variable.
* <p>The single DriverStation instance is created statically with the instance static member
* variable.
*/
protected DriverStation() {
m_dataSem = new Object();
@@ -110,18 +109,18 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Kill the thread
* Kill the thread.
*/
public void release() {
m_thread_keepalive = false;
m_threadKeepAlive = false;
}
/**
* Provides the service routine for the DS polling thread.
* Provides the service routine for the DS polling m_thread.
*/
private void task() {
int safetyCounter = 0;
while (m_thread_keepalive) {
while (m_threadKeepAlive) {
HALUtil.takeMultiWait(m_packetDataAvailableSem, m_packetDataAvailableMutex);
synchronized (this) {
getData();
@@ -156,8 +155,8 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Wait for new data or for timeout, which ever comes first. If timeout is 0,
* wait for new data only.
* Wait for new data or for timeout, which ever comes first. If timeout is 0, wait for new data
* only.
*
* @param timeout The maximum time in milliseconds to wait.
*/
@@ -166,14 +165,14 @@ public class DriverStation implements RobotState.Interface {
try {
m_dataSem.wait(timeout);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
/**
* Copy data from the DS task for the user. If no new data exists, it will
* just be returned, otherwise the data will be copied from the DS polling
* loop.
* Copy data from the DS task for the user. If no new data exists, it will just be returned,
* otherwise the data will be copied from the DS polling loop.
*/
protected synchronized void getData() {
@@ -182,9 +181,9 @@ public class DriverStation implements RobotState.Interface {
m_joystickAxes[stick] = FRCNetworkCommunicationsLibrary.HALGetJoystickAxes(stick);
m_joystickPOVs[stick] = FRCNetworkCommunicationsLibrary.HALGetJoystickPOVs(stick);
ByteBuffer countBuffer = ByteBuffer.allocateDirect(1);
m_joystickButtons[stick].buttons =
FRCNetworkCommunicationsLibrary.HALGetJoystickButtons((byte) stick, countBuffer);
m_joystickButtons[stick].count = countBuffer.get();
m_joystickButtons[stick].m_buttons =
FRCNetworkCommunicationsLibrary.HALGetJoystickButtons(stick, countBuffer);
m_joystickButtons[stick].m_count = countBuffer.get();
}
m_newControlData = true;
@@ -200,8 +199,8 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Reports errors related to unplugged joysticks Throttles the errors so that
* they don't overwhelm the DS
* Reports errors related to unplugged joysticks Throttles the errors so that they don't overwhelm
* the DS.
*/
private void reportJoystickUnpluggedError(String message) {
double currentTime = Timer.getFPGATimestamp();
@@ -212,8 +211,8 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Reports errors related to unplugged joysticks Throttles the errors so that
* they don't overwhelm the DS
* Reports errors related to unplugged joysticks Throttles the errors so that they don't overwhelm
* the DS.
*/
private void reportJoystickUnpluggedWarning(String message) {
double currentTime = Timer.getFPGATimestamp();
@@ -224,11 +223,11 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Get the value of the axis on a joystick. This depends on the mapping of the
* joystick connected to the specified port.
* Get the value of the axis on a joystick. This depends on the mapping of the joystick connected
* 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 synchronized double getStickAxis(int stick, int axis) {
@@ -256,7 +255,7 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Returns the number of axes on a given joystick port
* Returns the number of axes on a given joystick port.
*
* @param stick The joystick port number
* @return The number of axes on the indicated joystick
@@ -294,7 +293,7 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Returns the number of POVs on a given joystick port
* Returns the number of POVs on a given joystick port.
*
* @param stick The joystick port number
* @return The number of POVs on the indicated joystick
@@ -319,13 +318,13 @@ public class DriverStation implements RobotState.Interface {
throw new RuntimeException("Joystick index is out of range, should be 0-3");
}
return m_joystickButtons[stick].buttons;
return m_joystickButtons[stick].m_buttons;
}
/**
* 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.
*/
@@ -335,7 +334,7 @@ public class DriverStation implements RobotState.Interface {
}
if (button > m_joystickButtons[stick].count) {
if (button > m_joystickButtons[stick].m_count) {
reportJoystickUnpluggedWarning("Joystick Button " + button + " on port " + stick
+ " not available, check if controller is plugged in");
return false;
@@ -344,11 +343,11 @@ public class DriverStation implements RobotState.Interface {
reportJoystickUnpluggedError("Button indexes begin at 1 in WPILib for C++ and Java");
return false;
}
return ((0x1 << (button - 1)) & m_joystickButtons[stick].buttons) != 0;
return ((0x1 << (button - 1)) & m_joystickButtons[stick].m_buttons) != 0;
}
/**
* Gets the number of buttons on a joystick
* Gets the number of buttons on a joystick.
*
* @param stick The joystick port number
* @return The number of buttons on the indicated joystick
@@ -360,11 +359,11 @@ public class DriverStation implements RobotState.Interface {
}
return m_joystickButtons[stick].count;
return m_joystickButtons[stick].m_count;
}
/**
* Gets the value of isXbox on a joystick
* Gets the value of isXbox on a joystick.
*
* @param stick The joystick port number
* @return A boolean that returns the value of isXbox
@@ -376,7 +375,7 @@ public class DriverStation implements RobotState.Interface {
}
// TODO: Remove this when calling for descriptor on empty stick no longer
// crashes
if (1 > m_joystickButtons[stick].count && 1 > m_joystickAxes[stick].length) {
if (1 > m_joystickButtons[stick].m_count && 1 > m_joystickAxes[stick].length) {
reportJoystickUnpluggedWarning("Joystick on port " + stick
+ " not available, check if controller is plugged in");
return false;
@@ -389,7 +388,7 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Gets the value of type on a joystick
* Gets the value of type on a joystick.
*
* @param stick The joystick port number
* @return The value of type
@@ -401,7 +400,7 @@ public class DriverStation implements RobotState.Interface {
}
// TODO: Remove this when calling for descriptor on empty stick no longer
// crashes
if (1 > m_joystickButtons[stick].count && 1 > m_joystickAxes[stick].length) {
if (1 > m_joystickButtons[stick].m_count && 1 > m_joystickAxes[stick].length) {
reportJoystickUnpluggedWarning("Joystick on port " + stick
+ " not available, check if controller is plugged in");
return -1;
@@ -410,7 +409,7 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Gets the name of the joystick at a port
* Gets the name of the joystick at a port.
*
* @param stick The joystick port number
* @return The value of name
@@ -422,7 +421,7 @@ public class DriverStation implements RobotState.Interface {
}
// TODO: Remove this when calling for descriptor on empty stick no longer
// crashes
if (1 > m_joystickButtons[stick].count && 1 > m_joystickAxes[stick].length) {
if (1 > m_joystickButtons[stick].m_count && 1 > m_joystickAxes[stick].length) {
reportJoystickUnpluggedWarning("Joystick on port " + stick
+ " not available, check if controller is plugged in");
return "";
@@ -431,8 +430,7 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Gets a value indicating whether the Driver Station requires the robot to be
* enabled.
* Gets a value indicating whether the Driver Station requires the robot to be enabled.
*
* @return True if the robot is enabled, false otherwise.
*/
@@ -442,8 +440,7 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Gets a value indicating whether the Driver Station requires the robot to be
* disabled.
* Gets a value indicating whether the Driver Station requires the robot to be disabled.
*
* @return True if the robot should be disabled, false otherwise.
*/
@@ -452,8 +449,8 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Gets a value indicating whether the Driver Station requires the robot to be
* running in autonomous mode.
* Gets a value indicating whether the Driver Station requires the robot to be running in
* autonomous mode.
*
* @return True if autonomous mode should be enabled, false otherwise.
*/
@@ -463,9 +460,9 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Gets a value indicating whether the Driver Station requires the robot to be
* running in test mode.
*$
* Gets a value indicating whether the Driver Station requires the robot to be running in test
* mode.
*
* @return True if test mode should be enabled, false otherwise.
*/
public boolean isTest() {
@@ -474,20 +471,18 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Gets a value indicating whether the Driver Station requires the robot to be
* running in operator-controlled mode.
* Gets a value indicating whether the Driver Station requires the robot to be running in
* operator-controlled mode.
*
* @return True if operator-controlled mode should be enabled, false
* otherwise.
* @return True if operator-controlled mode should be enabled, false otherwise.
*/
public boolean isOperatorControl() {
return !(isAutonomous() || isTest());
}
/**
* Gets a value indicating whether the FPGA outputs are enabled. The outputs
* may be disabled if the robot is disabled or e-stopped, the watdhog has
* expired, or if the roboRIO browns out.
* Gets a value indicating whether the FPGA outputs are enabled. The outputs may be disabled if
* the robot is disabled or e-stopped, the watdhog has expired, or if the roboRIO browns out.
*
* @return True if the FPGA outputs are enabled.
*/
@@ -497,7 +492,7 @@ public class DriverStation implements RobotState.Interface {
/**
* Check if the system is browned out.
*$
*
* @return True if the system is browned out
*/
public boolean isBrownedOut() {
@@ -505,9 +500,9 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Has a new control packet from the driver station arrived since the last
* time this function was called?
*$
* Has a new control packet from the driver station arrived since the last time this function was
* called?
*
* @return True if the control data has been updated since the last call.
*/
public synchronized boolean isNewControlData() {
@@ -517,8 +512,8 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Get the current alliance from the FMS
*$
* Get the current alliance from the FMS.
*
* @return the current alliance
*/
public Alliance getAlliance() {
@@ -574,11 +569,10 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Is the driver station attached to a Field Management System? Note: This
* does not work with the Blue DS.
*$
* @return True if the robot is competing on a field being controlled by a
* Field Management System
* Is the driver station attached to a Field Management System? Note: This does not work with the
* Blue DS.
*
* @return True if the robot is competing on a field being controlled by a Field Management System
*/
public boolean isFMSAttached() {
HALControlWord controlWord = FRCNetworkCommunicationsLibrary.HALGetControlWord();
@@ -591,14 +585,12 @@ public class DriverStation implements RobotState.Interface {
}
/**
* 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 behaviour seen on the
* field.
*$
* 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 behaviour seen on the field.
*
* @return Time remaining in current match period (auto or teleop) in seconds
*/
public double getMatchTime() {
@@ -606,9 +598,9 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Report error to Driver Station. Also prints error to System.err Optionally
* appends Stack trace to error message
*$
* Report error to Driver Station. Also prints error to System.err Optionally appends Stack trace
* to error message.
*
* @param printTrace If true, append stack trace to error string
*/
public static void reportError(String error, boolean printTrace) {
@@ -616,25 +608,26 @@ public class DriverStation implements RobotState.Interface {
}
/**
* Report warning to Driver Station. Also prints error to System.err Optionally
* appends Stack trace to warning message
*$
* Report warning to Driver Station. Also prints error to System.err Optionally appends Stack
* trace to warning message.
*
* @param printTrace If true, append stack trace to warning string
*/
public static void reportWarning(String error, boolean printTrace) {
reportErrorImpl(false, 1, error, printTrace);
}
private static void reportErrorImpl(boolean is_error, int code, String error, boolean printTrace) {
private static void reportErrorImpl(boolean isError, int code, String error, boolean
printTrace) {
StackTraceElement[] traces = Thread.currentThread().getStackTrace();
String locString;
if (traces.length > 3)
if (traces.length > 3) {
locString = traces[3].toString();
else
} else {
locString = new String();
}
boolean haveLoc = false;
String traceString = new String();
traceString = " at ";
String traceString = " at ";
for (int i = 3; i < traces.length; i++) {
String loc = traces[i].toString();
traceString += loc + "\n";
@@ -644,48 +637,50 @@ public class DriverStation implements RobotState.Interface {
haveLoc = true;
}
}
FRCNetworkCommunicationsLibrary.HALSendError(is_error, code, false, error, locString, printTrace ? traceString : "", true);
FRCNetworkCommunicationsLibrary.HALSendError(isError, code, false, error, locString,
printTrace ? traceString : "", true);
}
/**
* Only to be used to tell the Driver Station what code you claim to be
* executing for diagnostic purposes only
*$
* @param entering If true, starting disabled code; if false, leaving disabled
* code
* Only to be used to tell the Driver Station what code you claim to be executing for diagnostic
* purposes only.
*
* @param entering If true, starting disabled code; if false, leaving disabled code
*/
@SuppressWarnings("MethodName")
public void InDisabled(boolean entering) {
m_userInDisabled = entering;
}
/**
* Only to be used to tell the Driver Station what code you claim to be
* executing for diagnostic purposes only
*$
* @param entering If true, starting autonomous code; if false, leaving
* autonomous code
* Only to be used to tell the Driver Station what code you claim to be executing for diagnostic
* purposes only.
*
* @param entering If true, starting autonomous code; if false, leaving autonomous code
*/
@SuppressWarnings("MethodName")
public void InAutonomous(boolean entering) {
m_userInAutonomous = entering;
}
/**
* Only to be used to tell the Driver Station what code you claim to be
* executing for diagnostic purposes only
*$
* @param entering If true, starting teleop code; if false, leaving teleop
* code
* Only to be used to tell the Driver Station what code you claim to be executing for diagnostic
* purposes only.
*
* @param entering If true, starting teleop code; if false, leaving teleop code
*/
@SuppressWarnings("MethodName")
public void InOperatorControl(boolean entering) {
m_userInTeleop = entering;
}
/**
* Only to be used to tell the Driver Station what code you claim to be
* executing for diagnostic purposes only
*$
* Only to be used to tell the Driver Station what code you claim to be executing for diagnostic
* purposes only.
*
* @param entering If true, starting test code; if false, leaving test code
*/
@SuppressWarnings("MethodName")
public void InTest(boolean entering) {
m_userInTest = entering;
}

View File

@@ -7,30 +7,27 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteOrder;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tInstances;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.hal.EncoderJNI;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
import edu.wpi.first.wpilibj.util.BoundaryException;
/**
* Class to read quad encoders. Quadrature encoders are devices that count shaft
* rotation and can sense direction. The output of the QuadEncoder class is an
* integer that can count either up or down, and can go negative for reverse
* direction counting. When creating QuadEncoders, a direction is supplied that
* changes the sense of the output to make code more readable if the encoder is
* mounted such that forward movement generates negative values. Quadrature
* encoders have two digital outputs, an A Channel and a B Channel that are out
* of phase with each other to allow the FPGA to do direction sensing.
* Class to read quad encoders. Quadrature encoders are devices that count shaft rotation and can
* sense direction. The output of the QuadEncoder class is an integer that can count either up or
* down, and can go negative for reverse direction counting. When creating QuadEncoders, a direction
* is supplied that changes the sense of the output to make code more readable if the encoder is
* mounted such that forward movement generates negative values. Quadrature encoders have two
* digital outputs, an A Channel and a B Channel that are out of phase with each other to allow the
* FPGA to do direction sensing.
*
* All encoders will immediately start counting - reset() them if you need them
* to be zeroed before use.
* <p>All encoders will immediately start counting - reset() them if you need them to be zeroed
* before use.
*/
public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveWindowSendable {
public enum IndexingType {
@@ -38,15 +35,17 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* The a source
* The a source.
*/
@SuppressWarnings("MemberName")
protected DigitalSource m_aSource; // the A phase of the quad encoder
/**
* The b source
* The b source.
*/
@SuppressWarnings("MemberName")
protected DigitalSource m_bSource; // the B phase of the quad encoder
/**
* The index source
* The index source.
*/
protected DigitalSource m_indexSource = null; // Index on some encoders
private long m_encoder;
@@ -54,27 +53,27 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
private double m_distancePerPulse; // distance of travel for each encoder
// tick
private Counter m_counter; // Counter object for 1x and 2x encoding
/**
* 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 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.
*/
private EncodingType m_encodingType = EncodingType.k4X;
private int m_encodingScale; // 1x, 2x, or 4x, per the encodingType
private int m_encodingScale; // 1x, 2x, or 4x, per the m_encodingType
private boolean m_allocatedA;
private boolean m_allocatedB;
private boolean m_allocatedI;
private PIDSourceType m_pidSource;
/**
* Common initialization code for Encoders. This code allocates resources for
* Encoders and is common to all constructors.
* Common initialization code for Encoders. This code allocates resources for Encoders and is
* common to all constructors.
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param reverseDirection If true, counts down instead of up (this is all
* relative)
* @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 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.
* @param reverseDirection If true, counts down instead of up (this is all relative)
*/
private void initEncoder(boolean reverseDirection) {
switch (m_encodingType) {
@@ -84,9 +83,9 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
// set the byte order
index.order(ByteOrder.LITTLE_ENDIAN);
m_encoder =
EncoderJNI.initializeEncoder((byte) m_aSource.getModuleForRouting(), m_aSource
.getChannelForRouting(), m_aSource.getAnalogTriggerForRouting(),
(byte) m_bSource.getModuleForRouting(), m_bSource.getChannelForRouting(),
EncoderJNI.initializeEncoder(m_aSource.getModuleForRouting(), m_aSource
.getChannelForRouting(), m_aSource.getAnalogTriggerForRouting(),
m_bSource.getModuleForRouting(), m_bSource.getChannelForRouting(),
m_bSource.getAnalogTriggerForRouting(),
reverseDirection, index.asIntBuffer());
m_index = index.asIntBuffer().get(0);
@@ -99,6 +98,8 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
m_counter = new Counter(m_encodingType, m_aSource, m_bSource, reverseDirection);
m_index = m_counter.getFPGAIndex();
break;
default:
throw new AssertionError("Illegal encoding type: " + m_encodingType);
}
m_distancePerPulse = 1.0;
m_pidSource = PIDSourceType.kDisplacement;
@@ -110,249 +111,249 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
/**
* Encoder constructor. Construct a Encoder given a and b channels.
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param aChannel The a channel DIO channel. 0-9 are on-board, 10-25 are on
* the MXP port
* @param bChannel 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.
* @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.
*/
public Encoder(final int aChannel, final int bChannel, boolean reverseDirection) {
public Encoder(final int channelA, final int channelB, boolean reverseDirection) {
m_allocatedA = true;
m_allocatedB = true;
m_allocatedI = false;
m_aSource = new DigitalInput(aChannel);
m_bSource = new DigitalInput(bChannel);
m_aSource = new DigitalInput(channelA);
m_bSource = new DigitalInput(channelB);
initEncoder(reverseDirection);
}
/**
* Encoder constructor. Construct a Encoder given a and b channels.
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param aChannel The a channel digital input channel.
* @param bChannel The b channel digital input channel.
* @param channelA The a channel digital input channel.
* @param channelB The b channel digital input channel.
*/
public Encoder(final int aChannel, final int bChannel) {
this(aChannel, bChannel, false);
public Encoder(final int channelA, final int channelB) {
this(channelA, channelB, false);
}
/**
* Encoder constructor. Construct a Encoder given a and b channels.
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param aChannel The a channel digital input channel.
* @param bChannel 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 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.
* @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.
*/
public Encoder(final int aChannel, final int bChannel, boolean reverseDirection,
final EncodingType encodingType) {
public Encoder(final int channelA, final int channelB, boolean reverseDirection,
final EncodingType encodingType) {
m_allocatedA = true;
m_allocatedB = true;
m_allocatedI = false;
if (encodingType == null)
if (encodingType == null) {
throw new NullPointerException("Given encoding type was null");
}
m_encodingType = encodingType;
m_aSource = new DigitalInput(aChannel);
m_bSource = new DigitalInput(bChannel);
m_aSource = new DigitalInput(channelA);
m_bSource = new DigitalInput(channelB);
initEncoder(reverseDirection);
}
/**
* Encoder constructor. Construct a Encoder given a and b channels. Using an
* index pulse forces 4x encoding
* Encoder constructor. Construct a Encoder given a and b channels. Using an index pulse forces 4x
* encoding
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param aChannel The a channel digital input channel.
* @param bChannel 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.
* @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.
*/
public Encoder(final int aChannel, final int bChannel, final int indexChannel,
boolean reverseDirection) {
public Encoder(final int channelA, final int channelB, final int indexChannel,
boolean reverseDirection) {
m_allocatedA = true;
m_allocatedB = true;
m_allocatedI = true;
m_aSource = new DigitalInput(aChannel);
m_bSource = new DigitalInput(bChannel);
m_aSource = new DigitalInput(channelA);
m_bSource = new DigitalInput(channelB);
m_indexSource = new DigitalInput(indexChannel);
initEncoder(reverseDirection);
setIndexSource(indexChannel);
}
/**
* Encoder constructor. Construct a Encoder given a and b channels. Using an
* index pulse forces 4x encoding
* Encoder constructor. Construct a Encoder given a and b channels. Using an index pulse forces 4x
* encoding
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param aChannel The a channel digital input channel.
* @param bChannel 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 aChannel, final int bChannel, final int indexChannel) {
this(aChannel, bChannel, indexChannel, false);
public Encoder(final int channelA, final int channelB, final int indexChannel) {
this(channelA, channelB, indexChannel, false);
}
/**
* Encoder constructor. Construct a Encoder given a and b channels as digital
* inputs. This is used in the case where the digital inputs are shared. The
* Encoder class will not allocate the digital inputs and assume that they
* already are counted.
* Encoder constructor. Construct a Encoder given a and b channels as digital inputs. This is used
* in the case where the digital inputs are shared. The Encoder class will not allocate the
* digital inputs and assume that they already are counted.
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param aSource The source that should be used for the a channel.
* @param bSource 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 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.
*/
public Encoder(DigitalSource aSource, DigitalSource bSource, boolean reverseDirection) {
public Encoder(DigitalSource sourceA, DigitalSource sourceB, boolean reverseDirection) {
m_allocatedA = false;
m_allocatedB = false;
m_allocatedI = false;
if (aSource == null)
if (sourceA == null) {
throw new NullPointerException("Digital Source A was null");
m_aSource = aSource;
if (bSource == null)
}
m_aSource = sourceA;
if (sourceB == null) {
throw new NullPointerException("Digital Source B was null");
m_bSource = bSource;
}
m_bSource = sourceB;
initEncoder(reverseDirection);
}
/**
* Encoder constructor. Construct a Encoder given a and b channels as digital
* inputs. This is used in the case where the digital inputs are shared. The
* Encoder class will not allocate the digital inputs and assume that they
* already are counted.
* Encoder constructor. Construct a Encoder given a and b channels as digital inputs. This is used
* in the case where the digital inputs are shared. The Encoder class will not allocate the
* digital inputs and assume that they already are counted.
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param aSource The source that should be used for the a channel.
* @param bSource 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.
*/
public Encoder(DigitalSource aSource, DigitalSource bSource) {
this(aSource, bSource, false);
public Encoder(DigitalSource sourceA, DigitalSource sourceB) {
this(sourceA, sourceB, false);
}
/**
* Encoder constructor. Construct a Encoder given a and b channels as digital
* inputs. This is used in the case where the digital inputs are shared. The
* Encoder class will not allocate the digital inputs and assume that they
* already are counted.
* Encoder constructor. Construct a Encoder given a and b channels as digital inputs. This is used
* in the case where the digital inputs are shared. The Encoder class will not allocate the
* digital inputs and assume that they already are counted.
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param aSource The source that should be used for the a channel.
* @param bSource 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 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.
* @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.
*/
public Encoder(DigitalSource aSource, DigitalSource bSource, boolean reverseDirection,
final EncodingType encodingType) {
public Encoder(DigitalSource sourceA, DigitalSource sourceB, boolean reverseDirection,
final EncodingType encodingType) {
m_allocatedA = false;
m_allocatedB = false;
m_allocatedI = false;
if (encodingType == null)
if (encodingType == null) {
throw new NullPointerException("Given encoding type was null");
}
m_encodingType = encodingType;
if (aSource == null)
if (sourceA == null) {
throw new NullPointerException("Digital Source A was null");
m_aSource = aSource;
if (bSource == null)
}
m_aSource = sourceA;
if (sourceB == null) {
throw new NullPointerException("Digital Source B was null");
m_aSource = aSource;
m_bSource = bSource;
}
m_aSource = sourceA;
m_bSource = sourceB;
initEncoder(reverseDirection);
}
/**
* Encoder constructor. Construct a Encoder given a, b and index channels as
* digital inputs. This is used in the case where the digital inputs are
* shared. The Encoder class will not allocate the digital inputs and assume
* that they already are counted.
* Encoder constructor. Construct a Encoder given a, b and index channels as digital inputs. This
* is used in the case where the digital inputs are shared. The Encoder class will not allocate
* the digital inputs and assume that they already are counted.
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param aSource The source that should be used for the a channel.
* @param bSource 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.
* @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.
*/
public Encoder(DigitalSource aSource, DigitalSource bSource, DigitalSource indexSource,
boolean reverseDirection) {
public Encoder(DigitalSource sourceA, DigitalSource sourceB, DigitalSource indexSource,
boolean reverseDirection) {
m_allocatedA = false;
m_allocatedB = false;
m_allocatedI = false;
if (aSource == null)
if (sourceB == null) {
throw new NullPointerException("Digital Source A was null");
m_aSource = aSource;
if (bSource == null)
}
m_aSource = sourceA;
if (sourceB == null) {
throw new NullPointerException("Digital Source B was null");
m_aSource = aSource;
m_bSource = bSource;
}
m_aSource = sourceA;
m_bSource = sourceB;
m_indexSource = indexSource;
initEncoder(reverseDirection);
setIndexSource(indexSource);
}
/**
* Encoder constructor. Construct a Encoder given a, b and index channels as
* digital inputs. This is used in the case where the digital inputs are
* shared. The Encoder class will not allocate the digital inputs and assume
* that they already are counted.
* Encoder constructor. Construct a Encoder given a, b and index channels as digital inputs. This
* is used in the case where the digital inputs are shared. The Encoder class will not allocate
* the digital inputs and assume that they already are counted.
*
* The encoder will start counting immediately.
* <p>The encoder will start counting immediately.
*
* @param aSource The source that should be used for the a channel.
* @param bSource 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 aSource, DigitalSource bSource, DigitalSource indexSource) {
this(aSource, bSource, indexSource, false);
public Encoder(DigitalSource sourceA, DigitalSource sourceB, DigitalSource indexSource) {
this(sourceA, sourceB, indexSource, false);
}
/**
* @return the Encoder's FPGA index
* @return The Encoder's FPGA index.
*/
@SuppressWarnings("AbbreviationAsWordInName")
public int getFPGAIndex() {
return m_index;
}
/**
* @return the encoding scale factor 1x, 2x, or 4x, per the requested
* encodingType. Used to divide raw edge counts down to spec'd counts.
* Used to divide raw edge counts down to spec'd counts.
*
* @return The encoding scale factor 1x, 2x, or 4x, per the requested encoding type.
*/
public int getEncodingScale() {
return m_encodingScale;
}
/**
* Free the resources used by this object.
*/
public void free() {
if (m_aSource != null && m_allocatedA) {
m_aSource.free();
@@ -379,8 +380,8 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* Gets the raw value from the encoder. The raw value is the actual count
* unscaled by the 1x, 2x, or 4x scale factor.
* Gets the raw value from the encoder. The raw value is the actual count unscaled by the 1x, 2x,
* or 4x scale factor.
*
* @return Current raw count from the encoder
*/
@@ -395,19 +396,17 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* Gets the current count. Returns the current count on the Encoder. This
* method compensates for the decoding type.
* Gets the current count. Returns the current count on the Encoder. This method compensates for
* the decoding type.
*
* @return Current count from the Encoder adjusted for the 1x, 2x, or 4x scale
* factor.
* @return Current count from the Encoder adjusted for the 1x, 2x, or 4x scale factor.
*/
public int get() {
return (int) (getRaw() * decodingScaleFactor());
}
/**
* 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.
*/
public void reset() {
if (m_counter != null) {
@@ -418,15 +417,14 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* Returns the period of the most recent pulse. Returns the period of the most
* recent Encoder pulse in seconds. This method compensates for the decoding
* type.
* Returns the period of the most recent pulse. Returns the period of the most recent Encoder
* pulse in seconds. This method compensates for the decoding type.
*
* @deprecated Use getRate() in favor of this method. This returns unscaled
* periods and getRate() scales using value from
* setDistancePerPulse().
* <p></p><b>Warning:</b> This returns unscaled periods and getRate() scales using value from
* setDistancePerPulse().
*
* @return Period in seconds of the most recent pulse.
* @deprecated Use getRate() in favor of this method.
*/
public double getPeriod() {
double measuredPeriod;
@@ -439,16 +437,13 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* Sets the maximum period for stopped detection. Sets the value that
* represents the maximum period of the Encoder before it will assume that the
* attached device is stopped. This timeout allows users to determine if the
* wheels or other shaft has stopped rotating. This method compensates for the
* decoding type.
* Sets the maximum period for stopped detection. Sets the value that represents the maximum
* period of the Encoder before it will assume that the attached device is stopped. This timeout
* allows users to determine if the wheels or other shaft has stopped rotating. This method
* 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.
* @param maxPeriod The maximum time between rising and falling edges before the FPGA will report
* the device stopped. This is expressed in seconds.
*/
public void setMaxPeriod(double maxPeriod) {
if (m_counter != null) {
@@ -459,10 +454,9 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* Determine if the encoder is stopped. Using the MaxPeriod value, a boolean
* is returned that is true if the encoder is considered stopped and false if
* it is still moving. A stopped encoder is one where the most recent pulse
* width exceeds the MaxPeriod.
* Determine if the encoder is stopped. Using the MaxPeriod value, a boolean is returned that is
* true if the encoder is considered stopped and false if it is still moving. A stopped encoder is
* one where the most recent pulse width exceeds the MaxPeriod.
*
* @return True if the encoder is considered stopped.
*/
@@ -488,8 +482,7 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* The scale needed to convert a raw counter value into a number of encoder
* pulses.
* The scale needed to convert a raw counter value into a number of encoder pulses.
*/
private double decodingScaleFactor() {
switch (m_encodingType) {
@@ -506,18 +499,18 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* Get the distance the robot has driven since the last reset.
* Get the distance the robot has driven since the last reset as scaled by the value from {@link
* #setDistancePerPulse(double)}.
*
* @return The distance driven since the last reset as scaled by the value
* from setDistancePerPulse().
* @return The distance driven since the last reset
*/
public double getDistance() {
return getRaw() * decodingScaleFactor() * m_distancePerPulse;
}
/**
* Get the current rate of the encoder. Units are distance per second as
* scaled by the value from setDistancePerPulse().
* Get the current rate of the encoder. Units are distance per second as scaled by the value from
* setDistancePerPulse().
*
* @return The current rate of the encoder.
*/
@@ -528,51 +521,42 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
/**
* 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().
* @param minRate The minimum rate. The units are in distance per second as scaled by the value
* from setDistancePerPulse().
*/
public void setMinRate(double minRate) {
setMaxPeriod(m_distancePerPulse / minRate);
}
/**
* Set the distance per pulse for this encoder. This sets the multiplier used
* to determine the distance driven based on the count value from the encoder.
* Do not include the decoding type in this scale. The library already
* compensates for the decoding type. Set this value based on the encoder's
* rated Pulses per Revolution 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 pulse for this encoder. This sets the multiplier used to determine the
* distance driven based on the count value from the encoder. Do not include the decoding type in
* this scale. The library already compensates for the decoding type. Set this value based on the
* encoder's rated Pulses per Revolution and factor in gearing reductions following the encoder
* shaft. This distance can be in any units you like, linear or angular.
*
* @param distancePerPulse The scale factor that will be used to convert
* pulses to useful units.
* @param distancePerPulse The scale factor that will be used to convert pulses to useful units.
*/
public void setDistancePerPulse(double distancePerPulse) {
m_distancePerPulse = distancePerPulse;
}
/**
* Set the direction sensing for this encoder. This sets the direction sensing
* on the encoder so that it could count in the correct software direction
* regardless of the mounting.
* Set the direction sensing for this encoder. This sets the direction sensing on the encoder so
* that it could count in the correct software direction regardless of the mounting.
*
* @param reverseDirection true if the encoder direction should be reversed
*/
public void setReverseDirection(boolean reverseDirection) {
if (m_counter != null) {
m_counter.setReverseDirection(reverseDirection);
} else {
}
}
/**
* Set the Samples to Average which specifies the number of samples of the
* timer to average when calculating the period. Perform averaging to account
* for mechanical imperfections or as oversampling to increase resolution.
*
* TODO: Should this throw a checked exception, so that the user has to deal
* with giving an incorrect value?
* Set the Samples to Average which specifies the number of samples of the timer to average when
* calculating the period. Perform averaging to account for mechanical imperfections or as
* oversampling to increase resolution.
*
* @param samplesToAverage The number of samples to average from 1 to 127.
*/
@@ -584,17 +568,18 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
case k1X:
case k2X:
m_counter.setSamplesToAverage(samplesToAverage);
break;
break;
default:
throw new AssertionError("Illegal encoding type: " + m_encodingType);
}
}
/**
* Get the Samples to Average which specifies the number of samples of the
* timer to average when calculating the period. Perform averaging to account
* for mechanical imperfections or as oversampling to increase resolution.
* Get the Samples to Average which specifies the number of samples of the timer to average when
* calculating the period. Perform averaging to account for mechanical imperfections or as
* oversampling to increase resolution.
*
* @return SamplesToAverage The number of samples being averaged (from 1 to
* 127)
* @return SamplesToAverage The number of samples being averaged (from 1 to 127)
*/
public int getSamplesToAverage() {
switch (m_encodingType) {
@@ -603,13 +588,14 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
case k1X:
case k2X:
return m_counter.getSamplesToAverage();
default:
return 1;
}
return 1;
}
/**
* Set which parameter of the encoder you are using as a process control
* variable. The encoder class supports the rate and distance parameters.
* Set which parameter of the encoder you are using as a process control variable. The encoder
* class supports the rate and distance parameters.
*
* @param pidSource An enum to select the parameter.
*/
@@ -617,9 +603,7 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
m_pidSource = pidSource;
}
/**
* {@inheritDoc}
*/
@Override
public PIDSourceType getPIDSourceType() {
return m_pidSource;
}
@@ -641,11 +625,31 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* Set the index source for the encoder. When this source rises, the encoder
* count automatically resets.
* Set the index source for the encoder. When this source is activated, the encoder count
* automatically resets.
*
* @param channel A DIO channel to set as the encoder index
* @param type The state that will cause the encoder to reset
*/
public void setIndexSource(int channel) {
setIndexSource(channel, IndexingType.kResetOnRisingEdge);
}
/**
* Set the index source for the encoder. When this source is activated, the encoder count
* automatically resets.
*
* @param source A digital source to set as the encoder index
*/
public void setIndexSource(DigitalSource source) {
setIndexSource(source, IndexingType.kResetOnRisingEdge);
}
/**
* Set the index source for the encoder. When this source rises, the encoder count automatically
* resets.
*
* @param channel A DIO channel to set as the encoder index
* @param type The state that will cause the encoder to reset
*/
public void setIndexSource(int channel, IndexingType type) {
boolean activeHigh =
@@ -657,21 +661,11 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* Set the index source for the encoder. When this source is activated, the
* encoder count automatically resets.
*
* @param channel A DIO channel to set as the encoder index
*/
public void setIndexSource(int channel) {
this.setIndexSource(channel, IndexingType.kResetOnRisingEdge);
}
/**
* Set the index source for the encoder. When this source rises, the encoder
* count automatically resets.
* Set the index source for the encoder. When this source rises, the encoder count automatically
* 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) {
boolean activeHigh =
@@ -684,16 +678,6 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
/**
* Set the index source for the encoder. When this source is activated, the
* encoder count automatically resets.
*
* @param source A digital source to set as the encoder index
*/
public void setIndexSource(DigitalSource source) {
this.setIndexSource(source, IndexingType.kResetOnRisingEdge);
}
/*
* Live Window code, only does anything if live window is activated.
*/
public String getSmartDashboardType() {
@@ -707,24 +691,18 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
private ITable m_table;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("Speed", getRate());
@@ -733,13 +711,11 @@ public class Encoder extends SensorBase implements CounterBase, PIDSource, LiveW
}
}
/**
* {@inheritDoc}
*/
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
/**
* {@inheritDoc}
*/
public void stopLiveWindowMode() {}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -12,10 +12,9 @@ import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* Alias for counter class. Implement the gear tooth sensor supplied by FIRST.
* Currently there is no reverse sensing on the gear tooth sensor, but in future
* versions we might implement the necessary timing in the FPGA to sense
* direction.
* Alias for counter class. Implement the gear tooth sensor supplied by FIRST. Currently there is no
* reverse sensing on the gear tooth sensor, but in future versions we might implement the necessary
* timing in the FPGA to sense direction.
*/
public class GearTooth extends Counter {
@@ -33,7 +32,7 @@ public class GearTooth extends Counter {
/**
* Construct a GearTooth sensor given a channel.
*
* No direction sensing is assumed.
* <p>No direction sensing is assumed.
*
* @param channel The GPIO channel that the sensor is connected to.
*/
@@ -44,10 +43,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 directionSensitive True to enable the pulse length decoding in
* hardware to specify count direction.
* @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.
*/
public GearTooth(final int channel, boolean directionSensitive) {
super(channel);
@@ -61,12 +60,12 @@ public class GearTooth extends Counter {
}
/**
* Construct a GearTooth sensor given a digital input. This should be used
* when sharing digital inputs.
* 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 directionSensitive True to enable the pulse length decoding in
* hardware to specify count direction.
* @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.
*/
public GearTooth(DigitalSource source, boolean directionSensitive) {
super(source);
@@ -74,13 +73,12 @@ public class GearTooth extends Counter {
}
/**
* Construct a GearTooth sensor given a digital input. This should be used
* when sharing digial inputs.
* Construct a GearTooth sensor given a digital input. This should be used when sharing digial
* inputs.
*
* No direction sensing is assumed.
* <p>No direction sensing is assumed.
*
* @param source An object that fully descibes the input that the sensor is
* connected to.
* @param source An object that fully descibes the input that the sensor is connected to.
*/
public GearTooth(DigitalSource source) {
this(source, false);

View File

@@ -7,7 +7,6 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteOrder;
import java.nio.ByteBuffer;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
@@ -18,38 +17,38 @@ import edu.wpi.first.wpilibj.util.BoundaryException;
/**
* I2C bus interface class.
*
* This class is intended to be used by sensor (and other I2C device) drivers.
* It probably should not be used directly.
*
* <p>This class is intended to be used by sensor (and other I2C device) drivers. It probably should
* not be used directly.
*/
public class I2C extends SensorBase {
public enum Port {
kOnboard(0), kMXP(1);
private int value;
private int m_value;
private Port(int value) {
this.value = value;
Port(int value) {
m_value = value;
}
public int getValue() {
return this.value;
return m_value;
}
};
}
private Port m_port;
private int m_deviceAddress;
private final Port m_port;
private final int m_deviceAddress;
/**
* 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) {
m_port = port;
m_deviceAddress = deviceAddress;
I2CJNI.i2CInitialize((byte) m_port.getValue());
I2CJNI.i2CInitialize((byte) port.getValue());
UsageReporting.report(tResourceType.kResourceType_I2C, deviceAddress);
}
@@ -57,23 +56,24 @@ public class I2C extends SensorBase {
/**
* Destructor.
*/
public void free() {}
public void free() {
}
/**
* Generic transaction.
*
* This is a lower-level interface to the I2C hardware giving you more control
* over each transaction.
* <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.
*/
public synchronized boolean transaction(byte[] dataToSend, int sendSize, byte[] dataReceived,
int receiveSize) {
int status = -1;
public synchronized boolean transaction(byte[] dataToSend, int sendSize,
byte[] dataReceived, int receiveSize) {
final int status;
ByteBuffer dataToSendBuffer = ByteBuffer.allocateDirect(sendSize);
if (sendSize > 0 && dataToSend != null) {
@@ -81,9 +81,10 @@ public class I2C extends SensorBase {
}
ByteBuffer dataReceivedBuffer = ByteBuffer.allocateDirect(receiveSize);
status =
I2CJNI.i2CTransaction((byte) m_port.getValue(), (byte) m_deviceAddress, dataToSendBuffer,
(byte) sendSize, dataReceivedBuffer, (byte) receiveSize);
status = I2CJNI
.i2CTransaction((byte) m_port.getValue(), (byte) m_deviceAddress,
dataToSendBuffer, (byte) sendSize, dataReceivedBuffer,
(byte) receiveSize);
if (receiveSize > 0 && dataReceived != null) {
dataReceivedBuffer.get(dataReceived);
}
@@ -93,54 +94,58 @@ public class I2C extends SensorBase {
/**
* Generic transaction.
*
* This is a lower-level interface to the I2C hardware giving you more control
* over each transaction.
* <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. Must
* be allocated using ByteBuffer.allocateDirect().
* @param sendSize Number of bytes to send as part of the transaction.
* @param dataReceived Buffer to read data into. Must be allocated using
* ByteBuffer.allocateDirect().
* @param receiveSize Number of bytes to read from the device.
* @param dataToSend Buffer of data to send as part of the transaction. Must be allocated using
* ByteBuffer.allocateDirect().
* @param sendSize Number of bytes to send as part of the transaction.
* @param dataReceived Buffer to read data into. Must be allocated using {@link
* ByteBuffer#allocateDirect(int)}.
* @param receiveSize Number of bytes to read from the device.
* @return Transfer Aborted... false for success, true for aborted.
*/
public synchronized boolean transaction(ByteBuffer dataToSend, int sendSize, ByteBuffer dataReceived,
int receiveSize) {
boolean aborted = true;
if (!dataToSend.isDirect())
public synchronized boolean transaction(ByteBuffer dataToSend, int sendSize,
ByteBuffer dataReceived, int receiveSize) {
if (!dataToSend.isDirect()) {
throw new IllegalArgumentException("dataToSend must be a direct buffer");
if (dataToSend.capacity() < sendSize)
}
if (dataToSend.capacity() < sendSize) {
throw new IllegalArgumentException("dataToSend is too small, must be at least " + sendSize);
if (!dataReceived.isDirect())
}
if (!dataReceived.isDirect()) {
throw new IllegalArgumentException("dataReceived must be a direct buffer");
if (dataReceived.capacity() < receiveSize)
throw new IllegalArgumentException("dataReceived is too small, must be at least " + receiveSize);
}
if (dataReceived.capacity() < receiveSize) {
throw new IllegalArgumentException(
"dataReceived is too small, must be at least " + receiveSize);
}
return I2CJNI.i2CTransaction((byte) m_port.getValue(), (byte) m_deviceAddress, dataToSend, (byte) sendSize, dataReceived, (byte) receiveSize) < receiveSize;
return I2CJNI
.i2CTransaction((byte) m_port.getValue(), (byte) m_deviceAddress,
dataToSend, (byte) sendSize, dataReceived, (byte) receiveSize)
< receiveSize;
}
/**
* Attempt to address a device on the I2C bus.
*
* This allows you to figure out if there is a device on the I2C bus that
* responds to the address specified in the constructor.
* <p>This allows you to figure out if there is a device on the I2C bus that responds to the
* address specified in the constructor.
*
* @return Transfer Aborted... false for success, true for aborted.
*/
public boolean addressOnly() {
return transaction((byte[]) null, (byte) 0, (byte[]) null, (byte) 0);
return transaction((byte[]) null, (byte) 0, null, (byte) 0);
}
/**
* Execute a write transaction with the device.
*
* Write a single byte to a register on a device and wait until the
* transaction is complete.
* <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 registerAddress The address of the register on the device to be written.
* @param data The byte to write to the register on the device.
*/
public synchronized boolean write(int registerAddress, int data) {
byte[] buffer = new byte[2];
@@ -150,15 +155,14 @@ public class I2C extends SensorBase {
ByteBuffer dataToSendBuffer = ByteBuffer.allocateDirect(2);
dataToSendBuffer.put(buffer);
return I2CJNI.i2CWrite((byte) m_port.getValue(), (byte) m_deviceAddress, dataToSendBuffer,
(byte) buffer.length) < buffer.length;
return I2CJNI.i2CWrite((byte) m_port.getValue(), (byte) m_deviceAddress,
dataToSendBuffer, (byte) buffer.length) < buffer.length;
}
/**
* Execute a write transaction with the device.
*
* Write multiple bytes to a register on a device and wait until the
* transaction is complete.
* <p>Write multiple bytes to a register on a device and wait until the transaction is complete.
*
* @param data The data to write to the device.
*/
@@ -166,46 +170,44 @@ public class I2C extends SensorBase {
ByteBuffer dataToSendBuffer = ByteBuffer.allocateDirect(data.length);
dataToSendBuffer.put(data);
return I2CJNI.i2CWrite((byte) m_port.getValue(), (byte) m_deviceAddress, dataToSendBuffer,
(byte) data.length) < data.length;
return I2CJNI.i2CWrite((byte) m_port.getValue(), (byte) m_deviceAddress,
dataToSendBuffer, (byte) data.length) < data.length;
}
/**
* Execute a write transaction with the device.
*
* Write multiple bytes to a register on a device and wait until the
* transaction is complete.
* <p>Write multiple bytes to a register on a device and wait until the transaction is complete.
*
* @param data The data to write to the device. Must be created using
* ByteBuffer.allocateDirect().
* @param data The data to write to the device. Must be created using ByteBuffer.allocateDirect().
*/
public synchronized boolean writeBulk(ByteBuffer data, int size) {
if (!data.isDirect())
if (!data.isDirect()) {
throw new IllegalArgumentException("must be a direct buffer");
if (data.capacity() < size)
throw new IllegalArgumentException("buffer is too small, must be at least " + size);
}
if (data.capacity() < size) {
throw new IllegalArgumentException(
"buffer is too small, must be at least " + size);
}
return I2CJNI.i2CWrite((byte) m_port.getValue(), (byte) m_deviceAddress, data,
(byte) size) < size;
return I2CJNI.i2CWrite((byte) m_port.getValue(), (byte) m_deviceAddress,
data, (byte) size) < size;
}
/**
* Execute a read transaction with the device.
*
* Read bytes from a device. Most I2C devices will auto-increment the
* register pointer internally allowing you to read consecutive
* registers on a device in a single transaction.
* <p>Read bytes from a device. Most I2C devices will auto-increment the register pointer
* 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) {
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 == null) {
@@ -220,26 +222,26 @@ public class I2C extends SensorBase {
/**
* Execute a read transaction with the device.
*
* Read bytes from a device. Most I2C devices will auto-increment the
* register pointer internally allowing you to read consecutive
* registers on a device in a single transaction.
* <p>Read bytes from a device. Most I2C devices will auto-increment the register pointer
* 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. Must be
* created using ByteBuffer.allocateDirect().
* @param count The number of bytes to read in the transaction.
* @param buffer A buffer to store the data read from the device. Must be created using
* ByteBuffer.allocateDirect().
* @return Transfer Aborted... false for success, true for aborted.
*/
public boolean read(int registerAddress, int count, ByteBuffer buffer) {
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.isDirect())
if (!buffer.isDirect()) {
throw new IllegalArgumentException("must be a direct buffer");
if (buffer.capacity() < count)
}
if (buffer.capacity() < count) {
throw new IllegalArgumentException("buffer is too small, must be at least " + count);
}
ByteBuffer dataToSendBuffer = ByteBuffer.allocateDirect(1);
dataToSendBuffer.put(0, (byte) registerAddress);
@@ -250,18 +252,15 @@ public class I2C extends SensorBase {
/**
* Execute a read only transaction with the device.
*
* Read bytes from a device. This method does not write any data to prompt
* the device.
* <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 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.
* @return Transfer Aborted... false for success, true for aborted.
*/
public boolean readOnly(byte[] 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 == null) {
@@ -270,8 +269,8 @@ public class I2C extends SensorBase {
ByteBuffer dataReceivedBuffer = ByteBuffer.allocateDirect(count);
int retVal =
I2CJNI.i2CRead((byte) m_port.getValue(), (byte) m_deviceAddress, dataReceivedBuffer,
int retVal = I2CJNI
.i2CRead((byte) m_port.getValue(), (byte) m_deviceAddress, dataReceivedBuffer,
(byte) count);
dataReceivedBuffer.get(buffer);
return retVal < count;
@@ -280,61 +279,62 @@ public class I2C extends SensorBase {
/**
* Execute a read only transaction with the device.
*
* Read bytes from a device. This method does not write any data to prompt
* the device.
* <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. Must be created using ByteBuffer.allocateDirect().
* @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. Must be
* created using ByteBuffer.allocateDirect().
* @param count The number of bytes to read in the transaction.
* @return Transfer Aborted... false for success, true for aborted.
*/
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.isDirect())
if (!buffer.isDirect()) {
throw new IllegalArgumentException("must be a direct buffer");
if (buffer.capacity() < count)
}
if (buffer.capacity() < count) {
throw new IllegalArgumentException("buffer is too small, must be at least " + count);
}
return I2CJNI.i2CRead((byte) m_port.getValue(), (byte) m_deviceAddress, buffer,
(byte) count) < count;
return I2CJNI
.i2CRead((byte) m_port.getValue(), (byte) m_deviceAddress, buffer, (byte) count) < count;
}
/**
* Send a broadcast write to all devices on the I2C bus.
*
* This is not currently implemented!
* <p>This is not currently implemented!
*
* @param registerAddress The register to write on all devices on the bus.
* @param data The value to write to the devices.
* @param data The value to write to the devices.
*/
public void broadcast(int registerAddress, int data) {}
public void broadcast(int registerAddress, int data) {
}
/**
* Verify that a device's registers contain expected values.
*
* Most devices will have a set of registers that contain a known value that
* can be used to identify them. This allows an I2C device driver to easily
* verify that the device contains the expected value.
*
* @pre The device must support and be configured to use register
* auto-increment.
* <p>Most devices will have a set of registers that contain a known value that can be used to
* identify them. This allows an I2C device driver to easily verify that the device contains the
* 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
ByteBuffer dataToSendBuffer = ByteBuffer.allocateDirect(1);
ByteBuffer deviceData = ByteBuffer.allocateDirect(4);
for (int i = 0, curRegisterAddress = registerAddress; i < count; i += 4, curRegisterAddress +=
4) {
for (int i = 0, curRegisterAddress = registerAddress;
i < count; i += 4, curRegisterAddress += 4) {
int toRead = count - i < 4 ? count - i : 4;
// Read the chunk of data. Return false if the sensor does not
// respond.

View File

@@ -11,21 +11,19 @@ import edu.wpi.first.wpilibj.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.
* 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)}
* @author Jonathan Leitschuh
*
* @param <T> The type of the parameter that should be returned to the the
* method {@link #interruptFired(int, Object)}
*/
public abstract class InterruptHandlerFunction<T> {
/**
* The entry point for the interrupt. When the interrupt fires the
* {@link #apply(int, Object)} method is called. The outer class is provided
* as an interface to allow the implementer to pass a generic object to the
* interrupt fired method.
*$
* The entry point for the interrupt. When the interrupt fires the {@link #apply(int, Object)}
* method is called. The outer class is provided as an interface to allow the implementer to pass
* a generic object to the interrupt fired method.
*
* @author Jonathan Leitschuh
*/
private class Function implements InterruptJNIHandlerFunction {
@@ -36,25 +34,23 @@ public abstract class InterruptHandlerFunction<T> {
}
}
final Function function = new Function();
final Function m_function = new Function();
/**
* 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 when
* {@link InterruptableSensorBase#requestInterrupts(InterruptHandlerFunction)}
* is run.
*$
* 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
* when {@link InterruptableSensorBase#requestInterrupts(InterruptHandlerFunction)} is run.
*
* @return The object that should be passed to the interrupt when it runs
*/
public T overridableParameter() {

View File

@@ -12,15 +12,18 @@ import edu.wpi.first.wpilibj.util.AllocationException;
import edu.wpi.first.wpilibj.util.CheckedAllocationException;
/**
* Base for sensors to be used with interrupts
* Base for sensors to be used with interrupts.
*/
public abstract class InterruptableSensorBase extends SensorBase {
public static enum WaitResult {
@SuppressWarnings("JavadocMethod")
public enum WaitResult {
kTimeout(0x0), kRisingEdge(0x1), kFallingEdge(0x100), kBoth(0x101);
@SuppressWarnings("MemberName")
public final int value;
@SuppressWarnings("JavadocMethod")
public static WaitResult valueOf(int value) {
for (WaitResult mode : values()) {
if (mode.value == value) {
@@ -31,48 +34,54 @@ public abstract class InterruptableSensorBase extends SensorBase {
}
private WaitResult(int value) {
WaitResult(int value) {
this.value = value;
}
}
/**
* The interrupt resource
* The interrupt resource.
*/
protected long m_interrupt = 0;
/**
* Flags if the interrupt being allocated is synchronous
* Flags if the interrupt being allocated is synchronous.
*/
protected boolean m_isSynchronousInterrupt = false;
/**
* The index of the interrupt
* The index of the interrupt.
*/
protected int m_interruptIndex;
/**
* Resource manager
* Resource manager.
*/
protected static Resource interrupts = new Resource(8);
protected static Resource m_interrupts = new Resource(8);
/**
* Create a new InterrupatableSensorBase
* Create a new InterrupatableSensorBase.
*/
public InterruptableSensorBase() {
m_interrupt = 0;
}
/**
* @return true if this is an analog trigger
* If this is an analog trigger.
*
* @return true if this is an analog trigger.
*/
abstract boolean getAnalogTriggerForRouting();
/**
* The channel routing number.
*
* @return channel routing number
*/
abstract int getChannelForRouting();
/**
* The modules routing number.
*
* @return module routing number
*/
abstract byte getModuleForRouting();
@@ -80,12 +89,11 @@ public abstract class InterruptableSensorBase extends SensorBase {
/**
* 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.
* @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.
*/
public void requestInterrupts(InterruptHandlerFunction<?> handler) {
if (m_interrupt != 0) {
@@ -99,15 +107,14 @@ public abstract class InterruptableSensorBase extends SensorBase {
InterruptJNI.requestInterrupts(m_interrupt, getModuleForRouting(), getChannelForRouting(),
getAnalogTriggerForRouting());
setUpSourceEdge(true, false);
InterruptJNI.attachInterruptHandler(m_interrupt, handler.function,
InterruptJNI.attachInterruptHandler(m_interrupt, handler.m_function,
handler.overridableParameter());
}
/**
* Request one of the 8 interrupts synchronously on this digital input.
* Request interrupts in synchronous mode where the user program will have to
* explicitly wait for the interrupt to occur using {@link #waitForInterrupt}.
* The default is interrupt on rising edges only.
* Request one of the 8 interrupts synchronously on this digital input. Request interrupts in
* synchronous mode where the user program will have to explicitly wait for the interrupt to occur
* using {@link #waitForInterrupt}. The default is interrupt on rising edges only.
*/
public void requestInterrupts() {
if (m_interrupt != 0) {
@@ -127,14 +134,13 @@ public abstract class InterruptableSensorBase extends SensorBase {
/**
* 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.
* @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.
*/
protected void allocateInterrupts(boolean watcher) {
try {
m_interruptIndex = interrupts.allocate();
} catch (CheckedAllocationException e) {
m_interruptIndex = m_interrupts.allocate();
} catch (CheckedAllocationException ex) {
throw new AllocationException("No interrupts are left to be allocated");
}
m_isSynchronousInterrupt = watcher;
@@ -144,8 +150,8 @@ public abstract class InterruptableSensorBase extends SensorBase {
}
/**
* Cancel interrupts on this device. This deallocates all the chipobject
* structures and disables any interrupts.
* Cancel interrupts on this device. This deallocates all the chipobject structures and disables
* any interrupts.
*/
public void cancelInterrupts() {
if (m_interrupt == 0) {
@@ -153,15 +159,15 @@ public abstract class InterruptableSensorBase extends SensorBase {
}
InterruptJNI.cleanInterrupts(m_interrupt);
m_interrupt = 0;
interrupts.free(m_interruptIndex);
m_interrupts.free(m_interruptIndex);
}
/**
* In synchronous mode, wait for the defined interrupt to occur.
*
* @param timeout Timeout in seconds
* @param ignorePrevious If true, ignore interrupts that happened before
* waitForInterrupt was called.
* @param timeout Timeout in seconds
* @param ignorePrevious If true, ignore interrupts that happened before waitForInterrupt was
* called.
* @return Result of the wait.
*/
public WaitResult waitForInterrupt(double timeout, boolean ignorePrevious) {
@@ -184,9 +190,9 @@ public abstract class InterruptableSensorBase extends SensorBase {
}
/**
* Enable interrupts to occur on this input. Interrupts are disabled when the
* RequestInterrupt call is made. This gives time to do the setup of the other
* options before starting to field interrupts.
* Enable interrupts to occur on this input. Interrupts are disabled when the RequestInterrupt
* call is made. This gives time to do the setup of the other options before starting to field
* interrupts.
*/
public void enableInterrupts() {
if (m_interrupt == 0) {
@@ -212,10 +218,10 @@ public abstract class InterruptableSensorBase extends SensorBase {
}
/**
* Return the timestamp for the rising interrupt that occurred most recently.
* This is in the same time domain as getClock(). The rising-edge interrupt
* should be enabled with {@link #setUpSourceEdge}
*$
* Return the timestamp for the rising interrupt that occurred most recently. This is in the same
* time domain as getClock(). The rising-edge interrupt should be enabled with {@link
* #setUpSourceEdge}.
*
* @return Timestamp in seconds since boot.
*/
public double readRisingTimestamp() {
@@ -226,10 +232,10 @@ public abstract class InterruptableSensorBase extends SensorBase {
}
/**
* Return the timestamp for the falling interrupt that occurred most recently.
* This is in the same time domain as getClock(). The falling-edge interrupt
* should be enabled with {@link #setUpSourceEdge}
*$
* Return the timestamp for the falling interrupt that occurred most recently. This is in the same
* time domain as getClock(). The falling-edge interrupt should be enabled with {@link
* #setUpSourceEdge}.
*
* @return Timestamp in seconds since boot.
*/
public double readFallingTimestamp() {
@@ -240,9 +246,9 @@ public abstract class InterruptableSensorBase extends SensorBase {
}
/**
* Set which edge to trigger interrupts on
* 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) {

View File

@@ -11,35 +11,29 @@ import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tInstances;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* IterativeRobot implements a specific type of Robot Program framework,
* extending the RobotBase class.
* IterativeRobot implements a specific type of Robot Program framework, extending the RobotBase
* class.
*
* The IterativeRobot class is intended to be subclassed by a user creating a
* robot program.
* <p>The IterativeRobot class is intended to be subclassed by a user creating a robot program.
*
* This class is intended to implement the "old style" default code, by
* providing the following functions which are called by the main loop,
* startCompetition(), at the appropriate times:
* <p>This class is intended to implement the "old style" default code, by providing the following
* functions which are called by the main loop, startCompetition(), at the appropriate times:
*
* robotInit() -- provide for initialization at robot power-on
* <p>robotInit() -- provide for initialization at robot power-on
*
* init() functions -- each of the following functions is called once when the
* appropriate mode is entered: - DisabledInit() -- called only when first
* disabled - 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
* mode is entered from anothermode
*
* Periodic() functions -- each of these functions is called iteratively at the
* appropriate periodic rate (aka the "slow loop"). The period of the iterative
* robot is synced to the driver station control packets, giving a periodic
* frequency of about 50Hz (50 times per second). - disabledPeriodic() -
* autonomousPeriodic() - teleopPeriodic() - testPeriodoc()
* <p>init() functions -- each of the following functions is called once when the appropriate mode
* is entered: - DisabledInit() -- called only when first disabled - 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 mode is
* entered from anothermode
*
* <p>Periodic() functions -- each of these functions is called iteratively at the appropriate
* periodic rate (aka the "slow loop"). The period of the iterative robot is synced to the driver
* station control packets, giving a periodic frequency of about 50Hz (50 times per second). -
* disabledPeriodic() - autonomousPeriodic() - teleopPeriodic() - testPeriodoc()
*/
public class IterativeRobot extends RobotBase {
private boolean m_disabledInitialized;
@@ -48,11 +42,10 @@ public class IterativeRobot extends RobotBase {
private boolean m_testInitialized;
/**
* Constructor for RobotIterativeBase
* Constructor for RobotIterativeBase.
*
* The constructor initializes the instance variables for the robot to
* indicate the status of initialization for disabled, autonomous, and teleop
* code.
* <p>The constructor initializes the instance variables for the robot to indicate the status of
* initialization for disabled, autonomous, and teleop code.
*/
public IterativeRobot() {
// set status for initialization of disabled, autonomous, and teleop code.
@@ -64,7 +57,6 @@ public class IterativeRobot extends RobotBase {
/**
* Provide an alternate "main loop" via startCompetition().
*
*/
public void startCompetition() {
UsageReporting.report(tResourceType.kResourceType_Framework, tInstances.kFramework_Iterative);
@@ -148,9 +140,8 @@ public class IterativeRobot extends RobotBase {
}
/**
* Determine if the appropriate next periodic function should be called. Call
* the periodic functions whenever a packet is received from the Driver
* Station, or about every 20ms.
* Determine if the appropriate next periodic function should be called. Call the periodic
* functions whenever a packet is received from the Driver Station, or about every 20ms.
*/
private boolean nextPeriodReady() {
return m_ds.isNewControlData();
@@ -161,14 +152,12 @@ public class IterativeRobot extends RobotBase {
/**
* Robot-wide initialization code should go here.
*
* Users should override this method for default Robot-wide initialization
* which will be called when the robot is first powered on. It will be called
* exactly one time.
* <p>Users should override this method for default Robot-wide initialization which will be called
* when the robot is first powered on. It will be called exactly one time.
*
* Warning: the Driver Station "Robot Code" light and FMS "Robot Ready"
* indicators will be off until RobotInit() exits. Code in RobotInit() that
* waits for enable will cause the robot to never indicate that the code is
* ready, causing the robot to be bypassed in a match.
* <p>Warning: the Driver Station "Robot Code" light and FMS "Robot Ready" indicators will be off
* until RobotInit() exits. Code in RobotInit() that waits for enable will cause the robot to
* never indicate that the code is ready, causing the robot to be bypassed in a match.
*/
public void robotInit() {
System.out.println("Default IterativeRobot.robotInit() method... Overload me!");
@@ -177,8 +166,8 @@ public class IterativeRobot extends RobotBase {
/**
* Initialization code for disabled mode should go here.
*
* Users should override this method for initialization code which will be
* called each time the robot enters disabled mode.
* <p>Users should override this method for initialization code which will be called each time the
* robot enters disabled mode.
*/
public void disabledInit() {
System.out.println("Default IterativeRobot.disabledInit() method... Overload me!");
@@ -187,8 +176,8 @@ public class IterativeRobot extends RobotBase {
/**
* Initialization code for autonomous mode should go here.
*
* Users should override this method for initialization code which will be
* called each time the robot enters autonomous mode.
* <p>Users should override this method for initialization code which will be called each time the
* robot enters autonomous mode.
*/
public void autonomousInit() {
System.out.println("Default IterativeRobot.autonomousInit() method... Overload me!");
@@ -197,8 +186,8 @@ public class IterativeRobot extends RobotBase {
/**
* Initialization code for teleop mode should go here.
*
* Users should override this method for initialization code which will be
* called each time the robot enters teleop mode.
* <p>Users should override this method for initialization code which will be called each time the
* robot enters teleop mode.
*/
public void teleopInit() {
System.out.println("Default IterativeRobot.teleopInit() method... Overload me!");
@@ -207,8 +196,8 @@ public class IterativeRobot extends RobotBase {
/**
* Initialization code for test mode should go here.
*
* Users should override this method for initialization code which will be
* called each time the robot enters test mode.
* <p>Users should override this method for initialization code which will be called each time the
* robot enters test mode.
*/
public void testInit() {
System.out.println("Default IterativeRobot.testInit() method... Overload me!");
@@ -216,66 +205,66 @@ public class IterativeRobot extends RobotBase {
/* ----------- Overridable periodic code ----------------- */
private boolean dpFirstRun = true;
private boolean m_dpFirstRun = true;
/**
* Periodic code for disabled mode should go here.
*
* Users should override this method for code which will be called
* periodically at a regular rate while the robot is in disabled mode.
* <p>Users should override this method for code which will be called periodically at a regular
* rate while the robot is in disabled mode.
*/
public void disabledPeriodic() {
if (dpFirstRun) {
if (m_dpFirstRun) {
System.out.println("Default IterativeRobot.disabledPeriodic() method... Overload me!");
dpFirstRun = false;
m_dpFirstRun = false;
}
Timer.delay(0.001);
}
private boolean apFirstRun = true;
private boolean m_apFirstRun = true;
/**
* Periodic code for autonomous mode should go here.
*
* Users should override this method for code which will be called
* periodically at a regular rate while the robot is in autonomous mode.
* <p>Users should override this method for code which will be called periodically at a regular
* rate while the robot is in autonomous mode.
*/
public void autonomousPeriodic() {
if (apFirstRun) {
if (m_apFirstRun) {
System.out.println("Default IterativeRobot.autonomousPeriodic() method... Overload me!");
apFirstRun = false;
m_apFirstRun = false;
}
Timer.delay(0.001);
}
private boolean tpFirstRun = true;
private boolean m_tpFirstRun = true;
/**
* Periodic code for teleop mode should go here.
*
* Users should override this method for code which will be called
* periodically at a regular rate while the robot is in teleop mode.
* <p>Users should override this method for code which will be called periodically at a regular
* rate while the robot is in teleop mode.
*/
public void teleopPeriodic() {
if (tpFirstRun) {
if (m_tpFirstRun) {
System.out.println("Default IterativeRobot.teleopPeriodic() method... Overload me!");
tpFirstRun = false;
m_tpFirstRun = false;
}
Timer.delay(0.001);
}
private boolean tmpFirstRun = true;
private boolean m_tmpFirstRun = true;
/**
* Periodic code for test mode should go here
* Periodic code for test mode should go here.
*
* Users should override this method for code which will be called
* periodically at a regular rate while the robot is in test mode.
* <p>Users should override this method for code which will be called periodically at a regular
* rate while the robot is in test mode.
*/
public void testPeriodic() {
if (tmpFirstRun) {
if (m_tmpFirstRun) {
System.out.println("Default IterativeRobot.testPeriodic() method... Overload me!");
tmpFirstRun = false;
m_tmpFirstRun = false;
}
}
}

View File

@@ -13,7 +13,7 @@ import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* Texas Instruments / Vex Robotics Jaguar Speed Controller as a PWM device.
*$
*
* @see CANJaguar CANJaguar for CAN control
*/
public class Jaguar extends PWMSpeedController {
@@ -24,7 +24,7 @@ public class Jaguar extends PWMSpeedController {
private void initJaguar() {
/*
* Input profile defined by Luminary Micro.
*$
*
* Full reverse ranges from 0.671325ms to 0.6972211ms Proportional reverse
* ranges from 0.6972211ms to 1.4482078ms Neutral ranges from 1.4482078ms to
* 1.5517922ms Proportional forward ranges from 1.5517922ms to 2.3027789ms
@@ -42,8 +42,8 @@ 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
* @param channel The PWM channel that the Jaguar is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
public Jaguar(final int channel) {
super(channel);

View File

@@ -7,16 +7,15 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
/**
* Handle input from standard Joysticks connected to the Driver Station. This
* class handles standard input that comes from the Driver Station. Each time a
* value is requested the most recent value is returned. There is a single class
* instance for each joystick and the mapping of ports to hardware buttons
* depends on the code in the driver station.
* Handle input from standard Joysticks connected to the Driver Station. This class handles standard
* input that comes from the Driver Station. Each time a value is requested the most recent value is
* returned. There is a single class instance for each joystick and the mapping of ports to hardware
* buttons depends on the code in the driver station.
*/
public class Joystick extends GenericHID {
@@ -31,11 +30,12 @@ public class Joystick extends GenericHID {
/**
* Represents an analog axis on a joystick.
*/
public static class AxisType {
public static final class AxisType {
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
static final int kX_val = 0;
static final int kY_val = 1;
@@ -44,27 +44,27 @@ public class Joystick extends GenericHID {
static final int kThrottle_val = 4;
static final int kNumAxis_val = 5;
/**
* axis: x-axis
* axis: x-axis.
*/
public static final AxisType kX = new AxisType(kX_val);
/**
* axis: y-axis
* axis: y-axis.
*/
public static final AxisType kY = new AxisType(kY_val);
/**
* axis: z-axis
* axis: z-axis.
*/
public static final AxisType kZ = new AxisType(kZ_val);
/**
* axis: twist
* axis: twist.
*/
public static final AxisType kTwist = new AxisType(kTwist_val);
/**
* axis: throttle
* axis: throttle.
*/
public static final AxisType kThrottle = new AxisType(kThrottle_val);
/**
* axis: number of axis
* axis: number of axis.
*/
public static final AxisType kNumAxis = new AxisType(kNumAxis_val);
@@ -74,27 +74,28 @@ public class Joystick extends GenericHID {
}
/**
* Represents a digital button on the JoyStick
* Represents a digital button on the JoyStick.
*/
public static class ButtonType {
public static final class ButtonType {
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
static final int kTrigger_val = 0;
static final int kTop_val = 1;
static final int kNumButton_val = 2;
/**
* button: trigger
* button: trigger.
*/
public static final ButtonType kTrigger = new ButtonType((kTrigger_val));
/**
* button: top button
* button: top button.
*/
public static final ButtonType kTop = new ButtonType(kTop_val);
/**
* button: num button types
* button: num button types.
*/
public static final ButtonType kNumButton = new ButtonType((kNumButton_val));
@@ -105,22 +106,23 @@ public class Joystick extends GenericHID {
/**
* Represents a rumble output on the JoyStick
* Represents a rumble output on the JoyStick.
*/
public static class RumbleType {
public static final class RumbleType {
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
static final int kLeftRumble_val = 0;
static final int kRightRumble_val = 1;
/**
* Left Rumble
* Left Rumble.
*/
public static final RumbleType kLeftRumble = new RumbleType((kLeftRumble_val));
/**
* Right Rumble
* Right Rumble.
*/
public static final RumbleType kRightRumble = new RumbleType(kRightRumble_val);
@@ -129,7 +131,7 @@ public class Joystick extends GenericHID {
}
}
private DriverStation m_ds;
private final DriverStation m_ds;
private final int m_port;
private final byte[] m_axes;
private final byte[] m_buttons;
@@ -138,11 +140,10 @@ public class Joystick extends GenericHID {
private short m_rightRumble;
/**
* 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.
* @param port The port on the driver station that the joystick is plugged into.
*/
public Joystick(final int port) {
this(port, AxisType.kNumAxis.value, ButtonType.kNumButton.value);
@@ -162,12 +163,11 @@ public class Joystick extends GenericHID {
/**
* Protected version of the constructor to be called by sub-classes.
*
* This constructor allows the subclass to configure the number of constants
* for axes and buttons.
* <p>This constructor allows the subclass to configure the number of constants for axes and
* buttons.
*
* @param port The port on the driver station that the joystick is plugged
* into.
* @param numAxisTypes The number of axis types in the enum.
* @param port The port on the driver station that the joystick is plugged into.
* @param numAxisTypes The number of axis types in the enum.
* @param numButtonTypes The number of button types in the enum.
*/
protected Joystick(int port, int numAxisTypes, int numButtonTypes) {
@@ -178,8 +178,8 @@ public class Joystick extends GenericHID {
}
/**
* Get the X value of the joystick. This depends on the mapping of the
* joystick connected to the current port.
* Get the X value of the joystick. This depends on the mapping of the joystick connected to the
* current port.
*
* @param hand Unused
* @return The X value of the joystick.
@@ -189,8 +189,8 @@ public class Joystick extends GenericHID {
}
/**
* Get the Y value of the joystick. This depends on the mapping of the
* joystick connected to the current port.
* Get the Y value of the joystick. This depends on the mapping of the joystick connected to the
* current port.
*
* @param hand Unused
* @return The Y value of the joystick.
@@ -200,8 +200,8 @@ public class Joystick extends GenericHID {
}
/**
* Get the Z value of the joystick. This depends on the mapping of the
* joystick connected to the current port.
* Get the Z value of the joystick. This depends on the mapping of the joystick connected to the
* current port.
*
* @param hand Unused
* @return The Z value of the joystick.
@@ -211,8 +211,8 @@ public class Joystick extends GenericHID {
}
/**
* Get the twist value of the current joystick. This depends on the mapping of
* the joystick connected to the current port.
* Get the twist value of the current joystick. This depends on the mapping of the joystick
* connected to the current port.
*
* @return The Twist value of the joystick.
*/
@@ -221,8 +221,8 @@ public class Joystick extends GenericHID {
}
/**
* Get the throttle value of the current joystick. This depends on the mapping
* of the joystick connected to the current port.
* Get the throttle value of the current joystick. This depends on the mapping of the joystick
* connected to the current port.
*
* @return The Throttle value of the joystick.
*/
@@ -243,9 +243,8 @@ public class Joystick extends GenericHID {
/**
* For the current joystick, return the axis determined by the argument.
*
* This is for cases where the joystick axis is returned programatically,
* otherwise one of the previous functions would be preferable (for example
* getX()).
* <p>This is for cases where the joystick axis is returned programatically, otherwise one of the
* previous functions would be preferable (for example getX()).
*
* @param axis The axis to read.
* @return The value of the axis.
@@ -268,7 +267,7 @@ public class Joystick extends GenericHID {
}
/**
* For the current joystick, return the number of axis
* For the current joystick, return the number of axis.
*/
public int getAxisCount() {
return m_ds.getStickAxisCount(m_port);
@@ -277,10 +276,10 @@ public class Joystick extends GenericHID {
/**
* Read the state of the trigger on the joystick.
*
* Look up which button has been assigned to the trigger and read its state.
* <p>Look up which button has been assigned to the trigger and read its state.
*
* @param hand This parameter is ignored for the Joystick class and is only
* here to complete the GenericHID interface.
* @param hand This parameter is ignored for the Joystick class and is only here to complete the
* GenericHID interface.
* @return The state of the trigger.
*/
public boolean getTrigger(Hand hand) {
@@ -290,10 +289,10 @@ public class Joystick extends GenericHID {
/**
* Read the state of the top button on the joystick.
*
* Look up which button has been assigned to the top and read its state.
* <p>Look up which button has been assigned to the top and read its state.
*
* @param hand This parameter is ignored for the Joystick class and is only
* here to complete the GenericHID interface.
* @param hand This parameter is ignored for the Joystick class and is only here to complete the
* GenericHID interface.
* @return The state of the top button.
*/
public boolean getTop(Hand hand) {
@@ -301,11 +300,11 @@ public class Joystick extends GenericHID {
}
/**
* This is not supported for the Joystick. This method is only here to
* complete the GenericHID interface.
* This is not supported for the Joystick. This method is only here to complete the GenericHID
* interface.
*
* @param hand This parameter is ignored for the Joystick class and is only
* here to complete the GenericHID interface.
* @param hand This parameter is ignored for the Joystick class and is only here to complete the
* GenericHID interface.
* @return The state of the bumper (always false)
*/
public boolean getBumper(Hand hand) {
@@ -313,9 +312,9 @@ public class Joystick extends GenericHID {
}
/**
* Get the button value (starting at button 1)
* Get the button value (starting at button 1).
*
* The appropriate button is returned as a boolean value.
* <p>The appropriate button is returned as a boolean value.
*
* @param button The button number to be read (starting at 1).
* @return The state of the button.
@@ -325,7 +324,7 @@ public class Joystick extends GenericHID {
}
/**
* For the current joystick, return the number of buttons
* For the current joystick, return the number of buttons.
*/
public int getButtonCount() {
return m_ds.getStickButtonCount(m_port);
@@ -334,8 +333,8 @@ public class Joystick extends GenericHID {
/**
* Get the angle in degrees of a POV on the joystick.
*
* The POV angles start at 0 in the up direction, and increase
* clockwise (eg right is 90, upper-left is 315).
* <p>The POV angles start at 0 in the up direction, and increase clockwise (eg right is 90,
* upper-left is 315).
*
* @param pov The index of the POV to read (starting at 0)
* @return the angle of the POV in degrees, or -1 if the POV is not pressed.
@@ -345,7 +344,7 @@ public class Joystick extends GenericHID {
}
/**
* For the current joystick, return the number of POVs
* For the current joystick, return the number of POVs.
*/
public int getPOVCount() {
return m_ds.getStickPOVCount(m_port);
@@ -354,7 +353,7 @@ public class Joystick extends GenericHID {
/**
* Get buttons based on an enumerated type.
*
* The button type will be looked up in the list of buttons and then read.
* <p>The button type will be looked up in the list of buttons and then read.
*
* @param button The type of button to read.
* @return The state of the button.
@@ -371,8 +370,8 @@ public class Joystick extends GenericHID {
}
/**
* Get the magnitude of the direction vector formed by the joystick's current
* position relative to its origin
* Get the magnitude of the direction vector formed by the joystick's current position relative to
* its origin.
*
* @return The magnitude of the direction vector
*/
@@ -381,8 +380,7 @@ public class Joystick extends GenericHID {
}
/**
* Get the direction of the vector formed by the joystick and its origin in
* radians
* Get the direction of the vector formed by the joystick and its origin in radians.
*
* @return The direction of the vector in radians
*/
@@ -391,11 +389,9 @@ public class Joystick extends GenericHID {
}
/**
* Get the direction of the vector formed by the joystick and its origin in
* degrees
* Get the direction of the vector formed by the joystick and its origin in degrees.
*
* uses acos(-1) to represent Pi due to absence of readily accessable Pi
* constant in C++
* <p>Uses acos(-1) to represent Pi due to absence of readily accessable Pi constant in C++
*
* @return The direction of the vector in degrees
*/
@@ -416,7 +412,7 @@ public class Joystick extends GenericHID {
/**
* Set the channel associated with a specified axis.
*
* @param axis The axis to set the channel for.
* @param axis The axis to set the channel for.
* @param channel The channel to set the axis to.
*/
public void setAxisChannel(AxisType axis, int channel) {
@@ -425,9 +421,8 @@ public class Joystick extends GenericHID {
/**
* Get the value of isXbox for the current joystick.
*$
* @return A boolean that is true if the controller is an xbox
* controller.
*
* @return A boolean that is true if the controller is an xbox controller.
*/
public boolean getIsXbox() {
return m_ds.getJoystickIsXbox(m_port);
@@ -435,7 +430,7 @@ public class Joystick extends GenericHID {
/**
* Get the HID type of the current joystick.
*$
*
* @return The HID type value of the current joystick.
*/
public int getType() {
@@ -444,7 +439,7 @@ public class Joystick extends GenericHID {
/**
* Get the name of the current joystick.
*$
*
* @return The name of the current joystick.
*/
public String getName() {
@@ -452,30 +447,32 @@ public class Joystick extends GenericHID {
}
/**
* Set the rumble output for the joystick. The DS currently supports 2 rumble
* values, left rumble and right rumble
*$
* @param type Which rumble value to set
* Set the rumble output for the joystick. The DS currently supports 2 rumble values, left rumble
* and right rumble.
*
* @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, float value) {
if (value < 0)
if (value < 0) {
value = 0;
else if (value > 1)
} else if (value > 1) {
value = 1;
if (type.value == RumbleType.kLeftRumble_val)
}
if (type.value == RumbleType.kLeftRumble_val) {
m_leftRumble = (short) (value * 65535);
else
} else {
m_rightRumble = (short) (value * 65535);
}
FRCNetworkCommunicationsLibrary.HALSetJoystickOutputs((byte) m_port, m_outputs, m_leftRumble,
m_rightRumble);
}
/**
* Set a single HID output value for the joystick.
*$
*
* @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) {
@@ -486,7 +483,7 @@ public class Joystick extends GenericHID {
/**
* Set all HID output values for the joystick.
*$
*
* @param value The 32 bit output value (1 bit for each output)
*/
public void setOutputs(int value) {

View File

@@ -7,48 +7,43 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.Timer;
/**
* The MotorSafetyHelper object is constructed for every object that wants to
* implement the Motor Safety protocol. The helper object has the code to
* actually do the timing and call the motors Stop() method when the timeout
* expires. The motor object is expected to call the Feed() method whenever the
* motors value is updated.
* The MotorSafetyHelper object is constructed for every object that wants to implement the Motor
* Safety protocol. The helper object has the code to actually do the timing and call the motors
* Stop() method when the timeout expires. The motor object is expected to call the Feed() method
* whenever the motors value is updated.
*
* @author brad
*/
public class MotorSafetyHelper {
public final class MotorSafetyHelper {
double m_expiration;
boolean m_enabled;
double m_stopTime;
MotorSafety m_safeObject;
MotorSafetyHelper m_nextHelper;
static MotorSafetyHelper m_headHelper = null;
private double m_expiration;
private boolean m_enabled;
private double m_stopTime;
private final MotorSafety m_safeObject;
private final MotorSafetyHelper m_nextHelper;
private static MotorSafetyHelper headHelper = null;
/**
* The constructor for a MotorSafetyHelper object. The helper object is
* constructed for every object that wants to implement the Motor Safety
* protocol. The helper object has the code to actually do the timing and call
* the motors Stop() method when the timeout expires. The motor object is
* expected to call the Feed() method whenever the motors value is updated.
* The constructor for a MotorSafetyHelper object. The helper object is constructed for every
* object that wants to implement the Motor Safety protocol. The helper object has the code to
* actually do the timing and call the motors Stop() method when the timeout expires. The motor
* object is expected to call the Feed() method whenever the motors value is updated.
*
* @param safeObject a pointer to the motor object implementing MotorSafety.
* This is used to call the Stop() method on the motor.
* @param safeObject a pointer to the motor object implementing MotorSafety. This is used to call
* the Stop() method on the motor.
*/
public MotorSafetyHelper(MotorSafety safeObject) {
m_safeObject = safeObject;
m_enabled = false;
m_expiration = MotorSafety.DEFAULT_SAFETY_EXPIRATION;
m_stopTime = Timer.getFPGATimestamp();
m_nextHelper = m_headHelper;
m_headHelper = this;
m_nextHelper = headHelper;
headHelper = this;
}
/**
* Feed the motor safety object. Resets the timer on this object that is used
* to do the timeouts.
* Feed the motor safety object. Resets the timer on this object that is used to do the timeouts.
*/
public void feed() {
m_stopTime = Timer.getFPGATimestamp() + m_expiration;
@@ -56,7 +51,7 @@ public class MotorSafetyHelper {
/**
* Set the expiration time for the corresponding motor safety object.
*$
*
* @param expirationTime The timeout value in seconds.
*/
public void setExpiration(double expirationTime) {
@@ -65,7 +60,7 @@ public class MotorSafetyHelper {
/**
* Retrieve the timeout value for the corresponding motor safety object.
*$
*
* @return the timeout value in seconds.
*/
public double getExpiration() {
@@ -74,34 +69,34 @@ public class MotorSafetyHelper {
/**
* Determine of the motor is still operating or has timed out.
*$
* @return a true value if the motor is still operating normally and hasn't
* timed out.
*
* @return a true value if the motor is still operating normally and hasn't timed out.
*/
public boolean isAlive() {
return !m_enabled || m_stopTime > Timer.getFPGATimestamp();
}
/**
* Check if this motor has exceeded its timeout. This method is called
* periodically to determine if this motor has exceeded its timeout value. If
* it has, the stop method is called, and the motor is shut down until its
* value is updated again.
* Check if this motor has exceeded its timeout. This method is called periodically to determine
* if this motor has exceeded its timeout value. If it has, the stop method is called, and the
* motor is shut down until its value is updated again.
*/
public void check() {
if (!m_enabled || RobotState.isDisabled() || RobotState.isTest())
if (!m_enabled || RobotState.isDisabled() || RobotState.isTest()) {
return;
}
if (m_stopTime < Timer.getFPGATimestamp()) {
DriverStation.reportError(m_safeObject.getDescription() + "... Output not updated often enough.", false);
DriverStation.reportError(m_safeObject.getDescription() + "... Output not updated often "
+ "enough.", false);
m_safeObject.stopMotor();
}
}
/**
* Enable/disable motor safety for this device Turn on and off the motor
* safety option for this PWM object.
*$
* Enable/disable motor safety for this device Turn on and off the motor safety option for this
* PWM object.
*
* @param enabled True if motor safety is enforced for this object
*/
public void setSafetyEnabled(boolean enabled) {
@@ -109,9 +104,9 @@ public class MotorSafetyHelper {
}
/**
* Return the state of the motor safety enabled flag Return if the motor
* safety is currently enabled for this devicce.
*$
* Return the state of the motor safety enabled flag Return if the motor safety is currently
* enabled for this devicce.
*
* @return True if motor safety is enforced for this device
*/
public boolean isSafetyEnabled() {
@@ -119,13 +114,13 @@ public class MotorSafetyHelper {
}
/**
* Check the motors to see if any have timed out. This static method is called
* periodically to poll all the motors and stop any that have timed out.
* Check the motors to see if any have timed out. This static method is called periodically to
* poll all the motors and stop any that have timed out.
*/
// TODO: these should be synchronized with the setting methods in case it's
// called from a different thread
public static void checkMotors() {
for (MotorSafetyHelper msh = m_headHelper; msh != null; msh = msh.m_nextHelper) {
for (MotorSafetyHelper msh = headHelper; msh != null; msh = msh.m_nextHelper) {
msh.check();
}
}

View File

@@ -7,18 +7,15 @@
package edu.wpi.first.wpilibj;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.lang.Runtime;
import edu.wpi.first.wpilibj.hal.NotifierJNI;
import edu.wpi.first.wpilibj.Utility;
public class Notifier {
private static class Process implements NotifierJNI.NotifierJNIHandlerFunction {
// The lock for the process information.
private ReentrantLock m_processLock = new ReentrantLock();
private final ReentrantLock m_processLock = new ReentrantLock();
// The C pointer to the notifier object. We don't use it directly, it is
// just passed to the JNI bindings.
private long m_notifier;
@@ -37,7 +34,7 @@ public class Notifier {
// completed. This is only relevant if the handler takes a very long time
// to complete (or the period is very short) and when everything is being
// destructed.
private ReentrantLock m_handlerLock = new ReentrantLock();
private final ReentrantLock m_handlerLock = new ReentrantLock();
public Process(Runnable run) {
m_handler = run;
@@ -45,10 +42,10 @@ public class Notifier {
}
@Override
@SuppressWarnings("NoFinalizer")
protected void finalize() {
NotifierJNI.cleanNotifier(m_notifier);
m_handlerLock.lock();
m_handlerLock = null;
}
/**
@@ -59,8 +56,8 @@ public class Notifier {
}
/**
* Handler which is called by the HAL library; it handles the subsequent
* calling of the user handler.
* Handler which is called by the HAL library; it handles the subsequent calling of the user
* handler.
*/
@Override
public void apply(long time) {
@@ -81,7 +78,7 @@ public class Notifier {
synchronized (m_processLock) {
m_periodic = periodic;
m_period = period;
m_expirationTime = Utility.getFPGATime() * 1e-6 + m_period;
m_expirationTime = Utility.getFPGATime() * 1e-6 + period;
updateAlarm();
}
}
@@ -101,16 +98,16 @@ public class Notifier {
/**
* 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) {
m_process = new Process(run);
}
/**
* 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.
*/
@@ -119,22 +116,21 @@ public class Notifier {
}
/**
* 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_process.start(period, true);
}
/**
* Stop timer events from occuring. Stop any repeating timer events from
* occuring. 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 occuring. Stop any repeating timer events from occuring. 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_process.stop();

View File

@@ -9,27 +9,24 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.hal.PWMJNI;
import edu.wpi.first.wpilibj.hal.DIOJNI;
import edu.wpi.first.wpilibj.hal.PWMJNI;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
import edu.wpi.first.wpilibj.tables.ITableListener;
import edu.wpi.first.wpilibj.util.AllocationException;
import edu.wpi.first.wpilibj.util.CheckedAllocationException;
/**
* Class implements the PWM generation in the FPGA.
*
* The values supplied as arguments for PWM outputs range from -1.0 to 1.0. They
* are mapped to the hardware dependent values, in this case 0-2000 for the
* FPGA. Changes are immediately sent to the FPGA, and the update occurs at the
* next FPGA cycle. There is no delay.
* <p>The values supplied as arguments for PWM outputs range from -1.0 to 1.0. They are mapped to
* the hardware dependent values, in this case 0-2000 for the FPGA. Changes are immediately sent to
* the FPGA, and the update occurs at the next FPGA cycle. There is no delay.
*
* As of revision 0.1.10 of the FPGA, the FPGA interprets the 0-2000 values as
* follows: - 2000 = maximum pulse width - 1999 to 1001 = linear scaling from
* "full forward" to "center" - 1000 = center value - 999 to 2 = linear scaling
* from "center" to "full reverse" - 1 = minimum pulse width (currently .5ms) -
* 0 = disabled (i.e. PWM output is held low)
* <p>As of revision 0.1.10 of the FPGA, the FPGA interprets the 0-2000 values as follows: - 2000 =
* maximum pulse width - 1999 to 1001 = linear scaling from "full forward" to "center" - 1000 =
* center value - 999 to 2 = linear scaling from "center" to "full reverse" - 1 = minimum pulse
* width (currently .5ms) - 0 = disabled (i.e. PWM output is held low)
*/
public class PWM extends SensorBase implements LiveWindowSendable {
/**
@@ -38,22 +35,23 @@ public class PWM extends SensorBase implements LiveWindowSendable {
public static class PeriodMultiplier {
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
static final int k1X_val = 1;
static final int k2X_val = 2;
static final int k4X_val = 4;
/**
* Period Multiplier: don't skip pulses
* Period Multiplier: don't skip pulses.
*/
public static final PeriodMultiplier k1X = new PeriodMultiplier(k1X_val);
/**
* Period Multiplier: skip every other pulse
* Period Multiplier: skip every other pulse.
*/
public static final PeriodMultiplier k2X = new PeriodMultiplier(k2X_val);
/**
* Period Multiplier: skip three out of four pulses
* Period Multiplier: skip three out of four pulses.
*/
public static final PeriodMultiplier k4X = new PeriodMultiplier(k4X_val);
@@ -64,55 +62,55 @@ public class PWM extends SensorBase implements LiveWindowSendable {
private int m_channel;
private long m_port;
/**
* kDefaultPwmPeriod is in ms
* kDefaultPwmPeriod is in ms.
*
* - 20ms periods (50 Hz) are the "safest" setting in that this works for all
* devices - 20ms periods seem to be desirable for Vex Motors - 20ms periods
* are the specified period for HS-322HD servos, but work reliably down to
* 10.0 ms; starting at about 8.5ms, the servo sometimes hums and get hot; by
* 5.0ms the hum is nearly continuous - 10ms periods work well for Victor 884
* - 5ms periods allows higher update rates for Luminary Micro Jaguar speed
* controllers. Due to the shipping firmware on the Jaguar, we can't run the
* update period less than 5.05 ms.
* <p>- 20ms periods (50 Hz) are the "safest" setting in that this works for all devices - 20ms
* periods seem to be desirable for Vex Motors - 20ms periods are the specified period for
* HS-322HD servos, but work reliably down to 10.0 ms; starting at about 8.5ms, the servo
* sometimes hums and get hot; by 5.0ms the hum is nearly continuous - 10ms periods work well for
* Victor 884 - 5ms periods allows higher update rates for Luminary Micro Jaguar speed
* controllers. Due to the shipping firmware on the Jaguar, we can't run the update period less
* than 5.05 ms.
*
* kDefaultPwmPeriod is the 1x period (5.05 ms). In hardware, the period
* scaling is implemented as an output squelch to get longer periods for old
* devices.
* <p>kDefaultPwmPeriod is the 1x period (5.05 ms). In hardware, the period scaling is implemented
* as an output squelch to get longer periods for old devices.
*/
protected static final double kDefaultPwmPeriod = 5.05;
/**
* kDefaultPwmCenter is the PWM range center in ms
* kDefaultPwmCenter is the PWM range center in ms.
*/
protected static final double kDefaultPwmCenter = 1.5;
/**
* kDefaultPWMStepsDown is the number of PWM steps below the centerpoint
* kDefaultPWMStepsDown is the number of PWM steps below the centerpoint.
*/
protected static final int kDefaultPwmStepsDown = 1000;
public static final int kPwmDisabled = 0;
boolean m_eliminateDeadband;
int m_maxPwm;
int m_deadbandMaxPwm;
private boolean m_eliminateDeadband;
private int m_maxPwm;
private int m_deadbandMaxPwm;
/*
* Intentionally package private
*/
int m_centerPwm;
int m_deadbandMinPwm;
int m_minPwm;
private int m_deadbandMinPwm;
private int m_minPwm;
/**
* Initialize PWMs given a channel.
*
* This method is private and is the common path for all the constructors for
* creating PWM instances. Checks channel value ranges and allocates the
* appropriate channel. The allocation is only done to help users ensure that
* they don't double assign channels.
*$
* @param channel The PWM channel number. 0-9 are on-board, 10-19 are on the
* MXP port
* <p>This method is private and is the common path for all the constructors for creating PWM
* instances. Checks channel value ranges and allocates the appropriate channel. The allocation is
* only done to help users ensure that they don't double assign channels.
*
* @param channel The PWM channel number. 0-9 are on-board, 10-19 are on the MXP port
*/
private void initPWM(final int channel) {
checkPWMChannel(channel);
m_channel = channel;
m_port = DIOJNI.initializeDigitalPort(DIOJNI.getPort((byte) m_channel));
m_port = DIOJNI.initializeDigitalPort(DIOJNI.getPort((byte) channel));
if (!PWMJNI.allocatePWMChannel(m_port)) {
throw new AllocationException("PWM channel " + channel + " is already allocated");
@@ -137,10 +135,12 @@ public class PWM extends SensorBase implements LiveWindowSendable {
/**
* Free the PWM channel.
*
* Free the resource associated with the PWM channel and set the value to 0.
* <p>Free the resource associated with the PWM channel and set the value to 0.
*/
public void free() {
if (m_port == 0) return;
if (m_port == 0) {
return;
}
PWMJNI.setPWM(m_port, (short) 0);
PWMJNI.freePWMChannel(m_port);
PWMJNI.freeDIO(m_port);
@@ -150,30 +150,30 @@ public class PWM extends SensorBase implements LiveWindowSendable {
/**
* 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.
*
* @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.
*/
public void enableDeadbandElimination(boolean eliminateDeadband) {
m_eliminateDeadband = eliminateDeadband;
}
/**
* Set the bounds on the PWM values. This sets the bounds on the PWM values
* for a particular each type of controller. The values determine the upper
* and lower speeds as well as the deadband bracket.
*$
* @deprecated Recommended to set bounds in ms using
* {@link #setBounds(double, double, double, double, double)}
* @param max The Minimum pwm value
* Set the bounds on the PWM values. This sets the bounds on the PWM values for a particular each
* type of controller. The values determine the upper and lower speeds as well as the deadband
* bracket.
*
* @param max The Minimum pwm value
* @param deadbandMax The high end of the deadband range
* @param center The center speed (off)
* @param center The center speed (off)
* @param deadbandMin The low end of the deadband range
* @param min The minimum pwm value
* @param min The minimum pwm value
* @deprecated Recommended to set bounds in ms using {@link #setBounds(double, double, double,
* double, double)}
*/
public void setBounds(final int max, final int deadbandMax, final int center,
final int deadbandMin, final int min) {
final int deadbandMin, final int min) {
m_maxPwm = max;
m_deadbandMaxPwm = deadbandMax;
m_centerPwm = center;
@@ -182,18 +182,18 @@ public class PWM extends SensorBase implements LiveWindowSendable {
}
/**
* Set the bounds on the PWM pulse widths. This sets 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.
*$
* @param max The max PWM pulse width in ms
* Set the bounds on the PWM pulse widths. This sets 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.
*
* @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
*/
protected void setBounds(double max, double deadbandMax, double center, double deadbandMin,
double min) {
double min) {
double loopTime =
DIOJNI.getLoopTiming() / (kSystemClockTicksPerMicrosecond * 1e3);
@@ -218,12 +218,11 @@ public class PWM extends SensorBase implements LiveWindowSendable {
/**
* Set the PWM value based on a position.
*
* This is intended to be used by servos.
*
* @pre SetMaxPositivePwm() called.
* @pre SetMinNegativePwm() called.
* <p>This is intended to be used by servos.
*
* @param pos The position to set the servo between 0.0 and 1.0.
* @pre SetMaxPositivePwm() called.
* @pre SetMinNegativePwm() called.
*/
public void setPosition(double pos) {
if (pos < 0.0) {
@@ -244,12 +243,11 @@ public class PWM extends SensorBase implements LiveWindowSendable {
/**
* Get the PWM value in terms of a position.
*
* This is intended to be used by servos.
*
* @pre SetMaxPositivePwm() called.
* @pre SetMinNegativePwm() called.
* <p>This is intended to be used by servos.
*
* @return The position the servo is set to between 0.0 and 1.0.
* @pre SetMaxPositivePwm() called.
* @pre SetMinNegativePwm() called.
*/
public double getPosition() {
int value = getRaw();
@@ -265,15 +263,14 @@ public class PWM extends SensorBase implements LiveWindowSendable {
/**
* Set the PWM value based on a speed.
*
* This is intended to be used by speed controllers.
* <p>This is intended to be used by speed controllers.
*
* @param speed The speed to set the speed controller between -1.0 and 1.0.
* @pre SetMaxPositivePwm() called.
* @pre SetMinPositivePwm() called.
* @pre SetCenterPwm() called.
* @pre SetMaxNegativePwm() called.
* @pre SetMinNegativePwm() called.
*
* @param speed The speed to set the speed controller between -1.0 and 1.0.
*/
final void setSpeed(double speed) {
// clamp speed to be in the range 1.0 >= speed >= -1.0
@@ -289,10 +286,12 @@ public class PWM extends SensorBase implements LiveWindowSendable {
rawValue = getCenterPwm();
} else if (speed > 0.0) {
rawValue =
(int) (speed * ((double) getPositiveScaleFactor()) + ((double) getMinPositivePwm()) + 0.5);
(int) (speed * ((double) getPositiveScaleFactor())
+ ((double) getMinPositivePwm()) + 0.5);
} else {
rawValue =
(int) (speed * ((double) getNegativeScaleFactor()) + ((double) getMaxNegativePwm()) + 0.5);
(int) (speed * ((double) getNegativeScaleFactor())
+ ((double) getMaxNegativePwm()) + 0.5);
}
// send the computed pwm value to the FPGA
@@ -302,14 +301,13 @@ public class PWM extends SensorBase implements LiveWindowSendable {
/**
* Get the PWM value in terms of speed.
*
* This is intended to be used by speed controllers.
* <p>This is intended to be used by speed controllers.
*
* @return The most recently set speed between -1.0 and 1.0.
* @pre SetMaxPositivePwm() called.
* @pre SetMinPositivePwm() called.
* @pre SetMaxNegativePwm() called.
* @pre SetMinNegativePwm() called.
*
* @return The most recently set speed between -1.0 and 1.0.
*/
public double getSpeed() {
int value = getRaw();
@@ -329,7 +327,7 @@ public class PWM extends SensorBase implements LiveWindowSendable {
/**
* Set the PWM value directly to the hardware.
*
* Write a raw value to a PWM channel.
* <p>Write a raw value to a PWM channel.
*
* @param value Raw PWM value. Range 0 - 255.
*/
@@ -340,7 +338,7 @@ public class PWM extends SensorBase implements LiveWindowSendable {
/**
* Get the PWM value directly from the hardware.
*
* Read a raw value from a PWM channel.
* <p>Read a raw value from a PWM channel.
*
* @return Raw PWM control value. Range: 0 - 255.
*/
@@ -411,56 +409,47 @@ public class PWM extends SensorBase implements LiveWindowSendable {
/*
* Live Window code, only does anything if live window is activated.
*/
@Override
public String getSmartDashboardType() {
return "Speed Controller";
}
private ITable m_table;
private ITableListener m_table_listener;
private ITableListener m_tableListener;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("Value", getSpeed());
}
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void startLiveWindowMode() {
setSpeed(0); // Stop for safety
m_table_listener = new ITableListener() {
m_tableListener = new ITableListener() {
public void valueChanged(ITable itable, String key, Object value, boolean bln) {
setSpeed(((Double) value).doubleValue());
setSpeed((Double) value);
}
};
m_table.addTableListener("Value", m_table_listener, true);
m_table.addTableListener("Value", m_tableListener, true);
}
/**
* {@inheritDoc}
*/
@Override
public void stopLiveWindowMode() {
setSpeed(0); // Stop for safety
// TODO: Broken, should only remove the listener from "Value" only.
m_table.removeTableListener(m_table_listener);
m_table.removeTableListener(m_tableListener);
}
}

View File

@@ -11,13 +11,13 @@ package edu.wpi.first.wpilibj;
* Common base class for all PWM Speed Controllers.
*/
public abstract class PWMSpeedController extends SafePWM implements SpeedController {
private boolean isInverted = false;
private boolean m_isInverted = false;
/**
* Constructor.
*
* @param channel The PWM channel that the controller is attached to. 0-9 are
* on-board, 10-19 are on the MXP port
* @param channel The PWM channel that the controller is attached to. 0-9 are on-board, 10-19 are
* on the MXP port
*/
protected PWMSpeedController(int channel) {
super(channel);
@@ -26,53 +26,54 @@ public abstract class PWMSpeedController extends SafePWM implements SpeedControl
/**
* Set the PWM value.
*
* <p>The PWM value is set using a range of -1.0 to 1.0, appropriately scaling the value for the
* FPGA.
*
* @param speed The speed to set. Value should be between -1.0 and 1.0.
* @param syncGroup The update group to add this Set() to, pending UpdateSyncGroup(). If 0, update
* immediately.
* @deprecated For compatibility with CANJaguar
*
* The PWM value is set using a range of -1.0 to 1.0,
* appropriately scaling the value for the FPGA.
*
* @param speed The speed to set. Value should be between -1.0 and 1.0.
* @param syncGroup The update group to add this Set() to, pending
* UpdateSyncGroup(). If 0, update immediately.
*/
@Deprecated
@Override
public void set(double speed, byte syncGroup) {
setSpeed(isInverted ? -speed : speed);
setSpeed(m_isInverted ? -speed : speed);
Feed();
}
/**
* Set the PWM value.
*
* The PWM value is set using a range of -1.0 to 1.0, appropriately scaling
* the value for the FPGA.
* <p>The PWM value is set using a range of -1.0 to 1.0, appropriately scaling the value for the
* FPGA.
*
* @param speed The speed value between -1.0 and 1.0 to set.
*/
@Override
public void set(double speed) {
setSpeed(isInverted ? -speed : speed);
setSpeed(m_isInverted ? -speed : speed);
Feed();
}
/**
* Common interface for inverting direction of a speed controller
* Common interface for inverting direction of a speed controller.
*
* @param isInverted The state of inversion true is inverted
*/
@Override
public void setInverted(boolean isInverted) {
this.isInverted = isInverted;
m_isInverted = isInverted;
}
/**
* Common interface for the inverting direction of a speed controller.
*
* @return isInverted The state of inversion, true is inverted.
*
*/
@Override
public boolean getInverted() {
return this.isInverted;
return m_isInverted;
}
/**
@@ -80,6 +81,7 @@ public abstract class PWMSpeedController extends SafePWM implements SpeedControl
*
* @return The most recently set value for the PWM between -1.0 and 1.0.
*/
@Override
public double get() {
return getSpeed();
}
@@ -89,7 +91,8 @@ public abstract class PWMSpeedController extends SafePWM implements SpeedControl
*
* @param output Write out the PWM value as was found in the PIDController
*/
@Override
public void pidWrite(double output) {
set(output);
}
}
}

View File

@@ -8,35 +8,34 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.hal.PDPJNI;
import edu.wpi.first.wpilibj.hal.HALUtil;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
/**
* Class for getting voltage, current, temperature, power and energy from the
* CAN PDP.
*$
* Class for getting voltage, current, temperature, power and energy from the CAN PDP.
*
* @author Thomas Clark
*/
public class PowerDistributionPanel extends SensorBase implements LiveWindowSendable {
int m_module;
private final int m_module;
@SuppressWarnings("JavadocMethod")
public PowerDistributionPanel(int module) {
m_module = module;
checkPDPModule(m_module);
PDPJNI.initializePDP(m_module);
checkPDPModule(module);
PDPJNI.initializePDP(module);
}
@SuppressWarnings("JavadocMethod")
public PowerDistributionPanel() {
this(0);
}
/**
* Query the input voltage of the PDP
*$
* Query the input voltage of the PDP.
*
* @return The voltage of the PDP in volts
*/
public double getVoltage() {
@@ -44,8 +43,8 @@ public class PowerDistributionPanel extends SensorBase implements LiveWindowSend
}
/**
* Query the temperature of the PDP
*$
* Query the temperature of the PDP.
*
* @return The temperature of the PDP in degrees Celsius
*/
public double getTemperature() {
@@ -53,8 +52,8 @@ public class PowerDistributionPanel extends SensorBase implements LiveWindowSend
}
/**
* Query the current of a single channel of the PDP
*$
* Query the current of a single channel of the PDP.
*
* @return The current of one of the PDP channels (channels 0-15) in Amperes
*/
public double getCurrent(int channel) {
@@ -66,8 +65,8 @@ public class PowerDistributionPanel extends SensorBase implements LiveWindowSend
}
/**
* Query the current of all monitored PDP channels (0-15)
*$
* Query the current of all monitored PDP channels (0-15).
*
* @return The current of all the channels in Amperes
*/
public double getTotalCurrent() {
@@ -75,8 +74,8 @@ public class PowerDistributionPanel extends SensorBase implements LiveWindowSend
}
/**
* Query the total power drawn from the monitored PDP channels
*$
* Query the total power drawn from the monitored PDP channels.
*
* @return the total power in Watts
*/
public double getTotalPower() {
@@ -84,8 +83,8 @@ public class PowerDistributionPanel extends SensorBase implements LiveWindowSend
}
/**
* Query the total energy drawn from the monitored PDP channels
*$
* Query the total energy drawn from the monitored PDP channels.
*
* @return the total energy in Joules
*/
public double getTotalEnergy() {
@@ -93,19 +92,20 @@ public class PowerDistributionPanel extends SensorBase implements LiveWindowSend
}
/**
* Reset the total energy to 0
* Reset the total energy to 0.
*/
public void resetTotalEnergy() {
PDPJNI.resetPDPTotalEnergy(m_module);
}
/**
* Clear all PDP sticky faults
* Clear all PDP sticky faults.
*/
public void clearStickyFaults() {
PDPJNI.clearPDPStickyFaults(m_module);
}
@Override
public String getSmartDashboardType() {
return "PowerDistributionPanel";
}
@@ -115,24 +115,18 @@ public class PowerDistributionPanel extends SensorBase implements LiveWindowSend
*/
private ITable m_table;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("Chan0", getCurrent(0));
@@ -157,15 +151,17 @@ public class PowerDistributionPanel extends SensorBase implements LiveWindowSend
}
/**
* PDP doesn't have to do anything special when entering the LiveWindow.
* {@inheritDoc}
* PDP doesn't have to do anything special when entering the LiveWindow. {@inheritDoc}
*/
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
/**
* PDP doesn't have to do anything special when exiting the LiveWindow.
* {@inheritDoc}
* PDP doesn't have to do anything special when exiting the LiveWindow. {@inheritDoc}
*/
public void stopLiveWindowMode() {}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -17,49 +17,44 @@ import edu.wpi.first.wpilibj.tables.ITableListener;
import edu.wpi.first.wpilibj.tables.TableKeyNotDefinedException;
/**
* The preferences class provides a relatively simple way to save important
* values to the RoboRIO to access the next time the RoboRIO is booted.
* 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 directly, but may modify values at specific fields which will
* then be automatically saved to the file by the NetworkTables server.
* </p>
* <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>
*
* <p>
* This class is thread safe.
* </p>
* <p> This class is thread safe. </p>
*
* <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. </p>
*
* @author Joe Grinstead
*/
public 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 NetworkTable table;
private final NetworkTable m_table;
/**
* Listener to set all Preferences values to persistent (for backwards
* compatibility with old dashboards).
* Listener to set all Preferences values to persistent (for backwards compatibility with old
* dashboards).
*/
private final ITableListener listener = new ITableListener() {
private final ITableListener m_listener = new ITableListener() {
@Override
public void valueChanged(ITable table, String key, Object value, boolean isNew) {
// unused
}
@Override
public void valueChangedEx(ITable table, String key, Object value, int flags) {
table.setPersistent(key);
@@ -71,7 +66,7 @@ public class Preferences {
*
* @return the preferences instance
*/
public synchronized static Preferences getInstance() {
public static synchronized Preferences getInstance() {
if (instance == null) {
instance = new Preferences();
}
@@ -82,17 +77,18 @@ public class Preferences {
* Creates a preference class.
*/
private Preferences() {
table = NetworkTable.getTable(TABLE_NAME);
table.addTableListenerEx(listener, ITable.NOTIFY_NEW | ITable.NOTIFY_IMMEDIATE);
m_table = NetworkTable.getTable(TABLE_NAME);
m_table.addTableListenerEx(m_listener, ITable.NOTIFY_NEW | ITable.NOTIFY_IMMEDIATE);
UsageReporting.report(tResourceType.kResourceType_Preferences, 0);
}
/**
* Gets the vector of keys.
* @return a vector of the keys
*/
public Vector getKeys() {
Vector<String> keys = new Vector<String>();
for (String key : table.getKeys()) {
for (String key : m_table.getKeys()) {
keys.add(key);
}
return keys;
@@ -101,71 +97,71 @@ public 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
*/
public void putString(String key, String value) {
if (value == null) {
throw new NullPointerException();
throw new NullPointerException("Value is null");
}
table.putString(key, value);
table.setPersistent(key);
m_table.putString(key, value);
m_table.setPersistent(key);
}
/**
* 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) {
table.putNumber(key, value);
table.setPersistent(key);
m_table.putNumber(key, value);
m_table.setPersistent(key);
}
/**
* 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) {
table.putNumber(key, value);
table.setPersistent(key);
m_table.putNumber(key, value);
m_table.setPersistent(key);
}
/**
* 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) {
table.putNumber(key, value);
table.setPersistent(key);
m_table.putNumber(key, value);
m_table.setPersistent(key);
}
/**
* 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) {
table.putBoolean(key, value);
table.setPersistent(key);
m_table.putBoolean(key, value);
m_table.setPersistent(key);
}
/**
* 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) {
table.putNumber(key, value);
table.setPersistent(key);
m_table.putNumber(key, value);
m_table.setPersistent(key);
}
/**
@@ -175,106 +171,106 @@ public class Preferences {
* @return if there is a value at the given key
*/
public boolean containsKey(String key) {
return table.containsKey(key);
return m_table.containsKey(key);
}
/**
* Remove a preference
* Remove a preference.
*
* @param key the key
*/
public void remove(String key) {
table.delete(key);
m_table.delete(key);
}
/**
* 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.
* 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
*/
public String getString(String key, String backup) {
return table.getString(key, backup);
return m_table.getString(key, backup);
}
/**
* 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.
* 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
*/
public int getInt(String key, int backup) {
try {
return (int)table.getNumber(key);
} catch (TableKeyNotDefinedException e) {
return (int) m_table.getNumber(key);
} catch (TableKeyNotDefinedException ex) {
return backup;
}
}
/**
* 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.
* 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
*/
public double getDouble(String key, double backup) {
return table.getDouble(key, backup);
return m_table.getDouble(key, backup);
}
/**
* 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.
* 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
*/
public boolean getBoolean(String key, boolean backup) {
return table.getBoolean(key, backup);
return m_table.getBoolean(key, backup);
}
/**
* 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.
* 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
*/
public float getFloat(String key, float backup) {
try {
return (float)table.getNumber(key);
} catch (TableKeyNotDefinedException e) {
return (float) m_table.getNumber(key);
} catch (TableKeyNotDefinedException ex) {
return backup;
}
}
/**
* 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.
* 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
*/
public long getLong(String key, long backup) {
try {
return (long)table.getNumber(key);
} catch (TableKeyNotDefinedException e) {
return (long) m_table.getNumber(key);
} catch (TableKeyNotDefinedException ex) {
return backup;
}
}
/**
* This function is no longer required, as NetworkTables automatically
* saves persistent values (which all Preferences values are) periodically
* when running as a server.
* This function is no longer required, as NetworkTables automatically saves persistent values
* (which all Preferences values are) periodically when running as a server.
*
* @deprecated backwards compatibility shim
*/
public void save() {

View File

@@ -18,27 +18,28 @@ import edu.wpi.first.wpilibj.tables.ITableListener;
import edu.wpi.first.wpilibj.util.AllocationException;
import edu.wpi.first.wpilibj.util.CheckedAllocationException;
import static java.util.Objects.requireNonNull;
/**
* 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
* pins 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).
* 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 pins 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).
*/
public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable {
private MotorSafetyHelper m_safetyHelper;
/**
* This class represents errors in trying to set relay values contradictory to
* the direction to which the relay is set.
* This class represents errors in trying to set relay values contradictory to the direction to
* which the relay is set.
*/
public class InvalidValueException extends RuntimeException {
/**
* Create a new exception with the given message
* Create a new exception with the given message.
*
* @param message the message to pass with the exception
*/
@@ -50,30 +51,31 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
/**
* The state to drive a Relay to.
*/
public static enum Value {
public enum Value {
/**
* value: off
* value: off.
*/
kOff(0),
/**
* value: on for relays with defined direction
* value: on for relays with defined direction.
*/
kOn(1),
/**
* value: forward
* value: forward.
*/
kForward(2),
/**
* value: reverse
* value: reverse.
*/
kReverse(3);
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
private Value(int value) {
Value(int value) {
this.value = value;
}
}
@@ -81,27 +83,28 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
/**
* The Direction(s) that a relay is configured to operate in.
*/
public static enum Direction {
public enum Direction {
/**
* direction: both directions are valid
* direction: both directions are valid.
*/
kBoth(0),
/**
* direction: Only forward is valid
* direction: Only forward is valid.
*/
kForward(1),
/**
* direction: only reverse is valid
* direction: only reverse is valid.
*/
kReverse(2);
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
private Direction(int value) {
Direction(int value) {
this.value = value;
}
@@ -114,9 +117,9 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
private static Resource relayChannels = new Resource(kRelayChannels * 2);
/**
* Common relay initialization method. This code is common to all Relay
* constructors and initializes the relay and reserves all resources that need
* to be locked. Initially the relay is set to both lines at 0v.
* Common relay initialization method. This code is common to all Relay constructors and
* initializes the relay and reserves all resources that need to be locked. Initially the relay is
* set to both lines at 0v.
*/
private void initRelay() {
SensorBase.checkRelayChannel(m_channel);
@@ -129,7 +132,7 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
relayChannels.allocate(m_channel * 2 + 1);
UsageReporting.report(tResourceType.kResourceType_Relay, m_channel + 128);
}
} catch (CheckedAllocationException e) {
} catch (CheckedAllocationException ex) {
throw new AllocationException("Relay channel " + m_channel + " is already allocated");
}
@@ -144,14 +147,12 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
/**
* Relay constructor given a channel.
*
* @param channel The channel number for this relay (0 - 3).
* @param channel The channel number for this relay (0 - 3).
* @param direction The direction that the Relay object will control.
*/
public Relay(final int channel, Direction direction) {
if (direction == null)
throw new NullPointerException("Null Direction was given");
m_channel = channel;
m_direction = direction;
m_direction = requireNonNull( direction, "Null Direction was given");
initRelay();
set(Value.kOff);
}
@@ -185,15 +186,13 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
/**
* Set the relay state.
*
* Valid values depend on which directions of the relay are controlled by the
* object.
* <p>Valid values depend on which directions of the relay are controlled by the object.
*
* When set to kBothDirections, the relay can be set to any of the four
* states: 0v-0v, 12v-0v, 0v-12v, 12v-12v
* <p>When set to kBothDirections, the relay can be set to any of the four states: 0v-0v, 12v-0v,
* 0v-12v, 12v-12v
*
* When set to kForwardOnly or kReverseOnly, you can specify the constant for
* the direction or you can simply specify kOff_val and kOn_val. Using only
* kOff_val and kOn_val is recommended.
* <p>When set to kForwardOnly or kReverseOnly, you can specify the constant for the direction or
* you can simply specify kOff_val and kOn_val. Using only kOff_val and kOn_val is recommended.
*
* @param value The state to set the relay.
*/
@@ -216,8 +215,10 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
}
break;
case kForward:
if (m_direction == Direction.kReverse)
throw new InvalidValueException("A relay configured for reverse cannot be set to forward");
if (m_direction == Direction.kReverse) {
throw new InvalidValueException("A relay configured for reverse cannot be set to "
+ "forward");
}
if (m_direction == Direction.kBoth || m_direction == Direction.kForward) {
RelayJNI.setRelayForward(m_port, true);
}
@@ -226,8 +227,10 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
}
break;
case kReverse:
if (m_direction == Direction.kForward)
throw new InvalidValueException("A relay configured for forward cannot be set to reverse");
if (m_direction == Direction.kForward) {
throw new InvalidValueException("A relay configured for forward cannot be set to "
+ "reverse");
}
if (m_direction == Direction.kBoth) {
RelayJNI.setRelayForward(m_port, false);
}
@@ -241,11 +244,11 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
}
/**
* Get the Relay State
* Get the Relay State.
*
* Gets the current state of the relay.
* <p>Gets the current state of the relay.
*
* When set to kForwardOnly or kReverseOnly, value is returned as kOn/kOff not
* <p>When set to kForwardOnly or kReverseOnly, value is returned as kOn/kOff not
* kForward/kReverse (per the recommendation in Set)
*
* @return The current state of the relay as a Relay::Value
@@ -319,18 +322,18 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
}
/**
* Set the Relay Direction
* Set the Relay Direction.
*
* Changes which values the relay can be set to depending on which direction
* is used
* <p>Changes which values the relay can be set to depending on which direction is used
*
* Valid inputs are kBothDirections, kForwardOnly, and kReverseOnly
* <p>Valid inputs are kBothDirections, kForwardOnly, and kReverseOnly
*
* @param direction The direction for the relay to operate in
*/
public void setDirection(Direction direction) {
if (direction == null)
if (direction == null) {
throw new NullPointerException("Null Direction was given");
}
if (m_direction == direction) {
return;
}
@@ -351,28 +354,19 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
}
private ITable m_table;
private ITableListener m_table_listener;
private ITableListener m_tableListener;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
@@ -388,12 +382,9 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
}
}
/**
* {@inheritDoc}
*/
@Override
public void startLiveWindowMode() {
m_table_listener = new ITableListener() {
m_tableListener = new ITableListener() {
@Override
public void valueChanged(ITable itable, String key, Object value, boolean bln) {
String val = ((String) value);
@@ -408,15 +399,12 @@ public class Relay extends SensorBase implements MotorSafety, LiveWindowSendable
}
}
};
m_table.addTableListener("Value", m_table_listener, true);
m_table.addTableListener("Value", m_tableListener, true);
}
/**
* {@inheritDoc}
*/
@Override
public void stopLiveWindowMode() {
// TODO: Broken, should only remove the listener from "Value" only.
m_table.removeTableListener(m_table_listener);
m_table.removeTableListener(m_tableListener);
}
}

View File

@@ -11,31 +11,30 @@ import edu.wpi.first.wpilibj.util.AllocationException;
import edu.wpi.first.wpilibj.util.CheckedAllocationException;
/**
* Track resources in the program. The Resource class is a convenient way of
* keeping track of allocated arbitrary resources in the program. Resources are
* just indicies that have an lower and upper bound that are tracked by this
* class. In the library they are used for tracking allocation of hardware
* channels but this is purely arbitrary. The resource class does not do any
* actual allocation, but simply tracks if a given index is currently in use.
* Track resources in the program. The Resource class is a convenient way of keeping track of
* allocated arbitrary resources in the program. Resources are just indicies that have an lower and
* upper bound that are tracked by this class. In the library they are used for tracking allocation
* of hardware channels but this is purely arbitrary. The resource class does not do any actual
* allocation, but simply tracks if a given index is currently in use.
*
* WARNING: this should only be statically allocated. When the program loads
* into memory all the static constructors are called. At that time a linked
* list of all the "Resources" is created. Then when the program actually starts
* - in the Robot constructor, all resources are initialized. This ensures that
* the program is restartable in memory without having to unload/reload.
* <p><b>WARNING:</b> this should only be statically allocated. When the program loads into memory
* all the static constructors are called. At that time a linked list of all the "Resources" is
* created. Then when the program actually starts - in the Robot constructor, all resources are
* initialized. This ensures that the program is restartable in memory without having to
* unload/reload.
*/
public class Resource {
public final class Resource {
private static Resource m_resourceList = null;
private final boolean m_numAllocated[];
private static Resource resourceList = null;
private final boolean[] m_numAllocated;
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.m_resourceList; r != null; r = r.m_nextResource) {
for (Resource r = Resource.resourceList; r != null; r = r.m_nextResource) {
for (int i = 0; i < r.m_size; i++) {
r.m_numAllocated[i] = false;
}
@@ -43,30 +42,28 @@ public 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 indicies of the resources are 0..size-1.
* 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 indicies of the
* resources are 0..size-1.
*
* @param size The number of blocks to allocate
*/
public Resource(final int size) {
m_size = size;
m_numAllocated = new boolean[m_size];
for (int i = 0; i < m_size; i++) {
m_numAllocated = new boolean[size];
for (int i = 0; i < size; i++) {
m_numAllocated[i] = false;
}
m_nextResource = Resource.m_resourceList;
Resource.m_resourceList = this;
m_nextResource = Resource.resourceList;
Resource.resourceList = this;
}
/**
* Allocate a resource. When a resource is requested, mark it allocated. In
* this case, a free resource value within the range is located and returned
* after it is marked allocated.
* Allocate a resource. When a resource is requested, mark it allocated. In this case, a free
* resource value within the range is located and returned after it is marked allocated.
*
* @return The index of the allocated block.
* @throws CheckedAllocationException If there are no resources available to
* be allocated.
* @throws CheckedAllocationException If there are no resources available to be allocated.
*/
public int allocate() throws CheckedAllocationException {
for (int i = 0; i < m_size; i++) {
@@ -79,13 +76,12 @@ public class Resource {
}
/**
* Allocate a specific resource value. The user requests a specific resource
* value, i.e. channel number and it is verified unallocated, then returned.
* Allocate a specific resource value. The user requests a specific resource value, i.e. channel
* number and it is verified unallocated, then returned.
*
* @param index The resource to allocate
* @return The index of the allocated block
* @throws CheckedAllocationException If there are no resources available to
* be allocated.
* @throws CheckedAllocationException If there are no resources available to be allocated.
*/
public int allocate(final int index) throws CheckedAllocationException {
if (index >= m_size || index < 0) {
@@ -99,16 +95,16 @@ public class Resource {
}
/**
* Free an allocated resource. After a resource is no longer needed, for
* example a destructor is called for a channel assignment class, Free will
* release the resource value so it can be reused somewhere else in the
* program.
* Free an allocated resource. After a resource is no longer needed, for example a destructor is
* called for a channel assignment class, Free will release the resource value so it can be reused
* somewhere else in the program.
*
* @param index The index of the resource to free.
*/
public void free(final int index) {
if (m_numAllocated[index] == false)
if (m_numAllocated[index] == false) {
throw new AllocationException("No resource available to be freed");
}
m_numAllocated[index] = false;
}

View File

@@ -10,12 +10,10 @@ package edu.wpi.first.wpilibj;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.jar.Manifest;
import java.util.Arrays;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tInstances;
@@ -24,35 +22,30 @@ import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.internal.HardwareHLUsageReporting;
import edu.wpi.first.wpilibj.internal.HardwareTimer;
import edu.wpi.first.wpilibj.networktables.NetworkTable;
import edu.wpi.first.wpilibj.Utility;
/**
* Implement a Robot Program framework. The RobotBase class is intended to be
* subclassed by a user creating a robot program. Overridden autonomous() and
* operatorControl() methods are called at the appropriate time as the match
* proceeds. In the current implementation, the Autonomous code will run to
* completion before the OperatorControl code could start. In the future the
* Autonomous code might be spawned as a task, then killed at the end of the
* Autonomous period.
* Implement a Robot Program framework. The RobotBase class is intended to be subclassed by a user
* creating a robot program. Overridden autonomous() and operatorControl() methods are called at the
* appropriate time as the match proceeds. In the current implementation, the Autonomous code will
* run to completion before the OperatorControl code could start. In the future the Autonomous code
* might be spawned as a task, then killed at the end of the Autonomous period.
*/
public abstract class RobotBase {
/**
* The VxWorks priority that robot code should work at (so Java code should
* run at)
* The VxWorks priority that robot code should work at (so Java code should run at).
*/
public static final int ROBOT_TASK_PRIORITY = 101;
protected final DriverStation m_ds;
/**
* Constructor for a generic robot program. User code should be placed in the
* constructor that runs before the Autonomous or Operator Control period
* starts. The constructor will run to completion before Autonomous is
* entered.
* Constructor for a generic robot program. User code should be placed in the constructor that
* runs before the Autonomous or Operator Control period starts. The constructor will run to
* completion before Autonomous is entered.
*
* 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.
* <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.
*/
protected RobotBase() {
// TODO: StartCAPI();
@@ -70,7 +63,8 @@ public abstract class RobotBase {
/**
* Free the resources for a RobotBase class.
*/
public void free() {}
public void free() {
}
/**
* @return If the robot is running in simulation.
@@ -88,7 +82,7 @@ public abstract class RobotBase {
/**
* Determine if the Robot is currently disabled.
*$
*
* @return True if the Robot is currently disabled by the field controls.
*/
public boolean isDisabled() {
@@ -97,7 +91,7 @@ public abstract class RobotBase {
/**
* Determine if the Robot is currently enabled.
*$
*
* @return True if the Robot is currently enabled by the field controls.
*/
public boolean isEnabled() {
@@ -105,30 +99,30 @@ public abstract class RobotBase {
}
/**
* Determine if the robot is currently in Autonomous mode.
*$
* @return True if the robot is currently operating Autonomously 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.
*/
public boolean isAutonomous() {
return m_ds.isAutonomous();
}
/**
* Determine if the robot is currently in Test mode
*$
* @return True if the robot is currently operating 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.
*/
public boolean isTest() {
return m_ds.isTest();
}
/**
* Determine if the robot is currently in Operator Control mode.
*$
* @return True if the robot is currently operating in Tele-Op mode as
* determined by the field controls.
* Determine if the robot is currently in Operator Control mode as determined by the field
* controls.
*
* @return True if the robot is currently operating in Tele-Op mode.
*/
public boolean isOperatorControl() {
return m_ds.isOperatorControl();
@@ -136,9 +130,8 @@ public abstract class RobotBase {
/**
* Indicates if new data is available from the driver station.
*$
* @return Has new data arrived over the network since the last time this
* function was called?
*
* @return Has new data arrived over the network since the last time this function was called?
*/
public boolean isNewDataAvailable() {
return m_ds.isNewControlData();
@@ -149,6 +142,7 @@ public abstract class RobotBase {
*/
public abstract void startCompetition();
@SuppressWarnings("JavadocMethod")
public static boolean getBooleanProperty(String name, boolean defaultValue) {
String propVal = System.getProperty(name);
if (propVal == null) {
@@ -178,7 +172,7 @@ public abstract class RobotBase {
/**
* Starting point for the applications.
*/
public static void main(String args[]) {
public static void main(String... args) {
initializeHardwareConfiguration();
UsageReporting.report(tResourceType.kResourceType_Language, tInstances.kLanguage_Java);
@@ -187,70 +181,63 @@ public abstract class RobotBase {
Enumeration<URL> resources = null;
try {
resources = RobotBase.class.getClassLoader().getResources("META-INF/MANIFEST.MF");
} catch (IOException e) {
e.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
while (resources != null && resources.hasMoreElements()) {
try {
Manifest manifest = new Manifest(resources.nextElement().openStream());
robotName = manifest.getMainAttributes().getValue("Robot-Class");
} catch (IOException e) {
e.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
RobotBase robot;
try {
robot = (RobotBase) Class.forName(robotName).newInstance();
} catch (Throwable t) {
} catch (Throwable throwable) {
DriverStation.reportError("ERROR Unhandled exception instantiating robot " + robotName + " "
+ t.toString() + " at " + Arrays.toString(t.getStackTrace()), false);
+ throwable.toString() + " at " + Arrays.toString(throwable.getStackTrace()), false);
System.err.println("WARNING: Robots don't quit!");
System.err.println("ERROR: Could not instantiate robot " + robotName + "!");
System.exit(1);
return;
}
File file = null;
FileOutputStream output = null;
try {
file = new File("/tmp/frc_versions/FRC_Lib_Version.ini");
final File file = new File("/tmp/frc_versions/FRC_Lib_Version.ini");
if (file.exists())
if (file.exists()) {
file.delete();
}
file.createNewFile();
output = new FileOutputStream(file);
output.write("2016 Java Release 5".getBytes());
try (FileOutputStream output = new FileOutputStream(file)) {
output.write("2016 Java Release 5".getBytes());
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (output != null) {
try {
output.close();
} catch (IOException ex) {
}
}
}
boolean errorOnExit = false;
try {
System.out.println("********** Robot program starting **********");
robot.startCompetition();
} catch (Throwable t) {
} catch (Throwable throwable) {
DriverStation.reportError(
"ERROR Unhandled exception: " + t.toString() + " at "
+ Arrays.toString(t.getStackTrace()), false);
"ERROR Unhandled exception: " + throwable.toString() + " at "
+ Arrays.toString(throwable.getStackTrace()), false);
errorOnExit = true;
} finally {
// startCompetition never returns unless exception occurs....
System.err.println("WARNING: Robots don't quit!");
if (errorOnExit) {
System.err
.println("---> The startCompetition() method (or methods called by it) should have handled the exception above.");
.println("---> The startCompetition() method (or methods called by it) should have "
+ "handled the exception above.");
} else {
System.err.println("---> Unexpected return from startCompetition() method.");
}

View File

@@ -11,47 +11,48 @@ import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tInst
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import static java.util.Objects.requireNonNull;
/**
* 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 drive trains are supported. In the
* future other drive types like swerve might be implemented. Motor channel
* numbers are supplied on creation of the class. Those are used for either the
* drive function (intended for hand created drive code, such as autonomous) or
* with the Tank/Arcade functions intended to be used for Operator Control
* driving.
* 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
* drive trains are supported. In the future other drive types like swerve might be implemented.
* Motor channel numbers are supplied on creation of the class. Those are used for either the drive
* function (intended for hand created drive code, such as autonomous) or with the Tank/Arcade
* functions intended to be used for Operator Control driving.
*/
public class RobotDrive implements MotorSafety {
protected MotorSafetyHelper m_safetyHelper;
/**
* 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 static class MotorType {
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
static final int kFrontLeft_val = 0;
static final int kFrontRight_val = 1;
static final int kRearLeft_val = 2;
static final int kRearRight_val = 3;
/**
* motortype: front left
* motortype: front left.
*/
public static final MotorType kFrontLeft = new MotorType(kFrontLeft_val);
/**
* motortype: front right
* motortype: front right.
*/
public static final MotorType kFrontRight = new MotorType(kFrontRight_val);
/**
* motortype: rear left
* motortype: rear left.
*/
public static final MotorType kRearLeft = new MotorType(kRearLeft_val);
/**
* motortype: rear right
* motortype: rear right.
*/
public static final MotorType kRearRight = new MotorType(kRearRight_val);
@@ -79,14 +80,12 @@ public class RobotDrive implements MotorSafety {
protected static boolean kMecanumPolar_Reported = false;
/**
* Constructor for RobotDrive with 2 motors specified with channel numbers.
* Set up parameters for 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 rightMotorChannel The PWM channel number that drives the right
* motor.
* Constructor for RobotDrive with 2 motors specified with channel numbers. Set up parameters for
* 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 rightMotorChannel The PWM channel number that drives the right motor.
*/
public RobotDrive(final int leftMotorChannel, final int rightMotorChannel) {
m_sensitivity = kDefaultSensitivity;
@@ -101,18 +100,17 @@ public class RobotDrive implements MotorSafety {
}
/**
* Constructor for RobotDrive with 4 motors specified with channel numbers.
* Set up parameters for 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
* Constructor for RobotDrive with 4 motors specified with channel numbers. Set up parameters for
* 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 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) {
final int rearRightMotor) {
m_sensitivity = kDefaultSensitivity;
m_maxOutput = kDefaultMaxOutput;
m_rearLeftMotor = new Talon(rearLeftMotor);
@@ -125,13 +123,12 @@ public class RobotDrive implements MotorSafety {
}
/**
* Constructor for RobotDrive with 2 motors specified as SpeedController
* objects. The SpeedController version of the constructor enables programs to
* use the RobotDrive classes with 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.
* Constructor for RobotDrive with 2 motors specified as SpeedController objects. The
* SpeedController version of the constructor enables programs to use the RobotDrive classes with
* 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 rightMotor the right SpeedController object used to drive the robot.
*/
public RobotDrive(SpeedController leftMotor, SpeedController rightMotor) {
@@ -151,30 +148,20 @@ public class RobotDrive implements MotorSafety {
}
/**
* Constructor for RobotDrive with 4 motors specified as SpeedController
* objects. Speed controller input version of RobotDrive (see previous
* comments).
*$
* @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 rearRightMotor The back right SpeedController object used to drive
* the robot.
* @param frontRightMotor The front right SpeedController object used to drive
* the robot.
* Constructor for RobotDrive with 4 motors specified as SpeedController objects. Speed controller
* input version of RobotDrive (see previous comments).
*
* @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 rearRightMotor The back right SpeedController object used to drive the robot.
* @param frontRightMotor The front right SpeedController object used to drive the robot.
*/
public RobotDrive(SpeedController frontLeftMotor, SpeedController rearLeftMotor,
SpeedController frontRightMotor, SpeedController rearRightMotor) {
if (frontLeftMotor == null || rearLeftMotor == null || frontRightMotor == null
|| rearRightMotor == null) {
m_frontLeftMotor = m_rearLeftMotor = m_frontRightMotor = m_rearRightMotor = null;
throw new NullPointerException("Null motor provided");
}
m_frontLeftMotor = frontLeftMotor;
m_rearLeftMotor = rearLeftMotor;
m_frontRightMotor = frontRightMotor;
m_rearRightMotor = rearRightMotor;
SpeedController frontRightMotor, SpeedController rearRightMotor) {
m_frontLeftMotor = requireNonNull(frontLeftMotor, "frontLeftMotor cannot be null");
m_rearLeftMotor = requireNonNull(rearLeftMotor, "rearLeftMotor cannot be null");
m_frontRightMotor = requireNonNull(frontRightMotor, "frontRightMotor cannot be null");
m_rearRightMotor = requireNonNull(rearRightMotor, "rearRightMotor cannot be null");
m_sensitivity = kDefaultSensitivity;
m_maxOutput = kDefaultMaxOutput;
m_allocatedSpeedControllers = false;
@@ -183,27 +170,26 @@ public class RobotDrive implements MotorSafety {
}
/**
* Drive the motors at "outputMagnitude" and "curve".
* Both outputMagnitude and curve are -1.0 to +1.0 values, where 0.0
* represents stopped and not turning. {@literal curve < 0 will turn left and curve > 0}
* will turn right.
* Drive the motors at "outputMagnitude" and "curve". Both outputMagnitude and curve are -1.0 to
* +1.0 values, where 0.0 represents stopped and not turning. {@literal curve < 0 will turn left
* and curve > 0} will turn right.
*
* The algorithm for steering provides a constant turn radius for any normal
* speed range, both forward and backward. Increasing m_sensitivity causes
* sharper turns for fixed values of curve.
* <p>The algorithm for steering provides a constant turn radius for any normal speed range, both
* forward and backward. Increasing sensitivity causes sharper turns for fixed values of curve.
*
* This function will most likely be used in an autonomous routine.
* <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.
* @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.
*/
public void drive(double outputMagnitude, double curve) {
double leftOutput, rightOutput;
final double leftOutput;
final double rightOutput;
if (!kArcadeRatioCurve_Reported) {
UsageReporting.report(tResourceType.kResourceType_RobotDrive, getNumMotors(),
@@ -234,11 +220,10 @@ public class RobotDrive implements MotorSafety {
}
/**
* 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.
* 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.
*/
public void tankDrive(GenericHID leftStick, GenericHID rightStick) {
@@ -249,14 +234,12 @@ public class RobotDrive implements MotorSafety {
}
/**
* 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 squaredInputs Setting this parameter to true decreases the
* sensitivity at lower speeds
* 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 squaredInputs Setting this parameter to true decreases the sensitivity at lower speeds
*/
public void tankDrive(GenericHID leftStick, GenericHID rightStick, boolean squaredInputs) {
if (leftStick == null || rightStick == null) {
@@ -266,18 +249,16 @@ public class RobotDrive implements MotorSafety {
}
/**
* 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.
* 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.
*/
public void tankDrive(GenericHID leftStick, final int leftAxis, GenericHID rightStick,
final int rightAxis) {
final int rightAxis) {
if (leftStick == null || rightStick == null) {
throw new NullPointerException("Null HID provided");
}
@@ -285,20 +266,17 @@ public class RobotDrive implements MotorSafety {
}
/**
* 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 squaredInputs Setting this parameter to true decreases the
* sensitivity at lower speeds
* 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 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) {
final int rightAxis, boolean squaredInputs) {
if (leftStick == null || rightStick == null) {
throw new NullPointerException("Null HID provided");
}
@@ -306,13 +284,12 @@ public class RobotDrive implements MotorSafety {
}
/**
* 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 squaredInputs Setting this parameter to true decreases the
* sensitivity at lower speeds
* 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 squaredInputs Setting this parameter to true decreases the sensitivity at lower speeds
*/
public void tankDrive(double leftValue, double rightValue, boolean squaredInputs) {
@@ -342,10 +319,10 @@ public class RobotDrive implements MotorSafety {
}
/**
* 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.
* 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.
*/
public void tankDrive(double leftValue, double rightValue) {
@@ -353,16 +330,14 @@ public class RobotDrive implements MotorSafety {
}
/**
* Arcade drive implements single stick driving. Given a single Joystick, the
* class assumes the Y 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 squaredInputs If true, the sensitivity will be decreased for small
* values
* Arcade drive implements single stick driving. Given a single Joystick, the class assumes the Y
* 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 squaredInputs If true, the sensitivity will be decreased for small values
*/
public void arcadeDrive(GenericHID stick, boolean squaredInputs) {
// simply call the full-featured arcadeDrive with the appropriate values
@@ -370,35 +345,31 @@ public class RobotDrive implements MotorSafety {
}
/**
* Arcade drive implements single stick driving. Given a single Joystick, the
* class assumes the Y 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.
* Arcade drive implements single stick driving. Given a single Joystick, the class assumes the Y
* 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.
*/
public void arcadeDrive(GenericHID stick) {
this.arcadeDrive(stick, true);
arcadeDrive(stick, true);
}
/**
* 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 squaredInputs Setting this parameter to true decreases the
* sensitivity at lower speeds
* 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 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) {
final int rotateAxis, boolean squaredInputs) {
double moveValue = moveStick.getRawAxis(moveAxis);
double rotateValue = rotateStick.getRawAxis(rotateAxis);
@@ -406,28 +377,27 @@ public class RobotDrive implements MotorSafety {
}
/**
* 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)
* 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 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) {
this.arcadeDrive(moveStick, moveAxis, rotateStick, rotateAxis, true);
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.
*$
* @param moveValue The value to use for forwards/backwards
* @param rotateValue The value to use for the rotate right/left
* 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 squaredInputs If set, decreases the sensitivity at low speeds
*/
public void arcadeDrive(double moveValue, double rotateValue, boolean squaredInputs) {
@@ -481,52 +451,52 @@ public class RobotDrive implements MotorSafety {
}
/**
* Arcade drive implements single stick driving. This function lets you
* directly provide joystick values from any source.
*$
* @param moveValue The value to use for fowards/backwards
* Arcade drive implements single stick driving. This function lets you directly provide
* joystick values from any source.
*
* @param moveValue The value to use for fowards/backwards
* @param rotateValue The value to use for the rotate right/left
*/
public void arcadeDrive(double moveValue, double rotateValue) {
this.arcadeDrive(moveValue, rotateValue, true);
arcadeDrive(moveValue, rotateValue, true);
}
/**
* Drive method for Mecanum wheeled robots.
*
* A method for driving with Mecanum wheeled robots. There are 4 wheels on the
* robot, arranged so that the front and back wheels are toed in 45 degrees.
* When looking at the wheels from the top, the roller axles should form an X
* across the robot.
* <p>A method for driving with Mecanum wheeled robots. There are 4 wheels on the robot, arranged
* so that the front and back wheels are toed in 45 degrees. When looking at the wheels from the
* top, the roller axles should form an X across the robot.
*
* This is designed to be directly driven by joystick axes.
* <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 gyroAngle The current angle reading from the gyro. Use this to
* implement field-oriented controls.
* @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.
*/
@SuppressWarnings("ParameterName")
public void mecanumDrive_Cartesian(double x, double y, double rotation, double gyroAngle) {
if (!kMecanumCartesian_Reported) {
UsageReporting.report(tResourceType.kResourceType_RobotDrive, getNumMotors(),
tInstances.kRobotDrive_MecanumCartesian);
kMecanumCartesian_Reported = true;
}
@SuppressWarnings("LocalVariableName")
double xIn = x;
@SuppressWarnings("LocalVariableName")
double yIn = y;
// Negate y for the joystick.
yIn = -yIn;
// Compenstate for gyro angle.
double rotated[] = rotateVector(xIn, yIn, gyroAngle);
double[] rotated = rotateVector(xIn, yIn, gyroAngle);
xIn = rotated[0];
yIn = rotated[1];
double wheelSpeeds[] = new double[kMaxNumberOfMotors];
double[] wheelSpeeds = new double[kMaxNumberOfMotors];
wheelSpeeds[MotorType.kFrontLeft_val] = xIn + yIn + rotation;
wheelSpeeds[MotorType.kFrontRight_val] = -xIn + yIn - rotation;
wheelSpeeds[MotorType.kRearLeft_val] = -xIn + yIn + rotation;
@@ -542,24 +512,23 @@ public class RobotDrive implements MotorSafety {
CANJaguar.updateSyncGroup(m_syncGroup);
}
if (m_safetyHelper != null)
if (m_safetyHelper != null) {
m_safetyHelper.feed();
}
}
/**
* Drive method for Mecanum wheeled robots.
*
* A method for driving with Mecanum wheeled robots. There are 4 wheels on the
* robot, arranged so that the front and back wheels are toed in 45 degrees.
* When looking at the wheels from the top, the roller axles should form an X
* across the robot.
* <p>A method for driving with Mecanum wheeled robots. There are 4 wheels on the robot, arranged
* so that the front and back wheels are toed in 45 degrees. When looking at the wheels from the
* top, the roller axles should form an X across the robot.
*
* @param magnitude The speed that the robot should drive in a given
* direction.
* @param direction The direction the robot should drive in degrees. The
* direction and maginitute 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]
* @param magnitude The speed that the robot should drive in a given direction.
* @param direction The direction the robot should drive in degrees. The direction and maginitute
* 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]
*/
public void mecanumDrive_Polar(double magnitude, double direction, double rotation) {
if (!kMecanumPolar_Reported) {
@@ -567,7 +536,6 @@ public class RobotDrive implements MotorSafety {
tInstances.kRobotDrive_MecanumPolar);
kMecanumPolar_Reported = true;
}
double frontLeftSpeed, rearLeftSpeed, frontRightSpeed, rearRightSpeed;
// Normalized for full power along the Cartesian axes.
magnitude = limit(magnitude) * Math.sqrt(2.0);
// The rollers are at 45 degree angles.
@@ -575,7 +543,7 @@ public class RobotDrive implements MotorSafety {
double cosD = Math.cos(dirInRad);
double sinD = Math.sin(dirInRad);
double wheelSpeeds[] = new double[kMaxNumberOfMotors];
double[] wheelSpeeds = new double[kMaxNumberOfMotors];
wheelSpeeds[MotorType.kFrontLeft_val] = (sinD * magnitude + rotation);
wheelSpeeds[MotorType.kFrontRight_val] = (cosD * magnitude - rotation);
wheelSpeeds[MotorType.kRearLeft_val] = (cosD * magnitude + rotation);
@@ -588,37 +556,36 @@ public class RobotDrive implements MotorSafety {
m_rearLeftMotor.set(wheelSpeeds[MotorType.kRearLeft_val] * m_maxOutput, m_syncGroup);
m_rearRightMotor.set(wheelSpeeds[MotorType.kRearRight_val] * m_maxOutput, m_syncGroup);
if (this.m_syncGroup != 0) {
if (m_syncGroup != 0) {
CANJaguar.updateSyncGroup(m_syncGroup);
}
if (m_safetyHelper != null)
if (m_safetyHelper != null) {
m_safetyHelper.feed();
}
}
/**
* Holonomic Drive method for Mecanum wheeled robots.
*
* This is an alias to mecanumDrive_Polar() for backward compatability
* <p>This is an alias to mecanumDrive_Polar() for backward compatability
*
* @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
* maginitute 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]
* @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 maginitute 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]
*/
void holonomicDrive(float magnitude, float direction, float rotation) {
mecanumDrive_Polar(magnitude, direction, rotation);
}
/**
* 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.
*$
* @param leftOutput The speed to send to the left side of the robot.
* 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.
*
* @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) {
@@ -636,12 +603,13 @@ public class RobotDrive implements MotorSafety {
}
m_rearRightMotor.set(-limit(rightOutput) * m_maxOutput, m_syncGroup);
if (this.m_syncGroup != 0) {
if (m_syncGroup != 0) {
CANJaguar.updateSyncGroup(m_syncGroup);
}
if (m_safetyHelper != null)
if (m_safetyHelper != null) {
m_safetyHelper.feed();
}
}
/**
@@ -658,19 +626,18 @@ public class RobotDrive implements 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 static void normalize(double wheelSpeeds[]) {
protected static void normalize(double[] wheelSpeeds) {
double maxMagnitude = Math.abs(wheelSpeeds[0]);
int i;
for (i = 1; i < kMaxNumberOfMotors; i++) {
for (int i = 1; i < kMaxNumberOfMotors; i++) {
double temp = Math.abs(wheelSpeeds[i]);
if (maxMagnitude < temp)
if (maxMagnitude < temp) {
maxMagnitude = temp;
}
}
if (maxMagnitude > 1.0) {
for (i = 0; i < kMaxNumberOfMotors; i++) {
for (int i = 0; i < kMaxNumberOfMotors; i++) {
wheelSpeeds[i] = wheelSpeeds[i] / maxMagnitude;
}
}
@@ -679,22 +646,22 @@ public class RobotDrive implements MotorSafety {
/**
* Rotate a vector in Cartesian space.
*/
@SuppressWarnings("ParameterName")
protected static double[] rotateVector(double x, double y, double angle) {
double cosA = Math.cos(angle * (3.14159 / 180.0));
double sinA = Math.sin(angle * (3.14159 / 180.0));
double out[] = new double[2];
double[] out = new double[2];
out[0] = x * cosA - y * sinA;
out[1] = x * sinA + y * cosA;
return out;
}
/**
* Invert a motor direction. This is used when a motor should run in the
* opposite direction as the 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.
* Invert a motor direction. This is used when a motor should run in the opposite direction as the
* 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 isInverted True if the motor should be inverted when operated.
*/
public void setInvertedMotor(MotorType motor, boolean isInverted) {
@@ -711,36 +678,36 @@ public class RobotDrive implements MotorSafety {
case MotorType.kRearRight_val:
m_rearRightMotor.setInverted(isInverted);
break;
default:
throw new IllegalArgumentException("Illegal motor type: " + motor);
}
}
/**
* Set the turning sensitivity.
*
* This only impacts the drive() entry-point.
*$
* @param sensitivity Effectively sets the turning sensitivity (or turn radius
* for a given value)
* <p>This only impacts the drive() entry-point.
*
* @param sensitivity Effectively sets the turning sensitivity (or turn radius for a given value)
*/
public void setSensitivity(double sensitivity) {
m_sensitivity = sensitivity;
}
/**
* Configure the scaling factor for using RobotDrive with motor controllers in
* a mode other than PercentVbus.
*$
* @param maxOutput Multiplied with the output percentage computed by the
* drive functions.
* Configure the scaling factor for using RobotDrive with motor controllers in a mode other than
* PercentVbus.
*
* @param maxOutput Multiplied with the output percentage computed by the drive functions.
*/
public void setMaxOutput(double maxOutput) {
m_maxOutput = maxOutput;
}
/**
* Set the number of the sync group for the motor controllers. If the motor
* controllers are {@link CANJaguar}s, then they will all be added to this
* sync group, causing them to update their values at the same time.
* Set the number of the sync group for the motor controllers. If the motor controllers are {@link
* CANJaguar}s, then they will all be added to this sync group, causing them to update their
* values at the same time.
*
* @param syncGroup the update group to add the motor controllers to
*/
@@ -749,7 +716,7 @@ public class RobotDrive implements MotorSafety {
}
/**
* Free the speed controllers if they were allocated locally
* Free the speed controllers if they were allocated locally.
*/
public void free() {
if (m_allocatedSpeedControllers) {
@@ -768,30 +735,37 @@ public class RobotDrive implements MotorSafety {
}
}
@Override
public void setExpiration(double timeout) {
m_safetyHelper.setExpiration(timeout);
}
@Override
public double getExpiration() {
return m_safetyHelper.getExpiration();
}
@Override
public boolean isAlive() {
return m_safetyHelper.isAlive();
}
@Override
public boolean isSafetyEnabled() {
return m_safetyHelper.isSafetyEnabled();
}
@Override
public void setSafetyEnabled(boolean enabled) {
m_safetyHelper.setSafetyEnabled(enabled);
}
@Override
public String getDescription() {
return "Robot Drive";
}
@Override
public void stopMotor() {
if (m_frontLeftMotor != null) {
m_frontLeftMotor.stopMotor();
@@ -805,8 +779,9 @@ public class RobotDrive implements MotorSafety {
if (m_rearRightMotor != null) {
m_rearRightMotor.stopMotor();
}
if (m_safetyHelper != null)
if (m_safetyHelper != null) {
m_safetyHelper.feed();
}
}
private void setupMotorSafety() {
@@ -817,14 +792,18 @@ public class RobotDrive implements MotorSafety {
protected int getNumMotors() {
int motors = 0;
if (m_frontLeftMotor != null)
if (m_frontLeftMotor != null) {
motors++;
if (m_frontRightMotor != null)
}
if (m_frontRightMotor != null) {
motors++;
if (m_rearLeftMotor != null)
}
if (m_rearLeftMotor != null) {
motors++;
if (m_rearRightMotor != null)
}
if (m_rearRightMotor != null) {
motors++;
}
return motors;
}
}

View File

@@ -12,23 +12,22 @@ import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* Mindsensors SD540 Speed Controller
* Mindsensors SD540 Speed Controller.
*/
public class SD540 extends PWMSpeedController {
/**
* Common initialization code called by all constructors.
*
* 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.
* <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.
*
* - 2.05ms = full "forward" - 1.55ms = the "high end" of the deadband range
* - 1.50ms = center of the deadband range (off) - 1.44ms = the "low end" of
* the deadband range - .94ms = full "reverse"
* <p>- 2.05ms = full "forward" - 1.55ms = the "high end" of the deadband range - 1.50ms = center
* of the deadband range (off) - 1.44ms = the "low end" of the deadband range - .94ms = full
* "reverse"
*/
protected void initSD540() {
setBounds(2.05, 1.55, 1.50, 1.44, .94);
@@ -43,8 +42,8 @@ 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
* @param channel The PWM channel that the SD540 is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
public SD540(final int channel) {
super(channel);

View File

@@ -7,19 +7,16 @@
package edu.wpi.first.wpilibj;
import java.nio.ByteOrder;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ByteOrder;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.hal.SPIJNI;
/**
* Represents a SPI bus port.
*
* Represents a SPI bus port
*$
* @author koconnor
*/
public class SPI extends SensorBase {
@@ -27,26 +24,26 @@ public class SPI extends SensorBase {
public enum Port {
kOnboardCS0(0), kOnboardCS1(1), kOnboardCS2(2), kOnboardCS3(3), kMXP(4);
private int value;
private int m_value;
private Port(int value) {
this.value = value;
Port(int value) {
m_value = value;
}
public int getValue() {
return this.value;
return m_value;
}
};
}
private static int devices = 0;
private byte m_port;
private int bitOrder;
private int clockPolarity;
private int dataOnTrailing;
private int m_bitOrder;
private int m_clockPolarity;
private int m_dataOnTrailing;
/**
* Constructor
* Constructor.
*
* @param port the physical SPI port
*/
@@ -60,15 +57,15 @@ public class SPI extends SensorBase {
}
/**
* Free the resources used by this object
* Free the resources used by this object.
*/
public void free() {
SPIJNI.spiClose(m_port);
}
/**
* Configure the rate of the generated clock signal. The default value is
* 500,000 Hz. The maximum value is 4,000,000 Hz.
* Configure the rate of the generated clock signal. The default value is 500,000 Hz. The maximum
* value is 4,000,000 Hz.
*
* @param hz The clock rate in Hertz.
*/
@@ -77,57 +74,55 @@ public class SPI extends SensorBase {
}
/**
* Configure the order that bits are sent and received on the wire to be most
* significant bit first.
* Configure the order that bits are sent and received on the wire to be most significant bit
* first.
*/
public final void setMSBFirst() {
this.bitOrder = 1;
SPIJNI.spiSetOpts(m_port, this.bitOrder, this.dataOnTrailing, this.clockPolarity);
m_bitOrder = 1;
SPIJNI.spiSetOpts(m_port, m_bitOrder, m_dataOnTrailing, m_clockPolarity);
}
/**
* Configure the order that bits are sent and received on the wire to be least
* significant bit first.
* Configure the order that bits are sent and received on the wire to be least significant bit
* first.
*/
public final void setLSBFirst() {
this.bitOrder = 0;
SPIJNI.spiSetOpts(m_port, this.bitOrder, this.dataOnTrailing, this.clockPolarity);
m_bitOrder = 0;
SPIJNI.spiSetOpts(m_port, m_bitOrder, m_dataOnTrailing, m_clockPolarity);
}
/**
* Configure the clock output line to be active low. This is sometimes called
* clock polarity high or clock idle high.
* Configure the clock output line to be active low. This is sometimes called clock polarity high
* or clock idle high.
*/
public final void setClockActiveLow() {
this.clockPolarity = 1;
SPIJNI.spiSetOpts(m_port, this.bitOrder, this.dataOnTrailing, this.clockPolarity);
m_clockPolarity = 1;
SPIJNI.spiSetOpts(m_port, m_bitOrder, m_dataOnTrailing, m_clockPolarity);
}
/**
* Configure the clock output line to be active high. This is sometimes called
* clock polarity low or clock idle low.
* Configure the clock output line to be active high. This is sometimes called clock polarity low
* or clock idle low.
*/
public final void setClockActiveHigh() {
this.clockPolarity = 0;
SPIJNI.spiSetOpts(m_port, this.bitOrder, this.dataOnTrailing, this.clockPolarity);
m_clockPolarity = 0;
SPIJNI.spiSetOpts(m_port, m_bitOrder, m_dataOnTrailing, m_clockPolarity);
}
/**
* Configure that the data is stable on the falling edge and the data changes
* on the rising edge.
* Configure that the data is stable on the falling edge and the data changes on the rising edge.
*/
public final void setSampleDataOnFalling() {
this.dataOnTrailing = 1;
SPIJNI.spiSetOpts(m_port, this.bitOrder, this.dataOnTrailing, this.clockPolarity);
m_dataOnTrailing = 1;
SPIJNI.spiSetOpts(m_port, m_bitOrder, m_dataOnTrailing, m_clockPolarity);
}
/**
* Configure that the data is stable on the rising edge and the data changes
* on the falling edge.
* Configure that the data is stable on the rising edge and the data changes on the falling edge.
*/
public final void setSampleDataOnRising() {
this.dataOnTrailing = 0;
SPIJNI.spiSetOpts(m_port, this.bitOrder, this.dataOnTrailing, this.clockPolarity);
m_dataOnTrailing = 0;
SPIJNI.spiSetOpts(m_port, m_bitOrder, m_dataOnTrailing, m_clockPolarity);
}
/**
@@ -145,11 +140,10 @@ public class SPI extends SensorBase {
}
/**
* Write data to the slave device. Blocks until there is space in the output
* FIFO.
* Write data to the slave device. Blocks until there is space in the output FIFO.
*
* If not running in output only mode, also saves the data received on the
* MISO input during the transfer into the receive FIFO.
* <p>If not running in output only mode, also saves the data received on the MISO input during
* the transfer into the receive FIFO.
*/
public int write(byte[] dataToSend, int size) {
ByteBuffer dataToSendBuffer = ByteBuffer.allocateDirect(size);
@@ -158,43 +152,44 @@ public class SPI extends SensorBase {
}
/**
* Write data to the slave device. Blocks until there is space in the output
* FIFO.
* Write data to the slave device. Blocks until there is space in the output FIFO.
*
* If not running in output only mode, also saves the data received on the
* MISO input during the transfer into the receive FIFO.
* <p>If not running in output only mode, also saves the data received on the MISO input during
* the transfer into the receive FIFO.
*
* @param dataToSend The buffer containing the data to send. Must be created
* using ByteBuffer.allocateDirect().
* @param dataToSend The buffer containing the data to send. Must be created using
* ByteBuffer.allocateDirect().
*/
public int write(ByteBuffer dataToSend, int size) {
if (!dataToSend.isDirect())
if (!dataToSend.isDirect()) {
throw new IllegalArgumentException("must be a direct buffer");
if (dataToSend.capacity() < size)
}
if (dataToSend.capacity() < size) {
throw new IllegalArgumentException("buffer is too small, must be at least " + size);
}
return SPIJNI.spiWrite(m_port, dataToSend, (byte) size);
}
/**
* Read a word from the receive FIFO.
*
* Waits for the current transfer to complete if the receive FIFO is empty.
* <p>Waits for the current transfer to complete if the receive FIFO is empty.
*
* If the receive FIFO is empty, there is no active transfer, and initiate is
* false, errors.
* <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.
*/
public int read(boolean initiate, byte[] dataReceived, int size) {
int retVal = 0;
final int retVal;
ByteBuffer dataReceivedBuffer = ByteBuffer.allocateDirect(size);
ByteBuffer dataToSendBuffer = ByteBuffer.allocateDirect(size);
if (initiate)
if (initiate) {
retVal = SPIJNI.spiTransaction(m_port, dataToSendBuffer, dataReceivedBuffer, (byte) size);
else
} else {
retVal = SPIJNI.spiRead(m_port, dataReceivedBuffer, (byte) size);
}
dataReceivedBuffer.get(dataReceived);
return retVal;
}
@@ -202,25 +197,24 @@ public class SPI extends SensorBase {
/**
* Read a word from the receive FIFO.
*
* Waits for the current transfer to complete if the receive FIFO is empty.
* <p>Waits for the current transfer to complete if the receive FIFO is empty.
*
* If the receive FIFO is empty, there is no active transfer, and initiate is
* false, errors.
* <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 dataReceived The buffer to be filled with the received data. Must be
* created using ByteBuffer.allocateDirect().
*
* @param size The length of the transaction, in bytes
* @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. Must be created using
* ByteBuffer.allocateDirect().
* @param size The length of the transaction, in bytes
*/
public int read(boolean initiate, ByteBuffer dataReceived, int size) {
if (!dataReceived.isDirect())
if (!dataReceived.isDirect()) {
throw new IllegalArgumentException("must be a direct buffer");
if (dataReceived.capacity() < size)
}
if (dataReceived.capacity() < size) {
throw new IllegalArgumentException("buffer is too small, must be at least " + size);
}
if (initiate) {
ByteBuffer dataToSendBuffer = ByteBuffer.allocateDirect(size);
return SPIJNI.spiTransaction(m_port, dataToSendBuffer, dataReceived, (byte) size);
@@ -229,11 +223,11 @@ public class SPI extends SensorBase {
}
/**
* Perform a simultaneous read/write transaction with the device
* 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) {
ByteBuffer dataToSendBuffer = ByteBuffer.allocateDirect(size);
@@ -247,46 +241,48 @@ public class SPI extends SensorBase {
/**
* Perform a simultaneous read/write transaction with the device
*
* @param dataToSend The data to be written out to the device. Must be
* created using ByteBuffer.allocateDirect().
* @param dataReceived Buffer to receive data from the device. Must be
* created using ByteBuffer.allocateDirect().
* @param size The length of the transaction, in bytes
* @param dataToSend The data to be written out to the device. Must be created using
* ByteBuffer.allocateDirect().
* @param dataReceived Buffer to receive data from the device. Must be created using
* ByteBuffer.allocateDirect().
* @param size The length of the transaction, in bytes
*/
public int transaction(ByteBuffer dataToSend, ByteBuffer dataReceived, int size) {
if (!dataToSend.isDirect())
if (!dataToSend.isDirect()) {
throw new IllegalArgumentException("dataToSend must be a direct buffer");
if (dataToSend.capacity() < size)
}
if (dataToSend.capacity() < size) {
throw new IllegalArgumentException("dataToSend is too small, must be at least " + size);
if (!dataReceived.isDirect())
}
if (!dataReceived.isDirect()) {
throw new IllegalArgumentException("dataReceived must be a direct buffer");
if (dataReceived.capacity() < size)
}
if (dataReceived.capacity() < size) {
throw new IllegalArgumentException("dataReceived is too small, must be at least " + size);
}
return SPIJNI.spiTransaction(m_port, dataToSend, dataReceived, (byte) size);
}
/**
* Initialize the accumulator.
*
* @param period Time between reads
* @param cmd SPI command to send to request data
* @param xfer_size SPI transfer size, in bytes
* @param valid_mask Mask to apply to received data for validity checking
* @param valid_data After valid_mask is applied, required matching value for
* validity checking
* @param data_shift Bit shift to apply to received data to get actual data
* value
* @param data_size Size (in bits) of data field
* @param is_signed Is data field signed?
* @param big_endian Is device big endian?
* @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?
*/
public void initAccumulator(double period, int cmd, int xfer_size,
int valid_mask, int valid_value,
int data_shift, int data_size,
boolean is_signed, boolean big_endian) {
SPIJNI.spiInitAccumulator(m_port, (int)(period * 1.0e6), cmd,
(byte)xfer_size, valid_mask, valid_value, (byte)data_shift,
(byte)data_size, is_signed, big_endian);
public void initAccumulator(double period, int cmd, int xferSize,
int validMask, int validValue,
int dataShift, int dataSize,
boolean isSigned, boolean bigEndian) {
SPIJNI.spiInitAccumulator(m_port, (int) (period * 1.0e6), cmd,
(byte) xferSize, validMask, validValue, (byte) dataShift,
(byte) dataSize, isSigned, bigEndian);
}
/**
@@ -306,7 +302,7 @@ public class SPI extends SensorBase {
/**
* Set the center value of the accumulator.
*
* The center value is subtracted from each value before it is added to the accumulator. This
* <p>The center value is subtracted from each value before it is added to the accumulator. This
* is used for the center value of devices like gyros and accelerometers to make integration work
* and to take the device offset into account when integrating.
*/
@@ -340,7 +336,7 @@ public class SPI extends SensorBase {
/**
* Read the number of accumulated values.
*
* Read the count of the accumulated values since the accumulator was last Reset().
* <p>Read the count of the accumulated values since the accumulator was last Reset().
*
* @return The number of times samples from the channel were accumulated.
*/
@@ -360,8 +356,7 @@ public class SPI extends SensorBase {
/**
* Read the accumulated value and the number of accumulated values atomically.
*
* This function reads the value and count atomically.
* This can be used for averaging.
* <p>This function reads the value and count atomically. This can be used for averaging.
*
* @param result AccumulatorResult object to store the results in.
*/

View File

@@ -8,37 +8,30 @@
package edu.wpi.first.wpilibj;
/**
* Manages a PWM object.
*
* @author brad
*/
public class SafePWM extends PWM implements MotorSafety {
private MotorSafetyHelper m_safetyHelper;
private final MotorSafetyHelper m_safetyHelper;
/**
* Initialize a SafePWM object by setting defaults
* Constructor for a SafePWM object taking a channel number.
*
* @param channel The channel number to be used for the underlying PWM object. 0-9 are on-board,
* 10-19 are on the MXP port.
*/
void initSafePWM() {
public SafePWM(final int channel) {
super(channel);
m_safetyHelper = new MotorSafetyHelper(this);
m_safetyHelper.setExpiration(0.0);
m_safetyHelper.setSafetyEnabled(false);
}
/**
* Constructor for a SafePWM object taking a channel number
*$
* @param channel The channel number to be used for the underlying PWM object.
* 0-9 are on-board, 10-19 are on the MXP port.
*/
public SafePWM(final int channel) {
super(channel);
initSafePWM();
}
/*
* Set the expiration time for the PWM object
*$
* Set the expiration time for the PWM object.
*
* @param timeout The timeout (in seconds) for this motor object
*/
public void setExpiration(double timeout) {
@@ -47,7 +40,7 @@ public class SafePWM extends PWM implements MotorSafety {
/**
* Return the expiration time for the PWM object.
*$
*
* @return The expiration time value.
*/
public double getExpiration() {
@@ -56,26 +49,24 @@ public class SafePWM extends PWM implements MotorSafety {
/**
* Check if the PWM object is currently alive or stopped due to a timeout.
*$
* @return a bool value that is true if the motor has NOT timed out and should
* still be running.
*
* @return a bool value that is true if the motor has NOT timed out and should still be running.
*/
public boolean isAlive() {
return m_safetyHelper.isAlive();
}
/**
* Stop the motor associated with this PWM object. This is called by the
* MotorSafetyHelper object when it has a timeout for this PWM and needs to
* stop it from running.
* Stop the motor associated with this PWM object. This is called by the MotorSafetyHelper object
* when it has a timeout for this PWM and needs to stop it from running.
*/
public void stopMotor() {
disable();
}
/**
* Check if motor safety is enabled for this object
*$
* Check if motor safety is enabled for this object.
*
* @return True if motor safety is enforced for this object
*/
public boolean isSafetyEnabled() {
@@ -83,9 +74,10 @@ public class SafePWM extends PWM implements MotorSafety {
}
/**
* Feed the MotorSafety timer. This method is called by the subclass motor
* whenever it updates its speed, thereby reseting the timeout value.
* Feed the MotorSafety timer. This method is called by the subclass motor whenever it updates its
* speed, thereby reseting the timeout value.
*/
@SuppressWarnings("MethodName")
public void Feed() {
m_safetyHelper.feed();
}

View File

@@ -7,31 +7,29 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tInstances;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* A simple robot base class that knows the standard FRC competition states
* (disabled, autonomous, or operator controlled).
* A simple robot base class that knows the standard FRC competition states (disabled, autonomous,
* or operator controlled).
*
* You can build a simple robot program off of this by overriding the
* robotinit(), disabled(), autonomous() and operatorControl() methods. The
* startCompetition() method will calls these methods (sometimes repeatedly).
* depending on the state of the competition.
* <p>You can build a simple robot program off of this by overriding the robotinit(), disabled(),
* autonomous() and operatorControl() methods. The startCompetition() method will calls these
* methods (sometimes repeatedly). depending on the state of the competition.
*
* Alternatively you can override the robotMain() method and manage all aspects
* of the robot yourself.
* <p>Alternatively you can override the robotMain() method and manage all aspects of the robot
* yourself.
*/
public class SampleRobot extends RobotBase {
private boolean m_robotMainOverridden;
/**
* Create a new SampleRobot
* Create a new SampleRobot.
*/
public SampleRobot() {
super();
@@ -41,53 +39,50 @@ public class SampleRobot extends RobotBase {
/**
* Robot-wide initialization code should go here.
*
* Users should override this method for default Robot-wide initialization
* which will be called when the robot is first powered on. It will be called
* exactly one time.
* <p>Users should override this method for default Robot-wide initialization which will be called
* when the robot is first powered on. It will be called exactly one time.
*
* Warning: the Driver Station "Robot Code" light and FMS "Robot Ready"
* indicators will be off until RobotInit() exits. Code in RobotInit() that
* waits for enable will cause the robot to never indicate that the code is
* ready, causing the robot to be bypassed in a match.
* <p>Warning: the Driver Station "Robot Code" light and FMS "Robot Ready" indicators will be off
* until RobotInit() exits. Code in RobotInit() that waits for enable will cause the robot to
* never indicate that the code is ready, causing the robot to be bypassed in a match.
*/
protected void robotInit() {
System.out.println("Default robotInit() method running, consider providing your own");
}
/**
* Disabled should go here. Users should overload this method to run code that
* should run while the field is disabled.
* Disabled should go here. Users should overload this method to run code that should run while
* the field is disabled.
*
* Called once each time the robot enters the disabled state.
* <p>Called once each time the robot enters the disabled state.
*/
protected void disabled() {
System.out.println("Default disabled() method running, consider providing your own");
}
/**
* Autonomous should go here. Users should add autonomous code to this method
* that should run while the field is in the autonomous period.
* Autonomous should go here. Users should add autonomous code to this method that should run
* while the field is in the autonomous period.
*
* Called once each time the robot enters the autonomous state.
* <p>Called once each time the robot enters the autonomous state.
*/
public void autonomous() {
System.out.println("Default autonomous() method running, consider providing your own");
}
/**
* Operator control (tele-operated) code should go here. Users should add
* Operator Control code to this method that should run while the field is in
* the Operator Control (tele-operated) period.
* Operator control (tele-operated) code should go here. Users should add Operator Control code to
* this method that should run while the field is in the Operator Control (tele-operated) period.
*
* Called once each time the robot enters the operator-controlled state.
* <p>Called once each time the robot enters the operator-controlled state.
*/
public void operatorControl() {
System.out.println("Default operatorControl() method running, consider providing your own");
}
/**
* Test code should go here. Users should add test code to this method that
* should run while the robot is in test mode.
* Test code should go here. Users should add test code to this method that should run while the
* robot is in test mode.
*/
public void test() {
System.out.println("Default test() method running, consider providing your own");
@@ -96,27 +91,24 @@ public class SampleRobot extends RobotBase {
/**
* Robot main program for free-form programs.
*
* This should be overridden by user subclasses if the intent is to not use
* the autonomous() and operatorControl() methods. In that case, the program
* is responsible for sensing when to run the autonomous and operator control
* functions in their program.
* <p>This should be overridden by user subclasses if the intent is to not use the autonomous()
* and operatorControl() methods. In that case, the program is responsible for sensing when to run
* the autonomous and operator control functions in their program.
*
* This method will be called immediately after the constructor is called. If
* it has not been overridden by a user subclass (i.e. the default version
* runs), then the robotInit(), disabled(), autonomous() and operatorControl()
* methods will be called.
* <p>This method will be called immediately after the constructor is called. If it has not been
* overridden by a user subclass (i.e. the default version runs), then the robotInit(),
* disabled(), autonomous() and operatorControl() methods will be called.
*/
public void robotMain() {
m_robotMainOverridden = false;
}
/**
* Start a competition. This code tracks the order of the field starting to
* ensure that everything happens in the right order. Repeatedly run the
* correct method, either Autonomous or OperatorControl when the robot is
* enabled. After running the correct method, wait for some state to change,
* either the other mode starts or the robot is disabled. Then go back and
* wait for the robot to be enabled again.
* Start a competition. This code tracks the order of the field starting to ensure that everything
* happens in the right order. Repeatedly run the correct method, either Autonomous or
* OperatorControl when the robot is enabled. After running the correct method, wait for some
* state to change, either the other mode starts or the robot is disabled. Then go back and wait
* for the robot to be enabled again.
*/
public void startCompetition() {
UsageReporting.report(tResourceType.kResourceType_Framework, tInstances.kFramework_Sample);
@@ -151,8 +143,9 @@ public class SampleRobot extends RobotBase {
m_ds.InTest(true);
test();
m_ds.InTest(false);
while (isTest() && isEnabled())
while (isTest() && isEnabled()) {
Timer.delay(0.01);
}
LiveWindow.setEnabled(false);
} else {
m_ds.InOperatorControl(true);

View File

@@ -8,7 +8,6 @@
package edu.wpi.first.wpilibj;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
@@ -18,14 +17,13 @@ import edu.wpi.first.wpilibj.hal.SerialPortJNI;
/**
* Driver for the RS-232 serial port on the RoboRIO.
*
* The current implementation uses the VISA formatted I/O mode. This means that
* all traffic goes through the formatted buffers. This allows the intermingled
* use of print(), readString(), and the raw buffer accessors read() and
* write().
* <p>The current implementation uses the VISA formatted I/O mode. This means that all traffic goes
* through the formatted buffers. This allows the intermingled use of print(), readString(), and the
* raw buffer accessors read() and write().
*
* More information can be found in the NI-VISA User Manual here:
* http://www.ni.com/pdf/manuals/370423a.pdf and the NI-VISA Programmer's
* Reference Manual here: http://www.ni.com/pdf/manuals/370132c.pdf
* <p>More information can be found in the NI-VISA User Manual here: http://www.ni
* .com/pdf/manuals/370423a.pdf and the NI-VISA Programmer's Reference Manual here:
* http://www.ni.com/pdf/manuals/370132c.pdf
*/
public class SerialPort {
@@ -34,25 +32,26 @@ public class SerialPort {
public enum Port {
kOnboard(0), kMXP(1), kUSB(2);
private int value;
private int m_value;
private Port(int value) {
this.value = value;
Port(int value) {
m_value = value;
}
public int getValue() {
return this.value;
return m_value;
}
};
}
/**
* Represents the parity to use for serial communications
* Represents the parity to use for serial communications.
*/
public static class Parity {
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
static final int kNone_val = 0;
static final int kOdd_val = 1;
@@ -60,23 +59,23 @@ public class SerialPort {
static final int kMark_val = 3;
static final int kSpace_val = 4;
/**
* parity: Use no parity
* parity: Use no parity.
*/
public static final Parity kNone = new Parity(kNone_val);
/**
* parity: Use odd parity
* parity: Use odd parity.
*/
public static final Parity kOdd = new Parity(kOdd_val);
/**
* parity: Use even parity
* parity: Use even parity.
*/
public static final Parity kEven = new Parity(kEven_val);
/**
* parity: Use mark parity
* parity: Use mark parity.
*/
public static final Parity kMark = new Parity(kMark_val);
/**
* parity: Use space parity
* parity: Use space parity.
*/
public static final Parity kSpace = new Parity((kSpace_val));
@@ -86,27 +85,28 @@ public class SerialPort {
}
/**
* Represents the number of stop bits to use for Serial Communication
* Represents the number of stop bits to use for Serial Communication.
*/
public static class StopBits {
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
static final int kOne_val = 10;
static final int kOnePointFive_val = 15;
static final int kTwo_val = 20;
/**
* stopBits: use 1
* stopBits: use 1.
*/
public static final StopBits kOne = new StopBits(kOne_val);
/**
* stopBits: use 1.5
* stopBits: use 1.5.
*/
public static final StopBits kOnePointFive = new StopBits(kOnePointFive_val);
/**
* stopBits: use 2
* stopBits: use 2.
*/
public static final StopBits kTwo = new StopBits(kTwo_val);
@@ -116,32 +116,33 @@ public class SerialPort {
}
/**
* Represents what type of flow control to use for serial communication
* Represents what type of flow control to use for serial communication.
*/
public static class FlowControl {
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
static final int kNone_val = 0;
static final int kXonXoff_val = 1;
static final int kRtsCts_val = 2;
static final int kDtrDsr_val = 4;
/**
* flowControl: use none
* flowControl: use none.
*/
public static final FlowControl kNone = new FlowControl(kNone_val);
/**
* flowcontrol: use on/off
* flowcontrol: use on/off.
*/
public static final FlowControl kXonXoff = new FlowControl(kXonXoff_val);
/**
* flowcontrol: use rts cts
* flowcontrol: use rts cts.
*/
public static final FlowControl kRtsCts = new FlowControl(kRtsCts_val);
/**
* flowcontrol: use dts dsr
* flowcontrol: use dts dsr.
*/
public static final FlowControl kDtrDsr = new FlowControl(kDtrDsr_val);
@@ -151,22 +152,23 @@ public class SerialPort {
}
/**
* 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 m_port.
*/
public static class WriteBufferMode {
/**
* The integer value representing this enumeration
* The integer value representing this enumeration.
*/
@SuppressWarnings("MemberName")
public final int value;
static final int kFlushOnAccess_val = 1;
static final int kFlushWhenFull_val = 2;
/**
* Flush on access
* Flush on access.
*/
public static final WriteBufferMode kFlushOnAccess = new WriteBufferMode(kFlushOnAccess_val);
/**
* Flush when full
* Flush when full.
*/
public static final WriteBufferMode kFlushWhenFull = new WriteBufferMode(kFlushWhenFull_val);
@@ -179,15 +181,13 @@ public class SerialPort {
* 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 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 stopBits The number of stop bits to use as defined by the enum
* StopBits.
* @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 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) {
StopBits stopBits) {
m_port = (byte) port.getValue();
SerialPortJNI.serialInitializePort(m_port);
@@ -214,29 +214,26 @@ public class SerialPort {
* Create an instance of a Serial Port class. Defaults to one stop bit.
*
* @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 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.
*/
public SerialPort(final int baudRate, Port port, final int dataBits, Parity parity) {
this(baudRate, port, dataBits, parity, StopBits.kOne);
}
/**
* Create an instance of a Serial Port class. Defaults to no parity and one
* stop bit.
* Create an instance of a Serial Port class. Defaults to no parity and one stop bit.
*
* @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 dataBits The number of data bits per transfer. Valid values are between 5 and 8 bits.
*/
public SerialPort(final int baudRate, Port port, final int dataBits) {
this(baudRate, port, dataBits, Parity.kNone, StopBits.kOne);
}
/**
* 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.
*/
@@ -254,9 +251,9 @@ public class SerialPort {
/**
* Set the type of flow control to enable on this port.
*
* By default, flow control is disabled.
*$
* @param flowControl the FlowControl value to use
* <p>By default, flow control is disabled.
*
* @param flowControl the FlowControl m_value to use
*/
public void setFlowControl(FlowControl flowControl) {
SerialPortJNI.serialSetFlowControl(m_port, (byte) flowControl.value);
@@ -265,9 +262,9 @@ public class SerialPort {
/**
* Enable termination and specify the termination character.
*
* Termination is currently only implemented for receive. When the the
* terminator is received, the read() or readString() will return fewer bytes
* than requested, stopping after the terminator.
* <p>Termination is currently only implemented for receive. When the the terminator is received,
* the read() or readString() will return fewer bytes than requested, stopping after the
* terminator.
*
* @param terminator The character to use for termination.
*/
@@ -278,14 +275,14 @@ public class SerialPort {
/**
* Enable termination with the default terminator '\n'
*
* Termination is currently only implemented for receive. When the the
* terminator is received, the read() or readString() will return fewer bytes
* than requested, stopping after the terminator.
* <p>Termination is currently only implemented for receive. When the the terminator is received,
* the read() or readString() will return fewer bytes than requested, stopping after the
* terminator.
*
* The default terminator is '\n'
* <p>The default terminator is '\n'
*/
public void enableTermination() {
this.enableTermination('\n');
enableTermination('\n');
}
/**
@@ -325,7 +322,7 @@ public class SerialPort {
return new String(out, 0, out.length, "US-ASCII");
} catch (UnsupportedEncodingException ex) {
ex.printStackTrace();
return new String();
return "";
}
}
@@ -347,7 +344,7 @@ public class SerialPort {
* 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) {
@@ -367,11 +364,10 @@ public class SerialPort {
}
/**
* Configure the timeout of the serial port.
* Configure the timeout of the serial m_port.
*
* This defines the timeout for transactions with the hardware. It will affect
* reads if less bytes are available than the read buffer size (defaults to 1)
* and very large writes.
* <p>This defines the timeout for transactions with the hardware. It will affect reads if less
* bytes are available than the read buffer size (defaults to 1) and very large writes.
*
* @param timeout The number of seconds to to wait for I/O.
*/
@@ -382,12 +378,11 @@ public class SerialPort {
/**
* Specify the size of the input buffer.
*
* Specify the amount of data that can be stored before data from the device
* is returned to Read. If you want data that is received to be returned
* immediately, set this to 1.
* <p>Specify the amount of data that can be stored before data from the device is returned to
* Read. If you want data that is received to be returned immediately, set this to 1.
*
* It the buffer is not filled before the read timeout expires, all data that
* has been received so far will be returned.
* <p>It the buffer is not filled before the read timeout expires, all data that has been received
* so far will be returned.
*
* @param size The read buffer size.
*/
@@ -398,8 +393,7 @@ public class SerialPort {
/**
* Specify the size of the output buffer.
*
* Specify the amount of data that can be stored before being transmitted to
* the device.
* <p>Specify the amount of data that can be stored before being transmitted to the device.
*
* @param size The write buffer size.
*/
@@ -410,11 +404,11 @@ public class SerialPort {
/**
* Specify the flushing behavior of the output buffer.
*
* 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().
*
* 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.
*/
@@ -425,8 +419,8 @@ public class SerialPort {
/**
* Force the output buffer to be written to the port.
*
* This is used when setWriteBufferMode() is set to kFlushWhenFull to force a
* flush before the buffer is full.
* <p>This is used when setWriteBufferMode() is set to kFlushWhenFull to force a flush before the
* buffer is full.
*/
public void flush() {
SerialPortJNI.serialFlush(m_port);
@@ -435,7 +429,7 @@ public class SerialPort {
/**
* Reset the serial port driver to a known state.
*
* Empty the transmit and receive buffers in the device and formatted I/O.
* <p>Empty the transmit and receive buffers in the device and formatted I/O.
*/
public void reset() {
SerialPortJNI.serialClear(m_port);

View File

@@ -16,8 +16,8 @@ import edu.wpi.first.wpilibj.tables.ITableListener;
/**
* Standard hobby style servo.
*
* The range parameters default to the appropriate values for the Hitec HS-322HD
* servo provided in the FIRST Kit of Parts in 2008.
* <p>The range parameters default to the appropriate values for the Hitec HS-322HD servo provided
* in the FIRST Kit of Parts in 2008.
*/
public class Servo extends PWM {
@@ -30,10 +30,8 @@ public class Servo extends PWM {
/**
* Common initialization code called by all constructors.
*
* InitServo() assigns defaults for the period multiplier for the servo PWM
* control signal, as well as the minimum and maximum PWM values supported by
* the servo.
*
* <p>InitServo() assigns defaults for the period multiplier for the servo PWM control signal, as
* well as the minimum and maximum PWM values supported by the servo.
*/
private void initServo() {
setBounds(kDefaultMaxServoPWM, 0, 0, 0, kDefaultMinServoPWM);
@@ -46,11 +44,11 @@ public class Servo extends PWM {
/**
* Constructor.<br>
*
* 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
* @param channel The PWM channel to which the servo is attached. 0-9 are on-board, 10-19 are on
* the MXP port
*/
public Servo(final int channel) {
super(channel);
@@ -61,8 +59,7 @@ public class Servo extends PWM {
/**
* Set the servo position.
*
* Servo values range from 0.0 to 1.0 corresponding to the range of full left
* to full right.
* <p>Servo values range from 0.0 to 1.0 corresponding to the range of full left to full right.
*
* @param value Position from 0.0 to 1.0.
*/
@@ -73,8 +70,7 @@ public class Servo extends PWM {
/**
* Get the servo position.
*
* Servo values range from 0.0 to 1.0 corresponding to the range of full left
* to full right.
* <p>Servo values range from 0.0 to 1.0 corresponding to the range of full left to full right.
*
* @return Position from 0.0 to 1.0.
*/
@@ -85,14 +81,13 @@ public class Servo extends PWM {
/**
* Set the servo angle.
*
* Assume that the servo angle is linear with respect to the PWM value (big
* assumption, need to test).
* <p>Assume that the servo angle is linear with respect to the PWM value (big assumption, need to
* test).
*
* Servo angles that are out of the supported range of the servo simply
* "saturate" in that direction In other words, if the servo has a range of (X
* degrees to Y degrees) than angles of less than X result in an angle of X
* being set and angles of more than Y degrees result in an angle of Y being
* set.
* <p>Servo angles that are out of the supported range of the servo simply "saturate" in that
* direction In other words, if the servo has a range of (X degrees to Y degrees) than angles of
* less than X result in an angle of X being set and angles of more than Y degrees result in an
* angle of Y being set.
*
* @param degrees The angle in degrees to set the servo.
*/
@@ -109,9 +104,9 @@ public class Servo extends PWM {
/**
* Get the servo angle.
*
* Assume that the servo angle is linear with respect to the PWM value (big
* assumption, need to test).
*$
* <p>Assume that the servo angle is linear with respect to the PWM value (big assumption, need to
* test).
*
* @return The angle in degrees to which the servo is set.
*/
public double getAngle() {
@@ -130,42 +125,34 @@ public class Servo extends PWM {
}
private ITable m_table;
private ITableListener m_table_listener;
private ITableListener m_tableListener;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("Value", get());
}
}
/**
* {@inheritDoc}
*/
@Override
public void startLiveWindowMode() {
m_table_listener = new ITableListener() {
m_tableListener = new ITableListener() {
public void valueChanged(ITable itable, String key, Object value, boolean bln) {
set(((Double) value).doubleValue());
}
};
m_table.addTableListener("Value", m_table_listener, true);
m_table.addTableListener("Value", m_tableListener, true);
}
/**
* {@inheritDoc}
*/
@Override
public void stopLiveWindowMode() {
// TODO: Broken, should only remove the listener from "Value" only.
m_table.removeTableListener(m_table_listener);
m_table.removeTableListener(m_tableListener);
}
}

View File

@@ -20,13 +20,13 @@ import edu.wpi.first.wpilibj.util.CheckedAllocationException;
/**
* Solenoid class for running high voltage Digital Output.
*
* The Solenoid class is typically used for pneumatics solenoids, but could be
* used for any device within the current spec of the PCM.
* <p>The Solenoid class is typically used for pneumatics solenoids, but could be used for any
* device within the current spec of the PCM.
*/
public class Solenoid extends SolenoidBase implements LiveWindowSendable {
private int m_channel; // /< The channel to control.
private long m_solenoid_port;
private final int m_channel; // /< The channel to control.
private long m_solenoidPort;
/**
* Common function to implement constructor behavior.
@@ -36,14 +36,14 @@ public class Solenoid extends SolenoidBase implements LiveWindowSendable {
checkSolenoidChannel(m_channel);
try {
m_allocated.allocate(m_moduleNumber * kSolenoidChannels + m_channel);
} catch (CheckedAllocationException e) {
allocated.allocate(m_moduleNumber * kSolenoidChannels + m_channel);
} catch (CheckedAllocationException ex) {
throw new AllocationException("Solenoid channel " + m_channel + " on module "
+ m_moduleNumber + " is already allocated");
+ m_moduleNumber + " is already allocated");
}
long port = SolenoidJNI.getPortWithModule((byte) m_moduleNumber, (byte) m_channel);
m_solenoid_port = SolenoidJNI.initializeSolenoidPort(port);
m_solenoidPort = SolenoidJNI.initializeSolenoidPort(port);
LiveWindow.addActuator("Solenoid", m_moduleNumber, m_channel, this);
UsageReporting.report(tResourceType.kResourceType_Solenoid, m_channel, m_moduleNumber);
@@ -64,7 +64,7 @@ public class Solenoid extends SolenoidBase implements LiveWindowSendable {
* 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);
@@ -76,9 +76,9 @@ public class Solenoid extends SolenoidBase implements LiveWindowSendable {
* Destructor.
*/
public synchronized void free() {
m_allocated.free(m_moduleNumber * kSolenoidChannels + m_channel);
SolenoidJNI.freeSolenoidPort(m_solenoid_port);
m_solenoid_port = 0;
allocated.free(m_moduleNumber * kSolenoidChannels + m_channel);
SolenoidJNI.freeSolenoidPort(m_solenoidPort);
m_solenoidPort = 0;
super.free();
}
@@ -105,12 +105,11 @@ public class Solenoid extends SolenoidBase implements LiveWindowSendable {
}
/**
* Check if solenoid is blacklisted. If a solenoid is shorted, it is added to
* the blacklist and disabled until power cycle, or until faults are cleared.
*
* @see #clearAllPCMStickyFaults()
* Check if solenoid is blacklisted. If a solenoid is shorted, it is added to the blacklist and
* disabled until power cycle, or until faults are cleared.
*
* @return If solenoid is disabled due to short.
* @see #clearAllPCMStickyFaults()
*/
public boolean isBlackListed() {
int value = getPCMSolenoidBlackList() & (1 << m_channel);
@@ -125,26 +124,20 @@ public class Solenoid extends SolenoidBase implements LiveWindowSendable {
}
private ITable m_table;
private ITableListener m_table_listener;
private ITableListener m_tableListener;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
m_table.putBoolean("Value", get());
@@ -152,25 +145,17 @@ public class Solenoid extends SolenoidBase implements LiveWindowSendable {
}
/**
* {@inheritDoc}
*/
@Override
public void startLiveWindowMode() {
set(false); // Stop for safety
m_table_listener = new ITableListener() {
public void valueChanged(ITable itable, String key, Object value, boolean bln) {
set(((Boolean) value).booleanValue());
}
};
m_table.addTableListener("Value", m_table_listener, true);
m_tableListener = (itable, key, value, bln) -> set((Boolean) value);
m_table.addTableListener("Value", m_tableListener, true);
}
/**
* {@inheritDoc}
*/
@Override
public void stopLiveWindowMode() {
set(false); // Stop for safety
// TODO: Broken, should only remove the listener from "Value" only.
m_table.removeTableListener(m_table_listener);
m_table.removeTableListener(m_tableListener);
}
}

View File

@@ -10,15 +10,14 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.hal.SolenoidJNI;
/**
* SolenoidBase class is the common base class for the Solenoid and
* DoubleSolenoid classes.
* SolenoidBase class is the common base class for the Solenoid and DoubleSolenoid classes.
*/
public abstract class SolenoidBase extends SensorBase {
private long[] m_ports;
protected int m_moduleNumber; // /< The number of the solenoid module being
// used.
protected static Resource m_allocated = new Resource(63 * SensorBase.kSolenoidChannels);
private final long[] m_ports;
protected final int m_moduleNumber; // /< The number of the solenoid module being
// used.
protected static final Resource allocated = new Resource(63 * SensorBase.kSolenoidChannels);
/**
* Constructor.
@@ -49,18 +48,19 @@ public abstract class SolenoidBase extends SensorBase {
* Set the value of a solenoid.
*
* @param value The value you want to set on the module.
* @param mask The channels you want to be affected.
* @param mask The channels you want to be affected.
*/
protected synchronized void set(int value, int mask) {
for (int i = 0; i < SensorBase.kSolenoidChannels; i++) {
int local_mask = 1 << i;
if ((mask & local_mask) != 0)
SolenoidJNI.setSolenoid(m_ports[i], (value & local_mask) != 0);
int localMask = 1 << i;
if ((mask & localMask) != 0) {
SolenoidJNI.setSolenoid(m_ports[i], (value & localMask) != 0);
}
}
}
/**
* Read all 8 solenoids from the module used by this solenoid as a single byte
* Read all 8 solenoids from the module used by this solenoid as a single byte.
*
* @return The current value of all 8 solenoids on this module.
*/
@@ -69,30 +69,32 @@ public abstract class SolenoidBase extends SensorBase {
}
/**
* Reads complete solenoid blacklist for all 8 solenoids as a single byte.
*$
* If a solenoid is shorted, it is added to the blacklist and disabled until
* power cycle, or until faults are cleared.
* Reads complete solenoid blacklist for all 8 solenoids as a single byte. If a solenoid is
* shorted, it is added to the blacklist and disabled until power cycle, or until faults are
* cleared.
*
* @see #clearAllPCMStickyFaults()
*$
* @return The solenoid blacklist of all 8 solenoids on the module.
* @see #clearAllPCMStickyFaults()
*/
public byte getPCMSolenoidBlackList() {
return (byte)SolenoidJNI.getPCMSolenoidBlackList(m_ports[0]);
return (byte) SolenoidJNI.getPCMSolenoidBlackList(m_ports[0]);
}
/**
* @return true if PCM sticky fault is set : The common highside solenoid
* voltage rail is too low, most likely a solenoid channel is shorted.
* If true, the common highside solenoid voltage rail is too low, most likely a solenoid channel
* is shorted.
*
* @return true if PCM sticky fault is set
*/
public boolean getPCMSolenoidVoltageStickyFault() {
return SolenoidJNI.getPCMSolenoidVoltageStickyFault(m_ports[0]);
}
/**
* @return true if PCM is in fault state : The common highside solenoid
* voltage rail is too low, most likely a solenoid channel is shorted.
* The common highside solenoid voltage rail is too low, most likely a solenoid channel is
* shorted.
*
* @return true if PCM is in fault state.
*/
public boolean getPCMSolenoidVoltageFault() {
return SolenoidJNI.getPCMSolenoidVoltageFault(m_ports[0]);
@@ -101,12 +103,11 @@ public abstract class SolenoidBase extends SensorBase {
/**
* Clear ALL sticky faults inside PCM that Compressor is wired to.
*
* If a sticky fault is set, then it will be persistently cleared. Compressor
* drive maybe momentarily disable while flags are being cleared. Care should
* be taken to not call this too frequently, otherwise normal compressor
* functionality may be prevented.
* <p>If a sticky fault is set, then it will be persistently cleared. Compressor drive maybe
* momentarily disable while flags are being cleared. Care should be taken to not call this too
* frequently, otherwise normal compressor functionality may be prevented.
*
* If no sticky faults are set then this call will have no effect.
* <p>If no sticky faults are set then this call will have no effect.
*/
public void clearAllPCMStickyFaults() {
SolenoidJNI.clearAllPCMStickyFaults(m_ports[0]);

View File

@@ -12,23 +12,22 @@ import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* REV Robotics SPARK Speed Controller
* REV Robotics SPARK Speed Controller.
*/
public class Spark extends PWMSpeedController {
/**
* Common initialization code called by all constructors.
*
* 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.
* <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.
*
* - 2.003ms = full "forward" - 1.55ms = the "high end" of the deadband range
* - 1.50ms = center of the deadband range (off) - 1.46ms = the "low end" of
* the deadband range - .999ms = full "reverse"
* <p>- 2.003ms = full "forward" - 1.55ms = the "high end" of the deadband range - 1.50ms =
* center of the deadband range (off) - 1.46ms = the "low end" of the deadband range - .999ms =
* full "reverse"
*/
protected void initSpark() {
setBounds(2.003, 1.55, 1.50, 1.46, .999);
@@ -43,8 +42,8 @@ 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
* @param channel The PWM channel that the SPARK is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
public Spark(final int channel) {
super(channel);

View File

@@ -1,64 +0,0 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008-2016. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj;
/**
* Interface for speed controlling devices.
*/
public interface SpeedController extends PIDOutput {
/**
* Common interface for getting the current set speed of a speed controller.
*
* @return The current set speed. Value is between -1.0 and 1.0.
*/
double get();
/**
* Common interface for setting the speed of a speed controller.
*
* @param speed The speed to set. Value should be between -1.0 and 1.0.
* @param syncGroup The update group to add this Set() to, pending
* UpdateSyncGroup(). If 0, update immediately.
*/
void set(double speed, byte syncGroup);
/**
* Common interface for setting the speed of a speed controller.
*
* @param speed The speed to set. Value should be between -1.0 and 1.0.
*/
void set(double speed);
/**
* Common interface for inverting direction of a speed controller.
*
* @param isInverted The state of inversion true is inverted.
*/
void setInverted(boolean isInverted);
/**
* Common interface for returning if a speed controller is in the inverted
* state or not.
*$
* @return isInverted The state of the inversion true is inverted.
*
*/
boolean getInverted();
/**
* Disable the speed controller
*/
void disable();
/**
* Stops motor movement. Motor can be moved again by calling set without having
* to re-enable the motor.
*/
void stopMotor();
}

View File

@@ -12,23 +12,22 @@ import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* Cross the Road Electronics (CTRE) Talon and Talon SR Speed Controller
* Cross the Road Electronics (CTRE) Talon and Talon SR Speed Controller.
*/
public class Talon extends PWMSpeedController {
/**
* Common initialization code called by all constructors.
*
* 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.
* <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.
*
* - 2.037ms = full "forward" - 1.539ms = the "high end" of the deadband range
* - 1.513ms = center of the deadband range (off) - 1.487ms = the "low end" of
* the deadband range - .989ms = full "reverse"
* <p>- 2.037ms = full "forward" - 1.539ms = the "high end" of the deadband range - 1.513ms =
* center of the deadband range (off) - 1.487ms = the "low end" of the deadband range - .989ms
* = full "reverse"
*/
private void initTalon() {
setBounds(2.037, 1.539, 1.513, 1.487, .989);
@@ -41,10 +40,10 @@ public class Talon extends PWMSpeedController {
}
/**
* Constructor for a Talon (original or Talon SR)
* 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
* @param channel The PWM channel that the Talon is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
public Talon(final int channel) {
super(channel);

View File

@@ -12,8 +12,8 @@ import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* Cross the Road Electronics (CTRE) Talon SRX Speed Controller with PWM control
*$
* Cross the Road Electronics (CTRE) Talon SRX Speed Controller with PWM control.
*
* @see CANTalon CANTalon for CAN control of Talon SRX
*/
public class TalonSRX extends PWMSpeedController {
@@ -21,16 +21,16 @@ public class TalonSRX extends PWMSpeedController {
/**
* Common initialization code called by all constructors.
*
* 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.
* <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.
*
* - 2.0004ms = full "forward" - 1.52ms = the "high end" of the deadband range
* - 1.50ms = center of the deadband range (off) - 1.48ms = the "low end" of
* the deadband range - .997ms = full "reverse"
* <p>- 2.0004ms = full "forward" - 1.52ms = the "high end" of the deadband range - 1.50ms =
* center
* of the deadband range (off) - 1.48ms = the "low end" of the deadband range - .997ms = full
* "reverse"
*/
protected void initTalonSRX() {
setBounds(2.004, 1.52, 1.50, 1.48, .997);
@@ -43,10 +43,10 @@ public class TalonSRX extends PWMSpeedController {
}
/**
* Constructor for a TalonSRX connected via PWM
* Constructor for a TalonSRX connected via PWM.
*
* @param channel The PWM channel that the TalonSRX is attached to. 0-9 are
* on-board, 10-19 are on the MXP port
* @param channel The PWM channel that the TalonSRX is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
public TalonSRX(final int channel) {
super(channel);

View File

@@ -9,104 +9,101 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType;
import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable;
import edu.wpi.first.wpilibj.tables.ITable;
/**
* Ultrasonic rangefinder class. The Ultrasonic rangefinder measures absolute
* distance based on the round-trip time of a ping generated by the controller.
* These sensors use two transducers, a speaker and a microphone both tuned to
* the ultrasonic range. A common ultrasonic sensor, the Daventech SRF04
* requires a short pulse to be generated on a digital channel. This causes the
* chirp to be emmitted. A second line becomes high as the ping is transmitted
* and goes low when the echo is received. The time that the line is high
* determines the round trip distance (time of flight).
* Ultrasonic rangefinder class. The Ultrasonic rangefinder measures absolute distance based on the
* round-trip time of a ping generated by the controller. These sensors use two transducers, a
* speaker and a microphone both tuned to the ultrasonic range. A common ultrasonic sensor, the
* Daventech SRF04 requires a short pulse to be generated on a digital channel. This causes the
* chirp to be emmitted. A second line becomes high as the ping is transmitted and goes low when the
* echo is received. The time that the line is high determines the round trip distance (time of
* flight).
*/
public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSendable {
/**
* The units to return when PIDGet is called
* The units to return when PIDGet is called.
*/
public static enum Unit {
public enum Unit {
/**
* Use inches for PIDGet
* Use inches for PIDGet.
*/
kInches,
/**
* Use millimeters for PIDGet
* Use millimeters for PIDGet.
*/
kMillimeters
}
private static final double kPingTime = 10 * 1e-6; // /< Time (sec) for the
// ping trigger pulse.
private static final int kPriority = 90; // /< Priority that the ultrasonic
// round robin task runs.
private static final double kMaxUltrasonicTime = 0.1; // /< Max time (ms)
// between readings.
// Time (sec) for the ping trigger pulse.
private static final double kPingTime = 10 * 1e-6;
// Priority that the ultrasonic round robin task runs.
private static final int kPriority = 90;
// Max time (ms) between readings.
private static final double kMaxUltrasonicTime = 0.1;
private static final double kSpeedOfSoundInchesPerSec = 1130.0 * 12.0;
private static Ultrasonic m_firstSensor = null; // head of the ultrasonic
// sensor list
private static boolean m_automaticEnabled = false; // automatic round robin
// mode
private DigitalInput m_echoChannel = null;
// head of the ultrasonic sensor list
private static Ultrasonic m_firstSensor = null;
// automatic round robin mode
private static boolean m_automaticEnabled = false;
private DigitalInput m_echoChannel;
private DigitalOutput m_pingChannel = null;
private boolean m_allocatedChannels;
private boolean m_enabled = false;
private Counter m_counter = null;
private Ultrasonic m_nextSensor = null;
private static Thread m_task = null; // task doing the round-robin automatic
// sensing
// task doing the round-robin automatic sensing
private static Thread m_task = null;
private Unit m_units;
private static int m_instances = 0;
protected PIDSourceType m_pidSource = PIDSourceType.kDisplacement;
/**
* Background task that goes through the list of ultrasonic sensors and pings
* each one in turn. The counter is configured to read the timing of the
* returned echo pulse.
* Background task that goes through the list of ultrasonic sensors and pings each one in turn.
* The counter is configured to read the timing of the returned echo pulse.
*
* DANGER WILL ROBINSON, DANGER WILL ROBINSON: This code runs as a task and
* assumes that none of the ultrasonic sensors will change while it's running.
* If one does, then this will certainly break. Make sure to disable automatic
* mode before changing anything with the sensors!!
* <p><b>DANGER WILL ROBINSON, DANGER WILL ROBINSON:</b> This code runs as a task and assumes that
* none of the ultrasonic sensors will change while it's running. If one does, then this will
* certainly break. Make sure to disable automatic mode before changing anything with the
* sensors!!
*/
private class UltrasonicChecker extends Thread {
@Override
public synchronized void run() {
Ultrasonic u = null;
Ultrasonic ultrasonic = null;
while (m_automaticEnabled) {
if (u == null) {
u = m_firstSensor;
if (ultrasonic == null) {
ultrasonic = m_firstSensor;
}
if (u == null) {
if (ultrasonic == null) {
return;
}
if (u.isEnabled()) {
u.m_pingChannel.pulse(m_pingChannel.m_channel, (float) kPingTime); // do
// the
// ping
if (ultrasonic.isEnabled()) {
ultrasonic.m_pingChannel.pulse(m_pingChannel.m_channel, (float) kPingTime); // do
// the
// ping
}
u = u.m_nextSensor;
ultrasonic = ultrasonic.m_nextSensor;
Timer.delay(.1); // wait for ping to return
}
}
}
/**
* Initialize the Ultrasonic Sensor. This is the common code that initializes
* the ultrasonic sensor given that there are two digital I/O channels
* allocated. If the system was running in automatic mode (round robin) when
* the new sensor is added, it is stopped, the sensor is added, then automatic
* mode is restored.
* Initialize the Ultrasonic Sensor. This is the common code that initializes the ultrasonic
* sensor given that there are two digital I/O channels allocated. If the system was running in
* automatic mode (round robin) when the new sensor is added, it is stopped, the sensor is added,
* then automatic mode is restored.
*/
private synchronized void initialize() {
if (m_task == null) {
m_task = new UltrasonicChecker();
}
boolean originalMode = m_automaticEnabled;
final boolean originalMode = m_automaticEnabled;
setAutomaticMode(false); // kill task when adding a new sensor
m_nextSensor = m_firstSensor;
m_firstSensor = this;
@@ -125,15 +122,15 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Create an instance of the Ultrasonic Sensor. This is designed to supchannel
* the Daventech SRF04 and Vex ultrasonic sensors.
* Create an instance of the Ultrasonic Sensor. This is designed to supchannel the Daventech SRF04
* and Vex ultrasonic sensors.
*
* @param pingChannel The digital output channel that sends the pulse to
* initiate the sensor 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
* @param pingChannel The digital output channel that sends the pulse to initiate the sensor
* 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
*/
public Ultrasonic(final int pingChannel, final int echoChannel, Unit units) {
m_pingChannel = new DigitalOutput(pingChannel);
@@ -144,28 +141,28 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Create an instance of the Ultrasonic Sensor. This is designed to supchannel
* the Daventech SRF04 and Vex ultrasonic sensors. Default unit is inches.
* Create an instance of the Ultrasonic Sensor. This is designed to supchannel the Daventech SRF04
* 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.
* @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 pingChannel The digital output channel that sends the pulse to initiate the sensor
* 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.
*/
public Ultrasonic(final int pingChannel, final int echoChannel) {
this(pingChannel, echoChannel, Unit.kInches);
}
/**
* Create an instance of an Ultrasonic Sensor from a DigitalInput for the echo
* channel and a DigitalOutput for the ping channel.
* Create an instance of an Ultrasonic Sensor from a DigitalInput for the echo channel and a
* 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
* @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
*/
public Ultrasonic(DigitalOutput pingChannel, DigitalInput echoChannel, Unit units) {
if (pingChannel == null || echoChannel == null) {
@@ -179,26 +176,27 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Create an instance of an Ultrasonic Sensor from a DigitalInput for the echo
* channel and a DigitalOutput for the ping channel. Default unit is inches.
* Create an instance of an Ultrasonic Sensor from a DigitalInput for the echo channel and a
* 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.
* @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.
*/
public Ultrasonic(DigitalOutput pingChannel, DigitalInput echoChannel) {
this(pingChannel, echoChannel, Unit.kInches);
}
/**
* Destructor for the ultrasonic sensor. Delete the instance of the ultrasonic
* sensor by freeing the allocated digital channels. If the system was in
* automatic mode (round robin), then it is stopped, then started again after
* this sensor is removed (provided this wasn't the last sensor).
* Destructor for the ultrasonic sensor. Delete the instance of the ultrasonic sensor by freeing
* the allocated digital channels. If the system was in automatic mode (round robin), then it is
* stopped, then started again after this sensor is removed (provided this wasn't the last
* sensor).
*/
@Override
public synchronized void free() {
boolean wasAutomaticMode = m_automaticEnabled;
final boolean wasAutomaticMode = m_automaticEnabled;
setAutomaticMode(false);
if (m_allocatedChannels) {
if (m_pingChannel != null) {
@@ -236,15 +234,14 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Turn Automatic mode on/off. When in Automatic mode, all sensors will fire
* in round robin, waiting a set time between each sensor.
* Turn Automatic mode on/off. When in Automatic mode, all sensors will fire in round robin,
* waiting a set time between 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 preffered, it can be
* implemented by pinging the sensors manually and waiting for the
* results to come back.
* @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 preffered, it can be implemented by pinging the sensors manually and waiting
* for the results to come back.
*/
public void setAutomaticMode(boolean enabling) {
if (enabling == m_automaticEnabled) {
@@ -266,8 +263,9 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
// Wait for background task to stop running
try {
m_task.join();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
ex.printStackTrace();
}
/* Clear all the counters (data now invalid) since automatic mode is
@@ -281,10 +279,10 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Single ping to ultrasonic sensor. Send out a single ping to the ultrasonic
* sensor. This only works if automatic (round robin) mode is disabled. A
* single ping is sent out, and the counter should count the semi-period when
* it comes in. The counter is reset to make the current value invalid.
* Single ping to ultrasonic sensor. Send out a single ping to the ultrasonic sensor. This only
* works if automatic (round robin) mode is disabled. A single ping is sent out, and the counter
* should count the semi-period when it comes in. The counter is reset to make the current value
* invalid.
*/
public void ping() {
setAutomaticMode(false); // turn off automatic round robin if pinging
@@ -302,10 +300,9 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Check if there is a valid range measurement. The ranges are accumulated in
* a counter that will increment on each edge of the echo (return) signal. If
* the count is not at least 2, then the range has not yet been measured, and
* is invalid.
* Check if there is a valid range measurement. The ranges are accumulated in a counter that will
* increment on each edge of the echo (return) signal. If the count is not at least 2, then the
* range has not yet been measured, and is invalid.
*
* @return true if the range is valid
*/
@@ -314,11 +311,10 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Get the range in inches from the ultrasonic sensor.
* Get the range in inches from the ultrasonic sensor. If there is no valid value yet, i.e. at
* least one measurement hasn't completed, then return 0.
*
* @return double Range in inches of the target returned from the ultrasonic
* sensor. If there is no valid value yet, i.e. at least one
* measurement hasn't completed, then return 0.
* @return double Range in inches of the target returned from the ultrasonic sensor.
*/
public double getRangeInches() {
if (isRangeValid()) {
@@ -329,19 +325,16 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Get the range in millimeters from the ultrasonic sensor.
* Get the range in millimeters from the ultrasonic sensor. If there is no valid value yet, i.e.
* at least one measurement hasn't completed, then return 0.
*
* @return double Range in millimeters of the target returned by the
* ultrasonic sensor. If there is no valid value yet, i.e. at least
* one measurement hasn't complted, then return 0.
* @return double Range in millimeters of the target returned by the ultrasonic sensor.
*/
public double getRangeMM() {
return getRangeInches() * 25.4;
}
/**
* {@inheritDoc}
*/
@Override
public void setPIDSourceType(PIDSourceType pidSource) {
if (!pidSource.equals(PIDSourceType.kDisplacement)) {
throw new IllegalArgumentException("Only displacement PID is allowed for ultrasonics.");
@@ -349,9 +342,7 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
m_pidSource = pidSource;
}
/**
* {@inheritDoc}
*/
@Override
public PIDSourceType getPIDSourceType() {
return m_pidSource;
}
@@ -361,6 +352,7 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
*
* @return The range in DistanceUnit
*/
@Override
public double pidGet() {
switch (m_units) {
case kInches:
@@ -373,8 +365,7 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Set the current DistanceUnit that should be used for the PIDSource base
* object.
* Set the current DistanceUnit that should be used for the PIDSource base object.
*
* @param units The DistanceUnit that should be used.
*/
@@ -392,7 +383,7 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Is the ultrasonic enabled
* Is the ultrasonic enabled.
*
* @return true if the ultrasonic is enabled
*/
@@ -401,7 +392,7 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
}
/**
* Set if the ultrasonic is enabled
* Set if the ultrasonic is enabled.
*
* @param enable set to true to enable the ultrasonic
*/
@@ -409,46 +400,39 @@ public class Ultrasonic extends SensorBase implements PIDSource, LiveWindowSenda
m_enabled = enable;
}
/*
/**
* Live Window code, only does anything if live window is activated.
*/
@Override
public String getSmartDashboardType() {
return "Ultrasonic";
}
private ITable m_table;
/**
* {@inheritDoc}
*/
@Override
public void initTable(ITable subtable) {
m_table = subtable;
updateTable();
}
/**
* {@inheritDoc}
*/
@Override
public ITable getTable() {
return m_table;
}
/**
* {@inheritDoc}
*/
@Override
public void updateTable() {
if (m_table != null) {
m_table.putNumber("Value", getRangeInches());
}
}
/**
* {@inheritDoc}
*/
public void startLiveWindowMode() {}
@Override
public void startLiveWindowMode() {
}
/**
* {@inheritDoc}
*/
public void stopLiveWindowMode() {}
@Override
public void stopLiveWindowMode() {
}
}

View File

@@ -10,28 +10,31 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.hal.HALUtil;
/**
* Contains global utility functions
* Contains global utility functions.
*/
public class Utility {
public final class Utility {
private Utility() {}
private Utility() {
}
/**
* Return the FPGA Version number. For now, expect this to be 2009.
*
* @return FPGA Version number.
*/
@SuppressWarnings("AbbreviationAsWordInName")
int getFPGAVersion() {
return HALUtil.getFPGAVersion();
}
/**
* Return the FPGA Revision number. The format of the revision is 3 numbers.
* The 12 most significant bits are the Major Revision. the next 8 bits are
* the Minor Revision. The 12 least significant bits are the Build Number.
* Return the FPGA Revision number. The format of the revision is 3 numbers. The 12 most
* significant bits are the Major Revision. the next 8 bits are the Minor Revision. The 12 least
* significant bits are the Build Number.
*
* @return FPGA Revision number.
*/
@SuppressWarnings("AbbreviationAsWordInName")
long getFPGARevision() {
return (long) HALUtil.getFPGARevision();
}
@@ -46,8 +49,8 @@ public class Utility {
}
/**
* Get the state of the "USER" button on the RoboRIO
*$
* Get the state of the "USER" button on the RoboRIO.
*
* @return true if the button is currently pressed down
*/
public static boolean getUserButton() {

View File

@@ -12,28 +12,24 @@ import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* 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.
*/
public class Victor extends PWMSpeedController {
/**
* Common initialization code called by all constructors.
*
* 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 behaviour 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>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 behaviour 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
*
* - 2.027ms = full "forward" - 1.525ms = the "high end" of the deadband range
* - 1.507ms = center of the deadband range (off) - 1.49ms = the "low end" of
* the deadband range - 1.026ms = full "reverse"
* <p>- 2.027ms = full "forward" - 1.525ms = the "high end" of the deadband range - 1.507ms =
* center of the deadband range (off) - 1.49ms = the "low end" of the deadband range - 1.026ms =
* full "reverse"
*/
private void initVictor() {
setBounds(2.027, 1.525, 1.507, 1.49, 1.026);
@@ -48,8 +44,8 @@ public class Victor extends PWMSpeedController {
/**
* Constructor.
*
* @param channel The PWM channel that the Victor is attached to. 0-9 are
* on-board, 10-19 are on the MXP port
* @param channel The PWM channel that the Victor is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
public Victor(final int channel) {
super(channel);

View File

@@ -12,23 +12,22 @@ import edu.wpi.first.wpilibj.communication.UsageReporting;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
* VEX Robotics Victor SP Speed Controller
* VEX Robotics Victor SP Speed Controller.
*/
public class VictorSP extends PWMSpeedController {
/**
* Common initialization code called by all constructors.
*
* 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.
* <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.
*
* - 2.004ms = full "forward" - 1.52ms = the "high end" of the deadband range
* - 1.50ms = center of the deadband range (off) - 1.48ms = the "low end" of
* the deadband range - .997ms = full "reverse"
* <p>- 2.004ms = full "forward" - 1.52ms = the "high end" of the deadband range - 1.50ms =
* center of the deadband range (off) - 1.48ms = the "low end" of the deadband range - .997ms =
* full "reverse"
*/
protected void initVictorSP() {
setBounds(2.004, 1.52, 1.50, 1.48, .997);
@@ -43,8 +42,8 @@ public class VictorSP extends PWMSpeedController {
/**
* Constructor.
*
* @param channel The PWM channel that the VictorSP is attached to. 0-9 are
* on-board, 10-19 are on the MXP port
* @param channel The PWM channel that the VictorSP is attached to. 0-9 are on-board, 10-19 are on
* the MXP port
*/
public VictorSP(final int channel) {
super(channel);

View File

@@ -17,6 +17,7 @@ public class CANExceptionFactory {
static final int ERR_CANSessionMux_NotAllowed = -44088;
static final int ERR_CANSessionMux_NotInitialized = -44089;
@SuppressWarnings("JavadocMethod")
public static void checkStatus(int status, int messageID) throws CANInvalidBufferException,
CANMessageNotAllowedException, CANNotInitializedException, UncleanStatusException {
switch (status) {
@@ -36,7 +37,8 @@ public class CANExceptionFactory {
case NIRioStatus.kRIOStatusResourceNotInitialized:
throw new CANNotInitializedException();
default:
throw new UncleanStatusException("Fatal status code detected: " + Integer.toString(status));
throw new UncleanStatusException("Fatal status code detected: " + Integer.toString(
status));
}
}
}

View File

@@ -8,9 +8,8 @@
package edu.wpi.first.wpilibj.can;
/**
* Exception indicating that a CAN driver library entry-point was passed an
* invalid buffer. Typically, this is due to a buffer being too small to include
* the needed safety token.
* Exception indicating that a CAN driver library entry-point was passed an invalid buffer.
* Typically, this is due to a buffer being too small to include the needed safety token.
*/
public class CANInvalidBufferException extends RuntimeException {
public CANInvalidBufferException() {

File diff suppressed because it is too large Load Diff

View File

@@ -8,9 +8,8 @@
package edu.wpi.first.wpilibj.can;
/**
* Exception indicating that the CAN driver layer has not been initialized. This
* happens when an entry-point is called before a CAN driver plugin has been
* installed.
* Exception indicating that the CAN driver layer has not been initialized. This happens when an
* entry-point is called before a CAN driver plugin has been installed.
*/
public class CANJaguarVersionException extends RuntimeException {

View File

@@ -8,8 +8,8 @@
package edu.wpi.first.wpilibj.can;
/**
* Exception indicating that the Jaguar CAN Driver layer refused to send a
* restricted message ID to the CAN bus.
* Exception indicating that the Jaguar CAN Driver layer refused to send a restricted message ID to
* the CAN bus.
*/
public class CANMessageNotAllowedException extends RuntimeException {
public CANMessageNotAllowedException(String msg) {

View File

@@ -8,9 +8,8 @@
package edu.wpi.first.wpilibj.can;
/**
* Exception indicating that a can message is not available from Network
* Communications. This usually just means we already have the most recent value
* cached locally.
* Exception indicating that a can message is not available from Network Communications. This
* usually just means we already have the most recent value cached locally.
*/
public class CANMessageNotFoundException extends RuntimeException {
public CANMessageNotFoundException() {

View File

@@ -8,9 +8,8 @@
package edu.wpi.first.wpilibj.can;
/**
* Exception indicating that the CAN driver layer has not been initialized. This
* happens when an entry-point is called before a CAN driver plugin has been
* installed.
* Exception indicating that the CAN driver layer has not been initialized. This happens when an
* entry-point is called before a CAN driver plugin has been installed.
*/
public class CANNotInitializedException extends RuntimeException {
public CANNotInitializedException() {

View File

@@ -8,160 +8,174 @@
package edu.wpi.first.wpilibj.communication;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import edu.wpi.first.wpilibj.hal.JNIWrapper;
/**
* JNI Wrapper for library <b>FRC_NetworkCommunications</b><br>
* JNI Wrapper for library <b>FRC_NetworkCommunications</b><br>.
*/
@SuppressWarnings("MethodName")
public class FRCNetworkCommunicationsLibrary extends JNIWrapper {
/** Module type from LoadOut.h */
public static interface tModuleType {
public static final int kModuleType_Unknown = 0x00;
public static final int kModuleType_Analog = 0x01;
public static final int kModuleType_Digital = 0x02;
public static final int kModuleType_Solenoid = 0x03;
};
/** Target class from LoadOut.h */
public static interface tTargetClass {
public static final int kTargetClass_Unknown = 0x00;
public static final int kTargetClass_FRC1 = 0x10;
public static final int kTargetClass_FRC2 = 0x20;
public static final int kTargetClass_FRC2_Analog =
/**
* Module type from LoadOut.h
*/
@SuppressWarnings("TypeName")
public interface tModuleType {
int kModuleType_Unknown = 0x00;
int kModuleType_Analog = 0x01;
int kModuleType_Digital = 0x02;
int kModuleType_Solenoid = 0x03;
}
/**
* Target class from LoadOut.h
*/
@SuppressWarnings("TypeName")
public interface tTargetClass {
int kTargetClass_Unknown = 0x00;
int kTargetClass_FRC1 = 0x10;
int kTargetClass_FRC2 = 0x20;
int kTargetClass_FRC2_Analog =
kTargetClass_FRC2 | FRCNetworkCommunicationsLibrary.tModuleType.kModuleType_Analog;
public static final int kTargetClass_FRC2_Digital =
int kTargetClass_FRC2_Digital =
kTargetClass_FRC2 | FRCNetworkCommunicationsLibrary.tModuleType.kModuleType_Digital;
public static final int kTargetClass_FRC2_Solenoid =
int kTargetClass_FRC2_Solenoid =
kTargetClass_FRC2 | FRCNetworkCommunicationsLibrary.tModuleType.kModuleType_Solenoid;
public static final int kTargetClass_FamilyMask = 0xF0;
public static final int kTargetClass_ModuleMask = 0x0F;
};
/** Resource types from UsageReporting.h */
public static interface tResourceType {
public static final int kResourceType_Controller = 0;
public static final int kResourceType_Module = 1;
public static final int kResourceType_Language = 2;
public static final int kResourceType_CANPlugin = 3;
public static final int kResourceType_Accelerometer = 4;
public static final int kResourceType_ADXL345 = 5;
public static final int kResourceType_AnalogChannel = 6;
public static final int kResourceType_AnalogTrigger = 7;
public static final int kResourceType_AnalogTriggerOutput = 8;
public static final int kResourceType_CANJaguar = 9;
public static final int kResourceType_Compressor = 10;
public static final int kResourceType_Counter = 11;
public static final int kResourceType_Dashboard = 12;
public static final int kResourceType_DigitalInput = 13;
public static final int kResourceType_DigitalOutput = 14;
public static final int kResourceType_DriverStationCIO = 15;
public static final int kResourceType_DriverStationEIO = 16;
public static final int kResourceType_DriverStationLCD = 17;
public static final int kResourceType_Encoder = 18;
public static final int kResourceType_GearTooth = 19;
public static final int kResourceType_Gyro = 20;
public static final int kResourceType_I2C = 21;
public static final int kResourceType_Framework = 22;
public static final int kResourceType_Jaguar = 23;
public static final int kResourceType_Joystick = 24;
public static final int kResourceType_Kinect = 25;
public static final int kResourceType_KinectStick = 26;
public static final int kResourceType_PIDController = 27;
public static final int kResourceType_Preferences = 28;
public static final int kResourceType_PWM = 29;
public static final int kResourceType_Relay = 30;
public static final int kResourceType_RobotDrive = 31;
public static final int kResourceType_SerialPort = 32;
public static final int kResourceType_Servo = 33;
public static final int kResourceType_Solenoid = 34;
public static final int kResourceType_SPI = 35;
public static final int kResourceType_Task = 36;
public static final int kResourceType_Ultrasonic = 37;
public static final int kResourceType_Victor = 38;
public static final int kResourceType_Button = 39;
public static final int kResourceType_Command = 40;
public static final int kResourceType_AxisCamera = 41;
public static final int kResourceType_PCVideoServer = 42;
public static final int kResourceType_SmartDashboard = 43;
public static final int kResourceType_Talon = 44;
public static final int kResourceType_HiTechnicColorSensor = 45;
public static final int kResourceType_HiTechnicAccel = 46;
public static final int kResourceType_HiTechnicCompass = 47;
public static final int kResourceType_SRF08 = 48;
public static final int kResourceType_AnalogOutput = 49;
public static final int kResourceType_VictorSP = 50;
public static final int kResourceType_TalonSRX = 51;
public static final int kResourceType_CANTalonSRX = 52;
public static final int kResourceType_ADXL362 = 53;
public static final int kResourceType_ADXRS450 = 54;
public static final int kResourceType_RevSPARK = 55;
public static final int kResourceType_MindsensorsSD540 = 56;
public static final int kResourceType_DigitalFilter = 57;
};
/** Instances from UsageReporting.h */
public static interface tInstances {
public static final int kLanguage_LabVIEW = 1;
public static final int kLanguage_CPlusPlus = 2;
public static final int kLanguage_Java = 3;
public static final int kLanguage_Python = 4;
int kTargetClass_FamilyMask = 0xF0;
int kTargetClass_ModuleMask = 0x0F;
}
public static final int kCANPlugin_BlackJagBridge = 1;
public static final int kCANPlugin_2CAN = 2;
/**
* Resource types from UsageReporting.h
*/
@SuppressWarnings("TypeName")
public interface tResourceType {
int kResourceType_Controller = 0;
int kResourceType_Module = 1;
int kResourceType_Language = 2;
int kResourceType_CANPlugin = 3;
int kResourceType_Accelerometer = 4;
int kResourceType_ADXL345 = 5;
int kResourceType_AnalogChannel = 6;
int kResourceType_AnalogTrigger = 7;
int kResourceType_AnalogTriggerOutput = 8;
int kResourceType_CANJaguar = 9;
int kResourceType_Compressor = 10;
int kResourceType_Counter = 11;
int kResourceType_Dashboard = 12;
int kResourceType_DigitalInput = 13;
int kResourceType_DigitalOutput = 14;
int kResourceType_DriverStationCIO = 15;
int kResourceType_DriverStationEIO = 16;
int kResourceType_DriverStationLCD = 17;
int kResourceType_Encoder = 18;
int kResourceType_GearTooth = 19;
int kResourceType_Gyro = 20;
int kResourceType_I2C = 21;
int kResourceType_Framework = 22;
int kResourceType_Jaguar = 23;
int kResourceType_Joystick = 24;
int kResourceType_Kinect = 25;
int kResourceType_KinectStick = 26;
int kResourceType_PIDController = 27;
int kResourceType_Preferences = 28;
int kResourceType_PWM = 29;
int kResourceType_Relay = 30;
int kResourceType_RobotDrive = 31;
int kResourceType_SerialPort = 32;
int kResourceType_Servo = 33;
int kResourceType_Solenoid = 34;
int kResourceType_SPI = 35;
int kResourceType_Task = 36;
int kResourceType_Ultrasonic = 37;
int kResourceType_Victor = 38;
int kResourceType_Button = 39;
int kResourceType_Command = 40;
int kResourceType_AxisCamera = 41;
int kResourceType_PCVideoServer = 42;
int kResourceType_SmartDashboard = 43;
int kResourceType_Talon = 44;
int kResourceType_HiTechnicColorSensor = 45;
int kResourceType_HiTechnicAccel = 46;
int kResourceType_HiTechnicCompass = 47;
int kResourceType_SRF08 = 48;
int kResourceType_AnalogOutput = 49;
int kResourceType_VictorSP = 50;
int kResourceType_TalonSRX = 51;
int kResourceType_CANTalonSRX = 52;
int kResourceType_ADXL362 = 53;
int kResourceType_ADXRS450 = 54;
int kResourceType_RevSPARK = 55;
int kResourceType_MindsensorsSD540 = 56;
int kResourceType_DigitalFilter = 57;
}
public static final int kFramework_Iterative = 1;
public static final int kFramework_Sample = 2;
public static final int kFramework_CommandControl = 3;
/**
* Instances from UsageReporting.h
*/
@SuppressWarnings("TypeName")
public interface tInstances {
int kLanguage_LabVIEW = 1;
int kLanguage_CPlusPlus = 2;
int kLanguage_Java = 3;
int kLanguage_Python = 4;
public static final int kRobotDrive_ArcadeStandard = 1;
public static final int kRobotDrive_ArcadeButtonSpin = 2;
public static final int kRobotDrive_ArcadeRatioCurve = 3;
public static final int kRobotDrive_Tank = 4;
public static final int kRobotDrive_MecanumPolar = 5;
public static final int kRobotDrive_MecanumCartesian = 6;
int kCANPlugin_BlackJagBridge = 1;
int kCANPlugin_2CAN = 2;
public static final int kDriverStationCIO_Analog = 1;
public static final int kDriverStationCIO_DigitalIn = 2;
public static final int kDriverStationCIO_DigitalOut = 3;
int kFramework_Iterative = 1;
int kFramework_Sample = 2;
int kFramework_CommandControl = 3;
public static final int kDriverStationEIO_Acceleration = 1;
public static final int kDriverStationEIO_AnalogIn = 2;
public static final int kDriverStationEIO_AnalogOut = 3;
public static final int kDriverStationEIO_Button = 4;
public static final int kDriverStationEIO_LED = 5;
public static final int kDriverStationEIO_DigitalIn = 6;
public static final int kDriverStationEIO_DigitalOut = 7;
public static final int kDriverStationEIO_FixedDigitalOut = 8;
public static final int kDriverStationEIO_PWM = 9;
public static final int kDriverStationEIO_Encoder = 10;
public static final int kDriverStationEIO_TouchSlider = 11;
int kRobotDrive_ArcadeStandard = 1;
int kRobotDrive_ArcadeButtonSpin = 2;
int kRobotDrive_ArcadeRatioCurve = 3;
int kRobotDrive_Tank = 4;
int kRobotDrive_MecanumPolar = 5;
int kRobotDrive_MecanumCartesian = 6;
public static final int kADXL345_SPI = 1;
public static final int kADXL345_I2C = 2;
int kDriverStationCIO_Analog = 1;
int kDriverStationCIO_DigitalIn = 2;
int kDriverStationCIO_DigitalOut = 3;
public static final int kCommand_Scheduler = 1;
int kDriverStationEIO_Acceleration = 1;
int kDriverStationEIO_AnalogIn = 2;
int kDriverStationEIO_AnalogOut = 3;
int kDriverStationEIO_Button = 4;
int kDriverStationEIO_LED = 5;
int kDriverStationEIO_DigitalIn = 6;
int kDriverStationEIO_DigitalOut = 7;
int kDriverStationEIO_FixedDigitalOut = 8;
int kDriverStationEIO_PWM = 9;
int kDriverStationEIO_Encoder = 10;
int kDriverStationEIO_TouchSlider = 11;
public static final int kSmartDashboard_Instance = 1;
};
int kADXL345_SPI = 1;
int kADXL345_I2C = 2;
int kCommand_Scheduler = 1;
int kSmartDashboard_Instance = 1;
}
/**
* Report the usage of a resource of interest. <br>
*
* <br>
*$
* @param resource one of the values in the tResourceType above (max value
* 51). <br>
* <p>Original signature: <code>uint32_t report(tResourceType, uint8_t, uint8_t, const
* char*)</code>
*
* @param resource one of the values in the tResourceType above (max value 51). <br>
* @param instanceNumber an index that identifies the resource instance. <br>
* @param context an optional additional context number for some cases (such
* as module number). Set to 0 to omit. <br>
* @param feature a string to be included describing features in use on a
* specific resource. Setting the same resource more than once allows
* you to change the feature string.<br>
* Original signature :
* <code>uint32_t report(tResourceType, uint8_t, uint8_t, const char*)</code>
* @param context an optional additional context number for some cases (such as module
* number). Set to 0 to omit. <br>
* @param feature a string to be included describing features in use on a specific
* resource. Setting the same resource more than once allows you to change
* the feature string.
*/
public static native int FRCNetworkCommunicationUsageReportingReport(byte resource,
byte instanceNumber, byte context, String feature);
byte instanceNumber,
byte context,
String feature);
public static native void setNewDataSem(long mutexId);
@@ -179,6 +193,7 @@ public class FRCNetworkCommunicationsLibrary extends JNIWrapper {
private static native int NativeHALGetControlWord();
@SuppressWarnings("JavadocMethod")
public static HALControlWord HALGetControlWord() {
int word = NativeHALGetControlWord();
return new HALControlWord((word & 1) != 0, ((word >> 1) & 1) != 0, ((word >> 2) & 1) != 0,
@@ -187,6 +202,7 @@ public class FRCNetworkCommunicationsLibrary extends JNIWrapper {
private static native int NativeHALGetAllianceStation();
@SuppressWarnings("JavadocMethod")
public static HALAllianceStationID HALGetAllianceStation() {
switch (NativeHALGetAllianceStation()) {
case 0:
@@ -216,7 +232,7 @@ public class FRCNetworkCommunicationsLibrary extends JNIWrapper {
public static native int HALGetJoystickButtons(byte joystickNum, ByteBuffer count);
public static native int HALSetJoystickOutputs(byte joystickNum, int outputs, short leftRumble,
short rightRumble);
short rightRumble);
public static native int HALGetJoystickIsXbox(byte joystickNum);
@@ -234,5 +250,7 @@ public class FRCNetworkCommunicationsLibrary extends JNIWrapper {
public static native int HALSetErrorData(String error);
public static native int HALSendError(boolean isError, int errorCode, boolean isLVCode, String details, String location, String callStack, boolean printMsg);
public static native int HALSendError(boolean isError, int errorCode, boolean isLVCode,
String details, String location, String callStack,
boolean printMsg);
}

View File

@@ -8,22 +8,22 @@
package edu.wpi.first.wpilibj.communication;
/**
* A wrapper for the HALControlWord bitfield
* A wrapper for the HALControlWord bitfield.
*/
public class HALControlWord {
private boolean m_enabled;
private boolean m_autonomous;
private boolean m_test;
private boolean m_eStop;
private boolean m_fmsAttached;
private boolean m_dsAttached;
private final boolean m_enabled;
private final boolean m_autonomous;
private final boolean m_test;
private final boolean m_emergencyStop;
private final boolean m_fmsAttached;
private final boolean m_dsAttached;
protected HALControlWord(boolean enabled, boolean autonomous, boolean test, boolean eStop,
boolean fmsAttached, boolean dsAttached) {
protected HALControlWord(boolean enabled, boolean autonomous, boolean test, boolean emergencyStop,
boolean fmsAttached, boolean dsAttached) {
m_enabled = enabled;
m_autonomous = autonomous;
m_test = test;
m_eStop = eStop;
m_emergencyStop = emergencyStop;
m_fmsAttached = fmsAttached;
m_dsAttached = dsAttached;
}
@@ -41,7 +41,7 @@ public class HALControlWord {
}
public boolean getEStop() {
return m_eStop;
return m_emergencyStop;
}
public boolean getFMSAttached() {

View File

@@ -9,17 +9,17 @@ package edu.wpi.first.wpilibj.communication;
public class UsageReporting {
public static void report(int resource, int instanceNumber, int i) {
report(resource, instanceNumber, i, "");
public static void report(int resource, int instanceNumber, int context) {
report(resource, instanceNumber, context, "");
}
public static void report(int resource, int instanceNumber) {
report(resource, instanceNumber, 0, "");
}
public static void report(int resource, int instanceNumber, int i, String string) {
public static void report(int resource, int instanceNumber, int context, String string) {
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationUsageReportingReport((byte) resource,
(byte) instanceNumber, (byte) i, string);
(byte) instanceNumber, (byte) context, string);
}
}

View File

@@ -12,40 +12,34 @@ import java.nio.LongBuffer;
public class AnalogJNI extends JNIWrapper {
/**
* <i>native declaration :
* AthenaJava\target\native\include\HAL\Analog.h:58</i><br>
* enum values
* <i>native declaration : AthenaJava\target\native\include\HAL\Analog.h:58</i><br> enum values
*/
public static interface AnalogTriggerType {
public interface AnalogTriggerType {
/**
* <i>native declaration :
* AthenaJava\target\native\include\HAL\Analog.h:54</i>
* <i>native declaration : AthenaJava\target\native\include\HAL\Analog.h:54</i>
*/
public static final int kInWindow = 0;
int kInWindow = 0;
/**
* <i>native declaration :
* AthenaJava\target\native\include\HAL\Analog.h:55</i>
* <i>native declaration : AthenaJava\target\native\include\HAL\Analog.h:55</i>
*/
public static final int kState = 1;
int kState = 1;
/**
* <i>native declaration :
* AthenaJava\target\native\include\HAL\Analog.h:56</i>
* <i>native declaration : AthenaJava\target\native\include\HAL\Analog.h:56</i>
*/
public static final int kRisingPulse = 2;
int kRisingPulse = 2;
/**
* <i>native declaration :
* AthenaJava\target\native\include\HAL\Analog.h:57</i>
* <i>native declaration : AthenaJava\target\native\include\HAL\Analog.h:57</i>
*/
public static final int kFallingPulse = 3;
};
int kFallingPulse = 3;
}
public static native long initializeAnalogInputPort(long port_pointer);
public static native long initializeAnalogInputPort(long portPointer);
public static native void freeAnalogInputPort(long port_pointer);
public static native void freeAnalogInputPort(long portPointer);
public static native long initializeAnalogOutputPort(long port_pointer);
public static native long initializeAnalogOutputPort(long portPointer);
public static native void freeAnalogOutputPort(long port_pointer);
public static native void freeAnalogOutputPort(long portPointer);
public static native boolean checkAnalogModule(byte module);
@@ -53,72 +47,72 @@ public class AnalogJNI extends JNIWrapper {
public static native boolean checkAnalogOutputChannel(int pin);
public static native void setAnalogOutput(long port_pointer, double voltage);
public static native void setAnalogOutput(long portPointer, double voltage);
public static native double getAnalogOutput(long port_pointer);
public static native double getAnalogOutput(long portPointer);
public static native void setAnalogSampleRate(double samplesPerSecond);
public static native double getAnalogSampleRate();
public static native void setAnalogAverageBits(long analog_port_pointer, int bits);
public static native void setAnalogAverageBits(long analogPortPointer, int bits);
public static native int getAnalogAverageBits(long analog_port_pointer);
public static native int getAnalogAverageBits(long analogPortPointer);
public static native void setAnalogOversampleBits(long analog_port_pointer, int bits);
public static native void setAnalogOversampleBits(long analogPortPointer, int bits);
public static native int getAnalogOversampleBits(long analog_port_pointer);
public static native int getAnalogOversampleBits(long analogPortPointer);
public static native short getAnalogValue(long analog_port_pointer);
public static native short getAnalogValue(long analogPortPointer);
public static native int getAnalogAverageValue(long analog_port_pointer);
public static native int getAnalogAverageValue(long analogPortPointer);
public static native int getAnalogVoltsToValue(long analog_port_pointer, double voltage);
public static native int getAnalogVoltsToValue(long analogPortPointer, double voltage);
public static native double getAnalogVoltage(long analog_port_pointer);
public static native double getAnalogVoltage(long analogPortPointer);
public static native double getAnalogAverageVoltage(long analog_port_pointer);
public static native double getAnalogAverageVoltage(long analogPortPointer);
public static native int getAnalogLSBWeight(long analog_port_pointer);
public static native int getAnalogLSBWeight(long analogPortPointer);
public static native int getAnalogOffset(long analog_port_pointer);
public static native int getAnalogOffset(long analogPortPointer);
public static native boolean isAccumulatorChannel(long analog_port_pointer);
public static native boolean isAccumulatorChannel(long analogPortPointer);
public static native void initAccumulator(long analog_port_pointer);
public static native void initAccumulator(long analogPortPointer);
public static native void resetAccumulator(long analog_port_pointer);
public static native void resetAccumulator(long analogPortPointer);
public static native void setAccumulatorCenter(long analog_port_pointer, int center);
public static native void setAccumulatorCenter(long analogPortPointer, int center);
public static native void setAccumulatorDeadband(long analog_port_pointer, int deadband);
public static native void setAccumulatorDeadband(long analogPortPointer, int deadband);
public static native long getAccumulatorValue(long analog_port_pointer);
public static native long getAccumulatorValue(long analogPortPointer);
public static native int getAccumulatorCount(long analog_port_pointer);
public static native int getAccumulatorCount(long analogPortPointer);
public static native void getAccumulatorOutput(long analog_port_pointer, LongBuffer value,
IntBuffer count);
public static native void getAccumulatorOutput(long analogPortPointer, LongBuffer value,
IntBuffer count);
public static native long initializeAnalogTrigger(long port_pointer, IntBuffer index);
public static native long initializeAnalogTrigger(long portPointer, IntBuffer index);
public static native void cleanAnalogTrigger(long analog_trigger_pointer);
public static native void cleanAnalogTrigger(long analogTriggerPointer);
public static native void setAnalogTriggerLimitsRaw(long analog_trigger_pointer, int lower,
int upper);
public static native void setAnalogTriggerLimitsRaw(long analogTriggerPointer, int lower,
int upper);
public static native void setAnalogTriggerLimitsVoltage(long analog_trigger_pointer,
double lower, double upper);
public static native void setAnalogTriggerLimitsVoltage(long analogTriggerPointer,
double lower, double upper);
public static native void setAnalogTriggerAveraged(long analog_trigger_pointer,
boolean useAveragedValue);
public static native void setAnalogTriggerAveraged(long analogTriggerPointer,
boolean useAveragedValue);
public static native void setAnalogTriggerFiltered(long analog_trigger_pointer,
boolean useFilteredValue);
public static native void setAnalogTriggerFiltered(long analogTriggerPointer,
boolean useFilteredValue);
public static native boolean getAnalogTriggerInWindow(long analog_trigger_pointer);
public static native boolean getAnalogTriggerInWindow(long analogTriggerPointer);
public static native boolean getAnalogTriggerTriggerState(long analog_trigger_pointer);
public static native boolean getAnalogTriggerTriggerState(long analogTriggerPointer);
public static native boolean getAnalogTriggerOutput(long analog_trigger_pointer, int type);
public static native boolean getAnalogTriggerOutput(long analogTriggerPointer, int type);
}

View File

@@ -7,19 +7,21 @@
package edu.wpi.first.wpilibj.hal;
@SuppressWarnings("MethodName")
public class CanTalonJNI extends JNIWrapper {
// Motion Profile status bits
public static final int kMotionProfileFlag_ActTraj_IsValid = 0x1;
public static final int kMotionProfileFlag_HasUnderrun = 0x2;
public static final int kMotionProfileFlag_IsUnderrun = 0x4;
public static final int kMotionProfileFlag_ActTraj_IsLast = 0x8;
public static final int kMotionProfileFlag_HasUnderrun = 0x2;
public static final int kMotionProfileFlag_IsUnderrun = 0x4;
public static final int kMotionProfileFlag_ActTraj_IsLast = 0x8;
public static final int kMotionProfileFlag_ActTraj_VelOnly = 0x10;
/**
* Signal enumeration for generic signal access.
* Although every signal is enumerated, only use this for traffic that must be solicited.
* Use the auto generated getters/setters at bottom of this header as much as possible.
* Signal enumeration for generic signal access. Although every signal is enumerated, only use
* this for traffic that must be solicited. Use the auto generated getters/setters at bottom of
* this header as much as possible.
*/
@SuppressWarnings("TypeName")
public enum param_t {
eProfileParamSlot0_P(1),
eProfileParamSlot0_I(2),
@@ -115,118 +117,227 @@ public class CanTalonJNI extends JNIWrapper {
eReserved120(120),
eLegacyControlMode(121);
@SuppressWarnings("MemberName")
public final int value;
private param_t(int value) {
param_t(int value) {
this.value = value;
}
}
public static native long new_CanTalonSRX(int deviceNumber, int controlPeriodMs, int enablePeriodMs);
public static native long new_CanTalonSRX(int deviceNumber, int controlPeriodMs,
int enablePeriodMs);
public static native long new_CanTalonSRX(int deviceNumber, int controlPeriodMs);
public static native long new_CanTalonSRX(int deviceNumber);
public static native long new_CanTalonSRX();
public static native void delete_CanTalonSRX(long handle);
public static native void GetMotionProfileStatus(long handle, Object canTalon, Object motionProfileStatus);
public static native void GetMotionProfileStatus(long handle, Object canTalon,
Object motionProfileStatus);
public static native void Set(long handle, double value);
public static native void SetParam(long handle, int paramEnum, double value);
public static native void RequestParam(long handle, int paramEnum);
public static native double GetParamResponse(long handle, int paramEnum);
public static native int GetParamResponseInt32(long handle, int paramEnum);
public static native void SetPgain(long handle, int slotIdx, double gain);
public static native void SetIgain(long handle, int slotIdx, double gain);
public static native void SetDgain(long handle, int slotIdx, double gain);
public static native void SetFgain(long handle, int slotIdx, double gain);
public static native void SetIzone(long handle, int slotIdx, int zone);
public static native void SetCloseLoopRampRate(long handle, int slotIdx, int closeLoopRampRate);
public static native void SetVoltageCompensationRate(long handle, double voltagePerMs);
public static native void SetSensorPosition(long handle, int pos);
public static native void SetForwardSoftLimit(long handle, int forwardLimit);
public static native void SetReverseSoftLimit(long handle, int reverseLimit);
public static native void SetForwardSoftEnable(long handle, int enable);
public static native void SetReverseSoftEnable(long handle, int enable);
public static native double GetPgain(long handle, int slotIdx);
public static native double GetIgain(long handle, int slotIdx);
public static native double GetDgain(long handle, int slotIdx);
public static native double GetFgain(long handle, int slotIdx);
public static native int GetIzone(long handle, int slotIdx);
public static native int GetCloseLoopRampRate(long handle, int slotIdx);
public static native double GetVoltageCompensationRate(long handle);
public static native int GetForwardSoftLimit(long handle);
public static native int GetReverseSoftLimit(long handle);
public static native int GetForwardSoftEnable(long handle);
public static native int GetReverseSoftEnable(long handle);
public static native int GetPulseWidthRiseToFallUs(long handle);
public static native int IsPulseWidthSensorPresent(long handle);
public static native void SetModeSelect2(long handle, int modeSelect, int demand);
public static native void SetStatusFrameRate(long handle, int frameEnum, int periodMs);
public static native void ClearStickyFaults(long handle);
public static native void ChangeMotionControlFramePeriod(long handle, int periodMs);
public static native void ClearMotionProfileTrajectories(long handle);
public static native int GetMotionProfileTopLevelBufferCount(long handle);
public static native boolean IsMotionProfileTopLevelBufferFull(long handle);
public static native void PushMotionProfileTrajectory(long handle, int targPos, int targVel, int profileSlotSelect, int timeDurMs, int velOnly, int isLastPoint, int zeroPos);
public static native void PushMotionProfileTrajectory(long handle, int targPos, int targVel,
int profileSlotSelect, int timeDurMs,
int velOnly, int isLastPoint, int zeroPos);
public static native void ProcessMotionProfileBuffer(long handle);
public static native int GetFault_OverTemp(long handle);
public static native int GetFault_UnderVoltage(long handle);
public static native int GetFault_ForLim(long handle);
public static native int GetFault_RevLim(long handle);
public static native int GetFault_HardwareFailure(long handle);
public static native int GetFault_ForSoftLim(long handle);
public static native int GetFault_RevSoftLim(long handle);
public static native int GetStckyFault_OverTemp(long handle);
public static native int GetStckyFault_UnderVoltage(long handle);
public static native int GetStckyFault_ForLim(long handle);
public static native int GetStckyFault_RevLim(long handle);
public static native int GetStckyFault_ForSoftLim(long handle);
public static native int GetStckyFault_RevSoftLim(long handle);
public static native int GetAppliedThrottle(long handle);
public static native int GetCloseLoopErr(long handle);
public static native int GetFeedbackDeviceSelect(long handle);
public static native int GetModeSelect(long handle);
public static native int GetLimitSwitchEn(long handle);
public static native int GetLimitSwitchClosedFor(long handle);
public static native int GetLimitSwitchClosedRev(long handle);
public static native int GetSensorPosition(long handle);
public static native int GetSensorVelocity(long handle);
public static native double GetCurrent(long handle);
public static native int GetBrakeIsEnabled(long handle);
public static native int GetEncPosition(long handle);
public static native int GetEncVel(long handle);
public static native int GetEncIndexRiseEvents(long handle);
public static native int GetQuadApin(long handle);
public static native int GetQuadBpin(long handle);
public static native int GetQuadIdxpin(long handle);
public static native int GetAnalogInWithOv(long handle);
public static native int GetAnalogInVel(long handle);
public static native double GetTemp(long handle);
public static native double GetBatteryV(long handle);
public static native int GetResetCount(long handle);
public static native int GetResetFlags(long handle);
public static native int GetFirmVers(long handle);
public static native int GetPulseWidthPosition(long handle);
public static native int GetPulseWidthVelocity(long handle);
public static native int GetPulseWidthRiseToRiseUs(long handle);
public static native int GetActTraj_IsValid(long handle);
public static native int GetActTraj_ProfileSlotSelect(long handle);
public static native int GetActTraj_VelOnly(long handle);
public static native int GetActTraj_IsLast(long handle);
public static native int GetOutputType(long handle);
public static native int GetHasUnderrun(long handle);
public static native int GetIsUnderrun(long handle);
public static native int GetNextID(long handle);
public static native int GetBufferIsFull(long handle);
public static native int GetCount(long handle);
public static native int GetActTraj_Velocity(long handle);
public static native int GetActTraj_Position(long handle);
public static native void SetDemand(long handle, int param);
public static native void SetOverrideLimitSwitchEn(long handle, int param);
public static native void SetFeedbackDeviceSelect(long handle, int param);
public static native void SetRevMotDuringCloseLoopEn(long handle, int param);
public static native void SetOverrideBrakeType(long handle, int param);
public static native void SetModeSelect(long handle, int param);
public static native void SetProfileSlotSelect(long handle, int param);
public static native void SetRampThrottle(long handle, int param);
public static native void SetRevFeedbackSensor(long handle, int param);
}

View File

@@ -12,27 +12,27 @@ public class CompressorJNI extends JNIWrapper {
public static native boolean checkCompressorModule(byte module);
public static native boolean getCompressor(long pcm_pointer);
public static native boolean getCompressor(long pcmPointer);
public static native void setClosedLoopControl(long pcm_pointer, boolean value);
public static native void setClosedLoopControl(long pcmPointer, boolean value);
public static native boolean getClosedLoopControl(long pcm_pointer);
public static native boolean getClosedLoopControl(long pcmPointer);
public static native boolean getPressureSwitch(long pcm_pointer);
public static native boolean getPressureSwitch(long pcmPointer);
public static native float getCompressorCurrent(long pcm_pointer);
public static native float getCompressorCurrent(long pcmPointer);
public static native boolean getCompressorCurrentTooHighFault(long pcm_pointer);
public static native boolean getCompressorCurrentTooHighFault(long pcmPointer);
public static native boolean getCompressorCurrentTooHighStickyFault(long pcm_pointer);
public static native boolean getCompressorCurrentTooHighStickyFault(long pcmPointer);
public static native boolean getCompressorShortedStickyFault(long pcm_pointer);
public static native boolean getCompressorShortedStickyFault(long pcmPointer);
public static native boolean getCompressorShortedFault(long pcm_pointer);
public static native boolean getCompressorShortedFault(long pcmPointer);
public static native boolean getCompressorNotConnectedStickyFault(long pcm_pointer);
public static native boolean getCompressorNotConnectedStickyFault(long pcmPointer);
public static native boolean getCompressorNotConnectedFault(long pcm_pointer);
public static native boolean getCompressorNotConnectedFault(long pcmPointer);
public static native void clearAllPCMStickyFaults(long pcm_pointer);
public static native void clearAllPCMStickyFaults(long pcmPointer);
}

View File

@@ -12,54 +12,54 @@ import java.nio.IntBuffer;
public class CounterJNI extends JNIWrapper {
public static native long initializeCounter(int mode, IntBuffer index);
public static native void freeCounter(long counter_pointer);
public static native void freeCounter(long counterPointer);
public static native void setCounterAverageSize(long counter_pointer, int size);
public static native void setCounterAverageSize(long counterPointer, int size);
public static native void setCounterUpSource(long counter_pointer, int pin,
boolean analogTrigger);
public static native void setCounterUpSource(long counterPointer, int pin,
boolean analogTrigger);
public static native void setCounterUpSourceEdge(long counter_pointer, boolean risingEdge,
boolean fallingEdge);
public static native void setCounterUpSourceEdge(long counterPointer, boolean risingEdge,
boolean fallingEdge);
public static native void clearCounterUpSource(long counter_pointer);
public static native void clearCounterUpSource(long counterPointer);
public static native void setCounterDownSource(long counter_pointer, int pin,
boolean analogTrigger);
public static native void setCounterDownSource(long counterPointer, int pin,
boolean analogTrigger);
public static native void setCounterDownSourceEdge(long counter_pointer, boolean risingEdge,
boolean fallingEdge);
public static native void setCounterDownSourceEdge(long counterPointer, boolean risingEdge,
boolean fallingEdge);
public static native void clearCounterDownSource(long counter_pointer);
public static native void clearCounterDownSource(long counterPointer);
public static native void setCounterUpDownMode(long counter_pointer);
public static native void setCounterUpDownMode(long counterPointer);
public static native void setCounterExternalDirectionMode(long counter_pointer);
public static native void setCounterExternalDirectionMode(long counterPointer);
public static native void setCounterSemiPeriodMode(long counter_pointer,
boolean highSemiPeriod);
public static native void setCounterSemiPeriodMode(long counterPointer,
boolean highSemiPeriod);
public static native void setCounterPulseLengthMode(long counter_pointer, double threshold);
public static native void setCounterPulseLengthMode(long counterPointer, double threshold);
public static native int getCounterSamplesToAverage(long counter_pointer);
public static native int getCounterSamplesToAverage(long counterPointer);
public static native void setCounterSamplesToAverage(long counter_pointer,
int samplesToAverage);
public static native void setCounterSamplesToAverage(long counterPointer,
int samplesToAverage);
public static native void resetCounter(long counter_pointer);
public static native void resetCounter(long counterPointer);
public static native int getCounter(long counter_pointer);
public static native int getCounter(long counterPointer);
public static native double getCounterPeriod(long counter_pointer);
public static native double getCounterPeriod(long counterPointer);
public static native void setCounterMaxPeriod(long counter_pointer, double maxPeriod);
public static native void setCounterMaxPeriod(long counterPointer, double maxPeriod);
public static native void setCounterUpdateWhenEmpty(long counter_pointer, boolean enabled);
public static native void setCounterUpdateWhenEmpty(long counterPointer, boolean enabled);
public static native boolean getCounterStopped(long counter_pointer);
public static native boolean getCounterStopped(long counterPointer);
public static native boolean getCounterDirection(long counter_pointer);
public static native boolean getCounterDirection(long counterPointer);
public static native void setCounterReverseDirection(long counter_pointer,
boolean reverseDirection);
public static native void setCounterReverseDirection(long counterPointer,
boolean reverseDirection);
}

View File

@@ -7,24 +7,25 @@
package edu.wpi.first.wpilibj.hal;
@SuppressWarnings("AbbreviationAsWordInName")
public class DIOJNI extends JNIWrapper {
public static native long initializeDigitalPort(long port_pointer);
public static native long initializeDigitalPort(long portPointer);
public static native void freeDigitalPort(long port_pointer);
public static native void freeDigitalPort(long portPointer);
public static native boolean allocateDIO(long digital_port_pointer, boolean input);
public static native boolean allocateDIO(long digitalPortPointer, boolean input);
public static native void freeDIO(long digital_port_pointer);
public static native void freeDIO(long digitalPortPointer);
public static native void setDIO(long digital_port_pointer, short value);
public static native void setDIO(long digitalPortPointer, short value);
public static native boolean getDIO(long digital_port_pointer);
public static native boolean getDIO(long digitalPortPointer);
public static native boolean getDIODirection(long digital_port_pointer);
public static native boolean getDIODirection(long digitalPortPointer);
public static native void pulse(long digital_port_pointer, double pulseLength);
public static native void pulse(long digitalPortPointer, double pulseLength);
public static native boolean isPulsing(long digital_port_pointer);
public static native boolean isPulsing(long digitalPortPointer);
public static native boolean isAnyPulsing();

View File

@@ -8,8 +8,11 @@
package edu.wpi.first.wpilibj.hal;
public class DigitalGlitchFilterJNI extends JNIWrapper {
public static native void setFilterSelect(long digital_port_pointer, int filter_index);
public static native int getFilterSelect(long digital_port_pointer);
public static native void setFilterPeriod(int filter_index, int fpga_cycles);
public static native int getFilterPeriod(int filter_index);
public static native void setFilterSelect(long digitalPortPointer, int filterIndex);
public static native int getFilterSelect(long digitalPortPointer);
public static native void setFilterPeriod(int filterIndex, int fpgaCycles);
public static native int getFilterPeriod(int filterIndex);
}

View File

@@ -10,32 +10,34 @@ package edu.wpi.first.wpilibj.hal;
import java.nio.IntBuffer;
public class EncoderJNI extends JNIWrapper {
public static native long initializeEncoder(byte port_a_module, int port_a_pin,
boolean port_a_analog_trigger, byte port_b_module, int port_b_pin, boolean port_b_analog_trigger,
boolean reverseDirection, IntBuffer index);
public static native long initializeEncoder(byte portAModule, int portAPin,
boolean portAAnalogTrigger, byte portBModule,
int portBPin, boolean portBAnalogTrigger,
boolean reverseDirection, IntBuffer index);
public static native void freeEncoder(long encoder_pointer);
public static native void freeEncoder(long encoderPointer);
public static native void resetEncoder(long encoder_pointer);
public static native void resetEncoder(long encoderPointer);
public static native int getEncoder(long encoder_pointer);
public static native int getEncoder(long encoderPointer);
public static native double getEncoderPeriod(long encoder_pointer);
public static native double getEncoderPeriod(long encoderPointer);
public static native void setEncoderMaxPeriod(long encoder_pointer, double maxPeriod);
public static native void setEncoderMaxPeriod(long encoderPointer, double maxPeriod);
public static native boolean getEncoderStopped(long encoder_pointer);
public static native boolean getEncoderStopped(long encoderPointer);
public static native boolean getEncoderDirection(long encoder_pointer);
public static native boolean getEncoderDirection(long encoderPointer);
public static native void setEncoderReverseDirection(long encoder_pointer,
boolean reverseDirection);
public static native void setEncoderReverseDirection(long encoderPointer,
boolean reverseDirection);
public static native void setEncoderSamplesToAverage(long encoder_pointer,
int samplesToAverage);
public static native void setEncoderSamplesToAverage(long encoderPointer,
int samplesToAverage);
public static native int getEncoderSamplesToAverage(long encoder_pointer);
public static native int getEncoderSamplesToAverage(long encoderPointer);
public static native void setEncoderIndexSource(long digital_port, int pin,
boolean analogTrigger, boolean activeHigh, boolean edgeSensitive);
public static native void setEncoderIndexSource(long digitalPort, int pin,
boolean analogTrigger, boolean activeHigh,
boolean edgeSensitive);
}

View File

@@ -7,6 +7,7 @@
package edu.wpi.first.wpilibj.hal;
@SuppressWarnings("AbbreviationAsWordInName")
public class HALUtil extends JNIWrapper {
public static final int NULL_PARAMETER = -1005;
public static final int SAMPLE_RATE_TOO_HIGH = 1001;
@@ -33,7 +34,7 @@ public class HALUtil extends JNIWrapper {
public static native void deleteMultiWait(long sem);
public static native void takeMultiWait(long sem, long m);
public static native void takeMultiWait(long sem, long ms);
public static native short getFPGAVersion();

View File

@@ -9,16 +9,17 @@ package edu.wpi.first.wpilibj.hal;
import java.nio.ByteBuffer;
@SuppressWarnings("AbbreviationAsWordInName")
public class I2CJNI extends JNIWrapper {
public static native void i2CInitialize(byte port);
public static native int i2CTransaction(byte port, byte address, ByteBuffer dataToSend,
byte sendSize, ByteBuffer dataReceived, byte receiveSize);
byte sendSize, ByteBuffer dataReceived, byte receiveSize);
public static native int i2CWrite(byte port, byte address, ByteBuffer dataToSend, byte sendSize);
public static native int i2CRead(byte port, byte address, ByteBuffer dataRecieved,
byte receiveSize);
byte receiveSize);
public static native void i2CClose(byte port);
}

View File

@@ -10,29 +10,30 @@ package edu.wpi.first.wpilibj.hal;
public class InterruptJNI extends JNIWrapper {
public interface InterruptJNIHandlerFunction {
void apply(int interruptAssertedMask, Object param);
};
}
public static native long initializeInterrupts(int interruptIndex, boolean watcher);
public static native void cleanInterrupts(long interrupt_pointer);
public static native void cleanInterrupts(long interruptPointer);
public static native int waitForInterrupt(long interrupt_pointer, double timeout,
boolean ignorePrevious);
public static native int waitForInterrupt(long interruptPointer, double timeout,
boolean ignorePrevious);
public static native void enableInterrupts(long interrupt_pointer);
public static native void enableInterrupts(long interruptPointer);
public static native void disableInterrupts(long interrupt_pointer);
public static native void disableInterrupts(long interruptPointer);
public static native double readRisingTimestamp(long interrupt_pointer);
public static native double readRisingTimestamp(long interruptPointer);
public static native double readFallingTimestamp(long interrupt_pointer);
public static native double readFallingTimestamp(long interruptPointer);
public static native void requestInterrupts(long interrupt_pointer, byte routing_module,
int routing_pin, boolean routing_analog_trigger);
public static native void requestInterrupts(long interruptPointer, byte routingModule,
int routingPin, boolean routingAnalogTrigger);
public static native void attachInterruptHandler(long interrupt_pointer,
InterruptJNIHandlerFunction handler, Object param);
public static native void attachInterruptHandler(long interruptPointer,
InterruptJNIHandlerFunction handler,
Object param);
public static native void setInterruptUpSourceEdge(long interrupt_pointer, boolean risingEdge,
boolean fallingEdge);
public static native void setInterruptUpSourceEdge(long interruptPointer, boolean risingEdge,
boolean fallingEdge);
}

View File

@@ -8,9 +8,9 @@
package edu.wpi.first.wpilibj.hal;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
//
// base class for all JNI wrappers
@@ -18,6 +18,7 @@ import java.io.FileOutputStream;
public class JNIWrapper {
static boolean libraryLoaded = false;
static File jniLibrary = null;
static {
try {
if (!libraryLoaded) {
@@ -62,5 +63,5 @@ public class JNIWrapper {
public static native long getPort(byte pin);
public static native void freePort(long port_pointer);
public static native void freePort(long portPointer);
}

View File

@@ -7,18 +7,15 @@
package edu.wpi.first.wpilibj.hal;
import java.lang.Runtime;
/**
* The NotifierJNI class directly wraps the C++ HAL Notifier.
*
* This class is not meant for direct use by teams. Instead, the
* edu.wpi.first.wpilibj.Notifier class, which corresponds to the C++ Notifier
* class, should be used.
* <p>This class is not meant for direct use by teams. Instead, the edu.wpi.first.wpilibj.Notifier
* class, which corresponds to the C++ Notifier class, should be used.
*/
public class NotifierJNI extends JNIWrapper {
/**
* Callback function
* Callback function.
*/
public interface NotifierJNIHandlerFunction {
void apply(long curTime);

View File

@@ -7,6 +7,7 @@
package edu.wpi.first.wpilibj.hal;
@SuppressWarnings("AbbreviationAsWordInName")
public class PDPJNI extends JNIWrapper {
public static native void initializePDP(int module);

View File

@@ -7,18 +7,19 @@
package edu.wpi.first.wpilibj.hal;
@SuppressWarnings("AbbreviationAsWordInName")
public class PWMJNI extends DIOJNI {
public static native boolean allocatePWMChannel(long digital_port_pointer);
public static native boolean allocatePWMChannel(long digitalPortPointer);
public static native void freePWMChannel(long digital_port_pointer);
public static native void freePWMChannel(long digitalPortPointer);
public static native void setPWM(long digital_port_pointer, short value);
public static native void setPWM(long digitalPortPointer, short value);
public static native short getPWM(long digital_port_pointer);
public static native short getPWM(long digitalPortPointer);
public static native void latchPWMZero(long digital_port_pointer);
public static native void latchPWMZero(long digitalPortPointer);
public static native void setPWMPeriodScale(long digital_port_pointer, int squelchMask);
public static native void setPWMPeriodScale(long digitalPortPointer, int squelchMask);
public static native long allocatePWM();

View File

@@ -8,11 +8,11 @@
package edu.wpi.first.wpilibj.hal;
public class RelayJNI extends DIOJNI {
public static native void setRelayForward(long digital_port_pointer, boolean on);
public static native void setRelayForward(long digitalPortPointer, boolean on);
public static native void setRelayReverse(long digital_port_pointer, boolean on);
public static native void setRelayReverse(long digitalPortPointer, boolean on);
public static native boolean getRelayForward(long digital_port_pointer);
public static native boolean getRelayForward(long digitalPortPointer);
public static native boolean getRelayReverse(long digital_port_pointer);
public static native boolean getRelayReverse(long digitalPortPointer);
}

View File

@@ -11,11 +11,12 @@ import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
@SuppressWarnings("AbbreviationAsWordInName")
public class SPIJNI extends JNIWrapper {
public static native void spiInitialize(byte port);
public static native int spiTransaction(byte port, ByteBuffer dataToSend,
ByteBuffer dataReceived, byte size);
ByteBuffer dataReceived, byte size);
public static native int spiWrite(byte port, ByteBuffer dataToSend, byte sendSize);
@@ -25,16 +26,16 @@ public class SPIJNI extends JNIWrapper {
public static native void spiSetSpeed(byte port, int speed);
public static native void spiSetOpts(byte port, int msb_first, int sample_on_trailing,
int clk_idle_high);
public static native void spiSetOpts(byte port, int msbFirst, int sampleOnTrailing,
int clkIdleHigh);
public static native void spiSetChipSelectActiveHigh(byte port);
public static native void spiSetChipSelectActiveLow(byte port);
public static native void spiInitAccumulator(byte port, int period, int cmd,
byte xferSize, int validMask, int validValue, byte dataShift,
byte dataSize, boolean isSigned, boolean bigEndian);
public static native void spiInitAccumulator(byte port, int period, int cmd, byte xferSize,
int validMask, int validValue, byte dataShift,
byte dataSize, boolean isSigned, boolean bigEndian);
public static native void spiFreeAccumulator(byte port);
@@ -53,5 +54,5 @@ public class SPIJNI extends JNIWrapper {
public static native double spiGetAccumulatorAverage(byte port);
public static native void spiGetAccumulatorOutput(byte port, LongBuffer value,
IntBuffer count);
IntBuffer count);
}

View File

@@ -10,7 +10,7 @@ package edu.wpi.first.wpilibj.hal;
public class SolenoidJNI extends JNIWrapper {
public static native long initializeSolenoidPort(long portPointer);
public static native void freeSolenoidPort(long port_pointer);
public static native void freeSolenoidPort(long portPointer);
public static native long getPortWithModule(byte module, byte channel);
@@ -20,11 +20,11 @@ public class SolenoidJNI extends JNIWrapper {
public static native byte getAllSolenoids(long port);
public static native int getPCMSolenoidBlackList(long pcm_pointer);
public static native int getPCMSolenoidBlackList(long pcmPointer);
public static native boolean getPCMSolenoidVoltageStickyFault(long pcm_pointer);
public static native boolean getPCMSolenoidVoltageStickyFault(long pcmPointer);
public static native boolean getPCMSolenoidVoltageFault(long pcm_pointer);
public static native boolean getPCMSolenoidVoltageFault(long pcmPointer);
public static native void clearAllPCMStickyFaults(long pcm_pointer);
public static native void clearAllPCMStickyFaults(long pcmPointer);
}

View File

@@ -7,18 +7,20 @@
package edu.wpi.first.wpilibj.image;
import edu.wpi.first.wpilibj.util.SortedVector;
import com.ni.vision.NIVision;
import edu.wpi.first.wpilibj.util.SortedVector;
/**
* An image where each pixel is treated as either on or off.
*
* @author dtjones
*/
public class BinaryImage extends MonoImage {
private int numParticles = -1;
private int m_numParticles = -1;
BinaryImage() throws NIVisionException {}
BinaryImage() throws NIVisionException {
}
BinaryImage(BinaryImage sourceImage) {
super(sourceImage);
@@ -30,25 +32,27 @@ public class BinaryImage extends MonoImage {
* @return The number of particles
*/
public int getNumberParticles() throws NIVisionException {
if (numParticles < 0)
numParticles = NIVision.imaqCountParticles(image, 1);
return numParticles;
if (m_numParticles < 0) {
m_numParticles = NIVision.imaqCountParticles(image, 1);
}
return m_numParticles;
}
private class ParticleSizeReport {
final int index;
final double size;
final int m_index;
final double m_size;
public ParticleSizeReport(int index) throws NIVisionException {
if ((!(index < BinaryImage.this.getNumberParticles())) || index < 0)
if ((!(index < BinaryImage.this.getNumberParticles())) || index < 0) {
throw new IndexOutOfBoundsException();
this.index = index;
size = ParticleAnalysisReport.getParticleToImagePercent(BinaryImage.this, index);
}
m_index = index;
m_size = ParticleAnalysisReport.getParticleToImagePercent(BinaryImage.this, index);
}
public ParticleAnalysisReport getParticleAnalysisReport() throws NIVisionException {
return new ParticleAnalysisReport(BinaryImage.this, index);
return new ParticleAnalysisReport(BinaryImage.this, m_index);
}
}
@@ -59,47 +63,50 @@ public class BinaryImage extends MonoImage {
* @return The ParticleAnalysisReport for the particle at the given index
*/
public ParticleAnalysisReport getParticleAnalysisReport(int index) throws NIVisionException {
if (!(index < getNumberParticles()))
if (!(index < getNumberParticles())) {
throw new IndexOutOfBoundsException();
}
return new ParticleAnalysisReport(this, index);
}
/**
* Gets all the particle analysis reports ordered from largest area to
* smallest.
* Gets all the particle analysis reports ordered from largest area to smallest.
*
* @param size The number of particles to return
* @return An array of ParticleReports from largest area to smallest
*/
public ParticleAnalysisReport[] getOrderedParticleAnalysisReports(int size)
throws NIVisionException {
if (size > getNumberParticles())
if (size > getNumberParticles()) {
size = getNumberParticles();
}
ParticleSizeReport[] reports = new ParticleSizeReport[size];
SortedVector sorter = new SortedVector(new SortedVector.Comparator() {
public int compare(Object object1, Object object2) {
ParticleSizeReport p1 = (ParticleSizeReport) object1;
ParticleSizeReport p2 = (ParticleSizeReport) object2;
if (p1.size < p2.size)
if (p1.m_size < p2.m_size) {
return -1;
else if (p1.size > p2.size)
} else if (p1.m_size > p2.m_size) {
return 1;
}
return 0;
}
});
for (int i = 0; i < getNumberParticles(); i++)
for (int i = 0; i < getNumberParticles(); i++) {
sorter.addElement(new ParticleSizeReport(i));
}
sorter.setSize(size);
sorter.copyInto(reports);
ParticleAnalysisReport[] finalReports = new ParticleAnalysisReport[reports.length];
for (int i = 0; i < finalReports.length; i++)
for (int i = 0; i < finalReports.length; i++) {
finalReports[i] = reports[i].getParticleAnalysisReport();
}
return finalReports;
}
/**
* Gets all the particle analysis reports ordered from largest area to
* smallest.
* Gets all the particle analysis reports ordered from largest area to smallest.
*
* @return An array of ParticleReports from largest are to smallest
*/
@@ -107,7 +114,7 @@ public class BinaryImage extends MonoImage {
return getOrderedParticleAnalysisReports(getNumberParticles());
}
@SuppressWarnings({"summaryjavadoc", "javadocmethod"})
public void write(String fileName) throws NIVisionException {
NIVision.RGBValue colorTable = new NIVision.RGBValue(0, 0, 255, 0);
try {
@@ -118,15 +125,14 @@ public class BinaryImage extends MonoImage {
}
/**
* removeSmallObjects filters particles based on their size. The algorithm
* erodes the image a specified number of times and keeps the particles from
* the original image that remain in the eroded image.
* removeSmallObjects filters particles based on their m_size. The algorithm erodes the image a
* specified number of times and keeps the particles from the original image that remain in the
* eroded image.
*
* @param connectivity8 true to use connectivity-8 or false for connectivity-4
* to determine whether particles are touching. For more information
* about connectivity, see Chapter 9, Binary Morphology, in the NI
* Vision Concepts manual.
* @param erosions the number of erosions to perform
* @param connectivity8 true to use connectivity-8 or false for connectivity-4 to determine
* whether particles are touching. For more information about connectivity,
* see Chapter 9, Binary Morphology, in the NI Vision Concepts manual.
* @param erosions the number of erosions to perform
* @return a BinaryImage after applying the filter
*/
public BinaryImage removeSmallObjects(boolean connectivity8, int erosions)
@@ -139,15 +145,14 @@ public class BinaryImage extends MonoImage {
}
/**
* removeLargeObjects filters particles based on their size. The algorithm
* erodes the image a specified number of times and discards the particles
* from the original image that remain in the eroded image.
* removeLargeObjects filters particles based on their m_size. The algorithm erodes the image a
* specified number of times and discards the particles from the original image that remain in the
* eroded image.
*
* @param connectivity8 true to use connectivity-8 or false for connectivity-4
* to determine whether particles are touching. For more information
* about connectivity, see Chapter 9, Binary Morphology, in the NI
* Vision Concepts manual.
* @param erosions the number of erosions to perform
* @param connectivity8 true to use connectivity-8 or false for connectivity-4 to determine
* whether particles are touching. For more information about connectivity,
* see Chapter 9, Binary Morphology, in the NI Vision Concepts manual.
* @param erosions the number of erosions to perform
* @return a BinaryImage after applying the filter
*/
public BinaryImage removeLargeObjects(boolean connectivity8, int erosions)
@@ -158,12 +163,14 @@ public class BinaryImage extends MonoImage {
return result;
}
@SuppressWarnings({"summaryjavadoc", "javadocmethod"})
public BinaryImage convexHull(boolean connectivity8) throws NIVisionException {
BinaryImage result = new BinaryImage();
NIVision.imaqConvexHull(result.image, image, connectivity8 ? 1 : 0);
return result;
}
@SuppressWarnings({"summaryjavadoc", "javadocmethod"})
public BinaryImage particleFilter(NIVision.ParticleFilterCriteria2[] criteria)
throws NIVisionException {
BinaryImage result = new BinaryImage();

View File

@@ -25,7 +25,7 @@ public abstract class ColorImage extends ImageBase {
}
private BinaryImage threshold(NIVision.ColorMode colorMode, int low1, int high1, int low2,
int high2, int low3, int high3) throws NIVisionException {
int high2, int low3, int high3) throws NIVisionException {
BinaryImage res = new BinaryImage();
NIVision.Range range1 = new NIVision.Range(low1, high1);
NIVision.Range range2 = new NIVision.Range(low2, high2);
@@ -39,73 +39,69 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Return a mask of the areas of the image that fall within the given ranges
* for color values
* Return a mask of the areas of the image that fall within the given ranges for color values
*
* @param redLow The lower red limit.
* @param redHigh The upper red limit.
* @param greenLow The lower green limit.
* @param redLow The lower red limit.
* @param redHigh The upper red limit.
* @param greenLow The lower green limit.
* @param greenHigh The upper green limit.
* @param blueLow The lower blue limit.
* @param blueHigh The upper blue limit.
* @param blueLow The lower blue limit.
* @param blueHigh The upper blue limit.
* @return A BinaryImage masking the areas which match the given thresholds.
*/
public BinaryImage thresholdRGB(int redLow, int redHigh, int greenLow, int greenHigh,
int blueLow, int blueHigh) throws NIVisionException {
int blueLow, int blueHigh) throws NIVisionException {
return threshold(NIVision.ColorMode.RGB, redLow, redHigh, greenLow, greenHigh, blueLow,
blueHigh);
}
/**
* Return a mask of the areas of the image that fall within the given ranges
* for color values
* Return a mask of the areas of the image that fall within the given ranges for color values
*
* @param hueLow The lower hue limit.
* @param hueHigh The upper hue limit.
* @param saturationLow The lower saturation limit.
* @param hueLow The lower hue limit.
* @param hueHigh The upper hue limit.
* @param saturationLow The lower saturation limit.
* @param saturationHigh The upper saturation limit.
* @param luminenceLow The lower luminence limit.
* @param luminenceHigh The upper luminence limit.
* @param luminenceLow The lower luminence limit.
* @param luminenceHigh The upper luminence limit.
* @return A BinaryImage masking the areas which match the given thresholds.
*/
public BinaryImage thresholdHSL(int hueLow, int hueHigh, int saturationLow, int saturationHigh,
int luminenceLow, int luminenceHigh) throws NIVisionException {
int luminenceLow, int luminenceHigh) throws NIVisionException {
return threshold(NIVision.ColorMode.HSL, hueLow, hueHigh, saturationLow, saturationHigh,
luminenceLow, luminenceHigh);
}
/**
* Return a mask of the areas of the image that fall within the given ranges
* for color values
* Return a mask of the areas of the image that fall within the given ranges for color values
*
* @param hueLow The lower hue limit.
* @param hueHigh The upper hue limit.
* @param saturationLow The lower saturation limit.
* @param hueLow The lower hue limit.
* @param hueHigh The upper hue limit.
* @param saturationLow The lower saturation limit.
* @param saturationHigh The upper saturation limit.
* @param valueHigh The lower value limit.
* @param valueLow The upper value limit.
* @param valueHigh The lower value limit.
* @param valueLow The upper value limit.
* @return A BinaryImage masking the areas which match the given thresholds.
*/
public BinaryImage thresholdHSV(int hueLow, int hueHigh, int saturationLow, int saturationHigh,
int valueLow, int valueHigh) throws NIVisionException {
int valueLow, int valueHigh) throws NIVisionException {
return threshold(NIVision.ColorMode.HSV, hueLow, hueHigh, saturationLow, saturationHigh,
valueLow, valueHigh);
}
/**
* Return a mask of the areas of the image that fall within the given ranges
* for color values
* Return a mask of the areas of the image that fall within the given ranges for color values
*
* @param hueLow The lower hue limit.
* @param hueHigh The upper hue limit.
* @param saturationLow The lower saturation limit.
* @param hueLow The lower hue limit.
* @param hueHigh The upper hue limit.
* @param saturationLow The lower saturation limit.
* @param saturationHigh The upper saturation limit.
* @param intansityLow The lower intensity limit.
* @param intensityHigh The upper intensity limit.
* @param intansityLow The lower intensity limit.
* @param intensityHigh The upper intensity limit.
* @return A BinaryImage masking the areas which match the given thresholds.
*/
public BinaryImage thresholdHSI(int hueLow, int hueHigh, int saturationLow, int saturationHigh,
int intansityLow, int intensityHigh) throws NIVisionException {
int intansityLow, int intensityHigh) throws NIVisionException {
return threshold(NIVision.ColorMode.HSI, hueLow, hueHigh, saturationLow, saturationHigh,
intansityLow, intensityHigh);
}
@@ -141,8 +137,7 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Get the green color plane from the image when represented in RGB color
* space.
* Get the green color plane from the image when represented in RGB color space.
*
* @return The green color plane from the image.
*/
@@ -151,8 +146,7 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Get the blue color plane from the image when represented in RGB color
* space.
* Get the blue color plane from the image when represented in RGB color space.
*
* @return The blue color plane from the image.
*/
@@ -188,8 +182,7 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Get the saturation color plane from the image when represented in HSL color
* space.
* Get the saturation color plane from the image when represented in HSL color space.
*
* @return The saturation color plane from the image.
*/
@@ -198,8 +191,7 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Get the saturation color plane from the image when represented in HSV color
* space.
* Get the saturation color plane from the image when represented in HSV color space.
*
* @return The saturation color plane from the image.
*/
@@ -208,8 +200,7 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Get the saturation color plane from the image when represented in HSI color
* space.
* Get the saturation color plane from the image when represented in HSI color space.
*
* @return The saturation color plane from the image.
*/
@@ -218,8 +209,7 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Get the luminance color plane from the image when represented in HSL color
* space.
* Get the luminance color plane from the image when represented in HSL color space.
*
* @return The luminance color plane from the image.
*/
@@ -228,8 +218,7 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Get the value color plane from the image when represented in HSV color
* space.
* Get the value color plane from the image when represented in HSV color space.
*
* @return The value color plane from the image.
*/
@@ -238,8 +227,7 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Get the intensity color plane from the image when represented in HSI color
* space.
* Get the intensity color plane from the image when represented in HSI color space.
*
* @return The intensity color plane from the image.
*/
@@ -266,9 +254,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the red color plane from the image when represented in RGB color space.
* This does not create a new image, but modifies this one instead. Create a
* copy before hand if you need to continue using the original.
* Set the red color plane from the image when represented in RGB color space. This does not
* create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -278,9 +266,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the green color plane from the image when represented in RGB color
* space. This does not create a new image, but modifies this one instead.
* Create a copy before hand if you need to continue using the original.
* Set the green color plane from the image when represented in RGB color space. This does not
* create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -290,9 +278,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the blue color plane from the image when represented in RGB color
* space. This does not create a new image, but modifies this one instead.
* Create a copy before hand if you need to continue using the original.
* Set the blue color plane from the image when represented in RGB color space. This does not
* create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -302,9 +290,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the hue color plane from the image when represented in HSL color space.
* This does not create a new image, but modifies this one instead. Create a
* copy before hand if you need to continue using the original.
* Set the hue color plane from the image when represented in HSL color space. This does not
* create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -314,9 +302,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the hue color plane from the image when represented in HSV color space.
* This does not create a new image, but modifies this one instead. Create a
* copy before hand if you need to continue using the original.
* Set the hue color plane from the image when represented in HSV color space. This does not
* create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -326,9 +314,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the hue color plane from the image when represented in HSI color space.
* This does not create a new image, but modifies this one instead. Create a
* copy before hand if you need to continue using the original.
* Set the hue color plane from the image when represented in HSI color space. This does not
* create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -338,9 +326,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the saturation color plane from the image when represented in HSL color
* space. This does not create a new image, but modifies this one instead.
* Create a copy before hand if you need to continue using the original.
* Set the saturation color plane from the image when represented in HSL color space. This does
* not create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -350,9 +338,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the saturation color plane from the image when represented in HSV color
* space. This does not create a new image, but modifies this one instead.
* Create a copy before hand if you need to continue using the original.
* Set the saturation color plane from the image when represented in HSV color space. This does
* not create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -362,9 +350,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the saturation color plane from the image when represented in HSI color
* space. This does not create a new image, but modifies this one instead.
* Create a copy before hand if you need to continue using the original.
* Set the saturation color plane from the image when represented in HSI color space. This does
* not create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -374,9 +362,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the luminance color plane from the image when represented in HSL color
* space. This does not create a new image, but modifies this one instead.
* Create a copy before hand if you need to continue using the original.
* Set the luminance color plane from the image when represented in HSL color space. This does not
* create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -386,9 +374,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the value color plane from the image when represented in HSV color
* space. This does not create a new image, but modifies this one instead.
* Create a copy before hand if you need to continue using the original.
* Set the value color plane from the image when represented in HSV color space. This does not
* create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -398,9 +386,9 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Set the intensity color plane from the image when represented in HSI color
* space. This does not create a new image, but modifies this one instead.
* Create a copy before hand if you need to continue using the original.
* Set the intensity color plane from the image when represented in HSI color space. This does not
* create a new image, but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
*
* @param plane The MonoImage representing the new color plane.
* @return The resulting image.
@@ -410,10 +398,10 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Calculates the histogram of each plane of a color image and redistributes
* pixel values across the desired range while maintaining pixel value
* groupings. This does not create a new image, but modifies this one instead.
* Create a copy before hand if you need to continue using the original.
* Calculates the histogram of each plane of a color image and redistributes pixel values across
* the desired range while maintaining pixel value groupings. This does not create a new image,
* but modifies this one instead. Create a copy before hand if you need to continue using the
* original.
*
* @return The modified image.
*/
@@ -423,11 +411,10 @@ public abstract class ColorImage extends ImageBase {
}
/**
* Calculates the histogram of each plane of a color image and redistributes
* pixel values across the desired range while maintaining pixel value
* groupings for the Luminance plane only. This does not create a new image,
* but modifies this one instead. Create a copy before hand if you need to
* continue using the original.
* Calculates the histogram of each plane of a color image and redistributes pixel values across
* the desired range while maintaining pixel value groupings for the Luminance plane only. This
* does not create a new image, but modifies this one instead. Create a copy before hand if you
* need to continue using the original.
*
* @return The modified image.
*/

View File

@@ -11,7 +11,7 @@ import com.ni.vision.NIVision;
/**
* A color image represented in HSL color space at 3 bytes per pixel.
*$
*
* @author dtjones
*/
public class HSLImage extends ColorImage {
@@ -29,7 +29,7 @@ public class HSLImage extends ColorImage {
/**
* Create a new image by loading a file.
*$
*
* @param fileName The path of the file to load.
*/
public HSLImage(String fileName) throws NIVisionException {

View File

@@ -12,14 +12,15 @@ import com.ni.vision.NIVision.Image;
/**
* Class representing a generic image.
*$
*
* @author dtjones
*/
public abstract class ImageBase {
/**
* Pointer to the image memory
* Pointer to the image memory.
*/
@SuppressWarnings("MemberName")
public final Image image;
static final int DEFAULT_BORDER_SIZE = 3;
@@ -28,10 +29,9 @@ public abstract class ImageBase {
}
/**
* Creates a new image pointing to the same data as the source image. The
* imgae data is not copied, it is just referenced by both objects. Freeing
* one will free both.
*$
* Creates a new image pointing to the same data as the source image. The imgae data is not
* copied, it is just referenced by both objects. Freeing one will free both.
*
* @param sourceImage The image to reference
*/
ImageBase(ImageBase sourceImage) {
@@ -41,8 +41,8 @@ public abstract class ImageBase {
/**
* Write the image to a file.
*
* Supported extensions: .aipd or .apd AIPD .bmp BMP .jpg or .jpeg JPEG .jp2
* JPEG2000 .png PNG .tif or .tiff TIFF
* <p>Supported extensions: .aipd or .apd AIPD .bmp BMP .jpg or .jpeg JPEG .jp2 JPEG2000 .png PNG
* .tif or .tiff TIFF
*
* @param fileName The path to write the image to.
*/
@@ -61,7 +61,7 @@ public abstract class ImageBase {
/**
* Get the height of the image in pixels.
*$
*
* @return The height of the image.
*/
public int getHeight() throws NIVisionException {
@@ -70,7 +70,7 @@ public abstract class ImageBase {
/**
* Get the width of the image in pixels.
*$
*
* @return The width of the image.
*/
public int getWidth() throws NIVisionException {

View File

@@ -8,15 +8,15 @@
package edu.wpi.first.wpilibj.image;
import com.ni.vision.NIVision;
import com.ni.vision.NIVision.EllipseDescriptor;
import com.ni.vision.NIVision.CurveOptions;
import com.ni.vision.NIVision.ShapeDetectionOptions;
import com.ni.vision.NIVision.ROI;
import com.ni.vision.NIVision.DetectEllipsesResult;
import com.ni.vision.NIVision.EllipseDescriptor;
import com.ni.vision.NIVision.ROI;
import com.ni.vision.NIVision.ShapeDetectionOptions;
/**
* A grey scale image represented at a byte per pixel.
*$
*
* @author dtjones
*/
public class MonoImage extends ImageBase {
@@ -33,10 +33,11 @@ public class MonoImage extends ImageBase {
}
public DetectEllipsesResult detectEllipses(EllipseDescriptor ellipseDescriptor,
CurveOptions curveOptions, ShapeDetectionOptions shapeDetectionOptions, ROI roi)
throws NIVisionException {
return NIVision.imaqDetectEllipses(image, ellipseDescriptor, curveOptions,
shapeDetectionOptions, roi);
CurveOptions curveOptions,
ShapeDetectionOptions shapeDetectionOptions,
ROI roi) throws NIVisionException {
return NIVision
.imaqDetectEllipses(image, ellipseDescriptor, curveOptions, shapeDetectionOptions, roi);
}
public DetectEllipsesResult detectEllipses(EllipseDescriptor ellipseDescriptor)

View File

@@ -8,25 +8,25 @@
package edu.wpi.first.wpilibj.image;
/**
* Exception class which looks up nivision error codes
*$
* Exception class which looks up nivision error codes.
*
* @author dtjones
*/
@SuppressWarnings("all")
public class NIVisionException extends Exception {
/**
* Create a new NIVisionException.
*$
* @param msg The message to pass with the exception describing what caused
* it.
*
* @param msg The message to pass with the exception describing what caused it.
*/
public NIVisionException(String msg) {
super(msg);
}
/**
* Create a new vision exception
*$
* Create a new vision exception.
*
* @param errorCode the bad status code
*/
public NIVisionException(int errorCode) {

View File

@@ -11,7 +11,7 @@ import com.ni.vision.NIVision;
/**
* Class to store commonly used information about a particle.
*$
*
* @author dtjones
*/
public class ParticleAnalysisReport {
@@ -19,45 +19,72 @@ public class ParticleAnalysisReport {
/**
* The height of the image in pixels.
*/
@SuppressWarnings("membername")
public final int imageHeight;
/**
* The width of the image in pixels.
*/
@SuppressWarnings("membername")
public final int imageWidth;
/**
* X-coordinate of the point representing the average position of the total
* particle mass, assuming every point in the particle has a constant density
* X-coordinate of the point representing the average position of the total particle mass,
* assuming every point in the particle has a constant density.
*/
@SuppressWarnings("membername")
public final int center_mass_x; // MeasurementType: IMAQ_MT_CENTER_OF_MASS_X
/**
* Y-coordinate of the point representing the average position of the total
* particle mass, assuming every point in the particle has a constant density
* Y-coordinate of the point representing the average position of the total particle mass,
* assuming every point in the particle has a constant density.
*/
@SuppressWarnings("membername")
public final int center_mass_y; // MeasurementType: IMAQ_MT_CENTER_OF_MASS_Y
/**
* Center of mass x value normalized to -1.0 to +1.0 range.
*/
@SuppressWarnings("membername")
public final double center_mass_x_normalized;
/**
* Center of mass y value normalized to -1.0 to +1.0 range.
*/
@SuppressWarnings("membername")
public final double center_mass_y_normalized;
/** Area of the particle */
/**
* Area of the particle.
*/
@SuppressWarnings("membername")
public final double particleArea; // MeasurementType: IMAQ_MT_AREA
/** Bounding Rectangle */
/**
* Bounding Rectangle.
*/
@SuppressWarnings("membername")
public final int boundingRectLeft; // left/top/width/height
/** Bounding Rectangle */
/**
* Bounding Rectangle.
*/
@SuppressWarnings("membername")
public final int boundingRectTop;
/** Bounding Rectangle */
/**
* Bounding Rectangle.
*/
@SuppressWarnings("membername")
public final int boundingRectWidth;
/** Bounding Rectangle */
/**
* Bounding Rectangle.
*/
@SuppressWarnings("membername")
public final int boundingRectHeight;
/** Percentage of the particle Area covering the Image Area. */
/**
* Percentage of the particle Area covering the Image Area.
*/
@SuppressWarnings("membername")
public final double particleToImagePercent; // MeasurementType:
// IMAQ_MT_AREA_BY_IMAGE_AREA
/** Percentage of the particle Area in relation to its Particle and Holes Area */
// IMAQ_MT_AREA_BY_IMAGE_AREA
/**
* Percentage of the particle Area in relation to its Particle and Holes Area.
*/
@SuppressWarnings("membername")
public final double particleQuality; // MeasurementType:
// IMAQ_MT_AREA_BY_PARTICLE_AND_HOLES_AREA
// IMAQ_MT_AREA_BY_PARTICLE_AND_HOLES_AREA
ParticleAnalysisReport(BinaryImage image, int index) throws NIVisionException {
imageHeight = image.getHeight();
@@ -99,7 +126,7 @@ public class ParticleAnalysisReport {
/**
* Get string representation of the particle analysis report.
*$
*
* @return A string representation of the particle analysis report.
*/
public String toString() {

View File

@@ -11,7 +11,7 @@ import com.ni.vision.NIVision;
/**
* A color image represented in RGB color space at 3 bytes per pixel.
*$
*
* @author dtjones
*/
public class RGBImage extends ColorImage {
@@ -29,7 +29,7 @@ public class RGBImage extends ColorImage {
/**
* Create a new image by loading a file.
*$
*
* @param fileName The path of the file to load.
*/
public RGBImage(String fileName) throws NIVisionException {

View File

@@ -1,12 +1,14 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<head>
<title>Image Processing Wrappers</title>
<meta http-equiv="Content-Type" content="text/html; charset=MacRoman">
</head>
<body>
Provides classes to access National Instrument's nivison library for machine vision enables automated image processing
for color identification, tracking and analysis. The full specification for the simplified FRC Vision programming
interface is in the FRC Vision API Specification document, which is in the
WindRiver\docs\extensions\FRC directory of the Wind River installation with this document. </body>
</head>
<body>
Provides classes to access National Instrument's nivison library for machine vision enables
automated image processing for color identification, tracking and analysis. The full
specification for the simplified FRC Vision programming interface is in the FRC Vision API
Specification document, which is in the WindRiver\docs\extensions\FRC directory of the Wind River
installation with this document.
</body>
</html>

View File

@@ -12,19 +12,17 @@ import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.Utility;
/**
* Timer objects measure accumulated time in milliseconds. The timer object
* functions like a stopwatch. It can be started, stopped, and cleared. When the
* timer is running its value counts up in milliseconds. When stopped, the timer
* holds the current value. The implementation simply records the time when
* started and subtracts the current time whenever the value is requested.
* Timer objects measure accumulated time in milliseconds. The timer object functions like a
* stopwatch. It can be started, stopped, and cleared. When the timer is running its value counts
* up in milliseconds. When stopped, the timer holds the current value. The implementation simply
* records the time when started and subtracts the current time whenever the value is requested.
*/
public class HardwareTimer implements Timer.StaticInterface {
/**
* Pause the thread for a specified time. Pause the execution of the thread
* for a specified period of time given in seconds. Motors will continue to
* run at their last assigned values, and sensors will continue to update.
* Only the task containing the wait will pause until the wait time is
* expired.
* Pause the thread for a specified time. Pause the execution of the thread for a specified period
* of time given in seconds. Motors will continue to run at their last assigned values, and
* sensors will continue to update. Only the task containing the wait will pause until the wait
* time is expired.
*
* @param seconds Length of time to pause
*/
@@ -32,13 +30,14 @@ public class HardwareTimer implements Timer.StaticInterface {
public void delay(final double seconds) {
try {
Thread.sleep((long) (seconds * 1e3));
} catch (final InterruptedException e) {
} catch (final InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
/**
* Return the system clock time in seconds. Return the time from the FPGA
* hardware clock in seconds since the FPGA started.
* Return the system clock time in seconds. Return the time from the FPGA hardware clock in
* seconds since the FPGA started.
*
* @return Robot running time in seconds.
*/
@@ -63,8 +62,8 @@ public class HardwareTimer implements Timer.StaticInterface {
private boolean m_running;
/**
* Create a new timer object. Create a new timer object and reset the time
* to zero. The timer is initially not running and must be started.
* Create a new timer object. Create a new timer object and reset the time to zero. The timer is
* initially not running and must be started.
*/
public TimerImpl() {
reset();
@@ -75,24 +74,23 @@ public class HardwareTimer implements Timer.StaticInterface {
}
/**
* Get the current time from the timer. If the clock is running it is
* derived from the current system clock the start time stored in the timer
* class. If the clock is not running, then return the time when it was last
* stopped.
* Get the current time from the timer. If the clock is running it is derived from the current
* system clock the start time stored in the timer class. If the clock is not running, then
* return the time when it was last stopped.
*
* @return Current time value for this timer in seconds
*/
public synchronized double get() {
if (m_running) {
return ((double) ((getMsClock() - m_startTime) + m_accumulatedTime)) / 1000.0;
return ((getMsClock() - m_startTime) + m_accumulatedTime) / 1000.0;
} else {
return m_accumulatedTime;
}
}
/**
* Reset the timer by setting the time to 0. Make the timer startTime the
* current time so new requests will be relative now
* Reset the timer by setting the time to 0. Make the timer start time the current time so new
* requests will be relative now
*/
public synchronized void reset() {
m_accumulatedTime = 0;
@@ -100,8 +98,8 @@ public class HardwareTimer implements Timer.StaticInterface {
}
/**
* Start the timer running. Just set the running flag to true indicating
* that all time requests should be relative to the system clock.
* Start the timer running. Just set the running flag to true indicating that all time
* requests should be relative to the system clock.
*/
public synchronized void start() {
m_startTime = getMsClock();
@@ -109,9 +107,9 @@ public class HardwareTimer implements Timer.StaticInterface {
}
/**
* Stop the timer. This computes the time as of now and clears the running
* flag, causing all subsequent time requests to be read from the
* accumulated time rather than looking at the system clock.
* Stop the timer. This computes the time as of now and clears the running flag, causing all
* subsequent time requests to be read from the accumulated time rather than looking at the
* system clock.
*/
public synchronized void stop() {
final double temp = get();
@@ -120,10 +118,9 @@ public class HardwareTimer implements Timer.StaticInterface {
}
/**
* Check if the period specified has passed and if it has, advance the start
* time by that period. This is useful to decide if it's time to do periodic
* work without drifting later by the time it took to get around to
* checking.
* Check if the period specified has passed and if it has, advance the start time by that
* period. This is useful to decide if it's time to do periodic work without drifting later by
* the time it took to get around to checking.
*
* @param period The period to check for (in seconds).
* @return If the period has passed.

View File

@@ -1,23 +1,25 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<head>
<title>WPI Robotics library</title>
<meta http-equiv="Content-Type" content="text/html; charset=MacRoman">
</head>
<body>
The WPI Robotics library (WPILibJ) is a set of Java classes that interfaces to the hardware in the FRC
control system and your robot. There are classes to handle sensors, motors, the driver
</head>
<body>
The WPI Robotics library (WPILibJ) is a set of Java classes that interfaces to the hardware in the
FRC control system and your robot. There are classes to handle sensors, motors, the driver
station, and a number of other utility functions like timing and field management.
The library is designed to:
<ul>
<li>Deal with all the low level interfacing to these components so you can concentrate on
solving this yearÕs Òrobot problemÓ. This is a philosophical decision to let you focus
on the higher-level design of your robot rather than deal with the details of the
processor and the operating system.</li>
solving this yearÕs Òrobot problemÓ. This is a philosophical decision to let you focus
on the higher-level design of your robot rather than deal with the details of the
processor and the operating system.
</li>
<li>Understand everything at all levels by making the full source code of the library
available. You can study (and modify) the algorithms used by the gyro class for
oversampling and integration of the input signal or just ask the class for the current
robot heading. You can work at any level.</li>
available. You can study (and modify) the algorithms used by the gyro class for
oversampling and integration of the input signal or just ask the class for the current
robot heading. You can work at any level.
</li>
</ul>
</body>
</html>
</body>
</html>

View File

@@ -7,10 +7,6 @@
package edu.wpi.first.wpilibj.vision;
import edu.wpi.first.wpilibj.image.ColorImage;
import edu.wpi.first.wpilibj.image.HSLImage;
import edu.wpi.first.wpilibj.image.NIVisionException;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.OutputStream;
@@ -18,16 +14,21 @@ import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.image.ColorImage;
import edu.wpi.first.wpilibj.image.HSLImage;
import edu.wpi.first.wpilibj.image.NIVisionException;
import static com.ni.vision.NIVision.Image;
import static com.ni.vision.NIVision.Priv_ReadJPEGString_C;
import static edu.wpi.first.wpilibj.Timer.delay;
/**
* Axis M1011 network camera
* Axis M1011 network camera.
*/
public class AxisCamera {
public enum WhiteBalance {
kAutomatic, kHold, kFixedOutdoor1, kFixedOutdoor2, kFixedIndoor, kFixedFluorescent1, kFixedFluorescent2,
kAutomatic, kHold, kFixedOutdoor1, kFixedOutdoor2, kFixedIndoor, kFixedFluorescent1,
kFixedFluorescent2,
}
public enum ExposureControl {
@@ -53,7 +54,7 @@ public class AxisCamera {
private static final String[] kRotationStrings = {"0", "180",};
private final static int kImageBufferAllocationIncrement = 1000;
private static final int kImageBufferAllocationIncrement = 1000;
private String m_cameraHost;
private Socket m_cameraSocket;
@@ -78,19 +79,50 @@ public class AxisCamera {
private boolean m_done = false;
/**
* AxisCamera constructor
* AxisCamera constructor.
*
* @param cameraHost The host to find the camera at, typically an IP address
*/
public AxisCamera(String cameraHost) {
m_cameraHost = cameraHost;
m_captureThread.start();
/*
Thread spawned by AxisCamera constructor to receive images from cam.
*/
final Thread captureThread = new Thread(() -> {
int consecutiveErrors = 0;
// Loop on trying to setup the camera connection. This happens in a
// background
// thread so it shouldn't effect the operation of user programs.
while (!m_done) {
String requestString =
"GET /mjpg/video.mjpg HTTP/1.1\n" + "User-Agent: HTTPStreamClient\n"
+ "Connection: Keep-Alive\n" + "Cache-Control: no-cache\n"
+ "Authorization: Basic RlJDOkZSQw==\n\n";
try {
m_cameraSocket = AxisCamera.this.createCameraSocket(requestString);
AxisCamera.this.readImagesFromCamera();
consecutiveErrors = 0;
} catch (IOException ex) {
consecutiveErrors++;
if (consecutiveErrors > 5) {
ex.printStackTrace();
}
}
Timer.delay(0.5);
}
});
captureThread.start();
}
/**
* Return true if the latest image from the camera has not been retrieved by
* calling GetImage() yet.
*$
* Return true if the latest image from the camera has not been retrieved by calling GetImage()
* yet.
*
* @return true if the image has not been retrieved yet.
*/
public boolean isFreshImage() {
@@ -100,8 +132,7 @@ public class AxisCamera {
/**
* Get an image from the camera and store it in the provided image.
*
* @param image The imaq image to store the result in. This must be an HSL or
* RGB image.
* @param image The imaq image to store the result in. This must be an HSL or RGB image.
* @return <code>true</code> upon success, <code>false</code> on a failure
*/
public boolean getImage(Image image) {
@@ -121,8 +152,7 @@ public class AxisCamera {
/**
* Get an image from the camera and store it in the provided image.
*
* @param image The image to store the result in. This must be an HSL or RGB
* image
* @param image The image to store the result in. This must be an HSL or RGB image
* @return true upon success, false on a failure
*/
public boolean getImage(ColorImage image) {
@@ -130,8 +160,7 @@ public class AxisCamera {
}
/**
* Instantiate a new image object and fill it with the latest image from the
* camera.
* Instantiate a new image object and fill it with the latest image from the camera.
*
* @return a pointer to an HSLImage object
*/
@@ -160,6 +189,8 @@ public class AxisCamera {
}
/**
* The brightness.
*
* @return The configured brightness of the camera images
*/
public int getBrightness() {
@@ -183,6 +214,8 @@ public class AxisCamera {
}
/**
* The white balance.
*
* @return The configured white balances of the camera images
*/
public WhiteBalance getWhiteBalance() {
@@ -210,6 +243,8 @@ public class AxisCamera {
}
/**
* The current color level.
*
* @return The configured color level of the camera images
*/
public int getColorLevel() {
@@ -233,6 +268,8 @@ public class AxisCamera {
}
/**
* The current exposure control.
*
* @return The configured exposure control mode of the camera
*/
public ExposureControl getExposureControl() {
@@ -244,8 +281,8 @@ public class AxisCamera {
/**
* Request a change in the exposure priority of the camera.
*
* @param exposurePriority Valid values are 0, 50, 100. 0 = Prioritize image
* quality 50 = None 100 = Prioritize frame rate
* @param exposurePriority Valid values are 0, 50, 100. 0 = Prioritize image quality 50 = None 100
* = Prioritize frame rate
*/
public void writeExposurePriority(int exposurePriority) {
if (exposurePriority != 0 && exposurePriority != 50 && exposurePriority != 100) {
@@ -261,6 +298,8 @@ public class AxisCamera {
}
/**
* Gets the exposure priority.
*
* @return The configured exposure priority of the camera
*/
public int getExposurePriority() {
@@ -270,11 +309,10 @@ public class AxisCamera {
}
/**
* Write the maximum frames per second that the camera should send Write 0 to
* send as many as possible.
* Write the maximum frames per second that the camera should send Write 0 to send as many as
* possible.
*
* @param maxFPS The number of frames the camera should send in a second,
* exposure permitting.
* @param maxFPS The number of frames the camera should send in a second, exposure permitting.
*/
public void writeMaxFPS(int maxFPS) {
synchronized (m_parametersLock) {
@@ -287,6 +325,8 @@ public class AxisCamera {
}
/**
* The max frames per second of the camera.
*
* @return The configured maximum FPS of the camera
*/
public int getMaxFPS() {
@@ -311,8 +351,10 @@ public class AxisCamera {
}
/**
* @return The configured resolution of the camera (not necessarily the same
* resolution as the most recent image, if it was changed recently.)
* Gets the configured resolution (not necessarily the same resolution as the most recent
* image, if it was changed recently).
*
* @return The configured resolution of the camera.
*/
public Resolution getResolution() {
synchronized (m_parametersLock) {
@@ -340,7 +382,9 @@ public class AxisCamera {
}
/**
* @return The configured compression level of the camera images
* Gets the configured compression level of the camera images.
*
* @return The configured compression level of the camera images.
*/
public int getCompression() {
synchronized (m_parametersLock) {
@@ -349,8 +393,8 @@ public class AxisCamera {
}
/**
* Write the rotation value to the camera. If you mount your camera upside
* down, use this to adjust the image for you.
* Write the motation value to the camera. If you mount your camera upside down, use this to
* adjust the image for you.
*
* @param rotation A value from the {@link Rotation} enum
*/
@@ -365,6 +409,8 @@ public class AxisCamera {
}
/**
* Gets the configured rotation mode of the camera.
*
* @return The configured rotation mode of the camera
*/
public Rotation getRotation() {
@@ -373,40 +419,6 @@ public class AxisCamera {
}
}
/**
* Thread spawned by AxisCamera constructor to receive images from cam
*/
private Thread m_captureThread = new Thread(new Runnable() {
@Override
public void run() {
int consecutiveErrors = 0;
// Loop on trying to setup the camera connection. This happens in a
// background
// thread so it shouldn't effect the operation of user programs.
while (!m_done) {
String requestString =
"GET /mjpg/video.mjpg HTTP/1.1\n" + "User-Agent: HTTPStreamClient\n"
+ "Connection: Keep-Alive\n" + "Cache-Control: no-cache\n"
+ "Authorization: Basic RlJDOkZSQw==\n\n";
try {
m_cameraSocket = AxisCamera.this.createCameraSocket(requestString);
AxisCamera.this.readImagesFromCamera();
consecutiveErrors = 0;
} catch (IOException e) {
consecutiveErrors++;
if (consecutiveErrors > 5) {
e.printStackTrace();
}
}
delay(0.5);
}
}
});
/**
* This function actually reads the images from the camera.
*/
@@ -453,16 +465,14 @@ public class AxisCamera {
}
/**
* Send a request to the camera to set all of the parameters. This is called
* in the capture thread between each frame. This strategy avoids making lots
* of redundant HTTP requests, accounts for failed initial requests, and
* avoids blocking calls in the main thread unless necessary.
* <p>
* This method does nothing if no parameters have been modified since it last
* completely successfully.
* Send a request to the camera to set all of the parameters. This is called in the capture thread
* between each frame. This strategy avoids making lots of redundant HTTP requests, accounts for
* failed initial requests, and avoids blocking calls in the main thread unless necessary.
*
* @return <code>true</code> if the stream should be restarted due to a
* parameter changing.
* <p>This method does nothing if no parameters have been modified since it last completely
* successfully.
*
* @return <code>true</code> if the stream should be restarted due to a parameter changing.
*/
private boolean writeParameters() {
if (m_parametersDirty) {
@@ -490,7 +500,7 @@ public class AxisCamera {
request += "Authorization: Basic RlJDOkZSQw==\n\n";
try {
Socket socket = this.createCameraSocket(request);
Socket socket = createCameraSocket(request);
socket.close();
m_parametersDirty = false;
@@ -501,7 +511,7 @@ public class AxisCamera {
} else {
return false;
}
} catch (IOException | NullPointerException e) {
} catch (IOException | NullPointerException ex) {
return false;
}
@@ -511,11 +521,10 @@ public class AxisCamera {
}
/**
* Create a socket connected to camera Used to create a connection for reading
* images and setting parameters
* Create a socket connected to camera Used to create a connection for reading images and setting
* parameters
*
* @param requestString The initial request string to send upon successful
* connection.
* @param requestString The initial request string to send upon successful connection.
* @return The created socket
*/
private Socket createCameraSocket(String requestString) throws IOException {

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