MSMsgInductLoop.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00006 // An unextended detector measuring at a fixed position on a fixed lane.
00007 /****************************************************************************/
00008 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00009 // Copyright 2001-2010 DLR (http://www.dlr.de/) and contributors
00010 /****************************************************************************/
00011 //
00012 //   This program is free software; you can redistribute it and/or modify
00013 //   it under the terms of the GNU General Public License as published by
00014 //   the Free Software Foundation; either version 2 of the License, or
00015 //   (at your option) any later version.
00016 //
00017 /****************************************************************************/
00018 
00019 
00020 // ===========================================================================
00021 // included modules
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 // method definitions
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         // detector not reached yet
00085         return true;
00086     }
00087     if (myVehiclesOnDet.find(&veh) == myVehiclesOnDet.end()) {
00088         // entered the detector by move
00089         SUMOReal entryTimestep = (SUMOReal)
00090                                  ((SUMOReal) MSNet::getInstance()->getCurrentTimeStep() + ((myPosition - oldPos) / newSpeed));
00091         if (newPos - veh.getVehicleType().getLength() > myPosition) {
00092             // entered and passed detector in a single timestep
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         // entered detector, but not passed
00100         enterDetectorByMove(veh, entryTimestep);
00101         return true;
00102     } else {
00103         // vehicle has been on the detector the previous timestep
00104         if (newPos - veh.getVehicleType().getLength() >= myPosition) {
00105             // vehicle passed the detector
00106             SUMOReal leaveTimestep = (SUMOReal)
00107                                      ((SUMOReal) MSNet::getInstance()->getCurrentTimeStep() + ((myPosition - oldPos + veh.getVehicleType().getLength()) / newSpeed));
00108             leaveDetectorByMove(veh, leaveTimestep);
00109             return false;
00110         }
00111         // vehicle stays on the detector
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         // vehicle is on detector during lane change
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         // vehicle-front is beyond detector. Ignore
00130         return false;
00131     }
00132     // vehicle is in front of detector
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         // detector is occupied
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     //dev<< "   <interval begin=\""<<startTime<<"\" end=\""<<stopTime<<"\" id=\""<<getID()<<"\" msg=\""<<myMsg<<"\" />\n";
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     //dev<<"   <interval begin=\""<<startTime<<"\" end=\""<<
00216     //stopTime<<"\" "<<"id=\""<<getID()<<"\" ";
00217     dev << "   <message timestep=\"" <<time2string(startTime)<<"\" "<<"vID=\""<<myCurrentID<<"\" ";//<<getID()<<"\" ";
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     // Discard entry data
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 

Generated on Wed May 5 00:06:32 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6