Brick
Loading...
Searching...
No Matches
pid.h
Go to the documentation of this file.
1/**
2 * @file pid.h
3 * @brief A control loop that utilizes the proportional, integral, and derivative values of error to
4 * get an output value
5 *
6 * This is a conventional PID controller using the Feedback class as an interface.
7 * It calculates an output using the proportional, integral, and derivative values of the error.
8 * It can decide whether or not it has reached it's target state based on how long the error has
9 * remained inside the deadband
10 */
11
12#pragma once
13
15#include "core/math/units.h"
16
17using namespace units::literals;
18
19/*
20 * @param T the data type for states
21 * @param U the data type for output
22 *
23 * Feedback child class to create PID control loops
24 */
25template <typename T, typename U>
26class PID : public Feedback<T, U> {
27 public:
28 using kPType = units::Divided<U, T>;
31
32 /**
33 * @brief PID controller object constructor
34 *
35 * @param kP the proportional constant for the controller
36 * @param kI the integral constant for the controller
37 * @param kD the derivative constant for the controller
38 * @param deadband the deadband where the loop decides it
39 * is on target
40 * @param on_target_time the time where the loops decides
41 * it is on target
42 */
43 PID(kPType kP, kIType kI, kDType kD, T deadband, units::Time on_target_time)
44 : kP_(kP), kI_(kI), kD_(kD), deadband_(deadband), on_target_time_(on_target_time) {
45 reset();
46 }
47
48 /// Resets the internal state of the PID controller
49 void reset() override {
50 this->accum_error_ = T();
51 this->last_error_ = T();
52 this->output_ = U();
53 }
54
55 /**
56 * @brief Updates the control loop output
57 *
58 * @param state the current state the PID controller is at
59 * @param reference the target state for the PID controller
60 * @param dt the timestep since the last time this method was called
61 * @return the controller output
62 */
63 U update(const double& state, const double& reference, const units::Time& dt = 10_ms) override {
64 this->state_ = state;
65 this->reference_ = reference;
66
67 const T current_error = this->reference_ - this->state_;
68 const T delta_error = current_error - this->last_error_;
69
70 accum_error_ += current_error;
71
72 const U p_out = kP_ * current_error;
73
74 const U i_out = kI_ * accum_error_;
75
76 const U d_out = kP_ * delta_error;
77
78 this->last_error_ = current_error;
79
80 if (std::abs(current_error) < deadband_) {
81 last_target_time_ += dt;
82 } else {
83 last_target_time_ = 0_ms;
84 }
85
86 if (last_target_time_ > on_target_time_) {
87 on_target_ = true;
88 } else {
89 on_target_ = false;
90 }
91
92 this->output_ = p_out + i_out + d_out;
93
94 this->output_ = clamp(this->output_, this->output_min_, this->output_max_);
95
96 return this->output_;
97 }
98
99 /// Gets the on target state of the PID controller
100 bool get_on_target() { return on_target_; }
101
102 kPType kP_;
103 kIType kI_;
104 kDType kD_;
105 T deadband_;
106 units::Time on_target_time_;
107
108 private:
109 bool on_target_;
110 units::Time last_target_time_;
111 T accum_error_;
112};
113
114using AngularPositionPID = PID<units::Angle, units::Voltage>;
115using AngularVelocityPID = PID<units::AngularVelocity, units::Voltage>;
116using LinearPositionPID = PID<units::Length, units::Voltage>;
117using LinearVelocityPID = PID<units::Velocity, units::Voltage>;
pure virtual class for generic feedback control loops.
Definition feedback.h:21
Definition pid.h:26
bool get_on_target()
Gets the on target state of the PID controller.
Definition pid.h:100
U update(const double &state, const double &reference, const units::Time &dt=10_ms) override
Updates the control loop output.
Definition pid.h:63
PID(kPType kP, kIType kI, kDType kD, T deadband, units::Time on_target_time)
PID controller object constructor.
Definition pid.h:43
void reset() override
Definition pid.h:49
A pure virual class to function as an interface for all feedback control loops.
Definition units.h:691
Quantity< std::ratio_subtract< typename Q1::mass, typename Q2::mass >, std::ratio_subtract< typename Q1::length, typename Q2::length >, std::ratio_subtract< typename Q1::time, typename Q2::time >, std::ratio_subtract< typename Q1::current, typename Q2::current >, std::ratio_subtract< typename Q1::angle, typename Q2::angle >, std::ratio_subtract< typename Q1::temperature, typename Q2::temperature >, std::ratio_subtract< typename Q1::luminosity, typename Q2::luminosity >, std::ratio_subtract< typename Q1::moles, typename Q2::moles > > Divided
Dividing quantities subtracts their dimensions.
Definition units.h:206
Quantity< std::ratio_add< typename Q1::mass, typename Q2::mass >, std::ratio_add< typename Q1::length, typename Q2::length >, std::ratio_add< typename Q1::time, typename Q2::time >, std::ratio_add< typename Q1::current, typename Q2::current >, std::ratio_add< typename Q1::angle, typename Q2::angle >, std::ratio_add< typename Q1::temperature, typename Q2::temperature >, std::ratio_add< typename Q1::luminosity, typename Q2::luminosity >, std::ratio_add< typename Q1::moles, typename Q2::moles > > Multiplied
Multiplying quantities adds their dimensions.
Definition units.h:194