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

news2024/11/20 0:48:50

这几天看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,对于连接到本地地面站的无人机,通常为1
    vehicle._master.target_component:MAVLink消息的目标组件ID,向无人机的某个特定组件发送命令。通常为0
    mavutil.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 the
    specified `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 to
    the 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设置为True
    home_position_set = True
#--------------------------------------------------------


#--------------------------------------------------------
# Start mission example
# wait for a home position lock 等待home位置锁定
while not home_position_set:
    #持续循环检查home_position_set是否为True
    print ("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.next
    time.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.coloradmin.cn/o/1594037.html

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

相关文章

【日常记录】【CSS】SASS循环的使用

文章目录 1、引言2、安装3、举例4、参考链接 1、引言 目前在任何项目框架中&#xff0c;都会有css 预处理器&#xff0c;目前一般使用 sass、less 这俩其中之一&#xff0c;它可以简化css的书写 Sass 是一款强化 CSS 的辅助工具&#xff0c;它在 CSS 语法的基础上增加了变量 (v…

内网渗透-Earthworm的简单使用(内网穿透工具)

Earthworm的简单介绍&#xff08;一&#xff09; 文章目录 EarthWorm下载地址1. 普通网络 1.1 跳板机存在公网IP 1.1.1 网络环境1.1.2 使用方法1.1.3 流量走向 1.2 跳板机不存在公网IP&#xff0c;可出网 1.2.1 网络环境1.2.2 使用方法1.2.3 流量走向 2. 二级网络 2.1 一级跳…

【随笔】Git 基础篇 -- 远程仓库 git clone(二十五)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

刷题之Leetcode707题(超级详细)

707.设计链表 力扣题目链接(opens new window)https://leetcode.cn/problems/design-linked-list/ 题意&#xff1a; 在链表类中实现这些功能&#xff1a; get(index)&#xff1a;获取链表中第 index 个节点的值。如果索引无效&#xff0c;则返回-1。addAtHead(val)&#x…

【数据库】加 Redis 就无懈可击? —— 缓存雪崩、击穿、穿透的破解之道

一般来说&#xff0c;目前的系统设计上为了缓解数据库峰值压力&#xff0c;都会增加 Redis 作为第一道屏障&#xff0c;但是其依然存在一些不足。总结起来是三大问题&#xff0c;分别是缓存雪崩、缓存击穿和缓存穿透。本文旨在说清楚三个问题的原因及相应的防范策略。 以 Redis…

计算机基础知识-第9章-存储的本质(2)——硬盘和文件系统基础知识

一、机械硬盘的原理 概括来说&#xff0c;硬盘的工作原理是利用特定的磁粒子的极性来记录数据。磁头在读取数据时&#xff0c;将磁力子的不同极性转换成不同的电脉冲信号&#xff0c;再利用数据转换器将这些原始信号变成电脑可以使用的数据&#xff0c;写的操作正好与此相反。…

react 初学增删改查购物车案例

界面 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>react-购物车案例</title><…

gpt在线网页版最全收录

ChatGPT镜像 今天在知乎看到一个问题&#xff1a;“平民不参与内测的话没有账号还有机会使用ChatGPT吗&#xff1f;” 从去年GPT大火到现在&#xff0c;关于GPT的消息铺天盖地&#xff0c;真要有心想要去用&#xff0c;途径很多&#xff0c;别的不说&#xff0c;国内GPT的镜像…

我的新书,在西西弗书店上架了!

大家好&#xff0c;我是程序员小灰。今天告诉大家一个好消息&#xff0c;我的新书在西西弗书店上架了&#xff01; 熟悉小灰的朋友都知道&#xff0c;我以前是京东的一名程序员&#xff0c;现在全职投入到IT领域的自媒体创作。在2019年&#xff0c;我出版了人生中的第一本书《漫…

eclipse 取消生成注释 TODO Auto-generated method stub

eclipse 取消生成注释 // TODO Auto-generated method stub 基本步骤 windows -> preferencesJava -> Code Style -> Code TemplatesCode -> Method body -> 编辑删除 // ${todo} Auto-generated method stub参考材料 Eclipse 中取消生成 TODO Auto-generated…

Unity类银河恶魔城学习记录12-14 p136 Merge Skill Tree with Sword skill源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili CharacterStats.cs using System.Collections; using System.Collections.…

RTC的基本概念以及相关例程

实时时钟(RTC) 北京时间跟伦敦时间错8个小时 BKP简介 BKP本质上是RAM存储器&#xff0c;没有掉电不丢失的能力。 VBAT的作用就是&#xff0c;当VDD断电时&#xff0c;BKP会切换到VBAT供电&#xff0c;这样可以继续维持BKP里面的数据&#xff0c;如果VDD断电&#xff0c;VBAT也…

《猎灵online》游戏完整源码(源码+客户端+服务端+文档+工具),云盘下载

《猎灵》是一款由国内知名开发运营开发的大型3D魔幻网游&#xff0c;《猎灵》研发团队突破诸多瓶颈&#xff0c;首创“全自由无限制PK”&#xff0c;让玩家拒绝无意义等待&#xff0c;自由作战不受任何束缚&#xff0c;真正的实现想战就战&#xff0c;游戏创建了六界神魔乱斗的…

蓝桥杯嵌入式模板(cubemxkeil5)

LED 引脚PC8~PC15&#xff0c;默认高电平&#xff08;灭&#xff09;。 此外还要配置PD2为输出引脚&#xff08;控制LED锁存&#xff09; &#xff0c;默认低电平&#xff08;锁住&#xff09;&#xff01;&#xff01;&#xff01; #include "led.h"void led_disp…

五子棋:不会下五子棋也没关系,会用Java写五子棋就行

关注公号“微澜网络”获取完整源代码&#xff01; 效果展示&#xff1a; 目录 效果展示&#xff1a; 导语&#xff1a; 游戏介绍&#xff1a; 程序设计&#xff1a; 1.游戏规则和功能&#xff1a; 2.用户界面设计&#xff1a; 3.程序架构设计&#xff1a; 4.可扩展性和灵…

【IC验证】fork...join

1.fork...join 各线程并行执行&#xff0c;当耗时最长的线程执行完后&#xff0c;跳出该语句块。如果任何一个子线程无法结束&#xff0c;则整个fork...join将被挂起 2.fork...join_any 如果任何一个子线程完成&#xff0c;则程序允许执行fork...join_any块外面接下来的语句…

SVN的介绍

首先SVN是什么&#xff1a; Apache下的一个开源的项目Subversion&#xff0c;通常缩写为 SVN&#xff0c;是一个版本控制系统。 版本控制系统是一个软件&#xff0c;它可以伴随我们软件开发人员一起工作&#xff0c;让我们编写代码的完整的历史保存下来。 目前它的各个版本的…

华为ensp中aaa(3a)实现telnet远程连接认证配置命令

作者主页&#xff1a;点击&#xff01; ENSP专栏&#xff1a;点击&#xff01; 创作时间&#xff1a;2024年4月14日18点49分 AAA认证的全称是Authentication、Authorization、Accounting&#xff0c;中文意思是认证、授权、计费。 以下是详细解释 认证&#xff08;Authentic…

Kylin-Server-V10-SP3-General-Release-2303-X86_64

Kylin-Server-V10-SP3-General-Release-2303-X86_64 银河麒麟V10 银河蓝色麒麟比红麒麟养眼多了 Kylin-CSDN博客 Kylin IPv4 setting-CSDN博客

安全加速SCDN带的态势感知能为网站安全带来哪些帮助

随着安全加速SCDN被越来越多的用户使用&#xff0c;很多用户都不知道安全加速SCDN的态势感知是用于做什么的&#xff0c;德迅云安全今天就带大家来了解下什么是态势感知&#xff0c;态势感知顾名思义就是对未发生的事件进行预知&#xff0c;并提前进行防范措施的布置&#xff0…