阅读量:0
在 ROS 中,ros::init
和 launch 文件中 node
标签的 name
参数都用于设置节点的名称,但它们的作用和影响有所不同:
1. ros::init
设置节点名称
当你使用 ros::init
函数初始化一个 ROS 节点时,你可以通过传递第三个参数来设置节点的名称。例如:
ros::init(argc, argv, "my_node_name");
这里,"my_node_name"
是你给节点指定的名字。ros::init
设置的节点名称通常是节点的全局名称,即 ROS 主节点(master)将使用这个名字来识别和跟踪这个节点。
2. Launch 文件中的 name
参数
在 launch 文件中,你可以为每个 <node>
标签指定 name
属性。例如:
<node pkg="mypkg" type="mynode" name="my_launch_node" />
这里,name="my_launch_node"
指定了节点的名称。当通过 launch 文件启动节点时,ROS 会使用这个名称作为节点的名称。
区别
命名冲突处理:
- 如果使用
ros::init
设置节点名称,ROS 会检查是否有其他具有相同名称的节点正在运行。如果有,ROS 会自动为新节点添加后缀(如_1
、_2
等),以避免命名冲突。 - 如果使用 launch 文件中的
name
参数,ROS 会直接使用提供的名称,即使有命名冲突也不会自动添加后缀。因此,如果在 launch 文件中指定了相同的名称,ROS 会报错。
- 如果使用
灵活性:
- 使用
ros::init
设置节点名称允许你在运行时动态地改变节点的名称,例如根据不同的运行环境或配置文件来设置不同的名称。 - 使用 launch 文件中的
name
参数则是在编写 launch 文件时就确定了节点的名称,这种方式更适合固定的部署场景。
- 使用
命名空间:
- 当你在 launch 文件中使用
<node>
标签时,你可以为节点指定命名空间,例如:
这样,节点的实际名称将是<node pkg="mypkg" type="mynode" name="my_node" namespace="/robot1" />
/robot1/my_node
。 - 如果使用
ros::init
设置节点名称,你也可以通过ros::NodeHandle
的构造函数来指定命名空间,例如:
这样,节点的名称将会是ros::NodeHandle nh("/robot1");
/robot1/my_node_name
。
- 当你在 launch 文件中使用
实践建议
- 如果你需要在运行时动态地设置节点名称,或者希望避免命名冲突时自动添加后缀,那么使用
ros::init
是更好的选择。 - 如果你需要在 launch 文件中启动多个节点,并且希望它们具有特定的名称,或者需要在不同的 launch 文件之间共享相同的节点名称,那么在
<node>
标签中使用name
参数更为合适。
如果在 ROS 节点中同时使用 ros::init 设置节点名称,并且在 launch 文件中也通过 标签的 name 属性设置了节点名称,那么最终节点的名称将由 launch 文件中的 name 属性决定。
详细说明
ros::init
设置节点名称:- 当你使用
ros::init
设置节点名称时,ROS 会在内部记录这个名称,并且会尝试使用这个名称来注册节点。 - 例如:
ros::init(argc, argv, "my_node_name");
- 当你使用
launch 文件中的
name
属性:- 当你在 launch 文件中启动节点时,通过
<node>
标签的name
属性指定的名称将覆盖ros::init
设置的名称。 - 例如:
<node pkg="mypkg" type="mynode" name="my_launch_node" />
- 当你在 launch 文件中启动节点时,通过
实际效果
- 当你启动节点时,ROS 会首先读取
ros::init
设置的节点名称。 - 如果你随后通过 launch 文件启动节点,并且在
<node>
标签中指定了name
属性,那么这个name
属性将成为节点的实际名称,无论ros::init
设置的名称是什么。
示例
假设你有以下代码:
#include "ros/ros.h" int main(int argc, char **argv) { ros::init(argc, argv, "my_node_name"); ros::NodeHandle nh; ROS_INFO("Node name: %s", ros::this_node::getName().c_str()); ros::spin(); return 0; }
同时你有以下 launch 文件:
<launch> <node pkg="mypkg" type="mynode" name="my_launch_node" /> </launch>
当你通过 launch 文件启动节点时,ROS 会使用 name="my_launch_node"
作为节点的名称,而不是 ros::init
设置的 "my_node_name"
。因此,节点的日志输出将会显示:
Node name: my_launch_node
总结
- 如果你既使用
ros::init
设置节点名称,又在 launch 文件中通过<node>
标签的name
属性设置了节点名称,那么最终的节点名称将由 launch 文件中的name
属性决定。 - 这种情况下,
ros::init
设置的名称不会被使用。