blob: 0c86f55c483e3bebca4f462b69c39d8a213c9097 [file] [log] [blame]
Brian Silverman41cdd3e2019-01-19 19:48:58 -08001/*----------------------------------------------------------------------------*/
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -08002/* Copyright (c) 2008-2019 FIRST. All Rights Reserved. */
Brian Silverman41cdd3e2019-01-19 19:48:58 -08003/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7
8#include "frc/PIDController.h"
9
10#include "frc/Notifier.h"
11#include "frc/PIDOutput.h"
12#include "frc/smartdashboard/SendableBuilder.h"
13
14using namespace frc;
15
16PIDController::PIDController(double Kp, double Ki, double Kd, PIDSource* source,
17 PIDOutput* output, double period)
18 : PIDController(Kp, Ki, Kd, 0.0, *source, *output, period) {}
19
20PIDController::PIDController(double Kp, double Ki, double Kd, double Kf,
21 PIDSource* source, PIDOutput* output,
22 double period)
23 : PIDController(Kp, Ki, Kd, Kf, *source, *output, period) {}
24
25PIDController::PIDController(double Kp, double Ki, double Kd, PIDSource& source,
26 PIDOutput& output, double period)
27 : PIDController(Kp, Ki, Kd, 0.0, source, output, period) {}
28
29PIDController::PIDController(double Kp, double Ki, double Kd, double Kf,
30 PIDSource& source, PIDOutput& output,
31 double period)
32 : PIDBase(Kp, Ki, Kd, Kf, source, output) {
33 m_controlLoop = std::make_unique<Notifier>(&PIDController::Calculate, this);
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080034 m_controlLoop->StartPeriodic(units::second_t(period));
Brian Silverman41cdd3e2019-01-19 19:48:58 -080035}
36
37PIDController::~PIDController() {
38 // Forcefully stopping the notifier so the callback can successfully run.
39 m_controlLoop->Stop();
40}
41
42void PIDController::Enable() {
43 {
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080044 std::scoped_lock lock(m_thisMutex);
Brian Silverman41cdd3e2019-01-19 19:48:58 -080045 m_enabled = true;
46 }
47}
48
49void PIDController::Disable() {
50 {
51 // Ensures m_enabled modification and PIDWrite() call occur atomically
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080052 std::scoped_lock pidWriteLock(m_pidWriteMutex);
Brian Silverman41cdd3e2019-01-19 19:48:58 -080053 {
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080054 std::scoped_lock mainLock(m_thisMutex);
Brian Silverman41cdd3e2019-01-19 19:48:58 -080055 m_enabled = false;
56 }
57
58 m_pidOutput->PIDWrite(0);
59 }
60}
61
62void PIDController::SetEnabled(bool enable) {
63 if (enable) {
64 Enable();
65 } else {
66 Disable();
67 }
68}
69
70bool PIDController::IsEnabled() const {
James Kuszmaul4f3ad3c2019-12-01 16:35:21 -080071 std::scoped_lock lock(m_thisMutex);
Brian Silverman41cdd3e2019-01-19 19:48:58 -080072 return m_enabled;
73}
74
75void PIDController::Reset() {
76 Disable();
77
78 PIDBase::Reset();
79}
80
81void PIDController::InitSendable(SendableBuilder& builder) {
82 PIDBase::InitSendable(builder);
83 builder.AddBooleanProperty("enabled", [=]() { return IsEnabled(); },
84 [=](bool value) { SetEnabled(value); });
85}