LCOV - code coverage report
Current view: top level - src/netbuild - NBTrafficLightLogic.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 80 137 58.4 %
Date: 2024-05-06 15:32:35 Functions: 15 27 55.6 %

          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    NBTrafficLightLogic.cpp
      15             : /// @author  Daniel Krajzewicz
      16             : /// @author  Jakob Erdmann
      17             : /// @author  Michael Behrisch
      18             : /// @date    Sept 2002
      19             : ///
      20             : // A SUMO-compliant built logic for a traffic light
      21             : /****************************************************************************/
      22             : #include <config.h>
      23             : 
      24             : #include <vector>
      25             : #include <bitset>
      26             : #include <utility>
      27             : #include <string>
      28             : #include <sstream>
      29             : #include <cassert>
      30             : #include "NBEdge.h"
      31             : #include "NBEdgeCont.h"
      32             : #include "NBTrafficLightLogic.h"
      33             : #include "NBTrafficLightDefinition.h"
      34             : #include <utils/options/OptionsCont.h>
      35             : #include <utils/options/Option.h>
      36             : #include <utils/common/ToString.h>
      37             : #include <utils/common/MsgHandler.h>
      38             : #include <utils/common/StringTokenizer.h>
      39             : #include <utils/iodevices/OutputDevice.h>
      40             : 
      41             : 
      42             : // ===========================================================================
      43             : // static members
      44             : // ===========================================================================
      45             : 
      46             : // ===========================================================================
      47             : // member method definitions
      48             : // ===========================================================================
      49        4418 : NBTrafficLightLogic::NBTrafficLightLogic(const std::string& id,
      50             :         const std::string& subid, int noLinks,
      51        4418 :         SUMOTime offset, TrafficLightType type) :
      52        4418 :     Named(id), myNumLinks(noLinks), mySubID(subid),
      53        4418 :     myOffset(offset),
      54        8836 :     myType(type) {}
      55             : 
      56             : 
      57         974 : NBTrafficLightLogic::NBTrafficLightLogic(const NBTrafficLightLogic* logic) :
      58             :     Named(logic->getID()),
      59         974 :     myNumLinks(logic->myNumLinks),
      60         974 :     mySubID(logic->getProgramID()),
      61         974 :     myOffset(logic->getOffset()),
      62         974 :     myPhases(logic->myPhases.begin(), logic->myPhases.end()),
      63         974 :     myType(logic->getType())
      64             : {
      65         974 :     updateParameters(logic->getParametersMap());
      66         974 : }
      67             : 
      68             : 
      69       16202 : NBTrafficLightLogic::~NBTrafficLightLogic() {}
      70             : 
      71             : 
      72             : void
      73        8559 : NBTrafficLightLogic::addStep(const SUMOTime duration, const std::string& state, const std::vector<int>& next, const std::string& name, const int index) {
      74        8559 :     addStep(duration, state,
      75             :             NBTrafficLightDefinition::UNSPECIFIED_DURATION,
      76             :             NBTrafficLightDefinition::UNSPECIFIED_DURATION,
      77             :             NBTrafficLightDefinition::UNSPECIFIED_DURATION,
      78             :             NBTrafficLightDefinition::UNSPECIFIED_DURATION,
      79             :             NBTrafficLightDefinition::UNSPECIFIED_DURATION,
      80             :             NBTrafficLightDefinition::UNSPECIFIED_DURATION,
      81             :             NBTrafficLightDefinition::UNSPECIFIED_DURATION,
      82             :             name, next, index);
      83        8559 : }
      84             : 
      85             : 
      86             : void
      87       22020 : NBTrafficLightLogic::addStep(const SUMOTime duration, const std::string& state, const SUMOTime minDur, const SUMOTime maxDur, const SUMOTime earliestEnd,
      88             :                              const SUMOTime latestEnd, const SUMOTime vehExt, const SUMOTime yellow, const SUMOTime red,
      89             :                              const std::string& name,
      90             :                              const std::vector<int>& next,
      91             :                              int index) {
      92             :     // check state size
      93       22020 :     if (myNumLinks == 0) {
      94             :         // initialize
      95         911 :         myNumLinks = (int)state.size();
      96       21109 :     } else if ((int)state.size() != myNumLinks) {
      97           0 :         throw ProcessError("When adding phase to tlLogic '" + getID() + "': state length of " + toString(state.size()) +
      98           0 :                            " does not match declared number of links " + toString(myNumLinks));
      99             :     }
     100             :     // check state contents
     101             :     const std::string::size_type illegal = state.find_first_not_of(SUMOXMLDefinitions::ALLOWED_TLS_LINKSTATES);
     102       22020 :     if (std::string::npos != illegal) {
     103           3 :         throw ProcessError(TLF("When adding phase: illegal character '%' in state", toString(state[illegal])));
     104             :     }
     105             :     // interpret index
     106       22019 :     if (index < 0 || index >= (int)myPhases.size()) {
     107             :         // insert at the end
     108       22019 :         index = (int)myPhases.size();
     109             :     }
     110       44038 :     myPhases.insert(myPhases.begin() + index, PhaseDefinition(duration, state, minDur, maxDur, earliestEnd, latestEnd, vehExt, yellow, red, next, name));
     111       22019 : }
     112             : 
     113             : 
     114             : void
     115           0 : NBTrafficLightLogic::deletePhase(int index) {
     116           0 :     if (index >= (int)myPhases.size()) {
     117           0 :         throw InvalidArgument("Index " + toString(index) + " out of range for logic with "
     118           0 :                               + toString(myPhases.size()) + " phases.");
     119             :     }
     120           0 :     myPhases.erase(myPhases.begin() + index);
     121           0 : }
     122             : 
     123             : 
     124             : void
     125           0 : NBTrafficLightLogic::swapPhase(int indexPhaseA, int indexPhaseB) {
     126           0 :     if (indexPhaseA >= (int)myPhases.size()) {
     127           0 :         throw InvalidArgument("Index " + toString(indexPhaseA) + " out of range for logic with "
     128           0 :                               + toString(myPhases.size()) + " phases.");
     129             :     }
     130           0 :     if (indexPhaseB >= (int)myPhases.size()) {
     131           0 :         throw InvalidArgument("Index " + toString(indexPhaseB) + " out of range for logic with "
     132           0 :                               + toString(myPhases.size()) + " phases.");
     133             :     }
     134             :     // declare auxiliar PhaseDefinition and swap
     135           0 :     const auto auxPhase = myPhases.at(indexPhaseA);
     136           0 :     myPhases.at(indexPhaseA) = myPhases.at(indexPhaseB);
     137           0 :     myPhases.at(indexPhaseB) = auxPhase;
     138           0 : }
     139             : 
     140             : 
     141             : void
     142           0 : NBTrafficLightLogic::swapfirstPhase() {
     143           0 :     const auto firstPhase = myPhases.front();
     144           0 :     myPhases.erase(myPhases.begin());
     145           0 :     myPhases.push_back(firstPhase);
     146           0 : }
     147             : 
     148             : 
     149             : void
     150           0 : NBTrafficLightLogic::swaplastPhase() {
     151           0 :     const auto lastPhase = myPhases.back();
     152           0 :     myPhases.pop_back();
     153           0 :     myPhases.insert(myPhases.begin(), lastPhase);
     154           0 : }
     155             : 
     156             : void
     157          11 : NBTrafficLightLogic::setStateLength(int numLinks, LinkState fill) {
     158          11 :     if (myNumLinks > numLinks) {
     159           0 :         for (PhaseDefinition& p : myPhases) {
     160           0 :             p.state = p.state.substr(0, numLinks);
     161             :         }
     162             :     } else {
     163          11 :         std::string add(numLinks - myNumLinks, (char)fill);
     164         107 :         for (PhaseDefinition& p : myPhases) {
     165         192 :             p.state = p.state + add;
     166             :         }
     167             :     }
     168          11 :     myNumLinks = numLinks;
     169          11 : }
     170             : 
     171             : 
     172             : void
     173          29 : NBTrafficLightLogic::deleteStateIndex(int index) {
     174             :     assert(index >= 0);
     175             :     assert(index < myNumLinks);
     176         227 :     for (PhaseDefinition& p : myPhases) {
     177         198 :         p.state.erase(index, 1);
     178             :     }
     179          29 :     myNumLinks--;
     180          29 : }
     181             : 
     182             : 
     183             : void
     184          41 : NBTrafficLightLogic::resetPhases() {
     185          41 :     myNumLinks = 0;
     186             :     myPhases.clear();
     187          41 : }
     188             : 
     189             : 
     190             : SUMOTime
     191       10523 : NBTrafficLightLogic::getDuration() const {
     192             :     SUMOTime duration = 0;
     193       61911 :     for (PhaseDefinitionVector::const_iterator i = myPhases.begin(); i != myPhases.end(); ++i) {
     194       51388 :         duration += (*i).duration;
     195             :     }
     196       10523 :     return duration;
     197             : }
     198             : 
     199             : 
     200             : void
     201        5440 : NBTrafficLightLogic::closeBuilding(bool checkVarDurations) {
     202       27725 :     for (int i = 0; i < (int)myPhases.size() - 1;) {
     203       22285 :         if (myPhases[i].state != myPhases[i + 1].state || myPhases[i].next.size() > 0 || myPhases[i + 1].next.size() > 0 || myPhases[i].name != myPhases[i + 1].name) {
     204             :             ++i;
     205       21301 :             continue;
     206             :         }
     207         984 :         myPhases[i].duration += myPhases[i + 1].duration;
     208         984 :         if (myPhases[i + 1].minDur != NBTrafficLightDefinition::UNSPECIFIED_DURATION) {
     209         188 :             if (myPhases[i].minDur != NBTrafficLightDefinition::UNSPECIFIED_DURATION) {
     210         164 :                 myPhases[i].minDur += myPhases[i + 1].minDur;
     211             :             } else {
     212          24 :                 myPhases[i].minDur = myPhases[i + 1].minDur;
     213             :             }
     214             :         }
     215         984 :         if (myPhases[i + 1].maxDur != NBTrafficLightDefinition::UNSPECIFIED_DURATION) {
     216          14 :             if (myPhases[i].maxDur != NBTrafficLightDefinition::UNSPECIFIED_DURATION) {
     217          14 :                 myPhases[i].maxDur += myPhases[i + 1].maxDur;
     218             :             } else {
     219           0 :                 myPhases[i].maxDur = myPhases[i + 1].maxDur;
     220             :             }
     221             :         }
     222         984 :         myPhases.erase(myPhases.begin() + i + 1);
     223             :     }
     224             :     // check if actuated lights are defined correctly
     225        5440 :     if (checkVarDurations) {
     226        4466 :         if (myType != TrafficLightType::STATIC) {
     227             :             bool found = false;
     228         954 :             for (auto p : myPhases) {
     229         951 :                 if (p.minDur != NBTrafficLightDefinition::UNSPECIFIED_DURATION
     230          18 :                         || p.maxDur != NBTrafficLightDefinition::UNSPECIFIED_DURATION) {
     231             :                     found = true;
     232             :                     break;
     233             :                 }
     234         951 :             }
     235             :             if (!found) {
     236          10 :                 WRITE_WARNINGF(TL("Non-static traffic light '%' does not define variable phase length."), getID());
     237             :             }
     238             :         }
     239             :     }
     240        5440 : }
     241             : 
     242             : 
     243             : void
     244        2839 : NBTrafficLightLogic::setPhaseState(int phaseIndex, int tlIndex, LinkState linkState) {
     245             :     assert(phaseIndex < (int)myPhases.size());
     246        2839 :     std::string& phaseState = myPhases[phaseIndex].state;
     247             :     assert(tlIndex < (int)phaseState.size());
     248        2839 :     phaseState[tlIndex] = (char)linkState;
     249        2839 : }
     250             : 
     251             : 
     252             : void
     253       10083 : NBTrafficLightLogic::setPhaseDuration(int phaseIndex, SUMOTime duration) {
     254             :     assert(phaseIndex < (int)myPhases.size());
     255       10083 :     myPhases[phaseIndex].duration = duration;
     256       10083 : }
     257             : 
     258             : 
     259             : void
     260           4 : NBTrafficLightLogic::setPhaseMinDuration(int phaseIndex, SUMOTime duration) {
     261             :     assert(phaseIndex < (int)myPhases.size());
     262           4 :     myPhases[phaseIndex].minDur = duration;
     263           4 : }
     264             : 
     265             : 
     266             : void
     267          10 : NBTrafficLightLogic::setPhaseMaxDuration(int phaseIndex, SUMOTime duration) {
     268             :     assert(phaseIndex < (int)myPhases.size());
     269          10 :     myPhases[phaseIndex].maxDur = duration;
     270          10 : }
     271             : 
     272             : 
     273             : void
     274           0 : NBTrafficLightLogic::setPhaseEarliestEnd(int phaseIndex, SUMOTime duration) {
     275             :     assert(phaseIndex < (int)myPhases.size());
     276           0 :     myPhases[phaseIndex].earliestEnd = duration;
     277           0 : }
     278             : 
     279             : 
     280             : void
     281           0 : NBTrafficLightLogic::setPhaseLatestEnd(int phaseIndex, SUMOTime duration) {
     282             :     assert(phaseIndex < (int)myPhases.size());
     283           0 :     myPhases[phaseIndex].latestEnd = duration;
     284           0 : }
     285             : 
     286             : 
     287             : void
     288           0 : NBTrafficLightLogic::setPhaseVehExt(int phaseIndex, SUMOTime duration) {
     289             :     assert(phaseIndex < (int)myPhases.size());
     290           0 :     myPhases[phaseIndex].vehExt = duration;
     291           0 : }
     292             : 
     293             : 
     294             : void
     295           0 : NBTrafficLightLogic::setPhaseYellow(int phaseIndex, SUMOTime duration) {
     296             :     assert(phaseIndex < (int)myPhases.size());
     297           0 :     myPhases[phaseIndex].yellow = duration;
     298           0 : }
     299             : 
     300             : 
     301             : void
     302           0 : NBTrafficLightLogic::setPhaseRed(int phaseIndex, SUMOTime duration) {
     303             :     assert(phaseIndex < (int)myPhases.size());
     304           0 :     myPhases[phaseIndex].red = duration;
     305           0 : }
     306             : 
     307             : 
     308             : void
     309           0 : NBTrafficLightLogic::setPhaseNext(int phaseIndex, const std::vector<int>& next) {
     310             :     assert(phaseIndex < (int)myPhases.size());
     311           0 :     myPhases[phaseIndex].next = next;
     312           0 : }
     313             : 
     314             : 
     315             : void
     316           0 : NBTrafficLightLogic::setPhaseName(int phaseIndex, const std::string& name) {
     317             :     assert(phaseIndex < (int)myPhases.size());
     318           0 :     myPhases[phaseIndex].name = name;
     319           0 : }
     320             : 
     321             : 
     322             : void
     323           0 : NBTrafficLightLogic::overrideState(int phaseIndex, const char c) {
     324             :     assert(phaseIndex < (int)myPhases.size());
     325           0 :     for (int i = 0; i < (int)myPhases[phaseIndex].state.size(); i++) {
     326           0 :         myPhases[phaseIndex].state[i] = c;
     327             :     }
     328           0 : }
     329             : 
     330             : /****************************************************************************/

Generated by: LCOV version 1.14