Project AirSim简介(1):无人机避障算法解析

Project AirSim简介(1):无人机避障算法解析

目录

一、为什么选择 Project AirSim

二、无人机避障算法解析

2.1 初始化与连接

2.2 图像订阅与显示

2.3 起飞与准备工作

2.4 深度图避障逻辑核心

2.4.1 获取前置深度图

2.4.2 取图像上半部分

2.4.3 横向分割为五个区域

2.4.4 判断最近障碍与最开阔方向

2.4.5 悬停操作避免碰撞

2.4.6 动态调整航向(yaw)

2.4.7 以固定高度和速度前进

2.5 循环退出与资源释放

3 相关连接


一、为什么选择 Project AirSim

近年来,微软开源的AirSim 项目成为了无人机与自动驾驶研究中的重要仿真平台,但AirSim有个限制:同一仿真中无法同时使用车辆(Car)和无人机(Multirotor)。在 AirSim 中,我们需要通过修改 SimMode(SimMode=Multirotor 或 SimMode=Car)来切换模式,这意味着两种载具无法在一个世界中同时存在。

Project AirSim在原版 AirSim 的基础上进行了大量改进和重构,可以在同一场景中同时渲染无人机与地面车辆。(Issue #61 - Can ProjectAirSim support both cars and UAVs simulation?

二、无人机避障算法解析

项目中自带了多个示例脚本,其中一个典型案例是:

ProjectAirSim/client/python/airsimv1_scripts_migrated/multirotor/navigate.py

它展示了如何让无人机基于深度图(Depth Image)实现一个简单的前向避障算法。下面我将结合源代码来详细分析其执行逻辑。

2.1 初始化与连接

首先,脚本通过 ProjectAirSimClient() 连接到仿真服务器,并加载场景与无人机对象:

client = ProjectAirSimClient() client.connect() world = World(client, "scene_drone_classic.jsonc", delay_after_load_sec=2) drone = Drone(client, world, "Drone1")

其中,ProjectAirSimClient 模块负责与后端进行通信。World 会加载与 navigate.py 位于同一目录下的 sim_config 文件夹中的 scene_drone_classic.jsonc 配置文件。该配置文件中通过 "robot-config": "robot_quadrotor_classic.jsonc" 指定了机器人配置,从而进一步导入 robot_quadrotor_classic.jsonc 中的详细参数设置。

2.2 图像订阅与显示

前面,脚本使用ImageDisplay()创建显示窗口,并分别订阅追踪相机(ChaseCam)和前向深度相机(front_center depth)。

image_display = ImageDisplay() chase_cam_window = "ChaseCam" image_display.add_chase_cam(chase_cam_window) client.subscribe( drone.sensors["Chase"]["scene_camera"], lambda _, chase: image_display.receive(chase, chase_cam_window), ) depth_name = "Depth-Image" image_display.add_image(depth_name, subwin_idx=0) client.subscribe( drone.sensors["front_center"]["depth_planar_camera"], lambda _, depth: image_display.receive(depth, depth_name), )

这一步的目的是在本地实时显示仿真画面,便于调试。相机传感器(sensors)中第一个键(key)的获取,是根据前文提到的 robot_quadrotor_classic.jsonc 文件中的 id 进行匹配得到的。部分配置内容如下所示。

"sensors": [ { "id": "Chase", "type": "camera", "enabled": true, "parent-link": "Frame", "capture-interval": 0.03, "capture-settings": [

2.3 起飞与准备工作

image_display.start() drone.enable_api_control() drone.arm() await drone.takeoff_async()

无人机起飞后,将进入主循环。

2.4 深度图避障逻辑核心

主循环中,算法每一帧执行如下步骤:

2.4.1 获取前置深度图

result = drone.get_images("front_center", [ImageType.DEPTH_PLANAR]) depth_image = unpack_image(result[ImageType.DEPTH_PLANAR])

这里的 depth_image 是一个 NumPy 数组,表示视场内每个像素的深度信息。值越小表示越近。

2.4.2 取图像上半部分

top = np.vsplit(depth_image, 2)[0]

算法只分析上半部分(前方视野),忽略地面区域。

2.4.3 横向分割为五个区域

bands = np.hsplit(top, [50,100,150,200]) mins = [np.min(x) for x in bands]

将画面从左到右分为 5 个区域,并计算每个区域的最小深度值(代表最近的障碍距离)。

例如:索引 0 → 最左侧,索引 2 → 正前方,索引 4 → 最右侧。

2.4.4 判断最近障碍与最开阔方向

max = np.argmax(mins) distance = mins[max] current = mins[2]

mins[max] 最大的区域表示“最开阔的方向”; current 是当前正前方的障碍距离。

2.4.5 悬停操作避免碰撞

if (current < 20): await drone.hover_async() projectairsim_log().info("whoops - we are about to crash, so stopping!") input()

若正前方障碍过近(阈值为 20),无人机悬停并等待人工干预。

2.4.6 动态调整航向(yaw)

if (distance > current + 300): if (max == 0): change = -2*pi/10 elif (max == 1): change = -pi/10 elif (max == 2): change = 0 elif (max == 3): change = pi/10 else: change = 2*pi/10 yaw += change vx = math.cos(yaw) vy = math.sin(yaw)

算法把 90° 视场分为 5 段,每段约 18°。当检测到某侧更“开阔”时,无人机偏航一定角度(±18° 或 ±36°),并重新计算速度向量。

2.4.7 以固定高度和速度前进

await drone.move_by_velocity_z_async( vx, vy, -6, 1, YawControlMode.ForwardOnly, yaw=0, yaw_is_rate=False )

move_by_velocity_z_async 是 Project AirSim 提供的用于控制无人机飞行的 API 接口。该函数使无人机在 高度 z = -6(由于 Project AirSim 采用 NED 坐标系,即 North–East–Down)时,以指定的 水平速度 vx、vy 飞行 1 秒。飞行结束后,系统会重新采样图像,并进入下一次循环。

值得注意的是,YawControlMode.ForwardOnly (= 1)(在drone.py中定义) 表示偏航角(Yaw)被限制为与运动方向保持一致,即无人机的机头始终朝向其当前的运动方向。 这也解释了在 2.4.6 节中,vx 和 vy 是根据偏航角的正弦与余弦计算得到的原因。除此之外,在drone.py文件中还定义一个MaxDegreeOfFreedom = 0,表示偏航与速度向量相互独立,即可以让无人机头朝向和移动方向不一致。

2.5 循环退出与资源释放

按下 Esc / q / x 键退出,程序会停止显示并断开连接:

image_display.stop() client.disconnect()

三、相关连接

AirSim:https://github.com/microsoft/AirSim.git

Project AirSim:https://github.com/iamaisim/ProjectAirSim.git

本文仅为个人学习与理解笔记,水平有限,如有错误或理解偏差,欢迎评论区指正,轻喷。

希望这篇文章能帮到正在研究 Project AirSim 的同学!

Read more

掌控消息全链路(4)——RabbitMQ/Spring-AMQP高级特性详解之事务与消息分发

掌控消息全链路(4)——RabbitMQ/Spring-AMQP高级特性详解之事务与消息分发

🔥我的主页:九转苍翎⭐️个人专栏:《Java SE》《Java集合框架系统精讲》《MySQL高手之路:从基础到高阶》《计算机网络》《Java工程师核心能力体系构建》《RabbitMQ理论与实践》天行健,君子以自强不息。 1.事务 AMQP(高级消息队列协议)实现了事务机制,主要用于确保消息的原子性发布和确认。换言之,它允许你将多个操作(如发送消息、确认消息)绑定在一起,要么全部成功,要么全部失败 发送消息 @RestController@RequestMapping("/producer")publicclassProducerController{@Resource(name ="transRabbitTemplate")privateRabbitTemplate transRabbitTemplate;@Transactional@RequestMapping("/trans")publicStringtrans(){ transRabbitTemplate.convertAndSend(""

By Ne0inhk

Flutter 三方库 aws_cloudwatch 的鸿蒙化适配指南 - 让分布式鸿蒙应用的日志监控与分析入云实战

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 aws_cloudwatch 的鸿蒙化适配指南 - 让分布式鸿蒙应用的日志监控与分析入云实战 在鸿蒙(OpenHarmony)应用进入生产环境后,如何实时监控分布在各地的设备运行状态?传统的本地日志落盘已无法满足现代云原生监控的需求。aws_cloudwatch 做为一款轻量级、开箱即用的 AWS CloudWatch 日志上报方案,为鸿蒙开发者提供了分钟级的数据透传能力。本文将带你深度适配该组件,实现鸿蒙应用日志的一站式上报。 前言 什么是 CloudWatch?它是亚马逊提供的一套监控与日志管理服务。aws_cloudwatch 库封装了复杂的 AWS SignV4 签名和 LogStream 管理逻辑。在 Flutter for OpenHarmony 的场景下,我们不仅要处理好网络权限,更要解决鸿蒙设备在弱网环境下日志堆积与批量重发的工程难题,确保每一个关键 Error 都能在云端看板实时呈现。 一、

By Ne0inhk
【沧海拾昧】绿联NAS配置WebDAV公网访问并使用RaiDrive挂载到本地

【沧海拾昧】绿联NAS配置WebDAV公网访问并使用RaiDrive挂载到本地

#C0601 沧海茫茫千钟粟,且拾吾昧一微尘 ——《沧海拾昧集》@CuPhoenix 【阅前敬告】沧海拾昧集仅做个人学习笔记之用,所述内容不专业不严谨不成体系【如有问题必是本集记录有谬,切勿深究】 目录 * 前言 * 一、配置步骤 * 1、确认网络设备支持 IPv6 * 2、购买域名 * 3、配置访问凭证 * 2、NAS 配置 WebDAV 服务 * 3、NAS 配置 DDNS 支持 * 4、配置反向代理 * 5、在 RaiDrive 中挂载 * 6、设置防火墙 * 二、最终结果 前言 将 NAS 的磁盘空间通过 RaiDrive 等软件挂载到本地使用是一种十分便捷的方法,但是 RaiDrive 中只有针对群晖(

By Ne0inhk
卷积神经网络(CNN)进阶:经典架构解析与实战开发

卷积神经网络(CNN)进阶:经典架构解析与实战开发

卷积神经网络(CNN)进阶:经典架构解析与实战开发 💡 学习目标:掌握CNN的经典进阶架构设计思路,理解不同架构的核心创新点,能够基于经典架构开发定制化图像任务模型。 💡 学习重点:LeNet-5、AlexNet、VGGNet、ResNet的核心结构与改进逻辑,基于PyTorch实现ResNet-50并完成图像分类任务。 49.1 卷积神经网络进阶的核心驱动力 卷积神经网络从最初的简单结构发展到深度模型,核心驱动力是解决深层网络的性能瓶颈和提升特征提取的效率与精度。 在早期CNN的应用中,研究人员发现两个关键问题: 1. 网络深度增加到一定程度后,会出现梯度消失或梯度爆炸问题,导致模型无法收敛。 2. 简单堆叠卷积层的方式,会造成特征冗余和计算资源浪费,模型泛化能力受限。 ⚠️ 注意:CNN的进阶过程不是单纯的“堆层数”,而是通过结构创新、参数优化和训练技巧的结合,实现性能的突破。 ✅ 结论:经典CNN架构的每一次升级,都针对当时的技术痛点提出了创新性解决方案,掌握这些方案的设计思路,比记住网络结构更重要。 49.2 经典CNN架构深度解析 49.2.1

By Ne0inhk