Eclipse SUMO - Simulation of Urban MObility
ROVehicle.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2002-2022 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 as used by router
22 /****************************************************************************/
23 #include <config.h>
24 
25 #include <string>
26 #include <iostream>
28 #include <utils/common/ToString.h>
34 #include "RORouteDef.h"
35 #include "RORoute.h"
36 #include "ROHelper.h"
37 #include "RONet.h"
38 #include "ROLane.h"
39 #include "ROVehicle.h"
40 
41 // ===========================================================================
42 // static members
43 // ===========================================================================
44 std::map<ConstROEdgeVector, std::string> ROVehicle::mySavedRoutes;
45 
46 // ===========================================================================
47 // method definitions
48 // ===========================================================================
50  RORouteDef* route, const SUMOVTypeParameter* type,
51  const RONet* net, MsgHandler* errorHandler)
52  : RORoutable(pars, type), myRoute(route) {
53  getParameter().stops.clear();
54  if (route != nullptr && route->getFirstRoute() != nullptr) {
55  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator s = route->getFirstRoute()->getStops().begin(); s != route->getFirstRoute()->getStops().end(); ++s) {
56  addStop(*s, net, errorHandler);
57  }
58  }
59  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator s = pars.stops.begin(); s != pars.stops.end(); ++s) {
60  addStop(*s, net, errorHandler);
61  }
62  if (pars.via.size() != 0) {
63  // via takes precedence over stop edges
64  // XXX check for inconsistencies #2275
65  myStopEdges.clear();
66  for (std::vector<std::string>::const_iterator it = pars.via.begin(); it != pars.via.end(); ++it) {
67  assert(net->getEdge(*it) != 0);
68  myStopEdges.push_back(net->getEdge(*it));
69  }
70  }
71 }
72 
73 
74 void
75 ROVehicle::addStop(const SUMOVehicleParameter::Stop& stopPar, const RONet* net, MsgHandler* errorHandler) {
76  const ROEdge* stopEdge = net->getEdge(stopPar.edge);
77  assert(stopEdge != 0); // was checked when parsing the stop
78  if (stopEdge->prohibits(this)) {
79  if (errorHandler != nullptr) {
80  errorHandler->inform("Stop edge '" + stopEdge->getID() + "' does not allow vehicle '" + getID() + "'.");
81  }
82  return;
83  }
84  // where to insert the stop
85  std::vector<SUMOVehicleParameter::Stop>::iterator iter = getParameter().stops.begin();
86  ConstROEdgeVector::iterator edgeIter = myStopEdges.begin();
87  if (stopPar.index == STOP_INDEX_END || stopPar.index >= static_cast<int>(getParameter().stops.size())) {
88  if (getParameter().stops.size() > 0) {
89  iter = getParameter().stops.end();
90  edgeIter = myStopEdges.end();
91  }
92  } else {
93  if (stopPar.index == STOP_INDEX_FIT) {
95  ConstROEdgeVector::const_iterator stopEdgeIt = std::find(edges.begin(), edges.end(), stopEdge);
96  if (stopEdgeIt == edges.end()) {
97  iter = getParameter().stops.end();
98  edgeIter = myStopEdges.end();
99  } else {
100  while (iter != getParameter().stops.end()) {
101  if (edgeIter > stopEdgeIt || (edgeIter == stopEdgeIt && iter->endPos >= stopPar.endPos)) {
102  break;
103  }
104  ++iter;
105  ++edgeIter;
106  }
107  }
108  } else {
109  iter += stopPar.index;
110  edgeIter += stopPar.index;
111  }
112  }
113  getParameter().stops.insert(iter, stopPar);
114  myStopEdges.insert(edgeIter, stopEdge);
115 }
116 
117 
119 
120 
121 const ROEdge*
123  return myRoute->getFirstRoute()->getFirst();
124 }
125 
126 
127 void
129  const bool removeLoops, MsgHandler* errorHandler) {
131  std::string noRouteMsg = "The vehicle '" + getID() + "' has no valid route.";
132  RORouteDef* const routeDef = getRouteDefinition();
133  // check if the route definition is valid
134  if (routeDef == nullptr) {
135  errorHandler->inform(noRouteMsg);
136  myRoutingSuccess = false;
137  return;
138  }
139  RORoute* current = routeDef->buildCurrentRoute(router, getDepartureTime(), *this);
140  if (current == nullptr || current->size() == 0) {
141  delete current;
142  if (current == nullptr || !routeDef->discardSilent()) {
143  errorHandler->inform(noRouteMsg);
144  }
145  myRoutingSuccess = false;
146  return;
147  }
148  // check whether we have to evaluate the route for not containing loops
149  if (removeLoops) {
154  current->recheckForLoops(getMandatoryEdges(requiredStart, requiredEnd));
155  // check whether the route is still valid
156  if (current->size() == 0) {
157  delete current;
158  errorHandler->inform(noRouteMsg + " (after removing loops)");
159  myRoutingSuccess = false;
160  return;
161  }
162  }
163  // add built route
164  routeDef->addAlternative(router, this, current, getDepartureTime());
165  myRoutingSuccess = true;
166 }
167 
168 
170 ROVehicle::getMandatoryEdges(const ROEdge* requiredStart, const ROEdge* requiredEnd) const {
171  ConstROEdgeVector mandatory;
172  if (requiredStart) {
173  mandatory.push_back(requiredStart);
174  }
175  for (const ROEdge* e : getStopEdges()) {
176  if (e->isInternal()) {
177  // the edges before and after the internal edge are mandatory
178  const ROEdge* before = e->getNormalBefore();
179  const ROEdge* after = e->getNormalAfter();
180  if (mandatory.size() == 0 || after != mandatory.back()) {
181  mandatory.push_back(before);
182  mandatory.push_back(after);
183  }
184  } else {
185  if (mandatory.size() == 0 || e != mandatory.back()) {
186  mandatory.push_back(e);
187  }
188  }
189  }
190  if (requiredEnd) {
191  if (mandatory.size() < 2 || mandatory.back() != requiredEnd) {
192  mandatory.push_back(requiredEnd);
193  }
194  }
195  return mandatory;
196 }
197 
198 
199 void
200 ROVehicle::saveAsXML(OutputDevice& os, OutputDevice* const typeos, bool asAlternatives, OptionsCont& options) const {
201  if (typeos != nullptr && getType() != nullptr && !getType()->saved) {
202  getType()->write(*typeos);
203  getType()->saved = true;
204  }
205  if (getType() != nullptr && !getType()->saved) {
206  getType()->write(os);
207  getType()->saved = asAlternatives;
208  }
209 
210  const bool writeTrip = options.exists("write-trips") && options.getBool("write-trips");
211  const bool writeGeoTrip = writeTrip && options.getBool("write-trips.geo");
212  const bool writeJunctions = writeTrip && options.getBool("write-trips.junctions");
213  const bool writeNamedRoute = !asAlternatives && options.getBool("named-routes");
214  const bool writeCosts = options.exists("write-costs") && options.getBool("write-costs");
215  const bool writeExit = options.exists("exit-times") && options.getBool("exit-times");
216  const bool writeLength = options.exists("route-length") && options.getBool("route-length");
217 
218  std::string routeID;
219  if (writeNamedRoute) {
221  auto it = mySavedRoutes.find(edges);
222  if (it == mySavedRoutes.end()) {
223  routeID = "r" + toString(mySavedRoutes.size());
224  myRoute->getUsedRoute()->writeXMLDefinition(os, this, writeCosts, false, writeExit,
225  writeLength, routeID);
226  mySavedRoutes[edges] = routeID;
227  } else {
228  routeID = it->second;
229  }
230  }
231  // write the vehicle (new style, with included routes)
232  getParameter().write(os, options, writeTrip ? SUMO_TAG_TRIP : SUMO_TAG_VEHICLE);
233 
234  // save the route
235  if (writeTrip) {
237  const ROEdge* from = nullptr;
238  const ROEdge* to = nullptr;
239  if (edges.size() > 0) {
240  if (edges.front()->isTazConnector()) {
241  if (edges.size() > 1) {
242  from = edges[1];
243  if (from->isTazConnector() && writeJunctions && edges.front()->getSuccessors().size() > 0) {
244  // routing was skipped
245  from = edges.front()->getSuccessors(getVClass()).front();
246  }
247  }
248  } else {
249  from = edges[0];
250  }
251  if (edges.back()->isTazConnector()) {
252  if (edges.size() > 1) {
253  to = edges[edges.size() - 2];
254  if (to->isTazConnector() && writeJunctions && edges.back()->getPredecessors().size() > 0) {
255  // routing was skipped
256  to = edges.back()->getPredecessors().front();
257  }
258  }
259  } else {
260  to = edges[edges.size() - 1];
261  }
262  }
263  if (from != nullptr) {
264  if (writeGeoTrip) {
265  Position fromPos = from->getLanes()[0]->getShape().positionAtOffset2D(0);
266  if (GeoConvHelper::getFinal().usingGeoProjection()) {
269  os.writeAttr(SUMO_ATTR_FROMLONLAT, fromPos);
271  } else {
272  os.writeAttr(SUMO_ATTR_FROMXY, fromPos);
273  }
274  } else if (writeJunctions) {
276  } else {
277  os.writeAttr(SUMO_ATTR_FROM, from->getID());
278  }
279  }
280  if (to != nullptr) {
281  if (writeGeoTrip) {
282  Position toPos = to->getLanes()[0]->getShape().positionAtOffset2D(to->getLanes()[0]->getShape().length2D());
283  if (GeoConvHelper::getFinal().usingGeoProjection()) {
286  os.writeAttr(SUMO_ATTR_TOLONLAT, toPos);
288  } else {
289  os.writeAttr(SUMO_ATTR_TOXY, toPos);
290  }
291  } else if (writeJunctions) {
293  } else {
294  os.writeAttr(SUMO_ATTR_TO, to->getID());
295  }
296  }
297  if (getParameter().via.size() > 0) {
298  std::vector<std::string> viaOut;
299  SumoXMLAttr viaAttr = (writeGeoTrip
301  : (writeJunctions ? SUMO_ATTR_VIAJUNCTIONS : SUMO_ATTR_VIA));
302  for (const std::string& viaID : getParameter().via) {
303  const ROEdge* viaEdge = RONet::getInstance()->getEdge(viaID);
304  if (viaEdge->isTazConnector()) {
305  if (viaEdge->getPredecessors().size() == 0) {
306  continue;
307  }
308  // XXX used edge that was used in route
309  viaEdge = viaEdge->getPredecessors().front();
310  }
311  assert(viaEdge != nullptr);
312  if (writeGeoTrip) {
313  Position viaPos = viaEdge->getLanes()[0]->getShape().positionAtOffset2D(viaEdge->getLanes()[0]->getShape().length2D() / 2);
314  if (GeoConvHelper::getFinal().usingGeoProjection()) {
316  viaOut.push_back(toString(viaPos, gPrecisionGeo));
317  } else {
318  viaOut.push_back(toString(viaPos, gPrecision));
319  }
320  } else if (writeJunctions) {
321  viaOut.push_back(viaEdge->getToJunction()->getID());
322  } else {
323  viaOut.push_back(viaEdge->getID());
324  }
325  }
326  os.writeAttr(viaAttr, viaOut);
327  }
328  } else if (writeNamedRoute) {
329  os.writeAttr(SUMO_ATTR_ROUTE, routeID);
330  } else {
331  myRoute->writeXMLDefinition(os, this, asAlternatives, writeExit, writeCosts, writeLength);
332  }
333  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator stop = getParameter().stops.begin(); stop != getParameter().stops.end(); ++stop) {
334  stop->write(os);
335  }
337  os.closeTag();
338 }
339 
340 
341 /****************************************************************************/
std::vector< const ROEdge * > ConstROEdgeVector
Definition: ROEdge.h:54
const int STOP_INDEX_END
@ GIVEN
The lane is given.
@ GIVEN
The position is given.
@ GIVEN
The arrival lane is given.
const int STOP_INDEX_FIT
@ GIVEN
The arrival position is given.
@ SUMO_TAG_VEHICLE
description of a vehicle
@ SUMO_TAG_TRIP
a single trip definition (used by router)
SumoXMLAttr
Numbers representing SUMO-XML - attributes.
@ SUMO_ATTR_VIALONLAT
@ SUMO_ATTR_VIA
@ SUMO_ATTR_VIAXY
@ SUMO_ATTR_FROMJUNCTION
@ SUMO_ATTR_TOLONLAT
@ SUMO_ATTR_TO
@ SUMO_ATTR_FROM
@ SUMO_ATTR_VIAJUNCTIONS
@ SUMO_ATTR_FROMXY
@ SUMO_ATTR_TOXY
@ SUMO_ATTR_ROUTE
@ SUMO_ATTR_FROMLONLAT
@ SUMO_ATTR_TOJUNCTION
int gPrecision
the precision for floating point outputs
Definition: StdDefs.cpp:25
int gPrecisionGeo
Definition: StdDefs.cpp:26
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
void cartesian2geo(Position &cartesian) const
Converts the given cartesian (shifted) position to its geo (lat/long) representation.
static const GeoConvHelper & getFinal()
the coordinate transformation for writing the location element and for tracking the original coordina...
bool usingGeoProjection() const
Returns whether a transformation from geo to metric coordinates will be performed.
virtual void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:117
const std::string & getID() const
Returns the id.
Definition: Named.h:74
A storage for options typed value containers)
Definition: OptionsCont.h:89
bool exists(const std::string &name) const
Returns the information whether the named option is known.
bool getBool(const std::string &name) const
Returns the boolean-value of the named option (only for Option_Bool)
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:248
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
void setPrecision(int precision=gPrecision)
Sets the precision or resets it to default.
void writeParams(OutputDevice &device) const
write Params in the given outputdevice
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:37
A basic edge for routing applications.
Definition: ROEdge.h:70
const ROEdge * getNormalBefore() const
if this edge is an internal edge, return its first normal predecessor, otherwise the edge itself
Definition: ROEdge.cpp:267
const ROEdge * getNormalAfter() const
if this edge is an internal edge, return its first normal successor, otherwise the edge itself
Definition: ROEdge.cpp:279
bool isTazConnector() const
Definition: ROEdge.h:159
bool prohibits(const ROVehicle *const vehicle) const
Returns whether this edge prohibits the given vehicle to pass it.
Definition: ROEdge.h:269
const RONode * getFromJunction() const
Definition: ROEdge.h:508
const std::vector< ROLane * > & getLanes() const
Returns this edge's lanes.
Definition: ROEdge.h:520
const ROEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: ROEdge.cpp:364
const ROEdgeVector & getPredecessors() const
Returns the edge at the given position from the list of incoming edges.
Definition: ROEdge.h:361
const RONode * getToJunction() const
Definition: ROEdge.h:512
The router's network representation.
Definition: RONet.h:62
static RONet * getInstance()
Returns the pointer to the unique instance of RONet (singleton).
Definition: RONet.cpp:56
ROEdge * getEdge(const std::string &name) const
Retrieves an edge from the network.
Definition: RONet.h:157
A routable thing such as a vehicle or person.
Definition: RORoutable.h:52
const SUMOVehicleParameter & getParameter() const
Returns the definition of the vehicle / person parameter.
Definition: RORoutable.h:71
const std::string & getID() const
Returns the id of the routable.
Definition: RORoutable.h:91
SUMOVehicleClass getVClass() const
Definition: RORoutable.h:109
const SUMOVTypeParameter * getType() const
Returns the type of the routable.
Definition: RORoutable.h:82
bool myRoutingSuccess
Whether the last routing was successful.
Definition: RORoutable.h:185
Base class for a vehicle's route definition.
Definition: RORouteDef.h:53
OutputDevice & writeXMLDefinition(OutputDevice &dev, const ROVehicle *const veh, bool asAlternatives, bool withExitTimes, bool withCost, bool withLength) const
Saves the built route / route alternatives.
Definition: RORouteDef.cpp:383
RORoute * buildCurrentRoute(SUMOAbstractRouter< ROEdge, ROVehicle > &router, SUMOTime begin, const ROVehicle &veh) const
Triggers building of the complete route (via preComputeCurrentRoute) or returns precomputed route.
Definition: RORouteDef.cpp:84
const RORoute * getFirstRoute() const
Definition: RORouteDef.h:98
void addAlternative(SUMOAbstractRouter< ROEdge, ROVehicle > &router, const ROVehicle *const, RORoute *current, SUMOTime begin)
Adds an alternative to the list of routes.
Definition: RORouteDef.cpp:273
const RORoute * getUsedRoute() const
Definition: RORouteDef.h:105
bool discardSilent() const
whether this route shall be silently discarded
Definition: RORouteDef.h:137
A complete router's route.
Definition: RORoute.h:52
const ROEdge * getFirst() const
Returns the first edge in the route.
Definition: RORoute.h:91
const std::vector< SUMOVehicleParameter::Stop > & getStops() const
Returns the list of stops this route contains.
Definition: RORoute.h:183
int size() const
Returns the number of edges in this route.
Definition: RORoute.h:143
ConstROEdgeVector getNormalEdges() const
return edges that shall be written in the route definition
Definition: RORoute.cpp:87
void recheckForLoops(const ConstROEdgeVector &mandatory)
Checks whether this route contains loops and removes such.
Definition: RORoute.cpp:76
const ConstROEdgeVector & getEdgeVector() const
Returns the list of edges this route consists of.
Definition: RORoute.h:152
OutputDevice & writeXMLDefinition(OutputDevice &dev, const ROVehicle *const veh, const bool withCosts, const bool withProb, const bool withExitTimes, const bool withLength, const std::string &id="") const
Definition: RORoute.cpp:99
const ConstROEdgeVector & getStopEdges() const
Definition: ROVehicle.h:97
static std::map< ConstROEdgeVector, std::string > mySavedRoutes
map of all routes that were already saved with a name
Definition: ROVehicle.h:156
const ROEdge * getDepartEdge() const
Returns the first edge the vehicle takes.
Definition: ROVehicle.cpp:122
RORouteDef * getRouteDefinition() const
Returns the definition of the route the vehicle takes.
Definition: ROVehicle.h:73
SUMOTime getDepartureTime() const
Returns the time the vehicle starts at, 0 for triggered vehicles.
Definition: ROVehicle.h:92
ConstROEdgeVector getMandatoryEdges(const ROEdge *requiredStart, const ROEdge *requiredEnd) const
compute mandatory edges
Definition: ROVehicle.cpp:170
void saveAsXML(OutputDevice &os, OutputDevice *const typeos, bool asAlternatives, OptionsCont &options) const
Saves the complete vehicle description.
Definition: ROVehicle.cpp:200
ConstROEdgeVector myStopEdges
The edges where the vehicle stops.
Definition: ROVehicle.h:153
ROVehicle(const SUMOVehicleParameter &pars, RORouteDef *route, const SUMOVTypeParameter *type, const RONet *net, MsgHandler *errorHandler=0)
Constructor.
Definition: ROVehicle.cpp:49
virtual ~ROVehicle()
Destructor.
Definition: ROVehicle.cpp:118
void addStop(const SUMOVehicleParameter::Stop &stopPar, const RONet *net, MsgHandler *errorHandler)
Adds a stop to this vehicle.
Definition: ROVehicle.cpp:75
void computeRoute(const RORouterProvider &provider, const bool removeLoops, MsgHandler *errorHandler)
Definition: ROVehicle.cpp:128
RORouteDef *const myRoute
The route the vehicle takes.
Definition: ROVehicle.h:150
SUMOAbstractRouter< E, V > & getVehicleRouter(SUMOVehicleClass svc) const
Structure representing possible vehicle parameter.
void write(OutputDevice &dev) const
Writes the vtype.
bool saved
Information whether this type was already saved (needed by routers)
Definition of vehicle stop (position and duration)
std::string edge
The edge to stop at (used only in NETEDIT)
int index
at which position in the stops list
double endPos
The stopping position end.
Structure representing possible vehicle parameter.
std::vector< std::string > via
List of the via-edges the vehicle must visit.
ArrivalLaneDefinition arrivalLaneProcedure
Information how the vehicle shall choose the lane to arrive on.
void write(OutputDevice &dev, const OptionsCont &oc, const SumoXMLTag altTag=SUMO_TAG_VEHICLE, const std::string &typeID="") const
Writes the parameters as a beginning element.
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
std::vector< Stop > stops
List of the stops the vehicle will make, TraCI may add entries here.
ArrivalPosDefinition arrivalPosProcedure
Information how the vehicle shall choose the arrival position.
DepartPosDefinition departPosProcedure
Information how the vehicle shall choose the departure position.