Path: blob/main/tests/complex/traci/vehicle/openGap/runner.py
169689 views
#!/usr/bin/env python1# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2# Copyright (C) 2008-2025 German Aerospace Center (DLR) and others.3# This program and the accompanying materials are made available under the4# terms of the Eclipse Public License 2.0 which is available at5# https://www.eclipse.org/legal/epl-2.0/6# This Source Code may also be made available under the following Secondary7# Licenses when the conditions for such availability set forth in the Eclipse8# Public License 2.0 are satisfied: GNU General Public License, version 29# or later which is available at10# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later1213# @file runner.py14# @author Leonhard Luecken15# @date 2018-11-021617from __future__ import absolute_import18from __future__ import print_function1920import os21import sys2223if "SUMO_HOME" in os.environ:24sys.path.append(os.path.join(os.environ["SUMO_HOME"], "tools"))25import sumolib # noqa26import traci # noqa27import traci.constants as tc # noqa28sumoBinary = sumolib.checkBinary(sys.argv[1])2930# id of vehicle that is controlled31followerID = "follower"32# id of vehicle that is followed33leaderID = "leader"34# time to simulate after gap control is released35extraTime = 50.36# Offset to trigger phase of keeping enlarged headway37POSITIONAL_EPS = 0.1383940def runSingle(targetTimeHeadway, targetSpaceHeadway, duration, changeRate, maxDecel, refVehID):41step = 042traci.start([sumoBinary, "-c", "sumo.sumocfg"])43# traci.init(port=54321)44dt = traci.simulation.getDeltaT()4546traci.simulationStep()47# print(traci.vehicle.getIDList())48print("Fix follower's lane.")49traci.vehicle.changeLane(followerID, 0, 500)50print("Subscribe to leader.")51traci.vehicle.subscribeLeader(followerID, 500)52traci.vehicle.subscribe(followerID, [tc.VAR_SPEED])53traci.vehicle.subscribe(leaderID, [tc.VAR_SPEED])5455gapControlActive = False56targetGapEstablished = False57remainingTime = duration58testCompleted = False59prevLeader = ""60leaderArrived = False61while not testCompleted:62traci.simulationStep()63results = traci.vehicle.getSubscriptionResults(followerID)64if refVehID == "":65leader = results[tc.VAR_LEADER][0]66leaderDist = results[tc.VAR_LEADER][1]67elif not leaderArrived:68leader = refVehID69arrived = traci.simulation.getArrivedIDList()70# print ("arrived vehicles: %s"%(str(arrived)))71if leader in arrived:72print("Reference vehicle has been removed.")73leaderArrived = True74targetGapEstablished = True75gapControlActive = False76else:77traci.vehicle.subscribe(leaderID, [tc.VAR_SPEED])78leaderEdgeID = traci.vehicle.getRoadID(leader)79leaderPos = traci.vehicle.getLanePosition(leader)80leaderDist = traci.vehicle.getDrivingDistance(followerID, leaderEdgeID, leaderPos)81followerSpeed = results[tc.VAR_SPEED]82leaderSpeed = traci.vehicle.getSubscriptionResults(leaderID)[tc.VAR_SPEED]83currentTimeHeadway = leaderDist/followerSpeed if followerSpeed > 0 else 1000084currentTime = traci.simulation.getTime()85print("Time %s: Gap 'follower'->'%s' = %.3f (headway=%.3f)" %86(currentTime, leader, leaderDist, currentTimeHeadway))87print("'follower' speed = %s" % followerSpeed)88sys.stdout.flush()89if (not gapControlActive and not targetGapEstablished and currentTime > 50.):90print("## Starting to open gap.")91sys.stdout.flush()92print("(followerID, targetTimeHeadway, targetSpaceHeadway, duration, changeRate) = %s" %93str((followerID, targetTimeHeadway, targetSpaceHeadway, duration, changeRate)))94if refVehID == "":95if maxDecel == -1:96traci.vehicle.openGap(followerID, targetTimeHeadway, targetSpaceHeadway, duration, changeRate)97else:98print("maxDecel = %s" % maxDecel)99traci.vehicle.openGap(followerID, targetTimeHeadway, targetSpaceHeadway, duration, changeRate,100maxDecel)101else:102print("(maxDecel, refVehID) = %s" % str((maxDecel, refVehID)))103traci.vehicle.openGap(followerID, targetTimeHeadway, targetSpaceHeadway, duration, changeRate,104maxDecel, refVehID)105if maxDecel == -1:106# For test 'reference_vehicle_removed' set new route for merger107traci.vehicle.setRouteID('merger', 'route_merger')108109gapControlActive = True110elif gapControlActive:111print("Current/target headway: {0:.3f}/{1}".format(currentTimeHeadway, targetTimeHeadway))112currentSpacing = currentTimeHeadway * followerSpeed113targetSpacing = targetTimeHeadway * followerSpeed114minSpacing = max(targetSpacing, targetSpaceHeadway) - POSITIONAL_EPS115if not targetGapEstablished and (leader == "" or currentSpacing > minSpacing or prevLeader != leader):116if (leader != "" and prevLeader != leader):117traci.vehicle.deactivateGapControl(followerID)118print("## Deactivating gap control (leader has changed).")119remainingTime = 0.0120else:121print("## Target Headway attained.")122targetGapEstablished = True123if targetGapEstablished:124remainingTime -= dt125print("Remaining: %s" % max(0.0, remainingTime))126if gapControlActive and remainingTime < 0.:127gapControlActive = False128print("## Gap control expired.")129if remainingTime <= -extraTime:130testCompleted = True131if leaderSpeed == 0:132# Let leader go on slowly, to test space gap133traci.vehicle.setSpeed(leaderID, 1.)134prevLeader = leader135step += 1136137traci.close()138sys.stdout.flush()139140141sys.stdout.flush()142targetTimeHeadway = float(sys.argv[2])143targetSpaceHeadway = float(sys.argv[3])144duration = float(sys.argv[4])145changeRate = float(sys.argv[5])146if (len(sys.argv) > 6):147maxDecel = float(sys.argv[6])148if (len(sys.argv) > 7):149refVehID = sys.argv[7]150else:151refVehID = ""152else:153maxDecel = -1154refVehID = ""155runSingle(targetTimeHeadway, targetSpaceHeadway, duration, changeRate, maxDecel, refVehID)156157158