Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add random reactive patrolling algo + experiment #89

Merged
merged 2 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 185 additions & 0 deletions Assets/Scripts/ExperimentSimulations/RandomReactiveExperiment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
// Copyright 2024 MAES
//
// This file is part of MAES
//
// MAES is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the
// Free Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// MAES is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with MAES. If not, see http://www.gnu.org/licenses/.
//
// Contributors:
// Casper Nyvang Sørensen,
// Christian Ziegler Sejersen,
// Henrik van Peet,
// Jakob Meyer Olsen,
// Mads Beyer Mogensen,
// Puvikaran Santhirasegaram
//
// Original repository: https://github.com/Molitany/MAES

using System.Collections.Generic;

using Maes.Algorithms;
using Maes.Map.MapGen;
using Maes.Map.RobotSpawners;
using Maes.PatrollingAlgorithms;
using Maes.Robot;
using Maes.Simulation;
using Maes.Simulation.SimulationScenarios;

using UnityEngine;

namespace Maes.ExperimentSimulations
{
using MySimulator = PatrollingSimulator;
using MySimulationScenario = PatrollingSimulationScenario;

internal class RandomReactiveExperiment : MonoBehaviour
{
private void Start()
{
var constraintsDict = new Dictionary<string, RobotConstraints>();

//var constraintsGlobalCommunication = new RobotConstraints(
constraintsDict["Global"] = new RobotConstraints(
senseNearbyAgentsRange: 5f,
senseNearbyAgentsBlockedByWalls: true,
automaticallyUpdateSlam: true,
slamUpdateIntervalInTicks: 1,
slamSynchronizeIntervalInTicks: 10,
slamPositionInaccuracy: 0.2f,
mapKnown: true,
distributeSlam: false,
environmentTagReadRange: 100f,
slamRayTraceRange: 7f,
relativeMoveSpeed: 1f,
agentRelativeSize: 0.6f,
calculateSignalTransmissionProbability: (_, _) => true);

//var constraintsMaterials = new RobotConstraints(
constraintsDict["Material"] = new RobotConstraints(
senseNearbyAgentsRange: 5f,
senseNearbyAgentsBlockedByWalls: true,
automaticallyUpdateSlam: true,
slamUpdateIntervalInTicks: 1,
slamSynchronizeIntervalInTicks: 10,
slamPositionInaccuracy: 0.2f,
mapKnown: true,
distributeSlam: false,
environmentTagReadRange: 100.0f,
slamRayTraceRange: 7f,
relativeMoveSpeed: 1f,
agentRelativeSize: 0.6f,
materialCommunication: true
);

//var constraintsLOS = new RobotConstraints(
constraintsDict["LOS"] = new RobotConstraints(
senseNearbyAgentsRange: 5f,
senseNearbyAgentsBlockedByWalls: true,
automaticallyUpdateSlam: true,
slamUpdateIntervalInTicks: 1,
slamSynchronizeIntervalInTicks: 10,
slamPositionInaccuracy: 0.2f,
mapKnown: true,
distributeSlam: false,
environmentTagReadRange: 100.0f,
slamRayTraceRange: 7f,
relativeMoveSpeed: 1f,
agentRelativeSize: 0.6f,
calculateSignalTransmissionProbability: (_, distanceThroughWalls) => distanceThroughWalls <= 0);

var simulator = new MySimulator();
var random = new System.Random(12345);
var randNumbers = new List<int>();
for (int i = 0; i < 100; i++)
{
var val = random.Next(0, 1000000);
randNumbers.Add(val);
}

var constraintName = "Global";
var robotConstraints = constraintsDict[constraintName];

var buildingConfigList100 = new List<BuildingMapConfig>();
foreach (int val in randNumbers)
{
buildingConfigList100.Add(new BuildingMapConfig(val, widthInTiles: 100, heightInTiles: 100));
}

var mapSizes = new List<int> { 50, 75, 100 };
var algorithms = new Dictionary<string, RobotSpawner<IPatrollingAlgorithm>.CreateAlgorithmDelegate>
{
{ "random_reactive", _ => new RandomReactive() },
};
var buildingMaps = ((buildingConfigList100));
foreach (var mapConfig in buildingMaps)
{
for (var amountOfRobots = 1; amountOfRobots < 10; amountOfRobots += 2)
{
var robotCount = amountOfRobots;
foreach (var size in mapSizes)
{
foreach (var (algorithmName, algorithm) in algorithms)
{
simulator.EnqueueScenario(new MySimulationScenario(seed: 123,
mapSpawner: generator => generator.GenerateMap(mapConfig),
robotSpawner: (buildingConfig, spawner) => spawner.SpawnRobotsTogether(
buildingConfig,
seed: 123,
numberOfRobots: robotCount,
suggestedStartingPoint: new Vector2Int(random.Next(-size/2, size/2), random.Next(-size/2, size/2)),
createAlgorithmDelegate: algorithm),
statisticsFileName: $"{algorithmName}-seed-{mapConfig.RandomSeed}-size-{size}-comms-{constraintName}-robots-{robotCount}-SpawnTogether",
robotConstraints: robotConstraints)
);

var spawningPosList = new List<Vector2Int>();
for (var amountOfSpawns = 0; amountOfSpawns < robotCount; amountOfSpawns++)
{
spawningPosList.Add(new Vector2Int(random.Next(0, size), random.Next(0, size)));
}

simulator.EnqueueScenario(new MySimulationScenario(seed: 123,
mapSpawner: generator => generator.GenerateMap(mapConfig),
robotSpawner: (buildingConfig, spawner) => spawner.SpawnRobotsAtPositions(
collisionMap: buildingConfig,
seed: 123,
numberOfRobots: robotCount,
spawnPositions: spawningPosList,
createAlgorithmDelegate: algorithm),
statisticsFileName: $"{algorithmName}-seed-{mapConfig.RandomSeed}-size-{size}-comms-{constraintName}-robots-{robotCount}-SpawnApart",
robotConstraints: robotConstraints)
);
}
}
}
}

//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,
mapSpawner: generator => generator.GenerateMap(dumpMap),
robotSpawner: (buildingConfig, spawner) => spawner.SpawnRobotsTogether(
buildingConfig,
seed: 123,
numberOfRobots: 5,
suggestedStartingPoint: Vector2Int.zero,
createAlgorithmDelegate: _ => new RandomReactive()),
statisticsFileName: "delete-me",
robotConstraints: robotConstraints));

simulator.PressPlayButton(); // Instantly enter play mode

//simulator.GetSimulationManager().AttemptSetPlayState(SimulationPlayState.FastAsPossible);
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 56 additions & 0 deletions Assets/Scripts/PatrollingAlgorithms/RandomReactive.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System;
using System.Linq;
using UnityEngine;

using Maes.Map;

/// <summary>
/// The random reactive patrolling algorithm from "Multi-Agent Movement Coordination in Patrolling", 2002
/// </summary>
namespace Maes.PatrollingAlgorithms
{
public class RandomReactive : PatrollingAlgorithm
{
public override string AlgorithmName => "Random Reactive Algorithm";
private bool _isPatrolling;

public override string GetDebugInfo()
{
return
base.GetDebugInfo() +
$"Init done: {_isPatrolling}\n";
}


protected override void Preliminaries()
{
if (_isPatrolling) return;

var vertex = GetClosestVertex();
TargetVertex = vertex;
_isPatrolling = true;
}

protected override Vertex NextVertex()
{
return TargetVertex.Neighbors.ElementAt(UnityEngine.Random.Range(0, TargetVertex.Neighbors.Count));
}

private Vertex GetClosestVertex()
{
Vertex? closestVertex = null;
var closestDistance = float.MaxValue;
var position = _controller.GetSlamMap().GetCoarseMap().GetCurrentPosition();
foreach (var vertex in _vertices)
{
var distance = Vector2Int.Distance(position, vertex.Position);
if (distance < closestDistance)
{
closestDistance = distance;
closestVertex = vertex;
}
}
return closestVertex ?? throw new InvalidOperationException("There are no vertices!");
}
}
}
11 changes: 11 additions & 0 deletions Assets/Scripts/PatrollingAlgorithms/RandomReactive.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading