Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/fcdReplay.py
169660 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 fcdReplay.py
15
# @author Jakob Erdmann
16
# @date 2023-01-11
17
18
"""
19
Replay an fcd-file as moving POIs on top of a simulation (or empty network)
20
"""
21
22
from __future__ import print_function
23
import os
24
import sys
25
from collections import defaultdict
26
sys.path.append(os.path.join(os.environ["SUMO_HOME"], 'tools'))
27
import sumolib # noqa
28
import traci # noqa
29
30
31
def main():
32
parser = sumolib.options.ArgumentParser()
33
parser.add_argument("-k", "--sumo-config", category="input", default="sumo.sumocfg", help="sumo config file")
34
parser.add_argument("-f", "--fcd-files", category="processing", dest="fcdFiles", help="the fcd files to replay")
35
parser.add_argument("--geo", category="processing", action="store_true", default=False,
36
help="use fcd data in lon,lat format")
37
parser.add_argument("-v", "--verbose", category="processing", action="store_true", default=False,
38
help="tell me what you are doing")
39
parser.add_argument("sumo_args", nargs="*", catch_all=True, help="additional sumo arguments")
40
options = parser.parse_args()
41
42
sumoBinary = sumolib.checkBinary("sumo-gui")
43
traci.start([sumoBinary, "-c", options.sumo_config] + options.sumo_args)
44
t = traci.simulation.getTime()
45
deltaT = traci.simulation.getDeltaT()
46
47
fcdData = defaultdict(list) # time -> objects
48
lastTime = {} # objectID -> last known time
49
for fname in options.fcdFiles.split(','):
50
if options.verbose:
51
print("Loading fcd data from '%s'" % fname)
52
for ts in sumolib.xml.parse(fname, 'timestep'):
53
time = sumolib.miscutils.parseTime(ts.time)
54
if time < t:
55
continue
56
for obj in ts.getChildList():
57
obj.x = float(obj.x)
58
obj.y = float(obj.y)
59
if options.geo:
60
obj.x, obj.y = traci.simulation.convertGeo(obj.x, obj.y, True)
61
fcdData[time].append(obj)
62
lastTime[obj.id] = time
63
64
removeAtTime = defaultdict(list) # time -> objects to remove
65
for oID, rt in lastTime.items():
66
removeAtTime[rt + deltaT].append(oID)
67
68
end = max(max(lastTime.values()), traci.simulation.getEndTime())
69
created = set()
70
71
while t <= end:
72
for obj in fcdData.get(t, []):
73
if obj.id in created:
74
traci.poi.setPosition(obj.id, obj.x, obj.y)
75
else:
76
traci.poi.add(obj.id, obj.x, obj.y, (255, 0, 0, 255), layer=340)
77
created.add(obj.id)
78
for a, v in obj.getAttributes():
79
if a == 'x' or a == 'y' or a == 'id':
80
continue
81
traci.poi.setParameter(obj.id, a, v)
82
for objID in removeAtTime.get(t, []):
83
traci.poi.remove(objID)
84
85
traci.simulationStep()
86
t = traci.simulation.getTime()
87
88
traci.close()
89
90
91
if __name__ == "__main__":
92
main()
93
94