Clase 06 - Laboratorio
Programación de nodos con parámetros
Definir parámetros
En el constructor del nodo a través del atributo self
:
self.declare_parameter('<nombre_parametro>', <valor>)
El tipo es inferido a través del valor
Obtener el valor
Tipo texto (string
):
self.get_parameter('<nombre_parametro>') .get_parameter_value().string_value
Tipo entero (int
), decimal (double
), booleano (bool
), es igual:
self.get_parameter('<nombre_parametro>').get_parameter_value().string_value.<int|double|bool>_value
Programación de archivos launch
Adecuación del paquete para albergar los archivos
Crear una carpeta
launch
Crear la carpeta launch
que contendrá los archivos
📂 src 📂 clase_06 📂 launch ⬅️ 📄 nombre_archivo.launch.py ⬅️ ... 📁 resource 📁 test 📄 package.xml ...
Modificar el archivo
setup.py
Modificar la configuración de data_files
para instalar correctamente los archivos launch
setup.py
from setuptools import setup
import os
from glob import glob
package_name = 'nombre_paquete'
setup(
name=package_name,
# Otros parámetros ...
data_files=[
# ... Otros archivos
# Incluir todos los archivos de la carpeta launch
(os.path.join('share', package_name, 'launch'), glob('launch/*'))
],
# El resto de la configuración ...
)
Se recomienda agregar ros2launch
como dependencia de ejecución:
<exec_depend>ros2launch</exec_depend>
Programación del launch
Importar las librerías
launch
ylaunch_ros
from launch import LaunchDescription
from launch_ros import actions
Definir la función
generate_launch_description
que devolverá elLaunchDescription
def generate_launch_description():
...return LaunchDescription([
# Contenido del launch
... ])
Actions: Ejecutar un nodo
Importar la librería
from launch_ros.actions import Node
Crear la acción
def generate_launch_description():
node = Node(
package = '<nombre_paquete>',
executable = '<nombre_ejecutable>',
# Adicionales (según corresponda) ⬇️
name = '<nombre_nodo>',
namespace = '<nombre_namespace>',
parameters = [ # Pueden ser archivos
{'<nombre_parametro>': <valor>, .. }
],
remappings = [
('<nombre_topic>', '<nuevo_nombre>'),
],
output = '<screen|log|both>',
ros_arguments = [...],
arguments = [...],
)
return LaunchDescription([
node,
...
])
No es necesario completar todos los campos, los requeridos son los mínimos para el comando ros2 run
: package
y executable
Declaración de argumentos
Importar la librería
from launch.substitutions import LaunchConfiguration
from launch.actions import DeclareLaunchArgument
Primero declarar los argumentos con DeclareLaunchArgument
y luego utilizarlos mediante las sustituciones LaunchConfiguration
...
def generate_launch_description():
return LaunchDescription([
DeclareLaunchArgument(
'<nombre_parametro>', default_value=<valor>
),
Node(
package = '<nombre_paquete>',
executable = '<nombre_ejecutable>',
...
parameters=[{
'<parametro_del_nodo>': LaunchConfiguration('<nombre_parametro>'),
}]
),
])
Uso de loggers
Generar un mensaje de log
<nodo>.get_logger().{debug,info,warning,error,fatal} ('<mensaje_de_log>')
self.get_logger().info('Mensaje de prueba con severidad INFO')
Generar un mensaje de log por única vez
<nodo>.get_logger().{debug,info,warning,error,fatal} ('<mensaje_de_log>', once=True)
self.get_logger().warn('Advertencia una sola vez', once=True)
Enviar el mensaje como máximo N veces por segundo
<nodo>.get_logger().{debug,info,warning,error,fatal} ('<mensaje_de_log>', throttle_duration_sec=<N>)
self.get_logger().debug(f'Valor de la medicion {valor}', throttle_duration_sec=1)
Sistema de Monitoreo de temperatura
Objetivos
- Crear un nodo publicador que envíe mediciones de temperatura
- Crear un nodo suscriptor que escuche esas mediciones y emita una alarma si se supera un umbral de temperatura configurable
- Crear archivos de launch que permitan iniciar todo el sistema estableciendo los parámetros programados
Crear el nodo: temperature_sensor
- El valor de temperatura es generado a partir de un valor base (
base_temperature
) con una variación aleatoria máxima (max_variation
) configurable ambas mediante parámetros - Publica en el topic
\temperature
utilizando el tipo de mensajesensor_msgs/msg/Temperature
- Enviar un mensaje de log que muestre la temperatura generada (
info
odebug
) - Además agregar un parámetro de configuración de la frecuencia de publicación en Hz (
publish_rate
)
Nombre | Tipo | Descripción | Valor por defecto |
---|---|---|---|
base_temperature |
float |
Temperatura inicial/base en grados Celsius | 25.0 |
max_variation |
float |
Máxima variación aleatoria | 5.0 |
publish_rate |
int |
Frecuencia de publicación en Hz | 1 |
Para generar la temperatura puedes utilizar la función uniform
de la librería random
= base_temperature + random.uniform(-max_variation, max_variation) temperature
base_temperature
: valor basemax_variation
: cuánto puede subir o bajar como máximo en cada mediciónrandom.uniform(a, b)
: genera un número flotante aleatorio entrea
yb
.
Uno de los campos del mensaje de tipo Temperature
es el header
, que contiene un stamp
de tipo Time
y un frame_id
, puedes completar dichos campos opcionalmente
Para obtener un stamp
actual puedes utilizar el método get_clock
de la clase Node
de ROS:
= self.get_clock().now().to_msg()
msg.header.stamp = 'sensor1' msg.header.frame_id
Crear el nodo temperature_monitor
- Suscribe al topic
\temperature
y por cada mensaje verifica si la temperatura supera un umbral crítico configurable mediante un parámetroalarm_threshold
- Agregar un parámetro de configuración
temperature_unit
que definirá la unidad utilizada para el umbral y las alertas de temperatura
\[ T \, [°F] = T \, [°C] \times 9/5 + 32 \]
- Si supera el umbral imprime un mensaje de alarma con severidad
warn
y si no publicar la temperatura recibida con severidadinfo
odebug
Probar el sistema mediante ros2 run
- Ejecutar ambos nodos desde consola comprobando el funcionamiento de los valores por defecto de los parámetros y el funcionamiento del sistema en su conjunto
- Probar distintas ejecuciones variando los parámetros definidos y probar cambios de parámetros durante la ejecución, comprobando cuales tienen efecto inmediato y cuales requieren reinciar el nodo
- Comprobar el funcionamiento de los mensajes de log según distintos niveles de severidad seteados para cada nodo
Crear el archivo launch
para ambos nodos
- Iniciar ambos nodos
temperature_sensor
con una temperatura base de 27°C y una variación máxima de 5°C, con una frecuencia de publicación de 2Hz.temperature_monitor
con un umbral en 30°C
- Declarar los argumentos necesarios para poder configurar los parámetros establecidos en ambos nodos
- Ambos nodos deben enviar la salida por la consola con nivel de severidad
info
Probar el sistema mediante ros2 launch
- Ejecutar el archivo
launch
creado para verificar el funcionamiento de los parámetros por defecto - Probar distintas ejecuciones variando los parámetros definidos