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 <utils/common/MsgHandler.h>
00040 #include <utils/common/UtilExceptions.h>
00041 #include <utils/common/StringUtils.h>
00042 #include <utils/iodevices/OutputDevice.h>
00043 
00044 #ifdef CHECK_MEMORY_LEAKS
00045 #include <foreign/nvwa/debug_new.h>
00046 #endif // CHECK_MEMORY_LEAKS
00047 
00048 
00049 // ===========================================================================
00050 // method definitions
00051 // ===========================================================================
00052 MSInstantInductLoop::MSInstantInductLoop(const std::string& id,
00053         OutputDevice& od, MSLane* const lane, SUMOReal positionInMeters)
00054     : MSMoveReminder(lane), MSDetectorFileOutput(id), myOutputDevice(od),
00055       myPosition(positionInMeters), myLastExitTime(-1) {
00056     assert(myPosition >= 0 && myPosition <= myLane->getLength());
00057     writeXMLDetectorProlog(od);
00058 }
00059 
00060 
00061 MSInstantInductLoop::~MSInstantInductLoop() {
00062 }
00063 
00064 
00065 bool
00066 MSInstantInductLoop::notifyMove(SUMOVehicle& veh, SUMOReal oldPos,
00067                                 SUMOReal newPos, SUMOReal newSpeed) {
00068     if (newPos < myPosition) {
00069         // detector not reached yet
00070         return true;
00071     }
00072     if (newPos >= myPosition && oldPos < myPosition/* && static_cast<MSVehicle&>(veh).getLane() == myLane*/) {
00073         SUMOReal entryTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
00074         if (newSpeed != 0) {
00075             if (myPosition > oldPos) {
00076                 entryTime += (myPosition - oldPos) / newSpeed;
00077             }
00078         }
00079         if (myLastExitTime >= 0) {
00080             write("enter", entryTime, veh, newSpeed, "gap", entryTime - myLastExitTime);
00081         } else {
00082             write("enter", entryTime, veh, newSpeed);
00083         }
00084         myEntryTimes[&veh] = entryTime;
00085         return true;
00086     }
00087     if (newPos - veh.getVehicleType().getLengthWithGap() > myPosition) {
00088         // vehicle passed the detector
00089         SUMOReal leaveTime = STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep());
00090         leaveTime += (myPosition - oldPos + veh.getVehicleType().getLengthWithGap()) / newSpeed;
00091         std::map<SUMOVehicle*, SUMOReal>::iterator i = myEntryTimes.find(&veh);
00092         if (i != myEntryTimes.end()) {
00093             write("leave", leaveTime, veh, newSpeed, "occupancy", leaveTime - (*i).second);
00094             myEntryTimes.erase(i);
00095         } else {
00096             write("leave", leaveTime, veh, newSpeed);
00097         }
00098         myLastExitTime = leaveTime;
00099         return false;
00100     }
00101     // vehicle stays on the detector
00102     write("stay", STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()), veh, newSpeed);
00103     return true;
00104 }
00105 
00106 
00107 void
00108 MSInstantInductLoop::write(const char* state, SUMOReal t, SUMOVehicle& veh, SUMOReal speed, const char* add, SUMOReal addValue) {
00109     myOutputDevice.openTag("instantOut").writeAttr(
00110         "id", getID()).writeAttr("time", toString(t)).writeAttr("state", state).writeAttr(
00111             "vehID", veh.getID()).writeAttr("speed", toString(speed)).writeAttr(
00112                 "length", toString(veh.getVehicleType().getLength())).writeAttr(
00113                     "type", veh.getVehicleType().getID());
00114     if (add != 0) {
00115         myOutputDevice.writeAttr(add, toString(addValue));
00116     }
00117     myOutputDevice << ">";
00118     myOutputDevice.closeTag();
00119 }
00120 
00121 bool
00122 MSInstantInductLoop::notifyLeave(SUMOVehicle& veh, SUMOReal /*lastPos*/, MSMoveReminder::Notification reason) {
00123     std::map<SUMOVehicle*, SUMOReal>::iterator i = myEntryTimes.find(&veh);
00124     if (i != myEntryTimes.end()) {
00125         myEntryTimes.erase(i);
00126     }
00127     if (reason != MSMoveReminder::NOTIFICATION_JUNCTION) {
00128         write("leave", STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep()), veh, veh.getSpeed());
00129         return false;
00130     }
00131     return true;
00132 }
00133 
00134 
00135 bool
00136 MSInstantInductLoop::notifyEnter(SUMOVehicle& veh, MSMoveReminder::Notification) {
00137     if (veh.getPositionOnLane() - veh.getVehicleType().getLengthWithGap() > myPosition) {
00138         // vehicle-front is beyond detector. Ignore
00139         return false;
00140     }
00141     // vehicle is in front of detector
00142     return true;
00143 }
00144 
00145 
00146 void
00147 MSInstantInductLoop::writeXMLDetectorProlog(OutputDevice& dev) const {
00148     dev.writeXMLHeader("instantE1");
00149 }
00150 
00151 
00152 
00153 /****************************************************************************/
00154 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines