-
Notifications
You must be signed in to change notification settings - Fork 10
/
pid.cpp
79 lines (61 loc) · 1.64 KB
/
pid.cpp
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
#include "pid.h"
PID::PID(int p, int i, int d)
{
kP = p;
kI = i;
kD = d;
refVal = 0;
inputValue = 0;
iTerm = 0;
lastValue = 0;
}
PID::PID(float p, float i, float d)
{
kP = (int32_t)(p * FLOAT_TO_INT_SCALE);
kI = (int32_t)(i * FLOAT_TO_INT_SCALE);
kD = (int32_t)(d * FLOAT_TO_INT_SCALE);
}
void PID::setCoeffs(int32_t p, int32_t i, int32_t d)
{
kP = p;
kI = i;
kD = d;
}
void PID::setCoeffs(float p, float i, float d)
{
kP = (int32_t)(p * FLOAT_TO_INT_SCALE);
kI = (int32_t)(i * FLOAT_TO_INT_SCALE);
kD = (int32_t)(d * FLOAT_TO_INT_SCALE);
}
void PID::setRef(int32_t pnt)
{
refVal = pnt;
}
void PID::setMinValue(int32_t mn)
{
minValue = mn;
scaledMin = mn * FLOAT_TO_INT_SCALE;
}
void PID::setMaxValue(int32_t mx)
{
maxValue = mx;
scaledMax = mx * FLOAT_TO_INT_SCALE;
}
int32_t PID::calculatePID(int32_t input)
{
int32_t output, error, diffInput;
inputValue = input;
error = refVal - inputValue;
iTerm += (kI * error); //remember, all k* variables are scaled up
if (iTerm > scaledMax) iTerm = scaledMax;
if (iTerm < scaledMin) iTerm = scaledMin;
diffInput = (inputValue - lastValue);
//it's traditional to try to avoid using division in microcontrollers but the
//SAM3X has a very fast hardware divider anyway. Besides, FLOAT_TO_INT_SCALE is
//an even power of 2 so it can be done via a shift which is even faster.
output = ((kP * error) + (iTerm) - (kD * diffInput)) / FLOAT_TO_INT_SCALE;
if (output > maxValue) output = maxValue;
if (output < minValue) output = minValue;
lastValue = inputValue;
return output;
}