ROS series: Chapter 4 (3)

4. ROS operation management

This chapter is mainly to solve the multi-level deep ROS system, associating different function packages, starting a large number of ROS nodes, function packages, nodes, topics, parameter duplication, and communication problems between nodes on different hosts;

  • Master the usage syntax of meta-function packages;
  • Master the usage syntax of launch files;
  • Understand what ROS workspace coverage is and what security risks exist;
  • Master the processing method when the node name is duplicated;
  • Master the handling method when the topic name is duplicated;
  • Master the processing method when the parameter name is duplicated;
  • It can realize ROS distributed communication.

1. ROS meta function package

Metapackage is a Linux file management system concept. It is a virtual package in ROS, which has no substantive content, but it depends on other software packages. In this way, other packages can be combined.

effect:

The meta-function package depends on some other function packages in ROS, and other dependencies will be installed when installing this package;

Implementation process:

  1. Right-click src and select Create Catkin Package;
  2. Enter the name of the function package plumbing_my, add a function package that does not depend on the function package dependency, and add the dependency package in package.xml after pressing Enter:

<exec_depend>plumbing_pub_sub</exec_depend>
<exec_depend>plumbing_server_client</exec_depend>
<exec_depend>plumbing_param_server</exec_depend>

​ Add meta feature package request:

<export>
 <!-- Other tools can request additional information be placed here -->
 <metapackage/>
</export>
  1. Modify CMakeLists.txt, the content is as follows:

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

    Note: The last line in the CMakeLists.txt cannot have a newline, and there are only four lines of code, and the second line is the name of the function package.

    Just compile and run;

2. ROS node runs and manages launch files

The launch file is a file in XML format, which can start multiple local and remote nodes, and can also set parameters in the parameter server;
function:

Simplify the configuration and startup of nodes and improve the startup efficiency of ROS programs

Use:
Take the little turtle as an example:

  1. Create a new launch file
    Add a launch directory under the function package, create a new xxxx.launch file under the directory, and edit the launch file:
<launch>
    <node pkg="turtlesim" type="turtlesim_node"     name="myTurtle" output="screen" />
    <node pkg="turtlesim" type="turtle_teleop_key"  name="myTurtleContro" output="screen" />
</launch>
  1. call launch file
roslaunch 包名 xxx.launch

**Note: ** When the roslaunch command executes the launch file, it will automatically determine whether there is roscore, and if not, call roscore; ctrl+shift+~ to quickly start the terminal

2.1 launch file—launch tag

The tag is the root tag of all launch files and acts as a container for other tags

Attributes:

deprecated = "Deprecated Declaration"

effect:

Inform the user that the current launch file is deprecated and will not run

Subset labels:

All other tags are children of launch

Code example:

<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 launch file—node label

The label is used to specify the ROS node, which is the most common label. It should be noted that: the roslaunch command cannot guarantee to start the node in the order of declaration of the node (the start of the node is multi-process)

Attributes:

Attributes Function
pkg="package name" the package the node belongs to
type=“nodeType” Node type (executable with the same name)
name=“nodeName” NodeName (the name of the node in the ROS network topology)
args="xxx xxx xxx" (optional) Pass parameters to node
machine="machine name" Start the node on the specified machine
respawn="true|false" (optional) Whether to automatically restart if the node exits
respawn_delay="N" (optional) If respawn is true, start the node after a delay of N seconds
required="true|false" (optional) Whether the node must, if true, then if the node exits, the entire roslaunch will be killed
ns="xxx" (optional) Start the node in the specified namespace xxx
clear_params="true|false" (optional) Before starting, delete all parameters of the private space of the node
output="log|screen" (optional) Log sending target, can be set to log log file, or screen screen, the default is log

Subset labels:

  • env environment variable settings
  • remap remaps node names
  • rosparam parameter settings
  • param parameter setting

Code example:

<?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.3launch file—include tag

Attributes:

  • file="$(find package name)/xxx/xxx.launch"

    file paths to include

  • ns="xxx" (optional)

    Import files in the specified namespace

effect:

Used to import launch files in other xml formats into the current file

Subset labels:

  • env environment variable settings
  • arg to pass arguments to the included file

Code example:

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

2.4launch file—remap label

Attributes:

  • file="$(find package name)/xxx/xxx.launch"

    file paths to include

  • ns="xxx" (optional)

    Import files in the specified namespace

effect:

for topic renaming

Subset labels:

  • none

Code example:

<?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>

Code implementation function:

The topic name sent by the ros built-in keyboard control node is /cmd_vel, and the turtle gui subscribes to /turtle1/cmd_vel. Because the topic names are inconsistent, it is not possible to directly use the keyboard control node to control the turtle gui, so the node node that generates the turtle gui needs to be The label redefines the topic name, that is, /turtle1/cmd_vel is changed to /cmd_vel"; you can use rostopic list to view the current topic communication list.

Use rqt_graph to get the current topic communication more clearly

2.5launch file—param tag

Attributes:

  • name="namespace/parameter name"

    The parameter name, which can contain a namespace

  • value="xxx" (optional)

    Define the parameter value, if omitted here, you must specify an external file as the parameter source

  • type="str|int|double|bool|yaml" (optional)

    Specify the parameter type, if not specified, roslaunch will try to determine the parameter type, the rules are as follows:

    • If the number containing '.' is not parsed as a floating point type, otherwise it is an integer type
    • "true" and "false" are bool values ​​(case insensitive)
    • else is a string

effect:

Applied to setting parameters on the parameter server, the parameter source can be defined with value in the tag, or loaded from an external file, when it is in the node tag, it is equivalent to a private namespace

Subset labels:

  • none

Code example:

<?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>

Code implementation function:

Set the parameters in the param parameter, you can view it in the rosparam list, and get the parameters through rosparam get /xxx

2.6launch file—rosparam tag

Attributes:

  • command="load | dump | delete" (optional, default load)

    Load, export or delete parameters

  • file=“$(find xxxxx)/xxx/yyy…”

    yaml file to load or export to

  • param="parameter name"

  • ns="namespace" (optional)

effect:

Import parameters from yaml files, or export parameters to yaml files, and can also be used to delete parameters. If defined under the node tag, it will be considered private

Subset labels:

  • none

Code example:

start_turtle.launch

<?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>

dump.launch

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

Code implementation function:

Use the rosparam command to set the parameters in the param parameter, you can view it in the rosparam list, and get the parameters through rosparam get /xxx

Notice:

1. When setting the three primary colors in the yaml file, a space must be added after the colon, otherwise an error will be reported

2. rosparam has priority, and rosparam will be run first, so if the export data is not the target parameter, you can set another launch file to export the yaml file

2.7launch file—group label (group)

Attributes:

  • ns="namespace" (optional)

  • clear_params="true|false" (optional)

    Before starting, whether to delete all parameters of the group namespace (use with caution...this function is dangerous)

effect:

Nodes can be grouped, with the ns attribute, allowing nodes to belong to a namespace

Subset labels:

  • tags other than the launch tag

Code example:

turtles.launch

<?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>

Code implementation function:

After grouping, although the two GUIs have the same name, it will not happen that the one started later will stop the previous program

2.8launch file—arg label

Attributes:

  • name="parameter name"

  • default="default value" (optional)

  • value="value" (optional)

    Cannot coexist with default

  • doc="description"

    Parameter Description

effect:

Used for dynamic parameter passing, similar to function parameters, which can enhance the flexibility of launch files

Subset labels:

  • none

Code example:

turtles.launch

<?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>

Code implementation function:

Similar to declaring a global variable and assigning a value, you can directly change the value of the variable later, saving you the effort of line-by-line modification

Dynamic parameter passing function:

roslaunch launch01_basic arg.launch car_length:=0.6

3. ROS workspace coverage problem

Try to avoid the problem of ROS workspace coverage

**Problem description: **In different workspaces, there may be cases where the function package has the same name. At this time, if the function package with this name is called, the wrong path function package may be called, and confusion may occur when calling;

Reason analysis : ROS will parse the hidden folder .bashrc file and generate the ROS package path. The path information will arrange the path priority according to the order of the workspace configured in .bashrc, that is, the last configuration has the highest priority, and the higher the priority The lower the value, the current path priority can be viewed through the echo command. The higher priority in the front will be used first when the program is called. The sample code is as follows:

echo $ROS_PACKAGE_PATH 

**Conclusion:** When the function package has the same name, there will be a call priority, that is, the last configuration will be executed first, and you can view it through ROS_PACKAGE_PATH

BUG description:

When multiple workspaces are sourced in the .bashrc file, it may happen that only two workspaces are included in the ROS PACKAGE PATH, you can delete the build and devel directories of the custom workspace, re-catkin_make, and then reload. bashrc file, problem solved

4. Duplicate ROS node name

When you need to start a node with the same name or start the same node multiple times, you should pay attention to the problem of duplication of ROS node names

**Concept:**Namespace is to add a prefix to the name, and name remapping is to alias the name. Both of these strategies can solve the node duplicate name problem, and there are many ways to implement the two strategies:

  • rosrun command
  • launch file
  • Encoding implementation

The above three methods can avoid duplicate node names through namespace or name remapping. This section will demonstrate the use of the three one by one. The requirements to be realized by the three are similar.

4.1rosrun setting namespace and remapping

4.1.1rosrun set namespace

Syntax: rosrun package name node name __ns:= new name

Code example:

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

Both nodes are up and running;

4.1.2 rosrun name remapping

Syntax: rosrun package name node name __name:= new name

Code example:

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

Both nodes are up and running;

4.1.3 rosrun namespace and name remapping superimposed use

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

Code example:

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

Both nodes are up and running;

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

4.2 Launch file setting namespace and remapping

When using the syntax of the launch file, there are two attributes in the node tag: name and ns, which are used to implement name remapping and namespace settings respectively. It is also relatively simple to set up namespaces and name remapping using launch files.

launch file:

<?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>

In the node tag in the launch file, the name attribute must exist, and the ns namespace is optional;

operation result:

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

It can also be seen from here that the node label call is not executed strictly in the order of programming; it may be in the reverse order of calling;

4.3 Encoding settings namespace and remapping

If you customize the node implementation, you can more flexibly implement setting namespaces and name remapping;

4.3.1 C++ Implementation: Remapping

4.3.1.1 Name alias setting

Core code:ros::init(argc,argv,"zhangsan",ros::init_options::AnonymousName);

4.3.1.2 Execution

A timestamp is appended to the name.

4.3.2 C++ Implementation: Namespaces

4.3.2.1 Namespace Settings

core code

  std::map<std::string, std::string> map;
  map["__ns"] = "xxxx";
  ros::init(map,"wangqiang");
Copy
4.3.2.2 Execution effect

The node name sets the namespace.

Guess you like

Origin blog.csdn.net/TianHW103/article/details/127625482