DDS与PX4通讯
本文介绍了DDS安装、ROS2工作区创建及与PX4通信的实现过程。首先安装MicroXRCE-DDS-Agent并配置依赖,然后安装VSCode及必要插件。接着创建ROS2工作区,添加PX4消息定义包,配置bashrc环境变量。通过VSCode配置工程环境后,编写PX4桥接节点代码订阅无人机位置信息,并完成CMake编译配置。最后启动Agent、PX4仿真环境和桥接节点,验证了DDS通信功能。文章
接着上一期,这一期进行DDS的安装以及ROS2工作区的创建,并通过DDS实现与PX4的通信。
1.安装 Micro XRCE-DDS Agent
1.1 安装依赖
sudo apt update
sudo apt install git cmake g++ build-essential libasio-dev libtinyxml2-dev -y

1.2 下载并编译 Agent
cd ~
git clone https://github.com/eProsima/Micro-XRCE-DDS-Agent.git
cd Micro-XRCE-DDS-Agent
mkdir build
cd build
cmake ..
make -j$(nproc)
sudo make install
sudo ldconfig





验证安装
MicroXRCEAgent --help

DDS到此就已经安装完成了,下一步,进行ROS2工作空间的创建,在此之前呢,先安装vscode的代码编辑器。
2.vscode安装
直接在ubuntu中的浏览器中,搜索vscode,并进行下载
下载地址(供参考):https://code.visualstudio.com/Download

下载完成后,使用sudo dpkg -i 进行安装:
出现该页面直接勾选Yes,然后回车即可:

安装完成:

接下来安装一些vscode的插件:
新打开一个终端,输入code,打开vscode:

在左侧边栏点击插件选项:

可在搜索栏中直接搜索插件安装,博主这值安装了三个插件:
1.中文包
2.C/C++
3.Python

后续插件可在使用过程中在进行添加,这里就不过多的记录了。安装完成后,重启vscode页面即变为中文显示:

现在,代码的编译工具也有了,接下来,
3.创建 ROS2 工作区和工程包
drone_drl(博主自己的工程包名称,根据自己的项目而定,这里只是做示范用)。
3.1 创建工作区目录并进入该文件夹下:
mkdir -p ~/Drone_drl_ws/src
cd ~/Drone_drl_ws/src

此时,在主目录的文件夹下,可看到我们所建立的工程包:

3.2 创建 ROS2 C++ 包:drone_drl

此时如果提示找不到 px4_msgs 没关系,下面会克隆它。
此时,项目的结构如图所示:
~/Drone_drl_ws
└── src
└── drone_drl
├── CMakeLists.txt
├── package.xml
├── include/drone_drl/
└── src/
3.3 克隆 PX4 消息定义包 px4_msgs
cd ~/Drone_drl_ws/src
git clone https://github.com/PX4/px4_msgs.git

现在,我们的工程包目录结构如下:
~/Drone_drl_ws/src
├── drone_drl
└── px4_msgs
3.4 添加bashrc
打开新终端(博主这里使用nano编译器)
nano ~/.bashrc
在打开的页面中,滑到最底部,写入下面的两行(缺哪行写哪行即可):
source /opt/ros/humble/setup.bash
source ~/Drone_drl_ws/install/setup.bash

保存并退出(Ctrl+O 回车,Ctrl+X)
让其立即生效:
source ~/.bashrc
出现下面的提示没关系,因为我们还没有开始编译工程包:
在工程包中配置vscode:
打开工作区:
code ~/Drone_drl_ws
在最开始的基础上,安装Cmake tools拓展包:

配置 IntelliSense 头文件路径:
在打开的vscode项目中,创建
.vscode文件夹:

在该文件夹下,创建c_cpp_properties.json:
在创建的文件中,写入以下内容(注意替换成自己的用户路径):
{
"configurations": [
{
"name": "ROS2-Humble",
"includePath": [
"${workspaceFolder}/**",
"/opt/ros/humble/include/**",
"/home/z/Drone_drl_ws/install/px4_msgs/include/**"
],
"defines": [],
"compilerPath": "/usr/bin/g++",
"cStandard": "c11",
"cppStandard": "c++14",
"intelliSenseMode": "linux-gcc-x64"
}
],
"version": 4
}
写入后,记得保存“ctrl+s”
接下来,创建一个px4_bridge节点代码(订阅PX4位置信息,仅作范例使用)
在Drone_drl_ws/src/drone_drl/src目录下,创建px4_bridge.cpp文件:

在文件中写入以下的范例代码:
#include "rclcpp/rclcpp.hpp"
// PX4 消息类型
#include "px4_msgs/msg/vehicle_local_position.hpp"
#include "px4_msgs/msg/offboard_control_mode.hpp"
#include "px4_msgs/msg/trajectory_setpoint.hpp"
#include "px4_msgs/msg/vehicle_command.hpp"
using namespace std::chrono_literals;
class Px4Bridge : public rclcpp::Node
{
public:
Px4Bridge()
: Node("px4_drl_bridge")
{
// === 使用与 PX4 匹配的 QoS(传感器数据,Best Effort) ===
rclcpp::SensorDataQoS sensor_qos;
// 订阅 PX4 本地位置话题
local_pos_sub_ = this->create_subscription<px4_msgs::msg::VehicleLocalPosition>(
"/fmu/out/vehicle_local_position",
sensor_qos,
std::bind(&Px4Bridge::localPositionCallback, this, std::placeholders::_1));
// 预创建 Offboard 控制相关 publisher(后续 DRL 会用到)
offboard_mode_pub_ = this->create_publisher<px4_msgs::msg::OffboardControlMode>(
"/fmu/in/offboard_control_mode", 10);
traj_sp_pub_ = this->create_publisher<px4_msgs::msg::TrajectorySetpoint>(
"/fmu/in/trajectory_setpoint", 10);
vehicle_cmd_pub_ = this->create_publisher<px4_msgs::msg::VehicleCommand>(
"/fmu/in/vehicle_command", 10);
// 控制定时器(当前只占位,后续可写 Offboard/DRL 控制逻辑)
control_timer_ = this->create_wall_timer(
100ms, std::bind(&Px4Bridge::controlLoop, this));
RCLCPP_INFO(this->get_logger(),
"Px4Bridge node started. Subscribing /fmu/out/vehicle_local_position");
}
private:
// 接收 PX4 本地位置的回调
void localPositionCallback(const px4_msgs::msg::VehicleLocalPosition::SharedPtr msg)
{
RCLCPP_INFO_THROTTLE(
this->get_logger(),
*this->get_clock(),
500, // 每 500ms 打印一次
"PX4 Local Position: x=%.2f, y=%.2f, z=%.2f, vx=%.2f, vy=%.2f, vz=%.2f",
msg->x, msg->y, msg->z, msg->vx, msg->vy, msg->vz);
// TODO:后续在此处将状态写入 DRL 的状态向量中
}
// 控制循环(未来用来做 Offboard 控制 / DRL 控制)
void controlLoop()
{
// TODO:
// 1. 周期性发布 OffboardControlMode(心跳)
// 2. 根据 DRL 输出,发布 TrajectorySetpoint
// 3. 必要时发布 VehicleCommand(解锁、上锁等)
}
private:
// 订阅 PX4 状态
rclcpp::Subscription<px4_msgs::msg::VehicleLocalPosition>::SharedPtr local_pos_sub_;
// 发布 Offboard 控制相关消息
rclcpp::Publisher<px4_msgs::msg::OffboardControlMode>::SharedPtr offboard_mode_pub_;
rclcpp::Publisher<px4_msgs::msg::TrajectorySetpoint>::SharedPtr traj_sp_pub_;
rclcpp::Publisher<px4_msgs::msg::VehicleCommand>::SharedPtr vehicle_cmd_pub_;
// 控制定时器
rclcpp::TimerBase::SharedPtr control_timer_;
};
int main(int argc, char * argv[])
{
rclcpp::init(argc, argv);
auto node = std::make_shared<Px4Bridge>();
rclcpp::spin(node);
rclcpp::shutdown();
return 0;
}
代码写入后,保存,会看到编译器报错,提示找不到对应的头文件:

这个没关系,因为我们还没开始编辑Cmake文件,接下来,进行Cmake的编写:
配置 CMakeLists.txt(编译 px4_bridge)
直接替换drone_drl目录下的CMakeLists.txt文件内容:
cmake_minimum_required(VERSION 3.5)
project(drone_drl)
# 使用 C++14
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
# 依赖包
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(px4_msgs REQUIRED)
# 可执行文件:px4_bridge
add_executable(px4_bridge src/px4_bridge.cpp)
ament_target_dependencies(px4_bridge rclcpp px4_msgs)
# 安装可执行文件到 lib/drone_drl/
install(TARGETS
px4_bridge
DESTINATION lib/${PROJECT_NAME}
)
ament_package()
保存完后,在vscode中,使用终端,输入以下指令进行编译:


等待编译完成即可:

此时,我们的基础工程包已完成了基础的编译,下面就是运行包,测试所搭建的环境是否成功。
4.启动全集:Agent + PX4(gazebo-classic)+px4_bridge
4.1 打开终端1,启动启动 Micro XRCE-DDS Agent:
MicroXRCEAgent udp4 --port 8888

4.2 打开终端2 ,启动 PX4 SITL + Gazebo Classic:
cd ~/PX4-Autopilot
make px4_sitl gazebo-classic
此时,gazebo的页面打开,并显示无人机,同时DDS窗口也有了通信数据,此时,我们新打开一个窗口,输入以下代码,查看当前的无人机话题:
ros2 topic list
可以看到当前无人机的所有话题

下面有一个需要注意的点,在我们的示例代码中,我们使用的是:
/fmu/out/vehicle_local_position 这个话题
但在ros2 topic list打印的话题,话题变为了:

此时,我们需要修改我们的代码,将话题名改为一致,否则会找不到对应的话题名称:

将其改为:

改完代码后,保存,并重新编译:

编译完成后,打开终端3,运行我们的工程包:
ros2 run drone_drl px4_bridge
成功运行,即可看到以下的输出:

至此,我们的工程包已经监听到了当前无人机的位置信息,并且,px4+DDS的通信已完成大同,最基础的工程包已完成搭建。
下一步,博主将在无人机模型上,加入mid360激光雷达,并在项目中加入激光slam相应的算法,在ros2的基础上进行仿真验证。后续验证完成后,也会相应的更新在这里,各位同学,请期待下一期:ros2+px4+mid360激光雷达仿真
更多推荐

所有评论(0)