使用ros::init设置节点名称 和 launch文件中node里面使用name参数设置节点名称的区别

avatar
作者
猴君
阅读量: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

实践建议

  • 如果你需要在运行时动态地设置节点名称,或者希望避免命名冲突时自动添加后缀,那么使用 ros::init 是更好的选择。
  • 如果你需要在 launch 文件中启动多个节点,并且希望它们具有特定的名称,或者需要在不同的 launch 文件之间共享相同的节点名称,那么在 <node> 标签中使用 name 参数更为合适。

如果在 ROS 节点中同时使用 ros::init 设置节点名称,并且在 launch 文件中也通过 标签的 name 属性设置了节点名称,那么最终节点的名称将由 launch 文件中的 name 属性决定。

详细说明

  1. ros::init 设置节点名称

    • 当你使用 ros::init 设置节点名称时,ROS 会在内部记录这个名称,并且会尝试使用这个名称来注册节点。
    • 例如:
      ros::init(argc, argv, "my_node_name"); 
  2. launch 文件中的 name 属性

    • 当你在 launch 文件中启动节点时,通过 <node> 标签的 name 属性指定的名称将覆盖 ros::init 设置的名称。
    • 例如:
      <node pkg="mypkg" type="mynode" name="my_launch_node" /> 

实际效果

  • 当你启动节点时,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 设置的名称不会被使用。

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!