Utilizzare una Singola Callback per Molteplici Subscriber – ROS Italian Tutorial

Written by Alessandro Pozzoni

06/02/2024

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

Masterclass 2023 batch2 blog banner

Check Out These Related Posts

0 Comments

Submit a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Pin It on Pinterest

Share This