虽然在官方的Github中有不少的例子,但是感觉都挺复杂的,不能很好的理解,所以自己拆解成比较简单的,易于学习理解。我是刚开始学习,一定会有不扫理解有误的地方,希望大家指正
- 首先编写 .idl 文件,这个文件的主要作用是定义用于发布topic的数据类型
struct Test
{
unsigned long index;
string message;
};
- 将.idl文件制作成可以被c++认识的类型,这一步需要fastrtpsgen工具
fastrtpsgen test.idl
//如果需要生成示例
fastrtpsgen -example CMake test.idl
执行上面两条命令中的一条后,会生成至少四个文件,这四个文件将被用于定义topic的类型,和实例
生成的四个文件的分别是
test.cxx test.h testPubSubTypes.cxx testPubSubTypes.h
- 编写发布节点的代码
#include "test.h"
#include "testPubSubTypes.h"
#include <fastrtps/fastrtps_fwd.h>
#include <fastrtps/participant/Participant.h>
#include <fastrtps/attributes/ParticipantAttributes.h>
#include <fastrtps/attributes/PublisherAttributes.h>
#include <fastrtps/publisher/PublisherListener.h>
#include <fastrtps/publisher/Publisher.h>
#include <fastrtps/Domain.h>
#include <fastrtps/utils/eClock.h>
#include <iostream>
using namespace std;
int main()
{
//topic消息实例
Test m_test;
//topic类型实例
TestPubSubType m_type;
//下面两句为消息实例赋值
m_test.index( 0 );
m_test.message( "HelloTest" );
//初始化一个参与者属性的实例,这个实例可以设置许多属性,这一点我还类有研究,使用用默认的
eprosima::fastrtps::ParticipantAttributes parAttr;
//创建一个参与者
eprosima::fastrtps::Participant * par = eprosima::fastrtps::Domain::createParticipant( parAttr );
if( par == nullptr)
return 1;
//注册topic的消息类型
eprosima::fastrtps::Domain::registerType( par, &m_type);
//创建一个发布者属性的实例,并设置消息类型和topic名字,是必须的
eprosima::fastrtps::PublisherAttributes pubAttr;
pubAttr.topic.topicDataType = "Test";
pubAttr.topic.topicName = "firstTopic";
//创建一个发布者
eprosima::fastrtps::Publisher * pub = eprosima::fastrtps::Domain::createPublisher( par, pubAttr);
if( pub == nullptr )
return 2;
//while循环发送消息,并每次发送后休眠1000毫秒
int i = 0;
while( i++ < 10000)
{
pub->write( (void *)&m_test );
m_test.index( m_test.index() + 1);
eprosima::fastrtps::eClock::my_sleep( 1000 );
}
//remove这个参与者
eprosima::fastrtps::Domain::removeParticipant( par );
return 0;
}
- 编写订阅节点
#include "test.h"
#include "testPubSubTypes.h"
#include <fastrtps/participant/Participant.h>
#include <fastrtps/attributes/ParticipantAttributes.h>
#include <fastrtps/attributes/SubscriberAttributes.h>
#include <fastrtps/subscriber/SubscriberListener.h>
#include <fastrtps/subscriber/Subscriber.h>
#include <fastrtps/Domain.h>
#include <fastrtps/subscriber/SampleInfo.h>
class SubListener : public eprosima::fastrtps::SubscriberListener
{
public:
SubListener():n_matched(0),n_samples(0){};
~SubListener(){};
// void onSubscriptionMatched(eprosima::fastrtps::Subscriber* sub, eprosima::fastrtps::rtps::MatchingInfo& info);
void onNewDataMessage(eprosima::fastrtps::Subscriber* sub)
{
if(sub->takeNextData((void*)&m_test, &m_info))
{
if(m_info.sampleKind == eprosima::fastrtps::rtps::ALIVE)
{
this->n_samples++;
// Print your structure data here.
std::cout << "Message "<< m_test.message()<< " "<< m_test.index()<< " RECEIVED"<<std::endl;
}
}
}
Test m_test;
eprosima::fastrtps::SampleInfo_t m_info;
int n_matched;
uint32_t n_samples;
};
int main(int argc, char *argv[])
{
Test m_test;
TestPubSubType m_type;
eprosima::fastrtps::ParticipantAttributes PParam;
eprosima::fastrtps::Participant *participant = eprosima::fastrtps::Domain::createParticipant(PParam);
if( participant == nullptr )
return false;
eprosima::fastrtps::Domain::registerType(participant, &m_type);
eprosima::fastrtps::SubscriberAttributes Rparam;
Rparam.topic.topicDataType = "Test";
Rparam.topic.topicName = "firstTopic";
//与发布者节点相比最大的不同在于,创建订阅者的时候有一个类用于处理订阅到的消息,估计患有其他的方式处理订阅到的消息
SubListener lis;
eprosima::fastrtps::Subscriber * subscriber = eprosima::fastrtps::Domain::createSubscriber(participant, Rparam, &lis);
std::cin.get();
eprosima::fastrtps::Domain::removeParticipant( participant );
return 0;
}