Eclipse SUMO - Simulation of Urban MObility
MSDevice_StationFinder.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2001-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 // A device which triggers rerouting to nearby charging stations
20 /****************************************************************************/
21 #include <config.h>
22 
23 #include <microsim/MSEdge.h>
26 #include <microsim/MSNet.h>
27 #include <microsim/MSParkingArea.h>
28 #include <microsim/MSStop.h>
38 #include "MSRoutingEngine.h"
39 #include "MSDevice_Battery.h"
40 #include "MSDevice_StationFinder.h"
41 
42 //#define DEBUG_STATIONFINDER_RESCUE
43 //#define DEBUG_STATIONFINDER_REROUTE
44 
45 
46 // ===========================================================================
47 // static variables
48 // ===========================================================================
49 
50 
51 // ===========================================================================
52 // method definitions
53 // ===========================================================================
54 // ---------------------------------------------------------------------------
55 // static initialisation methods
56 // ---------------------------------------------------------------------------
57 void
59  insertDefaultAssignmentOptions("stationfinder", "Battery", oc);
60  oc.doRegister("device.stationfinder.rescueTime", new Option_String("1800", "TIME"));
61  oc.addDescription("device.stationfinder.rescueTime", "Battery", TL("Time to wait for a rescue vehicle on the road side when the battery is empty"));
62  oc.doRegister("device.stationfinder.rescueAction", new Option_String("remove"));
63  oc.addDescription("device.stationfinder.rescueAction", "Battery", TL("How to deal with a vehicle which has to stop due to low battery: [none, remove, tow]"));
64  oc.doRegister("device.stationfinder.reserveFactor", new Option_Float(1.1));
65  oc.addDescription("device.stationfinder.reserveFactor", "Battery", TL("Scale battery need with this factor to account for unexpected traffic situations"));
66  oc.doRegister("device.stationfinder.emptyThreshold", new Option_Float(0.05));
67  oc.addDescription("device.stationfinder.emptyThreshold", "Battery", TL("Battery percentage to go into rescue mode"));
68  oc.doRegister("device.stationfinder.radius", new Option_String("180", "TIME"));
69  oc.addDescription("device.stationfinder.radius", "Battery", TL("Search radius in travel time seconds"));
70  oc.doRegister("device.stationfinder.maxEuclideanDistance", new Option_Float(-1));
71  oc.addDescription("device.stationfinder.maxEuclideanDistance", "Battery", TL("Euclidean search distance in meters (a negative value disables the restriction)"));
72  oc.doRegister("device.stationfinder.repeat", new Option_String("60", "TIME"));
73  oc.addDescription("device.stationfinder.repeat", "Battery", TL("When to trigger a new search if no station has been found"));
74  oc.doRegister("device.stationfinder.maxChargePower", new Option_Float(100000.));
75  oc.addDescription("device.stationfinder.maxChargePower", "Battery", TL("The maximum charging speed of the vehicle battery"));
76  oc.doRegister("device.stationfinder.chargeType", new Option_String("charging"));
77  oc.addDescription("device.stationfinder.chargeType", "Battery", TL("Type of energy transfer"));
78  oc.doRegister("device.stationfinder.waitForCharge", new Option_String("600", "TIME"));
79  oc.addDescription("device.stationfinder.waitForCharge", "Battery", TL("After this waiting time vehicle searches for a new station when the initial one is blocked"));
80  oc.doRegister("device.stationfinder.saturatedChargeLevel", new Option_Float(0.8));
81  oc.addDescription("device.stationfinder.saturatedChargeLevel", "Battery", TL("Target state of charge after which the vehicle stops charging"));
82  oc.doRegister("device.stationfinder.needToChargeLevel", new Option_Float(0.4));
83  oc.addDescription("device.stationfinder.needToChargeLevel", "Battery", TL("State of charge the vehicle begins searching for charging stations"));
84  oc.doRegister("device.stationfinder.replacePlannedStop", new Option_Float(0.));
85  oc.addDescription("device.stationfinder.replacePlannedStop", "Battery", TL("Share of stopping time of the next independently planned stop to use for charging instead"));
86  oc.doRegister("device.stationfinder.maxDistanceToReplacedStop", new Option_Float(300.));
87  oc.addDescription("device.stationfinder.maxDistanceToReplacedStop", "Battery", TL("Maximum distance in meters from the original stop to be replaced by the charging stop"));
88  oc.doRegister("device.stationfinder.chargingStrategy", new Option_String("none"));
89  oc.addDescription("device.stationfinder.chargingStrategy", "Battery", TL("Set a charging strategy to alter time and charging load from the set: [none, balanced, latest]"));
90 }
91 
92 
93 
94 void
95 MSDevice_StationFinder::buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into) {
97  if (equippedByDefaultAssignmentOptions(oc, "stationfinder", v, false)) {
98  into.push_back(new MSDevice_StationFinder(v));
99  }
100 }
101 
102 
103 // ---------------------------------------------------------------------------
104 // MSDevice_StationFinder-methods
105 // ---------------------------------------------------------------------------
107  : MSVehicleDevice(holder, "stationfinder_" + holder.getID()),
108  MSStoppingPlaceRerouter(SUMO_TAG_CHARGING_STATION, "device.stationfinder.charging", true, false, {
109  {"waitingTime", 1.}, {"chargingTime", 1.}
110 }, { {"waitingTime", false}, {"chargingTime", false} }),
111 myVeh(dynamic_cast<MSVehicle&>(holder)),
112 myBattery(nullptr), myChargingStation(nullptr), myRescueCommand(nullptr), myChargeLimitCommand(nullptr),
113 myLastChargeCheck(0), myCheckInterval(1000), myArrivalAtChargingStation(-1), myLastSearch(-1) {
114  // consider whole path to/from a charging station in the search
115  myEvalParams["distanceto"] = 0.;
116  myEvalParams["timeto"] = 1.;
117  myEvalParams["timefrom"] = 1.;
118  myNormParams["chargingTime"] = true;
119  myNormParams["waitingTime"] = true;
120  myRescueTime = STEPS2TIME(holder.getTimeParam("device.stationfinder.rescueTime"));
121  const std::string chargingStrategy = holder.getStringParam("device.stationfinder.chargingStrategy");
122  if (chargingStrategy == "balanced") {
123  myChargingStrategy = CHARGINGSTRATEGY_BALANCED;
124  } else if (chargingStrategy == "latest") {
125  myChargingStrategy = CHARGINGSTRATEGY_LATEST;
126  } else if (chargingStrategy == "none") {
127  myChargingStrategy = CHARGINGSTRATEGY_NONE;
128  } else {
129  WRITE_ERRORF(TL("Invalid device.stationfinder.chargingStrategy '%'."), chargingStrategy);
130  }
131  const std::string rescueAction = holder.getStringParam("device.stationfinder.rescueAction");
132  if (rescueAction == "remove") {
133  myRescueAction = RESCUEACTION_REMOVE;
134  } else if (rescueAction == "tow") {
135  myRescueAction = RESCUEACTION_TOW;
136  } else if (rescueAction == "none") {
137  myRescueAction = RESCUEACTION_NONE;
138  } else {
139  WRITE_ERRORF(TL("Invalid device.stationfinder.rescueAction '%'."), rescueAction);
140  }
141  initRescueCommand();
142  myReserveFactor = MAX2(1., holder.getFloatParam("device.stationfinder.reserveFactor"));
143  myEmptySoC = MAX2(0., MIN2(holder.getFloatParam("device.stationfinder.emptyThreshold"), 1.));
144  myRadius = holder.getTimeParam("device.stationfinder.radius");
145  myMaxEuclideanDistance = holder.getFloatParam("device.stationfinder.maxEuclideanDistance");
146  myRepeatInterval = holder.getTimeParam("device.stationfinder.repeat");
147  myMaxChargePower = holder.getFloatParam("device.stationfinder.maxChargePower");
148  myChargeType = CHARGETYPE_CHARGING;
149 
150  myWaitForCharge = holder.getTimeParam("device.stationfinder.waitForCharge");
151  myTargetSoC = MAX2(0., MIN2(holder.getFloatParam("device.stationfinder.saturatedChargeLevel"), 1.));
152  mySearchSoC = MAX2(0., MIN2(holder.getFloatParam("device.stationfinder.needToChargeLevel"), 1.));
153  if (mySearchSoC <= myEmptySoC) {
154  WRITE_WARNINGF(TL("Vehicle '%' searches for charging stations only in the rescue case due to search threshold % <= rescue threshold %."), myHolder.getID(), mySearchSoC, myEmptySoC);
155  }
156  myReplacePlannedStop = MAX2(0., holder.getFloatParam("device.stationfinder.replacePlannedStop"));
157  myDistanceToOriginalStop = holder.getFloatParam("device.stationfinder.maxDistanceToReplacedStop");
158  myUpdateSoC = MAX2(0., mySearchSoC - DEFAULT_SOC_INTERVAL);
159 }
160 
161 
163  // make the rescue command invalid if there is one
164  if (myRescueCommand != nullptr) {
166  }
167  if (myChargeLimitCommand != nullptr) {
169  }
170 }
171 
172 
173 bool
174 MSDevice_StationFinder::notifyMove(SUMOTrafficObject& veh, double /*oldPos*/, double /*newPos*/, double /*newSpeed*/) {
175  if (myBattery->getEnergyCharged() > 0. && myChargingStation != nullptr) {
177  myChargingStation = nullptr;
179  return true;
180  } else if (mySearchState == SEARCHSTATE_CHARGING) {
181  if (myBattery->getChargingStationID() == "") {
183  } else {
184  return true;
185  }
186  }
187  // check if the vehicle travels at most an edge length to the charging station after jump/teleport
189  return true;
190  }
191  const SUMOTime now = SIMSTEP;
192  if (myChargingStation != nullptr) {
194  // waited for too long, try another charging station
195  if (rerouteToChargingStation(true)) {
196  WRITE_MESSAGE(TLF("Rerouted vehicle '%' after waiting too long at the previous charging station at time=%.", veh.getID(), toString(SIMTIME)));
197  }
199  // remember when the vehicle arrived close to the target charging station
202  }
203  }
204  const double currentSoC = myBattery->getActualBatteryCapacity() / myBattery->getMaximumBatteryCapacity();
205  if (currentSoC > mySearchSoC || mySearchState == SEARCHSTATE_BROKEN_DOWN) {
206  // battery SoC is too high to look for charging facilities or the vehicle is already in rescue mode
207  return true;
208  }
209  // only check once per second
210  if (now - myLastChargeCheck < 1000) {
211  return true;
212  } else if (myRescueAction != RESCUEACTION_NONE && (currentSoC < myEmptySoC || currentSoC < NUMERICAL_EPS)) {
213 
214  // vehicle has to stop at the end of the because battery SoC is too low
215  double brakeGap = myVeh.getCarFollowModel().brakeGap(myVeh.getSpeed());
216  std::pair<const MSLane*, double> stopPos = myVeh.getLanePosAfterDist(brakeGap);
217  if (stopPos.first != nullptr) {
218  const MSLane* stopLane = (stopPos.first->isInternal()) ? stopPos.first->getNormalSuccessorLane() : stopPos.first;
219  double endPos = stopPos.second;
220  if (stopLane != stopPos.first) {
221  endPos = MIN2(POSITION_EPS, stopLane->getLength());
222  }
223  // remove possibly scheduled charging stop
224  if (myVeh.hasStops() && myVeh.getStop(0).chargingStation != nullptr) {
226  }
227 
228  // schedule the rescue stop
229  SUMOVehicleParameter::Stop rescueStop;
230  rescueStop.index = 0;
231  rescueStop.edge = stopLane->getEdge().getID();
232  rescueStop.lane = stopLane->getID();
233  rescueStop.startPos = MAX2(endPos - 2 * myHolder.getVehicleType().getLength(), 0.);
234  rescueStop.endPos = endPos;
235  rescueStop.parametersSet |= STOP_START_SET | STOP_END_SET;
236  WRITE_MESSAGEF(TL("Vehicle '%' wants to stop on lane % at pos % because of low battery charge % at time=%."), myHolder.getID(), rescueStop.lane, toString(rescueStop.endPos), toString(currentSoC), toString(SIMTIME));
237 
239  // remove vehicle from network
240  rescueStop.until = SUMOTime_MAX;
241  rescueStop.breakDown = true;
242  std::string errorMsg = "Could not insert the rescue stop.";
243  if (!myVeh.insertStop(0, rescueStop, "stationfinder:rescue", false, errorMsg)) {
244  WRITE_ERROR(errorMsg);
245  }
247  return true;
248  } else if (myRescueAction == RESCUEACTION_TOW) {
249  // wait next to the road and get teleported to a charging station
250  SUMOTime rescueTime = TIME2STEPS(myRescueTime);
251  rescueStop.duration = rescueTime;
252  rescueStop.parking = ParkingType::ONROAD;
253  rescueStop.jump = 0;
254  std::string errorMsg = "Could not insert the rescue stop.";
255  if (!myVeh.insertStop(0, rescueStop, "stationfinder:rescue", false, errorMsg)) {
256  WRITE_ERROR(errorMsg);
257  }
261  return true;
262  }
263  }
264  } else if (myChargingStation == nullptr &&
266  now - myLastSearch >= myRepeatInterval && !myHolder.isStopped()))) {
267  // check if a charging stop is already planned without the device, otherwise reroute inside this device
268  if (!alreadyPlannedCharging() && now > myHolder.getDeparture()) {
270  }
271  myUpdateSoC = currentSoC;
272  }
274  return true;
275 }
276 
277 
278 bool
280  return true;
281 }
282 
283 
284 void
286  const double /* frontOnLane */,
287  const double /* timeOnLane */,
288  const double /* meanSpeedFrontOnLane */,
289  const double /* meanSpeedVehicleOnLane */,
290  const double /* travelledDistanceFrontOnLane */,
291  const double /* travelledDistanceVehicleOnLane */,
292  const double /* meanLengthOnLane */) {
293 
294  // called by meso (see MSMeanData_Emissions::MSLaneMeanDataValues::notifyMoveInternal)
295 }
296 
297 
299 MSDevice_StationFinder::findChargingStation(SUMOAbstractRouter<MSEdge, SUMOVehicle>& /*router*/, double expectedConsumption, StoppingPlaceParamMap_t& scores, bool constrainTT, bool skipVisited, bool skipOccupied) {
300  MSChargingStation* minStation = nullptr;
301  std::vector<StoppingPlaceVisible> candidates;
302  const StoppingPlaceMemory* chargingMemory = myVeh.getChargingMemory();
303  if (chargingMemory == nullptr) {
304  skipVisited = false;
305  }
306  const SUMOTime stoppingPlaceMemory = TIME2STEPS(getWeight(myHolder, "memory", 600));
307  for (const auto& stop : MSNet::getInstance()->getStoppingPlaces(SUMO_TAG_CHARGING_STATION)) {
308  MSChargingStation* cs = static_cast<MSChargingStation*>(stop.second);
309  if (cs->getEfficency() < NUMERICAL_EPS || cs->getChargingPower(false) < NUMERICAL_EPS) {
310  continue;
311  }
312  if (cs->getParkingArea() != nullptr && !cs->getParkingArea()->accepts(&myVeh)) {
313  // skip stations where the linked parking area does not grant access to the device holder
314  continue;
315  }
316  if (skipOccupied && freeSpaceAtChargingStation(cs) < 1.) {
317  continue;
318  }
319  if (skipVisited && chargingMemory->sawBlockedStoppingPlace(cs, false) > 0 && SIMSTEP - chargingMemory->sawBlockedStoppingPlace(cs, false) < stoppingPlaceMemory) {
320  // skip recently visited
321  continue;
322  }
323  if (constrainTT && myMaxEuclideanDistance > 0 && stop.second->getLane().geometryPositionAtOffset(stop.second->getBeginLanePosition()).distanceTo2D(myHolder.getPosition()) > myMaxEuclideanDistance) {
324  // skip probably too distant charging stations
325  continue;
326  }
327  candidates.push_back({cs, false});
328  }
329  ConstMSEdgeVector newRoute;
330  scores["expectedConsumption"] = expectedConsumption;
331  std::vector<double> probs(candidates.size(), 1.);
332  bool newDestination;
333  myCheckValidity = constrainTT;
334  MSStoppingPlace* bestCandidate = reroute(candidates, probs, myHolder, newDestination, newRoute, scores);
335  myCheckValidity = true;
336  minStation = dynamic_cast<MSChargingStation*>(bestCandidate);
337  return minStation;
338 }
339 
340 
341 bool
344  if (myBattery->getActualBatteryCapacity() < expectedConsumption) {
347  StoppingPlaceParamMap_t scores = {};
348  MSChargingStation* cs = findChargingStation(router, expectedConsumption, scores);
349  if (cs != nullptr) {
350  // integrate previously planned stops which do not have charging facilities
351  myChargingStation = cs;
353  stopPar.chargingStation = cs->getID();
354  if (cs->getParkingArea() != nullptr) {
355  stopPar.parkingarea = cs->getParkingArea()->getID();
357  }
358  stopPar.edge = cs->getLane().getEdge().getID();
359  stopPar.lane = cs->getLane().getID();
360  stopPar.duration = TIME2STEPS(expectedConsumption / (cs->getChargingPower(false) * cs->getEfficency()));
361  if (myReplacePlannedStop > 0) {
362  // "reuse" a previously planned stop (stop at charging station instead of a different stop)
363  // what if the charging station is skipped due to long waiting time?
365  // compare the distance to the original target
366  if (scores["distfrom"] < myDistanceToOriginalStop /*actualDist < myDistanceToOriginalStop*/) {
367  // compute the arrival time at the original stop
368  const SUMOTime timeToOriginalStop = TIME2STEPS(scores["timefrom"]);
369  const SUMOTime originalUntil = myHolder.getNextStopParameter()->until;
370  if (timeToOriginalStop + myLastSearch < originalUntil) {
371  const SUMOTime delta = originalUntil - (timeToOriginalStop + myLastSearch);
372  stopPar.until = timeToOriginalStop + myLastSearch + (SUMOTime)((double)delta * MIN2(myReplacePlannedStop, 1.));
373  if (myReplacePlannedStop > 1.) {
375  }
376  // optionally implement a charging strategy by adjusting the accepted charging rates
378  // the charging strategy should actually only be computed at the arrival at the charging station
379  implementChargingStrategy(myLastSearch + TIME2STEPS(scores["timeto"]), stopPar.until, expectedConsumption, cs);
380  }
381  }
382  }
383  }
384  }
385  stopPar.startPos = cs->getBeginLanePosition();
386  stopPar.endPos = cs->getEndLanePosition();
387  std::string errorMsg;
388 #ifdef DEBUG_STATIONFINDER_REROUTE
389  std::ostringstream os;
390  const ConstMSEdgeVector edgesBefore = myVeh.getRoute().getEdges();
391  for (auto edge : edgesBefore) {
392  os << edge->getID() << " ";
393  }
394  std::cout << "MSDevice_StationFinder::rerouteToChargingStation: \n\tRoute before scheduling the charging station: " << os.str() << "\n";
395 #endif
396  if ((replace && !myVeh.replaceStop(0, stopPar, "stationfinder:search", false, errorMsg)) || (!replace && !myVeh.insertStop(0, stopPar, "stationfinder:search", false, errorMsg))) {
397  WRITE_MESSAGE(TLF("Problem with inserting the charging station stop for vehicle %.", myHolder.getID()));
398  WRITE_ERROR(errorMsg);
399  }
400 
401 #ifdef DEBUG_STATIONFINDER_REROUTE
402  std::ostringstream os2;
403  const ConstMSEdgeVector edgesAfter = myVeh.getRoute().getEdges();
404  for (auto edge : edgesAfter) {
405  os2 << edge->getID() << " ";
406  }
407  std::cout << "\tRoute after scheduling the charging station: " << os2.str() << "\n";
408 #endif
411 #ifdef DEBUG_STATIONFINDER_REROUTE
412  std::cout << "\tVehicle " << myHolder.getID() << " gets rerouted to charging station " << cs->getID() << " on edge " << stopPar.edge << " at time " << SIMTIME << "\n";
413 #endif
414  return true;
415  }
417  WRITE_MESSAGEF(TL("Vehicle '%' wants to charge at time=% but does not find any charging station nearby."), myHolder.getID(), toString(SIMTIME));
418  }
419  return false;
420 }
421 
422 
423 SUMOTime
425  // find closest charging station
427  double expectedConsumption = MIN2(estimateConsumption(nullptr, true, STEPS2TIME(myVeh.getStops().front().pars.duration)) * myReserveFactor, myBattery->getMaximumBatteryCapacity() * myTargetSoC);
428  StoppingPlaceParamMap_t scores = {};
429  MSChargingStation* cs = findChargingStation(router, expectedConsumption, scores, false, false, true);
430  if (cs == nullptr) {
431  // continue waiting if all charging stations are occupied
432 #ifdef DEBUG_STATIONFINDER_RESCUE
433  std::cout << "MSDevice_StationFinder::teleportToChargingStation: No charging station available to teleport the broken-down vehicle " << myHolder.getID() << " to at time " << SIMTIME << ".\n.";
434 #endif
435  // remove the vehicle if teleport to a charging station fails
436  if (myHolder.isStopped()) {
437  MSStop& currentStop = myHolder.getNextStop();
438  currentStop.duration += DELTA_T;
439  SUMOVehicleParameter::Stop& stopPar = const_cast<SUMOVehicleParameter::Stop&>(currentStop.pars);
440  stopPar.jump = -1;
441  stopPar.breakDown = true;
443  WRITE_WARNINGF(TL("There is no charging station available to teleport the vehicle '%' to at time=%. Thus the vehicle will be removed."), myHolder.getID(), toString(SIMTIME));
444  }
445 #ifdef DEBUG_STATIONFINDER_RESCUE
446  else {
447 #ifdef DEBUG_STATIONFINDER_RESCUE
448  std::cout << "MSDevice_StationFinder::teleportToChargingStation: Rescue stop of " << myHolder.getID() << " ended prematurely before regular end at " << SIMTIME << ".\n.";
449 #endif
450  }
451 #endif
452  return myRepeatInterval;
453  }
454 
455  // teleport to the charging station, stop there for charging
456  myChargingStation = cs;
458  stopPar.chargingStation = cs->getID();
459  if (cs->getParkingArea() != nullptr) {
460  stopPar.parkingarea = cs->getParkingArea()->getID();
462  }
463  stopPar.edge = cs->getLane().getEdge().getID();
464  stopPar.lane = cs->getLane().getID();
465  stopPar.startPos = cs->getBeginLanePosition();
466  stopPar.endPos = cs->getEndLanePosition();
467  stopPar.duration = TIME2STEPS(expectedConsumption / (cs->getChargingPower(false) * cs->getEfficency()));
468  std::string errorMsg;
469  if (!myVeh.insertStop(1, stopPar, "stationfinder:search", true, errorMsg)) {
470  WRITE_ERROR(errorMsg);
471  }
473  myRescueCommand = nullptr;
474  return 0;
475 }
476 
477 
478 double
479 MSDevice_StationFinder::estimateConsumption(const MSEdge* target, const bool includeEmptySoC, const double stopDiscount) const {
480  const SUMOTime now = SIMSTEP;
482  const ConstMSEdgeVector& route = myHolder.getRoute().getEdges();
483  ConstMSEdgeVector::const_iterator targetIt = (target == nullptr) ? route.end() : std::find(route.begin(), route.end(), target) + 1;
484  const ConstMSEdgeVector remainingRoute(route.begin() + myHolder.getRoutePosition(), targetIt);
485  const double remainingTime = router.recomputeCosts(remainingRoute, &myHolder, now);
486  if (now > myHolder.getDeparture()) {
487  const double totalConsumption = myBattery->getTotalConsumption();
488  double expectedConsumption = 0.;
489  double passedTime = STEPS2TIME(now - myHolder.getDeparture());
490  if (totalConsumption > 0. && passedTime - stopDiscount > DEFAULT_CONSUMPTION_ESTIMATE_HISTORY) {
491  expectedConsumption = totalConsumption / (passedTime - stopDiscount) * remainingTime;
492  } else {
493  // fallback consumption rate for vehicles starting with low battery
494  const double speed = MIN2(myHolder.getMaxSpeed(), myHolder.getLane()->getSpeedLimit());
495  EnergyParams* const params = myHolder.getEmissionParameters();
497  speed * 0.8, 0., 0., params) * (remainingTime - passedTime);
498  }
499  if (includeEmptySoC) {
501  }
503  return expectedConsumption;
504  }
505  return 0.;
506 }
507 
508 
509 double
512 }
513 
514 
515 bool
517  if (myChargingStation == nullptr) {
518  auto stops = myHolder.getStops();
519  for (auto stop : stops) {
520  if (stop.chargingStation != nullptr) {
521  // compare whether we'll make it there without intermediate charging
522  double expectedConsumption = estimateConsumption(*stop.edge);
523  if (myBattery->getActualBatteryCapacity() < expectedConsumption) {
524  myChargingStation = stop.chargingStation;
525  return true;
526  }
527  }
528  }
529  }
530  return false;
531 }
532 
533 
534 void
536  if (myRescueAction == RESCUEACTION_TOW && myRescueCommand == nullptr) {
538  }
539 }
540 
541 
542 void
546  }
547 }
548 
549 
550 SUMOTime
552  if (myChargeLimits.size() > 0 && myChargeLimits.begin()->first < currentTime - DELTA_T) {
553  myChargeLimits.clear();
554  }
555  if (myChargeLimits.size() > 0) {
556  double chargeLimit = myChargeLimits.begin()->second;
557  myBattery->setChargeLimit(chargeLimit);
558  if (chargeLimit < 0) {
559  WRITE_MESSAGEF(TL("The charging rate limit of vehicle '%' is lifted at time=%"), myHolder.getID(), STEPS2TIME(SIMSTEP));
560  } else {
561  WRITE_MESSAGEF(TL("The charging rate of vehicle '%' is limited to % at time=%"), myHolder.getID(), chargeLimit, STEPS2TIME(SIMSTEP));
562  }
563  myChargeLimits.erase(myChargeLimits.begin());
564  }
565  if (myChargeLimits.size() == 0) {
567  myChargeLimitCommand = nullptr;
568  return 0;
569  } else {
570  return myChargeLimits.begin()->first - currentTime;
571  }
572 }
573 
574 
575 void
576 MSDevice_StationFinder::implementChargingStrategy(SUMOTime begin, SUMOTime end, const double plannedCharge, const MSChargingStation* cs) {
577  myChargeLimits.clear();
579  const double balancedCharge = plannedCharge / STEPS2TIME(end - begin);
580  myChargeLimits.push_back({ begin, balancedCharge });
581  myChargeLimits.push_back({ end, -1});
582  } else { // CHARGINGSTRATEGY_LATEST
583  SUMOTime expectedDuration = myBattery->estimateChargingDuration(plannedCharge, cs->getChargingPower(false) * cs->getEfficency());
584  if (end - expectedDuration > begin) {
585  myChargeLimits.push_back({ begin, 0 });
586  myChargeLimits.push_back({ end - expectedDuration, -1 });
587  }
588  }
589  if (myChargeLimits.size() > 0) {
592  }
593 }
594 
595 
596 void
598  if (tripinfoOut != nullptr && myChargingStation != nullptr) {
599  tripinfoOut->openTag("stationfinder");
600  tripinfoOut->writeAttr("chargingStation", myChargingStation->getID());
601  tripinfoOut->closeTag();
602  }
603 }
604 
605 
606 std::string
607 MSDevice_StationFinder::getParameter(const std::string& key) const {
608  if (key == "chargingStation") { // eventually abstract with enum
609  return (myChargingStation == nullptr) ? "" : myChargingStation->getID();
610  } else if (key == "batteryNeed") {
612  }
613  throw InvalidArgument(TLF("Parameter '%' is not supported for device of type '%'", key, deviceName()));
614 }
615 
616 
617 bool
618 MSDevice_StationFinder::evaluateCustomComponents(SUMOVehicle& /* veh */, double /* brakeGap */, bool /* newDestination */,
619  MSStoppingPlace* alternative, double /* occupancy */, double /* prob */,
621  StoppingPlaceParamMap_t& stoppingPlaceValues,
622  ConstMSEdgeVector& /* newRoute */, ConstMSEdgeVector& /* stoppingPlaceApproach */,
623  StoppingPlaceParamMap_t& /* maxValues */, StoppingPlaceParamMap_t& addInput) {
624  // estimated waiting time and charging time
625  MSChargingStation* cs = dynamic_cast<MSChargingStation*>(alternative);
626  double parkingCapacity = (cs->getParkingArea() != nullptr) ? cs->getParkingArea()->getCapacity() : (cs->getEndLanePosition() - cs->getBeginLanePosition()) / myHolder.getVehicleType().getParameter().length;
627  double freeParkingCapacity = freeSpaceAtChargingStation(cs);
628  stoppingPlaceValues["waitingTime"] = (freeParkingCapacity < 1.) ? DEFAULT_AVG_WAITING_TIME / parkingCapacity : 0.;
629  stoppingPlaceValues["chargingTime"] = STEPS2TIME(cs->getChargeDelay()) + addInput["expectedConsumption"] / cs->getChargingPower(false);
630  return true;
631 }
632 
633 
634 bool
636  if (stoppingPlaceValues["timeto"] > STEPS2TIME(myRadius)) {
637  return false;
638  }
639  return true;
640 }
641 
642 
643 bool
645  return true;
646 }
647 
648 
650  return MSRoutingEngine::getRouterTT(veh.getRNGIndex(), veh.getVClass(), prohibited);
651 }
652 
653 
654 double
656  MSChargingStation* cs = dynamic_cast<MSChargingStation*>(stoppingPlace);
657  if (cs->getParkingArea() != nullptr) {
658  return cs->getParkingArea()->getOccupancy();
659  }
661 }
662 
663 
664 double
666  MSChargingStation* cs = dynamic_cast<MSChargingStation*>(stoppingPlace);
667  if (cs->getParkingArea() != nullptr) {
668  return cs->getParkingArea()->getLastStepOccupancy();
669  }
671 }
672 
673 
674 double
676  MSChargingStation* cs = dynamic_cast<MSChargingStation*>(stoppingPlace);
677  if (cs->getParkingArea() != nullptr) {
678  return cs->getParkingArea()->getCapacity();
679  }
681 }
682 
683 
684 void
686  veh.rememberBlockedChargingStation(stoppingPlace, blocked);
687 }
688 
689 
690 void
692  veh.rememberChargingStationScore(place, score);
693 }
694 
695 
696 void
699 }
700 
701 
702 SUMOTime
704  return veh.sawBlockedChargingStation(place, local);
705 }
706 
707 
708 int
710  return 0;
711 }
712 
713 
714 void
716 }
717 
718 
719 /****************************************************************************/
long long int SUMOTime
Definition: GUI.h:35
#define DEFAULT_CONSUMPTION_ESTIMATE_HISTORY
#define DEFAULT_SOC_INTERVAL
#define DEFAULT_AVG_WAITING_TIME
#define DEFAULT_CHARGINGSTATION_VIEW_DIST
std::vector< const MSEdge * > ConstMSEdgeVector
Definition: MSEdge.h:74
std::vector< MSEdge * > MSEdgeVector
Definition: MSEdge.h:73
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:296
#define WRITE_MESSAGEF(...)
Definition: MsgHandler.h:298
#define WRITE_ERRORF(...)
Definition: MsgHandler.h:305
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:297
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:304
#define TL(string)
Definition: MsgHandler.h:315
#define TLF(string,...)
Definition: MsgHandler.h:317
SUMOTime DELTA_T
Definition: SUMOTime.cpp:38
#define STEPS2TIME(x)
Definition: SUMOTime.h:55
#define SIMSTEP
Definition: SUMOTime.h:61
#define SUMOTime_MAX
Definition: SUMOTime.h:34
#define SIMTIME
Definition: SUMOTime.h:62
#define TIME2STEPS(x)
Definition: SUMOTime.h:57
const int STOP_START_SET
const int STOP_END_SET
@ SUMO_TAG_CHARGING_STATION
A Charging Station.
@ SUMO_ATTR_PROPULSIONEFFICIENCY
Propulsion efficiency.
T MIN2(T a, T b)
Definition: StdDefs.h:76
T MAX2(T a, T b)
Definition: StdDefs.h:82
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:46
An upper class for objects with additional parameters.
Definition: EnergyParams.h:43
double getDouble(SumoXMLAttr attr) const
bool replaceStop(int nextStopIndex, SUMOVehicleParameter::Stop stop, const std::string &info, bool teleport, std::string &errorMsg)
const std::list< MSStop > & getStops() const
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
bool hasStops() const
Returns whether the vehicle has to stop somewhere.
MSStop & getStop(int nextStopIndex)
bool insertStop(int nextStopIndex, SUMOVehicleParameter::Stop stop, const std::string &info, bool teleport, std::string &errorMsg)
const StoppingPlaceMemory * getChargingMemory() const
const MSRoute & getRoute() const
Returns the current route.
bool abortNextStop(int nextStopIndex=0)
deletes the next stop at the given index if it exists
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 getChargingPower(bool usingFuel) const
Get charging station's charging power.
SUMOTime getChargeDelay() const
Get Charge Delay.
double getEfficency() const
Get efficiency of the charging station.
const MSParkingArea * getParkingArea() const
Get the parking area the charging station is placed on.
double getActualBatteryCapacity() const
Get the actual vehicle's Battery Capacity in Wh.
void setChargeLimit(const double limit)
Set (temporary) charge limit.
double getMaximumBatteryCapacity() const
Get the total vehicle's Battery Capacity in Wh.
SUMOTime estimateChargingDuration(const double toCharge, const double csPower) const
Estimate the charging duration given the current battery state.
double getTotalConsumption() const
Get total consumption.
double getEnergyCharged() const
Get charged energy.
std::string getChargingStationID() const
Get current Charging Station ID.
double myUpdateSoC
SoC the last time the station finder algorithm was run completely.
void resetStoppingPlaceScores(SUMOVehicle &veh) override
forget all stopping place score for this vehicle
void notifyMoveInternal(const SUMOTrafficObject &veh, const double frontOnLane, const double timeOnLane, const double meanSpeedFrontOnLane, const double meanSpeedVehicleOnLane, const double travelledDistanceFrontOnLane, const double travelledDistanceVehicleOnLane, const double meanLengthOnLane) override
Internal notification about the vehicle moves, see MSMoveReminder::notifyMoveInternal()
void rememberBlockedStoppingPlace(SUMOVehicle &veh, const MSStoppingPlace *stoppingPlace, bool blocked) override
store the blocked stopping place in the vehicle
WrappingCommand< MSDevice_StationFinder > * myRescueCommand
The command responsible for rescue actions.
void implementChargingStrategy(SUMOTime begin, SUMOTime end, const double plannedCharge, const MSChargingStation *cs)
MSDevice_StationFinder(SUMOVehicle &holder)
Constructor.
ChargingStrategy myChargingStrategy
The chosen charging strategy.
SUMOTime teleportToChargingStation(const SUMOTime currentTime)
search for a charging station and teleport the vehicle there as a rescue measure
double myDistanceToOriginalStop
The distance in meters to the original stop replaced by the charging stop (models charging close to t...
MSVehicle & myVeh
myHolder cast to needed type
double getStoppingPlaceOccupancy(MSStoppingPlace *stoppingPlace) override
Return the number of occupied places of the StoppingPlace.
MSStoppingPlace * myChargingStation
To which station we are currently travelling.
WrappingCommand< MSDevice_StationFinder > * myChargeLimitCommand
The command responsible for limiting the charging rate (~ implement charging strategies)
static void insertOptions(OptionsCont &oc)
Inserts MSDevice_StationFinder-options.
int getNumberStoppingPlaceReroutes(SUMOVehicle &veh) override
ask how many times already the vehicle has been rerouted to another stopping place
double myTargetSoC
The target state of charge where the vehicle stops charging.
const std::string deviceName() const override
return the name for this type of device
std::string getParameter(const std::string &key) const override
try to retrieve the given parameter from this device. Throw exception for unsupported key
bool rerouteToChargingStation(bool replace=false)
reroute to a charging station
double myRescueTime
The time to wait for a rescue vehicle in case the battery is empty.
SUMOTime myLastChargeCheck
Last time the SoC was checked.
static void buildVehicleDevices(SUMOVehicle &v, std::vector< MSVehicleDevice * > &into)
Build devices for the given vehicle, if needed.
void initRescueCommand()
create the event command for teleporting in case of brake-down
bool useStoppingPlace(MSStoppingPlace *stoppingPlace) override
Whether the stopping place should be included in the search (can be used to add an additional filter)
double getLastStepStoppingPlaceOccupancy(MSStoppingPlace *stoppingPlace) override
Return the number of occupied places of the StoppingPlace from the previous time step.
double getStoppingPlaceCapacity(MSStoppingPlace *stoppingPlace) override
Return the number of places the StoppingPlace provides.
void rememberStoppingPlaceScore(SUMOVehicle &veh, MSStoppingPlace *place, const std::string &score) override
store the stopping place score in the vehicle
SUMOTime myWaitForCharge
Accepted waiting time at the charging station before a place becomes available.
SUMOTime myLastSearch
Last time charging stations have been searched.
void setNumberStoppingPlaceReroutes(SUMOVehicle &veh, int value) override
update the number of reroutes for the vehicle
SUMOTime sawBlockedStoppingPlace(SUMOVehicle &veh, MSStoppingPlace *place, bool local) override
ask the vehicle when it has seen the stopping place
double mySearchSoC
The state of charge at which the vehicle starts looking for charging stations.
SUMOTime myArrivalAtChargingStation
Arrival time in the vicinity of the target charging station (to track the waiting time before accessi...
double myEmptySoC
The state of charge threshold below which rescue mode is activated.
double myMaxEuclideanDistance
The maximum euclidean distance between the vehicle and the charging station (-1 deactivates the condi...
bool validComponentValues(StoppingPlaceParamMap_t &stoppingPlaceValues) override
Whether the stopping place should be discarded due to its results from the component evaluation.
bool notifyIdle(SUMOTrafficObject &veh) override
Computes idling emission values and adds them to the emission sums.
void generateOutput(OutputDevice *tripinfoOut) const override
Called on writing tripinfo output.
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouter(SUMOVehicle &veh, const MSEdgeVector &prohibited) override
Provide the router to use (MSNet::getRouterTT or MSRoutingEngine)
MSDevice_Battery * myBattery
The corresponding battery device.
MSChargingStation * findChargingStation(SUMOAbstractRouter< MSEdge, SUMOVehicle > &router, double expectedConsumption, StoppingPlaceParamMap_t &scores, bool constrainTT=true, bool skipVisited=true, bool skipOccupied=false)
central search function for close charging stations
bool alreadyPlannedCharging()
adopt a planned charging stop outside of the device
double freeSpaceAtChargingStation(MSChargingStation *cs) const
compute the free space at a charging station
std::vector< std::pair< SUMOTime, double > > myChargeLimits
The next charging rates to set via myChargingRateCommand.
SUMOTime myRadius
The max travel time to the next charging station.
SearchState mySearchState
The current state of the charging search (remember for decision logic)
SUMOTime myRepeatInterval
Time interval to search again for a charging station if the first attempt failed.
bool evaluateCustomComponents(SUMOVehicle &veh, double brakeGap, bool newDestination, MSStoppingPlace *alternative, double occupancy, double prob, SUMOAbstractRouter< MSEdge, SUMOVehicle > &router, StoppingPlaceParamMap_t &stoppingPlaceValues, ConstMSEdgeVector &newRoute, ConstMSEdgeVector &stoppingPlaceApproach, StoppingPlaceParamMap_t &maxValues, StoppingPlaceParamMap_t &addInput) override
Compute some custom target function components.
SUMOTime updateChargeLimit(const SUMOTime currentTime)
update the maximum charge rate of the battery to simulate charging strategies
double myReplacePlannedStop
The share of stopping time a charging stop should take from the next regulr (non-charging) stop under...
RescueAction myRescueAction
What to do when the state of charge gets very low.
bool notifyMove(SUMOTrafficObject &veh, double oldPos, double newPos, double newSpeed) override
Computes current emission values and adds them to their sums.
double myReserveFactor
The safety buffer when calculating expected consumption.
void initChargeLimitCommand()
create the event command for changing charging rates
double estimateConsumption(const MSEdge *target=nullptr, const bool includeEmptySoC=true, const double stopDiscount=0.) const
estimate the energy needed for the planned route / up to a target edge
static void insertDefaultAssignmentOptions(const std::string &deviceName, const std::string &optionsTopic, OptionsCont &oc, const bool isPerson=false)
Adds common command options that allow to assign devices to vehicles.
Definition: MSDevice.cpp:155
static bool equippedByDefaultAssignmentOptions(const OptionsCont &oc, const std::string &deviceName, DEVICEHOLDER &v, bool outputOptionSet, const bool isPerson=false)
Determines whether a vehicle should get a certain device.
Definition: MSDevice.h:195
A road/street connecting two junctions.
Definition: MSEdge.h:77
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
Representation of a lane in the micro simulation.
Definition: MSLane.h:84
const MSLane * getNormalSuccessorLane() const
get normal lane following this internal lane, for normal lanes, the lane itself is returned
Definition: MSLane.cpp:3151
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
Definition: MSLane.h:584
double getLength() const
Returns the lane's length.
Definition: MSLane.h:598
MSEdge & getEdge() const
Returns the lane's edge.
Definition: MSLane.h:756
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:184
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition: MSNet.h:471
int getCapacity() const
Returns the area capacity.
bool parkOnRoad() const
whether vehicles park on the road
bool accepts(MSBaseVehicle *veh) const
Return the parking accepts the vehicle (due to its given badges)
int getLastStepOccupancy() const
Returns the area occupancy at the end of the last simulation step.
int getOccupancy() const
Returns the area occupancy.
const ConstMSEdgeVector & getEdges() const
Definition: MSRoute.h:124
static MSVehicleRouter & getRouterTT(const int rngIndex, SUMOVehicleClass svc, const MSEdgeVector &prohibited=MSEdgeVector())
return the vehicle router instance
Definition: MSStop.h:44
MSStoppingPlace * chargingStation
(Optional) charging station if one is assigned to the stop
Definition: MSStop.h:60
SUMOTime duration
The stopping duration.
Definition: MSStop.h:67
const SUMOVehicleParameter::Stop pars
The stop parameter.
Definition: MSStop.h:65
A lane area vehicles can halt at.
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.
double getLastFreePos(const SUMOVehicle &forVehicle, double brakePos=0) const
Returns the last free position on this stop.
MSStoppingPlace * reroute(std::vector< StoppingPlaceVisible > &stoppingPlaceCandidates, const std::vector< double > &probs, SUMOVehicle &veh, bool &newDestination, ConstMSEdgeVector &newRoute, StoppingPlaceParamMap_t &scores, const MSEdgeVector &closedEdges={})
main method to trigger the rerouting to the "best" StoppingPlace according to the custom evaluation f...
std::map< std::string, double > StoppingPlaceParamMap_t
double getWeight(SUMOVehicle &veh, const std::string param, const double defaultWeight, const bool warn=false)
read the value of a stopping place search param, e.g. a component weight factor
Abstract in-vehicle device.
SUMOVehicle & myHolder
The vehicle that stores the device.
Representation of a vehicle in the micro simulation.
Definition: MSVehicle.h:77
bool willStop() const
Returns whether the vehicle will stop on the current edge.
Definition: MSVehicle.cpp:1574
double getDistanceToPosition(double destPos, const MSLane *destLane) const
Definition: MSVehicle.cpp:6513
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 MSLane * getLane() const
Returns the lane the vehicle is on.
Definition: MSVehicle.h:584
const MSCFModel & getCarFollowModel() const
Returns the vehicle's car following model definition.
Definition: MSVehicle.h:977
double getMinGap() const
Get the free space in front of vehicles of this class.
SUMOEmissionClass getEmissionClass() const
Get this vehicle type's emission class.
double getLength() const
Get vehicle's length [m].
const SUMOVTypeParameter & getParameter() const
const std::string & getID() const
Returns the id.
Definition: Named.h:74
A storage for options typed value containers)
Definition: OptionsCont.h:89
void addDescription(const std::string &name, const std::string &subtopic, const std::string &description)
Adds a description for an option.
void doRegister(const std::string &name, Option *o)
Adds an option under the given name.
Definition: OptionsCont.cpp:76
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:60
Static storage of an output device and its base (abstract) implementation.
Definition: OutputDevice.h:61
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
Definition: OutputDevice.h:254
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
static double compute(const SUMOEmissionClass c, const EmissionType e, const double v, const double a, const double slope, const EnergyParams *param)
Returns the amount of the emitted pollutant given the vehicle type and state (in mg/s or ml/s for fue...
virtual double recomputeCosts(const std::vector< const E * > &edges, const V *const v, SUMOTime msTime, double *lengthp=nullptr) const
Representation of a vehicle, person, or container.
virtual int getRNGIndex() const =0
virtual bool isStopped() const =0
Returns whether the object is at a stop.
virtual double getMaxSpeed() const =0
Returns the object's maximum speed (minimum of technical and desired maximum speed)
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual SUMOVehicleClass getVClass() const =0
Returns the object's access class.
virtual Position getPosition(const double offset=0) const =0
Return current position (x/y, cartesian)
virtual int getRoutePosition() const =0
return index of edge within route
virtual const MSLane * getLane() const =0
Returns the lane the object is currently at.
double length
The physical vehicle length.
Representation of a vehicle.
Definition: SUMOVehicle.h:62
virtual const MSRoute & getRoute() const =0
Returns the current route.
virtual const std::list< MSStop > & getStops() const =0
virtual bool hasStops() const =0
Returns whether the vehicle has to stop somewhere.
virtual SUMOTime sawBlockedChargingStation(const MSStoppingPlace *cs, bool local) const =0
virtual SUMOTime getDeparture() const =0
Returns this vehicle's real departure time.
virtual MSStop & getNextStop()=0
virtual double getLength() const =0
Returns the vehicles's length.
virtual void rememberBlockedChargingStation(const MSStoppingPlace *cs, bool local)=0
virtual void resetChargingStationScores()=0
virtual void rememberChargingStationScore(const MSStoppingPlace *cs, const std::string &score)=0
virtual const SUMOVehicleParameter::Stop * getNextStopParameter() const =0
Returns parameters of the next stop or nullptr.
virtual EnergyParams * getEmissionParameters() const =0
Returns the vehicle's emission model parameter.
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.
bool breakDown
Whether this stop was triggered by a car failure / mechanical problem / lack of energy.
std::string chargingStation
(Optional) charging station if one is assigned to the stop
int parametersSet
Information for the output which parameter were set.
int index
at which position in the stops list
SUMOTime jump
transfer time if there shall be a jump from this stop to the next route edge
SUMOTime until
The time at which the vehicle may continue its journey.
double endPos
The stopping position end.
SUMOTime duration
The stopping duration.
SUMOTime sawBlockedStoppingPlace(const MSStoppingPlace *stoppingPlace, bool local) const
Get the time the StoppingPlace was confirmed to be blocked.
void deschedule()
Marks this Command as being descheduled.