MSRightOfWayJunction.cpp
Go to the documentation of this file.00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
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
00082 unsigned int requestPos = 0;
00083 std::vector<MSLane*>::iterator i;
00084
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
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
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
00129 requestPos = 0;
00130 for (i=myInternalLanes.begin(); i!=myInternalLanes.end(); ++i) {
00131
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
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 #endif
00174
00175 myLogic->respond(myRequest, myInnerState, myRespond);
00176 deadlockKiller();
00177
00178 #ifdef HAVE_INTERNAL_LANES
00179
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
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
00205
00206 if (myRespond.none() && myInnerState.none()) {
00207
00208
00209
00210
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
00220
00221 unsigned int noLockIndex = (unsigned int) RandHelper::rand(trueRequests.size());
00222
00223
00224 std::bitset<64> noLockRequest(false);
00225 assert(trueRequests.size()>noLockIndex);
00226 noLockRequest.set(trueRequests[ noLockIndex ]);
00227
00228 myLogic->respond(noLockRequest, myInnerState, myRespond);
00229 }
00230 return;
00231 }
00232
00233
00234
00235