소프트웨어 시뮬레이션 수치해석 마지막 수정: 2026-09-06 04:47:29

1. 개요[편집]

SUMO
Simulation of Urban MObility
개발독일항공우주센터(DLR) 교통시스템연구소, 2001년부터
현재 주관Eclipse 재단 (Eclipse SUMO)
라이선스EPL 2.0 (2차 라이선스로 GPL 2.0 이상 선택 가능)
모드미시(차량 한 대씩) · 메조(구간 대기행렬)
기본 추종모형Krauss (다른 선택지: IDM · EIDM · Wiedemann · W99 · ACC · NaSch 등)
기본 차선변경LC2013 · 서브레인 모드 SL2015
외부 제어TraCI(TCP 클라이언트/서버) · libsumo(직접 링크) · libtraci
주요 입력.net.xml(도로망) · .rou.xml(수요) · .sumocfg(설정)

SUMO(Simulation of Urban MObility)는 차량·보행자·대중교통을 한 대씩 개별 객체로 굴리는 오픈소스 미시 교통 시뮬레이터이자, 도로망 변환부터 수요 생성·경로 배정·후처리까지 한 세트로 묶인 툴체인이다. 독일항공우주센터(DLR) 교통시스템연구소가 2001년부터 개발했고, 2018년 Eclipse 재단 프로젝트가 되면서 Eclipse SUMO 라는 이름을 쓴다.1

이 바닥의 상용 대안(VISSIM, Aimsun)이 수천만 원대라는 점을 감안하면 SUMO 의 존재감은 가격만으로도 설명이 되지만, 실제로 학계 표준이 된 이유는 TraCI 라는 외부 제어 인터페이스다. 매 시뮬레이션 스텝마다 파이썬에서 신호등을 바꾸고 차량 속도를 조작하고 상태를 읽어올 수 있어서, 신호 제어 알고리즘·강화 학습 에이전트·V2X 통신 시뮬레이터를 붙이는 실험대가 됐다. 교통 시뮬레이터라기보다 교통 환경을 제공하는 라이브러리로 쓰이는 셈이다.

교통 배정이 다루는 정적 수요 배정과의 관계는 이렇다. SUMO 는 배정 결과를 받아 실제 통행시간으로 바꿔주는 아래층이고, 동시에 자체 반복으로 근사 균형을 만들어 낼 수도 있다. 그 안에서 돌아가는 물리는 교통 흐름의 차량추종·차선변경 모형 그대로다.

2. 역사와 위치[편집]

  • 2001년 — DLR 교통시스템연구소에서 개발이 시작됐고 처음부터 오픈소스로 공개됐다. 초기 목표는 “도시 전체 규모의 네트워크를 미시적으로 굴린다”는, 당시로서는 다소 무모한 것이었다.
  • 2010년대 — 유럽 연구 프로젝트들의 사실상 표준 시뮬레이터로 자리 잡는다. V2X 통신 연구가 네트워크 시뮬레이터(OMNeT++, ns-3)와 교통 시뮬레이터를 결합할 필요를 만들었고, 무료·개방 인터페이스를 가진 SUMO 가 그 자리에 딱 들어맞았다.
  • 2017~2018년 — Eclipse 재단으로 이관. 라이선스가 GPL 계열에서 EPL 2.0 으로 바뀌었다(2차 라이선스로 GPL 2.0 이상을 선택할 수 있도록 열어 두었다). 상용 제품에 임베드하려는 쪽에서는 이게 꽤 큰 변화였다.2
  • 대표 인용 문헌은 Lopez 등(2018)의 Microscopic Traffic Simulation using SUMO 이며, 연례 SUMO User Conference 가 이어지고 있다.

3. 미시 모드 — 차량 한 대씩[편집]

기본 모드는 차량 각각에 위치·속도·목적 경로를 들고 정해진 시간 간격마다 갱신하는 순수 미시 시뮬레이션이다. 기본 시간 간격이 1초라는 점을 먼저 알아 두어야 한다. 정체 전파 같은 거시량에는 충분하지만 가감속 프로파일이나 충돌 위험 지표를 볼 거면 --step-length 0.1 로 내려야 하고, 그러면 당연히 느려진다.

3.1. Krauss 추종 모형[편집]

기본 carFollowModelKrauss 다. 크라우스(1998)의 착상은 “앞차가 지금 최대 감속으로 급제동해도 내 반응시간 뒤에 안 박는 최대 속도”를 매 스텝 직접 계산하는 것이다. 앞차 속도 vlv_l, 순간극 gg, 최대 감속도 bb, 반응시간 τ\tau 에 대해

vsafe  =  vl  +  gvlτvl+v2b+τv_{\mathrm{safe}} \;=\; v_l \;+\; \frac{g - v_l\,\tau}{\dfrac{v_l + v}{2b} + \tau}

이고, 실제 속도는 여기에 가속 한계와 최고속도를 씌운 뒤

vdes=min(vsafe, v+aΔt, vmax),v  =  max(0, vdesσaξ),ξU[0,1]v_{\mathrm{des}} = \min\bigl(v_{\mathrm{safe}},\ v + a\,\Delta t,\ v_{\max}\bigr), \qquad v \;=\; \max\bigl(0,\ v_{\mathrm{des}} - \sigma\, a\,\xi\bigr),\quad \xi \sim U[0,1]

로 정해진다. 마지막 항 σ\sigma(SUMO 파라미터 sigma, 기본값 0.5)가 운전자 불완전성이다. 속도를 깎기만 하므로 안전성은 그대로 유지되면서, 교통 흐름에서 본 것처럼 이 잡음이 준안정 자유류를 무너뜨려 팬텀 정체를 만들어 낸다. sigma=0 으로 놓으면 시뮬레이션이 부자연스럽게 매끄러워지고 정체가 잘 안 생기는 것을 바로 확인할 수 있다.

Krauss 가 기본인 이유는 명확하다 — 구조적으로 충돌이 안 난다. 반면 IDM 은 파라미터가 물리적으로 해석되는 대신 강한 감속 상황에서 충돌을 원리적으로 배제하지 못한다. 그래서 SUMO 는 어느 모형을 쓰든 별도의 안전 장치(--collision.action, 교차로 우선권 검사, 정션 블로킹 회피)를 위에 얹어 둔다.

3.2. 그 밖의 모형[편집]

carFollowModel 속성 하나로 갈아 끼울 수 있다. IDM · IDMM · EIDM(확장 IDM) · WiedemannW99(비덴만 심리-생리 계열, VISSIM 호환 비교용) · ACCCACC(적응형·협조형 순항제어) · BKerner(3상 이론) · PWagner2009 · NaSch(Nagel–Schreckenberg 셀룰러 오토마타) · Rail(철도) 등이 들어 있다. 즉 SUMO 하나로 서로 다른 추종 모형의 결과를 같은 네트워크·같은 수요 위에서 비교할 수 있고, 실제로 그게 이 소프트웨어의 연구 가치 중 큰 부분이다.

차선변경은 기본이 LC2013(에르트만 개발)이며, 전략적(경로상 필요)·협조적(남을 끼워 줌)·속도이득·우측주행 준수라는 네 동기의 가중합으로 결정한다. --lateral-resolution 을 주면 서브레인 모드(SL2015)가 켜져 차선 내부의 횡방향 위치까지 연속으로 다룬다 — 오토바이가 차 사이를 비집는 상황이나 차선 폭이 넓은 도로를 볼 때 필요하다.

3.3. 메조 모드[편집]

--mesosim 으로 켜는 메조스코픽 모드는 링크를 몇 개의 구간으로 쪼개고 그 안의 차량을 개별 동역학 없이 대기행렬로 다룬다. 차량 정체성은 유지되지만 가감속을 계산하지 않으므로 훨씬 빠르다. 도시 전역 수요를 여러 번 반복해서 균형을 잡아야 할 때 미시로는 계산 예산이 안 나오므로, 메조로 배정을 수렴시키고 관심 구간만 미시로 다시 보는 조합이 실무 국룰이다.

4. 툴체인[편집]

SUMO 는 실행 파일 하나가 아니라 도구 묶음이다. 각각이 CLI 프로그램이라 스크립트로 엮기 좋다.

도구하는 일
netconvert외부 도로망(OSM, Shapefile, OpenDRIVE, VISSIM/Vissum 등)을 .net.xml 로 변환
netgenerate격자·거미줄·무작위 추상 네트워크 생성
netedit네트워크·신호·검지기를 손으로 고치는 GUI 편집기
duarouter기점-종점 trip 을 최단경로로 풀어 .rou.xml 생성
jtrrouter회전 비율만 주고 경로를 확률적으로 생성
dfrouter검지기 관측 유량에서 수요를 역산
marouter거시적 배정(용량제약 반복)으로 링크 유량 산출
od2tripsOD 행렬을 개별 trip 으로 분해
polyconvert건물·토지이용 폴리곤 임포트(시각화용)
sumo / sumo-gui시뮬레이션 본체 (콘솔 / GUI)

여기에 파이썬 스크립트들이 붙는다. randomTrips.py 는 네트워크만 있으면 무작위 OD 를 뿌려 즉시 돌아가는 수요를 만들어 주는, 사실상 모든 튜토리얼의 1단계다.3 osmWebWizard.pyOpenStreetMap 영역을 브라우저에서 드래그하면 netconvert + randomTrips + 설정 파일 생성까지 한 번에 해 준다 — 처음 만져 볼 때 5분 안에 자기 동네가 돌아가는 것을 보게 되는 이유다.

다만 OSM 임포트 결과를 그대로 믿으면 안 된다. 교차로 형상, 회전 금지, 차로 수, 신호 프로그램은 OSM 태그가 부실한 곳에서 추정으로 채워지고, 그 추정이 틀리면 없는 병목이 생기거나 있는 병목이 사라진다. netedit 으로 대상 교차로를 직접 확인하는 것이 정식 절차다.

5. 파일 구조[편집]

전부 XML 이다. 손으로 읽히고 diff 가 되고 스크립트로 생성하기 쉽다는 게 장점이고, 대규모 시나리오에서 파일이 수백 MB 로 부푼다는 게 단점이다.

  • 네트워크. 평문 입력은 .nod.xml(노드) · .edg.xml(링크) · .con.xml(연결) · .typ.xml(도로 유형) 네 개로 나뉘고, netconvert 가 이걸 물어 .net.xml 하나로 굽는다. 구워진 .net.xml 에는 교차로 내부 차로(internal lane), 우선권 관계, 신호 논리가 전부 전개돼 들어가므로 사람이 손으로 편집할 물건이 아니다.
  • 수요. .rou.xmlvType(차종 — 여기에 carFollowModel, accel, decel, sigma, tau, length 등이 붙는다), route(엣지 나열), vehicle/flow(언제 몇 대) 를 담는다.
  • 부가물. .add.xml 에 검지기(E1 유도루프 · E2 구간 · E3 다지점), 정류장, 가변속도표지, 신호 프로그램 재정의를 넣는다.
  • 설정. .sumocfg 가 위 파일들과 시뮬레이션 시간·스텝·출력 옵션을 묶는다. 재현성을 위해 난수 시드(--seed)를 여기 명시해 두는 것이 좋다.
  • 출력. --tripinfo-output(통행별 요약), --fcd-output(매 스텝 전 차량의 위치·속도 — 파일이 순식간에 GB 로 간다), --summary-output, --emission-output, 검지기별 집계 파일. 후처리 스크립트도 배포판에 같이 들어 있다.

6. 수요를 균형으로 — duaIterate[편집]

duarouter비어 있는 네트워크의 최단경로를 준다. 혼잡을 반영하지 않으므로 그대로 쓰면 모두가 같은 길로 몰린다. 그래서 배포판의 duaIterate.py 가 반복을 돌린다 — 시뮬레이션을 한 번 돌려 링크별 실제 통행시간을 뽑고, 그 통행시간으로 경로를 다시 계산하고, 다시 돌린다. 경로 선택 확률 갱신에는 가브론(1998)의 로짓 형태 갱신 규칙을 쓴다.

이건 워드롭 균형을 방정식으로 푸는 것이 아니라 날짜 반복(day-to-day)으로 근사하는 것이다. 성질을 정직하게 적으면 이렇다.

  • 수렴 보장이 없다. 프랭크-울프의 선탐색 같은 이론적 장치가 없고, 진동하거나 시드에 따라 다른 곳에 정착할 수 있다.
  • 수렴 판정을 직접 해야 한다. 반복 사이 통행시간 변화나 경로 전환율을 스스로 보고 멈춰야 하며, “50번 돌렸다”는 재현 가능한 정보가 아니다.
  • 비싸다. 미시 시뮬레이션 한 번이 반복 한 번이므로, 도시 규모에서는 앞서 말한 메조 모드나 marouter 로 대체하는 것이 정석이다.

바꿔 말하면, 고정밀 균형이 목적이라면 SUMO 는 잘못된 도구다. 그건 교통 배정의 기점기반 알고리즘이 할 일이고, SUMO 는 균형이 아니라 동역학을 보려고 쓰는 것이다.

7. TraCI 와 libsumo[편집]

SUMO 를 특별하게 만든 것은 TraCI(Traffic Control Interface)다. SUMO 가 TCP 서버로 뜨고 외부 클라이언트가 스텝을 하나씩 진행시키면서 값을 읽고 쓴다. 파이썬 클라이언트가 표준이며 골격은 이 정도다.

traci.start(["sumo", "-c", "scenario.sumocfg"])
while traci.simulation.getMinExpectedNumber() > 0:
    traci.simulationStep()
    q = traci.lanearea.getLastStepVehicleNumber("det_0")
    if q > 10:
        traci.trafficlight.setPhase("J1", 2)
traci.close()

차량 속도·경로·색을 바꾸고, 신호 위상을 강제하고, 차량을 새로 넣고 지우고, 엣지의 통행비용을 조작하는 것까지 전부 된다. 시뮬레이터를 환경으로, 외부 코드를 정책으로 두는 구조강화 학습 실험과 궁합이 완벽하고, 실제로 신호 제어 RL 논문의 압도적 다수가 SUMO 위에서 돌아간다.

대가는 성능이다. TCP 왕복이 스텝마다 발생하므로 큰 네트워크에서 매 스텝 수천 개 객체를 조회하면 통신이 시뮬레이션보다 오래 걸리는 상황이 온다.4 그래서 두 가지 대안이 있다.

  • libsumo — SUMO 를 라이브러리로 직접 링크해 같은 API 를 C++ 정적 함수로 노출한다. import libsumo as traci 한 줄로 갈아 끼울 수 있고 훨씬 빠르다. 대신 프로세스가 하나로 합쳐지므로 GUI 와 다중 클라이언트를 못 쓴다.
  • libtraci — libsumo 와 같은 C++ API 를 제공하되 내부적으로는 TraCI 프로토콜로 통신한다. 다중 클라이언트와 GUI 를 유지하면서 언어 바인딩을 통일하고 싶을 때 쓴다.

개발은 TraCI + GUI 로, 대량 실행은 libsumo 로 가 국룰이다. 한 가지 함정 — libsumo 는 예외 처리와 오류 메시지가 TraCI 만큼 친절하지 않아서, 잘 돌던 스크립트가 갈아 끼우자마자 조용히 죽는 일이 있다.

8. 쓰임새와 결합[편집]

  • 신호 제어. 고정 주기·감응식(actuated)·지연 기반(delay_based) 제어기가 내장돼 있고, TraCI 로 임의의 제어 논리를 얹을 수 있다. 강화 학습 기반 신호 제어의 사실상 표준 벤치마크 환경.
  • V2X·통신 연구. OMNeT++ 와 SUMO 를 TraCI 로 묶는 Veins 프레임워크가 대표적이다. 통신 지연이 차량 거동에 영향을 주고 그 거동이 다시 통신 토폴로지를 바꾸는 양방향 결합이 핵심이며, 한쪽만 시뮬레이션해서는 잡을 수 없는 효과들이 여기서 나온다.
  • 자율주행·ACC. ACC/CACC 추종 모형과 군집주행(platooning) 확장으로 자율주행 침투율에 따른 용량 변화를 본다. CARLA 같은 고충실도 주행 시뮬레이터와 공동 시뮬레이션해 “주변 교통은 SUMO, 자차 센서는 CARLA” 식으로 나누는 구성도 흔하다.
  • 배출가스. HBEFA 기반 모형과 PHEMlight 로 차량별 순간 배출량을 적산한다. 가감속 프로파일이 배출량을 지배하므로 이 용도에서는 시간 간격을 반드시 1초 아래로 내려야 한다.
  • 보행자·대중교통. 보행자 striping 모형, 버스·지하철 노선과 환승, 자전거·철도·선박까지 다룬다. 그래서 이름이 “urban mobility” 이지 “traffic” 이 아니다.

9. 실무에서 조심할 것[편집]

  • 시드를 여러 개 돌려라. sigma, 차량 투입 시각, 경로 선택이 전부 확률적이다. 단일 실행 결과로 두 시나리오를 비교하는 것은 몬테카를로 방법의 표본 하나로 결론을 내리는 것과 같다.
  • 투입 적체(insertion backlog)를 확인하라. 진입 지점이 막혀 차량이 예정대로 못 들어가면 SUMO 는 경고만 내고 계속 돌아간다. 이걸 놓치면 네트워크에 들어오지도 못한 수요를 처리했다고 착각한 채 통행시간을 보고하게 된다.
  • --step-length 를 목적에 맞춰라. 정체 길이만 볼 거면 1초로 충분하고, 배출량·충돌대리지표·가감속을 볼 거면 0.1초가 필요하다. 기본값을 그대로 둔 채 가속도 통계를 뽑은 결과는 대개 못 쓴다.
  • vType 을 기본값으로 두지 마라. 기본 차량은 길이 5 m, 최고속도 200 km/h 짜리 승용차다. 화물차 비율·차종 구성을 안 넣으면 용량이 낙관적으로 나온다.
  • OSM 네트워크는 반드시 검수하라. 앞서 말한 대로 교차로 우선권과 신호가 추정으로 채워진다. 결과가 이상하면 솔버가 아니라 네트워크를 먼저 의심하는 것이 순서다.
  • 미시 시뮬레이션은 균형 솔버가 아니다. 반복 배정 결과를 정밀 균형처럼 인용하면 안 된다. 그 목적에는 교통 배정의 전용 알고리즘을, 정책 요금 설계에는 혼잡통행료의 이단계 구조를 쓰고, SUMO 는 그 결과를 동역학으로 검증하는 단계에 배치하는 것이 맞다.

10. 관련 문서[편집]

11. Footnotes[편집]

  1. 이름이 “Simulation of Urban MObility” 라서 대문자가 S·U·MO 로 튀는데, 약자를 SUMO 로 만들려고 끼워 맞춘 티가 난다. 덕분에 검색창에 SUMO 를 치면 씨름이 먼저 나오고, 그래서 이 바닥 사람들은 습관적으로 “sumo traffic” 이라고 친다.

  2. EPL 로 바뀐 것이 실무에서 의미가 큰 이유는 GPL 의 전염성 때문이다. SUMO 를 라이브러리로 링크해 사내 제품에 넣으려는 쪽에서는 이 한 줄이 도입 가부를 갈랐다. 라이선스는 기능이 아니지만 채택률에는 기능보다 크게 작용한다.

  3. randomTrips.py 로 뿌린 무작위 수요는 아무 현실성이 없다. 그런데도 이걸로 만든 시나리오가 논문 실험 절에 그대로 실리는 경우가 적지 않다. “네트워크는 실제 도시, 수요는 균등 난수”라는 조합은 실제 도시에서 관측되는 방향별 첨두를 통째로 지워 버린다. 튜토리얼 도구는 튜토리얼까지만.

  4. TraCI 로 매 스텝 전 차량을 조회하는 코드를 짜 놓고 “SUMO 가 느리다”고 하는 것은 거의 통과의례다. 필요한 객체만 구독(subscription) API 로 걸어 두면 통신량이 크게 줄어드는데, 문서가 그걸 뒤쪽에서 다루기 때문에 대부분 나중에 알게 된다.