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 "MSVehicle.h"
00039 #include "MSVehicleControl.h"
00040 #include "MSVehicleTransfer.h"
00041 
00042 #ifdef CHECK_MEMORY_LEAKS
00043 #include <foreign/nvwa/debug_new.h>
00044 #endif // CHECK_MEMORY_LEAKS
00045 
00046 
00047 // ===========================================================================
00048 // static member definitions
00049 // ===========================================================================
00050 MSVehicleTransfer* MSVehicleTransfer::myInstance = 0;
00051 
00052 
00053 // ===========================================================================
00054 // member method definitions
00055 // ===========================================================================
00056 void
00057 MSVehicleTransfer::addVeh(const SUMOTime t, MSVehicle* veh) {
00058     // get the current edge of the vehicle
00059     const MSEdge* e = veh->getEdge();
00060     if (veh->isParking()) {
00061         veh->onRemovalFromNet(MSMoveReminder::NOTIFICATION_PARKING);
00062     } else {
00063         if ((veh->succEdge(1) == 0) || veh->enterLaneAtMove(veh->succEdge(1)->getLanes()[0], true)) {
00064             veh->onRemovalFromNet(MSMoveReminder::NOTIFICATION_TELEPORT_ARRIVED);
00065             MSNet::getInstance()->getVehicleControl().scheduleVehicleRemoval(veh);
00066             return;
00067         }
00068         veh->onRemovalFromNet(MSMoveReminder::NOTIFICATION_TELEPORT);
00069         MSNet::getInstance()->informVehicleStateListener(veh, MSNet::VEHICLE_STATE_STARTING_TELEPORT);
00070     }
00071     myVehicles.push_back(VehicleInformation(veh, t + TIME2STEPS(e->getCurrentTravelTime()), veh->isParking()));
00072 }
00073 
00074 
00075 void
00076 MSVehicleTransfer::checkInsertions(SUMOTime time) {
00077     // go through vehicles
00078     for (VehicleInfVector::iterator i = myVehicles.begin(); i != myVehicles.end();) {
00079         // get the vehicle information
00080         VehicleInformation& desc = *i;
00081 
00082         if (desc.myParking) {
00083             // handle parking vehicles
00084             if (desc.myVeh->processNextStop(1) == 0) {
00085                 ++i;
00086                 continue;
00087             }
00088             // parking finished, head back into traffic
00089         }
00090         const SUMOVehicleClass vclass = desc.myVeh->getVehicleType().getVehicleClass();
00091         const MSEdge* e = desc.myVeh->getEdge();
00092         const MSEdge* nextEdge = desc.myVeh->succEdge(1);
00093 
00094         // get the lane on which this vehicle should continue
00095         // first select all the lanes which allow continuation onto nextEdge
00096         //   then pick the one which is least occupied
00097         // @todo maybe parking vehicles should always continue on the rightmost lane?
00098         MSLane* l = e->getFreeLane(e->allowedLanes(*nextEdge, vclass), vclass);
00099 
00100         if (desc.myParking) {
00101             // handle parking vehicles
00102             if (l->isInsertionSuccess(desc.myVeh, 0, desc.myVeh->getPositionOnLane(), false, MSMoveReminder::NOTIFICATION_PARKING)) {
00103                 i = myVehicles.erase(i);
00104             } else {
00105                 i++;
00106             }
00107         } else {
00108             // handle teleporting vehicles
00109             if (l->freeInsertion(*(desc.myVeh), MIN2(l->getMaxSpeed(), desc.myVeh->getMaxSpeed()), MSMoveReminder::NOTIFICATION_TELEPORT)) {
00110                 WRITE_WARNING("Vehicle '" + desc.myVeh->getID() + "' ends teleporting on edge '" + e->getID() + "', simulation time " + time2string(MSNet::getInstance()->getCurrentTimeStep()) + ".");
00111                 MSNet::getInstance()->informVehicleStateListener(desc.myVeh, MSNet::VEHICLE_STATE_ENDING_TELEPORT);
00112                 i = myVehicles.erase(i);
00113             } else {
00114                 // could not insert. maybe we should proceed in virtual space
00115                 if (desc.myProceedTime < time) {
00116                     // get the lanes of the next edge (the one the vehicle wiil be
00117                     //  virtually on after all these computations)
00118                     desc.myVeh->leaveLane(MSMoveReminder::NOTIFICATION_TELEPORT);
00119                     // get the one beyond the one the vehicle moved to
00120                     // !!! only move reminders are called but the edge is not advanced
00121                     const MSEdge* nextEdge = desc.myVeh->succEdge(1);
00122                     // let the vehicle move to the next edge
00123                     if (nextEdge == 0) {
00124                         WRITE_WARNING("Vehicle '" + desc.myVeh->getID() + "' ends teleporting on end edge '" + e->getID() + "'.");
00125                         MSNet::getInstance()->getVehicleControl().scheduleVehicleRemoval(desc.myVeh);
00126                         i = myVehicles.erase(i);
00127                         continue;
00128                     }
00129                     // use current travel time to determine when to move the vehicle forward
00130                     desc.myProceedTime = time + TIME2STEPS(e->getCurrentTravelTime());
00131                 }
00132                 ++i;
00133             }
00134         }
00135     }
00136 }
00137 
00138 
00139 bool
00140 MSVehicleTransfer::hasPending() const {
00141     return !myVehicles.empty();
00142 }
00143 
00144 
00145 MSVehicleTransfer*
00146 MSVehicleTransfer::getInstance() {
00147     if (myInstance == 0) {
00148         myInstance = new MSVehicleTransfer();
00149     }
00150     return myInstance;
00151 }
00152 
00153 
00154 MSVehicleTransfer::MSVehicleTransfer() {}
00155 
00156 
00157 MSVehicleTransfer::~MSVehicleTransfer() {
00158     myInstance = 0;
00159 }
00160 
00161 
00162 
00163 /****************************************************************************/
00164 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines