From c8e066be647058d1790262c20cfbd3e2514e5a5a Mon Sep 17 00:00:00 2001 From: tian <11429339@qq.com> Date: Fri, 19 Jun 2026 09:59:55 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=BF=E7=9C=9F=E5=AE=9E=E4=BD=93=20+ModelId?= =?UTF-8?q?=EF=BC=9ADroneSpec/FireUnitSpec/SensorSpec=20=E2=86=92=20Entity?= =?UTF-8?q?Snapshot?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - DroneSpec/FireUnitSpec/SensorSpec 加 ModelId (FK→ModelInfo) - DroneEntity/PlatformEntity/DetectionEntity 内部带 ModelId - DetectionSource +ModelId - EntitySnapshot +ModelId,每帧推送给 Unity - CollectSnapshots 传播所有实体 ModelId --- src/CounterDrone.Core/Algorithms/AlgorithmTypes.cs | 1 + src/CounterDrone.Core/DefaultData.cs | 9 +++++++++ src/CounterDrone.Core/Simulation/DetectionEntity.cs | 4 +++- src/CounterDrone.Core/Simulation/DroneEntity.cs | 2 ++ src/CounterDrone.Core/Simulation/PlatformEntity.cs | 3 +++ src/CounterDrone.Core/Simulation/SimTypes.cs | 2 ++ src/CounterDrone.Core/Simulation/SimulationEngine.cs | 12 +++++++----- 7 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/CounterDrone.Core/Algorithms/AlgorithmTypes.cs b/src/CounterDrone.Core/Algorithms/AlgorithmTypes.cs index 5874f32..dd89239 100644 --- a/src/CounterDrone.Core/Algorithms/AlgorithmTypes.cs +++ b/src/CounterDrone.Core/Algorithms/AlgorithmTypes.cs @@ -154,6 +154,7 @@ namespace CounterDrone.Core.Algorithms public float MaxElevation { get; set; } = float.MaxValue; public float MinDetectAlt { get; set; } = float.MaxValue; public float MaxDetectAlt { get; set; } = float.MaxValue; + public string? ModelId { get; set; } } /// 规划方案 diff --git a/src/CounterDrone.Core/DefaultData.cs b/src/CounterDrone.Core/DefaultData.cs index 5a9f521..156cb7c 100644 --- a/src/CounterDrone.Core/DefaultData.cs +++ b/src/CounterDrone.Core/DefaultData.cs @@ -114,6 +114,9 @@ namespace CounterDrone.Core public double MuzzleVelocity { get; set; } public double CruiseSpeed { get; set; } public double ReleaseAltitude { get; set; } + + /// 3D 模型 ID(FK → ModelInfo),Unity 可视化用 + public string ModelId { get; set; } = ""; [SQLite.Ignore] public List AmmoTypes { get; set; } = new(); public double RadarRange { get; set; } @@ -157,6 +160,9 @@ namespace CounterDrone.Core public double TypicalSpeed { get; set; } public double TypicalAltitude { get; set; } + /// 3D 模型 ID(FK → ModelInfo),Unity 可视化用 + public string ModelId { get; set; } = ""; + public ScenarioDrone ToScenarioDrone(string waveId = "default") { return new ScenarioDrone @@ -179,6 +185,9 @@ namespace CounterDrone.Core public double EORange { get; set; } public double IRRange { get; set; } public double Accuracy { get; set; } = 50.0; + + /// 3D 模型 ID(FK → ModelInfo),Unity 可视化用 + public string ModelId { get; set; } = ""; // 3D 球冠几何(缺失时退化 2D) public double? MinElevation { get; set; } public double? MaxElevation { get; set; } diff --git a/src/CounterDrone.Core/Simulation/DetectionEntity.cs b/src/CounterDrone.Core/Simulation/DetectionEntity.cs index 1bd1152..be28b37 100644 --- a/src/CounterDrone.Core/Simulation/DetectionEntity.cs +++ b/src/CounterDrone.Core/Simulation/DetectionEntity.cs @@ -12,6 +12,7 @@ namespace CounterDrone.Core.Simulation { public string Id { get; } public DetectionSource Source { get; } + public string? ModelId { get; } public float PosX => Source.Position.X; public float PosY => Source.Position.Y; public float PosZ => Source.Position.Z; @@ -19,10 +20,11 @@ namespace CounterDrone.Core.Simulation /// 每无人机 Id → 探测状态(true=Detected, false=Undetected) private readonly Dictionary _droneStates = new(); - public DetectionEntity(string id, DetectionSource source) + public DetectionEntity(string id, DetectionSource source, string? modelId = null) { Id = id; Source = source; + ModelId = modelId; } /// 检查目标是否在本设备探测范围内(3D 球冠判定) diff --git a/src/CounterDrone.Core/Simulation/DroneEntity.cs b/src/CounterDrone.Core/Simulation/DroneEntity.cs index f9eca6d..2d1761d 100644 --- a/src/CounterDrone.Core/Simulation/DroneEntity.cs +++ b/src/CounterDrone.Core/Simulation/DroneEntity.cs @@ -14,6 +14,7 @@ namespace CounterDrone.Core.Simulation public PowerType PowerType { get; } public float Wingspan { get; } public float CruiseSpeed { get; } + public string? ModelId { get; } public List Route { get; } public float PosX { get; private set; } public float PosY { get; private set; } @@ -48,6 +49,7 @@ namespace CounterDrone.Core.Simulation DroneType = (DroneType)spec.DroneType; PowerType = (PowerType)spec.PowerType; Wingspan = (float)spec.Wingspan; + ModelId = string.IsNullOrEmpty(spec.ModelId) ? null : spec.ModelId; float spd = (float)route[0].Speed; if (spd <= 0) throw new InvalidOperationException($"无人机 {id}: 航路点速度必须 > 0"); CruiseSpeed = spd; diff --git a/src/CounterDrone.Core/Simulation/PlatformEntity.cs b/src/CounterDrone.Core/Simulation/PlatformEntity.cs index 96dd284..421497b 100644 --- a/src/CounterDrone.Core/Simulation/PlatformEntity.cs +++ b/src/CounterDrone.Core/Simulation/PlatformEntity.cs @@ -44,6 +44,8 @@ namespace CounterDrone.Core.Simulation // 地基平台 public float MuzzleVelocity { get; } + public string? ModelId { get; } + /// Ready 包含:冷却就绪 + 有弹药 + 非飞行中 public bool Ready => CooldownRemaining <= 0 && MunitionCount > 0 && State != PlatformState.FlyingToTarget; @@ -61,6 +63,7 @@ namespace CounterDrone.Core.Simulation MuzzleVelocity = (float)spec.MuzzleVelocity; CruiseSpeed = (float)spec.CruiseSpeed; ReleaseAltitude = (float)spec.ReleaseAltitude; + ModelId = string.IsNullOrEmpty(spec.ModelId) ? null : spec.ModelId; PatrolX = PosX; PatrolY = PosY; diff --git a/src/CounterDrone.Core/Simulation/SimTypes.cs b/src/CounterDrone.Core/Simulation/SimTypes.cs index e54ccf4..8480ed5 100644 --- a/src/CounterDrone.Core/Simulation/SimTypes.cs +++ b/src/CounterDrone.Core/Simulation/SimTypes.cs @@ -40,6 +40,8 @@ namespace CounterDrone.Core.Simulation public float VelX, VelY, VelZ; + public string? ModelId; + /// 仅 Flush 入库时使用,仿真期间保持 null public string? StateData; } diff --git a/src/CounterDrone.Core/Simulation/SimulationEngine.cs b/src/CounterDrone.Core/Simulation/SimulationEngine.cs index 0b54633..87d4833 100644 --- a/src/CounterDrone.Core/Simulation/SimulationEngine.cs +++ b/src/CounterDrone.Core/Simulation/SimulationEngine.cs @@ -161,7 +161,7 @@ namespace CounterDrone.Core.Simulation var detectionSrcs = BuildDetectionSources(config, _fireUnitSpecs, _sensorSpecs); int detIdx = 0; foreach (var src in detectionSrcs) - _detectionEntities.Add(new DetectionEntity($"det_{++detIdx}", src)); + _detectionEntities.Add(new DetectionEntity($"det_{++detIdx}", src, src.ModelId)); _munitions.Clear(); _clouds.Clear(); @@ -492,11 +492,12 @@ namespace CounterDrone.Core.Simulation RadarRange = (float)spec.RadarRange, EORange = (float)spec.EORange, IRRange = (float)spec.IRRange, - Accuracy = (float)(spec.MinElevation.HasValue ? 50f : 50f), // default accuracy + Accuracy = (float)(spec.MinElevation.HasValue ? 50f : 50f), MinElevation = (float)(spec.MinElevation ?? float.MaxValue), MaxElevation = (float)(spec.MaxElevation ?? float.MaxValue), MinDetectAlt = (float)(spec.MinDetectAlt ?? float.MaxValue), MaxDetectAlt = (float)(spec.MaxDetectAlt ?? float.MaxValue), + ModelId = string.IsNullOrEmpty(spec.ModelId) ? null : spec.ModelId, }); } } @@ -519,6 +520,7 @@ namespace CounterDrone.Core.Simulation MaxElevation = (float)(sensor.MaxElevation ?? float.MaxValue), MinDetectAlt = (float)(sensor.MinDetectAlt ?? float.MaxValue), MaxDetectAlt = (float)(sensor.MaxDetectAlt ?? float.MaxValue), + ModelId = string.IsNullOrEmpty(sensor.ModelId) ? null : sensor.ModelId, }); } } @@ -553,7 +555,7 @@ namespace CounterDrone.Core.Simulation { var d = _drones[i]; float vx = d.PosX - d.PrevX, vy = d.PosY - d.PrevY, vz = d.PosZ - d.PrevZ; - _snapshotPool.Add(new EntitySnapshot { EntityId = d.Id, EntityType = Models.EntityType.Drone, PosX = d.PosX, PosY = d.PosY, PosZ = d.PosZ, VelX = vx, VelY = vy, VelZ = vz, DamageStage = (int)_damageModel.GetDamageStage(1 - d.Hp), Hp = d.Hp }); + _snapshotPool.Add(new EntitySnapshot { EntityId = d.Id, EntityType = Models.EntityType.Drone, PosX = d.PosX, PosY = d.PosY, PosZ = d.PosZ, VelX = vx, VelY = vy, VelZ = vz, DamageStage = (int)_damageModel.GetDamageStage(1 - d.Hp), Hp = d.Hp, ModelId = d.ModelId }); } for (int i = 0; i < _munitions.Count; i++) { @@ -565,12 +567,12 @@ namespace CounterDrone.Core.Simulation { var p = _platforms[i]; var (vx, vy, vz) = p.CurrentVelocity; - _snapshotPool.Add(new EntitySnapshot { EntityId = p.Id, EntityType = Models.EntityType.Platform, PosX = p.PosX, PosY = p.PosY, PosZ = p.PosZ, VelX = vx, VelY = vy, VelZ = vz, PlatformStateStr = p.State.ToString() }); + _snapshotPool.Add(new EntitySnapshot { EntityId = p.Id, EntityType = Models.EntityType.Platform, PosX = p.PosX, PosY = p.PosY, PosZ = p.PosZ, VelX = vx, VelY = vy, VelZ = vz, PlatformStateStr = p.State.ToString(), ModelId = p.ModelId }); } for (int i = 0; i < _detectionEntities.Count; i++) { var d = _detectionEntities[i]; - _snapshotPool.Add(new EntitySnapshot { EntityId = d.Id, EntityType = Models.EntityType.DetectionEquip, PosX = d.PosX, PosY = d.PosY, PosZ = d.PosZ }); + _snapshotPool.Add(new EntitySnapshot { EntityId = d.Id, EntityType = Models.EntityType.DetectionEquip, PosX = d.PosX, PosY = d.PosY, PosZ = d.PosZ, ModelId = d.ModelId }); } for (int i = 0; i < _clouds.Count; i++) {