Visualizzare messaggi e salvare la configurazione con RViZ – Italian ROS Tutorial

Visualizzare messaggi e salvare la configurazione con RViZ – Italian ROS Tutorial

This tutorial is created by Robotics Ambassador 012 Alessandro

Rosbotics Ambassador Program (https://www.theconstruct.ai/robotics-ambassador/)

In questo tutorial vedremo come poter impostare la visualizzazione grafica di messaggi pubblicati sui differenti topic da una simulazione tramite l’uso di RViz e come poter salvare una configurazione della visualizzazione per poterla riutilizzare in futuro.

Visualizzazione dei messaggi dei topic

Per iniziare sarà necessario che siano attivi dei nodi che pubblicano dei messaggi adeguati, che siano nodi che abbiamo scritto noi, o preesistenti all’interno di una simulazione o di un robot con ROS installato.
Per questo tutorial utilizzeremo la simulazione di un drone disponibile sul corso di TheConstruct “Programming Drones with ROS“.

La simulazione sarà avviata nel momento in cui apriremo il corso e il relativo Rosject sarà avviato quando accederemo all’unità 3.

Possiamo verificare l’attività dei publisher relativi ai dati dei sensori a bordo del drone:
rostopic list
Otterremo come output una serie di topic che pubblicano informazioni relative a sensori di varia natura (LiDAR, Depth Cameras ecc.) la cui visualizzazione potrebbe risultare interessante per lo scopo di un nostro progetto.

RViz

Per poter lavorare con RViz sarà necessario lanciarlo dal nostro terminale.
Procediamo quindi con il seguente comando:
rosrun rviz rviz

Una volta di fronte alla schermata di RViz possiamo quindi iniziare a impostare un reference frame (in questo caso “base_link”).
Andiamo in alto a sinistra, in “Global options”, e impostiamo il “Fixed Frame” con valore “base_link”.

Siamo quindi pronti per poter aggiungere e visualizzare tutti i topic a cui siamo interessati.

Un ottimo punto di partenza sarebbe quello di visualizzare il modello fisico del robot che viene pubblicato dalla simulazione. In basso a sinistra premiamo quindi su “Add” e scorriamo fino a trovare “RobotModel”. Clicchiamo su “RobotModel” e poi su “Ok”.
Il modello fisico del robot sarà quindi rappresentato al centro della nostra simulazione.

All’interno di questa simulazione abbiamo per esempio anche la pubblicazione di messaggi da parte di sensori legati al robot, come LaserScan, ottenuti attraverso uno scan da parte di un LiDAR dell’ambiente circostante. In basso a sinistra premiamo quindi su “Add” e ci spostiamo nella tab “By topic”, dove potremo vedere quali topic stanno pubblicando messaggi, il loro nome e il tipo di messaggio che possiamo andare a visualizzare.

Aggiungiamo per esempio lo scan relativo al LiDAR
/scan/LaserScan
le immagini raccolte dalla telecamera rgb frontale on-board
/camera/rgb/image_raw/Image
e il PointCloud ritornato dalla DepthCamera
/camera/depth/points/PointCloud2

Salvare la configurazione

Poter visualizzare tutti questi topic porta un grosso vantaggio nel momento in cui andremo a testare i nostri progetti o semplicemente a raccogliere informazioni su ciò che il robot effettivamente è in grado di percepire. Chiaramente, più topic dovranno essere tracciati più sarà lungo il processo di configurazione ogni volta che andremo ad aprire RViz.

Per evitare questa faticosa operazione è possibile salvare la configurazione di RViz in modo da poterla riutilizzare in una seconda apertura, recuperandola direttamente dal comando di avvio di RViz.
Questo permetterà non solo di non dover ripetere il processo di configurazione, ma anche di poter salvare configurazioni differenti in base a ciò di a cui siamo interessati e di potersi muovere in modo semplice tra di esse.

Procediamo dunque con creare uno spazio all’interno del quale salvare le nostre configurazioni.
Ci spostiamo sull’editor di codice e creiamo una nuova cartella “rviz” all’interno di catkin_ws/src/my_rtab_package.
Qui andremo a salvare la configurazione e a recuperarla quando andremo a lanciare RViz.

Torniamo quindi su RViz (ripetiamo la configurazione nel caso l’avessimo o si dovesse essere chiuso) e poi su “File” > “Save Config As” e scegliamo il percorso in cui salvare il nostro file di configurazione, in questo caso salviamo il file in  /home/user/catkin_ws/src/my_rtab_package/rviz/sensor_view.rviz.

Avviare RViz con configurazione salvata

Quello che ci manca a questo punto sarà solo un modo per avviare RViz indicando la configurazione che vogliamo che sia utilizzata. Utilizziamo dunque il comando:
rosrun rviz rviz -d `rospack find my_rtab_package`/rviz/sensor_view.rviz

IMPORTANTE: l’uso del backtick (`) è essenziale perché il comando funzioni, con il layout italiano è possibile ottenerlo con [AltGr + ‘]

In questo modo RViz viene avviato e configurato a seconda del file che indichiamo all’interno del comando, risparmiandoci la fatica di dover ripetere tutto il procedimento dei punti precedenti e garantendo una maggiore flessibilità nell’osservare diverse visualizzazioni dei nostri messaggi.

 

Video Tutorial

Definizione e nesting di messaggi personalizzati – ROS (Noetic) Italian Tutorial

Definizione e nesting di messaggi personalizzati – ROS (Noetic) Italian Tutorial

This tutorial is created by Robotics Ambassador Alessandro

Robotics Ambassador Program https://www.theconstruct.ai/robotics-ambassador/

In questo tutorial andremo a vedere come definire messaggi personalizzati da utilizzare all’interno dei nostri nodi e come comporli per ottenere messaggi più elaborati. Inoltre vedremo come poter accedere ai singoli campi dei messaggi in modo più intuitivo all’interno del codice.
Il progetto descritto da questo tutorial è disponibile sul sito di TheConstruct al seguente link: Definizione e nesting di messaggi personalizzati [ROS Noetic] [Python]

Definire la struttura dei messaggi

All’interno del package in cui vogliamo andare a definire i nostri messaggi personalizzati (in questo caso custom_messages_nesting) andiamo a creare una nuova cartella, identificata dal nome “msg”. Questa sarà la cartella che durante la compilazione sarà utilizzata per verificare la presenza dei file di definizione dei messaggi personalizzati (che indicheremo successivamente).
Quindi possiamo creare un file con estensione .msg per ogni tipo di messaggio personalizzato che vogliamo definire.
Nel caso di questo tutorial assumiamo di voler avere un messaggio che contiene delle letture provenienti da sensori di un robot mobile con una componente di edge computing visiva, e avremo quindi:

  • NestedCustomMessage.msg che conterrà un’istanza dei seguenti messaggi e vi aggiungerà un ID
  • LidarGradient.msg rappresentante i valori del gradiente computato su una serie di letture da parte di un LiDAR
  • BoundingBoxLabeled.msg contenente le coordinate di una bounding box e la relativa label
  • EncodersReadings.msg con i valori letti dagli encoder delle ruote del nostro robot

Di seguito riportiamo le definizioni dei messaggi, in modo da avere un’idea chiara e immediata della loro struttura. In particolare possiamo notare come messaggi personalizzati possano essere annidati per andare a comporne altri più complessi, nel caso di NestedCustomMessage.

NestedCustomMessage.msg
int32 id
LidarGradient gradient
BoundingBoxLabeled bb_labeled
EncodersReadings enc_readings
LidarGradient.msg
float32[] measures
BoundingBoxLabeled.msg
string label
float32 x_left
float32 x_right
float32 y_top
float32 y_bottom
EncodersReadings.msg
float32 wheel1
float32 wheel2
float32 wheel3

Garantire la compilazione e generazione dei messaggi

Per poter usufruire dei messaggi che abbiamo definito è necessario dare indicazione a ROS di dove si trovino e delle dependencies necessarie alla loro compilazione e generazione. Per questo motivo apporteremo delle modifiche al file CMakeLists.txt e al Package.xml del nostro package.

Package.xml

All’interno di questo file dobbiamo aggiungere le due seguenti righe:

<build_depend>message_generation</build_depend>
<exec_depend>message_runtime</exec_depend>

CMakeLists.txt

Qui partiamo dal modificare le required components in questo modo:

find_package(catkin REQUIRED COMPONENTS
   rospy
   std_msgs
   message_generation
)

Indichiamo poi i file in cui abbiamo definito i messaggi (i file verranno cercati all’interno della cartella “msg” del nostro package):

add_message_files(
   FILES
   LidarGradient.msg
   BoundingBoxLabeled.msg
   EncodersReadings.msg
   NestedCustomMessage.msg
)

E includiamo le dependencies necessarie per la generazione dei nostri messaggi. In questo caso i nostri messaggi dipendono solo da std_msgs (abbiamo usato solo stringhe e float), per cui sarà sufficiente includere:

generate_messages(
   DEPENDENCIES
   std_msgs
)

Generazione dei messaggi

Possiamo a questo punto verificare che tutto sia stato definito in modo corretto e che ROS sia in grado di trovare, identificare e generare i nostri messaggi personalizzati.
Ci spostiamo all’interno di un terminale, a livello del nostro workspace di catkin, e ricompiliamo.

catkin_make

Importare e accedere ai singoli campi dei messaggi

La situazione di partenza di questo tutorial è un semplice publisher (custom_messages_nesting/script/custom_user_node.py) che pubblica un Float32. Andremo ora a modificare il codice per poter includere i nostri messaggi.

#! /usr/bin/env python3

import rospy
from std_msgs.msg import Float32

def start_chatter():
   rospy.init_node('custom_chatter')
   pub = rospy.Publisher('custom_chatter_topic', Float32, queue_size = 10)
   rate = rospy.Rate(1)
   id = 0
   while not rospy.is_shutdown():
      id += 1
      pub.publish(id)
      rate.sleep()

if __name__ == "__main__":
   try:
      start_chatter()
   except rospy.ROSInterruptException:
      pass

Vogliamo per prima cosa importare i messaggi personalizzati. Aggiungiamo quindi (o rimpiazziamo l’import già presente con):

from custom_messages_nesting.msg import LidarGradient.msg, BoundingBoxLabeled.msg, EncodersReadings.msg, NestedCustomMessage.msg

Possiamo poi quindi ridefinire il publisher in modo che pubblichi il nostro NestedCustomMessage:

pub = rospy.Publisher('custom_chatter_topic', NestedCustomMessage, queue_size = 10)

Per poter accedere ai singoli campi della struttura del NestedCustomMessage (nel caso della pubblicazione) sarà sufficiente istanziare i sottomessaggi di cui è composto e assegnare ai rispettivi campi i valori letti dai nostri ipotetici sensori.
Istanziamo quindi tutti i messaggi necessari:

nc = NestedCustomMessage()
gradient_msg = LidarGradient()
bb_labeled_msg = BoundingBoxLabeled()
enc_readings_msg = EncodersReadings()

E procediamo ad assegnare loro dei valori, accedendo ai campi del messaggio con il nome che abbiamo indicato all’interno della rispettiva definizione. In particolare per questo esempio abbiamo selezionato i seguenti valori:

gradient_msg.measures = range(36)
bb_labeled_msg.label = 'Persona'
bb_labeled_msg.x_left = bb_labeled_msg.y_bottom = 1.0
bb_labeled_msg.x_right = bb_labeled_msg.y_top = 2.0
enc_readings_msg.wheel1 = enc_readings_msg.wheel2 = enc_readings_msg.wheel3 = 0.035

Avendo assegnato valori a tutte le componenti di NestedCustomMessage, queste possono poi essere unite per andare a comporre il nostro messaggio finale in questo modo:

nc.id = id
nc.gradient = gradient_msg
nc.bb_labeled = bb_labeled_msg
nc.enc_readings = enc_readings_msg

Test del publisher

Per verificare che tutto funzioni correttamente sarà sufficiente eseguire il nodo e osservare il relativo topic.
In una prima shell:

roscore

In una seconda shell:

rosrun custom_messages_nesting custom_user_node.py

E infine in una terza shell:

rostopic echo /custom_chatter_topic

Il risulato che ci aspettiamo è di osservare che il nostro messaggio viene pubblicato una volta al secondo, con ID crescente e con gli altri campi in accordo con quello che abbiamo indicato nel codice del nodo.

E con questo abbiamo accesso a infinite possibilità, componendo i messaggi come più conviene e utilizzandoli all’interno della nostra implementazione!

Video Tutorial

ROS su più macchine – Italian ROS Tutorial

ROS su più macchine – Italian ROS Tutorial

In questo tutorial vedremo come sia possibile configurare ROS per funzionare su più macchine connesse attraverso la rete, espandendo le possibilità per i tuoi progetti.

La configurazione iniziale parte da un nodo publisher minimale chatter.py appartenente al pacchetto chatter, con un singolo publisher di stringhe.

 

Come definire e utilizzare servizi personalizzati – ROS Italian Tutorial

Come definire e utilizzare servizi personalizzati – ROS Italian Tutorial

This tutorial is created by Rosbotics Ambassador 012 Alessandro 

Rosbotics Ambassador Program https://www.theconstruct.ai/rosbotics-ambassador/)

Contenuto del tutorial

  1. Come creare Service personalizzati
  2. Cosa definisce la struttura di un Service
  3. Quali cambiamenti apportare al package per compilare il nuovo Service
  4. Come importare i messaggi relativi al Service all’interno del nostro package

In questo video imparerai come definire e utilizzare i servizi personalizzati.

Risorse

  1. Rosject utilizzato per questo tutorial
  2. Piattaforma: The Construct
  3. Corso: ROS Basics in 5 days

Come utilizzare i Rosject

Nel caso non si volesse installare ROS Noetic sul proprio sistema e fare il set up dell’ambiente di sviluppo, è possibile utilizzare i Rosject offerti da The Construct per poter testare i contenuti del tutorial o per seguirlo passo passo.

Per fare ciò sarà sufficiente seguire il link indicato nelle risorse e cliccare su “Run”. In questo modo si avrà accesso a una copia del Rosject utilizzato all’interno del tutorial.

Aprire terminal e IDE

Per aprire un nuovo terminale e avere accesso all’IDE forniti dal Rosject, sarà possibile utilizzare la console in basso a destra

Creare un nuovo package

Per poter creare un nuovo package sarà sufficiente spostarsi all’interno del workspace di catkin, e creare il package con l’aiuto di catkin_create_pkg. In questo caso aggiungendo come dependencies rospy (poiché scriveremo in Python) e std_msgs.
cd ~/catkin_ws
catkin_create_pkg custom_srv_pkg rospy std_msgs

Creare un nuovo file per la definizione del Service

Quello che bisogna fare ora è creare una cartella che possa contenere i file di definizione dei Service e il file per il nostro Service personalizzato.

mkdir custom_srv_pkg/srv
touch custom_srv_pkg/srv/CustomSrvMsg.srv

Definizione della struttura del Service personalizzato

I servizi sono identificati da due sezioni, divise da un triplo dash (- – -):

Request: inviata da un client a un server, con i parametri necessari all’esecuzione del servizio

Response: ritornata dal server al client, con eventuali risultati dell’esecuzione del servizio

Request e response possono essere anche vuoti

All’interno delle due sezioni possiamo usare per esempio std_msgs, ma anche altri tipi di messaggio come geometry_msgs. 

Andiamo quindi a definire il nostro servizio con i seguenti parametri:
# Request
string da_stampare
geometry_msgs/Point punto
---
# Response
float64 somma
bool successo

In questo caso abbiamo una stringa da stampare, un punto tridimensionale, una variabile somma rappresentante la somma delle coordinate del punto e un booleano che indica il successo dell’esecuzione del servizio.

CMakeLists e package.xml

Per permettere la compilazione del servizio e la generazione dei relativi messaggi, bisogna apportare qualche modifica al file CMakeLists e al package.xml.

CMakeLists

Qui sarà necessario includere le seguenti linee:

cmake_minimum_required(VERSION 3.0.2)
project(custom_srv_pkg)
find_package(catkin REQUIRED COMPONENT
rospy
std_msgs
message_generation # per la generazione dei messaggi relativi al servizio
geometry_msgs # poiché abbiamo utilizzato un messaggio di questo tipo
)
add_service_files(
FILES
CustomSrvMsg.srv # il nostro file dove abbiamo definito il servizio
)
generate_messages(
DEPENDENCIES
std_msgs
geometry_msgs # per generare messaggi contenenti geometry_msgs
)
catkin_package(
CATKIN_DEPENDS rospy std_msgs
)

package.xml

All’interno del package.xml dovremo aggiungere le dependencies per la generazione e l’utlizzo dei messaggi relativi al servizio

<build_depend>message_generation</build_depend>
<build_export_depend>message_runtime</build_export_depend>
<exec_depend>message_runtime</exec_depend>

Compilazione

cd ~/catkin_ws
catkin_make –only-pkg-with-deps custom_srv_pkg
source devel/setup.bash # poiché sono stati generati nuovi messaggi e servizi

Verificare la generazione dei messaggi del Service personalizzato

Per poter verificare la presenza dei messaggi relativi al nostro nuovo messaggio e il loro contenuto possiamo utilizzare i seguenti comandi:
rossrv list | grep custom # grep custom è usato per filtrare l’output
# l’output sarà del tipo:
# custom_srv_pkg/CustomSrvMsg
rossrv show custom_srv_pkg/CustomSrvMsg
# l’output sarà del tipo:
# string da_stampare
# geometry_msgs/Point punto
# float64 x
# float64 y
# float64 z
# ---
# float64 somma
# bool successo

Importare i messaggi generati per il servizio

All’interno dello script server.py possiamo importare:

  • Nel caso di un server:
    • [NomeDelMessaggioDelServizio]
    • [NomeDelMessaggioDelServizio]Response
  • Nel caso di un client:
    • [NomeDelMessaggioDelServizio]
    • [NomeDelMessaggioDelServizio]Request

Nel tutorial scriveremo un esempio di un server di Servizi, quindi importeremo i messaggi in questo modo:

from custom_srv_pkg.srv import CustomSrvMsg,CustomSrvMsgResponse
# from custom_srv_pkg.srv import CustomSrvMsg,CustomSrvMsgRequest # nel caso client

Accesso ai parametri di request e response

In una possibile implementazione del nostro server accediamo a request, ricevuto dal client tramite una callback invocata ogni volta che viene richiesto il servizio, e ai relativi parametri.

Possiamo poi istanziare una response (di tipo CustomSrvMsgResponse) e riempirne i campi con le informazioni che ci interessa ritornare al client.

#! /usr/bin/env python
import rospy
from custom_srv_pkg.srv import CustomSrvMsg, CustomSrvMsgResponse
# CustomServiceRequest in caso di un client
def callback(request):
response = CustomSrvMsgResponse()
print(request.da_stampare)
response.somma = request.punto.x + request.punto.y + request.punto.z
response.successo = True
return response
rospy.init_node("service_server")
service = rospy.Service("my_service", CustomSrvMsg, callback)
rospy.spin()

Conclusione

Se siete riusciti a seguire fino a qui sarà possibile compilare il package e eseguire il nodo relativo al Service server. In questo modo sarà reso disponibile il servizio che potrà essere chiamato da linea di comando o da un client.

# terminale 1
roscore
# terminale 2
rosrun custom_srv_pkg server.py # esecuzione del nodo server.py
# terminale 3
rosservice list | grep my # mostra tutti i servizi disponibili contenenti "my"
rosservice call /my_service [TAB] [TAB] # chiama il servizio e precompone la request

 

 

Video Tutorial

Utilizzare una Singola Callback per Molteplici Subscriber – ROS Italian Tutorial

Utilizzare una Singola Callback per Molteplici Subscriber – ROS Italian Tutorial

This tutorial is created by Rosbotics Ambassador 012 Alessandro 

Rosbotics Ambassador Program https://www.theconstruct.ai/rosbotics-ambassador/)

In questo tutorial verrà mostrata un’implementazione di un nodo subscriber in grado di leggere messaggi di diverso tipo e provenienti da molteplici topic, gestiti attraverso una singola funzione di callback.

Risorse

Come utilizzare i Rosject

Nel caso non si volesse installare ROS Noetic sul proprio sistema e fare il set up dell’ambiente di sviluppo, è possibile utilizzare i
Rosject offerti da The Construct per poter testare i contenuti del tutorial o per seguirlo passo passo.
Per fare ciò sarà sufficiente seguire il link indicato nelle risorse e cliccare su “Run”. In questo modo si avrà accesso a una copia del
Rosject utilizzato all’interno del tutorial.

Aprire terminal e IDE

Per aprire un nuovo terminale e avere accesso all’IDE forniti dal Rosject, sarà possibile utilizzare la console in basso a destra.

Prerequisiti

Per poter seguire il tutorial passo passo sarò necessario avere il nodo publisher, che pubblica su diversi topic, attivo e creare un package dove poter inserire il codice per il subscriber.
Per iniziare eseguiamo il nodo publisher. Sarà sufficiente aprire il terminale dalla console (vedi Risorse) e inserire i seguenti comandi nelle rispettive schede del terminale:

Terminale 1:
roscore
Terminale 2:
cd catkin_ws
rosrun publisher publisher.py

Quindi è possibile verificare il corretto funzionamento del nodo aprendo una seconda finestra al’interno del terminale e osservando l’output del comando rostopic list.
L’output previsto è il seguente:

Terminale 3:
rostopic list

/chatter0
/chatter1
/chatter2
/rosout
/rosout_agg

Procediamo quindi a creare il package per il subscriber:

Terminale 3:
cd src
catkin_create_pkg multiple_subscriber rospy std_msgs
mkdir multiple_subscriber/script

Situazione di partenza

Al momento abbiamo eseguito il nodo publisher che pubblica su 3 topic messaggi di vario tipo. In particolare:

  • /chatter0 pubblica messaggi di tipo String
  • /chatter1 pubblica messaggi di tipo Float64
  • /chatter2 pubblica messaggi di tipo Bool

Vediamo quindi come possiamo gestire tutti e tre i topic, creando un subscriber in grado di leggere i messaggi dai chatter e di gestirli con una singola funzione di callback, differenziando il risultato di quest’ultima sfruttando l’uso di parametri.

Creazione del file multiple_sub.py

Proseguiamo creando il file necessario a definire il nostro subscriber e tutte le sue funzioni.

Terminale 3:
touch multiple_sub/script/multiple_subscriber.py # Crea il file
chmod +x multiple_sub/script/multiple_subscriber.py # Garantisce i permessi di esecuzione
cd ..
catkin_make

Implementazione del subscriber

Partiamo quindi dallo specificare un interprete per il nostro codice in Python, dall’importare i moduli necessari (rospy e in questo caso std_msgs/String, std_msgs/Float64, std_msgs/Bool) e dallo scrivere un main che inizializzi il nodo e invochi rospy.spin() per poter eseguire le callback del nostro subscriber.

main

multiple_subscriber.py
import rospy
from std_msgs.msg import String, Float64, Bool

if __name__=="__main__":

rospy.init_node("multiple_subscriber")

topics = {"chatter0": [String, "Argomento passato da chatter0"], "chatter1": [Float64, "Argomento passato da chatter1"], "chatter2": [Bool, "Argomento passato da chatter2"]}

multiple_subscribe()

rospy.spin()

All’interno della funzione abbiamo definito anche topics, un dizionario contenente le specifiche dei topic che vogliamo andare a leggere, seguendo la seguente struttura:
{"nome_topic": [Tipo, Argomento]}

Per ogni chiave topic abbiamo quindi definito una lista contente il tipo del messaggio inviato dal topic e un argomento (in questo caso una stringa che esplicita di essere l’argomento passato per lo specifico topic) .

multiple_subscribe

La funzione multiple_subscribe() sarà definita perché il nodo possa seguire i 3 topic e perché i messaggi pubblicati possano innescare la callback.

multiple_subscriber.py
def multiple_subscribe():

for t in topics:

rospy.Subscriber(t, topics[t][0], callback, callback_args=topics[t][1])

Il nodo segue quindi ciascuno dei topic definiti nel dizionario, aspettandosi messaggi del relativo tipo, invocando una funzione callback e passando il relativo argomento tramite il parametro callback_args.

callback

Vediamo una semplice implementazione della callback per poter gestire i tre topic.

multiple_subscriber.py
def callback(data, args):

rospy.loginfo(f"Ricevuto: {data.data}")

print(args)

print('\n')

In questo caso andiamo a stampare come info di ROS il contenuto del messaggio arrivato alla callback e stampiamo l’argomento passato corrispondente. Entrambi dipenderanno da quale topic ha innescato la callback e perciò a questo livello il messaggio può essere gestito a seconda del parametro ad esso associato, potendo implementare in qualche modo un’esecuzione “su misura” della funzione di callback.

Test del subscriber

Siamo pronti per poter eseguire il nostro subscriber!
Ciò che ci aspettiamo è che vengano stampati allo stesso tempo il messaggio e l’argomento relativi alla callback innescata dall’arrivo di un messaggio dal singolo topic. L’output dovrebbe quindi essere di questo tipo:

[INFO] [***.***]: Ricevuto: Questo pubblica una stringa
Argomento passato da chatter0

[INFO] [***.***]: Ricevuto: 0.42
Argomento passato da chatter1

[INFO] [***.***]: Ricevuto: True
Argomento passato da chatter2

Per fare ciò dobbiamo eseguire il nostro nodo:

Terminale 3:
rosrun multiple_sub multiple_subscriber.py

Possiamo osservare come gli output si alternano ogni secondo a rotazione, ma questo è dovuto alla singola implementazione del publisher (che è possibile trovare all’interno del Rosject, vedi Risorse).

In ogni caso per ogni topic viene ricevuto, gestito e stampato un messaggio specifico relativo ad esso, e l’elaborazione del relativo parametro, con diverso risultato nonostante l’utilizzo della medesima funzione di callback.

Video Tutorial

Pin It on Pinterest