Lab 06 - Wprowadzenie do ROS 2 - struktura środowiska i podstawowe koncepty
Wprowadzenie do ROS 2 - struktura środowiska i podstawowe koncepty
Robot Operating System
Robot Operating System (ROS) to zestaw bibliotek programistycznych i narzędzi do budowania aplikacji robotycznych. ROS oferuje narzędzia open-source od sterowników sensorów i robotów, po zaawansowane algorytmy. Od końcówki roku 2017 istnieje pierwsza dystrybucja ROS'a 2, Ardent Apalone, która znacznie poszerza funkcjonalności ROS'a 1 (opisane tutaj). Obecnie w ramach laboratorium wykorzystywana jest najnowsza stabilna wersja - Humble Hawksbill. Pomimio tej zmiany, kluczowe koncepty pozostały takie same:
🐢 przetwarzanie oparte o niezależne moduły (koncepcja grafów - węzły, ang. nodes),
🐢 komunikacja poprzez publikowanie i subskrypcję (ang. publisher/subscriber),
🐢 komunikacja z informacją zwrotną poprzez serwisy lub akcje (ang. services, actions),
🐢 neutralność językowa (istnieje możliwość integracji z dowolnym językiem programowania, ang. ROS client library).
ROS 1 dedykowany pod zaawansowane projekty badawcze nie mógł zostać wdrożony 1:1 do zastosowań przemysłowych. Ograniczały go słabości związane z bezpieczeństwem dostępu do wiadomości oraz brak dostosowania do wymagań systemów czasu rzeczywistego. Druga generacja, ROS 2, została przeprojektowana, aby sprostać tym wyzwaniom. Różnice pomiędzy wersjami zostały opisane w artykule.
Podstawowe pojęcia
Środowisko (ang. workspace)
Środowisko ROS'a to miejsce, w którym przechowywane są paczki np. dla danego robota. Na jednym komputerze może istnieć wiele różnych środowisk (np. ros2_robotA_ws, ros2_robotB_ws).
Przykładowa struktura środowiska:
ros2_ws
├── build - zawiera pliki służące do procesu budowania, dzięki nim ponowne budowanie może uwzględnić tylko nowe zmiany
├── install - miejsce, w którym instalowane są paczki
├── log - zawiera logi procesu budowania
└── src - miejsce pracy ROS dewelopera zawierające paczki
Budowanie środowiska ROS 2 odbywa się z wykorzystaniem colcon
, poniższą komendą:
colcon build
Możliwe jest zbudowanie pojedynczej paczki:
colcon build --packages-select package_name
Pierwszym krokiem przed rozpoczęciem pracy ze zbudowanym środowiskiem ROS'a jest ustawienie zmiennych środowiskowych (source'owanie), dzięki czemu możemy uzyskać dostęp do paczek w danym terminalu.
W katalogu ~/ros2_ws
wywołaj komendę:
source install/setup.bash
Za każdym razem, gdy otwierasz okno terminala i zamierzasz pracować w danym środowisku, wywołaj powyższą komendę w odpowiednim katalogu.
Powinna ona zostać wywołana w katalogu głównym środowiska ROS 2 (np. ~/ros2_ws
).
Paczka
Paczkę to miejsce, w którym przechowywane są węzły. Służy do organizacji kodu tak, aby zapewnić modułowość oprogramowania.
Przykładowa struktura paczki (Python):
my_package/
my_package - katalog zawierający węzły
setup.py - zawiera instrukcje dotyczące instalacji paczki
setup.cfg - przechowuje informacje o plikach wykonywalnych
package.xml - zawiera informację o paczce oraz jej zależności
resource/my_package - katalog wymagany, aby zlokalizować paczkę
test - zawiera skrypty do automatycznego testowania
Organizowanie paczek odbywa się poprzez wykorzystanie ament
, ewolucji catkin
znanej z ROS 1. Dzięki temu narzędziu paczki mają usystematyzowaną strukturę.
Tworzenie paczki (C++):
ros2 pkg create --build-type ament_cmake package_name
Tworzenie paczki (Python):
ros2 pkg create --build-type ament_python package_name
Możliwe jest wskazanie zależności z argumentem --dependencies
oraz jednoczesne utworzenie węzła poprzez dodatkowy argument --node-name
.
Zarządzanie zależnościami paczki
Narzędziem istotnie usprawniającym pracę dewelopera ROS jest rosdep
. Pozwala ono na automatyczną instalację zależności (paczek, bibliotek) wszystkich paczek w danym środowisku. Dzięki temu, że zależności są definiowane w pliku package.xml
nie ma konieczności ręcznej ich instalacji.
Wiele gotowych paczek znajduje się w repozytorium ROS - rosdistro
, każdy użytkownik ma możliwość dodania do niego swojej paczki poprzez pull request. Informacja o tym jak dodać paczkę, która jeszcze nie znajduje się na liście jest tutaj.
Aby wykorzystać rosdep
wywołaj poniższe komendy wewnątrz katalogu ~/ros2_ws
:
sudo rosdep init
rosdep update
rosdep install --from-paths src -y --ignore-src --rosdistro humble
Te polecenia zainicjują rosdep
, a następnie zaktualizują lokalne indeksy z bazy paczek rosdistro
. Ostatnia komendy dokonuje instalacji zależności. Argument --from-paths src
mówi o tym, aby szukać plików package.xml
wewnątrz katalogu src
, -y
powoduje automatyczne akceptowanie komunikatów w konsoli, a --ignore-src
pomija w instalacji paczki znajdujące się w katalogu src
(ponieważ one zostaną przez nas zbudowane).
Węzeł
Węzeł reprezentuje pojedynczy proces w ROS'ie. Węzły mogą publikować lub subskrybować tematy, udostępniać usługi i akcje lub z nich korzystać.
Uruchamianie węzłów odbywa się poprzez komendę:
ros2 run package_name node_name
Aby uzyskać aktualną listę węzłów:
ros2 node list
Uzyskanie informacji o węźle:
ros2 node info <node_name>
Koncepcja grafów (ROS 2 graph
)
Graf ROS (ang. ROS graph) to sieć węzłów przetwarzających dane. Obejmuje wszystkie węzły i połączenia komunikacyjne między nimi. Graf ROS'a zawiera:
🐢 węzły - procesy wymieniające wiadomości
🐢 wiadomości - typy wymienianych danych
🐢 tematy - kanał komunikacji pomiędzy węzłami
🐢 odkrywanie - automatyczny proces nawiązywania połączenia pomiędzy węzłami
Narzędziem, które umożliwia podgląd i wizualizację aktualnego stanu grafu jest:
rqt_graph
Przykładowa wizualizacja grafu:
Możliwe jest grupowanie węzłów umożliwiając ich zbiorcze uruchamianie. Służą do tego pliki launch
. Wywołanie istniejącego pliku launch
odbywa się poprzez polecenie:
ros2 launch package_name launch_name
W ROS 2 pliku launch
mogą przyjmować jedno z trzech rozszerzeń, .xml
, .py
lub .yaml
. Rozszerzenie .py
jest rekomendowane ze względu na elastyczność tego języka. Więcej informacji na ten temat znajduje się w odnośniku do plików launch
.
Temat
Temat to unikalna nazwa, dzięki której węzły mogą nawiązywać połączenia oraz się komunikować. Temat powstaje w momencie, gdy węzeł rozpoczyna publikację określonego typu wiadomości.
Pojedynczy węzeł może publikować wiadomości na wielu tematach oraz subskrybować wiadomości z wielu tematów.
Podgląd aktualnej listy tematów odbywa się z wykorzystaniem komendy:
ros2 topic list
Lista tematów wraz z związanymi z nimi typami wiadomości:
ros2 topic list -t
Odczyt wiadomości z tematu:
ros2 topic echo topic_name
Pojedynczy temat może mieć wielu publikujących jak i subskrybentów. Informację o nich, a także o typie wymienianej wiadomości można sprawdzić komendą:
ros2 topic info topic_name
Możliwe jest również publikowanie wiadomości na danym temacie z poziomu terminala:
ros2 topic pub topic_name message_type 'message_data'
Example:
ros2 topic pub --once /turtle1/cmd_vel geometry_msgs/msg/Twist "{linear: {x: 2.0, y: 0.0, z: 0.0}, angular: {x: 0.0, y: 0.0, z: 1.8}}"
Aby opublikować wiadomość raz, można użyć argumentu --once
.
Odczyt częstliwości z jaką publikowane są dane na temacie:
ros2 topic hz topic_name
Wiadomość
Wiadomość jest elementem komunikacji pomiędzy węzłami. Może zawierać różnego rodzaju informację (np. położenie, orientację, obraz z kamery). Przykładowe domyślne typy wiadomości:
Aby uzyskać informacji o wiadomości:
ros2 interface show message_type
Wizualizacja wiadomości
RViz
to graficzny interfejs, który umożliwia wyświetlanie informacji z tematów z wykorzystaniem wbudowanych pluginów. Pozwala na spojrzenie na świat oczami robota lub sensora. Dla ROS 2, RViz
uruchamiamy poleceniem:
rviz2
Symulacja dynamiczna
Gazebo
to środowisko symulacyjne, które umożliwia tworzenie otoczenia pracy dla robota i symulację jego interakcji z obiektami. Gazebo
uruchamiamy poleceniem:
gazebo
ROS w Dockerze
Na początek warto zbudować własny, rozszerzony obraz na podstawie oficjalnego za pomocą następującego Dockerfile:
FROM ros:humble
RUN apt-get update && apt-get -y upgrade && apt-get -y install ros-humble-desktop
Budowanie można wykonać za pomocą polecenia:
docker build -t ros2_lab .
Kontener na podstawie oficjalnego obrazu można uruchomić poleceniem:
xhost +local:root && docker run -it \
--env="DISPLAY" \
--env="QT_X11_NO_MITSHM=1" \
--volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \
-v ~/ros2:/root/ros2 \
--net=host \
--privileged \
--name=ros2_lab \
ros2_lab:latest
Tak przygotowany kontener będziemy mogli wykorzystywać wielokrotnie. W celu ponownego uruchomienia wystarczy wywołać polecenie:
docker start -i ros2_lab
Jeśli potrzebujemy dodatkowego terminala działającego "w kontenerze", możemy go otworzyć poleceniem:
docker exec -it ros2_lab bash
Praca z ROS'em 2 przy wielu komputerach w lokalnej sieci
Standardem używanym przez ROS 2 do komunikacji jest DDS. W DDS istnieje pojęcie "domen". Pozwalają one na logiczne rozdzielenie połączeń w obrębie sieci.
Węzły w tej samej domenie mogą swobodnie siebie wykrywać i wysyłać do siebie wiadomości, podczas gdy węzły znajdujące się w różnych domenach nie mogą. Wszystkie węzły ROS 2 domyślnie używają identyfikatora domeny 0. Aby uniknąć zakłóceń między różnymi grupami komputerów z systemem ROS 2 w tej samej sieci, dla każdej grupy należy ustawić inny identyfikator domeny. W obrębie laboratorium konieczne jest ustawienie osobnego unikalnego ID domeny dla każdego z komputerów. W tym celu, odczytaj numer z naklejki przyklejonej do monitora i podstaw go do poniższej komendy w miejscu NR_KOMPUTERA
. Jeśli na Twoim komputerze nie ma naklejki, wybierz numer z przedziału 0-101 lub 215-232. Więcej informacji znajdziesz w poniższym odnośniku: About domain ID.
grep -q ^'export ROS_DOMAIN_ID=' ~/.bashrc || echo 'export ROS_DOMAIN_ID=NR_KOMPUTERA' >> ~/.bashrc
Powyższa komenda spowoduje, że w każdym oknie terminala ustawiany będzie wskazany identyfikator domeny. Dzięki temu węzły nie będą widoczne pomiędzy różnymi komputerami w tej samej sieci.
Zadania
- Dokonaj zmiany id domeny na unikalną. W tym celu odczytaj numer z naklejki przyklejonej do monitora (np. K006 - wybieramy tylko liczbę 6) i podstaw go do poniższej komendy w miejscu
NR_KOMPUTERA
. Jeśli na Twoim komputerze nie ma naklejki, wybierz numer z przedziału 0-101 lub 215-232.
grep -q ^'export ROS_DOMAIN_ID=' ~/.bashrc || echo 'export ROS_DOMAIN_ID=NR_KOMPUTERA' >> ~/.bashrc
💡Aby zaobserwować zmiany zamknij obecne okno terminala i uruchom nowe lub jeśli nie chcesz zamykać okna terminala, wpisz source ~/.bashrc
.
- Zainstaluj i uruchom przykładowy węzeł. Pobierz paczkę
usb_cam
i umieść ją w katalogusrc
środowiska ROS 2. Wykorzystaj komendęgit clone --branch ros2 https://github.com/ros-drivers/usb_cam.git
. - Paczka
usb_cam
definiuje zależność od innych paczek. Dokonaj automatycznej instalacji zależności z wykorzystaniemrosdep
. - Zbuduj środowisko ROS 2 poleceniem
colcon build
i dokonaj source'owania:source install/setup.bash
.
💡Uwaga: w przypadku problemów z powyższą instalacją ze źródeł, istnieje druga możliwość zainstalowania paczki. Możesz dokonać instalacji systemowej poleceniem sudo apt-get install ros-humble-usb-cam
. W tym przypadku paczka nie pojawi się w katalogu src
lokalnego środowiska i nie będzie konieczności budowania tej paczki. Aby wczytać biblioteki zainstalowane w systemie wykorzystaj komendę: source /opt/ros/humble/setup.bash
zamiast lokalnego odpowiednika.
Uruchom węzeł zainstalowanej paczki poleceniem:
ros2 run usb_cam usb_cam_node_exe
W nowym oknie terminala (
Ctrl + Shift + T
), dokonaj następującej analizy:5.1. Wyświetl listę tematów.
5.2. Wyświetl informację o temacie
/image_raw
.5.3. Wyświetl wiadomości z tematu
/image_raw
.Uruchom
RViz
poleceniemrviz2
i wyświetl obraz z kamery. W tym celu zlokalizuj przycisk "Add" -> "By topic" ->/image_raw
->Image
.Wyświetl obraz z wykorzystaniem węzła
image_view
, dokonaj instalacji jeśli to będzie konieczne.sudo apt-get install ros-humble-image-view ros2 run image_view image_view --ros-args --remap /image:=/image_raw
Uruchom
rqt_graph
. Następnie ponownie zasubkrybuj temat/image_raw
i zaobserwuj zmiany w grafie.Zainstaluj i uruchom paczkę sensors_demos_gazebo do symulacji sensorów (instrukcja jest w pliku
README
paczki). Umieść ją w katalogusrc
środowiska ROS 2. Do uruchomienia wykorzystaj plikilaunch
.9.1. IMU
IMU to układ elektroniczny wyposażony w jeden lub wiele trójosiowych żyroskopów i akcelerometrów. Możliwe jest również dołączenie magnetometru.
Dokonaj symulacji urządzenia w
Gazebo
i zapoznaj się z publikowanym tematem. Wyświetl jego zawartość w terminalu.9.2. Kinect
Kinect jest popularnie wykorzystywany w robotyce do lokalizowania robotów, wykrywania przeszkód i budowania modeli otoczenia. Sensor zwraca obraz RGB i obraz głębi.
Dokonaj symulacji sensora w
Gazebo
i zapoznaj się z listą tematów. Wyświetl ich zawartość w terminalu i wRViz
'ie.Zastanów się, dlaczego chmura punktów jest obrócona a obrazy nie nakładają się na siebie (w osi
z
).9.3. Hokuyo URG-04LX 2D laser scanner
Skaner laserowy URG-04LX-UG01 ma zakres pomiarowy od 20 mm do 5600 mm z dokładnością co do 1 mm.
Dodaj dowolne obiekty w zasięgu skaneru z interfejsu
Gazebo
lub przy pomocy menu wczytywania modeli.Zapoznaj się z listą tematów i wyświetl ich zawartość w terminalu i w
RViz
'ie.
Źródła i przydatne odnośniki
🐢 ROS2 - instalacja - Desktop Install