Архитектура ros

39
Архитектура ROS. Практическое занятие. Андрей Антонов | robotosha.ru 10.10.2014 1 Цель работы Знакомство с Robot Operating System (ROS). Изучение концепций и инструмен- тов фреймворка ROS. Знакомство с узлами, темами и сервисами, а также изучение их использования. 2 Знакомство с ROS Robot Operating System (ROS) — это широко используемый в робототехнике фреймворк. Философией ROS является создание программного обеспечения, поз- воляющего работать с различными роботами, лишь внеся небольшие изменения в код. Эта идея позволяет создавать функциональность, которая может быть до- статочно просто перенесена для использования различными роботами, избежав постоянного «изобретения колеса». ROS была разработана в 2007 году в лаборатории искусственного интеллекта Стэнфорда (Stanford Artificial Intellegence Laboratory, SAIL) для поддержки стэн- фордского проекта AI Robot. C 2008 года, разработка продолжилась в основном в исследовательском институте Willow Garage, сотрудничающим с более чем два- дцатью различными институтами в рамках модели совместного развития. Множество исследовательских институтов начали разрабатывать собственные проекты в ROS, добавляя поддержку своего аппаратного обеспечения и делясь примерами собственного программного кода. Некоторые компании, производящие роботов, стали адаптировать свои продукты для их использования с ROS. Рис. 1: Популярные роботы, поддерживаемые ROS 1

Upload: -

Post on 30-Jun-2015

285 views

Category:

Software


6 download

TRANSCRIPT

Page 1: Архитектура ROS

Архитектура ROS. Практическое занятие.

Андрей Антонов | robotosha.ru

10.10.2014

1 Цель работыЗнакомство с Robot Operating System (ROS). Изучение концепций и инструмен-

тов фреймворка ROS. Знакомство с узлами, темами и сервисами, а также изучениеих использования.

2 Знакомство с ROSRobot Operating System (ROS) — это широко используемый в робототехнике

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

ROS была разработана в 2007 году в лаборатории искусственного интеллектаСтэнфорда (Stanford Artificial Intellegence Laboratory, SAIL) для поддержки стэн-фордского проекта AI Robot. C 2008 года, разработка продолжилась в основномв исследовательском институте Willow Garage, сотрудничающим с более чем два-дцатью различными институтами в рамках модели совместного развития.

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

Рис. 1: Популярные роботы, поддерживаемые ROS

1

Page 2: Архитектура ROS

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

В ROS также поддерживается множество различных датчиков и исполнитель-ных устройств (актуаторов), используемых в робототехнике. Каждый день появ-ляются новые устройства, совместимые с этим фреймворком.

Рис. 2: ROS поддерживает различные исполнительные устройства

В ROS имеются стандартные возможности операционной системы, такие как,аппаратная абстракция, управление устройствами на низком уровне, реализованачасто используемая функциональность, передача сообщений между процессами,и управление библиотеками. Архитектура ROS основана не графе с централизо-ванной топологией. Обработка происходит в узлах, которые могут принимать илиотправлять данные с датчиков, систем контроля состояния и планирования, при-водов, и так далее. Библиотека ориентирована на Unix-подобные системы (подUbuntu Linux работает отлично, а Fedora и Mac OS X имеют статус эксперимен-тальных).

Пакет *-ros-pkg является является общим репозиторием для разработки вы-сокоуровневых библиотек. Многие из возможностей часто ассоциируемые с ROS,такие как библиотеки навигации и визуализатор rviz, хранятся в этом репози-тории. Эти библиотеки предоставляют мощный набор инструментов (различныевизуализаторы, симуляторы, средства отладки) для упрощения работы.

Рис. 3: ROS позволяет наблюдать за тем, что происходит на каждом шаге

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

2

Page 3: Архитектура ROS

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

ROS поддерживает параллельные вычисления, имеет хорошую интеграциюс популярными C++ библиотеками, такими как как OpenCV, Qt, Point CloudLibrary и пр., и она может работать на одноплатных компьютерах, таких какRaspberry Pi или BeagleBone Black, а также с микроконтроллерными платформа-ми, например, Arduino. Вы можете создать своего собственного робота на основеArduino или Raspberry Pi и использовать для его управления Robot OperatingSystem.

Рис. 4: Интеграция ROS

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

3 Архитектура ROSВ архитектуре ROS можно выделить три концептуальных уровня:

∙ Уровень файловой системы (Filesystem level)

∙ Уровень вычислительного графа (Computation Graph level)

∙ Уровень сообщества (Community level)

Первый уровень — это уровень файловой системы. На этом уровне располо-жена внутренняя структура ROS — структура папок, файлы, необходимые дляработы.

3

Page 4: Архитектура ROS

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

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

3.1 Файловая система ROS

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

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

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

∙ Пакеты (Packages): формируют атомарный уровень ROS. Пакет имеет ми-нимальную структуру и содержимое, чтобы создать программу в ROS. Онможет иметь выполняемые процессы (узлы или node), файлы конфигурациии так далее.

∙ Декларации (Manifests): содержится информация о пакетах, лицензионнаяинформация, зависимости, флаги компиляции и прочее. Управление декла-рациями осуществляется через файл manifests.xml.

∙ Стеки (Stacks): когда вы собираете вместе несколько пакетов для получениянекоторой функциональности, то получите стек. В ROS, существует многотаких стеков для различных целей, например, стек навигации.

∙ Декларации стеков (Stack manifests): предоставляют данные о стеке, вклю-чая его лицензионную информацию и его зависимости от других стеков.Файл stack.xml.

∙ Типы сообщений (Message types, msg): сообщение является информацией,которую процесс отправляет другим процессам. В ROS имеется множествостандартных типов сообщений. Описание сообщения сохраняется вmy_package/msg/MyMessageType.msg

∙ Типы сервисов (Service types, src): описания сервисов хранятся вmy_package/srv/MyServiceType.srvОпределяют в ROS структуры данных запросов и ответов для сервисов.

4

Page 5: Архитектура ROS

Рис. 5: Файловая система ROS

3.1.1 Пакеты

Обычно, когда мы говорим о пакетах, то имеем ввиду типичную структурупапок и файлов. Эта структура выглядит следующим образом:

∙ bin/ Это папка, где сохраняются наши скомпилированные программы

∙ include/package_name Эта директория включает заголовки библиотек, кото-рые понадобятся. Не забудьте экспортировать декларацию, так как она ис-пользуется другими пакетами

∙ msg/ Если вы разработали нестандартное сообщение, то помещайте его сюда

∙ scripts/ Здесь находятся исполняемые скрипты. Это могут быть скрипты обо-лочки Bash, Python’а или какие-либо еще

∙ src/ Здесь располагаются исходные файлы вашей программы. Вы можетесоздать папку для узлов и разрешений для узлов, либо организовать, таккак вы хотите

∙ srv/ Здесь представлены типы сервисов

∙ CMakeLists.txt Это файл построения CMake

∙ manifest.xml Это файл декларации пакета

Для создания, редактирования или другой работы с пакетами, в ROS имеетсянесколько вспомогательных инструментов:

∙ rospack Эта команда используется для получения информации или поискапакетов в системе

∙ roscreate-pkg Если вы хотите создать новый пакет, то воспользуйтесь этойкомандой

5

Page 6: Архитектура ROS

∙ rosmake Эта команда используется для компиляции пакета

∙ rosdep Эта команда устанавливает системные зависимости для пакета

∙ rxdeps Эта команда используется, если вы хотите посмотреть зависимостипакета в виде графа

Для перемещения между пакетами и их папками, в ROS имеется очень полез-ный инструмент, называемый rosbash, в котором имеется несколько команд, оченьсильно похожих на команды Linux. Вот несколько примеров:

∙ roscd Эта команда помогает сменить директорию — аналог команды cd вLinux

∙ rosed Команда используется для редактирования файла

∙ roscp Команда используется для копирования файла из некоторого пакета

∙ rosd Эта команда выдает список директорий пакета

∙ rosls Список файлов пакета — аналог команды ls в Linux

Файл manifest.xml обязательно должен присутствовать в пакете. Он содержитспецифическую информацию о конкретном пакете. Если вы найдете этот файл впапке, то возможно, эта папка является пакетом.

Если открыть файл manifest.xml, то вы увидите информацию о названии пакета,зависимостях и так далее. Все это упрощает установку и распространение этогопакета.

Два типичных тега, которые используются в файле декларации — это <depend>и <export>. Тег <depend> показывает, какие пакеты должны быть установленыдо того, как будет установлен выбранный пакет. Это сделано из-за того, что новыйпакет пользуется некоторой функциональностью других пакетов. Тег <export> го-ворит системе, какие флаги должны быть использованы для компиляции пакета,какие заголовки должны быть включены и так далее.

Ниже приведен пример этого файла.

<package><description brief="short description">long description,</description><author>Ivanov Ivan Ivanovich</author><license>BSD</license><url>http://example.com/</url><depend package="roscpp"/><depend package="common"/><depend package="otherPackage"/><versioncontrol type="svn" url="https://urlofpackage/trunk"/><export><cpp cflags="-I${prefix}/include" lflags="-L${prefix}/lib -lros"/></package>

6

Page 7: Архитектура ROS

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

Стеку необходима базовая структура файлов и папок. Ее можно создать вруч-ную, однако, в ROS для этого имеется инструмент в виде команды roscreate-stack.

Для стека необходимы следующие три файла: CMakeList.txt, Makefile и stack.xml.Если в папке вам попадется файл stack.xml, вы можете быть уверены, что это стек.

Ниже приведен пример этого файла.

<stack><description brief="Sample_Stack">Sample_Stack1</description><author>Ivanov Ivan Ivanovich</author><license>BSD,LGPL,proprietary</license><review status="unreviewed" notes=""/><url>http://someurl.blablabla</url><depend stack="common_msgs" /> <!-- nav_msgs, sensor_msgs, geometry_msgs --><depend stack="ros_tutorials" /> <!-- turtlesim --></stack>

3.1.2 Сообщения

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

ROS имеет множество предопределенных сообщений, но если вы разрабатыва-ете новое сообщение, оно будет в папке msg/ вашего пакета. Внутри этой папки,некоторые файлы с расширением .msg определяют сообщения.

Сообщение должно иметь две основные части: поля и константы. Поля опре-деляют тип данных, передаваемых в сообщении. например, int32, float32 и string,или же новые типы, которые вы могли создать до этого, например, типы type1 иtype2. Константы определяют имена полей.

Пример файла msg:

int32 idfloat32 velstring name

В ROS имеется множество стандартных типов для использования в сообщени-ях.

7

Page 8: Архитектура ROS

Простой тип данных Описание C++ Pythonbool Unsigned 8-bit int uint8_t boolint8 Signed 8-bit int int8_t intuint8 Unsigned 8-bit int uint8_t intint16 Signed 16-bit int int16_t intuint16 Unsigned 16-bit int uint16_t intint32 Signed 32-bit int int32_t intuint32 Unsigned 32-bit int uint32_t intint64 Signed 64-bit int int64_t longuint64 Unsigned 64-bit int uint64_t longfloat32 32-bit IEEE float float floatfloat64 64-bit IEEE float double floatstring ASCII string (4 bit) std::string stringtime Secs/nsecs signed ros::Time rospy.Time

32 bit intduration Secs/nsecs signed ros::Duration rospy.Duration

32 bit int

Специальным типом в ROS является Header. Он используется для добавлениявременных меток, кадров и так далее. Этот тип позволяет сообщениям быть про-нумерованными, таким образом, мы можем знать, кто отправил сообщение. Могутбыть добавлены другие функции, прозрачные для пользователя, но управляемыеROS.

Тип Header содержит следующие поля:

uint32 seqtime stampstring frame_id

3.1.3 Сервисы

ROS использует упрощенный язык описания сервисов для характеристики ти-пов сервисов. Он создается непосредственно из формата msg для обеспечения свя-зи запрос/ответ между узлами. Описания сервиса хранятся в .srv файлах в под-директории srv/ пакета.

Для вызова сервиса необходимо использовать имя пакета вместе с именем сер-виса. Например, файлу sample_package1/srv/sample1.srv соответствуетsample_package1/sample1.

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

Если вы хотите создать сервис, ROS может помочь вам генератором серви-сов. Эти инструменты генерируют код для начального определения сервиса. Вамтолько нужно добавить строку gensrv() в ваш файл CMakeLists.txt.

8

Page 9: Архитектура ROS

3.2 Уровень вычислительного графа

ROS создает сеть, в которой соединены все процессы. Любой узел в системе мо-жет получить доступ к этой сети, взаимодействовать с другими узлами, смотретьинформацию, которую они посылают и передавать данные в сеть.

Рис. 6: Структура уровня вычислительного графа

Базовыми понятиями на этом уровне являются: узлы, мастер, сервер парамет-ров, сообщения, сервисы, темы и бэги. Все они различными способами обеспечива-ют граф данными.

∙ Узлы (nodes): являются процессами, производящими вычисления. Если вамнужен процесс, который может взаимодействовать с другими узлами, вамнужно создать узел с этим процессом, подключив его к сети ROS. Обыч-но, система имеет множество узлов для управления различными функция-ми. Лучше иметь множество узкоспециализированных узлов, выполняющихединственную функцию, чем большой универсальный узел, который бы де-лал в системе все на свете. Узлы записываются в клиентскую библиотекуROS. Примером могут служить roscpp или rospy.

∙ Мастер (master): обеспечивает регистрацию имени и ищет оставшиеся узлы.Если его нет в системе, вы не сможете обмениваться информацией с узлами,сервисами, сообщениями и прочим. Мастер может быть на компьютере, гдеузлы работают с другими компьютерами.

∙ Сервер параметров (parameter server): дает возможность сохранять дан-ные, используя ключи, размещенные централизованно. С этим параметромвозможно конфигурировать узлы во время их работы или для изменениярабочего узла.

∙ Сообщения(messages): узлы взаимодействуют друг с другом посредствомсообщений. Сообщение содержит данные, передающие информацию другимузлам. ROS имеет много типов сообщений. Возможно разработать свой соб-ственный тип сообщения, используя стандартные сообщения.

9

Page 10: Архитектура ROS

∙ Темы (topics): Каждое сообщение должно иметь имя, чтобы направлятьсяв сети ROS. Когда узел является отправителем данных, мы говорим, чтоузел опубликовал тему. Узлы могут получить темы от других узлов, простоподписавшись на тему. Узел может подписаться на тему, и не обязательно,чтобы узел, который бы публиковал тему, должен в настоящий момент су-ществовать. Это позволяет отделить выпуск от потребления. Важно, чтобыназвание темы было уникальным, чтобы избежать проблем и недоразумениймежду темами с одинаковыми названиями.

∙ Сервисы (services): при публикации темы, вы отправляете данные, имею-щие отношения многие-ко-многим, но когда вам нужно сделать запрос илиполучить ответ от узла, вы не можете сделать это, используя темы. Сервисыдают нам возможность взаимодействовать с узлами. Сервисы также должныиметь уникальное имя. Когда у узла есть сервис, все узлы могут общаться сним, благодаря клиентским библиотекам ROS

∙ Бэги (bags): формат для сохранения и воспроизведения данных сообщенийROS. Бэги являются важным механизмом для хранения данных, таких какданные сенсоров, которые сложно собирать, но они требуются для разра-ботки и тестирования алгоритмов. Бэги часто используются при работе сосложными роботами.

На Рисунке 7 показано графическое представление уровня вычислительногографа. Это представление реального робота в реальных условиях. На графе естьузлы, темы, информация о том, на какие темы подписан узел и т.д. На этом графене представлены сообщения, бэги, сервер параметров и сервисы. Для их графиче-ского представления требуются другие инструменты. Инструментом для созданияграфа является rxgraph.

Рис. 7: Структура уровня вычислительного графа

10

Page 11: Архитектура ROS

3.2.1 Узлы

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

Узел должен иметь в системе уникальное имя. Это имя используется для по-лучения доступа узлом к обмену информацией с другим узлом, используя недву-смысленное имя. Код узла может быть написан с использованием различных биб-лиотек, таких как roscpp (C++) и rospy (Python).

ROS имеет инструменты для обработки узлов и получения информации о них,например, rosnode. rosnode — это инструмент командной строки для отображенияинформации об узлах, например списка выполняющихся в настоящее время узлов.Поддерживаемые команды:

∙ rosnode info node — информация об узле

∙ rosnode kill node — завершает работу узла или отправляет такой сигнал

∙ rosnode list — список активных узлов

∙ rosnode machine hostname — список узлов, выполняющихся на конкретноймашине или список компьютеров

∙ rosnode ping node — тест подключения к узлу

∙ rosnode cleanup — очищает регистрационную информацию о недоступных уз-лах

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

Пример изменения имени темы:

$ rosrun roboscool_tutorials tutorialX topic1:=/level1/topic1

Эта команда изменит имя темы topic1 на /level1/topic1.Для изменения параметров узла необходимо добавить нижнее подчеркивание

к названию параметра. Например:

$ rosrun roboscool_tutorials tutorialX _param:=9.0

В результате param будет присвоено вещественное число 9.0.Нельзя использовать зарезервированные системой имена:

∙ _name — специально зарезервированное ключевое слово для имени узла

∙ _log — зарезервированное ключевое слово, обозначающее место, куда дол-жен записываться лог-файл узла

11

Page 12: Архитектура ROS

∙ _ip и _hostname — синонимы для ROS_IP и ROS_HOSTNAME

∙ _master — синоним для ROS_MASTER_URI

∙ _ns — синоним для ROS_NAMESPACE

3.2.2 Темы

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

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

Темы в ROS могут передаваться, используя TCP/IP и UDP. Основанная наTCP/IP передача называется TCPROS и использует постоянное TCP/IP соеди-нение. Это используемый по умолчанию тип передачи в ROS.

Передача, основанная на UDP, называется UDPROS. Это передача с низкойзадержкой. Лучше всего подходит для задач дистанционного управления.

В ROS есть инструмент для работы с темами, называемый rostopic. Это инстру-мент командной строки, который дает информацию о теме или публикует данныенепосредственно в сети.

Этот инструмент имеет следующие параметры:

∙ rostopic bw /topic — отображает ширину канала данных, используемую темой

∙ rostopic echo /topic — отображает сообщения на экране

∙ rostopic find meggage_type — ищет темы по их типу

∙ hz /topic — отображает скорость публикации темы

∙ rostopic info /topic — информация об активной теме, опубликованных темах,подписчиках и сервисах

∙ rostopic list — информация об активных темах

∙ rostopic pub /topic type args — публикует данные к теме. Позволяет создаватьи публиковать данные в желаемую тему, прямо из командной строки

∙ rostopic type /topic — отображает тип темы, то есть тип сообщения, которыйона выдает.

12

Page 13: Архитектура ROS

3.2.3 Сервисы

Когда необходимо обмениваться сообщениями с узлами и получать от них от-вет, то это нельзя сделать, используя темы. Для этого нужны сервисы.

Сервисы разрабатываются пользователем и для узлов не существует стандарт-ных сервисов. Файлы с исходным кодом сообщений хранятся в папке srv.

Как и темы, сервисы имеют соответствующий тип, который является файломс расширением .srv для названия пакета источника. Как и с другими основнымитипами файловой системы ROS, тип сервиса предсталяет собой имя пакета и имя.srv файла. Например, файл roboschool_tutorials/srv/roboschool_srv1.srv имеет типсервиса roboschool_tutorials/roboschool_srv1.

В ROS есть два инструмента командной строки для работы с сервисами, rossrvи rosservice. С rossrv мы можем понять информацию о структуре данных сервисови он используется также как и rosmsg.

С rosservice мы можем перечислять и запрашивать сервисы. Поддерживаемыекоманды:

∙ rosservice call /service args — вызывает сервис, используя указанные параметры

∙ rosservice find msg-type — ищет сервисы по типу сервиса

∙ rosservice info /service — информация о сервисе

∙ rosservice list — список активных сервисов

∙ rosservice type /service — тип сервиса

∙ rosservice uri /service — отображает сервис ROSRPC URI

3.2.4 Сообщения

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

Типы сообщений используют следующие стандартные соглашения об именахROS: имя пакета, затем прямой слеш и имя .msg файла.Например, std_msgs/msg/String.msg имеет тип сообщения std_msg/String.

В ROS есть иструмент командной строки rosmsg для получения информации осообщениях.

Используемые параметры:

∙ rosmsg show — отображает поля сообщения

∙ rosmag list — список всех сообщений

∙ rosmsg package — список всех сообщений в пакете

∙ rosmsg packages — список всех пакетов, в которых есть сообщение

∙ rosmsg users — ищет файлы с кодом, которые используют тип сообщиения

∙ rosmsg md5 — отображает MD5 сумму сообщения

13

Page 14: Архитектура ROS

3.2.5 Бэги

Бэг - файл, созданный ROS с расширением .bag для сохранения всей инфор-мации сообщений, тем, сервисов и так далее. Эти данные можно использоватьдля визуализации, можно воспроизводить, останавливать, перематывать и произ-водить другие операции.

Бэг-файл может быть воспроизведен в ROS как реальный сеанс, посылая темыодновременно с теми же данными. Обычно, мы используем эту функциональностьдля отладки алгоритмов.

Для использования бэг-фалов в ROS есть следующие инструменты:

∙ rosbag — используется для записи, воспроизведения и других операций

∙ rxbag — используется для визуализации данных в графическом окружении

∙ rostopic — помогает выяснить темы, отправленные в узлы

3.2.6 Мастер

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

Мастер также обеспечивает сервер параметров. Мастер, в общем случае, за-пускается, используя команду roscore, которая загружает мастер ROS наряду сдругими основными компонентами.

3.2.7 Сервер параметров

Сервер параметров является используемым совместно многомерным словарем,доступным через сеть. Узлы используют этот сервер для хранения и извлеченияпараметров во время выполнения.

Сервер параметров реализуется, используя XML-RPC и запускается внутримастера ROS. Это означает. что его API доступны из обычных XMLRPC библио-тек.

Сервер параметров использует типы данных XMLRPC для значений парамет-ров, включая следующие:

∙ 32-bit integer

∙ Boolean

∙ String

∙ Double

∙ ISO 8601 date

∙ List

14

Page 15: Архитектура ROS

∙ Base 64-encoded binary data

В ROS для работы с сервером параметров имеется инструмент rosparam. Под-держиваемые параметры:

∙ rosparam list — списки всех параметров на сервере

∙ rosparam get parameter — получает значение параметра

∙ rosparam set param value — устанавливает значение параметра

∙ rosparam delete parameter — удаляет параметр

∙ rosparam dump file — сохраняет сервер параметров в файл

∙ rosparam load file — загружает файл (с параметрами) на сервер параметров

3.3 Уровень сообщества ROS

Уровень сообщества ROS представляет собой ресурсы ROS, которые позволяютотдельным сообществам обмениваться ПО и знаниями. Эти ресурсы включают:

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

∙ Репозитории — ROS опирается на объединенную сеть репозиториев кода,где различные разработчики могут разрабатывать и выпускать компонентыПО их собственных роботов.

∙ ROS Wiki — ROS Wiki является основным форумом для документированияинформации по ROS. Любой может зарегистрироваться и распространятьсвою собственную документацию, производить корректировки или выпус-кать обновления, создавать учебные пособия и прочее.

∙ Списки почтовых ящиков — Списки почтовых ящиков пользователейROS являются главным каналом получения информации о новых обновле-ниях ROS аналогично форуму с вопросами по ROS.

4 Практические примеры

4.1 Навигация по файловой системе ROS

В ROS есть несколько инструментов командной строки для навигации по фай-ловой системе.

Для получения информации и перехода к пакетам и стекам используютсяrospac, rosstack, roscd и rosls.

15

Page 16: Архитектура ROS

rospack и rosstack используются для получения информации о пакетах и стеках,путях, зависимостях и т.д.

Например, если вы хотите найти путь к пакету turtlesim, необходимо написатьв командной строке:

$ rospack find turtlesim

Вы получите в ответ следующее:

/opt/ros/indigo/share/turtlesim

То же самое происходит со стеками, установленными в системе. Пример:

$ rosstack find ’имя_стека’

Для получения списка файлов, внутри пакета или стека, используйте

$ rosls turtlesim

После этого вы увидите следующее:

cmake images msg package.xml srv

Если вы хотите перейти внутрь папки, то вам необходимо использовать roscd сле-дующим образом:

$ roscd turtlesim$ pwd

В ответ вы полусите следующий новый путь:

/opt/ros/indigo/share/turtlesim

4.2 Создание собственного рабочего пространства

Перед тем как что-либо делать, необходимо создать собственное рабочее про-странство. В этом рабочем пространстве у вас будет весь код, который вы созда-дите.

Чтобы посмотреть, какое рабочее пространство использует ROS, необходимовыполнить следующую команду:

$ echo $ROS_PACKAGE_PATH

Вы увидите что-то типа:

/opt/ros/indigo/share:/opt/ros/indigo/stacks

Папка, которую мы собираемся создать находится в /dev/roboschool/. Для добав-ления этой папки, используем следующие строки:

$ cd ~$ mkdir -p dev/roboschool

16

Page 17: Архитектура ROS

Как только папка будет создана, нам необходимо добавить этот новый путь вROS_PACKAGE_PATH. Чтобы это сделать, нам нужно только добавить новуюстроку в конец файла /baschrc:

$ echo "export ROS_PACKAGE_PATH="~/dev/roboschool:${ROS_PACKAGE_PATH}"" >>~/.bashrc$ . ~/.bashrc

Проверяем новое значение переменной окружения:

$ echo $ROS\_PACKAGE\_PATH

Теперь у нас есть новая папка, созданная и сконфигурированная для работы сROS.

4.3 Создание пакета ROS

Как уже говорилось ранее, вы можете создать пакет вручную. Но для того,чтобы избежать скучной работы, мы используем инструмент командной строкиroscreate-pkg

Мы создадим новый пакет в подготовленной ранее папке, используя следующиестроки:

$ cd ~/dev/roboschool$ roscreate-pkg architect_tutorials std_msgs rospy roscpp

Формат этой команды включает имя пакета и зависимости, которые использу-ются этим пакетом. В нашем случае, это std_msgs, rospy и roscpp. Это показано вследующей командной строке:

roscreate-pkg [package_name] [depend1] [depend2] [depend3]

Зависимости включают:

∙ std_msgs - содержит общие типы сообщений, представленные примитивнымитипами данных и другими базовыми конструкциями сообщений, такими какмногомерные массивы.

∙ rospy - это клиентская библиотека Python для ROS

∙ rospy - это C++ реализация ROS. Она обеспечивает клиентскую библиотеку,подключаемую программистами на C++ для быстроко интерфейса с темами,сервисами и параметрами ROS.

Если все сделано правильно, вы увидите на экране что-то типа этого:

17

Page 18: Архитектура ROS

Как мы говорили ранее, вы можете использовать команды rospack, roscd и roslsдля получения информации о новом пакете:

∙ rospack find architect_tutorials - эта команда помогает нам найти путь

∙ rospack depends architect_tutorials - эта команда позволяет посмотреть зави-симости

∙ rosls architect_tutorials - команда позволяет посмотреть содержимое

∙ roscd architect_tutorials - меняет текущий путь

4.4 Компиляция пакета ROS

Как только ваш пакет создан, необходимо выполнить компиляцию пакета.

$ rosmake architect_tutorials

После выполнения операции, вы увидите что-то вроде:

18

Page 19: Архитектура ROS

Если не произойдет каких-то ошибок, пакет будет откомпилирован.

4.5 Работаем с узлами ROS

Узлы являются исполняемыми программами, и эти исполняемые файлы нахо-дятся в директории имя_пакета/bin. Чтобы попрактиковаться и изучить работу сузлами, мы используем пакет под названием turtlesim.

Перед тем, как начать работать, необходимо выполнить:

$ roscore

Результат выглядит примерно так:

Установим простенький симулятор (если он не установлен заранее):

19

Page 20: Архитектура ROS

$ sudo apt-get install ros-indigo-ros-tutorials

Для получения информации об узлах существует инструмент rosnode. Чтобыпосмотреть, какие у этой команды есть параметры, открываем новое окно Те-ринала и выполняем в нем команду:

$ rosnode

Вы увидите список возможных параметров как показано ниже:

Если вам требуется более подробное описание, как использовать эти парамет-ры, используйте следующий формат:

$ rosnode имя_параметра -h

Теперь, когда roscore запущен, мы собираемся получить информацию о запу-щенных узлах:

$ rosnode list

Вы увидите, что выполняется только узел /rosout. Это нормально, потому чтоэтот узел выполняется вместе с roscore.

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

$ rosnode info$ rosnode ping$ rosnode machine$ rosnode kill

Запустим новый узел, используя rosrun:

$ rosrun turtlesim turtlesim_node

20

Page 21: Архитектура ROS

Должно открыться новое окно с маленькой черепашкой в центре.

Если теперь посмотреть на список узлов, то мы увидим в нем узел с именем/turtlesim.

Информацию об узле можно посмотреть, используя rosnode info имя_узла. Выможете увидеть большое количество информации, которую можно использоватьдля отладки ваших программ:

$ rosnode info /turtlesimNode [/turtlesim]Publications:* /turtle1/color_sensor [turtlesim/Color]* /rosout [rosgraph_msgs/Log]* /turtle1/pose [turtlesim/Pose]

Subscriptions:* /turtle1/cmd_vel [unknown type]

Services:* /turtle1/teleport_absolute* /turtlesim/get_loggers* /turtlesim/set_logger_level* /reset* /spawn* /clear* /turtle1/set_pen* /turtle1/teleport_relative* /kill

contacting node http://hp-notebook:60243/ ...Pid: 7997Connections:

21

Page 22: Архитектура ROS

* topic: /rosout* to: /rosout* direction: outbound* transport: TCPROS

Здесь мы можем увидеть публикации (тем), описания (тем) и сервисы (srv),которые есть у узла, а также уникальные имена каждого.

Теперь давайте посмотрим, как взаимодействовать с узлами, используя темыи сервисы.

4.6 Взаимодействие с темами

Для взаимодействия и получения информации о темах используется инстру-мент rostopic, имеющий следующие параметры:

∙ rostopic bw - Отображает ширину полосы данных, используемую темой

∙ rostopic echo - Выводит сообщения на экран

∙ rostopic find - Ищет темы по их типу

∙ rostopic hz - Отображает скорость публикации тем

∙ rostopic info - Выводит информацию об активных темах

∙ rostopic list - Список активных тем

∙ rostopic pub - Публикует данные в тему

∙ rostopic type - Выводит тип темы

Если вы хотите посмотреть больше информаии об этих параметрах, исполь-зуйте -h:

$ rostopic bw -h

Используя параметр pub, мы можем публиковать темы, на которые может под-писаться любой узел. Нам нужно лишь опубликовать тему с корректным именем.

Используем узел, который необходим для управления. Запустим в новом окнеТерминала:

$ rosrun turtlesim turtle_teleop_key

Мы можем двигать черепашку, используя клавиши со стрелками.

22

Page 23: Архитектура ROS

Как черепашка движется во время выполнения turtle_teleop_key?Если вы хотите увидеть информацию об узлах /teleop_turtle и /turtlesim, мы

можем посмотреть на следующий код, который находится в теме, под названием* /turtle1/ cmd_vel [geometry_msgs/Twist] в разделе Publications первого узла. Вразделе Subscriptions второго узла есть * /turtle1/cmd_vel [geometry_msgs/Twist]:

$ rosnode info /teleop_turtleNode [/teleop_turtle]Publications:* /turtle1/cmd_vel [geometry_msgs/Twist]...

$ rosnode info /turtlesimNode [/turtlesim]...Subscriptions:* /turtle1/cmd_vel [geometry_msgs/Twist]

...

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

turtlesim_node и узел turtle_teleop обмениваются информацией посредством темROS. turtle_teleop_key публикует клавиши перемещения в теме, в то время какturtlesim подписан на ту же самую тему для получения клавиш перемещения.Можно использовать rqt_graph, который показывает выполняющиеся в настоя-щий момент узлы и темы.

rqt_graph создает динамический граф того, что происходит в системе. rqt_graphявляется частью пакета rqt. Если rqt_graph еще не установлен в системе, выпол-ните:

23

Page 24: Архитектура ROS

$ sudo apt-get install ros-indigo-rqt$ sudo apt-get install ros-indigo-rqt-common-plugins

В новом окне Теринала выполним следующую команду:

$ rosrun rqt_graph rqt_graph

У вас должно появиться похожее окно:

Если переместить указатель мыши на /turtle1/cmd_vel, то это выделит узлыROS (здесь - синим и зеленым цветом) и темы (здесь - красным цветом). Как выможете видеть, /teleop_turtle обменивается информацией с /turtlesim, используятему /turtle1/cmd_vel.

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

$ rostopic echo /turtle1/cmd_vel

Вы увидите что-то похожее на следующее:

linear:x: -2.0y: 0.0z: 0.0angular:

x: 0.0y: 0.0z: 0.0---linear:

x: 0.0y: 0.0z: 0.0

24

Page 25: Архитектура ROS

angular:x: 0.0y: 0.0z: 2.0---

Вновь вернемся с rqt_graph. В левом верхмем углу нажмите кнопку «Обно-вить» для отображения нового узла.

Как видно, показанный здесь красным rostopic echo, также теперь подписан натему turtle1/cmd_vel.

Вы можете посмотреть список тем, на которые подписаны и которые опубли-кованы, используя следующую строку кода:

$ rostopic list

/rosout/rosout_agg/turtle1/cmd_vel/turtle1/color_sensor/turtle1/pose

Посмотреть тип сообщения, отправленного темой, можно используя следую-щую команду:

$ rostopic type /turtle1/cmd\_vel

geometry_msgs/Twist

Если вам необходимо восмотреть поля сообщения, выполните:

$ rosmsg show geometry_msgs/Twist

geometry_msgs/Vector3 linearfloat64 xfloat64 yfloat64 z

geometry_msgs/Vector3 angularfloat64 xfloat64 yfloat64 z

25

Page 26: Архитектура ROS

Это полезные инструменты, потому что, используя эту информацию, мы мо-жем публиковать темы, используя команду rostopic pub [topic] [msg_type] [args]

$ rostopic pub -1 /turtle1/cmd_vel geometry_msgs/Twist -- ’[3.0, 0.0, 0.0]’ ’[0.0, 0.0, 2]’

Вы увидите черепашку, создающую кривую.

Эта команда отправляет единственное сообщение в turtlesim, в котором содер-жится информация о том, что необходимо двигаться с линейной скоростью равной3.0 и угловой скоростью равной 2.0.

Разберем эту команду по частям:

∙ rostopic pub — публикуем сообщение в данной теме

∙ -1 — публиковать только одно сообщение, затем выйти

∙ /turtle1/cmd_vel — имя темы, в которую публиковать

∙ geometry_msgs/Twist — тип сообщения, который использовался при публи-кации темы

∙ - - — двойное тире сообщает анализатору синтаксиса, что ни один из следу-ющих аргументов не является параметром. Это необходимо в тех случаях,когда в аргумент входит дефис, например в отрицательных числах.

∙ ’[3.0, 0.0, 0.0]’ ’[0.0, 0.0, 2]’ — сообщение geometry_msgs/Twist имеет два век-тора: linear и angular, каждый из которых состоит из трех числовых элементовc плавающей точкой. В нашем случае, ’[3.0, 0.0, 0.0]’ становится линейнымзначением с x=3, y=0, z=0 и ’[0.0, 0.0, 2]’ является угловым значением с x=0,y=0, z=2. Эти аргументы имеют YAML синтаксис.

26

Page 27: Архитектура ROS

4.7 Использование сервисов

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

Для взаимодействия с сервисами используется инструмент rosservice. Парамет-ры для этой команды:

∙ rosservice args /service - Отображает аргументы сервиса

∙ rosservice call /service - Вызывает сервис с представленными аргументами

∙ rosservice find msg-type - Ищет сервисы по их типу

∙ rosservice info /service - Выводит информацию о сервисе

∙ rosservice list - Список активных сервисов

∙ rosservice type /service - Отображает тип сервиса

∙ rosservice uri /service - Выводит ROSPRC URI сервиса

Для получения списка доступных сервисов для узла turtlesim, используется сле-дующий код. Если он не заработает, выполните roscore и запустите узел turtlesim.

$ rosservice list

Вы увидите следующее:

/clear/kill/reset/rosout/get_loggers/rosout/set_logger_level/rostopic_9126_1412423515462/get_loggers/rostopic_9126_1412423515462/set_logger_level/rqt_gui_py_node_8979/get_loggers/rqt_gui_py_node_8979/set_logger_level/spawn/teleop_turtle/get_loggers/teleop_turtle/set_logger_level/turtle1/set_pen/turtle1/teleport_absolute/turtle1/teleport_relative/turtle2/set_pen/turtle2/teleport_absolute/turtle2/teleport_relative/turtlesim/get_loggers/turtlesim/set_logger_level

Рабочий стол при этом выглядит примерно таким образом:

27

Page 28: Архитектура ROS

Для того, чтобы посмотреть тип любого сервиса, например, сервиса /clear:

$ rosservice type /clear

Вы увидите:

std_srvs/Empty

Для вызова сервиса используйте rosservice call [service] [args]. Если вы хотитезапустить сервис /clear:

$ rosservice call /clear

В окне turtlesim вы увидите, что линии, созданные движением черепашкибудут удалены.

Теперь попробуйем другой сервис, например, сервис /spawn. Этот сервис со-здаст другую черепашку в другом месте, с другой пространственной ориентацией.

$ rosservice type /spawn | rossrv show

Увидим следующее:

float32 xfloat32 yfloat32 thetastring name---string name

Используя эти поля, мы знаем как запустить сервис. Нам необходимы коорди-наты x и y, ориентация theta и имя новой черепашки:

$ rosservice call /spawn 3.0 3.0 0.2 "new_turtle"

28

Page 29: Архитектура ROS

Увидим следующий результат:

4.8 Использование сервера параметров

Сервер параметров используется для хранения данных, доступных любым уз-лам. В ROS имеется инструмент для управления сервером параметров под назва-нием rosparam. Параметры:

∙ rosparam set parameter value - устанавливает параметр

∙ rosparam get parameter - получает параметр

∙ rosparam load file - загружает параметры из файла

∙ rosparam dump file - выгружает параметры в файл

∙ rosparam delete parameter - удаляет параметр

∙ rosparam list - список имен параметров

Например, мы можем посмотреть параметры на сервере, которые используютсявсеми узлами:

$ rosparam list

На выходе получим:

29

Page 30: Архитектура ROS

/background_b/background_g/background_r/rosdistro/roslaunch/uris/host_hp_notebook__48988/rosversion/run_id

Параметры background принадлежат узлу turtlesim. Эти параметры изменяютцвет окон, который изначально голубой. Если вы хотите считать значение, исполь-зуйте параметр get:

$ rosparam get /background_b

Для установки нового значения, используйте параметр set:

$ rosparam set /background_b 100

Для того, чтобы изменный параметр начал действовать, необходимо вызватьсервис clear:

$ rosservice call clear

Если нам нужно посмотреть содержимое всего сервера параметров, то для это-го используется команда rosparam get /:

$ rosparam get /

Другим важным свойством rosparam является параметр dump. Используя этотпараметр, мы можем загружать или сохранять содержимое сервера параметров.

Для сохранения сервера параметров используйте rosparam dump [file_name][пространство_имен]:

$ rosparam dump save.yaml

Для загрузки файла с новыми данными на сервер параметров используйтеrosparam load [file_ name] [пространство_имен]:

$ rosparam load load.yaml пространство_имен

Пример: загрузим сохраненный сервер параметров в новое пространство имен,например copy:

$ rosparam load save.yaml copy$ rosparam get copy/background_b

100

30

Page 31: Архитектура ROS

4.9 Создание узлов

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

$ roscd architect_tutorials/src/

Создадим файл example1_a.cpp, который будет посылать данные по имени узлаи файл example1_b.cpp, который будет показывать данные в оболочке.

Скопируйте следующий код в файл example1_a.cpp:

#include "ros/ros.h"#include "std_msgs/String.h"#include <sstream>

int main(int argc, char **argv){

ros::init(argc, argv, "example1_a");ros::NodeHandle n;ros::Publisher chatter_pub = n.advertise<std_msgs::String>("message", 1000);

ros::Rate loop_rate(10);while (ros::ok()){

std_msgs::String msg;std::stringstream ss;ss << " I am the example1_a node ";msg.data = ss.str();//ROS_INFO("%s", msg.data.c_str());chatter_pub.publish(msg);ros::spinOnce();loop_rate.sleep();

}return 0;

}

Несколько пояснений к коду. В заголовке подключаются библиотеки ros/ros.h,std_msgs/String.h и sstream. Здесь ros/ros.h включает все необходимые файлы дляиспользования узла с ROS и std_msgs/String.h включает заголовок, который обо-значает тип сообщения, которое мы собираемся использовать:

#include "ros/ros.h"#include "std_msgs/String.h"#include <sstream>

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

31

Page 32: Архитектура ROS

ros::init(argc,argv,"example1_a");

Следом идет обработчик нашего процесса:

ros::NodeHandle n;

Устанавливаем издателя и сообщаем мастеру имя и тип темы. Имя message ивторой параметр является размером буфера. Если тема быстро публикует данные,буфер будет содержать 1000 сообщений:

ros::Publisher chatter_pub = n.advertise<std_msgs::String>("message", 1000);

Установим частоту отправки данных, в этом случае, равную 10 Гц:

ros::Rate loop_rate(10);

Библиотека ros::ok() останавливает узел, если он принимает нажатие клавишCtrl+C или если ROS останавливает все узлы:

while (ros::ok()){

Далее создается переменная для сообщения с корректным типом отправляемыхданных:

std_msgs::String msg;std::stringstream ss;ss << " I am the example1_a node ";msg.data = ss.str();

Публикация сообщения:

chatter_pub.publish(msg);

Далее, у нас есть подписчик, где ROS обновляет и читает все темы:

ros::spinOnce();

Необходимое время для паузы, чтобы получить частоту 10 Гц:

loop_rate.sleep();

Скопируйте следующий код в файл example_b.cpp:

32

Page 33: Архитектура ROS

#include "ros/ros.h"#include "std_msgs/String.h"

void chatterCallback(const std_msgs::String::ConstPtr& msg){ROS_INFO("I heard: [%s]", msg->data.c_str());}

int main(int argc, char **argv){

ros::init(argc, argv, "example1_b");ros::NodeHandle n;ros::Subscriber sub = n.subscribe("message", 1000, chatterCallback);ros::spin();return 0;

}

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

#include "ros/ros.h"#include "std_msgs/String.h"

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

ROS_INFO() is used to print it in the shell.void messageCallback(const std_msgs::String::ConstPtr& msg){

ROS_INFO("I heard: [%s]", msg->data.c_str());}

Создаем подписчика и «слушаем» тему с именем message. Буфер будет 1000 ифункция-обработчик сообщения будет messageCallback:

ros::Subscriber sub = n.subscribe("message", 1000, messageCallback);

Библиотека ros::spin() является циклом, где узел начинает читать тему и затемприходит сообщение, называемое messageCallback. Когда пользователь нажимаетCtrl+C, узел выходит из цикла и цикл завершается:

ros::spin();

33

Page 34: Архитектура ROS

4.10 Компиляция узла

Так как мы используем пакет architect_tutorials, нам нужно отредактироватьфайл CMakeLists.txt. Для этого вы можете использовать текстовый редактор илииспользовать инструмент rosed. Он открывает файл в редакторе Vim:

$ rosed architect_tutorials CMakeLists.txt

В конец файла копируем следующие строки кода:

rosbuild_add_executable(example1_a src/example1_a.cpp)rosbuild_add_executable(example1_b src/example1_b.cpp)

Эти строки создадут два исполняемых файла в папке /bin.Теперь для построения пакета и компиляции всех узлов используем инструмент

rosmake:

$ rosmake architect_tutorials

Если ROS не запущена на вашем компьютере, используйте:

$ roscore

Вы можете проверить запущена ли ROS, испльзуя команду rosnode list:

$ rosnode list

Теперь запустим оба узла в различных оболочках:

$ rosrun architect_tutorials example1_a$ rosrun architect_tutorials example1_b

Если вы проверите оболочку, где запущен узел example1_b, вы увидите что-тотипа:

...[ INFO] [1355228542.283236850]: I heard: [ I am the example1_a node ][ INFO] [1355228542.383221843]: I heard: [ I am the example1_a node ][ INFO] [1355228542.483249861]: I heard: [ I am the example1_a node ]...

Все что происходит, проиллюстрировано ниже на рисунке. Узел example_1 пуб-ликует тему message и узел example_2 подписан на тему.

Вы можете использовать rosnode и rostopic для отладки и контроля за тем, чтоделает узел.

Попробуйте следующие команды:

34

Page 35: Архитектура ROS

$ rosnode list$ rosnode info /example1_a$ rosnode info /example1_b$ rostopic list$ rostopic info /message$ rostopic type /message$ rostopic bw /message

4.11 Создание файлов msg и srv

msg и srv являются файлами, содержащие определения типов передаваемыхданных и сами данные. ROS использует эти файлы для создания необходимогокода для нас.

В примере из предыдущего раздела «Компиляция узла» мы создали два узластандартного типа mesaage. Теперь мы создадим пользовательские сообщения припомощи инструментов, имеющихся в ROS.

Во-первых, создадим новую папку msg в нашем пакете architect_tutorials и со-здадим новый файл architect_msg1.msg, добавив в него следующие строки:

int32 Aint32 Bint32 C

Теперь отредактируем CMakeLists.txt, удалим # из строки # rosbuild_genmsg(),и откомпилируем пакет, используя rosmake:

$ rosmake architect_tutorials

Для проверки все ли нормально, можно использовать команду rosmsg:

$ rosmsg show architect_tutorials/architect_msg1

Если вы увидите то же содержимое что и в файле architect_msg1.msg, то всенормально.

Создадим файл srv. Для этого создадим новую папку с именем srv в папкеarchitect_tutorials и создадим новый файл architect_srv1.srv, добавив следующиестроки:

int32 Aint32 Bint32 C---int32 sum

Отредактируем CMakeList.txt и удалим # из строки # rosbuild_gensrv() и от-компилируем пакет, используя rosmake architect_tutorials.

Для проверки все ли нормально, используем инструмент rossrv:

$ rossrv show architect_tutorials/architect_srv1

Если вы увидите то же содержимое, что и в файле architect_srv1.srv, то всенормально.

35

Page 36: Архитектура ROS

4.12 Использование новых файлов srv и msg

Теперь разберем как создать сервис и как использовать его в ROS. Наш сервисбудет вычислять сумму трех чисел. Нам нужно два узла: клиент и сервер.

В пакете architect_tutorials создадим два новых узла с именами example2_a.cppи example2_b.cpp. Файлы необходимо поместить в папку src.

В файл example2_a.cpp добавляем следующий код:

#include "ros/ros.h"#include "chapter2_tutorials/chapter2_srv1.h"

bool add(chapter2_tutorials::chapter2_srv1::Request &req,chapter2_tutorials::chapter2_srv1::Response &res){

res.sum = req.A + req.B + req.C;ROS_INFO("request: A=%ld, B=%ld C=%ld", (int)req.A, (int)req.B,(int)req.C);ROS_INFO("sending back response: [%ld]", (int)res.sum);return true;

}

int main(int argc, char **argv){ros::init(argc, argv, "add_3_ints_server");ros::NodeHandle n;ros::ServiceServer service = n.advertiseService("add_3_ints", add);ROS_INFO("Ready to add 3 ints.");ros::spin();return 0;}

Подключаем необходимые заголовки и созданный нами файл srv:

#include "ros/ros.h"#include "architect_tutorials/architect_srv1.h"

Следующая функция добавляет три переменные и отправляет результат в дру-гой узел:

bool add(architect_tutorials::architect_srv1::Request &req,architect_tutorials::architect_srv1::Response &res)

Далее создается сервис и оповещается ROS:

ros::ServiceServer service = n.advertiseService("add_3_ints", add);

В файл example2_b.cpp добавляем код:

36

Page 37: Архитектура ROS

#include "ros/ros.h"#include "architect_tutorials/architect_srv1.h"#include <cstdlib>

int main(int argc, char **argv){ros::init(argc, argv, "add_3_ints_client");if (argc != 4){

ROS_INFO("usage: add_3_ints_client A B C ");return 1;

}ros::NodeHandle n;ros::ServiceClient client = n.serviceClient<architect_tutorials::architect_srv1>("add_3_ints");architect_tutorials::architect_srv1 srv;srv.request.A = atoll(argv[1]);srv.request.B = atoll(argv[2]);srv.request.C = atoll(argv[3]);if (client.call(srv)){

ROS_INFO("Sum: %ld", (long int)srv.response.sum);}else{

ROS_ERROR("Failed to call service add_3_ints");return 1;

}return 0;

}

Создаем клиента для сервиса с именем add_3_ints:

ros::ServiceClient client = n.serviceClient<architect_tutorials::architect_srv1>("add_3_ints");

Здесь мы создаем экземпляр нашего файла srv и заполняем все значения дляотправки. Сообщением имеет три поля:

architect_tutorials::architect_srv1 srv;srv.request.A = atoll(argv[1]);srv.request.B = atoll(argv[2]);srv.request.C = atoll(argv[3]);

Этими строками кода вызывается сервис и отправляются данные. Если вызовпрошел успешно, call() вернет true, если же нет - call() вернет false:

if (client.call(srv))

37

Page 38: Архитектура ROS

Для компиляции нового в файл CMakeList.txt добавим следующие строки:

rosbuild_add_executable(example2_a src/example2_a.cpp)rosbuild_add_executable(example2_b src/example2_b.cpp)

Выполняем команду:

$ rosmake architect_tutorials

Для запуска узлов выполняем в двух оболочках следующие строки команд:

$rosrun architect_tutorials example2_a$rosrun architect_tutorials example2_b 1 2 3

После этого, вы должны увидеть следущее:

Node example2_a[ INFO] [1355256113.014539262]: Ready to add 3 ints.[ INFO] [1355256115.792442091]: request: A=1, B=2 C=3[ INFO] [1355256115.792607196]: sending back response: [6]Node example2_b[ INFO] [1355256115.794134975]: Sum: 6

Теперь создадим узлы, используя наш пользовательский файл msg. В качествепримера опять же берем example1_a.cpp, но уже с новым сообщением architect_msg1.msg

Следующий фрагмент кода представляет содержимое файла example3_a.cpp:

#include "ros/ros.h"#include "architect_tutorials/architect_msg1.h"#include <sstream>

int main(int argc, char **argv){

ros::init(argc, argv, "example1_a");ros::NodeHandle n;ros::Publisher pub = n.advertise<architect_tutorials::architect_

msg1>("message", 1000);ros::Rate loop_rate(10);while (ros::ok()){architect_tutorials::architect_msg1 msg;msg.A = 1;msg.B = 2;msg.C = 3;pub.publish(msg);ros::spinOnce();loop_rate.sleep();

}return 0;}

38

Page 39: Архитектура ROS

Ниже приведено содержимое файла example3_b.cpp:

#include "ros/ros.h"#include "architect_tutorials/architect_msg1.h"

void messageCallback(const architect_tutorials::architect_msg1::ConstPtr& msg){

ROS_INFO("I heard: [%d] [%d] [%d]", msg->A, msg->B, msg->C);}

int main(int argc, char **argv){

ros::init(argc, argv, "example1_b");ros::NodeHandle n;ros::Subscriber sub = n.subscribe("message", 1000, messageCallback);ros::spin();return 0;

}

Если мы запустим оба узла сейчас, то увидим что-то похожее:

...[ INFO] [1355270835.920368620]: I heard: [1] [2] [3][ INFO] [1355270836.020326372]: I heard: [1] [2] [3][ INFO] [1355270836.120367449]: I heard: [1] [2] [3][ INFO] [1355270836.220266466]: I heard: [1] [2] [3]...

5 ИтогВ ходе практического занятия вы получили общее представление об архитек-

туре ROS и том, как это работает. Мы рассмотрели некоторые концепции, инстру-менты и примеры взаимодействия с узлами, темами и сервисами.

Для более детального изучения на официальном сайте ROS есть пошаговыеруководства: http://wiki.ros.org/ROS/Tutorials

39