|
ПИД регулятор на ARM |
|
|
|
 |
Ответов
(1 - 58)
|
Jul 17 2008, 06:36
|
Участник

Группа: Свой
Сообщений: 45
Регистрация: 7-11-05
Пользователь №: 10 537

|
Цитата(kanzler @ Jul 17 2008, 08:02)  Господа! Прошу подсказать где можно взять программный модуль(на Си) ПИД регулятора под ARM? Под АРМ не нашла...  но есть вот такой вариант
Прикрепленные файлы
PID.zip ( 1.25 килобайт )
Кол-во скачиваний: 522
|
|
|
|
|
Jul 17 2008, 07:42
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(kanzler @ Jul 17 2008, 07:02)  Господа! Прошу подсказать где можно взять программный модуль(на Си) ПИД регулятора под ARM? Цитата Под АРМ не нашла... А чем собственно ПИД под АРМ отличается от ПИД под АВР? или PC? Тем более если на си? "Дайте мне, пожалуйста, глобус Украины" - вот это что напоминает. Сорри за офтоп. Не удержался.
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Jul 17 2008, 08:29
|
Участник

Группа: Свой
Сообщений: 45
Регистрация: 7-11-05
Пользователь №: 10 537

|
Продолжая оффтоп... А вы смайлики вообще правильно трактуете?  или вы их отключили?  И здерживайте всётаки себя, а то глупо смотриться... причем здесь разница между ПИД для АРМ и ПИД для АВР, написано же что пример реализации ПИД на Си есть в апноте для АВР, а не ПИД для АВР...
Сообщение отредактировал маша - Jul 17 2008, 08:35
|
|
|
|
|
Jul 17 2008, 15:47
|
Местный
  
Группа: Свой
Сообщений: 285
Регистрация: 5-11-05
Пользователь №: 10 491

|
Цитата(Dir @ Jul 17 2008, 13:46)  О, очень многим  При реализации алгоритма ПИД на ARM в подавляющем большинстве случаев можно вообще не заморачиваться эффектами насыщения интегрального терма. Работай в лоб с флоутами (и даже даблами) и в ус не дуй. Быстродействия хватает. Для AVR же приходится морочиться с целочисленной арифметикой, перекалибровками, следить за границами термов... В общем, ARMы для ПИДов зверски упрощают жизнь  Я считаю, что, наоборот, необходимо следить за границами, особенно интегральной части. Иначе это может привести к неприятным эффектам. ЗЫ: немного непонятно, что значит "морочится с целочисленной арифметикой"? Что за перекалибровки?
|
|
|
|
|
Jul 17 2008, 16:38
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата да и быстродействие нужно, с чем AVR вряд ли справиться Ну вообщем мы тут вывели формулу  2*Navr=Narm, где Navr - количество тактов AVR, Narm - количество тактов для ARM аналогичного кода (тестовым кодом был JPEG-кодер). А что у Вас за объект регулирования, что надо прямо за микросекунды его крутить?
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Jul 20 2008, 16:55
|

Местный
  
Группа: Свой
Сообщений: 201
Регистрация: 6-01-05
Пользователь №: 1 830

|
Цитата(SpyBot @ Jul 17 2008, 18:47)  Я считаю, что, наоборот, необходимо следить за границами, особенно интегральной части. Иначе это может привести к неприятным эффектам. ЗЫ: немного непонятно, что значит "морочится с целочисленной арифметикой"? Что за перекалибровки? Так все ж про него, про Аппнот Атмеля, который про ПИД. Вот какой он есть для AVR: http://atmel.com/dyn/resources/prod_documents/AVR221.ziphttp://atmel.com/dyn/resources/prod_documents/doc2558.pdfИ вот что от него остается для ARM: Код typedef struct { float fKp; float fKi; float fKd; float fLastProcessValue; float fSumError; float fMaxPID; float fMinPID; } PID_DATA; Код WORD ContrPID(float fSetPoint, float fProcessValue, PID_DATA *pid) { float fError, fPterm, fDterm, fIterm, fRet, fsError; fError = fSetPoint - fProcessValue; // Вычисление P-терма fPterm = pid->fKp * fError; // Вычисление D-терма fDterm = pid->fKd * (fProcessValue - pid->fLastProcessValue); pid->fLastProcessValue = fProcessValue; // Вычисление I-терма fsError = pid->fSumError + fError; fIterm = pid->fKi * fsError; // fRet = fPterm + fDterm + fIterm + pid->fMinPID; // if (fRet > pid->fMaxPID) return (WORD)(pid->fMaxPID); else if (fRet < pid->fMinPID) return (WORD)(pid->fMinPID); pid->fSumError = fsError; return (WORD)fRet; } Остается добавить инициализацию и ... фсе, можно использовать Конкретный пример: Код void FlowRatePID(void) { WORD U_reg; // вычисление нижней и верхней границы переменной регулирования PidDataFR.fMinPID = DELTA_LOWLIM + K_LOWLIM * fPin; PidDataFR.fMaxPID = DELTA_HIGHLIM + K_HIGHLIM * fPin; // вычисление коеффициентов Kp, Ki, Kd PidDataFR.fKp = fKpFR; PidDataFR.fKi = fKiFR; PidDataFR.fKd = fKdFR; // регулирование U_reg = ContrPID(fSetFlowRate, fFlowRate, &PidDataFR); setPWM_pr(U_reg); } Куда в реальной жизни может убежать интегральный терм, если он во флоуте? Или в дабле? Это в целом виде он может переполнить 16-битную разрядную сетку (AN221). PS. Пример реальный, но писался очень давно для регулирования скорости расхода газа (Flow Rate) регулятором на ARM по мотивам AN221. Тонкости уже подзабылись. PPS. "Для ARM" это я, конечно, говорю условно. Ничто не мешает его и на AVR запустить. Но вот что-то не много я знаю людей, которые на AVR свободно флоутами и даблами ворочают. Все боятся (и правильно!), что производительности не хватит...
|
|
|
|
|
Jul 20 2008, 17:43
|
Гуру
     
Группа: Модераторы
Сообщений: 8 752
Регистрация: 6-01-06
Пользователь №: 12 883

|
Цитата(Dir @ Jul 20 2008, 20:55)  Куда в реальной жизни может убежать интегральный терм, если он во флоуте? Или в дабле? Это в целом виде он может переполнить 16-битную разрядную сетку (AN221). PS. Пример реальный, но писался очень давно для регулирования скорости расхода газа (Flow Rate) регулятором на ARM по мотивам AN221. Тонкости уже подзабылись. Уважаемые господа! Я, лично, а может не только я... думаю, что с какой точностью и с какой разрядностью ни считай, интегральная часть не должна расти больше, чем нужно. иными словами, пока ошибка больше некоторой, должен работать пропорциональный и дифференциальный члены... (во время переходного процесса). Надо учитывать реальности объекта регулирования. При изменении задающего параметра его скорость нужно ограничивать или не трогать интегральный член... Тогда зашкала не будет. Правильный алгоритм и в целых числах будет нормально работать, переход на плавующую арифметику ничего не улучшит, а только иллюзию создаст.
|
|
|
|
|
Jul 20 2008, 18:01
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(Tanya @ Jul 20 2008, 20:43)  интегральная часть не должна расти больше, чем нужно. иными словами, пока ошибка больше некоторой, должен работать пропорциональный и дифференциальный члены... +1000  Люди,ау! Добавьте признак, что если имеется ограничение по выходу, то считаем интегральный терм. Для уверенности лучше микрочиповские аппликухи перечитать, раз на атмеловских такаядеталь проскочила.
|
|
|
|
|
Jul 20 2008, 18:09
|

Местный
  
Группа: Свой
Сообщений: 201
Регистрация: 6-01-05
Пользователь №: 1 830

|
Цитата(_Pasha @ Jul 20 2008, 21:01)  +1000  Люди,ау! Добавьте признак, что если имеется ограничение по выходу, то считаем интегральный терм. Для уверенности лучше микрочиповские аппликухи перечитать, раз на атмеловских такаядеталь проскочила. Какая деталь проскочила? Есть там в алгоритме ограничение интегрального терма (нижние и верхние границы регулировки)! Смотри хотя бы текст программы.
|
|
|
|
|
Jul 20 2008, 18:40
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(Dir @ Jul 20 2008, 21:09)  Какая деталь проскочила? Есть там в алгоритме ограничение интегрального терма (нижние и верхние границы регулировки)! Смотри хотя бы текст программы. Возвращаемся. Я про это: Цитата(Dir @ Jul 20 2008, 19:55)  И вот что от него остается для ARM: С исправлениями Код typedef struct { float fKp; float fKi; float fKd; float fLastProcessValue; float fLastOutput; // добавлено: последний ПИД float fSumError; float fMaxPID; float fMinPID; } PID_DATA; /********************************************************/ WORD ContrPID(float fSetPoint, float fProcessValue, PID_DATA *pid) { float fError, fPterm, fDterm, fIterm, fRet, fsError; fError = fSetPoint - fProcessValue; // Вычисление P-терма fPterm = pid->fKp * fError; // Вычисление D-терма fDterm = pid->fKd * (fProcessValue - pid->fLastProcessValue); pid->fLastProcessValue = fProcessValue;
// Вычисление I-терма /* накапливаем сумму для интегрального терма, если выход был в насыщении то считаем его, иначе сумма курит в сторонке и отражает медленные процессы, т.е. в конце концов ошибка изменит свой знак и скомпенсирует все, что складывалось до того */
pid->fSumError += fError;
if((pid->fLastOutput > pid->fMaxPID)||(pid->fLastOutput < pid->fMinPID )) { fIterm = pid->fKi * pid->fSumError; // посчитали } // выход fRet = fPterm + fDterm + fIterm + pid->fMinPID; // тоже непонятно, потому что должен быть pid->fOffset pid->fLastOutput = fRet; // запомнили выход для анализа его в следующий раз // if (fRet > pid->fMaxPID) return (WORD)(pid->fMaxPID); else if (fRet < pid->fMinPID) return (WORD)(pid->fMinPID); pid->fSumError = fsError; return (WORD)fRet; } Ясное дело, коряво немного, но с минимумом изменений. Кому надо, тот флаг Saturated добавит вместо плавучки  Исправил код еще раз.
|
|
|
|
|
Jul 20 2008, 19:52
|

Местный
  
Группа: Свой
Сообщений: 201
Регистрация: 6-01-05
Пользователь №: 1 830

|
Пока не рабирал, т.к. воскресенье и думать совсем лень, но вот это не понял сразу Цитата(_Pasha @ Jul 20 2008, 21:40)  /* накапливаем сумму для интегрального терма, если выход был в насыщении то считаем его, иначе сумма курит в сторонке и отражает медленные процессы, т.е. в конце концов ошибка изменит свой знак и скомпенсирует все, что складывалось до того */ Т.е. почему сумма изменит свой знак?
|
|
|
|
|
Jul 20 2008, 20:28
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Повторю, что сказала Таня, но своими словами. Выход регулятора имеет уровни ограничения - это понятно. Пока выход не ограничивается, нам интегральная часть не нужна Все-таки в коде ошибка, правильно так Код if((pid->fLastOutput > pid->fMaxPID)||(pid->fLastOutput < pid->fMinPID )) { fIterm = pid->fKi * pid->fSumError; // посчитали } else { fIterm = 0; } Как только выход в насыщении (ограничении), мы вспоминаем о сумме и интегральном терме. Получаеццо, выход в насыщении, а ошибка все равно есть. Девушко: Доктор, что мне делать, у меня прыщи и маленькая грудь... Доктор: Прыщи, маленькая грудь... Маленькая грудь, прыщи - это ж замкнутый круг какой-то... И вот наступает время, когда замкнутый круг наконец-то порвался, и ошибка (по модулю) начинает снижаться. Если же этого не происходит - то чума на голову такого регулятора. А выход все равно в ограничении. А потом наступает перерегулирование, и знак ошибки ужЕ поменялся, и у нас наконец-то выход не в ограничении. Забыли про интегральный терм. И т.д.
|
|
|
|
|
Jul 20 2008, 22:12
|

Местный
  
Группа: Свой
Сообщений: 201
Регистрация: 6-01-05
Пользователь №: 1 830

|
Дневная жара спала и наконец-то возратилась способность хоть как то соображать  Не оставляет ощущение, что мы говорим о разных регуляторах. Или совсем не понимаем друг друга. На эту мысль наводят слова: Цитата(_Pasha @ Jul 20 2008, 23:28)  Повторю, что сказала Таня, но своими словами. Выход регулятора имеет уровни ограничения - это понятно. Пока выход не ограничивается, нам интегральная часть не нужна Все-таки в коде ошибка, правильно так Код if((pid->fLastOutput > pid->fMaxPID)||(pid->fLastOutput < pid->fMinPID )) { fIterm = pid->fKi * pid->fSumError; // посчитали } else { fIterm = 0; } Недаром pid->fMaxPID восприняты как регулируемая величина. А на самом деле это регулирующее воздействие. Причем вместо выхода сумматора сравнение ведется с регулируемой величиной (хотя не возражаю, иногда работают и с выходом). Поэтому приведу расшифровку принятых обозначений. Структура PID_DATA: fKp, fKi, fKd - коэффициенты регулятора fLastProcessValue - последнее значение регулируемой величины fSumError - понятно fMinPID...fMaxPID - допустимый диапазон задания регулирующих воздействий Переменные функции ContrPID: fSetPoint - желаемое значение регулируемой величины fProcessValue - текущее значение регулируемой величины PID-регулятор классический. Т.е. все термы работают одновременно, а не так, что I-терм нужен только в режиме насыщения. Отсюда понятна формула, что регулирующее воздействие fRet равно сумме всех термов, которые считаем от 0, плюс pid->fMinPID - начальное регулирующее воздействие. fRet = fPterm + fDterm + fIterm + pid->fMinPID В случае достижения регулирующего воздействия максимальной величины fMaxPID или минимальной величины fMinPID происходит его ограничение на этом уровне. Поэтому ошибка регулирования в дальнейшем в случае приближения регулируемой величины к желаемому значению должна уменьшаться. ... И вот теперь, когда расставлены дефиниции, можно поговорить и о предмете Жду замечаний и возражений
|
|
|
|
|
Jul 20 2008, 22:46
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(Dir @ Jul 21 2008, 01:12)  Структура PID_DATA: fLastOutput - добавил от себя для реализации порожденного Татьяной замечания. Цитата PID-регулятор классический. Т.е. все термы работают одновременно, а не так, что I-терм нужен только в режиме насыщения. Вы ж понимаете, что они оба классические? Только имхо второй вариант имеет много больше применений. Ну да ладно. Пусть еще кто-нить рассудит А вот про то, что с fSumError в исходном варианте было неправильно, я думаю, Вы возражать не будете
|
|
|
|
|
Jul 21 2008, 05:02
|
Участник

Группа: Свой
Сообщений: 45
Регистрация: 7-11-05
Пользователь №: 10 537

|
Некоторые соображения по поводу ограничения интеграла... Код typedef struct { float fKp; float fKi; float fKd; float fLastProcessValue; float fI_term; float fMaxPID; float fMinPID; } PID_DATA; /********************************************************/ WORD ContrPID(float fSetPoint, float fProcessValue, PID_DATA *pid) { float fError, fPterm, fDterm, fIterm, fRet; fError = fSetPoint - fProcessValue; // Вычисление P-терма fPterm = pid->fKp * fError; // Вычисление D-терма fDterm = pid->fKd * (fProcessValue - pid->fLastProcessValue); pid->fLastProcessValue = fProcessValue;
// Вычисление I-терма fIterm = pid->fI_term + pid->fKi * fError;
// выход fRet = fPterm + fDterm + fIterm + pid->fMinPID;
if(fRet > pid->fMaxPID) { fRet = pid->fMaxPID; } if(fRet < pid->fMinPID ) { fRet = pid->fMinPID; } // Ограничение интеграла pid->fI_term = fRet - fPterm - fDterm - pid->fMinPID;
return (WORD)fRet; }
|
|
|
|
|
Jul 21 2008, 05:17
|

Местный
  
Группа: Свой
Сообщений: 201
Регистрация: 6-01-05
Пользователь №: 1 830

|
Цитата(_Pasha @ Jul 21 2008, 01:46)  fLastOutput - добавил от себя для реализации порожденного Татьяной замечания. Вы ж понимаете, что они оба классические? Только имхо второй вариант имеет много больше применений. Интересно услышать почему. Цитата(_Pasha @ Jul 21 2008, 01:46)  А вот про то, что с fSumError в исходном варианте было неправильно, я думаю, Вы возражать не будете Если речь про "мой" вариант, то буду. Нижняя и верхняя граница пределов задания управляющих воздействий (fMinPID, fMaxPID) выбирается с некоторым запасом меньше (больше) тех, что нужно для регулирования fProcessValue к уставкам fSetValue(min) и fSetValue(max). Это автоматом не позволяет интегральному терму бесконечно расти да еще и в направлении компенсации ошибки регулирования
|
|
|
|
|
Jul 21 2008, 06:18
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(маша @ Jul 21 2008, 08:02)  Некоторые соображения по поводу ограничения интеграла... Код // выход
//skipped
// Ограничение интеграла pid->fI_term = fRet - fPterm - fDterm - pid->fMinPID;
return (WORD)fRet; } Зачем в плавучке ограничение интеграла? Цитата(Dir @ Jul 21 2008, 08:17)  Если речь про "мой" вариант, то буду. Ну нельзя же так отжигать, право слово... Там нету накапливающего суммирования pid->fSumError не участвует как приемник данных ни в одном выражении
|
|
|
|
|
Jul 21 2008, 07:11
|
Гуру
     
Группа: Модераторы
Сообщений: 8 752
Регистрация: 6-01-06
Пользователь №: 12 883

|
Цитата(Dir @ Jul 20 2008, 21:53)  Не иллюзию создаст, а будет нормально работать. Вопрос в том стоит ли корпеть и вылизывать целочисленный алгоритм на AVR со множественными побочными явлениями и эффектами или за 5 минут наваять то же самое на ARM с плавучкой. А мне кажется, что иллюзии уже созданы. Проблема управления не есть задача программирования или электроники... Вот прикиньте - какова максимальная величина и минимальный квант управляющего воздействия. Разделим одно на другое и получим требуемую разрядность Интегрального Члена. Может разное получиться, но, обычно 16 бит хватит. Следует заметить, что в стационарном случае именно Интегральный член дает 95+ процентов управляющего воздействия (зависит от возмушений). Для Пропорционального и Дифференциального членов обычно хватает половинной разрядности. Но, пусть тоже будет 16 бит. Не вижу тут сложностей или потери быстродействия, - когда оно нужно - аналоговое управление. Для нестационарного случая - выход на стационарный режим - закон управления должен быть другой, если не хочется терять грубость (робастность).
|
|
|
|
|
Jul 21 2008, 12:00
|
Участник

Группа: Свой
Сообщений: 45
Регистрация: 7-11-05
Пользователь №: 10 537

|
Цитата(_Pasha @ Jul 21 2008, 10:18)  Зачем в плавучке ограничение интеграла? Ограничение интеграла - это алгоритмическое действие. И может применяться и в плавучке и в целых. В данном случае происходит не ограничение-замораживание интеграла, а его ограничение-коррекция.
|
|
|
|
|
Jul 21 2008, 19:45
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(маша @ Jul 21 2008, 15:00)  Ограничение интеграла - это алгоритмическое действие. И может применяться и в плавучке и в целых. В данном случае происходит не ограничение-замораживание интеграла, а его ограничение-коррекция. Нет, давайте, все-таки, поспорим. Я исхожу из 1. Нельзя объять необъятное, и ситуации, когда выход долго находится в насыщении, отслеживаются не ПИД, а тупо тайм-аутами, например, либо иным доступным способом. А ограничение интеграла в плавучке вызовет лишь видимость, что "все под контролем". И теряется "кумулятивный эффект" интегрального терма. 2. Другое дело целые числа. Здесь наскочить на арифметическое переполнение - легко. Поэтому для адекватности вычислений надо вводить ограничение, иначе - конопляные поля Галуа  Ждем-с контраргументов...
|
|
|
|
|
Jul 21 2008, 19:52
|

Местный
  
Группа: Свой
Сообщений: 201
Регистрация: 6-01-05
Пользователь №: 1 830

|
Цитата(_Pasha @ Jul 21 2008, 09:18)  Ну нельзя же так отжигать, право слово... Там нету накапливающего суммирования pid->fSumError не участвует как приемник данных ни в одном выражении Чето я вас не понимаю. Ну нет у моего процесса ограничения и насыщения как сверху так и снизу. Регулирование осуществляется в диапазоне значений. Поэтому и искусственно ограничивать интегральный терм смысла нет. Я же согласился с вами, что в "ваших" случаях при наличии ограничений это обязательно  Чего же вы пытаетесь найти несуществующую ошибку у меня. Просто вынимательнее рассмотрите программу и найдете то, чего так настойчиво не хотите видеть  Ну не работала бы она с ошибкой так долго
|
|
|
|
|
Jul 22 2008, 05:29
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(_Pasha @ Jul 21 2008, 23:45)  Нет, давайте, все-таки, поспорим. Давайте. Цитата(_Pasha @ Jul 21 2008, 23:45)  1. Нельзя объять необъятное Точно. Цитата(_Pasha @ Jul 21 2008, 23:45)  когда выход долго находится в насыщении, Интеграл интегрирует и интегрирует, интегрирует и интегрирует, интегрирует и интегрирует ... Представьте себе теперь, что будет когда рассогласование изменит знак (т.е. уже надо бы при пропорциональном воздействии менять знак на ШИМ на минус). Реакция будет через очень продолжительное время, т.к. долго будет списываться интеграл, а ШИМ будет стоять на максимуме, но со знаком плюс. Я это объясняю на пальцах для ясности. Прочувствовать влияние несогласоапнных ограничений можно моделированием. Результат. Сделали из устойчивой в малом замкнутой системы неустойчивую при больших воздействиях. Цитата(_Pasha @ Jul 21 2008, 23:45)  2. Другое дело целые числа. Здесь наскочить на арифметическое переполнение - легко. Поэтому для адекватности вычислений надо вводить ограничение, иначе - конопляные поля Галуа  Ждем-с контраргументов... Правильно. Но это только один аспект. Как же без функционально необходимых ограничений по ШИМ. Это, если хотите нормализация для правильной работы. ШИМ бесконечной разрядности в природе не существует.
|
|
|
|
|
Jul 22 2008, 05:38
|
Участник

Группа: Свой
Сообщений: 45
Регистрация: 7-11-05
Пользователь №: 10 537

|
Цитата(_Pasha @ Jul 21 2008, 23:45)  Нет, давайте, все-таки, поспорим. Я исхожу из 1. Нельзя объять необъятное, и ситуации, когда выход долго находится в насыщении, отслеживаются не ПИД, а тупо тайм-аутами, например, либо иным доступным способом. А ограничение интеграла в плавучке вызовет лишь видимость, что "все под контролем". И теряется "кумулятивный эффект" интегрального терма. 2. Другое дело целые числа. Здесь наскочить на арифметическое переполнение - легко. Поэтому для адекватности вычислений надо вводить ограничение, иначе - конопляные поля Галуа  Ждем-с контраргументов... 1. Про переполнение целых чисел здесь речь не идет (я не виду), дабы это просто необходимость нормальной работы самого математического аппарата целочисленного ПИД регулятора. 2. Я согласна, что вариант тайм-аутама, отслеживающего знак ошибки и последующим запрещением интегрирования должен быть. Но после смены знака изменения ошибки возможны переходные выбросы, которые скорее всего необходимо гасить алгоритмами безударного перехода, что приведет к затягиванию процесса. 3. А можно не просто запрещать интегрирование, а корректировать значение интеграла (или ввести дополнительную обратную связь по исполнительному устройству), если изменение ошибки сохраняет знак. Пример: дизель-генератор. Регулятор частоты тупо держит частоту, и нагрузка начинает ее давить. Тайм-аут отследил и заморозил интеграл, а частота продолжает падать...После уменьшения нагрузки (сменился знак изменения ошибки) регулятор продолжает "газовать" на том же уровне (разомкнут) , пока не сменится знак ошибки, а при этом дизель ускорится и улетит... А если интеграл корректировать, то после смены знака изменения ошибки, регулятор сразу вступит в работу. Сильно не бейте...
|
|
|
|
|
Jul 22 2008, 05:45
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(Dir @ Jul 21 2008, 23:52)  Я уже не знаю с кем спорю. Цитата(маша @ Jul 22 2008, 09:38)  3. А можно не просто запрещать интегрирование, а корректировать значение интеграла В обоих случаях стрктура ПИ регулятора изменяется на П. Насчет корректирования, наверное, имеется ввиду ограничение, иначе ничего не понятно.
|
|
|
|
|
Jul 22 2008, 06:19
|
Участник

Группа: Свой
Сообщений: 45
Регистрация: 7-11-05
Пользователь №: 10 537

|
Цитата(alexander55 @ Jul 22 2008, 09:45)  Насчет корректирования, наверное, имеется ввиду ограничение, иначе ничего не понятно. Кажется пора кондишн включать  Сама себя запутала... Корректирование - это ограничение интеграла при достижении выхода регулятора мин или макс значения, I = Umax(min) - P (- D). Вобщем мысль была такая: при ограничении интеграла по знаку ошибки, необходимо учитывать и величину ошибки... всё.
|
|
|
|
|
Jul 22 2008, 07:39
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(alexander55 @ Jul 22 2008, 08:29)  долго будет списываться интеграл, а ШИМ будет стоять на максимуме, но со знаком плюс. Результат. Сделали из устойчивой в малом замкнутой системы неустойчивую при больших воздействиях. В смысле - а ШИМ будет стоять на максимуме, но с противоположным знаком, стремиться вернуть домой отвязавшийся параметр. Обратите внимание, что необходимые запасы по динамическому диапазону воздействий закладываются изначально. Цитата(маша @ Jul 22 2008, 08:38)  Пример: дизель-генератор. В принципе, совершенно нормальный аргумент, но если сказать другими словами: Вышли из зоны регулирования - ПИД выключается - вошли обратно - ПИД включился. Мораль: спорим о разных вещах. Любая нелинейщина кроме ограничения по выходу и подключения интегратора - выделяется в отдельный функциональный блок.
|
|
|
|
|
Jul 22 2008, 08:44
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(_Pasha @ Jul 22 2008, 11:39)  В смысле - а ШИМ будет стоять на максимуме, но с противоположным знаком, стремиться вернуть домой отвязавшийся параметр. Нет. Для простоты и понимания процесса пока забудем про П состовляющую. ШИМ будет стоять на максимуме, т.к. интерграл глубоко в +. Рассогласование уже стало со знаком -, но интерграл долго еще будет выходить из +, т.к. он глубоко ушел в +. Соответственно и ШИМ гонит в +, хотя надо уже в -.
|
|
|
|
|
Jul 22 2008, 09:01
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(alexander55 @ Jul 22 2008, 12:44)  ШИМ будет стоять на максимуме, т.к. интерграл глубоко в +. Рассогласование уже стало со знаком -, но интерграл долго еще будет выходить из +, т.к. он глубоко ушел в +. Соответственно и ШИМ гонит в +, хотя надо уже в -. А про Д-составляющую чё-то забыли? Которая учитывает скорость изменения и "гасит" волновые процессы. Вообще при правильно настроенных коэффициентах обычно никаких велосипедов придумывать не надо. Чем проще, тем лучше. Слишком "интеллектуальная" система иногда ведёт себя неадекватно. Я недавно делал терморегулятор, наворотил там такого... режим начального прогрева, режим вывода на стационарный уровень, грубая подстройка, тонкая подстройка... ужос! Помучился месяц-другой, в результате всё переписал заново, осталось только 2 режима: прогрев с выходом в дельта-окрестность заданной температуры и собственно регулирование. И всё отлично работает!
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Jul 22 2008, 10:16
|
Гуру
     
Группа: Модераторы
Сообщений: 8 752
Регистрация: 6-01-06
Пользователь №: 12 883

|
Цитата(MrYuran @ Jul 22 2008, 13:01)  Я недавно делал терморегулятор, наворотил там такого... режим начального прогрева, режим вывода на стационарный уровень, грубая подстройка, тонкая подстройка... ужос! Помучился месяц-другой, в результате всё переписал заново, осталось только 2 режима: прогрев с выходом в дельта-окрестность заданной температуры и собственно регулирование. И всё отлично работает! Пример разумного подхода. К сожалению, имеется огромное количество "высоконаучных" статей по выбору коэффициентов, их автоматической настройке, сравнению переходных процессов в "стационаре". Там эти коэффициенты с большой точностью подбирают/рассчитывают (вот откуда желание перейти на плавующую точку...), добиваясь никому не нужных рекордов по минимизации отклонений для малых переходных процессов. В результате (на практике) можно получить очень плохую устойчивость при немалых отклонениях (помехах), если не менять алгоритм. А разумный подход состоит в том, что нужно ответить на главный вопрос - что должна обеспечить система управления. Еще замечу, что если есть некоторый (несколько неоптимальный в вышеупомянутом смысле) набор коэффициентов ПИДа, то примерно такую же переходную характеристику может дать другой набор параметров, которые отличаются процентов на 30, что косвенно свидетельствует о запасе грубости...
|
|
|
|
|
Jul 23 2008, 18:42
|
Местный
  
Группа: Свой
Сообщений: 285
Регистрация: 5-11-05
Пользователь №: 10 491

|
ИМХО против ограничения интегральной части выступают те, кто не работал с двигателями  Т.е. понятно, что при регулировке температуры или потока газа, ошибка будет минимальной и, видимо, беспокоится об интегральной части не нужно. Но в приводе двигателя, когда нагрузка может поменяться от минус фактически бесконечности  к плюс, интегральной части надо уделять самое пристальное внимание. Да и вобще не понятно - измеряем целыми числами, на выходе (тот же ШИМ) тоже целые, так зачем нам плавучка???  Цитата(маша @ Jul 22 2008, 10:19)  Вобщем мысль была такая: при ограничении интеграла по знаку ошибки, необходимо учитывать и величину ошибки... всё. На таком принципе удавалось сделать более-менее устойчивый И-регулятор
|
|
|
|
|
Jul 24 2008, 05:13
|
Участник

Группа: Свой
Сообщений: 45
Регистрация: 7-11-05
Пользователь №: 10 537

|
Еще как вариант неявного ограничения интеграла это применение селективного регулятора с одним основным регулятором (например частоты того же двигателя) и несколькими ограничительными (макс давления, макс температуры, темпов набора, сброса частоты, мин и макс частоты, макс подачи топлива и т.д. и т.п.). Выходы нескольких регуляторов проходят селекторы (мин/макс) и получается один, который в итоге и регулирует нужный параметр. интеграл выбранного регулятора присваивается всем остальным. Интеграл приэтом может насытится только если не наступают ограничения, тогда конечно нужно применять дополнительные меры по защите интеграла.
|
|
|
|
|
Jul 24 2008, 06:09
|

Местный
  
Группа: Свой
Сообщений: 201
Регистрация: 6-01-05
Пользователь №: 1 830

|
Цитата(SpyBot @ Jul 23 2008, 21:42)  ИМХО против ограничения интегральной части выступают те, кто не работал с двигателями  Т.е. понятно, что при регулировке температуры или потока газа, ошибка будет минимальной и, видимо, беспокоится об интегральной части не нужно. Но в приводе двигателя, когда нагрузка может поменяться от минус фактически бесконечности  к плюс, интегральной части надо уделять самое пристальное внимание. Да и вобще не понятно - измеряем целыми числами, на выходе (тот же ШИМ) тоже целые, так зачем нам плавучка???  Вообще то это я говорил, что делал регулятор для стабилизации потока и, наверное, должен ответить. Приведите пример бесконечно отрицательной и бесконечно положительной нагрузки, тогда я вам может и поверю. А так нагрузка либо есть, либо ее нет. Соответственно нельзя приложить бесконечное регулирующее воздействие любого знака, чтобы компенсировать возмущение. И, в конце концов, пояснит ли кто-нибуть чем конкретно не нравится простая и логичная операция из одной команды, которая не позволяет неограниченно расти интегральному терму, которое я привел в начале темы (топик 12): Код ... fError = fSetPoint - fProcessValue; ... fsError = pid->fSumError + fError; fIterm = pid->fKi * fsError; ... fRet = fPterm + fDterm + fIterm + pid->fMinPID; // if (fRet > pid->fMaxPID) return (WORD)(pid->fMaxPID); else if (fRet < pid->fMinPID) return (WORD)(pid->fMinPID); pid->fSumError = fsError; return (WORD)fRet; Т.е. сравнимаем полученное регулирующее воздействие (fRet) с границами регулирования (pid->fMinPID, pid->fMaxPID) и если оно выходит за эти границы, то интегральный терм (pid->fSumError) замораживается, т.к. просто программа не доходит до его обновления. Мы, фактически, выбором этих границ и регулируем наш I-терм. О каком пристальном внимании речь? И просьба пояснить чем плохо именно данное решение, а не приводить примеры, вводящие дополнительные ограничения I-терма. А насчет того, зачем тут плавучка я уже говорил: сравните текст программы в AVR221 в целочисленном виде и приведенный в топике 12 данной темы ее плавучий аналог и все станет ясно. Программа скукоживается в несколько раз, все внимание разработчика к процессу, а не к особенностям реализации в целых числах. Запасов производительности у ARMа, как правило, хватает. PS. Для профи это, конечно, не аргумент. Они оперируют понятиями "робастности" и т.п. У них свои критерии и свои объекты регулирования: атомные станции, ракетоносители, авиатехника... А что делать простым программистам и электронщикам у которых такая задача как, например, управление потоком CO2 или его температурой стоит раз в 3 года и занимает 0,01%. Утром поставили задачу и до обеда ждут решения в железе. Отлаживать целочисленку ни времени, ни аргументов не хватает.
|
|
|
|
|
Jul 24 2008, 06:10
|
Гуру
     
Группа: Модераторы
Сообщений: 8 752
Регистрация: 6-01-06
Пользователь №: 12 883

|
Цитата(SpyBot @ Jul 23 2008, 22:42)  ИМХО против ограничения интегральной части выступают те, кто не работал с двигателями  Т.е. понятно, что при регулировке температуры или потока газа, ошибка будет минимальной и, видимо, беспокоится об интегральной части не нужно. Но в приводе двигателя, когда нагрузка может поменяться от минус фактически бесконечности  к плюс, интегральной части надо уделять самое пристальное внимание. Да и вобще не понятно - измеряем целыми числами, на выходе (тот же ШИМ) тоже целые, так зачем нам плавучка???  На таком принципе удавалось сделать более-менее устойчивый И-регулятор  Математика - это искусство называть совершенно разные вещи одинаковыми словами... Уравнения могут быть такими же и для двигателя и для печки... А весь сыр-бор, как всегда, разгорелся из-за терминологических разногласий. Если ограничивать какой либо член в ПИД-регуляторе, то это уже не будет ПИД-регулятор...
|
|
|
|
|
Jul 24 2008, 07:46
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(Tanya @ Jul 24 2008, 10:10)  Если ограничивать какой либо член в ПИД-регуляторе, то это уже не будет ПИД-регулятор... Теория автоматического регулирования рассматривает все процессы при малых рассогласованиях и хорошо работает. Одна из стандартных входных воздействий - ступенька подразумевает не насыщение регуляторов, не вход ШИМ на ограничение, не ограничение энергетических показателей исполнительных двигателей и т.д. и т.п. Исследование нелинейных систем сводится только к расчету параметров возможного колебательного процесса качающейся замкнутой системы. Здесь САУ и ТАР заканчиваются и начинается моделирование и опыт. Понятно, что ограничение интегральной части в момент ограничение изменяет его структуру (пропадает интегральная часть, а точнее уменьшается коэффициент передачи интегральной части). В любой системе реально присутствуют нелинейности, а где-то они выходят на передний план. Задача сводится к тому, чтобы не вводить такие условия, при которых система устойчивая в малом становилась неустойчивой в большом. Извините, за наукообразность, но тут уже без этого никак. PS. Чего это меня в курилку не пускают, я там никого не обижаю. Странно.
|
|
|
|
|
Jul 24 2008, 08:23
|
Участник

Группа: Свой
Сообщений: 45
Регистрация: 7-11-05
Пользователь №: 10 537

|
Цитата(Dir @ Jul 24 2008, 10:09)  И, в конце концов, пояснит ли кто-нибуть чем конкретно не нравится простая и логичная операция из одной команды, которая не позволяет неограниченно расти интегральному терму Да куда же еще ему позволять расти интегральному терму, когда выход у вас уже в максимуме??? Это же равносильно ограничивать сам интеграл значениями fMaxPID и fMinPID, разница на П и Д составляющие небольшая и скорее всего не принципиальная. Это базовый вариант любого ПИД. Нужно решать проблему, когда при неизменной уставке знак ошибки сохраняется длительное время, а интеграл накапливается. Вскоре он дойдет конечно же до максимума или минимума значения выхода. Но что будет с самим объектом, выдержит ли он максимальное управляющее воздействие чтобы отрегулировать параметр, который ни в какую не хочет регулироваться? А может у вас есть еще методика расчета значений fMaxPID и fMinPID для всех режимов работы объекта? или это просто максимальное значения разрядности, например ШИМ?
|
|
|
|
|
Jul 24 2008, 19:32
|

Местный
  
Группа: Свой
Сообщений: 201
Регистрация: 6-01-05
Пользователь №: 1 830

|
Цитата(маша @ Jul 24 2008, 11:23)  А может у вас есть еще методика расчета значений fMaxPID и fMinPID для всех режимов работы объекта? или это просто максимальное значения разрядности, например ШИМ? Особой методики нет. Просто экспериментальным путем подбираю эти макс. и мин. значения ШИМ, чтобы регулируемая величина достаточно быстро доходила до минимума и максимума и при возврате назад в регулируемую область ощутимой задержки не было. Обычно 2...4 итераций хватает. Занимает времени меньше, чем подбор коэффициентов ПИД. А потом, как правило, пересчитываю параметры регулятора так, чтобы диапазон регулировки ШИМ был от 5 до 95% для всего диапазона выходных величин. PS. Пересчитывать или нет, переделывать или нет определяется чаще всего причинами, напрямую к регулированию касательства не имеющими.
|
|
|
|
|
Jul 25 2008, 04:58
|
Бывалый
    
Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615

|
Цитата(Dir @ Jul 24 2008, 23:32)  Особой методики нет. Пусть закон регулятора ПИ U[i]=Kп*X[i] + Ки*Sum(X[i]) Пусть Umax - модуль максимальной величины U[i] Sum_max=Umax/Ki - модуль максимального значения интегральной суммы, т.е. ограничения в (+) Sum_max, а в (-) -Sum_max. Не правда ли очень просто и ясно ?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|