From ce7f6422469eaf1e5ad3227763d39c057c89dd74 Mon Sep 17 00:00:00 2001 From: Leandro Afonso Date: Sat, 22 Nov 2025 21:45:16 +0000 Subject: [PATCH] slight sim change and engine code fomat --- .../main/java/sd/engine/SimulationEngine.java | 303 +++++++++--------- main/src/main/resources/simulation.properties | 74 ++--- 2 files changed, 196 insertions(+), 181 deletions(-) diff --git a/main/src/main/java/sd/engine/SimulationEngine.java b/main/src/main/java/sd/engine/SimulationEngine.java index b69c7ef..f273cfd 100644 --- a/main/src/main/java/sd/engine/SimulationEngine.java +++ b/main/src/main/java/sd/engine/SimulationEngine.java @@ -28,49 +28,51 @@ import sd.util.VehicleGenerator; * - The {@link StatisticsCollector} for tracking metrics. */ public class SimulationEngine { - + /** * Holds all simulation parameters loaded from the properties file. */ private final SimulationConfig config; - + /** * The core of the discrete event simulation. Events are pulled from this * queue in order of their timestamp. */ private final PriorityQueue eventQueue; - + /** - * A map storing all intersections in the simulation, keyed by their ID (e.g., "Cr1"). + * A map storing all intersections in the simulation, keyed by their ID (e.g., + * "Cr1"). */ private final Map intersections; - + /** - * Responsible for creating new vehicles according to the configured arrival model. + * Responsible for creating new vehicles according to the configured arrival + * model. */ private final VehicleGenerator vehicleGenerator; - + /** * Collects and calculates statistics throughout the simulation. */ private final StatisticsCollector statisticsCollector; - + /** * The current time in the simulation (in virtual seconds). * This time advances based on the timestamp of the event being processed. */ private double currentTime; - + /** * A simple counter to generate unique IDs for vehicles. */ private int vehicleCounter; - + /** * Constructs a new SimulationEngine. * * @param config The {@link SimulationConfig} object containing all - * simulation parameters. + * simulation parameters. */ public SimulationEngine(SimulationConfig config) { this.config = config; @@ -89,19 +91,19 @@ public class SimulationEngine { * @return The travel time in seconds. */ private double calculateTravelTime(VehicleType vehicleType) { - double baseTime = config.getBaseTravelTime(); - - switch (vehicleType) { - case BIKE: - return baseTime * config.getBikeTravelTimeMultiplier(); - case HEAVY: - return baseTime * config.getHeavyTravelTimeMultiplier(); - case LIGHT: - default: - return baseTime; + double baseTime = config.getBaseTravelTime(); + + switch (vehicleType) { + case BIKE: + return baseTime * config.getBikeTravelTimeMultiplier(); + case HEAVY: + return baseTime * config.getHeavyTravelTimeMultiplier(); + case LIGHT: + default: + return baseTime; + } } -} - + /** * Initializes the simulation. This involves: * 1. Creating all {@link Intersection} and {@link TrafficLight} objects. @@ -111,53 +113,53 @@ public class SimulationEngine { */ public void initialize() { System.out.println("Initializing simulation..."); - + setupIntersections(); setupRouting(); - + // Schedule initial events to "bootstrap" the simulation scheduleTrafficLightEvents(); scheduleNextVehicleGeneration(0.0); scheduleStatisticsUpdates(); - + System.out.println("Simulation initialized with " + intersections.size() + " intersections"); } - + /** * Creates all intersections defined in the configuration * and adds their corresponding traffic lights. */ private void setupIntersections() { - String[] intersectionIds = {"Cr1", "Cr2", "Cr3", "Cr4", "Cr5"}; + String[] intersectionIds = { "Cr1", "Cr2", "Cr3", "Cr4", "Cr5" }; // Note: "North" is commented out, so it won't be created. - String[] directions = {/*"North",*/ "South", "East", "West"}; - + String[] directions = { /* "North", */ "South", "East", "West" }; + for (String id : intersectionIds) { Intersection intersection = new Intersection(id); - + // Add traffic lights for each configured direction for (String direction : directions) { double greenTime = config.getTrafficLightGreenTime(id, direction); double redTime = config.getTrafficLightRedTime(id, direction); - + TrafficLight light = new TrafficLight( - id + "-" + direction, - direction, - greenTime, - redTime - ); - + id + "-" + direction, + direction, + greenTime, + redTime); + intersection.addTrafficLight(light); } - + intersections.put(id, intersection); } } - + /** * Configures how vehicles should be routed between intersections. * This hardcoded logic defines the "map" of the city. - * * For example, `intersections.get("Cr1").configureRoute("Cr2", "East");` means + * * For example, `intersections.get("Cr1").configureRoute("Cr2", "East");` + * means * "at intersection Cr1, any vehicle whose *next* destination is Cr2 * should be sent to the 'East' traffic light queue." */ @@ -165,26 +167,26 @@ public class SimulationEngine { // Cr1 routing intersections.get("Cr1").configureRoute("Cr2", "East"); intersections.get("Cr1").configureRoute("Cr4", "South"); - + // Cr2 routing intersections.get("Cr2").configureRoute("Cr1", "West"); intersections.get("Cr2").configureRoute("Cr3", "East"); intersections.get("Cr2").configureRoute("Cr5", "South"); - + // Cr3 routing intersections.get("Cr3").configureRoute("Cr2", "West"); intersections.get("Cr3").configureRoute("S", "South"); // "S" is the exit - + // Cr4 routing - //intersections.get("Cr4").configureRoute("Cr1", "North"); + // intersections.get("Cr4").configureRoute("Cr1", "North"); intersections.get("Cr4").configureRoute("Cr5", "East"); - + // Cr5 routing - //intersections.get("Cr5").configureRoute("Cr2", "North"); - //intersections.get("Cr5").configureRoute("Cr4", "West"); + // intersections.get("Cr5").configureRoute("Cr2", "North"); + // intersections.get("Cr5").configureRoute("Cr4", "West"); intersections.get("Cr5").configureRoute("S", "East"); // "S" is the exit } - + /** * Schedules the initial {@link EventType#TRAFFIC_LIGHT_CHANGE} event * for every traffic light in the simulation. @@ -201,38 +203,40 @@ public class SimulationEngine { } } } - + /** * Creates and schedules a new {@link EventType#TRAFFIC_LIGHT_CHANGE} event. * The event is scheduled to occur at {@code currentTime + delay}. * - * @param light The {@link TrafficLight} that will change state. + * @param light The {@link TrafficLight} that will change state. * @param intersectionId The ID of the intersection where the light is located. - * @param delay The time (in seconds) from {@code currentTime} when the change should occur. + * @param delay The time (in seconds) from {@code currentTime} when the + * change should occur. */ private void scheduleTrafficLightChange(TrafficLight light, String intersectionId, double delay) { double changeTime = currentTime + delay; Event event = new Event(changeTime, EventType.TRAFFIC_LIGHT_CHANGE, light, intersectionId); eventQueue.offer(event); } - + /** * Schedules the next {@link EventType#VEHICLE_GENERATION} event. * The time of the next arrival is determined by the {@link VehicleGenerator}. * - * @param baseTime The time from which to calculate the next arrival (usually {@code currentTime}). + * @param baseTime The time from which to calculate the next arrival (usually + * {@code currentTime}). */ private void scheduleNextVehicleGeneration(double baseTime) { // Get the absolute time for the next arrival. double nextArrivalTime = vehicleGenerator.getNextArrivalTime(baseTime); - + // Only schedule the event if it's within the simulation's total duration. if (nextArrivalTime < config.getSimulationDuration()) { Event event = new Event(nextArrivalTime, EventType.VEHICLE_GENERATION, null, null); eventQueue.offer(event); } } - + /** * Schedules all periodic {@link EventType#STATISTICS_UPDATE} events * for the entire duration of the simulation. @@ -240,13 +244,13 @@ public class SimulationEngine { private void scheduleStatisticsUpdates() { double interval = config.getStatisticsUpdateInterval(); double duration = config.getSimulationDuration(); - + for (double time = interval; time < duration; time += interval) { Event event = new Event(time, EventType.STATISTICS_UPDATE, null, null); eventQueue.offer(event); } } - + /** * Runs the main simulation loop. * The loop continues as long as there are events in the queue and @@ -260,46 +264,47 @@ public class SimulationEngine { public void run() { System.out.println("Starting simulation..."); double duration = config.getSimulationDuration(); - + while (!eventQueue.isEmpty() && currentTime < duration) { // Get the next event in chronological order Event event = eventQueue.poll(); - + // Advance simulation time to this event's time currentTime = event.getTimestamp(); - + // Process the event processEvent(event); } - + System.out.println("\nSimulation completed at t=" + String.format("%.2f", currentTime) + "s"); printFinalStatistics(); } - + /** * Main event processing logic. - * Delegates the event to the appropriate handler method based on its {@link EventType}. + * Delegates the event to the appropriate handler method based on its + * {@link EventType}. * * @param event The {@link Event} to be processed. */ private void processEvent(Event event) { switch (event.getType()) { case VEHICLE_GENERATION -> handleVehicleGeneration(); - + case VEHICLE_ARRIVAL -> handleVehicleArrival(event); - + case TRAFFIC_LIGHT_CHANGE -> handleTrafficLightChange(event); - + case CROSSING_START -> handleCrossingStart(event); - + case CROSSING_END -> handleCrossingEnd(event); - + case STATISTICS_UPDATE -> handleStatisticsUpdate(); - + default -> System.err.println("Unknown event type: " + event.getType()); } } - + /** * Handles {@link EventType#VEHICLE_GENERATION}. * 1. Creates a new {@link Vehicle} using the {@link #vehicleGenerator}. @@ -308,17 +313,18 @@ public class SimulationEngine { * at its first destination intersection. * 4. Schedules the *next* {@link EventType#VEHICLE_GENERATION} event. * (Note: This line is commented out in the original, which might be a bug, - * as it implies only one vehicle is ever generated. It should likely be active.) + * as it implies only one vehicle is ever generated. It should likely be + * active.) */ private void handleVehicleGeneration() { Vehicle vehicle = vehicleGenerator.generateVehicle("V" + (++vehicleCounter), currentTime); - + System.out.printf("[t=%.2f] Vehicle %s generated (type=%s, route=%s)%n", - currentTime, vehicle.getId(), vehicle.getType(), vehicle.getRoute()); - + currentTime, vehicle.getId(), vehicle.getType(), vehicle.getRoute()); + // Register with statistics collector statisticsCollector.recordVehicleGeneration(vehicle, currentTime); - + // Schedule arrival at first intersection String firstIntersection = vehicle.getCurrentDestination(); if (firstIntersection != null && !firstIntersection.equals("S")) { @@ -327,13 +333,13 @@ public class SimulationEngine { Event arrivalEvent = new Event(arrivalTime, EventType.VEHICLE_ARRIVAL, vehicle, firstIntersection); eventQueue.offer(arrivalEvent); } - + // Schedule next vehicle generation // This was commented out in the original file. // For a continuous simulation, it should be enabled: scheduleNextVehicleGeneration(currentTime); } - + /** * Handles {@link EventType#VEHICLE_ARRIVAL} at an intersection. * 1. Records the arrival for statistics. @@ -344,65 +350,67 @@ public class SimulationEngine { * current intersection using {@link Intersection#receiveVehicle(Vehicle)}. * 5. Attempts to process the vehicle immediately if its light is green. * - * @param event The arrival event, containing the {@link Vehicle} and intersection ID. + * @param event The arrival event, containing the {@link Vehicle} and + * intersection ID. */ private void handleVehicleArrival(Event event) { Vehicle vehicle = (Vehicle) event.getData(); String intersectionId = event.getLocation(); - + Intersection intersection = intersections.get(intersectionId); if (intersection == null) { System.err.println("Unknown intersection: " + intersectionId); return; } - + System.out.printf("[t=%.2f] Vehicle %s arrived at %s%n", - currentTime, vehicle.getId(), intersectionId); - + currentTime, vehicle.getId(), intersectionId); + // Record arrival time (used to calculate waiting time later) statisticsCollector.recordVehicleArrival(vehicle, intersectionId, currentTime); - + // Advance the vehicle's route to the *next* stop // (it has now arrived at its *current* destination) boolean hasNext = vehicle.advanceRoute(); - + if (!hasNext) { // This was the last stop handleVehicleExit(vehicle); return; } - + String nextDestination = vehicle.getCurrentDestination(); if (nextDestination == null || "S".equals(nextDestination)) { // Next stop is the exit handleVehicleExit(vehicle); return; } - - // Add vehicle to the appropriate traffic light queue based on its next destination + + // Add vehicle to the appropriate traffic light queue based on its next + // destination intersection.receiveVehicle(vehicle); - + // Try to process the vehicle immediately if its light is already green tryProcessVehicle(vehicle, intersection); } - + /** * Checks if a newly arrived vehicle (or a vehicle in a queue * that just turned green) can start crossing. * - * @param vehicle The vehicle to process. + * @param vehicle The vehicle to process. * @param intersection The intersection where the vehicle is. */ - private void tryProcessVehicle(Vehicle vehicle, Intersection intersection) { //FIXME + private void tryProcessVehicle(Vehicle vehicle, Intersection intersection) { // FIXME // Find the direction (and light) this vehicle is queued at // This logic is a bit flawed: it just finds the *first* non-empty queue // A better approach would be to get the light from the vehicle's route String direction = intersection.getTrafficLights().stream() - .filter(tl -> tl.getQueueSize() > 0) - .map(TrafficLight::getDirection) - .findFirst() - .orElse(null); - + .filter(tl -> tl.getQueueSize() > 0) + .map(TrafficLight::getDirection) + .findFirst() + .orElse(null); + if (direction != null) { TrafficLight light = intersection.getTrafficLight(direction); // If the light is green and it's the correct one... @@ -416,26 +424,26 @@ public class SimulationEngine { } } } - + /** * Schedules the crossing for a vehicle that has just been dequeued * from a green light. * 1. Calculates and records the vehicle's waiting time. * 2. Schedules an immediate {@link EventType#CROSSING_START} event. * - * @param vehicle The {@link Vehicle} that is crossing. + * @param vehicle The {@link Vehicle} that is crossing. * @param intersection The {@link Intersection} it is crossing. */ private void scheduleCrossing(Vehicle vehicle, Intersection intersection) { // Calculate time spent waiting at the red light double waitTime = currentTime - statisticsCollector.getArrivalTime(vehicle); vehicle.addWaitingTime(waitTime); - + // Schedule crossing start event *now* Event crossingStart = new Event(currentTime, EventType.CROSSING_START, vehicle, intersection.getId()); processEvent(crossingStart); // Process immediately } - + /** * Handles {@link EventType#CROSSING_START}. * 1. Determines the crossing time based on vehicle type. @@ -447,23 +455,24 @@ public class SimulationEngine { private void handleCrossingStart(Event event) { Vehicle vehicle = (Vehicle) event.getData(); String intersectionId = event.getLocation(); - + double crossingTime = getCrossingTime(vehicle.getType()); - + System.out.printf("[t=%.2f] Vehicle %s started crossing at %s (duration=%.2fs)%n", - currentTime, vehicle.getId(), intersectionId, crossingTime); - + currentTime, vehicle.getId(), intersectionId, crossingTime); + // Schedule the *end* of the crossing double endTime = currentTime + crossingTime; Event crossingEnd = new Event(endTime, EventType.CROSSING_END, vehicle, intersectionId); eventQueue.offer(crossingEnd); } - + /** * Handles {@link EventType#CROSSING_END}. * 1. Updates intersection and vehicle statistics. * 2. Checks the vehicle's *next* destination. - * 3. If the next destination is the exit ("S"), call {@link #handleVehicleExit(Vehicle)}. + * 3. If the next destination is the exit ("S"), call + * {@link #handleVehicleExit(Vehicle)}. * 4. Otherwise, schedule a {@link EventType#VEHICLE_ARRIVAL} event at the * *next* intersection, after some travel time. * @@ -472,24 +481,25 @@ public class SimulationEngine { private void handleCrossingEnd(Event event) { Vehicle vehicle = (Vehicle) event.getData(); String intersectionId = event.getLocation(); - + // Update stats Intersection intersection = intersections.get(intersectionId); if (intersection != null) { intersection.incrementVehiclesSent(); } - + double crossingTime = getCrossingTime(vehicle.getType()); vehicle.addCrossingTime(crossingTime); - + System.out.printf("[t=%.2f] Vehicle %s finished crossing at %s%n", - currentTime, vehicle.getId(), intersectionId); - + currentTime, vehicle.getId(), intersectionId); + // Decide what to do next String nextDest = vehicle.getCurrentDestination(); if (nextDest != null && !nextDest.equals("S")) { // Route to the *next* intersection - // Travel time varies by vehicle type: tmoto = 0.5 × tcarro, tcaminhão = 4 × tmoto + // Travel time varies by vehicle type: tmoto = 0.5 × tcarro, tcaminhão = 4 × + // tmoto double travelTime = calculateTravelTime(vehicle.getType()); double arrivalTime = currentTime + travelTime; Event arrivalEvent = new Event(arrivalTime, EventType.VEHICLE_ARRIVAL, vehicle, nextDest); @@ -499,7 +509,7 @@ public class SimulationEngine { handleVehicleExit(vehicle); } } - + /** * Handles a vehicle exiting the simulation. * Records final statistics for the vehicle. @@ -508,18 +518,19 @@ public class SimulationEngine { */ private void handleVehicleExit(Vehicle vehicle) { System.out.printf("[t=%.2f] Vehicle %s exited the system (wait=%.2fs, travel=%.2fs)%n", - currentTime, vehicle.getId(), - vehicle.getTotalWaitingTime(), - vehicle.getTotalTravelTime(currentTime)); - + currentTime, vehicle.getId(), + vehicle.getTotalWaitingTime(), + vehicle.getTotalTravelTime(currentTime)); + // Record the exit for final statistics calculation statisticsCollector.recordVehicleExit(vehicle, currentTime); } - + /** * Handles {@link EventType#TRAFFIC_LIGHT_CHANGE}. * 1. Toggles the light's state (RED to GREEN or GREEN to RED). - * 2. If the light just turned GREEN, call {@link #processGreenLight(TrafficLight, Intersection)} + * 2. If the light just turned GREEN, call + * {@link #processGreenLight(TrafficLight, Intersection)} * to process any waiting vehicles. * 3. Schedules the *next* state change for this light based on its * green/red time duration. @@ -529,17 +540,17 @@ public class SimulationEngine { private void handleTrafficLightChange(Event event) { TrafficLight light = (TrafficLight) event.getData(); String intersectionId = event.getLocation(); - + // Toggle state - TrafficLightState newState = (light.getState() == TrafficLightState.RED) - ? TrafficLightState.GREEN - : TrafficLightState.RED; - + TrafficLightState newState = (light.getState() == TrafficLightState.RED) + ? TrafficLightState.GREEN + : TrafficLightState.RED; + light.changeState(newState); - + System.out.printf("[t=%.2f] Traffic light %s changed to %s%n", - currentTime, light.getId(), newState); - + currentTime, light.getId(), newState); + // If changed to GREEN, process waiting vehicles if (newState == TrafficLightState.GREEN) { Intersection intersection = intersections.get(intersectionId); @@ -547,15 +558,15 @@ public class SimulationEngine { processGreenLight(light, intersection); } } - + // Schedule the *next* state change for this same light - double nextChangeDelay = (newState == TrafficLightState.GREEN) - ? light.getGreenTime() - : light.getRedTime(); - + double nextChangeDelay = (newState == TrafficLightState.GREEN) + ? light.getGreenTime() + : light.getRedTime(); + scheduleTrafficLightChange(light, intersectionId, nextChangeDelay); } - + /** * Processes vehicles when a light turns green. * It loops as long as the light is green and there are vehicles in the queue, @@ -566,7 +577,7 @@ public class SimulationEngine { * processes the entire queue "instantaneously" at the moment * the light turns green. * - * @param light The {@link TrafficLight} that just turned green. + * @param light The {@link TrafficLight} that just turned green. * @param intersection The {@link Intersection} where the light is. */ private void processGreenLight(TrafficLight light, Intersection intersection) { @@ -579,7 +590,7 @@ public class SimulationEngine { } } } - + /** * Handles {@link EventType#STATISTICS_UPDATE}. * Calls the {@link StatisticsCollector} to print the current @@ -590,9 +601,10 @@ public class SimulationEngine { statisticsCollector.printCurrentStatistics(intersections, currentTime); System.out.println(); } - + /** - * Utility method to get the configured crossing time for a given {@link VehicleType}. + * Utility method to get the configured crossing time for a given + * {@link VehicleType}. * * @param type The type of vehicle. * @return The crossing time in seconds. @@ -605,7 +617,7 @@ public class SimulationEngine { default -> 2.0; }; // Default fallback } - + /** * Prints the final summary of statistics at the end of the simulation. */ @@ -613,33 +625,36 @@ public class SimulationEngine { System.out.println("\n" + "=".repeat(60)); System.out.println("FINAL SIMULATION STATISTICS"); System.out.println("=".repeat(60)); - + statisticsCollector.printFinalStatistics(intersections, currentTime); - + System.out.println("=".repeat(60)); } - + // --- Public Getters --- /** * Gets the current simulation time. + * * @return The time in virtual seconds. */ public double getCurrentTime() { return currentTime; } - + /** * Gets a map of all intersections in the simulation. * Returns a copy to prevent external modification. + * * @return A {@link Map} of intersection IDs to {@link Intersection} objects. */ public Map getIntersections() { return new HashMap<>(intersections); } - + /** * Gets the statistics collector instance. + * * @return The {@link StatisticsCollector}. */ public StatisticsCollector getStatisticsCollector() { diff --git a/main/src/main/resources/simulation.properties b/main/src/main/resources/simulation.properties index ffd421d..9613e78 100644 --- a/main/src/main/resources/simulation.properties +++ b/main/src/main/resources/simulation.properties @@ -46,54 +46,54 @@ simulation.arrival.fixed.interval=2.0 # === TRAFFIC LIGHT TIMINGS === # Format: trafficlight...= -# Intersection 1 -trafficlight.Cr1.North.green=30.0 -trafficlight.Cr1.North.red=30.0 -trafficlight.Cr1.South.green=30.0 -trafficlight.Cr1.South.red=30.0 -trafficlight.Cr1.East.green=30.0 -trafficlight.Cr1.East.red=30.0 -trafficlight.Cr1.West.green=30.0 -trafficlight.Cr1.West.red=30.0 +# Intersection 1 (Entry point - balanced) +trafficlight.Cr1.North.green=20.0 +trafficlight.Cr1.North.red=40.0 +trafficlight.Cr1.South.green=20.0 +trafficlight.Cr1.South.red=40.0 +trafficlight.Cr1.East.green=20.0 +trafficlight.Cr1.East.red=40.0 +trafficlight.Cr1.West.green=20.0 +trafficlight.Cr1.West.red=40.0 -# Intersection 2 -trafficlight.Cr2.North.green=25.0 -trafficlight.Cr2.North.red=35.0 -trafficlight.Cr2.South.green=25.0 -trafficlight.Cr2.South.red=35.0 -trafficlight.Cr2.East.green=35.0 -trafficlight.Cr2.East.red=25.0 -trafficlight.Cr2.West.green=35.0 -trafficlight.Cr2.West.red=25.0 +# Intersection 2 (Main hub - shorter cycles, favor East-West) +trafficlight.Cr2.North.green=12.0 +trafficlight.Cr2.North.red=36.0 +trafficlight.Cr2.South.green=12.0 +trafficlight.Cr2.South.red=36.0 +trafficlight.Cr2.East.green=18.0 +trafficlight.Cr2.East.red=30.0 +trafficlight.Cr2.West.green=18.0 +trafficlight.Cr2.West.red=30.0 -# Intersection 3 -trafficlight.Cr3.North.green=30.0 +# Intersection 3 (Path to exit - favor East) +trafficlight.Cr3.North.green=15.0 trafficlight.Cr3.North.red=30.0 -trafficlight.Cr3.South.green=30.0 +trafficlight.Cr3.South.green=15.0 trafficlight.Cr3.South.red=30.0 -trafficlight.Cr3.East.green=30.0 -trafficlight.Cr3.East.red=30.0 -trafficlight.Cr3.West.green=30.0 +trafficlight.Cr3.East.green=20.0 +trafficlight.Cr3.East.red=25.0 +trafficlight.Cr3.West.green=15.0 trafficlight.Cr3.West.red=30.0 -# Intersection 4 -trafficlight.Cr4.North.green=30.0 +# Intersection 4 (Favor East toward Cr5) +trafficlight.Cr4.North.green=15.0 trafficlight.Cr4.North.red=30.0 -trafficlight.Cr4.South.green=30.0 +trafficlight.Cr4.South.green=15.0 trafficlight.Cr4.South.red=30.0 -trafficlight.Cr4.East.green=30.0 -trafficlight.Cr4.East.red=30.0 -trafficlight.Cr4.West.green=30.0 +trafficlight.Cr4.East.green=20.0 +trafficlight.Cr4.East.red=25.0 +trafficlight.Cr4.West.green=15.0 trafficlight.Cr4.West.red=30.0 -# Intersection 5 -trafficlight.Cr5.North.green=30.0 +# Intersection 5 (Near exit - favor East) +trafficlight.Cr5.North.green=15.0 trafficlight.Cr5.North.red=30.0 -trafficlight.Cr5.South.green=30.0 +trafficlight.Cr5.South.green=15.0 trafficlight.Cr5.South.red=30.0 -trafficlight.Cr5.East.green=30.0 -trafficlight.Cr5.East.red=30.0 -trafficlight.Cr5.West.green=30.0 +trafficlight.Cr5.East.green=22.0 +trafficlight.Cr5.East.red=23.0 +trafficlight.Cr5.West.green=15.0 trafficlight.Cr5.West.red=30.0 # === VEHICLE CONFIGURATION === @@ -118,4 +118,4 @@ vehicle.travel.time.heavy.multiplier=2.0 # === STATISTICS === # Interval between dashboard updates (seconds) -statistics.update.interval=10.0 +statistics.update.interval=1.0