LCOV - code coverage report
Current view: top level - src/guisim - GUIOverheadWire.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 69.6 % 181 126
Test Date: 2024-11-22 15:46:21 Functions: 62.5 % 16 10

            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              : /// @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           12 : GUIOverheadWire::GUIOverheadWire(const std::string& id, MSLane& lane, double frompos, double topos, bool voltageSource) :
      56              :     MSOverheadWire(id, lane, frompos, topos, voltageSource),
      57           12 :     GUIGlObject_AbstractAdd(GLO_OVERHEAD_WIRE_SEGMENT, id, GUIIconSubSys::getIcon(GUIIcon::OVERHEADWIRE)) {
      58              :     myFGShape = lane.getShape();
      59           24 :     myFGShape = myFGShape.getSubpart(
      60              :                     lane.interpolateLanePosToGeometryPos(frompos),
      61              :                     lane.interpolateLanePosToGeometryPos(topos));
      62           12 :     myFGShapeRotations.reserve(myFGShape.size() - 1);
      63           12 :     myFGShapeLengths.reserve(myFGShape.size() - 1);
      64           12 :     int e = (int)myFGShape.size() - 1;
      65           24 :     for (int i = 0; i < e; ++i) {
      66           12 :         const Position& f = myFGShape[i];
      67           12 :         const Position& s = myFGShape[i + 1];
      68           12 :         myFGShapeLengths.push_back(f.distanceTo(s));
      69           12 :         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           12 :     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           12 :     myFGSignPos = tmp[0];
      80              : 
      81           12 :     myFGSignRot = 0;
      82           12 :     if (tmp.length() != 0) {
      83           12 :         myFGSignRot = myFGShape.rotationDegreeAtOffset(double((myFGShape.length() / 2.)));
      84           12 :         const double rotSign = MSGlobals::gLefthand ? -1 : 1;
      85           12 :         myFGSignRot -= 90 * rotSign;
      86              :     }
      87           12 : }
      88              : 
      89              : 
      90           24 : GUIOverheadWire::~GUIOverheadWire() {
      91           24 : }
      92              : 
      93            1 : GUIOverheadWireClamp::GUIOverheadWireClamp(const std::string& id, MSLane& lane_start, MSLane& lane_end) :
      94            1 :     GUIGlObject_AbstractAdd(GLO_OVERHEAD_WIRE_SEGMENT, id, GUIIconSubSys::getIcon(GUIIcon::OVERHEADWIRE_CLAMP)) {
      95              :     myFGShape.clear();
      96            1 :     myFGShape.push_back(lane_start.getShape().front());
      97            1 :     myFGShape.push_back(lane_end.getShape().back());
      98            1 : }
      99              : 
     100            0 : GUIOverheadWireClamp::~GUIOverheadWireClamp() {
     101            0 : }
     102              : 
     103              : GUIParameterTableWindow*
     104            0 : GUIOverheadWire::getParameterWindow(GUIMainWindow& app, GUISUMOAbstractView&) {
     105              :     // Create table items
     106            0 :     GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this);
     107              : 
     108              :     // add items
     109            0 :     ret->mkItem(TL("begin position [m]"), false, myBegPos);
     110            0 :     ret->mkItem(TL("end position [m]"), false, myEndPos);
     111              :     //ret->mkItem(TL("voltage [V]"), false, myVoltage);
     112              : 
     113              :     // close building
     114            0 :     ret->closeBuilding();
     115            0 :     return ret;
     116              : }
     117              : 
     118              : 
     119              : GUIGLObjectPopupMenu*
     120            0 : GUIOverheadWire::getPopUpMenu(GUIMainWindow& app, GUISUMOAbstractView& parent) {
     121            0 :     GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
     122            0 :     buildPopupHeader(ret, app);
     123            0 :     buildCenterPopupEntry(ret);
     124            0 :     buildNameCopyPopupEntry(ret);
     125            0 :     buildSelectionPopupEntry(ret);
     126            0 :     buildShowParamsPopupEntry(ret);
     127            0 :     buildPositionCopyEntry(ret, app);
     128            0 :     return ret;
     129              : }
     130              : 
     131              : 
     132              : double
     133           28 : GUIOverheadWire::getExaggeration(const GUIVisualizationSettings& s) const {
     134           28 :     return s.addSize.getExaggeration(s, this);
     135              : }
     136              : 
     137              : 
     138              : Boundary
     139           40 : GUIOverheadWire::getCenteringBoundary() const {
     140           40 :     Boundary b = myFGShape.getBoxBoundary();
     141           40 :     b.grow(20);
     142           40 :     return b;
     143            0 : }
     144              : 
     145              : 
     146              : void
     147           28 : GUIOverheadWire::drawGL(const GUIVisualizationSettings& s) const {
     148              :     // Draw overhead wire segment
     149           28 :     GLHelper::pushName(getGlID());
     150           28 :     GLHelper::pushMatrix();
     151           28 :     RGBColor lightgray(211, 211, 211, 255);
     152           28 :     RGBColor green(76, 170, 50, 255);
     153           28 :     RGBColor yellow(255, 235, 0, 255);
     154           28 :     RGBColor yellowCharge(255, 180, 0, 255);
     155           28 :     RGBColor redCharge(255, 51, 51, 255);
     156           28 :     RGBColor redChargeOverheadWire(180, 0, 0, 255);
     157              : 
     158           56 :     GUIColorScheme scheme = GUIColorScheme("by overhead wire current", RGBColor::BLACK, "road", true);
     159              :     double range = 200;
     160           28 :     scheme.clear();
     161           28 :     scheme.addColor(RGBColor::RED, (0));
     162           28 :     scheme.addColor(RGBColor::ORANGE, (range * 1 / 6.0));
     163           28 :     scheme.addColor(RGBColor::YELLOW, (range * 2 / 6.0));
     164           28 :     scheme.addColor(RGBColor::GREEN, (range * 3 / 6.0));
     165           28 :     scheme.addColor(RGBColor::CYAN, (range * 4 / 6.0));
     166           28 :     scheme.addColor(RGBColor::BLUE, (range * 5 / 6.0));
     167           56 :     scheme.addColor(RGBColor::MAGENTA, (200));
     168              : 
     169              :     // draw the area depending if the vehicle is charging
     170           28 :     glTranslated(0, 0, getType());
     171              : 
     172              :     // get relative line thickness
     173           28 :     const double exaggeration = getExaggeration(s);
     174              : 
     175              :     //right catenary
     176           28 :     double toPos = getEndLanePosition();
     177              :     double fromPos = 0;
     178              :     PositionVector myFGShape_aux = myFGShape;
     179           28 :     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           28 :     if (myCircuitStartNodePos != NULL) {
     187           16 :         voltage = myCircuitStartNodePos->getVoltage();
     188           16 :         GLHelper::setColor(scheme.getColor(MAX2(0.0, voltage - 400)));
     189              :     }
     190              : 
     191           28 :     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           28 :     lock();
     195           31 :     for (auto it = myChargingVehicles.begin(); it != myChargingVehicles.end(); ++it) {
     196              :         // position of the vehicle on the lane
     197            3 :         fromPos = (*it)->getPositionOnLane() - ((*it)->getVehicleType().getLength() / 2);
     198            3 :         if (fromPos < 0) {
     199              :             fromPos = 0;
     200              :         };
     201              : 
     202              :         myFGShape_aux = myFGShape;
     203            6 :         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            3 :         myFGShapeRotations_aux.reserve(myFGShape.size() - 1);
     211            3 :         myFGShapeLengths_aux.reserve(myFGShape.size() - 1);
     212              : 
     213            3 :         e_aux = (int)myFGShape_aux.size() - 1;
     214            6 :         for (int i = 0; i < e_aux; ++i) {
     215            3 :             const Position& f_aux = myFGShape_aux[i];
     216            3 :             const Position& s_aux = myFGShape_aux[i + 1];
     217            3 :             myFGShapeLengths_aux.push_back(f_aux.distanceTo(s_aux));
     218            3 :             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            3 :         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            0 :             circuit->lock();
     227            0 :             node = circuit->getNode("pos_" + (*it)->getID());
     228            0 :             if (node != nullptr) {
     229            0 :                 voltage = node->getVoltage();
     230              :             }
     231            0 :             circuit->unlock();
     232              :         }
     233            3 :         GLHelper::setColor(scheme.getColor(MAX2(0.0, voltage - 400)));
     234            3 :         GLHelper::drawBoxLines(myFGShape_aux, myFGShapeRotations_aux, myFGShapeLengths_aux, exaggeration / 8, 0, 0.5);
     235              : 
     236              :         toPos = fromPos;
     237              :     }
     238           28 :     unlock();
     239              : 
     240              :     // coloring the last remaining part of wire's segment
     241              :     myFGShape_aux = myFGShape;
     242              : 
     243           56 :     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           28 :     myFGShapeRotations_aux.reserve(myFGShape.size() - 1);
     251           28 :     myFGShapeLengths_aux.reserve(myFGShape.size() - 1);
     252              : 
     253           28 :     e_aux = (int)myFGShape_aux.size() - 1;
     254           56 :     for (int i = 0; i < e_aux; ++i) {
     255           28 :         const Position& f_aux = myFGShape_aux[i];
     256           28 :         const Position& s_aux = myFGShape_aux[i + 1];
     257           28 :         myFGShapeLengths_aux.push_back(f_aux.distanceTo(s_aux));
     258           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);
     259              :     }
     260           28 :     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           28 :     if (getElecHybridCount() > 0) {
     269            2 :         GLHelper::setColor(redChargeOverheadWire);
     270           26 :     } else if (myTractionSubstation != NULL && myTractionSubstation->getElecHybridCount() > 0) {
     271            0 :         GLHelper::setColor(yellowCharge);
     272              :     } else {
     273           26 :         GLHelper::setColor(green);
     274              :     }
     275           28 :     GLHelper::drawBoxLines(myFGShape, myFGShapeRotations, myFGShapeLengths, exaggeration / 8, 0, -0.5);
     276              : 
     277              : 
     278              :     // draw details unless zoomed out to far
     279           28 :     if (s.scale * exaggeration >= 10 && myVoltageSource) {
     280              : 
     281              :         // push charging power matrix
     282            0 :         GLHelper::pushMatrix();
     283              :         // draw charging power
     284            0 :         const double lineAngle = s.getTextAngle(myFGSignRot);
     285            0 :         glTranslated(myFGSignPos.x(), myFGSignPos.y(), 0);
     286            0 :         glRotated(-lineAngle, 0, 0, 1);
     287            0 :         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            0 :         GLHelper::popMatrix();
     290              : 
     291              :         // draw the sign
     292            0 :         glTranslated(myFGSignPos.x(), myFGSignPos.y(), 0);
     293              :         int noPoints = 9;
     294            0 :         if (s.scale * exaggeration > 25) {
     295            0 :             noPoints = MIN2((int)(9.0 + (s.scale * exaggeration) / 10.0), 36);
     296              :         }
     297              : 
     298            0 :         glScaled(exaggeration, exaggeration, 1);
     299            0 :         GLHelper::drawFilledCircle((double) 1.1, noPoints);
     300            0 :         glTranslated(0, 0, .1);
     301              : 
     302            0 :         GLHelper::setColor(yellow);
     303            0 :         GLHelper::drawFilledCircle((double) 0.9, noPoints);
     304              : 
     305            0 :         if (s.scale * exaggeration >= 4.5) {
     306            0 :             GLHelper::drawText("C", Position(), .1, 1.6, lightgray, myFGSignRot);
     307              :         }
     308              : 
     309            0 :         glTranslated(5, 0, 0);
     310              : 
     311              :     }
     312              : 
     313              : 
     314           28 :     GLHelper::popMatrix();
     315           28 :     GLHelper::popName();
     316           28 :     drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
     317           28 : }
     318              : 
     319              : 
     320              : GUIParameterTableWindow*
     321            0 : GUIOverheadWireClamp::getParameterWindow(GUIMainWindow& app, GUISUMOAbstractView&) {
     322              :     // Create table items
     323            0 :     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            0 :     ret->closeBuilding();
     332            0 :     return ret;
     333              : }
     334              : 
     335              : 
     336              : GUIGLObjectPopupMenu*
     337            0 : GUIOverheadWireClamp::getPopUpMenu(GUIMainWindow& app, GUISUMOAbstractView& parent) {
     338            0 :     GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
     339            0 :     buildPopupHeader(ret, app);
     340            0 :     buildCenterPopupEntry(ret);
     341            0 :     buildNameCopyPopupEntry(ret);
     342            0 :     buildSelectionPopupEntry(ret);
     343            0 :     buildShowParamsPopupEntry(ret);
     344            0 :     buildPositionCopyEntry(ret, app);
     345            0 :     return ret;
     346              : }
     347              : 
     348              : 
     349              : double
     350            2 : GUIOverheadWireClamp::getExaggeration(const GUIVisualizationSettings& s) const {
     351            2 :     return s.addSize.getExaggeration(s, this);
     352              : }
     353              : 
     354              : 
     355              : Boundary
     356            3 : GUIOverheadWireClamp::getCenteringBoundary() const {
     357            3 :     Boundary b = myFGShape.getBoxBoundary();
     358            3 :     b.grow(20);
     359            3 :     return b;
     360            0 : }
     361              : 
     362              : 
     363              : void
     364            2 : GUIOverheadWireClamp::drawGL(const GUIVisualizationSettings& s) const {
     365              :     // Draw overhead wire segment
     366            2 :     GLHelper::pushName(getGlID());
     367            2 :     GLHelper::pushMatrix();
     368            2 :     RGBColor lightgray(211, 211, 211, 255);
     369            2 :     RGBColor green(76, 170, 50, 255);
     370            2 :     RGBColor yellow(255, 235, 0, 255);
     371            2 :     RGBColor yellowCharge(255, 180, 0, 255);
     372            2 :     RGBColor redCharge(255, 51, 51, 255);
     373            2 :     RGBColor redChargeOverheadWire(180, 0, 0, 255);
     374              : 
     375              :     // draw the area depending if the vehicle is charging
     376            2 :     glTranslated(0, 0, getType());
     377              : 
     378              : 
     379            2 :     GLHelper::setColor(redChargeOverheadWire);
     380              : 
     381              : 
     382            2 :     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            2 :     myFGShapeRotations_aux.reserve(myFGShape.size() - 1);
     395            2 :     myFGShapeLengths_aux.reserve(myFGShape.size() - 1);
     396              : 
     397            2 :     int e_aux = (int)myFGShape_aux.size() - 1;
     398            4 :     for (int i = 0; i < e_aux; ++i) {
     399            2 :         const Position& f_aux = myFGShape_aux[i];
     400            2 :         const Position& s_aux = myFGShape_aux[i + 1];
     401            2 :         myFGShapeLengths_aux.push_back(f_aux.distanceTo(s_aux));
     402            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);
     403              :     }
     404              : 
     405              :     //GLHelper::setColor(green);
     406            2 :     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            2 :     GLHelper::popMatrix();
     413            2 :     GLHelper::popName();
     414            2 :     drawName(getCenteringBoundary().getCenter(), s.scale, s.addName);
     415            2 : }
     416              : 
     417              : 
     418              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1