Skip to content

BrightSoulXYHY/dds_temple

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 

Repository files navigation

dds_temple

一个fast-dds开发的模版和例子

安装

简单易懂的DDS安装指南,参见官网。官网提供二进制安装但是注册帐号啥的巨麻烦,选择通过源码编译安装。

建议使用cmake安装,可能需要科学上网下载一些东西。

DDS上手

DDS通信的也是订阅发布的机制,底层没怎么研究,大概的流程是先创建一个话题,然后通过局域网自动match这个话题,match上了进行推送和订阅。

消息定义

fast-dds的消息格式定义后缀是idl,消息的语法定义参见官网的文档

C++的原生类型和一些STL都有实现

image-20220517190553559

并且可以在idl里面引用idl。比如定义下面一个这样的数据

//BBoxData.idl
struct BBoxData
{
    short id;

    string obj_class;
    int64 xmin;
    int64 ymin;
    int64 xmax;
    int64 ymax;

    float probability;

    // geometry_msgs/Point
    float pose_x;
    float pose_y;
    float pose_z;

};

然后定义一个BBoxData的列表可以这么弄

//BBoxesData.idl
#include "BBoxData.idl"

struct BBoxesData
{
    short system_ID;
	sequence<BBoxData> bounding_boxes;
};

消息生成

消息定义完成后就可以通过dds的命令行生成对应的cpp文件。运行下面的指令生成

fastddsgen dds_msg/*.idl -d dds_gen

一个idl文件大概会生成四个文件,比如BBoxData.idl会生成下面四个文件。

BBoxData.cxx
BBoxData.h
BBoxDataPubSubTypes.cxx
BBoxDataPubSubTypes.h

具体干啥的不用管,基本是生成的模版代码,有需要的时候具体再读就行。

DDS和ROS1联动

有分布式的数据交互需要但是又没用上ROS2的话可以用ROS1+dds联动的方式。PC1上的ros的话题推给dds,dds通过局域网推给PC2的dds,PC2的dds接收到数据之后再发给PC2的ros。

image-20220517192037471

DDS的Node编写

首先在DDS_NodeBase.h里面定义一些基类,后面会用的上,主要参考了官网的demo

主要是定义了DDS_PublisherDDS_Subscriber,从官方的DataWriterListenerDataReaderListener继承而来

然后针对定义的数据类型编写对应的Node,并在Node下实现发送函数和接收函数

以BBoxes为例,接收函数如下,把从dds来的数据推送到对应的ros话题中

class BBoxesDataSubscriber : public DDS_Subscriber
{
    // 接收,数据可用的时候
    void on_data_available(DataReader* reader) override
    {
        SampleInfo info;
        if (reader->take_next_sample(&recvData, &info) == ReturnCode_t::RETCODE_OK)
        {
            if (info.valid_data)
            {
                swarm_msgs::BoundingBoxes bboxesMsg;
                

                bboxesMsg.header.stamp = ros::Time::now();
                for (size_t i = 0; i < recvData.bounding_boxes().size(); i++)
                {
                    swarm_msgs::BoundingBox bboxMsg;
                    auto bbox_data = recvData.bounding_boxes()[i];

                    bboxMsg.id = bbox_data.id();
                    bboxMsg.Class = bbox_data.obj_class();

                    bboxMsg.xmin = bbox_data.xmin();
                    bboxMsg.ymin = bbox_data.ymin();
                    bboxMsg.xmax = bbox_data.xmax();
                    bboxMsg.ymax = bbox_data.ymax();
                    bboxMsg.probability = bbox_data.probability();

                    bboxMsg.point.x = bbox_data.pose_x();
                    bboxMsg.point.y = bbox_data.pose_y();
                    bboxMsg.point.z = bbox_data.pose_z();

                    bboxesMsg.bounding_boxes.push_back(bboxMsg);
                }
                bboxesPubs[recvData.system_ID()].publish(bboxesMsg);
            }
        }
    }

    BBoxesData  recvData;
};

发送函数如下:

bool BBoxesDataNode::publish(BBoxesData* sendData)
{
    if (dwListener_.matched_ > 0)
    {
        writer_->write(sendData);
        return true;
    }
    return false;
}

要点主要是准备好打包的数据。

其他的细节看代码就行。

代码仓库:

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors