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-12-21 15:45:41 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          954 : MSInstantInductLoop::MSInstantInductLoop(const std::string& id,
      47              :         OutputDevice& od, MSLane* const lane, double positionInMeters,
      48              :         const std::string name, const std::string& vTypes,
      49          954 :         const std::string& nextEdges) :
      50              :     MSMoveReminder(id, lane),
      51              :     MSDetectorFileOutput(id, vTypes, nextEdges),
      52          954 :     myName(name),
      53          954 :     myOutputDevice(od),
      54         1908 :     myPosition(positionInMeters), myLastExitTime(-1) {
      55              :     assert(myPosition >= 0 && myPosition <= myLane->getLength());
      56          954 :     writeXMLDetectorProlog(od);
      57          954 : }
      58              : 
      59              : 
      60         1780 : MSInstantInductLoop::~MSInstantInductLoop() {
      61         1780 : }
      62              : 
      63              : 
      64              : bool
      65        69220 : MSInstantInductLoop::notifyMove(SUMOTrafficObject& veh, double oldPos,
      66              :                                 double newPos, double newSpeed) {
      67        69220 :     if (!vehicleApplies(veh)) {
      68              :         return false;
      69              :     }
      70        69040 :     if (newPos < myPosition) {
      71              :         // detector not reached yet
      72              :         return true;
      73              :     }
      74              : #ifdef HAVE_FOX
      75        15789 :     ScopedLocker<> lock(myNotificationMutex, MSGlobals::gNumSimThreads > 1);
      76              : #endif
      77              : 
      78        15789 :     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        15789 :     if (newPos >= myPosition && oldPos < myPosition/* && static_cast<MSVehicle&>(veh).getLane() == myLane*/) {
      82        10287 :         const double timeBeforeEnter = MSCFModel::passingTime(oldPos, myPosition, newPos, oldSpeed, newSpeed);
      83        10287 :         const double entryTime = SIMTIME - TS + timeBeforeEnter;
      84        10287 :         enterSpeed = MSCFModel::speedAfterTime(timeBeforeEnter, oldSpeed, newPos - oldPos);
      85        10287 :         if (myLastExitTime >= 0) {
      86         9962 :             write("enter", entryTime, veh, enterSpeed, "gap", entryTime - myLastExitTime);
      87              :         } else {
      88          325 :             write("enter", entryTime, veh, enterSpeed);
      89              :         }
      90        10287 :         myEntryTimes[&veh] = entryTime;
      91              :     }
      92        15789 :     const double newBackPos = newPos - veh.getVehicleType().getLength();
      93        15789 :     const double oldBackPos = oldPos - veh.getVehicleType().getLength();
      94        15789 :     if (newBackPos > myPosition) {
      95              :         std::map<SUMOTrafficObject*, double>::iterator i = myEntryTimes.find(&veh);
      96        10383 :         if (i != myEntryTimes.end()) {
      97              :             // vehicle passed the detector
      98        10284 :             const double timeBeforeLeave = MSCFModel::passingTime(oldBackPos, myPosition, newBackPos, oldSpeed, newSpeed);
      99        10284 :             const double leaveTime = SIMTIME - TS + timeBeforeLeave;
     100        10284 :             write("leave", leaveTime, veh, newSpeed, "occupancy", leaveTime - (*i).second);
     101              :             myEntryTimes.erase(i);
     102        10284 :             myLastExitTime = leaveTime;
     103              :         }
     104              :         return false;
     105              :     }
     106              :     // vehicle stays on the detector
     107         5406 :     write("stay", SIMTIME, veh, newSpeed);
     108              :     return true;
     109              : }
     110              : 
     111              : 
     112              : void
     113        25980 : MSInstantInductLoop::write(const char* state, double t, SUMOTrafficObject& veh, double speed, const char* add, double addValue) {
     114        25980 :     if (!myOutputDevice.isNull()) {
     115        51882 :         myOutputDevice.openTag("instantOut").writeAttr(
     116       103764 :             "id", getID()).writeAttr("time", toString(t)).writeAttr("state", state).writeAttr(
     117       103764 :                 "vehID", veh.getID()).writeAttr("speed", toString(speed)).writeAttr(
     118       103764 :                     "length", toString(veh.getVehicleType().getLength())).writeAttr(
     119        25941 :                         "type", veh.getVehicleType().getID());
     120        25941 :         if (add != nullptr) {
     121        40450 :             myOutputDevice.writeAttr(add, toString(addValue));
     122              :         }
     123        51882 :         myOutputDevice.closeTag();
     124              :     }
     125        25980 : }
     126              : 
     127              : 
     128              : bool
     129         4935 : MSInstantInductLoop::notifyLeave(SUMOTrafficObject& veh, double /* lastPos */, MSMoveReminder::Notification reason, const MSLane* /* enteredLane */) {
     130         4935 :     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         1473 :     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          954 : MSInstantInductLoop::writeXMLDetectorProlog(OutputDevice& dev) const {
     146         1908 :     dev.writeXMLHeader("instantE1", "instant_e1_file.xsd");
     147          954 : }
     148              : 
     149              : 
     150              : /****************************************************************************/
        

Generated by: LCOV version 2.0-1