Eclipse SUMO - Simulation of Urban MObility
MSIdling.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2007-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 /****************************************************************************/
19 // An algorithm that performs Idling for the taxi device
20 /****************************************************************************/
21 #include <config.h>
22 
23 #include <limits>
24 #include <microsim/MSNet.h>
25 #include <microsim/MSEdge.h>
26 #include <microsim/MSLane.h>
27 #include <microsim/MSStop.h>
28 #include <microsim/MSParkingArea.h>
31 #include <mesosim/MELoop.h>
32 #include "MSRoutingEngine.h"
33 #include "MSIdling.h"
34 
35 //#define DEBUG_IDLING
36 //#define DEBUG_COND(obj) (obj->getHolder().getID() == "p0")
37 //#define DEBUG_COND(obj) (obj->getHolder().isSelected())
38 #define DEBUG_COND(obj) (true)
39 
40 
41 // ===========================================================================
42 // MSIdling_stop methods
43 // ===========================================================================
44 
45 void
47  if (!taxi->getHolder().hasStops()) {
48 #ifdef DEBUG_IDLING
49  if (DEBUG_COND(taxi)) {
50  std::cout << SIMTIME << " taxi=" << taxi->getHolder().getID() << " MSIdling_Stop add stop\n";
51  }
52 #endif
53  std::string errorOut;
54  double brakeGap = 0;
55  std::pair<const MSLane*, double> stopPos;
57  // stops are only checked in MESegment::receive so we need to put this onto the next segment
58  MSBaseVehicle& veh = dynamic_cast<MSBaseVehicle&>(taxi->getHolder());
61  MESegment* stopSeg = curSeg->getNextSegment();
62  if (stopSeg == nullptr) {
63  if ((ri + 1) != veh.getRoute().end()) {
64  stopSeg = MSGlobals::gMesoNet->getSegmentForEdge(**(ri + 1), 0);
65  } else {
66  WRITE_WARNINGF(TL("Idle taxi '%' has no next segment to stop. time=%."), taxi->getHolder().getID(), time2string(SIMSTEP));
67  return;
68  }
69  }
70  // determine offset of stopSeg
71  double stopOffset = 0;
72  const MSEdge& stopEdge = stopSeg->getEdge();
74  while (seg != stopSeg) {
75  stopOffset += seg->getLength();
76  seg = seg->getNextSegment();
77  }
78  stopPos = std::make_pair(stopEdge.getLanes()[0], stopOffset);
79  } else {
80  MSVehicle& veh = dynamic_cast<MSVehicle&>(taxi->getHolder());
81  brakeGap = veh.getCarFollowModel().brakeGap(veh.getSpeed(), veh.getCarFollowModel().getMaxDecel(), 0.0);
82  stopPos = veh.getLanePosAfterDist(brakeGap);
83  }
84  if (stopPos.first != nullptr) {
87  stop.edge = stopPos.first->getEdge().getID();
88  } else {
89  stop.lane = stopPos.first->getID();
90  }
91  stop.startPos = MAX2(0.0, stopPos.second - POSITION_EPS);
92  stop.endPos = stopPos.second;
94  // meso needs the stop to be on the next segment
95  stop.startPos += POSITION_EPS;
96  stop.endPos += POSITION_EPS;
97  }
98  if (taxi->getHolder().getVehicleType().getContainerCapacity() > 0) {
99  stop.containerTriggered = true;
100  } else {
101  stop.triggered = true;
102  }
103  stop.actType = "idling";
105  taxi->getHolder().addTraciStop(stop, errorOut);
106  if (errorOut != "") {
107  WRITE_WARNING(errorOut);
108  }
109  } else {
110  WRITE_WARNINGF(TL("Idle taxi '%' could not stop within %m"), taxi->getHolder().getID(), toString(brakeGap));
111  }
112  } else {
113  MSStop& stop = taxi->getHolder().getNextStop();
114 #ifdef DEBUG_IDLING
115  if (DEBUG_COND(taxi)) {
116  std::cout << SIMTIME << " taxi=" << taxi->getHolder().getID() << " MSIdling_Stop reusing stop with duration " << time2string(stop.duration) << "\n";
117  }
118 #endif
119  if (taxi->getHolder().getVehicleType().getContainerCapacity() > 0) {
120  stop.containerTriggered = true;
121  } else {
122  stop.triggered = true;
123  }
124  }
125 }
126 
127 
128 // ===========================================================================
129 // MSIdling_RandomCircling methods
130 // ===========================================================================
131 
132 void
134  SUMOVehicle& veh = taxi->getHolder();
135  ConstMSEdgeVector edges = veh.getRoute().getEdges();
136  ConstMSEdgeVector newEdges;
137  double remainingDist = -veh.getPositionOnLane();
138  int remainingEdges = 0;
139  int routePos = veh.getRoutePosition();
140  const int routeLength = (int)edges.size();
141  while (routePos + 1 < routeLength && (remainingEdges < 2 || remainingDist < 200)) {
142  const MSEdge* edge = edges[routePos];
143  remainingDist += edge->getLength();
144  remainingEdges++;
145  routePos++;
146  newEdges.push_back(edge);
147  }
148  const MSEdge* lastEdge = edges.back();
149  newEdges.push_back(lastEdge);
150  int added = 0;
151  while (remainingEdges < 2 || remainingDist < 200) {
152  remainingDist += lastEdge->getLength();
153  remainingEdges++;
154  MSEdgeVector successors = lastEdge->getSuccessors(veh.getVClass());
155  for (auto it = successors.begin(); it != successors.end();) {
156  if ((*it)->getFunction() == SumoXMLEdgeFunc::CONNECTOR) {
157  it = successors.erase(it);
158  } else {
159  it++;
160  }
161  }
162  if (successors.size() == 0) {
163  WRITE_WARNINGF(TL("Vehicle '%' ends idling in a cul-de-sac"), veh.getID());
164  break;
165  } else {
166  int nextIndex = RandHelper::rand((int)successors.size(), veh.getRNG());
167  newEdges.push_back(successors[nextIndex]);
168  lastEdge = newEdges.back();
169  added++;
170  }
171  }
172  if (added > 0) {
173  //std::cout << SIMTIME << " circleVeh=" << veh.getID() << " newEdges=" << toString(newEdges) << "\n";
174  veh.replaceRouteEdges(newEdges, -1, 0, "taxi:idling:randomCircling", false, false, false);
175  }
176 }
177 
178 // ===========================================================================
179 // MSIdling_TaxiStand methods
180 // ===========================================================================
181 
182 void
184  MSBaseVehicle& veh = dynamic_cast<MSBaseVehicle&>(taxi->getHolder());
185 
187  if (rerouteDef == nullptr || rerouteDef->parkProbs.getVals().size() == 0) {
188  if (!myHaveWarned) {
189  WRITE_WARNINGF(TL("Could not determine taxi stand for vehicle '%' at time=%"), veh.getID(), time2string(SIMSTEP));
190  myHaveWarned = true;
191  }
192  return;
193  }
194  MSStop* lastStop = nullptr;
195  if (veh.hasStops()) {
196  lastStop = &veh.getStop((int)veh.getStops().size() - 1);
197  }
198  if (lastStop == nullptr || lastStop->parkingarea == nullptr) {
199  const MSParkingArea* pa = dynamic_cast<MSParkingArea*>(rerouteDef->parkProbs.getVals().front().first);
201  stop.lane = pa->getLane().getID();
202  stop.startPos = pa->getBeginLanePosition();
203  stop.endPos = pa->getEndLanePosition();
204 
205  if (taxi->getHolder().getVehicleType().getContainerCapacity() > 0) {
206  stop.containerTriggered = true;
207  } else {
208  stop.triggered = true;
209  }
210  stop.actType = "idling";
211  stop.parkingarea = pa->getID();
213  const int nextStopIndex = (int)veh.getStops().size();
214  std::string error;
215  if (!veh.insertStop(nextStopIndex, stop, "taxi:taxistand", false, error)) {
216  WRITE_WARNING("Stop insertion failed for idling taxi '" + veh.getID() + "' (" + error + ").");
217  } else {
218  //std::cout << SIMTIME << " taxistandsVeh=" << veh.getID() << " driving to parkingArea " << pa->getID() << "\n";
220  }
221  } else {
222  //std::cout << SIMTIME << " taxistandsVeh=" << veh.getID() << " already driving to parkingArea\n";
223  }
224 }
225 
226 
227 
228 /****************************************************************************/
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:74
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:73
#define DEBUG_COND(obj)
Definition: MSIdling.cpp:38
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition: MSRoute.h:56
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:296
#define WRITE_WARNING(msg)
Definition: MsgHandler.h:295
#define TL(string)
Definition: MsgHandler.h:315
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition: SUMOTime.cpp:69
#define SIMSTEP
Definition: SUMOTime.h:61
#define SIMTIME
Definition: SUMOTime.h:62
T MAX2(T a, T b)
Definition: StdDefs.h:82
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
MESegment * getSegmentForEdge(const MSEdge &e, double pos=0)
Get the segment for a given edge at a given position.
Definition: MELoop.cpp:333
A single mesoscopic segment (cell)
Definition: MESegment.h:49
double getLength() const
Returns the length of the segment in meters.
Definition: MESegment.h:242
MESegment * getNextSegment() const
Returns the following segment on the same edge (0 if it is the last).
Definition: MESegment.h:234
const MSEdge & getEdge() const
Returns the edge this segment belongs to.
Definition: MESegment.h:359
The base class for microscopic and mesoscopic vehicles.
Definition: MSBaseVehicle.h:57
const std::list< MSStop > & getStops() const
const MSRouteIterator & getCurrentRouteEdge() const
Returns an iterator pointing to the current edge in this vehicles route.
bool hasStops() const
Returns whether the vehicle has to stop somewhere.
virtual void activateReminders(const MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
"Activates" all current move reminder
MSStop & getStop(int nextStopIndex)
bool insertStop(int nextStopIndex, SUMOVehicleParameter::Stop stop, const std::string &info, bool teleport, std::string &errorMsg)
const MSRoute & getRoute() const
Returns the current route.
double brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver's reaction time tau (i....
Definition: MSCFModel.h:380
double getMaxDecel() const
Get the vehicle type's maximal comfortable deceleration [m/s^2].
Definition: MSCFModel.h:264
A device which collects info on the vehicle trip (mainly on departure and arrival)
Definition: MSDevice_Taxi.h:49
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
double getLength() const
return the length of the edge
Definition: MSEdge.h:670
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition: MSEdge.cpp:1206
static bool gUseMesoSim
Definition: MSGlobals.h:103
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition: MSGlobals.h:109
void idle(MSDevice_Taxi *taxi)
computes Idling and updates reservations
Definition: MSIdling.cpp:133
void idle(MSDevice_Taxi *taxi)
computes Idling and updates reservations
Definition: MSIdling.cpp:46
MSTriggeredRerouter * myRerouter
Definition: MSIdling.h:71
void idle(MSDevice_Taxi *taxi)
computes Idling and updates reservations
Definition: MSIdling.cpp:183
@ NOTIFICATION_PARKING_REROUTE
The vehicle needs another parking area.
A lane area vehicles can halt at.
Definition: MSParkingArea.h:60
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition: MSRoute.cpp:79
const ConstMSEdgeVector & getEdges() const
Definition: MSRoute.h:124
Definition: MSStop.h:44
bool triggered
whether an arriving person lets the vehicle continue
Definition: MSStop.h:69
bool containerTriggered
whether an arriving container lets the vehicle continue
Definition: MSStop.h:71
MSParkingArea * parkingarea
(Optional) parkingArea if one is assigned to the stop
Definition: MSStop.h:58
SUMOTime duration
The stopping duration.
Definition: MSStop.h:67
double getBeginLanePosition() const
Returns the begin position of this stop.
double getEndLanePosition() const
Returns the end position of this stop.
const MSLane & getLane() const
Returns the lane this stop is located at.
const RerouteInterval * getCurrentReroute(SUMOTime time, SUMOTrafficObject &obj) const
Returns the rerouting definition valid for the given time and object, nullptr if none.
SUMOVehicle & getHolder() const
Returns the vehicle that holds this device.
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:77
std::pair< const MSLane *, double > getLanePosAfterDist(double distance) const
return lane and position along bestlanes at the given distance
Definition: MSVehicle.cpp:6496
double getSpeed() const
Returns the vehicle's current speed.
Definition: MSVehicle.h:493
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
Definition: MSVehicle.h:977
int getContainerCapacity() const
Get this vehicle type's container capacity.
const std::string & getID() const
Returns the id.
Definition: Named.h:74
static double rand(SumoRNG *rng=nullptr)
Returns a random real number in [0, 1)
Definition: RandHelper.cpp:94
const std::vector< T > & getVals() const
Returns the members of the distribution.
virtual SumoRNG * getRNG() const =0
Returns the associated RNG for this object.
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual SUMOVehicleClass getVClass() const =0
Returns the object's access class.
virtual int getRoutePosition() const =0
return index of edge within route
virtual double getPositionOnLane() const =0
Get the object's position along the lane.
Representation of a vehicle.
Definition: SUMOVehicle.h:62
virtual bool replaceRouteEdges(ConstMSEdgeVector &edges, double cost, double savings, const std::string &info, bool onInit=false, bool check=false, bool removeStops=true, std::string *msgReturn=nullptr)=0
Replaces the current route by the given edges.
virtual const MSRoute & getRoute() const =0
Returns the current route.
virtual bool hasStops() const =0
Returns whether the vehicle has to stop somewhere.
virtual MSStop & getNextStop()=0
virtual bool addTraciStop(SUMOVehicleParameter::Stop stop, std::string &errorMsg)=0
Definition of vehicle stop (position and duration)
std::string edge
The edge to stop at.
ParkingType parking
whether the vehicle is removed from the net while stopping
std::string lane
The lane to stop at.
std::string parkingarea
(Optional) parking area if one is assigned to the stop
double startPos
The stopping position start.
std::string actType
act Type (only used by Persons) (used by netedit)
bool triggered
whether an arriving person lets the vehicle continue
double endPos
The stopping position end.
bool containerTriggered
whether an arriving container lets the vehicle continue
RandomDistributor< MSStoppingPlaceRerouter::StoppingPlaceVisible > parkProbs
The distributions of new parking areas to use as destinations.