ROS 节点初始化步骤、topic/service创建及使用

2023-05-16

目录

1、节点初始化步骤

2、service 创建及使用

3、topic创建及使用

4、框架总结


这是一个总结复盘的记录

1、节点初始化步骤

在 mian 函数中使用 ros::init 初始化节点,注册节点名,这里注册的节点名为 "test_node" :

#include <ros/ros.h>
int main(int argc, char ** argv)
{
    ros::init(argc, argv, "test_node"); //解析传入的ROS参数,定义节点名称
    ros::NodeHandle nh; // 创建句柄对象
    。。。
}

一个 cpp 文件只能注册一个 ROS 节点,但作为该节点的句柄却可以设置多个,不同的句柄通过不同的命名空间来区别。在这里节点句柄有两个作用:

  1. 第一个是在roscpp程序里管理内部节点的启动和关闭
  2. 第二个是它提供了一个额外的命名空间解析层,可以使编写子组件变得更容易。

节点句柄允许让我们自定义命名空间,命名空间分为 全局命名空间、局部命名空间、私有命名空间。理解命名空间有助于我们理解话题名(message)或者服务名(service)该如何调用。

假设创建的包名为 test,该包中的某个节点的上层命名空间为 <node_namespace> ,不过默认是没有这层命名空间的,除非你在代码中刻意设置了这个上层命名空间。为了说明问题,下面的例子中都会带上这层命名空间。

  • 对于局部变量,定义如下:
ros::NodeHandle nh1("namespace1");  // 局部命名空间:<node_namespace>/namespace1

这个句柄的完整命名为:<node_namespace>/namespace1 ,也就是 test/namespace1

  • 对于全局命名空间 即在名称前面加一个斜线 "/" ,定义如下:
ros::NodeHandle nh3("/namespace2");  // 全局命名空间:/namespace2

 其不受外部命名空间的影响,这个句柄的完整命名为:/namespace2

  • 对于私有命名空间 即在名称前面加一个波浪线 "~" ,定义如下:
ros::NodeHandle nh3("~namespace3");  // 私有命名空间:<node_namespace>/<node_name>/namespace4

其实际的命名为:<node_namespace>/<node_name>/namespace3

也就是:test/test_node/namespace3

这里注意 <node_namespace><node_name> 的区别,前面有说。私有名称就是节点私有,因此要加上节点名,其他的只需要通过包名直接定位就行了

  • 另外还可以设置具有父子关系的句柄
ros::NodeHandle nh2(nh1, "namespace4");  // 设置节点的父句柄:<node_namespace>/namespace1/namespace4

这个句柄的完整命名为:<node_namespace>/namespace1/namespace4  

也就是:test/namespace1/namespace4  

启动节点使用如下命令:

rosrun <package_name> <node_name>

对于本例包名为 test,节点名为 test_node,启动节点的命令就是:

rosrun test test_node

2、service 创建及使用

service 数据类型文件建立在 srv 文件夹中,后缀名为 .srv, 分为 request 与 response 两部分,用三条短横线 --- 隔开,假设我创建了名为 mySrvInfo.srv 的 service 数据。 这里以创建服务端(server)为例。

service 通过前面定义的句柄 nh 来创建,类型是 ros::ServiceServer。第一个参数是这个服务的名字,这个命名空间也是分局部全局私有的。第二个参数是回调函数的函数名。

ros::ServiceServer my_service = nh.advertiseService("/my_service", my_serviceCallback);

这里的设置是全局命名空间,调用时直接使用  /my_service 即可,前面不需要加其他命名空间。

其他的话一般的完整名称为:<node_namespace>/<node_name>/<nh_name>/<service_name>

具体的名称是具体定义时的设置而定,比如前面定义句柄是并没有给句柄命名,则忽略 <nh_name>,如果不是私有命名空间,则忽略<node_name>,其他类似,后面说的 topic 的命名也是一样的。

service是有回调函数的,service的回调函数有返回值,类型为 bool

bool my_serviceCallback(test::mySrvInfo::Request  & req,
                        test::mySrvInfo::Response & res)
{
    ...
    // you should return true or false
}

在定义 srv 文件时,req 和 res 部分会用 --- 隔开,程序在编译时会自动生成对应的结构体的头文件放在 devel/include/<package_name> 文件夹下,使用时 req 和 res 部分是要分开声明的,其命名空间为:

  • <package_name>::<srv_file_name>::Request 
  • <package_name>::<srv_file_name>::Respone

service 服务端可以通过其他的客服端节点进行调用,或者使用命令行的形式:

rosservice call /my_service "<req参数>"

3、topic创建及使用

topic 也是通过句柄 nh 创建的,topic 的消息类型文件建立在 msg 文件夹中,后缀名为 .msg,假设我创建了名为 myMsgInfo.msg 的 message 数据。这里记录下如何订阅(subscribe)消息的。

第一个参数是 topic 的名字,同样可以全局/局部/私有命名

第二个参数是一个消息接收队列,可以规定队列的长度,相当于数据缓冲的作用,如果接受数据大于缓冲队列的长度,则会丢弃最早缓冲的数据

第三个参数是回调函数的名字,函数名随便起,符合语法要求就行。

ros::Subscriber my_subscribe = nh.subscribe("/my_topic", 10, elevatorSetCallback);

topic 的回调函数没有返回值,传入的参数就是消息类型的结构体指针,回调函数就是对接收到的消息(由发布节点发布的)进行处理。

void myTopicCallback(const test::myMsgInfo::ConstPtr & msg)
{
    ...
}

程序在编译时会自动生成消息文件对应的结构体的头文件放在 devel/include/<package_name> 文件夹下,使用时调用消息类型对应的常量指针,其命名空间为:

  • <package_name>::<msg_file_name>::ConstPtr

比如这里就是 test::myMsgInfo::ConstPtr

topic 可以由其他的节点进行调用,或者使用命令行的形式,发布消息供节点订阅的命令为:

rostopic pub -1 /my_topic test/myMsgInfo "<msg参数>"

-1 代表发布一次,不加这个参数就是一直发布,后面跟 topic 名字,这里用的全局命名空间,就是 /my_topic,话题名后跟消息类型,具体为 <package_name>/<msg_name>,这里就是test/myMsgInfo,然后最后是具体的参数值,要跟msg文件里定义的参数类型相对应。

最后在代码后面加上 ros::spin(); 函数实现阻塞回调。

4、框架总结

// service 回调函数
bool my_serviceCallback(test::mySrvInfo::Request  & req,
                        test::mySrvInfo::Response & res)
{
    ...
    // you should return true or false
}
// topic订阅回调函数
void myTopicCallback(const test::myMsgInfo::ConstPtr & msg)
{
    ...
}

// 主函数
int main(int argc, char ** argv)
{
  // init node
  ros::init(argc, argv, "test_node");
  // nh init
  ros::NodeHandle nh;

  // srvice server
  ros::ServiceServer my_service = nh.advertiseService("/my_service", my_serviceCallback);

  // topic subscriber
  ros::Subscriber my_subscribe = nh.subscribe("/my_topic", 10, elevatorSetCallback);

  ROS_INFO("start");

  ros::spin();

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

ROS 节点初始化步骤、topic/service创建及使用 的相关文章

  • Snipaste(简单好用的截图工具)下载和使用

    下载 下载地址 xff1a https www snipaste com 简单版就够用了 绿色软件 xff0c 直接安装就行 使用快捷键 F1截图 xff0c 可测量大小 xff0c 设置箭头 xff0c 书写文字等F3在桌面置顶显示点击图
  • 通过外部中断按键去控制蜂鸣器开关

    EXTI功能说明 xff1a 要产生中断 xff0c 必须先配置好并使能中断线 根据需要的边沿检测设置2个触发寄存器 xff0c 同时在中断屏蔽寄存器的相应位写 1 允许中断请求 当外部中断线上发生了期待的边沿时 xff0c 将产生一个中断
  • 信号量的使用

    信号量 英文名字 xff1a semaphore 这里的进程信号量会为下列的信号量打基础 Ucos系统的信号量c线程的信号量java进程和线程的信号量 信号量作用 当多个进程 线程进行共享操作时 xff0c 用于资源保护 xff0c 以防止
  • 海康威视摄像头对接SDK实时预览功能和抓拍功能,懒癌福利,可直接CV

    海康威视摄像头完成实时预览功能和抓拍功能 背景思路 流程开发步骤1 海康的SDK xff0c 只需要在项目启动的时候初始化一次就行 xff0c 所以我直接将初始化SDK和加载DLL库的代码丢到启动类中去了 xff1a 2 先讲实时预览功能
  • 一、什么是SLAM?

    书中定义 xff1a slam是指移动智能体从一个未知环境里未知地点出发 xff0c 在运动过程中通过自身传感器观测周围环境 xff0c 并根据环境定位自身位置 xff0c 再根据自身的位置进行增量式的地图构建 xff0c 从而达到同时定位
  • ROS 创建工作空间流程

    本文以移植代码为例说明 目标是把一款云台SDK中的ROS代码部分抠出来移植到自己创建的工作空间中 记录下大致的流程 目录 1 创建工作空间 2 编译工作空间 xff08 可选 xff09 3 设置环境变量 xff08 可选 xff09 4
  • 边缘计算系列之MEC介绍

    前言 上篇内容 xff0c 跟大家简单介绍了边缘计算发展现状和边缘计算的基本概念 今天 xff0c 我们来讲讲MEC 目录 一 MEC的基本概念 二 MEC和边缘计算的关系 三 MEC的价值和优势 四 运营商MEC白皮书 1 MEC的基本概
  • 元学习(meta learning) 最新进展综述论文,28页pdf

    关注上方 深度学习技术前沿 xff0c 选择 星标公众号 xff0c 资源干货 xff0c 第一时间送达 xff01 本文综述了元学习在图像分类 自然语言处理和机器人技术等领域的应用 与深度学习不同 xff0c 元学习使用较少的样本数据集
  • 王海峰、李飞飞、山世光、王井东、汪玉……众多AI华人学者入选2022 IEEE Fellow...

    来源 xff1a 机器之心 北京时间 11 月 24 日凌晨 xff0c IEEE 公布了 2022 年度新一届会士的入选完整名单 IEEE 全称是美国电子电气工程师学会 xff08 Institute of Electrical and
  • 博后年薪58万起,副教授35万起,出站享80万安家费或100万房补,西电杭州研究院...

    来源 博士后招聘平台 编辑 硕博就业圈 研究院简介 XDU HANGZHOU 西安电子科技大学杭州研究院是西安电子科技大学为深入贯彻落实党中央 国务院关于深化产教融合改革部署和教育部 国家发展改革委 财政部关于加快新时代研究生教育改革发展的
  • 为什么要使用事件委托,使用事件委托的好处

    事件委托在我们程序员应聘阶段好多人都会被面试官问及到 xff0c 那到底什么是事件委托呢 xff1f 其实啊 xff0c 事件委托是本应给子元素注册的事件 xff0c 注册在父元素身上 然后使用 e tage方法由父元素统一分配给每个触发了
  • C++类和对象——友元

    目录 xff08 1 xff09 xff0c 全局函数做友元 xff08 2 xff09 xff0c 类做友元 xff08 3 xff09 xff0c 成员函数做友元 类中的私有属性 xff0c 也想让类外特殊的函数或者类进行访问 xff0
  • ubuntu系统安装TVM(保姆级)

    下载tvm span class token function git span clone recursive https github com apache tvm tvm 建议开代理 下载完成后在主目录看到tvm文件夹 依赖工具安装
  • Linux防火墙——Firewalld防火墙规则(内含防火墙的配置方法、图形化工具、firewall-cmd命令 )

    文章目录 Firewalld防火墙的配置一 Firewalld防火墙的配置方法运行时配置永久配置 二 Firewall config图形工具配置运行时配置 永久配置重新加载防火墙关联网卡到指定区域修改默认区域连接状态 区域 选项卡 服务 选
  • 人生苦短,我用k8s--------------Pod概念与Pod网络通讯方式详解

    一 pod概念 Pod是kubernetes中你可以创建和部署的最小也是最简的单位 Pod代表着集群中运行的进程 Pod中封装着应用的容器 xff08 数量大于等于1 xff0c docker最常用 xff0c 也可使用其他的 xff09
  • 装饰器三种写法之带参数的装饰器

    装饰器是AOP编程思想 xff0c 给主体函数增加功能 xff0c 又不让代码入侵到主体函数中 xff0c 实现高内聚 xff0c 低耦合 如果装饰功能部分代码也需要参数的话 xff0c 可以在原来的两层函数外面再加一层 xff0c 专门用
  • 把Linux下外设的USB端口号映射到固定的名字

    目录 1 固定USB设备的端口号的原理 2 rules文件的编写方法 3 映射结果查看 1 固定USB设备的端口号的原理 近期调试了一款云台 xff0c 控制方面需要用到串口通信 xff0c 调试过程中发现了一个问题 xff0c 就是 Li
  • GCC 消除编译器的特定警告

    GCC allows the user to selectively enable or disable certain types of diagnostics and change the kind of the diagnostic
  • 输入一个int型整数,按照从右向左的阅读顺序,返回一个不含重复数字的新的整数。 保证输入的整数最后一位不是0。

    题目描述 输入一个int型整数 xff0c 按照从右向左的阅读顺序 xff0c 返回一个不含重复数字的新的整数 保证输入的整数最后一位不是0 输入描述 输入一个int型整数 输出描述 按照从右向左的阅读顺序 xff0c 返回一个不含重复数字
  • C#WinForm

    WinForm 是 Windows Form 的简称 xff0c 是基于 NET Framework 平台的客户端 xff08 PC软件 xff09 开发技术使用 C 编程 C WinForm 编程需要创建Windows窗体应用程序项目 W

随机推荐