Eclipse SUMO - Simulation of Urban MObility
NLJunctionControlBuilder.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3// Copyright (C) 2001-2022 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/****************************************************************************/
21// Builder of microsim-junctions and tls
22/****************************************************************************/
23#include <config.h>
24
25#include <map>
26#include <string>
27#include <vector>
28#include <list>
29#include <algorithm>
33#include <microsim/MSGlobals.h>
34#include <microsim/MSNet.h>
56#include "NLBuilder.h"
59
60
61// ===========================================================================
62// static members
63// ===========================================================================
65
66// ===========================================================================
67// method definitions
68// ===========================================================================
70 myNet(net),
71 myDetectorBuilder(db),
72 myOffset(0),
73 myJunctions(nullptr),
74 myNetIsLoaded(false) {
77}
78
79
81 delete myLogicControl;
82 delete myJunctions;
83}
84
85
86void
88 const std::string& key,
89 const SumoXMLNodeType type,
90 const Position pos,
91 const PositionVector& shape,
92 const std::vector<MSLane*>& incomingLanes,
93 const std::vector<MSLane*>& internalLanes,
94 const std::string& name) {
95 myActiveInternalLanes = internalLanes;
96 myActiveIncomingLanes = incomingLanes;
97 myActiveID = id;
98 myActiveKey = key;
99 myType = type;
100 myPosition.set(pos);
101 myShape = shape;
102 myActiveName = name;
103 myAdditionalParameter.clear();
104}
105
106
107void
108NLJunctionControlBuilder::closeJunction(const std::string& basePath) {
109 if (myJunctions == nullptr) {
110 throw ProcessError("Information about the number of nodes was missing.");
111 }
112 MSJunction* junction = nullptr;
113 switch (myType) {
119 junction = buildNoLogicJunction();
120 break;
129 junction = buildLogicJunction();
130 break;
133 junction = buildInternalJunction();
134 }
135 break;
138 myOffset = 0;
140 myActiveProgram = "0";
142 closeTrafficLightLogic(basePath);
143 junction = buildLogicJunction();
144 break;
145 default:
146 throw InvalidArgument("False junction logic type.");
147 }
148 if (junction != nullptr) {
149 if (!myJunctions->add(myActiveID, junction)) {
150 throw InvalidArgument("Another junction with the id '" + myActiveID + "' exists.");
151 }
153 }
154}
155
156
160 myJunctions = nullptr;
161 return js;
162}
163
164
169}
170
171
175 // build the junction
179 jtype);
180}
181
182
185 // build the junction
188}
189
190
193 // get and check the junction logic
194 if (myLogics.find(myActiveID) == myLogics.end()) {
195 throw InvalidArgument("Missing junction logic '" + myActiveID + "'.");
196 }
197 return myLogics[myActiveID];
198}
199
200
202NLJunctionControlBuilder::getTLLogic(const std::string& id) const {
203 return getTLLogicControlToUse().get(id);
204}
205
206
207void
209 if (myActiveProgram == "off") {
210 if (myAbsDuration > 0) {
211 throw InvalidArgument("The off program for TLS '" + myActiveKey + "' has phases.");
212 }
215 throw InvalidArgument("Another logic with id '" + myActiveKey + "' and programID '" + myActiveProgram + "' exists.");
216 }
217 return;
218 }
219 SUMOTime firstEventOffset = 0;
220 int step = 0;
221 MSSimpleTrafficLightLogic::Phases::const_iterator i = myActivePhases.begin();
223 if (existing != nullptr && (existing->getLogicType() == TrafficLightType::RAIL_SIGNAL || existing->getLogicType() == TrafficLightType::RAIL_CROSSING)) {
225 return;
226 } else {
228 if (myAbsDuration == 0) {
229 if (existing == nullptr) {
230 throw InvalidArgument("TLS program '" + myActiveProgram + "' for TLS '" + myActiveKey + "' has a duration of 0.");
231 } else {
232 // only modify the offset of an existing logic
234 i = existing->getPhases().begin();
235 }
236 } else if (existing != nullptr) {
237 throw InvalidArgument("Another logic with id '" + myActiveKey + "' and programID '" + myActiveProgram + "' exists.");
238 }
239 // compute the initial step and first switch time of the tls-logic
240 // a positive offset delays all phases by x (advance by absDuration - x) while a negative offset advances all phases by x seconds
241 // @note The implementation of % for negative values is implementation defined in ISO1998
242 SUMOTime offset; // the time to run the traffic light in advance
243 if (myOffset >= 0) {
245 } else {
247 }
248 while (offset >= (*i)->duration) {
249 step++;
250 offset -= (*i)->duration;
251 ++i;
252 }
253 firstEventOffset = (*i)->duration - offset + myNet.getCurrentTimeStep();
254 if (existing != nullptr) {
256 myNet.getCurrentTimeStep(), step, (*i)->duration - offset);
257 // parameters that are used when initializing a logic will not take
258 // effect but parameters that are checked at runtime can be used
259 // here (i.e. device.glosa.range)
261 return;
262 }
263 }
264 }
265
266 if (myActiveProgram == "") {
267 myActiveProgram = "default";
268 }
269 MSTrafficLightLogic* tlLogic = nullptr;
270 // build the tls-logic in dependance to its type
271 switch (myLogicType) {
273 firstEventOffset = DELTA_T; //this is needed because swarm needs to update the pheromone on the lanes at every step
275 break;
278 break;
281 break;
284 break;
287 break;
290 break;
293 break;
295 // @note it is unclear how to apply the given offset in the context
296 // of variable-length phases
299 myActivePhases, step, (*i)->minDuration + myNet.getCurrentTimeStep(),
301 break;
303 tlLogic = new NEMALogic(getTLLogicControlToUse(),
305 myActivePhases, step, (*i)->minDuration + myNet.getCurrentTimeStep(),
306 myAdditionalParameter, basePath);
307 break;
311 myActivePhases, step, (*i)->minDuration + myNet.getCurrentTimeStep(),
312 myAdditionalParameter, basePath);
313 break;
318 myActivePhases, step, firstEventOffset,
320 break;
322 tlLogic = new MSRailSignal(getTLLogicControlToUse(),
325 break;
330 break;
333 break;
335 throw ProcessError("Invalid traffic light type '" + toString(myLogicType) + "'");
336 }
337 myActivePhases.clear();
338 if (tlLogic != nullptr) {
340 if (myNetIsLoaded) {
341 tlLogic->init(myDetectorBuilder);
342 } else {
343 myLogics2PostLoadInit.push_back(tlLogic);
344 }
345 } else {
346 WRITE_ERROR("Another logic with id '" + myActiveKey + "' and programID '" + myActiveProgram + "' exists.");
347 delete tlLogic;
348 }
349 }
350}
351
352
353void
355 myActiveKey = id;
356 myActiveProgram = "";
357 myActiveLogic.clear();
358 myActiveFoes.clear();
359 myActiveConts.reset();
360 myRequestSize = NO_REQUEST_SIZE; // seems not to be used
362 myCurrentHasError = false;
363}
364
365
366void
368 const std::string& response,
369 const std::string& foes,
370 bool cont) {
371 if (myCurrentHasError) {
372 // had an error
373 return;
374 }
375 if (request >= SUMO_MAX_CONNECTIONS) {
376 // bad request
377 myCurrentHasError = true;
378 throw InvalidArgument("Junction logic '" + myActiveKey + "' is larger than allowed; recheck the network.");
379 }
381 // initialize
382 myRequestSize = (int)response.size();
383 }
384 if (static_cast<int>(response.size()) != myRequestSize) {
385 myCurrentHasError = true;
386 throw InvalidArgument("Invalid response size " + toString(response.size()) +
387 " in Junction logic '" + myActiveKey + "' (expected " + toString(myRequestSize) + ")");
388 }
389 if (static_cast<int>(foes.size()) != myRequestSize) {
390 myCurrentHasError = true;
391 throw InvalidArgument("Invalid foes size " + toString(foes.size()) +
392 " in Junction logic '" + myActiveKey + "' (expected " + toString(myRequestSize) + ")");
393 }
394 // assert that the logicitems come ordered by their request index
395 assert((int)myActiveLogic.size() == request);
396 assert((int)myActiveFoes.size() == request);
397 // add the read response for the given request index
398 myActiveLogic.push_back(std::bitset<SUMO_MAX_CONNECTIONS>(response));
399 // add the read junction-internal foes for the given request index
400 myActiveFoes.push_back(std::bitset<SUMO_MAX_CONNECTIONS>(foes));
401 // add whether the vehicle may drive a little bit further
402 myActiveConts.set(request, cont);
403 // increse number of set information
405}
406
407
408void
409NLJunctionControlBuilder::initTrafficLightLogic(const std::string& id, const std::string& programID,
410 TrafficLightType type, SUMOTime offset) {
411 myActiveKey = id;
412 myActiveProgram = programID;
413 myActivePhases.clear();
414 myActiveConditions.clear();
415 myActiveAssignments.clear();
416 myActiveFunctions.clear();
417 myAbsDuration = 0;
419 myLogicType = type;
420 myOffset = offset;
421 myAdditionalParameter.clear();
422}
423
424
425void
427 // build and add the phase definition to the list
428 myActivePhases.push_back(phase);
429 // add phase duration to the absolute duration
430 myAbsDuration += phase->duration;
431}
432
433
434bool
435NLJunctionControlBuilder::addCondition(const std::string& id, const std::string& value) {
436 if (myActiveConditions.count(id) == 0) {
437 myActiveConditions[id] = value;
438 return true;
439 } else {
440 return false;
441 }
442}
443
444
445void
446NLJunctionControlBuilder::addAssignment(const std::string& id, const std::string& check, const std::string& value) {
447 if (myActiveFunction.id == "") {
448 myActiveAssignments.push_back(std::make_tuple(id, check, value));
449 } else {
450 myActiveFunction.assignments.push_back(std::make_tuple(id, check, value));
451 }
452}
453
454
455void
456NLJunctionControlBuilder::addFunction(const std::string& id, int nArgs) {
457 myActiveFunction.id = id;
458 myActiveFunction.nArgs = nArgs;
459}
460
461void
464 myActiveFunction.id = "";
466}
467
468void
471 // We have a legacy network. junction element did not contain logicitems; read the logic later
472 return;
473 }
474 if (myCurrentHasError) {
475 // had an error before...
476 return;
477 }
479 throw InvalidArgument("The description for the junction logic '" + myActiveKey + "' is malicious.");
480 }
481 if (myLogics.count(myActiveKey) > 0) {
482 throw InvalidArgument("Junction logic '" + myActiveKey + "' was defined twice.");
483 }
488 myLogics[myActiveKey] = logic;
489}
490
491
494 postLoadInitialization(); // must happen after edgeBuilder is finished
496 throw ProcessError("Traffic lights could not be built.");
497 }
499 myLogicControl = nullptr;
500 return ret;
501}
502
503
504void
506 const std::string& value) {
507 myAdditionalParameter[key] = value;
508}
509
510
513 if (myLogicControl != nullptr) {
514 return *myLogicControl;
515 }
516 return myNet.getTLSControl();
517}
518
519
520const std::string&
522 return myActiveKey;
523}
524
525
526const std::string&
528 return myActiveProgram;
529}
530
531
532void
534 for (MSTrafficLightLogic* const logic : myLogics2PostLoadInit) {
535 logic->init(myDetectorBuilder);
536 }
537 myNetIsLoaded = true;
538}
539
540
543 if (myJunctions != nullptr) {
544 return myJunctions->get(id);
545 } else {
546 return nullptr;
547 }
548}
549
550
551/****************************************************************************/
long long int SUMOTime
Definition: GUI.h:36
MSBitSetLogic< SUMO_MAX_CONNECTIONS > MSBitsetLogic
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:274
SUMOTime DELTA_T
Definition: SUMOTime.cpp:37
TrafficLightType
SumoXMLNodeType
Numbers representing special SUMO-XML-attribute values for representing node- (junction-) types used ...
#define SUMO_MAX_CONNECTIONS
the maximum number of connections across an intersection
Definition: StdDefs.h:41
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
An actuated (adaptive) traffic light logic.
std::vector< std::bitset< N > > Foes
Container holding the information which internal lanes prohibt which links Build the same way as Logi...
Definition: MSBitSetLogic.h:53
std::vector< std::bitset< N > > Logic
Container that holds the right of way bitsets. Each link has it's own bitset. The bits in the bitsets...
Definition: MSBitSetLogic.h:49
An actuated traffic light logic based on time delay of approaching vehicles.
static bool gUsingInternalLanes
Information whether the simulation regards internal lanes.
Definition: MSGlobals.h:78
Container for junctions; performs operations on all stored junctions.
The base class for an intersection.
Definition: MSJunction.h:58
The simulated network and simulation perfomer.
Definition: MSNet.h:88
MSTLLogicControl & getTLSControl()
Returns the tls logics control.
Definition: MSNet.h:452
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:321
A traffic lights logic which represents a tls in an off-mode.
The definition of a single phase of a tls logic.
SUMOTime duration
The duration of the phase.
A signal for rails.
A signal for rails.
Definition: MSRailSignal.h:46
A junction with right-of-way - rules.
Class for low-level marching policy.
Class for low-level phase policy.
Class for low-level platoon policy.
A self-organizing traffic light logic based on a particular policy.
Class for low-level request policy.
A fixed traffic light logic.
Storage for all programs of a single tls.
A class that stores and controls tls and switching of their programs.
bool closeNetworkReading()
Lets MSTLLogicControl know that the network has been loaded.
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
The parent class for traffic light logics.
virtual void changeStepAndDuration(MSTLLogicControl &tlcontrol, SUMOTime simStep, int step, SUMOTime stepDuration)=0
Changes the current phase and her duration.
TrafficLightType getLogicType() const
Returns the type of the logic.
virtual const Phases & getPhases() const =0
Returns the phases of this tls program.
SUMOTime getDefaultCycleTime() const
Returns the cycle time (in ms)
virtual void init(NLDetectorBuilder &nb)
Initialises the tls with information about incoming lanes.
A NEMA (adaptive) traffic light logic based on E2Detector.
Builds detectors for microsim.
PositionVector myShape
The shape of the current junction.
NLJunctionControlBuilder(MSNet &net, NLDetectorBuilder &db)
Constructor.
void closeJunctionLogic()
Ends the building of a junction logic (row-logic)
int myRequestItemNumber
Counter for the inserted items.
SumoXMLNodeType myType
The type of the currently chosen junction.
MSTLLogicControl::TLSLogicVariants & getTLLogic(const std::string &id) const
Returns a previously build tls logic.
std::string myActiveName
the name of the current junction
virtual ~NLJunctionControlBuilder()
Destructor.
void closeFunction()
closes a switching condition function to the traffic lights logic currently build
MSJunction * retrieve(const std::string id)
try to retrieve junction by id
MSActuatedTrafficLightLogic::AssignmentMap myActiveAssignments
The current assignments for an actuated traffic light.
MSBitsetLogic::Foes myActiveFoes
The description about which lanes disallow other passing the junction simultaneously.
std::string myActiveID
The id of the currently chosen junction.
MSActuatedTrafficLightLogic::ConditionMap myActiveConditions
The current switching conditions for an actuated traffic light.
SUMOTime myOffset
The switch offset within the tls.
MSTLLogicControl * myLogicControl
The tls control to use (0 if net's tls control shall be used)
std::string myActiveKey
The key of the currently chosen junction.
TrafficLightType myLogicType
The current logic type.
bool myCurrentHasError
Information whether the current logic had an error.
MSTLLogicControl * buildTLLogics()
Returns the built tls-logic control.
MSJunctionControl * build() const
Builds the MSJunctionControl which holds all of the simulations junctions.
int myRequestSize
The size of the request.
void addPhase(MSPhaseDefinition *phase)
Adds a phase to the currently built traffic lights logic.
MSTLLogicControl & getTLLogicControlToUse() const
Returns the used tls control.
void addFunction(const std::string &id, int nArgs)
adds a switching condition function to the traffic lights logic currently build
LaneVector myActiveIncomingLanes
The list of the incoming lanes of the currently chosen junction.
std::map< std::string, MSJunctionLogic * > myLogics
Map of loaded junction logics.
const std::string & getActiveSubKey() const
Returns the active sub key.
bool addCondition(const std::string &id, const std::string &value)
Adds a condition to the currently built traffic lights logic.
StringParameterMap myAdditionalParameter
Parameter map (key->value)
void openJunction(const std::string &id, const std::string &key, const SumoXMLNodeType type, const Position pos, const PositionVector &shape, const std::vector< MSLane * > &incomingLanes, const std::vector< MSLane * > &internalLanes, const std::string &name)
Begins the processing of the named junction.
void addParam(const std::string &key, const std::string &value)
Adds a parameter.
LaneVector myActiveInternalLanes
The list of the internal lanes of the currently chosen junction.
void initJunctionLogic(const std::string &id)
Initialises a junction logic.
void initTrafficLightLogic(const std::string &id, const std::string &programID, TrafficLightType type, SUMOTime offset)
Begins the reading of a traffic lights logic.
virtual MSJunction * buildLogicJunction()
Builds a junction with a logic.
MSActuatedTrafficLightLogic::FunctionMap myActiveFunctions
The current functions for an actuated traffic light.
NLDetectorBuilder & myDetectorBuilder
The detector builder to use.
virtual MSJunction * buildNoLogicJunction()
Builds a junction that does not use a logic.
virtual MSJunction * buildInternalJunction()
Builds an internal junction.
MSJunctionControl * myJunctions
The junctions controls.
const std::string & getActiveKey() const
Returns the active key.
Position myPosition
The position of the junction.
void addAssignment(const std::string &id, const std::string &check, const std::string &value)
Adds an assignment to the currently built traffic lights logic.
MSJunctionLogic * getJunctionLogicSecure()
Returns the current junction logic.
void postLoadInitialization()
initialize junctions after all connections have been loaded
void addLogicItem(int request, const std::string &response, const std::string &foes, bool cont)
Adds a logic item.
MSActuatedTrafficLightLogic::Function myActiveFunction
The current function for an actuated traffic light.
std::vector< MSTrafficLightLogic * > myLogics2PostLoadInit
The container for information which junctions shall be initialised using which values.
MSBitsetLogic::Logic myActiveLogic
The right-of-way-logic of the currently chosen bitset-logic.
SUMOTime myAbsDuration
The absolute duration of a tls-control loop.
void closeJunction(const std::string &basePath)
Closes (ends) the processing of the current junction.
MSSimpleTrafficLightLogic::Phases myActivePhases
The current phase definitions for a simple traffic light.
bool myNetIsLoaded
whether the network has been loaded
virtual void closeTrafficLightLogic(const std::string &basePath)
Ends the building of a traffic lights logic.
std::bitset< SUMO_MAX_CONNECTIONS > myActiveConts
The description about which lanes have an internal follower.
T get(const std::string &id) const
Retrieves an item.
bool add(const std::string &id, T item)
Adds an item.
void updateParameters(const Parameterised::Map &mapArg)
Adds or updates all given parameters from the map.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
void set(double x, double y)
set positions x and y
Definition: Position.h:85
A list of positions.