Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
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-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// 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>
28#include <microsim/MSStop.h>
39#include "MSRoutingEngine.h"
40#include "MSDevice_Battery.h"
42
43//#define DEBUG_STATIONFINDER_RESCUE
44//#define DEBUG_STATIONFINDER_REROUTE
45#define DEBUG_COND (myHolder.isSelected())
46
47
48// ===========================================================================
49// static variables
50// ===========================================================================
51
52
53// ===========================================================================
54// method definitions
55// ===========================================================================
56// ---------------------------------------------------------------------------
57// static initialisation methods
58// ---------------------------------------------------------------------------
59void
61 insertDefaultAssignmentOptions("stationfinder", "Battery", oc);
62 oc.doRegister("device.stationfinder.rescueTime", new Option_String("1800", "TIME"));
63 oc.addDescription("device.stationfinder.rescueTime", "Battery", TL("Time to wait for a rescue vehicle on the road side when the battery is empty"));
64 oc.doRegister("device.stationfinder.rescueAction", new Option_String("remove"));
65 oc.addDescription("device.stationfinder.rescueAction", "Battery", TL("How to deal with a vehicle which has to stop due to low battery: [none, remove, tow]"));
66 oc.doRegister("device.stationfinder.reserveFactor", new Option_Float(1.1));
67 oc.addDescription("device.stationfinder.reserveFactor", "Battery", TL("Scale battery need with this factor to account for unexpected traffic situations"));
68 oc.doRegister("device.stationfinder.emptyThreshold", new Option_Float(0.05));
69 oc.addDescription("device.stationfinder.emptyThreshold", "Battery", TL("Battery percentage to go into rescue mode"));
70 oc.doRegister("device.stationfinder.radius", new Option_String("180", "TIME"));
71 oc.addDescription("device.stationfinder.radius", "Battery", TL("Search radius in travel time seconds"));
72 oc.doRegister("device.stationfinder.maxEuclideanDistance", new Option_Float(-1));
73 oc.addDescription("device.stationfinder.maxEuclideanDistance", "Battery", TL("Euclidean search distance in meters (a negative value disables the restriction)"));
74 oc.doRegister("device.stationfinder.repeat", new Option_String("60", "TIME"));
75 oc.addDescription("device.stationfinder.repeat", "Battery", TL("When to trigger a new search if no station has been found"));
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.minOpportunityDuration", new Option_String("3600", "TIME"));
81 oc.addDescription("device.stationfinder.minOpportunityDuration", "Battery", TL("Only stops with a predicted duration of at least the given threshold are considered for opportunistic charging."));
82 oc.doRegister("device.stationfinder.saturatedChargeLevel", new Option_Float(0.8));
83 oc.addDescription("device.stationfinder.saturatedChargeLevel", "Battery", TL("Target state of charge after which the vehicle stops charging"));
84 oc.doRegister("device.stationfinder.needToChargeLevel", new Option_Float(0.4));
85 oc.addDescription("device.stationfinder.needToChargeLevel", "Battery", TL("State of charge the vehicle begins searching for charging stations"));
86 oc.doRegister("device.stationfinder.opportunisticChargeLevel", new Option_Float(0.));
87 oc.addDescription("device.stationfinder.opportunisticChargeLevel", "Battery", TL("State of charge below which the vehicle may look for charging opportunities along its planned stops"));
88 oc.doRegister("device.stationfinder.replacePlannedStop", new Option_Float(0.));
89 oc.addDescription("device.stationfinder.replacePlannedStop", "Battery", TL("Share of stopping time of the next independently planned stop to use for charging instead"));
90 oc.doRegister("device.stationfinder.maxDistanceToReplacedStop", new Option_Float(300.));
91 oc.addDescription("device.stationfinder.maxDistanceToReplacedStop", "Battery", TL("Maximum distance in meters from the original stop to be replaced by the charging stop"));
92 oc.doRegister("device.stationfinder.chargingStrategy", new Option_String("none"));
93 oc.addDescription("device.stationfinder.chargingStrategy", "Battery", TL("Set a charging strategy to alter time and charging load from the set: [none, balanced, latest]"));
94 oc.doRegister("device.stationfinder.checkEnergyForRoute", new Option_Bool(true));
95 oc.addDescription("device.stationfinder.checkEnergyForRoute", "Battery", TL("Only search for charging stations if the battery charge is not estimated sufficient to complete the current route"));
96}
97
98
99
100void
101MSDevice_StationFinder::buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into) {
103 if (equippedByDefaultAssignmentOptions(oc, "stationfinder", v, false)) {
104 into.push_back(new MSDevice_StationFinder(v));
105 }
106}
107
108
109// ---------------------------------------------------------------------------
110// MSDevice_StationFinder-methods
111// ---------------------------------------------------------------------------
113 : MSVehicleDevice(holder, "stationfinder_" + holder.getID()),
114 MSStoppingPlaceRerouter("device.stationfinder.charging", true, {
115 {"waitingTime", 1.}, {"chargingTime", 1.}
116}, { {"waitingTime", false}, {"chargingTime", false} }),
117myVeh(dynamic_cast<MSVehicle&>(holder)),
118myBattery(nullptr), myChargingStation(nullptr), myRescueCommand(nullptr), myChargeLimitCommand(nullptr),
119myLastChargeCheck(0), myCheckInterval(1000), myArrivalAtChargingStation(-1), myLastSearch(-1),
120myLastOpportunisticSearch(-1) {
121 // consider whole path to/from a charging station in the search
122 myEvalParams["distanceto"] = 0.;
123 myEvalParams["timeto"] = 1.;
124 myEvalParams["timefrom"] = 1.;
125 myNormParams["chargingTime"] = true;
126 myNormParams["waitingTime"] = true;
127 myRescueTime = STEPS2TIME(holder.getTimeParam("device.stationfinder.rescueTime"));
128 const std::string chargingStrategy = holder.getStringParam("device.stationfinder.chargingStrategy");
129 if (chargingStrategy == "balanced") {
130 myChargingStrategy = CHARGINGSTRATEGY_BALANCED;
131 } else if (chargingStrategy == "latest") {
132 myChargingStrategy = CHARGINGSTRATEGY_LATEST;
133 } else if (chargingStrategy == "none") {
134 myChargingStrategy = CHARGINGSTRATEGY_NONE;
135 } else {
136 WRITE_ERRORF(TL("Invalid device.stationfinder.chargingStrategy '%'."), chargingStrategy);
137 }
138 const std::string rescueAction = holder.getStringParam("device.stationfinder.rescueAction");
139 if (rescueAction == "remove") {
140 myRescueAction = RESCUEACTION_REMOVE;
141 } else if (rescueAction == "tow") {
142 myRescueAction = RESCUEACTION_TOW;
143 } else if (rescueAction == "none") {
144 myRescueAction = RESCUEACTION_NONE;
145 } else {
146 WRITE_ERRORF(TL("Invalid device.stationfinder.rescueAction '%'."), rescueAction);
147 }
148 initRescueCommand();
149 myReserveFactor = MAX2(1., holder.getFloatParam("device.stationfinder.reserveFactor"));
150 myEmptySoC = MAX2(0., MIN2(holder.getFloatParam("device.stationfinder.emptyThreshold"), 1.));
151 myRadius = holder.getTimeParam("device.stationfinder.radius");
152 myMaxEuclideanDistance = holder.getFloatParam("device.stationfinder.maxEuclideanDistance");
153 myRepeatInterval = holder.getTimeParam("device.stationfinder.repeat");
154 myChargeType = CHARGETYPE_CHARGING;
155
156 myWaitForCharge = holder.getTimeParam("device.stationfinder.waitForCharge");
157 myMinOpportunisticTime = holder.getTimeParam("device.stationfinder.minOpportunityDuration");
158 myTargetSoC = MAX2(0., MIN2(holder.getFloatParam("device.stationfinder.saturatedChargeLevel"), 1.));
159 mySearchSoC = MAX2(0., MIN2(holder.getFloatParam("device.stationfinder.needToChargeLevel"), 1.));
160 if (mySearchSoC <= myEmptySoC) {
161 WRITE_WARNINGF(TL("Vehicle '%' searches for charging stations only in the rescue case due to search threshold % <= rescue threshold %."), myHolder.getID(), mySearchSoC, myEmptySoC);
162 }
163 myOpportunitySoC = MAX2(0., MIN2(holder.getFloatParam("device.stationfinder.opportunisticChargeLevel"), 1.));
164 if (myOpportunitySoC > 0. && myOpportunitySoC < MIN2(mySearchSoC + NUMERICAL_EPS, 1.)) {
165 myOpportunitySoC = 0.;
166 WRITE_WARNINGF(TL("Vehicle '%' won't do opportunistic charging as the threshold % is too close to the regular one %."), myHolder.getID(), myOpportunitySoC, mySearchSoC);
167 }
168 myReplacePlannedStop = MAX2(0., holder.getFloatParam("device.stationfinder.replacePlannedStop"));
169 myDistanceToOriginalStop = holder.getFloatParam("device.stationfinder.maxDistanceToReplacedStop");
170 myUpdateSoC = 2; // check once at the beginning
171 myCheckEnergyForRoute = holder.getBoolParam("device.stationfinder.checkEnergyForRoute");
172}
173
174
176 // make the rescue command invalid if there is one
177 if (myRescueCommand != nullptr) {
179 }
180 if (myChargeLimitCommand != nullptr) {
182 }
183}
184
185
186bool
187MSDevice_StationFinder::notifyMove(SUMOTrafficObject& veh, double /*oldPos*/, double /*newPos*/, double /*newSpeed*/) {
188 if (myBattery->getEnergyCharged() > 0. && myChargingStation != nullptr) {
190 myChargingStation = nullptr;
192 return true;
193 } else if (mySearchState == SEARCHSTATE_CHARGING) {
194 if (myBattery->getChargingStation() == nullptr) {
196 } else {
197 return true;
198 }
199 }
200 // check if the vehicle travels at most an edge length to the charging station after jump/teleport
202 return true;
203 }
204 const SUMOTime now = SIMSTEP;
205 if (myChargingStation != nullptr) {
207 // waited for too long, try another charging station
208 if (rerouteToChargingStation(true)) {
209 WRITE_MESSAGE(TLF("Rerouted vehicle '%' after waiting too long at the previous charging station at time=%.", veh.getID(), toString(SIMTIME)));
210 }
212 // remember when the vehicle arrived close to the target charging station
215 }
216 }
218 if (currentSoC < myOpportunitySoC && currentSoC < myTargetSoC && mySearchState == SEARCHSTATE_NONE) {
219 // battery SoC is low enough to allow opportunistic charging (charging whenever - wherever)
222 return true;
223 } else if (currentSoC > mySearchSoC || mySearchState == SEARCHSTATE_BROKEN_DOWN) {
224 // battery SoC is too high to look for charging facilities or the vehicle is already in rescue mode
225 return true;
226 }
227 // only check once per second
228 if (now - myLastChargeCheck < 1000) {
229 return true;
230 } else if (myRescueAction != RESCUEACTION_NONE && (currentSoC < myEmptySoC || currentSoC < NUMERICAL_EPS)) {
231
232 // vehicle has to stop at the end of the because battery SoC is too low
233 double brakeGap = myVeh.getCarFollowModel().brakeGap(myVeh.getSpeed());
234 std::pair<const MSLane*, double> stopPos = myVeh.getLanePosAfterDist(brakeGap);
235 if (stopPos.first != nullptr) {
236 const MSLane* stopLane = (stopPos.first->isInternal()) ? stopPos.first->getNormalSuccessorLane() : stopPos.first;
237 double endPos = stopPos.second;
238 if (stopLane != stopPos.first) {
239 endPos = MIN2(POSITION_EPS, stopLane->getLength());
240 }
241 // remove possibly scheduled charging stop
242 if (myVeh.hasStops() && myVeh.getStop(0).chargingStation != nullptr) {
244 }
245
246 // schedule the rescue stop
248 rescueStop.index = 0;
249 rescueStop.edge = stopLane->getEdge().getID();
250 rescueStop.lane = stopLane->getID();
251 rescueStop.startPos = MAX2(endPos - 2 * myHolder.getVehicleType().getLength(), 0.);
252 rescueStop.endPos = endPos;
254 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));
255
257 // remove vehicle from network
258 rescueStop.until = SUMOTime_MAX;
259 rescueStop.breakDown = true;
260 std::string errorMsg = "Could not insert the rescue stop.";
261 if (!myVeh.insertStop(0, rescueStop, "stationfinder:rescue", false, errorMsg)) {
262 WRITE_ERROR(errorMsg);
263 }
265 return true;
266 } else if (myRescueAction == RESCUEACTION_TOW) {
267 // wait next to the road and get teleported to a charging station
268 SUMOTime rescueTime = TIME2STEPS(myRescueTime);
269 rescueStop.duration = rescueTime;
270 rescueStop.parking = ParkingType::ONROAD;
271 rescueStop.jump = 0;
272 std::string errorMsg = "Could not insert the rescue stop.";
273 if (!myVeh.insertStop(0, rescueStop, "stationfinder:rescue", false, errorMsg)) {
274 WRITE_ERROR(errorMsg);
275 }
279 return true;
280 }
281 }
282 } else if (myChargingStation == nullptr &&
285 // check if a charging stop is already planned without the device, otherwise reroute inside this device
286 if (!alreadyPlannedCharging() && now > myHolder.getDeparture()) {
288 }
289 myUpdateSoC = currentSoC - MAX2(0.1 * currentSoC, 0.01);
290#ifdef DEBUG_STATIONFINDER_REROUTE
291 std::cout << SIMTIME << " " << myHolder.getID() << " currentSoC=" << currentSoC << " nextUpdateSoC=" << myUpdateSoC << "\n";
292#endif
293 }
295 return true;
296}
297
298
299bool
303
304
305void
309 std::vector<std::string> internals;
310 internals.push_back(toString(myLastChargeCheck));
311 internals.push_back(toString(myUpdateSoC));
312 internals.push_back(toString(mySearchSoC));
313 internals.push_back(toString(myTargetSoC));
314 internals.push_back(toString(myWaitForCharge));
315 internals.push_back(toString(myRepeatInterval));
316 internals.push_back(toString(myRadius));
317 internals.push_back(toString(myLastSearch));
318 internals.push_back(toString(myReserveFactor));
319 internals.push_back(toString(mySearchState));
320 internals.push_back(toString(myArrivalAtChargingStation));
321 internals.push_back((myChargingStation == nullptr) ? "NULL" : myChargingStation->getID());
322 internals.push_back(toString(myChargeLimits.size()));
323 for (auto chargeLimit : myChargeLimits) {
324 internals.push_back(toString(chargeLimit.first));
325 internals.push_back(toString(chargeLimit.second));
326 }
327 internals.push_back(toString(myOpportunitySoC));
328 internals.push_back(toString(myMinOpportunisticTime));
329 internals.push_back(toString(myCheckEnergyForRoute));
330 out.writeAttr(SUMO_ATTR_STATE, toString(internals));
331 out.closeTag();
332}
333
334
335void
337 std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
338 bis >> myLastChargeCheck;
339 bis >> myUpdateSoC;
340 bis >> mySearchSoC;
341 bis >> myTargetSoC;
342 bis >> myWaitForCharge;
343 bis >> myRepeatInterval;
344 bis >> myRadius;
345 bis >> myLastSearch;
346 bis >> myReserveFactor;
347 int searchState;
348 bis >> searchState;
349 mySearchState = (SearchState)searchState;
351 std::string csID;
352 bis >> csID;
353 if (csID != "NULL") {
355 }
356 int chargeLimitCount = 0;
357 bis >> chargeLimitCount;
358 for (int i = 0; i < chargeLimitCount; ++i) {
359 SUMOTime t = 0;
360 double limit = 0.;
361 bis >> t;
362 bis >> limit;
363 myChargeLimits.push_back({ t, limit });
364 }
365 bis >> myOpportunitySoC;
368}
369
370
371void
373 const double /* frontOnLane */,
374 const double /* timeOnLane */,
375 const double /* meanSpeedFrontOnLane */,
376 const double /* meanSpeedVehicleOnLane */,
377 const double /* travelledDistanceFrontOnLane */,
378 const double /* travelledDistanceVehicleOnLane */,
379 const double /* meanLengthOnLane */) {
380
381 // called by meso (see MSMeanData_Emissions::MSLaneMeanDataValues::notifyMoveInternal)
382}
383
384
386MSDevice_StationFinder::findChargingStation(SUMOAbstractRouter<MSEdge, SUMOVehicle>& /*router*/, double expectedConsumption, StoppingPlaceParamMap_t& scores, bool constrainTT, bool skipVisited, bool skipOccupied, bool visible) {
387 MSChargingStation* minStation = nullptr;
388 std::vector<StoppingPlaceVisible> candidates;
389 const StoppingPlaceMemory* chargingMemory = myVeh.getChargingMemory();
390 if (chargingMemory == nullptr) {
391 skipVisited = false;
392 }
393 const SUMOTime stoppingPlaceMemory = TIME2STEPS(getWeight(myHolder, "memory", 600));
395 MSChargingStation* cs = static_cast<MSChargingStation*>(stop.second);
396 if (cs->getEfficency() < NUMERICAL_EPS || cs->getChargingPower(false) < NUMERICAL_EPS) {
397 continue;
398 }
399 if (cs->getChargeType() != myBattery->getChargeType()) {
400 continue;
401 }
402 if (cs->getParkingArea() != nullptr && !cs->getParkingArea()->accepts(&myVeh)) {
403 // skip stations where the linked parking area does not grant access to the device holder
404 continue;
405 }
406 if (skipOccupied && freeSpaceAtChargingStation(cs) < 1.) {
407 continue;
408 }
409 if (skipVisited && chargingMemory->sawBlockedStoppingPlace(cs, false) > 0 && SIMSTEP - chargingMemory->sawBlockedStoppingPlace(cs, false) < stoppingPlaceMemory) {
410 // skip recently visited
411 continue;
412 }
413 if (constrainTT && myMaxEuclideanDistance > 0 && stop.second->getLane().geometryPositionAtOffset(stop.second->getBeginLanePosition()).distanceTo2D(myHolder.getPosition()) > myMaxEuclideanDistance) {
414 // skip probably too distant charging stations
415 continue;
416 }
417 if (visible && myHolder.getEdge()->getID() != stop.second->getLane().getEdge().getID()) {
418 continue;
419 }
420 candidates.push_back({cs, false});
421 }
422 ConstMSEdgeVector newRoute;
423 scores["expectedConsumption"] = expectedConsumption;
424 std::vector<double> probs(candidates.size(), 1.);
425 bool newDestination;
426 myCheckValidity = constrainTT;
427 MSStoppingPlace* bestCandidate = rerouteStoppingPlace(nullptr, candidates, probs, myHolder, newDestination, newRoute, scores);
428 myCheckValidity = true;
429 minStation = dynamic_cast<MSChargingStation*>(bestCandidate);
430 return minStation;
431}
432
433
434bool
438#ifdef DEBUG_STATIONFINDER_REROUTE
439 std::cout << SIMTIME << " " << myHolder.getID() << " expectedConsumption=" << expectedConsumption << " reserve=" << (myEmptySoC * myBattery->getMaximumBatteryCapacity()) << " chargeLevel=" << myBattery->getActualBatteryCapacity() << "\n";
440#endif
444 StoppingPlaceParamMap_t scores = {};
445 MSChargingStation* cs = findChargingStation(router, expectedConsumption, scores);
446 if (cs != nullptr) {
447 // integrate previously planned stops which do not have charging facilities
450 stopPar.chargingStation = cs->getID();
451 if (cs->getParkingArea() != nullptr) {
452 stopPar.parkingarea = cs->getParkingArea()->getID();
454 }
455 stopPar.edge = cs->getLane().getEdge().getID();
456 stopPar.lane = cs->getLane().getID();
457 stopPar.duration = TIME2STEPS(expectedConsumption / (cs->getChargingPower(false) * cs->getEfficency()));
459 if (myReplacePlannedStop > 0) {
460 // "reuse" a previously planned stop (stop at charging station instead of a different stop)
461 // what if the charging station is skipped due to long waiting time?
463 // compare the distance to the original target
464 if (scores["distfrom"] < myDistanceToOriginalStop /*actualDist < myDistanceToOriginalStop*/) {
465 // compute the arrival time at the original stop
466 const SUMOTime timeToOriginalStop = TIME2STEPS(scores["timefrom"]);
467 const SUMOTime originalUntil = myHolder.getNextStopParameter()->until;
468 if (timeToOriginalStop + myLastSearch < originalUntil) {
469 const SUMOTime delta = originalUntil - (timeToOriginalStop + myLastSearch);
470 stopPar.until = timeToOriginalStop + myLastSearch + (SUMOTime)((double)delta * MIN2(myReplacePlannedStop, 1.));
471 stopPar.parametersSet |= STOP_UNTIL_SET;
472 if (myReplacePlannedStop > 1.) {
474 }
475 // optionally implement a charging strategy by adjusting the accepted charging rates
477 // the charging strategy should actually only be computed at the arrival at the charging station
478 implementChargingStrategy(myLastSearch + TIME2STEPS(scores["timeto"]), stopPar.until, expectedConsumption, cs);
479 }
480 }
481 }
482 }
483 }
484 stopPar.startPos = cs->getBeginLanePosition();
485 stopPar.endPos = cs->getEndLanePosition();
486 std::string errorMsg;
487#ifdef DEBUG_STATIONFINDER_REROUTE
488 std::ostringstream os;
489 const ConstMSEdgeVector edgesBefore = myVeh.getRoute().getEdges();
490 for (auto edge : edgesBefore) {
491 os << edge->getID() << " ";
492 }
493 std::cout << "MSDevice_StationFinder::rerouteToChargingStation: \n\tRoute before scheduling the charging station: " << os.str() << "\n";
494#endif
495 if ((replace && !myVeh.replaceStop(0, stopPar, "stationfinder:search", false, errorMsg)) || (!replace && !myVeh.insertStop(0, stopPar, "stationfinder:search", false, errorMsg))) {
496 WRITE_MESSAGE(TLF("Problem with inserting the charging station stop for vehicle %.", myHolder.getID()));
497 WRITE_ERROR(errorMsg);
498 }
499
500#ifdef DEBUG_STATIONFINDER_REROUTE
501 std::ostringstream os2;
502 const ConstMSEdgeVector edgesAfter = myVeh.getRoute().getEdges();
503 for (auto edge : edgesAfter) {
504 os2 << edge->getID() << " ";
505 }
506 std::cout << "\tRoute after scheduling the charging station: " << os2.str() << "\n";
507#endif
510#ifdef DEBUG_STATIONFINDER_REROUTE
511 std::cout << "\tVehicle " << myHolder.getID() << " gets rerouted to charging station " << cs->getID() << " on edge " << stopPar.edge << " at time " << SIMTIME << "\n";
512#endif
513 return true;
514 }
516 WRITE_MESSAGEF(TL("Vehicle '%' wants to charge at time=% but does not find any charging station nearby."), myHolder.getID(), toString(SIMTIME));
517 }
518 return false;
519}
520
521
522bool
524 // check next stop
526 if (myHolder.hasStops() && capacityDelta > 0.) {
527 const MSStop& nextStop = myHolder.getNextStop();
528 if (myHolder.isStopped() || nextStop.chargingStation != nullptr || myHolder.getCurrentRouteEdge() != nextStop.edge ||
530 return false;
531 }
532 // find charging station on same edge
534 StoppingPlaceParamMap_t scores = {};
535 MSChargingStation* cs = findChargingStation(router, 0., scores, true, true, true, true);
536 if (cs != nullptr) {
537 // replace next stop by charging stop
540 stopPar.chargingStation = cs->getID();
541 if (cs->getParkingArea() != nullptr) {
542 stopPar.parkingarea = cs->getParkingArea()->getID();
544 }
545 stopPar.edge = cs->getLane().getEdge().getID();
546 stopPar.lane = cs->getLane().getID();
547 stopPar.startPos = cs->getBeginLanePosition();
548 stopPar.endPos = cs->getEndLanePosition();
549 // copy over depart time from previously planned stop
550 SUMOTime oldUntil = nextStop.getUntil();
551 if (oldUntil > 0) {
552 stopPar.until = oldUntil;
553 stopPar.duration = 0;
554 } else { // set a duration needed to charge to the target SoC
555 stopPar.duration = nextStop.duration;
556 }
557 std::string errorMsg;
558 if (!myVeh.replaceStop(0, stopPar, "stationfinder:opportunisticSearch", false, errorMsg)) {
559 WRITE_ERROR(errorMsg);
560 }
561 return true;
562 }
563 }
564 return false;
565}
566
567
570 // find closest charging station
572 double expectedConsumption = MIN2(estimateConsumption(nullptr, true, STEPS2TIME(myVeh.getStops().front().pars.duration)) * myReserveFactor, myBattery->getMaximumBatteryCapacity() * myTargetSoC);
573 StoppingPlaceParamMap_t scores = {};
574 MSChargingStation* cs = findChargingStation(router, expectedConsumption, scores, false, false, true);
575 if (cs == nullptr) {
576 // continue waiting if all charging stations are occupied
577#ifdef DEBUG_STATIONFINDER_RESCUE
578 std::cout << "MSDevice_StationFinder::teleportToChargingStation: No charging station available to teleport the broken-down vehicle " << myHolder.getID() << " to at time " << SIMTIME << ".\n.";
579#endif
580 // remove the vehicle if teleport to a charging station fails
581 if (myHolder.isStopped()) {
582 MSStop& currentStop = myHolder.getNextStopMutable();
583 currentStop.duration += DELTA_T;
584 SUMOVehicleParameter::Stop& stopPar = const_cast<SUMOVehicleParameter::Stop&>(currentStop.pars);
585 stopPar.jump = -1;
586 stopPar.breakDown = true;
588 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));
589 }
590#ifdef DEBUG_STATIONFINDER_RESCUE
591 else {
592#ifdef DEBUG_STATIONFINDER_RESCUE
593 std::cout << "MSDevice_StationFinder::teleportToChargingStation: Rescue stop of " << myHolder.getID() << " ended prematurely before regular end at " << SIMTIME << ".\n.";
594#endif
595 }
596#endif
597 return myRepeatInterval;
598 }
599
600 // teleport to the charging station, stop there for charging
603 stopPar.chargingStation = cs->getID();
604 if (cs->getParkingArea() != nullptr) {
605 stopPar.parkingarea = cs->getParkingArea()->getID();
607 }
608 stopPar.edge = cs->getLane().getEdge().getID();
609 stopPar.lane = cs->getLane().getID();
610 stopPar.startPos = cs->getBeginLanePosition();
611 stopPar.endPos = cs->getEndLanePosition();
612 stopPar.duration = TIME2STEPS(expectedConsumption / (cs->getChargingPower(false) * cs->getEfficency()));
613 std::string errorMsg;
614 if (!myVeh.insertStop(1, stopPar, "stationfinder:search", true, errorMsg)) {
615 WRITE_ERROR(errorMsg);
616 }
618 myRescueCommand = nullptr;
619 return 0;
620}
621
622
623double
624MSDevice_StationFinder::estimateConsumption(const MSEdge* target, const bool includeEmptySoC, const double stopDiscount) const {
625 const SUMOTime now = SIMSTEP;
627 const ConstMSEdgeVector& route = myHolder.getRoute().getEdges();
628 ConstMSEdgeVector::const_iterator targetIt = (target == nullptr) ? route.end() : std::find(route.begin(), route.end(), target) + 1;
629 const ConstMSEdgeVector remainingRoute(route.begin() + myHolder.getRoutePosition(), targetIt);
630 const double remainingTime = router.recomputeCosts(remainingRoute, &myHolder, now);
631 if (now > myHolder.getDeparture()) {
632 const double totalConsumption = myBattery->getTotalConsumption();
633 double expectedConsumption = 0.;
634 double passedTime = STEPS2TIME(now - myHolder.getDeparture());
635 if (totalConsumption > 0. && passedTime - stopDiscount > DEFAULT_CONSUMPTION_ESTIMATE_HISTORY) {
636 expectedConsumption = totalConsumption / (passedTime - stopDiscount) * remainingTime;
637 } else {
638 // fallback consumption rate for vehicles starting with low battery
640 WRITE_ERRORF("The stationfinder device needs emission parameters for range estimation but no emission class has been set for the vehicle '%'", myHolder.getID());
641 }
642 const double speed = MIN2(myHolder.getMaxSpeed(), myHolder.getLane()->getSpeedLimit());
645 expectedConsumption = PollutantsInterface::compute(myVeh.getVehicleType().getEmissionClass(), emType,
646 speed * 0.8, 0., 0., params) * (remainingTime - passedTime);
647 }
648 if (includeEmptySoC) {
650 }
652 return expectedConsumption;
653 }
654 return 0.;
655}
656
657
658double
662
663
664bool
666 if (myChargingStation == nullptr) {
667 auto stops = myHolder.getStops();
668 for (auto stop : stops) {
669 if (stop.chargingStation != nullptr) {
670 // compare whether we'll make it there without intermediate charging
671 double expectedConsumption = estimateConsumption(*stop.edge);
672 if (myBattery->getActualBatteryCapacity() < expectedConsumption) {
673 myChargingStation = stop.chargingStation;
674 return true;
675 }
676 }
677 }
678 }
679 return false;
680}
681
682
683void
689
690
691void
697
698
701 if (myChargeLimits.size() > 0 && myChargeLimits.begin()->first < currentTime - DELTA_T) {
702 myChargeLimits.clear();
703 }
704 if (myChargeLimits.size() > 0) {
705 double chargeLimit = myChargeLimits.begin()->second;
706 myBattery->setChargeLimit(chargeLimit);
707 if (chargeLimit < 0) {
708 WRITE_MESSAGEF(TL("The charging rate limit of vehicle '%' is lifted at time=%"), myHolder.getID(), STEPS2TIME(SIMSTEP));
709 } else {
710 WRITE_MESSAGEF(TL("The charging rate of vehicle '%' is limited to % at time=%"), myHolder.getID(), chargeLimit, STEPS2TIME(SIMSTEP));
711 }
712 myChargeLimits.erase(myChargeLimits.begin());
713 }
714 if (myChargeLimits.size() == 0) {
716 myChargeLimitCommand = nullptr;
717 return 0;
718 } else {
719 return myChargeLimits.begin()->first - currentTime;
720 }
721}
722
723
724void
726 myChargeLimits.clear();
728 const double balancedChargeRate = plannedCharge / STEPS2TIME(end - begin) * 3600.;
729 myChargeLimits.push_back({ begin, balancedChargeRate });
730 myChargeLimits.push_back({ end, -1});
731 } else { // CHARGINGSTRATEGY_LATEST
732 SUMOTime expectedDuration = myBattery->estimateChargingDuration(plannedCharge, cs->getChargingPower(false) * cs->getEfficency());
733 if (end - expectedDuration > begin) {
734 myChargeLimits.push_back({ begin, 0 });
735 myChargeLimits.push_back({ end - expectedDuration, -1 });
736 }
737 }
738 if (myChargeLimits.size() > 0) {
741 }
742}
743
744
745void
747 if (tripinfoOut != nullptr && myChargingStation != nullptr) {
748 tripinfoOut->openTag("stationfinder");
749 tripinfoOut->writeAttr("chargingStation", myChargingStation->getID());
750 tripinfoOut->closeTag();
751 }
752}
753
754
755std::string
756MSDevice_StationFinder::getParameter(const std::string& key) const {
757 if (key == "chargingStation") { // eventually abstract with enum
758 return (myChargingStation == nullptr) ? "" : myChargingStation->getID();
759 } else if (key == "batteryNeed") {
761 } else if (key == "needToChargeLevel") {
762 return toString(mySearchSoC);
763 } else if (key == "saturatedChargeLevel") {
764 return toString(myTargetSoC);
765 } else if (key == "waitForCharge") {
767 } else if (key == "repeat") {
769 } else if (key == "radius") {
770 return toString(myRadius);
771 } else if (key == "reserveFactor") {
773 }
774 throw InvalidArgument(TLF("Parameter '%' is not supported for device of type '%'", key, deviceName()));
775}
776
777
778void
779MSDevice_StationFinder::setParameter(const std::string& key, const std::string& value) {
780 double doubleValue;
781 try {
782 doubleValue = StringUtils::toDouble(value);
783 } catch (NumberFormatException&) {
784 throw InvalidArgument(TLF("Setting parameter '%' requires a number for device of type '%'", key, deviceName()));
785 }
786 if (key == "needToChargeLevel") {
787 mySearchSoC = MAX2(0., MIN2(1., doubleValue));
788 } else if (key == "saturatedChargeLevel") {
789 myTargetSoC = MAX2(0., MIN2(1., doubleValue));
790 } else if (key == "waitForCharge") {
791 myWaitForCharge = TIME2STEPS(MAX2(0., doubleValue));
792 } else if (key == "repeat") {
793 myRepeatInterval = TIME2STEPS(MAX2(0., doubleValue));
794 } else if (key == "radius") {
795 myRadius = TIME2STEPS(MAX2(0., doubleValue));
796 } else if (key == "reserveFactor") {
797 myReserveFactor = MAX2(1., doubleValue);
798 } else {
799 throw InvalidArgument(TLF("Setting parameter '%' is not supported for device of type '%'", key, deviceName()));
800 }
801}
802
803
804bool
805MSDevice_StationFinder::evaluateCustomComponents(SUMOVehicle& /* veh */, double /* brakeGap */, bool /* newDestination */,
806 MSStoppingPlace* alternative, double /* occupancy */, double /* prob */,
808 StoppingPlaceParamMap_t& stoppingPlaceValues,
809 ConstMSEdgeVector& /* newRoute */, ConstMSEdgeVector& /* stoppingPlaceApproach */,
810 StoppingPlaceParamMap_t& /* maxValues */, StoppingPlaceParamMap_t& addInput) {
811 // estimated waiting time and charging time
812 MSChargingStation* cs = dynamic_cast<MSChargingStation*>(alternative);
813 double parkingCapacity = (cs->getParkingArea() != nullptr) ? cs->getParkingArea()->getCapacity() : (cs->getEndLanePosition() - cs->getBeginLanePosition()) / myHolder.getVehicleType().getParameter().length;
814 double freeParkingCapacity = freeSpaceAtChargingStation(cs);
815 stoppingPlaceValues["waitingTime"] = (freeParkingCapacity < 1.) ? DEFAULT_AVG_WAITING_TIME / parkingCapacity : 0.;
816 stoppingPlaceValues["chargingTime"] = STEPS2TIME(cs->getChargeDelay()) + addInput["expectedConsumption"] / cs->getChargingPower(false);
817 return true;
818}
819
820
821bool
823 if (stoppingPlaceValues["timeto"] > STEPS2TIME(myRadius)) {
824 return false;
825 }
826 return true;
827}
828
829
830bool
832 return true;
833}
834
835
839
840
841double
843 MSChargingStation* cs = dynamic_cast<MSChargingStation*>(stoppingPlace);
844 if (cs->getParkingArea() != nullptr) {
845 return cs->getParkingArea()->getOccupancy();
846 }
848}
849
850
851double
853 MSChargingStation* cs = dynamic_cast<MSChargingStation*>(stoppingPlace);
854 if (cs->getParkingArea() != nullptr) {
855 return cs->getParkingArea()->getLastStepOccupancy();
856 }
858}
859
860
861double
863 MSChargingStation* cs = dynamic_cast<MSChargingStation*>(stoppingPlace);
864 if (cs->getParkingArea() != nullptr) {
865 return cs->getParkingArea()->getCapacity();
866 }
868}
869
870
871void
873 veh.rememberBlockedChargingStation(stoppingPlace, blocked);
874}
875
876
877void
879 veh.rememberChargingStationScore(place, score);
880}
881
882
883void
887
888
893
894
895int
899
900
901void
904
905
906/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define DEFAULT_CONSUMPTION_ESTIMATE_HISTORY
#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:287
#define WRITE_MESSAGEF(...)
Definition MsgHandler.h:289
#define WRITE_ERRORF(...)
Definition MsgHandler.h:296
#define WRITE_MESSAGE(msg)
Definition MsgHandler.h:288
#define WRITE_ERROR(msg)
Definition MsgHandler.h:295
#define TL(string)
Definition MsgHandler.h:304
#define TLF(string,...)
Definition MsgHandler.h:306
SUMOTime DELTA_T
Definition SUMOTime.cpp:38
#define STEPS2TIME(x)
Definition SUMOTime.h:58
#define SIMSTEP
Definition SUMOTime.h:64
#define SUMOTime_MAX
Definition SUMOTime.h:34
#define SIMTIME
Definition SUMOTime.h:65
#define TIME2STEPS(x)
Definition SUMOTime.h:60
const long long int VTYPEPARS_EMISSIONCLASS_SET
const int STOP_DURATION_SET
const int STOP_UNTIL_SET
const int STOP_START_SET
const int STOP_END_SET
@ SUMO_TAG_DEVICE
@ SUMO_TAG_CHARGING_STATION
A Charging Station.
@ SUMO_ATTR_ID
@ SUMO_ATTR_PROPULSIONEFFICIENCY
Propulsion efficiency.
@ SUMO_ATTR_STATE
The state of a link.
T MIN2(T a, T b)
Definition StdDefs.h:80
T MAX2(T a, T b)
Definition StdDefs.h:86
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:49
An upper class for objects with additional parameters.
double getDoubleOptional(SumoXMLAttr attr, const double def) const
Returns the value for a given key with an optional default. SUMO_ATTR_MASS and SUMO_ATTR_FRONTSURFACE...
bool replaceStop(int nextStopIndex, SUMOVehicleParameter::Stop stop, const std::string &info, bool teleport, std::string &errorMsg)
const std::list< MSStop > & getStops() const
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.
const StoppingPlaceMemory * getChargingMemory() const
const MSVehicleType & getVehicleType() const
Returns the vehicle's type definition.
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:424
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.
ChargeType getChargeType() const
Get charge type.
const MSParkingArea * getParkingArea() const
Get the parking area the charging station is placed on.
MSChargingStation::ChargeType getChargeType() const
Get the charge type.
double getActualBatteryCapacity() const
Get the actual vehicle's Battery Capacity in Wh.
void setChargeLimit(const double limit)
Set (temporary) charge limit.
MSChargingStation * getChargingStation() const
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.
bool tracksFuel() const
Whether the battery device is actually used as a tank of a combustion vehicle.
double getTotalConsumption() const
Get total consumption.
double getEnergyCharged() const
Get charged energy.
A device which triggers rerouting to nearby charging stations.
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 setParameter(const std::string &key, const std::string &value) override
try to set the given parameter for this device. Throw exception for unsupported key
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)
SUMOTime myLastOpportunisticSearch
Last time charging stations have been searched for opportunistic charging.
MSDevice_StationFinder(SUMOVehicle &holder)
Constructor.
ChargingStrategy myChargingStrategy
The chosen charging strategy.
MSChargingStation * findChargingStation(SUMOAbstractRouter< MSEdge, SUMOVehicle > &router, double expectedConsumption, StoppingPlaceParamMap_t &scores, bool constrainTT=true, bool skipVisited=true, bool skipOccupied=false, bool visible=false)
central search function for close charging stations
double getLastStepStoppingPlaceOccupancy(MSStoppingPlace *stoppingPlace, const SUMOVehicle *veh) override
Return the number of occupied places of the StoppingPlace from the previous time step.
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
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
double myOpportunitySoC
The state of charge at/below which the vehicle is interested in charging although it may still be suf...
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 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
void saveState(OutputDevice &out) const override
Saves the state of the device.
bool myCheckEnergyForRoute
Whether to skip searching charging stations if the battery charge is sufficient to complete the curre...
SUMOTime myWaitForCharge
Accepted waiting time at the charging station before a place becomes available.
SUMOTime myLastSearch
Last time charging stations have been searched.
double getStoppingPlaceOccupancy(MSStoppingPlace *stoppingPlace, const SUMOVehicle *veh) override
Return the number of occupied places of the StoppingPlace.
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.
MSDevice_Battery * myBattery
The corresponding battery device.
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.
bool planOpportunisticCharging()
check which stop is suited for opportunistic charging and try to plan charging stops
SUMOTime updateChargeLimit(const SUMOTime currentTime)
update the maximum charge rate of the battery to simulate charging strategies
SUMOTime myMinOpportunisticTime
Minimal expected stop duration to allow for opportunistic charging (not needed to complete the route)
double myReplacePlannedStop
The share of stopping time a charging stop should take from the next regular (non-charging) stop unde...
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.
void loadState(const SUMOSAXAttributes &attrs) override
Loads the state of the device from the given description.
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
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouter(SUMOVehicle &veh, const Prohibitions &prohibited) override
Provide the router to use (MSNet::getRouterTT or MSRoutingEngine)
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:157
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:200
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:3296
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
Definition MSLane.h:602
double getLength() const
Returns the lane's length.
Definition MSLane.h:632
MSEdge & getEdge() const
Returns the lane's edge.
Definition MSLane.h:790
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:199
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition MSNet.h:495
MSStoppingPlace * getStoppingPlace(const std::string &id, const SumoXMLTag category) const
Returns the named stopping place of the given category.
Definition MSNet.cpp:1513
const NamedObjectCont< MSStoppingPlace * > & getStoppingPlaces(SumoXMLTag category) const
Definition MSNet.cpp:1564
int getCapacity() const
Returns the area capacity.
bool parkOnRoad() const
whether vehicles park on the road
bool accepts(SUMOVehicle *veh) const override
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:128
static MSVehicleRouter & getRouterTT(const int rngIndex, SUMOVehicleClass svc, const Prohibitions &prohibited={})
return the vehicle router instance
SUMOTime getMinDuration(SUMOTime time) const
return minimum stop duration when starting stop at time
Definition MSStop.cpp:171
MSRouteIterator edge
The edge in the route to stop at.
Definition MSStop.h:48
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
SUMOTime getUntil() const
return until / ended time
Definition MSStop.cpp:188
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.
virtual double getLastFreePos(const SUMOVehicle &forVehicle, double brakePos=0) const
Returns the last free position on this stop.
std::map< std::string, double > StoppingPlaceParamMap_t
MSStoppingPlace * rerouteStoppingPlace(MSStoppingPlace *destStoppingPlace, const std::vector< StoppingPlaceVisible > &stoppingPlaceCandidates, const std::vector< double > &probs, SUMOVehicle &veh, bool &newDestination, ConstMSEdgeVector &newRoute, StoppingPlaceParamMap_t &scores, const Prohibitions &closedEdges={}, const int insertStopIndex=0, const bool keepCurrentStop=true)
main method to trigger the rerouting to the "best" StoppingPlace according to the custom evaluation f...
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
std::map< const MSEdge *, RouterProhibition > Prohibitions
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.
double getDistanceToPosition(double destPos, const MSLane *destLane) const
const MSLane * getLane() const
Returns the lane the vehicle is on.
Definition MSVehicle.h:581
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:973
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:73
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.
static OptionsCont & getOptions()
Retrieves the options.
Static storage of an output device and its base (abstract) implementation.
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
OutputDevice & writeAttr(const ATTR_TYPE &attr, const T &val, const bool isNull=false, const bool escape=false)
writes a named attribute
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
EmissionType
Enumerating all emission types, including fuel.
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
Encapsulated SAX-Attributes.
virtual std::string getString(int id, bool *isPresent=nullptr) const =0
Returns the string-value of the named (by its enum-value) attribute.
Representation of a vehicle, person, or container.
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual const MSLane * getLane() const =0
Returns the lane the object is currently at.
virtual int getRNGIndex() const =0
virtual double getMaxSpeed() const =0
Returns the object's maximum speed (minimum of technical and desired maximum speed)
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 MSEdge * getEdge() const =0
Returns the (normal) route edge the object is currently at.
bool wasSet(long long int what) const
Returns whether the given parameter was set.
double length
The physical vehicle length.
Representation of a vehicle.
Definition SUMOVehicle.h:63
virtual bool isStopped() const =0
Returns whether the vehicle is at a stop and waiting for a person or container to continue.
virtual bool hasStops() const =0
Returns whether the vehicle has to stop somewhere.
virtual const std::list< MSStop > & getStops() const =0
virtual SUMOTime sawBlockedChargingStation(const MSStoppingPlace *cs, bool local) const =0
virtual SUMOTime getDeparture() const =0
Returns this vehicle's real departure time.
virtual double getLength() const =0
Returns the vehicles's length.
virtual void rememberBlockedChargingStation(const MSStoppingPlace *cs, bool local)=0
virtual const MSStop & getNextStop() const =0
virtual MSStop & getNextStopMutable()=0
virtual void resetChargingStationScores()=0
virtual EnergyParams * getEmissionParameters() const =0
Returns the vehicle's emission model parameter.
virtual void rememberChargingStationScore(const MSStoppingPlace *cs, const std::string &score)=0
virtual const ConstMSEdgeVector::const_iterator & getCurrentRouteEdge() const =0
Returns an iterator pointing to the current edge in this vehicles route.
virtual const SUMOVehicleParameter::Stop * getNextStopParameter() const =0
Returns parameters of the next stop or nullptr.
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.
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.
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter
A wrapper for a Command function.
void deschedule()
Marks this Command as being descheduled.