SUMO - Simulation of Urban MObility
GUINet.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00010 // A MSNet extended by some values for usage within the gui
00011 /****************************************************************************/
00012 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00013 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00014 /****************************************************************************/
00015 //
00016 //   This file is part of SUMO.
00017 //   SUMO is free software: you can redistribute it and/or modify
00018 //   it under the terms of the GNU General Public License as published by
00019 //   the Free Software Foundation, either version 3 of the License, or
00020 //   (at your option) any later version.
00021 //
00022 /****************************************************************************/
00023 // ===========================================================================
00024 // included modules
00025 // ===========================================================================
00026 #ifdef _MSC_VER
00027 #include <windows_config.h>
00028 #else
00029 #include <config.h>
00030 #endif
00031 
00032 #include <utility>
00033 #include <set>
00034 #include <vector>
00035 #include <map>
00036 #include <utils/shapes/ShapeContainer.h>
00037 #include <utils/gui/globjects/GUIPolygon.h>
00038 #include <utils/gui/globjects/GUIPointOfInterest.h>
00039 #include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
00040 #include <utils/gui/div/GUIParameterTableWindow.h>
00041 #include <utils/common/StringUtils.h>
00042 #include <utils/common/RGBColor.h>
00043 #include <utils/gui/div/GLObjectValuePassConnector.h>
00044 #include <microsim/MSNet.h>
00045 #include <microsim/MSJunction.h>
00046 #include <microsim/output/MSDetectorControl.h>
00047 #include <microsim/MSEdge.h>
00048 #include <microsim/MSVehicleTransfer.h>
00049 #include <microsim/MSVehicle.h>
00050 #include <microsim/MSInsertionControl.h>
00051 #include <microsim/traffic_lights/MSTrafficLightLogic.h>
00052 #include <microsim/traffic_lights/MSTLLogicControl.h>
00053 #include <microsim/MSJunctionControl.h>
00054 #include <microsim/MSRouteLoader.h>
00055 #include <guisim/GUIEdge.h>
00056 #include <guisim/GUILaneSpeedTrigger.h>
00057 #include <guisim/GUIDetectorWrapper.h>
00058 #include <guisim/GUITrafficLightLogicWrapper.h>
00059 #include <guisim/GUIJunctionWrapper.h>
00060 #include <guisim/GUIVehicleControl.h>
00061 #include <gui/GUIGlobals.h>
00062 #include "GUIVehicle.h"
00063 #include "GUINet.h"
00064 #include "GUIShapeContainer.h"
00065 
00066 #ifdef CHECK_MEMORY_LEAKS
00067 #include <foreign/nvwa/debug_new.h>
00068 #endif // CHECK_MEMORY_LEAKS
00069 
00070 
00071 // ===========================================================================
00072 // definition of static variables used for visualisation of objects' values
00073 // ===========================================================================
00074 template std::vector< GLObjectValuePassConnector<SUMOReal>* > GLObjectValuePassConnector<SUMOReal>::myContainer;
00075 template MFXMutex GLObjectValuePassConnector<SUMOReal>::myLock;
00076 
00077 template std::vector< GLObjectValuePassConnector<std::pair<int, class MSPhaseDefinition> >* > GLObjectValuePassConnector<std::pair<int, class MSPhaseDefinition> >::myContainer;
00078 template MFXMutex GLObjectValuePassConnector<std::pair<int, class MSPhaseDefinition> >::myLock;
00079 
00080 
00081 // ===========================================================================
00082 // member method definitions
00083 // ===========================================================================
00084 GUINet::GUINet(MSVehicleControl* vc, MSEventControl* beginOfTimestepEvents,
00085                MSEventControl* endOfTimestepEvents, MSEventControl* insertionEvents) :
00086     MSNet(vc, beginOfTimestepEvents, endOfTimestepEvents, insertionEvents, new GUIShapeContainer(myGrid)),
00087     GUIGlObject(GLO_NETWORK, ""),
00088     myLastSimDuration(0), /*myLastVisDuration(0),*/ myLastIdleDuration(0),
00089     myLastVehicleMovementCount(0), myOverallVehicleCount(0), myOverallSimDuration(0) {
00090     GUIGlObjectStorage::gIDStorage.setNetObject(this);
00091 }
00092 
00093 
00094 GUINet::~GUINet() {
00095     // delete allocated wrappers
00096     //  of junctions
00097     for (std::vector<GUIJunctionWrapper*>::iterator i1 = myJunctionWrapper.begin(); i1 != myJunctionWrapper.end(); i1++) {
00098         delete(*i1);
00099     }
00100     //  of additional structures
00101     GUIGlObject_AbstractAdd::clearDictionary();
00102     //  of tl-logics
00103     for (Logics2WrapperMap::iterator i3 = myLogics2Wrapper.begin(); i3 != myLogics2Wrapper.end(); i3++) {
00104         delete(*i3).second;
00105     }
00106     //  of detectors
00107     for (std::vector<GUIDetectorWrapper*>::iterator i = myDetectorDict.begin(); i != myDetectorDict.end(); ++i) {
00108         delete *i;
00109     }
00110 }
00111 
00112 
00113 const Boundary&
00114 GUINet::getBoundary() const {
00115     return myBoundary;
00116 }
00117 
00118 
00119 
00120 void
00121 GUINet::initTLMap() {
00122     // get the list of loaded tl-logics
00123     const std::vector<MSTrafficLightLogic*> &logics = getTLSControl().getAllLogics();
00124     // allocate storage for the wrappers
00125     myTLLogicWrappers.reserve(logics.size());
00126     // go through the logics
00127     for (std::vector<MSTrafficLightLogic*>::const_iterator i = logics.begin(); i != logics.end(); ++i) {
00128         createTLWrapper(*i);
00129     }
00130 }
00131 
00132 
00133 GUIGlID
00134 GUINet::createTLWrapper(MSTrafficLightLogic* tll) {
00135     if (myLogics2Wrapper.count(tll) > 0) {
00136         return myLogics2Wrapper[tll]->getGlID();
00137     }
00138     // get the links
00139     const MSTrafficLightLogic::LinkVectorVector& links = tll->getLinks();
00140     if (links.size() == 0) { // @legacy this should never happen in 0.13.0+ networks
00141         return 0;
00142     }
00143     // build the wrapper
00144     GUITrafficLightLogicWrapper* tllw =
00145         new GUITrafficLightLogicWrapper(*myLogics, *tll);
00146     // build the association link->wrapper
00147     MSTrafficLightLogic::LinkVectorVector::const_iterator j;
00148     for (j = links.begin(); j != links.end(); j++) {
00149         MSTrafficLightLogic::LinkVector::const_iterator j2;
00150         for (j2 = (*j).begin(); j2 != (*j).end(); j2++) {
00151             myLinks2Logic[*j2] = tll->getID();
00152         }
00153     }
00154     myGrid.addAdditionalGLObject(tllw);
00155     myLogics2Wrapper[tll] = tllw;
00156     return tllw->getGlID();
00157 }
00158 
00159 
00160 Position
00161 GUINet::getJunctionPosition(const std::string& name) const {
00162     // !!! no check for existance!
00163     return myJunctions->get(name)->getPosition();
00164 }
00165 
00166 
00167 bool
00168 GUINet::vehicleExists(const std::string& name) const {
00169     return myVehicleControl->getVehicle(name) != 0;
00170 }
00171 
00172 
00173 Boundary
00174 GUINet::getEdgeBoundary(const std::string& name) const {
00175     GUIEdge* edge = static_cast<GUIEdge*>(MSEdge::dictionary(name));
00176     return edge->getBoundary();
00177 }
00178 
00179 
00180 unsigned int
00181 GUINet::getLinkTLID(MSLink* link) const {
00182     if (myLinks2Logic.count(link) == 0) {
00183         assert(false);
00184         return 0;
00185     }
00186     MSTrafficLightLogic* tll = myLogics->getActive(myLinks2Logic.find(link)->second);
00187     if (myLogics2Wrapper.count(tll) == 0) {
00188         // tll may have been added via traci. @see ticket #459
00189         return 0;
00190     }
00191     return myLogics2Wrapper.find(tll)->second->getGlID();
00192 }
00193 
00194 
00195 int
00196 GUINet::getLinkTLIndex(MSLink* link) const {
00197     Links2LogicMap::const_iterator i = myLinks2Logic.find(link);
00198     if (i == myLinks2Logic.end()) {
00199         return -1;
00200     }
00201     if (myLogics2Wrapper.find(myLogics->getActive((*i).second)) == myLogics2Wrapper.end()) {
00202         return -1;
00203     }
00204     return myLogics2Wrapper.find(myLogics->getActive((*i).second))->second->getLinkIndex(link);
00205 }
00206 
00207 
00208 void
00209 GUINet::guiSimulationStep() {
00210     GLObjectValuePassConnector<SUMOReal>::updateAll();
00211     GLObjectValuePassConnector<std::pair<SUMOTime, MSPhaseDefinition> >::updateAll();
00212 }
00213 
00214 
00215 std::vector<GUIGlID>
00216 GUINet::getJunctionIDs(bool includeInternal) const {
00217     std::vector<GUIGlID> ret;
00218     for (std::vector<GUIJunctionWrapper*>::const_iterator i = myJunctionWrapper.begin(); i != myJunctionWrapper.end(); ++i) {
00219         if (!(*i)->isInner() || includeInternal) {
00220             ret.push_back((*i)->getGlID());
00221         }
00222     }
00223     return ret;
00224 }
00225 
00226 
00227 std::vector<GUIGlID>
00228 GUINet::getTLSIDs() const {
00229     std::vector<GUIGlID> ret;
00230     std::vector<std::string> ids;
00231     for (std::map<MSTrafficLightLogic*, GUITrafficLightLogicWrapper*>::const_iterator i = myLogics2Wrapper.begin(); i != myLogics2Wrapper.end(); ++i) {
00232         std::string sid = (*i).second->getMicrosimID();
00233         if (find(ids.begin(), ids.end(), sid) == ids.end()) {
00234             ret.push_back((*i).second->getGlID());
00235             ids.push_back(sid);
00236         }
00237     }
00238     return ret;
00239 }
00240 
00241 
00242 void
00243 GUINet::initGUIStructures() {
00244     // initialise detector storage for gui
00245     for (std::map<SumoXMLTag, NamedObjectCont<MSDetectorFileOutput*> >::const_iterator i = myDetectorControl->myDetectors.begin(); i != myDetectorControl->myDetectors.end(); ++i) {
00246         const std::map<std::string, MSDetectorFileOutput*> &dets = myDetectorControl->getTypedDetectors((*i).first).getMyMap();
00247         for (std::map<std::string, MSDetectorFileOutput*>::const_iterator j = dets.begin(); j != dets.end(); ++j) {
00248             GUIDetectorWrapper* wrapper = (*j).second->buildDetectorGUIRepresentation();
00249             if (wrapper != 0) {
00250                 myDetectorDict.push_back(wrapper);
00251                 myGrid.addAdditionalGLObject(wrapper);
00252             }
00253         }
00254     }
00255     // initialise the tl-map
00256     initTLMap();
00257     // initialise edge storage for gui
00258     GUIEdge::fill(myEdgeWrapper);
00259     // initialise junction storage for gui
00260     size_t size = myJunctions->size();
00261     myJunctionWrapper.reserve(size);
00262     const std::map<std::string, MSJunction*> &junctions = myJunctions->getMyMap();
00263     for (std::map<std::string, MSJunction*>::const_iterator i = junctions.begin(); i != junctions.end(); ++i) {
00264         myJunctionWrapper.push_back(new GUIJunctionWrapper(*(*i).second));
00265     }
00266     // build the visualization tree
00267     float* cmin = new float[2];
00268     float* cmax = new float[2];
00269     for (std::vector<GUIEdge*>::iterator i = myEdgeWrapper.begin(); i != myEdgeWrapper.end(); ++i) {
00270         GUIEdge* edge = *i;
00271         Boundary b;
00272         const std::vector<MSLane*> &lanes = edge->getLanes();
00273         for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
00274             b.add((*j)->getShape().getBoxBoundary());
00275         }
00276         b.grow(2.);
00277         cmin[0] = b.xmin();
00278         cmin[1] = b.ymin();
00279         cmax[0] = b.xmax();
00280         cmax[1] = b.ymax();
00281         myGrid.Insert(cmin, cmax, edge);
00282         myBoundary.add(b);
00283         if (myBoundary.getWidth() > 10e16 || myBoundary.getHeight() > 10e16) {
00284             throw ProcessError("Network size exceeds 1 Lightyear. Please reconsider your inputs.\n");
00285         }
00286     }
00287     for (std::vector<GUIJunctionWrapper*>::iterator i = myJunctionWrapper.begin(); i != myJunctionWrapper.end(); ++i) {
00288         GUIJunctionWrapper* junction = *i;
00289         Boundary b = junction->getBoundary();
00290         b.grow(2.);
00291         cmin[0] = b.xmin();
00292         cmin[1] = b.ymin();
00293         cmax[0] = b.xmax();
00294         cmax[1] = b.ymax();
00295         myGrid.Insert(cmin, cmax, junction);
00296         myBoundary.add(b);
00297     }
00298     delete[] cmin;
00299     delete[] cmax;
00300     myGrid.add(myBoundary);
00301 }
00302 
00303 
00304 unsigned int
00305 GUINet::getWholeDuration() const {
00306     return myLastSimDuration +/*myLastVisDuration+*/myLastIdleDuration;
00307 }
00308 
00309 
00310 unsigned int
00311 GUINet::getSimDuration() const {
00312     return myLastSimDuration;
00313 }
00314 
00315 /*
00316 int
00317 GUINet::getVisDuration() const
00318 {
00319     return myLastVisDuration;
00320 }
00321 */
00322 
00323 
00324 SUMOReal
00325 GUINet::getRTFactor() const {
00326     if (myLastSimDuration == 0) {
00327         return -1;
00328     }
00329     return (SUMOReal) 1000. / (SUMOReal) myLastSimDuration;
00330 }
00331 
00332 
00333 SUMOReal
00334 GUINet::getUPS() const {
00335     if (myLastSimDuration == 0) {
00336         return -1;
00337     }
00338     return (SUMOReal) myLastVehicleMovementCount / (SUMOReal) myLastSimDuration * (SUMOReal) 1000.;
00339 }
00340 
00341 
00342 SUMOReal
00343 GUINet::getMeanRTFactor(int duration) const {
00344     if (myOverallSimDuration == 0) {
00345         return -1;
00346     }
00347     return ((SUMOReal)(duration) * (SUMOReal) 1000. / (SUMOReal)myOverallSimDuration);
00348 }
00349 
00350 
00351 SUMOReal
00352 GUINet::getMeanUPS() const {
00353     if (myOverallSimDuration == 0) {
00354         return -1;
00355     }
00356     return ((SUMOReal)myVehiclesMoved / (SUMOReal)myOverallSimDuration * (SUMOReal) 1000.);
00357 }
00358 
00359 
00360 unsigned int
00361 GUINet::getIdleDuration() const {
00362     return myLastIdleDuration;
00363 }
00364 
00365 
00366 void
00367 GUINet::setSimDuration(int val) {
00368     myLastSimDuration = val;
00369     myOverallSimDuration += val;
00370     myLastVehicleMovementCount = getVehicleControl().getRunningVehicleNo();
00371     myOverallVehicleCount += myLastVehicleMovementCount;
00372 }
00373 
00374 /*
00375 void
00376 GUINet::setVisDuration(int val)
00377 {
00378     myLastVisDuration = val;
00379 }
00380 */
00381 
00382 void
00383 GUINet::setIdleDuration(int val) {
00384     myLastIdleDuration = val;
00385 }
00386 
00387 
00388 GUIGLObjectPopupMenu*
00389 GUINet::getPopUpMenu(GUIMainWindow& app,
00390                      GUISUMOAbstractView& parent) {
00391     GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
00392     buildPopupHeader(ret, app);
00393     buildCenterPopupEntry(ret);
00394     buildShowParamsPopupEntry(ret);
00395     buildPositionCopyEntry(ret, false);
00396     return ret;
00397 }
00398 
00399 
00400 GUIParameterTableWindow*
00401 GUINet::getParameterWindow(GUIMainWindow& app,
00402                            GUISUMOAbstractView&) {
00403     GUIParameterTableWindow* ret =
00404         new GUIParameterTableWindow(app, *this, 13);
00405     // add items
00406     ret->mkItem("loaded vehicles [#]", true,
00407                 new FunctionBinding<MSVehicleControl, unsigned int>(&getVehicleControl(), &MSVehicleControl::getLoadedVehicleNo));
00408     ret->mkItem("waiting vehicles [#]", true,
00409                 new FunctionBinding<MSInsertionControl, unsigned int>(&getInsertionControl(), &MSInsertionControl::getWaitingVehicleNo));
00410     ret->mkItem("departed vehicles [#]", true,
00411                 new FunctionBinding<MSVehicleControl, unsigned int>(&getVehicleControl(), &MSVehicleControl::getDepartedVehicleNo));
00412     ret->mkItem("running vehicles [#]", true,
00413                 new FunctionBinding<MSVehicleControl, unsigned int>(&getVehicleControl(), &MSVehicleControl::getRunningVehicleNo));
00414     ret->mkItem("arrived vehicles [#]", true,
00415                 new FunctionBinding<MSVehicleControl, unsigned int>(&getVehicleControl(), &MSVehicleControl::getEndedVehicleNo));
00416     ret->mkItem("end time [s]", false, OptionsCont::getOptions().getString("end"));
00417     ret->mkItem("begin time [s]", false, OptionsCont::getOptions().getString("begin"));
00418 //    ret->mkItem("time step [s]", true, new FunctionBinding<GUINet, SUMOTime>(this, &GUINet::getCurrentTimeStep));
00419     if (logSimulationDuration()) {
00420         ret->mkItem("step duration [ms]", true, new FunctionBinding<GUINet, unsigned int>(this, &GUINet::getWholeDuration));
00421         ret->mkItem("simulation duration [ms]", true, new FunctionBinding<GUINet, unsigned int>(this, &GUINet::getSimDuration));
00422         /*
00423         ret->mkItem("visualisation duration [ms]", true,
00424             new CastingFunctionBinding<GUINet, SUMOReal, int>(
00425                 &(getNet()), &GUINet::getVisDuration));
00426         */
00427         ret->mkItem("idle duration [ms]", true, new FunctionBinding<GUINet, unsigned int>(this, &GUINet::getIdleDuration));
00428         ret->mkItem("duration factor []", true, new FunctionBinding<GUINet, SUMOReal>(this, &GUINet::getRTFactor));
00429         /*
00430         ret->mkItem("mean duration factor []", true,
00431             new FuncBinding_IntParam<GUINet, SUMOReal>(
00432                 &(getNet()), &GUINet::getMeanRTFactor), 1);
00433                 */
00434         ret->mkItem("ups [#]", true, new FunctionBinding<GUINet, SUMOReal>(this, &GUINet::getUPS));
00435         ret->mkItem("mean ups [#]", true, new FunctionBinding<GUINet, SUMOReal>(this, &GUINet::getMeanUPS));
00436     }
00437     // close building
00438     ret->closeBuilding();
00439     return ret;
00440 }
00441 
00442 
00443 void
00444 GUINet::drawGL(const GUIVisualizationSettings& /*s*/) const {
00445 }
00446 
00447 Boundary
00448 GUINet::getCenteringBoundary() const {
00449     return getBoundary();
00450 }
00451 
00452 
00453 GUINet*
00454 GUINet::getGUIInstance() {
00455     GUINet* net = dynamic_cast<GUINet*>(MSNet::getInstance());
00456     if (net != 0) {
00457         return net;
00458     }
00459     throw ProcessError("A gui-network was not yet constructed.");
00460 }
00461 
00462 /****************************************************************************/
00463 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines