赞
踩
在智能驾驶中,DDS有可能被广泛使用,因此推出这篇说明教程。
https://gitee.com/hiyanyx/qt5.14-cpp_dds_-project/tree/qt-dds
git分支"qt-dds"
查看《【eProsima Fast DDS(1)】安装eProsima Fast DDS》
至少安装:
foonathan_memory_vendor,一个 STL 兼容的 C++ 内存分配器 库。
fastcdr,一个根据 CDR 标准进行数据序列化的 C++ 库。
fastrtps,eProsima Fast DDS库的核心库。
测试安装是否正确的方法:在cmakelists 中加入
find_package(fastcdr REQUIRED)
find_package(foonathan_memory REQUIRED)
find_package(fastrtps REQUIRED)
如果cmake 提示找到了该库,则表示库ok。
我们一般是先写 DDS 的idl 文件(本质是定义定义数据结构体类型),然后通过DDS的代码生成工具生成 cpp 和hpp文件。如下图:
因为我们使用的【QT开发(5)】教程的项目文档进行开发,哪个项目直接遍历src 目录里面全部的cpp和hpp文件。因此我们把message 复制进入src目录即可,不用变更cmakelists
例如我们定义两个数据结构体PerceptionCommand 和WorkingStatus
module auto_msg {
module msg {
struct PerceptionCommand {
uint64 time_stamp;
uint8 system_command;
uint8 system_reset;
};
};
};
module auto_msg {
module msg {
struct WorkingStatus {
uint64 time_stamp;
uint32 counter;
};
};
};
目的:移植rclcpp 的publisher、subscription、和timer
因为我们使用的【QT开发(5)】教程的项目文档进行开发,哪个项目直接遍历src 目录里面全部的cpp和hpp文件。因此我们把rclcpp复制进入src目录即可,不用变更cmakelists
增加
find_package(fastcdr REQUIRED)
find_package(foonathan_memory REQUIRED)
find_package(fastrtps REQUIRED)
修改target_link_libraries ,增加fastrtps
target_link_libraries( emptyApp
fmt
Qt5::Widgets
${OpenCV_LIBS}
fastrtps
pthread
)
因为我们使用的【QT开发(5)】教程的项目文档进行开发,哪个项目直接遍历src 目录里面全部的cpp和hpp文件。因此我们把message 、rclcpp复制进入src目录即可,不用变更cmakelists
我们建立一个example文件夹,建立example.cpp 和 example.hpp
先写 example.hpp,首先引入头文件
#include <rclcpp/rclcpp.hpp>
#include <PerceptionCommand.hpp> // 这个是message 里面定义的 dds 通信数据结构体
#include <WorkingStatus.hpp> // 这个是message 里面定义的 dds 通信数据结构体
然后建立一个对象Example class
class Example : public rclcpp::Node { public: Example(); ~Example(); int Init(); private: // 1# 订阅者 rclcpp::Subscription<auto_msg::msg::PerceptionCommand>::SharedPtr perceptionCommand_sub_; // 2# 信息存储的成员 rclcpp::AtomicSet<auto_msg::msg::PerceptionCommand> perceptionCommand_; // 3#建立 订阅者的回调函数 msg_PerceptionCommand_callback,实现的数据存放在perceptionCommand_成员 void msg_PerceptionCommand_callback(const auto_msg::msg::PerceptionCommand::SharedPtr msg); // 4# 建立一个50ms 的定时器 rclcpp::TimerBase::SharedPtr workingStatus_timer_; // 5# 建立发布者 Publisher rclcpp::Publisher<auto_msg::msg::WorkingStatus>::SharedPtr workingStatus_pub_; rclcpp::AtomicSet<auto_msg::msg::WorkingStatus> workingStatus_; // 6# 定时器的回调函数 void timer_WorkingStatus_callback(); };
我们建立了6个函数,分别的作用是
1、建立一个 perceptionCommand_sub_ 订阅者
2、建立一个 perceptionCommand_ 的信息存储的成员
3、建立 订阅者的回调函数 msg_PerceptionCommand_callback,实现把收到的数据存放在 perceptionCommand_ 的信息存储的成员
里面
4、建立一个50ms 的定时器
5、建立一个 workingStatus_pub_ 的发布者;4、建立一个 workingStatus_ 成员
6、建立一个 定时器的回调函数,处理perceptionCommand_ 成员
的数据,并发送workingStatus_pub_ 数据。
example.cpp 里面这么写
int Example::Init() { counter_ = 0; workingStatus_pub_ = this->create_publisher<auto_msg::msg::WorkingStatus>( "example_status_pub", 2); perceptionCommand_sub_ = this->create_subscription<auto_msg::msg::PerceptionCommand>( "perception_command_pub", 2, std::bind(&Example::msg_PerceptionCommand_callback, this, _1)); workingStatus_timer_ = this->create_wall_timer(50, std::bind(&Example::timer_WorkingStatus_callback, this)); // 50 millisecond return 0; } void Example::timer_WorkingStatus_callback() { // here is how use the msg which had received auto_msg::msg::PerceptionCommand perceptionCommand = perceptionCommand_.Get(); if (perceptionCommand.system_command() == 0x06) { // for example, do sth what you want when command equal some value int a = 1; } auto_msg::msg::WorkingStatus workingStatus; workingStatus.time_stamp() = rclcpp::PlatformGetMs(); workingStatus_pub_->publish(workingStatus); } void Example::msg_PerceptionCommand_callback(const auto_msg::msg::PerceptionCommand::SharedPtr msg) { perceptionCommand_.Set(*msg); }
增加头文件引用
#include <rclcpp/rclcpp.hpp>
#include "example.h"
main 函数里面加入
rclcpp::init(argc, argv);
std::shared_ptr<yanyx::auto::Example> example = std::make_shared<yanyx::auto::Example>();
example->Init();
rclcpp::spin(example);
关于 rclcpp::spin()
的说明可以看我的另外一篇文章《【eProsima Fast DDS(2)】ROS2:spin() spin_some()函数》,这个是堵塞了main 函数。
1、建立一个 perceptionCommand_sub_ 订阅者
2、建立一个 perceptionCommand_ 的信息存储的成员
3、建立 订阅者的回调函数 msg_PerceptionCommand_callback,实现把收到的数据存放在 perceptionCommand_ 的信息存储的成员
里面
4、建立一个50ms 的定时器
5、建立一个 workingStatus_pub_ 的发布者;4、建立一个 workingStatus_ 成员
6、建立一个 定时器的回调函数,处理perceptionCommand_ 成员
的数据,并发送workingStatus_pub_ 数据。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。