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

在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 modeuint64 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 controlleduint64 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_setpointreceive: true- msg:     trajectory_setpoint # multi-topic / alias of vehicle_local_position_setpointbase:    vehicle_local_position_setpointreceive: 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" ]]; thenfollow_mode="--gui-client-plugin libgazebo_user_camera_plugin.so"
elsefollow_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.mzph.cn/news/694483.shtml

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

相关文章

识别图片字符-PaddleOCR

PaddleOCR 是由百度开发的一个开源光学字符识别&#xff08;OCR&#xff09;工具&#xff0c;它可以识别图片中的文本信息。然而&#xff0c;PaddleOCR 本身主要专注于文本的检测与识别 安装PaddleOCR框架 pip install paddlepaddle paddleocr 使用PaddleOCR识别图片代码 fro…

STL - hash

1、unordered系列关联式容器 在C98中&#xff0c;STL提供了底层为红黑树结构的一系列关联式容器&#xff0c;在查询时效率可达到O()&#xff0c;即最差情况下需要比较红黑树的高度次&#xff0c;当树中的节点非常多时&#xff0c;查询效率也不理想。最好 的查询是&#xff0c;进…

第四十一回 还道村受三卷天书 宋公明遇九天玄女-python创建临时文件和文件夹

宋江想回家请老父亲上山&#xff0c;晁盖说过几天带领山寨人马一起去。宋江还是坚持一个人去。 宋江到了宋家村&#xff0c;被两个都头和捕快们追捕&#xff0c;慌不择路&#xff0c;躲进了一所古庙。一会儿&#xff0c;听见有人说&#xff1a;小童奉娘娘法旨&#xff0c;请星主…

SpringBoot2整合支付宝进行沙箱支付

目录 1. 进入支付宝的开放平台 2. 导入Maven依赖 3. 配置application.yml文件 NATAPP.cn(内网穿透工具) 注册登录 下载 4. 后端配置 5. 测试 1. 进入支付宝的开放平台 开发平台: 支付宝开放平台 登录后,点击控制台 点击最下面的沙箱 2. 导入Maven依赖 <dependency…

Git 客户端可视化工具tortoisegit

Git 使用教程 git一点通 (kdocs.cn) 二、Git 客户端可视化工具-推荐 1.常用工具 tortoisegit 官网 https://tortoisegit.org/ 推荐 sourcetree 官网 https://www.sourcetreeapp.com/ 2.tortoisegit安装 2.1 下载安装包 2.2 下载语言包 2.3 安装 2.4 安装语言包 5.使用 5.1 新建…

Spring学习笔记(三)--Spring中的Bean的管理

一、什么是Bean Bean是注册到Spring容器中的Java类&#xff0c;控制反转和依赖注入都是通过Bean实现的&#xff0c;任何一个Java类都可以是一个Bean。Bean由Spring进行管理&#xff0c;可以通过xml文件对bean进行配置和管理。 二、BeanFactory接口和ApplicationContext接口&a…

利用Python实现科学式占卜

一直以来&#xff0c;中式占卜都是基于算命先生手工实现&#xff0c;程序繁琐&#xff08;往往需要沐浴、计算天时、静心等等流程&#xff09;。准备工作复杂&#xff08;通常需要铜钱等道具&#xff09;&#xff0c;计算方法复杂&#xff0c;需要纯手工计算二进制并转换为最终…

2023年12月 Python(六级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,共50分) 第1题 运行以下程序,输出的结果是?( ) class A():def __init__(self,x):self.x=x

手机连接电脑后资源管理器无法识别(识别设备但无法访问文件)

问题描述 小米8刷了pixel experience系统,今天用电脑连接后无法访问手机文件,但是手机选择了usb传输模式为文件传输 解决办法 在设备和打印机页面中右键选择属性 点击改变设置 卸载驱动,注意勾选删除设备的驱动程序软件 卸载后重新连接手机,电脑弹出希望对设备进行什么操作时…

Code-Audit(代码审计)习题记录4-5

4、习题4 题目内容如下&#xff1a; <?php error_reporting(0); show_source(__FILE__); $a $_REQUEST[hello]; eval("var_dump($a);"); 函数解释 $REQUEST — HTTP Request 变量&#xff0c;默认情况下包含了 [$GET]&#xff0c;[$POST] 和 [$COOKIE]的数…

HTML知识点

HTML 【一】HTML简介 【1】什么是HTML HTML是一种用于创建网页结构和内容的超文本标记语言&#xff0c;它是构建网页的基础。为了让浏览器正确渲染页面&#xff0c;我们必须遵循HTML的语法规则。浏览器在解析网页时会将HTML代码转换为可视化的页面&#xff0c;所以我们在浏览…

python接口测试实践:参数化测试、数据驱动测试和断言的使用

在Python接口测试实践中&#xff0c;参数化测试、数据驱动测试和断言是常用的技术手段。 参数化测试 参数化测试是指将测试用例中的某些部分&#xff08;如输入数据或配置&#xff09;作为参数传递给测试函数&#xff0c;以便于复用和减少代码重复。 例如&#xff0c;使用uni…

2024年最新腾讯云轻量4核8G12M服务器CPU内存性价比如何?

4核8G服务器支持多少人同时在线访问&#xff1f;阿腾云的4核8G服务器可以支持20个访客同时访问&#xff0c;关于4核8G服务器承载量并发数qps计算测评&#xff0c;云服务器上运行程序效率不同支持人数在线人数不同&#xff0c;公网带宽也是影响4核8G服务器并发数的一大因素&…

时序分析深入必学的时序模型详细讲解

目录 一、前言 二、时序建模 2.1 反相器 2.2 线性时序模型 2.3 非线性时序模型 三、时序模块 3.1 组合单元 3.2 时序单元 3.3 同步检查&#xff1a;setup和hold 3.4 异步检查&#xff1a;recovery和removal 3.5 脉冲宽度检查Pulse width check 3.6 传输时延 3.7 …

微信小程序配置文件

目录 小程序配置文件 1. 配置文件介绍 2. 全局配置 2.1 pages 2.2 window 2.3 tabBar 3. 页面配置 4. 项目配置文件 5. 支持使用 sass/less 6. sitemap.json 小程序配置文件 1. 配置文件介绍 JSON是一种轻量级的数据格式&#xff0c;常用于前后端数据的交互&#xf…

LDRA Testbed软件静态分析_软件质量度量

系列文章目录 LDRA Testbed软件静态分析_操作指南 LDRA Testbed软件静态分析_自动提取静态分析数据生成文档 LDRA Testbed软件静态分析_Jenkins持续集成_(1)自动进行静态分析的环境搭建 LDRA Testbed软件静态分析_Jenkins持续集成_(2)配置邮件自动发送静态分析结果 LDRA Testb…

typescript映射类型

ts映射类型简介 TypeScript中的映射类型&#xff08;Mapped Type&#xff09;是一种高级类型&#xff0c;它允许我们基于现有类型创建新的类型&#xff0c;同时对新类型的每个属性应用一个转换函数。通过使用映射类型&#xff0c;我们可以方便地对对象的属性进行批量操作&…

typescript 索引签名类型

ts索引类型简介 在TypeScript中&#xff0c;索引签名类型&#xff08;Index Signature Type&#xff09;是一种特殊的类型&#xff0c;它定义了对象中键的类型以及相应的值的类型。通过使用索引签名类型&#xff0c;我们可以表示一个对象&#xff0c;该对象的键可以是任意类型…

python3 flask 实现对config.yaml文件的内容的增删改查,并重启服务

config.yaml配置文件内容 功能就是userpass下的用户名和密码做增删改查&#xff0c;并重启hy2服务 auth:type: userpassuserpass:csdn: csdnlisten: :443 masquerade:proxy:rewriteHost: trueurl: https://www.bing.com/type: proxy tls:cert: /root/hyst*****马赛克******er…

【算法2-1】前缀和、差分与离散化

一、【P3406】海底高铁&#xff08;差分贪心&#xff09;​​​​​​ 由于本题涉及到线路问题&#xff0c;需要统计Uim途径每条线路的次数&#xff0c;而且Uim每次的轨迹都是很长一段路径&#xff0c;所以需要使用一个合理的数据结构来维护区间的变化&#xff0c;首先想到线段…