@@ -70,6 +70,7 @@ std::set<std::string> MSDevice_Taxi::myVClassWarningVTypes;
7070
7171#define TAXI_SERVICE " taxi"
7272#define TAXI_SERVICE_PREFIX " taxi:"
73+ #define SWAP_THRESHOLD 5
7374
7475// ===========================================================================
7576// method definitions
@@ -830,8 +831,11 @@ MSDevice_Taxi::customerArrived(const MSTransportable* person) {
830831 myDispatcher->fulfilledReservation (res);
831832 }
832833 myCurrentReservations.clear ();
833- if (MSGlobals::gUseMesoSim && MSNet::getInstance ()->getCurrentTimeStep () < myServiceEnd) {
834- myIdleAlgorithm->idle (this );
834+ checkTaskSwap ();
835+ if (isEmpty ()) {
836+ if (MSGlobals::gUseMesoSim && MSNet::getInstance ()->getCurrentTimeStep () < myServiceEnd) {
837+ myIdleAlgorithm->idle (this );
838+ }
835839 }
836840 } else {
837841 // check whether a single reservation has been fulfilled
@@ -854,6 +858,44 @@ MSDevice_Taxi::customerArrived(const MSTransportable* person) {
854858}
855859
856860
861+ void
862+ MSDevice_Taxi::checkTaskSwap () {
863+ const std::string swapGroup = myHolder.getStringParam (" device.taxi.swapGroup" , false , " " );
864+ if (swapGroup != " " ) {
865+ SUMOAbstractRouter<MSEdge, SUMOVehicle>& router = myDispatcher->getRouter ();
866+ const double stopTime = myHolder.isStopped () ? MAX2 (0.0 , STEPS2TIME (myHolder.getNextStop ().duration )) : 0 ;
867+ double maxSaving = 0 ;
868+ MSDevice_Taxi* bestSwap = nullptr ;
869+ for (MSDevice_Taxi* taxi : myFleet) {
870+ if (taxi->getHolder ().hasDeparted () && taxi->getState () == PICKUP
871+ && taxi->getHolder ().getStringParam (" device.taxi.swapGroup" , false , " " ) == swapGroup) {
872+ SUMOVehicle& veh = taxi->getHolder ();
873+ const MSStop& stop = veh.getNextStop ();
874+ ConstMSEdgeVector toPickup (veh.getCurrentRouteEdge (), stop.edge + 1 );
875+ const double cost = router.recomputeCostsPos (toPickup, &veh, veh.getPositionOnLane (), stop.pars .endPos , SIMSTEP);
876+ ConstMSEdgeVector toPickup2;
877+ router.compute (myHolder.getEdge (), myHolder.getPositionOnLane (), *stop.edge , stop.pars .endPos , &myHolder, SIMSTEP, toPickup2, true );
878+ if (!toPickup2.empty ()) {
879+ const double cost2 = router.recomputeCostsPos (toPickup2, &myHolder, myHolder.getPositionOnLane (), stop.pars .endPos , SIMSTEP);
880+ const double saving = cost - cost2 - stopTime;
881+ // std::cout << SIMTIME << " taxi=" << getID() << " other=" << veh.getID() << " cost=" << cost << " cost2=" << cost2 << " stopTime=" << stopTime << " saving=" << saving << " route1=" << toString(toPickup) << " route2=" << toString(toPickup2) << "\n";
882+ if (saving > maxSaving) {
883+ maxSaving = saving;
884+ bestSwap = taxi;
885+ }
886+ }
887+ }
888+ }
889+ if (maxSaving > SWAP_THRESHOLD) {
890+ dispatchShared (bestSwap->myLastDispatch );
891+ bestSwap->myCurrentReservations .clear ();
892+ bestSwap->myCustomers .clear ();
893+ bestSwap->myState = EMPTY;
894+ }
895+ }
896+ }
897+
898+
857899bool
858900MSDevice_Taxi::hasFuturePickup () {
859901 for (const auto & stop : myHolder.getStops ()) {
0 commit comments