SUMO - Simulation of Urban MObility
MSVehicleTransfer.cpp
Go to the documentation of this file.
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 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines