- 架构文档: IDefenseAdvisor→IDefensePlanner 全量替换,架构图更新 - DefensePlanner: FireUnit模型补全通道/检测字段,数据流改为引擎内部调用 - 旧接口迁移表标记完成,实现状态分已实现/已删除/不变
1513 lines
62 KiB
Markdown
1513 lines
62 KiB
Markdown
# 反无人机仿真系统 — 总体架构设计
|
||
|
||
> **版本**:V9
|
||
> **日期**:2026-06-13
|
||
> **状态**:已实现
|
||
> **Unity 版本**:22.3.62
|
||
> **.NET 版本**:.NET Standard 2.1
|
||
> **变更**:DefensePlanner 五步规划引擎;FireUnit 通道模型;空基平台飞控;SQLite domain reload 修复;删除所有 fallback 默认值
|
||
|
||
---
|
||
|
||
## 一、系统概述
|
||
|
||
本系统对新型气溶胶武器的三种防空毁伤机制(吸入式灭火、爆燃式、吸入式爆炸)进行数字化仿真。通过参数化配置与可视化推演,量化评估新型气溶胶武器对不同类型空中威胁源目标(动力系统)的毁伤效能。
|
||
|
||
系统分为三大模块:
|
||
|
||
| 模块 | 核心功能 |
|
||
|------|----------|
|
||
| **模型管理** | 3D 模型导入/预览/删除,编组管理 |
|
||
| **想定管理** | 仿真任务 CRUD,步骤化配置向导,管控区域设置,搜索分页 |
|
||
| **仿真报告** | 报告列表,含时序图的完整报告预览,导出 PDF/Word,删除 |
|
||
|
||
### 要求来源对照
|
||
|
||
本设计融合两份需求文档:
|
||
|
||
| 文档 | 侧重 |
|
||
|------|------|
|
||
| V1.0 反无人机仿真系统功能需求 | UI 交互、业务流程、业务字段 |
|
||
| 技术要求终版 | 毁伤机制、装备体系、可视化效果、性能指标、第三方算法集成 |
|
||
|
||
---
|
||
|
||
## 二、架构分层
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────┐
|
||
│ Unity UI Layer │
|
||
│ 模型管理 │ 想定管理(含管控区域) │ 仿真运行&回放 │ 仿真报告 │
|
||
├──────────────────────────────────────────────────────────┤
|
||
│ Unity Application Layer │
|
||
│ ModelPanel | ScenarioWizard | SimulationRunner | │
|
||
│ ReplayController | ReportPanel | GroupManager │
|
||
├──────────────────────────────────────────────────────────┤
|
||
│ Service Layer (Pure C#) │
|
||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
|
||
│ │ ModelService │ │ScenarioService│ │ SimulationEngine │ │
|
||
│ │ GroupService │ │ DefensePlanner │ │ ├ DroneEntity │ │
|
||
│ └──────────────┘ └──────────────┘ │ ├ PlatformEntity │ │
|
||
│ ┌──────────────┐ ┌──────────────┐ │ ├ MunitionEntity │ │
|
||
│ │FrameDataStore│ │ReportService │ │ ├ CloudEntity │ │
|
||
│ │ │ │ ├ ReportGen │ │ │ └ GaussianPuff│ │
|
||
│ └──────────────┘ │ └ Markdown │ │ ├ ControlZone │ │
|
||
│ └──────────────┘ │ ├ IDamageModel×3 │ │
|
||
│ │ └ FireSchedule │ │
|
||
│ ┌──────────────────────────────────────────────────────┐│
|
||
│ │ Algorithm Layer (自主实现) ││
|
||
│ │ GaussianPuffDispersion | DamageCalculator ││
|
||
│ │ DefaultDefensePlanner | Kinematics(PG稳定度) ││
|
||
│ └──────────────────────────────────────────────────────┘│
|
||
├──────────────────────────────────────────────────────────┤
|
||
│ Data Layer │
|
||
│ ┌────────────────────────────┐ ┌────────────────────┐ │
|
||
│ │ main.db (SQLite) │ │ frames/ (SQLite) │ │
|
||
│ │ 11张业务表 + SimEvent │ │ 每任务一个 .db │ │
|
||
│ │ + SimulationReport │ │ SimFrameRecord │ │
|
||
│ │ < 100MB,永久保留 │ │ 6个月 TTL │ │
|
||
│ └────────────────────────────┘ └────────────────────┘ │
|
||
│ ┌────────────────────────────────────────────────────┐ │
|
||
│ │ FileSystem │ │
|
||
│ │ 模型文件(.fbx/.obj/.stl/.glb/.gltf) + 预览图 │ │
|
||
│ └────────────────────────────────────────────────────┘ │
|
||
└──────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 各层职责
|
||
|
||
| 层 | 依赖 | 职责 |
|
||
|----|------|------|
|
||
| **Data Layer** | 主库 SQLite + 任务分库 SQLite + 文件系统 | 主库存元数据/事件/报告(<100MB,永久保留);分库按任务存帧数据(6月TTL);文件系统存模型文件 |
|
||
| **Algorithm Layer** | 纯 C#,零外部依赖 | 气溶胶扩散模型、毁伤计算、防御推荐算法(全部自主实现) |
|
||
| **Service Layer** | Data Layer + Algorithm Layer | 纯业务逻辑、仿真引擎、录制、报告生成 |
|
||
| **Application Layer** | Service Layer + Unity | MonoBehaviour 桥接,生命周期协调,驱动仿真 |
|
||
| **UI Layer** | Application Layer | UGUI 页面、弹窗、3D 预览、回放、粒子参数传递 |
|
||
|
||
### 2.1 程序集拆分:Core 独立于 Unity
|
||
|
||
后端代码拆分为两个程序集,确保 Core 可脱离 Unity 独立编译和测试:
|
||
|
||
```
|
||
CounterDrone.Core.dll ← .NET Standard 2.1 类库
|
||
零 UnityEngine 引用
|
||
可在任何 .NET 环境运行
|
||
├── /Models 数据模型(POCO)
|
||
├── /Repository 数据访问(SQLite + 文件存储)
|
||
├── /Services 业务服务(ModelService, ScenarioService 等)
|
||
├── /Simulation 仿真引擎 + 实体(SimulationEngine, DroneEntity, ...)
|
||
└── /Algorithms 扩散模型、毁伤模型、防御推荐
|
||
|
||
CounterDrone.Core.Tests.dll ← xUnit 测试项目
|
||
直接引用 Core.dll
|
||
dotnet test 即可运行
|
||
├── /Unit 单元测试(每个类独立测)
|
||
└── /Integration 集成测试(完整仿真流程)
|
||
|
||
Unity 项目/Assets/Scripts/ ← Unity 侧
|
||
├── /Managers MonoBehaviours 桥接层(薄)
|
||
└── /UI UGUI 绑定
|
||
引用 → CounterDrone.Core.dll(放在 Assets/Plugins/)
|
||
```
|
||
|
||
### 2.2 Unity 依赖隔离:关键设计
|
||
|
||
| 隔离点 | 做法 |
|
||
|------|------|
|
||
| **时间** | `engine.Tick(float deltaTime)` — Unity 传 `Time.deltaTime`,测试传固定值 `0.05f` |
|
||
| **文件路径** | Core 使用接口 `IPathProvider` → Unity 实现返回 `Application.persistentDataPath`,测试返回 `./testdata/` |
|
||
| **日志** | Core 使用 `Microsoft.Extensions.Logging` 抽象 → Unity 桥接到 `Debug.Log`,测试用控制台 |
|
||
| **模型加载** | Core 不涉及 3D 渲染,只管理文件路径和元数据 |
|
||
| **粒子参数** | Core 输出 `ParticleParams` 数据对象 → Unity 读值设置 ParticleSystem |
|
||
|
||
### 2.3 Manager 桥接层示例(极薄)
|
||
|
||
```csharp
|
||
// Unity 侧 SimulationRunner.cs — 仅负责桥接
|
||
public class SimulationRunner : MonoBehaviour
|
||
{
|
||
private ISimulationEngine _engine;
|
||
private IRecordService _recorder;
|
||
|
||
void Start()
|
||
{
|
||
// 通过 DI 或工厂获取实例(Core 创建)
|
||
_engine = SimulationEngineFactory.Create(taskId);
|
||
_recorder = ServiceFactory.CreateRecordService();
|
||
}
|
||
|
||
void Update()
|
||
{
|
||
if (_engine.State != SimulationState.Running) return;
|
||
|
||
// 核心只有这一行:把 Unity 时间传入纯 C# 引擎
|
||
var result = _engine.Tick(Time.deltaTime);
|
||
|
||
// 更新 Unity 侧的 3D 物体位置(根据 result 中的实体快照)
|
||
UpdateVisuals(result.EntitySnapshots);
|
||
}
|
||
|
||
void UpdateVisuals(List<EntitySnapshot> snapshots)
|
||
{
|
||
foreach (var s in snapshots)
|
||
{
|
||
// 找到对应 GameObject,设置 transform
|
||
_entityMap[s.EntityId].transform.position = s.Position;
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2.4 测试策略
|
||
|
||
| 测试类型 | 工具 | 内容 |
|
||
|------|------|------|
|
||
| **单元测试** | xUnit + Moq | Repository 增删改查、Service 业务逻辑、Algorithm 计算正确性 |
|
||
| **仿真确定性测试** | xUnit | 固定输入 + 固定 deltaTime → 断言帧 N 的实体位置 = 预期值 |
|
||
| **集成测试** | xUnit + SQLite 文件 | 完整想定配置 → 启动仿真 → 跑 1000 帧 → 断言事件序列和对抗结果 |
|
||
| **性能测试** | BenchmarkDotNet | Tick() 单帧耗时 P99 < 5ms |
|
||
|
||
> Core 测试无需 Unity,`dotnet test` 即可运行全部测试,适合 CI 流水线。
|
||
|
||
---
|
||
|
||
## 三、枚举定义
|
||
|
||
```csharp
|
||
// === 任务 ===
|
||
enum TaskStatus { Draft = 0, Configuring = 1, Completed = 2 }
|
||
|
||
// === 场景 ===
|
||
enum SceneType { Urban = 0, Plain = 1, Mountain = 2, Coast = 3 }
|
||
enum WeatherType { Sunny = 0, Overcast = 1, Fog = 2, Rain = 3, Night = 4 }
|
||
enum WindDirection { N = 0, NE = 1, E = 2, SE = 3, S = 4, SW = 5, W = 6, NW = 7 }
|
||
|
||
// === 目标 ===
|
||
enum TargetType { Rotor = 0, FixedWing = 1, Electric = 2, Piston = 3, HighSpeed = 4 }
|
||
enum PowerType { Electric = 0, Piston = 1, Jet = 2 }
|
||
|
||
// === 装备 & 搭载平台 ===
|
||
enum PlatformType { AirBased = 0, GroundBased = 1 } // 空基(大型无人机) / 地基(炮弹)
|
||
enum EquipmentRole { Detection = 0, LaunchPlatform = 1 } // 装备角色:探测 / 发射平台
|
||
|
||
// === 气溶胶 & 毁伤 ===
|
||
enum AerosolType { InertGas = 0, ActiveMaterial = 1, ActiveFuel = 2 }
|
||
// 对应的毁伤机制名称:吸入式灭火 / 爆燃式 / 吸入式爆炸
|
||
enum ReleaseMode { Single = 0, Continuous = 1, Pulse = 2 }
|
||
enum TriggerMode { Time = 0, Area = 1, Manual = 2 }
|
||
|
||
// === 毁伤状态阶段(输出到 StateData 供 Unity 渲染)===
|
||
enum DamageStage { Normal = 0, EngineAnomaly = 1, AttitudeLoss = 2, Destroyed = 3 }
|
||
|
||
// === 编队 & 编组 ===
|
||
enum FormationMode { Single = 0, Formation = 1, Swarm = 2 }
|
||
enum GroupType { DroneFleet = 0, EquipmentGroup = 1 }
|
||
|
||
// === 运行时 ===
|
||
enum EntityType { Drone = 0, Platform = 1, DetectionEquip = 2, Cloud = 3, Munition = 4 }
|
||
enum EventType
|
||
{
|
||
TargetDetected = 0,
|
||
MunitionLaunched = 1,
|
||
CloudGenerated = 2,
|
||
DroneEnteredCloud = 3,
|
||
DroneDestroyed = 4,
|
||
DroneReachedTarget = 5,
|
||
ZoneIntruded = 6, // 无人机侵入管控区域
|
||
WaypointReached = 7,
|
||
SimulationEnd = 8
|
||
}
|
||
|
||
// === 报告 ===
|
||
enum InterceptResult { Success = 0, Partial = 1, Failed = 2 }
|
||
enum PositionMode { PointSelect = 0, ManualInput = 1 }
|
||
```
|
||
|
||
---
|
||
|
||
## 四、数据模型设计
|
||
|
||
### 4.1 存储架构:主库 + 任务分库
|
||
|
||
```
|
||
CounterDroneBackend_Data/
|
||
├── main.db ← 主库(< 100MB,永久保留)
|
||
│ ├── 11 张业务配置表
|
||
│ ├── SimEvent ← 事件表(~30 条/任务)
|
||
│ └── SimulationReport
|
||
│
|
||
├── frames/ ← 帧数据分库(6 个月 TTL)
|
||
│ ├── {taskId_001}.db ← 单任务 ~161 MB(30min 仿真)
|
||
│ └── {taskId_002}.db
|
||
│
|
||
└── models/ ← 模型文件 + 预览图
|
||
```
|
||
|
||
### 4.2 数据表总览
|
||
|
||
共 11 张业务表(主库) + 1 张运行时表(主库) + 1 张运行时表(任务分库):
|
||
|
||
```
|
||
主库(main.db)— 永久保留:
|
||
ModelInfo — 模型元数据
|
||
AmmunitionSpec — 弹药基础参数(第三方数据,NEW)
|
||
SimTask — 仿真任务主表
|
||
CombatScene — 步骤1:作战场景(含24h时间、天气)
|
||
ControlZone — 步骤1+:管控区域/电子围栏(NEW)
|
||
TargetConfig — 步骤2:目标配置
|
||
EquipmentDeployment — 步骤3:装备部署(搭载平台+探测设备)
|
||
CloudDispersal — 步骤4:云团抛撒配置
|
||
RoutePlan — 步骤5:航路规划(1:N SimTask,多编队)
|
||
Waypoint — 航路点
|
||
Group — 编组(独立管理)
|
||
SimulationReport — 仿真报告
|
||
SimEvent — 仿真事件(时序图数据源)
|
||
|
||
任务分库(frames/{taskId}.db)— 6 个月 TTL:
|
||
SimFrameRecord — 逐帧位置记录(回放用)
|
||
```
|
||
|
||
### 4.3 业务表详细设计
|
||
|
||
#### ModelInfo — 模型元数据
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| Id | TEXT | PK | GUID |
|
||
| Name | TEXT | NOT NULL | 模型名称 |
|
||
| ModelType | TEXT | | 分类标签 |
|
||
| FilePath | TEXT | | persistentDataPath 下的相对路径 |
|
||
| FileSize | REAL | | MB |
|
||
| PreviewPath | TEXT | | 预览图路径 |
|
||
| HasHighResTexture | INTEGER | DEFAULT 0 | 是否含 2K+ 贴图 |
|
||
| CreatedAt | TEXT | | 导入时间 ISO8601 |
|
||
|
||
> 支持格式:**.fbx / .obj / .stl / .glb / .gltf**,单文件 ≤ 500MB,支持 2K 及以上分辨率贴图。
|
||
|
||
#### SimTask — 仿真任务主表
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| Id | TEXT | PK | GUID |
|
||
| Name | TEXT | NOT NULL | 任务名称 |
|
||
| TaskNumber | TEXT | UNIQUE | SIM-yyyyMMdd-xxx |
|
||
| Status | INTEGER | DEFAULT 0 | 0=草稿 1=配置中 2=已完成 |
|
||
| CurrentStep | INTEGER | DEFAULT 1 | 当前配置步骤 1-5 |
|
||
| TickRate | INTEGER | DEFAULT 20 | 仿真 Tick 频率(Hz) |
|
||
| CreatedAt | TEXT | | |
|
||
| UpdatedAt | TEXT | | |
|
||
|
||
#### CombatScene — 步骤1:作战场景
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| TaskId | TEXT | PK, FK | 1:1 SimTask |
|
||
| SceneType | INTEGER | | 0城市 1平原 2山区 3海岸 |
|
||
| TimeOfDay | TEXT | DEFAULT "12:00" | **NEW** 24h 制时间,如 "14:30" |
|
||
| WeatherType | INTEGER | | 0晴 1阴 2雾 3雨 4夜 |
|
||
| WindSpeed | REAL | DEFAULT 5 | m/s,范围 0-30 |
|
||
| WindDirection | INTEGER | DEFAULT 0 | 八方位 0-7 |
|
||
| Temperature | REAL | DEFAULT 20 | ℃ |
|
||
| Humidity | REAL | DEFAULT 60 | %RH |
|
||
| Pressure | REAL | DEFAULT 1013 | hPa |
|
||
| Visibility | REAL | DEFAULT 5000 | m,范围 100-10000 |
|
||
| SceneWidth | REAL | DEFAULT 4000 | **NEW** 场景宽 m(≥4m) |
|
||
| SceneLength | REAL | DEFAULT 10000 | **NEW** 场景纵深 m(≥100m) |
|
||
| SceneHeight | REAL | DEFAULT 1000 | **NEW** 场景高 m(≥10m) |
|
||
|
||
> 场景空间范围最低要求:4m × 100m × 10m。默认值 4000m × 10000m × 1000m 可配置。
|
||
|
||
#### ControlZone — 步骤1扩展:管控区域 / 电子围栏(NEW)
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| Id | TEXT | PK | GUID |
|
||
| TaskId | TEXT | FK | |
|
||
| Name | TEXT | | 区域名称 |
|
||
| VerticesJson | TEXT | NOT NULL | 多边形顶点 JSON:`[{"x":0,"y":0,"z":0},...]` |
|
||
| MinAltitude | REAL | | 区域底高 m |
|
||
| MaxAltitude | REAL | | 区域顶高 m |
|
||
| OrderIndex | INTEGER | | 多个区域的顺序 |
|
||
|
||
> 管控区域在场景设置(地形+天气)之后配置。无人机进入管控区域 → 触发 ZoneIntruded 事件 → 该无人机任务失败。
|
||
|
||
#### TargetConfig — 步骤2:目标配置
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| Id | TEXT | PK | GUID |
|
||
| TaskId | TEXT | FK | |
|
||
| GroupId | TEXT | FK | 关联无人机编队 Group |
|
||
| TargetType | INTEGER | | 0旋翼 1固定翼 2电推 3活塞 4高速 |
|
||
| Quantity | INTEGER | DEFAULT 1 | 目标数量 |
|
||
| PowerType | INTEGER | | 0电推 1活塞 2喷吸气 |
|
||
| Wingspan | REAL | | m |
|
||
| TypicalSpeed | REAL | | km/h |
|
||
| TypicalAltitude | REAL | | m |
|
||
|
||
> 目标类型默认值:
|
||
|
||
| 目标类型 | 翼展(m) | 典型速度(km/h) | 典型飞行高度(m) |
|
||
|----------|---------|---------------|----------------|
|
||
| 旋翼 | 1.2 | 60 | 300 |
|
||
| 固定翼 | 3.5 | 150 | 1000 |
|
||
| 电推 | 1.8 | 100 | 500 |
|
||
| 活塞 | 2.5 | 120 | 800 |
|
||
| 高速目标 | 1.5 | 300 | 2000 |
|
||
|
||
#### EquipmentDeployment — 步骤3:装备部署(重构)
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| Id | TEXT | PK | GUID |
|
||
| TaskId | TEXT | FK | |
|
||
| EquipmentRole | INTEGER | | 0=探测设备 1=发射平台 |
|
||
| Quantity | INTEGER | DEFAULT 1 | 部署数量 |
|
||
| GroupId | TEXT | FK | 关联装备编组 Group(火力单元,多批次时用于分配) |
|
||
| // 以下为发射平台专用字段 |
|
||
| PlatformType | INTEGER | NULLABLE | 0=空基(大型无人机) 1=地基(炮弹),探测设备为 NULL |
|
||
| PositionX | REAL | | 部署位置 |
|
||
| PositionY | REAL | | |
|
||
| PositionZ | REAL | | |
|
||
| AerosolType | INTEGER | NULLABLE | 挂载气溶胶类型,探测设备为 NULL |
|
||
| MunitionCount | INTEGER | NULLABLE | 挂载弹药数量 |
|
||
| MuzzleVelocity | REAL | NULLABLE | **NEW** 弹药初速 m/s(地基炮弹用) |
|
||
| ReleaseAltitude | REAL | NULLABLE | **NEW** 弹药释放高度 m(空基平台用) |
|
||
| Cooldown | REAL | DEFAULT 5 | 发射冷却时间 s(同弹种连发间隔) |
|
||
| AmmoChangeTime | REAL | DEFAULT 300 | **NEW** 更换弹种所需时间 s(默认 5 分钟) |
|
||
| // 以下为探测设备专用字段 |
|
||
| DetectionRadius | REAL | NULLABLE | 探测半径 m |
|
||
|
||
> **装备体系说明**:
|
||
> - **搭载平台**(2 种):
|
||
> - 空基(大型无人机):飞到释放点投放弹药 → 弹药自由落体/滑翔至云团生成点
|
||
> - 地基(炮弹):地面发射 → 抛物线弹道 → 到达释放点生成云团
|
||
> - **探测设备**:目标搜索发现与跟踪,输出目标坐标给发射平台
|
||
> - 弹药类型决定生成云团的 AerosolType 和覆盖体积
|
||
|
||
#### CloudDispersal — 步骤4:云团抛撒配置
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| TaskId | TEXT | PK, FK | 1:1 SimTask |
|
||
| AerosolType | INTEGER | | 0吸入式灭火 1爆燃式 2吸入式爆炸 |
|
||
| DisperseHeight | REAL | DEFAULT 300 | m |
|
||
| TriggerMode | INTEGER | | 0时间 1区域 2手动 |
|
||
| SpreadAngle | REAL | DEFAULT 0 | 度 |
|
||
| ReleaseMode | INTEGER | | 0单次 1连续 2脉冲 |
|
||
| InitialScale | REAL | DEFAULT 1000 | m³ |
|
||
| Duration | REAL | DEFAULT 60 | s |
|
||
| ReleaseInterval | REAL | DEFAULT 5 | s |
|
||
| TotalAmount | REAL | DEFAULT 50 | kg |
|
||
| PositionX | REAL | | 抛撒坐标 |
|
||
| PositionY | REAL | | |
|
||
| PositionZ | REAL | | |
|
||
| PositionMode | INTEGER | | 0三维点选 1手动输入 2算法推荐(NEW) |
|
||
| // 算法推荐结果(NEW) |
|
||
| RecommendedPosX | REAL | NULLABLE | 算法推荐最佳抛撒位置 |
|
||
| RecommendedPosY | REAL | NULLABLE | |
|
||
| RecommendedPosZ | REAL | NULLABLE | |
|
||
| RecommendedTiming | REAL | NULLABLE | 算法推荐最佳触发时机(仿真秒) |
|
||
| CriticalPosX | REAL | NULLABLE | 最危险值—抛撒位置 |
|
||
| CriticalPosY | REAL | NULLABLE | |
|
||
| CriticalPosZ | REAL | NULLABLE | |
|
||
| CriticalTiming | REAL | NULLABLE | 最危险值—触发时机 |
|
||
|
||
#### RoutePlan — 步骤5:航路规划
|
||
|
||
> **支持多批次**:通过 `TaskId + GroupId` 唯一标识一条航路,一个任务可有多个编队各自独立航路。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| TaskId | TEXT | PK(复合) | |
|
||
| GroupId | TEXT | PK(复合), FK → Group | 关联编队:同一任务不同编队可有独立航路 |
|
||
| FormationMode | INTEGER | | 0单机 1编队 2蜂群 |
|
||
| FormationSpacing | REAL | DEFAULT 50 | m |
|
||
| ETA | TEXT | | 预计到达时间 |
|
||
|
||
#### Waypoint — 航路点
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| Id | TEXT | PK | GUID |
|
||
| TaskId | TEXT | FK | |
|
||
| OrderIndex | INTEGER | NOT NULL | 航路顺序 |
|
||
| PosX | REAL | | 坐标(支持三维点选) |
|
||
| PosY | REAL | | |
|
||
| PosZ | REAL | | |
|
||
| Altitude | REAL | | 该航点飞行高度 m |
|
||
| Speed | REAL | | 该段速度 km/h |
|
||
|
||
#### Group — 编组
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| Id | TEXT | PK | GUID |
|
||
| Name | TEXT | NOT NULL | 编组名称 |
|
||
| GroupType | INTEGER | | 0=无人机编队 1=装备编组 |
|
||
| Description | TEXT | | 备注 |
|
||
| CreatedAt | TEXT | | |
|
||
|
||
### 4.4 运行时表
|
||
|
||
> **注意**:SimEvent 和 SimulationReport 存储在主库 main.db;SimFrameRecord 存储在各任务的独立分库 frames/{taskId}.db 中。
|
||
|
||
#### SimFrameRecord — 逐帧记录
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| Id | INTEGER | PK AUTOINCREMENT | |
|
||
| TaskId | TEXT | FK | |
|
||
| FrameIndex | INTEGER | | 帧序号 |
|
||
| Timestamp | REAL | | 仿真时间(秒) |
|
||
| EntityId | TEXT | | |
|
||
| EntityType | INTEGER | | 实体类型枚举 |
|
||
| PosX | REAL | | |
|
||
| PosY | REAL | | |
|
||
| PosZ | REAL | | |
|
||
| RotX | REAL | | |
|
||
| RotY | REAL | | |
|
||
| RotZ | REAL | | |
|
||
| StateData | TEXT | | JSON,包含:DestroyStage、CloudRadius、CloudColor 等 |
|
||
|
||
> StateData JSON 结构(供 Unity 粒子系统 & 毁伤渲染):
|
||
> ```json
|
||
> {
|
||
> "damageStage": 0, // DamageStage 枚举
|
||
> "hp": 0.75, // 剩余血量 0~1
|
||
> "cloudRadius": 150.0, // 云团当前半径 m(CloudEntity)
|
||
> "cloudOpacity": 0.8, // 云团透明度(CloudEntity)
|
||
> "cloudColor": "#AABBCC", // 云团颜色(CloudEntity)
|
||
> "particleEmitRate": 500 // 粒子发射率(CloudEntity)
|
||
> }
|
||
> ```
|
||
|
||
#### SimEvent — 仿真事件(时序图数据源)
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| Id | TEXT | PK | GUID |
|
||
| TaskId | TEXT | FK | |
|
||
| OccurredAt | REAL | | 仿真时间(秒) |
|
||
| EventType | INTEGER | | 事件类型枚举 |
|
||
| SourceId | TEXT | | 源实体 ID |
|
||
| TargetId | TEXT | | 目标实体 ID |
|
||
| DataJson | TEXT | | 事件携带的结构化数据 |
|
||
| Description | TEXT | | 事件描述 |
|
||
|
||
---
|
||
|
||
## 五、仿真引擎设计
|
||
|
||
### 5.1 核心实体关系
|
||
|
||
```
|
||
SimulationEngine
|
||
│
|
||
├── SimulationState ← 状态(运行/暂停/结束)
|
||
├── SceneConfig ← 配置快照(含场景边界、管控区域)
|
||
├── List<DroneEntity> ← 无人机(目标方)
|
||
│ └── 按编组组织,共享航路
|
||
├── List<PlatformEntity> ← 搭载平台(发射方)★重构
|
||
│ ├── AirBasedPlatform ← 空基(大型无人机)
|
||
│ └── GroundBasedPlatform ← 地基(火炮)
|
||
├── List<DetectionEntity> ← 探测设备
|
||
├── List<MunitionEntity> ← 飞行中的弹药
|
||
│ ├── 空基投放:短程自由落体/滑翔
|
||
│ └── 地基发射:抛物线弹道
|
||
├── List<CloudEntity> ← 气溶胶云团 ★核心毁伤载体★
|
||
│ └── GaussianPuffDispersion(三阶段扩散)
|
||
├── List<ControlZone> ← 管控区域(电子围栏)
|
||
├── FireSchedule ← 发射计划(推荐算法生成)
|
||
└── FrameDataStore ← 帧数据写入(任务分库)
|
||
```
|
||
|
||
### 5.2 拦截链路(完整流程)
|
||
|
||
```
|
||
探测设备扫描
|
||
│ 发现目标 → 输出目标坐标
|
||
▼
|
||
火控分配(分配给可用搭载平台)
|
||
│
|
||
├── 空基平台:飞至投放点
|
||
│ │
|
||
│ ▼
|
||
│ 投放弹药(自由落体/滑翔至云团生成点)
|
||
│
|
||
└── 地基平台:计算射击诸元
|
||
│
|
||
▼
|
||
发射炮弹(抛物线弹道飞向目标区域)
|
||
│
|
||
▼
|
||
弹药到达释放点 → 生成 CloudEntity
|
||
MunitionEntity 销毁
|
||
│
|
||
▼
|
||
云团扩散膨胀(三阶段模型:爆轰→湍流→高斯)
|
||
│ 持续膨胀 + 消散计时
|
||
▼
|
||
无人机进入云团范围
|
||
│ 施加毁伤(IDamageModel 接口,三种机制自主实现)
|
||
│ 吸入式灭火 / 爆燃式 / 吸入式爆炸
|
||
▼
|
||
无人机被摧毁 / 存活
|
||
│ 毁伤阶段状态输出到 StateData
|
||
▼
|
||
Unity 渲染毁伤效果(尾焰异常、姿态失控、坠落)
|
||
```
|
||
|
||
### 5.3 仿真 Tick 流程
|
||
|
||
```
|
||
1. 【发射阶段】
|
||
按 FireSchedule 执行:
|
||
├─ SimulationTime ≥ FireTime → 平台发射弹药
|
||
└─ 触发 OnMunitionLaunched 事件
|
||
|
||
2. 【弹药飞行 → 云团生成】
|
||
FOR EACH MunitionEntity:
|
||
├─ 抛物线弹道 / 自由落体
|
||
└─ 到达释放高度 → 生成 CloudEntity → 触发 OnCloudGenerated
|
||
|
||
3. 【云团演化】
|
||
FOR EACH CloudEntity:
|
||
├─ GaussianPuffDispersion.Tick():三阶段扩散
|
||
├─ 更新粒子参数(半径、透明度 → 写入 StateData)
|
||
└─ 消散条件满足 → 移除
|
||
|
||
4. 【毁伤判定】
|
||
FOR EACH DroneEntity × CloudEntity:
|
||
├─ 无人机坐标 ∈ 云团有效范围?
|
||
├─ 是 → IDamageModel.CalculateDamage()
|
||
├─ drone.HP -= damage
|
||
└─ HP ≤ 0 → 触发 OnDroneDestroyed
|
||
|
||
5. 【无人机移动】
|
||
FOR EACH 存活 DroneEntity:
|
||
├─ 沿航路点线性插值
|
||
├─ 风偏影响
|
||
└─ 到达终点 → 触发 OnDroneReachedTarget
|
||
|
||
6. 【平台冷却】
|
||
FOR EACH PlatformEntity:Cooldown -= dt
|
||
|
||
7. 【管控区域判定】
|
||
FOR EACH 存活 DroneEntity:
|
||
├─ Point-in-Polygon 判定
|
||
└─ 侵入 → 触发 OnZoneIntruded
|
||
|
||
8. 【结束判定】
|
||
所有无人机 Status ≠ Flying → 触发 OnSimulationEnded
|
||
|
||
9. 【结束判定】
|
||
├─ 所有无人机 (被摧毁 OR 到达目标 OR 侵入管控区) → SimulationEnd
|
||
├─ 停止录制
|
||
└─ 更新 SimulationState
|
||
```
|
||
|
||
### 5.4 实体行为模型
|
||
|
||
#### DroneEntity(无人机)
|
||
|
||
```
|
||
属性:
|
||
- 编组 GroupId、航路点队列 Waypoint[]
|
||
- 当前位置、速度、朝向
|
||
- HP(0~1 归一化)
|
||
- DamageStage(Normal → EngineAnomaly → AttitudeLoss → Destroyed)
|
||
- 目标类型 TargetType、动力类型 PowerType
|
||
- 存活状态(飞行中/抵达目标/侵入管控区/被摧毁)
|
||
|
||
运动模型(简化运动学):
|
||
- 两航路点之间线性插值
|
||
- 实际位移 = 航向位移 + 风速矢量 × deltaTime
|
||
- 到达判定:||currentPos - waypointPos|| < 1m
|
||
|
||
结束条件(任一触发即该无人机结束):
|
||
- 被毁伤(HP ≤ 0)→ Destroyed
|
||
- 到达攻击目标 → ReachedTarget
|
||
- 侵入管控区域 → ZoneIntruded
|
||
```
|
||
|
||
#### PlatformEntity(搭载平台)★重构
|
||
|
||
```
|
||
空基平台(AirBasedPlatform):
|
||
- 位置(动态,飞向投放点)
|
||
- 挂载弹药类型 AerosolType、数量 MunitionCount
|
||
- 释放高度 ReleaseAltitude
|
||
- 冷却计时器
|
||
- 行为:接收目标坐标 → 计算拦截航路 → 飞至投放点 → 投放弹药
|
||
|
||
地基平台(GroundBasedPlatform):
|
||
- 固定位置
|
||
- 弹药初速 MuzzleVelocity
|
||
- 挂载弹药类型 AerosolType、数量 MunitionCount
|
||
- 冷却计时器
|
||
- 行为:接收目标坐标 → 计算射击诸元 → 发射炮弹
|
||
```
|
||
|
||
#### MunitionEntity(飞行中弹药)★重构
|
||
|
||
```
|
||
属性:
|
||
- 弹药类型 AerosolType
|
||
- 发射方式 LaunchMode(AirDrop / GroundArtillery)
|
||
- 当前位置、速度
|
||
- 目标坐标(云团生成点)
|
||
|
||
行为(两种弹道):
|
||
- AirDrop(空基投放):
|
||
初始位置 = 投放点,初始速度 = 平台速度
|
||
运动 = 自由落体 + 水平惯性(简化)
|
||
到达条件 = 当前位置.Z ≤ 云团生成高度
|
||
|
||
- GroundArtillery(地基炮弹):
|
||
初始位置 = 发射点,初始速度 = MuzzleVelocity
|
||
运动 = 抛物线弹道
|
||
x(t) = x0 + v0*cos(θ)*cos(φ)*t
|
||
y(t) = y0 + v0*cos(θ)*sin(φ)*t
|
||
z(t) = z0 + v0*sin(θ)*t - 0.5*g*t²
|
||
到达条件 = z(t) ≤ 云团生成高度
|
||
```
|
||
|
||
#### CloudEntity(气溶胶云团)
|
||
|
||
```
|
||
属性:
|
||
- 气溶胶类型 AerosolType
|
||
- 中心坐标
|
||
- 当前半径(调用第三方 DLL 扩散模型计算)
|
||
- 最大半径
|
||
- 持续时间、剩余时间
|
||
- 粒子系统参数(半径、透明度、颜色 → 输出到 StateData)
|
||
|
||
行为(委托第三方 DLL):
|
||
- 扩散膨胀:GaussianPuffDispersion.Tick()(三阶段)
|
||
- 消散计时
|
||
- 毁伤判定:IDamageModel.CalculateDamage()(三种机制自主实现)
|
||
```
|
||
|
||
---
|
||
|
||
## 六、算法设计 — 接口驱动 & 可替换架构 ★关键
|
||
|
||
### 设计原则
|
||
|
||
所有算法组件通过**接口隔离**,SimulationEngine 只依赖接口,不感知具体实现。每个算法组件可独立替换为第三方实现,无需修改引擎代码。
|
||
|
||
```
|
||
SimulationEngine
|
||
│
|
||
┌─────┼─────┐
|
||
▼ ▼ ▼
|
||
ICloudDispersionModel ← 扩散模型接口
|
||
IDamageModel ← 毁伤模型接口
|
||
IDefensePlanner ← 防御规划接口
|
||
│
|
||
┌───────┼───────┐
|
||
▼ ▼ ▼
|
||
自主实现 第三方实现 混合(部分自研+部分外购)
|
||
(Default) (Future) (Future)
|
||
```
|
||
|
||
### 6.1 算法工厂与注册
|
||
|
||
```csharp
|
||
/// <summary>算法工厂 — 统一管理所有算法组件的创建与替换</summary>
|
||
public static class AlgorithmFactory
|
||
{
|
||
// 注册表:每个接口 → 实现类型
|
||
private static readonly Dictionary<Type, Type> _registry = new()
|
||
{
|
||
{ typeof(ICloudDispersionModel), typeof(GaussianPuffDispersion) },
|
||
{ typeof(IDamageModel), typeof(DamageModelRouter) },
|
||
{ typeof(IDefensePlanner), typeof(DefaultDefensePlanner) },
|
||
};
|
||
|
||
/// <summary>替换某个算法实现(第三方接入点)</summary>
|
||
public static void Register<TInterface, TImpl>() where TImpl : TInterface
|
||
{
|
||
_registry[typeof(TInterface)] = typeof(TImpl);
|
||
}
|
||
|
||
/// <summary>创建实例,SimulationEngine 统一调用此方法</summary>
|
||
public static T Create<T>(params object[] args)
|
||
{
|
||
var implType = _registry[typeof(T)];
|
||
return (T)Activator.CreateInstance(implType, args);
|
||
}
|
||
}
|
||
```
|
||
|
||
> **替换示例**:将来第三方提供 `ThirdPartyDispersion.dll`,只需一行:
|
||
> `AlgorithmFactory.Register<ICloudDispersionModel, ThirdPartyDispersion>();`
|
||
> 无需改动 SimulationEngine 任何代码。
|
||
|
||
### 6.2 第三方提供的数据
|
||
|
||
```csharp
|
||
/// <summary>第三方提供的弹药基础参数(数据配置,非运行时 DLL)</summary>
|
||
public class AmmunitionSpec
|
||
{
|
||
public AerosolType AerosolType; // 气溶胶类型
|
||
public string Name; // 弹药名称
|
||
|
||
// 初始扩散状态
|
||
public float InitialRadius; // 初始云团半径(m)
|
||
public float InitialVolume; // 初始云团体积(m³)
|
||
public float CoreDensity; // 核心密度(kg/m³)
|
||
public float EdgeDensity; // 边缘密度(kg/m³)
|
||
public float InitialTemperature; // 初始温度(K)
|
||
public float BuoyancyFactor; // 浮力系数
|
||
|
||
// 弹药基础参数
|
||
public float EffectiveConcentration; // 有效毁伤浓度阈值(kg/m³)
|
||
public float DispersionRateBase; // 基础扩散速率(m/s)
|
||
public float MaxRadius; // 最大有效半径(m)
|
||
public float MaxDuration; // 最大持续时间(s)
|
||
public ParticleRenderParams Particles; // 粒子渲染参数
|
||
}
|
||
```
|
||
|
||
> 第三方以 JSON 配置文件形式交付 `AmmunitionSpec` 数组,系统启动时加载到 SQLite `AmmunitionSpec` 表。
|
||
|
||
### 6.2.1 系统内置默认值(第三方提供前使用)
|
||
|
||
基于 155mm 炮弹载荷的物理合理估计:
|
||
|
||
| 参数 | 惰性气体弹 | 活性材料弹 | 活性燃料弹 |
|
||
|------|------|------|------|
|
||
| 药剂质量 (SourceStrength) | 10 kg | 12 kg | 10 kg |
|
||
| 爆发药 TNT 当量 (BurstChargeKg) | 1.5 kg | 4.0 kg | 1.5 kg |
|
||
| 有效浓度阈值 (EffectiveConcentration) | 0.0001 kg/m³ | 0.0002 kg/m³ | 0.0001 kg/m³ |
|
||
| 湍流扩散系数 (TurbulentExpansionK) | 3.0 | 4.0 | 3.0 |
|
||
| 最大半径 (MaxRadius) | 100 m | 80 m | 90 m |
|
||
| 最大持续时间 (MaxDuration) | 120 s | 90 s | 100 s |
|
||
| Phase 1 初始半径 (R₀) | 3.75 m | 5.14 m | 3.75 m |
|
||
|
||
> **数据来源**:10kg烟幕剂,抛射药/烟幕剂质量比 5%-20%,TNT当量取 1.5kg(典型值)。活性材料弹取爆炸分散型上限 4kg。
|
||
|
||
### 6.3 扩散模型设计 — 高斯烟团模型(Gaussian Puff)V2
|
||
|
||
#### 6.3.1 模型选择
|
||
|
||
采用**高斯烟团扩散模型**,使用**Pasquill-Gifford 稳定度分类**计算扩散系数 σ。
|
||
|
||
#### 6.3.2 大气稳定度映射
|
||
|
||
从天气类型和风速推导稳定度等级,无需额外参数:
|
||
|
||
| 天气 | 风速 | 稳定度 | 太阳辐射 | 湍流 |
|
||
|------|------|------|------|------|
|
||
| 晴天 | ≤ 5 m/s | A(极不稳定) | 强 | 强 |
|
||
| 晴天 | > 5 m/s | B(不稳定) | 中 | 中 |
|
||
| 阴天 | 任意 | D(中性) | 弱 | 中 |
|
||
| 雨天 | 任意 | D(中性) | 弱 | 中 |
|
||
| 雾天 | 任意 | E(稳定) | 无 | 弱 |
|
||
| 夜间 | 任意 | F(极稳定) | 无 | 最弱 |
|
||
|
||
#### 6.3.3 σ 扩散系数(Pasquill-Gifford)
|
||
|
||
扩散距离 x 米后,水平扩散系数 σ_y、垂直扩散系数 σ_z(单位 m):
|
||
|
||
| 稳定度 | σ_y | σ_z |
|
||
|------|------|------|
|
||
| A | 0.22x / (1+0.0001x)^0.5 | 0.20x |
|
||
| B | 0.16x / (1+0.0001x)^0.5 | 0.12x |
|
||
| C | 0.11x / (1+0.0001x)^0.5 | 0.08x / (1+0.0002x)^0.5 |
|
||
| D | 0.08x / (1+0.0001x)^0.5 | 0.06x / (1+0.0015x)^0.5 |
|
||
| E | 0.06x / (1+0.0001x)^0.5 | 0.03x / (1+0.0003x)^0.5 |
|
||
| F | 0.04x / (1+0.0001x)^0.5 | 0.016x / (1+0.0003x)^0.5 |
|
||
|
||
> 对于瞬时释放的烟团(Puff),扩散距离 x 取云团中心随风漂移的距离:x = u × t,其中 u 为风速,t 为经过时间。若风速为 0,取 x ≈ 1m(纯湍流扩散)。
|
||
|
||
#### 6.3.4 浓度场公式
|
||
|
||
云团内任意点 (x, y, z) 在时刻 t 的浓度:
|
||
|
||
```
|
||
C(x, y, z, t) = ────────────── × exp[ -½( (x-ut)/σy )² ]
|
||
(2π)^(3/2) σy σy σz
|
||
× exp[ -½( y/σy )² ]
|
||
× { exp[ -½( (z-H)/σz )² ] + exp[ -½( (z+H)/σz )² ] }
|
||
|
||
其中:
|
||
Q = 源强(释放物质总量,kg),来自 AmmunitionSpec
|
||
u = 风速(m/s)
|
||
H = 有效释放高度(m)
|
||
σy, σz = 扩散系数(由 6.3.2 和 6.3.3 确定)
|
||
```
|
||
|
||
#### 6.3.5 可判定指标
|
||
|
||
| 指标 | 计算 | 说明 |
|
||
|------|------|------|
|
||
| 中心浓度 | C_max = Q / [(2π)^(3/2) σy² σz] | 云团最浓处 |
|
||
| 有效半径 | R_eff = min{ r | C(中心, r) < C_threshold } | 浓度超过阈值的范围 |
|
||
| 消散条件 | C_max < C_threshold / 10 或 经过时间 > MaxDuration | 浓度可忽略 |
|
||
|
||
> **简化**:实时判定时,无人机位于云团内当且仅当 C(无人机坐标) ≥ EffectiveConcentration。不需要球体假设,直接用高斯公式计算。
|
||
|
||
#### 6.3.6 AmmunitionSpec 调整
|
||
|
||
| 字段 | 变更 | 说明 |
|
||
|------|------|------|
|
||
| `DispersionRateBase` | ❌ 删除 | 由 PG 稳定度代替 |
|
||
| `InitialRadius` | 保留 | 仍作初始 σ 参考 |
|
||
| `SourceStrength` | ✅ 新增 | 源强 Q(kg),取代线性模型 |
|
||
|
||
> 浓度 C 的单位为 kg/m³,无人机是否受损取决于 C ≥ EffectiveConcentration。
|
||
|
||
#### 6.3.7 接口(不变)
|
||
|
||
```csharp
|
||
public interface ICloudDispersionModel
|
||
{
|
||
void Initialize(AmmunitionSpec ammo, CombatScene env, Vector3 releasePos, float releaseTime);
|
||
void Tick(float deltaTime, float windSpeed, WindDirection windDir);
|
||
Vector3 Center { get; }
|
||
float Radius { get; }
|
||
float CoreDensity { get; }
|
||
float EffectiveRadius { get; }
|
||
ParticleParams Particles { get; }
|
||
bool IsDissipated { get; }
|
||
}
|
||
```
|
||
|
||
### 6.4 毁伤模型设计
|
||
|
||
三种气溶胶对应三种毁伤机制,我们自主实现:
|
||
|
||
#### 6.4.1 共同接口
|
||
|
||
```csharp
|
||
public interface IDamageModel
|
||
{
|
||
/// <summary>每 Tick 计算毁伤值</summary>
|
||
/// <param name="droneType">目标类型</param>
|
||
/// <param name="powerType">动力类型(影响毁伤效率)</param>
|
||
/// <param name="aerosolType">气溶胶类型</param>
|
||
/// <param name="cloudDensity">当前位置云团密度(kg/m³)</param>
|
||
/// <param name="exposureTime">累计暴露时间(s)</param>
|
||
/// <param name="deltaTime">本次 Tick 时长</param>
|
||
/// <returns>本次毁伤值(0~1 归一化)</returns>
|
||
float CalculateDamage(TargetType droneType, PowerType powerType,
|
||
AerosolType aerosolType, float cloudDensity,
|
||
float exposureTime, float deltaTime);
|
||
|
||
DamageStage GetDamageStage(float accumulatedDamage);
|
||
}
|
||
```
|
||
|
||
#### 6.4.2 三种机制的差异
|
||
|
||
| 机制 | 气溶胶类型 | 毁伤原理 | 毁伤曲线特征 |
|
||
|------|------|------|------|
|
||
| **吸入式灭火** | 惰性气体 | 发动机吸入惰性气体 → 氧气浓度下降 → 熄火 | 阈值型:密度达标后快速生效,延迟短 |
|
||
| **爆燃式** | 活性材料 | 材料接触高温发动机表面 → 化学反应爆燃 | 触发型:密度 + 温度双条件,瞬间高伤害 |
|
||
| **吸入式爆炸** | 活性燃料 | 燃料被吸入进气道 → 内部爆炸 | 累积型:随暴露时间指数增长 |
|
||
|
||
```csharp
|
||
// 实现示例伪代码
|
||
|
||
// 吸入式灭火:阈值判定
|
||
class InertGasDamageModel : IDamageModel
|
||
{
|
||
float CalculateDamage(...) {
|
||
if (cloudDensity < effectiveThreshold) return 0; // 浓度不够,无伤害
|
||
// 超过阈值后,线性累积毁伤
|
||
return damageRate * deltaTime;
|
||
}
|
||
}
|
||
|
||
// 爆燃式:瞬时触发
|
||
class ActiveMaterialDamageModel : IDamageModel
|
||
{
|
||
float CalculateDamage(...) {
|
||
if (cloudDensity < triggerThreshold) return 0;
|
||
if (!triggered) { triggered = true; return burstDamage; } // 一次性爆发
|
||
return residualDamage * deltaTime; // 后续余伤
|
||
}
|
||
}
|
||
|
||
// 吸入式爆炸:指数累积
|
||
class ActiveFuelDamageModel : IDamageModel
|
||
{
|
||
float CalculateDamage(...) {
|
||
if (cloudDensity < effectiveThreshold) return 0;
|
||
// 累积暴露 → 指数增长
|
||
return baseRate * Mathf.Exp(exposureTime * factor) * deltaTime;
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 6.4.3 毁伤阶段判定
|
||
|
||
```
|
||
accumulatedDamage: 0.0 ─────── 0.25 ─────── 0.6 ─────── 1.0
|
||
DamageStage: Normal EngineAnomaly AttitudeLoss Destroyed
|
||
|
||
Normal: 正常运行
|
||
EngineAnomaly: 发动机异常(Unity: 尾焰变色/不稳定)
|
||
AttitudeLoss: 姿态失控(Unity: 偏航/滚转)
|
||
Destroyed: 被摧毁(Unity: 坠落动画)
|
||
```
|
||
|
||
### 6.5 防御推荐算法设计
|
||
|
||
#### 6.5.1 Step A:气溶胶选型
|
||
|
||
基于**规则匹配**,根据目标动力类型推荐最佳毁伤机制:
|
||
|
||
| 目标动力 | 推荐气溶胶 | 理由 |
|
||
|------|------|------|
|
||
| 电推式 | 惰性气体(吸入式灭火) | 电动机无高温,爆燃/爆炸不适用;惰性气体使电调/散热失效 |
|
||
| 活塞式 | 惰性气体(吸入式灭火) | 活塞发动机依赖氧气,窒息最有效 |
|
||
| 喷吸气式 | 活性材料(爆燃式) | 喷气发动机高温表面触发爆燃 |
|
||
| — | 活性燃料(吸入式爆炸) | 适用于高价值高速目标,追求一击必杀 |
|
||
|
||
```csharp
|
||
// 选型规则表(可配置)
|
||
static readonly Dictionary<PowerType, AerosolType> MatchTable = new()
|
||
{
|
||
{ PowerType.Electric, AerosolType.InertGas },
|
||
{ PowerType.Piston, AerosolType.InertGas },
|
||
{ PowerType.Jet, AerosolType.ActiveMaterial },
|
||
};
|
||
```
|
||
|
||
#### 6.5.2 Step B:云团参数推荐 — 时空交汇优化
|
||
|
||
```
|
||
问题:
|
||
输入 = 目标航路 R(t)、风速 Vw、搭载平台位置 Pp、弹药飞行时间 Tf
|
||
输出 = 最优抛撒位置 Ps 和触发时机 Ts
|
||
|
||
方法:
|
||
1. 将目标航路离散为时间点 t₁, t₂, ..., tₙ
|
||
2. 对每个 tᵢ:
|
||
a. 无人机位置 = R(tᵢ)
|
||
b. 考虑炮弹飞行时间 Tf,抛撒时刻 = tᵢ - Tf
|
||
c. 云团在 [tᵢ - Tf, tᵢ - Tf + Duration] 内的扩散范围
|
||
d. 计算交汇窗口 = 无人机航路 ∩ 云团扩散范围的时空重叠
|
||
3. 选择交汇窗口最大的 (Ps, Ts) 作为最佳值
|
||
4. 选择交汇窗口刚好有效的边界作为最危险值
|
||
|
||
简化实现:
|
||
- 云团近似为匀速膨胀球体
|
||
- 无人机匀速直线飞行(取平均速度)
|
||
- 解析解:计算无人机航迹与云团膨胀球面的两个交点
|
||
- 最佳 = 无人机在云团中时间最长
|
||
- 最危险 = 无人机刚好擦边
|
||
```
|
||
|
||
#### 6.5.3 Step C:反推平台部署
|
||
|
||
```
|
||
根据云团方案反推:
|
||
|
||
Q: 需要覆盖多大面积?
|
||
→ 根据目标数量、编队间距、航路宽度 → 需要的云团数
|
||
|
||
Q: 每个云团需要多少弹药?
|
||
→ 云团体积 / 单发覆盖体积 → 弹药数
|
||
|
||
Q: 用什么平台?
|
||
→ 抛撒点距目标 > 平台航程?→ 地基
|
||
→ 抛撒点距目标 ≤ 平台航程?→ 空基
|
||
→ 根据弹药初速 / 飞行时间校验可行性
|
||
|
||
Q: 探测设备需要多大半径?
|
||
→ 探测半径 ≥ 从平台发现目标到完成拦截期间目标飞过的距离
|
||
```
|
||
|
||
#### 6.5.4 接口
|
||
|
||
```csharp
|
||
// === 防御规划 ===
|
||
public interface IDefensePlanner
|
||
{
|
||
PlannerResult Plan(List<FireUnit> fireUnits, List<DroneGroup> threats, CombatScene environment);
|
||
}
|
||
|
||
// ThreatProfile / DefenseRecommendation / DefenseSolution 等模型见本节上文
|
||
```
|
||
|
||
### 6.6 新增数据表:AmmunitionSpec
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| Id | TEXT | PK | GUID |
|
||
| AerosolType | INTEGER | | 气溶胶类型 |
|
||
| Name | TEXT | | 弹药名称 |
|
||
| InitialRadius | REAL | | 初始云团半径 m |
|
||
| InitialVolume | REAL | | 初始云团体积 m³ |
|
||
| CoreDensity | REAL | | 核心密度 kg/m³ |
|
||
| EdgeDensity | REAL | | 边缘密度 kg/m³ |
|
||
| InitialTemperature | REAL | | 初始温度 K |
|
||
| BuoyancyFactor | REAL | | 浮力系数 |
|
||
| EffectiveConcentration | REAL | | 有效毁伤浓度阈值 |
|
||
| DispersionRateBase | REAL | | 基础扩散速率 m/s |
|
||
| MaxRadius | REAL | | 最大有效半径 m |
|
||
| MaxDuration | REAL | | 最大持续时间 s |
|
||
| ParticlesJson | TEXT | | 粒子渲染参数 JSON |
|
||
|
||
> 第三方以 JSON 文件交付,导入到此表。系统启动时若表为空则从默认配置文件加载。
|
||
|
||
### 6.7 算法替换完整示例
|
||
|
||
以下是将来用第三方 DLL 替换扩散模型的完整流程,演示接口驱动架构的灵活性:
|
||
|
||
```
|
||
┌─ 步骤 1:第三方提供实现 ─────────────────────────────┐
|
||
│ │
|
||
│ ThirdPartyDispersion.dll │
|
||
│ └─ class ThirdPartyPuff : ICloudDispersionModel │
|
||
│ { │
|
||
│ void Initialize(AmmunitionSpec, ...) → P/Invoke → native_init()
|
||
│ void Tick(float, float, WindDirection) → P/Invoke → native_tick()
|
||
│ Vector3 Center → P/Invoke → native_center()
|
||
│ float Radius → P/Invoke → native_radius()
|
||
│ ... │
|
||
│ } │
|
||
│ │
|
||
└────────────────────────────────────────────────────────┘
|
||
|
||
┌─ 步骤 2:一行注册 ──────────────────────────────────┐
|
||
│ │
|
||
│ AlgorithmFactory.Register │
|
||
│ <ICloudDispersionModel, ThirdPartyPuff>(); │
|
||
│ │
|
||
└────────────────────────────────────────────────────────┘
|
||
|
||
┌─ 步骤 3:SimulationEngine 无感知切换 ───────────────┐
|
||
│ │
|
||
│ var dispersion = AlgorithmFactory │
|
||
│ .Create<ICloudDispersionModel>(ammo, env, pos, t);│
|
||
│ │
|
||
│ // 后续代码完全不变,无论底层是自主实现还是第三方 DLL │
|
||
│ dispersion.Tick(deltaTime, windSpeed, windDir); │
|
||
│ if (dispersion.IsDissipated) { ... } │
|
||
│ │
|
||
└────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**替换粒度**:每个算法组件独立替换,可以实现如下组合:
|
||
|
||
```
|
||
组合 A(当前):
|
||
ICloudDispersionModel → GaussianPuffDispersion(自主)
|
||
IDamageModel → DamageModelRouter(自主)
|
||
IDefensePlanner → DefaultDefensePlanner(自主)
|
||
|
||
组合 B(将来可能):
|
||
ICloudDispersionModel → ThirdPartyPuff(第三方 DLL)
|
||
IDamageModel → DamageModelRouter(自主保留)
|
||
IDefensePlanner → DefaultDefensePlanner(自主保留)
|
||
|
||
组合 C(将来可能):
|
||
ICloudDispersionModel → ThirdPartyPuff(第三方 DLL)
|
||
IDamageModel → ThirdPartyDamage(第三方 DLL)
|
||
IDefensePlanner → DefaultDefensePlanner(自主保留)
|
||
```
|
||
|
||
---
|
||
|
||
## 七、数据录制与回放
|
||
|
||
### 7.1 IFrameDataStore 接口
|
||
|
||
```csharp
|
||
/// <summary>帧数据存储 — 每任务一个独立 SQLite 文件</summary>
|
||
public interface IFrameDataStore
|
||
{
|
||
/// <summary>为任务创建帧数据库文件</summary>
|
||
void CreateTaskDb(string taskId);
|
||
|
||
/// <summary>批量写入一帧所有实体状态</summary>
|
||
void WriteFrame(string taskId, int frameIdx, float timestamp,
|
||
List<EntitySnapshot> entities);
|
||
|
||
/// <summary>按帧范围读取(回放用)</summary>
|
||
List<SimFrameRecord> ReadFrames(string taskId, int fromFrame, int toFrame);
|
||
|
||
/// <summary>删除任务的帧数据库</summary>
|
||
void DeleteTaskDb(string taskId);
|
||
|
||
/// <summary>清理过期的帧数据库(定时调用)</summary>
|
||
void CleanupExpired(DateTime olderThan);
|
||
}
|
||
```
|
||
|
||
### 7.2 录制
|
||
|
||
- 仿真启动时创建 `frames/{taskId}.db`
|
||
- 录制帧率 = 仿真 TickRate(每想定可配置,默认 20Hz)
|
||
- 每 Tick 调用 `WriteFrame()` 写入该帧所有实体状态
|
||
- SQLite 事务批量提交(如每 50 帧一批,减少磁盘 IO)
|
||
- 仿真事件 `SimEvent` 直接写入主库 `main.db`(每任务 ~30 条,轻量)
|
||
|
||
### 7.3 回放
|
||
|
||
- ReplayController 协程驱动
|
||
- 打开 `frames/{taskId}.db`,按 FrameIndex 范围查询
|
||
- WHERE FrameIndex BETWEEN a AND b 命中索引,毫秒级
|
||
- 回放帧率由前端控制(可与录制不同)
|
||
- 支持暂停 / 快进 / 后退 / 跳转
|
||
|
||
### 7.4 容量估算
|
||
|
||
以默认 20Hz TickRate,16 实体为例:
|
||
|
||
| 仿真时长 | 帧数 | 行数(16实体) | 单任务大小 |
|
||
|------|------|------|------|
|
||
| 5 min | 6,000 | 96,000 | ~27 MB |
|
||
| 15 min | 18,000 | 288,000 | ~80 MB |
|
||
| 30 min | 36,000 | 576,000 | ~161 MB |
|
||
| 60 min | 72,000 | 1,152,000 | ~322 MB |
|
||
|
||
6 个月累计(假设日均 5 次仿真,每次 30min):
|
||
|
||
| 项目 | 数据 |
|
||
|------|------|
|
||
| 仿真总次数 | 5 × 180 = 900 次 |
|
||
| 帧数据总大小 | 900 × 161 MB ≈ **145 GB** |
|
||
| main.db | < **100 MB** |
|
||
| 全部合计 | **~145 GB** |
|
||
|
||
### 7.5 TTL 清理策略
|
||
|
||
```
|
||
仿真完成 → 生成 frames/{taskId}.db
|
||
│
|
||
▼
|
||
CleanupExpired() 每天执行一次:
|
||
├─ 扫描 frames/ 目录
|
||
├─ 检查 {taskId}.db 的创建时间
|
||
└─ 超过 6 个月 → 删除文件
|
||
|
||
可选扩展:
|
||
- 归档:移到 archive/ 目录并压缩(.db.gz)
|
||
- 降采样:删除前先保留每 N 帧 1 帧的精简版
|
||
```
|
||
|
||
### 7.6 为什么分库而非单库
|
||
|
||
| 对比 | 单库(全部在 main.db) | 分库(每任务一个 .db) |
|
||
|------|------|------|
|
||
| 帧表行数(6月) | 5.18 亿行 | 每库 57.6 万行 |
|
||
| 查询延迟 | 秒级(需精细索引) | 毫秒级 |
|
||
| 单文件体积 | > 100 GB | 每文件 ~161 MB |
|
||
| 备份/VACUUM | 灾难级 | 无痛 |
|
||
| 数据损坏影响 | 全部丢失 | 仅一个任务 |
|
||
| 运维(删除/归档) | 复杂 SQL | 直接删文件 |
|
||
|
||
---
|
||
|
||
## 八、报告生成
|
||
|
||
### 8.1 报告结构
|
||
|
||
技术要求终版要求报告包含**时序图**和三个分析维度:
|
||
|
||
| 阶段 | 内容 | 数据来源 |
|
||
|------|------|------|
|
||
| **仿真前** | 我方配置(装备类型/数量/编组、弹药类型/数量、部署位置、管控区域) | SimTask + 5 步配置 |
|
||
| **仿真中** | 关键事件时序表、各实体轨迹概要、云团演化数据 | SimEvent + SimFrameRecord |
|
||
| **仿真后** | 拦截成功率、各阶段耗时、毁伤效果评估、对抗结果判定 | SimEvent 汇总统计 |
|
||
|
||
### 8.2 对抗结果判定逻辑
|
||
|
||
```
|
||
成功拦截:所有无人机 被摧毁(未抵达目标、未侵入管控区)
|
||
部分拦截:部分无人机被摧毁,其余抵达目标或侵入管控区
|
||
拦截失败:所有无人机抵达目标或侵入管控区(无摧毁)
|
||
```
|
||
|
||
### 8.3 导出
|
||
|
||
- 格式:PDF / Word(默认 PDF)
|
||
- 模板占位符填充后输出
|
||
- 技术选型:QuestPDF 或其他 .NET Standard 2.1 兼容方案(待调研)
|
||
|
||
---
|
||
|
||
## 九、服务接口概要
|
||
|
||
```csharp
|
||
// === 模型管理 ===
|
||
interface IModelService
|
||
{
|
||
ModelInfo ImportModel(string filePath, string name);
|
||
void DeleteModel(string id);
|
||
List<ModelInfo> GetAllModels();
|
||
ModelInfo GetModel(string id);
|
||
}
|
||
|
||
// === 编组管理 ===
|
||
interface IGroupService
|
||
{
|
||
Group CreateGroup(string name, GroupType type, string description);
|
||
void DeleteGroup(string id);
|
||
List<Group> GetGroups(GroupType? type);
|
||
}
|
||
|
||
// === 想定管理 ===
|
||
interface IScenarioService
|
||
{
|
||
SimTask CreateTask(string name, string taskNumber);
|
||
void DeleteTask(string id);
|
||
PagedResult<SimTask> SearchTasks(string kw, DateTime? from, DateTime? to, int page, int size);
|
||
TaskFullConfig GetTaskDetail(string id);
|
||
|
||
// 步骤保存
|
||
void SaveScene(string taskId, CombatScene scene);
|
||
void SaveControlZones(string taskId, List<ControlZone> zones); // NEW
|
||
void SaveTarget(string taskId, TargetConfig target);
|
||
void SaveDeployment(string taskId, List<EquipmentDeployment> equips); // 重构
|
||
void SaveCloudDispersal(string taskId, CloudDispersal cloud);
|
||
void SaveRoute(string taskId, RoutePlan route, List<Waypoint> wps);
|
||
void UpdateStep(string taskId, int step);
|
||
|
||
// 综合防御推荐(NEW — 多编队版)
|
||
DefenseRecommendation GetDefenseRecommendation(string taskId);
|
||
}
|
||
|
||
// === 仿真引擎 ===
|
||
interface ISimulationEngine
|
||
{
|
||
void Initialize(string taskId);
|
||
SimulationFrameResult Tick(float deltaTime);
|
||
void Pause();
|
||
void Resume();
|
||
void Stop();
|
||
SimulationState State { get; }
|
||
}
|
||
|
||
// === 数据录制 ===
|
||
interface IRecordService
|
||
{
|
||
void StartRecording(string taskId, int tickRate);
|
||
void WriteFrame(int frameIdx, float timestamp, List<EntitySnapshot> entities);
|
||
void WriteEvent(SimEvent evt);
|
||
void StopRecording();
|
||
List<SimFrameRecord> GetFrames(string taskId, int from, int to);
|
||
List<SimEvent> GetEvents(string taskId);
|
||
void CleanupExpired(DateTime olderThan); // TTL 清理
|
||
}
|
||
|
||
// === 仿真报告 ===
|
||
interface IReportService
|
||
{
|
||
SimulationReport Generate(string taskId);
|
||
SimulationReport GetReport(string id);
|
||
void DeleteReport(string id);
|
||
byte[] ExportReport(string id, string format); // "pdf" | "word"
|
||
PagedResult<SimulationReport> SearchReports(string kw, DateTime? from, DateTime? to, int page, int size);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 九-A、多批次多编队设计
|
||
|
||
### 数据模型
|
||
|
||
一个仿真任务可包含**多种类型、多批次**的无人机,每批次(编队)有独立的航路:
|
||
|
||
```
|
||
SimTask "城市防御演习"
|
||
├── CombatScene(共享)
|
||
├── ControlZone[](共享)
|
||
├── CloudDispersal(共享:云团参数,具体拦截方案由算法确定)
|
||
│
|
||
├── 编队 A(活塞×3) ← Group.Id
|
||
│ ├── TargetConfig(类型=活塞,数量=3)
|
||
│ ├── RoutePlan(航路 A:北→南)
|
||
│ └── Waypoint[]
|
||
│
|
||
├── 编队 B(喷气×2) ← Group.Id
|
||
│ ├── TargetConfig(类型=高速,数量=2)
|
||
│ ├── RoutePlan(航路 B:西→东)
|
||
│ └── Waypoint[]
|
||
│
|
||
└── 编队 C(旋翼×5) ← Group.Id
|
||
├── TargetConfig(类型=旋翼,数量=5)
|
||
├── RoutePlan(航路 C)
|
||
└── Waypoint[]
|
||
```
|
||
|
||
**关键变更**:`RoutePlan` 主键从 `TaskId` 改为 `(TaskId, GroupId)` 复合键。
|
||
|
||
### 推荐算法
|
||
|
||
算法需要同时考虑**所有无人机编队**和**可用装备火力单元**,自动匹配分配:
|
||
|
||
```csharp
|
||
// 输入:所有无人机编队 + 已部署的火力单元
|
||
// 输出:每个编队的拦截方案 + 合并的发射计划
|
||
|
||
var allSolutions = new List<DefenseSolution>();
|
||
var usedPlatforms = new HashSet<int>();
|
||
|
||
foreach (var droneGroup in threat.DroneGroups)
|
||
{
|
||
// 从可用装备中选择合适的火力单元(弹药类型匹配目标动力类型)
|
||
var availableUnits = fireUnits.Where(u => !usedPlatforms.Contains(u.Id)).ToList();
|
||
var solution = advisor.RecommendForGroup(droneGroup, environment, availableUnits);
|
||
|
||
// 标记占用的平台(一组装备可同时对付一个编队)
|
||
foreach (var idx in solution.AssignedPlatformIndices)
|
||
usedPlatforms.Add(idx);
|
||
|
||
allSolutions.Add(solution);
|
||
}
|
||
|
||
// 复用判定(不写死"一对一"或"一对多"):
|
||
// 同种弹药 → 只需冷却时间(秒级),可直接复用
|
||
// 异种弹药 → 需要 AmmoChangeTime(默认 5 分钟),检查编队间隔是否够
|
||
// 弹药耗尽 → 不可复用
|
||
|
||
var merged = MergeFireSchedules(allSolutions);
|
||
engine.SetFireSchedule(merged);
|
||
```
|
||
|
||
**关键原则**:
|
||
- 算法决定分配,而非写死"一对一"或"一对多"
|
||
- 决策依据:弹药类型匹配、时间窗口重叠、火力单元能力
|
||
- 人工可调整算法推荐结果
|
||
- 引擎不感知分组——只看合并后的 `FireSchedule`
|
||
|
||
### 数据表变更
|
||
|
||
| 表 | 变更 |
|
||
|------|------|
|
||
| `RoutePlan` | PK 改为 (TaskId, GroupId) 复合键 |
|
||
| `TargetConfig` | 不变(已有 GroupId FK) |
|
||
| `Waypoint` | 关联 `(TaskId, GroupId)` 定位航路 |
|
||
|
||
`IScenarioService` 新增:
|
||
```csharp
|
||
void SaveRoute(string taskId, string groupId, RoutePlan route, List<Waypoint> wps); // groupId 参数
|
||
```
|
||
|
||
### 报告
|
||
|
||
报告新增多编队汇总:
|
||
|
||
```markdown
|
||
## 编队汇总
|
||
| 编队 | 目标 | 数量 | 拦截方案 | 结果 |
|
||
|------|------|------|------|------|
|
||
| 编队A | 活塞 | 3 | 惰性气体 12发 | ✅ 全毁 |
|
||
| 编队B | 喷气 | 2 | 活性材料 8发 | ⚠️ 1逃脱 |
|
||
```
|
||
|
||
---
|
||
|
||
## 十、配置向导步骤(整合后)
|
||
|
||
整合需求 V1.0 和技术要求终版后,配置向导保持 5 步但内容调整:
|
||
|
||
```
|
||
┌────────────────────────────────────────────────────────┐
|
||
│ 步骤 1:作战场景设置 │
|
||
│ ├─ 场景类型(城市/平原/山区/海岸) │
|
||
│ ├─ 时间段(24h 制 NEW) │
|
||
│ ├─ 天气 + 风速/风向/温度/湿度/气压/能见度 │
|
||
│ ├─ 场景空间范围(宽/纵深/高 NEW) │
|
||
│ └─ 管控区域(电子围栏 NEW) │
|
||
│ └─ 多边形绘制 / 编辑 / 删除 │
|
||
├────────────────────────────────────────────────────────┤
|
||
│ 步骤 2:目标配置 │
|
||
│ ├─ 编组选择(已有编队/新建编队) │
|
||
│ ├─ 目标类型选择(自动填充默认参数) │
|
||
│ ├─ 数量 / 动力类型 / 翼展 / 速度 / 高度 │
|
||
│ └─ 预设典型目标库(NEW) │
|
||
├────────────────────────────────────────────────────────┤
|
||
│ 步骤 3:装备部署(重构) │
|
||
│ ├─ 装备角色(探测设备 / 发射平台) │
|
||
│ ├─ 发射平台类型(空基 / 地基 NEW) │
|
||
│ ├─ 数量 / 编组 / 部署位置 │
|
||
│ ├─ 挂载气溶胶类型 / 弹药数量 │
|
||
│ ├─ 弹药初速 / 释放高度 / 冷却时间 │
|
||
│ └─ 探测半径(探测设备) │
|
||
├────────────────────────────────────────────────────────┤
|
||
│ 步骤 4:云团抛撒配置 │
|
||
│ ├─ 气溶胶类型(吸入式灭火/爆燃式/吸入式爆炸) │
|
||
│ ├─ 释放参数(高度/触发模式/扩散方向/规模/持续等) │
|
||
│ ├─ 抛撒位置(三维点选 / 手动输入 / 算法推荐 NEW) │
|
||
│ ├─ 算法推荐按钮 → 显示最佳值 & 最危险值(NEW) │
|
||
│ └─ 可点选采纳推荐值 │
|
||
├────────────────────────────────────────────────────────┤
|
||
│ 步骤 5:航路规划 │
|
||
│ ├─ 编队模式(单机/编队/蜂群) │
|
||
│ ├─ 编队间距 / 预计到达时间 │
|
||
│ ├─ 航路点画布(三维点选添加/调整/删除 NEW) │
|
||
│ └─ 航路点列表(坐标/高度/速度) │
|
||
└────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 十一、关键技术决策
|
||
|
||
| # | 决策 | 选择 | 理由 |
|
||
|---|------|------|------|
|
||
| 1 | 数据持久化 | SQLite (sqlite-net) | 支持复杂查询、筛选、分页 |
|
||
| 2 | 模型文件格式 | .fbx / .obj / .stl / .glb / .gltf | 合并两份需求,≤500MB,2K+贴图 |
|
||
| 3 | 模型文件存储 | Application.persistentDataPath | 不与 Unity Assets 耦合 |
|
||
| 4 | 序列化方案 | System.Text.Json | Unity 2022+ 内置支持 |
|
||
| 5 | Service/Data 层 | 零 UnityEngine 依赖 | 可独立单元测试 |
|
||
| 6 | 仿真驱动方式 | 固定 TickRate 帧驱动 | 每想定可配置(默认 20Hz),保证确定性 |
|
||
| 7 | 仿真并发 | 单仿真 | 简化状态管理 |
|
||
| 8 | 拦截机制 | 多阶段链路 | 探测→火控→发射→弹药飞行→云团→毁伤 |
|
||
| 9 | 云团扩散模型 | **高斯烟团模型(自主实现)** | 简化球体膨胀 + 风速漂移 + 密度衰减,适合实时 20Hz |
|
||
| 10 | 毁伤模型 | **三种机制自主实现** | 吸入式灭火(阈值型)、爆燃式(触发型)、吸入式爆炸(指数累积型) |
|
||
| 11 | 防御方案推荐 | **IDefensePlanner(自主实现)** | 五步规划:威胁排序 → 弹药匹配 → 候选生成 → 贪心分配 → 时序生成 |
|
||
| 12 | 第三方数据 | **静态配置(JSON → SQLite)** | 仅提供弹药基础参数和初始扩散状态,不提供运行时算法 |
|
||
| 13 | 运动学 | 简化运动学 + 风偏 | 航路点线性插值 + 风速矢量 |
|
||
| 14 | 弹药弹道 | 抛物线(地基)/ 自由落体(空基) | 基于初速、角度、释放高度计算 |
|
||
| 15 | 编组 | Group 独立实体 | 编组独立管理,任务中引用 |
|
||
| 16 | 管控区域 | ControlZone 表 + Tick 判定 | 电子围栏,侵入即任务失败 |
|
||
| 17 | 配置向导流程 | **威胁驱动三阶段** | Phase1 定义威胁 → Phase2 算法推荐 → Phase3 审阅确认 |
|
||
| 18 | 报告导出 | 模板填充 → Markdown | PDF/Word 待调研 |
|
||
| 19 | 坐标系统 | 右手系 Y-up,米为单位 | 与 Unity 一致 |
|
||
| 20 | 空间范围 | 最低 4×100×10m,默认更大 | 可配置 |
|
||
| 21 | 帧数据存储 | **主库 + 任务分库** | 主库存元数据+事件(<100MB永久);分库每任务存帧数据(6月TTL),单文件~161MB,直接删文件运维 |
|
||
| 22 | 程序集拆分 | **Core 独立于 Unity** | Core 为 .NET Standard 2.1 纯类库,零 UnityEngine 依赖;Unity 仅作桥接;dotnet test 即可全量测试 |
|
||
|
||
---
|
||
|
||
## 十二、性能指标(来自技术要求终版)
|
||
|
||
| 指标 | 要求 | 说明 |
|
||
|------|------|------|
|
||
| 最大目标数 | ≥ 5 独立运动实体(3D 显示) | 显示层面,非逻辑上限 |
|
||
| 渲染帧率 | ≥ 30 FPS(满载 + 粒子特效) | Unity 前端职责 |
|
||
| 仿真空间 | ≥ 4m × 100m × 10m | 默认更大,可配置 |
|
||
| 粒子系统 | 云团扩散/流动/色彩 | Unity 根据后端参数渲染 |
|
||
| 毁伤效果 | 尾焰异常、姿态失控、坠落 | Unity 根据 DamageStage 渲染 |
|
||
|
||
---
|
||
|
||
## 十三、待后续讨论
|
||
|
||
| # | 议题 | 说明 |
|
||
|---|------|------|
|
||
| 1 | 第三方 DLL 的具体接口规范 | 需与供应商对齐函数签名、数据结构、调用约定 |
|
||
| 2 | 3 种毁伤机制的差异化细节 | 吸入式灭火 vs 爆燃式 vs 吸入式爆炸的毁伤曲线差异 |
|
||
| 3 | 探测设备融合逻辑 | 多设备发现同一目标时的数据融合策略 |
|
||
| 4 | 火控分配策略 | 多目标时的优先级分配规则 |
|
||
| 5 | 蜂群模式运动模型 | 随机扰动范围、个体行为差异 |
|
||
| 6 | 报告模板具体格式 | 统计维度、图表需求 |
|
||
| 7 | 场景类型对仿真的影响 | 山区是否影响探测/运动 |
|
||
| 8 | PDF/Word 导出库选型 | QuestPDF 或其他 .NET Standard 2.1 方案 |
|
||
| 9 | 预置典型目标库内容 | 具体包含哪些无人机型号及参数 |
|
||
| 10 | 扩散模型的大气稳定度参数 | 不同天气条件下 σ 的增长速率如何量化 |
|
||
| 11 | 毁伤曲线的具体数值 | 三种机制的 damageRate、threshold、burstDamage 等参数取值 |
|
||
| 12 | 时空交汇优化的精度 | 离散采样步长 vs 解析解的选择 |
|