реклама на сайте
подробности

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> ПИД регулятор на ARM
Dir
сообщение Jul 20 2008, 18:09
Сообщение #16


Местный
***

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



Цитата(_Pasha @ Jul 20 2008, 21:01) *
+1000
1111493779.gif
Люди,ау!
Добавьте признак, что если имеется ограничение по выходу, то считаем интегральный терм.
Для уверенности лучше микрочиповские аппликухи перечитать, раз на атмеловских такаядеталь проскочила.


Какая деталь проскочила? Есть там в алгоритме ограничение интегрального терма (нижние и верхние границы регулировки)! Смотри хотя бы текст программы.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jul 20 2008, 18:40
Сообщение #17


;
******

Группа: Участник
Сообщений: 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 добавит вместо плавучки smile.gif

Исправил код еще раз.
Go to the top of the page
 
+Quote Post
Dir
сообщение Jul 20 2008, 19:52
Сообщение #18


Местный
***

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



Пока не рабирал, т.к. воскресенье и думать совсем лень, но вот это не понял сразу

Цитата(_Pasha @ Jul 20 2008, 21:40) *
/*
накапливаем сумму для интегрального терма, если выход был в насыщении
то считаем его, иначе сумма курит в сторонке и отражает медленные процессы,
т.е. в конце концов ошибка изменит свой знак и скомпенсирует все, что складывалось до того
*/


Т.е. почему сумма изменит свой знак?
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jul 20 2008, 19:57
Сообщение #19


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Dir @ Jul 20 2008, 22:52) *
Т.е. почему сумма изменит свой знак?

biggrin.gif
Не сумма, а ошибка.
Go to the top of the page
 
+Quote Post
Dir
сообщение Jul 20 2008, 20:00
Сообщение #20


Местный
***

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



Цитата(_Pasha @ Jul 20 2008, 22:57) *
biggrin.gif
Не сумма, а ошибка.


// Ну пусть ошибка. Но почему она должна изменить знак?

Вопрос снимается. Туплю после пляжа и на такую жару. Да и в теме не был уже несколько лет. Но тем не менее фрагмент проги рабочий и фокусов за ней не замечено. Если жара отпустит, возможно на досуге вспомню прошлое wink.gif
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jul 20 2008, 20:28
Сообщение #21


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Повторю, что сказала Таня, но своими словами.
Выход регулятора имеет уровни ограничения - это понятно.
Пока выход не ограничивается, нам интегральная часть не нужна
Все-таки в коде ошибка, правильно так
Код
if((pid->fLastOutput > pid->fMaxPID)||(pid->fLastOutput < pid->fMinPID ))
{
   fIterm = pid->fKi * pid->fSumError; // посчитали
  }
   else
  {
    fIterm = 0;
  }


Как только выход в насыщении (ограничении), мы вспоминаем о сумме и интегральном терме.
Получаеццо, выход в насыщении, а ошибка все равно есть.

bb-offtopic.gif
Девушко: Доктор, что мне делать, у меня прыщи и маленькая грудь...
Доктор: Прыщи, маленькая грудь... Маленькая грудь, прыщи - это ж замкнутый круг какой-то...
bb-offtopic.gif

И вот наступает время, когда замкнутый круг наконец-то порвался, и ошибка (по модулю) начинает снижаться. Если же этого не происходит - то чума на голову такого регулятора. А выход все равно в ограничении. А потом наступает перерегулирование, и знак ошибки ужЕ поменялся, и у нас наконец-то выход не в ограничении. Забыли про интегральный терм.
И т.д.
Go to the top of the page
 
+Quote Post
Dir
сообщение Jul 20 2008, 22:12
Сообщение #22


Местный
***

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



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

Цитата(_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 происходит его ограничение на этом уровне. Поэтому ошибка регулирования в дальнейшем в случае приближения регулируемой величины к желаемому значению должна уменьшаться.

... И вот теперь, когда расставлены дефиниции, можно поговорить и о предмете smile.gif
Жду замечаний и возражений 1111493779.gif
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jul 20 2008, 22:46
Сообщение #23


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Dir @ Jul 21 2008, 01:12) *
Структура PID_DATA:

fLastOutput - добавил от себя для реализации порожденного Татьяной замечания.

Цитата
PID-регулятор классический. Т.е. все термы работают одновременно, а не так, что I-терм нужен только в режиме насыщения.


Вы ж понимаете, что они оба классические? Только имхо второй вариант имеет много больше применений. Ну да ладно. Пусть еще кто-нить рассудит

А вот про то, что с fSumError в исходном варианте было неправильно, я думаю, Вы возражать не будете
Go to the top of the page
 
+Quote Post
маша
сообщение Jul 21 2008, 05:02
Сообщение #24


Участник
*

Группа: Свой
Сообщений: 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;
}
Go to the top of the page
 
+Quote Post
Dir
сообщение Jul 21 2008, 05:17
Сообщение #25


Местный
***

Группа: Свой
Сообщений: 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). Это автоматом не позволяет интегральному терму бесконечно расти да еще и в направлении компенсации ошибки регулирования smile.gif
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jul 21 2008, 06:18
Сообщение #26


;
******

Группа: Участник
Сообщений: 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) *
Если речь про "мой" вариант, то буду.


Ну нельзя же так отжигать, право слово... lol.gif
Там нету накапливающего суммирования
pid->fSumError не участвует как приемник данных ни в одном выражении
Go to the top of the page
 
+Quote Post
alexander55
сообщение Jul 21 2008, 06:44
Сообщение #27


Бывалый
*****

Группа: Свой
Сообщений: 1 584
Регистрация: 7-08-07
Пользователь №: 29 615



Цитата(Dir @ Jul 17 2008, 13:46) *
О, очень многим smile.gif
При реализации алгоритма ПИД на ARM в подавляющем большинстве случаев можно вообще не заморачиваться эффектами насыщения интегрального терма.

Пардон, но надо включать токоограничение на уровне, соответствующем датчику тока (для 2 контурной системы) или максимальному коду ШИМ (для одноконтурной) и т.д.) , надо приводить ограничение интегральной состовляющей в соответствие ограничением регулятора.
Заморочки здесь функционально необходимы иначе бед не оберешься.
Go to the top of the page
 
+Quote Post
Tanya
сообщение Jul 21 2008, 07:11
Сообщение #28


Гуру
******

Группа: Модераторы
Сообщений: 8 752
Регистрация: 6-01-06
Пользователь №: 12 883



Цитата(Dir @ Jul 20 2008, 21:53) *
Не иллюзию создаст, а будет нормально работать. Вопрос в том стоит ли корпеть и вылизывать целочисленный алгоритм на AVR со множественными побочными явлениями и эффектами или за 5 минут наваять то же самое на ARM с плавучкой.

А мне кажется, что иллюзии уже созданы. Проблема управления не есть задача программирования или электроники...
Вот прикиньте - какова максимальная величина и минимальный квант управляющего воздействия. Разделим одно на другое и получим требуемую разрядность Интегрального Члена. Может разное получиться, но, обычно 16 бит хватит. Следует заметить, что в стационарном случае именно Интегральный член дает 95+ процентов управляющего воздействия (зависит от возмушений). Для Пропорционального и Дифференциального членов обычно хватает половинной разрядности. Но, пусть тоже будет 16 бит. Не вижу тут сложностей или потери быстродействия, - когда оно нужно - аналоговое управление.
Для нестационарного случая - выход на стационарный режим - закон управления должен быть другой, если не хочется терять грубость (робастность).
Go to the top of the page
 
+Quote Post
маша
сообщение Jul 21 2008, 12:00
Сообщение #29


Участник
*

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



Цитата(_Pasha @ Jul 21 2008, 10:18) *
Зачем в плавучке ограничение интеграла?

Ограничение интеграла - это алгоритмическое действие. И может применяться и в плавучке и в целых. В данном случае происходит не ограничение-замораживание интеграла, а его ограничение-коррекция.
Go to the top of the page
 
+Quote Post
Goofy
сообщение Jul 21 2008, 17:16
Сообщение #30


Частый гость
**

Группа: Свой
Сообщений: 169
Регистрация: 17-09-07
Из: Красноярск
Пользователь №: 30 600



Для того, чтобы регулятор функционаровал прогнозируемо есть смысл "заморочиться" как на ограничения с выхода регулятора, так и на ограничение интегральной части.
Гарантированно не случиться всяких гадостей вроде зависания или диких перерегулирований.
Это всё по опыту управления мех. объектами.
Дешёвые меры по сохранению робастости, ИМХО

можно погуглить
PID without Phd
Там есть пример программ, но так, псевдокодно.
Go to the top of the page
 
+Quote Post

4 страниц V  < 1 2 3 4 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd June 2025 - 03:35
Рейтинг@Mail.ru


Страница сгенерированна за 0.02703 секунд с 7
ELECTRONIX ©2004-2016