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