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 <string>
00031 #include <vector>
00032 #include <set>
00033 #include <algorithm>
00034 #include <bitset>
00035 #include <sstream>
00036 #include <map>
00037 #include <cassert>
00038 #include <utils/common/MsgHandler.h>
00039 #include <utils/common/ToString.h>
00040 #include "NBEdge.h"
00041 #include "NBJunctionLogicCont.h"
00042 #include "NBContHelper.h"
00043 #include "NBTrafficLightLogic.h"
00044 #include "NBTrafficLightLogicCont.h"
00045 #include "NBNode.h"
00046 #include "NBRequest.h"
00047 #include <utils/options/OptionsCont.h>
00048
00049 #ifdef CHECK_MEMORY_LEAKS
00050 #include <foreign/nvwa/debug_new.h>
00051 #endif // CHECK_MEMORY_LEAKS
00052
00053
00054
00055
00056
00057 size_t NBRequest::myGoodBuilds = 0;
00058 size_t NBRequest::myNotBuild = 0;
00059
00060
00061
00062
00063
00064 NBRequest::NBRequest(const NBEdgeCont &ec,
00065 NBNode *junction, const EdgeVector * const all,
00066 const EdgeVector * const incoming,
00067 const EdgeVector * const outgoing,
00068 const NBConnectionProhibits &loadedProhibits)
00069 : myJunction(junction),
00070 myAll(all), myIncoming(incoming), myOutgoing(outgoing) {
00071 size_t variations = myIncoming->size() * myOutgoing->size();
00072
00073
00074 myForbids.reserve(variations);
00075 myDone.reserve(variations);
00076 for (size_t i=0; i<variations; i++) {
00077 myForbids.push_back(LinkInfoCont(variations, false));
00078 myDone.push_back(LinkInfoCont(variations, false));
00079 }
00080
00081 for (NBConnectionProhibits::const_iterator j=loadedProhibits.begin(); j!=loadedProhibits.end(); j++) {
00082 NBConnection prohibited = (*j).first;
00083 bool ok1 = prohibited.check(ec);
00084 if (find(myIncoming->begin(), myIncoming->end(), prohibited.getFrom())==myIncoming->end()) {
00085 ok1 = false;
00086 }
00087 if (find(myOutgoing->begin(), myOutgoing->end(), prohibited.getTo())==myOutgoing->end()) {
00088 ok1 = false;
00089 }
00090 int idx1 = 0;
00091 if (ok1) {
00092 idx1 = getIndex(prohibited.getFrom(), prohibited.getTo());
00093 if (idx1<0) {
00094 ok1 = false;
00095 }
00096 }
00097 const NBConnectionVector &prohibiting = (*j).second;
00098 for (NBConnectionVector::const_iterator k=prohibiting.begin(); k!=prohibiting.end(); k++) {
00099 NBConnection sprohibiting = *k;
00100 bool ok2 = sprohibiting.check(ec);
00101 if (find(myIncoming->begin(), myIncoming->end(), sprohibiting.getFrom())==myIncoming->end()) {
00102 ok2 = false;
00103 }
00104 if (find(myOutgoing->begin(), myOutgoing->end(), sprohibiting.getTo())==myOutgoing->end()) {
00105 ok2 = false;
00106 }
00107 if (ok1&&ok2) {
00108 int idx2 = getIndex(sprohibiting.getFrom(), sprohibiting.getTo());
00109 if (idx2<0) {
00110 ok2 = false;
00111 } else {
00112 myForbids[idx2][idx1] = true;
00113 myDone[idx2][idx1] = true;
00114 myDone[idx1][idx2] = true;
00115 myGoodBuilds++;
00116 }
00117 } else {
00118 std::string pfID = prohibited.getFrom()!=0 ? prohibited.getFrom()->getID() : "UNKNOWN";
00119 std::string ptID = prohibited.getTo()!=0 ? prohibited.getTo()->getID() : "UNKNOWN";
00120 std::string bfID = sprohibiting.getFrom()!=0 ? sprohibiting.getFrom()->getID() : "UNKNOWN";
00121 std::string btID = sprohibiting.getTo()!=0 ? sprohibiting.getTo()->getID() : "UNKNOWN";
00122 WRITE_WARNING("could not prohibit " + pfID + "->" + ptID+ " by "+ bfID + "->" + btID);
00123 myNotBuild++;
00124 }
00125 }
00126 }
00127
00128
00129 size_t no = myIncoming->size()*myOutgoing->size();
00130 for (size_t s1=0; s1<no; s1++) {
00131 for (size_t s2=s1+1; s2<no; s2++) {
00132
00133 if (!myDone[s1][s2]) {
00134 continue;
00135 }
00136
00137 if (myForbids[s1][s2]&&myForbids[s2][s1]) {
00138
00139 myDone[s1][s2] = false;
00140 myDone[s2][s1] = false;
00141 }
00142 }
00143 }
00144 }
00145
00146
00147 NBRequest::~NBRequest() {}
00148
00149
00150 void
00151 NBRequest::buildBitfieldLogic(bool leftHanded, NBJunctionLogicCont &jc,
00152 const std::string &key) {
00153 EdgeVector::const_iterator i, j;
00154 for (i=myIncoming->begin(); i!=myIncoming->end(); i++) {
00155 for (j=myOutgoing->begin(); j!=myOutgoing->end(); j++) {
00156 computeRightOutgoingLinkCrossings(leftHanded, *i, *j);
00157 computeLeftOutgoingLinkCrossings(leftHanded, *i, *j);
00158 }
00159 }
00160 jc.add(key, bitsetToXML(key));
00161 }
00162
00163
00164 void
00165 NBRequest::computeRightOutgoingLinkCrossings(bool leftHanded, NBEdge *from, NBEdge *to) {
00166 EdgeVector::const_iterator pfrom = find(myAll->begin(), myAll->end(), from);
00167 while (*pfrom!=to) {
00168 NBContHelper::nextCCW(myAll, pfrom);
00169 if ((*pfrom)->getToNode()==myJunction) {
00170 EdgeVector::const_iterator pto = find(myAll->begin(), myAll->end(), to);
00171 while (*pto!=from) {
00172 if (!((*pto)->getToNode()==myJunction)) {
00173 setBlocking(leftHanded, from, to, *pfrom, *pto);
00174 }
00175 NBContHelper::nextCCW(myAll, pto);
00176 }
00177 }
00178 }
00179 }
00180
00181
00182 void
00183 NBRequest::computeLeftOutgoingLinkCrossings(bool leftHanded, NBEdge *from, NBEdge *to) {
00184 EdgeVector::const_iterator pfrom = find(myAll->begin(), myAll->end(), from);
00185 while (*pfrom!=to) {
00186 NBContHelper::nextCW(myAll, pfrom);
00187 if ((*pfrom)->getToNode()==myJunction) {
00188 EdgeVector::const_iterator pto = find(myAll->begin(), myAll->end(), to);
00189 while (*pto!=from) {
00190 if (!((*pto)->getToNode()==myJunction)) {
00191 setBlocking(leftHanded, from, to, *pfrom, *pto);
00192 }
00193 NBContHelper::nextCW(myAll, pto);
00194 }
00195 }
00196 }
00197 }
00198
00199
00200 void
00201 NBRequest::setBlocking(bool leftHanded,
00202 NBEdge *from1, NBEdge *to1,
00203 NBEdge *from2, NBEdge *to2) {
00204
00205 if (to1==0||to2==0) {
00206 return;
00207 }
00208
00209 int idx1 = getIndex(from1, to1);
00210 int idx2 = getIndex(from2, to2);
00211 if (idx1<0||idx2<0) {
00212 return;
00213 }
00214
00215 assert((size_t) idx1<myIncoming->size()*myOutgoing->size());
00216 if (myDone[idx1][idx2]) {
00217 return;
00218 }
00219
00220 myDone[idx1][idx2] = true;
00221 myDone[idx2][idx1] = true;
00222
00223
00224 if (from1->isTurningDirectionAt(myJunction, to1)) {
00225 myForbids[idx2][idx1] = true;
00226 return;
00227 }
00228 if (from2->isTurningDirectionAt(myJunction, to2)) {
00229 myForbids[idx1][idx2] = true;
00230 return;
00231 }
00232
00233
00234 int from1p = from1->getJunctionPriority(myJunction);
00235 int from2p = from2->getJunctionPriority(myJunction);
00236
00237
00238
00239 if (from1p>from2p) {
00240 assert(myJunction->getType()!=NBNode::NODETYPE_RIGHT_BEFORE_LEFT);
00241 myForbids[idx1][idx2] = true;
00242 return;
00243 }
00244 if (from2p>from1p) {
00245 assert(myJunction->getType()!=NBNode::NODETYPE_RIGHT_BEFORE_LEFT);
00246 myForbids[idx2][idx1] = true;
00247 return;
00248 }
00249
00250
00251
00252
00253
00254 if (from1p>0&&from2p>0) {
00255 assert(myJunction->getType()!=NBNode::NODETYPE_RIGHT_BEFORE_LEFT);
00256 int to1p = to1->getJunctionPriority(myJunction);
00257 int to2p = to2->getJunctionPriority(myJunction);
00258 if (to1p>to2p) {
00259 myForbids[idx1][idx2] = true;
00260 return;
00261 }
00262 if (to2p>to1p) {
00263 myForbids[idx2][idx1] = true;
00264 return;
00265 }
00266 }
00267
00268
00269
00270 EdgeVector::const_iterator c1 = find(myAll->begin(), myAll->end(), from1);
00271 NBContHelper::nextCW(myAll, c1);
00272
00273 while (*c1!=from1&&*c1!=from2) {
00274 if (*c1==to2) {
00275
00276 if (!leftHanded) {
00277 myForbids[idx2][idx1] = true;
00278 } else {
00279 myForbids[idx1][idx2] = true;
00280 }
00281 return;
00282 }
00283 NBContHelper::nextCW(myAll, c1);
00284 }
00285
00286 EdgeVector::const_iterator c2 = find(myAll->begin(), myAll->end(), from2);
00287 NBContHelper::nextCW(myAll, c2);
00288
00289 while (*c2!=from2&&*c2!=from1) {
00290 if (*c2==to1) {
00291
00292 if (!leftHanded) {
00293 myForbids[idx1][idx2] = true;
00294 } else {
00295 myForbids[idx2][idx1] = true;
00296 }
00297 return;
00298 }
00299 NBContHelper::nextCW(myAll, c2);
00300 }
00301 }
00302
00303
00304 size_t
00305 NBRequest::distanceCounterClockwise(NBEdge *from, NBEdge *to) {
00306 EdgeVector::const_iterator p = find(myAll->begin(), myAll->end(), from);
00307 size_t ret = 0;
00308 while (true) {
00309 ret++;
00310 if (p==myAll->begin()) {
00311 p = myAll->end();
00312 }
00313 p--;
00314 if ((*p)==to) {
00315 return ret;
00316 }
00317 }
00318 }
00319
00320
00321 std::string
00322 NBRequest::bitsetToXML(std::string key) {
00323 std::ostringstream os;
00324
00325 resetSignalised();
00326
00327 std::pair<size_t, size_t> sizes = getSizes();
00328 size_t absNoLinks = sizes.second;
00329 size_t absNoLanes = sizes.first;
00330 assert(absNoLinks>=absNoLanes);
00331 os << " <row-logic id=\"" << key << "\" requestSize=\"" << absNoLinks
00332 << "\" laneNumber=\"" << absNoLanes << "\">" << std::endl;
00333 int pos = 0;
00334
00335 os << " <logic>" << std::endl;
00336 EdgeVector::const_iterator i;
00337 for (i=myIncoming->begin(); i!=myIncoming->end(); i++) {
00338 unsigned int noLanes = (*i)->getNoLanes();
00339 for (unsigned int k=0; k<noLanes; k++) {
00340 pos = writeLaneResponse(os, *i, k, pos);
00341 }
00342 }
00343 os << " </logic>" << std::endl;
00344 os << " </row-logic>" << std::endl;
00345 return os.str();
00346 }
00347
00348
00349 void
00350 NBRequest::resetSignalised() {
00351
00352 for (EdgeVector::const_iterator i11=myIncoming->begin(); i11!=myIncoming->end(); i11++) {
00353 unsigned int noLanesEdge1 = (*i11)->getNoLanes();
00354 for (unsigned int j1=0; j1<noLanesEdge1; j1++) {
00355 std::vector<NBEdge::Connection> el1 = (*i11)->getConnectionsFromLane(j1);
00356 for (std::vector<NBEdge::Connection>::iterator i12=el1.begin(); i12!=el1.end(); ++i12) {
00357 int idx1 = getIndex((*i11), (*i12).toEdge);
00358 if (idx1<0) {
00359 continue;
00360 }
00361
00362 for (EdgeVector::const_iterator i21=myIncoming->begin(); i21!=myIncoming->end(); i21++) {
00363 unsigned int noLanesEdge2 = (*i21)->getNoLanes();
00364 for (unsigned int j2=0; j2<noLanesEdge2; j2++) {
00365 std::vector<NBEdge::Connection> el2 = (*i21)->getConnectionsFromLane(j2);
00366 for (std::vector<NBEdge::Connection>::iterator i22=el2.begin(); i22!=el2.end(); i22++) {
00367 int idx2 = getIndex((*i21), (*i22).toEdge);
00368 if (idx2<0) {
00369 continue;
00370 }
00371
00372
00373 if ((*i11)==(*i21)) {
00374 myForbids[idx1][idx2] = false;
00375 myForbids[idx2][idx1] = false;
00376 continue;
00377 }
00378
00379
00380 if (((*i12).tlID==""&&(*i22).tlID=="")
00381 ||
00382 ((*i12).tlID!=""&&(*i22).tlID!="")) {
00383
00384 continue;
00385 }
00386
00387
00388 if (!foes(*i11, (*i12).toEdge, *i21, (*i22).toEdge)) {
00389 continue;
00390 }
00391
00392
00393 if ((*i12).tlID!="") {
00394 myForbids[idx1][idx2] = true;
00395 myForbids[idx2][idx1] = false;
00396 } else {
00397 myForbids[idx1][idx2] = false;
00398 myForbids[idx2][idx1] = true;
00399 }
00400 }
00401 }
00402 }
00403 }
00404 }
00405 }
00406 }
00407
00408
00409 std::pair<unsigned int, unsigned int>
00410 NBRequest::getSizes() const {
00411 unsigned int noLanes = 0;
00412 unsigned int noLinks = 0;
00413 for (EdgeVector::const_iterator i=myIncoming->begin();
00414 i!=myIncoming->end(); i++) {
00415 unsigned int noLanesEdge = (*i)->getNoLanes();
00416 for (unsigned int j=0; j<noLanesEdge; j++) {
00417
00418 assert((*i)->getConnectionsFromLane(j).size()!=0);
00419 noLinks += (unsigned int)(*i)->getConnectionsFromLane(j).size();
00420 }
00421 noLanes += noLanesEdge;
00422 }
00423 return std::pair<size_t, size_t>(noLanes, noLinks);
00424 }
00425
00426
00427 bool
00428 NBRequest::foes(const NBEdge * const from1, const NBEdge * const to1,
00429 const NBEdge * const from2, const NBEdge * const to2) const throw() {
00430
00431 if (to1==0 || to2==0) {
00432 return false;
00433 }
00434
00435 int idx1 = getIndex(from1, to1);
00436 int idx2 = getIndex(from2, to2);
00437 if (idx1<0||idx2<0) {
00438 return false;
00439 }
00440 assert((size_t) idx1<myIncoming->size()*myOutgoing->size());
00441 assert((size_t) idx2<myIncoming->size()*myOutgoing->size());
00442 return myForbids[idx1][idx2] || myForbids[idx2][idx1];
00443 }
00444
00445
00446 bool
00447 NBRequest::forbids(const NBEdge * const possProhibitorFrom, const NBEdge * const possProhibitorTo,
00448 const NBEdge * const possProhibitedFrom, const NBEdge * const possProhibitedTo,
00449 bool regardNonSignalisedLowerPriority) const throw() {
00450
00451 if (possProhibitorTo==0 || possProhibitedTo==0) {
00452 return false;
00453 }
00454
00455 int possProhibitorIdx = getIndex(possProhibitorFrom, possProhibitorTo);
00456 int possProhibitedIdx = getIndex(possProhibitedFrom, possProhibitedTo);
00457 if (possProhibitorIdx<0||possProhibitedIdx<0) {
00458 return false;
00459 }
00460 assert((size_t) possProhibitorIdx<myIncoming->size()*myOutgoing->size());
00461 assert((size_t) possProhibitedIdx<myIncoming->size()*myOutgoing->size());
00462
00463 if (!regardNonSignalisedLowerPriority) {
00464 return myForbids[possProhibitorIdx][possProhibitedIdx];
00465 }
00466
00467 if (!myForbids[possProhibitorIdx][possProhibitedIdx]) {
00468 return false;
00469 }
00470
00471 if (!possProhibitorFrom->hasSignalisedConnectionTo(possProhibitorTo)) {
00472 return false;
00473 }
00474 return true;
00475 }
00476
00477
00478 int
00479 NBRequest::writeLaneResponse(std::ostream &os, NBEdge *from,
00480 int fromLane, int pos) {
00481 std::vector<NBEdge::Connection> connected = from->getConnectionsFromLane(fromLane);
00482 for (std::vector<NBEdge::Connection>::iterator j=connected.begin(); j!=connected.end(); j++) {
00483 os << " <logicitem request=\"" << pos++ << "\" response=\"";
00484 writeResponse(os, from, (*j).toEdge, fromLane, (*j).toLane, (*j).mayDefinitelyPass);
00485 os << "\" foes=\"";
00486 writeAreFoes(os, from, (*j).toEdge, myJunction->getCrossingPosition(from, fromLane, (*j).toEdge, (*j).toLane).first>=0);
00487 os << "\"";
00488 if (!OptionsCont::getOptions().getBool("no-internal-links")) {
00489 if (myJunction->getCrossingPosition(from, fromLane, (*j).toEdge, (*j).toLane).first>=0) {
00490 os << " cont=\"1\"";
00491 } else {
00492 os << " cont=\"0\"";
00493 }
00494 }
00495 os << "/>" << std::endl;
00496 }
00497 return pos;
00498 }
00499
00500
00501 void
00502 NBRequest::writeResponse(std::ostream &os, const NBEdge * const from, const NBEdge * const to,
00503 int fromLane, int toLane, bool mayDefinitelyPass) const throw(IOError) {
00504 int idx = 0;
00505 if (to!=0) {
00506 idx = getIndex(from, to);
00507 }
00508 for (EdgeVector::const_reverse_iterator i=myIncoming->rbegin(); i!=myIncoming->rend(); i++) {
00509 const std::vector<NBEdge::Connection> &allConnections = (*i)->getConnections();
00510 unsigned int noLanes = (*i)->getNoLanes();
00511 for (int j=noLanes; j-->0;) {
00512 std::vector<NBEdge::Connection> connected = (*i)->getConnectionsFromLane(j);
00513 int size = (int) connected.size();
00514 for (int k=size; k-->0;) {
00515 if (mayDefinitelyPass) {
00516 os << '0';
00517 } else if (to==0) {
00518
00519 os << '1';
00520 } else if ((*i)==from&&fromLane==j) {
00521
00522 os << '0';
00523 } else {
00524 assert(k<(int) connected.size());
00525 assert((size_t) idx<myIncoming->size()*myOutgoing->size());
00526 assert(connected[k].toEdge==0 || (size_t) getIndex(*i, connected[k].toEdge)<myIncoming->size()*myOutgoing->size());
00527
00528 if (connected[k].toEdge!=0 && myForbids[getIndex(*i, connected[k].toEdge)][idx]) {
00529 os << '1';
00530 continue;
00531 }
00532 os << '0';
00533 }
00534 }
00535 }
00536 }
00537 }
00538
00539
00540 void
00541 NBRequest::writeAreFoes(std::ostream &os, NBEdge *from, NBEdge *to, bool isInnerEnd) {
00542
00543
00544
00545 int idx = 0;
00546 if (to!=0) {
00547 idx = getIndex(from, to);
00548 }
00549
00550 for (EdgeVector::const_reverse_iterator i=myIncoming->rbegin();
00551 i!=myIncoming->rend(); i++) {
00552
00553 unsigned int noLanes = (*i)->getNoLanes();
00554 for (unsigned int j=noLanes; j-->0;) {
00555 std::vector<NBEdge::Connection> connected = (*i)->getConnectionsFromLane(j);
00556 int size = (int) connected.size();
00557 for (int k=size; k-->0;) {
00558 if (to==0) {
00559 os << '0';
00560 } else {
00561
00562 if (foes(from, to, (*i), connected[k].toEdge)) {
00563 os << '1';
00564 } else {
00565 os << '0';
00566 }
00567 }
00568 }
00569 }
00570 }
00571 }
00572
00573
00574 int
00575 NBRequest::getIndex(const NBEdge * const from, const NBEdge * const to) const throw() {
00576 EdgeVector::const_iterator fp = find(myIncoming->begin(), myIncoming->end(), from);
00577 EdgeVector::const_iterator tp = find(myOutgoing->begin(), myOutgoing->end(), to);
00578 if (fp==myIncoming->end()||tp==myOutgoing->end()) {
00579 return -1;
00580 }
00581
00582 return (int)(distance(myIncoming->begin(), fp) * myOutgoing->size() + distance(myOutgoing->begin(), tp));
00583 }
00584
00585
00586 std::ostream &
00587 operator<<(std::ostream &os, const NBRequest &r) {
00588 size_t variations = r.myIncoming->size() * r.myOutgoing->size();
00589 for (size_t i=0; i<variations; i++) {
00590 os << i << ' ';
00591 for (size_t j=0; j<variations; j++) {
00592 if (r.myForbids[i][j])
00593 os << '1';
00594 else
00595 os << '0';
00596 }
00597 os << std::endl;
00598 }
00599 os << std::endl;
00600 return os;
00601 }
00602
00603
00604 bool
00605 NBRequest::mustBrake(const NBEdge * const from, const NBEdge * const to) const throw() {
00606
00607 if (to==0) {
00608 return true;
00609 }
00610
00611 int idx2 = getIndex(from, to);
00612 if (idx2==-1) {
00613 return false;
00614 }
00615
00616
00617 assert((size_t) idx2<myIncoming->size()*myOutgoing->size());
00618 for (size_t idx1=0; idx1<myIncoming->size()*myOutgoing->size(); idx1++) {
00619
00620 if (myDone[idx1][idx2]&&myForbids[idx1][idx2]) {
00621 return true;
00622 }
00623 }
00624 return false;
00625 }
00626
00627
00628 bool
00629 NBRequest::mustBrake(const NBEdge * const possProhibitorFrom, const NBEdge * const possProhibitorTo,
00630 const NBEdge * const possProhibitedFrom, const NBEdge * const possProhibitedTo) const throw() {
00631
00632 int idx1 = getIndex(possProhibitorFrom, possProhibitorTo);
00633 int idx2 = getIndex(possProhibitedFrom, possProhibitedTo);
00634 return (myForbids[idx2][idx1]);
00635 }
00636
00637
00638 void
00639 NBRequest::reportWarnings() {
00640
00641 if (myNotBuild!=0) {
00642 WRITE_WARNING(toString(myNotBuild) + " of " + toString(myNotBuild+myGoodBuilds)+ " prohibitions were not build.");
00643 }
00644 }
00645
00646
00647
00648
00649