ROS:关于节点和节点句柄以及命名空间

ROS中的节点和节点句柄有重要区别。节点句柄用于启动和关闭节点,并提供命名空间管理。一个cpp文件可创建多个句柄,但它们共享同一节点。命名空间可自定义,全局命名不受外部影响,私有命名则置于节点名下。节点句柄的销毁会导致节点关闭,而通过指定命名空间,可实现灵活的组件组织。
摘要由CSDN通过智能技术生成

ROS:关于节点和节点句柄以及命名空间

参考资料:ROS官方文档

首先,我们需要明确的是 节点节点句柄 是不同的。一般而言,一个cpp文件只能启动一个ROS节点,但作为该节点的句柄却可以设置多个。

The ros::NodeHandle class serves two purposes. First, it provides RAII-style startup and shutdown of the internal node inside a roscpp program. Second, it provides an extra layer of namespace resolution that can make writing subcomponents easier.

如上所言,节点句柄类有两个作用:

  1. 在一个roscpp程序中,节点句柄可以启动或关闭一个ROS内部节点;
  2. 节点句柄可以增加一层命名空间,可以为编写组件提供便利。

1.启动或关闭节点

创建一个节点句柄最简单的方式如下所示:

ros::NodeHandle nh;

在创建节点句柄时,若内部节点还未启动,则创建的句柄会启动该节点。一旦该节点所有的句柄实例(同一个cpp程序下创建的都是同一个节点的句柄)都被销毁,则该节点也会自动关闭。这句话也从侧面说明了,一个节点可以创建多个句柄。

On creation, if the internal node has not been started already, ros::NodeHandle will start the node. Once all ros::NodeHandle instances have been destroyed, the node will be automatically shutdown.

2.命名空间

节点句柄的另一个构造函数形式可以让我们自定义命名空间:

ros::NodeHandle nh("my_ns");  // <node_namespace>/my_ns
  • 若存在节点命名空间,如在launch文件中启动该节点时加入ns="node_ns",则命名空间为node_ns/my_ns
  • 若不存在节点命名空间,则为my_ns

另外也可以创建多个节点句柄,然后为某个句柄设置父节点句柄:

ros::NodeHandle nh1("ns1");  // <node_namespace>/ns1
ros::NodeHandle nh2(nh1, "ns2");  // <node_namespace>/ns1/ns2

此外,还有两种命名方式:

  1. 全局命名

    ros::NodeHandle nh("/my_global_namespace");  // /my_global_namespace(不受外部命名影响)
    

    注意:在ROS的命名中,加或不加/是存在区别的。 若加上/,说明这是一个全局命名,则无法再被放入一个命名空间当中;若不加/,则可以通过如launch中设置ns,使得该命名被放入到该命名空间当中。比如,我定义了两个发布器,发布话题分别为/cmd_velcmd_vel,此外若外部还存在一个命名空间为dwa_planner,则它们的命名分别变为

    • /cmd_vel => /cmd_vel
    • cmd_vel => /dwa_planner/cmd_vel
  2. 私有命名

    // 1.~+name
    ros::NodeHandle nh("~my_private_ns");
    ros::Subscriber sub = nh.subscribe("my_private_topic", ...);  // <node_namespace>/<node_name>/my_private_ns/my_private_topic
    
    // 2.~
    ros::NodeHandle nh("~");
    ros::Subscriber sub = nh.subscribe("my_private_topic", ...);  // <node_namespace>/<node_name>/my_private_topic
    

    私有命名与上述提到的命名都不同,它会把原本命名放入到<node_name>下。因此,上面订阅器的话题的命名如下:

    • <node_namespace>/<node_name>/my_private_ns/my_private_topic

    需要注意的是,<node_name>指的是节点名字,也就是在cpp程序中初始化节点时的命名。 节点名字最好让程序中初始化的名字和launch文件中启动该节点时设置的"name"保持一致。

    ros::init(argc, argv, "node_name");  // 节点名字
    

总结:从上可知,一个cpp文件中可以设置多个节点句柄,但它们的区别只在于命名空间不同,表示的都是同一个节点。

  • 49
    点赞
  • 158
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值