Сущности ROS как элементы ТАУ
Last updated
Last updated
Рассмотрим как сущности и принципы ТАУ реализованы в ROS.
Вернемся к схеме из прошлого раздела. Дополним ее некоторыми отсутствующими деталями и разберем этот процесс управления на сущности.
Первая сущность - это объект управления. В рамках ROS, объект управления это всегда какая-то система робота. Это может быть система отвечающая за движение робота, за движение манипуляторов робота или каких-либо сервоприводов, за электропитание или за управление какой-либо полезной нагрузкой, то есть, в ROS мы управляем не роботом в целом, а каким-то конкретным функционалом робота.
Вторая сущность - это характеристика объекта управления. В нашем случае Направление - это что-то, что может изменяться, и, логично предположить, что об этих изменениях мы должны знать, то есть, мы должны постоянно получать данные о какой-то меняющейся величине.
В логике компьютерных систем некоторую характеристику объекта постоянно меняющую свое значение называют “переменная”.
У переменной есть имя и значение. Например:
В нашем случае это - имя “Направление” и значение - какое-то количество угловых градусов по азимуту, от первоначальной ориентации.
Переменные могут принимать различные значения не только по величине, то есть, x может быть равен не только 5, а также 6, 7, 99, но и по типу - целое число, дробное число, символ, строка или список символов и так далее.
Во многих языках программирования, переменная так и описывается - имя, тип ее данных и ее значение.
А что делать, если мы хотим в одном месте собрать данные разных типов, которые относятся к одному объекту ?
К примеру, у меня есть робот который едет прямо со скоростью 5 см в секунду в точке с координатами Х - 1 метр, У - 2 метра и с ориентацией 30 градусов вправо от первоначального положения.
Очевидно, что я могу его описать набором переменных:
Всё это - числа, с какими-то значениями. Причем заметьте, типы этих данных в общем случае - разные. Скорости и координаты это, скорее всего, дробные числа, а вот ориентация (в градусах) принимает целочисленные значения.
Получать и обрабатывать этот набор переменных удобнее в рамках единого набора данных, а не по отдельности. Для этого мы логически объединим эти скорости, координаты и ориентацию в один объект (Положение робота). После объединения позиция робота характеризуется таким набором переменных, вот что-то изменилось и у нас новый набор значений переменных, но состав остался неизменным.
Это все те же скорости, координаты и ориентация. И как-бы не менялась позиция робота, каждый раз такой набор переменных однозначно характеризует положение робота.
Такой единый набор переменных разных типов в языках программирования называется структурой данных. У структуры, как и у переменной есть имя, а значение - это входящие в эту структуру переменные.
Анализируя эту структуру данных можно сделать выводы о том куда едет робот, как быстро он туда доедет, да и в целом правильно ли он едет с нашей точки зрения.
Cтруктуры данных в ROS - это и есть характеристики объекта управления.
Это могут быть следующие структуры:
Структуры данных одометрии (тот самый наборы скоростей, координат и ориентации);
Структуры данных от лидаров или других датчиков;
Структуры видео-данных с камер робота;
Производные структуры, например нарисованные самим роботом карты и т.д.
Но основное что необходимо понять, что все данные в ROS находятся в своих определенных структурах с заранее заданной логикой и типизацией.
Очевидно, что значения данных меняются со временем: робот едет, температура растет или падает, препятствия появляются или исчезают - и все эти данные надо обновлять.
В ROS каждое обновление передается в сообщении, содержащим полную структуру данных соответствующей системы, то есть, робот сдвинулся на несколько миллиметров - появилось сообщение с обновленными координатами в структуре одометрии. Повернул - и опять новое сообщение со структурой одометрии, но с новым значением ориентации внутри.
Собственно ROS обеспечивает своевременный обмен сообщениями между всеми системами управляющими роботом.
Ядро ROS следит, чтобы все, кому нужны данные о каких-то параметрах робота, получали их сразу же как только они обновляются; чтобы все, кто передают значения этих параметров, соблюдали их структуру; чтобы данные не перемешивались и не конфликтовали друг с другом.
Если посмотреть на схему, представленную в начале, то становится понятно, что передаваемая в сообщениях структура данных - это и есть входные сигналы для регулятора.
Для того чтобы передать в программу структуры данных мы будем использовать инструмент, который называется в терминологии ROS - Подписчик (Subscriber).
Подписчик - это объект ROS - он получает сообщения от того, кто их посылает и передает содержащуюся в этих сообщениях структуру данных в программу.
Сообщения которые получает Подписчик, и есть характеристики объекта управления о которых было написано ранее.
Если Подписчик использует данные о состоянии какой-то системы робота, значит есть какой-то другой инструмент, который эти данные предоставляет. В терминологии ROS - это Издатель(Publisher). Именно Издатель считывает показания с датчиков различных систем робота, заполняет соответствующую структуру данных реальными значениями и передает ее в ROS.
Для обозначения передачи сообщений в ROS используется термин Публикация(Publish). Говорится, что Издатель публикует сообщения. Для обозначения принятия сообщений из ROS используется термин Подписка(Subscribe).
Из идеи передачи и приема сообщений возникает еще одна сущность ROS - это топик(Topic).
Топик можно сравнить с почтовым ящиком в который Издатель отправляет сообщения, с какой-то частотой, а Подписчик получает эти сообщения, как только они появляются в этом почтовом ящике.
У топика есть Имя и по нему Издатель и Подписчик обращаются для передачи и получения сообщений.
Топик в терминах теории управления, это аналог источника сигналов. Если сами сигналы - это значения переменных в структуре данных, то топик это то место, где эти сигналы возникают. Чтобы считать эти сигналы и как-то их проанализировать, надо обратиться в топик при помощи Подписчика. А чтобы передать какие-то выходные сигналы на исполнение роботу, надо “опубликовать” их в топик при помощи Издателя.
Что же такое программа под ROS, написанная к примеру на Python, и запущенная на роботе ?
Существует поставленная задача: мы хотим, чтобы робот ехал прямо и программа должна следить за направлением робота, и поворачивать его в случае отклонения от прямой. В соответствии с ее функциями программа должна содержать Регулятор. Действительно, именно в нём мы будем сравнивать текущие значения получаемые с различных датчиков робота с нашими целевыми задачами - уставками, а при помощи выходных сигналов - сообщений в соответствующие топики будем заставлять робота делать то, что мы от него хотим.
Кроме непосредственных функций регулятора (которые бывают разнообразными) и его реализация - это отдельная задача, наша программа в целом описывает систему управления роботом, то есть, в ней указаны все входные и выходные сигналы - топики; в ней может быть указано, как часто отправлять управляющие сообщения, как именно заполнять структуры данных. А также, в нашей программе мы инициализируем еще одну сущность ROS - ноду (Node).
От имени ноды мы будем вести публикацию в топики Издателем, от имени ноды мы будем подписываться на сообщения Подписчиком. От имени ноды, мы будем писать сообщения в лог-файлы и по имени ноды, мы сможем отследить какие именно взаимосвязи порождает внутри ROS наша программа.
В терминах теории управления - нода, это непосредственное отображение функций нашей автоматической системы в ROS. Но более просто, нода - это и есть наша программа.
И последняя, но одна из самых важных по значению сущностей это Мастер-нода ROS. Именно она следит, за тем, чтобы все Подписчики получали сообщения из тех топиков на которые они подписаны, а все Издатели соблюдали правила публикации. Она регистрирует все запущенные ноды и следит за их работой. Она реализует API для сервисных утилит. Именно она запускается когда мы запускаем ROS командой roscore
.
Чтобы управлять роботом, мы можем использовать стандартные принципы управления автоматическими системами. Например, управление с обратной связью. Для этого нам нужно написать программу определенного вида, запустить и зарегистрировать ее в мастер-ноде нашего робота. Чтобы считывать данные с датчиков робота, мы должны использовать Подписчик, который принесет нам из соответствующего топика, специально заполненную структуру данных. Например, чтобы считать текущую скорость, мы должны настроить Подписчика на топик одометрии, в структуре данных которого есть значение скорости. Чтобы отдавать какие-либо команды системам робота, мы должны заполнить соответствующую структуру данных и отправить ее в сообщении в нужный топик при помощи Издателя. Например, чтобы заставить робота двигаться, мы должны заполнить структуру данных команд на движение, теми значениями скоростей, которые мы хотим передать роботу, и при помощи Издателя опубликовать их соответствующий топик.