Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2024 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 155 : 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 155 : const std::vector<int>& vehicleTypes)
59 155 : : myID(id), myName(name), myGroupIDs(groupids),
60 155 : myEdgeID(edgeid), myLane(laneno), myPosition(position),
61 155 : myVehicleTypes(vehicleTypes) {}
62 :
63 :
64 155 : NIVissimTL::NIVissimTLSignal::~NIVissimTLSignal() {}
65 :
66 : bool
67 0 : NIVissimTL::NIVissimTLSignal::isWithin(const PositionVector& poly) const {
68 0 : return poly.around(getPosition());
69 : }
70 :
71 :
72 : Position
73 0 : NIVissimTL::NIVissimTLSignal::getPosition() const {
74 0 : return NIVissimAbstractEdge::dictionary(myEdgeID)->getGeomPosition(myPosition);
75 : }
76 :
77 :
78 : bool
79 155 : NIVissimTL::NIVissimTLSignal::dictionary(int lsaid, int id,
80 : NIVissimTL::NIVissimTLSignal* o) {
81 : SignalDictType::iterator i = myDict.find(lsaid);
82 155 : if (i == myDict.end()) {
83 24 : myDict[lsaid] = SSignalDictType();
84 : i = myDict.find(lsaid);
85 : }
86 : SSignalDictType::iterator j = (*i).second.find(id);
87 155 : if (j == (*i).second.end()) {
88 155 : myDict[lsaid][id] = o;
89 155 : return true;
90 : }
91 : return false;
92 : }
93 :
94 :
95 : NIVissimTL::NIVissimTLSignal*
96 0 : NIVissimTL::NIVissimTLSignal::dictionary(int lsaid, int id) {
97 : SignalDictType::iterator i = myDict.find(lsaid);
98 0 : if (i == myDict.end()) {
99 : return nullptr;
100 : }
101 : SSignalDictType::iterator j = (*i).second.find(id);
102 0 : if (j == (*i).second.end()) {
103 : return nullptr;
104 : }
105 0 : return (*j).second;
106 : }
107 :
108 :
109 : void
110 9 : NIVissimTL::NIVissimTLSignal::clearDict() {
111 21 : for (SignalDictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
112 167 : for (SSignalDictType::iterator j = (*i).second.begin(); j != (*i).second.end(); j++) {
113 155 : delete (*j).second;
114 : }
115 : }
116 : myDict.clear();
117 9 : }
118 :
119 :
120 : NIVissimTL::SSignalDictType
121 33 : NIVissimTL::NIVissimTLSignal::getSignalsFor(int tlid) {
122 : SignalDictType::iterator i = myDict.find(tlid);
123 33 : if (i == myDict.end()) {
124 21 : return SSignalDictType();
125 : }
126 : return (*i).second;
127 : }
128 :
129 :
130 : bool
131 155 : NIVissimTL::NIVissimTLSignal::addTo(NBEdgeCont& ec, NBLoadedTLDef* tl) const {
132 155 : NIVissimConnection* c = NIVissimConnection::dictionary(myEdgeID);
133 : NBConnectionVector assignedConnections;
134 155 : if (c == nullptr) {
135 : // What to do if on an edge? -> close all outgoing connections
136 105 : NBEdge* edge = ec.retrievePossiblySplit(toString<int>(myEdgeID), myPosition);
137 105 : if (edge == nullptr) {
138 12 : WRITE_WARNINGF(TL("Could not set tls signal at edge '%' - the edge was not built."), myEdgeID);
139 12 : 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 93 : if (edge->lanesWereAssigned()) {
145 48 : std::vector<NBEdge::Connection> connections = edge->getConnectionsFromLane(myLane - 1);
146 105 : 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 114 : assignedConnections.push_back(NBConnection(edge, myLane - 1, conn.toEdge, conn.toLane));
150 : }
151 48 : } else {
152 45 : WRITE_WARNINGF(TL("Edge '%': Lanes were not assigned."), myEdgeID);
153 114 : for (int j = 0; j < edge->getNumLanes(); j++) {
154 69 : std::vector<NBEdge::Connection> connections = edge->getConnectionsFromLane(j);
155 123 : for (std::vector<NBEdge::Connection>::iterator i = connections.begin(); i != connections.end(); i++) {
156 : const NBEdge::Connection& conn = *i;
157 108 : assignedConnections.push_back(NBConnection(edge, j, conn.toEdge, conn.toLane));
158 : }
159 69 : }
160 : }
161 : } else {
162 : // get the edges
163 100 : NBEdge* tmpFrom = ec.retrievePossiblySplit(toString<int>(c->getFromEdgeID()), toString<int>(c->getToEdgeID()), true);
164 100 : NBEdge* tmpTo = ec.retrievePossiblySplit(toString<int>(c->getToEdgeID()), toString<int>(c->getFromEdgeID()), false);
165 : // check whether the edges are known
166 50 : if (tmpFrom != nullptr && tmpTo != nullptr) {
167 : // add connections this signal is responsible for
168 100 : 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 286 : return tl->addToSignalGroup(toString<int>(myGroupIDs.front()), assignedConnections);
188 155 : }
189 :
190 :
191 :
192 :
193 :
194 :
195 :
196 :
197 : NIVissimTL::GroupDictType NIVissimTL::NIVissimTLSignalGroup::myDict;
198 :
199 77 : NIVissimTL::NIVissimTLSignalGroup::NIVissimTLSignalGroup(
200 : int id,
201 : const std::string& name,
202 : bool isGreenBegin, const std::vector<SUMOTime>& times,
203 77 : SUMOTime tredyellow, SUMOTime tyellow)
204 77 : : myID(id), myName(name), myTimes(times),
205 77 : myFirstIsRed(!isGreenBegin), myTRedYellow(tredyellow),
206 77 : myTYellow(tyellow) {}
207 :
208 :
209 77 : NIVissimTL::NIVissimTLSignalGroup::~NIVissimTLSignalGroup() {}
210 :
211 :
212 : bool
213 77 : NIVissimTL::NIVissimTLSignalGroup::dictionary(int lsaid, int id,
214 : NIVissimTL::NIVissimTLSignalGroup* o) {
215 : GroupDictType::iterator i = myDict.find(lsaid);
216 77 : if (i == myDict.end()) {
217 24 : myDict[lsaid] = SGroupDictType();
218 : i = myDict.find(lsaid);
219 : }
220 : SGroupDictType::iterator j = (*i).second.find(id);
221 77 : if (j == (*i).second.end()) {
222 77 : myDict[lsaid][id] = o;
223 77 : 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 0 : NIVissimTL::NIVissimTLSignalGroup::dictionary(int lsaid, int id) {
239 : GroupDictType::iterator i = myDict.find(lsaid);
240 0 : if (i == myDict.end()) {
241 : return nullptr;
242 : }
243 : SGroupDictType::iterator j = (*i).second.find(id);
244 0 : if (j == (*i).second.end()) {
245 : return nullptr;
246 : }
247 0 : return (*j).second;
248 : }
249 :
250 : void
251 9 : NIVissimTL::NIVissimTLSignalGroup::clearDict() {
252 21 : for (GroupDictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
253 89 : for (SGroupDictType::iterator j = (*i).second.begin(); j != (*i).second.end(); j++) {
254 77 : delete (*j).second;
255 : }
256 : }
257 : myDict.clear();
258 9 : }
259 :
260 :
261 : NIVissimTL::SGroupDictType
262 33 : NIVissimTL::NIVissimTLSignalGroup::getGroupsFor(int tlid) {
263 : GroupDictType::iterator i = myDict.find(tlid);
264 33 : if (i == myDict.end()) {
265 21 : return SGroupDictType();
266 : }
267 : return (*i).second;
268 : }
269 :
270 :
271 : bool
272 77 : NIVissimTL::NIVissimTLSignalGroup::addTo(NBLoadedTLDef* tl) const {
273 : // get the color at the begin
274 77 : NBTrafficLightDefinition::TLColor color = myFirstIsRed
275 77 : ? NBTrafficLightDefinition::TLCOLOR_RED : NBTrafficLightDefinition::TLCOLOR_GREEN;
276 77 : std::string id = toString<int>(myID);
277 77 : tl->addSignalGroup(id);
278 231 : for (SUMOTime t : myTimes) {
279 154 : tl->addSignalGroupPhaseBegin(id, t, color);
280 : color = color == NBTrafficLightDefinition::TLCOLOR_RED
281 154 : ? NBTrafficLightDefinition::TLCOLOR_GREEN : NBTrafficLightDefinition::TLCOLOR_RED;
282 : }
283 77 : if (myTimes.size() == 0) {
284 3 : if (myFirstIsRed) {
285 3 : tl->addSignalGroupPhaseBegin(id, 0, NBTrafficLightDefinition::TLCOLOR_RED);
286 : } else {
287 0 : tl->addSignalGroupPhaseBegin(id, 0, NBTrafficLightDefinition::TLCOLOR_GREEN);
288 : }
289 : }
290 77 : tl->setSignalYellowTimes(id, myTRedYellow, myTYellow);
291 77 : return true;
292 : }
293 :
294 :
295 : NIVissimTL::DictType NIVissimTL::myDict;
296 :
297 33 : NIVissimTL::NIVissimTL(int id, const std::string& type,
298 : const std::string& name, SUMOTime absdur,
299 33 : SUMOTime offset)
300 33 : : myID(id), myName(name), myAbsDuration(absdur), myOffset(offset),
301 33 : myCurrentGroup(nullptr), myType(type)
302 :
303 33 : {}
304 :
305 :
306 33 : NIVissimTL::~NIVissimTL() {}
307 :
308 :
309 : bool
310 33 : NIVissimTL::dictionary(int id, const std::string& type,
311 : const std::string& name, SUMOTime absdur,
312 : SUMOTime offset) {
313 33 : NIVissimTL* o = new NIVissimTL(id, type, name, absdur, offset);
314 33 : if (!dictionary(id, o)) {
315 0 : delete o;
316 0 : return false;
317 : }
318 : return true;
319 : }
320 :
321 : bool
322 33 : NIVissimTL::dictionary(int id, NIVissimTL* o) {
323 : DictType::iterator i = myDict.find(id);
324 33 : if (i == myDict.end()) {
325 33 : myDict[id] = o;
326 33 : return true;
327 : }
328 : return false;
329 : }
330 :
331 :
332 : NIVissimTL*
333 553 : NIVissimTL::dictionary(int id) {
334 : DictType::iterator i = myDict.find(id);
335 553 : if (i == myDict.end()) {
336 : return nullptr;
337 : }
338 541 : return (*i).second;
339 : }
340 :
341 :
342 : void
343 9 : NIVissimTL::clearDict() {
344 42 : for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
345 33 : delete (*i).second;
346 : }
347 : myDict.clear();
348 9 : }
349 :
350 :
351 :
352 :
353 :
354 : bool
355 9 : NIVissimTL::dict_SetSignals(NBTrafficLightLogicCont& tlc,
356 : NBEdgeCont& ec) {
357 9 : int ref = 0;
358 9 : int ref_groups = 0;
359 9 : int ref_signals = 0;
360 9 : int no_signals = 0;
361 9 : int no_groups = 0;
362 42 : for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
363 33 : 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 33 : std::string id = toString<int>(tl->myID);
371 57 : TrafficLightType type = ((tl->getType() == "festzeit" || tl->getType() == "festzeit_fake") ?
372 : TrafficLightType::STATIC : TrafficLightType::ACTUATED);
373 33 : NBLoadedTLDef* def = new NBLoadedTLDef(ec, id, 0, type);
374 33 : if (!tlc.insert(def)) {
375 0 : WRITE_ERRORF(TL("Error on adding a traffic light\n Must be a multiple id ('%')"), id);
376 : continue;
377 : }
378 33 : def->setCycleDuration(tl->myAbsDuration);
379 : // add each group to the node's container
380 33 : SGroupDictType sgs = NIVissimTLSignalGroup::getGroupsFor(tl->getID());
381 110 : for (SGroupDictType::const_iterator j = sgs.begin(); j != sgs.end(); j++) {
382 77 : if (!(*j).second->addTo(def)) {
383 0 : WRITE_WARNINGF(TL("The signal group '%' could not be assigned to tl '%'."), toString<int>((*j).first), toString<int>(tl->myID));
384 0 : ref_groups++;
385 : }
386 77 : no_groups++;
387 : }
388 : // add the signal group signals to the node
389 33 : SSignalDictType signals = NIVissimTLSignal::getSignalsFor(tl->getID());
390 188 : for (SSignalDictType::const_iterator k = signals.begin(); k != signals.end(); k++) {
391 155 : if (!(*k).second->addTo(ec, def)) {
392 24 : WRITE_WARNINGF(TL("The signal '%' could not be assigned to tl '%'."), toString<int>((*k).first), toString<int>(tl->myID));
393 12 : ref_signals++;
394 : }
395 155 : 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 9 : if (ref_groups != 0) {
402 0 : WRITE_WARNINGF(TL("Could not set % of % groups."), toString<int>(ref_groups), toString<int>(no_groups));
403 : }
404 9 : if (ref_signals != 0) {
405 6 : WRITE_WARNINGF(TL("Could not set % of % signals."), toString<int>(ref_signals), toString<int>(no_signals));
406 : }
407 9 : return true;
408 :
409 : }
410 :
411 :
412 : std::string
413 455 : NIVissimTL::getType() const {
414 455 : return myType;
415 : }
416 :
417 :
418 : int
419 66 : NIVissimTL::getID() const {
420 66 : return myID;
421 : }
422 :
423 :
424 : /****************************************************************************/
|