无人机/飞控--ArduPilot、PX4学习记录(5)

news/2024/4/30 10:29:15/文章来源:https://blog.csdn.net/weixin_63010525/article/details/137550265

这几天看dronekit,做无人机失控保护。


PX4官网上的经典案例,我做了很多注解,把代码过了一遍。

无人机具体执行了: 先起飞,飞至正上空10m->向北移动10m->向东移动10m->向南移动10m->向西移动10m->回到初始起飞点(即home点),降落。

具体执行之前,要打开JMAVSim,接下来会在JMAVSim上看到无人机仿真效果:

代码+详细注解:

#####################################
# @File DroneKitPX4.py
# Example usage of DroneKit with PX4
# @author Sander Smeets <sander@droneslab.com>
# Code partly based on DroneKit (c) Copyright 2015-2016, 3D Robotics.
################################# Import DroneKit-Python
#库:提供与无人机通信、解析命令行参数、进行数学运算功能#dronekit:通过MAVLink协议与自动驾驶系统(如PX4)进行通信,控制无人机
from dronekit import connect, Command, LocationGlobal#pymavlink:用于解析和生成MAVLink消息
from pymavlink import mavutil#分别用于时间处理、系统调用、命令行参数解析、数学运算
import time, sys, argparse, math#----------------------------------------------------
# Settings设置
connection_string = '127.0.0.1:14540' #字符串:连接到无人机的地址和端口MAV_MODE_AUTO = 4 #定义无人机自动飞行模式的代码,设置为4
MAV_MODE_POSHOLD = 5 #定点模式,设置为5
MAV_MODE_STABILIZE = 6 #自稳模式,设置为6# https://github.com/PX4/Firmware/blob/master/Tools/mavlink_px4.py#------------------------------------------------------------
# Parse connection argument解析命令行参数
#使用argparse库,允许用户通过过命令行参数来指定连接字符串。
parser = argparse.ArgumentParser()
parser.add_argument("-c", "--connect", help="connection string")
args = parser.parse_args()#若用户提供-c或--connect参数,那么connection_string会被更新为用户的输入
if args.connect:connection_string = args.connect#------------------------------------------------------------
# Init 初始化  ;Connect to the Vehicle 连接到无人机
print ("Connecting")# 使用dronekit中的connect函数连接到无人机
# wait_ready=True表示在继续执行代码前,程序会等待无人机准备好
vehicle = connect(connection_string, wait_ready=True)#PX4setMode(mavMode):设置无人机模式 使用MAVLink协议向无人机发送命令
def PX4setMode(mavMode):# 使用 pymavlink 的 command_long_send 方法向无人机发送一个 MAV_CMD_DO_SET_MODE 命令# 告诉无人机切换到指定的飞行模式(由 mavMode 参数指定)'''vehicle._master.target_system:MAVLink消息的目标系统ID,对于连接到本地地面站的无人机,通常为1vehicle._master.target_component:MAVLink消息的目标组件ID,向无人机的某个特定组件发送命令。通常为0mavutil.mavlink.MAV_CMD_DO_SET_MODE:MAVLink命令的ID,表示要执行的具体操作,用于请求无人机切换到指定的飞行模式0:确认标志,0表示不需要任何确认mavMode:想要无人机进入的飞行模式,是PX4setMode函数的输入参数,表示想要设置的飞行模式代码(手动、稳定、自动模式等)(0, 0, 0, 0, 0, 0):额外的参数对于MAV_CMD_DO_SET_MODE命令不是必需的,这些参数可能包含额外的信息如目标位置、速度或方向'''vehicle._master.mav.command_long_send(vehicle._master.target_system, vehicle._master.target_component,mavutil.mavlink.MAV_CMD_DO_SET_MODE, 0,mavMode,0, 0, 0, 0, 0, 0)#计算偏移位置--------------------------------------------------------------------
#根据给定原始位置、北偏移量、东偏移量和高度,计算新的全球位置。使用地球的半径来计算偏移量
def get_location_offset_meters(original_location, dNorth, dEast, alt):"""original_location:原始位置,包括经度 纬度 高度dNorth:向北偏移量(以米为计算单位)dEast:向东偏移量alt:高度Returns a LocationGlobal object containing the latitude/longitude `dNorth` and `dEast` metres from thespecified `original_location`. The returned Location adds the entered `alt` value to the altitude of the `original_location`.The function is useful when you want to move the vehicle around specifying locations relative tothe current vehicle position.The algorithm is relatively accurate over small distances (10m within 1km) except close to the poles.For more information see:http://gis.stackexchange.com/questions/2951/algorithm-for-offsetting-a-latitude-longitude-by-some-amount-of-meters"""earth_radius=6378137.0 #Radius of "spherical" earth 地球半径的近似值#Coordinate offsets in radians#计算纬度、经度偏移量dLat = dNorth/earth_radius #将向北的偏移量除以地球半径,将米转换为弧度dLon = dEast/(earth_radius*math.cos(math.pi*original_location.lat/180))#计算向东的偏移量#New position in decimal degrees计算新的纬度和经度# 将弧度偏移量转换回十进制度,并加到原始位置的纬度和经度上newlat = original_location.lat + (dLat * 180/math.pi)newlon = original_location.lon + (dLon * 180/math.pi)#使用新的纬度和经度以及调整后的高度(原始高度加上输入的高度)来创建一个新的LocationGlobal对象,并返回return LocationGlobal(newlat, newlon,original_location.alt+alt)
#-----------------------------------------------------------------------------#---------------------------------------------------------
# Listeners  设置监听器
#定义全局变量home_position_set 标记是否已经收到无人机home位置的信息
home_position_set = False#Create a message listener for home position fix
@vehicle.on_message('HOME_POSITION') #使用装饰器 创建一个监听器#该监听器(装饰器)会在收到HOME_POSITION消息时被调用
def listener(self, name, home_position):global home_position_set #全局变量#当接收到此消息时,listener函数会将home_position_set设置为Truehome_position_set = True
#--------------------------------------------------------#--------------------------------------------------------
# Start mission example
# wait for a home position lock 等待home位置锁定
while not home_position_set:#持续循环检查home_position_set是否为Trueprint ("Waiting for home position...")#尚未收到home位置消息,等待一秒钟。确保无人机获得home位置后才能继续执行time.sleep(1)
#--------------------------------------------------------------#--------------------------------------------------------------
# Display basic vehicle state显示无人机状态
print (" Type: %s" % vehicle._vehicle_type) #类型
print (" Armed: %s" % vehicle.armed) #武装状态
print (" System status: %s" % vehicle.system_status.state)#系统状态
print (" GPS: %s" % vehicle.gps_0)#GPS状态
print (" Alt: %s" % vehicle.location.global_relative_frame.alt) #海拔高度
#--------------------------------------------------------------#--------------------------------------------------------------
# Change to AUTO mode 切换到自动模式/定点模式/自稳模式
#使用先前定义的PX4setMode函数将无人机切换到自动飞行模式MAV_MODE_AUTO
PX4setMode(MAV_MODE_AUTO)#PX4setMode(MAV_MODE_POSHOLD) #设置为定点模式#PX4setMode(MAV_MODE_STABILIZE) #设置为自稳模式time.sleep(1) #为确保模式切换生效,程序暂停一秒
#-----------------------------------------------------------------#---------------------------------------------------------------
# Load commands 清楚飞行命令并获取home位置
cmds = vehicle.commands #获取无人机的飞行命令对象
cmds.clear() #清除之前所有的命令 为准备加载新的飞行计划#获取无人机当前home位置(起飞点或归位点)
home = vehicle.location.global_relative_frame
#---------------------------------------------------------------#-----------------------------------------------------------------
# 设置无人机飞行任务-起飞、移动、降落 并上传这些任务到无人机# 1.takeoff to 10 meters 起飞至10米
# get_.._meters函数根据home位置(起飞点),计算新位置 偏移量为向东0米、向北0米、向上10米。这将是无人机起飞的目标位置
wp = get_location_offset_meters(home, 0, 0, 10);#Command创建一个无人机命令对象,用于指示无人机起飞。
#这里使用了MAV_CMD_NAV_TAKEOFF命令,并指定了目标位置的经纬度和高度
'''
0: Command 的序列号,通常情况下可以将其设置为 0。
0: 系统 ID,表示指令发送者的系统 ID。
0: 组件 ID,表示指令发送者的组件 ID。
mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT: 定义了航点的参考坐标系,此处为全球相对高度坐标系。
mavutil.mavlink.MAV_CMD_NAV_TAKEOFF: 起飞命令的 ID,指示无人机执行起飞动作。
0: 确认/重发标志位,通常设置为 0。
1: 参数 1,此处表示起飞的最小高度(单位:米)。
0,0,0,0,0: 参数 2-6,通常设置为 0。
wp.lat: 航点的纬度坐标
wp.lon: 航点的经度坐标
wp.alt: 航点的高度
'''
cmd = Command(0,0,0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_TAKEOFF, 0, 1, 0, 0, 0, 0, wp.lat, wp.lon, wp.alt)cmds.add(cmd) #将起飞命令添加到飞行命令列表中# 2.move 10 meters north向北移动10米
#根据前一个命令的结束位置计算新的位置wp:偏移量为向北10m,向东0m,向上0m   (wp,北,东,上)
wp = get_location_offset_meters(wp, 10, 0, 0);#创建无人机命令对象MAV_CMD_NAV_WAYPOINT,指示无人机移动到新的位置
cmd = Command(0,0,0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 1, 0, 0, 0, 0, wp.lat, wp.lon, wp.alt)
cmds.add(cmd)#将移动命令添加到飞行命令列表中# 3.move 10 meters east向东移动10米
wp = get_location_offset_meters(wp, 0, 10, 0);
cmd = Command(0,0,0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 1, 0, 0, 0, 0, wp.lat, wp.lon, wp.alt)
cmds.add(cmd)#将移动命令添加到飞行命令列表中# 4.move 10 meters south向南移动10米
wp = get_location_offset_meters(wp, -10, 0, 0);
cmd = Command(0,0,0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 1, 0, 0, 0, 0, wp.lat, wp.lon, wp.alt)
cmds.add(cmd)#将移动命令添加到飞行命令列表中# 5.move 10 meters west向西移动10米
#根据前一个命令的结束位置计算新位置:偏移量为向东0m,向北-10(向南10米),向上0米
wp = get_location_offset_meters(wp, 0, -10, 0);#创建无人机命令对象,指示无人机向西移动
cmd = Command(0,0,0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_WAYPOINT, 0, 1, 0, 0, 0, 0, wp.lat, wp.lon, wp.alt)
cmds.add(cmd)#将移动命令添加到飞行命令列表中# 6.land 降落 先回到起始home位置
#计算降落位置,偏移量为相对于起飞点home:向东0m,向北0m,向上10m.实际上是在起飞点上方10米处降落
wp = get_location_offset_meters(home, 0, 0, 10);#创建无人机命令对象,指示无人机降落。使用的是MAV_CMD_NAV_LAND命令
cmd = Command(0,0,0, mavutil.mavlink.MAV_FRAME_GLOBAL_RELATIVE_ALT, mavutil.mavlink.MAV_CMD_NAV_LAND, 0, 1, 0, 0, 0, 0, wp.lat, wp.lon, wp.alt)
cmds.add(cmd)#将移动命令添加到飞行命令列表中
#----------------------------------------------------------------------------------------#----------------------------------------------------------------# Upload mission 上传任务
cmds.upload() #将命令列表上传到无人机
time.sleep(2) #等待两秒,确保无人机有足够的时间来处理上传的飞行任务# Arm vehicle 武装无人机
vehicle.armed = True #True意味着无人机现在处于武装状态,可执行飞行任务# monitor mission execution监控无人机执行任务的过程
nextwaypoint = vehicle.commands.next #初始化nextwaypoint变量为当前无人机正在执行的命令的索引#此循环会一直运行 直到无人机完成了所有的飞行命令
while nextwaypoint < len(vehicle.commands):#检查无人机是否已经开始执行下一个命令if vehicle.commands.next > nextwaypoint:#计算并显示无人机将要移动到的命令的序号(从1开始记号)display_seq = vehicle.commands.next+1#打印无人机将要移动到的命令序号print ("Moving to waypoint %s" % display_seq)#更新nextwaypoint变量为无人机当前正在执行的命令的索引nextwaypoint = vehicle.commands.nexttime.sleep(1) #每次循环后等待1s,避免过度占用处理器资源,允许无人机有时间执行命令# wait for the vehicle to land 等待无人机降落
while vehicle.commands.next > 0: #循环结束至无人机完成了最后一个命令time.sleep(1)  #每次循环后等待1s,允许无人机有时间执行命令# Disarm vehicle 接触无人机武装
vehicle.armed = False#将无人机armed属性设为False,无人机现处于非武装状态,不能执行飞行任务#这通常是在无人机完成任务并安全降落后进行的
time.sleep(1) #等待1s,允许无人机有时间处理武装状态的改变# Close vehicle object before exiting script关闭无人机
vehicle.close() #关闭与无人机的连接,释放相关资源
time.sleep(1) #等待一秒,确保关闭过程完成

保存几个网站:

px4官方文档:安全配置(故障保护) | PX4 自动驾驶用户指南 (v1.12)

雷迅教程:遥控器失控保护 · copter (cuav.net)

pix2.4.8教程:配件接线 · GitBook

阿木实验室 疑难杂症:pixhawk飞控使用及常见问题解决方法 持续更新-硬件产品-Amovlab阿木实验室-让机器人研发更高效! -

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

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

相关文章

milvus search api的数据结构

search api的数据结构 此api的功能是向量相似度搜索(vector similarity search) 一个完整的search例子: 服务端collection是一个hnsw类型的索引。 import random from pymilvus import (connections,Collection, )dim 128if __name__ __main__:connections.connect(alias…

springboot websocket 持续打印 pod 日志

springboot 整合 websocket 和 连接 k8s 集群的方式参考历史 Java 专栏文章 修改前端页面 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>Java后端WebSocket的Tomcat实现</title><script type"text/javasc…

A股企业数据要素利用水平数据集(2001-2022年)

参照史青春&#xff08;2023&#xff09;的做法&#xff0c;团队对上市公司-数据要素利用水平进行测算。统计人工智能技术、区块链技术、云计算技术、大数据技术、大数据技术应用五项指标在企业年报中的披露次数&#xff0c;求和后衡量数据要素投入水平。 一、数据介绍 数据名…

贪心算法|1005.K次取反后最大化的数组和

力扣题目链接 class Solution { static bool cmp(int a, int b) {return abs(a) > abs(b); } public:int largestSumAfterKNegations(vector<int>& A, int K) {sort(A.begin(), A.end(), cmp); // 第一步for (int i 0; i < A.size(); i) { // 第二步if…

力扣HOT100 - 56. 合并区间

解题思路&#xff1a; class Solution {public int[][] merge(int[][] intervals) {// 先按照区间起始位置排序Arrays.sort(intervals, (v1, v2) -> v1[0] - v2[0]);int[][] res new int[intervals.length][2];int idx -1;for (int[] interval : intervals) {//直接加入的…

PCF8591(ADDA转换芯片)

工具 1.Proteus 8 仿真器 2.keil 5 编辑器 原理图 讲解 PCF8591是一个单片集成、单独供电、低功耗、8-bit CMOS数据获取器件。PCF8591具有4个模拟输入、1个模拟输出和1个串行IC总线接口。PCF8591的3个地址引脚A0, A1和A2可用于硬件地址编程&#xff0c;允许在同个I2C总线上接…

【实战解析】YOLOv9全流程训练至优化终极指南

【实战解析】YOLOv9全流程训练至优化终极指南 0.引言1.环境准备2.数据预处理&#xff08;1&#xff09;数据准备&#xff08;2&#xff09;按比例划分数据集&#xff08;3&#xff09;xml转txt脚本&#xff08;4&#xff09;配置文件 3.模型训练&#xff08;1&#xff09;单GPU…

【UE5 C++】各个头文件的含义

#pragma once 预处理程序指令 作用&#xff1a;保护同一个文件不会被多次包含&#xff0c;使得头文件只会被编译一次&#xff0c; #include “CoreMinimal.h” 包含了一套来自UE4的核心编程环境的普遍存在类型 #include “GameFramework/GameModeBase.h” 基于GameModeBas…

如何训练自己的ChatGPT?需要多少训练数据?

近年&#xff0c;聊天机器人已经是很常见的AI技术。小度、siri、以及越来越广泛的机器人客服&#xff0c;都是聊天机器人的重要适用领域。然而今年&#xff0c;ChatGPT的面世让这一切都进行到一个全新的高度&#xff0c;也掀起了大语言模型&#xff08;LLM&#xff09;的热潮。…

SpringBoot和Vue2项目配置https协议

1、SpringBoot项目 ① 去你自己的云申请并下载好相关文件&#xff0c;SpringBoot下载的是Tomcat&#xff08;默认&#xff09;&#xff0c;Vue2下载的是Nginx ② 将下载的压缩包里面的.pfx后缀文件拷贝到项目的resources目录下 ③ 编辑配置文件 &#xff08;主要是框里面的内…

Java项目:基于SSM+vue框架实现的人力资源管理系统设计与实现(源码+数据库+毕业论文+任务书)

一、项目简介 本项目是一套基于SSM框架实现的人力资源管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、功能…

线程池的方式爬虫

<!--爬虫仅支持1.8版本的jdk--> <!-- 爬虫需要的依赖--> <dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.2</version> </dependency><!-- 爬虫需…

Spring学习(四)反射、AOP、JUnit

文章目录 Java反射回顾 AOP代理模式AOP概念及术语概述术语作用 基于注解的AOP步骤依赖配置文件切入点表达式语法切面类重用切入点表达式切面的优先级 基于XML的AOP 单元测试JUnit引入依赖JUnit5 Java反射 Spring框架的IoC基于java反射机制实现&#xff0c;反射是指在运行状态中…

antd+Vue 3实现table行内upload文件图片上传【超详细图解】

目录 一、背景 二、效果图 三、代码 一、背景 一名被组长逼着干前端的苦逼后端&#xff0c;在一个晴天霹雳的日子&#xff0c;被要求前端订单产品实现上传产品图片并立刻回显图片。 二、效果图 三、代码 <template><a-table :dataSource"dataSource" :c…

CTF之矛盾

这一题就是php的弱比较“” 这里要求输入的不是数字&#xff0c;并且输入要为1才打印flag 那我们就输入一个1后面接随便什么字符&#xff0c;因为php的弱比较将字符与数字进行比较的时候&#xff0c;会把字符转换成数字再比较&#xff0c;当转换到字符时后面便都为空了 flag{…

Android如何实现一个应用位于前台时全局页面每隔三分钟弹出一次一天最多弹出5次的GroMore半插屏广告,处于付费页和后台时停止

首先我们需要添加一个全局的Application public class MyApp extends LitePalApplication {private static final String TAG "MyApp";private static Context mContext;private boolean isManageMent;public static String oaid;Overridepublic void onCreate() {…

【opencv】示例-epipolar_lines.cpp 对极线

这段代码总的功能是使用OpenCV库进行立体视觉的估计。它从命令行读取两个图像文件名&#xff0c;使用SIFT算法检测关键点并计算这些点的描述子&#xff0c;接着通过FLANN库进行快速近似最近邻搜索来找到匹配的关键点。然后使用RANSAC方法计算基础矩阵&#xff0c;找到内点&…

Python中大的一把锁

今天可以来讲解下GIL是个什么了。 GIL为什么是Python中大的一把锁&#xff1f; GIL是Global Interpreter Lock的缩写&#xff0c;翻译过来就是全局解释器锁。 从字面上去理解&#xff0c;它就是锁在解释器头上的一把锁&#xff0c;它使Python代码运行变得有序。 假如有一段…

基于FPGA轻松玩转AI

启动人工智能应用从来没有像现在这样容易&#xff01;受益于像Xilinx Zynq UltraScale MPSoC 这样的FPGA&#xff0c;AI现在也可以离线使用或在边缘部署、使用.可用于开发和部署用于实时推理的机器学习应用&#xff0c;因此将AI集成到应用中变得轻而易举。图像检测或分类、模式…

关于hive启动的相关问题记录

问题&#xff1a;初始化hive元数据报错 [atguiguhadoop102 software]$ schematool -initSchema -dbType mysql -verboseError: Table CTLGS already exists (state42S01,code1050) Closing: 0: jdbc:mysql://hadoop102:3306/metastore?useSSLfalse org.apache.hadoop.hive.me…