SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GUINet.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // A MSNet extended by some values for usage within the gui
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
13 // Copyright (C) 2001-2013 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #ifdef _MSC_VER
27 #include <windows_config.h>
28 #else
29 #include <config.h>
30 #endif
31 
32 #include <utility>
33 #include <set>
34 #include <vector>
35 #include <map>
42 #include <utils/common/RGBColor.h>
44 #include <microsim/MSNet.h>
45 #include <microsim/MSJunction.h>
47 #include <microsim/MSEdge.h>
52 #include <guisim/GUIEdge.h>
59 #include <gui/GUIGlobals.h>
60 #include "GUINet.h"
61 #include "GUIShapeContainer.h"
62 
63 #ifdef HAVE_INTERNAL
64 #include <mesogui/GUIMEVehicleControl.h>
65 #endif
66 
67 #ifdef CHECK_MEMORY_LEAKS
68 #include <foreign/nvwa/debug_new.h>
69 #endif // CHECK_MEMORY_LEAKS
70 
71 
72 // ===========================================================================
73 // definition of static variables used for visualisation of objects' values
74 // ===========================================================================
75 template std::vector< GLObjectValuePassConnector<SUMOReal>* > GLObjectValuePassConnector<SUMOReal>::myContainer;
77 
78 template std::vector< GLObjectValuePassConnector<std::pair<int, class MSPhaseDefinition> >* > GLObjectValuePassConnector<std::pair<int, class MSPhaseDefinition> >::myContainer;
80 
81 
82 // ===========================================================================
83 // member method definitions
84 // ===========================================================================
85 GUINet::GUINet(MSVehicleControl* vc, MSEventControl* beginOfTimestepEvents,
86  MSEventControl* endOfTimestepEvents, MSEventControl* insertionEvents) :
87  MSNet(vc, beginOfTimestepEvents, endOfTimestepEvents, insertionEvents, new GUIShapeContainer(myGrid)),
89  myLastSimDuration(0), /*myLastVisDuration(0),*/ myLastIdleDuration(0),
90  myLastVehicleMovementCount(0), myOverallVehicleCount(0), myOverallSimDuration(0) {
92 }
93 
94 
96  if (myLock.locked()) {
97  myLock.unlock();
98  }
99  // delete allocated wrappers
100  // of junctions
101  for (std::vector<GUIJunctionWrapper*>::iterator i1 = myJunctionWrapper.begin(); i1 != myJunctionWrapper.end(); i1++) {
102  delete(*i1);
103  }
104  // of additional structures
106  // of tl-logics
107  for (Logics2WrapperMap::iterator i3 = myLogics2Wrapper.begin(); i3 != myLogics2Wrapper.end(); i3++) {
108  delete(*i3).second;
109  }
110  // of detectors
111  for (std::vector<GUIDetectorWrapper*>::iterator i = myDetectorDict.begin(); i != myDetectorDict.end(); ++i) {
112  delete *i;
113  }
114 }
115 
116 
117 const Boundary&
119  return myBoundary;
120 }
121 
122 
125  if (myPersonControl == 0) {
127  }
128  return *myPersonControl;
129 }
130 
131 
132 void
134  // get the list of loaded tl-logics
135  const std::vector<MSTrafficLightLogic*>& logics = getTLSControl().getAllLogics();
136  // allocate storage for the wrappers
137  myTLLogicWrappers.reserve(logics.size());
138  // go through the logics
139  for (std::vector<MSTrafficLightLogic*>::const_iterator i = logics.begin(); i != logics.end(); ++i) {
140  createTLWrapper(*i);
141  }
142 }
143 
144 
145 GUIGlID
147  if (myLogics2Wrapper.count(tll) > 0) {
148  return myLogics2Wrapper[tll]->getGlID();
149  }
150  // get the links
151  const MSTrafficLightLogic::LinkVectorVector& links = tll->getLinks();
152  if (links.size() == 0) { // @legacy this should never happen in 0.13.0+ networks
153  return 0;
154  }
155  // build the wrapper
158  // build the association link->wrapper
159  MSTrafficLightLogic::LinkVectorVector::const_iterator j;
160  for (j = links.begin(); j != links.end(); ++j) {
161  MSTrafficLightLogic::LinkVector::const_iterator j2;
162  for (j2 = (*j).begin(); j2 != (*j).end(); ++j2) {
163  myLinks2Logic[*j2] = tll->getID();
164  }
165  }
167  myLogics2Wrapper[tll] = tllw;
168  return tllw->getGlID();
169 }
170 
171 
172 Position
173 GUINet::getJunctionPosition(const std::string& name) const {
174  // !!! no check for existance!
175  return myJunctions->get(name)->getPosition();
176 }
177 
178 
179 bool
180 GUINet::vehicleExists(const std::string& name) const {
181  return myVehicleControl->getVehicle(name) != 0;
182 }
183 
184 
185 unsigned int
187  if (myLinks2Logic.count(link) == 0) {
188  assert(false);
189  return 0;
190  }
191  MSTrafficLightLogic* tll = myLogics->getActive(myLinks2Logic.find(link)->second);
192  if (myLogics2Wrapper.count(tll) == 0) {
193  // tll may have been added via traci. @see ticket #459
194  return 0;
195  }
196  return myLogics2Wrapper.find(tll)->second->getGlID();
197 }
198 
199 
200 int
202  Links2LogicMap::const_iterator i = myLinks2Logic.find(link);
203  if (i == myLinks2Logic.end()) {
204  return -1;
205  }
206  if (myLogics2Wrapper.find(myLogics->getActive((*i).second)) == myLogics2Wrapper.end()) {
207  return -1;
208  }
209  return myLogics2Wrapper.find(myLogics->getActive((*i).second))->second->getLinkIndex(link);
210 }
211 
212 
213 void
217 }
218 
219 
220 void
224 }
225 
226 
227 std::vector<GUIGlID>
228 GUINet::getJunctionIDs(bool includeInternal) const {
229  std::vector<GUIGlID> ret;
230  for (std::vector<GUIJunctionWrapper*>::const_iterator i = myJunctionWrapper.begin(); i != myJunctionWrapper.end(); ++i) {
231  if (!(*i)->isInner() || includeInternal) {
232  ret.push_back((*i)->getGlID());
233  }
234  }
235  return ret;
236 }
237 
238 
239 std::vector<GUIGlID>
241  std::vector<GUIGlID> ret;
242  std::vector<std::string> ids;
243  for (std::map<MSTrafficLightLogic*, GUITrafficLightLogicWrapper*>::const_iterator i = myLogics2Wrapper.begin(); i != myLogics2Wrapper.end(); ++i) {
244  std::string sid = (*i).second->getMicrosimID();
245  if (find(ids.begin(), ids.end(), sid) == ids.end()) {
246  ret.push_back((*i).second->getGlID());
247  ids.push_back(sid);
248  }
249  }
250  return ret;
251 }
252 
253 
254 void
256  // initialise detector storage for gui
257  for (std::map<SumoXMLTag, NamedObjectCont<MSDetectorFileOutput*> >::const_iterator i = myDetectorControl->myDetectors.begin(); i != myDetectorControl->myDetectors.end(); ++i) {
258  const std::map<std::string, MSDetectorFileOutput*>& dets = myDetectorControl->getTypedDetectors((*i).first).getMyMap();
259  for (std::map<std::string, MSDetectorFileOutput*>::const_iterator j = dets.begin(); j != dets.end(); ++j) {
260  GUIDetectorWrapper* wrapper = (*j).second->buildDetectorGUIRepresentation();
261  if (wrapper != 0) {
262  myDetectorDict.push_back(wrapper);
263  myGrid.addAdditionalGLObject(wrapper);
264  }
265  }
266  }
267  // initialise the tl-map
268  initTLMap();
269  // initialise edge storage for gui
271  // initialise junction storage for gui
272  size_t size = myJunctions->size();
273  myJunctionWrapper.reserve(size);
274  const std::map<std::string, MSJunction*>& junctions = myJunctions->getMyMap();
275  for (std::map<std::string, MSJunction*>::const_iterator i = junctions.begin(); i != junctions.end(); ++i) {
276  myJunctionWrapper.push_back(new GUIJunctionWrapper(*(*i).second));
277  }
278  // build the visualization tree
279  float* cmin = new float[2];
280  float* cmax = new float[2];
281  for (std::vector<GUIEdge*>::iterator i = myEdgeWrapper.begin(); i != myEdgeWrapper.end(); ++i) {
282  GUIEdge* edge = *i;
283  Boundary b;
284  const std::vector<MSLane*>& lanes = edge->getLanes();
285  for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
286  b.add((*j)->getShape().getBoxBoundary());
287  }
288  // make sure persons are always drawn and selectable since they depend on their edge being drawn
290  cmin[0] = b.xmin();
291  cmin[1] = b.ymin();
292  cmax[0] = b.xmax();
293  cmax[1] = b.ymax();
294  myGrid.Insert(cmin, cmax, edge);
295  myBoundary.add(b);
296  if (myBoundary.getWidth() > 10e16 || myBoundary.getHeight() > 10e16) {
297  throw ProcessError("Network size exceeds 1 Lightyear. Please reconsider your inputs.\n");
298  }
299  }
300  for (std::vector<GUIJunctionWrapper*>::iterator i = myJunctionWrapper.begin(); i != myJunctionWrapper.end(); ++i) {
301  GUIJunctionWrapper* junction = *i;
302  Boundary b = junction->getBoundary();
303  b.grow(2.);
304  cmin[0] = b.xmin();
305  cmin[1] = b.ymin();
306  cmax[0] = b.xmax();
307  cmax[1] = b.ymax();
308  myGrid.Insert(cmin, cmax, junction);
309  myBoundary.add(b);
310  }
311  delete[] cmin;
312  delete[] cmax;
314 }
315 
316 
317 unsigned int
319  return myLastSimDuration +/*myLastVisDuration+*/myLastIdleDuration;
320 }
321 
322 
323 unsigned int
325  return myLastSimDuration;
326 }
327 
328 /*
329 int
330 GUINet::getVisDuration() const
331 {
332  return myLastVisDuration;
333 }
334 */
335 
336 
337 SUMOReal
339  if (myLastSimDuration == 0) {
340  return -1;
341  }
342  return (SUMOReal) 1000. / (SUMOReal) myLastSimDuration;
343 }
344 
345 
346 SUMOReal
347 GUINet::getUPS() const {
348  if (myLastSimDuration == 0) {
349  return -1;
350  }
352 }
353 
354 
355 SUMOReal
356 GUINet::getMeanRTFactor(int duration) const {
357  if (myOverallSimDuration == 0) {
358  return -1;
359  }
360  return ((SUMOReal)(duration) * (SUMOReal) 1000. / (SUMOReal)myOverallSimDuration);
361 }
362 
363 
364 SUMOReal
366  if (myOverallSimDuration == 0) {
367  return -1;
368  }
370 }
371 
372 
373 unsigned int
375  return myLastIdleDuration;
376 }
377 
378 
379 void
381  myLastSimDuration = val;
382  myOverallSimDuration += val;
385 }
386 
387 /*
388 void
389 GUINet::setVisDuration(int val)
390 {
391  myLastVisDuration = val;
392 }
393 */
394 
395 void
397  myLastIdleDuration = val;
398 }
399 
400 
403  GUISUMOAbstractView& parent) {
404  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
405  buildPopupHeader(ret, app);
408  buildPositionCopyEntry(ret, false);
409  return ret;
410 }
411 
412 
417  new GUIParameterTableWindow(app, *this, 15);
418  // add items
419  ret->mkItem("loaded vehicles [#]", true,
421  ret->mkItem("waiting vehicles [#]", true,
423  ret->mkItem("departed vehicles [#]", true,
425  ret->mkItem("running vehicles [#]", true,
427  ret->mkItem("arrived vehicles [#]", true,
429  ret->mkItem("collisions [#]", true,
431  ret->mkItem("teleports [#]", true,
433  ret->mkItem("end time [s]", false, OptionsCont::getOptions().getString("end"));
434  ret->mkItem("begin time [s]", false, OptionsCont::getOptions().getString("begin"));
435 // ret->mkItem("time step [s]", true, new FunctionBinding<GUINet, SUMOTime>(this, &GUINet::getCurrentTimeStep));
436  if (logSimulationDuration()) {
437  ret->mkItem("step duration [ms]", true, new FunctionBinding<GUINet, unsigned int>(this, &GUINet::getWholeDuration));
438  ret->mkItem("simulation duration [ms]", true, new FunctionBinding<GUINet, unsigned int>(this, &GUINet::getSimDuration));
439  /*
440  ret->mkItem("visualisation duration [ms]", true,
441  new CastingFunctionBinding<GUINet, SUMOReal, int>(
442  &(getNet()), &GUINet::getVisDuration));
443  */
444  ret->mkItem("idle duration [ms]", true, new FunctionBinding<GUINet, unsigned int>(this, &GUINet::getIdleDuration));
445  ret->mkItem("duration factor []", true, new FunctionBinding<GUINet, SUMOReal>(this, &GUINet::getRTFactor));
446  /*
447  ret->mkItem("mean duration factor []", true,
448  new FuncBinding_IntParam<GUINet, SUMOReal>(
449  &(getNet()), &GUINet::getMeanRTFactor), 1);
450  */
451  ret->mkItem("ups [#]", true, new FunctionBinding<GUINet, SUMOReal>(this, &GUINet::getUPS));
452  ret->mkItem("mean ups [#]", true, new FunctionBinding<GUINet, SUMOReal>(this, &GUINet::getMeanUPS));
453  }
454  // close building
455  ret->closeBuilding();
456  return ret;
457 }
458 
459 
460 void
462 }
463 
464 Boundary
466  return getBoundary();
467 }
468 
469 
470 GUINet*
472  GUINet* net = dynamic_cast<GUINet*>(MSNet::getInstance());
473  if (net != 0) {
474  return net;
475  }
476  throw ProcessError("A gui-network was not yet constructed.");
477 }
478 
479 
482  return dynamic_cast<GUIVehicleControl*>(myVehicleControl);
483 }
484 
485 
486 void
488  myLock.lock();
489 }
490 
491 
492 void
494  myLock.unlock();
495 }
496 
497 #ifdef HAVE_INTERNAL
498 GUIMEVehicleControl*
499 GUINet::getGUIMEVehicleControl() {
500  return dynamic_cast<GUIMEVehicleControl*>(myVehicleControl);
501 }
502 #endif
503 
504 
505 #ifdef HAVE_OSG
506 void
507 GUINet::updateColor(const GUIVisualizationSettings& s) {
508  for (std::vector<GUIEdge*>::const_iterator i = myEdgeWrapper.begin(); i != myEdgeWrapper.end(); ++i) {
509  if ((*i)->getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL) {
510  const size_t numLanes = (*i)->getLanes().size();
511  for (size_t j = 0; j < numLanes; ++j) {
512  (*i)->getLaneGeometry(j).updateColor(s);
513  }
514  }
515  }
516  for (std::vector<GUIJunctionWrapper*>::iterator i = myJunctionWrapper.begin(); i != myJunctionWrapper.end(); ++i) {
517  (*i)->updateColor(s);
518  }
519 }
520 #endif
521 
522 /****************************************************************************/
523