【PX4SimulinkGazebo联合仿真】在Simulink中使用ROS2控制无人机沿自定义圆形轨迹飞行并在Gazebo中可视化

news2025/1/5 8:54:11

在Simulink中使用ROS2控制无人机沿自定义圆形轨迹飞行并在Gazebo中可视化

    • 系统架构
    • Matlab官方例程Control a Simulated UAV Using ROS 2 and PX4 Bridge
    • 运行所需的环境配置
    • PX4&Simulink&Gazebo联合仿真实现方法
      • 建立Simulink模型并完成基本配置
      • 整体框架
      • 各子系统实现原理
        • Arm子系统
        • Enable Offboard Control子系统
        • Takeoff子系统
        • Trajectory Flight子系统
    • 实现效果

本篇文章介绍如何使用ROS2控制无人机沿自定义圆形轨迹飞行并在Gazebo中可视化,提供了Matlab/Simulink源代码,以及演示效果图。

环境:

MATLAB : R2022b

Ubuntu :20.04 LTS

Windows :Windows 10

ROS :ROS2 Foxy

Python: 3.8.2

Visual Studio :Visual Studio 2019

PX4 :1.13.0

系统架构

ROS2的应用程序管道非常简单,这要归功于本地通信中间件(DDS/RTPS)。microRTPS桥接工具由运行在PX4上的客户端和运行在计算机上的服务端组成,它们进行通信以提供uORB和ROS2话题格式之间的双向数据交换和话题转换。使得可以创建直接与PX4的uORB话题接口的ROS2订阅服务器或发布服务器节点,其结构如下图所示。

在这里插入图片描述

ROS 2使用px4_msgs包和px4_ROS_com包来确保使用匹配的话题定义来创建客户端和服务端代码。

px4_msgs包:px4 ROS话题定义,当构建该项目时会生成相应的兼容ROS2节点的话题类型,以及IDL文件,由fastddsgen用于生成microRTPS代码。

px4_ros_com包:服务端发布者和订阅者的microRTPS代码模板,构建过程运行一个fastddsgen实例来生成micrortps_agent的代码,该代码可编译为单个可执行文件。

这样在Ubuntu中就生成了一个可以调用uORB话题接口的ROS2节点,这个节点可以和运行在同一局域网下的Matlab/Simulink上的ROS2节点进行通信,以实现PX4&Simulink&Gazebo联合仿真。

20240221092830.png" width="800">

Matlab官方例程Control a Simulated UAV Using ROS 2 and PX4 Bridge

Matlab官方给出了一个示例,该示例演示了如何从具有PX4自动驾驶仪的模拟无人机接收传感器读数和自动驾驶仪状态,并发送控制命令来导航模拟无人机,可以作为参考。

Control a Simulated UAV Using ROS 2 and PX4 Bridge

可以在Matlab命令行中输入以下命令打开该例程所在位置。

openExample('uav_ros/ControlASimulatedUAVUsingROS2AndPX4BridgeExample')

运行所需的环境配置

请确保已经安装前一篇文章配置好了PX4+Gazebo+ROS2+FastDDS+Matlab+Simulink联合调试环境。

【PX4-AutoPilot教程-开发环境】搭建PX4+Gazebo+ROS2+FastDDS+Matlab+Simulink联合调试环境

PX4&Simulink&Gazebo联合仿真实现方法

建立Simulink模型并完成基本配置

在Matlab工作文件夹中models文件夹中新建一个Simulink模型,我这里命名为TrajectoryFlight.slx,双击使用Simulink打开。

在这里插入图片描述

在【建模】栏打开【模型设置】,【求解器】栏中【求解器类型】选为【定步长】。

20240123211557.png" width="600">

【硬件实现】栏中【Hardware board】选择【ROS2】。

在这里插入图片描述

【代码生成】栏中【接口】勾选【连续时间】。

在这里插入图片描述

仿真调速界面勾选【启用调速以减慢仿真】。

在这里插入图片描述

整体框架

整体框架如下,主体是对时钟进行判断,1-3秒是触发Arm子系统,3-5秒是触发Enable Offboard Control子系统,5-7秒是触发Takeoff子系统,7秒后是触发Trajectory Flight子系统。

在这里插入图片描述

各子系统实现原理

Arm子系统

Arm子系统中使用ROS2 Subscribe模块订阅/fmu/timesync/out话题,并使用Bus Selector分解话题获取时间戳,将时间戳传入Subsystem子系统。

在这里插入图片描述

无人机的解锁是通过vehicle_command话题进行的,它的定义在源码Firmware/msg/vehicle_command.msg中,这个话题是地面站/nsh等终端发送的控制指令用的。

我们可以从任意已经编译过的固件中的Firmware\build\px4_fmu-v5_default\uORB\topics\vehicle_command.h文件中看到vehicle_command话题的结构体定义。

	uint64_t timestamp;
	double param5;
	double param6;
	float param1;
	float param2;
	float param3;
	float param4;
	float param7;
	uint32_t command;
	uint8_t target_system;
	uint8_t target_component;
	uint8_t source_system;
	uint8_t source_component;
	uint8_t confirmation;
	bool from_external;
	uint8_t _padding0[2]; // required for logger

可以看到其结构为:

时间戳+command命令+目标系统号+目标组件号+发出命令系统号+发出命令组件号+收到命令次数+数据包

在源码Firmware/msg/vehicle_command.msg中可以检索到解锁的命令ID是:

uint16 VEHICLE_CMD_COMPONENT_ARM_DISARM = 400		# Arms / Disarms a component |1 to arm, 0 to disarm|

可以在注释中看到用法,只需将param1的值赋值为1即可解锁。

综上,通过ROS2对无人机进行解锁的方法为:

订阅/fmu/timesync/out获得时间戳–>command设置为400、param1设置为1、target_system设置为1–>发布/fmu/vehicle_command/in话题。

Subsystem子系统中使用ROS2 Blank Message获得px4_msgs/vehicle_command的话题类型,导入获取到的时间戳、命令编号、传入参数等,并使用ROS2 Publish模块发布该话题。

在这里插入图片描述

Enable Offboard Control子系统

Enable Offboard Control子系统中使用ROS2 Subscribe模块订阅/fmu/timesync/out话题,并使用Bus Selector分解话题获取时间戳,将时间戳传入Subsystem子系统。

在这里插入图片描述

无人机进入Offboard模式也是通过vehicle_command话题进行的。

在源码Firmware/msg/vehicle_command.msg中可以检索到设置系统模式的命令ID是:

uint16 VEHICLE_CMD_DO_SET_MODE = 176			# Set system mode. |Mode, as defined by ENUM MAV_MODE| Empty| Empty| Empty| Empty| Empty| Empty|

这里的注释写的是将第一个参数param1设为模式的ID号,之后param2param7设置为空,但是这里的注释好像写错了。

在源码Firmware/src/modules/commander/Commander.cpp中,官方写的调节模式的命令是:

send_vehicle_command(vehicle_command_s::VEHICLE_CMD_DO_SET_MODE, 1, PX4_CUSTOM_MAIN_MODE_OFFBOARD);

send_vehicle_command()函数的定义为:

static bool send_vehicle_command(const uint32_t cmd, const float param1 = NAN, const float param2 = NAN,
				 const float param3 = NAN,  const float param4 = NAN, const double param5 = static_cast<double>(NAN),
				 const double param6 = static_cast<double>(NAN), const float param7 = NAN)
{
	vehicle_command_s vcmd{};
	vcmd.command = cmd;
	vcmd.param1 = param1;
	vcmd.param2 = param2;
	vcmd.param3 = param3;
	vcmd.param4 = param4;
	vcmd.param5 = param5;
	vcmd.param6 = param6;
	vcmd.param7 = param7;

	uORB::SubscriptionData<vehicle_status_s> vehicle_status_sub{ORB_ID(vehicle_status)};
	vcmd.source_system = vehicle_status_sub.get().system_id;
	vcmd.target_system = vehicle_status_sub.get().system_id;
	vcmd.source_component = vehicle_status_sub.get().component_id;
	vcmd.target_component = vehicle_status_sub.get().component_id;

	uORB::Publication<vehicle_command_s> vcmd_pub{ORB_ID(vehicle_command)};
	vcmd.timestamp = hrt_absolute_time();
	return vcmd_pub.publish(vcmd);
}

可以看出需要将param1赋值为1,将param2赋值为PX4_CUSTOM_MAIN_MODE_OFFBOARD才能切换为Offboard模式。

查询PX4_CUSTOM_MAIN_MODE_OFFBOARD的定义,在源码Firmware/src/modules/commander/px4_custom_mode.h中找到:

enum PX4_CUSTOM_MAIN_MODE {
	PX4_CUSTOM_MAIN_MODE_MANUAL = 1,
	PX4_CUSTOM_MAIN_MODE_ALTCTL,
	PX4_CUSTOM_MAIN_MODE_POSCTL,
	PX4_CUSTOM_MAIN_MODE_AUTO,
	PX4_CUSTOM_MAIN_MODE_ACRO,
	PX4_CUSTOM_MAIN_MODE_OFFBOARD,
	PX4_CUSTOM_MAIN_MODE_STABILIZED,
	PX4_CUSTOM_MAIN_MODE_RATTITUDE_LEGACY,
	PX4_CUSTOM_MAIN_MODE_SIMPLE /* unused, but reserved for future use */
};

PX4_CUSTOM_MAIN_MODE_OFFBOARD对应的数字是6。

综上,通过ROS2对无人机进入Offboard模式的方法为:

订阅/fmu/timesync/out获得时间戳–>command设置为176、param1设置为1、param2设置为6、target_system设置为1–>发布/fmu/vehicle_command/in话题。

Subsystem子系统中使用ROS2 Blank Message获得px4_msgs/vehicle_command的话题类型,导入获取到的时间戳、命令编号、传入参数等,并使用ROS2 Publish模块发布该话题。

在这里插入图片描述

Takeoff子系统

Takeoff子系统中使用ROS2 Subscribe模块订阅/fmu/timesync/out话题,并使用Bus Selector分解话题获取时间戳,将时间戳传入SendCommand子系统。

在这里插入图片描述

offboard_control_mode话题是Offboard模式的心跳包,为了保证飞行的安全性,心跳包必须以最低2Hz的频率发布,PX4在两个Offboard命令之间有一个500ms的延时,如果超过此延时,系统会将回到无人机进入Offboard模式之前的最后一个模式。

在源码Firmware/msg/offboard_control_mode.msg中可以看到offboard_control_mode话题的定义。

# Off-board control mode

uint64 timestamp		# time since system start (microseconds)

bool position
bool velocity
bool acceleration
bool attitude
bool body_rate
bool actuator

因为要进行位置控制所以需要将position赋值为true。

trajectory_setpoint话题是期望的位置,在源码Firmware/msg/vehicle_local_position_setpoint.msg中可以看到trajectory_setpoint话题的定义。

# Local position setpoint in NED frame
# setting something to NaN means the state should not be controlled

uint64 timestamp	# time since system start (microseconds)

float32 x		# in meters NED
float32 y		# in meters NED
float32 z		# in meters NED
float32 yaw		# in radians NED -PI..+PI
float32 yawspeed	# in radians/sec
float32 vx		# in meters/sec
float32 vy		# in meters/sec
float32 vz		# in meters/sec
float32[3] acceleration # in meters/sec^2
float32[3] jerk # in meters/sec^3
float32[3] thrust	# normalized thrust vector in NED

# TOPICS vehicle_local_position_setpoint trajectory_setpoint

其中trajectory_setpoint话题和vehicle_local_position_setpoint话题的内容是一样的,源码Firmware/msg/tools/urtps_bridge_topics.yaml中可以看到以下代码。

  - msg:     vehicle_local_position_setpoint
    receive: true
  - msg:     trajectory_setpoint # multi-topic / alias of vehicle_local_position_setpoint
    base:    vehicle_local_position_setpoint
    receive: true

可以看出trajectory_setpoint话题是基于vehicle_local_position_setpoint话题的。

这里需要注意坐标系是NED坐标系,即北东地坐标系,所以想让无人机飞起来,z的赋值应该为负数。

综上,通过ROS2对无人机进入Offboard模式起飞悬停的方法为:

订阅/fmu/timesync/out获得时间戳–>position设置为true、x设置为0、y设置为0、z设置为-5、target_system设置为1–>发布offboard_control_mode话题和trajectory_setpoint话题。

SendCommand子系统中使用ROS2 Blank Message获得offboard_control_mode的话题类型和trajectory_setpoint的话题类型,导入获取到的时间戳、传入参数、期望位置等,并使用ROS2 Publish模块发布这些话题。

在这里插入图片描述

Trajectory Flight子系统

Trajectory Flight子系统跟Takeoff子系统大体一样,只不过在Desired Position部分有所改动,改为实时的发送自定义圆轨迹上的位置。

在这里插入图片描述

在这里插入图片描述

MATLAB Function将仿真时间作为输入,输出的是期望位置,函数内部的代码为:

function y = fcn(t)

r = 5;%圆的半径
w = 0.5;%绕圆心的角速度

t = t - 7;%去掉轨迹飞行开始前的时间

position_x = r * (1 - cos(w * t));
position_y = r * sin(w * t);

y = single([position_x position_y -5]);

这里给定了圆的半径、绕圆心的角速度,结算出每一时刻无人机的期望位置。

实现效果

Ubuntu中启动Gazebo仿真和microrts_agent守护进程,运行Simulink模型,可以看到Gazebo中的无人机已经进入Offboard模式并起飞悬停在5m的高度后沿自定义圆形轨迹飞行。

在这里插入图片描述

无人机在Gazebo中飞行时,无人机始终处于画面中央,会带着视角乱晃,在Gazebo中进行任何操作视角都无法固定,分析原因是PX4在Gazebo仿真中写了一个脚本来使无人机一直处于画面中央。

在这里插入图片描述

在Tools/sitl_run.sh文件中有如下的代码,控制Gazebo中的视角跟随无人机。

# Disable follow mode
if [[ "$PX4_NO_FOLLOW_MODE" != "1" ]]; then
    follow_mode="--gui-client-plugin libgazebo_user_camera_plugin.so"
else
    follow_mode=""
fi

在运行仿真命令时加上前缀PX4_NO_FOLLOW_MODE=1来屏蔽视角跟随部分代码。

PX4_NO_FOLLOW_MODE=1 make px4_sitl_rtps gazebo

之后再次运行即可在固定视角下观察无人机的运动。

在这里插入图片描述

在这里插入图片描述


参考资料:

PX4 Gazebo Simulation

Control a Simulated UAV Using ROS 2 and PX4 Bridge

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1461492.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL 安装步骤

下载地址&#xff1a;https://downloads.mysql.com/archives/community/&#xff0c; 选择第二个 将下载的压缩包解压到自己想要放到的目录下&#xff08;路径中最好不要有中文&#xff09; 一、添加环境变量 环境变量里面有很多选项&#xff0c;这里我们只用到Path这个参数…

IOT-Reaserch虚拟机配置

我用的是VirturalBox 主机与物理机之间的复制粘贴问题 VirtualBox Ubuntu无法安装增强功能以及无法复制粘贴踩坑记录_virtualbox安装增强功能没反应-CSDN博客 上面这篇博客帮助了我很多&#xff0c;摘取重要的重新提示一遍 运行虚拟机选择&#xff1a;设备->安装增强功能…

基于EKF扩展卡尔曼滤波的传感器网络目标跟踪matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022a 3.部分核心程序 .....................................................................% 定义初始位置的均…

力扣773. 滑动谜题(BFS)

Problem: 773. 滑动谜题 文章目录 题目描述思路解题方法复杂度Code 题目描述 思路 由于题目提到最小步数&#xff0c;则可以使用BFS来穷举出最小的结果 1.转换为BFS问题&#xff1a;由于0代表空着的可以移动的位置&#xff0c;所以我们只需要从当前位置和0的相邻位置移动从而转…

错误票据题解

1、错误票据 题目信息 思路 先对数组进行排序&#xff0c;然后遍历数组&#xff0c;如果出现两个一样的&#xff0c;就是重号&#xff0c;如果连续的两个数之间相差大于1就是断号 题解 #include<bits/stdc.h> #define hh ios::sync_with_stdio(false),cin.tie(0),cou…

Golang - 从源码到二进制:探索在国产CPU架构上交叉编译Minio的方法

文章目录 前置知识交叉编译Go 支持的所有操作系统和体系结构组合列出 Go 支持的所有操作系统和体系结构组合 大端、小端minio使用的go版本ABI 官方下载目标编译loongarch架构下的minio编译mipsle架构下的minio编译sw64架构下的minio 前置知识 交叉编译 交叉编译是指在一台主机…

IP详细地理位置查询:技术原理与应用实践

IP地址是互联网上设备的唯一标识&#xff0c;在网络安全、个性化服务等领域具有重要意义。通过IP详细地理位置查询&#xff0c;可以获取到IP地址所在地的具体信息&#xff0c;为网络管理、定位服务等提供支持。IP数据云将深入探讨IP详细地理位置查询的技术原理、应用实践以及相…

【JavaEE】_form表单构造HTTP请求

目录 1. form表单的格式 1.1 form表单的常用属性 1.2 form表单的常用搭配标签&#xff1a;input 2. form表单构造GET请求实例 3. form表单构造POST请求实例 4. form表单构造法的缺陷 对于客户端浏览器&#xff0c;以下操作即构造了HTTP请求&#xff1a; 1. 直接在浏览器…

CTR之行为序列建模用户兴趣:DIN

在前面的文章中&#xff0c;已经介绍了很多关于推荐系统中CTR预估的相关技术&#xff0c;今天这篇文章也是延续这个主题。但不同的&#xff0c;重点是关于用户行为序列建模&#xff0c;阿里出品。 概要 论文&#xff1a;Deep Interest Network for Click-Through Rate Predict…

前端|Day5:盒子模型(黑马笔记)

Day5:盒子模型 目录 Day5:盒子模型一、选择器1.结构伪类选择器基本使用 2. :nth-child(公式)3.伪元素选择器 二、PxCook三、盒子模型1.盒子模型-组成2.边框线四个方向单方向边框线 3.内边距4.尺寸计算5.外边距6.版心居中7.清除默认样式8.元素溢出9.外边距问题合并现象外边距塌陷…

14. UE5 RPG使用GameplayTag

GameplayTag本来是应用在GAS游戏技能系统里面的&#xff0c;后来UE直接将其抽离出来&#xff0c;作为一个模块&#xff0c;现在可以不在GAS里也可以使用这个模块。比如&#xff0c;我需要判断一个射线拾取的物体&#xff0c;首先我需要判断这个actor是否存在&#xff0c;然后判…

K8S实战:Centos7部署Kubernetes1.20.0集群

目录 一、准备工作1.1、创建3台虚拟机1.1.1、下载虚拟机管理工具1.1.2、安装虚拟机管理工具1.1.3、下载虚Centos镜像1.1.4、创建3台虚拟机1.1.5、设置虚拟机网络环境 1.2、虚拟机基础配置&#xff08;3台虚拟机进行相同处理&#xff09;1.2.1、配置host1.2.2、关闭防火墙1.2.3、…

区块链游戏解说:什么是 Planet IX

作者&#xff1a;lesleyfootprint.network 编译&#xff1a;cicifootprint.network 数据源&#xff1a;Planet IX Dashboard 什么是 Planet IX Planet IX&#xff0c;一个由原生 IX TOKEN 推动的 Web3 玩赚平台。作为一款 GameFi 策略游戏&#xff0c; Planet IX 上的每项资…

python毕设选题 - 大数据商城人流数据分析与可视化 - python 大数据分析

文章目录 0 前言课题背景分析方法与过程初步分析&#xff1a;总体流程&#xff1a;1.数据探索分析2.数据预处理3.构建模型 总结 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题目缺少创新和亮点&#xff0c;往往达不到…

【C++语法基础】3.常用数学运算和位运算技巧(✨新手推荐阅读)

前言 在C编程中&#xff0c;数学运算是非常基础和常用的功能。C提供了多种数学运算符和函数&#xff0c;用于执行基本的数学计算&#xff0c;如加减乘除、取模运算以及位运算等。 一、加减乘除四则运算 C中的基本算术运算符包括加法()、减法(-)、乘法(*)、除法(/)。这些运算…

C++ bfs建模(六十一)【第八篇】

今天我们来学习一下bfs建模 1.bfs建模 BFS 建模 广度优先搜索是从某个起点由内向外逐层搜索&#xff08;多起点 BFS 中所有起点拥有同样的搜索特性&#xff09;。 搜索顺序为&#xff1a;1→2→3→4→5→6→7→8。 之前的课程中&#xff0c;我们学习过搜索树中的每个结点均表…

C++ 之LeetCode刷题记录(三十三)

&#x1f604;&#x1f60a;&#x1f606;&#x1f603;&#x1f604;&#x1f60a;&#x1f606;&#x1f603; 开始cpp刷题之旅。 目标&#xff1a;执行用时击败90%以上使用 C 的用户。 11. 盛最多水的容器 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;…

汽车电子论文学习---电动汽车用高功率密度碳化硅电机控制器研究

关键重点&#xff1a; sic的特点&#xff1a;耐压高、开关速度快、开关损耗小&#xff1b;采用sic的控制器&#xff0c;损耗降低70%&#xff0c;续航里程提高5%。sic的模块并联设计难度高于IGBT模块&#xff1b;多芯片并联导致热耦合问题、温升不均&#xff0c;导致部分芯片率…

【C++】类和对象---const成员,取地址及const取地址操作符重载,static成员

目录 ⭐const成员 ⭐取地址及const取地址操作符重载 ⭐static成员 ⭐概念 ⭐特性 ⭐const成员 将const修饰的“成员函数”称之为const成员函数&#xff0c;const修饰类成员函数&#xff0c;实际修饰该成员函数隐含的this指针&#xff0c;表明在该成员函数中不能对类的任何…

字符串相乘

43. 字符串相乘https://leetcode.cn/problems/multiply-strings/ 给定两个以字符串形式表示的非负整数 num1 和 num2&#xff0c;返回 num1 和 num2 的乘积&#xff0c;它们的乘积也表示为字符串形式。 注意&#xff1a;不能使用任何内置的 BigInteger 库或直接将输入转换为整…