eclipse-sumo/sumo

Get future TLS state

Closed this issue · 4 comments

I want to get the state of the TLS after 30 seconds.
traci.vehicle.getNextTLS can only get the current state of the TLS, and I couldn't find other traci function either.

SUMO-version:
1.17.0
operating system:
Windows 11

Following is the code I tried to write. I do get the TLS state at the ftime(after 30 seconds), but it only prints the results every 31 seconds. How can I make it print the results every second?

traci.start(["sumo", "-c", "test.sumocfg"])

jID = "J1"

while traci.simulation.getMinExpectedNumber() > 0:
    traci.simulationStep()
    time = traci.simulation.getTime()
    ftime = time + 30
    cphase = traci.trafficlight.getRedYellowGreenState(jID)
    traci.simulationStep(ftime)
    fphase = traci.trafficlight.getRedYellowGreenState(jID)
    print("\n", time)
    print(cphase)
    print(ftime)
    print(fphase)
    
traci.close()

Your code forwards the simulation to the time indicated in ftime. Is that what you want? Or do you want to have an estimate at time t=0 what the traffic light state could be in deltaT = 30s?

Thanks for the comment!
I think the latter one is what I want. I also tried another way to write the code, as below, but maybe there is a better way?

while traci.simulation.getMinExpectedNumber() > 0:
    
    traci.simulationStep()
    time = traci.simulation.getTime()
    ftime = time + 30
    cduration = traci.trafficlight.getNextSwitch(jID) - time  
    program = traci.trafficlight.getAllProgramLogics(jID)[0]
    phases = program.phases
    phases_idx = traci.trafficlight.getPhase(jID)
    cstate = phases[phases_idx].state[3]
    t = 30 - cduration 
    
    print("\n", time)
    print("idx", phases_idx)
    print(cstate)
    print(cduration)
    
    while t > 0:
        next_phase_idx = (phases_idx + 1) % len(phases)  
        next_phase_duration = phases[next_phase_idx].duration
        t -= next_phase_duration
        phases_idx = next_phase_idx

    print("Final idx:", phases_idx)
    
    fstate = phases[phases_idx].state[3]
    print(ftime)
    print(fstate)

Now I did not check your script above in detail, but the idea behind it seems alright. You can look up which phase would be active in 30s and access the signal state.