Практическое использование ROS на Raspberry Pi — часть 3

в 20:08, , рубрики: arduino, Raspberry Pi, ROS, rosserial, робототехника

Добрый день, уважаемые читатели !

Я продолжаю серию статей о практическом использовании ROS на Raspberry Pi (первая статья, вторая статья).
В данной статье мы будем использовать пакет teleop_twist_keyboard из стека ros-teleop для управления роботом с помощью нажатия клавиш на клавиатуре. Стек ros-teleop включает помимо данного пакета еще несколько пакетов для различных способов управления, например с помощью джойстика. Кто готов приступить к изучению teleop_twist_keyboard, прошу под кат.

Мультитерминал с tmux

Между делом, я вам хочу рассказать об одном приеме, который позволяет работать удаленно на Raspberry Pi через SSH одновременно в нескольких терминалах. Для этого на RPi нужно установить утилиту tmux.

$ sudo apt-get install tmux

После этого запускаем утилиту:

$ tmux

Внизу окна терминала должна появиться зеленая полоса с номером окна — 0.
tmux — это очень удобный менеджер терминальных окон, который позволяет создать в одном окне терминала любое число окон, размещая их несколькими различными способами (отдельное окно-терминал (window), панель окна (pane)) и удобно переключаться между ними.

Нажмите на клавиатуре Ctrl + B и C. Должно открыться еще одно окно с номером 1. Также попробуйте комбинацию Ctrl + B и %. Текущее окно терминала будет разделено посередине вертикальной зеленой полосой на два окна (pane). Если нажать комбинацию Ctrl + B,: и ввести “split window”, то окно будет разделено горизонтально на два одинаковых окна. Чтобы удалить панель (pane) воспользуйтесь комбинацией Ctrl + B, X и затем нажмите Y. Чтобы переключиться на другую панель в том же окне, используйте комбинацию Ctrl + B, O. Чтобы переключиться между окнами-терминалами по номеру окна, используйте комбинацию Ctrl + B, <номер окна>.

Теперь добавим запуск программы в файл ~/.bashrc для автоматического запуска при открытии нового терминала. Добавьте следующие строки в файл:

[[ $TERM != "screen" ]] && exec tmux

Работа с пакетом teleop_twist_keyboard

Теперь познакомимся с пакетом teleop_twist_keyboard.
Запустим скрипт teleop_twist_keyboard.py из пакета teleop_twist_keyboard как обычный узел ROS:

$ roscore
$ rosrun teleop_twist_keyboard teleop_twist_keyboard.py

Мы получим вывод такого вида:

Reading from the keyboard  and Publishing to Twist!
---------------------------
Moving around:
   u    i    o
   j    k    l
   m    ,    .

q/z : increase/decrease max speeds by 10%
w/x : increase/decrease only linear speed by 10%
e/c : increase/decrease only angular speed by 10%
anything else : stop

CTRL-C to quit

Выведем список всех активных на данный момент топиков:

$ rostopic list

Топик /cmd_vel должен появиться в списке. На этот топик узел teleop_twist_keyboard публикует сообщения каждый раз, когда была нажата клавиша на клавиатуре.
Покажем вывод сообщений, публикуемых в топик /cmd_vel:

$ rostopic echo cmd_vel

Запустим rqt_graph для представления вычислительного графа ROS в графическом виде. Схема вычислительного графа показывается все активные узлы и топики, которые их связывают.

$ rosrun rqt_graph rqt_graph

image

Здесь мы видим, что узел teleop_twist_keyboard публикует собщения в топик /cmd_vel, а узел rostopic подписывается на этот топик (команда rostopic echo).
Давайте узнаем какого типа сообщения публикуются на топик /cmd_vel:

$ rostopic type /cmd_vel

Команда выведет строку:

geometry_msgs/Twist

Это означает, что сообщения имеют тип Twist из стандартного ROS пакета geometry_msgs.
Мы также можем получить информацию о структуре сообщения командой rosmsg:

$ rosmsg info geometry_msgs/Twist
geometry_msgs/Vector3 linear
  float64 x
  float64 y
  float64 z
geometry_msgs/Vector3 angular
  float64 x
  float64 y
  float64 z

Поле ‘linear’ отвечает за линейную скорость, ‘angular’ — за угловую скорость.
Нажмите клавишу ‘i’, вывод будет таким (ассоциируется с движением вперед):

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

Нажмите клавишу ‘k’, вывод будет таким (остановка):

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

Нажмите клавишу ‘u’, вывод будет таким (поворот влево):

linear: 
  x: 0.5
  y: 0.0
  z: 0.0
angular: 
  x: 0.0
  y: 0.0
  z: 1.0
---

И наконец при нажатии на клавишу ‘o’ получим такой вывод (поворачиваем вправо):

linear: 
  x: 0.5
  y: 0.0
  z: 0.0
angular: 
  x: 0.0
  y: 0.0
  z: -1.0
---

Клавиши ‘j’ и ‘l’ отвечают за повороты влево и вправо на месте (без движения вперед).

Управление роботом с клавиатуры с teleop_twist_keyboard

У меня уже написан скетч rosserial для управления роботом посредством нажатия клавиш. Мы просто подписываемся на топик /cmd_vel и в зависимости от получаемого значения каждой из скоростей отдаем необходимую команду контроллеру движения (двигаться вперед, остановиться, повернуть влево или вправо). Скетч можно скачать отсюда.
Разберем подробнее код скетча.
В начале файла подключаем помимо стандартного заголовочного файла ros.h два дополнительных файла с типами сообщений geometry_msgs/Twist.h и geometry_msgs/Vector3.h:

#include <geometry_msgs/Twist.h>
#include <geometry_msgs/Vector3.h>

Мы объявляем обработчик узла ros::NodeHandle:

ros::NodeHandle nh;

Основное значение имеет метод messageCb:

void messageCb(const geometry_msgs::Twist& message) 
{
  geometry_msgs::Vector3 linear = message.linear;
  float forward_vel = float(linear.x);
  
  if(forward_vel == 0) { stop(); return; }
  
  geometry_msgs::Vector3 angular = message.angular;
  float ang_vel = float(angular.z);
  
  if(ang_vel > 0) { turnLeft(); }
  else if(ang_vel < 0) { turnRight(); }
  else { goForward(); }
}

В этом методе мы производим обработку получаемого сообщения из топика cmd_vel. В переменной forward_vel мы сохраняем линейную скорость, в переменной angular — угловую. Линейная скорость нам позволяет отследить команду остановки (значение 0). Угловая скорость определяет направление поворота (если больше 0, то поворачиваем влево, меньше 0 — вправо, если 0 — двигаемся вперед).
Создаем подписчика на топик /cmd_vel:

ros::Subscriber<geometry_msgs::Twist> sub("/cmd_vel", &messageCb);

со указанием ссылки на метод обработки сообщений (messageCb) и типа принимаемого сообщения — geometry_msgs::Twist.
В конце скрипта следуют стандартные методы скетча для rosserial_arduino:

nh.initNode();
nh.subscribe(sub);
Serial.begin(57600);

Запустите rosserial_arduino сервер:

$ rosrun rosserial_python serial_node _port:=/dev/ttyACM0

и загрузите скетч на плату Arduino.

Переключитесь на терминал, где запущен узел teleop_twist_keyboard, попробуйте нажатие клавиш ‘u’, ‘i’, ‘o’ и ‘k’ и проверьте в терминале вывод сервера rosserial.

Таким образом, используя пакет teleop_twist_keyboard мы теперь можем выполнять простое удаленное управление роботом передавая команды движения: двигаться вперед, остановиться, повернуть влево или вправо. В дальнейшем мы научимся управлять роботом с помощью джойстика, что значительно удобнее, с применением уже другого пакета в ROS. Но об этом в следующей статье.

Автор: vovaekb90

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js