|
SUMO - Simulation of Urban MObility
|
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