Страница 75 из 78 ПерваяПервая ... 25657374757677 ... ПоследняяПоследняя
Показано с 741 по 750 из 771

Тема: Обсуждение макросов для OWEN Logic

  1. #741

    По умолчанию

    Класс!!!!!

  2. #742
    Пользователь
    Регистрация
    01.04.2010
    Адрес
    Лыткарино
    Сообщений
    175

    По умолчанию

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

  3. #743

    По умолчанию

    Думаю, что в существующем виде это вполне законченный продукт - по-большому счёту GUI не требуется, т.к. в ходе работы и, особенно ПНР, в теле скрипта один раз заполняются исходные данные (входной и выходной файлы, название устройства), а потом просто кликом скрипт запускается, формируя обновлённый список тегов.

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

  4. #744

    По умолчанию

    Немного не закончил демонстрационную программу для 3-позиционного регулятора - хотел сделать FBD вариант и вместе их потестировать. Но время никак не выкрою... Может чуть позже завершу и заменю демку для этого объекта.

    При разработке регулятора актуальным остаётся вопрос проверки и отладки алгоритма до начала ПНР на объекте.

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

    Для регулятора с трёхпозиционным исполнительным механизмом собрать простой макет уже затруднительно.

    введение:
    Хорошую идею предлагают разработчики ПЛК Siemens S7-300 - библиотека этого ПЛК содержит три функциональных блока (ФБ) эмулятора объекта управления FB100, FB101 и FB102, соответственно для случаев непрерывного, трёхпозизионного и ШИМ управления исполнительным механизмом.
    Основой данных ФБ является FB100, на вход которого подаётся состояние выхода регулятора и производятся последующие вычисления. Для ФБ FB101 и FB102 состояния управляющих входов сначала преобразуются в положение регулирующего органа исполнительного механизма, а потом повторяются вычисления из FB100.

    Алгоритм FB100 эмулирует объект управления, который описывается тремя последовательно соединёнными апериодическими звеньями 1-го порядка. Общий коэффициент усиления позволяет сделать приведение выхода эмулятора к любым единицам измерения.

    С подробным описанием ФБ FB100, FB101 и FB102 можно ознакомиться в документации к ПЛК.

    Предлагаю самостоятельные реализации эмуляторов для среды разработки OwenLogic, появившиеся благодаря идеям FB100, FB101. Каждый из эмуляторов реализован в двух вариантах - на языках программирования ST и FBD, что связано с неравноценной реализацией отсчёта времени и возможностей вложения полученных ФБ в другие ФБ в среде Owen Logic.

    ЭМУЛЯТОР ОБЪЕКТА УПРАВЛЕНИЯ С "НЕПРЕРЫВНЫМ" УПРАВЛЕНИЕМ

    Структура эмулятора объекта управления с "непрерывным" регулированием показана на рисунке
    Схема Emulator_Cont_.png
    Для получения значения выхода эмулятора объекта нужно последовательно трижды найти численное решение дифференциального уравнения
    алгоритм решения дифференциального уравнения:
    Для вычисления значения выхода апериодического звена нужно интегрировать дифференциальное уравнение.

    Передаточная функция апериодического звена 1-го порядка в операторной форме

    W(p).PNG

    Уравнение в операторной форме

    DiffEqu_Laplas.PNG

    Дифференциальное уравнение

    DiffEqu.PNG

    DiffEqu_2.PNG

    Приняв начальные условия нулевыми и решая методом Эйлера получаем значение выхода на каждом цикле вычислений.
    Пусть длительность цикла равна h.

    EulerMethod.PNG

    Подставляя полученное значение y первого звена в качестве параметра x второго звена, и проведя аналогичные вычисления, сможем получить выход из второго звена. Аналогично получим выход из третьего звена.

    Реализация эмулятора с "непрерывным" управляющим входом
    на языке ST:
    Код:
    ///<Description>Эмулятор объекта управления. Эмулируется последовательное соединение трёх апериодических звеньев 1-го порядка.</Description>
    ///<Author>!!FPA!!</Author>
    ///<GroupName>Управляющие и регулирующие модули</GroupName>
    
    function_block Emulator_Cont_ST_
    
        var_input
            ///<Description>Перезапуск работы блока (инициализация всех переменных состояния) по фронту</Description>
            xReset: bool := false;
            ///<Description>Входная переменная. Управляющий сигнал с ПИД</Description>
            rVLV_Pos: real;
            ///<Description>Внешнее возмущающее воздействие (суммируется с rVLV_Pos для вычислений внутри ФБ)</Description>
            rDisturbance: REAL;
            ///<Description>Значение выхода при rVLV_Pos=0</Description>
            rPV_0: REAL:=20.0;
            ///<Description>Коэффициент передачи объекта управления (трёх последовательных апериодических звеньев 1-го порядка)</Description>
            rGain: REAL:=1.5;
            ///<Description>Постоянная времени первого апериодического звена 1-го порядка, [мс]</Description>
            dwTime_T1: udint:=60000;
            ///<Description>Постоянная времени второго апериодического звена 1-го порядка, [мс]</Description>
            dwTime_T2: udint:=10000;
            ///<Description>Постоянная времени третьего апериодического звена 1-го порядка, [мс]</Description>
            dwTime_T3: udint:=0;
        end_var
    
        var_output
            ///<Description>Выходное значение переменной процесса</Description>
            rPV: REAL;
        end_var
    
        var
            dwCurrent, dwCycle: udint;
            dwPrevious: udint := 0;
            bReset_previous: bool := false;
            rCycle: REAL;
            rT1: REAL;
            rT2: REAL;
            rT3: REAL;
            rPV_Prev1: real;
            rPV_Prev2: real;
            rPV_Prev3: real;
            rPV_Inner: real;
        end_var
    
        // вычисление длительности предыдущего цикла
        dwCurrent  := time_to_udint(get_time());
        dwCycle    := dwCurrent - dwPrevious;
        dwPrevious := dwCurrent;
        if (xReset and (not bReset_previous)) or (dwCycle = 0) then
            rPV_Prev1 := (rVLV_Pos + rDisturbance) * rGain;
            rPV_Prev2 := rPV_Prev1;
            rPV_Prev3 := rPV_Prev1;
            rPV := rPV_Prev1 + rPV_0;
        else
            rCycle  := udint_to_real(dwCycle);
            rT1 := udint_to_real(dwTime_T1);
            rT2 := udint_to_real(dwTime_T2);
            rT3 := udint_to_real(dwTime_T3);
    
            // вычисление выхода
            rPV_Inner := (rVLV_Pos + rDisturbance) * rGain;
            if rT1 >= rCycle then
                rPV_Inner := rPV_Prev1 + rCycle * (rPV_Inner - rPV_Prev1) / rT1;
                rPV_Prev1 := rPV_Inner;
            end_if;
            if rT2 >= rCycle then
                rPV_Inner := rPV_Prev2 + rCycle * (rPV_Inner - rPV_Prev2) / rT2;
                rPV_Prev2 := rPV_Inner;
            end_if;
            if rT3 >= rCycle then
                rPV_Inner := rPV_Prev3 + rCycle * (rPV_Inner - rPV_Prev3) / rT3;
                rPV_Prev3 := rPV_Inner;
            end_if;
            rPV := rPV_0 + rPV_Inner;
        end_if;
    
        bReset_previous := xReset;
    
    end_function_block

    на языке FBD:


    пример использования совместно с ФБ PID:


    ЭМУЛЯТОР ОБЪЕКТА УПРАВЛЕНИЯ С ТРЁХПОЗИЦИОННЫМ УПРАВЛЕНИЕМ

    ФБ будет состоять из двух частей: эмуляция привода с трёхпозиционным управлением (на вход которого поступают сигналы "открыть" и "закрыть", а выходе формируются сигналы положения регулирующего клапана и состояния концевых выключателей "открыт" и "закрыт") и эмуляция объекта управления с непрерывным управлением.

    Имеется возможность эмулировать неидеальный клапан - с отличающимися временами полного хода при открытии и закрытии, временами выборки люфта при открытии и закрытии.
    на языке ST:
    Код:
    ///<Description>Эмулятор объекта управления. Эмулируется последовательное соединение трёх апериодических звеньев 1-го порядка. Выходной параметр изменяется под воздействием трехпозиционного ПИД регулятора.</Description>
    ///<Author>!!FPA!!</Author>
    ///<GroupName>Управляющие и регулирующие модули</GroupName>
    
    function_block Emulator_3Pos_
    
        var_input
            ///<Description>Перезапуск работы блока (инициализация всех переменных состояния) по фронту</Description>
            xReset: bool := false;
            ///<Description>Сигнал Открыть</Description>
            xOpen: BOOL;
            ///<Description>Сигнал Закрыть</Description>
            xClose: BOOL;
            ///<Description>Время полного хода исполнительного устройства при открытии</Description>
            dwFullStroke_Open: udint:=30000;
            ///<Description>Время полного хода исполнительного устройства при закрытии</Description>
            dwFullStroke_Close: udint:=30000;
            ///<Description>Время выборки люфта исполнительного устройства при открытии</Description>
            dwVLV_Backlash_Open: udint := 0;
            ///<Description>Время выборки люфта исполнительного устройства при закрытии</Description>
            dwVLV_Backlash_Close: udint := 0;
            ///<Description>Верхний предел обратного сигнала клапана. Для клапана с контролем положения</Description>
            rVLV_Max: REAL:=100.0;
            ///<Description>Нижний предел обратного сигнала клапана. Для клапана с контролем положения</Description>
            rVLV_Min: REAL:=0.0;
            ///<Description>Внешнее возмущающее воздействие (суммируется с rVLV_Pos для вычислений внутри ФБ)</Description>
            rDisturbance: REAL;
            ///<Description>Значение выхода при rVLV_Pos=0</Description>
            rPV_0: REAL:=20.0;
            ///<Description>Коэффициент передачи объекта управления (трёх последовательных апериодических звеньев 1-го порядка)</Description>
            rGain: REAL:=1.5;
            ///<Description>Постоянная времени первого апериодического звена 1-го порядка, [мс]</Description>
            dwTime_T1: udint:=60000;
            ///<Description>Постоянная времени второго апериодического звена 1-го порядка, [мс]</Description>
            dwTime_T2: udint:=10000;
            ///<Description>Постоянная времени третьего апериодического звена 1-го порядка, [мс]</Description>
            dwTime_T3: udint:=0;
        end_var
    
        var_output
            ///<Description>Выходное значение переменной процесса</Description>
            rPV: REAL;
            ///<Description>Обратный сигнал клапана. Для клапана с контролем положения</Description>
            rVLV_Pos: REAL;
            ///<Description>Сигнал верхнего предела клапана</Description>
            bVLV_Opened: BOOL;
            ///<Description>Сигнал нижнего предела клапана</Description>
            bVLV_Closed: BOOL;
        end_var
    
        var
            dwCurrent, dwCycle: udint;
            dwPrevious: udint := 0;
            bReset_previous: bool := false;
            rCycle: REAL;
            rFullStroke_Open: REAL;
            rFullStroke_Close: REAL;
            rPos: real;
            rT1: REAL;
            rT2: REAL;
            rT3: REAL;
            h: real;
            rPV_Prev1: real;
            rPV_Prev2: real;
            rPV_Prev3: real;
            rPV_Inner: real;
            dwVLV_Backlash_Open_: udint;    // выбранная часть люфта при открытии
            dwVLV_Backlash_Close_: udint;   // выбранная часть люфта при закрытии
            dwRunTime: udint;               // часть времени dwCycle, потраченная на перемещение
        end_var
    
        // вычисление времени текущего цикла
        dwCurrent  := time_to_udint(get_time());
        dwCycle    := dwCurrent - dwPrevious;
        dwPrevious := dwCurrent;
        if (xReset and (not bReset_previous)) or (dwCycle = 0) then
            rPV_Prev1 := (rVLV_Pos - rVLV_Min + rDisturbance) * rGain;
            rPV_Prev2 := rPV_Prev1;
            rPV_Prev3 := rPV_Prev1;
            rPV := rPV_Prev1 + rPV_0;
            dwVLV_Backlash_Open_ := 0;
            dwVLV_Backlash_Close_ := 0;
        else
            // проверка ограничений диапазонов входных переменных
            if dwCycle <= 1 then
                dwCycle := 1;
            end_if;
            if dwFullStroke_Open < dwCycle then
                dwFullStroke_Open := dwCycle;
            end_if;
            if dwFullStroke_Close < dwCycle then
                dwFullStroke_Close := dwCycle;
            end_if;
    
            rCycle  := udint_to_real(dwCycle);
            rT1 := udint_to_real(dwTime_T1);
            rT2 := udint_to_real(dwTime_T2);
            rT3 := udint_to_real(dwTime_T3);
            rFullStroke_Open  := udint_to_real(dwFullStroke_Open);
            rFullStroke_Close := udint_to_real(dwFullStroke_Close);
    
            // обработка люфта - часть сигнала перемещения расходуется на компенсацию люфта
            dwRunTime := dwCycle;
            if xOpen then
                if dwRunTime <= dwVLV_Backlash_Close_ then
                    dwVLV_Backlash_Close_ := dwVLV_Backlash_Close_ - dwRunTime;
                else
                    dwVLV_Backlash_Close_ := 0;
                end_if;
                if dwVLV_Backlash_Open_ < dwVLV_Backlash_Open then
                    dwVLV_Backlash_Open_ := dwVLV_Backlash_Open_ + dwRunTime;
                    if dwVLV_Backlash_Open_ > dwVLV_Backlash_Open then
                        dwRunTime := dwVLV_Backlash_Open_ - dwVLV_Backlash_Open;
                        dwVLV_Backlash_Open_ := dwVLV_Backlash_Open;
                    else
                        dwRunTime := 0;
                    end_if;
                end_if;
            end_if;
            if xClose then
                if dwRunTime <=dwVLV_Backlash_Open_ then
                    dwVLV_Backlash_Open_ := dwVLV_Backlash_Open_ - dwRunTime;
                else
                    dwVLV_Backlash_Open_ := 0;
                end_if;
                if dwVLV_Backlash_Close_ < dwVLV_Backlash_Close then
                    dwVLV_Backlash_Close_ := dwVLV_Backlash_Close_ + dwRunTime;
                    if dwVLV_Backlash_Close_ > dwVLV_Backlash_Close then
                        dwRunTime := dwVLV_Backlash_Close_ - dwVLV_Backlash_Close;
                        dwVLV_Backlash_Close_ := dwVLV_Backlash_Close;
                    else
                        dwRunTime := 0;
                    end_if;
                end_if;
            end_if;
    
            // вычисление положения клапана, концевых переключателей
            h := (rVLV_Max - rVLV_Min) * udint_to_real(dwRunTime);
            if xOpen then
                rPos := rVLV_Pos + h / rFullStroke_Open;
            elsif xClose then
                rPos := rVLV_Pos - h / rFullStroke_Close;
            else
                rPos := rVLV_Pos;
            end_if;
            if rPos >= rVLV_Max then
                rPos := rVLV_Max;
                bVLV_Opened := true;
                bVLV_Closed := false;
            elsif rPos <= rVLV_Min then
                rPos := rVLV_Min;
                bVLV_Opened := false;
                bVLV_Closed := true;
            else
                bVLV_Opened := false;
                bVLV_Closed := false;
            end_if;
            rVLV_Pos := rPos;
    
            // вычисление выхода
            rPV_Inner := (rVLV_Pos - rVLV_Min + rDisturbance) * rGain;
            if dwTime_T1 >= dwCycle then
                rPV_Inner := rPV_Prev1 + rCycle * (rPV_Inner - rPV_Prev1) / rT1;
                rPV_Prev1 := rPV_Inner;
            end_if;
            if dwTime_T2 >= dwCycle then
                rPV_Inner := rPV_Prev2 + rCycle * (rPV_Inner - rPV_Prev2) / rT2;
                rPV_Prev2 := rPV_Inner;
            end_if;
            if dwTime_T3 >= dwCycle then
                rPV_Inner := rPV_Prev3 + rCycle * (rPV_Inner - rPV_Prev3) / rT3;
                rPV_Prev3 := rPV_Inner;
            end_if;
            rPV := rPV_0 + rPV_Inner;
        end_if;
    
        bReset_previous := xReset;
    
    end_function_block


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

    ЛИТЕРАТУРА

    1. Примеры программ для технологических функций. A5E00130042-01 (является частью документа 6ES7 398-8FA00-8AA0)
    https://www.siemens-ru.com/doc/Primeri_programm.pdf

    ПРИЛОЖЕНИЕ

    1. Демонстрационная программа работы эмулятора объекта с "непрерывным" управлением
    Test_Emu_Cont.owle

    2. Демонстрационная программа работы эмулятора объекта с "3-позиционным" управлением
    Test_EMU_3pos.owle
    Последний раз редактировалось FPavel; 06.02.2025 в 21:04. Причина: исправил эмулятор 3pos

  5. #745

    По умолчанию

    FPavel, здравствуйте!
    Воспользовался Вашим регулятором с трехпозиционным управлением, огромное спасибо!
    Проблема возникла, когда подал на вход уставки величину 3500. Ну и измеренную величину в том же масштабе. В итоге он регулировал без остановок.
    Внес в ФБ очень небольшую поправку, предлагаю на суд автора. Screenshot_11.png
    Последний раз редактировалось Юра54; 09.10.2024 в 07:52.

  6. #746

    По умолчанию

    Спасибо, за обратную связь!

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

    Почему-то думал, что именно абсолютное значение PV и SP не будет влиять на регулирование, ведь можно пропорционально уменьшить Kp и увеличить Ti.
    Если PV сильно зашумлён, то его можно дополнительно сгладить фильтром 1-го порядка (например, встроенным - свойства аналогового входа).
    Обычно, при настройке ПИД регулятора подбираю Kp, Ti, период пересчёта и постоянную фильтра аналогового сигнала - они все взаимосвязаны.

    Физический смысл полосы пропорциональности Xp = 1/Kp - величина невязки, при которой за счёт пропорциональной составляющей полностью откроется клапан. Брал его примерно как 3-4 допустимых диапазона отклонения при регулировании. Т.е. если при SP=3500 предполагается отклонения 50, то Xp=150-200 и Kp=1/200=0.005. Примерно, такой масштаб коэффициента Kp.

    Вечером попробую проверить работу ПИД с эмулятором на уставках со значением порядка 3500.

    В любом случае, спасибо - доработки означают, что Вы разобрались с логикой работы и по мере необходимости подстроите под конкретный случай.


    P.S. Не могу уяснить источник проблемы (автоколебаний) - ведь сам ПИД регулятор не работает с абсолютными значениями, а только с невязкой (E=SP-PV), т.е. "смещение" в 3500 и 10000 не должно оказывать влияние...
    Последний раз редактировалось FPavel; 09.10.2024 в 12:32.

  7. #747

    По умолчанию

    Цитата Сообщение от FPavel Посмотреть сообщение
    ...
    P.S. Не могу уяснить источник проблемы (автоколебаний) - ведь сам ПИД регулятор не работает с абсолютными значениями, а только с невязкой (E=SP-PV), т.е. "смещение" в 3500 и 10000 не должно оказывать влияние...
    Значения ошибки например между 35 и 37 и между 3500 и 3700 отличаются на два порядка. Для этого и предназначен коэффициент пропорциональности.
    А если сделать приведение сигналов к диапазону измерения датчика, то при замене на датчик с другим диапазоном придётся менять и коэффициент пропорциональности

  8. #748

    По умолчанию

    Проверил регулятор с уставкой 3500 вместе с эмулятором объекта.
    Эмулятор объекта:
    - время полного хода клапана 30 с,
    - люфт клапана равен 1 с в обоих направлениях
    - сам объект - апериодическое звено с постоянной времени 10 с, т.е. через 30 с от начала воздействия будет установлено стабильное состояние
    - выход объекта равен 0 при полностью закрытом клапане (rPV_0 = 0)
    - выход объекта равен 10000 при полностью открытом клапане (rGain = 100)
    - положение клапана измеряется в процентах (rVLV_Min = 0, rVLV_Max = 100)

    При Кп=0,0015, Ти=20000, Тм=5000 (время пересчёта), SP=3500, зоне=20 ПИД приводит объект к уставке, хотя и "подрабатывает" время от времени.
    И это даже без компенсации люфта в регуляторе.

    Т.е. всё-таки не могу принять, что регулятор не работает при уставках, сопоставимых с 3500.

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


    Единственно, захотелось добавить слагаемое - дифференциал по времени значения Кп. И вместе с опцией разрешения этого слагаемого, возможно, добавлю.
    Вложения Вложения

  9. #749

    По умолчанию

    UNIX_TIME + ПР100

    Проблема: в симуляторе и фактически не совпадают значение регистра (в примере 575-й).
    Ожидаемое значение: 47024
    Фактическое: -17786

    01.png

    Прибавление 2000, реализовано в макросе. +2000 на входе в макрос- такой же результат.
    Последний раз редактировалось Gena72; 10.10.2024 в 10:18.

  10. #750

    По умолчанию

    Цитата Сообщение от Gena72 Посмотреть сообщение
    UNIX_TIME + ПР100

    Проблема: в симуляторе и фактически не совпадают значение регистра (в примере 575-й).
    Ожидаемое значение: 47024
    Фактическое: -17786
    Проблема в том, что разные типы переменных, по разному отображают одни и те же числа, передаёте UINT, UDINT (целое без знака), а получаете типа INT, DINT (целое со знаком).
    Поменяйте тип в полученном.
    Последний раз редактировалось kondor3000; 10.10.2024 в 10:25.

Страница 75 из 78 ПерваяПервая ... 25657374757677 ... ПоследняяПоследняя

Похожие темы

  1. OWEN Logic v1.7
    от Евгений Сергеевич в разделе Среда программирования OWEN Logic
    Ответов: 404
    Последнее сообщение: 25.08.2020, 15:17
  2. OWEN Logic v1.7
    от Евгений Сергеевич в разделе Программируемые реле
    Ответов: 401
    Последнее сообщение: 28.07.2016, 19:46
  3. ПО OWEN Logic !!!
    от Ельцов Андрей в разделе Программируемые реле
    Ответов: 3
    Последнее сообщение: 11.10.2011, 15:33
  4. OWEN Logic 1.2.0.14b
    от Ельцов Андрей в разделе Программируемые реле
    Ответов: 40
    Последнее сообщение: 21.02.2011, 14:16
  5. OWEN Logic 1.1.0.11b
    от Ельцов Андрей в разделе Программируемые реле
    Ответов: 58
    Последнее сообщение: 12.10.2010, 20:55

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •