如何实现fastdds的topic调试工具

        在使用fastdds进行实际的开发调试中发现,常常需要对已经发布的话题进行进一步的调试,比如话题存在,话题内容,话题频率等等信息都需要确认,尤其是话题内容。这时候就需要一个能进行这项操作的调试工具。可能对于用过ros的同学来说,这很简单,因为ros、ros2提供的命令行调试调试工具就已经包含了该功能。那么fastdds作为ros2的底层支持是否直接支持了调试功能呢?如果想开发类似ros topic 的命令行的话题调试工具需要如何实现?

一、原生fastdds的支持情况

通过查看eProsima github和官网下载中心,可以确认eProsima提供了一系列的调试工具,其中包括:

monitor,用于查看已有实体和话题的归属图,构建话题发布的时序图

router,用于做网络路由方便远程网络进行dds组网

dds_py,用于对py开发者的python支持

结果是并没有一款直接可以用来查看话题内容的工具,那么我们是否可以直接依赖fastdds库开发一个类似工具呢?

实际上利用fastdds库现在无法实现话题内容调试的困难主要有两点,一是在接收到订阅的话题之后需要对应的反序列化文件去解析该话题实体,二是即使上层维护了对应的序列化文件,工具肯定是需要用户输入的参数来确认订阅的话题名称,这对C++这种编译时确定程序的语言来说是不可能实现。三是echo功能即便是订阅并反序列化话题内容后如何实现对所有idl里面struct的内容进行逐个打印。

二、ros2的ros2 topic功能是如何实现的

fastdds并没有提供直接的话题内容调试工具,那么既然ros2的底层是fastdds,ros2又是如何实现的呢?带着上面的几个问题去ros2_cli源码里面找一找答案。

ros2的cli是使用py开发的脚本命令行调试工具,下载cli代码进行初步分析,找到了我想要的功能 ros2 topic echo实现在ros2topic/verb/echo.py

如何实现fastdds的topic调试工具_第1张图片

主函数里面也是直接通过消息类型,话题名称,回调,qos创建话题订阅者,这和C++的创建订阅者的参数基本是一样的

 

如何实现fastdds的topic调试工具_第2张图片

实际上这里我们就已经注意到 message_type和topic_name已经完成了赋值,通过ros2 topic echo 命令,用户只输入了topic_name,message_type是一个根据topic_name确认的一个对应的序列化类的实体,那么message_type的类从哪里定义的?message_type是从哪里实例化的?

如何实现fastdds的topic调试工具_第3张图片

如何实现fastdds的topic调试工具_第4张图片

 

 通过查阅源码,get_msg_class->_get_msg_class->get_message->import_message_from_namespaced_type,我们发现import_message_from_namespaced_type最终通过import_module接口动态加载了话题对应的序列化库,并返回了对应的序列化类名,这就解决了第一和第二个问题。话题文件在编译的时候会生成对应的序列化库,而调试程序通过python的import_module动态的加载了对应的库。

那继续往下看,echo是如何知道话题内容结构中的属性和属性的类型的?这个问题我们肯定能想到是在收到消息后进行的,对应代码也就是订阅的回调函数

如何实现fastdds的topic调试工具_第5张图片

如何实现fastdds的topic调试工具_第6张图片

 通过查阅源码,_subscriber_callback->_print_yaml->message_to_yaml->message_to_ordereddict,我们发现message_to_ordereddict 将msg._slots_和msg.SLOT_TYPES的内容做了解析,将属性名和属性值映射到了一个字典,这样打印的时候直接打印字典的键和值就好了。

以Num的msg为例,全局搜索了一下_slots_字段,发现_slots_是存放的消息内容,而这部分实现是在Num.py,是ros2生成消息的产物。这就解决了第三个问题,消息在编译的时候不仅会生成对应的序列化库也会生成_slots_结构,用于字段解析;

如何实现fastdds的topic调试工具_第7张图片

 三、仿照ros2如何开发一个dds话题调试程序

通过第一二部分的了解,我们知道开发topic调试程序需要解决的问题对应应的措施如下:

1、通过idl生成序列化文件的同时生成一个py库(fastddsgen支持同时生成py辅助库)

2、生成序列化文件的同时生成一个存储idl结构的一个py结构,用于解析收到后的全结构解析

完成以上两点后,就可以基于py开发一个简单的topic调试程序,程序接收用户输入的参数话题名,通过话题名去匹配序列化类名,然后动态加载对应的库,创建订阅者,当收到消息后,在回调中做整个消息结构的解析和显示。 

        通过以上步骤基本能实现内容调试功能,但是由于工具是直接创建了对应的话题发布者,基于dds的发现策略,可能会有消息匹配的延迟。一个更好的补充是效仿ros2再开发一个中间件守护进程用于存储整个分布式系统的实体和话题地图,这样调试工具就可以直接从守护进程拿到对应消息的信息,进行静态发现,从而减少实体发现的时间。

 

你可能感兴趣的:(fastdds通信中间件,python,中间件,fastdds)