# 碰撞避免系统数据处理模块设计文档

## 1. 模块概述

数据处理模块（DataProcessing）是碰撞避免系统的核心组件之一，负责对从数据采集模块获取的原始数据进行处理、转换和分析。该模块包含坐标转换、速度计算、数据预处理等功能，为后续的碰撞检测和避险决策提供高质量的数据支持。

### 1.1 功能职责

- 将全球地理坐标（WGS84）转换为机场局部坐标系
- 对移动物体的速度和加速度进行计算和分析
- 执行数据质量检测，识别和标记异常数据
- 进行数据平滑和滤波处理
- 维护各类移动物体的实时状态
- 执行碰撞风险评估和预警（计划实现）

### 1.2 模块结构

数据处理模块采用分层架构设计，主要包含以下组件：

```
dataProcessing/
├── config/              # 配置类，如坐标系统配置等
├── model/               # 数据模型，定义数据结构（如碰撞风险等级等）
├── service/             # 服务层，实现核心业务逻辑
│   ├── DataProcessor.java                # 数据处理主服务
│   ├── CoordinateSystemService.java      # 坐标转换服务
│   ├── SpeedCalculationService.java      # 速度计算服务
│   ├── AirportCoordinateSystem.java      # 机场坐标系统
│   └── CollisionDetectionService.java    # 碰撞检测服务（待实现）
└── util/                # 工具类，提供辅助功能
```

## 2. 核心组件设计

### 2.1 DataProcessor（数据处理器）

DataProcessor是数据处理模块的核心组件，负责协调各种处理任务，管理数据流转，并确保数据的一致性和质量。

#### 2.1.1 主要职责

- 接收来自数据采集模块的数据更新
- 调度不同类型数据的处理流程
- 维护处理过程中的数据一致性
- 将处理后的数据提供给其他模块使用

#### 2.1.2 processLoop方法设计

`processLoop`方法是DataProcessor的核心循环，持续处理数据流。其主要业务逻辑如下：

```java
private void processLoop() {
    while (!Thread.currentThread().isInterrupted()) {
        // 获取数据更新
        Map<MovingObjectType, Set<String>> delta = movingObjectRepository.takeUpdate();
        
        // 判断更新是否为空
        if (delta == null || delta.isEmpty()) {
            // 无数据更新，等待一段时间
            Thread.sleep(500);
            continue;
        }
        
        // 处理各类型的数据更新
        delta.forEach((objectType, ids) -> {
            // 获取该类型的数据快照
            Map<String, MovingObject> snapshot = movingObjectRepository.getTypeMapDirect(objectType);
            List<MovingObject> dataList = new CopyOnWriteArrayList<>(snapshot.values());
            
            // 根据不同类型分别处理
            switch (objectType) {
                case AIRCRAFT -> processAircraftData(dataList);
                case SPECIAL_VEHICLE -> processVehicleData(dataList);
                case UNMANNED_VEHICLE -> processLocationData(dataList);
                default -> log.warn("未支持的数据类型: {}", objectType);
            }
        });
    }
}
```

processLoop方法的工作流程：

1. **循环监听更新**：持续检查是否有新的数据更新
2. **获取变更数据**：从数据仓库中获取已更新的对象ID集合
3. **获取数据快照**：基于更新的ID，获取完整的数据对象
4. **类型分发处理**：根据不同移动物体类型，调用相应的处理方法
5. **异常处理**：捕获并记录处理过程中的异常，确保主循环不会因异常而中断

#### 2.1.3 数据类型处理方法

对于不同类型的移动物体，DataProcessor提供了专门的处理方法：

- **processAircraftData**：处理航空器数据
- **processVehicleData**：处理特种车辆数据
- **processLocationData**：处理无人车数据

这些方法执行类似的处理流程，主要包括：

1. 坐标转换：调用 `convertToLocalCoordinate` 将地理坐标转换为局部坐标
2. 速度预处理：调用 `speedCalculationService.preprocessData` 进行速度相关计算和质量检查

### 2.2 CoordinateSystemService（坐标系统服务）

负责执行坐标转换，将GPS或WGS84坐标系下的经纬度转换为以机场为中心的局部坐标系。

#### 2.2.1 主要功能

- 根据机场中心点创建局部坐标系
- 执行地理坐标到局部坐标的转换
- 计算局部坐标系下的距离和方向

#### 2.2.2 核心方法

```java
public double[] convertToLocalCoordinate(double longitude, double latitude) throws Exception {
    return airportCoordinateSystem.convertToLocal(longitude, latitude);
}
```

此方法将WGS84坐标系的经纬度转换为以机场中心为原点的UTM局部坐标系下的坐标，返回一个包含x（东向）和y（北向）坐标的数组。

### 2.3 SpeedCalculationService（速度计算服务）

负责计算和处理移动物体的速度、加速度等动力学参数，同时进行数据质量检查。

#### 2.3.1 主要功能

- 计算移动物体的速度分量
- 执行异常值检测
- 应用数据质量标记
- 提供数据平滑和滤波
- 根据历史数据计算加速度

#### 2.3.2 核心方法

```java
public void preprocessData(List<MovingObject> dataList) {
    // 遍历数据列表
    for (MovingObject obj : dataList) {
        // 初始化历史状态队列
        if (obj.getStateHistory().isEmpty()) {
            // 创建初始状态
            // ...
            continue;
        }
        
        // 获取最近的历史状态
        MovementState lastState = obj.getStateHistory().getFirst();
        
        // 异常值检测（位置跳变、时间异常、速度异常）
        // ...
        
        // 标记数据质量
        // ...
    }
}
```

preprocessData方法对数据进行预处理，主要包括：

1. 历史状态初始化
2. 异常值检测：检查位置跳变、时间异常和速度异常
3. 数据质量标记：将异常数据标记为SUSPICIOUS
4. 将处理后的状态添加到历史状态队列

## 3. 碰撞检测功能设计

### 3.1 功能需求

碰撞检测功能是碰撞避免系统的核心，需要实现以下功能：

1. 实时检测不同移动物体之间的潜在碰撞风险
2. 根据物体的当前位置、速度和轨迹预测未来可能的碰撞
3. 计算碰撞风险等级，并发出预警
4. 为避险决策提供准确的碰撞位置和时间预测

### 3.2 CollisionDetectionService设计

#### 3.2.1 类结构

```java
@Service
public class CollisionDetectionService {
    // 碰撞风险阈值（米）
    private static final double SEVERE_RISK_THRESHOLD = 50.0;  // 严重风险
    private static final double HIGH_RISK_THRESHOLD = 100.0;   // 高风险
    private static final double MEDIUM_RISK_THRESHOLD = 200.0; // 中等风险
    private static final double LOW_RISK_THRESHOLD = 500.0;    // 低风险
    
    // 时间预测范围（秒）
    private static final int PREDICTION_HORIZON = 30;
    
    // 依赖注入
    private final MovingObjectRepository repository;
    private final WebSocketService webSocketService;
    
    // 碰撞检测方法
    public void detectCollisions() {
        // 实现碰撞检测逻辑
    }
    
    // 两物体间碰撞风险计算
    private CollisionRisk calculateCollisionRisk(MovingObject obj1, MovingObject obj2) {
        // 计算当前距离
        // 预测轨迹
        // 计算最近接近点
        // 评估风险等级
        // 返回碰撞风险对象
    }
    
    // 轨迹预测方法
    private List<PredictedPosition> predictTrajectory(MovingObject obj, int seconds) {
        // 基于当前位置、速度和加速度预测未来轨迹
    }
}
```

#### 3.2.2 数据模型设计

```java
// 碰撞风险模型
public class CollisionRisk {
    private String id;                     // 风险ID
    private String object1Id;              // 第一个物体ID
    private String object2Id;              // 第二个物体ID
    private MovingObjectType type1;        // 第一个物体类型
    private MovingObjectType type2;        // 第二个物体类型
    private double currentDistance;        // 当前距离
    private double minimumDistance;        // 预测最小距离
    private long timeToMinimumDistance;    // 达到最小距离的时间（毫秒）
    private RiskLevel riskLevel;           // 风险等级
    private PredictedPosition collisionPoint; // 潜在碰撞点
    private long createdTime;              // 创建时间
    
    // getters and setters...
}

// 风险等级枚举
public enum RiskLevel {
    SEVERE,     // 严重风险（紧急）
    HIGH,       // 高风险
    MEDIUM,     // 中等风险
    LOW,        // 低风险
    NONE        // 无风险
}

// 预测位置
public class PredictedPosition {
    private double x;           // 局部坐标系x坐标
    private double y;           // 局部坐标系y坐标
    private double z;           // 局部坐标系z坐标（高度）
    private long timestamp;     // 预测时间戳
    
    // getters and setters...
}
```

### 3.3 碰撞检测算法

#### 3.3.1 基本碰撞检测算法

```java
public void detectCollisions() {
    // 获取所有活跃的移动物体
    List<MovingObject> allObjects = getAllActiveObjects();
    
    // 生成物体对组合
    List<Pair<MovingObject, MovingObject>> objectPairs = generateObjectPairs(allObjects);
    
    // 并行处理所有物体对
    List<CollisionRisk> risks = objectPairs.parallelStream()
        .map(pair -> calculateCollisionRisk(pair.getLeft(), pair.getRight()))
        .filter(risk -> risk.getRiskLevel() != RiskLevel.NONE)
        .collect(Collectors.toList());
    
    // 处理检测到的风险
    processDetectedRisks(risks);
}

private CollisionRisk calculateCollisionRisk(MovingObject obj1, MovingObject obj2) {
    // 计算当前距离
    double currentDistance = calculateDistance(obj1, obj2);
    
    // 如果当前距离已经过远，可以直接排除
    if (currentDistance > LOW_RISK_THRESHOLD && 
        obj1.getVelocity().getSpeed() + obj2.getVelocity().getSpeed() < 50) {
        return new CollisionRisk(obj1, obj2, currentDistance, RiskLevel.NONE);
    }
    
    // 预测未来30秒的轨迹
    List<PredictedPosition> trajectory1 = predictTrajectory(obj1, PREDICTION_HORIZON);
    List<PredictedPosition> trajectory2 = predictTrajectory(obj2, PREDICTION_HORIZON);
    
    // 计算轨迹上所有点的距离，找出最小距离点
    Pair<Double, Long> minDistanceAndTime = findMinimumDistance(trajectory1, trajectory2);
    double minDistance = minDistanceAndTime.getLeft();
    long timeToMinDistance = minDistanceAndTime.getRight();
    
    // 确定风险等级
    RiskLevel riskLevel = determineRiskLevel(minDistance);
    
    // 创建并返回碰撞风险对象
    return new CollisionRisk(obj1, obj2, currentDistance, minDistance, 
                            timeToMinDistance, riskLevel, 
                            findCollisionPoint(trajectory1, trajectory2, timeToMinDistance));
}
```

#### 3.3.2 轨迹预测算法

```java
private List<PredictedPosition> predictTrajectory(MovingObject obj, int seconds) {
    List<PredictedPosition> trajectory = new ArrayList<>();
    double deltaT = 1.0; // 时间步长（秒）
    
    // 获取当前位置、速度
    double x = obj.getVelocity().getX();
    double y = obj.getVelocity().getY();
    double z = obj.getCurrentPosition().getAltitude();
    double vx = obj.getVelocity().getVx();
    double vy = obj.getVelocity().getVy();
    double vz = obj.getVelocity().getVz();
    
    // 估计加速度（如果有历史数据）
    double ax = 0, ay = 0, az = 0;
    if (obj.getStateHistory().size() >= 2) {
        // 计算加速度...
    }
    
    // 当前时间戳
    long currentTime = obj.getTimestamp();
    
    // 预测轨迹点
    for (int i = 0; i <= seconds; i++) {
        // 使用运动学公式预测位置
        double predictedX = x + vx * i * deltaT + 0.5 * ax * Math.pow(i * deltaT, 2);
        double predictedY = y + vy * i * deltaT + 0.5 * ay * Math.pow(i * deltaT, 2);
        double predictedZ = z + vz * i * deltaT + 0.5 * az * Math.pow(i * deltaT, 2);
        
        // 预测时间戳
        long predictedTime = currentTime + (long)(i * deltaT * 1000);
        
        // 添加到轨迹
        trajectory.add(new PredictedPosition(predictedX, predictedY, predictedZ, predictedTime));
    }
    
    return trajectory;
}
```

### 3.4 集成到现有系统

要将碰撞检测功能集成到现有系统中，需要修改DataProcessor类以调用碰撞检测服务：

```java
@Slf4j
@Component
public class DataProcessor {
    @Autowired
    private MovingObjectRepository movingObjectRepository;
    @Autowired
    private CoordinateSystemService coordinateSystemService;
    @Autowired
    private SpeedCalculationService speedCalculationService;
    @Autowired
    private CollisionDetectionService collisionDetectionService; // 新增
    @Resource
    private Executor processingExecutor;
    
    // 修改processLoop方法
    private void processLoop() {
        // ... 现有代码 ...
        
        delta.forEach((objectType, ids) -> {
            // ... 现有代码 ...
            
            // 数据处理完成后执行碰撞检测
            collisionDetectionService.detectCollisions();
        });
    }
}
```

## 4. 性能优化策略

由于碰撞检测需要大量计算，可采用以下优化策略：

### 4.1 空间分区优化

使用空间分区（Spatial Partitioning）技术将整个坐标空间分成网格或四叉树，只检测同一区域或相邻区域的物体：

```java
// 创建空间网格
private Map<GridCell, List<MovingObject>> createSpatialGrid(List<MovingObject> objects) {
    Map<GridCell, List<MovingObject>> grid = new HashMap<>();
    
    for (MovingObject obj : objects) {
        GridCell cell = calculateGridCell(obj);
        grid.computeIfAbsent(cell, k -> new ArrayList<>()).add(obj);
    }
    
    return grid;
}

// 获取需要比较的物体对
private List<Pair<MovingObject, MovingObject>> getPairsToCheck(Map<GridCell, List<MovingObject>> grid) {
    List<Pair<MovingObject, MovingObject>> pairs = new ArrayList<>();
    
    // 遍历每个网格及其相邻网格
    for (Map.Entry<GridCell, List<MovingObject>> entry : grid.entrySet()) {
        GridCell cell = entry.getKey();
        List<MovingObject> objectsInCell = entry.getValue();
        
        // 同一网格内的物体对比
        for (int i = 0; i < objectsInCell.size(); i++) {
            for (int j = i + 1; j < objectsInCell.size(); j++) {
                pairs.add(Pair.of(objectsInCell.get(i), objectsInCell.get(j)));
            }
        }
        
        // 与相邻网格的物体对比
        for (GridCell neighbor : getNeighborCells(cell)) {
            List<MovingObject> objectsInNeighbor = grid.get(neighbor);
            if (objectsInNeighbor != null) {
                for (MovingObject obj1 : objectsInCell) {
                    for (MovingObject obj2 : objectsInNeighbor) {
                        pairs.add(Pair.of(obj1, obj2));
                    }
                }
            }
        }
    }
    
    return pairs;
}
```

### 4.2 多级碰撞检测

实现多级碰撞检测，从粗略到精细：

1. **粗略检测**：使用包围盒（Bounding Box）或包围球进行快速排除
2. **中间检测**：对可能碰撞的物体对进行简化轨迹预测
3. **精细检测**：只对高风险物体对进行精确轨迹预测和分析

```java
private CollisionRisk calculateCollisionRisk(MovingObject obj1, MovingObject obj2) {
    // 第一级：粗略检测
    if (!couldPossiblyCollide(obj1, obj2)) {
        return new CollisionRisk(obj1, obj2, Double.MAX_VALUE, RiskLevel.NONE);
    }
    
    // 第二级：中间检测
    Pair<Double, Long> roughEstimate = estimateMinimumDistance(obj1, obj2);
    if (roughEstimate.getLeft() > HIGH_RISK_THRESHOLD) {
        return new CollisionRisk(obj1, obj2, roughEstimate.getLeft(), RiskLevel.LOW);
    }
    
    // 第三级：精细检测
    return performDetailedCollisionAnalysis(obj1, obj2);
}
```

### 4.3 并行计算

利用多线程和并行计算技术提高处理速度：

1. 使用Java的Stream API的并行处理能力
2. 将碰撞检测任务拆分为多个子任务并行执行
3. 利用线程池管理并优化线程资源

## 5. 日志记录和监控

在碰撞检测过程中，实现全面的日志记录和监控机制：

```java
// 日志记录
private void logCollisionRisk(CollisionRisk risk) {
    if (risk.getRiskLevel() == RiskLevel.SEVERE || risk.getRiskLevel() == RiskLevel.HIGH) {
        log.warn("检测到高风险碰撞可能! 对象: {} 和 {}, 风险等级: {}, 最小距离: {}米, 预计时间: {}秒后",
                risk.getObject1Id(), risk.getObject2Id(), risk.getRiskLevel(),
                risk.getMinimumDistance(), risk.getTimeToMinimumDistance() / 1000);
    } else {
        log.info("检测到碰撞风险. 对象: {} 和 {}, 风险等级: {}, 最小距离: {}米",
                risk.getObject1Id(), risk.getObject2Id(), risk.getRiskLevel(),
                risk.getMinimumDistance());
    }
}

// 性能监控
private void monitorPerformance(long startTime, int objectCount, int pairsChecked, List<CollisionRisk> risks) {
    long endTime = System.currentTimeMillis();
    long duration = endTime - startTime;
    
    log.debug("碰撞检测完成. 处理时间: {}ms, 物体数: {}, 检查对数: {}, 发现风险: {}",
            duration, objectCount, pairsChecked, risks.size());
    
    // 记录性能指标到监控系统
    // ...
}
```

## 6. 后续优化和扩展

### 6.1 机器学习增强

引入机器学习模型增强碰撞预测能力：

1. 使用历史数据训练移动物体的轨迹预测模型
2. 引入情境感知能力，识别特定场景下的常见模式
3. 通过强化学习优化避险策略

### 6.2 多传感器数据融合

整合多种数据源提高预测准确性：

1. 结合气象数据考虑环境因素对运动的影响
2. 整合地面雷达、ADS-B和其他传感器数据
3. 考虑地形和建筑物等静态障碍物

### 6.3 通信和响应机制

完善碰撞风险的通知和响应机制：

1. 实现分级预警通知（WebSocket、移动应用推送等）
2. 为不同类型的碰撞风险定制响应策略
3. 提供碰撞避免的建议路径和操作

## 7. 总结

本文档详细描述了碰撞避免系统中数据处理模块的当前设计和processLoop方法的业务逻辑，并提出了碰撞检测功能的设计方案。通过实现高效的碰撞检测算法、多级优化策略和完善的监控机制，系统能够有效检测和预警潜在的碰撞风险，为机场安全运行提供保障。

随着系统的持续优化和功能扩展，碰撞避免系统将能够应对更复杂的场景和更高的安全需求，实现从被动监测到主动避险的演进。 