Traffic Simulation/SUMO

[Tutorial] TraCI4Traffic Lights

rrojin 2022. 2. 5. 17:39

0. 튜토리얼 링크

https://sumo.dlr.de/docs/Tutorials/TraCI4Traffic_Lights.html

 

TraCI4Traffic Lights - SUMO Documentation

1.1.0 --> TraCI4Traffic Lights This shows how to use the Traffic Control Interface (in short TraCI) on a simple example. TraCI gives the possibility to control a running road traffic simulation. TraCI uses a TCP-based client/server architecture where SUMO

sumo.dlr.de

다음 튜토리얼의 목표는 북에서 남으로 이동하는 차량이 존재할 때만 신호를 바꾸는 도로 네트워크를 구성하는 것입니다. 해당 튜토리얼에서 차량의 흐름은 총 3개인데요. 동->서, 서->동, 북->남입니다. 이때 동,서간의 차량이 북->남 보다 많아 동,서간의 녹색신호를 유지하다가, 북->남으로의 이동차량이 있을때만 신호를 변경하는 것이 목표입니다 :)

 

1. Network 구성 

Nodes + Edges +(Edge type) + (Connection) + (tlogic)= Network

 custom input data로 SUMO network 구성시에는 plain-xml-files 작성 후 netconvert를 사용하여 .net.xml 파일로 전환하는 것이 강력 추천이라고 합니다. PlainXML 파일에는 node files, edges files, types files(for edge type), connections files, tlogic files(신호 로직)이 있습니다. 가장 간단하게는 node, edge파일만을 사용하여 network를 구성할 수 있습니다. 

https://sumo.dlr.de/docs/Networks/PlainXML.html

 

PlainXML - SUMO Documentation

1.1.0 --> PlainXML SUMO-Networks have two representations: A set of plain-xml files which describe the network topology and geometry The .net.xml file which is loaded into the simulation. This contains lots of generated information such as structures withi

sumo.dlr.de

 

해당 튜토리얼 network는 간단한 사거리입니다 :>

북->남으로 이동 차량이 발견되어 해당 방향 신호가 녹색으로 변경되었습니다 :) 

cross.nod.xml cross.edg.xml cross.con.xml cross.det.xml 에 netconvert를 적용하여 network를 구성합니다.

필요한 전체 파일들은 튜토리얼 github에서 확인 할 수 있습니다. 

https://github.com/eclipse/sumo/tree/main/tests/complex/tutorial/traci_tls/data

detector를 통해서 북->서로 차량이 이동 시, 이를 발견할 수 있는데, cross.det.xml파일에 detector가 명시되어있습니다.

신호등은 node로 표현되며, type을 type="traffic_light"로 지정하면 됩니다. 

cross.nod.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
<nodes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://sumo.dlr.de/xsd/nodes_file.xsd">
   <node id="0" x="0.0" y="0.0"  type="traffic_light"/>
 
   <node id="1" x="-500.0" y="0.0" type="priority"/>
   <node id="2" x="+500.0" y="0.0" type="priority"/>
   <node id="3" x="0.0" y="-500.0" type="priority"/>
   <node id="4" x="0.0" y="+500.0" type="priority"/>
   
   <node id="51" x="-510.0" y="0.0" type="priority"/>
   <node id="52" x="+510.0" y="0.0" type="priority"/>
   <node id="53" x="0.0" y="-510.0" type="priority"/>
   <node id="54" x="0.0" y="+510.0" type="priority"/>  
</nodes>
cs

netconvert를 통해 생성된 최종 network를 살펴보면(cross.net.xml) tlogic이 다음과 같이 명시되어있는 것을 확인할 수 있습니다. state는 신호 상태를 의미하는데 차례대로 N,E,S,W에 위치한 신호를 의미합니다. 예를 들어, 첫번째 phase의 state는 state="GrGr" 이므로 N,S 쪽으로 녹색신호, E,W쪽으로 적색신호를 의미합니다. 

1
2
3
4
5
6
 <tlLogic id="0" type="static" programID="0" offset="0">
        <phase duration="31" state="GrGr"/>
        <phase duration="6" state="yryr"/>
        <phase duration="31" state="rGrG"/>
        <phase duration="6" state="ryry"/>
 </tlLogic>
cs

 

2. TraCI

https://sumo.dlr.de/docs/TraCI.html

 

TraCI - SUMO Documentation

1.1.0 --> TraCI Introduction to TraCI TraCI is the short term for "Traffic Control Interface". Giving access to a running road traffic simulation, it allows to retrieve values of simulated objects and to manipulate their behavior "on-line". Using TraCI SUM

sumo.dlr.de

 이번 튜토리얼에서는 TraCI 인터페이스를 사용하여 route를 생성하고 신호를 조절합니다. 

TraCI는"Traffic Control Interface"의 약자입니다. 이를 통해 simulation환경에 접근할 수 있는데, 실시간으로 환경의 정보를 얻어올 수도 있고, 시뮬레이션에 원하는 행동을 취할 수도 있습니다.

sumo를 시작한 후, TraCI client는 약속된 sumo port를 사용하여 TCP 통신을 통해 sumo에 연결합니다. TraCI client는 simulation을 시작, 차량 움직임 제어 등 sumo 환경에 명령어를 전달할 수 있습니다. sumo 는 해당 명령어를 수행하고 결과를 반환합니다. client는 traci.simulationStep()를 통해 simulation step을 유발합니다.  

 

3. route 생성

WE방향으로는 pWE=1/10으로 평균적으로 매 10초마다 한대씩 차량을 추가합니다.

EW는 pEW = 1/11, NS는 pNS = 1/30의 값을 가집니다.

route를 생성하는 함수는 다음과 같습니다. 차량이 추가되는대로 xml파일에 적어나가는 방식입니다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def generate_routefile():
    random.seed(42)
    N = 36000
    pWE = 1./10
    pEW = 1./11
    pNS = 1./30
 
    with open("cross.rou.xml","w"as routes:
        print("""<routes>
        <vType id = "typeWE" accel="0.8" decel = "4.5" sigma="0.5" length="5" minGap="2.5" maxSpeed="16.67" guiShape="passenger"/>
        <vType id="typeNS" accel="0.8" decel="4.5" sigma="0.5" length="7" minGap="3" maxSpeed="25" guiShape="bus"/>
        <route id="right" edges="51o 1i 2o 52i" />
        <route id="left" edges="52o 2i 1o 51i" />
        <route id="down" edges="54o 4i 3o 53i" />"""file = routes)
        vehNr = 0
        for i in range(N):
            if random.uniform(01< pWE:
                print('    <vehicle id="right_%i" type="typeWE" route="right" depart="%i" />' % (
                    vehNr, i), file=routes)
                vehNr += 1
            if random.uniform(01< pEW:
                print('    <vehicle id="left_%i" type="typeWE" route="left" depart="%i" />' % (
                    vehNr, i), file=routes)
                vehNr += 1
            if random.uniform(01< pNS:
                print('    <vehicle id="down_%i" type="typeNS" route="down" depart="%i" color="1,0,0"/>' % (
                    vehNr, i), file=routes)
                vehNr += 1
        print("</routes>"file=routes)
cs

 

4. 신호 조정

if traci.trafficlight.getPhase("0"== 2   (<phase duration="31" state="rGrG"/>현재 신호가 phase2이고,

if traci.inductionloop.getLastStepVehicleNumber("0"> 0 와 같이 북->남쪽의 이동 차량이 detector에 발견되면,

북->남 방향이 녹색 신호를 받을 수 있도록 phase3으로 전환합니다.

최종 코드는 튜토리얼 github의 runner.py에서 확인할 수 있습니다 :) 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def run():
    """execute the TraCI control loop"""
    step = 0
    # we start with phase 2 where EW has green
    traci.trafficlight.setPhase("0"2)
    while traci.simulation.getMinExpectedNumber() > 0:
        traci.simulationStep()
        if traci.trafficlight.getPhase("0"== 2:
            # we are not already switching
            if traci.inductionloop.getLastStepVehicleNumber("0"> 0:
                # there is a vehicle from the north, switch
                traci.trafficlight.setPhase("0"3)
            else:
                # otherwise try to keep green for EW
                traci.trafficlight.setPhase("0"2)
        step += 1
    traci.close()
    sys.stdout.flush()
cs