禁飞区检测模块

功能说明

本模块为无人机配送场景提供禁飞区安全校验功能。用户输入取货点和送货点的经纬度坐标,模块判断这两点以及整条航线是否进入预设的禁飞区范围。

应用场景

在无人机执行配送任务前,需要确认航线起止点不会进入敏感区域(如机场、军事基地、学校上空)。本模块提供了一种基于球面距离与点到线段距离的快速检测方法。

算法原理

使用 Haversine 公式 计算两个经纬度坐标之间的球面距离,公式如下:

其中:

  • φ₁、φ₂ 为两点的纬度(弧度)
  • Δφ、Δλ 为两点纬度和经度的差值
  • R 为地球平均半径,取值 6371000 米
  • d 为最终距离(米)

航线穿越检测(新增)

旧版本只判断取货点/送货点是否落在禁飞区内。当两个端点都在禁区外、但航线从禁区中间穿过时(例如直线配送、绕行失败),会出现「端点安全、航线不安全」的漏判。本版本新增整条航线的检测:

  1. 以禁飞区中心为原点做局部等距投影(米),把经纬度变成平面坐标:

  1. 把航线变成线段 ,求禁区中心到线段的点到线段最短距离:

  1. 若 判定为穿越。

判定优先级:端点在内(pickup_inside / delivery_inside)优先于航线穿越(path_crosses),同一个禁区只记一条违规。禁飞区半径通常只有几百米到几公里,局部等距近似的误差远小于判定裕度,而且不会像「逐点采样」那样漏掉细长的穿越。

输出示例

$ python main.py --pickup 47.65,-122.17 --dropoff 47.65,-122.11
==================================================
航线禁飞区检测
==================================================
取货点: (47.65000, -122.17000)
送货点: (47.65000, -122.11000)
检查禁飞区数量: 3
--------------------------------------------------
[WARNING] 航线穿越禁飞区【Airport】:距离中心 0.0 m(半径 2000 m)

两个端点离 Airport 中心都约 2.2 km(在 2 km 半径之外),但航线正好从中心穿过——这正是旧版本「只查端点」会漏掉的情况。

使用方法

单点检测 + 内置示例(纯 Python,无需 AirSim / ROS):

cd src/no_fly_zone_check
python main.py

航线穿越检测:

python main.py --pickup 47.65,-122.17 --dropoff 47.65,-122.11
python main.py --pickup 47.65,-122.17 --dropoff 47.65,-122.11 --json

退出码:0 = 安全,1 = 存在违规;--json 输出机器可读结果(safe / zones_checked / violations)。

AirSim 版本(src/air/no_fly_zone_check)保持原有单点检测逻辑;本次改动在 src/no_fly_zone_check。

本地测试

python3 tests/test_no_fly_zone_check_local.py

运行效果

$ python main.py
==================================================
No-Fly Zone Check Module
==================================================
Loaded 3 no-fly zones:
  - Airport        center=(47.65, -122.14) radius=2000m
  - MilitaryBase   center=(47.6, -122.2) radius=1500m
  - School         center=(47.62, -122.1) radius=500m

--------------------------------------------------
单点检测
--------------------------------------------------
[WARNING] Airport center           (47.65, -122.14) -> INSIDE zone [Airport] (0.0 m)
[WARNING] Near Airport             (47.66, -122.13) -> INSIDE zone [Airport] (1340.7 m)
[OK]      Safe location (CN)       (30.0, 120.0) -> safe

--------------------------------------------------
航线穿越检测(两端都在区外,但航线从禁区中穿过)
--------------------------------------------------
[WARNING] 航线穿越禁飞区【Airport】:距离中心 0.0 m(半径 2000 m)

--------------------------------------------------
航线安全示例
--------------------------------------------------
[OK] 航线安全:起止点与整条航线都不在禁飞区内

模块是纯 Python 实现,不需要启动 AirSim 或 ROS;上图为离线运行结果。