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