Search code examples
pythonsumo

Modifying SUMO value to python


<?xml version="1.0" encoding="UTF-8"?>

    <!-- generated on 2023-04-02 15:50:23 by Eclipse SUMO netedit Version 1.16.0
-->

    <routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 
xsi:noNamespaceSchemaLocation="http://sumo.dlr.de/xsd/routes_file.xsd">
        <!-- Vehicles, persons and containers (sorted by depart) -->
        <trip id="car1" depart="0.00" from="E0" to="E0"/>
        <trip id="car10" depart="0.00" color="255,0,80" from="E0" to="E0"/>
        <trip id="car2" depart="0.00" from="E0" to="E0"/>
        <trip id="car3" depart="0.00" color="0,255,27" from="E0" to="E0"/>
        <trip id="car4" depart="0.00" from="E0" to="E0"/>
        <trip id="car5" depart="0.00" color="0,134,255" from="E0" to="E0"/>
        <trip id="car6" depart="0.00" color="255,170,0" from="E0" to="E0"/>
        <trip id="car7" depart="0.00" from="E0" to="E0"/>
        <trip id="car8" depart="0.00" color="79,0,255" from="E0" to="E0"/>
        <trip id="car9" depart="0.00" from="E0" to="E0"/>
    </routes>

I made 10 cars using SUMO. By the way, I want to use these values to modify them in Python.

#car value
from dataclasses import dataclass
from typing import Tuple

class CAR:
  frequency: float
  transmission_power: float
  idle_power: float
  download_power: float
  location: Tuple[float, float, float]

  def __post_init__(self):
    self.consumption_per_cycle = 10e-27 * (self.frequency**2)

I'd like to give each car this frequency, transmission_power, etc. Is it possible? How can I do?

I think I need to link the SUMO file with python for now, but I don't know how to do it.


Solution

  • If I understand your question correctly you want to give your values as additional parameters to the vehicles such that they can be accessed in the simulation. There are (at least) two ways to do so:

    1. Modify the XML. This means using some kind of XML parser, read the file and add your values as parameters:
    import xml.etree.ElementTree as ET   
    
    root = ET.parse("car.rou.xml").getroot()    
    for vehicle in root.iter('vehicle'):  # iterate over all vehicles
        param = ET.Element("param")
        param.set("key", "frequency")
        param.set("value", "10")  # or whatever value you like
        vehicle.append(param)
        # and now the same for the other parameters
    ET.ElementTree(root).write("parameterized_cars.rou.xml")   
    
    1. Do it inside sumo with traci / libsumo
    import traci
    traci.start(["sumo", "-n", "mynet.net.xml", "-r", "car.rou.xml"])
    traci.simulationStep()  # to ensure the cars are loaded
    for v in traci.vehicle.getIDList():
        traci.vehicle.setParameter(v, "frequency", "10")
    # now do the same for other cars / parameters
    

    The first approach will save a new file and you will have the parameters set to the same value whenever you load that filea nd you can query them in the GUI or via traci / libsumo. The second approach will change the parameters dynamically, so the change is not visible for everyone using the route file.

    Please note that the code above is untested, there may be bugs / typos in it. If it does not work, leave a comment and I will try to fix it.