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