LCOV - code coverage report
Current view: top level - src/microsim/traffic_lights - MSTrafficLightLogic.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 92.5 % 252 233
Test Date: 2024-11-22 15:46:21 Functions: 79.4 % 34 27

            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    MSTrafficLightLogic.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @date    Sept 2002
      19              : ///
      20              : // The parent class for traffic light logics
      21              : /****************************************************************************/
      22              : #include <config.h>
      23              : 
      24              : #include <cassert>
      25              : #include <string>
      26              : #include <iostream>
      27              : #include <map>
      28              : #include <microsim/MSLink.h>
      29              : #include <microsim/MSLane.h>
      30              : #include <microsim/MSEventControl.h>
      31              : #include <microsim/MSJunctionLogic.h>
      32              : #include <microsim/MSNet.h>
      33              : #include <microsim/MSEdge.h>
      34              : #include <microsim/MSGlobals.h>
      35              : #include <mesosim/MESegment.h>
      36              : #include "MSTLLogicControl.h"
      37              : #include "MSTrafficLightLogic.h"
      38              : 
      39              : 
      40              : // ===========================================================================
      41              : // static value definitions
      42              : // ===========================================================================
      43              : const MSTrafficLightLogic::LaneVector MSTrafficLightLogic::myEmptyLaneVector;
      44              : 
      45              : 
      46              : // ===========================================================================
      47              : // member method definitions
      48              : // ===========================================================================
      49              : /* -------------------------------------------------------------------------
      50              :  * member method definitions
      51              :  * ----------------------------------------------------------------------- */
      52       116926 : MSTrafficLightLogic::SwitchCommand::SwitchCommand(MSTLLogicControl& tlcontrol,
      53       116926 :         MSTrafficLightLogic* tlLogic, SUMOTime nextSwitch) :
      54       116926 :     myTLControl(tlcontrol), myTLLogic(tlLogic),
      55       116926 :     myAssumedNextSwitch(nextSwitch), myAmValid(true) {
      56              :     // higher than default command priority of 0
      57       116926 :     priority = 1;
      58       116926 : }
      59              : 
      60              : 
      61       232454 : MSTrafficLightLogic::SwitchCommand::~SwitchCommand() {}
      62              : 
      63              : 
      64              : 
      65              : SUMOTime
      66      9528619 : MSTrafficLightLogic::SwitchCommand::execute(SUMOTime t) {
      67              :     // check whether this command has been descheduled
      68      9528619 :     if (!myAmValid) {
      69              :         return 0;
      70              :     }
      71      9522379 :     int step1 = myTLLogic->getCurrentPhaseIndex();
      72      9522379 :     SUMOTime next = myTLLogic->trySwitch();
      73      9522694 :     while (next == 0) {
      74              :         // skip phase and switch again
      75          315 :         next = myTLLogic->trySwitch();
      76              :     }
      77      9522379 :     int step2 = myTLLogic->getCurrentPhaseIndex();
      78      9522379 :     if (step1 != step2) {
      79      7861461 :         if (myTLLogic->isActive()) {
      80              :             // execute any action connected to this tls
      81      7205991 :             const MSTLLogicControl::TLSLogicVariants& vars = myTLControl.get(myTLLogic->getID());
      82              :             // set link priorities
      83      7205991 :             myTLLogic->setTrafficLightSignals(t);
      84              :             // execute switch actions
      85      7205991 :             vars.executeOnSwitchActions();
      86              :         }
      87              :     }
      88      9522379 :     myAssumedNextSwitch += next;
      89      9522379 :     return next;
      90              : }
      91              : 
      92              : 
      93              : void
      94         6702 : MSTrafficLightLogic::SwitchCommand::deschedule(MSTrafficLightLogic* tlLogic) {
      95         6702 :     if (tlLogic == myTLLogic) {
      96         6702 :         myAmValid = false;
      97         6702 :         myAssumedNextSwitch = -1;
      98              :     }
      99         6702 : }
     100              : 
     101              : 
     102              : SUMOTime
     103         1003 : MSTrafficLightLogic::SwitchCommand::shiftTime(SUMOTime currentTime, SUMOTime execTime, SUMOTime newTime) {
     104              :     if (myTLLogic->getDefaultCycleTime() == DELTA_T) {
     105              :         // MSRailSignal
     106              :         return newTime;
     107              :     } else {
     108              :         UNUSED_PARAMETER(currentTime);
     109              :         UNUSED_PARAMETER(execTime);
     110              :         // XXX changeStepAndDuration (computed as in NLJunctionControlBuilder::closeTrafficLightLogic
     111              :         return newTime;
     112              :     }
     113              : }
     114              : 
     115              : /* -------------------------------------------------------------------------
     116              :  * member method definitions
     117              :  * ----------------------------------------------------------------------- */
     118       113709 : MSTrafficLightLogic::MSTrafficLightLogic(MSTLLogicControl& tlcontrol, const std::string& id,
     119              :         const std::string& programID, const SUMOTime offset, const TrafficLightType logicType, const SUMOTime delay,
     120       113709 :         const Parameterised::Map& parameters) :
     121              :     Named(id), Parameterised(parameters),
     122       113709 :     myProgramID(programID),
     123       113709 :     myOffset(offset),
     124       113709 :     myLogicType(logicType),
     125       113709 :     myCurrentDurationIncrement(-1),
     126       113709 :     myDefaultCycleTime(0),
     127       113709 :     myAmActive(true) {
     128       113709 :     mySwitchCommand = new SwitchCommand(tlcontrol, this, delay);
     129       113709 :     MSNet::getInstance()->getBeginOfTimestepEvents()->addEvent(mySwitchCommand, delay);
     130       113709 : }
     131              : 
     132              : 
     133              : void
     134       102130 : MSTrafficLightLogic::init(NLDetectorBuilder&) {
     135       102130 :     const Phases& phases = getPhases();
     136       102130 :     if (phases.size() > 0 && (MSGlobals::gUseMesoSim || MSGlobals::gTLSPenalty > 0)) {
     137        17221 :         initMesoTLSPenalties();
     138              :     }
     139       102130 :     if (phases.size() > 1) {
     140              :         bool haveWarnedAboutUnusedStates = false;
     141        85008 :         std::vector<bool> foundGreen(phases.front()->getState().size(), false);
     142       537032 :         for (int i = 0; i < (int)phases.size(); ++i) {
     143              :             // warn about unused states
     144              :             std::vector<int> nextPhases;
     145       452027 :             nextPhases.push_back((i + 1) % phases.size());
     146              :             bool iNextDefault = true;
     147       452027 :             if (phases[i]->nextPhases.size() > 0) {
     148          292 :                 nextPhases = phases[i]->nextPhases;
     149              :                 iNextDefault = false;
     150              :             }
     151       904184 :             for (int iNext : nextPhases) {
     152       452160 :                 if (iNext < 0 || iNext >= (int)phases.size()) {
     153            1 :                     throw ProcessError("Invalid nextPhase " + toString(iNext) + " in tlLogic '" + getID()
     154            3 :                                        + "', program '" + getProgramID() + "' with " + toString(phases.size()) + " phases");
     155              :                 }
     156       452583 :                 const std::string optionalFrom = iNextDefault ? "" : " from phase " + toString(i);
     157       452159 :                 const std::string& state1 = phases[i]->getState();
     158       452159 :                 const std::string& state2 = phases[iNext]->getState();
     159       452159 :                 if (state1.size() != state2.size()) {
     160            1 :                     throw ProcessError("Mismatching phase state length in tlLogic '" + getID()
     161            4 :                                        + "', program '" + getProgramID() + "' in phases " + toString(i) + " and " + toString(iNext));
     162              :                 }
     163       452158 :                 if (!haveWarnedAboutUnusedStates && state1.size() > myLanes.size() + myIgnoredIndices.size()) {
     164          222 :                     WRITE_WARNINGF(TL("Unused states in tlLogic '%', program '%' in phase % after tl-index %"),
     165              :                                    getID(), getProgramID(), i, (int)myLanes.size() - 1);
     166              :                     haveWarnedAboutUnusedStates = true;
     167              :                 }
     168              :                 // detect illegal states
     169              :                 const std::string::size_type illegal = state1.find_first_not_of(SUMOXMLDefinitions::ALLOWED_TLS_LINKSTATES);
     170       452158 :                 if (std::string::npos != illegal) {
     171            1 :                     throw ProcessError("Illegal character '" + toString(state1[illegal]) + "' in tlLogic '" + getID()
     172            3 :                                        + "', program '" + getProgramID() + "' in phase " + toString(i));
     173              :                 }
     174              :                 // warn about transitions from green to red without intermediate yellow
     175              :                 bool haveWarned = false;
     176      5480227 :                 for (int j = 0; j < (int)MIN3(state1.size(), state2.size(), myLanes.size()) && !haveWarned; ++j) {
     177      5028070 :                     if ((LinkState)state2[j] == LINKSTATE_TL_RED
     178      5028070 :                             && ((LinkState)state1[j] == LINKSTATE_TL_GREEN_MAJOR
     179      2683085 :                                 || (LinkState)state1[j] == LINKSTATE_TL_GREEN_MINOR)) {
     180        25820 :                         for (LaneVector::const_iterator it = myLanes[j].begin(); it != myLanes[j].end(); ++it) {
     181        13486 :                             if ((*it)->getPermissions() != SVC_PEDESTRIAN) {
     182         1208 :                                 if (getLogicType() != TrafficLightType::NEMA) {
     183         1217 :                                     WRITE_WARNINGF(TL("Missing yellow phase in tlLogic '%', program '%' for tl-index % when switching% to phase %."),
     184              :                                                    getID(), getProgramID(), j, optionalFrom, iNext);
     185              :                                     // one warning per program is enough
     186              :                                     haveWarned = true;
     187              :                                 }
     188              :                                 break;
     189              :                             }
     190              :                         }
     191              :                     }
     192              :                 }
     193              :                 // warn about links that never get the green light
     194      5496101 :                 for (int j = 0; j < (int)state1.size(); ++j) {
     195      5043944 :                     LinkState ls = (LinkState)state1[j];
     196      5043944 :                     if (ls == LINKSTATE_TL_GREEN_MAJOR || ls == LINKSTATE_TL_GREEN_MINOR || ls == LINKSTATE_TL_OFF_BLINKING || ls == LINKSTATE_TL_OFF_NOSIGNAL || ls == LINKSTATE_STOP) {
     197              :                         foundGreen[j] = true;
     198              :                     }
     199              :                 }
     200              :             }
     201       452027 :         }
     202      1894256 :         for (int j = 0; j < (int)foundGreen.size(); ++j) {
     203       862217 :             if (!foundGreen[j]) {
     204          285 :                 WRITE_WARNINGF(TL("Missing green phase in tlLogic '%', program '%' for tl-index %."), getID(), getProgramID(), j);
     205           94 :                 break;
     206              :             }
     207              :         }
     208              :     }
     209              :     // check incompatible junction logic
     210              :     // this can happen if the network was built with a very different signal
     211              :     // plan from the one currently being used.
     212              :     // Connections that never had a common green phase during network building may
     213              :     // have a symmetric response relation to avoid certain kinds of jam but this
     214              :     // can lead to deadlock if a different program gives minor green to both
     215              :     // connections at the same time
     216              :     // Note: mutual conflict between 'g' and 'G' is expected for traffic_light_right_on_red
     217              : 
     218       102127 :     const bool mustCheck = MSNet::getInstance()->hasInternalLinks();
     219              :     // The checks only runs for definitions from additional file and this is sufficient.
     220              :     // The distinction is implicit because original logics are loaded earlier and at that time hasInternalLinks is always false
     221              :     // Also, when the network has no internal links, mutual conflicts are not built by netconvert
     222              :     //std::cout << "init tlLogic=" << getID() << " prog=" << getProgramID() << " links=" << myLinks.size() << " internal=" << MSNet::getInstance()->hasInternalLinks() << "\n";
     223       102127 :     if (mustCheck && phases.size() > 0) {
     224              :         // see NBNode::tlsConflict
     225              :         std::set<const MSJunction*> controlledJunctions;
     226        33374 :         const int numLinks = (int)myLinks.size();
     227       257823 :         for (int j = 0; j < numLinks; ++j) {
     228       447929 :             for (int k = 0; k < (int)myLinks[j].size(); ++k) {
     229       223480 :                 MSLink* link = myLinks[j][k];
     230              :                 assert(link->getJunction() != nullptr);
     231       223480 :                 controlledJunctions.insert(link->getJunction());
     232              :             }
     233              :         }
     234        33374 :         const std::string minor = "gos";
     235        67302 :         for (const MSJunction* junction : controlledJunctions) {
     236        33928 :             const MSJunctionLogic* logic = junction->getLogic();
     237        33928 :             if (logic != nullptr) {
     238              :                 // find symmetrical response
     239              :                 const int logicSize = logic->getLogicSize();
     240              :                 bool foundProblem = false;
     241              :                 std::vector<int> tlIndex;
     242       258344 :                 for (int u = 0; u < logicSize && !foundProblem; u++) {
     243       224424 :                     const MSLogicJunction::LinkBits& response = logic->getResponseFor(u);
     244      3306080 :                     for (int v = 0; v < logicSize && !foundProblem; v++) {
     245      3081656 :                         if (response.test(v)) {
     246       601582 :                             if (logic->getResponseFor(v).test(u)) {
     247              :                                 // get tls link index for links u and v
     248       133204 :                                 if (tlIndex.size() == 0) {
     249              :                                     // init tlindex for all links  once
     250         4570 :                                     tlIndex.resize(logicSize, -1);
     251        96655 :                                     for (int j = 0; j < numLinks; ++j) {
     252       184291 :                                         for (int k = 0; k < (int)myLinks[j].size(); ++k) {
     253        92206 :                                             MSLink* link = myLinks[j][k];
     254        92206 :                                             if (link->getJunction() == junction) {
     255        91484 :                                                 tlIndex[link->getIndex()] = link->getTLIndex();
     256              :                                             }
     257              :                                         }
     258              :                                     }
     259              :                                 }
     260       133204 :                                 const int tlu = tlIndex[u];
     261       133204 :                                 const int tlv = tlIndex[v];
     262       133204 :                                 if (tlu >= 0 && tlv >= 0) {
     263              :                                     int phaseIndex = 0;
     264      1197779 :                                     for (MSPhaseDefinition* p : phases) {
     265      1064584 :                                         if (minor.find(p->getState()[tlu]) != std::string::npos
     266      1064584 :                                                 && minor.find(p->getState()[tlv]) != std::string::npos) {
     267           27 :                                             WRITE_WARNING(TLF("Program '%' at tlLogic '%' is incompatible with logic at junction '%' (mutual conflict between link indices %,% tl indices %,% phase %).\n"
     268              :                                                               "  To avoid deadlock/collisions, either: rebuild the signal plan with a newer version of netconvert/netedit\n"
     269              :                                                               "  or rebuild the network with option '--tls.ignore-internal-junction-jam' or include the program when building.",
     270              :                                                               getProgramID(), getID(), junction->getID(), u, v, tlu, tlv, phaseIndex));
     271              :                                             // only one warning per program
     272              :                                             foundProblem = true;
     273            9 :                                             break;
     274              :                                         }
     275      1064575 :                                         phaseIndex++;
     276              :                                     }
     277              :                                 }
     278              :                             }
     279              :                         }
     280              :                     }
     281              :                 }
     282        33920 :             }
     283              :         }
     284              :     }
     285       102127 :     myNumLinks = (int)myLinks.size();
     286       102127 : }
     287              : 
     288              : 
     289       226866 : MSTrafficLightLogic::~MSTrafficLightLogic() {
     290              :     // no need to do something about mySwitchCommand here,
     291              :     // it is handled by the event control
     292       226866 : }
     293              : 
     294              : 
     295              : // ----------- Handling of controlled links
     296              : void
     297       798732 : MSTrafficLightLogic::addLink(MSLink* link, MSLane* lane, int pos) {
     298              :     // !!! should be done within the loader (checking necessary)
     299       798732 :     myLinks.reserve(pos + 1);
     300      1598621 :     while ((int)myLinks.size() <= pos) {
     301       799889 :         myLinks.push_back(LinkVector());
     302              :     }
     303       798732 :     myLinks[pos].push_back(link);
     304              :     //
     305       798732 :     myLanes.reserve(pos + 1);
     306      1598621 :     while ((int)myLanes.size() <= pos) {
     307       799889 :         myLanes.push_back(LaneVector());
     308              :     }
     309       798732 :     myLanes[pos].push_back(lane);
     310       798732 :     link->setTLState((LinkState) getCurrentPhaseDef().getState()[pos], MSNet::getInstance()->getCurrentTimeStep());
     311       798732 : }
     312              : 
     313              : 
     314              : void
     315        14323 : MSTrafficLightLogic::adaptLinkInformationFrom(const MSTrafficLightLogic& logic) {
     316        14323 :     myLinks = logic.myLinks;
     317        14323 :     myLanes = logic.myLanes;
     318              :     myIgnoredIndices = logic.myIgnoredIndices;
     319        14323 : }
     320              : 
     321              : 
     322              : std::map<MSLink*, LinkState>
     323        98660 : MSTrafficLightLogic::collectLinkStates() const {
     324              :     std::map<MSLink*, LinkState> ret;
     325       890905 :     for (LinkVectorVector::const_iterator i1 = myLinks.begin(); i1 != myLinks.end(); ++i1) {
     326              :         const LinkVector& l = (*i1);
     327      1583333 :         for (LinkVector::const_iterator i2 = l.begin(); i2 != l.end(); ++i2) {
     328       791088 :             ret[*i2] = (*i2)->getState();
     329              :         }
     330              :     }
     331        98660 :     return ret;
     332              : }
     333              : 
     334              : 
     335              : bool
     336     23650084 : MSTrafficLightLogic::setTrafficLightSignals(SUMOTime t) const {
     337              :     // get the current traffic light signal combination
     338     23650084 :     const std::string& state = getCurrentPhaseDef().getState();
     339              :     // go through the links
     340    136202142 :     for (int i = 0; i < (int)myLinks.size(); i++) {
     341    112552058 :         const LinkVector& currGroup = myLinks[i];
     342    112552058 :         LinkState ls = (LinkState) state[i];
     343    225094739 :         for (LinkVector::const_iterator j = currGroup.begin(); j != currGroup.end(); j++) {
     344    112542681 :             (*j)->setTLState(ls, t);
     345              :         }
     346              :     }
     347     23650084 :     return true;
     348              : }
     349              : 
     350              : 
     351              : void
     352            0 : MSTrafficLightLogic::resetLinkStates(const std::map<MSLink*, LinkState>& vals) const {
     353            0 :     for (LinkVectorVector::const_iterator i1 = myLinks.begin(); i1 != myLinks.end(); ++i1) {
     354              :         const LinkVector& l = (*i1);
     355            0 :         for (LinkVector::const_iterator i2 = l.begin(); i2 != l.end(); ++i2) {
     356              :             assert(vals.find(*i2) != vals.end());
     357            0 :             (*i2)->setTLState(vals.find(*i2)->second, MSNet::getInstance()->getCurrentTimeStep());
     358              :         }
     359              :     }
     360            0 : }
     361              : 
     362              : 
     363              : // ----------- Static Information Retrieval
     364              : int
     365            0 : MSTrafficLightLogic::getLinkIndex(const MSLink* const link) const {
     366              :     int index = 0;
     367            0 :     for (LinkVectorVector::const_iterator i1 = myLinks.begin(); i1 != myLinks.end(); ++i1, ++index) {
     368              :         const LinkVector& l = (*i1);
     369            0 :         for (LinkVector::const_iterator i2 = l.begin(); i2 != l.end(); ++i2) {
     370            0 :             if ((*i2) == link) {
     371              :                 return index;
     372              :             }
     373              :         }
     374              :     }
     375              :     return -1;
     376              : }
     377              : 
     378              : 
     379              : 
     380              : // ----------- Dynamic Information Retrieval
     381              : SUMOTime
     382       111496 : MSTrafficLightLogic::getNextSwitchTime() const {
     383       111496 :     return mySwitchCommand != nullptr ? mySwitchCommand->getNextSwitchTime() : -1;
     384              : }
     385              : 
     386              : 
     387              : SUMOTime
     388         2584 : MSTrafficLightLogic::getSpentDuration(SUMOTime simStep) const {
     389         2584 :     if (simStep == -1) {
     390         2260 :         simStep = SIMSTEP;
     391              :     }
     392         2584 :     return simStep - getCurrentPhaseDef().myLastSwitch;
     393              : }
     394              : 
     395              : 
     396              : // ----------- Changing phases and phase durations
     397              : void
     398            0 : MSTrafficLightLogic::addOverridingDuration(SUMOTime duration) {
     399            0 :     myOverridingTimes.push_back(duration);
     400            0 : }
     401              : 
     402              : 
     403              : void
     404            0 : MSTrafficLightLogic::setCurrentDurationIncrement(SUMOTime delay) {
     405            0 :     myCurrentDurationIncrement = delay;
     406            0 : }
     407              : 
     408              : 
     409        17225 : void MSTrafficLightLogic::initMesoTLSPenalties() {
     410              :     // set mesoscopic time penalties
     411        17225 :     const Phases& phases = getPhases();
     412        17225 :     const int numLinks = (int)myLinks.size();
     413              :     // warning already given if not all states are used
     414              :     assert(numLinks <= (int)phases.front()->getState().size());
     415              :     SUMOTime duration = 0;
     416        17225 :     std::vector<double> firstRedDuration(numLinks, 0);
     417        17225 :     std::vector<double> redDuration(numLinks, 0);
     418        17225 :     std::vector<double> totalRedDuration(numLinks, 0);
     419        17225 :     std::vector<double> penalty(numLinks, 0);
     420       107899 :     for (int i = 0; i < (int)phases.size(); ++i) {
     421        90674 :         const std::string& state = phases[i]->getState();
     422        90674 :         duration += phases[i]->duration;
     423              :         // warn about transitions from green to red without intermediate yellow
     424      1101956 :         for (int j = 0; j < numLinks; ++j) {
     425      1011282 :             double& red = redDuration[j];
     426      1011282 :             if ((LinkState)state[j] == LINKSTATE_TL_RED
     427      1011282 :                     || (LinkState)state[j] == LINKSTATE_TL_REDYELLOW) {
     428       523264 :                 red += STEPS2TIME(phases[i]->duration);
     429       523264 :                 totalRedDuration[j] += STEPS2TIME(phases[i]->duration);
     430       488018 :             } else if (red > 0) {
     431        62623 :                 if (firstRedDuration[j] == 0) {
     432              :                     // store for handling wrap-around
     433        62583 :                     firstRedDuration[j] = red;
     434              :                 } else {
     435              :                     // vehicle may arive in any second or the red duration
     436              :                     // compute the sum over [0,red]
     437           40 :                     penalty[j] += 0.5 * (red * red + red);
     438              :                 }
     439        62623 :                 red = 0;
     440              :             }
     441              :         }
     442              :     }
     443              :     // final phase and wrap-around to first phase
     444       197826 :     for (int j = 0; j < numLinks; ++j) {
     445       180601 :         double red = redDuration[j] + firstRedDuration[j];
     446       180601 :         if (red) {
     447       130909 :             penalty[j] += 0.5 * (red * red + red);
     448              :         }
     449              :     }
     450        17225 :     double tlsPenalty = MSGlobals::gTLSPenalty;
     451        17225 :     const double durationSeconds = STEPS2TIME(duration);
     452              :     std::set<const MSJunction*> controlledJunctions;
     453       197826 :     for (int j = 0; j < numLinks; ++j) {
     454       361158 :         for (int k = 0; k < (int)myLinks[j].size(); ++k) {
     455       180557 :             MSLink* link = myLinks[j][k];
     456              :             MSEdge& edge = link->getLaneBefore()->getEdge();
     457       180557 :             if (MSGlobals::gUseMesoSim) {
     458       180397 :                 const MESegment::MesoEdgeType& edgeType = MSNet::getInstance()->getMesoType(edge.getEdgeType());
     459       180397 :                 tlsPenalty = edgeType.tlsPenalty;
     460       180397 :                 double greenFraction = (durationSeconds - totalRedDuration[j]) / durationSeconds;
     461       180397 :                 if (edgeType.tlsFlowPenalty == 0) {
     462              :                     greenFraction = 1;
     463              :                 } else {
     464          120 :                     greenFraction = MAX2(MIN2(greenFraction / edgeType.tlsFlowPenalty, 1.0), 0.01);
     465              :                 }
     466              :                 if (greenFraction == 0.01) {
     467           48 :                     WRITE_WARNINGF(TL("Green fraction is only 1% for link % in tlLogic '%', program '%'."), "%", j, getID(), getProgramID());
     468              :                 }
     469              :                 link->setGreenFraction(greenFraction);
     470              :             }
     471       180557 :             link->setMesoTLSPenalty(TIME2STEPS(tlsPenalty * penalty[j] / durationSeconds));
     472       180557 :             controlledJunctions.insert(link->getLane()->getEdge().getFromJunction()); // MSLink::myJunction is not yet initialized
     473              :             //std::cout << " tls=" << getID() << " i=" << j << " link=" << link->getDescription() << " p=" << penalty[j] << " fr=" << firstRedDuration[j] << " r=" << redDuration[j] << " tr=" << totalRedDuration[j] << " durSecs=" << durationSeconds << " tlsPen=" << STEPS2TIME(link->getMesoTLSPenalty()) << " gF=" << myLinks[j][k]->getGreenFraction() << "\n";
     474              :         }
     475              :     }
     476              :     // initialize empty-net travel times
     477              :     // XXX refactor after merging sharps (links know their incoming edge)
     478        34474 :     for (std::set<const MSJunction*>::iterator it = controlledJunctions.begin(); it != controlledJunctions.end(); ++it) {
     479        17249 :         const ConstMSEdgeVector incoming = (*it)->getIncoming();
     480        97343 :         for (ConstMSEdgeVector::const_iterator it_e = incoming.begin(); it_e != incoming.end(); ++it_e) {
     481        80094 :             const_cast<MSEdge*>(*it_e)->recalcCache();
     482              :         }
     483        17249 :     }
     484              : 
     485        17225 : }
     486              : 
     487              : 
     488              : void
     489          810 : MSTrafficLightLogic::ignoreLinkIndex(int pos) {
     490              :     myIgnoredIndices.insert(pos);
     491          810 : }
     492              : 
     493              : SUMOTime
     494       160886 : MSTrafficLightLogic::getTimeInCycle() const {
     495       160886 :     return mapTimeInCycle(SIMSTEP);
     496              : }
     497              : 
     498              : 
     499              : SUMOTime
     500            0 : MSTrafficLightLogic::mapTimeInCycle(SUMOTime t) const {
     501            0 :     return (t - myOffset) % myDefaultCycleTime;
     502              : }
     503              : 
     504              : 
     505              : bool
     506            0 : MSTrafficLightLogic::isSelected() const {
     507            0 :     return MSNet::getInstance()->isSelected(this);
     508              : }
     509              : 
     510              : 
     511              : void
     512       113940 : MSTrafficLightLogic::activateProgram() {
     513       113940 :     myAmActive = true;
     514              :     // updated the traffic light logic stored in the link
     515       309017 :     for (const LinkVector& currGroup : myLinks) {
     516       390222 :         for (MSLink* link : currGroup) {
     517       195145 :             link->setTLLogic(this);
     518              :         }
     519              :     }
     520       113940 : }
     521              : 
     522              : 
     523              : void
     524        14643 : MSTrafficLightLogic::deactivateProgram() {
     525        14643 :     myAmActive = false;
     526        14643 : }
     527              : 
     528              : bool
     529        24610 : MSTrafficLightLogic::getsMajorGreen(int linkIndex) const {
     530        24610 :     if (linkIndex >= 0 && linkIndex < getNumLinks()) {
     531        35859 :         for (const MSPhaseDefinition* p : getPhases()) {
     532              :             const std::string& s = p->getState();
     533              :             assert(linkIndex < (int)s.size());
     534        34336 :             if (s[linkIndex] == LINKSTATE_TL_GREEN_MAJOR) {
     535              :                 return true;
     536              :             }
     537              :         }
     538              :     }
     539              :     return false;
     540              : 
     541              : }
     542              : 
     543              : 
     544              : SUMOTime
     545         1828 : MSTrafficLightLogic::getMinDur(int step) const {
     546         1828 :     const MSPhaseDefinition& p = step < 0 ? getCurrentPhaseDef() : getPhase(step);
     547         1828 :     return p.minDuration;
     548              : }
     549              : 
     550              : SUMOTime
     551         2447 : MSTrafficLightLogic::getMaxDur(int step) const {
     552         2447 :     const MSPhaseDefinition& p = step < 0 ? getCurrentPhaseDef() : getPhase(step);
     553         2447 :     return p.maxDuration;
     554              : }
     555              : 
     556              : SUMOTime
     557       221794 : MSTrafficLightLogic::getEarliestEnd(int step) const {
     558       221794 :     const MSPhaseDefinition& p = step < 0 ? getCurrentPhaseDef() : getPhase(step);
     559       221794 :     return p.earliestEnd;
     560              : }
     561              : 
     562              : SUMOTime
     563       304574 : MSTrafficLightLogic::getLatestEnd(int step) const {
     564       304574 :     const MSPhaseDefinition& p = step < 0 ? getCurrentPhaseDef() : getPhase(step);
     565       304574 :     return p.latestEnd;
     566              : }
     567              : 
     568              : 
     569              : void
     570         1426 : MSTrafficLightLogic::loadState(MSTLLogicControl& tlcontrol, SUMOTime t, int step, SUMOTime spentDuration) {
     571         1426 :     const SUMOTime remaining = getPhase(step).duration - spentDuration;
     572         1426 :     changeStepAndDuration(tlcontrol, t, step, remaining);
     573         1426 :     setTrafficLightSignals(t - spentDuration);
     574         1426 : }
     575              : 
     576              : 
     577              : SUMOTime
     578       110096 : MSTrafficLightLogic::computeCycleTime(const Phases& phases) {
     579              :     SUMOTime result = 0;
     580       624820 :     for (const MSPhaseDefinition* p : phases) {
     581       514724 :         result += p->duration;
     582              :     }
     583       110096 :     return result;
     584              : }
     585              : 
     586              : 
     587              : 
     588              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1