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

Generated by: LCOV version 2.0-1