fastdds:编译、安装并运行helloworld

fastdds安装可以参考官方文档:

3. Linux installation from sources — Fast DDS 3.1.0 documentation

从INSTALLATION MANUAL这一节可以看出来,fastdds支持的操作系统包括linux、windows、qnx、MAC OS。本文记录通过源码和cmake的方式来安装fastdds的过程,也就是3.1.4节的安装过程:

1安装步骤

使用源码和cmake安装fastdds之前,需要先安装一些依赖,可以参考requirements和dependencies两节来安装。

camke、g++、pip3、wget、git这是常用一些工具
asioasynchronous io,异步io库。fastdds作为一个通信中间件,底层的通信就是基于asio实现的
tinyxml2fastdds的配置文件格式为xml,tinyxml2用来解析xml文件
openssl用于加密

1、在家目录下创建一个文件夹

2、安装foonathan memory和fast cdr

foonathan memory提供内存管理功能,fast cdr提供序列化和反序列化。

CMAKE_INSTALL_PREFIX指定安装目录的前缀,如下的install指令,把xxx安装在lib目录下,实际的安装目录会在lib前加上前缀,以上边的命令为例,xxx实际会被安装到~/Fast-DDS/install/lib目录下。

install(TARGETS xxx DESTINATION lib)

3、安装fastdds

如果我们安装fastdds是为了学习或者调试,那么可以编译debug版本,也就是CMAKE_BUILD_TYPE=Debug;需要编译examples,则需要将examples打开,也就是COMPILE_EXAMPLES=ON。

cmake .. -DCMAKE_INSTALL_PREFIX=~/Fast-DDS/install -DCOMPILE_EXAMPLES=ON -DCMAKE_BUILD_TYPE=Debug

2helloworld

2.1fastdds应用的组成

helloworld是fastdds一个最简单的应用,一个fasttdds的应用往往包括以下几个部分:

 topic:话题

topic也表示一个通道,表示reader和writer之间通信的通道,类似于我们的手机号、微信号、抖音号。topic需要在一个domain内保持唯一。topic在实际使用中用一个字符串来表示。helloword中使用的topic是hello_world_topic。

idl:interface definition language

helloworld的idl定义如下,可以看到,很像我们使用c/c++编程的时候使用的结构体。在具体使用的时候,idl不能直接用,要先使用fastddsgen工具将idl生成.h文件和.cpp。

idl定义了通信的数据内容,是writer和reader之间的通信的内容。

fastddsgen是用java开发的工具,用于将idl文件生成编程语言可以使用的格式。fastddsgen的安装说明如下:

3. Linux installation from sources — Fast DDS 3.1.0 documentation

如下是使用fastddsgen将HelloWorld.idl生成了.hpp,.cxx等文件

Publisher和Subscriber:

Publisher发布数据,Subscriber订阅数据。

xml

xml是fastdds应用使用的配置文件。xml中可以配置使用哪些传输层、qos配置、domain id配置、白名单配置等。如果想要使用配置文件,那么需要设置环境变量FASTDDS_DEFAULT_PROFILES_FILE。

<?xml version="1.0" encoding="UTF-8" ?>
<profiles xmlns="http://www.eprosima.com" ><participant profile_name="hello_world_participant_profile" is_default_profile="true"><domainId>0</domainId><rtps><name>hello_world_participant</name></rtps></participant><data_writer profile_name="hello_world_datawriter_profile" is_default_profile="true"><qos><durability><kind>TRANSIENT_LOCAL</kind></durability><reliability><kind>RELIABLE</kind></reliability></qos><topic><historyQos><kind>KEEP_LAST</kind><depth>100</depth></historyQos><resourceLimitsQos><max_samples>100</max_samples><max_instances>1</max_instances><max_samples_per_instance>100</max_samples_per_instance></resourceLimitsQos></topic></data_writer><data_reader profile_name="hello_world_datareader_profile" is_default_profile="true"><qos><durability><kind>TRANSIENT_LOCAL</kind></durability><reliability><kind>RELIABLE</kind></reliability></qos><topic><historyQos><kind>KEEP_LAST</kind><depth>100</depth></historyQos><resourceLimitsQos><max_samples>100</max_samples><max_instances>1</max_instances><max_samples_per_instance>100</max_samples_per_instance></resourceLimitsQos></topic></data_reader>
</profiles>

topic定义了通信的通道,类似于手机号

idl定义了数据内容,类似于打电话的双方之间通话的内容

Publisher和Subsciber是通信的双方

2.2ListenerSubscriber和WaitsetSubscriber

数据的订阅侧有两种实现方式:

ListenerSubscriber1、使用简单,继承fastdds提供的基类

DataReaderListener,实现其中的接口on_subscription_matched、on_data_available,当有publisher和这个subscriber匹配的时候,on_subscription_matched会被调用;当有新的订阅数据到来的时候,on_data_available会被调用。

2、不够灵活,函数on_subscription_matched、on_data_available在哪个线程中调用,线程的调度参数是怎么配置的,一个Subscriber使用一个线程,还是多个Subscriber使用同一个线程,我们不能控制。

WaitsetSubsriber

1、不需要继承fastdds提供的基类,使用灵活,subscriber运行在哪个线程中,线程的调度参数怎么配置,我们可以灵活的进行配置。

2、不如ListenerSubscriber使用简单

如下是helloworld中使用waitset的代码,waitset的使用分为如下3步:

①attach_condition,指定waitset关心哪些条件

②wait,等待条件到来

③使用一个for循环来遍历条件,在for循环中根据条件的类型进行对应的处理

看到这里,如果我们用过epoll的话,可以看到waitset的使用方式和epoll的使用方式是类似的,epoll的使用也可以分为如下3步:

①epoll_ctl,添加关心的事件

②epoll_wait,等待事件到来

③for循环处理事件,根据事件类型做对应处理

wait_set_.attach_condition(reader_->get_statuscondition());
wait_set_.attach_condition(terminate_condition_);void WaitsetSubscriberApp::run()
{while (!is_stopped()){ReturnCode_t ret_code = wait_set_.wait(triggered_conditions, eprosima::fastdds::dds::c_TimeInfinite);if (RETCODE_OK != ret_code){EPROSIMA_LOG_ERROR(SUBSCRIBER_WAITSET, "Error waiting for conditions");continue;}for (Condition* cond : triggered_conditions){StatusCondition* status_cond = dynamic_cast<StatusCondition*>(cond);if (nullptr != status_cond){Entity* entity = status_cond->get_entity();StatusMask changed_statuses = entity->get_status_changes();if (changed_statuses.is_active(StatusMask::subscription_matched())){...}if (changed_statuses.is_active(StatusMask::data_available())){...   }}}}
}

2.3Publisher/Subscriber创建步骤

从helloworld的代码来看,创建Publisher和Subscriber的步骤是类似的:

①创建participant

②创建publisher或subscriber

③创建topic

④创建writer/reader

domain

域,domain是fastdds中一个范围最大的概念,一个domain用一个domain id来区分,只有同一个domain内的参与者才可以通信,不同参与者之间的对象不能通信。这给业务隔离带来了方便,比如我们实际使用中,业务A和业务B之间不需要通信,那么就可以将业务A和业务B分别部署在两个domain内。

participant

参与者,一个domain内可以有多个参与者,一个参与者只能属于一个domain。

publisher/subscriber

一个participant可以创建多个publisher/subscriber。

writer/reader

一个publisher可以创建多个writer,一个subscriber可以创建多个reader。

idl定义的数据类型,也就是通信的内容,和topic是绑定的,在创建topic的时候,需要指定type,这里的type就是idl中定义的数据类型。

topic_ = participant_->create_topic(topic_name, type_.get_type_name(), topic_qos);

topic和writer/reader是绑定的,在创建writer/reader的时候需要指定topic:

writer_ = publisher_->create_datawriter(topic_, writer_qos, this, StatusMask::all());

qos,也就是服务质量,在创建publisher/subscriber、topic、writer/reader时均需要配置qos。

2.4运行helloworld

在两个终端分别启动subscriber和publisher,运行结果如下两张图所示。可以看出,当puhlisher和subscriber匹配的时候,会打印日志;当其中一方退出的时候,另一方也会打印unmatched日志。如果subscriber侧要使用waitset方式,可以执行./hello_world subscriber -w。

 

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

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

相关文章

mybatis:You have an error in your SQL syntax;

完整报错You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near false, false, false, false, false, false, false, false, false, false, false, at line 1 SQL: INSERT INTO user …

MappingJackson2HttpMessageConverter

MappingJackson2HttpMessageConverter 默认只支持 application/json 格式&#xff0c;&#xff0c;如果服务器返回的是text/plain不能转换 扩展一个可以转换text/plain的转换器&#xff1a; public class RestTemplateMessageConverter extends MappingJackson2HttpMessageCo…

7. 现代卷积神经网络

文章目录 7.1. 深度卷积神经网络&#xff08;AlexNet&#xff09;7.2. 使用块的网络&#xff08;VGG&#xff09;7.3. 网络中的网络&#xff08;NiN&#xff09;7.4. 含并行连结的网络&#xff08;GoogLeNet&#xff09;7.5. 批量规范化7.5.1. 训练深层网络7.5.2. 批量规范化层…

监控视频汇聚平台:Liveweb视频监控管理平台方案详细介绍

Liveweb国标视频综合管理平台是一款以视频为核心的智慧物联应用平台。它基于分布式、负载均衡等流媒体技术进行开发&#xff0c;提供广泛兼容、安全可靠、开放共享的视频综合服务。该平台具备多种功能&#xff0c;包括视频直播、录像、回放、检索、云存储、告警上报、语音对讲、…

常用函数的使用错题汇总

目录 new/delete malloc/free1. 语言和类型2. 内存分配3. 内存释放4. 安全性和类型安全5. 其他特性总结 线程停止文件流 new/delete malloc/free malloc/free 和 new/delete 是 C/C 中用于动态内存管理的两种方式&#xff0c;它们有一些重要的区别。以下是这两种方式的比较&…

Istio笔记01--快速体验Istio

Istio笔记01--快速体验Istio 介绍部署与测试部署k8s安装istio测试istio 注意事项说明 介绍 Istio是当前最热门的服务网格产品&#xff0c;已经被广泛应用于各个云厂商和IT互联网公司。企业可以基于Istio轻松构建服务网格&#xff0c;在接入过程中应用代码无需更改&#xff0c;…

ffmpeg RTP PS推流

要实现 CRtpSendPs 类&#xff0c;使其能够将 H264 数据通过 RTP PS 流推送到指定的 URL&#xff0c;并支持 TCP 和 UDP 传输方式&#xff0c;您需要使用 FFmpeg 库。以下是该类的实现示例&#xff0c;包括必要的初始化、推流和退出函数。 步骤 初始化 FFmpeg 库&#xff1a;…

爬取boss直聘上海市人工智能招聘信息+LDA主题建模

爬取boss直聘上海市人工智能招聘信息 import time import tqdm import random import requests import json import pandas as pd import os from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriv…

入门数据结构JAVADS——如何构建一棵简单二叉排序树

目录 前言 什么是二叉排序树 二叉排序树的特点 二叉排序树示意图 构建二叉排序树 插入元素 搜索元素 删除元素 完整代码 结尾 前言 在整个十一月,笔者因为一些原因停笔了,但马上迈入12月进而进入2025年,笔者决定不再偷懒了,继续更新以促进学习的积极性.闲话说到这,今天…

40分钟学 Go 语言高并发:GC原理与优化

GC原理与优化 一、GC基础知识概览 方面核心概念重要性优化目标GC算法三色标记法、并发GC⭐⭐⭐⭐⭐理解GC工作原理垃圾回收策略触发条件、回收步骤⭐⭐⭐⭐⭐掌握GC过程GC调优参数设置、性能监控⭐⭐⭐⭐优化GC效果内存管理内存分配、内存逃逸⭐⭐⭐⭐⭐减少内存压力 让我们…

梯度爆炸与消失

梯度爆炸和梯度消失 一、概念解析 &#xff08;一&#xff09;梯度爆炸 定义 在深度神经网络训练的反向传播过程中&#xff0c;梯度爆炸是指梯度的值过大的现象。这会使模型的参数更新出现异常。 产生原因 深层网络与链式法则&#xff1a;深度神经网络按链式法则计算某层权重…

linux 文件权限,修改权限,系统调用

参考chmod 777 到底是啥 ???看完这个你就完全懂了&#xff01;-CSDN博客 ls -l 查看当前目录文件的权限 会有一个十位的东西 分别为 d:这是一个文件夹 后面3*3位分别表示所有者用户&#xff0c;同组用户&#xff0c;其他用户的读(r)&#xff0c;写(w)&#xff0c;执行(x)…

notepad++文件github下载

1、github下载网址&#xff1a;Releases notepad-plus-plus/notepad-plus-plus GitHub 2、找到操作系统支持的软件&#xff1a; 3、CSDN下载链接&#xff1a;https://download.csdn.net/download/u013083576/90046203

【Spark源码分析】基于Spark3.4.2源码分析SparkSQL执行过程

基于Spark3.4.2源码分析SparkSQL执行过程 文章目录 基于Spark3.4.2源码分析SparkSQL执行过程基本执行流程Unresolved逻辑计划树相关类RuleExector相关类 详细代码SparkSessionAbstractSqlParserDatasetQueryExecutionAnalyzerRuleExecutorCheckAnalysis 附录CTE简述SQL解析器Qu…

PHP和GD库如何根据像素绘制图形

使用PHP和GD库&#xff0c;你可以根据像素绘制各种图形&#xff0c;比如点、线、矩形、圆形等。GD库是PHP的一个扩展&#xff0c;它提供了一系列用于创建和处理图像的函数。以下是一个简单的示例&#xff0c;展示如何使用GD库根据像素绘制图形。 安装GD库 首先&#xff0c;确…

kafka admin client 如何计算kafka发送速度

文章目录 方法 1&#xff1a;使用 AdminClient 获取消息数量示例代码&#xff1a;计算 Kafka 生产速度代码解释&#xff1a;解释&#xff1a;结果示例&#xff1a;方法 2&#xff1a;使用 Kafka JMX 监控JMX 指标&#xff1a; 总结&#xff1a; 要使用 Kafka Admin Client 来计…

【CSS in Depth 2 精译_064】10.3 CSS 中的容器查询相对单位 + 10.4 CSS 容器样式查询 + 10.5 本章小结

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 【第十章 CSS 容器查询】 ✔️ 10.1 容器查询的一个简单示例 10.1.1 容器尺寸查询的用法 10.2 深入理解容器 10.2.1 容器的类型10.2.2 容器的名称10.2.3 容器与模块化 CSS 10.3 与容器相关的单位 ✔…

适合写作中引用的名人名言 - 坚持与梦想 P1

概述 在写作中引用名人名言&#xff0c;有如下 3 大利 增强文章的权威性&#xff1a;名人名言往往是由历史上或当代具有广泛影响力的人物提出的&#xff0c;他们的言论经过时间的考验&#xff0c;是智慧的结晶 丰富文章内涵&#xff1a;名人名言往往言简意赅&#xff0c;蕴含…

TYUT设计模式精华版

七大原则 单一职责原则 职责要单一不能将太多的职责放在一个类中 开闭原则 软件实体对扩展是开放的&#xff0c;但对修改是关闭的 里氏代换原则 一个可以接受基类对象的地方必然可以接受子类 依赖倒转原则 要针对抽象层编程&#xff0c;而不要针对具体类编程 接口隔离原则 …

Java全栈:超市购物系统实现

项目介绍 本文将介绍如何使用Java全栈技术开发一个简单的超市购物系统。该系统包含以下主要功能: 商品管理用户管理购物车订单处理库存管理技术栈 后端 Spring Boot 2.7.0Spring SecurityMyBatis PlusMySQL 8.0Redis前端 Vue.js 3Element PlusAxiosVuex系统架构 整体架构 …