【QT开发(6)】0926-QT 中加入 fastDDS 通信库的程序使用说明

在智能驾驶中,DDS有可能被广泛使用,因此推出这篇说明教程。

1、基于【QT开发(5)】教程的项目文档进行开发

2、安装DDS

查看《【eProsima Fast DDS(1)】安装eProsima Fast DDS》

至少安装:

foonathan_memory_vendor,一个 STL 兼容的 C++ 内存分配器 库。
fastcdr,一个根据 CDR 标准进行数据序列化的 C++ 库。
fastrtps,eProsima Fast DDS库的核心库。

测试安装是否正确的方法:在cmakelists 中加入

find_package(fastcdr REQUIRED)
find_package(foonathan_memory REQUIRED)
find_package(fastrtps REQUIRED)

如果cmake 提示找到了该库,则表示库ok。

3、在项目中添加通信message文件

我们一般是先写 DDS 的idl 文件(本质是定义定义数据结构体类型),然后通过DDS的代码生成工具生成 cpp 和hpp文件。如下图:
在这里插入图片描述

因为我们使用的【QT开发(5)】教程的项目文档进行开发,哪个项目直接遍历src 目录里面全部的cpp和hpp文件。因此我们把message 复制进入src目录即可,不用变更cmakelists

例如我们定义两个数据结构体PerceptionCommand 和WorkingStatus

module auto_msg {module msg {struct PerceptionCommand {uint64 time_stamp;uint8 system_command;uint8 system_reset;};};
};

module auto_msg {module msg {struct WorkingStatus {uint64 time_stamp;uint32 counter;};};
};

4、为了保持ROS2 代码的风格兼容,我们导入了rclcpp

目的:移植rclcpp 的publisher、subscription、和timer

因为我们使用的【QT开发(5)】教程的项目文档进行开发,哪个项目直接遍历src 目录里面全部的cpp和hpp文件。因此我们把rclcpp复制进入src目录即可,不用变更cmakelists

5、修改cmakelists 增加fastrtps

增加

find_package(fastcdr REQUIRED)
find_package(foonathan_memory REQUIRED)
find_package(fastrtps REQUIRED)

修改target_link_libraries ,增加fastrtps

    target_link_libraries( emptyApp fmtQt5::Widgets${OpenCV_LIBS}fastrtpspthread)

因为我们使用的【QT开发(5)】教程的项目文档进行开发,哪个项目直接遍历src 目录里面全部的cpp和hpp文件。因此我们把message 、rclcpp复制进入src目录即可,不用变更cmakelists

6、增加一个基于DDS 通信的核心功能

我们建立一个example文件夹,建立example.cpp 和 example.hpp

先写 example.hpp,首先引入头文件

#include <rclcpp/rclcpp.hpp>
#include <PerceptionCommand.hpp>  // 这个是message 里面定义的 dds 通信数据结构体
#include <WorkingStatus.hpp>    // 这个是message 里面定义的 dds 通信数据结构体

然后建立一个对象Example class

class Example : public rclcpp::Node
{public:Example();~Example();int Init();private:// 1# 订阅者rclcpp::Subscription<auto_msg::msg::PerceptionCommand>::SharedPtr perceptionCommand_sub_;// 2#  信息存储的成员rclcpp::AtomicSet<auto_msg::msg::PerceptionCommand> perceptionCommand_;// 3#建立 订阅者的回调函数 msg_PerceptionCommand_callback,实现的数据存放在perceptionCommand_成员void msg_PerceptionCommand_callback(const auto_msg::msg::PerceptionCommand::SharedPtr msg);// 4# 建立一个50ms 的定时器rclcpp::TimerBase::SharedPtr workingStatus_timer_;// 5# 建立发布者 Publisherrclcpp::Publisher<auto_msg::msg::WorkingStatus>::SharedPtr workingStatus_pub_;rclcpp::AtomicSet<auto_msg::msg::WorkingStatus> workingStatus_;// 6# 定时器的回调函数void timer_WorkingStatus_callback();};

我们建立了6个函数,分别的作用是
1、建立一个 perceptionCommand_sub_ 订阅者
2、建立一个 perceptionCommand_ 的信息存储的成员
3、建立 订阅者的回调函数 msg_PerceptionCommand_callback,实现把收到的数据存放在 perceptionCommand_ 的信息存储的成员里面
4、建立一个50ms 的定时器
5、建立一个 workingStatus_pub_ 的发布者;4、建立一个 workingStatus_ 成员
6、建立一个 定时器的回调函数,处理perceptionCommand_ 成员的数据,并发送workingStatus_pub_ 数据。

example.cpp 里面这么写

int Example::Init()
{counter_ = 0;workingStatus_pub_ = this->create_publisher<auto_msg::msg::WorkingStatus>("example_status_pub",2);perceptionCommand_sub_ = this->create_subscription<auto_msg::msg::PerceptionCommand>("perception_command_pub",2,std::bind(&Example::msg_PerceptionCommand_callback, this, _1));workingStatus_timer_ = this->create_wall_timer(50, std::bind(&Example::timer_WorkingStatus_callback, this)); // 50 millisecondreturn 0;
}void Example::timer_WorkingStatus_callback()
{// here is how use the msg which had receivedauto_msg::msg::PerceptionCommand perceptionCommand = perceptionCommand_.Get();if (perceptionCommand.system_command() == 0x06) {// for example, do sth what you want when command equal some valueint a = 1;}auto_msg::msg::WorkingStatus workingStatus;workingStatus.time_stamp() = rclcpp::PlatformGetMs();workingStatus_pub_->publish(workingStatus);
}void Example::msg_PerceptionCommand_callback(const auto_msg::msg::PerceptionCommand::SharedPtr msg)
{perceptionCommand_.Set(*msg);
}

7、修改main 文件

增加头文件引用

#include <rclcpp/rclcpp.hpp>
#include "example.h"

main 函数里面加入

        rclcpp::init(argc, argv);std::shared_ptr<yanyx::auto::Example> example = std::make_shared<yanyx::auto::Example>();example->Init();rclcpp::spin(example);

关于 rclcpp::spin() 的说明可以看我的另外一篇文章《【eProsima Fast DDS(2)】ROS2:spin() spin_some()函数》,这个是堵塞了main 函数。

整体上处理的思路是:

1、建立一个 perceptionCommand_sub_ 订阅者
2、建立一个 perceptionCommand_ 的信息存储的成员
3、建立 订阅者的回调函数 msg_PerceptionCommand_callback,实现把收到的数据存放在 perceptionCommand_ 的信息存储的成员里面
4、建立一个50ms 的定时器
5、建立一个 workingStatus_pub_ 的发布者;4、建立一个 workingStatus_ 成员
6、建立一个 定时器的回调函数,处理perceptionCommand_ 成员的数据,并发送workingStatus_pub_ 数据。

建立一个订阅者
建立一个存储成员
订阅者的回调函数把收到的数据存放在成员
建立一个50ms 的定时器
建立发布者
定时器回调>处理存储的数据>并调用发布者发数据

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode每日一题:2136. 全部开花的最早一天(2023.9.30 C++)

目录 2136. 全部开花的最早一天 题目描述&#xff1a; 实现代码与解析&#xff1a; 贪心 原理思路&#xff1a; 2136. 全部开花的最早一天 题目描述&#xff1a; 你有 n 枚花的种子。每枚种子必须先种下&#xff0c;才能开始生长、开花。播种需要时间&#xff0c;种子的生…

Java八股文

JAVA八股文 这里写目录标题 **JAVA八股文**面向对象三大特征接口与抽象类的区别重载与重写与equals异常处理机制HashMap原理红黑树乐观锁和悲观锁HashTable与HashMap的区别ArrayList和LinkedList的区别如何保证ArrayList的线程安全什么是线程上下文切换sleep()和wait()的区别yi…

Nginx简介与Docker Compose部署指南

Nginx是一款高性能的开源Web服务器和反向代理服务器&#xff0c;以其卓越的性能、可伸缩性和灵活性而闻名。它在全球范围内广泛用于托管Web应用程序、负载均衡、反向代理和更多场景中。在本文中&#xff0c;我们将首先介绍Nginx的基本概念&#xff0c;然后演示如何使用Docker C…

stm32 - GPIO

stm32 - GPIO GPIO结构图GPIO原理图输入上拉/下拉/浮空施密特触发器片上外设 输出推挽/开漏/关闭输出方式 GPIO88种模式复用输出 GPIO寄存器端口配置寄存器_CRL端口输入数据寄存器_IDR端口输出数据寄存器_ODR端口位设置/清除寄存器_BSRR端口位清除寄存器_BRR端口配置锁定寄存器…

Window 安装多个版本的 java 并按需切换

1、按需下载对应版本的 java 官网链接&#xff1a;Java Downloads | Oracle 2、执行安装程序&#xff0c;根据安装向导一步一步走就行&#xff0c;每个版本安装在不同的目录下。 3、配置环境变量 a&#xff09;为每个版本 java 新建不同名称的 JAVA_HOME 系统变量&#xff0…

【Java 进阶篇】JDBC插入数据详解

在Java应用程序中&#xff0c;与数据库交互是一项常见的任务。其中&#xff0c;插入数据操作是一种基本的数据库操作之一。本文将详细介绍如何使用Java JDBC&#xff08;Java Database Connectivity&#xff09;来执行插入数据操作。无论您是初学者还是有一定经验的开发人员&am…

数仓精品理论-做大数据还有没有前途?

数仓精品理论-做大数据还有没有前途&#xff1f; 做大数据还有没有前途&#xff1f;大数据三要三不要我来讲讲大数据前景 做大数据还有没有前途&#xff1f; 先说&#xff0c;答案是肯定的&#xff0c;但一定要记住三要三不要。 datapulse官网&#xff1a; github:https://data…

LeetCode 热题 HOT 100:回溯专题

LeetCode 热题 HOT 100&#xff1a;https://leetcode.cn/problem-list/2cktkvj/ 文章目录 17. 电话号码的字母组合22. 括号生成39. 组合总和46. 全排列补充&#xff1a;47. 全排列 II &#xff08;待优化)78. 子集79. 单词搜索124. 二叉树中的最大路径和200. 岛屿数量437. 路径…

手机电脑数码小程序商城的作用是什么

手机几乎是每个成年人人手一个以上&#xff0c;市场非常大&#xff0c;加之产品更新迭代速度快&#xff0c;每年都会推出多个型号、造型等&#xff0c;因此对高收入群体或爱机人群来说&#xff0c;新手机往往一年或二年时间就会换&#xff0c;或者直接购买当备用机等。 每个城…

关于解决 unable to start ssh-agent service, error :1058

前言 操作系统&#xff1a;win11 命令终端&#xff1a;Powershell 当我在终端输入命令 启动 ssh-agent 代理的时候 ssh-agent -s 很不幸出现了 unable to start ssh-agent service, error :1058以下错误 问题的解决 查看我们ssh-agent 服务是否运行&#xff0c;执行如下命令…

快看看你的手机有没有:谷歌Android全面封杀此类软件!

谷歌坐不住了&#xff0c;因为Android应用商店中&#xff0c;充斥着大量可窃取用户数据的应用&#xff0c;所以必然要出手整治了。 一款名叫“SonicSpy”软件是整个事情的导火索&#xff0c;而该应用是典型的窃取用户数据的应用&#xff0c;其除了可以从手机中提取个人数据外&…

C++ 学习系列 -- std::stack 与 std::queue

一 std::stack 与 std::queue 分别是什么&#xff1f; 两者均是 c 中的序列化容器&#xff0c;区别在于&#xff1a; std::stack 元素是先进后出 std::queue 元素是先进先出 二 std::stack 与 std::queue 原理 1 std:statck 2. std::queue 两者底层容器可以是 list 也可以…

黑豹程序员-架构师学习路线图-百科:HTML-网页三剑客

为什么需要HTML 在网站技术发达之前&#xff0c;千年来我们获取信息是通过书籍。电脑流行后我们看文章、小说通过txt文件。看图通过单独的图片流量工具看单个的图片文件。 而HTML把文字和图片一起展示&#xff0c;让今天的电子书成为可能。 另外一点&#xff0c;我们的信息是…

蜂蜜配送销售商城小程序的作用是什么

蜂蜜是农产品中重要的一个类目&#xff0c;其受众之广市场需求量大&#xff0c;但由于非人人必需品&#xff0c;因此传统线下门店经营也面临着痛点&#xff0c;线上入驻平台也有很多限制难以打造自有品牌&#xff0c;无法管理销售商品及会员、营销等&#xff0c;缺少自营渠道&a…

Linux常见操作命令(1)

​ 前言&#xff1a;作者也是初学Linux&#xff0c;可能总结的还不是很到位 ♈️今日夜电波&#xff1a;达尔文—林俊杰 0:30━━━━━━️&#x1f49f;──────── 4:06 &#x1f504; ◀️ …

集合在多线程下安全问题

如果在多线程下&#xff0c;同时操作同一个数据源&#xff0c;就会出现数据安全问题&#xff1a; A线程取出值为10&#xff0c;准备加5. 同时B线程也取出来10&#xff0c;减了5 C取出的时候有可能时15&#xff0c;也有可能时5。产生了数据安全问题。 方法有很多例如&#xff1a…

Acwing 143. 最大异或对

Acwing 143. 最大异或对 题目描述思路讲解代码展示 题目描述 思路讲解 这道题的启示是&#xff1a;字典树不单单可以高效存储和查找字符串集合,还可以存储二进制数字 思路:将每个数以二进制方式存入字典树,找的时候从最高位去找有无该位的异. 代码展示 #include<iostream…

uboot启动流程-涉及_main汇编函数

一. uboot启动流程涉及函数 本文简单分析一下 save_boot_params_ret调用的函数&#xff1a;_main汇编函数。 本文继之前文章的学习&#xff0c;地址如下&#xff1a; uboot启动流程-涉及s_init汇编函数_凌肖战的博客-CSDN博客 二. uboot启动流程涉及的 _main汇编函数 经过之…

鞋类 整鞋试验方法 剥离强度

声明 本文是学习GB-T 3903.3-2011 鞋类 整鞋试验方法 剥离强度. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 GB/T 3903 的本部分规定了整鞋鞋底与鞋帮或外底与外中底之间剥离强度的试验方法。 本部分适用于采用模压、硫化、注塑、灌注、胶…

Springboot对MVC、tomcat扩展配置

Springboot在web层的开发基本都是采用Springmvc框架技术&#xff0c;但是Springmvc中的某些配置在boot是没有的&#xff0c;我们就应该根据自己的需求进行对mvc扩展配置 Springboot1.x版本如何配置 通过注解Configuration一个类&#xff0c;继承webmvcconfigureradapter&#…