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++)
{