Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
libsumo/GUI.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2017-2024 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/****************************************************************************/
18// C++ TraCI client API implementation
19/****************************************************************************/
20#include <config.h>
21
33#include <utils/xml/XMLSubSys.h>
35#include <gui/GUIRunThread.h>
36#include <guisim/GUIVehicle.h>
37#include <guisim/GUIPerson.h>
38#include <guisim/GUIContainer.h>
39#include <microsim/MSFrame.h>
40#include <microsim/MSNet.h>
43#include <libsumo/TraCIDefs.h>
44#include <libsumo/Helper.h>
45#include <libsumo/GUI.h>
46
47
48namespace libsumo {
49// ===========================================================================
50// static member initializations
51// ===========================================================================
52SubscriptionResults GUI::mySubscriptionResults;
53ContextSubscriptionResults GUI::myContextSubscriptionResults;
54GUIApplicationWindow* GUI::myWindow = nullptr;
55FXApp* GUI::myApp = nullptr;
56
57
58// ===========================================================================
59// static member definitions
60// ===========================================================================
61std::vector<std::string>
62GUI::getIDList() {
63 try {
65 } catch (const ProcessError&) {
66 throw TraCIException("GUI is not running, command not implemented in command line sumo");
67 }
68}
69
70
71int
72GUI::getIDCount() {
73 try {
74 return (int)GUIMainWindow::getInstance()->getViewIDs().size();
75 } catch (const ProcessError&) {
76 throw TraCIException("GUI is not running, command not implemented in command line sumo");
77 }
78}
79
80
81double
82GUI::getZoom(const std::string& viewID) {
83 return getView(viewID)->getChanger().getZoom();
84}
85
86
87double
88GUI::getAngle(const std::string& viewID) {
89 return getView(viewID)->getChanger().getRotation();
90}
91
92
94GUI::getOffset(const std::string& viewID) {
95 GUISUMOAbstractView* v = getView(viewID);
97 pos.x = v->getChanger().getXPos();
98 pos.y = v->getChanger().getYPos();
99 return pos;
100}
101
102
103std::string
104GUI::getSchema(const std::string& viewID) {
105 return getView(viewID)->getVisualisationSettings().name;
106}
107
108
110GUI::getBoundary(const std::string& viewID) {
111 const Boundary& b = getView(viewID)->getVisibleBoundary();
112 TraCIPositionVector tb;
113 TraCIPosition minV;
114 TraCIPosition maxV;
115 minV.x = b.xmin();
116 maxV.x = b.xmax();
117 minV.y = b.ymin();
118 maxV.y = b.ymax();
119 minV.z = b.zmin();
120 maxV.z = b.zmax();
121 tb.value.push_back(minV);
122 tb.value.push_back(maxV);
123 return tb;
124}
125
126
127void
128GUI::setZoom(const std::string& viewID, double zoom) {
129 GUISUMOAbstractView* const v = getView(viewID);
130 const Position off(v->getChanger().getXPos(), v->getChanger().getYPos(), v->getChanger().zoom2ZPos(zoom));
131 const Position p(off.x(), off.y(), 0);
133}
134
135
136void
137GUI::setAngle(const std::string& viewID, double angle) {
138 GUISUMOAbstractView* const v = getView(viewID);
139 const Position off(v->getChanger().getXPos(), v->getChanger().getYPos(), v->getChanger().getZPos());
140 const Position p(off.x(), off.y(), 0);
141 v->setViewportFromToRot(off, p, angle);
142}
143
144
145void
146GUI::setOffset(const std::string& viewID, double x, double y) {
147 GUISUMOAbstractView* const v = getView(viewID);
148 const Position off(x, y, v->getChanger().getZPos());
149 const Position p(x, y, 0);
151}
152
153
154void
155GUI::setSchema(const std::string& viewID, const std::string& schemeName) {
156 getView(viewID)->setColorScheme(schemeName);
157}
158
159
160void
161GUI::addView(const std::string& viewID, const std::string& schemeName, bool in3D) {
162 try {
163 // calling openNewView directly doesn't work from the traci/simulation thread
164 GUIMainWindow::getInstance()->sendBlockingEvent(new GUIEvent_AddView(viewID, schemeName, in3D));
165 } catch (const ProcessError&) {
166 throw TraCIException("GUI is not running, command not implemented in command line sumo");
167 }
168 // sonar thinks here is a memory leak but the GUIApplicationWindow does the clean up
169} // NOSONAR
170
171
172void
173GUI::removeView(const std::string& viewID) {
174 try {
175 // calling removeViewByID directly doesn't work from the traci/simulation thread
177 } catch (const ProcessError&) {
178 throw TraCIException("GUI is not running, command not implemented in command line sumo");
179 }
180 // sonar thinks here is a memory leak but the GUIApplicationWindow does the clean up
181} // NOSONAR
182
183
184void
185GUI::setBoundary(const std::string& viewID, double xmin, double ymin, double xmax, double ymax) {
186 getView(viewID)->centerTo(Boundary(xmin, ymin, xmax, ymax));
187}
188
189
190void
191GUI::screenshot(const std::string& viewID, const std::string& filename, const int width, const int height) {
192 getView(viewID)->addSnapshot(SIMSTEP, filename, width, height);
193}
194
195
196void
197GUI::trackVehicle(const std::string& viewID, const std::string& vehID) {
198 GUISUMOAbstractView* const v = getView(viewID);
199 if (vehID == "") {
200 v->stopTrack();
201 } else {
202 GUIGlID glID = 0;
204 if (veh != nullptr) {
205 glID = static_cast<GUIVehicle*>(veh)->getGlID();
206 } else {
208 if (person != nullptr) {
209 glID = static_cast<GUIPerson*>(person)->getGlID();
210 } else {
212 if (container != nullptr) {
213 glID = static_cast<GUIContainer*>(container)->getGlID();
214 } else {
215 throw TraCIException("Could not find vehicle or person '" + vehID + "'.");
216 }
217 }
218 }
219 if (v->getTrackedID() != glID) {
220 v->startTrack(glID);
221 }
222 }
223}
224
225
226bool
227GUI::hasView(const std::string& viewID) {
228 try {
229 return GUIMainWindow::getInstance()->getViewByID(viewID) != nullptr;
230 } catch (const ProcessError&) {
231 throw TraCIException("GUI is not running, command not implemented in command line sumo");
232 }
233}
234
235
236std::string
237GUI::getTrackedVehicle(const std::string& viewID) {
238 GUISUMOAbstractView* const v = getView(viewID);
239 GUIGlObject* tracked = nullptr;
240 const GUIGlID gid = v->getTrackedID();
241 if (gid != GUIGlObject::INVALID_ID) {
243 }
244 const std::string result = tracked == nullptr ? "" : tracked->getMicrosimID();
245 if (gid != GUIGlObject::INVALID_ID) {
247 }
248 return result;
249}
250
251
252void
253GUI::track(const std::string& objID, const std::string& viewID) {
254 trackVehicle(viewID, objID);
255}
256
257
258bool
259GUI::isSelected(const std::string& objID, const std::string& objType) {
260 const std::string fullName = objType + ":" + objID;
262 if (obj == nullptr) {
264 throw TraCIException("The " + objType + " " + objID + " is not known.");
265 }
266 const bool result = gSelected.isSelected(obj);
268 return result;
269}
270
271
272void
273GUI::toggleSelection(const std::string& objID, const std::string& objType) {
274 const std::string fullName = objType + ":" + objID;
276 if (obj == nullptr) {
278 throw TraCIException("The " + objType + " " + objID + " is not known.");
279 }
282}
283
284
285std::string
286GUI::getParameter(const std::string& /* viewID */, const std::string& /* name */) {
287 return "";
288}
289
290
291void
292GUI::setParameter(const std::string& /* viewID */, const std::string& /* name */, const std::string& /* value */) {
293}
294
295
298
299
300bool
301GUI::start(const std::vector<std::string>& cmd) {
302 if (cmd[0].find("sumo-gui") == std::string::npos && std::getenv("LIBSUMO_GUI") == nullptr) {
303 return false;
304 }
305#ifdef WIN32
306 WRITE_WARNING("Libsumo on Windows does not work with GUI, falling back to plain libsumo.");
307 return false;
308#else
309 try {
310 if (!GUI::close("Libsumo started new instance.")) {
311// SystemFrame::close();
312 }
313 int argc = 1;
314 char array[1][10] = {{0}};
315 strcpy(array[0], "dummy");
316 char* argv[1];
317 argv[0] = array[0];
318 // make the output aware of threading
320 gSimulation = true;
323 std::vector<std::string> args(cmd.begin() + 1, cmd.end());
324 OptionsIO::setArgs(args);
327 // Open display
328 myApp = new FXApp("SUMO GUI", "sumo-gui");
329 myApp->init(argc, argv);
330 int minor, major;
331 if (!FXGLVisual::supported(myApp, major, minor)) {
332 throw ProcessError(TL("This system has no OpenGL support. Exiting."));
333 }
334
335 // build the main window
336 myWindow = new GUIApplicationWindow(myApp, "*.sumo.cfg,*.sumocfg");
337 gSchemeStorage.init(myApp);
338 myWindow->dependentBuild(true);
339 myApp->create();
340 myWindow->getRunner()->enableLibsumo();
341 // Load configuration given on command line
342 myWindow->loadOnStartup(true);
343 } catch (const ProcessError& e) {
344 throw TraCIException(e.what());
345 }
346 return true;
347#endif
348}
349
350
351bool
352GUI::load(const std::vector<std::string>& /* cmd */) {
353 if (myWindow != nullptr) {
354 WRITE_ERROR("libsumo.load is not implemented for the GUI.");
355 return true;
356 }
357 return false;
358}
359
360
361bool
362GUI::hasInstance() {
363 return myWindow != nullptr;
364}
365
366
367bool
368GUI::step(SUMOTime t) {
369 if (myWindow != nullptr) {
370 if (t == 0) {
371 t = SIMSTEP + DELTA_T;
372 }
373 while (SIMSTEP < t) {
374 myWindow->getRunner()->tryStep();
375 }
376 return true;
377 }
378 return false;
379}
380
381
382bool
383GUI::close(const std::string& /*reason*/) {
384 if (myWindow != nullptr) {
385 myApp->stop();
386 delete myWindow;
387 myWindow = nullptr;
389 delete myApp;
390 return true;
391 }
392 return false;
393}
394
395
397GUI::getView(const std::string& id) {
398 // we cannot use myWindow here, this is not set for the traci server
399 try {
401 if (c == nullptr) {
402 throw TraCIException("View '" + id + "' is not known");
403 }
404 return c->getView();
405 } catch (const ProcessError&) {
406 throw TraCIException("GUI is not running, command not implemented in command line sumo");
407 }
408}
409
410
411std::shared_ptr<VariableWrapper>
412GUI::makeWrapper() {
413 return std::make_shared<Helper::SubscriptionWrapper>(handleVariable, mySubscriptionResults, myContextSubscriptionResults);
414}
415
416
417bool
418GUI::handleVariable(const std::string& objID, const int variable, VariableWrapper* wrapper, tcpip::Storage* /* paramData */) {
419 switch (variable) {
420 case TRACI_ID_LIST:
421 return wrapper->wrapStringList(objID, variable, getIDList());
422 case ID_COUNT:
423 return wrapper->wrapInt(objID, variable, getIDCount());
424 case VAR_VIEW_ZOOM:
425 return wrapper->wrapDouble(objID, variable, getZoom(objID));
426 case VAR_VIEW_OFFSET:
427 return wrapper->wrapPosition(objID, variable, getOffset(objID));
428 case VAR_VIEW_SCHEMA:
429 return wrapper->wrapString(objID, variable, getSchema(objID));
430 case VAR_ANGLE:
431 return wrapper->wrapDouble(objID, variable, getAngle(objID));
433 return wrapper->wrapPositionVector(objID, variable, getBoundary(objID));
434 case VAR_HAS_VIEW:
435 return wrapper->wrapInt(objID, variable, hasView(objID) ? 1 : 0);
437 return wrapper->wrapString(objID, variable, getTrackedVehicle(objID));
438 default:
439 return false;
440 }
441}
442
443}
444
445
446/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
GUICompleteSchemeStorage gSchemeStorage
unsigned int GUIGlID
Definition GUIGlObject.h:43
GUISelectedStorage gSelected
A global holder of selected objects.
#define WRITE_ERROR(msg)
Definition MsgHandler.h:304
#define WRITE_WARNING(msg)
Definition MsgHandler.h:295
#define TL(string)
Definition MsgHandler.h:315
SUMOTime DELTA_T
Definition SUMOTime.cpp:38
#define SIMSTEP
Definition SUMOTime.h:61
bool gSimulation
Definition StdDefs.cpp:30
#define LIBSUMO_SUBSCRIPTION_IMPLEMENTATION(CLASS, DOM)
Definition TraCIDefs.h:76
#define LIBSUMO_GET_PARAMETER_WITH_KEY_IMPLEMENTATION(CLASS)
Definition TraCIDefs.h:123
A class that stores a 2D geometrical boundary.
Definition Boundary.h:39
double ymin() const
Returns minimum y-coordinate.
Definition Boundary.cpp:130
double xmin() const
Returns minimum x-coordinate.
Definition Boundary.cpp:118
double zmin() const
Returns minimum z-coordinate.
Definition Boundary.cpp:142
double ymax() const
Returns maximum y-coordinate.
Definition Boundary.cpp:136
double xmax() const
Returns maximum x-coordinate.
Definition Boundary.cpp:124
double zmax() const
Returns maximum z-coordinate.
Definition Boundary.cpp:148
The main window of the SUMO-gui.
void init(FXApp *app, bool netedit=false)
Initialises the storage with some default settings.
GUISUMOAbstractView * getView() const
return GUISUMOAbstractView
const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
static const GUIGlID INVALID_ID
Definition GUIGlObject.h:72
GUIGlID getGlID() const
Returns the numerical id of the object.
void unblockObject(GUIGlID id)
Marks an object as unblocked.
GUIGlObject * getObjectBlocking(GUIGlID id) const
Returns the object from the container locking it.
static GUIGlObjectStorage gIDStorage
A single static instance of this class.
C++ TraCI client API implementation.
GUIGlChildWindow * getViewByID(const std::string &id) const
get specific view by ID
std::vector< std::string > getViewIDs() const
get view IDs
static GUIMainWindow * getInstance()
get instance
virtual void sendBlockingEvent(GUIEvent *event)
Sends an event from the application thread to the GUI and waits until it is handled.
virtual double zoom2ZPos(double zoom) const =0
Returns the camera height at which the given zoom level is reached.
virtual double getRotation() const =0
Returns the rotation of the canvas stored in this changer.
virtual double getXPos() const =0
Returns the x-offset of the field to show stored in this changer.
virtual double getYPos() const =0
Returns the y-offset of the field to show stored in this changer.
virtual double getZPos() const =0
Returns the camera height corresponding to the current zoom factor.
GUIPerspectiveChanger & getChanger() const
get changer
virtual void setViewportFromToRot(const Position &lookFrom, const Position &lookAt, double rotation)
applies the given viewport settings
virtual void stopTrack()
stop track
virtual void startTrack(int)
star track
virtual GUIGlID getTrackedID() const
get tracked id
void toggleSelection(GUIGlID id)
Toggles selection of an object.
bool isSelected(GUIGlObjectType type, GUIGlID id)
Returns the information whether the object with the given type and id is selected.
A MSVehicle extended by some values for usage within the gui.
Definition GUIVehicle.h:51
static void fillOptions()
Inserts options used by the simulation into the OptionsCont-singleton.
Definition MSFrame.cpp:60
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:186
virtual MSTransportableControl & getContainerControl()
Returns the container control.
Definition MSNet.cpp:1199
MSVehicleControl & getVehicleControl()
Returns the vehicle control.
Definition MSNet.h:378
virtual MSTransportableControl & getPersonControl()
Returns the person control.
Definition MSNet.cpp:1190
MSTransportable * get(const std::string &id) const
Returns the named transportable, if existing.
SUMOVehicle * getVehicle(const std::string &id) const
Returns the vehicle with the given id.
static void setFactory(Factory func)
Sets the factory function to use for new MsgHandlers.
Definition MsgHandler.h:64
static MsgHandler * create(MsgType type)
static OptionsCont & getOptions()
Retrieves the options.
bool processMetaOptions(bool missingOptions)
Checks for help and configuration output, returns whether we should exit.
static void setArgs(int argc, char **argv)
Stores the command line arguments for later parsing.
Definition OptionsIO.cpp:58
static void getOptions(const bool commandLineOnly=false)
Parses the command line arguments and loads the configuration.
Definition OptionsIO.cpp:74
A point in 2D or 3D with translation and scaling methods.
Definition Position.h:37
Representation of a vehicle.
Definition SUMOVehicle.h:62
static void close()
Closes all of an applications subsystems.
static void init()
Initialises the xml-subsystem.
Definition XMLSubSys.cpp:56
TRACI_CONST int TRACI_ID_LIST
TRACI_CONST int VAR_VIEW_BOUNDARY
std::map< std::string, libsumo::SubscriptionResults > ContextSubscriptionResults
Definition TraCIDefs.h:338
TRACI_CONST int VAR_ANGLE
TRACI_CONST int VAR_VIEW_OFFSET
TRACI_CONST int VAR_VIEW_SCHEMA
TRACI_CONST int VAR_VIEW_ZOOM
TRACI_CONST int VAR_TRACK_VEHICLE
std::map< std::string, libsumo::TraCIResults > SubscriptionResults
{object->{variable->value}}
Definition TraCIDefs.h:337
TRACI_CONST int VAR_HAS_VIEW
TRACI_CONST int ID_COUNT
@ array
array (ordered collection of values)
A 2D or 3D-position, for 2D positions z == INVALID_DOUBLE_VALUE.
Definition TraCIDefs.h:178
A list of positions.
Definition TraCIDefs.h:234