# 反无人机仿真系统 — 总体架构设计 > **版本**:V7 > **日期**:2026-06-11 > **状态**:设计中 > **Unity 版本**:22.3.62 > **.NET 版本**:.NET Standard 2.1 > **变更**:明确 Core 程序集独立于 Unity;新增 IPathProvider 隔离点;新增测试策略(xUnit/确定性测试/CI 兼容) --- ## 一、系统概述 本系统对新型气溶胶武器的三种防空毁伤机制(吸入式灭火、爆燃式、吸入式爆炸)进行数字化仿真。通过参数化配置与可视化推演,量化评估新型气溶胶武器对不同类型空中威胁源目标(动力系统)的毁伤效能。 系统分为三大模块: | 模块 | 核心功能 | |------|----------| | **模型管理** | 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 │ │ DefenseAdvisor│ │ ├ DroneEntity │ │ │ └──────────────┘ └──────────────┘ │ ├ PlatformEntity │ │ │ ┌──────────────┐ ┌──────────────┐ │ ├ MunitionEntity │ │ │ │ RecordService│ │ReportService │ │ ├ CloudEntity │ │ │ │ │ │ ├ ReportGen │ │ │ └ GaussianPuff│ │ │ └──────────────┘ │ └ PDF/Word │ │ ├ ControlZone │ │ │ └──────────────┘ │ ├ IDamageModel×3 │ │ │ │ └ EventQueue │ │ │ ┌──────────────────────────────────────────────────────┐│ │ │ Algorithm Layer (自主实现) ││ │ │ DispersionEngine | DamageCalculator ││ │ │ DefenseAdvisor | SpatioTemporalOptimizer ││ │ └──────────────────────────────────────────────────────┘│ ├──────────────────────────────────────────────────────────┤ │ 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 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:航路规划 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 | | // 以下为探测设备专用字段 | | 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 | TEXT | PK, FK | 1:1 SimTask | | GroupId | TEXT | 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 ← 无人机(目标方) │ └── 按编组组织,共享航路 ├── List ← 搭载平台(发射方)★重构 │ ├── AirBasedPlatform ← 空基(大型无人机) │ └── GroundBasedPlatform ← 地基(火炮) ├── List ← 探测设备 ├── List ← 飞行中的弹药 │ ├── 空基投放:短程自由落体/滑翔 │ └── 地基发射:抛物线弹道 ├── List ← 气溶胶云团 ★核心毁伤载体★ │ └── 扩散模型调用第三方 DLL ├── List ← 管控区域(电子围栏)★NEW ├── EventQueue ← 事件队列 └── IRecordWriter ← 帧数据写入 ``` ### 5.2 拦截链路(完整流程) ``` 探测设备扫描 │ 发现目标 → 输出目标坐标 ▼ 火控分配(分配给可用搭载平台) │ ├── 空基平台:飞至投放点 │ │ │ ▼ │ 投放弹药(自由落体/滑翔至云团生成点) │ └── 地基平台:计算射击诸元 │ ▼ 发射炮弹(抛物线弹道飞向目标区域) │ ▼ 弹药到达释放点 → 生成 CloudEntity MunitionEntity 销毁 │ ▼ 云团扩散膨胀(调用第三方 DLL 扩散模型) │ 持续膨胀 + 消散计时 ▼ 无人机进入云团范围 │ 施加毁伤(调用第三方 DLL 毁伤模型) │ 吸入式灭火 / 爆燃式 / 吸入式爆炸 ▼ 无人机被摧毁 / 存活 │ 毁伤阶段状态输出到 StateData ▼ Unity 渲染毁伤效果(尾焰异常、姿态失控、坠落) ``` ### 5.3 仿真 Tick 流程(8 阶段) ``` 1. 【探测阶段】 FOR EACH 探测设备: ├─ 扫描场景内无人机(距离 < DetectionRadius) └─ 发现目标 → EventQueue.Enqueue(TargetDetected) 2. 【火控决策阶段】 处理 TargetDetected 事件: ├─ 分配目标给可用搭载平台 ├─ 空基平台:计算拦截航路,飞向投放点 └─ 地基平台:计算射击诸元(发射角、方位角) 3. 【发射阶段】 FOR EACH 搭载平台: ├─ 满足发射条件 & 冷却完毕 → 生成 MunitionEntity │ ├─ 空基:初始速度 = 平台速度,初始位置 = 投放点 │ └─ 地基:初始速度 = MuzzleVelocity,按抛物线计算 └─ 进入冷却倒计时 4. 【弹药飞行】 FOR EACH MunitionEntity: ├─ 空基弹药:自由落体/滑翔至云团生成高度 ├─ 地基弹药:抛物线位置 = f(初速, 发射角, t) └─ 到达释放条件 → 生成 CloudEntity → MunitionEntity 销毁 └─ EventQueue.Enqueue(CloudGenerated) 5. 【云团演化】(调用第三方 DLL) FOR EACH CloudEntity: ├─ 扩散膨胀:radius = DLL.Dispersion.Update(deltaTime, config) ├─ 更新粒子系统参数(半径、透明度、颜色 → 写入 StateData) └─ 剩余时间 ≤ 0 → 销毁 6. 【毁伤判定】(调用第三方 DLL) DOUBLE LOOP DroneEntity × CloudEntity: ├─ 无人机坐标 ∈ 云团球体? ├─ 是 → damage = DLL.DamageModel.Calculate(DroneType, AerosolType, exposureTime) ├─ 更新 drone.HP -= damage ├─ 更新 drone.DamageStage(Normal → EngineAnomaly → AttitudeLoss → Destroyed) └─ HP ≤ 0 → EventQueue.Enqueue(DroneDestroyed) 7. 【无人机移动】 FOR EACH 存活 DroneEntity: ├─ 沿航路点线性插值移动 ├─ 实际位移 += 风速矢量 × deltaTime ├─ 到达航路点 → EventQueue.Enqueue(WaypointReached) ├─ 到达最后一个航路点 → EventQueue.Enqueue(DroneReachedTarget) └─ 编队/蜂群模式决定集群排列 8. 【管控区域判定】★NEW FOR EACH 存活 DroneEntity: ├─ 无人机坐标 ∈ 任一 ControlZone 多边形体积? └─ 是 → EventQueue.Enqueue(ZoneIntruded) → 标记该无人机任务失败 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): - 扩散膨胀:DLL.Dispersion.Update(deltaTime, 环境参数, 释放参数) - 消散计时 - 毁伤判定:DLL.DamageModel.Calculate(DroneType, AerosolType, exposureTime) ``` --- ## 六、算法设计 — 接口驱动 & 可替换架构 ★关键 ### 设计原则 所有算法组件通过**接口隔离**,SimulationEngine 只依赖接口,不感知具体实现。每个算法组件可独立替换为第三方实现,无需修改引擎代码。 ``` SimulationEngine │ ┌─────┼─────┐ ▼ ▼ ▼ ICloudDispersionModel ← 扩散模型接口 IDamageModel ← 毁伤模型接口 IDefenseAdvisor ← 防御推荐接口 │ ┌───────┼───────┐ ▼ ▼ ▼ 自主实现 第三方实现 混合(部分自研+部分外购) (Default) (Future) (Future) ``` ### 6.1 算法工厂与注册 ```csharp /// 算法工厂 — 统一管理所有算法组件的创建与替换 public static class AlgorithmFactory { // 注册表:每个接口 → 实现类型 private static readonly Dictionary _registry = new() { { typeof(ICloudDispersionModel), typeof(GaussianPuffDispersion) }, { typeof(IDamageModel), typeof(DamageModelRouter) }, { typeof(IDefenseAdvisor), typeof(DefaultDefenseAdvisor) }, }; /// 替换某个算法实现(第三方接入点) public static void Register() where TImpl : TInterface { _registry[typeof(TInterface)] = typeof(TImpl); } /// 创建实例,SimulationEngine 统一调用此方法 public static T Create(params object[] args) { var implType = _registry[typeof(T)]; return (T)Activator.CreateInstance(implType, args); } } ``` > **替换示例**:将来第三方提供 `ThirdPartyDispersion.dll`,只需一行: > `AlgorithmFactory.Register();` > 无需改动 SimulationEngine 任何代码。 ### 6.2 第三方提供的数据 ```csharp /// 第三方提供的弹药基础参数(数据配置,非运行时 DLL) 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.3 扩散模型设计 — 高斯烟团模型(Gaussian Puff) #### 6.3.1 模型选择 选用**高斯烟团扩散模型**(Gaussian Puff Model),理由: - 计算简单,适合实时 20Hz Tick - 能反映风速、大气稳定度对扩散的影响 - 工业级大气扩散的经典方法 #### 6.3.2 核心公式 云团内任意点 (x, y, z) 在时刻 t 的浓度: ``` C(x, y, z, t) = ────────────── × exp[ -½( (x-ut)/σx )² ] (2π)^(3/2) σx σy σz × exp[ -½( y/σy )² ] × { exp[ -½( (z-H)/σz )² ] + exp[ -½( (z+H)/σz )² ] } 其中: Q = 源强(释放总量) u = 风速(m/s) H = 有效释放高度(m) σx, σy, σz = 三轴扩散系数,随时间增大 ``` #### 6.3.3 简化方案 完整三维浓度场计算量大。实时仿真中采用**简化方案**: ``` 简化假设: - 云团近似为球体(σx = σy = σz = σ) - 半径 R(t) = InitialRadius + DispersionRate × t - DispersionRate = DispersionRateBase × f(风速, 大气稳定度) - 中心随风速漂移:Center(t) = Center(0) + WindVector × t - 密度随半径衰减:Density(t) = CoreDensity × (InitialRadius / R(t))³ 简化判定: - 无人机进入球体 → 暴露于云团 - 密度 ≥ EffectiveConcentration → 有效毁伤 - 半径 ≥ MaxRadius OR 时间 ≥ MaxDuration → 消散 ``` #### 6.3.4 接口 ```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; } // 当前半径(m) float CoreDensity { get; } // 当前核心密度 float EffectiveRadius { get; } // 密度 ≥ 有效浓度的半径 ParticleParams Particles { get; } // Unity 粒子参数 bool IsDissipated { get; } // 是否已消散 } ``` ### 6.4 毁伤模型设计 三种气溶胶对应三种毁伤机制,我们自主实现: #### 6.4.1 共同接口 ```csharp public interface IDamageModel { /// 每 Tick 计算毁伤值 /// 目标类型 /// 动力类型(影响毁伤效率) /// 气溶胶类型 /// 当前位置云团密度(kg/m³) /// 累计暴露时间(s) /// 本次 Tick 时长 /// 本次毁伤值(0~1 归一化) 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 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 IDefenseAdvisor { DefenseRecommendation Recommend(ThreatProfile threat); } // 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 │ │ (); │ │ │ └────────────────────────────────────────────────────────┘ ┌─ 步骤 3:SimulationEngine 无感知切换 ───────────────┐ │ │ │ var dispersion = AlgorithmFactory │ │ .Create(ammo, env, pos, t);│ │ │ │ // 后续代码完全不变,无论底层是自主实现还是第三方 DLL │ │ dispersion.Tick(deltaTime, windSpeed, windDir); │ │ if (dispersion.IsDissipated) { ... } │ │ │ └────────────────────────────────────────────────────────┘ ``` **替换粒度**:每个算法组件独立替换,可以实现如下组合: ``` 组合 A(当前): ICloudDispersionModel → GaussianPuffDispersion(自主) IDamageModel → DamageModelRouter(自主) IDefenseAdvisor → DefaultDefenseAdvisor(自主) 组合 B(将来可能): ICloudDispersionModel → ThirdPartyPuff(第三方 DLL) IDamageModel → DamageModelRouter(自主保留) IDefenseAdvisor → DefaultDefenseAdvisor(自主保留) 组合 C(将来可能): ICloudDispersionModel → ThirdPartyPuff(第三方 DLL) IDamageModel → ThirdPartyDamage(第三方 DLL) IDefenseAdvisor → DefaultDefenseAdvisor(自主保留) ``` --- ## 七、数据录制与回放 ### 7.1 IFrameDataStore 接口 ```csharp /// 帧数据存储 — 每任务一个独立 SQLite 文件 public interface IFrameDataStore { /// 为任务创建帧数据库文件 void CreateTaskDb(string taskId); /// 批量写入一帧所有实体状态 void WriteFrame(string taskId, int frameIdx, float timestamp, List entities); /// 按帧范围读取(回放用) List ReadFrames(string taskId, int fromFrame, int toFrame); /// 删除任务的帧数据库 void DeleteTaskDb(string taskId); /// 清理过期的帧数据库(定时调用) 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 GetAllModels(); ModelInfo GetModel(string id); } // === 编组管理 === interface IGroupService { Group CreateGroup(string name, GroupType type, string description); void DeleteGroup(string id); List GetGroups(GroupType? type); } // === 想定管理 === interface IScenarioService { SimTask CreateTask(string name, string taskNumber); void DeleteTask(string id); PagedResult 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 zones); // NEW void SaveTarget(string taskId, TargetConfig target); void SaveDeployment(string taskId, List equips); // 重构 void SaveCloudDispersal(string taskId, CloudDispersal cloud); void SaveRoute(string taskId, RoutePlan route, List wps); void UpdateStep(string taskId, int step); // 算法推荐(NEW) DispersalRecommendation GetDispersalRecommendation(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 entities); void WriteEvent(SimEvent evt); void StopRecording(); List GetFrames(string taskId, int from, int to); List 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 SearchReports(string kw, DateTime? from, DateTime? to, int page, int size); } ``` --- ## 十、配置向导步骤(整合后) 整合需求 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 | 防御方案推荐 | **IDefenseAdvisor(自主实现)** | 规则匹配选型 + 时空交汇优化 + 反推平台部署 | | 12 | 第三方数据 | **静态配置(JSON → SQLite)** | 仅提供弹药基础参数和初始扩散状态,不提供运行时算法 | | 13 | 运动学 | 简化运动学 + 风偏 | 航路点线性插值 + 风速矢量 | | 14 | 弹药弹道 | 抛物线(地基)/ 自由落体(空基) | 基于初速、角度、释放高度计算 | | 15 | 编组 | Group 独立实体 | 编组独立管理,任务中引用 | | 16 | 管控区域 | ControlZone 表 + Tick 判定 | 电子围栏,侵入即任务失败 | | 17 | 配置向导流程 | **威胁驱动三阶段** | Phase1 定义威胁 → Phase2 算法推荐 → Phase3 审阅确认 | | 18 | 报告导出 | 模板填充 → PDF/Word | QuestPDF 待调研 | | 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 解析解的选择 |