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-sim.org/
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>
53 #include <guisim/GUILane.h>
60 #include <gui/GUIGlobals.h>
61 #include "GUINet.h"
62 #include "GUIShapeContainer.h"
63 
64 #ifdef HAVE_INTERNAL
65 #include <mesogui/GUIMEVehicleControl.h>
66 #endif
67 
68 #ifdef CHECK_MEMORY_LEAKS
69 #include <foreign/nvwa/debug_new.h>
70 #endif // CHECK_MEMORY_LEAKS
71 
72 
73 // ===========================================================================
74 // definition of static variables used for visualisation of objects' values
75 // ===========================================================================
76 template std::vector< GLObjectValuePassConnector<SUMOReal>* > GLObjectValuePassConnector<SUMOReal>::myContainer;
78 
79 template std::vector< GLObjectValuePassConnector<std::pair<int, class MSPhaseDefinition> >* > GLObjectValuePassConnector<std::pair<int, class MSPhaseDefinition> >::myContainer;
81 
82 
83 // ===========================================================================
84 // member method definitions
85 // ===========================================================================
86 GUINet::GUINet(MSVehicleControl* vc, MSEventControl* beginOfTimestepEvents,
87  MSEventControl* endOfTimestepEvents, MSEventControl* insertionEvents) :
88  MSNet(vc, beginOfTimestepEvents, endOfTimestepEvents, insertionEvents, new GUIShapeContainer(myGrid)),
90  myLastSimDuration(0), /*myLastVisDuration(0),*/ myLastIdleDuration(0),
91  myLastVehicleMovementCount(0), myOverallVehicleCount(0), myOverallSimDuration(0) {
93 }
94 
95 
97  if (myLock.locked()) {
98  myLock.unlock();
99  }
100  // delete allocated wrappers
101  // of junctions
102  for (std::vector<GUIJunctionWrapper*>::iterator i1 = myJunctionWrapper.begin(); i1 != myJunctionWrapper.end(); i1++) {
103  delete(*i1);
104  }
105  // of additional structures
107  // of tl-logics
108  for (Logics2WrapperMap::iterator i3 = myLogics2Wrapper.begin(); i3 != myLogics2Wrapper.end(); i3++) {
109  delete(*i3).second;
110  }
111  // of detectors
112  for (std::vector<GUIDetectorWrapper*>::iterator i = myDetectorDict.begin(); i != myDetectorDict.end(); ++i) {
113  delete *i;
114  }
115 }
116 
117 
118 const Boundary&
120  return myBoundary;
121 }
122 
123 
126  if (myPersonControl == 0) {
128  }
129  return *myPersonControl;
130 }
131 
132 
133 void
135  // get the list of loaded tl-logics
136  const std::vector<MSTrafficLightLogic*>& logics = getTLSControl().getAllLogics();
137  // allocate storage for the wrappers
138  myTLLogicWrappers.reserve(logics.size());
139  // go through the logics
140  for (std::vector<MSTrafficLightLogic*>::const_iterator i = logics.begin(); i != logics.end(); ++i) {
141  createTLWrapper(*i);
142  }
143 }
144 
145 
146 GUIGlID
148  if (myLogics2Wrapper.count(tll) > 0) {
149  return myLogics2Wrapper[tll]->getGlID();
150  }
151  // get the links
152  const MSTrafficLightLogic::LinkVectorVector& links = tll->getLinks();
153  if (links.size() == 0) { // @legacy this should never happen in 0.13.0+ networks
154  return 0;
155  }
156  // build the wrapper
159  // build the association link->wrapper
160  MSTrafficLightLogic::LinkVectorVector::const_iterator j;
161  for (j = links.begin(); j != links.end(); ++j) {
162  MSTrafficLightLogic::LinkVector::const_iterator j2;
163  for (j2 = (*j).begin(); j2 != (*j).end(); ++j2) {
164  myLinks2Logic[*j2] = tll->getID();
165  }
166  }
168  myLogics2Wrapper[tll] = tllw;
169  return tllw->getGlID();
170 }
171 
172 
173 Position
174 GUINet::getJunctionPosition(const std::string& name) const {
175  // !!! no check for existance!
176  return myJunctions->get(name)->getPosition();
177 }
178 
179 
180 bool
181 GUINet::vehicleExists(const std::string& name) const {
182  return myVehicleControl->getVehicle(name) != 0;
183 }
184 
185 
186 unsigned int
188  if (myLinks2Logic.count(link) == 0) {
189  assert(false);
190  return 0;
191  }
192  MSTrafficLightLogic* tll = myLogics->getActive(myLinks2Logic.find(link)->second);
193  if (myLogics2Wrapper.count(tll) == 0) {
194  // tll may have been added via traci. @see ticket #459
195  return 0;
196  }
197  return myLogics2Wrapper.find(tll)->second->getGlID();
198 }
199 
200 
201 int
203  Links2LogicMap::const_iterator i = myLinks2Logic.find(link);
204  if (i == myLinks2Logic.end()) {
205  return -1;
206  }
207  if (myLogics2Wrapper.find(myLogics->getActive((*i).second)) == myLogics2Wrapper.end()) {
208  return -1;
209  }
210  return myLogics2Wrapper.find(myLogics->getActive((*i).second))->second->getLinkIndex(link);
211 }
212 
213 
214 void
218 }
219 
220 
221 void
225 }
226 
227 
228 std::vector<GUIGlID>
229 GUINet::getJunctionIDs(bool includeInternal) const {
230  std::vector<GUIGlID> ret;
231  for (std::vector<GUIJunctionWrapper*>::const_iterator i = myJunctionWrapper.begin(); i != myJunctionWrapper.end(); ++i) {
232  if (!(*i)->isInner() || includeInternal) {
233  ret.push_back((*i)->getGlID());
234  }
235  }
236  return ret;
237 }
238 
239 
240 std::vector<GUIGlID>
242  std::vector<GUIGlID> ret;
243  std::vector<std::string> ids;
244  for (std::map<MSTrafficLightLogic*, GUITrafficLightLogicWrapper*>::const_iterator i = myLogics2Wrapper.begin(); i != myLogics2Wrapper.end(); ++i) {
245  std::string sid = (*i).second->getMicrosimID();
246  if (find(ids.begin(), ids.end(), sid) == ids.end()) {
247  ret.push_back((*i).second->getGlID());
248  ids.push_back(sid);
249  }
250  }
251  return ret;
252 }
253 
254 
255 void
257  // initialise detector storage for gui
258  for (std::map<SumoXMLTag, NamedObjectCont<MSDetectorFileOutput*> >::const_iterator i = myDetectorControl->myDetectors.begin(); i != myDetectorControl->myDetectors.end(); ++i) {
259  const std::map<std::string, MSDetectorFileOutput*>& dets = myDetectorControl->getTypedDetectors((*i).first).getMyMap();
260  for (std::map<std::string, MSDetectorFileOutput*>::const_iterator j = dets.begin(); j != dets.end(); ++j) {
261  GUIDetectorWrapper* wrapper = (*j).second->buildDetectorGUIRepresentation();
262  if (wrapper != 0) {
263  myDetectorDict.push_back(wrapper);
264  myGrid.addAdditionalGLObject(wrapper);
265  }
266  }
267  }
268  // initialise the tl-map
269  initTLMap();
270  // initialise edge storage for gui
272  // initialise junction storage for gui
273  size_t size = myJunctions->size();
274  myJunctionWrapper.reserve(size);
275  const std::map<std::string, MSJunction*>& junctions = myJunctions->getMyMap();
276  for (std::map<std::string, MSJunction*>::const_iterator i = junctions.begin(); i != junctions.end(); ++i) {
277  myJunctionWrapper.push_back(new GUIJunctionWrapper(*(*i).second));
278  }
279  // build the visualization tree
280  float* cmin = new float[2];
281  float* cmax = new float[2];
282  for (std::vector<GUIEdge*>::iterator i = myEdgeWrapper.begin(); i != myEdgeWrapper.end(); ++i) {
283  GUIEdge* edge = *i;
284  Boundary b;
285  const std::vector<MSLane*>& lanes = edge->getLanes();
286  for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
287  b.add((*j)->getShape().getBoxBoundary());
288  }
289  // make sure persons are always drawn and selectable since they depend on their edge being drawn
291  cmin[0] = b.xmin();
292  cmin[1] = b.ymin();
293  cmax[0] = b.xmax();
294  cmax[1] = b.ymax();
295  myGrid.Insert(cmin, cmax, edge);
296  myBoundary.add(b);
297  if (myBoundary.getWidth() > 10e16 || myBoundary.getHeight() > 10e16) {
298  throw ProcessError("Network size exceeds 1 Lightyear. Please reconsider your inputs.\n");
299  }
300  }
301  for (std::vector<GUIJunctionWrapper*>::iterator i = myJunctionWrapper.begin(); i != myJunctionWrapper.end(); ++i) {
302  GUIJunctionWrapper* junction = *i;
303  Boundary b = junction->getBoundary();
304  b.grow(2.);
305  cmin[0] = b.xmin();
306  cmin[1] = b.ymin();
307  cmax[0] = b.xmax();
308  cmax[1] = b.ymax();
309  myGrid.Insert(cmin, cmax, junction);
310  myBoundary.add(b);
311  }
312  delete[] cmin;
313  delete[] cmax;
315 }
316 
317 
318 unsigned int
320  return myLastSimDuration +/*myLastVisDuration+*/myLastIdleDuration;
321 }
322 
323 
324 unsigned int
326  return myLastSimDuration;
327 }
328 
329 /*
330 int
331 GUINet::getVisDuration() const
332 {
333  return myLastVisDuration;
334 }
335 */
336 
337 
338 SUMOReal
340  if (myLastSimDuration == 0) {
341  return -1;
342  }
343  return (SUMOReal) 1000. / (SUMOReal) myLastSimDuration;
344 }
345 
346 
347 SUMOReal
348 GUINet::getUPS() const {
349  if (myLastSimDuration == 0) {
350  return -1;
351  }
353 }
354 
355 
356 SUMOReal
357 GUINet::getMeanRTFactor(int duration) const {
358  if (myOverallSimDuration == 0) {
359  return -1;
360  }
361  return ((SUMOReal)(duration) * (SUMOReal) 1000. / (SUMOReal)myOverallSimDuration);
362 }
363 
364 
365 SUMOReal
367  if (myOverallSimDuration == 0) {
368  return -1;
369  }
371 }
372 
373 
374 unsigned int
376  return myLastIdleDuration;
377 }
378 
379 
380 void
382  myLastSimDuration = val;
383  myOverallSimDuration += val;
386 }
387 
388 /*
389 void
390 GUINet::setVisDuration(int val)
391 {
392  myLastVisDuration = val;
393 }
394 */
395 
396 void
398  myLastIdleDuration = val;
399 }
400 
401 
404  GUISUMOAbstractView& parent) {
405  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
406  buildPopupHeader(ret, app);
409  buildPositionCopyEntry(ret, false);
410  return ret;
411 }
412 
413 
418  new GUIParameterTableWindow(app, *this, 15);
419  // add items
420  ret->mkItem("loaded vehicles [#]", true,
422  ret->mkItem("waiting vehicles [#]", true,
424  ret->mkItem("departed vehicles [#]", true,
426  ret->mkItem("running vehicles [#]", true,
428  ret->mkItem("arrived vehicles [#]", true,
430  ret->mkItem("collisions [#]", true,
432  ret->mkItem("teleports [#]", true,
434  ret->mkItem("end time [s]", false, OptionsCont::getOptions().getString("end"));
435  ret->mkItem("begin time [s]", false, OptionsCont::getOptions().getString("begin"));
436 // ret->mkItem("time step [s]", true, new FunctionBinding<GUINet, SUMOTime>(this, &GUINet::getCurrentTimeStep));
437  if (logSimulationDuration()) {
438  ret->mkItem("step duration [ms]", true, new FunctionBinding<GUINet, unsigned int>(this, &GUINet::getWholeDuration));
439  ret->mkItem("simulation duration [ms]", true, new FunctionBinding<GUINet, unsigned int>(this, &GUINet::getSimDuration));
440  /*
441  ret->mkItem("visualisation duration [ms]", true,
442  new CastingFunctionBinding<GUINet, SUMOReal, int>(
443  &(getNet()), &GUINet::getVisDuration));
444  */
445  ret->mkItem("idle duration [ms]", true, new FunctionBinding<GUINet, unsigned int>(this, &GUINet::getIdleDuration));
446  ret->mkItem("duration factor []", true, new FunctionBinding<GUINet, SUMOReal>(this, &GUINet::getRTFactor));
447  /*
448  ret->mkItem("mean duration factor []", true,
449  new FuncBinding_IntParam<GUINet, SUMOReal>(
450  &(getNet()), &GUINet::getMeanRTFactor), 1);
451  */
452  ret->mkItem("ups [#]", true, new FunctionBinding<GUINet, SUMOReal>(this, &GUINet::getUPS));
453  ret->mkItem("mean ups [#]", true, new FunctionBinding<GUINet, SUMOReal>(this, &GUINet::getMeanUPS));
454  }
455  // close building
456  ret->closeBuilding();
457  return ret;
458 }
459 
460 
461 void
463 }
464 
465 Boundary
467  return getBoundary();
468 }
469 
470 
471 GUINet*
473  GUINet* net = dynamic_cast<GUINet*>(MSNet::getInstance());
474  if (net != 0) {
475  return net;
476  }
477  throw ProcessError("A gui-network was not yet constructed.");
478 }
479 
480 
483  return dynamic_cast<GUIVehicleControl*>(myVehicleControl);
484 }
485 
486 
487 void
489  myLock.lock();
490 }
491 
492 
493 void
495  myLock.unlock();
496 }
497 
498 #ifdef HAVE_INTERNAL
499 GUIMEVehicleControl*
500 GUINet::getGUIMEVehicleControl() {
501  return dynamic_cast<GUIMEVehicleControl*>(myVehicleControl);
502 }
503 #endif
504 
505 
506 #ifdef HAVE_OSG
507 void
508 GUINet::updateColor(const GUIVisualizationSettings& s) {
509  for (std::vector<GUIEdge*>::const_iterator i = myEdgeWrapper.begin(); i != myEdgeWrapper.end(); ++i) {
510  if ((*i)->getPurpose() != MSEdge::EDGEFUNCTION_INTERNAL) {
511  const std::vector<MSLane*>& lanes = (*i)->getLanes();
512  for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
513  static_cast<GUILane*>(*j)->updateColor(s);
514  }
515  }
516  }
517  for (std::vector<GUIJunctionWrapper*>::iterator i = myJunctionWrapper.begin(); i != myJunctionWrapper.end(); ++i) {
518  (*i)->updateColor(s);
519  }
520 }
521 #endif
522 
523 /****************************************************************************/
524