На текущий момент я работаю в последней версии ROS - Noetic Ninjemys. К сожалению, она официально поддерживает только версию Ubuntu 20.04. Поэтому, столкнувшись с выбором после обновления системы до версии 22.04 LTS: либо собирать ROS 1 из исходников, либо попробовать развернуть ее в контейнере, остановился на последнем. К тому же, было интересно поработать с Docker - как-то раньше не доводилось.
С установкой docker проблем возникнуть не должно. Примеры для docker будут без sudo (инструкция по настройке прав пользователя). Если все работает, то в ответ на запуск тестового контейнера:
$ docker run hello-world
docker выдаст сообщение о своей успешной установке:
На вики ros есть целый раздел по работе c ROS из docker.
Для себя я выбрал официальный образ - noetic-robot. Для его установки достаточно обной каманды:
$ docker pull ros:noetic-robot
После скачивания образа, контейнер для работы с ros запускается командой:
$ docker run -it ros:noetic-robot
В результате чего становится доступна консоль контейнера (буду обозначать ее "ctr:$"), в ней и запускается ros:
ctr:$ roscore
в ответ появится стандартное приветствие, в котором указаны параметры ros:
Исходно, в образе noetic-robot пакеты rosserial_arduino и rosserial, необходимые для работы с arduino не установлены. Их установка в контейнере производится обычным способом с помощью apt (sudo не требуется, т.к. сеанс контейнера запускается с пользователем root):
ctr:$ apt update
ctr:$ apt install ros-noetic-rosserial-arduino
ctr:$ apt install ros-noetic-rosserial
После установки добавится несколько новых пакетов, получить их список можно камандой:
ctr:$ rospack list | grep rosserial
Тут сразу необходимо сделать замечание, что все изменения в контейнере будут доступны только во время текущего сеанса, если выйти и заново запустить контейнер, то установленных ранее пакетов в нем не окажется. Для сохранения изменений необходимо сделать commit в образ. В новом окне терминала нужно проверить ID запущенного контейнера:
$ docker ps
после чего сделать коммит в текущий образ или создать новый (я буду использовать текущий):
$ docker commit 0059faf98a62 ros:noetic-robot
При следующем запуске пакет rosserial_arduino будет доступен.
Теперь необходимо сделать подготовку Arduino Mega: подключить, определить порт, залить тестовый скетч и проверить связь через последовательный порт - в рамках основной системы.
Порт легко определяется в Arduino IDE - в моем случае, это "/dev/ttyACM0". Для проверки работы через com-port удобно воспользоваться примером SerialEvent из стандартной библиотеки:
Arduino с ним делает эхо, отправляя в ответ принятую строку, при получении символа перехода на новую строку.
Если при попытке прошить скетч появится ошибка доступа к serial port:
avrdude: ser_open(): can't open device "/dev/ttyACM0": Permission denied
необходимо добавить текущего пользователя в группу dialout:
$ sudo usermod -a -G dialout ${USER}
и выполнить выход из системы, после повторного входа доступ должен появиться.
Проверить общение с платой после загрузки скрипта можно с помощью одной из терминальных программ (например, serial monitor, встроенный в Arduino IDE, или picocom / minicom). Либо напрямую отправляя строку в порт, для чего понадобится открыть два терминала, один для просмотра полученных данных:
$ cat /dev/ttyACM
второй для отправки строки в порт:
$ echo "HELLO WORLD" >> /dev/ttyACM0
Для того, чтобы устройства, подключенные к ПК, стали доступны из контейнера, необходимо назначить ему привилегии для всех устройств или только для выбранных. В данном случае доступ к только к com-port для связи с arduino выглядит так:
$ docker run --device=/dev/ttyACM0 -it ros:noetic-robot
После запуска контейнера доступ к com-port "/dev/ttyACM0" становится общим как для основной системы (host), так и для контейнера (container). Это легко проверить, посылая строку в arduino из основной системы и принимая ответ в контейнере и наоборот:
Для того, чтобы передать строку в порт и получить ее в рамках только контейнера во втором терминале необходимо запустить процесс docker с ID исходного контейнера:
$ docker exec -it <container ID> bash
теперь работать с com-port можно внутри контейнера:
Связь с arduino есть - можно переходить к настройке на ней тестового узла и проверке работы с ros. Для этого необходимо сгенерировать библиотеку ros_lib для Arduino IDE в папке контейнера - например "/home":
ctr:$ cd /home
ctr:$ rosrun rosserial_arduino make_libraries.py .
Скрипт создаст папку ros_lib с библиотекой. Ее содержание должно быть примерно таким:
Для этого во втором терминале по ID или имени запущенного контейнера (по имени даже удобней, т.к. работает автодополнение) копируем с помощью docker:
$ docker cp <ID>:/home/ros_lib <arduino_libraries_dir>
После запуска Arduino IDE библитека ros_lib должна стать доступна для использования, в том числе, ее примеры появятся в меню Files -> Examples. Для проверки взаимодействия с ros используем пример Blink:
Этот пример позволяет управлять встроенным светодиодом arduino с помощью сообщений в топике "toggle_led" типа "std_msgs::Empty". Для того, чтобы включать и выключать светодиод понадобится три консоли контейнера. В первой, с которой ранее работали, запускаем ros:
ctr:$ roscore
Во второй подключаемся к текущему контейнеру:
$ docker exec -it <ID> bash
и настраиваем окружение ros командой:
ctr:$ source ros_entrypoint.sh
Проверить, что во второй консоли есть доступ к основному процессу ros можно с помощью rostopic:
ctr:$ rostopic list
в списке активных топиков должы быть:
/rosout
/rosout_agg
Далее во второй консоли запускаем узел, обеспечивающий взаимодействие с arduino:
ctr:$ rosrun rosserial_python serial_node.py /dev/ttyACM0
ctr:$ rostopic pub toggle_led std_msgs/Empty --once
После каждой новой отправки сообщения состояние светодиода будет изменяться - arduino работает в качестве узла ros, при этом сам ros запущен в контейнере - именно такой результат и хотелось получить ☺
В библиотеке ros_lib также есть и другие примеры, позволяющие попробовать arduino в различных применениях, а их описание можно посмотреть в разделе tutorials пакета rosserial_arduino.
Всем мира! Let`s go design!
Комментарии
Отправить комментарий