Mercurial Hosting > traffic-intelligence
view python/traffic_engineering.py @ 33:4bd7cc69b6cd
added traffic engineering utilities with first version of LaneGroups
author | Nicolas Saunier <nico@confins.net> |
---|---|
date | Sat, 10 Apr 2010 20:46:33 -0400 |
parents | |
children | 388a5a25fe92 |
line wrap: on
line source
#! /usr/bin/env python ''' Traffic Engineering Tools.''' from math import ceil __metaclass__ = type ######################### # traffic signals ######################### class Volume: '''Class to represent volumes with varied vehicule types ''' def __init__(self, volume, types = ['pc'], proportions = [1], equivalents = [1], nLanes = 1): '''mvtEquivalent is the equivalent if the movement is right of left turn''' # check the sizes of the lists if sum(proportions) == 1: self.volume = volume self.types = types self.proportions = proportions self.equivalents = equivalents self.nLanes = nLanes else: pass def getPCEVolume(self): '''Returns the passenger-car equivalent for the input volume''' v = 0 for p, e in zip(self.proportions, self.equivalents): v += p*e return v*self.volume class IntersectionMouvement: '''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): self.volume = volume self.type = type self.mvtEquivalent = mvtEquivalent def getTVUVolume(self): return self.mvtEquivalent*self.volume.getPCEVolume() class IntersectionApproach: def __init__(self, leftTurnVolume, throughVolume, rightTurnVolume): self.leftTurnVolume = leftTurnVolume self.throughVolume = throughVolume self.rightTurnVolume = rightTurnVolume def getTVUVolume(self, leftTurnEquivalent = 1, throughEquivalent = 1, rightTurnEquivalent = 1): return self.leftTurnVolume.getPCEVolume()*leftTurnEquivalent+self.throughVolume.getPCEVolume()*throughEquivalent+self.rightTurnVolume.getPCEVolume()*rightTurnEquivalent 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 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 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 def optimalCycle(lostTime, criticalCharge): return ceil((1.5*lostTime+5)/(1-criticalCharge)) def computeInterGreen(perceptionReactionTime, initialSpeed, intersectionLength, vehicleAverageLength = 6, deceleration = 3): '''Computes the intergreen time (yellow/amber plus all red time) Deceleration is positive All variables should be in the same units''' if deceleration > 0: return [perceptionReactionTime+initialSpeed/(2*deceleration), (intersectionLength+vehicleAverageLength)/initialSpeed] else: print 'Issue deceleration should be strictly positive' return None