# 机场碰撞预警系统设计文档 ## 1. 系统概述 ### 1.1 系统目标 实现机场内航空器与车辆的实时位置监控和碰撞预警。 ### 1.2 主要功能 - 实时获取航空器位置数据 - 实时获取车辆位置数据 - 碰撞风险检测 - 预警信息输出 ## 2. 系统架构 ### 2.1 整体架构 - 数据采集层:负责从外部系统获取位置数据 - 数据处理层:进行坐标转换和数据规范化 - 碰撞检测层:执行碰撞风险分析 - 预警输出层:生成和发送预警信息 ### 2.2 核心模块 1. System:系统总控模块 2. DataCollector:数据采集模块 3. CollisionDetector:碰撞检测模块 4. CoordinateConverter:坐标转换模块 ## 3. 数据模型 ### 3.1 基础数据类型 ```cpp // 移动物体类型 enum class MovingObjectType { AIRCRAFT, // 航空器 SPECIAL, // 特勤车 UNMANNED // 无人车(可控车辆) }; // 二维向量 struct Vector2D { double x; // 东西方向(米) double y; // 南北方向(米) double magnitude() const; // 计算向量大小 double direction() const; // 计算向量方向 }; // 地理坐标 struct GeoPosition { double latitude; // 纬度 double longitude; // 经度 }; // 位置记录 struct PositionRecord { GeoPosition geo; // 地理位置 uint64_t timestamp; // 时间戳 }; // 移动物体基类 class MovingObject { public: std::string id; // 唯一标识 Vector2D position; // 平面坐标 GeoPosition geo; // 地理坐标 double heading; // 航向角 double speed; // 速度 int64_t timestamp; // 时间戳 MovingObjectType type; // 物体类型 std::deque positionHistory; // 位置历史记录 virtual bool isValidPosition(const GeoPosition& newPos) const = 0; virtual bool isValidSpeed(double speed) const = 0; void updateMotion(const GeoPosition& newPos, uint64_t newTime); }; ``` ### 3.2 业务数据类型 ```cpp // 航空器 class Aircraft : public MovingObject { public: std::string flightNo; // 航班号 std::string trackNumber; // 航迹号 double altitude; // 高度(米) static constexpr double MAX_SPEED = 100.0; // 最大速度(米/秒) static constexpr double MAX_POSITION_JUMP = 50.0; // 最大位置跳变(米) bool isValidPosition(const GeoPosition& newPos) const override; bool isValidSpeed(double speed) const override; }; // 车辆 class Vehicle : public MovingObject { public: std::string vehicleNo; // 车牌号 bool isControllable; // 是否可控 static constexpr double MAX_SPEED = 20.0; // 最大速度(米/秒) static constexpr double MAX_POSITION_JUMP = 10.0; // 最大位置跳变(米) bool isValidPosition(const GeoPosition& newPos) const override; bool isValidSpeed(double speed) const override; }; ``` ### 3.3 配置数据类型 ```cpp // 可控车辆配置 struct ControllableVehicleConfig { std::string vehicleNo; // 车牌号 std::string ip; // 车辆IP地址 int port; // 车辆端口号 }; ``` ## 4. 接口设计 ### 4.1 数据源接口 ```cpp class DataSource { virtual std::vector getAircraftData() = 0; virtual std::vector getVehicleData() = 0; }; ``` ### 4.2 碰撞检测接口 ```cpp class CollisionDetector { bool detectAircraft(const Aircraft& a1, const Aircraft& a2); bool detectAircraftVehicle(const Aircraft& aircraft, const Vehicle& vehicle); }; ``` ## 5. 碰撞检测算法 ### 5.1 碰撞类型 系统支持以下碰撞类型: 1. HEAD_ON:相向碰撞(航向差大于 150 度) 2. CROSSING:交叉碰撞(航向差在 15-165 度之间) 3. PARALLEL:平行碰撞(航向差小于 30 度) 4. STATIC:静止碰撞(双方速度接近 0) ### 5.2 风险等级 ```cpp enum class RiskLevel { NONE = 0, // 无风险 WARNING = 1, // 预警:进入预警区域 CRITICAL = 2 // 告警:进入危险区域 }; enum class WarningZoneType { NONE = 0, // 无风险区域 WARNING = 1, // 预警区域 DANGER = 2 // 危险区域 }; ``` ### 5.3 碰撞检测流程 1. 距离检测: ```cpp // 计算当前距离 double dx = obj2.position.x - obj1.position.x; double dy = obj2.position.y - obj1.position.y; double current_distance = std::sqrt(dx*dx + dy*dy); // 如果当前距离大于警告区域,直接返回不会碰撞 if (current_distance > (warning_radius1 + warning_radius2)) { return false; } ``` 2. 碰撞类型判断: ```cpp double angle_diff = getAngleDifference(heading1, heading2); if (angle_diff > 150.0) { // 相向碰撞检测 type = CollisionType::HEAD_ON; } else if (angle_diff > 15.0 && angle_diff < 165.0) { // 交叉碰撞检测 type = CollisionType::CROSSING; } else { // 平行碰撞检测 type = CollisionType::PARALLEL; } ``` 3. 相对运动分析: ```cpp // 计算速度分量 double vx1 = speed1 * std::cos((90.0 - heading1) * M_PI / 180.0); double vy1 = speed1 * std::sin((90.0 - heading1) * M_PI / 180.0); double vx2 = speed2 * std::cos((90.0 - heading2) * M_PI / 180.0); double vy2 = speed2 * std::sin((90.0 - heading2) * M_PI / 180.0); // 计算相对运动 double rel_vx = vx2 - vx1; double rel_vy = vy2 - vy1; double rel_speed = std::sqrt(rel_vx*rel_vx + rel_vy*rel_vy); ``` 4. 碰撞预测: ```cpp // 在时间窗口内采样检查 for (int i = 1; i <= STEPS; ++i) { double t = i * dt; // 计算t时刻的位置 Vector2D future1 = predictPosition(pos1, speed1, heading1, t); Vector2D future2 = predictPosition(pos2, speed2, heading2, t); // 计算t时刻的距离 double distance = calculateDistance(future1, future2); // 检查是否会碰撞 if (distance <= safe_distance) { return true; } } ``` ### 5.4 碰撞记录管理 ```cpp struct CollisionRecord { Vector2D collisionPoint; // 冲突点位置 int64_t detectedTime; // 检测到冲突的时间 RiskLevel maxLevel; // 历史最高风险等级 bool resolved; // 是否已解除 }; ``` 碰撞解除条件: 1. 对于已通过交叉点的情况: - 物体距离交叉点的距离大于安全距离 2. 对于未通过交叉点的情况: - 两个物体都在安全距离之外 - 预测不会发生碰撞 ### 5.5 区域特定阈值 不同区域采用不同的安全距离阈值: | 区域 | 航空器地面阈值 | 车辆阈值 | |----------|----------------|-----------| | 跑道 | 100米 | 50米 | | 滑行道 | 50米 | 30米 | | 停机位 | 40米 | 20米 | | 服务区 | 30米 | 15米 | ### 5.6 空间优化 使用四叉树进行空间索引,优化查询性能: 1.四叉树构建: ```cpp QuadTree vehicleTree_(bounds, 8); // 容量为8的四叉树 ``` 2.邻近查询: ```cpp auto nearbyVehicles = vehicleTree_.queryNearby( position, // 中心点 threshold // 查询半径 ); ``` ### 5.7 性能考虑 1. 空间复杂度: - 四叉树:O(n),其中 n 为车辆数量 - 航空器列表:O(m),其中 m 为航空器数量 2. 时间复杂度: - 四叉树查询:O(log n) - 总体碰撞检测:O(m * log n) ### 5.8 安全保障 1. 距离冗余: - 使用阈值的一半作为直接报警条件 - 为不同区域设置合适的安全距离 2. 运动预测: - 考虑物体的相对运动 - 提前发现潜在碰撞风险 3. 降级处理: - 当无法计算相对运动时,仅使用距离判断 - 保证基本的安全检测功能 ### 5.9 碰撞检测主流程 ```cpp // 加载可控车辆配置 std::vector controllableVehicles = loadControllableVehicleConfig(); for (const auto& aircraft : aircrafts) { for (const auto& vehicle : vehicles) { if (detectCollision(aircraft, vehicle)) { // 检查是否为可控车辆 auto iter = std::find_if(controllableVehicles.begin(), controllableVehicles.end(), [&](const ControllableVehicleConfig& config) { return config.vehicleNo == vehicle.vehicleNo; }); if (iter != controllableVehicles.end()) { // 生成控制指令 auto command = generateCommand(aircraft, vehicle); // 发送控制指令 sendCommand(command, iter->ip, iter->port); } else { // 发送普通预警 sendWarning(aircraft, vehicle); } } } } ``` ### 5.10 可控车辆配置加载 从配置文件加载可控车辆信息: ```cpp std::vector loadControllableVehicleConfig() { std::vector configs; // 读取配置文件 std::ifstream file("controllable_vehicles.json"); nlohmann::json jsonConfig; file >> jsonConfig; // 解析配置项 for (const auto& item : jsonConfig["vehicles"]) { ControllableVehicleConfig config; config.vehicleNo = item["vehicleNo"].get(); config.ip = item["ip"].get(); config.port = item["port"].get(); configs.push_back(config); } return configs; } ``` 配置文件 `controllable_vehicles.json` 的格式如下: ```json { "vehicles": [ { "vehicleNo": "VEH001", "ip": "192.168.1.101", "port": 8080 }, { "vehicleNo": "VEH002", "ip": "192.168.1.102", "port": 8080 }, { "vehicleNo": "VEH003", "ip": "192.168.1.103", "port": 8080 } ] } ``` ## 6. 坐标转换 ### 6.1 转换方法 - 使用等角投影方法 - 基于机场参考点(青岛胶东国际机场:北纬36°21'43.2",东经120°05'16.8") - 考虑地球曲率影响 - WGS84椭球体参数 ## 7. 数据更新策略 ### 7.1 数据采集 - 定时轮询(默认1秒) - 独立的数据采集线程 - 分别缓存航空器和车辆数据 ### 7.2 碰撞检测 - 实时检测(默认100ms) - 独立的检测线程 - 分类处理不同类型的碰撞风险 ## 8. 开发规范 ### 8.1 代码规范 - Google C++ Style - 智能指针管理 - 异常安全 - RAII原则 ### 8.2 性能规范 - 避免虚函数滥用 - 减少动态内存分配 - 合理使用模板 - 注意数据对齐 ### 8.3 网络编程规范 #### 8.3.1 数据读取策略 - 使用分块读取代替一次性读取 - 合理设置分块大小(如1KB) - 正确处理部分读取的情况 - 验证数据完整性 #### 8.3.2 错误处理 - 实现请求重试机制 - 设置合理的超时时间 - 正确处理连接断开 - 完善的错误日志记录 #### 8.3.3 连接管理 - 及时关闭无用连接 - 正确处理连接状态 - 实现连接池(如需要) - 处理并发连接 #### 8.3.4 性能考虑 - 使用异步操作处理并发 - 实现数据缓存机制 - 免频繁建立连接 - 合理控制缓冲区大小 #### 8.3.5 最佳实践 ```cpp // 分块读取示例 const size_t chunk_size = 1024; // 1KB per chunk while (total_read < content_length) { size_t to_read = std::min(chunk_size, content_length - total_read); // 读取数据块 // 处理错误 // 更新计数 } // 重试机制示例 const int max_retries = 3; for (int retry = 0; retry < max_retries; ++retry) { try { // 尝试操作 break; // 成功则退出 } catch (...) { if (retry == max_retries - 1) throw; // 最后一次重试失败 // 等待后重试 } } ``` ### 8.4 HTTP 数据读取规范 #### 8.4.1 问题描述 在使用 Boost.Asio 读取 HTTP 响应时,可能会遇到 "End of file" 错误。这个错误通常发生在: - 读取响应体时 - 服务器已关闭连接 - 数据未完全读取 #### 8.4.2 错误原因分析 1. HTTP 响应头读取时可能已包含部分响应体数据 2. 忽略缓冲区中的这部分数据会导致: - 数据丢失 - 读取位置错误 - 连接提前关闭 #### 8.4.3 解决方案 1. 正确处理响应数据: ```cpp // 1. 读取响应头 size_t header_length = asio::read_until(*socket_, response_buf, "\r\n\r\n"); // 2. 处理缓冲区中的响应体数据 size_t body_part = response_buf.size() - header_length; if (body_part > 0) { // 提取已缓冲的响应体数据 body.append( asio::buffers_begin(response_buf.data()) + header_length, asio::buffers_end(response_buf.data()) ); total_read += body_part; } // 3. 继续读取剩余数据 while (total_read < content_length) { // 读取剩余的响应体 } ``` #### 8.4.4 最佳实践 1. 数据读取原则: - 使用简单直接的读取逻辑 - 准确跟踪已读取的数据量 - 正确处理缓冲区中的所有数据 - 避免复杂的重试机制 2. 错误处理: - 及时检查错误码 - 提供详细的错误日志 - 在错误发生时及时关闭连接 - 保持连接状态的一致性 3. 数据完整性: - 验证 Content-Length - 确保读取完整的响应体 - 避免数据丢失或重复 - 正确处理分块数据 4. 日志记录: - 记录关键操作步骤 - 包含详细的错误信息 - 记录数据读取进度 - 便于问题诊断和调试 ## 9. 测试策略 ### 9.1 单元测试 - 模块功能测试 - 边界条件测试 - 异常处理测试 - 内存泄漏测试 - 坐标转换精度测试 ### 9.2 性能测试 - 延迟测试 - 并发测试 - 压力测试 - 内存使用测试 - 坐标转换性能测试 ## 9. 测试场景 ### 9.1 碰撞风险场景模拟 #### 9.1.1 场景描述 模拟一个典型的地面碰撞风险场景: - 航空器在跑道上滑行 - 地面车辆垂直接近跑道 - 两者轨迹存在交叉点 - 如不采取措施将发生碰撞 #### 9.1.2 场景参数 1. 航空器参数: - 初始位置:跑道西端 (AIRPORT_LON - 0.002, AIRPORT_LAT) - 运动方向:向东滑行 - 运动速度:0.0002经度/秒 - 高度:5米(地面滑行高度) 2. 车辆参数: - 初始位置:跑道南侧 (AIRPORT_LON, AIRPORT_LAT - 0.002) - 运动方向:向北行驶 - 运动速度:0.0002纬度/秒 - 与航空器轨迹垂直相交 3. 时间参数: - 更新频率:每秒一次 - 场景周期:10秒 - 碰撞风险时间:约5秒(场景中点) #### 9.1.3 数据特点 1. 位置数据: - 只提供实时位置信息 - 不包含速度信息 - 不包含方向信息 - 位置精度:小数点后6位 2. 数据格式: ```json // 航空器数据 { "flightNo": "CES2501", "longitude": 120.088003, "latitude": 36.361999, "time": 1700123456, } // 车辆数据 { "vehicleNo": "VEH001", "longitude": 120.088003, "latitude": 36.361999, "time": 1700123456 } ``` #### 9.1.4 预期结果 1. 碰撞检测: - 在交叉点附近应触发预警 - 预警时间:碰撞前约5秒 - 持续时间:直到危险解除 2. 风险等级: - 距离大于100米:低风险 - 距离50-100米:中等风险 - 距离小于50米:高风险 3. 系统响应: - 实时计算相对距离 - 及时发出预警信息 - 记录完整的碰撞风险过程 ## 10. 风险控制 ### 10.1 技术风险 - 实时性保证 - 内存管理 - 多线程同步 - 系统稳定性 - 坐标转换精度 ### 10.2 解决方案 - 性能优化 - 资源监控 - 故障恢复 - 降级处理 - 坐标转换验证 ## 11. 后续优化 1. 引入GPU加速计算 2. 优化空间索引算法 3. 改进故障检测机制 4. 增加自适应负载均衡 5. 完善监控告警系统 6. 优化坐标转换算法 7. 支持多种投影方式 使用纯C++实现可以获得: 1. 最佳的实时性能 2. 直接的硬件控制 3. 精确的内存管理 4. 最小的系统开销 5. 可预测的行为表现 ## 10. 单元测试 ### 10.1 测试框架 - 使用 Google Test 框架 - 支持 EXPECT 和 ASSERT 断言 - 支持 Mock 对象 - 支持测试夹具(Test Fixtures) ### 10.2 测试用例组织 #### 10.2.1 基础类型测试 (BasicTypesTest) 1. Vector2D 测试 - 测试向量大小计算 - 测试方向角计算 2. MovingObject 测试 - 测试速度计算 - 测试航向角计算 - 验证位置历史记录 3. 数据有效性测试 - 测试航空器数据 - 测试车辆数据 - 验证速度和位置限制 #### 10.2.2 碰撞检测测试 (CollisionDetectorTest) 1. 安全距离测试 - 测试水平安全距离 - 测试垂直安全距离 2. 边界条件测试 - 测试临界距离 - 测试高度边界 3. 特殊情况测试 - 测试零距离情况 - 测试对角线距离 #### 10.2.3 数据采集测试 (DataCollectorTest) 1. 速度计算测试 ```cpp // 测试数据生成 double lon = 120.08 + (LON_CHANGE_PER_SEC * i); // 每秒经度变化 uint64_t timestamp = baseTime + (i * 1); // 每秒一个点 // 验证速度计算 EXPECT_NEAR(aircraft.speed, 55.0, 5.0); // 允许5m/s误差 ``` 2. Mock 数据源 ```cpp class MockDataSource : public DataSource { MOCK_METHOD(bool, connect, (), (override)); MOCK_METHOD(bool, fetchAircraftData, (std::vector&), (override)); MOCK_METHOD(bool, fetchVehicleData, (std::vector&), (override)); }; ``` ### 10.3 测试数据生成 #### 10.3.1 位置数据 1. 航空器数据 - 基于青岛胶东机场坐标 - 模拟地面滑行场景 - 生成连续位置点 2. 车辆数据 - 模拟地面车辆运动 - 生成可能的碰撞场景 #### 10.3.2 时间序列 1. 时间戳生成 - 使用 Unix 时间戳 - 每秒更新一次 - 保证时间连性 2. 数据更新频率 - 模拟实际系统的更新频率 - 确保数据连续性 - 避免时间戳重复 ### 10.4 测试覆盖率 1. 基础功能测试 - 坐标转换 - 速度计算 - 航向计算 2. 错误处理测试 - 无效数据处理 - 连接错误处理 - 数据解析错误 3. 边界条件测试 - 最大/最小速度 - 位置跳变限制 - 时间戳异常 ### 10.5 测试最佳实践 1. 测试数据准备 - 使用实际的地理坐标 - 模拟真实的运动场景 - 考虑数据精度 2. Mock 对象使用 - 模拟外部依赖 - 控制测试环境 - 验证交互逻辑 3. 日志记录 - 记录测试过程 - 输出中间结果 - 便于问题诊断 ## 11. 可控车辆通信 ### 11.1 通信方式 使用 HTTP 协议与可控车辆通信: - 碰撞检测系统作为 HTTP 客户端,向可控车辆发送 POST 请求 - 请求地址格式为: `http://:/command` - 请求 Body 中包含控制指令的 JSON 表示 - 可控车辆作为 HTTP 服务器,接收并处理控制指令 ### 11.2 指令格式 使用 JSON 格式表示控制指令: ```json POST /command HTTP/1.1 Host: : Content-Type: application/json { "command": "stop", "timestamp": 1700123456 } ``` 或者: ```json POST /command HTTP/1.1 Host: : Content-Type: application/json { "command": "change_route", "route": [ {"longitude": 120.08, "latitude": 36.36}, {"longitude": 120.09, "latitude": 36.37}, {"longitude": 120.10, "latitude": 36.38} ], "timestamp": 1700123456 } ``` ### 11.3 可控车辆响应 可控车辆收到指令后,需要及时响应: 1. 立即执行停车、减速等指令 2. 如果是改变路线,则规划新的路径并切换 3. 将执行结果以 JSON 格式返回: ```json HTTP/1.1 200 OK Content-Type: application/json { "status": "ok", "message": "Command executed successfully", "timestamp": 1700123456 } ``` 或者: ```json HTTP/1.1 500 Internal Server Error Content-Type: application/json { "status": "error", "message": "Failed to execute command", "error": "No route found", "timestamp": 1700123456 } ``` ### 11.4 安全考虑 由于 HTTP 是明文传输协议,存在安全隐患。需要采取以下措施: 1. 使用 HTTPS 代替 HTTP,实现加密通信 2. 对可控车辆的访问进行身份验证,防止非法控制 3. 对控制指令进行数字签名,防止指令被篡改 4. 对敏感数据(如路径点坐标)进行加密,防止泄露 ### 11.5 可用性考虑 为保证可控车辆的控制链路高可用,需要: 1. 监控可控车辆的 HTTP 服务可用性,发现异常及时告警 2. 对控制指令的发送进行重试和超时处理,避免单次请求失败导致控制中断 3. 考虑引入备用的控制方式(如 MQTT),作为 HTTP 不可用时的降级方案 ### 11.6 指令发送 根据可控车辆的IP地址和端口号,发送控制指令: ```cpp void sendCommand(const ControlCommand& command, const std::string& ip, int port) { // 创建HTTP客户端 HttpClient client(ip, port); // 构造请求 HttpRequest request; request.setMethod(HttpRequest::POST); request.setPath("/command"); request.setHeader("Content-Type", "application/json"); request.setBody(command.toJson()); // 发送请求 HttpResponse response = client.send(request); // 处理响应 if (response.getStatus() == HttpResponse::OK) { // 指令发送成功 logger.info("Command sent successfully"); } else { // 指令发送失败 logger.error("Failed to send command, status code: {}", response.getStatus()); } } ``` 使用 HTTP 客户端库,向可控车辆发送 POST 请求。请求路径为 `/command`,请求体为控制指令的 JSON 表示。根据响应状态码判断指令是否发送成功。 ## 遗留问题 ### 1. Python 包依赖问题 - 当前部署脚本在 Python 3.6 环境下存在依赖问题 - 需要添加 importlib-metadata 和 zipp 包 - 需要调整包版本以兼容 Python 3.6 - 考虑使用系统自带的 Python 包替代 pip 安装 ### 2. 部署脚本改进 - prepare_deploy.sh 中下载 Python 包时需要包含所有依赖 - deploy.sh 中需要按正确顺序安装 Python 包 - 考虑使用 requirements.txt 管理 Python 依赖 - 需要优化部署脚本的错误处理和日志输出 ### 3. 生产环境适配 - 需要适配离线环境的部署需求 - 需要完善 SELinux 相关的配置 - 需要优化日志文件的管理 - 需要完善服务启动失败的故障排查机制 ### 4. 后续优化建议 - 简化部署步骤,减少人工干预 - 添加部署回滚机制 - 添加部署验证步骤 - 完善部署文档 - 简化部署步骤,减少人工干预 - 添加部署回滚机制 - 添加部署验证步骤 - 完善部署文档 ## 机场边界设计 ### 问题描述 实际机场通常是倾斜的(如东南-西北走向),需要一个合适的方案来判断车辆和飞机是否在机场各个区域内。 ### 设计方案 #### 坐标系统设计 1. 世界坐标系 - 使用标准的笛卡尔坐标系 - X 轴指向东,Y 轴指向北 2. 机场局部坐标系 - 原点:可配置的机场参考点 - 方向:通过旋转角度将世界坐标系对齐到机场主轴 - 旋转规则: - 以正北方向为基准 - 正值表示逆时针旋转 - 负值表示顺时针旋转 - 例:东南-西北走向的机场(以青岛国际机场为例),从东南指向西北为 -21.47 度 #### 核心组件 1. `AirportBounds` 类 - 负责管理机场边界和区域定义 - 提供坐标转换功能 - 判断位置所属区域 2. 配置文件 (`airport_bounds.json`) ```json { "airport": { "rotation_angle": -45.0, // 机场旋转角度(度) "reference_point": { // 机场参考点 "x": 0.0, "y": 0.0 }, "bounds": { // 机场总边界 "x": -2000, "y": -1000, "width": 4000, "height": 2000 } }, "areas": { // 各功能区定义 // ... 具体区域配置 } } ``` #### 坐标转换流程 1. 位置判断流程 - 接收世界坐标系中的点坐标 - 将点坐标转换到机场局部坐标系 - 在局部坐标系中进行边界检查 2. 坐标转换算法 ```cpp Vector2D toAirportCoordinate(const Vector2D& point) { // 1. 平移到参考点为原点 double dx = point.x - referencePoint_.x; double dy = point.y - referencePoint_.y; // 2. 应用旋转变换 double cos_angle = std::cos(rotationAngle_); double sin_angle = std::sin(rotationAngle_); return Vector2D{ dx * cos_angle + dy * sin_angle, -dx * sin_angle + dy * cos_angle }; } ``` ### 优势 1. 实现简单,易于理解和维护 2. 计算开销小 3. 不需要修改现有的碰撞检测逻辑 4. 可以方便地调整机场方向 5. 支持不同区域的差异化配置 ### 使用说明 1. 确定机场实际旋转角度 2. 选择合适的参考点(通常是机场中心或跑道中心) 3. 在机场局部坐标系中定义各个区域的边界 4. 配置各区域的安全参数(如碰撞半径、警告区域等) ### 注意事项 1. 角度配置采用度数(而非弧度) 2. 顺时针旋转使用负角度 3. 确保参考点选择合理,便于区域划分 4. 区域边界在局部坐标系中定义 如果需要计算角度(比如判断车辆朝向),则使用向量点积方法