Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2007-2025 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 : /****************************************************************************/
14 : /// @file MSDispatch_TraCI.cpp
15 : /// @author Jakob Erdmann
16 : /// @date 16.12.2019
17 : ///
18 : // An algorithm that performs dispatch for the taxi device
19 : /****************************************************************************/
20 : #include <config.h>
21 :
22 : #include <limits>
23 : #include <microsim/transportables/MSTransportable.h>
24 : #include "MSDispatch_TraCI.h"
25 :
26 : //#define DEBUG_RESERVATION
27 : //#define DEBUG_DISPATCH
28 : //#define DEBUG_SERVABLE
29 : //#define DEBUG_TRAVELTIME
30 : //#define DEBUG_DETOUR
31 : //#define DEBUG_COND2(obj) (obj->getID() == "p0")
32 : #define DEBUG_COND2(obj) (true)
33 :
34 : // ===========================================================================
35 : // MSDispatch_TraCI methods
36 : // ===========================================================================
37 :
38 : Reservation*
39 369 : MSDispatch_TraCI::addReservation(MSTransportable* person,
40 : SUMOTime reservationTime,
41 : SUMOTime pickupTime,
42 : SUMOTime earliestPickupTime,
43 : const MSEdge* from, double fromPos,
44 : const MSStoppingPlace* fromStop,
45 : const MSEdge* to, double toPos,
46 : const MSStoppingPlace* toStop,
47 : std::string group,
48 : const std::string& line,
49 : int maxCapacity,
50 : int maxContainerCapacity) {
51 738 : Reservation* res = MSDispatch::addReservation(person, reservationTime, pickupTime, earliestPickupTime, from, fromPos, fromStop, to, toPos, toStop, group, line, maxCapacity, maxContainerCapacity);
52 369 : if (!myReservationLookup.has(res)) {
53 708 : myReservationLookup.insert(res->id, res);
54 : }
55 369 : return res;
56 : }
57 :
58 : std::string
59 72 : MSDispatch_TraCI::removeReservation(MSTransportable* person,
60 : const MSEdge* from, double fromPos,
61 : const MSEdge* to, double toPos,
62 : std::string group) {
63 144 : const std::string removedID = MSDispatch::removeReservation(person, from, fromPos, to, toPos, group);
64 : if (myReservationLookup.hasString(removedID)) {
65 : // warning! res is already deleted
66 0 : const Reservation* res = myReservationLookup.get(removedID);
67 0 : myReservationLookup.remove(removedID, res);
68 : }
69 72 : return removedID;
70 : }
71 :
72 :
73 : void
74 317 : MSDispatch_TraCI::fulfilledReservation(const Reservation* res) {
75 317 : myReservationLookup.remove(res->id, res);
76 317 : MSDispatch::fulfilledReservation(res);
77 317 : myHasServableReservations = myReservationLookup.size() > 0;
78 317 : }
79 :
80 : void
81 207 : MSDispatch_TraCI::interpretDispatch(MSDevice_Taxi* taxi, const std::vector<std::string>& reservationsIDs) {
82 : std::vector<const Reservation*> reservations;
83 906 : for (std::string resID : reservationsIDs) {
84 : if (myReservationLookup.hasString(resID)) {
85 699 : reservations.push_back(myReservationLookup.get(resID));
86 : } else {
87 0 : throw InvalidArgument("Reservation id '" + resID + "' is not known");
88 : }
89 : }
90 : try {
91 207 : if (reservations.size() == 1) {
92 93 : taxi->dispatch(*reservations.front());
93 : } else {
94 114 : taxi->dispatchShared(reservations);
95 : }
96 4 : } catch (ProcessError& e) {
97 8 : throw InvalidArgument(e.what());
98 4 : }
99 : // in case of ride sharing the same reservation may occur multiple times
100 203 : std::set<const Reservation*> unique(reservations.begin(), reservations.end());
101 605 : for (const Reservation* res : unique) {
102 402 : servedReservation(res, taxi);
103 : }
104 207 : }
105 :
106 :
107 : std::string
108 5 : MSDispatch_TraCI::splitReservation(std::string resID, std::vector<std::string> personIDs) {
109 : if (myReservationLookup.hasString(resID)) {
110 5 : Reservation* res = const_cast<Reservation*>(myReservationLookup.get(resID));
111 5 : if (myRunningReservations.count(res->group) != 0 && myRunningReservations[res->group].count(res) != 0) {
112 0 : throw InvalidArgument("Cannot split reservation '" + resID + "' after dispatch");
113 : }
114 : std::set<std::string> allPersons;
115 25 : for (const MSTransportable* t : res->persons) {
116 : allPersons.insert(t->getID());
117 : }
118 15 : for (std::string p : personIDs) {
119 : if (allPersons.count(p) == 0) {
120 0 : throw InvalidArgument("Person '" + p + "' is not part of reservation '" + resID + "'");
121 : }
122 : }
123 5 : if (personIDs.size() == allPersons.size()) {
124 0 : throw InvalidArgument("Cannot remove all person from reservation '" + resID + "'");
125 : }
126 : std::vector<const MSTransportable*> split;
127 15 : for (const std::string& p : personIDs) {
128 14 : for (const MSTransportable* const t : res->persons) {
129 14 : if (t->getID() == p) {
130 : res->persons.erase(t);
131 10 : split.push_back(t);
132 : break;
133 : }
134 : }
135 : }
136 10 : Reservation* newRes = new Reservation(toString(myReservationCount++), split,
137 : res->reservationTime, res->pickupTime,
138 : res->earliestPickupTime,
139 : res->from, res->fromPos, res->fromStop,
140 : res->to, res->toPos, res->toStop,
141 5 : res->group, res->line);
142 5 : myGroupReservations[res->group].push_back(newRes);
143 10 : myReservationLookup.insert(newRes->id, newRes);
144 5 : return newRes->id;
145 5 : } else {
146 0 : throw InvalidArgument("Reservation id '" + resID + "' is not known");
147 : }
148 : }
149 :
150 :
151 :
152 : //
153 : /****************************************************************************/
|