SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00009 // A mover of vehicles that got stucked due to grid locks 00010 /****************************************************************************/ 00011 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00012 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors 00013 /****************************************************************************/ 00014 // 00015 // This file is part of SUMO. 00016 // SUMO is free software: you can redistribute it and/or modify 00017 // it under the terms of the GNU General Public License as published by 00018 // the Free Software Foundation, either version 3 of the License, or 00019 // (at your option) any later version. 00020 // 00021 /****************************************************************************/ 00022 00023 00024 // =========================================================================== 00025 // included modules 00026 // =========================================================================== 00027 #ifdef _MSC_VER 00028 #include <windows_config.h> 00029 #else 00030 #include <config.h> 00031 #endif 00032 00033 #include <iostream> 00034 #include <cassert> 00035 #include <utils/common/MsgHandler.h> 00036 #include "MSNet.h" 00037 #include "MSLane.h" 00038 #include "MSEdge.h" 00039 #include "MSVehicle.h" 00040 #include "MSVehicleControl.h" 00041 #include "MSVehicleTransfer.h" 00042 00043 #ifdef CHECK_MEMORY_LEAKS 00044 #include <foreign/nvwa/debug_new.h> 00045 #endif // CHECK_MEMORY_LEAKS 00046 00047 00048 // =========================================================================== 00049 // static member definitions 00050 // =========================================================================== 00051 MSVehicleTransfer* MSVehicleTransfer::myInstance = 0; 00052 00053 00054 // =========================================================================== 00055 // member method definitions 00056 // =========================================================================== 00057 void 00058 MSVehicleTransfer::addVeh(const SUMOTime t, MSVehicle* veh) { 00059 // get the current edge of the vehicle 00060 const MSEdge* e = veh->getEdge(); 00061 if (veh->isParking()) { 00062 veh->onRemovalFromNet(MSMoveReminder::NOTIFICATION_PARKING); 00063 } else { 00064 if ((veh->succEdge(1) == 0) || veh->enterLaneAtMove(veh->succEdge(1)->getLanes()[0], true)) { 00065 veh->onRemovalFromNet(MSMoveReminder::NOTIFICATION_TELEPORT_ARRIVED); 00066 MSNet::getInstance()->getVehicleControl().scheduleVehicleRemoval(veh); 00067 return; 00068 } 00069 veh->onRemovalFromNet(MSMoveReminder::NOTIFICATION_TELEPORT); 00070 MSNet::getInstance()->informVehicleStateListener(veh, MSNet::VEHICLE_STATE_STARTING_TELEPORT); 00071 } 00072 myVehicles.push_back(VehicleInformation(veh, t + TIME2STEPS(e->getCurrentTravelTime()), veh->isParking())); 00073 } 00074 00075 00076 void 00077 MSVehicleTransfer::checkInsertions(SUMOTime time) { 00078 // go through vehicles 00079 for (VehicleInfVector::iterator i = myVehicles.begin(); i != myVehicles.end();) { 00080 // get the vehicle information 00081 VehicleInformation& desc = *i; 00082 00083 if (desc.myParking) { 00084 // handle parking vehicles 00085 if (desc.myVeh->processNextStop(1) == 0) { 00086 ++i; 00087 continue; 00088 } 00089 // parking finished, head back into traffic 00090 } 00091 const SUMOVehicleClass vclass = desc.myVeh->getVehicleType().getVehicleClass(); 00092 const MSEdge* e = desc.myVeh->getEdge(); 00093 const MSEdge* nextEdge = desc.myVeh->succEdge(1); 00094 00095 // get the lane on which this vehicle should continue 00096 // first select all the lanes which allow continuation onto nextEdge 00097 // then pick the one which is least occupied 00098 // @todo maybe parking vehicles should always continue on the rightmost lane? 00099 MSLane* l = e->getFreeLane(e->allowedLanes(*nextEdge, vclass), vclass); 00100 00101 if (desc.myParking) { 00102 // handle parking vehicles 00103 if (l->isInsertionSuccess(desc.myVeh, 0, desc.myVeh->getPositionOnLane(), false, MSMoveReminder::NOTIFICATION_PARKING)) { 00104 i = myVehicles.erase(i); 00105 } else { 00106 i++; 00107 } 00108 } else { 00109 // handle teleporting vehicles 00110 if (l->freeInsertion(*(desc.myVeh), MIN2(l->getMaxSpeed(), desc.myVeh->getMaxSpeed()), MSMoveReminder::NOTIFICATION_TELEPORT)) { 00111 WRITE_WARNING("Vehicle '" + desc.myVeh->getID() + "' ends teleporting on edge '" + e->getID() + "', simulation time " + time2string(MSNet::getInstance()->getCurrentTimeStep()) + "."); 00112 MSNet::getInstance()->informVehicleStateListener(desc.myVeh, MSNet::VEHICLE_STATE_ENDING_TELEPORT); 00113 i = myVehicles.erase(i); 00114 } else { 00115 // could not insert. maybe we should proceed in virtual space 00116 if (desc.myProceedTime < time) { 00117 // get the lanes of the next edge (the one the vehicle wiil be 00118 // virtually on after all these computations) 00119 desc.myVeh->leaveLane(MSMoveReminder::NOTIFICATION_TELEPORT); 00120 // get the one beyond the one the vehicle moved to 00121 // !!! only move reminders are called but the edge is not advanced 00122 const MSEdge* nextEdge = desc.myVeh->succEdge(1); 00123 // let the vehicle move to the next edge 00124 if (nextEdge == 0) { 00125 WRITE_WARNING("Vehicle '" + desc.myVeh->getID() + "' ends teleporting on end edge '" + e->getID() + "'."); 00126 MSNet::getInstance()->getVehicleControl().scheduleVehicleRemoval(desc.myVeh); 00127 i = myVehicles.erase(i); 00128 continue; 00129 } 00130 // use current travel time to determine when to move the vehicle forward 00131 desc.myProceedTime = time + TIME2STEPS(e->getCurrentTravelTime()); 00132 } 00133 ++i; 00134 } 00135 } 00136 } 00137 } 00138 00139 00140 bool 00141 MSVehicleTransfer::hasPending() const { 00142 return !myVehicles.empty(); 00143 } 00144 00145 00146 MSVehicleTransfer* 00147 MSVehicleTransfer::getInstance() { 00148 if (myInstance == 0) { 00149 myInstance = new MSVehicleTransfer(); 00150 } 00151 return myInstance; 00152 } 00153 00154 00155 MSVehicleTransfer::MSVehicleTransfer() {} 00156 00157 00158 MSVehicleTransfer::~MSVehicleTransfer() { 00159 myInstance = 0; 00160 } 00161 00162 00163 00164 /****************************************************************************/ 00165