Prometheus-自主无人机开源项目

提示

Prometheus使用手册为Prometheus-v2版本,我们推荐大家使用Prometheus-v2,并且Prometheus-v1已不再维护,如需使用Prometheus-v1请前往 Prometheus仿真环境配置:Ubuntu 了解相关内容

Prometheus简介

Prometheus.png

Prometheus是希腊神话中最具智慧的神明之一,希望本项目能为无人机研发带来无限的智慧与光明。

Prometheus是一套开源的自主无人机软件系统平台,为无人机的智能与自主飞行提供全套解决方案。本项目基于PX4开源飞控固件ROS机器人操作系统,旨在为无人机开发者配套成熟可用的机载电脑端软件系统,提供更加简洁快速的开发体验。目前已集成控制、规划及目标检测等研究方向,提供多个功能demo,并配套有Amovlab仿真组件。

Prometheus项目由阿木实验室运营维护,阿木实验室提供Prometheus项目配套硬件

为什么要用Prometheus?

代码开源

Prometheus项目绝大部分代码都是开源的,并且代码都有比较完善的中文注释,能够帮助大家更好地进行二次开发。

功能丰富

目前已集成控制、规划以及目标检测等功能模块,涉及无人机绝大部分研究方向。

稳定易用

  • 所有功能模块均在不同无人机机型、不同场景下经过大量测试,并且所有功能模块均配备有无人机安全保护系统,确保无人机飞行稳定性

  • 在功能设计上尽可能减少操作步骤,几乎所有功能操作都可以实现“一键式”操作,确保功能易用性

  • 配备有Prometheus地面站,能够支持图形化界面操作

  • 提供turtorial_demo模块,该模块拥有更全面的注释,能够帮助用户快速了解Prometheus二次开发接口,上手Prometheus二次开发

配套齐全

Amovlab仿真组件

基于Gazebo/PX4/ROS的仿真系统,Prometheus项目所有功能均能够在Amovlab仿真组件上复现,支持二次开发。

仿真镜像系统

提供搭建好Prometheus项目以及相关依赖环境的Ubuntu镜像系统。

配套硬件

仿真镜像系统mini主机、搭载有Prometheus项目的三种不同大小机型产品(p230/p450/p600),适合各种应用场景下的二次开发无人机平台。

Prometheus使用手册

完善的Prometheus使用手册,帮助用户熟悉Prometheus,搭建Prometheus仿真系统以及熟悉Prometheus二次开发接口。

Prometheus配套课程

全面的Prometheus二次开发课程,针对无人机开发者,从零到一掌握无人机开发的基础知识。

Prometheus社区

  • 由阿木实验室维护的阿木社区-Prometheus问答专区,在学习使用Prometheus过程中遇到的相关问题都可以在里面进行讨论沟通,Prometheus项目组成员也会定期在论坛里答疑

  • Prometheus微信交流群,需要进Prometheus微信群可扫描下方微信二维码加阿木实验室-嘉月微信联系

  • 不定期的直播、线上培训、线下培训等活动,能够更好地帮助大家更好地沟通交流

  • Prometheus校园赞助计划:奖励使用Prometheus进行实验并发表相关论文的学生科研工作者

提示

建议初次查看Prometheus使用手册的用户先阅览Prometheus使用手册概述,先简单了解Prometheus使用手册包含哪些具体内容。

Prometheus使用手册概述

Prometheus-wiki分为以下内容板块

  • Prometheus-自主无人机开源项目

    本章内容为Prometheus项目概述,通过阅览本章内容,可快速了解Prometheus项目整体情况以及相关内容

  • 快速上手

    本章讲解如何快速搭建Prometheus项目仿真环境,分别介绍了使用Ubuntu原生系统以及使用虚拟机两种方式

  • Prometheus仿真入门

    本章讲解Prometheus项目仿真基础知识,主要包含仿真系统框架、仿真功能介绍以及遥控器使用相关说明

  • 无人机控制模块 - uav_control

    本章讲解Prometheus无人机控制子模块,包含整个子模块介绍以及功能demo讲解

  • 目标检测模块 - object_detection

    本章讲解Prometheus目标检测子模块,包含整个子模块介绍以及功能demo讲解

  • 路径规划模块 - motion_planning

    本章讲解Prometheus路径规划子模块,包含整个子模块介绍以及功能demo讲解

  • Prometheus真机教程

    本章讲解Prometheus真机教程相关内容,以Z410无人机为例,讲解如何在真机中部署Prometheus项目

  • 其他

    本章讲解与Prometheus项目其余相关内容,包括Ubuntu、PX4、ROS以及其余相关内容

配套硬件

淘宝Prometheus专区:点击购买

京东Prometheus专区:点击购买

客服咨询(皓月):17360174433(微信同号)

仿真镜像系统mini主机

预装Prometheus、PX4、ROS、Gazebo、MAVROS开发环境,可快速上手仿真开发。京东链接

a1a8adc0aa8ea1e9b8813543925f331.jpg

  • 特点:

    1.搭配8G内存和128G硬盘。

    2.拥有HDMI、DP、USB3.0、TypeC等多种接口。

    3.已预装Prometheus自主无人机开源项目的官方仿真镜像。

P230

Prometheus230(简称P230)是一款专为科研工作者及无人机开发者设计的无人机实验室平台,适用于室内环境,提供控制、SLAM、室内定位、视觉避障、路径规划等功能demo。京东链接

图片 1.png

图片 2(1).png

图片 3(1).png

  • 特点:

    1.内置基于PX4-ROS的控制模块和SLAM、自主决策、编队、避障等多种算法。

    2.搭载Pixhawk4 Mini开源飞控与英伟达Jetson Xavier NX边缘AI计算机。

    3.预装基于PX4+ROS的Prometheus自主无人机机载系统。

    4.配置Intel RealSense D435i深度相机。

    5.可通过内置的VINS-Fusion和EGO-Planner等算法。

    6.可实现室内定点飞行、路径规划和自主避障等功能。

    7.可广泛应用于室内环境下的无人机编队。

    8.支持接入主流的MOCAP动作捕捉和UWB等外部定位系统,通过ROS组网实现室内的编队飞行。

P450

Prometheus450(简称P450)是一款专为科研工作者及无人机开发者设计的无人机实验平台,兼容室内外环境,提供控制、SLAM、室内/室外定位、激光雷达/视觉避障、目标检测、路径规划等功能demo。京东链接

图片 2.png

图片 4.png

图片 5.png图片 6.png

  • 特点:

    1. 基于Pixhawk V4开源飞控架构,通过内走线设计集成了高性能旋翼动力系统。

    2. 可轻易实现室内/室外的简易飞行控制。

    3. 搭载Nvidia Jetson Xavier NX机载计算机。

    4. 内置ROS(机器人操作系统)环境下的无人机控制程序与多种前沿算法。

    5. 可一键实现目标识别、激光SLAM、视觉避障等功能。

    6. 采用3D打印外壳&轻量化碳管机架的设计,提高了传感器的搭载量。

    7. 高拓展性的二次开发平台,支持使用者自行加装其他设备,满足不同的研发需求。

    8. 所有功能及相关算法均通过开源项目Prometheus发布了源代码与仿真脚本,真正做到到手即飞,即刻开发!

P600

Prometheus600(简称P600)是一款专为科研工作者及无人机开发者设计的无人机实验平台,适用于室外环境,提供控制、室外定位、激光雷达避障、目标检测、目标追踪、圆叉降落等功能demo。京东链接

图片 3.png 图片 6.png 图片 10.png 图片 11.png

  • 特点:

    1. 全机身内走线+内置飞控的设计,预留三层拓展空间,可自由地加装适配PX4飞控或ROS的传感器。

    2. 可搭载云台吊舱、激光雷达与图数传一体组网链路等挂载设备。

    3. 实现基于视觉的目标识别、框选追踪、激光雷达避障、室外指点飞行等功能。

    4. 具备超视距多机组网+图数传通信的能力。

    5. 内置基于Pixhawk V5深度优化的飞控核心,贴合开发者使用习惯。

    6. 可选配10倍变焦光电吊舱、激光雷达与图数传一体组网链路。

    7. 支持复现Prometheus中的KCF框选追踪、A*全局规划、激光雷达SLAM和YOLO通用目标识别等算法。

Prometheus校园赞助计划

image.png

赞助示例

  • 题目:拦截非合作机动四旋翼的最优末速控制制导律

  • 期刊:中科院分区2区 - 机器人领域顶刊《Journal of Field Robotics》

  • 作者:陶宏,林德福,何绍溟,宋韬,金忍

  • 作者单位:北京理工大学无人自主控制研究所

  • 通讯作者:宋韬

  • 论文链接:https://onlinelibrary.wiley.com/doi/10.1002/rob.22059

Prometheus项目组

高校科研团队

  • 戚煜华(项目创始人):中山大学博士后,本科及博士毕业于北京理工大学,在自主无人机平台搭建及二次开发方面经验丰富。参与多项航空航天科研院所无人 机相关项目,曾获得2017年国际微小型无人机比赛第三名,已在铂贝学院开设PX4自主无人机线下培训课程10次,累计培训学员300余人次。 目前在International Journal of Systems Science及Robotics and Autonomous Systems等SCI期刊上发表论文4篇,会议论文3篇。主要研究方向为:无人机控制、自主避障等。

  • 金忍(目标检测):北京理工大学博士后/博士,多年从事机器视觉、无人机视觉的开发及教学工作,曾作为视觉组队长参加2017与2020年穆罕默德·本·扎耶德国际机器人挑战赛(MBZIRC),两次获得冠军。目前在Journal of Field Robotics等SCI期刊上发表论文3篇,会议论文2篇。擅长数据驱动算法编写、性能优化、实时计算等,研究兴趣主要包括深度学习,目标检测与跟踪,迁移学习,目标定位与姿态估计。

  • 祝洋(控制方向):西南交通大学助理教授,博士毕业于电子科技大学,长期以理论与工程紧密结合的方式开展无人机、运动体和集群的(多源)抗干扰控制技术 研究、验证与应用。目前已在TIM、IJRNC等期刊发表SCI论文5篇(其中包括IJRNC封面论文一篇),会议论文6篇(其中两篇分别获得ICCA2018和GNCC2018两个会议的Best Paper Finalist) 。负责Prometheus Matlab工具包模块。

  • 江涛(路径规划):重庆大学讲师,北京理工大学博士,具有多年无人机系统、控制和导航算法开发经验。参与过多项航空航天科研院所无人机相关项目,曾获得2017年穆罕默德·本·扎耶德国际机器人挑战赛(MBZIRC)冠军。目前在Journal of the Franklin Institute等SCI期刊上发表无人机自主控制论文7篇。主要研究方向包括:无人机自主控制、移动机器人规划和定位建图等。

  • 李春雨(SLAM):北京理工大学在读博士,具有丰富的竞赛经验及仿真系统的开发经验,负责阿木实验室Prometheus系列无人机的视觉导航及仿真部分的开发。主要研究兴趣包括:无人机状态估计、无人机高机动自主飞行等

阿木实验室研发团队

  • 王根(阿木实验室研发总监):参与PX4开源技术的推广与培训,累计培训学员近千人,主要研究方向:嵌入式驱动开发、PX4系统二次开发与控制调参、ROS系统二次开发与产品落地。参与Prometheus项目飞控端的适配与开发工作。

  • 弋鑫(控制算法工程师):在控制算法工程师开源飞控及自主无人机二次开发方面经验丰富,参与多个航空航天院校及科研院所自主无人机项目。目前主要负责P系列无人机开发与维护,负责无人机控制模块、路径规划模块、gazebo仿真模块的开发与测试。

  • 李博(控制算法工程师):多年从事研究无人车、类人型机器人、无人机以及编队集群等系统开发相关工作,参与多个无人车以及集群相关项目,行业经验丰富。目前负责阿木实验室无人车以及集群相关开发、维护及测试工作。负责Prometheus集群控制模块的开发与测试。

  • 张灵(软件工程师):参与过多个机器人相关的项目,负责其中的通信以及地面站开发工作;目前在阿木实验室负责P系列无人机、R系列无人车的通信模块和地面站的开发、维护及调试工作。负责Prometheus集群地面站的开发与测试。

  • 王明(视觉算法工程师):参与过多项与深度学习相关的计算机视觉,自然语言处理工作,负责阿木实验室的P系列无人机的视觉算法的落地,P600无人机的软件开发,维护及调试,以及AirSim仿真的推进。负责Prometheus视觉模块的开发与测试。

  • 李科衡(视觉算法工程师):参与过多项机器人竞赛以及和机器人相关的项目,负责阿木实验室吊舱开发、维护及调试,主要研究方向:目标检测、目标追踪、视频编解码(Deepstream)。参与Prometheus目标追踪模块的开发与测试。

  • 张子超 (结构工程师):从事多年无人机、无人车、消费级电子产品结构及外观设计,在产品设计领域有丰富的经验,参与过多款阿木实验室无人机产品的研发。负责Prometheus项目中无人机、无人车产品外观与结构的设计。

  • 龙飞宇(无人车工程师):哈尔滨工业大学校友,ROS经验丰富。参与过多项机器人竞赛及其项目。目前负责阿木实验室Rhea无人车项目开发、维护与落地以及刘锦涛博士智能机器人集群项目的工程落地。负责Rhea无人车控制、无人车教学模块的开发与测试。

开源License及版权声明

Apache License Version 2.0, January 2004 http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

  1. Definitions.

    "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

    "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

    "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

    "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.

    "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

    "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

    "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

    "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

    "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution".

    "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

  2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

  3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

  4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    • You must give any other recipients of the Work or Derivative Works a copy of this License; and

    • You must cause any modified files to carry prominent notices stating that You changed the files; and

    • You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and

    • If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

      You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

  5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

  6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

  7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

  8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

  9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

Copyright 2022 AMOVLAB

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

快速上手

本章将讲解如何快速搭建Prometheus仿真环境

提示

Prometheus仿真环境搭建出现相关问题或异常可以前往Prometheus配置常见问题处理 查询相关解决办法,如果没有,可前往阿木社区-Prometheus问答专区或Prometheus微信交流群提问

本教程提供Ubuntu系统下载搭建Prometheus仿真环境以及使用Prometheus仿真镜像系统两种安装方式,任选其中一种方式安装即可。

Ubuntu系统下载搭建Prometheus仿真环境教程除使用手册有介绍外,还搭配有视频教程(如下),用户可参考文档结合视频学习。 Matlab-Gazebo联合仿真展示

提示

虽然使用虚拟机Prometheus仿真镜像系统能够快速搭建环境,但我们仍然建议大家能够从0到1搭建整个Prometheus环境,这对于后面的开发是非常有意义的。也能够让大家能够对整个Prometheus系统能有更深入地理解。

旧版本Prometheus删除

  • 如果已经安装过旧版本的Prometheus项目(指在2022年7月20日之前已完成Prometheus项目的安装),建议先删除Prometheus以及prometheus_px4,然后按照本教程进行安装。

  • .bashrc中prometheus以及prometheus_px4相关环境变量需删除,重新按照本教程添加相关环境变量。

运行第一次仿真

仿真运行依赖于遥控器,需要通过USB数据线将遥控器与仿真电脑进行连接。

如需购买遥控器请点击遥控器购买链接

如果使用其他遥控器,只要数据流能符合目前的程序设计也是可以的。可以查看仿真中的遥控器使用说明中遥控器通道以及含义进行对比。

image.png

输入以下命令启动仿真功能测试脚本文件。

# 请将示例中的{your prometheus path}替换为prometheus的安装路径
cd ${your prometheus path}/Prometheus/Scripts/simulation/px4_gazebo_sitl_test
# 第一次使用时需要给脚本文件添加可执行权限
chmod +x px4_sitl_*
# 启动室外无人机仿真启动脚本
./px4_sitl_outdoor.sh

输入该命令后,会出现一个含有三个标签页的终端以及Gazebo,如下图所示。

图片1.png

第一个标签页内启动ROS主节点,出现图中内容则说明启动正常。

点击终端内的第二个标签页,该标签页为启动PX4以及仿真组件。查看打印信息,出现关键字CON: Got HEARTBEAT, connected. FCU:PX4 Autopilot则证明PX4正常启动,出现Gazebo和无人机则说明仿真组件启动正常。

图片2.png

点击终端内第三个标签页,该标签页为启动Prometheus uav_control_main节点。该界面会打印无人机相关信息,包含无人机状态信息和控制数据。

图片3.png

其中无人机状态信息如下图所示。

图片4.png

控制数据如下图所示。

图片5.png

然后将遥控器SWA档杆打至最底端,此时无人机将解锁进入怠速状态,无人机状态信息如下图所示。

图片7.png

再将遥控器SWB档杆打至中间位置,此时无人机及进入RC_POS_CONTROL控制模式,此时可以通过遥控器控制无人机飞行,无人机状态信息如下图所示。

图片8.png

Prometheus仿真环境配置: Ubuntu

警告

提示

本章Prometheus仿真环境配置教程为Prometheus-v2版本的教程, 需要注意,由于Prometheus-v2版本更新,Prometheus-v1和Prometheus-v2相关项目分支存在差异

Prometheus-v2:Prometheus为main分支,prometheus_px4为1.12.3分支

也就是说如果你要配置Prometheus V1,那么在最开始不能直接git clone,那样会直接下载最新Prometheus 你需要指定分支v1.1下载 如下

git clone -b v1.1 https://gitee.com/amovlab/Prometheus.git

#进入目录检查一下分支
cd Prometheus
git branch
#显示* v1.1代表分支下载正确

Prometheus-v1:Prometheus为v1.1分支,prometheus_px4为1.11.1分支

这个和上面同理,下载时需要指定分支,如下

git clone -b Prometheus_PX4_1.11.1 https://gitee.com/amovlab/prometheus_px4.git

#进入目录检查一下分支
cd prometheus_px4/
git branch
#显示* Prometheus_PX4_1.11.1代表分支下载正确

如果需要搭建Prometheus-v1版本,需要前往Prometheus旧版WIKI

前面已经提到Prometheus项目基于PX4和ROS,目前Prometheus支持在Ubuntu操作系统上运行,因此进行Prometheus仿真环境配置需要在电脑上安装Ubuntu操作系统,在Ubuntu操作系统上需要安装PX4ROSPrometheus以及相关依赖的环境

安装步骤

  1. 安装Ubuntu操作系统以及ROS
  2. prometheus_px4配置
  3. Prometheus配置

Ubuntu系统

提示

Prometheus支持Ubuntu18.04以及Ubuntu20.04操作系统

工具准备

  • Rufus软件
  • Usb3.0接口U盘一个,推荐容量大于16G
  • Ubuntu18.04桌面版镜像文件

Rufus下载

点击链接下载安装Rufus软件,选择图示版本。

image.png

Ubuntu系统镜像下载

Ubuntu18.04

点击链接下载安装Ubuntu18.04系统镜像,选择桌面版镜像,并设置好下载路径确保能找到镜像。

image.png

Ubuntu20.04

Ubuntu20.04系统镜像下载链接

image.png

系统启动盘制作

格式化U盘

警告

在格式U盘之前一定要备份好U盘中的数据!!!!

格式化U盘.png

Rufus软件使用

使用Rufus软件制作启动盘。选择对应的U盘,选择下载好的Ubuntu镜像文件,其余设置与图示相同。等待制作完成关闭即可。

image.png

系统安装

若为双系统安装,需压缩硬盘留出系统安装空间,单系统安装可跳过。

image.png

将U盘插上电脑、重启,在出现品牌logo时按F7进入boot模式,选择启动介质。

1.png

提示

不同品牌电脑,进入boot模式按键不同,可对照下图操作。

快捷键.png

选择启动盘后,选择安装Ubuntu。

20190119013933270.jpg

点击继续下一步。

3.png

选择Normal installation 选项,如下图所示。

4.png

选择Something else 选项,如下图所示。

image.png

选择之前预留的存储空间。

image.png

设置分区根据电脑内存和存储不同而不同,具体参见Ubuntu分区,勾选后点击install now。

image.png

设置用户名及密码,点击继续。

image.png

等待安装完成后,重启。

image.png

对于Ubuntu使用由于国内网络环境影响,强烈建议更改Ubuntu的源,这里的源是指你使用Ubuntu下载东西时所经过的网络途径,默认是国外源,国内使用很慢,且经常出现下载失败,所以强烈建议改源,建议改为阿里源或者清华源 修改方法参见: 改源的两种方法

提示

ROS官方安装教程已经比较完善,Prometheus使用手册不再详细介绍,可参考官方的进行安装。

需要注意的是官方的安装由于国内网络环境影响可能会出现下载缓慢或者失败,这里也提供国内安装方法

fish一键安装:fish一键安装

国内源安装:国内源安装

Ubuntu18.04: ROS-melodic安装教程

Ubuntu20.04: ROS-noetic安装教程

ROS是否安装好可以通过终端依次输入下面指令,运行小乌龟程序来检验,如果可以正常键盘的↑↓←→键控制小乌龟代表正常ROS安装成功

roscore
rosrun turtlesim turtlesim_node
rosrun turtlesim turtle_teleop_key

需注意无论哪种安装方式,其中一定包含构建包的依赖,也就是下面这个安装命令,否则后面安装PX4环境会出现问题

Ubuntu18.04依赖包

sudo apt install python-rosdep python-rosinstall python-rosinstall-generator python-wstool build-essential

Ubuntu20.04依赖包

sudo apt install python3-rosdep python3-rosinstall python3-rosinstall-generator python3-wstool build-essential

prometheus_px4配置

prometheus_px4是Prometheus项目配套使用的PX4固件,Prometheus项目的仿真模块依赖PX4固件以及sitl_gazebo ros功能包。(如果是配置Prometheus到真实无人机上那不需要配置prometheus_px4,因为这个是用于虚拟仿真的,真实无人机不需要)

电脑建议Ubuntu18.04/20.04,内存建议大于等于16G,如果内存不足可以通过增加Swap空间来避免编译爆内存。Ubuntu20.04电脑默认分配swap 2G,如果编译卡住,也可以通过增加swap空间解决,教程链接

更新系统

sudo apt-get update

sudo apt-get upgrade

确保系统在当下版本保持最新

安装prometheus_px4

打开终端输入下面的命令安装prometheus_px4

git clone https://gitee.com/amovlab/prometheus_px4.git

首次安装PX4固件时,需要安装PX4环境

cd prometheus_px4/Tools/setup
source ./ubuntu.sh

安装子模块以及相关依赖

注意

请将示例中的{your_prometheus_px4_path}替换为prometheus_px4的安装路径。

cd prometheus_px4
git submodule update --init --recursive #下载子模块可能会有些慢稍等,下载完可以再运行,如果下载好是不会显示什么的
pip3 install --user toml empy jinja2 packaging

编译prometheus_px4

cd prometheus_px4
make amovlab_sitl_default gazebo_p450

编译对于CPU性能和内存有一定要求,内存建议16G及以上,CPU性能建议i7 10代及以上,安装Ubuntu18.04相比20.04对于性能要求相对低一些

编译结束后,会自动运行gazebo仿真环境并加载P450无人机

如果遇到错误无法如下图显示,见下面常见错误解决

prometheus_px4_make.png

常见报错如下图所示

1.启动仿真环境时部分电脑可能出现下面这种报错信息,但只要仿真环境和P450无人机可以正常加载就可以忽略相关报错。

prometheus_px4_error.png

2.如果出现“Waiting for simulator to accept connection on TCP port 4560”并且一直保持,并且往上看显示lookup error:........./libgazebo_common.so.9,如下图 ,那么关闭终端,单独打开gazebo软件,不出意外是没有反应,这个错误原因:ignition-math库太老了,需要更新。 运行下面代码

sudo apt upgrade libignition-math2

59ce7708b4741e9029c0fea54c5fea7.jpg

3.如果错误显示'amovlab_sitl_default'failed ,中间错误显示error:'........../libignition-common.so.1.0.1',如下图所示,这个是系统缺少libignition-common_1.0.1-1 点击ignition-common,下载libignition-common_1.0.1-1_amd64.deb,右键->用软件安装打开

3745f7ff7e1991622064ef7b16ae830.jpg

4.如果出现错误显示“could not find a package configuration file provided by "gazebo" with any”,这个是缺少gazebo中的配置文件 运行下面代码

sudo apt-get install ros-melodic-gazebo-dev

2023-03-13 14-14-07 的屏幕截图.png

ubuntu的终端中遇到错误不要慌,根据终端错误提示,将提示复制,百度搜索,一般都可以解决

Prometheus配置

安装Prometheus

打开终端输入以下命令安装Prometheus项目。

git clone https://gitee.com/amovlab/Prometheus.git

安装prometheus_mavros

prometheus_mavros是Prometheus项目配套使用的MAVROS功能包,Prometheus项目与PX4连接进行数据交互依赖于MAVROS功能包。

打开终端输入以下命令安装prometheus_mavros。

注意

请将示例中的{your_prometheus_path}替换为Prometheus的安装路径。

cd Prometheus/Scripts/installation/prometheus_mavros
chmod +x install_prometheus_mavros.sh
./install_prometheus_mavros.sh

Prometheus_mavros.png

安装完毕后关闭当前终端窗口,打开新的终端输入以下命令测试prometheus_mavros是否正常安装完毕以及环境变量是否正常加载。

roscd mavros

如果出现路径为~/prometheus_mavros/src/mavros/mavros则证明安装成功。

roscd_mavros.png

如果上面执行后没有报错,但是roscd mavros 并不能成功,那么打开.bashrc文件

sudo gedit ~/.bashrc

正常情况下.bashrc里显示了ROS的环境"source /opt/ros/melodic/setup.bash",这时添加mavros如下所示

source ~/prometheus_mavros/devel/setup.bash

Screenshot from 2023-05-05 09-37-48.png

保存退出,再终端中更新环境变量

source .bashrc

roscd mavros

如果还没有成功那么就是前面有错误,仔细看看运行过程中是否异常,报错。

依赖项下载

遥控器仿真驱动安装

## 安装遥控器仿真驱动
sudo apt-get install jstest-gtk
## 安装完成之后,可以在终端中运行如下指令确认遥控器是否正常以及摇杆和按钮的响应情况
jstest-gtk

Gazebo模型库下载

 cd ~/.gazebo/
 # 如果之前没有models文件夹的话,创建models文件夹
 mkdir -p models
 cd ~/.gazebo/models/
 # 这个仓库是从官方仓库(https://github.com/osrf/gazebo_models)复制过来的,会定期更新
 git clone https://gitee.com/amovlab/gazebo-models.git

nlink_parser安装

nlink_parser为UWB驱动功能包,目前仅支持nooploop相关UWB产品

# 通过git clone方式下载功能包,参考README配置该功能包
git clone https://github.com/nooploop-dev/nlink_parser.git

vrpn_client_ros安装(可选)

vrpn_client_ros功能包为动捕定位系统应用所依赖的ROS功能包,如果使用动捕定位则需要下载该功能包

sudo apt-get install ros-melodic-vrpn-client-ros

编译Prometheus

输入以下命令编译Prometheus项目。

cd Prometheus 

# 第一次使用时需要给编译脚本文件添加可执行权限
chmod +x compile_*

# 编译控制功能模块
./compile_control.sh

compile_control.png

目前提供四个编译脚本:

编译脚本文件编译模块
compile_all.sh编译全部功能模块,包含基础模块、通信模块、Gazebo仿真模块、控制模块、demo模块、规划模块、目标检测模块
compile_control.sh编译控制功能相关模块,包含基础模块、Gazebo仿真模块、控制模块、demo模块
compile_planning.sh编译规划功能相关模块,包含基础模块、Gazebo仿真模块、控制模块、规划模块
compile_detection.sh编译视觉功能相关模块,包含基础模块、Gazebo仿真模块、控制模块、demo模块、目标检测模块

警告

  • 目标检测模块能编译通过,并不代表所有功能都能正常运行
  • 目标检测模块大部分功能都需要Nvidia显卡,CUDA环境支持,具体请看视觉功能汇总
  • 如果需要使用完整目标检测模块,请前往目标检测模块介绍完成相关依赖环境安装

提示

用户可根据自身情况选择其中一个编译脚本文件运行,可避免不需要的功能模块带来的环境或编译问题。

其他配置

环境变量配置

打开终端输入以下命令打开.bashrc文件。

sudo gedit ~/.bashrc

将以下内容复制到.bashrc文件中后保存退出,如果.bashrc已有相关内容,则无需重复添加。

提示

其中{your prometheus path}为Prometheus项目路径,{your px4 path}为安装prometheus_px4固件的路径。

source {your prometheus path}/Prometheus/devel/setup.bash

export GAZEBO_PLUGIN_PATH=$GAZEBO_PLUGIN_PATH:{your prometheus path}/Prometheus/devel/lib
export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:{your prometheus path}/Prometheus/Simulator/gazebo_simulator/gazebo_models/uav_models
export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:{your prometheus path}/Prometheus/Simulator/gazebo_simulator/gazebo_models/ugv_models
export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:{your prometheus path}/Prometheus/Simulator/gazebo_simulator/gazebo_models/sensor_models
export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:{your prometheus path}/Prometheus/Simulator/gazebo_simulator/gazebo_models/scene_models
export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:{your prometheus path}/Prometheus/Simulator/gazebo_simulator/gazebo_models/texture

source {your px4 path}/prometheus_px4/Tools/setup_gazebo.bash {your px4 path}/prometheus_px4 {your px4 path}/prometheus_px4/build/amovlab_sitl_default
export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:{your px4 path}/prometheus_px4
export ROS_PACKAGE_PATH=$ROS_PACKAGE_PATH:{your px4 path}/prometheus_px4/Tools/sitl_gazebo

以下图为例,Prometheus安装在/home文件夹下,可用~代表。~/Prometheus/home/amov/Prometheus等效。示例中的amov为用户名,如果使用/home/{user}/Prometheus这种形式的需要将用户名更改。

prometheus_px4环境变量.png

Prometheus仿真环境配置:Prometheus镜像

提示

Prometheus镜像支持在虚拟机上安装使用 ,但若是想在双系统上安装Prometheus镜像,需注意必须使用Rufus 3.19以上版本软件去制作系统启动盘。另外,在双系统下安装Prometheus镜像兼容性较差,不太容易成功。

Prometheus镜像系统基于Ubuntu18.04操作系统,大小约10个G,镜像系统已提前安装并配置好Prometheus、prometheus_mavros以及prometheus_px4以及相关依赖环境,可以直接上手使用Prometheus。

虚拟机安装Prometheus镜像

安装准备

注意

这里提供的Prometheus镜像只是为了方便用户安装,安装后并不是就可以直接上手使用Prometheus,用户需要按照wiki中操作配置Prometheus

如果用户不想要配置或者时间紧急需要快速上手Prometheus仿真,阿木实验室提供仿真套件供用户购买,到手即用,包含仿真遥控器

购买链接

仿真套件wiki

Prometheus镜像下载链接

提供的下载链接为百度网盘方式,提取码为amov

注意

此处提到的Prometheus镜像系统为Prometheus-v2版本(指2022年7月15日发布的新版Prometheus),此前的Prometheus-v1版本镜像请点击下方链接进行下载

Prometheus-v1镜像下载链接

提供的下载链接为百度网盘方式,提取码为amov

安装步骤

首先,创建一个新的虚拟机。

1.png

选择自定义安装,点击下一步。

2.png

选择稍后安装操作系统,继续下一步。

3.png

选择Linux操作系统,版本为Ubuntu64位。

4.png

根据电脑配置和需求选择合适的虚拟机处理器配置和内存大小。

5.png

6.png

7.png

接下来按照引导推荐选择即可。

8.png

9.png

10.png

根据需求选择合适的磁盘大小,至少大于30G空间,推荐60G空间以上,其余根据引导推荐完成安装。

11.png

14.png

创建虚拟机之后,在虚拟机设置中选择使用Prometheus镜像,然后点击运行虚拟机。

13.png

选择Boot system installer,按下回车。

15.png

进入登录界面,输入密码 amov,即可进入Prometheus镜像系统开始安装。

16.png

开始安装镜像系统,配置用户名和密码。

17.png

选择之前创建的虚拟磁盘分区,点击delete。

18.png

选中虚拟磁盘分区,再选择生成的新磁盘大小,再点击右边的绿色箭头分配。

19.png

将生成的四个新虚拟磁盘分别设置为 “/” , “/home" , "/SWAp" , "/boot/efi"。

21.png

注意要勾选传递用户配置文件,如何点击next。

22.png

点击start后,耐心等待镜像安装完成。

23.png

安装完成点击reboot重启后即可使用Prometheus镜像系统。

24.png

Prometheus配置常见问题处理

  1. 更新子模块遇到报错

    尝试输入以下命令解决。

    make distclean
    git submodule update --init --recursive
    
  2. arm-none-eabi-gcc安装失败或者版本不对

    一定要使用prometheus_px4/Tools/setup目录下的ubuntu.sh进行安装,如果使用PX4官方master分支下的对应文件则会安装高级版本的arm-none-eabi-gcc,会使得编译prometheus_px4出错,可通过下面的命令查看查看arm-none-eabi-gcc版本。

    arm-none-eabi-gcc --version
    

    prometheus_px4对应的版本是gcc version 9-2020-q2-update(其他版本gcc可能也支持,只要能顺利编译固件即可),如果之前已经安装过最新的arm-none-eabi-gcc,请重新运行ubuntu.sh文件后,重启电脑。

    安装失败一般是由于网络原因导致,在运行ubuntu.sh文件时,请耐心查看安装记录,下载arm-none-eabi-gcc有时会因为网络原因而自动放弃下载,此时,也只需要反复运行ubuntu.sh文件直至安装成功。

  3. 缺少gstreamer依赖

    输入以下命令安装相关依赖。

    sudo apt-get install libgstreamer1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio
    
  4. 编译prometheus_px4时提示"Failed to import numpy: No module named 'numpy' "

    输入以下命令安装numpy。

    pip3 install --user numpy
    
  5. prometheus_mavros安装时出现rosdep update 错误

    # 需要科学上网
    rosdep update
    

Prometheus仿真入门

本章将为大家介绍Prometheus仿真涉及的基础内容。

在本章内容中,会首先介绍一些常用开发工具的安装,这些工具能帮助大家更好地进行开发,能够提升开发效率,大家可以从中找出比较适合自己的工具下载即可。

接下来会介绍PX4-Gazebo的仿真原理,能够让大家快速了解掌握仿真各模块的框架,也能了解到Prometheus、PX4、Gazebo中各个功能模块的关系,强烈建议大家熟悉这一块内容,当掌握了仿真框架,再去了解真机相关内容后,基本上就能够明白如何将仿真代码移植到真机中。

然后是Prometheus代码框架及功能汇总,介绍Prometheus项目的代码框架、消息文件以及功能汇总。

最后是仿真中的遥控器说明,这一块将详细介绍Prometheus仿真中遥控器操作相关内容,这一节内容较为重要,需要完全掌握全部内容。

常用开发工具的安装

  • VSCode

    VSCode(全称:Visual Studio Code)是一款由微软开发且跨平台的免费源代码编辑器。该软件支持语法高亮、代码自动补全(又称 IntelliSense)、代码重构、查看定义功能,并且内置了命令行工具和 Git 版本控制系统。用户可以更改主题和键盘快捷方式实现个性化设置,也可以通过内置的扩展程序商店安装扩展以拓展软件功能。

    VSCode下载地址

    打开VSCode下载地址后将出现以下界面,点击.deb下载方式。

    image.png

    一般情况下默认下载在Downloads文件夹下,输入以下命令进行安装。

    	cd ~/Downloads
    	sudo dpkg -i ***.deb
    
  • NoMachine

    NoMachine是一款远程桌面工具,在高延迟低带宽的通信链路上也有较好地表现。

    NoMachine下载地址

    image.png

    建议大家使用.deb下载方式,下载完后安装命令与VSCode安装方式一致。

  • QGroudControl

    QGroundControl简称QGC,是一款与PX4飞控通信连接进行交互的地面站软件,官方网站对于下载安装的说明已经非常完善了,此处不再过多讲解,大家参考官网即可完成下载安装。

    QGroundControl下载地址

PX4-Gazebo仿真说明

在介绍PX4-Gazebo仿真之前,我们先介绍一下基于PX4的旋翼无人机系统

PX4无人机框架图.png

首先,先了解一下上面这幅PX4无人机框架图,可以看到PX4旋翼无人机包含机架、电机、旋翼、飞控(飞行控制板)、脚架等必需模块,这是无人机实现飞行移动的基础。

其次还包含图传、数传、GPS、激光雷达、视觉传感器等模块,这一块非必需模块和无人机应用场景相关,根据不同的场景会搭载其余模块。

其中,我们需要清楚地认识到真实无人机能够实现飞行功能就必须要有上面所说的必需模块以及配套的软件系统。

PX4-Gazebo仿真框架.png

而在仿真当中,我们并不需要这些硬件模块,但是我们需要通过软件来模拟这些硬件模块的数据交互。

其中Gazebo为我们提供了一个物理环境的模拟系统,例如无人机以及飞行环境的可视化物理属性碰撞属性等。

而PX4完成了对无人机物理模型以及运动控制模型的搭建、运动控制插件飞行控制系统等内容。

基于PX4-Gazebo的仿真系统能够完全实现无人机飞行控制的全部功能,除了性能,其余方面与真机表现并无差异.可以简单理解为Gazebo提供无人机硬件仿真,而PX4提供飞控仿真,当然无人机硬件仿真也是由PX4项目组完成,Gazebo仅仅是提供一个物理仿真平台。

关于PX4-Gazebo仿真更多的内容可参考PX4-Gazebo官网介绍

Prometheus代码框架及功能汇总

Prometheus代码框架图

提示

Prometheus代码框架图仅展示主要内容,并未包含所有文件。

Prometheus代码框架主要包含ExperimentScriptsSimulatorModules四个模块:

  • Experiment

    与阿木实验室Z410无人机配套的真机代码,其余安装有Prometheus项目的无人机也可以通过该模块内容适配Prometheus项目,但可能需要修改部分参数,详情请查看Prometheus真机教程

  • Modules

    Modules作为Prometheus项目最重要的组成部分,包含各个功能子模块的全部源代码,主要包括通用子模块、控制子模块、教程子模块、目标检测子模块、规划子模块等功能源代码。

  • Scripts

    Scripts下有installationsimulation两大部分,其中installation包含目标检测子模块环境安装脚本以及prometheus_mavros安装脚本,simulation包含各仿真功能启动脚本以及测试脚本。

  • Simulator

    提供基于PX4-Gazebo的Prometheus仿真代码,包含无人机、传感器、二维码以及环境等相关模型,控制插件以及仿真launch文件等。

Prometheus_msgs说明

ArucoInfo: Aruco二维码的信息, 标定相机后可估计二维码的位姿

MultiArucoInfo: ArucoInfo的数组形式

BoundingBox: 表示目标检测的分类,边框坐标,置信度

BoundingBoxes: BoundingBox的数组形式

DetectionInfo: 目标检测反馈信息,包含对目标、类别、位姿估计

MultiDetectionInfo: DetectionInfo的数组形式

FormationAssign: 集群队形位置分配

GPSData: GPS经纬度以及海拔高度

MultiUAVState: 多架无人机状态

OffsetPose: 无人机ENU坐标系下的定位数据位置偏移量

SwarmCommand: 集群控制指令,包含位置控制、控制模式设置、队形变换设置、队形间距设置等.

TextInfo: 无人机向地面站反馈文本消息

UAVCommand: 无人机控制指令,包含控制命令设置、惯性系、机体系、轨迹、姿态、经纬度、位置、速度、加速度等多种控制模式

UAVControlState: 无人机控制状态

UAVSetup: 无人机设置,包含解上锁、设置px4飞行模式、设置控制模式、重启飞控

UAVState: 无人机状态,包含飞行模式、连接状态、定位来源、gps状态、位置、速度、姿态等信息

Prometheus项目功能模块组成

uav_control:Prometheus项目中的基础模块,负责其余上层功能模块与底层MAVROS进行数据交互的接口

gazebo_simulator:仿真模块,包含室内外无人机仿真模型、仿真环境、Gazebo插件以及仿真启动的launch文件等内容

turtorial_demo: 示例模块,包含Prometheus项目绝大部分功能模块的基础教程源代码以及相应的启动lauch文件

planning: 路径规划模块

object_detection:视觉检测模块

swarm_control:集群控制模块

matlab_bridge:matlab子模块

仿真中的遥控器使用说明

在真实飞行过程中,我们使用真实的遥控器作为控制无人机的主要操作来源,遥控器始终拥有最高的权限,精湛的遥控器操作手法可以保证无人机安稳着陆,但对于很多非专业来说,遥控的操作技巧是需要不断的练习的。我们始终强调一个观念,仿真与实机结合,这样更加符合开发流程,在以往的仿真中,我们通过键盘控制无人机飞行,并不能真实的反应出实机飞行时该怎么操作,也是基于现在存在的种种问题,为了让仿真与实机结合的更加完美,在Prometheus中增加遥控器控制方式,与真机使用更加对应起来,更加容易上手进行二次开发。

遥控器通道和方向

FS-i6S.png

  1. 开关机按钮,开关机需要同时按下两个按钮,开机时需要所有档杆开关打至最上端
  2. 摇杆
  3. 档杆开关,从左到右依次为SWA、SWB、SWC、SWD
遥控器通道含义
右摇杆(左右)通道1滚转(向左推,无人机向左移动)
右摇杆(上下)通道2俯仰(向上推,无人机向前飞)
左摇杆(上下)通道3油门(向上推,无人机向上飞)
左摇杆(左右)通道4偏航(向左推,无人机向左转弯)
SWA(两段开关)通道5解锁/上锁开关
SWB(三段开关)通道6Prometheus控制模式切换,分别对应INIT-RC_POS_CONTROL-COMMAND_CONTROL
SWC(三段开关)通道7KILL开关,也可以留作用户自定义
SWD(两段开关)通道8Prometheus中的LAND模式

仿真电脑和遥控器连接

仿真电脑和遥控器通过Micro USB数据线连接

Micro USB数据线

image.png

仿真电脑与遥控器连接图

USB连接电脑.jpg

Prometheus控制模式包含四种,分别是INITRC_POS_CONTROLCOMMAND_CONTROLLAND_CONTROL下图为无人机运行时的控制状态机图

Prometheus控制状态机图.png

无人机各种情况下的操作说明

无人机档杆情况说明

SWA/SWC/SWD档杆都属于触发型,而SWB档杆属于维持型,SWA档杆执行解上锁操作,触发解锁操作需要从上往下拨这个动作,而不是SWA档杆处于底部,而SWB切换到某一模式,是因为档杆处于那个位置,而不是拨的动作。

无人机未解锁时

1.仅能通过SWA档杆进行解锁上锁操作,SWB档杆无法切换控制模式,SWD无法切换到降落模式。

2.将SWB档杆拨到中间位置时,无人机解锁后会直接进入RC_POS_CONTROL,而直接拨到底部位置时,无人机解锁后无法进入COMMAND_CONTROL,因为需要先进入RC_POS_CONTROL才能切入到COMMAND_CONTROL模式。

无人机解锁并处于INIT(PX4处于Position模式)模式时

1.处于地面时可执行上锁操作。

2.可使用摇杆控制无人机移动。

3.可切入RC_POS_CONTROL模式。

4.无法切入LAND_CONTROL模式(需要在RC_POS_CONTROL或LAND_CONTROL模式下)。

5.无法直接切入COMMAND_CONTROL模式(档杆以及软件都需要先进入RC_POS_CONTROL模式)。

6.将SWB档杆快速切入到COMMAND_CONTROL模式时,会导致系统异常,此时,档杆处于COMMAND_CONTROL模式,但无人机上一状态为INIT模式,导致无人机无法正常进入COMMAND_CONTROL模式。

无人机解锁并处于RC_POS_CONTROL(PX4处于OFFBOARD模式)模式时

1.无人机此时会离地一定高度,不能上锁。

2.可切入LAND_CONTROL。

3.可切入COMMAND_CONTROL。

无人机解锁并处于COMMAND_CONTROL(PX4处于OFFBOARD模式)模式时

1.可切入LAND_CONTROL。

2.可切入RC_POS_CONTROL。

3.将SWB档杆快速移动至顶端可直接切入到INIT模式。

无人机遥控器操作正常流程

1.将SWA/SWB/SWC/SWD档杆全部打到最顶端。

2.启动相关功能代码脚本。

3.将SWA档杆切入到底端进行解锁。

4.无人机解锁后将SWB档杆切入到RC_POS_CONTROL模式,缓慢升高到一定高度。

5.将SWB档杆切入到COMMAND_CONTROL模式,无人机进行自主飞行。

6.自主飞行任务结束后将SWD档杆拨到底端,无人机自主降落。

无人机定位异常无法正常飞行

1.此时无人机将触发保护机制,进行快速降落。

2.如果快速降落依然存在安全风险或无人机已经失控,则将SWC档杆向下拨,无人机电机将停转。

无人机在COMMAND_CONTROL模式下需要人为接管

1.将SWB档杆拨到中间位置或最顶端位置切换至RC_POS_CONTROL或INIT人为进行操作。

无人机控制模块 - uav_control

uav_control代码框架

uav_control包含两个功能模块uav_controller(无人机控制)和uav_estimator(无人机状态);

uav_controller模块一次循环的的核心逻辑为:

  1. 无人机状态检查,包含飞控连接状态、定位状态、地理围栏等
  2. 检查无人机控制状态,包含INIT、RC_POS_CONTROL、COMMAND_CONTROL、LAND_CONTROL四种控制状态并对控制变量进行赋值
  3. 如果无人机状态为INIT则本次循环结束
  4. 下发控制指令

uav_estimator模块一次循环的的核心逻辑为:

  1. 订阅无人机状态、电池状态、无人机定位数据、外部定位数据等
  2. 如果使用外部定位数据,则将定位数据下发到MAVROS
  3. 打印显示无人机相关数据
  4. 发送相关提示信息到地面站

下图为uav_control模块代码运行流程

uav_control代码框架图

uav_control_node介绍

uav_control模块相关源代码放置在Prometheus/Modules/uav_control文件夹下,对应的ROS功能包名为prometheus_uav_control。该模块为Prometheus项目的基础模块,完成Prometheus其他功能模块与mavros节点进行数据交互。

发布话题和订阅话题中均带有命名空间/uav*,无人机编号不同则对应的命名空间不同,一般情况下默认为/uav1

发布话题

  • /uav*/mavros/setpoint_raw/attitude(mavros_msgs/AttitudeTarget)

    期望的无人机姿态控制量

  • /uav*/mavros/setpoint_raw/global(mavros_msgs/GlobalPositionTarget)

    期望的无人机经纬高控制量

  • /uav*/mavros/setpoint_raw/local(mavros_msgs/PositionTarget)

    期望的无人机ENU坐标系的控制量(包含位置、速度、加速度等)

  • /uav*/mavros/vision_pose/pose(geometry_msgs/PoseStamped)

    MAVROS提供的外部定位数据接口

  • /uav*/prometheus/control_state(prometheus_msgs/UAVControlState)

    Prometheus控制状态

  • /uav*/prometheus/odom(nav_msgs/Odometry)

    无人机里程计数据

  • /uav*/prometheus/offset_pose(prometheus_msgs/OffsetPose)

    ENU坐标系下的位置偏移量

  • /uav*/prometheus/state(prometheus_msgs/UAVState)

    无人机状态合集,包括位置\速度\姿态\模式等

  • /uav*/prometheus/text_info(prometheus_msgs/TextInfo)

    反馈到地面站的打印信息

  • /uav*/prometheus/trajectory(nav_msgs/Path)

    无人机运动轨迹

  • /uav*/prometheus/uav_mesh(visualization_msgs/Marker)

    无人机位置(带图标),用于RVIZ显示

订阅话题

  • /uav*/mavros/battery(sensor_msgs/BatteryState)

    无人机电池状态

  • /uav*/mavros/global_position/global(sensor_msgs/NavSatFix)

    无人机当前经纬度数据,经飞控融合过后的数据.

  • /uav*/mavros/gpsstatus/gps*/raw(mavros_msgs/GPSRAW)

    GPS模块数据状态

  • /uav*/mavros/imu/data(sensor_msgs/Imu)

    IMU模块数据

  • /uav*/mavros/local_position/pose(geometry_msgs/PoseStamped)

    无人机ENU坐标系下的位置数据

  • /uav*/mavros/local_position/velocity_local(geometry_msgs/TwistStamped)

    无人机ENU坐标系的当前速度数据

  • /uav*/mavros/setpoint_raw/target_attitude(mavros_msgs/AttitudeTarget)

    PX4中无人机的姿态设定值 (坐标系:ENU系)

  • /uav*/mavros/setpoint_raw/target_local(mavros_msgs/PositionTarget)

    PX4中无人机的位置/速度/加速度设定值(坐标系:ENU系)

  • /uav*/mavros/state(mavros_msgs/State)

    无人机当前状态(PX4)

  • /uav*/prometheus/command(prometheus_msgs::UAVCommand)

    无人机控制指令(用于COMMAND_CONTROL模式)

  • /uav*/prometheus/fake_rc_in(mavros_msgs/RCIn)

    PX4遥控器数据

  • /uav*/prometheus/offset_pose(prometheus_msgs::OffsetPose)

    ENU坐标系下的位置偏移量

  • /uav*/prometheus/set_local_offset_pose(prometheus_msgs::OffsetPose)

    设置ENU坐标系下无人机的位置偏移量

  • /uav*/prometheus/setup(prometheus_msgs/UAVSetup)

    无人机设置指令

  • /uav*/prometheus/state(prometheus_msgs/UAVState)

    无人机状态合集,包括位置、速度、姿态、模式等

参数

  • uav_id:

    参数说明: 无人机编号

    单位: -

    数据类型: int

    默认值: 1

    备注: 无

  • sim_mode:

    参数说明: 是否为仿真

    单位: -

    数据类型: bool

    默认值: true

    备注: true代表为仿真模式,false代表为非仿真模式

  • control/pos_controller:

    参数说明: 控制器标志位

    单位: -

    数据类型: int

    默认值: 0

    备注: 0: PX4_ORIGIN, 1: PID, 2: UDE, 3: NE

  • control/enable_external_control:

    参数说明: 是否使用外部控制器

    单位: -

    数据类型: bool

    默认值: false

    备注: true代表使用外部控制器,false代表不使用外部控制器

  • control/Takeoff_height:

    参数说明: 起飞高度(command_control模式下的起飞高度)

    单位: 米

    数据类型: float

    默认值: 1.0

    备注: 无

  • control/Disarm_height:

    参数说明: land_control模式下自动上锁的高度

    单位: 米

    数据类型: float

    默认值: 0.2

    备注: 无

  • control/Land_speed:

    参数说明: land_control模式下下降的速度

    单位: 米

    数据类型: float

    默认值: 0.2

    备注: 位置坐标系为ENU坐标系

  • control/location_source:

    参数说明: 定位数据来源

    单位: 无

    数据类型: int

    默认值: 4

    备注: 0: MOCAP, 1: T265, 2: GAZEBO, 3: FAKE_ODOM, 4: GPS, 5: RTK, 6: UWB

  • control/maximum_safe_vel_xy:

    参数说明: XY轴最大安全速度

    单位: 米/秒

    数据类型: float

    默认值: 4.0

    备注: 无

  • control/maximum_safe_vel_z:

    参数说明: Z轴最大安全速度

    单位: 米/秒

    数据类型: float

    默认值: 3.0

    备注: 无

  • control/maximum_vel_error_for_vision:

    参数说明: 最大vision/px4速度误差

    单位: 米/秒

    数据类型: float

    默认值: 1.0

    备注: 无

  • geo_fence/x_min:

    参数说明: 地理围栏X轴最小值

    单位: 米

    数据类型: float

    默认值: -100.0

    备注: 位置坐标系为ENU坐标系

  • geo_fence/x_max:

    参数说明: 地理围栏X轴最大值

    单位: 米

    数据类型: float

    默认值: 100.0

    备注: 位置坐标系为ENU坐标系

  • geo_fence/y_min:

    参数说明: 地理围栏Y轴最小值

    单位: 米

    数据类型: float

    默认值: -100.0

    备注: 位置坐标系为ENU坐标系

  • geo_fence/y_max:

    参数说明: 地理围栏Y轴最大值

    单位: 米

    数据类型: float

    默认值: 100.0

    备注: 位置坐标系为ENU坐标系

  • geo_fence/z_min:

    参数说明: 地理围栏Z轴最小值

    单位: 米

    数据类型: float

    默认值: -100.0

    备注: 位置坐标系为ENU坐标系

  • geo_fence/z_max:

    参数说明: 地理围栏Z轴最大值

    单位: 米

    数据类型: float

    默认值: 100.0

    备注: 位置坐标系为ENU坐标系

无人机控制模块教学例程

提示

尝试运行无人机控制模块教学例程前需要掌握仿真入门中仿真中的遥控器使用说明

学习无人机控制模块教学例程需要掌握一定的UbuntuROSC++/Python基础

无人机控制模块作为Prometheus项目的基础子模块,Prometheus项目中其余子模块均会通过控制模块与无人机进行数据交互。所以学习Prometheus项目以及通过Prometheus项目进行无人机二次开发都是需要先从控制模块开始学习。

在控制模块我们提供了对应的教学例程,包含起飞降落惯性系控制机体系控制经纬高控制轨迹控制以及集群控制六个教学例程。通过教学例程大家能够快速了解控制模块的相关数据接口,也能够通过学习例程demo的源码学习Prometheus控制模块的二次开发

教学例程提供有C++以及Python两种语言的源码,用户可自行选择相应的源码文件进行学习。

  • 控制模块源码文件位置:/Prometheus/Modules/uav_control
  • 教学例程demo源码文件:/Prometheus/Modules/tutorial_demo/basic

无人机控制模块教学例程 - 起飞降落

<span style="display: flex; flex-direction: column; width: 100%"> <img src = https://qiniu.md.amovlab.com/img/m/202206/20220630/1050113953508024345067520.gif>

运行结果展示

起飞降落demo对应脚本文件位于 ~/Prometheus/Scripts/simulation/tutorial_demo/takeoff_land/takeoff_land_P450.sh

操作步骤

  1. 将遥控器开机并通过USB接口接入电脑

  2. 输入以下命令启动起飞降落仿真demo

    cd ~/Prometheus/Scripts/simulation/tutorial_demo/takeoff_land
    # 第一次启动该脚本时,需要添加可执行权限
    chmod +x takeoff_land_P450.sh
    ./takeoff_land_P450.sh
    
  3. 遥控器SWA档杆向下拨解锁无人机

  4. 遥控器SWB档杆拨到中间位置将无人机控制状态切换到RC_POS_CONTROL

  5. 遥控器SWB档杆拨到最底部将无人机控制状态切换到COMMAND_CONTROL

  6. 无人机将自动起飞,到达预设高度后悬停30秒,随后自动降落

检查终端运行是否正常

  • ros主节点
    • 下图所示为正常运行

74.png

  • PX4飞控仿真
    • 下图所示为正常运行

75.png

  • Prometheus控制
    • 下图所示为正常运行

76.png

  • Prometheus控制demo,起飞降落
    • 下图所示为正常运行

77.png

  • 正常启动仿真界面
    • 下图所示为正常运行

78.png

运行仿真功能

  • 拨动遥控器的SW-A拨杆,到最下面,解锁无人机

79.png

  • 拨动遥控器的SW-B拨杆,到中间位置,切换到RC_POS_CONTROL模式

80.png

  • 拨动遥控器的SW-B拨杆,到最下面,切换到COMMAND_CONTROL模式

81.png

  • 此时无人机会在初始点悬停

82.png

  • 在COMMAND_CONTROL模式下可以使用代码控制无人机飞行了,此处运行代码控制无人机,到达预设高度后悬停30秒,随后自动降落

83.png

节点运行图

起飞降落节点运行图.png

起飞降落例程主要包含 /joy_node/uav1/mavros/uav_control_main_1/takeoff_land等ROS节点。

  • /joy_node节点为遥控器ROS驱动节点,用以获取遥控器数据。
  • /uav1/mavros节点为飞控ROS驱动节点,与飞控进行数据交互。在仿真中,该驱动节点与模拟飞控进行数据交互。
  • /uav_control_main_1节点为Prometheus项目中最基础的ROS节点,所有Prometheus项目的功能模块都通过该节点与无人机进行数据交互。
  • /takeoff_land节点为起飞降落节点,通过 /uav_control_main_1节点提供的数据接口获取无人机数据以及控制无人机。

从节点运行图中,我们可以看到 /takeoff_land节点与 /uav_control_main_1节点进行数据交互主要有三个ROS话题

  • /uav1/prometheus/command:无人机控制接口,对应的消息为 prometheus_msgs/UAVCommand
  • /uav1/prometheus/state:无人机状态,对应的消息为 prometheus_msgs/UAVState
  • /uav1/prometheus/control_state:无人机控制状态,对应的消息为 prometheus_msgs/UAVControalState

建议阅读 /Prometheus/Modules/common/prometheus_msgs/msg内对应的消息文件,了解上面提到的三个消息的详细定义。

代码讲解

源码文件名为 takeoff_land.cpp

位于 /Prometheus/Modules/tutorial_demo/basic/takeoff_land/src文件夹下

起飞降落demo-1.png

起飞降落demo-2.png

该demo为Prometheus 起飞&降落控制接口开发示例,核心代码如上图所示;主要是填充以下数据:

  1. Agent_CMD设置为Init_Pos_Hover模式,该模式为起飞;Agent_CMD设置为Land,该模式为降落
  2. 每发送一次数据,Command_ID加1
  3. 时间戳通过调用 ros::Time::now()函数获取当前ROS系统时间并赋值即可,frame_id并不影响功能,但建议与控制命令所采用的坐标系一致。

无人机控制模块教学例程 - 惯性系控制

运行结果展示

惯性系控制demo对应脚本文件位于~/Prometheus/Scripts/simulation/tutorial_demo/enu_xyz_pos_control/enu_xyz_pos_control_P450.sh

操作步骤

  1. 将遥控器开机并通过USB接口接入电脑

  2. 输入以下命令启动惯性系移动仿真demo

    cd ~/Prometheus/Scripts/simulation/tutorial_demo/enu_xyz_pos_control
    # 第一次启动该脚本时,需要添加可执行权限
    chmod +x enu_xyz_pos_control_P450.sh
    ./enu_xyz_pos_control_P450.sh
    
  3. 遥控器SWA档杆向下拨解锁无人机

  4. 遥控器SWB档杆拨到中间位置将无人机控制状态切换到RC_POS_CONTROL

  5. 遥控器SWB档杆拨到最底部将无人机控制状态切换到COMMAND_CONTROL

  6. 无人机将自动起飞,飞行到预设位置(ENU坐标系下(1,0,1)坐标点)后将悬停30秒,随后降落

检查终端运行是否正常

  • ros主节点
    • 下图所示为正常运行

86.png

  • PX4飞控仿真
    • 下图所示为正常运行

87.png

  • Prometheus控制
    • 下图所示为正常运行

88.png

  • Prometheus惯性系控制demo
    • 下图所示为正常运行

89.png

  • 正常启动仿真界面
    • 下图所示为正常运行

90.png

运行仿真功能

  • 拨动遥控器的SW-A拨杆,到最下面,解锁无人机

91.png

  • 拨动遥控器的SW-B拨杆,到中间位置,切换到RC_POS_CONTROL模式

92.png

  • 拨动遥控器的SW-B拨杆,到最下面,切换到COMMAND_CONTROL模式

93.png

  • 此时无人机会在初始点悬停

94.png

  • 在COMMAND_CONTROL模式下可以使用代码控制无人机飞行了,此处运行代码控制无人机,到达惯性系控制预设点后(ENU坐标系下(1,0,1)坐标点)悬停30秒,随后自动降落

95.png

代码讲解

惯性系移动demo.png

该demo为Prometheus XYZ_POS控制接口开发示例,XYZ_POS为无人机XYZ轴位置(ENU坐标系)的控制模式,核心代码如上图所示;主要是填充以下数据:

  1. Agent_CMD设置为Move模式
  2. Move_mode设置为XYZ_POS
  3. 填充XYZ轴的位置数据
  4. 每发送一次数据,Command_ID加1

无人机控制模块教学例程 - 机体系控制

运行结果展示

机体系控制demo对应脚本文件位于~/Prometheus/Scripts/simulation/tutorial_demo/body_xyz_pos_control/body_xyz_pos_control_P450.sh

操作步骤

  1. 将遥控器开机并通过USB接口接入电脑

  2. 输入以下命令启动机体系移动仿真demo

    cd ~/Prometheus/Scripts/simulation/tutorial_demo/body_xyz_pos_control
    # 第一次启动该脚本时,需要添加可执行权限
    chmod +x body_xyz_pos_control_P450.sh
    ./body_xyz_pos_control_P450.sh
    
  3. 遥控器SWA档杆向下拨解锁无人机

  4. 遥控器SWB档杆拨到中间位置将无人机控制状态切换到RC_POS_CONTROL

  5. 遥控器SWB档杆拨到最底部将无人机控制状态切换到COMMAND_CONTROL

  6. 无人机将自动起飞,飞行到预设位置(body坐标系下(1,0,0)坐标点)后将悬停30秒,随后降落

检查终端运行是否正常

  • ros主节点
    • 下图所示为正常运行

99.png

  • PX4飞控仿真
    • 下图所示为正常运行

100.png

  • Prometheus控制
    • 下图所示为正常运行

101.png

  • Prometheus机体系控制demo
    • 下图所示为正常运行

102.png

  • 正常启动仿真界面
    • 下图所示为正常运行

103.png

运行仿真功能

  • 拨动遥控器的SW-A拨杆,到最下面,解锁无人机

104.png

  • 拨动遥控器的SW-B拨杆,到中间位置,切换到RC_POS_CONTROL模式

105.png

  • 拨动遥控器的SW-B拨杆,到最下面,切换到COMMAND_CONTROL模式

106.png

  • 在COMMAND_CONTROL模式下可以使用代码控制无人机飞行了,此处运行代码控制无人机,到达惯性系控制预设点后(body坐标系下(1,0,0))悬停30秒,随后自动降落

107.png

代码讲解

机体系移动demo.png

该demo为Prometheus XYZ_POS_BODY控制接口开发示例,XYZ_POS_BODY为无人机XYZ轴位置(BODY坐标系)的控制模式,核心代码如上图所示;主要是填充以下数据:

  1. Agent_CMD设置为Move模式
  2. Move_mode设置为XYZ_POS_BODY
  3. 填充XYZ轴的位置数据
  4. 每发送一次数据,Command_ID加1

注意

机体坐标系控制对Command_ID变量有严格限制,当前发送控制命令的Command_ID必须高于上一个控制命令的Command_ID才会执行

无人机控制模块教学例程 - 经纬高控制

<span style="display: flex; flex-direction: column; width: 100%"> <img src = https://qiniu.md.amovlab.com/img/m/202206/20220630/1051424338210948570316800.gif>

运行结果展示

经纬高控制demo对应脚本文件位于 ~/Prometheus/Scripts/simulation/tutorial_demo/global_pos_control/global_pos_control_P450.sh

操作步骤

  1. 将遥控器开机并通过USB接口接入电脑

  2. 输入以下命令启动经纬高控制仿真demo

    cd ~/Prometheus/Scripts/simulation/tutorial_demo/global_pos_control
    # 第一次启动该脚本时,需要添加可执行权限
    chmod +x global_pos_control_P450.sh
    ./global_pos_control_P450.sh
    
  3. 遥控器SWA档杆向下拨解锁无人机

  4. 遥控器SWB档杆拨到中间位置将无人机控制状态切换到RC_POS_CONTROL

  5. 遥控器SWB档杆拨到最底部将无人机控制状态切换到COMMAND_CONTROL

  6. 无人机将自动起飞,飞行到预设位置(无人机当前经纬度,高度5米的位置点)后将悬停30秒,随后降落

注意

高度数据为相对高度,并不是海拔高度

检查终端运行是否正常

  • ros主节点
    • 下图所示为正常运行

110.png

  • PX4飞控仿真
    • 下图所示为正常运行

111.png

  • Prometheus控制
    • 下图所示为正常运行

112.png

  • Prometheus经纬高控制demo
    • 下图所示为正常运行

113.png

  • 正常启动仿真界面
    • 下图所示为正常运行

114.png

运行仿真功能

  • 拨动遥控器的SW-A拨杆,到最下面,解锁无人机

115.png

  • 拨动遥控器的SW-B拨杆,到中间位置,切换到RC_POS_CONTROL模式

116.png

  • 拨动遥控器的SW-B拨杆,到最下面,切换到COMMAND_CONTROL模式

117.png

  • 在COMMAND_CONTROL模式下可以使用代码控制无人机飞行了,此处运行代码控制无人机,到达惯性系控制预设点后(无人机当前经纬度,高度5米的位置点)悬停30秒,随后自动降落

118.png

代码讲解

经纬高控制demo.png

该demo为Prometheus LAT_LON_ALT控制接口开发示例,LAT_LON_ALT为无人机经纬度以及高度位置(WGS84坐标系)的控制模式,核心代码如上图所示;主要是填充以下数据:

  1. Agent_CMD设置为Move模式
  2. Move_mode设置为LAT_LON_ALT
  3. 填充经纬度以及高度数据
  4. 每发送一次数据,Command_ID加1

无人机控制模块教学例程 - 轨迹控制

运行结果展示

轨迹控制demo对应脚本文件位于~/Prometheus/Scripts/simulation/tutorial_demo/circular_trajectory_control/circular_trajectory_control_P450.sh

操作步骤

  1. 将遥控器开机并通过USB接口接入电脑

  2. 输入以下命令启动圆形轨迹追踪仿真demo

    cd ~/Prometheus/Scripts/simulation/tutorial_demo/circular_trajectory_control
    # 第一次启动该脚本时,需要添加可执行权限
    chmod +x circular_trajectory_control_P450.sh
    ./circular_trajectory_control_P450.sh
    
  3. 遥控器SWA档杆向下拨解锁无人机

  4. 遥控器SWB档杆拨到中间位置将无人机控制状态切换到RC_POS_CONTROL

  5. 遥控器SWB档杆拨到最底部将无人机控制状态切换到COMMAND_CONTROL

  6. 无人机将自动起飞,然后飞行一个圆形轨迹后将悬停30秒,随后降落

检查终端运行是否正常

  • ros主节点
    • 下图所示为正常运行

121.png

  • PX4飞控仿真
    • 下图所示为正常运行

122.png

  • Prometheus控制
    • 下图所示为正常运行

123.png

  • Prometheus机体系控制demo
    • 下图所示为正常运行

124 .png

  • 正常启动仿真界面
    • 下图所示为正常运行

125.png

运行仿真功能

  • 拨动遥控器的SW-A拨杆,到最下面,解锁无人机

126.png

  • 拨动遥控器的SW-B拨杆,到中间位置,切换到RC_POS_CONTROL模式

127.png

  • 拨动遥控器的SW-B拨杆,到最下面,切换到COMMAND_CONTROL模式

128.png

  • 在COMMAND_CONTROL模式下可以使用代码控制无人机飞行了,此处运行代码控制无人机,到达惯性系控制预设点后,飞行一个圆形轨迹,并悬停30秒,随后自动降落

129.png

代码讲解

圆形轨迹控制demo.png

该demo为Prometheus XY_VEL_Z_POS控制接口开发示例,XY_VEL_Z_POS为无人机XY轴速度、Z轴位置(ENU坐标系)的控制模式,核心代码如上图所示;主要是填充以下数据:

  1. Agent_CMD设置为Move模式
  2. Move_mode设置为XY_VEL_Z_POS
  3. 填充XY轴的速度数据以及Z轴的位置数据
  4. 每发送一次数据,Command_ID加1

无人机控制模块教学例程 - 集群控制

<span style="display: flex; flex-direction: column; width: 100%"> <img src = https://qiniu.md.amovlab.com/img/m/202206/20220630/1052294532238464493453312.gif>

运行结果展示

集群控制demo对应脚本文件位于 ~/Prometheus/Scripts/simulation/tutorial_demo/formation_control/formation_control_P450.sh

操作步骤

  1. 将遥控器开机并通过USB接口接入电脑

  2. 输入以下命令启动集群控制仿真demo

    cd ~/Prometheus/Scripts/simulation/tutorial_demo/formation_control
    # 第一次启动该脚本时,需要添加可执行权限
    chmod +x formation_control_P450.sh
    ./formation_control_P450.sh
    
  3. 遥控器SWA档杆向下拨解锁无人机

  4. 遥控器SWB档杆拨到中间位置将无人机控制状态切换到RC_POS_CONTROL

  5. 遥控器SWB档杆拨到最底部将无人机控制状态切换到COMMAND_CONTROL

  6. 此时可通过在终端界面输入相关指令控制无人机集群,如下图所示

    • 其中输入0后将输入位置控制数据,控制无人机集群移动
    • 输入1后切换无人机集群队形为一字队形(无人机默认以一字队形飞行)
    • 输入2后切换无人机集群队形为三角队形

代码讲解

  1. 接收终端输入的控制指令(集群位置控制、队形切换)
  2. 将集群控制指令转化为单台无人机控制指令
  3. 下发单台无人机控制指令

spirecv-ros的大致框架

  1. 顶层目录

img

  • cv_bridge_1804/:包含适用于 Ubuntu 18.04 的 cv_bridge 代码。

  • cv_bridge_2004/:包含适用于 Ubuntu 20.04 的 cv_bridge 代码。

  • sv-msgs/:包含消息定义相关的代码。

  • sv-rosapp/:包含主要的 ROS 应用程序代码。

  • sv-srvs/:包含服务定义相关的代码。

  • build.sh:构建项目的脚本,根据操作系统版本选择合适的 cv_bridge 版本,并构建消息、服务和 ROS 应用程序。

  • README.md:项目介绍和安装教程

  1. sv-msgs目录

    2.1主要目录和文件:

img

  • msg/:消息文件目录,包含具体的消息定义文件。

  • CMakeLists.txt:CMake 构建配置文件。

  • package.xml:ROS 包描述文件。

    2.2消息文件 (msg/目录)

img

  • AttitudeCorrection.msg:姿态校正消息。

  • Control.msg:控制消息。

  • GimbalControl.msg:云台控制消息。

  • GimbalState.msg:云台状态消息。

  • ROI.msg:感兴趣区域消息。

  • Target.msg:单个目标消息。

  • TargetsInFrame.msg:帧内多个目标消息。

  1. sv-rosapp 目录内容介绍

img

  • algorithm_params/:该目录下的文件用于定义和配置各种算法的参数。build/:这是 CMake 的默认构建目录,存储了编译过程中的中间文件和最终生成的二进制文件。

  • camera_params/:该目录包含相机校准文件,用于校正相机的内参和外参,以保证图像处理算法的准确性。

  • launch/:包含用于启动 ROS 节点的 launch 文件。launch 文件可以配置多个节点、参数和启动顺序,方便一次性启动整个系统。

  • samples/:提供了多个示例代码和样本项目,展示了如何使用该包的功能。

img

  • g1/目录:包含与g1设备相关的示例代码

  • gazebo/目录:包含与gazebo仿真环境相关的示例代码

  • gx40/目录:包含与gx40设备相关的示例代码

  • mipi/目录:包含与mipi设备相关的示例代码

  • gimbal_server.cpp:该文件用于控制云台的服务端

  • saving_image_with_airball.cpp:该文件用于保存图像

  • web_cam.cpp:该文件使用网络摄像头进行图像捕获和处理

  1. sv-srvs目录内容介绍

img

  • CameraService.srv:定义了一个相机服务

  • GimbalSetHome.srv:定义了一个设置云台回到初始位置的服务

  • TrackService.srv:定义了一个目标跟踪服务

spirecv-ros的大致框架

  1. 顶层目录

img

  • cv_bridge_1804/:包含适用于 Ubuntu 18.04 的 cv_bridge 代码。

  • cv_bridge_2004/:包含适用于 Ubuntu 20.04 的 cv_bridge 代码。

  • sv-msgs/:包含消息定义相关的代码。

  • sv-rosapp/:包含主要的 ROS 应用程序代码。

  • sv-srvs/:包含服务定义相关的代码。

  • build.sh:构建项目的脚本,根据操作系统版本选择合适的 cv_bridge 版本,并构建消息、服务和 ROS 应用程序。

  • README.md:项目介绍和安装教程

  1. sv-msgs目录

    2.1主要目录和文件:

img

  • msg/:消息文件目录,包含具体的消息定义文件。

  • CMakeLists.txt:CMake 构建配置文件。

  • package.xml:ROS 包描述文件。

    2.2消息文件 (msg/目录)

img

  • AttitudeCorrection.msg:姿态校正消息。

  • Control.msg:控制消息。

  • GimbalControl.msg:云台控制消息。

  • GimbalState.msg:云台状态消息。

  • ROI.msg:感兴趣区域消息。

  • Target.msg:单个目标消息。

  • TargetsInFrame.msg:帧内多个目标消息。

  1. sv-rosapp 目录内容介绍

img

  • algorithm_params/:该目录下的文件用于定义和配置各种算法的参数。build/:这是 CMake 的默认构建目录,存储了编译过程中的中间文件和最终生成的二进制文件。

  • camera_params/:该目录包含相机校准文件,用于校正相机的内参和外参,以保证图像处理算法的准确性。

  • launch/:包含用于启动 ROS 节点的 launch 文件。launch 文件可以配置多个节点、参数和启动顺序,方便一次性启动整个系统。

  • samples/:提供了多个示例代码和样本项目,展示了如何使用该包的功能。

img

  • g1/目录:包含与g1设备相关的示例代码

  • gazebo/目录:包含与gazebo仿真环境相关的示例代码

  • gx40/目录:包含与gx40设备相关的示例代码

  • mipi/目录:包含与mipi设备相关的示例代码

  • gimbal_server.cpp:该文件用于控制云台的服务端

  • saving_image_with_airball.cpp:该文件用于保存图像

  • web_cam.cpp:该文件使用网络摄像头进行图像捕获和处理

  1. sv-srvs目录内容介绍

img

  • CameraService.srv:定义了一个相机服务

  • GimbalSetHome.srv:定义了一个设置云台回到初始位置的服务

  • TrackService.srv:定义了一个目标跟踪服务

教学历程

敬请期待!正在进一步完善中!!!!!

源码解析

二维码点击跟踪代码讲解

  1. 当 ROS 系统正常运行时,检查是否接收到新的 ROS 图像,重置 get_ros_img 标志,并将 ROS 图像克隆到本地图像变量 img

image.png

  1. 创建一个 SpireCV 库的 TargetsInFrame 类的实例,用于保存单帧的检测结果,并递增帧 ID,将图像调整为 ad 指定的宽度和高度,在图像上运行检测,并在帧中绘制特定目标,即在检测的时候显示所有的二维码检测框,在追踪的时候,只显示追踪的二维码检测框

image.png

  1. 初始化一个 ROS 消息 ros_tgts,用于保存帧中的目标,并设置其元数据。

image.png

  1. 遍历所有检测到的目标,如果 clicked_id 未设置,将目标添加到 ROS 消息中。

image.png

  1. 如果此前没有二维码被点击,并且当前被点击了,找到被点击的二维码的id

image.png

  1. 如果二维码ID 匹配 clicked_id,则重置 no_track_frame_count,将目标添加到 ROS 消息,并设置云台状态为跟踪模式。

image.png

  1. no_track_frame_count标志位可以控制吊舱的移动和停止

image.png

  1. 将目标和云台状态发布到各自的 ROS 话题,将图像推流到指定的 RTSP 地址,并在窗口中显示图像

image.png

通用目标点击跟踪

  1. 当 ROS 系统正常运行时,检查是否接收到新的 ROS 图像,重置 get_ros_img 标志,并将 ROS 图像克隆到本地图像变量 img

image.png

  1. 如果处于检测状态,创建一个 TargetsInFrame 实例,用于存储检测结果,并递增帧 ID,将图像调整到指定的宽度和高度,使用调整后的图像和选定区域,初始化跟踪矩形和跟踪器,在图像上执行通用目标检测,将检测目标显示在图像上面

image.png

  1. 创建一个检测的ROS 消息 ros_tgts,用于保存帧中的目标,并设置其元数据。

image.png

  1. 遍历检测到的目标,将每个目标的详细信息填充到 ROS 消息中,包括中心坐标、尺寸、置信度、类别、视线角度、跟踪 ID 和 3D 位置。

image.png

  1. 计算目标外接矩形框的四个顶点坐标 ,使用叉乘方法确定被点击的点是否在目标的外接矩形框内。如果是,则更新跟踪状态,初始化新的 ROI,并打印模式状态,发布检测结果到 ROS 主题

image.png

  1. 如果处于追踪状态,创建一个 TargetsInFrame 实例,用于存储检测结果,并递增帧 ID,将图像调整到指定的宽度和高度,如果有新的框选区域,则重新初始化跟踪器,开始追踪,显示追踪框

image.png

  1. 创建一个追踪的ROS 消息 TargetsInFrame 并填充相关元数据

image.png

  1. 如果有追踪目标,则创建 spirecv_msgs::Target 消息并填充和发布目标数据,包括中心坐标、宽度、高度、视线角、3D 位置等。

原理讲解

7.png

  • Backbone:特征提取网络,用于从输入图像中提取特征。YOLOv5使用的是CSPDarknet。

  • Neck:特征融合层,用于融合不同尺度的特征。YOLOv5采用的是PANet(Path Aggregation Network)。

  • Head:检测头,用于生成最终的检测结果,包括目标的类别和边界框。

详细流程

输入图像

输入图像被调整到统一的尺寸(如640x640像素),并进行归一化处理。

Backbone(特征提取)

Backbone部分采用CSPDarknet,该网络通过多个卷积层和残差块,从图像中提取出多层次的特征。

Neck(特征融合)

Neck部分使用了PANet,结合了不同层次的特征,通过上采样和下采样操作,使得高层特征和低层特征有效融合,从而提高了检测效果。

Head(检测头)

Head部分采用了YOLOv5的检测头,分为三个尺度(大、中、小),每个尺度负责检测不同大小的目标。每个尺度上的每个位置会预测一个锚框,并给出该框的类别概率和边界框偏移量。

损失函数

YOLOv5的损失函数由三部分组成:

  • 边界框回归损失:用于衡量预测边界框与真实边界框的差异,通常使用GIoU或DIoU损失。

  • 置信度损失:用于衡量是否存在目标的置信度差异。

  • 类别损失:用于衡量预测类别与真实类别的差异,通常使用交叉熵损失。

训练和推理

训练

训练过程中,模型通过前向传播计算输出,通过损失函数计算误差,再通过反向传播更新模型参数。YOLOv5采用了数据增强技术,如随机裁剪、颜色抖动等,提升模型的鲁棒性。

推理

推理过程中,输入图像经过模型后,输出检测结果。通过NMS(非极大值抑制)处理,去除冗余的检测框,只保留置信度最高的框。

优势与改进

YOLOv5相比于之前版本和其他目标检测模型,具有以下优势:

  • 高效:能在保持高精度的同时,实现实时检测。

  • 简洁:模型架构简洁,易于理解和实现。

  • 灵活:支持多种输入尺寸,能够检测多尺度目标。

  • 增强训练:采用了更好的数据增强和损失函数,提高了模型性能。

扩展阅读

如何训练自己的模型

  1. 打开github,克隆yolov5 7.0

image.png

  1. 了解一下整个目录结构

image.png

  • data:主要是存放一些超参数的配置文件,用来配置训练集和测试集还有验证集的路径的
  • models:里面主要是一些网络构建的配置文件和函数
  • utils:存放的是工具类的函数
  • weights:放置训练好的权重参数。
  • detect.py:利用训练好的权重参数进行目标检测
  • train.py:训练自己的数据集的函数。
  • test.py:测试训练的结果的函数。
  • requirements.txt:yolov5项目的环境依赖包(pip install -r requirements.txt)
  1. 数据标注好,划分训练集和验证集,创建目录,将其放到对应图像和标签目录里面 数据如何标注请看5.2怎么打标签 标签转化请看5.3标注文件的相互转化 划分训练集和验证集请看5.4 划分数据集和验证集

image.png

  1. 获取预训练权重 进入此网站https://github.com/ultralytics/yolov5/releases,放到yolov5

image.png

  1. 修改配置文件,准备训练

image.png

复制一份VOC.yaml,命名一个跟自己模型相关的名字

image.png

写好之前创建好的目录,然后写上要训练的类别

image.png

假设你要训练的是yolov5s的模型,在models文件夹的yolov5s.yaml文件里面修改类别的数量,改为5

image.png

在train.py文件里面,修改模型的pt文件(默认在yolov5-7.0主目录下),yolov5s的yaml文件,数据集的yaml文件,训练轮数可以设置为1000,训练到不能提升会自动停下来,batch_size可以根据自己的GPU显存进行调整

怎么打标签

  1. 打标签工具:labelimg 安装命令 :
pip install labelimg -i https://pypi.tuna.tsinghua.edu.cn/simple
  1. 创建打标签的目录

image.png

├── make_labels │├── images 存放需要打标签的图片文件 │├── lebels 存放标注的标签文件 ││├── classes.txt 定义自己要标注的所有类别(可以没有这个文件)
  1. 打开labelImg软件,打开图片和标签目录,并设置labelimg配置 打开软件的命令如下图 :
    labelImg

image.png

打开图片目录

image.png

打开标签目录

image.png

使用PascalVOC模式的标签 设置自动保存和显示类别

image.png

常用快捷键如下 :

  • A:切换到上一张图片
  • D:切换到下一张图片
  • W:调出标注十字架
  • del :删除标注框框
  • Ctrl+u:选择标注的图片文件夹
  • Ctrl+r:选择标注好的label标签存在的文件夹
  1. 开始标注

image.png

  1. 标签文件就自动生成了

image.png

内容如下:

image.png

标注文件的互相转化

  1. voc转yolo代码
import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join
 
def convert(size, box):
    x_center = (box[0] + box[1]) / 2.0
    y_center = (box[2] + box[3]) / 2.0
    x = x_center / size[0]
    y = y_center / size[1]
    w = (box[1] - box[0]) / size[0]
    h = (box[3] - box[2]) / size[1]
    return (x, y, w, h)
 
def convert_annotation(xml_files_path, save_txt_files_path, classes):
    xml_files = os.listdir(xml_files_path)
    print(xml_files)
    for xml_name in xml_files:
        print(xml_name)
        xml_file = os.path.join(xml_files_path, xml_name)
        out_txt_path = os.path.join(save_txt_files_path, xml_name.split('.')[0] + '.txt')
        out_txt_f = open(out_txt_path, 'w')
        tree = ET.parse(xml_file)
        root = tree.getroot()
        size = root.find('size')
        w = int(size.find('width').text)
        h = int(size.find('height').text)
 
        for obj in root.iter('object'):
            difficult = obj.find('difficult').text
            cls = obj.find('name').text
            if cls not in classes or int(difficult) == 1:
                continue
            cls_id = classes.index(cls)
            xmlbox = obj.find('bndbox')
            b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text),
                 float(xmlbox.find('ymax').text))
            # b=(xmin, xmax, ymin, ymax)
            print(w, h, b)
            bb = convert((w, h), b)
            out_txt_f.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')

if __name__ == "__main__":
    # 需要转换的类别,需要一一对应
    classes = ['pig', 'beef','horse','monkey','donkey']
    # 2、voc格式的xml标签文件路径
    xml_folder = "/home/amov/downloads/yolov5-7.0/make_labels/lebels"
    # 3、转化为yolo格式的txt标签文件存储路径
    		yolo_folder="/home/amov/downloads/yolov5-7.0/make_labels/yolo_lebels"
 
    convert_annotation(xml_folder, yolo_folder, classes)

image.png

向转化函数传入xml目录,yolo目录,和类别即可

  1. yolo转voc代码
from xml.dom.minidom import Document
import os
import cv2
 
 
# def makexml(txtPath, xmlPath, picPath):  # txt所在文件夹路径,xml文件保存路径,图片所在文件夹路径
def makexml(picPath, txtPath, xmlPath):  # txt所在文件夹路径,xml文件保存路径,图片所在文件夹路径
    # 此函数用于将yolo格式txt标注文件转换为voc格式xml标注文件
    # 在自己的标注图片文件夹下建三个子文件夹,分别命名为picture、txt、xml
    
    dic = {'0': "pig",  # 创建字典用来对类型进行转换
           '1': "beef",  # 此处的字典要与自己的classes.txt文件中的类对应,且顺序要一致
           '2': "horse",
           '3': "monkey",
           '4': "donkey",
           }
    files = os.listdir(txtPath)
    for i, name in enumerate(files):
        xmlBuilder = Document()
        annotation = xmlBuilder.createElement("annotation")  # 创建annotation标签
        xmlBuilder.appendChild(annotation)
        txtFile = open(txtPath + name)
        txtList = txtFile.readlines()
        img = cv2.imread(picPath + name[0:-4] + ".jpg")
        Pheight, Pwidth, Pdepth = img.shape
 
        folder = xmlBuilder.createElement("folder")  # folder标签
        foldercontent = xmlBuilder.createTextNode("driving_annotation_dataset")
        folder.appendChild(foldercontent)
        annotation.appendChild(folder)  # folder标签结束
 
        filename = xmlBuilder.createElement("filename")  # filename标签
        filenamecontent = xmlBuilder.createTextNode(name[0:-4] + ".jpg")
        filename.appendChild(filenamecontent)
        annotation.appendChild(filename)  # filename标签结束
 
        size = xmlBuilder.createElement("size")  # size标签
        width = xmlBuilder.createElement("width")  # size子标签width
        widthcontent = xmlBuilder.createTextNode(str(Pwidth))
        width.appendChild(widthcontent)
        size.appendChild(width)  # size子标签width结束
 
        height = xmlBuilder.createElement("height")  # size子标签height
        heightcontent = xmlBuilder.createTextNode(str(Pheight))
        height.appendChild(heightcontent)
        size.appendChild(height)  # size子标签height结束
 
        depth = xmlBuilder.createElement("depth")  # size子标签depth
        depthcontent = xmlBuilder.createTextNode(str(Pdepth))
        depth.appendChild(depthcontent)
        size.appendChild(depth)  # size子标签depth结束
 
        annotation.appendChild(size)  # size标签结束
 
        for j in txtList:
            oneline = j.strip().split(" ")
            object = xmlBuilder.createElement("object")  # object 标签
            picname = xmlBuilder.createElement("name")  # name标签
            namecontent = xmlBuilder.createTextNode(dic[oneline[0]])
            picname.appendChild(namecontent)
            object.appendChild(picname)  # name标签结束
 
            pose = xmlBuilder.createElement("pose")  # pose标签
            posecontent = xmlBuilder.createTextNode("Unspecified")
            pose.appendChild(posecontent)
            object.appendChild(pose)  # pose标签结束
 
            truncated = xmlBuilder.createElement("truncated")  # truncated标签
            truncatedContent = xmlBuilder.createTextNode("0")
            truncated.appendChild(truncatedContent)
            object.appendChild(truncated)  # truncated标签结束
 
            difficult = xmlBuilder.createElement("difficult")  # difficult标签
            difficultcontent = xmlBuilder.createTextNode("0")
            difficult.appendChild(difficultcontent)
            object.appendChild(difficult)  # difficult标签结束
 
            bndbox = xmlBuilder.createElement("bndbox")  # bndbox标签
            xmin = xmlBuilder.createElement("xmin")  # xmin标签
            mathData = int(((float(oneline[1])) * Pwidth + 1) - (float(oneline[3])) * 0.5 * Pwidth)
            xminContent = xmlBuilder.createTextNode(str(mathData))
            xmin.appendChild(xminContent)
            bndbox.appendChild(xmin)  # xmin标签结束
 
            ymin = xmlBuilder.createElement("ymin")  # ymin标签
            mathData = int(((float(oneline[2])) * Pheight + 1) - (float(oneline[4])) * 0.5 * Pheight)
            yminContent = xmlBuilder.createTextNode(str(mathData))
            ymin.appendChild(yminContent)
            bndbox.appendChild(ymin)  # ymin标签结束
 
            xmax = xmlBuilder.createElement("xmax")  # xmax标签
            mathData = int(((float(oneline[1])) * Pwidth + 1) + (float(oneline[3])) * 0.5 * Pwidth)
            xmaxContent = xmlBuilder.createTextNode(str(mathData))
            xmax.appendChild(xmaxContent)
            bndbox.appendChild(xmax)  # xmax标签结束
 
            ymax = xmlBuilder.createElement("ymax")  # ymax标签
            mathData = int(((float(oneline[2])) * Pheight + 1) + (float(oneline[4])) * 0.5 * Pheight)
            ymaxContent = xmlBuilder.createTextNode(str(mathData))
            ymax.appendChild(ymaxContent)
            bndbox.appendChild(ymax)  # ymax标签结束
 
            object.appendChild(bndbox)  # bndbox标签结束
 
            annotation.appendChild(object)  # object标签结束
 
        f = open(xmlPath + name[0:-4] + ".xml", 'w')
        xmlBuilder.writexml(f, indent='\t', newl='\n', addindent='\t', encoding='utf-8')
        f.close()
 
if __name__ == "__main__":
    picPath = "/home/amov/downloads/yolov5-7.0/make_labels/images/"  # 图片所在文件夹路径,后面的/一定要带上
    txtPath = "/home/amov/downloads/yolov5-7.0/make_labels/yolo_lebels/"  # txt所在文件夹路径,后面的/一定要带上
    xmlPath = "/home/amov/downloads/yolov5-7.0/make_labels/lebels/"  # xml文件保存路径,后面的/一定要带上
makexml(picPath, txtPath, xmlPath)

image.png

将图片目录,yolo标注目录,和xml目录传入函数即可

划分数据集和验证集

import os, random, shutil

def moveimg(fileDir, tarDir):
    pathDir = os.listdir(fileDir)  # 取图片的原始路径
    filenumber = len(pathDir)
    rate = 0.2  # 自定义抽取图片的比例,比方说100张抽10张,那就是0.1
    picknumber = int(filenumber * rate)  # 按照rate比例从文件夹中取一定数量图片
    sample = random.sample(pathDir, picknumber)  # 随机选取picknumber数量的样本图片
    print(sample)
    for name in sample:
        shutil.move(fileDir + name, tarDir + "\\" + name)
    return
 
def movelabel(file_list, file_label_train, file_label_val):
    for i in file_list:
        if i.endswith('.jpg'):
            # filename = file_label_train + "\\" + i[:-4] + '.xml'  # 可以改成xml文件将’.txt‘改成'.xml'就可以了
            filename = file_label_train + "\\" + i[:-4] + '.txt'  # 可以改成xml文件将’.txt‘改成'.xml'就可以了
            if os.path.exists(filename):
                shutil.move(filename, file_label_val)
                print(i + "处理成功!")

if __name__ == '__main__':
    fileDir = "/home/amov/downloads/yolov5-7.0/train_path/images/train/"  # 源图片文件夹路径
    tarDir = "/home/amov/downloads/yolov5-7.0/train_path/images/val"  # 图片移动到新的文件夹路径
    moveimg(fileDir, tarDir)
    file_list = os.listdir(tarDir)
    file_label_train = "/home/amov/downloads/yolov5-7.0/train_path/lebels/train"  # 源图片标签路径
    file_label_val = "/home/amov/downloads/yolov5-7.0/train_path/lebels/val" # 标签
      # 移动到新的文件路径
    movelabel(file_list, file_label_train, file_label_val)

image.png

注意

一般会设置80%训练集和20%验证集,划分数据集的代码会抽取所有的数据集中的20%作为验证集,剩余的80%作为训练集

ego_planner_swarm 模块介绍

ego_planner_swarm 是 ego-planner 的扩展模块,专为多台无人机的协作和自主导航设计。该模块旨在帮助多个无人机在复杂和动态的环境中进行协同工作和自主决策,提升它们的自主性和效率。相关源代码位于 /home/amov/Prometheus/Modules/ego_planner_swarm 文件夹下。具体特点和功能包括:

- 高度自主决策 : 无人机能够实时感知环境变化并自主调整飞行策略,确保任务高效完成。
- 协同导航 : 无人机能够接收来自更高优先级无人机的轨迹信息,并将其存储起来,以便在需要时参考这些轨迹来为自己规划出更加安全的飞行路径。
- 去中心化架构 : 完全自主与分散式设计,每台无人机独立决策,无需中央控制,提升了系统的灵活性和鲁棒性。

目录

  1. 关键话题与参数介绍

  2. 教学与实践

    2.1 单机避障      2.1.1 D435i视觉避障      2.1.2 二维激光雷达避障

    2.2 集群避障      2.2.1 D435i视觉避障      2.2.2 二维激光雷达避障

  3. 扩展阅读 3.1 EGO-Swarm优势 3.2 A*算法原理

ego_planner_swarm 模块介绍

ego_planner_swarm 是 ego-planner 的扩展模块,专为多台无人机的协作和自主导航设计。该模块旨在帮助多个无人机在复杂和动态的环境中进行协同工作和自主决策,提升它们的自主性和效率。相关源代码位于 /home/amov/Prometheus/Modules/ego_planner_swarm 文件夹下。具体特点和功能包括:

- 高度自主决策 : 无人机能够实时感知环境变化并自主调整飞行策略,确保任务高效完成。
- 协同导航 : 无人机能够接收来自更高优先级无人机的轨迹信息,并将其存储起来,以便在需要时参考这些轨迹来为自己规划出更加安全的飞行路径。
- 去中心化架构 : 完全自主与分散式设计,每台无人机独立决策,无需中央控制,提升了系统的灵活性和鲁棒性。

目录

  1. 关键话题与参数介绍

  2. 教学与实践

    2.1 单机避障      2.1.1 D435i视觉避障      2.1.2 二维激光雷达避障

    2.2 集群避障      2.2.1 D435i视觉避障      2.2.2 二维激光雷达避障

  3. 扩展阅读 3.1 EGO-Swarm优势 3.2 A*算法原理

关键话题与参数介绍

发布话题和订阅话题中均带有命名空间/uav~,无人机编号不同则对应的命名空间不同,单机时默认为:/uav1

订阅话题

  • /broadcast_bspline (traj_utils/Bspline)

    无人机当前时刻及未来一段时间内的飞行轨迹

  • /uav1/mavros/local_position/odom (nav_msgs/Odometry)

    无人机里程计数据

  • /uav1/octomap_point_cloud_centers (sensor_msgs/PointCloud2)

    无人机点云数据

  • /uav1/prometheus/motion_planning/goal (geometry_msgs/PoseStamped)

    无人机目标点

发布话题

  • /broadcast_bspline (traj_utils/Bspline)

    每台无人机当前时刻及未来一段时间内的飞行轨迹

  • /uav1/planning/bspline (traj_utils/Bspline)

    一号无人机规划的B样条轨迹

  • /uav1_ego_planner_node/grid_map/occupancy_inflate (sensor_msgs/PointCloud2)

    无人机膨胀后的点云数据

  • /uav1/prometheus/command (prometheus_msgs/UAVCommand)

    无人机控制指令

  • /uav1_ego_planner_node/global_list (visualization_msgs/Marker)

    无人机规划的全局点合集,用于RVIZ显示

  • /uav1_ego_planner_node/goal_point (visualization_msgs/Marker)

    无人机终点,用于RVIZ显示

  • /uav1_ego_planner_node/optimal_list (visualization_msgs/Marker)

    无人机优化的轨迹,用于RVIZ显示

参数

  • uav_id :

    参数说明: 无人机编号

    单位:

    数据类型: int

    默认值: 1

    备注: 无

  • map_size_x_ :

    参数说明: 规划范围,x 方向

    单位: 米

    数据类型: double

    默认值: 50.0

    备注:

  • map_size_y_ :

    参数说明: 规划范围,y 方向

    单位: 米

    数据类型: double

    默认值: 50.0

    备注:

  • map_size_z_ :

    参数说明: 规划范围,z 方向

    单位: 米

    数据类型: double

    默认值: 3.0

    备注:

  • odometry_topic :

    参数说明: 订阅的里程计话题

    单位:

    消息类型: nav_msgs/Odometry

    默认值: /mavros/local_position/odom

    备注: 在advanced_param.xml文件中加了前缀 /uav* ,可根据自身需求进行替换

  • cloud_topic :

    参数说明: 订阅的点云话题

    单位:

    消息类型: sensor_msgs/PointCloud2

    默认值: /uav1/octomap_point_cloud_centers

    备注:

  • max_vel :

    参数说明: 最大飞行速度

    单位: m/s

    数据类型: double

    默认值: 0.8

    备注:

  • max_acc :

    参数说明: 最大加速度

    单位: m/s^2

    数据类型: double

    默认值: 6.0

    备注:

  • planning_horizon :

    参数说明: 规划范围

    单位: m

    数据类型: double

    默认值: 7.5

    备注: 一般设置为传感器的1.5倍

  • yaw_init :

    参数说明: 偏航角初始值

    单位: rad

    数据类型: double

    默认值: 0.0

    备注:

  • fsm/thresh_replan_time :

    参数说明: 重规划时间

    单位: rad

    数据类型: double

    默认值: 1.0

    备注:

  • fsm/thresh_no_replan_meter :

    参数说明: 重规划阈值

    单位: m

    数据类型: double

    默认值: 1.0

    备注: 在阈值范围内,停止规划

  • grid_map/resolution :

    参数说明: 地图分辨率

    单位:

    数据类型: double

    默认值: 1.0

    备注:

  • grid_map/local_update_range_x :

    参数说明: x 方向截断距离

    单位: m

    数据类型: double

    默认值: 5.5

    备注: y z 方向同理

  • grid_map/obstacles_inflation :

    参数说明: 障碍物膨胀距离

    单位: m

    数据类型: double

    默认值: 0.5

    备注: 为保证飞行安全,膨胀距离最小设置为无人机最大尺寸的一半

单机避障

仿真Demo-D435i视觉避障

效果展示

提示

运行Demo前请将该模块编译

编译代码如下:

cd ~/Prometheus
catkin_make --source Modules/ego_planner_swarm --build build/ego_planner_swarm

仿真脚本启动流程

  1. 将FS-i6s遥控器开机并通过USB接口接入电脑

  2. 输入以下命令启动二维激光雷达集群避障仿真demo

cd ~/Prometheus/Scripts/simulation/ego_planner/
# 第一次启动该脚本时,需要添加可执行权限
chmod +x ego_planner_p450_d435i.sh
 ./ego_planner_p450_d435i.sh

检查终端运行是否正常

  1. ROS主节点
    • 下图所示为正常运行

image.png

  1. PX4仿真
    • 下图所示为正常运行

image.png

  1. Prometheus控制
    • 下图所示为正常运行

image.png

  1. Octomap建图
    • 下图所示为正常运行

image.png

  1. Ego-planner规划避障
    • 下图所示为正常运行

image.png

开始仿真

  1. 遥控器拨动SW-A,解锁无人机

image.png

  1. 拨动SW-B,到中间,进入Prometheus的RC_POS_CONTROL控制

image.png

  1. 拨动SW-B,到最下面,进入Prometheus的COMMAND_CONTROL控制,无人机会自主起飞

image.png

  1. 选择 3D Nav Goal
    • 选择后鼠标的图表会发生变化

image.png

  1. 开始指点
    • 鼠标左键点击目标点,然后不松开,拖向无人机方向(如下图一绿色箭头,提供目标X和Y的位置),然后按住鼠标左键的同时,按下鼠标右键,在画面内向上划,可以提供Z的高度,如下图二所示
注意:如果不按住鼠标左键,在画面内向上划,提供Z的高度,那么Z的高度默认为0,则会出现到达不了目标点的情况!

image.png

image.png

  • 开始自主规划避障

image.png

  1. 到达后再次规划
    • 按照步骤再次指点规划

image.png

节点运行图

rosgraph_视觉ego.png

起飞降落例程主要包含/joy_node/uav1/mavros/uav_control_main_1/octomap_server/gazebo/uav1_ego_planner_node/uav1_traj_server_for_prometheus等ROS节点。

  • /joy_node节点为遥控器ROS驱动节点,用以获取遥控器数据,通过话题uav1/prometheus/fake_rc_in将遥控器数据传输给/uav_control_main_1节点。

  • /uav1/mavros节点为飞控ROS驱动节点,与飞控进行数据交互。在仿真中,该驱动节点与模拟飞控进行数据交互。

  • /uav_control_main_1节点为Prometheus项目中最基础的ROS节点,所有Prometheus项目的功能模块都通过该节点与无人机进行数据交互。

  • /octomap_server节点为建图服务节点,通过仿真D435i点云数据来进行建图。

  • /gazebo节点为gazebo ROS驱动节点,为/octomap_server节点提供局部点云数据,来进行建图

  • /uav1_ego_planner_node节点为ego_planner规划节点,通过/octomap_server节点的话题数据进行建图,输出/uav1/planning/bspline,来进行路线规划

  • /uav1_traj_server_for_prometheus节点为轨迹生成节点,由B样条(bspline)生成轨迹,转化为command命令控制无人机飞行

从节点运行图中,我们可以看到有如下的数据话题

  • /uav1/prometheus/command:无人机控制接口,对应的消息为prometheus_msgs/UAVCommand
  • /uav1/prometheus/state:无人机状态,对应的消息为prometheus_msgs/UAVState
  • /uav1/prometheus/fake_rc_in:仿真模拟PX4遥控器数据
  • /camera/depth/color/points:局部点云话题输入
  • /octomap_point_cloud_centers:点云信息,仿真中由map_generator产生
  • /broadcast_bspline:广播的B样条
  • /uav1/planning/bspline:发布的B样条

建议阅读/Prometheus/Modules/common/prometheus_msgs/msg内对应的消息文件,了解上面提到的消息详细定义。

代码讲解

脚本位于/home/amov/Prometheus/Scripts/simulation/ego_planner/ego_planner_p450_d435i.sh,打开规划脚本如下

Screenshot from 2024-05-10 15-17-48.png

除了运行ros必备启动的roscore,脚本依次运行了四个launch文件

1.sitl_p450_d435i.launch

2.uav_control_main_outdoor.launch

3.depth_to_octomap.launch

4.sitl_ego_planner_basic_octomap.launch

依次查看

1.sitl_p450_d435i.launch

Screenshot from 2024-05-10 15-20-32.png

启动prometheus_gazebo下gazebo环境,带有仿真D435i的无人机模型,以及rviz

2.uav_control_main_outdoor.launch

Screenshot from 2024-05-10 15-25-48.png

在prometheus_uav_control,启动UAV1控制节点,Prometheus下控制,为后面路径规划发送控制指令做准备

3.depth_to_octomap.launch

Screenshot from 2024-05-10 15-28-15.png

在prometheus_gazebo下启动octomap建图服务,为后面ego规划做准备。octomap_server是ROS中一个基于octomap的功能包,具有将点云地图转化为基于Octree的OctoMap的功能。

在ROS中,octomap_server和octomap_map都是用于构建三维地图的软件包。octomap_server软件包提供了一种将输入数据转换为OctoMap格式的方法。它可以将来自激光雷达或深度摄像头等传感器的数据转换为三维点云,并使用这些点云构建OctoMap。octomap_server还可以将OctoMap数据发布为ROS中的OctoMap消息,以便其他ROS节点可以使用它们。octomap_map软件包提供了一种使用OctoMap数据构建环境模型的方法。它可以订阅来自octomap_server的OctoMap消息,并使用该消息构建一个三维地图。该地图可以用于机器人的定位、路径规划和避障等任务。octomap_server用于构建OctoMap数据,而octomap_map用于将OctoMap数据转换为实际可用的地图。

可以查看octomap_server讲解来深入了解octomap

4.sitl_ego_planner_basic_octomap.launch

Screenshot from 2024-05-10 15-39-26.png

在ego_planner包下启动ego_planner 仿真,并由B样条生成轨迹,发送控制指令给无人机,控制飞行。其中包含两部分/uav1_ego_planner_node/uav1_traj_server_for_prometheus

前者/uav1_ego_planner_node进行ego_planner规划,相关源代码参见ego_planner_node.cpp ,ego_replan_fsm.cpp,planner_manager.cpp,路径:/home/amov/Prometheus/Modules/ego_planner_swarm/plan_manage/src/。

EGO-Planner是一个无ESDF(欧几里得符号距离场)的基于梯度的局部路径规划框架,EGO-Planner由基于梯度的样条优化器和后细化两部分组成。

可以查看EGO-Planner代码讲解来深入了解EGO-Planner

后者/uav1_traj_server_for_prometheus订阅ego_planner规划结果,由B样条(bspline)生成轨迹,转化为command命令控制无人机飞行。其源代码为traj_server_for_prometheus.cpp,路径:/home/amov/Prometheus/Modules/ego_planner_swarm/plan_manage/src_for_prometheus/

操作演示视频

仿真Demo-二维激光雷达避障

效果展示

提示

运行Demo前请将该模块编译

编译代码如下:

cd ~/Prometheus
catkin_make --source Modules/ego_planner_swarm --build build/ego_planner_swarm

仿真脚本启动流程

  1. 将FS-i6s遥控器开机并通过USB接口接入电脑

  2. 输入以下命令启动二维激光雷达集群避障仿真demo

cd ~/Prometheus/Scripts/simulation/ego_planner/
# 第一次启动该脚本时,需要添加可执行权限
chmod +x ego_planner_p450_2dlidar.sh
 ./ego_planner_p450_2dlidar.sh

检查终端运行是否正常

  1. ROS主节点
    • 下图所示为正常运行

25.png

  1. PX4仿真
    • 下图所示为正常运行

26.png

  1. Prometheus控制
    • 下图所示为正常运行

27.png

  1. 雷达驱动
    • 下图所示为正常运行

28.png

  1. Octomap建图
    • 下图所示为正常运行

29.png

  1. Ego-planner规划避障
    • 下图所示为正常运行

30.png

开始仿真

  1. 遥控器拨动SW-A,解锁无人机

31.png

  1. 拨动SW-B,到中间,进入Prometheus的RC_POS_CONTROL控制

32.png

  1. 拨动SW-B,到最下面,进入Prometheus的COMMAND_CONTROL控制,无人机会自主起飞

33.png

34.png

  1. 选择 3D Nav Goal
    • 选择后鼠标的图表会发生变化

35.png

  1. 开始指点
    • 鼠标左键点击目标点,然后不松开,拖向无人机方向(如下图一绿色箭头,提供目标X和Y的位置),然后按住鼠标左键的同时,按下鼠标右键,在画面内向上划,可以提供Z的高度,如下图二所示
注意:如果不按住鼠标左键,在画面内向上划,提供Z的高度,那么Z的高度默认为0,则会出现到达不了目标点的情况!

36.png

220.png

  • 开始自主规划避障

37.png

  1. 到达后再次规划
    • 按照步骤再次指点规划

38.png

节点运行图

rosgraph_雷达ego.png

起飞降落例程主要包含/joy_node/uav1/mavros/uav_control_main_1/octomap_server/gazebo/laser_filter/laser_to_pointcloud/uav1_ego_planner_node/uav1_traj_server_for_prometheus等ROS节点。

  • /joy_node节点为遥控器ROS驱动节点,用以获取遥控器数据,通过话题uav1/prometheus/fake_rc_in将遥控器数据传输给/uav_control_main_1节点。

  • /uav1/mavros节点为飞控ROS驱动节点,与飞控进行数据交互。在仿真中,该驱动节点与模拟飞控进行数据交互。

  • /uav_control_main_1节点为Prometheus项目中最基础的ROS节点,所有Prometheus项目的功能模块都通过该节点与无人机进行数据交互。

  • /gazebo节点为gazebo ROS驱动节点,为/octomap_server节点提供点云数据,来进行建图

  • /laser_filter节点为ROS感知模块节点,它提供了一系列滤波器,用于处理来自激光雷达传感器的数据。这些滤波器可以帮助你消除噪声、平滑扫描或者根据需要进行其他定制化操作。为/laser_to_pointcloud节点提供滤波后雷达数据

  • /laser_to_pointcloud节点为plan_env节点,将扫描的雷达数据LaserScan 转为 sensor_msgs::PointCloud2 点云格式,为后续/octomap_server建图做数据提供

  • /octomap_server节点为建图服务节点,通过仿真雷达数据转换出的点云数据来进行建图。

  • /uav1_ego_planner_node节点为ego_planner规划节点,通过/octomap_server节点的话题数据进行建图,输出/uav1/planning/bspline,来进行路线规划

  • /uav1_traj_server_for_prometheus节点为轨迹生成节点,由B样条(bspline)生成轨迹,转化为command命令控制无人机飞行

从节点运行图中,我们可以看到有如下的数据话题

  • /uav1/prometheus/command:无人机控制接口,对应的消息为prometheus_msgs/UAVCommand
  • /uav1/prometheus/state:无人机状态,对应的消息为prometheus_msgs/UAVState
  • /uav1/prometheus/fake_rc_in:仿真模拟PX4遥控器数据
  • /scan 仿真雷达扫描出的雷达数据
  • /scan_filter 滤波器滤波后的雷达数据
  • /uav1/prometheus/scan_point_cloud 雷达数据转换为点云数据输出
  • /octomap_point_cloud_centers:点云信息,仿真中由map_generator产生
  • /broadcast_bspline:广播的B样条
  • /uav1/planning/bspline:发布的B样条

建议阅读/Prometheus/Modules/common/prometheus_msgs/msg内对应的消息文件,了解上面提到的消息详细定义。

代码讲解

脚本位于/home/amov/Prometheus/Scripts/simulation/ego_planner/ego_planner_p450_2dlidar.sh,打开规划脚本如下

Screenshot from 2024-05-11 11-06-48.png

除了运行ros必备启动的roscore,脚本依次运行了五个launch文件

1.sitl_p450_2dlidar.launch

2.uav_control_main_outdoor.launch

3.filter_lidar.launch

4.scan_to_octomap.launch

5.sitl_ego_planner_basic_octomap.launch

依次查看

1.sitl_p450_2dlidar.launch

Screenshot from 2024-05-11 11-08-08.png

启动prometheus_gazebo下gazebo环境,带有仿真二维激光雷达的无人机模型,以及rviz

2.uav_control_main_outdoor.launch

Screenshot from 2024-05-11 11-18-31.png

在prometheus_uav_control,启动UAV1控制节点,Prometheus下控制,为后面路径规划发送控制指令做准备

3.filter_lidar.launch

Screenshot from 2024-05-11 11-18-51.png

在prometheus_gazebo下启动laser filter,laser_filters是ROS感知模块的一部分,它提供了一系列滤波器,用于处理来自激光雷达传感器的数据。这些滤波器可以帮助你消除噪声、平滑扫描或者根据需要进行其他定制化操作。

可以查看laser filter讲解来深入了解laser filter

4.scan_to_octomap.launch

Screenshot from 2024-05-11 11-26-35.png

在prometheus_gazebo下启动octomap建图服务,为后面ego规划做准备。octomap_server是ROS中一个基于octomap的功能包,具有将点云地图转化为基于Octree的OctoMap的功能。

在ROS中,octomap_server和octomap_map都是用于构建三维地图的软件包。octomap_server软件包提供了一种将输入数据转换为OctoMap格式的方法。它可以将来自激光雷达或深度摄像头等传感器的数据转换为三维点云,并使用这些点云构建OctoMap。octomap_server还可以将OctoMap数据发布为ROS中的OctoMap消息,以便其他ROS节点可以使用它们。octomap_map软件包提供了一种使用OctoMap数据构建环境模型的方法。它可以订阅来自octomap_server的OctoMap消息,并使用该消息构建一个三维地图。该地图可以用于机器人的定位、路径规划和避障等任务。octomap_server用于构建OctoMap数据,而octomap_map用于将OctoMap数据转换为实际可用的地图。

可以查看octomap_server讲解来深入了解octomap

5.sitl_ego_planner_basic_octomap.launch

Screenshot from 2024-05-10 15-39-26.png

在ego_planner包下启动ego_planner 仿真,并由B样条生成轨迹,发送控制指令给无人机,控制飞行。其中包含两部分/uav1_ego_planner_node/uav1_traj_server_for_prometheus

前者/uav1_ego_planner_node进行ego_planner规划,相关源代码参见ego_planner_node.cpp ,ego_replan_fsm.cpp,planner_manager.cpp,路径:/home/amov/Prometheus/Modules/ego_planner_swarm/plan_manage/src/。

EGO-Planner是一个无ESDF(欧几里得符号距离场)的基于梯度的局部路径规划框架,EGO-Planner由基于梯度的样条优化器和后细化两部分组成。

可以查看EGO-Planner代码讲解来深入了解EGO-Planner

后者/uav1_traj_server_for_prometheus订阅ego_planner规划结果,由B样条(bspline)生成轨迹,转化为command命令控制无人机飞行。其源代码为traj_server_for_prometheus.cpp,路径:/home/amov/Prometheus/Modules/ego_planner_swarm/plan_manage/src_for_prometheus/

操作演示视频

仿真Demo-MID360雷达避障

效果展示

提示

运行Demo前请将该模块编译

编译代码如下:

cd ~/Prometheus
catkin_make --source Modules/ego_planner_swarm --build build/ego_planner_swarm

仿真脚本启动流程

  1. 将FS-i6s遥控器开机并通过USB接口接入电脑

  2. 输入以下命令启动二维激光雷达集群避障仿真demo

cd ~/Prometheus/Scripts/simulation/ego_planner/
# 第一次启动该脚本时,需要添加可执行权限
chmod +x ego_panner_p600_mid360.sh
 ./ego_panner_p600_mid360.sh

检查终端运行是否正常

  1. ROS主节点
    • 下图所示为正常运行

ros主节点.png

  1. PX4仿真
    • 下图所示为正常运行

PX4仿真.png

  1. Prometheus控制
    • 下图所示为正常运行

prometheus控制.png

  1. Ego-planner规划避障
    • 下图所示为正常运行

ego规划.png

开始仿真

  1. 遥控器拨动SW-A,解锁无人机

sw_A.png

  1. 拨动SW-B,到中间,进入Prometheus的RC_POS_CONTROL控制

SWB1.png

  1. 拨动SW-B,到最下面,进入Prometheus的COMMAND_CONTROL控制,无人机会自主起飞

SWB2.png

  1. 选择 3D Nav Goal
    • 选择后鼠标的图表会发生变化

mid 360鼠标点击.png

  1. 开始指点
    • 鼠标左键点击目标点,然后不松开,拖向无人机方向(如下图一绿色箭头,提供目标X和Y的位置),然后按住鼠标左键的同时,按下鼠标右键,在画面内向上划,可以提供Z的高度,如下图二所示
注意:如果不按住鼠标左键,在画面内向上划,提供Z的高度,那么Z的高度默认为0,则会出现到达不了目标点的情况!

mid360 指点截图.png

  • 开始自主规划避障

mid360 规划截图2.png

  1. 到达后再次规划
    • 按照步骤再次指点规划 再次指点规划.png

节点运行图

mid节点运行图.png

起飞降落例程主要包含/gazebo/joy_node/uav1/mavros/uav_control_main_1/uav1mid360_point2_world/uav1_ego_planner_node/uav1_traj_server_for_prometheus等ROS节点

  • /gazebo节点为gazebo ROS驱动节点,为/laserMapping节点提供点云数据,可来进行建图、定位

  • /joy_node节点为遥控器ROS驱动节点,用以获取遥控器数据,通过话题uav1/prometheus/fake_rc_in将遥控器数据传输给/uav_control_main_1节点

  • /uav1/mavros节点为飞控ROS驱动节点,与飞控进行数据交互。在仿真中,该驱动节点与模拟飞控进行数据交互

  • /uav_control_main_1节点为Prometheus项目中最基础的ROS节点,所有Prometheus项目的功能模块都通过该节点与无人机进行数据交互

/uav1_ego_planner_node节点是将雷达从倾斜数据转到world系下

  • /uav1_ego_planner_node节点为ego_planner规划节点,通过/octomap_server节点的话题数据进行建图,输出/uav1/planning/bspline,来进行路线规划

  • /uav1_traj_server_for_prometheus节点为轨迹生成节点,由B样条(bspline)生成轨迹,转化为command命令控制无人机飞行

从节点运行图中,我们可以看到有如下的数据话题

  • /uav1/prometheus/command:无人机控制接口,对应的消息为prometheus_msgs/UAVCommand
  • /uav1/mavros/state:无人机状态,对应的消息为mavros_msgs/State
  • /uav1/prometheus/fake_rc_in:仿真模拟PX4遥控器数据
  • /livox/lidar 仿真中Mid360雷达扫描出的雷达数据
  • /broadcast_bspline:广播的B样条
  • /uav1/planning/bspline:发布的B样条
  • /uav1/mavros/local_position/odom: 无人机位置数据
  • /uav1/livox/lidar:雷达转换后的点云数据

建议阅读/Prometheus/Modules/common/prometheus_msgs/msg内对应的消息文件,了解上面提到的消息详细定义。

代码讲解

脚本位于/home/amov/Prometheus/Scripts/simulation/ego_planner/ego_panner_p600_mid360.sh,打开规划脚本如下

UAV_ID=1
gnome-terminal --window -e 'bash -c "roscore; exec bash"' \
--tab -e 'bash -c "sleep 3; roslaunch prometheus_gazebo sitl_outdoor_1uav_P600_mid360.launch uav1_id:='$UAV_ID' uav1_init_x:=-0.0 uav1_init_y:=-0.0; exec bash"' \
--tab -e 'bash -c "sleep 4; roslaunch prometheus_uav_control uav_control_main_outdoor_mid60.launch uav_id:='$UAV_ID'; exec bash"' \
--tab -e 'bash -c "sleep 4; roslaunch ego_planner sitl_ego_planner_mid360.launch; exec bash"' \

除了运行ros必备启动的roscore,脚本依次运行了三个launch文件

  1. sitl_outdoor_1uav_P600_mid360.launch

  2. uav_control_main_outdoor_mid60.launch

  3. sitl_ego_planner_mid360.launch

依次查看

1.sitl_outdoor_1uav_P600_mid360.launch

gazebo启动文件1.png

启动prometheus_gazebo下gazebo环境,带有仿真Mid360激光雷达的无人机模型,以及rviz

2.uav_control_main_outdoor.launch

启动文件2.png

在prometheus_uav_control,启动UAV1控制节点,Prometheus下控制,为后面路径规划发送控制指令做准备

3.sitl_ego_planner_mid360.launch

<launch>
  <arg name="uav_id" default="1"/>

  <!-- ego_planner 仿真 -->
  <include file="$(find ego_planner)/launch_for_prometheus/advanced_param_p600.xml">
    <!-- 无人机编号 -->
    <arg name="uav_id" value="$(arg uav_id)"/>
    <!-- 地图尺寸 -->
    <arg name="map_size_x_" value="100.0"/>
    <arg name="map_size_y_" value="100.0"/>
    <arg name="map_size_z_" value="3.0"/>
    <arg name="map_origin_x_" value="-25.0"/>
    <arg name="map_origin_y_" value="-25.0"/>
    <!-- 可以通过限制ground_height和map_size_z来使得飞机在特定高度飞行 -->
    <arg name="ground_height" value="0.5"/>
    <!-- 虚拟天花板高度要小于等于ground_height+z_size,否则重置该高度 -->
    <!-- 里程计话题 -->
    <arg name="odometry_topic" value="/mavros/local_position/odom"/>
    <!-- 相机及深度信息仿真中没有使用,此处可忽略(真机中使用) -->
    <arg name="camera_pose_topic" value="/depth/no_set"/>
    <arg name="depth_topic" value="/depth/image_rect_raw"/>
    <arg name="cx" value="321.04638671875"/>
    <arg name="cy" value="243.44969177246094"/>
    <arg name="fx" value="387.229248046875"/>
    <arg name="fy" value="387.229248046875"/>
    <!-- 点云信息,仿真中由map_generator产生 -->
    <!--arg name="cloud_topic" value="/uav$(arg uav_id)/octomap_point_cloud_centers"/-->
	<arg name="cloud_topic" value="/uav1/livox/lidar"/>
    <!-- scan -->
    <arg name="scan_topic" value="no_scan"/>
    <!-- 最大速度及加速度 -->
    <arg name="max_vel" value="0.8" />
    <arg name="max_acc" value="6" />
    <!-- 规划的范围,一般设置为感知范围的1.5倍 -->
    <arg name="planning_horizon" value="7.5" /> 
    <!-- ? -->
    <arg name="use_distinctive_trajs" value="true" />
    <!-- 1: use 2D Nav Goal to select goal  -->
    <!-- 2: use global waypoints below  -->
    <!-- 单机建议直接使用rviz指定目标点,多机情况请预设目标点 -->
    <arg name="flight_type" value="1" />
    <!-- global waypoints -->
    <!-- It generates a piecewise min-snap traj passing all waypoints -->
    <arg name="point_num" value="4" />
    <arg name="point0_x" value="-6.0" />
    <arg name="point0_y" value="-3.0" />
    <arg name="point0_z" value="1.5" />

    <arg name="point1_x" value="0.0" />
    <arg name="point1_y" value="3.0" />
    <arg name="point1_z" value="1.5" />

    <arg name="point2_x" value="3.0" />
    <arg name="point2_y" value="-3.0" />
    <arg name="point2_z" value="1.5" />

    <arg name="point3_x" value="6.0" />
    <arg name="point3_y" value="-7.0" />
    <arg name="point3_z" value="1.5" />
    <!-- 仿真 -->
    <arg name="realworld_experiment" value="true" />
  </include>

  <!-- trajectory server:由B样条生成轨迹 -->
  <!-- 偏航角初始值,重要参数 -->
  <arg name="yaw_init" default="0.0"/>
  <node pkg="ego_planner" name="uav$(arg uav_id)_traj_server_for_prometheus" type="traj_server_for_prometheus" output="screen">
    <param name="uav_id" value="$(arg uav_id)"/>
    <param name="control_flag" value="0"/>
    <param name="traj_server/time_forward" value="1.0"/>
    <param name="traj_server/last_yaw" value="$(arg yaw_init)"/>
  </node>
  
  <node pkg="plan_env" name="uav$(arg uav_id)mid360_point2_world" type="mid360_point2_world" output="screen"/>
  
</launch>

在ego_planner包下启动ego_planner 仿真,并由B样条生成轨迹,发送控制指令给无人机,控制飞行。其中包含两部分/uav1_ego_planner_node/uav1_traj_server_for_prometheus

前者/uav1_ego_planner_node进行ego_planner规划,相关源代码参见ego_planner_node.cpp ,ego_replan_fsm.cpp,planner_manager.cpp,路径:/home/amov/Prometheus/Modules/ego_planner_swarm/plan_manage/src/。

EGO-Planner是一个无ESDF(欧几里得符号距离场)的基于梯度的局部路径规划框架,EGO-Planner由基于梯度的样条优化器和后细化两部分组成。

可以查看EGO-Planner代码讲解来深入了解EGO-Planner

后者/uav1_traj_server_for_prometheus订阅ego_planner规划结果,由B样条(bspline)生成轨迹,转化为command命令控制无人机飞行。其源代码为traj_server_for_prometheus.cpp,路径:/home/amov/Prometheus/Modules/ego_planner_swarm/plan_manage/src_for_prometheus/

同时启动/uav1mid360_point2_world节点,用于将mid360雷达的数据从lidar_link转到world下,用于ego膨胀点云的数据生成。

操作演示视频

注意

终端显示的红色字体

WARNING: disk usage in log directory [/home/amov/.ros/log] is over 1GB. It's recommended that you use the 'rosclean' command.

可通过如下指令消除: rosclean purge 如下图所示:

image.png

多机避障

仿真Demo - D435i视觉避障

效果展示

提示

运行Demo前请将该模块编译

编译代码如下:

cd ~/Prometheus
catkin_make --source Modules/ego_planner_swarm --build build/ego_planner_swarm

仿真脚本启动流程

  1. 将FS-i6s遥控器开机并通过USB接口接入电脑

  2. 输入以下命令启动D435i 集群避障仿真demo

cd ~/Prometheus/Scripts/simulation/ego_planner/
# 第一次启动该脚本时,需要添加可执行权限
chmod +x ego_planner_p450_d435i_depth_swarm.sh
 ./ego_planner_p450_d435i_depth_swarm.sh

检查终端运行是否正常

  1. ROS主节点 - 下图所示为正常运行

image.png

  1. PX4 仿真 - 下图所示为正常运行

image.png

  1. Prometheus控制 - 下图所示为正常运行

image.png

  1. Ego-swarm 集群规划避障 - 下图所示为正常运行

image.png

开始仿真

  1. 等待rviz显示三台无人机

image.png

  1. 将遥控器SWA向下拨动以解锁无人机

image.png

解锁成功,第三个终端会出现 “vehicle arming, success!” 字样,并且Gazebo中无人机解锁。

  1. 遥控器SWB档杆拨到中间位置将无人机控制状态切换到 RC_POS_CONTROL

image.png

切换成功,第三个终端会出现“Switch to RC_POS_CONTROL”字样,且无人机螺旋桨加速旋转。

  1. 遥控器SWB档杆拨到最底部将无人机控制状态切换到 COMMAND_CONTROL

image.png

切换成功,第三个终端会出现 “Switch to COMMAND_CONTROL” 字样,且无人机会自动起飞到2m高度。

  1. 等待三台无人机都起飞到指定高度后,鼠标左键点击rviz里的3D Nav Goal,然后在rviz界面点击鼠标左键选择目标点,同时按住鼠标右键往上拖动

image.png

3D Nav Goal 位置如上图所示

注意

如果不按住鼠标左键,在画面内向上划,提供Z的高度,那么Z的高度默认为0,则会出现到达不了目标点的情况!
  1. 当飞机到达目标点后可再次选择目标点进行规划

节点运行图

image.png

ego-swarm仿真demo主要包含: /gazebo 、/motion_goal_swarm 、/uav1_ego_planner_node 、/uav2_ego_planner_node 、/uav3_ego_planner_node 、/uav1_traj_server_forprometheus 、/uav2_traj_server_forprometheus 、/uav3_traj_server_forprometheus 、/joy_node 、/uav_control_main_1 、/uav_control_main_2 、/uav_control_main_3 、/uav1_mavros 、/uav2_mavros 、/uav3_mavros等节点。
  • /gazebo 节点为gazebo ROS驱动节点,为ego-swarm提供深度点云数据,来进行建图

  • /motion_goal_swarm 节点为rviz指点节点,为每台无人机提供规划的目标点

  • /uav1_ego_planner_node 节点为ego-swarm的规划节点,根据输入的深度点云数据建立膨胀地图,并规划出可行路径,输出/broadcast_bspline话题到/uav2_ego_planner_node、/uav3_ego_planner_node节点,这两个节点根据1号无人机的轨迹再生成安全的轨迹,避免与1号无人机发生碰撞。同时输出/uav1/planning/bspline话题,将B样条曲线给到/uav1_traj_server_for_prometheus节点

  • /uav1_traj_server_for_prometheus 节点为轨迹生成节点,根据B样条(bspline)生成一系列轨迹点,然后转化为/uav1/prometheus/command话题控制1号无人机飞行

  • /uav2_ego_planner_node 节点为ego-swarm的规划节点,根据输入的深度点云数据建立膨胀地图,并规划出可行路径,输出/broadcast_bspline话题到/uav2_ego_planner_node、/uav1_ego_planner_node节点,这两个节点根据2号无人机的轨迹再生成安全的轨迹,避免与2号无人机发生碰撞。同时输出/uav2/planning/bspline话题,将B样条曲线给到/uav2_traj_server_for_prometheus节点

  • /uav2_traj_server_for_prometheus 节点为轨迹生成节点,根据B样条(bspline)生成一系列轨迹点,然后转化为/uav2/prometheus/command话题控制2号无人机飞行

  • /uav3_ego_planner_node 节点为ego-swarm的规划节点,根据输入的深度点云数据建立膨胀地图,并规划出可行路径,输出/broadcast_bspline话题到/uav1_ego_planner_node、/uav2_ego_planner_node节点,这两个节点根据3号无人机的轨迹再生成安全的轨迹,避免与3号无人机发生碰撞。同时输出/uav3/planning/bspline话题,将B样条曲线给到/uav3_traj_server_for_prometheus节点

  • /uav3_traj_server_for_prometheus 节点为轨迹生成节点,根据B样条(bspline)生成一系列轨迹点,然后转化为/uav3/prometheus/command话题控制2号无人机飞行

  • /joy_node 节点为遥控器ROS驱动节点,用以获取遥控器数据,将遥控器数据传输给/uav_control_main_1、/uav_control_main_2、/uav_control_main_3节点。

  • /uav1/mavros 节点为飞控ROS驱动节点,与飞控进行数据交互。在仿真中,该驱动节点与模拟飞控进行数据交互。

  • /uav2/mavros 节点为飞控ROS驱动节点,与飞控进行数据交互。在仿真中,该驱动节点与模拟飞控进行数据交互。

  • /uav3/mavros 节点为飞控ROS驱动节点,与飞控进行数据交互。在仿真中,该驱动节点与模拟飞控进行数据交互。

从节点运行图中,我们可以看到有如下的数据话题

  • /uav*/prometheus/command: 无人机控制接口,对应的消息为prometheus_msgs/UAVCommand

  • /uav*/prometheus/state: 无人机状态,对应的消息为prometheus_msgs/UAVState

  • /uav*/prometheus/fake_rc_in: 仿真模拟PX4遥控器数据

  • /uav*/camera/depth/image_raw: 深度点云话题输入

  • /broadcast_bspline: 广播的B样条

  • /uav*/planning/bspline: 发布的B样条

代码讲解

脚本位于~/Prometheus/Scripts/simulation/ego_planner/ego_planner_p450_d435i_depth_swarm.sh,内容如下:

# 脚本描述: 
gnome-terminal --window -e 'bash -c "roscore; exec bash"' \
--tab -e 'bash -c "sleep 3; roslaunch prometheus_gazebo sitl_p450_d435i_swarm.launch ; exec bash"' \
--tab -e 'bash -c "sleep 4; roslaunch prometheus_uav_control uav_control_main_intdoor_swarm.launch ; exec bash"' \
--tab -e 'bash -c "sleep 6; roslaunch ego_planner sitl_ego_planner_basic_octomap_d435i_swarm_depth.launch; exec bash"' \

除了运行ros必备启动的roscore,脚本依次运行了三个launch文件 1、sitl_p450_d435i_swarm.launch

2、uav_control_main_intdoor_swarm.launch

3、sitl_ego_planner_basic_octomap_d435i_swarm_depth.launch

依次查看

1、sitl_p450_d435i_swarm.launch

<launch>  
  <!-- Gazebo configs -->
    <arg name="gazebo_enable" default="true"/>
  <arg name="world" default="$(find prometheus_gazebo)/gazebo_worlds/planning_worlds/planning_easy_swarm.world"/>
    <!-- 启动Gazebo -->
  <group if="$(arg gazebo_enable)">
      <include file="$(find gazebo_ros)/launch/empty_world.launch">
          <arg name="world_name" value="$(arg world)"/>
    <!-- 设置为false,使用系统时间 -->
    <arg name="use_sim_time" value="true"/>
    <arg name="gui" value="true"/>
      </include>
  </group>

    <!-- Rviz config -->
  <arg name="rviz_enable" default="true"/>
  <arg name="rivz_config" default="$(find prometheus_gazebo)/launch_uav_with_sensor/visual_mapping_swarm.rviz"/>
  <!-- 启动Rviz-->
  <group if="$(arg rviz_enable)">
        <node type="rviz" name="rviz" pkg="rviz" args="-d $(arg rivz_config)"/>
  </group>
  <arg name="vehicle" default="p450_D435i"/>
  <!--无人机编号-->
  <arg name="uav1_id" default="1"/>
  <arg name="uav2_id" default="2"/>
  <arg name="uav3_id" default="3"/>
  <!-- 无人机初始位置 -->
  <!--arg name="uav1_init_x" default="-6"/>
  <arg name="uav1_init_y" default="2.5"/>
  <arg name="uav1_init_yaw" default="0.0"/>
  <arg name="uav2_init_x" default="-6"/>
  <arg name="uav2_init_y" default="0.5"/>
  <arg name="uav2_init_yaw" default="0.0"/>
  <arg name="uav3_init_x" default="-6"/>
  <arg name="uav3_init_y" default="-2.5"/>
  <arg name="uav3_init_yaw" default="0.0"/>
  <arg name="uav4_init_x" default="-6"/>
  <arg name="uav4_init_y" default="-5"/>
  <arg name="uav4_init_yaw" default="0.0"/-->
  <arg name="uav1_init_x" default="0"/>
  <arg name="uav1_init_y" default="1"/>
  <arg name="uav1_init_yaw" default="0.0"/>
  <arg name="uav2_init_x" default="0"/>
  <arg name="uav2_init_y" default="0"/>
  <arg name="uav2_init_yaw" default="0.0"/>
  <arg name="uav3_init_x" default="0"/>
  <arg name="uav3_init_y" default="-1"/>
  <arg name="uav3_init_yaw" default="0.0"/>
 
  <!-- 1号无人机 -->
  <include file="$(find prometheus_gazebo)/launch_basic/sitl_px4_indoor.launch">
    <arg name="uav_id" value="$(arg uav1_id)"/>
    <arg name="vehicle" value="$(arg vehicle)"/>
    <arg name="uav_init_x" value="$(arg uav1_init_x)"/>
    <arg name="uav_init_y" value="$(arg uav1_init_y)"/>
    <arg name="uav_init_z" value="0.15"/>
    <arg name="uav_init_yaw" value="$(arg uav1_init_yaw)"/>
  </include>

  <!-- 2号无人机 -->
  <include file="$(find prometheus_gazebo)/launch_basic/sitl_px4_indoor.launch">
    <arg name="uav_id" value="$(arg uav2_id)"/>
    <arg name="vehicle" value="$(arg vehicle)"/>
    <arg name="uav_init_x" value="$(arg uav2_init_x)"/>
    <arg name="uav_init_y" value="$(arg uav2_init_y)"/>
    <arg name="uav_init_z" value="0.15"/>
    <arg name="uav_init_yaw" value="$(arg uav2_init_yaw)"/>
  </include>

  <!-- 3号无人机 -->
  <include file="$(find prometheus_gazebo)/launch_basic/sitl_px4_indoor.launch">
    <arg name="uav_id" value="$(arg uav3_id)"/>
    <arg name="vehicle" value="$(arg vehicle)"/>
    <arg name="uav_init_x" value="$(arg uav3_init_x)"/>
    <arg name="uav_init_y" value="$(arg uav3_init_y)"/>
    <arg name="uav_init_z" value="0.15"/>
    <arg name="uav_init_yaw" value="$(arg uav3_init_yaw)"/>
  </include>

  <!-- TF for world and map-->
  <!-- 如果模型中使用了D435i,将下列TF转换打开 -->
    <node pkg="tf" type="static_transform_publisher" name="tf_camera_d435i_$(arg uav1_id)"
        args="0 0 0 0 0 0 /uav$(arg uav1_id)/camera_link /uav$(arg uav1_id)/d435i_link 100"/>

    <node pkg="tf" type="static_transform_publisher" name="tf_camera_d435i_$(arg uav2_id)"
        args="0 0 0 0 0 0 /uav$(arg uav2_id)/camera_link /uav$(arg uav2_id)/d435i_link 100"/>

    <node pkg="tf" type="static_transform_publisher" name="tf_camera_d435i_$(arg uav3_id)"
        args="0 0 0 0 0 0 /uav$(arg uav3_id)/camera_link /uav$(arg uav3_id)/d435i_link 100"/>

</launch>

上面launch文件用于启动prometheus_gazebo下gazebo环境,带有仿真D435i的无人机模型,以及rviz显示。

2、uav_control_main_intdoor_swarm.launch

<launch>
  <arg name="uav1_id" default="1"/>
  <arg name="uav2_id" default="2"/>
  <arg name="uav3_id" default="3"/>

  <arg name="sim_mode" default="true"/>
  <arg name="flag_printf" default="true"/>
  <!-- 如果是matlab配置为ATT_CTRL_MODE,则此处要设置为True-->
  <arg name="control/enable_external_control" default="false"/> 
  <arg name="launch_prefix" default="" />
  
  <arg name="agent_num" default="3"/>
  <!-- 启动uav_control_main -->
  <!-- 1号飞机 -->
    <node pkg="prometheus_uav_control" type="uav_control_main" name="uav_control_main_$(arg uav1_id)" output="screen">
    <param name="uav_id" value="$(arg uav1_id)" />
    <param name="sim_mode" value="$(arg sim_mode)" />
  	  <param name="flag_printf" value="$(arg flag_printf)" />
      <param name="control/enable_external_control" value="$(arg control/enable_external_control)" />
  	  <rosparam command="load" file="$(find prometheus_uav_control)/launch/uav_control_indoor.yaml" />
  	  <param name="control/Takeoff_height" value="2" />
    <rosparam command="load" file="$(find prometheus_uav_control)/launch/sensor_tf_offset.yaml" />
    </node>

  <!-- 2号飞机 -->
  <node pkg="prometheus_uav_control" type="uav_control_main" name="uav_control_main_$(arg uav2_id)" output="screen">
    <param name="uav_id" value="$(arg uav2_id)" />
    <param name="sim_mode" value="$(arg sim_mode)" />
    <param name="flag_printf" value="$(arg flag_printf)" />
    <param name="control/enable_external_control" value="$(arg control/enable_external_control)" />
    <rosparam command="load" file="$(find prometheus_uav_control)/launch/uav_control_indoor.yaml" />
    <param name="control/Takeoff_height" value="2" />
    <rosparam command="load" file="$(find prometheus_uav_control)/launch/sensor_tf_offset.yaml" />
  </node>

  <!-- 3号飞机 -->
  <node pkg="prometheus_uav_control" type="uav_control_main" name="uav_control_main_$(arg uav3_id)" output="screen">
    <param name="uav_id" value="$(arg uav3_id)" />
    <param name="sim_mode" value="$(arg sim_mode)" />
    <param name="flag_printf" value="$(arg flag_printf)" />
    <param name="control/enable_external_control" value="$(arg control/enable_external_control)" />
    <rosparam command="load" file="$(find prometheus_uav_control)/launch/uav_control_indoor.yaml" />
    <param name="control/Takeoff_height" value="2" />
    <rosparam command="load" file="$(find prometheus_uav_control)/launch/sensor_tf_offset.yaml" />
  </node>

  <!-- 启动虚拟摇杆驱动 -->
  <arg name="joy_enable" default="true"/>
  <group if="$(arg joy_enable)">
      <node pkg="prometheus_uav_control" type="joy_node" name="joy_node" output="screen">
          <param name="agent_num" value="$(arg agent_num)"/>
      </node>
  </group>
</launch>

上面launch文件用于启动UAV控制节点,在Prometheus下控制,为后面路径规划发送控制指令做准备

3、sitl_ego_planner_basic_octomap_d435i_swarm_depth.launch

<launch>
  <arg name="uav1_id" default="1"/>
  <arg name="uav2_id" default="2"/>
  <arg name="uav3_id" default="3"/>
  
  <!-- ego_planner 仿真 -->
  <include file="$(find ego_planner)/launch_for_prometheus/advanced_param_swarm.xml">
    <!-- 无人机编号 -->
    <arg name="uav1_id" value="$(arg uav1_id)"/>
    <arg name="uav2_id" value="$(arg uav2_id)"/>
    <arg name="uav3_id" value="$(arg uav3_id)"/>

    <!-- 地图尺寸 -->
    <arg name="map_size_x_" value="50.0"/>
    <arg name="map_size_y_" value="50.0"/>
    <arg name="map_size_z_" value="4.0"/>
    <arg name="map_origin_x_" value="-25.0"/>
    <arg name="map_origin_y_" value="-25.0"/>
    <!-- 可以通过限制ground_height和map_size_z来使得飞机在特定高度飞行 -->
    <arg name="ground_height" value="0.5"/>
    <!-- 虚拟天花板高度要小于等于ground_height+z_size,否则重置该高度 -->
    <!-- 里程计话题 -->
    <arg name="odometry_topic" value="/mavros/local_position/odom"/>
    <!-- 相机及深度信息仿真中没有使用,此处可忽略(真机中使用) -->
    <arg name="camera_pose_topic" value="/depth/no_set"/>
    <arg name="depth1_topic" value="/uav$(arg uav1_id)/camera/depth/image_raw"/>
    <arg name="depth2_topic" value="/uav$(arg uav2_id)/camera/depth/image_raw"/>
    <arg name="depth3_topic" value="/uav$(arg uav3_id)/camera/depth/image_raw"/>

    <arg name="cx" value="321.04638671875"/>
    <arg name="cy" value="243.44969177246094"/>
    <arg name="fx" value="387.229248046875"/>
    <arg name="fy" value="387.229248046875"/>
    <!-- 点云信息,仿真中由map_generator产生 -->
    <arg name="cloud1_topic" value=""/>
    <arg name="cloud2_topic" value=""/>
    <arg name="cloud3_topic" value=""/>
    
    <!-- scan -->
    <arg name="scan_topic" value="no_scan"/>
    <!-- 最大速度及加速度 -->
    <!--arg name="max_vel" value="0.8" /-->
    <!--arg name="max_acc" value="6" /-->
    <arg name="max_vel" value="0.8" />
    <arg name="max_acc" value="3" />
    <!-- 规划的范围,一般设置为感知范围的1.5倍 7.5-->
    <arg name="planning_horizon" value="7.5" /> 

    <arg name="use_distinctive_trajs" value="true" />
    <!-- 1: use 2D Nav Goal to select goal  -->
    <!-- 2: use global waypoints below  -->
    <!-- 单机建议直接使用rviz指定目标点,多机情况请预设目标点 -->
    <arg name="flight_type" value="1" />
    <!-- global waypoints -->
    <!-- It generates a piecewise min-snap traj passing all waypoints -->
    <arg name="point_num" value="1" />
    <arg name="point0_x" value="7.0" />
    <arg name="point0_y" value="0.0" />
    <arg name="point0_z" value="1.5" />
    
    <!-- 仿真 -->
    <arg name="realworld_experiment" value="true" />
  </include>

  <!-- trajectory server:由B样条生成轨迹 -->
  <!-- 偏航角初始值,重要参数 -->
  <arg name="yaw_init" default="0.0"/>
  <node pkg="ego_planner" name="uav$(arg uav1_id)_traj_server_for_prometheus" type="traj_server_for_prometheus" output="screen">
    <param name="uav_id" value="$(arg uav1_id)"/>
    <param name="control_flag" value="0"/>
    <param name="traj_server/time_forward" value="1.0"/>
    <param name="traj_server/last_yaw" value="$(arg yaw_init)"/>
  </node>
  
  <node pkg="ego_planner" name="uav$(arg uav2_id)_traj_server_for_prometheus" type="traj_server_for_prometheus" output="screen">
    <param name="uav_id" value="$(arg uav2_id)"/>
    <param name="control_flag" value="0"/>
    <param name="traj_server/time_forward" value="1.0"/>
    <param name="traj_server/last_yaw" value="$(arg yaw_init)"/>
  </node>
  
  <node pkg="ego_planner" name="uav$(arg uav3_id)_traj_server_for_prometheus" type="traj_server_for_prometheus" output="screen">
    <param name="uav_id" value="$(arg uav3_id)"/>
    <param name="control_flag" value="0"/>
    <param name="traj_server/time_forward" value="1.0"/>
    <param name="traj_server/last_yaw" value="$(arg yaw_init)"/>
  </node>
  <node pkg="ego_planner" name="motion_goal_swarm" type="motion_goal_swarm" output="screen"/>

</launch>

上面 launch文件在ego_planner包下启动ego_planner 仿真,并由B样条生成轨迹,发送控制指令给每台无人机,控制飞行。其中包含两部分/uav*_ego_planner_node和/uav*_traj_server_for_prometheus:

  • /uav*_ego_planner_node进行ego_planner规划,相关源代码参见ego_planner_node.cpp ,ego_replan_fsm.cpp,planner_manager.cpp,文件路径: ~/Prometheus/Modules/ego_planner_swarm/plan_manage/src/。
  • /uav*_traj_server_for_prometheus订阅ego_planner规划结果,由B样条(bspline)生成轨迹,转化为command命令控制无人机飞行。其源代码为traj_server_for_prometheus.cpp,文件路径: ~/Prometheus/Modules/ego_planner_swarm/plan_manage/src_for_prometheus/**

操作演示视频

仿真Demo - 二维激光雷达避障

效果展示

提示

运行Demo前请将该模块编译

编译代码如下:

cd ~/Prometheus
catkin_make --source Modules/ego_planner_swarm --build build/ego_planner_swarm

仿真脚本启动流程

  1. 将FS-i6s遥控器开机并通过USB接口接入电脑

  2. 输入以下命令启动二维激光雷达集群避障仿真demo

cd ~/Prometheus/Scripts/simulation/ego_planner/
# 第一次启动该脚本时,需要添加可执行权限
chmod +x ego_planner_p450_2dlidar_swarm.sh
 ./ego_planner_p450_2dlidar_swarm.sh

检查终端运行是否正常

  1. ROS主节点 - 下图所示为正常运行

image.png

  1. PX4 仿真 - 下图所示为正常运行

image.png

  1. Prometheus控制 - 下图所示为正常运行

image.png

  1. 雷达滤波 - 下图所示为正常运行

image.png

  1. Octomap建图 - 下图所示为正常运行

image.png

6. Ego-swarm 集群规划避障 - 下图所示为正常运行

image.png

开始仿真

  1. 等待rviz显示三台无人机

image.png

  1. 将遥控器SWA向下拨动以解锁无人机

image.png

解锁成功,第三个终端会出现“vehicle arming, success!”字样,并且Gazebo中无人机解锁。

  1. 遥控器SWB档杆拨到中间位置将无人机控制状态切换到 RC_POS_CONTROL

image.png

切换成功,第三个终端会出现“Switch to RC_POS_CONTROL”字样,且无人机螺旋桨加速旋转。
  1. 遥控器SWB档杆拨到最底部将无人机控制状态切换到 COMMAND_CONTROL

image.png

切换成功,第三个终端会出现“Switch to COMMAND_CONTROL”字样,且无人机会自动起飞到2m高度。
  1. 等待三台无人机都起飞到指定高度后,鼠标左键点击rviz里的3D Nav Goal(位置在下图箭头1所示),然后在rviz界面点击鼠标左键选择目标点,同时按住鼠标右键往上拖动(如箭头2所示)

image.png

注意

如果不按住鼠标左键,在画面内向上划,提供Z的高度,那么Z的高度默认为0,则会出现到达不了目标点的情况!
  1. 目标点设置成功后,会出现三个终点(如下图中箭头1所示); ego-planner会规划出可行路径(如下图中箭头2所示),三台无人机按照路径飞行。

image.png

  1. 在无人机到达指定目标点后,可重复步骤5 6 ,再次规划下一个目标点。

节点运行图

image.png

二维激光雷达集群避障仿真demo主要包含: /gazebo 、/motion_goal_swarm 、/uav1_ego_planner_node 、/uav2_ego_planner_node 、/uav3_ego_planner_node 、/uav1_traj_server_forprometheus 、/uav2_traj_server_forprometheus 、/uav3_traj_server_forprometheus 、/joy_node 、/uav_control_main_1 、/uav_control_main_2 、/uav_control_main_3 、/uav1_mavros 、/uav2_mavros 、/uav3_mavros、/laser_filter1、/laser_filter2、/laser_filter3、/laser_to_pointcloud_1、/laser_to_pointcloud_2、/laser_to_pointcloud_3、/octomap_server_1、/octomap_server_2、/octomap_server_3 等节点。
  • /gazebo 节点为gazebo ROS驱动节点,为ego-swarm提供深度点云数据,来进行建图

  • /motion_goal_swarm 节点为rviz指点节点,为每台无人机提供规划的目标点

  • /uav1_ego_planner_node 节点为ego-swarm的规划节点,根据/octomap_server_1输入的点云数据建立膨胀地图,并规划出可行路径,输出/broadcast_bspline话题到/uav2_ego_planner_node、/uav3_ego_planner_node节点,这两个节点根据1号无人机的轨迹再生成安全的轨迹,避免与1号无人机发生碰撞。同时输出/uav1/planning/bspline话题,将B样条曲线给到/uav1_traj_server_for_prometheus节点

  • /uav1_traj_server_for_prometheus 节点为轨迹生成节点,根据B样条(bspline)生成一系列轨迹点,然后转化为/uav1/prometheus/command话题控制1号无人机飞行

  • /uav2_ego_planner_node 节点为ego-swarm的规划节点,根据/octomap_server_2输入的点云数据建立膨胀地图,并规划出可行路径,输出/broadcast_bspline话题到/uav2_ego_planner_node、/uav1_ego_planner_node节点,这两个节点根据2号无人机的轨迹再生成安全的轨迹,避免与2号无人机发生碰撞。同时输出/uav2/planning/bspline话题,将B样条曲线给到/uav2_traj_server_for_prometheus节点

  • /uav2_traj_server_for_prometheus 节点为轨迹生成节点,根据B样条(bspline)生成一系列轨迹点,然后转化为/uav2/prometheus/command话题控制2号无人机飞行

  • /uav3_ego_planner_node 节点为ego-swarm的规划节点,根据/octomap_server_3输入的点云数据建立膨胀地图,并规划出可行路径,输出/broadcast_bspline话题到/uav1_ego_planner_node、/uav2_ego_planner_node节点,这两个节点根据3号无人机的轨迹再生成安全的轨迹,避免与3号无人机发生碰撞。同时输出/uav3/planning/bspline话题,将B样条曲线给到/uav3_traj_server_for_prometheus节点

  • /uav3_traj_server_for_prometheus 节点为轨迹生成节点,根据B样条(bspline)生成一系列轨迹点,然后转化为/uav3/prometheus/command话题控制2号无人机飞行

  • /joy_node 节点为遥控器ROS驱动节点,用以获取遥控器数据,将遥控器数据传输给/uav_control_main_1、/uav_control_main_2、/uav_control_main_3节点。

  • /uav1/mavros 节点为飞控ROS驱动节点,与1号无人机飞控进行数据交互。在仿真中,该驱动节点与模拟飞控进行数据交互。

  • /uav2/mavros 节点为飞控ROS驱动节点,与2号无人机飞控进行数据交互。在仿真中,该驱动节点与模拟飞控进行数据交互。

  • /uav3/mavros 节点为飞控ROS驱动节点,与3号无人机飞控进行数据交互。在仿真中,该驱动节点与模拟飞控进行数据交互。

  • /laser_filter1 节点为ROS感知模块节点,它为1号无人机提供了一系列滤波器,用于处理来自激光雷达传感器的数据。这些滤波器可以帮助你消除噪声、平滑扫描或者根据需要进行其他定制化操作。为/laser_to_pointcloud_1节点提供滤波后雷达数据

  • /laser_filter2 节点为ROS感知模块节点,它为2号无人机提供了一系列滤波器,用于处理来自激光雷达传感器的数据。这些滤波器可以帮助你消除噪声、平滑扫描或者根据需要进行其他定制化操作。为/laser_to_pointcloud_2节点提供滤波后雷达数据

  • /laser_filter3 节点为ROS感知模块节点,它为1号无人机提供了一系列滤波器,用于处理来自激光雷达传感器的数据。这些滤波器可以帮助你消除噪声、平滑扫描或者根据需要进行其他定制化操作。为/laser_to_pointcloud_3节点提供滤波后雷达数据

  • laser_to_pointcloud_1 节点将1号无人机的激光雷达数据转换为sensor_msgs::PointCloud2 点云格式,为/octomap_server建图提供数据

  • laser_to_pointcloud_2 节点将2号无人机的激光雷达数据转换为sensor_msgs::PointCloud2 点云格式,为/octomap_server建图提供数据

  • laser_to_pointcloud_3 节点将3号无人机的激光雷达数据转换为sensor_msgs::PointCloud2 点云格式,为/octomap_server建图提供数据

  • /octomap_server_1 节点根据获取1号无人机的点云数据并进行建图

  • /octomap_server_2 节点根据获取2号无人机的点云数据并进行建图

  • /octomap_server_3 节点根据获取3号无人机的点云数据并进行建图

从节点运行图中,我们可以看到有如下的数据话题

  • /uav*/prometheus/command: 无人机控制接口,对应的消息为prometheus_msgs/UAVCommand

  • /uav*/prometheus/state: 无人机状态,对应的消息为prometheus_msgs/UAVState

  • /uav*/prometheus/fake_rc_in: 仿真模拟PX4遥控器数据

  • /uav*/scan: 二维激光雷达点云话题输入

  • /uav*/scan_filtered : 过滤后的点云数据

  • /uav*/prometheus/scan_point_cloud : octomap生成的全局点云数据

  • /broadcast_bspline: 广播的B样条

  • /uav*/planning/bspline: 发布的B样条

代码讲解

脚本位置: /home/amov/Prometheus/Scripts/simulation/ego_planner/ego_planner_p450_2dlidar_swarm.sh,内容如下:

# 脚本描述: 
gnome-terminal --window -e 'bash -c "roscore; exec bash"' \
--tab -e 'bash -c "sleep 3; roslaunch prometheus_gazebo sitl_p450_2dlidar_swarm.launch; exec bash"' \
--tab -e 'bash -c "sleep 5; roslaunch prometheus_uav_control uav_control_main_intdoor_swarm.launch; exec bash"' \
--tab -e 'bash -c "sleep 6; roslaunch prometheus_gazebo filter_lidar_swarm.launch; exec bash"' \
--tab -e 'bash -c "sleep 7; roslaunch prometheus_gazebo scan_to_octomap_swarm.launch; exec bash"' \
--tab -e 'bash -c "sleep 8; roslaunch ego_planner sitl_ego_planner_basic_octomap_lidar_swarm.launch; exec bash"' \

除了运行ros必备启动的roscore,脚本依次运行了五个launch文件

  1. sitl_p450_2dlidar_swarm.launch
  2. uav_control_main_intdoor_swarm.launch
  3. filter_lidar_swarm.launch
  4. scan_to_octomap_swarm.launch
  5. sitl_ego_planner_basic_octomap_lidar_swarm.launch

依次查看每个文件

  1. sitl_p450_2dlidar_swarm.launch
<launch>  
	<!-- Gazebo configs -->
    <arg name="gazebo_enable" default="true"/>
	<arg name="world" default="$(find prometheus_gazebo)/gazebo_worlds/planning_worlds/planning_easy_swarm.world"/>
    <!-- 启动Gazebo -->
    <group if="$(arg gazebo_enable)">
        <include file="$(find gazebo_ros)/launch/empty_world.launch">
            <arg name="world_name" value="$(arg world)"/>
			<!-- 设置为false,使用系统时间 -->
			<arg name="use_sim_time" value="true"/>
			<arg name="gui" value="true"/>
        </include>
    </group>

    <!-- Rviz config -->
    <arg name="rviz_enable" default="true"/>
    <arg name="rivz_config" default="$(find prometheus_gazebo)/launch_uav_with_sensor/2dlidar_mapping_swarm.rviz"/>
	<!-- 启动Rviz-->
	<group if="$(arg rviz_enable)">
        <node type="rviz" name="rviz" pkg="rviz" args="-d $(arg rivz_config)"/>
    </group>
	<arg name="vehicle" default="p450_2Dlidar"/>

    <!--无人机编号-->
    <arg name="uav1_id" default="1"/>
    <arg name="uav2_id" default="2"/>
    <arg name="uav3_id" default="3"/>
	<!-- 无人机初始位置 -->
	<arg name="uav1_init_x"   default="1"/>
    <arg name="uav1_init_y"   default="1"/>
	<arg name="uav1_init_yaw" default="0.0"/>
    <arg name="uav2_init_x"   default="0"/>
    <arg name="uav2_init_y"   default="0"/>
	<arg name="uav2_init_yaw" default="0.0"/>
    <arg name="uav3_init_x"   default="1"/>
    <arg name="uav3_init_y"   default="-1"/>
	<arg name="uav3_init_yaw" default="0.0"/>

	<!-- 1号无人机 -->
	<include file="$(find prometheus_gazebo)/launch_basic/sitl_px4_indoor.launch">
		<arg name="uav_id" value="$(arg uav1_id)"/>
		<arg name="vehicle" value="$(arg vehicle)"/>
		<arg name="uav_init_x" value="$(arg uav1_init_x)"/>
		<arg name="uav_init_y" value="$(arg uav1_init_y)"/>
		<arg name="uav_init_z" value="0.1"/>
		<arg name="uav_init_yaw" value="$(arg uav1_init_yaw)"/>
	</include>
	<!-- 2号无人机 -->
	<include file="$(find prometheus_gazebo)/launch_basic/sitl_px4_indoor.launch">
		<arg name="uav_id" value="$(arg uav2_id)"/>
		<arg name="vehicle" value="$(arg vehicle)"/>
		<arg name="uav_init_x" value="$(arg uav2_init_x)"/>
		<arg name="uav_init_y" value="$(arg uav2_init_y)"/>
		<arg name="uav_init_z" value="0.1"/>
		<arg name="uav_init_yaw" value="$(arg uav2_init_yaw)"/>
	</include>
	<!-- 3号无人机 -->
	<include file="$(find prometheus_gazebo)/launch_basic/sitl_px4_indoor.launch">
		<arg name="uav_id" value="$(arg uav3_id)"/>
		<arg name="vehicle" value="$(arg vehicle)"/>
		<arg name="uav_init_x" value="$(arg uav3_init_x)"/>
		<arg name="uav_init_y" value="$(arg uav3_init_y)"/>
		<arg name="uav_init_z" value="0.1"/>
		<arg name="uav_init_yaw" value="$(arg uav3_init_yaw)"/>
	</include>

	<!-- TF for world and map-->
	<!-- 如果模型中使用了D435i,将下列TF转换打开 -->
     <node pkg="tf" type="static_transform_publisher" name="tf_camera_d435i_$(arg uav1_id)"
        args="0 0 0 0 0 0 /uav$(arg uav1_id)/camera_link /uav$(arg uav1_id)/d435i_link 100"/>

    <node pkg="tf" type="static_transform_publisher" name="tf_camera_d435i_$(arg uav2_id)"
        args="0 0 0 0 0 0 /uav$(arg uav2_id)/camera_link /uav$(arg uav2_id)/d435i_link 100"/>

    <node pkg="tf" type="static_transform_publisher" name="tf_camera_d435i_$(arg uav3_id)"
        args="0 0 0 0 0 0 /uav$(arg uav3_id)/camera_link /uav$(arg uav3_id)/d435i_link 100"/>
</launch>

启动prometheus_gazebo下gazebo环境,带有仿真二维激光雷达的无人机模型,以及rviz显示。

  1. uav_control_main_intdoor_swarm.launch
<launch>
    <!--arg name="uav_id" default="1"/-->
    <arg name="uav1_id" default="1"/>
    <arg name="uav2_id" default="2"/>
    <arg name="uav3_id" default="3"/>

    <arg name="sim_mode" default="true"/>
    <arg name="flag_printf" default="true"/>
    <!-- 如果是matlab配置为ATT_CTRL_MODE,则此处要设置为True-->
    <arg name="control/enable_external_control" default="false"/> 
    <arg name="launch_prefix" default="" />
    
    <arg name="agent_num" default="3"/>
    
    <!-- 启动uav_control_main -->
    <!-- 1号飞机 -->
	<node pkg="prometheus_uav_control" type="uav_control_main" name="uav_control_main_$(arg uav1_id)" output="screen">
		<param name="uav_id" value="$(arg uav1_id)" />
        <param name="sim_mode" value="$(arg sim_mode)" />
		<param name="flag_printf" value="$(arg flag_printf)" />
	<param name="control/enable_external_control" value="$(arg control/enable_external_control)" />
		<rosparam command="load" file="$(find prometheus_uav_control)/launch/uav_control_indoor.yaml" />
		<param name="control/Takeoff_height" value="2" />
        <rosparam command="load" file="$(find prometheus_uav_control)/launch/sensor_tf_offset.yaml" />
	</node>

    <!-- 2号飞机 -->
	<node pkg="prometheus_uav_control" type="uav_control_main" name="uav_control_main_$(arg uav2_id)" output="screen">
		<param name="uav_id" value="$(arg uav2_id)" />
        <param name="sim_mode" value="$(arg sim_mode)" />
		<param name="flag_printf" value="$(arg flag_printf)" />
	<param name="control/enable_external_control" value="$(arg control/enable_external_control)" />
		<rosparam command="load" file="$(find prometheus_uav_control)/launch/uav_control_indoor.yaml" />
		<param name="control/Takeoff_height" value="2" />
        <rosparam command="load" file="$(find prometheus_uav_control)/launch/sensor_tf_offset.yaml" />
	</node>

    <!-- 3号飞机 -->
	<node pkg="prometheus_uav_control" type="uav_control_main" name="uav_control_main_$(arg uav3_id)" output="screen">
		<param name="uav_id" value="$(arg uav3_id)" />
        <param name="sim_mode" value="$(arg sim_mode)" />
		<param name="flag_printf" value="$(arg flag_printf)" />
	<param name="control/enable_external_control" value="$(arg control/enable_external_control)" />
		<rosparam command="load" file="$(find prometheus_uav_control)/launch/uav_control_indoor.yaml" />
		<param name="control/Takeoff_height" value="2" />
        <rosparam command="load" file="$(find prometheus_uav_control)/launch/sensor_tf_offset.yaml" />
	</node>
       
    <!-- 启动虚拟摇杆驱动 -->
    <arg name="joy_enable" default="true"/>
    <group if="$(arg joy_enable)">
        <node pkg="prometheus_uav_control" type="joy_node" name="joy_node" output="screen">
            <param name="agent_num" value="$(arg agent_num)"/>
        </node>
    </group>
</launch>

启动prometheus_uav_control,将传感器通过tf变换,将数据转到全局坐标系下,Prometheus下控制,为后面路径规划发送控制指令做准备

  1. filter_lidar_swarm.launch
<launch>
  <arg name="uav1_id" default="1"/>
  <arg name="uav2_id" default="2"/>
  <arg name="uav3_id" default="3"/>
  
  <node pkg="laser_filters" type="scan_to_scan_filter_chain" output="screen" name="laser_filter_$(arg uav1_id)">
    <rosparam command="load" file="$(find prometheus_gazebo)/config/filter_lidar.yaml"/>
    <remap from="/scan" to="/uav$(arg uav1_id)/scan"/>
    <remap from="/scan_filtered" to="/uav$(arg uav1_id)/scan_filtered"/>
  </node>
  
    <node pkg="laser_filters" type="scan_to_scan_filter_chain" output="screen" name="laser_filter_$(arg uav2_id)">
    <rosparam command="load" file="$(find prometheus_gazebo)/config/filter_lidar_2.yaml"/>
    <remap from="/scan" to="/uav$(arg uav2_id)/scan"/>
    <remap from="/scan_filtered" to="/uav$(arg uav2_id)/scan_filtered"/>
  </node>
  
    <node pkg="laser_filters" type="scan_to_scan_filter_chain" output="screen" name="laser_filter_$(arg uav3_id)">
    <rosparam command="load" file="$(find prometheus_gazebo)/config/filter_lidar_3.yaml"/>
    <remap from="/scan" to="/uav$(arg uav3_id)/scan"/>
    <remap from="/scan_filtered" to="/uav$(arg uav3_id)/scan_filtered"/>
  </node>
  
</launch>

对每台无人机上二维激光雷达的数据进行滤波处理,屏蔽扫描到的无人机

  1. scan_to_octomap_swarm.launch
<launch>
  <arg name="uav1_id" default="1"/>
  <arg name="uav2_id" default="2"/>
  <arg name="uav3_id" default="3"/>
	<!-- run the laser_to_pointcloud -->
  <node pkg="plan_env" type="laser_to_pointcloud" name="laser_to_pointcloud_$(arg uav1_id)" output="screen">
      <param name="uav_id" value="$(arg uav1_id)" />
  </node>
  <node pkg="plan_env" type="laser_to_pointcloud" name="laser_to_pointcloud_$(arg uav2_id)" output="screen">
      <param name="uav_id" value="$(arg uav2_id)" />
  </node>
  <node pkg="plan_env" type="laser_to_pointcloud" name="laser_to_pointcloud_$(arg uav3_id)" output="screen">
      <param name="uav_id" value="$(arg uav3_id)" />
  </node>

  <!-- 启动octomap建图 -->
  <node pkg="octomap_server" type="octomap_server_node" name="octomap_server_$(arg uav1_id)" output="screen">
      <remap from="/octomap_point_cloud_centers" to="/uav$(arg uav1_id)/octomap_point_cloud_centers"/>
      <remap from="/octomap_full" to="/uav$(arg uav1_id)/octomap_full"/>
      <remap from="/octomap_binary" to="/uav$(arg uav1_id)/octomap_binary"/>
      
      <!-- 地图分辨率 -->
      <param name="resolution" value="0.1" />
      <!-- 发布地图的坐标系 -->
      <param name="frame_id" type="string" value="world" />
      <!-- 传感器最大感知范围 (speedup!) -->
      <param name="sensor_model/max_range" value="10" />
      <!-- 局部点云话题输入 -->
      <remap from="cloud_in" to="/uav$(arg uav1_id)/prometheus/scan_point_cloud" />
      <!-- 直通滤波的 Z 轴范围,保留 [-1.0, 10.0] 范围内的点 -->
      <!-- <param name = "pointcloud_max_z" value = "1.7" />
      <param name = "pointcloud_min_z" value = "1.4" /> -->
      <!-- 机器人坐标系 base_link,滤除地面需要该 frame -->
      <param name = "base_frame_id" type = "string" value = "world" />
      <!-- filter ground plane, distance value should be big! 项目并不需要滤除地面 -->
      <param name = "filter_ground" type = "bool" value = "true" />
      <param name = "ground_filter/distance" type = "double" value = "0.5" />
      <param name = "ground_filter/angle" type = "double" value = "0.7853" />
      <param name = "ground_filter/plane_distance" type = "double" value = "0.5" />

  </node>
  
  <node pkg="octomap_server" type="octomap_server_node" name="octomap_server_$(arg uav2_id)" output="screen">
      <remap from="/octomap_point_cloud_centers" to="/uav$(arg uav2_id)/octomap_point_cloud_centers"/>
      <remap from="/octomap_full" to="/uav$(arg uav2_id)/octomap_full"/>
      <remap from="/octomap_binary" to="/uav$(arg uav2_id)/octomap_binary"/>
      
      <!-- 地图分辨率 -->
      <param name="resolution" value="0.1" />
      <!-- 发布地图的坐标系 -->
      <param name="frame_id" type="string" value="world" />
      <!-- 传感器最大感知范围 (speedup!) -->
      <param name="sensor_model/max_range" value="10" />
      <!-- 局部点云话题输入 -->
      <remap from="cloud_in" to="/uav$(arg uav2_id)/prometheus/scan_point_cloud" />
      <!-- 直通滤波的 Z 轴范围,保留 [-1.0, 10.0] 范围内的点 -->
      <!-- <param name = "pointcloud_max_z" value = "1.7" />
      <param name = "pointcloud_min_z" value = "1.4" /> -->
      <!-- 机器人坐标系 base_link,滤除地面需要该 frame -->
      <param name = "base_frame_id" type = "string" value = "world" />
      <!-- filter ground plane, distance value should be big! 项目并不需要滤除地面 -->
      <param name = "filter_ground" type = "bool" value = "true" />
      <param name = "ground_filter/distance" type = "double" value = "0.5" />
      <param name = "ground_filter/angle" type = "double" value = "0.7853" />
      <param name = "ground_filter/plane_distance" type = "double" value = "0.5" />

  </node>
  
  <node pkg="octomap_server" type="octomap_server_node" name="octomap_server_$(arg uav3_id)" output="screen">
      <remap from="/octomap_point_cloud_centers" to="/uav$(arg uav3_id)/octomap_point_cloud_centers"/>
      <remap from="/octomap_full" to="/uav$(arg uav3_id)/octomap_full"/>
      <remap from="/octomap_binary" to="/uav$(arg uav3_id)/octomap_binary"/>
      
      <!-- 地图分辨率 -->
      <param name="resolution" value="0.1" />
      <!-- 发布地图的坐标系 -->
      <param name="frame_id" type="string" value="world" />
      <!-- 传感器最大感知范围 (speedup!) -->
      <param name="sensor_model/max_range" value="10" />
      <!-- 局部点云话题输入 -->
      <remap from="cloud_in" to="/uav$(arg uav3_id)/prometheus/scan_point_cloud" />
      <!-- 直通滤波的 Z 轴范围,保留 [-1.0, 10.0] 范围内的点 -->
      <!-- <param name = "pointcloud_max_z" value = "1.7" />
      <param name = "pointcloud_min_z" value = "1.4" /> -->
      <!-- 机器人坐标系 base_link,滤除地面需要该 frame -->
      <param name = "base_frame_id" type = "string" value = "world" />
      <!-- filter ground plane, distance value should be big! 项目并不需要滤除地面 -->
      <param name = "filter_ground" type = "bool" value = "true" />
      <param name = "ground_filter/distance" type = "double" value = "0.5" />
      <param name = "ground_filter/angle" type = "double" value = "0.7853" />
      <param name = "ground_filter/plane_distance" type = "double" value = "0.5" />

  </node>
</launch>

将雷达数据类型从"sensor_msgs/LaserScan" 类型转到 “sensor_msgs/PointCloud2”,同时启动octomap建图服务,为后面ego规划做准备。octomap_server是ROS中一个基于octomap的功能包,具有将点云地图转化为基于Octree的OctoMap的功能。 在ROS中,octomap_server和octomap_map都是用于构建三维地图的软件包。octomap_server软件包提供了一种将输入数据转换为OctoMap格式的方法。它可以将来自激光雷达或深度摄像头等传感器的数据转换为三维点云,并使用这些点云构建OctoMap。octomap_server还可以将OctoMap数据发布为ROS中的OctoMap消息,以便其他ROS节点可以使用它们。octomap_map软件包提供了一种使用OctoMap数据构建环境模型的方法。它可以订阅来自octomap_server的OctoMap消息,并使用该消息构建一个三维地图。该地图可以用于机器人的定位、路径规划和避障等任务。octomap_server用于构建OctoMap数据,而octomap_map用于将OctoMap数据转换为实际可用的地图。

  1. sitl_ego_planner_basic_octomap_lidar_swarm.launch
<launch>
  <arg name="uav1_id" default="1"/>
  <arg name="uav2_id" default="2"/>
  <arg name="uav3_id" default="3"/>
   
  <!-- ego_planner 仿真 -->
  <include file="$(find ego_planner)/launch_for_prometheus/advanced_param_swarm.xml">
    <!-- 无人机编号 -->
    <arg name="uav1_id" value="$(arg uav1_id)"/>
    <arg name="uav2_id" value="$(arg uav2_id)"/>
    <arg name="uav3_id" value="$(arg uav3_id)"/>
    <!-- 地图尺寸 -->
    <arg name="map_size_x_" value="50.0"/>
    <arg name="map_size_y_" value="50.0"/>
    <arg name="map_size_z_" value="4.0"/>
    <arg name="map_origin_x_" value="-25.0"/>
    <arg name="map_origin_y_" value="-25.0"/>
    <!-- 可以通过限制ground_height和map_size_z来使得飞机在特定高度飞行 -->
    <arg name="ground_height" value="0.5"/>
    <!-- 虚拟天花板高度要小于等于ground_height+z_size,否则重置该高度 -->
    <!-- 里程计话题 -->
    <arg name="odometry_topic" value="/mavros/local_position/odom"/>
    <!-- 相机及深度信息仿真中没有使用,此处可忽略(真机中使用) -->
    <arg name="camera_pose_topic" value="/depth/no_set"/>
    <arg name="depth1_topic" value="/uav$(arg uav1_id)/depth/image_rect_raw"/>
    <arg name="depth2_topic" value="/uav$(arg uav2_id)/depth/image_rect_raw"/>
    <arg name="depth3_topic" value="/uav$(arg uav3_id)/depth/image_rect_raw"/>
    
    <arg name="cx" value="321.04638671875"/>
    <arg name="cy" value="243.44969177246094"/>
    <arg name="fx" value="387.229248046875"/>
    <arg name="fy" value="387.229248046875"/>
    <!-- 点云信息,仿真中由map_generator产生 -->
    <arg name="cloud1_topic" value="/uav$(arg uav1_id)/octomap_point_cloud_centers"/>
    <arg name="cloud2_topic" value="/uav$(arg uav2_id)/octomap_point_cloud_centers"/>
    <arg name="cloud3_topic" value="/uav$(arg uav3_id)/octomap_point_cloud_centers"/>
       
    <!-- scan -->
    <arg name="scan_topic" value="no_scan"/>
    <!-- 最大速度及加速度 -->
    <arg name="max_vel" value="0.8" />
    <arg name="max_acc" value="3" />
    <!-- 规划的范围,一般设置为感知范围的1.5倍 7.5-->
    <arg name="planning_horizon" value="7.5" /> 
    <!-- ? -->
    <arg name="use_distinctive_trajs" value="true" />
    <!-- 1: use 2D Nav Goal to select goal  -->
    <!-- 2: use global waypoints below  -->
    <!-- 单机建议直接使用rviz指定目标点,多机情况请预设目标点 -->
    <arg name="flight_type" value="1" />
    <!-- global waypoints -->
    <!-- It generates a piecewise min-snap traj passing all waypoints -->
    <arg name="point_num" value="1" />
    <arg name="point0_x" value="7.0" />
    <arg name="point0_y" value="0.0" />
    <arg name="point0_z" value="1.5" />
    
    <!-- 仿真 -->
    <arg name="realworld_experiment" value="true" />
  </include>

  <!-- trajectory server:由B样条生成轨迹 -->
  <!-- 偏航角初始值,重要参数 -->
  <arg name="yaw_init" default="0.0"/>
  <node pkg="ego_planner" name="uav$(arg uav1_id)_traj_server_for_prometheus" type="traj_server_for_prometheus" output="screen">
    <param name="uav_id" value="$(arg uav1_id)"/>
    <param name="control_flag" value="0"/>
    <param name="traj_server/time_forward" value="1.0"/>
    <param name="traj_server/last_yaw" value="$(arg yaw_init)"/>
  </node>
  
  <node pkg="ego_planner" name="uav$(arg uav2_id)_traj_server_for_prometheus" type="traj_server_for_prometheus" output="screen">
    <param name="uav_id" value="$(arg uav2_id)"/>
    <param name="control_flag" value="0"/>
    <param name="traj_server/time_forward" value="1.0"/>
    <param name="traj_server/last_yaw" value="$(arg yaw_init)"/>
  </node>
  
  <node pkg="ego_planner" name="uav$(arg uav3_id)_traj_server_for_prometheus" type="traj_server_for_prometheus" output="screen">
    <param name="uav_id" value="$(arg uav3_id)"/>
    <param name="control_flag" value="0"/>
    <param name="traj_server/time_forward" value="1.0"/>
    <param name="traj_server/last_yaw" value="$(arg yaw_init)"/>
  </node>
  <node pkg="ego_planner" name="motion_goal_swarm" type="motion_goal_swarm" output="screen"/>

</launch>

上面 launch文件在ego_planner包下启动ego_planner 仿真,并由B样条生成轨迹,发送控制指令给每台无人机,控制飞行。其中包含两部分/uav*_ego_planner_node和/uav*_traj_server_for_prometheus:

  • /uav*_ego_planner_node进行ego_planner规划,相关源代码参见ego_planner_node.cpp ,ego_replan_fsm.cpp,planner_manager.cpp,文件路径: ~/Prometheus/Modules/ego_planner_swarm/plan_manage/src/。
  • /uav*_traj_server_for_prometheus订阅ego_planner规划结果,由B样条(bspline)生成轨迹,转化为command命令控制无人机飞行。其源代码为traj_server_for_prometheus.cpp,文件路径: ~/Prometheus/Modules/ego_planner_swarm/plan_manage/src_for_prometheus/**

操作演示视频

EGO-Swarm 优势

EGO-Swarm作为一种针对复杂环境设计的多无人机自动导航方案,凭借其去中心化异步系统、基于梯度的局部规划框架、轻量级拓扑学路径生成方法及可靠的路径分享网络等核心特性,实现了无人机群在拥挤环境中的高性能飞行。该方案不仅提高了任务执行的效率和安全性,还为多无人机协同作业提供了强有力的技术支持和保障。它具有一下优点:

  • 去中心化异步系统:EGO-Swarm构建了一个高度去中心化的无人机集群系统,摒弃了传统的集中控制模式。在这种模式下,每架无人机都具备独立决策的能力,通过相互间的信息交换与协同工作,实现自主导航、任务执行及避障。这种设计不仅提升了系统的灵活性和适应性,还显著增强了系统的鲁棒性,即使部分无人机出现故障或通信中断,整个集群仍能持续有效运行。

  • 基于梯度的局部规划框架:为避免无人机间的碰撞,EGO-Swarm将碰撞风险作为非线性优化问题中的关键惩罚项,通过梯度下降等优化算法,实时调整无人机的飞行轨迹,确保安全飞行。这一框架不仅提高了避障的精确性,还保证了无人机在复杂环境中的高效导航。

  • 轻量级拓扑学路径生成方法:为减轻计算负担并提升路径规划的效率,EGO-Swarm采用了轻量级的拓扑学路径生成方法(A*算法)。快速生成安全的飞行路径,有效应对复杂多变的飞行环境。

  • 可靠的路径分享网络:为了促进多无人机之间的协同工作,EGO-Swarm构建了一个可靠的路径分享网络。该网络允许无人机实时分享各自的飞行路径和状态信息,从而实现飞行路径的协同优化和冲突避免。这种机制不仅提高了任务执行的效率,还显著增强了系统的整体安全性。

算法步骤

image.png

A*算法原理

PrometheusGroundStation-Pro使用手册

本章将为大家介绍Prometheus专业版地面站。

PrometheusGroundStation-Pro简介

该软件是使用Qt开发的基于Prometheus自主无人机开源项目的人机交互界面。

优点

  • 简化了Prometheus的操作和使用流程,使用户可以更快的复现Prometheus中的相关demo功能。
  • 采用TCP/UDP通信机制,避免ROS1的多机通信机载的繁琐配置工作,尤其是在集群功能的使用上。
  • 支持跨平台运行。
  • 同时适用于真实飞行环境和仿真飞行环境。
  • 提供二次开发接口,并提供示例和相关文档。

该地面站目前已适配了Prometheus项目中绝大数功能。包括但不限于基本控制、集群控制、吊舱控制、视觉跟踪控制、路径规划功能等。

其他介绍

功能介绍

注意

下方ROS话题的发布者和订阅者为相关节点,括号内为对应文件,如无超链接则表示该文件为阿木实验室闭源仓库文件;如需查看,请联系相关人员。

数据监控

地面站会实时显示无人机的状态,包含以下话题的数据:

具体数据内容可以参考Prometheus中common模块的prometheus_msgs功能包的msg文件,UAVState.msgUAVControlState.msgUAVCommand.msgSwarmCommand.msgGimbalState.msg

消息反馈

地面站会根据用户操作、触发不同的信息反馈,根据消息反馈的提示可以更好的操作地面站。消息反馈话题如下:

  • 信息反馈:/uav*/prometheus/text_info

    发布者:uav_control_main_*(uav_controller.cpp),swarm_control_node(swarm_control.cpp)等
    订阅者:communication_bridge(uav_basic_topic.cpp

具体数据内容可以参考Prometheus中common模块的prometheus_msgs功能包的msg,TextInfo.msg

单机控制

地面站会根据用户的操作,发送不同的指令以控制无人机,包含当前点悬停、初始点悬停、降落,以及移动模式下惯性系、机体系中的位置、速度、定高,轨迹、姿态、经纬高控制等。单机控制话题如下:

具体数据内容可以参考Prometheus中common模块的prometheus_msgs功能包的msg,UAVCommand.msg

集群控制

地面站会根据用户操作,发送不同的指令以控制总个集群系统,包含位置控制、控制模式设置、队形变换设置、队形间距设置等。集群控制话题如下:

  • 集群控制指令:/prometheus/swarm_command

    发布者:communication_bridge(swarm_control_topic.cpp
    订阅者:swarm_control_node(swarm_control.cpp)

具体数据内容可以参考Prometheus中common模块的prometheus_msgs功能包的msg,SwarmCommand.msg

吊舱控制

地面站会根据用户操作,发送不同的指令去控制吊舱,包含roll、pitch、yaw、焦距等控制。吊舱控制话题如下:

  • 吊舱控制话题::/uav*/gimbal/control

    发布者:communication_bridge(gimbal_basic_topic.cpp
    订阅者:gimbal(gimbal_server.cpp)

具体数据内容可以参考Prometheus中common模块的prometheus_msgs功能包的msg,GimbalControl.msg

视觉控制

地面站会根据用户操作,去框选、取消框选,以及获得目标检测的结果,去点击对应目标ID框、取消点击对应目标ID框。相关话题如下:

  • 目标检测话题:/deepsort_ros/object_detection_result

    发布者:deepsort(main.cpp)
    订阅者:communication_bridge(object_tracking_topic.cpp

  • 视觉控制话题:/detection/bbox_draw

    发布者:communication_bridge(gimbal_basic_topic.cpp
    订阅者:tracker_ros(kcf.cpp)

具体数据内容可以参考Prometheus中common模块的prometheus_msgs功能包的msg,MultiDetectionInfoSub.msgWindowPosition.msg

百度地图

地面站内嵌百度地图,并使用相关SDK,实现下列功能:

  • 支持在线、离线两种模式,同时支持街道图、卫星图等多种观看模式,并且可以使用百度地图部分API接口。
  • 提供离线地图瓦片下载
  • 根据无人机经纬度信息,实时显示无人机当前位置
  • 配合单机控制中的经纬高控制,通过点击地图,自动填入经纬度,实现点哪儿飞哪儿
  • 支持OFFBOARD模式下航点规划功能

平面地图

地面站内嵌平面地图,实现下列功能:

  • 根据无人机位置(position)信息,实时显示无人机位置
  • 根据控制指令信息,在平面地图上指明各无人机要飞到的位置
  • 集群控制自主分配后,可以查看预期飞往的位置,避免交叉情况出现
  • 提供打点功能,记录轨迹、集群多机、定位精度等数据,可将数据保存为xlsx文件,然后通过散点图复现轨迹。

虚拟摇杆

地面站支持如下功能:

  • 支持鼠标或者键盘控制
  • 提供三轴、偏航最大速度设置接口
  • 提供回到初始点按钮

视频流拉取

地面站支持如下功能:

  • 支持rtsp流
  • 支持rtmp流

ROS参数

地面站支持如下功能:

  • 加载参数
  • 支持修改参数,达到调参作用
  • 支持一键修改全部无人机

一键启动

地面站支持一键启动程序功能,支持如下功能:

  • 一键启动对应程序,如单机控制、集群控制等相关程序。
  • 提供自定义一键启动接口,用户通过自己设置生成对应程序启动按钮。

日志记录

地面站支持日志记录功能,记录数据如下:

  • 无人机状态数据
  • 无人机控制状态数据
  • 信息反馈数据

三维数据可视化图

主要为适配路径规划功能所开发,ubuntu版本和windows版本采用不同实现方式,其中ubuntu版本基于librviz开发,windows则采用qtopengl开发。

支持以下三维数据显示:

  • OCTOMAP点云图
  • 膨胀点云图
  • 无人机模型
  • 无人机轨迹
  • 无人机规划轨迹
  • 无人机目标点

串口转发

一般用于H16遥控器和RTK模块同时使用情况,用于转发rtcm协议数据,支持如下功能:

  • 串口数据接收查看
  • 串口数据转发(目前仅支持UDP转发)

图像操作

根据拉取的图像,支持如下功能:

  • 截图
  • 录像

自定义消息发送

根据自行设定自定义数据,将其发送到机载端通信节点,然后通信节点提供对应接口,进行二次开发。

准备工作

环境要求

推荐环境

x86架构电脑:windows10、windows11、ubuntu 20.04系统

windows版本注意:目前windows版本仅在windows10和windows11上进行测试,其他windows版本可以自行测试使用。 ubuntu版本注意:最新版本地面站仅支持 ubuntu 20.04系统,理论上可以向后兼容,所以在 ubuntu 22.04系统应该可以运行(需自行测试)。

软件下载

注意

早期地面站因为协议上的一些变动,可能存在协议不匹配情况,从而导致地面站使用过程中出现协议不匹配的情况,可以查看更新记录查看更多对应情况。

PrometheusGroundStation-Pro下载

根据自己需求下载windows版本或者ubuntu版本,然后查看下方对应的配置使用教程。

Ubuntu版本

地面站下载运行

下载完成后需要赋予权限,操作如下:

chmod a+x PrometheusGroundStation-Pro.AppImage

下载完成后,双击运行或者使用下面命令进行运行:

./PrometheusGroundStation-Pro.AppImage

运行无误后会弹出校验窗口:

1716437577095.jpg

校验码获取可参考下方。

1716437736567.jpg

运行完成后关闭地面站软件。

配置文件下载(可选)

注意

进行该步骤之前,请先保证已经正常打开过一次地面站,并且当前地面站处于关闭状态。

首先检查存放配置文件路径是否创建,如下图:

1716445310361.jpg

如果是系统语言为中文,则在根目录下文档路径下。

然后下载配置文件:

真实GPS地图相关(如果只进行室内飞行可不下载):地图配置文件下载

rviz三维数据可视化相关(如果不使用路径规划相关功能可不下载):rviz模块下载

下载完成后解压到根目录下的/Documents/PrometheusGroundStation/中(~/Documents/PrometheusGroundStation/),解压完成后结构目录如下图:。

1716448384975.jpg

编译rviz功能包(如果不使用路径规划相关功能可不编译):

# 需要ROS环境,如果不是特别需求,推荐小鱼ROS一键安装
# 安装环境
sudo apt install ros-melodic-qt-build
sudo apt install ros-noetic-rosbridge-server
# 进入路径编译
cd ~/Documents/PrometheusGround/myrviz
catkin_make

配置成功测试

测试真实地图是否正常,首先打开地图监控,查看是否有了地图(如果没有连接网络,可以选择离线地图),如下图:

1716459580695.jpg

测试rviz模式是否正常,具体操作流程参考如下:

1716459993897.png

点击开启按钮跳转到主界面出现rviz界面,即配置成功,如下图:

1716460234987.jpg

Windows版本

地面站下载运行

下载完成后将其解压在任意位置(建议不要放在C盘),解压完成进入文件夹,找到PrometheusGroundStation.exe文件,然后操作如下:

1716451104295.jpg

此时可以在桌面文件中找到 PrometheusGroundStation.exe - 快捷方式 ,双击运行。

运行无误后会弹出校验窗口:

1716436952179.jpg

校验码获取可参考下方。

1716452139090.jpg

运行完成后关闭地面站软件。

配置文件下载(可选)

注意

进行该步骤之前,请先保证已经正常打开过一次地面站,并且当前地面站处于关闭状态。

真实GPS地图相关(如果只进行室内飞行可不下载):地图配置文件下载

下载完成后解压到系统文档路径下的PrometheusGroundStation文件夹中(~/文档/PrometheusGroundStation/),如下图:

1716454677411.jpg

配置成功测试

测试真实地图是否正常,首先打开地图监控,查看是否有了地图(如果没有连接网络,可以选择离线地图),如下图:

1716459580695.jpg

校验码获取

可以通过Star收藏Prometheus开源自主无人机软件系统平台,然后获取。

首先进入Prometheus代码仓库

1722588432845.jpg

然后将Star后截图发送给阿木实验室-嘉月确认。

1722588541974.jpg

联系阿木实验室-嘉月,可以扫描下方二维码。

1722589394478.jpg

界面说明

参考PrometheusGroundStation-Pro使用手册中的界面说明章节

使用手册

以下使用,以仿真下无人机单机控制为主,其他功能使用可以参考PrometheusGroundStation-Pro使用手册

连接无人机

注意

该步骤十分重要,基本上所有操作都是基于此步骤。

该小节讲述地面站连接无人机的使用过程,此处以仿真举例:

首先需要保证地面站和要连接的通信节点在同一数据链路上,可以相互Ping通,并关闭防火墙、科学上网软件、系统代理和VPN等。

通信节点配置

首先,请确保Prometheus已经正常安装(以仿真为例),可以参考Prometheus仿真环境配置

下面是一个完整的关于通信节点的启动launch文件,在这里介绍一下相关参数。

<launch>
    <!-- 自启动相关 -->
    <arg name="autoload" default="false"/>
    <arg name="uav_control_start" default="gnome-terminal -- roslaunch prometheus_uav_control uav_control_main_indoor.launch"/>
    <arg name="close_uav_control" default="gnome-terminal -- rosnode kill `rosnode list | grep -v /communication_bridge | grep -v /rosout`"/>
    <arg name="swarm_control_start" default="'/home/amov/Prometheus/Modules/swarm_control/sh/simulation/sitl_swarm_3uav.sh'"/>
    <arg name="close_swarm_control" default=""/>
    <!-- 地面站IP地址 -->
    <arg name="ground_station_ip" default="192.168.2.148"/>
    <!-- robot id为唯一标识符,如果是集群(无人机集群、无人车集群、机车协同),该值不能重复 -->
    <arg name="robot_id" default="1"/>
    <!-- 根据实际情况进行输入该参数,该载体为无人车时,该值必须设置为0-->
    <arg name="uav_id" default="1"/>
    <!-- 根据实际情况进行输入该参数,该载体为无人机时,该值必须设置为0-->
    <arg name="ugv_id" default="0"/>
    <!-- 如果不是仿真或集群,将该值设置为0-->
    <arg name="swarm_num" default="0"/>
    <arg name="swarm_ugv_num" default="0"/>

    <arg name="is_simulation" default="1"/>
    <arg name="swarm_data_update_timeout" default="5"/>

    <!-- 控制一些数据的转发给地面站或其他机器的频率 -->
    <!-- 无人机状态和无人机控制状态发送频率,设置为0则以订阅频率发送,不能超过订阅频率 -->
    <arg name="uav_basic_hz" default="10"/>
    <!-- 无人车状态发送频率,设置为0则以订阅频率发送 -->
    <arg name="ugv_basic_hz" default="10"/>
    <!-- 吊舱状态发送频率,设置为0则以订阅频率发送 -->
    <arg name="gimbal_basic_hz" default="0"/>

    <!-- Prometheus功能包路径 -->
    <arg name="prometheus_moudles_url" default="/home/amov/Prometheus/Modules/"/>
    <!-- 单机配置文件路径 -->
    <arg name="uav_control_yaml" default="uav_control/launch/uav_control_outdoor.yaml"/>
    <!-- 集群配置文件路径 -->
    <arg name="swarm_control_yaml" default="swarm_control/config/swarm_control_p600.yaml"/>
    <!-- 轨迹配置文件路径 -->
    <arg name="uav_command_yaml" default="uav_control/launch/uav_command_pub.yaml"/>

    <node pkg="prometheus_communication_bridge" type="communication_bridge" name="communication_bridge" output="screen">
        <!-- 组播ip -->
        <param name="multicast_udp_ip" value="$(arg ground_station_ip)"/>
	    <!-- ego planner -->
        <param name="next_drone_ip" value="127.0.0.1"/>
	    <param name="broadcast_ip" value="127.0.0.255"/>
        <param name="drone_id" value="1"/>
        <!-- 地面站IP,端口设置等 -->
        <param name="ground_station_ip" value="$(arg ground_station_ip)"/>
        <param name="udp_port" value="8889"/>
        <param name="tcp_port" value="55555"/>
        <param name="rviz_port" value="8890"/>
        <param name="ROBOT_ID" value="$(arg robot_id)"/>
        <param name="uav_id" value="$(arg uav_id)"/>
        <param name="ugv_id" value="$(arg ugv_id)"/>
        <param name="try_connect_num" value="5"/>
        <param name="tcp_heartbeat_port" value="55556"/>
        <!-- 是否仿真模式  1为是  0为否 -->
        <param name="is_simulation" value="$(arg is_simulation)"/>
        <!-- 集群数量,如果不是集群模式值为0 -->
        <param name="swarm_num" value="$(arg swarm_num)"/>
        <param name="swarm_ugv_num" value="$(arg swarm_ugv_num)"/>
        <!-- 集群模式下,数据超时情况,多久判断其失联且回传地面站 -->
        <param name="swarm_data_update_timeout" value="$(arg swarm_data_update_timeout)"/>

        <!-- 轨迹控制相关设置 -->
        <param name="trajectory_ground_control" value="true"/>
        <param name="trajectory_flag" value="false"/>
        <param name="trajectory_mode" value="0"/>
        <param name="trajectory_time" value="0"/>

        <!-- 是否自启 -->
        <param name="autoload" value="$(arg autoload)"/>
        <param name="uav_control_start" value="$(arg uav_control_start)"/>
        <param name="close_uav_control" value="$(arg close_uav_control)"/>
        <param name="swarm_control_start" value="$(arg swarm_control_start)"/>
        <param name="close_swarm_control" value="$(arg close_swarm_control)"/>

        <!-- 发送频率 -->
        <param name="uav_basic_hz" value="$(arg uav_basic_hz)"/>
        <param name="ugv_basic_hz" value="$(arg ugv_basic_hz)"/>
        <param name="gimbal_basic_hz" value="$(arg gimbal_basic_hz)"/>

        <!-- 单机配置文件加载 -->
        <rosparam command="load" file="$(arg prometheus_moudles_url)$(arg uav_control_yaml)"/>
        <!-- 集群配置文件加载 -->
        <rosparam command="load" file="$(arg prometheus_moudles_url)$(arg swarm_control_yaml)"/>
        <!-- 轨迹配置文件加载 -->
        <rosparam command="load" file="$(arg prometheus_moudles_url)$(arg uav_command_yaml)"/>
    </node>
</launch>

下面对一些可能需要修改的参数进行说明:

参数名说明
autoload用于地面站点击连接/开启集群和断开连接/关闭集群是否自动启动相关脚本
uav_control_startautoload为true时,地面站上点击连接会调用该命令
close_uav_controlautoload为true时,地面站点击断开连接会调用该命令
swarm_control_startautoload为true时,地面站上点击开启集群会调用该命令
close_swarm_controlautoload为true时,地面站上点击关闭集群会调用该命令
ground_station_ip此处设置为地面站的IP
multicast_udp_ip组播IP,默认为224.0.0.8,如果是单机建议设置为ground_station_ip的值
robot_id唯一标识符,如果是集群(无人机集群、无人车集群、机车协同),该值不能重复,一般来说跟载体ID相同
uav_id根据实际情况进行输入该参数,该载体为无人车时,该值必须设置为0
swarm_num集群数量
is_simulation是否仿真,是为1,不是为0

如果是在阿木实验室产品中,仿真电脑可以在仿真启动器中启动,真机会设置为自启动。

手动启动方式如下:

# 一般而言,如果是仿真电脑或者真机可以参考对应功能包
roslaunch prometheus_communication_bridge bridge.launch

地面站配置连接

1717035006741.jpg

  • 首先打开地面站,点击图上标注1连接设置,然后会弹出连接设置框。
  • 然后将标注2中的名字和主机地址以及主机端口号填写,填写规则如下:
    • 名字:分为两部分,第一部分,前缀为3个字母,只能为UAV或者UGV(不区分大小写),用于区分无人机和无人车,第二部分,后缀为一个数字,代表无人机的编号。可以参考机载端通信节点中的uav_id或者robot_id。
    • 主机IP:填写运行通信节点的机载IP地址。
    • 主机端口:默认55555,无特殊情况,默认不会进行修改。
  • 上述标注2填写完成后,点击标注3添加按钮,点击后生成标注4。
  • 上述标注5点击选择,勾选后,点击标注6连接按钮。

出现下图中提示语句说明连接成功:

1717037201571.jpg

地面站断开连接

1717042895179.jpg

  • 首先,根据标注1选择需要断开的无人机,然后点击标注2断开连接按钮。
  • 随后,出现标注3消息反馈说明断开连接成功。

地面站修改信息

1717042285333.jpg

  • 首先打开地面站,如果连接了,请先断开连接后。
  • 然后点击标注2,会将数据自动填充在标注3中。
  • 然后将标注3的数据进行修改,修改完成后,点击标注4的修改按钮即可。
  • 再次查看标注2中数据是否发生变化,变化成功说明修改成功。

单机控制

启动控制节点

以下在仿真环境下运行,需要安装好Prometheus仿真环境

运行仿真环境

打开终端输入如下指令:

# p450无人机模型室外定位仿真脚本
'/home/amov/Prometheus/Scripts/simulation/px4_gazebo_sitl_test/px4_sitl_outdoor_P450.sh'

运行完毕后查看gazebo中是否出现无人机,以及查看第三个终端,数据是否正常,如下图:

1717401117700.jpg

连接无人机

连接完成后,查看状态灯是否正常,如果不正常可将鼠标移动到该状态灯显示原因。

1717401433523.jpg

准备控制

需要配合遥控器使用,遥控器具体使用可以参考:仿真中的遥控器使用说明

然后将主界面切换到平面地图,然后查看单机控制栏,如下图:

1717464602150.jpg

前面两步为切到到平面地图,最后一步则为单机控制栏。

这里主要介绍单机控制栏:

控制中的按钮可以对应Prometheus中的几种模式(相关教程参考链接相关msg文件(UAVCommand.msg)相关代码(uav_controller.cpp)),如下表格:

Agent_CMD按钮名简介
Init_Pos_Hover初始点悬停无人机回到解锁点上方
Current_Pos_Hover当前点悬停无人机保持当前位置进行悬停,一般用于移动模式后
Land降落无人机降落
Move上传无人机根据不同子模式以及控制量进行自主移动

单机控制栏中除了四个按钮,还有一个下拉框,以及多个输入框,下拉框为选择移动子模式,输入框为输入控制量(输入框无数据时会提示用户输入的控制量,不输入默认为0),下面解释这些移动子模式接口:

移动子模式下拉框对应
惯性系定点控制XYZ_POS
惯性系定高速度控制XY_VEL_Z_POS
惯性系速度控制XYZ_VEL
机体系位置控制XYZ_POS_BODY
机体系速度控制XYZ_VEL_BODY
机体系定高速度控制XY_VEL_Z_POS_BODY
轨迹追踪控制TRAJECTORY
姿态控制(来自外部控制器)XYZ_ATT
绝对坐标系下的经纬度LAT_LON_ALT

其中姿态控制(XYZ_ATT)暂不可用,其余接口均可正常使用,绝对坐标系下的经纬度控制需要在GPS或者RTK定位下才能使用。

坐标系说明:

  • 惯性系:x轴指向东边,y轴指向北边,z轴指向天。
  • 机体系:以无人机当前位置为原点,机头向前方向为x轴,垂直机头90度向左为y轴,垂直xy平面向上为z轴。

地面站控制

首先将SWA切到最下方,此时无人机将会解锁,然后将SWB切到最下方(缓慢一点),此时无人机将会起飞。

此时地面站状态显示如下:

1717552259754.jpg

然后检查数据:

解锁状态(是否解锁),飞行模式(是否进入OFFBOARD),定位源(根据实际情况,仿真室外一般为GPS或者RTK),控制状态(COMMAND_CONTROL),GPS星数(仿真下默认一直为10,真机飞行建议大于16),高度数据(可以只管看到是否起飞成功)。

检查正常进入后续操作。

惯性系定点控制(XYZ_POS)

首先查看无人机当前位置,以及在平面地图显示的位置,如下图:

1717553236824.jpg

然后再单机控制栏中进行下列操作:

  • 控制栏中下拉框中选择XYZ_POS移动子模式
  • 输入指点的位置(1,1,1.5,单位:m)
  • 输入偏航(30,单位:deg)
  • 点击发送

发送成功后,无人机将开始移动,地面站数据变化以及平面地图变化如下:

1717553424584.jpg

也可以通过查看期望值是否生效。

测试完成后,点击初始点悬停按钮,将无人机飞回起飞点。

惯性系定高速度控制(XY_VEL_Z_POS)

首先查看无人机当前位置,以及在平面地图显示的位置。

1717554171256.jpg

然后再单机控制栏中进行下列操作:

  • 控制栏中下拉框中选择XY_VEL_Z_POS移动子模式
  • 输入XY的速度(0.5,0.5,单位:m/s)
  • 输入Z的高度(1.5,单位:m)
  • 输入偏航(0,单位:deg)
  • 点击发送

发送成功后,无人机将开始移动,地面站数据变化以及平面地图变化如下:

1717554388488.jpg

可以看到无人机存在一条红色的小尾巴(无人机的轨迹),然后期望XY速度都为0.5说明正常。

然后可以通过点击当前点悬停让无人机悬停,然后点击初始点悬停让无人机飞回起飞点。

惯性系速度控制(XYZ_VEL)

首先查看无人机当前位置,以及在平面地图显示的位置。

1717556476564.jpg

然后再单机控制栏中进行下列操作:

  • 控制栏中下拉框中选择XYZ_VEL移动子模式
  • 输入XYZ的速度(0.5,0.5,0.2,单位:m/s)
  • 输入偏航(0,单位:deg)
  • 点击发送

发送成功后,无人机将开始移动,地面站数据变化以及平面地图变化如下:

1717556424812.jpg

可以看到无人机存在一条红色的小尾巴(无人机的轨迹),然后期望XY速度都为0.5、期望Z速度为0.2说明正常。

然后可以通过点击当前点悬停让无人机悬停,然后点击初始点悬停让无人机飞回起飞点。

机体系位置控制(XYZ_POS_BODY)

首先查看无人机当前位置,以及在平面地图显示的位置。

1717556764371.jpg

然后再单机控制栏中进行下列操作:

  • 控制栏中下拉框中选择XYZ_POS_BODY移动子模式
  • 输入XYZ的位置(1,1,0,单位:m)
  • 输入偏航(0,单位:deg)
  • 点击发送

发送成功后,无人机将开始移动,地面站数据变化以及平面地图变化如下:

1717557057848.jpg

测试完成后,点击初始点悬停按钮,将无人机飞回起飞点。

机体系速度控制(XYZ_VEL_BODY)

首先查看无人机当前位置,以及在平面地图显示的位置。

1717557771743.jpg

然后再单机控制栏中进行下列操作:

  • 控制栏中下拉框中选择XYZ_VEL_BODY移动子模式
  • 输入XYZ的速度(0.5,0.5,0.2,单位:m/s)
  • 输入偏航(0,单位:deg)
  • 点击发送

发送成功后,无人机将开始移动,地面站数据变化以及平面地图变化如下:

1717557930588.jpg

可以看到无人机存在一条红色的小尾巴(无人机的轨迹),然后期望XY速度都为0.5、期望Z速度为0.2说明正常。

然后可以通过点击当前点悬停让无人机悬停,然后点击初始点悬停让无人机飞回起飞点。

机体系定高速度控制(XY_VEL_Z_POS_BODY)

首先查看无人机当前位置,以及在平面地图显示的位置。

1717558203842.jpg

然后再单机控制栏中进行下列操作:

  • 控制栏中下拉框中选择XY_VEL_Z_POS_BODY移动子模式
  • 输入XY的速度(0.5,0.5,单位:m/s)
  • 输入Z的高度(0,单位:m)
  • 输入偏航(0,单位:deg)
  • 点击发送

发送成功后,无人机将开始移动,地面站数据变化以及平面地图变化如下:

1717558298557.jpg

可以看到无人机存在一条红色的小尾巴(无人机的轨迹),然后期望XY速度都为0.5说明正常。

然后可以通过点击当前点悬停让无人机悬停,然后点击初始点悬停让无人机飞回起飞点。

轨迹追踪控制(TRAJECTORY)

这个控制接口需要配合uav_command_pub节点才能使用。

地面站参数修改

1717558743893.jpg

按上述步骤操作即可,下面简单介绍步骤流程:

  1. 点击 系统设置,切换到系统设置界面。
  2. 点击 参数设置,切换参数设置界面。
  3. 点击 轨迹控制,切换轨迹控制参数显示界面。
  4. 此时可以看到轨迹控制中的一些参数,如果为空白,可以点击加载按钮重新加载参数,比如绕圆圆心、半径、速度等等,可以自行设置。
启动轨迹控制节点

可以用两种方式启动,一种是手动启动,另一种是地面站启动:

手动启动

通过打开终端,输入下方指令:

roslaunch prometheus_uav_control uav_command_pub.launch
地面站启动

通过自定义一个按钮,将轨迹控制节点的命令封装,正常关闭后会自动保存到配置文件,再次打开依旧存在,可反复使用。

1717559074500.jpg

按上述步骤操作即可,下面简单介绍步骤流程:

  1. 点击 系统设置,切换到系统设置界面。
  2. 点击 脚本设置,切换脚本设置界面。
  3. 点击 添加按钮。
  4. 在最新生成的区域中填写要生成按钮的名字(traject)。
  5. 填写运行指令(roslaunch prometheus_uav_control uav_command_pub.launch)。
  6. 发送方式选择。
  7. 最后点击生成按钮。

上述操作完成后,可以在调试帮助界面中查看生成按钮,进行如下操作:

1717559185811.jpg

按上述步骤操作即可,下面简单介绍步骤流程:

  1. 点击 功能脚本,切换到功能脚本界面。
  2. 查看自定义demo里面生成的按钮 轨迹控制,然后点击该按钮后启动轨迹控制节点。

点击后或者手动运行出现如下终端:

1717560143927.jpg

开启平面地图打点连线功能(可选)

该功能可以设置一段时间并固定频率将无人机上一位置和当前位置进行连线,在平面地图上打印出这段时间的轨迹,支持数据导出。

1717647431427.jpg

按上述步骤操作即可,下面简单介绍步骤流程:

  1. 点击 系统设置,切换到系统设置界面。
  2. 点击 地图设置,切换地图设置界面。
  3. 输入总时间和频率和需要画轨迹的无人机,数据填入完成后点击启动,然后会跳转到平面地图。
地面站控制

首先查看无人机当前位置,以及在平面地图显示的位置。

1717637283547.jpg

选中轨迹控制,此时会再次出现一个下拉框,包含Circle,Eight Shape,Step,Line四种轨迹,选择好飞行轨迹后,输入飞行时间。

绕圆效果图(开启平面地图打点连线功能)如下:

1717646429684.jpg

绕8效果图(开启平面地图打点连线功能)如下:

1717646984758.jpg

另外两种轨迹跟踪这里就不再显示效果图,可自行尝试。

将半径设置大,速度设置小,效果越好,反之效果越差。

姿态控制(XYZ_ATT)

暂未使用

绝对坐标系下的经纬度控制(LAT_LON_ALT)

仿真下设置无人机初始经纬度(可选)

在安装的仿真环境中,默认定位为国外,如果想要将经纬度设置为其他地方,打开bashrc文件,操作如下:

gedit ~/.bashrc

打开后会出现一个txt文件,在最后面追加下列语句:

# 注意:=旁边不能存在空格,否则会导致失败
# 下面此处定位为阿木实验室附近
export PX4_HOME_LAT=30.788034
export PX4_HOME_LON=103.858487
export PX4_HOME_ALT=100

追加完成后,重新打开一个终端运行室外仿真脚本:

# p450无人机模型室外定位仿真脚本
'/home/amov/Prometheus/Scripts/simulation/px4_gazebo_sitl_test/px4_sitl_outdoor_P450.sh'

运行完毕后,查看第三个终端,可以看到下面经纬度已经发生变化,说明修改成功:

1718070898025.jpg

具体操作

首先查看无人机当前位置,以及在平面地图显示的位置。

1717648013663.jpg

按上述步骤操作即可,下面简单介绍步骤流程:

  1. 首先切换界面到百度地图,然后选择移动子模式为LAT_LON_ALT。
  2. 然后选择百度地图工具栏的第二个指点,然后再地图上指点,如果移动子模式为LAT_LON_ALT则会将经纬度填入输入框。
  3. 输入高度后,点击上传发送命令。

蓝色线为无人机轨迹,最终效果图如下:

1718071265743.jpg

Prometheus真机教程

本章真机教程内容仅提供基础教程,并且是以阿木实验室配套无人机Z410来进行讲解,其余无人机需要适当做出一定修改。

如果想实现更多功能需要自行移植Prometheus项目到无人机上或购买Prometheus配套无人机

警告

真机教程内容并不完善,也缺乏代码测试。目前该章节内容仅供参考

无人机组装

该无人机组装教程以阿木实验室推出的Z410机型为参考,如需购买,请点击下面购买链接

阿木实验室-Z410

无人机安装配套有视频教程—Z410无人机安装教程

安装流程

安装分电板、电调

准备物料

  1. 环氧板
  2. 机架碳板
  3. 分电板
  4. 电调
  5. 配套螺丝、螺丝柱、线材等其它材料
  6. 配套螺丝刀、电烙铁等其它工具

安装步骤

  1. 在环氧板上安装螺丝以及螺柱为分电板以及电调模块预留安装位置
  2. 将分电板和电调模块的安装孔位与环氧板上的螺丝对准后用螺母拧紧
  3. 使用电烙铁将电机线与电调模块连接为后续的电机连接做准备
  4. 将电机线从固定孔位穿过,并通过胶布或扎带等工具将电机线固定在环氧板凹槽内
  5. 将配套螺丝安装到机架碳板上
  6. 将电机安装螺丝安装到环氧板上,为机架碳板和电机安装预留安装位置

安装电机

准备物料

  1. 无人机主体(未安装完毕)
  2. 电机
  3. 配套螺丝、螺丝柱、线材、热缩管等其它材料
  4. 配套螺丝刀、电烙铁、热风枪、剥线钳等其它工具

安装步骤

  1. 将热缩管套进电机线中
  2. 使用电烙铁将电机与电机线连接
  3. 将热缩管移动至线材焊接点,并保证完全遮蔽焊接部位
  4. 使用热风枪加热热缩管使热缩管与线材紧密接触
  5. 将电机线多余部分塞入环氧板与机架碳板夹层中
  6. 将电机安装到机架碳板上
  7. 安装机臂螺丝

安装降压模块、电压回传模块

准备物料

  1. 无人机主体(未安装完毕)
  2. 降压模块
  3. 电压回传模块
  4. 配套线材等其它材料
  5. 配套螺丝刀、电烙铁等其它工具

安装步骤

  1. 使用电烙铁焊接降压模块以及配套线材
  2. 使用电烙铁焊接电压回传模块以及配套线材
  3. 使用电烙铁将降压模块与分电板连接
  4. 使用电烙铁将电压回传模块与分电板连接

安装脚架

准备物料

  1. 脚架碳板
  2. 减震绵
  3. 配套螺丝、螺丝柱等其它材料
  4. 配套螺丝刀等其它工具

安装步骤

  1. 在环氧板以及机架碳板上安装螺丝及螺丝柱为脚架预留安装接口
  2. 将一块脚架碳板安装上螺丝
  3. 将减震绵裁剪成合适大小后安装到脚架底部螺丝上
  4. 将两块脚架碳板连接,将海绵夹在两块脚架碳板中间
  5. 重复以上操作制作第二个脚架
  6. 将减震绵拆剪成合适大小,用长螺柱穿过减震绵,需要做两个
  7. 将带有减震绵的长螺柱将两块脚架连接
  8. 将脚架与无人机主体连接

安装飞控以及机载计算机

准备物料

  1. 飞控
  2. 减震板
  3. 机载计算机
  4. TTL转USB模块
  5. 配套螺丝、螺丝柱、碳板、3M胶、线材、碳板等其它材料
  6. 配套螺丝刀等其它工具

安装步骤

  1. 通过3M胶将飞控与减震板连接
  2. 将机载计算机安装到碳板上
  3. 将机载计算机和飞控模块安装到无人机主体上
  4. 通过TTL转USB模块一端连接至飞控telem2端口,另一端连接至机载计算机USB端口
  5. 通过电源线将飞控与分电板连接
  6. 通过电调线将飞控与电调模块连接

安装GPS模块、安全开关、蜂鸣器、数传模块、遥控器接收器、螺旋桨

准备物料

  1. GPS模块
  2. 安全开关
  3. 蜂鸣器
  4. 数传模块
  5. 遥控器接收器
  6. 配套螺丝、螺丝柱、碳板、3M胶、线材、碳板等其它材料
  7. 配套螺丝刀等其它工具

安装步骤

  1. 将GPS模块连接至飞控GPS Module端口,并固定在无人机主体上
  2. 将安全开关连接至飞控SWTICH端口,并固定在无人机主体上
  3. 将蜂鸣器连接至飞控BUZZER端口,并固定在无人机主体上
  4. 将数传模块连接至飞控TELEM1端口,并固定在无人机主体上
  5. 将遥控器接收器连接至飞控侧面的RC端口,并固定在无人机主体上
  6. 将螺旋桨安装到无人机电机上,需要区分顺时针和逆时针方向

整机检查

检查安装模块是否正常连接,相关连线通断是否正常

PX4固件以及参数配置

刷写PX4固件

准备内容:

1、一台装有QGC的电脑

2、数据线

3、Z410无人机

提示

prometheus_px4固件位于Prometheus/Experiment文件夹下,找到名为prometheus_Z410.px4文件,该文件为刷写的PX4固件。

QGC下载链接

将QGC打开,点击左上角按钮,点击设置,进入固件刷写界面

image.png

image.png

通过数据线将无人机飞控与电脑连接,QGC会弹出固件刷写提示框,点击高级设置,选择自定义固件

image.png

选择prometheus_px4.px4文件,等待刷写完毕即可

PX4参数修改

运行Prometheus真机示例demo前需要确认无人机飞控参数是否正确

将数据线断开后再重新打开QGC,再次插上数据线QGC会自动连接无人机

image.png

依然点击左上角按钮,点击设置,点击参数设置界面

image.png

  • EKF2_AID_MASK

    该参数为选择无人机定位数据来源参数,在搜索框内搜索aid可快速找到该参数,点击参数进入参数设置界面,选择use GPS,将定位数据来源设置为GPS。

image.png

  • EKF2_HGT_MODE

    该参数为选择无人机高度数据来源参数,在搜索框内搜索hgt可快速找到该参数,点击参数进入参数设置界面,选择Barometric pressure,将高度数据来源设置为气压计

image.png

  • MAV_0_CONFIG

    该参数为选择mavlink消息输出的接口,在搜索框内搜索mav可快速找到该参数,点击参数进入参数设置界面,选择TELEM2

image.png

  • SER_TEL2_BAUD

    该参数为选择TELM2接口波特率的参数,在搜索框内搜索tel2可快速找到该参数,点击参数进入参数设置界面,选择921600 8N1

image.png

注意

MAV_0_CONFIGSER_TEL2_BAUD两个参数的设置,是因为Prometheus项目代码默认为飞控与无人机通信采用TELEM2口,波特率为921600,如果机载计算机端与飞控连接方式改变,则相应地需要修改飞控参数以及Prometheus项目代码

机载计算机与飞控连接

硬件连接

下图为Pixhawk2.4.8的接口示意图,其中TELM2口引脚从左到右依次为5VTXRXCTSRTSGND

image.png

使用TTL转USB模块将飞控与机载计算机连接,需要连接TXRXGND

飞控TELEM2口的TX与TTL转USB模块的RX连接

飞控TELEM2口的RX与TTL转USB模块的TX连接

飞控TELEM2口的GND与TTL转USB模块的GND连接

IMG_20220711_143524.jpg

IMG_20220711_143348.jpg

软件连接

在上一节中PX4参数修改已经提到MAV_0_CONFIG以及SER_TEL2_BAUD两个连接相关的参数,飞控连接的软件设置按照教程内容设置即可。

在机载计算机端,需要确认Prometheus项目对应的MAVROS启动参数是否配置正确,文件位于Prometheus/Experiment/launch文件夹下,打开文件夹下的prometheus_experiment.launch文件,确认fcu_url参数是否为/dev/ttyUSB0:921600

image.png

真机实验

前提准备

  1. Z410无人机

Z410无人机已完全安装完毕并刷写完PX4固件相关内容,机载计算机上已安装配置好Prometheus系统(无需搭建仿真环境,核心组件包含Prometheus以及mavros)

  1. 地面端电脑

    地面端电脑运行Windows系统,需要安装有NoMachine以及QGC软件

  2. 无人机电池以及遥控器电池

    一块4S电池以及4节5号电池

  3. 无人机配套遥控器

    富斯I6-S遥控器

  4. 安全绳

调试阶段

  1. 数传模块通信测试

    按照阿木实验室官网提供的Z410-4B无人机使用手册连接上数传模块提供的wifi

  2. 软件程序运行测试

    输入以下命令,启动相关软件程序

    $ cd ${your prometheus path}/Prometheus/Scripts/experiment/tutorial_demo
    # 第一次启动该脚本时,需要添加可执行权限
    $ chmod +x takeoff_land.sh
    $ ./takeoff_land.sh
    

    该脚本会启动mavros、uav_control以及takeoff_land三个节点,通过查看脚本命令运行情况,确认各节点运行正常。

室外飞行测试

  1. 将无人机放置在室外环境中

  2. 将地面端电脑启动,连接上数传提供的wifi

  3. 地面端电脑通过NoMachine远程连接到无人机

  4. 在地面端电脑上启动QGC连接无人机飞控

  5. 确认无人机定位数据是否正常

    无人机在GPS定位良好情况下,无人机启动后如果没有移动过,无人机定位数据会有一定波动,但一般情况下为±3米内

  6. 在NoMachine中启动demo功能脚本文件

  7. 遥控器控制切换无人机控制模式为command_control(与仿真demo中遥控器操作一致)

建议先在Prometheus仿真系统当中熟悉相关程序运行以及遥控器控制相关内容

场景建模

一、介绍

  1. 打开场景编辑器
  2. UI介绍

二、导入平面图

三、添加特征

  1. 墙壁
  2. 添加门窗
  3. 添加楼梯
  4. 添加层
  5. 编辑建筑物 变更层数 编辑墙体 编辑门窗 添加颜色和纹理 保存场景 退出

四、模型编辑

  1. 保存退出
  2. 导出world

参考视频:

一、介绍

  • 在gazebo中,我们不仅可以对无人机建模,还可以对场景建模(即机器人所在环境),以下给大家介绍如何在gazebo中创建一栋房子,作为无人机的活动空间。

1、打开场景编辑器

启动gazebo,依次点击 Edit -> Building Editor, 或者使用快捷键 Ctrl+B 打开编辑器。界面如下:

image.png

2、UI介绍

该编辑器由以下3个区域组成:

  1. 调色板,在这里你可以选择你的建筑特征和材料。
  2. 2D视图,你可以导入楼层平面图,编辑器会根据平面图自动插入插入墙壁,门窗和楼梯。
  3. 3D视图,在这里你可以看到你的建筑物的预览。您还可以在其中为建筑物的不同部分分配颜色和纹理。

image.png

3、场景

  • 场景是模拟器的主要部分,是仿真模型显示的地方,你可以在这操作仿真对象,使其与环境进行交互。

图片.png

4、左右面板

图片.png

  • 左面板 启动Gazebo时,默认情况下界面会出现左侧面板。面板左上方有三个选项卡:

    • WORLD:“世界”选项卡,显示当前在场景中的模型,并允许你查看和修改模型参数,例如它们的姿势。你还可以通过展开“GUI”选项并调整相机姿势来更改摄像机视角。
    • INSERT:“插入”选项卡,向模拟添加新对象(模型)。要查看模型列表,您可能需要单击箭头以展开文件夹。在要插入的模型上单击(和释放),然后在场景中再次单击以添加它。
    • LAYER:“图层”选项卡可组织和显示模拟中可用的不同可视化组(如果有)。图层可以包含一个或多个模型。打开或关闭图层将显示或隐藏该图层中的模型。这是一个可选功能,因此在大多数情况下此选项卡将为空。要了解有关图层的更多信息,请查看gazebo官网。
  • 右侧面板 默认情况下Gazeb界面隐藏右侧面板。单击并拖动栏以将其打开。右侧面板可用于与所选模型(joint)的移动部件进行交互。如果未在场景中选择任何模型,则面板不会显示任何信息。

5、工具栏

  • Gazebo界面有两个工具栏。一个位于场景上方,另一个位于下方。 图片.png

  • 上部工作栏是Gazebo的主工具栏,它包含一些最常用的与模拟器交互的选项,例如:选择,移动,旋转和缩放对象等按钮; 创造一些简单的形状(如立方体,球体,圆柱体); 复制/粘贴模型选项。 -选择模式(select mode):在场景中导航

    • 翻译模式(translate mode):选择要移动的模型
    • 旋转模式(rotate mode):选择要旋转的模型
    • 缩放模式(scale mode):选择要缩放的模型
    • 撤消/重做(undo/redo):撤消/重做场景中的操作
    • 简单形状(simple shape):将简单形状插入场景中
    • 灯光(lights):为场景添加灯光
    • 复制/粘贴(copy/paste):在场景中复制/粘贴模型
    • Align:将模型彼此对齐
    • Snap:将一个模型与另一个模型对齐
    • 更改视图(change view):从各个角度查看场景
  • 底部工具栏 图片.png

  • 底部工具栏显示有关模拟的数据,如模拟时间及其与实际时间的关系。

    • “模拟时间”是指模拟运行时模拟器中时间流逝的速度。模拟时间可以比实时更慢或更快,具体取决于运行模拟所需的计算量。
    • “实时”是指模拟器运行时在现实生活中经过的实际时间。模拟时间和实时之间的关系称为“实时因子”(RTF)。它是模拟时间与实时的比率。RTF衡量模拟运行与实时相比的速度或速率。
    • Gazebo的世界状况每迭代一次,计算一次。你可以在底部工具栏的右侧看到迭代次数。每次迭代都会将模拟推进固定的秒数,称为步长。默认情况下,步长为1 ms。您可以按暂停按钮暂停模拟,并使用步骤按钮逐步执行几个步骤。

6、菜单栏

  • 像大多数应用程序一样,Gazebo顶部有一个应用程序菜单。某些菜单选项会显示工具栏中。在场景中,右键单击上下文菜单选项,可查看各种菜单。

图片.png

  • 注意: 一些 Linux 桌面隐藏应用程序菜单。 如果没有看到菜单,将光标移动到应用程序窗口的顶部,菜单就会出现。 图片.png

7、鼠标

鼠标操作方法,一般常用的就是“shift+鼠标左键”转换视角,“鼠标左键”平移视角,“滚轮”缩放大小

图片.png

二、导入平面图

  • 您可以从零开始创建建筑场景(参考第三、添加特征,来确定特征信息即可),也可以使用现有图像作为模板进行追溯。该图像可以是例如建筑物的2D激光扫描。
  • 这里给出示例平面图:

mmexport1680229529576.png

  • 然后按以下步骤操作:
  1. 点击调色板下方的 Import按钮。然后将会弹出 Import Image对话框。 image.png
  2. 选择平面图所在路径,然后单击 Nextimage.png image.png image.png
  3. 为确保在图像上绘制的墙以正确的比例显示,必须以像素/米(px/m)设置图像的分辨率。如果知道分辨率,则可以直接在对话框中输入分辨率,然后单击 Ok。在此示例中,我们不知道分辨率,但是我们知道图像中两点之间的真实距离(例如10米的墙壁),因此我们可以使用它来计算分辨率:
  • 点击墙的一端,然后在另一端释放。当您移动鼠标时,将显示橙色线,如下所示。 image.png image.png image.png
  • 现在,在对话框中输入以米为单位的距离(在这种情况下为10 m)。分辨率将根据您绘制的线条自动为您计算。 image.png
  • 最后,单击 Ok

三、添加特征

墙壁

  • 我们接下来会根据平面图绘制所有的墙壁。值得注意的是,稍后我们会将门窗附加到墙壁上,因此现阶段可以直接忽略门窗位置。如果你觉得墙壁不完美,不用担心,稍后我们将对其进行更加细致的编辑。
  1. 在调色板上,单击 Wall

image.png 2. 在2D视图上,在任意墙角单击开始绘制墙体。随着鼠标的移动,墙的长度也会跟着显示。

image.png

  1. 再次单击可以结束当前墙体的绘制,转而进入相邻墙体的绘制,如果想要取消绘制可以单击右键或者按下 esc。(这里跟cad sw的绘制直线有点类似)。 image.png

默认情况下,墙体会以15°和0.25 m递增,并且还会捕捉到现有墙的端点。如果不希望自动补抓,可在绘图时按住 Shift

添加门窗

注意:目前,门窗是墙上的简单孔。 让我们在平面图上所示的位置插入门窗。

在面板上,单击Window或Door。
在2D视图中移动鼠标时,要插入的特征会随之移动,在3D视图中其对应物也会随之移动。
单击所需位置以放置特征。![image.png](https://qiniu.md.amovlab.com/img/m/202303/20230331/1829474390216002965504000.png)

提示:将鼠标悬停在门上时,门窗会自动与墙壁对齐。移动时会显示到墙端的距离。![image.png](https://qiniu.md.amovlab.com/img/m/202303/20230331/1831154758321300009549824.png)

提示:在墙壁上添加了相关特征之后,可能很难看到其在平面图中的位置。为了简化操作,您可以在2D视图的顶部选择查看或隐藏当前级别的平面图或特征。您还可以使用热键来切换可见性,F对应floor和G对应特征。

image.png

编辑墙体

我们之前画了很多墙,但是也许它们并没有完全按照我们想要的方式绘制。我们有以下方式可以进行修改:

1、在2D视图中,单击要编辑的墙。

  • 通过将墙拖动到新位置来平移墙。
  • 通过拖动墙的端点之一来调整墙的大小或旋转墙。

2、在2D视图中双击墙以打开带有配置选项的检查器。或者,右键单击并选择 Open Wall Inspector。编辑你想要修改的内容,然后按 Apply预览更改。

3、选中你想要删除的墙体,按下键盘上的 Delete键,或在2D视图中右键单击墙体,选择 Delete

编辑门窗

  • 现在让我们一起编辑门窗。正如我们编辑墙体那样,也可以通过以下几种不同的方式更精确地控制门窗属性。
  1. 在2D视图中,单击要编辑的特征。 图片.png 图片.png

图片.png 图片.png

  • 通过将特征拖动到新位置来对其进行变换。
  • 拖动特征的旋转手柄来旋转特征。当前,只要将它们附着在墙上,它们的方向就不会改变。
  • 通过拖动端点之一来调整特征的宽度。
  1. 双击2D视图中的特征以打开带有配置选项的检查器。或者,右键单击并选择Open Window/Door Inspector
  2. 选中想要删除的特征,按下键盘的Delete键,或在2D视图中右键单击并选择Delete。

添加颜色和纹理

  • 现在,一切都已正确放置并确定大小,您可以为墙壁,地板和楼梯分配颜色和纹理。请记住,门窗只是墙上的孔,因此不能有任何材料。 有两种方法可以为建筑物添加颜色和纹理:
  1. 您可以从Wall Inspector、Stairs Inspector和Level Inspector分别为墙壁,楼梯和地板添加颜色和纹理。只需打开检查器,选择材料,然后按Apply
  2. 可以从调色板中选择颜色和纹理,然后通过在3D视图中单击将其分配给建筑物中的项目。

图片.png

a、单击调色板中的颜色或纹理。 b、在3D视图中移动鼠标时,悬停的功能将突出显示,显示所选材质的预览。 c、单击突出显示的功能会为其分配选定的材料。您可以根据需要单击任意数量的功能。 d、完成所选材质的操作后,右键单击3D视图,或在任何要素外部单击以退出材质模式。

保存场景

图片.png

在选用板上给您的建筑物起个名字。 图片.png

退出

注意:一旦退出场景编辑器后,场景就不能够再次编辑了。 完成创建建筑物并保存之后,请转到File,然后单击Exit Building Editor,您的建筑物将显示在主窗口中。您可以在Insert标签中找到该场景。

图片.png

图片.png

图片.png

模型编辑

  • 打开模型编辑
  1. 点击edit
  2. 点击model editor 图片.png
  • 插入制作的模型
    • 插入位置可以通过工具调整,不需要第一次插入时通过鼠标调整位置。
  1. 点击insert
  2. 找到创建的模型
  3. 放置模型到场景中 图片.png
  • 使用translate mode移动模型
  1. 点击translate mode
  2. 选择要移动的模型
  3. 选择要移动的方向
  4. 正负X移动
  5. 正负Y移动
  6. 正负Z移动

图片.png

  • 使用rotate mode旋转模型
  1. 点击rotate mode
  2. 选择要旋转的模型
  3. 蓝色绕Z轴旋转模型,绿色绕Y轴旋转模型,红色绕X轴旋转模型

图片.png

  • 将模型抬高以增加地板 图片.png
  1. 插入正方体
  2. 放置到场景中
  3. 点击scale mode缩放模型
  4. 选择正方体

图片.png

  1. 将正方体缩放到合适大小
  2. 将正方形缩放模型放到之前模型下做为地板

图片.png

  • 将地板向上移动贴合第一个模型

图片.png

  • 插入其他模型
  1. 选择插入的模型
  2. 放置到场景中
  3. 选择移动工具
  4. 移动到地板之上合适位置

图片.png

保存退出

  1. 点击file保存文件
  2. 推出编辑(之后就不可以编辑模型,只能导出world)

图片.png

图片.png

图片.png

导出world

  • 将模型调整好位置后,即可导出world文件
  1. 点击file

  2. 点击save world as 图片.png

  3. 选择保存位置

  4. 保存文件名(文件名以 .world 结尾保存)

  5. 保存save 图片.png

  • 打开保存的world文件,即可复制数据到仿真文件中。

图片.png

其他

本章内容将介绍与Prometheus相关内容,包括Prometheus项目使用当中的常见问题、科学上网指引、PX4参数大纲、ROS常见指令。

ROS常见指令

  • roscore

    启动ROS核心程序,包含master主节点,ros参数服务器,ros日志记录节点

  • rosrun

    启动任意ros功能包中的可执行节点,运行rosrun命令需要确保ROS主节点已经启动

    # 用法示例
    rosrun package_name executable_name
    
  • roslaunch

    启动任意ros功能包中的launch文件,launch文件可启动多个ROS节点以及设置ROS参数,在启动launch文件时,会自动检测是否运行roscore,如果没有将自动运行

    # 用法示例
    roslaunch package_name launch_file.launch
    
  • rosnode

    显示ROS节点相关信息

    rosnode info    # 打印有关节点信息
    rosnode kill    # 杀死一个正在运行的节点
    rosnode list    # 列出所有正在运行的节点列表
    rosnode machine # 列出在特定机器上运行的节点或列出机器
    rosnode ping    # 测试节点的连接状态
    rosnode cleanup # 清除不可达节点的注册信息
    
  • rostopic

    显示ROS话题相关信息

    rostopic bw     # 显示话题的带宽
    rostopic delay  # 显示话题通信的延迟
    rostopic echo   # 打印话题中的消息内容
    rostopic find   # 按消息类型查找话题
    rostopic hz     # 话题发布消息的频率
    rostopic info   # 话题发布的信息
    rostopic list   # 显示话题列表
    rostopic pub    # 发布消息到某一话题
    rostopic type   # 打印话题消息类型
    
  • rosmsg

    显示ROS消息相关信息

    rosmsg show    # 显示消息的具体数据类型以及变量名
    rosmsg list    # 显示消息列表
    
  • rosservice

    显示ROS服务相关信息

    rosservice call # 使用提供的参数调用服务
    rosservice find # 按服务类型查找服务
    rosservice info # 打印服务的信息
    rosservice list # 显示服务列表
    rosservice type # 打印服务消息类型
    
  • rossrv

    rossrv show # 显示服务消息的具体数据类型以及变量名
    rossrv list # 显示服务消息列表
    
  • rosparam

    显示ROS参数相关信息

    rosparam list   # 显示参数列表
    rosparam get    # 获取参数变量
    rosparam set    # 设置某一参数值
    rosparam delete # 删除某一参数变量
    
  • rosclean

    清除ROS日志,超过1GB时,ROS系统会出现红字提醒

    rosclean check # 检查ROS日志文件的磁盘使用情况
    rosclean purge # 删除存储的ROS日志文件
    
  • roscd

    直接通过功能包名搜寻到目标功能包路径,也可以搜寻其他ROS文件或文件夹

  • rosbag

    记录ROS相关话题信息

    rosbag record # 记录某一话题信息
    rosbag info   # 总结一个bag文件的内容
    rosbag play   # 播放一个bag文件的话题信息
    rosbag check  # 确定一个bag文件在当前系统中是否可以播放或迁移
    rosbag fix    # 修复bag文件的信息,使其可以在当前系统中播放
    
  • catkin_init_workspace

    声明终端当前路径所在文件夹为ROS工作空间

  • catkin_create_pkg

    创建一个ros功能包,改命令后第一个参数为新建功能包名字,后面的参数为依赖功能包名

    # 用法示例
    catkin_create_pkg package_name depend1 depend2 depend3
    

ubuntu系统软件推荐

常用软件推荐

  • 安装Chrome浏览器
    • 安装包下载网址:http://www.ubuntuchrome.com/
    • 同步账户需要翻墙,需要先装个翻墙小工具,附上网址:https://github.com/getlantern/lantern
  • 安装搜狗输入法
    • 安装包下载网址:https://pinyin.sogou.com/linux/
    • 教程:https://blog.csdn.net/scuping/article/details/86697287
  • 安装VScode
    • 强推的IDE,下载地址:https://code.visualstudio.com/#alt-downloads
    • deb安装方式,下载后配合一些插件使用,更加高效!
  • 安装sublime
    • 轻量化的IDE,下载地址:http://www.sublimetext.com/
  • 安装Typora
    • MD文档编辑工具,下载地址:https://www.typora.io/
  • 安装GitKraken(推荐)
    • git GUI工具,下载地址https://www.gitkraken.com/
    • 部分功能需要付费,但是很好用
  • 安装Matlab2018a
    • 下载安装包:https://www.52pojie.cn/thread-713126-1-1.html
    • 安装教程:https://www.cnblogs.com/iwuqing/p/9833292.html
  • CPU温度检测插件
    • https://blog.csdn.net/yjt1325/article/details/84639500(似乎有点问题)
    • https://jingyan.baidu.com/article/a17d5285f043c38098c8f21d.html
  • AX200无线网卡驱动安装
    • 可能需要更新内核
    • 下载并安装驱动https://www.intel.com/content/www/us/en/support/articles/000005511/network-and-i-o/wireless-networking.html
  • 其他
    • 使ubuntu支持exfat格式的移动硬盘
      • sudo apt-get install exfat-utils

ubuntu系统美化

  • ubuntu美化之GNOME Shell插件 (强烈推荐)
    • 参考教程:https://linux.cn/article-9447-1.html
    • 推荐的GNOME Shell插件有
      • User Themes 管理主体
      • Dash to dock
      • Drop from terminal 下拉式终端
      • Netspeed 网速监控插件
      • Sound Input & Output Device Chooser 声音输入输出设备选择
      • Clipboard Indicator 剪切板管理
      • Screenshot Tool 截图插件
      • Removable Driver Menu U盘可插拔提示
      • EasyScreenCast 录屏插件
  • ubuntu美化之自定义主题
    • 前提是已经装好tweak工具,下载对应主题,并解压至home/.theme目录中,便可在tweak中选择相应的主题
    • 主题下载网址 https://www.pling.com/s/Gnome

其他

安装sudo rosdep init 下载失败解决方案:https://blog.csdn.net/u013468614/article/details/102917569

科学上网指引

梯子工具推荐:https://stellar.dog/

网友教程:https://doc.fastgit.org/zh-cn/guide.html#web-%E7%9A%84%E4%BD%BF%E7%94%A8

常见问题

  • Q: 英伟达的板子能否跑仿真?

    A: 仿真不能在tx2和NX上跑,更加不推荐。仿真的合理配置是高性能的台式机。

  • Q: Prometheus镜像下载安装地址?

    A: 镜像地址 : https://mp.weixin.qq.com/s/rAtXVP2S5b1nGyHiY0eXgQ##

  • Q: 运行PX4仿真出现一些红字报错?

    A: 某些报错并不影响仿真运行,主要看某型有没有正常加载和运行。

  • Q: 树莓派4B可以运行Prometheus项目吗?

    A: 控制模块应该可以运行,但视觉模块应该不行。

  • Q: Prometheus支持ardupilot(APM)吗?

    A: Prometheus项目基于PX4,APM和PX4用mavros实现和飞控通信,但是需要一定量的改动。

PX4常用参数大纲以及说明

PX4无人机有非常多的参数,在仿真开发测试过程中,根据不同功能以及应用场景,都需要对无人机参数进行调整,常见的px4无人机参数可以参考以下资料,用户可根据自身开发以及测试需求更改无人机参数。

注意:不同PX4固件中参数略有差异,以下参数选择的PX4固件为1.12.3版本

传感器任务定义参数

  • COM_DL_LOSS_T

    参数说明:数据链路丢失时间阈值,在数据丢失时间达到阈值后,数据链路丢失模式触发

    单位: 秒(S)

    默认值:10.0

    最小值:5.0

    最大值:300.0

    备注:无

  • COM_RC_LOSS_T

    参数说明:RC丢失时间阈值,在RC丢失时间达到阈值后,它被认为丢失并且不再使用

    单位: 秒

    默认值:0.5

    最小值:0.0

    最大值:35.0

    备注:无

  • NAV_RCL_ACT

    参数说明:设置RC丢失故障保护模式

    单位:无

    默认值:0

    最小值:1

    最大值:6

    备注:1 - Hold 2 - Return 3 - Land 5 - Terminate 6 - Lockdown

  • COM_DISARM_LAND

    参数说明:降落后触发自动上锁时间,设置为非零的正值将会在降落后达到阈值后自动上锁,设置为0或负数为禁止该功能。

    单位: 秒

    默认值:2

    最小值:无

    最大值:无

    备注:无

  • COM_DISARM_PRFLT

    参数说明:不起飞时自动上锁时间,设置为一个非零时间,在该时间内预计无人机将起飞,如果无人机没有起飞则进行上锁,设置为负值则禁用。

    单位: 秒

    默认值:2

    最小值:无

    最大值:无

    备注:无

  • COM_ARM_WO_GPS

    参数说明:是否允许在无GPS的情况下进行解锁,默认允许在无GPS情况下进行解锁。

    单位:无

    默认值:10

    最小值:无

    最大值:无

    备注:0 - 需要GPS LOCK才能解锁,1 - 允许在无GPS情况下进行解锁

  • COM_LOW_BAT_ACT

    参数说明:电池故障保护模式,BAT_CRIT_THR和BAT_EMERGEN_THR可定义电池状态。

    单位:无

    默认值:0

    最小值:无

    最大值:无

    备注:0 - Warning,2 - Land mode 3 - 电池电量临界水平返航,紧急水平降落

  • COM_OF_LOSS_T

    参数说明:触发机载计算机控制信号丢失操作时间阈值,在板载计算机控制信号丢失时间达到该阈值后将触发信号丢失操作,配合COM_OBL_ACT以及COM_OBL_RC_ACT来使用

    单位:秒

    默认值:0

    最小值:0

    最大值:60

    备注:无

  • COM_OBL_ACT

    参数说明:设置机载计算机控制信号丢失故障保护模式

    单位:无

    默认值:0

    最小值:无

    最大值:无

    备注:-1 - 禁用 0 - Land 1 - Hold 2 - Return 3 - Terminate 4 - Lockdown

  • COM_OBC_LOSS_T

    参数说明:机载计算机连接丢失超时,发出连接丢失警告

    单位:秒

    默认值:5

    最小值:0

    最大值:60

    备注:无

  • COM_ARM_EKF_POS

    参数说明:允许解锁的 EKF position innovation test radio 值,高于该值则不能解锁

    单位:无

    默认值:0.5

    最小值:0.1

    最大值:1.0

    备注:无

  • COM_ARM_EKF_VEL

    参数说明:允许解锁的 EKF velocity innovation test radio 值,高于该值则不能解锁

    单位:无

    默认值:0.5

    最小值:0.1

    最大值:1.0

    备注:无

  • COM_ARM_EKF_HGT

    参数说明:允许解锁的 EKF height innovation test radio 值,高于该值则不能解锁

    单位:无

    默认值:1.0

    最小值:0.1

    最大值:1.0

    备注:无

  • COM_ARM_EKF_YAW

    参数说明:允许解锁的 EKF yaw innovation test radio 值,高于该值则不能解锁

    单位:无

    默认值:0.5

    最小值:0.1

    最大值:1.0

    备注:无

  • COM_ARM_IMU_ACC

    参数说明:IMU与加速度计差值最大值,高于该值则不能解锁

    单位:无

    默认值:0.7

    最小值:0.1

    最大值:1.0

    备注:无

  • COM_ARM_IMU_GYR

    参数说明:IMU与陀螺仪差值最大值,高于该值则不能解锁

    单位:无

    默认值:0.25

    最小值:0.02

    最大值:0.3

    备注:无

  • COM_ARM_MAG_ANG

    参数说明:磁场角度差值最大值,高于该值则不能解锁

    单位:度

    默认值:45

    最小值:3

    最大值:180

    备注:无

  • COM_ARM_MAG_STR

    参数说明:启动磁力强度预检检查,如果估算器检测到强磁场,则拒绝启动,EKF2_MAG_CHECK可启动检查

    单位:无

    默认值:1

    最小值:无

    最大值:无

    备注:无

  • COM_RCL_EXCEPT

    参数说明:指定忽略RC丢失且未触发故障保护动作的模式(额外的模式)

    单位:无

    默认值:2

    最小值:0

    最大值:31

    备注:bit0 - Mission bit1 - Hold bit2 - Offboard

  • COM_KILL_DISARM

    参数说明:触发kill之后多长时间后进行上锁

    单位:秒

    默认值:5

    最小值:0

    最大值:30

    备注:无

地理围栏

  • GF_MAX_HOR_DIST

    参数说明:无人机飞行范围的最大水平距离

    单位: 米

    默认值:0

    最小值:0

    最大值:10000

    备注:无

  • GF_MAX_VER_DIST

    参数说明:无人机飞行范围的最大垂直距离

    单位: 米

    默认值:0

    最小值:0

    最大值:10000

    备注:无

  • GF_ACTION

    参数说明:地理围栏违规行为,当无人机飞行超过地理围栏后触发的模式

    单位: 无

    默认值:2

    最小值:0

    最大值:5

    备注:0 - 不操作 1 - Warning 2 - Hold mode 3 - Return mode 4 - Terminate 5 - Land mode

返航

  • RTL_RETURN_ALT

    参数说明:返航模式飞行的高度

    单位: 米

    默认值:60

    最小值:0

    最大值:150

    备注:无

EKF2参数

  • EKF2_AID_MASK

    参数说明:控制数据融合和辅助方法(定位数据来源)

    单位: 无

    默认值:1

    最小值:0

    最大值:511

    备注: bit0 - 使用GPS bit1 - 使用光流 bit2 - 禁止IMU偏差估计 bit3 - 视觉位置融合 bit4 - 视觉偏航融合 bit5 - multi-rotor drag fusion bit6 - rotate external vision bit7 - GPS偏航融合 bit8 - 视觉速度融合

  • EKF2_HGT_MODE

    参数说明:确认EKF使用的高度数据的主要来源

    单位: 无

    默认值:0

    最小值:无

    最大值:无

    备注:0 - 气压计 1 - GPS 2 - 距离传感器 3 - 视觉

  • EKF2_EV_DELAY

    参数说明:相对于IMU测量的视觉位置估计器延迟

    单位: 毫秒

    默认值:175

    最小值:0

    最大值:300

    备注:无

  • EKF2_REQ_NSATS

    参数说明:使用GPS所需的最小卫星数量

    单位: 无

    默认值:6

    最小值:4

    最大值:12

    备注:无

  • EKF2_ACC_NOISE

    参数说明:用于协方差预测的加速度计噪声

    单位: m/s^2

    默认值:0.35

    最小值:0.01

    最大值:1.0

    备注:无

  • EKF2_GYR_NOISE

    参数说明:用于协方差预测的陀螺仪噪声

    单位: 无

    默认值:0.015

    最小值:0.0001

    最大值:0.1

    备注:无

  • EKF2_GPS_V_NOISE

    参数说明:GPS水平速度的测量噪声

    单位: m/s

    默认值:0.3

    最小值:0.01

    最大值:5.0

    备注:无

  • EKF2_GPS_P_NOISE

    参数说明:GPS位置的测量噪声

    单位: 无

    默认值:0.5

    最小值:0.01

    最大值:10.0

    备注:无

CBRK系列

  • CBRK_SUPPLY_CHK

    参数说明:电源检查使能

    单位: 无

    默认值:0

    最小值:0

    最大值:894281

    备注:该参数设置为894281将禁用电源有效检查

  • CBRK_RATE_CTRL

    参数说明:速率控制器输出使能

    单位: 无

    默认值:0

    最小值:0

    最大值:140253

    备注:参数设置为140253将禁用速率控制器uORB发布

  • CBRK_IO_SAFETY

    参数说明:IO安全使能

    单位: 无

    默认值:22027

    最小值:0

    最大值:22027

    备注:参数设置为22027将禁用IO安全

  • CBRK_AIRSPD_CHK

    参数说明:空速传感器使能

    单位: 无

    默认值:0

    最小值:0

    最大值:162128

    备注:参数设置为162128将禁用空速传感器检查

  • CBRK_FLIGHTTERM

    参数说明:飞行终止使能

    单位: 无

    默认值:121212

    最小值:0

    最大值:121212

    备注:此参数设置为121212将在触发失效保护操作或FMU丢失时禁用飞行终止动作

  • CBRK_ENGINEFAIL

    参数说明:电机故障检测使能

    单位: 无

    默认值:284953

    最小值:0

    最大值:284953

    备注:参数设置为284953将禁用电机故障检测

  • CBRK_BUZZER

    参数说明:蜂鸣器使能

    单位: 无

    默认值:0

    最小值:0

    最大值:782097

    备注:参数设置为782097将禁用蜂鸣器

  • CBRK_USB_CHK

    参数说明:USB连接检查使能

    单位: 无

    默认值:197848

    最小值:0

    最大值:197848

    备注:参数设置为197848将禁用USB连接检查

  • CBRK_VELPOSERR

    参数说明:位置检查使能

    单位: 无

    默认值:0

    最小值:0

    最大值:201607

    备注:设置为201607将禁用位置和速度检查

  • CBRK_VTOLARMING

    参数说明:固定翼模式解锁使能

    单位: 无

    默认值:0

    最小值:0

    最大值:159753

    备注:参数设置为159753将为VTOL启动固定翼模式解锁

多旋翼控制器参数

  • MPC_THR_MIN

    参数说明:自动推力控制中的最小推力

    单位: 无

    默认值:0.12

    最小值:0.05

    最大值:1.0

    备注:建议设置>0避免零推力自由落体

  • MPC_THR_MAX

    参数说明:自动推力控制中的最大推力

    单位: 无

    默认值:1.0

    最小值:0.0

    最大值:1.0

    备注:无

  • MPC_THR_HOVER

    参数说明:悬停推力

    单位: 无

    默认值:0.5

    最小值:0.1

    最大值:0.8

    备注:该参数对于降落检测的正常工作有影响

  • MPC_USE_HTE

    参数说明:悬停推力源选择器

    单位: 无

    默认值:1

    最小值:无

    最大值:无

    备注:设置为false使用固定参数MPC_THR_HOVER,设置为true使用悬停推力估计器估计的值

位置控制参数

  • MPC_POS_MODE ​ 参数说明:手动位置控制子模式

    单位:无

    默认值:4

    最小值:无

    最大值:无

    备注:0 - 简单位置控制 3 - 平滑位置控制(Jerk优化) 4 - 基于加速度的输入

  • MPC_Z_P

    参数说明:垂直位置误差的比例增益

    单位: 无

    默认值:1.0

    最小值:0.0

    最大值:1.5

    备注:无

  • MPC_Z_VEL_P_ACC

    参数说明:垂直速度误差的比例增益

    单位: 无

    默认值:4.0

    最小值:2.0

    最大值:15.0

    备注:无

  • MPC_Z_VEL_I_ACC

    参数说明:垂直速度误差的积分增益

    单位: 无

    默认值:4.0

    最小值:0.2

    最大值:3.0

    备注:无

  • MPC_Z_VEL_D_ACC

    参数说明:垂直速度误差的微分增益

    单位: 无

    默认值:0.0

    最小值:0.0

    最大值:2.0

    备注:无

  • MPC_VELD_LP

    参数说明:低通滤波器截止频率

    单位: HZ

    默认值:5.0

    最小值:0.0

    最大值:10.0

    备注:无

  • MPC_XY_P

    参数说明:水平位置误差的比例增益

    单位: 无

    默认值:0.95

    最小值:0.0

    最大值:2.0

    备注:无

  • MPC_XY_VEL_P_ACC

    参数说明:水平速度误差的比例增益

    单位: 无

    默认值:1.8

    最小值:1.2

    最大值:5.0

    备注:无

  • MPC_XY_VEL_I_ACC

    参数说明:水平速度误差的积分增益

    单位: 无

    默认值:0.4

    最小值:0.0

    最大值:60.0

    备注:无

  • MPC_XY_VEL_D_ACC

    参数说明:水平速度误差的微分增益

    单位: 无

    默认值:0.2

    最小值:0.1

    最大值:2.0

    备注:无

  • MPC_LAND_SPEED

    参数说明:降落速度

    单位: m/s

    默认值:0.7

    最小值:0.6

    最大值:无

    备注:-

  • MPC_TKO_SPEED

    参数说明:起飞速度

    单位: m/s

    默认值:1.5

    最小值:1

    最大值:5

    备注:无

位置控制限制参数

  • MPC_XY_VEL_MAX

    参数说明:最大水平速度

    单位: m/s

    默认值:12.0

    最小值:0.0

    最大值:20.0

    备注:无

  • MPC_Z_VEL_MAX_UP

    参数说明:最大垂直上升速度

    单位: m/s

    默认值:3.0

    最小值:0.5

    最大值:8.0

    备注:无

  • MPC_Z_VEL_MAX_DN

    参数说明:最大垂直下降速度

    单位: m/s

    默认值:1.0

    最小值:0.5

    最大值:4.0

    备注:无

  • MPC_XY_ERR_MAX

    参数说明:轨迹发生器允许的最大水平误差

    单位: 无

    默认值:2.0

    最小值:0.1

    最大值:10.0

    备注:无

  • MPC_TILTMAX_AIR

    参数说明:空中最大倾斜角

    单位: 度

    默认值:45

    最小值:20

    最大值:89

    备注:无

  • MPC_TILTMAX_LND

    参数说明:着陆时的最大倾斜角

    单位: 度

    默认值:12

    最小值:10

    最大值:89

    备注:无

  • MPC_ACC_UP_MAX

    参数说明:速度控制模式下的最大垂直上升加速度

    单位: m/s^2

    默认值:4.0

    最小值:2.0

    最大值:15.0

    备注:-

  • MPC_ACC_DOWN_MAX

    参数说明:速度控制模式下的最大垂直下降加速度

    单位: m/s^2

    默认值:3.0

    最小值:2.0

    最大值:15.0

    备注:无

  • MPC_JERK_MAX

    参数说明:最大加加速度限制

    单位: m/s^3

    默认值:8.0

    最小值:0.5

    最大值:500.0

    备注:仅在MPC_POS_MODE设置为3或4时使用,设置为最大值实际上会禁用限制

  • MPC_LAND_RC_HELP

    参数说明:自主降落例行程序启用用户辅助下降速度,0选择MPC_LAND_SPEED固定速度,1选择用户辅助下降速度

    单位: 无

    默认值:0

    最小值:0

    最大值:1

    备注:摇杆最顶端速度为0,摇杆中间速度为MPC_LAND_SPEED, 摇杆最底部速度为 2 * MPC_LAND_SPEED

角度控制参数

  • MC_ROLL_P

    参数说明:横滚角度控制的比例增益

    单位: 无

    默认值:6.5

    最小值:0.0

    最大值:12

    备注:无

  • MC_PITCH_P

    参数说明:俯仰角度控制的比例增益

    单位: 无

    默认值:6.5

    最小值:0.0

    最大值:12

    备注:无

  • MC_YAW_P

    参数说明:偏航角度控制的比例增益

    单位: 无

    默认值:2.8

    最小值:0.0

    最大值:5.0

    备注:无

角度控制限制参数

  • MC_ROLLRATE_MAX

    参数说明:横滚最大角速度

    单位: deg/s

    默认值:220

    最小值:0.0

    最大值:1800.0

    备注:无

  • MC_PITCHRATE_MAX

    参数说明:俯仰最大角速度

    单位: deg/s

    默认值:220

    最小值:0

    最大值:1800

    备注:无

  • MC_YAWRATE_MAX

    参数说明:偏航最大角速度

    单位: deg/s

    默认值:200

    最小值:0.0

    最大值:1800.0

    备注:无

角速度控制参数

  • MC_ROLLRATE_P

    参数说明:横滚角速度的比例增益

    单位: 无

    默认值:0.15

    最小值:0.01

    最大值:0.5

    备注:无

  • MC_ROLLRATE_I

    参数说明:横滚角速度的积分增益

    单位: 无

    默认值:0.2

    最小值:0.0

    最大值:无

    备注:无

  • MC_ROLLRATE_D

    参数说明:横滚角速度的微分增益

    单位: 无

    默认值:0.003

    最小值:0.0

    最大值:0.1

    备注:无

  • MC_ROLLRATE_FF

    参数说明:横滚加速度的前馈

    单位: 无

    默认值:0.0

    最小值:0.0

    最大值:无

    备注:无

  • MC_ROLLRATE_K

    参数说明:横滚角速度控制器增益,控制器的全局增益

    单位: 无

    默认值:1.0

    最小值:0.01

    最大值:5.0

    备注:无

  • MC_PITCHRATE_P

    参数说明:俯仰角速度的比例增益

    单位: 无

    默认值:0.15

    最小值:0.01

    最大值:0.6

    备注:无

  • MC_PITCHRATE_I

    参数说明:俯仰角速度的积分增益

    单位: 无

    默认值:0.2

    最小值:0.0

    最大值:无

    备注:无

  • MC_PITCHRATE_D

    参数说明:俯仰角速度的微分增益

    单位: 无

    默认值:0.003

    最小值:0.0

    最大值:无

    备注:无

  • MC_PITCHRATE_FF

    参数说明:俯仰角速度前馈

    单位: 无

    默认值:0.0

    最小值:0.0

    最大值:无

    备注:无

  • MC_PITCHRATE_K

    参数说明:俯仰角速度控制器增益,控制器的全局增益

    单位: 无

    默认值:1.0

    最小值:0.01

    最大值:5.0

    备注:无

  • MC_YAWRATE_P

    参数说明:偏航角速度的比例增益

    单位: 无

    默认值:0.2

    最小值:0.0

    最大值:0.6

    备注:无

  • MC_YAWRATE_I

    参数说明:偏航角速度的积分增益

    单位: 无

    默认值:0.1

    最小值:0.0

    最大值:无

    备注:无

  • MC_YAWRATE_D

    参数说明:偏航角速度的微分增益

    单位: 无

    默认值:0.0

    最小值:0.0

    最大值:无

    备注:无

  • MC_YAWRATE_FF

    参数说明:偏航角速度的前馈

    单位: 无

    默认值:0.0

    最小值:0.0

    最大值:无

    备注:无

  • MC_YAWRATE_K

    参数说明:俯仰角速度控制器增益,控制器的全局增益

    单位: 无

    默认值:1.0

    最小值:0.0

    最大值:5.0

    备注:无

角速度控制限制参数

  • MC_RR_INT_LIM

    参数说明:横滚角速度积分限制

    单位: 无

    默认值:0.3

    最小值:0.0

    最大值:无

    备注:无

  • MC_PR_INT_LIM

    参数说明:俯仰角速度积分限制

    单位: 无

    默认值:0.3

    最小值:0.0

    最大值:无

    备注:无

  • MC_YR_INT_LIM

    参数说明:偏航角速度积分限制

    单位: 无

    默认值:0.3

    最小值:0.0

    最大值:无

    备注:无