Source code for flow.scenarios.figure_eight
"""Contains the figure eight scenario class."""
import numpy as np
from numpy import pi, sin, cos, linspace
from flow.core.params import InitialConfig
from flow.core.params import TrafficLightParams
from flow.scenarios.base_scenario import Scenario
ADDITIONAL_NET_PARAMS = {
# radius of the circular components
"radius_ring": 30,
# number of lanes
"lanes": 1,
# speed limit for all edges
"speed_limit": 30,
# resolution of the curved portions
"resolution": 40
}
[docs]class Figure8Scenario(Scenario):
"""Figure eight scenario class.
The figure eight network is an extension of the ring road network: Two
rings, placed at opposite ends of the network, are connected by an
intersection with road segments of length equal to the diameter of the
rings. Serves as a simulation of a closed loop intersection.
Requires from net_params:
* **ring_radius** : radius of the circular portions of the network. Also
corresponds to half the length of the perpendicular straight lanes.
* **resolution** : number of nodes resolution in the circular portions
* **lanes** : number of lanes in the network
* **speed** : max speed of vehicles in the network
Usage
-----
>>> from flow.core.params import NetParams
>>> from flow.core.params import VehicleParams
>>> from flow.core.params import InitialConfig
>>> from flow.scenarios import Figure8Scenario
>>>
>>> scenario = Figure8Scenario(
>>> name='figure_eight',
>>> vehicles=VehicleParams(),
>>> net_params=NetParams(
>>> additional_params={
>>> 'radius_ring': 50,
>>> 'lanes': 75,
>>> 'speed_limit': 30,
>>> 'resolution': 40
>>> },
>>> )
>>> )
"""
def __init__(self,
name,
vehicles,
net_params,
initial_config=InitialConfig(),
traffic_lights=TrafficLightParams()):
"""Initialize a figure 8 scenario."""
for p in ADDITIONAL_NET_PARAMS.keys():
if p not in net_params.additional_params:
raise KeyError('Network parameter "{}" not supplied'.format(p))
ring_radius = net_params.additional_params["radius_ring"]
self.ring_edgelen = ring_radius * np.pi / 2.
self.intersection_len = 2 * ring_radius
self.junction_len = 2.9 + 3.3 * net_params.additional_params["lanes"]
self.inner_space_len = 0.28
# # instantiate "length" in net params
# net_params.additional_params["length"] = \
# 6 * self.ring_edgelen + 2 * self.intersection_len + \
# 2 * self.junction_len + 10 * self.inner_space_len
super().__init__(name, vehicles, net_params, initial_config,
traffic_lights)
[docs] def specify_nodes(self, net_params):
"""See parent class."""
r = net_params.additional_params["radius_ring"]
nodes = [{
"id": "center",
"x": 0,
"y": 0,
"radius": (2.9 + 3.3 * net_params.additional_params["lanes"])/2,
"type": "priority"
}, {
"id": "right",
"x": r,
"y": 0,
"type": "priority"
}, {
"id": "top",
"x": 0,
"y": r,
"type": "priority"
}, {
"id": "left",
"x": -r,
"y": 0,
"type": "priority"
}, {
"id": "bottom",
"x": 0,
"y": -r,
"type": "priority"
}]
return nodes
[docs] def specify_edges(self, net_params):
"""See parent class."""
r = net_params.additional_params["radius_ring"]
resolution = net_params.additional_params["resolution"]
ring_edgelen = 3 * r * pi / 2.
intersection_edgelen = 2 * r
# intersection edges
edges = [{
"id": "bottom",
"type": "edgeType",
"priority": "78",
"from": "bottom",
"to": "center",
"length": intersection_edgelen / 2
}, {
"id": "top",
"type": "edgeType",
"priority": 78,
"from": "center",
"to": "top",
"length": intersection_edgelen / 2
}, {
"id": "right",
"type": "edgeType",
"priority": 46,
"from": "right",
"to": "center",
"length": intersection_edgelen / 2
}, {
"id": "left",
"type": "edgeType",
"priority": 46,
"from": "center",
"to": "left",
"length": intersection_edgelen / 2
}]
# ring edges
edges += [{
"id": "upper_ring",
"type": "edgeType",
"from": "top",
"to": "right",
"length": ring_edgelen,
"shape": [(r * (1 - cos(t)), r * (1 + sin(t)))
for t in linspace(0, 3 * pi / 2, resolution)]
}, {
"id": "lower_ring",
"type": "edgeType",
"from": "left",
"to": "bottom",
"length": ring_edgelen,
"shape": [(-r + r * cos(t), -r + r * sin(t))
for t in linspace(pi / 2, 2 * pi, resolution)]
}]
return edges
[docs] def specify_types(self, net_params):
"""See parent class."""
lanes = net_params.additional_params["lanes"]
speed_limit = net_params.additional_params["speed_limit"]
types = [{
"id": "edgeType",
"numLanes": lanes,
"speed": speed_limit
}]
return types
[docs] def specify_routes(self, net_params):
"""See parent class."""
rts = {
"bottom":
["bottom", "top", "upper_ring", "right", "left", "lower_ring"],
"top":
["top", "upper_ring", "right", "left", "lower_ring", "bottom"],
"upper_ring":
["upper_ring", "right", "left", "lower_ring", "bottom", "top"],
"left":
["left", "lower_ring", "bottom", "top", "upper_ring", "right"],
"right":
["right", "left", "lower_ring", "bottom", "top", "upper_ring"],
"lower_ring":
["lower_ring", "bottom", "top", "upper_ring", "right", "left"],
}
return rts
[docs] def specify_connections(self, net_params):
"""See parent class."""
lanes = net_params.additional_params["lanes"]
conn_dict = {}
conn = []
for i in range(lanes):
conn += [{"from": "bottom",
"to": "top",
"fromLane": str(i),
"toLane": str(i)}]
conn += [{"from": "right",
"to": "left",
"fromLane": str(i),
"toLane": str(i)}]
conn_dict["center"] = conn
return conn_dict
[docs] def specify_edge_starts(self):
"""See base class."""
edgestarts = [
("bottom", self.inner_space_len),
("top", self.intersection_len / 2 + self.junction_len +
self.inner_space_len),
("upper_ring", self.intersection_len + self.junction_len +
2 * self.inner_space_len),
("right", self.intersection_len + 3 * self.ring_edgelen
+ self.junction_len + 3 * self.inner_space_len),
("left", 3 / 2 * self.intersection_len + 3 * self.ring_edgelen
+ 2 * self.junction_len + 3 * self.inner_space_len),
("lower_ring", 2 * self.intersection_len + 3 * self.ring_edgelen
+ 2 * self.junction_len + 4 * self.inner_space_len)]
return edgestarts
[docs] def specify_internal_edge_starts(self):
"""See base class."""
internal_edgestarts = [
(":bottom", 0),
(":center_{}".format(self.net_params.additional_params['lanes']),
self.intersection_len / 2 + self.inner_space_len),
(":top", self.intersection_len + self.junction_len +
self.inner_space_len),
(":right", self.intersection_len + 3 * self.ring_edgelen
+ self.junction_len + 2 * self.inner_space_len),
(":center_0", 3 / 2 * self.intersection_len + 3 * self.ring_edgelen
+ self.junction_len + 3 * self.inner_space_len),
(":left", 2 * self.intersection_len + 3 * self.ring_edgelen
+ 2 * self.junction_len + 3 * self.inner_space_len),
# for aimsun
('bottom_to_top',
self.intersection_len / 2 + self.inner_space_len),
('right_to_left',
+ self.junction_len + 3 * self.inner_space_len),
]
return internal_edgestarts