From e3486e5bdf5d27bceac1449da63ef2c3924e54af Mon Sep 17 00:00:00 2001
From: tian <11429339@qq.com>
Date: Fri, 12 Jun 2026 11:36:15 +0800
Subject: [PATCH] =?UTF-8?q?FireEvent=E7=A7=BB=E5=85=A5Algorithms,=20Adviso?=
=?UTF-8?q?r=E7=94=9F=E6=88=90FireSchedule,=20=E5=BC=95=E6=93=8E/=E6=B5=8B?=
=?UTF-8?q?=E8=AF=95=E9=9B=B6=E5=AF=B9=E9=BD=90=E9=80=BB=E8=BE=91,=20129?=
=?UTF-8?q?=E6=B5=8B=E8=AF=95=E9=80=9A=E8=BF=87?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Algorithms/AlgorithmTypes.cs | 21 ++++++----
.../Algorithms/DefaultDefenseAdvisor.cs | 21 ++++++++--
.../Models/CloudDispersal.cs | 5 ---
.../Simulation/SimulationEngine.cs | 8 ----
.../DispersionAdvisorRealityTests.cs | 26 ++++---------
.../FullPipelineTests.cs | 39 ++-----------------
6 files changed, 41 insertions(+), 79 deletions(-)
diff --git a/src/CounterDrone.Core/Algorithms/AlgorithmTypes.cs b/src/CounterDrone.Core/Algorithms/AlgorithmTypes.cs
index 642c62a..6d7beb2 100644
--- a/src/CounterDrone.Core/Algorithms/AlgorithmTypes.cs
+++ b/src/CounterDrone.Core/Algorithms/AlgorithmTypes.cs
@@ -3,7 +3,7 @@ using CounterDrone.Core.Models;
namespace CounterDrone.Core.Algorithms
{
- /// 威胁画像 — 防御推荐算法的输入
+ /// 威胁画像
public class ThreatProfile
{
public CombatScene Environment { get; set; } = new();
@@ -26,19 +26,15 @@ namespace CounterDrone.Core.Algorithms
public AerosolType RecommendedAerosolType { get; set; }
public string AerosolRationale { get; set; } = string.Empty;
public CloudDispersal RecommendedCloud { get; set; } = new();
- /// 多轮次云团列表(含主云团)
- public List CloudSalvo { get; set; } = new();
-
- /// 齐射参数:弹药数,由算法填充
- public int SalvoRounds { get; set; } = 1;
- /// 齐射参数:云团间隔(m),由算法填充
- public float SalvoSpacing { get; set; }
public List Platforms { get; set; } = new();
public List Detections { get; set; } = new();
public float InterceptProbability { get; set; }
public string SummaryRationale { get; set; } = string.Empty;
+
+ /// 由推荐方案生成的发射计划,仿真器直接执行
+ public List FireSchedule { get; set; } = new();
}
public class RecommendedPlatform
@@ -80,4 +76,13 @@ namespace CounterDrone.Core.Algorithms
public string ColorHex { get; set; } = "#FFFFFF";
public float SizeMultiplier { get; set; } = 1.0f;
}
+
+ /// 发射计划中的单次事件(算法生成 → 引擎执行)
+ public class FireEvent
+ {
+ public float FireTime;
+ public int PlatformIndex;
+ public float TargetX, TargetY, TargetZ;
+ public float MuzzleVelocity;
+ }
}
diff --git a/src/CounterDrone.Core/Algorithms/DefaultDefenseAdvisor.cs b/src/CounterDrone.Core/Algorithms/DefaultDefenseAdvisor.cs
index 44aebf8..f876a57 100644
--- a/src/CounterDrone.Core/Algorithms/DefaultDefenseAdvisor.cs
+++ b/src/CounterDrone.Core/Algorithms/DefaultDefenseAdvisor.cs
@@ -105,6 +105,22 @@ namespace CounterDrone.Core.Algorithms
var expansionTime = (float)Math.Pow((effectiveR - r0) / k, 2);
var recommendedTiming = halfTime - expansionTime;
+ // 生成发射计划
+ var fireSchedule = new List();
+ for (int i = 0; i < roundsNeeded; i++)
+ {
+ var offset = (i - (roundsNeeded - 1) / 2f) * spacing;
+ fireSchedule.Add(new FireEvent
+ {
+ FireTime = recommendedTiming,
+ PlatformIndex = i % roundsNeeded,
+ TargetX = mid.X + offset,
+ TargetY = mid.Y,
+ TargetZ = mid.Z,
+ MuzzleVelocity = 800f,
+ });
+ }
+
var bestCloud = new CloudDispersal
{
AerosolType = (int)aerosolType,
@@ -117,8 +133,6 @@ namespace CounterDrone.Core.Algorithms
Source = "Algorithm",
PositionMode = (int)PositionMode.AlgorithmRecommended,
RecommendedTiming = recommendedTiming,
- SalvoRounds = roundsNeeded,
- SalvoSpacing = spacing,
};
// 平台部署:假设齐射(同时发射),每门炮打一发后冷却 5s
@@ -142,8 +156,7 @@ namespace CounterDrone.Core.Algorithms
RecommendedAerosolType = aerosolType,
AerosolRationale = rationale,
RecommendedCloud = bestCloud,
- SalvoRounds = roundsNeeded,
- SalvoSpacing = spacing,
+ FireSchedule = fireSchedule,
Platforms = platforms,
Detections = new List
{
diff --git a/src/CounterDrone.Core/Models/CloudDispersal.cs b/src/CounterDrone.Core/Models/CloudDispersal.cs
index 719cebb..cf3ccc7 100644
--- a/src/CounterDrone.Core/Models/CloudDispersal.cs
+++ b/src/CounterDrone.Core/Models/CloudDispersal.cs
@@ -45,10 +45,5 @@ namespace CounterDrone.Core.Models
public double? CriticalPosY { get; set; }
public double? CriticalPosZ { get; set; }
public double? CriticalTiming { get; set; }
-
- /// 齐射弹药数(推荐算法填充)
- public int SalvoRounds { get; set; }
- /// 云团间隔(m)(推荐算法填充)
- public double SalvoSpacing { get; set; }
}
}
diff --git a/src/CounterDrone.Core/Simulation/SimulationEngine.cs b/src/CounterDrone.Core/Simulation/SimulationEngine.cs
index 69eb8a4..3285d84 100644
--- a/src/CounterDrone.Core/Simulation/SimulationEngine.cs
+++ b/src/CounterDrone.Core/Simulation/SimulationEngine.cs
@@ -9,14 +9,6 @@ using SQLite;
namespace CounterDrone.Core.Simulation
{
- public class FireEvent
- {
- public float FireTime;
- public int PlatformIndex;
- public float TargetX, TargetY, TargetZ;
- public float MuzzleVelocity;
- }
-
/// 仿真引擎 — 纯执行器,接收发射计划按时间表执行
public class SimulationEngine
{
diff --git a/test/unit/CounterDrone.Core.Tests/DispersionAdvisorRealityTests.cs b/test/unit/CounterDrone.Core.Tests/DispersionAdvisorRealityTests.cs
index 69f1005..be19603 100644
--- a/test/unit/CounterDrone.Core.Tests/DispersionAdvisorRealityTests.cs
+++ b/test/unit/CounterDrone.Core.Tests/DispersionAdvisorRealityTests.cs
@@ -1,11 +1,11 @@
using System.Collections.Generic;
+using System.Linq;
using CounterDrone.Core.Algorithms;
using CounterDrone.Core.Models;
using Xunit;
namespace CounterDrone.Core.Tests
{
- /// 验证三阶段扩散模型下推荐算法的参数合理性
public class DispersionAdvisorRealityTests
{
private ThreatProfile CreatePistonThreat(float speed = 200, float length = 20000)
@@ -33,24 +33,15 @@ namespace CounterDrone.Core.Tests
var advisor = new DefaultDefenseAdvisor(DefaultAmmunition.GetAll());
var rec = advisor.Recommend(CreatePistonThreat());
- // 基本断言
Assert.Equal(AerosolType.InertGas, rec.Best.RecommendedAerosolType);
- Assert.True(rec.Best.SalvoRounds >= 1, $"齐射数={rec.Best.SalvoRounds},应≥1");
- Assert.True(rec.Best.SalvoSpacing > 0, $"间隔={rec.Best.SalvoSpacing}m,应>0");
- Assert.True(rec.Best.RecommendedCloud.RecommendedTiming > 0,
- $"推荐时机={rec.Best.RecommendedCloud.RecommendedTiming}s,应>0");
+ Assert.NotEmpty(rec.Best.FireSchedule);
+ Assert.True(rec.Best.FireSchedule.Count >= 1, $"齐射数={rec.Best.FireSchedule.Count},应≥1");
- // 检查膨胀时间
- var ammo = DefaultAmmunition.GetByType(AerosolType.InertGas);
- var r0 = 3.3f * System.Math.Pow(ammo.BurstChargeKg, 0.32);
- var k = ammo.TurbulentExpansionK;
- var halfTime = 20000f / (200f / 3.6f) / 2f;
- var effectiveR = r0 + k * System.Math.Sqrt(System.Math.Min(halfTime, 30));
- if (halfTime > 30) effectiveR += k * System.Math.Sqrt(halfTime - 30) * 0.3f;
-
- // 膨胀应在合理范围
- Assert.True(effectiveR > 10, $"有效半径={effectiveR:F1}m,应>10m(初始{r0:F1}m)");
- Assert.True(effectiveR < 200, $"有效半径={effectiveR:F1}m,应<200m");
+ // 发射计划中的云团位置应在航路范围内且沿航路展开
+ var positions = rec.Best.FireSchedule.Select(f => f.TargetX).OrderBy(x => x).ToList();
+ Assert.True(positions.First() > 0, "第一个云团应在航路起点之后");
+ Assert.True(positions.Last() < 20000, "最后一个云团应在航路终点之前");
+ Assert.True(positions.Last() - positions.First() > 10, "云团应沿航路展开");
}
[Fact]
@@ -62,7 +53,6 @@ namespace CounterDrone.Core.Tests
var timing = rec.Best.RecommendedCloud.RecommendedTiming!.Value;
var halfTime = 20000f / (200f / 3.6f) / 2f;
- // 推荐时机应明显早于无人机到达中点(因为有飞行时间和膨胀时间)
Assert.True(timing < halfTime - 5,
$"推荐时机={timing:F1}s 应早于中点={halfTime:F1}s(预留飞行+膨胀时间)");
}
diff --git a/test/unit/CounterDrone.Core.Tests/FullPipelineTests.cs b/test/unit/CounterDrone.Core.Tests/FullPipelineTests.cs
index ec34143..795f427 100644
--- a/test/unit/CounterDrone.Core.Tests/FullPipelineTests.cs
+++ b/test/unit/CounterDrone.Core.Tests/FullPipelineTests.cs
@@ -21,6 +21,7 @@ namespace CounterDrone.Core.Tests
private readonly FrameDataStore _frameStore;
private readonly SQLiteConnection _mainDb;
private List _ammoCatalog;
+ private List _lastFireSchedule;
private string _taskId = string.Empty;
public FullPipelineTests()
@@ -73,42 +74,7 @@ namespace CounterDrone.Core.Tests
/// 从推荐方案的时机参数生成发射计划
private List BuildFireSchedule(TaskFullConfig detail)
{
- var schedule = new List();
- var cloud = detail.Cloud;
-
- if (!cloud.RecommendedTiming.HasValue || cloud.RecommendedTiming.Value <= 0)
- return schedule;
-
- var platforms = detail.Equipment
- .Where(e => e.EquipmentRole == (int)EquipmentRole.LaunchPlatform)
- .ToList();
- if (platforms.Count == 0) return schedule;
-
- // 齐射展开:按推荐间隔沿航路排列云团位置
- var spacing = (float)cloud.SalvoSpacing;
- if (spacing <= 0) spacing = 50f;
- var releaseAlt = (float)cloud.DisperseHeight;
- if (releaseAlt < 10) releaseAlt = 300f;
-
- for (int i = 0; i < platforms.Count; i++)
- {
- var p = platforms[i];
- var mv = (float)(p.MuzzleVelocity ?? 800);
- var offset = (i - (platforms.Count - 1) / 2f) * spacing;
- var tx = (float)cloud.PositionX + offset; var ty = (float)cloud.PositionY; var tz = (float)cloud.PositionZ;
- var dx = tx - (float)p.PositionX; var dz = tz - (float)p.PositionZ;
- var dist = (float)Math.Sqrt(dx * dx + dz * dz);
- var angle = Kinematics.CalculateLaunchAngle(dist, mv, releaseAlt);
- var sinA = (float)Math.Sin(angle);
- var tUp = mv * sinA / 9.81f;
- var peakH = mv * mv * sinA * sinA / (2f * 9.81f);
- var dropH = Math.Max(0, peakH - releaseAlt);
- var ft = tUp + (float)Math.Sqrt(2f * dropH / 9.81f);
- var fireTime = (float)cloud.RecommendedTiming!.Value - ft;
- if (fireTime < 0) fireTime = 0.1f;
- schedule.Add(new FireEvent { FireTime = fireTime, PlatformIndex = i, TargetX = tx, TargetY = ty, TargetZ = tz, MuzzleVelocity = mv });
- }
- return schedule;
+ return _lastFireSchedule ?? new List();
}
/// 将 DefenseAdvisor 推荐方案写入想定
@@ -152,6 +118,7 @@ namespace CounterDrone.Core.Tests
MuzzleVelocity = p.MuzzleVelocity,
});
_scenario.SaveDeployment(_taskId, equips);
+ _lastFireSchedule = rec.Best.FireSchedule;
return rec;
}