def checkMaxRedPhaseTimeRule(self, tl: TrafficLight) -> bool: if tl.maxRedPhaseTimeReached() is not False: traci.trafficlight.setPhase(tl.getName(), tl.maxRedPhaseTimeReached()) return True else: return False
def getEV_RLParameters(self, tl: TrafficLight, isEVApproaching: bool): leadingEV = None EVChangeInSpeed = None EVChangeInQueue = None EVIsStopped = False leadingEVBefore = tl.getLeadingEV() # Only evaluate EV parameters for the reinforcement learning if there is an EV this step and an EV the previous step if isEVApproaching and leadingEVBefore is not None and self.learnEVPreemption: leadingEV = self.getLeadingEV(tl) EVIsStopped: bool = leadingEV.getSpeed() == 0 if leadingEVBefore.getID() == leadingEV.getID(): EVChangeInSpeed = leadingEV.getSpeed( ) - leadingEVBefore.getSpeed() EVChangeInQueue = leadingEV.getQueue( ) - leadingEVBefore.getQueue() elif tl.existedBefore(leadingEV.getID()): leadingEVBefore = tl.getEV(leadingEV.getID()) EVChangeInSpeed = leadingEV.getSpeed( ) - leadingEVBefore.getSpeed() EVChangeInQueue = leadingEV.getQueue( ) - leadingEVBefore.getQueue() return (EVChangeInSpeed, EVChangeInQueue, EVIsStopped)
def getThroughputWaitingTime(self, trafficLight: TrafficLight, carsWaitingBefore: Dict[str, float], carsWaitingAfter: Dict[str, float]) -> float: carsThrough = { k: carsWaitingBefore[k] for k in set(carsWaitingBefore) - set(carsWaitingAfter) } # Update the relevant individual's aggregate vehicle wait time and return the throughput waiting time trafficLight.getAssignedIndividual().updateAggregateVehicleWaitTime( sum(carsThrough.values())) return sum(carsThrough.values())
def getWaitingTime(self, trafficLight: TrafficLight) -> float: waitTime = 0 # Sum waiting time of each edge controlled by the traffic light for edge in trafficLight.getEdges(): waitTime += traci.edge.getWaitingTime(edge) return waitTime
def applyUserDefinedRuleAction(self, trafficLight: TrafficLight, currPhaseName: str, rule: Rule) -> None: # If max green phase time reached, switch phase to yellow in same direction if rule.getConditions()[0] == "maxGreenPhaseTimeReached": currPhase = traci.trafficlight.getPhaseName(trafficLight.getName()) currPhase[5] = "Y" traci.trafficlight.setPhase(trafficLight.getName(), currPhase) # If max yellow phase time reached, switch to next phase in the schedule elif rule.getConditions()[0] == "maxYellowPhaseTimeReached": if traci.trafficlight.getPhase(trafficLight.getName()) >= ( len(trafficLight.getPhases()) - 2): traci.trafficlight.setPhase(trafficLight.getName(), 0) else: traci.trafficlight.setPhase( trafficLight.getName(), traci.trafficlight.getPhase(trafficLight.getName()) + 1)
def evaluateCoopRule(self, trafficLight: TrafficLight, rule: Rule) -> bool: intentions = trafficLight.getCommunicatedIntentions() for x in intentions: for i in intentions[x]: # For each condition, its parameters are acquired and the condition predicate is evaluated for cond in rule.getConditions(): predicate = cond.split("_")[0] # Get parameters if "partnerAction" == predicate: parameters = [cond, i] else: parameters = self.getCoopPredicateParameters( predicate, i, cond) # Construct predicate function call if "EVApproachingPartner" == predicate: predCall = self.getIsEVApproaching(parameters) elif "timeSinceLastEVThrough" == predicate: predCall = getattr( EVCoopPredicateSet, "timeSinceLastEVThrough")(*parameters) elif "partnerAction" == predicate: predCall = getattr(CoopPredicateSet, "partnerAction")(*parameters) elif "intendedActionIs" == predicate: predCall = getattr(CoopPredicateSet, "partnerAction")(*parameters) else: predCall = getattr(CoopPredicateSet, cond)(parameters) # Determine validity of predicate if predCall == False: return False return True # if all predicates return true, evaluate rule as True
def getPredicateParameters( self, trafficLight: TrafficLight, predicate: str ) -> Union[float, int, str, bool, List[str, float, int], List[str]]: if "longestTimeWaitedToProceedStraight" == predicate: # Find max wait time for relevant intersection maxWaitTime: float = 0 # Retrieve state of specified intersection state = self.getState(trafficLight) for lane in state: if lane in trafficLight.getLanes(): for veh in state[lane]: if "_Stopped_S" in veh: vehIDSplit = veh.split("_") vehID = vehIDSplit[0] if self.vehicleWaitingTimes[vehID] > maxWaitTime: maxWaitTime = self.vehicleWaitingTimes[vehID] return maxWaitTime elif "longestTimeWaitedToTurnLeft" == predicate: # Find max wait time for relevant intersection maxWaitTime: float = 0 # Retrieve state of specified intersection state = self.getState(trafficLight) for lane in state: if lane in trafficLight.getLanes(): for veh in state[lane]: if "_Stopped_L" in veh: vehIDSplit = veh.split("_") vehID = vehIDSplit[0] if self.vehicleWaitingTimes[vehID] > maxWaitTime: maxWaitTime = self.vehicleWaitingTimes[vehID] return maxWaitTime elif "numCarsWaitingToProceedStraight" == predicate: carsWaiting: int = 0 # Retrieve state of specified intersection state = self.getState(trafficLight) for lane in state: if lane in trafficLight.getLanes(): for veh in state[lane]: if "_Stopped_S" in veh: vehIDSplit = veh.split("_") vehID = vehIDSplit[0] if self.vehicleWaitingTimes[vehID] > 0: carsWaiting += 1 return carsWaiting elif "numCarsWaitingToTurnLeft" == predicate: carsWaiting: int = 0 # Retrieve state of specified intersection state = self.getState(trafficLight) for lane in state: if lane in trafficLight.getLanes(): for veh in state[lane]: if "_Stopped_L" in veh: vehIDSplit = veh.split("_") vehID = vehIDSplit[0] if self.vehicleWaitingTimes[vehID] > 0: carsWaiting += 1 return carsWaiting elif "timeSpentInCurrentPhase" == predicate: return traci.trafficlight.getPhaseDuration(trafficLight.getName()) elif ("verticalPhaseIs" in predicate or "horizontalPhaseIs" in predicate or "northSouthPhaseIs" in predicate or "southNorthPhaseIs" in predicate or "eastWestPhaseIs" in predicate or "westEastPhaseIs" in predicate): return traci.trafficlight.getPhaseName( trafficLight.getName()).split("_") elif "maxGreenPhaseTimeReached" == predicate: parameters: List[str, float, int] = [] parameters.append( traci.trafficlight.getPhaseName(trafficLight.getName())) # Get phase (G or Y) from phase name getPhase = parameters[0].split("_") parameters[0] = getPhase[2] parameters.append( traci.trafficlight.getPhaseDuration(trafficLight.getName()) - (traci.trafficlight.getNextSwitch(trafficLight.getName()) - traci.simulation.getTime())) parameters.append(self.maxGreenPhaseTime) return parameters elif "maxYellowPhaseTimeReached" == predicate: parameters = [] parameters.append( traci.trafficlight.getPhaseName( trafficLight.getName())) # Get traffic light phase name # Get phase (G or Y) from phase name getPhase = parameters[0].split("_") parameters[0] = getPhase[2] parameters.append( traci.trafficlight.getPhaseDuration(trafficLight.getName()) - (traci.trafficlight.getNextSwitch(trafficLight.getName()) - traci.simulation.getTime())) parameters.append(self.maxYellowPhaseTime) return parameters elif "EVDistanceToIntersection" == predicate: leadingEV = self.getLeadingEV(trafficLight) return leadingEV.getDistance() if leadingEV is not None else -1 elif "EVTrafficDensity" == predicate: leadingEV = self.getLeadingEV(trafficLight) return leadingEV.getTrafficDensity( ) if leadingEV is not None else -1 elif "leadingEVLane" == predicate: leadingEV = self.getLeadingEV(trafficLight) return leadingEV.getLane() if leadingEV is not None else None else: raise Exception("Undefined predicate:", predicate)
def getTimeSinceLastEVThrough(self, trafficLight: TrafficLight) -> int: return self.timeSinceLastEVThrough[trafficLight.getName()]
def getLeadingEV(self, trafficLight: TrafficLight) -> EmergencyVehicle: return self.leadingEV[trafficLight.getName()]
def getLastEVs(self, trafficLight: TrafficLight) -> List[EmergencyVehicle]: return self.lastEVs[trafficLight.getName()]
def getState(self, trafficLight: TrafficLight) -> Dict[str, List[str]]: return self.state[trafficLight.getName()]
def updateValues(self, tl: TrafficLight, isEVApproaching: bool, nextRule: Rule | Literal[-1], carsWaitingAfter: Dict[str, float]): # Update evolutionary learning attributes if there is at least one EV approaching if isEVApproaching and self.learnEVPreemption: tl.getAssignedIndividual().updateAverageEVSpeed( self.getAverageEVSpeed(tl)) tl.getAssignedIndividual().updateEVStops(self.getNumEVStops(tl)) # Update traffic light tl.setCurrentRule(nextRule) tl.updateCarsWaiting(carsWaitingAfter) tl.setEVs(self.getEVs(tl)) tl.setLeadingEV(self.getLeadingEV(tl))
def checkAssignGreenPhaseToSingleWaitingPhaseRule( self, tl: TrafficLight) -> bool: lanesWithWaitingVehicles = [] if tl.getName() == "four-arm": state = self.getState(tl) # print(state) for x in state: if state[x] != [] and "2four-arm" in x: lanesWithWaitingVehicles.append(x) possibleLanes0 = ["WB2four-arm_LTL_0", "incoming2four-arm_LTL_0"] possibleLanes2 = ["WB2four-arm_LTL_1", "incoming2four-arm_LTL_1"] possibleLanes4 = ["NWB2four-arm_LTL_0", "bend2four-arm_LTL_0"] possibleLanes6 = ["NWB2four-arm_LTL_1", "bend2four-arm_LTL_1"] posLanesWaiting = [] if set(lanesWithWaitingVehicles).issubset(set(possibleLanes0)): for i in range(len(lanesWithWaitingVehicles) + 1): if i == len(lanesWithWaitingVehicles): for i in range(len(lanesWithWaitingVehicles)): if lanesWithWaitingVehicles[i] in possibleLanes0: posLanesWaiting.append( lanesWithWaitingVehicles[i]) # print("posLanesWaiting is", posLanesWaiting, # "and lanesWithWaitingVeh is", lanesWithWaitingVehicles) if len(posLanesWaiting ) > 0 and posLanesWaiting == lanesWithWaitingVehicles: traci.trafficlight.setPhase(tl.getName(), 0) return True elif set(lanesWithWaitingVehicles).issubset(set(possibleLanes2)): for i in range(len(lanesWithWaitingVehicles) + 1): if i == len(lanesWithWaitingVehicles): for i in range(len(lanesWithWaitingVehicles)): if lanesWithWaitingVehicles[i] in possibleLanes2: posLanesWaiting.append( lanesWithWaitingVehicles[i]) if len(posLanesWaiting ) > 0 and posLanesWaiting == lanesWithWaitingVehicles: traci.trafficlight.setPhase(tl.getName(), 2) return True elif set(lanesWithWaitingVehicles).issubset(set(possibleLanes4)): for i in range(len(lanesWithWaitingVehicles) + 1): if i == len(lanesWithWaitingVehicles): for i in range(len(lanesWithWaitingVehicles)): if lanesWithWaitingVehicles[i] in possibleLanes4: posLanesWaiting.append( lanesWithWaitingVehicles[i]) if len(posLanesWaiting ) > 0 and posLanesWaiting == lanesWithWaitingVehicles: traci.trafficlight.setPhase(tl.getName(), 4) return True elif set(lanesWithWaitingVehicles).issubset(set(possibleLanes6)): for i in range(len(lanesWithWaitingVehicles) + 1): if i == len(lanesWithWaitingVehicles): for i in range(len(lanesWithWaitingVehicles)): if lanesWithWaitingVehicles[i] in possibleLanes6: posLanesWaiting.append( lanesWithWaitingVehicles[i]) if len(posLanesWaiting ) > 0 and posLanesWaiting == lanesWithWaitingVehicles: traci.trafficlight.setPhase(tl.getName(), 6) return True elif tl.getName() == "incoming": state = self.getState(tl) for x in state: if state[x] != [] and "2incoming" in x: lanesWithWaitingVehicles.append(x) possibleLanes0 = [ "four-arm2incoming_0", "four-arm2incoming_1", "EB2incoming_0", "EB2incoming_1" ] possibleLanes2 = [ "T-intersection2incoming_LTL_0", "T-intersection2incoming_LTL_1" ] possibleLanes4 = ["NEB2incoming_LTL_0", "NEB2incoming_LTL_1"] posLanesWaiting = [] if set(lanesWithWaitingVehicles).issubset(set(possibleLanes0)): for i in range(len(lanesWithWaitingVehicles) + 1): if i == len(lanesWithWaitingVehicles): for i in range(len(lanesWithWaitingVehicles)): if lanesWithWaitingVehicles[i] in possibleLanes0: posLanesWaiting.append( lanesWithWaitingVehicles[i]) if len(posLanesWaiting ) > 0 and posLanesWaiting == lanesWithWaitingVehicles: traci.trafficlight.setPhase(tl.getName(), 0) return True elif set(lanesWithWaitingVehicles).issubset(set(possibleLanes2)): for i in range(len(lanesWithWaitingVehicles) + 1): if i == len(lanesWithWaitingVehicles): for i in range(len(lanesWithWaitingVehicles)): if lanesWithWaitingVehicles[i] in possibleLanes2: posLanesWaiting.append( lanesWithWaitingVehicles[i]) if len(posLanesWaiting ) > 0 and posLanesWaiting == lanesWithWaitingVehicles: traci.trafficlight.setPhase(tl.getName(), 2) return True elif set(lanesWithWaitingVehicles).issubset(set(possibleLanes4)): for i in range(len(lanesWithWaitingVehicles) + 1): if i == len(lanesWithWaitingVehicles): for i in range(len(lanesWithWaitingVehicles)): if lanesWithWaitingVehicles[i] in possibleLanes4: posLanesWaiting.append( lanesWithWaitingVehicles[i]) if len(posLanesWaiting ) > 0 and posLanesWaiting == lanesWithWaitingVehicles: traci.trafficlight.setPhase(tl.getName(), 4) return True else: state = self.getState(tl) for x in state: if state[x] != [] and "2T" in x: lanesWithWaitingVehicles.append(x) possibleLanes0 = [ "SEB2T-intersection_0", "SEB2T-intersection_1", "bend2T-intersection_LTL_0" ] possibleLanes2 = ["bend2T-intersection_LTL_1"] posLanesWaiting = [] if set(lanesWithWaitingVehicles).issubset(set(possibleLanes0)): for i in range(len(lanesWithWaitingVehicles) + 1): if i == len(lanesWithWaitingVehicles): for i in range(len(lanesWithWaitingVehicles)): if lanesWithWaitingVehicles[i] in possibleLanes0: posLanesWaiting.append( lanesWithWaitingVehicles[i]) if len(posLanesWaiting ) > 0 and posLanesWaiting == lanesWithWaitingVehicles: traci.trafficlight.setPhase(tl.getName(), 0) return True elif set(lanesWithWaitingVehicles).issubset(set(possibleLanes2)): for i in range(len(lanesWithWaitingVehicles) + 1): if i == len(lanesWithWaitingVehicles): for i in range(len(lanesWithWaitingVehicles)): if lanesWithWaitingVehicles[i] in possibleLanes2: posLanesWaiting.append( lanesWithWaitingVehicles[i]) if len(posLanesWaiting ) > 0 and posLanesWaiting == lanesWithWaitingVehicles: traci.trafficlight.setPhase(tl.getName(), 2) return True return False # If not returned true by now, return false
def checkMaxGreenAndYellowPhaseRule(self, tl: TrafficLight, nextRule: Rule) -> bool: if "G" in traci.trafficlight.getPhaseName(tl.getName()): if tl.getTimeInCurrentPhase() >= self.maxGreenPhaseTime: if traci.trafficlight.getPhase( tl.getName()) >= (len(tl.getPhases()) - 2): traci.trafficlight.setPhase(tl.getName(), 0) return True else: traci.trafficlight.setPhase( tl.getName(), traci.trafficlight.getPhase(tl.getName()) + 1) return True else: #traci.trafficlight.setPhase(tl.getName(), nextRule.getAction()) tl.updateTimeInCurrentPhase(5) elif "Y" in traci.trafficlight.getPhaseName(tl.getName()): if tl.getTimeInCurrentPhase() >= self.maxYellowPhaseTime: if traci.trafficlight.getPhase( tl.getName()) >= (len(tl.getPhases()) - 2): traci.trafficlight.setPhase(tl.getName(), 0) return True else: traci.trafficlight.setPhase( tl.getName(), traci.trafficlight.getPhase(tl.getName()) + 1) return True else: tl.updateTimeInCurrentPhase(5) else: return False
def run(sumoNetworkName: str, minIndividualRunsPerGen: int, useShoutahead: bool, ruleSetOptions: List[str]): userDefinedRules: List[Rule] = [] edgePartners: Dict[str, List[str]] = {} # # Parse user defined rules file and create rules for each # f = open("UserDefinedRules.txt", "r") # # Parse file to gather information about traffic lights, and instantiate their objects # for x in f: # # Ignore comment sections of input file # if "//" in x: # continue # # For each user defined rule, create a rule with its conditions # if "udr" in x: # ruleComponents = x.split(": ") # ruleComponents = ruleComponents[1].split() # f.close() # Close file before moving on f = open(sumoNetworkName, "r") # Open desired file lanes: List[str] = [] trafficLights: List[TrafficLight] = [] tlPhases: Dict[str, List[str]] = {} # Parse file to gather information about traffic lights, and instantiate their objects for x in f: # Create an action set dictionary for each traffic light if "<tlLogic" in x: getTLName = x.split("id=\"") tlNameArray = getTLName[1].split("\"") tlPhases[tlNameArray[0]] = [] # Count number of phases/actions a TL has; loop max is arbitrarily high given phase number uncertainty for i in range(0, 1000): x = f.readline() # For each phase, record its phase name if "<phase" in x: phaseNameSplit = x.split("name=") phaseName = phaseNameSplit[1].split("\"") tlPhases[tlNameArray[0]].append(phaseName[1]) else: break # Gather info about individual traffic lights elif "<junction" and "type=\"traffic_light\"" in x: # Isolate individual TLs temp = x.split("id=\"") trafficLightName = temp[1].split("\"") # Traffic Light name # Get all lanes controlled by TL splitForlanes = temp[1].split("incLanes=\"") lanesBulk = splitForlanes[1].split("\"") lanesSplit = lanesBulk[0].split() # Split lanes into individual elements in a list for l in lanesSplit: lanes.append(l) trafficLights.append(TrafficLight(trafficLightName[0], lanes)) lanes = [] elif "<edge id=" in x and "function" not in x: isolateFrom = x.split("from=\"") isolateTo = x.split("to=\"") isolateFrom = isolateFrom[1].split("\"") fromJunction = isolateFrom[0] isolateTo = isolateTo[1].split("\"") toJunction = isolateTo[0] # Create new dictionary entry for junctions if they doesn't already exist if toJunction not in edgePartners: edgePartners[toJunction] = [] if fromJunction not in edgePartners: edgePartners[fromJunction] = [] # Add edges to each others dictionary entries if not already there if fromJunction not in edgePartners[toJunction]: edgePartners[toJunction].append(fromJunction) if toJunction not in edgePartners[fromJunction]: edgePartners[fromJunction].append(toJunction) else: continue f.close() # Close file once finished # Set number of phases for each traffic light for x in tlPhases: for tl in trafficLights: if x == tl.getName(): tl.setPhases(tlPhases[x]) # Create and assign agent pools; populate communicationPartners dictionary agentPools: List[AgentPool] = [] for tl in trafficLights: for edge in tl.getEdges(): edgeSplit = edge.split("2") endPoint = edgeSplit[1].split("_") if endPoint[0] == tl.getName(): for otherTL in trafficLights: if edgeSplit[0] == otherTL.getName( ) and otherTL not in tl.getCommunicationPartners(): tl.addCommunicationPartner(otherTL) apAssigned = False # If agent pool(s) already exist, check to see its ability to host the traffic light if len(agentPools) > 0: for ap in agentPools: # An agent pool can realistically host more than one traffic light iff at minimum all TL's using the pool share the same number of phases if tl.getPhases() == ap.getActionSet(): ap.addNewTrafficLight(tl) apAssigned = True break if apAssigned == False: apID = "AP" + str(len(agentPools) + 1) # Construct new agent ID agentPool = AgentPool( apID, tl.getPhases(), minIndividualRunsPerGen, [tl]) # Create a new agent pool for traffic light # tl.assignToAgentPool(agentPool) apAssigned = True agentPools.append(agentPool) # Add new pool to agent pools list # Finish the initialization of the agent pools for ap in agentPools: ap.finishSetUp(useShoutahead, ruleSetOptions) return (userDefinedRules, trafficLights, agentPools)
def addNewTrafficLight(self, trafficLight: TrafficLight): self.trafficLightsAssigned.append(trafficLight) trafficLight.assignToAgentPool(self)