First files added
This commit is contained in:
83
firmware/Core/Src/pid.c
Normal file
83
firmware/Core/Src/pid.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* pid.c
|
||||
*
|
||||
* Created on: Jan 18, 2022
|
||||
* Author: mcfly
|
||||
*/
|
||||
|
||||
#include "pid.h"
|
||||
|
||||
void PID_Init(PIDController *pid) {
|
||||
//Clear controller values
|
||||
pid->integrator = 0.0f;
|
||||
pid->prevError = 0.0f;
|
||||
|
||||
pid->differentiator = 0.0f;
|
||||
pid->prevMeasurement = 0.0f;
|
||||
|
||||
pid->out = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
float PID_Update(PIDController *pid, float setpoint, float measurement) {
|
||||
// PID = Kp + Ki * 1/s + Kd * s/(s*tau+1)
|
||||
|
||||
// e = error tothe setpoint
|
||||
// p[n] = Kp * e[n]
|
||||
// i[n] = Ki*T/2 * (e[n]+e[n-1]) + i[n-1]
|
||||
// d[n] = 2*Kd/(2*tau+T) * (e[n]-e[n-1]) + (2*tau-T)/(2*tau+T) * d[n-1]
|
||||
// PID = p[n]+i[n]+d[n]
|
||||
|
||||
|
||||
//Error signal
|
||||
float error = setpoint - measurement;
|
||||
|
||||
//Proportional
|
||||
float proportional = pid->Kp * error;
|
||||
|
||||
//Integral
|
||||
pid->integrator += 0.5f * pid->Ki * pid->T * (error + pid->prevError);
|
||||
|
||||
//Anti-wind-up via dynamic integrator clamping
|
||||
float limMinInt, limMaxInt;
|
||||
|
||||
//Compute integrator limits
|
||||
if (pid->limMax > proportional) {
|
||||
limMaxInt = pid->limMax - proportional;
|
||||
} else {
|
||||
limMaxInt = 0.0f;
|
||||
}
|
||||
if (pid->limMin < proportional) {
|
||||
limMinInt = pid->limMin - proportional;
|
||||
} else {
|
||||
limMinInt = 0.0f;
|
||||
}
|
||||
|
||||
//Clamp integrator
|
||||
if (pid->integrator > limMaxInt) {
|
||||
pid->integrator = limMaxInt;
|
||||
} else if (pid->integrator < limMinInt) {
|
||||
pid->integrator = limMinInt;
|
||||
}
|
||||
|
||||
//Derivative (band-limited differentiator)
|
||||
pid->differentiator = (2.0f * pid->Kd * (measurement - pid->prevMeasurement) //Note: derivative on measurement
|
||||
+ (2.0f * pid->tau - pid->T) * pid->differentiator)
|
||||
/ (2.0f * pid->tau + pid->T);
|
||||
|
||||
//Compute output and apply limits
|
||||
pid->out = proportional + pid->integrator + pid->differentiator;
|
||||
if (pid->out > pid->limMax) {
|
||||
pid->out = pid->limMax;
|
||||
} else if (pid->out < pid->limMin) {
|
||||
pid->out = pid->limMin;
|
||||
}
|
||||
|
||||
//Store error and measurement for later use
|
||||
pid->prevError = error;
|
||||
pid->prevMeasurement = measurement;
|
||||
|
||||
//Return controller output
|
||||
return pid->out;
|
||||
|
||||
}
|
Reference in New Issue
Block a user