diff --git a/Assets/StreamingAssets/Configs/Simulations/5_swarms_7_ucav.pbtxt b/Assets/StreamingAssets/Configs/Simulations/5_swarms_7_ucav.pbtxt index a9f0db88b..05bc178af 100644 --- a/Assets/StreamingAssets/Configs/Simulations/5_swarms_7_ucav.pbtxt +++ b/Assets/StreamingAssets/Configs/Simulations/5_swarms_7_ucav.pbtxt @@ -283,3 +283,46 @@ threat_swarm_configs { } } } +communication_config { + link_config { + latency_seconds: 0.10 + latency_std_seconds: 0.01 + packet_delivery_ratio: 1.0 + } + link_overrides { + from: VESSEL + to: CARRIER_INTERCEPTOR + link_config { + latency_seconds: 0.20 + latency_std_seconds: 0.02 + packet_delivery_ratio: 1.0 + } + } + link_overrides { + from: CARRIER_INTERCEPTOR + to: VESSEL + link_config { + latency_seconds: 0.20 + latency_std_seconds: 0.02 + packet_delivery_ratio: 1.0 + } + } + link_overrides { + from: CARRIER_INTERCEPTOR + to: MISSILE_INTERCEPTOR + link_config { + latency_seconds: 0.03 + latency_std_seconds: 0.005 + packet_delivery_ratio: 1.0 + } + } + link_overrides { + from: MISSILE_INTERCEPTOR + to: CARRIER_INTERCEPTOR + link_config { + latency_seconds: 0.03 + latency_std_seconds: 0.005 + packet_delivery_ratio: 1.0 + } + } +} diff --git a/Assets/StreamingAssets/Configs/Simulations/7_quadcopters.pbtxt b/Assets/StreamingAssets/Configs/Simulations/7_quadcopters.pbtxt index cfdbb642b..957487777 100644 --- a/Assets/StreamingAssets/Configs/Simulations/7_quadcopters.pbtxt +++ b/Assets/StreamingAssets/Configs/Simulations/7_quadcopters.pbtxt @@ -117,24 +117,22 @@ communication_config { latency_std_seconds: 0.02 packet_delivery_ratio: 1.0 } - link_overrides { from: VESSEL to: CARRIER_INTERCEPTOR link_config { latency_seconds: 0.25 latency_std_seconds: 0.02 - packet_delivery_ratio: 0.98 + packet_delivery_ratio: 1.0 } } - link_overrides { from: CARRIER_INTERCEPTOR to: MISSILE_INTERCEPTOR link_config { latency_seconds: 0.05 latency_std_seconds: 0.01 - packet_delivery_ratio: 0.99 + packet_delivery_ratio: 1.0 } } } diff --git a/Assets/Tests/EditMode/CarrierBaseMailboxTests.cs b/Assets/Tests/EditMode/CarrierBaseMailboxTests.cs index 0285ad13d..0905410c0 100644 --- a/Assets/Tests/EditMode/CarrierBaseMailboxTests.cs +++ b/Assets/Tests/EditMode/CarrierBaseMailboxTests.cs @@ -9,6 +9,8 @@ public class CarrierBaseMailboxTests : TestBase { private Mailbox _mailbox; private SimManager _simManager; + private IADS _iads; + private IadsCommsAgent _commsAgent; private TestCarrier _carrier; private readonly List _spawnedObjects = new List(); @@ -16,14 +18,25 @@ public class CarrierBaseMailboxTests : TestBase { public void SetUp() { SetMailboxInstance(null); SetSimManagerInstance(null); + SetIadsInstance(null); _simManager = CreateSimManagerStub(); SetPrivateField(_simManager, "_dummyAgents", new List()); + SetPrivateField(_simManager, "_interceptors", new List()); + SetPrivateField(_simManager, "_threats", new List()); SetSimManagerInstance(_simManager); SetElapsedTime(0f); _mailbox = new GameObject("Mailbox").AddComponent(); _spawnedObjects.Add(_mailbox.gameObject); + SetMailboxInstance(_mailbox); + + GameObject iadsObject = new GameObject("IADS"); + _spawnedObjects.Add(iadsObject); + _iads = iadsObject.AddComponent(); + InvokePrivateMethod(_iads, "Awake"); + _commsAgent = _iads.GetComponent(); + InvokePrivateMethod(_iads, "Start"); _carrier = CreateCarrier("Carrier", Configs.AgentType.CarrierInterceptor); SetPrivateField(_carrier, "_capacityPerSubInterceptor", 1); @@ -39,6 +52,7 @@ public void TearDown() { _spawnedObjects.Clear(); SetMailboxInstance(null); SetSimManagerInstance(null); + SetIadsInstance(null); } // Verifies that release bookkeeping only counts released interceptor children, surfaces an @@ -108,6 +122,56 @@ public void ReleasedInterceptor_RequestViaMailbox_ProducesCarrierAssignTargetRes Assert.AreSame(expectedLeafTarget, assignedTargets[0]); } + // Verifies that a released interceptor can propagate a mailbox target request through its + // carrier to IADS, and that the requesting interceptor receives the launcher-selected target. + [Test] + public void ReleasedInterceptor_RequestViaMailbox_PropagatesThroughCarrierAndIads() { + TestLauncherCarrier launcherCarrier = + CreateLauncherCarrier("LauncherCarrier", Configs.AgentType.Vessel); + SetPrivateField(launcherCarrier, "_capacityPerSubInterceptor", 1); + SetPrivateField(launcherCarrier, "_numSubInterceptorsRemaining", 1); + + TestReleasedInterceptor releasedInterceptor = + CreateReleasedInterceptor("ReleasedInterceptor", Configs.AgentType.MissileInterceptor); + launcherCarrier.ReleaseStrategy = + new FixedReleaseStrategy(launcherCarrier, new List { releasedInterceptor }); + RunReleaseManagerStep(launcherCarrier, period: 0.2f); + _iads.RegisterNewLauncher(launcherCarrier); + + var launcher = + new StubInterceptor(Configs.AgentType.Vessel, capacity: 1) { Position = Vector3.zero }; + launcher.HierarchicalAgent = new HierarchicalAgent(launcher); + FixedHierarchical expectedLeafTarget = + new FixedHierarchical(position: new Vector3(35f, 0f, 0f)); + launcher.HierarchicalAgent.Target = CreateCluster(expectedLeafTarget); + _iads.RegisterNewLauncher(launcher); + + TestReleasedInterceptor requestingInterceptor = + CreateReleasedInterceptor("RequestingInterceptor", Configs.AgentType.MissileInterceptor); + SetPrivateField(requestingInterceptor, "_capacityPerSubInterceptor", 1); + SetPrivateField(requestingInterceptor, "_numSubInterceptorsRemaining", 1); + + _mailbox.Configure(null); + releasedInterceptor.AssignSubInterceptor(requestingInterceptor); + + InvokePrivateMethod(_mailbox, "Update"); + Assert.IsNull(requestingInterceptor.HierarchicalAgent.Target); + + InvokePrivateMethod(_mailbox, "Update"); + Assert.IsNull(requestingInterceptor.HierarchicalAgent.Target); + + InvokePrivateMethod(_mailbox, "Update"); + Assert.NotNull(requestingInterceptor.HierarchicalAgent.Target); + + List assignedTargets = + requestingInterceptor.HierarchicalAgent.Target.LeafHierarchicals(activeOnly: true, + withTargetOnly: false); + Assert.AreEqual(1, assignedTargets.Count); + Assert.AreSame(expectedLeafTarget, assignedTargets[0]); + Assert.AreSame(launcherCarrier, releasedInterceptor.CommsParent); + Assert.AreSame(_commsAgent, launcherCarrier.CommsParent); + } + // Verifies that duplicate interceptor entries in a release batch do not double-count remaining // sub-interceptors. [Test] @@ -150,6 +214,18 @@ private TestReleasedInterceptor CreateReleasedInterceptor(string name, return interceptor; } + private TestLauncherCarrier CreateLauncherCarrier(string name, Configs.AgentType agentType) { + GameObject launcherObject = new GameObject(name); + _spawnedObjects.Add(launcherObject); + launcherObject.AddComponent(); + + TestLauncherCarrier launcher = launcherObject.AddComponent(); + launcher.HierarchicalAgent = new HierarchicalAgent(launcher); + launcher.InvokeAwakeForTest(); + launcher.StaticConfig = CreateStaticConfig(agentType); + return launcher; + } + private static void RunReleaseManagerStep(CarrierBase carrier, float period) { MethodInfo releaseManagerMethod = typeof(CarrierBase) @@ -198,6 +274,15 @@ private static void SetSimManagerInstance(SimManager simManager) { instanceField.SetValue(null, simManager); } + private static void SetIadsInstance(IADS iads) { + FieldInfo instanceField = typeof(IADS).GetField("k__BackingField", + BindingFlags.NonPublic | BindingFlags.Static); + Assert.NotNull(instanceField, + $"{nameof(IADS)} instance backing field was not found. " + + $"The {nameof(IADS.Instance)} property shape may have changed."); + instanceField.SetValue(null, iads); + } + private void SetElapsedTime(float elapsedTime) { FieldInfo elapsedTimeField = typeof(SimManager) .GetField("k__BackingField", @@ -217,6 +302,18 @@ void IAgent.DestroyTargetModel() {} void IAgent.UpdateTargetModel() {} } + private sealed class TestLauncherCarrier : LauncherBase, IAgent { + public void InvokeAwakeForTest() { + base.Awake(); + } + + void IAgent.CreateTargetModel(IHierarchical target) {} + + void IAgent.DestroyTargetModel() {} + + void IAgent.UpdateTargetModel() {} + } + private sealed class TestReleasedInterceptor : InterceptorBase, IAgent { public void InvokeAwakeForTest() { base.Awake(); diff --git a/Assets/Tests/EditMode/CarrierBaseMailboxTests.cs.meta b/Assets/Tests/EditMode/CarrierBaseMailboxTests.cs.meta new file mode 100644 index 000000000..fb0e898ae --- /dev/null +++ b/Assets/Tests/EditMode/CarrierBaseMailboxTests.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 2bcb7fd2c8997460788772dad50fdac3 \ No newline at end of file