LCOV - code coverage report
Current view: top level - src/guisim - GUIOverheadWire.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 126 178 70.8 %
Date: 2024-04-28 15:39:05 Functions: 10 16 62.5 %

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

Generated by: LCOV version 1.14