|
| 1 | +[](https://github.com/GyverLibs/uPID/releases/latest/download/uPID.zip) |
| 2 | +[](https://registry.platformio.org/libraries/gyverlibs/uPID) |
| 3 | +[](https://alexgyver.ru/) |
| 4 | +[](https://alexgyver.ru/support_alex/) |
| 5 | +[](https://github-com.translate.goog/GyverLibs/uPID?_x_tr_sl=ru&_x_tr_tl=en) |
| 6 | + |
| 7 | +[](https://t.me/GyverLibs) |
| 8 | + |
1 | 9 | # uPID
|
2 | 10 | Лёгкая универсальная библиотека ПИД-регулятора с опциональными надстройками над алгоритмом
|
| 11 | +- Ограничение выхода |
| 12 | +- Выбор направления регулирования |
| 13 | +- Пропорционально ошибке или изменению входа |
| 14 | +- Дифференциально ошибке или входу |
| 15 | +- Интегральная составляющая: |
| 16 | + - Ограничение интеграла Back Calculation |
| 17 | + - Ограничение интегрирования по насыщению выхода |
| 18 | + - Сброс интеграла при достижении уставки |
| 19 | + |
| 20 | +### Совместимость |
| 21 | +Совместима со всеми платформами |
| 22 | + |
| 23 | +## Содержание |
| 24 | +- [Использование](#usage) |
| 25 | +- [Версии](#versions) |
| 26 | +- [Установка](#install) |
| 27 | +- [Баги и обратная связь](#feedback) |
| 28 | + |
| 29 | +<a id="usage"></a> |
| 30 | + |
| 31 | +## Использование |
| 32 | +### uPID |
| 33 | +Стандартный класс. Режимы можно менять во время работы программы, коэффициенты можно писать и читать напрямую в переменные `Kp`, `Ki`, `Kd`. |
| 34 | + |
| 35 | +```cpp |
| 36 | +uPID(uint8_t cfg = 0, uint16_t dt = 30); |
| 37 | + |
| 38 | +float Kp = 0, Ki = 0, Kd = 0; |
| 39 | +float Kbc = 0; |
| 40 | +float setpoint = 0; |
| 41 | +float integral = 0; |
| 42 | +float outMax = 255; |
| 43 | +float outMin = 0; |
| 44 | + |
| 45 | +float getKp(); |
| 46 | +float getKi(); |
| 47 | +float getKd(); |
| 48 | + |
| 49 | +void setKp(float p); |
| 50 | +void setKi(float i); |
| 51 | +void setKd(float d); |
| 52 | + |
| 53 | +// установить конфиг |
| 54 | +void setConfig(uint8_t ncfg); |
| 55 | + |
| 56 | +// включить флаг |
| 57 | +void setMode(uPID_cfg mode); |
| 58 | + |
| 59 | +// выключить флаг |
| 60 | +void clearMode(uPID_cfg mode); |
| 61 | + |
| 62 | +// установить период работы в мс |
| 63 | +void setDt(uint16_t ms); |
| 64 | + |
| 65 | +// вычислить (вызывать с заданным периодом). Вернёт выход |
| 66 | +float compute(float input); |
| 67 | +``` |
| 68 | +
|
| 69 | +### uPIDfast |
| 70 | +Быстрая и лёгкая версия: режим задаётся в шаблоне на этапе компиляции, а коэффициенты можно менять только через set-get. Эта версия на 20 мкс быстрее считается - 67 против 87 мкс (AVR 16 MHz, стандартные настройки). |
| 71 | +
|
| 72 | +```cpp |
| 73 | +uPIDfast<uint8_t cfg = 0>(uint16_t dt = 30); |
| 74 | +
|
| 75 | +float Kbc = 0; |
| 76 | +float setpoint = 0; |
| 77 | +float integral = 0; |
| 78 | +float outMax = 255; |
| 79 | +float outMin = 0; |
| 80 | +
|
| 81 | +float getKp(); |
| 82 | +float getKi(); |
| 83 | +float getKd(); |
| 84 | +
|
| 85 | +void setKp(float p); |
| 86 | +void setKi(float i); |
| 87 | +void setKd(float d); |
| 88 | +
|
| 89 | +// установить период работы в мс |
| 90 | +void setDt(uint16_t ms); |
| 91 | +
|
| 92 | +// вычислить (вызывать с заданным периодом). Вернёт выход |
| 93 | +float compute(float input); |
| 94 | +``` |
| 95 | + |
| 96 | +### Настройка |
| 97 | +Режим работы регулятора строится из констант, разделённых `|`, например: |
| 98 | + |
| 99 | +```cpp |
| 100 | +uPID pid(D_INPUT | P_MEASURE | PID_REVERSE); |
| 101 | +pid.setConfig(D_INPUT | P_MEASURE); |
| 102 | +pid.clearMode(P_MEASURE); |
| 103 | + |
| 104 | +uPIDfast<D_INPUT | P_MEASURE | PID_REVERSE> pidfast; |
| 105 | +``` |
| 106 | +
|
| 107 | +### Пропорциональная |
| 108 | +Один вариант из двух: |
| 109 | +
|
| 110 | +- `P_ERROR` (по умолчанию) - пропорционально ошибке. Классический вариант П-составляющей |
| 111 | +- `P_MEASURE` - пропорционально входу (зависит от `D_INPUT`) или ошибке (зависит от `D_ERROR`). Меняет логику работы регулятора, хорошо подходит для интегрирующих процессов - например регулятор управляет скоростью (сигналом на мотор), а на вход подаётся позиция (энкодер на этом моторе) |
| 112 | +
|
| 113 | +### Интегральная |
| 114 | +Можно выбирать в любом сочетании, но `I_BACK_CALC` является аналогом `I_SATURATE` и включать их вместе не имеет смысла: |
| 115 | +
|
| 116 | +- `I_SATURATE` - *Conditional Integration*, отключение интегрирования при насыщении выхода |
| 117 | +- `I_BACK_CALC` - *Back Calculation*, умное ограничение интегрирования при насыщении выхода. Работает медленнее, чем `I_SATURATE`. Интенсивность регулируется коэф-м `Kbc` - для начала нужно выбрать его равным `Ki`, далее менять и смотреть за реакцией системы |
| 118 | +- `I_RESET` - автоматический сброс интеграла при достижении уставки |
| 119 | +
|
| 120 | +> Под "насыщением выхода" имеется в виду его уход из диапазона `(outMin.. outMax)`, в этом случае в обычном ПИДе интегральная сумма начинает бесконтрольно расти в одну сторону и потом долго возвращается обратно - т.н. *windup*. Библиотека предлагает несколько вариантов решения этой проблемы |
| 121 | +
|
| 122 | +### Дифференциальная |
| 123 | +Один вариант из двух: |
| 124 | +
|
| 125 | +- `D_ERROR` (по умолчанию) - дифференцирование ошибки. Классический вариант Д-составляющей |
| 126 | +- `D_INPUT` - дифференцирование входа. Меньшее влияние шума, полное отсутствие заброса по Д при изменении уставки. Если уставка часто меняется и нужно более динамичное поведение системы в ответ на это - лучше использовать `D_ERROR` |
| 127 | +
|
| 128 | +### Направление |
| 129 | +Один вариант из двух: |
| 130 | +
|
| 131 | +- `PID_FORWARD` (по умолчанию) - прямой регулятор, выход регулятора должен увеличивать вход (например управление мощностью нагрева, температура на вход регулятора) |
| 132 | +- `PID_REVERSE` - обратный регулятор, выход регулятора должен уменьшать вход (например управление мощностью охлаждения, температура на вход регулятора) |
| 133 | +
|
| 134 | +### Примеры |
| 135 | +```cpp |
| 136 | +#include <uPID.h> |
| 137 | +
|
| 138 | +const int dt = 30; |
| 139 | +uPID pid(D_INPUT | I_SATURATE); |
| 140 | +// uPIDfast<D_INPUT | I_SATURATE> pid; |
| 141 | +
|
| 142 | +void setup() { |
| 143 | + // pid.Kp = 10; |
| 144 | + // pid.Ki = 20; |
| 145 | + // pid.Kd = 5; |
| 146 | +
|
| 147 | + pid.setKp(10); |
| 148 | + pid.setKi(20); |
| 149 | + pid.setKd(5); |
| 150 | +
|
| 151 | + // pid.Kbc = 0.1; |
| 152 | + pid.setDt(dt); |
| 153 | + pid.outMax = 255; |
| 154 | + pid.outMin = -255; |
| 155 | +
|
| 156 | + pid.setpoint = уставка; |
| 157 | +} |
| 158 | +
|
| 159 | +void loop() { |
| 160 | + float result = pid.compute(показания_датчика); |
| 161 | + применить(result); |
| 162 | + delay(dt); |
| 163 | +} |
| 164 | +``` |
| 165 | + |
| 166 | +<a id="versions"></a> |
| 167 | + |
| 168 | +## Версии |
| 169 | +- v1.0 |
| 170 | + |
| 171 | +<a id="install"></a> |
| 172 | +## Установка |
| 173 | +- Библиотеку можно найти по названию **uPID** и установить через менеджер библиотек в: |
| 174 | + - Arduino IDE |
| 175 | + - Arduino IDE v2 |
| 176 | + - PlatformIO |
| 177 | +- [Скачать библиотеку](https://github.com/GyverLibs/uPID/archive/refs/heads/main.zip) .zip архивом для ручной установки: |
| 178 | + - Распаковать и положить в *C:\Program Files (x86)\Arduino\libraries* (Windows x64) |
| 179 | + - Распаковать и положить в *C:\Program Files\Arduino\libraries* (Windows x32) |
| 180 | + - Распаковать и положить в *Документы/Arduino/libraries/* |
| 181 | + - (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив |
| 182 | +- Читай более подробную инструкцию по установке библиотек [здесь](https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA) |
| 183 | +### Обновление |
| 184 | +- Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи |
| 185 | +- Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить" |
| 186 | +- Вручную: **удалить папку со старой версией**, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам! |
| 187 | + |
| 188 | +<a id="feedback"></a> |
| 189 | + |
| 190 | +## Баги и обратная связь |
| 191 | +При нахождении багов создавайте **Issue **, а лучше сразу пишите на почту [[email protected]](mailto:[email protected]) |
| 192 | +Библиотека открыта для доработки и ваших **Pull Request**'ов! |
| 193 | + |
| 194 | +При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать: |
| 195 | +- Версия библиотеки |
| 196 | +- Какой используется МК |
| 197 | +- Версия SDK (для ESP) |
| 198 | +- Версия Arduino IDE |
| 199 | +- Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде |
| 200 | +- Какой код загружался, какая работа от него ожидалась и как он работает в реальности |
| 201 | +- В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код |
0 commit comments