SlideShare a Scribd company logo
1 of 39
Download to read offline
Архитектура 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
Как правило, для всех поддерживаемых платформ публикуется большое коли- 
чество примеров, а также симуляторы, которые облегчают разработку собствен- 
ных проектов. 
В ROS также поддерживается множество различных датчиков и исполнитель- 
ных устройств (актуаторов), используемых в робототехнике. Каждый день появ- 
ляются новые устройства, совместимые с этим фреймворком. 
Рис. 2: ROS поддерживает различные исполнительные устройства 
В ROS имеются стандартные возможности операционной системы, такие как, 
аппаратная абстракция, управление устройствами на низком уровне, реализована 
часто используемая функциональность, передача сообщений между процессами, 
и управление библиотеками. Архитектура ROS основана не графе с централизо- 
ванной топологией. Обработка происходит в узлах, которые могут принимать или 
отправлять данные с датчиков, систем контроля состояния и планирования, при- 
водов, и так далее. Библиотека ориентирована на Unix-подобные системы (под 
Ubuntu Linux работает отлично, а Fedora и Mac OS X имеют статус эксперимен- 
тальных). 
Пакет *-ros-pkg является является общим репозиторием для разработки вы- 
сокоуровневых библиотек. Многие из возможностей часто ассоциируемые с ROS, 
такие как библиотеки навигации и визуализатор rviz, хранятся в этом репози- 
тории. Эти библиотеки предоставляют мощный набор инструментов (различные 
визуализаторы, симуляторы, средства отладки) для упрощения работы. 
Рис. 3: ROS позволяет наблюдать за тем, что происходит на каждом шаге 
ROS распространяется на условиях лицензии BSD и является ПО с открытым 
исходным кодом. ROS бесплатна для исследовательских и коммерческих целей. 
ROS способствует повторному использованию кода, так что разработчики робото- 
техники и ученые могут не изобретать колесо постоянно. Можно получить код из 
2
репозитория, изменить его и вновь поделиться улучшенным ПО. Вы также можете 
написать драйвер вашего собственного датчика для ROS. 
ROS поддерживает параллельные вычисления, имеет хорошую интеграцию 
с популярными C++ библиотеками, такими как как OpenCV, Qt, Point Cloud 
Library и пр., и она может работать на одноплатных компьютерах, таких как 
Raspberry Pi или BeagleBone Black, а также с микроконтроллерными платформа- 
ми, например, Arduino. Вы можете создать своего собственного робота на основе 
Arduino или Raspberry Pi и использовать для его управления Robot Operating 
System. 
Рис. 4: Интеграция ROS 
Время является очень важным ресурсом и ROS является одним из инструмен- 
тов, которые могут помочь разработать комплексное решение в кратчайшие сроки 
и с минимальными усилиями. Библиотека ROS поможет реализовать алгоритмы 
и сократить время, необходимое для интеграции целой кучи компонентов. 
3 Архитектура ROS 
В архитектуре ROS можно выделить три концептуальных уровня: 
∙ Уровень файловой системы (Filesystem level) 
∙ Уровень вычислительного графа (Computation Graph level) 
∙ Уровень сообщества (Community level) 
Первый уровень — это уровень файловой системы. На этом уровне располо- 
жена внутренняя структура ROS — структура папок, файлы, необходимые для 
работы. 
3
Второй уровень — это уровень вычислительного графа, на котором происходит 
взаимодействие между процессами и системами. На этом уровне находятся кон- 
цепции и модули, которые имеются в 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
Рис. 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
∙ 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
Пакеты в 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 id 
float32 vel 
string name 
В ROS имеется множество стандартных типов для использования в сообщени- 
ях. 
7
Простой тип данных Описание C++ Python 
bool Unsigned 8-bit int uint8_t bool 
int8 Signed 8-bit int int8_t int 
uint8 Unsigned 8-bit int uint8_t int 
int16 Signed 16-bit int int16_t int 
uint16 Unsigned 16-bit int uint16_t int 
int32 Signed 32-bit int int32_t int 
uint32 Unsigned 32-bit int uint32_t int 
int64 Signed 64-bit int int64_t long 
uint64 Unsigned 64-bit int uint64_t long 
float32 32-bit IEEE float float float 
float64 64-bit IEEE float double float 
string ASCII string (4 bit) std::string string 
time Secs/nsecs signed ros::Time rospy.Time 
32 bit int 
duration Secs/nsecs signed ros::Duration rospy.Duration 
32 bit int 
Специальным типом в ROS является Header. Он используется для добавления 
временных меток, кадров и так далее. Этот тип позволяет сообщениям быть про- 
нумерованными, таким образом, мы можем знать, кто отправил сообщение. Могут 
быть добавлены другие функции, прозрачные для пользователя, но управляемые 
ROS. 
Тип Header содержит следующие поля: 
uint32 seq 
time stamp 
string frame_id 
3.1.3 Сервисы 
ROS использует упрощенный язык описания сервисов для характеристики ти- 
пов сервисов. Он создается непосредственно из формата msg для обеспечения свя- 
зи запрос/ответ между узлами. Описания сервиса хранятся в .srv файлах в под- 
директории srv/ пакета. 
Для вызова сервиса необходимо использовать имя пакета вместе с именем сер- 
виса. Например, файлу sample_package1/srv/sample1.srv соответствует 
sample_package1/sample1. 
Есть несколько инструментов для работы с сервисами. Инструмент rossrv вы- 
водит описание сервиса, пакет содержащий .srv файлы и может найти файлы ис- 
точников, которые используют этот тип сервиса. 
Если вы хотите создать сервис, ROS может помочь вам генератором серви- 
сов. Эти инструменты генерируют код для начального определения сервиса. Вам 
только нужно добавить строку gensrv() в ваш файл CMakeLists.txt. 
8
3.2 Уровень вычислительного графа 
ROS создает сеть, в которой соединены все процессы. Любой узел в системе мо- 
жет получить доступ к этой сети, взаимодействовать с другими узлами, смотреть 
информацию, которую они посылают и передавать данные в сеть. 
Рис. 6: Структура уровня вычислительного графа 
Базовыми понятиями на этом уровне являются: узлы, мастер, сервер парамет- 
ров, сообщения, сервисы, темы и бэги. Все они различными способами обеспечива- 
ют граф данными. 
∙ Узлы (nodes): являются процессами, производящими вычисления. Если вам 
нужен процесс, который может взаимодействовать с другими узлами, вам 
нужно создать узел с этим процессом, подключив его к сети ROS. Обыч- 
но, система имеет множество узлов для управления различными функция- 
ми. Лучше иметь множество узкоспециализированных узлов, выполняющих 
единственную функцию, чем большой универсальный узел, который бы де- 
лал в системе все на свете. Узлы записываются в клиентскую библиотеку 
ROS. Примером могут служить roscpp или rospy. 
∙ Мастер (master): обеспечивает регистрацию имени и ищет оставшиеся узлы. 
Если его нет в системе, вы не сможете обмениваться информацией с узлами, 
сервисами, сообщениями и прочим. Мастер может быть на компьютере, где 
узлы работают с другими компьютерами. 
∙ Сервер параметров (parameter server): дает возможность сохранять дан- 
ные, используя ключи, размещенные централизованно. С этим параметром 
возможно конфигурировать узлы во время их работы или для изменения 
рабочего узла. 
∙ Сообщения(messages): узлы взаимодействуют друг с другом посредством 
сообщений. Сообщение содержит данные, передающие информацию другим 
узлам. ROS имеет много типов сообщений. Возможно разработать свой соб- 
ственный тип сообщения, используя стандартные сообщения. 
9
∙ Темы (topics): Каждое сообщение должно иметь имя, чтобы направляться 
в сети ROS. Когда узел является отправителем данных, мы говорим, что 
узел опубликовал тему. Узлы могут получить темы от других узлов, просто 
подписавшись на тему. Узел может подписаться на тему, и не обязательно, 
чтобы узел, который бы публиковал тему, должен в настоящий момент су- 
ществовать. Это позволяет отделить выпуск от потребления. Важно, чтобы 
название темы было уникальным, чтобы избежать проблем и недоразумений 
между темами с одинаковыми названиями. 
∙ Сервисы (services): при публикации темы, вы отправляете данные, имею- 
щие отношения многие-ко-многим, но когда вам нужно сделать запрос или 
получить ответ от узла, вы не можете сделать это, используя темы. Сервисы 
дают нам возможность взаимодействовать с узлами. Сервисы также должны 
иметь уникальное имя. Когда у узла есть сервис, все узлы могут общаться с 
ним, благодаря клиентским библиотекам ROS 
∙ Бэги (bags): формат для сохранения и воспроизведения данных сообщений 
ROS. Бэги являются важным механизмом для хранения данных, таких как 
данные сенсоров, которые сложно собирать, но они требуются для разра- 
ботки и тестирования алгоритмов. Бэги часто используются при работе со 
сложными роботами. 
На Рисунке 7 показано графическое представление уровня вычислительного 
графа. Это представление реального робота в реальных условиях. На графе есть 
узлы, темы, информация о том, на какие темы подписан узел и т.д. На этом графе 
не представлены сообщения, бэги, сервер параметров и сервисы. Для их графиче- 
ского представления требуются другие инструменты. Инструментом для создания 
графа является rxgraph. 
Рис. 7: Структура уровня вычислительного графа 
10
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
∙ _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
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
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
∙ 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
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
Как только папка будет создана, нам необходимо добавить этот новый путь в 
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
Как мы говорили ранее, вы можете использовать команды rospack, roscd и rosls 
для получения информации о новом пакете: 
∙ rospack find architect_tutorials - эта команда помогает нам найти путь 
∙ rospack depends architect_tutorials - эта команда позволяет посмотреть зави- 
симости 
∙ rosls architect_tutorials - команда позволяет посмотреть содержимое 
∙ roscd architect_tutorials - меняет текущий путь 
4.4 Компиляция пакета ROS 
Как только ваш пакет создан, необходимо выполнить компиляцию пакета. 
$ rosmake architect_tutorials 
После выполнения операции, вы увидите что-то вроде: 
18
Если не произойдет каких-то ошибок, пакет будет откомпилирован. 
4.5 Работаем с узлами ROS 
Узлы являются исполняемыми программами, и эти исполняемые файлы нахо- 
дятся в директории имя_пакета/bin. Чтобы попрактиковаться и изучить работу с 
узлами, мы используем пакет под названием turtlesim. 
Перед тем, как начать работать, необходимо выполнить: 
$ roscore 
Результат выглядит примерно так: 
Установим простенький симулятор (если он не установлен заранее): 
19
$ 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
Должно открыться новое окно с маленькой черепашкой в центре. 
Если теперь посмотреть на список узлов, то мы увидим в нем узел с именем 
/turtlesim. 
Информацию об узле можно посмотреть, используя rosnode info имя_узла. Вы 
можете увидеть большое количество информации, которую можно использовать 
для отладки ваших программ: 
$ rosnode info /turtlesim 
Node [/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: 7997 
Connections: 
21
* 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
Как черепашка движется во время выполнения turtle_teleop_key? 
Если вы хотите увидеть информацию об узлах /teleop_turtle и /turtlesim, мы 
можем посмотреть на следующий код, который находится в теме, под названием 
* /turtle1/ cmd_vel [geometry_msgs/Twist] в разделе Publications первого узла. В 
разделе Subscriptions второго узла есть * /turtle1/cmd_vel [geometry_msgs/Twist]: 
$ rosnode info /teleop_turtle 
Node [/teleop_turtle] 
Publications: 
* /turtle1/cmd_vel [geometry_msgs/Twist] 
... 
$ rosnode info /turtlesim 
Node [/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
$ 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.0 
y: 0.0 
z: 0.0 
angular: 
x: 0.0 
y: 0.0 
z: 0.0 
--- 
linear: 
x: 0.0 
y: 0.0 
z: 0.0 
24
angular: 
x: 0.0 
y: 0.0 
z: 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 linear 
float64 x 
float64 y 
float64 z 
geometry_msgs/Vector3 angular 
float64 x 
float64 y 
float64 z 
25
Это полезные инструменты, потому что, используя эту информацию, мы мо- 
жем публиковать темы, используя команду 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
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
Для того, чтобы посмотреть тип любого сервиса, например, сервиса /clear: 
$ rosservice type /clear 
Вы увидите: 
std_srvs/Empty 
Для вызова сервиса используйте rosservice call [service] [args]. Если вы хотите 
запустить сервис /clear: 
$ rosservice call /clear 
В окне turtlesim вы увидите, что линии, созданные движением черепашки 
будут удалены. 
Теперь попробуйем другой сервис, например, сервис /spawn. Этот сервис со- 
здаст другую черепашку в другом месте, с другой пространственной ориентацией. 
$ rosservice type /spawn | rossrv show 
Увидим следующее: 
float32 x 
float32 y 
float32 theta 
string name 
--- 
string name 
Используя эти поля, мы знаем как запустить сервис. Нам необходимы коорди- 
наты x и y, ориентация theta и имя новой черепашки: 
$ rosservice call /spawn 3.0 3.0 0.2 "new_turtle" 
28
Увидим следующий результат: 
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
/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
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
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
#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
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
$ 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 A 
int32 B 
int32 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 A 
int32 B 
int32 C 
--- 
int32 sum 
Отредактируем CMakeList.txt и удалим # из строки # rosbuild_gensrv() и от- 
компилируем пакет, используя rosmake architect_tutorials. 
Для проверки все ли нормально, используем инструмент rossrv: 
$ rossrv show architect_tutorials/architect_srv1 
Если вы увидите то же содержимое, что и в файле architect_srv1.srv, то все 
нормально. 
35
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
#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
Для компиляции нового в файл 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
Ниже приведено содержимое файла 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

More Related Content

What's hot

507.методическое пособие по дисциплине «информатика» ч1 программирование на я...
507.методическое пособие по дисциплине «информатика» ч1 программирование на я...507.методическое пособие по дисциплине «информатика» ч1 программирование на я...
507.методическое пособие по дисциплине «информатика» ч1 программирование на я...ivanov15548
 
курс Java 2016. занятие 03. интерфейсы, generic, исключения
курс Java 2016. занятие 03. интерфейсы, generic, исключениякурс Java 2016. занятие 03. интерфейсы, generic, исключения
курс Java 2016. занятие 03. интерфейсы, generic, исключения7bits
 
Linux
LinuxLinux
LinuxEzil
 
язык программирования
язык программированияязык программирования
язык программированияMihaNsx99
 
Операционная система Windows
Операционная система WindowsОперационная система Windows
Операционная система WindowsАнна Ефремова
 

What's hot (8)

507.методическое пособие по дисциплине «информатика» ч1 программирование на я...
507.методическое пособие по дисциплине «информатика» ч1 программирование на я...507.методическое пособие по дисциплине «информатика» ч1 программирование на я...
507.методическое пособие по дисциплине «информатика» ч1 программирование на я...
 
курс Java 2016. занятие 03. интерфейсы, generic, исключения
курс Java 2016. занятие 03. интерфейсы, generic, исключениякурс Java 2016. занятие 03. интерфейсы, generic, исключения
курс Java 2016. занятие 03. интерфейсы, generic, исключения
 
89
8989
89
 
Linux
LinuxLinux
Linux
 
язык программирования
язык программированияязык программирования
язык программирования
 
лекция 3
лекция 3лекция 3
лекция 3
 
Операционная система Windows
Операционная система WindowsОперационная система Windows
Операционная система Windows
 
Turbo pascal. toqrul
Turbo pascal. toqrulTurbo pascal. toqrul
Turbo pascal. toqrul
 

Viewers also liked

Дорожкина Н.Г. Промышленная робототехника
Дорожкина Н.Г. Промышленная робототехникаДорожкина Н.Г. Промышленная робототехника
Дорожкина Н.Г. Промышленная робототехникаfgos-igra
 
Курс делаем робота
Курс делаем роботаКурс делаем робота
Курс делаем роботаAnton Moiseev
 
Просторобот - мы делаем не только роботов!
Просторобот - мы делаем не только роботов!Просторобот - мы делаем не только роботов!
Просторобот - мы делаем не только роботов!Aleksandr Kazantcev
 
А. Ефимов. Робототехника в России.
А. Ефимов. Робототехника в России. А. Ефимов. Робототехника в России.
А. Ефимов. Робототехника в России. Skolkovo Robotics Center
 
Клуб Робототехники и ТехТворчества в IT Слободе
Клуб Робототехники и ТехТворчества в IT СлободеКлуб Робототехники и ТехТворчества в IT Слободе
Клуб Робототехники и ТехТворчества в IT СлободеGoodKarma.me
 
Заразительная робототехника на МикРобах
Заразительная робототехника на МикРобахЗаразительная робототехника на МикРобах
Заразительная робототехника на МикРобахАндрей Антонов
 
Чипы, платы, роботы
Чипы, платы, роботыЧипы, платы, роботы
Чипы, платы, роботыAnton Moiseev
 
Презентация на тему: Коммуникационные технологии
Презентация на тему: Коммуникационные технологииПрезентация на тему: Коммуникационные технологии
Презентация на тему: Коммуникационные технологии2berkas
 
цифровое производство плоских деталей
цифровое производство плоских деталейцифровое производство плоских деталей
цифровое производство плоских деталейAnton Moiseev
 
Робототехника в школьном образовании - Robotics Expo
Робототехника в школьном образовании - Robotics ExpoРобототехника в школьном образовании - Robotics Expo
Робототехника в школьном образовании - Robotics ExpoAnton Moiseev
 
Робототехника
Робототехника Робототехника
Робототехника budu_arrr
 
Устройство Robotiki и ScratchDuino
Устройство Robotiki и ScratchDuinoУстройство Robotiki и ScratchDuino
Устройство Robotiki и ScratchDuinoAnton Moiseev
 
робототехника - проблемы и перспективы (СМП-2014)
робототехника - проблемы и перспективы (СМП-2014)робототехника - проблемы и перспективы (СМП-2014)
робототехника - проблемы и перспективы (СМП-2014)Alexander Petrov
 
Promo presentation for robotics cources
Promo presentation for robotics courcesPromo presentation for robotics cources
Promo presentation for robotics courcesAlexander Kolotov
 
Клуб изобретательства и робототехники ДОСААФ - 2016
Клуб изобретательства и робототехники ДОСААФ - 2016Клуб изобретательства и робототехники ДОСААФ - 2016
Клуб изобретательства и робототехники ДОСААФ - 2016Anton Moiseev
 
Кружок по робототехнике. Занятие #1. Введение
Кружок по робототехнике. Занятие #1. Введение Кружок по робототехнике. Занятие #1. Введение
Кружок по робототехнике. Занятие #1. Введение Alexander Kolotov
 
ROS - Robotics Operation System
ROS - Robotics Operation SystemROS - Robotics Operation System
ROS - Robotics Operation Systemhudvin
 
Московская делегация на Всероссийской робототехнической олимпиаде #RRO2015
Московская делегация на Всероссийской робототехнической олимпиаде #RRO2015Московская делегация на Всероссийской робототехнической олимпиаде #RRO2015
Московская делегация на Всероссийской робототехнической олимпиаде #RRO2015 Андрей Гурьев
 
Презентация проекта Робостанция на ВДНХ (29 апреля - 23 августа 2015 года)
Презентация проекта Робостанция на ВДНХ (29 апреля - 23 августа 2015 года)Презентация проекта Робостанция на ВДНХ (29 апреля - 23 августа 2015 года)
Презентация проекта Робостанция на ВДНХ (29 апреля - 23 августа 2015 года)Андрей Гурьев
 

Viewers also liked (20)

Дорожкина Н.Г. Промышленная робототехника
Дорожкина Н.Г. Промышленная робототехникаДорожкина Н.Г. Промышленная робототехника
Дорожкина Н.Г. Промышленная робототехника
 
Курс делаем робота
Курс делаем роботаКурс делаем робота
Курс делаем робота
 
Просторобот - мы делаем не только роботов!
Просторобот - мы делаем не только роботов!Просторобот - мы делаем не только роботов!
Просторобот - мы делаем не только роботов!
 
А. Ефимов. Робототехника в России.
А. Ефимов. Робототехника в России. А. Ефимов. Робототехника в России.
А. Ефимов. Робототехника в России.
 
Клуб Робототехники и ТехТворчества в IT Слободе
Клуб Робототехники и ТехТворчества в IT СлободеКлуб Робототехники и ТехТворчества в IT Слободе
Клуб Робототехники и ТехТворчества в IT Слободе
 
Заразительная робототехника на МикРобах
Заразительная робототехника на МикРобахЗаразительная робототехника на МикРобах
Заразительная робототехника на МикРобах
 
Чипы, платы, роботы
Чипы, платы, роботыЧипы, платы, роботы
Чипы, платы, роботы
 
Презентация на тему: Коммуникационные технологии
Презентация на тему: Коммуникационные технологииПрезентация на тему: Коммуникационные технологии
Презентация на тему: Коммуникационные технологии
 
цифровое производство плоских деталей
цифровое производство плоских деталейцифровое производство плоских деталей
цифровое производство плоских деталей
 
Робототехника в школьном образовании - Robotics Expo
Робототехника в школьном образовании - Robotics ExpoРобототехника в школьном образовании - Robotics Expo
Робототехника в школьном образовании - Robotics Expo
 
Робототехника
Робототехника Робототехника
Робототехника
 
Устройство Robotiki и ScratchDuino
Устройство Robotiki и ScratchDuinoУстройство Robotiki и ScratchDuino
Устройство Robotiki и ScratchDuino
 
робототехника - проблемы и перспективы (СМП-2014)
робототехника - проблемы и перспективы (СМП-2014)робототехника - проблемы и перспективы (СМП-2014)
робототехника - проблемы и перспективы (СМП-2014)
 
Promo presentation for robotics cources
Promo presentation for robotics courcesPromo presentation for robotics cources
Promo presentation for robotics cources
 
Клуб изобретательства и робототехники ДОСААФ - 2016
Клуб изобретательства и робототехники ДОСААФ - 2016Клуб изобретательства и робототехники ДОСААФ - 2016
Клуб изобретательства и робототехники ДОСААФ - 2016
 
Кружок по робототехнике. Занятие #1. Введение
Кружок по робототехнике. Занятие #1. Введение Кружок по робототехнике. Занятие #1. Введение
Кружок по робототехнике. Занятие #1. Введение
 
02.10 arduino-scratchduino
02.10 arduino-scratchduino02.10 arduino-scratchduino
02.10 arduino-scratchduino
 
ROS - Robotics Operation System
ROS - Robotics Operation SystemROS - Robotics Operation System
ROS - Robotics Operation System
 
Московская делегация на Всероссийской робототехнической олимпиаде #RRO2015
Московская делегация на Всероссийской робототехнической олимпиаде #RRO2015Московская делегация на Всероссийской робототехнической олимпиаде #RRO2015
Московская делегация на Всероссийской робототехнической олимпиаде #RRO2015
 
Презентация проекта Робостанция на ВДНХ (29 апреля - 23 августа 2015 года)
Презентация проекта Робостанция на ВДНХ (29 апреля - 23 августа 2015 года)Презентация проекта Робостанция на ВДНХ (29 апреля - 23 августа 2015 года)
Презентация проекта Робостанция на ВДНХ (29 апреля - 23 августа 2015 года)
 

Similar to Архитектура ROS

Л1 Введение в ROS.pdf
Л1 Введение в ROS.pdfЛ1 Введение в ROS.pdf
Л1 Введение в ROS.pdfAlekseyKabanov3
 
Операционные системы и среды
Операционные системы и средыОперационные системы и среды
Операционные системы и средыAlexandr Konfidentsialno
 
Антон Шумихин - Архитектура ОС
Антон Шумихин - Архитектура ОСАнтон Шумихин - Архитектура ОС
Антон Шумихин - Архитектура ОСGAiN@ESD
 
инструментарий
инструментарийинструментарий
инструментарийigdweb
 
история развития бд1
история развития бд1история развития бд1
история развития бд1Sai_17
 
Урок 5. Операционная система Windows
Урок 5. Операционная система WindowsУрок 5. Операционная система Windows
Урок 5. Операционная система WindowsANSevrukova
 
Что должен уметь Linux программист
Что должен уметь Linux программистЧто должен уметь Linux программист
Что должен уметь Linux программистru_Parallels
 
Лекция 1. Модель OSI.
Лекция 1. Модель OSI.Лекция 1. Модель OSI.
Лекция 1. Модель OSI.Alexey Furmanov
 
10 компонентные и офисные приложения на платформе microsoft
10 компонентные и офисные приложения на платформе microsoft10 компонентные и офисные приложения на платформе microsoft
10 компонентные и офисные приложения на платформе microsoftKewpaN
 
Вячеслав Бирюков - Дистрибутивы Linux
Вячеслав Бирюков - Дистрибутивы LinuxВячеслав Бирюков - Дистрибутивы Linux
Вячеслав Бирюков - Дистрибутивы LinuxYandex
 
Язык программирования SocLang (VKLang)
Язык программирования SocLang (VKLang)Язык программирования SocLang (VKLang)
Язык программирования SocLang (VKLang)Alexander Petrov
 

Similar to Архитектура ROS (20)

Л1 Введение в ROS.pdf
Л1 Введение в ROS.pdfЛ1 Введение в ROS.pdf
Л1 Введение в ROS.pdf
 
Операционные системы и среды
Операционные системы и средыОперационные системы и среды
Операционные системы и среды
 
Deep storm presentation
Deep storm presentationDeep storm presentation
Deep storm presentation
 
Антон Шумихин - Архитектура ОС
Антон Шумихин - Архитектура ОСАнтон Шумихин - Архитектура ОС
Антон Шумихин - Архитектура ОС
 
инструментарий
инструментарийинструментарий
инструментарий
 
история развития бд1
история развития бд1история развития бд1
история развития бд1
 
Урок 5. Операционная система Windows
Урок 5. Операционная система WindowsУрок 5. Операционная система Windows
Урок 5. Операционная система Windows
 
ос урок1
ос урок1ос урок1
ос урок1
 
Что должен уметь Linux программист
Что должен уметь Linux программистЧто должен уметь Linux программист
Что должен уметь Linux программист
 
Лекция 1. Модель OSI.
Лекция 1. Модель OSI.Лекция 1. Модель OSI.
Лекция 1. Модель OSI.
 
45695
4569545695
45695
 
10 компонентные и офисные приложения на платформе microsoft
10 компонентные и офисные приложения на платформе microsoft10 компонентные и офисные приложения на платформе microsoft
10 компонентные и офисные приложения на платформе microsoft
 
Вячеслав Бирюков - Дистрибутивы Linux
Вячеслав Бирюков - Дистрибутивы LinuxВячеслав Бирюков - Дистрибутивы Linux
Вячеслав Бирюков - Дистрибутивы Linux
 
Genome
GenomeGenome
Genome
 
лек13 6
лек13 6лек13 6
лек13 6
 
лекция 2
лекция 2лекция 2
лекция 2
 
10145
1014510145
10145
 
2IDE~1.PPT
2IDE~1.PPT2IDE~1.PPT
2IDE~1.PPT
 
Node.js (RichClient)
 Node.js (RichClient) Node.js (RichClient)
Node.js (RichClient)
 
Язык программирования SocLang (VKLang)
Язык программирования SocLang (VKLang)Язык программирования SocLang (VKLang)
Язык программирования SocLang (VKLang)
 

More from Андрей Антонов

Сканирующие лазерные дальномеры (LIDAR)
Сканирующие лазерные дальномеры (LIDAR)Сканирующие лазерные дальномеры (LIDAR)
Сканирующие лазерные дальномеры (LIDAR)Андрей Антонов
 
Заразительная робототехника на МикРобах (Робофест-2016)
Заразительная робототехника на МикРобах (Робофест-2016)Заразительная робототехника на МикРобах (Робофест-2016)
Заразительная робототехника на МикРобах (Робофест-2016)Андрей Антонов
 
Применение технологии Bluetooth Smart в транспортных средствах
Применение технологии Bluetooth Smart в транспортных средствахПрименение технологии Bluetooth Smart в транспортных средствах
Применение технологии Bluetooth Smart в транспортных средствахАндрей Антонов
 
Выбираем осциллограф. Часть I
Выбираем осциллограф. Часть IВыбираем осциллограф. Часть I
Выбираем осциллограф. Часть IАндрей Антонов
 
Теория и практика автоматического управления в робототехнике
Теория и практика автоматического управления в робототехникеТеория и практика автоматического управления в робототехнике
Теория и практика автоматического управления в робототехникеАндрей Антонов
 
Управление с обратной связью в БПЛА
Управление с обратной связью в БПЛАУправление с обратной связью в БПЛА
Управление с обратной связью в БПЛААндрей Антонов
 
Робототехника и встраиваемые системы
Робототехника и встраиваемые системыРобототехника и встраиваемые системы
Робототехника и встраиваемые системыАндрей Антонов
 
Проблема локализации мобильного робота
Проблема локализации мобильного роботаПроблема локализации мобильного робота
Проблема локализации мобильного роботаАндрей Антонов
 
Программирование беспилотного автомобиля
Программирование беспилотного автомобиляПрограммирование беспилотного автомобиля
Программирование беспилотного автомобиляАндрей Антонов
 

More from Андрей Антонов (11)

Сканирующие лазерные дальномеры (LIDAR)
Сканирующие лазерные дальномеры (LIDAR)Сканирующие лазерные дальномеры (LIDAR)
Сканирующие лазерные дальномеры (LIDAR)
 
Заразительная робототехника на МикРобах (Робофест-2016)
Заразительная робототехника на МикРобах (Робофест-2016)Заразительная робототехника на МикРобах (Робофест-2016)
Заразительная робототехника на МикРобах (Робофест-2016)
 
Применение технологии Bluetooth Smart в транспортных средствах
Применение технологии Bluetooth Smart в транспортных средствахПрименение технологии Bluetooth Smart в транспортных средствах
Применение технологии Bluetooth Smart в транспортных средствах
 
Выбираем осциллограф. Часть I
Выбираем осциллограф. Часть IВыбираем осциллограф. Часть I
Выбираем осциллограф. Часть I
 
Теория и практика автоматического управления в робототехнике
Теория и практика автоматического управления в робототехникеТеория и практика автоматического управления в робототехнике
Теория и практика автоматического управления в робототехнике
 
Управление с обратной связью в БПЛА
Управление с обратной связью в БПЛАУправление с обратной связью в БПЛА
Управление с обратной связью в БПЛА
 
Робототехника и встраиваемые системы
Робототехника и встраиваемые системыРобототехника и встраиваемые системы
Робототехника и встраиваемые системы
 
Задача SLAM
Задача SLAMЗадача SLAM
Задача SLAM
 
Процесс создания робота
Процесс создания роботаПроцесс создания робота
Процесс создания робота
 
Проблема локализации мобильного робота
Проблема локализации мобильного роботаПроблема локализации мобильного робота
Проблема локализации мобильного робота
 
Программирование беспилотного автомобиля
Программирование беспилотного автомобиляПрограммирование беспилотного автомобиля
Программирование беспилотного автомобиля
 

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

  • 1. Архитектура 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
  • 2. Как правило, для всех поддерживаемых платформ публикуется большое коли- чество примеров, а также симуляторы, которые облегчают разработку собствен- ных проектов. В ROS также поддерживается множество различных датчиков и исполнитель- ных устройств (актуаторов), используемых в робототехнике. Каждый день появ- ляются новые устройства, совместимые с этим фреймворком. Рис. 2: ROS поддерживает различные исполнительные устройства В ROS имеются стандартные возможности операционной системы, такие как, аппаратная абстракция, управление устройствами на низком уровне, реализована часто используемая функциональность, передача сообщений между процессами, и управление библиотеками. Архитектура ROS основана не графе с централизо- ванной топологией. Обработка происходит в узлах, которые могут принимать или отправлять данные с датчиков, систем контроля состояния и планирования, при- водов, и так далее. Библиотека ориентирована на Unix-подобные системы (под Ubuntu Linux работает отлично, а Fedora и Mac OS X имеют статус эксперимен- тальных). Пакет *-ros-pkg является является общим репозиторием для разработки вы- сокоуровневых библиотек. Многие из возможностей часто ассоциируемые с ROS, такие как библиотеки навигации и визуализатор rviz, хранятся в этом репози- тории. Эти библиотеки предоставляют мощный набор инструментов (различные визуализаторы, симуляторы, средства отладки) для упрощения работы. Рис. 3: ROS позволяет наблюдать за тем, что происходит на каждом шаге ROS распространяется на условиях лицензии BSD и является ПО с открытым исходным кодом. ROS бесплатна для исследовательских и коммерческих целей. ROS способствует повторному использованию кода, так что разработчики робото- техники и ученые могут не изобретать колесо постоянно. Можно получить код из 2
  • 3. репозитория, изменить его и вновь поделиться улучшенным ПО. Вы также можете написать драйвер вашего собственного датчика для ROS. ROS поддерживает параллельные вычисления, имеет хорошую интеграцию с популярными C++ библиотеками, такими как как OpenCV, Qt, Point Cloud Library и пр., и она может работать на одноплатных компьютерах, таких как Raspberry Pi или BeagleBone Black, а также с микроконтроллерными платформа- ми, например, Arduino. Вы можете создать своего собственного робота на основе Arduino или Raspberry Pi и использовать для его управления Robot Operating System. Рис. 4: Интеграция ROS Время является очень важным ресурсом и ROS является одним из инструмен- тов, которые могут помочь разработать комплексное решение в кратчайшие сроки и с минимальными усилиями. Библиотека ROS поможет реализовать алгоритмы и сократить время, необходимое для интеграции целой кучи компонентов. 3 Архитектура ROS В архитектуре ROS можно выделить три концептуальных уровня: ∙ Уровень файловой системы (Filesystem level) ∙ Уровень вычислительного графа (Computation Graph level) ∙ Уровень сообщества (Community level) Первый уровень — это уровень файловой системы. На этом уровне располо- жена внутренняя структура ROS — структура папок, файлы, необходимые для работы. 3
  • 4. Второй уровень — это уровень вычислительного графа, на котором происходит взаимодействие между процессами и системами. На этом уровне находятся кон- цепции и модули, которые имеются в 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
  • 5. Рис. 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
  • 6. ∙ 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
  • 7. Пакеты в 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 id float32 vel string name В ROS имеется множество стандартных типов для использования в сообщени- ях. 7
  • 8. Простой тип данных Описание C++ Python bool Unsigned 8-bit int uint8_t bool int8 Signed 8-bit int int8_t int uint8 Unsigned 8-bit int uint8_t int int16 Signed 16-bit int int16_t int uint16 Unsigned 16-bit int uint16_t int int32 Signed 32-bit int int32_t int uint32 Unsigned 32-bit int uint32_t int int64 Signed 64-bit int int64_t long uint64 Unsigned 64-bit int uint64_t long float32 32-bit IEEE float float float float64 64-bit IEEE float double float string ASCII string (4 bit) std::string string time Secs/nsecs signed ros::Time rospy.Time 32 bit int duration Secs/nsecs signed ros::Duration rospy.Duration 32 bit int Специальным типом в ROS является Header. Он используется для добавления временных меток, кадров и так далее. Этот тип позволяет сообщениям быть про- нумерованными, таким образом, мы можем знать, кто отправил сообщение. Могут быть добавлены другие функции, прозрачные для пользователя, но управляемые ROS. Тип Header содержит следующие поля: uint32 seq time stamp string frame_id 3.1.3 Сервисы ROS использует упрощенный язык описания сервисов для характеристики ти- пов сервисов. Он создается непосредственно из формата msg для обеспечения свя- зи запрос/ответ между узлами. Описания сервиса хранятся в .srv файлах в под- директории srv/ пакета. Для вызова сервиса необходимо использовать имя пакета вместе с именем сер- виса. Например, файлу sample_package1/srv/sample1.srv соответствует sample_package1/sample1. Есть несколько инструментов для работы с сервисами. Инструмент rossrv вы- водит описание сервиса, пакет содержащий .srv файлы и может найти файлы ис- точников, которые используют этот тип сервиса. Если вы хотите создать сервис, ROS может помочь вам генератором серви- сов. Эти инструменты генерируют код для начального определения сервиса. Вам только нужно добавить строку gensrv() в ваш файл CMakeLists.txt. 8
  • 9. 3.2 Уровень вычислительного графа ROS создает сеть, в которой соединены все процессы. Любой узел в системе мо- жет получить доступ к этой сети, взаимодействовать с другими узлами, смотреть информацию, которую они посылают и передавать данные в сеть. Рис. 6: Структура уровня вычислительного графа Базовыми понятиями на этом уровне являются: узлы, мастер, сервер парамет- ров, сообщения, сервисы, темы и бэги. Все они различными способами обеспечива- ют граф данными. ∙ Узлы (nodes): являются процессами, производящими вычисления. Если вам нужен процесс, который может взаимодействовать с другими узлами, вам нужно создать узел с этим процессом, подключив его к сети ROS. Обыч- но, система имеет множество узлов для управления различными функция- ми. Лучше иметь множество узкоспециализированных узлов, выполняющих единственную функцию, чем большой универсальный узел, который бы де- лал в системе все на свете. Узлы записываются в клиентскую библиотеку ROS. Примером могут служить roscpp или rospy. ∙ Мастер (master): обеспечивает регистрацию имени и ищет оставшиеся узлы. Если его нет в системе, вы не сможете обмениваться информацией с узлами, сервисами, сообщениями и прочим. Мастер может быть на компьютере, где узлы работают с другими компьютерами. ∙ Сервер параметров (parameter server): дает возможность сохранять дан- ные, используя ключи, размещенные централизованно. С этим параметром возможно конфигурировать узлы во время их работы или для изменения рабочего узла. ∙ Сообщения(messages): узлы взаимодействуют друг с другом посредством сообщений. Сообщение содержит данные, передающие информацию другим узлам. ROS имеет много типов сообщений. Возможно разработать свой соб- ственный тип сообщения, используя стандартные сообщения. 9
  • 10. ∙ Темы (topics): Каждое сообщение должно иметь имя, чтобы направляться в сети ROS. Когда узел является отправителем данных, мы говорим, что узел опубликовал тему. Узлы могут получить темы от других узлов, просто подписавшись на тему. Узел может подписаться на тему, и не обязательно, чтобы узел, который бы публиковал тему, должен в настоящий момент су- ществовать. Это позволяет отделить выпуск от потребления. Важно, чтобы название темы было уникальным, чтобы избежать проблем и недоразумений между темами с одинаковыми названиями. ∙ Сервисы (services): при публикации темы, вы отправляете данные, имею- щие отношения многие-ко-многим, но когда вам нужно сделать запрос или получить ответ от узла, вы не можете сделать это, используя темы. Сервисы дают нам возможность взаимодействовать с узлами. Сервисы также должны иметь уникальное имя. Когда у узла есть сервис, все узлы могут общаться с ним, благодаря клиентским библиотекам ROS ∙ Бэги (bags): формат для сохранения и воспроизведения данных сообщений ROS. Бэги являются важным механизмом для хранения данных, таких как данные сенсоров, которые сложно собирать, но они требуются для разра- ботки и тестирования алгоритмов. Бэги часто используются при работе со сложными роботами. На Рисунке 7 показано графическое представление уровня вычислительного графа. Это представление реального робота в реальных условиях. На графе есть узлы, темы, информация о том, на какие темы подписан узел и т.д. На этом графе не представлены сообщения, бэги, сервер параметров и сервисы. Для их графиче- ского представления требуются другие инструменты. Инструментом для создания графа является rxgraph. Рис. 7: Структура уровня вычислительного графа 10
  • 11. 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
  • 12. ∙ _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
  • 13. 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
  • 14. 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
  • 15. ∙ 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
  • 16. 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
  • 17. Как только папка будет создана, нам необходимо добавить этот новый путь в 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
  • 18. Как мы говорили ранее, вы можете использовать команды rospack, roscd и rosls для получения информации о новом пакете: ∙ rospack find architect_tutorials - эта команда помогает нам найти путь ∙ rospack depends architect_tutorials - эта команда позволяет посмотреть зави- симости ∙ rosls architect_tutorials - команда позволяет посмотреть содержимое ∙ roscd architect_tutorials - меняет текущий путь 4.4 Компиляция пакета ROS Как только ваш пакет создан, необходимо выполнить компиляцию пакета. $ rosmake architect_tutorials После выполнения операции, вы увидите что-то вроде: 18
  • 19. Если не произойдет каких-то ошибок, пакет будет откомпилирован. 4.5 Работаем с узлами ROS Узлы являются исполняемыми программами, и эти исполняемые файлы нахо- дятся в директории имя_пакета/bin. Чтобы попрактиковаться и изучить работу с узлами, мы используем пакет под названием turtlesim. Перед тем, как начать работать, необходимо выполнить: $ roscore Результат выглядит примерно так: Установим простенький симулятор (если он не установлен заранее): 19
  • 20. $ 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
  • 21. Должно открыться новое окно с маленькой черепашкой в центре. Если теперь посмотреть на список узлов, то мы увидим в нем узел с именем /turtlesim. Информацию об узле можно посмотреть, используя rosnode info имя_узла. Вы можете увидеть большое количество информации, которую можно использовать для отладки ваших программ: $ rosnode info /turtlesim Node [/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: 7997 Connections: 21
  • 22. * 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
  • 23. Как черепашка движется во время выполнения turtle_teleop_key? Если вы хотите увидеть информацию об узлах /teleop_turtle и /turtlesim, мы можем посмотреть на следующий код, который находится в теме, под названием * /turtle1/ cmd_vel [geometry_msgs/Twist] в разделе Publications первого узла. В разделе Subscriptions второго узла есть * /turtle1/cmd_vel [geometry_msgs/Twist]: $ rosnode info /teleop_turtle Node [/teleop_turtle] Publications: * /turtle1/cmd_vel [geometry_msgs/Twist] ... $ rosnode info /turtlesim Node [/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
  • 24. $ 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.0 y: 0.0 z: 0.0 angular: x: 0.0 y: 0.0 z: 0.0 --- linear: x: 0.0 y: 0.0 z: 0.0 24
  • 25. angular: x: 0.0 y: 0.0 z: 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 linear float64 x float64 y float64 z geometry_msgs/Vector3 angular float64 x float64 y float64 z 25
  • 26. Это полезные инструменты, потому что, используя эту информацию, мы мо- жем публиковать темы, используя команду 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
  • 27. 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
  • 28. Для того, чтобы посмотреть тип любого сервиса, например, сервиса /clear: $ rosservice type /clear Вы увидите: std_srvs/Empty Для вызова сервиса используйте rosservice call [service] [args]. Если вы хотите запустить сервис /clear: $ rosservice call /clear В окне turtlesim вы увидите, что линии, созданные движением черепашки будут удалены. Теперь попробуйем другой сервис, например, сервис /spawn. Этот сервис со- здаст другую черепашку в другом месте, с другой пространственной ориентацией. $ rosservice type /spawn | rossrv show Увидим следующее: float32 x float32 y float32 theta string name --- string name Используя эти поля, мы знаем как запустить сервис. Нам необходимы коорди- наты x и y, ориентация theta и имя новой черепашки: $ rosservice call /spawn 3.0 3.0 0.2 "new_turtle" 28
  • 29. Увидим следующий результат: 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
  • 30. /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
  • 31. 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
  • 32. 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
  • 33. #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
  • 34. 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
  • 35. $ 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 A int32 B int32 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 A int32 B int32 C --- int32 sum Отредактируем CMakeList.txt и удалим # из строки # rosbuild_gensrv() и от- компилируем пакет, используя rosmake architect_tutorials. Для проверки все ли нормально, используем инструмент rossrv: $ rossrv show architect_tutorials/architect_srv1 Если вы увидите то же содержимое, что и в файле architect_srv1.srv, то все нормально. 35
  • 36. 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
  • 37. #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
  • 38. Для компиляции нового в файл 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
  • 39. Ниже приведено содержимое файла 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