SUMO - Simulation of Urban MObility
MEVehicle.cpp
Go to the documentation of this file.
1 /****************************************************************************/
7 // A vehicle from the mesoscopic point of view
8 /****************************************************************************/
9 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
10 // Copyright (C) 2001-2017 DLR (http://www.dlr.de/) and contributors
11 /****************************************************************************/
12 //
13 // This file is part of SUMO.
14 // SUMO is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 /****************************************************************************/
20 
21 
22 // ===========================================================================
23 // included modules
24 // ===========================================================================
25 #ifdef _MSC_VER
26 #include <windows_config.h>
27 #else
28 #include <config.h>
29 #endif
30 
31 #include <iostream>
32 #include <cassert>
33 #include <utils/common/StdDefs.h>
39 #include <microsim/MSGlobals.h>
40 #include <microsim/MSEdge.h>
41 #include <microsim/MSLane.h>
42 #include <microsim/MSNet.h>
43 #include <microsim/MSVehicleType.h>
44 #include <microsim/MSLink.h>
45 #include "MELoop.h"
46 #include "MEVehicle.h"
47 #include "MESegment.h"
48 
49 
50 // ===========================================================================
51 // method definitions
52 // ===========================================================================
54  const MSVehicleType* type, const double speedFactor) :
55  MSBaseVehicle(pars, route, type, speedFactor),
56  mySegment(0),
57  myQueIndex(0),
58  myEventTime(SUMOTime_MIN),
59  myLastEntryTime(SUMOTime_MIN),
60  myBlockTime(SUMOTime_MAX) {
61  if ((*myCurrEdge)->getPurpose() != MSEdge::EDGEFUNCTION_DISTRICT) {
62  if ((*myCurrEdge)->allowedLanes(type->getVehicleClass()) == 0) {
63  throw ProcessError("Vehicle '" + pars->id + "' is not allowed to depart on any lane of its first edge.");
64  }
65  if (pars->departSpeedProcedure == DEPART_SPEED_GIVEN && pars->departSpeed > type->getMaxSpeed()) {
66  throw ProcessError("Departure speed for vehicle '" + pars->id +
67  "' is too high for the vehicle type '" + type->getID() + "'.");
68  }
69  }
70 }
71 
72 
73 double
74 MEVehicle::getBackPositionOnLane(const MSLane* /* lane */) const {
76 }
77 
78 
79 double
81 // the following interpolation causes problems with arrivals and calibrators
82 // const double fracOnSegment = MIN2(double(1), STEPS2TIME(MSNet::getInstance()->getCurrentTimeStep() - myLastEntryTime) / STEPS2TIME(myEventTime - myLastEntryTime));
83  return (double(mySegment->getIndex()) /* + fracOnSegment */) * mySegment->getLength();
84 }
85 
86 
87 double
89  const MSLane* const lane = getEdge()->getLanes()[0];
91 }
92 
93 
94 double
96  const MSLane* const lane = getEdge()->getLanes()[0];
98 }
99 
100 
101 Position
102 MEVehicle::getPosition(const double offset) const {
103  const MSLane* const lane = getEdge()->getLanes()[0];
104  return lane->geometryPositionAtOffset(getPositionOnLane() + offset);
105 }
106 
107 
108 double
110  if (getWaitingTime() > 0) {
111  return 0;
112  } else {
113  return getAverageSpeed();
114  }
115 }
116 
117 
118 double
121 }
122 
123 
124 double
127  const double v = getSpeed();
128  return MIN2(link->getViaLaneOrLane()->getVehicleMaxSpeed(this),
129  (double)sqrt(2 * link->getLength() * getVehicleType().getCarFollowModel().getMaxAccel() + v * v));
130 }
131 
132 
133 double
134 MEVehicle::getConservativeSpeed(SUMOTime& earliestArrival) const {
135  earliestArrival = MAX2(myEventTime, earliestArrival - DELTA_T); // event times have subsecond resolution
136  return mySegment->getLength() / STEPS2TIME(earliestArrival - myLastEntryTime);
137 }
138 
139 
140 bool
142  // vehicle has just entered a new edge. Position is 0
143  if (myCurrEdge == myRoute->end() - 1) { // may happen during teleport
144  return true;
145  }
146  ++myCurrEdge;
147  if ((*myCurrEdge)->isVaporizing()) {
148  return true;
149  }
150  return hasArrived();
151 }
152 
153 
154 bool
156  // mySegment may be 0 due to teleporting or arrival
157  return myCurrEdge == myRoute->end() - 1 && (
158  (mySegment == 0)
161 }
162 
163 bool
165  return getSegment() != 0;
166 }
167 
168 
169 bool
171  return false; // parking attribute of a stop is not yet evaluated /implemented
172 }
173 
174 
175 bool
176 MEVehicle::replaceRoute(const MSRoute* newRoute, bool onInit, int offset, bool addStops) {
177  UNUSED_PARAMETER(addStops); // @todo recheck!
178  const ConstMSEdgeVector& edges = newRoute->getEdges();
179  // assert the vehicle may continue (must not be "teleported" or whatever to another position)
180  if (!onInit && !newRoute->contains(*myCurrEdge)) {
181  return false;
182  }
183  MSLink* oldLink = 0;
184  MSLink* newLink = 0;
185  if (mySegment != 0) {
186  oldLink = mySegment->getLink(this);
187  }
188  // rebuild in-vehicle route information
189  if (onInit) {
190  myCurrEdge = newRoute->begin();
191  } else {
192  myCurrEdge = find(edges.begin() + offset, edges.end(), *myCurrEdge);
193  }
194  // check whether the old route may be deleted (is not used by anyone else)
195  newRoute->addReference();
196  myRoute->release();
197  // assign new route
198  myRoute = newRoute;
199  if (mySegment != 0) {
200  newLink = mySegment->getLink(this);
201  }
202  // update approaching vehicle information
203  if (oldLink != 0 && oldLink != newLink) {
204  oldLink->removeApproaching(this);
205  MELoop::setApproaching(this, newLink);
206  }
207  // update arrival definition
209  // save information that the vehicle was rerouted
213  return true;
214 }
215 
216 
217 bool
218 MEVehicle::addStop(const SUMOVehicleParameter::Stop& stopPar, std::string& /*errorMsg*/, SUMOTime /* untilOffset */, bool /*collision*/) {
219  const MSEdge* const edge = MSEdge::dictionary(stopPar.lane.substr(0, stopPar.lane.rfind('_')));
220  assert(edge != 0);
221  MESegment* stopSeg = MSGlobals::gMesoNet->getSegmentForEdge(*edge, stopPar.endPos);
222  myStops[stopSeg] += stopPar.duration;
223  return true;
224 }
225 
226 
227 bool
229  return myStops.find(mySegment) != myStops.end();
230 }
231 
232 
233 bool
235  return false;
236 }
237 
238 
239 SUMOTime
240 MEVehicle::getStoptime(const MESegment* const seg) const {
241  if (myStops.find(seg) != myStops.end()) {
242  return myStops.find(seg)->second;
243  }
244  return 0;
245 }
246 
247 
248 const ConstMSEdgeVector
250  ConstMSEdgeVector result;
251  for (std::map<const MESegment* const, SUMOTime>::const_iterator iter = myStops.begin(); iter != myStops.end(); ++iter) {
252  result.push_back(&iter->first->getEdge());
253  }
254  return result;
255 }
256 
257 
258 bool
260  return mySegment == 0 || mySegment->isOpen(this);
261 }
262 
263 
264 double
266  if (mySegment == 0) {
267  return 0;
268  } else {
269  return STEPS2TIME(mySegment->getLinkPenalty(this));
270  }
271 }
272 
273 
274 void
276  for (MoveReminderCont::iterator i = myMoveReminders.begin(); i != myMoveReminders.end(); ++i) {
277  if (i->first == rem) {
279  (mySegment->getIndex() + 1) * mySegment->getLength(),
280  getLastEntryTime(), currentTime, exitTime, false);
281 #ifdef _DEBUG
282  if (myTraceMoveReminders) {
283  traceMoveReminder("notifyMove", i->first, i->second, true);
284  }
285 #endif
286  return;
287  }
288  }
289 }
290 
291 
292 void
293 MEVehicle::updateDetectors(SUMOTime currentTime, const bool isLeave, const MSMoveReminder::Notification reason) {
294  // segments of the same edge have the same reminder so no cleaning up must take place
295  const bool cleanUp = isLeave && (reason != MSMoveReminder::NOTIFICATION_SEGMENT);
296  for (MoveReminderCont::iterator rem = myMoveReminders.begin(); rem != myMoveReminders.end();) {
297  if (currentTime != getLastEntryTime()) {
298  rem->first->updateDetector(*this, mySegment->getIndex() * mySegment->getLength(),
299  (mySegment->getIndex() + 1) * mySegment->getLength(),
300  getLastEntryTime(), currentTime, getEventTime(), cleanUp);
301 #ifdef _DEBUG
302  if (myTraceMoveReminders) {
303  traceMoveReminder("notifyMove", rem->first, rem->second, true);
304  }
305 #endif
306  }
307  if (!isLeave || rem->first->notifyLeave(*this, mySegment->getLength(), reason)) {
308 #ifdef _DEBUG
309  if (isLeave && myTraceMoveReminders) {
310  traceMoveReminder("notifyLeave", rem->first, rem->second, true);
311  }
312 #endif
313  ++rem;
314  } else {
315 #ifdef _DEBUG
316  if (myTraceMoveReminders) {
317  traceMoveReminder("remove", rem->first, rem->second, false);
318  }
319 #endif
320  rem = myMoveReminders.erase(rem);
321  }
322  }
323 }
324 
325 
326 void
329  assert(mySegment == 0 || *myCurrEdge == &mySegment->getEdge());
330  std::vector<SUMOTime> internals;
331  internals.push_back(myDeparture);
332  internals.push_back((SUMOTime)distance(myRoute->begin(), myCurrEdge));
333  internals.push_back(mySegment == 0 ? (SUMOTime) - 1 : (SUMOTime)mySegment->getIndex());
334  internals.push_back((SUMOTime)getQueIndex());
335  internals.push_back(myEventTime);
336  internals.push_back(myLastEntryTime);
337  internals.push_back(myBlockTime);
338  out.writeAttr(SUMO_ATTR_STATE, toString(internals));
339  out.closeTag();
340 }
341 
342 
343 void
344 MEVehicle::loadState(const SUMOSAXAttributes& attrs, const SUMOTime offset) {
345  if (attrs.hasAttribute(SUMO_ATTR_POSITION)) {
346  throw ProcessError("Error: Invalid vehicles in state (may be a micro state)!");
347  }
348  int routeOffset;
349  int segIndex;
350  int queIndex;
351  std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
352  bis >> myDeparture;
353  bis >> routeOffset;
354  bis >> segIndex;
355  bis >> queIndex;
356  bis >> myEventTime;
357  bis >> myLastEntryTime;
358  bis >> myBlockTime;
359  if (hasDeparted()) {
360  myDeparture -= offset;
361  myEventTime -= offset;
362  myLastEntryTime -= offset;
363  myCurrEdge += routeOffset;
364  if (segIndex >= 0) {
366  while (seg->getIndex() != (int)segIndex) {
367  seg = seg->getNextSegment();
368  assert(seg != 0);
369  }
370  setSegment(seg, queIndex);
371  } else {
372  // on teleport
373  setSegment(0, 0);
374  assert(myEventTime != SUMOTime_MIN);
376  }
377  }
378  if (myBlockTime != SUMOTime_MAX) {
379  myBlockTime -= offset;
380  }
381 }
382 
383 
384 /****************************************************************************/
385 
void updateDetectorForWriting(MSMoveReminder *rem, SUMOTime currentTime, SUMOTime exitTime)
Updates a single vehicle detector if present.
Definition: MEVehicle.cpp:275
void loadState(const SUMOSAXAttributes &attrs, const SUMOTime offset)
Loads the state of this vehicle from the given description.
Definition: MEVehicle.cpp:344
MESegment * getNextSegment() const
Returns the following segment on the same edge (0 if it is the last).
Definition: MESegment.h:157
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:256
void updateDetector(SUMOVehicle &veh, double entryPos, double leavePos, SUMOTime entryTime, SUMOTime currentTime, SUMOTime leaveTime, bool cleanUp)
double getVehicleMaxSpeed(const SUMOVehicle *const veh) const
Returns the lane&#39;s maximum speed, given a vehicle&#39;s speed limit adaptation.
Definition: MSLane.h:462
virtual void setSegment(MESegment *s, int idx=0)
Sets the current segment the vehicle is at together with its que.
Definition: MEVehicle.h:216
double getAngle() const
Returns the vehicle&#39;s direction in degrees.
Definition: MEVehicle.cpp:88
bool isOpen(const MEVehicle *veh) const
Returns whether the vehicle may use the next link.
Definition: MESegment.cpp:426
double getLength() const
Returns the length of the segment in meters.
Definition: MESegment.h:165
MoveReminderCont myMoveReminders
Currently relevant move reminders.
const ConstMSEdgeVector & getEdges() const
Definition: MSRoute.h:128
MESegment * getSegmentForEdge(const MSEdge &e, double pos=0)
Get the segment for a given edge at a given position.
Definition: MELoop.cpp:289
bool hasDeparted() const
Returns whether this vehicle has already departed.
void release() const
deletes the route if there are no further references to it
Definition: MSRoute.cpp:105
double estimateLeaveSpeed(const MSLink *link) const
Returns the vehicle&#39;s estimated speed after driving accross the link.
Definition: MEVehicle.cpp:125
SUMOTime getLastEntryTime() const
Returns the time the vehicle entered the current segment.
Definition: MEVehicle.h:249
SUMOTime duration
The stopping duration.
bool replaceRoute(const MSRoute *route, bool onInit=false, int offset=0, bool addStops=true)
Replaces the current route by the given one.
Definition: MEVehicle.cpp:176
bool mayProceed() const
Returns whether the vehicle is allowed to pass the next junction.
Definition: MEVehicle.cpp:259
int getIndex() const
Returns the running index of the segment in the edge (0 is the most upstream).
Definition: MESegment.h:149
Position getPosition(const double offset=0) const
Return current position (x/y, cartesian)
Definition: MEVehicle.cpp:102
double getSlope() const
Returns the slope of the road at vehicle&#39;s position.
Definition: MEVehicle.cpp:95
double myArrivalPos
The position on the destination lane where the vehicle stops.
Notification
Definition of a vehicle state.
const std::vector< MSLane * > & getLanes() const
Returns this edge&#39;s lanes.
Definition: MSEdge.h:192
SUMOTime getWaitingTime() const
Returns the duration for which the vehicle was blocked.
Definition: MEVehicle.h:272
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:158
T MAX2(T a, T b)
Definition: StdDefs.h:70
SUMOTime DELTA_T
Definition: SUMOTime.cpp:40
const PositionVector & getShape() const
Returns this lane&#39;s shape.
Definition: MSLane.h:426
const MSRoute * myRoute
This Vehicle&#39;s route.
SUMOTime getEventTime() const
Returns the (planned) time at which the vehicle leaves his current cell.
Definition: MEVehicle.h:207
static bool dictionary(const std::string &id, MSEdge *edge)
Inserts edge into the static dictionary Returns true if the key id isn&#39;t already in the dictionary...
Definition: MSEdge.cpp:728
double rotationAtOffset(double pos) const
Returns the rotation at the given length.
The vehicle changes the segment (meso only)
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:78
The base class for microscopic and mesoscopic vehicles.
Definition: MSBaseVehicle.h:56
bool isOnRoad() const
Returns the information whether the vehicle is on a road (is simulated)
Definition: MEVehicle.cpp:164
virtual bool hasAttribute(int id) const =0
Returns the information whether the named (by its enum-value) attribute is within the current list...
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:38
The speed is given.
The car-following model and parameter.
Definition: MSVehicleType.h:74
virtual void saveState(OutputDevice &out)
Saves the (common) state of a vehicle.
virtual std::string getString(int id) const =0
Returns the string-value of the named (by its enum-value) attribute.
double getMaxAccel() const
Get the vehicle type&#39;s maximum acceleration [m/s^2].
Definition: MSCFModel.h:193
void calculateArrivalParams()
(Re-)Calculates the arrival position and lane from the vehicle parameters
The state of a link.
#define SUMOTime_MIN
Definition: SUMOTime.h:45
double departSpeed
(optional) The initial speed of the vehicle
A road/street connecting two junctions.
Definition: MSEdge.h:80
SUMOTime getLinkPenalty(const MEVehicle *veh) const
Returns the penalty time for passing a link (if using gMesoTLSPenalty > 0 or gMesoMinorPenalty > 0) ...
Definition: MESegment.cpp:699
DepartSpeedDefinition departSpeedProcedure
Information how the vehicle&#39;s initial speed shall be chosen.
const MSCFModel & getCarFollowModel() const
Returns the vehicle type&#39;s car following model definition (const version)
The edge is a district edge.
Definition: MSEdge.h:99
The vehicle got a new route.
Definition: MSNet.h:588
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:56
Encapsulated SAX-Attributes.
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
#define SUMOTime_MAX
Definition: TraCIDefs.h:53
MESegment * getSegment() const
Returns the current segment the vehicle is on.
Definition: MEVehicle.h:225
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
bool isStopped() const
Returns whether the vehicle is at a stop.
Definition: MEVehicle.cpp:228
#define STEPS2TIME(x)
Definition: SUMOTime.h:65
double getMaxSpeed() const
Get vehicle&#39;s maximum speed [m/s].
bool hasArrived() const
Returns whether this vehicle has already arived (reached the arrivalPosition on its final edge) ...
Definition: MEVehicle.cpp:155
T MIN2(T a, T b)
Definition: StdDefs.h:64
#define POSITION_EPS
Definition: config.h:175
SUMOTime myLastEntryTime
The time the vehicle entered its current segment.
Definition: MEVehicle.h:347
double endPos
The stopping position end.
Something on a lane to be noticed about vehicle movement.
int getQueIndex() const
Returns the index of the que the vehicle is in.
Definition: MEVehicle.h:233
void saveState(OutputDevice &out)
Saves the states of a vehicle.
Definition: MEVehicle.cpp:327
double getConservativeSpeed(SUMOTime &earliestArrival) const
Returns the vehicle&#39;s estimated speed taking into account delays.
Definition: MEVehicle.cpp:134
MESegment * mySegment
The segment the vehicle is at.
Definition: MEVehicle.h:338
static void setApproaching(MEVehicle *veh, MSLink *link)
registers vehicle with the given link
Definition: MELoop.cpp:211
std::string lane
The lane to stop at.
bool moveRoutePointer()
Update when the vehicle enters a new edge in the move step.
Definition: MEVehicle.cpp:141
double slopeDegreeAtOffset(double pos) const
Returns the slope at the given length.
SUMOTime getStoptime(const MESegment *const seg) const
Returns how long to stop at the given segment.
Definition: MEVehicle.cpp:240
void addStops(const bool ignoreStopErrors)
Adds stops to the built vehicle.
Structure representing possible vehicle parameter.
const MSVehicleType & getVehicleType() const
Returns the vehicle&#39;s type definition.
MSLink * getLink(const MEVehicle *veh, bool tlsPenalty=false) const
Returns the link the given car will use when passing the next junction.
Definition: MESegment.cpp:395
A single mesoscopic segment (cell)
Definition: MESegment.h:57
Definition of vehicle stop (position and duration)
void updateDetectors(SUMOTime currentTime, const bool isLeave, const MSMoveReminder::Notification reason=MSMoveReminder::NOTIFICATION_JUNCTION)
Updates all vehicle detectors.
Definition: MEVehicle.cpp:293
double interpolateLanePosToGeometryPos(double lanePos) const
Definition: MSLane.h:442
const std::string & getID() const
Returns the name of the vehicle type.
const Position geometryPositionAtOffset(double offset, double lateralOffset=0) const
Definition: MSLane.h:448
void addReference() const
increments the reference counter for the route
Definition: MSRoute.cpp:99
std::map< const MESegment *const, SUMOTime > myStops
where to stop
Definition: MEVehicle.h:353
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition: MSGlobals.h:113
MEVehicle(SUMOVehicleParameter *pars, const MSRoute *route, const MSVehicleType *type, const double speedFactor)
Constructor.
Definition: MEVehicle.cpp:53
int myNumberReroutes
The number of reroutings.
double getLength() const
Get vehicle&#39;s length [m].
void informVehicleStateListener(const SUMOVehicle *const vehicle, VehicleState to)
Informs all added listeners about a vehicle&#39;s state change.
Definition: MSNet.cpp:811
bool isParking() const
Returns whether the vehicle is parking.
Definition: MEVehicle.cpp:170
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:71
bool closeTag()
Closes the most recently opened tag.
double getPositionOnLane() const
Get the vehicle&#39;s position along the lane.
Definition: MEVehicle.cpp:80
SUMOTime myEventTime
The (planned) time of leaving the segment (cell)
Definition: MEVehicle.h:344
double getAverageSpeed() const
Returns the vehicle&#39;s estimated average speed on the segment assuming no further delays.
Definition: MEVehicle.cpp:119
long long int SUMOTime
Definition: TraCIDefs.h:52
MSRouteIterator myCurrEdge
Iterator to current route-edge.
double getCurrentLinkPenaltySeconds() const
Returns the delay that is accrued due to option –meso-tls-penalty or –meso-minor-penalty.
Definition: MEVehicle.cpp:265
MSRouteIterator begin() const
Returns the begin of the list of edges to pass.
Definition: MSRoute.cpp:74
double getSpeed() const
Returns the vehicle&#39;s estimated speed assuming no delays.
Definition: MEVehicle.cpp:109
const ConstMSEdgeVector getStopEdges() const
Returns the list of still pending stop edges.
Definition: MEVehicle.cpp:249
bool isStoppedTriggered() const
Returns whether the vehicle is on a triggered stop.
Definition: MEVehicle.cpp:234
bool addStop(const SUMOVehicleParameter::Stop &stopPar, std::string &errorMsg, SUMOTime untilOffset=0, bool collision=false)
Adds a stop.
Definition: MEVehicle.cpp:218
SUMOTime myBlockTime
The time at which the vehicle was blocked on its current segment.
Definition: MEVehicle.h:350
const MSEdge & getEdge() const
Returns the edge this segment belongs to.
Definition: MESegment.h:271
Representation of a lane in the micro simulation.
Definition: MSLane.h:79
void addLeaderCar(MEVehicle *veh, MSLink *link)
Adds the given car to the leading vehicles.
Definition: MELoop.cpp:204
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:80
bool contains(const MSEdge *const edge) const
Definition: MSRoute.h:110
SUMOTime myDeparture
The real departure time.
SUMOVehicleClass getVehicleClass() const
Get this vehicle type&#39;s vehicle class.
std::string id
The vehicle&#39;s id.
double getBackPositionOnLane(const MSLane *lane) const
Get the vehicle&#39;s position relative to the given lane.
Definition: MEVehicle.cpp:74