当前位置: 首页 > article >正文

别再只玩单机了!用AirSim+Python实现你的第一个无人机编队(附完整代码)

从单机到编队用AirSim和Python打造你的第一支无人机小队想象一下当你第一次在AirSim中成功让无人机起飞时的兴奋感——现在是时候将这份快乐乘以N倍了。本文将带你跨越单机操作的舒适区进入无人机编队控制的新世界。不需要复杂的数学公式也不用担心理论门槛过高我们会用最直观的方式从环境配置到代码实现一步步构建一个能够互相跟随的无人机小队。1. 环境准备搭建你的虚拟飞行实验室在开始编写代码之前我们需要确保开发环境已经准备就绪。与单机操作不同多无人机仿真需要一些额外的配置步骤。首先确保你已经安装了最新版本的AirSim。如果尚未安装可以通过以下命令获取pip install airsim接下来我们需要修改AirSim的设置文件以支持多无人机仿真。找到你的AirSim设置文件通常位于Documents/AirSim/settings.json添加以下配置{ SettingsVersion: 1.2, SimMode: Multirotor, Vehicles: { Drone1: { VehicleType: SimpleFlight, X: 0, Y: 0, Z: 0 }, Drone2: { VehicleType: SimpleFlight, X: 3, Y: 0, Z: 0 }, Drone3: { VehicleType: SimpleFlight, X: 0, Y: 3, Z: 0 } } }这个配置创建了三架无人机初始位置分别在(0,0,0)、(3,0,0)和(0,3,0)。你可以根据需要增加或减少无人机数量只需按照相同格式添加新的DroneX条目即可。提示在修改settings.json文件后需要重启AirSim才能生效。如果遇到任何问题可以尝试删除Documents/AirSim文件夹下的所有文件然后重新启动AirSim生成默认配置。2. 多机控制基础同时指挥多架无人机在单机操作中我们通常直接使用client对象来控制无人机。但在多机环境下我们需要为每架无人机创建独立的客户端连接。import airsim import time # 连接到AirSim client airsim.MultirotorClient() client.confirmConnection() # 获取所有无人机名称 drone_names list(client.listVehicles().values()) # 为每架无人机单独初始化 for name in drone_names: client.enableApiControl(True, name) client.armDisarm(True, name)这段代码首先建立与AirSim的连接然后获取场景中所有无人机的名称列表。接着我们遍历这个列表为每架无人机单独启用API控制并解锁电机。让所有无人机同时起飞也很简单# 让所有无人机同时起飞到2米高度 for name in drone_names: client.takeoffAsync(vehicle_namename).join() client.moveToZAsync(-2, 1, vehicle_namename).join()这里我们使用了Async方法配合join()确保每架无人机都完成当前动作后再执行下一个命令。moveToZAsync让无人机上升到2米高度注意AirSim中Z轴向下为正所以高度为负值速度为1米/秒。3. 实现基础跟随行为让无人机保持队形现在让我们实现一个简单的跟随行为——让一架无人机跟随另一架无人机保持一定距离。这是编队控制中最基础的行为模式。我们将使用基于距离的简单算法当跟随者与领航者的距离大于设定值时跟随者向领航者移动当距离过近时跟随者则远离。def simple_follow(leader, follower, follow_distance3, speed1): 实现简单的跟随行为 :param leader: 领航无人机名称 :param follower: 跟随无人机名称 :param follow_distance: 期望保持的距离(米) :param speed: 移动速度(米/秒) # 获取两架无人机的位置 leader_pos client.simGetVehiclePose(leader).position follower_pos client.simGetVehiclePose(follower).position # 计算两者之间的距离向量 delta_x leader_pos.x_val - follower_pos.x_val delta_y leader_pos.y_val - follower_pos.y_val delta_z leader_pos.z_val - follower_pos.z_val distance (delta_x**2 delta_y**2 delta_z**2)**0.5 # 如果距离大于期望值跟随者向领航者移动 if distance follow_distance * 1.2: # 加入20%的缓冲区域 target_x follower_pos.x_val delta_x * 0.1 target_y follower_pos.y_val delta_y * 0.1 client.moveToPositionAsync(target_x, target_y, leader_pos.z_val, speed, vehicle_namefollower) # 如果距离过近跟随者远离领航者 elif distance follow_distance * 0.8: target_x follower_pos.x_val - delta_x * 0.1 target_y follower_pos.y_val - delta_y * 0.1 client.moveToPositionAsync(target_x, target_y, leader_pos.z_val, speed, vehicle_namefollower)这个简单的跟随算法已经能够实现基本的编队保持功能。你可以通过调整follow_distance参数来控制无人机之间的间距通过speed参数调整跟随的速度。4. 进阶实现基于势场的编队控制虽然上面的简单跟随算法能够工作但在实际应用中我们通常需要更复杂的控制策略。让我们实现一个基于虚拟势场的编队控制算法它能够同时处理三种基本行为分离避免无人机之间碰撞聚合保持无人机编队不分散导航引导编队向目标点移动def potential_field_controller(drone_name, neighbors, target_pos, k_sep1.0, k_coh0.3, k_mig0.5, max_speed3, safe_distance2): 基于势场的编队控制器 :param drone_name: 当前控制的无人机名称 :param neighbors: 邻居无人机列表(名称) :param target_pos: 目标位置(Vector3r) :param k_sep: 分离力系数 :param k_coh: 聚合力系数 :param k_mig: 导航力系数 :param max_speed: 最大速度 :param safe_distance: 安全距离(避免碰撞) # 获取当前无人机位置 current_pos client.simGetVehiclePose(drone_name).position # 初始化速度向量 v_sep airsim.Vector3r(0, 0, 0) # 分离速度 v_coh airsim.Vector3r(0, 0, 0) # 聚合速度 v_mig airsim.Vector3r(0, 0, 0) # 导航速度 # 计算分离速度(避免碰撞) for neighbor in neighbors: neighbor_pos client.simGetVehiclePose(neighbor).position delta airsim.Vector3r(current_pos.x_val - neighbor_pos.x_val, current_pos.y_val - neighbor_pos.y_val, current_pos.z_val - neighbor_pos.z_val) distance (delta.x_val**2 delta.y_val**2 delta.z_val**2)**0.5 if distance safe_distance: # 距离越近排斥力越大 strength min(k_sep / (distance**2 0.1), max_speed) v_sep.x_val delta.x_val * strength v_sep.y_val delta.y_val * strength v_sep.z_val delta.z_val * strength # 计算聚合速度(保持编队) if neighbors: center airsim.Vector3r(0, 0, 0) for neighbor in neighbors: neighbor_pos client.simGetVehiclePose(neighbor).position center.x_val neighbor_pos.x_val center.y_val neighbor_pos.y_val center.z_val neighbor_pos.z_val center.x_val / len(neighbors) center.y_val / len(neighbors) center.z_val / len(neighbors) delta airsim.Vector3r(center.x_val - current_pos.x_val, center.y_val - current_pos.y_val, center.z_val - current_pos.z_val) distance (delta.x_val**2 delta.y_val**2 delta.z_val**2)**0.5 if distance 0: strength min(k_coh * distance, max_speed) v_coh.x_val delta.x_val * strength / distance v_coh.y_val delta.y_val * strength / distance v_coh.z_val delta.z_val * strength / distance # 计算导航速度(向目标移动) delta airsim.Vector3r(target_pos.x_val - current_pos.x_val, target_pos.y_val - current_pos.y_val, target_pos.z_val - current_pos.z_val) distance (delta.x_val**2 delta.y_val**2 delta.z_val**2)**0.5 if distance 0: strength min(k_mig * distance, max_speed) v_mig.x_val delta.x_val * strength / distance v_mig.y_val delta.y_val * strength / distance v_mig.z_val delta.z_val * strength / distance # 合并所有速度分量 v_total airsim.Vector3r( v_sep.x_val v_coh.x_val v_mig.x_val, v_sep.y_val v_coh.y_val v_mig.y_val, v_sep.z_val v_coh.z_val v_mig.z_val ) # 限制最大速度 speed (v_total.x_val**2 v_total.y_val**2 v_total.z_val**2)**0.5 if speed max_speed: v_total.x_val v_total.x_val * max_speed / speed v_total.y_val v_total.y_val * max_speed / speed v_total.z_val v_total.z_val * max_speed / speed # 应用速度控制 client.moveByVelocityAsync( v_total.x_val, v_total.y_val, v_total.z_val, 0.1, vehicle_namedrone_name )这个控制器实现了完整的势场算法你可以通过调整三个系数(k_sep、k_coh、k_mig)来改变编队的行为特征参数作用典型值范围效果k_sep分离力系数0.5-2.0值越大无人机之间保持的距离越大k_coh聚合力系数0.1-0.5值越大编队保持得越紧密k_mig导航力系数0.3-1.0值越大向目标移动的速度越快5. 完整示例三无人机三角形编队飞行现在我们将前面所有的代码片段组合起来创建一个完整的示例实现三架无人机以三角形编队飞向目标点的功能。import airsim import time import math # 连接到AirSim client airsim.MultirotorClient() client.confirmConnection() # 获取所有无人机名称 drone_names sorted(list(client.listVehicles().values())) leader drone_names[0] # 选择第一架作为领航无人机 # 初始化所有无人机 for name in drone_names: client.enableApiControl(True, name) client.armDisarm(True, name) # 同时起飞 for name in drone_names: client.takeoffAsync(vehicle_namename).join() # 上升到5米高度 for name in drone_names: client.moveToZAsync(-5, 1, vehicle_namename).join() # 设置目标点(距离起点50米) target_pos airsim.Vector3r(50, 0, -5) # 主控制循环 try: while True: # 对于领航无人机直接向目标点移动 leader_pos client.simGetVehiclePose(leader).position delta airsim.Vector3r(target_pos.x_val - leader_pos.x_val, target_pos.y_val - leader_pos.y_val, target_pos.z_val - leader_pos.z_val) distance (delta.x_val**2 delta.y_val**2 delta.z_val**2)**0.5 if distance 1.0: # 到达目标点 break # 领航无人机以1m/s速度向目标移动 if distance 0: client.moveByVelocityAsync( delta.x_val * 1.0 / distance, delta.y_val * 1.0 / distance, delta.z_val * 1.0 / distance, 0.1, vehicle_nameleader ) # 对于跟随无人机使用势场控制器保持编队 for i in range(1, len(drone_names)): # 计算期望的相对位置(三角形编队) angle 2 * math.pi * (i-1) / (len(drone_names)-1) desired_offset airsim.Vector3r( 3 * math.cos(angle), # 3米半径 3 * math.sin(angle), 0 ) # 计算期望的绝对位置 desired_pos airsim.Vector3r( leader_pos.x_val desired_offset.x_val, leader_pos.y_val desired_offset.y_val, leader_pos.z_val desired_offset.z_val ) # 使用势场控制器 potential_field_controller( drone_names[i], [n for n in drone_names if n ! drone_names[i]], desired_pos, k_sep1.2, k_coh0.4, k_mig0.6 ) time.sleep(0.1) except KeyboardInterrupt: pass # 降落所有无人机 for name in drone_names: client.landAsync(vehicle_namename).join() # 断开连接 for name in drone_names: client.enableApiControl(False, name)这个完整示例展示了如何协调多架无人机的飞行形成稳定的编队。领航无人机负责带领整个编队向目标点移动而跟随无人机则自动调整位置保持与领航无人机的相对位置关系同时避免与其他无人机碰撞。在实际测试中我发现当k_sep和k_coh参数的比例约为3:1时编队能够保持较好的稳定性。如果跟随无人机出现振荡现象可以尝试降低k_mig值或增加控制循环的频率。

相关文章:

别再只玩单机了!用AirSim+Python实现你的第一个无人机编队(附完整代码)

从单机到编队:用AirSim和Python打造你的第一支无人机小队 想象一下,当你第一次在AirSim中成功让无人机起飞时的兴奋感——现在,是时候将这份快乐乘以N倍了。本文将带你跨越单机操作的舒适区,进入无人机编队控制的新世界。不需要复…...

千问3.5-2B轻量化部署教程:边缘设备适配可能性分析与CPU回退方案说明

千问3.5-2B轻量化部署教程:边缘设备适配可能性分析与CPU回退方案说明 1. 模型简介 千问3.5-2B是Qwen系列中的小型视觉语言模型,专为边缘计算场景优化设计。这个2B参数量的版本在保持视觉理解能力的同时,大幅降低了硬件需求。 模型核心能力…...

基于比迪丽模型的Transformer架构优化:提升图像生成质量

基于比迪丽模型的Transformer架构优化:提升图像生成质量 在图像生成领域,比迪丽模型凭借其出色的生成效果和稳定性赢得了广泛关注。但很多用户可能不知道,通过合理的Transformer架构优化,这个模型的图像生成质量还能再上一个台阶…...

避开这些坑!Mapbox图层管理实战:动态加载GeoJSON数据的正确姿势

Mapbox高级图层管理实战:GeoJSON动态加载与性能优化全解析 当处理省级以上GIS数据可视化时,Mapbox的图层管理能力直接决定了应用的流畅度和用户体验。许多开发者在使用GeoJSON数据源时,常遇到内存泄漏、渲染卡顿、交互延迟等问题。本文将深入…...

ftools架构深度解析:Stata大数据处理的技术革命

ftools架构深度解析:Stata大数据处理的技术革命 【免费下载链接】ftools Fast Stata commands for large datasets 项目地址: https://gitcode.com/gh_mirrors/ft/ftools 在数据科学和经济学研究的实践中,Stata用户经常面临一个共同的挑战&#x…...

终极指南:如何使用Python实现同花顺自动化程序交易

终极指南:如何使用Python实现同花顺自动化程序交易 【免费下载链接】jqktrader 同花顺自动程序化交易 项目地址: https://gitcode.com/gh_mirrors/jq/jqktrader 在量化投资领域,自动化交易已成为专业投资者的标准配置。本文将详细介绍如何利用jqk…...

新手入门福音:用快马AI生成你的第一个Python版游戏账号管理工具

作为一个刚接触Python编程的新手,最近想尝试开发一个简单的游戏账号管理工具。这个需求其实挺常见的,比如我平时玩多个游戏,账号密码经常记混,如果能有个小工具统一管理就方便多了。在朋友的推荐下,我尝试用InsCode(快…...

Qt5.14.2与VS2019整合开发避坑指南(从安装到第一个GUI项目)

Qt5.14.2与VS2019整合开发避坑指南(从安装到第一个GUI项目) 在Windows平台进行Qt开发时,Visual Studio作为强大的IDE环境,与Qt框架的结合能够显著提升开发效率。本文将深入剖析Qt5.14.2与VS2019整合过程中的关键环节,从…...

从MATLAB/Python代码实现反推Newmark-β法:理解线性加速度假设如何变成迭代算法

从代码实现反推Newmark-β法:线性加速度假设的工程实践指南 在结构动力学分析中,地震响应、风荷载等时程分析问题常需要求解二阶微分方程。Newmark-β法作为经典数值解法,通过线性加速度假设将连续问题离散化。但教科书往往止步于公式推导&am…...

别再混淆了!一文讲透NvDecoder里ulNumDecodeSurfaces和ulNumOutputSurfaces到底怎么用

深入解析NvDecoder:解码缓存与输出缓存的本质区别与实战配置 在视频处理领域,NVIDIA的硬件解码器(NVDEC)因其出色的性能和高效的资源利用率而广受开发者青睐。然而,对于许多中高级开发者来说,NvDecoder中ul…...

保姆级教程:在PVE 8.3上搞定Windows 11和Server 2025的VirtIO驱动安装与优化

PVE 8.3虚拟化环境下的Windows系统性能优化全攻略 在虚拟化技术日益普及的今天,Proxmox VE(PVE)作为开源的虚拟化平台,因其稳定性和灵活性受到众多技术爱好者和企业用户的青睐。然而,许多用户在PVE上部署Windows系统时…...

WarcraftHelper:魔兽争霸III现代化增强工具全面指南

WarcraftHelper:魔兽争霸III现代化增强工具全面指南 【免费下载链接】WarcraftHelper Warcraft III Helper , support 1.20e, 1.24e, 1.26a, 1.27a, 1.27b 项目地址: https://gitcode.com/gh_mirrors/wa/WarcraftHelper 如何让经典游戏适配现代硬件环境&…...

Laya3D美术进阶:巧用Shader实现APP级游戏效果还原

1. 为什么选择Laya3D的Shader技术? 很多开发者第一次接触Laya3D时,都会有个疑问:为什么不用Unity直接开发?特别是在微信小游戏这个特定场景下,Laya3D的Shader技术到底能带来什么优势?我做了三年Laya小游戏…...

【测试之道】第四篇:分层测试论 —— 金字塔、奖杯与蜂巢:构建你的质量防御阵型

专栏进度:04 / 10 (测试理论专题) 在不同的架构(单体、微服务、前端驱动)下,测试资源的分配比例是完全不同的。盲目套用模板是测试经理最容易犯的错误。 一、 经典模型:测试金字塔 (Testing Pyramid) 由 Mike Cohn 提出…...

OpenMP实战避坑:你的C++并行程序为什么跑得比单线程还慢?

OpenMP实战避坑:你的C并行程序为什么跑得比单线程还慢? 第一次在C代码里加上#pragma omp parallel for时,那种期待性能飙升的心情,相信每个开发者都经历过。但现实往往很骨感——程序运行速度不升反降,甚至出现莫名其妙…...

Win10+VS2019环境下vcpkg安装全攻略:从Git克隆到环境变量配置

Win10VS2019环境下vcpkg高效配置指南:从零搭建C开发环境 在Windows平台进行C开发时,第三方库的管理一直是令人头疼的问题。传统的手动下载、配置包含路径和链接库的方式不仅效率低下,还容易引发版本冲突。而vcpkg作为微软推出的跨平台C库管理…...

企业微信考勤自动化解决方案:基于EasyWeChat的实战指南

企业微信考勤自动化解决方案:基于EasyWeChat的实战指南 【免费下载链接】easywechat 📦 一个 PHP 微信 SDK 项目地址: https://gitcode.com/gh_mirrors/ea/easywechat 在数字化办公普及的今天,企业考勤管理面临着数据采集繁琐、统计分…...

保姆级教程:用STM32的定时器输入捕获功能,手把手教你解码任意红外遥控器

STM32定时器输入捕获实战:从零解码未知协议红外遥控信号 红外遥控技术在家电控制领域已有数十年历史,但面对市面上五花八门的遥控协议,开发者常常陷入协议适配的泥潭。本文将带你突破协议限制,利用STM32的定时器输入捕获功能&…...

pg_textsearch:革新Postgres文本搜索的现代工具

【导语:GitHub上的pg_textsearch是一款适用于Postgres的现代排名文本搜索工具,具备简单语法、可配置参数等特性,目前已达v1.0.0版本可用于生产环境,对Postgres文本搜索领域带来新变革。】pg_textsearch:Postgres文本搜…...

从原理到代码:用Python实现简易变焦跟踪算法(OpenCV实战)

从原理到代码:用Python实现简易变焦跟踪算法(OpenCV实战) 在计算机视觉领域,变焦跟踪是一个既基础又关键的技术难题。想象一下,当你用手机拍摄远处景物时,镜头从广角切换到长焦的过程中,画面往往…...

OpenHarmony基线移植实战:从开源仓到定制仓的完整路径

1. 为什么需要移植OpenHarmony基线? 第一次接触OpenHarmony基线移植时,我也很困惑:为什么不能直接用官方开源代码?非要折腾这一套移植流程?直到在实际项目中踩了几个坑才明白,基线移植是产品开发的必经之路…...

Pixel Dream Workshop 快速上手:Python 零基础入门到生成第一幅AI画作

Pixel Dream Workshop 快速上手:Python 零基础入门到生成第一幅AI画作 1. 前言:为什么选择Pixel Dream Workshop 如果你对AI绘画感兴趣但苦于没有编程基础,这篇教程就是为你量身定制的。Pixel Dream Workshop是一个对新手极其友好的AI绘画工…...

细致配置Doctrine,专注于指定前缀表的迁移

在使用Symfony和Doctrine进行项目开发时,如何优雅地处理数据库迁移是一个常见的问题。本文将详细探讨如何配置Doctrine,使其在生成迁移文件时仅关注特定前缀的表(如pp_前缀的表),从而避免迁移文件中包含不必要的表。 背景介绍 假设你有一个Symfony项目,该项目中数据库已…...

菊水PBZ40电源协议详解:从‘*IDN?’到波形设置,一份给硬件测试新人的避坑指南

菊水PBZ40电源协议实战手册:从基础指令到复杂波形配置的工程指南 第一次接触菊水PBZ40可编程电源时,面对满屏的协议指令和参数配置,不少硬件测试工程师都会感到无从下手。这台看似简单的设备,实际上隐藏着许多需要特别注意的细节…...

VisionPro —— CogImageFileTool图像文件管理实战解析

1. CogImageFileTool核心功能解析 第一次接触CogImageFileTool时,我完全被它强大的图像管理能力震撼到了。这个工具就像工业视觉领域的"智能文件管家",专门处理图像文件的读写和存储问题。想象一下,你每天要处理上千张生产线上的产…...

从NTLM中继到域控接管:ADCS-ESC8漏洞实战解析

1. ADCS-ESC8漏洞概述 ADCS-ESC8是Active Directory证书服务(AD CS)中的一个高危漏洞,它允许攻击者通过NTLM中继攻击获取域控制器证书。这个漏洞的核心在于ADCS默认配置中的Web证书注册页面仅使用HTTP协议且支持NTLM认证,但未启用任何中继攻击防护措施。…...

DevOps实践:如何让开发、测试、运维不再“打架”?

质量不再是孤岛在追求快速迭代的现代软件开发中,开发、测试与运维团队之间的隔阂与摩擦,常常被戏称为“部门战争”。开发团队渴望快速交付新功能,测试团队需要足够的时间来保障质量,而运维团队则首要追求系统的稳定与可靠。当发布…...

PyTorch导入报错?手把手教你解决WinError 126找不到fbgemm.dll的问题(附libomp140.dll下载)

PyTorch导入报错终极解决方案:WinError 126缺失fbgemm.dll的深度修复指南 当你满怀期待地准备开始PyTorch深度学习项目时,突然遭遇"OSError: [WinError 126] 找不到指定的模块"错误,这感觉就像赛车手在起跑线上发现引擎无法启动。这…...

ESP8266天气时钟DIY全攻略:从零搭建到个性化定制

1. 硬件准备与成本控制 作为一个玩了多年智能硬件的爱好者,我强烈推荐从ESP8266开始入门物联网项目。这款芯片的价格实在太香了,9块钱就能买到NodeMCU开发板,性能却足够应付大多数DIY场景。我去年做过统计,用ESP8266搭建的天气时钟…...

APDS9960手势传感器驱动开发与嵌入式实战

1. APDS9960手势传感器库技术解析与嵌入式工程实践APDS9960是一款由Broadcom(原Avago)推出的集成环境光、颜色、接近度及手势识别功能的多模态光学传感器芯片。其核心价值在于将传统分立式光感方案(如独立ALSProximityGesture模块&#xff09…...