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

75 lines
2.8 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 CounterDrone.Core.Algorithms;
using CounterDrone.Core.Models;
using Xunit;
namespace CounterDrone.Core.Tests
{
public class DispersionModelTests
{
private static AmmunitionSpec Ammo() => DefaultAmmunition.GetByType(AerosolType.InertGas);
[Fact]
public void Phase1_InitialRadius_FromBurstCharge()
{
var m = new GaussianPuffDispersion();
m.Initialize(Ammo(), new CombatScene { WindSpeed = 0 }, new Algorithms.Vector3(0, 0, 0), 0f);
// R₀ = 3.3 × 0.3^0.32 ≈ 2.2m
Assert.True(m.Radius > 1.5f && m.Radius < 5f, $"R₀={m.Radius:F2}");
}
[Fact]
public void Phase2_Radius_GrowsWithSqrtT()
{
var m = new GaussianPuffDispersion();
m.Initialize(Ammo(), new CombatScene { WindSpeed = 0 }, new Algorithms.Vector3(0, 0, 0), 0f);
var r1 = m.Radius;
m.Tick(9f, 0f, WindDirection.N);
var r2 = m.Radius;
m.Tick(7f, 0f, WindDirection.N); // total 16s
var r3 = m.Radius;
// 0→9s: Δ = k×3 = 15; 9→16s: Δ = k×(4-3) = 5
Assert.True(r3 > r2 && r2 > r1, "半径应单调递增");
}
[Fact]
public void Phase2_Density_DropsWithVolume()
{
var m = new GaussianPuffDispersion();
m.Initialize(Ammo(), new CombatScene { WindSpeed = 0 }, new Algorithms.Vector3(0, 0, 0), 0f);
var d1 = m.CoreDensity;
m.Tick(10f, 0f, WindDirection.N);
Assert.True(m.CoreDensity < d1, "膨胀后密度应下降");
}
[Fact]
public void Phase3_SwitchesAfter30s()
{
var m = new GaussianPuffDispersion();
m.Initialize(Ammo(), new CombatScene { WindSpeed = 0 }, new Algorithms.Vector3(0, 0, 0), 0f);
m.Tick(35f, 0f, WindDirection.N);
Assert.False(m.IsDissipated, "35s不应消散");
}
[Fact]
public void Dissipates_AfterMaxDuration()
{
var m = new GaussianPuffDispersion();
var a = Ammo();
a.MaxDuration = 2;
m.Initialize(a, new CombatScene { WindSpeed = 0 }, new Algorithms.Vector3(0, 0, 0), 0f);
m.Tick(3f, 0f, WindDirection.N);
Assert.True(m.IsDissipated);
}
[Fact]
public void DefaultAmmo_ParametersInReasonableRange()
{
var inert = DefaultAmmunition.GetByType(AerosolType.InertGas);
Assert.True(inert.BurstChargeKg is > 0.01 and < 5, "爆发药应 0.01~5kg");
Assert.True(inert.TurbulentExpansionK is > 1 and < 20, "湍流系数应 1~20");
Assert.True(inert.EffectiveConcentration is >= 0.0001 and < 0.1, "有效浓度阈值应 ≥ 0.0001");
Assert.True(inert.SourceStrength is > 1 and < 100, "源强应 1~100kg");
}
}
}