LCOV - code coverage report
Current view: top level - src/microsim/traffic_lights - MSTrafficLightLogic.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 228 247 92.3 %
Date: 2024-05-19 15:37:39 Functions: 27 34 79.4 %

          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      114780 : MSTrafficLightLogic::SwitchCommand::SwitchCommand(MSTLLogicControl& tlcontrol,
      53      114780 :         MSTrafficLightLogic* tlLogic, SUMOTime nextSwitch) :
      54      114780 :     myTLControl(tlcontrol), myTLLogic(tlLogic),
      55      114780 :     myAssumedNextSwitch(nextSwitch), myAmValid(true) {
      56             :     // higher than default command priority of 0
      57      114780 :     priority = 1;
      58      114780 : }
      59             : 
      60             : 
      61      228066 : MSTrafficLightLogic::SwitchCommand::~SwitchCommand() {}
      62             : 
      63             : 
      64             : 
      65             : SUMOTime
      66    37080000 : MSTrafficLightLogic::SwitchCommand::execute(SUMOTime t) {
      67             :     // check whether this command has been descheduled
      68    37080000 :     if (!myAmValid) {
      69             :         return 0;
      70             :     }
      71    37075071 :     int step1 = myTLLogic->getCurrentPhaseIndex();
      72    37075071 :     SUMOTime next = myTLLogic->trySwitch();
      73    37075221 :     while (next == 0) {
      74             :         // skip phase and switch again
      75         150 :         next = myTLLogic->trySwitch();
      76             :     }
      77    37075071 :     int step2 = myTLLogic->getCurrentPhaseIndex();
      78    37075071 :     if (step1 != step2) {
      79     8397940 :         if (myTLLogic->isActive()) {
      80             :             // execute any action connected to this tls
      81     7702321 :             const MSTLLogicControl::TLSLogicVariants& vars = myTLControl.get(myTLLogic->getID());
      82             :             // set link priorities
      83     7702321 :             myTLLogic->setTrafficLightSignals(t);
      84             :             // execute switch actions
      85     7702321 :             vars.executeOnSwitchActions();
      86             :         }
      87             :     }
      88    37075071 :     myAssumedNextSwitch += next;
      89    37075071 :     return next;
      90             : }
      91             : 
      92             : 
      93             : void
      94        5509 : MSTrafficLightLogic::SwitchCommand::deschedule(MSTrafficLightLogic* tlLogic) {
      95        5509 :     if (tlLogic == myTLLogic) {
      96        5509 :         myAmValid = false;
      97        5509 :         myAssumedNextSwitch = -1;
      98             :     }
      99        5509 : }
     100             : 
     101             : 
     102             : SUMOTime
     103        1900 : 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      109271 : MSTrafficLightLogic::MSTrafficLightLogic(MSTLLogicControl& tlcontrol, const std::string& id,
     119             :         const std::string& programID, const SUMOTime offset, const TrafficLightType logicType, const SUMOTime delay,
     120      109271 :         const Parameterised::Map& parameters) :
     121             :     Named(id), Parameterised(parameters),
     122      109271 :     myProgramID(programID),
     123      109271 :     myOffset(offset),
     124      109271 :     myLogicType(logicType),
     125      109271 :     myCurrentDurationIncrement(-1),
     126      109271 :     myDefaultCycleTime(0),
     127      218542 :     myAmActive(true) {
     128      109271 :     mySwitchCommand = new SwitchCommand(tlcontrol, this, delay);
     129      109271 :     MSNet::getInstance()->getBeginOfTimestepEvents()->addEvent(mySwitchCommand, delay);
     130      109271 : }
     131             : 
     132             : 
     133             : void
     134       98402 : MSTrafficLightLogic::init(NLDetectorBuilder&) {
     135       98402 :     const Phases& phases = getPhases();
     136       98402 :     if (phases.size() > 0 && (MSGlobals::gUseMesoSim || MSGlobals::gTLSPenalty > 0)) {
     137       16980 :         initMesoTLSPenalties();
     138             :     }
     139       98402 :     if (phases.size() > 1) {
     140             :         bool haveWarnedAboutUnusedStates = false;
     141       98111 :         std::vector<bool> foundGreen(phases.front()->getState().size(), false);
     142      606326 :         for (int i = 0; i < (int)phases.size(); ++i) {
     143             :             // warn about unused states
     144             :             std::vector<int> nextPhases;
     145      508218 :             nextPhases.push_back((i + 1) % phases.size());
     146             :             bool iNextDefault = true;
     147      508218 :             if (phases[i]->nextPhases.size() > 0) {
     148         211 :                 nextPhases = phases[i]->nextPhases;
     149             :                 iNextDefault = false;
     150             :             }
     151     1016540 :             for (int iNext : nextPhases) {
     152      508325 :                 if (iNext < 0 || iNext >= (int)phases.size()) {
     153           2 :                     throw ProcessError("Invalid nextPhase " + toString(iNext) + " in tlLogic '" + getID()
     154           4 :                                        + "', program '" + getProgramID() + "' with " + toString(phases.size()) + " phases");
     155             :                 }
     156      508327 :                 const std::string optionalFrom = iNextDefault ? "" : " from phase " + toString(i);
     157      508324 :                 const std::string& state1 = phases[i]->getState();
     158      508324 :                 const std::string& state2 = phases[iNext]->getState();
     159      508324 :                 if (state1.size() != state2.size()) {
     160           2 :                     throw ProcessError("Mismatching phase state length in tlLogic '" + getID()
     161           4 :                                        + "', program '" + getProgramID() + "' in phases " + toString(i) + " and " + toString(iNext));
     162             :                 }
     163      508323 :                 if (!haveWarnedAboutUnusedStates && state1.size() > myLanes.size() + myIgnoredIndices.size()) {
     164         267 :                     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      508323 :                 if (std::string::npos != illegal) {
     171           2 :                     throw ProcessError("Illegal character '" + toString(state1[illegal]) + "' in tlLogic '" + getID()
     172           4 :                                        + "', program '" + getProgramID() + "' in phase " + toString(i));
     173             :                 }
     174             :                 // warn about transitions from green to red without intermediate yellow
     175             :                 bool haveWarned = false;
     176     6014104 :                 for (int j = 0; j < (int)MIN3(state1.size(), state2.size(), myLanes.size()) && !haveWarned; ++j) {
     177     5505782 :                     if ((LinkState)state2[j] == LINKSTATE_TL_RED
     178     5505782 :                             && ((LinkState)state1[j] == LINKSTATE_TL_GREEN_MAJOR
     179     2847199 :                                 || (LinkState)state1[j] == LINKSTATE_TL_GREEN_MINOR)) {
     180       14077 :                         for (LaneVector::const_iterator it = myLanes[j].begin(); it != myLanes[j].end(); ++it) {
     181        7629 :                             if ((*it)->getPermissions() != SVC_PEDESTRIAN) {
     182        1248 :                                 if (getLogicType() != TrafficLightType::NEMA) {
     183        1262 :                                     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     6030015 :                 for (int j = 0; j < (int)state1.size(); ++j) {
     195     5521693 :                     LinkState ls = (LinkState)state1[j];
     196     5521693 :                     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             :         }
     202     1053806 :         for (int j = 0; j < (int)foundGreen.size(); ++j) {
     203      955792 :             if (!foundGreen[j]) {
     204         296 :                 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       98399 :     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       98399 :     if (mustCheck && phases.size() > 0) {
     224             :         // see NBNode::tlsConflict
     225             :         std::set<const MSJunction*> controlledJunctions;
     226       24276 :         const int numLinks = (int)myLinks.size();
     227      242624 :         for (int j = 0; j < numLinks; ++j) {
     228      435717 :             for (int k = 0; k < (int)myLinks[j].size(); ++k) {
     229      217369 :                 MSLink* link = myLinks[j][k];
     230             :                 assert(link->getJunction() != nullptr);
     231      217369 :                 controlledJunctions.insert(link->getJunction());
     232             :             }
     233             :         }
     234       24276 :         const std::string minor = "gos";
     235       49133 :         for (const MSJunction* junction : controlledJunctions) {
     236       24857 :             const MSJunctionLogic* logic = junction->getLogic();
     237       24857 :             if (logic != nullptr) {
     238             :                 // find symmetrical response
     239             :                 const int logicSize = logic->getLogicSize();
     240             :                 bool foundProblem = false;
     241             :                 std::vector<int> tlIndex;
     242      242872 :                 for (int u = 0; u < logicSize && !foundProblem; u++) {
     243      218022 :                     const MSLogicJunction::LinkBits& response = logic->getResponseFor(u);
     244     3489143 :                     for (int v = 0; v < logicSize && !foundProblem; v++) {
     245     3271121 :                         if (response.test(v)) {
     246      613481 :                             if (logic->getResponseFor(v).test(u)) {
     247             :                                 // get tls link index for links u and v
     248      132784 :                                 if (tlIndex.size() == 0) {
     249             :                                     // init tlindex for all links  once
     250        4519 :                                     tlIndex.resize(logicSize, -1);
     251       96010 :                                     for (int j = 0; j < numLinks; ++j) {
     252      183079 :                                         for (int k = 0; k < (int)myLinks[j].size(); ++k) {
     253       91588 :                                             MSLink* link = myLinks[j][k];
     254       91588 :                                             if (link->getJunction() == junction) {
     255       90567 :                                                 tlIndex[link->getIndex()] = link->getTLIndex();
     256             :                                             }
     257             :                                         }
     258             :                                     }
     259             :                                 }
     260      132784 :                                 const int tlu = tlIndex[u];
     261      132784 :                                 const int tlv = tlIndex[v];
     262      132784 :                                 if (tlu >= 0 && tlv >= 0) {
     263             :                                     int phaseIndex = 0;
     264     1198122 :                                     for (MSPhaseDefinition* p : phases) {
     265     1065345 :                                         if (minor.find(p->getState()[tlu]) != std::string::npos
     266     1065345 :                                                 && minor.find(p->getState()[tlv]) != std::string::npos) {
     267          28 :                                             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           7 :                                             break;
     274             :                                         }
     275     1065338 :                                         phaseIndex++;
     276             :                                     }
     277             :                                 }
     278             :                             }
     279             :                         }
     280             :                     }
     281             :                 }
     282             :             }
     283             :         }
     284             :     }
     285       98399 :     myNumLinks = (int)myLinks.size();
     286       98399 : }
     287             : 
     288             : 
     289      108989 : MSTrafficLightLogic::~MSTrafficLightLogic() {
     290             :     // no need to do something about mySwitchCommand here,
     291             :     // it is handled by the event control
     292      217978 : }
     293             : 
     294             : 
     295             : // ----------- Handling of controlled links
     296             : void
     297      832702 : MSTrafficLightLogic::addLink(MSLink* link, MSLane* lane, int pos) {
     298             :     // !!! should be done within the loader (checking necessary)
     299      832702 :     myLinks.reserve(pos + 1);
     300     1666650 :     while ((int)myLinks.size() <= pos) {
     301      833948 :         myLinks.push_back(LinkVector());
     302             :     }
     303      832702 :     myLinks[pos].push_back(link);
     304             :     //
     305      832702 :     myLanes.reserve(pos + 1);
     306     1666650 :     while ((int)myLanes.size() <= pos) {
     307      833948 :         myLanes.push_back(LaneVector());
     308             :     }
     309      832702 :     myLanes[pos].push_back(lane);
     310      832702 :     link->setTLState((LinkState) getCurrentPhaseDef().getState()[pos], MSNet::getInstance()->getCurrentTimeStep());
     311      832702 : }
     312             : 
     313             : 
     314             : void
     315       15526 : MSTrafficLightLogic::adaptLinkInformationFrom(const MSTrafficLightLogic& logic) {
     316       15526 :     myLinks = logic.myLinks;
     317       15526 :     myLanes = logic.myLanes;
     318             :     myIgnoredIndices = logic.myIgnoredIndices;
     319       15526 : }
     320             : 
     321             : 
     322             : std::map<MSLink*, LinkState>
     323       92970 : MSTrafficLightLogic::collectLinkStates() const {
     324             :     std::map<MSLink*, LinkState> ret;
     325      918988 :     for (LinkVectorVector::const_iterator i1 = myLinks.begin(); i1 != myLinks.end(); ++i1) {
     326             :         const LinkVector& l = (*i1);
     327     1650790 :         for (LinkVector::const_iterator i2 = l.begin(); i2 != l.end(); ++i2) {
     328      824772 :             ret[*i2] = (*i2)->getState();
     329             :         }
     330             :     }
     331       92970 :     return ret;
     332             : }
     333             : 
     334             : 
     335             : bool
     336     7819881 : MSTrafficLightLogic::setTrafficLightSignals(SUMOTime t) const {
     337             :     // get the current traffic light signal combination
     338     7819881 :     const std::string& state = getCurrentPhaseDef().getState();
     339             :     // go through the links
     340    95556909 :     for (int i = 0; i < (int)myLinks.size(); i++) {
     341    87737028 :         const LinkVector& currGroup = myLinks[i];
     342    87737028 :         LinkState ls = (LinkState) state[i];
     343   175460140 :         for (LinkVector::const_iterator j = currGroup.begin(); j != currGroup.end(); j++) {
     344    87723112 :             (*j)->setTLState(ls, t);
     345             :         }
     346             :     }
     347     7819881 :     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      107813 : MSTrafficLightLogic::getNextSwitchTime() const {
     383      107813 :     return mySwitchCommand != nullptr ? mySwitchCommand->getNextSwitchTime() : -1;
     384             : }
     385             : 
     386             : 
     387             : SUMOTime
     388        2305 : MSTrafficLightLogic::getSpentDuration(SUMOTime simStep) const {
     389        2305 :     if (simStep == -1) {
     390        1981 :         simStep = SIMSTEP;
     391             :     }
     392        2305 :     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       16984 : void MSTrafficLightLogic::initMesoTLSPenalties() {
     410             :     // set mesoscopic time penalties
     411       16984 :     const Phases& phases = getPhases();
     412       16984 :     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       16984 :     std::vector<double> firstRedDuration(numLinks, 0);
     417       16984 :     std::vector<double> redDuration(numLinks, 0);
     418       16984 :     std::vector<double> totalRedDuration(numLinks, 0);
     419       16984 :     std::vector<double> penalty(numLinks, 0);
     420      106338 :     for (int i = 0; i < (int)phases.size(); ++i) {
     421       89354 :         const std::string& state = phases[i]->getState();
     422       89354 :         duration += phases[i]->duration;
     423             :         // warn about transitions from green to red without intermediate yellow
     424     1083670 :         for (int j = 0; j < numLinks; ++j) {
     425      994316 :             double& red = redDuration[j];
     426      994316 :             if ((LinkState)state[j] == LINKSTATE_TL_RED
     427      994316 :                     || (LinkState)state[j] == LINKSTATE_TL_REDYELLOW) {
     428      513692 :                 red += STEPS2TIME(phases[i]->duration);
     429      513692 :                 totalRedDuration[j] += STEPS2TIME(phases[i]->duration);
     430      480624 :             } else if (red > 0) {
     431       61575 :                 if (firstRedDuration[j] == 0) {
     432             :                     // store for handling wrap-around
     433       61535 :                     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       61575 :                 red = 0;
     440             :             }
     441             :         }
     442             :     }
     443             :     // final phase and wrap-around to first phase
     444      194803 :     for (int j = 0; j < numLinks; ++j) {
     445      177819 :         double red = redDuration[j] + firstRedDuration[j];
     446      177819 :         if (red) {
     447      128629 :             penalty[j] += 0.5 * (red * red + red);
     448             :         }
     449             :     }
     450       16984 :     double tlsPenalty = MSGlobals::gTLSPenalty;
     451       16984 :     const double durationSeconds = STEPS2TIME(duration);
     452             :     std::set<const MSJunction*> controlledJunctions;
     453      194803 :     for (int j = 0; j < numLinks; ++j) {
     454      355594 :         for (int k = 0; k < (int)myLinks[j].size(); ++k) {
     455      177775 :             MSLink* link = myLinks[j][k];
     456             :             MSEdge& edge = link->getLaneBefore()->getEdge();
     457      177775 :             if (MSGlobals::gUseMesoSim) {
     458      177615 :                 const MESegment::MesoEdgeType& edgeType = MSNet::getInstance()->getMesoType(edge.getEdgeType());
     459      177615 :                 tlsPenalty = edgeType.tlsPenalty;
     460      177615 :                 double greenFraction = (durationSeconds - totalRedDuration[j]) / durationSeconds;
     461      177615 :                 if (edgeType.tlsFlowPenalty == 0) {
     462             :                     greenFraction = 1;
     463             :                 } else {
     464         120 :                     greenFraction = MAX2(MIN2(greenFraction / edgeType.tlsFlowPenalty, 1.0), 0.01);
     465             :                 }
     466      177615 :                 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      177775 :             link->setMesoTLSPenalty(TIME2STEPS(tlsPenalty * penalty[j] / durationSeconds));
     472      177775 :             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       33992 :     for (std::set<const MSJunction*>::iterator it = controlledJunctions.begin(); it != controlledJunctions.end(); ++it) {
     479       17008 :         const ConstMSEdgeVector incoming = (*it)->getIncoming();
     480       95142 :         for (ConstMSEdgeVector::const_iterator it_e = incoming.begin(); it_e != incoming.end(); ++it_e) {
     481       78134 :             const_cast<MSEdge*>(*it_e)->recalcCache();
     482             :         }
     483             :     }
     484             : 
     485       16984 : }
     486             : 
     487             : 
     488             : void
     489         772 : MSTrafficLightLogic::ignoreLinkIndex(int pos) {
     490             :     myIgnoredIndices.insert(pos);
     491         772 : }
     492             : 
     493             : SUMOTime
     494      145620 : MSTrafficLightLogic::getTimeInCycle() const {
     495      145620 :     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      109505 : MSTrafficLightLogic::activateProgram() {
     513      109505 :     myAmActive = true;
     514      109505 : }
     515             : 
     516             : 
     517             : void
     518       15856 : MSTrafficLightLogic::deactivateProgram() {
     519       15856 :     myAmActive = false;
     520       15856 : }
     521             : 
     522             : bool
     523       40709 : MSTrafficLightLogic::getsMajorGreen(int linkIndex) const {
     524       40709 :     if (linkIndex >= 0 && linkIndex < getNumLinks()) {
     525       93231 :         for (const MSPhaseDefinition* p : getPhases()) {
     526             :             const std::string& s = p->getState();
     527             :             assert(linkIndex < (int)s.size());
     528       91456 :             if (s[linkIndex] == LINKSTATE_TL_GREEN_MAJOR) {
     529             :                 return true;
     530             :             }
     531             :         }
     532             :     }
     533             :     return false;
     534             : 
     535             : }
     536             : 
     537             : 
     538             : SUMOTime
     539         849 : MSTrafficLightLogic::getMinDur(int step) const {
     540         849 :     const MSPhaseDefinition& p = step < 0 ? getCurrentPhaseDef() : getPhase(step);
     541         849 :     return p.minDuration;
     542             : }
     543             : 
     544             : SUMOTime
     545        1470 : MSTrafficLightLogic::getMaxDur(int step) const {
     546        1470 :     const MSPhaseDefinition& p = step < 0 ? getCurrentPhaseDef() : getPhase(step);
     547        1470 :     return p.maxDuration;
     548             : }
     549             : 
     550             : SUMOTime
     551      208195 : MSTrafficLightLogic::getEarliestEnd(int step) const {
     552      208195 :     const MSPhaseDefinition& p = step < 0 ? getCurrentPhaseDef() : getPhase(step);
     553      208195 :     return p.earliestEnd;
     554             : }
     555             : 
     556             : SUMOTime
     557      991551 : MSTrafficLightLogic::getLatestEnd(int step) const {
     558      991551 :     const MSPhaseDefinition& p = step < 0 ? getCurrentPhaseDef() : getPhase(step);
     559      991551 :     return p.latestEnd;
     560             : }
     561             : 
     562             : 
     563             : void
     564        2044 : MSTrafficLightLogic::loadState(MSTLLogicControl& tlcontrol, SUMOTime t, int step, SUMOTime spentDuration) {
     565        2044 :     const SUMOTime remaining = getPhase(step).duration - spentDuration;
     566        2044 :     changeStepAndDuration(tlcontrol, t, step, remaining);
     567        2044 :     setTrafficLightSignals(t - spentDuration);
     568        2044 : }
     569             : 
     570             : 
     571             : SUMOTime
     572      106433 : MSTrafficLightLogic::computeCycleTime(const Phases& phases) {
     573             :     SUMOTime result = 0;
     574      660649 :     for (const MSPhaseDefinition* p : phases) {
     575      554216 :         result += p->duration;
     576             :     }
     577      106433 :     return result;
     578             : }
     579             : 
     580             : 
     581             : 
     582             : /****************************************************************************/

Generated by: LCOV version 1.14