SUMO - Simulation of Urban MObility
MSInstantInductLoop.cpp
Go to the documentation of this file.
00001 /****************************************************************************/
00007 // An instantaneous induction loop
00008 /****************************************************************************/
00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00010 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors
00011 /****************************************************************************/
00012 //
00013 //   This file is part of SUMO.
00014 //   SUMO is free software: you can redistribute it and/or modify
00015 //   it under the terms of the GNU General Public License as published by
00016 //   the Free Software Foundation, either version 3 of the License, or
00017 //   (at your option) any later version.
00018 //
00019 /****************************************************************************/
00020 
00021 
00022 // ===========================================================================
00023 // included modules
00024 // ===========================================================================
00025 #ifdef _MSC_VER
00026 #include <windows_config.h>
00027 #else
00028 #include <config.h>
00029 #endif
00030 
00031 #include "MSInstantInductLoop.h"
00032 #include <cassert>
00033 #include <numeric>
00034 #include <utility>
00035 #include <utils/common/WrappingCommand.h>
00036 #include <utils/common/ToString.h>
00037 #include <microsim/MSEventControl.h>
00038 #include <microsim/MSLane.h>
00039 #include <microsim/MSVehicle.h>
00040 #include <microsim/MSNet.h>
00041 #include <utils/common/MsgHandler.h>
00042 #include <utils/common/UtilExceptions.h>
00043 #include <utils/common/StringUtils.h>
00044 #include <utils/iodevices/OutputDevice.h>
00045 
00046 #ifdef CHECK_MEMORY_LEAKS
00047 #include <foreign/nvwa/debug_new.h>
00048 #endif // CHECK_MEMORY_LEAKS
00049 
00050 
00051 // ===========================================================================
00052 // method definitions
00053 // ===========================================================================
00054 MSInstantInductLoop::MSInstantInductLoop(const std::string& id,
00055         OutputDevice& od, MSLane* const lane, SUMOReal positionInMeters)
00056     : MSMoveReminder(lane), MSDetectorFileOutput(id), myOutputDevice(od),
00057       myPosition(positionInMeters), myLastExitTime(-1) {
00058     assert(myPosition >= 0 && myPosition <= myLane->getLength());
00059     writeXMLDetectorProlog(od);
00060 }
00061 
00062 
00063 MSInstantInductLoop::~MSInstantInductLoop() {
00064 }
00065 
00066 
00067 bool
00068 MSInstantInductLoop::notifyMove(SUMOVehicle& veh, SUMOReal oldPos,
00069                                 SUMOReal newPos, SUMOReal newSpeed) {
00070     if (newPos < myPosition) {
00071         // detector not reached yet
00072         return true;
00073     }
00074     if (newPos >= myPosition && oldPos < myPosition/* && static_cast<MSVehicle&>(veh).getLane() == myLane*/) {
00075         SUMOReal entryTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
00076         if (newSpeed != 0) {
00077             if (myPosition > oldPos) {
00078                 entryTime += (myPosition - oldPos) / newSpeed;
00079             }
00080         }
00081         if (myLastExitTime >= 0) {
00082             write("enter", entryTime, veh, newSpeed, "gap", entryTime - myLastExitTime);
00083         } else {
00084             write("enter", entryTime, veh, newSpeed);
00085         }
00086         myEntryTimes[&veh] = entryTime;
00087         return true;
00088     }
00089     if (newPos - veh.getVehicleType().getLength() > myPosition) {
00090         // vehicle passed the detector
00091         SUMOReal leaveTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
00092         leaveTime += (myPosition - oldPos + veh.getVehicleType().getLength()) / newSpeed;
00093         std::map<SUMOVehicle*, SUMOReal>::iterator i = myEntryTimes.find(&veh);
00094         if (i != myEntryTimes.end()) {
00095             write("leave", leaveTime, veh, newSpeed, "occupancy", leaveTime - (*i).second);
00096             myEntryTimes.erase(i);
00097         } else {
00098             write("leave", leaveTime, veh, newSpeed);
00099         }
00100         myLastExitTime = leaveTime;
00101         return false;
00102     }
00103     // vehicle stays on the detector
00104     write("stay", STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()), veh, newSpeed);
00105     return true;
00106 }
00107 
00108 
00109 void
00110 MSInstantInductLoop::write(const char* state, SUMOReal t, SUMOVehicle& veh, SUMOReal speed, const char* add, SUMOReal addValue) {
00111     myOutputDevice.openTag("instantOut").writeAttr(
00112         "id", getID()).writeAttr("time", toString(t)).writeAttr("state", state).writeAttr(
00113             "vehID", veh.getID()).writeAttr("speed", toString(speed)).writeAttr(
00114                 "length", toString(veh.getVehicleType().getLength())).writeAttr(
00115                     "type", veh.getVehicleType().getID());
00116     if (add != 0) {
00117         myOutputDevice.writeAttr(add, toString(addValue));
00118     }
00119     myOutputDevice << ">";
00120     myOutputDevice.closeTag();
00121 }
00122 
00123 bool
00124 MSInstantInductLoop::notifyLeave(SUMOVehicle& veh, SUMOReal /*lastPos*/, MSMoveReminder::Notification reason) {
00125     std::map<SUMOVehicle*, SUMOReal>::iterator i = myEntryTimes.find(&veh);
00126     if (i != myEntryTimes.end()) {
00127         myEntryTimes.erase(i);
00128     }
00129     if (reason != MSMoveReminder::NOTIFICATION_JUNCTION) {
00130         write("leave", STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()), veh, veh.getSpeed());
00131         return false;
00132     }
00133     return true;
00134 }
00135 
00136 
00137 bool
00138 MSInstantInductLoop::notifyEnter(SUMOVehicle& veh, MSMoveReminder::Notification) {
00139     if (veh.getPositionOnLane() - veh.getVehicleType().getLength() > myPosition) {
00140         // vehicle-front is beyond detector. Ignore
00141         return false;
00142     }
00143     // vehicle is in front of detector
00144     return true;
00145 }
00146 
00147 
00148 void
00149 MSInstantInductLoop::writeXMLDetectorProlog(OutputDevice& dev) const {
00150     dev.writeXMLHeader("instantE1");
00151 }
00152 
00153 
00154 
00155 /****************************************************************************/
00156 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines