LCOV - code coverage report
Current view: top level - src/netload - NLJunctionControlBuilder.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 90.0 % 249 224
Test Date: 2024-12-21 15:45:41 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-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    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        43238 : NLJunctionControlBuilder::NLJunctionControlBuilder(MSNet& net, NLDetectorBuilder& db) :
      70        43238 :     myNet(net),
      71        43238 :     myDetectorBuilder(db),
      72        43238 :     myOffset(0),
      73        43238 :     myJunctions(new MSJunctionControl()),
      74       172952 :     myNetIsLoaded(false) {
      75        43238 :     myLogicControl = new MSTLLogicControl();
      76        43238 : }
      77              : 
      78              : 
      79        43238 : NLJunctionControlBuilder::~NLJunctionControlBuilder() {
      80        43238 :     delete myLogicControl;
      81        43238 :     delete myJunctions;
      82       129714 : }
      83              : 
      84              : 
      85              : void
      86       565138 : 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       565138 :     myActiveInternalLanes = internalLanes;
      95       565138 :     myActiveIncomingLanes = incomingLanes;
      96       565138 :     myActiveID = id;
      97       565138 :     myActiveKey = key;
      98       565138 :     myType = type;
      99              :     myPosition.set(pos);
     100              :     myShape = shape;
     101       565138 :     myActiveName = name;
     102              :     myAdditionalParameter.clear();
     103       565138 : }
     104              : 
     105              : 
     106              : void
     107       565138 : NLJunctionControlBuilder::closeJunction(const std::string& basePath) {
     108       565138 :     if (myCurrentHasError) {
     109              :         // had an error before...
     110              :         return;
     111              :     }
     112       565138 :     if (myRequestSize != NO_REQUEST_SIZE && myRequestItemNumber != myRequestSize) {
     113            0 :         throw InvalidArgument("The description for the junction logic '" + myActiveKey + "' is malicious.");
     114              :     }
     115       565138 :     if (myJunctions == nullptr) {
     116            0 :         throw ProcessError(TL("Information about the number of nodes was missing."));
     117              :     }
     118              :     MSJunction* junction = nullptr;
     119       565138 :     switch (myType) {
     120        58796 :         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        58796 :             if (!myActiveLogic.empty()) {
     126          120 :                 WRITE_WARNINGF(TL("Ignoring junction logic for junction '%'."), myActiveID)
     127              :             }
     128        58796 :             junction = buildNoLogicJunction();
     129        58796 :             break;
     130       316527 :         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       316527 :             junction = buildLogicJunction(new MSBitsetLogic(myRequestSize, myActiveLogic, myActiveFoes, myActiveConts));
     139              :             break;
     140       186135 :         case SumoXMLNodeType::INTERNAL:
     141       186135 :             if (MSGlobals::gUsingInternalLanes) {
     142       153204 :                 if (!myActiveLogic.empty()) {
     143           18 :                     WRITE_WARNINGF(TL("Ignoring junction logic for junction '%'."), myActiveID)
     144              :                 }
     145       153204 :                 junction = buildInternalJunction();
     146              :             }
     147              :             break;
     148         3680 :         case SumoXMLNodeType::RAIL_SIGNAL:
     149              :         case SumoXMLNodeType::RAIL_CROSSING:
     150         3680 :             myOffset = 0;
     151         3680 :             myActiveKey = myActiveID;
     152         3680 :             myActiveProgram = "0";
     153         3680 :             myLogicType = myType == SumoXMLNodeType::RAIL_SIGNAL ? TrafficLightType::RAIL_SIGNAL : TrafficLightType::RAIL_CROSSING;
     154         3680 :             closeTrafficLightLogic(basePath);
     155         3680 :             junction = buildLogicJunction(new MSBitsetLogic(myRequestSize, myActiveLogic, myActiveFoes, myActiveConts));
     156              :             break;
     157            0 :         default:
     158            0 :             throw InvalidArgument("False junction logic type.");
     159              :     }
     160       532207 :     if (junction != nullptr) {
     161       532207 :         if (!myJunctions->add(myActiveID, junction)) {
     162           12 :             throw InvalidArgument("Another junction with the id '" + myActiveID + "' exists.");
     163              :         }
     164       532201 :         junction->updateParameters(myAdditionalParameter);
     165              :     }
     166              : }
     167              : 
     168              : 
     169              : MSJunctionControl*
     170        42811 : NLJunctionControlBuilder::build() const {
     171        42811 :     MSJunctionControl* js = myJunctions;
     172        42811 :     myJunctions = nullptr;
     173        42811 :     return js;
     174              : }
     175              : 
     176              : 
     177              : MSJunction*
     178        58796 : NLJunctionControlBuilder::buildNoLogicJunction() {
     179        58796 :     return new MSNoLogicJunction(myActiveID, myType, myPosition, myShape, myActiveName,
     180        58796 :                                  myActiveIncomingLanes, myActiveInternalLanes);
     181              : }
     182              : 
     183              : 
     184              : MSJunction*
     185       320207 : NLJunctionControlBuilder::buildLogicJunction(MSJunctionLogic* const logic) {
     186       320207 :     return new MSRightOfWayJunction(myActiveID, myType, myPosition, myShape, myActiveName,
     187       320207 :                                     myActiveIncomingLanes, myActiveInternalLanes, logic);
     188              : }
     189              : 
     190              : 
     191              : MSJunction*
     192       153204 : NLJunctionControlBuilder::buildInternalJunction() {
     193              :     // build the junction
     194       306408 :     return new MSInternalJunction(myActiveID, myType, myPosition, myShape, myActiveIncomingLanes,
     195       153204 :                                   myActiveInternalLanes);
     196              : }
     197              : 
     198              : 
     199              : MSTLLogicControl::TLSLogicVariants&
     200      1600043 : NLJunctionControlBuilder::getTLLogic(const std::string& id) const {
     201      1600043 :     return getTLLogicControlToUse().get(id);
     202              : }
     203              : 
     204              : 
     205              : void
     206       114069 : NLJunctionControlBuilder::closeTrafficLightLogic(const std::string& basePath) {
     207       114069 :     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          166 :         return;
     216              :     }
     217              :     SUMOTime firstEventOffset = 0;
     218              :     int step = 0;
     219              :     MSSimpleTrafficLightLogic::Phases::const_iterator i = myActivePhases.begin();
     220       114032 :     MSTrafficLightLogic* existing = getTLLogicControlToUse().get(myActiveKey, myActiveProgram);
     221       114032 :     if (existing != nullptr && (existing->getLogicType() == TrafficLightType::RAIL_SIGNAL || existing->getLogicType() == TrafficLightType::RAIL_CROSSING)) {
     222           35 :         existing->updateParameters(myAdditionalParameter);
     223           35 :         return;
     224              :     } else {
     225       113997 :         if (myLogicType != TrafficLightType::RAIL_SIGNAL && myLogicType != TrafficLightType::RAIL_CROSSING) {
     226       110317 :             if (myAbsDuration == 0) {
     227           95 :                 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           94 :                     myAbsDuration = existing->getDefaultCycleTime();
     232           94 :                     i = existing->getPhases().begin();
     233              :                 }
     234       110222 :             } 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       110315 :             if (myOffset >= 0) {
     242       110256 :                 offset = (myNet.getCurrentTimeStep() + myAbsDuration - (myOffset % myAbsDuration)) % myAbsDuration;
     243              :             } else {
     244           59 :                 offset = (myNet.getCurrentTimeStep() + ((-myOffset) % myAbsDuration)) % myAbsDuration;
     245              :             }
     246       111563 :             while (offset >= (*i)->duration) {
     247         1248 :                 step++;
     248         1248 :                 offset -= (*i)->duration;
     249              :                 ++i;
     250              :             }
     251       110315 :             firstEventOffset = (*i)->duration - offset + myNet.getCurrentTimeStep();
     252       110315 :             if (existing != nullptr) {
     253           94 :                 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           94 :                 myLogicParams[existing] = myAdditionalParameter;
     259           94 :                 return;
     260              :             }
     261              :         }
     262              :     }
     263              : 
     264       113901 :     if (myActiveProgram == "") {
     265              :         myActiveProgram = "default";
     266              :     }
     267       113901 :     MSTrafficLightLogic* tlLogic = nullptr;
     268              :     // build the tls-logic in dependence to its type
     269       113901 :     switch (myLogicType) {
     270           16 :         case TrafficLightType::SWARM_BASED:
     271           16 :             firstEventOffset = DELTA_T; //this is needed because swarm needs to update the pheromone on the lanes at every step
     272           16 :             tlLogic = new MSSwarmTrafficLightLogic(getTLLogicControlToUse(), myActiveKey, myActiveProgram, myActivePhases, step, firstEventOffset, myAdditionalParameter);
     273           16 :             break;
     274            0 :         case TrafficLightType::HILVL_DETERMINISTIC:
     275            0 :             tlLogic = new MSDeterministicHiLevelTrafficLightLogic(getTLLogicControlToUse(), myActiveKey, myActiveProgram, myActivePhases, step, firstEventOffset, myAdditionalParameter);
     276            0 :             break;
     277           16 :         case TrafficLightType::SOTL_REQUEST:
     278           16 :             tlLogic = new MSSOTLPolicyBasedTrafficLightLogic(getTLLogicControlToUse(), myActiveKey, myActiveProgram, myLogicType, myActivePhases, step, firstEventOffset, myAdditionalParameter, new MSSOTLRequestPolicy(myAdditionalParameter));
     279           16 :             break;
     280           16 :         case TrafficLightType::SOTL_PLATOON:
     281           16 :             tlLogic = new MSSOTLPolicyBasedTrafficLightLogic(getTLLogicControlToUse(), myActiveKey, myActiveProgram, myLogicType, myActivePhases, step, firstEventOffset, myAdditionalParameter, new MSSOTLPlatoonPolicy(myAdditionalParameter));
     282           16 :             break;
     283           16 :         case TrafficLightType::SOTL_WAVE:
     284           16 :             tlLogic = new MSSOTLWaveTrafficLightLogic(getTLLogicControlToUse(), myActiveKey, myActiveProgram, myActivePhases, step, firstEventOffset, myAdditionalParameter);
     285           16 :             break;
     286           16 :         case TrafficLightType::SOTL_PHASE:
     287           16 :             tlLogic = new MSSOTLPolicyBasedTrafficLightLogic(getTLLogicControlToUse(), myActiveKey, myActiveProgram, myLogicType, myActivePhases, step, firstEventOffset, myAdditionalParameter, new MSSOTLPhasePolicy(myAdditionalParameter));
     288           16 :             break;
     289           16 :         case TrafficLightType::SOTL_MARCHING:
     290           16 :             tlLogic = new MSSOTLPolicyBasedTrafficLightLogic(getTLLogicControlToUse(), myActiveKey, myActiveProgram, myLogicType, myActivePhases, step, firstEventOffset, myAdditionalParameter, new MSSOTLMarchingPolicy(myAdditionalParameter));
     291           16 :             break;
     292          487 :         case TrafficLightType::ACTUATED:
     293              :             // @note it is unclear how to apply the given offset in the context
     294              :             // of variable-length phases
     295          487 :             tlLogic = new MSActuatedTrafficLightLogic(getTLLogicControlToUse(),
     296              :                     myActiveKey, myActiveProgram, myOffset,
     297          487 :                     myActivePhases, step, (*i)->minDuration + myNet.getCurrentTimeStep(),
     298          487 :                     myAdditionalParameter, basePath, myActiveConditions, myActiveAssignments, myActiveFunctions);
     299          487 :             break;
     300           93 :         case TrafficLightType::NEMA:
     301           93 :             tlLogic = new NEMALogic(getTLLogicControlToUse(),
     302              :                                     myActiveKey, myActiveProgram, myOffset,
     303           93 :                                     myActivePhases, step, (*i)->minDuration + myNet.getCurrentTimeStep(),
     304           93 :                                     myAdditionalParameter, basePath);
     305           93 :             break;
     306           98 :         case TrafficLightType::DELAYBASED:
     307           98 :             tlLogic = new MSDelayBasedTrafficLightLogic(getTLLogicControlToUse(),
     308              :                     myActiveKey, myActiveProgram, myOffset,
     309           98 :                     myActivePhases, step, (*i)->minDuration + myNet.getCurrentTimeStep(),
     310           98 :                     myAdditionalParameter, basePath);
     311           98 :             break;
     312       109447 :         case TrafficLightType::STATIC:
     313       109447 :             tlLogic = new MSSimpleTrafficLightLogic(getTLLogicControlToUse(),
     314              :                                                     myActiveKey, myActiveProgram, myOffset,
     315              :                                                     TrafficLightType::STATIC,
     316       109447 :                                                     myActivePhases, step, firstEventOffset,
     317       109447 :                                                     myAdditionalParameter);
     318       109447 :             break;
     319         3533 :         case TrafficLightType::RAIL_SIGNAL:
     320         3533 :             tlLogic = new MSRailSignal(getTLLogicControlToUse(),
     321         3533 :                                        myActiveKey, myActiveProgram, myNet.getCurrentTimeStep(),
     322         3533 :                                        myAdditionalParameter);
     323         3533 :             break;
     324          147 :         case TrafficLightType::RAIL_CROSSING:
     325          147 :             tlLogic = new MSRailCrossing(getTLLogicControlToUse(),
     326          147 :                                          myActiveKey, myActiveProgram, myNet.getCurrentTimeStep(),
     327          147 :                                          myAdditionalParameter);
     328          147 :             break;
     329            0 :         case TrafficLightType::OFF:
     330            0 :             tlLogic = new MSOffTrafficLightLogic(getTLLogicControlToUse(), myActiveKey);
     331            0 :             break;
     332            0 :         case TrafficLightType::INVALID:
     333            0 :             throw ProcessError(TLF("Invalid traffic light type '%'", toString(myLogicType)));
     334              :     }
     335              :     myActivePhases.clear();
     336       113901 :     if (tlLogic != nullptr) {
     337       113901 :         if (getTLLogicControlToUse().add(myActiveKey, myActiveProgram, tlLogic)) {
     338       113895 :             if (myNetIsLoaded) {
     339        14098 :                 myAdditionalLogics.push_back(tlLogic);
     340        99797 :             } else if (myLogicType == TrafficLightType::RAIL_SIGNAL) {
     341              :                 // special case: intialize earlier because signals are already used when
     342              :                 // loading train routes in additional files
     343         3533 :                 myRailSignals.push_back(tlLogic);
     344              :             } else {
     345        96264 :                 myNetworkLogics.push_back(tlLogic);
     346              :             }
     347              :         } else {
     348            0 :             WRITE_ERRORF(TL("Another logic with id '%' and programID '%' exists."), myActiveKey, myActiveProgram);
     349              :         }
     350              :     }
     351              : }
     352              : 
     353              : 
     354              : void
     355       565138 : NLJunctionControlBuilder::initJunctionLogic(const std::string& id) {
     356       565138 :     myActiveKey = id;
     357       565138 :     myActiveProgram = "";
     358              :     myActiveLogic.clear();
     359              :     myActiveFoes.clear();
     360              :     myActiveConts.reset();
     361       565138 :     myRequestSize = NO_REQUEST_SIZE; // seems not to be used
     362       565138 :     myRequestItemNumber = 0;
     363       565138 :     myCurrentHasError = false;
     364       565138 : }
     365              : 
     366              : 
     367              : void
     368      1624582 : NLJunctionControlBuilder::addLogicItem(int request,
     369              :                                        const std::string& response,
     370              :                                        const std::string& foes,
     371              :                                        bool cont) {
     372      1624582 :     if (myCurrentHasError) {
     373              :         // had an error
     374              :         return;
     375              :     }
     376      1624582 :     if (request >= SUMO_MAX_CONNECTIONS) {
     377              :         // bad request
     378            0 :         myCurrentHasError = true;
     379            0 :         throw InvalidArgument("Junction logic '" + myActiveKey + "' is larger than allowed; recheck the network.");
     380              :     }
     381      1624582 :     if (myRequestSize == NO_REQUEST_SIZE) {
     382              :         // initialize
     383       320253 :         myRequestSize = (int)response.size();
     384              :     }
     385      1624582 :     if (static_cast<int>(response.size()) != myRequestSize) {
     386            0 :         myCurrentHasError = true;
     387            0 :         throw InvalidArgument("Invalid response size " + toString(response.size()) +
     388            0 :                               " in Junction logic '" + myActiveKey + "' (expected  " + toString(myRequestSize) + ")");
     389              :     }
     390      1624582 :     if (static_cast<int>(foes.size()) != myRequestSize) {
     391            0 :         myCurrentHasError = true;
     392            0 :         throw InvalidArgument("Invalid foes size " + toString(foes.size()) +
     393            0 :                               " in Junction logic '" + myActiveKey + "' (expected  " + toString(myRequestSize) + ")");
     394              :     }
     395              :     // assert that the logicitems come ordered by their request index
     396              :     assert((int)myActiveLogic.size() == request);
     397              :     assert((int)myActiveFoes.size() == request);
     398              :     // add the read response for the given request index
     399      1624582 :     myActiveLogic.push_back(std::bitset<SUMO_MAX_CONNECTIONS>(response));
     400              :     // add the read junction-internal foes for the given request index
     401      1624582 :     myActiveFoes.push_back(std::bitset<SUMO_MAX_CONNECTIONS>(foes));
     402              :     // add whether the vehicle may drive a little bit further
     403      1624582 :     myActiveConts.set(request, cont);
     404              :     // increse number of set information
     405      1624582 :     myRequestItemNumber++;
     406              : }
     407              : 
     408              : 
     409              : void
     410       110389 : NLJunctionControlBuilder::initTrafficLightLogic(const std::string& id, const std::string& programID,
     411              :         TrafficLightType type, SUMOTime offset) {
     412       110389 :     myActiveKey = id;
     413       110389 :     myActiveProgram = programID;
     414              :     myActivePhases.clear();
     415              :     myActiveConditions.clear();
     416              :     myActiveAssignments.clear();
     417              :     myActiveFunctions.clear();
     418       110389 :     myAbsDuration = 0;
     419       110389 :     myRequestSize = NO_REQUEST_SIZE;
     420       110389 :     myLogicType = type;
     421       110389 :     myOffset = offset;
     422              :     myAdditionalParameter.clear();
     423       110389 : }
     424              : 
     425              : 
     426              : void
     427       515627 : NLJunctionControlBuilder::addPhase(MSPhaseDefinition* phase) {
     428              :     // build and add the phase definition to the list
     429       515627 :     myActivePhases.push_back(phase);
     430              :     // add phase duration to the absolute duration
     431       515627 :     myAbsDuration += phase->duration;
     432       515627 : }
     433              : 
     434              : 
     435              : bool
     436           94 : NLJunctionControlBuilder::addCondition(const std::string& id, const std::string& value) {
     437              :     if (myActiveConditions.count(id) == 0) {
     438           94 :         myActiveConditions[id] = value;
     439           94 :         return true;
     440              :     } else {
     441            0 :         return false;
     442              :     }
     443              : }
     444              : 
     445              : 
     446              : void
     447           60 : NLJunctionControlBuilder::addAssignment(const std::string& id, const std::string& check, const std::string& value) {
     448           60 :     if (myActiveFunction.id == "") {
     449          102 :         myActiveAssignments.push_back(std::make_tuple(id, check, value));
     450              :     } else {
     451           18 :         myActiveFunction.assignments.push_back(std::make_tuple(id, check, value));
     452              :     }
     453           60 : }
     454              : 
     455              : 
     456              : void
     457            4 : NLJunctionControlBuilder::addFunction(const std::string& id, int nArgs) {
     458            4 :     myActiveFunction.id = id;
     459            4 :     myActiveFunction.nArgs = nArgs;
     460            4 : }
     461              : 
     462              : 
     463              : void
     464            4 : NLJunctionControlBuilder::closeFunction() {
     465            4 :     myActiveFunctions[myActiveFunction.id] = myActiveFunction;
     466              :     myActiveFunction.id = "";
     467              :     myActiveFunction.assignments.clear();
     468            4 : }
     469              : 
     470              : 
     471              : MSTLLogicControl*
     472        42800 : NLJunctionControlBuilder::buildTLLogics() {
     473        42800 :     if (!myLogicControl->closeNetworkReading()) {
     474            0 :         throw ProcessError(TL("Traffic lights could not be built."));
     475              :     }
     476        46333 :     for (MSTrafficLightLogic* const logic : myRailSignals) {
     477         3533 :         logic->init(myDetectorBuilder);
     478              :     }
     479        42800 :     MSTLLogicControl* ret = myLogicControl;
     480        42800 :     myNetIsLoaded = true;
     481        42800 :     myLogicControl = nullptr;
     482        42800 :     return ret;
     483              : }
     484              : 
     485              : 
     486              : void
     487        10281 : NLJunctionControlBuilder::addParam(const std::string& key,
     488              :                                    const std::string& value) {
     489        10281 :     myAdditionalParameter[key] = value;
     490        10281 : }
     491              : 
     492              : 
     493              : MSTLLogicControl&
     494      2052936 : NLJunctionControlBuilder::getTLLogicControlToUse() const {
     495      2052936 :     if (myLogicControl != nullptr) {
     496              :         return *myLogicControl;
     497              :     }
     498        57944 :     return myNet.getTLSControl();
     499              : }
     500              : 
     501              : 
     502              : const std::string&
     503      1031257 : NLJunctionControlBuilder::getActiveKey() const {
     504      1031257 :     return myActiveKey;
     505              : }
     506              : 
     507              : 
     508              : const std::string&
     509            1 : NLJunctionControlBuilder::getActiveSubKey() const {
     510            1 :     return myActiveProgram;
     511              : }
     512              : 
     513              : 
     514              : void
     515        42026 : NLJunctionControlBuilder::postLoadInitialization() {
     516       130448 :     for (MSTrafficLightLogic* const logic : myNetworkLogics) {
     517        88448 :         logic->init(myDetectorBuilder);
     518              :     }
     519        56078 :     for (MSTrafficLightLogic* const logic : myAdditionalLogics) {
     520        14083 :         logic->init(myDetectorBuilder);
     521              :     }
     522              :     // delay parameter loading until initialization
     523        42088 :     for (auto item : myLogicParams) {
     524           93 :         item.first->updateParameters(item.second);
     525              :     }
     526        41995 : }
     527              : 
     528              : 
     529              : MSJunction*
     530      3491342 : NLJunctionControlBuilder::retrieve(const std::string id) {
     531      3491342 :     if (myJunctions != nullptr) {
     532              :         return myJunctions->get(id);
     533              :     } else {
     534              :         return nullptr;
     535              :     }
     536              : }
     537              : 
     538              : 
     539              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1