Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netimport/vissim/tempstructs/NIVissimTL.cpp
169684 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-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 NIVissimTL.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Jakob Erdmann
17
/// @author Michael Behrisch
18
/// @date Sept 2002
19
///
20
// -------------------
21
/****************************************************************************/
22
#include <config.h>
23
24
25
#include <map>
26
#include <string>
27
#include <cassert>
28
#include <utils/geom/GeomHelper.h>
29
#include <utils/geom/Boundary.h>
30
#include <utils/common/MsgHandler.h>
31
#include <utils/common/ToString.h>
32
#include "NIVissimConnection.h"
33
#include <netbuild/NBEdge.h>
34
#include <netbuild/NBEdgeCont.h>
35
#include <netbuild/NBTrafficLightLogicCont.h>
36
#include <netbuild/NBLoadedTLDef.h>
37
#include "NIVissimDisturbance.h"
38
#include "NIVissimNodeDef.h"
39
#include "NIVissimEdge.h"
40
#include "NIVissimTL.h"
41
42
43
// ===========================================================================
44
// static member variables
45
// ===========================================================================
46
NIVissimTL::SignalDictType NIVissimTL::NIVissimTLSignal::myDict;
47
48
49
// ===========================================================================
50
// method definitions
51
// ===========================================================================
52
NIVissimTL::NIVissimTLSignal::NIVissimTLSignal(int id,
53
const std::string& name,
54
const std::vector<int>& groupids,
55
int edgeid,
56
int laneno,
57
double position,
58
const std::vector<int>& vehicleTypes)
59
: myID(id), myName(name), myGroupIDs(groupids),
60
myEdgeID(edgeid), myLane(laneno), myPosition(position),
61
myVehicleTypes(vehicleTypes) {}
62
63
64
NIVissimTL::NIVissimTLSignal::~NIVissimTLSignal() {}
65
66
bool
67
NIVissimTL::NIVissimTLSignal::isWithin(const PositionVector& poly) const {
68
return poly.around(getPosition());
69
}
70
71
72
Position
73
NIVissimTL::NIVissimTLSignal::getPosition() const {
74
return NIVissimAbstractEdge::dictionary(myEdgeID)->getGeomPosition(myPosition);
75
}
76
77
78
bool
79
NIVissimTL::NIVissimTLSignal::dictionary(int lsaid, int id,
80
NIVissimTL::NIVissimTLSignal* o) {
81
SignalDictType::iterator i = myDict.find(lsaid);
82
if (i == myDict.end()) {
83
myDict[lsaid] = SSignalDictType();
84
i = myDict.find(lsaid);
85
}
86
SSignalDictType::iterator j = (*i).second.find(id);
87
if (j == (*i).second.end()) {
88
myDict[lsaid][id] = o;
89
return true;
90
}
91
return false;
92
}
93
94
95
NIVissimTL::NIVissimTLSignal*
96
NIVissimTL::NIVissimTLSignal::dictionary(int lsaid, int id) {
97
SignalDictType::iterator i = myDict.find(lsaid);
98
if (i == myDict.end()) {
99
return nullptr;
100
}
101
SSignalDictType::iterator j = (*i).second.find(id);
102
if (j == (*i).second.end()) {
103
return nullptr;
104
}
105
return (*j).second;
106
}
107
108
109
void
110
NIVissimTL::NIVissimTLSignal::clearDict() {
111
for (SignalDictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
112
for (SSignalDictType::iterator j = (*i).second.begin(); j != (*i).second.end(); j++) {
113
delete (*j).second;
114
}
115
}
116
myDict.clear();
117
}
118
119
120
NIVissimTL::SSignalDictType
121
NIVissimTL::NIVissimTLSignal::getSignalsFor(int tlid) {
122
SignalDictType::iterator i = myDict.find(tlid);
123
if (i == myDict.end()) {
124
return SSignalDictType();
125
}
126
return (*i).second;
127
}
128
129
130
bool
131
NIVissimTL::NIVissimTLSignal::addTo(NBEdgeCont& ec, NBLoadedTLDef* tl) const {
132
NIVissimConnection* c = NIVissimConnection::dictionary(myEdgeID);
133
NBConnectionVector assignedConnections;
134
if (c == nullptr) {
135
// What to do if on an edge? -> close all outgoing connections
136
NBEdge* edge = ec.retrievePossiblySplit(toString<int>(myEdgeID), myPosition);
137
if (edge == nullptr) {
138
WRITE_WARNINGF(TL("Could not set tls signal at edge '%' - the edge was not built."), myEdgeID);
139
return false;
140
}
141
// Check whether it is already known, which edges are approached
142
// by which lanes
143
// check whether to use the original lanes only
144
if (edge->lanesWereAssigned()) {
145
std::vector<NBEdge::Connection> connections = edge->getConnectionsFromLane(myLane - 1);
146
for (std::vector<NBEdge::Connection>::iterator i = connections.begin(); i != connections.end(); i++) {
147
const NBEdge::Connection& conn = *i;
148
assert(myLane - 1 < (int)edge->getNumLanes());
149
assignedConnections.push_back(NBConnection(edge, myLane - 1, conn.toEdge, conn.toLane));
150
}
151
} else {
152
WRITE_WARNINGF(TL("Edge '%': Lanes were not assigned."), myEdgeID);
153
for (int j = 0; j < edge->getNumLanes(); j++) {
154
std::vector<NBEdge::Connection> connections = edge->getConnectionsFromLane(j);
155
for (std::vector<NBEdge::Connection>::iterator i = connections.begin(); i != connections.end(); i++) {
156
const NBEdge::Connection& conn = *i;
157
assignedConnections.push_back(NBConnection(edge, j, conn.toEdge, conn.toLane));
158
}
159
}
160
}
161
} else {
162
// get the edges
163
NBEdge* tmpFrom = ec.retrievePossiblySplit(toString<int>(c->getFromEdgeID()), toString<int>(c->getToEdgeID()), true);
164
NBEdge* tmpTo = ec.retrievePossiblySplit(toString<int>(c->getToEdgeID()), toString<int>(c->getFromEdgeID()), false);
165
// check whether the edges are known
166
if (tmpFrom != nullptr && tmpTo != nullptr) {
167
// add connections this signal is responsible for
168
assignedConnections.push_back(NBConnection(tmpFrom, -1, tmpTo, -1));
169
} else {
170
return false;
171
// !!! one of the edges could not be build
172
}
173
}
174
// add to the group
175
assert(myGroupIDs.size() != 0);
176
// @todo just another hack?!
177
/*
178
if (myGroupIDs.size() == 1) {
179
return tl->addToSignalGroup(toString<int>(*(myGroupIDs.begin())),
180
assignedConnections);
181
} else {
182
// !!!
183
return tl->addToSignalGroup(toString<int>(*(myGroupIDs.begin())),
184
assignedConnections);
185
}
186
*/
187
return tl->addToSignalGroup(toString<int>(myGroupIDs.front()), assignedConnections);
188
}
189
190
191
192
193
194
195
196
197
NIVissimTL::GroupDictType NIVissimTL::NIVissimTLSignalGroup::myDict;
198
199
NIVissimTL::NIVissimTLSignalGroup::NIVissimTLSignalGroup(
200
int id,
201
const std::string& name,
202
bool isGreenBegin, const std::vector<SUMOTime>& times,
203
SUMOTime tredyellow, SUMOTime tyellow)
204
: myID(id), myName(name), myTimes(times),
205
myFirstIsRed(!isGreenBegin), myTRedYellow(tredyellow),
206
myTYellow(tyellow) {}
207
208
209
NIVissimTL::NIVissimTLSignalGroup::~NIVissimTLSignalGroup() {}
210
211
212
bool
213
NIVissimTL::NIVissimTLSignalGroup::dictionary(int lsaid, int id,
214
NIVissimTL::NIVissimTLSignalGroup* o) {
215
GroupDictType::iterator i = myDict.find(lsaid);
216
if (i == myDict.end()) {
217
myDict[lsaid] = SGroupDictType();
218
i = myDict.find(lsaid);
219
}
220
SGroupDictType::iterator j = (*i).second.find(id);
221
if (j == (*i).second.end()) {
222
myDict[lsaid][id] = o;
223
return true;
224
}
225
return false;
226
/*
227
GroupDictType::iterator i=myDict.find(id);
228
if(i==myDict.end()) {
229
myDict[id] = o;
230
return true;
231
}
232
return false;
233
*/
234
}
235
236
237
NIVissimTL::NIVissimTLSignalGroup*
238
NIVissimTL::NIVissimTLSignalGroup::dictionary(int lsaid, int id) {
239
GroupDictType::iterator i = myDict.find(lsaid);
240
if (i == myDict.end()) {
241
return nullptr;
242
}
243
SGroupDictType::iterator j = (*i).second.find(id);
244
if (j == (*i).second.end()) {
245
return nullptr;
246
}
247
return (*j).second;
248
}
249
250
void
251
NIVissimTL::NIVissimTLSignalGroup::clearDict() {
252
for (GroupDictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
253
for (SGroupDictType::iterator j = (*i).second.begin(); j != (*i).second.end(); j++) {
254
delete (*j).second;
255
}
256
}
257
myDict.clear();
258
}
259
260
261
NIVissimTL::SGroupDictType
262
NIVissimTL::NIVissimTLSignalGroup::getGroupsFor(int tlid) {
263
GroupDictType::iterator i = myDict.find(tlid);
264
if (i == myDict.end()) {
265
return SGroupDictType();
266
}
267
return (*i).second;
268
}
269
270
271
bool
272
NIVissimTL::NIVissimTLSignalGroup::addTo(NBLoadedTLDef* tl) const {
273
// get the color at the begin
274
NBTrafficLightDefinition::TLColor color = myFirstIsRed
275
? NBTrafficLightDefinition::TLCOLOR_RED : NBTrafficLightDefinition::TLCOLOR_GREEN;
276
std::string id = toString<int>(myID);
277
tl->addSignalGroup(id);
278
for (SUMOTime t : myTimes) {
279
tl->addSignalGroupPhaseBegin(id, t, color);
280
color = color == NBTrafficLightDefinition::TLCOLOR_RED
281
? NBTrafficLightDefinition::TLCOLOR_GREEN : NBTrafficLightDefinition::TLCOLOR_RED;
282
}
283
if (myTimes.size() == 0) {
284
if (myFirstIsRed) {
285
tl->addSignalGroupPhaseBegin(id, 0, NBTrafficLightDefinition::TLCOLOR_RED);
286
} else {
287
tl->addSignalGroupPhaseBegin(id, 0, NBTrafficLightDefinition::TLCOLOR_GREEN);
288
}
289
}
290
tl->setSignalYellowTimes(id, myTRedYellow, myTYellow);
291
return true;
292
}
293
294
295
NIVissimTL::DictType NIVissimTL::myDict;
296
297
NIVissimTL::NIVissimTL(int id, const std::string& type,
298
const std::string& name, SUMOTime absdur,
299
SUMOTime offset)
300
: myID(id), myName(name), myAbsDuration(absdur), myOffset(offset),
301
myCurrentGroup(nullptr), myType(type)
302
303
{}
304
305
306
NIVissimTL::~NIVissimTL() {}
307
308
309
bool
310
NIVissimTL::dictionary(int id, const std::string& type,
311
const std::string& name, SUMOTime absdur,
312
SUMOTime offset) {
313
NIVissimTL* o = new NIVissimTL(id, type, name, absdur, offset);
314
if (!dictionary(id, o)) {
315
delete o;
316
return false;
317
}
318
return true;
319
}
320
321
bool
322
NIVissimTL::dictionary(int id, NIVissimTL* o) {
323
DictType::iterator i = myDict.find(id);
324
if (i == myDict.end()) {
325
myDict[id] = o;
326
return true;
327
}
328
return false;
329
}
330
331
332
NIVissimTL*
333
NIVissimTL::dictionary(int id) {
334
DictType::iterator i = myDict.find(id);
335
if (i == myDict.end()) {
336
return nullptr;
337
}
338
return (*i).second;
339
}
340
341
342
void
343
NIVissimTL::clearDict() {
344
for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
345
delete (*i).second;
346
}
347
myDict.clear();
348
}
349
350
351
352
353
354
bool
355
NIVissimTL::dict_SetSignals(NBTrafficLightLogicCont& tlc,
356
NBEdgeCont& ec) {
357
int ref = 0;
358
int ref_groups = 0;
359
int ref_signals = 0;
360
int no_signals = 0;
361
int no_groups = 0;
362
for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
363
NIVissimTL* tl = (*i).second;
364
/* if(tl->myType!="festzeit") {
365
cout << " Warning: The traffic light '" << tl->myID
366
<< "' could not be assigned to a node." << endl;
367
ref++;
368
continue;
369
}*/
370
std::string id = toString<int>(tl->myID);
371
TrafficLightType type = ((tl->getType() == "festzeit" || tl->getType() == "festzeit_fake") ?
372
TrafficLightType::STATIC : TrafficLightType::ACTUATED);
373
NBLoadedTLDef* def = new NBLoadedTLDef(ec, id, 0, type);
374
if (!tlc.insert(def)) {
375
WRITE_ERRORF(TL("Error on adding a traffic light\n Must be a multiple id ('%')"), id);
376
continue;
377
}
378
def->setCycleDuration(tl->myAbsDuration);
379
// add each group to the node's container
380
SGroupDictType sgs = NIVissimTLSignalGroup::getGroupsFor(tl->getID());
381
for (SGroupDictType::const_iterator j = sgs.begin(); j != sgs.end(); j++) {
382
if (!(*j).second->addTo(def)) {
383
WRITE_WARNINGF(TL("The signal group '%' could not be assigned to tl '%'."), toString<int>((*j).first), toString<int>(tl->myID));
384
ref_groups++;
385
}
386
no_groups++;
387
}
388
// add the signal group signals to the node
389
SSignalDictType signals = NIVissimTLSignal::getSignalsFor(tl->getID());
390
for (SSignalDictType::const_iterator k = signals.begin(); k != signals.end(); k++) {
391
if (!(*k).second->addTo(ec, def)) {
392
WRITE_WARNINGF(TL("The signal '%' could not be assigned to tl '%'."), toString<int>((*k).first), toString<int>(tl->myID));
393
ref_signals++;
394
}
395
no_signals++;
396
}
397
}
398
if (ref != 0) {
399
WRITE_WARNINGF(TL("Could not set % of % traffic lights."), toString<int>(ref), toString<int>((int)myDict.size()));
400
}
401
if (ref_groups != 0) {
402
WRITE_WARNINGF(TL("Could not set % of % groups."), toString<int>(ref_groups), toString<int>(no_groups));
403
}
404
if (ref_signals != 0) {
405
WRITE_WARNINGF(TL("Could not set % of % signals."), toString<int>(ref_signals), toString<int>(no_signals));
406
}
407
return true;
408
409
}
410
411
412
std::string
413
NIVissimTL::getType() const {
414
return myType;
415
}
416
417
418
int
419
NIVissimTL::getID() const {
420
return myID;
421
}
422
423
424
/****************************************************************************/
425
426