SUMO - Simulation of Urban MObility

NBRequest.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00010 // This class computes the logic of a junction
00011 /****************************************************************************/
00012 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00013 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00014 /****************************************************************************/
00015 //
00016 //   This file is part of SUMO.
00017 //   SUMO is free software: you can redistribute it and/or modify
00018 //   it under the terms of the GNU General Public License as published by
00019 //   the Free Software Foundation, either version 3 of the License, or
00020 //   (at your option) any later version.
00021 //
00022 /****************************************************************************/
00023 
00024 
00025 // ===========================================================================
00026 // included modules
00027 // ===========================================================================
00028 #ifdef _MSC_VER
00029 #include <windows_config.h>
00030 #else
00031 #include <config.h>
00032 #endif
00033 
00034 #include <string>
00035 #include <vector>
00036 #include <set>
00037 #include <algorithm>
00038 #include <bitset>
00039 #include <sstream>
00040 #include <map>
00041 #include <cassert>
00042 #include <utils/common/MsgHandler.h>
00043 #include <utils/common/ToString.h>
00044 #include <utils/options/OptionsCont.h>
00045 #include <utils/iodevices/OutputDevice_String.h>
00046 #include "NBEdge.h"
00047 #include "NBContHelper.h"
00048 #include "NBTrafficLightLogic.h"
00049 #include "NBTrafficLightLogicCont.h"
00050 #include "NBNode.h"
00051 #include "NBRequest.h"
00052 
00053 #ifdef CHECK_MEMORY_LEAKS
00054 #include <foreign/nvwa/debug_new.h>
00055 #endif // CHECK_MEMORY_LEAKS
00056 
00057 
00058 // ===========================================================================
00059 // static member variables
00060 // ===========================================================================
00061 size_t NBRequest::myGoodBuilds = 0;
00062 size_t NBRequest::myNotBuild = 0;
00063 
00064 
00065 // ===========================================================================
00066 // method definitions
00067 // ===========================================================================
00068 NBRequest::NBRequest(const NBEdgeCont& ec,
00069                      NBNode* junction,
00070                      const EdgeVector& all,
00071                      const EdgeVector& incoming,
00072                      const EdgeVector& outgoing,
00073                      const NBConnectionProhibits& loadedProhibits)
00074     : myJunction(junction),
00075       myAll(all), myIncoming(incoming), myOutgoing(outgoing) {
00076     size_t variations = myIncoming.size() * myOutgoing.size();
00077     // build maps with information which forbidding connection were
00078     //  computed and what's in there
00079     myForbids.reserve(variations);
00080     myDone.reserve(variations);
00081     for (size_t i = 0; i < variations; i++) {
00082         myForbids.push_back(LinkInfoCont(variations, false));
00083         myDone.push_back(LinkInfoCont(variations, false));
00084     }
00085     // insert loaded prohibits
00086     for (NBConnectionProhibits::const_iterator j = loadedProhibits.begin(); j != loadedProhibits.end(); j++) {
00087         NBConnection prohibited = (*j).first;
00088         bool ok1 = prohibited.check(ec);
00089         if (find(myIncoming.begin(), myIncoming.end(), prohibited.getFrom()) == myIncoming.end()) {
00090             ok1 = false;
00091         }
00092         if (find(myOutgoing.begin(), myOutgoing.end(), prohibited.getTo()) == myOutgoing.end()) {
00093             ok1 = false;
00094         }
00095         int idx1 = 0;
00096         if (ok1) {
00097             idx1 = getIndex(prohibited.getFrom(), prohibited.getTo());
00098             if (idx1 < 0) {
00099                 ok1 = false;
00100             }
00101         }
00102         const NBConnectionVector& prohibiting = (*j).second;
00103         for (NBConnectionVector::const_iterator k = prohibiting.begin(); k != prohibiting.end(); k++) {
00104             NBConnection sprohibiting = *k;
00105             bool ok2 = sprohibiting.check(ec);
00106             if (find(myIncoming.begin(), myIncoming.end(), sprohibiting.getFrom()) == myIncoming.end()) {
00107                 ok2 = false;
00108             }
00109             if (find(myOutgoing.begin(), myOutgoing.end(), sprohibiting.getTo()) == myOutgoing.end()) {
00110                 ok2 = false;
00111             }
00112             if (ok1 && ok2) {
00113                 int idx2 = getIndex(sprohibiting.getFrom(), sprohibiting.getTo());
00114                 if (idx2 < 0) {
00115                     ok2 = false;
00116                 } else {
00117                     myForbids[idx2][idx1] = true;
00118                     myDone[idx2][idx1] = true;
00119                     myDone[idx1][idx2] = true;
00120                     myGoodBuilds++;
00121                 }
00122             } else {
00123                 std::string pfID = prohibited.getFrom() != 0 ? prohibited.getFrom()->getID() : "UNKNOWN";
00124                 std::string ptID = prohibited.getTo() != 0 ? prohibited.getTo()->getID() : "UNKNOWN";
00125                 std::string bfID = sprohibiting.getFrom() != 0 ? sprohibiting.getFrom()->getID() : "UNKNOWN";
00126                 std::string btID = sprohibiting.getTo() != 0 ? sprohibiting.getTo()->getID() : "UNKNOWN";
00127                 WRITE_WARNING("could not prohibit " + pfID + "->" + ptID + " by " + bfID + "->" + btID);
00128                 myNotBuild++;
00129             }
00130         }
00131     }
00132     // ok, check whether someone has prohibited two links vice versa
00133     //  (this happens also in some Vissim-networks, when edges are joined)
00134     size_t no = myIncoming.size() * myOutgoing.size();
00135     for (size_t s1 = 0; s1 < no; s1++) {
00136         for (size_t s2 = s1 + 1; s2 < no; s2++) {
00137             // not set, yet
00138             if (!myDone[s1][s2]) {
00139                 continue;
00140             }
00141             // check whether both prohibit vice versa
00142             if (myForbids[s1][s2] && myForbids[s2][s1]) {
00143                 // mark unset - let our algorithm fix it later
00144                 myDone[s1][s2] = false;
00145                 myDone[s2][s1] = false;
00146             }
00147         }
00148     }
00149 }
00150 
00151 
00152 NBRequest::~NBRequest() {}
00153 
00154 
00155 void
00156 NBRequest::buildBitfieldLogic(bool leftHanded) {
00157     EdgeVector::const_iterator i, j;
00158     for (i = myIncoming.begin(); i != myIncoming.end(); i++) {
00159         for (j = myOutgoing.begin(); j != myOutgoing.end(); j++) {
00160             computeRightOutgoingLinkCrossings(leftHanded, *i, *j);
00161             computeLeftOutgoingLinkCrossings(leftHanded, *i, *j);
00162         }
00163     }
00164     // reset signalised/non-signalised dependencies
00165     resetSignalised();
00166 }
00167 
00168 
00169 void
00170 NBRequest::computeRightOutgoingLinkCrossings(bool leftHanded, NBEdge* from, NBEdge* to) {
00171     EdgeVector::const_iterator pfrom = find(myAll.begin(), myAll.end(), from);
00172     while (*pfrom != to) {
00173         NBContHelper::nextCCW(myAll, pfrom);
00174         if ((*pfrom)->getToNode() == myJunction) {
00175             EdgeVector::const_iterator pto = find(myAll.begin(), myAll.end(), to);
00176             while (*pto != from) {
00177                 if (!((*pto)->getToNode() == myJunction)) {
00178                     setBlocking(leftHanded, from, to, *pfrom, *pto);
00179                 }
00180                 NBContHelper::nextCCW(myAll, pto);
00181             }
00182         }
00183     }
00184 }
00185 
00186 
00187 void
00188 NBRequest::computeLeftOutgoingLinkCrossings(bool leftHanded, NBEdge* from, NBEdge* to) {
00189     EdgeVector::const_iterator pfrom = find(myAll.begin(), myAll.end(), from);
00190     while (*pfrom != to) {
00191         NBContHelper::nextCW(myAll, pfrom);
00192         if ((*pfrom)->getToNode() == myJunction) {
00193             EdgeVector::const_iterator pto = find(myAll.begin(), myAll.end(), to);
00194             while (*pto != from) {
00195                 if (!((*pto)->getToNode() == myJunction)) {
00196                     setBlocking(leftHanded, from, to, *pfrom, *pto);
00197                 }
00198                 NBContHelper::nextCW(myAll, pto);
00199             }
00200         }
00201     }
00202 }
00203 
00204 
00205 void
00206 NBRequest::setBlocking(bool leftHanded,
00207                        NBEdge* from1, NBEdge* to1,
00208                        NBEdge* from2, NBEdge* to2) {
00209     // check whether one of the links has a dead end
00210     if (to1 == 0 || to2 == 0) {
00211         return;
00212     }
00213     // get the indices of both links
00214     int idx1 = getIndex(from1, to1);
00215     int idx2 = getIndex(from2, to2);
00216     if (idx1 < 0 || idx2 < 0) {
00217         return; // !!! error output? did not happend, yet
00218     }
00219     // check whether the link crossing has already been checked
00220     assert((size_t) idx1 < myIncoming.size()*myOutgoing.size());
00221     if (myDone[idx1][idx2]) {
00222         return;
00223     }
00224     // mark the crossings as done
00225     myDone[idx1][idx2] = true;
00226     myDone[idx2][idx1] = true;
00227     // check if one of the links is a turn; this link is always not priorised
00228     //  true for right-before-left and priority
00229     if (from1->isTurningDirectionAt(myJunction, to1)) {
00230         myForbids[idx2][idx1] = true;
00231         return;
00232     }
00233     if (from2->isTurningDirectionAt(myJunction, to2)) {
00234         myForbids[idx1][idx2] = true;
00235         return;
00236     }
00237 
00238     // check the priorities
00239     int from1p = from1->getJunctionPriority(myJunction);
00240     int from2p = from2->getJunctionPriority(myJunction);
00241     // check if one of the connections is higher priorised when incoming into
00242     //  the junction, the connection road will yield
00243     // should be valid for priority junctions only
00244     if (from1p > from2p) {
00245         assert(myJunction->getType() != NODETYPE_RIGHT_BEFORE_LEFT);
00246         myForbids[idx1][idx2] = true;
00247         return;
00248     }
00249     if (from2p > from1p) {
00250         assert(myJunction->getType() != NODETYPE_RIGHT_BEFORE_LEFT);
00251         myForbids[idx2][idx1] = true;
00252         return;
00253     }
00254 
00255     // check whether one of the connections is higher priorised on
00256     //  the outgoing edge when both roads are high priorised
00257     //  the connection with the lower priorised outgoing edge will lead
00258     // should be valid for priority junctions only
00259     if (from1p > 0 && from2p > 0) {
00260         assert(myJunction->getType() != NODETYPE_RIGHT_BEFORE_LEFT);
00261         int to1p = to1->getJunctionPriority(myJunction);
00262         int to2p = to2->getJunctionPriority(myJunction);
00263         if (to1p > to2p) {
00264             myForbids[idx1][idx2] = true;
00265             return;
00266         }
00267         if (to2p > to1p) {
00268             myForbids[idx2][idx1] = true;
00269             return;
00270         }
00271     }
00272 
00273     // compute the yielding due to the right-before-left rule
00274     // get the position of the incoming lanes in the junction-wheel
00275     EdgeVector::const_iterator c1 = find(myAll.begin(), myAll.end(), from1);
00276     NBContHelper::nextCW(myAll, c1);
00277     // go through next edges clockwise...
00278     while (*c1 != from1 && *c1 != from2) {
00279         if (*c1 == to2) {
00280             // if we encounter to2 the second one prohibits the first
00281             if (!leftHanded) {
00282                 myForbids[idx2][idx1] = true;
00283             } else {
00284                 myForbids[idx1][idx2] = true;
00285             }
00286             return;
00287         }
00288         NBContHelper::nextCW(myAll, c1);
00289     }
00290     // get the position of the incoming lanes in the junction-wheel
00291     EdgeVector::const_iterator c2 = find(myAll.begin(), myAll.end(), from2);
00292     NBContHelper::nextCW(myAll, c2);
00293     // go through next edges clockwise...
00294     while (*c2 != from2 && *c2 != from1) {
00295         if (*c2 == to1) {
00296             // if we encounter to1 the second one prohibits the first
00297             if (!leftHanded) {
00298                 myForbids[idx1][idx2] = true;
00299             } else {
00300                 myForbids[idx2][idx1] = true;
00301             }
00302             return;
00303         }
00304         NBContHelper::nextCW(myAll, c2);
00305     }
00306 }
00307 
00308 
00309 size_t
00310 NBRequest::distanceCounterClockwise(NBEdge* from, NBEdge* to) {
00311     EdgeVector::const_iterator p = find(myAll.begin(), myAll.end(), from);
00312     size_t ret = 0;
00313     while (true) {
00314         ret++;
00315         if (p == myAll.begin()) {
00316             p = myAll.end();
00317         }
00318         p--;
00319         if ((*p) == to) {
00320             return ret;
00321         }
00322     }
00323 }
00324 
00325 
00326 void
00327 NBRequest::writeLogic(std::string key, OutputDevice& into) const {
00328     int pos = 0;
00329     EdgeVector::const_iterator i;
00330     for (i = myIncoming.begin(); i != myIncoming.end(); i++) {
00331         unsigned int noLanes = (*i)->getNumLanes();
00332         for (unsigned int k = 0; k < noLanes; k++) {
00333             pos = writeLaneResponse(into, *i, k, pos);
00334         }
00335     }
00336 }
00337 
00338 
00339 void
00340 NBRequest::resetSignalised() {
00341     // go through possible prohibitions
00342     for (EdgeVector::const_iterator i11 = myIncoming.begin(); i11 != myIncoming.end(); i11++) {
00343         unsigned int noLanesEdge1 = (*i11)->getNumLanes();
00344         for (unsigned int j1 = 0; j1 < noLanesEdge1; j1++) {
00345             std::vector<NBEdge::Connection> el1 = (*i11)->getConnectionsFromLane(j1);
00346             for (std::vector<NBEdge::Connection>::iterator i12 = el1.begin(); i12 != el1.end(); ++i12) {
00347                 int idx1 = getIndex((*i11), (*i12).toEdge);
00348                 if (idx1 < 0) {
00349                     continue;
00350                 }
00351                 // go through possibly prohibited
00352                 for (EdgeVector::const_iterator i21 = myIncoming.begin(); i21 != myIncoming.end(); i21++) {
00353                     unsigned int noLanesEdge2 = (*i21)->getNumLanes();
00354                     for (unsigned int j2 = 0; j2 < noLanesEdge2; j2++) {
00355                         std::vector<NBEdge::Connection> el2 = (*i21)->getConnectionsFromLane(j2);
00356                         for (std::vector<NBEdge::Connection>::iterator i22 = el2.begin(); i22 != el2.end(); i22++) {
00357                             int idx2 = getIndex((*i21), (*i22).toEdge);
00358                             if (idx2 < 0) {
00359                                 continue;
00360                             }
00361                             // check
00362                             // same incoming connections do not prohibit each other
00363                             if ((*i11) == (*i21)) {
00364                                 myForbids[idx1][idx2] = false;
00365                                 myForbids[idx2][idx1] = false;
00366                                 continue;
00367                             }
00368                             // check other
00369                             // if both are non-signalised or both are signalised
00370                             if (((*i12).tlID == "" && (*i22).tlID == "")
00371                                     ||
00372                                     ((*i12).tlID != "" && (*i22).tlID != "")) {
00373                                 // do nothing
00374                                 continue;
00375                             }
00376                             // supposing, we don not have to
00377                             //  brake if we are no foes
00378                             if (!foes(*i11, (*i12).toEdge, *i21, (*i22).toEdge)) {
00379                                 continue;
00380                             }
00381                             // otherwise:
00382                             //  the non-signalised must break
00383                             if ((*i12).tlID != "") {
00384                                 myForbids[idx1][idx2] = true;
00385                                 myForbids[idx2][idx1] = false;
00386                             } else {
00387                                 myForbids[idx1][idx2] = false;
00388                                 myForbids[idx2][idx1] = true;
00389                             }
00390                         }
00391                     }
00392                 }
00393             }
00394         }
00395     }
00396 }
00397 
00398 
00399 std::pair<unsigned int, unsigned int>
00400 NBRequest::getSizes() const {
00401     unsigned int noLanes = 0;
00402     unsigned int noLinks = 0;
00403     for (EdgeVector::const_iterator i = myIncoming.begin();
00404             i != myIncoming.end(); i++) {
00405         unsigned int noLanesEdge = (*i)->getNumLanes();
00406         for (unsigned int j = 0; j < noLanesEdge; j++) {
00407             unsigned int numConnections = (unsigned int)(*i)->getConnectionsFromLane(j).size();
00408             noLinks += numConnections;
00409             if (numConnections > 0) {
00410                 noLanes++;
00411             }
00412         }
00413     }
00414     return std::make_pair(noLanes, noLinks);
00415 }
00416 
00417 
00418 bool
00419 NBRequest::foes(const NBEdge* const from1, const NBEdge* const to1,
00420                 const NBEdge* const from2, const NBEdge* const to2) const {
00421     // unconnected edges do not forbid other edges
00422     if (to1 == 0 || to2 == 0) {
00423         return false;
00424     }
00425     // get the indices
00426     int idx1 = getIndex(from1, to1);
00427     int idx2 = getIndex(from2, to2);
00428     if (idx1 < 0 || idx2 < 0) {
00429         return false; // sure? (The connection does not exist within this junction)
00430     }
00431     assert((size_t) idx1 < myIncoming.size()*myOutgoing.size());
00432     assert((size_t) idx2 < myIncoming.size()*myOutgoing.size());
00433     return myForbids[idx1][idx2] || myForbids[idx2][idx1];
00434 }
00435 
00436 
00437 bool
00438 NBRequest::forbids(const NBEdge* const possProhibitorFrom, const NBEdge* const possProhibitorTo,
00439                    const NBEdge* const possProhibitedFrom, const NBEdge* const possProhibitedTo,
00440                    bool regardNonSignalisedLowerPriority) const {
00441     // unconnected edges do not forbid other edges
00442     if (possProhibitorTo == 0 || possProhibitedTo == 0) {
00443         return false;
00444     }
00445     // get the indices
00446     int possProhibitorIdx = getIndex(possProhibitorFrom, possProhibitorTo);
00447     int possProhibitedIdx = getIndex(possProhibitedFrom, possProhibitedTo);
00448     if (possProhibitorIdx < 0 || possProhibitedIdx < 0) {
00449         return false; // sure? (The connection does not exist within this junction)
00450     }
00451     assert((size_t) possProhibitorIdx < myIncoming.size()*myOutgoing.size());
00452     assert((size_t) possProhibitedIdx < myIncoming.size()*myOutgoing.size());
00453     // check simple right-of-way-rules
00454     if (!regardNonSignalisedLowerPriority) {
00455         return myForbids[possProhibitorIdx][possProhibitedIdx];
00456     }
00457     // if its not forbidden, report
00458     if (!myForbids[possProhibitorIdx][possProhibitedIdx]) {
00459         return false;
00460     }
00461     // do not forbid a signalised stream by a non-signalised
00462     if (!possProhibitorFrom->hasSignalisedConnectionTo(possProhibitorTo)) {
00463         return false;
00464     }
00465     return true;
00466 }
00467 
00468 
00469 int
00470 NBRequest::writeLaneResponse(OutputDevice& od, NBEdge* from,
00471                              int fromLane, int pos) const {
00472     std::vector<NBEdge::Connection> connected = from->getConnectionsFromLane(fromLane);
00473     for (std::vector<NBEdge::Connection>::iterator j = connected.begin(); j != connected.end(); j++) {
00474         od.openTag(SUMO_TAG_REQUEST);
00475         od.writeAttr(SUMO_ATTR_INDEX, pos++);
00476         od << " " << toString(SUMO_ATTR_RESPONSE) << "=\"";
00477         writeResponse(od, from, (*j).toEdge, fromLane, (*j).toLane, (*j).mayDefinitelyPass);
00478         od << "\" " << toString(SUMO_ATTR_FOES) << "=\"";
00479         writeAreFoes(od, from, (*j).toEdge, (*j).haveVia);
00480         od << "\"";
00481         if (!OptionsCont::getOptions().getBool("no-internal-links")) {
00482             if ((*j).haveVia) {
00483                 od.writeAttr(SUMO_ATTR_CONT, 1);
00484             } else {
00485                 od.writeAttr(SUMO_ATTR_CONT, 0);
00486             }
00487         }
00488         od.closeTag(true);
00489     }
00490     return pos;
00491 }
00492 
00493 
00494 void
00495 NBRequest::writeResponse(OutputDevice& od, const NBEdge* const from, const NBEdge* const to,
00496                          int fromLane, int toLane, bool mayDefinitelyPass) const {
00497     UNUSED_PARAMETER(toLane);
00498     int idx = 0;
00499     if (to != 0) {
00500         idx = getIndex(from, to);
00501     }
00502     for (EdgeVector::const_reverse_iterator i = myIncoming.rbegin(); i != myIncoming.rend(); i++) {
00503         //const std::vector<NBEdge::Connection> &allConnections = (*i)->getConnections();
00504         unsigned int noLanes = (*i)->getNumLanes();
00505         for (int j = noLanes; j-- > 0;) {
00506             std::vector<NBEdge::Connection> connected = (*i)->getConnectionsFromLane(j);
00507             int size = (int) connected.size();
00508             for (int k = size; k-- > 0;) {
00509                 if (mayDefinitelyPass) {
00510                     od << '0';
00511                 } else if (to == 0) {
00512                     // should wait if no further connection!?
00513                     od << '1';
00514                 } else if ((*i) == from && fromLane == j) {
00515                     // do not prohibit a connection by others from same lane
00516                     od << '0';
00517                 } else {
00518                     assert(k < (int) connected.size());
00519                     assert((size_t) idx < myIncoming.size()*myOutgoing.size());
00520                     assert(connected[k].toEdge == 0 || (size_t) getIndex(*i, connected[k].toEdge) < myIncoming.size()*myOutgoing.size());
00521                     // check whether the connection is prohibited by another one
00522                     if (connected[k].toEdge != 0 && myForbids[getIndex(*i, connected[k].toEdge)][idx]) {
00523                         od << '1';
00524                         continue;
00525                     }
00526                     od << '0';
00527                 }
00528             }
00529         }
00530     }
00531 }
00532 
00533 
00534 void
00535 NBRequest::writeAreFoes(OutputDevice& od, NBEdge* from, NBEdge* to, bool isInnerEnd) const {
00536     // remember the case when the lane is a "dead end" in the meaning that
00537     // vehicles must choose another lane to move over the following
00538     // junction
00539     UNUSED_PARAMETER(isInnerEnd);
00540     int idx = 0;
00541     if (to != 0) {
00542         idx = getIndex(from, to);
00543     }
00544     // !!! move to forbidden
00545     for (EdgeVector::const_reverse_iterator i = myIncoming.rbegin();
00546             i != myIncoming.rend(); i++) {
00547 
00548         unsigned int noLanes = (*i)->getNumLanes();
00549         for (unsigned int j = noLanes; j-- > 0;) {
00550             std::vector<NBEdge::Connection> connected = (*i)->getConnectionsFromLane(j);
00551             int size = (int) connected.size();
00552             for (int k = size; k-- > 0;) {
00553                 if (to == 0) {
00554                     od << '0';
00555                 } else {
00556 //                    if (foes(from, to, (*i), connected[k].edge) && !isInnerEnd) {
00557                     if (foes(from, to, (*i), connected[k].toEdge)) {
00558                         od << '1';
00559                     } else {
00560                         od << '0';
00561                     }
00562                 }
00563             }
00564         }
00565     }
00566 }
00567 
00568 
00569 int
00570 NBRequest::getIndex(const NBEdge* const from, const NBEdge* const to) const {
00571     EdgeVector::const_iterator fp = find(myIncoming.begin(), myIncoming.end(), from);
00572     EdgeVector::const_iterator tp = find(myOutgoing.begin(), myOutgoing.end(), to);
00573     if (fp == myIncoming.end() || tp == myOutgoing.end()) {
00574         return -1;
00575     }
00576     // compute the index
00577     return (int)(distance(myIncoming.begin(), fp) * myOutgoing.size() + distance(myOutgoing.begin(), tp));
00578 }
00579 
00580 
00581 std::ostream&
00582 operator<<(std::ostream& os, const NBRequest& r) {
00583     size_t variations = r.myIncoming.size() * r.myOutgoing.size();
00584     for (size_t i = 0; i < variations; i++) {
00585         os << i << ' ';
00586         for (size_t j = 0; j < variations; j++) {
00587             if (r.myForbids[i][j]) {
00588                 os << '1';
00589             } else {
00590                 os << '0';
00591             }
00592         }
00593         os << std::endl;
00594     }
00595     os << std::endl;
00596     return os;
00597 }
00598 
00599 
00600 bool
00601 NBRequest::mustBrake(const NBEdge* const from, const NBEdge* const to) const {
00602     // vehicles which do not have a following lane must always decelerate to the end
00603     if (to == 0) {
00604         return true;
00605     }
00606     // get the indices
00607     int idx2 = getIndex(from, to);
00608     if (idx2 == -1) {
00609         return false;
00610     }
00611     // go through all (existing) connections;
00612     //  check whether any of these forbids the one to determine
00613     assert((size_t) idx2 < myIncoming.size()*myOutgoing.size());
00614     for (size_t idx1 = 0; idx1 < myIncoming.size()*myOutgoing.size(); idx1++) {
00615         //assert(myDone[idx1][idx2]);
00616         if (myDone[idx1][idx2] && myForbids[idx1][idx2]) {
00617             return true;
00618         }
00619     }
00620     return false;
00621 }
00622 
00623 
00624 bool
00625 NBRequest::mustBrake(const NBEdge* const possProhibitorFrom, const NBEdge* const possProhibitorTo,
00626                      const NBEdge* const possProhibitedFrom, const NBEdge* const possProhibitedTo) const {
00627     // get the indices
00628     int idx1 = getIndex(possProhibitorFrom, possProhibitorTo);
00629     int idx2 = getIndex(possProhibitedFrom, possProhibitedTo);
00630     return (myForbids[idx2][idx1]);
00631 }
00632 
00633 
00634 void
00635 NBRequest::reportWarnings() {
00636     // check if any errors occured on build the link prohibitions
00637     if (myNotBuild != 0) {
00638         WRITE_WARNING(toString(myNotBuild) + " of " + toString(myNotBuild + myGoodBuilds) + " prohibitions were not build.");
00639     }
00640 }
00641 
00642 
00643 
00644 /****************************************************************************/
00645 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines