LCOV - code coverage report
Current view: top level - src/microsim/traffic_lights - MSRailSignal.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 73.7 % 304 224
Test Date: 2024-11-22 15:46:21 Functions: 62.0 % 50 31

            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    MSRailSignal.cpp
      15              : /// @author  Melanie Weber
      16              : /// @author  Andreas Kendziorra
      17              : /// @author  Jakob Erdmann
      18              : /// @date    Jan 2015
      19              : ///
      20              : // A rail signal logic
      21              : /****************************************************************************/
      22              : #include <config.h>
      23              : 
      24              : #include <cassert>
      25              : #include <utility>
      26              : #include <vector>
      27              : #include <bitset>
      28              : #ifdef HAVE_FOX
      29              : #include <utils/foxtools/MFXWorkerThread.h>
      30              : #endif
      31              : #include <utils/iodevices/OutputDevice_COUT.h>
      32              : #include <microsim/MSEventControl.h>
      33              : #include <microsim/MSNet.h>
      34              : #include <microsim/MSEdge.h>
      35              : #include <microsim/MSEdgeControl.h>
      36              : #include <microsim/MSLane.h>
      37              : #include <microsim/MSLink.h>
      38              : #include <microsim/MSVehicle.h>
      39              : #include <microsim/devices/MSDevice_Routing.h>
      40              : #include <microsim/devices/MSRoutingEngine.h>
      41              : #include <microsim/MSLane.h>
      42              : 
      43              : #include "MSTLLogicControl.h"
      44              : #include "MSTrafficLightLogic.h"
      45              : #include "MSPhaseDefinition.h"
      46              : #include "MSTLLogicControl.h"
      47              : #include "MSRailSignalConstraint.h"
      48              : #include "MSRailSignalControl.h"
      49              : #include "MSDriveWay.h"
      50              : #include "MSRailSignal.h"
      51              : 
      52              : //#define DEBUG_SELECT_DRIVEWAY
      53              : //#define DEBUG_DRIVEWAY_UPDATE
      54              : //#define DEBUG_SIGNALSTATE
      55              : //#define DEBUG_REROUTE
      56              : 
      57              : #define DEBUG_COND DEBUG_HELPER(this)
      58              : #define DEBUG_COND_LINKINFO DEBUG_HELPER(myLink->getTLLogic())
      59              : #define DEBUG_HELPER(obj) ((obj)->isSelected())
      60              : //#define DEBUG_HELPER(obj) ((obj)->getID() == "")
      61              : //#define DEBUG_HELPER(obj) (true)
      62              : 
      63              : // ===========================================================================
      64              : // static value definitions
      65              : // ===========================================================================
      66              : 
      67              : bool MSRailSignal::myStoreVehicles(false);
      68              : MSRailSignal::VehicleVector MSRailSignal::myBlockingVehicles;
      69              : MSRailSignal::VehicleVector MSRailSignal::myRivalVehicles;
      70              : MSRailSignal::VehicleVector MSRailSignal::myPriorityVehicles;
      71              : std::string MSRailSignal::myConstraintInfo;
      72              : int MSRailSignal::myRSIndex(0);
      73              : std::vector<const MSDriveWay*> MSRailSignal::myBlockingDriveWays;
      74              : std::string MSRailSignal::myRequestedDriveWay;
      75              : 
      76              : // ===========================================================================
      77              : // method definitions
      78              : // ===========================================================================
      79         3485 : MSRailSignal::MSRailSignal(MSTLLogicControl& tlcontrol,
      80              :                            const std::string& id, const std::string& programID, SUMOTime delay,
      81         3485 :                            const Parameterised::Map& parameters) :
      82              :     MSTrafficLightLogic(tlcontrol, id, programID, 0, TrafficLightType::RAIL_SIGNAL, delay, parameters),
      83         3485 :     myNumericalID(myRSIndex++),
      84        10455 :     myCurrentPhase(DELTA_T, std::string(SUMO_MAX_CONNECTIONS, 'X')), // dummy phase
      85         3485 :     myPhaseIndex(0),
      86         3485 :     myDriveWayIndex(0) {
      87         3485 :     myDefaultCycleTime = DELTA_T;
      88         3485 :     myMovingBlock = OptionsCont::getOptions().getBool("railsignal-moving-block");
      89         3485 :     MSRailSignalControl::getInstance().addSignal(this);
      90         3485 :     mySwitchCommand->deschedule(this);
      91         3485 : }
      92              : 
      93              : void
      94         3485 : MSRailSignal::init(NLDetectorBuilder&) {
      95         3485 :     if (myLanes.size() == 0) {
      96            9 :         WRITE_WARNINGF(TL("Rail signal at junction '%' does not control any links"), getID());
      97              :     }
      98         8078 :     for (LinkVector& links : myLinks) { //for every link index
      99         4593 :         if (links.size() != 1) {
     100            0 :             throw ProcessError("At railSignal '" + getID() + "' found " + toString(links.size())
     101            0 :                                + " links controlled by index " + toString(links[0]->getTLIndex()));
     102              :         }
     103         9186 :         myLinkInfos.push_back(LinkInfo(links[0]));
     104              :     }
     105         3485 :     updateCurrentPhase();
     106         3485 :     setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep());
     107         3485 :     myNumLinks = (int)myLinks.size();
     108         3485 : }
     109              : 
     110              : 
     111         6970 : MSRailSignal::~MSRailSignal() {
     112         3485 :     removeConstraints();
     113         6970 : }
     114              : 
     115              : 
     116              : // ----------- Handling of controlled links
     117              : void
     118            0 : MSRailSignal::adaptLinkInformationFrom(const MSTrafficLightLogic& logic) {
     119            0 :     MSTrafficLightLogic::adaptLinkInformationFrom(logic);
     120            0 :     updateCurrentPhase();
     121            0 : }
     122              : 
     123              : 
     124              : // ------------ Switching and setting current rows
     125              : SUMOTime
     126            0 : MSRailSignal::trySwitch() {
     127              :     // deschedule regular traffic light event,
     128              :     // updateCurrentPhase is instead called from MSRailSignalControl::updateSignals
     129            0 :     return SUMOTime_MAX;
     130              : }
     131              : 
     132              : 
     133              : 
     134              : bool
     135     16300396 : MSRailSignal::updateCurrentPhase() {
     136              : #ifdef DEBUG_SIGNALSTATE
     137              :     gDebugFlag4 = DEBUG_COND;
     138              : #endif
     139              :     bool keepActive = false;
     140              :     // green by default so vehicles can be inserted at the borders of the network
     141              :     std::string state(myLinks.size(), 'G');
     142     48086028 :     for (LinkInfo& li : myLinkInfos) {
     143     31785632 :         if (li.myLink->getApproaching().size() > 0) {
     144              :             keepActive = true;
     145      8163980 :             Approaching closest = li.myLink->getClosest();
     146      8163980 :             MSDriveWay& driveway = li.getDriveWay(closest.first);
     147              :             //std::cout << SIMTIME << " signal=" << getTLLinkID(li.myLink) << " veh=" << closest.first->getID() << " dw:\n";
     148              :             //driveway.writeBlocks(*OutputDevice_COUT::getDevice());
     149      8163980 :             const bool mustWait = !constraintsAllow(closest.first, true);
     150              :             MSEdgeVector occupied;
     151      8163980 :             if (mustWait || !driveway.reserve(closest, occupied)) {
     152      7881820 :                 state[li.myLink->getTLIndex()] = 'r';
     153      7881820 :                 if (occupied.size() > 0) {
     154       157299 :                     li.reroute(const_cast<SUMOVehicle*>(closest.first), occupied);
     155              :                 }
     156              : #ifdef DEBUG_SIGNALSTATE
     157              :                 if (gDebugFlag4) {
     158              :                     std::cout << SIMTIME << " rsl=" << li.getID() << " veh=" << closest.first->getID() << " notReserved\n";
     159              :                 }
     160              : #endif
     161              :             } else {
     162       282160 :                 state[li.myLink->getTLIndex()] = 'G';
     163              : #ifdef DEBUG_SIGNALSTATE
     164              :                 if (gDebugFlag4) {
     165              :                     std::cout << SIMTIME << " rsl=" << li.getID() << " veh=" << closest.first->getID() << " reserved\n";
     166              :                 }
     167              : #endif
     168              :             }
     169      8163980 :         } else {
     170     23621652 :             if (li.myDriveways.empty()) {
     171              : #ifdef DEBUG_SIGNALSTATE
     172              :                 if (gDebugFlag4) {
     173              :                     std::cout << SIMTIME << " rsl=" << li.getID() << " red for unitialized signal (no driveways yet)\n";
     174              :                 }
     175              : #endif
     176     15437190 :                 state[li.myLink->getTLIndex()] = 'r';
     177              :             } else {
     178      8184462 :                 const MSDriveWay& driveway = *li.myDriveways.front();
     179              :                 MSEdgeVector occupied;
     180      8184462 :                 if (driveway.foeDriveWayOccupied(true, nullptr, occupied) || driveway.foeDriveWayApproached()) {
     181              :                     keepActive = true;
     182              : #ifdef DEBUG_SIGNALSTATE
     183              :                     if (gDebugFlag4) {
     184              :                         std::cout << SIMTIME << " rsl=" << li.getID() << " red for default driveway " << driveway.getID() << "\n";
     185              :                     }
     186              : #endif
     187      8140289 :                     state[li.myLink->getTLIndex()] = 'r';
     188              :                 } else {
     189              : #ifdef DEBUG_SIGNALSTATE
     190              :                     if (gDebugFlag4) {
     191              :                         std::cout << SIMTIME << " rsl=" << li.getID() << " green for default driveway " << driveway.getID() << "\n";
     192              :                     }
     193              : #endif
     194              :                 }
     195      8184462 :             }
     196              :         }
     197              :     }
     198     16300396 :     if (myCurrentPhase.getState() != state) {
     199              :         myCurrentPhase.setState(state);
     200        27128 :         myPhaseIndex = 1 - myPhaseIndex;
     201              :         // set link priorities
     202        27128 :         setTrafficLightSignals(SIMSTEP);
     203              :         // execute switch actions (3D-gui)
     204              :         //const MSTLLogicControl::TLSLogicVariants& vars = myTLControl.get(myTLLogic->getID());
     205              :         //vars.executeOnSwitchActions();
     206              :     }
     207              : #ifdef DEBUG_SIGNALSTATE
     208              :     gDebugFlag4 = false;
     209              : #endif
     210     16300396 :     return keepActive;
     211              : }
     212              : 
     213              : 
     214              : bool
     215      8185358 : MSRailSignal::constraintsAllow(const SUMOVehicle* veh, bool storeWaitRelation) const {
     216      8185358 :     if (myConstraints.size() == 0) {
     217              :         return true;
     218              :     } else {
     219     15499716 :         const std::string tripID = veh->getParameter().getParameter("tripId", veh->getID());
     220              :         auto it = myConstraints.find(tripID);
     221      7749858 :         if (it != myConstraints.end()) {
     222      7763359 :             for (MSRailSignalConstraint* c : it->second) {
     223              :                 // ignore insertion constraints here
     224      7744291 :                 if (!c->isInsertionConstraint() && !c->cleared()) {
     225              : #ifdef DEBUG_SIGNALSTATE
     226              :                     if (gDebugFlag4) {
     227              :                         std::cout << "  constraint '" << c->getDescription() << "' not cleared\n";
     228              :                     }
     229              : #endif
     230      7718434 :                     if (storeWaitRelation && MSGlobals::gTimeToTeleportRSDeadlock > 0
     231      7739029 :                             && veh->getWaitingTime() > veh->getVehicleType().getCarFollowModel().getStartupDelay()) {
     232        11761 :                         const SUMOVehicle* foe = c->getFoe();
     233        11761 :                         if (foe != nullptr) {
     234         9721 :                             MSRailSignalControl::getInstance().addWaitRelation(veh, this, foe, c);
     235              :                         }
     236              :                     }
     237      7725392 :                     if (myStoreVehicles) {
     238            0 :                         myConstraintInfo = c->getDescription();
     239              :                     }
     240              :                     return false;
     241              :                 }
     242              :             }
     243              :         }
     244        24466 :         return true;
     245              :     }
     246              : }
     247              : 
     248              : 
     249              : void
     250          882 : MSRailSignal::addConstraint(const std::string& tripId, MSRailSignalConstraint* constraint) {
     251          882 :     myConstraints[tripId].push_back(constraint);
     252          882 : }
     253              : 
     254              : 
     255              : bool
     256          213 : MSRailSignal::removeConstraint(const std::string& tripId, MSRailSignalConstraint* constraint) {
     257              :     if (myConstraints.count(tripId) != 0) {
     258          213 :         auto& constraints = myConstraints[tripId];
     259          213 :         auto it = std::find(constraints.begin(), constraints.end(), constraint);
     260          213 :         if (it != constraints.end()) {
     261          213 :             delete *it;
     262              :             constraints.erase(it);
     263              :             return true;
     264              :         }
     265              :     }
     266              :     return false;
     267              : }
     268              : 
     269              : void
     270         3507 : MSRailSignal::removeConstraints() {
     271         4244 :     for (auto item : myConstraints) {
     272         1406 :         for (MSRailSignalConstraint* c : item.second) {
     273          669 :             delete c;
     274              :         }
     275              :     }
     276              :     myConstraints.clear();
     277         3507 : }
     278              : 
     279              : 
     280              : // ------------ Static Information Retrieval
     281              : int
     282            0 : MSRailSignal::getPhaseNumber() const {
     283            0 :     return 0;
     284              : }
     285              : 
     286              : const MSTrafficLightLogic::Phases&
     287         3485 : MSRailSignal::getPhases() const {
     288         3485 :     return myPhases;
     289              : }
     290              : 
     291              : const MSPhaseDefinition&
     292            0 : MSRailSignal::getPhase(int) const {
     293            0 :     return myCurrentPhase;
     294              : }
     295              : 
     296              : // ------------ Dynamic Information Retrieval
     297              : int
     298        29614 : MSRailSignal::getCurrentPhaseIndex() const {
     299        29614 :     return myPhaseIndex;
     300              : }
     301              : 
     302              : const MSPhaseDefinition&
     303     16400096 : MSRailSignal::getCurrentPhaseDef() const {
     304     16400096 :     return myCurrentPhase;
     305              : }
     306              : 
     307              : // ------------ Conversion between time and phase
     308              : SUMOTime
     309            0 : MSRailSignal::getPhaseIndexAtTime(SUMOTime) const {
     310            0 :     return 0;
     311              : }
     312              : 
     313              : SUMOTime
     314            0 : MSRailSignal::getOffsetFromIndex(int) const {
     315            0 :     return 0;
     316              : }
     317              : 
     318              : int
     319            0 : MSRailSignal::getIndexFromOffset(SUMOTime) const {
     320            0 :     return 0;
     321              : }
     322              : 
     323              : 
     324              : void
     325         4593 : MSRailSignal::addLink(MSLink* link, MSLane* lane, int pos) {
     326         4593 :     if (pos >= 0) {
     327         4593 :         MSTrafficLightLogic::addLink(link, lane, pos);
     328              :     } // ignore uncontrolled link
     329         4593 : }
     330              : 
     331              : 
     332              : std::string
     333            0 : MSRailSignal::describeLinks(std::vector<MSLink*> links) {
     334              :     std::string result;
     335            0 :     for (MSLink* link : links) {
     336            0 :         result += link->getDescription() + " ";
     337              :     }
     338            0 :     return result;
     339              : }
     340              : 
     341              : 
     342              : void
     343         2775 : MSRailSignal::writeBlocks(OutputDevice& od, bool writeVehicles) const {
     344         5550 :     od.openTag("railSignal");
     345              :     od.writeAttr(SUMO_ATTR_ID, getID());
     346         5973 :     for (const LinkInfo& li : myLinkInfos) {
     347         3198 :         MSLink* link = li.myLink;
     348         6396 :         od.openTag("link");
     349         6396 :         od.writeAttr(SUMO_ATTR_TLLINKINDEX, link->getTLIndex());
     350              :         od.writeAttr(SUMO_ATTR_FROM, link->getLaneBefore()->getID());
     351              :         od.writeAttr(SUMO_ATTR_TO, link->getViaLaneOrLane()->getID());
     352         6100 :         for (const MSDriveWay* dw : li.myDriveways) {
     353         2902 :             if (writeVehicles) {
     354          287 :                 dw->writeBlockVehicles(od);
     355              :             } else {
     356         2615 :                 dw->writeBlocks(od);
     357              :             }
     358              :         }
     359         6396 :         od.closeTag(); // link
     360              :     }
     361         2775 :     od.closeTag(); // railSignal
     362         2775 : }
     363              : 
     364              : 
     365              : void
     366         2345 : MSRailSignal::initDriveWays(const SUMOVehicle* ego, bool update) {
     367         2345 :     const ConstMSEdgeVector& edges = ego->getRoute().getEdges();
     368         2345 :     int endIndex = ego->getParameter().arrivalEdge;
     369         2345 :     if (endIndex < 0) {
     370         2345 :         endIndex = (int)edges.size() - 1;
     371              :     }
     372         2345 :     const int departIndex = ego->getParameter().departEdge;
     373         2345 :     MSDriveWay* prev = const_cast<MSDriveWay*>(MSDriveWay::getDepartureDriveway(ego));
     374        21413 :     for (int i = departIndex; i <= endIndex - 1; i++) {
     375        19068 :         const MSEdge* e = edges[i];
     376        19068 :         if (e->isNormal() && e->getToJunction()->getType() == SumoXMLNodeType::RAIL_SIGNAL) {
     377        10695 :             const MSEdge* e2 = edges[i + 1];
     378        21390 :             for (MSLane* lane : e->getLanes()) {
     379        21970 :                 for (MSLink* link : lane->getLinkCont()) {
     380        11275 :                     if (&link->getLane()->getEdge() == e2) {
     381        10690 :                         MSRailSignal* rs = const_cast<MSRailSignal*>(dynamic_cast<const MSRailSignal*>(link->getTLLogic()));
     382         9272 :                         if (rs != nullptr) {
     383         9272 :                             LinkInfo& li = rs->myLinkInfos[link->getTLIndex()];
     384              :                             // init driveway
     385         9272 :                             MSDriveWay* dw = &li.getDriveWay(ego);
     386         9272 :                             MSRailSignalControl::getInstance().addDrivewayFollower(prev, dw);
     387         9272 :                             MSRailSignalControl::getInstance().addDWDeadlockChecks(rs, prev);
     388         9272 :                             MSRailSignalControl::getInstance().notifyApproach(link);
     389              :                             prev = dw;
     390         9272 :                             if (update && rs->isActive()) {
     391              :                                 // vehicle may have rerouted its intial trip
     392              :                                 // after the states have been set
     393              :                                 // @note: This is a hack because it could lead to invalid tls-output
     394              :                                 // (it's still an improvement over switching based on default driveways)
     395         8030 :                                 rs->updateCurrentPhase();
     396         8030 :                                 rs->setTrafficLightSignals(SIMSTEP);
     397              :                             }
     398              :                         }
     399              :                     }
     400              :                 }
     401              :             }
     402              :         }
     403              :     }
     404         2345 :     MSDriveWay::getDepartureDriveway(ego);
     405         2345 : }
     406              : 
     407              : 
     408              : bool
     409        14310 : MSRailSignal::hasInsertionConstraint(MSLink* link, const MSVehicle* veh, std::string& info, bool& isInsertionOrder) {
     410        14310 :     if (link->getJunction() != nullptr && link->getJunction()->getType() == SumoXMLNodeType::RAIL_SIGNAL) {
     411         4953 :         const MSRailSignal* rs = dynamic_cast<const MSRailSignal*>(link->getTLLogic());
     412         4761 :         if (rs != nullptr && rs->myConstraints.size() > 0) {
     413         6874 :             const std::string tripID = veh->getParameter().getParameter("tripId", veh->getID());
     414              :             auto it = rs->myConstraints.find(tripID);
     415         3437 :             if (it != rs->myConstraints.end()) {
     416         3646 :                 for (MSRailSignalConstraint* c : it->second) {
     417         3367 :                     if (c->isInsertionConstraint() && !c->cleared()) {
     418              : #ifdef DEBUG_SIGNALSTATE
     419              :                         if (DEBUG_HELPER(rs)) {
     420              :                             std::cout << SIMTIME << " rsl=" << rs->getID() << " insertion constraint '" << c->getDescription() << "' for vehicle '" << veh->getID() << "' not cleared\n";
     421              :                         }
     422              : #endif
     423         6216 :                         info = c->getDescription();
     424         3108 :                         isInsertionOrder = c->getType() == MSRailSignalConstraint::ConstraintType::INSERTION_ORDER;
     425         3108 :                         if (MSGlobals::gTimeToTeleportRSDeadlock > 0) {
     426         3108 :                             const SUMOVehicle* foe = c->getFoe();
     427         3108 :                             if (foe != nullptr) {
     428         3108 :                                 MSRailSignalControl::getInstance().addWaitRelation(veh, rs, foe, c);
     429              :                             }
     430              :                         }
     431              :                         return true;
     432              :                     }
     433              :                 }
     434              :             }
     435              :         }
     436              :     }
     437              :     return false;
     438              : }
     439              : 
     440              : // ===========================================================================
     441              : // LinkInfo method definitions
     442              : // ===========================================================================
     443              : 
     444         4593 : MSRailSignal::LinkInfo::LinkInfo(MSLink* link):
     445         4593 :     myLink(link) {
     446         4593 :     reset();
     447         4593 : }
     448              : 
     449        10566 : MSRailSignal::LinkInfo::~LinkInfo() {
     450        13909 :     for (MSDriveWay* dw : myDriveways) {
     451         3343 :         delete dw;
     452              :     }
     453              :     myDriveways.clear();
     454        10566 : }
     455              : 
     456              : void
     457         4598 : MSRailSignal::LinkInfo::reset() {
     458         4598 :     myLastRerouteTime = -1;
     459         4598 :     myLastRerouteVehicle = nullptr;
     460              :     myDriveways.clear();
     461         4598 : }
     462              : 
     463              : 
     464              : std::string
     465            6 : MSRailSignal::LinkInfo::getID() const {
     466           12 :     return myLink->getTLLogic()->getID() + "_" + toString(myLink->getTLIndex());
     467              : }
     468              : 
     469              : 
     470              : MSDriveWay&
     471      8211121 : MSRailSignal::LinkInfo::getDriveWay(const SUMOVehicle* veh) {
     472      8211121 :     MSEdge* first = &myLink->getLane()->getEdge();
     473      8211121 :     MSRouteIterator firstIt = std::find(veh->getCurrentRouteEdge(), veh->getRoute().end(), first);
     474      8211121 :     if (firstIt == veh->getRoute().end()) {
     475              :         // possibly the vehicle has already gone past the first edge (i.e.
     476              :         // because first is short or the step-length is high)
     477              :         // lets look backward along the route
     478              :         // give some slack because the vehicle might have been braking from a higher speed and using ballistic integration
     479           50 :         double lookBack = SPEED2DIST(veh->getSpeed() + 10);
     480           50 :         int routeIndex = veh->getRoutePosition() - 1;
     481           60 :         while (lookBack > 0 && routeIndex > 0) {
     482           50 :             const MSEdge* prevEdge = veh->getRoute().getEdges()[routeIndex];
     483           50 :             if (prevEdge == first) {
     484           40 :                 firstIt = veh->getRoute().begin() + routeIndex;
     485           40 :                 break;
     486              :             }
     487           10 :             lookBack -= prevEdge->getLength();
     488           10 :             routeIndex--;
     489              :         }
     490              :     }
     491      8211121 :     MSRailSignal* rs = const_cast<MSRailSignal*>(dynamic_cast<const MSRailSignal*>(myLink->getTLLogic()));
     492      8211121 :     if (firstIt == veh->getRoute().end()) {
     493           40 :         WRITE_WARNING("Invalid approach information to rail signal '" + MSDriveWay::getClickableTLLinkID(myLink) + "' after rerouting for vehicle '" + veh->getID()
     494              :                       + "' first driveway edge '" + first->getID() + "' time=" + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
     495           10 :         if (myDriveways.empty()) {
     496              :             ConstMSEdgeVector dummyRoute;
     497            0 :             dummyRoute.push_back(&myLink->getLane()->getEdge());
     498            0 :             MSDriveWay* dw = MSDriveWay::buildDriveWay(rs->getNewDrivewayID(), myLink, dummyRoute.begin(), dummyRoute.end());
     499            0 :             myDriveways.push_back(dw);
     500            0 :         }
     501           10 :         return *myDriveways.front();
     502              :     }
     503              :     //std::cout << SIMTIME << " veh=" << veh->getID() << " rsl=" << getID() << " dws=" << myDriveways.size() << "\n";
     504      8211111 :     return getDriveWay(firstIt, veh->getRoute().end(), veh->getID());
     505              : }
     506              : 
     507              : 
     508              : MSDriveWay&
     509      8211111 : MSRailSignal::LinkInfo::getDriveWay(MSRouteIterator firstIt, MSRouteIterator endIt, const std::string& info) {
     510      8244519 :     for (MSDriveWay* dw : myDriveways) {
     511      8241176 :         if (dw->match(firstIt, endIt)) {
     512              :             return *dw;
     513              :         }
     514              : #ifdef DEBUG_SELECT_DRIVEWAY
     515              :         std::cout << SIMTIME << " rs=" << getID() << " veh=" << info << " other dwSignal=" << dw->foundSignal() << " dwRoute=" << toString(dw->getRoute()) << "\n";
     516              : #else
     517              :         UNUSED_PARAMETER(info);
     518              : #endif
     519              :     }
     520         3343 :     MSRailSignal* rs = const_cast<MSRailSignal*>(dynamic_cast<const MSRailSignal*>(myLink->getTLLogic()));
     521         3343 :     MSDriveWay* dw = MSDriveWay::buildDriveWay(rs->getNewDrivewayID(), myLink, firstIt, endIt);
     522              :     dw->setVehicle(info);
     523              : #ifdef DEBUG_SELECT_DRIVEWAY
     524              :     std::cout << SIMTIME << " rs=" << getID() << " veh=" << info << " new dwSignal=" << dw->foundSignal() << " dwRoute=" << toString(dw->getRoute()) << "\n";
     525              : #endif
     526         3343 :     myDriveways.push_back(dw);
     527         3343 :     return *myDriveways.back();
     528              : }
     529              : 
     530              : 
     531              : void
     532       157299 : MSRailSignal::LinkInfo::reroute(SUMOVehicle* veh, const MSEdgeVector& occupied) {
     533       157299 :     MSDevice_Routing* rDev = static_cast<MSDevice_Routing*>(veh->getDevice(typeid(MSDevice_Routing)));
     534       157299 :     const SUMOTime now = MSNet::getInstance()->getCurrentTimeStep();
     535              :     if (rDev != nullptr
     536       131601 :             && rDev->mayRerouteRailSignal()
     537       157458 :             && (myLastRerouteVehicle != veh
     538              :                 // reroute each vehicle only once if no periodic routing is allowed,
     539              :                 // otherwise with the specified period
     540          153 :                 || (rDev->getPeriod() > 0 && myLastRerouteTime + rDev->getPeriod() <= now))) {
     541            6 :         myLastRerouteVehicle = veh;
     542            6 :         myLastRerouteTime = now;
     543              : 
     544              : #ifdef DEBUG_REROUTE
     545              :         ConstMSEdgeVector oldRoute = veh->getRoute().getEdges();
     546              :         if (DEBUG_COND_LINKINFO) {
     547              :             std::cout << SIMTIME << " reroute veh=" << veh->getID() << " rs=" << getID() << " occupied=" << toString(occupied) << "\n";
     548              :         }
     549              : #endif
     550           18 :         MSRoutingEngine::reroute(*veh, now, "railSignal:" + getID(), false, true, occupied);
     551              : #ifdef DEBUG_REROUTE
     552              :         // attention this works only if we are not parallel!
     553              :         if (DEBUG_COND_LINKINFO) {
     554              :             if (veh->getRoute().getEdges() != oldRoute) {
     555              :                 std::cout << "    rerouting successful\n";
     556              :             }
     557              :         }
     558              : #endif
     559              :     }
     560       157299 : }
     561              : 
     562              : 
     563              : void
     564        18352 : MSRailSignal::storeTraCIVehicles(int linkIndex) {
     565              :     myBlockingVehicles.clear();
     566              :     myRivalVehicles.clear();
     567              :     myPriorityVehicles.clear();
     568              :     myConstraintInfo = "";
     569              :     myBlockingDriveWays.clear();
     570              :     myRequestedDriveWay = "";
     571        18352 :     myStoreVehicles = true;
     572        18352 :     LinkInfo& li = myLinkInfos[linkIndex];
     573        18352 :     if (li.myLink->getApproaching().size() > 0) {
     574         1825 :         Approaching closest = li.myLink->getClosest();
     575         1825 :         MSDriveWay& driveway = li.getDriveWay(closest.first);
     576              :         MSEdgeVector occupied;
     577              :         myRequestedDriveWay = driveway.getID();
     578              :         // call for side effects
     579         1825 :         driveway.reserve(closest, occupied);
     580         1825 :         constraintsAllow(closest.first);
     581        18352 :     } else if (li.myDriveways.size() > 0) {
     582        16035 :         li.myDriveways.front()->conflictLaneOccupied();
     583        16035 :         li.myDriveways.front()->foeDriveWayApproached();
     584              :     }
     585        18352 :     myStoreVehicles = false;
     586        18352 : }
     587              : 
     588              : MSRailSignal::VehicleVector
     589         6124 : MSRailSignal::getBlockingVehicles(int linkIndex) {
     590         6124 :     storeTraCIVehicles(linkIndex);
     591         6124 :     return myBlockingVehicles;
     592              : }
     593              : 
     594              : MSRailSignal::VehicleVector
     595         6114 : MSRailSignal::getRivalVehicles(int linkIndex) {
     596         6114 :     storeTraCIVehicles(linkIndex);
     597         6114 :     return myRivalVehicles;
     598              : }
     599              : 
     600              : MSRailSignal::VehicleVector
     601         6114 : MSRailSignal::getPriorityVehicles(int linkIndex) {
     602         6114 :     storeTraCIVehicles(linkIndex);
     603         6114 :     return myPriorityVehicles;
     604              : }
     605              : 
     606              : std::string
     607            0 : MSRailSignal::getConstraintInfo(int linkIndex) {
     608            0 :     storeTraCIVehicles(linkIndex);
     609            0 :     return myConstraintInfo;
     610              : }
     611              : 
     612              : 
     613              : std::string
     614            0 : MSRailSignal::getRequestedDriveWay(int linkIndex) {
     615            0 :     storeTraCIVehicles(linkIndex);
     616            0 :     return myRequestedDriveWay;
     617              : }
     618              : 
     619              : 
     620              : std::vector<const MSDriveWay*>
     621            0 : MSRailSignal::getBlockingDriveWays(int linkIndex) {
     622            0 :     storeTraCIVehicles(linkIndex);
     623            0 :     return myBlockingDriveWays;
     624              : }
     625              : 
     626              : const MSDriveWay&
     627            0 : MSRailSignal::retrieveDriveWay(int numericalID) const {
     628            0 :     for (const LinkInfo& li : myLinkInfos) {
     629            0 :         for (const MSDriveWay* dw : li.myDriveways) {
     630            0 :             if (dw->getNumericalID() == numericalID) {
     631            0 :                 return *dw;
     632              :             }
     633              :         }
     634              :     }
     635            0 :     throw ProcessError("Invalid driveway id " + toString(numericalID) + " at railSignal '" + getID() + "'");
     636              : }
     637              : 
     638              : const MSDriveWay&
     639        36044 : MSRailSignal::retrieveDriveWayForVeh(int tlIndex, const SUMOVehicle* veh) {
     640        36044 :     return myLinkInfos[tlIndex].getDriveWay(veh);
     641              : }
     642              : 
     643              : const MSDriveWay&
     644            0 : MSRailSignal::retrieveDriveWayForRoute(int tlIndex, MSRouteIterator first, MSRouteIterator end) {
     645            0 :     return myLinkInfos[tlIndex].getDriveWay(first, end);
     646              : }
     647              : 
     648              : 
     649              : const std::vector<MSDriveWay*>
     650         8837 : MSRailSignal::retrieveDriveWays(int tlIndex) const {
     651         8837 :     return myLinkInfos[tlIndex].myDriveways;
     652              : }
     653              : 
     654              : 
     655              : std::string
     656            0 : MSRailSignal::getBlockingVehicleIDs() const {
     657              :     MSRailSignal* rs = const_cast<MSRailSignal*>(this);
     658            0 :     if (myLinkInfos.size() == 1) {
     659            0 :         return toString(rs->getBlockingVehicles(0));
     660              :     } else {
     661              :         std::string result;
     662            0 :         for (int i = 0; i < (int)myLinkInfos.size(); i++) {
     663            0 :             result += toString(i) + ": " + toString(rs->getBlockingVehicles(i)) + ";";
     664              :         }
     665            0 :         return result;
     666              :     }
     667              : }
     668              : std::string
     669            0 : MSRailSignal::getRivalVehicleIDs() const {
     670              :     MSRailSignal* rs = const_cast<MSRailSignal*>(this);
     671            0 :     if (myLinkInfos.size() == 1) {
     672            0 :         return toString(rs->getRivalVehicles(0));
     673              :     } else {
     674              :         std::string result;
     675            0 :         for (int i = 0; i < (int)myLinkInfos.size(); i++) {
     676            0 :             result += toString(i) + ": " + toString(rs->getRivalVehicles(i)) + ";";
     677              :         }
     678            0 :         return result;
     679              :     }
     680              : }
     681              : std::string
     682            0 : MSRailSignal::getPriorityVehicleIDs() const {
     683              :     MSRailSignal* rs = const_cast<MSRailSignal*>(this);
     684            0 :     if (myLinkInfos.size() == 1) {
     685            0 :         return toString(rs->getPriorityVehicles(0));
     686              :     } else {
     687              :         std::string result;
     688            0 :         for (int i = 0; i < (int)myLinkInfos.size(); i++) {
     689            0 :             result += toString(i) + ": " + toString(rs->getPriorityVehicles(i)) + ";";
     690              :         }
     691            0 :         return result;
     692              :     }
     693              : }
     694              : std::string
     695            0 : MSRailSignal::getConstraintInfo() const {
     696              :     MSRailSignal* rs = const_cast<MSRailSignal*>(this);
     697            0 :     if (myLinkInfos.size() == 1) {
     698            0 :         return rs->getConstraintInfo(0);
     699              :     } else {
     700              :         std::string result;
     701            0 :         for (int i = 0; i < (int)myLinkInfos.size(); i++) {
     702            0 :             result += toString(i) + ": " + rs->getConstraintInfo(i);
     703              :         }
     704            0 :         return result;
     705              :     }
     706              : }
     707              : std::string
     708            0 : MSRailSignal::getRequestedDriveWay() const {
     709              :     MSRailSignal* rs = const_cast<MSRailSignal*>(this);
     710            0 :     if (myLinkInfos.size() == 1) {
     711            0 :         return toString(rs->getRequestedDriveWay(0));
     712              :     } else {
     713              :         std::string result;
     714            0 :         for (int i = 0; i < (int)myLinkInfos.size(); i++) {
     715            0 :             result += toString(i) + ": " + toString(rs->getRequestedDriveWay(i)) + ";";
     716              :         }
     717            0 :         return result;
     718              :     }
     719              : }
     720              : std::string
     721            0 : MSRailSignal::getBlockingDriveWayIDs() const {
     722              :     MSRailSignal* rs = const_cast<MSRailSignal*>(this);
     723            0 :     if (myLinkInfos.size() == 1) {
     724            0 :         return toString(rs->getBlockingDriveWays(0));
     725              :     } else {
     726              :         std::string result;
     727            0 :         for (int i = 0; i < (int)myLinkInfos.size(); i++) {
     728            0 :             result += toString(i) + ": " + toString(rs->getBlockingDriveWays(i)) + ";";
     729              :         }
     730            0 :         return result;
     731              :     }
     732              : }
     733              : 
     734              : void
     735            5 : MSRailSignal::setParameter(const std::string& key, const std::string& value) {
     736              :     // some pre-defined parameters can be updated at runtime
     737            5 :     if (key == "moving-block") {
     738            5 :         bool movingBlock = StringUtils::toBool(value);
     739            5 :         if (movingBlock != myMovingBlock) {
     740              :             // recompute driveways
     741            5 :             myMovingBlock = movingBlock;
     742           10 :             for (LinkInfo& li : myLinkInfos) {
     743            5 :                 li.reset();
     744              :             }
     745            5 :             updateCurrentPhase();
     746            5 :             setTrafficLightSignals(MSNet::getInstance()->getCurrentTimeStep());
     747              :         }
     748              :     }
     749            5 :     Parameterised::setParameter(key, value);
     750            5 : }
     751              : 
     752              : 
     753              : std::string
     754         3343 : MSRailSignal::getNewDrivewayID() {
     755         6686 :     return getID() + "." + toString(myDriveWayIndex++);
     756              : }
     757              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1