Page 1 of 1

Каскадный интегратор для ПИД (CIC-PID)

Posted: Fri Dec 22, 2017 12:16 pm
by andreika
Немного предыстории.
Мы с Артёмом @darxfame пробовали "на бумаге" некоторые методы автонастройки ПИДа для РХХ, вроде Циглера и подобных. Вбивали полученные коэффициенты в текущую реализацию ПИДа в rusEFI и смотрели по отладочным логам, что происходит. И заметили, что I-компонента очень часто упирается в пределы мин/макс, особенно на начальных этапах настройки ПИДа.
И это сильно искажает результаты работы, и не даёт адекватно воспринимать реакцию системы при подборе параметров. В текущей реализации ПИДа, I-компонента ограничивается мин/макс-значениями самого ПИДа. И они не годятся, особенно для высокоинерционных движков и медленных РХХ, где накопление интегратора весьма приличное.

Самое простое решение, предложенное ещё в комментариях реализации ПИДа, было просто задать отдельные (увеличенные) лимиты для I-компоненты. Но такой подход обладает одним недостатком: он не умеет "забывать" прошлые ошибки, полагаясь на то, что ПИД уже неплохо настроен, и ошибка будет неизбежно уменьшаться. Однако в случае недонастроенного ПИДа или иных причин, когда появляются автоколебания регулятора ("раскачивания"), этого не происходит. Интегратор всё равно упирается в лимиты, пусть даже расширенные. Но, главное, при этом внутри I-компоненты оказываются слишком старые ошибки, которые уже не актуальны для текущего положения регулятора.

Поэтому возникла идея: сделать для интегратора временнОе окно (измеряемое в N секундах, в зависимости от настройки периода ПИД), и тогда накопления прошлых ошибок не будет, и сама I-компонента будет естественным образом ограничена. К сожалению, реализовать "в лоб" moving sum мы не можем себе позволить, т.к. придётся хранить в большом буфере все значения ошибок в течение всего окна интегрирования (а оно может быть десятки секунд). Поэтому был реализован каскадный интегратор - алгоритм наподобие CIC-фильтра (cascaded integrator-comb), который требует на порядок меньше памяти для своего буфера, и при этом позволяет поддерживать moving sum в довольно большом окне.

Собственно, сейчас используется только два каскада (для экономии памяти) и, соответственно, один циклический буфер - этого хватает для окна интегрирования шириной более 10 секунд даже для самого малого периода 10 мс. При этом в памяти мы занимаем 32*4 байта. Также мы используем усреднение значений в буфере для сглаживания перехода между позициями буфера (иначе "резкий" CIC может спровоцировать возбуждение в ПИДе).

Алгоритм вынесен в отдельный класс PidCic, и тем самым в прошивке есть возможность на выбор использовать любую из имеющихся реализаций ПИД - старую и новую. Обратная совместимость полностью сохранена, и для пользователей не возникнет неудобств.

Этот алгоритм уже частично протестирован Артёмом на реальной машине, и тестирование ещё продолжается.

Итак, вот PR:
https://github.com/rusefi/rusefi/pull/519

Re: Каскадный интегратор для ПИД (CIC-PID)

Posted: Mon Dec 25, 2017 2:24 am
by AndreyB
Очень хороший топик! Лучше его можно сделать только переводом на английский, чтоб вся аудитория могла читать :)

Re: Каскадный интегратор для ПИД (CIC-PID)

Posted: Fri Sep 13, 2019 8:49 am
by andreika
russian wrote:
Mon Dec 25, 2017 2:24 am
Очень хороший топик! Лучше его можно сделать только переводом на английский, чтоб вся аудитория могла читать :)
https://github.com/rusefi/rusefi/blob/master/firmware/util/math/pid_cic.md
:roll: