Changeset 187 in tmcsimulator for trunk/src/tmcsim/cadsimulator/managers/TrafficModelManager.java
- Timestamp:
- 10/29/2017 12:56:40 PM (9 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/tmcsim/cadsimulator/managers/TrafficModelManager.java
r2 r187 1 1 package tmcsim.cadsimulator.managers; 2 2 3 import atmsdriver.ConsoleTrafficDriver; 4 import atmsdriver.model.Highways; 5 import atmsdriver.model.LoopDetector; 6 import atmsdriver.model.TrafficEvent; 7 import java.awt.event.ActionEvent; 8 import java.awt.event.ActionListener; 3 9 import java.io.FileInputStream; 10 import java.io.FileNotFoundException; 4 11 import java.rmi.RemoteException; 12 import java.text.ParseException; 13 import java.text.SimpleDateFormat; 14 import java.util.ArrayList; 15 import java.util.Collections; 16 import java.util.Date; 17 import java.util.HashMap; 18 import java.util.LinkedList; 19 import java.util.List; 20 import java.util.Map; 21 import java.util.Observable; 5 22 import java.util.Properties; 23 import java.util.Scanner; 24 import java.util.concurrent.TimeUnit; 6 25 import java.util.logging.Level; 7 26 import java.util.logging.Logger; 8 9 import tmcsim.cadsimulator.stillimagecontrol.ATMSCommunicator; 27 import javax.swing.JOptionPane; 28 import javax.swing.Timer; 29 import tmcsim.cadsimulator.Coordinator; 30 import tmcsim.client.ATMSBatchDriver; 31 import tmcsim.client.ATMSBatchViewer; 32 import tmcsim.common.SimulationException; 10 33 11 34 /** 12 * ATMSManager is a CAD Simulator Manager used to handle all 13 * communication between the CAD Simulator and the ATMS server. 14 * Upon construction, the ATMSCommunicator is initialized with 15 * information from the properties file. This Object is used 16 * to perform the specific communication functions to send and 17 * receive data to/from the ATMS server. Methods in this 18 * Manager allow for the current ATMS server time to be queried 19 * and still images to be updated for display to ATMS clients. 20 * 21 * @author Matthew Cechini 22 * @version 35 * Traffic Model Manager is a model and controller for the Traffic Model 36 * used in the simulation. It represents all the highways and traffic 37 * events that occur. 38 * @author jdalbey 39 * @version 2.0 23 40 */ 24 public class ATMSManager { 25 26 /** Error Logger. */ 27 private static Logger atmsLogger = Logger.getLogger("tmcsim.cadsimulator.managers"); 41 public class TrafficModelManager extends Observable 42 { 43 private final static int ONE_SECOND = 1000; 44 private static final int FEPSIM_INTERVAL = 30000; 45 private final static SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss"); 46 47 /** 48 * Error Logger. 49 */ 50 private static Logger atmsLogger = Logger.getLogger("tmcsim.cadsimulator.managers"); 51 52 /** 53 * Enumeration containing property names for Properties parsing. 54 * 55 * @author Matthew Cechini 56 */ 57 private static enum PROPERTIES 58 { 59 /** 60 * 61 */ 62 HIGHWAYS_MAP_FILE("Highways_Map_File"), 63 /** 64 * 65 */ 66 FEPSIM_IP_ADDR("FEPSim_IP_addr"), 67 /** 68 * 69 */ 70 EVENTS_FILE("Events_File"); 71 72 public String name; 73 74 private PROPERTIES(String n) 75 { 76 name = n; 77 } 78 }; 79 80 /** 81 * Reference to the simulation Coordinator from whom we get simulation 82 * elapsed time. 83 */ 84 private Coordinator theCoordinator; 85 86 /** 87 * Properties Object. 88 */ 89 private Properties atmsProperties = null; 90 /** 91 * Highways in traffic network 92 */ 93 final private Highways highways; 94 95 /** 96 * LinkedList of batch events 97 */ 98 private LinkedList<TrafficEvent> eventQueue; 99 /** 100 * Map of incidents to events 101 */ 102 private Map<String, List<TrafficEvent>> incidents; 103 104 /** 105 * GUI for this driver 106 */ 107 private TrafficModelViewer theView; 28 108 29 109 /** 30 * Enumeration containing property names for Properties parsing. 31 * @author Matthew Cechini 32 */ 33 private static enum ATMS_PROPERTIES { 34 /** */ 35 ATMS_HOST ("ATMSHost"), 36 /** */ 37 USERNAME ("Username"), 38 /** */ 39 PASSWORD ("Password"), 40 /** */ 41 IMAGE_DIR ("ImageDir"); 42 43 public String name; 110 * Constructor. Loads the Properties file and initializes the 111 * ATMSCommunicator with the parsed data. 112 * 113 * @param propertiesFile Target file path of properties file. 114 */ 115 public TrafficModelManager(String propertiesFile) throws SimulationException 116 { 117 if (!loadProperties(propertiesFile)) 118 { 119 System.exit(0); 120 } 121 122 // Initialize the highway model 123 incidents = new HashMap<String, List<TrafficEvent>>(); 124 highways = new Highways( 125 "config/vds_data/highways_fullmap.txt", 126 // "192.168.251.46", 8080); //IP address of FEP Sim Linux VM 127 "localhost", 8080); 128 129 // READ THE BATCH FILE OF COMMANDS and put in a queue 130 readBatchFile(); 131 // Launch the display 132 theView = new TrafficModelViewer(this, new ArrayList<String>(incidents.keySet())); 133 theView.setVisible(true); 134 theView.update("0:00", "1:11", eventQueue); 135 136 // Create a timer that fetches the simulation time every second. 137 Timer timer = new Timer(ONE_SECOND, new ActionListener() 138 { 139 // Every second, see if an event should be launched 140 public void actionPerformed(ActionEvent e) 141 { 142 String currentClock = ""; 143 String currentATMStime = ""; 144 Date simClock = new Date(); 145 // Obtain the simulation time from the CAD server 146 try 147 { 148 long simtime = theCoordinator.getCurrentSimulationTime(); 149 currentClock = formatInterval(simtime); 150 // For Debugging, show the ATMS time 151 // long ATMStime = theCoorInt.getATMStime(); 152 // Date atmsdate = new Date(ATMStime); 153 // currentATMStime = formatter.format(atmsdate); 154 try 155 { 156 simClock = formatter.parse(currentClock); 157 } 158 catch (ParseException ex) 159 { 160 Logger.getLogger(ATMSBatchDriver.class.getName()).log(Level.SEVERE, null, ex); 161 System.out.println("Invalid simulation clock time found in ATMSDriverClient"); 162 System.exit(-1); 163 } 164 //System.out.println("Current clock: " + currentClock); 165 } 166 catch (RemoteException ex) 167 { 168 System.out.println("Remote Exception reading sim or ATMS clock time"); 169 Logger.getLogger(ATMSBatchDriver.class.getName()).log(Level.SEVERE, null, ex); 170 } 171 // If we have any events left to process 172 if (!eventQueue.isEmpty()) 173 { 174 // Get the time to launch the next event 175 TrafficEvent nextEvent = eventQueue.peek(); 176 Date eventTime = nextEvent.eventDate; 177 //System.out.println("Next event will be launched at: " + formatter.format(eventTime)); 178 // Check the queue of events to see if the first 179 // item should be launched. IF so, 180 // issue that command and remove it from queue. 181 if (eventTime.before(simClock) || eventTime.equals(simClock)) 182 { 183 System.out.println("LAUNCHING EVENT: " + nextEvent.toString()); 184 // apply colorization to highways 185 highways.applyColorToHighwayStretch(nextEvent.routeNumber, nextEvent.dir, 186 nextEvent.postmile, nextEvent.range, nextEvent.color); 187 // Remove this event from the queue, we're done with it. 188 eventQueue.remove(); 189 } 190 191 theView.update(currentClock, currentATMStime, eventQueue); 192 } 193 } 194 }); 195 timer.start(); 196 197 // Start the FEP thread (to update ATMS every 30 sec). (See class def below) 198 Thread wtfep = new WriteToFEPThread(); 199 wtfep.start(); 44 200 45 private ATMS_PROPERTIES(String n) {46 name = n; 47 }48 };49 50 /** ATMSCommunicator Object used for communication to the ATMS server. */51 private ATMSCommunicator theATMSCommunicator;52 53 /** Properties Object. */54 private Properties atmsProperties = null;55 56 57 /**58 * Constructor. Loads the Properties file and initializes the59 * ATMSCommunicator with the parsed data.60 *61 * @param propertiesFile Target file path of properties file.62 */63 public ATMSManager(String propertiesFile) {64 65 try{201 } 202 203 /** 204 * This method verifies that the CAD Simulator Host and Port values are not 205 * null. Also, if a CAD Position or User ID do not exist in the properties 206 * file, the user is prompted to enter values. These values are written to 207 * the properties file. If the user cancels the process of entering these 208 * values, the verification fails. 209 * 210 * @param propertiesFile File path (absolute or relative) to the properties 211 * file containing configuration data. 212 * @return True if the properties file is valid, false if not. 213 * @throws SimulationException if there is an exception in verifying the 214 * properties file, or if the user cancels input. 215 */ 216 private boolean loadProperties(String propertiesFile) 217 throws SimulationException 218 { 219 // Load the properties file. 220 try 221 { 66 222 atmsProperties = new Properties(); 67 223 atmsProperties.load(new FileInputStream(propertiesFile)); 68 69 theATMSCommunicator = new ATMSCommunicator( 70 atmsProperties.getProperty(ATMS_PROPERTIES.ATMS_HOST.name), 71 atmsProperties.getProperty(ATMS_PROPERTIES.USERNAME.name), 72 atmsProperties.getProperty(ATMS_PROPERTIES.PASSWORD.name), 73 atmsProperties.getProperty(ATMS_PROPERTIES.IMAGE_DIR.name)); 74 75 } 76 catch (Exception e) { 77 atmsLogger.logp(Level.SEVERE, "ATMSManager", "Constructor", 224 225 } catch (Exception e) 226 { 227 atmsLogger.logp(Level.SEVERE, "TrafficModelManager", "Constructor", 78 228 "Exception in parsing properties file.", e); 79 } 80 } 81 82 83 /** 84 * Returns the current ATMS server time as the number of seconds since Jan 1, 1970. 85 * 86 * @return Current time in seconds. 87 * @throws Exception if an exception occurs communicating to the ATMS server. 88 */ 89 public long getCurrentTime() throws Exception { 90 return theATMSCommunicator.getCurrentTime(); 91 } 92 93 /** 94 * Show a new image for an ATMS camera. The ATMS camera files are named 95 * <ATMS_Camera_ID>.xpm. If a camera file exists, delete it. Then copy 96 * the parameter file name to <ATMS_Camera_ID>.xpm. If the camera ID or 97 * new file does not exist, throw an exception. 98 * 99 * @param ATMS_cameraID ATMS indexed camera ID. 100 * @param fileName Filename to show. 101 * @throws RemoteException if an exception occurs communicating to the ATMS server. 102 */ 103 public void showImage(Integer ATMS_cameraID, String fileName) throws RemoteException { 104 theATMSCommunicator.showImage(ATMS_cameraID, fileName); 105 } 106 229 throw new SimulationException(SimulationException.INITIALIZE_ERROR, 230 e); 231 } 232 233 234 // Ensure that the properties file does not have null values for the 235 // required information. 236 if (atmsProperties.getProperty(PROPERTIES.HIGHWAYS_MAP_FILE.name) == null 237 || atmsProperties.getProperty(PROPERTIES.FEPSIM_IP_ADDR.name) == null 238 || atmsProperties.getProperty(PROPERTIES.EVENTS_FILE.name) == null) 239 { 240 atmsLogger.logp(Level.SEVERE, "TrafficModelManager", 241 "Constructor", "Null value in properties file."); 242 throw new SimulationException(SimulationException.INITIALIZE_ERROR); 243 } 244 245 return true; 246 } 247 private void readBatchFile() 248 { 249 FileInputStream fis; 250 try 251 { 252 fis = new FileInputStream("config/vds_data/atmsBatchEvents.txt"); 253 eventQueue = new LinkedList<TrafficEvent>(); 254 // Read all lines from the file of events 255 Scanner scan = new Scanner(fis); 256 while (scan.hasNext()) 257 { 258 // Read a line and add it to the event queue 259 String line = scan.nextLine().trim(); 260 if (line.charAt(0) != '#') 261 { 262 TrafficEvent evt; 263 try 264 { 265 evt = new TrafficEvent(line); 266 eventQueue.add(evt); 267 String incident = evt.incident; 268 // Add the line to the list for the corresponding incident 269 List evtList; 270 if (incidents.containsKey(evt.incident)) 271 { 272 evtList = incidents.get(evt.incident); 273 } 274 else 275 { 276 evtList = new ArrayList<String>(); 277 } 278 evtList.add(evt); 279 // and put it back in the map 280 incidents.put(incident, evtList); 281 } 282 catch (ParseException ex) 283 { 284 Logger.getLogger(ATMSBatchDriver.class.getName()).log(Level.SEVERE, null, ex); 285 System.out.println("Wrong format data in batch event file: " + line + " \nskipping."); 286 System.out.println("Skipping badly formatted event."); 287 } 288 } 289 } 290 } 291 catch (FileNotFoundException ex) 292 { 293 Logger.getLogger(ATMSBatchDriver.class.getName()).log(Level.SEVERE, null, ex); 294 } 295 System.out.println("Events file read, " + eventQueue.size() + " events queued."); 296 // Put the events in chronological order 297 Collections.sort(eventQueue); 298 } 299 300 /** 301 * Clear an incident. For each event associated with an incident, turn the 302 * dots in its range Green and remove it from the event queue. 303 * 304 * @param incidentNumber incident to be cleared. 305 */ 306 public void clearIncident(String incidentNumber) 307 { 308 boolean ok = incidents.containsKey(incidentNumber); 309 if (!ok) 310 { 311 System.out.println("Sorry, that incident number isn't found."); 312 return; 313 } 314 System.out.println("Clearing incident " + incidentNumber); 315 List<TrafficEvent> events = incidents.get(incidentNumber); 316 // Process each event associated with this incident 317 for (TrafficEvent event : events) 318 { 319 System.out.println("Event: " + event + " cleared."); 320 eventQueue.remove(event); 321 322 // apply colorization to highways, forcing to green, indicating cleared 323 highways.applyColorToHighwayStretch(event.routeNumber, event.dir, 324 event.postmile, event.range, LoopDetector.DOTCOLOR.GREEN); 325 326 } 327 // Now refresh the view with the updated queue of events 328 theView.update("0:00", "0:00", eventQueue); 329 } 330 331 /** 332 * Format a time in seconds as HH:MM:SS 333 * 334 * @param l 335 * @return 336 */ 337 private String formatInterval(final long l) 338 { 339 final long hr = TimeUnit.SECONDS.toHours(l); 340 final long min = TimeUnit.SECONDS.toMinutes(l - TimeUnit.HOURS.toSeconds(hr)); 341 final long sec = TimeUnit.SECONDS.toSeconds(l - TimeUnit.HOURS.toSeconds(hr) - TimeUnit.MINUTES.toSeconds(min)); 342 return String.format("%02d:%02d:%02d", hr, min, sec); 343 } 344 345 class WriteToFEPThread extends Thread 346 { 347 348 public void run() 349 { 350 System.out.println("WriteToFEP Thread starting."); 351 // Run indefinitely 352 while (true) 353 { 354 try 355 { 356 // Write the highway network status to the FEP Simulator 357 highways.writeToFEP(); 358 } 359 catch (SimulationException ex) 360 { 361 // Ask user if they want to proceed without FEP Sim connection 362 int reply = JOptionPane.showConfirmDialog(null, "Failed to connect to FEP Sim, proceed anyway?", "Network Failure", JOptionPane.YES_NO_OPTION); 363 if (reply == JOptionPane.NO_OPTION) 364 { 365 System.exit(0); 366 } 367 System.out.println("Skipping writeToFEP..."); 368 } 369 370 // Wait for FEP Sim to process the data we just sent 371 try 372 { 373 Thread.sleep(FEPSIM_INTERVAL); 374 } 375 catch (InterruptedException ie) 376 { 377 ie.printStackTrace(); 378 } 379 } 380 381 } 382 } 107 383 }
Note: See TracChangeset
for help on using the changeset viewer.
