MSMsgInductLoop.cpp
Go to the documentation of this file.00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifdef _MSC_VER
00024 #include <windows_config.h>
00025 #else
00026 #include <config.h>
00027 #endif
00028
00029 #ifdef _MESSAGES
00030
00031 #include "MSMsgInductLoop.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/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
00050
00051 MSMsgInductLoop::MSMsgInductLoop(const std::string& id, const std::string& msg,
00052 MSLane* lane,
00053 SUMOReal positionInMeters) throw()
00054 : MSMoveReminder(lane), Named(id), myMsg(msg), myCurrentVehicle(0),
00055 myCurrentID(""),
00056 myPosition(positionInMeters), myLastLeaveTime(0),
00057 myVehiclesOnDet(), myVehicleDataCont() {
00058 assert(myPosition >= 0 && myPosition <= lane->getLength());
00059 reset();
00060 myLastLeaveTime = (SUMOReal) MSNet::getInstance()->getCurrentTimeStep() / 1000.;
00061 }
00062
00063
00064 MSMsgInductLoop::~MSMsgInductLoop() throw() {
00065 if (myCurrentVehicle!=0) {
00066 myCurrentVehicle->quitRemindedLeft(this);
00067 }
00068 myCurrentVehicle = 0;
00069 }
00070
00071
00072 void
00073 MSMsgInductLoop::reset() throw() {
00074 myDismissedVehicleNumber = 0;
00075 myVehicleDataCont.clear();
00076 myCurrentID = "";
00077 }
00078
00079
00080 bool
00081 MSMsgInductLoop::isStillActive(MSVehicle& veh, SUMOReal oldPos,
00082 SUMOReal newPos, SUMOReal newSpeed) throw() {
00083 if (newPos < myPosition) {
00084
00085 return true;
00086 }
00087 if (myVehiclesOnDet.find(&veh) == myVehiclesOnDet.end()) {
00088
00089 SUMOReal entryTimestep = (SUMOReal)
00090 ((SUMOReal) MSNet::getInstance()->getCurrentTimeStep() + ((myPosition - oldPos) / newSpeed));
00091 if (newPos - veh.getVehicleType().getLength() > myPosition) {
00092
00093 SUMOReal leaveTimestep = (SUMOReal)
00094 ((SUMOReal) MSNet::getInstance()->getCurrentTimeStep() + ((myPosition - oldPos + veh.getVehicleType().getLength()) / newSpeed));
00095 enterDetectorByMove(veh, entryTimestep);
00096 leaveDetectorByMove(veh, leaveTimestep);
00097 return false;
00098 }
00099
00100 enterDetectorByMove(veh, entryTimestep);
00101 return true;
00102 } else {
00103
00104 if (newPos - veh.getVehicleType().getLength() >= myPosition) {
00105
00106 SUMOReal leaveTimestep = (SUMOReal)
00107 ((SUMOReal) MSNet::getInstance()->getCurrentTimeStep() + ((myPosition - oldPos + veh.getVehicleType().getLength()) / newSpeed));
00108 leaveDetectorByMove(veh, leaveTimestep);
00109 return false;
00110 }
00111
00112 return true;
00113 }
00114 }
00115
00116
00117 void
00118 MSMsgInductLoop::notifyLeave(MSVehicle& veh, bool isArrival, bool isLaneChange) throw() {
00119 if (veh.getPositionOnLane() > myPosition && veh.getPositionOnLane() - veh.getVehicleType().getLength() <= myPosition) {
00120
00121 leaveDetectorByLaneChange(veh);
00122 }
00123 }
00124
00125
00126 bool
00127 MSMsgInductLoop::notifyEnter(MSVehicle& veh, bool, bool) throw() {
00128 if (veh.getPositionOnLane() - veh.getVehicleType().getLength() > myPosition) {
00129
00130 return false;
00131 }
00132
00133 return true;
00134 }
00135
00136
00137 SUMOReal
00138 MSMsgInductLoop::getCurrentSpeed() const throw() {
00139 if (myCurrentVehicle!=0) {
00140 return myCurrentVehicle->getSpeed();
00141 }
00142 return -1;
00143 }
00144
00145
00146 SUMOReal
00147 MSMsgInductLoop::getCurrentLength() const throw() {
00148 if (myCurrentVehicle!=0) {
00149 return myCurrentVehicle->getVehicleType().getLength();
00150 }
00151 return -1;
00152 }
00153
00154
00155 SUMOReal
00156 MSMsgInductLoop::getCurrentOccupancy() const throw() {
00157 if (myCurrentVehicle!=0) {
00158 return 1.;
00159 }
00160 if (myLastLeaveTime*1000.>MSNet::getInstance()->getCurrentTimeStep()-DELTA_T) {
00161 return 0.;
00162 }
00163 return myLastOccupancy;
00164 }
00165
00166
00167 SUMOReal
00168 MSMsgInductLoop::getCurrentPassedNumber() const throw() {
00169 if (myCurrentVehicle!=0) {
00170 return 1.;
00171 }
00172 if (myLastLeaveTime*1000.>MSNet::getInstance()->getCurrentTimeStep()-DELTA_T) {
00173 return 0.;
00174 }
00175 return 1.;
00176 }
00177
00178
00179 unsigned
00180 MSMsgInductLoop::getNVehContributed() const throw() {
00181 return (unsigned) myVehicleDataCont.size();
00182 }
00183
00184
00185 SUMOReal
00186 MSMsgInductLoop::getTimestepsSinceLastDetection() const throw() {
00187 if (myVehiclesOnDet.size() != 0) {
00188
00189 return 0;
00190 }
00191 return MSNet::getInstance()->getCurrentTimeStep() / 1000. - myLastLeaveTime;
00192 }
00193
00194
00195 void
00196 MSMsgInductLoop::writeXMLDetectorProlog(OutputDevice &dev) const throw(IOError) {
00197 dev.writeXMLHeader("detector");
00198 }
00199
00200
00201 void
00202 MSMsgInductLoop::writeXMLOutput(OutputDevice &dev,
00203 SUMOTime startTime, SUMOTime stopTime) throw(IOError) {
00204
00205 SUMOTime t(stopTime-startTime);
00206 unsigned nVehCrossed = (unsigned) myVehicleDataCont.size() + myDismissedVehicleNumber;
00207 SUMOReal flow = ((SUMOReal) myVehicleDataCont.size() / (SUMOReal) t) / DELTA_T * (SUMOReal) 3600.0;
00208 SUMOReal occupancy = accumulate(myVehicleDataCont.begin(), myVehicleDataCont.end(), (SUMOReal) 0.0, occupancySum) / (SUMOReal) t * (SUMOReal) 100.;
00209 SUMOReal meanSpeed = myVehicleDataCont.size()!=0
00210 ? accumulate(myVehicleDataCont.begin(), myVehicleDataCont.end(), (SUMOReal) 0.0, speedSum) / (SUMOReal) myVehicleDataCont.size()
00211 : -1;
00212 SUMOReal meanLength = myVehicleDataCont.size()!=0
00213 ? accumulate(myVehicleDataCont.begin(), myVehicleDataCont.end(), (SUMOReal) 0.0, lengthSum) / (SUMOReal) myVehicleDataCont.size()
00214 : -1;
00215
00216
00217 dev << " <message timestep=\"" <<time2string(startTime)<<"\" "<<"vID=\""<<myCurrentID<<"\" ";
00218 dev<<"nVehContrib=\""<<myVehicleDataCont.size()<<"\" flow=\""<<flow<<
00219 "\" occupancy=\""<<occupancy<<"\" speed=\""<<meanSpeed<<
00220 "\" length=\""<<meanLength<<
00221 "\" nVehEntered=\""<<nVehCrossed<<"\" event_type=\""<<myMsg<<"\" />\n";
00222 reset();
00223 }
00224
00225
00226 void
00227 MSMsgInductLoop::enterDetectorByMove(MSVehicle& veh,
00228 SUMOReal entryTimestep) throw() {
00229 myVehiclesOnDet.insert(std::make_pair(&veh, entryTimestep));
00230 veh.quitRemindedEntered(this);
00231 myCurrentVehicle = &veh;
00232 }
00233
00234
00235 void
00236 MSMsgInductLoop::leaveDetectorByMove(MSVehicle& veh,
00237 SUMOReal leaveTimestep) throw() {
00238 VehicleMap::iterator it = myVehiclesOnDet.find(&veh);
00239 assert(it != myVehiclesOnDet.end());
00240 SUMOReal entryTimestep = it->second;
00241 myVehiclesOnDet.erase(it);
00242 assert(entryTimestep < leaveTimestep);
00243 myVehicleDataCont.push_back(VehicleData(veh.getVehicleType().getLength(), entryTimestep, leaveTimestep));
00244 myLastOccupancy = leaveTimestep - entryTimestep;
00245 myLastLeaveTime = leaveTimestep;
00246 myCurrentID = myCurrentVehicle->getID();
00247 myCurrentVehicle = 0;
00248 veh.quitRemindedLeft(this);
00249 }
00250
00251
00252 void
00253 MSMsgInductLoop::leaveDetectorByLaneChange(MSVehicle& veh) throw() {
00254
00255 myVehiclesOnDet.erase(&veh);
00256 myDismissedVehicleNumber++;
00257 myCurrentID = myCurrentVehicle->getID();
00258 myCurrentVehicle = 0;
00259 veh.quitRemindedLeft(this);
00260 }
00261
00262
00263 void
00264 MSMsgInductLoop::removeOnTripEnd(MSVehicle *veh) throw() {
00265 myCurrentVehicle = 0;
00266 myVehiclesOnDet.erase(veh);
00267 }
00268
00269 #endif
00270
00271
00272