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

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

Generated by: LCOV version 1.14