LCOV - code coverage report
Current view: top level - src/microsim/output - MSInstantInductLoop.cpp (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 49 49
Test Date: 2024-11-20 15:55:46 Functions: 100.0 % 7 7

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2011-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    MSInstantInductLoop.cpp
      15              : /// @author  Daniel Krajzewicz
      16              : /// @author  Jakob Erdmann
      17              : /// @author  Michael Behrisch
      18              : /// @date    2011-09.08
      19              : ///
      20              : // An instantaneous induction loop
      21              : /****************************************************************************/
      22              : #include <config.h>
      23              : 
      24              : #include "MSInstantInductLoop.h"
      25              : #include <cassert>
      26              : #include <numeric>
      27              : #include <utility>
      28              : #ifdef HAVE_FOX
      29              : #include <utils/common/ScopedLocker.h>
      30              : #endif
      31              : #include <utils/common/WrappingCommand.h>
      32              : #include <utils/common/ToString.h>
      33              : #include <microsim/MSEventControl.h>
      34              : #include <microsim/MSLane.h>
      35              : #include <microsim/MSVehicle.h>
      36              : #include <microsim/MSNet.h>
      37              : #include <utils/common/MsgHandler.h>
      38              : #include <utils/common/UtilExceptions.h>
      39              : #include <utils/common/StringUtils.h>
      40              : #include <utils/iodevices/OutputDevice.h>
      41              : 
      42              : 
      43              : // ===========================================================================
      44              : // method definitions
      45              : // ===========================================================================
      46          813 : MSInstantInductLoop::MSInstantInductLoop(const std::string& id,
      47              :         OutputDevice& od, MSLane* const lane, double positionInMeters,
      48              :         const std::string name, const std::string& vTypes,
      49          813 :         const std::string& nextEdges) :
      50              :     MSMoveReminder(id, lane),
      51              :     MSDetectorFileOutput(id, vTypes, nextEdges),
      52          813 :     myName(name),
      53          813 :     myOutputDevice(od),
      54         1626 :     myPosition(positionInMeters), myLastExitTime(-1) {
      55              :     assert(myPosition >= 0 && myPosition <= myLane->getLength());
      56          813 :     writeXMLDetectorProlog(od);
      57          813 : }
      58              : 
      59              : 
      60         1497 : MSInstantInductLoop::~MSInstantInductLoop() {
      61         1497 : }
      62              : 
      63              : 
      64              : bool
      65        47932 : MSInstantInductLoop::notifyMove(SUMOTrafficObject& veh, double oldPos,
      66              :                                 double newPos, double newSpeed) {
      67        47932 :     if (!vehicleApplies(veh)) {
      68              :         return false;
      69              :     }
      70        47752 :     if (newPos < myPosition) {
      71              :         // detector not reached yet
      72              :         return true;
      73              :     }
      74              : #ifdef HAVE_FOX
      75         7679 :     ScopedLocker<> lock(myNotificationMutex, MSGlobals::gNumSimThreads > 1);
      76              : #endif
      77              : 
      78         7679 :     const double oldSpeed = veh.getPreviousSpeed();
      79              :     double enterSpeed = MSGlobals::gSemiImplicitEulerUpdate ? newSpeed : oldSpeed; // NOTE: For the euler update, the vehicle is assumed to travel at constant speed for the whole time step
      80              : 
      81         7679 :     if (newPos >= myPosition && oldPos < myPosition/* && static_cast<MSVehicle&>(veh).getLane() == myLane*/) {
      82         4901 :         const double timeBeforeEnter = MSCFModel::passingTime(oldPos, myPosition, newPos, oldSpeed, newSpeed);
      83         4901 :         const double entryTime = SIMTIME - TS + timeBeforeEnter;
      84         4901 :         enterSpeed = MSCFModel::speedAfterTime(timeBeforeEnter, oldSpeed, newPos - oldPos);
      85         4901 :         if (myLastExitTime >= 0) {
      86         4604 :             write("enter", entryTime, veh, enterSpeed, "gap", entryTime - myLastExitTime);
      87              :         } else {
      88          297 :             write("enter", entryTime, veh, enterSpeed);
      89              :         }
      90         4901 :         myEntryTimes[&veh] = entryTime;
      91              :     }
      92         7679 :     const double newBackPos = newPos - veh.getVehicleType().getLength();
      93         7679 :     const double oldBackPos = oldPos - veh.getVehicleType().getLength();
      94         7679 :     if (newBackPos > myPosition) {
      95              :         std::map<SUMOTrafficObject*, double>::iterator i = myEntryTimes.find(&veh);
      96         4998 :         if (i != myEntryTimes.end()) {
      97              :             // vehicle passed the detector
      98         4898 :             const double timeBeforeLeave = MSCFModel::passingTime(oldBackPos, myPosition, newBackPos, oldSpeed, newSpeed);
      99         4898 :             const double leaveTime = SIMTIME - TS + timeBeforeLeave;
     100         4898 :             write("leave", leaveTime, veh, newSpeed, "occupancy", leaveTime - (*i).second);
     101              :             myEntryTimes.erase(i);
     102         4898 :             myLastExitTime = leaveTime;
     103              :         }
     104              :         return false;
     105              :     }
     106              :     // vehicle stays on the detector
     107         2681 :     write("stay", SIMTIME, veh, newSpeed);
     108              :     return true;
     109              : }
     110              : 
     111              : 
     112              : void
     113        12483 : MSInstantInductLoop::write(const char* state, double t, SUMOTrafficObject& veh, double speed, const char* add, double addValue) {
     114        12483 :     if (!myOutputDevice.isNull()) {
     115        24862 :         myOutputDevice.openTag("instantOut").writeAttr(
     116        49724 :             "id", getID()).writeAttr("time", toString(t)).writeAttr("state", state).writeAttr(
     117        49724 :                 "vehID", veh.getID()).writeAttr("speed", toString(speed)).writeAttr(
     118        49724 :                     "length", toString(veh.getVehicleType().getLength())).writeAttr(
     119        12431 :                         "type", veh.getVehicleType().getID());
     120        12431 :         if (add != nullptr) {
     121        18948 :             myOutputDevice.writeAttr(add, toString(addValue));
     122              :         }
     123        24862 :         myOutputDevice.closeTag();
     124              :     }
     125        12483 : }
     126              : 
     127              : 
     128              : bool
     129         4095 : MSInstantInductLoop::notifyLeave(SUMOTrafficObject& veh, double /* lastPos */, MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
     130         4095 :     if (reason == MSMoveReminder::NOTIFICATION_JUNCTION) {
     131              :         // vehicle might have jumped over detector at the end of the lane. we need
     132              :         // one more notifyMove to register it
     133              :         return true;
     134              :     }
     135              :     std::map<SUMOTrafficObject*, double>::iterator i = myEntryTimes.find(&veh);
     136         1513 :     if (i != myEntryTimes.end()) {
     137            3 :         write("leave", SIMTIME, veh, veh.getSpeed());
     138              :         myEntryTimes.erase(i);
     139              :     }
     140              :     return false;
     141              : }
     142              : 
     143              : 
     144              : void
     145          813 : MSInstantInductLoop::writeXMLDetectorProlog(OutputDevice& dev) const {
     146         1626 :     dev.writeXMLHeader("instantE1", "instant_e1_file.xsd");
     147          813 : }
     148              : 
     149              : 
     150              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1