MSRightOfWayJunction.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // junction.
00008 /****************************************************************************/
00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00010 // Copyright 2001-2010 DLR (http://www.dlr.de/) and contributors
00011 /****************************************************************************/
00012 //
00013 //   This program is free software; you can redistribute it and/or modify
00014 //   it under the terms of the GNU General Public License as published by
00015 //   the Free Software Foundation; either version 2 of the License, or
00016 //   (at your option) any later version.
00017 //
00018 /****************************************************************************/
00019 
00020 
00021 // ===========================================================================
00022 // included modules
00023 // ===========================================================================
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029 
00030 #include "MSRightOfWayJunction.h"
00031 #include "MSLane.h"
00032 #include "MSJunctionLogic.h"
00033 #include "MSBitSetLogic.h"
00034 #include "MSGlobals.h"
00035 #include "MSInternalLane.h"
00036 #include <algorithm>
00037 #include <cassert>
00038 #include <cmath>
00039 #include <utils/common/RandHelper.h>
00040 
00041 #ifdef CHECK_MEMORY_LEAKS
00042 #include <foreign/nvwa/debug_new.h>
00043 #endif // CHECK_MEMORY_LEAKS
00044 
00045 
00046 // ===========================================================================
00047 // method definitions
00048 // ===========================================================================
00049 MSRightOfWayJunction::MSRightOfWayJunction(const std::string &id,
00050         const Position2D &position,
00051         const Position2DVector &shape,
00052         std::vector<MSLane*> incoming,
00053 #ifdef HAVE_INTERNAL_LANES
00054         std::vector<MSLane*> internal,
00055 #endif
00056         MSJunctionLogic* logic) throw()
00057         : MSLogicJunction(id, position, shape, incoming
00058 #ifdef HAVE_INTERNAL_LANES
00059                           , internal),
00060 #else
00061                          ),
00062 #endif
00063         myLogic(logic) {}
00064 
00065 
00066 bool
00067 MSRightOfWayJunction::clearRequests() {
00068     myRequest.reset();
00069     myInnerState.reset();
00070     return true;
00071 }
00072 
00073 
00074 MSRightOfWayJunction::~MSRightOfWayJunction() {
00075     delete myLogic;
00076 }
00077 
00078 
00079 void
00080 MSRightOfWayJunction::postloadInit() throw(ProcessError) {
00081     // inform links where they have to report approaching vehicles to
00082     unsigned int requestPos = 0;
00083     std::vector<MSLane*>::iterator i;
00084     // going through the incoming lanes...
00085     unsigned int maxNo = 0;
00086     std::vector<std::pair<MSLane*, MSLink*> > sortedLinks;
00087     for (i=myIncomingLanes.begin(); i!=myIncomingLanes.end(); ++i) {
00088         const MSLinkCont &links = (*i)->getLinkCont();
00089         // ... set information for every link
00090         for (MSLinkCont::const_iterator j=links.begin(); j!=links.end(); j++) {
00091             if (myLogic->getLogicSize()<=requestPos) {
00092                 throw ProcessError("Found invalid logic position of a link (network error)");
00093             }
00094             sortedLinks.push_back(std::make_pair(*i, *j));
00095             ++maxNo;
00096         }
00097     }
00098 
00099     bool isCrossing = myLogic->isCrossing();
00100     for (i=myIncomingLanes.begin(); i!=myIncomingLanes.end(); ++i) {
00101         const MSLinkCont &links = (*i)->getLinkCont();
00102         // ... set information for every link
00103         for (MSLinkCont::const_iterator j=links.begin(); j!=links.end(); j++) {
00104             if (myLogic->getLogicSize()<=requestPos) {
00105                 throw ProcessError("Found invalid logic position of a link (network error)");
00106             }
00107             const MSLogicJunction::LinkFoes &foeLinks = myLogic->getFoesFor(requestPos);
00108             const std::bitset<64> &internalFoes = myLogic->getInternalFoesFor(requestPos);
00109             bool cont = myLogic->getIsCont(requestPos);
00110             myLinkFoeLinks[*j] = std::vector<MSLink*>();
00111             for (unsigned int c=0; c<maxNo; ++c) {
00112                 if (foeLinks.test(c)) {
00113                     myLinkFoeLinks[*j].push_back(sortedLinks[c].second);
00114                 }
00115             }
00116             myLinkFoeInternalLanes[*j] = std::vector<MSLane*>();
00117             for (unsigned int c=0; c<myInternalLanes.size(); ++c) {
00118                 if (internalFoes.test(c)) {
00119                     myLinkFoeInternalLanes[*j].push_back(myInternalLanes[c]);
00120                 }
00121             }
00122             (*j)->setRequestInformation(&myRequest, requestPos, &myRespond, requestPos,
00123                                         foeLinks, isCrossing, cont, myLinkFoeLinks[*j], myLinkFoeInternalLanes[*j]);
00124             requestPos++;
00125         }
00126     }
00127 #ifdef HAVE_INTERNAL_LANES
00128     // set information for the internal lanes
00129     requestPos = 0;
00130     for (i=myInternalLanes.begin(); i!=myInternalLanes.end(); ++i) {
00131         // ... set information about participation
00132         static_cast<MSInternalLane*>(*i)->setParentJunctionInformation(&myInnerState, requestPos++);
00133     }
00134 #endif
00135 }
00136 
00137 
00138 bool
00139 MSRightOfWayJunction::setAllowed() {
00140 #ifdef HAVE_INTERNAL_LANES
00141     // lets reset the yield information on internal, split
00142     //  left-moving links
00143     /*
00144     if (MSGlobals::gUsingInternalLanes) {
00145         std::vector<MSLane*>::iterator i;
00146         size_t requestPos = 0;
00147         // going through the incoming lanes...
00148         for (i=myIncomingLanes.begin(); i!=myIncomingLanes.end(); ++i) {
00149             const MSLinkCont &links = (*i)->getLinkCont();
00150             // check whether the next lane is free
00151             for (MSLinkCont::const_iterator j=links.begin(); j!=links.end(); j++) {
00152                 if(myRequest.test(requestPos)) {
00153                     MSLane *dest = (*j)->getLane();
00154                     if (dest!=0) {
00155                         SUMOReal approachingLength = 0;
00156                         MSLane *via = 0;
00157                         if(via!=0) {
00158                             approachingLength = via->getVehLenSum();
00159                         }
00160                         const MSVehicle * const lastOnDest = dest->getLastVehicle();
00161                         if (lastOnDest!=0) {
00162                             if (lastOnDest->getPositionOnLane()-lastOnDest->getLength()-approachingLength<0) {
00163                                 myRequest.set(requestPos, false);
00164                             }
00165                         }
00166                     }
00167                 }
00168                 requestPos++;
00169             }
00170         }
00171     }
00172     */
00173 #endif
00174     // Get myRespond from logic and check for deadlocks.
00175     myLogic->respond(myRequest, myInnerState, myRespond);
00176     deadlockKiller();
00177 
00178 #ifdef HAVE_INTERNAL_LANES
00179     // reset the yield information on internal, split left-moving links
00180     if (MSGlobals::gUsingInternalLanes) {
00181         for (std::vector<MSLane*>::iterator i=myInternalLanes.begin(); i!=myInternalLanes.end(); ++i) {
00182             const MSLinkCont &lc = (*i)->getLinkCont();
00183             if (lc.size()==1) {
00184                 MSLink *link = lc[0];
00185                 if (link->getViaLane()!=0) {
00186                     // this is a split left-mover
00187                     link->resetInternalPriority();
00188                 }
00189             }
00190         }
00191     }
00192 #endif
00193     myInnerState.reset();
00194     return true;
00195 }
00196 
00197 
00198 void
00199 MSRightOfWayJunction::deadlockKiller() {
00200     if (myRequest.none()) {
00201         return;
00202     }
00203 
00204     // let's assume temporary, that deadlocks only occure on right-before-left
00205     //  junctions
00206     if (myRespond.none() && myInnerState.none()) {
00207         // Handle deadlock: Create randomly a deadlock-free request out of
00208         // myRequest, i.e. a "single bit" request. Then again, send it
00209         // through myLogic (this is necessary because we don't have a
00210         // mapping between requests and lanes.) !!! (we do now!!)
00211         std::vector< unsigned > trueRequests;
00212         trueRequests.reserve(myRespond.size());
00213         for (unsigned i = 0; i < myRequest.size(); ++i) {
00214             if (myRequest.test(i)) {
00215                 trueRequests.push_back(i);
00216                 assert(trueRequests.size() <= myRespond.size());
00217             }
00218         }
00219         // Choose randomly an index out of [0,trueRequests.size()];
00220         // !!! random choosing may choose one of less priorised lanes
00221         unsigned int noLockIndex = (unsigned int) RandHelper::rand(trueRequests.size());
00222 
00223         // Create deadlock-free request.
00224         std::bitset<64> noLockRequest(false);
00225         assert(trueRequests.size()>noLockIndex);
00226         noLockRequest.set(trueRequests[ noLockIndex ]);
00227         // Calculate respond with deadlock-free request.
00228         myLogic->respond(noLockRequest, myInnerState,  myRespond);
00229     }
00230     return;
00231 }
00232 
00233 
00234 /****************************************************************************/
00235 

Generated on Wed May 5 00:06:32 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6