In the previous tutorial, we discussed how OpenStreetMap files can be simulated in Flow. These networks, however, may at time be imperfect, as we can see in the toll section of the Bay Bridge (see the figure below). The simulators SUMO and Aimsun both possess methods for augmenting the network after they have been imported, and store the changes in their own versions of the initial template (whether it was generated via a custom scenario class or a network imported from OpenStreetMap). In order to utilize these newly generated networks, we demonstrate in this tutorial how simulator-generated template files can be imported when running a simulation in Flow.
The remainder of the tutorial is organized as follows. In section 1, we begin by importing the classic set of parameters. In section 2, we introduce the template files that are used as examples for importing the template files. In section 3, we present how custom SUMO network templates, i.e. the generated .net.xml files, can be modified and simulated in Flow for the purposed of improving network features. Finally, in section 4, we demonstrate how custom Aimsun network files can be simulated in Flow.
Before we begin, let us import all relevant Flow parameters as we have done for previous tutorials. If you are unfamiliar with these parameters, you are encouraged to review tutorial 1.
In [1]:
# the TestEnv environment is used to simply simulate the network
from flow.envs import TestEnv
# the Experiment class is used for running simulations
from flow.core.experiment import Experiment
# the base scenario class
from flow.scenarios import Scenario
# all other imports are standard
from flow.core.params import VehicleParams
from flow.core.params import NetParams
from flow.core.params import InitialConfig
from flow.core.params import EnvParams
# create some default parameters parameters
env_params = EnvParams()
initial_config = InitialConfig()
vehicles = VehicleParams()
vehicles.add('human', num_vehicles=1)
In this tutorial, we use the Luxembourg SUMO Traffic (LuST) Scenario as an example use case. This example consists of a well-calibrated model of vehicles in Luxembourg. A representation of the simulation can be seen in the figure below.
Before, continuing with this tutorial, please begin by cloning the LuST scenario repository by running the following command.
git clone https://github.com/lcodeca/LuSTScenario.git
Once you have cloned the repository, please modify the code snippet below to match correct location of the repository's main directory.
In [2]:
LuST_dir = "/home/aboudy/LuSTScenario"
Sumo generates several network and simulation-specifc template files prior to starting a simulation. This procedure when creating custom scenarios and scenarios from OpenStreetMap is covered by the scenario class. Three of these files (*.net.xml, *.rou.xml, and vtype.add.xml) can be imported once again via the scenario class to recreate a previously decided scenario.
We start by creating the simulation parameters:
In [3]:
from flow.core.params import SumoParams
sim_params = SumoParams(render=True, sim_step=1)
In [4]:
import os
net_params = NetParams(
template=os.path.join(LuST_dir, "scenario/lust.net.xml"),
)
This network alone, similar to the OpenStreetMap file, does not cover the placement of vehicles or the routes vehicles can traverse. These, however, can be defined a they were in the previous tutorial for importing networks from OpenStreetMap. For the LuST network, this looks something similar to the following code snippet (note that the specific edges were not spoken for any specific reason).
In [5]:
# specify the edges vehicles can originate on
initial_config = InitialConfig(
edges_distribution=["-32410#3"]
)
# specify the routes for vehicles in the network
class TemplateScenario(Scenario):
def specify_routes(self, net_params):
return {"-32410#3": ["-32410#3"]}
The simulation can then be executed as follows:
In [6]:
# create the scenario
scenario = TemplateScenario(
name="template",
net_params=net_params,
initial_config=initial_config,
vehicles=vehicles
)
# create the environment
env = TestEnv(
env_params=env_params,
sim_params=sim_params,
scenario=scenario
)
# run the simulation for 1000 steps
exp = Experiment(env=env)
_ = exp.run(1, 1000)
Sumo templates will at times contain files other than the network templates that can be used to specify the positions, speeds, and properties of vehicles at the start of a simulation, as well as the departure times of vehicles while the scenario is running and the routes that all these vehicles are meant to traverse. All these files can also be imported under the template
attribute in order to recreate the simulation in it's entirety.
When incorporating files other that the net.xml file to the simulation, the template attribute is treated as a dictionary instead, with a different element for each of the additional files that are meant to be imported. Starting with the net.xml file, it is added to the template attribute as follows:
In [7]:
new_net_params = NetParams(
template={
# network geometry features
"net": os.path.join(LuST_dir, "scenario/lust.net.xml")
}
)
The vehicle types file describing the properties of different vehicle types in the network. These include parameters such as the max acceleration and comfortable deceleration of drivers. This file can be imported via the "vtype" attribute in template.
Note that, when vehicle information is being imported from a template file, the VehicleParams
object does not need be modified, unless you would like additionally vehicles to enter the network as well.
In [8]:
new_net_params = NetParams(
template={
# network geometry features
"net": os.path.join(LuST_dir, "scenario/lust.net.xml"),
# features associated with the properties of drivers
"vtype": os.path.join(LuST_dir, "scenario/vtype.add.xml")
}
)
# we no longer need to specify anything in VehicleParams
new_vehicles = VehicleParams()
Next, the routes can be imported from the *.rou.xml files that are generated by SUMO. These files help define which cars enter the network at which point in time, whether it be at the beginning of a simulation or some time during it run. The route files are passed to the "rou" key in the templates attribute. Moreover, since the vehicle routes can be spread over multiple files, the "rou" key that a list of string filenames.
In [9]:
new_net_params = NetParams(
template={
# network geometry features
"net": os.path.join(LuST_dir, "scenario/lust.net.xml"),
# features associated with the properties of drivers
"vtype": os.path.join(LuST_dir, "scenario/vtypes.add.xml"),
# features associated with the routes vehicles take
"rou": [os.path.join(LuST_dir, "scenario/DUARoutes/local.0.rou.xml"),
os.path.join(LuST_dir, "scenario/DUARoutes/local.1.rou.xml"),
os.path.join(LuST_dir, "scenario/DUARoutes/local.2.rou.xml")]
}
)
# we no longer need to specify anything in VehicleParams
new_vehicles = VehicleParams()
In [ ]:
# create the scenario
scenario = Scenario(
name="template",
net_params=new_net_params,
vehicles=new_vehicles
)
# create the environment
env = TestEnv(
env_params=env_params,
sim_params=sim_params,
scenario=scenario
)
# run the simulation for 100000 steps
exp = Experiment(env=env)
_ = exp.run(1, 100000)
Flow can run templates that have been created in Aimsun and saved into an *.ang file. Although it is possible to have control over the network, for instance add vehicles and monitor them directly from Flow, this tutorial only covers how to run the network.
We will use the template located at tutorials/networks/test_template.ang
, which looks like this:
test_template.ang
in AimsunIt contains two input and three output centroids that define the centroid configuration Centroid Configuration 910
. The inflows are defined by two OD matrices, one for the type Car
(in blue), the other for the type rl
(in red). Note that there is no learning in this tutorial so the two types both act as regular cars. The two OD matrices form the traffic demand Traffic Demand 925
that is used by the scenario Dynamic Scenario 927
. Finally, the experiment Micro SRC Experiment 928
and the replication Replication 930
are created, and we will run this replication in the following.
First, we create the Aimsun-specific simulation parameters:
In [ ]:
from flow.core.params import AimsunParams
sim_params = AimsunParams(
sim_step=0.1,
render=True,
emission_path='data',
replication_name="Replication 930",
centroid_config_name="Centroid Configuration 910"
)
As you can see, we need to specify the name of the replication we want to run as well as the centroid configuration that is to be used. There is an other optional parameter, subnetwork_name
, that can be specified if only part of the network should be simulated. Please refer to the documentation for more information.
The template can then be imported as follows:
In [ ]:
import os
import flow.config as config
net_params = NetParams(
template=os.path.join(config.PROJECT_PATH,
"tutorials/networks/test_template.ang")
)
Finally, we can run the simulation by specifying 'aimsun'
as the simulator to be used:
In [ ]:
scenario = Scenario(
name="template",
net_params=net_params,
initial_config=initial_config,
vehicles=vehicles
)
env = TestEnv(
env_params,
sim_params,
scenario,
simulator='aimsun'
)
exp = Experiment(env)
exp.run(1, 1000)