Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/tools/output/generateTLSE3Detectors.py
169674 views
1
#!/usr/bin/env python
2
# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
# Copyright (C) 2009-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 generateTLSE3Detectors.py
15
# @author Daniel Krajzewicz
16
# @author Karol Stosiek
17
# @author Michael Behrisch
18
# @date 2007-10-25
19
20
from __future__ import absolute_import
21
from __future__ import print_function
22
23
import logging
24
import optparse
25
import os
26
import sys
27
28
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
29
import sumolib # noqa
30
31
32
def getOptions():
33
option_parser = optparse.OptionParser()
34
option_parser.add_option("-n", "--net-file",
35
dest="net_file",
36
help="Network file to work with. Mandatory.",
37
type="string")
38
option_parser.add_option("-j", "--junction-ids",
39
dest="junctionIDs",
40
help="List of junctions that shall receive detectors (comma separated)",
41
type="string")
42
option_parser.add_option("-l", "--detector-length",
43
dest="requested_detector_length",
44
help="Length of the detector in meters "
45
"(-1 for maximal length).",
46
type="int",
47
default=250)
48
option_parser.add_option("-d", "--distance-to-TLS",
49
dest="requested_distance_to_tls",
50
help="Distance of the detector to the traffic "
51
"light in meters. Defaults to 0.1m.",
52
type="float",
53
default=.1)
54
option_parser.add_option("-f", "--frequency",
55
dest="frequency",
56
help="Detector's frequency. Defaults to 60.",
57
type="int",
58
default=60)
59
option_parser.add_option("-o", "--output",
60
dest="output",
61
help="The name of the file to write the detector "
62
"definitions into. Defaults to e3.add.xml.",
63
type="string",
64
default="e3.add.xml")
65
option_parser.add_option("--prefix",
66
dest="prefix",
67
help="Prefix for generated detectors",
68
type="string",
69
default="e3_")
70
option_parser.add_option("-r", "--results-file",
71
dest="results",
72
help="The name of the file the detectors write "
73
"their output into. Defaults to e3output.xml.",
74
type="string",
75
default="e3output.xml")
76
option_parser.add_option("--min-pos",
77
dest="minPos",
78
help="minimum position of entry detectors light in meters. Defaults to 0.1m.",
79
type="float",
80
default=.1)
81
82
option_parser.add_option(
83
"--interior", action="store_true",
84
default=False, help="Extend measurement area to the junction interior")
85
option_parser.add_option(
86
"--joined", action="store_true",
87
default=False, help="Create one e3Detector per junction")
88
option_parser.add_option(
89
"--follow-turnaround", dest="followTurnaround", action="store_true",
90
default=False, help="Extend entry detectors past turn-around connections")
91
option_parser.set_usage("generateTLSE3Detectors.py -n example.net.xml "
92
"-l 250 -d .1 -f 60")
93
94
(options, args) = option_parser.parse_args()
95
if not options.net_file:
96
print("Missing arguments")
97
option_parser.print_help()
98
exit()
99
return options
100
101
102
def writeEntryExit(options, edge, detector_xml, writeExit=True):
103
stopOnTLS = True
104
stopOnTurnaround = not options.followTurnaround
105
input_edges = network.getUpstreamEdges(
106
edge, options.requested_detector_length, stopOnTLS, stopOnTurnaround)
107
input_edges.sort(key=lambda vals: vals[0].getID())
108
for firstEdge, position, intermediate, aborted in input_edges:
109
if aborted:
110
position = .1
111
position = max(position, min(options.minPos, firstEdge.getLength()))
112
for lane in firstEdge.getLanes():
113
detector_entry_xml = detector_xml.addChild("detEntry")
114
detector_entry_xml.setAttribute("lane", lane.getID())
115
detector_entry_xml.setAttribute("pos", "%.2f" % position)
116
117
if writeExit:
118
if options.interior:
119
# exit just after leaving the intersection
120
for e2 in sorted(edge.getOutgoing(), key=lambda e: e.getID()):
121
for lane in e2.getLanes():
122
detector_exit_xml = detector_xml.addChild("detExit")
123
detector_exit_xml.setAttribute("lane", lane.getID())
124
detector_exit_xml.setAttribute("pos", "0")
125
else:
126
# exit just before entering the intersection
127
for lane in edge.getLanes():
128
detector_exit_xml = detector_xml.addChild("detExit")
129
detector_exit_xml.setAttribute("lane", lane.getID())
130
detector_exit_xml.setAttribute("pos", "-.1")
131
132
133
if __name__ == "__main__":
134
# pylint: disable-msg=C0103
135
options = getOptions()
136
137
logging.basicConfig(level="INFO")
138
139
logging.info("Reading net...")
140
network = sumolib.net.readNet(options.net_file)
141
142
logging.info("Generating detectors...")
143
detectors_xml = sumolib.xml.create_document("additional")
144
generated_detectors = 0
145
146
tlsList, getEdges = network._tlss, sumolib.net.TLS.getEdges
147
if options.junctionIDs:
148
tlsList = [network.getNode(n) for n in options.junctionIDs.split(',')]
149
getEdges = sumolib.net.node.Node.getIncoming
150
151
for tls in tlsList:
152
if options.joined:
153
detector_xml = detectors_xml.addChild("e3Detector")
154
detector_xml.setAttribute("id", options.prefix + str(tls.getID()))
155
detector_xml.setAttribute("freq", str(options.frequency))
156
detector_xml.setAttribute("file", options.results)
157
generated_detectors += 1
158
writeExit = True
159
for edge in sorted(getEdges(tls), key=sumolib.net.edge.Edge.getID):
160
writeEntryExit(options, edge, detector_xml, writeExit)
161
writeExit = not options.interior
162
163
else:
164
for edge in sorted(getEdges(tls), key=sumolib.net.edge.Edge.getID):
165
detector_xml = detectors_xml.addChild("e3Detector")
166
detector_xml.setAttribute(
167
"id", options.prefix + str(tls.getID()) + "_" + str(edge.getID()))
168
detector_xml.setAttribute("freq", str(options.frequency))
169
detector_xml.setAttribute("file", options.results)
170
if options.interior:
171
detector_xml.setAttribute("openEntry", "true")
172
writeEntryExit(options, edge, detector_xml)
173
generated_detectors += 1
174
175
detector_file = open(options.output, 'w')
176
detector_file.write(detectors_xml.toXML())
177
detector_file.close()
178
179
logging.info("%d e3 detectors generated!" % (generated_detectors))
180
181