SUMO - Simulation of Urban MObility
NIVissimTL.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00009 // -------------------
00010 /****************************************************************************/
00011 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00012 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00013 /****************************************************************************/
00014 //
00015 //   This file is part of SUMO.
00016 //   SUMO is free software: you can redistribute it and/or modify
00017 //   it under the terms of the GNU General Public License as published by
00018 //   the Free Software Foundation, either version 3 of the License, or
00019 //   (at your option) any later version.
00020 //
00021 /****************************************************************************/
00022 
00023 
00024 // ===========================================================================
00025 // included modules
00026 // ===========================================================================
00027 #ifdef _MSC_VER
00028 #include <windows_config.h>
00029 #else
00030 #include <config.h>
00031 #endif
00032 
00033 
00034 #include <map>
00035 #include <string>
00036 #include <cassert>
00037 #include <utils/geom/GeomHelper.h>
00038 #include <utils/geom/Boundary.h>
00039 #include <utils/common/MsgHandler.h>
00040 #include <utils/common/ToString.h>
00041 #include "NIVissimConnection.h"
00042 #include <netbuild/NBLoadedTLDef.h>
00043 #include <netbuild/NBEdge.h>
00044 #include <netbuild/NBEdgeCont.h>
00045 #include <netbuild/NBTrafficLightLogicCont.h>
00046 #include <netbuild/NBLoadedTLDef.h>
00047 #include "NIVissimConnection.h"
00048 #include "NIVissimDisturbance.h"
00049 #include "NIVissimNodeDef.h"
00050 #include "NIVissimEdge.h"
00051 #include "NIVissimTL.h"
00052 
00053 #ifdef CHECK_MEMORY_LEAKS
00054 #include <foreign/nvwa/debug_new.h>
00055 #endif // CHECK_MEMORY_LEAKS
00056 // ===========================================================================
00057 // used namespaces
00058 // ===========================================================================
00059 
00060 using namespace std;
00061 
00062 
00063 NIVissimTL::SignalDictType NIVissimTL::NIVissimTLSignal::myDict;
00064 
00065 NIVissimTL::NIVissimTLSignal::NIVissimTLSignal(int lsaid, int id,
00066         const std::string& name,
00067         const std::vector<int>& groupids,
00068         int edgeid,
00069         int laneno,
00070         SUMOReal position,
00071         const std::vector<int>& vehicleTypes)
00072     : myLSA(lsaid), myID(id), myName(name), myGroupIDs(groupids),
00073       myEdgeID(edgeid), myLane(laneno), myPosition(position),
00074       myVehicleTypes(vehicleTypes) {}
00075 
00076 
00077 NIVissimTL::NIVissimTLSignal::~NIVissimTLSignal() {}
00078 
00079 bool
00080 NIVissimTL::NIVissimTLSignal::isWithin(const PositionVector& poly) const {
00081     return poly.around(getPosition());
00082 }
00083 
00084 
00085 Position
00086 NIVissimTL::NIVissimTLSignal::getPosition() const {
00087     return NIVissimAbstractEdge::dictionary(myEdgeID)->getGeomPosition(myPosition);
00088 }
00089 
00090 
00091 bool
00092 NIVissimTL::NIVissimTLSignal::dictionary(int lsaid, int id,
00093         NIVissimTL::NIVissimTLSignal* o) {
00094     SignalDictType::iterator i = myDict.find(lsaid);
00095     if (i == myDict.end()) {
00096         myDict[lsaid] = SSignalDictType();
00097         i = myDict.find(lsaid);
00098     }
00099     SSignalDictType::iterator j = (*i).second.find(id);
00100     if (j == (*i).second.end()) {
00101         myDict[lsaid][id] = o;
00102         return true;
00103     }
00104     return false;
00105 }
00106 
00107 
00108 NIVissimTL::NIVissimTLSignal*
00109 NIVissimTL::NIVissimTLSignal::dictionary(int lsaid, int id) {
00110     SignalDictType::iterator i = myDict.find(lsaid);
00111     if (i == myDict.end()) {
00112         return 0;
00113     }
00114     SSignalDictType::iterator j = (*i).second.find(id);
00115     if (j == (*i).second.end()) {
00116         return 0;
00117     }
00118     return (*j).second;
00119 }
00120 
00121 
00122 void
00123 NIVissimTL::NIVissimTLSignal::clearDict() {
00124     for (SignalDictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
00125         for (SSignalDictType::iterator j = (*i).second.begin(); j != (*i).second.end(); j++) {
00126             delete(*j).second;
00127         }
00128     }
00129     myDict.clear();
00130 }
00131 
00132 
00133 NIVissimTL::SSignalDictType
00134 NIVissimTL::NIVissimTLSignal::getSignalsFor(int tlid) {
00135     SignalDictType::iterator i = myDict.find(tlid);
00136     if (i == myDict.end()) {
00137         return SSignalDictType();
00138     }
00139     return (*i).second;
00140 }
00141 
00142 
00143 bool
00144 NIVissimTL::NIVissimTLSignal::addTo(NBEdgeCont& ec, NBLoadedTLDef* tl) const {
00145     NIVissimConnection* c = NIVissimConnection::dictionary(myEdgeID);
00146     NBConnectionVector assignedConnections;
00147     if (c == 0) {
00148         // What to do if on an edge? -> close all outgoing connections
00149         NBEdge* edge = ec.retrievePossiblySplitted(toString<int>(myEdgeID), myPosition);
00150         if (edge == 0) {
00151             WRITE_WARNING("Could not set tls signal at edge '" + toString(myEdgeID) + "' - the edge was not built.");
00152             return false;
00153         }
00154         // Check whether it is already known, which edges are approached
00155         //  by which lanes
00156         // check whether to use the original lanes only
00157         if (edge->lanesWereAssigned()) {
00158             std::vector<NBEdge::Connection> connections = edge->getConnectionsFromLane(myLane - 1);
00159             for (std::vector<NBEdge::Connection>::iterator i = connections.begin(); i != connections.end(); i++) {
00160                 const NBEdge::Connection& conn = *i;
00161                 assert(myLane - 1 < (int)edge->getNumLanes());
00162                 assignedConnections.push_back(NBConnection(edge, myLane - 1, conn.toEdge, conn.toLane));
00163             }
00164         } else {
00165             WRITE_WARNING("Edge : Lanes were not assigned(!)");
00166             for (unsigned int j = 0; j < edge->getNumLanes(); j++) {
00167                 std::vector<NBEdge::Connection> connections = edge->getConnectionsFromLane(j);
00168                 for (std::vector<NBEdge::Connection>::iterator i = connections.begin(); i != connections.end(); i++) {
00169                     const NBEdge::Connection& conn = *i;
00170                     assignedConnections.push_back(NBConnection(edge, j, conn.toEdge, conn.toLane));
00171                 }
00172             }
00173         }
00174     } else {
00175         // get the edges
00176         NBEdge* tmpFrom = ec.retrievePossiblySplitted(
00177                               toString<int>(c->getFromEdgeID()),
00178                               toString<int>(c->getToEdgeID()),
00179                               true);
00180         NBEdge* tmpTo = ec.retrievePossiblySplitted(
00181                             toString<int>(c->getToEdgeID()),
00182                             toString<int>(c->getFromEdgeID()),
00183                             false);
00184         // check whether the edges are known
00185         if (tmpFrom != 0 && tmpTo != 0) {
00186             // add connections this signal is responsible for
00187             assignedConnections.push_back(NBConnection(tmpFrom, -1, tmpTo, -1));
00188         } else {
00189             return false;
00190             // !!! one of the edges could not be build
00191         }
00192     }
00193     // add to the group
00194     assert(myGroupIDs.size() != 0);
00195     if (myGroupIDs.size() == 1) {
00196         return tl->addToSignalGroup(toString<int>(*(myGroupIDs.begin())),
00197                                     assignedConnections);
00198     } else {
00199         // !!!
00200         return tl->addToSignalGroup(toString<int>(*(myGroupIDs.begin())),
00201                                     assignedConnections);
00202     }
00203     return true;
00204 }
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 NIVissimTL::GroupDictType NIVissimTL::NIVissimTLSignalGroup::myDict;
00214 
00215 NIVissimTL::NIVissimTLSignalGroup::NIVissimTLSignalGroup(
00216     int lsaid, int id,
00217     const std::string& name,
00218     bool isGreenBegin, const std::vector<SUMOReal>& times,
00219     SUMOTime tredyellow, SUMOTime tyellow)
00220     : myLSA(lsaid), myID(id), myName(name), myTimes(times),
00221       myFirstIsRed(!isGreenBegin), myTRedYellow(tredyellow),
00222       myTYellow(tyellow) {}
00223 
00224 
00225 NIVissimTL::NIVissimTLSignalGroup::~NIVissimTLSignalGroup() {}
00226 
00227 
00228 bool
00229 NIVissimTL::NIVissimTLSignalGroup::dictionary(int lsaid, int id,
00230         NIVissimTL::NIVissimTLSignalGroup* o) {
00231     GroupDictType::iterator i = myDict.find(lsaid);
00232     if (i == myDict.end()) {
00233         myDict[lsaid] = SGroupDictType();
00234         i = myDict.find(lsaid);
00235     }
00236     SGroupDictType::iterator j = (*i).second.find(id);
00237     if (j == (*i).second.end()) {
00238         myDict[lsaid][id] = o;
00239         return true;
00240     }
00241     return false;
00242     /*
00243         GroupDictType::iterator i=myDict.find(id);
00244         if(i==myDict.end()) {
00245             myDict[id] = o;
00246             return true;
00247         }
00248         return false;
00249         */
00250 }
00251 
00252 
00253 NIVissimTL::NIVissimTLSignalGroup*
00254 NIVissimTL::NIVissimTLSignalGroup::dictionary(int lsaid, int id) {
00255     GroupDictType::iterator i = myDict.find(lsaid);
00256     if (i == myDict.end()) {
00257         return 0;
00258     }
00259     SGroupDictType::iterator j = (*i).second.find(id);
00260     if (j == (*i).second.end()) {
00261         return 0;
00262     }
00263     return (*j).second;
00264 }
00265 
00266 void
00267 NIVissimTL::NIVissimTLSignalGroup::clearDict() {
00268     for (GroupDictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
00269         for (SGroupDictType::iterator j = (*i).second.begin(); j != (*i).second.end(); j++) {
00270             delete(*j).second;
00271         }
00272     }
00273     myDict.clear();
00274 }
00275 
00276 
00277 NIVissimTL::SGroupDictType
00278 NIVissimTL::NIVissimTLSignalGroup::getGroupsFor(int tlid) {
00279     GroupDictType::iterator i = myDict.find(tlid);
00280     if (i == myDict.end()) {
00281         return SGroupDictType();
00282     }
00283     return (*i).second;
00284 }
00285 
00286 
00287 bool
00288 NIVissimTL::NIVissimTLSignalGroup::addTo(NBLoadedTLDef* tl) const {
00289     // get the color at the begin
00290     NBTrafficLightDefinition::TLColor color = myFirstIsRed
00291             ? NBTrafficLightDefinition::TLCOLOR_RED : NBTrafficLightDefinition::TLCOLOR_GREEN;
00292     std::string id = toString<int>(myID);
00293     tl->addSignalGroup(id); // !!! myTimes als SUMOTime
00294     for (std::vector<SUMOReal>::const_iterator i = myTimes.begin(); i != myTimes.end(); i++) {
00295         tl->addSignalGroupPhaseBegin(id, (SUMOTime) *i, color);
00296         color = color == NBTrafficLightDefinition::TLCOLOR_RED
00297                 ? NBTrafficLightDefinition::TLCOLOR_GREEN : NBTrafficLightDefinition::TLCOLOR_RED;
00298     }
00299     if (myTimes.size() == 0) {
00300         if (myFirstIsRed) {
00301             tl->addSignalGroupPhaseBegin(id, 0, NBTrafficLightDefinition::TLCOLOR_RED);
00302         } else {
00303             tl->addSignalGroupPhaseBegin(id, 0, NBTrafficLightDefinition::TLCOLOR_GREEN);
00304         }
00305     }
00306     tl->setSignalYellowTimes(id, myTRedYellow, myTYellow);
00307     return true;
00308 }
00309 
00310 
00311 
00312 
00313 
00314 
00315 
00316 
00317 NIVissimTL::DictType NIVissimTL::myDict;
00318 
00319 NIVissimTL::NIVissimTL(int id, const std::string& type,
00320                        const std::string& name, SUMOTime absdur,
00321                        SUMOTime offset)
00322     : myID(id), myName(name), myAbsDuration(absdur), myOffset(offset),
00323       myCurrentGroup(0), myType(type)
00324 
00325 {}
00326 
00327 
00328 NIVissimTL::~NIVissimTL() {}
00329 
00330 
00331 
00332 
00333 
00334 bool
00335 NIVissimTL::dictionary(int id, const std::string& type,
00336                        const std::string& name, SUMOTime absdur,
00337                        SUMOTime offset) {
00338     NIVissimTL* o = new NIVissimTL(id, type, name, absdur, offset);
00339     if (!dictionary(id, o)) {
00340         delete o;
00341         return false;
00342     }
00343     return true;
00344 }
00345 
00346 bool
00347 NIVissimTL::dictionary(int id, NIVissimTL* o) {
00348     DictType::iterator i = myDict.find(id);
00349     if (i == myDict.end()) {
00350         myDict[id] = o;
00351         return true;
00352     }
00353     return false;
00354 }
00355 
00356 
00357 NIVissimTL*
00358 NIVissimTL::dictionary(int id) {
00359     DictType::iterator i = myDict.find(id);
00360     if (i == myDict.end()) {
00361         return 0;
00362     }
00363     return (*i).second;
00364 }
00365 
00366 
00367 void
00368 NIVissimTL::clearDict() {
00369     for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
00370         delete(*i).second;
00371     }
00372     myDict.clear();
00373 }
00374 
00375 
00376 
00377 
00378 
00379 bool
00380 NIVissimTL::dict_SetSignals(NBTrafficLightLogicCont& tlc,
00381                             NBEdgeCont& ec) {
00382     size_t ref = 0;
00383     size_t ref_groups = 0;
00384     size_t ref_signals = 0;
00385     size_t no_signals = 0;
00386     size_t no_groups = 0;
00387     for (DictType::iterator i = myDict.begin(); i != myDict.end(); i++) {
00388         NIVissimTL* tl = (*i).second;
00389         /*      if(tl->myType!="festzeit") {
00390                     cout << " Warning: The traffic light '" << tl->myID
00391                         << "' could not be assigned to a node." << endl;
00392                     ref++;
00393                     continue;
00394                 }*/
00395         std::string id = toString<int>(tl->myID);
00396         NBLoadedTLDef* def = new NBLoadedTLDef(id);
00397         if (!tlc.insert(def)) {
00398             WRITE_ERROR("Error on adding a traffic light\n Must be a multiple id ('" + id + "')");
00399             continue;
00400         }
00401         def->setCycleDuration((unsigned int) tl->myAbsDuration);
00402         // add each group to the node's container
00403         SGroupDictType sgs = NIVissimTLSignalGroup::getGroupsFor(tl->getID());
00404         for (SGroupDictType::const_iterator j = sgs.begin(); j != sgs.end(); j++) {
00405             if (!(*j).second->addTo(def)) {
00406                 WRITE_WARNING("The signal group '" + toString<int>((*j).first) + "' could not be assigned to tl '" + toString<int>(tl->myID) + "'.");
00407                 ref_groups++;
00408             }
00409             no_groups++;
00410         }
00411         // add the signal group signals to the node
00412         SSignalDictType signals = NIVissimTLSignal::getSignalsFor(tl->getID());
00413         for (SSignalDictType::const_iterator k = signals.begin(); k != signals.end(); k++) {
00414             if (!(*k).second->addTo(ec, def)) {
00415                 WRITE_WARNING("The signal '" + toString<int>((*k).first) + "' could not be assigned to tl '" + toString<int>(tl->myID) + "'.");
00416                 ref_signals++;
00417             }
00418             no_signals++;
00419         }
00420     }
00421     if (ref != 0) {
00422         WRITE_WARNING("Could not set " + toString<size_t>(ref) + " of " + toString<size_t>(myDict.size()) + " traffic lights.");
00423     }
00424     if (ref_groups != 0) {
00425         WRITE_WARNING("Could not set " + toString<size_t>(ref_groups) + " of " + toString<size_t>(no_groups) + " groups.");
00426     }
00427     if (ref_signals != 0) {
00428         WRITE_WARNING("Could not set " + toString<size_t>(ref_signals) + " of " + toString<size_t>(no_signals) + " signals.");
00429     }
00430     return true;
00431 
00432 }
00433 
00434 
00435 std::string
00436 NIVissimTL::getType() const {
00437     return myType;
00438 }
00439 
00440 
00441 int
00442 NIVissimTL::getID() const {
00443     return myID;
00444 }
00445 
00446 
00447 
00448 /****************************************************************************/
00449 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines