Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tests/complex/tutorial/city_mobil/data/agentManager.py
169708 views
1
#!/usr/bin/env python
2
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
# Copyright (C) 2008-2025 German Aerospace Center (DLR) and others.
4
# This program and the accompanying materials are made available under the
5
# terms of the Eclipse Public License 2.0 which is available at
6
# https://www.eclipse.org/legal/epl-2.0/
7
# This Source Code may also be made available under the following Secondary
8
# Licenses when the conditions for such availability set forth in the Eclipse
9
# Public License 2.0 are satisfied: GNU General Public License, version 2
10
# or later which is available at
11
# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13
14
# @file agentManager.py
15
# @author Michael Behrisch
16
# @author Daniel Krajzewicz
17
# @date 2008-10-09
18
19
from __future__ import absolute_import
20
import vehicleControl
21
import statistics
22
from constants import INFINITY, DOUBLE_ROWS, ROW_DIST, CYBER_SPEED, WAIT_PER_PERSON
23
24
25
class PersonAgent:
26
27
def __init__(self, id):
28
self.id = id
29
30
def startRequest(self, source, target, cybers):
31
minCost = INFINITY
32
minCar = None
33
for car in cybers:
34
cost = car.request(self, source, target)
35
if (cost < minCost):
36
if minCar:
37
minCar.reject(self)
38
minCar = car
39
minCost = cost
40
else:
41
car.reject(self)
42
minCar.accept(self)
43
44
45
class Task:
46
47
def __init__(self, person, source, target, estCost):
48
self.person = person
49
self.source = source
50
self.target = target
51
self.estCost = estCost
52
self.startStep = None
53
54
def __repr__(self):
55
return "<%s %s %s %s>" % (self.person.id, self.source, self.target, self.startStep)
56
57
58
class CyberAgent:
59
60
def __init__(self, id):
61
self.id = id
62
self.load = 0
63
self.pending = {}
64
self.tasks = []
65
self.running = []
66
self.costMatrix = {}
67
self.totalEstimatedCost = 0
68
self.position = None
69
self.broken = False
70
71
def request(self, person, source, target):
72
if self.broken:
73
estCost = INFINITY
74
elif (source, target) in self.costMatrix:
75
estCost = self.costMatrix[(source, target)]
76
else:
77
estCost = 2 * DOUBLE_ROWS * ROW_DIST / CYBER_SPEED
78
self.pending[person] = Task(person, source, target, estCost)
79
return self.totalEstimatedCost + estCost
80
81
def accept(self, person):
82
task = self.pending[person]
83
self.tasks.append(task)
84
self.totalEstimatedCost += task.estCost
85
del self.pending[person]
86
87
def reject(self, person):
88
del self.pending[person]
89
90
def _findNextTarget(self, wait):
91
minTarget = "z"
92
minDownstreamTarget = "z"
93
minSource = "z"
94
minDownstreamSource = "z"
95
edge = vehicleControl.getPosition(self.id)
96
if edge == "cyberin":
97
edge = "cyber"
98
for task in self.running:
99
if task.target < minTarget:
100
minTarget = task.target
101
if task.target < minDownstreamTarget and task.target > edge:
102
minDownstreamTarget = task.target
103
for task in self.tasks[:vehicleControl.getCapacity() - self.load]:
104
if task.source < minSource:
105
minSource = task.source
106
if task.source < minDownstreamSource and task.source > edge:
107
minDownstreamSource = task.source
108
if minDownstreamTarget != "z":
109
minTarget = minDownstreamTarget
110
elif minDownstreamSource < minTarget:
111
minTarget = minDownstreamSource
112
elif minTarget < edge and minSource < minTarget:
113
minTarget = minSource
114
if minTarget == "z":
115
minTarget = "cyberin"
116
if minTarget != vehicleControl.getPosition(self.id):
117
vehicleControl.leaveStop(self.id, delay=wait)
118
vehicleControl.stopAt(self.id, minTarget)
119
120
def setPosition(self, edge):
121
self.position = edge
122
self.broken = False
123
124
def checkBoarding(self):
125
step = vehicleControl.getStep()
126
wait = 0
127
running = []
128
for task in self.running:
129
if task.target == self.position:
130
statistics.personUnloaded(task.person.id, step)
131
self.load -= 1
132
wait += WAIT_PER_PERSON
133
self.costMatrix[
134
(task.source, task.target)] = step - task.startStep
135
self.totalEstimatedCost -= task.estCost
136
else:
137
running.append(task)
138
self.running = running
139
if self.load < vehicleControl.getCapacity():
140
tasks = []
141
for task in self.tasks:
142
if task.source == self.position and self.load < vehicleControl.getCapacity():
143
vehicleControl.leaveStop(task.person.id)
144
statistics.personLoaded(task.person.id, step)
145
self.load += 1
146
wait += WAIT_PER_PERSON
147
task.startStep = step
148
self.running.append(task)
149
else:
150
tasks.append(task)
151
self.tasks = tasks
152
self._findNextTarget(wait)
153
154
def reallocateTasks(self, cybers):
155
self.broken = True
156
tasks = self.tasks
157
self.tasks = []
158
for task in tasks:
159
task.person.startRequest(task.source, task.target, cybers)
160
161
162
class AgentManager(vehicleControl.Manager):
163
164
def __init__(self):
165
self.agents = {}
166
self.cyberCars = []
167
168
def personArrived(self, personID, edge, target):
169
if personID not in self.agents:
170
person = PersonAgent(personID)
171
self.agents[personID] = person
172
person.startRequest(edge.replace("footmain", "cyber"),
173
target.replace("footmain", "cyber"), self.cyberCars)
174
175
def cyberCarArrived(self, vehicleID, edge):
176
if vehicleID in self.agents:
177
cyberCar = self.agents[vehicleID]
178
else:
179
cyberCar = CyberAgent(vehicleID)
180
self.agents[vehicleID] = cyberCar
181
self.cyberCars.append(cyberCar)
182
cyberCar.setPosition(edge)
183
184
def cyberCarBroken(self, vehicleID, edge):
185
self.agents[vehicleID].reallocateTasks(self.cyberCars)
186
187
def setNewTargets(self):
188
for car in self.cyberCars:
189
if not car.broken:
190
car.checkBoarding()
191
192
193
if __name__ == "__main__":
194
vehicleControl.init(AgentManager())
195
196