Implementing the “knowledge” package
The Knowledge Module represents the memory of an agent. It stores the knowledge an agent knows about itself. In addition, it stores external knowledge acquired by the agent through its perception sensors or learned by combining the knowledge acquired by various perception sensors.
1. Implementing the “ontology” package
In “knowledge package”, create “ontology” subpackage. This subpackage includes 2 classes:
Class “Door” stores information regarding door’s. Each door has exactly two rooms attached to it.
Class “Room” stores knowledge about the room.
To implement the “Door” class:
- Create a new class inside the “ontology” package and name it “Door”.
- Copy the code given below that describes the full implementation of a “Door” class.
package edu.utdallas.mavs.evacuation.simulation.sim.agent.knowledge.ontology; import edu.utdallas.mavs.divas.core.sim.agent.knowledge.ontology.Thing; import edu.utdallas.mavs.divas.utils.collections.LightWeightBoundedQueue; /** * Store information regarding door's. Each door has exactly two rooms attached to it. */ public class Door extends Thing { /** * Serializer ID */ private static final long serialVersionUID = 1L; private static final int MAX_NEIGHBOR = 25; /** * The Door's ID */ private int id = -1; private int doorCongestion = 0; private boolean visited = false; private boolean isExit = false; private boolean obstacled = false; private LightWeightBoundedQueue<Integer> neighbors; private float doorflow = 0; private float gscore, fscore; private Door cameFrom; private int depth = 0; private boolean closed = false; private boolean newNode = true; private long cycleSet = 0; /** * Create a door with envobj ID * * @param id * ID of envobj */ public Door(int id) { this.id = id; neighbors = new LightWeightBoundedQueue<Integer>(MAX_NEIGHBOR); } /** * Get ID * * @return ID */ public int getId() { return id; } /** * Set ID * * @param id * ID */ public void setId(int id) { this.id = id; } /** * Get all neighbors to this door * * @return list of neighbors */ public LightWeightBoundedQueue<Integer> getNeighbors() { return neighbors; } /** * clear the neighbor list */ public void clearNeighbors() { neighbors.clear(); } /** * Add a new neighbor to this door * * @param newNeighbor * the neighbor to be added */ public void addNeighbor(int newNeighbor) { neighbors.add(newNeighbor); } /** * Remove a neighbor to this door * * @param neighbor * the neighbor to be removed */ public void removeNeighbor(int neighbor) { neighbors.remove(neighbor); } public boolean isVisited() { return visited; } public void setVisited(boolean visited) { this.visited = visited; } /** * Get the depth if this node (Astar) * * @return integer depth */ public int getDepth() { return depth; } /** * Set the depth of this node (Astar) * * @param depth * the integer depth */ public void setDepth(int depth) { this.depth = depth; } /** * Whether the node is closed or not. (Astar) * * @return true if closed, false otherwise */ public boolean isClosed() { return closed; } /** * Set whether this node is closed or not. (Astar) * * @param closed * true if closed, false if not */ public void setClosed(boolean closed) { this.closed = closed; } /** * Check whether this is a new node or not. (Astar) * * @return true if new, false otherwise */ public boolean isNewNode() { return newNode; } /** * Set whether this is a new node or not. (Astar) * * @param newNode * true if new, false otherwise */ public void setNewNode(boolean newNode) { this.newNode = newNode; } /** * Get the G-score of the node (Astar) * * @return the G-score float */ public float getGscore() { return gscore; } /** * Set the G-score of the node (Astar) * * @param gscore * the G-score float */ public void setGscore(float gscore) { this.gscore = gscore; } /** * Get the F-score of the node (Astar) * * @return the F-score float */ public float getFscore() { return fscore; } /** * Set the F-score of the node (Astar) * * @param fscore * the F-score float */ public void setFscore(float fscore) { this.fscore = fscore; } /** * Get the parent node (Astar) * * @return parent node */ public Door getCameFrom() { return cameFrom; } /** * Set the parent node (Astar) * * @param cameFrom * parent node */ public void setCameFrom(Door cameFrom) { this.cameFrom = cameFrom; } public boolean isExit() { return isExit; } public void setExit(boolean isExit) { this.isExit = isExit; } public boolean isObstacled() { return obstacled; } public void setObstacled(boolean obstacled) { this.obstacled = obstacled; } public int getDoorCongestion() { return doorCongestion; } public void setDoorCongestion(int doorCongestion) { this.doorCongestion = doorCongestion; } public long getCycleSet() { return cycleSet; } public void setCycleSet(long cycleSet) { this.cycleSet = cycleSet; } public float getDoorflow() { return doorflow; } public void setDoorflow(float doorflow) { this.doorflow = doorflow; } }
To implement the “Room” class:
- Create a new class inside the “ontology” package and name it “Room”.
- Copy the code given below that describes the full implementation of a “Room” class.
package edu.utdallas.mavs.evacuation.simulation.sim.agent.knowledge.ontology; import java.util.ArrayList; import java.util.List; import edu.utdallas.mavs.divas.core.sim.agent.knowledge.ontology.Thing; /** * Class to store knowledge about rooms */ public class Room extends Thing { /** * Serializer ID */ private static final long serialVersionUID = 1L; /** * Each room can have any number of doors */ private List<Integer> doorsIDs; /** * Each room has an ID */ int id; /** * Whether or not the "room" is inside our outside */ boolean outside = false; /** * Whether or not the "room" is inside our outside * * @return Whether outside */ public boolean isOutside() { return outside; } /** * Set Whether or not the "room" is inside our outside * * @param outside * whether outside */ public void setOutside(boolean outside) { this.outside = outside; } /** * Create a new room * * @param id * the room's ID */ public Room(int id) { doorsIDs = new ArrayList<Integer>(); this.id = id; } /** * Get all the doors in the room. * * @return The doors */ public List<Integer> getDoorsIDs() { return doorsIDs; } /** * Check whether room has door with specified ID or not. * * @param id * ID to check * @return true if it has the door */ public boolean hasDoor(int id) { // prevent concurrent modification of doors synchronized(doorsIDs) { for(Integer i : doorsIDs) { if(i.equals(id)) { return true; } } } // System.out.println("rut FAWSEE on "+id); return false; } /** * Add a new door to the room. * * @param id * The door's ID */ public void addDoor(int id) { doorsIDs.add(id); } /** * Get the room's ID * * @return ID */ public int getId() { return id; } /** * Set the room's ID * * @param id * ID */ public void setId(int id) { this.id = id; } }
2. Implementing the “internal” package
In “knowledge package”, create “internal” subpackage. This subpackage includes class “LocationGoal” which stores information about location goal.
To implement the “LocationGoal” class:
- Create a new class inside the “internal” package and name it “LocationGoal”.
- Copy the code given below that describes the full implementation of a “LocationGoal” class.
package edu.utdallas.mavs.evacuation.simulation.sim.agent.knowledge.internal; import java.io.Serializable; import com.jme3.math.Vector3f; import edu.utdallas.mavs.divas.core.sim.agent.knowledge.internal.Goal; public class LocationGoal extends Goal implements Serializable { private static final long serialVersionUID = 1L; protected Vector3f location; public LocationGoal(int utilityValue, Vector3f location) { super(utilityValue); this.location = location; } public void setGoal(Vector3f location) { this.location = location; } public Vector3f getLocation() { return location; } }
3. Implementing the “external” package
In “knowledge package”, create “external” subpackage.
The external package stores knowledge about external objects. In this package, we create the class as listed below:
- VirtualKnowledgeStorageObject
- AbstractKnowledgeStorageObject
- AgentKnowledgeStorageObject
- EnvObjectKnowledgeStorageObject
- NeighborKnowledgeStorageObject
- VisionModel
To implement the “VirtualKnowledgeStorageObject” class:
- Create a new class inside the “external” package and name it “VirtualKnowledgeStorageObject”.
- Copy the code given below that describes the full implementation of a “VirtualKnowledgeStorageObject” class.
package edu.utdallas.mavs.evacuation.simulation.sim.agent.knowledge.external; import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.GeometryFactory; import edu.utdallas.mavs.divas.utils.physics.ActualObjectPolygon; /** * Store critial information about virtual objects. (All virtual objects will have this information) */ public class VirtualKnowledgeStorageObject extends AbstractKnowledgeStorageObject { private static final long serialVersionUID = 1L; /** * Virtual Object's Position */ protected Vector3f position = new Vector3f(0, 0, 0); /** * Virtual Object's Scale */ protected Vector3f scale = new Vector3f(0, 0, 0); /** * Flag indicating if this object is collidable */ protected boolean isCollidable = true; /** * The bounding area of the virtual entity in this state. */ protected ActualObjectPolygon boundingArea; /** * Returns the rectangles bounding area. * * @return the rectangles bounding area */ public ActualObjectPolygon getBoundingArea() { return boundingArea; } /** * Construct a Virtual Object's KSO * * @param id * the ID * @param scale * the Scale * @param position * the Position * @param isCollidable * if the object is collidable or not * @param boundingArea * the object's bounding area * @param boundingVolume * the object's bounding volume */ public VirtualKnowledgeStorageObject(int id, Vector3f scale, Vector3f position, boolean isCollidable, ActualObjectPolygon boundingArea) { super(id); this.scale = scale; this.position = position; this.isCollidable = isCollidable; this.boundingArea = boundingArea; } /** * Construct a Virtual Object's KSO * * @param id * the ID * @param position * the Position */ public VirtualKnowledgeStorageObject(int id, Vector3f position) { super(id); this.position = position; } /** * Get Virtual Object's Position * * @return Position */ public Vector3f getPosition() { return position; } /** * Get Virtual Object's Position * * @return Position */ public Vector2f getPosition2D() { return new Vector2f(position.x, position.z); } /** * Set Virtual Object's Position * * @param position * Position */ public void setPosition(Vector3f position) { this.position = position; } /** * Get Virtual Object's scale * * @return Scale */ public Vector3f getScale() { return scale; } /** * Set Virtual Object's Scale * * @param scale * Scale */ public void setScale(Vector3f scale) { this.scale = scale; } /** * Checks if the object is collidable * * @return true if colidable. False otherwise. */ public boolean isCollidable() { return isCollidable; } /** * Checks if its bounding area intersects the line determined by the given start and end points * * @param endPoint * end point of the line * @param startPoint * start point of the line * @return true if it intersects. Otherwise, false. */ public boolean intersects2DLine(Vector3f endPoint, Vector3f startPoint) { return boundingArea.intersects(new GeometryFactory().createLineString(new Coordinate[] {new Coordinate(endPoint.x, endPoint.z), new Coordinate(startPoint.x, startPoint.z)})); } /** * Checks if its bounding area contains the given point * * @param point * a point * @return true if it contains. Otherwise, false. */ public boolean contains2D(Vector3f point) { return boundingArea.contains(new GeometryFactory().createPoint(new Coordinate(point.x, point.z))); } /** * Checks if its bounding area intersects an agent * * @param testPoint * point to test * @param testScale * scale of agent to be tested * @return true if they intersect. Otherwise, false. */ public boolean intersects2D(Vector3f testPoint, Vector3f testScale) { ActualObjectPolygon test = new ActualObjectPolygon(new Vector2f(testPoint.x, testPoint.y), testScale); return boundingArea.intersects(test); } }
To implement the “AbstractKnowledgeStorageObject” class:
- Create a new class inside the “external” package and name it “AbstractKnowledgeStorageObject”.
- Copy the code given below that describes the full implementation of a “AbstractKnowledgeStorageObject” class.
package edu.utdallas.mavs.evacuation.simulation.sim.agent.knowledge.external; import java.io.Serializable; /** * Store important knowledge only. */ public abstract class AbstractKnowledgeStorageObject implements Serializable { /** * Serializer */ private static final long serialVersionUID = 9064581745286227871L; /** * ID of stored Object */ int id; /** * Constructor * * @param id * The ID */ public AbstractKnowledgeStorageObject(int id) { this.id = id; } /** * Get the ID * * @return The ID */ public int getID() { return id; } /** * Set the ID * * @param id * The ID */ public void setID(int id) { this.id = id; } @Override public boolean equals(Object arg0) { if(arg0 instanceof NeighborKnowledgeStorageObject) { return getID() == ((NeighborKnowledgeStorageObject) arg0).getID(); } return false; } @Override public int hashCode() { int hash = 1 + getID(); return hash; } @Override public String toString() { return "Id: " + getID(); } }
To implement the “AgentKnowledgeStorageObject” class:
- Create a new class inside the “external” package and name it “AgentKnowledgeStorageObject”.
- Copy the code given below that describes the full implementation of a “AgentKnowledgeStorageObject” class.
package edu.utdallas.mavs.evacuation.simulation.sim.agent.knowledge.external; import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; import edu.utdallas.mavs.divas.core.config.SimConfig; import edu.utdallas.mavs.divas.core.sim.common.state.AgentState; /** * Agent Knowledge Storage Object - Stores critical information regarding agents. */ public class AgentKnowledgeStorageObject extends VirtualKnowledgeStorageObject { private static final long serialVersionUID = 1L; Vector3f velocity; /** * GEts the ID, scale and position * * @param agent * an agent state to create the agent KSO from */ public AgentKnowledgeStorageObject(AgentState agent) { super(agent.getID(), agent.getScale(), agent.getPosition(), agent.isCollidable(), agent.getBoundingArea()); this.velocity = agent.getVelocity(); } public void updateValues(AgentState agent) { this.scale = agent.getScale(); this.position = agent.getPosition(); this.boundingArea = agent.getBoundingArea(); this.velocity = agent.getVelocity(); } public Vector3f getVelocity() { return velocity; } public Vector2f getVelocity2D() { return new Vector2f(velocity.x, velocity.z); } public void setVelocity(Vector3f velocity) { this.velocity = velocity; } public float getRadius() { return SimConfig.getInstance().agent_Radius; } }
To implement the “EnvObjectKnowledgeStorageObject” class:
- Create a new class inside the “external” package and name it “EnvObjectKnowledgeStorageObject”.
- Copy the code given below that describes the full implementation of a “EnvObjectKnowledgeStorageObject” class.
package edu.utdallas.mavs.evacuation.simulation.sim.agent.knowledge.external; import java.util.ArrayList; import java.util.List; import com.jme3.math.Vector3f; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.GeometryFactory; import edu.utdallas.mavs.divas.core.sim.common.state.EnvObjectState; import edu.utdallas.mavs.evacuation.simulation.sim.agent.planning.PathFindingNode; import edu.utdallas.mavs.evacuation.simulation.sim.common.state.DoorObjectState; /** * Store critial information about environment objects */ public class EnvObjectKnowledgeStorageObject extends VirtualKnowledgeStorageObject { private static final long serialVersionUID = 1L; /** * The EnvObj's description */ protected String description = ""; /** * The EnvObj's Type */ protected String type = ""; protected boolean isOpen = true; /** * Create an KSO from an environment object State * * @param envObj * the env object state */ public EnvObjectKnowledgeStorageObject(EnvObjectState envObj) { super(envObj.getID(), envObj.getScale(), envObj.getPosition(), envObj.isCollidable(), envObj.getBoundingArea()); this.description = envObj.getDescription(); this.type = envObj.getType(); if(envObj instanceof DoorObjectState) { this.isOpen = ((DoorObjectState) envObj).isOpen(); } } public boolean updateValues(EnvObjectState envObj) { boolean changed = false; if(!this.scale.equals(envObj.getScale())) { this.scale = envObj.getScale(); changed = true; } if(!this.position.equals(envObj.getPosition())) { this.position = envObj.getPosition(); changed = true; } if(this.isCollidable != envObj.isCollidable()) { this.isCollidable = envObj.isCollidable(); changed = true; } if(!this.boundingArea.equals(envObj.getBoundingArea())) { this.boundingArea = envObj.getBoundingArea(); changed = true; } if(envObj instanceof DoorObjectState && this.isOpen != ((DoorObjectState) envObj).isOpen()) { this.isOpen = ((DoorObjectState) envObj).isOpen(); changed = true; } return changed; } /** * Get the KSO's description * * @return the description */ public String getDescription() { return description; } /** * Set the KSO's description * * @param description * the description */ public void setDescription(String description) { this.description = description; } /** * Get the KSO's type * * @return the type */ public String getType() { return type; } /** * Set the KSO's type * * @param type * the type */ public void setType(String type) { this.type = type; } /** * Calculate the four corner points of an env object. * * @param points * passed in empty ponts reference * @param space * space away from object to buffer space with * @return the points list filled */ public List<Vector3f> calcPoints(float space) { List<Vector3f> points = new ArrayList<Vector3f>(); points.add(new Vector3f((position.x - (scale.x + space)), 0, (position.z - (scale.z + space)))); points.add(new Vector3f((position.x - (scale.x + space)), 0, (position.z + (scale.z + space)))); points.add(new Vector3f((position.x + (scale.x + space)), 0, (position.z - (scale.z + space)))); points.add(new Vector3f((position.x + (scale.x + space)), 0, (position.z + (scale.z + space)))); points.add(position); return points; } /** * Calculate the four corner points of an env object. * * @param points * passed in empty ponts reference * @param space * space away from object to buffer space with * @param agentSize * @return the points list filled */ public List<PathFindingNode> calcNodesNoCenter(float space, float agentSize) { List<PathFindingNode> points = new ArrayList<PathFindingNode>(); points.add(new PathFindingNode(agentSize, new Vector3f((position.x - (scale.x + space)), 0, (position.z - (scale.z + space))), id)); points.add(new PathFindingNode(agentSize, new Vector3f((position.x - (scale.x + space)), 0, (position.z + (scale.z + space))), id)); points.add(new PathFindingNode(agentSize, new Vector3f((position.x + (scale.x + space)), 0, (position.z - (scale.z + space))), id)); points.add(new PathFindingNode(agentSize, new Vector3f((position.x + (scale.x + space)), 0, (position.z + (scale.z + space))), id)); return points; } /** * Calculate the nodes of a door. * @param space * @param agentSize * * @return the points list filled */ public List<PathFindingNode> calcNodesForDoor(float space, float agentSize) { List<PathFindingNode> points = new ArrayList<PathFindingNode>(); points.add(new PathFindingNode(agentSize, new Vector3f((position.x - (scale.x + space)), 0, position.z), id)); points.add(new PathFindingNode(agentSize, new Vector3f((position.x + (scale.x + space)), 0, position.z), id)); points.add(new PathFindingNode(agentSize, new Vector3f(position.x, 0, (position.z - (scale.z + space))), id)); points.add(new PathFindingNode(agentSize, new Vector3f(position.x, 0, (position.z + (scale.z + space))), id)); return points; } /** * Checks if this object is in between two points * * @param startPoint * start point * @param endPoint * end point * @param space * space away from object to buffer space with * @return true if object is in between. Otherwise, false. */ public boolean isInBetween(Vector3f startPoint, Vector3f endPoint, float space) { List<Vector3f> points = calcPoints(space); for(Vector3f point : points) { if(((point.x > startPoint.x) && (point.x < endPoint.x)) || ((point.x < startPoint.x) && (point.x > endPoint.x))) { return true; } else if(((point.z > startPoint.z) && (point.z < endPoint.z)) || ((point.z < startPoint.z) && (point.z > endPoint.z))) { return true; } } return false; } public boolean agentPathIntersectsObj2D(Vector3f agentPosition, Vector3f goalPoint, float agentSize) { if(intersects2DLine(goalPoint.add(1, 0, 1), agentPosition.add(1, 0, 1))) { return true; } if(intersects2DLine(goalPoint.add(-1, 0, 1), agentPosition.add(-1, 0, 1))) { return true; } if(intersects2DLine(goalPoint.add(1, 0, -1), agentPosition.add(1, 0, -1))) { return true; } if(intersects2DLine(goalPoint.add(-1, 0, -1), agentPosition.add(-1, 0, -1))) { return true; } if(intersects2DLine(goalPoint, agentPosition)) { return true; } return false; } public boolean isOpen() { return isOpen; } public void setOpen(boolean isOpen) { this.isOpen = isOpen; } /** * Checks if its mini bounding area intersects the line determined by the given start and end points * * @param endPoint * end point of the line * @param startPoint * start point of the line * @return true if it intersects. Otherwise, false. */ public boolean miniBAIntersects2DLine(Vector3f endPoint, Vector3f startPoint) { return boundingArea.intersects(new GeometryFactory().createLineString(new Coordinate[] {new Coordinate(endPoint.x, endPoint.z), new Coordinate(startPoint.x, startPoint.z)})); } }
To implement the “NeighborKnowledgeStorageObject” class:
- Create a new class inside the “external” package and name it “NeighborKnowledgeStorageObject”.
- Copy the code given below that describes the full implementation of a “NeighborKnowledgeStorageObject” class.
package edu.utdallas.mavs.evacuation.simulation.sim.agent.knowledge.external; import edu.utdallas.mavs.divas.core.sim.common.state.AgentState; /** * Agent Knowledge Storage Object - Stores critical information regarding agents. */ public class NeighborKnowledgeStorageObject extends AgentKnowledgeStorageObject { private static final long serialVersionUID = 1L; protected float distance; protected long cycle; public NeighborKnowledgeStorageObject(AgentState agent, float distance, long cycle) { super(agent); this.distance = distance; this.cycle = cycle; } public float getDistance() { return distance; } public void setDistance(float distance) { this.distance = distance; } public long getCycle() { return cycle; } }
To implement the “VisionModel” class:
- Create a new class inside the “external” package and name it “VisionModel”.
- Copy the code given below that describes the full implementation of a “VisionModel” class.
package edu.utdallas.mavs.evacuation.simulation.sim.agent.knowledge.external; import java.io.Serializable; /** * Store information about something (anything) that is visible. */ public class VisionModel implements Serializable { /** * Serializer ID */ private static final long serialVersionUID = 1L; /** * The type of the thing that is visible. */ String type; /** * The ID of the visible thing. */ int id; /** * Indicates how visible the thing is that is visible. */ double visibility; // 1 = 100%, 0 = 0% vision quality /** * Create a new visible thing. * * @param id * the id * @param type * the type */ public VisionModel(int id, String type) { this.type = type; this.id = id; this.visibility = 1; // default is perfect visibility } /** * Set the visible quality * * @param visibility * the visible quality */ public void setVisionQuality(double visibility) { this.visibility = visibility; } /** * Get the type * * @return the type */ public String getType() { return type; } /** * Set the type * * @param type * the type */ public void setType(String type) { this.type = type; } /** * Get the ID * * @return The ID */ public int getId() { return id; } /** * Set the ID * * @param id * the ID */ public void setId(int id) { this.id = id; } /** * Get the visibility * * @return the visibility */ public double getVisibility() { return visibility; } }
4. Implementing the “EvacuationHumanKnowledgeModule” class
In “knowledge package”, create “EvacuationHumanKnowledgeModule” class.
To implement the “EvacuationHumanKnowledgeModule” class:
package edu.utdallas.mavs.evacuation.simulation.sim.agent.knowledge; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Random; import com.jme3.math.FastMath; import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; import edu.utdallas.mavs.divas.core.sim.agent.interaction.perception.data.CombinedReasonedData; import edu.utdallas.mavs.divas.core.sim.agent.knowledge.HumanKnowledgeModule; import edu.utdallas.mavs.divas.core.sim.agent.knowledge.external.EventKnowledge; import edu.utdallas.mavs.divas.core.sim.agent.knowledge.external.EventPropertyKnowledge; import edu.utdallas.mavs.divas.core.sim.agent.knowledge.internal.Goal; import edu.utdallas.mavs.divas.core.sim.common.event.EventProperty.Sense; import edu.utdallas.mavs.divas.core.sim.common.state.AgentState; import edu.utdallas.mavs.divas.core.sim.common.state.EnvObjectState; import edu.utdallas.mavs.divas.utils.collections.BoundedPrioritySet; import edu.utdallas.mavs.divas.utils.collections.LightWeightBoundedMap; import edu.utdallas.mavs.evacuation.simulation.sim.agent.knowledge.external.AgentKnowledgeStorageObject; import edu.utdallas.mavs.evacuation.simulation.sim.agent.knowledge.external.EnvObjectKnowledgeStorageObject; import edu.utdallas.mavs.evacuation.simulation.sim.agent.knowledge.external.NeighborKnowledgeStorageObject; import edu.utdallas.mavs.evacuation.simulation.sim.agent.knowledge.external.VisionModel; import edu.utdallas.mavs.evacuation.simulation.sim.agent.knowledge.ontology.Door; import edu.utdallas.mavs.evacuation.simulation.sim.agent.planning.AgentPath; import edu.utdallas.mavs.evacuation.simulation.sim.agent.planning.RVOObstacle; import edu.utdallas.mavs.evacuation.simulation.sim.agent.planning.RVO_Utils; import edu.utdallas.mavs.evacuation.simulation.sim.common.state.EHumanAgentState; /** * The Agents Knowledge Module. Stores all agent knowledge. */ public class EvacuationHumanKnowledgeModule extends HumanKnowledgeModule<EHumanAgentState> { protected static final int MAX_AGENT = 100; protected static final int MAX_ENV_OBJ = 600; private static final int MAX_NEIGHBOR_AGE = 5; private static final long serialVersionUID = 1L; private static final float NEAR_DISTANCE = 20; private static final int NEIGHBORS_COUNT = 30; private static final String DOOR = "door"; private Map<Integer, Door> doors; private Map<Integer, EnvObjectKnowledgeStorageObject> exitDoors = new LightWeightBoundedMap<Integer, EnvObjectKnowledgeStorageObject>(MAX_ENV_OBJ); private Map<Integer, EnvObjectKnowledgeStorageObject> importantObjects = new LightWeightBoundedMap<Integer, EnvObjectKnowledgeStorageObject>(MAX_ENV_OBJ); private BoundedPrioritySet<NeighborKnowledgeStorageObject> nearbyAgents = new BoundedPrioritySet<>(NEIGHBORS_COUNT, new DistanceComparator()); private List<String> dangerousEvents; private List<EnvObjectKnowledgeStorageObject> wallsInCurrentRoom = new ArrayList<EnvObjectKnowledgeStorageObject>(); // private List<Door> nearbyDoors; private Map<Integer, EnvObjectKnowledgeStorageObject> doorObjs = new LightWeightBoundedMap<Integer, EnvObjectKnowledgeStorageObject>(MAX_ENV_OBJ * 2); private Map<Integer, EnvObjectKnowledgeStorageObject> wallObjs = new LightWeightBoundedMap<Integer, EnvObjectKnowledgeStorageObject>(MAX_ENV_OBJ); private List<Goal> goals; private Goal searchGoal = null; private Goal unStuckGoal = null; private Goal currentGoal = null; private Goal reactGoal = null; private Door goalDoor = new Door(-1); private Vector3f savedPos = new Vector3f(); private Vector3f goingDoorPos = new Vector3f(); private Vector3f treatDirection = null; private Vector3f stuckPos = new Vector3f(); private Vector3f explorePos = null; private Vector3f finalGoalPos = null; private boolean wantToMove = false; private boolean agentIsStuck = false; private boolean inroom = false; private boolean noDoors = false; private boolean searchingDoor = false; private boolean inNewRoom = true; private boolean finishedExploring = false; private boolean getSafe = false; private boolean insideDoor = false; private boolean localizedSelf = false; private boolean sirenHeard = false; private boolean waiting = false; private boolean sirenOn = false; private int waitingTime = 0; private int exploringTime = 0; private int localizationTime = 30; private int stuckCount = 0; private int panicTime; private int checkingRoomNumber = 0; private int timeOnCurrentLegOfPath = 0; private int pathLegThreshold = 250; long obsCalculatedCycle = -1; public float desiredSpeed = 0; private float patience; private AgentPath agentPath; private MentalStateOfAgent currentMentalState = MentalStateOfAgent.IDLE; List<RVOObstacle> obs; protected Map<Integer, EnvObjectKnowledgeStorageObject> envObjs; protected Map<Integer, AgentKnowledgeStorageObject> agents; protected ArrayList<EnvObjectKnowledgeStorageObject> newEnvObjs; /** * Event Knowledge Storage */ protected Map<String, EventKnowledge> evk; protected ArrayList<CombinedReasonedData> eventsPerceivedThisTick; protected Map<Integer, VisionModel> visibleList; public enum MentalStateOfAgent { EXITED_BUILDING, EXPLORING_AREA, GOING_DOOR, FLEEING, IDLE, SAFE, PERSUING_USER_GOAL, ARRIVED_IN_ROOM, STUCK, ENTERING_NEW_ROOM, ARRIVED, NEED_NEW_PATH, ARRIVED_AT_EXIT, GOING_TO_SAFETY, EXITING_BUILDING } public List<Goal> getGoals() { return goals; } public EvacuationHumanKnowledgeModule(EHumanAgentState state) { super(state); this.envObjs = new LightWeightBoundedMap<Integer, EnvObjectKnowledgeStorageObject>(MAX_ENV_OBJ); this.newEnvObjs = new ArrayList<EnvObjectKnowledgeStorageObject>(); this.agents = new LightWeightBoundedMap<Integer, AgentKnowledgeStorageObject>(MAX_AGENT); this.eventsPerceivedThisTick = new ArrayList<CombinedReasonedData>(); this.visibleList = new HashMap<Integer, VisionModel>(); doors = new LightWeightBoundedMap<Integer, Door>(MAX_ENV_OBJ * 2); dangerousEvents = new ArrayList<>(); // nearbyDoors = new ArrayList<>(); cycle = 0; goals = new ArrayList<>(); populateEventKnowledge(); obs = new ArrayList<>(); agentPath = new AgentPath(); Random r = new Random(); patience = r.nextFloat(); if(patience < .2f) { patience = .2f; } if(patience > .9f) { patience = .9f; } } public Door findDoor(int doorID) { return doors.get(doorID); } public Door addDoor(int doorID) { if(doors.get(doorID) == null) { Door d = new Door(doorID); doors.put(doorID, d); return d; } return null; } public Door getDoor(int id) { return doors.get(id); } public Collection<Door> getDoors() { return doors.values(); } public Map<Integer, Door> getDoorsMap() { return doors; } private void populateEventKnowledge() { evk = new HashMap<String, EventKnowledge>(); EventKnowledge tempek = new EventKnowledge("Bomb"); tempek.addEventPropertyKnowledge(new EventPropertyKnowledge("flash", Sense.Vision, 40, 200)); tempek.addEventPropertyKnowledge(new EventPropertyKnowledge("fire", Sense.Vision, 20, 40)); tempek.addEventPropertyKnowledge(new EventPropertyKnowledge("boom", Sense.Hearing, 50, 160)); tempek.addEventPropertyKnowledge(new EventPropertyKnowledge("smoke", Sense.Smell, 20, 100)); evk.put(tempek.getName(), tempek); tempek = new EventKnowledge("Firework"); tempek.addEventPropertyKnowledge(new EventPropertyKnowledge("flash", Sense.Vision, 20, 50)); tempek.addEventPropertyKnowledge(new EventPropertyKnowledge("colors", Sense.Vision, 40, 100)); tempek.addEventPropertyKnowledge(new EventPropertyKnowledge("boom", Sense.Hearing, 40, 120)); tempek.addEventPropertyKnowledge(new EventPropertyKnowledge("smoke", Sense.Smell, 5, 40)); evk.put(tempek.getName(), tempek); tempek = new EventKnowledge("GrillingFood"); tempek.addEventPropertyKnowledge(new EventPropertyKnowledge("grill", Sense.Vision, 1, 1)); tempek.addEventPropertyKnowledge(new EventPropertyKnowledge("sizzle", Sense.Hearing, 5, 20)); tempek.addEventPropertyKnowledge(new EventPropertyKnowledge("smoke", Sense.Smell, 3, 45)); evk.put(tempek.getName(), tempek); tempek = new EventKnowledge("Drums"); tempek.addEventPropertyKnowledge(new EventPropertyKnowledge("drums", Sense.Vision, 1, 1)); tempek.addEventPropertyKnowledge(new EventPropertyKnowledge("boom", Sense.Hearing, 10, 70)); evk.put(tempek.getName(), tempek); tempek = new EventKnowledge("Spotlight"); tempek.addEventPropertyKnowledge(new EventPropertyKnowledge("flash", Sense.Vision, 20, 80)); evk.put(tempek.getName(), tempek); tempek = new EventKnowledge("Siren"); tempek.addEventPropertyKnowledge(new EventPropertyKnowledge("siren", Sense.Hearing, 70, 140)); evk.put(tempek.getName(), tempek); dangerousEvents.add("Bomb"); } public boolean isSearchingDoor() { return searchingDoor; } public void setSearchingDoor(boolean searchingDoor) { this.searchingDoor = searchingDoor; } public boolean isLocalizedSelf() { return localizedSelf; } public void setLocalizedSelf(boolean localizedSelf) { this.localizedSelf = localizedSelf; } public List<EnvObjectKnowledgeStorageObject> getWallsInCurrentRoom() { return wallsInCurrentRoom; } public boolean isInNewRoom() { return inNewRoom; } public boolean isInsideDoor() { return insideDoor; } public void setInsideDoor(boolean insideDoor) { this.insideDoor = insideDoor; } public void setInNewRoom(boolean inNewRoom) { this.inNewRoom = inNewRoom; } public void setWallsInCurrentRoom(List<EnvObjectKnowledgeStorageObject> wallsInCurrentRoom) { this.wallsInCurrentRoom = wallsInCurrentRoom; } public boolean isWantToMove() { return wantToMove; } public void setWantToMove(boolean wantToMove) { this.wantToMove = wantToMove; } public boolean isAgentIsStuck() { return agentIsStuck; } public void setAgentIsStuck(boolean agentIsStuck) { this.agentIsStuck = agentIsStuck; } public boolean isInroom() { return inroom; } public void setInroom(boolean inroom) { this.inroom = inroom; } public Goal getSearchGoal() { return searchGoal; } public void setSearchGoal(Goal searchGoal) { this.searchGoal = searchGoal; } public boolean isNoDoors() { return noDoors; } public void setNoDoors(boolean noDoors) { this.noDoors = noDoors; } public int getCheckingRoomNumber() { return checkingRoomNumber; } public void setCheckingRoomNumber(int checkingRoomNumber) { this.checkingRoomNumber = checkingRoomNumber; } public Vector3f getSavedPos() { return savedPos; } public void setSavedPos(Vector3f savedPos) { this.savedPos = savedPos; } public Vector3f getGoingDoorPos() { return goingDoorPos; } public void setGoingDoorPos(Vector3f goingDoorPos) { this.goingDoorPos = goingDoorPos; } public Goal getUnStuckGoal() { return unStuckGoal; } public void setUnStuckGoal(Goal unStuckGoal) { this.unStuckGoal = unStuckGoal; } public Goal getCurrentGoal() { return currentGoal; } public void setCurrentGoal(Goal currentGoal) { this.currentGoal = currentGoal; } public int getExploringTime() { return exploringTime; } public void resetExploringTime() { exploringTime = 0; } public void incrementExploringTime() { exploringTime++; } public boolean isFinishedExploring() { return finishedExploring; } public void setFinishedExploring(boolean finishedExploring) { this.finishedExploring = finishedExploring; } public int getPanicTime() { return panicTime; } public void setPanicTime(int panicTime) { this.panicTime = panicTime; } public Vector3f getThreatDirection() { return treatDirection; } public void setThreatDirection(Vector3f treatDirection) { this.treatDirection = treatDirection; } protected void updateNearbyAgents(AgentState agent) { float distance = self.getPosition().distance(agent.getPosition()); if(distance < NEAR_DISTANCE && agent.getID() != self.getID()) { nearbyAgents.add(new NeighborKnowledgeStorageObject(agent, distance, getTime())); } /* * if(nearbyAgents.size() > NEIGHBORS_COUNT) * { * System.out.println(nearbyAgents.size() + " ####################################################################################"); * } */ } public void cleanNearbyAgents() { Iterator<NeighborKnowledgeStorageObject> it = nearbyAgents.values().iterator(); while(it.hasNext()) { NeighborKnowledgeStorageObject n = it.next(); if((getTime() - n.getCycle()) > MAX_NEIGHBOR_AGE) { it.remove(); } else if(n.getCycle() != getTime()) { n.setPosition(n.getPosition().add(n.getVelocity())); n.setDistance(self.getPosition().distance(n.getPosition())); if(n.getDistance() > NEAR_DISTANCE) { it.remove(); } } } } public BoundedPrioritySet<NeighborKnowledgeStorageObject> getNearbyAgents() { // for(NeighborKnowledgeStorageObject n : nearbyAgents.values()) // { // System.out.println("AgentID: " + getId() + " NEIGHBORID: " + n.getID() + " DISTANCE: " + n.getDistance()); // } return nearbyAgents; } public float getNearDistance() { return NEAR_DISTANCE; } public boolean isEventDangerous(String event) { if(dangerousEvents.contains(event)) { return true; } return false; } public List<RVOObstacle> getPerceivedRVOObstacles() { if(obsCalculatedCycle < getTime()) { obs.clear(); obsCalculatedCycle = getTime(); for(EnvObjectKnowledgeStorageObject obj : envObjs.values()) { if(obj.isCollidable()) { if(obj.getPosition().distance(self.getPosition()) - FastMath.sqrt(obj.getScale().getX() * obj.getScale().getX() + obj.getScale().getZ() * obj.getScale().getZ()) < 30) { if(!obj.getType().equals(DOOR)) { Vector2f pospos = new Vector2f(obj.getScale().x, obj.getScale().z); Vector2f posneg = new Vector2f(obj.getScale().x, -obj.getScale().z); Vector2f negpos = new Vector2f(-obj.getScale().x, obj.getScale().z); Vector2f negneg = new Vector2f(-obj.getScale().x, -obj.getScale().z); // outside RVOObstacle obs1 = new RVOObstacle(obj.getPosition2D().add(pospos)); RVOObstacle obs2 = new RVOObstacle(obj.getPosition2D().add(negpos)); RVOObstacle obs3 = new RVOObstacle(obj.getPosition2D().add(negneg)); RVOObstacle obs4 = new RVOObstacle(obj.getPosition2D().add(posneg)); // inside // RVOObstacle obs1 = new RVOObstacle(obj.getPosition2D().add(pospos)); // RVOObstacle obs2 = new RVOObstacle(obj.getPosition2D().add(posneg)); // RVOObstacle obs3 = new RVOObstacle(obj.getPosition2D().add(negneg)); // RVOObstacle obs4 = new RVOObstacle(obj.getPosition2D().add(negpos)); obs1.setID(obj.getID()); obs2.setID(obj.getID()); obs3.setID(obj.getID()); obs4.setID(obj.getID()); obs1.setNextObstacle(obs2); obs2.setNextObstacle(obs3); obs3.setNextObstacle(obs4); obs4.setNextObstacle(obs1); obs1.setPrevObstacle(obs4); obs2.setPrevObstacle(obs1); obs3.setPrevObstacle(obs2); obs4.setPrevObstacle(obs3); obs1.updateUnitVector(); obs2.updateUnitVector(); obs3.updateUnitVector(); obs4.updateUnitVector(); obs.add(obs1); obs.add(obs2); obs.add(obs3); obs.add(obs4); // RVOObstacle obs5 = new RVOObstacle(obj.getPosition2D().add(pospos)); // RVOObstacle obs6 = new RVOObstacle(obj.getPosition2D().add(negpos)); // obs5.setNextObstacle(obs6); // obs6.setNextObstacle(obs5); // obs5.setPrevObstacle(obs6); // obs6.setPrevObstacle(obs5); // obs5.updateUnitVector(); // obs6.updateUnitVector(); // obs.add(obs5); // obs.add(obs6); for(RVOObstacle rvoObstacle : obs) { // rvoObstacle.setDistance(rvoObstacle.getPoint().distance(self.getPosition2D())); rvoObstacle.setDistance(RVO_Utils.calcDistanceToLineSegment(rvoObstacle.getPoint(), rvoObstacle.getNextObstacle().getPoint(), self.getPosition2D())); } Collections.sort(obs); // for(RVOObstacle rvoObstacle : obs) // { // System.out.println("dist: " + rvoObstacle.getDistance()); // } // for(RVOObstacle rvoObstacle : obs) // { // System.out.println(RVO_Utils.leftOf(rvoObstacle.getPrevObstacle().getPoint(), rvoObstacle.getPoint(), rvoObstacle.getNextObstacle().getPoint())); // } // obs.add(new RVOObstacle(obj.getPosition2D().add(pospos), obj.getPosition2D().add(negpos))); // obs.add(new RVOObstacle(obj.getPosition2D().add(negpos), obj.getPosition2D().add(negneg))); // obs.add(new RVOObstacle(obj.getPosition2D().add(negneg), obj.getPosition2D().add(posneg))); // obs.add(new RVOObstacle(obj.getPosition2D().add(posneg), obj.getPosition2D().add(pospos))); } } } } } return obs; } class DistanceComparator implements Comparator<NeighborKnowledgeStorageObject>, Serializable { private static final long serialVersionUID = 1L; @Override public int compare(NeighborKnowledgeStorageObject arg0, NeighborKnowledgeStorageObject arg1) { Float f0 = arg0.getDistance(); Float f1 = arg1.getDistance(); return -f0.compareTo(f1); } } public Goal getReactGoal() { return reactGoal; } public void setReactGoal(Goal reactGoal) { this.reactGoal = reactGoal; } // public void addNearbyDoor(Door d) // { // nearbyDoors.add(d); // } // // public void clearNearbyDoor() // { // nearbyDoors.clear(); // } // // public List<Door> getNearbyDoors() // { // return nearbyDoors; // } public Door getGoalDoor() { return goalDoor; } public void setGoalDoor(Door goalDoor) { this.goalDoor = goalDoor; } public MentalStateOfAgent getCurrentMentalState() { return currentMentalState; } public void setCurrentMentalState(MentalStateOfAgent newState) { // System.out.println("Changing state from: " + currentMentalState + " to: " + newState); currentMentalState = newState; } public int getLocalizationTime() { return localizationTime; } public void setLocalizationTime(int localizationTime) { this.localizationTime = localizationTime; } public Map<Integer, EnvObjectKnowledgeStorageObject> getExitDoors() { return exitDoors; } public void setExitDoors(Map<Integer, EnvObjectKnowledgeStorageObject> exitDoors) { this.exitDoors = exitDoors; } public void addExitDoor(EnvObjectKnowledgeStorageObject exitDoor) { exitDoors.put(exitDoor.getID(), exitDoor); } public EnvObjectKnowledgeStorageObject getExitDoor(int id) { return exitDoors.get(id); } // <<<<<<< .working public boolean isGetSafe() { return getSafe; } public void setGetSafe(boolean getSafe) { this.getSafe = getSafe; } public EnvObjectKnowledgeStorageObject getImportantObject(int id) { return importantObjects.get(id); } public void addImportantObject(EnvObjectKnowledgeStorageObject importantObject) { importantObjects.put(importantObject.getID(), importantObject); } public void removeImportantObject(EnvObjectKnowledgeStorageObject importantObject) { importantObjects.remove(importantObject.getID()); } public void clearImportantObjects() { importantObjects.clear(); } public Vector3f getStuckPos() { return stuckPos; } public void setStuckPos(Vector3f stuckPos) { this.stuckPos = stuckPos; } public int getStuckCount() { return stuckCount; } public void incrementStuckCount() { stuckCount++; } public void resetStuckCount() { stuckCount = 0; } public int getTimeOnCurrentLegOfPath() { return timeOnCurrentLegOfPath; } public void incrementTimeOnCurrentLegOfPath() { timeOnCurrentLegOfPath++; } public void resetTimeOnCurrentLegOfPath() { timeOnCurrentLegOfPath = 0; } public int getPathLegThreshold() { return pathLegThreshold; } public Vector3f getExplorePos() { return explorePos; } public void setExplorePos(Vector3f explorePos) { this.explorePos = explorePos; } public AgentPath getAgentPath() { return agentPath; } public void setAgentPath(AgentPath agentPath) { this.agentPath = agentPath; } public EnvObjectKnowledgeStorageObject getDoorObj(int i) { return doorObjs.get(i); } public EnvObjectKnowledgeStorageObject getWallObj(int i) { return wallObjs.get(i); } public void addDoorObj(EnvObjectKnowledgeStorageObject obj) { doorObjs.put(obj.getID(), obj); } public void addWallObj(EnvObjectKnowledgeStorageObject obj) { wallObjs.put(obj.getID(), obj); } public EnvObjectKnowledgeStorageObject findEnvObj(int envObjID) { EnvObjectKnowledgeStorageObject returnObj = envObjs.get(envObjID); if(returnObj == null) { returnObj = doorObjs.get(envObjID); } if(returnObj == null) { returnObj = wallObjs.get(envObjID); } return returnObj; } public boolean isSirenHeard() { return sirenHeard; } public void setSirenHeard(boolean sirenHeard) { this.sirenHeard = sirenHeard; } public boolean isWaiting() { return waiting; } public void setWaiting(boolean waiting) { this.waiting = waiting; } public int getWaitingTime() { return waitingTime; } public void setWaitingTime(int waitingTime) { this.waitingTime = waitingTime; } public float getPatience() { return patience; } public void setPatience(float patience) { this.patience = patience; } public boolean isSirenOn() { return sirenOn; } public void setSirenOn(boolean sirenOn) { this.sirenOn = sirenOn; } public Vector3f getFinalGoalPos() { return finalGoalPos; } public void setFinalGoalPos(Vector3f finalGoalPos) { this.finalGoalPos = finalGoalPos; } // ======= /** * @param obj */ @Override public void addEnvObj(EnvObjectState obj) { EnvObjectKnowledgeStorageObject envobjKSO = envObjs.get(obj.getID()); if(envobjKSO != null) { if(envobjKSO.updateValues(obj)) { newEnvObjs.add(envobjKSO); } } else { envobjKSO = new EnvObjectKnowledgeStorageObject(obj); envObjs.put(obj.getID(), envobjKSO); newEnvObjs.add(envobjKSO); } addElementToVisionList(obj.getID(), "envObject"); } /** * @param agent */ @Override public void addAgent(AgentState agent) { AgentKnowledgeStorageObject agentKSO = agents.get(agent.getID()); if(agentKSO != null) { agentKSO.updateValues(agent); } else { agents.put(agent.getID(), new AgentKnowledgeStorageObject(agent)); } updateNearbyAgents(agent); addElementToVisionList(agent.getID(), "agent"); } // public EnvObjectKnowledgeStorageObject findEnvObj(int envObjID) // { // return envObjs.get(envObjID); // } public EnvObjectKnowledgeStorageObject findEnvObj(String description) { // prevent concurrent modification of knownNodes for(EnvObjectKnowledgeStorageObject envObjModel : envObjs.values()) if(envObjModel.getDescription().equals(description)) return envObjModel; return null; } public AgentKnowledgeStorageObject findAgent(int agentID) { return agents.get(agentID); } public List<EnvObjectKnowledgeStorageObject> getEnvObjects() { return new ArrayList<EnvObjectKnowledgeStorageObject>(envObjs.values()); } public Map<Integer, EnvObjectKnowledgeStorageObject> getEnvObjectsMap() { return envObjs; } public List<EnvObjectKnowledgeStorageObject> getNewEnvObjs() { return newEnvObjs; } @Override public List<EventPropertyKnowledge> getEventKnowledgeFromType(String type) { ArrayList<EventPropertyKnowledge> returnData = new ArrayList<EventPropertyKnowledge>(); Iterator<EventKnowledge> evkIter = evk.values().iterator(); while(evkIter.hasNext()) { EventKnowledge tempevk = evkIter.next(); EventPropertyKnowledge tempepk = tempevk.getEventProperty(type); if(tempepk != null) { tempepk.setEventName(tempevk.getName()); returnData.add(tempepk); } } return returnData; } @Override public EventKnowledge getEventKnowledgeByName(String name) { return evk.get(name); } @Override public List<CombinedReasonedData> getEventsThisTick() { return eventsPerceivedThisTick; } @Override public void addEventsThisTick(CombinedReasonedData crd) { eventsPerceivedThisTick.add(crd); } public List<VisionModel> getVisibleList() { return new ArrayList<VisionModel>(visibleList.values()); } public void addElementToVisionList(int id, String type) { visibleList.put(id, new VisionModel(id, type)); } @Override public void clearPerceptionKnowledge() { eventsPerceivedThisTick.clear(); visibleList.clear(); newEnvObjs.clear(); } public Collection<AgentKnowledgeStorageObject> getAgents() { return agents.values(); } }
Note: EnvObjectKnowledgeStorageObject and EvacuationHumanKnowledgeModule are expected to throw error message pending creation of planning package and the classes in item 2.4.3.5