QAUP_Management/doc/design/collision_detection_design.md
Tian jianyong 5e1e9f4507 统一了前后端到一个项目,实现了无人车的位置和超速检测,并发送到前端。
管理端在 Ruoyi 框架的基础上,对菜单进行了修改,并添加了司机信息、车辆信息和车辆类型管理。
2025-07-08 20:04:14 +08:00

533 lines
19 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 碰撞避免系统数据处理模块设计文档
## 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方法的业务逻辑并提出了碰撞检测功能的设计方案。通过实现高效的碰撞检测算法、多级优化策略和完善的监控机制系统能够有效检测和预警潜在的碰撞风险为机场安全运行提供保障。
随着系统的持续优化和功能扩展,碰撞避免系统将能够应对更复杂的场景和更高的安全需求,实现从被动监测到主动避险的演进。