Commit 71a79a0c authored by Eduardo Varas's avatar Eduardo Varas
Browse files

Ubiksim adaptado a MOSI-AGIL

parent 53843b97
#Configuracion de UbikSim
#Parte estandar de simulación:
# Modo de vision, 3 valores: "0D","2D","3D"
mode=3D
#Tamaño de la celda en centimetros
cellSize=30
# Lista deficheros de cada planta separados por comas, e.j., "floors=f0.sh3d,f1.sh3d,f2.sh3d"
#Lista deficheros de cada planta separados por comas, e.j., "floors=f0.sh3d,f1.sh3d,f2.sh3d"
floors=./environments/EtsitEdificioBPlantaBaja.ubiksim
# Valor de la semilla para la simulacion, valores: "random" o un numero.
seed=2
......@@ -16,6 +17,15 @@ initialDate=2012-01-01 00:00:00
# perspectiva de la camara 1 primera persona, 0 vista aerea.
cameraMode=0
# nombre del personaje que se quiere controlar con el teclado
#keyboardControlled=Paula
#Integracion con Prodia
prodia=off
#Parte variable de la simulación
#Valores iniciales de emergencia
xfire=60
yfire=50
......@@ -23,12 +33,16 @@ sizefire=1
speedfire=1
delayfire=100
#Personas:
pospeople=/30,30/50,50/60,60/70,70/
#Valores de agentes:
#Generación de múltiples personas en coordenadas concretas
personloc=/30,30/50,50/60,60/70,70/80,80/
population=80
# nombre del personaje que se quiere controlar con el teclado
#keyboardControlled=Paula
#4 tipos de comportamientos
#Behaviors: mindist, maxdistfire, leastload, bestsol
behavior=mindist
#Integracion con Prodia
prodia=off
\ No newline at end of file
1508319629661
\ No newline at end of file
......@@ -77,7 +77,17 @@ public class Ubik extends SimState {
/**
*
*/
/**
* Eleccin del tipo de comportamiento
*/
private int behavior;
/**
* Eleccin de gente y colocacin en posiciones
*/
protected List<Int2D> posPeople;
protected int population;
int[] ocupacionSalidas = new int[3];
private UbikClock clock; // Reloj para registrarse y que te avisa cuando se
// alcanza el tiempo indicado
......@@ -119,7 +129,33 @@ public class Ubik extends SimState {
super(seed);
loadConfig(new Configuration());
}
/**
* Clculo de salidas ms ocupadas
* @param exit
*/
public void setOcupation(String exit) {
if (exit=="Exit1") {
ocupacionSalidas[0]++;
}
else if (exit=="Exit2") {
ocupacionSalidas[1]++;
}
else if (exit=="Exit3") {
ocupacionSalidas[2]++;
}
}
public int[] getOcupation() {
return ocupacionSalidas;
}
public int getBehavior() {
return behavior;
}
private void loadConfig(Configuration configuration) {
cellSize = configuration.getCellSize();
seedFromFile = configuration.getSeed();
......@@ -133,6 +169,8 @@ public class Ubik extends SimState {
speedFire = configuration.getSpeedFire();
posPeople = configuration.getPosPeople();
delayFire = configuration.getDelayFire();
behavior= configuration.getBehavior();
population = configuration.getPopulation();
}
/**
......
......@@ -35,7 +35,7 @@ import sim.portrayal.Inspector;
public class UbikSimWithUI extends GUIState {
private static final Logger LOG = Logger.getLogger(UbikSimWithUI.class.getName());
protected static final Logger LOG = Logger.getLogger(UbikSimWithUI.class.getName());
public UbikSimDisplay3D ubikSimDisplay3D;
public UbikSimDisplay2D ubikSimDisplay2D;
......
......@@ -57,7 +57,7 @@ public class EscapeMonitorAgent implements MonitorService {
/**
* Counter with people who have touch fire
*/
protected int peopleCloseToFire=0;
public int peopleCloseToFire=0;
......
......@@ -172,7 +172,8 @@ public class Fire implements Steppable, Stoppable {
}
private void spreadFire(){
private void spreadFire(){
if(fireFurniture!=null){
ubik.getBuilding().getFloor(0).getHome().deletePieceOfFurniture(fireFurniture);
......@@ -180,6 +181,8 @@ public class Fire implements Steppable, Stoppable {
fireFurniture.setDepth(fireFurniture.getDepth()+advanceOfFirePerStep*ubik.getCellSize());
ubik.getBuilding().getFloor(0).getHome().addPieceOfFurniture(fireFurniture);
}
}
}
......@@ -45,120 +45,137 @@ import ubik3d.model.HomePieceOfFurniture;
* adjust speed and algorithm efficiency (bigger cells make the algorithm faster
* since nodes are reduced)
*
* Consider parameters of AStarPathFinder when navigation faults are found. The diagonal movements
* can make agents go through walls corners (using the diagonal movement); and the max number of steps
* can be not large enough if cell size is small.
* Consider parameters of AStarPathFinder when navigation faults are found. The
* diagonal movements can make agents go through walls corners (using the
* diagonal movement); and the max number of steps can be not large enough if
* cell size is small.
*
* @author Emilio Serrano, Ph.d.; eserrano [at] gsi.dit.upm.es
*/
public class Pathfinder implements Steppable {
protected AStarPathFinder pathfinder;
protected Path path;
protected BooleanPathfindingMap pmap;
/**
* Index for the path followed
*/
protected int lastStepInPath;
protected Int2D goal;
protected Person p;
protected static final Logger LOG = Logger.getLogger(Pathfinder.class.getName());
/**
* Used to add marks in the 3D environment
*/
protected HomePieceOfFurniture marker;
public Pathfinder(Person p) {
this.p = p;
pmap = new BooleanPathfindingMap(p, 10);//perception of 10, the person can see 10 positions ahead to detect mobile obstacles
pathfinder = new AStarPathFinder(pmap, 10000, true);//plan with no more than 1000 steps,diagonal movement allowed
Logger.getLogger(Pathfinder.class.getName()).setLevel(Level.WARNING);//change to info for more details about pathfinding
}
/**
* Make the agent take a step in the path generated. If the mobile obstacles such as people do not let the agent advance, a new path is recalculated
* and the next step will try to follow it.
*
* It does not count tries of getting the goal (so an agent can keep trying to calculate a path to reach an unreachele goal)
* @param state
*/
@Override
public void step(SimState state) {
if (goal == null) {
LOG.info(p.getName() + " DOESN'T have a path or goal defined, use setGoal");
return;
}
if(goal!=null && path==null){//try getting path again, the agent could be sorrounded by mobile agents
setGoalAndGeneratePath(goal);
if(path==null) return; //no path found
}
Int2D nextPosition = new Int2D(path.getX(lastStepInPath), path.getY(lastStepInPath)); //get next step in path
boolean moved = p.setPosition(nextPosition.x, nextPosition.y);//false if movement could no be finished (another person in that position)
if (moved) {
lastStepInPath++;
} else {//generate path again without changing the goal the perception is considered to avoid close mobile obstacles
LOG.info(p.getName() + " found a mobile obstacle, recalculating");
setGoalAndGeneratePath(goal);
}
}
public void deletePath() {
this.path=null;
}
/**
* Set goal an calculate path.
* The agent color is change to red if no path was found and a marker inserted in the display. This can be removed with p.setColor
* A blue marker is inserted when path found, red marker when not found
* Consider that if the agent is surrounded or there is no path without obstacles, path will be null and false returned.
* @param goal
* @return false if path was not generated (no path far the given goal)
*/
public boolean setGoalAndGeneratePath(Int2D goal) {
this.goal = goal;
path = pathfinder.findPath(null, p.getPosition().x, p.getPosition().y, goal.x, goal.y); //get path
lastStepInPath = 1;
if(marker!=null){
PositionTools.removeMarkerInDisplay(p, marker);
marker=null;
}
if (path != null) {
LOG.info(p.getName() + " generated a path from (" + p.getPosition().x + "," + p.getPosition().y + ") to (" + goal.x + "," + goal.y + ") in " + path.getLength() + " steps.");
marker= PositionTools.insertMakerInDisplay(p, goal.x,goal.y, Color.BLUE);
} else {
LOG.info(p.getName() + " DIDN'T find a reachable path from (" + p.getPosition().x + "," + p.getPosition().y + ") to (" + goal.x + "," + goal.y + ")");
p.setColor(Color.RED);
marker= PositionTools.insertMakerInDisplay(p, goal.x,goal.y, Color.RED);
}
return (path != null);
}
/**
* true if agent is in goal fixed
* @return
*/
public boolean isInGoal() {
return (p.getPosition().x == goal.x && p.getPosition().y == goal.y);
}
/**
* Check if reachable. It can be interesting to make sure that tha path is reachable before fixing a goal
* @return
*/
public boolean checkIfReachable(){
return (pathfinder.findPath(null, p.getPosition().x, p.getPosition().y, goal.x, goal.y))!=null;
}
protected AStarPathFinder pathfinder;
protected Path path;
protected BooleanPathfindingMap pmap;
/**
* Index for the path followed
*/
protected int lastStepInPath;
protected Int2D goal;
protected Person p;
protected static final Logger LOG = Logger.getLogger(Pathfinder.class.getName());
/**
* Used to add marks in the 3D environment
*/
protected HomePieceOfFurniture marker;
public Pathfinder(Person p) {
this.p = p;
pmap = new BooleanPathfindingMap(p, 10);// perception of 10, the person can see 10 positions ahead to detect
// mobile obstacles
pathfinder = new AStarPathFinder(pmap, 10000, true);// plan with no more than 1000 steps,diagonal movement
// allowed
Logger.getLogger(Pathfinder.class.getName()).setLevel(Level.WARNING);// change to info for more details about
// pathfinding
}
/**
* Make the agent take a step in the path generated. If the mobile obstacles
* such as people do not let the agent advance, a new path is recalculated and
* the next step will try to follow it.
*
* It does not count tries of getting the goal (so an agent can keep trying to
* calculate a path to reach an unreachele goal)
*
* @param state
*/
@Override
public void step(SimState state) {
if (goal == null) {
LOG.info(p.getName() + " DOESN'T have a path or goal defined, use setGoal");
return;
}
if (goal != null && path == null) {// try getting path again, the agent could be sorrounded by mobile agents
setGoalAndGeneratePath(goal);
if (path == null)
return; // no path found
}
try {
Int2D nextPosition = new Int2D(path.getX(lastStepInPath), path.getY(lastStepInPath)); // get next step in
// path
boolean moved = p.setPosition(nextPosition.x, nextPosition.y);// false if movement could no be finished
// (another person in that position)
if (moved) {
lastStepInPath++;
} else {// generate path again without changing the goal the perception is considered to
// avoid close mobile obstacles
LOG.info(p.getName() + " found a mobile obstacle, recalculating");
setGoalAndGeneratePath(goal);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void deletePath() {
this.path = null;
}
/**
* Set goal an calculate path. The agent color is change to red if no path was
* found and a marker inserted in the display. This can be removed with
* p.setColor A blue marker is inserted when path found, red marker when not
* found Consider that if the agent is surrounded or there is no path without
* obstacles, path will be null and false returned.
*
* @param goal
* @return false if path was not generated (no path far the given goal)
*/
public boolean setGoalAndGeneratePath(Int2D goal) {
this.goal = goal;
path = pathfinder.findPath(null, p.getPosition().x, p.getPosition().y, goal.x, goal.y); // get path
lastStepInPath = 1;
if (marker != null) {
PositionTools.removeMarkerInDisplay(p, marker);
marker = null;
}
if (path != null) {
LOG.info(p.getName() + " generated a path from (" + p.getPosition().x + "," + p.getPosition().y + ") to ("
+ goal.x + "," + goal.y + ") in " + path.getLength() + " steps.");
marker = PositionTools.insertMakerInDisplay(p, goal.x, goal.y, Color.BLUE);
} else {
LOG.info(p.getName() + " DIDN'T find a reachable path from (" + p.getPosition().x + "," + p.getPosition().y
+ ") to (" + goal.x + "," + goal.y + ")");
p.setColor(Color.RED);
marker = PositionTools.insertMakerInDisplay(p, goal.x, goal.y, Color.RED);
}
return (path != null);
}
/**
* true if agent is in goal fixed
*
* @return
*/
public boolean isInGoal() {
return (p.getPosition().x == goal.x && p.getPosition().y == goal.y);
}
/**
* Check if reachable. It can be interesting to make sure that tha path is
* reachable before fixing a goal
*
* @return
*/
public boolean checkIfReachable() {
return (pathfinder.findPath(null, p.getPosition().x, p.getPosition().y, goal.x, goal.y)) != null;
}
}
......@@ -34,7 +34,9 @@ import sim.app.ubik.behaviors.pathfinderDemos.PathfinderThread;
import sim.app.ubik.building.rooms.Room;
import sim.engine.SimState;
import sim.util.Int2D;
import sim.util.MutableInt2D;
import ubik3d.model.HomePieceOfFurniture;
import ubiksimdist.EscapeSim;
/**
* Teacher person example: uses the pathfinding to reach 5 random positions
......@@ -58,6 +60,8 @@ public class Teacher extends Person {
private String localGoal=null;//local goal if no global is fixed
private List<String> roomList;
private String newGoal;
protected boolean hasBeenCloseToFire;
protected EscapeSim sim= (EscapeSim) this.getUbik();
public Teacher(int floor, HomePieceOfFurniture person3DModel, Ubik ubik) {
super(floor, person3DModel, ubik);
......@@ -85,29 +89,48 @@ public class Teacher extends Person {
else{this.setColor(Color.BLUE);}//blue to say that agent has accomplished all goals
}
else if(ubik.getFireActivity()&&!buscaSalida) {
goals.clear();
goals.clear();
currentGoal=null;
this.localGoal=this.getMaxExit();//random exit
int behavior = this.getUbik().getBehavior();
if (behavior == 1) {
this.localGoal=this.getMinExit();
}
else if(behavior == 2) {
this.localGoal=this.getMaxExit();
}
else if (behavior == 3) {
this.localGoal=this.getLeastLoadedExit();
}
else if (behavior == 4) {
this.localGoal=this.getBestExit();
}
this.ubik.setOcupation(this.localGoal);
goals.add(PositionTools.getRoom(this,localGoal).getCenter());
currentGoal = goals.get(0);
pf.setGoalAndGeneratePath(currentGoal);
/*if(pf.isInGoal()){
this.stop();//stop agent and make it get out of the simulation
PositionTools.getOutOfSpace(this);
LOG.info(name + " has leave the building using " + localGoal);
return;
}*/
buscaSalida=true;
}
else if(pf.isInGoal() && buscaSalida) {
this.stop();//stop agent and make it get out of the simulation
PositionTools.getOutOfSpace(this);
LOG.info(name + " has leave the building using " + localGoal);
if(this.hasBeenCloseToFire)
LOG.info(name + " has touched the fire");
else
LOG.info(name + " has not touched the fire");
return;
}
else{
pf.step(state);//take steps to the goal (step can regenerate paths)
}
if(!this.hasBeenCloseToFire()){
if (sim.getFire().tauchingFire(this)){
this.setCloseToFire(true);
sim.getMonitorAgent().peopleCloseToFire++;
}
}
......@@ -129,41 +152,196 @@ public class Teacher extends Person {
* Devuelve el nombre de la salida ms cercana
*
*/
private String getBestExit(){
String bestexit = "";
String minexit = this.getMinExit();
double mindistance = this.getMinExitDistance();
String maxfire = this.getMaxExit();
String leastload = this.getLeastLoadedExit();
String minfireexit = this.getMinExitFire(this.getUbik().getFirePos());
double minfireexitdist = this.getMinExitFireDist(this.getUbik().getFirePos());
int indice;
int[] ocupation = this.getUbik().getOcupation();
PersonHandler ph = this.getUbik().getBuilding().getFloor(0).getPersonHandler();
if(minexit == minfireexit) {
if (mindistance<minfireexitdist){
bestexit=minexit;
}
else {
for(indice = 0; indice<exits.length; indice++) {
if(exits[indice]==maxfire) {
break;
}
}
if((double)ocupation[indice]<(double) ph.getPersons().size()/2) {
bestexit=maxfire;
}
else {
if(maxfire!=leastload && minexit != leastload) {
bestexit=leastload;
}
else {
for (int i=0; i<exits.length; i++) {
if(exits[i]!=minexit && exits[i]!=maxfire)
bestexit=exits[i];
break;
}
}
}
}
}
else {
bestexit=minexit;
}
return bestexit;
}
/**
* Busca la salida ms cercana a la persona
* @return
*/
private String getMinExit(){
String exit="";
String min="";
int mindist = 0;
int mindist = 1999999999;
for (int i=0; i<exits.length; i++) {
exit = exits[i];
Int2D pos = PositionTools.getRoom(this,exit).getCenter();
int distance = PositionTools.getDistance(this.getPosition().x, this.getPosition().y, pos.x, pos.y);
if (distance <mindist || mindist==0) {
if (distance <mindist) {
mindist=distance;
min = exits[i];
}
}
return min;
}
/**
* Devuelve el nombre de la salida ms cercana al fuego
* @return
*/
private String getMinExitFire(Int2D firepos){
String exit="";
String min="";
int mindist = 1999999999;
for (int i=0; i<exits.length; i++) {
exit = exits[i];
Int2D pos = PositionTools.getRoom(this,exit).getCenter();
int distance = PositionTools.getDistance(firepos.x, firepos.y, pos.x, pos.y);
if (distance <mindist) {
mindist=distance;
min = exits[i];
}
}
return min;
}
/**
* Devuelve la distancia del fuego a la puerta mas cercana
* @param firepos
* @return
*/
private double getMinExitFireDist(Int2D firepos){
String exit="";
String min="";
double mindist = 1999999999;
for (int i=0; i<exits.length; i++) {
exit = exits[i];
Int2D pos = PositionTools.getRoom(this,exit).getCenter();
double distance = PositionTools.getDistance(firepos.x, firepos.y, pos.x, pos.y);
if (distance <mindist) {
mindist=distance;
min = exits[i];
}
}
return mindist;
}
/**
* Devuelve la distancia a la salida ms cercana a la persona
* @return
*/
private double getMinExitDistance(){
String exit="";
String min="";
double mindist = 1999999999;
for (int i=0; i<exits.length; i++) {
exit = exits[i];
Int2D pos = PositionTools.getRoom(this,exit).getCenter();