Simplify Sendable interface (#1864)

This removes the name and subsystem from individual objects, and instead
puts this data into a new singleton class, SendableRegistry.  Much of
LiveWindow has been refactored into SendableRegistry.

In C++, a new CRTP helper class, SendableHelper, has been added to provide
move and destruction functionality.

Shims for GetName, SetName, GetSubsystem, and SetSubsystem have been added
to Command and Subsystem (both old and new), and also to SendableHelper to
prevent code breakage.

This deprecates SendableBase in preparation for future removal.
This commit is contained in:
Peter Johnson
2019-09-14 15:22:54 -05:00
committed by GitHub
parent 1d8c4d016f
commit 471f375a38
216 changed files with 2448 additions and 1433 deletions

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -16,12 +16,13 @@ import edu.wpi.first.hal.HAL;
import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* ADXL345 I2C Accelerometer.
*/
@SuppressWarnings({"TypeName", "PMD.UnusedPrivateField"})
public class ADXL345_I2C extends SendableBase implements Accelerometer {
public class ADXL345_I2C implements Accelerometer, Sendable, AutoCloseable {
private static final byte kAddress = 0x1D;
private static final byte kPowerCtlRegister = 0x2D;
private static final byte kDataFormatRegister = 0x31;
@@ -89,12 +90,11 @@ public class ADXL345_I2C extends SendableBase implements Accelerometer {
setRange(range);
HAL.report(tResourceType.kResourceType_ADXL345, tInstances.kADXL345_I2C);
setName("ADXL345_I2C", port.value);
SendableRegistry.addLW(this, "ADXL345_I2C", port.value);
}
@Override
public void close() {
super.close();
m_i2c.close();
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -16,12 +16,13 @@ import edu.wpi.first.hal.HAL;
import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* ADXL345 SPI Accelerometer.
*/
@SuppressWarnings({"TypeName", "PMD.UnusedPrivateField"})
public class ADXL345_SPI extends SendableBase implements Accelerometer {
public class ADXL345_SPI implements Accelerometer, Sendable, AutoCloseable {
private static final int kPowerCtlRegister = 0x2D;
private static final int kDataFormatRegister = 0x31;
private static final int kDataRegister = 0x32;
@@ -75,12 +76,11 @@ public class ADXL345_SPI extends SendableBase implements Accelerometer {
public ADXL345_SPI(SPI.Port port, Range range) {
m_spi = new SPI(port);
init(range);
setName("ADXL345_SPI", port.value);
SendableRegistry.addLW(this, "ADXL345_SPI", port.value);
}
@Override
public void close() {
super.close();
m_spi.close();
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -15,6 +15,7 @@ import edu.wpi.first.hal.HAL;
import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* ADXL362 SPI Accelerometer.
@@ -22,7 +23,7 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
* <p>This class allows access to an Analog Devices ADXL362 3-axis accelerometer.
*/
@SuppressWarnings("PMD.UnusedPrivateField")
public class ADXL362 extends SendableBase implements Accelerometer {
public class ADXL362 implements Accelerometer, Sendable, AutoCloseable {
private static final byte kRegWrite = 0x0A;
private static final byte kRegRead = 0x0B;
@@ -108,12 +109,11 @@ public class ADXL362 extends SendableBase implements Accelerometer {
m_spi.write(transferBuffer, 3);
HAL.report(tResourceType.kResourceType_ADXL362, port.value);
setName("ADXL362", port.value);
SendableRegistry.addLW(this, "ADXL362", port.value);
}
@Override
public void close() {
super.close();
if (m_spi != null) {
m_spi.close();
m_spi = null;

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2015-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2015-2019 FIRST. 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. */
@@ -13,6 +13,7 @@ import java.nio.ByteOrder;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.interfaces.Gyro;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Use a rate gyro to return the robots heading relative to a starting position. The Gyro class
@@ -24,7 +25,7 @@ import edu.wpi.first.wpilibj.interfaces.Gyro;
* <p>This class is for the digital ADXRS450 gyro sensor that connects via SPI.
*/
@SuppressWarnings({"TypeName", "AbbreviationAsWordInName", "PMD.UnusedPrivateField"})
public class ADXRS450_Gyro extends GyroBase implements Gyro, PIDSource, Sendable {
public class ADXRS450_Gyro extends GyroBase implements Gyro, PIDSource, Sendable, AutoCloseable {
private static final double kSamplePeriod = 0.0005;
private static final double kCalibrationSampleTime = 5.0;
private static final double kDegreePerSecondPerLSB = 0.0125;
@@ -77,7 +78,7 @@ public class ADXRS450_Gyro extends GyroBase implements Gyro, PIDSource, Sendable
calibrate();
HAL.report(tResourceType.kResourceType_ADXRS450, port.value);
setName("ADXRS450_Gyro", port.value);
SendableRegistry.addLW(this, "ADXRS450_Gyro", port.value);
}
public boolean isConnected() {
@@ -142,7 +143,6 @@ public class ADXRS450_Gyro extends GyroBase implements Gyro, PIDSource, Sendable
*/
@Override
public void close() {
super.close();
if (m_spi != null) {
m_spi.close();
m_spi = null;

View File

@@ -10,6 +10,7 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
@@ -18,7 +19,7 @@ import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
* 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 SendableBase implements PIDSource {
public class AnalogAccelerometer implements PIDSource, Sendable, AutoCloseable {
private AnalogInput m_analogChannel;
private double m_voltsPerG = 1.0;
private double m_zeroGVoltage = 2.5;
@@ -31,7 +32,7 @@ public class AnalogAccelerometer extends SendableBase implements PIDSource {
private void initAccelerometer() {
HAL.report(tResourceType.kResourceType_Accelerometer,
m_analogChannel.getChannel());
setName("Accelerometer", m_analogChannel.getChannel());
SendableRegistry.addLW(this, "Accelerometer", m_analogChannel.getChannel());
}
/**
@@ -43,7 +44,7 @@ public class AnalogAccelerometer extends SendableBase implements PIDSource {
*/
public AnalogAccelerometer(final int channel) {
this(new AnalogInput(channel), true);
addChild(m_analogChannel);
SendableRegistry.addChild(this, m_analogChannel);
}
/**
@@ -70,7 +71,6 @@ public class AnalogAccelerometer extends SendableBase implements PIDSource {
*/
@Override
public void close() {
super.close();
if (m_analogChannel != null && m_allocatedChannel) {
m_analogChannel.close();
}

View File

@@ -11,6 +11,7 @@ import edu.wpi.first.hal.AnalogGyroJNI;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.interfaces.Gyro;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
@@ -23,7 +24,7 @@ import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
*
* <p>This class is for gyro sensors that connect to an analog input.
*/
public class AnalogGyro extends GyroBase implements Gyro, PIDSource, Sendable {
public class AnalogGyro extends GyroBase implements Gyro, PIDSource, Sendable, AutoCloseable {
private static final double kDefaultVoltsPerDegreePerSecond = 0.007;
protected AnalogInput m_analog;
private boolean m_channelAllocated;
@@ -41,7 +42,7 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, Sendable {
AnalogGyroJNI.setupAnalogGyro(m_gyroHandle);
HAL.report(tResourceType.kResourceType_Gyro, m_analog.getChannel());
setName("AnalogGyro", m_analog.getChannel());
SendableRegistry.addLW(this, "AnalogGyro", m_analog.getChannel());
}
@Override
@@ -58,7 +59,7 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, Sendable {
public AnalogGyro(int channel) {
this(new AnalogInput(channel));
m_channelAllocated = true;
addChild(m_analog);
SendableRegistry.addChild(this, m_analog);
}
/**
@@ -88,7 +89,7 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, Sendable {
public AnalogGyro(int channel, int center, double offset) {
this(new AnalogInput(channel), center, offset);
m_channelAllocated = true;
addChild(m_analog);
SendableRegistry.addChild(this, m_analog);
}
/**
@@ -120,7 +121,6 @@ public class AnalogGyro extends GyroBase implements Gyro, PIDSource, Sendable {
*/
@Override
public void close() {
super.close();
if (m_analog != null && m_channelAllocated) {
m_analog.close();
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -14,6 +14,7 @@ import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.sim.AnalogInSim;
import edu.wpi.first.hal.util.AllocationException;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Analog channel class.
@@ -27,7 +28,7 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
* 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 SendableBase implements PIDSource {
public class AnalogInput implements PIDSource, Sendable, AutoCloseable {
private static final int kAccumulatorSlot = 1;
int m_port; // explicit no modifier, private and package accessible.
private int m_channel;
@@ -48,12 +49,11 @@ public class AnalogInput extends SendableBase implements PIDSource {
m_port = AnalogJNI.initializeAnalogInputPort(portHandle);
HAL.report(tResourceType.kResourceType_AnalogChannel, channel);
setName("AnalogInput", channel);
SendableRegistry.addLW(this, "AnalogInput", channel);
}
@Override
public void close() {
super.close();
AnalogJNI.freeAnalogInputPort(m_port);
m_port = 0;
m_channel = 0;

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2014-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2014-2019 FIRST. 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. */
@@ -12,11 +12,12 @@ import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.sim.AnalogOutSim;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Analog output class.
*/
public class AnalogOutput extends SendableBase {
public class AnalogOutput implements Sendable, AutoCloseable {
private int m_port;
private int m_channel;
@@ -33,12 +34,11 @@ public class AnalogOutput extends SendableBase {
m_port = AnalogJNI.initializeAnalogOutputPort(portHandle);
HAL.report(tResourceType.kResourceType_AnalogOutput, channel);
setName("AnalogOutput", channel);
SendableRegistry.addLW(this, "AnalogOutput", channel);
}
@Override
public void close() {
super.close();
AnalogJNI.freeAnalogOutputPort(m_port);
m_port = 0;
m_channel = 0;

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -9,13 +9,14 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.interfaces.Potentiometer;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* 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.
*/
public class AnalogPotentiometer extends SendableBase implements Potentiometer {
public class AnalogPotentiometer implements Potentiometer, Sendable, AutoCloseable {
private AnalogInput m_analogInput;
private boolean m_initAnalogInput;
private double m_fullRange;
@@ -38,7 +39,7 @@ public class AnalogPotentiometer extends SendableBase implements Potentiometer {
public AnalogPotentiometer(final int channel, double fullRange, double offset) {
this(new AnalogInput(channel), fullRange, offset);
m_initAnalogInput = true;
addChild(m_analogInput);
SendableRegistry.addChild(this, m_analogInput);
}
/**
@@ -55,7 +56,7 @@ public class AnalogPotentiometer extends SendableBase implements Potentiometer {
* @param offset The offset to add to the scaled value for controlling the zero value
*/
public AnalogPotentiometer(final AnalogInput input, double fullRange, double offset) {
setName("AnalogPotentiometer", input.getChannel());
SendableRegistry.addLW(this, "AnalogPotentiometer", input.getChannel());
m_analogInput = input;
m_initAnalogInput = false;
@@ -156,7 +157,6 @@ public class AnalogPotentiometer extends SendableBase implements Potentiometer {
@Override
public void close() {
super.close();
if (m_initAnalogInput) {
m_analogInput.close();
m_analogInput = null;

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -16,12 +16,13 @@ import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.util.BoundaryException;
import edu.wpi.first.wpilibj.AnalogTriggerOutput.AnalogTriggerType;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Class for creating and configuring Analog Triggers.
*/
public class AnalogTrigger extends SendableBase {
public class AnalogTrigger implements Sendable, AutoCloseable {
/**
* Exceptions dealing with improper operation of the Analog trigger.
*/
@@ -53,7 +54,7 @@ public class AnalogTrigger extends SendableBase {
public AnalogTrigger(final int channel) {
this(new AnalogInput(channel));
m_ownsAnalog = true;
addChild(m_analogInput);
SendableRegistry.addChild(this, m_analogInput);
}
/**
@@ -72,12 +73,11 @@ public class AnalogTrigger extends SendableBase {
m_index = index.asIntBuffer().get(0);
HAL.report(tResourceType.kResourceType_AnalogTrigger, channel.getChannel());
setName("AnalogTrigger", channel.getChannel());
SendableRegistry.addLW(this, "AnalogTrigger", channel.getChannel());
}
@Override
public void close() {
super.close();
AnalogJNI.cleanAnalogTrigger(m_port);
m_port = 0;
if (m_ownsAnalog && m_analogInput != null) {

View File

@@ -40,7 +40,7 @@ import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
* the averaging engine may help with this, but rotational speeds of the sensor will then be
* limited.
*/
public class AnalogTriggerOutput extends DigitalSource {
public class AnalogTriggerOutput extends DigitalSource implements Sendable {
/**
* Exceptions dealing with improper operation of the Analog trigger output.
*/

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2014-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2014-2019 FIRST. 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. */
@@ -13,13 +13,14 @@ import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.sim.AccelerometerSim;
import edu.wpi.first.wpilibj.interfaces.Accelerometer;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Built-in accelerometer.
*
* <p>This class allows access to the roboRIO's internal accelerometer.
*/
public class BuiltInAccelerometer extends SendableBase implements Accelerometer {
public class BuiltInAccelerometer implements Accelerometer, Sendable {
/**
* Constructor.
*
@@ -28,7 +29,7 @@ public class BuiltInAccelerometer extends SendableBase implements Accelerometer
public BuiltInAccelerometer(Range range) {
setRange(range);
HAL.report(tResourceType.kResourceType_Accelerometer, 0, 0, "Built-in accelerometer");
setName("BuiltInAccel", 0);
SendableRegistry.addLW(this, "BuiltInAccel", 0);
}
/**

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2019 FIRST. 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. */
@@ -11,6 +11,7 @@ import edu.wpi.first.hal.CompressorJNI;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Class for operating a compressor connected to a PCM (Pneumatic Control Module). The PCM will
@@ -23,7 +24,7 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
* the safety provided by 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 SendableBase {
public class Compressor implements Sendable {
private int m_compressorHandle;
private byte m_module;
@@ -39,7 +40,7 @@ public class Compressor extends SendableBase {
m_compressorHandle = CompressorJNI.initializeCompressor((byte) module);
HAL.report(tResourceType.kResourceType_Compressor, module);
setName("Compressor", module);
SendableRegistry.addLW(this, "Compressor", module);
}
/**

View File

@@ -15,6 +15,7 @@ import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.AnalogTriggerOutput.AnalogTriggerType;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
import static java.util.Objects.requireNonNull;
@@ -29,7 +30,7 @@ import static java.util.Objects.requireNonNull;
* <p>All counters will immediately start counting - reset() them if you need them to be zeroed
* before use.
*/
public class Counter extends SendableBase implements CounterBase, PIDSource {
public class Counter implements CounterBase, PIDSource, Sendable, AutoCloseable {
/**
* Mode determines how and what the counter counts.
*/
@@ -86,7 +87,7 @@ public class Counter extends SendableBase implements CounterBase, PIDSource {
setMaxPeriod(.5);
HAL.report(tResourceType.kResourceType_Counter, m_index, mode.value);
setName("Counter", m_index);
SendableRegistry.addLW(this, "Counter", m_index);
}
/**
@@ -182,7 +183,6 @@ public class Counter extends SendableBase implements CounterBase, PIDSource {
@Override
public void close() {
super.close();
setUpdateWhenEmpty(true);
clearUpSource();
@@ -213,7 +213,7 @@ public class Counter extends SendableBase implements CounterBase, PIDSource {
public void setUpSource(int channel) {
setUpSource(new DigitalInput(channel));
m_allocatedUpSource = true;
addChild(m_upSource);
SendableRegistry.addChild(this, m_upSource);
}
/**
@@ -280,7 +280,7 @@ public class Counter extends SendableBase implements CounterBase, PIDSource {
public void setDownSource(int channel) {
setDownSource(new DigitalInput(channel));
m_allocatedDownSource = true;
addChild(m_downSource);
SendableRegistry.addChild(this, m_downSource);
}
/**

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -9,6 +9,7 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Digilent DMC 60 Speed Controller.
@@ -39,6 +40,6 @@ public class DMC60 extends PWMSpeedController {
setZeroLatch();
HAL.report(tResourceType.kResourceType_DigilentDMC60, getChannel());
setName("DMC60", getChannel());
SendableRegistry.setName(this, "DMC60", getChannel());
}
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2015-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2015-2019 FIRST. 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. */
@@ -14,13 +14,14 @@ import edu.wpi.first.hal.DigitalGlitchFilterJNI;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* 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 SendableBase {
public class DigitalGlitchFilter implements Sendable, AutoCloseable {
/**
* Configures the Digital Glitch Filter to its default settings.
*/
@@ -35,14 +36,13 @@ public class DigitalGlitchFilter extends SendableBase {
m_filterAllocated[index] = true;
HAL.report(tResourceType.kResourceType_DigitalGlitchFilter,
m_channelIndex, 0);
setName("DigitalGlitchFilter", index);
SendableRegistry.addLW(this, "DigitalGlitchFilter", index);
}
}
}
@Override
public void close() {
super.close();
if (m_channelIndex >= 0) {
synchronized (m_mutex) {
m_filterAllocated[m_channelIndex] = false;

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -11,6 +11,7 @@ import edu.wpi.first.hal.DIOJNI;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Class to read a digital input. This class will read digital inputs and return the current value
@@ -18,7 +19,7 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
* 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 {
public class DigitalInput extends DigitalSource implements Sendable, AutoCloseable {
private final int m_channel;
private int m_handle;
@@ -34,7 +35,7 @@ public class DigitalInput extends DigitalSource {
m_handle = DIOJNI.initializeDIOPort(HAL.getPort((byte) channel), true);
HAL.report(tResourceType.kResourceType_DigitalInput, channel);
setName("DigitalInput", channel);
SendableRegistry.addLW(this, "DigitalInput", channel);
}
@Override

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -11,12 +11,13 @@ import edu.wpi.first.hal.DIOJNI;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* 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 SendableBase {
public class DigitalOutput implements Sendable, AutoCloseable {
private static final int invalidPwmGenerator = 0;
private int m_pwmGenerator = invalidPwmGenerator;
@@ -37,12 +38,11 @@ public class DigitalOutput extends SendableBase {
m_handle = DIOJNI.initializeDIOPort(HAL.getPort((byte) channel), false);
HAL.report(tResourceType.kResourceType_DigitalOutput, channel);
setName("DigitalOutput", channel);
SendableRegistry.addLW(this, "DigitalOutput", channel);
}
@Override
public void close() {
super.close();
// Disable the pwm only if we have allocated it
if (m_pwmGenerator != invalidPwmGenerator) {
disablePWM();

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -12,6 +12,7 @@ import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.SolenoidJNI;
import edu.wpi.first.hal.util.UncleanStatusException;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* DoubleSolenoid class for running 2 channels of high voltage Digital Output on the PCM.
@@ -19,7 +20,7 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
* <p>The DoubleSolenoid class is typically used for pneumatics solenoids that have two positions
* controlled by two separate channels.
*/
public class DoubleSolenoid extends SolenoidBase {
public class DoubleSolenoid extends SolenoidBase implements Sendable, AutoCloseable {
/**
* Possible values for a DoubleSolenoid.
*/
@@ -80,12 +81,11 @@ public class DoubleSolenoid extends SolenoidBase {
m_moduleNumber);
HAL.report(tResourceType.kResourceType_Solenoid, reverseChannel,
m_moduleNumber);
setName("DoubleSolenoid", m_moduleNumber, forwardChannel);
SendableRegistry.addLW(this, "DoubleSolenoid", m_moduleNumber, forwardChannel);
}
@Override
public synchronized void close() {
super.close();
SolenoidJNI.freeSolenoidPort(m_forwardHandle);
SolenoidJNI.freeSolenoidPort(m_reverseHandle);
}

View File

@@ -12,6 +12,7 @@ import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.util.AllocationException;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
@@ -28,7 +29,7 @@ import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
* <p>All encoders will immediately start counting - reset() them if you need them to be zeroed
* before use.
*/
public class Encoder extends SendableBase implements CounterBase, PIDSource {
public class Encoder implements CounterBase, PIDSource, Sendable, AutoCloseable {
public enum IndexingType {
kResetWhileHigh(0), kResetWhileLow(1), kResetOnFallingEdge(2), kResetOnRisingEdge(3);
@@ -79,7 +80,7 @@ public class Encoder extends SendableBase implements CounterBase, PIDSource {
int fpgaIndex = getFPGAIndex();
HAL.report(tResourceType.kResourceType_Encoder, fpgaIndex, type.value);
setName("Encoder", fpgaIndex);
SendableRegistry.addLW(this, "Encoder", fpgaIndex);
}
/**
@@ -133,8 +134,8 @@ public class Encoder extends SendableBase implements CounterBase, PIDSource {
m_allocatedI = false;
m_aSource = new DigitalInput(channelA);
m_bSource = new DigitalInput(channelB);
addChild(m_aSource);
addChild(m_bSource);
SendableRegistry.addChild(this, m_aSource);
SendableRegistry.addChild(this, m_bSource);
initEncoder(reverseDirection, encodingType);
}
@@ -155,7 +156,7 @@ public class Encoder extends SendableBase implements CounterBase, PIDSource {
this(channelA, channelB, reverseDirection);
m_allocatedI = true;
m_indexSource = new DigitalInput(indexChannel);
addChild(m_indexSource);
SendableRegistry.addChild(this, m_indexSource);
setIndexSource(m_indexSource);
}
@@ -292,7 +293,6 @@ public class Encoder extends SendableBase implements CounterBase, PIDSource {
@Override
public void close() {
super.close();
if (m_aSource != null && m_allocatedA) {
m_aSource.close();
m_allocatedA = false;
@@ -544,7 +544,7 @@ public class Encoder extends SendableBase implements CounterBase, PIDSource {
}
m_indexSource = new DigitalInput(channel);
m_allocatedI = true;
addChild(m_indexSource);
SendableRegistry.addChild(this, m_indexSource);
setIndexSource(m_indexSource, type);
}

View File

@@ -10,6 +10,7 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Alias for counter class. Implement the gear tooth sensor supplied by FIRST. Currently there is no
@@ -59,7 +60,7 @@ public class GearTooth extends Counter {
} else {
HAL.report(tResourceType.kResourceType_GearTooth, channel, 0);
}
setName("GearTooth", channel);
SendableRegistry.setName(this, "GearTooth", channel);
}
/**
@@ -78,7 +79,7 @@ public class GearTooth extends Counter {
} else {
HAL.report(tResourceType.kResourceType_GearTooth, source.getChannel(), 0);
}
setName("GearTooth", source.getChannel());
SendableRegistry.setName(this, "GearTooth", source.getChannel());
}
/**

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -13,7 +13,7 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
/**
* GyroBase is the common base class for Gyro implementations such as AnalogGyro.
*/
public abstract class GyroBase extends SendableBase implements Gyro, PIDSource {
public abstract class GyroBase implements Gyro, PIDSource, Sendable {
private PIDSourceType m_pidSource = PIDSourceType.kDisplacement;
/**

View File

@@ -17,7 +17,7 @@ import edu.wpi.first.hal.util.AllocationException;
* Base for sensors to be used with interrupts.
*/
@SuppressWarnings("PMD.TooManyMethods")
public abstract class InterruptableSensorBase extends SendableBase {
public abstract class InterruptableSensorBase implements AutoCloseable {
@SuppressWarnings("JavadocMethod")
public enum WaitResult {
kTimeout(0x0), kRisingEdge(0x1), kFallingEdge(0x100), kBoth(0x101);
@@ -61,7 +61,6 @@ public abstract class InterruptableSensorBase extends SendableBase {
@Override
public void close() {
super.close();
if (m_interrupt != 0) {
cancelInterrupts();
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -9,6 +9,7 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Texas Instruments / Vex Robotics Jaguar Speed Controller as a PWM device.
@@ -37,6 +38,6 @@ public class Jaguar extends PWMSpeedController {
setZeroLatch();
HAL.report(tResourceType.kResourceType_Jaguar, getChannel());
setName("Jaguar", getChannel());
SendableRegistry.setName(this, "Jaguar", getChannel());
}
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2017-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2017-2019 FIRST. 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. */
@@ -10,6 +10,7 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Nidec Brushless Motor.
@@ -22,8 +23,6 @@ public class NidecBrushless extends MotorSafety implements SpeedController, Send
private volatile double m_speed;
private volatile boolean m_disabled;
private final SendableImpl m_sendableImpl;
/**
* Constructor.
*
@@ -33,81 +32,28 @@ public class NidecBrushless extends MotorSafety implements SpeedController, Send
* 0-9 are on-board, 10-25 are on the MXP port
*/
public NidecBrushless(final int pwmChannel, final int dioChannel) {
m_sendableImpl = new SendableImpl(true);
setSafetyEnabled(false);
// the dio controls the output (in PWM mode)
m_dio = new DigitalOutput(dioChannel);
addChild(m_dio);
SendableRegistry.addChild(this, m_dio);
m_dio.setPWMRate(15625);
m_dio.enablePWM(0.5);
// the pwm enables the controller
m_pwm = new PWM(pwmChannel);
addChild(m_pwm);
SendableRegistry.addChild(this, m_pwm);
HAL.report(tResourceType.kResourceType_NidecBrushless, pwmChannel);
setName("Nidec Brushless", pwmChannel);
SendableRegistry.addLW(this, "Nidec Brushless", pwmChannel);
}
@Override
public void close() {
m_sendableImpl.close();
m_dio.close();
m_pwm.close();
}
@Override
public final synchronized String getName() {
return m_sendableImpl.getName();
}
@Override
public final synchronized void setName(String name) {
m_sendableImpl.setName(name);
}
/**
* Sets the name of the sensor with a channel number.
*
* @param moduleType A string that defines the module name in the label for the value
* @param channel The channel number the device is plugged into
*/
protected final void setName(String moduleType, int channel) {
m_sendableImpl.setName(moduleType, channel);
}
/**
* Sets the name of the sensor with a module and channel number.
*
* @param moduleType A string that defines the module name in the label for the value
* @param moduleNumber The number of the particular module type
* @param channel The channel number the device is plugged into (usually PWM)
*/
protected final void setName(String moduleType, int moduleNumber, int channel) {
m_sendableImpl.setName(moduleType, moduleNumber, channel);
}
@Override
public final synchronized String getSubsystem() {
return m_sendableImpl.getSubsystem();
}
@Override
public final synchronized void setSubsystem(String subsystem) {
m_sendableImpl.setSubsystem(subsystem);
}
/**
* Add a child component.
*
* @param child child component
*/
protected final void addChild(Object child) {
m_sendableImpl.addChild(child);
}
/**
* Set the PWM value.
*

View File

@@ -13,6 +13,7 @@ import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.util.BoundaryException;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
@@ -27,7 +28,7 @@ import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
* given set of PID constants.
*/
@SuppressWarnings("PMD.TooManyFields")
public class PIDBase extends SendableBase implements PIDInterface, PIDOutput {
public class PIDBase implements PIDInterface, PIDOutput, Sendable {
public static final double kDefaultPeriod = 0.05;
private static int instances;
@@ -154,7 +155,6 @@ public class PIDBase extends SendableBase implements PIDInterface, PIDOutput {
@SuppressWarnings("ParameterName")
public PIDBase(double Kp, double Ki, double Kd, double Kf, PIDSource source,
PIDOutput output) {
super(false);
requireNonNullParam(source, "PIDSource", "PIDBase");
requireNonNullParam(output, "output", "PIDBase");
@@ -174,7 +174,7 @@ public class PIDBase extends SendableBase implements PIDInterface, PIDOutput {
instances++;
HAL.report(tResourceType.kResourceType_PIDController, instances);
m_tolerance = new NullTolerance();
setName("PIDController", instances);
SendableRegistry.add(this, "PIDController", instances);
}
/**

View File

@@ -22,7 +22,7 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
* @deprecated Use {@link edu.wpi.first.wpilibj.controller.PIDController} instead.
*/
@Deprecated(since = "2020", forRemoval = true)
public class PIDController extends PIDBase implements Controller {
public class PIDController extends PIDBase implements Controller, AutoCloseable {
Notifier m_controlLoop = new Notifier(this::calculate);
/**
@@ -97,7 +97,6 @@ public class PIDController extends PIDBase implements Controller {
@Override
public void close() {
super.close();
m_controlLoop.close();
m_thisMutex.lock();
try {

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -12,6 +12,7 @@ import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.PWMConfigDataResult;
import edu.wpi.first.hal.PWMJNI;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Class implements the PWM generation in the FPGA.
@@ -47,16 +48,12 @@ public class PWM extends MotorSafety implements Sendable, AutoCloseable {
private final int m_channel;
private int m_handle;
private final SendableImpl m_sendableImpl;
/**
* Allocate a PWM given a channel.
*
* @param channel The PWM channel number. 0-9 are on-board, 10-19 are on the MXP port
*/
public PWM(final int channel) {
m_sendableImpl = new SendableImpl(true);
SensorUtil.checkPWMChannel(channel);
m_channel = channel;
@@ -67,7 +64,7 @@ public class PWM extends MotorSafety implements Sendable, AutoCloseable {
PWMJNI.setPWMEliminateDeadband(m_handle, false);
HAL.report(tResourceType.kResourceType_PWM, channel);
setName("PWM", channel);
SendableRegistry.addLW(this, "PWM", channel);
setSafetyEnabled(false);
}
@@ -77,8 +74,6 @@ public class PWM extends MotorSafety implements Sendable, AutoCloseable {
*/
@Override
public void close() {
m_sendableImpl.close();
if (m_handle == 0) {
return;
}
@@ -87,56 +82,6 @@ public class PWM extends MotorSafety implements Sendable, AutoCloseable {
m_handle = 0;
}
@Override
public final synchronized String getName() {
return m_sendableImpl.getName();
}
@Override
public final synchronized void setName(String name) {
m_sendableImpl.setName(name);
}
/**
* Sets the name of the sensor with a channel number.
*
* @param moduleType A string that defines the module name in the label for the value
* @param channel The channel number the device is plugged into
*/
protected final void setName(String moduleType, int channel) {
m_sendableImpl.setName(moduleType, channel);
}
/**
* Sets the name of the sensor with a module and channel number.
*
* @param moduleType A string that defines the module name in the label for the value
* @param moduleNumber The number of the particular module type
* @param channel The channel number the device is plugged into (usually PWM)
*/
protected final void setName(String moduleType, int moduleNumber, int channel) {
m_sendableImpl.setName(moduleType, moduleNumber, channel);
}
@Override
public final synchronized String getSubsystem() {
return m_sendableImpl.getSubsystem();
}
@Override
public final synchronized void setSubsystem(String subsystem) {
m_sendableImpl.setSubsystem(subsystem);
}
/**
* Add a child component.
*
* @param child child component
*/
protected final void addChild(Object child) {
m_sendableImpl.addChild(child);
}
@Override
public void stopMotor() {
setDisabled();

View File

@@ -9,6 +9,7 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* REV Robotics SparkMax Speed Controller.
@@ -36,6 +37,6 @@ public class PWMSparkMax extends PWMSpeedController {
setZeroLatch();
HAL.report(tResourceType.kResourceType_RevSparkMaxPWM, getChannel());
setName("PWMSparkMax", getChannel());
SendableRegistry.setName(this, "PWMSparkMax", getChannel());
}
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -9,6 +9,7 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Cross the Road Electronics (CTRE) Talon SRX Speed Controller with PWM control.
@@ -40,6 +41,6 @@ public class PWMTalonSRX extends PWMSpeedController {
setZeroLatch();
HAL.report(tResourceType.kResourceType_PWMTalonSRX, getChannel());
setName("PWMTalonSRX", getChannel());
SendableRegistry.setName(this, "PWMTalonSRX", getChannel());
}
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -9,6 +9,7 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Cross the Road Electronics (CTRE) Victor SPX Speed Controller with PWM control.
@@ -40,6 +41,6 @@ public class PWMVictorSPX extends PWMSpeedController {
setZeroLatch();
HAL.report(tResourceType.kResourceType_PWMVictorSPX, getChannel());
setName("PWMVictorSPX", getChannel());
SendableRegistry.setName(this, "PWMVictorSPX", getChannel());
}
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2014-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2014-2019 FIRST. 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. */
@@ -11,12 +11,13 @@ import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.PDPJNI;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Class for getting voltage, current, temperature, power and energy from the Power Distribution
* Panel over CAN.
*/
public class PowerDistributionPanel extends SendableBase {
public class PowerDistributionPanel implements Sendable {
private final int m_handle;
/**
@@ -29,7 +30,7 @@ public class PowerDistributionPanel extends SendableBase {
m_handle = PDPJNI.initializePDP(module);
HAL.report(tResourceType.kResourceType_PDP, module);
setName("PowerDistributionPanel", module);
SendableRegistry.addLW(this, "PowerDistributionPanel", module);
}
/**

View File

@@ -15,6 +15,7 @@ import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.RelayJNI;
import edu.wpi.first.hal.util.UncleanStatusException;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
@@ -93,8 +94,6 @@ public class Relay extends MotorSafety implements Sendable, AutoCloseable {
private Direction m_direction;
private final SendableImpl m_sendableImpl;
/**
* 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
@@ -115,7 +114,7 @@ public class Relay extends MotorSafety implements Sendable, AutoCloseable {
setSafetyEnabled(false);
setName("Relay", m_channel);
SendableRegistry.addLW(this, "Relay", m_channel);
}
/**
@@ -125,8 +124,6 @@ public class Relay extends MotorSafety implements Sendable, AutoCloseable {
* @param direction The direction that the Relay object will control.
*/
public Relay(final int channel, Direction direction) {
m_sendableImpl = new SendableImpl(true);
m_channel = channel;
m_direction = requireNonNullParam(direction, "direction", "Relay");
initRelay();
@@ -144,7 +141,6 @@ public class Relay extends MotorSafety implements Sendable, AutoCloseable {
@Override
public void close() {
m_sendableImpl.close();
freeRelay();
}
@@ -167,56 +163,6 @@ public class Relay extends MotorSafety implements Sendable, AutoCloseable {
m_reverseHandle = 0;
}
@Override
public final synchronized String getName() {
return m_sendableImpl.getName();
}
@Override
public final synchronized void setName(String name) {
m_sendableImpl.setName(name);
}
/**
* Sets the name of the sensor with a channel number.
*
* @param moduleType A string that defines the module name in the label for the value
* @param channel The channel number the device is plugged into
*/
protected final void setName(String moduleType, int channel) {
m_sendableImpl.setName(moduleType, channel);
}
/**
* Sets the name of the sensor with a module and channel number.
*
* @param moduleType A string that defines the module name in the label for the value
* @param moduleNumber The number of the particular module type
* @param channel The channel number the device is plugged into (usually PWM)
*/
protected final void setName(String moduleType, int moduleNumber, int channel) {
m_sendableImpl.setName(moduleType, moduleNumber, channel);
}
@Override
public final synchronized String getSubsystem() {
return m_sendableImpl.getSubsystem();
}
@Override
public final synchronized void setSubsystem(String subsystem) {
m_sendableImpl.setSubsystem(subsystem);
}
/**
* Add a child component.
*
* @param child child component
*/
protected final void addChild(Object child) {
m_sendableImpl.addChild(child);
}
/**
* Set the relay state.
*

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -9,6 +9,7 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Mindsensors SD540 Speed Controller.
@@ -34,7 +35,7 @@ public class SD540 extends PWMSpeedController {
setZeroLatch();
HAL.report(tResourceType.kResourceType_MindsensorsSD540, getChannel());
setName("SD540", getChannel());
SendableRegistry.setName(this, "SD540", getChannel());
}
/**

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2019 FIRST. 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. */
@@ -8,6 +8,7 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
@@ -18,40 +19,93 @@ public interface Sendable {
* Gets the name of this {@link Sendable} object.
*
* @return Name
* @deprecated Use SendableRegistry.getName()
*/
String getName();
@Deprecated(since = "2020", forRemoval = true)
default String getName() {
return SendableRegistry.getName(this);
}
/**
* Sets the name of this {@link Sendable} object.
*
* @param name name
* @deprecated Use SendableRegistry.setName()
*/
void setName(String name);
@Deprecated(since = "2020", forRemoval = true)
default void setName(String name) {
SendableRegistry.setName(this, name);
}
/**
* Sets both the subsystem name and device name of this {@link Sendable} object.
*
* @param subsystem subsystem name
* @param name device name
* @deprecated Use SendableRegistry.setName()
*/
@Deprecated(since = "2020", forRemoval = true)
default void setName(String subsystem, String name) {
setSubsystem(subsystem);
setName(name);
SendableRegistry.setName(this, subsystem, name);
}
/**
* Sets the name of the sensor with a channel number.
*
* @param moduleType A string that defines the module name in the label for the value
* @param channel The channel number the device is plugged into
* @deprecated Use SendableRegistry.setName()
*/
@Deprecated(since = "2020", forRemoval = true)
default void setName(String moduleType, int channel) {
SendableRegistry.setName(this, moduleType, channel);
}
/**
* Sets the name of the sensor with a module and channel number.
*
* @param moduleType A string that defines the module name in the label for the value
* @param moduleNumber The number of the particular module type
* @param channel The channel number the device is plugged into (usually PWM)
* @deprecated Use SendableRegistry.setName()
*/
@Deprecated(since = "2020", forRemoval = true)
default void setName(String moduleType, int moduleNumber, int channel) {
SendableRegistry.setName(this, moduleType, moduleNumber, channel);
}
/**
* Gets the subsystem name of this {@link Sendable} object.
*
* @return Subsystem name
* @deprecated Use SendableRegistry.getSubsystem()
*/
String getSubsystem();
@Deprecated(since = "2020", forRemoval = true)
default String getSubsystem() {
return SendableRegistry.getSubsystem(this);
}
/**
* Sets the subsystem name of this {@link Sendable} object.
*
* @param subsystem subsystem name
* @deprecated Use SendableRegistry.setSubsystem()
*/
void setSubsystem(String subsystem);
@Deprecated(since = "2020", forRemoval = true)
default void setSubsystem(String subsystem) {
SendableRegistry.setSubsystem(this, subsystem);
}
/**
* Add a child component.
*
* @param child child component
* @deprecated Use SendableRegistry.addChild()
*/
@Deprecated(since = "2020", forRemoval = true)
default void addChild(Object child) {
SendableRegistry.addChild(this, child);
}
/**
* Initializes this {@link Sendable} object.

View File

@@ -7,16 +7,15 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Base class for all sensors. Stores most recent status information as well as containing utility
* functions for checking channels and error processing.
* @deprecated Use Sendable and SendableRegistry
*/
@Deprecated(since = "2020", forRemoval = true)
public abstract class SendableBase implements Sendable, AutoCloseable {
private String m_name = "";
private String m_subsystem = "Ungrouped";
/**
* Creates an instance of the sensor base.
*/
@@ -31,67 +30,12 @@ public abstract class SendableBase implements Sendable, AutoCloseable {
*/
public SendableBase(boolean addLiveWindow) {
if (addLiveWindow) {
LiveWindow.add(this);
SendableRegistry.addLW(this, "");
} else {
SendableRegistry.add(this, "");
}
}
@Deprecated
public void free() {
close();
}
@Override
public void close() {
LiveWindow.remove(this);
}
@Override
public final String getName() {
return m_name;
}
@Override
public final void setName(String name) {
m_name = name;
}
/**
* Sets the name of the sensor with a channel number.
*
* @param moduleType A string that defines the module name in the label for the value
* @param channel The channel number the device is plugged into
*/
protected final void setName(String moduleType, int channel) {
setName(moduleType + "[" + channel + "]");
}
/**
* Sets the name of the sensor with a module and channel number.
*
* @param moduleType A string that defines the module name in the label for the value
* @param moduleNumber The number of the particular module type
* @param channel The channel number the device is plugged into (usually PWM)
*/
protected final void setName(String moduleType, int moduleNumber, int channel) {
setName(moduleType + "[" + moduleNumber + "," + channel + "]");
}
@Override
public final String getSubsystem() {
return m_subsystem;
}
@Override
public final void setSubsystem(String subsystem) {
m_subsystem = subsystem;
}
/**
* Add a child component.
*
* @param child child component
*/
protected final void addChild(Object child) {
LiveWindow.addChild(this, child);
}
public void close() {}
}

View File

@@ -1,101 +0,0 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2018 FIRST. 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;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
/**
* The base interface for objects that can be sent over the network through network tables.
*/
public class SendableImpl implements Sendable, AutoCloseable {
private String m_name = "";
private String m_subsystem = "Ungrouped";
/**
* Creates an instance of the sensor base.
*/
public SendableImpl() {
this(true);
}
/**
* Creates an instance of the sensor base.
*
* @param addLiveWindow if true, add this Sendable to LiveWindow
*/
public SendableImpl(boolean addLiveWindow) {
if (addLiveWindow) {
LiveWindow.add(this);
}
}
@Deprecated
public void free() {
close();
}
@Override
public void close() {
LiveWindow.remove(this);
}
@Override
public synchronized String getName() {
return m_name;
}
@Override
public synchronized void setName(String name) {
m_name = name;
}
/**
* Sets the name of the sensor with a channel number.
*
* @param moduleType A string that defines the module name in the label for the value
* @param channel The channel number the device is plugged into
*/
public void setName(String moduleType, int channel) {
setName(moduleType + "[" + channel + "]");
}
/**
* Sets the name of the sensor with a module and channel number.
*
* @param moduleType A string that defines the module name in the label for the value
* @param moduleNumber The number of the particular module type
* @param channel The channel number the device is plugged into (usually PWM)
*/
public void setName(String moduleType, int moduleNumber, int channel) {
setName(moduleType + "[" + moduleNumber + "," + channel + "]");
}
@Override
public synchronized String getSubsystem() {
return m_subsystem;
}
@Override
public synchronized void setSubsystem(String subsystem) {
m_subsystem = subsystem;
}
@Override
public void initSendable(SendableBuilder builder) {
}
/**
* Add a child component.
*
* @param child child component
*/
public void addChild(Object child) {
LiveWindow.addChild(this, child);
}
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -10,6 +10,7 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Standard hobby style servo.
@@ -39,7 +40,7 @@ public class Servo extends PWM {
setPeriodMultiplier(PeriodMultiplier.k4X);
HAL.report(tResourceType.kResourceType_Servo, getChannel());
setName("Servo", getChannel());
SendableRegistry.setName(this, "Servo", getChannel());
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -11,6 +11,7 @@ import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.hal.SolenoidJNI;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Solenoid class for running high voltage Digital Output on the PCM.
@@ -18,7 +19,7 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
* <p>The Solenoid class is typically used for pneumatic solenoids, but could be used for any
* device within the current spec of the PCM.
*/
public class Solenoid extends SolenoidBase {
public class Solenoid extends SolenoidBase implements Sendable, AutoCloseable {
private final int m_channel; // The channel to control.
private int m_solenoidHandle;
@@ -48,12 +49,11 @@ public class Solenoid extends SolenoidBase {
m_solenoidHandle = SolenoidJNI.initializeSolenoidPort(portHandle);
HAL.report(tResourceType.kResourceType_Solenoid, m_channel, m_moduleNumber);
setName("Solenoid", m_moduleNumber, m_channel);
SendableRegistry.addLW(this, "Solenoid", m_moduleNumber, m_channel);
}
@Override
public void close() {
super.close();
SolenoidJNI.freeSolenoidPort(m_solenoidHandle);
m_solenoidHandle = 0;
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -13,7 +13,7 @@ import edu.wpi.first.hal.SolenoidJNI;
* SolenoidBase class is the common base class for the {@link Solenoid} and {@link DoubleSolenoid}
* classes.
*/
public abstract class SolenoidBase extends SendableBase {
public class SolenoidBase {
protected final int m_moduleNumber; // The number of the solenoid module being used.
/**
@@ -21,7 +21,7 @@ public abstract class SolenoidBase extends SendableBase {
*
* @param moduleNumber The PCM CAN ID
*/
public SolenoidBase(final int moduleNumber) {
protected SolenoidBase(final int moduleNumber) {
m_moduleNumber = moduleNumber;
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -9,6 +9,7 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* REV Robotics SPARK Speed Controller.
@@ -34,7 +35,7 @@ public class Spark extends PWMSpeedController {
setZeroLatch();
HAL.report(tResourceType.kResourceType_RevSPARK, getChannel());
setName("Spark", getChannel());
SendableRegistry.setName(this, "Spark", getChannel());
}
/**

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2016-2019 FIRST. 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. */
@@ -8,11 +8,12 @@
package edu.wpi.first.wpilibj;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Allows multiple {@link SpeedController} objects to be linked together.
*/
public class SpeedControllerGroup extends SendableBase implements SpeedController {
public class SpeedControllerGroup implements SpeedController, Sendable {
private boolean m_isInverted;
private final SpeedController[] m_speedControllers;
private static int instances;
@@ -27,13 +28,13 @@ public class SpeedControllerGroup extends SendableBase implements SpeedControlle
SpeedController... speedControllers) {
m_speedControllers = new SpeedController[speedControllers.length + 1];
m_speedControllers[0] = speedController;
addChild(speedController);
SendableRegistry.addChild(this, speedController);
for (int i = 0; i < speedControllers.length; i++) {
m_speedControllers[i + 1] = speedControllers[i];
addChild(speedControllers[i]);
SendableRegistry.addChild(this, speedControllers[i]);
}
instances++;
setName("SpeedControllerGroup", instances);
SendableRegistry.addLW(this, "tSpeedControllerGroup", instances);
}
@Override

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -9,6 +9,7 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* Cross the Road Electronics (CTRE) Talon and Talon SR Speed Controller.
@@ -39,6 +40,6 @@ public class Talon extends PWMSpeedController {
setZeroLatch();
HAL.report(tResourceType.kResourceType_Talon, getChannel());
setName("Talon", getChannel());
SendableRegistry.setName(this, "Talon", getChannel());
}
}

View File

@@ -13,6 +13,7 @@ import java.util.List;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import static java.util.Objects.requireNonNull;
@@ -25,7 +26,7 @@ import static java.util.Objects.requireNonNull;
* echo is received. The time that the line is high determines the round trip distance (time of
* flight).
*/
public class Ultrasonic extends SendableBase implements PIDSource {
public class Ultrasonic implements PIDSource, Sendable, AutoCloseable {
/**
* The units to return when PIDGet is called.
*/
@@ -101,7 +102,7 @@ public class Ultrasonic extends SendableBase implements PIDSource {
m_sensors.add(this);
m_counter = new Counter(m_echoChannel); // set up counter for this
addChild(m_counter);
SendableRegistry.addChild(this, m_counter);
// sensor
m_counter.setMaxPeriod(1.0);
m_counter.setSemiPeriodMode(true);
@@ -111,7 +112,7 @@ public class Ultrasonic extends SendableBase implements PIDSource {
m_instances++;
HAL.report(tResourceType.kResourceType_Ultrasonic, m_instances);
setName("Ultrasonic", m_echoChannel.getChannel());
SendableRegistry.addLW(this, "Ultrasonic", m_echoChannel.getChannel());
}
/**
@@ -128,8 +129,8 @@ public class Ultrasonic extends SendableBase implements PIDSource {
public Ultrasonic(final int pingChannel, final int echoChannel, Unit units) {
m_pingChannel = new DigitalOutput(pingChannel);
m_echoChannel = new DigitalInput(echoChannel);
addChild(m_pingChannel);
addChild(m_echoChannel);
SendableRegistry.addChild(this, m_pingChannel);
SendableRegistry.addChild(this, m_echoChannel);
m_allocatedChannels = true;
m_units = units;
initialize();
@@ -191,7 +192,6 @@ public class Ultrasonic extends SendableBase implements PIDSource {
*/
@Override
public synchronized void close() {
super.close();
final boolean wasAutomaticMode = m_automaticEnabled;
setAutomaticMode(false);
if (m_allocatedChannels) {

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -9,6 +9,7 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* VEX Robotics Victor 888 Speed Controller The Vex Robotics Victor 884 Speed Controller can also
@@ -41,6 +42,6 @@ public class Victor extends PWMSpeedController {
setZeroLatch();
HAL.report(tResourceType.kResourceType_Victor, getChannel());
setName("Victor", getChannel());
SendableRegistry.setName(this, "Victor", getChannel());
}
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -9,6 +9,7 @@ package edu.wpi.first.wpilibj;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* VEX Robotics Victor SP Speed Controller.
@@ -39,6 +40,6 @@ public class VictorSP extends PWMSpeedController {
setZeroLatch();
HAL.report(tResourceType.kResourceType_VictorSP, getChannel());
setName("VictorSP", getChannel());
SendableRegistry.setName(this, "VictorSP", getChannel());
}
}

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -7,7 +7,7 @@
package edu.wpi.first.wpilibj.buttons;
import edu.wpi.first.wpilibj.SendableBase;
import edu.wpi.first.wpilibj.Sendable;
import edu.wpi.first.wpilibj.command.Command;
import edu.wpi.first.wpilibj.command.Scheduler;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
@@ -23,7 +23,7 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
* certain sensor input). For this, they only have to write the {@link Trigger#get()} method to get
* the full functionality of the Trigger class.
*/
public abstract class Trigger extends SendableBase {
public abstract class Trigger implements Sendable {
private volatile boolean m_sendablePressed;
/**

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -10,9 +10,10 @@ package edu.wpi.first.wpilibj.command;
import java.util.Enumeration;
import edu.wpi.first.wpilibj.RobotState;
import edu.wpi.first.wpilibj.SendableBase;
import edu.wpi.first.wpilibj.Sendable;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* The Command class is at the very core of the entire command framework. Every command can be
@@ -40,7 +41,7 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
* @see IllegalUseOfCommandException
*/
@SuppressWarnings("PMD.TooManyMethods")
public abstract class Command extends SendableBase {
public abstract class Command implements Sendable {
/**
* The time since this command was initialized.
*/
@@ -100,9 +101,8 @@ public abstract class Command extends SendableBase {
* Creates a new command. The name of this command will be set to its class name.
*/
public Command() {
super(false);
String name = getClass().getName();
setName(name.substring(name.lastIndexOf('.') + 1));
SendableRegistry.add(this, name.substring(name.lastIndexOf('.') + 1));
}
/**
@@ -112,11 +112,10 @@ public abstract class Command extends SendableBase {
* @throws IllegalArgumentException if name is null
*/
public Command(String name) {
super(false);
if (name == null) {
throw new IllegalArgumentException("Name must not be null.");
}
setName(name);
SendableRegistry.add(this, name);
}
/**
@@ -596,6 +595,46 @@ public abstract class Command extends SendableBase {
return m_runWhenDisabled;
}
/**
* Gets the name of this Command.
*
* @return Name
*/
@Override
public String getName() {
return SendableRegistry.getName(this);
}
/**
* Sets the name of this Command.
*
* @param name name
*/
@Override
public void setName(String name) {
SendableRegistry.setName(this, name);
}
/**
* Gets the subsystem name of this Command.
*
* @return Subsystem name
*/
@Override
public String getSubsystem() {
return SendableRegistry.getSubsystem(this);
}
/**
* Sets the subsystem name of this Command.
*
* @param subsystem subsystem name
*/
@Override
public void setSubsystem(String subsystem) {
SendableRegistry.setSubsystem(this, subsystem);
}
/**
* The string representation for a {@link Command} is by default its name.
*

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -15,9 +15,10 @@ import edu.wpi.first.hal.FRCNetComm.tInstances;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.wpilibj.SendableBase;
import edu.wpi.first.wpilibj.Sendable;
import edu.wpi.first.wpilibj.buttons.Trigger.ButtonScheduler;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* The {@link Scheduler} is a singleton which holds the top-level running commands. It is in charge
@@ -31,7 +32,7 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
*
* @see Command
*/
public final class Scheduler extends SendableBase {
public final class Scheduler implements Sendable {
/**
* The Singleton Instance.
*/
@@ -95,7 +96,7 @@ public final class Scheduler extends SendableBase {
*/
private Scheduler() {
HAL.report(tResourceType.kResourceType_Command, tInstances.kCommand_Scheduler);
setName("Scheduler");
SendableRegistry.addLW(this, "Scheduler");
}
/**

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2008-2019 FIRST. 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. */
@@ -10,9 +10,8 @@ package edu.wpi.first.wpilibj.command;
import java.util.Collections;
import edu.wpi.first.wpilibj.Sendable;
import edu.wpi.first.wpilibj.SendableBase;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* This class defines a major component of the robot.
@@ -28,7 +27,7 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
*
* @see Command
*/
public abstract class Subsystem extends SendableBase {
public abstract class Subsystem implements Sendable {
/**
* Whether or not getDefaultCommand() was called.
*/
@@ -50,7 +49,7 @@ public abstract class Subsystem extends SendableBase {
* @param name the name of the subsystem
*/
public Subsystem(String name) {
setName(name, name);
SendableRegistry.addLW(this, name, name);
Scheduler.getInstance().registerSubsystem(this);
}
@@ -60,7 +59,7 @@ public abstract class Subsystem extends SendableBase {
public Subsystem() {
String name = getClass().getName();
name = name.substring(name.lastIndexOf('.') + 1);
setName(name, name);
SendableRegistry.addLW(this, name, name);
Scheduler.getInstance().registerSubsystem(this);
m_currentCommandChanged = true;
}
@@ -179,8 +178,8 @@ public abstract class Subsystem extends SendableBase {
* @param child sendable
*/
public void addChild(String name, Sendable child) {
child.setName(getSubsystem(), name);
LiveWindow.add(child);
SendableRegistry.addLW(child, getSubsystem(), name);
SendableRegistry.addChild(this, child);
}
/**
@@ -189,8 +188,49 @@ public abstract class Subsystem extends SendableBase {
* @param child sendable
*/
public void addChild(Sendable child) {
child.setSubsystem(getSubsystem());
LiveWindow.add(child);
SendableRegistry.setSubsystem(child, getSubsystem());
SendableRegistry.enableLiveWindow(child);
SendableRegistry.addChild(this, child);
}
/**
* Gets the name of this Subsystem.
*
* @return Name
*/
@Override
public String getName() {
return SendableRegistry.getName(this);
}
/**
* Sets the name of this Subsystem.
*
* @param name name
*/
@Override
public void setName(String name) {
SendableRegistry.setName(this, name);
}
/**
* Gets the subsystem name of this Subsystem.
*
* @return Subsystem name
*/
@Override
public String getSubsystem() {
return SendableRegistry.getSubsystem(this);
}
/**
* Sets the subsystem name of this Subsystem.
*
* @param subsystem subsystem name
*/
@Override
public void setSubsystem(String subsystem) {
SendableRegistry.setSubsystem(this, subsystem);
}
@Override

View File

@@ -9,15 +9,16 @@ package edu.wpi.first.wpilibj.controller;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.SendableBase;
import edu.wpi.first.wpilibj.Sendable;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import edu.wpi.first.wpiutil.math.MathUtils;
/**
* Implements a PID control loop.
*/
@SuppressWarnings("PMD.TooManyFields")
public class PIDController extends SendableBase {
public class PIDController implements Sendable {
private static int instances;
// Factor for "proportional" control
@@ -97,7 +98,7 @@ public class PIDController extends SendableBase {
m_period = period;
instances++;
setName("PIDController", instances);
SendableRegistry.addLW(this, "PIDController", instances);
HAL.report(tResourceType.kResourceType_PIDController, instances);
}

View File

@@ -7,7 +7,7 @@
package edu.wpi.first.wpilibj.controller;
import edu.wpi.first.wpilibj.SendableBase;
import edu.wpi.first.wpilibj.Sendable;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.trajectory.TrapezoidProfile;
@@ -16,7 +16,7 @@ import edu.wpi.first.wpilibj.trajectory.TrapezoidProfile;
* profile.
*/
@SuppressWarnings("PMD.TooManyMethods")
public class ProfiledPIDController extends SendableBase {
public class ProfiledPIDController implements Sendable {
private PIDController m_controller;
private TrapezoidProfile.State m_goal = new TrapezoidProfile.State();
private TrapezoidProfile.State m_setpoint = new TrapezoidProfile.State();

View File

@@ -12,9 +12,11 @@ import java.util.StringJoiner;
import edu.wpi.first.hal.FRCNetComm.tInstances;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.Sendable;
import edu.wpi.first.wpilibj.SpeedController;
import edu.wpi.first.wpilibj.SpeedControllerGroup;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import edu.wpi.first.wpiutil.math.MathUtils;
/**
@@ -94,7 +96,7 @@ import edu.wpi.first.wpiutil.math.MathUtils;
* {@link edu.wpi.first.wpilibj.RobotDrive#drive(double, double)} with the addition of a quick turn
* mode. However, it is not designed to give exactly the same response.
*/
public class DifferentialDrive extends RobotDriveBase {
public class DifferentialDrive extends RobotDriveBase implements Sendable {
public static final double kDefaultQuickStopThreshold = 0.2;
public static final double kDefaultQuickStopAlpha = 0.1;
@@ -119,10 +121,10 @@ public class DifferentialDrive extends RobotDriveBase {
verify(leftMotor, rightMotor);
m_leftMotor = leftMotor;
m_rightMotor = rightMotor;
addChild(m_leftMotor);
addChild(m_rightMotor);
SendableRegistry.addChild(this, m_leftMotor);
SendableRegistry.addChild(this, m_rightMotor);
instances++;
setName("DifferentialDrive", instances);
SendableRegistry.addLW(this, "DifferentialDrive", instances);
}
/**

View File

@@ -12,8 +12,10 @@ import java.util.StringJoiner;
import edu.wpi.first.hal.FRCNetComm.tInstances;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.Sendable;
import edu.wpi.first.wpilibj.SpeedController;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import edu.wpi.first.wpiutil.math.MathUtils;
/**
@@ -40,7 +42,7 @@ import edu.wpi.first.wpiutil.math.MathUtils;
* points down. Rotations follow the right-hand rule, so clockwise rotation around the Z axis is
* positive.
*/
public class KilloughDrive extends RobotDriveBase {
public class KilloughDrive extends RobotDriveBase implements Sendable {
public static final double kDefaultLeftMotorAngle = 60.0;
public static final double kDefaultRightMotorAngle = 120.0;
public static final double kDefaultBackMotorAngle = 270.0;
@@ -100,11 +102,11 @@ public class KilloughDrive extends RobotDriveBase {
Math.sin(rightMotorAngle * (Math.PI / 180.0)));
m_backVec = new Vector2d(Math.cos(backMotorAngle * (Math.PI / 180.0)),
Math.sin(backMotorAngle * (Math.PI / 180.0)));
addChild(m_leftMotor);
addChild(m_rightMotor);
addChild(m_backMotor);
SendableRegistry.addChild(this, m_leftMotor);
SendableRegistry.addChild(this, m_rightMotor);
SendableRegistry.addChild(this, m_backMotor);
instances++;
setName("KilloughDrive", instances);
SendableRegistry.addLW(this, "KilloughDrive", instances);
}
/**

View File

@@ -12,8 +12,10 @@ import java.util.StringJoiner;
import edu.wpi.first.hal.FRCNetComm.tInstances;
import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.wpilibj.Sendable;
import edu.wpi.first.wpilibj.SpeedController;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
import edu.wpi.first.wpiutil.math.MathUtils;
/**
@@ -59,7 +61,7 @@ import edu.wpi.first.wpiutil.math.MathUtils;
* {@link edu.wpi.first.wpilibj.RobotDrive#mecanumDrive_Polar(double, double, double)} if a
* deadband of 0 is used.
*/
public class MecanumDrive extends RobotDriveBase {
public class MecanumDrive extends RobotDriveBase implements Sendable {
private static int instances;
private final SpeedController m_frontLeftMotor;
@@ -82,12 +84,12 @@ public class MecanumDrive extends RobotDriveBase {
m_rearLeftMotor = rearLeftMotor;
m_frontRightMotor = frontRightMotor;
m_rearRightMotor = rearRightMotor;
addChild(m_frontLeftMotor);
addChild(m_rearLeftMotor);
addChild(m_frontRightMotor);
addChild(m_rearRightMotor);
SendableRegistry.addChild(this, m_frontLeftMotor);
SendableRegistry.addChild(this, m_rearLeftMotor);
SendableRegistry.addChild(this, m_frontRightMotor);
SendableRegistry.addChild(this, m_rearRightMotor);
instances++;
setName("MecanumDrive", instances);
SendableRegistry.addLW(this, "MecanumDrive", instances);
}
/**

View File

@@ -8,21 +8,17 @@
package edu.wpi.first.wpilibj.drive;
import edu.wpi.first.wpilibj.MotorSafety;
import edu.wpi.first.wpilibj.Sendable;
import edu.wpi.first.wpilibj.SendableImpl;
/**
* Common base class for drive platforms.
*/
public abstract class RobotDriveBase extends MotorSafety implements Sendable, AutoCloseable {
public abstract class RobotDriveBase extends MotorSafety {
public static final double kDefaultDeadband = 0.02;
public static final double kDefaultMaxOutput = 1.0;
protected double m_deadband = kDefaultDeadband;
protected double m_maxOutput = kDefaultMaxOutput;
private final SendableImpl m_sendableImpl;
/**
* The location of a motor on the robot for the purpose of driving.
*/
@@ -42,65 +38,7 @@ public abstract class RobotDriveBase extends MotorSafety implements Sendable, Au
* RobotDriveBase constructor.
*/
public RobotDriveBase() {
m_sendableImpl = new SendableImpl(true);
setSafetyEnabled(true);
setName("RobotDriveBase");
}
@Override
public void close() {
m_sendableImpl.close();
}
@Override
public final synchronized String getName() {
return m_sendableImpl.getName();
}
@Override
public final synchronized void setName(String name) {
m_sendableImpl.setName(name);
}
/**
* Sets the name of the sensor with a channel number.
*
* @param moduleType A string that defines the module name in the label for the value
* @param channel The channel number the device is plugged into
*/
protected final void setName(String moduleType, int channel) {
m_sendableImpl.setName(moduleType, channel);
}
/**
* Sets the name of the sensor with a module and channel number.
*
* @param moduleType A string that defines the module name in the label for the value
* @param moduleNumber The number of the particular module type
* @param channel The channel number the device is plugged into (usually PWM)
*/
protected final void setName(String moduleType, int moduleNumber, int channel) {
m_sendableImpl.setName(moduleType, moduleNumber, channel);
}
@Override
public final synchronized String getSubsystem() {
return m_sendableImpl.getSubsystem();
}
@Override
public final synchronized void setSubsystem(String subsystem) {
m_sendableImpl.setSubsystem(subsystem);
}
/**
* Add a child component.
*
* @param child child component
*/
protected final void addChild(Object child) {
m_sendableImpl.addChild(child);
}
/**

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2014-2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2014-2019 FIRST. 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. */
@@ -56,10 +56,4 @@ public interface Gyro extends AutoCloseable {
* @return the current rate in degrees per second
*/
double getRate();
/**
* Free the resources used by the gyro.
*/
@Deprecated
void free();
}

View File

@@ -7,38 +7,27 @@
package edu.wpi.first.wpilibj.livewindow;
import java.util.HashMap;
import java.util.Map;
import edu.wpi.first.networktables.NetworkTable;
import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.networktables.NetworkTableInstance;
import edu.wpi.first.wpilibj.Sendable;
import edu.wpi.first.wpilibj.command.Scheduler;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilderImpl;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* The LiveWindow class is the public interface for putting sensors and actuators on the
* LiveWindow.
*/
@SuppressWarnings("PMD.TooManyMethods")
public class LiveWindow {
private static class Component {
Component(Sendable sendable, Sendable parent) {
m_sendable = sendable;
m_parent = parent;
}
final Sendable m_sendable;
Sendable m_parent;
final SendableBuilderImpl m_builder = new SendableBuilderImpl();
boolean m_firstTime = true;
boolean m_telemetryEnabled = true;
}
@SuppressWarnings("PMD.UseConcurrentHashMap")
private static final Map<Object, Component> components = new HashMap<>();
private static final int dataHandle = SendableRegistry.getDataHandle();
private static final NetworkTable liveWindowTable =
NetworkTableInstance.getDefault().getTable("LiveWindow");
private static final NetworkTable statusTable = liveWindowTable.getSubTable(".status");
@@ -47,6 +36,15 @@ public class LiveWindow {
private static boolean liveWindowEnabled;
private static boolean telemetryEnabled = true;
private static Component getOrAdd(Sendable sendable) {
Component data = (Component) SendableRegistry.getData(sendable, dataHandle);
if (data == null) {
data = new Component();
SendableRegistry.setData(sendable, dataHandle, data);
}
return data;
}
private LiveWindow() {
throw new UnsupportedOperationException("This is a utility class!");
}
@@ -75,53 +73,19 @@ public class LiveWindow {
scheduler.removeAll();
} else {
System.out.println("stopping live window mode.");
for (Component component : components.values()) {
component.m_builder.stopLiveWindowMode();
}
SendableRegistry.foreachLiveWindow(dataHandle,
(sendable, name, subsystem, parent, data) -> {
if (data != null) {
((Component) data).m_builder.stopLiveWindowMode();
}
return data;
});
scheduler.enable();
}
enabledEntry.setBoolean(enabled);
}
}
/**
* Add a component to the LiveWindow.
*
* @param sendable component to add
*/
public static synchronized void add(Sendable sendable) {
components.putIfAbsent(sendable, new Component(sendable, null));
}
/**
* Add a child component to a component.
*
* @param parent parent component
* @param child child component
*/
public static synchronized void addChild(Sendable parent, Object child) {
Component component = components.get(child);
if (component == null) {
component = new Component(null, parent);
components.put(child, component);
} else {
component.m_parent = parent;
}
component.m_telemetryEnabled = false;
}
/**
* Remove a component from the LiveWindow.
*
* @param sendable component to remove
*/
public static synchronized void remove(Sendable sendable) {
Component component = components.remove(sendable);
if (component != null && isEnabled()) {
component.m_builder.stopLiveWindowMode();
}
}
/**
* Enable telemetry for a single component.
*
@@ -130,10 +94,7 @@ public class LiveWindow {
public static synchronized void enableTelemetry(Sendable sendable) {
// Re-enable global setting in case disableAllTelemetry() was called.
telemetryEnabled = true;
Component component = components.get(sendable);
if (component != null) {
component.m_telemetryEnabled = true;
}
getOrAdd(sendable).m_telemetryEnabled = true;
}
/**
@@ -142,10 +103,7 @@ public class LiveWindow {
* @param sendable component
*/
public static synchronized void disableTelemetry(Sendable sendable) {
Component component = components.get(sendable);
if (component != null) {
component.m_telemetryEnabled = false;
}
getOrAdd(sendable).m_telemetryEnabled = false;
}
/**
@@ -153,9 +111,13 @@ public class LiveWindow {
*/
public static synchronized void disableAllTelemetry() {
telemetryEnabled = false;
for (Component component : components.values()) {
component.m_telemetryEnabled = false;
}
SendableRegistry.foreachLiveWindow(dataHandle, (sendable, name, subsystem, parent, data) -> {
if (data == null) {
data = new Component();
}
((Component) data).m_telemetryEnabled = false;
return data;
});
}
/**
@@ -164,48 +126,58 @@ public class LiveWindow {
* <p>Actuators are handled through callbacks on their value changing from the
* SmartDashboard widgets.
*/
@SuppressWarnings("PMD.CyclomaticComplexity")
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.NPathComplexity"})
public static synchronized void updateValues() {
// Only do this if either LiveWindow mode or telemetry is enabled.
if (!liveWindowEnabled && !telemetryEnabled) {
return;
}
for (Component component : components.values()) {
if (component.m_sendable != null && component.m_parent == null
&& (liveWindowEnabled || component.m_telemetryEnabled)) {
if (component.m_firstTime) {
// By holding off creating the NetworkTable entries, it allows the
// components to be redefined. This allows default sensor and actuator
// values to be created that are replaced with the custom names from
// users calling setName.
String name = component.m_sendable.getName();
if (name.isEmpty()) {
continue;
}
String subsystem = component.m_sendable.getSubsystem();
NetworkTable ssTable = liveWindowTable.getSubTable(subsystem);
NetworkTable table;
// Treat name==subsystem as top level of subsystem
if (name.equals(subsystem)) {
table = ssTable;
} else {
table = ssTable.getSubTable(name);
}
table.getEntry(".name").setString(name);
component.m_builder.setTable(table);
component.m_sendable.initSendable(component.m_builder);
ssTable.getEntry(".type").setString("LW Subsystem");
component.m_firstTime = false;
}
if (startLiveWindow) {
component.m_builder.startLiveWindowMode();
}
component.m_builder.updateTable();
SendableRegistry.foreachLiveWindow(dataHandle, (sendable, name, subsystem, parent, data) -> {
if (sendable == null || parent != null) {
return data;
}
}
if (data == null) {
data = new Component();
}
Component component = (Component) data;
if (!liveWindowEnabled && !component.m_telemetryEnabled) {
return data;
}
if (component.m_firstTime) {
// By holding off creating the NetworkTable entries, it allows the
// components to be redefined. This allows default sensor and actuator
// values to be created that are replaced with the custom names from
// users calling setName.
if (name.isEmpty()) {
return data;
}
NetworkTable ssTable = liveWindowTable.getSubTable(subsystem);
NetworkTable table;
// Treat name==subsystem as top level of subsystem
if (name.equals(subsystem)) {
table = ssTable;
} else {
table = ssTable.getSubTable(name);
}
table.getEntry(".name").setString(name);
component.m_builder.setTable(table);
sendable.initSendable(component.m_builder);
ssTable.getEntry(".type").setString("LW Subsystem");
component.m_firstTime = false;
}
if (startLiveWindow) {
component.m_builder.startLiveWindowMode();
}
component.m_builder.updateTable();
return data;
});
startLiveWindow = false;
}

View File

@@ -22,6 +22,7 @@ import java.util.function.Supplier;
import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.wpilibj.Sendable;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* A helper class for Shuffleboard containers to handle common child operations.
@@ -66,10 +67,11 @@ final class ContainerHelper {
}
ComplexWidget add(Sendable sendable) throws IllegalArgumentException {
if (sendable.getName() == null || sendable.getName().isEmpty()) {
String name = SendableRegistry.getName(sendable);
if (name.isEmpty()) {
throw new IllegalArgumentException("Sendable must have a name");
}
return add(sendable.getName(), sendable);
return add(name, sendable);
}
SimpleWidget add(String title, Object defaultValue) {

View File

@@ -1,5 +1,5 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2018 FIRST. All Rights Reserved. */
/* Copyright (c) 2018-2019 FIRST. 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. */
@@ -12,13 +12,13 @@ import java.util.WeakHashMap;
import edu.wpi.cscore.VideoSource;
import edu.wpi.first.wpilibj.Sendable;
import edu.wpi.first.wpilibj.SendableBase;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* A wrapper to make video sources sendable and usable from Shuffleboard.
*/
public final class SendableCameraWrapper extends SendableBase {
public final class SendableCameraWrapper implements Sendable {
private static final String kProtocol = "camera_server://";
private static Map<VideoSource, SendableCameraWrapper> m_wrappers = new WeakHashMap<>();
@@ -32,9 +32,8 @@ public final class SendableCameraWrapper extends SendableBase {
* @param source the source to wrap
*/
private SendableCameraWrapper(VideoSource source) {
super(false);
String name = source.getName();
setName(name);
SendableRegistry.add(this, name);
m_uri = kProtocol + name;
}

View File

@@ -15,7 +15,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.wpilibj.SendableBase;
import edu.wpi.first.wpilibj.Sendable;
import edu.wpi.first.wpilibj.command.Command;
import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
@@ -32,7 +32,7 @@ import static edu.wpi.first.wpilibj.util.ErrorMessages.requireNonNullParam;
*
* @param <V> The type of the values to be stored
*/
public class SendableChooser<V> extends SendableBase {
public class SendableChooser<V> implements Sendable {
/**
* The key for the default value.
*/
@@ -65,8 +65,8 @@ public class SendableChooser<V> extends SendableBase {
* Instantiates a {@link SendableChooser}.
*/
public SendableChooser() {
super(false);
m_instance = s_instances.getAndIncrement();
SendableRegistry.add(this, "SendableChooser", m_instance);
}
/**

View File

@@ -0,0 +1,437 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2019 FIRST. 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.smartdashboard;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.Map;
import java.util.WeakHashMap;
import edu.wpi.first.wpilibj.Sendable;
/**
* The SendableRegistry class is the public interface for registering sensors
* and actuators for use on dashboards and LiveWindow.
*/
@SuppressWarnings("PMD.TooManyMethods")
public class SendableRegistry {
private static class Component {
Component() {}
Component(Sendable sendable) {
m_sendable = new WeakReference<>(sendable);
}
WeakReference<Sendable> m_sendable;
String m_name;
String m_subsystem = "Ungrouped";
WeakReference<Sendable> m_parent;
boolean m_liveWindow;
Object[] m_data;
void setName(String moduleType, int channel) {
m_name = moduleType + "[" + channel + "]";
}
void setName(String moduleType, int moduleNumber, int channel) {
m_name = moduleType + "[" + moduleNumber + "," + channel + "]";
}
}
private static final Map<Object, Component> components = new WeakHashMap<>();
private static int nextDataHandle;
private static Component getOrAdd(Sendable sendable) {
Component comp = components.get(sendable);
if (comp == null) {
comp = new Component(sendable);
components.put(sendable, comp);
} else {
if (comp.m_sendable == null) {
comp.m_sendable = new WeakReference<>(sendable);
}
}
return comp;
}
private SendableRegistry() {
throw new UnsupportedOperationException("This is a utility class!");
}
/**
* Adds an object to the registry.
*
* @param sendable object to add
* @param name component name
*/
public static synchronized void add(Sendable sendable, String name) {
Component comp = getOrAdd(sendable);
comp.m_name = name;
}
/**
* Adds an object to the registry.
*
* @param sendable object to add
* @param moduleType A string that defines the module name in the label for
* the value
* @param channel The channel number the device is plugged into
*/
public static synchronized void add(Sendable sendable, String moduleType, int channel) {
Component comp = getOrAdd(sendable);
comp.setName(moduleType, channel);
}
/**
* Adds an object to the registry.
*
* @param sendable object to add
* @param moduleType A string that defines the module name in the label for
* the value
* @param moduleNumber The number of the particular module type
* @param channel The channel number the device is plugged into
*/
public static synchronized void add(Sendable sendable, String moduleType, int moduleNumber,
int channel) {
Component comp = getOrAdd(sendable);
comp.setName(moduleType, moduleNumber, channel);
}
/**
* Adds an object to the registry.
*
* @param sendable object to add
* @param subsystem subsystem name
* @param name component name
*/
public static synchronized void add(Sendable sendable, String subsystem, String name) {
Component comp = getOrAdd(sendable);
comp.m_name = name;
comp.m_subsystem = subsystem;
}
/**
* Adds an object to the registry and LiveWindow.
*
* @param sendable object to add
* @param name component name
*/
public static synchronized void addLW(Sendable sendable, String name) {
Component comp = getOrAdd(sendable);
comp.m_liveWindow = true;
comp.m_name = name;
}
/**
* Adds an object to the registry and LiveWindow.
*
* @param sendable object to add
* @param moduleType A string that defines the module name in the label for
* the value
* @param channel The channel number the device is plugged into
*/
public static synchronized void addLW(Sendable sendable, String moduleType, int channel) {
Component comp = getOrAdd(sendable);
comp.m_liveWindow = true;
comp.setName(moduleType, channel);
}
/**
* Adds an object to the registry and LiveWindow.
*
* @param sendable object to add
* @param moduleType A string that defines the module name in the label for
* the value
* @param moduleNumber The number of the particular module type
* @param channel The channel number the device is plugged into
*/
public static synchronized void addLW(Sendable sendable, String moduleType, int moduleNumber,
int channel) {
Component comp = getOrAdd(sendable);
comp.m_liveWindow = true;
comp.setName(moduleType, moduleNumber, channel);
}
/**
* Adds an object to the registry and LiveWindow.
*
* @param sendable object to add
* @param subsystem subsystem name
* @param name component name
*/
public static synchronized void addLW(Sendable sendable, String subsystem, String name) {
Component comp = getOrAdd(sendable);
comp.m_liveWindow = true;
comp.m_name = name;
comp.m_subsystem = subsystem;
}
/**
* Adds a child object to an object. Adds the child object to the registry
* if it's not already present.
*
* @param parent parent object
* @param child child object
*/
public static synchronized void addChild(Sendable parent, Object child) {
Component comp = components.get(child);
if (comp == null) {
comp = new Component();
components.put(child, comp);
}
comp.m_parent = new WeakReference<>(parent);
}
/**
* Removes an object from the registry.
*
* @param sendable object to remove
* @return true if the object was removed; false if it was not present
*/
public static synchronized boolean remove(Sendable sendable) {
return components.remove(sendable) != null;
}
/**
* Determines if an object is in the registry.
*
* @param sendable object to check
* @return True if in registry, false if not.
*/
public static synchronized boolean contains(Sendable sendable) {
return components.containsKey(sendable);
}
/**
* Gets the name of an object.
*
* @param sendable object
* @return Name (empty if object is not in registry)
*/
public static synchronized String getName(Sendable sendable) {
Component comp = components.get(sendable);
if (comp == null) {
return "";
}
return comp.m_name;
}
/**
* Sets the name of an object.
*
* @param sendable object
* @param name name
*/
public static synchronized void setName(Sendable sendable, String name) {
Component comp = components.get(sendable);
if (comp != null) {
comp.m_name = name;
}
}
/**
* Sets the name of an object with a channel number.
*
* @param sendable object
* @param moduleType A string that defines the module name in the label for
* the value
* @param channel The channel number the device is plugged into
*/
public static synchronized void setName(Sendable sendable, String moduleType, int channel) {
Component comp = components.get(sendable);
if (comp != null) {
comp.setName(moduleType, channel);
}
}
/**
* Sets the name of an object with a module and channel number.
*
* @param sendable object
* @param moduleType A string that defines the module name in the label for
* the value
* @param moduleNumber The number of the particular module type
* @param channel The channel number the device is plugged into
*/
public static synchronized void setName(Sendable sendable, String moduleType, int moduleNumber,
int channel) {
Component comp = components.get(sendable);
if (comp != null) {
comp.setName(moduleType, moduleNumber, channel);
}
}
/**
* Sets both the subsystem name and device name of an object.
*
* @param sendable object
* @param subsystem subsystem name
* @param name device name
*/
public static synchronized void setName(Sendable sendable, String subsystem, String name) {
Component comp = components.get(sendable);
if (comp != null) {
comp.m_name = name;
comp.m_subsystem = subsystem;
}
}
/**
* Gets the subsystem name of an object.
*
* @param sendable object
* @return Subsystem name (empty if object is not in registry)
*/
public static synchronized String getSubsystem(Sendable sendable) {
Component comp = components.get(sendable);
if (comp == null) {
return "";
}
return comp.m_subsystem;
}
/**
* Sets the subsystem name of an object.
*
* @param sendable object
* @param subsystem subsystem name
*/
public static synchronized void setSubsystem(Sendable sendable, String subsystem) {
Component comp = components.get(sendable);
if (comp != null) {
comp.m_subsystem = subsystem;
}
}
/**
* Gets a unique handle for setting/getting data with setData() and getData().
*
* @return Handle
*/
public static synchronized int getDataHandle() {
return nextDataHandle++;
}
/**
* Associates arbitrary data with an object in the registry.
*
* @param sendable object
* @param handle data handle returned by getDataHandle()
* @param data data to set
* @return Previous data (may be null)
*/
public static synchronized Object setData(Sendable sendable, int handle, Object data) {
Component comp = components.get(sendable);
if (comp == null) {
return null;
}
Object rv = null;
if (handle < comp.m_data.length) {
rv = comp.m_data[handle];
} else if (comp.m_data == null) {
comp.m_data = new Object[handle + 1];
} else {
comp.m_data = Arrays.copyOf(comp.m_data, handle + 1);
}
comp.m_data[handle] = data;
return rv;
}
/**
* Gets arbitrary data associated with an object in the registry.
*
* @param sendable object
* @param handle data handle returned by getDataHandle()
* @return data (may be null if none associated)
*/
public static synchronized Object getData(Sendable sendable, int handle) {
Component comp = components.get(sendable);
if (comp == null || comp.m_data == null || handle >= comp.m_data.length) {
return null;
}
return comp.m_data[handle];
}
/**
* Enables LiveWindow for an object.
*
* @param sendable object
*/
public static synchronized void enableLiveWindow(Sendable sendable) {
Component comp = components.get(sendable);
if (comp != null) {
comp.m_liveWindow = true;
}
}
/**
* Disables LiveWindow for an object.
*
* @param sendable object
*/
public static synchronized void disableLiveWindow(Sendable sendable) {
Component comp = components.get(sendable);
if (comp != null) {
comp.m_liveWindow = false;
}
}
/**
* Functional interface for foreachLiveWindow().
*/
@FunctionalInterface
public interface LiveWindowForeachCallback {
/**
* Callback.
*
* @param sendable sendable object
* @param name name
* @param subsystem subsystem
* @param parent parent sendable object
* @param data data stored in object with setData()
* @return data to be stored back into object, or null if none/don't modify
*/
Object call(Sendable sendable, String name, String subsystem, Sendable parent, Object data);
}
/**
* Iterates over LiveWindow-enabled objects in the registry.
* It is *not* safe to call other SendableRegistry functions from the
* callback.
*
* @param dataHandle data handle to get data pointer passed to callback
* @param callback function to call for each object
*/
@SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.AvoidInstantiatingObjectsInLoops"})
public static synchronized void foreachLiveWindow(int dataHandle,
LiveWindowForeachCallback callback) {
for (Component comp : components.values()) {
Sendable sendable = comp.m_sendable.get();
if (sendable != null && comp.m_liveWindow) {
Sendable parent = null;
if (comp.m_parent != null) {
parent = comp.m_parent.get();
}
Object data = null;
if (comp.m_data != null && dataHandle < comp.m_data.length) {
data = comp.m_data[dataHandle];
}
data = callback.call(sendable, comp.m_name, comp.m_subsystem, parent, data);
if (data != null) {
if (comp.m_data == null) {
comp.m_data = new Object[dataHandle + 1];
} else if (dataHandle >= comp.m_data.length) {
comp.m_data = Arrays.copyOf(comp.m_data, dataHandle + 1);
}
comp.m_data[dataHandle] = data;
}
}
}
}
}

View File

@@ -97,7 +97,10 @@ public class SmartDashboard {
* @throws IllegalArgumentException If key is null
*/
public static void putData(Sendable value) {
putData(value.getName(), value);
String name = SendableRegistry.getName(value);
if (!name.isEmpty()) {
putData(name, value);
}
}
/**

View File

@@ -298,6 +298,11 @@ public interface Command {
return false;
}
/**
* Gets the name of this Command.
*
* @return Name
*/
default String getName() {
return this.getClass().getSimpleName();
}

View File

@@ -12,6 +12,7 @@ import java.util.Set;
import edu.wpi.first.wpilibj.Sendable;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* A {@link Sendable} base class for {@link Command}s.
@@ -19,10 +20,13 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
@SuppressWarnings("PMD.AbstractClassWithoutAbstractMethod")
public abstract class CommandBase implements Sendable, Command {
protected String m_name = this.getClass().getSimpleName();
protected String m_subsystem = "Ungrouped";
protected Set<Subsystem> m_requirements = new HashSet<>();
protected CommandBase() {
String name = getClass().getName();
SendableRegistry.add(this, name.substring(name.lastIndexOf('.') + 1));
}
/**
* Adds the specified requirements to the command.
*
@@ -39,22 +43,37 @@ public abstract class CommandBase implements Sendable, Command {
@Override
public String getName() {
return this.getClass().getSimpleName();
return SendableRegistry.getName(this);
}
/**
* Sets the name of this Command.
*
* @param name name
*/
@Override
public void setName(String name) {
m_name = name;
SendableRegistry.setName(this, name);
}
/**
* Gets the subsystem name of this Command.
*
* @return Subsystem name
*/
@Override
public String getSubsystem() {
return m_subsystem;
return SendableRegistry.getSubsystem(this);
}
/**
* Sets the subsystem name of this Command.
*
* @param subsystem subsystem name
*/
@Override
public void setSubsystem(String subsystem) {
m_subsystem = subsystem;
SendableRegistry.setSubsystem(this, subsystem);
}
/**

View File

@@ -23,8 +23,9 @@ import edu.wpi.first.hal.FRCNetComm.tResourceType;
import edu.wpi.first.hal.HAL;
import edu.wpi.first.networktables.NetworkTableEntry;
import edu.wpi.first.wpilibj.RobotState;
import edu.wpi.first.wpilibj.SendableBase;
import edu.wpi.first.wpilibj.Sendable;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* The scheduler responsible for running {@link Command}s. A Command-based robot should call {@link
@@ -34,7 +35,7 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
* Subsystem#periodic()} methods to be called and for their default commands to be scheduled.
*/
@SuppressWarnings({"PMD.GodClass", "PMD.TooManyMethods", "PMD.TooManyFields"})
public final class CommandScheduler extends SendableBase {
public final class CommandScheduler implements Sendable {
/**
* The Singleton Instance.
*/
@@ -82,7 +83,7 @@ public final class CommandScheduler extends SendableBase {
CommandScheduler() {
HAL.report(tResourceType.kResourceType_Command, tInstances.kCommand_Scheduler);
setName("Scheduler");
SendableRegistry.addLW(this, "Scheduler");
}
/**

View File

@@ -8,8 +8,8 @@
package edu.wpi.first.wpilibj2.command;
import edu.wpi.first.wpilibj.Sendable;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* A base for subsystems that handles registration in the constructor, and provides a more intuitive
@@ -17,30 +17,54 @@ import edu.wpi.first.wpilibj.smartdashboard.SendableBuilder;
*/
public abstract class SubsystemBase implements Subsystem, Sendable {
protected String m_name = this.getClass().getSimpleName();
/**
* Constructor.
*/
public SubsystemBase() {
String name = this.getClass().getSimpleName();
name = name.substring(name.lastIndexOf('.') + 1);
SendableRegistry.addLW(this, name, name);
CommandScheduler.getInstance().registerSubsystem(this);
}
/**
* Gets the name of this Subsystem.
*
* @return Name
*/
@Override
public String getName() {
return m_name;
return SendableRegistry.getName(this);
}
/**
* Sets the name of this Subsystem.
*
* @param name name
*/
@Override
public void setName(String name) {
m_name = name;
SendableRegistry.setName(this, name);
}
/**
* Gets the subsystem name of this Subsystem.
*
* @return Subsystem name
*/
@Override
public String getSubsystem() {
return getName();
return SendableRegistry.getSubsystem(this);
}
/**
* Sets the subsystem name of this Subsystem.
*
* @param subsystem subsystem name
*/
@Override
public void setSubsystem(String subsystem) {
setName(subsystem);
SendableRegistry.setSubsystem(this, subsystem);
}
/**
@@ -51,8 +75,8 @@ public abstract class SubsystemBase implements Subsystem, Sendable {
* @param child sendable
*/
public void addChild(String name, Sendable child) {
child.setName(getSubsystem(), name);
LiveWindow.add(child);
SendableRegistry.addLW(child, getSubsystem(), name);
SendableRegistry.addChild(this, child);
}
@Override

View File

@@ -8,6 +8,7 @@
package edu.wpi.first.wpilibj2.command;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.smartdashboard.SendableRegistry;
/**
* A command that does nothing but takes a specified amount of time to finish. Useful for
@@ -24,7 +25,7 @@ public class WaitCommand extends CommandBase {
*/
public WaitCommand(double seconds) {
m_duration = seconds;
setName(m_name + ": " + seconds + " seconds");
SendableRegistry.setName(this, getName() + ": " + seconds + " seconds");
}
@Override