VERSION 0.10.0 — 模型重命名、属性完善、文档同步

- VERSION: 0.9.0 → 0.10.0
- CHANGELOG: 新增 0.10.0 条目
- 架构设计 V15: DroneType 枚举清理、表结构加 Model/Description
- 对接文档 V1.6: 去历史对照,只写现状核心模型表
- 数据库迁移: 删旧表 SimTask/TargetConfig/SimulationReport
- 238 测试全过
This commit is contained in:
tian 2026-06-18 15:24:14 +08:00
parent ad0eaf47da
commit ff6db2786e
5 changed files with 114 additions and 32 deletions

View File

@ -2,6 +2,42 @@
---
## [0.10.0] - 2026-06-18
### Breaking — 平台物理统一 + 模型重命名
- **空基/地基物理统一**:去除 DefensePlanner 所有平台类型分支,统一用 `InterceptCalculator.Compute`(删 `ComputeHorizontal`),统一用 `MuzzleVelocity`(删 `CruiseSpeed` 分支)
- **抛物线选解策略**:两解逐一计算距离匹配 + `fireTime>0` 可行性,选最早拦截的解(非简单选高角/低角)
- **`TargetType``DroneType`**:删 `Electric`/`Piston`,重编号 `HighSpeed=2``TargetConfig.DroneType` 属性同步改名
- **`TargetConfig``DroneProfile`**:核心模型重命名
- **`SimTask``Scenario`**:想定主表重命名,`ScenarioNumber` 取代 `TaskNumber`
- **`TaskFullConfig``ScenarioConfig`**:聚合配置重命名,`Task` 属性 → `Info`
- **`TaskId``ScenarioId`**:所有 FK 重命名
- **`ScenarioService` 方法**`CreateTask`→`CreateScenario`、`DeleteTask`→`DeleteScenario`、`SearchTasks`→`SearchScenarios`、`GetTaskDetail`→`GetScenarioDetail`
### Added — 模型业务属性
- **`DroneProfile` / `DroneSpec`**+`Model`(型号)、+`Description`(描述/用途)
- **`Scenario`**+`Description`(想定描述)
- **`EquipmentDeployment` / `FireUnitSpec`**+`Description`
- **`ReportManager.Export(reportId, outputDir)`**:支持指定导出路径
### Changed — 数据库迁移
- `CreateMainTables` 删旧表 `SimTask`、`TargetConfig`、`SimulationReport`(自动重建)
- `scenariosVersion` 3→4 触发 demo 想定重建
### Docs
- 对接文档 V1.6:去历史命名对照,只写现状
- 架构设计 V15同步模型表结构 + 枚举值
### Metrics
- 测试 **238**,全量通过 11s
---
## [0.9.0] - 2026-06-17
### Breaking — 运动学前向计算 + 基础数据 CRUD

View File

@ -1 +1 @@
0.9.0
0.10.0

View File

@ -1,6 +1,6 @@
# 反无人机仿真系统 — 总体架构设计
> **版本**V14
> **版本**V15
> **日期**2026-06-17
> **状态**:已实现
> **变更**V14 新增 DataService 基础数据 CRUD + FrameDataStore 内存回放架构
@ -185,7 +185,7 @@ 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 DroneType { Rotor = 0, FixedWing = 1, Electric = 2, Piston = 3, HighSpeed = 4 }
enum DroneType { Rotor = 0, FixedWing = 1, HighSpeed = 2 }
enum PowerType { Electric = 0, Piston = 1, Jet = 2 }
// === 装备 & 搭载平台 ===
@ -308,6 +308,7 @@ CounterDroneBackend_Data/
| Id | TEXT | PK | GUID |
| Name | TEXT | NOT NULL | 任务名称 |
| ScenarioNumber | TEXT | UNIQUE | SIM-yyyyMMdd-xxx |
| Description | TEXT | | 想定描述 |
| Status | INTEGER | DEFAULT 0 | 0=草稿 1=配置中 2=已完成 |
| CurrentStep | INTEGER | DEFAULT 1 | 当前配置步骤 1-5 |
| TickRate | INTEGER | DEFAULT 20 | 仿真 Tick 频率Hz |
@ -348,14 +349,16 @@ CounterDroneBackend_Data/
> 管控区域在场景设置(地形+天气)之后配置。无人机进入管控区域 → 触发 ZoneIntruded 事件 → 该无人机任务失败。
#### DroneProfile — 步骤2目标配置
#### DroneProfile — 步骤2无人机批次参数
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| Id | TEXT | PK | GUID |
| ScenarioId | TEXT | FK | |
| WaveId | TEXT | FK | 关联无人机批次(同一 WaveId 的无人机共享航路) |
| DroneType | INTEGER | | 0旋翼 1固定翼 2电推 3活塞 4高速 |
| DroneType | INTEGER | | 0旋翼 1固定翼 2高速 |
| Model | TEXT | | 型号 |
| Description | TEXT | | 描述/用途 |
| Quantity | INTEGER | DEFAULT 1 | 目标数量 |
| PowerType | INTEGER | | 0电推 1活塞 2喷吸气 |
| Wingspan | REAL | | m |
@ -368,8 +371,6 @@ CounterDroneBackend_Data/
|----------|---------|---------------|----------------|
| 旋翼 | 1.2 | 60 | 300 |
| 固定翼 | 3.5 | 150 | 1000 |
| 电推 | 1.8 | 100 | 500 |
| 活塞 | 2.5 | 120 | 800 |
| 高速目标 | 1.5 | 300 | 2000 |
#### EquipmentDeployment — 步骤3装备部署火力单元 + 独立探测节点)
@ -381,6 +382,7 @@ CounterDroneBackend_Data/
| EquipmentRole | INTEGER | | 0=独立探测节点 1=火力单元(发射平台) |
| Quantity | INTEGER | DEFAULT 1 | 部署数量 |
| WaveId | TEXT | NULLABLE | 可选关联批次(用于 UI 分组,火力单元是独立作战单位,不强依赖批次) |
| Description | TEXT | | 部署备注 |
| // 以下为火力单元(发射平台)专用字段 |
| PlatformType | INTEGER | NULLABLE | 0=空基(大型无人机) 1=地基(炮弹),独立探测节点为 NULL |
| PositionX | REAL | | 部署位置 |

View File

@ -1,7 +1,7 @@
# 后端对接文档Unity 前端)
> **版本**V1.5
> **日期**2026-06-17
> **版本**V1.6
> **日期**2026-06-18
> **Unity 版本**2022.3.62f3c1
---
@ -52,7 +52,7 @@ var ammo = ds.GetAllAmmo();
var units = ds.GetAllFireUnits();
// 新增
ds.SaveDrone(new DroneSpec { Id = "custom", Name = "自定义", TypicalSpeed = 100, ... });
ds.SaveDrone(new DroneSpec { Id = "custom", Name = "自定义", Model = "DJI-M3", Description = "小型四旋翼", TypicalSpeed = 100, ... });
// 删除
ds.DeleteDrone("custom");
@ -70,18 +70,24 @@ var demos = scenario.Search("Demo", null, null, 1, 100);
var scenarioId = demos.Items[0].Id;
// 方式 B自定义
var scenario = scenario.CreateScenario("我的想定", "");
scenario.SaveScene(scenario.Id, new CombatScene { WindSpeed = 5, WindDirection = (int)WindDirection.E });
scenario.SaveTarget(scenario.Id, new DroneProfile { WaveId = "w1", Quantity = 1, TypicalSpeed = 200, TypicalAltitude = 500 });
scenario.SaveRoute(scenario.Id, "w1", new RoutePlan(), new List<Waypoint> {
var sc = scenario.CreateScenario("我的想定", "");
scenario.SaveScene(sc.Id, new CombatScene { WindSpeed = 5, WindDirection = (int)WindDirection.E });
scenario.SaveTarget(sc.Id, new DroneProfile {
WaveId = "w1", Model = "Shahed-136", Description = "活塞巡飞弹",
Quantity = 1, DroneType = (int)DroneType.FixedWing,
TypicalSpeed = 200, TypicalAltitude = 500
});
scenario.SaveRoute(sc.Id, "w1", new RoutePlan(), new List<Waypoint> {
new() { PosX = 0, PosY = 500, PosZ = 0, Speed = 200 },
new() { PosX = 10000, PosY = 500, PosZ = 0, Speed = 200 }
});
scenario.SaveDeployment(scenario.Id, new List<EquipmentDeployment> {
new() { EquipmentRole = 1, PlatformType = 1, Quantity = 1, PositionX = 5000, AerosolType = 0, MunitionCount = 8 }
scenario.SaveDeployment(sc.Id, new List<EquipmentDeployment> {
new() { EquipmentRole = 1, PlatformType = 1, Quantity = 1,
PositionX = 5000, AerosolType = 0, MunitionCount = 8,
Description = "地面轻型平台" }
});
scenario.SaveCloud(scenario.Id, new CloudDispersal { AerosolType = 0, DisperseHeight = 500 });
scenario.UpdateStep(scenario.Id, 5);
scenario.SaveCloud(sc.Id, new CloudDispersal { AerosolType = 0, DisperseHeight = 500 });
scenario.UpdateStep(sc.Id, 5);
```
### 3.3 步骤 3运行仿真
@ -142,7 +148,8 @@ mgr.DataService.GetAllFireUnits() / GetAllDrones() / GetAllSensors()
mgr.DataService.GetAllEnvironments() / GetAllFormations() / GetAllRoutes()
// 想定 CRUD
mgr.CreateScenario(name, "") / mgr.DeleteScenario(id) / mgr.Search(kw, from, to, page, size)
mgr.CreateScenario(name, number) / mgr.DeleteScenario(id)
mgr.Search(kw, from, to, page, size)
mgr.SaveScene / SaveTarget / SaveDeployment / SaveCloud / SaveRoute / UpdateStep
mgr.GetDetail(id) → ScenarioConfig
```
@ -165,6 +172,7 @@ runner.Stop();
var rm = GetComponent<ReportManager>();
rm.Generate(scenarioId, detail, events, status, duration) → SimulationReport
rm.Export(reportId) → 文件路径
rm.Export(reportId, "D:\\MyReports") // 支持指定导出路径
```
### ReplayController — 回放
@ -199,7 +207,7 @@ replay.TotalFrames / replay.GetFrame(index)
| 实体 | 关键属性 |
|------|------|
| **DroneEntity** | Id, PosX/Y/Z, Hp, Status, Type, Wingspan, CruiseSpeed, Route, TraveledArc, TotalArc, Progress |
| **DroneEntity** | Id, PosX/Y/Z, Hp, Status, DroneType, Wingspan, CruiseSpeed, Route, TraveledArc, TotalArc, Progress |
| **CloudEntity** | Id, PosX/Y/Z, Radius, Density, Phase, Elapsed, IsDissipated |
| **MunitionEntity** | Id, PosX/Y/Z, Velocity, Start, LaunchTime, ElapsedTime, LaunchAngle, Azimuth, MuzzleVelocity, FlightDuration, Target, HasArrived |
| **PlatformEntity** | Id, PosX/Y/Z, CurrentVelocity, State, MunitionCount, Cooldown, MuzzleVelocity, CruiseSpeed, ReleaseAltitude, Target, FlightDistance |
@ -207,17 +215,48 @@ replay.TotalFrames / replay.GetFrame(index)
---
## 七、规格类命名对照
## 七、核心模型
| 旧名 | 新名 | SQLite 表 |
### 7.1 数据库表
| 模型 | SQLite 表 | 说明 |
|------|------|------|
| `TargetPreset` | `DroneSpec` | `DroneSpec` |
| `DetectionPreset` | `SensorSpec` | `SensorSpec` |
| `WeatherPreset` | `EnvironmentSpec` | `EnvironmentSpec` |
| `FireUnitTemplate` | `FireUnitSpec` | `FireUnitSpec` |
| `RoutePreset` | `RouteTemplate` | `RouteTemplate` |
| `FormationTemplate` | 不变 | `FormationTemplate` |
| `AmmunitionSpec` | 不变 | `AmmunitionSpec` |
| `Scenario` | `Scenario` | 想定任务 |
| `CombatScene` | `CombatScene` | 作战环境 |
| `DroneProfile` | `DroneProfile` | 无人机批次参数 |
| `EquipmentDeployment` | `EquipmentDeployment` | 装备部署 |
| `CloudDispersal` | `CloudDispersal` | 云团抛撒配置 |
| `RoutePlan` | `RoutePlan` | 航路规划 |
| `Waypoint` | `Waypoint` | 航路点 |
| `ControlZone` | `ControlZone` | 管控区域 |
| `SimulationReport` | `SimulationReport` | 仿真报告 |
| `AmmunitionSpec` | `AmmunitionSpec` | 弹药基础参数 |
| `DroneSpec` | `DroneSpec` | 无人机基础模板 |
| `FireUnitSpec` | `FireUnitSpec` | 火力单元基础模板 |
| `SensorSpec` | `SensorSpec` | 传感器基础模板 |
| `EnvironmentSpec` | `EnvironmentSpec` | 环境基础模板 |
| `FormationTemplate` | `FormationTemplate` | 编队基础模板 |
| `RouteTemplate` | `RouteTemplate` | 航线基础模板 |
| `ModelInfo` | `ModelInfo` | 3D 模型元数据 |
### 7.2 关键属性
| 模型 | 属性 | 类型 | 说明 |
|------|------|------|------|
| `DroneProfile` | `Model` | string | 型号 |
| `DroneProfile` | `Description` | string | 描述/用途 |
| `DroneProfile` | `DroneType` | DroneType | Rotor / FixedWing / HighSpeed |
| `DroneProfile` | `PowerType` | PowerType | Electric / Piston / Jet |
| `DroneProfile` | `TypicalSpeed` | double | 典型速度 (km/h) |
| `DroneProfile` | `TypicalAltitude` | double | 典型高度 (m) |
| `Scenario` | `ScenarioNumber` | string | 想定编号(唯一) |
| `Scenario` | `Description` | string | 想定描述 |
| `EquipmentDeployment` | `Description` | string | 部署备注 |
| `EquipmentDeployment` | `MuzzleVelocity` | double? | 初速 (m/s) |
| `EquipmentDeployment` | `CruiseSpeed` | double? | 巡航速度 (m/s),空基专用 |
| `DroneSpec` | `Model` | string | 型号 |
| `DroneSpec` | `Description` | string | 描述/用途 |
| `FireUnitSpec` | `Description` | string | 描述/用途 |
---
@ -252,4 +291,4 @@ dotnet publish -c Release -o ../../unity_plugins
|------|------|
| 架构设计 | `docs/design/architecture/总体架构设计.md` |
| 实体事件映射 | `docs/design/technical/仿真器实体与事件映射.md` |
| 测试状态 | **243 测试11 秒(全部通过)** |
| 测试状态 | **238 测试11 秒(全部通过)** |

View File

@ -82,7 +82,7 @@ namespace CounterDrone.Core
.FirstOrDefault(m => m.Key == "scenariosVersion")?.Value;
// 版本未变 → 跳过
if (currentVersion == "3") return;
if (currentVersion == "4") return;
var defaults = DefaultData.Load(_paths);
var scenario = new ScenarioService(
@ -93,11 +93,16 @@ namespace CounterDrone.Core
DefaultScenarios.Seed(scenario, defaults);
db.InsertOrReplace(new MetaEntry { Key = "scenariosVersion", Value = "3" });
db.InsertOrReplace(new MetaEntry { Key = "scenariosVersion", Value = "4" });
}
private void CreateMainTables(SQLiteConnection db)
{
// 删除旧版本残留表V1.6 重命名)
db.Execute("DROP TABLE IF EXISTS SimTask");
db.Execute("DROP TABLE IF EXISTS TargetConfig");
db.Execute("DROP TABLE IF EXISTS SimulationReport"); // TaskNumber→ScenarioNumber
db.CreateTable<ModelInfo>();
db.CreateTable<AmmunitionSpec>();
db.CreateTable<Scenario>();