ROS 话题订阅模型之自定义消息类型 C++实现

ROS 话题订阅模型之自定义消息类型

1.自定义消息类型好处

ROS提供了许多标准的消息类型,如 std_msgs/Stringsensor_msgs/Image 等,涵盖了很多常见的数据类型和传感器数据。但是,在实际的开发中,我们经常会遇到需要传输的数据类型是标准消息类型中没有的,或者我们希望定义自己的数据结构以适应特定的应用场景。

因此,ROS允许用户定义自己的消息类型,这样用户可以更灵活地描述和传输数据。一些常见的情况包括:

  1. 特定的传感器数据:例如,你可能有一种特殊类型的传感器,它输出的数据类型在标准消息中没有涵盖。
  2. 自定义控制命令:你可能需要向机器人或设备发送一些自定义的控制命令,以便执行特定的动作或行为。
  3. 自定义数据结构:你可能需要在ROS系统中传输一些复杂的数据结构,例如地图、路径规划数据等。

自定义消息使得ROS更加灵活,能够满足各种各样的应用需求。通过定义自己的消息类型,用户可以更好地组织和传输数据,从而更容易地开发复杂的ROS应用。

2. 使用自定义消息类型

以发送模拟相机数据自定义类型数据为例:

2.1 定义msg 文件

在功能包下新建msg目录,添加Image.msg 文件,用来模拟相机数据

添加以下内容:

uint16 frame_id  # 图像帧的ID  
uint16 width     # 图像的宽度  
uint16 height    # 图像的高度  
int64 timestamp  # 图像的时间戳,通常以纳秒为单位

2.2 编辑配置文件

package.xml中添加编译依赖与执行依赖

  <build_depend>message_generation</build_depend>
  <exec_depend>message_runtime</exec_depend>

CMakeLists.txt编辑 msg 相关配置

find_package(catkin REQUIRED COMPONENTS
  roscpp
  std_msgs
  message_generation
)
## 配置 msg 源文件
add_message_files(
  FILES
  Image.msg
)
# 生成消息时依赖于 std_msgs
generate_messages(
  DEPENDENCIES
  std_msgs
)
#执行时依赖
catkin_package(
  CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
)

2.3 编译

使用编译命令之后,在 工程目录下的 devel/include/包名 会生成对应的C++头文件

后续编写代码要引用这些头文件

3.编写简单用例 C++ 传输模拟相机数据

如果使用VsCode开发,为了方便代码提示以及避免误抛异常,需要先配置 vscode,将前面生成的 head 文件路径配置进 c_cpp_properties.json 的 includepath属性:

{
    "configurations": [
        {
            "browse": {
                "databaseFilename": "${default}",
                "limitSymbolsToIncludedHeaders": false
            },
            "includePath": [
                "/opt/ros/melodic/include/**",
                "/usr/include/**",
                "/opt/ros/melodic/include",
                "/home/marxist/userdata/catkin_ws/devel/include/*"

            ],
            "name": "ROS",
            "intelliSenseMode": "gcc-x64",
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "gnu17",
            "cppStandard": "c++17"
        },
        {
            "name": "ros_inc",
            "includePath": [
                "${workspaceFolder}/**"
            ],
            "defines": [],
            "compilerPath": "/usr/bin/gcc",
            "cStandard": "c11",
            "cppStandard": "gnu++14",
            "intelliSenseMode": "linux-gcc-x64"
        }
    ],
    "version": 4
}

3.1 发布模拟相机数据

#include "ros/ros.h"
#include "image_node/Image.h"

int main(int argc, char *argv[])
{
    setlocale(LC_ALL,"");

    //1.初始化 ROS 节点
    ros::init(argc,argv,"image_pub_node");

    //2.创建 ROS 句柄
    ros::NodeHandle nh;

    //3.创建发布者对象
    ros::Publisher pub = nh.advertise<image_node::Image>("image_info",1000);

    //4.组织被发布的消息,编写发布逻辑并发布消息
   image_node::Image image_data;
 
    int start_id =0;
    image_data.height=1080;
    image_data.width=1920;

    ros::Rate r(1);
    while (ros::ok())
    {

  // 获取当前时间  
    ros::Time current_time = ros::Time::now();  
// 将当前时间转换为int64纳秒时间戳  
     image_data.timestamp = current_time.toNSec();  
        pub.publish(image_data);
         // 打印消息字段  

        ROS_INFO("Image frame ID: %d, Width: %d, Height: %d, Timestamp: %ld",image_data.frame_id,image_data.width,image_data.height,image_data.timestamp);
        ros::spinOnce();
    }
    return 0;
}

3.2 接受模拟相机数据



#include "ros/ros.h"
#include "image_node/Image.h"

void doGetData(const image_node::Image::ConstPtr& image_data){
  ROS_INFO("Image frame ID: %d, Width: %d, Height: %d, Timestamp: %ld",image_data->frame_id,image_data->width,image_data->height,image_data->timestamp);
}
int main(int argc, char *argv[])
{   
    setlocale(LC_ALL,"");
    //1.初始化 ROS 节点
    ros::init(argc,argv,"get_image");
    //2.创建 ROS 句柄
    ros::NodeHandle nh;
    //3.创建订阅对象
    ros::Subscriber sub = nh.subscribe<image_node::Image>("image_info",10,doGetData);
    
    //4.回调函数中处理 person

    //5.ros::spin();
    ros::spin();    
    return 0;
}

3.3 配置CmakeLists.txt

add_executable(
  image_pub  src/Image_pub.cpp)

add_dependencies(image_pub ${PROJECT_NAME}_generate_messages_cpp)

target_link_libraries(image_pub
  ${catkin_LIBRARIES}
)

add_executable(
  image_sub  src/Image_sub.cpp)

add_dependencies(image_sub ${PROJECT_NAME}_generate_messages_cpp)

target_link_libraries(image_sub
  ${catkin_LIBRARIES}
)

4. 效果图

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/568166.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Image captioning】论文阅读九—Self-Distillation for Few-Shot Image Captioning_2022

摘要 大规模图像字幕数据集的开发成本高昂,而大量未配对的图像和文本语料库可能有助于减少手动注释的工作。在本文中,我们研究了只需要少量带注释的图像标题对的少样本图像标题问题。我们提出了一种基于集成的自蒸馏方法,允许使用不成对的图像和字幕来训练图像字幕模型。该…

springcloud alibaba 整合seata的TCC

一、seata服务端搭建同上篇。 Seata的AT模式客户端两阶段提交流程源码分析 二、seata客户端的结构 1.示例DEMO工程 下单&#xff0c;扣余额&#xff0c; 减库存。 2. MAVEN配置。 父工程&#xff1a;由于spring-cloud-starter-alibaba-seata依赖的seata-spring-boot-starter…

C语言(static和extern)

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸各位能阅读我的文章&#xff0c;诚请评论指点&#xff0c;关注收藏&#xff0c;欢迎欢迎~~ &#x1f4a5;个人主页&#xff1a;小羊在奋斗 &#x1f4a5;所属专栏&#xff1a;C语言 本系列文章为个人学习笔记&#x…

Python写个二维码

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、进入官网下载二、下载一下三.输入代码 前言 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、进入官网下载 官网 pip insta…

FR-E840-0120-4-60 三菱变频器5.5KW型

FR-E840-0120-4-60 三菱变频器替换FR-E740-5.5K FR-E840用户手册,FR-E840-0120-4-60价格,FR-E840-5.5K价格,FR-E840-0120-4-60外部连接图,FR-E740-5.5K替换产品。 FR-E740-5.5K-CHT逐渐开始停产&#xff0c;现在用新型号FR-E840-0120-4-60替换。 FR-E840-0120-4-60参数说明&…

2024年前端技术发展趋势

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

anaconda安装python 3.8环境

打开anaconda命令行窗口 在命令行窗口中&#xff0c;输入命令&#xff1a;conda create -n py38 python3.8 执行命令后&#xff0c;显示conda版本、安装路径和安装的包 然后提醒是否安装&#xff0c;输入y 等待安装完成。然后进入python3.8&#xff0c;执行命令&#xff1a;con…

全网最全的平行坐标图(parallel coordinates plot)的绘制攻略

早上起来拥抱太阳&#xff0c;写小论文&#xff0c;看到人家的图怎么那么好看&#xff01;&#xff01;&#xff1f;&#xff1f; 这不得赶紧抄下来&#xff0c;我也发一个顶刊&#xff1f;于是开始思考如何解决绘制这个问题&#xff0c;目前现有的大部分解决方案都是直接调库…

【计算机毕业设计】理发店管理系统产品功能说明——后附源码

&#x1f389;**欢迎来到我的技术世界&#xff01;**&#x1f389; &#x1f4d8; 博主小档案&#xff1a; 一名来自世界500强的资深程序媛&#xff0c;毕业于国内知名985高校。 &#x1f527; 技术专长&#xff1a; 在深度学习任务中展现出卓越的能力&#xff0c;包括但不限于…

Python Selenium无法打开Chrome浏览器处理自定义浏览器路径

问题 在使用Python Selenium控制Chrome浏览器操作的过程中&#xff0c;由于安装的Chrome浏览器的版本找不到对应版本的驱动chromedriver.exe文件&#xff0c;下载了小几个版本号的驱动软件。发现运行下面的代码是无法正常使用的&#xff1a; from selenium import webdriver …

HWOD:合并整型数组

一、知识点 合并整型数组目前有两种方法 合并数组并不一定需要真正的合并 1、下意识的方法 对两个整型数组分别排序&#xff0c;然后合并 2、不排序的方法 遍历两个数组&#xff0c;找出最小值&#xff0c;输出最小值。将两个数组中与最小值相等的位置置为超大值 重复以…

二叉树oj题(2)

1.二叉树的最近公共祖先 解题思路&#xff1a;方法一&#xff1a; 1.先判断p或者q 是不是 root当中的一个 2.左子树当中递归査找p或者q 3.右子树当中递归查找p或者q 如何查找: root 的 left 和 right 都不为空 ->root root的 left 为空 right 不为空->right这一侧找…

终于有人说明白了session、cookie和token的区别

一、首先介绍一下名词&#xff1a;Session、cookie、token&#xff0c;如下&#xff1a; 1.Session会话&#xff1a;客户端A访问服务器&#xff0c;服务器存储A的数据value&#xff0c;把key返回给客户端A&#xff0c;客户端A下次带着key&#xff08;session ID&#xff09;来…

ROS轻松入门(一)—— 基本概念:node节点、topic通信、service通信

node节点 ROS 中的每个节点都应该负责单一的、模块化的目的&#xff0c;例如控制车轮马达或发布来自激光测距仪的传感器数据。每个节点都可以通过主题、服务、操作或参数从其他节点发送和接收数据。 一个完整的机器人系统由许多协同工作的节点组成。在 ROS 2 中&#xff0c;单…

【java配置】jpcap的下载与idea配置

解决报错&#xff1a;Cannot resolve symbol ‘jpcap’ 1. jpcap的下载 官网下载链接 百度网盘下载 双击WinpPca安装&#xff0c;jacap1和jpcap2任选其中之一 2. idea配置 &#xff08;1&#xff09;查看当前使用jdk目录 File -> Project Settings -> SDKs &#…

STM32H750时钟频率和功耗以及RTC功能测试

STM32H750时钟频率和功耗和RTC功能测试 &#x1f4cc;相关篇《STM32H750片外QSPI启动配置简要》 ✨在使用STM32CubeMX修改STM32H750时钟树参数时&#xff0c;如果使用软件自动求解&#xff0c;这是一个非常耗时的操作&#xff0c;有时候还不一定成功&#xff0c;还是推荐使用手…

2024成都直播电商硝烟再起,天府锋巢AI 时代拉开帷幕

在今年1月份的“AI重构电商”生态大会上&#xff0c;百度借力AI数字人直播和文心大模型能力杀入电商场内&#xff0c;强调“AI重塑电商”。成都兴隆湖畔&#xff0c;天府锋巢直播产业基地计划开展高质量、低成本、互动性更强的虚拟数字人直播&#xff0c;为直播行业注入新的活力…

低代码技术与仓储管理的新纪元:革命性的供应链变革

引言 在当今数字化时代&#xff0c;企业对于创新和效率的追求越发迫切。在这样的背景下&#xff0c;低代码技术应运而生&#xff0c;成为企业数字化转型的重要工具之一。低代码技术的崛起为企业提供了一种快速、灵活、成本效益高的开发方式&#xff0c;大大缩短了软件开发周期…

2024五一劳动节市集露营生活节活动策划方案

2024五一劳动节市集露营生活节&#xff08;向野而生 躺平生活节主题&#xff09;活动策划方案 方案页码&#xff1a;72页 文件格式&#xff1a;pptx 方案简介&#xff1a; 五一躺平生活节 咖啡一饮&#xff0c;书本一翻&#xff0c;轻松又自在,看着窗外的阳光&#xff0c;…

4.23日总结(项目总结)

1.项目&#xff1a; 今日项目通过一个在登录界面的一个静态变量&#xff0c;完成了区分老师和学生&#xff0c;能够分开老师和学生&#xff0c;并且不同身份的人进去会有不同的显示&#xff0c;以及登录链接主界面&#xff0c;还有学生和老师的不同的表&#xff0c;其次就是创…