def loadVTypeMap(fn): '''loadVTypeMap(string) -> dict Reads lines of the form 'origMode:leadMode:followMode:catchupMode:catchupFollowMode' (last three elements can be omitted) from a given file and write corresponding key:value pairs to PLATOON_VTYPES ''' global PLATOON_VTYPES with open(fn, "r") as f: # if rp.VERBOSITY >= 2: if rp.VERBOSITY >= 2: report("Loading vehicle type mappings from file '%s'..." % fn, True) splits = [l.split(":") for l in f.readlines()] NrBadLines = 0 for j, spl in enumerate(splits): if len(spl) >= 2 and len(spl) <= 5: stripped = list(map(lambda x: x.strip(), spl)) origType = stripped[0] if origType == "": raise SimplaException("Original vType must be specified in line %s of vType file '%s'!" % (j, fn)) if rp.VERBOSITY >= 2: report("original type: '%s'" % origType, True) leadType = stripped[1] if leadType == "": raise SimplaException("Platoon leader vType must be specified in line %s of vType file '%s'!" % (j, fn)) if rp.VERBOSITY >= 2: report("platoon leader type: '%s'" % leadType, True) if (len(stripped) >= 3 and stripped[2] != ""): followerType = stripped[2] if rp.VERBOSITY >= 2: report("platoon follower type: '%s'" % followerType, True) else: followerType = None if (len(stripped) >= 4 and stripped[3] != ""): catchupType = stripped[3] if rp.VERBOSITY >= 2: report("catchup type: '%s'" % catchupType, True) else: catchupType = None if len(stripped) >= 5 and stripped[4] != "": catchupFollowerType = stripped[4] if rp.VERBOSITY >= 2: report("catchup follower type: '%s'" % catchupFollowerType, True) else: catchupFollowerType = None PLATOON_VTYPES[origType][PlatoonMode.NONE] = origType PLATOON_VTYPES[origType][PlatoonMode.LEADER] = leadType PLATOON_VTYPES[origType][PlatoonMode.FOLLOWER] = followerType PLATOON_VTYPES[origType][PlatoonMode.CATCHUP] = catchupType PLATOON_VTYPES[origType][PlatoonMode.CATCHUP_FOLLOWER] = catchupFollowerType else: NrBadLines += 1 if NrBadLines > 0: if rp.VERBOSITY >= 1: warn("vType file '%s' contained %d lines that were not parsed into a colon-separated sequence of strings!" % (fn, NrBadLines))
def __init__(self): ''' PlatoonManager() Creates and initializes the PlatoonManager ''' if rp.VERBOSITY >= 2: report("Initializing simpla.PlatoonManager...", True) # Load parameters from config # vehicle type filter self._typeSubstrings = cfg.VEH_SELECTORS if self._typeSubstrings == [""] and rp.VERBOSITY >= 1: warn("No typeSubstring given. Managing all vehicles.", True) elif rp.VERBOSITY >= 2: report("Managing all vTypes selected by %s" % str(self._typeSubstrings), True) # max intra platoon gap self._maxPlatoonGap = cfg.MAX_PLATOON_GAP # max distance for trying to catch up self._catchupDist = cfg.CATCHUP_DIST # platoons currently in the simulation # map: platoon ID -> platoon objects self._platoons = dict() # IDs of all potential platoon members currently in the simulation # map: ID -> vehicle self._connectedVehicles = dict() for vehID in traci.vehicle.getIDList(): if self._hasConnectedType(vehID): self._addVehicle(vehID) # integration step-length self._DeltaT = traci.simulation.getDeltaT() # rate for executing the platoon logic if(1. / cfg.CONTROL_RATE < self._DeltaT): if rp.VERBOSITY >= 1: warn( "Restricting given control rate (= %d per sec.) to 1 per timestep (= %g per sec.)" % (cfg.CONTROL_RATE, 1. / self._DeltaT), True) self._controlInterval = self._DeltaT else: self._controlInterval = 1. / cfg.CONTROL_RATE self._timeSinceLastControl = 1000. # Check for undefined vtypes and fill with defaults for origType, specialTypes in cfg.PLATOON_VTYPES.items(): if specialTypes[PlatoonMode.FOLLOWER] is None: if rp.VERBOSITY >= 2: report("Setting unspecified follower vtype for '%s' to '%s'" % (origType, specialTypes[PlatoonMode.LEADER]), True) specialTypes[PlatoonMode.FOLLOWER] = specialTypes[PlatoonMode.LEADER] if specialTypes[PlatoonMode.CATCHUP] is None: if rp.VERBOSITY >= 2: report("Setting unspecified catchup vtype for '%s' to '%s'" % (origType, origType), True) specialTypes[PlatoonMode.CATCHUP] = origType if specialTypes[PlatoonMode.CATCHUP_FOLLOWER] is None: if rp.VERBOSITY >= 2: report("Setting unspecified catchup-follower vtype for '%s' to '%s'" % (origType, specialTypes[PlatoonMode.FOLLOWER]), True) specialTypes[PlatoonMode.CATCHUP_FOLLOWER] = specialTypes[PlatoonMode.FOLLOWER] # Commented snippet generated automatically a catchup follower type with a different color # catchupFollowerType = origType + "_catchupFollower" # specialTypes[PlatoonMode.CATCHUP]=catchupFollowerType # if rp.VERBOSITY >= 2: # print("Catchup follower type '%s' for '%s' dynamically created as duplicate of '%s'" % # (catchupFollowerType, origType, specialTypes[PlatoonMode.CATCHUP_FOLLOWER])) # traci.vehicletype.copy(specialTypes[PlatoonMode.CATCHUP_FOLLOWER] , catchupFollowerType) # traci.vehicletype.setColor(catchupFollowerType, (0, 255, 200, 0)) # fill global lookup table for vType parameters (used below in safetycheck) knownVTypes = traci.vehicletype.getIDList() for origType, mappings in cfg.PLATOON_VTYPES.items(): if origType not in knownVTypes: raise SimplaException( "vType '%s' is unknown to sumo! Note: Platooning vTypes must be defined at startup." % origType) origLength = traci.vehicletype.getLength(origType) origEmergencyDecel = traci.vehicletype.getEmergencyDecel(origType) for typeID in list(mappings.values()) + [origType]: if typeID not in knownVTypes: raise SimplaException( "vType '%s' is unknown to sumo! Note: Platooning vTypes must be defined at startup." % typeID) mappedLength = traci.vehicletype.getLength(typeID) mappedEmergencyDecel = traci.vehicletype.getEmergencyDecel(typeID) if origLength != mappedLength: if rp.VERBOSITY >= 1: warn(("length of mapped vType '%s' (%sm.) does not equal length of original vType " + "'%s' (%sm.)\nThis will probably lead to collisions.") % ( typeID, mappedLength, origType, origLength), True) if origEmergencyDecel != mappedEmergencyDecel: if rp.VERBOSITY >= 1: warn(("emergencyDecel of mapped vType '%s' (%gm.) does not equal emergencyDecel of original " + "vType '%s' (%gm.)") % ( typeID, mappedEmergencyDecel, origType, origEmergencyDecel), True) simpla._pvehicle.vTypeParameters[typeID][tc.VAR_TAU] = traci.vehicletype.getTau(typeID) simpla._pvehicle.vTypeParameters[typeID][tc.VAR_DECEL] = traci.vehicletype.getDecel(typeID) simpla._pvehicle.vTypeParameters[typeID][tc.VAR_MINGAP] = traci.vehicletype.getMinGap(typeID) simpla._pvehicle.vTypeParameters[typeID][tc.VAR_EMERGENCY_DECEL] = traci.vehicletype.getEmergencyDecel( typeID)
def load(filename): '''load(string) This loads configuration parameters from a file and overwrites default values. ''' global CONTROL_RATE, VEH_SELECTORS, MAX_PLATOON_GAP, CATCHUP_DIST, PLATOON_SPLIT_TIME global VTYPE_FILE, PLATOON_VTYPES, LC_MODE, SPEEDFACTOR, SWITCH_IMPATIENCE_FACTOR configDir = os.path.dirname(filename) configElements = ET.parse(filename).getroot() parsedTags = [] for e in configElements: parsedTags.append(e.tag) if e.tag == "verbosity": if hasAttributes(e): verbosity = int(list(e.attrib.values())[0]) if verbosity in range(5): rp.VERBOSITY = verbosity else: if rp.VERBOSITY >= 1: warn("Verbosity must be one of %s! Ignoring given value: %s" % (str(list(range(5))), verbosity), True) elif e.tag == "controlRate": if hasAttributes(e): rate = float(list(e.attrib.values())[0]) if rate <= 0.: if rp.VERBOSITY >= 1: warn("Parameter controlRate must be positive. Ignoring given value: %s" % (rate), True) else: CONTROL_RATE = float(rate) elif e.tag == "vehicleSelectors": if hasAttributes(e): VEH_SELECTORS = list(map(lambda x: x.strip(), list(e.attrib.values())[0].split(","))) elif e.tag == "maxPlatoonGap": if hasAttributes(e): maxgap = float(list(e.attrib.values())[0]) if maxgap <= 0: if rp.VERBOSITY >= 1: warn("Parameter maxPlatoonGap must be positive. Ignoring given value: %s" % (maxgap), True) else: MAX_PLATOON_GAP = maxgap elif e.tag == "catchupDist": if hasAttributes(e): dist = float(list(e.attrib.values())[0]) if dist <= 0: if rp.VERBOSITY >= 1: warn("Parameter catchupDist must be positive. Ignoring given value: %s" % (dist), True) else: CATCHUP_DIST = dist elif e.tag == "switchImpatienceFactor": if hasAttributes(e): impfact = float(list(e.attrib.values())[0]) if impfact < 0: if rp.VERBOSITY >= 1: warn("Parameter switchImpatienceFactor must be non-negative. Ignoring given value: %s" % (impfact), True) else: SWITCH_IMPATIENCE_FACTOR = impfact elif e.tag == "platoonSplitTime": if hasAttributes(e): splittime = float(list(e.attrib.values())[0]) if splittime < 0: if rp.VERBOSITY >= 1: warn("Parameter platoonSplitTime must be non-negative. Ignoring given value: %s" % (splittime), True) else: PLATOON_SPLIT_TIME = splittime elif e.tag == "lcMode": if hasAttributes(e): if ("leader" in e.attrib): if isValidLCMode(int(e.attrib["leader"])): LC_MODE[PlatoonMode.LEADER] = int(e.attrib["leader"]) if ("follower" in e.attrib): if isValidLCMode(int(e.attrib["follower"])): LC_MODE[PlatoonMode.FOLLOWER] = int(e.attrib["follower"]) if ("catchup" in e.attrib): if isValidLCMode(int(e.attrib["catchup"])): LC_MODE[PlatoonMode.CATCHUP] = int(e.attrib["catchup"]) if ("catchupFollower" in e.attrib): if isValidLCMode(int(e.attrib["catchupFollower"])): LC_MODE[PlatoonMode.CATCHUP_FOLLOWER] = int(e.attrib["catchupFollower"]) if ("original" in e.attrib): if isValidLCMode(int(e.attrib["original"])): LC_MODE[PlatoonMode.NONE] = int(e.attrib["original"]) elif e.tag == "speedFactor": if hasAttributes(e): if ("leader" in e.attrib): if isValidSpeedFactor(float(e.attrib["leader"])): SPEEDFACTOR[PlatoonMode.LEADER] = float(e.attrib["leader"]) if ("follower" in e.attrib): if isValidSpeedFactor(float(e.attrib["follower"])): SPEEDFACTOR[PlatoonMode.FOLLOWER] = float(e.attrib["follower"]) if ("catchup" in e.attrib): if isValidSpeedFactor(float(e.attrib["catchup"])): SPEEDFACTOR[PlatoonMode.CATCHUP] = float(e.attrib["catchup"]) if ("catchupFollower" in e.attrib): if isValidSpeedFactor(float(e.attrib["catchupFollower"])): SPEEDFACTOR[PlatoonMode.CATCHUP_FOLLOWER] = float(e.attrib["catchupFollower"]) if ("original" in e.attrib): if isValidSpeedFactor(float(e.attrib["original"])): SPEEDFACTOR[PlatoonMode.NONE] = float(e.attrib["original"]) elif e.tag == "vTypeMapFile": if hasAttributes(e): fn = os.path.join(configDir, list(e.attrib.values())[0]) if not os.path.isfile(fn): raise SimplaException("Given vTypeMapFile '%s' does not exist." % fn) VTYPE_FILE = fn elif e.tag == "vTypeMap": if hasAttributes(e): if "original" not in e.attrib: warn("vTypeMap must specify original type. Ignoring malformed vTypeMap element.", True) else: origType = e.attrib["original"] PLATOON_VTYPES[origType][PlatoonMode.NONE] = origType if ("leader" in e.attrib): leaderType = e.attrib["leader"] PLATOON_VTYPES[origType][PlatoonMode.LEADER] = leaderType # report("Registering vtype map '%s':'%s'"%(origType,leaderType), True) if ("follower" in e.attrib): followerType = e.attrib["follower"] PLATOON_VTYPES[origType][PlatoonMode.FOLLOWER] = followerType # report("Registering vtype map '%s':'%s'"%(origType,followerType), True) if ("catchup" in e.attrib): catchupType = e.attrib["catchup"] PLATOON_VTYPES[origType][PlatoonMode.CATCHUP] = catchupType # report("Registering vtype map '%s':'%s'"%(origType,followerType), True) if ("catchupFollower" in e.attrib): catchupFollowerType = e.attrib["catchupFollower"] PLATOON_VTYPES[origType][PlatoonMode.CATCHUP_FOLLOWER] = catchupFollowerType # report("Registering vtype map '%s':'%s'"%(origType,followerType), True) elif rp.VERBOSITY >= 1: warn("Encountered unknown configuration parameter '%s'!" % e.tag, True) if "vTypeMapFile" in parsedTags: # load vType mapping from file loadVTypeMap(VTYPE_FILE) if SPEEDFACTOR[PlatoonMode.CATCHUP_FOLLOWER] is None: # if unset, set speedfactor for catchupfollower mode to the same as in catchup mode SPEEDFACTOR[PlatoonMode.CATCHUP_FOLLOWER] = SPEEDFACTOR[PlatoonMode.CATCHUP]