source: tmcsimulator/trunk/src/atmsdriver/ConsoleTrafficDriver.java @ 180

Revision 180, 11.8 KB checked in by jdalbey, 9 years ago (diff)

ATMSDriver.java Refactored for cleaner design. DotColor? enum moved to LoopDetector? class. ConsoleDriver? renamed ConsoleTrafficDriver? (and associated project configurations updated), build.xml package-jars target updated, ConsoleTrafficDriver? logic improved to allow more user control, runtraffic.bash script created for automating traffic display tests.

Line 
1package atmsdriver;
2
3import atmsdriver.model.Highways;
4import atmsdriver.model.Station.DIRECTION;
5import atmsdriver.model.Highway;
6import atmsdriver.model.Station;
7import atmsdriver.model.LoopDetector.DOTCOLOR;
8import java.io.FileInputStream;
9import java.util.ArrayList;
10import java.util.Arrays;
11import java.util.List;
12import java.util.Properties;
13import java.util.Scanner;
14import java.util.logging.Level;
15import java.util.logging.Logger;
16import tmcsim.common.SimulationException;
17
18/**
19 * A console application to drive the ATMS Server.
20 *
21 * @author jdalbey, John A. Torres
22 * @version 10/11/2017
23 */
24public final class ConsoleTrafficDriver {
25    // highways model
26    private final Highways highways;
27   
28    // lists used for user input validation
29    private final List<Integer> routeNumInputList;
30    /**
31     * Properties for the ConsoleTrafficDriver
32     */
33    private static Properties ConsoleDriverProperties;
34
35    /** Entry point for the application.
36     *
37     * @param args unused
38     */
39    public static void main(String[] args) {
40        try {
41            if (System.getProperty("ATMSDRIVER_PROPERTIES") != null) 
42            {
43                // Load properties of runtime parameters
44                if (!loadProperties()) 
45                {
46                    System.exit(0);
47                }       
48                // Create the Highway Model
49                Highways highways = new Highways(
50                    "config/vds_data/lds.txt",
51                    "config/vds_data/loop.txt",
52                    "config/vds_data/highwaysMeta.txt",
53                    ConsoleDriverProperties.getProperty(
54                        "FEPWriterHost"),
55                    Integer.parseInt(ConsoleDriverProperties.getProperty(
56                        "FEPWriterPort")));
57
58                // Construct the console driver using the highways model
59                ConsoleTrafficDriver driver = new ConsoleTrafficDriver(highways);
60                driver.runConsole();   
61            } else {
62                throw new Exception("ATMSDRIVER_PROPERTIES system property not defined.");
63            }
64        } catch (Exception e) {
65            Logger.getLogger("ConsoleDriver").logp(Level.SEVERE, "ConsoleDriver", "Main",
66                    "Error occured initializing application", e);
67            System.exit(-1);
68        }
69    }   
70    /**
71     * Load the properties file containing values for runtime parameters.
72     *
73     * @param propertiesFile
74     * @return
75     */
76    private static boolean loadProperties() 
77    {
78        // Load the properties file.
79        try {
80            ConsoleDriverProperties = new Properties();
81            ConsoleDriverProperties.load(new FileInputStream(System.getProperty("ATMSDRIVER_PROPERTIES")));
82        } catch (Exception e) {
83            Logger.getLogger("CosoleDriver").logp(Level.SEVERE, "ConsoleDriver",
84                    "Constructor", "Exception in reading properties file.", e);
85        }
86
87        return true;
88    }
89    /**
90     * Constructor. Sets the highways model and generates the input validation
91     * lists, and then runs the console driver application.
92     * @param highways
93     */
94    public ConsoleTrafficDriver(Highways highways) {
95        // set highways model
96        this.highways = highways;
97       
98        // set input validation lists
99        routeNumInputList = generateRouteNumInputList();
100    }
101   
102    /**
103     * Generates the route number list, used for user input validation.
104     * @return list of route numbers.
105     */
106    private ArrayList<Integer> generateRouteNumInputList()
107    {
108        ArrayList<Integer> routeNums = new ArrayList<>();
109        // add the route number for each highway to the list
110        for(Highway hwy : highways.highways)
111        {
112            routeNums.add(hwy.routeNumber);
113        }
114        return routeNums;
115    }
116
117    /**
118     * Runs the console driver application.
119     */
120    public void runConsole() {
121        Scanner sc = new Scanner(System.in);
122        char choice = 'A';
123        // Run continuously
124        while (choice != 'Q')
125        {
126            // Get necessary values for colorization of highways
127            Integer routeNumber = getRouteNumber(sc);
128            DIRECTION direction = getDirection(sc, routeNumber);
129            Double postmile = getPostmile(sc, routeNumber, direction);
130            Double range = getRange(sc, postmile);
131            DOTCOLOR dotcolor = getDotColor(sc);
132
133            // apply colorization to highways
134            highways.applyColorToHighwayStretch(routeNumber, direction, postmile, range, dotcolor);
135
136            System.out.println("Add another entry or Send now? (A/S)");
137            choice = sc.next().toUpperCase().trim().charAt(0);
138            System.out.println("");
139            if (choice == 'S')
140            {
141                // Send highway model to FEP for transmit to ATMS
142                try {
143                    highways.writeToFEP();
144                } catch (SimulationException ex) {
145                    System.out.println("Skipping writeToFEP...");
146                }
147                System.out.println("Add another entry or Quit? (A/Q)");
148                choice = sc.next().toUpperCase().trim().charAt(0);
149            }
150        }
151    }
152   
153   
154    /**
155     * Gets the highway route number from user and validates the input.
156     *
157     * @param sc stdIn scanner
158     * @return highway route number
159     */
160    private Integer getRouteNumber(Scanner sc) {
161        Integer routeNum = null;
162        Boolean verified = false;
163       
164        // validation loop
165        while(!verified)
166        {
167            // Prints out available route numbers to user to select from
168            System.out.print("Available route numbers: [");
169            for(Integer rtNum : routeNumInputList)
170            {
171                System.out.print(rtNum.toString() + ", ");
172            }
173            System.out.print("]");
174            System.out.println("");
175           
176            // Prompt user to input a route number
177            System.out.println("Enter a route number: ");
178            routeNum = sc.nextInt();
179            System.out.println("");
180           
181            // validate the user's input
182            if(routeNumInputList.contains(routeNum))
183            {
184                verified = true;
185            }
186            else
187            {
188                System.out.println("Invalid route number, please re-enter: ");
189            }
190        }
191       
192        return routeNum;
193    }
194   
195    /**
196     * Gets the highway direction from the user and validates the input.
197     *
198     * @param sc stdIn scanner
199     * @return highway direction
200     */
201    private DIRECTION getDirection(Scanner sc, Integer routeNum) {
202        DIRECTION direction;
203        String directionInput = null;
204        Boolean verified = false;
205       
206        // validation loop
207        while(!verified)
208        {
209            // Get available directions for route
210            ArrayList<DIRECTION> availDirs = new ArrayList<>();
211            for(Station stn : highways.getHighwayByRouteNumber(routeNum).stations)
212            {
213                if(!availDirs.contains(stn.direction))
214                {
215                    availDirs.add(stn.direction);
216                }
217            }
218           
219            // prompt user for input
220            System.out.print("Available directions for highway " + routeNum + ": [");
221            for(DIRECTION dir : availDirs)
222            {
223                System.out.print(dir.getLetter() + ", ");
224            }
225            System.out.print("]");
226            System.out.println("");
227            System.out.println("Enter a direction:");
228            directionInput = sc.next().toUpperCase();
229            System.out.println("");
230           
231            // validate the user's input
232            if(availDirs.contains(DIRECTION.toDirection(directionInput)))
233            {
234                verified = true;
235            }
236            else
237            {
238                System.out.println("Invalid direction, please re-enter: ");
239            }
240        }
241       
242        return DIRECTION.toDirection(directionInput);
243    }
244   
245    /**
246     * Gets the starting/origin postmile value for the highway section from the
247     * user and validates the input.
248     *
249     * @param sc stdIn scanner
250     * @param routeNumber highway route number
251     * @param dir highway direction
252     * @return highway section start/origin postmile value
253     */
254    private Double getPostmile(Scanner sc, Integer routeNumber, DIRECTION dir) {
255        Double postmile = null;
256        Boolean verified = false;
257       
258        // validation loop
259        while(!verified)
260        {
261            // Get highway, and grab the floor and ceiling for postmile values
262            // from the highway stations to present to the user
263            Highway hwy = highways.getHighwayByRouteNumber(routeNumber);
264            Double floorPostmile = hwy.stations.get(0).postmile;
265            Double ceilPostmile = hwy.stations
266                    .get(hwy.stations.size() - 1).postmile;
267           
268            // present user with range of postmiles for given highway
269            System.out.println("Route " + hwy.routeNumber + " " + dir
270                    + " postmile range: [" + floorPostmile + ", " 
271                    + ceilPostmile + "]");
272           
273            // prompt user for postmile value
274            System.out.println("Enter a postmile value (Integer/Double): ");
275            postmile = sc.nextDouble();
276            System.out.println("");
277           
278            // validate user's input, ensures that the postmile is within given
279            // postmile range (floorPostmile, ceilPostmile)
280            if(postmile >= floorPostmile && postmile <= ceilPostmile)
281            {
282                verified = true;
283            }
284            else
285            {
286                System.out.println("Postmile must be within postmile range: [" + floorPostmile + ", " 
287                    + ceilPostmile + "] please re-enter: ");
288            }
289        }
290       
291        return postmile;
292    }
293   
294    /**
295     * Gets the range to extend the highway stretch from the start/origin postmile
296     * value from the user and validates the input.
297     *
298     * @param sc stdIn scanner
299     * @param postmile origin/start postmile value for highway stretch
300     * @return range value
301     */
302    private Double getRange(Scanner sc, Double postmile) {
303        Double range = null;
304        Boolean verified = false;
305       
306        // validation loop
307        while(!verified)
308        {
309            // prompt user for range value
310            System.out.println("Enter a range value (decimal):");
311            range = sc.nextDouble();
312            System.out.println("");
313           
314            // range must be greater than or equal to 0
315            if(range >= 0)
316            {
317                verified = true;
318            }
319            else
320            {
321                System.out.println("Range must be >= 0");
322            }
323        }
324       
325        return range;
326    }
327
328    /**
329     * Gets the dot color from the user, to be applied to specified highway
330     * stretch and validates the user's input.
331     *
332     * @param sc stdIn scanner
333     * @return dot color to be applied to highway stretch
334     */
335    private DOTCOLOR getDotColor(Scanner sc) {
336        DOTCOLOR dotColor;
337        String dotColorInput = null;
338        Boolean verified = false;
339       
340        // validationloop
341        while(!verified)
342        {
343            // prompt user for color
344            System.out.println("Enter a dot color (G/Y/R):");
345            dotColorInput = sc.next().toUpperCase();
346            System.out.println("");
347            // validate user's input
348            if(DOTCOLOR.allLetters.contains(dotColorInput))
349            {
350                verified = true;
351            }
352            else
353            {
354                System.out.println("Invalid dot color, please re-enter: ");
355            }
356        }
357       
358        return DOTCOLOR.toDotColor(dotColorInput);
359    }
360   
361}
Note: See TracBrowser for help on using the repository browser.