RealSim SUMO documentation
Contacts
Yunli Shao
realsimxil@gmail.com
Table of Contents
Simulation Setups
Select the message data fields, ip address and port of the TrafficLayer, vehicle id of interest in the config.yaml. In this example, vehicle id ‘vehicle_0’ is selected, ip address is ‘127.0.0.1’, port is 420.
# Global Simulation setup
SimulationSetup:
# Master Switch to turn on/off RealSim interface
# if turned off, VISSIM will just run without RealSim
# SUMO needs to run without traci
EnableRealSim: true
# Whether or not to save verbose log during the simulation. skip log can potentially speed up
EnableVerboseLog: false
# Simulation end time
# if NOT specificed, SimulationEndTime will be set to a large value (90000 seconds)
#--------------------------------------------------
#SimulationEndTime: 1800
# specify which traffic simulator
#--------------------------------------------------
SelectedTrafficSimulator: 'SUMO'
# default will send all
VehicleMessageField: [id, type, speed, acceleration, positionX, positionY, positionZ, color, linkId, laneId, distanceTravel, speedDesired]
# by default it is false
EnableExternalDynamics: true
# ip and port are server ip and port
# setup Application Layer
ApplicationSetup:
# turn on/off application layer
EnableApplicationLayer: false
#--------------------------------------------------
VehicleSubscription:
# subscription in XilSetup must be subset of ApplicationSetup
XilSetup:
# enable/disable XIL
EnableXil: true
#--------------------------------------------------
VehicleSubscription:
- type: ego
attribute: {id: ['vehicle_0'], radius: [0]}
ip: ["127.0.0.1"]
port: [420]
Create a batch file to run. Launch of the TrafficLayer.exe can be within this batch file or within matlab script, see next step.
start sumo -c .\osm.sumocfg --remote-port 1337 --step-length 0.1 --start --netstate-dump osm_out.xml --netstate-dump.precision 5 --num-clients 1
:: can start TrafficLayer.exe here or in matlab script
::start cmd /k ..\..\realsimrelease\TrafficLayer.exe -f config_SUMOdriver.yaml
Create a runSumo.m matlab script to specify the RealSim library folder, yaml configuration file, and simulink model. Then call the batch script to launch SUMO and start TrafficLayer.exe. Then initialize simulink using RealSimInitSimulink and start Simulink.
% initialization of vehicle data subscription setup before runnning any
% simulink files. A config.yaml needs to present to read the vehicle data
% subscription setup.
close all;clear all;clc;format compact;
%% Initializations
RealSimPath = '..\..\CommonLib';
configFilename = '.\config_SUMOdriver.yaml';
stopTime = 250; % simulation stop time in seconds. co-simulation will automatically stop after this seconds
simModelName = 'sumoDriverClient';
%% add path of RealSim tools
addpath(genpath(RealSimPath))
%% Run Batch Scripts
system("runSUMOdriver.bat")
system(['start cmd /c ..\..\TrafficLayer\x64\Release\TrafficLayer.exe -f ', sprintf('%s', configFilename)])
%% Initialize RealSim for Simulink, Read yaml file
[VehicleMessageFieldDefInputVec, VehDataBus, TrafficLayerIP, TrafficLayerPort] = RealSimInitSimulink(configFilename);
RealSimPara = struct;
RealSimPara.speedInit = 0; % initial speed of the ego vehicle when entering SUMO network
RealSimPara.tLookahead = 0.1; % use 0.1 for exteranl control, recommend to use tLookahead >= 0.2 for SUMO driver
RealSimPara.smoothWindow = 1; % number of moving average data point, 1 essentially mean no moving average
RealSimPara.speedSource = 2; % select sine wave for tracking
%% RealSim Start Procedure
tic
% start simulink model
% !!! specify the followings:
% 1) simulink model name
% 2) stopTime of the simulink model
load_system(simModelName)
set_param(simModelName,'StopTime',num2str(stopTime));
% set_param(simModelName, 'SimulationCommand', 'start');
VehicleOut = sim(simModelName); % alternatively can use 'sim' command
sim_time = toc
Specific Features for SUMO Co-simulation
Speed Limit
In SUMO, speed limit can be specified on the entire edge or on a lane of an edge. Real-Sim supports retrieving speed limit of both implementations.
Junctions in SUMO can be assigned a different speed limit than edges connecting to them. Currently Real-Sim will neglect any speed limit specified on junctions.
In SUMO, different vehicle types can have different speed limit, which is not currently supported by Real-Sim.
For next speed limit, if multiple lanes have different speed limits, Real-Sim will return any of the speed limits since it does not know which lane the ego vehicle will drive ahead of time.
If route of the ego is changed during simulation, then the speed limit information from Real-Sim may not reflect the latest route.
Preceding Vehicle
Real-Sim will only consider any vehicle within 1000 meters radius of the ego vehicle as the lead vehicle/preceding vehicle. In the future, this radius will be a parameter that can be changed in config.yaml
Multiple Clients
SUMO natively supports multiple TraCI clients. So Real-Sim can be used by another application, e.g., a python script, together with SUMO. The following shows an example to run a python script together with Real-Sim
in the runSumo.bat, specify to have total of 2 clients. Both the python script and Real-Sim will connect to SUMO through port 1337
start sumo-gui -c .\speedLimit.sumocfg --remote-port 1337 --step-length 0.1 --start --num-clients 2
inside python script, connects to the SUMO, assuming it is running at localhost IP address 127.0.0.1. Note since we started SUMO from the runSumo.bat, here we call
traci.initrather thantraci.start. Also, notetraci.setOrderis mandatory for multiple TraCI clients. By default, Real-Sim will always be order 1, so python script have to be in order >= 2
PORT = int(1337)
traci.init(PORT,host="localhost")
traci.setOrder(2)
#....
# more traci commands
#....
There should be no need to modify anything on the Real-Sim side. In the future, the setOrder of Real-Sim can be one argument user can change in the yaml. For more information, check the following screenshots from SUMO documentation
https://sumo.dlr.de/docs/TraCI.html
https://sumo.dlr.de/docs/TraCI/Interfacing_TraCI_from_Python.html

SumoSetup in config.yaml
In the config.yaml, there is a section that can define specific settings for SUMO simulation. For example:
SumoSetup:
# set the speed mode, in integer. default value is 0
# check Sumo documentation https://sumo.dlr.de/docs/TraCI/Change_Vehicle_State.html#speed_mode_0xb3
SpeedMode: 32
The SpeedMode is an integer defines behavior of SetSpeed command of SUMO TraCI API. More parameters can be included in SumoSetup for future releases.
Performance & TraCI transport (libtraci vs libsumo)
Notes from the #177 investigation (measured, June 2026). Detailed data + reusable benchmark harnesses live in
tests/Sumo/Probes/TrafficLayer_SUMO_CMoffice/PERF_177_TRACI.md.
Which transport the build uses
CommonLib/TrafficHelper.h leaves ENABLE_LIBSUMO commented out, so the build
compiles the libtraci namespace — the socket TraCI client. TrafficLayer
therefore talks to a separate sumo/sumo-gui process over TCP (see
run_sumo_cm_demo.bat: sumo-gui --remote-port ...). The alternative, libsumo,
embeds SUMO in-process (no socket). The #ifdef is already in the header, so it is
a per-build choice.
Measured cost difference (SUMO 1.21, simple_loop, 36 veh):
per single getter call |
bulk subscription (1 call/step, all veh) |
|
|---|---|---|
libtraci (socket) |
~78 µs (TCP round-trip) |
~150 µs/step transport penalty |
libsumo (in-process) |
~0.3 µs |
baseline |
Implication: libsumo only wins big against per-call patterns (one TraCI getter per vehicle per step). For a single bulk context subscription the socket penalty is only ~150 µs/step. So the fix for slow SUMO co-sim is to stop making per-vehicle individual TraCI calls (fold data into the subscription / cache it), not to switch transport. After that, libtraci ≈ libsumo and you keep the GUI.
#177 root cause (slow SUMO↔CarMaker co-sim)
The dominant per-step cost was Vehicle::getNextTLS(vehID) called per traffic
vehicle per step in TrafficHelper::parserSumoSubscription (≈ 2.5 ms/veh →
~90 ms/step at 36 veh, RTF ≈ 1.1). It is not the context-subscription variable
list (that is ~free). getNextTLS is O(upcoming-route length); the SimpleLoop demand
uses repeat="100000" (~400 k-edge route) so it walks the whole thing. The data it
produces (signalLight*) is not even sent unless a signalLight* field is in
VehicleMessageField. Same for getLeader/getSpeed (→ precedingVehicle*). VISSIM
is immune because the DSProxy path makes zero per-vehicle TraCI calls.
Why you cannot have libsumo + sumo-gui on Windows
libsumo cannot drive sumo-gui on Windows — confirmed at the SUMO source level
(src/libsumo/GUI.cpp, a hard #ifdef WIN32 { WRITE_WARNING("Libsumo on Windows does not work with GUI, falling back to plain libsumo."); return false; }), present on the
latest main and unchanged through 1.27. Reason: libsumo drives the GUI incrementally
from the simulation/client thread instead of FOX’s blocking main-thread event loop,
and FOX windows are thread-affine (“FOX really likes to work in the main thread”) —
Win32’s window/message model doesn’t tolerate that, so it is hard-disabled (X11/Linux is
“highly experimental” but works). A separately-launched sumo-gui cannot attach to an
in-process libsumo sim (no server socket; it would be a different simulation). SUMO’s
planned FOX→Qt migration (issue eclipse-sumo/sumo#311) has been backlogged since
2010, so do not count on it.
Practical guidance: keep libtraci + sumo-gui for interactive/demo runs (GUI,
real-time once the per-vehicle calls are fixed); use libsumo headless only for
max-throughput batch runs, where CarMaker IPGMovie / Carla already provide the visual.