Как создавать блоки с помощью генератора кода на языке Си?

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

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

Чтобы ориентироваться в SimInTech, перед началом работы над задачей рекомендуется пройти упражнения, представленные в разделе справки poshagovoe_rukovodstvo.dita#.

Первым делом необходимо перенести на схему следующие блоки:

В рамках текущей задачи сгенерированный код будет применяться для создания нового блока в SimInTech, поэтому лучше использовать блоки Signaly/1021.dita# и Signaly/1020.dita#, которые осуществляют запись и считывание локальных сигналов модели или сигналов из базы данных. Однако, для демонстрации возможностей SimInTech в генерации кода и применении его, например, для стыковки с программным обеспечением контроллера, мы используем блоки Signaly/3001.dita# и Signaly/3002.dita#, которые при локальном моделировании эквивалентны константам.

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

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

После размещения на схеме вышеуказанных блоков схема должна принять следующий облик:

Рисунок 1. Первые блоки размещены на схеме

Сразу зададим свойства этих блоков. Для первого входного контакта укажем имя input:0, для второго – input:1». Имя выходного контакта – out:0. Обратите внимание на формат записи имен входных и выходных контактов. В своей схеме назовите контакты также.

Рисунок 2. Заданы имена входных и выходных контактов

Для входных контактов зададим в графе «Тип контакта» - «Float». Этим свойством мы определяем тип данных, который будет воспринимать блок.

В графе «Операция для нескольких контактов» зададим «Операция ИЛИ». Этим свойством мы определяем то, что блок векторный.

Так как блок должен обладать возможностью векторной обработки сигналов, то в строке «Значение по умолчанию» нужно указать начальное значение для каждого входного сигнала. Напишем в этой строке «10#0». Этой записью мы определяем размерность вектора на соответствующем входе – 10. При локальном моделировании блок будет выдавать на схему константу.

Ниже на рисунке (Рисунок 3) показаны свойства для первого блока «Входной контакт s3». Для второго блока свойства будут идентичными за исключением имени контакта.

Для выходного контакта кроме имени достаточно изменить лишь свойство «Операция для нескольких контактов» на «Копирование». Этим шагом мы также обеспечиваем возможность обработки векторных сигналов. Свойства блока «Выходной контакт s3» показаны на рисунке (Рисунок 4).

Рисунок 3. Свойства первого блока «Входной контакт s3»

Рисунок 4. Свойства второго блока «Входной контакт s3»

Следующим шагом будет обеспечение возможности задания свойств для каждого элемента ПИД-регулятора. К ним относятся:

Для удобства на схеме автоматики создадим отдельную субмодель, где эти свойства будут считываться из внешней целевой системы. Блок «Субмодель» находится в библиотеке «Субструктуры». Для красоты дополним добавленную субмодель подписью «Входные параметры».

Рисунок 5. Добавлен блок «Субмодель»

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

Первый входной контакт должен считывать извне коэффициент усиления для пропорциональной составляющей. Этот коэффициент будет являться свойством создаваемого блока. Поэтому в графе «Имя контакта» мы указываем следующее: Property:P. Этой записью мы обозначили, что данный блок типа «Входной контакт s3» будет считывать значение свойства создаваемого звена с именем «P».

Остальные блоки по аналогии назовем: Property:I, Property:I0, Property:D, Property:Td, Property:D0. Для каждого из этих блоков тип контакта задаем «Float», а в графе «Операция для нескольких контактов» указываем «Операция ИЛИ». Начальные условия для свойств Property:P, Property:I, Property:D, Property:Td назначим «10#1». Начальные условия для остальных свойств Property:I0, Property:D0 укажем 10#0.

Рисунок 6. Свойства блока

Также сразу давайте добавим на схему шесть элементов Substruktury/1008.dita# из библиотеки «Субструктуры». Эти элементы необходимы, чтобы не «засорять» схему линиями связи. В этом демонстрационном примере мы не будем останавливаться подробно на работе со стандартными блоками, такими как блок «В память». Статья предполагается для пользователей, которые уже в какой-то степени владеют SimInTech. Соединим соответствующие блоки линиями связи.

Рисунок 7. Содержание субмодели «Входные параметры»

Теперь вернемся на главное окно схемы, выполнив двойной щелчок мышью по пустому месту окна схемы. Из библиотеки «Операторы» перенесем на схему блок Operatory/0038.dita#. Этот блок является векторным и будет вычислять рассогласование между заданной извне уставкой и показанием датчика. Соединим элементы линиями связи.

Рисунок 8. Добавлен блок «Сравнивающее устройство»

На следующем этапе мы должны добавить на схему главные элементы – усилитель, интегратор и инерционно-дифференцирующее звено. Мы можем найти первый из этих элементов в библиотеке «Операторы». Отметим, что нас интересует векторный усилитель. Вторые два элемента можно найти в библиотеке «Динамические». Далее с помощью блоков Substruktury/1009.dita# и Substruktury/3016.dita# из библиотеки «Субструктуры», а также блока Operatory/0024.dita# из библиотеки «Операторы» мы можем связать заданные извне свойства элементов с этими блоками.

Рисунок 9. Схема ПИД-регулятора

Однако, такое построение схемы-шаблона имеет один существенный недостаток, связанный с заданием начальных условий для блоков Dinamicheskie/0027.dita# и Dinamicheskie/0032.dita#. Начальное условие – это свойство, которое используется только при инициализации модели. Поэтому в качестве начальных условий для вышеупомянутых блоков будут приняты величины, заданные в свойствах звеньев по умолчанию, а не те значения, которые мы задаем извне.

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

Если есть необходимость задавать начальные условия, то, во-первых, сгенерированный программой код на языке Си можно править, воспользовавшись соответствующей средой разработки. Во-вторых, среди стандартных блоков в SimInTech есть звено Dinamicheskie/0114.dita#, использование которого поможет решить появившуюся проблему.

Перенесем на схему еще три элемента «Субмодель». Сделаем подписи для каждой из добавленных субмоделей.

Рисунок 10. Добавлены субмодели для составляющих регулятора

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

Рисунок 11. «П» составляющая регулятора

Приступим к созданию интегрирующего элемента регулятора. Динамика этого звена описывается следующим уравнением:

где xi(t) – вектор входных сигналов, yi(t) – вектор выходных сигналов, ki – вектор коэффициентов усиления.

Для создания звена нам понадобятся следующие элементы:

Далее необходимо соединить данные блоки следующим образом (Рисунок 12). В результате имеем интегрирующее звено, работающее по стандартной схеме.

Рисунок 12. «И» составляющая регулятора

Осталось предусмотреть возможность задания начальных условий для интегрирующего звена. Начальные условия для интегратора будем задавать с помощью блока «Интегратор с изменяемыми н.у». Этот элемент работает по следующему алгоритму: как только управляющий сигал становится больше 0.5, значение, накопленное интегратором, сбрасывается, и на выход подается величина новых начальных условий.

Ненадолго вернемся к субмодели «Входные параметры». Здесь мы соберем небольшую схему, которая будет генерировать управляющий сигнал для интегратора. Переместите на схемное окно следующие блоки:

Схема должна в результате выглядеть следующим образом (Рисунок 13). Смысл этой схемы очевиден: пока модельное время меньше шага интегрирования (или равно ему), сигнал остается равным 1. Блок «Размножитель» для соответствия размерностей из одного управляющего сигнала делает десять. Поэтому для этого элемента в графе свойств «Коэффициенты размножения» указываем «10#1» или [1,1,1,1,1,1,1,1,1,1].

Рисунок 13. Создание сигнала для задания начальных условий

Вернемся к субмодели «И». Добавим на схему еще два блока «Из памяти». Далее необходимо соединить их с уже созданной схемой интегратора.

Рисунок 14. «И» составляющая регулятора с возможностью задания н.у.

Приступим к созданию «Д» составляющей ПИД-регулятора. Она представляет собой инерционно-дифференцирующее звено, динамика которого описывается следующим уравнением:

где xi(t) – вектор входных сигналов, yi(t) – вектор выходных сигналов, ki – вектор коэффициентов усиления, Ti – вектор постоянных времени.

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

Рисунок 15. «Д» составляющая регулятора

Осталось задать необходимые для приведения в соответствие размерностей свойства блоков. На этом создание «Д» составляющей регулятора окончено.

Перейдем на главное окно схемы. Добавим еще один блок – «Сумматор». Он необходим для сложения трех составляющих регулятора: «П», «И» и «Д». Выполним соединение всех блоков линиями связи.

Сохраняем нашу схему в созданной папке под именем «Схема-шаблон». Далее можем перейти к процессу генерации кода.

Рисунок 16. Схема-шаблон для генерации кода

Генерация кода

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

Для генерации кода существует набор подготовленных шаблонов, настроенных под различные компиляторы. В SimInTech реализовано несколько вариантов шаблонов генерации кода, предназначенных для разных аппаратных платформ и ОС. В их числе – генерация кода под Windows, Linux, QNX. С сайта http://www.sumintech.ru можно скачать набор инструментов MinGW для создания исполняемых файлов и библиотек под Windows. В нашем примере мы будем пользоваться именно этим набором инструментов.

Предварительно необходимо изменить имя схемы, так как созданный DLL-файл будет именоваться также. Для этого откройте «Параметры расчета» и в графе «Имя (имена) алгоритма» напишите «pid_dll».

Рисунок 17. Окно «Параметры расчета»

Открываем пункт главного меню «Кодогенератор». В появившемся списке выбираем «Кодогенератор Си». Заходим во вкладку «Настройки». В строке «Директория шаблона кода» нужно выбрать интересующий нас шаблон для кодогенерации. Как было сказано выше, это шаблон для создания DLL-файлов под Windows «MinGW». Поэтому в этой графе выберите «%codetemplates%MinGW_DLL\». Если вас интересует сборка с помощью компилятора от компании Microsoft, выберите «%codetemplates%VC2015\». Строку «Директория исходников» оставляем пустой для того, чтобы генерация кода осуществлялась в папку с нашей схемой-шаблоном. Теперь сохраняем конфигурацию под именем «Конфигурация кодогенератора», нажав по соответствующей кнопке во вкладке «Загрузка», в папку, где расположена схема-шаблон.

Рисунок 18. Настройка конфигурации кодогенератора

Приступаем непосредственно к генерации кода. Нажимаем «Инструменты», далее «Сгенерировать программу». Если в вашей версии программного обеспечения SimInTech отсутствует нужный компилятор, вы автоматически будете отправлены на сайт, где можете его скачать. После скачивания и установки компилятора (если это потребуется) повторите вышеописанное действие еще раз. В процессе генерации кода система отправила нам следующие уведомления:

Рисунок 19. Окно уведомлений

Как видно из рисунка (Рисунок 19), система информирует нас, что максимально допустимое количество блоков для нашей версии лицензии не достигнуто. Также система показывает, что генерации DLL-файла прошла успешно. Убедится в этом вы можете, зайдя в папку, где находится схема-шаблон. Там появился ряд новых файлов. Давайте коротко опишем, какой файл за что отвечает.

Подключение сгенерированного DLL-файла

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

Первым шагом станет создание новой схемы автоматики, в которой будем осуществлять загрузку DLL-файла.

Поместите на схему ее центральный элемент – блок 4_vneshnie_modeli/3063.dita# из библиотеки «Субструктуры».

Рисунок 20. Добавлен блок «Внешняя DLL»

Теперь необходимо корректно задать его свойства в соответствии с размерностями входов, выходов и свойств блока.

Блок должен иметь два входных порта, поэтому в графе «Количество портов» необходимо указать значение «2».

Выход должен быть один размерностью 10. В связи с этим в строке «Массив размерностей выходов» задаем «[10]».

В следующей графе «Имена загружаемых DLL» можно указать полный путь к DLL-файлу, а можно указать только его имя в случае, если данную схему мы сохраним с DLL-файлом в одной директории. Записываем в этой строке pid_dll.dll.

В строке «Имена файлов проектов для отладки» зададим «Схема-шаблон.prt». В данном случае также нет необходимости указывать полный путь к файлу. Это свойство в процессе работы модели поможет осуществить отладку созданной ранее схемы-шаблона. Для запуска отладчика в процессе моделирования выполните двойной щелчок по блоку «Внешняя DLL». Нажимаем «Ок».

Рисунок 21. Свойства блока «Внешняя DLL»

Во вкладке «Общие» изменим свойство «Тип элемента» на «ПИД». Этим действием мы подчеркнули, что создаем новый блок для SimInTech. Также изменим расположение портов входа. Первый вход оставим слева, а второй расположим снизу.

Рисунок 22. Изменено расположение портов

Рекомендуем изменить графическое изображения блока с помощью панели примитивов. Это делается во вкладке «Общие» в свойстве «Графическое изображение».

Рисунок 23. Изменено графическое изображение блока

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

Рисунок 24. Добавление новых свойств блока

Зададим входы блока. Из библиотеки «Векторные» расположим на схеме блок 1_avtomatika/Vektornye/0019.dita#. Количество портов укажем равным десяти. На некоторые из входов мультиплексора подадим, например, синусоиды из библиотеки «Источники» с разными значениями амплитуды: 1, 2, 3, 4, 5.

Рисунок 25. Задан первый вход блока

На выходе из ПИД-регулятора расположим блок Dinamicheskie/0027.dita# из библиотеки «Динамические», имитирующий простейший исполнительный механизм. При указании свойств интегратора не забудьте о десяти обрабатываемых сигналах.

Рисунок 26.

Из библиотеки «Данные» добавляем блок Vyvod_dannyh/1001.dita#. Также нам понадобится элемент Substruktury/3015.dita# из библиотеки «Субструктуры». Этот блок необходим для задания значений неподключенных портов (некоторые из портов мультиплексора остались неподключенными). Укажем уровень неподсоединенных портов равным нулю с помощью элемента Istochniki/0002.dita#. Соединим все элементы линиями связи.

Рисунок 27. Схема для проверки работы блока

Сохраняем схему в папку, где находится сгенерированный DLL-файл, под именем «Схема-загрузчик». В параметрах расчета ставим конечное время расчета – 100 секунд, максимальный шаг интегрирования уменьшим до 0.01 для повышения точности, а также включаем синхронизацию с реальным временем из вкладки с соответствующим именем. Запускаем модель на расчет. Открыв добавленный ранее график, можно убедиться в корректной работе регулятора.

Рисунок 28. График регулируемых величин

В процессе моделирования выполните двойной щелчок мышью по созданному блоку «ПИД». Откроется окно отладчика, где с помощью линий связи можно осущесвлять котроль работы сгенерированного DLL-файла, тем самым выполняя отладку схемы-шаблона (Рисунок 29).

Рисунок 29. Окно отладчика

Создание новой библиотеки блоков

В этой главе будет показан процесс создания новых библиотек и заполнения их блоками в SimInTech.

Первым делом для создания новой библиотеки нужно загрузить пустую библиотеку, на основе которой будем создавать свою собственную. Нажимаем «Файл», затем «Загрузить библиотеку». Выбираем пустую библиотеку под названием «ClassLib».

Теперь открываем редактор библиотеки нажатием по кнопке «Редактировать библиотеку» из пункта меню «Файл». После открытия редактора мы должны нажать по кнопке «Сохранить библиотеку в файл».

Рисунок 30. Редактор библиотеки

Как вы смогли заметить, все библиотеки хранятся в директории …\SimInTech\bin. Сохраняем библиотеку в эту же папку под именем «Regulators». Файлы библиотек имеют расширение «csl».

Теперь нужно сделать созданную только что библиотеку активной. Опять нажимаем «Загрузить библиотеку» и выбираем библиотеку «Regulators».

Далее необходимо загрузить библиотеку в рабочее пространство. Для этого укажите библиотеку в списке, который находится во вкладке «Библиотеки блоков». Данную вкладку можно найти в окне «Параметры» пункта меню «Файл». Нажимаем «Добавить», выбираем библиотеку «Regulators». Добавление библиотеки в этот перечень нужно для автозагрузки, если поменяется активная библиотека. В рамках текущей задачи достаточно сделать библиотеку активной.

Рисунок 31. Вкладка «Библиотеки блоков»

Осталось добавить созданное звено ПИД-регулятора в новую библиотеку. Но до этого давайте уделим немного внимания самому звену.

Во-первых, зададим свойство блока «Имя объекта» – «ПИД» (Рисунок 32).

Во-вторых, необходимо скрыть ненужные для использования блока в качестве регулятора свойства, такие как «Количество портов», «Массив размерностей выходов» и т.д. С этими свойствами мы больше работать не будем. Эта операция делается следующим образом: все ненужные свойства, а вернее их «Имя», через точку с запятой заносятся в графу «Список невидимых свойств». Таким образом, в графе «Список невидимых свойств» должна быть следующая запись: «nport; outdims; dllnames; componentnames; prjnames; useemptyvars; nthread;». В результате, вкладка «Свойства» ПИД-регулятора приняла вид, изображенный на рисунке (Рисунок 33).

Рисунок 32. Свойства объекта, вкладка «Общие»

Рисунок 33. Свойства объекта, вкладка «Свойства»

Теперь добавляем звено в библиотеку «Regulators». Для этого выделяем блок. Нажимаем по меню «Файл», далее «Сохранить в библиотеку». В появившемся окне задаем имя блока. Имя блока в библиотеке желательно задавать одинаковым с типом элемента (из свойств объекта).

Блок добавлен. Но в панели инструментов он еще не появился. Для этого опять заходим в «Редактировать библиотеку». Заметим, что там появился блок, имя которого мы задали «ПИД». В столбце «Страницы» нужно добавить новую запись. Нажимаем по кнопке «Добавить» и вводим имя страницы. Например, «Регуляторы».

Рисунок 34. Редактор библиотеки

Выделяем запись «ПИД» и нажимаем по зеленой стрелке, указывающей налево. Блок переместился в столбец «Записи страницы».

Открываем вкладку «Свойства записей». Там в строке «Группа» укажем «МВТУ». Этой записью мы определили, что библиотека будет отображаться только при разработке модели автоматики.

Осталось создать изображение бока для панели инструментов. Изображение должно представлять файл графического формата разрешением 32x32 пикселя. Добавляем графическое изображение, нажимаем «Ок».

Обращаем внимание, что в панели инструментов появилась новая библиотека «Регуляторы». В ней находится одно звено – «ПИД». Попробуйте добавить данное звено на схему.

Рисунок 35. Панель инструментов

На этом процесс создания нового элемента, а также новой библиотеки блоков для SimInTech с нуля закончен.