SUMO - Simulation of Urban MObility
|
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