- Simulation Setups
- Run Simulation Manually
- Run Simulation with Automation Script
- Specific Features for VISSIM Co-simulation
- Debugging
Currently, only compiled VISSIM dll is provided. Detailed instruction on user compiled source code will be provided later.
- 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 '6' is selected, ip address is '127.0.0.1', port is 2333.
# Global Simulation setup
SimulationSetup:
# Master Switch to turn on/off RealSim interface
EnableRealSim: true
# Whether or not to save verbose log during the simulation. skip log can potentially speed up
EnableVerboseLog: true
# specify which traffic simulator
#--------------------------------------------------
SelectedTrafficSimulator: 'VISSIM'
# if not specified, default will be localhost
TrafficSimulatorIP: "127.0.0.1"
# if not specified, default will be 1337
TrafficSimulatorPort: 1337
# default will send all
VehicleMessageField: [id, speed, speedDesired, hasPrecedingVehicle, precedingVehicleDistance, precedingVehicleSpeed, signalLightId, signalLightHeadId, signalLightDistance, signalLightColor, speedLimit, speedLimitNext, speedLimitChangeDistance, heading, linkId, activeLaneChange]
# setup Application Layer
ApplicationSetup:
# turn on/off application layer
EnableApplicationLayer: true
#--------------------------------------------------
VehicleSubscription:
- type: ego
attribute: {id: ['6'], radius: [0]}
ip: ["127.0.0.1"]
port: [2333]
# subscription in XilSetup must be subset of ApplicationSetup
XilSetup:
# enable/disable XIL
EnableXil: false
#--------------------------------------------------
VehicleSubscription:
- Open the VISSIM network file wants to simulate, for all the vehicle types of interest, enable driver model dll, select the RealSimDriverModel.dll and config.yaml.
- Create an empty subdirectory DriverModelData\ in the directory of vissim.exe if it does not exit.
- Start a cmd window, change path to where TrafficLayer.exe locates, then execute as
TrafficLayer.exe -f PATH\CONFIG_FILENAME
, for example,TrafficLayer.exe -f .\config.yaml
- Start the Simulink simulation
- Start VISSIM simulation. It could be a manual click from the VISSIM GUI or from COM interface. If there is any VISSIM pre-simulation setups, it should be executed first (e.g., through COM) before starting the simulation.
- Stop Simulink Simulation manually.
- Stop VISSIM manually.
- The cmd window running TrafficLayer.exe will stop automatically after the first two steps. NOTE: The cmd window might pop an error message which is not indeed an error but part of the shutdown procedure.
Use the main_autoRealSim.m
as the template to build your own automation script applications. The startup order is similar to manual procedure as in section above, i.e.,
- start
TrafficLayer.exe
; - start Simulink application;
- start VISSIM simulation.
main_autoRealSim.m
must call a RealSimInitSimulink.m
script to initialize the vehicle message field specification based on a .yaml configuration file.
main_autoRealSim.m
will start VISSIM through VISSIM COM through a second instance of Matlab. This process is automated and a script startVissim.m
will be executed, use it as the template to setup customized VISSIM simulation.
Make sure modify the main_autoRealSim.m
and startVissim.m
as needed, especially path of programs and simulation files. Below are all snapshots from the main_autoRealSim.m
:
main_autoRealSim.m
- Define simulation stop time, after which co-simulation will automatically stops, e.g., define a variable 'stopTime':
%% Genearl Simulation Setups stopTime = 200; % simulation stop time in seconds. co-simulation will automatically stop after this seconds
- Modify the
RealSimInitSimulink.m
to read the correct .yaml configuration file, then call the script withinmain_autoRealSim.m
:%% Initialize RealSim for Simulink, Read yaml file RealSimInitSimulink
- set the path and configuration file name of the
TrafficLayer.exe
:% start RealSim interface % !!! specify the followings: % 1) path of TrafficLayer.exe % 2) name of .yaml configuration file realSimPath = 'D:\src_ornl\RealSimInterface\'; system(['cd "', realSimPath, '" &; ".\TrafficLayer.exe" -f ".\config.yaml" &']);
- setup second Matlab instance to start VISSIM simulation:
% start Vissim in second Matlab window % this Matlab window will be closed automatically after simulation ends % !!! specify the followings: % 1) path of matlab.exe, % 2) path of VISSIM COM script, % 3) VISSIM COM script name and input arguments system([' "C:\Program Files\MATLAB\R2019a\bin\matlab.exe" -nodesktop -nosplash -r ', ... '"cd(''D:\src_ornl\RealSimInterface\CommonLib''); ', ... sprintf('startVissim(''..\\VISSIMfiles\\VissimNetwork.inpx'', %f); ', stopTime), ... 'quit; " '])
- setup Simulink model to run:
% start simulink model % !!! specify the followings: % 1) simulink model name % 2) stopTime of the simulink model simModelName = 'RealSimTemplate'; load_system(simModelName) set_param(simModelName,'StopTime',num2str(stopTime)); set_param(simModelName, 'SimulationCommand', 'start'); % simout = sim(simModelName); % alternatively can use 'sim' command
Simulation will automatically stop after Simulink model reaches the 'StopTime' (see where this variable can be defined in section above), VISSIM file simulation seconds/periods should be larger or equal to this 'StopTime'. Adjust these simulation stops time as needed.
To automatically close the command window runs TrafficLayer.exe
, need to know the pid of that command window instance then use taskkill
to close it.
-
right after starting
TrafficLayer.exe
, getting pid using:main_autoRealSim.m
% get an image of cmd.exe pid after start a new one pidListPost = getCmdPid(); % get pid of the RealSim interface cmd.exe pidToKill = setdiff(pidListPost, pidListPrior);
where
getCmdPid()
is a function:function pidList = getCmdPid() [~,pidString]=system('tasklist /FI "IMAGENAME eq cmd.exe" /FO LIST | find "PID:"'); pidCell=split(strrep(replace(pidString,newline,''),' ',''), 'PID:'); % remove newline symbol and spaces, split into PID list pidList=cellfun(@str2num,pidCell(2:end-1)); % remove first empty pid and last one (last pid appears to change every time, not sure meaning of it) end
-
uncomment these commands in
main_autoRealSim.m
:main_autoRealSim.m
%% RealSim Shutdown Procedure % !!! uncomment to auto-close TrafficLayer.exe after simulation finishes % kill RealSim cmd.exe if numel(pidToKill) == 1 system(['taskkill /F /PID ', num2str(pidToKill)]); fprintf('TrafficLayer.exe has been killed!\n'); else fprintf('Warning: cannot kill RealSim TrafficLayer.exe, please close it manually\n'); end
Check runRealSim.bat
for an example to run multiple co-simulations simultaneously. A separate configuration .yaml file is needed to configure each co-simulation. The .yaml file now supports two new fields to define IP and Port of the Traffic Simulator (VISSIM):
excerpt of a .yaml file
SimulationSetup:
# if not specified, default will be localhost
TrafficSimulatorIP: "127.0.0.1"
# if not specified, default will be 1337
TrafficSimulatorPort: 1337
ApplicationSetup:
EnableApplicationLayer: true
VehicleSubscription:
- type: ego
attribute: {id: ['6'], radius: [0]}
ip: ["127.0.0.1"]
port: [2333]
The TrafficSimulatorPort
and VehicleSubscription port MUST be different for each co-simulation. The IP can be same or different for each co-simulation.
VISSIM does not provide an out-of-box approach to precisely control just an ego vehicle. The workaround is
-
create a dedicated vehicle type and vehicle class for the ego vehicle
create dedicated vehicle type, id
1000
in this example, do not forget to select external driver model and configuration file:create dedicated vehicle class, id
70
in this example, and assign the vehicle type1000
we define to this vehicle class: -
use COM commands to add that vehicle to VISSIM simulation at a particular simulation on a particular link, lane, and initial speed. When using automation script, the commands shall be part of the
startVissim.m
. Essentially, break VISSIM simulation at the simulation time you want the ego vehicle enters the simulation, start the simulation until it breaks, then add ego vehicle. For example:startVissim.m
% break at XXX seconds to add ego vehicle set(Vissim.Simulation, 'AttValue', 'SimBreakAt', 10); Vissim.Simulation.RunContinuous % add ego vehicle vehicle_type = 1000; % use type specified in the config.yaml desired_speed = 13*2.23694; % unit according to the user setting in Vissim [km/h or mph] link = 6; lane = 3; xcoordinate = 1; % unit according to the user setting in Vissim [m or ft] interaction = true; % please select 'true' egoVehicle = Vissim.Net.Vehicles.AddVehicleAtLinkPosition(vehicle_type, link, lane, xcoordinate, desired_speed, interaction);
-
use the interface to get all vehicle of this particular vehicle type (which essentially the vehicle type only has one vehicle), for example:
config.yaml
VehicleSubscription: - type: vehicleType attribute: {id: ['1000'], radius: [0]} ip: ["127.0.0.1"] port: [2333]
For vehicles that enter the network as part of 'Vehicle Inputs' of VISSIM, the route will be determined by VISSIM and it will NOT follow external lane change command if it must make a left or right turn due to its route. If want to let one ego vehicle always go straight in VISSIM, the workaround is as the follows:
-
Define a specific vehicle type and vehicle class for that ego vehicle, following steps as section above
-
Make exemption for that particular vehicle class from all 'static route decisions'. The
setVissimStaticRouteExemption.py
is an example script showing how to do it programmatically. You do need to make changes based on the specific vehicle class id and VISSIM files to use. Say the particular ego vehicle class is with id70
, Figure below shows what it should look like in VISSIM after this vehicle class exempted from 'static route decisions'.NOTE: VISSIM manual says that if using command
Vissim.Net.Vehicles.AddVehicleAtLinkPosition
,A vehicle placed this way doesn't travel with a specific path, so it will use only connectors with direction "All" before it passes a routing decision.
. My experience is that it may still make a turn in some cases. This static route exemption approach is more reliable. -
Now can add a 'Go Straight' ego vehicle following steps as section above using VISSIM COM command
Vissim.Net.Vehicles.AddVehicleAtLinkPosition
, the vehicle added will always go straight until exited the VISSIM network.
Before simulation, getVissimNetworkInfo.py needs to be run. Three tables will be generated LinkGeometryTable.csv has the link topology of VISSIM network; DesSpdDistr2SpeedLimitMap.csv has a map from desired speed decisions to speed limit definition; SpeedLimitTable.csv is the actual lookup table for a link, lane, vehicle type to each speed limit point (desired speed decision point).
VISSIM does not have a true speed limit concept, rather, desired speed decisions are used to control the desired speed of each vehicle which equivalent to a speed limit change. Desired speed decisions are not defined as a fixed value but defined using desired speed distributions, essentially a cumulative probability density function. Therefore, users need to assign a corresponding speed limit for each desired speed distribution.
The getVissimNetworkInfo.py will attempt to interpret the speed limit from name of desired speed distributions, but users MUST check the DesSpdDistr2SpeedLimitMap.csv manually to make sure it is correct.
In addition, VISSIM does not have a complete route concept for each vehicle, rather, each vehicle will be assigned a decision at each static route decision point. Hence, it is infeasible to obtain all following routes and links a vehicle will be driven until it travels to each static route decision point. To counter this, users MUST supply a Routes.yaml file to specify routes of vehicles of interest. This Routes.yaml MUST be in the same folder as VISSIM .inpx files. Examples of route definitions (download here):
Routes:
# example route 1
- id: [6]
vehicleType: [100]
link: [1,10002,4,10011,11,10000,2,10001,3]
lane: [3]
initialSpeedLimit: [13.89]
# example route 2
- id: [36]
vehicleType: [100]
link: [1,10002,4,10011,11,10003,6,10007,8,10008,9,10009,10]
lane: [2,2,2,1,1,1,1,1,2,1,1,1,1]
initialSpeedLimit: [13.89]
# example route 3
- vehicleType: [100]
link: [1,10002,4,10011,11,10000,2,10001,3]
lane: [3]
initialSpeedLimit: [13.89]
# example route 4
- id: [3, 5]
vehicleType: [100, 100]
link: [1,10002,4,10011,11,10000,2,10001,3]
lane: [2]
initialSpeedLimit: [13.89]
Notes:
link
andlane
should be vector of same length. The only exception is iflink
is a vector andlane
is a scalar. In this case, it is assumed that the vehicle will stay on the same lane for the entire route. see example route 1 and example route 2. lane is needed since VISSIM definie desired speed decisions with respective to each lane.- if
id
field is omitted, it is assumed that the route is defined for entire vehicle type. This is useful if a dedicated vehicle type is defined for ego CAVs. see example route 3 - if multiple vehicles will travel the same route,
id
andvehicleType
can be a vector holds id and vehicle type of each vehicle on this same route. see example route 4 initialSpeedLimit
is needed to define the speed limit the vehicle is following when first entering the VISSIM network, it should be scalar since each route should have one single initial speed limit. Unit: m/s. see example route 4
Right now only Release version of the dll can work due to missing symbols definitions in the VISSIM internal dll. You will need to open the Visual Studio solution file, make sure you are selecting "Remote Window Debugger" with specified VISSIM executable location. Then start the debugging which will load a VISSIM instance and then you can select the VISSIM simulation file to run. Afterwards, you can debug as usual.