forked from pms67/PID
-
Notifications
You must be signed in to change notification settings - Fork 0
/
PID.c
78 lines (49 loc) · 1.56 KB
/
PID.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include "PID.h"
void PIDController_Init(PIDController *pid) {
/* Clear controller variables */
pid->integrator = 0.0f;
pid->prevError = 0.0f;
pid->differentiator = 0.0f;
pid->prevMeasurement = 0.0f;
pid->out = 0.0f;
}
float PIDController_Update(PIDController *pid, float setpoint, float measurement) {
/*
* Error signal
*/
float error = setpoint - measurement;
/*
* Proportional
*/
float proportional = pid->Kp * error;
/*
* Integral
*/
pid->integrator = pid->integrator + 0.5f * pid->Ki * pid->T * (error + pid->prevError);
/* Anti-wind-up via integrator clamping */
if (pid->integrator > pid->limMaxInt) {
pid->integrator = pid->limMaxInt;
} else if (pid->integrator < pid->limMinInt) {
pid->integrator = pid->limMinInt;
}
/*
* Derivative (band-limited differentiator)
*/
pid->differentiator = -(2.0f * pid->Kd * (measurement - pid->prevMeasurement) /* Note: derivative on measurement, therefore minus sign in front of equation! */
+ (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;
}