Базовые утилиты ROS
Last updated
Last updated
Рассмотрим, как сущности и принципы, пройденные на прошлом занятии, реализованы в ROS, а также познакомимся с некоторыми сервисными утилитами, которые сделают нашу программистскую жизнь легче.
У людей начинающих изучать ROS, часто возникает вопрос “Ну хорошо, вот мы установили ROS, а как нам его запустить. Запустить roscore?”.
Не совсем. ROS - это не программа. ROS - это набор утилит, принципов программирования и управления. А значит запустить ROS нельзя. Но можно запустить те или иные программы, которые реализуют какие-то концепции ROS.
Вот тот самый упомянутый roscore
- это мастер-нода ROS - ядро ROS, которое следит, чтобы все издатели, подписчики, ноды, сервисы и т.д. работали правильно, и получали нужные им данные вовремя и целостно.
roscore
обычно запускается на роботе и как раз отвечает за работу нод - программ обеспечивающих функционирование подсистем робота.
Пока не будем подключаться к роботу, а запустим roscore
локально и представим, что наш компьютер и есть основной компьютер управляющий роботом. Откроем терминал и введем:
Не будем закрывать этот терминал, чтобы roscore
не закончил свою работу, а откроем новый (или новую вкладку) и в нем будем смотреть, что же происходит в системе.
Для начала давайте посмотрим какие ноды зарегистрированы в ROS.
Для получения информации о нодах мы будем использовать утилиту rosnode. Чтобы получить их список в системе введем:
Как мы видим сейчас в ROS зарегистрирована только одна нода - /rosout
/rosout - это системная нода ROS, которую запускает roscore
и она отвечает за логгирование информации о работе ROS.
Теперь давайте посмотрим что у нас с топиками. Для этого используем утилиту rostopic. Запустим ее с тем же параметром list, чтобы получить список топиков:
Это топики ноды /rosout, которые используются для отображения сообщений логирования. Сейчас мы не будем останавливаться на них подробно, отметим лишь, что мастер-нода запустилась и создала какие-то топики и какие-то ноды.
Но смотреть на голый ROS достаточно скучно. Давайте запустим какую-нибудь другую ноду, которая делает что-то осмысленное, и изучим её.
Небольшое отступление. Программы-ноды в ROS редко существуют сами по себе. Обычно они находятся в составе пакетов - групп файлов, которые реализуют какую-то определенную функциональность.
Чтобы запустить пакет, используются команды roslaunch или rosrun. Подробнее о том как работать с пакетами разберемся позже, а пока давайте запустим один из стандартных пакетов ROS - симулятор робота-черепахи:
Оставим наш симулятор работающим в этом терминале, и откроем новый, чтобы посмотреть что изменилось в системе:
Смотрите кроме уже виденных нами /rosout и /rosout_agg, появились еще топики содержащие в начале названия /turtle1. Это /cmd_vel, /color_sensor и /pose.
Небольшая ремарка. Такое наименование топиков с /turtle1 в начале - называется наименованием в пространстве имен /turtle1. И часто используется чтобы организовывать доступ к топикам с одинаковыми названиями, но относящимися к разными роботам или частям робота. Например, если мы запустим еще одну черепаху, то появятся еще три таких же топика, /cmd_vel, /color_sensor и /pose, но уже в другом пространстве имен (/turtle2).
Или если у нас на роботе есть топики управляющие, к примеру, правой и левой рукой, то логично будет организовать к ним доступ, через пространство имен правой и левой руки, при этом не меняя названия топиков.
Как нам узнать, какой тип данных публикуется в данном топике ?
Воспользуемся утилитой rostopic с параметром info. Давайте посмотрим информацию про топик /cmd_vel
Тип данных, как мы видим - geometry_msgs/Twist, чтобы это не значило.
Издателей - нет
Подписчики - /turtlesim
И если с подписчиками и издателями все более менее понятно, то что такое geometry_msgs/Twist ?
Twist - это название структуры данных, которое используется в данном топике. А geometry_msgs это имя директории в которой находится файл с описанием данной структуры.
Давайте посмотрим из чего состоит структура данных Twist. Для этого мы будем использовать еще одну утилиту ROS - rosmsg:
Как мы видим Twist состоит из двух структур Vector3 - linear и angular по три переменные типа float64
Главное что необходимо усвоить - посмотреть имя структуры данных в топике можно при помощи команды rostopic info, а посмотреть из чего она состоит - при помощи команды rosmsg info.
Существует еще один практический способ, как выяснить где именно расположен файл со стандартной структурой ROS, или посмотреть из чего эта структура состоит. В браузере надо вбить название структуры в любую поисковую систему:
Обычно первая или вторая ссылка ведет на нужный документ с описанием структуры.
Официальная документация существенно удобнее при изучении сложных структур данных, так как вы можете сразу переходить по ссылкам на вложенные структуры и смотреть из чего они состоят. Теперь мы видим из чего состоит Vector3 - это три именованных Float64 - x, y и z:
Теперь стало понятно, что топик /cmd_vel может содержать только структуру данных типа Twist. А что это вообще такое cmd_vel?
Те из вас, кто знает английский в достаточной мере, уже по названию топика могут понять, что он отвечает за передачу роботу команды на поддержание нужных скоростей. Т.к. cmd - это command, а vel - сокращение от velocity - скорость.
Т.е. заполняя структуру Twist, теми значениями скоростей, которые мы хотим от робота, и публикуя их в топик cmd_vel мы сможем заставить робота двигаться. Давайте попробуем это на нашей черепахе.
Чтобы публиковать сообщение в топик мы будем пользоваться все той же утилитой rostopic, только теперь с параметром pub.
Напишем в терминале rostopic pub, а теперь немного линуксовской магии. Напишите /turtle1/cm и нажмите кнопку Tab два раза. Линукс дополнил команду и она стала rostopic pub /turtle1/cmd_vel. Жмите кнопку Tab еще несколько раз, до тех пор пока линукс полностью не заполнит за вас, всю структуру.
Вот так:
Теперь перемещая курсор при помощи стрелочек влево и вправо на клавиатуре, замените значение linear x, с 0.0 на 1.0 и нажмите Enter:
Черепаха поехала.
Мы заполнили структуру данных Twist значением линейной скорости по оси X - 1 метр в секунду, опубликовали эту структуру в топик /cmd_vel, и черепаха выполнила эту команду.
Тут необходимо сделать еще одно уточнение, различные роботы по разному отрабатывают команду Twist переданную в топик /cmd_vel. В основном роботы стараются развивать и поддерживать ту скорость, которая указана в Twist, до тех пор, пока не придет новое сообщение с новыми значениями скоростей. Но некоторые поддерживают заданную скорость только некоторое время, а затем останавливаются и наша черепаха-симулятор как раз такая. Она едет с заданной в Twist скоростью только 1 секунду, после чего останавливается. Следовательно, для поддержания постоянной скорости перемещения нам нужно постоянно публиковать в топик /cmd_vel требуемое значения скорости при помощи Twist. Ну а для того, чтобы остановить черепаху в нужный нам момент, а не через одну секунду с последнего переданного сообщения, нам надо заполнить структуру данных Twist нулевыми значениями, опубликовать ее в /cmd_vel и черепаха остановится.
Теперь давайте рассмотрим еще одну полезную особенность утилиты rostopic это возможность “послушать” топик - т.е. посмотреть какие именно сообщения публикуются в нем. Для этого надо запустить утилиту rostopic с параметром echo, и дальше написать на какой именно топик мы хотим подписаться.
Давайте посмотрим какие сообщения публикуются в топике /turtle1/pose:
Как мы видим в топике постоянно публикуются сообщения о позиции нашей черепахи. Мы можем прервать работу rostopic echo (Ctrl+C) и рассмотреть эти сообщения подробнее.
Теперь, давайте посмотрим как и какие сообщения появляются в топике /cmd_vel.
Подпишемся на него при помощи rostopic echo, и откроем еще один терминал через который будем публиковать наши сообщения в топик /cmd_vel.
Давайте разместим окна наших терминалов и черепашку так, чтобы мы могли видеть их всех одновременно. Вот так.
Теперь давайте отправим нашу черепашку вперед со скоростью 1 метр в секунду заполнив linear x составляющую структуры Twist и опубликуем ее в /cmd_vel:
Смотрите что произошло: Мы опубликовали заполненную структуру в топик /cmd_vel. И это же сообщение появилось в топике /cmd_vel. И как только это сообщение там появилось черепаха поехала вперед.
Давайте попробуем применить то, чему мы уже научились на реальном роботе.
Для того, чтобы исполнять команды на реальном роботе, нам сначала надо к нему подключиться.
Как вы знаете из Подготовка к курсу по ROS, чтобы подключиться к удаленному терминалу, нам надо использовать утилиту ssh.
Напомню, что утилита ssh имеет следующий синтаксис:
Давайте введем в терминале:
ssh запросит пароль от учетной записи pi. Пароль можно посмотреть в инструкции к роботу. По умолчанию он - brobro
Давайте посмотрим на список топиков командой rostopic list:
Смотрите топиков больше чем у ROS-мастера на нашем компьютере, но какие-то топики нам уже знакомы. Из названий других топиков примерно понятно, что за информация в них публикуется.
Например топик /bat, наверное содержит информацию об аккумуляторе. Давайте подпишемся на него и послушаем:
Действительно, смотрите, структура данных описывает параметры аккумулятора: вольтаж, ток и т.д.
Теперь, давайте заставим робота двигаться.
В ROS размерность линейной скорости равна метрам в секунду, то есть, задавая значение линейной скорости по Х равное единице, мы ожидаем, что робот будет ехать со скоростью 1 метр в секунду. Но так как наш робот маленький, он не может ехать так быстро. Его предельная скорость примерно 20 сантиметров в секунду или 0.2 метра в секунду. О размерности линейных скоростей надо помнить, когда мы будем передавать наши команды роботу.
Угловая скорость задается вокруг какой-то оси вращения. Знак угловой скорости определяется по правилу правой руки - вращение вокруг какой-то оси по часовой стрелке происходит с отрицательной угловой скоростью, а против часовой стрелки - с положительной.
Угловая скорость в ROS имеет размерность радиан в секунду (1 радиан ~ 58 угловых градусов).
Давайте заставим нашего робота ехать по дуге налево.
Налево - это против часовой стрелки - значит знак плюс. Выберем значение z = 1.
Прямо со скоростью 0.1 м/с (x = 0.1). Давайте заполним структуру Twist значениями и опубликуем ее в топик /cmd_vel:
Робот поехали именно так, как мы и хотели: прямо со скоростью 0.1 и налево с угловой скоростью 1 радиан в секунду. Для того, чтобы остановить робота опубликуйте структуру Twist в топик /cmd_vel с нулевыми значениями линейной и угловой скорости:
Теперь давайте рассмотрим очень важную возможность ROS - это подключение к удаленному мастеру.
Давайте отключимся от робота, закроем все терминалы и выполним:
Как мы видим, ROS выдает ошибку - не могу подключиться к мастеру.
Это логично, ведь мы закрыли терминал с roscore
и мастер-нода на нашем компьютере не запущена. Но! Она же запущена на нашем роботе! И все что нам надо сделать, это сказать нашему локальному ROS, где находится мастер, к которому надо подключиться.
Для того, чтобы это сделать, надо заполнить переменную окружения ROS_MASTER_URI, значением IP-адреса и порта нашего робота. Сделаем это при помощи команды export:
Теперь давайте снова введем rostopic list:
Вот! Теперь мы видим топики нашего робота, при этом обращаясь к ним через локальный ROS нашего компьютера.
Еще одна переменная среды, это ROS_HOSTNAME, ее тоже надо обязательно заполнить, т.к. она указывается в тот момент, когда нода публикует или подписывается на топик. И для того, чтобы публикация или подписка работали правильно, нам надо присвоить этой переменной значение IP-адреса нашего компьютера при помощи команды export:
Вот теперь мы можем и публиковать и читать сообщения в топиках удаленного ROS-мастера.
Напомню еще раз:
ROS_MASTER_URI - это адрес удаленного мастера;
ROS_HOSTNAME - это адрес нашей локальной машины.
Команды export
необходимо выполнять при запуске каждого нового терминала. Удобно прописать ROS_MASTER_URI
и ROS_HOSTNAME
в файле .bashrc
, для того чтобы каждый раз не делать export.
Для этого необходимо открыть, с помощью текстового редактора, файл ~/.bashrc
и в самый конец добавить строчки: