ROS

Основная документация: https://wiki.ros.org.

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

Установка

ROS уже установлен на образе для RPi.

Концепции

Ноды

Основная статья: https://wiki.ros.org/Nodes.

ROS-нода1 – это специальная программа (обычно написанная на Python или C++), которая взаимодействует с другими нодами посредством ROS-топиков и ROS-сервисов. Разделение сложных робототехнических систем на изолированные ноды дает определенные преимущества: понижается связанность кода, повышается переиспользуемость и надежность.

Очень многие робототехнические библиотеки и драйвера выполнены именно в виде ROS-нод.

Для того, чтобы превратить обычную программу в ROS-ноду, необходимо подключить к ней библиотеку rospy (Python) или roscpp (C++) и добавить инициализирующий код.

Пример ROS-ноды на языке Python:

import rospy

rospy.init_node('my_ros_node')  # имя ROS-ноды

rospy.spin()  # входим в бесконечный цикл...

Любая программа для автономного полета является ROS-нодой.

Топики

Основная статья: https://wiki.ros.org/Topics.

Топик – это именованная шина данных, по которой ноды обмениваются сообщениями. Любая нода может опубликовать сообщение в произвольный топик, а также подписаться на произвольный топик.

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

Тип сообщения Описание
std_msgs/Int64 Целое число.
std_msgs/Float64 Число с плавающей точкой (дробное) двойной точности.
std_msgs/String Строка.
geometry_msgs/PoseStamped Позиция и ориентация объекта с заданной системой координат и временной меткой (широко используется для передачи текущей позиции робота и его частей).
geometry_msgs/TwistStamped Линейная и угловая скорость объекта с заданной системой координат и временной меткой.
sensor_msgs/Image Изображение (см. статью о работе с камерой)

Смотрите остальные стандартные типы сообщений в пакетах common_msgs, std_msgs, geometry_msgs, sensor_msgs и других.

Пример публикации сообщения типа std_msgs/String (строка) в топик /foo на языке Python:

import rospy
from std_msgs.msg import String

rospy.init_node('my_ros_node')

foo_pub = rospy.Publisher('/foo', String, queue_size=1)  # создаем Publisher

foo_pub.publish(data='Hello, world!')  # публикуем сообщение

Пример подписки на топик /foo:

import rospy
from std_msgs.msg import String

rospy.init_node('my_ros_node')

def foo_callback(msg):
    print(msg.data)

# Подписываемся. При получении сообщения в топик /foo будет вызвана функция foo_callback.
rospy.Subscriber('/foo', String, foo_callback)

rospy.spin()  # входим в бесконечный цикл, чтобы программа не завершила работу

Вы можете прочитать данные из топика однократно, используя функцию wait_for_message:

msg = rospy.wait_for_message('/foo', String, timeout=3)  # ждать сообщения в топике /foo в таймаутом 3 с

Также существует возможность работы с топиками с помощью утилиты rostopic. Например, с помощью следующей команды можно просматривать сообщения, публикуемые в топик /mavros/state:

rostopic echo /mavros/state

Команда rostopic info позволяет узнать тип сообщений в топике, команда rostopic hz — частоту публикуемых в топике сообщений.

Сервисы

Основная статья: https://wiki.ros.org/Services.

Сервис – это некоторый аналог функции, которая может быть вызвана из одной ноды, а обработана в другой. У сервиса есть имя, аналогичное имени топика, и 2 типа сообщений: тип запроса и тип ответа.

Таким образом, сервисы реализуют паттерн удаленного вызова процедур.

Пример вызова ROS-сервиса из языка Python:

import rospy
from drone.srv import GetTelemetry

rospy.init_node('my_ros_node')

# Создаем обертку над сервисом get_telemetry пакета drone с типом GetTelemetry:
get_telemetry = rospy.ServiceProxy('get_telemetry', srv.GetTelemetry)

# Вызываем сервис и получаем телеметрию дрона:
telemetry = get_telemetry()

С сервисами можно также работать при помощи утилиты rosservice. Так можно вызвать сервис /get_telemetry из командной строки:

rosservice call /get_telemetry "{frame_id: ''}"

Больше примеров использования сервисов для автономных полетов можно посмотреть в документации ноды simple_offboard.

Имена

Основная статья: https://wiki.ros.org/Names.

Любой топик, сервис или параметр идентифицируется с помощью уникального имени. ROS-имя представляет собой иерархическую структуру с символом / в качестве разделителя (сходно с именами в файловой системе).

Примеры ROS-имен:

  • / (глобальное пространство имен)
  • /foo
  • /stanford/robot/name
  • /wg/node1

Эти имена является глобальными (аналогично полному пути в файлу в файловой системе). На практике рекомендуется использование приватных или относительных имен.

Приватное имя

Каждая нода может использовать собственное приватное пространство имен (соответствующее имени ноды) для своих ресурсов. Например, нода aruco_detect может публиковать такие топики:

  • /aruco_detect/markers
  • /aruco_detect/visualization
  • /aruco_detect/debug

Когда нода ссылается на свой приватный ресурс, вместо пространства имен (/aruco_detect/) используется символ ~, например:

  • ~markers
  • ~visualization
  • ~debug

Таким образом, создание топика foo в приватном пространство имен из Python будет выглядеть так:

private_foo_pub = rospy.Publisher('~foo', String, queue_size=1)

Относительное имя

Несколько нод также могут объединяться в общее пространство имен (например, при одновременной работе нескольких роботов). Для того, чтобы ссылаться на топики с учетом общего пространства имен, в названии ресурса опускается начальный символ /.

Пример создание топика foo с учетом общего пространства имен:

relative_foo_pub = rospy.Publisher('foo', String, queue_size=1)

В общем случае всегда рекомендуется использовать приватные или относительные имена ресурсов и никогда не использовать глобальные.

Работа на нескольких машинах

Основная статья: https://wiki.ros.org/ROS/Tutorials/MultipleMachines.

Преимуществом использования ROS является возможность распределения нод на несколько машин в сети. Например, ноду, осуществляющую распознавание образом на изображении можно запустить на более мощном компьютере; ноду, управляющую коптером можно запустить непосредственно на Raspberry Pi, подключенном к полетному контроллеру и т. д.

Дополнительные материалы

1. Также встречается перевод "узел".

results matching ""

    No results matching ""