001 /** 002 * planningtool - A Planning Tool with Critiquing Support. 003 * 004 * Copyright (C) 2006 olale 005 006 * This program is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU General Public License 008 * as published by the Free Software Foundation; either version 2 009 * of the License, or (at your option) any later version. 010 011 * This program is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 016 * You should have received a copy of the GNU General Public License 017 * along with this program; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 019 020 * Contact information: 021 * E-mail: olale@ida.liu.se 022 * olale@lysator.liu.se 023 */ 024 package se.liu.ida.critiquer.simulation; 025 026 import java.awt.Graphics2D; 027 import java.text.DateFormat; 028 import java.util.ArrayList; 029 import java.util.Calendar; 030 import java.util.Collections; 031 import java.util.Comparator; 032 import java.util.HashMap; 033 import java.util.List; 034 035 import se.liu.ida.critiquer.activities.Activity; 036 import se.liu.ida.critiquer.activities.ActivityUtils; 037 import se.liu.ida.critiquer.activities.TransportationActivity; 038 import se.liu.ida.critiquer.gui.GeoView; 039 import se.liu.ida.critiquer.mics.Comparer; 040 import se.liu.ida.critiquer.mics.ReferenceHolder; 041 import se.liu.ida.critiquer.mics.Utils; 042 import se.liu.ida.critiquer.resources.Agent; 043 import se.liu.ida.critiquer.scenarios.standard.AgentParameterName; 044 045 /** 046 * @author olale 047 * 048 */ 049 public class DefaultAgentSimulationState implements AgentSimulationState { 050 051 /** 052 * 053 */ 054 public static final String FUEL_LEVEL = "fuel level"; 055 056 /** 057 * 058 */ 059 private static final long serialVersionUID = 1L; 060 061 private HashMap<String, Object> state = new HashMap<String, Object>(); 062 063 private Agent agent; 064 065 private SimulationEngine engine; 066 067 /** 068 * This is the list of all activities this agent participates in, sorted in 069 * temporal order 070 */ 071 private ArrayList<Activity> activitiesForAgent = new ArrayList<Activity>(); 072 073 /** 074 * This is the list of activities that have already been simulated 075 */ 076 private ArrayList<Activity> consumedActivities = new ArrayList<Activity>(); 077 078 /** 079 * 080 */ 081 public DefaultAgentSimulationState(Agent agent) { 082 this.agent = agent; 083 } 084 085 /* 086 * (non-Javadoc) 087 * 088 * @see se.liu.ida.critiquer.resources.AgentSimulationState#setPropertyMap(java.util.HashMap) 089 */ 090 091 public <T> void setProperty(String key, T value) { 092 state.put(key, value); 093 } 094 095 /* 096 * (non-Javadoc) 097 * 098 * @see se.liu.ida.critiquer.resources.AgentSimulationState#getProperty(java.lang.String, 099 * java.lang.Class) 100 */ 101 @SuppressWarnings("unchecked") 102 public <C> C getProperty(String name, Class<C> type) { 103 C returnValue = null; 104 if (state.containsKey(name)) { 105 Object value = state.get(name); 106 if (value.getClass() == type) { 107 returnValue = (C) value; 108 } 109 } 110 return returnValue; 111 112 } 113 114 /* 115 * (non-Javadoc) 116 * 117 * @see se.liu.ida.critiquer.resources.AgentSimulationState#renderState(se.liu.ida.critiquer.simulation.GeoView, 118 * java.awt.Graphics2D) 119 */ 120 public void renderState(GeoView view, Graphics2D g2) { 121 // TODO Auto-generated method stub 122 123 } 124 125 /** 126 * @see se.liu.ida.critiquer.simulation.AgentSimulationState#getAgent() 127 */ 128 public Agent getAgent() { 129 130 return agent; 131 } 132 133 /** 134 * 135 * Called every time the simulation engine starts a simulation 136 * 137 * @see se.liu.ida.critiquer.simulation.SimulationElement#initSimulation() 138 */ 139 public void initSimulation(SimulationEngine engine) { 140 this.engine=engine; 141 setProperties(); 142 activitiesForAgent = agent.getActivitiesForAgent(); 143 144 sortActivities(activitiesForAgent); 145 } 146 147 private void sortActivities(List<Activity> activities) { 148 Collections.sort(activities, new Comparator<Activity>() { 149 150 public int compare(Activity a1, Activity a2) { 151 Calendar t1 = ActivityUtils.getStartTimeParameter(a1).getValue(); 152 Calendar t2 = ActivityUtils.getStartTimeParameter(a2).getValue(); 153 return t1.compareTo(t2); 154 } 155 156 }); 157 } 158 159 /** 160 * 161 * Step forward or backwards in time to the absolute time <code>time</code> 162 * 163 * @param time 164 * the destination time 165 */ 166 public void stepTo(Calendar time) { 167 setProperties(); 168 ArrayList<Activity> activities = activitiesForAgent; 169 for (Activity activity : activities) { 170 Calendar endTime = ActivityUtils.getEndTimeParameter(activity).getValue(); 171 if (time.after(endTime)) { 172 consumeActivity(activity); 173 } else { 174 break; 175 } 176 } 177 } 178 179 /** 180 * 181 * Move forward in the simulation with the agent 182 * 183 * @see se.liu.ida.critiquer.simulation.SimulationElement#stepForward(int) 184 */ 185 public void stepForward(int step) { 186 Calendar nextTime = (Calendar) engine.getCurrentTime().clone(); 187 nextTime.add(Calendar.MINUTE, step); 188 stepTo(nextTime); 189 190 } 191 192 193 /** 194 * Set the properties that define this state. 195 * 196 */ 197 protected void setProperties() { 198 setProperty(FUEL_LEVEL, agent.getParamByClassAndName(Integer.class, AgentParameterName.FUEL_CAPACITY).getValue()); 199 //setProperty("time since rest", 0); 200 } 201 202 /** 203 * When <code>activity</code> has finished, calculate how properties are 204 * modified 205 * 206 * @param activity 207 */ 208 protected void consumeActivity(Activity activity) { 209 if (activity instanceof TransportationActivity) { 210 TransportationActivity transportActivity = (TransportationActivity) activity; 211 // distance in meters 212 double distanceInPixels = transportActivity.getStart().distanceTo(transportActivity.getEnd()); 213 // Distance in 100 kilometers 214 double distance = ReferenceHolder.simulationView.getScale()*distanceInPixels/100000; 215 // fuel consumption in liters per 100 kilometers 216 Integer fuelConsumption = getAgent().getParamByClassAndName(Integer.class, AgentParameterName.FUEL_CONSUMPTION).getValue(); 217 Integer fuelLevel = getProperty(FUEL_LEVEL, Integer.class); 218 219 int newFuelLevel = (int) (fuelLevel-fuelConsumption*distance); 220 System.out.println("New fuel level: "+newFuelLevel); 221 setProperty(FUEL_LEVEL,new Integer(newFuelLevel)); 222 223 224 } 225 } 226 227 /** 228 * @see se.liu.ida.critiquer.simulation.SimulationElement#stepBackward(int) 229 */ 230 public void stepBackward(int step) { 231 Calendar previousTime = (Calendar) engine.getCurrentTime().clone(); 232 previousTime.add(Calendar.MINUTE, step); 233 stepTo(previousTime); 234 } 235 236 }