LCOV - code coverage report
Current view: top level - src/mesogui - GUIMEVehicle.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 14.4 % 139 20
Test Date: 2026-03-02 16:00:03 Functions: 37.5 % 16 6

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2001-2026 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    GUIMEVehicle.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @date    Sept 2002
      19              : ///
      20              : // A MSVehicle extended by some values for usage within the gui
      21              : /****************************************************************************/
      22              : #include <config.h>
      23              : 
      24              : #include <utils/gui/globjects/GLIncludes.h>
      25              : #include <utils/gui/div/GLHelper.h>
      26              : #include <utils/gui/div/GUIParameterTableWindow.h>
      27              : #include <utils/gui/div/GUIGlobalSelection.h>
      28              : #include <utils/gui/div/GUIBaseVehicleHelper.h>
      29              : #include <utils/emissions/PollutantsInterface.h>
      30              : #include <utils/gui/settings/GUIVisualizationSettings.h>
      31              : #include <microsim/MSStop.h>
      32              : #include <microsim/MSParkingArea.h>
      33              : #include <microsim/logging/CastingFunctionBinding.h>
      34              : #include <microsim/logging/FunctionBinding.h>
      35              : #include <microsim/devices/MSVehicleDevice.h>
      36              : #include <guisim/GUILane.h>
      37              : 
      38              : #include "GUIMEVehicle.h"
      39              : 
      40              : 
      41              : // ===========================================================================
      42              : // method definitions
      43              : // ===========================================================================
      44              : #ifdef _MSC_VER
      45              : #pragma warning(push)
      46              : #pragma warning(disable: 4355) // mask warning about "this" in initializers
      47              : #endif
      48       303641 : GUIMEVehicle::GUIMEVehicle(SUMOVehicleParameter* pars, ConstMSRoutePtr route,
      49       303641 :                            MSVehicleType* type, const double speedFactor) :
      50              :     MEVehicle(pars, route, type, speedFactor),
      51       607282 :     GUIBaseVehicle((MSBaseVehicle&) * this) {
      52       303641 : }
      53              : #ifdef _MSC_VER
      54              : #pragma warning(pop)
      55              : #endif
      56              : 
      57              : 
      58       607272 : GUIMEVehicle::~GUIMEVehicle() {
      59       303636 :     gSelected.deselect(GLO_VEHICLE, getGlID());
      60       303636 :     cleanupOnDestruction();
      61       607272 : }
      62              : 
      63              : 
      64              : GUIParameterTableWindow*
      65            0 : GUIMEVehicle::getParameterWindow(GUIMainWindow& app,
      66              :                                  GUISUMOAbstractView&) {
      67            0 :     GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this);
      68              :     // add items
      69            0 :     ret->mkItem("edge [id]", true, new FunctionBindingString<GUIMEVehicle>(this, &GUIMEVehicle::getEdgeID));
      70            0 :     ret->mkItem("segment [#]", true,  new FunctionBinding<GUIMEVehicle, int>(this, &GUIMEVehicle::getSegmentIndex));
      71            0 :     ret->mkItem("queue [#]", true,  new FunctionBinding<GUIMEVehicle, int>(this, &GUIMEVehicle::getQueIndex));
      72            0 :     ret->mkItem("position [m]", true, new FunctionBinding<GUIMEVehicle, double>(this, &MEVehicle::getPositionOnLane));
      73            0 :     ret->mkItem("speed [m/s]", true, new FunctionBinding<GUIMEVehicle, double>(this, &MEVehicle::getSpeed));
      74            0 :     ret->mkItem("angle [degree]", true, new FunctionBinding<GUIMEVehicle, double>(this, &GUIBaseVehicle::getNaviDegree));
      75            0 :     ret->mkItem("waiting time [s]", true,
      76            0 :                 new FunctionBinding<GUIMEVehicle, double>(this, &MEVehicle::getWaitingSeconds));
      77            0 :     ret->mkItem("speed factor", false, getChosenSpeedFactor());
      78              :     //ret->mkItem("time gap [s]", true,
      79              :     //            new FunctionBinding<GUIMEVehicle, double>(this, &MSVehicle::getTimeGap));
      80              :     //ret->mkItem("waiting time [s]", true,
      81              :     //            new FunctionBinding<GUIMEVehicle, double>(this, &MSVehicle::getWaitingSeconds));
      82              :     //ret->mkItem("impatience", true,
      83              :     //            new FunctionBinding<GUIMEVehicle, double>(this, &MSVehicle::getImpatience));
      84              :     //ret->mkItem("last lane change [s]", true,
      85              :     //            new FunctionBinding<GUIMEVehicle, double>(this, &GUIMEVehicle::getLastLaneChangeOffset));
      86            0 :     ret->mkItem("desired depart [s]", false, time2string(getParameter().depart));
      87            0 :     ret->mkItem("depart delay [s]", false, time2string(getDepartDelay()));
      88            0 :     ret->mkItem("odometer [m]", true,
      89            0 :                 new FunctionBinding<GUIMEVehicle, double>(this, &MSBaseVehicle::getOdometer));
      90            0 :     if (getParameter().repetitionNumber < std::numeric_limits<long long int>::max()) {
      91            0 :         ret->mkItem("remaining [#]", false, (long long int) getParameter().repetitionNumber - getParameter().repetitionsDone);
      92              :     }
      93            0 :     if (getParameter().repetitionOffset > 0) {
      94            0 :         ret->mkItem("insertion period [s]", false, time2string(getParameter().repetitionOffset));
      95              :     }
      96            0 :     if (getParameter().repetitionProbability > 0) {
      97            0 :         ret->mkItem("insertion probability", false, getParameter().repetitionProbability);
      98              :     }
      99            0 :     if (getParameter().poissonRate > 0) {
     100            0 :         ret->mkItem(TL("poisson rate"), false, getParameter().poissonRate);
     101              :     }
     102              :     //ret->mkItem("stop info", false, getStopInfo());
     103            0 :     ret->mkItem("line", false, myParameter->line);
     104              :     //ret->mkItem("CO2 [mg/s]", true,
     105              :     //            new FunctionBinding<GUIMEVehicle, double>(this, &GUIMEVehicle::getCO2Emissions));
     106              :     //ret->mkItem("CO [mg/s]", true,
     107              :     //            new FunctionBinding<GUIMEVehicle, double>(this, &GUIMEVehicle::getCOEmissions));
     108              :     //ret->mkItem("HC [mg/s]", true,
     109              :     //            new FunctionBinding<GUIMEVehicle, double>(this, &GUIMEVehicle::getHCEmissions));
     110              :     //ret->mkItem("NOx [mg/s]", true,
     111              :     //            new FunctionBinding<GUIMEVehicle, double>(this, &GUIMEVehicle::getNOxEmissions));
     112              :     //ret->mkItem("PMx [mg/s]", true,
     113              :     //            new FunctionBinding<GUIMEVehicle, double>(this, &GUIMEVehicle::getPMxEmissions));
     114              :     //ret->mkItem("fuel [ml/s]", true,
     115              :     //            new FunctionBinding<GUIMEVehicle, double>(this, &GUIMEVehicle::getFuelConsumption));
     116              :     //ret->mkItem("noise (Harmonoise) [dB]", true,
     117              :     //            new FunctionBinding<GUIMEVehicle, double>(this, &GUIMEVehicle::getHarmonoise_NoiseEmissions));
     118            0 :     ret->mkItem("devices", false, getDeviceDescription());
     119              :     //ret->mkItem("persons", true,
     120              :     //            new FunctionBinding<GUIMEVehicle, int>(this, &GUIMEVehicle::getPersonNumber));
     121              :     //ret->mkItem("containers", true,
     122              :     //            new FunctionBinding<GUIMEVehicle, int>(this, &GUIMEVehicle::getContainerNumber));
     123              :     // meso specific values
     124            0 :     ret->mkItem("event time [s]", true, new FunctionBinding<GUIMEVehicle, double>(this, &MEVehicle::getEventTimeSeconds));
     125            0 :     ret->mkItem("entry time [s]", true, new FunctionBinding<GUIMEVehicle, double>(this, &MEVehicle::getLastEntryTimeSeconds));
     126            0 :     ret->mkItem("block time [s]", true, new FunctionBinding<GUIMEVehicle, double>(this, &MEVehicle::getBlockTimeSeconds));
     127            0 :     ret->mkItem("link penalty [s]", true, new FunctionBinding<GUIMEVehicle, double>(this, &MEVehicle::getCurrentLinkPenaltySeconds));
     128            0 :     ret->mkItem("stop time [s]", true, new FunctionBinding<GUIMEVehicle, double>(this, &MEVehicle::getCurrentStoppingTimeSeconds));
     129              :     // close building
     130            0 :     ret->closeBuilding(&getParameter());
     131            0 :     return ret;
     132              : }
     133              : 
     134              : 
     135              : GUIParameterTableWindow*
     136            0 : GUIMEVehicle::getTypeParameterWindow(GUIMainWindow& app, GUISUMOAbstractView&) {
     137            0 :     GUIParameterTableWindow* ret = new GUIParameterTableWindow(app, *this, "vType:" + myType->getID());
     138            0 :     ret->mkItem("type", false, myType->getID());
     139            0 :     ret->mkItem("length [m]", false, myType->getLength());
     140            0 :     ret->mkItem("width [m]", false, myType->getWidth());
     141            0 :     ret->mkItem("height [m]", false, myType->getHeight());
     142            0 :     ret->mkItem("minGap [m]", false, myType->getMinGap());
     143            0 :     ret->mkItem("vehicle class", false, SumoVehicleClassStrings.getString(myType->getVehicleClass()));
     144            0 :     ret->mkItem("emission class", false, PollutantsInterface::getName(myType->getEmissionClass()));
     145            0 :     ret->mkItem("mass [kg]", false, myType->getMass());
     146            0 :     ret->mkItem("guiShape", false, getVehicleShapeName(myType->getGuiShape()));
     147            0 :     ret->mkItem("maximum speed [m/s]", false, getMaxSpeed());
     148            0 :     ret->mkItem("desired maximum speed [m/s]", false, getVehicleType().getDesiredMaxSpeed());
     149            0 :     ret->mkItem("desired headway (tau) [s]", false, getVehicleType().getCarFollowModel().getHeadwayTime());
     150            0 :     ret->mkItem("speedFactor", false, myType->getParameter().speedFactor.toStr(gPrecision));
     151            0 :     ret->mkItem("person capacity", false, myType->getPersonCapacity());
     152            0 :     ret->mkItem(TL("boarding time [s]"), false, STEPS2TIME(myType->getLoadingDuration(true)));
     153            0 :     ret->mkItem("container capacity", false, myType->getContainerCapacity());
     154            0 :     ret->mkItem(TL("loading time [s]"), false, STEPS2TIME(myType->getLoadingDuration(false)));
     155            0 :     ret->closeBuilding(&(myType->getParameter()));
     156            0 :     return ret;
     157              : }
     158              : 
     159              : 
     160              : void
     161            0 : GUIMEVehicle::drawAction_drawCarriageClass(const GUIVisualizationSettings& /* s */, double scaledLength, bool /* asImage */) const {
     162            0 :     GUIBaseVehicleHelper::drawAction_drawVehicleAsBoxPlus(getVType().getWidth(), scaledLength);
     163            0 : }
     164              : 
     165              : 
     166              : double
     167      1280058 : GUIMEVehicle::getColorValue(const GUIVisualizationSettings& /* s */, int activeScheme) const {
     168      1280058 :     switch (activeScheme) {
     169            0 :         case 8:
     170            0 :             return getSpeed();
     171              :         case 9:
     172              :             return 0; // by actionStep
     173            0 :         case 10:
     174            0 :             return getWaitingSeconds();
     175              :         case 11:
     176              :             return 0; // getAccumulatedWaitingSeconds
     177              :         case 12:
     178              :             return 0; // invalid getLastLaneChangeOffset();
     179            0 :         case 13:
     180            0 :             return getSegment()->getEdge().getVehicleMaxSpeed(this);
     181              :         case 14:
     182              :             return 0; // invalid getEmissions<PollutantsInterface::CO2>();
     183              :         case 15:
     184              :             return 0; // invalid getEmissions<PollutantsInterface::CO>();
     185              :         case 16:
     186              :             return 0; // invalid getEmissions<PollutantsInterface::PM_X>();
     187              :         case 17:
     188              :             return 0; // invalid getEmissions<PollutantsInterface::NO_X>();
     189              :         case 18:
     190              :             return 0; // invalid getEmissions<PollutantsInterface::HC>();
     191              :         case 19:
     192              :             return 0; // invalid getEmissions<PollutantsInterface::FUEL>();
     193              :         case 20:
     194              :             return 0; // invalid getHarmonoise_NoiseEmissions();
     195            0 :         case 21: // reroute number
     196            0 :             if (getNumberReroutes() == 0) {
     197              :                 return -1;
     198              :             }
     199            0 :             return getNumberReroutes();
     200            0 :         case 22:
     201            0 :             return gSelected.isSelected(GLO_VEHICLE, getGlID());
     202              :         case 23:
     203              :             return 0; // invalid getBestLaneOffset();
     204              :         case 24:
     205              :             return 0; // invalid getAcceleration();
     206              :         case 25:
     207              :             return 0; // invalid getTimeGapOnLane();
     208            0 :         case 26:
     209            0 :             return STEPS2TIME(getDepartDelay());
     210              :         case 27:
     211              :             return 0; // electricityConsumption
     212              :         case 28:
     213              :             return 0; // timeLossSeconds
     214              :         case 29:
     215              :             return 0; // getSpeedLat
     216              :     }
     217              :     return 0;
     218              : }
     219              : 
     220              : 
     221              : 
     222              : void
     223            0 : GUIMEVehicle::drawRouteHelper(const GUIVisualizationSettings& s, ConstMSRoutePtr r, bool future, bool noLoop, const RGBColor& col) const {
     224            0 :     const double exaggeration = getExaggeration(s);
     225            0 :     MSRouteIterator start = future ? myCurrEdge : r->begin();
     226              :     MSRouteIterator i = start;
     227              :     std::map<const MSLane*, int> repeatLane; // count repeated occurrences of the same edge
     228            0 :     const double textSize = s.vehicleName.size / s.scale;
     229            0 :     const int indexDigits = (int)toString(r->size()).size();
     230            0 :     const bool s2 = s.secondaryShape;
     231            0 :     for (; i != r->end(); ++i) {
     232            0 :         const GUILane* lane = static_cast<GUILane*>((*i)->getLanes()[0]);
     233            0 :         GLHelper::drawBoxLines(lane->getShape(s2), lane->getShapeRotations(s2), lane->getShapeLengths(s2), exaggeration);
     234            0 :         if (s.showRouteIndex) {
     235            0 :             std::string label = toString((int)(i - myCurrEdge));
     236            0 :             const double laneAngle = lane->getShape(s2).angleAt2D(0);
     237            0 :             Position pos = lane->getShape(s2).front() - Position(0, textSize * repeatLane[lane]) + Position(
     238            0 :                                (laneAngle >= -0.25 * M_PI && laneAngle < 0.75 * M_PI ? 1 : -1) * 0.4 * indexDigits * textSize, 0);
     239              :             //GLHelper::drawText(label, pos, 1.0, textSize, s.vehicleName.color);
     240            0 :             GLHelper::drawTextSettings(s.vehicleName, label, pos, s.scale, s.angle, 1.0);
     241              :         }
     242            0 :         if (noLoop && i != start && (*i) == (*start)) {
     243              :             break;
     244              :         }
     245            0 :         repeatLane[lane]++;
     246              :     }
     247            0 :     drawStopLabels(s, noLoop, col);
     248            0 :     drawParkingInfo(s);
     249            0 : }
     250              : 
     251              : 
     252              : double
     253            0 : GUIMEVehicle::getLastLaneChangeOffset() const {
     254              :     // @todo possibly we could compute something reasonable here
     255            0 :     return 0;
     256              : }
     257              : 
     258              : 
     259              : std::string
     260            0 : GUIMEVehicle::getStopInfo() const {
     261            0 :     std::string result = "";
     262            0 :     if (isParking()) {
     263              :         result += "parking";
     264            0 :     } else if (isStopped()) {
     265              :         result += "stopped";
     266              :     } else {
     267            0 :         return "";
     268              :     }
     269            0 :     return result;
     270              : }
     271              : 
     272              : std::string
     273            0 : GUIMEVehicle::getEdgeID() const {
     274            0 :     return getEdge()->getID();
     275              : }
     276              : 
     277              : 
     278              : void
     279            0 : GUIMEVehicle::selectBlockingFoes() const {
     280              :     // @todo possibly we could compute something reasonable here
     281            0 : }
     282              : 
     283              : 
     284              : double
     285      1338411 : GUIMEVehicle::getExaggeration(const GUIVisualizationSettings& s) const {
     286      1338411 :     return s.vehicleSize.getExaggeration(s, this);
     287              : }
     288              : 
     289              : 
     290              : Boundary
     291            0 : GUIMEVehicle::getCenteringBoundary() const {
     292              :     // getPosition returns the start of the first lane, so we do not use it here
     293            0 :     getEdge()->lock();
     294            0 :     const double curTime = SIMTIME;
     295              :     double vehiclePosition = 0.;
     296              :     const MESegment* const segment = getSegment();
     297              :     const int queIdx = getQueIndex();
     298            0 :     if (segment != nullptr && queIdx != MESegment::PARKING_QUEUE) {
     299              :         vehiclePosition = segment->getLength();
     300              :         const std::vector<MEVehicle*>& queue = segment->getQueue(queIdx);
     301            0 :         for (auto it = queue.rbegin(); it != queue.rend(); ++it) {
     302            0 :             const MEVehicle* const v = *it;
     303              :             const double intendedLeave = MIN2(v->getEventTimeSeconds(), v->getBlockTimeSeconds());
     304              :             const double entry = v->getLastEntryTimeSeconds();
     305            0 :             const double offset = segment->getLength() * (curTime - entry) / (intendedLeave - entry);
     306            0 :             if (offset < vehiclePosition) {
     307              :                 vehiclePosition = offset;
     308              :             }
     309            0 :             if (v == this) {
     310              :                 break;
     311              :             }
     312            0 :             vehiclePosition -= v->getVehicleType().getLengthWithGap();
     313              :         }
     314              :     }
     315            0 :     Boundary b;
     316            0 :     const MSLane* const lane = getEdge()->getLanes()[queIdx == MESegment::PARKING_QUEUE ? 0 : queIdx];
     317            0 :     b.add(lane->geometryPositionAtOffset(getPositionOnLane() + vehiclePosition));
     318            0 :     b.grow(getVehicleType().getLength());
     319            0 :     getEdge()->unlock();
     320            0 :     return b;
     321              : }
     322              : 
     323              : Position
     324          531 : GUIMEVehicle::getVisualPosition(bool s2, const double offset) const {
     325          531 :     if (isParking()) {
     326              :         // meso vehicles do not enter/leave parkingAreas so we cannot call
     327              :         // myStops.begin()->parkingarea->getVehiclePosition(*this);
     328              : 
     329              :         // position beside the road
     330          527 :         const MSLane* first = getEdge()->getLanes()[0];
     331          527 :         PositionVector shp = first->getShape(s2);
     332         1053 :         shp.move2side(SUMO_const_laneWidth * (MSGlobals::gLefthand ? -1 : 1));
     333          527 :         return shp.positionAtOffset((getPositionOnLane() + offset) * first->getLengthGeometryFactor(s2));
     334          527 :     }
     335            4 :     return MEVehicle::getPosition(offset);
     336              : }
     337              : 
     338              : bool
     339            0 : GUIMEVehicle::isSelected() const {
     340            0 :     return gSelected.isSelected(GLO_VEHICLE, getGlID());
     341              : }
     342              : 
     343              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1