Path: blob/main/tests/complex/tutorial/city_mobil/data/agentManager.py
169708 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 agentManager.py14# @author Michael Behrisch15# @author Daniel Krajzewicz16# @date 2008-10-091718from __future__ import absolute_import19import vehicleControl20import statistics21from constants import INFINITY, DOUBLE_ROWS, ROW_DIST, CYBER_SPEED, WAIT_PER_PERSON222324class PersonAgent:2526def __init__(self, id):27self.id = id2829def startRequest(self, source, target, cybers):30minCost = INFINITY31minCar = None32for car in cybers:33cost = car.request(self, source, target)34if (cost < minCost):35if minCar:36minCar.reject(self)37minCar = car38minCost = cost39else:40car.reject(self)41minCar.accept(self)424344class Task:4546def __init__(self, person, source, target, estCost):47self.person = person48self.source = source49self.target = target50self.estCost = estCost51self.startStep = None5253def __repr__(self):54return "<%s %s %s %s>" % (self.person.id, self.source, self.target, self.startStep)555657class CyberAgent:5859def __init__(self, id):60self.id = id61self.load = 062self.pending = {}63self.tasks = []64self.running = []65self.costMatrix = {}66self.totalEstimatedCost = 067self.position = None68self.broken = False6970def request(self, person, source, target):71if self.broken:72estCost = INFINITY73elif (source, target) in self.costMatrix:74estCost = self.costMatrix[(source, target)]75else:76estCost = 2 * DOUBLE_ROWS * ROW_DIST / CYBER_SPEED77self.pending[person] = Task(person, source, target, estCost)78return self.totalEstimatedCost + estCost7980def accept(self, person):81task = self.pending[person]82self.tasks.append(task)83self.totalEstimatedCost += task.estCost84del self.pending[person]8586def reject(self, person):87del self.pending[person]8889def _findNextTarget(self, wait):90minTarget = "z"91minDownstreamTarget = "z"92minSource = "z"93minDownstreamSource = "z"94edge = vehicleControl.getPosition(self.id)95if edge == "cyberin":96edge = "cyber"97for task in self.running:98if task.target < minTarget:99minTarget = task.target100if task.target < minDownstreamTarget and task.target > edge:101minDownstreamTarget = task.target102for task in self.tasks[:vehicleControl.getCapacity() - self.load]:103if task.source < minSource:104minSource = task.source105if task.source < minDownstreamSource and task.source > edge:106minDownstreamSource = task.source107if minDownstreamTarget != "z":108minTarget = minDownstreamTarget109elif minDownstreamSource < minTarget:110minTarget = minDownstreamSource111elif minTarget < edge and minSource < minTarget:112minTarget = minSource113if minTarget == "z":114minTarget = "cyberin"115if minTarget != vehicleControl.getPosition(self.id):116vehicleControl.leaveStop(self.id, delay=wait)117vehicleControl.stopAt(self.id, minTarget)118119def setPosition(self, edge):120self.position = edge121self.broken = False122123def checkBoarding(self):124step = vehicleControl.getStep()125wait = 0126running = []127for task in self.running:128if task.target == self.position:129statistics.personUnloaded(task.person.id, step)130self.load -= 1131wait += WAIT_PER_PERSON132self.costMatrix[133(task.source, task.target)] = step - task.startStep134self.totalEstimatedCost -= task.estCost135else:136running.append(task)137self.running = running138if self.load < vehicleControl.getCapacity():139tasks = []140for task in self.tasks:141if task.source == self.position and self.load < vehicleControl.getCapacity():142vehicleControl.leaveStop(task.person.id)143statistics.personLoaded(task.person.id, step)144self.load += 1145wait += WAIT_PER_PERSON146task.startStep = step147self.running.append(task)148else:149tasks.append(task)150self.tasks = tasks151self._findNextTarget(wait)152153def reallocateTasks(self, cybers):154self.broken = True155tasks = self.tasks156self.tasks = []157for task in tasks:158task.person.startRequest(task.source, task.target, cybers)159160161class AgentManager(vehicleControl.Manager):162163def __init__(self):164self.agents = {}165self.cyberCars = []166167def personArrived(self, personID, edge, target):168if personID not in self.agents:169person = PersonAgent(personID)170self.agents[personID] = person171person.startRequest(edge.replace("footmain", "cyber"),172target.replace("footmain", "cyber"), self.cyberCars)173174def cyberCarArrived(self, vehicleID, edge):175if vehicleID in self.agents:176cyberCar = self.agents[vehicleID]177else:178cyberCar = CyberAgent(vehicleID)179self.agents[vehicleID] = cyberCar180self.cyberCars.append(cyberCar)181cyberCar.setPosition(edge)182183def cyberCarBroken(self, vehicleID, edge):184self.agents[vehicleID].reallocateTasks(self.cyberCars)185186def setNewTargets(self):187for car in self.cyberCars:188if not car.broken:189car.checkBoarding()190191192if __name__ == "__main__":193vehicleControl.init(AgentManager())194195196