1
- from typing import TYPE_CHECKING , Dict , Optional
1
+ from typing import TYPE_CHECKING , Collection , Dict , Optional , Tuple , Union
2
2
3
- from sym_metanet .blocks .base import ElementWithVars , sym_var
3
+ from sym_metanet .blocks .base import ElementWithVars
4
4
from sym_metanet .blocks .origins import MeteredOnRamp
5
5
from sym_metanet .engines .core import EngineBase , get_current_engine
6
6
from sym_metanet .util .funcs import first
7
+ from sym_metanet .util .types import VarType
7
8
8
9
if TYPE_CHECKING :
10
+ from sym_metanet .blocks .nodes import Node
9
11
from sym_metanet .network import Network
10
12
11
13
12
- class Link (ElementWithVars [sym_var ]):
14
+ class Link (ElementWithVars [VarType ]):
13
15
"""Highway link between two nodes [1, Section 3.2.1]. Links represent stretch of
14
16
highway with similar traffic characteristics and no road changes (e.g., same number
15
17
of lanes and maximum speed).
@@ -26,13 +28,13 @@ class Link(ElementWithVars[sym_var]):
26
28
def __init__ (
27
29
self ,
28
30
nb_segments : int ,
29
- lanes : sym_var ,
30
- length : sym_var ,
31
- maximum_density : sym_var ,
32
- critical_density : sym_var ,
33
- free_flow_velocity : sym_var ,
34
- a : sym_var ,
35
- turnrate : sym_var = 1.0 ,
31
+ lanes : Union [ VarType , int ] ,
32
+ length : Union [ VarType , float ] ,
33
+ maximum_density : Union [ VarType , float ] ,
34
+ critical_density : Union [ VarType , float ] ,
35
+ free_flow_velocity : Union [ VarType , float ] ,
36
+ a : Union [ VarType , float ] ,
37
+ turnrate : Union [ VarType , float ] = 1.0 ,
36
38
name : Optional [str ] = None ,
37
39
) -> None :
38
40
"""Creates an instance of a METANET link.
@@ -41,20 +43,20 @@ def __init__(
41
43
----------
42
44
nb_segments : int
43
45
Number of segments in this highway link, i.e., `N`.
44
- lanes : int or symbolic
46
+ lanes : int or variable
45
47
Number of lanes in each segment, i.e., `lam`.
46
- lengths : float or symbolic
48
+ lengths : float or variable
47
49
Length of each segment in the link, i.e., `L`.
48
- maximum density : float or symbolic
50
+ maximum density : float or variable
49
51
Maximum density that the link can withstand, i.e., `rho_max`.
50
- critical_densities : float or symbolic
52
+ critical_densities : float or variable
51
53
Critical density at which the traffic flow is maximal, i.e., `rho_crit`.
52
- free_flow_velocities : float or symbolic
54
+ free_flow_velocities : float or variable
53
55
Average speed of cars when traffic is freely flowing, i.e., `v_free`.
54
- a : float or symbolic
56
+ a : float or variable
55
57
Model parameter in the computations of the equivalent speed [1, Equation
56
58
3.4].
57
- turnrate : float or symbolic , optional
59
+ turnrate : float or variable , optional
58
60
Fraction of the total flow that enters this link via the upstream node. Only
59
61
relevant if multiple exiting links are attached to the same node, in order
60
62
to split the flow according to these rates. Needs not be normalized. By
@@ -79,7 +81,7 @@ def __init__(
79
81
80
82
def init_vars (
81
83
self ,
82
- init_conditions : Optional [Dict [str , sym_var ]] = None ,
84
+ init_conditions : Optional [Dict [str , VarType ]] = None ,
83
85
engine : Optional [EngineBase ] = None ,
84
86
) -> None :
85
87
"""For each segment in the link, initializes
@@ -100,7 +102,7 @@ def init_vars(
100
102
init_conditions = {}
101
103
if engine is None :
102
104
engine = get_current_engine ()
103
- self .states : Dict [str , sym_var ] = {
105
+ self .states : Dict [str , VarType ] = {
104
106
name : (
105
107
init_conditions [name ]
106
108
if name in init_conditions
@@ -109,7 +111,7 @@ def init_vars(
109
111
for name in ("rho" , "v" )
110
112
}
111
113
112
- def get_flow (self , engine : Optional [EngineBase ] = None , ** kwargs ) -> sym_var :
114
+ def get_flow (self , engine : Optional [EngineBase ] = None , ** kwargs ) -> VarType :
113
115
"""Gets the flow in this link's segments.
114
116
115
117
Parameters
@@ -119,7 +121,7 @@ def get_flow(self, engine: Optional[EngineBase] = None, **kwargs) -> sym_var:
119
121
120
122
Returns
121
123
-------
122
- sym_var
124
+ variable
123
125
The flow in this link.
124
126
"""
125
127
if engine is None :
@@ -131,46 +133,46 @@ def get_flow(self, engine: Optional[EngineBase] = None, **kwargs) -> sym_var:
131
133
def step_dynamics (
132
134
self ,
133
135
net : "Network" ,
134
- tau : sym_var ,
135
- eta : sym_var ,
136
- kappa : sym_var ,
137
- T : sym_var ,
138
- delta : Optional [ sym_var ] = None ,
139
- phi : Optional [ sym_var ] = None ,
136
+ tau : Union [ VarType , float ] ,
137
+ eta : Union [ VarType , float ] ,
138
+ kappa : Union [ VarType , float ] ,
139
+ T : Union [ VarType , float ] ,
140
+ delta : Union [ None , VarType , float ] = None ,
141
+ phi : Union [ None , VarType , float ] = None ,
140
142
engine : Optional [EngineBase ] = None ,
141
143
** kwargs ,
142
- ) -> Dict [str , sym_var ]:
144
+ ) -> Dict [str , VarType ]:
143
145
"""Steps the dynamics of this link.
144
146
145
147
Parameters
146
148
----------
147
149
net : Network
148
150
The network the link belongs to.
149
- tau : sym_var
151
+ tau : float or variable
150
152
Model parameter for the speed relaxation term.
151
- eta : sym_var
153
+ eta : float or variable
152
154
Model parameter for the speed anticipation term.
153
- kappa : sym_var
155
+ kappa : float or variable
154
156
Model parameter for the speed anticipation term.
155
- T : sym_var
157
+ T : float or variable
156
158
Sampling time.
157
- delta : sym_var , optional
159
+ delta : float or variable , optional
158
160
Model parameter for merging phenomenum. By default, not considered.
159
- phi : sym_var , optional
161
+ phi : float or variable , optional
160
162
Model parameter for lane drop phenomenum. By defaul, not considered.
161
163
engine : EngineBase, optional
162
164
The engine to be used. If `None`, the current engine is used.
163
165
164
166
Returns
165
167
-------
166
- Dict[str, sym_var ]
168
+ Dict[str, variable ]
167
169
A dict with the states of the link (speeds and densities) at the next time
168
170
step.
169
171
"""
170
172
if engine is None :
171
173
engine = get_current_engine ()
172
174
173
- node_up , node_down = net .nodes_by_link [self ]
175
+ node_up , node_down = net .nodes_by_link [self ] # type: ignore[index]
174
176
rho = self .states ["rho" ]
175
177
v = self .states ["v" ]
176
178
q = self .get_flow (engine = engine )
@@ -204,10 +206,12 @@ def step_dynamics(
204
206
# check for lane drops in the next link (only if one link downstream)
205
207
lanes_drop = None
206
208
if phi is not None :
207
- links_down = net .out_links (node_down )
209
+ links_down : Collection [
210
+ Tuple ["Node" , "Node" , "Link[VarType]" ]
211
+ ] = net .out_links (node_down )
208
212
if len (links_down ) == 1 :
209
213
link_down = first (links_down )[- 1 ]
210
- lanes_drop = self .lam - link_down .lam
214
+ lanes_drop = self .lam - link_down .lam # type: ignore[operator]
211
215
if lanes_drop == 0 :
212
216
lanes_drop = None
213
217
0 commit comments