00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef _MSC_VER
00024 #include <windows_config.h>
00025 #else
00026 #include <config.h>
00027 #endif
00028
00029 #include <vector>
00030 #include <set>
00031 #include <cassert>
00032 #include <utils/common/MsgHandler.h>
00033 #include <utils/common/ToString.h>
00034 #include <utils/options/OptionsCont.h>
00035 #include "NBTrafficLightLogic.h"
00036 #include "NBTrafficLightDefinition.h"
00037 #include "NBLoadedTLDef.h"
00038 #include "NBNode.h"
00039
00040 #ifdef CHECK_MEMORY_LEAKS
00041 #include <foreign/nvwa/debug_new.h>
00042 #endif // CHECK_MEMORY_LEAKS
00043
00044
00045
00046
00047
00048
00049
00050
00051 NBLoadedTLDef::SignalGroup::SignalGroup(const std::string &id) throw()
00052 : Named(id) {}
00053
00054 NBLoadedTLDef::SignalGroup::~SignalGroup() throw() {}
00055
00056 void
00057 NBLoadedTLDef::SignalGroup::addConnection(const NBConnection &c) throw() {
00058 assert(c.getFromLane()<0||c.getFrom()->getNoLanes()>(unsigned int)c.getFromLane());
00059 myConnections.push_back(c);
00060 }
00061
00062
00063 void
00064 NBLoadedTLDef::SignalGroup::addPhaseBegin(SUMOTime time, TLColor color) throw() {
00065 myPhases.push_back(PhaseDef(time, color));
00066 }
00067
00068
00069 void
00070 NBLoadedTLDef::SignalGroup::setYellowTimes(SUMOTime tRedYellow,
00071 SUMOTime tYellow) throw() {
00072 myTRedYellow = tRedYellow;
00073 myTYellow = tYellow;
00074 }
00075
00076
00077 void
00078 NBLoadedTLDef::SignalGroup::sortPhases() throw() {
00079 sort(myPhases.begin(), myPhases.end(),
00080 phase_by_time_sorter());
00081 }
00082
00083
00084 void
00085 NBLoadedTLDef::SignalGroup::patchTYellow(SUMOTime tyellow) throw() {
00086 if (myTYellow<tyellow) {
00087 WRITE_WARNING("TYellow of signal group '" + getID()+ "' was less than the computed one; patched (was:" + toString<SUMOTime>(myTYellow) + ", is:" + toString<int>(tyellow) + ")");
00088 myTYellow = tyellow;
00089 }
00090 }
00091
00092
00093 DoubleVector
00094 NBLoadedTLDef::SignalGroup::getTimes(SUMOTime cycleDuration) const throw() {
00095
00096
00097 DoubleVector ret;
00098 for (std::vector<PhaseDef>::const_iterator i=myPhases.begin(); i!=myPhases.end(); i++) {
00099 ret.push_back((SUMOReal)(*i).myTime);
00100 }
00101
00102 if (myTYellow>0) {
00103 for (std::vector<PhaseDef>::const_iterator i=myPhases.begin(); i!=myPhases.end(); i++) {
00104 if ((*i).myColor==TLCOLOR_RED) {
00105 SUMOTime time = (SUMOTime)(*i).myTime + myTYellow;
00106 if (time>cycleDuration) {
00107 time = time - cycleDuration ;
00108 }
00109 ret.push_back((SUMOReal) time);
00110 }
00111 }
00112 }
00113 return ret;
00114 }
00115
00116
00117 unsigned int
00118 NBLoadedTLDef::SignalGroup::getLinkNo() const throw() {
00119 return (unsigned int) myConnections.size();
00120 }
00121
00122
00123 bool
00124 NBLoadedTLDef::SignalGroup::mayDrive(SUMOTime time) const throw() {
00125 assert(myPhases.size()!=0);
00126 for (std::vector<PhaseDef>::const_reverse_iterator i=myPhases.rbegin(); i!=myPhases.rend(); i++) {
00127 SUMOTime nextTime = (*i).myTime;
00128 if (time>=nextTime) {
00129 return (*i).myColor==TLCOLOR_GREEN;
00130 }
00131 }
00132 return (*(myPhases.end()-1)).myColor==TLCOLOR_GREEN;
00133 }
00134
00135
00136 bool
00137 NBLoadedTLDef::SignalGroup::hasYellow(SUMOTime time) const throw() {
00138 bool has_red_now = !mayDrive(time);
00139 bool had_green = mayDrive(time-myTYellow);
00140 return has_red_now&&had_green;
00141 }
00142
00143
00144 bool
00145 NBLoadedTLDef::SignalGroup::containsConnection(NBEdge *from, NBEdge *to) const throw() {
00146 for (NBConnectionVector::const_iterator i=myConnections.begin(); i!=myConnections.end(); i++) {
00147 if ((*i).getFrom()==from&&(*i).getTo()==to) {
00148 return true;
00149 }
00150 }
00151 return false;
00152
00153 }
00154
00155
00156 const NBConnection &
00157 NBLoadedTLDef::SignalGroup::getConnection(unsigned int pos) const throw() {
00158 assert(pos<myConnections.size());
00159 return myConnections[pos];
00160 }
00161
00162
00163 bool
00164 NBLoadedTLDef::SignalGroup::containsIncoming(NBEdge *from) const throw() {
00165 for (NBConnectionVector::const_iterator i=myConnections.begin(); i!=myConnections.end(); i++) {
00166 if ((*i).getFrom()==from) {
00167 return true;
00168 }
00169 }
00170 return false;
00171 }
00172
00173
00174 void
00175 NBLoadedTLDef::SignalGroup::remapIncoming(NBEdge *which, const EdgeVector &by) throw(ProcessError) {
00176 NBConnectionVector newConns;
00177 for (NBConnectionVector::iterator i=myConnections.begin(); i!=myConnections.end();) {
00178 if ((*i).getFrom()==which) {
00179 NBConnection conn((*i).getFrom(), (*i).getTo());
00180 i = myConnections.erase(i);
00181 for (EdgeVector::const_iterator j=by.begin(); j!=by.end(); j++) {
00182 NBConnection curr(conn);
00183 if (!curr.replaceFrom(which, *j)) {
00184 throw ProcessError("Could not replace edge '" + which->getID() + "' by '" + (*j)->getID() + "'.\nUndefined...");
00185 }
00186 newConns.push_back(curr);
00187 }
00188 } else {
00189 i++;
00190 }
00191 }
00192 copy(newConns.begin(), newConns.end(),
00193 back_inserter(myConnections));
00194 }
00195
00196
00197 bool
00198 NBLoadedTLDef::SignalGroup::containsOutgoing(NBEdge *to) const throw() {
00199 for (NBConnectionVector::const_iterator i=myConnections.begin(); i!=myConnections.end(); i++) {
00200 if ((*i).getTo()==to) {
00201 return true;
00202 }
00203 }
00204 return false;
00205 }
00206
00207
00208 void
00209 NBLoadedTLDef::SignalGroup::remapOutgoing(NBEdge *which, const EdgeVector &by) throw(ProcessError) {
00210 NBConnectionVector newConns;
00211 for (NBConnectionVector::iterator i=myConnections.begin(); i!=myConnections.end();) {
00212 if ((*i).getTo()==which) {
00213 NBConnection conn((*i).getFrom(), (*i).getTo());
00214 i = myConnections.erase(i);
00215 for (EdgeVector::const_iterator j=by.begin(); j!=by.end(); j++) {
00216 NBConnection curr(conn);
00217 if (!curr.replaceTo(which, *j)) {
00218 throw ProcessError("Could not replace edge '" + which->getID() + "' by '" + (*j)->getID() + "'.\nUndefined...");
00219 }
00220 newConns.push_back(curr);
00221 }
00222 } else {
00223 i++;
00224 }
00225 }
00226 copy(newConns.begin(), newConns.end(),
00227 back_inserter(myConnections));
00228 }
00229
00230
00231 void
00232 NBLoadedTLDef::SignalGroup::remap(NBEdge *removed, int removedLane,
00233 NBEdge *by, int byLane) throw() {
00234 for (NBConnectionVector::iterator i=myConnections.begin(); i!=myConnections.end(); i++) {
00235 if ((*i).getTo()==removed
00236 &&
00237 ((*i).getToLane()==removedLane
00238 ||
00239 (*i).getToLane()==-1)) {
00240 (*i).replaceTo(removed, removedLane, by, byLane);
00241
00242 } else if ((*i).getTo()==removed && removedLane==-1) {
00243 (*i).replaceTo(removed, by);
00244 }
00245
00246 if ((*i).getFrom()==removed
00247 &&
00248 ((*i).getFromLane()==removedLane
00249 ||
00250 (*i).getFromLane()==-1)) {
00251 (*i).replaceFrom(removed, removedLane, by, byLane);
00252
00253 } else if ((*i).getFrom()==removed && removedLane==-1) {
00254 (*i).replaceFrom(removed, by);
00255 }
00256 }
00257 }
00258
00259
00260
00261
00262
00263 NBLoadedTLDef::NBLoadedTLDef(const std::string &id,
00264 const std::vector<NBNode*> &junctions) throw()
00265 : NBTrafficLightDefinition(id, junctions) {}
00266
00267
00268 NBLoadedTLDef::NBLoadedTLDef(const std::string &id, NBNode *junction) throw()
00269 : NBTrafficLightDefinition(id, junction) {}
00270
00271
00272 NBLoadedTLDef::NBLoadedTLDef(const std::string &id) throw()
00273 : NBTrafficLightDefinition(id) {}
00274
00275
00276 NBLoadedTLDef::~NBLoadedTLDef() throw() {
00277 for (SignalGroupCont::iterator i=mySignalGroups.begin(); i!=mySignalGroups.end(); ++i) {
00278 delete(*i).second;
00279 }
00280 }
00281
00282
00283 NBTrafficLightLogic *
00284 NBLoadedTLDef::myCompute(const NBEdgeCont &ec, unsigned int brakingTime) throw() {
00285 MsgHandler::getWarningInstance()->clear();
00286 NBLoadedTLDef::SignalGroupCont::const_iterator i;
00287
00288 std::set<SUMOReal> tmpSwitchTimes;
00289 for (i=mySignalGroups.begin(); i!=mySignalGroups.end(); i++) {
00290 NBLoadedTLDef::SignalGroup *group = (*i).second;
00291
00292 group->sortPhases();
00293
00294 if (OptionsCont::getOptions().getBool("patch-small-tyellow")) {
00295 group->patchTYellow(brakingTime);
00296 }
00297
00298
00299
00300 DoubleVector gtimes = group->getTimes(myCycleDuration);
00301 for (DoubleVector::const_iterator k=gtimes.begin(); k!=gtimes.end(); k++) {
00302 tmpSwitchTimes.insert(*k);
00303 }
00304 }
00305 std::vector<SUMOReal> switchTimes;
00306 copy(tmpSwitchTimes.begin(), tmpSwitchTimes.end(), back_inserter(switchTimes));
00307 sort(switchTimes.begin(), switchTimes.end());
00308
00309
00310 unsigned int noSignals = 0;
00311 for (i=mySignalGroups.begin(); i!=mySignalGroups.end(); i++) {
00312 noSignals += (*i).second->getLinkNo();
00313 }
00314
00315 NBTrafficLightLogic *logic = new NBTrafficLightLogic(getID(), "0", noSignals);
00316 for (std::vector<SUMOReal>::iterator l=switchTimes.begin(); l!=switchTimes.end(); l++) {
00317
00318 unsigned int duration;
00319 if (l!=switchTimes.end()-1) {
00320
00321 duration = (unsigned int)((*(l+1)) - (*l));
00322 } else {
00323
00324 duration = (unsigned int)(myCycleDuration - (*l) + *(switchTimes.begin())) ;
00325 }
00326
00327 assert((*l)>=0);
00328 logic->addStep(duration, buildPhaseState(ec, (unsigned int)(*l)));
00329 }
00330
00331 if (MsgHandler::getWarningInstance()->wasInformed()) {
00332 WRITE_WARNING("During computation of traffic light '" + getID() + "'.");
00333 }
00334 logic->closeBuilding();
00335 return logic;
00336 }
00337
00338
00339 void
00340 NBLoadedTLDef::setTLControllingInformation(const NBEdgeCont &ec) const throw() {
00341
00342 unsigned int pos = 0;
00343 for (SignalGroupCont::const_iterator m=mySignalGroups.begin(); m!=mySignalGroups.end(); m++) {
00344 SignalGroup *group = (*m).second;
00345 unsigned int linkNo = group->getLinkNo();
00346 for (unsigned int j=0; j<linkNo; j++) {
00347 const NBConnection &conn = group->getConnection(j);
00348 assert(conn.getFromLane()<0||(int) conn.getFrom()->getNoLanes()>conn.getFromLane());
00349 NBConnection tst(conn);
00350 if (tst.check(ec)) {
00351 NBEdge *edge = conn.getFrom();
00352 if (edge->setControllingTLInformation(conn.getFromLane(), conn.getTo(), conn.getToLane(), getID(), pos)) {
00353 pos++;
00354 }
00355 } else {
00356 WRITE_WARNING("Could not set signal on connection (signal: " + getID() + ", group: " + group->getID()+ ")");
00357 }
00358 }
00359 }
00360 }
00361
00362
00363 std::string
00364 NBLoadedTLDef::buildPhaseState(const NBEdgeCont &ec, unsigned int time) const throw() {
00365 unsigned int pos = 0;
00366 std::string state;
00367
00368
00369
00370 for (SignalGroupCont::const_iterator i=mySignalGroups.begin(); i!=mySignalGroups.end(); i++) {
00371 SignalGroup *group = (*i).second;
00372 unsigned int linkNo = group->getLinkNo();
00373 bool mayDrive = group->mayDrive(time);
00374 bool hasYellow = group->hasYellow(time);
00375 char c = 'r';
00376 if (mayDrive) {
00377 c = 'g';
00378 }
00379 if (hasYellow) {
00380 c = 'y';
00381 }
00382 for (unsigned int j=0; j<linkNo; j++) {
00383 const NBConnection &conn = group->getConnection(j);
00384 NBConnection assConn(conn);
00385
00386 if (assConn.check(ec)) {
00387 state = state + c;
00388 ++pos;
00389 }
00390 }
00391 }
00392
00393 pos = 0;
00394 for (SignalGroupCont::const_iterator i=mySignalGroups.begin(); i!=mySignalGroups.end(); i++) {
00395 SignalGroup *group = (*i).second;
00396 unsigned int linkNo = group->getLinkNo();
00397 for (unsigned int j=0; j<linkNo; j++) {
00398 const NBConnection &conn = group->getConnection(j);
00399 NBConnection assConn(conn);
00400 if (assConn.check(ec)) {
00401 if (!mustBrake(ec, assConn, state, pos)) {
00402 if (state[pos]=='g') {
00403 state[pos] = 'G';
00404 }
00405 if (state[pos]=='y') {
00406 state[pos] = 'Y';
00407 }
00408 }
00409 pos++;
00410 }
00411 }
00412 }
00413 return state;
00414 }
00415
00416
00417 bool
00418 NBLoadedTLDef::mustBrake(const NBEdgeCont &ec,
00419 const NBConnection &possProhibited,
00420 const std::string &state,
00421 unsigned int strmpos) const throw() {
00422
00423 if (state[strmpos]!='g'&&state[strmpos]!='G') {
00424 return true;
00425 }
00426
00427
00428
00429 unsigned int pos = 0;
00430 for (SignalGroupCont::const_iterator i=mySignalGroups.begin(); i!=mySignalGroups.end(); i++) {
00431 SignalGroup *group = (*i).second;
00432
00433 unsigned int linkNo = group->getLinkNo();
00434 for (unsigned int j=0; j<linkNo; j++) {
00435
00436 const NBConnection &other = group->getConnection(j);
00437 NBConnection possProhibitor(other);
00438
00439 if (possProhibitor.check(ec)) {
00440
00441 if (possProhibited.getFrom()==possProhibitor.getFrom()) {
00442 pos++;
00443 continue;
00444 }
00445 if (state[pos]=='g'||state[pos]=='G') {
00446 if (NBTrafficLightDefinition::mustBrake(possProhibited, possProhibitor, true)) {
00447 return true;
00448 }
00449 }
00450 pos++;
00451 }
00452 }
00453 }
00454 return false;
00455 }
00456
00457
00458 void
00459 NBLoadedTLDef::collectNodes() throw() {
00460 SignalGroupCont::const_iterator m;
00461 for (m=mySignalGroups.begin(); m!=mySignalGroups.end(); m++) {
00462 SignalGroup *group = (*m).second;
00463 unsigned int linkNo = group->getLinkNo();
00464 for (unsigned int j=0; j<linkNo; j++) {
00465 const NBConnection &conn = group->getConnection(j);
00466 NBEdge *edge = conn.getFrom();
00467 NBNode *node = edge->getToNode();
00468 myControlledNodes.push_back(node);
00469 }
00470 }
00471 std::sort(myControlledNodes.begin(), myControlledNodes.end(), NBNode::nodes_by_id_sorter());
00472 }
00473
00474
00475 void
00476 NBLoadedTLDef::collectLinks() throw(ProcessError) {
00477
00478 for (EdgeVector::iterator i=myIncomingEdges.begin(); i!=myIncomingEdges.end(); i++) {
00479 NBEdge *incoming = *i;
00480 unsigned int noLanes = incoming->getNoLanes();
00481 for (unsigned int j=0; j<noLanes; j++) {
00482 std::vector<NBEdge::Connection> elv = incoming->getConnectionsFromLane(j);
00483 for (std::vector<NBEdge::Connection>::iterator k=elv.begin(); k!=elv.end(); k++) {
00484 NBEdge::Connection el = *k;
00485 if (el.toEdge!=0) {
00486 myControlledLinks.push_back(NBConnection(incoming, j, el.toEdge, el.toLane));
00487 }
00488 }
00489 }
00490 }
00491 }
00492
00493
00494 NBLoadedTLDef::SignalGroup *
00495 NBLoadedTLDef::findGroup(NBEdge *from, NBEdge *to) const throw() {
00496 for (SignalGroupCont::const_iterator i=mySignalGroups.begin(); i!=mySignalGroups.end(); i++) {
00497 if ((*i).second->containsConnection(from, to)) {
00498 return (*i).second;
00499 }
00500 }
00501 return 0;
00502 }
00503
00504
00505 bool
00506 NBLoadedTLDef::addToSignalGroup(const std::string &groupid,
00507 const NBConnection &connection) throw() {
00508 if (mySignalGroups.find(groupid)==mySignalGroups.end()) {
00509 return false;
00510 }
00511 mySignalGroups[groupid]->addConnection(connection);
00512 NBNode *n1 = connection.getFrom()->getToNode();
00513 if (n1!=0) {
00514 addNode(n1);
00515 n1->addTrafficLight(this);
00516 }
00517 NBNode *n2 = connection.getTo()->getFromNode();
00518 if (n2!=0) {
00519 addNode(n2);
00520 n2->addTrafficLight(this);
00521 }
00522 return true;
00523 }
00524
00525
00526 bool
00527 NBLoadedTLDef::addToSignalGroup(const std::string &groupid,
00528 const NBConnectionVector &connections) throw() {
00529 bool ok = true;
00530 for (NBConnectionVector::const_iterator i=connections.begin(); i!=connections.end(); i++) {
00531 ok &= addToSignalGroup(groupid, *i);
00532 }
00533 return ok;
00534 }
00535
00536
00537 void
00538 NBLoadedTLDef::addSignalGroup(const std::string &id) throw() {
00539 assert(mySignalGroups.find(id)==mySignalGroups.end());
00540 mySignalGroups[id] = new SignalGroup(id);
00541 }
00542
00543
00544 void
00545 NBLoadedTLDef::addSignalGroupPhaseBegin(const std::string &groupid, SUMOTime time,
00546 TLColor color) throw() {
00547 assert(mySignalGroups.find(groupid)!=mySignalGroups.end());
00548 mySignalGroups[groupid]->addPhaseBegin(time, color);
00549 }
00550
00551 void
00552 NBLoadedTLDef::setSignalYellowTimes(const std::string &groupid,
00553 SUMOTime myTRedYellow, SUMOTime myTYellow) throw() {
00554 assert(mySignalGroups.find(groupid)!=mySignalGroups.end());
00555 mySignalGroups[groupid]->setYellowTimes(myTRedYellow, myTYellow);
00556 }
00557
00558
00559 void
00560 NBLoadedTLDef::setCycleDuration(unsigned int cycleDur) throw() {
00561 myCycleDuration = cycleDur;
00562 }
00563
00564
00565 void
00566 NBLoadedTLDef::remapRemoved(NBEdge *removed,
00567 const EdgeVector &incoming,
00568 const EdgeVector &outgoing) throw() {
00569 for (SignalGroupCont::const_iterator i=mySignalGroups.begin(); i!=mySignalGroups.end(); i++) {
00570 SignalGroup *group = (*i).second;
00571 if (group->containsIncoming(removed)) {
00572 group->remapIncoming(removed, incoming);
00573 }
00574 if (group->containsOutgoing(removed)) {
00575 group->remapOutgoing(removed, outgoing);
00576 }
00577 }
00578 }
00579
00580
00581 void
00582 NBLoadedTLDef::replaceRemoved(NBEdge *removed, int removedLane,
00583 NBEdge *by, int byLane) throw() {
00584 for (SignalGroupCont::const_iterator i=mySignalGroups.begin(); i!=mySignalGroups.end(); i++) {
00585 SignalGroup *group = (*i).second;
00586 if (group->containsIncoming(removed)||group->containsOutgoing(removed)) {
00587 group->remap(removed, removedLane, by, byLane);
00588 }
00589 }
00590 }
00591
00592
00593
00594
00595