LCOV - code coverage report
Current view: top level - src/netload - NLJunctionControlBuilder.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 90.0 % 250 225
Test Date: 2025-05-18 15:30:03 Functions: 96.2 % 26 25

            Line data    Source code
       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    NLJunctionControlBuilder.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Sascha Krieg
      18              : /// @author  Michael Behrisch
      19              : /// @date    Mon, 9 Jul 2001
      20              : ///
      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>
      30              : #include <utils/xml/SUMOXMLDefinitions.h>
      31              : #include <utils/common/UtilExceptions.h>
      32              : #include <utils/common/ToString.h>
      33              : #include <microsim/MSGlobals.h>
      34              : #include <microsim/MSNet.h>
      35              : #include <microsim/MSJunctionLogic.h>
      36              : #include <microsim/MSNoLogicJunction.h>
      37              : #include <microsim/MSRightOfWayJunction.h>
      38              : #include <microsim/MSInternalJunction.h>
      39              : #include <microsim/MSJunctionControl.h>
      40              : #include <microsim/MSEventControl.h>
      41              : #include <microsim/traffic_lights/MSTrafficLightLogic.h>
      42              : #include <microsim/traffic_lights/MSSimpleTrafficLightLogic.h>
      43              : #include <microsim/traffic_lights/MSRailSignal.h>
      44              : #include <microsim/traffic_lights/MSRailCrossing.h>
      45              : #include <microsim/traffic_lights/MSSOTLPolicyBasedTrafficLightLogic.h>
      46              : #include <microsim/traffic_lights/MSSOTLPlatoonPolicy.h>
      47              : #include <microsim/traffic_lights/MSSOTLRequestPolicy.h>
      48              : #include <microsim/traffic_lights/MSSOTLPhasePolicy.h>
      49              : #include <microsim/traffic_lights/MSSOTLMarchingPolicy.h>
      50              : #include <microsim/traffic_lights/MSSwarmTrafficLightLogic.h>
      51              : #include <microsim/traffic_lights/MSDeterministicHiLevelTrafficLightLogic.h>
      52              : #include <microsim/traffic_lights/MSSOTLWaveTrafficLightLogic.h>
      53              : #include <microsim/traffic_lights/MSDelayBasedTrafficLightLogic.h>
      54              : #include <microsim/traffic_lights/MSOffTrafficLightLogic.h>
      55              : #include <microsim/traffic_lights/MSTLLogicControl.h>
      56              : #include "NLBuilder.h"
      57              : #include "NLJunctionControlBuilder.h"
      58              : #include "microsim/traffic_lights/NEMAController.h"
      59              : 
      60              : 
      61              : // ===========================================================================
      62              : // static members
      63              : // ===========================================================================
      64              : const int NLJunctionControlBuilder::NO_REQUEST_SIZE = -1;
      65              : 
      66              : // ===========================================================================
      67              : // method definitions
      68              : // ===========================================================================
      69        44136 : NLJunctionControlBuilder::NLJunctionControlBuilder(MSNet& net, NLDetectorBuilder& db) :
      70        44136 :     myNet(net),
      71        44136 :     myDetectorBuilder(db),
      72        44136 :     myOffset(0),
      73        44136 :     myJunctions(new MSJunctionControl()),
      74       176544 :     myNetIsLoaded(false) {
      75        44136 :     myLogicControl = new MSTLLogicControl();
      76        44136 : }
      77              : 
      78              : 
      79        44136 : NLJunctionControlBuilder::~NLJunctionControlBuilder() {
      80        44136 :     delete myLogicControl;
      81        44136 :     delete myJunctions;
      82       132408 : }
      83              : 
      84              : 
      85              : void
      86       581579 : NLJunctionControlBuilder::openJunction(const std::string& id,
      87              :                                        const std::string& key,
      88              :                                        const SumoXMLNodeType type,
      89              :                                        const Position pos,
      90              :                                        const PositionVector& shape,
      91              :                                        const std::vector<MSLane*>& incomingLanes,
      92              :                                        const std::vector<MSLane*>& internalLanes,
      93              :                                        const std::string& name) {
      94       581579 :     myActiveInternalLanes = internalLanes;
      95       581579 :     myActiveIncomingLanes = incomingLanes;
      96       581579 :     myActiveID = id;
      97       581579 :     myActiveKey = key;
      98       581579 :     myType = type;
      99              :     myPosition.set(pos);
     100              :     myShape = shape;
     101       581579 :     myActiveName = name;
     102              :     myAdditionalParameter.clear();
     103       581579 : }
     104              : 
     105              : 
     106              : void
     107       581579 : NLJunctionControlBuilder::closeJunction(const std::string& basePath) {
     108       581579 :     if (myCurrentHasError) {
     109              :         // had an error before...
     110              :         return;
     111              :     }
     112       581579 :     if (myRequestSize != NO_REQUEST_SIZE && myRequestItemNumber != myRequestSize) {
     113            0 :         throw InvalidArgument("The description for the junction logic '" + myActiveKey + "' is malicious.");
     114              :     }
     115       581579 :     if (myJunctions == nullptr) {
     116            0 :         throw ProcessError(TL("Information about the number of nodes was missing."));
     117              :     }
     118              :     MSJunction* junction = nullptr;
     119       581579 :     switch (myType) {
     120        61680 :         case SumoXMLNodeType::NOJUNCTION:
     121              :         case SumoXMLNodeType::DEAD_END:
     122              :         case SumoXMLNodeType::DEAD_END_DEPRECATED:
     123              :         case SumoXMLNodeType::DISTRICT:
     124              :         case SumoXMLNodeType::TRAFFIC_LIGHT_NOJUNCTION:
     125        61680 :             if (!myActiveLogic.empty()) {
     126          120 :                 WRITE_WARNINGF(TL("Ignoring junction logic for junction '%'."), myActiveID)
     127              :             }
     128        61680 :             junction = buildNoLogicJunction();
     129        61680 :             break;
     130       321768 :         case SumoXMLNodeType::TRAFFIC_LIGHT:
     131              :         case SumoXMLNodeType::TRAFFIC_LIGHT_RIGHT_ON_RED:
     132              :         case SumoXMLNodeType::RIGHT_BEFORE_LEFT:
     133              :         case SumoXMLNodeType::LEFT_BEFORE_RIGHT:
     134              :         case SumoXMLNodeType::PRIORITY:
     135              :         case SumoXMLNodeType::PRIORITY_STOP:
     136              :         case SumoXMLNodeType::ALLWAY_STOP:
     137              :         case SumoXMLNodeType::ZIPPER:
     138       321768 :             junction = buildLogicJunction(new MSBitsetLogic(myRequestSize, myActiveLogic, myActiveFoes, myActiveConts));
     139              :             break;
     140       193715 :         case SumoXMLNodeType::INTERNAL:
     141       193715 :             if (MSGlobals::gUsingInternalLanes) {
     142       158901 :                 if (!myActiveLogic.empty()) {
     143           18 :                     WRITE_WARNINGF(TL("Ignoring junction logic for junction '%'."), myActiveID)
     144              :                 }
     145       158901 :                 junction = buildInternalJunction();
     146              :             }
     147              :             break;
     148         4416 :         case SumoXMLNodeType::RAIL_SIGNAL:
     149              :         case SumoXMLNodeType::RAIL_CROSSING:
     150         4416 :             myOffset = 0;
     151         4416 :             myActiveKey = myActiveID;
     152         4416 :             myActiveProgram = "0";
     153         4416 :             myLogicType = myType == SumoXMLNodeType::RAIL_SIGNAL ? TrafficLightType::RAIL_SIGNAL : TrafficLightType::RAIL_CROSSING;
     154         4416 :             closeTrafficLightLogic(basePath);
     155         4416 :             junction = buildLogicJunction(new MSBitsetLogic(myRequestSize, myActiveLogic, myActiveFoes, myActiveConts));
     156              :             break;
     157            0 :         default:
     158            0 :             throw InvalidArgument("False junction logic type.");
     159              :     }
     160       546765 :     if (junction != nullptr) {
     161       546765 :         if (!myJunctions->add(myActiveID, junction)) {
     162           12 :             throw InvalidArgument("Another junction with the id '" + myActiveID + "' exists.");
     163              :         }
     164       546759 :         junction->updateParameters(myAdditionalParameter);
     165              :     }
     166              : }
     167              : 
     168              : 
     169              : MSJunctionControl*
     170        43718 : NLJunctionControlBuilder::build() const {
     171        43718 :     MSJunctionControl* js = myJunctions;
     172        43718 :     myJunctions = nullptr;
     173        43718 :     return js;
     174              : }
     175              : 
     176              : 
     177              : MSJunction*
     178        61680 : NLJunctionControlBuilder::buildNoLogicJunction() {
     179        61680 :     return new MSNoLogicJunction(myActiveID, myType, myPosition, myShape, myActiveName,
     180        61680 :                                  myActiveIncomingLanes, myActiveInternalLanes);
     181              : }
     182              : 
     183              : 
     184              : MSJunction*
     185       326184 : NLJunctionControlBuilder::buildLogicJunction(MSJunctionLogic* const logic) {
     186       326184 :     return new MSRightOfWayJunction(myActiveID, myType, myPosition, myShape, myActiveName,
     187       326184 :                                     myActiveIncomingLanes, myActiveInternalLanes, logic);
     188              : }
     189              : 
     190              : 
     191              : MSJunction*
     192       158901 : NLJunctionControlBuilder::buildInternalJunction() {
     193              :     // build the junction
     194       317802 :     return new MSInternalJunction(myActiveID, myType, myPosition, myShape, myActiveIncomingLanes,
     195       158901 :                                   myActiveInternalLanes);
     196              : }
     197              : 
     198              : 
     199              : MSTLLogicControl::TLSLogicVariants&
     200      1621207 : NLJunctionControlBuilder::getTLLogic(const std::string& id) const {
     201      1621207 :     return getTLLogicControlToUse().get(id);
     202              : }
     203              : 
     204              : 
     205              : void
     206       115826 : NLJunctionControlBuilder::closeTrafficLightLogic(const std::string& basePath) {
     207       115826 :     if (myActiveProgram == "off") {
     208           37 :         if (myAbsDuration > 0) {
     209            0 :             throw InvalidArgument("The off program for TLS '" + myActiveKey + "' has phases.");
     210              :         }
     211           37 :         MSOffTrafficLightLogic* off = new MSOffTrafficLightLogic(getTLLogicControlToUse(), myActiveKey);
     212           37 :         if (!getTLLogicControlToUse().add(myActiveKey, myActiveProgram, off)) {
     213            0 :             throw InvalidArgument("Another logic with id '" + myActiveKey + "' and programID '" + myActiveProgram + "' exists.");
     214              :         }
     215          182 :         return;
     216              :     }
     217              :     SUMOTime firstEventOffset = 0;
     218              :     int step = 0;
     219              :     MSSimpleTrafficLightLogic::Phases::const_iterator i = myActivePhases.begin();
     220       115789 :     MSTrafficLightLogic* existing = getTLLogicControlToUse().get(myActiveKey, myActiveProgram);
     221       115789 :     if (existing != nullptr && (existing->getLogicType() == TrafficLightType::RAIL_SIGNAL || existing->getLogicType() == TrafficLightType::RAIL_CROSSING)) {
     222           35 :         existing->updateParameters(myAdditionalParameter);
     223           35 :         return;
     224              :     } else {
     225       115754 :         if (myLogicType != TrafficLightType::RAIL_SIGNAL && myLogicType != TrafficLightType::RAIL_CROSSING) {
     226       111338 :             if (myAbsDuration == 0) {
     227          111 :                 if (existing == nullptr) {
     228            2 :                     throw InvalidArgument("TLS program '" + myActiveProgram + "' for TLS '" + myActiveKey + "' has a duration of 0.");
     229              :                 } else {
     230              :                     // only modify the offset of an existing logic
     231          110 :                     myAbsDuration = existing->getDefaultCycleTime();
     232          110 :                     i = existing->getPhases().begin();
     233              :                 }
     234       111227 :             } else if (existing != nullptr) {
     235            2 :                 throw InvalidArgument("Another logic with id '" + myActiveKey + "' and programID '" + myActiveProgram + "' exists.");
     236              :             }
     237              :             // compute the initial step and first switch time of the tls-logic
     238              :             // a positive offset delays all phases by x (advance by absDuration - x) while a negative offset advances all phases by x seconds
     239              :             // @note The implementation of % for negative values is implementation defined in ISO1998
     240              :             SUMOTime offset; // the time to run the traffic light in advance
     241       111336 :             if (myOffset >= 0) {
     242       111277 :                 offset = (myNet.getCurrentTimeStep() + myAbsDuration - (myOffset % myAbsDuration)) % myAbsDuration;
     243              :             } else {
     244           59 :                 offset = (myNet.getCurrentTimeStep() + ((-myOffset) % myAbsDuration)) % myAbsDuration;
     245              :             }
     246       112682 :             while (offset >= (*i)->duration) {
     247         1346 :                 step++;
     248         1346 :                 offset -= (*i)->duration;
     249              :                 ++i;
     250              :             }
     251       111336 :             firstEventOffset = (*i)->duration - offset + myNet.getCurrentTimeStep();
     252       111336 :             if (existing != nullptr) {
     253          110 :                 existing->changeStepAndDuration(getTLLogicControlToUse(),
     254              :                                                 myNet.getCurrentTimeStep(), step, (*i)->duration - offset);
     255              :                 // parameters that are used when initializing a logic will not take
     256              :                 // effect but parameters that are checked at runtime can be used
     257              :                 // here (i.e. device.glosa.range)
     258          110 :                 myLogicParams[existing] = myAdditionalParameter;
     259              :                 if (myAdditionalParameter.count(MESegment::OVERRIDE_TLS_PENALTIES) != 0) {
     260              :                     // value must be available when calling setMesoTypes and before setting the rest in postLoadInitialization
     261            4 :                     existing->setParameter(MESegment::OVERRIDE_TLS_PENALTIES, myAdditionalParameter[MESegment::OVERRIDE_TLS_PENALTIES]);
     262              :                 }
     263          110 :                 return;
     264              :             }
     265              :         }
     266              :     }
     267              : 
     268       115642 :     if (myActiveProgram == "") {
     269              :         myActiveProgram = "default";
     270              :     }
     271       115642 :     MSTrafficLightLogic* tlLogic = nullptr;
     272              :     // build the tls-logic in dependence to its type
     273       115642 :     switch (myLogicType) {
     274           16 :         case TrafficLightType::SWARM_BASED:
     275           16 :             firstEventOffset = DELTA_T; //this is needed because swarm needs to update the pheromone on the lanes at every step
     276           16 :             tlLogic = new MSSwarmTrafficLightLogic(getTLLogicControlToUse(), myActiveKey, myActiveProgram, myActivePhases, step, firstEventOffset, myAdditionalParameter);
     277           16 :             break;
     278            0 :         case TrafficLightType::HILVL_DETERMINISTIC:
     279            0 :             tlLogic = new MSDeterministicHiLevelTrafficLightLogic(getTLLogicControlToUse(), myActiveKey, myActiveProgram, myActivePhases, step, firstEventOffset, myAdditionalParameter);
     280            0 :             break;
     281           16 :         case TrafficLightType::SOTL_REQUEST:
     282           16 :             tlLogic = new MSSOTLPolicyBasedTrafficLightLogic(getTLLogicControlToUse(), myActiveKey, myActiveProgram, myLogicType, myActivePhases, step, firstEventOffset, myAdditionalParameter, new MSSOTLRequestPolicy(myAdditionalParameter));
     283           16 :             break;
     284           16 :         case TrafficLightType::SOTL_PLATOON:
     285           16 :             tlLogic = new MSSOTLPolicyBasedTrafficLightLogic(getTLLogicControlToUse(), myActiveKey, myActiveProgram, myLogicType, myActivePhases, step, firstEventOffset, myAdditionalParameter, new MSSOTLPlatoonPolicy(myAdditionalParameter));
     286           16 :             break;
     287           16 :         case TrafficLightType::SOTL_WAVE:
     288           16 :             tlLogic = new MSSOTLWaveTrafficLightLogic(getTLLogicControlToUse(), myActiveKey, myActiveProgram, myActivePhases, step, firstEventOffset, myAdditionalParameter);
     289           16 :             break;
     290           16 :         case TrafficLightType::SOTL_PHASE:
     291           16 :             tlLogic = new MSSOTLPolicyBasedTrafficLightLogic(getTLLogicControlToUse(), myActiveKey, myActiveProgram, myLogicType, myActivePhases, step, firstEventOffset, myAdditionalParameter, new MSSOTLPhasePolicy(myAdditionalParameter));
     292           16 :             break;
     293           16 :         case TrafficLightType::SOTL_MARCHING:
     294           16 :             tlLogic = new MSSOTLPolicyBasedTrafficLightLogic(getTLLogicControlToUse(), myActiveKey, myActiveProgram, myLogicType, myActivePhases, step, firstEventOffset, myAdditionalParameter, new MSSOTLMarchingPolicy(myAdditionalParameter));
     295           16 :             break;
     296          494 :         case TrafficLightType::ACTUATED:
     297              :             // @note it is unclear how to apply the given offset in the context
     298              :             // of variable-length phases
     299          494 :             tlLogic = new MSActuatedTrafficLightLogic(getTLLogicControlToUse(),
     300              :                     myActiveKey, myActiveProgram, myOffset,
     301          494 :                     myActivePhases, step, (*i)->minDuration + myNet.getCurrentTimeStep(),
     302          494 :                     myAdditionalParameter, basePath, myActiveConditions, myActiveAssignments, myActiveFunctions);
     303          494 :             break;
     304           94 :         case TrafficLightType::NEMA:
     305           94 :             tlLogic = new NEMALogic(getTLLogicControlToUse(),
     306              :                                     myActiveKey, myActiveProgram, myOffset,
     307           94 :                                     myActivePhases, step, (*i)->minDuration + myNet.getCurrentTimeStep(),
     308           94 :                                     myAdditionalParameter, basePath);
     309           94 :             break;
     310          106 :         case TrafficLightType::DELAYBASED:
     311          106 :             tlLogic = new MSDelayBasedTrafficLightLogic(getTLLogicControlToUse(),
     312              :                     myActiveKey, myActiveProgram, myOffset,
     313          106 :                     myActivePhases, step, (*i)->minDuration + myNet.getCurrentTimeStep(),
     314          106 :                     myAdditionalParameter, basePath);
     315          106 :             break;
     316       110436 :         case TrafficLightType::STATIC:
     317       110436 :             tlLogic = new MSSimpleTrafficLightLogic(getTLLogicControlToUse(),
     318              :                                                     myActiveKey, myActiveProgram, myOffset,
     319              :                                                     TrafficLightType::STATIC,
     320       110436 :                                                     myActivePhases, step, firstEventOffset,
     321       110436 :                                                     myAdditionalParameter);
     322       110436 :             break;
     323         4265 :         case TrafficLightType::RAIL_SIGNAL:
     324         4265 :             tlLogic = new MSRailSignal(getTLLogicControlToUse(),
     325         4265 :                                        myActiveKey, myActiveProgram, myNet.getCurrentTimeStep(),
     326         4265 :                                        myAdditionalParameter);
     327         4265 :             break;
     328          151 :         case TrafficLightType::RAIL_CROSSING:
     329          151 :             tlLogic = new MSRailCrossing(getTLLogicControlToUse(),
     330          151 :                                          myActiveKey, myActiveProgram, myNet.getCurrentTimeStep(),
     331          151 :                                          myAdditionalParameter);
     332          151 :             break;
     333            0 :         case TrafficLightType::OFF:
     334            0 :             tlLogic = new MSOffTrafficLightLogic(getTLLogicControlToUse(), myActiveKey);
     335            0 :             break;
     336            0 :         case TrafficLightType::INVALID:
     337            0 :             throw ProcessError(TLF("Invalid traffic light type '%'", toString(myLogicType)));
     338              :     }
     339              :     myActivePhases.clear();
     340       115642 :     if (tlLogic != nullptr) {
     341       115642 :         if (getTLLogicControlToUse().add(myActiveKey, myActiveProgram, tlLogic)) {
     342       115636 :             if (myNetIsLoaded) {
     343        14137 :                 myAdditionalLogics.push_back(tlLogic);
     344       101499 :             } else if (myLogicType == TrafficLightType::RAIL_SIGNAL) {
     345              :                 // special case: intialize earlier because signals are already used when
     346              :                 // loading train routes in additional files
     347         4265 :                 myRailSignals.push_back(tlLogic);
     348              :             } else {
     349        97234 :                 myNetworkLogics.push_back(tlLogic);
     350              :             }
     351              :         } else {
     352            0 :             WRITE_ERRORF(TL("Another logic with id '%' and programID '%' exists."), myActiveKey, myActiveProgram);
     353              :         }
     354              :     }
     355              : }
     356              : 
     357              : 
     358              : void
     359       581579 : NLJunctionControlBuilder::initJunctionLogic(const std::string& id) {
     360       581579 :     myActiveKey = id;
     361       581579 :     myActiveProgram = "";
     362              :     myActiveLogic.clear();
     363              :     myActiveFoes.clear();
     364              :     myActiveConts.reset();
     365       581579 :     myRequestSize = NO_REQUEST_SIZE; // seems not to be used
     366       581579 :     myRequestItemNumber = 0;
     367       581579 :     myCurrentHasError = false;
     368       581579 : }
     369              : 
     370              : 
     371              : void
     372      1659317 : NLJunctionControlBuilder::addLogicItem(int request,
     373              :                                        const std::string& response,
     374              :                                        const std::string& foes,
     375              :                                        bool cont) {
     376      1659317 :     if (myCurrentHasError) {
     377              :         // had an error
     378              :         return;
     379              :     }
     380      1659317 :     if (request >= SUMO_MAX_CONNECTIONS) {
     381              :         // bad request
     382            0 :         myCurrentHasError = true;
     383            0 :         throw InvalidArgument("Junction logic '" + myActiveKey + "' is larger than allowed; recheck the network.");
     384              :     }
     385      1659317 :     if (myRequestSize == NO_REQUEST_SIZE) {
     386              :         // initialize
     387       326230 :         myRequestSize = (int)response.size();
     388              :     }
     389      1659317 :     if (static_cast<int>(response.size()) != myRequestSize) {
     390            0 :         myCurrentHasError = true;
     391            0 :         throw InvalidArgument("Invalid response size " + toString(response.size()) +
     392            0 :                               " in Junction logic '" + myActiveKey + "' (expected  " + toString(myRequestSize) + ")");
     393              :     }
     394      1659317 :     if (static_cast<int>(foes.size()) != myRequestSize) {
     395            0 :         myCurrentHasError = true;
     396            0 :         throw InvalidArgument("Invalid foes size " + toString(foes.size()) +
     397            0 :                               " in Junction logic '" + myActiveKey + "' (expected  " + toString(myRequestSize) + ")");
     398              :     }
     399              :     // assert that the logicitems come ordered by their request index
     400              :     assert((int)myActiveLogic.size() == request);
     401              :     assert((int)myActiveFoes.size() == request);
     402              :     // add the read response for the given request index
     403      1659317 :     myActiveLogic.push_back(std::bitset<SUMO_MAX_CONNECTIONS>(response));
     404              :     // add the read junction-internal foes for the given request index
     405      1659317 :     myActiveFoes.push_back(std::bitset<SUMO_MAX_CONNECTIONS>(foes));
     406              :     // add whether the vehicle may drive a little bit further
     407      1659317 :     myActiveConts.set(request, cont);
     408              :     // increse number of set information
     409      1659317 :     myRequestItemNumber++;
     410              : }
     411              : 
     412              : 
     413              : void
     414       111410 : NLJunctionControlBuilder::initTrafficLightLogic(const std::string& id, const std::string& programID,
     415              :         TrafficLightType type, SUMOTime offset) {
     416       111410 :     myActiveKey = id;
     417       111410 :     myActiveProgram = programID;
     418              :     myActivePhases.clear();
     419              :     myActiveConditions.clear();
     420              :     myActiveAssignments.clear();
     421              :     myActiveFunctions.clear();
     422       111410 :     myAbsDuration = 0;
     423       111410 :     myRequestSize = NO_REQUEST_SIZE;
     424       111410 :     myLogicType = type;
     425       111410 :     myOffset = offset;
     426              :     myAdditionalParameter.clear();
     427       111410 : }
     428              : 
     429              : 
     430              : void
     431       520826 : NLJunctionControlBuilder::addPhase(MSPhaseDefinition* phase) {
     432              :     // build and add the phase definition to the list
     433       520826 :     myActivePhases.push_back(phase);
     434              :     // add phase duration to the absolute duration
     435       520826 :     myAbsDuration += phase->duration;
     436       520826 : }
     437              : 
     438              : 
     439              : bool
     440           94 : NLJunctionControlBuilder::addCondition(const std::string& id, const std::string& value) {
     441              :     if (myActiveConditions.count(id) == 0) {
     442           94 :         myActiveConditions[id] = value;
     443           94 :         return true;
     444              :     } else {
     445            0 :         return false;
     446              :     }
     447              : }
     448              : 
     449              : 
     450              : void
     451           60 : NLJunctionControlBuilder::addAssignment(const std::string& id, const std::string& check, const std::string& value) {
     452           60 :     if (myActiveFunction.id == "") {
     453          102 :         myActiveAssignments.push_back(std::make_tuple(id, check, value));
     454              :     } else {
     455           18 :         myActiveFunction.assignments.push_back(std::make_tuple(id, check, value));
     456              :     }
     457           60 : }
     458              : 
     459              : 
     460              : void
     461            4 : NLJunctionControlBuilder::addFunction(const std::string& id, int nArgs) {
     462            4 :     myActiveFunction.id = id;
     463            4 :     myActiveFunction.nArgs = nArgs;
     464            4 : }
     465              : 
     466              : 
     467              : void
     468            4 : NLJunctionControlBuilder::closeFunction() {
     469            4 :     myActiveFunctions[myActiveFunction.id] = myActiveFunction;
     470              :     myActiveFunction.id = "";
     471              :     myActiveFunction.assignments.clear();
     472            4 : }
     473              : 
     474              : 
     475              : MSTLLogicControl*
     476        43710 : NLJunctionControlBuilder::buildTLLogics() {
     477        43710 :     if (!myLogicControl->closeNetworkReading()) {
     478            0 :         throw ProcessError(TL("Traffic lights could not be built."));
     479              :     }
     480        47975 :     for (MSTrafficLightLogic* const logic : myRailSignals) {
     481         4265 :         logic->init(myDetectorBuilder);
     482              :     }
     483        43710 :     MSTLLogicControl* ret = myLogicControl;
     484        43710 :     myNetIsLoaded = true;
     485        43710 :     myLogicControl = nullptr;
     486        43710 :     return ret;
     487              : }
     488              : 
     489              : 
     490              : void
     491        10315 : NLJunctionControlBuilder::addParam(const std::string& key,
     492              :                                    const std::string& value) {
     493        10315 :     myAdditionalParameter[key] = value;
     494        10315 : }
     495              : 
     496              : 
     497              : MSTLLogicControl&
     498      2080376 : NLJunctionControlBuilder::getTLLogicControlToUse() const {
     499      2080376 :     if (myLogicControl != nullptr) {
     500              :         return *myLogicControl;
     501              :     }
     502        58148 :     return myNet.getTLSControl();
     503              : }
     504              : 
     505              : 
     506              : const std::string&
     507      1041655 : NLJunctionControlBuilder::getActiveKey() const {
     508      1041655 :     return myActiveKey;
     509              : }
     510              : 
     511              : 
     512              : const std::string&
     513            1 : NLJunctionControlBuilder::getActiveSubKey() const {
     514            1 :     return myActiveProgram;
     515              : }
     516              : 
     517              : 
     518              : void
     519        42823 : NLJunctionControlBuilder::postLoadInitialization() {
     520       132137 :     for (MSTrafficLightLogic* const logic : myNetworkLogics) {
     521        89340 :         logic->init(myDetectorBuilder);
     522              :     }
     523        56914 :     for (MSTrafficLightLogic* const logic : myAdditionalLogics) {
     524        14122 :         logic->init(myDetectorBuilder);
     525              :     }
     526              :     // delay parameter loading until initialization
     527        42901 :     for (auto item : myLogicParams) {
     528          109 :         item.first->updateParameters(item.second);
     529              :     }
     530        42792 : }
     531              : 
     532              : 
     533              : MSJunction*
     534      3599432 : NLJunctionControlBuilder::retrieve(const std::string id) {
     535      3599432 :     if (myJunctions != nullptr) {
     536              :         return myJunctions->get(id);
     537              :     } else {
     538              :         return nullptr;
     539              :     }
     540              : }
     541              : 
     542              : 
     543              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1