Mercurial > hg > nsaunier > traffic-intelligence
comparison python/traffic_engineering.py @ 314:539e2b4cfaa3
modified for 4740 tps
| author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
|---|---|
| date | Tue, 09 Apr 2013 12:38:58 -0400 |
| parents | 9d88a4d97473 |
| children | 7828fec8bbd2 |
comparison
equal
deleted
inserted
replaced
| 306:93d851d0d21e | 314:539e2b4cfaa3 |
|---|---|
| 157 if sum(proportions) == 1: | 157 if sum(proportions) == 1: |
| 158 self.volume = volume | 158 self.volume = volume |
| 159 self.types = types | 159 self.types = types |
| 160 self.proportions = proportions | 160 self.proportions = proportions |
| 161 self.equivalents = equivalents | 161 self.equivalents = equivalents |
| 162 self.nLanes = nLanes # unused | 162 self.nLanes = nLanes |
| 163 else: | 163 else: |
| 164 print('Proportions do not sum to 1') | 164 print('Proportions do not sum to 1') |
| 165 pass | 165 pass |
| 166 | |
| 167 def checkProtected(self, opposedThroughMvt): | |
| 168 '''Checks if this left movement should be protected, | |
| 169 ie if one of the main two conditions on left turn is verified''' | |
| 170 return self.volume >= 200 or self.volume*opposedThroughMvt.volume/opposedThroughMvt.nLanes > 50000 | |
| 166 | 171 |
| 167 def getPCUVolume(self): | 172 def getPCUVolume(self): |
| 168 '''Returns the passenger-car equivalent for the input volume''' | 173 '''Returns the passenger-car equivalent for the input volume''' |
| 169 v = 0 | 174 v = 0 |
| 170 for p, e in zip(self.proportions, self.equivalents): | 175 for p, e in zip(self.proportions, self.equivalents): |
| 180 self.mvtEquivalent = mvtEquivalent | 185 self.mvtEquivalent = mvtEquivalent |
| 181 | 186 |
| 182 def getTVUVolume(self): | 187 def getTVUVolume(self): |
| 183 return self.mvtEquivalent*self.volume.getPCUVolume() | 188 return self.mvtEquivalent*self.volume.getPCUVolume() |
| 184 | 189 |
| 185 class IntersectionApproach: # should probably not be used | |
| 186 def __init__(self, leftTurnVolume, throughVolume, rightTurnVolume): | |
| 187 self.leftTurnVolume = leftTurnVolume | |
| 188 self.throughVolume = throughVolume | |
| 189 self.rightTurnVolume = rightTurnVolume | |
| 190 | |
| 191 def getTVUVolume(self, leftTurnEquivalent = 1, throughEquivalent = 1, rightTurnEquivalent = 1): | |
| 192 return self.leftTurnVolume.getPCUVolume()*leftTurnEquivalent+self.throughVolume.getPCUVolume()*throughEquivalent+self.rightTurnVolume.getPCUVolume()*rightTurnEquivalent | |
| 193 | |
| 194 class LaneGroup: | 190 class LaneGroup: |
| 195 '''Class that represents a group of mouvements''' | 191 '''Class that represents a group of mouvements''' |
| 196 | 192 |
| 197 def __init__(self, movements, nLanes): | 193 def __init__(self, movements, nLanes): |
| 198 self.movements = movements | 194 self.movements = movements |
| 201 def getTVUVolume(self): | 197 def getTVUVolume(self): |
| 202 return sum([mvt.getTVUVolume() for mvt in self.movements]) | 198 return sum([mvt.getTVUVolume() for mvt in self.movements]) |
| 203 | 199 |
| 204 def getCharge(self, saturationVolume): | 200 def getCharge(self, saturationVolume): |
| 205 return self.getTVUVolume()/(self.nLanes*saturationVolume) | 201 return self.getTVUVolume()/(self.nLanes*saturationVolume) |
| 206 | |
| 207 def checkProtectedLeftTurn(leftMvt, opposedThroughMvt): | |
| 208 '''Checks if one of the main two conditions on left turn is verified | |
| 209 The lane groups should contain left and through movement''' | |
| 210 return leftMvt.volume >= 200 or leftMvt.volume*opposedThroughMvt.volume/opposedThroughMvt.nLanes > 50000 | |
| 211 | 202 |
| 212 def optimalCycle(lostTime, criticalCharge): | 203 def optimalCycle(lostTime, criticalCharge): |
| 213 return (1.5*lostTime+5)/(1-criticalCharge) | 204 return (1.5*lostTime+5)/(1-criticalCharge) |
| 214 | 205 |
| 215 def minimumCycle(lostTime, criticalCharge, degreeSaturation=1.): | 206 def minimumCycle(lostTime, criticalCharge, degreeSaturation=1.): |
| 224 self.phases = phases | 215 self.phases = phases |
| 225 self.lostTime = lostTime | 216 self.lostTime = lostTime |
| 226 self.saturationVolume = saturationVolume | 217 self.saturationVolume = saturationVolume |
| 227 | 218 |
| 228 def computeCriticalCharges(self): | 219 def computeCriticalCharges(self): |
| 229 self.criticalCharges = [] | 220 self.criticalCharges = [max([lg.getCharge(self.saturationVolume) for lg in phase]) for phase in self.phases] |
| 230 for phase in self.phases: | |
| 231 self.criticalCharges.append(max([lg.getCharge(self.saturationVolume) for lg in phase])) | |
| 232 self.criticalCharge = sum(self.criticalCharges) | 221 self.criticalCharge = sum(self.criticalCharges) |
| 233 | 222 |
| 234 def computeOptimalCycle(self): | 223 def computeOptimalCycle(self): |
| 235 self.computeCriticalCharges() | 224 self.computeCriticalCharges() |
| 236 self.C = optimalCycle(self.lostTime, self.criticalCharge) | 225 self.C = optimalCycle(self.lostTime, self.criticalCharge) |
| 240 self.computeCriticalCharges() | 229 self.computeCriticalCharges() |
| 241 self.C = minimumCycle(self.lostTime, self.criticalCharge, degreeSaturation) | 230 self.C = minimumCycle(self.lostTime, self.criticalCharge, degreeSaturation) |
| 242 return self.C | 231 return self.C |
| 243 | 232 |
| 244 def computeEffectiveGreen(self): | 233 def computeEffectiveGreen(self): |
| 245 from numpy import round | 234 #from numpy import round |
| 246 #self.computeCycle() # in case it was not done before | 235 #self.computeCycle() # in case it was not done before |
| 247 effectiveGreenTime = self.C-self.lostTime | 236 effectiveGreenTime = self.C-self.lostTime |
| 248 self.effectiveGreens = [round(c*effectiveGreenTime/self.criticalCharge,1) for c in self.criticalCharges] | 237 self.effectiveGreens = [round(c*effectiveGreenTime/self.criticalCharge,1) for c in self.criticalCharges] |
| 249 return self.effectiveGreens | 238 return self.effectiveGreens |
| 250 | 239 |
