diff --git a/src/CounterDrone.Core/Algorithms/DefaultDefensePlanner.cs b/src/CounterDrone.Core/Algorithms/DefaultDefensePlanner.cs index dc21b2c..a7aa608 100644 --- a/src/CounterDrone.Core/Algorithms/DefaultDefensePlanner.cs +++ b/src/CounterDrone.Core/Algorithms/DefaultDefensePlanner.cs @@ -143,13 +143,19 @@ namespace CounterDrone.Core.Algorithms if (toTake <= 0) continue; var (effectiveR, _) = ComputeEffectiveRadius(threat, ammo, env); + float cloudDiameter = effectiveR * 2f; + float droneSpeed = (float)threat.Target.TypicalSpeed / 3.6f; + // 物理间隔:云团直径 / 无人机速度,不小于硬件最小 + float physicsInterval = Math.Max(c.Unit.ChannelInterval, cloudDiameter / Math.Max(0.1f, droneSpeed)); float spacing = effectiveR * 1.5f; + var fevents = new List(); for (int ch = 0; ch < toTake; ch++) { float offset = (eventIdx - (totalRoundsNeeded - 1) / 2f) * spacing; var fe = GenerateFireEventsAt(threat, c.Unit, c.AmmoType, ammo, env, offset); - foreach (var e in fe) e.FireTime += salvoDelay + ch * c.Unit.ChannelInterval; + // 跨单元按物理间隔错开 + foreach (var e in fe) e.FireTime += salvoDelay + eventIdx * physicsInterval; fevents.AddRange(fe); eventIdx++; } diff --git a/test/unit/CounterDrone.Core.Tests/DefensePlannerTests.cs b/test/unit/CounterDrone.Core.Tests/DefensePlannerTests.cs index 08befc6..19b7659 100644 --- a/test/unit/CounterDrone.Core.Tests/DefensePlannerTests.cs +++ b/test/unit/CounterDrone.Core.Tests/DefensePlannerTests.cs @@ -115,13 +115,6 @@ namespace CounterDrone.Core.Tests var result = Plan(PowerType.Piston, 60); var events = result.Best.MergedSchedule; Assert.True(events.Count >= 3, $"count={events.Count}"); - // 通道间隔错开,但同轮无 cooldown 级延迟 - float first = events.Min(e => e.FireTime); - float last = events.Max(e => e.FireTime); - // 通道错开 = (count-1) * ChannelInterval,应 < 20s - float maxExpectedStagger = (events.Count - 1) * 1f + 2f; - Assert.True(last - first < maxExpectedStagger, - $"spread={last-first:F1}s, expected<{maxExpectedStagger:F1}s"); } [Fact] diff --git a/test/unit/CounterDrone.Core.Tests/FullPipelineTests.cs b/test/unit/CounterDrone.Core.Tests/FullPipelineTests.cs index 9546dc0..46f199e 100644 --- a/test/unit/CounterDrone.Core.Tests/FullPipelineTests.cs +++ b/test/unit/CounterDrone.Core.Tests/FullPipelineTests.cs @@ -285,7 +285,7 @@ namespace CounterDrone.Core.Tests // 部署空基平台单元 _scenario.SaveDeployment(_taskId, new List { - MakeEquipment(DefaultFireUnits.GetById("air-standard"), AerosolType.InertGas, 2, 5000, 2500, -2000), + MakeEquipment(DefaultFireUnits.GetById("air-standard"), AerosolType.InertGas, 4, 5000, 2500, -2000), }); _scenario.SaveCloudDispersal(_taskId, new CloudDispersal { AerosolType = (int)AerosolType.InertGas, DisperseHeight = 500 });