Eclipse SUMO - Simulation of Urban MObility
MSDispatch_RouteExtension.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2007-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
18 // An algorithm that performs dispatch for the taxi device
19 /****************************************************************************/
20 #include <config.h>
21 
22 #include <limits>
23 #include <microsim/MSNet.h>
24 #include <microsim/MSEdge.h>
26 #include "MSRoutingEngine.h"
28 
29 //#define DEBUG_DISPATCH
30 //#define DEBUG_COND2(obj) (obj->getID() == "p0")
31 #define DEBUG_COND2(obj) (true)
32 
33 
34 // ===========================================================================
35 // method definitions
36 // ===========================================================================
37 void
38 MSDispatch_RouteExtension::findInsertionPoint(std::vector<const Reservation*>::iterator& resIt, EdgePosVector::iterator& edgeIt,
39  const EdgePosVector::iterator& edgeEnd, ConstMSEdgeVector& route,
40  const MSEdge* newEdge, const double newPos) const {
41  for (const MSEdge* edge : route) {
42  while (edgeIt != edgeEnd && edge == edgeIt->first) {
43  if (edge == newEdge && edgeIt->second > newPos) {
44  break;
45  }
46  resIt++;
47  edgeIt++;
48  }
49  if (edge == newEdge) {
50  break;
51  }
52  }
53 }
54 
55 
56 int
57 MSDispatch_RouteExtension::dispatch(MSDevice_Taxi* taxi, std::vector<Reservation*>::iterator& resIt, SUMOAbstractRouter<MSEdge, SUMOVehicle>& router, std::vector<Reservation*>& reservations) {
58  const Reservation* const res = *resIt;
59 #ifdef DEBUG_DISPATCH
60  if (DEBUG_COND2(person)) {
61  std::cout << SIMTIME << " dispatch taxi=" << taxi->getHolder().getID() << " person=" << toString(res->persons) << "\n";
62  }
63 #endif
65  const bool isPerson = (*res->persons.begin())->isPerson();
66  int capacityLeft = remainingCapacity(taxi, res);
67  std::vector<const Reservation*> sequence{ res, res };
68  std::vector<const Reservation*> toRemove{ res };
69  EdgePosVector posSequence({ std::make_pair(res->from, res->fromPos), std::make_pair(res->to, res->toPos) });
70  const Reservation* first = sequence.front();
71  const Reservation* last = sequence.back();
72  ConstMSEdgeVector route;
73  router.compute(first->from, first->fromPos, last->to, last->toPos, &taxi->getHolder(), MAX2(now, first->pickupTime), route);
74  // check whether the ride can be shared
75  for (auto it2 = resIt + 1; it2 != reservations.end();) {
76  Reservation* const res2 = *it2;
77  const bool isPerson2 = (*res2->persons.begin())->isPerson();
78  if (capacityLeft < (int)res2->persons.size() || isPerson != isPerson2 || !taxi->compatibleLine(res2)) {
79  it2++;
80  continue;
81  }
82  // check whether res2 picks up or gets picked up on the way
83  ConstMSEdgeVector route2;
84  // TODO It may be more efficient to check first whether from and to are already in the route
85  router.compute(res2->from, res2->fromPos, res2->to, res2->toPos, &taxi->getHolder(), MAX2(now, res2->pickupTime), route2);
86  const bool pickup = std::find(route.begin(), route.end(), res2->from) != route.end();
87  const bool dropoff = std::find(route.begin(), route.end(), res2->to) != route.end();
88 #ifdef DEBUG_DISPATCH
89  if (DEBUG_COND2(person)) std::cout << " consider sharing ride with " << toString(res2->persons)
90  << " pickup=" << pickup << " startFirst=" << (std::find(route2.begin(), route2.end(), first->from) != route2.end())
91  << " dropoff=" << dropoff << " endLast=" << (std::find(route2.begin(), route2.end(), last->to) != route2.end())
92  << "\n";
93 #endif
94  if ((pickup || std::find(route2.begin(), route2.end(), first->from) != route2.end()) &&
95  (dropoff || std::find(route2.begin(), route2.end(), last->to) != route2.end())) {
96  std::vector<const Reservation*>::iterator resSeqIt = sequence.begin();
97  EdgePosVector::iterator edgeIt = posSequence.begin();
98  if (pickup) {
99  // new reservation gets picked up
100  findInsertionPoint(resSeqIt, edgeIt, posSequence.end(), route, res2->from, res2->fromPos);
101  }
102  resSeqIt = sequence.insert(resSeqIt, res2) + 1;
103  edgeIt = posSequence.insert(edgeIt, std::make_pair(res2->from, res2->fromPos)) + 1;
104  if (dropoff) {
105  // new reservation drops off and route continues
106  findInsertionPoint(resSeqIt, edgeIt, posSequence.end(), route, res2->to, res2->toPos);
107  sequence.insert(resSeqIt, res2);
108  posSequence.insert(edgeIt, std::make_pair(res2->from, res2->fromPos));
109  } else {
110  // new reservation ends last
111  sequence.push_back(res2);
112  posSequence.push_back(std::make_pair(res2->to, res2->toPos));
113  }
114  toRemove.push_back(res2);
115  it2 = reservations.erase(it2); // (resIt before it2) stays valid
116  // TODO we have more capacity if some pickup is after an earlier dropoff
117  capacityLeft -= (int)res2->persons.size();
118  if (capacityLeft == 0) {
119  break;
120  }
121  route.clear();
122  first = sequence.front();
123  last = sequence.back();
124  // TODO this is wrong for non linear networks! should be reusing the route snippets from above
125  router.compute(first->from, first->fromPos, last->to, last->toPos, &taxi->getHolder(), MAX2(now, first->pickupTime), route);
126  } else {
127  it2++;
128  }
129  }
130  if (sequence.size() > 2) {
131  taxi->dispatchShared(sequence);
132  if (myOutput != nullptr) {
133  myOutput->writeXMLHeader("DispatchInfo_RouteExtension", "");
134  myOutput->openTag("dispatchShared");
135  myOutput->writeAttr("time", time2string(now));
136  myOutput->writeAttr("id", taxi->getHolder().getID());
137  myOutput->writeAttr("persons", toString(res->persons));
138  myOutput->writeAttr("sharingPersons", toString(sequence));
139  myOutput->writeAttr("type", "routeExtension");
140  myOutput->closeTag();
141  }
142 #ifdef DEBUG_DISPATCH
143  if (DEBUG_COND2(person)) std::cout << " sharing ride with " << toString(sequence)
144  << "\n";
145 #endif
146  } else {
147  taxi->dispatch(*res);
148  }
149  for (const Reservation* r : toRemove) {
150  servedReservation(r); // deleting r
151  }
152  resIt = reservations.erase(resIt);
153  return (int)toRemove.size();
154 }
155 
156 
157 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
#define DEBUG_COND2(obj)
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:74
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition: SUMOTime.cpp:69
#define SIMTIME
Definition: SUMOTime.h:62
T MAX2(T a, T b)
Definition: StdDefs.h:82
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
A device which collects info on the vehicle trip (mainly on departure and arrival)
Definition: MSDevice_Taxi.h:49
void dispatch(const Reservation &res)
service the given reservation
void dispatchShared(std::vector< const Reservation * > reservations)
service the given reservations
bool compatibleLine(const Reservation *res)
whether the given reservation is compatible with the taxi line
void findInsertionPoint(std::vector< const Reservation * >::iterator &resIt, EdgePosVector::iterator &edgeIt, const EdgePosVector::iterator &edgeEnd, ConstMSEdgeVector &route, const MSEdge *newEdge, const double newPos) const
virtual int dispatch(MSDevice_Taxi *taxi, std::vector< Reservation * >::iterator &resIt, SUMOAbstractRouter< MSEdge, SUMOVehicle > &router, std::vector< Reservation * > &reservations)
trigger taxi dispatch.
std::vector< std::pair< const MSEdge *, double > > EdgePosVector
OutputDevice * myOutput
optional file output for dispatch information
Definition: MSDispatch.h:203
int remainingCapacity(const MSDevice_Taxi *taxi, const Reservation *res)
whether the given taxi has sufficient capacity to serve the reservation
Definition: MSDispatch.cpp:316
void servedReservation(const Reservation *res)
Definition: MSDispatch.cpp:242
A road/street connecting two junctions.
Definition: MSEdge.h:77
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:184
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:320
SUMOVehicle & getHolder() const
Returns the vehicle that holds this device.
const std::string & getID() const
Returns the id.
Definition: Named.h:74
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:254
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
bool writeXMLHeader(const std::string &rootElement, const std::string &schemaFile, std::map< SumoXMLAttr, std::string > attrs=std::map< SumoXMLAttr, std::string >(), bool includeConfig=true)
Writes an XML header with optional configuration.
virtual bool compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into, bool silent=false)=0
Builds the route between the given edges using the minimum effort at the given time The definition of...
SUMOTime pickupTime
Definition: MSDispatch.h:79
const MSEdge * to
Definition: MSDispatch.h:84
double fromPos
Definition: MSDispatch.h:82
const MSEdge * from
Definition: MSDispatch.h:81
std::set< const MSTransportable * > persons
Definition: MSDispatch.h:77
double toPos
Definition: MSDispatch.h:85