Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.
4 : // This program and the accompanying materials are made available under the
5 : // terms of the Eclipse Public License 2.0 which is available at
6 : // https://www.eclipse.org/legal/epl-2.0/
7 : // This Source Code may also be made available under the following Secondary
8 : // Licenses when the conditions for such availability set forth in the Eclipse
9 : // Public License 2.0 are satisfied: GNU General Public License, version 2
10 : // or later which is available at
11 : // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 : // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 : /****************************************************************************/
14 : /// @file GUINet.h
15 : /// @author Daniel Krajzewicz
16 : /// @author Jakob Erdmann
17 : /// @author Michael Behrisch
18 : /// @date Sept 2002
19 : ///
20 : // A MSNet extended by some values for usage within the gui
21 : /****************************************************************************/
22 : #pragma once
23 : #include <config.h>
24 :
25 : #include <string>
26 : #include <utility>
27 : #include <microsim/MSNet.h>
28 : #include <microsim/devices/MSDevice_Tripinfo.h>
29 : #include <utils/geom/Boundary.h>
30 : #include <utils/geom/Position.h>
31 : #include <utils/xml/SUMOSAXHandler.h>
32 : #include <utils/xml/SAXWeightsHandler.h>
33 : #include <foreign/rtree/SUMORTree.h>
34 : #include <foreign/rtree/LayeredRTree.h>
35 : #include <utils/geom/PositionVector.h>
36 : #include <utils/gui/globjects/GUIGlObjectStorage.h>
37 : #include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
38 : #include <utils/gui/globjects/GUIGlObject.h>
39 : #include <utils/gui/globjects/GUIGlObject_AbstractAdd.h>
40 :
41 :
42 : // ===========================================================================
43 : // class declarations
44 : // ===========================================================================
45 : class MSEdgeControl;
46 : class MSJunctionControl;
47 : class MSTLLogicControl;
48 : class MSTrafficLightLogic;
49 : class MSLink;
50 : class GUIJunctionWrapper;
51 : class GUIDetectorWrapper;
52 : class GUICalibrator;
53 : class GUITrafficLightLogicWrapper;
54 : class RGBColor;
55 : class GUIEdge;
56 : class OutputDevice;
57 : class GUIVehicle;
58 : class GUIVehicleControl;
59 : class MSVehicleControl;
60 : class GUIMEVehicleControl;
61 : class Command;
62 :
63 :
64 : // ===========================================================================
65 : // class definitions
66 : // ===========================================================================
67 : /**
68 : * @class GUINet
69 : * @brief A MSNet extended by some values for usage within the gui
70 : *
71 : * This gui version of the network allows the retrieval of some more
72 : * information than the normal network version does. Due to this, not only
73 : * these retrieval, but also some further initialisation methods must have
74 : * been implemented. Nonethenless, this class has almost the same functions
75 : * as the MSNet-class.
76 : *
77 : * Some microsimulation items are wrapped in certain classes to allow their
78 : * drawing and their enumerated access. This enumeration is realised by
79 : * inserting the wrapped items into vectors and is needed to fasten the
80 : * network's drawing as only visible items are being drawn.
81 : */
82 : class GUINet : public MSNet, public GUIGlObject {
83 :
84 : friend class GUITrafficLightLogicWrapper; // see createTLWrapper
85 :
86 : public:
87 : /** @brief Constructor
88 : * @param[in] vc The vehicle control to use
89 : * @param[in] beginOfTimestepEvents The event control to use for simulation step begin events
90 : * @param[in] endOfTimestepEvents The event control to use for simulation step end events
91 : * @param[in] insertionEvents The event control to use for insertion events
92 : * @exception ProcessError If a network was already constructed
93 : */
94 : GUINet(MSVehicleControl* vc, MSEventControl* beginOfTimestepEvents,
95 : MSEventControl* endOfTimestepEvents,
96 : MSEventControl* insertionEvents);
97 :
98 :
99 : /// @brief Destructor
100 : ~GUINet();
101 :
102 :
103 : /**
104 : * @brief Returns whether this is a GUI Net
105 : */
106 29 : bool isGUINet() const override {
107 29 : return true;
108 : }
109 :
110 :
111 : /// @name inherited from GUIGlObject
112 : //@{
113 :
114 : /** @brief Returns an own popup-menu
115 : *
116 : * @param[in] app The application needed to build the popup-menu
117 : * @param[in] parent The parent window needed to build the popup-menu
118 : * @return The built popup-menu
119 : * @see GUIGlObject::getPopUpMenu
120 : */
121 : GUIGLObjectPopupMenu* getPopUpMenu(GUIMainWindow& app, GUISUMOAbstractView& parent) override;
122 :
123 : /** @brief Returns an own parameter window
124 : *
125 : * @param[in] app The application needed to build the parameter window
126 : * @param[in] parent The parent window needed to build the parameter window
127 : * @return The built parameter window
128 : * @see GUIGlObject::getParameterWindow
129 : */
130 : GUIParameterTableWindow* getParameterWindow(GUIMainWindow& app, GUISUMOAbstractView& parent) override;
131 :
132 : /** @brief Returns the boundary to which the view shall be centered in order to show the object
133 : *
134 : * @return The boundary the object is within
135 : * @see GUIGlObject::getCenteringBoundary
136 : */
137 : Boundary getCenteringBoundary() const override;
138 :
139 : /** @brief Draws the object
140 : * @param[in] s The settings for the current view (may influence drawing)
141 : * @see GUIGlObject::drawGL
142 : */
143 : void drawGL(const GUIVisualizationSettings& s) const override;
144 : //@}
145 :
146 :
147 : /// returns the bounder of the network
148 : const Boundary& getBoundary() const;
149 :
150 : /// returns the position of a junction
151 : Position getJunctionPosition(const std::string& name) const;
152 :
153 : /// returns the information whether the vehicle still exists
154 : bool vehicleExists(const std::string& name) const;
155 :
156 : /// Some further steps needed for gui processing
157 : void guiSimulationStep();
158 :
159 : /** @brief Performs a single simulation step (locking the simulation)
160 : */
161 : void simulationStep();
162 :
163 : /// @name functions for performance measurements
164 : /// @{
165 :
166 : /** @brief Returns the duration of the last step (sim+visualisation+idle) (in ms)
167 : * @return How long it took to compute and display the last step
168 : */
169 : int getWholeDuration() const;
170 :
171 :
172 : /** @brief Returns the duration of the last step's simulation part (in ms)
173 : * @return How long it took to compute the last step
174 : */
175 : int getSimDuration() const;
176 :
177 :
178 : /// Returns the simulation speed as a factor to real time
179 : double getRTFactor() const;
180 :
181 : /// Returns the update per seconds rate
182 : double getUPS() const;
183 :
184 : /// Returns the simulation speed as a factor to real time
185 : double getMeanRTFactor(int duration) const;
186 :
187 : /// Returns the update per seconds rate
188 : double getMeanUPS() const;
189 :
190 : // Returns the duration of the last step's visualisation part (in ms)
191 : //int getVisDuration() const;
192 :
193 : /// Returns the duration of the last step's idle part (in ms)
194 : int getIdleDuration() const;
195 :
196 : /// Sets the duration of the last step's simulation part
197 : void setSimDuration(int val);
198 :
199 : // Sets the duration of the last step's visualisation part
200 : //void setVisDuration(int val);
201 :
202 : /// Sets the duration of the last step's idle part
203 : void setIdleDuration(int val);
204 : //}
205 :
206 0 : double getAvgRouteLength() const {
207 0 : return MSDevice_Tripinfo::getAvgRouteLength();
208 : }
209 0 : double getAvgDuration() const {
210 0 : return MSDevice_Tripinfo::getAvgDuration();
211 : }
212 0 : double getAvgWaitingTime() const {
213 0 : return MSDevice_Tripinfo::getAvgWaitingTime();
214 : }
215 0 : double getAvgTimeLoss() const {
216 0 : return MSDevice_Tripinfo::getAvgTimeLoss();
217 : }
218 0 : double getAvgDepartDelay() const {
219 0 : return MSDevice_Tripinfo::getAvgDepartDelay();
220 : }
221 0 : double getAvgTripSpeed() const {
222 0 : return MSDevice_Tripinfo::getAvgDuration() != 0 ? MSDevice_Tripinfo::getAvgRouteLength() / MSDevice_Tripinfo::getAvgDuration() : 0;
223 : }
224 0 : double getAvgWalkRouteLength() const {
225 0 : return MSDevice_Tripinfo::getAvgWalkRouteLength();
226 : }
227 0 : double getAvgWalkDuration() const {
228 0 : return MSDevice_Tripinfo::getAvgWalkDuration();
229 : }
230 0 : double getAvgWalkTimeLoss() const {
231 0 : return MSDevice_Tripinfo::getAvgWalkTimeLoss();
232 : }
233 :
234 : /** @brief Returns the person control
235 : *
236 : * If the person control does not exist, yet, it is created.
237 : *
238 : * @return The person control
239 : * @see MSPersonControl
240 : * @see myPersonControl
241 : */
242 : MSTransportableControl& getPersonControl() override;
243 :
244 :
245 : /** @brief Returns the container control
246 : *
247 : * If the container control does not exist, yet, it is created.
248 : *
249 : * @return The container control
250 : * @see MSContainerControl
251 : * @see myContainerControl
252 : */
253 : MSTransportableControl& getContainerControl() override;
254 :
255 :
256 : /** Returns the gl-id of the traffic light that controls the given link
257 : * valid only if the link is controlled by a tls */
258 : int getLinkTLID(const MSLink* const link) const;
259 :
260 : /** Returns the index of the link within the junction that controls the given link;
261 : * Returns -1 if the link is not controlled by a tls */
262 : int getLinkTLIndex(const MSLink* const link) const;
263 :
264 : /** Returns the logic wrapper for the given tls if it exists */
265 : GUITrafficLightLogicWrapper* getTLLWrapper(MSTrafficLightLogic* tll);
266 :
267 : /// @name locator-methods
268 : //@{
269 :
270 : /* @brief Returns the gl-ids of all junctions within the net
271 : * @param[in] includeInternal Whether to include ids of internal junctions
272 : */
273 : std::vector<GUIGlID> getJunctionIDs(bool includeInternal) const;
274 :
275 : /// Returns the gl-ids of all traffic light logics within the net
276 : std::vector<GUIGlID> getTLSIDs() const;
277 : //@}
278 :
279 :
280 : /// Initialises gui wrappers
281 : void initGUIStructures();
282 :
283 :
284 : /** @brief Returns the RTree used for visualisation speed-up
285 : * @return The visualisation speed-up
286 : */
287 : SUMORTree& getVisualisationSpeedUp() {
288 11853 : return myGrid;
289 : }
290 :
291 :
292 : /** @brief Returns the RTree used for visualisation speed-up
293 : * @return The visualisation speed-up
294 : */
295 : const SUMORTree& getVisualisationSpeedUp(bool secondary = false) const {
296 647075 : return secondary ? myGrid2 : myGrid;
297 : }
298 :
299 : /// @brief add object into rtree
300 : void registerRenderedObject(GUIGlObject* o);
301 :
302 : /** @brief Returns the vehicle control
303 : * @return The vehicle control
304 : * @see MSVehicleControl
305 : * @see myVehicleControl
306 : */
307 : GUIVehicleControl* getGUIVehicleControl();
308 :
309 : /** @brief Returns the vehicle control
310 : * @return The vehicle control
311 : * @see MSVehicleControl
312 : * @see myVehicleControl
313 : */
314 : GUIMEVehicleControl* getGUIMEVehicleControl();
315 :
316 : /// @brief retrieve loaded edged weight for the given attribute and the current simulation time
317 : double getEdgeData(const MSEdge* edge, const std::string& attr);
318 :
319 : /// @brief retrieve live lane/edge weight for the given meanData id and attribute
320 : double getMeanData(const MSLane* lane, const std::string& id, const std::string& attr);
321 :
322 : /// @brief load edgeData from file
323 : bool loadEdgeData(const std::string& file);
324 :
325 : /// @brief return list of loaded edgeData attributes
326 : std::vector<std::string> getEdgeDataAttrs() const;
327 :
328 : /// @brief return list of loaded edgeData ids (being computed in the current simulation)
329 : std::vector<std::string> getMeanDataIDs() const;
330 :
331 : /// @brief return list of available attributes for the given meanData id
332 : std::vector<std::string> getMeanDataAttrs(const std::string& meanDataID) const;
333 :
334 : #ifdef HAVE_OSG
335 : void updateColor(const GUIVisualizationSettings& s);
336 : #endif
337 :
338 : /// @brief grant exclusive access to the simulation state
339 : void lock();
340 :
341 : /// @brief release exclusive access to the simulation state
342 : void unlock();
343 :
344 : /** @brief Returns the pointer to the unique instance of GUINet (singleton).
345 : * @return Pointer to the unique GUINet-instance
346 : * @exception ProcessError If a network was not yet constructed
347 : */
348 : static GUINet* getGUIInstance();
349 :
350 : /// @brief creates a wrapper for the given logic
351 : void createTLWrapper(MSTrafficLightLogic* tll) override;
352 :
353 : /// @brief return wheter the given logic (or rather it's wrapper) is selected in the GUI
354 : bool isSelected(const MSTrafficLightLogic* tll) const override;
355 :
356 : /// @brief update view after simulation.loadState
357 : void updateGUI() const override;
358 :
359 : /// @brief register custom hotkey action
360 : void addHotkey(int key, Command* press, Command* release = nullptr);
361 :
362 : /// @brief flush outputs once the simulation has reached its end
363 : void flushOutputsAtEnd();
364 :
365 1454829 : virtual bool skipFinalReset() const override {
366 1454829 : return mySkipFinalReset;
367 : }
368 :
369 : private:
370 : /// @brief Initialises the tl-logic map and wrappers
371 : void initTLMap();
372 :
373 : friend class GUIOSGBuilder;
374 :
375 : protected:
376 : /// @brief The visualization speed-up
377 : LayeredRTree myGrid;
378 :
379 : /// @brief The visualization speed-up for secondary shapes
380 : SUMORTree myGrid2;
381 :
382 : /// @brief The networks boundary
383 : Boundary myBoundary;
384 :
385 : /// @brief Wrapped MS-edges
386 : std::vector<GUIEdge*> myEdgeWrapper;
387 :
388 : /// @brief Wrapped MS-junctions
389 : std::vector<GUIJunctionWrapper*> myJunctionWrapper;
390 :
391 : /// @brief A detector dictionary
392 : std::vector<GUIDetectorWrapper*> myDetectorWrapper;
393 :
394 : /// @brief A calibrator dictionary
395 : std::vector<GUICalibrator*> myCalibratorWrapper;
396 :
397 : /// @brief Definition of a link-to-logic-id map
398 : typedef std::map<const MSLink*, std::string> Links2LogicMap;
399 : /// @brief The link-to-logic-id map
400 : Links2LogicMap myLinks2Logic;
401 :
402 :
403 : /// @brief Definition of a traffic light-to-wrapper map
404 : typedef std::map<MSTrafficLightLogic*, GUITrafficLightLogicWrapper*> Logics2WrapperMap;
405 : /// @brief The traffic light-to-wrapper map
406 : Logics2WrapperMap myLogics2Wrapper;
407 :
408 :
409 : /// @brief The step durations (simulation, /*visualisation, */idle)
410 : int myLastSimDuration, /*myLastVisDuration, */myLastIdleDuration;
411 :
412 : long myLastVehicleMovementCount, myOverallVehicleCount;
413 : long myOverallSimDuration;
414 :
415 : /// @brief loaded edge data for visualization
416 : std::map<std::string, MSEdgeWeightsStorage*> myLoadedEdgeData;
417 :
418 : bool mySkipFinalReset = false;
419 :
420 : /// @brief class for discovering edge attributes
421 : class DiscoverAttributes : public SUMOSAXHandler {
422 : public:
423 0 : DiscoverAttributes(const std::string& file):
424 0 : SUMOSAXHandler(file), firstIntervalBegin(SUMOTime_MAX), lastIntervalEnd(0), numIntervals(0) {};
425 0 : ~DiscoverAttributes() {};
426 : void myStartElement(int element, const SUMOSAXAttributes& attrs);
427 : std::vector<std::string> getEdgeAttrs();
428 : SUMOTime firstIntervalBegin;
429 : SUMOTime lastIntervalEnd;
430 : int numIntervals;
431 : private:
432 : std::set<std::string> edgeAttrs;
433 : };
434 :
435 0 : class EdgeFloatTimeLineRetriever_GUI : public SAXWeightsHandler::EdgeFloatTimeLineRetriever {
436 : public:
437 : /// @brief Constructor
438 0 : EdgeFloatTimeLineRetriever_GUI(MSEdgeWeightsStorage* weightStorage) : myWeightStorage(weightStorage) {}
439 :
440 : /// @brief Destructor
441 0 : ~EdgeFloatTimeLineRetriever_GUI() { }
442 :
443 : /** @brief Adds an effort for a given edge and time period
444 : *
445 : * @param[in] id The id of the object to add a weight for
446 : * @param[in] val The effort
447 : * @param[in] beg The begin of the interval the weight is valid for
448 : * @param[in] end The end of the interval the weight is valid for
449 : * @see SAXWeightsHandler::EdgeFloatTimeLineRetriever::addEdgeWeight
450 : */
451 : void addEdgeWeight(const std::string& id, double val, double beg, double end) const;
452 : void addEdgeRelWeight(const std::string& from, const std::string& to, double val, double beg, double end) const;
453 :
454 : private:
455 : /// @brief The storage that edges shall be added to
456 : MSEdgeWeightsStorage* myWeightStorage;
457 :
458 : };
459 :
460 : private:
461 : /// The mutex used to avoid concurrent updates of the vehicle buffer
462 : mutable FXMutex myLock;
463 :
464 : };
|