LCOV - code coverage report
Current view: top level - src/libsumo - InductionLoop.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 96.9 % 161 156
Test Date: 2024-12-21 15:45:41 Functions: 87.2 % 39 34

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2012-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    InductionLoop.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Mario Krumnow
      17              : /// @author  Jakob Erdmann
      18              : /// @author  Michael Behrisch
      19              : /// @date    30.05.2012
      20              : ///
      21              : // C++ TraCI client API implementation
      22              : /****************************************************************************/
      23              : #include <config.h>
      24              : 
      25              : #include <microsim/output/MSDetectorControl.h>
      26              : #include <microsim/output/MSInductLoop.h>
      27              : #include <mesosim/MEInductLoop.h>
      28              : #include <microsim/MSNet.h>
      29              : #include <microsim/MSEdge.h>
      30              : #include <libsumo/Helper.h>
      31              : #include <libsumo/TraCIDefs.h>
      32              : #include <libsumo/TraCIConstants.h>
      33              : #include "InductionLoop.h"
      34              : 
      35              : 
      36              : namespace libsumo {
      37              : // ===========================================================================
      38              : // static member initializations
      39              : // ===========================================================================
      40              : SubscriptionResults InductionLoop::mySubscriptionResults;
      41              : ContextSubscriptionResults InductionLoop::myContextSubscriptionResults;
      42              : NamedRTree* InductionLoop::myTree(nullptr);
      43              : 
      44              : 
      45              : // ===========================================================================
      46              : // member definitions
      47              : // ===========================================================================
      48              : std::vector<std::string>
      49          426 : InductionLoop::getIDList() {
      50              :     std::vector<std::string> ids;
      51          426 :     MSNet::getInstance()->getDetectorControl().getTypedDetectors(SUMO_TAG_INDUCTION_LOOP).insertIDs(ids);
      52          424 :     return ids;
      53            2 : }
      54              : 
      55              : 
      56              : int
      57           21 : InductionLoop::getIDCount() {
      58              :     std::vector<std::string> ids;
      59           42 :     return (int)MSNet::getInstance()->getDetectorControl().getTypedDetectors(SUMO_TAG_INDUCTION_LOOP).size();
      60           21 : }
      61              : 
      62              : 
      63              : double
      64           16 : InductionLoop::getPosition(const std::string& loopID) {
      65           16 :     return getDetector(loopID)->getPosition();
      66              : }
      67              : 
      68              : 
      69              : std::string
      70           16 : InductionLoop::getLaneID(const std::string& loopID) {
      71           16 :     return getDetector(loopID)->getLane()->getID();
      72              : }
      73              : 
      74              : 
      75              : int
      76         3318 : InductionLoop::getLastStepVehicleNumber(const std::string& loopID) {
      77         3318 :     return (int)getDetector(loopID)->getEnteredNumber((int)DELTA_T);
      78              : }
      79              : 
      80              : 
      81              : double
      82          139 : InductionLoop::getLastStepMeanSpeed(const std::string& loopID) {
      83          139 :     return getDetector(loopID)->getSpeed((int)DELTA_T);
      84              : }
      85              : 
      86              : 
      87              : std::vector<std::string>
      88          979 : InductionLoop::getLastStepVehicleIDs(const std::string& loopID) {
      89          979 :     return getDetector(loopID)->getVehicleIDs((int)DELTA_T);
      90              : }
      91              : 
      92              : 
      93              : double
      94          707 : InductionLoop::getLastStepOccupancy(const std::string& loopID) {
      95          707 :     return getDetector(loopID)->getOccupancy();
      96              : }
      97              : 
      98              : 
      99              : double
     100          139 : InductionLoop::getLastStepMeanLength(const std::string& loopID) {
     101          139 :     return getDetector(loopID)->getVehicleLength((int)DELTA_T);
     102              : }
     103              : 
     104              : 
     105              : double
     106          140 : InductionLoop::getTimeSinceDetection(const std::string& loopID) {
     107          140 :     return getDetector(loopID)->getTimeSinceLastDetection();
     108              : }
     109              : 
     110              : std::vector<libsumo::TraCIVehicleData>
     111        42475 : InductionLoop::getVehicleData(const std::string& loopID) {
     112        42475 :     const std::vector<MSInductLoop::VehicleData> vd = getDetector(loopID)->collectVehiclesOnDet(SIMSTEP - DELTA_T, true, true);
     113              :     std::vector<libsumo::TraCIVehicleData> tvd;
     114        48941 :     for (const MSInductLoop::VehicleData& vdi : vd) {
     115         6466 :         tvd.push_back(libsumo::TraCIVehicleData());
     116         6466 :         tvd.back().id = vdi.idM;
     117         6466 :         tvd.back().length = vdi.lengthM;
     118         6466 :         tvd.back().entryTime = vdi.entryTimeM;
     119         6466 :         tvd.back().leaveTime = vdi.leaveTimeM;
     120         6466 :         tvd.back().typeID = vdi.typeIDM;
     121              :     }
     122        42475 :     return tvd;
     123        42475 : }
     124              : 
     125              : 
     126              : double
     127          600 : InductionLoop::getIntervalOccupancy(const std::string& loopID) {
     128          600 :     if (MSGlobals::gUseMesoSim) {
     129          120 :         const MEInductLoop* det = getMEDetector(loopID);
     130              :         const auto& meanData = det->getMeanData();
     131          120 :         return meanData.getOccupancy(SIMSTEP - meanData.getResetTime(), det->getEdge().getNumLanes());
     132              :     } else {
     133          480 :         return getDetector(loopID)->getIntervalOccupancy();
     134              :     }
     135              : }
     136              : 
     137              : 
     138              : double
     139          600 : InductionLoop::getIntervalMeanSpeed(const std::string& loopID) {
     140          600 :     if (MSGlobals::gUseMesoSim) {
     141          120 :         const MEInductLoop* det = getMEDetector(loopID);
     142              :         const auto& meanData = det->getMeanData();
     143          120 :         if (meanData.getSamples() != 0) {
     144           69 :             return meanData.getTravelledDistance() / meanData.getSamples();
     145              :         } else {
     146           51 :             const double defaultTravelTime = det->getEdge().getLength() / det->getEdge().getSpeedLimit();
     147           51 :             return meanData.getLaneLength() / defaultTravelTime;
     148              :         }
     149              :     } else {
     150          480 :         return getDetector(loopID)->getIntervalMeanSpeed();
     151              :     }
     152              : }
     153              : 
     154              : 
     155              : int
     156          600 : InductionLoop::getIntervalVehicleNumber(const std::string& loopID) {
     157          600 :     if (MSGlobals::gUseMesoSim) {
     158          120 :         const auto& meanData = getMEDetector(loopID)->getMeanData();
     159          120 :         return meanData.nVehDeparted + meanData.nVehEntered;
     160              :     } else {
     161          480 :         return getDetector(loopID)->getIntervalVehicleNumber();
     162              :     }
     163              : }
     164              : 
     165              : 
     166              : std::vector<std::string>
     167          600 : InductionLoop::getIntervalVehicleIDs(const std::string& loopID) {
     168          600 :     if (MSGlobals::gUseMesoSim) {
     169          120 :         WRITE_ERROR("getIntervalVehicleIDs not applicable for meso");
     170          120 :         return std::vector<std::string>();
     171              :     }
     172          480 :     return getDetector(loopID)->getIntervalVehicleIDs();
     173              : }
     174              : 
     175              : 
     176              : double
     177          600 : InductionLoop::getLastIntervalOccupancy(const std::string& loopID) {
     178          600 :     if (MSGlobals::gUseMesoSim) {
     179          120 :         WRITE_ERROR("getLastIntervalOccupancy not applicable for meso");
     180          120 :         return INVALID_DOUBLE_VALUE;
     181              :     }
     182          480 :     return getDetector(loopID)->getIntervalOccupancy(true);
     183              : }
     184              : 
     185              : 
     186              : double
     187          600 : InductionLoop::getLastIntervalMeanSpeed(const std::string& loopID) {
     188          600 :     if (MSGlobals::gUseMesoSim) {
     189          120 :         WRITE_ERROR("getLastIntervalMeanSpeed not applicable for meso");
     190          120 :         return INVALID_DOUBLE_VALUE;
     191              :     }
     192          480 :     return getDetector(loopID)->getIntervalMeanSpeed(true);
     193              : }
     194              : 
     195              : 
     196              : int
     197          600 : InductionLoop::getLastIntervalVehicleNumber(const std::string& loopID) {
     198          600 :     if (MSGlobals::gUseMesoSim) {
     199          120 :         WRITE_ERROR("getLastIntervalVehicleNumber not applicable for meso");
     200          120 :         return INVALID_INT_VALUE;
     201              :     }
     202          480 :     return getDetector(loopID)->getIntervalVehicleNumber(true);
     203              : }
     204              : 
     205              : 
     206              : std::vector<std::string>
     207          600 : InductionLoop::getLastIntervalVehicleIDs(const std::string& loopID) {
     208          600 :     if (MSGlobals::gUseMesoSim) {
     209          120 :         WRITE_ERROR("getLastIntervalVehicleIDs not applicable for meso");
     210          120 :         return std::vector<std::string>();
     211              :     }
     212          480 :     return getDetector(loopID)->getIntervalVehicleIDs(true);
     213              : }
     214              : 
     215              : 
     216              : void
     217           20 : InductionLoop::overrideTimeSinceDetection(const std::string& loopID, double time) {
     218           20 :     getDetector(loopID)->overrideTimeSinceDetection(time);
     219           20 : }
     220              : 
     221              : 
     222              : MSInductLoop*
     223        52130 : InductionLoop::getDetector(const std::string& id) {
     224       104259 :     MSInductLoop* il = dynamic_cast<MSInductLoop*>(MSNet::getInstance()->getDetectorControl().getTypedDetectors(SUMO_TAG_INDUCTION_LOOP).get(id));
     225        52130 :     if (il == nullptr) {
     226           10 :         throw TraCIException("Induction loop '" + id + "' is not known");
     227              :     }
     228        52125 :     return il;
     229              : }
     230              : 
     231              : 
     232              : MEInductLoop*
     233          360 : InductionLoop::getMEDetector(const std::string& id) {
     234          720 :     MEInductLoop* il = dynamic_cast<MEInductLoop*>(MSNet::getInstance()->getDetectorControl().getTypedDetectors(SUMO_TAG_INDUCTION_LOOP).get(id));
     235          360 :     if (il == nullptr) {
     236            0 :         throw TraCIException("Induction loop '" + id + "' is not known");
     237              :     }
     238          360 :     return il;
     239              : }
     240              : 
     241              : 
     242              : 
     243              : std::string
     244           30 : InductionLoop::getParameter(const std::string& loopID, const std::string& param) {
     245           60 :     return getDetector(loopID)->getParameter(param, "");
     246              : }
     247              : 
     248              : 
     249            0 : LIBSUMO_GET_PARAMETER_WITH_KEY_IMPLEMENTATION(InductionLoop)
     250              : 
     251              : 
     252              : void
     253           15 : InductionLoop::setParameter(const std::string& loopID, const std::string& name, const std::string& value) {
     254           15 :     getDetector(loopID)->setParameter(name, value);
     255           15 : }
     256              : 
     257              : 
     258          287 : LIBSUMO_SUBSCRIPTION_IMPLEMENTATION(InductionLoop, INDUCTIONLOOP)
     259              : 
     260              : 
     261              : NamedRTree*
     262          332 : InductionLoop::getTree() {
     263          332 :     if (myTree == nullptr) {
     264           12 :         myTree = new NamedRTree();
     265           48 :         for (const auto& i : MSNet::getInstance()->getDetectorControl().getTypedDetectors(SUMO_TAG_INDUCTION_LOOP)) {
     266           36 :             MSInductLoop* il = static_cast<MSInductLoop*>(i.second);
     267           36 :             Position p = il->getLane()->getShape().positionAtOffset(il->getPosition());
     268           36 :             const float cmin[2] = {(float) p.x(), (float) p.y()};
     269           36 :             const float cmax[2] = {(float) p.x(), (float) p.y()};
     270           36 :             myTree->Insert(cmin, cmax, il);
     271              :         }
     272              :     }
     273          332 :     return myTree;
     274              : }
     275              : 
     276              : void
     277        40516 : InductionLoop::cleanup() {
     278        40516 :     delete myTree;
     279        40516 :     myTree = nullptr;
     280        40516 : }
     281              : 
     282              : void
     283          296 : InductionLoop::storeShape(const std::string& id, PositionVector& shape) {
     284          296 :     MSInductLoop* const il = getDetector(id);
     285          296 :     shape.push_back(il->getLane()->getShape().positionAtOffset(il->getPosition()));
     286          296 : }
     287              : 
     288              : 
     289              : std::shared_ptr<VariableWrapper>
     290          264 : InductionLoop::makeWrapper() {
     291          264 :     return std::make_shared<Helper::SubscriptionWrapper>(handleVariable, mySubscriptionResults, myContextSubscriptionResults);
     292              : }
     293              : 
     294              : 
     295              : bool
     296        32146 : InductionLoop::handleVariable(const std::string& objID, const int variable, VariableWrapper* wrapper, tcpip::Storage* paramData) {
     297        32146 :     switch (variable) {
     298          237 :         case TRACI_ID_LIST:
     299          237 :             return wrapper->wrapStringList(objID, variable, getIDList());
     300           14 :         case ID_COUNT:
     301           14 :             return wrapper->wrapInt(objID, variable, getIDCount());
     302            9 :         case VAR_POSITION:
     303            9 :             return wrapper->wrapDouble(objID, variable, getPosition(objID));
     304            9 :         case VAR_LANE_ID:
     305           18 :             return wrapper->wrapString(objID, variable, getLaneID(objID));
     306         2911 :         case LAST_STEP_VEHICLE_NUMBER:
     307         2911 :             return wrapper->wrapInt(objID, variable, getLastStepVehicleNumber(objID));
     308           96 :         case LAST_STEP_MEAN_SPEED:
     309           96 :             return wrapper->wrapDouble(objID, variable, getLastStepMeanSpeed(objID));
     310          548 :         case LAST_STEP_VEHICLE_ID_LIST:
     311          548 :             return wrapper->wrapStringList(objID, variable, getLastStepVehicleIDs(objID));
     312          380 :         case LAST_STEP_OCCUPANCY:
     313          380 :             return wrapper->wrapDouble(objID, variable, getLastStepOccupancy(objID));
     314           96 :         case LAST_STEP_LENGTH:
     315           96 :             return wrapper->wrapDouble(objID, variable, getLastStepMeanLength(objID));
     316           97 :         case LAST_STEP_TIME_SINCE_DETECTION:
     317           97 :             return wrapper->wrapDouble(objID, variable, getTimeSinceDetection(objID));
     318          360 :         case VAR_INTERVAL_OCCUPANCY:
     319          360 :             return wrapper->wrapDouble(objID, variable, getIntervalOccupancy(objID));
     320          360 :         case VAR_INTERVAL_SPEED:
     321          360 :             return wrapper->wrapDouble(objID, variable, getIntervalMeanSpeed(objID));
     322          360 :         case VAR_INTERVAL_NUMBER:
     323          360 :             return wrapper->wrapInt(objID, variable, getIntervalVehicleNumber(objID));
     324          360 :         case VAR_INTERVAL_IDS:
     325          360 :             return wrapper->wrapStringList(objID, variable, getIntervalVehicleIDs(objID));
     326          360 :         case VAR_LAST_INTERVAL_OCCUPANCY:
     327          360 :             return wrapper->wrapDouble(objID, variable, getLastIntervalOccupancy(objID));
     328          360 :         case VAR_LAST_INTERVAL_SPEED:
     329          360 :             return wrapper->wrapDouble(objID, variable, getLastIntervalMeanSpeed(objID));
     330          360 :         case VAR_LAST_INTERVAL_NUMBER:
     331          360 :             return wrapper->wrapInt(objID, variable, getLastIntervalVehicleNumber(objID));
     332          360 :         case VAR_LAST_INTERVAL_IDS:
     333          360 :             return wrapper->wrapStringList(objID, variable, getLastIntervalVehicleIDs(objID));
     334           16 :         case libsumo::VAR_PARAMETER:
     335           16 :             paramData->readUnsignedByte();
     336           32 :             return wrapper->wrapString(objID, variable, getParameter(objID, paramData->readString()));
     337            0 :         case libsumo::VAR_PARAMETER_WITH_KEY:
     338            0 :             paramData->readUnsignedByte();
     339            0 :             return wrapper->wrapStringPair(objID, variable, getParameterWithKey(objID, paramData->readString()));
     340              :         default:
     341              :             return false;
     342              :     }
     343              : }
     344              : 
     345              : 
     346              : }
     347              : 
     348              : 
     349              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1