package Agents; import Agents.Attributes.VehicleAttributes; import Agents.Behaviour.CompositeBehaviour; import Agents.Behaviour.VehicleMoveBehaviour; import Database.Sql; import Entity.Disaster; import GeographicInformation.Cell; import GeographicInformation.Location; import GlobalData.Constants; import Utilities.AIDGenerator; import java.util.ArrayList; import org.postgis.Point; /** * Vehicle agent class for the simulation * This class decribes the characteristic of a Vehicle Agent. * Each vehicle is expected to have a capacity to carry a certain amount of load * in terms of people (Person Agents). */ public class Vehicle extends Agent { /** * The attributes of a Vehicle agent. * @see VehicleAttributes */ protected VehicleAttributes attributes = null; /** * Initilizes Vehicle Object * @param mycap The capacity of the vehicle. * @param curload The current load on the vehicle. * @param home The home base of the vehicle. * @param curloc The current location of the vehicle. * @param spd The current speed with which the vehicle moves. * @param type The type of vehicle. * @param startcellId * @param homebaseId * @throws InstantiationException Agentattribution initialization error */ public Vehicle(int mycap, int curload, Location home, Cell curloc, int spd, String type, long startcellId, long homebaseId) throws InstantiationException { attributes = new VehicleAttributes(type, mycap, spd, home, curloc, new ArrayList<Cell>()); attributes.currentLoad = curload; attributes.CAPACITY = mycap; attributes.homeBase = home; attributes.currentCellLocation = curloc; attributes.SPEED = spd; attributes.homeBaseId = homebaseId; attributes.startCellId = startcellId; AID = AIDGenerator.newID(getClass().toString().substring(6)); behaviour = new CompositeBehaviour(); behaviour.add(new VehicleMoveBehaviour()); getBestPath(); //THis call has to return true or the vehicle cannot be spwaned. //attributes.currentCellLocation.updateOccupiedFlagInDB(true); } /** * Returns the Vehicle's attributes * @return Vehicle agent attributes */ public VehicleAttributes getAttributes() { return attributes; } /** * Set the Vehicle's attributes * @param attributes Vehicle's attributes */ public void setAttributes(VehicleAttributes attributes) { this.attributes = attributes; } /** * Returns the best path between any two given locations * @param startPoint start location * @param endPoint destination * @param costColumn cost set to use to evaluate the best path * @param cellsTable the set of cells to use to form the path */ public void getBestPath(Point startPoint, Point endPoint, String costColumn, String cellsTable) { this.attributes.currentCellIndex = 0; this.attributes.bestRouteToHome = Sql.getBestPathForPerson(startPoint, endPoint, costColumn, cellsTable); } /** * Returns the best path between any two given locations * @param startPoint start location * @param endPointId destination * @param costColumn cost set to use to evaluate the best path * @param cellsTable the set of cells to use to form the path */ public void getBestPath(Point startPoint, long endPointId, String costColumn, String cellsTable) { this.attributes.currentCellIndex = 0; this.attributes.bestRouteToHome = Sql.getBestPathForPerson(startPoint, endPointId, costColumn, cellsTable); } /** * Returns the best path based on the start cell and home base of the agent */ public void getBestPath() { this.attributes.currentCellIndex = 0; this.attributes.bestRouteToHome = Sql.getBestPathForPerson(attributes.startCellId, attributes.homeBaseId, Constants.COST_COLUMN_REGULAR_VEHICLE, Constants.TABLE_VEHICLE_CELLS); } /** * This method performs the necessary state changes and processes the given * disaster. This methods makes the agent aware of a disaster * @param disaster the disaster that has taken place */ private void processDisaster(Disaster disaster) { if (this.attributes.isHome()) { return; } getBestPath(this.attributes.currentCellLocation.getLatLon(), this.attributes.homeBaseId, Constants.COST_COLUMN_REGULAR_VEHICLE, Constants.TABLE_VEHICLE_CELLS); } /** * This method is called to notify the agent about a disaster * @param disaster the disaster that has taken place */ public void notifyDisaster(Disaster disaster) { processDisaster(disaster); } /** * Return the current load of the vehicle. * @return the current load on the vehicle. */ public int getCurrentLoad() { return this.attributes.currentLoad; } /** * Sets the curent load of the vehicle. * @param currentLoad Current load of the vehicle. */ public void setCurrentLoad(int currentLoad) { this.attributes.currentLoad = currentLoad; } /** * Check if the vehicle agent is home. * @return boolean true if the vehicle agent is home. */ public boolean isHome() { return this.isHome(); } /** * Set the home status flag for vehicle agent. * @param isHome */ public void setIsHome(boolean isHome) { this.attributes.setIsHome(isHome); } /** * Return the home base of the vehicle. * @return home base of the vehicle */ public Location getHomeBase() { return attributes.homeBase; } /** * Set the home base of the vehicle. * @param homeBase home base of the vehicle. */ public void setHomeBase(Location homeBase) { this.attributes.homeBase = homeBase; } /** * String representation of vehicle agent object. * @return String represeantation of vehicle */ @Override public String toString() { return "ID: " + AID + " Class: " + getClass().toString() + " Type: " + attributes.TYPE + " Maximum Capacity: " + attributes.CAPACITY + " Current Load: " + attributes.currentLoad + " Speed: " + attributes.SPEED; } /** * Compare two vehicles, return true if their IDs are equal. * @param obj * @return true if vehicle ids are equal. */ @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final Vehicle other = (Vehicle) obj; if (this.AID.equals(other.AID)) { return true; } return false; } /** * Return hashCode of the vehicle agent object * @return hashCode of the vehicle agent object */ @Override public int hashCode() { throw new UnsupportedOperationException("Can't create a vehicle without any attributes"); } /** * Check if a vehicle agent is home. Since the speed of the vehicle agents * is not constant, the step size is multiplied with the agent's speed * before checking if they are home. * @return whether the agent is home or not */ protected boolean isHomeStatus() { if (attributes.currentCellIndex < attributes.bestRouteToHome.size() - 1) { return false; } else { attributes.currentCellLocation.updateOccupiedFlagInDB(false); return true; } } /** * The run method. The run method for vehicles will depend on the type of vehicle. */ @Override public void run() { if (!statusFlag) { this.attributes.isAgentHome = isHomeStatus(); if (!this.attributes.isAgentHome) { behaviour.run(attributes); } else { objectiveFlag = true; } statusFlag = true;//Function call done } } /** * Queries the GIS database for the shortest route * NOTE THE FUNCTION IS INCOMPLETE: The location is a laton and * the corresponding cell has to be searched. * @return current location of the Vehicle */ public Point getCurrentLocation() { return attributes.currentCellLocation.getLatLon(); } /** * Set the current location of the vehicle agent * @param location current location of the Vehicle */ public void setCurrentLocation(Point location) { attributes.currentCellLocation.setLatLon(location); } }