Конечные автоматы в среде динамического моделирования SimInTech. Часть 3. Переходим к коду Си
В этой части будет показано как из SimInTech сгенерировать код Си, реализующий программу управления на основе логики «конечных автоматов», а потом отдалить в MS Visual Studio 2015 совместно с моделью объекта в SimInTech.
Созданный на предыдущем этапе алгоритм управления на базе логики конечных автоматов в среде SimInTech может быть автоматически преобразован в код Си, готовый к загрузке в контроллер. Контроллера у меня нет под рукой, поэтому в данном примере мы просто соберем dll из созданного кода. В данной части мы разберем основные шаги по подготовки модели и генерации кода Си из среды SimInTech.
Сохраните проект созданный на предыдущей стадии под именем Нагреватель.prt
Для создания кода Си необходимо разделить нашу общую модель на модель объекта и модель системы управления. Поскольку на первом этапе мы упаковали модель управления в субструктуру «Контроллер нагревателя», нам достаточно вынести данную структуру в отдельный проект.
Создайте новый проект с именем «Контроллер_dll» и сохраните его в той же директории. Потом скопируйте в него блок «Контроллер нагревателя».
Для создания внешней программы в SimInTech необходимо использовать специальные блоки входа — выхода. Эти блоки «входной контакт S3» и «выходной контакт S3» расположены в закладке «Данные» (см. Рис. 45 — 46).
Рисунок 45. Блок входной контакт S3.
Рисунок 46. Блок выходной контакт S3.
Разместите на схеме два блока «входной контакт S3» и два блока «выходной контакт S3» и соедините с блоком «Контроллер нагревателя». Вид схемы приведен на рисунке 47.
Рисунок 47. Схема алгоритмов контроллера нагревателя в отдельном проекте.
Для настройки входов войдите в свойства блоков (двойной клик на блоке) и настройте параметры входных портов следующим образом:
«Имя контакта» — input:0 для первого блока и input:1 для второго блока
«Тип контакта» — Float (см. Рисунок 48)
Рисунок 48. Настройка входного сигнала в программу.
Для настройки выходов войдите в свойства блоков и настройте параметры выходных портов следующим образом:
«Имя контакта» — out:0 для первого блока и out:1 для второго блока
«Тип контакта» — Float (см. Рисунок 49)
Рисунок 49. Настройка сигналов выходов из программы управления.
Для настройки имени программы или динамической библиотеки нажмите кнопку «Параметры расчета» на схемном окне. В появившемся диалоговом окне задайте имя будущей программы. В параметре «Имя (имена) алгоритмов» укажите controller_dll. (см. рис. 50)
Рисунок 50. Настройка имени программы.
Сохраните проект под именем контроллер_dll.prt.
Перейдем к настройке процесса генерации кода. В главном меню программы выберите пункт «Кодогенератор». В диалоговом окне перейдите на закладку «Настройки» и выберите директорию кода шаблона »%codetemplates%VC2015\» (см. рис. 51)
Рисунок 51. Настройка шаблона генерации кода.
Для генерации кода существует набор подготовленных шаблонов, настроенных под различные компиляторы. Разработчики SimInTech предлагают несколько вариантов шаблонов генерации кода, предназначенных для разных аппаратных платформ и ОС. В их числе — генерация кода под Windows, Linux, QNX. С сайта разработчиков можно скачать набор инструментов MinGW для создания исполняемых файлов и библиотек по Windows.
В данном примере мы будем использовать шаблон для компилятора Visual Studio 2015. Для работы достаточно бесплатной («коммунистической») версии данной программы. Версию Visual Studio Community 2015 можно скачать с официального сайта beta.visualstudio.com/ru
Основной текст программы создается в виде чистого Си кода, соответствующего стандарту ANSI. Этот текст размещается в заранее подготовленный шаблон для различных компиляторов.
Для генерации кода в главном меню программы выберите пункт «Инструменты» и подпункт «Сгенерировать программу». При выборе этого пункта в нижней части схемного окна появится сообщение об ошибке. Двойной клик на строку ошибки приводит к переходу на субмодель, в которой произошла ошибка, и происходит выделение блока, для которого не может быть сгенерирован программный код (см. рисунок 52).
Рисунок 52. Сообщение об ошибке и выделение блока с ошибкой.
В данном случае ошибка связана с тем, что в общем проекте мы использовали глобальный сигнал flash_time для изменения времени срабатывания перехода из состояния включен в состояние выключен и обратно. После переноса части схемы в новый проект, где данного сигнала нет, SimInTech показывает ошибку. Исправляется данная ошибка путем создания данного сигнала в новом проекте. В главном меню SimInTech выберите в пункте «Сервис» подменю «Сигналы» (см рис. 53)
Рисунок 53. Вызов настройки сигналов проекта.
Создайте новый сигнал (кнопка «добавить» внизу окна), задайте имя flash_time. Режим установите в «Ненаправленный» и задайте значение по умолчанию — 5 (см. рис. 54)
Рисунок 54. Добавление сигнала проекта.
Закройте диалоговое окно кнопкой «ОК» и повторите процесс генерации кода: в главном меню программы выберете в пункте «Инструменты» подпункт «Сгенерировать программу».
Если среда Visual Studio Community 2015 у вас установлена правильно, то в окне сообщений схемы появится соответствующий текст (см. рис. 55):
Рисунок 55. Окно сообщений о проекте.
[Ошибка]: «Модуль генерации кода не зарегистрирован. Максимальное допустимое количество блоков для схемы: 200»
[Ошибка]: «Количество блоков в проекте: 56»
Первые две строки сообщений информируют об ошибке — незарегистрированном модуле генерации кода. В незарегистрированном виде модуль позволяет генерировать код для схем, количество блоков которых не превышает 200. Наш проект содержит 56 блоков, поэтому происходит генерация кода, несмотря на сообщения об ошибках.
[Информация]: «Исходный текст сохранён в c:\simintech\demo\automatic\Карты состояний — state flow\Контроллер нагревателя\controller_dll.inc»
[Информация]: «Секция состояний сохранена в c:\simintech\demo\automatic\Карты состояний — state flow\Контроллер нагревателя\controller_dll_state.inc»
[Информация]: «Заголовок сохранён в c:\simintech\demo\automatic\Карты состояний — state flow\Контроллер нагревателя\controller_dll.h»
[Информация]: «Заголовок сохранён в c:\simintech\demo\automatic\Карты состояний — state flow\Контроллер нагревателя\controller_dll_init.inc»
[Информация]: «Исходные тексты программы сгенерированы»
Следующие сообщения информируют пользователя о создании файлов исходных кодов и указывается, где они расположены. Если иное не указано специально в настройках кодогенератора, то файлы сохраняются в той же директории, где мы сохранили проект.
[Информация]: «Используется шаблон кода C:\SimInTech\bin\CodeTemplates\VC2015\»
[Информация]: «Запуск сборочного скрипта compile.bat «c:\simintech\demo\automatic\Карты состояний — state flow\Контроллер нагревателя\controller_dll» 192.168.1.1 root root»
Далее SimInTech сообщает, какой шаблон кода используется (в какой директории он находится).
Последняя строка сообщает, что запущен скрипт сборки controller_dll. Если программа Visual Studio 2015 установлена и настроена правильно, то, открыв проводник, мы увидим, что все файлы находятся в той же папке, где и исходный проект. (см. Рис. 56)
Рисунок 56. Файлы созданные генератором кода и компилятором.
Вызов созданной dll из проекта
Откройте исходный проект (мы его сохраняли под именем Нагреватель.prt) и сохраните его под именем Нагреватель_загрузчик.prt Этот проект мы будем использовать для тестирования кода, созданного средой SimInTech.
Удалите блок «Контроллер нагревателя» и разместите на его месте блок «Внешняя DLL» из закладки «Субструкутуры» (см. рис. 57).
Рисунок 57. Настройка проекта для тестирования dll.
По умолчанию данный блок не содержит портов входа и выхода. Для настройки данного блока выполните двойной щелчок на блоке и в свойствах блока задайте следующие параметры (см. рис 58):
- Количество портов — 2 (Количество входных портов).
- Массив размерностей выходов — [1,1] (Для выходных портов нужно указать размерности каждого, у нас в модели два порта с 1 сигналом).
- Имена загружаемых DLL — controller_dll.dll — имя файла которое мы задавали при генерации кода (см. рис. 50).
- Имена файлов проектов для отладки — Контроллер_dll.prt — имя файла проекта, под которым мы сохранили схему для генерации dll.
Рисунок 58. Настройка свойств блока «Внешняя dll»
Закройте окно нажатием кнопки «ОК», после этого на схеме у блока «Внешняя DLL» появились порты, аналогичные портам удаленного блока «Контроллер нагревателя». Соедините схему, как показано на рисунке 59.
Рисунок 59. Схема нагревателя для тестирования dll.
После этого можно запустить проект на расчет и посмотреть, как работает собранный в dll код.
Ранее мы указали в свойствах блока «Внешняя DLL» имя проекта, из которого был сгенерирован код, и теперь, во время моделирования, по двойному клику на изображении блока «Внешняя DLL», откроется окно проекта, из которого был сгенерирован кода и можно будет наблюдать работу кода в dll. (cм. Рис. 60).
Рисунок 60. Отображение на схеме работы dll.
Графики расчета модели приведены на рисунке 61. На графиках видно, что температура падает в момент выключения и растет в момент нагрева. Так же видно, что режим работы соответствует модели конечных автоматов, созданных на первой стадии. Сначала 40 секунд нагреватель выключен и температура снижается со скоростью охлаждения, далее 20 секунд включён и температура повышается со скоростью нагрева. И далее цикл повторяется
Но индикатор работает не так, как планировалось. Индикатор верно показывает состояние, однако частота переключения не меняется. Очевидно, что есть проблемы со свойством flash_time у блоков моделирования работы индикатора (см. рис. 61)
Рисунок 61. Графики работы нагревателя с контроллером из dll.
Особенности генерации кода Си в SimInTech
Обнаруженное несоответствие работы кода и исходной модели связано с особенностями кодогенератора. В среде SimInTech в режиме моделирования любое свойство может быть задано как переменная и рассчитано с использованием скриптового языка, что мы и сделали при создании конечного автомата, управляющего индикацией. Во время моделирования возможно любое изменение свойств блока. Математическое ядро SimInTech учитывает это в процессе сортировки блоков и в процессе расчета. Схема работы блока «Выдержка состояния» в среде SimInTech приведена на рисунке 62.
Рисунок 62. Схема работы блока «Выдержка состояния» в среде SimInTech.
Возможность изменения параметров «на ходу», во время моделирования, значительно повышает гибкость системы, позволяет производить подбор параметров блока средствами оптимизации SimInTech, а так же производить настройку регуляторов.
При создании кода Си необходимо иметь однозначное соответствие между входами и выходами блока при заданных параметрах. При генерации кода Си возможность изменять параметры приводит к возникновению неопределенности с формированием кода, в котором должно быть четкое разделение между входными величинами, свойствами блоков и результатом вычислений функции блока. Для устранения этой неопределённости все свойства блока при генерации кода преобразуются в константы. Схема работы блока «Выдержка состояния» в коде Си приведена на рисунке 63.
Рисунок 63. Схема работы блока «Выдержка состояния» в коде Си
Чтобы изменять свойства блок при работе в коде Си необходимо явно указать, что сигнал flash_time изменяется в ходе работы кода. В этом случае для генератора кода данное свойство превращается в обычный вход и неопределённость со свойствами блока снимается. Схема работы блока «Выдержка состояния» будет выглядеть так, как представлено на рисунке 64.
Рисунок 64. Схема работы блока с переменным временем выдержки в коде Си.
Давайте исправим наш контроллер с учетом вышеизложенных особенностей генерации кода Си в SimInTech.
Откройте проект Контроллер_ dll.prt, перейдите двойным кликом в субмодель «Контроллер нагревателя», далее в состояние выключен и удалите из схемы блок «Язык программирования». Поместите на схему блок «Запись в список сигналов» из закладки «Данные» (см. Рис. 65)
Рисунок 65. Схема состояния «выключен» после исправления.
В свойствах блока «Запись в список сигналов» укажите имя сигнала — flash_time. (см. рис. 66)
Рисунок 66. Свойства блока «Запись в список сигналов»
Повторите данную процедуру для состояния включен. Можно скопировать два блока «Константа» и «Запись в список сигналов» и вставить в блоке состояния включен. На вход в блок подайте константу 1 (время переключения в режиме нагрева). Схема блока состояния включен должна выглядеть, как показано на рисунке 67.
Рисунок 67. Схема работы в состоянии включен.
Таким образом мы явно указали, что хотим менять сигнал из схемы состояния при генерации кода.
Перейдем к настройке конечного автомата индикации. Войдите в субмодель автомата индикации, и далее — в состояние выключен. Удалите блок «Выдержка состояния» и установите на его место блок «Переменная выдержка состояния» из закладки «Конечные автоматы».
Поместите также на схему блок «Чтение из списка сигналов» из закладки «Данные». Установите в качестве имени сигнала flash_time. Схема должна выглядеть, как показано на рисунке 68.
Рисунок 68. Схема состояния включен в автомате работы таймера.
Повторите то же самое для состояния выключен. Схема должна выглядеть так, как показано на рисунке 69.
Рисунок 69. Схема состояния выключен.
Таким образом, мы явно указываем генератору кода, что хотим менять значение времени выдержки в состоянии (интервал мигания индикатора). Сохраните проект.
Повторите процесс генерации кода. В главном меню программы выберите в пункте «Инструменты» подпункт «Сгенерировать программу». Если вы выполнили все по инструкции выше, то у вас будет сформирована dll, созданная из кода Си.
Откройте проект Нагреватель_загрузчик_dll. Запустите проект на расчет и убедитесь, что теперь автомат индикации работает правильно и меняет частоту индикации в зависимости от режима. (cм. Рис. 70)
Рисунок 70. Работа нагревателя с контроллером из dll.
Совместная отладка в Visual Studio 2015 и SimInTech
По умолчанию среда SimInTech настроена таким образом, что процесс создания программ из схемы полностью автоматизирован. Пользователю не нужно править текст программы на Си. Пользователь получает программу из схемы, готовую к загрузке в контроллер, либо в виде dll. В приведенном ранее примере показано как создавать программы, не редактируя код.
Однако, возможны ситуации, когда необходимо одновременно отлаживать код Си и использовать SimInTech для тестирования этого кода. Далее мы покажем как настроить Visual Studio 2015 для ручной правки кода Си с тестированием в среде SimInTech.
Для автоматизации генерации кода и создания программ среда SimInTech использует предварительно настроенные шаблоны для разных компиляторов и сред разработки. В нашем примере мы использовали шаблон Visual Studio 2015, который расположен в папке:
C:\SimInTech\bin\CodeTemplates\VC2015
В данной папке расположены файлы командного запуска, которые и обеспечивают полностью автоматизированную сборку библиотек. При генерации кода файлы с кодом помещаются как в директорию проекта (или другую, указанную пользователем при настройке), так и в директорию шаблона. Имена в папке проекта соответствуют имени программы в настройках кода генерации. Имена файлов в папке шаблона фиксированные, а файлы перезаписываются при генерации разных проектов в SimInTech.
Соответствие между файлами в паке шаблона и папке проекта для контроллера нагревателя приведено в следующей таблице:
Для отладки и ручной правки исходного кода необходимо перенести папку C:\SimInTech\bin\CodeTemplates\VC2015\src в рабочую директорию проекта. Для нашего примера выполните следующие действия:
- Скопируйте C:\SimInTech\bin\CodeTemplates\VC2015\src в папку, в которой находится проект Контроллер нагревателя (у меня это C:\SimInTech\Demo\Контроллер нагревателя).
- Откройте файл проекта Visual Studio 2015 example_cpp.vcxproj, расположенный в директории C:\SimInTech\Demo\Контроллер нагревателя\src в среде Visual Studio.
- В настройках проекта укажите пути к рабочим директориям. Для этого: в окне «Solution Explorer», выделите файл example_cpp и нажмите кнопку «Properties». В диалоговом окне настроек укажите в качестве «Output Directory» рабочую директорию, где находится проект с вызовом dll. (В нашем примере рабочая директория находится на уровень выше директории с исходными файлами). Имя создаваемой dll «Target Name» — controller_dll, расширение создаваемого файла — dll. (см. рис. 71)
Рисунок 71. Настройка рабочих директорий отладки - Перейдите в раздел «Debugging» и настройте вызов среды SimInTech:
- «Command» — C:\SimInTech\bin\mmain.exe — имя исполняемого файла программы.
- «Command Arguments» — «C:\SimInTech\Demo\Контроллер нагревателя\Нагреватель_загрузчик_dll.prt» — имя проекта с вызовом отлаживаемой dll.
- «Working Directory» — C:\SimInTech\Demo\Контроллер нагревателя\ рабочая директория, в которой у нас находится проект и отлаживаемая dll (см. рис. 72)
Рисунок 72. Настройка среды SimInTech для отладки dll.
Установите точку останова на вход в главную процедуру исполнения программы RUN_FUNC и запустите локальную отладку, нажав соответствующую кнопку в Visual Studio 2015 (см. рис. 73).
Рисунок 73. Точка остановки в основном теле программы
Если все настройки выполнены правильно, то при запуске локальной отладки, будет запущен SimInTech и в нем будет открыт проект Нагреватель_загрузчик_dll.prt.
После запуска моделирования данного проекта в среде SimInTech на первом шаге будет вызвана отлаживаемая controller_dll.dll и управление перейдет к Visual Studio 2015 на точке останова.
Созданная конфигурация проекта и настроек рабочей директории позволяет производить ручное изменение кода Cи в среде Visual Studio 2015 и осуществлять пошаговую отладку кода совместно с моделью в среде SimInTech. Основной текст программы находится в файле prog.inc (см. Рис. 73)
Для настройки подсветки синтаксиса файла с расширением inc в Visual Studio, выберите в главном меню «Tools» / «Оptions…», в диалоговом окне в разделе Text Editor/ File Extention, добавьте расширение inc.
Рисунок 74. Настройка расширения файла.
Для поиска участков кода Си, связанных с блоками расчетной схемы, выполните следующие действия:
- Выделите блок на схеме.
- Вызовите окно редактирования свойств блока (двойной клик).
- На закладке «Общие» найдите значение уникального идентификатора (UID).
- В окне Visual Studio поиском найдет текст UID=«N», где N — номер уникального идентификатора блока. (См. Рис. 75)
Рисунок 75. Поиск кода Си по индексу блока в схеме.
Последнюю вресию SimInTech можно запросить здесь…
Архив с файлами проекта можно расположен здесь…