00001 /****************************************************************************/ 00007 // A mover of vehicles that got stucked due to grid locks 00008 /****************************************************************************/ 00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00010 // Copyright 2001-2010 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 <iostream> 00031 #include <cassert> 00032 #include <utils/common/MsgHandler.h> 00033 #include "MSNet.h" 00034 #include "MSLane.h" 00035 #include "MSVehicle.h" 00036 #include "MSVehicleControl.h" 00037 #include "MSVehicleTransfer.h" 00038 00039 #ifdef CHECK_MEMORY_LEAKS 00040 #include <foreign/nvwa/debug_new.h> 00041 #endif // CHECK_MEMORY_LEAKS 00042 00043 00044 // =========================================================================== 00045 // static member definitions 00046 // =========================================================================== 00047 MSVehicleTransfer *MSVehicleTransfer::myInstance = 0; 00048 00049 00050 // =========================================================================== 00051 // member method definitions 00052 // =========================================================================== 00053 void 00054 MSVehicleTransfer::addVeh(MSVehicle *veh) throw() { 00055 // get the current edge of the vehicle 00056 MSEdge *e = MSEdge::dictionary(veh->getEdge()->getID()); 00057 // let the vehicle be on the one 00058 veh->onRemovalFromNet(true); 00059 if (!veh->hasSuccEdge(1)||proceedVirtualReturnWhetherEnded(*veh, MSEdge::dictionary(veh->succEdge(1)->getID()))) { 00060 MSNet::getInstance()->getVehicleControl().scheduleVehicleRemoval(veh); 00061 return; 00062 } 00063 // mark the next one 00064 myNoTransfered++; 00065 // save information 00066 myVehicles.push_back(VehicleInformation(veh, MSNet::getInstance()->getCurrentTimeStep())); 00067 MSNet::getInstance()->informVehicleStateListener(veh, MSNet::VEHICLE_STATE_STARTING_TELEPORT); 00068 } 00069 00070 00071 void 00072 MSVehicleTransfer::checkEmissions(SUMOTime time) throw() { 00073 // go through vehicles 00074 for (VehicleInfVector::iterator i=myVehicles.begin(); i!=myVehicles.end();) { 00075 // get the vehicle information 00076 VehicleInformation &desc = *i; 00077 const MSEdge *e = desc.myVeh->getEdge(); 00078 MSLane *l = e->getFreeLane(desc.myVeh->getVehicleType().getVehicleClass()); 00079 // check whether the vehicle may be emitted onto a following edge 00080 if (l->freeEmit(*(desc.myVeh), MIN2(l->getMaxSpeed(), desc.myVeh->getMaxSpeed()))) { 00081 // remove from this if so 00082 WRITE_WARNING("Vehicle '" + desc.myVeh->getID()+ "' ends teleporting on edge '" + e->getID()+ "', simulation time " + toString(MSNet::getInstance()->getCurrentTimeStep()) + "."); 00083 MSNet::getInstance()->informVehicleStateListener(desc.myVeh, MSNet::VEHICLE_STATE_ENDING_TELEPORT); 00084 i = myVehicles.erase(i); 00085 } else { 00086 // otherwise, check whether a consecutive edge may be used 00087 if (desc.myProceedTime<time) { 00088 // get the lanes of the next edge (the one the vehicle wiil be 00089 // virtually on after all these computations) 00090 MSLane *tmp = *(e->getLanes().begin()); 00091 // get the one beyond the one the vehicle moved to 00092 MSEdge *nextEdge = MSEdge::dictionary(desc.myVeh->succEdge(1)->getID()); 00093 // let the vehicle move to the next edge 00094 if (proceedVirtualReturnWhetherEnded(*desc.myVeh, nextEdge)) { 00095 WRITE_WARNING("Vehicle '" + desc.myVeh->getID()+ "' ends teleporting on end edge '" + e->getID()+ "'."); 00096 MSNet::getInstance()->getVehicleControl().scheduleVehicleRemoval(desc.myVeh); 00097 i = myVehicles.erase(i); 00098 continue; 00099 } 00100 // get the time the vehicle needs to pass the current edge 00101 // !!! maybe, the time should be compued in other ways 00102 desc.myProceedTime = time + (SUMOTime)(tmp->getLength() / tmp->getMaxSpeed() * 2.0); 00103 } 00104 ++i; 00105 } 00106 00107 } 00108 } 00109 00110 00111 bool 00112 MSVehicleTransfer::proceedVirtualReturnWhetherEnded(MSVehicle &veh, const MSEdge *const newEdge) throw() { 00113 veh.moveRoutePointer(newEdge); 00114 MSRouteIterator destination = veh.getRoute().end() - 1; 00115 return veh.getEdge() == *destination; 00116 } 00117 00118 00119 MSVehicleTransfer * 00120 MSVehicleTransfer::getInstance() throw() { 00121 if (myInstance==0) { 00122 myInstance = new MSVehicleTransfer(); 00123 } 00124 return myInstance; 00125 } 00126 00127 00128 MSVehicleTransfer::MSVehicleTransfer() throw() 00129 : myNoTransfered(0) {} 00130 00131 00132 MSVehicleTransfer::~MSVehicleTransfer() throw() { 00133 myInstance = 0; 00134 } 00135 00136 00137 00138 /****************************************************************************/ 00139
1.5.6