Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
MSRoute.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2002-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/****************************************************************************/
21// A vehicle route
22/****************************************************************************/
23#include <config.h>
24
25#include <cassert>
26#include <algorithm>
27#include <limits>
31#include "MSEdge.h"
32#include "MSLane.h"
33#include "MSRoute.h"
34
35
36// ===========================================================================
37// static member variables
38// ===========================================================================
41#ifdef HAVE_FOX
42FXMutex MSRoute::myDictMutex(true);
43#endif
44
45
46// ===========================================================================
47// member method definitions
48// ===========================================================================
49MSRoute::MSRoute(const std::string& id,
50 const ConstMSEdgeVector& edges,
51 const bool isPermanent, const RGBColor* const c,
52 const std::vector<SUMOVehicleParameter::Stop>& stops,
53 SUMOTime replacedTime,
54 int replacedIndex) :
55 Named(id), myEdges(edges), myAmPermanent(isPermanent),
56 myColor(c),
57 myPeriod(0),
58 myCosts(-1),
59 mySavings(0),
60 myReroute(false),
61 myStops(stops),
62 myReplacedTime(replacedTime),
63 myReplacedIndex(replacedIndex)
64{}
65
66
68 delete myColor;
69}
70
71
74 return myEdges.begin();
75}
76
77
79MSRoute::end() const {
80 return myEdges.end();
81}
82
83
84int
86 return (int)myEdges.size();
87}
88
89
90const MSEdge*
92 assert(myEdges.size() > 0);
93 return myEdges.back();
94}
95
96
97void
99#ifdef HAVE_FOX
100 FXMutexLock f(myDictMutex);
101#endif
102 if (!myAmPermanent) {
103 myDict.erase(getID());
104 }
105}
106
107
108bool
109MSRoute::dictionary(const std::string& id, ConstMSRoutePtr route) {
110#ifdef HAVE_FOX
111 FXMutexLock f(myDictMutex);
112#endif
113 if (myDict.find(id) == myDict.end() && myDistDict.find(id) == myDistDict.end()) {
114 myDict[id] = route;
115 return true;
116 }
117 return false;
118}
119
120
121bool
122MSRoute::dictionary(const std::string& id, RandomDistributor<ConstMSRoutePtr>* const routeDist, const bool permanent) {
123#ifdef HAVE_FOX
124 FXMutexLock f(myDictMutex);
125#endif
126 if (myDict.find(id) == myDict.end() && myDistDict.find(id) == myDistDict.end()) {
127 myDistDict[id] = std::make_pair(routeDist, permanent);
128 return true;
129 }
130 return false;
131}
132
133
135MSRoute::dictionary(const std::string& id, SumoRNG* rng) {
136#ifdef HAVE_FOX
137 FXMutexLock f(myDictMutex);
138#endif
139 RouteDict::iterator it = myDict.find(id);
140 if (it == myDict.end()) {
141 RouteDistDict::iterator it2 = myDistDict.find(id);
142 if (it2 == myDistDict.end() || it2->second.first->getOverallProb() == 0) {
143 return nullptr;
144 }
145 return it2->second.first->get(rng);
146 }
147 return it->second;
148}
149
150
151bool
152MSRoute::hasRoute(const std::string& id) {
153#ifdef HAVE_FOX
154 FXMutexLock f(myDictMutex);
155#endif
156 return myDict.find(id) != myDict.end();
157}
158
159
161MSRoute::distDictionary(const std::string& id) {
162#ifdef HAVE_FOX
163 FXMutexLock f(myDictMutex);
164#endif
165 RouteDistDict::iterator it2 = myDistDict.find(id);
166 if (it2 == myDistDict.end()) {
167 return nullptr;
168 }
169 return it2->second.first;
170}
171
172
173void
175#ifdef HAVE_FOX
176 FXMutexLock f(myDictMutex);
177#endif
178 for (RouteDistDict::iterator i = myDistDict.begin(); i != myDistDict.end(); ++i) {
179 delete i->second.first;
180 }
181 myDistDict.clear();
182 myDict.clear();
183}
184
185
186void
187MSRoute::checkDist(const std::string& id) {
188#ifdef HAVE_FOX
189 FXMutexLock f(myDictMutex);
190#endif
191 RouteDistDict::iterator it = myDistDict.find(id);
192 if (it != myDistDict.end() && !it->second.second) {
193 for (ConstMSRoutePtr rp : it->second.first->getVals()) {
194 const MSRoute& r = *rp;
195 r.checkRemoval();
196 }
197 delete it->second.first;
198 myDistDict.erase(it);
199 }
200}
201
202
203void
204MSRoute::insertIDs(std::vector<std::string>& into) {
205#ifdef HAVE_FOX
206 FXMutexLock f(myDictMutex);
207#endif
208 into.reserve(myDict.size() + myDistDict.size() + into.size());
209 for (RouteDict::const_iterator i = myDict.begin(); i != myDict.end(); ++i) {
210 into.push_back((*i).first);
211 }
212 for (RouteDistDict::const_iterator i = myDistDict.begin(); i != myDistDict.end(); ++i) {
213 into.push_back((*i).first);
214 }
215}
216
217
218int
219MSRoute::writeEdgeIDs(OutputDevice& os, int firstIndex, int lastIndex, bool withInternal, SUMOVehicleClass svc) const {
220 //std::cout << SIMTIME << " writeEdgeIDs " << getID() << " first=" << firstIndex << " lastIndex=" << lastIndex << " edges=" << toString(myEdges) << "\n";
221 if (lastIndex < 0) {
222 lastIndex = (int)myEdges.size();
223 }
224 int internal = 0;
225 for (int i = firstIndex; i < lastIndex; i++) {
226 os << myEdges[i]->getID() << ' ';
227 if (withInternal && i + 1 < lastIndex) {
228 const MSEdge* next = myEdges[i + 1];
229 const MSEdge* edge = myEdges[i]->getInternalFollowingEdge(next, svc);
230 // Take into account non-internal lengths until next non-internal edge
231 while (edge != nullptr && edge->isInternal()) {
232 os << edge->getID() << ' ';
233 internal++;
234 edge = edge->getInternalFollowingEdge(next, svc);
235 }
236 }
237 }
238 return internal + lastIndex - firstIndex;
239}
240
241
242bool
243MSRoute::containsAnyOf(const MSEdgeVector& edgelist) const {
244 MSEdgeVector::const_iterator i = edgelist.begin();
245 for (; i != edgelist.end(); ++i) {
246 if (contains(*i)) {
247 return true;
248 }
249 }
250 return false;
251}
252
253
254const MSEdge*
255MSRoute::operator[](int index) const {
256 return myEdges[index];
257}
258
259
260void
262#ifdef HAVE_FOX
263 FXMutexLock f(myDictMutex);
264#endif
265 for (RouteDict::iterator it = myDict.begin(); it != myDict.end(); ++it) {
266 ConstMSRoutePtr r = (*it).second;
268 out.writeAttr(SUMO_ATTR_ID, r->getID());
269 out.writeAttr(SUMO_ATTR_STATE, r->myAmPermanent);
270 out.writeAttr(SUMO_ATTR_EDGES, r->myEdges);
271 if (r->myColor != nullptr) {
272 out.writeAttr(SUMO_ATTR_COLOR, *r->myColor);
273 }
274 for (auto stop : r->getStops()) {
275 stop.write(out);
276 }
277 out.closeTag();
278 }
279 for (const auto& item : myDistDict) {
280 if (item.second.first->getVals().size() > 0) {
282 out.writeAttr(SUMO_ATTR_STATE, item.second.second);
283 std::ostringstream oss;
284 bool space = false;
285 for (const auto& route : item.second.first->getVals()) {
286 if (space) {
287 oss << " ";
288 }
289 oss << route->getID();
290 space = true;
291 }
292 out.writeAttr(SUMO_ATTR_ROUTES, oss.str());
293 out.writeAttr(SUMO_ATTR_PROBS, item.second.first->getProbs());
294 out.closeTag();
295 }
296 }
297}
298
299
300void
302#ifdef HAVE_FOX
303 FXMutexLock f(myDictMutex);
304#endif
305 myDistDict.clear();
306 myDict.clear();
307}
308
309
310double
311MSRoute::getDistanceBetween(double fromPos, double toPos,
312 const MSLane* fromLane, const MSLane* toLane, int routePosition) const {
313 // std::cout << SIMTIME << " getDistanceBetween from=" << fromEdge->getID() << " to=" << toEdge->getID() << " fromPos=" << fromPos << " toPos=" << toPos << "\n";
314 assert(fromPos >= 0. && fromPos <= fromLane->getLength());
315 assert(toPos >= 0. && toPos <= toLane->getLength());
316 assert(routePosition >= 0 && routePosition < (int)myEdges.size());
317 assert(routePosition == 0 || !myEdges.front()->isInternal());
318 const MSEdge* fromEdge = &fromLane->getEdge();
319 const MSEdge* toEdge = &toLane->getEdge();
320 if (fromEdge == toEdge && fromPos <= toPos) {
321 return toPos - fromPos;
322 }
323 // TODO If fromEdge and toEdge are identical or both are internal and directly connected,
324 // the code does not check whether they are in any relation to the route.
325 if (fromEdge->isInternal()) {
326 double minDist = std::numeric_limits<double>::max();
327 for (const auto& via : fromEdge->getViaSuccessors()) {
328 const MSEdge* const succ = via.second == nullptr ? via.first : via.second;
329 assert(succ != nullptr);
330 // std::cout << " recurse fromSucc=" << succ->getID() << "\n";
331 const double d = getDistanceBetween(0., toPos, succ->getLanes()[0], toLane, routePosition);
332 if (d != std::numeric_limits<double>::max() && fromLane->getLength() - fromPos + d < minDist) {
333 minDist = fromLane->getLength() - fromPos + d;
334 }
335 }
336 return minDist;
337 }
338 if (toEdge->isInternal()) {
339 const MSEdge* const pred = toEdge->getPredecessors().front();
340 assert(pred != nullptr);
341 // std::cout << " recurse toPred=" << pred->getID() << "\n";
342 const double d = getDistanceBetween(fromPos, pred->getLength(), fromLane, pred->getLanes()[0], routePosition);
343 return d == std::numeric_limits<double>::max() ? d : toPos + d;
344 }
345 ConstMSEdgeVector::const_iterator fromIt = std::find(myEdges.begin() + routePosition, myEdges.end(), fromEdge);
346 if (fromIt == myEdges.end()) {
347 // start not contained in route
348 return std::numeric_limits<double>::max();
349 }
350 ConstMSEdgeVector::const_iterator toIt = std::find(fromIt + 1, myEdges.end(), toEdge);
351 if (toIt == myEdges.end()) {
352 // destination not contained in route
353 return std::numeric_limits<double>::max();
354 }
355 return getDistanceBetween(fromPos, toPos, fromIt, toIt, true);
356}
357
358
359double
360MSRoute::getDistanceBetween(double fromPos, double toPos,
361 const MSRouteIterator& fromEdge, const MSRouteIterator& toEdge, bool includeInternal) const {
362 bool isFirstIteration = true;
363 double distance = -fromPos;
364 MSRouteIterator it = fromEdge;
365 if (fromEdge == toEdge) {
366 // destination position is on start edge
367 if (fromPos <= toPos) {
368 return toPos - fromPos;
369 } else {
370 // we cannot go backwards. Something is wrong here
371 return std::numeric_limits<double>::max();
372 }
373 } else if (fromEdge > toEdge) {
374 // we don't visit the edge again
375 return std::numeric_limits<double>::max();
376 }
377 for (; it != end(); ++it) {
378 if (it == toEdge && !isFirstIteration) {
379 distance += toPos;
380 break;
381 } else {
382 distance += (*it)->getLength();
383 if (includeInternal && (it + 1) != end()) {
384 // XXX the length may be wrong if there are parallel internal edges for different vClasses
385 distance += (*it)->getInternalFollowingLengthTo(*(it + 1), SVC_IGNORING);
386 }
387 }
388 isFirstIteration = false;
389 }
390 return distance;
391}
392
393
394const RGBColor&
396 if (myColor == nullptr) {
398 }
399 return *myColor;
400}
401
402
403const std::vector<SUMOVehicleParameter::Stop>&
405 return myStops;
406}
407
408
409/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
std::vector< const MSEdge * > ConstMSEdgeVector
Definition MSRoute.h:55
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition MSRoute.h:57
std::vector< MSEdge * > MSEdgeVector
Definition MSRoute.h:56
std::shared_ptr< const MSRoute > ConstMSRoutePtr
Definition MSRoute.h:58
std::shared_ptr< const MSRoute > ConstMSRoutePtr
Definition Route.h:32
SUMOVehicleClass
Definition of vehicle classes to differ between different lane usage and authority types.
@ SVC_IGNORING
vehicles ignoring classes
@ SUMO_TAG_ROUTE_DISTRIBUTION
distribution of a route
@ SUMO_TAG_ROUTE
begin/end of the description of a route
@ SUMO_ATTR_PROBS
@ SUMO_ATTR_EDGES
the edges of a route
@ SUMO_ATTR_ROUTES
@ SUMO_ATTR_COLOR
A color information.
@ SUMO_ATTR_ID
@ SUMO_ATTR_STATE
The state of a link.
A road/street connecting two junctions.
Definition MSEdge.h:77
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition MSEdge.h:168
const MSConstEdgePairVector & getViaSuccessors(SUMOVehicleClass vClass=SVC_IGNORING, bool ignoreTransientPermissions=false) const
Returns the following edges with internal vias, restricted by vClass.
Definition MSEdge.cpp:1288
double getLength() const
return the length of the edge
Definition MSEdge.h:685
bool isInternal() const
return whether this edge is an internal edge
Definition MSEdge.h:268
const MSEdgeVector & getPredecessors() const
Definition MSEdge.h:409
const MSEdge * getInternalFollowingEdge(const MSEdge *followerAfterInternal, SUMOVehicleClass vClass) const
Definition MSEdge.cpp:900
Representation of a lane in the micro simulation.
Definition MSLane.h:84
double getLength() const
Returns the lane's length.
Definition MSLane.h:606
MSEdge & getEdge() const
Returns the lane's edge.
Definition MSLane.h:764
static void dict_clearState()
Decrement all route references before quick-loading state.
Definition MSRoute.cpp:301
int size() const
Returns the number of edges to pass.
Definition MSRoute.cpp:85
static RouteDistDict myDistDict
The dictionary container.
Definition MSRoute.h:324
static void dict_saveState(OutputDevice &out)
Saves all known routes into the given stream.
Definition MSRoute.cpp:261
const RGBColor *const myColor
The color.
Definition MSRoute.h:290
static RouteDict myDict
The dictionary container.
Definition MSRoute.h:318
std::vector< SUMOVehicleParameter::Stop > myStops
List of the stops on the parsed route.
Definition MSRoute.h:305
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the stops.
Definition MSRoute.cpp:404
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition MSRoute.cpp:79
int writeEdgeIDs(OutputDevice &os, int firstIndex=0, int lastIndex=-1, bool withInternal=false, SUMOVehicleClass svc=SVC_IGNORING) const
Output the edge ids up to but not including the id of the given edge.
Definition MSRoute.cpp:219
static bool hasRoute(const std::string &id)
returns whether a route with the given id exists
Definition MSRoute.cpp:152
std::map< std::string, ConstMSRoutePtr > RouteDict
Definition of the dictionary container.
Definition MSRoute.h:315
virtual ~MSRoute()
Destructor.
Definition MSRoute.cpp:67
void checkRemoval() const
removes the route from the internal dict if it is not marked as permanent
Definition MSRoute.cpp:98
const MSEdge * operator[](int index) const
Definition MSRoute.cpp:255
bool contains(const MSEdge *const edge) const
Definition MSRoute.h:104
const MSEdge * getLastEdge() const
returns the destination edge
Definition MSRoute.cpp:91
ConstMSEdgeVector myEdges
The list of edges to pass.
Definition MSRoute.h:284
static void insertIDs(std::vector< std::string > &into)
Definition MSRoute.cpp:204
bool containsAnyOf(const MSEdgeVector &edgelist) const
Definition MSRoute.cpp:243
std::map< std::string, std::pair< RandomDistributor< ConstMSRoutePtr > *, bool > > RouteDistDict
Definition of the dictionary container.
Definition MSRoute.h:321
static bool dictionary(const std::string &id, ConstMSRoutePtr route)
Adds a route to the dictionary.
Definition MSRoute.cpp:109
const RGBColor & getColor() const
Returns the color.
Definition MSRoute.cpp:395
static RandomDistributor< ConstMSRoutePtr > * distDictionary(const std::string &id)
Returns the named route distribution.
Definition MSRoute.cpp:161
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition MSRoute.cpp:73
double getDistanceBetween(double fromPos, double toPos, const MSLane *fromLane, const MSLane *toLane, int routePosition=0) const
Compute the distance between 2 given edges on this route, optionally including the length of internal...
Definition MSRoute.cpp:311
const bool myAmPermanent
whether the route may be deleted after the last vehicle abandoned it
Definition MSRoute.h:287
static void checkDist(const std::string &id)
Checks the distribution whether it is permanent and deletes it if not.
Definition MSRoute.cpp:187
MSRoute(const std::string &id, const ConstMSEdgeVector &edges, const bool isPermanent, const RGBColor *const c, const std::vector< SUMOVehicleParameter::Stop > &stops, SUMOTime replacedTime=-1, int replacedIndex=0)
Constructor.
Definition MSRoute.cpp:49
static void clear()
Clears the dictionary (delete all known routes, too)
Definition MSRoute.cpp:174
Base class for objects which have an id.
Definition Named.h:54
const std::string & getID() const
Returns the id.
Definition Named.h:74
Static storage of an output device and its base (abstract) implementation.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
static const RGBColor DEFAULT_COLOR
The default color (for vehicle types and vehicles)
Definition RGBColor.h:199
Represents a generic random distribution.