Warning: Can't use blame annotator:
svn blame failed on trunk/src/tmcsim/cadsimulator/managers/TrafficModelManager.java: ("Can't find a temporary directory: Internal error", 20014)

source: tmcsimulator/trunk/src/tmcsim/cadsimulator/managers/TrafficModelManager.java @ 187

Revision 187, 13.7 KB checked in by jdalbey, 9 years ago (diff)

TrafficModelManager?.java: Initial refactoring to put the traffic model as a manager within CAD Server. Compiles, but not functioning yet.

RevLine 
1package tmcsim.cadsimulator.managers;
2
3import atmsdriver.ConsoleTrafficDriver;
4import atmsdriver.model.Highways;
5import atmsdriver.model.LoopDetector;
6import atmsdriver.model.TrafficEvent;
7import java.awt.event.ActionEvent;
8import java.awt.event.ActionListener;
9import java.io.FileInputStream;
10import java.io.FileNotFoundException;
11import java.rmi.RemoteException;
12import java.text.ParseException;
13import java.text.SimpleDateFormat;
14import java.util.ArrayList;
15import java.util.Collections;
16import java.util.Date;
17import java.util.HashMap;
18import java.util.LinkedList;
19import java.util.List;
20import java.util.Map;
21import java.util.Observable;
22import java.util.Properties;
23import java.util.Scanner;
24import java.util.concurrent.TimeUnit;
25import java.util.logging.Level;
26import java.util.logging.Logger;
27import javax.swing.JOptionPane;
28import javax.swing.Timer;
29import tmcsim.cadsimulator.Coordinator;
30import tmcsim.client.ATMSBatchDriver;
31import tmcsim.client.ATMSBatchViewer;
32import tmcsim.common.SimulationException;
33
34/**
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
40 */
41public 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;
108   
109    /**
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();
200       
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        {
222            atmsProperties = new Properties();
223            atmsProperties.load(new FileInputStream(propertiesFile));
224
225        } catch (Exception e)
226        {
227            atmsLogger.logp(Level.SEVERE, "TrafficModelManager", "Constructor",
228                    "Exception in parsing properties file.", e);
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    }
383}
Note: See TracBrowser for help on using the repository browser.