ROS之命名空间

2023-05-16

已经学ROS快两个月了,一开始对ROS 命名空间,参数,参数服务器,重映射没认真看,后来发现很重要,它是学习ROS代码的基础。我们都知道ros以topic通信,但是只靠topic通信是远远不够的,于是使用客服端服务器、actionlib、参数服务器来补充,这几种都是通信的机制。但还不够,为了方便又加入了命名空间,重映射。只有清楚了这些,其实才算对ros有了初步了解,下面的几个文章我将分别介绍。

在介绍之前,我先抱怨一下,对于只学过C语言的我,没有写过什么项目,然后自己学习ROS,简直痛苦。想找几个资料,英文的根本看不懂,四级都没过,找中文的基本都是直译过来的,而且大多数人的理解,或多或少的都有点错误,当然,我的理解应该有点错误的,希望明白之人能指出,感激不尽。

在C++中的命名空间,using namespace std,std就是名空间,这里的命名空间跟它差不多,但是比它更多,一层嵌套一层,用的特别灵活。先举个简单的例子,然后细说。

我们先运行一个小乌龟:

rosrun turtlesim turtlesim_node 


turtlesim是一个包名,turtlesim_node是执行文件名,可以与节点名相同,也不可以不同。这里的节点名是 /turtlesim。说明可能初始化的时候是这样的,为什么是可能,因为重映射可以改变:

ros::init(argc, argv, "turtlesim");

节点名前面加个“/”,这意味这个节点是全局空间的。另外说下,节点是有类型的,节点的类型就是节点所在包名和可执行文件名的加。一般的定义节点句柄:

ros::NodeHandle n;

NodeHandle是一个类,然后我们实例化的一个对象n.这种情况默认n这个节点是全局命名空间下的。你可以认为"/"这个斜杠就是全局名空间。现在我们来改变这个节点的名空间,通过重映射,我们先用重映射,以后再讲。


你会发现,这个节点的名变为/my/turtlesim,此时,节点所在的空间发生了变化,我们把这个节点从全局名空间放进了一个/my的名空间下。于是节点内的所有参数,服务,话题也都放在了/my的命名空间下。

你会发现,它所发布的和订阅的话题,服务都在这个名空间,这意味着它现在只会订阅和发布这个名空间下的话题。

这个时候运行rosrun turtlesim turtle_teleop_key ,是不会控制小乌龟的,因为它只会发布/turtel1/cmd_vel话题,不会发布/my/turtel1/cmd_vel。

这个时候你可能懂一点了,节点,话题,服务,包括参数都是有名空间的,这个名空间约束着是它们的范围。这个时候你可能会想,那不在一个名空间节点是不是就无法通信了,显然这种想法是错误的,这违背了我们通信的初衷,我们通过重映射和参数服务器,很容易让不同命名空间的节点都能通信。好吧,先简单的通过重映射使他们通信,具体下一篇文再讲,这一篇主要记录命名空间。


看到没,重映射不仅可以把命名空间改变,还可以将发布的话题给改变(还可改变参数的空间),这样/my空间下的乌龟就可以移动了。当然你也可以直接将这个节点的名空间改为/my,这样他们在同一个命名空间,当然可以直接通信了。

上面说的是全局命名空间,还有一个相对命名空间,/turtle1/cmd_vel就是相对命名空间,它在/my的命名空间下,发布/turtle1/cmd_vel话题,解析器会把它解析成/my/turtle1/cmd_vel话题。发布的/turtle1/cmd_vel话题相对/my空间下是/turtle1/cmd_vel话题,对于全局它是/my/turtle1/cmd_vel话题。

接下来我们看看节点句柄的构造函数,也可以跳过:

namespace ros
{

  class NodeHandleBackingCollection;

  /**
   * \brief roscpp's interface for creating subscribers, publishers, etc.
   *
   * This class is used for writing nodes.  It provides a RAII interface
   * to this process' node, in that when the first NodeHandle is
   * created, it instantiates everything necessary for this node, and
   * when the last NodeHandle goes out of scope it shuts down the node.
   *
   * NodeHandle uses reference counting internally, and copying a
   * NodeHandle is very lightweight.
   *
   * You must call one of the ros::init functions prior to instantiating
   * this class.
   *
   * The most widely used methods are:
   *   - Setup:
   *    - ros::init()
   *   - Publish / subscribe messaging:
   *    - advertise()
   *    - subscribe()
   *   - RPC services:
   *    - advertiseService()
   *    - serviceClient()
   *    - ros::service::call()
   *   - Parameters:
   *    - getParam()
   *    - setParam()
   */
  class ROSCPP_DECL NodeHandle
  {
  public:
    /**
     * \brief Constructor
     *
     * When a NodeHandle is constructed, it checks to see if the global
     * node state has already been started.  If so, it increments a
     * global reference count.  If not, it starts the node with
     * ros::start() and sets the reference count to 1.
     *
     * \param ns Namespace for this NodeHandle.  This acts in addition to any namespace assigned to this ROS node.
     *           eg. If the node's namespace is "/a" and the namespace passed in here is "b", all 
     *           topics/services/parameters will be prefixed with "/a/b/"
     * \param remappings Remappings for this NodeHandle.
     * \throws InvalidNameException if the namespace is not a valid graph resource name
     */
    NodeHandle(const std::string& ns = std::string(), const M_string& remappings = M_string());
  
    NodeHandle(const NodeHandle& rhs);
    
    NodeHandle(const NodeHandle& parent, const std::string& ns);

    NodeHandle(const NodeHandle& parent, const std::string& ns, const M_string& remappings);
 
    ~NodeHandle();
}

是不是发现他有多个构造函数,


ros::init(argc, argv, "my_node_name");
ros::NodeHandle nh("/my_node_handle_namespace");  
我们创建节点句柄nh时,指明了它的命名空间,所以nh的命名空间为/my_node_handle_namespace,

所以这个节点里的所有的参数,话题前面都应该有/my_node_handle_namespace

最后一种命名空间是私有命名空间,私有名称,以一个波浪字符(~)开始。和相对名称一样,私有名称并不能完全确定它们自身所在的命名空间,而是需要ROS 客户端库将这个名称解析为一个全局名称。与相对名称的主要差别在于,私有名称不是用当前默认命名空间,而是用的它们节点名称作为命名空间。


ros::init(argc, argv, "my_node_name");
ros::NodeHandle nh1("~");
ros::NodeHandle nh2("~foo");  

 ros::Subscriber sub1 = nh1.subscribe("my_private_topic", ...);  

 ros::Subscriber sub2 = nh2.subscribe("my_private_topic", ...);  
sub1订阅的话题是my_node_name/my_private_topic

sub2订阅的话题是my_node_name/foo/my_private_topic

到这里,我相信大家对命名空间似懂非懂,这个东西到底是干什么的。如果你懂上面说的东西,接下来,看看参数的使用,似乎就懂命名空间到底是干什么的了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ROS之命名空间 的相关文章

随机推荐

  • Linux基础知识学习:Linux下修改文件名或修改文件夹名称(有待解决问题)

    Linux下修改文件名或修改文件夹名称 1 修改文件夹名称 1 1我先创建一个test文件夹用来测试 span class hljs keyword mkdir span test 1 2用 mv 命令 将文件移动 xff0c 目标地址如果
  • C语言学习:平方-->乘方(m的n方)

    平方 xff1a 直接用两个数 或变量 相乘就可以表示平方 xff0c 比如x x 不过如果 xff0c 需要求m的n次方 xff0c 就需要用到pow x y 乘方 包括开方 这个库函数了 xff0c 使用pow x y 这个库函数 xf
  • MySql学习:自定义函数之带参函数

    delimiter 如果数据库 test 里的存在函数 formatDate xff0c 就删除这个函数 DROP FUNCTION IF EXISTS test formatDate 创建一个函数 CREATE FUNCTION test
  • docker离线安装

    1 下载离线包 docker官网下载地址 本示例下载的是 xff1a docker 19 03 14 tgz 2 解压到对应目录 解压文件 span class token function tar span xzvf docker 19
  • 2013年:一个技术领导的启程

    作者 xff1a 朱金灿 来源 xff1a http blog csdn net clever101 又到一年总结时 总的来说 xff0c 这一年忙碌而充实 xff0c 现在有点胸中有千言却又不知从何说起 可能每一个希望有所作为的开发人员都
  • STM32——硬件IIC从机通信

    前言 xff1a 根据网上的资料 xff0c 大部分网友表示STM32自带的硬件IIC存在bug xff0c 读写时很容易卡死 自己在调试的时候也出现卡死的情况 xff0c 最后一点一点调试 xff0c 也还是调通了 本文将记录自己调试ST
  • HI3516的编译参数-mcpu=cortex-a7、-mfloat-abi=softfp和-mfpu=neon-vfpv4

    前言 Hi3516A具有浮点运算单元和neon 文件系统中的库是采用软浮点和neon编译而成 xff0c 因此所有Hi3516A板端代码编译时需要在Makefile里面添加选项 mcpu 61 cortex a7 mfloat abi 61
  • 算法移植优化基础

    PS xff1a 为了面试准备的 xff0c 总结的有点粗糙 ARM xff1a Advanced RISC Machines xff0c ARM架构是面向低预算市场设计的第一款RISC微处理器 xff0c 基本是32位单片机的行业标准 x
  • DBoW2在windows上的vs工程搭建方法

    xfeff xfeff 注释 xff1a 蓝体字是 opencv249 专用的修改 xff1b 黑体字是 opencv3 需要的修改 环境 xff1a vs2012 32bit 叙述比较简略 不明之处可以留言 1 配置 opencv 2 4
  • MSCKF_vio学习笔记

    最近因为项目需求 xff0c 对MSCKF vio的论文和代码进行了一番研读 xff0c 现将学习过程记下 MSCKF vio是一种基于多状态约束卡尔曼滤波器的双目视觉里程计 其中多状态约束是指将多帧图像的相机位姿加入卡尔曼状态向量中 xf
  • MSCKF2.0(Mingyang Li-IJRR2013) 论文要点总结

    论文 xff1a Li M Mourikis A I High precision consistent EKF based visual inertial odometry J The International Journal of R
  • SLAM,SLAM+IMU的状态估计问题描述-个人理解

    1 状态估计问题 令状态变量为x 61 x1 x2 x3 观测变量为z 61 z1 z2 z3 状态估计问题等同于求解条件概率分布 xff1a P x z xff0c 在当前观测状态z下的状态x分布 xff0c 也就是最可能的状态是什么 由
  • VINS-Fusion运行时的段错误(核心已转储)解决方法

    平台 ubuntu16 04 43 ROS 问题描述 xff1a 前两天VINS的原作者开源了VINS Fusion的双目版以及给出了和GPS融合的一个demo xff0c 所以试着运行下数据集 每次单目运行10s左右 xff0c 双目1
  • Jetson Xavier NX 刷机+更换清华源完美讲解

    当你拿到梦寐以求的NVIDIA Jetson Xavier NX开发板时 xff0c 第一个工作就是要刷机 究竟要怎么做呢 xff1f Let s go 这种板子有两种 xff0c 一种是带Micro SD卡槽的 xff0c 可以插入小型S
  • vmware下vmdk文件越来越大的解决方法探讨

    前段时间在vmware下面安装了ubuntu镜像 xff0c 用了一段时间后发现ubuntu的vmdk文件越来越大 xff0c 达到了31 6GB xff0c 如下图所示 而且随着继续安装新的软件仍然在增大中 即使在ubuntu里面删除了文
  • 工作日志的作用

    朱金灿 公司提倡我们每天都写工作日志 这使得我思考工作日志的作用 我想了一下 xff0c 工作日志应该要起两个作用 xff1a 1 计划作用 俗话说 xff1a 凡事预则立 xff0c 不预则废 最好在每天开始工作前先在工作日志上写下今天要
  • Tracealyzer for FreeRTOS(FreeRTOS+Trace) 详解(源码解析+移植)

    原文 xff1a http blog csdn net zcshoucsdn article details 54670473 最近公司搞新项目 xff0c 需要使用FreeRTOS xff0c 之前只有Linux的基础 xff08 学了个
  • 职场 | Intel因特尔2019届软件工程师秋招笔试题

    同样的本文是对笔试过程中 xff0c 仍然记得的考点的查漏补缺 一共分为三部分 xff1a 选择题 编程题 附加题 时间是两个小时 xff0c 个人感觉因特尔的笔试题对于内核 xff0c 内存管理等方面的考点较多 xff0c 具体属于什么科
  • Linux-LCD驱动实现

    一 帧缓冲设备驱动在Linux子系统中的结构 xff1a 二 帧缓冲相关的重要数据结构 从帧缓冲设备驱动程序结构 看 xff0c 该驱动主要跟fb info结构体有关 xff0c 该结构体记录了帧缓冲设备的全部信息 xff0c 包括设备的设
  • ROS之命名空间

    已经学ROS快两个月了 xff0c 一开始对ROS 命名空间 xff0c 参数 xff0c 参数服务器 xff0c 重映射没认真看 xff0c 后来发现很重要 xff0c 它是学习ROS代码的基础 我们都知道ros以topic通信 xff0