Eclipse SUMO - Simulation of Urban MObility
GUICalibrator.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2001-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 /****************************************************************************/
20 // Changes flow and speed on a set of lanes (gui version)
21 /****************************************************************************/
22 #include <config.h>
23 
24 #include <string>
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>
38 #include <gui/GUIGlobals.h>
44 #include <guisim/GUICalibrator.h>
48 
49 #include "GUICalibrator.h"
50 
51 // ===========================================================================
52 // FOX callback mapping
53 // ===========================================================================
54 
55 FXDEFMAP(GUICalibrator::GUICalibratorPopupMenu) GUICalibratorPopupMenuMap[] = {
57 };
58 
59 FXDEFMAP(GUICalibrator::GUIManip_Calibrator) GUIManip_CalibratorMap[] = {
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  * ----------------------------------------------------------------------- */
80  GUIMainWindow& app,
81  const std::string& name, GUICalibrator& o,
82  int /*xpos*/, int /*ypos*/) :
83  GUIManipulator(app, name, 0, 0),
84  myParent(&app),
85  myChosenValue(0),
86  myChosenTarget(myChosenValue, nullptr, MID_OPTION),
87  //mySpeed(o.getDefaultSpeed()),
88  mySpeed(0),
89  mySpeedTarget(mySpeed),
90  myObject(&o) {
91  myChosenTarget.setTarget(this);
92  FXVerticalFrame* f1 =
93  new FXVerticalFrame(this, LAYOUT_FILL_X | LAYOUT_FILL_Y, 0, 0, 0, 0, 0, 0, 0, 0);
94 
95  FXGroupBox* gp = new FXGroupBox(f1, "Change Speed",
96  GROUPBOX_TITLE_LEFT | FRAME_RIDGE,
97  0, 0, 0, 0, 4, 4, 1, 1, 2, 0);
98  {
99  // default
100  FXHorizontalFrame* gf1 =
101  new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
102  new FXRadioButton(gf1, "Default", &myChosenTarget, FXDataTarget::ID_OPTION + 0,
103  ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP,
104  0, 0, 0, 0, 2, 2, 0, 0);
105  }
106  {
107  // loaded
108  FXHorizontalFrame* gf0 =
109  new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
110  new FXRadioButton(gf0, "Loaded", &myChosenTarget, FXDataTarget::ID_OPTION + 1,
111  ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP,
112  0, 0, 0, 0, 2, 2, 0, 0);
113  }
114  {
115  // predefined
116  FXHorizontalFrame* gf2 =
117  new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
118  new FXRadioButton(gf2, "Predefined: ", &myChosenTarget, FXDataTarget::ID_OPTION + 2,
119  ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP | LAYOUT_CENTER_Y,
120  0, 0, 0, 0, 2, 2, 0, 0);
121  myPredefinedValues =
122  new MFXComboBoxIcon(gf2, 10, false, GUIDesignComboBoxVisibleItemsSmall, this, MID_PRE_DEF,
123  ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP | LAYOUT_CENTER_Y | COMBOBOX_STATIC);
124  myPredefinedValues->appendIconItem("20 km/h");
125  myPredefinedValues->appendIconItem("40 km/h");
126  myPredefinedValues->appendIconItem("60 km/h");
127  myPredefinedValues->appendIconItem("80 km/h");
128  myPredefinedValues->appendIconItem("100 km/h");
129  myPredefinedValues->appendIconItem("120 km/h");
130  myPredefinedValues->appendIconItem("140 km/h");
131  myPredefinedValues->appendIconItem("160 km/h");
132  myPredefinedValues->appendIconItem("180 km/h");
133  myPredefinedValues->appendIconItem("200 km/h");
134  }
135  {
136  // free
137  FXHorizontalFrame* gf12 =
138  new FXHorizontalFrame(gp, LAYOUT_TOP | LAYOUT_LEFT, 0, 0, 0, 0, 10, 10, 5, 5);
139  new FXRadioButton(gf12, "Free Entry: ", &myChosenTarget, FXDataTarget::ID_OPTION + 3,
140  ICON_BEFORE_TEXT | LAYOUT_SIDE_TOP | LAYOUT_CENTER_Y,
141  0, 0, 0, 0, 2, 2, 0, 0);
142  myUserDefinedSpeed =
143  new FXRealSpinner(gf12, 10, this, MID_USER_DEF,
144  LAYOUT_TOP | FRAME_SUNKEN | FRAME_THICK);
145  //myUserDefinedSpeed->setFormatString("%.0f km/h");
146  //myUserDefinedSpeed->setIncrements(1, 10, 10);
147  myUserDefinedSpeed->setIncrement(10);
148  myUserDefinedSpeed->setRange(0, 300);
149  myUserDefinedSpeed->setValue(0);
150  //static_cast<GUICalibrator*>(myObject)->getDefaultSpeed() * 3.6);
151  }
152  GUIDesigns::buildFXButton(f1, "Close", "", "", nullptr, this, MID_CLOSE,
153  BUTTON_INITIAL | BUTTON_DEFAULT | FRAME_RAISED | FRAME_THICK | LAYOUT_TOP | LAYOUT_LEFT | LAYOUT_CENTER_X, 0, 0, 0, 0, 30, 30, 4, 4);
154  //static_cast<GUICalibrator*>(myObject)->setOverriding(true);
155 }
156 
157 
159 
160 
161 long
162 GUICalibrator::GUIManip_Calibrator::onCmdClose(FXObject*, FXSelector, void*) {
163  destroy();
164  return 1;
165 }
166 
167 
168 long
170  //mySpeed = (double)(myUserDefinedSpeed->getValue() / 3.6);
171  //static_cast<GUICalibrator*>(myObject)->setOverridingValue(mySpeed);
172  //myParent->updateChildren();
173  return 1;
174 }
175 
176 
177 long
178 GUICalibrator::GUIManip_Calibrator::onUpdUserDef(FXObject* sender, FXSelector, void* ptr) {
179  sender->handle(this,
180  myChosenValue != 3 ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
181  ptr);
182  myParent->updateChildren();
183  return 1;
184 }
185 
186 
187 long
188 GUICalibrator::GUIManip_Calibrator::onCmdPreDef(FXObject*, FXSelector, void*) {
189  //mySpeed = (double)(double)((myPredefinedValues->getCurrentItem() * 20 + 20) / 3.6);
190  //static_cast<GUICalibrator*>(myObject)->setOverridingValue(mySpeed);
191  //myParent->updateChildren();
192  return 1;
193 }
194 
195 
196 long
197 GUICalibrator::GUIManip_Calibrator::onUpdPreDef(FXObject* sender, FXSelector, void* ptr) {
198  sender->handle(this,
199  myChosenValue != 2 ? FXSEL(SEL_COMMAND, ID_DISABLE) : FXSEL(SEL_COMMAND, ID_ENABLE),
200  ptr);
201  myParent->updateChildren();
202  return 1;
203 }
204 
205 
206 long
208  //static_cast<GUICalibrator*>(myObject)->setOverriding(true);
209  //switch (myChosenValue) {
210  // case 0:
211  // mySpeed = (double) static_cast<GUICalibrator*>(myObject)->getDefaultSpeed();
212  // break;
213  // case 1:
214  // mySpeed = (double) static_cast<GUICalibrator*>(myObject)->getLoadedSpeed();
215  // break;
216  // case 2:
217  // mySpeed = (double)((myPredefinedValues->getCurrentItem() * 20 + 20) / 3.6);
218  // break;
219  // case 3:
220  // mySpeed = (double)(myUserDefinedSpeed->getValue() / 3.6);
221  // break;
222  // default:
223  // // hmmm, should not happen
224  // break;
225  //}
226  //static_cast<GUICalibrator*>(myObject)->setOverridingValue(mySpeed);
227  //myParent->updateChildren();
228  //if (myChosenValue == 1) {
229  // // !!! lock in between
230  // static_cast<GUICalibrator*>(myObject)->setOverriding(false);
231  //}
232  return 1;
233 }
234 
235 
236 
237 /* -------------------------------------------------------------------------
238  * GUICalibrator::GUICalibratorPopupMenu - methods
239  * ----------------------------------------------------------------------- */
241  GUIMainWindow& app, GUISUMOAbstractView& parent,
242  GUIGlObject& o)
243  : GUIGLObjectPopupMenu(app, parent, o) {}
244 
245 
247 
248 
249 long
251  FXSelector,
252  void*) {
253  static_cast<GUICalibrator*>(myObject)->openManipulator(
254  *myApplication, *myParent);
255  return 1;
256 }
257 
258 
259 /* -------------------------------------------------------------------------
260  * GUICalibrator - methods
261  * ----------------------------------------------------------------------- */
263  GUIGlObject_AbstractAdd(GLO_CALIBRATOR, calibrator->getID(), GUIIconSubSys::getIcon(GUIIcon::CALIBRATOR)),
264  myCalibrator(calibrator),
265  myShowAsKMH(true) {
266  if (calibrator->getEdge() != nullptr) {
267  const std::vector<MSLane*>& destLanes = calibrator->getEdge()->getLanes();
268  const MSLane* lane = calibrator->getLane();
269  const double pos = calibrator->myPos;
270  for (std::vector<MSLane*>::const_iterator i = destLanes.begin(); i != destLanes.end(); ++i) {
271  if (lane == nullptr || (*i) == lane) {
272  const PositionVector& v = (*i)->getShape();
273  myFGPositions.push_back(v.positionAtOffset(pos));
275  myFGRotations.push_back(-v.rotationDegreeAtOffset(pos));
276  }
277  }
278  }
279  if (calibrator->myNode != nullptr) {
280  myBoundary.add(calibrator->myNode->getPosition());
281  }
282 }
283 
284 
286 
287 
290  GUISUMOAbstractView& parent) {
291  GUIGLObjectPopupMenu* ret = new GUICalibratorPopupMenu(app, parent, *this);
292  buildPopupHeader(ret, app);
294  //buildShowManipulatorPopupEntry(ret);
298  buildPositionCopyEntry(ret, app);
299  return ret;
300 }
301 
302 
307  auto myCurrentStateInterval = myCalibrator->myCurrentStateInterval;
308  if (myCalibrator->isActive()) {
309  ret = new GUIParameterTableWindow(app, *this);
310  // add items
311  ret->mkItem(TL("interval start"), false, STEPS2TIME(myCurrentStateInterval->begin));
312  ret->mkItem(TL("interval end"), false, STEPS2TIME(myCurrentStateInterval->end));
313  ret->mkItem(TL("aspired flow [veh/h]"), false, myCurrentStateInterval->q);
314  ret->mkItem(TL("aspired speed"), false, myCurrentStateInterval->v);
315  ret->mkItem(TL("current flow [veh/h]"), true, new FunctionBinding<MSCalibrator, double>(myCalibrator, &MSCalibrator::currentFlow));
317  ret->mkItem(TL("default speed"), false, myCalibrator->myDefaultSpeed);
318  ret->mkItem(TL("required vehicles"), true, new FunctionBinding<MSCalibrator, int>(myCalibrator, &MSCalibrator::totalWished));
319  ret->mkItem(TL("passed vehicles"), true, new FunctionBinding<MSCalibrator, int>(myCalibrator, &MSCalibrator::passed));
320  ret->mkItem(TL("inserted vehicles"), true, new FunctionBinding<MSCalibrator, int>(myCalibrator, &MSCalibrator::inserted));
321  ret->mkItem(TL("removed vehicles"), true, new FunctionBinding<MSCalibrator, int>(myCalibrator, &MSCalibrator::removed));
323  } else {
324  ret = new GUIParameterTableWindow(app, *this);
325  const std::string nextStart =
326  (myCurrentStateInterval != myCalibrator->myIntervals.end() ?
327  time2string(myCurrentStateInterval->begin) :
328  "simulation end");
329  ret->mkItem(TL("inactive until"), false, nextStart);
330  }
331  // close building
332  ret->closeBuilding();
333  return ret;
334 }
335 
336 
337 void
339  const double exaggeration = getExaggeration(s);
341  std::string flow = "-";
342  std::string speed = "-";
343  if (myCalibrator->isActive()) {
344  auto myCurrentStateInterval = myCalibrator->myCurrentStateInterval;
345  if (myCurrentStateInterval->v >= 0) {
346  speed = toString(myCurrentStateInterval->v) + "m/s";
347  }
348  if (myCurrentStateInterval->q >= 0) {
349  flow = toString((int)myCurrentStateInterval->q) + "v/h";
350  }
351  }
352  for (int i = 0; i < (int)myFGPositions.size(); ++i) {
353  const Position& pos = myFGPositions[i];
354  double rot = myFGRotations[i];
356  glTranslated(pos.x(), pos.y(), getType());
357  glRotated(rot, 0, 0, 1);
358  glTranslated(0, 0, getType());
359  glScaled(exaggeration, exaggeration, 1);
360  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
361 
362  glBegin(GL_TRIANGLES);
363  glColor3d(1, .8f, 0);
364  // base
365  glVertex2d(0 - 1.4, 0);
366  glVertex2d(0 - 1.4, 6);
367  glVertex2d(0 + 1.4, 6);
368  glVertex2d(0 + 1.4, 0);
369  glVertex2d(0 - 1.4, 0);
370  glVertex2d(0 + 1.4, 6);
371  glEnd();
372 
373  // draw text
374  if (s.scale * exaggeration >= 1.) {
375  glTranslated(0, 0, .1);
376  GLHelper::drawText("C", Position(0, 2), 0.1, 3, RGBColor::BLACK, 180);
377  GLHelper::drawText(flow, Position(0, 4), 0.1, 0.7, RGBColor::BLACK, 180);
378  GLHelper::drawText(speed, Position(0, 5), 0.1, 0.7, RGBColor::BLACK, 180);
379  }
381  }
382  drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
384 }
385 
386 
387 double
389  return s.addSize.getExaggeration(s, this);
390 }
391 
392 
393 Boundary
395  Boundary b(myBoundary);
396  b.grow(20);
397  return b;
398 }
399 
400 
404  GUIManip_Calibrator* gui =
405  new GUIManip_Calibrator(app, getFullName(), *this, 0, 0);
406  gui->create();
407  gui->show();
408  return gui;
409 }
410 
411 
412 /****************************************************************************/
@ MID_MANIP
Open the object's manipulator.
Definition: GUIAppEnum.h:489
FXDEFMAP(GUICalibrator::GUICalibratorPopupMenu) GUICalibratorPopupMenuMap[]
#define GUIDesignComboBoxVisibleItemsSmall
Definition: GUIDesigns.h:49
@ GLO_CALIBRATOR
a Calibrator
GUIIcon
An enumeration of icons used by the gui applications.
Definition: GUIIcons.h:33
#define TL(string)
Definition: MsgHandler.h:315
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition: SUMOTime.cpp:69
#define STEPS2TIME(x)
Definition: SUMOTime.h:55
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:39
void add(double x, double y, double z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:78
Boundary & grow(double by)
extends the boundary by the given amount
Definition: Boundary.cpp:319
static void pushName(unsigned int name)
push Name
Definition: GLHelper.cpp:139
static void popMatrix()
pop matrix
Definition: GLHelper.cpp:130
static void popName()
pop Name
Definition: GLHelper.cpp:148
static void pushMatrix()
push matrix
Definition: GLHelper.cpp:117
static void drawText(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &col=RGBColor::BLACK, const double angle=0, const int align=0, double width=-1)
Definition: GLHelper.cpp:756
long onCmdOpenManip(FXObject *, FXSelector, void *)
Called if the object's manipulator shall be shown.
long onCmdClose(FXObject *, FXSelector, void *)
long onCmdChangeOption(FXObject *, FXSelector, void *)
long onCmdUserDef(FXObject *, FXSelector, void *)
long onCmdPreDef(FXObject *, FXSelector, void *)
virtual ~GUIManip_Calibrator()
Destructor.
long onUpdUserDef(FXObject *, FXSelector, void *)
long onUpdPreDef(FXObject *, FXSelector, void *)
Changes the speed allowed on a set of lanes (gui version)
Definition: GUICalibrator.h:42
bool myShowAsKMH
The information whether the speed shall be shown in m/s or km/h.
MSCalibrator * myCalibrator
the calibrator being wrapped
double getExaggeration(const GUIVisualizationSettings &s) const
return exaggeration associated with this GLObject
RotCont myFGRotations
The rotations in full-geometry mode.
PosCont myFGPositions
The positions in full-geometry mode.
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own parameter window.
void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
GUIManipulator * openManipulator(GUIMainWindow &app, GUISUMOAbstractView &parent)
Boundary myBoundary
The boundary of this rerouter.
GUICalibrator(MSCalibrator *calibrator)
Constructor.
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
static FXButton * buildFXButton(FXComposite *p, const std::string &text, const std::string &tip, const std::string &help, FXIcon *ic, FXObject *tgt, FXSelector sel, FXuint opts=BUTTON_NORMAL, FXint x=0, FXint y=0, FXint w=0, FXint h=0, FXint pl=DEFAULT_PAD, FXint pr=DEFAULT_PAD, FXint pt=DEFAULT_PAD, FXint pb=DEFAULT_PAD)
build button
Definition: GUIDesigns.cpp:128
The popup menu of a globject.
const std::string & getFullName() const
Definition: GUIGlObject.h:94
void buildShowParamsPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to open the parameter window.
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
void buildNameCopyPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds entries which allow to copy the name / typed name into the clipboard.
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
Definition: GUIGlObject.h:156
void buildSelectionPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to (de)select the object.
void buildPositionCopyEntry(GUIGLObjectPopupMenu *ret, const GUIMainWindow &app) const
Builds an entry which allows to copy the cursor position if geo projection is used,...
GUIGlID getGlID() const
Returns the numerical id of the object.
Definition: GUIGlObject.h:104
void drawName(const Position &pos, const double scale, const GUIVisualizationTextSettings &settings, const double angle=0, bool forceShow=false) const
draw name of item
A window containing a gl-object's parameter.
void mkItem(const char *name, bool dynamic, ValueSource< T > *src)
Adds a row which obtains its value from a ValueSource.
void closeBuilding(const Parameterised *p=0)
Closes the building of the table.
Stores the information about how to visualize structures.
GUIVisualizationTextSettings addName
GUIVisualizationSizeSettings addSize
double scale
information about a lane's width (temporary, used for a single view)
ComboBox with icon.
Calibrates the flow on a segment to a specified one.
Definition: MSCalibrator.h:47
double currentSpeed() const
measured speed in the current interval
bool isActive() const
Definition: MSCalibrator.h:234
const MSLane * getLane() const
Definition: MSCalibrator.h:113
virtual int passed() const
Definition: MSCalibrator.h:121
std::vector< AspiredState >::const_iterator myCurrentStateInterval
Iterator pointing to the current interval.
Definition: MSCalibrator.h:319
int clearedInJam() const
Definition: MSCalibrator.h:268
double currentFlow() const
flow in the current interval in veh/h
std::vector< AspiredState > myIntervals
List of adaptation intervals.
Definition: MSCalibrator.h:317
const double myPos
the position on the edge where this calibrator lies
Definition: MSCalibrator.h:306
int totalWished() const
number of vehicles expected to pass this interval
double myDefaultSpeed
The default (maximum) speed on the segment.
Definition: MSCalibrator.h:347
int removed() const
Definition: MSCalibrator.h:265
int inserted() const
Definition: MSCalibrator.h:262
const MSEdge * getEdge() const
Definition: MSCalibrator.h:109
MSJunction *const myNode
the junction on which this calibrator lies (nullptr if is edge or lane specific)
Definition: MSCalibrator.h:304
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:168
const Position & getPosition(bool secondaryShape=false) const
Definition: MSJunction.cpp:68
Representation of a lane in the micro simulation.
Definition: MSLane.h:84
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
double x() const
Returns the x-position.
Definition: Position.h:55
double y() const
Returns the y-position.
Definition: Position.h:60
A list of positions.
double rotationDegreeAtOffset(double pos) const
Returns the rotation at the given length.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
static const RGBColor BLACK
Definition: RGBColor.h:193
Definition: json.hpp:4471
double getExaggeration(const GUIVisualizationSettings &s, const GUIGlObject *o, double factor=20) const
return the drawing size including exaggeration and constantSize values