Uruchamianie ROS na wielu maszynach
ROS pozwala na łączenie programów – które nazywane są Nodami, w wielu językach i, co ważne, na wielu komputerach. Jednak samo ustawienie sieci ROS na wielu komputerach, jest trochę podchwytliwe, stąd w tym artykule chcę wam przybliżyć moją konfigurację, ew mój sposób na znalezienie błędów w konfiguracji.
Na każdym komputerze musi być oczywiście zainstalowany, chociaż w podstawowym zakresie ROS, wszędzie w tej samej wersji (np. ROS Indigo). Dość ciężko łączy się ROS’y w różnych wersjach.
Artykuł piszę w takiej kolejności, jak ustawiałbym to na maszynach. Sporo zależy od możliwości routera czy wsześniejszej konfiguracji komputerów. Komputery muszą być w tej samej sieci i muszą się widzieć.
Podstawowe testy
Załóżmy, że komputer z roscore nazwaliśmy (hostname) duzy_ros a komputer-klienta maly_ros. Rzeczywistą nazwę możemy sprawdzić, pisząc w konsoli polecenie hostname. Zazwyczaj nazwa hosta pojawia się też po znaku @ w konsoli.
igor@duzy_ros:~$ hostname
duzy_ros
Dobrze jest też na tym etapie wiedzieć, jaki komputer ma adres IP. Ogólnie radzę na routerze ustawić tzw static DHCP (rezerwowanie adresów DHCP), to znaczy, aby danemu adresowi MAC ustalał zawsze ten sam adres IP. Można też ustawić stałe adresy samym komputerom, jednak jest to stosunkowo uciążliwe jeśli tym komputerem jest np. nasz laptop, który raz służy do kontrolowania robota, a innym razem jest komputerem domowym. Sprawdzić IP możemy za pomocą komendy ifconfig.
igor@maly_ros:~$ ifconfig
eth0 Link encap:Ethernet HWaddr 2c:41:38:09:f9:d4
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:452957 errors:0 dropped:0 overruns:0 frame:0
TX packets:227647 errors:0 dropped:0 overruns:0 carrier:2
collisions:0 txqueuelen:1000
RX bytes:617762669 (617.7 MB) TX bytes:20174253 (20.1 MB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:150077 errors:0 dropped:0 overruns:0 frame:0
TX packets:150077 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:17070833 (17.0 MB) TX bytes:17070833 (17.0 MB)
wlan0 Link encap:Ethernet HWaddr bc:77:37:dc:d2:1e
inet addr:192.168.1.103 Bcast:192.168.1.255 Mask:255.255.255.0
inet6 addr: fe80::be77:37ff:fedc:d21e/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:3432045 errors:0 dropped:1 overruns:0 frame:0
TX packets:2071139 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3574669623 (3.5 GB) TX bytes:440387517 (440.3 MB)
W zależności od tego, czy komputer jest wpięty poprzez kabel Ethernet czy WiFi, interesuje nas adres IP (inet addr) opisany w części wlan albo eth. W moim przypadku, adres karty WiFi komputera maly_ros to 192.168.1.103
Kolejnym testem jest to, czy komputery się widzą . Radzę sprawdzić na obu komputerach, poleceniem ping. Odpowiedź będzie miała podobny charakter. Powinny być czasy w milisekundach (albo częściach milisekudny). Router powinien znaleźć adres ip po nazwie hosta – ale tak będzie się działo tylko przy nowych routerach.
Na serwerze
igor@duzy_ros:~$ ping maly_ros
PING maly_ros (192.168.3.103) 56(84) bytes of data.
64 bytes from maly_ros: icmp_seq=1 ttl=61 time=3.96 ms
64 bytes from maly_ros: icmp_seq=2 ttl=61 time=2.61 ms
Na kliencie
igor@maly_ros:~$ ping duzy_ros
PING duzy_ros (192.168.3.101) 56(84) bytes of data.
64 bytes from duzy_ros: icmp_seq=1 ttl=61 time=3.11 ms
64 bytes from duzy_ros: icmp_seq=2 ttl=61 time=2.01 ms
Jeśli to się nie udało to musimy nazwy hostów przypisać na sztywno ( jest to opisane w dalszej części tego artykułu), ale próbujemy czy chociaż widzą się po adresach ip. W poleceniu ping, piszemy wobec tego adres ip zamiast nazwy hosta.
igor@duzy_ros:~$ ping 192.168.3.103
PING 192.168.3.103 (192.168.3.103) 56(84) bytes of data.
64 bytes from 192.168.3.103: icmp_seq=1 ttl=61 time=3.96ms
64 bytes from 192.168.3.103: icmp_seq=2 ttl=61 time=2.61 ms
To musi zakończyć się sukcesem zanim pójdziemy dalej. Jeśli komputery się nie pingują, chociaż po adresie IP, to problem tkwi w samej konfiguracji sieci. Dla przykładu, komputery podłączone są do innych sieci WiFi (zdaża się, szczególnie w przypadku uczelni czy firm gdzie tych sieci jest sporo).
Ostatnią rzeczą wartą przetestowania na starcie, jest sprawdzenie czy aby na komputerze z roscore nie ma uruchomionego firewalla. Natura ROS’a ogólnie wymusza, aby firewalla nie było ani na serwerze ani na komputerach klienckich, firewall powienien być ustawiony tylko na routerze. Najprostrzym testem jest wejść przeglądarką na stronę o adresie ip (ew. hostname) roscore i porcie 11311 czyli w przeglądarce napiszę albo 192.168.1.101:11311 albo duzy_ros:11311
Interesuje nas aby strona wyglądała jak na screenshocie, to znaczy aby wyświetlił się błąd 501, a nie np. błąd 404, że strona nie istnieje. Jeśli strona nie istnieje, a na serwerze jest uruchomiony roscore (upewnij się ;) ), to znaczy, że komputer serwera blokuje port 11311 (i pewnie inne). Trzeba wyłączyć firewall np. pisząc w konsoli.
igor@duzy_ros:~$ sudo ufw disable
[sudo] password for igor:
Firewall stopped and disabled on system startup
Sam stan firewalla można sprawdzić też w samym ubuntu uruchamiająć graficzny program, który wygląda tak:
Przejdźmy do samych ustawień
Ustawienia klienta
Na komputerze klienta (maly_ros) w pliku ~/.bashrc dodajemy linijki (dopisujemy na końcu). Polecam otworzyć ten plik i zapoznać się z jego strukturą. Plik .bashrc jest to plik programu bash, który uruchamia się za każdym razem gdy otworzymy terminal.
export ROS_MASTER_URI=http://duzy_ros:11311
export ROS_HOSTNAME=maly_ros
Jeśli komputery nie widziały się po nazwach hosta, możemy zamiast tego napisać
export ROS_MASTER_URI=http://192.168.1.101:11311
export ROS_ID=192.168.1.103
Ustawienia serwera
W pliku bash ustalamy podobnie:
export ROS_MASTER_URI=http://duzy_ros:11311
export ROS_HOSTNAME=duzy_ros
Następnie, na obu komputerach, w konsoli sourcujemy to znaczy ładujemy do konsoli zawartość plików poprzez polecenie source.
source ~/.bashrc
Finalne testy
Możemy sprawdzić, czy zmiany zostały wprowadzone, sprawdzająć zawartość zmienionych zmiennych
igor@maly_ros:~$ echo $ROS_MASTER_URI
http://duzy_ros:11311
Wreszcie, jeśli roscore na serwerze (duzy_ros) jest uruchomiamy na maly_ros polecenie rostopic list
igor@maly_ros:~$ rostopic list
/rosout
/rosout_agg
jeśli pojawia się ERROR: Unable to communicate with master!, coś mamy jeszcze źle skonfigurowane, polecam uruchomić testy z początku tego dokumentu.
Ustawienia hosts
Jeśli komputery się nie widzą po nazwach hostów, można zastąpić router w poszukiwaniu hosts, na obu komputerach przypisując wzajemnie swoje adresy w pliku /etc/hosts Uwaga! W takiej konfiguracji adresy IP poszczególnych komputerów nie mogą się zmieniać, co musimy ustalić albo na routerze albo ustalając stałe adresy ip na komputerach. Nie ma sensu przeprowadzać poniższej
Na obu komputerach, będziemy edytować plik /etc/hosts. Można to zrobić dowolnym programem do edycji plików tekstowych, np gedit czy vim
igor@maly_ros:~$ sudo gedit /etc/hosts.
W zawartości dopisujemy linijkę (na końcu). Pomiędzy adresem ip a nazwą hosta jest znak tabulator.
192.168.1.101 duzy_ros
analogicznie na serwerze
192.168.1.103 maly_ros
po zapisaniu plików, można przetestować konfigurację, pingująć komputery po nazwach, tak jak było to opisane na początku.