changeset 34:388a5a25fe92

Code for lab5 works
author Nicolas Saunier <nico@confins.net>
date Sun, 11 Apr 2010 02:23:48 -0400
parents 4bd7cc69b6cd
children 8cafee54466f
files python/traffic_engineering.py
diffstat 1 files changed, 39 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/python/traffic_engineering.py	Sat Apr 10 20:46:33 2010 -0400
+++ b/python/traffic_engineering.py	Sun Apr 11 02:23:48 2010 -0400
@@ -31,11 +31,11 @@
             v += p*e
         return v*self.volume
 
-class IntersectionMouvement:
+class IntersectionMovement:
     '''Represents an intersection movement
     with a volume, a type (through, left or right)
     and an equivalent for movement type'''
-    def __init__(self, volume,  type, mvtEquivalent = 1):
+    def __init__(self, volume, type, mvtEquivalent = 1):
         self.volume = volume
         self.type = type
         self.mvtEquivalent = mvtEquivalent
@@ -55,33 +55,49 @@
 class LaneGroup:
     '''Class that represents a group of mouvements'''
 
-    def __init__(self):
-        self.mouvements = {'left': [],
-                           'through': [],
-                           'right': []}
-
-    # all the add*Mvt should add a IntersectionMovement instance
-    def addLeftMvt(self, vol):
-        self.mouvements['left'].append(vol)
+    def __init__(self, movements, nLanes):
+        self.movements = movements
+        self.nLanes = nLanes
 
-    def addRightMvt(self, vol):
-        self.mouvements['right'].append(vol)
-
-    def addThroughMvt(self, vol):
-        self.mouvements['through'].append(vol)
-
-    def getTVUVolume(self, leftTurnEquivalent = 1, throughEquivalent = 1, rightTurnEquivalent = 1):
-        return leftTurnEquivalent*sum([m.getPCEVolume() for m in mouvements['left']])\
-            +rightTurnEquivalent*sum([m.getPCEVolume() for m in mouvements['right']])\
-            +throughTurnEquivalent*sum([m.getPCEVolume() for m in mouvements['through']])
+    def getTVUVolume(self):
+        return sum([mvt.getTVUVolume() for mvt in self.movements])
 
 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*opposedMvt.volume/opposedMvt.nLanes > 50000
+    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)
+
+class Cycle:
+    '''Class to compute optimal cycle and the split of effective green times'''
+    def __init__(self, phases, lostTime, saturationVolume):
+        '''phases is a list of phases
+        a phase is a list of lanegroups'''
+        self.phases = phases
+        self.lostTime = lostTime
+        self.saturationVolume = saturationVolume
 
-def optimalCycle(lostTime, criticalCharge):
-    return ceil((1.5*lostTime+5)/(1-criticalCharge))
+    def computeCycle(self):
+        self.criticalCharges = []
+        for phase in self.phases:
+            self.criticalCharges.append(max([lg.getTVUVolume() for lg in phase])/(lg.nLanes*self.saturationVolume))
+
+        self.criticalCharge = sum(self.criticalCharges)
+        self.C0 = optimalCycle(self.lostTime, self.criticalCharge)
+        return self.C0
+
+    def computeEffectiveGreen(self):
+        from numpy import round
+        self.computeCycle() # in case it was not done before
+        effectiveGreenTime = self.C0-self.lostTime
+        self.effectiveGreens = [round(c*effectiveGreenTime/self.criticalCharge,1) for c in self.criticalCharges]
+        return self.effectiveGreens
+
 
 def computeInterGreen(perceptionReactionTime, initialSpeed, intersectionLength, vehicleAverageLength = 6, deceleration = 3):
     '''Computes the intergreen time (yellow/amber plus all red time)