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

79 lines
3.3 KiB
C#

using System.Collections.Generic;
using CounterDrone.Core.Algorithms;
using CounterDrone.Core.Models;
using Xunit;
namespace CounterDrone.Core.Tests
{
public class DefenseAdvisorRealityTests
{
private static readonly List<AmmunitionSpec> TestAmmo = new()
{
new AmmunitionSpec { AerosolType = (int)AerosolType.InertGas, InitialRadius = 50, CoreDensity = 1.0, DispersionRateBase = 5, MaxRadius = 200, MaxDuration = 60 },
new AmmunitionSpec { AerosolType = (int)AerosolType.ActiveMaterial, InitialRadius = 30, CoreDensity = 2.0, DispersionRateBase = 3, MaxRadius = 150, MaxDuration = 45 },
};
[Fact]
public void PistonDrone_RecommendsReachableCloudPosition()
{
var threat = new ThreatProfile
{
Environment = new CombatScene
{
WindSpeed = 3,
WindDirection = (int)WindDirection.W,
},
Targets = new List<TargetConfig>
{
new TargetConfig
{
TargetType = (int)TargetType.Piston,
PowerType = (int)PowerType.Piston,
Quantity = 1, TypicalSpeed = 200, TypicalAltitude = 500,
},
},
Route = new RoutePlan { FormationMode = (int)FormationMode.Single },
Waypoints = new List<Waypoint>
{
new Waypoint { PosX = 0, PosY = 500, PosZ = 0, Speed = 200 },
new Waypoint { PosX = 20000, PosY = 500, PosZ = 0, Speed = 200 },
},
};
var advisor = new DefaultDefenseAdvisor(TestAmmo);
var rec = advisor.Recommend(threat);
// 1. 选型正确
Assert.Equal(AerosolType.InertGas, rec.Best.RecommendedAerosolType);
// 2. 云团位置应在航路上
var c = rec.Best.RecommendedCloud;
Assert.True(c.PositionX > 0 && c.PositionX < 20000,
$"云团 X={c.PositionX} 应在航路范围内");
Assert.True(c.PositionY >= 400 && c.PositionY <= 600,
$"云团 Y={c.PositionY} 应接近飞行高度 500");
// 3. 平台部署应有合理位置
Assert.NotEmpty(rec.Best.Platforms);
var p = rec.Best.Platforms[0];
// 4. 炮弹能打到吗?用运动学验证
var muzzleV = 800f;
var releaseAlt = (float)c.DisperseHeight;
var targetDist = (float)System.Math.Sqrt(
(c.PositionX - p.Position.X) * (c.PositionX - p.Position.X) +
(c.PositionZ - p.Position.Z) * (c.PositionZ - p.Position.Z));
var launchAngle = Kinematics.CalculateLaunchAngle(targetDist, muzzleV, releaseAlt);
Assert.True(launchAngle > 0 && launchAngle < 1.57f,
$"发射角 {launchAngle * 180 / System.Math.PI:F1}° 应在 0-90°");
// 5. 弹道能到达释放高度
var peakHeight = muzzleV * muzzleV * (float)System.Math.Sin(launchAngle)
* (float)System.Math.Sin(launchAngle) / (2f * 9.81f);
Assert.True(peakHeight >= releaseAlt,
$"弹道顶点 {peakHeight:F0}m ≥ 释放高度 {releaseAlt:F0}m");
}
}
}