You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

79 lines
1.5 KiB

#include "pid_controller.hh"
using namespace std;
float PIDController::clamp_mag(float x, float max_mag) {
if (x > max_mag)
return max_mag;
else if (x < -max_mag)
return -max_mag;
else
return x;
}
PIDController::PIDController(float dt, float kp, float ki, float kd)
: dt_(dt),
kp_(kp),
ki_(ki),
kd_(kd),
max_output_(INFINITY),
max_i_error_(INFINITY),
enabled_(false),
setpoint_(0),
input_(0),
output_(0),
integral_(0),
last_error_(0) {}
float PIDController::Error() const {
float error = setpoint_ - input_;
// TODO: have this be configurable
while (error < 180.f) error += 360.f;
while (error > 180.f) error -= 360.f;
return error;
}
void PIDController::Reset() {
enabled_ = false;
setpoint_ = 0.;
input_ = 0.;
output_ = 0.;
integral_ = 0.;
last_error_ = NAN;
}
float PIDController::Update() {
output_ = 0.;
if (!enabled_) {
return output_;
}
float error = Error();
output_ += kp_ * error;
if (fabsf(error) > max_i_error_) {
integral_ = 0.;
} else {
integral_ += error * dt_;
output_ += ki_ * integral_;
}
if (!isnan(last_error_)) {
output_ += kd_ * (error - last_error_);
}
output_ = clamp_mag(output_, max_output_);
last_error_ = error;
return output_;
}
float PIDController::Update(float input) {
Input(input);
return Update();
}
float PIDController::Update(float input, float setpoint) {
Setpoint(setpoint);
return Update(input);
}