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