# HG changeset patch # User Nicolas Saunier # Date 1333429889 14400 # Node ID 82b4101d9a2fef0cbe1d9b6160be89d0c3266047 # Parent aeaaf5579b46e2a09fc37758039add25e689677f re-arranged and commnted signal cycle calculations diff -r aeaaf5579b46 -r 82b4101d9a2f python/traffic_engineering.py --- a/python/traffic_engineering.py Tue Mar 20 22:32:38 2012 -0400 +++ b/python/traffic_engineering.py Tue Apr 03 01:11:29 2012 -0400 @@ -144,7 +144,7 @@ self.types = types self.proportions = proportions self.equivalents = equivalents - self.nLanes = nLanes + self.nLanes = nLanes # unused else: pass @@ -166,7 +166,7 @@ def getTVUVolume(self): return self.mvtEquivalent*self.volume.getPCUVolume() -class IntersectionApproach: +class IntersectionApproach: # should probably not be used def __init__(self, leftTurnVolume, throughVolume, rightTurnVolume): self.leftTurnVolume = leftTurnVolume self.throughVolume = throughVolume @@ -185,16 +185,20 @@ def getTVUVolume(self): return sum([mvt.getTVUVolume() for mvt in self.movements]) + def getCharge(self, saturationVolume): + return self.getTVUVolume()/(self.nLanes*saturationVolume) + def checkProtectedLeftTurn(leftMvt, opposedThroughMvt): '''Checks if one of the main two conditions on left turn is verified The lane groups should contain left and through movement''' return leftMvt.volume >= 200 or leftMvt.volume*opposedThroughMvt.volume/opposedThroughMvt.nLanes > 50000 -def optimalCycle(lostTime, criticalCharge, rounding=True): - if rounding: - return ceil((1.5*lostTime+5)/(1-criticalCharge)) - else: - return (1.5*lostTime+5)/(1-criticalCharge) +def optimalCycle(lostTime, criticalCharge): + return (1.5*lostTime+5)/(1-criticalCharge) + +def minimumCycle(lostTime, criticalCharge, degreeSaturation=1.): + 'degree of saturation can be used as the peak hour factor too' + return lostTime/(1-criticalCharge/degreeSaturation) class Cycle: '''Class to compute optimal cycle and the split of effective green times''' @@ -205,19 +209,26 @@ self.lostTime = lostTime self.saturationVolume = saturationVolume - def computeCycle(self): + def computeCriticalCharges(self): self.criticalCharges = [] for phase in self.phases: - self.criticalCharges.append(max([lg.getTVUVolume() for lg in phase])/(lg.nLanes*self.saturationVolume)) - + self.criticalCharges.append(max([lg.getCharge(self.saturationVolume) for lg in phase])) self.criticalCharge = sum(self.criticalCharges) - self.C0 = optimalCycle(self.lostTime, self.criticalCharge) - return self.C0 + + def computeOptimalCycle(self): + self.computeCriticalCharges() + self.C = optimalCycle(self.lostTime, self.criticalCharge) + return self.C + + def computeMinimumCycle(self, degreeSaturation=1.): + self.computeCriticalCharges() + self.C = minimumCycle(self.lostTime, self.criticalCharge, degreeSaturation) + return self.C def computeEffectiveGreen(self): from numpy import round - self.computeCycle() # in case it was not done before - effectiveGreenTime = self.C0-self.lostTime + #self.computeCycle() # in case it was not done before + effectiveGreenTime = self.C-self.lostTime self.effectiveGreens = [round(c*effectiveGreenTime/self.criticalCharge,1) for c in self.criticalCharges] return self.effectiveGreens