代码改变世界

详细介绍:opendds初入门之安装环境后初步探索

2025-09-29 21:06  tlnshuju  阅读(6)  评论(0)    收藏  举报

本文的目的是安装opendds后,初步探索,结合了解源码目录,运行测试demo对opendds进行初步了解。

1:梳理当前情况

有关项目核心模块,当前只是基于opendds的最简单的方案实现。

1:需要了解opendds的发布订阅机制(运行测试demo)。
2:需要了解opendds的参数加载和配置文件相关参数细节(ini配置文件参数)。

扩展:首先基于opendds实现一个最简单的发布订阅的demo,基于集中模式和非集中模式的差异是什么。

2:考虑网络架构。

思考

我们对opendds的使用只是作为基本的组件来进行使用,核心需要考虑网络的复杂性。
===》基于传统的tcp/ip交互能力进行上层封装,实现发布订阅,提供网络支撑。
===》考虑复杂网络场景,比如多个局域网内部进行交互的方案设计。

思考复杂网络,如多局域网交互

1.非集中模式:(公网:静态配置路由/端口映射+tcp),(rtps 中继),(VPN),(是否考虑在opendds中静态配置+公网映射实现)

2.集中模式:repo+vpn/repo+stun和tun/repo+手动映射+配置文件+RTPS/TCP

repo是基于corba,CORBA 是一种基于对象的 RPC 架构。

3:基于网络+当前进行思考。

我们的目标:提供so接口的方式,供上层组件使用(可扩展考虑一下插件的方式),提供基于特定业务的网络交互能力。
===》这里的业务交互能力主要依赖于opendds的发布订阅。
===》考虑系统所能支持的QPS需要进行测试。
===》基于组件的发布和订阅,考虑节点监控的支持。
===》基于组件的发布和订阅之后,考虑qos的支持。
===》基于组件的发布和订阅之后,考虑按需要进行订阅和过滤的支持。
===》基于组件的发布和订阅之后,考虑航位推算的设计。

4:技术探索

4.1 首先对源码目录和架构进行简单了解。

DCPS(Data-Centric Publish-Subscribe)是OpenDDS的核心实现目录,包含DDS规范的主要功能:
DCPS/transport 子目录,传输层框架和各种传输实现:
	framework/ - 传输框架的基础设施
	tcp/ - TCP传输实现
	rtps_udp/ - RTPS/UDP传输实现
	udp/ - UDP传输实现
	multicast/ - 多播传输实现
	shmem/ - 共享内存传输实现
DCPS/RTPS子目录
    RTPS(Real-time Publish-Subscribe)协议的实现。
DCPS/XTypes子目录:DDS XTypes规范的实现,支持动态类型,是opendds中的“类型解释器 + 类型兼容器”。
DCPS/security子目录:DDS安全规范的实现。
其他重要目录
idl目录:IDL编译器相关代码。
InfoRepo目录:信息仓库发现机制的实现。
monitor目录:监控功能的实现。

首先用https://deepwiki.com/看看代码的核心架构:

在这里插入图片描述

看看数据流:

在这里插入图片描述

看看对传输层的注册使用流:

在这里插入图片描述

4.2 实现基于opendds的发布订阅逻辑,集中式和非集中式测试。

===》基于最简单的非集中模式的发布订阅进行测试,

首先查看开源库中自带的测试代码,

如果你是初学者或跟随官方指南学习,选择 DevGuideExamples:它更易懂、文档化强,但测试简单。

如果你需要高级应用或自动化验证,选择 examples:它更灵活、测试 robust,但学习曲线稍陡。

====》DevGuideExamples下的测试demo,支持集中模式和非集中模式(最简单的demo,直接运行对应的run_test.pl看效果,分别演示了最简单的发布订阅,封装后的发布订阅,以及支持零拷贝的发布订阅)。

====》简单梳理发布和订阅的逻辑,底层的发布写数据和监听读数据,都是通过底层一个线程专门调用reactor机制进行处理的。(基于reactor可以单线程,支持配置线程池。)

====》支持单拷贝和零拷贝(零拷贝是函数内部实现的,在on_data_available接口内部处理读数据时,take函数支持零拷贝,需要给入参强制为0)

//take函数支持零拷贝的接口实现如下
// 方法1:显式 max_len = 0
Messenger::MessageSeq messages(0);  // 强制零拷贝模式
DDS::SampleInfoSeq info(0);         // 强制零拷贝模式
// 方法2:使用 reserve(0)
messages.reserve(0);  // 确保零拷贝
info.reserve(0);
// 然后 take()
reader_i->take(messages, info, DDS::LENGTH_UNLIMITED, ...);

4.3 ishapes的理解

首先运行,发现是一个带ui界面的,支持qos配置,支持过滤配置,以不同图形进行展示发布订阅交互逻辑的demo。

在这里插入图片描述

分析源码,对支持qos的加载和过滤支持进行理解。

====》qos的支持需要在发布或者订阅前进行配置,创建DataReader或者DataWriter时使用。

====》filter是订阅端使用的,设置后点击sub才会真正过滤。

====》分析源码后发现,该demo也用到一定的架构设计,模块划分清晰,值得思考一下。

4.4 其他测试

opendds的集中模式需要启动一个inforepo服务,底层实际上是corba进行交互的。

===》inforepo崩溃会导致数据丢失的,imr是opendds提供的一个自动拉起inforepo的服务机制,参考examples/DCPS/Messenger_Imr (首先启动imr服务,ior服务启动时加入)

===》基于imr的机制,可以配置多个inforepo,opendds提供支持客户端使用IOGR选择多个ior中的一个,参考examples/DCPS/Messenger_IOGR_Imr (iogr管理了一组ior,保证了外部连接无感知,但是各ior数据没有同步)

=======》总结:imr和iogr是opendds提供对inforepo的可靠保障,imr保障inforepo的自动重启,iogr是对ior的一个简单集群方案(只是解决了连接容错问题,内部各ior数据没有同步)。

5:报错梳理(ORBEndpoint参数localhost时节点报异常)

在梳理测试demo时,遇到一个报错,如下:

#example下的DistributedContent实现的是过滤自己节点消息的功能
OpenDDS\examples\DCPS\DistributedContent\Release>perl run_test.pl
>>> C:\Users\LEGION\Desktop\opendds_study\OpenDDS\bin\.\DCPSInfoRepo.EXE -ORBEndpoint iiop://:23520
[INFO] ORB_init() 成功
[INFO] RootPOA resolved 成功
infoRepo has run start..\.\node.EXE   -n node_1 -d files1 -DCPSInfoRepo corbaloc:iiop:localhost:23520/DCPSInfoRepo
.\.\node.EXE   -n node_2 -d files2 -DCPSInfoRepo corbaloc:iiop:localhost:23520/DCPSInfoRepo
.\.\node.EXE   -n node_3 -d files3 -f starter.bin -DCPSInfoRepo corbaloc:iiop:localhost:23520/DCPSInfoRepo
(25872|22020) EXCEPTION, ERROR: InfoRepoDiscovery::get_dcps_info: failed to resolve ior -
system exception, ID 'IDL:omg.org/CORBA/TRANSIENT:1.0'
OMG minor code (2), described as '*unknown description*', completed = NO
ERROR - Create participant failed.
ERROR: Initialization of DDS failed!
usage: -d <file directory>  -n <node name>  -f <start file name>
  ERROR: InfoRepoDiscovery::~InfoRepoDiscovery - Exception caught during ORB shutdown: system exception, ID 'IDL:omg.org/CORBA/BAD_INV_ORDER:1.0'
  OMG minor code (4), described as '*unknown description*', completed = NO
  ...

其中看到是初始化的时候无法创建 participant:system exception, ID ‘IDL:omg.org/CORBA/TRANSIENT:1.0’
OMG minor code (2), described as ‘unknown description’, completed = NO

最终解决如下,是因为localhost和回环地址相关原因,需要明确具体的网卡ip:

 C:\Users\LEGION\Desktop\opendds_study\OpenDDS\bin\.\DCPSInfoRepo.EXE -ORBEndpoint iiop://192.168.1.161:12345 -DCPSDebugLevel 5 -ORBDebugLevel 5 -ORBVerboseLogging 1
node.EXE -n node_2 -d files2 -DCPSDomainID 43 -DCPSInfoRepo "corbaloc:iiop:192.168.1.161:12345/DCPSInfoRepo" -DCPSDebugLevel 10

IntroductionToOpenDDS 就是一个加载tcp/udp配置文件的方式,验证同时发布多个topic进行交互的demo。

ishapes是一个带界面的发布订阅的demo,代码中支持加载transport,命令行解析,安全证书,

====》注意TheServiceParticipant 全局单例服务管理器,内部DomainParticipantFactory_varDomainParticipant_var(DDS 应用的入口点,管理 Publisher、Subscriber、Topic 等子实体) 是其管理的核心组件,

6:总结

ishapes测试源码中可以看出,DataReader读数据不止可以用listener,也可以专门的线程一致试着读数据(ShapeTypeDataReader_var去读)。

在这里插入图片描述