From 186b1288a05396f199c3466f4ac4129f9ead5efc Mon Sep 17 00:00:00 2001 From: Daniel Lovell Date: Fri, 18 Oct 2024 18:37:02 -0700 Subject: [PATCH 1/4] ConfigTest->SimIntegration, add TestBasicMicromissilePerformance In a simple, reduced scenario, the micromissiles should have a minimum level of performance that results in a 100% kill rate of quadcopters Adds two _kp1 threat model files, as we test that we have a 100% kill rate in this reduced scenario --- Assets/Scripts/SimManager.cs | 5 +- .../Models/Threats/quadcopter_kp1.json | 30 +++ .../Models/Threats/quadcopter_kp1.json.meta | 7 + .../Configs/Models/Threats/ucav_kp1.json | 30 +++ .../Configs/Models/Threats/ucav_kp1.json.meta | 7 + .../Configs/test_simple_config.json | 88 ++++++ .../Configs/test_simple_config.json.meta | 7 + Assets/Tests/PlayMode/ConfigTest.cs | 73 ----- Assets/Tests/PlayMode/SimIntegrationTests.cs | 250 ++++++++++++++++++ ...st.cs.meta => SimIntegrationTests.cs.meta} | 0 10 files changed, 421 insertions(+), 76 deletions(-) create mode 100644 Assets/StreamingAssets/Configs/Models/Threats/quadcopter_kp1.json create mode 100644 Assets/StreamingAssets/Configs/Models/Threats/quadcopter_kp1.json.meta create mode 100644 Assets/StreamingAssets/Configs/Models/Threats/ucav_kp1.json create mode 100644 Assets/StreamingAssets/Configs/Models/Threats/ucav_kp1.json.meta create mode 100644 Assets/StreamingAssets/Configs/test_simple_config.json create mode 100644 Assets/StreamingAssets/Configs/test_simple_config.json.meta delete mode 100644 Assets/Tests/PlayMode/ConfigTest.cs create mode 100644 Assets/Tests/PlayMode/SimIntegrationTests.cs rename Assets/Tests/PlayMode/{ConfigTest.cs.meta => SimIntegrationTests.cs.meta} (100%) diff --git a/Assets/Scripts/SimManager.cs b/Assets/Scripts/SimManager.cs index 3423fab4..77f81c53 100644 --- a/Assets/Scripts/SimManager.cs +++ b/Assets/Scripts/SimManager.cs @@ -160,6 +160,8 @@ public void SetTimeScale(float timeScale) { } public void StartSimulation() { + // Invoke the simulation started event to let listeners + // know to invoke their own handler behavior OnSimulationStarted?.Invoke(); InitializeSimulation(); } @@ -189,9 +191,6 @@ private void InitializeSimulation() { // updating the time scale and fixed delta time from the newly loaded config files } - // Invoke the simulation started event to let listeners - // know to invoke their own handler behavior - OnSimulationStarted?.Invoke(); List missiles = new List(); // Create missiles based on config foreach (var swarmConfig in simulationConfig.interceptor_swarm_configs) { diff --git a/Assets/StreamingAssets/Configs/Models/Threats/quadcopter_kp1.json b/Assets/StreamingAssets/Configs/Models/Threats/quadcopter_kp1.json new file mode 100644 index 00000000..ef2aa28c --- /dev/null +++ b/Assets/StreamingAssets/Configs/Models/Threats/quadcopter_kp1.json @@ -0,0 +1,30 @@ +{ + "name": "Quadcopter", + "agentClass": "RotaryWingThreat", + "unitCost": 1000, + "accelerationConfig": { + "maxReferenceNormalAcceleration": 300, + "referenceSpeed": 1000, + "maxForwardAcceleration": 50 + }, + "boostConfig": { + "boostTime": 0 + }, + "liftDragConfig": { + "dragCoefficient": 0 + }, + "bodyConfig": { + "mass": 1 + }, + "hitConfig": { + "hitRadius": 1, + "killProbability": 1.0 + }, + "powerTable": { + "IDLE": 0, + "LOW": 20, + "CRUISE": 40, + "MIL": 50, + "MAX": 75 + } +} diff --git a/Assets/StreamingAssets/Configs/Models/Threats/quadcopter_kp1.json.meta b/Assets/StreamingAssets/Configs/Models/Threats/quadcopter_kp1.json.meta new file mode 100644 index 00000000..1ca2d8e0 --- /dev/null +++ b/Assets/StreamingAssets/Configs/Models/Threats/quadcopter_kp1.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c557a31d1bbee9b479ca5c2c5dbcf271 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/StreamingAssets/Configs/Models/Threats/ucav_kp1.json b/Assets/StreamingAssets/Configs/Models/Threats/ucav_kp1.json new file mode 100644 index 00000000..2801ee9a --- /dev/null +++ b/Assets/StreamingAssets/Configs/Models/Threats/ucav_kp1.json @@ -0,0 +1,30 @@ +{ + "name": "UCAV", + "agentClass": "FixedWingThreat", + "unitCost": 30000, + "accelerationConfig": { + "maxReferenceNormalAcceleration": 300, + "referenceSpeed": 1000, + "maxForwardAcceleration": 1 + }, + "boostConfig": { + "boostTime": 0 + }, + "liftDragConfig": { + "dragCoefficient": 0 + }, + "bodyConfig": { + "mass": 10 + }, + "hitConfig": { + "hitRadius": 1, + "killProbability": 1.0 + }, + "powerTable": { + "IDLE": 0, + "LOW": 40, + "CRUISE": 80, + "MIL": 100, + "MAX": 120 + } +} diff --git a/Assets/StreamingAssets/Configs/Models/Threats/ucav_kp1.json.meta b/Assets/StreamingAssets/Configs/Models/Threats/ucav_kp1.json.meta new file mode 100644 index 00000000..529f592d --- /dev/null +++ b/Assets/StreamingAssets/Configs/Models/Threats/ucav_kp1.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9433a1699a8c3d84ca4e05329b988edc +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/StreamingAssets/Configs/test_simple_config.json b/Assets/StreamingAssets/Configs/test_simple_config.json new file mode 100644 index 00000000..123e6a31 --- /dev/null +++ b/Assets/StreamingAssets/Configs/test_simple_config.json @@ -0,0 +1,88 @@ + + { + "endTime": 20, + "timeScale": 2, + "interceptor_swarm_configs": [ + { + "num_agents": 1, + "dynamic_agent_config": { + "agent_model": "hydra70.json", + "initial_state": { + "position": { "x": 0, "y": 20, "z": 0 }, + "velocity": { "x": 0, "y": 10, "z": 10 } + }, + "standard_deviation": { + "position": { "x": 10, "y": 0, "z": 10 }, + "velocity": { "x": 5, "y": 0, "z": 1 } + }, + "dynamic_config": { + "launch_config": { "launch_time": 0 }, + "sensor_config": { + "type": "IDEAL", + "frequency": 100 + }, + "flight_config": { + "augmentedPnEnabled": false + } + }, + "submunitions_config": { + "num_submunitions": 7, + "dispense_time": 0.5, + "dynamic_agent_config": { + "agent_model": "micromissile.json", + "initial_state": { + "position": { "x": 0, "y": 0, "z": 0 }, + "velocity": { "x": 0, "y": 0, "z": 0 } + }, + "standard_deviation": { + "position": { "x": 5, "y": 5, "z": 5 }, + "velocity": { "x": 0, "y": 0, "z": 0 } + }, + "dynamic_config": { + "launch_config": { "launch_time": 0 }, + "sensor_config": { + "type": "IDEAL", + "frequency": 100 + }, + "flight_config": { + "augmentedPnEnabled": false + } + } + } + } + } + } + ], + "threat_swarm_configs": [ + { + "num_agents": 7, + "dynamic_agent_config": { + "agent_model": "quadcopter_kp1.json", + "attack_behavior": "default_direct_attack.json", + "initial_state": { + "position": { "x": 0, "y": 600, "z": 3000 }, + "velocity": { "x": 0, "y": 0, "z": -50 } + }, + "standard_deviation": { + "position": { "x": 50, "y": 50, "z": 50 }, + "velocity": { "x": 0, "y": 0, "z": 25 } + }, + "dynamic_config": { + "launch_config": { "launch_time": 0 }, + "sensor_config": { + "type": "IDEAL", + "frequency": 100 + }, + "flight_config": { + "evasionEnabled": false, + "evasionRangeThreshold": 1000 + } + }, + "submunitions_config": { + "num_submunitions": 0 + } + } + } + ] + } + \ No newline at end of file diff --git a/Assets/StreamingAssets/Configs/test_simple_config.json.meta b/Assets/StreamingAssets/Configs/test_simple_config.json.meta new file mode 100644 index 00000000..3b3cd010 --- /dev/null +++ b/Assets/StreamingAssets/Configs/test_simple_config.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 74e0abcf37d151a4585e099cc03ce23e +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Tests/PlayMode/ConfigTest.cs b/Assets/Tests/PlayMode/ConfigTest.cs deleted file mode 100644 index 652164dc..00000000 --- a/Assets/Tests/PlayMode/ConfigTest.cs +++ /dev/null @@ -1,73 +0,0 @@ -using NUnit.Framework; -using UnityEngine; -using UnityEngine.TestTools; -using System.Collections; -using UnityEngine.SceneManagement; -using System.IO; -using System.Linq; -using System.Collections.Generic; -public class ConfigTest : TestBase { - [OneTimeSetUp] - public void LoadScene() { - SceneManager.LoadScene("Scenes/MainScene"); - } - - [UnityTest] - public IEnumerator TestAllConfigFilesLoad() { - string configPath = Path.Combine(Application.streamingAssetsPath, "Configs"); - string[] jsonFiles = Directory.GetFiles(configPath, "*.json"); - - Assert.IsTrue(jsonFiles.Length > 0, "No JSON files found in the Configs directory"); - - bool isPaused = false; - double epsilon = 0.0002; - for (int i = 0; i < jsonFiles.Length; i++) { - if (i % 2 == 1) { - SimManager.Instance.PauseSimulation(); - isPaused = true; - } - yield return new WaitForSecondsRealtime(0.1f); - SimManager.Instance.LoadNewConfig(jsonFiles[i]); - yield return new WaitForSecondsRealtime(0.1f); - double elapsedTime = SimManager.Instance.GetElapsedSimulationTime(); - if (isPaused) { - List agents = SimManager.Instance.GetActiveAgents(); - foreach (Agent agent in agents) { - if (agent is Interceptor) { - // All interceptors start in INITIALIZED phase - Assert.AreEqual( - Agent.FlightPhase.INITIALIZED, agent.GetFlightPhase(), - "All INTERCEPTOR agents should be in the INITIALIZED flight phase after loading while paused"); - - } else if (agent is Threat) { - // All threats start in MIDCOURSE phase - Assert.AreEqual( - Agent.FlightPhase.MIDCOURSE, agent.GetFlightPhase(), - "All THREAT agents should be in the MIDCOURSE flight phase after loading while paused"); - } - } - Assert.LessOrEqual(Mathf.Abs(Time.fixedDeltaTime), epsilon, - "Fixed delta time should be approximately 0 after loading while paused"); - Assert.LessOrEqual(Mathf.Abs(Time.timeScale), epsilon, - "Time scale should be approximately 0 after loading while paused"); - Assert.IsFalse(elapsedTime > 0 + epsilon, - "Simulation time should not have advanced after loading while paused"); - } else { - Assert.IsTrue(elapsedTime > 0 + epsilon, - "Simulation time should have advanced after loading while not paused"); - Assert.LessOrEqual( - Mathf.Abs(Time.fixedDeltaTime - - (1.0f / SimManager.Instance.simulatorConfig.physicsUpdateRate)), - epsilon, "Physics update rate should be 1 / simulatorConfig.physicsUpdateRate"); - } - - if (isPaused) { - SimManager.Instance.ResumeSimulation(); - isPaused = false; - yield return new WaitForSecondsRealtime(0.1f); - Assert.IsTrue(SimManager.Instance.GetElapsedSimulationTime() > 0 + epsilon, - "Simulation time should have advanced after resuming"); - } - } - } -} diff --git a/Assets/Tests/PlayMode/SimIntegrationTests.cs b/Assets/Tests/PlayMode/SimIntegrationTests.cs new file mode 100644 index 00000000..1c620cec --- /dev/null +++ b/Assets/Tests/PlayMode/SimIntegrationTests.cs @@ -0,0 +1,250 @@ +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using System.Collections; +using UnityEngine.SceneManagement; +using System.IO; +using System.Linq; +using System.Collections.Generic; +public class SimIntegrationTests : TestBase { + [OneTimeSetUp] + public void LoadScene() { + SceneManager.LoadScene("Scenes/MainScene"); + } + + [UnityTest] + public IEnumerator TestAllConfigFilesLoad() { + string configPath = Path.Combine(Application.streamingAssetsPath, "Configs"); + string[] jsonFiles = Directory.GetFiles(configPath, "*.json"); + + Assert.IsTrue(jsonFiles.Length > 0, "No JSON files found in the Configs directory"); + + bool isPaused = false; + double epsilon = 0.0002; + for (int i = 0; i < jsonFiles.Length; i++) { + if (i % 2 == 1) { + SimManager.Instance.PauseSimulation(); + isPaused = true; + } + yield return new WaitForSecondsRealtime(0.1f); + SimManager.Instance.LoadNewConfig(jsonFiles[i]); + yield return new WaitForSecondsRealtime(0.1f); + double elapsedTime = SimManager.Instance.GetElapsedSimulationTime(); + if (isPaused) { + List agents = SimManager.Instance.GetActiveAgents(); + foreach (Agent agent in agents) { + if (agent is Interceptor) { + // All interceptors start in INITIALIZED phase + Assert.AreEqual( + Agent.FlightPhase.INITIALIZED, agent.GetFlightPhase(), + "All INTERCEPTOR agents should be in the INITIALIZED flight phase after loading while paused"); + + } else if (agent is Threat) { + // All threats start in MIDCOURSE phase + Assert.AreEqual( + Agent.FlightPhase.MIDCOURSE, agent.GetFlightPhase(), + "All THREAT agents should be in the MIDCOURSE flight phase after loading while paused"); + } + } + Assert.LessOrEqual(Mathf.Abs(Time.fixedDeltaTime), epsilon, + "Fixed delta time should be approximately 0 after loading while paused"); + Assert.LessOrEqual(Mathf.Abs(Time.timeScale), epsilon, + "Time scale should be approximately 0 after loading while paused"); + Assert.IsFalse(elapsedTime > 0 + epsilon, + "Simulation time should not have advanced after loading while paused"); + } else { + Assert.IsTrue(elapsedTime > 0 + epsilon, + "Simulation time should have advanced after loading while not paused"); + Assert.LessOrEqual( + Mathf.Abs(Time.fixedDeltaTime - + (1.0f / SimManager.Instance.simulatorConfig.physicsUpdateRate)), + epsilon, "Physics update rate should be 1 / simulatorConfig.physicsUpdateRate"); + } + + if (isPaused) { + SimManager.Instance.ResumeSimulation(); + isPaused = false; + yield return new WaitForSecondsRealtime(0.1f); + Assert.IsTrue(SimManager.Instance.GetElapsedSimulationTime() > 0 + epsilon, + "Simulation time should have advanced after resuming"); + } + } + } + + private const string TestSimpleConfigJson = + @" + { + ""endTime"": 20, + ""timeScale"": 2, + ""interceptor_swarm_configs"": [ + { + ""num_agents"": 1, + ""dynamic_agent_config"": { + ""agent_model"": ""hydra70.json"", + ""initial_state"": { + ""position"": { ""x"": 0, ""y"": 20, ""z"": 0 }, + ""velocity"": { ""x"": 0, ""y"": 10, ""z"": 10 } + }, + ""standard_deviation"": { + ""position"": { ""x"": 10, ""y"": 0, ""z"": 10 }, + ""velocity"": { ""x"": 5, ""y"": 0, ""z"": 1 } + }, + ""dynamic_config"": { + ""launch_config"": { ""launch_time"": 0 }, + ""sensor_config"": { + ""type"": ""IDEAL"", + ""frequency"": 100 + }, + ""flight_config"": { + ""augmentedPnEnabled"": false + } + }, + ""submunitions_config"": { + ""num_submunitions"": 7, + ""dispense_time"": 0.5, + ""dynamic_agent_config"": { + ""agent_model"": ""micromissile.json"", + ""initial_state"": { + ""position"": { ""x"": 0, ""y"": 0, ""z"": 0 }, + ""velocity"": { ""x"": 0, ""y"": 0, ""z"": 0 } + }, + ""standard_deviation"": { + ""position"": { ""x"": 5, ""y"": 5, ""z"": 5 }, + ""velocity"": { ""x"": 0, ""y"": 0, ""z"": 0 } + }, + ""dynamic_config"": { + ""launch_config"": { ""launch_time"": 0 }, + ""sensor_config"": { + ""type"": ""IDEAL"", + ""frequency"": 100 + }, + ""flight_config"": { + ""augmentedPnEnabled"": false + } + } + } + } + } + } + ], + ""threat_swarm_configs"": [ + { + ""num_agents"": 7, + ""dynamic_agent_config"": { + ""agent_model"": ""quadcopter_kp1.json"", + ""attack_behavior"": ""default_direct_attack.json"", + ""initial_state"": { + ""position"": { ""x"": 0, ""y"": 600, ""z"": 3000 }, + ""velocity"": { ""x"": 0, ""y"": 0, ""z"": -50 } + }, + ""standard_deviation"": { + ""position"": { ""x"": 50, ""y"": 50, ""z"": 50 }, + ""velocity"": { ""x"": 0, ""y"": 0, ""z"": 25 } + }, + ""dynamic_config"": { + ""launch_config"": { ""launch_time"": 0 }, + ""sensor_config"": { + ""type"": ""IDEAL"", + ""frequency"": 100 + }, + ""flight_config"": { + ""evasionEnabled"": false, + ""evasionRangeThreshold"": 1000 + } + }, + ""submunitions_config"": { + ""num_submunitions"": 0 + } + } + } + ] + } + "; + + private int _simulationStartedCount = 0; + private int _simulationEndedCount = 0; + private int _interceptorHitCount = 0; + private int _interceptorMissCount = 0; + public void RegisterSimulationStarted() { + _simulationStartedCount++; + } + public void RegisterSimulationEnded() { + _simulationEndedCount++; + } + public void RegisterInterceptorHit(Interceptor interceptor, Threat threat) { + _interceptorHitCount++; + } + + public void RegisterInterceptorMiss(Interceptor interceptor, Threat threat) { + _interceptorMissCount++; + } + + public void RegisterNewInterceptor(Interceptor interceptor) { + interceptor.OnInterceptHit += RegisterInterceptorHit; + interceptor.OnInterceptMiss += RegisterInterceptorMiss; + } + + [UnityTest] + public IEnumerator TestBasicMicromissilePerformance() { + // In a simple, reduced scenario, the micromissiles should have a minimum + // level of performance that results in a 100% kill rate of quadcopters + SimManager.Instance.OnSimulationStarted += RegisterSimulationStarted; + SimManager.Instance.OnSimulationEnded += RegisterSimulationEnded; + SimManager.Instance.OnNewInterceptor += RegisterNewInterceptor; + string configPath = + Path.Combine(Application.streamingAssetsPath, "Configs/test_simple_config.json"); + Directory.CreateDirectory(Path.GetDirectoryName(configPath)); + File.WriteAllText(configPath, TestSimpleConfigJson); + Time.fixedDeltaTime = 0.001f; // Force 1000 Hz Physics update rate + SimManager.Instance.LoadNewConfig(configPath); + + double dispenseTime = SimManager.Instance.GetActiveAgents()[0].dynamicAgentConfig.submunitions_config.dispense_time; + for (int i = 0; i < 3; i++) { + + double elapsedTime = SimManager.Instance.GetElapsedSimulationTime(); + // Wait for 10ms, micromissiles should not have been dispensed yet + yield return new WaitUntil(() => SimManager.Instance.GetElapsedSimulationTime() >= elapsedTime + 0.01); + if(SimManager.Instance.GetElapsedSimulationTime() < dispenseTime) { + Assert.AreEqual( + 1, SimManager.Instance.GetActiveInterceptors().Count, + "Only one interceptor should be active, micromissiles should not have dispensed yet"); + } + // Wait for 600ms, micromissiles should have been dispensed + elapsedTime = SimManager.Instance.GetElapsedSimulationTime(); + yield return new WaitUntil(() => SimManager.Instance.GetElapsedSimulationTime() >= elapsedTime + dispenseTime); + List interceptors = SimManager.Instance.GetActiveInterceptors(); + Assert.AreEqual( + 8, interceptors.Count, + "All micromissiles should have been dispensed"); + + // All interceptors which are not CarrierInterceptor should have been + // assigned a target + foreach (Interceptor interceptor in interceptors) { + if (interceptor is CarrierInterceptor) { + continue; + } + Assert.IsTrue(interceptor.HasAssignedTarget(), + $"Interceptor {interceptor.name} should have a target"); + } + elapsedTime = SimManager.Instance.GetElapsedSimulationTime(); + yield return new WaitUntil(() => SimManager.Instance.GetActiveThreats().Count == 0 || + SimManager.Instance.GetElapsedSimulationTime() >= + elapsedTime + 6); + Assert.GreaterOrEqual(_simulationStartedCount, 1, + "Simulation should be started at least once"); + Assert.GreaterOrEqual(_simulationEndedCount, 1, "Simulation should be ended at least once"); + Assert.AreEqual(_interceptorHitCount, 7, "All threats should be hit"); + Assert.AreEqual(_interceptorMissCount, 0, "No threats should be missed"); + Debug.Log($"Simulation started {_simulationStartedCount} times"); + Debug.Log($"Simulation ended {_simulationEndedCount} times"); + _simulationStartedCount = 0; + _simulationEndedCount = 0; + _interceptorHitCount = 0; + _interceptorMissCount = 0; + SimManager.Instance.RestartSimulation(); + } + + // Clean up the config file + File.Delete(configPath); + } +} diff --git a/Assets/Tests/PlayMode/ConfigTest.cs.meta b/Assets/Tests/PlayMode/SimIntegrationTests.cs.meta similarity index 100% rename from Assets/Tests/PlayMode/ConfigTest.cs.meta rename to Assets/Tests/PlayMode/SimIntegrationTests.cs.meta From a04561562aea07f4e5f90cdbfef9f268018f6b84 Mon Sep 17 00:00:00 2001 From: Daniel Lovell Date: Fri, 18 Oct 2024 18:39:41 -0700 Subject: [PATCH 2/4] clang-format --- Assets/Tests/PlayMode/SimIntegrationTests.cs | 22 ++++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Assets/Tests/PlayMode/SimIntegrationTests.cs b/Assets/Tests/PlayMode/SimIntegrationTests.cs index 1c620cec..aee18053 100644 --- a/Assets/Tests/PlayMode/SimIntegrationTests.cs +++ b/Assets/Tests/PlayMode/SimIntegrationTests.cs @@ -198,27 +198,27 @@ public IEnumerator TestBasicMicromissilePerformance() { Time.fixedDeltaTime = 0.001f; // Force 1000 Hz Physics update rate SimManager.Instance.LoadNewConfig(configPath); - double dispenseTime = SimManager.Instance.GetActiveAgents()[0].dynamicAgentConfig.submunitions_config.dispense_time; + double dispenseTime = SimManager.Instance.GetActiveAgents()[0] + .dynamicAgentConfig.submunitions_config.dispense_time; for (int i = 0; i < 3; i++) { - double elapsedTime = SimManager.Instance.GetElapsedSimulationTime(); // Wait for 10ms, micromissiles should not have been dispensed yet - yield return new WaitUntil(() => SimManager.Instance.GetElapsedSimulationTime() >= elapsedTime + 0.01); - if(SimManager.Instance.GetElapsedSimulationTime() < dispenseTime) { + yield return new WaitUntil(() => SimManager.Instance.GetElapsedSimulationTime() >= + elapsedTime + 0.01); + if (SimManager.Instance.GetElapsedSimulationTime() < dispenseTime) { Assert.AreEqual( - 1, SimManager.Instance.GetActiveInterceptors().Count, - "Only one interceptor should be active, micromissiles should not have dispensed yet"); + 1, SimManager.Instance.GetActiveInterceptors().Count, + "Only one interceptor should be active, micromissiles should not have dispensed yet"); } // Wait for 600ms, micromissiles should have been dispensed elapsedTime = SimManager.Instance.GetElapsedSimulationTime(); - yield return new WaitUntil(() => SimManager.Instance.GetElapsedSimulationTime() >= elapsedTime + dispenseTime); + yield return new WaitUntil(() => SimManager.Instance.GetElapsedSimulationTime() >= + elapsedTime + dispenseTime); List interceptors = SimManager.Instance.GetActiveInterceptors(); - Assert.AreEqual( - 8, interceptors.Count, - "All micromissiles should have been dispensed"); + Assert.AreEqual(8, interceptors.Count, "All micromissiles should have been dispensed"); // All interceptors which are not CarrierInterceptor should have been - // assigned a target + // assigned a target foreach (Interceptor interceptor in interceptors) { if (interceptor is CarrierInterceptor) { continue; From e761d01421ddb2ef4f048a8b4a03a9cf000b269a Mon Sep 17 00:00:00 2001 From: Daniel Lovell Date: Fri, 18 Oct 2024 18:50:12 -0700 Subject: [PATCH 3/4] Remove test that will fail due to random/noise dispense times --- Assets/Tests/PlayMode/SimIntegrationTests.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Assets/Tests/PlayMode/SimIntegrationTests.cs b/Assets/Tests/PlayMode/SimIntegrationTests.cs index aee18053..d6b0fd12 100644 --- a/Assets/Tests/PlayMode/SimIntegrationTests.cs +++ b/Assets/Tests/PlayMode/SimIntegrationTests.cs @@ -205,11 +205,8 @@ public IEnumerator TestBasicMicromissilePerformance() { // Wait for 10ms, micromissiles should not have been dispensed yet yield return new WaitUntil(() => SimManager.Instance.GetElapsedSimulationTime() >= elapsedTime + 0.01); - if (SimManager.Instance.GetElapsedSimulationTime() < dispenseTime) { - Assert.AreEqual( - 1, SimManager.Instance.GetActiveInterceptors().Count, - "Only one interceptor should be active, micromissiles should not have dispensed yet"); - } + // TODO: Here is a good opportunity to test things before dispense. + // BUT keep in mind, dispense time is noisy (1sd = 0.5s) // Wait for 600ms, micromissiles should have been dispensed elapsedTime = SimManager.Instance.GetElapsedSimulationTime(); yield return new WaitUntil(() => SimManager.Instance.GetElapsedSimulationTime() >= From d2f1d3facedce1894c4657ca9f8715e7b32d8968 Mon Sep 17 00:00:00 2001 From: Daniel Lovell Date: Mon, 28 Oct 2024 18:36:48 -0700 Subject: [PATCH 4/4] SimIntegrationtests speed up sim, increase robustness to random noise --- .../Configs/test_simple_config.json | 88 ------------------- .../Configs/test_simple_config.json.meta | 7 -- Assets/Tests/PlayMode/SimIntegrationTests.cs | 6 +- 3 files changed, 3 insertions(+), 98 deletions(-) delete mode 100644 Assets/StreamingAssets/Configs/test_simple_config.json delete mode 100644 Assets/StreamingAssets/Configs/test_simple_config.json.meta diff --git a/Assets/StreamingAssets/Configs/test_simple_config.json b/Assets/StreamingAssets/Configs/test_simple_config.json deleted file mode 100644 index 123e6a31..00000000 --- a/Assets/StreamingAssets/Configs/test_simple_config.json +++ /dev/null @@ -1,88 +0,0 @@ - - { - "endTime": 20, - "timeScale": 2, - "interceptor_swarm_configs": [ - { - "num_agents": 1, - "dynamic_agent_config": { - "agent_model": "hydra70.json", - "initial_state": { - "position": { "x": 0, "y": 20, "z": 0 }, - "velocity": { "x": 0, "y": 10, "z": 10 } - }, - "standard_deviation": { - "position": { "x": 10, "y": 0, "z": 10 }, - "velocity": { "x": 5, "y": 0, "z": 1 } - }, - "dynamic_config": { - "launch_config": { "launch_time": 0 }, - "sensor_config": { - "type": "IDEAL", - "frequency": 100 - }, - "flight_config": { - "augmentedPnEnabled": false - } - }, - "submunitions_config": { - "num_submunitions": 7, - "dispense_time": 0.5, - "dynamic_agent_config": { - "agent_model": "micromissile.json", - "initial_state": { - "position": { "x": 0, "y": 0, "z": 0 }, - "velocity": { "x": 0, "y": 0, "z": 0 } - }, - "standard_deviation": { - "position": { "x": 5, "y": 5, "z": 5 }, - "velocity": { "x": 0, "y": 0, "z": 0 } - }, - "dynamic_config": { - "launch_config": { "launch_time": 0 }, - "sensor_config": { - "type": "IDEAL", - "frequency": 100 - }, - "flight_config": { - "augmentedPnEnabled": false - } - } - } - } - } - } - ], - "threat_swarm_configs": [ - { - "num_agents": 7, - "dynamic_agent_config": { - "agent_model": "quadcopter_kp1.json", - "attack_behavior": "default_direct_attack.json", - "initial_state": { - "position": { "x": 0, "y": 600, "z": 3000 }, - "velocity": { "x": 0, "y": 0, "z": -50 } - }, - "standard_deviation": { - "position": { "x": 50, "y": 50, "z": 50 }, - "velocity": { "x": 0, "y": 0, "z": 25 } - }, - "dynamic_config": { - "launch_config": { "launch_time": 0 }, - "sensor_config": { - "type": "IDEAL", - "frequency": 100 - }, - "flight_config": { - "evasionEnabled": false, - "evasionRangeThreshold": 1000 - } - }, - "submunitions_config": { - "num_submunitions": 0 - } - } - } - ] - } - \ No newline at end of file diff --git a/Assets/StreamingAssets/Configs/test_simple_config.json.meta b/Assets/StreamingAssets/Configs/test_simple_config.json.meta deleted file mode 100644 index 3b3cd010..00000000 --- a/Assets/StreamingAssets/Configs/test_simple_config.json.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 74e0abcf37d151a4585e099cc03ce23e -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Tests/PlayMode/SimIntegrationTests.cs b/Assets/Tests/PlayMode/SimIntegrationTests.cs index d6b0fd12..fd3e3765 100644 --- a/Assets/Tests/PlayMode/SimIntegrationTests.cs +++ b/Assets/Tests/PlayMode/SimIntegrationTests.cs @@ -134,12 +134,12 @@ public IEnumerator TestAllConfigFilesLoad() { ""agent_model"": ""quadcopter_kp1.json"", ""attack_behavior"": ""default_direct_attack.json"", ""initial_state"": { - ""position"": { ""x"": 0, ""y"": 600, ""z"": 3000 }, + ""position"": { ""x"": 0, ""y"": 1000, ""z"": 1500 }, ""velocity"": { ""x"": 0, ""y"": 0, ""z"": -50 } }, ""standard_deviation"": { ""position"": { ""x"": 50, ""y"": 50, ""z"": 50 }, - ""velocity"": { ""x"": 0, ""y"": 0, ""z"": 25 } + ""velocity"": { ""x"": 0, ""y"": 0, ""z"": 5 } }, ""dynamic_config"": { ""launch_config"": { ""launch_time"": 0 }, @@ -210,7 +210,7 @@ public IEnumerator TestBasicMicromissilePerformance() { // Wait for 600ms, micromissiles should have been dispensed elapsedTime = SimManager.Instance.GetElapsedSimulationTime(); yield return new WaitUntil(() => SimManager.Instance.GetElapsedSimulationTime() >= - elapsedTime + dispenseTime); + elapsedTime + dispenseTime + 0.3); List interceptors = SimManager.Instance.GetActiveInterceptors(); Assert.AreEqual(8, interceptors.Count, "All micromissiles should have been dispensed");