diff --git a/tools/sumolib/net/__init__.py b/tools/sumolib/net/__init__.py index 5f8366a7dfce..dd25896674ca 100644 --- a/tools/sumolib/net/__init__.py +++ b/tools/sumolib/net/__init__.py @@ -48,7 +48,14 @@ from . import lane, edge, netshiftadaptor, node, connection, roundabout # noqa from .connection import Connection +class Condition: + def __init__(self, id, value): + self.id = id + self.value = value + def toXML(self): + return f'\t \n' + class TLS: """Traffic Light Signal for a sumo network""" @@ -102,7 +109,7 @@ def getPrograms(self): class Phase: - def __init__(self, duration, state, minDur=None, maxDur=None, next=tuple(), name=""): + def __init__(self, duration, state, minDur=None, maxDur=None, next=tuple(), name="",earlyTarget=""): """ Constructs a traffic light phase duration (float): the duration of the phase in seconds @@ -111,6 +118,7 @@ def __init__(self, duration, state, minDur=None, maxDur=None, next=tuple(), name maxDur (float): the maximum duration (ignored by static tls) next (intList): possible succesor phase (optional) name (string): the name of the phase + earlyTarget (string): early switching to phase with the given index(es) """ self.duration = duration self.state = state @@ -119,12 +127,31 @@ def __init__(self, duration, state, minDur=None, maxDur=None, next=tuple(), name self.maxDur = maxDur if maxDur is not None else duration self.next = next self.name = name + self.earlyTarget = earlyTarget def __repr__(self): - name = (", name='%s'" % self.name) if self.name else "" + name = f', name="{self.name}"' if self.name else "" next = (", next='%s'" % str(self.next)) if self.next else "" - return ("Phase(duration=%s, state='%s', minDur=%s, maxDur=%s%s%s)" % - (self.duration, self.state, self.minDur, self.maxDur, name, next)) + earlyTarget = f', earlyTarget="{self.earlyTarget}"' if self.earlyTarget else "" + return (f'Phase(duration="{self.duration}",state="{self.state}",minDur="{self.minDur}", maxDur="{self.maxDur}"{name}{next}{earlyTarget})') + + def addNext(self,next): + self.next = next + + def addEarlyTarget(self,target_str): + self.earlyTarget = target_str + + def addMinDur(self,duration): + self.minDur = duration + + def addMaxDur(self,duration): + self.maxDur = duration + + def getMinDur(self): + return None if self.minDur is None else self.minDur + + def getMaxDur(self): + return None if self.maxDur is None else self.maxDur class TLSProgram: @@ -135,9 +162,13 @@ def __init__(self, id, offset, type): self._offset = offset self._phases = [] self._params = {} + self._conditions = {} - def addPhase(self, state, duration, minDur=-1, maxDur=-1, next=None, name=""): - self._phases.append(Phase(duration, state, minDur, maxDur, next, name)) + def addPhase(self, state, duration, minDur=-1, maxDur=-1, next=None, name="",earlyTarget=""): + self._phases.append(Phase(duration, state, minDur, maxDur, next, name, earlyTarget)) + + def addCondition(self,id,value): + self._conditions[id] = value def toXML(self, tlsID): ret = ' \n' % ( @@ -147,10 +178,13 @@ def toXML(self, tlsID): maxDur = '' if p.maxDur < 0 else ' maxDur="%s"' % p.maxDur name = '' if p.name == '' else ' name="%s"' % p.name next = '' if len(p.next) == 0 else ' next="%s"' % ' '.join(map(str, p.next)) - ret += ' \n' % ( - p.duration, p.state, minDur, maxDur, name, next) + earlyTarget = '' if p.earlyTarget == '' else ' earlyTarget="%s"' % p.earlyTarget + ret += ' \n' % ( + p.duration, p.state, minDur, maxDur, name, next, earlyTarget) for k, v in self._params.items(): ret += ' \n' % (k, v) + for i, j in self._conditions.items(): + ret += f' \n' ret += ' \n' return ret @@ -169,6 +203,27 @@ def getParam(self, key, default=None): def getParams(self): return self._params + def getPhasesWithIndex(self): + return{key:value for key,value in enumerate(self.getPhases())} + + def numPhases(self): + return len(self._phases) + + def getPhaseByIndex(self,idx): + ret = {key:value for key,value in enumerate(self.getPhases())} + return ret[idx] + + def getStages(self): + stages = dict() + for idx,phase in enumerate(self.getPhases()): + if phase not in stages.values(): + if 'G' in list(phase.state) and 'y' not in list(phase.state) and len(phase.name)>0: + stages[idx]= phase + return stages + + def getOffset(self): + return self._offset + class EdgeType: def __init__(self, id, allow, disallow): diff --git a/tools/sumolib/sensors/inductive_loop.py b/tools/sumolib/sensors/inductive_loop.py index c81d07f030f1..16cd4fcd48e4 100644 --- a/tools/sumolib/sensors/inductive_loop.py +++ b/tools/sumolib/sensors/inductive_loop.py @@ -27,17 +27,18 @@ class InductiveLoop: - def __init__(self, id, lane, pos, frequency=60, file="NUL", friendlyPos=True): + def __init__(self, id, lane, pos, frequency=60, file="NUL", friendlyPos=True, vTypes=""): self.id = id self.lane = lane self.pos = pos self.frequency = frequency self.file = file self.friendlyPos = friendlyPos + self.vTypes = vTypes def toXML(self): - return '' % ( - self.id, self.lane, self.pos, self.frequency, self.file, self.friendlyPos) + return '' % ( + self.id, self.lane, self.pos, self.frequency, self.file, self.friendlyPos, self.vTypes) class InductiveLoopReader(handler.ContentHandler):