Serie ROS: Capítulo 4 (6)

Directorio de artículos

4. Gestión de operaciones de ROS

Este capítulo es principalmente para resolver el sistema ROS profundo multinivel, asociando diferentes paquetes de funciones, iniciando una gran cantidad de nodos ROS, paquetes de funciones, nodos, temas, duplicación de parámetros y problemas de comunicación entre nodos en diferentes hosts;

  • Domine la sintaxis de uso de los paquetes de metafunciones;
  • Domine la sintaxis de uso de los archivos de lanzamiento;
  • Comprender qué es la cobertura del espacio de trabajo de ROS y qué riesgos de seguridad existen;
  • Domine el método de procesamiento cuando se duplica el nombre del nodo;
  • Domina el método de manejo cuando el nombre del tema está duplicado;
  • Domine el método de procesamiento cuando se duplica el nombre del parámetro;
  • Puede realizar comunicación distribuida ROS.

1. Paquete de funciones meta de ROS

Metapackage es un concepto de sistema de gestión de archivos de Linux. Es un paquete virtual en ROS, que no tiene contenido sustantivo, sino que depende de otros paquetes de software, de esta manera se pueden combinar otros paquetes.

efecto:

El paquete de metafunciones depende de algunos otros paquetes de funciones en ROS, y otras dependencias se instalarán al instalar este paquete;

Proceso de implementación:

  1. Haga clic con el botón derecho en src y seleccione Crear paquete Catkin;
  2. Ingrese el nombre del paquete de funciones plumbing_my, agregue un paquete de funciones que no dependa de la dependencia del paquete de funciones y agregue el paquete de dependencia en package.xml después de presionar Enter:

<exec_depend>plomería_pub_sub</exec_depend>
<exec_depend>plomería_servidor_cliente</exec_depend>
<exec_depend>plomería_param_servidor</exec_depend>

Agregar solicitud de paquete de características meta:

<export>
 <!-- Other tools can request additional information be placed here -->
 <metapackage/>
</export>
  1. Modifique CMakeLists.txt, el contenido es el siguiente:

    cmake_minimum_required(VERSION 3.0.2)
    project(demo)
    find_package(catkin REQUIRED)
    catkin_metapackage()
    

    Nota: La última línea en CMakeLists.txt no puede tener una nueva línea, y solo hay cuatro líneas de código, y la segunda línea es el nombre del paquete de funciones.

    Solo compila y ejecuta;

2. El nodo ROS ejecuta y administra los archivos de lanzamiento

El archivo de lanzamiento es un archivo en formato XML, que puede iniciar múltiples nodos locales y remotos, y también puede establecer parámetros en el servidor de parámetros;
función:

Simplifique la configuración y el inicio de nodos y mejore la eficiencia de inicio de los programas ROS

Uso:
Tome la pequeña tortuga como ejemplo:

  1. Cree un nuevo archivo de inicio
    Agregue un directorio de inicio en el paquete de funciones, cree un nuevo archivo xxxx.launch en el directorio y edite el archivo de inicio:
<launch>
    <node pkg="turtlesim" type="turtlesim_node"     name="myTurtle" output="screen" />
    <node pkg="turtlesim" type="turtle_teleop_key"  name="myTurtleContro" output="screen" />
</launch>
  1. archivo de inicio de llamada
roslaunch 包名 xxx.launch

**Nota: ** Cuando el comando roslaunch ejecuta el archivo de inicio, determinará automáticamente si hay roscore y, de no ser así, llame a roscore; ctrl+shift+~ para iniciar rápidamente la terminal

2.1 archivo de lanzamiento: etiqueta de lanzamiento

La etiqueta es la etiqueta raíz de todos los archivos de inicio y actúa como contenedor para otras etiquetas.

Atributos:

deprecated = "Declaración en desuso"

efecto:

Informar al usuario que el archivo de inicio actual está obsoleto y no se ejecutará

Etiquetas de subconjunto:

Todas las demás etiquetas son hijos de lanzamiento.

Ejemplo de código:

<launch deprecated = "当前版本已经过时,请停止使用!">
    <node pkg="turtlesim" type="turtlesim_node"     name="myTurtle" output="screen" />
    <node pkg="turtlesim" type="turtle_teleop_key"  name="myTurtleContro" output="screen" />
</launch>

2.2 archivo de lanzamiento: etiqueta de nodo

La etiqueta se utiliza para especificar el nodo ROS, que es la etiqueta más común. Cabe señalar que: el comando roslaunch no puede garantizar iniciar el nodo en el orden de declaración del nodo (el inicio del nodo es multiproceso )

Atributos:

Atributos Función
pkg="nombre del paquete" el paquete al que pertenece el nodo
tipo = "tipo de nodo" Tipo de nodo (ejecutable con el mismo nombre)
nombre = "Nombre de nodo" NodeName (el nombre del nodo en la topología de red ROS)
argumentos="xxx xxx xxx" (opcional) Pasar parámetros al nodo
máquina = "nombre de la máquina" Inicie el nodo en la máquina especificada
respawn="verdadero|falso" (opcional) Si reiniciar automáticamente si el nodo sale
respawn_delay="N" (opcional) Si la reaparición es verdadera, inicie el nodo después de un retraso de N segundos
requerido="verdadero|falso" (opcional) Si el nodo debe, si es cierto, entonces si el nodo sale, todo el roslaunch se eliminará
ns="xxx" (opcional) Inicie el nodo en el espacio de nombres especificado xxx
clear_params="verdadero|falso" (opcional) Antes de comenzar, borre todos los parámetros del espacio privado del nodo
salida="registro|pantalla" (opcional) El objetivo de envío de registro, se puede configurar para registrar el archivo de registro o la pantalla de pantalla, el valor predeterminado es registro

Etiquetas de subconjunto:

  • configuración de variables de entorno env
  • reasignar reasigna nombres de nodos
  • configuración de parámetros de rosparam
  • configuración de parámetros

Ejemplo de código:

<?xml version="1.0"?>
<launch>
<!-- <launch deprecated="此文件已经过时,不建议使用!"> -->

    <!-- 启动的节点 -->
    <!-- respawn="true" 节点关闭后自动重启 -->
    <!-- respawn_delay="10" 在respawn设置为true后可以通过delay延时自动启动节点  -->
    <!-- required="true"  节点退出后关闭整个roslaunch -->
    <!-- 当上述三个在一行时,可能会出现错误提示The traceback for the exception was written to the log file -->
    <!-- ns="hello"可以在指定命名空间启动节点  避免重名问题 -->
    <node name="my_turtlesim" pkg="turtlesim" type="turtlesim_node" output="screen" />

    <!-- 键盘控制节点 -->
    <node name="my_key" pkg="turtlesim" type="turtle_teleop_key" output="screen"/>


</launch>

2.3archivo de lanzamiento: incluir etiqueta

Atributos:

  • file="$(buscar el nombre del paquete)/xxx/xxx.launch"

    rutas de archivo para incluir

  • ns="xxx" (opcional)

    Importar archivos en el espacio de nombres especificado

efecto:

Se utiliza para importar archivos de lanzamiento en otros formatos xml al archivo actual

Etiquetas de subconjunto:

  • configuración de variables de entorno env
  • arg para pasar argumentos al archivo incluido

Ejemplo de código:

<launch>
    <!-- 包含文件路径   $(find 功能包名)/xxx/yyy.launch   -->
    <include file="$(find launch01_basic)/launch/start_turtle.launch"/>
</launch>

2.4archivo de lanzamiento: etiqueta de reasignación

Atributos:

  • file="$(buscar el nombre del paquete)/xxx/xxx.launch"

    rutas de archivo para incluir

  • ns="xxx" (opcional)

    Importar archivos en el espacio de nombres especificado

efecto:

para cambiar el nombre del tema

Etiquetas de subconjunto:

  • ninguno

Ejemplo de código:

<?xml version="1.0"?>
<launch>
<!-- <launch deprecated="此文件已经过时,不建议使用!"> -->

    <!-- 启动的节点 -->
    <!-- respawn="true" 节点关闭后自动重启 -->
    <!-- respawn_delay="10" 在respawn设置为true后可以通过delay延时自动启动节点  -->
    <!-- required="true"  节点退出后关闭整个roslaunch -->
    <!-- 当上述三个在一起时,会出现错误提示The traceback for the exception was written to the log file -->
    <!-- ns="hello"可以在指定命名空间启动节点  避免重名问题 -->
    <node name="my_turtlesim" pkg="turtlesim" type="turtlesim_node" output="screen" >
        <remap from="/turtle1/cmd_vel" to="/cmd_vel"/>
    </node>
    <!-- 键盘控制节点 -->
    <node name="my_key" pkg="turtlesim" type="turtle_teleop_key" output="screen"/>   
</launch>

Función de implementación de código:

El nombre del tema enviado por el nodo de control del teclado incorporado de ros es /cmd_vel, y la interfaz gráfica de usuario de la tortuga se suscribe a /turtle1/cmd_vel. Debido a que los nombres de los temas son inconsistentes, no es posible usar directamente el nodo de control del teclado para controlar la tortuga. gui, por lo que el nodo que genera la tortuga gui debe ser La etiqueta redefine el nombre del tema, es decir, /turtle1/cmd_vel se cambia a /cmd_vel"; puede usar rostopic list para ver la lista de comunicación del tema actual.

Use rqt_graph para obtener la comunicación del tema actual más claramente

2.5archivo de lanzamiento: etiqueta de parámetro

Atributos:

  • name="espacio de nombres/nombre del parámetro"

    El nombre del parámetro, que puede contener un espacio de nombres.

  • valor="xxx" (opcional)

    Defina el valor del parámetro; si se omite aquí, debe especificar un archivo externo como origen del parámetro

  • type="str|int|doble|bool|yaml" (opcional)

    Especifique el tipo de parámetro, si no se especifica, roslaunch intentará determinar el tipo de parámetro, las reglas son las siguientes:

    • Si el número que contiene '.' no se analiza como un tipo de punto flotante, de lo contrario, es un tipo entero
    • "verdadero" y "falso" son valores booleanos (sin distinción entre mayúsculas y minúsculas)
    • otra cosa es una cadena

efecto:

Aplicado a la configuración de parámetros en el servidor de parámetros, la fuente del parámetro se puede definir con el valor en la etiqueta o cargar desde un archivo externo, cuando está en la etiqueta del nodo, es equivalente a un espacio de nombres privado

Etiquetas de subconjunto:

  • ninguno

Ejemplo de código:

<?xml version="1.0"?>
<launch>
<!-- <launch deprecated="此文件已经过时,不建议使用!"> -->

    <!-- 启动的节点 -->
    <!-- respawn="true" 节点关闭后自动重启 -->
    <!-- respawn_delay="10" 在respawn设置为true后可以通过delay延时自动启动节点  -->
    <!-- required="true"  节点退出后关闭整个roslaunch -->
    <!-- 当上述三个在一起时,会出现错误提示The traceback for the exception was written to the log file -->
    <!-- ns="hello"可以在指定命名空间启动节点  避免重名问题 -->
    <!-- param标签 使用:向参数服务器设置参数 -->
    <!-- param标签格式1 会在参数前私有命名,node节点名称 -->
    <param name="param_A"  type="int" value="100"/>
    <node name="my_turtlesim" pkg="turtlesim" type="turtlesim_node" output="screen" >
        <remap from="/turtle1/cmd_vel" to="/cmd_vel"/>
        <!-- param标签格式2 launch目录下,node标签外 -->
        <param name="param_B" type="double" value="3.14"/>
    </node>
    <!-- 键盘控制节点 -->
    <node name="my_key" pkg="turtlesim" type="turtle_teleop_key" output="screen"/>   
</launch>

Función de implementación de código:

Establezca los parámetros en el parámetro param, puede verlo en la lista de rosparam y obtener los parámetros a través de rosparam get /xxx

2.6archivo de lanzamiento: etiqueta rosparam

Atributos:

  • command="load | dump | delete" (opcional, carga predeterminada)

    Cargar, exportar o eliminar parámetros

  • archivo = “$ (buscar xxxxx)/xxx/yyy…”

    archivo yaml para cargar o exportar

  • param="nombre del parámetro"

  • ns="espacio de nombres" (opcional)

efecto:

Importe parámetros de archivos yaml o exporte parámetros a archivos yaml, y también se puede usar para eliminar parámetros. Si se define bajo la etiqueta de nodo, se considerará privado

Etiquetas de subconjunto:

  • ninguno

Ejemplo de código:

inicio_tortuga.lanzamiento

<?xml version="1.0"?>
<launch>
    <!-- <launch deprecated="此文件已经过时,不建议使用!"> -->

    <!-- 启动的节点 -->
    <!-- respawn="true" 节点关闭后自动重启 -->
    <!-- respawn_delay="10" 在respawn设置为true后可以通过delay延时自动启动节点  -->
    <!-- required="true"  节点退出后关闭整个roslaunch -->
    <!-- 当上述三个在一起时,会出现错误提示The traceback for the exception was written to the log file -->
    <!-- ns="hello"可以在指定命名空间启动节点  避免重名问题 -->
    <!-- param标签 使用:向参数服务器设置参数 -->
    <!-- param标签格式1 launch目录下,node标签外 -->
    <param name="param_A" type="int" value="100"/>
    <!-- rosparam 使用:操作参数服务器数据 -->
    <!-- rosparam格式1: launch 下,node 外 -->
    <!-- 加载参数 -->
    <rosparam command="load" file="$(find launch01_basic)/launch/params.yaml"/>

    <!-- 导出参数 -->
    <!-- <rosparam command="dump" file="$(find launch01_basic)/launch/params_out.yaml"/> -->

    
    <node name="my_turtlesim" pkg="turtlesim" type="turtlesim_node" output="screen">
        <remap from="/turtle1/cmd_vel" to="/cmd_vel"/>
        <!-- param标签格式2 node标签内  会在参数前私有命名,node节点名称-->
        <param name="param_B" type="double" value="3.14"/>
        <!--rosparam格式2: node 内 -->
        <rosparam command="load" file="$(find launch01_basic)/launch/params.yaml"/>

    </node>
    <!-- 键盘控制节点 -->
    <node name="my_key" pkg="turtlesim" type="turtle_teleop_key" output="screen"/>
</launch>

volcado.lanzamiento

<?xml version="1.0"?>
<launch>
    <rosparam command="dump" file="$(find launch01_basic)/launch/params_out.yaml"/>
    <!-- 删除参数 -->
    <rosparam command="delete" param="bg_B"/> 
</launch>

Función de implementación de código:

Use el comando rosparam para establecer los parámetros en el parámetro param, puede verlo en la lista de rosparam y obtener los parámetros a través de rosparam get /xxx

Aviso:

1. Al configurar los tres colores primarios en el archivo yaml, se debe agregar un espacio después de los dos puntos; de lo contrario, se informará un error.

2. rosparam tiene prioridad, y rosparam se ejecutará primero, por lo que si los datos de exportación no son el parámetro de destino, puede configurar otro archivo de inicio para exportar el archivo yaml

2.7archivo de lanzamiento: etiqueta de grupo (grupo)

Atributos:

  • ns="espacio de nombres" (opcional)

  • clear_params="verdadero|falso" (opcional)

    Antes de comenzar, si desea eliminar todos los parámetros del espacio de nombres del grupo (usar con precaución... esta función es peligrosa)

efecto:

Los nodos se pueden agrupar, con el atributo ns, lo que permite que los nodos pertenezcan a un espacio de nombres

Etiquetas de subconjunto:

  • etiquetas que no sean la etiqueta de lanzamiento

Ejemplo de código:

tortugas.lanzamiento

<?xml version="1.0"?>
<launch>

    <!-- 同时启动两队乌龟GUI以及键盘控制节点 -->
    <group ns="first">
        <node name="my_turtlesim" pkg="turtlesim" type="turtlesim_node" output="screen"/>
        <node name="my_key" pkg="turtlesim" type="turtle_teleop_key" output="screen"/>
    </group>
    <group ns="second">
        <node name="my_turtlesim" pkg="turtlesim" type="turtlesim_node" output="screen"/>
        <node name="my_key" pkg="turtlesim" type="turtle_teleop_key" output="screen"/>
    </group>
</launch>

Función de implementación de código:

Después de la agrupación, aunque las dos GUI tengan el mismo nombre, no ocurrirá que la iniciada más tarde detenga el programa anterior.

2.8archivo de lanzamiento—etiqueta arg

Atributos:

  • name="nombre del parámetro"

  • default="valor predeterminado" (opcional)

  • valor="valor" (opcional)

    No puede coexistir con el predeterminado

  • doc="descripción"

    Descripción de parámetros

efecto:

Se utiliza para el paso de parámetros dinámicos, similar a los parámetros de función, que pueden mejorar la flexibilidad de los archivos de inicio

Etiquetas de subconjunto:

  • ninguno

Ejemplo de código:

tortugas.lanzamiento

<?xml version="1.0"?>
<launch>

    <!-- 演示arg的使用,需要设置多个参数,参数使用的是同一个值(小车长度) -->
    <!-- <param name="A" value="0.5"/>
    <param name="B" value="0.5"/>
    <param name="C" value="0.5"/> -->

    <arg name="car_length" default="0.55"/>
    
    <param name="A" value="$(arg car_length)"/>
    <param name="B" value="$(arg car_length)"/>
    <param name="C" value="$(arg car_length)"/>
</launch>

Función de implementación de código:

Similar a declarar una variable global y asignar un valor, puede cambiar directamente el valor de la variable más tarde, ahorrándose el esfuerzo de modificar línea por línea.

Función de paso de parámetros dinámicos:

roslaunch launch01_basic arg.launch car_length:=0.6

3. Problema de cobertura del espacio de trabajo de ROS

Intente evitar el problema de la cobertura del espacio de trabajo de ROS

**Descripción del problema: **En diferentes espacios de trabajo, puede haber casos en los que el paquete de funciones tenga el mismo nombre. En este momento, si se llama al paquete de funciones con este nombre, se puede llamar al paquete de funciones de ruta incorrecta y puede haber confusión. ocurrir al llamar;

Análisis del motivo : ROS analizará el archivo .bashrc de la carpeta oculta y generará la ruta del paquete ROS. La información de la ruta organizará la prioridad de la ruta de acuerdo con el orden del espacio de trabajo configurado en .bashrc, es decir, la última configuración tiene la prioridad más alta, y cuanto mayor sea la prioridad Cuanto menor sea el valor, la prioridad de la ruta actual se puede ver a través del comando echo.La prioridad más alta en el frente se usará primero cuando se llame al programa. El código de ejemplo es el siguiente:

echo $ROS_PACKAGE_PATH 

**Conclusión:** Cuando el paquete de funciones tenga el mismo nombre, habrá una prioridad de llamada, es decir, la última configuración se ejecutará primero, y puede verla a través de ROS_PACKAGE_PATH

Descripción del ERROR:

Cuando se obtienen varios espacios de trabajo en el archivo .bashrc, puede suceder que solo se incluyan dos espacios de trabajo en la RUTA DEL PAQUETE ROS, puede eliminar los directorios de compilación y desarrollo del espacio de trabajo personalizado, re-catkin_make y luego volver a cargar el archivo .bashrc, problema resuelto

4. Nombre de nodo ROS duplicado

Cuando necesite iniciar un nodo con el mismo nombre o iniciar el mismo nodo varias veces, debe prestar atención al problema de la duplicación de nombres de nodos de ROS.

**Concepto:**El espacio de nombres es para agregar un prefijo al nombre, y la reasignación de nombres es para alias del nombre. Ambas estrategias pueden resolver el problema del nombre duplicado del nodo, y hay muchas maneras de implementar las dos estrategias:

  • comando rosrun
  • iniciar archivo
  • Implementación de codificación

Los tres métodos anteriores pueden evitar nombres de nodos duplicados a través del espacio de nombres o la reasignación de nombres. Esta sección demostrará el uso de los tres uno por uno. Los requisitos que deben cumplir los tres son similares.

4.1rosrun configuración de espacio de nombres y reasignación

4.1.1 espacio de nombres del conjunto rosrun

Sintaxis: rosrun nombre del paquete nombre del nodo __ns:= nuevo nombre

Ejemplo de código:

rosrun turtlesim turtlesim_node __ns:=ergouzi
rosrun turtlesim turtlesim_node __ns:=dagouzi

Ambos nodos están en funcionamiento;

4.1.2 reasignación de nombres de rosrun

Sintaxis: rosrun nombre del paquete nombre del nodo __nombre:= nuevo nombre

Ejemplo de código:

rosrun turtlesim  turtlesim_node __name:=daqiang
rosrun turtlesim  turtlesim_node __name:=xiaoqiang

Ambos nodos están en funcionamiento;

4.1.3 Espacio de nombres rosrun y uso superpuesto de reasignación de nombres

语法: rosrun 包名 节点名 __ns:=新名称 __name:=新名称

Ejemplo de código:

rosrun turtlesim  turtlesim_node __ns:=ergouzi __name:=daqiang 
rosrun turtlesim  turtlesim_node __ns:=dagouzi __name:=xiaoqiang

Ambos nodos están en funcionamiento;

甚至可以直接用  rosrun turtlesim  turtlesim_node /turtlesim_node:=daqiang  即/节点名称:=新名称

4.2 Espacio de nombres de configuración de archivo de lanzamiento y reasignación

Cuando se usa la sintaxis del archivo de inicio, hay dos atributos en la etiqueta del nodo: nombre y ns, que se usan para implementar la reasignación de nombres y la configuración del espacio de nombres, respectivamente. También es relativamente simple configurar espacios de nombres y reasignar nombres usando archivos de inicio.

archivo de lanzamiento:

<?xml version="1.0"?>
<launch>
    <node name="turtlesim" pkg="turtlesim" type="turtlesim_node" output="screen"/>
    <!-- 名称重映射 -->
    <node name="t1" pkg="turtlesim" type="turtlesim_node" output="screen"/>
    <!-- 命名空间 -->
    <node name="turtlesim" ns="ergouzi" pkg="turtlesim" type="turtlesim_node" output="screen"/> 
    <!-- 命名空间 + 名称重映射 -->
    <node name="t2" ns="dagouzi" pkg="turtlesim" type="turtlesim_node" output="screen"/> 
</launch>

En la etiqueta de nodo del archivo de inicio, debe existir el atributo de nombre y el espacio de nombres ns es opcional;

resultado de la operación:

rosnode list
/dagouzi/t2
/ergouzi/turtlesim
/rosout
/t1
/turtlesim

También se puede ver desde aquí que la llamada de la etiqueta del nodo no se ejecuta estrictamente en el orden de programación, puede ser en el orden inverso de la llamada;

4.3 Espacio de nombres de configuración de codificación y reasignación

Si personaliza la implementación del nodo, puede implementar de forma más flexible la configuración de espacios de nombres y la reasignación de nombres;

4.3.1 Implementación de C++: reasignación

4.3.1.1 Configuración de alias de nombre

Código central:ros::init(argc,argv,"zhangsan",ros::init_options::AnonymousName);

4.3.1.2 Ejecución

Se adjunta una marca de tiempo al nombre.

4.3.2 Implementación de C++: espacios de nombres

4.3.2.1 Configuración del espacio de nombres

código central

  std::map<std::string, std::string> map;
  map["__ns"] = "xxxx";
  ros::init(map,"wangqiang");
Copy
4.3.2.2 Efecto de ejecución

El nombre del nodo establece el espacio de nombres.

5. Configuración del nombre del tema ROS

En ROS, el nombre del tema puede tener el mismo nombre, cuando el mensaje suscrito tiene el mismo nombre, puede haber un problema cuando el suscriptor recibe un mensaje innecesario, lo que hará que el nodo funcione de manera anormal, o desea que los dos no comunicar Los nodos se comunican sobre el tema, por lo que es necesario modificar el tema para que sea el mismo.

Según los diferentes prefijos, hay tres tipos: global, relativo y privado.

  • Global (el nombre del parámetro se refiere directamente al sistema ROS, que está al mismo nivel que el espacio de nombres del nodo)
  • Relativo (el nombre del parámetro hace referencia al espacio de nombres del nodo, que está al mismo nivel que el nombre del nodo)
  • privado (el nombre del parámetro hace referencia al nombre del nodo y es un elemento secundario del nombre del nodo)

La reasignación de nombres consiste en crear un alias para el nombre y agregar un prefijo al nombre. Esta implementación es más complicada que el cambio de nombre del nodo. No solo usa el espacio de nombres como prefijo, sino que también usa el nombre del nodo como prefijo. Hay varias formas de implementar las dos estrategias:

  • comando rosrun
  • iniciar archivo
  • Implementación de codificación

Esta sección demostrará el uso de los tres uno por uno, y los requisitos que deben cumplir los tres son similares.

caso:

Use el paquete de funciones ros-noetic-teleop-twist-keyboard para controlar la GUI de visualización de tortugas

5.1 reasignación de tema de conjunto de rosrun

**Sintaxis: **sintaxis de reasignación de nombre de rosrun: nombre de paquete de rorun nombre de nodo nombre de tema: = nuevo nombre de tema

5.1.1 Solución 1: Modifique el nodo de control del teclado para publicar el nombre del tema

Establezca el tema del nodo teleop_twist_keyboard en/turtle1/cmd_vel

Inicie el nodo de control del teclado:rosrun teleop_twist_keyboard teleop_twist_keyboard.py /cmd_vel:=/turtle1/cmd_vel

Inicie el nodo de visualización de tortuga:rosrun turtlesim turtlesim_node

Los dos pueden lograr una comunicación normal.

5.1.2 Solución 2: Modifique el nombre del tema de suscripción del nodo de la GUI de la tortuga

Establezca el tema del nodo de visualización de la tortuga en/cmd_vel

Inicie el nodo de control del teclado:rosrun teleop_twist_keyboard teleop_twist_keyboard.py

Inicie el nodo de visualización de tortuga:rosrun turtlesim turtlesim_node /turtle1/cmd_vel:=/cmd_vel

Los dos pueden lograr una comunicación normal.

5.2 reasignación de tema de configuración de archivo de inicio

** Sintaxis: ** Usar etiqueta de reasignación

<node pkg="xxx" type="xxx" name="xxx">
    <remap from="原话题" to="新话题" />
</node>
5.2.1 Solución 1: establezca el tema del nodo teleop_twist_keyboard en/turtle1/cmd_vel
<?xml version="1.0"?>
<!-- 执行键盘功能包直接控制小乌龟 -->
<launch>
    <!-- 将乌龟的话题设置与键盘控制一致 -->
    <node name="my_turtle" pkg="turtlesim" type="turtlesim_node" >
       
    </node>

    <!-- 将乌龟的话题设置与键盘控制一致 -->
    <node name="key" pkg="teleop_twist_keyboard" type="teleop_twist_keyboard.py">
        <remap from="/cmd_vel" to="/turtle1/cmd_vel"/>
    </node>
</launch>

Los dos pueden lograr una comunicación normal.

5.2.2 Solución 2: establezca el tema del nodo de visualización de tortugas en/cmd_vel
<?xml version="1.0"?>
<!-- 执行键盘功能包直接控制小乌龟 -->
<launch>
    <!-- 将乌龟的话题设置与键盘控制一致 -->
    <node name="my_turtle" pkg="turtlesim" type="turtlesim_node" >
        <remap from="/turtle1/cmd_vel" to="/cmd_vel"/>   
    </node>
    <node name="key" pkg="teleop_twist_keyboard" type="teleop_twist_keyboard.py"/>
    <!-- 将乌龟的话题设置与键盘控制一致 -->

</launch>

Los dos pueden lograr una comunicación normal.

5.3 Nombre del tema de configuración de código

El nombre del tema tiene cierta relación con el espacio de nombres del nodo y el nombre del nodo. El nombre del tema se puede dividir aproximadamente en tres tipos:

  • Global (los temas se refieren al sistema ROS, que está al mismo nivel que el espacio de nombres del nodo)
  • Relativo (el tema se refiere al espacio de nombres del nodo, que está al mismo nivel que el nombre del nodo)
  • Privado (el tema hace referencia al nombre del nodo, que es un elemento secundario del nombre del nodo)

[La transferencia de la imagen del enlace externo falló, el sitio de origen puede tener un mecanismo anti-leeching, se recomienda guardar la imagen y cargarla directamente (img-2SKGiOC6-1667583256847) (C:\Users\Haotian\AppData\Roaming\Typora\ typora-user-images \1667384023357.png)]

Codificación para demostrar la relación específica:

proceso:

5.3.1 Implementación de C++ de nombre global

**Formato:** /El nombre que comienza con no tiene nada que ver con el nombre del nodo

Por ejemplo: /xxx/yyy/zzz

Ejemplo 1:ros::Publisher pub = nh.advertise("/chatter",1000);

Resultado 1:/chatter

Ejemplo 2:ros::Publisher pub = nh.advertise("/chatter/money",1000);

Resultado 2:/chatter/money

Ejemplo de código:

#include "ros/ros.h"
#include "std_msgs/String.h"
/**
 * @brief 需求:演示不同类型的话题名称设置
 *             设置话题名称以及命名空间
 *  
 *
 */
int main(int argc, char *argv[])
{
    
    

    ros::init(argc, argv, "hello");
    ros::NodeHandle nh;
    //核心:设置不同类型的话题
    // 1.全局 --- 话题名称需要以 / 开头(也可以设置自己的命名空间),此时话题名称与节点(命名空间以及名称)没有任何关系
    // ros::Publisher pub = nh.advertise<std_msgs::String>("/chatter",1000);
    ros::Publisher pub = nh.advertise<std_msgs::String>("/yyy/chatter", 1000);

    // 2.相对

    // 3.私有

    while (ros::ok())
    {
    
    
        

    }
    return 0;
}

5.3.2 Implementación de C++ de nombre relativo

**Formato:** /Nombres que no son iniciales, consulte el espacio de nombres (nivel con el nombre del nodo) para determinar el nombre del tema

Ejemplo 1:ros::Publisher pub = nh.advertise("chatter",1000);

Resultado 1:xxx/chatter

Ejemplo 2:ros::Publisher pub = nh.advertise("chatter/money",1000);

Resultado 2:xxx/chatter/money

Ejemplo de código:

#include "ros/ros.h"
#include "std_msgs/String.h"
/**
 * @brief 需求:演示不同类型的话题名称设置
 *             设置话题名称以及命名空间
 *  
 *
 */
int main(int argc, char *argv[])
{
    
    

    ros::init(argc, argv, "hello");
    ros::NodeHandle nh;
    //核心:设置不同类型的话题
    // 1.全局 --- 话题名称需要以 / 开头(也可以设置自己的命名空间),此时话题名称与节点(命名空间以及名称)没有任何关系
    // ros::Publisher pub = nh.advertise<std_msgs::String>("/chatter",1000);
    // ros::Publisher pub = nh.advertise<std_msgs::String>("/yyy/chatter", 1000);

    // 2.相对 --- 非 / 开头    相对的会把话题后缀到命名空间后方,与命名空间同级
    // ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",1000);
    ros::Publisher pub = nh.advertise<std_msgs::String>("yyy/chatter", 1000);

    // 3.私有

    while (ros::ok())
    {
    
    
        

    }
    

    return 0;
}

5.3.3 Nombres privados C++

**Formato:** ~Nombres que comienzan con

Ejemplo 1:

ros::NodeHandle nh("~");
ros::Publisher pub = nh.advertise("chatter",1000);

Resultado 1:/xxx/hello/chatter

Ejemplo 2:

ros::NodeHandle nh("~");
ros::Publisher pub = nh.advertise("chatter/money",1000);

Resultado 2:/xxx/hello/chatter/money

PD: cuando se usa ~, y el nombre del tema a veces /comienza con , entonces el nombre del tema es absoluto

Ejemplo 3:

ros::NodeHandle nh("~");
ros::Publisher pub = nh.advertise("/chatter/money",1000);

Resultado 3:/chatter/money

Ejemplo de código:

#include "ros/ros.h"
#include "std_msgs/String.h"
/**
 * @brief 需求:演示不同类型的话题名称设置
 *             设置话题名称以及命名空间
 *  
 *
 */
int main(int argc, char *argv[])
{
    
    

    ros::init(argc, argv, "hello");
    // ros::NodeHandle nh;
    //核心:设置不同类型的话题
    // 1.全局 --- 话题名称需要以 / 开头(也可以设置自己的命名空间),此时话题名称与节点(命名空间以及名称)没有任何关系
    // ros::Publisher pub = nh.advertise<std_msgs::String>("/chatter",1000);
    // ros::Publisher pub = nh.advertise<std_msgs::String>("/yyy/chatter", 1000);

    // 2.相对 --- 非 / 开头    相对的会把话题后缀到命名空间后方,与命名空间同级
    // ros::Publisher pub = nh.advertise<std_msgs::String>("chatter",1000);
    // ros::Publisher pub = nh.advertise<std_msgs::String>("yyy/chatter", 1000);

    // 3.私有--- 需要创建特定句柄 NodeHandle  nh(~);
    ros::NodeHandle nh("~");
    // ros::Publisher pub = nh.advertise<std_msgs::String>("chatter", 1000);
    // ros::Publisher pub = nh.advertise<std_msgs::String>("yyy/chatter", 1000);

    //注意:如果私有的NH创建的话题以 / 开通(全局话题) 生成的话题就是全局话题而非私有话题
    //全局话题优先级更高
    ros::Publisher pub = nh.advertise<std_msgs::String>("/yyy/chatter", 1000);//私有句柄 话题名称变全局名称时 变成全局话题,因为全局话题优先级最高

    while (ros::ok())
    {
    
    
        

    }
    

    return 0;
}

6. Configuración del nombre del tema ROS


En ROS, el nombre del tema del nombre del nodo puede tener el mismo nombre y el nombre del parámetro también puede tener el mismo nombre. Sin embargo, no existe una operación de reasignación de nombres para la duplicación de parámetros. Para evitar la duplicación, se utiliza el método de agregar un prefijo al parámetro, que es similar a los métodos global, relativo y privado del nombre del tema en la sección anterior. ;

  • Global (el nombre del parámetro se refiere directamente al sistema ROS, que está al mismo nivel que el espacio de nombres del nodo)
  • Relativo (el nombre del parámetro hace referencia al espacio de nombres del nodo, que está al mismo nivel que el nombre del nodo)
  • privado (el nombre del parámetro hace referencia al nombre del nodo y es un elemento secundario del nombre del nodo)

También hay tres formas de configurar los parámetros:

  • comando rosrun
  • iniciar archivo
  • Implementación de codificación

6.1 parámetros de configuración de rosrun

Cuando rosrun inicia el nodo, puede establecer parámetros:

**Sintaxis:**paquete de funciones rosrun nombre del paquete nombre del nodo_nombre del parámetro:=valor del parámetro

1. Configuración de parámetros

rosrun turtlesim turtlesim_node _radius:=3.56

2. correr

rosparam listVer información del nodo y mostrar los resultados:

/rosdistro
/roslaunch/uris/host_wht_vpc__35637
/rosversion
/run_id
/turtlesim/background_b
/turtlesim/background_g
/turtlesim/background_r
/turtlesim/radius

Los resultados muestran que el parámetro A precede al nombre del nodo, lo que significa que el nombre del parámetro de configuración de ejecución de rosrun utiliza el modo privado

6.2 parámetros de configuración de lanzamiento

El método de configuración de parámetros a través del archivo de inicio se ha introducido anteriormente, y los parámetros se pueden configurar fuera de la etiqueta del nodo o mediante param o rosparam en la etiqueta del nodo. Los parámetros establecidos fuera de la etiqueta del nodo son globales, consulte / , los parámetros establecidos dentro de la etiqueta del nodo son privados, consulte /namespace/nodename.

1. Configuración de parámetros

Tome la etiqueta param como ejemplo para establecer parámetros

<!-- 设置参数 -->
<launch>
    <!-- 格式1:全局 -->
    <param name="radius" value="0.2"/>
    <node name="my_turtle" pkg="turtlesim" type="turtlesim_node" ns="xxx">
        <!-- 格式2:私有 -->
        <param name="radius" value="0.08"/>
    </node>
</launch>

2. correr

rosparam listVer información del nodo y mostrar los resultados:

/radius
/rosdistro
/roslaunch/uris/host_wht_vpc__45767
/rosversion
/run_id
/xxx/my_turtle/background_b
/xxx/my_turtle/background_g
/xxx/my_turtle/background_r
/xxx/my_turtle/radius

Los resultados de ejecución son consistentes con las expectativas.

6.3 Parámetros de configuración de codificación

El método de codificación se puede configurar de manera más conveniente: parámetros globales, relativos y privados.

6.3.1 parámetros de configuración de ros::param

La API de llamada para configurar parámetros es ros::param::set. En esta función, el parámetro 1 se pasa en el nombre del parámetro y el parámetro 2 es el valor del parámetro pasado. Al configurar el nombre del parámetro en el parámetro 1, si comienza con /, es un parámetro global, si comienza con ~, entonces es un parámetro privado, si no comienza con / o ~, entonces es un parámetro relativo.

Ejemplo de código:

#include <ros/ros.h>

int main(int argc, char* argv[])
{
    
    
    ros::init(argc, argv, "hello");
    ros::NodeHandle nh;
    /*
         使用ros::param来设置参数
    */
    //全局,和命名空间以及节点名称无关
    ros::param::set("/radiusA", 100);
    //相对,参考命名空间
    ros::param::set("radiusB", 100);  
    //私有,参考命名空间与节点名称
    ros::param::set("~radiusC", 100); 

    return 0;
}

Al ejecutar, suponga que el espacio de nombres establecido es xxx, el nombre del nodo es yyy, use la lista rosparam para ver:

/radiusA
/rosdistro
/roslaunch/uris/host_wht_vpc__46715
/rosversion
/run_id
/xxx/hello/radiusC
/xxx/radiusB

6.3.2 ros::NodeHandle parámetros de configuración

Al configurar parámetros, primero debe crear un objeto NodeHandle y luego llamar a la función setParam del objeto. El parámetro 1 de esta función es el nombre del parámetro, y el parámetro 2 es el valor del parámetro que se establecerá. Si el nombre del parámetro comienza con /, entonces es un parámetro global. Si el nombre del parámetro Si no comienza con /, entonces si el parámetro es un parámetro relativo o un parámetro privado está relacionado con el objeto NodeHandle. Si el objeto NodeHandle se crea cuando el se llama a la construcción predeterminada sin argumentos, entonces el parámetro es un parámetro relativo.Si el objeto NodeHandle se crea usando: ros::NodeHandle nh("~"), entonces este parámetro es un parámetro privado. Ejemplo de código:

#include <ros/ros.h>

int main(int argc, char* argv[])
{
    
    
    ros::init(argc, argv, "hello");
    ros::NodeHandle nh;
    /*
         使用ros::param来设置参数
    */
    //全局,和命名空间以及节点名称无关
    ros::param::set("/radiusA", 100);
    //相对,参考命名空间
    ros::param::set("radiusB", 100);  
    //私有,参考命名空间与节点名称
    ros::param::set("~radiusC", 100);
    /*
         使用NodeHandle来设置参数
    */
    //全局,和命名空间以及节点名称无关
    nh.setParam("/radius_nh_A", 100);
    //相对,参考命名空间
    nh.setParam("radius_nh_B", 100);
    //私有,参考命名空间与节点名称
    ros::NodeHandle nh_private("~");
    nh_private.setParam("radius_nh_C", 100); 
    return 0;
}

Al ejecutar, suponga que el espacio de nombres establecido es xxx, el nombre del nodo es yyy, use la lista rosparam para ver:

/radiusA
/radius_nh_A
/rosdistro
/roslaunch/uris/host_wht_vpc__36311
/rosversion
/run_id
/yyy/hello/radiusC
/yyy/hello/radius_nh_C
/yyy/radiusB
/yyy/radius_nh_B

**Nota:** Si los parámetros son anormales, puede actualizar el roscore una vez y luego volver a ejecutar la lista de rosparam para actualizar la pantalla;

7. Comunicación distribuida ROS


ROS es un entorno informático distribuido. Un sistema ROS en ejecución puede constar de múltiples nodos distribuidos en múltiples computadoras. Dependiendo de cómo esté configurado el sistema, cualquier nodo puede necesitar comunicarse con cualquier otro nodo en cualquier momento.

Por lo tanto, ROS tiene ciertos requisitos para la configuración de la red:

  • Debe haber conectividad bidireccional completa entre todas las máquinas en todos los puertos.
  • Cada computadora debe anunciarse con un nombre que todas las demás computadoras puedan resolver.

lograr

1. Prepárate

Primero, asegúrese de que diferentes computadoras estén en la misma red. Lo mejor es configurar las IP fijas por separado. Si se trata de una máquina virtual, debe cambiar el adaptador de red al modo puente;

2. Modificación del archivo de configuración

Modifique los archivos /etc/hosts de diferentes computadoras respectivamente, y agregue la dirección IP y el nombre de la computadora de la otra parte al archivo:

Lado del anfitrión:

从机的IP    从机计算机名

Lado esclavo:

主机的IP    主机计算机名

Después de configurar, puede usar el comando ping para probar si la comunicación de la red es normal.

Nombre de vista de dirección IP: ifconfig

Verifique el nombre de la computadora: nombre de host

3. Configurar la IP del host

Configurar la dirección IP del host

Añadir ~/.bashrc

export ROS_MASTER_URI=http://主机IP:11311
export ROS_HOSTNAME=主机IP

4. Configurar IP esclava

Configure la dirección IP de la máquina esclava, puede haber varias máquinas esclavas y cada una de ellas establece las siguientes configuraciones:

Añadir ~/.bashrc

export ROS_MASTER_URI=http://主机IP:11311
export ROS_HOSTNAME=从机IP

4. Configurar IP esclava

Configure la dirección IP de la máquina esclava, puede haber varias máquinas esclavas y cada una de ellas establece las siguientes configuraciones:

Añadir ~/.bashrc

export ROS_MASTER_URI=http://主机IP:11311
export ROS_HOSTNAME=从机IP

prueba

1. El anfitrión inicia roscore (obligatorio)

2. El host inicia el nodo de suscripción y el esclavo inicia el nodo de publicación para comprobar si la comunicación es normal.

3. Prueba inversa, el maestro inicia el nodo de publicación, el esclavo inicia el nodo de suscripción y prueba si la comunicación es normal

Supongo que te gusta

Origin blog.csdn.net/TianHW103/article/details/127699152
Recomendado
Clasificación