# Сущности ROS как элементы ТАУ

{% embed url="<https://youtu.be/wR3sRiXelyA>" %}

Рассмотрим как сущности и принципы ТАУ реализованы в ROS.

Вернемся к схеме из прошлого раздела. Дополним ее некоторыми отсутствующими деталями и разберем этот процесс управления на сущности.&#x20;

![](https://278680980-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F8k5AErXJnw5qW5Fo5HbH%2Fuploads%2FoQIDM6vo0EXaMp2UDFDI%2Fscheme-1.png?alt=media\&token=91f9f5ca-4982-4afd-8784-5f647c14dadc)

### Объект управления

*Первая сущность* - это объект управления. ***В рамках ROS***, объект управления это всегда какая-то ***система робота***. Это может быть система отвечающая за движение робота, за движение манипуляторов робота или каких-либо сервоприводов, за электропитание или за управление какой-либо полезной нагрузкой, то есть, в ROS мы управляем не роботом в целом, а каким-то конкретным функционалом робота.

### Структура данных

*Вторая сущность* - это характеристика объекта управления. В нашем случае Направление - это что-то, что может изменяться, и, логично предположить, что об этих изменениях мы должны знать, то есть, мы должны постоянно получать данные о какой-то меняющейся величине.

В логике компьютерных систем некоторую характеристику объекта постоянно меняющую свое значение называют ***“переменная”***.

У переменной есть имя и значение. Например:

```
x = 5 #у переменной Х числовое значение 5

или

s = "Hello World" #строка

или

t = 36,6 #температура в градусах
```

В нашем случае это - имя “Направление” и значение - какое-то количество угловых градусов по азимуту, от первоначальной ориентации.

Переменные могут принимать различные значения не только по величине, то есть, x может быть равен не только 5, а также 6, 7, 99, но и по типу - целое число, дробное число, символ, строка или список символов и так далее.

Во многих языках программирования, *переменная* так и описывается - ***имя, тип ее данных и ее значение***.

А что делать, если мы хотим в одном месте собрать данные разных типов, которые относятся к одному объекту ?

К примеру, у меня есть робот который едет прямо со скоростью 5 см в секунду в точке с координатами Х - 1 метр, У - 2 метра и с ориентацией 30 градусов вправо от первоначального положения.

Очевидно, что я могу его описать набором переменных:

```
Скорость:

Vx
Vy
```

```
Координаты:

X
Y
```

```
Ориентация:

Theta
```

Всё это - числа, с какими-то значениями. Причем заметьте, типы этих данных в общем случае - разные. Скорости и координаты это, скорее всего, дробные числа, а вот ориентация (в градусах) принимает целочисленные значения.

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

```
Положение робота:

Vx
Vy
X
Y
Theta
```

Это все те же скорости, координаты и ориентация. И как-бы не менялась позиция робота, каждый раз такой набор переменных однозначно характеризует положение робота.

Такой единый набор переменных разных типов в языках программирования называется ***структурой данных***. У структуры, как и у переменной есть имя, а значение - это входящие в эту структуру переменные.

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

***Cтруктуры данных в ROS*** - это и есть характеристики объекта управления.

Это могут быть следующие структуры:

* Структуры данных одометрии (тот самый наборы скоростей, координат и ориентации);
* Структуры данных от лидаров или других датчиков;
* Структуры видео-данных с камер робота;
* Производные структуры, например нарисованные самим роботом карты и т.д.

Но основное что необходимо понять, что *все данные в ROS находятся в своих определенных структурах* с заранее заданной логикой и типизацией.

Очевидно, что значения данных меняются со временем: робот едет, температура растет или падает, препятствия появляются или исчезают - и все эти данные надо обновлять.

В ROS каждое обновление передается в сообщении, содержащим полную структуру данных соответствующей системы, то есть, робот сдвинулся на несколько миллиметров - появилось сообщение с обновленными координатами в структуре одометрии. Повернул - и опять новое сообщение со структурой одометрии, но с новым значением ориентации внутри.

Собственно ROS обеспечивает своевременный обмен сообщениями между всеми системами управляющими роботом.

Ядро ROS следит, чтобы все, кому нужны данные о каких-то параметрах робота, получали их сразу же как только они обновляются; чтобы все, кто передают значения этих параметров, соблюдали их структуру; чтобы данные не перемешивались и не конфликтовали друг с другом.

Если посмотреть на схему, представленную в начале, то становится понятно, что ***передаваемая в сообщениях структура данных*** - это и есть ***входные сигналы для регулятора***.

### Подписчик (Subscriber)

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

***Подписчик*** - это объект ROS - он получает сообщения от того, кто их посылает и передает содержащуюся в этих сообщениях структуру данных в программу.

Сообщения которые получает *Подписчик*, и есть характеристики объекта управления о которых было написано ранее.

### Издатель (Publisher)

Если *Подписчик* использует данные о состоянии какой-то системы робота, значит есть какой-то другой инструмент, который эти данные предоставляет. В терминологии ROS - это ***Издатель(Publisher)***. Именно ***Издатель*** считывает показания с датчиков различных систем робота, заполняет соответствующую структуру данных реальными значениями и передает ее в ROS.

Для обозначения передачи сообщений в ROS используется термин ***Публикация(Publish)***. Говорится, что Издатель публикует сообщения. Для обозначения принятия сообщений из ROS используется термин ***Подписка(Subscribe)***.&#x20;

### Топик (Topic)

Из идеи передачи и приема сообщений возникает еще одна сущность ROS - это ***топик(Topic)***.&#x20;

***Топик*** можно сравнить с почтовым ящиком в который ***Издатель*** отправляет сообщения, с какой-то частотой, а ***Подписчик*** получает эти сообщения, как только они появляются в этом почтовом ящике.

У топика есть **Имя** и по нему Издатель и Подписчик обращаются для передачи и получения сообщений.

Топик в терминах теории управления, это аналог источника сигналов. Если сами сигналы - это значения переменных в структуре данных, то топик это то место, где эти сигналы возникают. Чтобы считать эти сигналы и как-то их проанализировать, надо обратиться в топик при помощи Подписчика. А чтобы передать какие-то выходные сигналы на исполнение роботу, надо “опубликовать” их в топик при помощи Издателя.

### Нода (Node)

Что же такое программа под ROS, написанная к примеру на Python, и запущенная на роботе ?

Существует поставленная задача: мы хотим, чтобы робот ехал прямо и программа должна следить за направлением робота, и поворачивать его в случае отклонения от прямой. В соответствии с ее функциями программа должна содержать ***Регулятор***. Действительно, именно в нём мы будем сравнивать текущие значения получаемые с различных датчиков робота с нашими целевыми задачами - уставками, а при помощи выходных сигналов - ***сообщений*** в соответствующие топики будем заставлять робота делать то, что мы от него хотим.

Кроме непосредственных функций регулятора (которые бывают разнообразными) и его реализация - это отдельная задача, наша программа в целом описывает систему управления роботом, то есть, в ней указаны все входные и выходные сигналы - ***топики***; в ней может быть указано, как часто отправлять управляющие сообщения, как именно заполнять структуры данных. А также, в нашей программе мы инициализируем еще одну сущность ROS - ***ноду (Node)***.

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

***В терминах теории управления - нода***, это непосредственное отображение функций нашей автоматической системы в ROS. Но более просто, нода - это и есть наша программа.

### Мастер-нода (master-node)

И последняя, но одна из самых важных по значению сущностей это **Мастер-нода ROS**. Именно она следит, за тем, чтобы все ***Подписчики*** получали сообщения из тех топиков на которые они подписаны, а все ***Издатели*** соблюдали правила публикации. Она регистрирует все запущенные ноды и следит за их работой. Она реализует API для сервисных утилит. Именно она запускается когда мы запускаем **ROS** командой `roscore` .

### Выводы

Чтобы управлять роботом, мы можем использовать стандартные принципы управления автоматическими системами. Например, управление с обратной связью. Для этого нам нужно написать программу определенного вида, запустить и зарегистрировать ее в **мастер-ноде** нашего робота. Чтобы считывать данные с датчиков робота, мы должны использовать **Подписчик**, который принесет нам из соответствующего **топика**, специально заполненную **структуру данных**. Например, чтобы считать текущую скорость, мы должны настроить Подписчика на топик одометрии, в структуре данных которого есть значение скорости. Чтобы отдавать какие-либо команды системам робота, мы должны заполнить соответствующую структуру данных и отправить ее в сообщении в нужный топик при помощи **Издателя**. Например, чтобы заставить робота двигаться, мы должны заполнить структуру данных команд на движение, теми значениями скоростей, которые мы хотим передать роботу, и при помощи Издателя опубликовать их соответствующий топик.&#x20;
