Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/guisim/GUICalibrator.cpp
169666 views
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 GUICalibrator.cpp
15
/// @author Daniel Krajzewicz
16
/// @author Jakob Erdmann
17
/// @author Michael Behrisch
18
/// @date Mon, 26.04.2004
19
///
20
// Changes flow and speed on a set of lanes (gui version)
21
/****************************************************************************/
22
#include <config.h>
23
24
#include <string>
25
#include <utils/common/MsgHandler.h>
26
#include <utils/geom/PositionVector.h>
27
#include <utils/geom/Boundary.h>
28
#include <utils/gui/div/GLHelper.h>
29
#include <utils/common/ToString.h>
30
#include <utils/common/Command.h>
31
#include <microsim/MSNet.h>
32
#include <microsim/MSLane.h>
33
#include <microsim/MSEdge.h>
34
#include <guisim/GUINet.h>
35
#include <guisim/GUIEdge.h>
36
#include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
37
#include <utils/gui/windows/GUIAppEnum.h>
38
#include <gui/GUIGlobals.h>
39
#include <utils/gui/div/GUIParameterTableWindow.h>
40
#include <gui/GUIApplicationWindow.h>
41
#include <microsim/logging/FunctionBinding.h>
42
#include <utils/gui/div/GUIGlobalSelection.h>
43
#include <utils/gui/images/GUIIconSubSys.h>
44
#include <guisim/GUICalibrator.h>
45
#include <utils/common/MsgHandler.h>
46
#include <utils/gui/globjects/GLIncludes.h>
47
#include <utils/gui/div/GUIDesigns.h>
48
49
#include "GUICalibrator.h"
50
51
// ===========================================================================
52
// FOX callback mapping
53
// ===========================================================================
54
55
FXDEFMAP(GUICalibrator::GUICalibratorPopupMenu) GUICalibratorPopupMenuMap[] = {
56
FXMAPFUNC(SEL_COMMAND, MID_MANIP, GUICalibrator::GUICalibratorPopupMenu::onCmdOpenManip),
57
};
58
59
FXDEFMAP(GUICalibrator::GUIManip_Calibrator) GUIManip_CalibratorMap[] = {
60
FXMAPFUNC(SEL_COMMAND, GUICalibrator::GUIManip_Calibrator::MID_USER_DEF, GUICalibrator::GUIManip_Calibrator::onCmdUserDef),
61
FXMAPFUNC(SEL_UPDATE, GUICalibrator::GUIManip_Calibrator::MID_USER_DEF, GUICalibrator::GUIManip_Calibrator::onUpdUserDef),
62
FXMAPFUNC(SEL_COMMAND, GUICalibrator::GUIManip_Calibrator::MID_PRE_DEF, GUICalibrator::GUIManip_Calibrator::onCmdPreDef),
63
FXMAPFUNC(SEL_UPDATE, GUICalibrator::GUIManip_Calibrator::MID_PRE_DEF, GUICalibrator::GUIManip_Calibrator::onUpdPreDef),
64
FXMAPFUNC(SEL_COMMAND, GUICalibrator::GUIManip_Calibrator::MID_OPTION, GUICalibrator::GUIManip_Calibrator::onCmdChangeOption),
65
FXMAPFUNC(SEL_COMMAND, GUICalibrator::GUIManip_Calibrator::MID_CLOSE, GUICalibrator::GUIManip_Calibrator::onCmdClose),
66
};
67
68
// Object implementation
69
FXIMPLEMENT(GUICalibrator::GUICalibratorPopupMenu, GUIGLObjectPopupMenu, GUICalibratorPopupMenuMap, ARRAYNUMBER(GUICalibratorPopupMenuMap))
70
FXIMPLEMENT(GUICalibrator::GUIManip_Calibrator, GUIManipulator, GUIManip_CalibratorMap, ARRAYNUMBER(GUIManip_CalibratorMap))
71
72
// ===========================================================================
73
// method definitions
74
// ===========================================================================
75
76
/* -------------------------------------------------------------------------
77
* GUICalibrator::GUIManip_Calibrator - methods
78
* ----------------------------------------------------------------------- */
79
GUICalibrator::GUIManip_Calibrator::GUIManip_Calibrator(GUIMainWindow& app, const std::string& name, GUICalibrator& o, int /*xpos*/, int /*ypos*/) :
80
GUIManipulator(app, name, 0, 0),
81
myParent(&app),
82
myChosenValue(0),
83
myChosenTarget(myChosenValue, nullptr, MID_OPTION),
84
//mySpeed(o.getDefaultSpeed()),
85
mySpeed(0),
86
mySpeedTarget(mySpeed),
87
myObject(&o) {
88
myChosenTarget.setTarget(this);
89
FXVerticalFrame* f1 =
90
new FXVerticalFrame(this, LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 0, 0, 0, 0, 0, 0);
91
92
FXGroupBox* gp = new FXGroupBox(f1, "Change Speed", GROUPBOX_TITLE_LEFT | FRAME_RIDGE,
93
0, 0, 0, 0, 4, 4, 1, 1, 2, 0);
94
{
95
// default
96
FXHorizontalFrame* gf1 = new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
97
new FXRadioButton(gf1, "Default", &myChosenTarget, FXDataTarget::ID_OPTION + 0, ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP,
98
0, 0, 0, 0, 2, 2, 0, 0);
99
}
100
{
101
// loaded
102
FXHorizontalFrame* gf0 = new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
103
new FXRadioButton(gf0, "Loaded", &myChosenTarget, FXDataTarget::ID_OPTION + 1, ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP,
104
0, 0, 0, 0, 2, 2, 0, 0);
105
}
106
{
107
// predefined
108
FXHorizontalFrame* gf2 = new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
109
new FXRadioButton(gf2, "Predefined: ", &myChosenTarget, FXDataTarget::ID_OPTION + 2, ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP | LAYOUT_CENTER_Y,
110
0, 0, 0, 0, 2, 2, 0, 0);
111
myPredefinedValues = new MFXComboBoxIcon(gf2, nullptr, false, GUIDesignComboBoxVisibleItems, this, MID_PRE_DEF,
112
ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP | LAYOUT_CENTER_Y | COMBOBOX_STATIC);
113
myPredefinedValues->appendIconItem("20 km/h");
114
myPredefinedValues->appendIconItem("40 km/h");
115
myPredefinedValues->appendIconItem("60 km/h");
116
myPredefinedValues->appendIconItem("80 km/h");
117
myPredefinedValues->appendIconItem("100 km/h");
118
myPredefinedValues->appendIconItem("120 km/h");
119
myPredefinedValues->appendIconItem("140 km/h");
120
myPredefinedValues->appendIconItem("160 km/h");
121
myPredefinedValues->appendIconItem("180 km/h");
122
myPredefinedValues->appendIconItem("200 km/h");
123
}
124
{
125
// free
126
FXHorizontalFrame* gf12 = new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
127
new FXRadioButton(gf12, "Free Entry: ", &myChosenTarget, FXDataTarget::ID_OPTION + 3,
128
ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP | LAYOUT_CENTER_Y,
129
0, 0, 0, 0, 2, 2, 0, 0);
130
myUserDefinedSpeed = new FXRealSpinner(gf12, 10, this, MID_USER_DEF, LAYOUT_TOP | FRAME_SUNKEN | FRAME_THICK);
131
//myUserDefinedSpeed->setFormatString("%.0f km/h");
132
//myUserDefinedSpeed->setIncrements(1, 10, 10);
133
myUserDefinedSpeed->setIncrement(10);
134
myUserDefinedSpeed->setRange(0, 300);
135
myUserDefinedSpeed->setValue(0);
136
//static_cast<GUICalibrator*>(myObject)->getDefaultSpeed() * 3.6);
137
}
138
GUIDesigns::buildFXButton(f1, "Close", "", "", nullptr, this, MID_CLOSE,
139
BUTTON_INITIAL | BUTTON_DEFAULT | FRAME_RAISED | FRAME_THICK | LAYOUT_TOP | LAYOUT_LEFT | LAYOUT_CENTER_X, 0, 0, 0, 0, 30, 30, 4, 4);
140
//static_cast<GUICalibrator*>(myObject)->setOverriding(true);
141
}
142
143
144
GUICalibrator::GUIManip_Calibrator::~GUIManip_Calibrator() {}
145
146
147
long
148
GUICalibrator::GUIManip_Calibrator::onCmdClose(FXObject*, FXSelector, void*) {
149
destroy();
150
return 1;
151
}
152
153
154
long
155
GUICalibrator::GUIManip_Calibrator::onCmdUserDef(FXObject*, FXSelector, void*) {
156
//mySpeed = (double)(myUserDefinedSpeed->getValue() / 3.6);
157
//static_cast<GUICalibrator*>(myObject)->setOverridingValue(mySpeed);
158
//myParent->updateChildren();
159
return 1;
160
}
161
162
163
long
164
GUICalibrator::GUIManip_Calibrator::onUpdUserDef(FXObject* sender, FXSelector, void* ptr) {
165
sender->handle(this,
166
myChosenValue != 3 ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
167
ptr);
168
myParent->updateChildren();
169
return 1;
170
}
171
172
173
long
174
GUICalibrator::GUIManip_Calibrator::onCmdPreDef(FXObject*, FXSelector, void*) {
175
//mySpeed = (double)(double)((myPredefinedValues->getCurrentItem() * 20 + 20) / 3.6);
176
//static_cast<GUICalibrator*>(myObject)->setOverridingValue(mySpeed);
177
//myParent->updateChildren();
178
return 1;
179
}
180
181
182
long
183
GUICalibrator::GUIManip_Calibrator::onUpdPreDef(FXObject* sender, FXSelector, void* ptr) {
184
sender->handle(this,
185
myChosenValue != 2 ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
186
ptr);
187
myParent->updateChildren();
188
return 1;
189
}
190
191
192
long
193
GUICalibrator::GUIManip_Calibrator::onCmdChangeOption(FXObject*, FXSelector, void*) {
194
//static_cast<GUICalibrator*>(myObject)->setOverriding(true);
195
//switch (myChosenValue) {
196
// case 0:
197
// mySpeed = (double) static_cast<GUICalibrator*>(myObject)->getDefaultSpeed();
198
// break;
199
// case 1:
200
// mySpeed = (double) static_cast<GUICalibrator*>(myObject)->getLoadedSpeed();
201
// break;
202
// case 2:
203
// mySpeed = (double)((myPredefinedValues->getCurrentItem() * 20 + 20) / 3.6);
204
// break;
205
// case 3:
206
// mySpeed = (double)(myUserDefinedSpeed->getValue() / 3.6);
207
// break;
208
// default:
209
// // hmmm, should not happen
210
// break;
211
//}
212
//static_cast<GUICalibrator*>(myObject)->setOverridingValue(mySpeed);
213
//myParent->updateChildren();
214
//if (myChosenValue == 1) {
215
// // !!! lock in between
216
// static_cast<GUICalibrator*>(myObject)->setOverriding(false);
217
//}
218
return 1;
219
}
220
221
222
223
/* -------------------------------------------------------------------------
224
* GUICalibrator::GUICalibratorPopupMenu - methods
225
* ----------------------------------------------------------------------- */
226
227
GUICalibrator::GUICalibratorPopupMenu::GUICalibratorPopupMenu(
228
GUIMainWindow& app, GUISUMOAbstractView& parent, GUIGlObject* o) :
229
GUIGLObjectPopupMenu(app, parent, o) {}
230
231
232
GUICalibrator::GUICalibratorPopupMenu::~GUICalibratorPopupMenu() {}
233
234
235
long
236
GUICalibrator::GUICalibratorPopupMenu::onCmdOpenManip(FXObject*,
237
FXSelector,
238
void*) {
239
static_cast<GUICalibrator*>(myObject)->openManipulator(
240
*myApplication, *myParent);
241
return 1;
242
}
243
244
245
/* -------------------------------------------------------------------------
246
* GUICalibrator - methods
247
* ----------------------------------------------------------------------- */
248
GUICalibrator::GUICalibrator(MSCalibrator* calibrator) :
249
GUIGlObject_AbstractAdd(GLO_CALIBRATOR, calibrator->getID(), GUIIconSubSys::getIcon(GUIIcon::CALIBRATOR)),
250
myCalibrator(calibrator),
251
myShowAsKMH(true) {
252
if (calibrator->getEdge() != nullptr) {
253
const std::vector<MSLane*>& destLanes = calibrator->getEdge()->getLanes();
254
const MSLane* lane = calibrator->getLane();
255
const double pos = calibrator->myPos;
256
for (std::vector<MSLane*>::const_iterator i = destLanes.begin(); i != destLanes.end(); ++i) {
257
if (lane == nullptr || (*i) == lane) {
258
const PositionVector& v = (*i)->getShape();
259
myFGPositions.push_back(v.positionAtOffset(pos));
260
myBoundary.add(v.positionAtOffset(pos));
261
myFGRotations.push_back(-v.rotationDegreeAtOffset(pos));
262
}
263
}
264
}
265
if (calibrator->myNode != nullptr) {
266
myBoundary.add(calibrator->myNode->getPosition());
267
}
268
}
269
270
271
GUICalibrator::~GUICalibrator() {}
272
273
274
GUIGLObjectPopupMenu*
275
GUICalibrator::getPopUpMenu(GUIMainWindow& app, GUISUMOAbstractView& parent) {
276
GUIGLObjectPopupMenu* ret = new GUICalibratorPopupMenu(app, parent, this);
277
buildPopupHeader(ret, app);
278
buildCenterPopupEntry(ret);
279
//buildShowManipulatorPopupEntry(ret);
280
buildNameCopyPopupEntry(ret);
281
buildSelectionPopupEntry(ret);
282
buildShowParamsPopupEntry(ret);
283
buildPositionCopyEntry(ret, app);
284
return ret;
285
}
286
287
288
GUIParameterTableWindow*
289
GUICalibrator::getParameterWindow(GUIMainWindow& app, GUISUMOAbstractView&) {
290
GUIParameterTableWindow* ret;
291
auto myCurrentStateInterval = myCalibrator->myCurrentStateInterval;
292
if (myCalibrator->isActive()) {
293
ret = new GUIParameterTableWindow(app, *this);
294
// add items
295
ret->mkItem(TL("interval start"), false, STEPS2TIME(myCurrentStateInterval->begin));
296
ret->mkItem(TL("interval end"), false, STEPS2TIME(myCurrentStateInterval->end));
297
ret->mkItem(TL("aspired flow [veh/h]"), false, myCurrentStateInterval->q);
298
ret->mkItem(TL("aspired speed"), false, myCurrentStateInterval->v);
299
ret->mkItem(TL("current flow [veh/h]"), true, new FunctionBinding<MSCalibrator, double>(myCalibrator, &MSCalibrator::currentFlow));
300
ret->mkItem(TL("current speed"), true, new FunctionBinding<MSCalibrator, double>(myCalibrator, &MSCalibrator::currentSpeed));
301
ret->mkItem(TL("default speed"), false, myCalibrator->myDefaultSpeed);
302
ret->mkItem(TL("required vehicles"), true, new FunctionBinding<MSCalibrator, int>(myCalibrator, &MSCalibrator::totalWished));
303
ret->mkItem(TL("passed vehicles"), true, new FunctionBinding<MSCalibrator, int>(myCalibrator, &MSCalibrator::passed));
304
ret->mkItem(TL("inserted vehicles"), true, new FunctionBinding<MSCalibrator, int>(myCalibrator, &MSCalibrator::inserted));
305
ret->mkItem(TL("removed vehicles"), true, new FunctionBinding<MSCalibrator, int>(myCalibrator, &MSCalibrator::removed));
306
ret->mkItem(TL("cleared in jam"), true, new FunctionBinding<MSCalibrator, int>(myCalibrator, &MSCalibrator::clearedInJam));
307
} else {
308
ret = new GUIParameterTableWindow(app, *this);
309
const std::string nextStart =
310
(myCurrentStateInterval != myCalibrator->myIntervals.end() ?
311
time2string(myCurrentStateInterval->begin) :
312
"simulation end");
313
ret->mkItem(TL("inactive until"), false, nextStart);
314
}
315
// close building
316
ret->closeBuilding();
317
return ret;
318
}
319
320
321
void
322
GUICalibrator::drawGL(const GUIVisualizationSettings& s) const {
323
const double exaggeration = getExaggeration(s);
324
GLHelper::pushName(getGlID());
325
std::string flow = "-";
326
std::string speed = "-";
327
if (myCalibrator->isActive()) {
328
auto myCurrentStateInterval = myCalibrator->myCurrentStateInterval;
329
if (myCurrentStateInterval->v >= 0) {
330
speed = toString(myCurrentStateInterval->v) + "m/s";
331
}
332
if (myCurrentStateInterval->q >= 0) {
333
flow = toString((int)myCurrentStateInterval->q) + "v/h";
334
}
335
}
336
for (int i = 0; i < (int)myFGPositions.size(); ++i) {
337
const Position& pos = myFGPositions[i];
338
double rot = myFGRotations[i];
339
GLHelper::pushMatrix();
340
glTranslated(pos.x(), pos.y(), getType());
341
glRotated(rot, 0, 0, 1);
342
glTranslated(0, 0, getType());
343
glScaled(exaggeration, exaggeration, 1);
344
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
345
346
glBegin(GL_TRIANGLES);
347
glColor3d(1, .8f, 0);
348
// base
349
glVertex2d(0 - 1.4, 0);
350
glVertex2d(0 - 1.4, 6);
351
glVertex2d(0 + 1.4, 6);
352
glVertex2d(0 + 1.4, 0);
353
glVertex2d(0 - 1.4, 0);
354
glVertex2d(0 + 1.4, 6);
355
glEnd();
356
357
// draw text
358
if (s.scale * exaggeration >= 1.) {
359
glTranslated(0, 0, .1);
360
GLHelper::drawText("C", Position(0, 2), 0.1, 3, RGBColor::BLACK, 180);
361
GLHelper::drawText(flow, Position(0, 4), 0.1, 0.7, RGBColor::BLACK, 180);
362
GLHelper::drawText(speed, Position(0, 5), 0.1, 0.7, RGBColor::BLACK, 180);
363
}
364
GLHelper::popMatrix();
365
}
366
drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
367
GLHelper::popName();
368
}
369
370
371
double
372
GUICalibrator::getExaggeration(const GUIVisualizationSettings& s) const {
373
return s.addSize.getExaggeration(s, this);
374
}
375
376
377
Boundary
378
GUICalibrator::getCenteringBoundary() const {
379
Boundary b(myBoundary);
380
b.grow(20);
381
return b;
382
}
383
384
385
GUIManipulator*
386
GUICalibrator::openManipulator(GUIMainWindow& app,
387
GUISUMOAbstractView&) {
388
GUIManip_Calibrator* gui =
389
new GUIManip_Calibrator(app, getFullName(), *this, 0, 0);
390
gui->create();
391
gui->show();
392
return gui;
393
}
394
395
396
/****************************************************************************/
397
398