Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/guisim/GUIOverheadWire.cpp
169665 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 GUIOverheadWire.cpp
15
/// @author Jakub Sevcik (RICE)
16
/// @author Jan Prikryl (RICE)
17
/// @author Mirko Barthauer
18
/// @date 2019-12-15
19
///
20
// The gui-version of a MSOverheadWire
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/geom/GeomHelper.h>
29
#include <utils/gui/div/GLHelper.h>
30
#include <utils/common/ToString.h>
31
#include <utils/traction_wire/Node.h>
32
#include <microsim/MSNet.h>
33
#include <microsim/MSLane.h>
34
#include <microsim/MSEdge.h>
35
#include <utils/gui/globjects/GUIGLObjectPopupMenu.h>
36
#include <utils/gui/windows/GUIAppEnum.h>
37
#include <gui/GUIGlobals.h>
38
#include <utils/gui/div/GUIParameterTableWindow.h>
39
#include <gui/GUIApplicationWindow.h>
40
#include <microsim/logging/FunctionBinding.h>
41
#include <utils/gui/div/GUIGlobalSelection.h>
42
#include <foreign/fontstash/fontstash.h>
43
#include <utils/gui/globjects/GLIncludes.h>
44
#include <utils/vehicle/SUMOVehicle.h>
45
#include <microsim/MSVehicleType.h>
46
#include "GUINet.h"
47
#include "GUIEdge.h"
48
#include "GUIPerson.h"
49
#include "GUIOverheadWire.h"
50
51
52
// ===========================================================================
53
// method definitions
54
// ===========================================================================
55
GUIOverheadWire::GUIOverheadWire(const std::string& id, MSLane& lane, double frompos, double topos, bool voltageSource) :
56
MSOverheadWire(id, lane, frompos, topos, voltageSource),
57
GUIGlObject_AbstractAdd(GLO_OVERHEAD_WIRE_SEGMENT, id, GUIIconSubSys::getIcon(GUIIcon::OVERHEADWIRE)) {
58
myFGShape = lane.getShape();
59
myFGShape = myFGShape.getSubpart(
60
lane.interpolateLanePosToGeometryPos(frompos),
61
lane.interpolateLanePosToGeometryPos(topos));
62
myFGShapeRotations.reserve(myFGShape.size() - 1);
63
myFGShapeLengths.reserve(myFGShape.size() - 1);
64
int e = (int)myFGShape.size() - 1;
65
for (int i = 0; i < e; ++i) {
66
const Position& f = myFGShape[i];
67
const Position& s = myFGShape[i + 1];
68
myFGShapeLengths.push_back(f.distanceTo(s));
69
myFGShapeRotations.push_back((double)atan2((s.x() - f.x()), (f.y() - s.y())) * (double) 180.0 / (double)M_PI);
70
}
71
PositionVector tmp = myFGShape;
72
tmp.move2side(1.5);
73
74
// position of the centre of the lane + move2side
75
//myFGSignPos = tmp.getLineCenter();
76
77
// position of beginning of the lane + move2side (2 equivallent commands ?)
78
//myFGSignPos = tmp.positionAtOffset(double(0.0));
79
myFGSignPos = tmp[0];
80
81
myFGSignRot = 0;
82
if (tmp.length() != 0) {
83
myFGSignRot = myFGShape.rotationDegreeAtOffset(double((myFGShape.length() / 2.)));
84
const double rotSign = MSGlobals::gLefthand ? -1 : 1;
85
myFGSignRot -= 90 * rotSign;
86
}
87
}
88
89
90
GUIOverheadWire::~GUIOverheadWire() {
91
}
92
93
GUIOverheadWireClamp::GUIOverheadWireClamp(const std::string& id, MSLane& lane_start, MSLane& lane_end) :
94
GUIGlObject_AbstractAdd(GLO_OVERHEAD_WIRE_SEGMENT, id, GUIIconSubSys::getIcon(GUIIcon::OVERHEADWIRE_CLAMP)) {
95
myFGShape.clear();
96
myFGShape.push_back(lane_start.getShape().front());
97
myFGShape.push_back(lane_end.getShape().back());
98
}
99
100
GUIOverheadWireClamp::~GUIOverheadWireClamp() {
101
}
102
103
GUIParameterTableWindow*
104
GUIOverheadWire::getParameterWindow(GUIMainWindow& app, GUISUMOAbstractView&) {
105
// Create table items
106
GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this);
107
108
// add items
109
ret->mkItem(TL("begin position [m]"), false, myBegPos);
110
ret->mkItem(TL("end position [m]"), false, myEndPos);
111
//ret->mkItem(TL("voltage [V]"), false, myVoltage);
112
113
// close building
114
ret->closeBuilding();
115
return ret;
116
}
117
118
119
GUIGLObjectPopupMenu*
120
GUIOverheadWire::getPopUpMenu(GUIMainWindow& app, GUISUMOAbstractView& parent) {
121
GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, this);
122
buildPopupHeader(ret, app);
123
buildCenterPopupEntry(ret);
124
buildNameCopyPopupEntry(ret);
125
buildSelectionPopupEntry(ret);
126
buildShowParamsPopupEntry(ret);
127
buildPositionCopyEntry(ret, app);
128
return ret;
129
}
130
131
132
double
133
GUIOverheadWire::getExaggeration(const GUIVisualizationSettings& s) const {
134
return s.addSize.getExaggeration(s, this);
135
}
136
137
138
Boundary
139
GUIOverheadWire::getCenteringBoundary() const {
140
Boundary b = myFGShape.getBoxBoundary();
141
b.grow(20);
142
return b;
143
}
144
145
146
void
147
GUIOverheadWire::drawGL(const GUIVisualizationSettings& s) const {
148
// Draw overhead wire segment
149
GLHelper::pushName(getGlID());
150
GLHelper::pushMatrix();
151
RGBColor lightgray(211, 211, 211, 255);
152
RGBColor green(76, 170, 50, 255);
153
RGBColor yellow(255, 235, 0, 255);
154
RGBColor yellowCharge(255, 180, 0, 255);
155
RGBColor redCharge(255, 51, 51, 255);
156
RGBColor redChargeOverheadWire(180, 0, 0, 255);
157
158
GUIColorScheme scheme = GUIColorScheme("by overhead wire current", RGBColor::BLACK, "road", true);
159
double range = 200;
160
scheme.clear();
161
scheme.addColor(RGBColor::RED, (0));
162
scheme.addColor(RGBColor::ORANGE, (range * 1 / 6.0));
163
scheme.addColor(RGBColor::YELLOW, (range * 2 / 6.0));
164
scheme.addColor(RGBColor::GREEN, (range * 3 / 6.0));
165
scheme.addColor(RGBColor::CYAN, (range * 4 / 6.0));
166
scheme.addColor(RGBColor::BLUE, (range * 5 / 6.0));
167
scheme.addColor(RGBColor::MAGENTA, (200));
168
169
// draw the area depending if the vehicle is charging
170
glTranslated(0, 0, getType());
171
172
// get relative line thickness
173
const double exaggeration = getExaggeration(s);
174
175
//right catenary
176
double toPos = getEndLanePosition();
177
double fromPos = 0;
178
PositionVector myFGShape_aux = myFGShape;
179
const MSLane& lane_aux = getLane();
180
std::vector<double> myFGShapeRotations_aux;
181
std::vector<double> myFGShapeLengths_aux;
182
int e_aux = 0;
183
Node* node = NULL;
184
double voltage = 0;
185
186
if (myCircuitStartNodePos != NULL) {
187
voltage = myCircuitStartNodePos->getVoltage();
188
GLHelper::setColor(scheme.getColor(MAX2(0.0, voltage - 400)));
189
}
190
191
Circuit* circuit = getCircuit();
192
// loop over charging vehicles under the overhead wire segment to color the wire segment parts according to the voltage level
193
// lock access to myChargingVehicles
194
lock();
195
for (auto it = myChargingVehicles.begin(); it != myChargingVehicles.end(); ++it) {
196
// position of the vehicle on the lane
197
fromPos = (*it)->getPositionOnLane() - ((*it)->getVehicleType().getLength() / 2);
198
if (fromPos < 0) {
199
fromPos = 0;
200
};
201
202
myFGShape_aux = myFGShape;
203
myFGShape_aux = myFGShape_aux.getSubpart(
204
lane_aux.interpolateLanePosToGeometryPos(fromPos),
205
lane_aux.interpolateLanePosToGeometryPos(toPos));
206
207
myFGShapeRotations_aux.clear();
208
myFGShapeLengths_aux.clear();
209
210
myFGShapeRotations_aux.reserve(myFGShape.size() - 1);
211
myFGShapeLengths_aux.reserve(myFGShape.size() - 1);
212
213
e_aux = (int)myFGShape_aux.size() - 1;
214
for (int i = 0; i < e_aux; ++i) {
215
const Position& f_aux = myFGShape_aux[i];
216
const Position& s_aux = myFGShape_aux[i + 1];
217
myFGShapeLengths_aux.push_back(f_aux.distanceTo(s_aux));
218
myFGShapeRotations_aux.push_back((double)atan2((s_aux.x() - f_aux.x()), (f_aux.y() - s_aux.y())) * (double) 180.0 / (double)M_PI);
219
}
220
221
voltage = 0;
222
if (circuit != nullptr) {
223
// RICE_CHECK: it caused crash of SUMO GUI often in debug mode and
224
// vector "_STL_VERIFY(_Mycont->_Myfirst <= _Ptr && _Ptr < _Mycont->_Mylast,
225
// "can't dereference out of range vector iterator"); "
226
circuit->lock();
227
node = circuit->getNode("pos_" + (*it)->getID());
228
if (node != nullptr) {
229
voltage = node->getVoltage();
230
}
231
circuit->unlock();
232
}
233
GLHelper::setColor(scheme.getColor(MAX2(0.0, voltage - 400)));
234
GLHelper::drawBoxLines(myFGShape_aux, myFGShapeRotations_aux, myFGShapeLengths_aux, exaggeration / 8, 0, 0.5);
235
236
toPos = fromPos;
237
}
238
unlock();
239
240
// coloring the last remaining part of wire's segment
241
myFGShape_aux = myFGShape;
242
243
myFGShape_aux = myFGShape_aux.getSubpart(
244
lane_aux.interpolateLanePosToGeometryPos(getBeginLanePosition()),
245
lane_aux.interpolateLanePosToGeometryPos(toPos));
246
247
myFGShapeRotations_aux.clear();
248
myFGShapeLengths_aux.clear();
249
250
myFGShapeRotations_aux.reserve(myFGShape.size() - 1);
251
myFGShapeLengths_aux.reserve(myFGShape.size() - 1);
252
253
e_aux = (int)myFGShape_aux.size() - 1;
254
for (int i = 0; i < e_aux; ++i) {
255
const Position& f_aux = myFGShape_aux[i];
256
const Position& s_aux = myFGShape_aux[i + 1];
257
myFGShapeLengths_aux.push_back(f_aux.distanceTo(s_aux));
258
myFGShapeRotations_aux.push_back((double)atan2((s_aux.x() - f_aux.x()), (f_aux.y() - s_aux.y())) * (double) 180.0 / (double)M_PI);
259
}
260
GLHelper::drawBoxLines(myFGShape_aux, myFGShapeRotations_aux, myFGShapeLengths_aux, exaggeration / 8, 0, 0.5);
261
262
263
//left catenary
264
//coloring of left-side overhead wire segment in case of
265
// * a vehicle is under the segment
266
// * a vehicle is at least under the traction substation of the segment
267
// * no vehicle is connected to the traction substation of the segment
268
if (getElecHybridCount() > 0) {
269
GLHelper::setColor(redChargeOverheadWire);
270
} else if (myTractionSubstation != NULL && myTractionSubstation->getElecHybridCount() > 0) {
271
GLHelper::setColor(yellowCharge);
272
} else {
273
GLHelper::setColor(green);
274
}
275
GLHelper::drawBoxLines(myFGShape, myFGShapeRotations, myFGShapeLengths, exaggeration / 8, 0, -0.5);
276
277
278
// draw details unless zoomed out to far
279
if (s.scale * exaggeration >= 10 && myVoltageSource) {
280
281
// push charging power matrix
282
GLHelper::pushMatrix();
283
// draw charging power
284
const double lineAngle = s.getTextAngle(myFGSignRot);
285
glTranslated(myFGSignPos.x(), myFGSignPos.y(), 0);
286
glRotated(-lineAngle, 0, 0, 1);
287
GLHelper::drawText((toString(getTractionSubstation()->getSubstationVoltage()) + " V").c_str(), Position(1.2, 0), .1, 1.f, RGBColor(114, 210, 252), 0, FONS_ALIGN_LEFT);
288
// pop charging power matrix
289
GLHelper::popMatrix();
290
291
// draw the sign
292
glTranslated(myFGSignPos.x(), myFGSignPos.y(), 0);
293
int noPoints = 9;
294
if (s.scale * exaggeration > 25) {
295
noPoints = MIN2((int)(9.0 + (s.scale * exaggeration) / 10.0), 36);
296
}
297
298
glScaled(exaggeration, exaggeration, 1);
299
GLHelper::drawFilledCircle((double) 1.1, noPoints);
300
glTranslated(0, 0, .1);
301
302
GLHelper::setColor(yellow);
303
GLHelper::drawFilledCircle((double) 0.9, noPoints);
304
305
if (s.scale * exaggeration >= 4.5) {
306
GLHelper::drawText("C", Position(), .1, 1.6, lightgray, myFGSignRot);
307
}
308
309
glTranslated(5, 0, 0);
310
311
}
312
313
314
GLHelper::popMatrix();
315
GLHelper::popName();
316
drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
317
}
318
319
320
GUIParameterTableWindow*
321
GUIOverheadWireClamp::getParameterWindow(GUIMainWindow& app, GUISUMOAbstractView&) {
322
// Create table items
323
GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this);
324
325
// add items
326
//ret->mkItem(TL("begin position [m]"), false, NAN);
327
//ret->mkItem(TL("end position [m]"), false, NAN);
328
//ret->mkItem(TL("voltage [V]"), false, NAN);
329
330
// close building
331
ret->closeBuilding();
332
return ret;
333
}
334
335
336
GUIGLObjectPopupMenu*
337
GUIOverheadWireClamp::getPopUpMenu(GUIMainWindow& app, GUISUMOAbstractView& parent) {
338
GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, this);
339
buildPopupHeader(ret, app);
340
buildCenterPopupEntry(ret);
341
buildNameCopyPopupEntry(ret);
342
buildSelectionPopupEntry(ret);
343
buildShowParamsPopupEntry(ret);
344
buildPositionCopyEntry(ret, app);
345
return ret;
346
}
347
348
349
double
350
GUIOverheadWireClamp::getExaggeration(const GUIVisualizationSettings& s) const {
351
return s.addSize.getExaggeration(s, this);
352
}
353
354
355
Boundary
356
GUIOverheadWireClamp::getCenteringBoundary() const {
357
Boundary b = myFGShape.getBoxBoundary();
358
b.grow(20);
359
return b;
360
}
361
362
363
void
364
GUIOverheadWireClamp::drawGL(const GUIVisualizationSettings& s) const {
365
// Draw overhead wire segment
366
GLHelper::pushName(getGlID());
367
GLHelper::pushMatrix();
368
RGBColor lightgray(211, 211, 211, 255);
369
RGBColor green(76, 170, 50, 255);
370
RGBColor yellow(255, 235, 0, 255);
371
RGBColor yellowCharge(255, 180, 0, 255);
372
RGBColor redCharge(255, 51, 51, 255);
373
RGBColor redChargeOverheadWire(180, 0, 0, 255);
374
375
// draw the area depending if the vehicle is charging
376
glTranslated(0, 0, getType());
377
378
379
GLHelper::setColor(redChargeOverheadWire);
380
381
382
const double exaggeration = getExaggeration(s);
383
//exaggeration - wide of line
384
385
386
387
PositionVector myFGShape_aux = myFGShape;
388
std::vector<double> myFGShapeRotations_aux;
389
std::vector<double> myFGShapeLengths_aux;
390
391
myFGShapeRotations_aux.clear();
392
myFGShapeLengths_aux.clear();
393
394
myFGShapeRotations_aux.reserve(myFGShape.size() - 1);
395
myFGShapeLengths_aux.reserve(myFGShape.size() - 1);
396
397
int e_aux = (int)myFGShape_aux.size() - 1;
398
for (int i = 0; i < e_aux; ++i) {
399
const Position& f_aux = myFGShape_aux[i];
400
const Position& s_aux = myFGShape_aux[i + 1];
401
myFGShapeLengths_aux.push_back(f_aux.distanceTo(s_aux));
402
myFGShapeRotations_aux.push_back((double)atan2((s_aux.x() - f_aux.x()), (f_aux.y() - s_aux.y())) * (double) 180.0 / (double)M_PI);
403
}
404
405
//GLHelper::setColor(green);
406
GLHelper::drawBoxLines(myFGShape_aux, myFGShapeRotations_aux, myFGShapeLengths_aux, exaggeration / 8, 0, 0.5);
407
408
//GLHelper::drawBoxLines(myFGShape, myFGShapeRotations, myFGShapeLengths, exaggeration / 8, 0, -0.5);
409
410
411
412
GLHelper::popMatrix();
413
GLHelper::popName();
414
drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
415
}
416
417
418
/****************************************************************************/
419
420