Программное обеспечение системы управления мехатронного модуля управления защитной дверью. 2 лаба. мирэа Российский технологический университет рту мирэа институт искусственного интеллекта Кафедра проблем управления
![]()
|
![]() МИНОБРНАУКИ РОССИИ Федеральное государственное бюджетное образовательное учреждение высшего образования «МИРЭА – Российский технологический университет» РТУ МИРЭА __________________________________________________________ Институт искусственного интеллекта Кафедра проблем управления
Москва, 2022г. ЛАБОРАТОРНАЯ РАБОТА № 1 «Отладка программного обеспечения роботехнических систем с использованием виртуального моделирования» Цель работыПолучение навыков построения программного обеспечения промышленных систем управления на базе функциональных блоков и конечных автоматов.Задание Разработать программное обеспечение системы автоматического управления приводом защитной двери. Схема механизма представлена на рисунке 1. Дверь оснащена асинхронным двигателем и четырьмя датчиками положения ( ![]() ![]() При включении системы управления дверь должна двигаться в заданную сторону на небольшой скорости для определения своего местоположения. В этом режиме необходимо, чтобы индикаторы мерцали с частотой 1 Гц. После чего происходит переход в рабочий режим. В рабочем режиме обеспечить максимально возможную скорость движения на отрезке ![]() ![]() ![]() Система управления ворот должна быть выполнена в виде функционального блока, предполагающего повторное использование. ![]() рисунок 1 – Устройство защитной двери Выполнение начинается с открытия заархивированного проекта исходной конфигурации, хранящийся в директории “C:\projects\Blank lab\POMRS_2”, распаковав его в папку группы, находящуюся в “C:\projects”. Далее необходимо открыть визуальную конфигурацию оборудования и добавить к имеющимся модуль частотного преобразователя “8I64xxxxxxx.00x-1”, соединив его шиной с основной установкой (рис. 2). ![]() рисунок 2 – Конфигурация оборудования Реализация проекта в виде функциональных блоков используется для повышения удобства работы с созданным программным обеспечением в дальнейшем, чтобы была возможность использовать нынешние наработки в других программах. Зададим необходимые параметры для асинхронного двигателя (табл. 1). Они также указаны на самом двигателе или документации к нему. Для этого необходимо в меню в меню Physical View выбрать частотный преобразователь и в контекстном меню выбрать пункт «Configuration». Результат настройки двигателя показан на рисунке 3. Таблица 1. Параметры асинхронного двигателя.
![]() рисунок 3 – Конфигурация асинхронного двигателя через частотный преобразователь Завершив настройку частотного преобразователя, приступаем к созданию необходимых объектов в проекте, а именно: ANSI C Program; ANSI C Library « DriveLib». В библиотеке «DriveLib» создать функциональные блоки (рис. 4): «DriveStateMashine» – заготовка функционального блока управления частотным преобразователем. Структура ФБ должна иметь следующий набор переменных, указанный в таблице 2. «DoorStateMashine» - функциональный блок, в котором будет реализована основная логика программы – задание направления вращения и скорости движения воротами в зависимости от их положения и требуемого направления вращения. Для упрощения описания состояний ворот необходимо создать новый тип данных (см. приложение): перечисление «DoorStates». Сами состояния, которые необходимо добавить приведены в таблице 3, а их связь представлена в функциональной схеме (рис. 5-6). ![]() рисунок 4 - функциональные блоки и их переменные ![]() рисунок 5 - инициализация переменных функциональных блоков Таблица 2. Параметры функционального блока двигателя.
![]() Рисунок 6. Блок-схема состояний ворот и возможных переходов между ними. Таблица 3. Состояния ворот.
Теперь, имея новый необходимый тип данных, заполним структуру функционального блока (результат представлен на рисунке 4): Таблица 4. Структура функционального блока управления воротами.
«LedStateMashine» – машина состояний обработки светодиодных индикаторов. Структура ФБ должна иметь следующий набор переменных: Таблица 5. Структура функционального блока управления воротами.
Для совмещения работы аппаратной и программной частей, следует произвести мэпинг переменных (рис.7-9). Таблица 6. Мэпинг переменных для частотного преобразователя.
![]() Рисунок 7. Мэппинг переменных частотного преобразователя Таблица 7. Мэпинг переменных для датчиков положения
![]() Рисунок 8. Мэппинг переменных датчиков положения Для мэпинга индикаторов для модуля X20DO9322 (DO - Digital Output), соответствия каналов соответственно будут: Таблица 8. Мэппинг переменных для индикаторов
![]() Рисунок 9. Мэппинг индикаторов Далее готовим программу к запуску программу (рис. 10-15) ![]() Рисунок 10. Организация управления частотным преобраователем ![]() Рисунок 11. Состояния двери ![]() Рисунок 12. Блок-схема управления частотным преобразователем. ![]() Рисунок 13. Подготовка к запуску. ![]() Рисунок 14. Результат запуска программы в AutomationStudio ![]() Рисунок 15. Результат запуска программы на стенде Приложение (листинг кода) //DriveStatemachine #include #ifdef __cplusplus Extern “C” { #endif #include “DriveLib.h” #ifdef __cplusplus }; #endif void DriveStateMachine(struct DriveStateMachine* inst) { UINT mask = inst->state & 0x6f; if(!inst->enable) { inst->command = CMD_SHUTDOWN; } else { switch(mask) { case STATE_DISABLED: inst->command = CMD_SGUTDOWN; break; case STATE_READY: inst->command = CMD_ENABLED; break; case STATE_SWITCHED_ON: inst->command = CMD_ SWITCHED_ON; break; } } } //DoorStateMachine #include #ifdef __cplusplus extern "C" { #endif #include "DriveLib.h" #ifdef __cplusplus }; #endif /* TODO: Add your comment here */ void DoorStateMachine(struct DoorStateMachine* inst) { /*TODO: Add your code here*/ switch(inst->state) { case ST_INIT: { if(inst->sw1==0 && inst->sw2==0 && inst->sw3==0 && inst->sw4==0) inst->state=ST_UNKNOWN; break; } case ST_UNKNOWN: { if(inst->direction==0 && inst->sw4==0) inst->state=ST_OPEN; if(inst->direction==0 && inst->sw3==0 && inst->sw4!=0) inst->state=ST_DEC_POS; if(inst->direction==0 && inst->sw2==0 && inst->sw3!=0) inst->state=ST_POS; if(inst->direction==0 && inst->sw1==0 && inst->sw2!=0) inst->state=ST_ACC_POS; if(inst->direction==1 && inst->sw1==1) inst->state=ST_CLOSE; if(inst->direction==1 && inst->sw2==1 && inst->sw1!=1) inst->state=ST_DEC_NEG; if(inst->direction==1 && inst->sw3==1 && inst->sw2!=1) inst->state=ST_NEG; if(inst->direction==1 && inst->sw4==1 && inst->sw3!=1) inst->state=ST_ACC_NEG; break; } case ST_CLOSE: { inst->speed = 0; if(inst->direction==0) inst->state=ST_ACC_POS; break; } case ST_ACC_NEG: { inst->speed = -200; if(inst->direction==1 && inst->sw3==1) inst->state=ST_NEG; if(inst->direction==0) inst->state=ST_DEC_POS; break; } case ST_NEG: { inst->speed = -600; if(inst->direction==1 && inst->sw2==1) inst->state=ST_DEC_NEG; if(inst->direction==0) inst->state=ST_POS; break; } case ST_DEC_NEG: { inst->speed = -200; if(inst->direction==1 && inst->sw1==1) inst->state=ST_CLOSE; if(inst->direction==0) inst->state=ST_ACC_POS; break; } //LedStateMachine #include #ifdef __cplusplus extern "C" { #endif #include "DriveLib.h" #ifdef __cplusplus }; #endif void LedStateMachine(struct LedStateMachine* inst) { switch(inst->state) { case ST_INIT: { break; } case ST_UNKNOWN; { if(inst->timer%5==4) { inst->led1=!inst->led1; inst->led2=!inst->led2; inst->led3=!inst->led3; inst->led4=!inst->led4; } break; } //Cyclic #include #ifdef _DEFAULT_INCLUDES #include #endif void _CYCLIC ProgramCyclic(void) { DoorStateMachine(&doorSM); driveSM.speed = doorSM.speed; DriveStateMachine(&driveSM); ledSM.state = doorSM.state; LedStateMachine(&ledSM); } //Init #include #ifdef _DEFAULT_INCLUDES #include #endif void _INIT ProgramInit(void) { driveSM.enable=1; } //Exit #include #ifdef _DEFAULT_INCLUDES #include #endif void _EXIT ProgramExit(void) { } |