import os
import traci
from utils.sumo import build_sumo_diagnostics, find_sumo_binary
def run_simple_simulation(config_path: str, steps: int = 100) -> str:
"""
Run a SUMO simulation using the given configuration file.
Args:
config_path: Path to the .sumocfg file.
steps: Number of simulation steps to run.
Returns:
A summary string of the simulation execution.
"""
if not os.path.exists(config_path):
return f"Error: Config file not found at {config_path}"
sumo_binary = find_sumo_binary("sumo")
if not sumo_binary:
return "\n".join(
[
"Error: Could not locate SUMO executable (`sumo`).",
build_sumo_diagnostics("sumo"),
"Please ensure SUMO is installed and either `sumo` is available in PATH or `SUMO_HOME` is set.",
]
)
# Start simulation
# We use a random label to allow parallel runs if needed (though traci global lock is an issue)
# Ideally use libsumo if available for speed, but traci is safer for now.
cmd = [sumo_binary, "-c", config_path, "--no-step-log", "true", "--random"]
try:
traci.start(cmd)
vehicle_counts = []
for step in range(steps):
traci.simulationStep()
vehicle_counts.append(traci.vehicle.getIDCount())
traci.close()
avg_vehicles = sum(vehicle_counts) / len(vehicle_counts) if vehicle_counts else 0
max_vehicles = max(vehicle_counts) if vehicle_counts else 0
return (f"Simulation finished successfully.\n"
f"Steps run: {steps}\n"
f"Average vehicles: {avg_vehicles:.2f}\n"
f"Max vehicles: {max_vehicles}")
except Exception as e:
try:
traci.close()
except:
pass
return f"Simulation error: {str(e)}"