Eclipse SUMO - Simulation of Urban MObility
PublicTransportEdge.h
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2001-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 // The PublicTransportEdge is a special intermodal edge connecting the stop edges with scheduled traffic
19 /****************************************************************************/
20 #pragma once
21 #include <config.h>
22 
23 #include "IntermodalEdge.h"
24 
25 
26 // ===========================================================================
27 // class definitions
28 // ===========================================================================
30 template<class E, class L, class N, class V>
31 class PublicTransportEdge : public IntermodalEdge<E, L, N, V> {
32 private:
33  struct Schedule {
34  Schedule(const std::string& _id, const SUMOTime _begin, const int _repetitionNumber, const SUMOTime _period, const SUMOTime _travelTime)
35  : ids({
36  _id
37  }), begin(_begin), repetitionNumber(_repetitionNumber), period(_period), travelTime(_travelTime) {}
38  // the id of the vehicle or flow from which this schedule is generated
39  std::vector<std::string> ids;
40  const SUMOTime begin;
42  // the repetition period for a flow or -1 for a vehicle
45  };
46 
47 public:
48  PublicTransportEdge(const std::string id, int numericalID, const IntermodalEdge<E, L, N, V>* entryStop, const E* endEdge, const std::string& line, const double length) :
49  IntermodalEdge<E, L, N, V>(line + ":" + (id != "" ? id : endEdge->getID()), numericalID, endEdge, line, length), myEntryStop(entryStop) { }
50 
51  bool includeInRoute(bool /* allEdges */) const {
52  return true;
53  }
54 
55  bool prohibits(const IntermodalTrip<E, N, V>* const trip) const {
56  return (trip->modeSet & SVC_BUS) == 0;
57  }
58 
60  return myEntryStop;
61  }
62 
63  bool hasSchedule(const SUMOTime begin) const {
64  return mySchedules.find(begin) != mySchedules.end();
65  }
66 
67  void addSchedule(const std::string id, const SUMOTime begin, const int repetitionNumber, const SUMOTime period, const SUMOTime travelTime) {
68  // try to merge with existing vehicle or flow
69  bool found = false;
70  for (auto& it : mySchedules) {
71  Schedule& s = it.second;
72  if (travelTime == s.travelTime) {
73  if (repetitionNumber == -1 && s.repetitionNumber == 1) {
74  if (begin > s.begin) {
75  s.period = begin - s.begin;
76  found = true;
77  }
78  } else if (begin == s.begin + s.repetitionNumber * s.period) {
79  found = true;
80  }
81  if (found) {
82  s.repetitionNumber += MAX2(repetitionNumber, 1);
83  s.ids.push_back(id);
84  break;
85  }
86  }
87  }
88  if (!found) {
89  mySchedules.insert(std::make_pair(begin, Schedule(id, begin, MAX2(repetitionNumber, 1), MAX2<SUMOTime>(period, 1), travelTime)));
90  }
91  }
92 
93  double getTravelTime(const IntermodalTrip<E, N, V>* const /* trip */, double time) const {
94  SUMOTime minArrival = SUMOTime_MAX;
95  const SUMOTime step = TIME2STEPS(time);
96  for (typename std::multimap<SUMOTime, Schedule>::const_iterator it = mySchedules.begin(); it != mySchedules.end(); ++it) {
97  const Schedule& s = it->second;
98  if (it->first > minArrival) {
99  break;
100  }
101  const SUMOTime offset = MAX2<SUMOTime>(0, step - s.begin);
102  int running = (int)(offset / s.period);
103  if (offset % s.period != 0) {
104  running++;
105  }
106  if (running < s.repetitionNumber) {
107  const SUMOTime nextDepart = s.begin + running * s.period;
108  minArrival = MIN2(nextDepart + s.travelTime, minArrival);
109  //std::cout << " edge=" << myEntryStop->getID() << "->" << this->getID() << " beg=" << s.begin << " end=" << s.end
110  // << " atTime=" << time
111  // << " running=" << running << " nextDepart=" << nextDepart
112  // << " minASec=" << minArrivalSec << " travelTime=" << minArrivalSec - time << "\n";
113  }
114  }
115  if (minArrival != SUMOTime_MAX) {
116  return STEPS2TIME(minArrival - step);
117  } else {
118  // indicate failure
119  return std::numeric_limits<double>::max();
120  }
121  }
122 
123  double getIntended(const double time, std::string& intended) const {
125  SUMOTime minArrival = SUMOTime_MAX;
126  double bestDepartTime = std::numeric_limits<double>::max();
127  const SUMOTime step = TIME2STEPS(time);
128  for (typename std::multimap<SUMOTime, Schedule>::const_iterator it = mySchedules.begin(); it != mySchedules.end(); ++it) {
129  const Schedule& s = it->second;
130  if (it->first > minArrival) {
131  break;
132  }
133  const SUMOTime offset = MAX2<SUMOTime>(0, step - s.begin);
134  int running = (int)(offset / s.period);
135  if (offset % s.period != 0) {
136  running++;
137  }
138  if (running < s.repetitionNumber) {
139  const SUMOTime nextDepart = s.begin + running * s.period;
140  if (nextDepart + s.travelTime < minArrival) {
141  minArrival = nextDepart + s.travelTime;
142  bestDepartTime = STEPS2TIME(nextDepart);
143  // see naming scheme inMSInsertionControl::determineCandidates()
144  if (s.ids.size() == 1 || running >= (int)s.ids.size()) {
145  intended = s.repetitionNumber == 1 ? s.ids[0] : s.ids[0] + "." + toString(running);
146  } else {
147  intended = s.ids[running];
148  }
149  }
150  }
151  }
152  return bestDepartTime;
153  }
154 
155 private:
156  std::multimap<SUMOTime, Schedule> mySchedules;
158 
159 };
long long int SUMOTime
Definition: GUI.h:35
#define STEPS2TIME(x)
Definition: SUMOTime.h:55
#define SUMOTime_MAX
Definition: SUMOTime.h:34
#define TIME2STEPS(x)
Definition: SUMOTime.h:57
@ SVC_BUS
vehicle is a bus
T MIN2(T a, T b)
Definition: StdDefs.h:76
T MAX2(T a, T b)
Definition: StdDefs.h:82
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
the base edge type that is given to the internal router (SUMOAbstractRouter)
the "vehicle" type that is given to the internal router (SUMOAbstractRouter)
const SVCPermissions modeSet
const std::string & getID() const
Returns the id.
Definition: Named.h:74
the public transport edge type connecting the stop edges
bool hasSchedule(const SUMOTime begin) const
bool prohibits(const IntermodalTrip< E, N, V > *const trip) const
PublicTransportEdge(const std::string id, int numericalID, const IntermodalEdge< E, L, N, V > *entryStop, const E *endEdge, const std::string &line, const double length)
bool includeInRoute(bool) const
const IntermodalEdge< E, L, N, V > *const myEntryStop
const IntermodalEdge< E, L, N, V > * getEntryStop() const
double getIntended(const double time, std::string &intended) const
get intended vehicle id and departure time of next public transport ride
std::multimap< SUMOTime, Schedule > mySchedules
void addSchedule(const std::string id, const SUMOTime begin, const int repetitionNumber, const SUMOTime period, const SUMOTime travelTime)
double getTravelTime(const IntermodalTrip< E, N, V > *const, double time) const
Schedule(const std::string &_id, const SUMOTime _begin, const int _repetitionNumber, const SUMOTime _period, const SUMOTime _travelTime)
std::vector< std::string > ids