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 <vector>
00031 #include <cassert>
00032 #include "NBTrafficLightDefinition.h"
00033 #include "NBNode.h"
00034 #include "NBOwnTLDef.h"
00035 #include "NBTrafficLightLogic.h"
00036 #include <utils/common/MsgHandler.h>
00037 #include <utils/common/UtilExceptions.h>
00038 #include <utils/common/ToString.h>
00039 #include <utils/options/OptionsCont.h>
00040 #include <utils/options/Option.h>
00041
00042 #ifdef CHECK_MEMORY_LEAKS
00043 #include <foreign/nvwa/debug_new.h>
00044 #endif // CHECK_MEMORY_LEAKS
00045
00046
00047
00048
00049
00050 NBOwnTLDef::NBOwnTLDef(const std::string &id,
00051 const std::vector<NBNode*> &junctions) throw()
00052 : NBTrafficLightDefinition(id, junctions) {}
00053
00054
00055 NBOwnTLDef::NBOwnTLDef(const std::string &id, NBNode *junction) throw()
00056 : NBTrafficLightDefinition(id, junction) {}
00057
00058
00059 NBOwnTLDef::NBOwnTLDef(const std::string &id) throw()
00060 : NBTrafficLightDefinition(id) {}
00061
00062
00063 NBOwnTLDef::~NBOwnTLDef() throw() {}
00064
00065
00066 int
00067 NBOwnTLDef::getToPrio(const NBEdge * const e) throw() {
00068 return e->getJunctionPriority(e->getToNode());
00069 }
00070
00071
00072 SUMOReal
00073 NBOwnTLDef::getDirectionalWeight(NBMMLDirection dir) throw() {
00074 switch (dir) {
00075 case MMLDIR_STRAIGHT:
00076 case MMLDIR_PARTLEFT:
00077 case MMLDIR_PARTRIGHT:
00078 return 2.;
00079 case MMLDIR_LEFT:
00080 case MMLDIR_RIGHT:
00081 return .5;
00082 case MMLDIR_NODIR:
00083 case MMLDIR_TURN:
00084 return 0;
00085 }
00086 return 0;
00087 }
00088
00089 SUMOReal
00090 NBOwnTLDef::computeUnblockedWeightedStreamNumber(const NBEdge * const e1, const NBEdge * const e2) throw() {
00091 SUMOReal val = 0;
00092 for (unsigned int e1l=0; e1l<e1->getNoLanes(); e1l++) {
00093 std::vector<NBEdge::Connection> approached1 = e1->getConnectionsFromLane(e1l);
00094 for (unsigned int e2l=0; e2l<e2->getNoLanes(); e2l++) {
00095 std::vector<NBEdge::Connection> approached2 = e2->getConnectionsFromLane(e2l);
00096 for (std::vector<NBEdge::Connection>::iterator e1c=approached1.begin(); e1c!=approached1.end(); ++e1c) {
00097 if (e1->getTurnDestination()==(*e1c).toEdge) {
00098 continue;
00099 }
00100 for (std::vector<NBEdge::Connection>::iterator e2c=approached2.begin(); e2c!=approached2.end(); ++e2c) {
00101 if (e2->getTurnDestination()==(*e2c).toEdge) {
00102 continue;
00103 }
00104 if (!foes(e1, (*e1c).toEdge, e2, (*e2c).toEdge)) {
00105 val += getDirectionalWeight(e1->getToNode()->getMMLDirection(e1, (*e1c).toEdge));
00106 val += getDirectionalWeight(e2->getToNode()->getMMLDirection(e2, (*e2c).toEdge));
00107 }
00108 }
00109 }
00110 }
00111 }
00112 return val;
00113 }
00114
00115
00116 std::pair<NBEdge*, NBEdge*>
00117 NBOwnTLDef::getBestCombination(const std::vector<NBEdge*> &edges) throw() {
00118 std::pair<NBEdge*, NBEdge*> bestPair(0,0);
00119 SUMOReal bestValue = -1;
00120 for (std::vector<NBEdge*>::const_iterator i=edges.begin(); i!=edges.end(); ++i) {
00121 for (std::vector<NBEdge*>::const_iterator j=i+1; j!=edges.end(); ++j) {
00122 SUMOReal value = computeUnblockedWeightedStreamNumber(*i, *j);
00123 if (value>bestValue) {
00124 bestValue = value;
00125 bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j);
00126 } else if (value==bestValue) {
00127 SUMOReal ca = GeomHelper::getMinAngleDiff((*i)->getAngle(*(*i)->getToNode()), (*j)->getAngle(*(*j)->getToNode()));
00128 SUMOReal oa = GeomHelper::getMinAngleDiff(bestPair.first->getAngle(*bestPair.first->getToNode()), bestPair.second->getAngle(*bestPair.second->getToNode()));
00129 if (oa<ca) {
00130 bestPair = std::pair<NBEdge*, NBEdge*>(*i, *j);
00131 }
00132 }
00133 }
00134 }
00135 return bestPair;
00136 }
00137
00138
00139 std::pair<NBEdge*, NBEdge*>
00140 NBOwnTLDef::getBestPair(std::vector<NBEdge*> &incoming) throw() {
00141 if (incoming.size()==1) {
00142
00143 std::pair<NBEdge*, NBEdge*> ret(*incoming.begin(), 0);
00144 incoming.clear();
00145 return ret;
00146 }
00147
00148
00149 std::vector<NBEdge*> used;
00150 std::sort(incoming.begin(), incoming.end(), edge_by_incoming_priority_sorter());
00151 used.push_back(*incoming.begin());
00152
00153 int prio = getToPrio(*used.begin());
00154 for (std::vector<NBEdge*>::iterator i=incoming.begin()+1; i!=incoming.end()&&prio!=getToPrio(*i); ++i) {
00155 used.push_back(*i);
00156 }
00157
00158 if (used.size()<2) {
00159 used = incoming;
00160 }
00161 std::pair<NBEdge*, NBEdge*> ret = getBestCombination(used);
00162 incoming.erase(find(incoming.begin(), incoming.end(), ret.first));
00163 incoming.erase(find(incoming.begin(), incoming.end(), ret.second));
00164 return ret;
00165 }
00166
00167
00168 NBTrafficLightLogic *
00169 NBOwnTLDef::myCompute(const NBEdgeCont &,
00170 unsigned int brakingTime) throw() {
00171
00172 const EdgeVector &incoming = getIncomingEdges();
00173 std::vector<NBEdge*> fromEdges, toEdges;
00174 std::vector<bool> isLeftMoverV, isTurnaround;
00175 unsigned int noLanesAll = 0;
00176 unsigned int noLinksAll = 0;
00177 for (unsigned int i1=0; i1<incoming.size(); i1++) {
00178 unsigned int noLanes = incoming[i1]->getNoLanes();
00179 noLanesAll += noLanes;
00180 for (unsigned int i2=0; i2<noLanes; i2++) {
00181 NBEdge *fromEdge = incoming[i1];
00182 std::vector<NBEdge::Connection> approached = fromEdge->getConnectionsFromLane(i2);
00183 noLinksAll += (unsigned int) approached.size();
00184 for (unsigned int i3=0; i3<approached.size(); i3++) {
00185 if (!fromEdge->mayBeTLSControlled(i2, approached[i3].toEdge, approached[i3].toLane)) {
00186 --noLinksAll;
00187 continue;
00188 }
00189 assert(i3<approached.size());
00190 NBEdge *toEdge = approached[i3].toEdge;
00191 fromEdges.push_back(fromEdge);
00192
00193 toEdges.push_back(toEdge);
00194 if (toEdge!=0) {
00195 isLeftMoverV.push_back(
00196 isLeftMover(fromEdge, toEdge)
00197 ||
00198 fromEdge->isTurningDirectionAt(fromEdge->getToNode(), toEdge));
00199
00200 isTurnaround.push_back(
00201 fromEdge->isTurningDirectionAt(
00202 fromEdge->getToNode(), toEdge));
00203 } else {
00204 isLeftMoverV.push_back(true);
00205 isTurnaround.push_back(true);
00206 }
00207 }
00208 }
00209 }
00210
00211 NBTrafficLightLogic *logic = new NBTrafficLightLogic(getID(), "0", noLinksAll);
00212 std::vector<NBEdge*> toProc = incoming;
00213
00214 while (toProc.size()>0) {
00215 std::pair<NBEdge*, NBEdge*> chosen;
00216 if (incoming.size()==2) {
00217 chosen = std::pair<NBEdge*, NBEdge*>(toProc[0], 0);
00218 toProc.erase(toProc.begin());
00219 } else {
00220 chosen = getBestPair(toProc);
00221 }
00222 unsigned int pos = 0;
00223 unsigned int duration = 31;
00224 if (OptionsCont::getOptions().isSet("traffic-light-green")) {
00225 duration = OptionsCont::getOptions().getInt("traffic-light-green");
00226 }
00227 std::string state((size_t) noLinksAll, 'o');
00228
00229 for (unsigned int i1=0; i1<(unsigned int) incoming.size(); ++i1) {
00230 NBEdge *fromEdge = incoming[i1];
00231 bool inChosen = fromEdge==chosen.first||fromEdge==chosen.second;
00232 unsigned int noLanes = fromEdge->getNoLanes();
00233 for (unsigned int i2=0; i2<noLanes; i2++) {
00234 std::vector<NBEdge::Connection> approached = fromEdge->getConnectionsFromLane(i2);
00235 for (unsigned int i3=0; i3<approached.size(); ++i3) {
00236 if (!fromEdge->mayBeTLSControlled(i2, approached[i3].toEdge, approached[i3].toLane)) {
00237 continue;
00238 }
00239 if (inChosen) {
00240 state[pos] = 'G';
00241 } else {
00242 state[pos] = 'r';
00243 }
00244 ++pos;
00245 }
00246 }
00247 }
00248
00249 for (unsigned int i1=0; i1<pos; ++i1) {
00250 if (state[i1]=='G') {
00251 continue;
00252 }
00253 bool isForbidden = false;
00254 for (unsigned int i2=0; i2<pos&&!isForbidden; ++i2) {
00255 if (state[i2]=='G'&&!isTurnaround[i2]&&
00256 (forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1], true)||forbids(fromEdges[i1], toEdges[i1], fromEdges[i2], toEdges[i2], true))) {
00257 isForbidden = true;
00258 }
00259 }
00260 if (!isForbidden) {
00261 state[i1] = 'G';
00262 }
00263 }
00264
00265 bool haveForbiddenLeftMover = false;
00266 for (unsigned int i1=0; i1<pos; ++i1) {
00267 if (state[i1]!='G') {
00268 continue;
00269 }
00270 for (unsigned int i2=0; i2<pos; ++i2) {
00271 if ((state[i2]=='G'||state[i2]=='g')&&forbids(fromEdges[i2], toEdges[i2], fromEdges[i1], toEdges[i1], true)) {
00272 state[i1] = 'g';
00273 if (!isTurnaround[i1]) {
00274 haveForbiddenLeftMover = true;
00275 }
00276 }
00277 }
00278 }
00279
00280
00281 logic->addStep(duration, state);
00282
00283 if (brakingTime>0) {
00284
00285 duration = brakingTime;
00286 for (unsigned int i1=0; i1<pos; ++i1) {
00287 if (state[i1]!='G'&&state[i1]!='g') {
00288 continue;
00289 }
00290 if ((state[i1]>='a'&&state[i1]<='z')&&haveForbiddenLeftMover) {
00291 continue;
00292 }
00293 state[i1] = 'y';
00294 }
00295
00296 logic->addStep(duration, state);
00297 }
00298
00299 if (haveForbiddenLeftMover) {
00300
00301 duration = 6;
00302 for (unsigned int i1=0; i1<pos; ++i1) {
00303 if (state[i1]=='Y'||state[i1]=='y') {
00304 state[i1] = 'r';
00305 continue;
00306 }
00307 if (state[i1]=='g') {
00308 state[i1] = 'G';
00309 }
00310 }
00311
00312 logic->addStep(duration, state);
00313
00314
00315 if (brakingTime>0) {
00316 duration = brakingTime;
00317 for (unsigned int i1=0; i1<pos; ++i1) {
00318 if (state[i1]!='G'&&state[i1]!='g') {
00319 continue;
00320 }
00321 state[i1] = 'y';
00322 }
00323
00324 logic->addStep(duration, state);
00325 }
00326 }
00327 }
00328 if (logic->getDuration()>0) {
00329 return logic;
00330 } else {
00331 delete logic;
00332 return 0;
00333 }
00334
00335 }
00336
00337
00338 void
00339 NBOwnTLDef::collectNodes() throw() {}
00340
00341
00342 void
00343 NBOwnTLDef::collectLinks() throw(ProcessError) {
00344
00345 for (EdgeVector::iterator i=myIncomingEdges.begin(); i!=myIncomingEdges.end(); i++) {
00346 NBEdge *incoming = *i;
00347 unsigned int noLanes = incoming->getNoLanes();
00348 for (unsigned int j=0; j<noLanes; j++) {
00349 std::vector<NBEdge::Connection> connected = incoming->getConnectionsFromLane(j);
00350 for (std::vector<NBEdge::Connection>::iterator k=connected.begin(); k!=connected.end(); k++) {
00351 const NBEdge::Connection &el = *k;
00352 if (incoming->mayBeTLSControlled(el.fromLane, el.toEdge, el.toLane)) {
00353 if (el.toEdge!=0&&el.toLane>=(int) el.toEdge->getNoLanes()) {
00354 throw ProcessError("Connection '" + incoming->getID() + "_" + toString(j) + "->" + el.toEdge->getID() + "_" + toString(el.toLane) + "' yields in a not existing lane.");
00355 }
00356 myControlledLinks.push_back(NBConnection(incoming, j, el.toEdge, el.toLane));
00357 }
00358 }
00359 }
00360 }
00361 }
00362
00363
00364 void
00365 NBOwnTLDef::setParticipantsInformation() throw() {
00366
00367 collectNodes();
00368
00369 collectEdges();
00370 collectLinks();
00371 }
00372
00373
00374 void
00375 NBOwnTLDef::setTLControllingInformation(const NBEdgeCont &) const throw() {
00376
00377
00378 unsigned int pos = 0;
00379 for (NBConnectionVector::const_iterator j=myControlledLinks.begin(); j!=myControlledLinks.end(); ++j) {
00380 const NBConnection &conn = *j;
00381 NBEdge *edge = conn.getFrom();
00382 if (edge->setControllingTLInformation(conn.getFromLane(), conn.getTo(), conn.getToLane(), getID(), pos)) {
00383 pos++;
00384 }
00385 }
00386 }
00387
00388
00389 void
00390 NBOwnTLDef::remapRemoved(NBEdge * , const EdgeVector &,
00391 const EdgeVector &) throw() {}
00392
00393
00394 void
00395 NBOwnTLDef::replaceRemoved(NBEdge * , int ,
00396 NBEdge * , int ) throw() {}
00397
00398
00399
00400