mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-20 00:51:42 +00:00
[wpilib] Remove PIDController, PIDOutput, PIDSource
Move them to the old commands vendordep so that PIDCommand and PIDSubsystem continue to work. This also removes Filter and LinearDigitalFilter.
This commit is contained in:
@@ -48,10 +48,6 @@ void AnalogAccelerometer::SetZero(double zero) {
|
||||
m_zeroGVoltage = zero;
|
||||
}
|
||||
|
||||
double AnalogAccelerometer::PIDGet() {
|
||||
return GetAcceleration();
|
||||
}
|
||||
|
||||
void AnalogAccelerometer::InitSendable(SendableBuilder& builder) {
|
||||
builder.SetSmartDashboardType("Accelerometer");
|
||||
builder.AddDoubleProperty(
|
||||
|
||||
@@ -254,13 +254,6 @@ double AnalogInput::GetSampleRate() {
|
||||
return sampleRate;
|
||||
}
|
||||
|
||||
double AnalogInput::PIDGet() {
|
||||
if (StatusIsFatal()) {
|
||||
return 0.0;
|
||||
}
|
||||
return GetAverageVoltage();
|
||||
}
|
||||
|
||||
void AnalogInput::SetSimDevice(HAL_SimDeviceHandle device) {
|
||||
HAL_SetAnalogInputSimDevice(m_port, device);
|
||||
}
|
||||
|
||||
@@ -42,10 +42,6 @@ double AnalogPotentiometer::Get() const {
|
||||
m_offset;
|
||||
}
|
||||
|
||||
double AnalogPotentiometer::PIDGet() {
|
||||
return Get();
|
||||
}
|
||||
|
||||
void AnalogPotentiometer::InitSendable(SendableBuilder& builder) {
|
||||
builder.SetSmartDashboardType("Analog Input");
|
||||
builder.AddDoubleProperty(
|
||||
|
||||
@@ -213,20 +213,6 @@ int Encoder::GetSamplesToAverage() const {
|
||||
return result;
|
||||
}
|
||||
|
||||
double Encoder::PIDGet() {
|
||||
if (StatusIsFatal()) {
|
||||
return 0.0;
|
||||
}
|
||||
switch (GetPIDSourceType()) {
|
||||
case PIDSourceType::kDisplacement:
|
||||
return GetDistance();
|
||||
case PIDSourceType::kRate:
|
||||
return GetRate();
|
||||
default:
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void Encoder::SetIndexSource(int channel, Encoder::IndexingType type) {
|
||||
// Force digital input if just given an index
|
||||
m_indexSource = std::make_shared<DigitalInput>(channel);
|
||||
|
||||
@@ -9,17 +9,6 @@
|
||||
|
||||
using namespace frc;
|
||||
|
||||
double GyroBase::PIDGet() {
|
||||
switch (GetPIDSourceType()) {
|
||||
case PIDSourceType::kRate:
|
||||
return GetRate();
|
||||
case PIDSourceType::kDisplacement:
|
||||
return GetAngle();
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void GyroBase::InitSendable(SendableBuilder& builder) {
|
||||
builder.SetSmartDashboardType("Gyro");
|
||||
builder.AddDoubleProperty(
|
||||
|
||||
@@ -59,10 +59,6 @@ void NidecBrushless::Enable() {
|
||||
m_disabled = false;
|
||||
}
|
||||
|
||||
void NidecBrushless::PIDWrite(double output) {
|
||||
Set(output);
|
||||
}
|
||||
|
||||
void NidecBrushless::StopMotor() {
|
||||
m_dio.UpdateDutyCycle(0.5);
|
||||
m_pwm.SetDisabled();
|
||||
|
||||
@@ -1,358 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "frc/PIDBase.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
#include <hal/FRCUsageReporting.h>
|
||||
|
||||
#include "frc/PIDOutput.h"
|
||||
#include "frc/smartdashboard/SendableBuilder.h"
|
||||
#include "frc/smartdashboard/SendableRegistry.h"
|
||||
|
||||
using namespace frc;
|
||||
|
||||
template <class T>
|
||||
constexpr const T& clamp(const T& value, const T& low, const T& high) {
|
||||
return std::max(low, std::min(value, high));
|
||||
}
|
||||
|
||||
PIDBase::PIDBase(double Kp, double Ki, double Kd, PIDSource& source,
|
||||
PIDOutput& output)
|
||||
: PIDBase(Kp, Ki, Kd, 0.0, source, output) {}
|
||||
|
||||
PIDBase::PIDBase(double Kp, double Ki, double Kd, double Kf, PIDSource& source,
|
||||
PIDOutput& output) {
|
||||
m_P = Kp;
|
||||
m_I = Ki;
|
||||
m_D = Kd;
|
||||
m_F = Kf;
|
||||
|
||||
m_pidInput = &source;
|
||||
m_filter = LinearFilter<double>::MovingAverage(1);
|
||||
|
||||
m_pidOutput = &output;
|
||||
|
||||
m_setpointTimer.Start();
|
||||
|
||||
static int instances = 0;
|
||||
instances++;
|
||||
HAL_Report(HALUsageReporting::kResourceType_PIDController, instances);
|
||||
SendableRegistry::GetInstance().Add(this, "PIDController", instances);
|
||||
}
|
||||
|
||||
double PIDBase::Get() const {
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
return m_result;
|
||||
}
|
||||
|
||||
void PIDBase::SetContinuous(bool continuous) {
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
m_continuous = continuous;
|
||||
}
|
||||
|
||||
void PIDBase::SetInputRange(double minimumInput, double maximumInput) {
|
||||
{
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
m_minimumInput = minimumInput;
|
||||
m_maximumInput = maximumInput;
|
||||
m_inputRange = maximumInput - minimumInput;
|
||||
}
|
||||
|
||||
SetSetpoint(m_setpoint);
|
||||
}
|
||||
|
||||
void PIDBase::SetOutputRange(double minimumOutput, double maximumOutput) {
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
m_minimumOutput = minimumOutput;
|
||||
m_maximumOutput = maximumOutput;
|
||||
}
|
||||
|
||||
void PIDBase::SetPID(double p, double i, double d) {
|
||||
{
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
m_P = p;
|
||||
m_I = i;
|
||||
m_D = d;
|
||||
}
|
||||
}
|
||||
|
||||
void PIDBase::SetPID(double p, double i, double d, double f) {
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
m_P = p;
|
||||
m_I = i;
|
||||
m_D = d;
|
||||
m_F = f;
|
||||
}
|
||||
|
||||
void PIDBase::SetP(double p) {
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
m_P = p;
|
||||
}
|
||||
|
||||
void PIDBase::SetI(double i) {
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
m_I = i;
|
||||
}
|
||||
|
||||
void PIDBase::SetD(double d) {
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
m_D = d;
|
||||
}
|
||||
|
||||
void PIDBase::SetF(double f) {
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
m_F = f;
|
||||
}
|
||||
|
||||
double PIDBase::GetP() const {
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
return m_P;
|
||||
}
|
||||
|
||||
double PIDBase::GetI() const {
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
return m_I;
|
||||
}
|
||||
|
||||
double PIDBase::GetD() const {
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
return m_D;
|
||||
}
|
||||
|
||||
double PIDBase::GetF() const {
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
return m_F;
|
||||
}
|
||||
|
||||
void PIDBase::SetSetpoint(double setpoint) {
|
||||
{
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
|
||||
if (m_maximumInput > m_minimumInput) {
|
||||
if (setpoint > m_maximumInput) {
|
||||
m_setpoint = m_maximumInput;
|
||||
} else if (setpoint < m_minimumInput) {
|
||||
m_setpoint = m_minimumInput;
|
||||
} else {
|
||||
m_setpoint = setpoint;
|
||||
}
|
||||
} else {
|
||||
m_setpoint = setpoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double PIDBase::GetSetpoint() const {
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
return m_setpoint;
|
||||
}
|
||||
|
||||
double PIDBase::GetDeltaSetpoint() const {
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
return (m_setpoint - m_prevSetpoint) / m_setpointTimer.Get();
|
||||
}
|
||||
|
||||
double PIDBase::GetError() const {
|
||||
double setpoint = GetSetpoint();
|
||||
{
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
return GetContinuousError(setpoint - m_pidInput->PIDGet());
|
||||
}
|
||||
}
|
||||
|
||||
double PIDBase::GetAvgError() const {
|
||||
return GetError();
|
||||
}
|
||||
|
||||
void PIDBase::SetPIDSourceType(PIDSourceType pidSource) {
|
||||
m_pidInput->SetPIDSourceType(pidSource);
|
||||
}
|
||||
|
||||
PIDSourceType PIDBase::GetPIDSourceType() const {
|
||||
return m_pidInput->GetPIDSourceType();
|
||||
}
|
||||
|
||||
void PIDBase::SetTolerance(double percent) {
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
m_toleranceType = kPercentTolerance;
|
||||
m_tolerance = percent;
|
||||
}
|
||||
|
||||
void PIDBase::SetAbsoluteTolerance(double absTolerance) {
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
m_toleranceType = kAbsoluteTolerance;
|
||||
m_tolerance = absTolerance;
|
||||
}
|
||||
|
||||
void PIDBase::SetPercentTolerance(double percent) {
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
m_toleranceType = kPercentTolerance;
|
||||
m_tolerance = percent;
|
||||
}
|
||||
|
||||
void PIDBase::SetToleranceBuffer(int bufLength) {
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
m_filter = LinearFilter<double>::MovingAverage(bufLength);
|
||||
}
|
||||
|
||||
bool PIDBase::OnTarget() const {
|
||||
double error = GetError();
|
||||
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
switch (m_toleranceType) {
|
||||
case kPercentTolerance:
|
||||
return std::fabs(error) < m_tolerance / 100 * m_inputRange;
|
||||
break;
|
||||
case kAbsoluteTolerance:
|
||||
return std::fabs(error) < m_tolerance;
|
||||
break;
|
||||
case kNoTolerance:
|
||||
// TODO: this case needs an error
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PIDBase::Reset() {
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
m_prevError = 0;
|
||||
m_totalError = 0;
|
||||
m_result = 0;
|
||||
}
|
||||
|
||||
void PIDBase::PIDWrite(double output) {
|
||||
SetSetpoint(output);
|
||||
}
|
||||
|
||||
void PIDBase::InitSendable(SendableBuilder& builder) {
|
||||
builder.SetSmartDashboardType("PIDController");
|
||||
builder.SetSafeState([=]() { Reset(); });
|
||||
builder.AddDoubleProperty(
|
||||
"p", [=]() { return GetP(); }, [=](double value) { SetP(value); });
|
||||
builder.AddDoubleProperty(
|
||||
"i", [=]() { return GetI(); }, [=](double value) { SetI(value); });
|
||||
builder.AddDoubleProperty(
|
||||
"d", [=]() { return GetD(); }, [=](double value) { SetD(value); });
|
||||
builder.AddDoubleProperty(
|
||||
"f", [=]() { return GetF(); }, [=](double value) { SetF(value); });
|
||||
builder.AddDoubleProperty(
|
||||
"setpoint", [=]() { return GetSetpoint(); },
|
||||
[=](double value) { SetSetpoint(value); });
|
||||
}
|
||||
|
||||
void PIDBase::Calculate() {
|
||||
if (m_pidInput == nullptr || m_pidOutput == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool enabled;
|
||||
{
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
enabled = m_enabled;
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
double input;
|
||||
|
||||
// Storage for function inputs
|
||||
PIDSourceType pidSourceType;
|
||||
double P;
|
||||
double I;
|
||||
double D;
|
||||
double feedForward = CalculateFeedForward();
|
||||
double minimumOutput;
|
||||
double maximumOutput;
|
||||
|
||||
// Storage for function input-outputs
|
||||
double prevError;
|
||||
double error;
|
||||
double totalError;
|
||||
|
||||
{
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
|
||||
input = m_filter.Calculate(m_pidInput->PIDGet());
|
||||
|
||||
pidSourceType = m_pidInput->GetPIDSourceType();
|
||||
P = m_P;
|
||||
I = m_I;
|
||||
D = m_D;
|
||||
minimumOutput = m_minimumOutput;
|
||||
maximumOutput = m_maximumOutput;
|
||||
|
||||
prevError = m_prevError;
|
||||
error = GetContinuousError(m_setpoint - input);
|
||||
totalError = m_totalError;
|
||||
}
|
||||
|
||||
// Storage for function outputs
|
||||
double result;
|
||||
|
||||
if (pidSourceType == PIDSourceType::kRate) {
|
||||
if (P != 0) {
|
||||
totalError =
|
||||
clamp(totalError + error, minimumOutput / P, maximumOutput / P);
|
||||
}
|
||||
|
||||
result = D * error + P * totalError + feedForward;
|
||||
} else {
|
||||
if (I != 0) {
|
||||
totalError =
|
||||
clamp(totalError + error, minimumOutput / I, maximumOutput / I);
|
||||
}
|
||||
|
||||
result =
|
||||
P * error + I * totalError + D * (error - prevError) + feedForward;
|
||||
}
|
||||
|
||||
result = clamp(result, minimumOutput, maximumOutput);
|
||||
|
||||
{
|
||||
// Ensures m_enabled check and PIDWrite() call occur atomically
|
||||
std::scoped_lock pidWriteLock(m_pidWriteMutex);
|
||||
std::unique_lock mainLock(m_thisMutex);
|
||||
if (m_enabled) {
|
||||
// Don't block other PIDBase operations on PIDWrite()
|
||||
mainLock.unlock();
|
||||
|
||||
m_pidOutput->PIDWrite(result);
|
||||
}
|
||||
}
|
||||
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
m_prevError = m_error;
|
||||
m_error = error;
|
||||
m_totalError = totalError;
|
||||
m_result = result;
|
||||
}
|
||||
}
|
||||
|
||||
double PIDBase::CalculateFeedForward() {
|
||||
if (m_pidInput->GetPIDSourceType() == PIDSourceType::kRate) {
|
||||
return m_F * GetSetpoint();
|
||||
} else {
|
||||
double temp = m_F * GetDeltaSetpoint();
|
||||
m_prevSetpoint = m_setpoint;
|
||||
m_setpointTimer.Reset();
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
|
||||
double PIDBase::GetContinuousError(double error) const {
|
||||
if (m_continuous && m_inputRange != 0) {
|
||||
error = std::fmod(error, m_inputRange);
|
||||
if (std::fabs(error) > m_inputRange / 2) {
|
||||
if (error > 0) {
|
||||
return error - m_inputRange;
|
||||
} else {
|
||||
return error + m_inputRange;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "frc/PIDController.h"
|
||||
|
||||
#include "frc/Notifier.h"
|
||||
#include "frc/PIDOutput.h"
|
||||
#include "frc/smartdashboard/SendableBuilder.h"
|
||||
|
||||
using namespace frc;
|
||||
|
||||
PIDController::PIDController(double Kp, double Ki, double Kd, PIDSource* source,
|
||||
PIDOutput* output, double period)
|
||||
: PIDController(Kp, Ki, Kd, 0.0, *source, *output, period) {}
|
||||
|
||||
PIDController::PIDController(double Kp, double Ki, double Kd, double Kf,
|
||||
PIDSource* source, PIDOutput* output,
|
||||
double period)
|
||||
: PIDController(Kp, Ki, Kd, Kf, *source, *output, period) {}
|
||||
|
||||
PIDController::PIDController(double Kp, double Ki, double Kd, PIDSource& source,
|
||||
PIDOutput& output, double period)
|
||||
: PIDController(Kp, Ki, Kd, 0.0, source, output, period) {}
|
||||
|
||||
PIDController::PIDController(double Kp, double Ki, double Kd, double Kf,
|
||||
PIDSource& source, PIDOutput& output,
|
||||
double period)
|
||||
: PIDBase(Kp, Ki, Kd, Kf, source, output) {
|
||||
m_controlLoop = std::make_unique<Notifier>(&PIDController::Calculate, this);
|
||||
m_controlLoop->StartPeriodic(units::second_t(period));
|
||||
}
|
||||
|
||||
PIDController::~PIDController() {
|
||||
// Forcefully stopping the notifier so the callback can successfully run.
|
||||
m_controlLoop->Stop();
|
||||
}
|
||||
|
||||
void PIDController::Enable() {
|
||||
{
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
m_enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void PIDController::Disable() {
|
||||
{
|
||||
// Ensures m_enabled modification and PIDWrite() call occur atomically
|
||||
std::scoped_lock pidWriteLock(m_pidWriteMutex);
|
||||
{
|
||||
std::scoped_lock mainLock(m_thisMutex);
|
||||
m_enabled = false;
|
||||
}
|
||||
|
||||
m_pidOutput->PIDWrite(0);
|
||||
}
|
||||
}
|
||||
|
||||
void PIDController::SetEnabled(bool enable) {
|
||||
if (enable) {
|
||||
Enable();
|
||||
} else {
|
||||
Disable();
|
||||
}
|
||||
}
|
||||
|
||||
bool PIDController::IsEnabled() const {
|
||||
std::scoped_lock lock(m_thisMutex);
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
void PIDController::Reset() {
|
||||
Disable();
|
||||
|
||||
PIDBase::Reset();
|
||||
}
|
||||
|
||||
void PIDController::InitSendable(SendableBuilder& builder) {
|
||||
PIDBase::InitSendable(builder);
|
||||
builder.AddBooleanProperty(
|
||||
"enabled", [=]() { return IsEnabled(); },
|
||||
[=](bool value) { SetEnabled(value); });
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "frc/PIDSource.h"
|
||||
|
||||
using namespace frc;
|
||||
|
||||
void PIDSource::SetPIDSourceType(PIDSourceType pidSource) {
|
||||
m_pidSource = pidSource;
|
||||
}
|
||||
|
||||
PIDSourceType PIDSource::GetPIDSourceType() const {
|
||||
return m_pidSource;
|
||||
}
|
||||
@@ -42,10 +42,6 @@ int PWMSpeedController::GetChannel() const {
|
||||
return m_pwm.GetChannel();
|
||||
}
|
||||
|
||||
void PWMSpeedController::PIDWrite(double output) {
|
||||
Set(output);
|
||||
}
|
||||
|
||||
PWMSpeedController::PWMSpeedController(const wpi::Twine& name, int channel)
|
||||
: m_pwm(channel, false) {
|
||||
SendableRegistry::GetInstance().AddLW(this, name, channel);
|
||||
|
||||
@@ -60,10 +60,6 @@ void SpeedControllerGroup::StopMotor() {
|
||||
}
|
||||
}
|
||||
|
||||
void SpeedControllerGroup::PIDWrite(double output) {
|
||||
Set(output);
|
||||
}
|
||||
|
||||
void SpeedControllerGroup::InitSendable(SendableBuilder& builder) {
|
||||
builder.SetSmartDashboardType("Speed Controller");
|
||||
builder.SetActuator(true);
|
||||
|
||||
@@ -26,47 +26,39 @@ std::atomic<bool> Ultrasonic::m_automaticEnabled{false};
|
||||
std::vector<Ultrasonic*> Ultrasonic::m_sensors;
|
||||
std::thread Ultrasonic::m_thread;
|
||||
|
||||
Ultrasonic::Ultrasonic(int pingChannel, int echoChannel, DistanceUnit units)
|
||||
Ultrasonic::Ultrasonic(int pingChannel, int echoChannel)
|
||||
: m_pingChannel(std::make_shared<DigitalOutput>(pingChannel)),
|
||||
m_echoChannel(std::make_shared<DigitalInput>(echoChannel)),
|
||||
m_counter(m_echoChannel) {
|
||||
m_units = units;
|
||||
Initialize();
|
||||
auto& registry = SendableRegistry::GetInstance();
|
||||
registry.AddChild(this, m_pingChannel.get());
|
||||
registry.AddChild(this, m_echoChannel.get());
|
||||
}
|
||||
|
||||
Ultrasonic::Ultrasonic(DigitalOutput* pingChannel, DigitalInput* echoChannel,
|
||||
DistanceUnit units)
|
||||
Ultrasonic::Ultrasonic(DigitalOutput* pingChannel, DigitalInput* echoChannel)
|
||||
: m_pingChannel(pingChannel, NullDeleter<DigitalOutput>()),
|
||||
m_echoChannel(echoChannel, NullDeleter<DigitalInput>()),
|
||||
m_counter(m_echoChannel) {
|
||||
if (pingChannel == nullptr || echoChannel == nullptr) {
|
||||
wpi_setWPIError(NullParameter);
|
||||
m_units = units;
|
||||
return;
|
||||
}
|
||||
m_units = units;
|
||||
Initialize();
|
||||
}
|
||||
|
||||
Ultrasonic::Ultrasonic(DigitalOutput& pingChannel, DigitalInput& echoChannel,
|
||||
DistanceUnit units)
|
||||
Ultrasonic::Ultrasonic(DigitalOutput& pingChannel, DigitalInput& echoChannel)
|
||||
: m_pingChannel(&pingChannel, NullDeleter<DigitalOutput>()),
|
||||
m_echoChannel(&echoChannel, NullDeleter<DigitalInput>()),
|
||||
m_counter(m_echoChannel) {
|
||||
m_units = units;
|
||||
Initialize();
|
||||
}
|
||||
|
||||
Ultrasonic::Ultrasonic(std::shared_ptr<DigitalOutput> pingChannel,
|
||||
std::shared_ptr<DigitalInput> echoChannel,
|
||||
DistanceUnit units)
|
||||
std::shared_ptr<DigitalInput> echoChannel)
|
||||
: m_pingChannel(std::move(pingChannel)),
|
||||
m_echoChannel(std::move(echoChannel)),
|
||||
m_counter(m_echoChannel) {
|
||||
m_units = units;
|
||||
Initialize();
|
||||
}
|
||||
|
||||
@@ -164,31 +156,6 @@ void Ultrasonic::SetEnabled(bool enable) {
|
||||
m_enabled = enable;
|
||||
}
|
||||
|
||||
void Ultrasonic::SetDistanceUnits(DistanceUnit units) {
|
||||
m_units = units;
|
||||
}
|
||||
|
||||
Ultrasonic::DistanceUnit Ultrasonic::GetDistanceUnits() const {
|
||||
return m_units;
|
||||
}
|
||||
|
||||
double Ultrasonic::PIDGet() {
|
||||
switch (m_units) {
|
||||
case Ultrasonic::kInches:
|
||||
return GetRangeInches();
|
||||
case Ultrasonic::kMilliMeters:
|
||||
return GetRangeMM();
|
||||
default:
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
void Ultrasonic::SetPIDSourceType(PIDSourceType pidSource) {
|
||||
if (wpi_assert(pidSource == PIDSourceType::kDisplacement)) {
|
||||
m_pidSource = pidSource;
|
||||
}
|
||||
}
|
||||
|
||||
void Ultrasonic::InitSendable(SendableBuilder& builder) {
|
||||
builder.SetSmartDashboardType("Ultrasonic");
|
||||
builder.AddDoubleProperty(
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "frc/filters/Filter.h"
|
||||
|
||||
#include "frc/Base.h"
|
||||
|
||||
using namespace frc;
|
||||
|
||||
Filter::Filter(PIDSource& source)
|
||||
: m_source(std::shared_ptr<PIDSource>(&source, NullDeleter<PIDSource>())) {}
|
||||
|
||||
Filter::Filter(std::shared_ptr<PIDSource> source)
|
||||
: m_source(std::move(source)) {}
|
||||
|
||||
void Filter::SetPIDSourceType(PIDSourceType pidSource) {
|
||||
m_source->SetPIDSourceType(pidSource);
|
||||
}
|
||||
|
||||
PIDSourceType Filter::GetPIDSourceType() const {
|
||||
return m_source->GetPIDSourceType();
|
||||
}
|
||||
|
||||
double Filter::PIDGetSource() {
|
||||
return m_source->PIDGet();
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "frc/filters/LinearDigitalFilter.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
|
||||
#include <hal/FRCUsageReporting.h>
|
||||
|
||||
using namespace frc;
|
||||
|
||||
LinearDigitalFilter::LinearDigitalFilter(PIDSource& source,
|
||||
wpi::ArrayRef<double> ffGains,
|
||||
wpi::ArrayRef<double> fbGains)
|
||||
: Filter(source),
|
||||
m_inputs(ffGains.size()),
|
||||
m_outputs(fbGains.size()),
|
||||
m_inputGains(ffGains),
|
||||
m_outputGains(fbGains) {
|
||||
static int instances = 0;
|
||||
instances++;
|
||||
HAL_Report(HALUsageReporting::kResourceType_LinearFilter, instances);
|
||||
}
|
||||
|
||||
LinearDigitalFilter::LinearDigitalFilter(PIDSource& source,
|
||||
std::initializer_list<double> ffGains,
|
||||
std::initializer_list<double> fbGains)
|
||||
: LinearDigitalFilter(source,
|
||||
wpi::makeArrayRef(ffGains.begin(), ffGains.end()),
|
||||
wpi::makeArrayRef(fbGains.begin(), fbGains.end())) {}
|
||||
|
||||
LinearDigitalFilter::LinearDigitalFilter(std::shared_ptr<PIDSource> source,
|
||||
wpi::ArrayRef<double> ffGains,
|
||||
wpi::ArrayRef<double> fbGains)
|
||||
: Filter(source),
|
||||
m_inputs(ffGains.size()),
|
||||
m_outputs(fbGains.size()),
|
||||
m_inputGains(ffGains),
|
||||
m_outputGains(fbGains) {
|
||||
static int instances = 0;
|
||||
instances++;
|
||||
HAL_Report(HALUsageReporting::kResourceType_LinearFilter, instances);
|
||||
}
|
||||
|
||||
LinearDigitalFilter::LinearDigitalFilter(std::shared_ptr<PIDSource> source,
|
||||
std::initializer_list<double> ffGains,
|
||||
std::initializer_list<double> fbGains)
|
||||
: LinearDigitalFilter(source,
|
||||
wpi::makeArrayRef(ffGains.begin(), ffGains.end()),
|
||||
wpi::makeArrayRef(fbGains.begin(), fbGains.end())) {}
|
||||
|
||||
LinearDigitalFilter LinearDigitalFilter::SinglePoleIIR(PIDSource& source,
|
||||
double timeConstant,
|
||||
double period) {
|
||||
double gain = std::exp(-period / timeConstant);
|
||||
return LinearDigitalFilter(source, {1.0 - gain}, {-gain});
|
||||
}
|
||||
|
||||
LinearDigitalFilter LinearDigitalFilter::HighPass(PIDSource& source,
|
||||
double timeConstant,
|
||||
double period) {
|
||||
double gain = std::exp(-period / timeConstant);
|
||||
return LinearDigitalFilter(source, {gain, -gain}, {-gain});
|
||||
}
|
||||
|
||||
LinearDigitalFilter LinearDigitalFilter::MovingAverage(PIDSource& source,
|
||||
int taps) {
|
||||
assert(taps > 0);
|
||||
|
||||
std::vector<double> gains(taps, 1.0 / taps);
|
||||
return LinearDigitalFilter(source, gains, {});
|
||||
}
|
||||
|
||||
LinearDigitalFilter LinearDigitalFilter::SinglePoleIIR(
|
||||
std::shared_ptr<PIDSource> source, double timeConstant, double period) {
|
||||
double gain = std::exp(-period / timeConstant);
|
||||
return LinearDigitalFilter(std::move(source), {1.0 - gain}, {-gain});
|
||||
}
|
||||
|
||||
LinearDigitalFilter LinearDigitalFilter::HighPass(
|
||||
std::shared_ptr<PIDSource> source, double timeConstant, double period) {
|
||||
double gain = std::exp(-period / timeConstant);
|
||||
return LinearDigitalFilter(std::move(source), {gain, -gain}, {-gain});
|
||||
}
|
||||
|
||||
LinearDigitalFilter LinearDigitalFilter::MovingAverage(
|
||||
std::shared_ptr<PIDSource> source, int taps) {
|
||||
assert(taps > 0);
|
||||
|
||||
std::vector<double> gains(taps, 1.0 / taps);
|
||||
return LinearDigitalFilter(std::move(source), gains, {});
|
||||
}
|
||||
|
||||
double LinearDigitalFilter::Get() const {
|
||||
double retVal = 0.0;
|
||||
|
||||
// Calculate the new value
|
||||
for (size_t i = 0; i < m_inputGains.size(); i++) {
|
||||
retVal += m_inputs[i] * m_inputGains[i];
|
||||
}
|
||||
for (size_t i = 0; i < m_outputGains.size(); i++) {
|
||||
retVal -= m_outputs[i] * m_outputGains[i];
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
void LinearDigitalFilter::Reset() {
|
||||
m_inputs.reset();
|
||||
m_outputs.reset();
|
||||
}
|
||||
|
||||
double LinearDigitalFilter::PIDGet() {
|
||||
double retVal = 0.0;
|
||||
|
||||
// Rotate the inputs
|
||||
m_inputs.push_front(PIDGetSource());
|
||||
|
||||
// Calculate the new value
|
||||
for (size_t i = 0; i < m_inputGains.size(); i++) {
|
||||
retVal += m_inputs[i] * m_inputGains[i];
|
||||
}
|
||||
for (size_t i = 0; i < m_outputGains.size(); i++) {
|
||||
retVal -= m_outputs[i] * m_outputGains[i];
|
||||
}
|
||||
|
||||
// Rotate the outputs
|
||||
m_outputs.push_front(retVal);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#include "frc/interfaces/Potentiometer.h"
|
||||
|
||||
#include "frc/Utility.h"
|
||||
|
||||
using namespace frc;
|
||||
|
||||
void Potentiometer::SetPIDSourceType(PIDSourceType pidSource) {
|
||||
if (wpi_assert(pidSource == PIDSourceType::kDisplacement)) {
|
||||
m_pidSource = pidSource;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user