Un'introduzione al sistema operativo dei robot: l'ultimo framework per applicazioni robot

Pubblicato: 2022-03-11

Il Robot Operating System (ROS) non è un vero e proprio sistema operativo, ma un framework e un insieme di strumenti che forniscono funzionalità di un sistema operativo su un cluster di computer eterogeneo. La sua utilità non si limita ai robot, ma la maggior parte degli strumenti forniti si concentra sul lavoro con l'hardware periferico.

ROS è suddiviso in più di 2000 pacchetti, ciascuno dei quali fornisce funzionalità specializzate. Il numero di strumenti collegati al framework sono probabilmente il suo più grande potere.

Perché dovrei usare il sistema operativo robot?

ROS fornisce funzionalità per l'astrazione hardware, driver di dispositivo, comunicazione tra processi su più macchine, strumenti per test e visualizzazione e molto altro.

La caratteristica fondamentale di ROS è il modo in cui il software viene eseguito e il modo in cui comunica, consentendo di progettare software complessi senza sapere come funziona un determinato hardware. ROS fornisce un modo per connettere una rete di processi (nodi) con un hub centrale. I nodi possono essere eseguiti su più dispositivi e si connettono a quell'hub in vari modi.

I modi principali per creare la rete sono fornire servizi su richiesta o definire connessioni editore/abbonato con altri nodi. Entrambi i metodi comunicano tramite tipi di messaggio specificati. Alcuni tipi sono forniti dai pacchetti principali, ma i tipi di messaggi possono essere definiti dai singoli pacchetti.

Gli sviluppatori possono assemblare un sistema complesso collegando soluzioni esistenti per piccoli problemi. Il modo in cui il sistema è implementato, ci consente di:

  • Sostituisci al volo i componenti con interfacce simili, eliminando la necessità di arrestare il sistema per varie modifiche

  • Multiplexing di output di più componenti in un input per un altro componente, consentendo la risoluzione parallela di vari problemi

  • Collega componenti realizzati in vari linguaggi di programmazione semplicemente implementando i connettori appropriati al sistema di messaggistica, semplificando lo sviluppo di software collegando moduli esistenti di vari sviluppatori

  • Crea nodi su una rete di dispositivi, senza preoccuparti di dove viene eseguito il codice e implementando i sistemi di comunicazione interprocesso (IPC) e Remote Procedure Call (RPC)

  • Connettiti direttamente ai feed on demand dall'hardware remoto senza scrivere alcun codice aggiuntivo, utilizzando i due punti precedenti

Intendiamo dimostrare quanto sia utile sviluppando in modo iterativo una soluzione semplice. Ci sono diversi vantaggi chiave rispetto ad altri approcci. ROS ha il supporto multipiattaforma e consente connessioni tra processi su più dispositivi tramite connessioni peer-to-peer che vengono gestite dietro le quinte. Il design consente il supporto per qualsiasi linguaggio avvolgendo le classi di comunicazione C++ o sviluppando manualmente classi per l'interfaccia del linguaggio.

ROS è fatto dalla sua stessa comunità, pensato per la sua comunità. Dopo diversi anni, ciò ha portato a una grande quantità di pacchetti riutilizzabili che sono semplici da integrare, grazie all'architettura del sistema.

Approcci alternativi come MRPT, CARMEN, LCM, Player, Microsoft RDS e altri forniscono alcune di queste funzionalità, ma non tutte. Il più delle volte, gli svantaggi del design sono le limitazioni del supporto linguistico, la comunicazione non ottimizzata tra i processi o la mancanza di supporto per vari dispositivi, che è probabilmente il problema più difficile da risolvere.

Cosa costruiremo?

Poiché il nostro obiettivo è il framework e non gli algoritmi effettivi per problemi particolari, il problema dato sarà abbastanza semplice. Il nostro obiettivo è costruire un software per un computer di bordo che ci permetta di controllare e monitorare da remoto un robot, collegato a noi tramite Wi-Fi, utilizzando un gamepad sul nostro computer e un feed dalla telecamera montata sul robot.

Prima di tutto, faremo collegare un semplice programma a una semplice simulazione, solo per dimostrare i principi di base dei ROS. Attaccheremo un gamepad a un computer e proveremo a progettare un buon schema di controllo per trasformare l'input del gamepad in segnali di controllo per un robot.

I linguaggi principali per scrivere codice ROS sono C++ e Python, C++ è preferito per le migliori prestazioni. Spiegheremo i nostri esempi in Python a causa del minor numero di boilerplate nel codice e non c'è bisogno di una costruzione esplicita.

Installazione e configurazione

Le versioni ROS sono indicate per nome. A partire da questa data, l'ultima versione è Jade Turtle e l'ultima versione LTS Indigo Igloo . È preferibile utilizzare la versione LTS e la compatibilità con le versioni precedenti non è garantita in ROS, quindi tutti gli esempi verranno scritti per Indigo .

ROS è disponibile su varie piattaforme *NIX. La versione ufficialmente supportata è su Ubuntu. Le versioni OS X, Arch Linux, Debian, Raspbian e Android sono supportate dalla community.

Esamineremo il processo di installazione di Ubuntu 14.04 su desktop. I processi per tutte le versioni e piattaforme supportate sono disponibili sul sito ufficiale. Sono disponibili anche macchine virtuali con ROS installato.

L'installazione dipende dalla piattaforma (e la maggior parte delle piattaforme dispone di pacchetti forniti), ma la configurazione dell'area di lavoro è la stessa per tutte le piattaforme.

Installazione su Ubuntu

ROS fornisce i propri repository. Il primo passo è aggiungerli.

 sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' sudo apt-key adv --keyserver hkp://pool.sks-keyservers.net --recv-key 0xB01FA116 sudo apt-get update

Dopodiché avrai tutti i pacchetti ospitati per tutte le versioni ROS disponibili per la tua versione di Ubuntu. Ad esempio, Ubuntu 14.04 supporta indigo e jade .

L'installazione dei pacchetti di base sul desktop ha una delle tre opzioni:

  • sudo apt-get install ros-indigo-ros-base per un'installazione minima

  • sudo apt-get install ros-indigo-desktop per avere gli strumenti GUI aggiuntivi di base

  • sudo apt-get install ros-indigo-desktop-full per avere tutte le funzionalità ufficiali, inclusi vari simulatori e librerie per la navigazione e la percezione

Per la migliore esperienza di lavoro, si consiglia l'opzione completa. Per l'installazione su dispositivi che verranno utilizzati solo per eseguire nodi, è sufficiente la versione base. Indipendentemente dall'opzione scelta, puoi installare qualsiasi pacchetto necessario denominato package_name eseguendo:

 sudo apt-get install ros-indigo-<package-name>

I trattini bassi sono sostituiti da trattini nel nome finale, quindi stage_ros sarà nel pacchetto ros-indigo-stage-ros .

Il prossimo passo è inizializzare rosdep . I pacchetti in ROS possono dichiarare da quali componenti dipendono. rosdep ti consente di compilare quei pacchetti senza troppa gestione manuale delle dipendenze. Per inizializzarlo, chiama:

 sudo rosdep init rosdep update

ROS ha diverse variabili di ambiente utilizzate dai suoi strumenti. Con l'installazione predefinita, lo script bash per inizializzarli si trova in /opt/ros/indigo/setup.bash . Le variabili devono essere inizializzate all'interno di ogni sessione bash, quindi la soluzione migliore è aggiungerle a ~/.bashrc .

 echo "source /opt/ros/indigo/setup.bash" >> ~/.bashrc source ~/.bashrc

Alcuni pacchetti installano dipendenze esterne tramite rosinstall , che è disponibile come pacchetto e installato tramite sudo apt-get install python-rosinstall .

Questa è la fine dell'installazione su Ubuntu. Quella che segue è una breve introduzione all'installazione degli spazi di lavoro.

Configurazione

Sin da Groovy Galapagos , gli spazi di lavoro ROS sono gestiti tramite catkin . Dobbiamo definire una directory per tutti i pacchetti che ospitiamo. All'interno della directory creiamo una cartella src e al suo interno chiamiamo il modulo catkin_init_workspace . Ciò creerà vari collegamenti simbolici alla versione ROS attualmente di origine. Il passaggio successivo consiste nell'aggiungere questo spazio di lavoro anche alle variabili di ambiente.

Per eseguire l'intera configurazione dell'area di lavoro, scegli una directory vuota ed esegui i seguenti comandi:

 mkdir src cd src catkin_init_workspace cd .. catkin_make echo "source $(pwd)/devel/setup.bash" >> ~/.bashrc source ~/.bashrc

Ora hai creato uno spazio di lavoro all'interno del quale puoi creare i tuoi pacchetti ROS.

Familiarizzazione con gli strumenti

La creazione di qualsiasi codice è un grande salto. Per prima cosa acquisiamo familiarità con alcuni dei sistemi in esecuzione dietro le quinte. Il nostro primo passo sarà eseguire la GUI di base e vedere quali messaggi genera.

Per eseguire qualsiasi cosa in ROS, è necessario avviare un processo principale. È facile come aprire una nuova finestra di terminale e digitare:

 roscore

Nell'intera rete di dispositivi connessi, roscore deve essere avviato una sola volta, sul dispositivo che ospiterà l'hub centrale per l'invio delle comunicazioni.

Il ruolo principale di roscore è dire ai nodi a quali altri nodi dovrebbero connettersi e in che modo (tramite una porta di rete o una memoria condivisa). L'obiettivo è consentire ai nodi di preoccuparsi solo dei dati che desiderano conoscere, piuttosto che del nodo a cui desiderano connettersi, riducendo al minimo il tempo e la larghezza di banda necessari per eseguire tutte le comunicazioni.

qt

Dopo aver eseguito roscore , possiamo avviare lo strumento GUI principale per ROS: rqt . Quello che vediamo è molto deludente: una finestra vuota. rqt ospita un'ampia varietà di plugin che possono essere configurati in qualsiasi configurazione visiva e qualsiasi numero di viste predefinite.

Screenshot di una finestra GUI vuota intitolata "Default - rqt" e con i menu File, Plugin, Esecuzione, Prospettive e Guida.

Per cominciare, eseguiamo il plug-in Robot Steering , scegliendolo in Plugins > Robot Tools > Robot Steering . Quello che otteniamo sono due cursori, che rappresentano il movimento lineare e rotatorio che vogliamo che il nostro robot abbia. Nella parte superiore del plugin vediamo una casella di testo con /cmd_vel al suo interno. Possiamo rinominarlo come vogliamo. Rappresenta il nome dell'argomento su cui sta pubblicando lo sterzo. Gli strumenti del terminale sono il posto migliore per vedere cosa sta succedendo in background.

Screenshot che mostra la stessa finestra di prima, ma con un'interfaccia Robot Steering, con le icone D, ricarica, guida, minimizza, cerchio e X, al suo interno. La prima riga ha una casella di testo con "/cmd_vel" e un pulsante Stop. Sotto c'è un cursore verticale centrato verticalmente impostato al centro a 0,0 m/s, con pulsanti a sinistra per +, 0 e - e controlli numerici sopra e sotto che indicano 1,00 e -1,00. Sotto c'è un cursore simile che è orizzontale e misurato in rad/s, impostato su 0 al centro, con i controlli numerici a 3,00 a sinistra e -3,00 a destra.

Strumenti terminali

ROS ha diversi potenti strumenti per ispezionare ciò che sta accadendo nel sistema. Il primo strumento che introdurremo è rostopic . Ci consente di esaminare gli argomenti a cui i nodi possono iscriversi e pubblicare. L'esecuzione rostopic list produrrà:

 /cmd_vel /rosout /rosout_agg

Gli ultimi 2 argomenti sono sempre in esecuzione e sono relativi ai sistemi ROS centrali. L'argomento /cmd_vel è stato pubblicato dal nostro governo. La ridenominazione dell'argomento nello sterzo lo rinominerà anche qui. Ora, siamo interessati a cosa sta succedendo all'interno dell'argomento. L'esecuzione rostopic echo /cmd_vel non ci mostrerà nulla (a meno che tu non abbia armeggiato con i cursori). Il processo continua finché non lo annulliamo. Spostiamo ora il cursore verticale a 20 m/s. Guardando l'eco, possiamo vedere quanto segue ripetuto più e più volte:

 linear: x: 0.2 y: 0.0 z: 0.0 angular: x: 0.0 y: 0.0 z: 0.0

Quanto spesso invia spam a questo messaggio? rostopic hz /cmd_vel dice a una frequenza media di 10 Hz. Bene, quanti argomenti come questo posso eseguire tramite la mia connessione Wi-Fi lenta? rostopic bw /cmd_vel rileva una media di 480 B/s.

Ora va tutto bene, ma abbiamo parlato dei tipi di messaggi. Questi dati sono utili per un essere umano, ma un'applicazione avrà bisogno dei dati grezzi e dovrà conoscere il tipo di messaggio in modo da poter interpretare i dati. Il tipo può essere determinato con rostopic type /cmd_vel , dicendoci che è un geometry_msgs/Twist . Tutti gli strumenti del terminale ROS chiamati senza alcun argomento restituiscono un messaggio di aiuto standard.

Il ROS Wiki è abbastanza buono da far sì che una ricerca sul web di questa stringa si traduca in una spiegazione Wiki di ciò che contiene e di come è strutturata. Ma non dobbiamo fare affidamento su di esso. rosmsg è lo strumento generale per i tipi di messaggi. L'esecuzione rosmsg show geometry_msgs/Twist restituirà:

 geometry_msgs/Vector3 linear float64 x float64 y float64 z geometry_msgs/Vector3 angular float64 x float64 y float64 z

Il messaggio è costituito da due vettori 3D, che rappresentano la velocità lineare e angolare nello spazio 3D.

Se vogliamo a quali argomenti è connesso un nodo, rosnode info <node-name> ci fornirà dati dettagliati sul nodo. Gli strumenti rostopic , rosmsg e rosnode sono gli strumenti principali per l'ispezione della funzionalità ROS grezza. ROS ha molti più strumenti GUI e terminali, ma quelli sono fuori dal nostro scopo per questa introduzione.

Gli strumenti principali per eseguire i nodi ROS sono rusrun e roslaunch . rosrun può eseguire nodi tramite rosrun <package_name> <node_name> e roslaunch esegue nodi basati su file di avvio, con i quali acquisiremo una minima familiarità poiché sono l'elemento più complesso dell'automazione ROS.

Possiamo chiudere tutto ciò che abbiamo eseguito per iniziare a lavorare sul nostro primo codice. Per riferimento futuro, è ovvio che l'esecuzione di qualsiasi cosa relativa a ROS richiede un'istanza attiva di roscore . Molti problemi che incontri possono essere risolti chiudendo la finestra del terminale in cui viene eseguito roscore e aprendone una nuova per riavviarlo. Questo aggiorna tutte le dipendenze che dovevano essere ricaricate, sia in bash che in roscore .

Creazione della teleoperazione del gamepad

Il nostro primo obiettivo è imitare la funzionalità di Robot Steering creando un nodo che pubblichi i dati geometry_msgs/Twist in /cmd_vel in base all'input del gamepad. La nostra prima tappa è il pacchetto joy .

Il Pacchetto joy

Il pacchetto joy fornisce driver ROS generici per joystick e gamepad. Non è incluso nell'installazione predefinita, quindi deve essere installato tramite:

 sudo apt-get install ros-indigo-joy

Dopo l'installazione, possiamo eseguire rosrun joy joy_node . Questo ci collegherà al joystick o gamepad predefinito. L'esecuzione rostopic list ci mostra che abbiamo un argomento chiamato /joy . Ascoltandolo tramite rostopic echo ci vengono mostrati messaggi del seguente formato (nota che devi interagire con il gamepad o il joystick per pubblicare i messaggi).

 header: seq: 4156 stamp: secs: 1450707466 nsecs: 204517084 frame_id: '' axes: [0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0, 0.0] buttons: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Puoi ignorare le intestazioni per ora. Oltre a questo, abbiamo axes e buttons , che spiegano bene cosa rappresentano. Lo spostamento degli assi e la pressione dei pulsanti sul controller comporteranno la modifica di questi numeri. Utilizzando i nostri strumenti, possiamo determinare che il tipo di messaggio è sensor_msgs/Joy e il formato è:

 std_msgs/Header header uint32 seq time stamp string frame_id float32[] axes int32[] buttons

Creare la nostra teleoperazione

Il primo passo per scrivere codice è creare un pacchetto. All'interno della cartella src dell'area di lavoro, eseguire:

 catkin_create_pkg toptal_tutorial rospy joy geometry_msgs sensor_msgs

Qui indichiamo il nome del pacchetto che stiamo creando, seguito dai pacchetti da cui prevediamo di dipendere. Nessun problema, le dipendenze possono essere aggiornate manualmente in un secondo momento.

Ora abbiamo una cartella toptal_tutorial . All'interno della cartella, crea una cartella di scripts che conterrà tutti i nostri script Python.

Creiamo un file chiamato teleop.py e al suo interno imposteremo:

 #!/usr/bin/env python import rospy from sensor_msgs.msg import Joy def joy_callback(data): print data def main(): rospy.init_node('teleop') rospy.Subscriber('joy', Joy, joy_callback) while not rospy.is_shutdown(): pass if __name__ == '__main__': main()

Avremo anche bisogno di impostare chmod +x teleop.py in modo che lo script diventi eseguibile. L'esecuzione rosrun joy joy_node in un terminale e rosrun toptal_tutorial teleop.py in un altro risulterà nell'output del terminale di teleop.py riempito di messaggi Joy.

Esaminiamo cosa fa il codice.

Per prima cosa importiamo rospy, che ospita la libreria per interagire con il framework ROS. Ogni pacchetto che definisce i messaggi ha un sottopacchetto msg con le definizioni dei messaggi al suo interno. Stiamo importando Joy per gestire l'input. Non è necessario importare tipi di messaggi incorporati (come Header da std_msgs.msg che si trova nel messaggio Joy ) a meno che non si desideri menzionarli esplicitamente.

Il nostro primo passo è inizializzare un nodo con un nome specifico (in questo caso lo chiamiamo "teleop"). Successivamente creiamo un abbonato che si iscrive all'argomento "joy" di tipo sensor_msgs.msg.Joy e che gestisce ogni messaggio chiamando la funzione joy_callback . Le richiamate ricevono un parametro, i dati del messaggio. L'accesso ai membri dei dati è semplice. Se volessimo stampare lo stato del primo asse, se ricordiamo il tipo di messaggio, chiameremo print data.axes[0] , e sarà un float. Il loop alla fine si ripete finché ROS non viene spento.

Il nostro prossimo passo sarebbe gestire i nostri dati in qualche modo. Dovremmo creare un messaggio Twist che cambia a seconda dell'input, quindi pubblicarlo nell'argomento cmd_vel .

 #!/usr/bin/env python import rospy from sensor_msgs.msg import Joy from geometry_msgs.msg import Twist # new from functools import partial # new def joy_callback(pub, data): # modified cmd_vel = Twist() # new cmd_vel.linear.x = data.axes[1] # new cmd_vel.angular.z = data.axes[0] # new pub.publish(cmd_vel) # new def main(): rospy.init_node('teleop') pub = rospy.Publisher('cmd_vel', Twist, queue_size=1000) # new rospy.Subscriber('joy', Joy, partial(joy_callback, pub)) # modified while not rospy.is_shutdown(): pass if __name__ == '__main__': main()

Innanzitutto, aggiungiamo il messaggio Twist e aggiungiamo il supporto per gli argomenti della funzione di associazione tramite functools.partial . Creiamo un editore, pub , che pubblica su cmd_vel un messaggio di tipo Twist . Leghiamo quell'editore al callback e gli facciamo pubblicare un messaggio Twist su ogni input con le velocità rappresentate dai primi due assi. Questo codice fa quello che ci aspettiamo e possiamo vedere l'output risultante tramite rostopic echo /cmd_vel .

Abbiamo ancora un problema. L'argomento /joy può essere pubblicato a ottimi prezzi. Se monitoriamo il rostopic hz /cmd_vel e muoviamo lo stick analogico in cerchio, possiamo vedere un gran numero di messaggi. Non solo ciò si traduce in una grande quantità di comunicazione, ma i processi che ricevono questi messaggi devono elaborare ciascuno di essi. Non è necessario pubblicare quei dati così frequentemente e faremmo meglio a pubblicare semplicemente a una frequenza stabile di 10 Hz. Possiamo farlo con il codice seguente.

 #!/usr/bin/env python import rospy from sensor_msgs.msg import Joy from geometry_msgs.msg import Twist from functools import partial def joy_callback(cmd_vel, data): # modified cmd_vel.linear.x = data.axes[1] cmd_vel.angular.z = data.axes[0] # moved pub.publish(cmd_vel) to main loop def main(): rospy.init_node('teleop') cmd_vel = Twist() # new pub = rospy.Publisher('cmd_vel', Twist, queue_size=1000) rospy.Subscriber('joy', Joy, partial(joy_callback, cmd_vel)) # modified rate = rospy.Rate(10) # new while not rospy.is_shutdown(): pub.publish(cmd_vel) # new rate.sleep() # new if __name__ == '__main__': main()

Abbiamo modificato il callback per ricevere l'oggetto Twist mutevole e modificarlo all'interno del ciclo. La funzione sleep di rospy.Rate mantiene una frequenza di uscita stabile.

Il codice finale risulterà /cmd_vel che riceverà i comandi di velocità a 10 Hz, imitando l'output del plug-in Robot Steering rqt .

Esecuzione di un sistema simulato

Simulazione del mondo

Il nostro primo obiettivo è creare un ambiente in cui possiamo simulare uno scenario che vogliamo realizzare. Il nodo stageros all'interno del pacchetto stage_ros ci consente di eseguire un robot all'interno di una fase 2D definita tramite un'immagine. C'è un'intera sintassi, descritta all'interno del pacchetto stage_ros per i file del mondo e come generarli. È abbastanza semplice, ma al di fuori del nostro scopo. Fortunatamente, il pacchetto viene fornito con diversi mondi demo. Per prima cosa, andiamo alla directory dei file eseguendo:

 roscd stage_ros cd world

All'interno della cartella ci sono diversi file. Eseguiamone uno.

 rosrun stage_ros stageros willow-erratic.world

Questo ha creato diversi argomenti. Il significato di ciascuno di essi è anche documentato con il pacchetto. La parte importante è che abbia cmd_vel .

Screenshot di una finestra intitolata Stage: willow-erratic.world. L'etichetta di stato recita "0m 20s 300msec (1.0)". C'è una scala a destra che va da 18 in basso a 30 in alto, con incrementi di uno. L'immagine principale è una scacchiera con punti e linee nere principali sparsi su di essa, più un quadrato blu vicino al centro e un quadrato rosso leggermente più grande a pochi quadrati a scacchiera da quello.

All'interno della fase visualizzata, c'è un quadrato blu, che rappresenta il robot che controlli. Utilizzando il nostro codice o Robot Steering , possiamo controllare questo robot. Provalo.

Configurazione del nostro sistema tramite file di avvio

creiamo una cartella di launch all'interno del nostro pacchetto e al suo interno creiamo un file chiamato teleop.launch . La struttura della cartella finale dovrebbe essere simile a questa:

 toptal_tutorial/ ├── CMakeLists.txt ├── launch │ └── teleop.launch ├── package.xml ├── scripts │ └── teleop.py └── src

All'interno del file teleop.launch definiremo un insieme di nodi e le loro interconnessioni.

 <launch> <arg name="world_file" default="$(find stage_ros)/world/willow-four-erratics-multisensor.world" /> <node pkg="stage_ros" type="stageros" name="simulated_world" args="$(arg world_file)"></node> <group ns="robot_0"> <node pkg="joy" type="joy_node" name="joy_input"></node> <node pkg="toptal_tutorial" type="teleop.py" name="joy_convert"></node> </group> </launch>

Il nuovo mondo è composto da quattro robot e ciascuno dei loro argomenti ha il prefisso robot_<n> . Quindi, il robot numero 0 ha un argomento del comando di velocità chiamato robot_0/cmd_vel . Ecco perché mettiamo il nostro controllo all'interno di uno spazio dei nomi chiamato robot_0 , per adattare i loro nomi alla nuova forma. In questo senso, puoi pensare ai nomi degli argomenti come a cartelle in un filesystem.

Diagramma con due sezioni, mondo simulato e /robot_0. Quest'ultimo ha caselle e bolle che iniziano con /robot_0/. Il primo ha una bolla etichettata /simulated-world collegata alla bolla cmd_vel del secondo, che si unisce a una casella joy_convert, che si unisce a una casella di gioia, che si unisce a una bolla di joy_input. /simulated-world si collega anche a quattro caselle in /robot-0, ovvero image_1, depth_0, depth_1 e image_0.

Per eseguire i file di avvio, non è necessario roscore . In un certo senso, roscore è solo un caso speciale di un file di avvio che non fa nulla. Se manca un roscore , solo il primo launchfile lanciato eseguirà un core, mentre il resto si collegherà ad esso. Ora eseguiamo il lancio con:

 roslaunch toptal_tutorial teleop.launch

Se tutto è corretto, questo risulterà in un simulatore con 4 robot, uno dei quali è controllato con il nostro gamepad o joystick. Questo mondo ha molto di più sotto il cofano del precedente. Ciascuno dei quattro robot ha:

 /robot_<n>/base_pose_ground_truth /robot_<n>/base_scan_0 /robot_<n>/base_scan_1 /robot_<n>/camera_info_0 /robot_<n>/camera_info_1 /robot_<n>/cmd_vel /robot_<n>/depth_0 /robot_<n>/depth_1 /robot_<n>/image_0 /robot_<n>/image_1 /robot_<n>/odom

Sostituiamo <n> con 0, 1, 2 o 3. Questo ci porta al nostro ultimo argomento.

Visualizzazione dei nostri dati con rqt

Non abbiamo approfondito rqt , ma è lo strumento perfetto per visualizzare dati più complessi. Puoi sperimentare tutti gli argomenti, ma ci concentreremo sugli image_0 , image_1 , depth_0 e depth_1 .

rqt e rimuoviamo tutti i plugin aperti. Ora apriremo 4 visualizzatori di immagini ( Plugins > Visualization > Image View ) e li posizioneremo in una formazione di griglia 2x2. Infine, nell'angolo in alto a sinistra di ciascuna vista, scegliamo uno dei quattro argomenti indicati per robot_0 .

Screenshot che mostra un'interfaccia di guida del robot, con la casella di testo e gli slider menzionati in precedenza, ma la casella di testo con la scritta "/robot_0/cmd_vel". A destra ci sono quattro visualizzazioni di immagini. I primi due (image_0 e image_1) mostrano due riquadri blu e un riquadro rosso in 3D. Le due in basso (depth_0 e depth_1) mostrano immagini simili a quelle in alto, ma in scala di grigi, e in particolare i riquadri colorati in primo piano qui appaiono in un grigio più scuro degli oggetti sullo sfondo.

Quello che otteniamo è una visione stereo con percezione della profondità, con telecamere a bassa risoluzione. Tieni presente che avremmo potuto ottenere questo risultato anche senza il nostro sistema di input. Se eseguiamo questo (dalla cartella stage_ros/world ):

 rosrun stage_ros stageros willow-four-erratics-multisensor.world

e aggiungi il plug-in Robot Steering con un argomento chiamato /robot_0/cmd_vel , avremmo ottenuto gli stessi risultati con i controlli che erano dispositivi di scorrimento sullo schermo.

Applicare i risultati a un sistema reale

Molto hardware ha il pieno supporto per ROS, molto spesso fornito da volontari di terze parti. Molte piattaforme robot hanno driver che generano questo tipo di messaggi e ROS ha nodi che prendono una webcam e pubblicano un feed di immagini.

Mentre l'ultimo risultato è stato una simulazione di ciò che vogliamo ottenere, lo stesso può essere ottenuto con le seguenti modifiche:

  • Installa ROS sul computer di bordo del tuo robot
  • Crea un file di lancio per il computer di bordo che collega ROS alla piattaforma sottostante e tutti i sensori di alto livello come telecamere, telemetri laser e altri. I nodi necessari possono già esistere, oppure possono essere implementati creando un editore/abbonato a ROS da un lato e un driver per le comunicazioni seriali dall'altro
  • Fai eseguire il file di avvio all'avvio
  • Sul tuo computer remoto aggiungi export ROS_MASTER_URI=http://<robot_hostname>:11311/ all'avvio di bash, facendo in modo che il computer remoto cerchi roscore su quel dato hostname e porta
  • Avvia rqt e/o qualsiasi script per il monitoraggio e il controllo del robot

Ciò a cui si riduce davvero è semplicemente esportare la variabile di ambiente corretta sul dispositivo remoto e il resto si gestisce da solo. L'esecuzione di ROS su un cluster di computer richiede solo un passaggio per ogni macchina.

Conclusione

Abbiamo dimostrato come, con pochissima codifica, puoi avere un complesso sistema di variabili che puoi manipolare a tuo piacimento. Il semplice sistema editore/abbonato consente di sviluppare rapidamente una pipeline software che elabora i dati in un cluster di computer, senza preoccuparsi dell'implementazione sottostante di determinati elementi.

Mentre abbiamo utilizzato un semplice simulatore, simulatori più complessi come gazebo (incluso anche nella versione desktop completa) ti consentono di creare mondi 3D con fisica e sensori complessi e possono darti un'esperienza dei risultati finali e del prodotto molto prima che venga sviluppato.

Questa introduzione è stata molto semplice, ma la speranza è che tu sia diventato più interessato a lavorare con questo framework versatile.