SUMO - Simulation of Urban MObility

MSVehicleTransfer.cpp

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