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>
37 #include "MSRoutingEngine.h"
38 #include "MSDevice_Battery.h"
39 #include "MSDevice_StationFinder.h"
40 
41 //#define DEBUG_STATIONFINDER_RESCUE
42 //#define DEBUG_STATIONFINDER_REROUTE
43 
44 
45 // ===========================================================================
46 // static variables
47 // ===========================================================================
48 
49 
50 // ===========================================================================
51 // method definitions
52 // ===========================================================================
53 // ---------------------------------------------------------------------------
54 // static initialisation methods
55 // ---------------------------------------------------------------------------
56 void
58  insertDefaultAssignmentOptions("stationfinder", "Battery", oc);
59  oc.doRegister("device.stationfinder.rescueTime", new Option_String("1800", "TIME"));
60  oc.addDescription("device.stationfinder.rescueTime", "Battery", TL("Time to wait for a rescue vehicle on the road side when the battery is empty"));
61  oc.doRegister("device.stationfinder.rescueAction", new Option_String("remove"));
62  oc.addDescription("device.stationfinder.rescueAction", "Battery", TL("How to deal with a vehicle which has to stop due to low battery: [none, remove, tow]"));
63  oc.doRegister("device.stationfinder.reserveFactor", new Option_Float(1.1));
64  oc.addDescription("device.stationfinder.reserveFactor", "Battery", TL("Scale battery need with this factor to account for unexpected traffic situations"));
65  oc.doRegister("device.stationfinder.emptyThreshold", new Option_Float(0.05));
66  oc.addDescription("device.stationfinder.emptyThreshold", "Battery", TL("Battery percentage to go into rescue mode"));
67  oc.doRegister("device.stationfinder.radius", new Option_String("180", "TIME"));
68  oc.addDescription("device.stationfinder.radius", "Battery", TL("Search radius in travel time seconds"));
69  oc.doRegister("device.stationfinder.maxEuclideanDistance", new Option_String("2000", "FLOAT"));
70  oc.addDescription("device.stationfinder.maxEuclideanDistance", "Battery", TL("Euclidean search distance in meters"));
71  oc.doRegister("device.stationfinder.repeat", new Option_String("60", "TIME"));
72  oc.addDescription("device.stationfinder.repeat", "Battery", TL("When to trigger a new search if no station has been found"));
73  oc.doRegister("device.stationfinder.maxChargePower", new Option_Float(100000.));
74  oc.addDescription("device.stationfinder.maxChargePower", "Battery", TL("The maximum charging speed of the vehicle battery"));
75  oc.doRegister("device.stationfinder.chargeType", new Option_String("charging"));
76  oc.addDescription("device.stationfinder.chargeType", "Battery", TL("Type of energy transfer"));
77  oc.doRegister("device.stationfinder.waitForCharge", new Option_String("600", "TIME"));
78  oc.addDescription("device.stationfinder.waitForCharge", "Battery", TL("After this waiting time vehicle searches for a new station when the initial one is blocked"));
79  oc.doRegister("device.stationfinder.saturatedChargeLevel", new Option_Float(0.8));
80  oc.addDescription("device.stationfinder.saturatedChargeLevel", "Battery", TL("Target state of charge after which the vehicle stops charging"));
81  oc.doRegister("device.stationfinder.needToChargeLevel", new Option_Float(0.4));
82  oc.addDescription("device.stationfinder.needToChargeLevel", "Battery", TL("State of charge the vehicle begins searching for charging stations"));
83 }
84 
85 
86 void
87 MSDevice_StationFinder::buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into) {
89  if (equippedByDefaultAssignmentOptions(oc, "stationfinder", v, false)) {
90  into.push_back(new MSDevice_StationFinder(v));
91  }
92 }
93 
94 
95 // ---------------------------------------------------------------------------
96 // MSDevice_StationFinder-methods
97 // ---------------------------------------------------------------------------
99  : MSVehicleDevice(holder, "stationfinder_" + holder.getID()), myVeh(dynamic_cast<MSVehicle&>(holder)),
100  myBattery(nullptr), myChargingStation(nullptr), myRescueCommand(nullptr), myLastChargeCheck(0),
101  myCheckInterval(1000), myArrivalAtChargingStation(-1), myLastSearch(-1) {
103  myRescueTime = getFloatParam(holder, oc, "stationfinder.rescueTime", 1800.);
104  initRescueAction(holder, oc, "stationfinder.rescueAction", myRescueAction);
106  myReserveFactor = MAX2(1., getFloatParam(holder, oc, "stationfinder.reserveFactor", 1.1));
107  myEmptySoC = MAX2(0., MIN2(getFloatParam(holder, oc, "stationfinder.emptyThreshold", 5.), 1.));
108  myRadius = getTimeParam(holder, oc, "stationfinder.radius", 180000);
109  myMaxEuclideanDistance = getFloatParam(holder, oc, "stationfinder.maxEuclideanDistance", -1);
110  myRepeatInterval = getTimeParam(holder, oc, "stationfinder.repeat", 60000);
111  myMaxChargePower = getFloatParam(holder, oc, "stationfinder.maxChargePower", 80000.);
113  myWaitForCharge = getTimeParam(holder, oc, "stationfinder.waitForCharge", 600000);
114  myTargetSoC = MAX2(0., MIN2(getFloatParam(holder, oc, "stationfinder.saturatedChargeLevel", 80.), 1.));
115  mySearchSoC = MAX2(0., MIN2(getFloatParam(holder, oc, "stationfinder.needToChargeLevel", 40.), 1.));
116  if (mySearchSoC <= myEmptySoC) {
117  WRITE_WARNINGF(TL("Vehicle '%' searches for charging stations only in the rescue case due to search threshold % <= rescue threshold %."), myHolder.getID(), mySearchSoC, myEmptySoC);
118  }
120 }
121 
122 
124  // make the rescue command invalid if there is one
125  if (myRescueCommand != nullptr) {
127  }
128 }
129 
130 
131 bool
132 MSDevice_StationFinder::notifyMove(SUMOTrafficObject& veh, double /*oldPos*/, double /*newPos*/, double /*newSpeed*/) {
133  if (myBattery->getEnergyCharged() > 0. && myChargingStation != nullptr) {
134  // we have started charging thus can forget searched charging stations
135  myPassedChargingStations.clear();
137  myChargingStation = nullptr;
139  return true;
140  } else if (mySearchState == SEARCHSTATE_CHARGING) {
141  if (myBattery->getChargingStationID() == "") {
143  } else {
144  return true;
145  }
146  }
147  // check if the vehicle travels at most an edge length to the charging station after jump/teleport
149  return true;
150  }
151  const SUMOTime now = SIMSTEP;
152  if (myChargingStation != nullptr) {
154  // waited for too long, try another charging station
155  if (rerouteToChargingStation(true)) {
156  WRITE_MESSAGE(TLF("Rerouted vehicle '%' after waiting too long at the previous charging station at time=%.", veh.getID(), toString(SIMTIME)));
157  }
159  // remember when the vehicle arrived close to the target charging station
162  }
163  }
164  const double currentSoC = myBattery->getActualBatteryCapacity() / myBattery->getMaximumBatteryCapacity();
165  if (currentSoC > mySearchSoC || mySearchState == SEARCHSTATE_BROKEN_DOWN) {
166  // battery SoC is too high to look for charging facilities or the vehicle is already in rescue mode
167  return true;
168  }
169  // only check once per second
170  if (now - myLastChargeCheck < 1000) {
171  return true;
172  } else if (myRescueAction != RESCUEACTION_NONE && (currentSoC < myEmptySoC || currentSoC < NUMERICAL_EPS)) {
173 
174  // vehicle has to stop at the end of the because battery SoC is too low
175  double brakeGap = myVeh.getCarFollowModel().brakeGap(myVeh.getSpeed());
176  std::pair<const MSLane*, double> stopPos = myVeh.getLanePosAfterDist(brakeGap);
177  if (stopPos.first != nullptr) {
178  const MSLane* stopLane = (stopPos.first->isInternal()) ? stopPos.first->getNormalSuccessorLane() : stopPos.first;
179  double endPos = stopPos.second;
180  if (stopLane != stopPos.first) {
181  endPos = MIN2(POSITION_EPS, stopLane->getLength());
182  }
183  // remove possibly scheduled charging stop
184  if (myVeh.hasStops() && myVeh.getStop(0).chargingStation != nullptr) {
186  }
187 
188  // schedule the rescue stop
189  SUMOVehicleParameter::Stop rescueStop;
190  rescueStop.index = 0;
191  rescueStop.edge = stopLane->getEdge().getID();
192  rescueStop.lane = stopLane->getID();
193  rescueStop.startPos = MAX2(endPos - 2 * myHolder.getVehicleType().getLength(), 0.);
194  rescueStop.endPos = endPos;
195  rescueStop.parametersSet |= STOP_START_SET | STOP_END_SET;
196  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));
197 
199  // remove vehicle from network
200  rescueStop.until = SUMOTime_MAX;
201  rescueStop.breakDown = true;
202  std::string errorMsg = "Could not insert the rescue stop.";
203  if (!myVeh.insertStop(0, rescueStop, "stationfinder:rescue", false, errorMsg)) {
204  WRITE_ERROR(errorMsg);
205  }
207  return true;
208  } else if (myRescueAction == RESCUEACTION_TOW) {
209  // wait next to the road and get teleported to a charging station
210  SUMOTime rescueTime = TIME2STEPS(myRescueTime);
211  rescueStop.duration = rescueTime;
212  rescueStop.parking = ParkingType::ONROAD;
213  rescueStop.jump = 0;
214  std::string errorMsg = "Could not insert the rescue stop.";
215  if (!myVeh.insertStop(0, rescueStop, "stationfinder:rescue", false, errorMsg)) {
216  WRITE_ERROR(errorMsg);
217  }
221  return true;
222  }
223  }
224  } else if (myChargingStation == nullptr &&
226  // check if a charging stop is already planned without the device, otherwise reroute inside this device
227  if (!alreadyPlannedCharging() && now > myHolder.getDeparture()) {
229  }
230  myUpdateSoC = currentSoC;
231  }
233  return true;
234 }
235 
236 
237 bool
239  return true;
240 }
241 
242 
243 void
245  const double /* frontOnLane */,
246  const double /* timeOnLane */,
247  const double /* meanSpeedFrontOnLane */,
248  const double /* meanSpeedVehicleOnLane */,
249  const double /* travelledDistanceFrontOnLane */,
250  const double /* travelledDistanceVehicleOnLane */,
251  const double /* meanLengthOnLane */) {
252 
253  // called by meso (see MSMeanData_Emissions::MSLaneMeanDataValues::notifyMoveInternal)
254 }
255 
256 
258 MSDevice_StationFinder::findChargingStation(SUMOAbstractRouter<MSEdge, SUMOVehicle>& router, double expectedConsumption, bool constrainTT, bool skipVisited, bool skipOccupied) {
259  const MSEdge* const start = myHolder.getEdge();
260  double minTargetValue = std::numeric_limits<double>::max();
261  MSChargingStation* minStation = nullptr;
262  const ConstMSEdgeVector& route = myHolder.getRoute().getEdges();
263  // search for charging stations that can be reached in a certain travel time
264  const SUMOTime now = SIMSTEP;
265 
266  // first evaluate all routes from the current edge to all charging stations in bulk mode
267  std::map<MSChargingStation*, double> travelTimeToCharging;
268  double maxTT = STEPS2TIME(myRadius);
269  for (const auto& stop : MSNet::getInstance()->getStoppingPlaces(SUMO_TAG_CHARGING_STATION)) {
270  MSChargingStation* cs = static_cast<MSChargingStation*>(stop.second);
271  if (cs->getEfficency() < NUMERICAL_EPS) {
272  continue;
273  }
274  if (cs->getParkingArea() != nullptr && !cs->getParkingArea()->accepts(&myVeh)) {
275  // skip stations where the linked parking area does not grant access to the device holder
276  continue;
277  }
278  if (skipOccupied && freeSpaceAtChargingStation(cs) < 1.) {
279  continue;
280  }
281  if (skipVisited && std::find(myPassedChargingStations.begin(), myPassedChargingStations.end(), cs) != myPassedChargingStations.end()) {
282  // skip recently visited
283  continue;
284  }
285  if (constrainTT && myMaxEuclideanDistance > 0 && stop.second->getLane().geometryPositionAtOffset(stop.second->getBeginLanePosition()).distanceTo2D(myHolder.getPosition()) > myMaxEuclideanDistance) {
286  // skip probably too distant charging stations
287  continue;
288  }
289  const MSEdge* const csEdge = &stop.second->getLane().getEdge();
290  ConstMSEdgeVector routeTo;
291  if (router.compute(start, myHolder.getPositionOnLane(), csEdge, stop.second->getBeginLanePosition(), &myHolder, now, routeTo, true)) {
292  ConstMSEdgeVector routeFrom;
293  double time = router.recomputeCosts(routeTo, &myHolder, now) - csEdge->getMinimumTravelTime(&myHolder) * (csEdge->getLength() - cs->getBeginLanePosition()) / csEdge->getLength();
294  if (!constrainTT || time < maxTT) {
295  travelTimeToCharging.insert({ cs, time });
296  }
297  }
298  router.setBulkMode(true);
299  }
300  router.setBulkMode(false);
301  // now complete the routes with the stretch from a charging station to the destination
302  for (const auto& tt : travelTimeToCharging) {
303  MSChargingStation* cs = tt.first;
304  double parkingCapacity = (cs->getParkingArea() != nullptr) ? cs->getParkingArea()->getCapacity() : (cs->getEndLanePosition() - cs->getBeginLanePosition()) / myHolder.getVehicleType().getParameter().length;
305  double freeParkingCapacity = freeSpaceAtChargingStation(cs);
306  double waitingTime = (freeParkingCapacity < 1.) ? DEFAULT_AVG_WAITING_TIME / parkingCapacity : 0.; // TODO: create true waiting time function
307  double chargingTime = STEPS2TIME(cs->getChargeDelay()) + expectedConsumption / cs->getChargingPower(false);
308 
309  ConstMSEdgeVector routeFrom;
310  const MSEdge* const csEdge = &cs->getLane().getEdge();
311  if (csEdge == route.back() || router.compute(csEdge, route.back(), &myHolder, now, routeFrom, true)) {
312  double time = tt.second;
313  if (csEdge != route.back()) {
314  routeFrom.erase(routeFrom.begin()); // do no count charging station edge twice
315  time += router.recomputeCosts(routeFrom, &myHolder, now);
316  }
317  double targetValue = time + chargingTime + waitingTime / parkingCapacity;
318 
319 #ifdef DEBUG_STATIONFINDER_REROUTE
320  std::cout << "MSDevice_StationFinder::findChargingStation: CS " << cs->getID() << " targetValue " << targetValue << " travelTime " << time << " freeParkingCapacity " << freeParkingCapacity << " chargingTime " << chargingTime << "\n";
321 #endif
322  if (targetValue < minTargetValue) {
323  minTargetValue = targetValue;
324  minStation = cs;
325  }
326  }
327  }
328  return minStation;
329 }
330 
331 
332 bool
335  if (myBattery->getActualBatteryCapacity() < expectedConsumption) {
338  MSChargingStation* cs = findChargingStation(router, expectedConsumption);
339  if (cs != nullptr) {
340  // integrate previously planned stops which do not have charging facilities
341  myChargingStation = cs;
343  stopPar.chargingStation = cs->getID();
344  if (cs->getParkingArea() != nullptr) {
345  stopPar.parkingarea = cs->getParkingArea()->getID();
347  }
348  stopPar.edge = cs->getLane().getEdge().getID();
349  stopPar.lane = cs->getLane().getID();
350  stopPar.duration = TIME2STEPS(expectedConsumption / (cs->getChargingPower(false) * cs->getEfficency()));
351  stopPar.startPos = cs->getBeginLanePosition();
352  stopPar.endPos = cs->getEndLanePosition();
353  std::string errorMsg;
354 #ifdef DEBUG_STATIONFINDER_REROUTE
355  std::ostringstream os;
356  const ConstMSEdgeVector edgesBefore = myVeh.getRoute().getEdges();
357  for (auto edge : edgesBefore) {
358  os << edge->getID() << " ";
359  }
360  std::cout << "MSDevice_StationFinder::rerouteToChargingStation: \n\tRoute before scheduling the charging station: " << os.str() << "\n";
361 #endif
362  if ((replace && !myVeh.replaceStop(0, stopPar, "stationfinder:search", false, errorMsg)) || (!replace && !myVeh.insertStop(0, stopPar, "stationfinder:search", false, errorMsg))) {
363  WRITE_MESSAGE(TLF("Problem with inserting the charging station stop for vehicle %.", myHolder.getID()));
364  WRITE_ERROR(errorMsg);
365  }
366 #ifdef DEBUG_STATIONFINDER_REROUTE
367  std::ostringstream os2;
368  const ConstMSEdgeVector edgesAfter = myVeh.getRoute().getEdges();
369  for (auto edge : edgesAfter) {
370  os2 << edge->getID() << " ";
371  }
372  std::cout << "\tRoute after scheduling the charging station: " << os2.str() << "\n";
373 #endif
374  myPassedChargingStations.push_back(cs);
377 #ifdef DEBUG_STATIONFINDER_REROUTE
378  std::cout << "\tVehicle " << myHolder.getID() << " gets rerouted to charging station " << cs->getID() << " on edge " << stopPar.edge << " at time " << SIMTIME << "\n";
379 #endif
380  return true;
381  }
383  WRITE_MESSAGEF(TL("Vehicle '%' wants to charge at time=% but does not find any charging station nearby."), myHolder.getID(), toString(SIMTIME));
384  }
385  return false;
386 }
387 
388 
389 SUMOTime
391  // find closest charging station
393  double expectedConsumption = MIN2(estimateConsumption(nullptr, true, STEPS2TIME(myVeh.getStops().front().pars.duration)) * myReserveFactor, myBattery->getMaximumBatteryCapacity() * myTargetSoC);
394  MSChargingStation* cs = findChargingStation(router, expectedConsumption, false, false, true);
395  if (cs == nullptr) {
396  // continue waiting if all charging stations are occupied
397 #ifdef DEBUG_STATIONFINDER_RESCUE
398  std::cout << "MSDevice_StationFinder::teleportToChargingStation: No charging station available to teleport the broken-down vehicle " << myHolder.getID() << " to at time " << SIMTIME << ".\n.";
399 #endif
400  // remove the vehicle if teleport to a charging station fails
401  if (myHolder.isStopped()) {
402  MSStop& currentStop = myHolder.getNextStop();
403  currentStop.duration += DELTA_T;
404  SUMOVehicleParameter::Stop& stopPar = const_cast<SUMOVehicleParameter::Stop&>(currentStop.pars);
405  stopPar.jump = -1;
406  stopPar.breakDown = true;
408  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));
409  }
410 #ifdef DEBUG_STATIONFINDER_RESCUE
411  else {
412 #ifdef DEBUG_STATIONFINDER_RESCUE
413  std::cout << "MSDevice_StationFinder::teleportToChargingStation: Rescue stop of " << myHolder.getID() << " ended prematurely before regular end at " << SIMTIME << ".\n.";
414 #endif
415  }
416 #endif
417  return myRepeatInterval;
418  }
419 
420 
421  // teleport to the charging station, stop there for charging
422  myChargingStation = cs;
424  stopPar.chargingStation = cs->getID();
425  if (cs->getParkingArea() != nullptr) {
426  stopPar.parkingarea = cs->getParkingArea()->getID();
428  }
429  stopPar.edge = cs->getLane().getEdge().getID();
430  stopPar.lane = cs->getLane().getID();
431  stopPar.startPos = cs->getBeginLanePosition();
432  stopPar.endPos = cs->getEndLanePosition();
433  stopPar.duration = TIME2STEPS(expectedConsumption / (cs->getChargingPower(false) * cs->getEfficency()));
434  std::string errorMsg;
435  if (!myVeh.insertStop(1, stopPar, "stationfinder:search", true, errorMsg)) {
436  WRITE_ERROR(errorMsg);
437  }
438  myPassedChargingStations.push_back(cs);
440  myRescueCommand = nullptr;
441  return 0;
442 }
443 
444 
445 double
446 MSDevice_StationFinder::estimateConsumption(const MSEdge* target, const bool includeEmptySoC, const double stopDiscount) const {
447  const SUMOTime now = SIMSTEP;
449  const ConstMSEdgeVector& route = myHolder.getRoute().getEdges();
450  ConstMSEdgeVector::const_iterator targetIt = (target == nullptr) ? route.end() : std::find(route.begin(), route.end(), target) + 1;
451  const ConstMSEdgeVector remainingRoute(route.begin() + myHolder.getRoutePosition(), targetIt);
452  const double remainingTime = router.recomputeCosts(remainingRoute, &myHolder, now);
453  if (now > myHolder.getDeparture()) {
454  const double totalConsumption = myBattery->getTotalConsumption();
455  double expectedConsumption = 0.;
456  double passedTime = STEPS2TIME(now - myHolder.getDeparture());
457  if (totalConsumption > 0. && passedTime - stopDiscount > DEFAULT_CONSUMPTION_ESTIMATE_HISTORY) {
458  expectedConsumption = totalConsumption / (passedTime - stopDiscount) * remainingTime;
459  } else {
460  // fallback consumption rate for vehicles starting with low battery
461  const double speed = MIN2(myHolder.getMaxSpeed(), myHolder.getLane()->getSpeedLimit());
462  EnergyParams* const params = myHolder.getEmissionParameters();
464  speed * 0.8, 0., 0., params) * (remainingTime - passedTime);
465  }
466  if (includeEmptySoC) {
468  }
470  return expectedConsumption;
471  }
472  return 0.;
473 }
474 
475 
476 double
479 }
480 
481 
482 bool
484  if (myChargingStation == nullptr) {
485  auto stops = myHolder.getStops();
486  for (auto stop : stops) {
487  if (stop.chargingStation != nullptr) {
488  // compare whether we'll make it there without intermediate charging
489  double expectedConsumption = estimateConsumption(*stop.edge);
490  if (myBattery->getActualBatteryCapacity() < expectedConsumption) {
491  myChargingStation = stop.chargingStation;
492  return true;
493  }
494  }
495  }
496  }
497  return false;
498 }
499 
500 
501 void
503  if (myRescueAction == RESCUEACTION_TOW && myRescueCommand == nullptr) {
505  }
506 }
507 
508 
509 void
511  if (tripinfoOut != nullptr && myChargingStation != nullptr) {
512  tripinfoOut->openTag("stationfinder");
513  tripinfoOut->writeAttr("chargingStation", myChargingStation->getID());
514  tripinfoOut->closeTag();
515  }
516 }
517 
518 
519 std::string
520 MSDevice_StationFinder::getParameter(const std::string& key) const {
521  if (key == "chargingStation") { // eventually abstract with enum
522  return (myChargingStation == nullptr) ? "" : myChargingStation->getID();
523  } else if (key == "batteryNeed") {
525  }
526  throw InvalidArgument(TLF("Parameter '%' is not supported for device of type '%'", key, deviceName()));
527 }
528 
529 
530 void
531 MSDevice_StationFinder::initRescueAction(const SUMOVehicle& v, const OptionsCont& oc, const std::string& option, RescueAction& myAction) {
532  const std::string action = getStringParam(v, oc, option, "remove");
533  if (action == "remove") {
534  myAction = RESCUEACTION_REMOVE;
535  } else if (action == "tow") {
536  myAction = RESCUEACTION_TOW;
537  } else if (action == "none") {
538  myAction = RESCUEACTION_NONE;
539  } else {
540  WRITE_ERROR(TLF("Invalid % '%'.", option, action));
541  }
542 }
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
#define WRITE_WARNINGF(...)
Definition: MsgHandler.h:296
#define WRITE_MESSAGEF(...)
Definition: MsgHandler.h:298
#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 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.
double getMaximumBatteryCapacity() const
Get the total vehicle's Battery Capacity in Wh.
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.
MSChargingStation * findChargingStation(SUMOAbstractRouter< MSEdge, SUMOVehicle > &router, double expectedConsumption, bool constrainTT=true, bool skipVisited=true, bool skipOccupied=false)
central search function for close charging stations
void generateOutput(OutputDevice *tripinfoOut) const
Called on writing tripinfo output.
WrappingCommand< MSDevice_StationFinder > * myRescueCommand
The command responsible for rescue actions.
std::vector< MSChargingStation * > myPassedChargingStations
The memory of lastly visited charging stations during the search before being able to charge.
MSDevice_StationFinder(SUMOVehicle &holder)
Constructor.
std::string getParameter(const std::string &key) const
try to retrieve the given parameter from this device. Throw exception for unsupported key
SUMOTime teleportToChargingStation(const SUMOTime currentTime)
search for a charging station and teleport the vehicle there as a rescue measure
MSVehicle & myVeh
myHolder cast to needed type
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)
Internal notification about the vehicle moves, see MSMoveReminder::notifyMoveInternal()
bool notifyMove(SUMOTrafficObject &veh, double oldPos, double newPos, double newSpeed)
Computes current emission values and adds them to their sums.
MSStoppingPlace * myChargingStation
To which station we are currently travelling.
const std::string deviceName() const
return the name for this type of device
static void insertOptions(OptionsCont &oc)
Inserts MSDevice_StationFinder-options.
double myTargetSoC
The target state of charge where the vehicle stops charging.
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
SUMOTime myWaitForCharge
Accepted waiting time at the charging station before a place becomes available.
static void initRescueAction(const SUMOVehicle &v, const OptionsCont &oc, const std::string &option, RescueAction &myAction)
SUMOTime myLastSearch
Last time charging stations have been searched.
bool notifyIdle(SUMOTrafficObject &veh)
Computes idling emission values and adds them to the emission sums.
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...
MSDevice_Battery * myBattery
The corresponding battery device.
ChargeType myChargeType
The type of charging permitted by the battery (charging, bidirectional, battery exchange)
bool alreadyPlannedCharging()
adopt a planned charging stop outside of the device
double freeSpaceAtChargingStation(MSChargingStation *cs) const
compute the free space at a charging station
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.
double myMaxChargePower
The maximum charging speed of the vehicle battery in W.
RescueAction myRescueAction
What to do when the state of charge gets very low.
double myReserveFactor
The safety buffer when calculating expected consumption.
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 double getFloatParam(const SUMOVehicle &v, const OptionsCont &oc, const std::string &paramName, const double deflt, bool required=false)
Definition: MSDevice.cpp:206
static std::string getStringParam(const SUMOVehicle &v, const OptionsCont &oc, const std::string &paramName, const std::string &deflt, bool required=false)
Definition: MSDevice.cpp:182
static SUMOTime getTimeParam(const SUMOVehicle &v, const OptionsCont &oc, const std::string &paramName, const SUMOTime deflt, bool required=false)
Definition: MSDevice.cpp:230
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:203
A road/street connecting two junctions.
Definition: MSEdge.h:77
double getLength() const
return the length of the edge
Definition: MSEdge.h:662
double getMinimumTravelTime(const SUMOVehicle *const veh) const
returns the minimum travel time for the given vehicle
Definition: MSEdge.h:473
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:3130
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:182
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 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
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.
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:1568
double getDistanceToPosition(double destPos, const MSLane *destLane) const
Definition: MSVehicle.cpp:6488
std::pair< const MSLane *, double > getLanePosAfterDist(double distance) const
return lane and position along bestlanes at the given distance
Definition: MSVehicle.cpp:6471
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
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 void setBulkMode(const bool mode)
virtual bool compute(const E *from, const E *to, const V *const vehicle, SUMOTime msTime, std::vector< const E * > &into, bool silent=false)=0
Builds the route between the given edges using the minimum effort at the given time The definition of...
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.
virtual const MSEdge * getEdge() const =0
Returns the edge the object is currently at.
virtual double getPositionOnLane() const =0
Get the object's position along the lane.
double length
The physical vehicle length.
Representation of a vehicle.
Definition: SUMOVehicle.h:60
virtual const MSRoute & getRoute() const =0
Returns the current route.
virtual const std::list< MSStop > & getStops() const =0
virtual SUMOTime getDeparture() const =0
Returns this vehicle's real departure time.
virtual MSStop & getNextStop()=0
virtual EnergyParams * getEmissionParameters() const =0
Returns the vehicle's emission model parameter.
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.
void deschedule()
Marks this Command as being descheduled.