CollisionAvoidance/docs/design.md

11 KiB
Raw Blame History

机场碰撞预警系统设计文档

1. 系统概述

1.1 系统目标

实现机场内航空器与车辆的实时位置监控和碰撞预警。

1.2 主要功能

  • 实时获取航空器位置数据
  • 实时获取车辆位置数据
  • 碰撞风险检测
  • 预警信息输出

2. 系统架构

2.1 整体架构

  • 数据采集层:负责从外部系统获取位置数据
  • 数据处理层:进行坐标转换和数据规范化
  • 碰撞检测层:执行碰撞风险分析
  • 预警输出层:生成和发送预警信息

2.2 核心模块

  1. System系统总控模块
  2. DataCollector数据采集模块
  3. CollisionDetector碰撞检测模块
  4. CoordinateConverter坐标转换模块

3. 数据模型

3.1 基础数据类型

// 二维向量
struct Vector2D {
    double x;  // 东西方向(米)
    double y;  // 南北方向(米)
};

// 地理坐标
struct GeoPosition {
    double latitude;   // 纬度
    double longitude;  // 经度
};

// 基础移动物体
struct MovingObject {
    std::string id;          // 唯一标识
    GeoPosition geo;         // 地理坐标
    Vector2D position;       // 平面坐标
    double heading;          // 航向角(度)
    uint64_t timestamp;      // 时间戳
};

3.2 业务数据类型

// 航空器数据
struct Aircraft : MovingObject {
    std::string flightNo;    // 航班号
    std::string trackNumber; // 航迹号
    double altitude;         // 高度(米)
};

// 车辆数据
struct Vehicle : MovingObject {
    std::string vehicleNo;   // 车牌号
    double speed;           // 速度
    double direction;       // 方向
};

4. 接口设计

4.1 数据源接口

class DataSource {
    virtual std::vector<Aircraft> getAircraftData() = 0;
    virtual std::vector<Vehicle> getVehicleData() = 0;
};

4.2 碰撞检测接口

class CollisionDetector {
    bool detectAircraft(const Aircraft& a1, const Aircraft& a2);
    bool detectAircraftVehicle(const Aircraft& aircraft, const Vehicle& vehicle);
};

5. 碰撞检测算法

5.1 碰撞风险判定

  • 计算航空器与车辆之间的平面距离
  • 考虑航空器的当前高度
  • 同时满足以下条件时触发预警:
    1. 平面距离小于50米
    2. 航空器高度低于50米

5.2 安全阈值

  • 水平安全距离50米
  • 垂直安全距离50米
  • 阈值可根据<EFBFBD><EFBFBD>运行情况调整

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 性能考虑

  • 使用异步操作处理并发
  • 实现数据缓存机制
  • <EFBFBD><EFBFBD>免频繁建立连接
  • 合理控制缓冲区大小

8.3.5 最佳实践

// 分块读取示例
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. 正确处理响应数据:
// 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. 数据格式:

// 航空器数据
{
    "flightNo": "CES2501",
    "longitude": 120.088003,
    "latitude": 36.361999,
    "time": 1700123456.789,
    "altitude": 5.0,
    "trackNumber": "TN001"
}

// 车辆数据
{
    "vehicleNo": "VEH001",
    "longitude": 120.088003,
    "latitude": 36.361999,
    "time": 1700123456.789
}

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. 速度计算测试

    // 测试数据生成
    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 数据源

    class MockDataSource : public DataSource {
        MOCK_METHOD(bool, connect, (), (override));
        MOCK_METHOD(bool, fetchAircraftData, (std::vector<Aircraft>&), (override));
        MOCK_METHOD(bool, fetchVehicleData, (std::vector<Vehicle>&), (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. 日志记录

    • 记录测试过程
    • 输出中间结果
    • 便于问题诊断