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

گیزبو سمولیشن میں روبوٹ میں ورچوئل ڈیپتھ کیمرہ کیسے شامل کریں۔ – Udru ROS Tutorial

گیزبو سمولیشن میں روبوٹ میں ورچوئل ڈیپتھ کیمرہ کیسے شامل کریں۔ – Udru ROS Tutorial

This tutorial is created by Rosbotics Ambassador 020 Muhammad

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


کمپیوٹر ویژن روبوٹکس میں ایک اہم حصہ ہے اور روبوٹکس میں کمپیوٹر ویژن الگورتھم کو لاگو کرنے اور جانچنے کے لیے ہمیں اپنے روبوٹ میں ویژن سینسرز (RGB اور RGB-D کیمروں) کو ضم کرنے کی ضرورت ہے۔ اس پوسٹ میں ہم مصنوعی ماحول کو دیکھنے کے لیے Gazebo Simulation میں اپنے روبوٹ میں مصنوعی RGB-D کیمرہ شامل کرنا سیکھیں گے۔

اس پوسٹ میں استعمال ہونے والے وسائل کی فہرست

کیا آپ روبوٹکس میں مہارت حاصل کرنا چاہتے ہیں؟ روبوٹکس ڈویلپر ماسٹر کلاس: https://www.theconstruct.ai/robotics-developer/

جائزہ:

سمولیشن روبوٹک سسٹمز ٹیسٹنگ میں ایک مربوط حصہ ہے، روبوٹکس سسٹمز کے تمام پہلوؤں کو صحیح طریقے سے جانچنے کے لیے، تمام اجزاء کو سمولیشن میں شامل کیا جانا چاہیے (بشمول سینسر، ایکچویٹرز وغیرہ)۔ Gazebo، روبوٹکس میں بڑے پیمانے پر استعمال ہونے والا سمولیشن سافٹ ویئر ہونے کے ناطے، اس میں بنائے گئے زیادہ تر سینسرز کے لیے تعاون حاصل ہے۔

ROS Inside!

ROS Inside

Before anything else, if you want to use the logo above on your own robot or computer, feel free to download it, print it, and attach it to your robot. It is really free. Find it in the link below:

ROS Inside Logo

Opening the ROSJect:

پوسٹ میں فراہم کردہ لنکس کا استعمال شروع کرنے سے ہی سب کچھ کرنے کی سفارش کی جاتی ہے۔ وہاں نقلی چلانے کے لیے، پہلے سے ہی ایک ROSJect تیار ہے جسے آپ ہر چیز کو دوبارہ پیش کرنے کے لیے استعمال کر سکتے ہیں، ROSJect کو صرف حوالہ کے طور پر استعمال کریں: https://app.theconstructsim.com/l/5ef573e3/

ROSJect کھولنے کے بعد، ٹرمینل چلائیں۔

کمانڈ کا استعمال کرتے ہوئے اپنے ROS ورک اسپیس پر جائیں:

cd catkin_ws

اور پھر بھاگو

catkin_make

کام کی جگہ کو دوبارہ بنانے کے لیے۔

اب، آپ نے کام کی جگہ کو کامیابی کے ساتھ بنایا ہے، تبدیلیوں کو مؤثر بنانے کے لیے آپ کو اس کا ذریعہ بنانا ہوگا۔

source devel/setup.bash

انحصار انسٹال کرنا:

اب ہمیں تخروپن کو چلانے کے لیے کچھ انحصار انسٹال کرنے کی ضرورت ہے۔ ٹرمینل کھولیں اور ٹائپ کریں:

sudo apt update

مندرجہ بالا کمانڈ پر عمل کرنے کے بعد، ایک اور کمانڈ چلائیں

sudo apt install ros-noetic-turtlebot3 ros-noetic-turtlebot3-simulations -y

نقلی چل رہا ہے۔

ٹرمینل کھولیں اور چلائیں:

roslaunch my_robot_gazebo my_robot_world.launch

ایک گیزبو سمولیشن ونڈو کھلی ہے جس میں آپ کے روبوٹ کو بنایا گیا ہے۔

آپ شائع ہونے والے عنوانات کو دیکھنے کے لیے دوسرا ٹرمینل بھی کھول سکتے ہیں۔

 

کمانڈ ٹائپ کریں۔

rostopic list

اس میں ان تمام موضوعات کی فہرست دی جائے گی جو فی الحال شائع ہو رہے ہیں۔

رنگین تصویری موضوع کو تصور کرنا

نقلی کیمرہ فیڈ دیکھنے کے لیے کمانڈ چلائیں۔

rosrun image_view image_view image:=/mobile_robot/color/image_raw

RViz میں پوائنٹ کلاؤڈ ڈیٹا کا تصور کرنا

ہم RViz میں پوائنٹ کلاؤڈ ڈیٹا کو بھی دیکھ سکتے ہیں۔ ٹرمینل چلائیں اور ٹائپ کریں:

rosrun rviz rviz

یہ RViz کے ساتھ نئے گرافیکل ٹولز ونڈو کو کھولے گا۔ “شامل کریں” پر کلک کریں اور “پوائنٹ کلاؤڈ 2” فیلڈ شامل کریں۔

اس کے بعد، اس موضوع کو منتخب کریں جس پر پوائنٹ کلاؤڈ ڈیٹا شائع کیا گیا ہے جیسا کہ ذیل کی تصویر میں دکھایا گیا ہے۔

آپ پوائنٹ کلاؤڈ ڈیٹا کو دیکھ سکیں گے جو روبوٹ میں کیمرہ فریم کے میدان میں ہے، مندرجہ ذیل ہے۔

حتمی خیالات:

اب جب کہ ہمارے پاس گیزبو ماحول میں اپنے روبوٹ سمولیشن میں کیمرہ فیڈ موجود ہے، ہم اسے مختلف کاموں کو انجام دینے کے لیے استعمال کر سکتے ہیں جیسے کہ کمپیوٹر وژن، آبجیکٹ کا پتہ لگانے، سیمنٹک سیگمنٹیشن، اور لوکلائزیشن وغیرہ۔ یہ بھی نوٹ کریں کہ RViz میں پوائنٹ کلاؤڈ ڈیٹا غلط ہے۔ واقفیت. اس کو حل کرنے کے لیے ہمیں بیس لنک سے کیمرہ لنک میں کچھ سٹیٹک ٹرانسفارمز شامل کرنے ہوں گے (ہم آنے والی پوسٹس میں دیکھیں گے)۔


Video Tutorial

Crea un Paquete MoveIt Para Tu Robot – ROS Spanish Tutorial

Crea un Paquete MoveIt Para Tu Robot – ROS Spanish Tutorial

This tutorial is created by Rosbotics Ambassador 017 Jose

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

Lo que vamos a aprender

  1. Como iniciar y usar el asistente de configuración de MoveIt
  2. Como configurar un paquete de configuración MoveIt para un robot
  3. Como ejecutar el launch de ejemplo de MoveIt en RViz

Lista de recursos usados en esta publicación

  1. Usa este rosject: https://app.theconstructsim.com/l/5f3d5b06/
  2. The Construct: https://app.theconstructsim.com/
  3. Cursos ROS: ROS Manipulation in 5 Days: https://app.theconstructsim.com/courses/66

Resumen

ROS (Robot Operating System) se está convirtiendo en el “framework” estándar para programar robots. En este tutorial crearemos paso a paso el paquete de configuración de MoveIt usando Moveit Setup Assistant para tu robot. Ten encuesta que se usará ROS Noetic para este tutorial.

PASO 1: Abriendo el rosject

Para seguir este tutorial, necesitamos tener instalado ROS en nuestro sistema, y lo ideal sería tener un catkin_ws (Espacio de Trabajo ROS). Para facilitarte la vida, ya hemos preparado un rosject para eso: https://app.theconstructsim.com/l/5f3d5b06/.

Simplemente copiando el rosject (haciendo clic en el enlace de arriba), tendrás una configuración ya preparada para ti.

Después de haber copiado el rosject a tu propia área de trabajo, deberías ver el botón RUN. Haz clic en ese botón para lanzar el rosject (abajo tienes un ejemplo de rosject).

RUN rosject

Tras pulsar el botón RUN, deberías tener cargado el rosject. Ahora, pasemos a la siguiente sección para ponernos manos a la obra.

PASO 2: Iniciando MoveIt Setup Assistant

Para crear un paquete MoveIt para nuestro robot usando el asistente de configuración de MoveIt necesitamos solamente el paquete de descripción de este (que contenga los archivos urdf/xacro y los meshes de ser necesario).

El robot que se usará es el EDO (una paquete de descripción con una versión simplificada).

EDO

Para iniciar el asistente ejecutamos el siguiente comando en una terminal:

roslaunch moveit_setup_assistant setup_assistant.launch

Con ello se iniciar el asistente y deberíamos ver esta interfaz:

Inicio asistente

PASO 3: Configurar el paquete con la ayuda del asistente

El asistente de MoveIt tiene múltiples pestañas de configuración. Recorreremos cada una de ellas en orden configurando lo necesario.

Inicio (Start)

En esta parte cargamos la descripción de nuestro robot mediante el archivo urdf/xacro principal.

Para seleccionamos la opción Create New Moveit Configuration Package, luego buscamos el xacro de nuestro robot dándole a Browse y luego le damos a Load Files para cargar nuestro robot.

Seleccionar URDF

Esperamos, y si todo esta correcto con nuestro archivo Xacro/URDF se mostrará nuestro robot en la parte derecha.

URDF Cargado

Autocolisiones (Self-collisions)

En esta parte le decimos a MoveIt que pares de juntas no necesita revisar por colisiones ya que siempre están en colisión, reduciendo así la carga computacional a este proceso.

Aquí solo pulsamos el botón Generate Collision Matrix y la matriz ya se genera automáticamente.

Autocolisiones

Juntas virtuales (Virtual Joints)

En esta parte creamos una junta virtual entre la base del robot y un sistema coordenado de referencia. Sirve para posicionar el robot en world o una plataforma móvil.

Esta configuración ya se puede hacer desde nuestro archivo xacro (como en este ejemplo), por lo que no se definirá ninguna junta virtual.

Juntas virtuales

Grupos de planificación (Planning groups)

En esta parte se crea los grupos de planificación ya que MoveIt trabaja con grupos para la planificación de movimiento. Típicamente se configura un grupo para las juntas del brazo robótico y otro para el efector final.

Aquí le damos a Add Group, y configuramos las opciones que nos aparecen.

  • Group Name: Nombre del grupo a elección. Le colocaremos arm.
  • Kinematic Solver: El plugin encargado de resolver la cinemática del robot. Usaremos KDLKinematicsPlugin.
  • Group Default Planner: El algoritmo encargado de realizar la planificación de movimiento. Usaremos RRT.

Las demás opciones las dejamos con sus valores por defecto y ahora seleccionaremos las juntas que pertenecerán a este grupo, para ello le damos a Add Joints.

Grupos de planificación

Seleccionamos las juntas que deseamos que pertenezcan al grupo, y le damos a Save.

Juntas de grupo

Debido a que el robot del ejemplo no cuenta con un efector final solo creamos un grupo para el brazo robótico.

Poses del robot (Robot Poses)

En esta parte configuramos posiciones del robot según nuestras necesidades. Para ello asignamos un set de valores de juntas para la pose deseada y le asignamos un nombre.

Le damos a Add Pose, seleccionamos el grupo de planificación (solo tenemos a arm en este caso), le ponemos un nombre (home que siempre es conveniente definirlo) y le damos los valores correspondientes a las juntas moviendo los Sliders o colocando directamente los valores. Le damos a Save para guardar esta pose.

Poses del robot

Añadimos otra pose al robot a la que llamaremos Inicio, al que le puedes dar los valores válidos que desees. En la parte derecha puedes ver la pose que robot adopta. Esta pestaña es importante para ver si las juntas de tu robot están correctamente definidas en la descripción.

Efectores final (End Effectors)

En esta parte se añaden los efectores finales definiendo el nombre, el grupo de planificación y el sistema coordenado padre.

Ya que en este ejemplo no contamos con un efector final no lo definiremos.

Efector final

Juntas Pasivas (Passive Joints)

En esta parte se definen las juntas que no tiene un actuador. Ya que nuestro robot no tiene ese tipo de juntas no definiremos nada en esta pestaña.

Juntas pasivas

Controladores (Controllers)

En esta parte se definen los controladores, los cuales deben ser los adecuados para nuestro robot.

Le damos a Add Controller, le ponemos un nombre a elección, seleccionamos el tipo de controlador y seleccionamos el grupo de planificación al que se aplicará este controlador.

Controladores

Luego solo seleccionamos el grupos de planificación correspondiente y guardamos. Con ello ya tendríamos el controlador configurado.

Grupo del controlador

Simulación (Simulation)

En esta parte se puede autogenerar los cambios necesarios en el URDF para que los controladores y MoveIt sea compatible con la simulación en Gazebo. Los cambios se muestran en verde luego de darle click a Generate URDF.

URDF autogenerado

Básicamente se añaden inercias, transmisiones y el plugin gazebo_ros_control, sin embargo, todo ello ya esta definido en el xacro de nuestro robot así que no necesitaremos copiar y pegar este URDF generado.

Percepción 3D (3D Perception)

En esta parte se configura el sensor 3D con el cual trabaja nuestro robot. Podemos seleccionar entre 2 tipos de plugins para sensor 3D: PointCloud y Depth Map. Y luego configurar algunos parámetros y el tópico que se usará.

Ya que en este ejemplo el robot no cuenta con un sensor, no lo configuraremos.

Sensor

Información del autor (Author Information)

En esta parte se inserta el nombre y el correo del creador del paquete.

Información del autor

Archivos de configuración (Configuration Files)

En esta parte se genera el paquete de configuración de MoveIt con todo lo que hemos definido previamente.

Para ello, primero le damos a Browse para seleccionar la carpeta en la que queremos guardar nuestro paquete, debemos elegir un nombre (es común usar la estructura nombreRobot_moveit_config), luego le damos a Generate Package, le damos Ok en la ventana de advertencia que nos aparece (Nos alerta que no definimos juntas virtuales ni efector final) y esperamos a que se genere nuestro paquete.

Generar paquete

Una vez generado nuestro paquete le damos a Exit Setup Assistant. Con ello ya tenemos nuestro paquete MoveIt listo para usarse.

Paquete generado

Los archivos del paquete los puedes encontrar en la ruta que especificaste anteriormente, esta compuesto de archivos de configuración y launch.

Archivos generados

Ejecutar la demo en RViz

Listo! ya tenemos nuestro paquete MoveIt generado, para probarlo ejecutaremos el launch demo.launch con el siguiente comando:

roslaunch edo_moveit_config demo.launch

Con ello se iniciará RViz junto con todo lo necesario para realizar la planificación de movimiento a través de la interfaz que se carga en RViz. En la pestaña Planning de dicha interfaz podemos seleccionar un grupo de planificación, una pose inicial, una pose deseada y darle a planear y ejecutar.

Demo en RViz

Observarás como el robot se mueve por la ruta planificada. Y así de sencillo!, partiendo de un paquete de descripción de nuestro robot podemos realizar planificación de movimiento gracias al asistente de MoveIt.

Video Tutorial

Como utilizar uma Action do ROS para resolver um problema prático de navegação em Python – ROS Portuguese Tutorial

Como utilizar uma Action do ROS para resolver um problema prático de navegação em Python – ROS Portuguese Tutorial

This tutorial is created by Rosbotics Ambassador 014 Anderson

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


O que nós vamos aprender:

    1. Como acessar as mensagens associadas a uma ação
    2. Como criar um servidor de ações
    3. Como inicializar uma ação
    4. Como disponibilizar uma informação de odometria enquanto o robô se move

Lista de recursos usados neste post:

  1. Use este rosject: https://app.theconstructsim.com/l/5e7ce8b4/
  2. The Construct: https://app.theconstructsim.com/
  3. ROS Courses: ROS Basics in 5 Days (Python) https://app.theconstructsim.com/Course/55
  4. ROS Couses: ROS Navigation: https://app.theconstructsim.com/courses/57

Panorama
Em ROS, quando se fala em realizar uma tarefa enquanto uma outra está sendo realizada, estamos falando das “Actions”. Neste artigo, trataremos de um exemplo em ROS com o TurtleBot3 programado em Python. Basicamente, dada uma posição no espaço, teremos que iniciar uma ação que cuidará de calcular o quanto nosso robô está longe da posição inicial enquanto este se movimenta pelo ambiente.

Abrindo o rosject
Para seguir este tutorial, será útil e conveniente usar um rosject (que a grosso modo é um projeto ROS configurado para rodar um exemplo).
Acesse o link:
https://app.theconstructsim.com/l/5e7ce8b4/
Clique no botão vermelho “RUN”:

Descobrindo as mensagens associadas:
Abra um terminal clicando no ícone indicado na figura:

Na janela do primeiro terminal, insira o comando:

roscd actionlib

Você notará que o caminho para a pasta será:

user:/home/simulations/public_sim_ws/src/all/actionlib/actionlib

Isso significa que você está acessando a pasta de um pacote chamado actionlib. Neste pacote, tipos padrão de mensagens usadas para realizar ações podem ser encontradas e isso nos será útil.

Navegue para a pasta action com o comando:

cd action

Aqui, você encontra um arquivo chamado Test.action. Para visualizá-lo diretamente no terminal, rode:

cat Test.action

O seguinte conteúdo é apresentado:

int32 goal
---
int32 result
---
int32 feedback

Muitas informações importantes são extraídas deste arquivo. Por exemplo, vemos a estrutura padrão de um arquivo de ação que contém objetivo, resultado e feedback separados pelos hífens. Não necessariamente teremos variáveis associadas a esses tipos em todos os arquivos. No nosso exemplo, estamos especialmente interessados no feedback (que não precisa ter esse nome sempre).

Criando um servidor de ações
Clique no ícone para abrir a IDE e navegue nas pastas do workspace para encontrar o arquivo action_server.py.

Neste arquivo, vemos como a informação da ação é utilizada. Por exemplo, precisamos importar as possíveis mensagens, por isso temos:

from actionlib.msg import TestFeedback, TestResult, TestAction

Repare na implementação de variáveis necessárias para o código:

_feedback = TestFeedback()
_result   = TestResult()

Gaste alguns minutos lendo o código para entender como a distância para a localização inicial é calculada.
No terminal 1, rode o comando:

roslaunch realrobotlab main.launch

Você será apresentado à uma janela do Gazebo como esta:

Aproxime-se (zoom in) para visualizar o nosso robô no centro da tela:

Inicializando e verificando a ação
No terminal 2, rode o servidor de ações que acabamos de ver:

rosrun basic_project action_server.py

No terminal 3, inicialize a ação publicando na variável goal:

rostopic pub /record_odom/goal actionlib/TestActionGoal "header:
seq: 0
stamp:
secs: 0
nsecs: 0
frame_id: ''
goal_id:
stamp:
secs: 0
nsecs: 0
id: ''
goal:
goal: 0"

Existem outras formas de se inicializar uma ação por exemplo usando um script dedicado (action client) ou mesmo usando a interface gráfica axclient via comando:

rosrun actionlib_tools axclient.py /record_odom

obs.: Você pode usar o comando anterior no terminal 3 se preferir ao invés do comando de publição no tópico.

Clique no ícone de ferramentas gráficas para visualizar o axclient:

Independentemente da forma como você inicialize o servidor de ações, em um novo terminal (4) você pode verificar a variável feedback sendo atualizada com o valor da distância calculada entre a posição atual e a inicial do robô.

rostopic echo /record_odom/feedback

Para fazer o exemplo mais ilustrativo, você pode mover o robô usando as teclas do seu teclado, isto é, teleoperando o robô. Para teleoperar o robô, abra um novo terminal (5) e rode:

rosrun teleop_twist_keyboard teleop_twist_keyboard.py

Então, verá como a distância varia no seu terminal dedicado a ecoar tal resultado. Não se perca em meio a tantos terminais abertos simultaneamente. Algo como isto será apresentado na sua tela:

---
header:
seq: 581
stamp:
secs: 1597
nsecs:  72000000
frame_id: ''
status:
goal_id:
stamp:
secs: 1016
nsecs:  62000000
id: "/axclient_5154_1705261443951-1-1016.062"
status: 1
text: "This goal has been accepted by the simple action server"
feedback:
feedback: 58
---

Agora sim, você pode ficar tranquilo sabendo que a ação que você criou estará sempre atenta a quanto seu robô se distanciou da posição inicial. Uma ressalva importante é que neste cálculo simples de distância, os eventuais obstáculos são negligenciados.

Nós esperamos que este post seja útil para você!

Vídeo no YouTube

Este foi o post de hoje. Lembre-se que nós temos uma versão deste post em vídeo no YouTube.

Se você gostou do conteúdo, por favor, considere se inscrever no nosso canal do YouTube. Estamos publicando novos conteúdos quase todos os dias.

 

Continue avançando no seu aprendizado de ROS.

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