Как мне использовать ПИД-регулятор?
В настоящее время я работаю над регулятором температуры.
У меня есть функция Temperature_PID(), которая возвращает управляемую переменную (которая является суммой членов P, I и D), но что мне делать с этим выводом?
Температура контролируется с помощью ШИМ, поэтому рабочий цикл 0% = нагреватель выключен, а рабочий цикл 100% = нагреватель включен.
Пока я пытался
Duty_Cycle += Temperature_PID();
if(Duty_Cycle > 100) Duty_Cycle = 100;
else if(Duty_Cycle < 0) Duty_Cycle = 0;
Это не сработало для меня, потому что термин I в основном делает эту систему очень нестабильной. Представьте, что вы интегрируете область, добавляете еще одну небольшую точку данных, снова интегрируете область и суммируете их. Вновь и вновь. Это означает, что каждая точка данных значительно ухудшает эту схему управления.
Другая вещь, которую я хотел бы попробовать,
Duty_Cycle = Expected_Duty_Cycle + Temperature_PID();
где Expected_Duty_Cycle - это то, что температура должна быть установлена, когда контроллер достигнет стабильной точки, а Temperature_PID() равен 0. Однако это также не работает, потому что Expected_Duty_Cycle всегда будет меняться в зависимости от состояния нагревателя, например, при другой погоде.,
Итак, мой вопрос, что именно я делаю с выводом PID? Я не понимаю, как назначить рабочий цикл на основе вывода ПИД. В идеале это будет при 100% рабочем цикле, пока температура почти не достигнет заданного значения и не начнет снижаться до более низкого рабочего цикла. Но, используя мой первый метод (с моим коэффициентом усиления, установленным на ноль), он начинает понижать рабочий цикл только после того, как он уже перескочил.
Это мой первый пост. Надеюсь, я найду свой ответ. Спасибо stackru.
РЕДАКТИРОВАТЬ: Вот моя функция PID.
double TempCtrl_PID(PID_Data *pid)
{
Thermo_Data tc;
double error, pTerm, iTerm, dTerm;
Thermo_Read(CHIP_TC1, &tc);
pid->last_pv = pid->pv;
pid->pv = Thermo_Temperature(&tc);
error = pid->sp - pid->pv;
if(error/pid->sp < 0.1)
pid->err_sum += error;
pTerm = pid->kp * error;
iTerm = pid->ki * pid->err_sum;
dTerm = pid->kd * (pid->last_pv - pid->pv);
return pTerm + iTerm + dTerm;
}
РЕДАКТИРОВАТЬ 2: Никогда не использовал это раньше, поэтому дайте мне знать, если ссылка не работает. https://picasaweb.google.com/113881440334423462633/January302013
Извините, Excel вылетает из-за меня, когда я пытаюсь переименовать оси или название. Примечание: в системе еще нет вентилятора, поэтому я не могу охладить нагреватель так быстро, как могу, чтобы он нагрелся, поэтому он проводит очень мало времени ниже установленного значения по сравнению с вышеупомянутым. Первое изображение - простой контроллер включения / выключения. Второе изображение - мой контроллер PD. Как вы можете видеть, для снижения температуры требуется гораздо больше времени, поскольку она не вычитается до превышения температуры, она ждет, пока температура не поднимется, прежде чем вычесть из рабочего цикла, и делает это слишком медленно. Как именно я могу сказать своему контроллеру снизить рабочий цикл, прежде чем он достигнет максимальной температуры?
3 ответа
Выход PID является рабочим циклом. Вы должны настроить kp
, ki
, а также kd
поставить выход ПИД в диапазоне Duty_Cycle
Например, от 0 до 100. Обычно хорошей идеей является явное ограничение вывода в самой функции PID.
Вы должны "настроить" свой PID в простых шагах.
Отключить интегральные и производные условия (установить
ki
а такжеkd
в ноль)Медленно увеличивайте свой
kp
пока изменение уставки на 10% не заставит выходной сигнал колебатьсяуменьшить
kp
на 30% или около того, что должно устранить колебанияЗадавать
ki
до долиkp
и настройте, чтобы получить желаемый компромисс между перерегулированием и временем для достижения заданного значенияНадеюсь, вам не понадобится
kd
, но если вы делаете, сделайте его еще меньше
Выходной сигнал ПИД-регулятора должен напрямую устанавливать значение коэффициента заполнения.
По сути, вы будете управлять настройками нагревателя, основываясь на разнице фактической температуры и заданной температуры.
Вам нужно будет отрегулировать значения параметров PID для получения требуемой производительности.
Сначала установите I и D на ноль и введите значение для P, скажем, 2, чтобы начать.
Измените заданное значение и посмотрите, каков ваш ответ. Увеличьте P и сделайте другое изменение уставки и посмотрите, что произойдет. В конце концов вы увидите, что температура постоянно колеблется и никогда не достигнет стабильного значения. Это значение известно как "усиление ультиматата". Обратите внимание также на частоту колебаний. Установите P равным половине предельного усиления.
Начните со значения 1,2(предельное усиление)/(частота колебаний) для I и измените заданное значение. Отрегулируйте значения P и I из этих значений, чтобы добраться туда, куда вы хотите пойти, отслеживая процесс и наблюдая, улучшают ли увеличивающиеся или уменьшающиеся значения.
Если у вас есть P и I, вы можете работать с D, но в зависимости от динамики процесса, значение D может ухудшить вашу жизнь.
Метод Циглера-Николса дает вам некоторые рекомендации по значениям PID, которые должны помочь вам в этом. Оттуда вы можете внести коррективы, чтобы получить лучшую производительность.
Вам нужно будет взвесить варианты превышения с количеством времени, которое требуется температуре для достижения нового заданного значения. Чем быстрее регулируется температура, тем больше будет превышение. Отсутствие перерегулирования значительно увеличит это время.
Несколько предложений:
- Вы, кажется, интегрируете дважды. Однажды внутри вашего
TempCtrl_PID
функционировать и однажды снаружи.Duty_Cycle +=
, Так что теперь ваш термин P на самом деле я. - Начните только с P-члена и продолжайте увеличивать его, пока система не станет нестабильной. Затем отступите (например, используйте значение от 1/2 до 1/4, где оно становится нестабильным) и начните добавлять термин I. Начните с очень низких значений в I семестре, а затем постепенно увеличивайте. Этот процесс является способом настройки цикла. Поскольку система, вероятно, будет иметь довольно большую постоянную времени, это может занять много времени...
- Вы можете добавить некоторую прямую связь, как вы предлагаете (ожидаемый рабочий цикл для заданного заданного значения - отобразите его, задав рабочий цикл и позволив системе стабилизироваться.). Не имеет значения, если этот термин не идеален, поскольку цикл устранит оставшуюся ошибку. Вы также можете просто добавить некоторое постоянное смещение в рабочий цикл. Имейте в виду, что константа не будет иметь никакого значения, поскольку интегратор ее уберет. Это повлияет только на холодный старт.
- Убедитесь, что у вас есть какая-то фиксированная временная база для этого цикла. Например, настройте каждые 10 мс.
- Я бы не стал беспокоиться о термине D на данный момент. Контроллер PI должен быть достаточно хорошим для большинства приложений.