LCOV - code coverage report
Current view: top level - src/netload - NLJunctionControlBuilder.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 226 251 90.0 %
Date: 2024-05-03 15:29:52 Functions: 25 26 96.2 %

          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       35455 : NLJunctionControlBuilder::NLJunctionControlBuilder(MSNet& net, NLDetectorBuilder& db) :
      70       35455 :     myNet(net),
      71       35455 :     myDetectorBuilder(db),
      72       35455 :     myOffset(0),
      73       35455 :     myJunctions(new MSJunctionControl()),
      74      141820 :     myNetIsLoaded(false) {
      75       35455 :     myLogicControl = new MSTLLogicControl();
      76       35455 : }
      77             : 
      78             : 
      79       35455 : NLJunctionControlBuilder::~NLJunctionControlBuilder() {
      80       35455 :     delete myLogicControl;
      81       35455 :     delete myJunctions;
      82      106365 : }
      83             : 
      84             : 
      85             : void
      86      480279 : 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      480279 :     myActiveInternalLanes = internalLanes;
      95      480279 :     myActiveIncomingLanes = incomingLanes;
      96      480279 :     myActiveID = id;
      97      480279 :     myActiveKey = key;
      98      480279 :     myType = type;
      99             :     myPosition.set(pos);
     100             :     myShape = shape;
     101      480279 :     myActiveName = name;
     102             :     myAdditionalParameter.clear();
     103      480279 : }
     104             : 
     105             : 
     106             : void
     107      480279 : NLJunctionControlBuilder::closeJunction(const std::string& basePath) {
     108      480279 :     if (myCurrentHasError) {
     109             :         // had an error before...
     110             :         return;
     111             :     }
     112      480279 :     if (myRequestSize != NO_REQUEST_SIZE && myRequestItemNumber != myRequestSize) {
     113           0 :         throw InvalidArgument("The description for the junction logic '" + myActiveKey + "' is malicious.");
     114             :     }
     115      480279 :     if (myJunctions == nullptr) {
     116           0 :         throw ProcessError(TL("Information about the number of nodes was missing."));
     117             :     }
     118             :     MSJunction* junction = nullptr;
     119      480279 :     switch (myType) {
     120       62883 :         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       62883 :             if (!myActiveLogic.empty()) {
     126         120 :                 WRITE_WARNINGF(TL("Ignoring junction logic for junction '%'."), myActiveID)
     127             :             }
     128       62883 :             junction = buildNoLogicJunction();
     129       62883 :             break;
     130      246486 :         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      246486 :             junction = buildLogicJunction(new MSBitsetLogic(myRequestSize, myActiveLogic, myActiveFoes, myActiveConts));
     139      246486 :             break;
     140      168008 :         case SumoXMLNodeType::INTERNAL:
     141      168008 :             if (MSGlobals::gUsingInternalLanes) {
     142      134263 :                 if (!myActiveLogic.empty()) {
     143          18 :                     WRITE_WARNINGF(TL("Ignoring junction logic for junction '%'."), myActiveID)
     144             :                 }
     145      134263 :                 junction = buildInternalJunction();
     146             :             }
     147             :             break;
     148        2902 :         case SumoXMLNodeType::RAIL_SIGNAL:
     149             :         case SumoXMLNodeType::RAIL_CROSSING:
     150        2902 :             myOffset = 0;
     151        2902 :             myActiveKey = myActiveID;
     152        2902 :             myActiveProgram = "0";
     153        2902 :             myLogicType = myType == SumoXMLNodeType::RAIL_SIGNAL ? TrafficLightType::RAIL_SIGNAL : TrafficLightType::RAIL_CROSSING;
     154        2902 :             closeTrafficLightLogic(basePath);
     155        2902 :             junction = buildLogicJunction(new MSBitsetLogic(myRequestSize, myActiveLogic, myActiveFoes, myActiveConts));
     156        2902 :             break;
     157           0 :         default:
     158           0 :             throw InvalidArgument("False junction logic type.");
     159             :     }
     160      446534 :     if (junction != nullptr) {
     161      446534 :         if (!myJunctions->add(myActiveID, junction)) {
     162         172 :             throw InvalidArgument("Another junction with the id '" + myActiveID + "' exists.");
     163             :         }
     164      446448 :         junction->updateParameters(myAdditionalParameter);
     165             :     }
     166             : }
     167             : 
     168             : 
     169             : MSJunctionControl*
     170       34684 : NLJunctionControlBuilder::build() const {
     171       34684 :     MSJunctionControl* js = myJunctions;
     172       34684 :     myJunctions = nullptr;
     173       34684 :     return js;
     174             : }
     175             : 
     176             : 
     177             : MSJunction*
     178       62883 : NLJunctionControlBuilder::buildNoLogicJunction() {
     179       62883 :     return new MSNoLogicJunction(myActiveID, myType, myPosition, myShape, myActiveName,
     180      169260 :                                  myActiveIncomingLanes, myActiveInternalLanes);
     181             : }
     182             : 
     183             : 
     184             : MSJunction*
     185      249388 : NLJunctionControlBuilder::buildLogicJunction(MSJunctionLogic* const logic) {
     186      249388 :     return new MSRightOfWayJunction(myActiveID, myType, myPosition, myShape, myActiveName,
     187      748164 :                                     myActiveIncomingLanes, myActiveInternalLanes, logic);
     188             : }
     189             : 
     190             : 
     191             : MSJunction*
     192      134263 : NLJunctionControlBuilder::buildInternalJunction() {
     193             :     // build the junction
     194      268526 :     return new MSInternalJunction(myActiveID, myType, myPosition, myShape, myActiveIncomingLanes,
     195      402789 :                                   myActiveInternalLanes);
     196             : }
     197             : 
     198             : 
     199             : MSTLLogicControl::TLSLogicVariants&
     200     1662825 : NLJunctionControlBuilder::getTLLogic(const std::string& id) const {
     201     1662825 :     return getTLLogicControlToUse().get(id);
     202             : }
     203             : 
     204             : 
     205             : void
     206      109198 : NLJunctionControlBuilder::closeTrafficLightLogic(const std::string& basePath) {
     207      109198 :     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         218 :         return;
     216             :     }
     217             :     SUMOTime firstEventOffset = 0;
     218             :     int step = 0;
     219             :     MSSimpleTrafficLightLogic::Phases::const_iterator i = myActivePhases.begin();
     220      109161 :     MSTrafficLightLogic* existing = getTLLogicControlToUse().get(myActiveKey, myActiveProgram);
     221      109161 :     if (existing != nullptr && (existing->getLogicType() == TrafficLightType::RAIL_SIGNAL || existing->getLogicType() == TrafficLightType::RAIL_CROSSING)) {
     222          35 :         existing->updateParameters(myAdditionalParameter);
     223          35 :         return;
     224             :     } else {
     225      109126 :         if (myLogicType != TrafficLightType::RAIL_SIGNAL && myLogicType != TrafficLightType::RAIL_CROSSING) {
     226      106224 :             if (myAbsDuration == 0) {
     227         147 :                 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         146 :                     myAbsDuration = existing->getDefaultCycleTime();
     232         146 :                     i = existing->getPhases().begin();
     233             :                 }
     234      106077 :             } 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      106222 :             if (myOffset >= 0) {
     242      106151 :                 offset = (myNet.getCurrentTimeStep() + myAbsDuration - (myOffset % myAbsDuration)) % myAbsDuration;
     243             :             } else {
     244          71 :                 offset = (myNet.getCurrentTimeStep() + ((-myOffset) % myAbsDuration)) % myAbsDuration;
     245             :             }
     246      107618 :             while (offset >= (*i)->duration) {
     247        1396 :                 step++;
     248        1396 :                 offset -= (*i)->duration;
     249             :                 ++i;
     250             :             }
     251      106222 :             firstEventOffset = (*i)->duration - offset + myNet.getCurrentTimeStep();
     252      106222 :             if (existing != nullptr) {
     253         146 :                 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         146 :                 myLogicParams[existing] = myAdditionalParameter;
     259         146 :                 return;
     260             :             }
     261             :         }
     262             :     }
     263             : 
     264      108978 :     if (myActiveProgram == "") {
     265             :         myActiveProgram = "default";
     266             :     }
     267      108978 :     MSTrafficLightLogic* tlLogic = nullptr;
     268             :     // build the tls-logic in dependence to its type
     269      108978 :     switch (myLogicType) {
     270          32 :         case TrafficLightType::SWARM_BASED:
     271          32 :             firstEventOffset = DELTA_T; //this is needed because swarm needs to update the pheromone on the lanes at every step
     272          32 :             tlLogic = new MSSwarmTrafficLightLogic(getTLLogicControlToUse(), myActiveKey, myActiveProgram, myActivePhases, step, firstEventOffset, myAdditionalParameter);
     273          32 :             break;
     274           0 :         case TrafficLightType::HILVL_DETERMINISTIC:
     275           0 :             tlLogic = new MSDeterministicHiLevelTrafficLightLogic(getTLLogicControlToUse(), myActiveKey, myActiveProgram, myActivePhases, step, firstEventOffset, myAdditionalParameter);
     276           0 :             break;
     277          32 :         case TrafficLightType::SOTL_REQUEST:
     278          32 :             tlLogic = new MSSOTLPolicyBasedTrafficLightLogic(getTLLogicControlToUse(), myActiveKey, myActiveProgram, myLogicType, myActivePhases, step, firstEventOffset, myAdditionalParameter, new MSSOTLRequestPolicy(myAdditionalParameter));
     279          32 :             break;
     280          32 :         case TrafficLightType::SOTL_PLATOON:
     281          32 :             tlLogic = new MSSOTLPolicyBasedTrafficLightLogic(getTLLogicControlToUse(), myActiveKey, myActiveProgram, myLogicType, myActivePhases, step, firstEventOffset, myAdditionalParameter, new MSSOTLPlatoonPolicy(myAdditionalParameter));
     282          32 :             break;
     283          32 :         case TrafficLightType::SOTL_WAVE:
     284          32 :             tlLogic = new MSSOTLWaveTrafficLightLogic(getTLLogicControlToUse(), myActiveKey, myActiveProgram, myActivePhases, step, firstEventOffset, myAdditionalParameter);
     285          32 :             break;
     286          32 :         case TrafficLightType::SOTL_PHASE:
     287          32 :             tlLogic = new MSSOTLPolicyBasedTrafficLightLogic(getTLLogicControlToUse(), myActiveKey, myActiveProgram, myLogicType, myActivePhases, step, firstEventOffset, myAdditionalParameter, new MSSOTLPhasePolicy(myAdditionalParameter));
     288          32 :             break;
     289          32 :         case TrafficLightType::SOTL_MARCHING:
     290          32 :             tlLogic = new MSSOTLPolicyBasedTrafficLightLogic(getTLLogicControlToUse(), myActiveKey, myActiveProgram, myLogicType, myActivePhases, step, firstEventOffset, myAdditionalParameter, new MSSOTLMarchingPolicy(myAdditionalParameter));
     291          32 :             break;
     292         582 :         case TrafficLightType::ACTUATED:
     293             :             // @note it is unclear how to apply the given offset in the context
     294             :             // of variable-length phases
     295         582 :             tlLogic = new MSActuatedTrafficLightLogic(getTLLogicControlToUse(),
     296             :                     myActiveKey, myActiveProgram, myOffset,
     297         582 :                     myActivePhases, step, (*i)->minDuration + myNet.getCurrentTimeStep(),
     298         582 :                     myAdditionalParameter, basePath, myActiveConditions, myActiveAssignments, myActiveFunctions);
     299         582 :             break;
     300          97 :         case TrafficLightType::NEMA:
     301          97 :             tlLogic = new NEMALogic(getTLLogicControlToUse(),
     302             :                                     myActiveKey, myActiveProgram, myOffset,
     303          97 :                                     myActivePhases, step, (*i)->minDuration + myNet.getCurrentTimeStep(),
     304          97 :                                     myAdditionalParameter, basePath);
     305          97 :             break;
     306         105 :         case TrafficLightType::DELAYBASED:
     307         105 :             tlLogic = new MSDelayBasedTrafficLightLogic(getTLLogicControlToUse(),
     308             :                     myActiveKey, myActiveProgram, myOffset,
     309         105 :                     myActivePhases, step, (*i)->minDuration + myNet.getCurrentTimeStep(),
     310         105 :                     myAdditionalParameter, basePath);
     311         105 :             break;
     312      105100 :         case TrafficLightType::STATIC:
     313      105100 :             tlLogic = new MSSimpleTrafficLightLogic(getTLLogicControlToUse(),
     314             :                                                     myActiveKey, myActiveProgram, myOffset,
     315             :                                                     TrafficLightType::STATIC,
     316      105100 :                                                     myActivePhases, step, firstEventOffset,
     317      105100 :                                                     myAdditionalParameter);
     318      105100 :             break;
     319        2727 :         case TrafficLightType::RAIL_SIGNAL:
     320        2727 :             tlLogic = new MSRailSignal(getTLLogicControlToUse(),
     321        5454 :                                        myActiveKey, myActiveProgram, myNet.getCurrentTimeStep(),
     322        2727 :                                        myAdditionalParameter);
     323        2727 :             break;
     324         175 :         case TrafficLightType::RAIL_CROSSING:
     325         175 :             tlLogic = new MSRailCrossing(getTLLogicControlToUse(),
     326         175 :                                          myActiveKey, myActiveProgram, myNet.getCurrentTimeStep(),
     327         175 :                                          myAdditionalParameter);
     328         175 :             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      108978 :     if (tlLogic != nullptr) {
     337      108978 :         if (getTLLogicControlToUse().add(myActiveKey, myActiveProgram, tlLogic)) {
     338      108972 :             if (myNetIsLoaded) {
     339       15318 :                 myAdditionalLogics.push_back(tlLogic);
     340       93654 :             } 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        2727 :                 myRailSignals.push_back(tlLogic);
     344             :             } else {
     345       90927 :                 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      480279 : NLJunctionControlBuilder::initJunctionLogic(const std::string& id) {
     356      480279 :     myActiveKey = id;
     357      480279 :     myActiveProgram = "";
     358             :     myActiveLogic.clear();
     359             :     myActiveFoes.clear();
     360             :     myActiveConts.reset();
     361      480279 :     myRequestSize = NO_REQUEST_SIZE; // seems not to be used
     362      480279 :     myRequestItemNumber = 0;
     363      480279 :     myCurrentHasError = false;
     364      480279 : }
     365             : 
     366             : 
     367             : void
     368     1505503 : NLJunctionControlBuilder::addLogicItem(int request,
     369             :                                        const std::string& response,
     370             :                                        const std::string& foes,
     371             :                                        bool cont) {
     372     1505503 :     if (myCurrentHasError) {
     373             :         // had an error
     374             :         return;
     375             :     }
     376     1505503 :     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     1505503 :     if (myRequestSize == NO_REQUEST_SIZE) {
     382             :         // initialize
     383      249434 :         myRequestSize = (int)response.size();
     384             :     }
     385     1505503 :     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     1505503 :     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     1505503 :     myActiveLogic.push_back(std::bitset<SUMO_MAX_CONNECTIONS>(response));
     400             :     // add the read junction-internal foes for the given request index
     401     1505503 :     myActiveFoes.push_back(std::bitset<SUMO_MAX_CONNECTIONS>(foes));
     402             :     // add whether the vehicle may drive a little bit further
     403     1505503 :     myActiveConts.set(request, cont);
     404             :     // increse number of set information
     405     1505503 :     myRequestItemNumber++;
     406             : }
     407             : 
     408             : 
     409             : void
     410      106296 : NLJunctionControlBuilder::initTrafficLightLogic(const std::string& id, const std::string& programID,
     411             :         TrafficLightType type, SUMOTime offset) {
     412      106296 :     myActiveKey = id;
     413      106296 :     myActiveProgram = programID;
     414             :     myActivePhases.clear();
     415             :     myActiveConditions.clear();
     416             :     myActiveAssignments.clear();
     417             :     myActiveFunctions.clear();
     418      106296 :     myAbsDuration = 0;
     419      106296 :     myRequestSize = NO_REQUEST_SIZE;
     420      106296 :     myLogicType = type;
     421      106296 :     myOffset = offset;
     422             :     myAdditionalParameter.clear();
     423      106296 : }
     424             : 
     425             : 
     426             : void
     427      553615 : NLJunctionControlBuilder::addPhase(MSPhaseDefinition* phase) {
     428             :     // build and add the phase definition to the list
     429      553615 :     myActivePhases.push_back(phase);
     430             :     // add phase duration to the absolute duration
     431      553615 :     myAbsDuration += phase->duration;
     432      553615 : }
     433             : 
     434             : 
     435             : bool
     436          96 : NLJunctionControlBuilder::addCondition(const std::string& id, const std::string& value) {
     437             :     if (myActiveConditions.count(id) == 0) {
     438          96 :         myActiveConditions[id] = value;
     439          96 :         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       34665 : NLJunctionControlBuilder::buildTLLogics() {
     473       34665 :     if (!myLogicControl->closeNetworkReading()) {
     474           0 :         throw ProcessError(TL("Traffic lights could not be built."));
     475             :     }
     476       37392 :     for (MSTrafficLightLogic* const logic : myRailSignals) {
     477        2727 :         logic->init(myDetectorBuilder);
     478             :     }
     479       34665 :     MSTLLogicControl* ret = myLogicControl;
     480       34665 :     myNetIsLoaded = true;
     481       34665 :     myLogicControl = nullptr;
     482       34665 :     return ret;
     483             : }
     484             : 
     485             : 
     486             : void
     487       14385 : NLJunctionControlBuilder::addParam(const std::string& key,
     488             :                                    const std::string& value) {
     489       14385 :     myAdditionalParameter[key] = value;
     490       14385 : }
     491             : 
     492             : 
     493             : MSTLLogicControl&
     494     2096892 : NLJunctionControlBuilder::getTLLogicControlToUse() const {
     495     2096892 :     if (myLogicControl != nullptr) {
     496             :         return *myLogicControl;
     497             :     }
     498       63424 :     return myNet.getTLSControl();
     499             : }
     500             : 
     501             : 
     502             : const std::string&
     503     1107233 : NLJunctionControlBuilder::getActiveKey() const {
     504     1107233 :     return myActiveKey;
     505             : }
     506             : 
     507             : 
     508             : const std::string&
     509           1 : NLJunctionControlBuilder::getActiveSubKey() const {
     510           1 :     return myActiveProgram;
     511             : }
     512             : 
     513             : 
     514             : void
     515       33933 : NLJunctionControlBuilder::postLoadInitialization() {
     516      117082 :     for (MSTrafficLightLogic* const logic : myNetworkLogics) {
     517       83176 :         logic->init(myDetectorBuilder);
     518             :     }
     519       49204 :     for (MSTrafficLightLogic* const logic : myAdditionalLogics) {
     520       15303 :         logic->init(myDetectorBuilder);
     521             :     }
     522             :     // delay parameter loading until initialization
     523       34046 :     for (auto item : myLogicParams) {
     524         145 :         item.first->updateParameters(item.second);
     525             :     }
     526       33901 : }
     527             : 
     528             : 
     529             : MSJunction*
     530     2881282 : NLJunctionControlBuilder::retrieve(const std::string id) {
     531     2881282 :     if (myJunctions != nullptr) {
     532             :         return myJunctions->get(id);
     533             :     } else {
     534             :         return nullptr;
     535             :     }
     536             : }
     537             : 
     538             : 
     539             : /****************************************************************************/

Generated by: LCOV version 1.14