comparison python/traffic_engineering.py @ 206:82b4101d9a2f

re-arranged and commnted signal cycle calculations
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Tue, 03 Apr 2012 01:11:29 -0400
parents aeaaf5579b46
children f65b828e5521
comparison
equal deleted inserted replaced
205:aeaaf5579b46 206:82b4101d9a2f
142 if sum(proportions) == 1: 142 if sum(proportions) == 1:
143 self.volume = volume 143 self.volume = volume
144 self.types = types 144 self.types = types
145 self.proportions = proportions 145 self.proportions = proportions
146 self.equivalents = equivalents 146 self.equivalents = equivalents
147 self.nLanes = nLanes 147 self.nLanes = nLanes # unused
148 else: 148 else:
149 pass 149 pass
150 150
151 def getPCUVolume(self): 151 def getPCUVolume(self):
152 '''Returns the passenger-car equivalent for the input volume''' 152 '''Returns the passenger-car equivalent for the input volume'''
164 self.mvtEquivalent = mvtEquivalent 164 self.mvtEquivalent = mvtEquivalent
165 165
166 def getTVUVolume(self): 166 def getTVUVolume(self):
167 return self.mvtEquivalent*self.volume.getPCUVolume() 167 return self.mvtEquivalent*self.volume.getPCUVolume()
168 168
169 class IntersectionApproach: 169 class IntersectionApproach: # should probably not be used
170 def __init__(self, leftTurnVolume, throughVolume, rightTurnVolume): 170 def __init__(self, leftTurnVolume, throughVolume, rightTurnVolume):
171 self.leftTurnVolume = leftTurnVolume 171 self.leftTurnVolume = leftTurnVolume
172 self.throughVolume = throughVolume 172 self.throughVolume = throughVolume
173 self.rightTurnVolume = rightTurnVolume 173 self.rightTurnVolume = rightTurnVolume
174 174
183 self.nLanes = nLanes 183 self.nLanes = nLanes
184 184
185 def getTVUVolume(self): 185 def getTVUVolume(self):
186 return sum([mvt.getTVUVolume() for mvt in self.movements]) 186 return sum([mvt.getTVUVolume() for mvt in self.movements])
187 187
188 def getCharge(self, saturationVolume):
189 return self.getTVUVolume()/(self.nLanes*saturationVolume)
190
188 def checkProtectedLeftTurn(leftMvt, opposedThroughMvt): 191 def checkProtectedLeftTurn(leftMvt, opposedThroughMvt):
189 '''Checks if one of the main two conditions on left turn is verified 192 '''Checks if one of the main two conditions on left turn is verified
190 The lane groups should contain left and through movement''' 193 The lane groups should contain left and through movement'''
191 return leftMvt.volume >= 200 or leftMvt.volume*opposedThroughMvt.volume/opposedThroughMvt.nLanes > 50000 194 return leftMvt.volume >= 200 or leftMvt.volume*opposedThroughMvt.volume/opposedThroughMvt.nLanes > 50000
192 195
193 def optimalCycle(lostTime, criticalCharge, rounding=True): 196 def optimalCycle(lostTime, criticalCharge):
194 if rounding: 197 return (1.5*lostTime+5)/(1-criticalCharge)
195 return ceil((1.5*lostTime+5)/(1-criticalCharge)) 198
196 else: 199 def minimumCycle(lostTime, criticalCharge, degreeSaturation=1.):
197 return (1.5*lostTime+5)/(1-criticalCharge) 200 'degree of saturation can be used as the peak hour factor too'
201 return lostTime/(1-criticalCharge/degreeSaturation)
198 202
199 class Cycle: 203 class Cycle:
200 '''Class to compute optimal cycle and the split of effective green times''' 204 '''Class to compute optimal cycle and the split of effective green times'''
201 def __init__(self, phases, lostTime, saturationVolume): 205 def __init__(self, phases, lostTime, saturationVolume):
202 '''phases is a list of phases 206 '''phases is a list of phases
203 a phase is a list of lanegroups''' 207 a phase is a list of lanegroups'''
204 self.phases = phases 208 self.phases = phases
205 self.lostTime = lostTime 209 self.lostTime = lostTime
206 self.saturationVolume = saturationVolume 210 self.saturationVolume = saturationVolume
207 211
208 def computeCycle(self): 212 def computeCriticalCharges(self):
209 self.criticalCharges = [] 213 self.criticalCharges = []
210 for phase in self.phases: 214 for phase in self.phases:
211 self.criticalCharges.append(max([lg.getTVUVolume() for lg in phase])/(lg.nLanes*self.saturationVolume)) 215 self.criticalCharges.append(max([lg.getCharge(self.saturationVolume) for lg in phase]))
212
213 self.criticalCharge = sum(self.criticalCharges) 216 self.criticalCharge = sum(self.criticalCharges)
214 self.C0 = optimalCycle(self.lostTime, self.criticalCharge) 217
215 return self.C0 218 def computeOptimalCycle(self):
219 self.computeCriticalCharges()
220 self.C = optimalCycle(self.lostTime, self.criticalCharge)
221 return self.C
222
223 def computeMinimumCycle(self, degreeSaturation=1.):
224 self.computeCriticalCharges()
225 self.C = minimumCycle(self.lostTime, self.criticalCharge, degreeSaturation)
226 return self.C
216 227
217 def computeEffectiveGreen(self): 228 def computeEffectiveGreen(self):
218 from numpy import round 229 from numpy import round
219 self.computeCycle() # in case it was not done before 230 #self.computeCycle() # in case it was not done before
220 effectiveGreenTime = self.C0-self.lostTime 231 effectiveGreenTime = self.C-self.lostTime
221 self.effectiveGreens = [round(c*effectiveGreenTime/self.criticalCharge,1) for c in self.criticalCharges] 232 self.effectiveGreens = [round(c*effectiveGreenTime/self.criticalCharge,1) for c in self.criticalCharges]
222 return self.effectiveGreens 233 return self.effectiveGreens
223 234
224 235
225 def computeInterGreen(perceptionReactionTime, initialSpeed, intersectionLength, vehicleAverageLength = 6, deceleration = 3): 236 def computeInterGreen(perceptionReactionTime, initialSpeed, intersectionLength, vehicleAverageLength = 6, deceleration = 3):