SUMO - Simulation of Urban MObility

GUINet.cpp

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