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-2020 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 // ===========================================================================
43 // method definitions
44 // ===========================================================================
46  RORouteDef* route, const SUMOVTypeParameter* type,
47  const RONet* net, MsgHandler* errorHandler)
48  : RORoutable(pars, type), myRoute(route) {
49  getParameter().stops.clear();
50  if (route != nullptr && route->getFirstRoute() != nullptr) {
51  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator s = route->getFirstRoute()->getStops().begin(); s != route->getFirstRoute()->getStops().end(); ++s) {
52  addStop(*s, net, errorHandler);
53  }
54  }
55  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator s = pars.stops.begin(); s != pars.stops.end(); ++s) {
56  addStop(*s, net, errorHandler);
57  }
58  if (pars.via.size() != 0) {
59  // via takes precedence over stop edges
60  // XXX check for inconsistencies #2275
61  myStopEdges.clear();
62  for (std::vector<std::string>::const_iterator it = pars.via.begin(); it != pars.via.end(); ++it) {
63  assert(net->getEdge(*it) != 0);
64  myStopEdges.push_back(net->getEdge(*it));
65  }
66  }
67 }
68 
69 
70 void
71 ROVehicle::addStop(const SUMOVehicleParameter::Stop& stopPar, const RONet* net, MsgHandler* errorHandler) {
72  const ROEdge* stopEdge = net->getEdge(stopPar.edge);
73  assert(stopEdge != 0); // was checked when parsing the stop
74  if (stopEdge->prohibits(this)) {
75  if (errorHandler != nullptr) {
76  errorHandler->inform("Stop edge '" + stopEdge->getID() + "' does not allow vehicle '" + getID() + "'.");
77  }
78  return;
79  }
80  // where to insert the stop
81  std::vector<SUMOVehicleParameter::Stop>::iterator iter = getParameter().stops.begin();
82  ConstROEdgeVector::iterator edgeIter = myStopEdges.begin();
83  if (stopPar.index == STOP_INDEX_END || stopPar.index >= static_cast<int>(getParameter().stops.size())) {
84  if (getParameter().stops.size() > 0) {
85  iter = getParameter().stops.end();
86  edgeIter = myStopEdges.end();
87  }
88  } else {
89  if (stopPar.index == STOP_INDEX_FIT) {
91  ConstROEdgeVector::const_iterator stopEdgeIt = std::find(edges.begin(), edges.end(), stopEdge);
92  if (stopEdgeIt == edges.end()) {
93  iter = getParameter().stops.end();
94  edgeIter = myStopEdges.end();
95  } else {
96  while (iter != getParameter().stops.end()) {
97  if (edgeIter > stopEdgeIt || (edgeIter == stopEdgeIt && iter->endPos >= stopPar.endPos)) {
98  break;
99  }
100  ++iter;
101  ++edgeIter;
102  }
103  }
104  } else {
105  iter += stopPar.index;
106  edgeIter += stopPar.index;
107  }
108  }
109  getParameter().stops.insert(iter, stopPar);
110  myStopEdges.insert(edgeIter, stopEdge);
111 }
112 
113 
115 
116 
117 const ROEdge*
119  return myRoute->getFirstRoute()->getFirst();
120 }
121 
122 
123 void
125  const bool removeLoops, MsgHandler* errorHandler) {
127  std::string noRouteMsg = "The vehicle '" + getID() + "' has no valid route.";
128  RORouteDef* const routeDef = getRouteDefinition();
129  // check if the route definition is valid
130  if (routeDef == nullptr) {
131  errorHandler->inform(noRouteMsg);
132  myRoutingSuccess = false;
133  return;
134  }
135  RORoute* current = routeDef->buildCurrentRoute(router, getDepartureTime(), *this);
136  if (current == nullptr || current->size() == 0) {
137  delete current;
138  if (current == nullptr || !routeDef->discardSilent()) {
139  errorHandler->inform(noRouteMsg);
140  }
141  myRoutingSuccess = false;
142  return;
143  }
144  // check whether we have to evaluate the route for not containing loops
145  if (removeLoops) {
150  current->recheckForLoops(getMandatoryEdges(requiredStart, requiredEnd));
151  // check whether the route is still valid
152  if (current->size() == 0) {
153  delete current;
154  errorHandler->inform(noRouteMsg + " (after removing loops)");
155  myRoutingSuccess = false;
156  return;
157  }
158  }
159  // add built route
160  routeDef->addAlternative(router, this, current, getDepartureTime());
161  myRoutingSuccess = true;
162 }
163 
164 
166 ROVehicle::getMandatoryEdges(const ROEdge* requiredStart, const ROEdge* requiredEnd) const {
167  ConstROEdgeVector mandatory;
168  if (requiredStart) {
169  mandatory.push_back(requiredStart);
170  }
171  for (const ROEdge* e : getStopEdges()) {
172  if (e->isInternal()) {
173  // the edges before and after the internal edge are mandatory
174  const ROEdge* before = e->getNormalBefore();
175  const ROEdge* after = e->getNormalAfter();
176  if (mandatory.size() == 0 || after != mandatory.back()) {
177  mandatory.push_back(before);
178  mandatory.push_back(after);
179  }
180  } else {
181  if (mandatory.size() == 0 || e != mandatory.back()) {
182  mandatory.push_back(e);
183  }
184  }
185  }
186  if (requiredEnd) {
187  if (mandatory.size() < 2 || mandatory.back() != requiredEnd) {
188  mandatory.push_back(requiredEnd);
189  }
190  }
191  return mandatory;
192 }
193 
194 
195 void
196 ROVehicle::saveAsXML(OutputDevice& os, OutputDevice* const typeos, bool asAlternatives, OptionsCont& options) const {
197  if (typeos != nullptr && getType() != nullptr && !getType()->saved) {
198  getType()->write(*typeos);
199  getType()->saved = true;
200  }
201  if (getType() != nullptr && !getType()->saved) {
202  getType()->write(os);
203  getType()->saved = asAlternatives;
204  }
205 
206  const bool writeTrip = options.exists("write-trips") && options.getBool("write-trips");
207  const bool writeGeoTrip = writeTrip && options.getBool("write-trips.geo");
208  const bool writeJunctions = writeTrip && options.getBool("write-trips.junctions");
209  // write the vehicle (new style, with included routes)
210  getParameter().write(os, options, writeTrip ? SUMO_TAG_TRIP : SUMO_TAG_VEHICLE);
211 
212  // save the route
213  if (writeTrip) {
215  const ROEdge* from = nullptr;
216  const ROEdge* to = nullptr;
217  if (edges.size() > 0) {
218  if (edges.front()->isTazConnector()) {
219  if (edges.size() > 1) {
220  from = edges[1];
221  if (from->isTazConnector() && writeJunctions && edges.front()->getSuccessors().size() > 0) {
222  // routing was skipped
223  from = edges.front()->getSuccessors(getVClass()).front();
224  }
225  }
226  } else {
227  from = edges[0];
228  }
229  if (edges.back()->isTazConnector()) {
230  if (edges.size() > 1) {
231  to = edges[edges.size() - 2];
232  if (to->isTazConnector() && writeJunctions && edges.back()->getPredecessors().size() > 0) {
233  // routing was skipped
234  to = edges.back()->getPredecessors().front();
235  }
236  }
237  } else {
238  to = edges[edges.size() - 1];
239  }
240  }
241  if (from != nullptr) {
242  if (writeGeoTrip) {
243  Position fromPos = from->getLanes()[0]->getShape().positionAtOffset2D(0);
244  if (GeoConvHelper::getFinal().usingGeoProjection()) {
247  os.writeAttr(SUMO_ATTR_FROMLONLAT, fromPos);
249  } else {
250  os.writeAttr(SUMO_ATTR_FROMXY, fromPos);
251  }
252  } else if (writeJunctions) {
254  } else {
255  os.writeAttr(SUMO_ATTR_FROM, from->getID());
256  }
257  }
258  if (to != nullptr) {
259  if (writeGeoTrip) {
260  Position toPos = to->getLanes()[0]->getShape().positionAtOffset2D(to->getLanes()[0]->getShape().length2D());
261  if (GeoConvHelper::getFinal().usingGeoProjection()) {
264  os.writeAttr(SUMO_ATTR_TOLONLAT, toPos);
266  } else {
267  os.writeAttr(SUMO_ATTR_TOXY, toPos);
268  }
269  } else if (writeJunctions) {
271  } else {
272  os.writeAttr(SUMO_ATTR_TO, to->getID());
273  }
274  }
275  if (getParameter().via.size() > 0) {
276  std::vector<std::string> viaOut;
277  SumoXMLAttr viaAttr = (writeGeoTrip
279  : (writeJunctions ? SUMO_ATTR_VIAJUNCTIONS : SUMO_ATTR_VIA));
280  for (const std::string& viaID : getParameter().via) {
281  const ROEdge* viaEdge = RONet::getInstance()->getEdge(viaID);
282  if (viaEdge->isTazConnector()) {
283  if (viaEdge->getPredecessors().size() == 0) {
284  continue;
285  }
286  // XXX used edge that was used in route
287  viaEdge = viaEdge->getPredecessors().front();
288  }
289  assert(viaEdge != nullptr);
290  if (writeGeoTrip) {
291  Position viaPos = viaEdge->getLanes()[0]->getShape().positionAtOffset2D(viaEdge->getLanes()[0]->getShape().length2D() / 2);
292  if (GeoConvHelper::getFinal().usingGeoProjection()) {
294  viaOut.push_back(toString(viaPos, gPrecisionGeo));
295  } else {
296  viaOut.push_back(toString(viaPos, gPrecision));
297  }
298  } else if (writeJunctions) {
299  viaOut.push_back(viaEdge->getToJunction()->getID());
300  } else {
301  viaOut.push_back(viaEdge->getID());
302  }
303  }
304  os.writeAttr(viaAttr, viaOut);
305  }
306  } else {
307  myRoute->writeXMLDefinition(os, this, asAlternatives, options.getBool("exit-times"));
308  }
309  for (std::vector<SUMOVehicleParameter::Stop>::const_iterator stop = getParameter().stops.begin(); stop != getParameter().stops.end(); ++stop) {
310  stop->write(os);
311  }
313  os.closeTag();
314 }
315 
316 
317 /****************************************************************************/
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_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:44
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:73
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:60
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:239
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
void setPrecision(int precision=gPrecision)
Sets the precison 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:36
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:265
const ROEdge * getNormalAfter() const
if this edge is an internal edge, return its first normal successor, otherwise the edge itself
Definition: ROEdge.cpp:276
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:504
const std::vector< ROLane * > & getLanes() const
Returns this edge's lanes.
Definition: ROEdge.h:516
const ROEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: ROEdge.cpp:361
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:508
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:55
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:105
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:179
Base class for a vehicle's route definition.
Definition: RORouteDef.h:53
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
OutputDevice & writeXMLDefinition(OutputDevice &dev, const ROVehicle *const veh, bool asAlternatives, bool withExitTimes) const
Saves the built route / route alternatives.
Definition: RORouteDef.cpp:363
void addAlternative(SUMOAbstractRouter< ROEdge, ROVehicle > &router, const ROVehicle *const, RORoute *current, SUMOTime begin)
Adds an alternative to the list of routes.
Definition: RORouteDef.cpp:270
bool discardSilent() const
whether this route shall be silently discarded
Definition: RORouteDef.h:142
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:181
int size() const
Returns the number of edges in this route.
Definition: RORoute.h:143
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
const ConstROEdgeVector & getStopEdges() const
Definition: ROVehicle.h:97
const ROEdge * getDepartEdge() const
Returns the first edge the vehicle takes.
Definition: ROVehicle.cpp:118
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:166
void saveAsXML(OutputDevice &os, OutputDevice *const typeos, bool asAlternatives, OptionsCont &options) const
Saves the complete vehicle description.
Definition: ROVehicle.cpp:196
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:45
virtual ~ROVehicle()
Destructor.
Definition: ROVehicle.cpp:114
void addStop(const SUMOVehicleParameter::Stop &stopPar, const RONet *net, MsgHandler *errorHandler)
Adds a stop to this vehicle.
Definition: ROVehicle.cpp:71
void computeRoute(const RORouterProvider &provider, const bool removeLoops, MsgHandler *errorHandler)
Definition: ROVehicle.cpp:124
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.
DepartLaneDefinition departLaneProcedure
Information how the vehicle shall choose the lane to depart from.
void write(OutputDevice &dev, const OptionsCont &oc, const SumoXMLTag tag=SUMO_TAG_VEHICLE, const std::string &typeID="") const
Writes the parameters as a beginning element.
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.