CollisionAvoidance/docs/design.md

1071 lines
25 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. 系统概述
### 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<PositionRecord> 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<Aircraft> getAircraftData() = 0;
virtual std::vector<Vehicle> 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<Vehicle> 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<ControllableVehicleConfig> 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<ControllableVehicleConfig> loadControllableVehicleConfig() {
std::vector<ControllableVehicleConfig> 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<std::string>();
config.ip = item["ip"].get<std::string>();
config.port = item["port"].get<int>();
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<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. 日志记录
- 记录测试过程
- 输出中间结果
- 便于问题诊断
## 11. 可控车辆通信
### 11.1 通信方式
使用 HTTP 协议与可控车辆通信:
- 碰撞检测系统作为 HTTP 客户端,向可控车辆发送 POST 请求
- 请求地址格式为: `http://<vehicle_ip>:<port>/command`
- 请求 Body 中包含控制指令的 JSON 表示
- 可控车辆作为 HTTP 服务器,接收并处理控制指令
### 11.2 指令格式
使用 JSON 格式表示控制指令:
```json
POST /command HTTP/1.1
Host: <vehicle_ip>:<port>
Content-Type: application/json
{
"command": "stop",
"timestamp": 1700123456
}
```
或者:
```json
POST /command HTTP/1.1
Host: <vehicle_ip>:<port>
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. 区域边界在局部坐标系中定义
如果需要计算角度(比如判断车辆朝向),则使用向量点积方法