CounterDroneBackend/src/Unity/Assets/Scripts/Managers/ManagerVerification.cs

134 lines
6.1 KiB
C#

using System.Collections.Generic;
using CounterDrone.Core;
using CounterDrone.Core.Algorithms;
using CounterDrone.Core.Models;
using CounterDrone.Core.Simulation;
using UnityEngine;
using AVector3 = CounterDrone.Core.Algorithms.Vector3;
namespace CounterDrone.Unity
{
[ExecuteAlways]
public class ManagerVerification : MonoBehaviour
{
[ContextMenu("Run Full Verification")]
void Run()
{
Debug.Log("===== Manager Verification Start =====");
var paths = new UnityPathProvider();
if (System.IO.File.Exists(paths.GetMainDbPath()))
System.IO.File.Delete(paths.GetMainDbPath());
if (System.IO.Directory.Exists(paths.GetFramesDir()))
System.IO.Directory.Delete(paths.GetFramesDir(), true);
var modelMgr = gameObject.AddComponent<ModelManager>();
modelMgr.Awake();
Debug.Log("1. ModelManager OK");
var scenarioMgr = gameObject.AddComponent<ScenarioManager>();
scenarioMgr.Awake();
var task = scenarioMgr.CreateTask("Verification", "");
var taskId = task.Id;
Debug.Log($"2. ScenarioManager OK. Task: {taskId}");
scenarioMgr.SaveScene(taskId, new CombatScene { WindSpeed = 0 });
scenarioMgr.SaveTarget(taskId, new TargetConfig
{
GroupId = "default",
TargetType = (int)TargetType.Piston, PowerType = (int)PowerType.Piston,
Quantity = 1, TypicalSpeed = 200, TypicalAltitude = 500,
});
scenarioMgr.SaveRoute(taskId, "default", new RoutePlan { FormationMode = (int)FormationMode.Single },
new List<Waypoint>
{
new Waypoint { PosX = 0, PosY = 500, PosZ = 0 },
new Waypoint { PosX = 10000, PosY = 500, PosZ = 0 },
});
scenarioMgr.UpdateStep(taskId, 3);
Debug.Log("3. Scenario configured");
var db = new DatabaseManager(paths).OpenMainDb();
foreach (var a in DefaultAmmunition.GetAll()) db.Insert(a);
var ammoCatalog = db.Table<AmmunitionSpec>().ToList();
var detail = scenarioMgr.GetDetail(taskId);
var droneGroup = new DroneGroup
{
GroupId = "default",
Target = detail.Targets[0],
Route = detail.Routes[0],
Waypoints = detail.WaypointGroups["default"],
};
var fireUnits = new List<FireUnit>();
for (int i = 0; i < 8; i++)
fireUnits.Add(new FireUnit
{
Id = $"u{i}",
Type = PlatformType.GroundBased,
Position = new AVector3(5000 + i * 50, 0, 50),
MuzzleVelocity = 800,
TotalMunitions = 3,
AmmoTypes = new() { AerosolType.InertGas, AerosolType.ActiveMaterial, AerosolType.ActiveFuel },
});
var result = new DefaultDefensePlanner(ammoCatalog).Plan(fireUnits, new List<DroneGroup> { droneGroup }, detail.Scene);
scenarioMgr.SaveCloud(taskId, new CloudDispersal
{
PositionX = (droneGroup.Waypoints[0].PosX + droneGroup.Waypoints[^1].PosX) / 2,
PositionY = (droneGroup.Waypoints[0].PosY + droneGroup.Waypoints[^1].PosY) / 2,
PositionZ = (droneGroup.Waypoints[0].PosZ + droneGroup.Waypoints[^1].PosZ) / 2,
DisperseHeight = droneGroup.Target.TypicalAltitude,
});
var equips = new List<EquipmentDeployment>();
foreach (var u in fireUnits)
equips.Add(new EquipmentDeployment
{
EquipmentRole = (int)EquipmentRole.LaunchPlatform,
PlatformType = (int)u.Type, Quantity = 1,
PositionX = u.Position.X, PositionY = u.Position.Y, PositionZ = u.Position.Z,
AerosolType = (int)u.AmmoTypes[0],
MunitionCount = u.TotalMunitions, Cooldown = u.Cooldown, MuzzleVelocity = u.MuzzleVelocity,
CruiseSpeed = u.CruiseSpeed > 0 ? u.CruiseSpeed : null,
ReleaseAltitude = u.ReleaseAltitude > 0 ? u.ReleaseAltitude : null,
});
scenarioMgr.SaveDeployment(taskId, equips);
db.Close();
var plan = result.Best;
Debug.Log($"4. Plan: {plan.ThreatsEngaged} threats engaged, {plan.MergedSchedule.Count} rounds, prob={plan.OverallProbability:P0}");
var runner = gameObject.AddComponent<SimulationRunner>();
runner.Awake();
runner.LoadAndStart(taskId);
runner.Engine.TimeScale = 10f;
float endTime = Time.realtimeSinceStartup + 60f;
int frameCount = 0;
float tickDt = 1f / 20f;
while (runner.Engine.State == SimulationState.Running && Time.realtimeSinceStartup < endTime)
{
runner.Engine.Tick(tickDt);
frameCount++;
}
Debug.Log($"5. Simulation done. State={runner.Engine.State}, DroneStatus={runner.Engine.Drones[0].Status}, HP={runner.Engine.Drones[0].Hp:F2}, Frames={frameCount}");
runner.Stop();
var reportMgr = gameObject.AddComponent<ReportManager>();
reportMgr.Awake();
detail = scenarioMgr.GetDetail(taskId);
var simEvents = new List<SimEvent>(runner.Engine.Events);
var status = runner.Engine.Drones.Count > 0 ? runner.Engine.Drones[0].Status.ToString() : "Unknown";
var report = reportMgr.Generate(taskId, detail, simEvents, status, runner.Engine.SimulationTime);
var path = reportMgr.Export(report.Id);
Debug.Log($"6. Report OK. Exported: {path}");
var replay = gameObject.AddComponent<ReplayController>();
replay.Awake();
replay.LoadReplay(taskId);
Debug.Log($"7. Replay OK. {replay.TotalFrames} frames, {replay.CurrentFrames.Count} records");
Debug.Log("===== ALL MANAGERS VERIFIED =====");
}
}
}