Собственный алгоритм работы ПИД регулятора.

WADDAW
Offline
Зарегистрирован: 13.04.2019

Здравствуйте!

Эту тему я решил выложить, потому, что долго искал простое описание и практическую реализацию ПИД регулятора. Толкового описания для “чайников” я так и не нашел, а практическая реализация сводится либо к использованию библиотек, либо сравнима с запуском ракеты на луну. Про подбор коэффициентов для регулятора вообще скромно умолчу, потому что это сродни танцам с бубном. Причем в каждом конкретном случае и недай бог изменятся какие-то начальные условия…

Выношу на ваш суд своё видение и реализацию ПИД регулятора. Может я и изобрел влосипед… Но если все попробуют и протестируют предложенный тип регулятора, а потом выскажут свое мнение, будет очень интересно. Возможно это облегчит кому-нибудь жизнь.

Алгоритм работы ПИД регулятора.

Теория:

Работа регулятора основана на пропорциональном регулировании, которое зависит от разности заданной и реальной величины регулирования и скорости нарастания реальной величины.

Предлагаемый регулятор имеет следующие особенности и характеристики;

  1. Высокая скорость нарастания выхода мощности регулирования при большой разнице между заданной величиной и измеренной.
  2. Высокая точность и плавность изменения мощности при небольшой разнице между заданной величиной и измеренной.
  3. Стабильность работы на всех краях диапазона регулирования.
  4. Простота математического расчёта.
  5. Малая зависимость от способа и типа прикладываемой мощности и количества или обьема регулируемого тела.

Можно представить, что величиной регулирования управляет оператор, который основывается только на показаниях измеряемой величины. Например: необходим нагрев тела неизвестной массы нагревательным элементом неизвестной мощности. Из величин, мы имеем измеренную, текущую температуру нагреваемой массы и заданную температуру. Мощность нагревательного элемента оператор может регулировать или включать и выключать по своему усмотрению. Если реальная температура ниже заданной, то оператор будет постепенно добавлять мощность нагрева следя за показаниями реальной температуры. Если разность заданной и реальной температур будет оставаться относительно большой, а скорость нарастания температуры маленькой или не меняться, то оператор постепенно доведет мощность нагрева до максимума. После начала повышения температуры, оператор начнет экстраполировать скорость нарастания температуры, чтобы вовремя уменьшить мощность нагрева, так чтобы при существующей скорости нарастания температуры, реальная температура была-бы близка к заданной. Таким образом наступит баланс между мощностью нагревательного элемента и реальной температурой, которая будет стремиться к заданной. Чем точнее будут измерения реальной температуры и чем чаще оператор будет производить экстраполяцию и регулирование мощьности нагревателя, тем точнее будет поддерживаться заданная температура. Из за того, что в реальности скорость нарастания температуры всегда разная, то частота экстраполирования и регулирования мощности подбирается соответственно такой, что-бы получить приемлемое приближение к заданной температуры и минимальное ее изменение по величине (синусойда).

В классическом ПИД регуляторе применяются три вычисляемых коэффициента, не считая временных переменных. Это П – пропорциональная составляющая, И – интегральная составляющая, Д – интегральная составляющая.

В предлагаемом регуляторе применяются два вычисляемых коэффициента. П – пропорциональная составляющая указывающая на разность заданной и реальной величины регулирования, И - интегральная составляющая указывающая на скорость изменения реальной величины. П – дает приращение величины регулирования. И – ограничивает приращение величины регулирования.

Практическое описание:

Рассмотрим классический пример регулировании температуры от 0 до 100* при регулировании прилагаемой мощности от 0 до 100% с временем интегррования 1сек. При регулировании неважно количество, масса, теплоемкость и тепло потери нагреваемого тела, а также прилагаемая мощность нагрева. Главное условие, что при прилагаемой мощности нагрева равной 100% ,  нагрев нагреваемого обьекта достигает или превышает заданное значение температуры, а при прилагаемой мощьности равной 0% происходит остывание обьекта.

При начальных условия температура нагреваемого объекта относительно мала, а заданная температура относительно высокая. Поэтому пропорциональная составляющая - П будет высокой. П = (Т.заданная-Т.реальная)*П.коэффицент

Приращение температуры – И, сначала будет небольшое и будет проверяться с начала времени интервала интегррования и по окончании. В нашем случае время интегрирования принято 1 сек. И = (Т.нач.интегр. - Т.кон.интегр.)*И.коэффициент

Выходная мощность Р.вых будет рассчитываться через каждый интервал времени интегррования, в нашем случае это 1 сек. Она будет равна приращению пропорциональной составляющей – П и вычитанию интегральной составляющей – И. 

Полная формула расчета будет выглядеть следующим образом: 

Р.вых = Р.вых + П – И     

или  

Р.вых = Р.вых + (Т.зад-Т.реал)*П.коэф – (Т.нач.интегр. - Т.кон.интегр.)*И.коэф

Вычисления будут проводиться каждый интервал времени интегрирования, в нашем случае это 1 сек.

При превышении выходной мощности Р.вых установленного максимального значения, оно приравнивается максимальному значению (при Р.вых > 100 тогда Р.вых = 100). При уменьшении выходной мощности Р.вых меньше минимального значения, оно приравнивается минимальному значению (при Р.вых < 0 тогда Р.вых = 0). Таким образом ограничивается минимальная и максимальная мощность.

При приближении реальной температуры к заданной, коэффициенты П и И будут стремится к нулю и изменяться только при нарушении реальной и заданной температуры. Поэтому после достижения реальной температуры и заданной, регулятор останется в покое, пока разница температур не изменит коэффициенты в формуле расчёта. Причем если интегральная составляющая будет отрицательной, тоесть температура будет падать, то минус в формуле будет давть плюс и интегральная составляющая уже будет не ограничивать, а увеличивать приращение выхода регулятора, тем самым увеличивая скорость реагирования. При повышении реальной температуры над заданной, коэффициент П уже будет с отрицательным значением и уменьшать величину выхода. Коэффициент И в этом случае тоже поменяет значение с минуса на плюс и будет ограничивать скорость уменьшения выхода регулятора.

Таким образом скорость нарастания выходной мощности будет варьироваться пропорциональной составляющей – П и ограничиваться интегральной составляющей – И и вписываться в  установленные рамки минимальной и максимальной мощности. Расчёт текущей мощности будет верен в пределах установленного интервала времени, в нашем случае это 1 сек.

Математика работы этого регулятора тоже очень простая, и позволяет легко регулировать мощность в указанных пределах и необходимой скоростью. Также регулятор легко позволяет динамически менять диапазон пределов и скорость регулирования прямо в процессе работы.

Предварительные испытания с различными мощностями нагрева и разными объёмами нагреваемого тела, показали, что регулятор настраивается один раз. Коэффициенты были взяты следующим образом П.коэф –  0,21  И.коэф – 2,9 . Коэффициенты были выбраны таким образом, чтобы обеспечить приемлемую скорость нарастания при относительно большой разнице между реальной и заданной температурой, а также примерно одинаковую компенсацию параметров «П» и «И» в диапазоне примерно равных значений между реальной и заданной температурой.   Регулятор уверенно регулирует нагрев, независимо от объёма нагреваемого тела и при различных мощностях нагревательных элементов. Также для настроенного регулятора нет разницы, какой тип мощности прикладывается для организации нагрева. Это может быть 1- аналоговый тип мощности, 2- широтно импульсный тип мощности, 3- дискретно импульсный тип мощности.

При дискретном регулировании мощности, регулятор показал высокую стабильность, точность и скорость регулирования температуры нагреваемого тела. Был применен следующий метод дискретным регулированием нагрева. Общий интервал сигнала был выбран равным 10 сек. Общий интервал сигнала был приравнен к времени интегрирования, так, как за это время были произведены замеры по изменению температуры. Общий интервал делился на количество сегментов равное количественно выходу регулятора. По таймеру имеющему длительность времени равную одному сегменту происходило суммирование этих интервалов. В начале общего интервала интегрирования выход включался на нагрев. При равенстве количества сегментов и значения выхода регулятора происходит отключение нагрева. Так например при выходе регулятора 30% , нагреватель сначала будет включенным 30 временных сегментов, а 70 временных сегментов будет выключен. При повторном интервале интегрирования процесс повторится. Если на выходе регулятора будет 0%, то не успев включится, нагреватель будет включенным 0 временных сегментов, а 100 временных сегментов будет выключен. Если на выходе регулятора будет 100%, то включившись, нагреватель будет постоянно включенным 100 временных сегментов, а 0 временных сегментов будет выключен.

Работа регулятора проверялась на регулировании температуры паяльника и с такими же коэффициентами и терморезистором на 10кОм нагрев емкости с водой  на 20л. газовым нагревателем. Логика и управление тестировалось на контроллере «Ардуино UNO» с релейным выходом и терморезистором на 10кОм.   Регулятор успешно набрал заданную температуру и уверенно удерживал ее на уровне погрешности 0,1-0,5 градуса. Нагрев производился от исходной температуры 22-23 градуса. На заданную температуру 80 градусов паяльник вышел примерно за 5 минут. Емкость с водой нагрелась до температуры 80 градусов примерно за 15-20 минут.

Вот пример реализации кода;

void PID_Output() //************************************* выход пид
{
     int PID_Long_Time = 0;
     // endmillis – время начала интегрирования

      PID_Long_Time = PID_Out * 10 * PID_Time;
     
       if (PID_Long_Time < (millis()- endmillis) ) { digitalWrite(OutPower, HIGH); }
       if (PID_Long_Time > (millis()- endmillis) ) { digitalWrite(OutPower, LOW); } 
 }  //************************************* выход пид


void PID_Count() //************************************* расчет пид
{
PID_T = (SetTempProdukt/10.)  - TempPID_1;
 PID_T = PID_T * (PID_Kt/100.);
  
 PID_D = TempPID_1-TempPID_2;
 PID_D = PID_D * (PID_Kd/100.);
 PID_D = PID_T - PID_D;
 
 PID_Out = ( PID_Out + PID_D );

 PID_D = TempPID_1-TempPID_2;
 PID_D = PID_D * (PID_Kd/100.);
 
 if (PID_Out  > 100) { PID_Out  = 100; }
 if (PID_Out  < 0) { PID_Out  = 0; }
 
} //************************************* расчет пид

 

SLKH
Offline
Зарегистрирован: 17.08.2015

Первое впечатление: перепутаны интеграл с дифференциалом. 

И ждать аж 5 минут, пока паяльник нагреется с 20 до 80 градусов - некузяво. 

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

WADDAW пишет:

сравнима с запуском ракеты на луну.

У Вас большой опыт запуска ракет? Вы знаете какие там сложности?

WADDAW пишет:

Про подбор коэффициентов ... это сродни танцам с бубном.

Не сродни, а оно и есть. Что, кстати, прямо следует из самой идеи ПИД регулирования.

WADDAW пишет:

И - интегральная составляющая указывающая на скорость изменения реальной величины. 

Это дифференциальная составляющая, а не интегральная

WADDAW пишет:

В предлагаемом регуляторе применяются два вычисляемых коэффициента. 

Значит, это не ПИД. По Вашим словам - это ПИ, а учитывая. что Вы запутались - получается ПД.

К сожалению, не могу оценить код, т.к. он приведён не полностью. Например, я не вижу как описаны и проинициализированы переменные.

SLKH
Offline
Зарегистрирован: 17.08.2015

ЕвгенийП пишет:

WADDAW пишет:

Про подбор коэффициентов ... это сродни танцам с бубном.

Не сродни, а оно и есть. 

Причем в традиционном исполнении эти танцы, надо признать, не слишком веселые. Крутишь эти три потенциометра туда/сюда/обратно - не одно, так другое вылезает.

То ли дело сейчас: микроконтроллер может на ходу менять коэффициенты. Можно чисто вывести систему на заданный параметр практически без запаздывания и выбросов и точно его держать - красота!

trembo
trembo аватар
Онлайн
Зарегистрирован: 08.04.2011
qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Напоминает- Великое искусство верховой езды заключается в удержании равновесия.Чем ниже голова тем глубже мои мысли https://www.youtube.com/watch?v=5JGye1VLH4Q

Onkel
Offline
Зарегистрирован: 22.02.2016

Что-то Вы тут прямо страх перед ПИДом наводите... Штука (в 99% случаев) элементарная, без танцев и бубнов, настраивается за  минуты- что для катера, что для кара, что для коптера с самолетиком. ПИДы для чайников, доступно и всерьез, чтобы без танцев с бубмнами. Автору - ТС спасибо за попытку, но начать лучше с этого:
http://we.easyelectronics.ru/Theory/pid-regulyatory--dlya-chaynikov-praktikov.html

настройка эмпирическим методом кого-то-там -циклера (у меня работает всегда)
 http://we.easyelectronics.ru/Theory/prostoy-metod-nastroyki-pid-regulyatora.html

 

WADDAW
Offline
Зарегистрирован: 13.04.2019

Вообще идея была в принципе реализации ПИД  регулятора.

Скорость регулирования различных устройств в большей мере зависит от инерционности самих устройств а также правильно подобранных коэффициентов. Тот же нагрев паяльника или емкости с водой не может происходить мгновенно.  На быстродействующих системах, таких как гироскопы или других системах, где скорость реагирования секунды и меньше, я регулятор не проверял. Поэтому было-бы неплохо, если кто-нибудь применит и испытает регулятор на быстродействующих системах, и поделится отзывом о его работе.

Ниже я попробовал причесать код, и сделать его более читабельным.

// Глобальные переменные
float PID_T = 0;                       // Составляющая по разнице температур
float PID_D = 0;                      // Дифиринцируемая составляющая по времени нарастания
float PID_Kt = 0.21;               // Коэффициент составляющей по времени нарастания
float PID_Kd = 2.9;                // Коэффициент дифиринцирующей составляющая по разнице температур
unsigned long endmillis = 0;       // осчет милисек интегрированного времени
float PID_Out = 0;                  // Выход ПИД
int PID_Time = 10;                   // Время интегрирования заданное в секундах
float TempPID_1 = 0;            // Значение температуры в конце интегрирования
float TempPID_2 = 0;            // Значение температуры в начале интегрирования
float SetTempProdukt ;        // Уставка температуры
float TempReal ;               // реальная температура
int OutPower = 12;             // назначение номера дискретного выхода


void loop()   //*************************** общий цикл программы
{
    if (( millis() - endmillis) > (1000* PID_Time))
   {                                                       // проверяем интервал интегрирования в секундах
     endmillis = millis();                                 // время начала интегрирования
    TempPID_2 = TempPID_1;                                 // Значение начальной температуры равно конечной предыдущей
     TempPID_1 = TempReal;                                 // Значение конечной температуры равно текущей конечной
     PID_Count();                                          // вызов функции по расщету ПИД
   }
   PID_Output();                                           //  вызов функции по выходу регулятора ПИД
}


void PID_Output() //************************************* выход пид
{
     int PID_Long_Time = 0;
     
     // так как PID_Out в максимуме =100 то умножаем его на 10 , чтоб довести до 1000 мСек. 
     // и умножаем на время интегрирования в секундах 

      PID_Long_Time = PID_Out * 10 * PID_Time;  // получаем время работы выхода в мСек.
     
      //  на вход реле надо подавать сигнал HIGH, чтобы его выключить и LOW, чтобы включить
      //  если с начала интегрирования прошло времени меньше работы выхода в мСек. 
      //  то не включаем выход 

       if (PID_Long_Time < (millis()- endmillis) ) { digitalWrite(OutPower, HIGH); }

      //  если с начала интегрирования прошло времени больше работы выхода в мСек. 
      //  то включаем выход 

       if (PID_Long_Time > (millis()- endmillis) ) { digitalWrite(OutPower, LOW); } 

 }  //************************************* выход пид


void PID_Count() //************************************* расчет пид
{
 PID_T = (SetTempProdukt  - TempPID_1) * PID_Kt;  // расчет пропорциональной составляющей
  
 PID_D = (TempPID_1 - TempPID_2) * PID_Kd;        // расчет диференциальной составляющей
 PID_Out = PID_Out + PID_T - PID_D ;              // расчет выхода регулятора
 
 if (PID_Out  > 100) { PID_Out  = 100; }          // ограничение ПИД по максимальному значению
 if (PID_Out  < 0) { PID_Out  = 0; }              // ограничение ПИД по минимальному значению
 
} //************************************* расчет пид
nik182
Offline
Зарегистрирован: 04.05.2015

Вы плюнули на теорию регулирования. Нельзя гордым словом ПИД называть элементарный ПД регулятор. Буква И в названии регулятора говорит о накапливании ошибки. Где в вашем коде это происходит? Всё остальное не тянет на откровение. Разделить расчёт коэффициентов и времени шага регулятора в отденые подпрограммы это круто. Но зачем? 

WADDAW
Offline
Зарегистрирован: 13.04.2019

Видимо я несмог толком разобраться с класическим ПИД регулятором, поэтому сделал свой регулятор, так как понимаю его я. В теории все удивительно и прекрасно, но на практике реализацию класического ПИД регулятора, особенно в простых системах, все советуют заменить на простое пороговое управление по уставке. Поэтому я придумал свой способ регулирования, а может быть и повторил уже сущевствующий. Может в теории что-то и не так, но на практике регулятор работает и как я отмечал в начале, имеет много положительных сторон. Самое главное, это практическое применение.  Хотелось бы услышать не толко теоретические отзывы, "плохо потому, что это плохо" а практические "собрал, включил, регулирует или не регулирует, медленно или неточно..." А то цифры то у всех одинаковые, но применяются то они поразному...

Logik
Offline
Зарегистрирован: 05.08.2014

WADDAW пишет:

Видимо я несмог толком разобраться с класическим ПИД регулятором

Да. И попробовали сделать, как выше замечено, ПД регулятор. И я бы даже согласился что сделали, но странная стр.55 не позволяет. Выходное на каждом такте не должно накапливатся. Накапливание его - как раз элемент интегрирования. Но в ПИД должна интегрироватся ошибка, а не разность П и Д. Вобщем низачет.

Но бросать дело не стоит, просто надо еще немного поразбирать вопрос.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

WADDAW, вот лично я никогда с ПИД регулятором ни в теории, ни на практике не сталкивался. Повода не было. Ну, возможно, за исключением некоторых частных случаев, когда мне, как и Вам, нужно было решить какую-то частную задачу, не особо вникая в общую теорию.

Поэтому буду рассуждать, опираясь исключительно на общую эрудицию. Насколько я понял, это как раз тот подход, которому Вы следуете.

Итак, ПИД - это наиболее общий вид регулятора. На практике в каждом частном случае обычно хватает лишь части его возможностей. Т.е. ПИД регулятор может работать в следующих режимах: "ПИД", "ПИ", "ПД", "ИД", "П", "И" и "Д". Всего получается 7 штук. Для общности можем ввести режим с полным отсутствием всякого регулирования "0", тогда получим как раз 2^3=8 режимов, где "^" - операция возведения в степень, а "3" - количество букв в "ПИД".

Вы рассматриваете не общий случай, а лишь один из его режимов "ПД" (впрочем, называя его "ПИ"), который пытаетесь применить к частной задаче, для которой, именно этот частный случай, вероятно, и подходит. Но этот частный случай никак не поможет в тех случаях, когда для регулирования потребуется один из 6 оставшихся режимов.

Исключите из классического описания ПИД регулятора 85% текста, относящегося к неиспользуемым Вами вариантам, и останется описание не длинее Вашего, только более аккуратное и без ошибок.

Logik
Offline
Зарегистрирован: 05.08.2014

Не, длиношеее, слишком академично загнул. Д не бывает, на уставку не выведет. И - абсолютно неустойчив, колебательно, могу представить чисто теоретически, для случая когда колебания пофиг, но скорей тоже не бывает. ИД - тоже крайне мутное шото, думаю не бывает. Вощем из вариантов комбинаторики сразу убираем безсмысленные.

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

SLKH
Offline
Зарегистрирован: 17.08.2015

WADDAW пишет:

но на практике регулятор работает .

На самом деле мы не видели результат с термографа и не знаем, как он работает на самом деле.

 

Цитата:
  Хотелось бы услышать не толко теоретические отзывы, "плохо потому, что это плохо" а практические "собрал, включил, регулирует или не регулирует, медленно или неточно..."

Практическое замечание я написал сразу: раз паяльник греется аж 5 минут, похоже, что ваш регулятор неверно спроектирован.

Logik
Offline
Зарегистрирован: 05.08.2014

Воще говоря по самой цифре 5 минут ниче сказать нельзя. Надо знать время нагрева без системы регулирования т.е. при нагреве на максимальной мощности до рабочей температуры. Система регулирования замедлит процесс и  время увеличит, вот на сколько стало медленней - один из показателей работы системы. Надо чтоб не более чем на несколько десятков процентов.

SLKH
Offline
Зарегистрирован: 17.08.2015

Logik пишет:

Воще говоря по самой цифре 5 минут ниче сказать нельзя. Надо знать время нагрева без системы регулирования т.е. при нагреве на максимальной мощности до рабочей температуры. Система регулирования замедлит процесс и  время увеличит, вот на сколько стало медленней - один из показателей работы системы. Надо чтоб не более чем на несколько десятков процентов.

Всё это совершенно правильно, но ТС хотел "практически".

Занижена мощность питателя (возможно, для лучших результатов работы алгоритма) или же плох алгоритм - особого значения не имеет. 5 минут греть паяльник с 20 до 80 (!) градусов - это не "регулятор мощности паяльника", а ерунда какая-то. Регулятор с цифровым управлением должен обеспечивать быстрый разогрев и дальнейшее поддержание температуры, иначе зачем всё это накручивать?

-NMi-
Offline
Зарегистрирован: 20.08.2018

ТС вот только "хотел" - но не сдюжил а только скопипастил код, причём совершенно не понимая его сути.

Для понимания сути процесса, кратко, объясню:

P - это как операционный усилитель со своим коэффициентом усиления, Px

I - копилка ошибок, опять-таки со своим коэффициентом ошибок Ix

D - дифференциальная составляющая (перерегулирование попросту) Dx

Это всё можно найти в нете, причём в разных интерпретациях и по разному оформленными в коде... но... самое главное не тУта, оно ниже!

Итак, если мы "хотим" управлять нагревателем посредством Timer0_pwm - то мы должны считать не от 0 до 100 а ОТ 0 до 255 !!!

Если с Timer1 - ТО считать нужно от 0 до 1024 !!!

Далее, если ПИД регулятор "продвинутый", он считает момент инициализации и накапливает не только PID коэффициенты, но и адаптивные коэффициенты за единицу времени. Например, если мы попытаемся небольшим нагревателем нагреть большой объём воды (например) , то при запуске PID регулятора коэффициент I очень быстро "переполнится" и такой регулятор "перегреет" воду в первой итерации. Во второй итерации D коэффициент "переполнится" и система будет долго "входить" в режим. ПОЭТОМУ ставят ещё и дополнительные коэффициенты на PID с некими "коридорами" от и до, в которых предотвращается переполнение. 

Ну и самое "крутое" на десерт --- это, конечно, таблица линейности всего ПИД регулятора, т.е. в классическом случае мы имеем линейность во всём диапазоне равную 1. В "продвинутых" ПИД регуляторах эту линейность можно корректировать "руками"

Ну, у меня на сегодня фсё... удачи в написании кода!

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

-NMi- пишет:

а только скопипастил код, причём совершенно не понимая его сути.

Так что, код не оригинальный? :(((

-NMi-
Offline
Зарегистрирован: 20.08.2018

Чото я очкую такой "код" применять...  ))))))))))))))))))))

WADDAW
Offline
Зарегистрирован: 13.04.2019

-NMi- пишет: а только скопипастил код, причём совершенно не понимая его сути.

Код не копипстил. Суть регулятора описана в начале, и сводится к управлению подобно виртуальному оператору. Код можно написать любой. Просто показал простоту реализации вычислений регулятора и вариант реализации при дискретном регулировании. При аналоговом регулировании помоему вообще проблем не возникает с выходом регулирования. Величина диапазона выхода 0 - 100 взята для удобства визуализации в % , но может быть любой. Только необходимо будет подобрать другие коэффициенты. Попробовать регулятор можно и на макете, необязательно сразу применять его на ответственных устройствах. Я вот так и сделал. Чем болше будет практических тестов и отзывов, тем понятнее будет работает тегулятор только в частном случае или во всех случаях. 

nik182
Offline
Зарегистрирован: 04.05.2015

Коэффициены ПИД регулятора зависят от постоянных времени реакции системы. Соответственно нет универсальных коэффициэнтов. Больше того, если в процессе работы постоянные времени реакции системы изменяются, например изменяется объём жидкости в котле, то и коэффициенты нужно подстраивать. В теории есть много методов настройки ПИД регулятора. Мне нравится тот где вводят систему в режим перерегулирования и по периоду колебаний рассчитывают первое приближение на значения коэффициентов. К выходному  значению ПИД регулятора этот процесс имеет очень опосредованное отношение. Контретное значение выдаваемое на управляющий модуль зависит от типа модуля и может быть легко масштабировано программно. У нас в институте курс регуляторов читали целый семестр  и сдавли мы его по довольно толстой книге. Это я к тому, что теория уже давно разработана, описана и сделать что то новое не имея базовых знаний просто невозможно. Ваши потуги смотрятся забавно. Возможно что для конкретной задачи вам удалось подобрать коэффициэнты ПИД регулятора и выглядят они как Ki=0, Kp=0.21, Kd=-2.9 . Но это не универсальное решение. 

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

nik182 пишет:

сделать что то новое не имея базовых знаний просто невозможно. 

Особенно, если интеграл от производной не отличать :)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Ворота пишет:

nik182 пишет:

сделать что то новое не имея базовых знаний просто невозможно. 

Особенно, если интеграл от производной не отличать :)

Так именно это и есть новое!

b707
Offline
Зарегистрирован: 26.05.2017

Ворота пишет:

nik182 пишет:

сделать что то новое не имея базовых знаний просто невозможно. 

Особенно, если интеграл от производной не отличать :)

лишние знания ограничивают полет фантазии исполнителя... :)

По теме - мне тут тоже пришлось писать свой ПИД регулятор. Мотивы "изобретения велосипеда". думаю, были те же, что у ТС - готовые примеры ПИД. найденные в инете, показались излишне сложными - подумалось. что написать свое будет проще. В итоге получился регулятор, который вполне успешно подбирает собственные коэффициенты, но насколько он близок к классическому ПИД - я до сих пор сказать не могу - в теории так и не разобрался.

 

lean_74
Offline
Зарегистрирован: 22.12.2015

b707 пишет:

В итоге получился регулятор, который вполне успешно подбирает собственные коэффициенты, но насколько он близок к классическому ПИД - я до сих пор сказать не могу - в теории так и не разобрался.

А поделиться кодом? я тоже теорию  ПИД не осилил, В инкубаторе использую алгоритм от yul-i-an ,но с подбором коєффициентов вечная проблема, можно даже на почту мойник@mail.ru, если на всеобщее обозрение выкладывать нет охоты.

b707
Offline
Зарегистрирован: 26.05.2017

lean_74 пишет:

А поделиться кодом?

Ну, на сколько-нибудь выдающийся алгоритм я не претендую, поэтому не думаю, что это может кого-то заинтересовать. Выложить можно, но это вопрос не одной минуты, так как регулятор является частью огромного проекта, откуда его надо выгрызать :)

Кроме того, из-за особенностей регулируемой системы алгоритм там специфичный, малопригодный для стандартных нагревателей и прочего.

Это регулятор давления в резервуаре с двумя клапанами - напорным и выпускным. Особенность конструкции в том, что в сам момент регулирования контролировать давление нельзя - при открытии напорного клапана датчик сразу завышает давление в резервуаре, а при спуске - занижает. Поэтому приходится пользоваться "пристрелкой": измерили текущее давление в покое, если оно отличается от нормы -  открыли соответвующий клапан на некоторое время.  Потом закрыли, снова измерили и расчитали изменение давления. Высчитали скорость изменния и необходимое время открытия клапана для следующей итерации. После 3х-5ти "пристрелок" регулятор начинает попадать в нужное давление с первой попытки.

К сожалению., скорость набора и спуска давления не постоянна и зависит и от давления на входе, и от актуального давления в емкости. Поэтому при крайних значениях регулятор начинает прилично ошибаться. Но тут уже нужен более сложный алгоритм, который мне показался излишним.

WADDAW
Offline
Зарегистрирован: 13.04.2019

lean_74 пишет:

А поделиться кодом? 

А что вам мешает попробовать применить предложенный алгоритм регулирования и код? Для регулирования нагрева точно должно подойти. Плавное управление нагревом по принципу включил - выключил любым реле. но лучше твердотельным. Для того, что-бы меньше было помех я использовал временной интервал 10 сек., стартовые коэффициенты в описании. 

lean_74
Offline
Зарегистрирован: 22.12.2015

WADDAW пишет:

А что вам мешает ...

b707 я как то больше доверяю...

b707
Offline
Зарегистрирован: 26.05.2017

lean_74 пишет:

b707 я как то больше доверяю...

это вы зря :)

nikolaki
nikolaki аватар
Offline
Зарегистрирован: 14.02.2013

b707 пишет:

По теме - мне тут тоже пришлось писать свой ПИД регулятор. Мотивы "изобретения велосипеда". ........................я до сих пор сказать не могу - в теории так и не разобрался

Аналогично.

Не пошел и у меня ПИД . Поэтому и я написал свое подобие ( да даже не подобие ПИДа) для очень инерционных систем - воды , пара .

Алгоритм простой. Имеем время "вкл"и время "выкл " нагрузки(ТЭНа).По мере приближения температуры к сетпойнту время включения и выключения уменьшается -увеличивается пропорционально.При достижении сетпойнта  нагрузка выключается. Если надо - добавляем коэффициент к сетпойнту .

Это в общих чертах.Своих целей я достиг . Как то так

Logik
Offline
Зарегистрирован: 05.08.2014

b707 пишет:

lean_74 пишет:

b707 я как то больше доверяю...

это вы зря :)

Не. Не зря!

Я посмотрел на приведеный код в #7 подробней.

08int PID_Time = 0;                   // Время интегрирования заданное в секундах

Хм... онако... Ну может гдето оно не нуль. Ищем.

16     if (( millis() - endmillis) > (1000* PID_Time))
 
34       PID_Long_Time = PID_Out * 10 * PID_Time;  // получаем время работы выхода в мСек.
 

Все, более в коде не встречается.  Отлично WADDAW, вы кого за лоха держите?

ПС. 80-90% кода с гитхаба не собирается. Судя по ошибкам сборки больше половины кода вообще никогда впринципе не собиралось. Про работу остального  - отдельный разговор. Поздравляю WADDAW, вы в тренде!

 

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Фига-се! 

Ну, зато

WADDAW пишет:

  1. Высокая скорость
  2. Высокая точность
  3. Стабильность работы

WADDAW
Offline
Зарегистрирован: 13.04.2019

Logik пишет:

Не. Не зря!

Я посмотрел на приведеный код в #7 подробней.

 

08int PID_Time = 0;                   // Время интегрирования заданное в секундах

 

Все, более в коде не встречается.  Отлично WADDAW, вы кого за лоха держите?

ПС. 80-90% кода с гитхаба не собирается. Судя по ошибкам сборки больше половины кода вообще никогда впринципе не собиралось. Про работу остального  - отдельный разговор. Поздравляю WADDAW, вы в тренде!

Так, как я вытащил текст кода из общего скетча, да еще привел его в удобочитаемый вид, то могли вкрасться некотороые неточности или опечатки. Прошу прощения. В программе PID_Time берет значение из параметров в EEPROM и может меняться по желанию. Поэтому при инициализации переменных он у меня 0. После считывания данных он становится каким нужно, у меня это 10 сек. Пока дело было на стадии эксперементирования, то сделал практически все параметры изменяемые, поэтому столько много переменных. Но зато удобство настройки без перепрошивки.

Хотелось бы сравнить работу класического ПИД регулятора и регулятора предложенного мною на одном и том-же стенде. Но как я говорил выше, сложности в том, что при подробном описании от грамотных людей, нет подробного кода на ардуино, как его вставить в программу, какие переменные нужны и как они считаются. Буду признателен, если мне дадут текст или ссылку на такой код и библиотеки к нему. Попробую сравнить работу обоих регуляторов на одном стенде. 

P.S. в ссылке о работе ПИД регулятора от Onkel http://we.easyelectronics.ru/Theory/pid-regulyatory--dlya-chaynikov-praktikov.html  кажется код не на ардуино...

 

nik182
Offline
Зарегистрирован: 04.05.2015

Вы не предложили ничего нового. У вас обычный ПИД, о чем я писал в #20. Сравнивать нечего. Вот если на вашу систему подобрать правильные коэффициенты тогда и можно сравнивать. ПИД не может быть универсальным. Пробовать вышу реализацию на другом оборудовании бессмысленно.

b707
Offline
Зарегистрирован: 26.05.2017

WADDAW пишет:

P.S. в ссылке о работе ПИД регулятора от Onkel http://we.easyelectronics.ru/Theory/pid-regulyatory--dlya-chaynikov-praktikov.html  кажется код не на ардуино...

 

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

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

WADDAW пишет:
кажется код не на ардуино...
Почему Вам так кажется?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ЕвгенийП пишет:

WADDAW пишет:
кажется код не на ардуино...
Почему Вам так кажется?

Слишком длинный.

Код на Ардуино называется "скетч" (набросок) и состоит обычно из следующих частей:

- подключение "библиотек" - обычно 1-2 строки,

- инициализация - 2-4 строки,

- цикл - обычно число берется из одной библиотеки и запихивается в другую. В зависимости от уровня исполнителя занимает от 1 до 3 строк. Иногда (чтобы цифры не мелькали на экране) в цикл добавляется еще одна строка - delay().

Итого: 10-20 строк.

WADDAW
Offline
Зарегистрирован: 13.04.2019

ЕвгенийП пишет:

WADDAW пишет:
кажется код не на ардуино...
Почему Вам так кажется?

Предложенный код, после вставки его в новый скетч, не компилируется и выдает кучу ошибок. Необьявленные переменные непонятной размерности "enum PIDstep {ReceivingE, ComputeP, ComputeI, ComputeD, MakeAction};    // тип данных «итерация вычислений»" 

Непонятны структуры типа "struct Timer {...};     // структура для часов реального времени" 

Да и стиль приведенного кода не очень похож на тот который предлагают для понимания "чайниками". Сильно много сокращений специфичных для проффессионального кода, плохо раскрывающего саму суть вычислений и логику.

b707
Offline
Зарегистрирован: 26.05.2017

WADDAW - это говорит только о том, что лично вы не знаете Си. А код тут непричем

И что, для вас новость, что все переменные перед использованием надо описывать? :)

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

WADDAW пишет:

Предложенный код, после вставки его в новый скетч, не компилируется и выдает кучу ошибок.

Так никто и не утверждал, что он полный - это пример.

WADDAW пишет:

Непонятны структуры типа "struct Timer {...};     // структура для часов реального времени" 

ну, это Вам они непонятны, код то чем виноват?

WADDAW пишет:

стиль приведенного кода не очень похож на тот который предлагают для понимания "чайниками".

А кто Вам сказал, что автор "чайник"? Или что писал для понимания "чайниками"? Он писал для программистов, которые умеют программировать, но не знаю что такое ПИД.

WADDAW
Offline
Зарегистрирован: 13.04.2019

Ну вообщето статья называется "ПИД-регуляторы - для чайников-практиков"

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Во-во - чайников в регулировании, а вовсе не в программировании.

SLKH
Offline
Зарегистрирован: 17.08.2015

WADDAW пишет:

ЕвгенийП пишет:

WADDAW пишет:
кажется код не на ардуино...
Почему Вам так кажется?

Предложенный код, после вставки его в новый скетч, не компилируется и выдает кучу ошибок. Необьявленные переменные непонятной размерности "enum PIDstep {ReceivingE, ComputeP, ComputeI, ComputeD, MakeAction};    // тип данных «итерация вычислений»" 

Непонятны структуры типа "struct Timer {...};     // структура для часов реального времени" 

Да и стиль приведенного кода не очень похож на тот который предлагают для понимания "чайниками". Сильно много сокращений специфичных для проффессионального кода, плохо раскрывающего саму суть вычислений и логику.

Ваш код с "float TempReal = 0" и  "TempPID_1 = TempReal", конечно, покруче будет...

WADDAW
Offline
Зарегистрирован: 13.04.2019

SLKH пишет:

Ваш код с "float TempReal = 0" и  "TempPID_1 = TempReal", конечно, покруче будет...

Я так понял сама идея работоспособности предложенного регулятора мало кого интересует... И дельных предложений маловато. Особенно по проверке регулятора в реальных условиях. Хотя в предложенном регуляторе присутствует и пропорционалная составляющая 

PID_T = (SetTempProdukt  - TempPID_1) * PID_Kt; // расчет пропорциональной составляющей

и интегральная составляющая с накоплением ошибки или смещением (кому как нравится)

PID_Out = PID_Out + PID_T - PID_D ;     // расчет выхода регулятора

и диференциалная составляющая с разностю температур предыдущего измерения и текущего измерения

PID_D = (TempPID_1 - TempPID_2) * PID_Kd;          // расчет диференциальной составляющей

То, что эти части применяются не так как в класическом описании, не значит что идея неработоспособна.

Код я привел как дополнение к пониманию идеи, которую изложил вначале и уточнил, что он может быль любой. Темболее, что это только часть кода по реализация регулирования, без обработки входных сигналов и прочей атрибутики. 

Я просил помощи в осмыслении идеи... Что-бы понимающие люди помогли мне и остальным понять, а стоит ли изобретать велосипед и будет ли он ездить, или пытаться кататься на уже изобретенном, но на котором треть кататься неможет, а треть катается с квадратными колесами. 

 

Pyotr
Offline
Зарегистрирован: 12.03.2014

Иногда для инерционных объектов применяю двухпозиционное регулирование и получаю приличный результат. 
Пример - температура в теплице поддерживается путем вкл/выкл котла. 
Измеряю среднюю Т за  1 мин. в тысячных градуса (мГрад)  Т_пред и Т_наст. Расчет состояния котла раз в мин.
Разность Т_наст-Т_пред = скорость изменения Т в мГрад/мин.
Считаю Т_будущ на 10-20 мин (время зависит от инерционности отопления и др.факторов) вперед с учетом Т_наст и скорости изменения.
Считаю Т_уставки на 10-20 мин вперед. Уставок несколько в течение суток и на каждый температурный период задается скорость изменения Т.
Тупо сравниваю Т_будущ и Т_уставки и вкл или выкл котел.
Например, Т стабильна, котел выкл, а через 15 мин должен начаться рост Т. Котел вкл заблаговременно и подтягивает график температуры к заданному.
Или вечером перед заходом солнца Т в теплице падает и котел нужно вкл примерно за 30-60 мин до того как Т упадет ниже заданной.