CounterDroneBackend/test/unit/CounterDrone.Core.Tests/DispersionAdvisorRealityTests.cs

71 lines
3.1 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections.Generic;
using CounterDrone.Core.Algorithms;
using CounterDrone.Core.Models;
using Xunit;
namespace CounterDrone.Core.Tests
{
/// <summary>验证三阶段扩散模型下推荐算法的参数合理性</summary>
public class DispersionAdvisorRealityTests
{
private ThreatProfile CreatePistonThreat(float speed = 200, float length = 20000)
{
return new ThreatProfile
{
Environment = new CombatScene { WindSpeed = 3, WindDirection = (int)WindDirection.W },
Targets = new List<TargetConfig>
{
new TargetConfig { PowerType = (int)PowerType.Piston, Quantity = 1,
TypicalSpeed = speed, TypicalAltitude = 500 },
},
Route = new RoutePlan { FormationMode = (int)FormationMode.Single },
Waypoints = new List<Waypoint>
{
new Waypoint { PosX = 0, PosY = 500, PosZ = 0 },
new Waypoint { PosX = length, PosY = 500, PosZ = 0 },
},
};
}
[Fact]
public void Piston_200kmh_20km_ProducesReasonableSalvo()
{
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");
// 检查膨胀时间
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");
}
[Fact]
public void Timing_AccountsForExpansion()
{
var advisor = new DefaultDefenseAdvisor(DefaultAmmunition.GetAll());
var rec = advisor.Recommend(CreatePistonThreat());
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预留飞行+膨胀时间)");
}
}
}