Skip to content

Commit

Permalink
Merge branch 'AcoVision_to_movement' into AcoAgentMultiMapMovement
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/main/java/app/controller/GameEngine.java
#	src/main/java/app/model/Map.java
#	src/main/java/app/model/boundary/InvisibleBoundary.java
#	src/main/java/app/view/Frame.java
  • Loading branch information
Travisd13 committed Mar 9, 2022
2 parents 8e34dc7 + be82de6 commit dc98c14
Show file tree
Hide file tree
Showing 15 changed files with 449 additions and 28 deletions.
3 changes: 2 additions & 1 deletion src/main/java/app/controller/GameEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public GameEngine(Map map, Renderer renderer)

public void tick()
{
map.getAgents().forEach(a -> a.updateView(graphicsEngine.compute(map, a)));

for (Agent a :map.getAgents())
{
Vector startPoint = a.getPosition();
Expand All @@ -52,7 +54,6 @@ public void tick()
}
}

map.getAgents().forEach(a -> a.updateView(graphicsEngine.compute(map, a)));
renderer.render();
}

Expand Down
5 changes: 5 additions & 0 deletions src/main/java/app/controller/graphicsEngine/Ray.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ public Ray(Vector u, Vector v)
this.v = v;
}

public double getAngle()
{
return angle;
}

public double angle()
{
return v.sub(u).getAngle();
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/app/controller/graphicsEngine/RayTracing.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ private ArrayList<Ray> scatterRays(Agent agent)
{
ArrayList<Ray> rays = new ArrayList<>();
Vector origin = agent.getPosition();
Vector direction = agent.getDirection();
Ray ray = new Ray(origin, direction);
Vector nextPosition = origin.add(agent.getDirection());
Ray ray = new Ray(origin, nextPosition);
double theta = 0;
for(int i = 0; i < noOfRays; i++)
{
Expand Down
10 changes: 9 additions & 1 deletion src/main/java/app/controller/linAlg/Vector.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,15 @@ public Vector rotate(double degrees)
public double getAngle()
{
// + 90 to set the angle to north, negate angle to make it clockwise
return (-Math.toDegrees(Math.atan2(y,x)) + 360.0 + 90.0) % 360.0;
// Rounded to 1 decimal place
double angle = (-Math.toDegrees(Math.atan2(y,x)) + 360.0 + 90.0) % 360.0;
double roundedAngle = (double) Math.round(angle * 10) / 10;

if(roundedAngle == 360.0)
{
roundedAngle = 0.0;
}
return roundedAngle;
}

public Vector copy()
Expand Down
12 changes: 7 additions & 5 deletions src/main/java/app/model/Grid/AcoGrid.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app.model.Grid;

import app.model.agents.ACO.AcoAgent;
import app.model.agents.Cells.Cell;
import app.model.agents.Cells.CellType;
import app.model.agents.Cells.PheromoneCell;

Expand All @@ -25,7 +26,7 @@ public void updateAgent(AcoAgent agent)
int col = getCellCol(agent.getPosition());

PheromoneCell cell = (PheromoneCell) super.getCellAt(row, col);
cell.updatePheromone(agent.releaseMaxPheramone());
cell.updatePheromone(agent.releaseMaxPheromone());
}

public void evaporationProcess()
Expand All @@ -40,13 +41,14 @@ public void evaporationProcess()
}
}

public void displayGridState()
//TODO Rewrite method to toString
public void print()
{
for(int i = 0; i < getRowDimension(); i++)
for(Cell[] line : grid)
{
for(int j = 0; j < getColDimension(); j++)
for(Cell cell: line)
{
System.out.print(grid[i][j].toString() + " ");
System.out.print(cell.toString() + " ");
}
System.out.println();
}
Expand Down
10 changes: 8 additions & 2 deletions src/main/java/app/model/Grid/Grid.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ public class Grid

public Grid(double length, double width, CellType type)
{
rowSize = (int)(length / cellSize);
colSize = (int)(width / cellSize);
//Addition of single cell to accomodate for 0 cells
rowSize = (int)(Math.ceil(length / cellSize) + 1);
colSize = (int)(Math.ceil(width / cellSize) + 1);
this.type = type;

grid = initializeAllCells();
Expand Down Expand Up @@ -67,4 +68,9 @@ public int getColDimension()
{
return grid[0].length;
}

public double getCellSize()
{
return cellSize;
}
}
1 change: 1 addition & 0 deletions src/main/java/app/model/Map.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import app.controller.settings.SettingsObject;
import app.controller.soundEngine.SoundFurniture;
import app.controller.soundEngine.SoundSource;
import app.model.agents.ACO.AcoAgent;
import app.model.agents.Agent;
import app.model.agents.Human;
import app.model.agents.WallFollowAgent;
Expand Down
168 changes: 163 additions & 5 deletions src/main/java/app/model/agents/ACO/AcoAgent.java
Original file line number Diff line number Diff line change
@@ -1,35 +1,188 @@
package app.model.agents.ACO;

import app.controller.graphicsEngine.Ray;
import app.controller.linAlg.Vector;
import app.model.Grid.AcoGrid;
import app.model.agents.AgentImp;
import app.model.agents.Cells.PheromoneCell;
import app.model.map.Move;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;

//TODO Accomodate for agents clashes
public class AcoAgent extends AgentImp
{
//TODO Place actual max pheramone value
private double maxPheramone = 10;
private double maxPheromone = 1;
private static AcoGrid world;
private double cellSize = world.getCellSize();
Random randomGenerator = new Random(1);

private HashMap<Integer, PheromoneCell> agentMap = new HashMap<>();

private int[] cardinalAngles = {0, 90, 180, 270};
private double epsilon = 0.3;

public AcoAgent(Vector position, Vector direction, double radius)
{
super(position, direction, radius);
world.updateAgent(this);
}

// 1. Agent looks around
// 2. Determine cardinal rays
// 3. Determine positions to move to that aren't blocked (Wall or agent)
// 4. Determine pheromone value at each position
// 5. Determine best move and execute it.
// 6. After all agents have gone, perform evaporation procedure
@Override
public Move move()
{
Ray[] cardinalRays = detectCardinalRays();
ArrayList<Vector> possibleMovements = determineAvailableMovements(cardinalRays);
ArrayList<Double> cellPheromones = accessAvaliableCellPheromones(possibleMovements);

ArrayList<Vector> equivalentMinMoves = determineEquivalentMinMoves(cellPheromones, possibleMovements);
Vector moveVector= selectRandomEquivalentMove(equivalentMinMoves);
return new Move(position, moveVector);
}

@Override
public void updateLocation(Vector endPoint)
{
position = endPoint;
world.updateAgent(this);
System.out.println(position.toString());
}

//TODO Implement movement bias based on target direction
public ArrayList<Vector> determineEquivalentMinMoves(ArrayList<Double> cellPheromones, ArrayList<Vector> possibleMovements)
{
double minValue = Double.MAX_VALUE;
ArrayList<Vector> equivalentMoves = new ArrayList<>();

for(int i = 0; i < cellPheromones.size(); i++)
{
if(cellPheromones.get(i) == minValue)
{
equivalentMoves.add(possibleMovements.get(i));
}
else if(cellPheromones.get(i) < minValue)
{
equivalentMoves.clear();
minValue = cellPheromones.get(i);
equivalentMoves.add(possibleMovements.get(i));
}
}
return equivalentMoves;
}

public Vector selectRandomEquivalentMove(ArrayList<Vector> equivalentMoves)
{
return equivalentMoves.get(randomGenerator.nextInt(equivalentMoves.size()));
}

public ArrayList<Double> accessAvaliableCellPheromones(ArrayList<Vector> possibleMovements)
{

ArrayList<Double> cellPheromoneValues = new ArrayList<>();

for(Vector movement : possibleMovements)
{
Vector resultingPosition = position.add(movement);
PheromoneCell possibleCell = (PheromoneCell) world.getCellAt(resultingPosition);
cellPheromoneValues.add(possibleCell.currentPheromoneValue());
}
return cellPheromoneValues;
}

public ArrayList<Vector> determineAvailableMovements(Ray[] cardinalRays)
{
ArrayList<Vector> possibleMovements = new ArrayList<>();

for(int i = 0; i < cardinalRays.length; i++)
{
if(cardinalRays[i].rayLength() > cellSize + epsilon)
{
possibleMovements.add(angleToGridMovementLink(cardinalAngles[i]));
}
}
return possibleMovements;
}

public Vector angleToGridMovementLink(int angle)
{
switch(angle)
{
case 0:
return new Vector(0, cellSize);
case 90:
return new Vector(cellSize, 0);
case 180:
return new Vector(0, -cellSize);
case 270:
return new Vector(-cellSize, 0);
default:
return null;
}
}

public Ray[] detectCardinalRays()
{
Ray[] cardinalRays = new Ray[cardinalAngles.length];

for(int i = 0; i < cardinalAngles.length; i++)
{
cardinalRays[i] = detectCardinalPoint(cardinalAngles[i]);
}
return cardinalRays;
}

public Ray detectCardinalPoint(double targetCardinalAngle)
{
int upperBound = view.size() - 1;
int lowerBound = 0;

while(lowerBound <= upperBound)
{
int midPoint = calculateMidPoint(upperBound, lowerBound);
double currentAngle = view.get(midPoint).angle();

if(approximateAngleRange(currentAngle, targetCardinalAngle))
{
return view.get(midPoint);
}
else if(currentAngle < targetCardinalAngle)
{
lowerBound = midPoint + 1;
}
else if(currentAngle > targetCardinalAngle)
{
upperBound = midPoint - 1;
}
}
System.out.println("Cardinal Point not found");
return null;
}

public int calculateMidPoint(int upperBound, int lowerBound)
{
return lowerBound + (upperBound - lowerBound)/2;
}

public double releaseMaxPheramone()
public boolean approximateAngleRange(double detectedAngle, double targetAngle)
{
return maxPheramone;
if(detectedAngle < (targetAngle + epsilon) && detectedAngle > (targetAngle - epsilon))
{
return true;
}
return false;
}

public double releaseMaxPheromone()
{
return maxPheromone;
}

public static void initializeWorld(double width, double height)
Expand All @@ -40,4 +193,9 @@ public static AcoGrid accessWorld()
{
return world;
}
}

public int[] getCardinalAngles()
{
return cardinalAngles;
}
}
12 changes: 6 additions & 6 deletions src/main/java/app/model/agents/Cells/PheromoneCell.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,31 @@

public class PheromoneCell implements Cell
{
private double pheramone;
private double pheromone;
private double evaporationConstant = 0.001;

public PheromoneCell()
{
this.pheramone = 0.0;
this.pheromone = 0.0;
}

public double currentPheromoneValue()
{
return pheramone;
return pheromone;
}

public void updatePheromone(double maxPheramone)
{
pheramone += maxPheramone;
pheromone += maxPheramone;
}

public void evaporation()
{
pheramone = pheramone * (1 - evaporationConstant);
pheromone = pheromone * (1 - evaporationConstant);
}

public String toString()
{
return Double.toString(pheramone);
return Double.toString(pheromone);
}
}
Empty file.
Empty file.
Loading

0 comments on commit dc98c14

Please sign in to comment.