|
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-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