Skip to content

Commit a50bd47

Browse files
committed
upd
1 parent d1e5a66 commit a50bd47

File tree

4 files changed

+34
-24
lines changed

4 files changed

+34
-24
lines changed

README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,20 +99,26 @@ float_t compute(float_t input);
9999
Режим работы регулятора строится из констант, разделённых `|`, например:
100100

101101
```cpp
102-
uPID pid(D_INPUT | P_MEASURE | PID_REVERSE);
103-
pid.setConfig(D_INPUT | P_MEASURE);
104-
pid.clearMode(P_MEASURE);
102+
uPID pid(D_INPUT | P_INPUT | PID_REVERSE);
103+
pid.setConfig(D_INPUT | P_INPUT);
104+
pid.clearMode(P_INPUT);
105105

106-
uPIDfast<D_INPUT | P_MEASURE | PID_REVERSE> pidfast;
106+
uPIDfast<D_INPUT | P_INPUT | PID_REVERSE> pidfast;
107107
```
108108
109109
### Пропорциональная
110110
Один вариант из двух:
111111
112112
- `P_ERROR` (по умолчанию) - пропорционально ошибке. Классический вариант П-составляющей
113-
- `P_MEASURE` - пропорционально входу (зависит от `D_INPUT`) или ошибке (зависит от `D_ERROR`). Меняет логику работы регулятора, хорошо подходит для интегрирующих процессов - например регулятор управляет скоростью (сигналом на мотор), а на вход подаётся позиция (энкодер на этом моторе)
113+
- `P_INPUT` - пропорционально входу. Меняет логику работы регулятора, хорошо подходит для интегрирующих или медленных процессов - например регулятор управляет скоростью (сигналом на мотор), а на вход подаётся позиция (энкодер на этом моторе). В этом случае регулятор должен работать в паре с I составляющей, т.е. быть как минимум PI - интегральная будет задавать основной выход, а пропорциональная - сглаживать его
114114
115115
### Интегральная
116+
Один вариант из двух:
117+
118+
- `I_KI_OUTSIDE` (по умолчанию) - коэффициент за интегралом, классическое уравнение ПИД
119+
- `I_KI_INSIDE` - коэффициент входит в интеграл
120+
121+
### Ограничение интеграла
116122
Можно выбирать в любом сочетании, но `I_BACK_CALC` является аналогом `I_SATURATE` и включать их вместе не имеет смысла:
117123
118124
- `I_SATURATE` - *Conditional Integration*, отключение интегрирования при насыщении выхода (`outMax` и `outMin` должны быть настроены)

keywords.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ compute KEYWORD2
2121
#######################################
2222

2323
P_ERROR LITERAL1
24-
P_MEASURE LITERAL1
24+
P_INPUT LITERAL1
25+
I_KI_OUTSIDE LITERAL1
26+
I_KI_INSIDE LITERAL1
2527
I_BACK_CALC LITERAL1
2628
I_SATURATE LITERAL1
2729
I_RESET LITERAL1

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=uPID
2-
version=1.0.0
2+
version=1.0.1
33
author=AlexGyver <alex@alexgyver.ru>
44
maintainer=AlexGyver <alex@alexgyver.ru>
55
sentence=Light and universal PID implementation

uPID.h

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@
33

44
// uPID_cfg
55
enum uPID_cfg : uint8_t {
6-
P_ERROR = 0, // пропорционально ошибке
7-
P_MEASURE = (1 << 0), // пропорционально вводу D_INPUT или ошибке D_ERROR. Для интегрирующих процессов
8-
I_BACK_CALC = (1 << 1), // Back Calculation, ограничение интегрирования регулируется коэф-м Kbc (по умолч. выбирать равным Ki)
9-
I_SATURATE = (1 << 2), // Conditional Integration, отключение интегрирования при насыщении выхода
10-
I_RESET = (1 << 3), // сброс интеграла при достижении уставки
11-
D_INPUT = (1 << 4), // дифференциально входу
12-
D_ERROR = 0, // дифференциально ошибке
13-
PID_FORWARD = 0, // прямое направление
14-
PID_REVERSE = (1 << 5), // обратное направление
6+
P_ERROR = 0, // пропорционально ошибке (по умолч.)
7+
P_INPUT = (1 << 0), // пропорционально вводу D_INPUT или ошибке D_ERROR. Для интегрирующих процессов
8+
I_KI_OUTSIDE = 0, // Ki снаружи интеграла (по умолч.)
9+
I_KI_INSIDE = (1 << 1), // Ki внутри интеграла
10+
I_BACK_CALC = (1 << 2), // Back Calculation, ограничение интегрирования регулируется коэф-м Kbc (по умолч. выбирать равным Ki)
11+
I_SATURATE = (1 << 3), // Conditional Integration, отключение интегрирования при насыщении выхода
12+
I_RESET = (1 << 4), // сброс интеграла при достижении уставки
13+
D_INPUT = (1 << 5), // дифференциально входу
14+
D_ERROR = 0, // дифференциально ошибке (по умолч.)
15+
PID_FORWARD = 0, // прямое направление (по умолч.)
16+
PID_REVERSE = (1 << 6), // обратное направление
1517
};
1618

1719
// uPID
@@ -65,9 +67,8 @@ class uPID {
6567
}
6668

6769
if ((cfg & I_RESET) && ((!(cfg & PID_REVERSE) && input >= setpoint) || ((cfg & PID_REVERSE) && input <= setpoint))) integral = 0;
68-
if (cfg & P_MEASURE) integral += Kp * deriv;
6970

70-
float output = ((cfg & P_MEASURE) ? 0 : Kp * error) + integral + Kd * deriv * _dt_i;
71+
float output = ((cfg & P_INPUT) ? -Kp * input : Kp * error) + ((cfg & I_KI_INSIDE) ? integral : Ki * integral) + Kd * deriv * _dt_i;
7172

7273
if (output >= outMax) {
7374
if ((cfg & I_BACK_CALC) && Kbc) error += (outMax - output) * Kbc;
@@ -79,27 +80,29 @@ class uPID {
7980
if ((cfg & I_SATURATE) && error < 0) return output;
8081
}
8182

82-
integral += Ki * error * _dt;
83+
integral += (cfg & I_KI_INSIDE) ? (Ki * error * _dt) : (error * _dt);
8384

8485
return output;
8586
}
8687

88+
uint8_t cfg = 0;
89+
8790
private:
8891
float _prev = 0;
8992
float _dt, _dt_i;
9093
bool _first = true;
91-
uint8_t cfg = 0;
9294
};
9395

9496
// uPIDfast
9597
template <uint8_t cfg = 0, typename float_t = float>
9698
class uPIDfast {
9799
static constexpr bool _backCalc = cfg & I_BACK_CALC;
98100
static constexpr bool _satur = cfg & I_SATURATE;
99-
static constexpr bool _pMeas = cfg & P_MEASURE;
101+
static constexpr bool _pInput = cfg & P_INPUT;
100102
static constexpr bool _rev = cfg & PID_REVERSE;
101103
static constexpr bool _dInput = cfg & D_INPUT;
102104
static constexpr bool _rst = cfg & I_RESET;
105+
static constexpr bool _inside = cfg & I_KI_INSIDE;
103106

104107
public:
105108
uPIDfast(uint16_t dt = 30) {
@@ -143,9 +146,8 @@ class uPIDfast {
143146
}
144147

145148
if (_rst && ((!_rev && input >= setpoint) || (_rev && input <= setpoint))) integral = 0;
146-
if (_pMeas) integral += Kp * deriv;
147149

148-
float_t output = (_pMeas ? float_t(0) : Kp * error) + integral + Kd * deriv;
150+
float_t output = (_pInput ? -Kp * input : Kp * error) + (_inside ? integral : Ki * integral) + Kd * deriv;
149151

150152
if (output >= outMax) {
151153
if (_backCalc && Kbc) error += (outMax - output) * Kbc;
@@ -157,7 +159,7 @@ class uPIDfast {
157159
if (_satur && error < 0) return output;
158160
}
159161

160-
integral += Ki * error;
162+
integral += _inside ? (Ki * error) : (error);
161163

162164
return output;
163165
}

0 commit comments

Comments
 (0)