Files
clover/docs/ru/ros.md
Oleg Kalachev 72491ade0e Update docs/ru/ros.md
Co-authored-by: Alexey Rogachevskiy <sfalexrog@gmail.com>
2020-08-07 00:41:42 +03:00

12 KiB
Raw Blame History

Введение в ROS

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

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

Установка

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

Для использования ROS на компьютере рекомендуется ОС Ubuntu Linux (либо виртуальная машина, например Parallels Desktop Lite или VirtualBox). Воспользуйтесь официальной документацией для установки ROS на компьютер.

Для быстрого старта вы можете воспользоваться образом виртуальной машины с ROS и симулятором Клевера.

Note

Для дистрибутива ROS Melodic рекомендуется Ubuntu версии 18.04.

Концепции

Ноды

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

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

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

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

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

import rospy

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

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

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

Топики

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

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

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

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

Info Смотрите остальные стандартные типы сообщений в пакетах 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

Данные в топиках можно мониторить и визуализировать и в графических инструментах ROS.

Сервисы

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

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

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

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

import rospy
from clover.srv import GetTelemetry

rospy.init_node('my_ros_node')

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

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

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

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

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

Параметры

TODO

Имена

Основная статья: http://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)

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

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

Далее: Графические инструменты ROS.


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