Update LiveWindow to provide continuous telemetry. (#771)

LiveWindow.updateValues() is now called from IterativeRobotBase on every
loop iteration.  Telemetry for all WPILib classes is enabled by default;
it can be disabled for specific classes using LiveWindow.disableTelemetry(),
or all telemetry can be disabled using LiveWindow.disableAllTelemetry().

This necessitated changing the hook methodology into other classes to
be more property-based rather than each class providing multiple functions.
This had the benefit of reducing boilerplate and increasing consistency.

- Remove NamedSendable, add name to Sendable.

- Provide SendableBase abstract class.

- Deprecate LiveWindow addSensor/addActuator interfaces.

- Add LiveWindow support to drive classes.

- Add addChild() helper functions to Subsystem.

- Fix inheritance hierarchy.  Now only sensors inherit from SensorBase.
  Other devices inherit from some combination of SendableBase, ErrorBase, or
  nothing.
This commit is contained in:
Peter Johnson
2017-12-04 23:28:33 -08:00
committed by GitHub
parent 3befc7015b
commit f9bece2ffb
213 changed files with 3704 additions and 3758 deletions

View File

@@ -9,8 +9,7 @@
#include <HAL/HAL.h>
#include "I2C.h"
#include "LiveWindow/LiveWindow.h"
#include "SmartDashboard/SendableBuilder.h"
using namespace frc;
@@ -30,7 +29,7 @@ ADXL345_I2C::ADXL345_I2C(I2C::Port port, Range range, int deviceAddress)
HAL_Report(HALUsageReporting::kResourceType_ADXL345,
HALUsageReporting::kADXL345_I2C, 0);
LiveWindow::GetInstance()->AddSensor("ADXL345_I2C", port, this);
SetName("ADXL345_I2C", port);
}
void ADXL345_I2C::SetRange(Range range) {
@@ -75,25 +74,15 @@ ADXL345_I2C::AllAxes ADXL345_I2C::GetAccelerations() {
return data;
}
std::string ADXL345_I2C::GetSmartDashboardType() const {
return "3AxisAccelerometer";
}
void ADXL345_I2C::InitTable(std::shared_ptr<nt::NetworkTable> subtable) {
if (subtable) {
m_xEntry = subtable->GetEntry("X");
m_yEntry = subtable->GetEntry("Y");
m_zEntry = subtable->GetEntry("Z");
UpdateTable();
} else {
m_xEntry = nt::NetworkTableEntry();
m_yEntry = nt::NetworkTableEntry();
m_zEntry = nt::NetworkTableEntry();
}
}
void ADXL345_I2C::UpdateTable() {
if (m_xEntry) m_xEntry.SetDouble(GetX());
if (m_yEntry) m_yEntry.SetDouble(GetY());
if (m_zEntry) m_zEntry.SetDouble(GetZ());
void ADXL345_I2C::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("3AxisAccelerometer");
auto x = builder.GetEntry("X").GetHandle();
auto y = builder.GetEntry("Y").GetHandle();
auto z = builder.GetEntry("Z").GetHandle();
builder.SetUpdateTable([=]() {
auto data = GetAccelerations();
nt::NetworkTableEntry(x).SetDouble(data.XAxis);
nt::NetworkTableEntry(y).SetDouble(data.YAxis);
nt::NetworkTableEntry(z).SetDouble(data.ZAxis);
});
}

View File

@@ -9,9 +9,7 @@
#include <HAL/HAL.h>
#include "DigitalInput.h"
#include "DigitalOutput.h"
#include "LiveWindow/LiveWindow.h"
#include "SmartDashboard/SendableBuilder.h"
using namespace frc;
@@ -40,7 +38,7 @@ ADXL345_SPI::ADXL345_SPI(SPI::Port port, ADXL345_SPI::Range range)
HAL_Report(HALUsageReporting::kResourceType_ADXL345,
HALUsageReporting::kADXL345_SPI);
LiveWindow::GetInstance()->AddSensor("ADXL345_SPI", port, this);
SetName("ADXL345_SPI", port);
}
void ADXL345_SPI::SetRange(Range range) {
@@ -103,25 +101,15 @@ ADXL345_SPI::AllAxes ADXL345_SPI::GetAccelerations() {
return data;
}
std::string ADXL345_SPI::GetSmartDashboardType() const {
return "3AxisAccelerometer";
}
void ADXL345_SPI::InitTable(std::shared_ptr<nt::NetworkTable> subtable) {
if (subtable) {
m_xEntry = subtable->GetEntry("X");
m_yEntry = subtable->GetEntry("Y");
m_zEntry = subtable->GetEntry("Z");
UpdateTable();
} else {
m_xEntry = nt::NetworkTableEntry();
m_yEntry = nt::NetworkTableEntry();
m_zEntry = nt::NetworkTableEntry();
}
}
void ADXL345_SPI::UpdateTable() {
if (m_xEntry) m_xEntry.SetDouble(GetX());
if (m_yEntry) m_yEntry.SetDouble(GetY());
if (m_zEntry) m_zEntry.SetDouble(GetZ());
void ADXL345_SPI::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("3AxisAccelerometer");
auto x = builder.GetEntry("X").GetHandle();
auto y = builder.GetEntry("Y").GetHandle();
auto z = builder.GetEntry("Z").GetHandle();
builder.SetUpdateTable([=]() {
auto data = GetAccelerations();
nt::NetworkTableEntry(x).SetDouble(data.XAxis);
nt::NetworkTableEntry(y).SetDouble(data.YAxis);
nt::NetworkTableEntry(z).SetDouble(data.ZAxis);
});
}

View File

@@ -9,29 +9,27 @@
#include <HAL/HAL.h>
#include "DigitalInput.h"
#include "DigitalOutput.h"
#include "DriverStation.h"
#include "LiveWindow/LiveWindow.h"
#include "SmartDashboard/SendableBuilder.h"
using namespace frc;
static int kRegWrite = 0x0A;
static int kRegRead = 0x0B;
static constexpr int kRegWrite = 0x0A;
static constexpr int kRegRead = 0x0B;
static int kPartIdRegister = 0x02;
static int kDataRegister = 0x0E;
static int kFilterCtlRegister = 0x2C;
static int kPowerCtlRegister = 0x2D;
static constexpr int kPartIdRegister = 0x02;
static constexpr int kDataRegister = 0x0E;
static constexpr int kFilterCtlRegister = 0x2C;
static constexpr int kPowerCtlRegister = 0x2D;
// static int kFilterCtl_Range2G = 0x00;
// static int kFilterCtl_Range4G = 0x40;
// static int kFilterCtl_Range8G = 0x80;
static int kFilterCtl_ODR_100Hz = 0x03;
// static constexpr int kFilterCtl_Range2G = 0x00;
// static constexpr int kFilterCtl_Range4G = 0x40;
// static constexpr int kFilterCtl_Range8G = 0x80;
static constexpr int kFilterCtl_ODR_100Hz = 0x03;
static int kPowerCtl_UltraLowNoise = 0x20;
// static int kPowerCtl_AutoSleep = 0x04;
static int kPowerCtl_Measure = 0x02;
static constexpr int kPowerCtl_UltraLowNoise = 0x20;
// static constexpr int kPowerCtl_AutoSleep = 0x04;
static constexpr int kPowerCtl_Measure = 0x02;
/**
* Constructor. Uses the onboard CS1.
@@ -75,7 +73,7 @@ ADXL362::ADXL362(SPI::Port port, Range range) : m_spi(port) {
HAL_Report(HALUsageReporting::kResourceType_ADXL362, port);
LiveWindow::GetInstance()->AddSensor("ADXL362", port, this);
SetName("ADXL362", port);
}
void ADXL362::SetRange(Range range) {
@@ -163,25 +161,15 @@ ADXL362::AllAxes ADXL362::GetAccelerations() {
return data;
}
std::string ADXL362::GetSmartDashboardType() const {
return "3AxisAccelerometer";
}
void ADXL362::InitTable(std::shared_ptr<nt::NetworkTable> subtable) {
if (subtable) {
m_xEntry = subtable->GetEntry("X");
m_yEntry = subtable->GetEntry("Y");
m_zEntry = subtable->GetEntry("Z");
UpdateTable();
} else {
m_xEntry = nt::NetworkTableEntry();
m_yEntry = nt::NetworkTableEntry();
m_zEntry = nt::NetworkTableEntry();
}
}
void ADXL362::UpdateTable() {
if (m_xEntry) m_xEntry.SetDouble(GetX());
if (m_yEntry) m_yEntry.SetDouble(GetY());
if (m_zEntry) m_zEntry.SetDouble(GetZ());
void ADXL362::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("3AxisAccelerometer");
auto x = builder.GetEntry("X").GetHandle();
auto y = builder.GetEntry("Y").GetHandle();
auto z = builder.GetEntry("Z").GetHandle();
builder.SetUpdateTable([=]() {
auto data = GetAccelerations();
nt::NetworkTableEntry(x).SetDouble(data.XAxis);
nt::NetworkTableEntry(y).SetDouble(data.YAxis);
nt::NetworkTableEntry(z).SetDouble(data.ZAxis);
});
}

View File

@@ -10,7 +10,6 @@
#include <HAL/HAL.h>
#include "DriverStation.h"
#include "LiveWindow/LiveWindow.h"
#include "Timer.h"
using namespace frc;
@@ -81,7 +80,7 @@ ADXRS450_Gyro::ADXRS450_Gyro(SPI::Port port) : m_spi(port) {
Calibrate();
HAL_Report(HALUsageReporting::kResourceType_ADXRS450, port);
LiveWindow::GetInstance()->AddSensor("ADXRS450_Gyro", port, this);
SetName("ADXRS450_Gyro", port);
}
static bool CalcParity(int v) {

View File

@@ -9,7 +9,7 @@
#include <HAL/HAL.h>
#include "LiveWindow/LiveWindow.h"
#include "SmartDashboard/SendableBuilder.h"
#include "WPIErrors.h"
using namespace frc;
@@ -20,8 +20,7 @@ using namespace frc;
void AnalogAccelerometer::InitAccelerometer() {
HAL_Report(HALUsageReporting::kResourceType_Accelerometer,
m_analogInput->GetChannel());
LiveWindow::GetInstance()->AddSensor("Accelerometer",
m_analogInput->GetChannel(), this);
SetName("Accelerometer", m_analogInput->GetChannel());
}
/**
@@ -32,9 +31,9 @@ void AnalogAccelerometer::InitAccelerometer() {
* @param channel The channel number for the analog input the accelerometer is
* connected to
*/
AnalogAccelerometer::AnalogAccelerometer(int channel) {
m_analogInput = std::make_shared<AnalogInput>(channel);
InitAccelerometer();
AnalogAccelerometer::AnalogAccelerometer(int channel)
: AnalogAccelerometer(std::make_shared<AnalogInput>(channel)) {
AddChild(m_analogInput);
}
/**
@@ -116,24 +115,8 @@ void AnalogAccelerometer::SetZero(double zero) { m_zeroGVoltage = zero; }
*/
double AnalogAccelerometer::PIDGet() { return GetAcceleration(); }
void AnalogAccelerometer::UpdateTable() {
if (m_valueEntry) m_valueEntry.SetDouble(GetAcceleration());
}
void AnalogAccelerometer::StartLiveWindowMode() {}
void AnalogAccelerometer::StopLiveWindowMode() {}
std::string AnalogAccelerometer::GetSmartDashboardType() const {
return "Accelerometer";
}
void AnalogAccelerometer::InitTable(
std::shared_ptr<nt::NetworkTable> subTable) {
if (subTable) {
m_valueEntry = subTable->GetEntry("Value");
UpdateTable();
} else {
m_valueEntry = nt::NetworkTableEntry();
}
void AnalogAccelerometer::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Accelerometer");
builder.AddDoubleProperty("Value", [=]() { return GetAcceleration(); },
nullptr);
}

View File

@@ -14,7 +14,6 @@
#include <HAL/HAL.h>
#include "AnalogInput.h"
#include "LiveWindow/LiveWindow.h"
#include "Timer.h"
#include "WPIErrors.h"
@@ -27,7 +26,9 @@ using namespace frc;
* be used on on-board Analog Inputs 0-1.
*/
AnalogGyro::AnalogGyro(int channel)
: AnalogGyro(std::make_shared<AnalogInput>(channel)) {}
: AnalogGyro(std::make_shared<AnalogInput>(channel)) {
AddChild(m_analog);
}
/**
* Gyro constructor with a precreated AnalogInput object.
@@ -75,18 +76,9 @@ AnalogGyro::AnalogGyro(std::shared_ptr<AnalogInput> channel)
* value.
* @param offset Preset uncalibrated value to use as the gyro offset.
*/
AnalogGyro::AnalogGyro(int channel, int center, double offset) {
m_analog = std::make_shared<AnalogInput>(channel);
InitGyro();
int32_t status = 0;
HAL_SetAnalogGyroParameters(m_gyroHandle, kDefaultVoltsPerDegreePerSecond,
offset, center, &status);
if (status != 0) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
m_gyroHandle = HAL_kInvalidHandle;
return;
}
Reset();
AnalogGyro::AnalogGyro(int channel, int center, double offset)
: AnalogGyro(std::make_shared<AnalogInput>(channel), center, offset) {
AddChild(m_analog);
}
/**
@@ -172,8 +164,7 @@ void AnalogGyro::InitGyro() {
}
HAL_Report(HALUsageReporting::kResourceType_Gyro, m_analog->GetChannel());
LiveWindow::GetInstance()->AddSensor("AnalogGyro", m_analog->GetChannel(),
this);
SetName("AnalogGyro", m_analog->GetChannel());
}
void AnalogGyro::Calibrate() {

View File

@@ -14,7 +14,7 @@
#include <llvm/SmallString.h>
#include <llvm/raw_ostream.h>
#include "LiveWindow/LiveWindow.h"
#include "SmartDashboard/SendableBuilder.h"
#include "Timer.h"
#include "WPIErrors.h"
@@ -49,8 +49,8 @@ AnalogInput::AnalogInput(int channel) {
return;
}
LiveWindow::GetInstance()->AddSensor("AnalogInput", channel, this);
HAL_Report(HALUsageReporting::kResourceType_AnalogChannel, channel);
SetName("AnalogInput", channel);
}
/**
@@ -414,23 +414,8 @@ double AnalogInput::PIDGet() {
return GetAverageVoltage();
}
void AnalogInput::UpdateTable() {
if (m_valueEntry) m_valueEntry.SetDouble(GetAverageVoltage());
}
void AnalogInput::StartLiveWindowMode() {}
void AnalogInput::StopLiveWindowMode() {}
std::string AnalogInput::GetSmartDashboardType() const {
return "Analog Input";
}
void AnalogInput::InitTable(std::shared_ptr<nt::NetworkTable> subTable) {
if (subTable) {
m_valueEntry = subTable->GetEntry("Value");
UpdateTable();
} else {
m_valueEntry = nt::NetworkTableEntry();
}
void AnalogInput::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Analog Input");
builder.AddDoubleProperty("Value", [=]() { return GetAverageVoltage(); },
nullptr);
}

View File

@@ -14,7 +14,8 @@
#include <llvm/SmallString.h>
#include <llvm/raw_ostream.h>
#include "LiveWindow/LiveWindow.h"
#include "SensorBase.h"
#include "SmartDashboard/SendableBuilder.h"
#include "WPIErrors.h"
using namespace frc;
@@ -51,8 +52,8 @@ AnalogOutput::AnalogOutput(int channel) {
return;
}
LiveWindow::GetInstance()->AddActuator("AnalogOutput", m_channel, this);
HAL_Report(HALUsageReporting::kResourceType_AnalogOutput, m_channel);
SetName("AnalogOutput", m_channel);
}
/**
@@ -93,23 +94,8 @@ double AnalogOutput::GetVoltage() const {
return voltage;
}
void AnalogOutput::UpdateTable() {
if (m_valueEntry) m_valueEntry.SetDouble(GetVoltage());
}
void AnalogOutput::StartLiveWindowMode() {}
void AnalogOutput::StopLiveWindowMode() {}
std::string AnalogOutput::GetSmartDashboardType() const {
return "Analog Output";
}
void AnalogOutput::InitTable(std::shared_ptr<nt::NetworkTable> subTable) {
if (subTable) {
m_valueEntry = subTable->GetEntry("Value");
UpdateTable();
} else {
m_valueEntry = nt::NetworkTableEntry();
}
void AnalogOutput::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Analog Output");
builder.AddDoubleProperty("Value", [=]() { return GetVoltage(); },
[=](double value) { SetVoltage(value); });
}

View File

@@ -8,6 +8,7 @@
#include "AnalogPotentiometer.h"
#include "ControllerPower.h"
#include "SmartDashboard/SendableBuilder.h"
using namespace frc;
@@ -23,9 +24,11 @@ using namespace frc;
*/
AnalogPotentiometer::AnalogPotentiometer(int channel, double fullRange,
double offset)
: m_analog_input(std::make_unique<AnalogInput>(channel)),
: m_analog_input(std::make_shared<AnalogInput>(channel)),
m_fullRange(fullRange),
m_offset(offset) {}
m_offset(offset) {
AddChild(m_analog_input);
}
/**
* Construct an Analog Potentiometer object from an existing Analog Input
@@ -76,26 +79,9 @@ double AnalogPotentiometer::Get() const {
*/
double AnalogPotentiometer::PIDGet() { return Get(); }
/**
* @return the Smart Dashboard Type
*/
std::string AnalogPotentiometer::GetSmartDashboardType() const {
return "Analog Input";
}
/**
* Live Window code, only does anything if live window is activated.
*/
void AnalogPotentiometer::InitTable(
std::shared_ptr<nt::NetworkTable> subtable) {
if (subtable) {
m_valueEntry = subtable->GetEntry("Value");
UpdateTable();
} else {
m_valueEntry = nt::NetworkTableEntry();
}
}
void AnalogPotentiometer::UpdateTable() {
if (m_valueEntry) m_valueEntry.SetDouble(Get());
void AnalogPotentiometer::InitSendable(SendableBuilder& builder) {
m_analog_input->InitSendable(builder);
}

View File

@@ -25,6 +25,7 @@ using namespace frc;
AnalogTrigger::AnalogTrigger(int channel)
: AnalogTrigger(new AnalogInput(channel)) {
m_ownsAnalog = true;
AddChild(m_analogInput);
}
/**
@@ -49,6 +50,7 @@ AnalogTrigger::AnalogTrigger(AnalogInput* input) {
m_index = index;
HAL_Report(HALUsageReporting::kResourceType_AnalogTrigger, input->m_channel);
SetName("AnalogTrigger", input->GetChannel());
}
AnalogTrigger::~AnalogTrigger() {
@@ -184,3 +186,7 @@ std::shared_ptr<AnalogTriggerOutput> AnalogTrigger::CreateOutput(
return std::shared_ptr<AnalogTriggerOutput>(
new AnalogTriggerOutput(*this, type), NullDeleter<AnalogTriggerOutput>());
}
void AnalogTrigger::InitSendable(SendableBuilder& builder) {
if (m_ownsAnalog) m_analogInput->InitSendable(builder);
}

View File

@@ -78,3 +78,5 @@ AnalogTriggerType AnalogTriggerOutput::GetAnalogTriggerTypeForRouting() const {
* @return The channel of the source.
*/
int AnalogTriggerOutput::GetChannel() const { return m_trigger.m_index; }
void AnalogTriggerOutput::InitSendable(SendableBuilder&) {}

View File

@@ -10,7 +10,7 @@
#include <HAL/Accelerometer.h>
#include <HAL/HAL.h>
#include "LiveWindow/LiveWindow.h"
#include "SmartDashboard/SendableBuilder.h"
#include "WPIErrors.h"
using namespace frc;
@@ -25,7 +25,7 @@ BuiltInAccelerometer::BuiltInAccelerometer(Range range) {
HAL_Report(HALUsageReporting::kResourceType_Accelerometer, 0, 0,
"Built-in accelerometer");
LiveWindow::GetInstance()->AddSensor((std::string) "BuiltInAccel", 0, this);
SetName("BuiltInAccel", 0);
}
void BuiltInAccelerometer::SetRange(Range range) {
@@ -54,26 +54,9 @@ double BuiltInAccelerometer::GetY() { return HAL_GetAccelerometerY(); }
*/
double BuiltInAccelerometer::GetZ() { return HAL_GetAccelerometerZ(); }
std::string BuiltInAccelerometer::GetSmartDashboardType() const {
return "3AxisAccelerometer";
}
void BuiltInAccelerometer::InitTable(
std::shared_ptr<nt::NetworkTable> subtable) {
if (subtable != nullptr) {
m_xEntry = subtable->GetEntry("X");
m_yEntry = subtable->GetEntry("Y");
m_zEntry = subtable->GetEntry("Z");
UpdateTable();
} else {
m_xEntry = nt::NetworkTableEntry();
m_yEntry = nt::NetworkTableEntry();
m_zEntry = nt::NetworkTableEntry();
}
}
void BuiltInAccelerometer::UpdateTable() {
if (m_xEntry) m_xEntry.SetDouble(GetX());
if (m_yEntry) m_yEntry.SetDouble(GetY());
if (m_zEntry) m_zEntry.SetDouble(GetZ());
void BuiltInAccelerometer::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("3AxisAccelerometer");
builder.AddDoubleProperty("X", [=]() { return GetX(); }, nullptr);
builder.AddDoubleProperty("Y", [=]() { return GetY(); }, nullptr);
builder.AddDoubleProperty("Z", [=]() { return GetZ(); }, nullptr);
}

View File

@@ -11,12 +11,11 @@
#include "Buttons/PressedButtonScheduler.h"
#include "Buttons/ReleasedButtonScheduler.h"
#include "Buttons/ToggleButtonScheduler.h"
#include "SmartDashboard/SendableBuilder.h"
using namespace frc;
bool Trigger::Grab() {
return Get() || (m_pressedEntry && m_pressedEntry.GetBoolean(false));
}
bool Trigger::Grab() { return Get() || m_sendablePressed; }
void Trigger::WhenActive(Command* command) {
auto pbs = new PressedButtonScheduler(Grab(), this, command);
@@ -43,13 +42,9 @@ void Trigger::ToggleWhenActive(Command* command) {
tbs->Start();
}
std::string Trigger::GetSmartDashboardType() const { return "Button"; }
void Trigger::InitTable(std::shared_ptr<nt::NetworkTable> subtable) {
if (subtable) {
m_pressedEntry = subtable->GetEntry("pressed");
m_pressedEntry.SetBoolean(Get());
} else {
m_pressedEntry = nt::NetworkTableEntry();
}
void Trigger::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Button");
builder.SetSafeState([=]() { m_sendablePressed = false; });
builder.AddBooleanProperty("pressed", [=]() { return Grab(); },
[=](bool value) { m_sendablePressed = value; });
}

View File

@@ -11,16 +11,14 @@
#include "Commands/CommandGroup.h"
#include "Commands/Scheduler.h"
#include "LiveWindow/LiveWindow.h"
#include "RobotState.h"
#include "SmartDashboard/SendableBuilder.h"
#include "Timer.h"
#include "WPIErrors.h"
using namespace frc;
static const std::string kName = ".name";
static const std::string kRunning = "running";
static const std::string kIsParented = ".isParented";
int Command::m_commandCounter = 0;
/**
@@ -35,7 +33,7 @@ Command::Command() : Command("", -1.0) {}
*
* @param name the name for this command
*/
Command::Command(const std::string& name) : Command(name, -1.0) {}
Command::Command(const llvm::Twine& name) : Command(name, -1.0) {}
/**
* Creates a new command with the given timeout and a default name.
@@ -52,7 +50,8 @@ Command::Command(double timeout) : Command("", timeout) {}
* @param timeout the time (in seconds) before this command "times out"
* @see IsTimedOut()
*/
Command::Command(const std::string& name, double timeout) {
Command::Command(const llvm::Twine& name, double timeout)
: SendableBase(false) {
// We use -1.0 to indicate no timeout.
if (timeout < 0.0 && timeout != -1.0)
wpi_setWPIErrorWithContext(ParameterOutOfRange, "timeout < 0.0");
@@ -60,17 +59,14 @@ Command::Command(const std::string& name, double timeout) {
m_timeout = timeout;
// If name contains an empty string
if (name.length() == 0) {
m_name = std::string("Command_") + std::string(typeid(*this).name());
if (name.isTriviallyEmpty() ||
(name.isSingleStringRef() && name.getSingleStringRef().empty())) {
SetName("Command_" + llvm::Twine(typeid(*this).name()));
} else {
m_name = name;
SetName(name);
}
}
Command::~Command() {
if (m_runningListener != 0) m_runningEntry.RemoveListener(m_runningListener);
}
/**
* Get the ID (sequence number) for this command.
*
@@ -144,7 +140,6 @@ void Command::Removed() {
m_initialized = false;
m_canceled = false;
m_running = false;
if (m_runningEntry) m_runningEntry.SetBoolean(false);
}
/**
@@ -291,10 +286,16 @@ void Command::SetParent(CommandGroup* parent) {
} else {
LockChanges();
m_parent = parent;
if (m_isParentedEntry) m_isParentedEntry.SetBoolean(true);
}
}
/**
* Returns whether the command has a parent.
*
* @param True if the command has a parent.
*/
bool Command::IsParented() const { return m_parent != nullptr; }
/**
* Clears list of subsystem requirements.
*
@@ -317,7 +318,6 @@ void Command::ClearRequirements() { m_requirements.clear(); }
void Command::StartRunning() {
m_running = true;
m_startTime = -1;
if (m_runningEntry) m_runningEntry.SetBoolean(true);
}
/**
@@ -422,28 +422,17 @@ void Command::SetRunWhenDisabled(bool run) { m_runWhenDisabled = run; }
*/
bool Command::WillRunWhenDisabled() const { return m_runWhenDisabled; }
std::string Command::GetName() const { return m_name; }
std::string Command::GetSmartDashboardType() const { return "Command"; }
void Command::InitTable(std::shared_ptr<nt::NetworkTable> subtable) {
if (m_runningListener != 0) m_runningEntry.RemoveListener(m_runningListener);
if (subtable) {
subtable->GetEntry(kName).SetString(GetName());
m_runningEntry = subtable->GetEntry(kRunning);
m_runningEntry.SetBoolean(IsRunning());
m_isParentedEntry = subtable->GetEntry(kIsParented);
m_isParentedEntry.SetBoolean(m_parent != nullptr);
m_runningListener = m_runningEntry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsBoolean()) return;
if (event.value->GetBoolean()) {
if (!IsRunning()) Start();
} else {
if (IsRunning()) Cancel();
}
},
NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
}
void Command::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Command");
builder.AddStringProperty(".name", [=]() { return GetName(); }, nullptr);
builder.AddBooleanProperty("running", [=]() { return IsRunning(); },
[=](bool value) {
if (value) {
if (!IsRunning()) Start();
} else {
if (IsRunning()) Cancel();
}
});
builder.AddBooleanProperty(".isParented", [=]() { return IsParented(); },
nullptr);
}

View File

@@ -7,6 +7,8 @@
#include "Commands/PIDCommand.h"
#include "SmartDashboard/SendableBuilder.h"
using namespace frc;
PIDCommand::PIDCommand(const std::string& name, double p, double i, double d,
@@ -65,9 +67,8 @@ double PIDCommand::GetSetpoint() const { return m_controller->GetSetpoint(); }
double PIDCommand::GetPosition() { return ReturnPIDInput(); }
std::string PIDCommand::GetSmartDashboardType() const { return "PIDCommand"; }
void PIDCommand::InitTable(std::shared_ptr<nt::NetworkTable> subtable) {
m_controller->InitTable(subtable);
Command::InitTable(subtable);
void PIDCommand::InitSendable(SendableBuilder& builder) {
m_controller->InitSendable(builder);
Command::InitSendable(builder);
builder.SetSmartDashboardType("PIDCommand");
}

View File

@@ -23,6 +23,7 @@ PIDSubsystem::PIDSubsystem(const std::string& name, double p, double i,
double d)
: Subsystem(name) {
m_controller = std::make_shared<PIDController>(p, i, d, this, this);
AddChild("PIDController", m_controller);
}
/**
@@ -38,6 +39,7 @@ PIDSubsystem::PIDSubsystem(const std::string& name, double p, double i,
double d, double f)
: Subsystem(name) {
m_controller = std::make_shared<PIDController>(p, i, d, f, this, this);
AddChild("PIDController", m_controller);
}
/**
@@ -58,6 +60,7 @@ PIDSubsystem::PIDSubsystem(const std::string& name, double p, double i,
: Subsystem(name) {
m_controller =
std::make_shared<PIDController>(p, i, d, f, this, this, period);
AddChild("PIDController", m_controller);
}
/**
@@ -72,6 +75,7 @@ PIDSubsystem::PIDSubsystem(const std::string& name, double p, double i,
PIDSubsystem::PIDSubsystem(double p, double i, double d)
: Subsystem("PIDSubsystem") {
m_controller = std::make_shared<PIDController>(p, i, d, this, this);
AddChild("PIDController", m_controller);
}
/**
@@ -87,6 +91,7 @@ PIDSubsystem::PIDSubsystem(double p, double i, double d)
PIDSubsystem::PIDSubsystem(double p, double i, double d, double f)
: Subsystem("PIDSubsystem") {
m_controller = std::make_shared<PIDController>(p, i, d, f, this, this);
AddChild("PIDController", m_controller);
}
/**
@@ -106,6 +111,7 @@ PIDSubsystem::PIDSubsystem(double p, double i, double d, double f,
: Subsystem("PIDSubsystem") {
m_controller =
std::make_shared<PIDController>(p, i, d, f, this, this, period);
AddChild("PIDController", m_controller);
}
/**
@@ -233,10 +239,3 @@ double PIDSubsystem::GetRate() { return ReturnPIDInput(); }
void PIDSubsystem::PIDWrite(double output) { UsePIDOutput(output); }
double PIDSubsystem::PIDGet() { return ReturnPIDInput(); }
std::string PIDSubsystem::GetSmartDashboardType() const { return "PIDCommand"; }
void PIDSubsystem::InitTable(std::shared_ptr<nt::NetworkTable> subtable) {
m_controller->InitTable(subtable);
Subsystem::InitTable(subtable);
}

View File

@@ -13,11 +13,15 @@
#include "Buttons/ButtonScheduler.h"
#include "Commands/Subsystem.h"
#include "HLUsageReporting.h"
#include "SmartDashboard/SendableBuilder.h"
#include "WPIErrors.h"
using namespace frc;
Scheduler::Scheduler() { HLUsageReporting::ReportScheduler(); }
Scheduler::Scheduler() {
HLUsageReporting::ReportScheduler();
SetName("Scheduler");
}
/**
* Returns the Scheduler, creating it if one does not exist.
@@ -161,8 +165,6 @@ void Scheduler::Run() {
}
lock->ConfirmCommand();
}
UpdateTable();
}
/**
@@ -223,12 +225,12 @@ void Scheduler::ResetAll() {
m_cancelEntry = nt::NetworkTableEntry();
}
/**
* Update the network tables associated with the Scheduler object on the
* SmartDashboard.
*/
void Scheduler::UpdateTable() {
if (m_cancelEntry && m_namesEntry && m_idsEntry) {
void Scheduler::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Scheduler");
m_namesEntry = builder.GetEntry("Names");
m_idsEntry = builder.GetEntry("Ids");
m_cancelEntry = builder.GetEntry("Cancel");
builder.SetUpdateTable([=]() {
// Get the list of possible commands to cancel
auto new_toCancel = m_cancelEntry.GetValue();
if (new_toCancel)
@@ -264,26 +266,5 @@ void Scheduler::UpdateTable() {
m_namesEntry.SetStringArray(commands);
m_idsEntry.SetDoubleArray(ids);
}
}
}
std::string Scheduler::GetName() const { return "Scheduler"; }
std::string Scheduler::GetType() const { return "Scheduler"; }
std::string Scheduler::GetSmartDashboardType() const { return "Scheduler"; }
void Scheduler::InitTable(std::shared_ptr<nt::NetworkTable> subTable) {
if (subTable) {
m_namesEntry = subTable->GetEntry("Names");
m_idsEntry = subTable->GetEntry("Ids");
m_cancelEntry = subTable->GetEntry("Cancel");
m_namesEntry.SetStringArray(commands);
m_idsEntry.SetDoubleArray(ids);
m_cancelEntry.SetDoubleArray(toCancel);
} else {
m_namesEntry = nt::NetworkTableEntry();
m_idsEntry = nt::NetworkTableEntry();
m_cancelEntry = nt::NetworkTableEntry();
}
});
}

View File

@@ -9,6 +9,8 @@
#include "Commands/Command.h"
#include "Commands/Scheduler.h"
#include "LiveWindow/LiveWindow.h"
#include "SmartDashboard/SendableBuilder.h"
#include "WPIErrors.h"
using namespace frc;
@@ -18,10 +20,11 @@ using namespace frc;
*
* @param name the name of the subsystem
*/
Subsystem::Subsystem(const std::string& name) {
m_name = name;
Subsystem::Subsystem(const llvm::Twine& name) {
SetName(name, name);
Scheduler::GetInstance()->RegisterSubsystem(this);
}
/**
* Initialize the default command for this subsystem.
*
@@ -64,14 +67,6 @@ void Subsystem::SetDefaultCommand(Command* command) {
m_defaultCommand = command;
}
if (m_hasDefaultEntry && m_defaultEntry) {
if (m_defaultCommand != nullptr) {
m_hasDefaultEntry.SetBoolean(true);
m_defaultEntry.SetString(m_defaultCommand->GetName());
} else {
m_hasDefaultEntry.SetBoolean(false);
}
}
}
/**
@@ -87,6 +82,20 @@ Command* Subsystem::GetDefaultCommand() {
return m_defaultCommand;
}
/**
* Returns the default command name, or empty string is there is none.
*
* @return the default command name
*/
llvm::StringRef Subsystem::GetDefaultCommandName() {
Command* defaultCommand = GetDefaultCommand();
if (defaultCommand) {
return defaultCommand->GetName();
} else {
return llvm::StringRef();
}
}
/**
* Sets the current command.
*
@@ -104,6 +113,20 @@ void Subsystem::SetCurrentCommand(Command* command) {
*/
Command* Subsystem::GetCurrentCommand() const { return m_currentCommand; }
/**
* Returns the current command name, or empty string if no current command.
*
* @return the current command name
*/
llvm::StringRef Subsystem::GetCurrentCommandName() const {
Command* currentCommand = GetCurrentCommand();
if (currentCommand) {
return currentCommand->GetName();
} else {
return llvm::StringRef();
}
}
/**
* When the run method of the scheduler is called this method will be called.
*/
@@ -118,41 +141,78 @@ void Subsystem::Periodic() {}
* avoid that situation.
*/
void Subsystem::ConfirmCommand() {
if (m_currentCommandChanged) {
if (m_hasCommandEntry && m_commandEntry) {
if (m_currentCommand != nullptr) {
m_hasCommandEntry.SetBoolean(true);
m_commandEntry.SetString(m_currentCommand->GetName());
} else {
m_hasCommandEntry.SetBoolean(false);
}
}
m_currentCommandChanged = false;
}
if (m_currentCommandChanged) m_currentCommandChanged = false;
}
std::string Subsystem::GetName() const { return m_name; }
std::string Subsystem::GetSmartDashboardType() const { return "Subsystem"; }
void Subsystem::InitTable(std::shared_ptr<nt::NetworkTable> subtable) {
if (subtable != nullptr) {
m_hasDefaultEntry = subtable->GetEntry("hasDefault");
m_defaultEntry = subtable->GetEntry("default");
m_hasCommandEntry = subtable->GetEntry("hasCommand");
m_commandEntry = subtable->GetEntry("command");
if (m_defaultCommand != nullptr) {
m_hasDefaultEntry.SetBoolean(true);
m_defaultEntry.SetString(m_defaultCommand->GetName());
} else {
m_hasDefaultEntry.SetBoolean(false);
}
if (m_currentCommand != nullptr) {
m_hasCommandEntry.SetBoolean(true);
m_commandEntry.SetString(m_currentCommand->GetName());
} else {
m_hasCommandEntry.SetBoolean(false);
}
}
/**
* Associate a Sendable with this Subsystem.
* Also update the child's name.
*
* @param name name to give child
* @param child sendable
*/
void Subsystem::AddChild(const llvm::Twine& name,
std::shared_ptr<Sendable> child) {
AddChild(name, *child);
}
/**
* Associate a Sendable with this Subsystem.
* Also update the child's name.
*
* @param name name to give child
* @param child sendable
*/
void Subsystem::AddChild(const llvm::Twine& name, Sendable* child) {
AddChild(name, *child);
}
/**
* Associate a Sendable with this Subsystem.
* Also update the child's name.
*
* @param name name to give child
* @param child sendable
*/
void Subsystem::AddChild(const llvm::Twine& name, Sendable& child) {
child.SetName(GetSubsystem(), name);
LiveWindow::GetInstance()->Add(&child);
}
/**
* Associate a {@link Sendable} with this Subsystem.
*
* @param child sendable
*/
void Subsystem::AddChild(std::shared_ptr<Sendable> child) { AddChild(*child); }
/**
* Associate a {@link Sendable} with this Subsystem.
*
* @param child sendable
*/
void Subsystem::AddChild(Sendable* child) { AddChild(*child); }
/**
* Associate a {@link Sendable} with this Subsystem.
*
* @param child sendable
*/
void Subsystem::AddChild(Sendable& child) {
child.SetSubsystem(GetSubsystem());
LiveWindow::GetInstance()->Add(&child);
}
void Subsystem::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Subsystem");
builder.AddBooleanProperty(
"hasDefault", [=]() { return m_defaultCommand != nullptr; }, nullptr);
builder.AddStringProperty("default",
[=]() { return GetDefaultCommandName(); }, nullptr);
builder.AddBooleanProperty(
"hasCommand", [=]() { return m_currentCommand != nullptr; }, nullptr);
builder.AddStringProperty("command",
[=]() { return GetCurrentCommandName(); }, nullptr);
}

View File

@@ -12,6 +12,7 @@
#include <HAL/Ports.h>
#include <HAL/Solenoid.h>
#include "SmartDashboard/SendableBuilder.h"
#include "WPIErrors.h"
using namespace frc;
@@ -32,13 +33,7 @@ Compressor::Compressor(int pcmID) : m_module(pcmID) {
SetClosedLoopControl(true);
HAL_Report(HALUsageReporting::kResourceType_Compressor, pcmID);
}
/**
* Destructor.
*/
Compressor::~Compressor() {
if (m_enabledListener != 0) m_enabledEntry.RemoveListener(m_enabledListener);
SetName("Compressor", pcmID);
}
/**
@@ -308,42 +303,15 @@ void Compressor::ClearAllPCMStickyFaults() {
}
}
void Compressor::UpdateTable() {
if (m_enabledEntry) m_enabledEntry.SetBoolean(Enabled());
if (m_pressureSwitchEntry)
m_pressureSwitchEntry.SetBoolean(GetPressureSwitchValue());
}
void Compressor::StartLiveWindowMode() {
if (m_enabledEntry) {
m_enabledListener = m_enabledEntry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsBoolean()) return;
if (event.value->GetBoolean())
Start();
else
Stop();
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
}
}
void Compressor::StopLiveWindowMode() {
if (m_enabledListener != 0) {
m_enabledEntry.RemoveListener(m_enabledListener);
m_enabledListener = 0;
}
}
std::string Compressor::GetSmartDashboardType() const { return "Compressor"; }
void Compressor::InitTable(std::shared_ptr<nt::NetworkTable> subTable) {
if (subTable) {
m_enabledEntry = subTable->GetEntry("Enabled");
m_pressureSwitchEntry = subTable->GetEntry("Pressure switch");
UpdateTable();
} else {
m_enabledEntry = nt::NetworkTableEntry();
m_pressureSwitchEntry = nt::NetworkTableEntry();
}
void Compressor::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Compressor");
builder.AddBooleanProperty("Enabled", [=]() { return Enabled(); },
[=](bool value) {
if (value)
Start();
else
Stop();
});
builder.AddBooleanProperty(
"Pressure switch", [=]() { return GetPressureSwitchValue(); }, nullptr);
}

View File

@@ -11,6 +11,7 @@
#include "AnalogTrigger.h"
#include "DigitalInput.h"
#include "SmartDashboard/SendableBuilder.h"
#include "WPIErrors.h"
using namespace frc;
@@ -36,6 +37,7 @@ Counter::Counter(Mode mode) {
SetMaxPeriod(.5);
HAL_Report(HALUsageReporting::kResourceType_Counter, m_index, mode);
SetName("Counter", m_index);
}
/**
@@ -181,6 +183,7 @@ Counter::~Counter() {
void Counter::SetUpSource(int channel) {
if (StatusIsFatal()) return;
SetUpSource(std::make_shared<DigitalInput>(channel));
AddChild(m_upSource);
}
/**
@@ -287,6 +290,7 @@ void Counter::ClearUpSource() {
void Counter::SetDownSource(int channel) {
if (StatusIsFatal()) return;
SetDownSource(std::make_shared<DigitalInput>(channel));
AddChild(m_downSource);
}
/**
@@ -603,21 +607,7 @@ void Counter::SetReverseDirection(bool reverseDirection) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
void Counter::UpdateTable() {
if (m_valueEntry) m_valueEntry.SetDouble(Get());
}
void Counter::StartLiveWindowMode() {}
void Counter::StopLiveWindowMode() {}
std::string Counter::GetSmartDashboardType() const { return "Counter"; }
void Counter::InitTable(std::shared_ptr<nt::NetworkTable> subTable) {
if (subTable) {
m_valueEntry = subTable->GetEntry("Value");
UpdateTable();
} else {
m_valueEntry = nt::NetworkTableEntry();
}
void Counter::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Counter");
builder.AddDoubleProperty("Value", [=]() { return Get(); }, nullptr);
}

View File

@@ -35,6 +35,7 @@ DigitalGlitchFilter::DigitalGlitchFilter() {
*index = true;
HAL_Report(HALUsageReporting::kResourceType_DigitalFilter, m_channelIndex);
SetName("DigitalGlitchFilter", m_channelIndex);
}
DigitalGlitchFilter::~DigitalGlitchFilter() {
@@ -199,3 +200,5 @@ uint64_t DigitalGlitchFilter::GetPeriodNanoSeconds() {
return static_cast<uint64_t>(fpgaCycles) * 1000L /
static_cast<uint64_t>(HAL_GetSystemClockTicksPerMicrosecond() / 4);
}
void DigitalGlitchFilter::InitSendable(SendableBuilder&) {}

View File

@@ -15,7 +15,7 @@
#include <llvm/SmallString.h>
#include <llvm/raw_ostream.h>
#include "LiveWindow/LiveWindow.h"
#include "SmartDashboard/SendableBuilder.h"
#include "WPIErrors.h"
using namespace frc;
@@ -49,8 +49,8 @@ DigitalInput::DigitalInput(int channel) {
return;
}
LiveWindow::GetInstance()->AddSensor("DigitalInput", channel, this);
HAL_Report(HALUsageReporting::kResourceType_DigitalInput, channel);
SetName("DigitalInput", channel);
}
/**
@@ -103,23 +103,7 @@ AnalogTriggerType DigitalInput::GetAnalogTriggerTypeForRouting() const {
return (AnalogTriggerType)0;
}
void DigitalInput::UpdateTable() {
if (m_valueEntry) m_valueEntry.SetBoolean(Get());
}
void DigitalInput::StartLiveWindowMode() {}
void DigitalInput::StopLiveWindowMode() {}
std::string DigitalInput::GetSmartDashboardType() const {
return "DigitalInput";
}
void DigitalInput::InitTable(std::shared_ptr<nt::NetworkTable> subTable) {
if (subTable) {
m_valueEntry = subTable->GetEntry("Value");
UpdateTable();
} else {
m_valueEntry = nt::NetworkTableEntry();
}
void DigitalInput::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Digital Input");
builder.AddBooleanProperty("Value", [=]() { return Get(); }, nullptr);
}

View File

@@ -15,6 +15,8 @@
#include <llvm/SmallString.h>
#include <llvm/raw_ostream.h>
#include "SensorBase.h"
#include "SmartDashboard/SendableBuilder.h"
#include "WPIErrors.h"
using namespace frc;
@@ -32,7 +34,7 @@ DigitalOutput::DigitalOutput(int channel) {
llvm::raw_svector_ostream buf(str);
m_pwmGenerator = HAL_kInvalidHandle;
if (!CheckDigitalChannel(channel)) {
if (!SensorBase::CheckDigitalChannel(channel)) {
buf << "Digital Channel " << channel;
wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, buf.str());
m_channel = std::numeric_limits<int>::max();
@@ -51,13 +53,13 @@ DigitalOutput::DigitalOutput(int channel) {
}
HAL_Report(HALUsageReporting::kResourceType_DigitalOutput, channel);
SetName("DigitalOutput", channel);
}
/**
* Free the resources associated with a digital output.
*/
DigitalOutput::~DigitalOutput() {
if (m_valueListener != 0) m_valueEntry.RemoveListener(m_valueListener);
if (StatusIsFatal()) return;
// Disable the PWM in case it was running.
DisablePWM();
@@ -190,7 +192,8 @@ void DigitalOutput::DisablePWM() {
int32_t status = 0;
// Disable the output by routing to a dead bit.
HAL_SetDigitalPWMOutputChannel(m_pwmGenerator, kDigitalChannels, &status);
HAL_SetDigitalPWMOutputChannel(m_pwmGenerator, SensorBase::kDigitalChannels,
&status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
HAL_FreeDigitalPWM(m_pwmGenerator, &status);
@@ -215,52 +218,8 @@ void DigitalOutput::UpdateDutyCycle(double dutyCycle) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* @return The HAL Handle to the specified source.
*/
HAL_Handle DigitalOutput::GetPortHandleForRouting() const { return m_handle; }
/**
* Is source an AnalogTrigger
*/
bool DigitalOutput::IsAnalogTrigger() const { return false; }
/**
* @return The type of analog trigger output to be used. 0 for Digitals
*/
AnalogTriggerType DigitalOutput::GetAnalogTriggerTypeForRouting() const {
return (AnalogTriggerType)0;
}
void DigitalOutput::UpdateTable() {}
void DigitalOutput::StartLiveWindowMode() {
if (m_valueEntry) {
m_valueListener = m_valueEntry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsBoolean()) return;
Set(event.value->GetBoolean());
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
}
}
void DigitalOutput::StopLiveWindowMode() {
if (m_valueListener != 0) {
m_valueEntry.RemoveListener(m_valueListener);
m_valueListener = 0;
}
}
std::string DigitalOutput::GetSmartDashboardType() const {
return "Digital Output";
}
void DigitalOutput::InitTable(std::shared_ptr<nt::NetworkTable> subTable) {
if (subTable) {
m_valueEntry = subTable->GetEntry("Value");
UpdateTable();
} else {
m_valueEntry = nt::NetworkTableEntry();
}
void DigitalOutput::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Digital Output");
builder.AddBooleanProperty("Value", [=]() { return Get(); },
[=](bool value) { Set(value); });
}

View File

@@ -13,7 +13,8 @@
#include <llvm/SmallString.h>
#include <llvm/raw_ostream.h>
#include "LiveWindow/LiveWindow.h"
#include "SensorBase.h"
#include "SmartDashboard/SendableBuilder.h"
#include "WPIErrors.h"
using namespace frc;
@@ -27,7 +28,7 @@ using namespace frc;
* @param reverseChannel The reverse channel number on the PCM (0..7).
*/
DoubleSolenoid::DoubleSolenoid(int forwardChannel, int reverseChannel)
: DoubleSolenoid(GetDefaultSolenoidModule(), forwardChannel,
: DoubleSolenoid(SensorBase::GetDefaultSolenoidModule(), forwardChannel,
reverseChannel) {}
/**
@@ -44,17 +45,17 @@ DoubleSolenoid::DoubleSolenoid(int moduleNumber, int forwardChannel,
m_reverseChannel(reverseChannel) {
llvm::SmallString<32> str;
llvm::raw_svector_ostream buf(str);
if (!CheckSolenoidModule(m_moduleNumber)) {
if (!SensorBase::CheckSolenoidModule(m_moduleNumber)) {
buf << "Solenoid Module " << m_moduleNumber;
wpi_setWPIErrorWithContext(ModuleIndexOutOfRange, buf.str());
return;
}
if (!CheckSolenoidChannel(m_forwardChannel)) {
if (!SensorBase::CheckSolenoidChannel(m_forwardChannel)) {
buf << "Solenoid Module " << m_forwardChannel;
wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, buf.str());
return;
}
if (!CheckSolenoidChannel(m_reverseChannel)) {
if (!SensorBase::CheckSolenoidChannel(m_reverseChannel)) {
buf << "Solenoid Module " << m_reverseChannel;
wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, buf.str());
return;
@@ -89,8 +90,7 @@ DoubleSolenoid::DoubleSolenoid(int moduleNumber, int forwardChannel,
m_moduleNumber);
HAL_Report(HALUsageReporting::kResourceType_Solenoid, m_reverseChannel,
m_moduleNumber);
LiveWindow::GetInstance()->AddActuator("DoubleSolenoid", m_moduleNumber,
m_forwardChannel, this);
SetName("DoubleSolenoid", m_moduleNumber, m_forwardChannel);
}
/**
@@ -99,7 +99,6 @@ DoubleSolenoid::DoubleSolenoid(int moduleNumber, int forwardChannel,
DoubleSolenoid::~DoubleSolenoid() {
HAL_FreeSolenoidPort(m_forwardHandle);
HAL_FreeSolenoidPort(m_reverseHandle);
if (m_valueListener != 0) m_valueEntry.RemoveListener(m_valueListener);
}
/**
@@ -183,56 +182,27 @@ bool DoubleSolenoid::IsRevSolenoidBlackListed() const {
return (blackList & m_reverseMask) != 0;
}
void DoubleSolenoid::UpdateTable() {
if (m_valueEntry) {
switch (Get()) {
case kForward:
m_valueEntry.SetString("Forward");
break;
case kReverse:
m_valueEntry.SetString("Reverse");
break;
default:
m_valueEntry.SetString("Off");
break;
}
}
}
void DoubleSolenoid::StartLiveWindowMode() {
Set(kOff);
if (m_valueEntry) {
m_valueListener = m_valueEntry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsString()) return;
Value lvalue = kOff;
if (event.value->GetString() == "Forward")
lvalue = kForward;
else if (event.value->GetString() == "Reverse")
lvalue = kReverse;
Set(lvalue);
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
}
}
void DoubleSolenoid::StopLiveWindowMode() {
Set(kOff);
if (m_valueListener != 0) {
m_valueEntry.RemoveListener(m_valueListener);
m_valueListener = 0;
}
}
std::string DoubleSolenoid::GetSmartDashboardType() const {
return "Double Solenoid";
}
void DoubleSolenoid::InitTable(std::shared_ptr<nt::NetworkTable> subTable) {
if (subTable) {
m_valueEntry = subTable->GetEntry("Value");
UpdateTable();
} else {
m_valueEntry = nt::NetworkTableEntry();
}
void DoubleSolenoid::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Double Solenoid");
builder.SetSafeState([=]() { Set(kOff); });
builder.AddSmallStringProperty(
"Value",
[=](llvm::SmallVectorImpl<char>& buf) -> llvm::StringRef {
switch (Get()) {
case kForward:
return "Forward";
case kReverse:
return "Reverse";
default:
return "Off";
}
},
[=](llvm::StringRef value) {
Value lvalue = kOff;
if (value == "Forward")
lvalue = kForward;
else if (value == "Reverse")
lvalue = kReverse;
Set(lvalue);
});
}

View File

@@ -11,6 +11,7 @@
#include <HAL/HAL.h>
#include "SmartDashboard/SendableBuilder.h"
#include "SpeedController.h"
using namespace frc;
@@ -23,7 +24,13 @@ using namespace frc;
*/
DifferentialDrive::DifferentialDrive(SpeedController& leftMotor,
SpeedController& rightMotor)
: m_leftMotor(leftMotor), m_rightMotor(rightMotor) {}
: m_leftMotor(leftMotor), m_rightMotor(rightMotor) {
AddChild(&m_leftMotor);
AddChild(&m_rightMotor);
static int instances = 0;
++instances;
SetName("DifferentialDrive", instances);
}
/**
* Arcade drive method for differential drive platform.
@@ -249,3 +256,13 @@ void DifferentialDrive::StopMotor() {
void DifferentialDrive::GetDescription(llvm::raw_ostream& desc) const {
desc << "DifferentialDrive";
}
void DifferentialDrive::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("DifferentialDrive");
builder.AddDoubleProperty("Left Motor Speed",
[=]() { return m_leftMotor.Get(); },
[=](double value) { m_leftMotor.Set(value); });
builder.AddDoubleProperty("Right Motor Speed",
[=]() { return m_rightMotor.Get(); },
[=](double value) { m_rightMotor.Set(value); });
}

View File

@@ -12,6 +12,7 @@
#include <HAL/HAL.h>
#include "SmartDashboard/SendableBuilder.h"
#include "SpeedController.h"
using namespace frc;
@@ -62,6 +63,12 @@ KilloughDrive::KilloughDrive(SpeedController& leftMotor,
std::sin(rightMotorAngle * (kPi / 180.0))};
m_backVec = {std::cos(backMotorAngle * (kPi / 180.0)),
std::sin(backMotorAngle * (kPi / 180.0))};
AddChild(&m_leftMotor);
AddChild(&m_rightMotor);
AddChild(&m_backMotor);
static int instances = 0;
++instances;
SetName("KilloughDrive", instances);
}
/**
@@ -146,3 +153,16 @@ void KilloughDrive::StopMotor() {
void KilloughDrive::GetDescription(llvm::raw_ostream& desc) const {
desc << "KilloughDrive";
}
void KilloughDrive::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("KilloughDrive");
builder.AddDoubleProperty("Left Motor Speed",
[=]() { return m_leftMotor.Get(); },
[=](double value) { m_leftMotor.Set(value); });
builder.AddDoubleProperty("Right Motor Speed",
[=]() { return m_rightMotor.Get(); },
[=](double value) { m_rightMotor.Set(value); });
builder.AddDoubleProperty("Back Motor Speed",
[=]() { return m_backMotor.Get(); },
[=](double value) { m_backMotor.Set(value); });
}

View File

@@ -13,6 +13,7 @@
#include <HAL/HAL.h>
#include "Drive/Vector2d.h"
#include "SmartDashboard/SendableBuilder.h"
#include "SpeedController.h"
using namespace frc;
@@ -31,7 +32,15 @@ MecanumDrive::MecanumDrive(SpeedController& frontLeftMotor,
: m_frontLeftMotor(frontLeftMotor),
m_rearLeftMotor(rearLeftMotor),
m_frontRightMotor(frontRightMotor),
m_rearRightMotor(rearRightMotor) {}
m_rearRightMotor(rearRightMotor) {
AddChild(&m_frontLeftMotor);
AddChild(&m_rearLeftMotor);
AddChild(&m_frontRightMotor);
AddChild(&m_rearRightMotor);
static int instances = 0;
++instances;
SetName("MecanumDrive", instances);
}
/**
* Drive method for Mecanum platform.
@@ -118,3 +127,19 @@ void MecanumDrive::StopMotor() {
void MecanumDrive::GetDescription(llvm::raw_ostream& desc) const {
desc << "MecanumDrive";
}
void MecanumDrive::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("MecanumDrive");
builder.AddDoubleProperty("Front Left Motor Speed",
[=]() { return m_frontLeftMotor.Get(); },
[=](double value) { m_frontLeftMotor.Set(value); });
builder.AddDoubleProperty(
"Front Right Motor Speed", [=]() { return m_frontRightMotor.Get(); },
[=](double value) { m_frontRightMotor.Set(value); });
builder.AddDoubleProperty("Rear Left Motor Speed",
[=]() { return m_rearLeftMotor.Get(); },
[=](double value) { m_rearLeftMotor.Set(value); });
builder.AddDoubleProperty("Rear Right Motor Speed",
[=]() { return m_rearRightMotor.Get(); },
[=](double value) { m_rearRightMotor.Set(value); });
}

View File

@@ -10,7 +10,7 @@
#include <HAL/HAL.h>
#include "DigitalInput.h"
#include "LiveWindow/LiveWindow.h"
#include "SmartDashboard/SendableBuilder.h"
#include "WPIErrors.h"
using namespace frc;
@@ -45,8 +45,7 @@ void Encoder::InitEncoder(bool reverseDirection, EncodingType encodingType) {
HAL_Report(HALUsageReporting::kResourceType_Encoder, GetFPGAIndex(),
encodingType);
LiveWindow::GetInstance()->AddSensor("Encoder", m_aSource->GetChannel(),
this);
SetName("Encoder", m_aSource->GetChannel());
}
/**
@@ -77,6 +76,8 @@ Encoder::Encoder(int aChannel, int bChannel, bool reverseDirection,
m_aSource = std::make_shared<DigitalInput>(aChannel);
m_bSource = std::make_shared<DigitalInput>(bChannel);
InitEncoder(reverseDirection, encodingType);
AddChild(m_aSource);
AddChild(m_bSource);
}
/**
@@ -371,6 +372,19 @@ void Encoder::SetDistancePerPulse(double distancePerPulse) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
/**
* Get the distance per pulse for this encoder.
*
* @return The scale factor that will be used to convert pulses to useful units.
*/
double Encoder::GetDistancePerPulse() const {
if (StatusIsFatal()) return 0.0;
int32_t status = 0;
double distancePerPulse = HAL_GetEncoderDistancePerPulse(m_encoder, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
return distancePerPulse;
}
/**
* Set the direction sensing for this encoder.
*
@@ -479,41 +493,18 @@ int Encoder::GetFPGAIndex() const {
return val;
}
void Encoder::UpdateTable() {
if (m_speedEntry) m_speedEntry.SetDouble(GetRate());
if (m_distanceEntry) m_distanceEntry.SetDouble(GetDistance());
if (m_distancePerTickEntry) {
int32_t status = 0;
double distancePerPulse =
HAL_GetEncoderDistancePerPulse(m_encoder, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
m_distancePerTickEntry.SetDouble(distancePerPulse);
}
}
void Encoder::StartLiveWindowMode() {}
void Encoder::StopLiveWindowMode() {}
std::string Encoder::GetSmartDashboardType() const {
void Encoder::InitSendable(SendableBuilder& builder) {
int32_t status = 0;
HAL_EncoderEncodingType type = HAL_GetEncoderEncodingType(m_encoder, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
if (type == HAL_EncoderEncodingType::HAL_Encoder_k4X)
return "Quadrature Encoder";
builder.SetSmartDashboardType("Quadrature Encoder");
else
return "Encoder";
}
builder.SetSmartDashboardType("Encoder");
void Encoder::InitTable(std::shared_ptr<nt::NetworkTable> subTable) {
if (subTable) {
m_speedEntry = subTable->GetEntry("Speed");
m_distanceEntry = subTable->GetEntry("Distance");
m_distancePerTickEntry = subTable->GetEntry("Distance per Tick");
UpdateTable();
} else {
m_speedEntry = nt::NetworkTableEntry();
m_distanceEntry = nt::NetworkTableEntry();
m_distancePerTickEntry = nt::NetworkTableEntry();
}
builder.AddDoubleProperty("Speed", [=]() { return GetRate(); }, nullptr);
builder.AddDoubleProperty("Distance", [=]() { return GetDistance(); },
nullptr);
builder.AddDoubleProperty("Distance per Tick",
[=]() { return GetDistancePerPulse(); }, nullptr);
}

View File

@@ -7,7 +7,7 @@
#include "GearTooth.h"
#include "LiveWindow/LiveWindow.h"
#include "SmartDashboard/SendableBuilder.h"
using namespace frc;
@@ -32,7 +32,7 @@ void GearTooth::EnableDirectionSensing(bool directionSensitive) {
*/
GearTooth::GearTooth(int channel, bool directionSensitive) : Counter(channel) {
EnableDirectionSensing(directionSensitive);
LiveWindow::GetInstance()->AddSensor("GearTooth", channel, this);
SetName("GearTooth", channel);
}
/**
@@ -48,6 +48,7 @@ GearTooth::GearTooth(int channel, bool directionSensitive) : Counter(channel) {
GearTooth::GearTooth(DigitalSource* source, bool directionSensitive)
: Counter(source) {
EnableDirectionSensing(directionSensitive);
SetName("GearTooth", source->GetChannel());
}
/**
@@ -64,6 +65,10 @@ GearTooth::GearTooth(std::shared_ptr<DigitalSource> source,
bool directionSensitive)
: Counter(source) {
EnableDirectionSensing(directionSensitive);
SetName("GearTooth", source->GetChannel());
}
std::string GearTooth::GetSmartDashboardType() const { return "GearTooth"; }
void GearTooth::InitSendable(SendableBuilder& builder) {
Counter::InitSendable(builder);
builder.SetSmartDashboardType("Gear Tooth");
}

View File

@@ -7,7 +7,7 @@
#include "GyroBase.h"
#include "LiveWindow/LiveWindow.h"
#include "SmartDashboard/SendableBuilder.h"
#include "WPIErrors.h"
using namespace frc;
@@ -29,21 +29,7 @@ double GyroBase::PIDGet() {
}
}
void GyroBase::UpdateTable() {
if (m_valueEntry) m_valueEntry.SetDouble(GetAngle());
}
void GyroBase::StartLiveWindowMode() {}
void GyroBase::StopLiveWindowMode() {}
std::string GyroBase::GetSmartDashboardType() const { return "Gyro"; }
void GyroBase::InitTable(std::shared_ptr<nt::NetworkTable> subTable) {
if (subTable) {
m_valueEntry = subTable->GetEntry("Value");
UpdateTable();
} else {
m_valueEntry = nt::NetworkTableEntry();
}
void GyroBase::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Gyro");
builder.AddDoubleProperty("Value", [=]() { return GetAngle(); }, nullptr);
}

View File

@@ -12,6 +12,7 @@
#include <HAL/HAL.h>
#include <llvm/raw_ostream.h>
#include "Commands/Scheduler.h"
#include "LiveWindow/LiveWindow.h"
using namespace frc;
@@ -191,4 +192,5 @@ void IterativeRobotBase::LoopFunc() {
TestPeriodic();
}
RobotPeriodic();
LiveWindow::GetInstance()->UpdateValues();
}

View File

@@ -9,8 +9,6 @@
#include <HAL/HAL.h>
#include "LiveWindow/LiveWindow.h"
using namespace frc;
/**
@@ -35,5 +33,5 @@ Jaguar::Jaguar(int channel) : PWMSpeedController(channel) {
SetZeroLatch();
HAL_Report(HALUsageReporting::kResourceType_Jaguar, GetChannel());
LiveWindow::GetInstance()->AddActuator("Jaguar", GetChannel(), this);
SetName("Jaguar", GetChannel());
}

View File

@@ -9,14 +9,52 @@
#include <algorithm>
#include <llvm/DenseMap.h>
#include <llvm/SmallString.h>
#include <llvm/raw_ostream.h>
#include <support/mutex.h>
#include "Commands/Scheduler.h"
#include "SmartDashboard/SendableBuilderImpl.h"
#include "networktables/NetworkTable.h"
#include "networktables/NetworkTableEntry.h"
#include "networktables/NetworkTableInstance.h"
using namespace frc;
using llvm::Twine;
struct LiveWindow::Impl {
Impl();
struct Component {
std::shared_ptr<Sendable> sendable;
Sendable* parent = nullptr;
SendableBuilderImpl builder;
bool firstTime = true;
bool telemetryEnabled = true;
};
wpi::mutex mutex;
llvm::DenseMap<void*, Component> components;
std::shared_ptr<nt::NetworkTable> liveWindowTable;
std::shared_ptr<nt::NetworkTable> statusTable;
nt::NetworkTableEntry enabledEntry;
bool startLiveWindow = false;
bool liveWindowEnabled = false;
bool telemetryEnabled = true;
};
LiveWindow::Impl::Impl()
: liveWindowTable(
nt::NetworkTableInstance::GetDefault().GetTable("LiveWindow")) {
statusTable = liveWindowTable->GetSubTable(".status");
enabledEntry = statusTable->GetEntry("LW Enabled");
}
/**
* Get an instance of the LiveWindow main class.
*
@@ -33,11 +71,11 @@ LiveWindow* LiveWindow::GetInstance() {
*
* Allocate the necessary tables.
*/
LiveWindow::LiveWindow() : m_scheduler(Scheduler::GetInstance()) {
m_liveWindowTable =
nt::NetworkTableInstance::GetDefault().GetTable("LiveWindow");
m_statusTable = m_liveWindowTable->GetSubTable(".status");
m_enabledEntry = m_statusTable->GetEntry("LW Enabled");
LiveWindow::LiveWindow() : m_impl(new Impl) {}
bool LiveWindow::IsEnabled() const {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
return m_impl->liveWindowEnabled;
}
/**
@@ -46,25 +84,21 @@ LiveWindow::LiveWindow() : m_scheduler(Scheduler::GetInstance()) {
* If it changes to enabled, start livewindow running otherwise stop it
*/
void LiveWindow::SetEnabled(bool enabled) {
if (m_enabled == enabled) return;
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
if (m_impl->liveWindowEnabled == enabled) return;
Scheduler* scheduler = Scheduler::GetInstance();
if (enabled) {
if (m_firstTime) {
InitializeLiveWindowComponents();
m_firstTime = false;
}
m_scheduler->SetEnabled(false);
m_scheduler->RemoveAll();
for (auto& elem : m_components) {
elem.first->StartLiveWindowMode();
}
scheduler->SetEnabled(false);
scheduler->RemoveAll();
} else {
for (auto& elem : m_components) {
elem.first->StopLiveWindowMode();
for (auto& i : m_impl->components) {
i.getSecond().builder.StopLiveWindowMode();
}
m_scheduler->SetEnabled(true);
scheduler->SetEnabled(true);
}
m_enabled = enabled;
m_enabledEntry.SetBoolean(m_enabled);
m_impl->startLiveWindow = enabled;
m_impl->liveWindowEnabled = enabled;
m_impl->enabledEntry.SetBoolean(enabled);
}
/**
@@ -74,41 +108,38 @@ void LiveWindow::SetEnabled(bool enabled) {
*
* @param subsystem The subsystem this component is part of.
* @param name The name of this component.
* @param component A LiveWindowSendable component that represents a sensor.
* @param component A Sendable component that represents a sensor.
*/
//@{
/**
* @brief Use a STL smart pointer to share ownership of component.
* @deprecated Use Sendable::SetName() instead.
*/
void LiveWindow::AddSensor(const std::string& subsystem,
const std::string& name,
std::shared_ptr<LiveWindowSendable> component) {
m_components[component].subsystem = subsystem;
m_components[component].name = name;
m_components[component].isSensor = true;
void LiveWindow::AddSensor(const llvm::Twine& subsystem,
const llvm::Twine& name,
std::shared_ptr<Sendable> component) {
Add(component);
component->SetName(subsystem, name);
}
/**
* @brief Pass a reference to LiveWindow and retain ownership of the component.
* @deprecated Use Sendable::SetName() instead.
*/
void LiveWindow::AddSensor(const std::string& subsystem,
const std::string& name,
LiveWindowSendable& component) {
AddSensor(subsystem, name,
std::shared_ptr<LiveWindowSendable>(&component,
[](LiveWindowSendable*) {}));
void LiveWindow::AddSensor(const llvm::Twine& subsystem,
const llvm::Twine& name, Sendable& component) {
Add(&component);
component.SetName(subsystem, name);
}
/**
* @brief Use a raw pointer to the LiveWindow.
* @deprecated Prefer smart pointers or references.
* @deprecated Use Sendable::SetName() instead.
*/
void LiveWindow::AddSensor(const std::string& subsystem,
const std::string& name,
LiveWindowSendable* component) {
AddSensor(subsystem, name,
std::shared_ptr<LiveWindowSendable>(
component, NullDeleter<LiveWindowSendable>()));
void LiveWindow::AddSensor(const llvm::Twine& subsystem,
const llvm::Twine& name, Sendable* component) {
Add(component);
component->SetName(subsystem, name);
}
//@}
@@ -116,87 +147,161 @@ void LiveWindow::AddSensor(const std::string& subsystem,
* @name AddActuator(subsystem, name, component)
*
* Add an Actuator associated with the subsystem and call it by the given name.
* @deprecated Use Sendable::SetName() instead.
*
* @param subsystem The subsystem this component is part of.
* @param name The name of this component.
* @param component A LiveWindowSendable component that represents a actuator.
* @param component A Sendable component that represents a actuator.
*/
//@{
/**
* @brief Use a STL smart pointer to share ownership of component.
*/
void LiveWindow::AddActuator(const std::string& subsystem,
const std::string& name,
std::shared_ptr<LiveWindowSendable> component) {
m_components[component].subsystem = subsystem;
m_components[component].name = name;
m_components[component].isSensor = false;
void LiveWindow::AddActuator(const llvm::Twine& subsystem,
const llvm::Twine& name,
std::shared_ptr<Sendable> component) {
Add(component);
component->SetName(subsystem, name);
}
/**
* @brief Pass a reference to LiveWindow and retain ownership of the component.
* @deprecated Use Sendable::SetName() instead.
*/
void LiveWindow::AddActuator(const std::string& subsystem,
const std::string& name,
LiveWindowSendable& component) {
AddActuator(subsystem, name,
std::shared_ptr<LiveWindowSendable>(&component,
[](LiveWindowSendable*) {}));
void LiveWindow::AddActuator(const llvm::Twine& subsystem,
const llvm::Twine& name, Sendable& component) {
Add(&component);
component.SetName(subsystem, name);
}
/**
* @brief Use a raw pointer to the LiveWindow.
* @deprecated Prefer smart pointers or references.
* @deprecated Use Sendable::SetName() instead.
*/
void LiveWindow::AddActuator(const std::string& subsystem,
const std::string& name,
LiveWindowSendable* component) {
AddActuator(subsystem, name,
std::shared_ptr<LiveWindowSendable>(
component, NullDeleter<LiveWindowSendable>()));
void LiveWindow::AddActuator(const llvm::Twine& subsystem,
const llvm::Twine& name, Sendable* component) {
Add(component);
component->SetName(subsystem, name);
}
//@}
/**
* Meant for internal use in other WPILib classes.
* @deprecated Use SensorBase::SetName() instead.
*/
void LiveWindow::AddSensor(std::string type, int channel,
LiveWindowSendable* component) {
llvm::SmallString<128> buf;
llvm::raw_svector_ostream oss(buf);
oss << type << "[" << channel << "]";
AddSensor("Ungrouped", oss.str(), component);
std::shared_ptr<LiveWindowSendable> component_stl(
component, NullDeleter<LiveWindowSendable>());
if (std::find(m_sensors.begin(), m_sensors.end(), component_stl) ==
m_sensors.end())
m_sensors.push_back(component_stl);
void LiveWindow::AddSensor(const llvm::Twine& type, int channel,
Sendable* component) {
Add(component);
component->SetName("Ungrouped",
type + Twine('[') + Twine(channel) + Twine(']'));
}
/**
* Meant for internal use in other WPILib classes.
* @deprecated Use SensorBase::SetName() instead.
*/
void LiveWindow::AddActuator(std::string type, int channel,
LiveWindowSendable* component) {
llvm::SmallString<128> buf;
llvm::raw_svector_ostream oss(buf);
oss << type << "[" << channel << "]";
AddActuator("Ungrouped", oss.str(),
std::shared_ptr<LiveWindowSendable>(component,
[](LiveWindowSendable*) {}));
void LiveWindow::AddActuator(const llvm::Twine& type, int channel,
Sendable* component) {
Add(component);
component->SetName("Ungrouped",
type + Twine('[') + Twine(channel) + Twine(']'));
}
/**
* Meant for internal use in other WPILib classes.
* @deprecated Use SensorBase::SetName() instead.
*/
void LiveWindow::AddActuator(std::string type, int module, int channel,
LiveWindowSendable* component) {
llvm::SmallString<128> buf;
llvm::raw_svector_ostream oss(buf);
oss << type << "[" << module << "," << channel << "]";
AddActuator("Ungrouped", oss.str(),
std::shared_ptr<LiveWindowSendable>(component,
[](LiveWindowSendable*) {}));
void LiveWindow::AddActuator(const llvm::Twine& type, int module, int channel,
Sendable* component) {
Add(component);
component->SetName("Ungrouped", type + Twine('[') + Twine(module) +
Twine(',') + Twine(channel) + Twine(']'));
}
/**
* Add a component to the LiveWindow.
*
* @param sendable component to add
*/
void LiveWindow::Add(std::shared_ptr<Sendable> sendable) {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
auto& comp = m_impl->components[sendable.get()];
comp.sendable = sendable;
}
/**
* Add a component to the LiveWindow.
*
* @param sendable component to add
*/
void LiveWindow::Add(Sendable* sendable) {
Add(std::shared_ptr<Sendable>(sendable, NullDeleter<Sendable>()));
}
/**
* Add a child component to a component.
*
* @param parent parent component
* @param child child component
*/
void LiveWindow::AddChild(Sendable* parent, std::shared_ptr<Sendable> child) {
AddChild(parent, child.get());
}
/**
* Add a child component to a component.
*
* @param parent parent component
* @param child child component
*/
void LiveWindow::AddChild(Sendable* parent, void* child) {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
auto& comp = m_impl->components[child];
comp.parent = parent;
comp.telemetryEnabled = false;
}
/**
* Remove the component from the LiveWindow.
*
* @param sendable component to remove
*/
void LiveWindow::Remove(Sendable* sendable) {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
m_impl->components.erase(sendable);
}
/**
* Enable telemetry for a single component.
*
* @param sendable component
*/
void LiveWindow::EnableTelemetry(Sendable* sendable) {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
// Re-enable global setting in case DisableAllTelemetry() was called.
m_impl->telemetryEnabled = true;
auto i = m_impl->components.find(sendable);
if (i != m_impl->components.end()) i->getSecond().telemetryEnabled = true;
}
/**
* Disable telemetry for a single component.
*
* @param sendable component
*/
void LiveWindow::DisableTelemetry(Sendable* sendable) {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
auto i = m_impl->components.find(sendable);
if (i != m_impl->components.end()) i->getSecond().telemetryEnabled = false;
}
/**
* Disable ALL telemetry.
*/
void LiveWindow::DisableAllTelemetry() {
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
m_impl->telemetryEnabled = false;
for (auto& i : m_impl->components) i.getSecond().telemetryEnabled = false;
}
/**
@@ -206,44 +311,41 @@ void LiveWindow::AddActuator(std::string type, int module, int channel,
* SmartDashboard widgets.
*/
void LiveWindow::UpdateValues() {
for (auto& elem : m_sensors) {
elem->UpdateTable();
}
}
std::lock_guard<wpi::mutex> lock(m_impl->mutex);
// Only do this if either LiveWindow mode or telemetry is enabled.
if (!m_impl->liveWindowEnabled && !m_impl->telemetryEnabled) return;
/**
* This method is called periodically to cause the sensors to send new values
* to the SmartDashboard.
*/
void LiveWindow::Run() {
if (m_enabled) {
UpdateValues();
}
}
for (auto& i : m_impl->components) {
auto& comp = i.getSecond();
if (comp.sendable && !comp.parent &&
(m_impl->liveWindowEnabled || comp.telemetryEnabled)) {
if (comp.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.
auto name = comp.sendable->GetName();
if (name.empty()) continue;
auto subsystem = comp.sendable->GetSubsystem();
auto ssTable = m_impl->liveWindowTable->GetSubTable(subsystem);
std::shared_ptr<NetworkTable> table;
// Treat name==subsystem as top level of subsystem
if (name == subsystem)
table = ssTable;
else
table = ssTable->GetSubTable(name);
table->GetEntry(".name").SetString(name);
comp.builder.SetTable(table);
comp.sendable->InitSendable(comp.builder);
ssTable->GetEntry(".type").SetString("LW Subsystem");
/**
* Initialize all the LiveWindow elements the first time we enter LiveWindow
* mode. By holding off creating the NetworkTable entries, it allows them to be
* redefined before the first time in LiveWindow mode. This allows default
* sensor and actuator values to be created that are replaced with the custom
* names from users calling addActuator and addSensor.
*/
void LiveWindow::InitializeLiveWindowComponents() {
for (auto& elem : m_components) {
std::shared_ptr<LiveWindowSendable> component = elem.first;
LiveWindowComponent c = elem.second;
std::string subsystem = c.subsystem;
std::string name = c.name;
m_liveWindowTable->GetSubTable(subsystem)->GetEntry(".type").SetString(
"LW Subsystem");
std::shared_ptr<NetworkTable> table(
m_liveWindowTable->GetSubTable(subsystem)->GetSubTable(name));
table->GetEntry(".type").SetString(component->GetSmartDashboardType());
table->GetEntry(".name").SetString(name);
table->GetEntry("Subsystem").SetString(subsystem);
component->InitTable(table);
if (c.isSensor) {
m_sensors.push_back(component);
comp.firstTime = false;
}
if (m_impl->startLiveWindow) comp.builder.StartLiveWindowMode();
comp.builder.UpdateTable();
}
}
m_impl->startLiveWindow = false;
}

View File

@@ -9,7 +9,7 @@
#include <HAL/HAL.h>
#include "LiveWindow/LiveWindow.h"
#include "SmartDashboard/SendableBuilder.h"
using namespace frc;
@@ -23,6 +23,8 @@ using namespace frc;
*/
NidecBrushless::NidecBrushless(int pwmChannel, int dioChannel)
: m_safetyHelper(this), m_dio(dioChannel), m_pwm(pwmChannel) {
AddChild(&m_dio);
AddChild(&m_pwm);
m_safetyHelper.SetExpiration(0.0);
m_safetyHelper.SetSafetyEnabled(false);
@@ -30,8 +32,8 @@ NidecBrushless::NidecBrushless(int pwmChannel, int dioChannel)
m_dio.SetPWMRate(15625);
m_dio.EnablePWM(0.5);
LiveWindow::GetInstance()->AddActuator("Nidec Brushless", pwmChannel, this);
HAL_Report(HALUsageReporting::kResourceType_NidecBrushless, pwmChannel);
SetName("Nidec Brushless", pwmChannel);
}
/**
@@ -145,44 +147,9 @@ void NidecBrushless::Enable() { m_disabled = false; }
*/
int NidecBrushless::GetChannel() const { return m_pwm.GetChannel(); }
/*
* Live Window code, only does anything if live window is activated.
*/
std::string NidecBrushless::GetSmartDashboardType() const {
return "Nidec Brushless";
}
void NidecBrushless::InitTable(std::shared_ptr<nt::NetworkTable> subtable) {
if (subtable) {
m_valueEntry = subtable->GetEntry("Value");
UpdateTable();
} else {
m_valueEntry = nt::NetworkTableEntry();
}
}
void NidecBrushless::UpdateTable() {
if (m_valueEntry) {
m_valueEntry.SetDouble(Get());
}
}
void NidecBrushless::StartLiveWindowMode() {
Set(0); // Stop for safety
if (m_valueEntry) {
m_valueListener = m_valueEntry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsDouble()) return;
Set(event.value->GetDouble());
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
}
}
void NidecBrushless::StopLiveWindowMode() {
Set(0); // Stop for safety
if (m_valueListener != 0) {
m_valueEntry.RemoveListener(m_valueListener);
m_valueListener = 0;
}
void NidecBrushless::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Nidec Brushless");
builder.SetSafeState([=]() { StopMotor(); });
builder.AddDoubleProperty("Value", [=]() { return Get(); },
[=](double value) { Set(value); });
}

View File

@@ -16,16 +16,10 @@
#include "Notifier.h"
#include "PIDOutput.h"
#include "PIDSource.h"
#include "SmartDashboard/SendableBuilder.h"
using namespace frc;
static const std::string kP = "p";
static const std::string kI = "i";
static const std::string kD = "d";
static const std::string kF = "f";
static const std::string kSetpoint = "setpoint";
static const std::string kEnabled = "enabled";
template <class T>
constexpr const T& clamp(const T& value, const T& low, const T& high) {
return std::max(low, std::min(value, high));
@@ -61,7 +55,8 @@ PIDController::PIDController(double Kp, double Ki, double Kd, PIDSource* source,
*/
PIDController::PIDController(double Kp, double Ki, double Kd, double Kf,
PIDSource* source, PIDOutput* output,
double period) {
double period)
: SendableBase(false) {
m_controlLoop = std::make_unique<Notifier>(&PIDController::Calculate, this);
m_P = Kp;
@@ -85,6 +80,7 @@ PIDController::PIDController(double Kp, double Ki, double Kd, double Kf,
static int instances = 0;
instances++;
HAL_Report(HALUsageReporting::kResourceType_PIDController, instances);
SetName("PIDController", instances);
}
/**
@@ -123,7 +119,6 @@ PIDController::PIDController(double Kp, double Ki, double Kd, double Kf,
PIDController::~PIDController() {
// forcefully stopping the notifier so the callback can successfully run.
m_controlLoop->Stop();
RemoveListeners();
}
/**
@@ -257,10 +252,6 @@ void PIDController::SetPID(double p, double i, double d) {
m_I = i;
m_D = d;
}
if (m_pEntry) m_pEntry.SetDouble(m_P);
if (m_iEntry) m_iEntry.SetDouble(m_I);
if (m_dEntry) m_dEntry.SetDouble(m_D);
}
/**
@@ -274,18 +265,51 @@ void PIDController::SetPID(double p, double i, double d) {
* @param f Feed forward coefficient
*/
void PIDController::SetPID(double p, double i, double d, double f) {
{
std::lock_guard<wpi::mutex> lock(m_thisMutex);
m_P = p;
m_I = i;
m_D = d;
m_F = f;
}
std::lock_guard<wpi::mutex> lock(m_thisMutex);
m_P = p;
m_I = i;
m_D = d;
m_F = f;
}
if (m_pEntry) m_pEntry.SetDouble(m_P);
if (m_iEntry) m_iEntry.SetDouble(m_I);
if (m_dEntry) m_dEntry.SetDouble(m_D);
if (m_fEntry) m_fEntry.SetDouble(m_F);
/**
* Set the Proportional coefficient of the PID controller gain.
*
* @param p proportional coefficient
*/
void PIDController::SetP(double p) {
std::lock_guard<wpi::mutex> lock(m_thisMutex);
m_P = p;
}
/**
* Set the Integral coefficient of the PID controller gain.
*
* @param i integral coefficient
*/
void PIDController::SetI(double i) {
std::lock_guard<wpi::mutex> lock(m_thisMutex);
m_I = i;
}
/**
* Set the Differential coefficient of the PID controller gain.
*
* @param d differential coefficient
*/
void PIDController::SetD(double d) {
std::lock_guard<wpi::mutex> lock(m_thisMutex);
m_D = d;
}
/**
* Get the Feed forward coefficient of the PID controller gain.
*
* @param f Feed forward coefficient
*/
void PIDController::SetF(double f) {
std::lock_guard<wpi::mutex> lock(m_thisMutex);
m_F = f;
}
/**
@@ -403,8 +427,6 @@ void PIDController::SetSetpoint(double setpoint) {
m_setpoint = setpoint;
}
}
if (m_setpointEntry) m_setpointEntry.SetDouble(m_setpoint);
}
/**
@@ -556,8 +578,6 @@ void PIDController::Enable() {
std::lock_guard<wpi::mutex> lock(m_thisMutex);
m_enabled = true;
}
if (m_enabledEntry) m_enabledEntry.SetBoolean(true);
}
/**
@@ -574,8 +594,17 @@ void PIDController::Disable() {
m_pidOutput->PIDWrite(0);
}
}
if (m_enabledEntry) m_enabledEntry.SetBoolean(false);
/**
* Set the enabled state of the PIDController.
*/
void PIDController::SetEnabled(bool enable) {
if (enable) {
Enable();
} else {
Disable();
}
}
/**
@@ -598,76 +627,21 @@ void PIDController::Reset() {
m_result = 0;
}
std::string PIDController::GetSmartDashboardType() const {
return "PIDController";
}
void PIDController::InitTable(std::shared_ptr<nt::NetworkTable> subtable) {
RemoveListeners();
if (subtable) {
m_pEntry = subtable->GetEntry(kP);
m_pEntry.SetDouble(GetP());
m_iEntry = subtable->GetEntry(kI);
m_iEntry.SetDouble(GetI());
m_dEntry = subtable->GetEntry(kD);
m_dEntry.SetDouble(GetD());
m_fEntry = subtable->GetEntry(kF);
m_fEntry.SetDouble(GetF());
m_setpointEntry = subtable->GetEntry(kSetpoint);
m_setpointEntry.SetDouble(GetSetpoint());
m_enabledEntry = subtable->GetEntry(kEnabled);
m_enabledEntry.SetBoolean(IsEnabled());
m_pListener = m_pEntry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsDouble()) return;
std::lock_guard<wpi::mutex> lock(m_thisMutex);
m_P = event.value->GetDouble();
},
NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
m_iListener = m_iEntry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsDouble()) return;
std::lock_guard<wpi::mutex> lock(m_thisMutex);
m_I = event.value->GetDouble();
},
NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
m_dListener = m_dEntry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsDouble()) return;
std::lock_guard<wpi::mutex> lock(m_thisMutex);
m_D = event.value->GetDouble();
},
NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
m_fListener = m_fEntry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsDouble()) return;
std::lock_guard<wpi::mutex> lock(m_thisMutex);
m_F = event.value->GetDouble();
},
NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
m_setpointListener = m_setpointEntry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsDouble()) return;
SetSetpoint(event.value->GetDouble());
},
NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
m_enabledListener = m_enabledEntry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsBoolean()) return;
if (event.value->GetBoolean()) {
Enable();
} else {
Disable();
}
},
NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
}
void PIDController::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("PIDController");
builder.SetSafeState([=]() { Reset(); });
builder.AddDoubleProperty("p", [=]() { return GetP(); },
[=](bool value) { SetP(value); });
builder.AddDoubleProperty("i", [=]() { return GetI(); },
[=](bool value) { SetI(value); });
builder.AddDoubleProperty("d", [=]() { return GetD(); },
[=](bool value) { SetD(value); });
builder.AddDoubleProperty("f", [=]() { return GetF(); },
[=](bool value) { SetF(value); });
builder.AddDoubleProperty("setpoint", [=]() { return GetSetpoint(); },
[=](bool value) { SetSetpoint(value); });
builder.AddBooleanProperty("enabled", [=]() { return IsEnabled(); },
[=](bool value) { SetEnabled(value); });
}
/**
@@ -691,36 +665,3 @@ double PIDController::GetContinuousError(double error) const {
return error;
}
void PIDController::UpdateTable() {}
void PIDController::StartLiveWindowMode() { Disable(); }
void PIDController::StopLiveWindowMode() {}
void PIDController::RemoveListeners() {
if (m_pListener != 0) {
m_pEntry.RemoveListener(m_pListener);
m_pListener = 0;
}
if (m_iListener != 0) {
m_iEntry.RemoveListener(m_iListener);
m_iListener = 0;
}
if (m_dListener != 0) {
m_dEntry.RemoveListener(m_dListener);
m_dListener = 0;
}
if (m_fListener != 0) {
m_fEntry.RemoveListener(m_fListener);
m_fListener = 0;
}
if (m_setpointListener != 0) {
m_setpointEntry.RemoveListener(m_setpointListener);
m_setpointListener = 0;
}
if (m_enabledListener != 0) {
m_enabledEntry.RemoveListener(m_enabledListener);
m_enabledListener = 0;
}
}

View File

@@ -13,6 +13,8 @@
#include <llvm/SmallString.h>
#include <llvm/raw_ostream.h>
#include "SensorBase.h"
#include "SmartDashboard/SendableBuilder.h"
#include "Utility.h"
#include "WPIErrors.h"
@@ -32,7 +34,7 @@ PWM::PWM(int channel) {
llvm::SmallString<32> str;
llvm::raw_svector_ostream buf(str);
if (!CheckPWMChannel(channel)) {
if (!SensorBase::CheckPWMChannel(channel)) {
buf << "PWM Channel " << channel;
wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, buf.str());
return;
@@ -57,6 +59,7 @@ PWM::PWM(int channel) {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
HAL_Report(HALUsageReporting::kResourceType_PWM, channel);
SetName("PWM", channel);
}
/**
@@ -72,8 +75,6 @@ PWM::~PWM() {
HAL_FreePWMPort(m_handle, &status);
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
if (m_valueListener != 0) m_valueEntry.RemoveListener(m_valueListener);
}
/**
@@ -314,37 +315,9 @@ void PWM::SetZeroLatch() {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
void PWM::UpdateTable() {
if (m_valueEntry) m_valueEntry.SetDouble(GetSpeed());
}
void PWM::StartLiveWindowMode() {
SetSpeed(0);
if (m_valueEntry) {
m_valueListener = m_valueEntry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsDouble()) return;
SetSpeed(event.value->GetDouble());
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
}
}
void PWM::StopLiveWindowMode() {
SetSpeed(0);
if (m_valueListener != 0) {
m_valueEntry.RemoveListener(m_valueListener);
m_valueListener = 0;
}
}
std::string PWM::GetSmartDashboardType() const { return "Speed Controller"; }
void PWM::InitTable(std::shared_ptr<NetworkTable> subTable) {
if (subTable) {
m_valueEntry = subTable->GetEntry("Value");
UpdateTable();
} else {
m_valueEntry = nt::NetworkTableEntry();
}
void PWM::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Speed Controller");
builder.SetSafeState([=]() { SetDisabled(); });
builder.AddDoubleProperty("Value", [=]() { return GetSpeed(); },
[=](double value) { SetSpeed(value); });
}

View File

@@ -9,8 +9,6 @@
#include <HAL/HAL.h>
#include "LiveWindow/LiveWindow.h"
using namespace frc;
/**
@@ -38,5 +36,5 @@ PWMTalonSRX::PWMTalonSRX(int channel) : PWMSpeedController(channel) {
SetZeroLatch();
HAL_Report(HALUsageReporting::kResourceType_PWMTalonSRX, GetChannel());
LiveWindow::GetInstance()->AddActuator("PWMTalonSRX", GetChannel(), this);
SetName("PWMTalonSRX", GetChannel());
}

View File

@@ -13,7 +13,7 @@
#include <llvm/SmallString.h>
#include <llvm/raw_ostream.h>
#include "LiveWindow/LiveWindow.h"
#include "SmartDashboard/SendableBuilder.h"
#include "WPIErrors.h"
using namespace frc;
@@ -32,6 +32,7 @@ PowerDistributionPanel::PowerDistributionPanel(int module) : m_module(module) {
m_module = -1;
return;
}
SetName("PowerDistributionPanel", module);
}
/**
@@ -171,39 +172,13 @@ void PowerDistributionPanel::ClearStickyFaults() {
}
}
void PowerDistributionPanel::UpdateTable() {
for (size_t i = 0; i < sizeof(m_chanEntry) / sizeof(m_chanEntry[0]); ++i) {
if (m_chanEntry[i]) m_chanEntry[i].SetDouble(GetCurrent(i));
}
if (m_voltageEntry) m_voltageEntry.SetDouble(GetVoltage());
if (m_totalCurrentEntry) m_totalCurrentEntry.SetDouble(GetTotalCurrent());
}
void PowerDistributionPanel::StartLiveWindowMode() {}
void PowerDistributionPanel::StopLiveWindowMode() {}
std::string PowerDistributionPanel::GetSmartDashboardType() const {
return "PowerDistributionPanel";
}
void PowerDistributionPanel::InitTable(
std::shared_ptr<nt::NetworkTable> subTable) {
if (subTable != nullptr) {
for (size_t i = 0; i < sizeof(m_chanEntry) / sizeof(m_chanEntry[0]); ++i) {
llvm::SmallString<32> buf;
llvm::raw_svector_ostream oss(buf);
oss << "Chan" << i;
m_chanEntry[i] = subTable->GetEntry(oss.str());
}
m_voltageEntry = subTable->GetEntry("Voltage");
m_totalCurrentEntry = subTable->GetEntry("TotalCurrent");
UpdateTable();
} else {
for (size_t i = 0; i < sizeof(m_chanEntry) / sizeof(m_chanEntry[0]); ++i) {
m_chanEntry[i] = nt::NetworkTableEntry();
}
m_voltageEntry = nt::NetworkTableEntry();
m_totalCurrentEntry = nt::NetworkTableEntry();
void PowerDistributionPanel::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("PowerDistributionPanel");
for (int i = 0; i < kPDPChannels; ++i) {
builder.AddDoubleProperty("Chan" + llvm::Twine(i),
[=]() { return GetCurrent(i); }, nullptr);
}
builder.AddDoubleProperty("Voltage", [=]() { return GetVoltage(); }, nullptr);
builder.AddDoubleProperty("TotalCurrent", [=]() { return GetTotalCurrent(); },
nullptr);
}

View File

@@ -12,8 +12,9 @@
#include <HAL/Relay.h>
#include <llvm/SmallString.h>
#include "LiveWindow/LiveWindow.h"
#include "MotorSafetyHelper.h"
#include "SensorBase.h"
#include "SmartDashboard/SendableBuilder.h"
#include "WPIErrors.h"
using namespace frc;
@@ -88,7 +89,7 @@ Relay::Relay(int channel, Relay::Direction direction)
m_safetyHelper = std::make_unique<MotorSafetyHelper>(this);
m_safetyHelper->SetSafetyEnabled(false);
LiveWindow::GetInstance()->AddActuator("Relay", 1, m_channel, this);
SetName("Relay", m_channel);
}
/**
@@ -103,8 +104,6 @@ Relay::~Relay() {
// ignore errors, as we want to make sure a free happens.
if (m_forwardHandle != HAL_kInvalidHandle) HAL_FreeRelayPort(m_forwardHandle);
if (m_reverseHandle != HAL_kInvalidHandle) HAL_FreeRelayPort(m_reverseHandle);
if (m_valueListener != 0) m_valueEntry.RemoveListener(m_valueListener);
}
/**
@@ -275,52 +274,31 @@ void Relay::GetDescription(llvm::raw_ostream& desc) const {
desc << "Relay " << GetChannel();
}
void Relay::UpdateTable() {
if (m_valueEntry) {
if (Get() == kOn) {
m_valueEntry.SetString("On");
} else if (Get() == kForward) {
m_valueEntry.SetString("Forward");
} else if (Get() == kReverse) {
m_valueEntry.SetString("Reverse");
} else {
m_valueEntry.SetString("Off");
}
}
}
void Relay::StartLiveWindowMode() {
if (m_valueEntry) {
m_valueListener = m_valueEntry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsString()) return;
if (event.value->GetString() == "Off")
Set(kOff);
else if (event.value->GetString() == "Forward")
Set(kForward);
else if (event.value->GetString() == "Reverse")
Set(kReverse);
else if (event.value->GetString() == "On")
Set(kOn);
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
}
}
void Relay::StopLiveWindowMode() {
if (m_valueListener != 0) {
m_valueEntry.RemoveListener(m_valueListener);
m_valueListener = 0;
}
}
std::string Relay::GetSmartDashboardType() const { return "Relay"; }
void Relay::InitTable(std::shared_ptr<nt::NetworkTable> subTable) {
if (subTable) {
m_valueEntry = subTable->GetEntry("Value");
UpdateTable();
} else {
m_valueEntry = nt::NetworkTableEntry();
}
void Relay::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Relay");
builder.SetSafeState([=]() { Set(kOff); });
builder.AddSmallStringProperty(
"Value",
[=](llvm::SmallVectorImpl<char>& buf) -> llvm::StringRef {
switch (Get()) {
case kOn:
return "On";
case kForward:
return "Forward";
case kReverse:
return "Reverse";
default:
return "Off";
}
},
[=](llvm::StringRef value) {
if (value == "Off")
Set(kOff);
else if (value == "Forward")
Set(kForward);
else if (value == "Reverse")
Set(kReverse);
else if (value == "On")
Set(kOn);
});
}

View File

@@ -9,8 +9,6 @@
#include <HAL/HAL.h>
#include "LiveWindow/LiveWindow.h"
using namespace frc;
/**
@@ -41,5 +39,5 @@ SD540::SD540(int channel) : PWMSpeedController(channel) {
SetZeroLatch();
HAL_Report(HALUsageReporting::kResourceType_MindsensorsSD540, GetChannel());
LiveWindow::GetInstance()->AddActuator("SD540", GetChannel(), this);
SetName("SD540", GetChannel());
}

View File

@@ -9,7 +9,7 @@
#include <HAL/HAL.h>
#include "LiveWindow/LiveWindow.h"
#include "SmartDashboard/SendableBuilder.h"
using namespace frc;
@@ -31,10 +31,7 @@ Servo::Servo(int channel) : SafePWM(channel) {
SetPeriodMultiplier(kPeriodMultiplier_4X);
HAL_Report(HALUsageReporting::kResourceType_Servo, channel);
}
Servo::~Servo() {
if (m_valueListener != 0) m_valueEntry.RemoveListener(m_valueListener);
SetName("Servo", channel);
}
/**
@@ -100,35 +97,8 @@ double Servo::GetAngle() const {
return GetPosition() * GetServoAngleRange() + kMinServoAngle;
}
void Servo::UpdateTable() {
if (m_valueEntry) m_valueEntry.SetDouble(Get());
}
void Servo::StartLiveWindowMode() {
if (m_valueEntry) {
m_valueListener = m_valueEntry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsDouble()) return;
Set(event.value->GetDouble());
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
}
}
void Servo::StopLiveWindowMode() {
if (m_valueListener != 0) {
m_valueEntry.RemoveListener(m_valueListener);
m_valueListener = 0;
}
}
std::string Servo::GetSmartDashboardType() const { return "Servo"; }
void Servo::InitTable(std::shared_ptr<nt::NetworkTable> subTable) {
if (subTable) {
m_valueEntry = subTable->GetEntry("Value");
UpdateTable();
} else {
m_valueEntry = nt::NetworkTableEntry();
}
void Servo::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Servo");
builder.AddDoubleProperty("Value", [=]() { return Get(); },
[=](double value) { Set(value); });
}

View File

@@ -0,0 +1,91 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2017 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. */
/*----------------------------------------------------------------------------*/
#include "SmartDashboard/SendableBase.h"
#include "LiveWindow/LiveWindow.h"
using namespace frc;
/**
* Creates an instance of the sensor base.
*
* @param addLiveWindow if true, add this Sendable to LiveWindow
*/
SendableBase::SendableBase(bool addLiveWindow) {
if (addLiveWindow) LiveWindow::GetInstance()->Add(this);
}
/**
* Free the resources used by this object.
*/
SendableBase::~SendableBase() { LiveWindow::GetInstance()->Remove(this); }
std::string SendableBase::GetName() const {
std::lock_guard<wpi::mutex> lock(m_mutex);
return m_name;
}
void SendableBase::SetName(const llvm::Twine& name) {
std::lock_guard<wpi::mutex> lock(m_mutex);
m_name = name.str();
}
std::string SendableBase::GetSubsystem() const {
std::lock_guard<wpi::mutex> lock(m_mutex);
return m_subsystem;
}
void SendableBase::SetSubsystem(const llvm::Twine& subsystem) {
std::lock_guard<wpi::mutex> lock(m_mutex);
m_subsystem = subsystem.str();
}
/**
* Add a child component.
*
* @param child child component
*/
void SendableBase::AddChild(std::shared_ptr<Sendable> child) {
LiveWindow::GetInstance()->AddChild(this, child);
}
/**
* Add a child component.
*
* @param child child component
*/
void SendableBase::AddChild(void* child) {
LiveWindow::GetInstance()->AddChild(this, child);
}
/**
* 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
*/
void SendableBase::SetName(const llvm::Twine& moduleType, int channel) {
SetName(moduleType + llvm::Twine('[') + llvm::Twine(channel) +
llvm::Twine(']'));
}
/**
* 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)
*/
void SendableBase::SetName(const llvm::Twine& moduleType, int moduleNumber,
int channel) {
SetName(moduleType + llvm::Twine('[') + llvm::Twine(moduleNumber) +
llvm::Twine(',') + llvm::Twine(channel) + llvm::Twine(']'));
}

View File

@@ -0,0 +1,365 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2017 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. */
/*----------------------------------------------------------------------------*/
#include "SmartDashboard/SendableBuilderImpl.h"
#include <llvm/SmallString.h>
#include "ntcore_cpp.h"
using namespace frc;
void SendableBuilderImpl::SetTable(std::shared_ptr<nt::NetworkTable> table) {
m_table = table;
}
std::shared_ptr<nt::NetworkTable> SendableBuilderImpl::GetTable() {
return m_table;
}
void SendableBuilderImpl::UpdateTable() {
uint64_t time = nt::Now();
for (auto& property : m_properties) {
if (property.update) property.update(property.entry, time);
}
if (m_updateTable) m_updateTable();
}
void SendableBuilderImpl::StartLiveWindowMode() {
if (m_safeState) m_safeState();
for (auto& property : m_properties) property.StartListener();
}
void SendableBuilderImpl::StopLiveWindowMode() {
if (m_safeState) m_safeState();
for (auto& property : m_properties) property.StopListener();
}
void SendableBuilderImpl::SetSmartDashboardType(const llvm::Twine& type) {
m_table->GetEntry(".type").SetString(type);
}
void SendableBuilderImpl::SetSafeState(std::function<void()> func) {
m_safeState = func;
}
void SendableBuilderImpl::SetUpdateTable(std::function<void()> func) {
m_updateTable = func;
}
nt::NetworkTableEntry SendableBuilderImpl::GetEntry(const llvm::Twine& key) {
return m_table->GetEntry(key);
}
void SendableBuilderImpl::AddBooleanProperty(const llvm::Twine& key,
std::function<bool()> getter,
std::function<void(bool)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
entry.SetValue(nt::Value::MakeBoolean(getter(), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsBoolean()) return;
setter(event.value->GetBoolean());
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
}
void SendableBuilderImpl::AddDoubleProperty(
const llvm::Twine& key, std::function<double()> getter,
std::function<void(double)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
entry.SetValue(nt::Value::MakeDouble(getter(), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsDouble()) return;
setter(event.value->GetDouble());
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
}
void SendableBuilderImpl::AddStringProperty(
const llvm::Twine& key, std::function<std::string()> getter,
std::function<void(llvm::StringRef)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
entry.SetValue(nt::Value::MakeString(getter(), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsString()) return;
setter(event.value->GetString());
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
}
void SendableBuilderImpl::AddBooleanArrayProperty(
const llvm::Twine& key, std::function<std::vector<int>()> getter,
std::function<void(llvm::ArrayRef<int>)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
entry.SetValue(nt::Value::MakeBooleanArray(getter(), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsBooleanArray()) return;
setter(event.value->GetBooleanArray());
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
}
void SendableBuilderImpl::AddDoubleArrayProperty(
const llvm::Twine& key, std::function<std::vector<double>()> getter,
std::function<void(llvm::ArrayRef<double>)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
entry.SetValue(nt::Value::MakeDoubleArray(getter(), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsDoubleArray()) return;
setter(event.value->GetDoubleArray());
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
}
void SendableBuilderImpl::AddStringArrayProperty(
const llvm::Twine& key, std::function<std::vector<std::string>()> getter,
std::function<void(llvm::ArrayRef<std::string>)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
entry.SetValue(nt::Value::MakeStringArray(getter(), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsStringArray()) return;
setter(event.value->GetStringArray());
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
}
void SendableBuilderImpl::AddRawProperty(
const llvm::Twine& key, std::function<std::string()> getter,
std::function<void(llvm::StringRef)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
entry.SetValue(nt::Value::MakeRaw(getter(), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsRaw()) return;
setter(event.value->GetRaw());
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
}
void SendableBuilderImpl::AddValueProperty(
const llvm::Twine& key, std::function<std::shared_ptr<nt::Value>()> getter,
std::function<void(std::shared_ptr<nt::Value>)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
entry.SetValue(getter());
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) { setter(event.value); },
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
}
void SendableBuilderImpl::AddSmallStringProperty(
const llvm::Twine& key,
std::function<llvm::StringRef(llvm::SmallVectorImpl<char>& buf)> getter,
std::function<void(llvm::StringRef)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
llvm::SmallString<128> buf;
entry.SetValue(nt::Value::MakeString(getter(buf), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsString()) return;
setter(event.value->GetString());
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
}
void SendableBuilderImpl::AddSmallBooleanArrayProperty(
const llvm::Twine& key,
std::function<llvm::ArrayRef<int>(llvm::SmallVectorImpl<int>& buf)> getter,
std::function<void(llvm::ArrayRef<int>)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
llvm::SmallVector<int, 16> buf;
entry.SetValue(nt::Value::MakeBooleanArray(getter(buf), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsBooleanArray()) return;
setter(event.value->GetBooleanArray());
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
}
void SendableBuilderImpl::AddSmallDoubleArrayProperty(
const llvm::Twine& key,
std::function<llvm::ArrayRef<double>(llvm::SmallVectorImpl<double>& buf)>
getter,
std::function<void(llvm::ArrayRef<double>)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
llvm::SmallVector<double, 16> buf;
entry.SetValue(nt::Value::MakeDoubleArray(getter(buf), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsDoubleArray()) return;
setter(event.value->GetDoubleArray());
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
}
void SendableBuilderImpl::AddSmallStringArrayProperty(
const llvm::Twine& key,
std::function<
llvm::ArrayRef<std::string>(llvm::SmallVectorImpl<std::string>& buf)>
getter,
std::function<void(llvm::ArrayRef<std::string>)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
llvm::SmallVector<std::string, 16> buf;
entry.SetValue(nt::Value::MakeStringArray(getter(buf), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsStringArray()) return;
setter(event.value->GetStringArray());
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
}
void SendableBuilderImpl::AddSmallRawProperty(
const llvm::Twine& key,
std::function<llvm::StringRef(llvm::SmallVectorImpl<char>& buf)> getter,
std::function<void(llvm::StringRef)> setter) {
m_properties.emplace_back(*m_table, key);
if (getter) {
m_properties.back().update = [=](nt::NetworkTableEntry entry,
uint64_t time) {
llvm::SmallVector<char, 128> buf;
entry.SetValue(nt::Value::MakeRaw(getter(buf), time));
};
}
if (setter) {
m_properties.back().createListener =
[=](nt::NetworkTableEntry entry) -> NT_EntryListener {
return entry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsRaw()) return;
setter(event.value->GetRaw());
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
};
}
}

View File

@@ -12,7 +12,3 @@ using namespace frc;
const char* SendableChooserBase::kDefault = "default";
const char* SendableChooserBase::kOptions = "options";
const char* SendableChooserBase::kSelected = "selected";
std::string SendableChooserBase::GetSmartDashboardType() const {
return "String Chooser";
}

View File

@@ -7,18 +7,28 @@
#include "SmartDashboard/SmartDashboard.h"
#include <map>
#include <llvm/StringMap.h>
#include <support/mutex.h>
#include "HLUsageReporting.h"
#include "SmartDashboard/NamedSendable.h"
#include "SmartDashboard/Sendable.h"
#include "SmartDashboard/SendableBuilderImpl.h"
#include "WPIErrors.h"
#include "networktables/NetworkTable.h"
#include "networktables/NetworkTableInstance.h"
using namespace frc;
namespace {
struct SmartDashboardData {
Sendable* sendable = nullptr;
SendableBuilderImpl builder;
};
} // namespace
static std::shared_ptr<nt::NetworkTable> s_table;
static std::map<std::shared_ptr<nt::NetworkTable>, Sendable*> s_tablesToData;
static llvm::StringMap<SmartDashboardData> s_tablesToData;
static wpi::mutex s_tablesToDataMutex;
void SmartDashboard::init() {
s_table = nt::NetworkTableInstance::GetDefault().GetTable("SmartDashboard");
@@ -126,22 +136,26 @@ void SmartDashboard::PutData(llvm::StringRef key, Sendable* data) {
wpi_setGlobalWPIErrorWithContext(NullParameter, "value");
return;
}
std::shared_ptr<nt::NetworkTable> dataTable(s_table->GetSubTable(key));
dataTable->GetEntry(".type").SetString(data->GetSmartDashboardType());
data->InitTable(dataTable);
s_tablesToData[dataTable] = data;
std::lock_guard<wpi::mutex> lock(s_tablesToDataMutex);
auto& sddata = s_tablesToData[key];
if (!sddata.sendable || sddata.sendable != data) {
sddata.sendable = data;
sddata.builder.SetTable(s_table->GetSubTable(key));
data->InitSendable(sddata.builder);
}
sddata.builder.UpdateTable();
}
/**
* Maps the specified key (where the key is the name of the
* {@link SmartDashboardNamedData} to the specified value in this table.
* Maps the specified key (where the key is the name of the Sendable)
* to the specified value in this table.
*
* The value can be retrieved by calling the get method with a key that is equal
* to the original key.
*
* @param value the value
*/
void SmartDashboard::PutData(NamedSendable* value) {
void SmartDashboard::PutData(Sendable* value) {
if (value == nullptr) {
wpi_setGlobalWPIErrorWithContext(NullParameter, "value");
return;
@@ -156,13 +170,13 @@ void SmartDashboard::PutData(NamedSendable* value) {
* @return the value
*/
Sendable* SmartDashboard::GetData(llvm::StringRef key) {
std::shared_ptr<nt::NetworkTable> subtable(s_table->GetSubTable(key));
Sendable* data = s_tablesToData[subtable];
if (data == nullptr) {
std::lock_guard<wpi::mutex> lock(s_tablesToDataMutex);
auto data = s_tablesToData.find(key);
if (data == s_tablesToData.end()) {
wpi_setGlobalWPIErrorWithContext(SmartDashboardMissingKey, key);
return nullptr;
}
return data;
return data->getValue().sendable;
}
/**

View File

@@ -13,7 +13,8 @@
#include <llvm/SmallString.h>
#include <llvm/raw_ostream.h>
#include "LiveWindow/LiveWindow.h"
#include "SensorBase.h"
#include "SmartDashboard/SendableBuilder.h"
#include "WPIErrors.h"
using namespace frc;
@@ -24,7 +25,7 @@ using namespace frc;
* @param channel The channel on the PCM to control (0..7).
*/
Solenoid::Solenoid(int channel)
: Solenoid(GetDefaultSolenoidModule(), channel) {}
: Solenoid(SensorBase::GetDefaultSolenoidModule(), channel) {}
/**
* Constructor.
@@ -36,12 +37,12 @@ Solenoid::Solenoid(int moduleNumber, int channel)
: SolenoidBase(moduleNumber), m_channel(channel) {
llvm::SmallString<32> str;
llvm::raw_svector_ostream buf(str);
if (!CheckSolenoidModule(m_moduleNumber)) {
if (!SensorBase::CheckSolenoidModule(m_moduleNumber)) {
buf << "Solenoid Module " << m_moduleNumber;
wpi_setWPIErrorWithContext(ModuleIndexOutOfRange, buf.str());
return;
}
if (!CheckSolenoidChannel(m_channel)) {
if (!SensorBase::CheckSolenoidChannel(m_channel)) {
buf << "Solenoid Module " << m_channel;
wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, buf.str());
return;
@@ -57,19 +58,15 @@ Solenoid::Solenoid(int moduleNumber, int channel)
return;
}
LiveWindow::GetInstance()->AddActuator("Solenoid", m_moduleNumber, m_channel,
this);
HAL_Report(HALUsageReporting::kResourceType_Solenoid, m_channel,
m_moduleNumber);
SetName("Solenoid", m_moduleNumber, m_channel);
}
/**
* Destructor.
*/
Solenoid::~Solenoid() {
HAL_FreeSolenoidPort(m_solenoidHandle);
if (m_valueListener != 0) m_valueEntry.RemoveListener(m_valueListener);
}
Solenoid::~Solenoid() { HAL_FreeSolenoidPort(m_solenoidHandle); }
/**
* Set the value of a solenoid.
@@ -141,34 +138,9 @@ void Solenoid::StartPulse() {
wpi_setErrorWithContext(status, HAL_GetErrorMessage(status));
}
void Solenoid::UpdateTable() {
if (m_valueEntry) m_valueEntry.SetBoolean(Get());
}
void Solenoid::StartLiveWindowMode() {
Set(false);
if (m_valueEntry) {
m_valueEntry.AddListener(
[=](const nt::EntryNotification& event) {
if (!event.value->IsBoolean()) return;
Set(event.value->GetBoolean());
},
NT_NOTIFY_IMMEDIATE | NT_NOTIFY_NEW | NT_NOTIFY_UPDATE);
}
}
void Solenoid::StopLiveWindowMode() {
Set(false);
if (m_valueListener != 0) m_valueEntry.RemoveListener(m_valueListener);
}
std::string Solenoid::GetSmartDashboardType() const { return "Solenoid"; }
void Solenoid::InitTable(std::shared_ptr<nt::NetworkTable> subTable) {
if (subTable) {
m_valueEntry = subTable->GetEntry("Value");
UpdateTable();
} else {
m_valueEntry = nt::NetworkTableEntry();
}
void Solenoid::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Solenoid");
builder.SetSafeState([=]() { Set(false); });
builder.AddBooleanProperty("Value", [=]() { return Get(); },
[=](bool value) { Set(value); });
}

View File

@@ -9,8 +9,6 @@
#include <HAL/HAL.h>
#include "LiveWindow/LiveWindow.h"
using namespace frc;
/**
@@ -41,5 +39,5 @@ Spark::Spark(int channel) : PWMSpeedController(channel) {
SetZeroLatch();
HAL_Report(HALUsageReporting::kResourceType_RevSPARK, GetChannel());
LiveWindow::GetInstance()->AddActuator("Spark", GetChannel(), this);
SetName("Spark", GetChannel());
}

View File

@@ -7,6 +7,8 @@
#include "SpeedControllerGroup.h"
#include "SmartDashboard/SendableBuilder.h"
using namespace frc;
void SpeedControllerGroup::Set(double speed) {
@@ -45,3 +47,10 @@ void SpeedControllerGroup::PIDWrite(double output) {
speedController.get().PIDWrite(output);
}
}
void SpeedControllerGroup::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Speed Controller");
builder.SetSafeState([=]() { StopMotor(); });
builder.AddDoubleProperty("Value", [=]() { return Get(); },
[=](double value) { Set(value); });
}

View File

@@ -9,8 +9,6 @@
#include <HAL/HAL.h>
#include "LiveWindow/LiveWindow.h"
using namespace frc;
/**
@@ -39,5 +37,5 @@ Talon::Talon(int channel) : PWMSpeedController(channel) {
SetZeroLatch();
HAL_Report(HALUsageReporting::kResourceType_Talon, GetChannel());
LiveWindow::GetInstance()->AddActuator("Talon", GetChannel(), this);
SetName("Talon", GetChannel());
}

View File

@@ -12,7 +12,7 @@
#include "Counter.h"
#include "DigitalInput.h"
#include "DigitalOutput.h"
#include "LiveWindow/LiveWindow.h"
#include "SmartDashboard/SendableBuilder.h"
#include "Timer.h"
#include "Utility.h"
#include "WPIErrors.h"
@@ -72,8 +72,7 @@ void Ultrasonic::Initialize() {
static int instances = 0;
instances++;
HAL_Report(HALUsageReporting::kResourceType_Ultrasonic, instances);
LiveWindow::GetInstance()->AddSensor("Ultrasonic",
m_echoChannel->GetChannel(), this);
SetName("Ultrasonic", m_echoChannel->GetChannel());
}
/**
@@ -94,6 +93,8 @@ Ultrasonic::Ultrasonic(int pingChannel, int echoChannel, DistanceUnit units)
m_counter(m_echoChannel) {
m_units = units;
Initialize();
AddChild(m_pingChannel);
AddChild(m_echoChannel);
}
/**
@@ -314,23 +315,8 @@ Ultrasonic::DistanceUnit Ultrasonic::GetDistanceUnits() const {
return m_units;
}
void Ultrasonic::UpdateTable() {
if (m_valueEntry) {
m_valueEntry.SetDouble(GetRangeInches());
}
}
void Ultrasonic::StartLiveWindowMode() {}
void Ultrasonic::StopLiveWindowMode() {}
std::string Ultrasonic::GetSmartDashboardType() const { return "Ultrasonic"; }
void Ultrasonic::InitTable(std::shared_ptr<NetworkTable> subTable) {
if (subTable) {
m_valueEntry = subTable->GetEntry("Value");
UpdateTable();
} else {
m_valueEntry = nt::NetworkTableEntry();
}
void Ultrasonic::InitSendable(SendableBuilder& builder) {
builder.SetSmartDashboardType("Ultrasonic");
builder.AddDoubleProperty("Value", [=]() { return GetRangeInches(); },
nullptr);
}

View File

@@ -9,8 +9,6 @@
#include <HAL/HAL.h>
#include "LiveWindow/LiveWindow.h"
using namespace frc;
/**
@@ -39,6 +37,6 @@ Victor::Victor(int channel) : PWMSpeedController(channel) {
SetSpeed(0.0);
SetZeroLatch();
LiveWindow::GetInstance()->AddActuator("Victor", GetChannel(), this);
HAL_Report(HALUsageReporting::kResourceType_Victor, GetChannel());
SetName("Victor", GetChannel());
}

View File

@@ -9,8 +9,6 @@
#include <HAL/HAL.h>
#include "LiveWindow/LiveWindow.h"
using namespace frc;
/**
@@ -40,5 +38,5 @@ VictorSP::VictorSP(int channel) : PWMSpeedController(channel) {
SetZeroLatch();
HAL_Report(HALUsageReporting::kResourceType_VictorSP, GetChannel());
LiveWindow::GetInstance()->AddActuator("VictorSP", GetChannel(), this);
SetName("VictorSP", GetChannel());
}

View File

@@ -7,13 +7,9 @@
#pragma once
#include <memory>
#include <string>
#include "I2C.h"
#include "LiveWindow/LiveWindowSendable.h"
#include "SensorBase.h"
#include "interfaces/Accelerometer.h"
#include "networktables/NetworkTableEntry.h"
namespace frc {
@@ -24,7 +20,7 @@ namespace frc {
* an I2C bus. This class assumes the default (not alternate) sensor address of
* 0x1D (7-bit address).
*/
class ADXL345_I2C : public Accelerometer, public LiveWindowSendable {
class ADXL345_I2C : public SensorBase, public Accelerometer {
public:
enum Axes { kAxis_X = 0x00, kAxis_Y = 0x02, kAxis_Z = 0x04 };
@@ -36,7 +32,7 @@ class ADXL345_I2C : public Accelerometer, public LiveWindowSendable {
explicit ADXL345_I2C(I2C::Port port, Range range = kRange_2G,
int deviceAddress = kAddress);
virtual ~ADXL345_I2C() = default;
~ADXL345_I2C() override = default;
ADXL345_I2C(const ADXL345_I2C&) = delete;
ADXL345_I2C& operator=(const ADXL345_I2C&) = delete;
@@ -50,11 +46,7 @@ class ADXL345_I2C : public Accelerometer, public LiveWindowSendable {
virtual double GetAcceleration(Axes axis);
virtual AllAxes GetAccelerations();
std::string GetSmartDashboardType() const override;
void InitTable(std::shared_ptr<nt::NetworkTable> subtable) override;
void UpdateTable() override;
void StartLiveWindowMode() override {}
void StopLiveWindowMode() override {}
void InitSendable(SendableBuilder& builder) override;
protected:
I2C m_i2c;
@@ -79,11 +71,6 @@ class ADXL345_I2C : public Accelerometer, public LiveWindowSendable {
kDataFormat_FullRes = 0x08,
kDataFormat_Justify = 0x04
};
private:
nt::NetworkTableEntry m_xEntry;
nt::NetworkTableEntry m_yEntry;
nt::NetworkTableEntry m_zEntry;
};
} // namespace frc

View File

@@ -7,27 +7,19 @@
#pragma once
#include <memory>
#include <string>
#include "LiveWindow/LiveWindowSendable.h"
#include "SPI.h"
#include "SensorBase.h"
#include "interfaces/Accelerometer.h"
#include "networktables/NetworkTableEntry.h"
namespace frc {
class DigitalInput;
class DigitalOutput;
/**
* ADXL345 Accelerometer on SPI.
*
* This class allows access to an Analog Devices ADXL345 3-axis accelerometer
* via SPI. This class assumes the sensor is wired in 4-wire SPI mode.
*/
class ADXL345_SPI : public Accelerometer, public LiveWindowSendable {
class ADXL345_SPI : public SensorBase, public Accelerometer {
public:
enum Axes { kAxis_X = 0x00, kAxis_Y = 0x02, kAxis_Z = 0x04 };
@@ -38,7 +30,7 @@ class ADXL345_SPI : public Accelerometer, public LiveWindowSendable {
};
explicit ADXL345_SPI(SPI::Port port, Range range = kRange_2G);
virtual ~ADXL345_SPI() = default;
~ADXL345_SPI() override = default;
ADXL345_SPI(const ADXL345_SPI&) = delete;
ADXL345_SPI& operator=(const ADXL345_SPI&) = delete;
@@ -52,11 +44,7 @@ class ADXL345_SPI : public Accelerometer, public LiveWindowSendable {
virtual double GetAcceleration(Axes axis);
virtual AllAxes GetAccelerations();
std::string GetSmartDashboardType() const override;
void InitTable(std::shared_ptr<nt::NetworkTable> subtable) override;
void UpdateTable() override;
void StartLiveWindowMode() override {}
void StopLiveWindowMode() override {}
void InitSendable(SendableBuilder& builder) override;
protected:
SPI m_spi;
@@ -82,11 +70,6 @@ class ADXL345_SPI : public Accelerometer, public LiveWindowSendable {
kDataFormat_FullRes = 0x08,
kDataFormat_Justify = 0x04
};
private:
nt::NetworkTableEntry m_xEntry;
nt::NetworkTableEntry m_yEntry;
nt::NetworkTableEntry m_zEntry;
};
} // namespace frc

View File

@@ -7,26 +7,18 @@
#pragma once
#include <memory>
#include <string>
#include "LiveWindow/LiveWindowSendable.h"
#include "SPI.h"
#include "SensorBase.h"
#include "interfaces/Accelerometer.h"
#include "networktables/NetworkTableEntry.h"
namespace frc {
class DigitalInput;
class DigitalOutput;
/**
* ADXL362 SPI Accelerometer.
*
* This class allows access to an Analog Devices ADXL362 3-axis accelerometer.
*/
class ADXL362 : public Accelerometer, public LiveWindowSendable {
class ADXL362 : public SensorBase, public Accelerometer {
public:
enum Axes { kAxis_X = 0x00, kAxis_Y = 0x02, kAxis_Z = 0x04 };
struct AllAxes {
@@ -52,19 +44,11 @@ class ADXL362 : public Accelerometer, public LiveWindowSendable {
virtual double GetAcceleration(Axes axis);
virtual AllAxes GetAccelerations();
std::string GetSmartDashboardType() const override;
void InitTable(std::shared_ptr<nt::NetworkTable> subtable) override;
void UpdateTable() override;
void StartLiveWindowMode() override {}
void StopLiveWindowMode() override {}
void InitSendable(SendableBuilder& builder) override;
private:
SPI m_spi;
double m_gsPerLSB = 0.001;
nt::NetworkTableEntry m_xEntry;
nt::NetworkTableEntry m_yEntry;
nt::NetworkTableEntry m_zEntry;
};
} // namespace frc

View File

@@ -8,13 +8,10 @@
#pragma once
#include <memory>
#include <string>
#include "AnalogInput.h"
#include "LiveWindow/LiveWindowSendable.h"
#include "PIDSource.h"
#include "SensorBase.h"
#include "networktables/NetworkTableEntry.h"
namespace frc {
@@ -25,25 +22,19 @@ namespace frc {
* sensors have multiple axis and can be treated as multiple devices. Each is
* calibrated by finding the center value over a period of time.
*/
class AnalogAccelerometer : public SensorBase,
public PIDSource,
public LiveWindowSendable {
class AnalogAccelerometer : public SensorBase, public PIDSource {
public:
explicit AnalogAccelerometer(int channel);
explicit AnalogAccelerometer(AnalogInput* channel);
explicit AnalogAccelerometer(std::shared_ptr<AnalogInput> channel);
virtual ~AnalogAccelerometer() = default;
~AnalogAccelerometer() override = default;
double GetAcceleration() const;
void SetSensitivity(double sensitivity);
void SetZero(double zero);
double PIDGet() override;
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
std::string GetSmartDashboardType() const override;
void InitTable(std::shared_ptr<nt::NetworkTable> subTable) override;
void InitSendable(SendableBuilder& builder) override;
private:
void InitAccelerometer();
@@ -51,8 +42,6 @@ class AnalogAccelerometer : public SensorBase,
std::shared_ptr<AnalogInput> m_analogInput;
double m_voltsPerG = 1.0;
double m_zeroGVoltage = 2.5;
nt::NetworkTableEntry m_valueEntry;
};
} // namespace frc

View File

@@ -9,15 +9,10 @@
#include <stdint.h>
#include <memory>
#include <string>
#include <HAL/Types.h>
#include "LiveWindow/LiveWindowSendable.h"
#include "PIDSource.h"
#include "SensorBase.h"
#include "networktables/NetworkTableEntry.h"
namespace frc {
@@ -33,9 +28,7 @@ namespace frc {
* are divided by the number of samples to retain the resolution, but get more
* stable values.
*/
class AnalogInput : public SensorBase,
public PIDSource,
public LiveWindowSendable {
class AnalogInput : public SensorBase, public PIDSource {
friend class AnalogTrigger;
friend class AnalogGyro;
@@ -45,7 +38,7 @@ class AnalogInput : public SensorBase,
static constexpr int kAccumulatorChannels[kAccumulatorNumChannels] = {0, 1};
explicit AnalogInput(int channel);
virtual ~AnalogInput();
~AnalogInput() override;
int GetValue() const;
int GetAverageValue() const;
@@ -78,19 +71,13 @@ class AnalogInput : public SensorBase,
double PIDGet() override;
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
std::string GetSmartDashboardType() const override;
void InitTable(std::shared_ptr<nt::NetworkTable> subTable) override;
void InitSendable(SendableBuilder& builder) override;
private:
int m_channel;
// TODO: Adjust HAL to avoid use of raw pointers.
HAL_AnalogInputHandle m_port;
int64_t m_accumulatorOffset;
nt::NetworkTableEntry m_valueEntry;
};
} // namespace frc

View File

@@ -7,40 +7,30 @@
#pragma once
#include <memory>
#include <string>
#include <HAL/AnalogOutput.h>
#include "LiveWindow/LiveWindowSendable.h"
#include "SensorBase.h"
#include "networktables/NetworkTableEntry.h"
#include "ErrorBase.h"
#include "SmartDashboard/SendableBase.h"
namespace frc {
/**
* MXP analog output class.
*/
class AnalogOutput : public SensorBase, public LiveWindowSendable {
class AnalogOutput : public ErrorBase, public SendableBase {
public:
explicit AnalogOutput(int channel);
virtual ~AnalogOutput();
~AnalogOutput() override;
void SetVoltage(double voltage);
double GetVoltage() const;
int GetChannel();
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
std::string GetSmartDashboardType() const override;
void InitTable(std::shared_ptr<nt::NetworkTable> subTable) override;
void InitSendable(SendableBuilder& builder) override;
protected:
int m_channel;
HAL_AnalogOutputHandle m_port;
nt::NetworkTableEntry m_valueEntry;
};
} // namespace frc

View File

@@ -8,12 +8,10 @@
#pragma once
#include <memory>
#include <string>
#include "AnalogInput.h"
#include "LiveWindow/LiveWindowSendable.h"
#include "SensorBase.h"
#include "interfaces/Potentiometer.h"
#include "networktables/NetworkTableEntry.h"
namespace frc {
@@ -23,7 +21,7 @@ namespace frc {
* units you choose, by way of the scaling and offset constants passed to the
* constructor.
*/
class AnalogPotentiometer : public Potentiometer, public LiveWindowSendable {
class AnalogPotentiometer : public SensorBase, public Potentiometer {
public:
/**
* AnalogPotentiometer constructor.
@@ -52,7 +50,7 @@ class AnalogPotentiometer : public Potentiometer, public LiveWindowSendable {
explicit AnalogPotentiometer(std::shared_ptr<AnalogInput> input,
double fullRange = 1.0, double offset = 0.0);
virtual ~AnalogPotentiometer() = default;
~AnalogPotentiometer() override = default;
/**
* Get the current reading of the potentiomer.
@@ -68,29 +66,11 @@ class AnalogPotentiometer : public Potentiometer, public LiveWindowSendable {
*/
double PIDGet() override;
/*
* Live Window code, only does anything if live window is activated.
*/
std::string GetSmartDashboardType() const override;
void InitTable(std::shared_ptr<nt::NetworkTable> subtable) override;
void UpdateTable() override;
/**
* AnalogPotentiometers don't have to do anything special when entering the
* LiveWindow.
*/
void StartLiveWindowMode() override {}
/**
* AnalogPotentiometers don't have to do anything special when exiting the
* LiveWindow.
*/
void StopLiveWindowMode() override {}
void InitSendable(SendableBuilder& builder) override;
private:
std::shared_ptr<AnalogInput> m_analog_input;
double m_fullRange, m_offset;
nt::NetworkTableEntry m_valueEntry;
};
} // namespace frc

View File

@@ -24,7 +24,7 @@ class AnalogTrigger : public SensorBase {
public:
explicit AnalogTrigger(int channel);
explicit AnalogTrigger(AnalogInput* channel);
virtual ~AnalogTrigger();
~AnalogTrigger() override;
void SetLimitsVoltage(double lower, double upper);
void SetLimitsRaw(int lower, int upper);
@@ -36,6 +36,8 @@ class AnalogTrigger : public SensorBase {
std::shared_ptr<AnalogTriggerOutput> CreateOutput(
AnalogTriggerType type) const;
void InitSendable(SendableBuilder& builder) override;
private:
int m_index;
HAL_AnalogTriggerHandle m_trigger;

View File

@@ -50,7 +50,7 @@ class AnalogTriggerOutput : public DigitalSource {
friend class AnalogTrigger;
public:
virtual ~AnalogTriggerOutput();
~AnalogTriggerOutput() override;
bool Get() const;
// DigitalSource interface
@@ -59,6 +59,8 @@ class AnalogTriggerOutput : public DigitalSource {
bool IsAnalogTrigger() const override;
int GetChannel() const override;
void InitSendable(SendableBuilder& builder) override;
protected:
AnalogTriggerOutput(const AnalogTrigger& trigger,
AnalogTriggerType outputType);

View File

@@ -7,13 +7,8 @@
#pragma once
#include <memory>
#include <string>
#include "LiveWindow/LiveWindowSendable.h"
#include "SensorBase.h"
#include "interfaces/Accelerometer.h"
#include "networktables/NetworkTableEntry.h"
namespace frc {
@@ -22,12 +17,9 @@ namespace frc {
*
* This class allows access to the roboRIO's internal accelerometer.
*/
class BuiltInAccelerometer : public Accelerometer,
public SensorBase,
public LiveWindowSendable {
class BuiltInAccelerometer : public SensorBase, public Accelerometer {
public:
explicit BuiltInAccelerometer(Range range = kRange_8G);
virtual ~BuiltInAccelerometer() = default;
// Accelerometer interface
void SetRange(Range range) override;
@@ -35,16 +27,7 @@ class BuiltInAccelerometer : public Accelerometer,
double GetY() override;
double GetZ() override;
std::string GetSmartDashboardType() const override;
void InitTable(std::shared_ptr<NetworkTable> subtable) override;
void UpdateTable() override;
void StartLiveWindowMode() override {}
void StopLiveWindowMode() override {}
private:
nt::NetworkTableEntry m_xEntry;
nt::NetworkTableEntry m_yEntry;
nt::NetworkTableEntry m_zEntry;
void InitSendable(SendableBuilder& builder) override;
};
} // namespace frc

View File

@@ -7,11 +7,9 @@
#pragma once
#include <memory>
#include <string>
#include <atomic>
#include "SmartDashboard/Sendable.h"
#include "networktables/NetworkTableEntry.h"
#include "SmartDashboard/SendableBase.h"
namespace frc {
@@ -30,10 +28,10 @@ class Command;
* only have to write the {@link Trigger#Get()} method to get the full
* functionality of the Trigger class.
*/
class Trigger : public Sendable {
class Trigger : public SendableBase {
public:
Trigger() = default;
virtual ~Trigger() = default;
~Trigger() override = default;
bool Grab();
virtual bool Get() = 0;
void WhenActive(Command* command);
@@ -42,11 +40,10 @@ class Trigger : public Sendable {
void CancelWhenActive(Command* command);
void ToggleWhenActive(Command* command);
void InitTable(std::shared_ptr<nt::NetworkTable> subtable) override;
std::string GetSmartDashboardType() const override;
void InitSendable(SendableBuilder& builder) override;
protected:
nt::NetworkTableEntry m_pressedEntry;
private:
std::atomic_bool m_sendablePressed{false};
};
} // namespace frc

View File

@@ -11,9 +11,10 @@
#include <set>
#include <string>
#include <llvm/Twine.h>
#include "ErrorBase.h"
#include "SmartDashboard/NamedSendable.h"
#include "networktables/NetworkTableEntry.h"
#include "SmartDashboard/SendableBase.h"
namespace frc {
@@ -44,16 +45,16 @@ class Subsystem;
* @see CommandGroup
* @see Subsystem
*/
class Command : public ErrorBase, public NamedSendable {
class Command : public ErrorBase, public SendableBase {
friend class CommandGroup;
friend class Scheduler;
public:
Command();
explicit Command(const std::string& name);
explicit Command(const llvm::Twine& name);
explicit Command(double timeout);
Command(const std::string& name, double timeout);
virtual ~Command();
Command(const llvm::Twine& name, double timeout);
~Command() override = default;
double TimeSinceInitialized() const;
void Requires(Subsystem* s);
bool IsCanceled() const;
@@ -76,6 +77,7 @@ class Command : public ErrorBase, public NamedSendable {
bool IsTimedOut() const;
bool AssertUnlocked(const std::string& message);
void SetParent(CommandGroup* parent);
bool IsParented() const;
void ClearRequirements();
virtual void Initialize();
@@ -116,9 +118,6 @@ class Command : public ErrorBase, public NamedSendable {
void StartRunning();
void StartTiming();
// The name of this command
std::string m_name;
// The time since this command was initialized
double m_startTime = -1;
@@ -153,14 +152,7 @@ class Command : public ErrorBase, public NamedSendable {
static int m_commandCounter;
public:
std::string GetName() const override;
void InitTable(std::shared_ptr<nt::NetworkTable> subtable) override;
std::string GetSmartDashboardType() const override;
private:
nt::NetworkTableEntry m_runningEntry;
nt::NetworkTableEntry m_isParentedEntry;
NT_EntryListener m_runningListener = 0;
void InitSendable(SendableBuilder& builder) override;
};
} // namespace frc

View File

@@ -54,8 +54,7 @@ class PIDCommand : public Command, public PIDOutput, public PIDSource {
std::shared_ptr<PIDController> m_controller;
public:
void InitTable(std::shared_ptr<nt::NetworkTable> subtable) override;
std::string GetSmartDashboardType() const override;
void InitSendable(SendableBuilder& builder) override;
};
} // namespace frc

View File

@@ -35,7 +35,7 @@ class PIDSubsystem : public Subsystem, public PIDOutput, public PIDSource {
PIDSubsystem(double p, double i, double d);
PIDSubsystem(double p, double i, double d, double f);
PIDSubsystem(double p, double i, double d, double f, double period);
virtual ~PIDSubsystem() = default;
~PIDSubsystem() override = default;
void Enable();
void Disable();
@@ -66,10 +66,6 @@ class PIDSubsystem : public Subsystem, public PIDOutput, public PIDSource {
private:
// The internal PIDController
std::shared_ptr<PIDController> m_controller;
public:
void InitTable(std::shared_ptr<nt::NetworkTable> subtable) override;
std::string GetSmartDashboardType() const override;
};
} // namespace frc

View File

@@ -16,9 +16,7 @@
#include "Commands/Command.h"
#include "ErrorBase.h"
#include "SmartDashboard/NamedSendable.h"
#include "SmartDashboard/SmartDashboard.h"
#include "networktables/NetworkTable.h"
#include "SmartDashboard/SendableBase.h"
#include "networktables/NetworkTableEntry.h"
namespace frc {
@@ -26,7 +24,7 @@ namespace frc {
class ButtonScheduler;
class Subsystem;
class Scheduler : public ErrorBase, public NamedSendable {
class Scheduler : public ErrorBase, public SendableBase {
public:
static Scheduler* GetInstance();
@@ -39,15 +37,11 @@ class Scheduler : public ErrorBase, public NamedSendable {
void ResetAll();
void SetEnabled(bool enabled);
void UpdateTable();
std::string GetSmartDashboardType() const;
void InitTable(std::shared_ptr<nt::NetworkTable> subTable);
std::string GetName() const;
std::string GetType() const;
void InitSendable(SendableBuilder& builder) override;
private:
Scheduler();
virtual ~Scheduler() = default;
~Scheduler() override = default;
void ProcessCommandAddition(Command* command);

View File

@@ -8,49 +8,50 @@
#pragma once
#include <memory>
#include <string>
#include <llvm/StringRef.h>
#include <llvm/Twine.h>
#include "ErrorBase.h"
#include "SmartDashboard/NamedSendable.h"
#include "networktables/NetworkTableEntry.h"
#include "SmartDashboard/Sendable.h"
#include "SmartDashboard/SendableBase.h"
namespace frc {
class Command;
class Subsystem : public ErrorBase, public NamedSendable {
class Subsystem : public ErrorBase, public SendableBase {
friend class Scheduler;
public:
explicit Subsystem(const std::string& name);
virtual ~Subsystem() = default;
explicit Subsystem(const llvm::Twine& name);
void SetDefaultCommand(Command* command);
Command* GetDefaultCommand();
llvm::StringRef GetDefaultCommandName();
void SetCurrentCommand(Command* command);
Command* GetCurrentCommand() const;
llvm::StringRef GetCurrentCommandName() const;
virtual void Periodic();
virtual void InitDefaultCommand();
void AddChild(const llvm::Twine& name, std::shared_ptr<Sendable> child);
void AddChild(const llvm::Twine& name, Sendable* child);
void AddChild(const llvm::Twine& name, Sendable& child);
void AddChild(std::shared_ptr<Sendable> child);
void AddChild(Sendable* child);
void AddChild(Sendable& child);
private:
void ConfirmCommand();
Command* m_currentCommand = nullptr;
bool m_currentCommandChanged = true;
Command* m_defaultCommand = nullptr;
std::string m_name;
bool m_initializedDefaultCommand = false;
public:
std::string GetName() const override;
void InitTable(std::shared_ptr<nt::NetworkTable> subtable) override;
std::string GetSmartDashboardType() const override;
protected:
nt::NetworkTableEntry m_hasDefaultEntry;
nt::NetworkTableEntry m_defaultEntry;
nt::NetworkTableEntry m_hasCommandEntry;
nt::NetworkTableEntry m_commandEntry;
void InitSendable(SendableBuilder& builder) override;
};
} // namespace frc

View File

@@ -7,14 +7,11 @@
#pragma once
#include <memory>
#include <string>
#include <HAL/Types.h>
#include "LiveWindow/LiveWindowSendable.h"
#include "ErrorBase.h"
#include "SensorBase.h"
#include "networktables/NetworkTableEntry.h"
#include "SmartDashboard/SendableBase.h"
namespace frc {
@@ -33,11 +30,11 @@ namespace frc {
* loop control. You can only turn off closed loop control, thereby stopping
* the compressor from operating.
*/
class Compressor : public SensorBase, public LiveWindowSendable {
class Compressor : public ErrorBase, public SendableBase {
public:
// Default PCM ID is 0
explicit Compressor(int pcmID = GetDefaultSolenoidModule());
virtual ~Compressor();
explicit Compressor(int pcmID = SensorBase::GetDefaultSolenoidModule());
~Compressor() override = default;
void Start();
void Stop();
@@ -58,11 +55,7 @@ class Compressor : public SensorBase, public LiveWindowSendable {
bool GetCompressorNotConnectedFault() const;
void ClearAllPCMStickyFaults();
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
std::string GetSmartDashboardType() const override;
void InitTable(std::shared_ptr<nt::NetworkTable> subTable) override;
void InitSendable(SendableBuilder& builder) override;
protected:
HAL_CompressorHandle m_compressorHandle;
@@ -70,10 +63,6 @@ class Compressor : public SensorBase, public LiveWindowSendable {
private:
void SetCompressor(bool on);
int m_module;
nt::NetworkTableEntry m_enabledEntry;
nt::NetworkTableEntry m_pressureSwitchEntry;
NT_EntryListener m_enabledListener = 0;
};
} // namespace frc

View File

@@ -8,16 +8,13 @@
#pragma once
#include <memory>
#include <string>
#include <HAL/Counter.h>
#include <HAL/Types.h>
#include "AnalogTrigger.h"
#include "CounterBase.h"
#include "LiveWindow/LiveWindowSendable.h"
#include "SensorBase.h"
#include "networktables/NetworkTableEntry.h"
namespace frc {
@@ -33,9 +30,7 @@ class DigitalGlitchFilter;
* All counters will immediately start counting - Reset() them if you need them
* to be zeroed before use.
*/
class Counter : public SensorBase,
public CounterBase,
public LiveWindowSendable {
class Counter : public SensorBase, public CounterBase {
public:
enum Mode {
kTwoPulse = 0,
@@ -53,7 +48,7 @@ class Counter : public SensorBase,
DigitalSource* downSource, bool inverted);
Counter(EncodingType encodingType, std::shared_ptr<DigitalSource> upSource,
std::shared_ptr<DigitalSource> downSource, bool inverted);
virtual ~Counter();
~Counter() override;
void SetUpSource(int channel);
void SetUpSource(AnalogTrigger* analogTrigger, AnalogTriggerType triggerType);
@@ -96,11 +91,7 @@ class Counter : public SensorBase,
int GetSamplesToAverage() const;
int GetFPGAIndex() const { return m_index; }
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
std::string GetSmartDashboardType() const override;
void InitTable(std::shared_ptr<nt::NetworkTable> subTable) override;
void InitSendable(SendableBuilder& builder) override;
protected:
// Makes the counter count up.
@@ -115,7 +106,6 @@ class Counter : public SensorBase,
private:
int m_index = 0; // The index of this counter.
nt::NetworkTableEntry m_valueEntry;
friend class DigitalGlitchFilter;
};

View File

@@ -14,6 +14,7 @@
#include <support/mutex.h>
#include "DigitalSource.h"
#include "SensorBase.h"
namespace frc {
@@ -30,7 +31,7 @@ class Counter;
class DigitalGlitchFilter : public SensorBase {
public:
DigitalGlitchFilter();
~DigitalGlitchFilter();
~DigitalGlitchFilter() override;
void Add(DigitalSource* input);
void Add(Encoder* input);
@@ -46,6 +47,8 @@ class DigitalGlitchFilter : public SensorBase {
int GetPeriodCycles();
uint64_t GetPeriodNanoSeconds();
void InitSendable(SendableBuilder& builder) override;
private:
// Sets the filter for the input to be the requested index. A value of 0
// disables the filter, and the filter value must be between 1 and 3,

View File

@@ -7,12 +7,7 @@
#pragma once
#include <memory>
#include <string>
#include "DigitalSource.h"
#include "LiveWindow/LiveWindowSendable.h"
#include "networktables/NetworkTableEntry.h"
namespace frc {
@@ -27,10 +22,10 @@ class DigitalGlitchFilter;
* as required. This class is only for devices like switches etc. that aren't
* implemented anywhere else.
*/
class DigitalInput : public DigitalSource, public LiveWindowSendable {
class DigitalInput : public DigitalSource {
public:
explicit DigitalInput(int channel);
virtual ~DigitalInput();
~DigitalInput() override;
bool Get() const;
int GetChannel() const override;
@@ -39,17 +34,12 @@ class DigitalInput : public DigitalSource, public LiveWindowSendable {
AnalogTriggerType GetAnalogTriggerTypeForRouting() const override;
bool IsAnalogTrigger() const override;
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
std::string GetSmartDashboardType() const override;
void InitTable(std::shared_ptr<nt::NetworkTable> subTable) override;
void InitSendable(SendableBuilder& builder) override;
private:
int m_channel;
HAL_DigitalHandle m_handle;
nt::NetworkTableEntry m_valueEntry;
friend class DigitalGlitchFilter;
};

View File

@@ -7,14 +7,10 @@
#pragma once
#include <memory>
#include <string>
#include <HAL/Types.h>
#include "DigitalSource.h"
#include "LiveWindow/LiveWindowSendable.h"
#include "networktables/NetworkTableEntry.h"
#include "ErrorBase.h"
#include "SmartDashboard/SendableBase.h"
namespace frc {
@@ -25,13 +21,13 @@ namespace frc {
* elsewhere will allocate channels automatically so for those devices it
* shouldn't be done here.
*/
class DigitalOutput : public DigitalSource, public LiveWindowSendable {
class DigitalOutput : public ErrorBase, public SendableBase {
public:
explicit DigitalOutput(int channel);
virtual ~DigitalOutput();
~DigitalOutput() override;
void Set(bool value);
bool Get() const;
int GetChannel() const override;
int GetChannel() const;
void Pulse(double length);
bool IsPulsing() const;
void SetPWMRate(double rate);
@@ -39,24 +35,12 @@ class DigitalOutput : public DigitalSource, public LiveWindowSendable {
void DisablePWM();
void UpdateDutyCycle(double dutyCycle);
// Digital Source Interface
HAL_Handle GetPortHandleForRouting() const override;
AnalogTriggerType GetAnalogTriggerTypeForRouting() const override;
bool IsAnalogTrigger() const override;
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
std::string GetSmartDashboardType() const override;
void InitTable(std::shared_ptr<nt::NetworkTable> subTable) override;
void InitSendable(SendableBuilder& builder) override;
private:
int m_channel;
HAL_DigitalHandle m_handle;
HAL_DigitalPWMHandle m_pwmGenerator;
nt::NetworkTableEntry m_valueEntry;
NT_EntryListener m_valueListener = 0;
};
} // namespace frc

View File

@@ -24,7 +24,6 @@ namespace frc {
*/
class DigitalSource : public InterruptableSensorBase {
public:
virtual ~DigitalSource() = default;
virtual HAL_Handle GetPortHandleForRouting() const = 0;
virtual AnalogTriggerType GetAnalogTriggerTypeForRouting() const = 0;
virtual bool IsAnalogTrigger() const = 0;

View File

@@ -7,14 +7,9 @@
#pragma once
#include <memory>
#include <string>
#include <HAL/Types.h>
#include "LiveWindow/LiveWindowSendable.h"
#include "SolenoidBase.h"
#include "networktables/NetworkTableEntry.h"
namespace frc {
@@ -25,23 +20,19 @@ namespace frc {
* The DoubleSolenoid class is typically used for pneumatics solenoids that
* have two positions controlled by two separate channels.
*/
class DoubleSolenoid : public SolenoidBase, public LiveWindowSendable {
class DoubleSolenoid : public SolenoidBase {
public:
enum Value { kOff, kForward, kReverse };
explicit DoubleSolenoid(int forwardChannel, int reverseChannel);
DoubleSolenoid(int moduleNumber, int forwardChannel, int reverseChannel);
virtual ~DoubleSolenoid();
~DoubleSolenoid() override;
virtual void Set(Value value);
virtual Value Get() const;
bool IsFwdSolenoidBlackListed() const;
bool IsRevSolenoidBlackListed() const;
void UpdateTable();
void StartLiveWindowMode();
void StopLiveWindowMode();
std::string GetSmartDashboardType() const;
void InitTable(std::shared_ptr<nt::NetworkTable> subTable);
void InitSendable(SendableBuilder& builder) override;
private:
int m_forwardChannel; // The forward channel on the module to control.
@@ -50,9 +41,6 @@ class DoubleSolenoid : public SolenoidBase, public LiveWindowSendable {
int m_reverseMask; // The mask for the reverse channel.
HAL_SolenoidHandle m_forwardHandle = HAL_kInvalidHandle;
HAL_SolenoidHandle m_reverseHandle = HAL_kInvalidHandle;
nt::NetworkTableEntry m_valueEntry;
NT_EntryListener m_valueListener = 0;
};
} // namespace frc

View File

@@ -102,7 +102,7 @@ class DifferentialDrive : public RobotDriveBase {
static constexpr double kDefaultQuickStopAlpha = 0.1;
DifferentialDrive(SpeedController& leftMotor, SpeedController& rightMotor);
virtual ~DifferentialDrive() = default;
~DifferentialDrive() override = default;
DifferentialDrive(const DifferentialDrive&) = delete;
DifferentialDrive& operator=(const DifferentialDrive&) = delete;
@@ -118,6 +118,8 @@ class DifferentialDrive : public RobotDriveBase {
void StopMotor() override;
void GetDescription(llvm::raw_ostream& desc) const override;
void InitSendable(SendableBuilder& builder) override;
private:
SpeedController& m_leftMotor;
SpeedController& m_rightMotor;

View File

@@ -55,7 +55,7 @@ class KilloughDrive : public RobotDriveBase {
KilloughDrive(SpeedController& leftMotor, SpeedController& rightMotor,
SpeedController& backMotor, double leftMotorAngle,
double rightMotorAngle, double backMotorAngle);
virtual ~KilloughDrive() = default;
~KilloughDrive() override = default;
KilloughDrive(const KilloughDrive&) = delete;
KilloughDrive& operator=(const KilloughDrive&) = delete;
@@ -67,6 +67,8 @@ class KilloughDrive : public RobotDriveBase {
void StopMotor() override;
void GetDescription(llvm::raw_ostream& desc) const override;
void InitSendable(SendableBuilder& builder) override;
private:
SpeedController& m_leftMotor;
SpeedController& m_rightMotor;

View File

@@ -67,7 +67,7 @@ class MecanumDrive : public RobotDriveBase {
MecanumDrive(SpeedController& frontLeftMotor, SpeedController& rearLeftMotor,
SpeedController& frontRightMotor,
SpeedController& rearRightMotor);
virtual ~MecanumDrive() = default;
~MecanumDrive() override = default;
MecanumDrive(const MecanumDrive&) = delete;
MecanumDrive& operator=(const MecanumDrive&) = delete;
@@ -79,6 +79,8 @@ class MecanumDrive : public RobotDriveBase {
void StopMotor() override;
void GetDescription(llvm::raw_ostream& desc) const override;
void InitSendable(SendableBuilder& builder) override;
private:
SpeedController& m_frontLeftMotor;
SpeedController& m_rearLeftMotor;

View File

@@ -12,9 +12,9 @@
#include <llvm/ArrayRef.h>
#include <llvm/raw_ostream.h>
#include "ErrorBase.h"
#include "MotorSafety.h"
#include "MotorSafetyHelper.h"
#include "SmartDashboard/SendableBase.h"
namespace frc {
@@ -23,7 +23,7 @@ class SpeedController;
/**
* Common base class for drive platforms.
*/
class RobotDriveBase : public MotorSafety, public ErrorBase {
class RobotDriveBase : public MotorSafety, public SendableBase {
public:
/**
* The location of a motor on the robot for the purpose of driving.
@@ -39,7 +39,7 @@ class RobotDriveBase : public MotorSafety, public ErrorBase {
};
RobotDriveBase();
virtual ~RobotDriveBase() = default;
~RobotDriveBase() override = default;
RobotDriveBase(const RobotDriveBase&) = delete;
RobotDriveBase& operator=(const RobotDriveBase&) = delete;

View File

@@ -17,8 +17,8 @@
#include <llvm/StringRef.h>
#include <support/mutex.h>
#include "ErrorBase.h"
#include "RobotState.h"
#include "SensorBase.h"
namespace frc {
@@ -28,12 +28,12 @@ struct MatchInfoData;
* Provide access to the network communication data to / from the Driver
* Station.
*/
class DriverStation : public SensorBase, public RobotStateInterface {
class DriverStation : public ErrorBase, public RobotStateInterface {
public:
enum Alliance { kRed, kBlue, kInvalid };
enum MatchType { kNone, kPractice, kQualification, kElimination };
virtual ~DriverStation();
~DriverStation() override;
static DriverStation& GetInstance();
static void ReportError(llvm::StringRef error);
static void ReportWarning(llvm::StringRef error);

View File

@@ -8,16 +8,13 @@
#pragma once
#include <memory>
#include <string>
#include <HAL/Encoder.h>
#include "Counter.h"
#include "CounterBase.h"
#include "LiveWindow/LiveWindowSendable.h"
#include "PIDSource.h"
#include "SensorBase.h"
#include "networktables/NetworkTableEntry.h"
namespace frc {
@@ -39,10 +36,7 @@ class DigitalGlitchFilter;
* All encoders will immediately start counting - Reset() them if you need them
* to be zeroed before use.
*/
class Encoder : public SensorBase,
public CounterBase,
public PIDSource,
public LiveWindowSendable {
class Encoder : public SensorBase, public CounterBase, public PIDSource {
public:
enum IndexingType {
kResetWhileHigh,
@@ -60,7 +54,7 @@ class Encoder : public SensorBase,
bool reverseDirection = false, EncodingType encodingType = k4X);
Encoder(DigitalSource& aSource, DigitalSource& bSource,
bool reverseDirection = false, EncodingType encodingType = k4X);
virtual ~Encoder();
~Encoder() override;
// CounterBase interface
int Get() const override;
@@ -76,6 +70,7 @@ class Encoder : public SensorBase,
double GetRate() const;
void SetMinRate(double minRate);
void SetDistancePerPulse(double distancePerPulse);
double GetDistancePerPulse() const;
void SetReverseDirection(bool reverseDirection);
void SetSamplesToAverage(int samplesToAverage);
int GetSamplesToAverage() const;
@@ -85,11 +80,7 @@ class Encoder : public SensorBase,
void SetIndexSource(const DigitalSource& source,
IndexingType type = kResetOnRisingEdge);
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
std::string GetSmartDashboardType() const override;
void InitTable(std::shared_ptr<nt::NetworkTable> subTable) override;
void InitSendable(SendableBuilder& builder) override;
int GetFPGAIndex() const;
@@ -103,9 +94,6 @@ class Encoder : public SensorBase,
std::unique_ptr<DigitalSource> m_indexSource = nullptr;
HAL_EncoderHandle m_encoder = HAL_kInvalidHandle;
nt::NetworkTableEntry m_speedEntry;
nt::NetworkTableEntry m_distanceEntry;
nt::NetworkTableEntry m_distancePerTickEntry;
friend class DigitalGlitchFilter;
};

View File

@@ -30,11 +30,10 @@ class GearTooth : public Counter {
explicit GearTooth(DigitalSource* source, bool directionSensitive = false);
explicit GearTooth(std::shared_ptr<DigitalSource> source,
bool directionSensitive = false);
virtual ~GearTooth() = default;
void EnableDirectionSensing(bool directionSensitive);
std::string GetSmartDashboardType() const override;
void InitSendable(SendableBuilder& builder) override;
};
} // namespace frc

View File

@@ -7,14 +7,9 @@
#pragma once
#include <memory>
#include <string>
#include "LiveWindow/LiveWindowSendable.h"
#include "PIDSource.h"
#include "SensorBase.h"
#include "interfaces/Gyro.h"
#include "networktables/NetworkTableEntry.h"
namespace frc {
@@ -22,24 +17,12 @@ namespace frc {
* GyroBase is the common base class for Gyro implementations such as
* AnalogGyro.
*/
class GyroBase : public Gyro,
public SensorBase,
public PIDSource,
public LiveWindowSendable {
class GyroBase : public Gyro, public SensorBase, public PIDSource {
public:
virtual ~GyroBase() = default;
// PIDSource interface
double PIDGet() override;
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
std::string GetSmartDashboardType() const override;
void InitTable(std::shared_ptr<nt::NetworkTable> subTable) override;
private:
nt::NetworkTableEntry m_valueEntry;
void InitSendable(SendableBuilder& builder) override;
};
} // namespace frc

View File

@@ -9,7 +9,7 @@
#include <stdint.h>
#include "SensorBase.h"
#include "ErrorBase.h"
enum HAL_I2CPort : int32_t;
@@ -21,12 +21,12 @@ namespace frc {
* This class is intended to be used by sensor (and other I2C device) drivers.
* It probably should not be used directly.
*/
class I2C : SensorBase {
class I2C : public ErrorBase {
public:
enum Port { kOnboard = 0, kMXP };
I2C(Port port, int deviceAddress);
virtual ~I2C();
~I2C() override;
I2C(const I2C&) = delete;
I2C& operator=(const I2C&) = delete;

View File

@@ -24,7 +24,6 @@ class InterruptableSensorBase : public SensorBase {
};
InterruptableSensorBase() = default;
virtual ~InterruptableSensorBase() = default;
virtual HAL_Handle GetPortHandleForRouting() const = 0;
virtual AnalogTriggerType GetAnalogTriggerTypeForRouting() const = 0;

View File

@@ -17,7 +17,6 @@ namespace frc {
class Jaguar : public PWMSpeedController {
public:
explicit Jaguar(int channel);
virtual ~Jaguar() = default;
};
} // namespace frc

View File

@@ -7,82 +7,76 @@
#pragma once
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "Commands/Scheduler.h"
#include "LiveWindow/LiveWindowSendable.h"
#include "networktables/NetworkTable.h"
#include "networktables/NetworkTableEntry.h"
#include <llvm/Twine.h>
#include <support/deprecated.h>
#include "SmartDashboard/Sendable.h"
namespace frc {
struct LiveWindowComponent {
std::string subsystem;
std::string name;
bool isSensor = false;
LiveWindowComponent() = default;
LiveWindowComponent(std::string subsystem, std::string name, bool isSensor) {
this->subsystem = subsystem;
this->name = name;
this->isSensor = isSensor;
}
};
/**
* The LiveWindow class is the public interface for putting sensors and
* actuators on the LiveWindow.
*/
class LiveWindow {
public:
LiveWindow(const LiveWindow&) = delete;
LiveWindow& operator=(const LiveWindow&) = delete;
static LiveWindow* GetInstance();
void Run();
void AddSensor(const std::string& subsystem, const std::string& name,
LiveWindowSendable* component);
void AddSensor(const std::string& subsystem, const std::string& name,
LiveWindowSendable& component);
void AddSensor(const std::string& subsystem, const std::string& name,
std::shared_ptr<LiveWindowSendable> component);
void AddActuator(const std::string& subsystem, const std::string& name,
LiveWindowSendable* component);
void AddActuator(const std::string& subsystem, const std::string& name,
LiveWindowSendable& component);
void AddActuator(const std::string& subsystem, const std::string& name,
std::shared_ptr<LiveWindowSendable> component);
void AddSensor(std::string type, int channel, LiveWindowSendable* component);
void AddActuator(std::string type, int channel,
LiveWindowSendable* component);
void AddActuator(std::string type, int module, int channel,
LiveWindowSendable* component);
WPI_DEPRECATED("no longer required")
void Run() { UpdateValues(); }
bool IsEnabled() const { return m_enabled; }
WPI_DEPRECATED("use Sendable::SetName() instead")
void AddSensor(const llvm::Twine& subsystem, const llvm::Twine& name,
Sendable* component);
WPI_DEPRECATED("use Sendable::SetName() instead")
void AddSensor(const llvm::Twine& subsystem, const llvm::Twine& name,
Sendable& component);
WPI_DEPRECATED("use Sendable::SetName() instead")
void AddSensor(const llvm::Twine& subsystem, const llvm::Twine& name,
std::shared_ptr<Sendable> component);
WPI_DEPRECATED("use Sendable::SetName() instead")
void AddActuator(const llvm::Twine& subsystem, const llvm::Twine& name,
Sendable* component);
WPI_DEPRECATED("use Sendable::SetName() instead")
void AddActuator(const llvm::Twine& subsystem, const llvm::Twine& name,
Sendable& component);
WPI_DEPRECATED("use Sendable::SetName() instead")
void AddActuator(const llvm::Twine& subsystem, const llvm::Twine& name,
std::shared_ptr<Sendable> component);
WPI_DEPRECATED("use SensorBase::SetName() instead")
void AddSensor(const llvm::Twine& type, int channel, Sendable* component);
WPI_DEPRECATED("use SensorBase::SetName() instead")
void AddActuator(const llvm::Twine& type, int channel, Sendable* component);
WPI_DEPRECATED("use SensorBase::SetName() instead")
void AddActuator(const llvm::Twine& type, int module, int channel,
Sendable* component);
void Add(std::shared_ptr<Sendable> component);
void Add(Sendable* component);
void AddChild(Sendable* parent, std::shared_ptr<Sendable> component);
void AddChild(Sendable* parent, void* component);
void Remove(Sendable* component);
void EnableTelemetry(Sendable* component);
void DisableTelemetry(Sendable* component);
void DisableAllTelemetry();
bool IsEnabled() const;
void SetEnabled(bool enabled);
protected:
LiveWindow();
virtual ~LiveWindow() = default;
void UpdateValues();
private:
void UpdateValues();
void Initialize();
void InitializeLiveWindowComponents();
LiveWindow();
std::vector<std::shared_ptr<LiveWindowSendable>> m_sensors;
std::map<std::shared_ptr<LiveWindowSendable>, LiveWindowComponent>
m_components;
std::shared_ptr<nt::NetworkTable> m_liveWindowTable;
std::shared_ptr<nt::NetworkTable> m_statusTable;
nt::NetworkTableEntry m_enabledEntry;
Scheduler* m_scheduler;
bool m_enabled = false;
bool m_firstTime = true;
struct Impl;
std::unique_ptr<Impl> m_impl;
};
} // namespace frc

View File

@@ -1,36 +0,0 @@
/*----------------------------------------------------------------------------*/
/* Copyright (c) 2012-2017 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. */
/*----------------------------------------------------------------------------*/
#pragma once
#include "SmartDashboard/Sendable.h"
namespace frc {
/**
* Live Window Sendable is a special type of object sendable to the live window.
*/
class LiveWindowSendable : public Sendable {
public:
/**
* Update the table for this sendable object with the latest values.
*/
virtual void UpdateTable() = 0;
/**
* Start having this sendable object automatically respond to value changes
* reflect the value on the table.
*/
virtual void StartLiveWindowMode() = 0;
/**
* Stop having this sendable object automatically respond to value changes.
*/
virtual void StopLiveWindowMode() = 0;
};
} // namespace frc

View File

@@ -8,28 +8,27 @@
#pragma once
#include <atomic>
#include <memory>
#include <string>
#include "DigitalOutput.h"
#include "LiveWindow/LiveWindowSendable.h"
#include "ErrorBase.h"
#include "MotorSafety.h"
#include "MotorSafetyHelper.h"
#include "PWM.h"
#include "SmartDashboard/SendableBase.h"
#include "SpeedController.h"
#include "networktables/NetworkTableEntry.h"
namespace frc {
/**
* Nidec Brushless Motor.
*/
class NidecBrushless : public SpeedController,
public MotorSafety,
public LiveWindowSendable {
class NidecBrushless : public ErrorBase,
public SendableBase,
public SpeedController,
public MotorSafety {
public:
NidecBrushless(int pwmChannel, int dioChannel);
~NidecBrushless() = default;
~NidecBrushless() override = default;
// SpeedController interface
void Set(double speed) override;
@@ -55,13 +54,7 @@ class NidecBrushless : public SpeedController,
int GetChannel() const;
// Sendable interface
void InitTable(std::shared_ptr<nt::NetworkTable> subtable) override;
std::string GetSmartDashboardType() const override;
// LiveWindowSendable interface
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
void InitSendable(SendableBuilder& builder) override;
private:
MotorSafetyHelper m_safetyHelper;
@@ -70,8 +63,6 @@ class NidecBrushless : public SpeedController,
DigitalOutput m_dio;
PWM m_pwm;
double m_speed = 0.0;
nt::NetworkTableEntry m_valueEntry;
int m_valueListener;
};
} // namespace frc

View File

@@ -7,21 +7,20 @@
#pragma once
#include <atomic>
#include <memory>
#include <string>
#include <support/deprecated.h>
#include <support/mutex.h>
#include "Base.h"
#include "Controller.h"
#include "Filters/LinearDigitalFilter.h"
#include "LiveWindow/LiveWindow.h"
#include "Notifier.h"
#include "PIDInterface.h"
#include "PIDSource.h"
#include "SmartDashboard/SendableBase.h"
#include "Timer.h"
#include "networktables/NetworkTableEntry.h"
namespace frc {
@@ -37,7 +36,7 @@ class PIDOutput;
* in the integral and derivative calculations. Therefore, the sample rate
* affects the controller's behavior for a given set of PID constants.
*/
class PIDController : public LiveWindowSendable, public PIDInterface {
class PIDController : public SendableBase, public PIDInterface {
public:
PIDController(double p, double i, double d, PIDSource* source,
PIDOutput* output, double period = 0.05);
@@ -47,7 +46,7 @@ class PIDController : public LiveWindowSendable, public PIDInterface {
PIDOutput& output, double period = 0.05);
PIDController(double p, double i, double d, double f, PIDSource& source,
PIDOutput& output, double period = 0.05);
virtual ~PIDController();
~PIDController() override;
PIDController(const PIDController&) = delete;
PIDController& operator=(const PIDController) = delete;
@@ -58,6 +57,10 @@ class PIDController : public LiveWindowSendable, public PIDInterface {
virtual void SetOutputRange(double minimumOutput, double maximumOutput);
void SetPID(double p, double i, double d) override;
virtual void SetPID(double p, double i, double d, double f);
void SetP(double p);
void SetI(double i);
void SetD(double d);
void SetF(double f);
double GetP() const override;
double GetI() const override;
double GetD() const override;
@@ -87,29 +90,17 @@ class PIDController : public LiveWindowSendable, public PIDInterface {
void Enable() override;
void Disable() override;
void SetEnabled(bool enable);
bool IsEnabled() const override;
void Reset() override;
void InitTable(std::shared_ptr<nt::NetworkTable> subtable) override;
void InitSendable(SendableBuilder& builder) override;
protected:
PIDSource* m_pidInput;
PIDOutput* m_pidOutput;
nt::NetworkTableEntry m_pEntry;
nt::NetworkTableEntry m_iEntry;
nt::NetworkTableEntry m_dEntry;
nt::NetworkTableEntry m_fEntry;
nt::NetworkTableEntry m_setpointEntry;
nt::NetworkTableEntry m_enabledEntry;
NT_EntryListener m_pListener = 0;
NT_EntryListener m_iListener = 0;
NT_EntryListener m_dListener = 0;
NT_EntryListener m_fListener = 0;
NT_EntryListener m_setpointListener = 0;
NT_EntryListener m_enabledListener = 0;
virtual void Calculate();
virtual double CalculateFeedForward();
double GetContinuousError(double error) const;
@@ -180,12 +171,6 @@ class PIDController : public LiveWindowSendable, public PIDInterface {
std::unique_ptr<Notifier> m_controlLoop;
Timer m_setpointTimer;
std::string GetSmartDashboardType() const override;
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
void RemoveListeners();
};
} // namespace frc

View File

@@ -9,7 +9,6 @@
#include "Base.h"
#include "Controller.h"
#include "LiveWindow/LiveWindow.h"
namespace frc {

View File

@@ -9,14 +9,10 @@
#include <stdint.h>
#include <memory>
#include <string>
#include <HAL/Types.h>
#include "LiveWindow/LiveWindowSendable.h"
#include "SensorBase.h"
#include "networktables/NetworkTableEntry.h"
#include "ErrorBase.h"
#include "SmartDashboard/SendableBase.h"
namespace frc {
@@ -37,7 +33,7 @@ namespace frc {
* - 1 = minimum pulse width (currently .5ms)
* - 0 = disabled (i.e. PWM output is held low)
*/
class PWM : public SensorBase, public LiveWindowSendable {
class PWM : public ErrorBase, public SendableBase {
public:
/**
* Represents the amount to multiply the minimum servo-pulse pwm period by.
@@ -58,7 +54,7 @@ class PWM : public SensorBase, public LiveWindowSendable {
};
explicit PWM(int channel);
virtual ~PWM();
~PWM() override;
virtual void SetRaw(uint16_t value);
virtual uint16_t GetRaw() const;
virtual void SetPosition(double pos);
@@ -78,14 +74,7 @@ class PWM : public SensorBase, public LiveWindowSendable {
int GetChannel() const { return m_channel; }
protected:
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
std::string GetSmartDashboardType() const override;
void InitTable(std::shared_ptr<nt::NetworkTable> subTable) override;
nt::NetworkTableEntry m_valueEntry;
NT_EntryListener m_valueListener = 0;
void InitSendable(SendableBuilder& builder) override;
private:
int m_channel;

View File

@@ -17,7 +17,6 @@ namespace frc {
*/
class PWMSpeedController : public SafePWM, public SpeedController {
public:
virtual ~PWMSpeedController() = default;
void Set(double value) override;
double Get() const override;
void SetInverted(bool isInverted) override;

View File

@@ -18,7 +18,6 @@ namespace frc {
class PWMTalonSRX : public PWMSpeedController {
public:
explicit PWMTalonSRX(int channel);
virtual ~PWMTalonSRX() = default;
};
} // namespace frc

View File

@@ -7,12 +7,7 @@
#pragma once
#include <memory>
#include <string>
#include "LiveWindow/LiveWindowSendable.h"
#include "SensorBase.h"
#include "networktables/NetworkTableEntry.h"
namespace frc {
@@ -20,7 +15,7 @@ namespace frc {
* Class for getting voltage, current, temperature, power and energy from the
* CAN PDP.
*/
class PowerDistributionPanel : public SensorBase, public LiveWindowSendable {
class PowerDistributionPanel : public SensorBase {
public:
PowerDistributionPanel();
explicit PowerDistributionPanel(int module);
@@ -34,16 +29,9 @@ class PowerDistributionPanel : public SensorBase, public LiveWindowSendable {
void ResetTotalEnergy();
void ClearStickyFaults();
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
std::string GetSmartDashboardType() const override;
void InitTable(std::shared_ptr<nt::NetworkTable> subTable) override;
void InitSendable(SendableBuilder& builder) override;
private:
nt::NetworkTableEntry m_chanEntry[16];
nt::NetworkTableEntry m_voltageEntry;
nt::NetworkTableEntry m_totalCurrentEntry;
int m_module;
};

View File

@@ -8,15 +8,13 @@
#pragma once
#include <memory>
#include <string>
#include <HAL/Types.h>
#include <llvm/raw_ostream.h>
#include "LiveWindow/LiveWindowSendable.h"
#include "ErrorBase.h"
#include "MotorSafety.h"
#include "SensorBase.h"
#include "networktables/NetworkTableEntry.h"
#include "SmartDashboard/SendableBase.h"
namespace frc {
@@ -34,13 +32,13 @@ class MotorSafetyHelper;
* independently for something that does not care about voltage polarity (like
* a solenoid).
*/
class Relay : public MotorSafety, public SensorBase, public LiveWindowSendable {
class Relay : public MotorSafety, public ErrorBase, public SendableBase {
public:
enum Value { kOff, kOn, kForward, kReverse };
enum Direction { kBothDirections, kForwardOnly, kReverseOnly };
explicit Relay(int channel, Direction direction = kBothDirections);
virtual ~Relay();
~Relay() override;
void Set(Value value);
Value Get() const;
@@ -54,15 +52,7 @@ class Relay : public MotorSafety, public SensorBase, public LiveWindowSendable {
void SetSafetyEnabled(bool enabled) override;
void GetDescription(llvm::raw_ostream& desc) const override;
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
std::string GetSmartDashboardType() const override;
void InitTable(std::shared_ptr<nt::NetworkTable> subTable) override;
protected:
nt::NetworkTableEntry m_valueEntry;
NT_EntryListener m_valueListener = 0;
void InitSendable(SendableBuilder& builder) override;
private:
int m_channel;

View File

@@ -17,7 +17,6 @@ namespace frc {
class SD540 : public PWMSpeedController {
public:
explicit SD540(int channel);
virtual ~SD540() = default;
};
} // namespace frc

View File

@@ -9,15 +9,12 @@
#include <stdint.h>
#include "SensorBase.h"
#include "ErrorBase.h"
enum HAL_SPIPort : int32_t;
namespace frc {
class DigitalOutput;
class DigitalInput;
/**
* SPI bus interface class.
*
@@ -25,12 +22,12 @@ class DigitalInput;
* It probably should not be used directly.
*
*/
class SPI : public SensorBase {
class SPI : public ErrorBase {
public:
enum Port { kOnboardCS0 = 0, kOnboardCS1, kOnboardCS2, kOnboardCS3, kMXP };
explicit SPI(Port port);
virtual ~SPI();
~SPI() override;
SPI(const SPI&) = delete;
SPI& operator=(const SPI&) = delete;

View File

@@ -7,8 +7,12 @@
#pragma once
#include <memory>
#include "Base.h"
#include "ErrorBase.h"
#include "SmartDashboard/Sendable.h"
#include "SmartDashboard/SendableBase.h"
namespace frc {
@@ -18,10 +22,9 @@ namespace frc {
* Stores most recent status information as well as containing utility functions
* for checking channels and error processing.
*/
class SensorBase : public ErrorBase {
class SensorBase : public ErrorBase, public SendableBase {
public:
SensorBase() = default;
virtual ~SensorBase() = default;
SensorBase(const SensorBase&) = delete;
SensorBase& operator=(const SensorBase&) = delete;

View File

@@ -7,12 +7,8 @@
#pragma once
#include <memory>
#include <string>
#include "SafePWM.h"
#include "SpeedController.h"
#include "networktables/NetworkTableEntry.h"
namespace frc {
@@ -25,7 +21,6 @@ namespace frc {
class Servo : public SafePWM {
public:
explicit Servo(int channel);
virtual ~Servo();
void Set(double value);
void SetOffline();
double Get() const;
@@ -34,15 +29,7 @@ class Servo : public SafePWM {
static double GetMaxAngle() { return kMaxServoAngle; }
static double GetMinAngle() { return kMinServoAngle; }
void UpdateTable() override;
void StartLiveWindowMode() override;
void StopLiveWindowMode() override;
std::string GetSmartDashboardType() const override;
void InitTable(std::shared_ptr<nt::NetworkTable> subTable) override;
protected:
nt::NetworkTableEntry m_valueEntry;
NT_EntryListener m_valueListener = 0;
void InitSendable(SendableBuilder& builder) override;
private:
double GetServoAngleRange() const { return kMaxServoAngle - kMinServoAngle; }

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