<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Tutorial 01
Step1:  This scenario, as well as all other scenarios in Flow, is parametrized by the following arguments
Step2:  2.2 VehicleParams
The VehicleParams class stores state information on all vehicles in the network. This class is used to identify the dynamical behavior of a vehicle and whether it is controlled by a reinforcement learning agent. Morover, information pertaining to the observations and reward function can be collected from various get methods within this class.
The initial configuration of this class describes the number of vehicles in the network at the start of every simulation, as well as the properties of these vehicles. We begin by creating an empty VehicleParams object.
Step3:  Once this object is created, vehicles may be introduced using the add method. This method specifies the types and quantities of vehicles at the start of a simulation rollout. For a description of the various arguements associated with the add method, we refer the reader to the following documentation (VehicleParams.add).
When adding vehicles, their dynamical behaviors may be specified either by the simulator (default), or by user-generated models. For longitudinal (acceleration) dynamics, several prominent car-following models are implemented in Flow. For this example, the acceleration behavior of all vehicles will be defined by the Intelligent Driver Model (IDM) [2].
Step4:  Another controller we define is for the vehicle's routing behavior. For closed network where the route for any vehicle is repeated, the ContinuousRouter controller is used to perpetually reroute all vehicles to the initial set route.
Step5:  Finally, we add 22 vehicles of type "human" with the above acceleration and routing behavior into the Vehicles class.
Step6:  2.3 NetParams
NetParams are network-specific parameters used to define the shape and properties of a network. Unlike most other parameters, NetParams may vary drastically depending on the specific network configuration, and accordingly most of its parameters are stored in additional_params. In order to determine which additional_params variables may be needed for a specific scenario, we refer to the ADDITIONAL_NET_PARAMS variable located in the scenario file.
Step7:  Importing the ADDITIONAL_NET_PARAMS dict from the ring road scenario, we see that the required parameters are
Step8:  2.4 InitialConfig
InitialConfig specifies parameters that affect the positioning of vehicle in the network at the start of a simulation. These parameters can be used to limit the edges and number of lanes vehicles originally occupy, and provide a means of adding randomness to the starting positions of vehicles. In order to introduce a small initial disturbance to the system of vehicles in the network, we set the perturbation term in InitialConfig to 1m.
Step9:  2.5 TrafficLightParams
TrafficLightParams are used to describe the positions and types of traffic lights in the network. These inputs are outside the scope of this tutorial, and instead are covered in exercise06_traffic_lights.ipynb. For our example, we create an empty TrafficLightParams object, thereby ensuring that none are placed on any nodes.
Step10:  3. Setting up an Environment
Several envionrments in Flow exist to train autonomous agents of different forms (e.g. autonomous vehicles, traffic lights) to perform a variety of different tasks. These environments are often scenario or task specific; however, some can be deployed on an ambiguous set of scenarios as well. One such environment, AccelEnv, may be used to train a variable number of vehicles in a fully observable network with a static number of vehicles.
Step11:  Although we will not be training any autonomous agents in this exercise, the use of an environment allows us to view the cumulative reward simulation rollouts receive in the absence of autonomy.
Envrionments in Flow are parametrized by three components
Step12:  3.2 EnvParams
EnvParams specify environment and experiment-specific parameters that either affect the training process or the dynamics of various components within the scenario. Much like NetParams, the attributes associated with this parameter are mostly environment specific, and can be found in the environment's ADDITIONAL_ENV_PARAMS dictionary.
Step13:  Importing the ADDITIONAL_ENV_PARAMS variable, we see that it consists of only one entry, "target_velocity", which is used when computing the reward function associated with the environment. We use this default value when generating the EnvParams object.
Step14:  4. Setting up and Running the Experiment
Once the inputs to the scenario and environment classes are ready, we are ready to set up a Experiment object.
Step15:  These objects may be used to simulate rollouts in the absence of reinforcement learning agents, as well as acquire behaviors and rewards that may be used as a baseline with which to compare the performance of the learning agent. In this case, we choose to run our experiment for one rollout consisting of 3000 steps (300 s).
Note
Step16:  As we can see from the above simulation, the initial perturbations in the network instabilities propogate and intensify, eventually leading to the formation of stop-and-go waves after approximately 180s.
5. Visualizing Post-Simulation
Once the simulation is done, a .xml file will be generated in the location of the specified emission_path in SumoParams (assuming this parameter has been specified) under the name of the scenario. In our case, this is
Step17:  The .xml file contains various vehicle-specific parameters at every time step. This information is transferred to a .csv file if the convert_to_csv parameter in exp.run() is set to True. This file looks as follows
<ASSISTANT_TASK:>
Python Code:
from flow.scenarios.loop import LoopScenario
Explanation: Tutorial 01: Running Sumo Simulations
This tutorial walks through the process of running non-RL traffic simulations in Flow. Simulations of this form act as non-autonomous baselines and depict the behavior of human dynamics on a network. Similar simulations may also be used to evaluate the performance of hand-designed controllers on a network. This tutorial focuses primarily on the former use case, while an example of the latter may be found in exercise07_controllers.ipynb.
In this exercise, we simulate a initially perturbed single lane ring road. We witness in simulation that as time advances the initially perturbations do not dissipate, but instead propagates and expands until vehicles are forced to periodically stop and accelerate. For more information on this behavior, we refer the reader to the following article [1].
1. Components of a Simulation
All simulations, both in the presence and absence of RL, require two components: a scenario, and an environment. Scenarios describe the features of the transportation network used in simulation. This includes the positions and properties of nodes and edges constituting the lanes and junctions, as well as properties of the vehicles, traffic lights, inflows, etc. in the network. Environments, on the other hand, initialize, reset, and advance simulations, and act the primary interface between the reinforcement learning algorithm and the scenario. Moreover, custom environments may be used to modify the dynamical features of an scenario.
2. Setting up a Scenario
Flow contains a plethora of pre-designed scenarios used to replicate highways, intersections, and merges in both closed and open settings. All these scenarios are located in flow/scenarios. In order to recreate a ring road network, we begin by importing the scenario LoopScenario.
End of explanation
name = "ring_example"
Explanation: This scenario, as well as all other scenarios in Flow, is parametrized by the following arguments: 
* name
* vehicles
* net_params
* initial_config
* traffic_lights
These parameters allow a single scenario to be recycled for a multitude of different network settings. For example, LoopScenario may be used to create ring roads of variable length with a variable number of lanes and vehicles.
2.1 Name
The name argument is a string variable depicting the name of the scenario. This has no effect on the type of network created.
End of explanation
from flow.core.params import VehicleParams
vehicles = VehicleParams()
Explanation: 2.2 VehicleParams
The VehicleParams class stores state information on all vehicles in the network. This class is used to identify the dynamical behavior of a vehicle and whether it is controlled by a reinforcement learning agent. Morover, information pertaining to the observations and reward function can be collected from various get methods within this class.
The initial configuration of this class describes the number of vehicles in the network at the start of every simulation, as well as the properties of these vehicles. We begin by creating an empty VehicleParams object.
End of explanation
from flow.controllers.car_following_models import IDMController
Explanation: Once this object is created, vehicles may be introduced using the add method. This method specifies the types and quantities of vehicles at the start of a simulation rollout. For a description of the various arguements associated with the add method, we refer the reader to the following documentation (VehicleParams.add).
When adding vehicles, their dynamical behaviors may be specified either by the simulator (default), or by user-generated models. For longitudinal (acceleration) dynamics, several prominent car-following models are implemented in Flow. For this example, the acceleration behavior of all vehicles will be defined by the Intelligent Driver Model (IDM) [2].
End of explanation
from flow.controllers.routing_controllers import ContinuousRouter
Explanation: Another controller we define is for the vehicle's routing behavior. For closed network where the route for any vehicle is repeated, the ContinuousRouter controller is used to perpetually reroute all vehicles to the initial set route.
End of explanation
vehicles.add("human",
             acceleration_controller=(IDMController, {}),
             routing_controller=(ContinuousRouter, {}),
             num_vehicles=22)
Explanation: Finally, we add 22 vehicles of type "human" with the above acceleration and routing behavior into the Vehicles class.
End of explanation
from flow.scenarios.loop import ADDITIONAL_NET_PARAMS
print(ADDITIONAL_NET_PARAMS)
Explanation: 2.3 NetParams
NetParams are network-specific parameters used to define the shape and properties of a network. Unlike most other parameters, NetParams may vary drastically depending on the specific network configuration, and accordingly most of its parameters are stored in additional_params. In order to determine which additional_params variables may be needed for a specific scenario, we refer to the ADDITIONAL_NET_PARAMS variable located in the scenario file.
End of explanation
from flow.core.params import NetParams
net_params = NetParams(additional_params=ADDITIONAL_NET_PARAMS)
Explanation: Importing the ADDITIONAL_NET_PARAMS dict from the ring road scenario, we see that the required parameters are:
length: length of the ring road
lanes: number of lanes
speed: speed limit for all edges
resolution: resolution of the curves on the ring. Setting this value to 1 converts the ring to a diamond.
At times, other inputs may be needed from NetParams to recreate proper network features/behavior. These requirements can be founded in the scenario's documentation. For the ring road, no attributes are needed aside from the additional_params terms. Furthermore, for this exercise, we use the scenario's default parameters when creating the NetParams object.
End of explanation
from flow.core.params import InitialConfig
initial_config = InitialConfig(spacing="uniform", perturbation=1)
Explanation: 2.4 InitialConfig
InitialConfig specifies parameters that affect the positioning of vehicle in the network at the start of a simulation. These parameters can be used to limit the edges and number of lanes vehicles originally occupy, and provide a means of adding randomness to the starting positions of vehicles. In order to introduce a small initial disturbance to the system of vehicles in the network, we set the perturbation term in InitialConfig to 1m.
End of explanation
from flow.core.params import TrafficLightParams
traffic_lights = TrafficLightParams()
Explanation: 2.5 TrafficLightParams
TrafficLightParams are used to describe the positions and types of traffic lights in the network. These inputs are outside the scope of this tutorial, and instead are covered in exercise06_traffic_lights.ipynb. For our example, we create an empty TrafficLightParams object, thereby ensuring that none are placed on any nodes.
End of explanation
from flow.envs.loop.loop_accel import AccelEnv
Explanation: 3. Setting up an Environment
Several envionrments in Flow exist to train autonomous agents of different forms (e.g. autonomous vehicles, traffic lights) to perform a variety of different tasks. These environments are often scenario or task specific; however, some can be deployed on an ambiguous set of scenarios as well. One such environment, AccelEnv, may be used to train a variable number of vehicles in a fully observable network with a static number of vehicles.
End of explanation
from flow.core.params import SumoParams
sumo_params = SumoParams(sim_step=0.1, render=True, emission_path='data')
Explanation: Although we will not be training any autonomous agents in this exercise, the use of an environment allows us to view the cumulative reward simulation rollouts receive in the absence of autonomy.
Envrionments in Flow are parametrized by three components:
* EnvParams
* SumoParams
* Scenario
3.1 SumoParams
SumoParams specifies simulation-specific variables. These variables include the length a simulation step (in seconds) and whether to render the GUI when running the experiment. For this example, we consider a simulation step length of 0.1s and activate the GUI.
Another useful parameter is emission_path, which is used to specify the path where the emissions output will be generated. They contain a lot of information about the simulation, for instance the position and speed of each car at each time step. If you do not specify any emission path, the emission file will not be generated. More on this in Section 5.
End of explanation
from flow.envs.loop.loop_accel import ADDITIONAL_ENV_PARAMS
print(ADDITIONAL_ENV_PARAMS)
Explanation: 3.2 EnvParams
EnvParams specify environment and experiment-specific parameters that either affect the training process or the dynamics of various components within the scenario. Much like NetParams, the attributes associated with this parameter are mostly environment specific, and can be found in the environment's ADDITIONAL_ENV_PARAMS dictionary.
End of explanation
from flow.core.params import EnvParams
env_params = EnvParams(additional_params=ADDITIONAL_ENV_PARAMS)
Explanation: Importing the ADDITIONAL_ENV_PARAMS variable, we see that it consists of only one entry, "target_velocity", which is used when computing the reward function associated with the environment. We use this default value when generating the EnvParams object.
End of explanation
from flow.core.experiment import Experiment
Explanation: 4. Setting up and Running the Experiment
Once the inputs to the scenario and environment classes are ready, we are ready to set up a Experiment object.
End of explanation
# create the scenario object
scenario = LoopScenario(name="ring_example",
                        vehicles=vehicles,
                        net_params=net_params,
                        initial_config=initial_config,
                        traffic_lights=traffic_lights)
# create the environment object
env = AccelEnv(env_params, sumo_params, scenario)
# create the experiment object
exp = Experiment(env)
# run the experiment for a set number of rollouts / time steps
_ = exp.run(1, 3000, convert_to_csv=True)
Explanation: These objects may be used to simulate rollouts in the absence of reinforcement learning agents, as well as acquire behaviors and rewards that may be used as a baseline with which to compare the performance of the learning agent. In this case, we choose to run our experiment for one rollout consisting of 3000 steps (300 s).
Note: When executing the below code, remeber to click on the    <img style="display:inline;" src="img/play_button.png"> Play button after the GUI is rendered.
End of explanation
import os
emission_location = os.path.join(exp.env.sim_params.emission_path, exp.env.scenario.name)
print(emission_location + '-emission.xml')
Explanation: As we can see from the above simulation, the initial perturbations in the network instabilities propogate and intensify, eventually leading to the formation of stop-and-go waves after approximately 180s.
5. Visualizing Post-Simulation
Once the simulation is done, a .xml file will be generated in the location of the specified emission_path in SumoParams (assuming this parameter has been specified) under the name of the scenario. In our case, this is:
End of explanation
import pandas as pd
pd.read_csv(emission_location + '-emission.csv')
Explanation: The .xml file contains various vehicle-specific parameters at every time step. This information is transferred to a .csv file if the convert_to_csv parameter in exp.run() is set to True. This file looks as follows:
End of explanation
<END_TASK>