From b267bc1ac9128383ab5f931ba600d79eb55feca1 Mon Sep 17 00:00:00 2001 From: Puvikaran Santhirasegaram <74664443+Puvikaran2001@users.noreply.github.com> Date: Mon, 11 Nov 2024 14:36:18 +0100 Subject: [PATCH] Added stopping criteria to patrolling --- .../ConscientiousReactiveExperiment.cs | 6 ++++++ .../RandomReactiveExperiment.cs | 6 ++++++ .../Scripts/Simulation/ExplorationSimulation.cs | 2 +- Assets/Scripts/Simulation/PatrollingSimulation.cs | 15 ++++++++++++--- .../PatrollingSimulationScenario.cs | 9 +++++++-- .../SimulationScenarios/SimulationScenario.cs | 2 +- Assets/Scripts/Trackers/PatrollingTracker.cs | 10 +++++++--- .../PatrollingInfoUIController.cs | 11 +++++++++-- 8 files changed, 49 insertions(+), 12 deletions(-) diff --git a/Assets/Scripts/ExperimentSimulations/ConscientiousReactiveExperiment.cs b/Assets/Scripts/ExperimentSimulations/ConscientiousReactiveExperiment.cs index 1bf8e6bf..5116211c 100644 --- a/Assets/Scripts/ExperimentSimulations/ConscientiousReactiveExperiment.cs +++ b/Assets/Scripts/ExperimentSimulations/ConscientiousReactiveExperiment.cs @@ -137,6 +137,8 @@ private void Start() foreach (var (algorithmName, algorithm) in algorithms) { simulator.EnqueueScenario(new MySimulationScenario(seed: 123, + totalCycles: 4, + stopAfterDiff: false, mapSpawner: generator => generator.GenerateMap(mapConfig), robotSpawner: (buildingConfig, spawner) => spawner.SpawnRobotsTogether( buildingConfig, @@ -155,6 +157,8 @@ private void Start() } simulator.EnqueueScenario(new MySimulationScenario(seed: 123, + totalCycles: 4, + stopAfterDiff: false, mapSpawner: generator => generator.GenerateMap(mapConfig), robotSpawner: (buildingConfig, spawner) => spawner.SpawnRobotsAtPositions( collisionMap: buildingConfig, @@ -173,6 +177,8 @@ private void Start() //Just code to make sure we don't get too many maps of the last one in the experiment var dumpMap = new BuildingMapConfig(-1, widthInTiles: 50, heightInTiles: 50); simulator.EnqueueScenario(new MySimulationScenario(seed: 123, + totalCycles: 4, + stopAfterDiff: false, mapSpawner: generator => generator.GenerateMap(dumpMap), robotSpawner: (buildingConfig, spawner) => spawner.SpawnRobotsTogether( buildingConfig, diff --git a/Assets/Scripts/ExperimentSimulations/RandomReactiveExperiment.cs b/Assets/Scripts/ExperimentSimulations/RandomReactiveExperiment.cs index 72644df0..a1b986ac 100644 --- a/Assets/Scripts/ExperimentSimulations/RandomReactiveExperiment.cs +++ b/Assets/Scripts/ExperimentSimulations/RandomReactiveExperiment.cs @@ -131,6 +131,8 @@ private void Start() foreach (var (algorithmName, algorithm) in algorithms) { simulator.EnqueueScenario(new MySimulationScenario(seed: 123, + totalCycles: 3, + stopAfterDiff: true, mapSpawner: generator => generator.GenerateMap(mapConfig), robotSpawner: (buildingConfig, spawner) => spawner.SpawnRobotsTogether( buildingConfig, @@ -149,6 +151,8 @@ private void Start() } simulator.EnqueueScenario(new MySimulationScenario(seed: 123, + totalCycles: 3, + stopAfterDiff: true, mapSpawner: generator => generator.GenerateMap(mapConfig), robotSpawner: (buildingConfig, spawner) => spawner.SpawnRobotsAtPositions( collisionMap: buildingConfig, @@ -167,6 +171,8 @@ private void Start() //Just code to make sure we don't get too many maps of the last one in the experiment var dumpMap = new BuildingMapConfig(-1, widthInTiles: 50, heightInTiles: 50); simulator.EnqueueScenario(new MySimulationScenario(seed: 123, + totalCycles: 3, + stopAfterDiff: true, mapSpawner: generator => generator.GenerateMap(dumpMap), robotSpawner: (buildingConfig, spawner) => spawner.SpawnRobotsTogether( buildingConfig, diff --git a/Assets/Scripts/Simulation/ExplorationSimulation.cs b/Assets/Scripts/Simulation/ExplorationSimulation.cs index c879c5bc..28e55ba6 100644 --- a/Assets/Scripts/Simulation/ExplorationSimulation.cs +++ b/Assets/Scripts/Simulation/ExplorationSimulation.cs @@ -25,7 +25,7 @@ public override void SetScenario(ExplorationSimulationScenario scenario) public override bool HasFinishedSim() { - return ExplorationTracker.ExploredProportion > 0.99f; + return ExplorationTracker.ExploredProportion > 0.99f || SimulatedLogicTicks > 3600 * 10; } public override void OnSimulationFinished() diff --git a/Assets/Scripts/Simulation/PatrollingSimulation.cs b/Assets/Scripts/Simulation/PatrollingSimulation.cs index 7fd172a9..159ebdd6 100644 --- a/Assets/Scripts/Simulation/PatrollingSimulation.cs +++ b/Assets/Scripts/Simulation/PatrollingSimulation.cs @@ -23,7 +23,7 @@ protected override void AfterCollisionMapGenerated(PatrollingSimulationScenario { var patrollingMap = scenario.PatrollingMapFactory(new PatrollingMapSpawner(), _collisionMap); - PatrollingTracker = new PatrollingTracker(_collisionMap, patrollingVisualizer, this, scenario.RobotConstraints, patrollingMap); + PatrollingTracker = new PatrollingTracker(_collisionMap, patrollingVisualizer, this, scenario, patrollingMap); patrollingVisualizer.SetPatrollingMap(patrollingMap); @@ -32,8 +32,17 @@ protected override void AfterCollisionMapGenerated(PatrollingSimulationScenario public override bool HasFinishedSim() { - // TODO: Implement - return false; + if (_scenario.TotalCycles != PatrollingTracker.CompletedCycles) + { + return false; + } + + if (!PatrollingTracker.StopAfterDiff) + { + return true; + } + + return PatrollingTracker.AverageGraphDiffLastTwoCyclesProportion <= 0.025; } } } \ No newline at end of file diff --git a/Assets/Scripts/Simulation/SimulationScenarios/PatrollingSimulationScenario.cs b/Assets/Scripts/Simulation/SimulationScenarios/PatrollingSimulationScenario.cs index 6abcfdb4..30236c1e 100644 --- a/Assets/Scripts/Simulation/SimulationScenarios/PatrollingSimulationScenario.cs +++ b/Assets/Scripts/Simulation/SimulationScenarios/PatrollingSimulationScenario.cs @@ -14,10 +14,13 @@ namespace Maes.Simulation.SimulationScenarios public sealed class PatrollingSimulationScenario : SimulationScenario { public PatrollingMapFactory PatrollingMapFactory { get; } + public int TotalCycles { get; } + public bool StopAfterDiff { get; } public PatrollingSimulationScenario( int seed, - SimulationEndCriteriaDelegate? hasFinishedSim = null, + int totalCycles, + bool stopAfterDiff, MapFactory? mapSpawner = null, RobotFactory? robotSpawner = null, RobotConstraints? robotConstraints = null, @@ -26,11 +29,13 @@ public PatrollingSimulationScenario( ) : base(seed, robotSpawner ?? ((map, spawner) => spawner.SpawnRobotsTogether(map, seed, 1, Vector2Int.zero, _ => new ConscientiousReactiveAlgorithm())), - hasFinishedSim, + null, mapSpawner, robotConstraints, statisticsFileName) { + TotalCycles = totalCycles; + StopAfterDiff = stopAfterDiff; PatrollingMapFactory = patrollingMapFactory ?? ((generator, map) => generator.GeneratePatrollingMapRectangleBased(map)); } } diff --git a/Assets/Scripts/Simulation/SimulationScenarios/SimulationScenario.cs b/Assets/Scripts/Simulation/SimulationScenarios/SimulationScenario.cs index c7f690b4..b8dbcf53 100644 --- a/Assets/Scripts/Simulation/SimulationScenarios/SimulationScenario.cs +++ b/Assets/Scripts/Simulation/SimulationScenarios/SimulationScenario.cs @@ -64,7 +64,7 @@ protected SimulationScenario( ) { Seed = seed; - HasFinishedSim = hasFinishedSim ?? (simulation => simulation.HasFinishedSim() || simulation.SimulatedLogicTicks > 3600 * 10); + HasFinishedSim = hasFinishedSim ?? (simulation => simulation.HasFinishedSim()); // Default to generating a cave map when no map generator is specified MapSpawner = mapSpawner ?? (generator => generator.GenerateMap(new CaveMapConfig(seed))); RobotSpawner = robotSpawner; diff --git a/Assets/Scripts/Trackers/PatrollingTracker.cs b/Assets/Scripts/Trackers/PatrollingTracker.cs index 819ab2c5..9ad68ba0 100644 --- a/Assets/Scripts/Trackers/PatrollingTracker.cs +++ b/Assets/Scripts/Trackers/PatrollingTracker.cs @@ -8,6 +8,7 @@ using Maes.Robot; using Maes.Simulation; +using Maes.Simulation.SimulationScenarios; using Maes.Statistics; using UnityEngine; @@ -31,14 +32,17 @@ public class PatrollingTracker : Tracker GraphIdlenessList { get; } = new(); //TODO: TotalCycles is not set any where in the code - public int TotalCycles { get; set; } = 10; + public int TotalCycles { get; } + public bool StopAfterDiff { get; set; } - public PatrollingTracker(SimulationMap collisionMap, PatrollingVisualizer visualizer, PatrollingSimulation patrollingSimulation, RobotConstraints constraints, - PatrollingMap map) : base(collisionMap, visualizer, constraints, tile => new PatrollingCell(isExplorable: !Tile.IsWall(tile.Type))) + public PatrollingTracker(SimulationMap collisionMap, PatrollingVisualizer visualizer, PatrollingSimulation patrollingSimulation, PatrollingSimulationScenario scenario, + PatrollingMap map) : base(collisionMap, visualizer, scenario.RobotConstraints, tile => new PatrollingCell(isExplorable: !Tile.IsWall(tile.Type))) { PatrollingSimulation = patrollingSimulation; Map = map; Vertices = map.Vertices.ToDictionary(vertex => vertex.Position, vertex => new VertexDetails(vertex)); + TotalCycles = scenario.TotalCycles; + StopAfterDiff = scenario.StopAfterDiff; _visualizer.meshRenderer.enabled = false; _currentVisualizationMode = new WaypointHeatMapVisualizationMode(); diff --git a/Assets/Scripts/UI/SimulationInfoUIControllers/PatrollingInfoUIController.cs b/Assets/Scripts/UI/SimulationInfoUIControllers/PatrollingInfoUIController.cs index 42ddf041..062ab35d 100644 --- a/Assets/Scripts/UI/SimulationInfoUIControllers/PatrollingInfoUIController.cs +++ b/Assets/Scripts/UI/SimulationInfoUIControllers/PatrollingInfoUIController.cs @@ -36,10 +36,17 @@ protected override void AfterStart() }; SelectVisualizationButton(WaypointHeatMapButton); + if (Simulation != null) + { + StoppingCriteriaToggle.isOn = Simulation.PatrollingTracker.StopAfterDiff; + } - StoppingCriteriaToggle.onValueChanged.AddListener(delegate + StoppingCriteriaToggle.onValueChanged.AddListener(toggleValue => { - //TODO: when the stopping criteria is toggled + if (Simulation != null) + { + Simulation.PatrollingTracker.StopAfterDiff = toggleValue; + } }); WaypointHeatMapButton.onClick.AddListener(() =>