In Formula E, races are won and lost on strategy, not just speed. Teams need to prepare for countless unpredictable events, but physical track time is impossibly expensive and limited.

That's why we plan to build Apex/RT, a real-time competitive mobility simulator. It's a digital twin of a Formula E race where teams can test and perfect their strategies against dynamic, real-world chaos.

Using the powerful open-source SUMO engine, Apex/RT models every car's energy consumption, regenerative braking, and tyre wear, and injects random events like safety cars and system faults.All of this is visualized on a live mission-control dashboard with a real-time leaderboard and deep telemetry.

A. What is SUMO

SUMO is an open-source, "microscopic and continuous" traffic simulation package, meaning it models the behavior and movement of every individual vehicle, which is essential for simulating race dynamics like overtaking, blocking, and drafting. The decisive feature that sets SUMO apart is the Traffic Control Interface (TraCI). TraCI is a powerful API that facilitates "Online Interaction," allowing an external script to query and manipulate every aspect of the simulation in real-time, on a per-step basis. This interface transforms SUMO from a static analysis tool into a dynamic, controllable environment.

B. Scenario Definition: Modeling a Formula E Circuit

Formula E is renowned for its use of "temporary inner-city tracks," a characteristic that aligns perfectly with SUMO's ability to generate road networks directly from OpenStreetMap (OSM) data.

Step 1: Network Import from OpenStreetMap
The process begins by downloading OSM data for a real-world Formula E location. SUMO's command-line tool, netconvert, is then used to process this raw geographic data into a SUMO-native network file (.net.xml). This provides a realistic, geo-accurate foundation for the track, saving dozens of hours of manual creation.
Step 2: Graphical Refinement with netedit
The imported network will contain the entire street grid of the selected area. The team will use netedit, SUMO's graphical network editor, to sculpt the precise race track from this raw data. This is an intuitive process that involves:

  • Deleting unnecessary roads and junctions.
  • Adjusting junction priorities and traffic rules to ensure a clear racing line.
  • Smoothing corner geometries and verifying lane connectivity to create a seamless, closed-loop circuit.
  • Setting appropriate speed limits for different sections of the track.

Step 3: Defining Race-Specific Features
The refined network must be augmented with race-specific elements using netedit and direct XML editing.

  • Pit Lane: Modeled as a separate edge parallel to the main straight, with a designated low speed limit. Entry and exit points are carefully connected to the main track.
  • Start/Finish Line & Sector Markers: These are defined using inductionLoop detectors placed at precise positions on the track edges. These detectors are the primary mechanism for the Python controller to track lap counts, lap times, and sector splits by querying which vehicles have passed over them in a given simulation step.
  • Attack Mode Activation Zone: This critical strategic element is modeled as a short, alternative path off the main racing line, designed to ensure a time loss as per real-world regulations. A SUMO rerouter element, placed on the edge preceding the zone entrance, will be used by the TraCI script to dynamically divert a car through this zone when the driver activates Attack Mode. Additional inductionLoop detectors at the zone's exit will confirm successful activation to the control script.

C. Vehicle Dynamics and Fleet Configuration

The simulation's realism depends on accurately modeling the Formula E race car. We will do this by defining a vType in a dedicated XML file, which specifies the physical and behavioral properties of all vehicles of that type.Performance data for the GEN3 Evo car will be synthesized to create this vehicle type.

Performance Metric Real-World Specification SUMO Attribute Calculated Value for XML (Estimated we will do better calcs in the hackathon)
Acceleration 0-60mph in 1.82s accel 14.7
Top Speed 200mph maxSpeed 89.4
Regenerative Braking 600kW capacity decel 12.0
Length Single-seater formula car length 5.0
Width Single-seater formula car width 1.8
Driver Imperfection Professional race driver sigma 0.1

The entire 22-car grid will be generated in a separate XML file. Each vehicle element will be assigned a unique ID (e.g., "car_01", "car_02"), the "GEN3Evo" vType, and an initial route for the first lap.

D. Initializing the Race: Demand and Route Generation

The initial state of the race is defined in a SUMO route file (.rou.xml).

  • Starting Grid Formation: Each of the 22 vehicles will be defined with a specific depart time (all set to t="0"), departLane, and departPos to place them accurately on the starting grid according to a pre-defined qualifying order.
  • Route Definition: A base route will be defined, consisting of the ordered sequence of edge IDs that form a single lap of the circuit. Each vehicle will be assigned this initial route. The Python controller will be responsible for dynamically assigning new routes lap after lap, allowing for strategic variations such as executing a pit stop.

II. Real-Time Interaction and Control: The TraCI-Python Bridge

It consists of a Python script that acts as the "race engineer," monitoring the simulation, making strategic decisions, and issuing commands back to the vehicles.

A. Establishing the TraCI Communication Channel

The architecture is a TCP-based client-server model where SUMO acts as the server and the Python control script is the client.

Implementation Steps & Boilerplate Code:

  1. Python Client Connection: The script uses traci.start(sumoCmd) to launch the SUMO process and establish the TCP connection.
  2. The Simulation Loop: The core of the control script is a while loop that orchestrates the entire race. The loop continues as long as there are vehicles in the simulation, a condition checked with traci.simulation.getMinExpectedNumber() > 0. Inside this loop, the script will execute all its logic reading state, making decisions, issuing commands before calling traci.simulationStep() to advance the simulation by one discrete time step.
  3. Graceful Shutdown: When the race concludes (e.g., the lead car completes the final lap), the loop terminates, and traci.close() is called to properly shut down the SUMO process.

B. Core API Functions for Vehicle State Monitoring and Manipulation

Vehicle State Retrieval (Getters): (rough function names)

  • traci.vehicle.getIDList(): Returns a Python list of all active vehicle ID strings in the current step. This is used to iterate through all cars.
  • traci.vehicle.getSpeed(vehID): Returns the current speed of the specified vehicle in m/s.
  • traci.vehicle.getAcceleration(vehID): Returns the vehicle's acceleration in m/s². This is crucial for the energy model, as negative values indicate braking and potential energy regeneration.
  • traci.vehicle.getPosition(vehID): Returns the vehicle's (x, y) coordinates, essential for the live visualization map.
  • traci.vehicle.getRoadID(vehID): Returns the ID of the edge (road segment) the vehicle is currently on.
  • traci.vehicle.getLeader(vehID): Returns the ID of the vehicle directly ahead and the distance to it. This is fundamental for implementing overtaking and drafting logic.

Vehicle Control (Setters): (rough function names)

  • traci.vehicle.setSpeed(vehID, speed): Directly sets a vehicle's speed. This is a "hard" override useful for enforcing safety car periods or simulating a terminal fault.
  • traci.vehicle.setMaxSpeed(vehID, speed): Adjusts the vehicle's maximum desired speed for its current lane. This is the primary mechanism for simulating Attack Mode power boosts or performance degradation from tyre wear or system damage.
  • traci.vehicle.setRoute(vehID, routeID): Dynamically changes a vehicle's entire planned route. This is used to command a vehicle to enter the pit lane.
  • traci.vehicle.changeTarget(vehID, edgeID): A more immediate way to reroute a vehicle towards a specific edge, perfect for the short diversion required to enter the Attack Mode activation zone.

Detector Interaction: (rough function names)

  • traci.inductionloop.getLastStepVehicleIDs(detectorID): Returns a list of vehicle IDs that passed over the specified detector in the last simulation step. This is used to confirm a car has crossed the finish line or successfully activated Attack Mode.

D. Implementing the Real-Time Event Engine

This module within the Python script is responsible for injecting the "real-time events" specified in the challenge, making the simulation unpredictable and strategically complex.

  • Safety Car /(FCY): A function can be triggered (e.g., randomly or by detecting a "crash" event like two vehicles occupying the same space). This function iterates through traci.vehicle.getIDList() and uses traci.vehicle.setSpeed() to cap all cars at a low, uniform speed ( 20 m/s). It can also use traci.vehicle.setLaneChangeMode() to disable overtaking during this period, perfectly simulating FCY rules.
  • Vehicle Faults: A probabilistic function can target a random vehicle and degrade its performance. This is achieved by calling traci.vehicle.setMaxSpeed() or traci.vehicle.setAccel() with permanently reduced values, simulating a technical problem that forces the car into a "limp-home" mode.
  • Dynamic Track Conditions: To simulate a sudden rain shower, the script can iterate through all track edges and modify their friction coefficient using the advanced function traci.edge.setParameter(edgeID, "friction", value). Reducing this value will cause SUMO's internal physics model to realistically reduce cornering speeds and increase braking distances, dramatically affecting lap times and strategy.

III. Advanced Simulation Modules: Modeling Race Strategy

A. Energy Management Model

Energy management is the single most important aspect of Formula E strategy. We plan to implement it by creating a Python class for a RaceCar that holds state variables.

  1. State Variable: Each RaceCar object will have an energy_level attribute, initialized to the usable battery capacity (e.g., 51 kWh).
  2. Consumption & Regeneration Logic: Within the main simulation loop, for each car, the energy level is updated at every time step.
    • Consumption: Energy consumed is proportional to the power output, which is a function of acceleration and velocity (P=F.V)
    • The script will use traci.vehicle.getAcceleration() and traci.vehicle.getSpeed() to calculate the power draw for propulsion and subtract the corresponding energy from energy_level.
    • Regeneration: When traci.vehicle.getAcceleration() is negative (indicating braking), energy is added back to energy_level. This regeneration is capped by the GEN3 Evo's 600kW limit.
  3. Strategic Impact: This model directly influences race strategy. A driver agent that pushes too hard (maintaining high acceleration) will deplete its battery before the race ends, forcing it to slow down dramatically. This creates a tangible trade-off between pace and efficiency.

B. Tyre Management Model

  1. State Variable: Each RaceCar object will have a tyre_grip attribute, initialized to 1.0 (representing 100% grip).
  2. Degradation Logic: At each step, the tyre_grip is reduced by a small amount based on several factors:
    • Distance Traveled: A baseline degradation per meter.
    • Aggressive Maneuvers: The degradation rate is increased when the car experiences high longitudinal acceleration (hard acceleration/braking) or high lateral acceleration (fast cornering). Lateral acceleration can be estimated from the car's speed and the track's corner radius (which can be pre-calculated from the network geometry).
  3. Performance Impact: The current tyre_grip value is used to dynamically limit the car's performance. This is done by scaling the car's maximum acceleration and deceleration parameters via traci.vehicle.setAccel() and traci.vehicle.setDecel(). As grip decreases, the car becomes slower out of corners and has longer braking zones, realistically modeling performance drop-off.

C. Race Strategy Logic

  • Attack Mode Strategy: The agent will decide when to activate Attack Mode. The logic will be a cost-benefit analysis based on:
    • Race Context: Is the car in a position to attack or defend? Is there a safety car period imminent?
    • Energy Level: Is there enough energy to sustain the higher power output?
    • Traffic Situation: Is the track ahead clear enough to use the extra speed effectively, or will the car be stuck behind a slower vehicle?
    • The decision will trigger a call to traci.vehicle.changeTarget() to divert the car through the activation zone.
  • Pitting Strategy: The agent will decide to pit if tyre_grip falls below a critical threshold or if a severe vehicle fault is simulated. The decision triggers a call to traci.vehicle.setRoute() to a pre-defined route that includes the pit lane edge.
  • Pacing and Energy Saving: The agent will manage its pace to meet a target energy consumption per lap. If it is over-consuming, it will slightly reduce its maxSpeed parameter. It can also implement drafting logic: if traci.vehicle.getLeader() shows a car is close ahead, the agent can reduce its power output, simulating the energy saved by sitting in the slipstream.

IV. Data Visualization and User Interface

A. Real-Time Telemetry Dashboard

Streamlit will be used for this. The UI should run as a separate process from the TraCI control loop to ensure that the simulation's performance is not affected by rendering updates.

B. Key Visualizations

  1. Live Track Map: A 2D scatter plot that is updated in real-time. It will display the position of every car on the track, using coordinates from traci.vehicle.getPosition(). Different colors can be used to indicate team, Attack Mode status, or other states.
  2. Dynamic Leaderboard: A table that ranks all cars based on their current race position, showing the driver's name, lap count, last lap time, and gap to the leader.
  3. Driver-Specific Telemetry: Interactive elements (e.g., a dropdown menu to select a car) that display detailed telemetry for the chosen vehicle. This should include line graphs plotting its speed, energy_level, and tyre_grip over the course of the race.
  4. Event Log: A simple text box or feed that logs key events as they happen, such as "Car 07 has activated Attack Mode," "Safety Car Deployed," or "Car 12 overtakes Car 05 for P3."

Built With

Share this project:

Updates

Submission history