Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
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-2026 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>
31#include <mesosim/MELoop.h>
32#include <mesosim/MEVehicle.h>
33#include "MSRoutingEngine.h"
34#include "MSIdling.h"
35
36//#define DEBUG_IDLING
37//#define DEBUG_COND(obj) (obj->getHolder().getID() == "p0")
38//#define DEBUG_COND(obj) (obj->getHolder().isSelected())
39#define DEBUG_COND(obj) (true)
40
41
42// ===========================================================================
43// MSIdling_stop methods
44// ===========================================================================
45
46void
48 if (!taxi->getHolder().hasStops()) {
49#ifdef DEBUG_IDLING
50 if (DEBUG_COND(taxi)) {
51 std::cout << SIMTIME << " taxi=" << taxi->getHolder().getID() << " MSIdling_Stop add stop\n";
52 }
53#endif
54 std::string errorOut;
55 double brakeGap = 0;
56 std::pair<const MSLane*, double> stopPos;
58 // stops are only checked in MESegment::receive so we need to put this onto the next segment
59 MSBaseVehicle& veh = dynamic_cast<MSBaseVehicle&>(taxi->getHolder());
62 MESegment* stopSeg = curSeg->getNextSegment();
63 if (stopSeg == nullptr) {
64 if ((ri + 1) != veh.getRoute().end()) {
65 stopSeg = MSGlobals::gMesoNet->getSegmentForEdge(**(ri + 1), 0);
66 } else {
67 WRITE_WARNINGF(TL("Idle taxi '%' has no next segment to stop. time=%."), taxi->getHolder().getID(), time2string(SIMSTEP));
68 return;
69 }
70 }
71 // determine offset of stopSeg
72 double stopOffset = 0;
73 const MSEdge& stopEdge = stopSeg->getEdge();
75 while (seg != stopSeg) {
76 stopOffset += seg->getLength();
77 seg = seg->getNextSegment();
78 }
79 stopPos = std::make_pair(stopEdge.getLanes()[0], stopOffset);
80 } else {
81 MSVehicle& veh = dynamic_cast<MSVehicle&>(taxi->getHolder());
82 brakeGap = veh.getCarFollowModel().brakeGap(veh.getSpeed(), veh.getCarFollowModel().getMaxDecel(), 0.0);
83 stopPos = veh.getLanePosAfterDist(brakeGap);
84 }
85 if (stopPos.first != nullptr) {
88 stop.edge = stopPos.first->getEdge().getID();
89 } else {
90 stop.lane = stopPos.first->getID();
91 }
92 stop.startPos = MAX2(0.0, stopPos.second - POSITION_EPS);
93 stop.endPos = stopPos.second;
95 // meso needs the stop to be on the next segment
96 stop.startPos += POSITION_EPS;
97 stop.endPos += POSITION_EPS;
98 }
99 stop.actType = "idling";
100 taxi->getHolder().addTraciStop(stop, errorOut);
101 if (errorOut != "") {
102 WRITE_WARNING(errorOut);
103 }
104 } else {
105 WRITE_WARNINGF(TL("Idle taxi '%' could not stop within %m"), taxi->getHolder().getID(), toString(brakeGap));
106 }
107 } else {
108#ifdef DEBUG_IDLING
109 if (DEBUG_COND(taxi)) {
110 std::cout << SIMTIME << " taxi=" << taxi->getHolder().getID() << " MSIdling_Stop reusing stop with duration " << time2string(taxi->getHolder().getNextStop().duration) << "\n";
111 }
112#endif
113 }
114 if (taxi->getHolder().hasStops()) {
115 MSStop& stop = taxi->getHolder().getNextStopMutable();
117 if (taxi->getHolder().getVehicleType().getContainerCapacity() > 0) {
118 stop.containerTriggered = true;
119 pars.containerTriggered = true;
120 } else {
121 stop.triggered = true;
122 pars.triggered = true;
123 }
127 MEVehicle& veh = dynamic_cast<MEVehicle&>(taxi->getHolder());
128 // register triggered stop
129 veh.mayProceed();
130 }
131 }
132}
133
134
135// ===========================================================================
136// MSIdling_RandomCircling methods
137// ===========================================================================
138
139void
141 SUMOVehicle& veh = taxi->getHolder();
142 ConstMSEdgeVector edges = veh.getRoute().getEdges();
143 ConstMSEdgeVector newEdges;
144 double remainingDist = -veh.getPositionOnLane();
145 int remainingEdges = 0;
146 int routePos = veh.getRoutePosition();
147 const int routeLength = (int)edges.size();
148 while (routePos + 1 < routeLength && (remainingEdges < 2 || remainingDist < 200)) {
149 const MSEdge* edge = edges[routePos];
150 remainingDist += edge->getLength();
151 remainingEdges++;
152 routePos++;
153 newEdges.push_back(edge);
154 }
155 const MSEdge* lastEdge = edges.back();
156 newEdges.push_back(lastEdge);
157 int added = 0;
158 while (remainingEdges < 2 || remainingDist < 200) {
159 remainingDist += lastEdge->getLength();
160 remainingEdges++;
161 MSEdgeVector successors = lastEdge->getSuccessors(veh.getVClass());
162 for (auto it = successors.begin(); it != successors.end();) {
163 if ((*it)->getFunction() == SumoXMLEdgeFunc::CONNECTOR) {
164 it = successors.erase(it);
165 } else {
166 it++;
167 }
168 }
169 if (gRoutingPreferences && successors.size() > 1) {
170 const double threshPref = veh.getFloatParam("device.taxi.idleMinPref", false, 0);
171 double maxPref = -std::numeric_limits<double>::max();
172 for (const MSEdge* edge : successors) {
173 maxPref = MAX2(maxPref, edge->getPreference(veh.getVTypeParameter()));
174 }
175 if (maxPref >= threshPref) {
176 // there is at least one favoured successor, remove low preference edges
177 for (auto it = successors.begin(); it != successors.end();) {
178 if ((*it)->getPreference(veh.getVTypeParameter()) < threshPref) {
179 it = successors.erase(it);
180 } else {
181 it++;
182 }
183 }
184 }
185 }
186 if (successors.size() == 0) {
187 WRITE_WARNINGF(TL("Vehicle '%' ends idling in a cul-de-sac"), veh.getID());
188 break;
189 } else {
190 int nextIndex = RandHelper::rand((int)successors.size(), veh.getRNG());
191 newEdges.push_back(successors[nextIndex]);
192 lastEdge = newEdges.back();
193 added++;
194 }
195 }
196 if (added > 0) {
197 //std::cout << SIMTIME << " circleVeh=" << veh.getID() << " newEdges=" << toString(newEdges) << "\n";
198 veh.replaceRouteEdges(newEdges, -1, 0, "taxi:idling:randomCircling", false, false, false);
199 }
200}
201
202// ===========================================================================
203// MSIdling_TaxiStand methods
204// ===========================================================================
205
206void
208 MSBaseVehicle& veh = dynamic_cast<MSBaseVehicle&>(taxi->getHolder());
209
211 if (rerouteDef == nullptr || rerouteDef->parkProbs.getVals().size() == 0) {
212 if (!myHaveWarned) {
213 WRITE_WARNINGF(TL("Could not determine taxi stand for vehicle '%' at time=%"), veh.getID(), time2string(SIMSTEP));
214 myHaveWarned = true;
215 }
216 return;
217 }
218 MSStop* lastStop = nullptr;
219 if (veh.hasStops()) {
220 lastStop = &veh.getStop((int)veh.getStops().size() - 1);
221 }
222 if (lastStop == nullptr || lastStop->parkingarea == nullptr) {
223 const MSParkingArea* pa = dynamic_cast<MSParkingArea*>(rerouteDef->parkProbs.getVals().front().first);
225 stop.lane = pa->getLane().getID();
226 stop.startPos = pa->getBeginLanePosition();
227 stop.endPos = pa->getEndLanePosition();
228
229 if (taxi->getHolder().getVehicleType().getContainerCapacity() > 0) {
230 stop.containerTriggered = true;
231 } else {
232 stop.triggered = true;
233 }
234 stop.actType = "idling";
235 stop.parkingarea = pa->getID();
237 const int nextStopIndex = (int)veh.getStops().size();
238 std::string error;
239 if (!veh.insertStop(nextStopIndex, stop, "taxi:taxistand", false, error)) {
240 WRITE_WARNING("Stop insertion failed for idling taxi '" + veh.getID() + "' (" + error + ").");
241 } else {
242 //std::cout << SIMTIME << " taxistandsVeh=" << veh.getID() << " driving to parkingArea " << pa->getID() << "\n";
244 }
245 } else if (!MSGlobals::gUseMesoSim) {
246 //std::cout << SIMTIME << " taxistandsVeh=" << veh.getID() << " already driving to parkingArea\n";
247 MSParkingArea* pa = lastStop->parkingarea;
248 if (taxi->getHolder().isStoppedTriggered() && pa != nullptr && pa->mustAdvance(taxi->getHolder().getVClass())) {
249 double vehPos = taxi->getHolder().getPositionOnLane();
250 double targetPos = pa->getLastFreePos(taxi->getHolder(), vehPos);
251 //std::cout << SIMTIME << " veh=" << taxi->getHolder().getID() << " vehPos=" << vehPos << " targetPos=" << targetPos << " cap=" << pa->getCapacity() << " occ=" << pa->getOccupancyIncludingBlocked() << "\n";
252 if (targetPos > vehPos + POSITION_EPS) {
253 taxi->getHolder().abortNextStop();
254 idle(taxi);
255 } else {
256 auto follower = veh.getFollower();
257 if (follower.first != nullptr && follower.first->getWaitingTime() > DELTA_T) {
258 // advance in queue to unblock follower
260 taxi->getHolder().abortNextStop();
261 ConstMSEdgeVector loopedRoute;
263 router.computeLooped(veh.getEdge(), veh.getEdge(), &veh, SIMSTEP, loopedRoute);
264 veh.replaceRouteEdges(loopedRoute, -1, 0, "taxi:idling_unblock", false, false, false);
265 stop.index = 1;
266 std::string error;
267 veh.addStop(stop, error);
268 }
269 }
270 }
271 }
272}
273
274
275
276/****************************************************************************/
std::vector< const MSEdge * > ConstMSEdgeVector
Definition MSEdge.h:74
std::vector< MSEdge * > MSEdgeVector
Definition MSEdge.h:73
ConstMSEdgeVector::const_iterator MSRouteIterator
Definition MSRoute.h:57
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:287
#define WRITE_WARNING(msg)
Definition MsgHandler.h:286
#define TL(string)
Definition MsgHandler.h:304
SUMOTime DELTA_T
Definition SUMOTime.cpp:38
std::string time2string(SUMOTime t, bool humanReadable)
convert SUMOTime to string (independently of global format setting)
Definition SUMOTime.cpp:91
#define SIMSTEP
Definition SUMOTime.h:64
#define SIMTIME
Definition SUMOTime.h:65
const int STOP_PARKING_SET
const int STOP_TRIGGER_SET
const int STOP_END_SET
bool gRoutingPreferences
Definition StdDefs.cpp:37
T MAX2(T a, T b)
Definition StdDefs.h:86
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:49
MESegment * getSegmentForEdge(const MSEdge &e, double pos=0)
Get the segment for a given edge at a given position.
Definition MELoop.cpp:339
A single mesoscopic segment (cell)
Definition MESegment.h:50
double getLength() const
Returns the length of the segment in meters.
Definition MESegment.h:251
const MSEdge & getEdge() const
Returns the edge this segment belongs to.
Definition MESegment.h:371
MESegment * getNextSegment() const
Returns the following segment on the same edge (0 if it is the last).
Definition MESegment.h:243
A vehicle from the mesoscopic point of view.
Definition MEVehicle.h:42
bool mayProceed()
Returns whether the vehicle is allowed to pass the next junction, checks also for triggered stops.
The base class for microscopic and mesoscopic vehicles.
const MSRouteIterator & getCurrentRouteEdge() const
Returns an iterator pointing to the current edge in this vehicles route.
const MSEdge * getEdge() const
Returns the edge the vehicle is currently at.
const std::list< MSStop > & getStops() const
bool hasStops() const
Returns whether the vehicle has to stop somewhere.
SUMOVehicleClass getVClass() const
Returns the vehicle's access class.
MSStop & getStop(int nextStopIndex)
virtual std::pair< const MSVehicle *const, double > getFollower(double dist=0) const
Returns the follower of the vehicle looking for a fixed distance.
bool insertStop(int nextStopIndex, SUMOVehicleParameter::Stop stop, const std::string &info, bool teleport, std::string &errorMsg)
bool addStop(const SUMOVehicleParameter::Stop &stopPar, std::string &errorMsg, SUMOTime untilOffset=0, MSRouteIterator *searchStart=nullptr)
Adds a stop.
const MSRoute & getRoute() const
Returns the current route.
int getRNGIndex() const
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)
Replaces the current route by the given edges.
double brakeGap(const double speed) const
Returns the distance the vehicle needs to halt including driver's reaction time tau (i....
Definition MSCFModel.h:408
double getMaxDecel() const
Get the vehicle type's maximal comfortable deceleration [m/s^2].
Definition MSCFModel.h:269
A device which collects info on the vehicle trip (mainly on departure and arrival)
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:694
const MSEdgeVector & getSuccessors(SUMOVehicleClass vClass=SVC_IGNORING) const
Returns the following edges, restricted by vClass.
Definition MSEdge.cpp:1292
static bool gUseMesoSim
Definition MSGlobals.h:106
static MELoop * gMesoNet
mesoscopic simulation infrastructure
Definition MSGlobals.h:115
void idle(MSDevice_Taxi *taxi)
computes Idling and updates reservations
Definition MSIdling.cpp:140
void idle(MSDevice_Taxi *taxi)
computes Idling and updates reservations
Definition MSIdling.cpp:47
MSTriggeredRerouter * myRerouter
Definition MSIdling.h:71
void idle(MSDevice_Taxi *taxi)
computes Idling and updates reservations
Definition MSIdling.cpp:207
@ NOTIFICATION_PARKING_REROUTE
The vehicle needs another parking area.
A lane area vehicles can halt at.
bool mustAdvance(SUMOVehicleClass svc) const
whether parked vehicles must advance in a queue
double getLastFreePos(const SUMOVehicle &forVehicle, double brakePos=0) const override
Returns the last free position on this stop.
const ConstMSEdgeVector & getEdges() const
Definition MSRoute.h:128
MSRouteIterator end() const
Returns the end of the list of edges to pass.
Definition MSRoute.cpp:79
static MSVehicleRouter & getRouterTT(const int rngIndex, SUMOVehicleClass svc, const Prohibitions &prohibited={})
return the vehicle router instance
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
const SUMOVehicleParameter::Stop pars
The stop parameter.
Definition MSStop.h:65
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.
bool triggerRouting(SUMOTrafficObject &veh, MSMoveReminder::Notification reason)
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
double getSpeed() const
Returns the vehicle's current speed.
Definition MSVehicle.h:490
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
Definition MSVehicle.h:969
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)
const std::vector< T > & getVals() const
Returns the members of the distribution.
bool computeLooped(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into, bool silent=false)
Builds the route between the given edges using the minimum effort at the given time if from == to,...
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual const SUMOVTypeParameter & getVTypeParameter() const =0
Returns the object's "vehicle" type parameter.
virtual SUMOVehicleClass getVClass() const =0
Returns the object's access class.
virtual SumoRNG * getRNG() const =0
Returns the associated RNG for this object.
virtual int getRoutePosition() const =0
return index of edge within route
double getFloatParam(const std::string &paramName, const bool required=false, const double deflt=INVALID_DOUBLE, bool checkDist=true) const
Retrieve a floating point parameter for the traffic object.
virtual double getPositionOnLane() const =0
Get the object's position along the lane.
Representation of a vehicle.
Definition SUMOVehicle.h:63
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 bool hasStops() const =0
Returns whether the vehicle has to stop somewhere.
virtual bool isStoppedTriggered() const =0
Returns whether the vehicle is at a stop and waiting for a person or container to continue.
virtual const MSStop & getNextStop() const =0
virtual MSStop & getNextStopMutable()=0
virtual bool addTraciStop(SUMOVehicleParameter::Stop stop, std::string &errorMsg)=0
virtual const MSRoute & getRoute() const =0
Returns the current route.
virtual bool abortNextStop(int nextStopIndex=0)=0
deletes the next stop at the given index if it exists
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.
int parametersSet
Information for the output which parameter were set.
int index
at which position in the stops list
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
#define DEBUG_COND
RandomDistributor< MSStoppingPlaceRerouter::StoppingPlaceVisible > parkProbs
The distributions of new parking areas to use as destinations.