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-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>
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
46
47// ===========================================================================
48// static variables
49// ===========================================================================
50
51
52// ===========================================================================
53// method definitions
54// ===========================================================================
55// ---------------------------------------------------------------------------
56// static initialisation methods
57// ---------------------------------------------------------------------------
58void
60 insertDefaultAssignmentOptions("stationfinder", "Battery", oc);
61 oc.doRegister("device.stationfinder.rescueTime", new Option_String("1800", "TIME"));
62 oc.addDescription("device.stationfinder.rescueTime", "Battery", TL("Time to wait for a rescue vehicle on the road side when the battery is empty"));
63 oc.doRegister("device.stationfinder.rescueAction", new Option_String("remove"));
64 oc.addDescription("device.stationfinder.rescueAction", "Battery", TL("How to deal with a vehicle which has to stop due to low battery: [none, remove, tow]"));
65 oc.doRegister("device.stationfinder.reserveFactor", new Option_Float(1.1));
66 oc.addDescription("device.stationfinder.reserveFactor", "Battery", TL("Scale battery need with this factor to account for unexpected traffic situations"));
67 oc.doRegister("device.stationfinder.emptyThreshold", new Option_Float(0.05));
68 oc.addDescription("device.stationfinder.emptyThreshold", "Battery", TL("Battery percentage to go into rescue mode"));
69 oc.doRegister("device.stationfinder.radius", new Option_String("180", "TIME"));
70 oc.addDescription("device.stationfinder.radius", "Battery", TL("Search radius in travel time seconds"));
71 oc.doRegister("device.stationfinder.maxEuclideanDistance", new Option_Float(-1));
72 oc.addDescription("device.stationfinder.maxEuclideanDistance", "Battery", TL("Euclidean search distance in meters (a negative value disables the restriction)"));
73 oc.doRegister("device.stationfinder.repeat", new Option_String("60", "TIME"));
74 oc.addDescription("device.stationfinder.repeat", "Battery", TL("When to trigger a new search if no station has been found"));
75 oc.doRegister("device.stationfinder.maxChargePower", new Option_Float(100000.));
76 oc.addDescription("device.stationfinder.maxChargePower", "Battery", TL("The maximum charging speed of the vehicle battery"));
77 oc.doRegister("device.stationfinder.chargeType", new Option_String("charging"));
78 oc.addDescription("device.stationfinder.chargeType", "Battery", TL("Type of energy transfer"));
79 oc.doRegister("device.stationfinder.waitForCharge", new Option_String("600", "TIME"));
80 oc.addDescription("device.stationfinder.waitForCharge", "Battery", TL("After this waiting time vehicle searches for a new station when the initial one is blocked"));
81 oc.doRegister("device.stationfinder.saturatedChargeLevel", new Option_Float(0.8));
82 oc.addDescription("device.stationfinder.saturatedChargeLevel", "Battery", TL("Target state of charge after which the vehicle stops charging"));
83 oc.doRegister("device.stationfinder.needToChargeLevel", new Option_Float(0.4));
84 oc.addDescription("device.stationfinder.needToChargeLevel", "Battery", TL("State of charge the vehicle begins searching for charging stations"));
85 oc.doRegister("device.stationfinder.replacePlannedStop", new Option_Float(0.));
86 oc.addDescription("device.stationfinder.replacePlannedStop", "Battery", TL("Share of stopping time of the next independently planned stop to use for charging instead"));
87 oc.doRegister("device.stationfinder.maxDistanceToReplacedStop", new Option_Float(300.));
88 oc.addDescription("device.stationfinder.maxDistanceToReplacedStop", "Battery", TL("Maximum distance in meters from the original stop to be replaced by the charging stop"));
89 oc.doRegister("device.stationfinder.chargingStrategy", new Option_String("none"));
90 oc.addDescription("device.stationfinder.chargingStrategy", "Battery", TL("Set a charging strategy to alter time and charging load from the set: [none, balanced, latest]"));
91}
92
93
94
95void
96MSDevice_StationFinder::buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into) {
98 if (equippedByDefaultAssignmentOptions(oc, "stationfinder", v, false)) {
99 into.push_back(new MSDevice_StationFinder(v));
100 }
101}
102
103
104// ---------------------------------------------------------------------------
105// MSDevice_StationFinder-methods
106// ---------------------------------------------------------------------------
108 : MSVehicleDevice(holder, "stationfinder_" + holder.getID()),
109 MSStoppingPlaceRerouter(SUMO_TAG_CHARGING_STATION, "device.stationfinder.charging", true, false, {
110 {"waitingTime", 1.}, {"chargingTime", 1.}
111}, { {"waitingTime", false}, {"chargingTime", false} }),
112myVeh(dynamic_cast<MSVehicle&>(holder)),
113myBattery(nullptr), myChargingStation(nullptr), myRescueCommand(nullptr), myChargeLimitCommand(nullptr),
114myLastChargeCheck(0), myCheckInterval(1000), myArrivalAtChargingStation(-1), myLastSearch(-1) {
115 // consider whole path to/from a charging station in the search
116 myEvalParams["distanceto"] = 0.;
117 myEvalParams["timeto"] = 1.;
118 myEvalParams["timefrom"] = 1.;
119 myNormParams["chargingTime"] = true;
120 myNormParams["waitingTime"] = true;
121 myRescueTime = STEPS2TIME(holder.getTimeParam("device.stationfinder.rescueTime"));
122 const std::string chargingStrategy = holder.getStringParam("device.stationfinder.chargingStrategy");
123 if (chargingStrategy == "balanced") {
124 myChargingStrategy = CHARGINGSTRATEGY_BALANCED;
125 } else if (chargingStrategy == "latest") {
126 myChargingStrategy = CHARGINGSTRATEGY_LATEST;
127 } else if (chargingStrategy == "none") {
128 myChargingStrategy = CHARGINGSTRATEGY_NONE;
129 } else {
130 WRITE_ERRORF(TL("Invalid device.stationfinder.chargingStrategy '%'."), chargingStrategy);
131 }
132 const std::string rescueAction = holder.getStringParam("device.stationfinder.rescueAction");
133 if (rescueAction == "remove") {
134 myRescueAction = RESCUEACTION_REMOVE;
135 } else if (rescueAction == "tow") {
136 myRescueAction = RESCUEACTION_TOW;
137 } else if (rescueAction == "none") {
138 myRescueAction = RESCUEACTION_NONE;
139 } else {
140 WRITE_ERRORF(TL("Invalid device.stationfinder.rescueAction '%'."), rescueAction);
141 }
142 initRescueCommand();
143 myReserveFactor = MAX2(1., holder.getFloatParam("device.stationfinder.reserveFactor"));
144 myEmptySoC = MAX2(0., MIN2(holder.getFloatParam("device.stationfinder.emptyThreshold"), 1.));
145 myRadius = holder.getTimeParam("device.stationfinder.radius");
146 myMaxEuclideanDistance = holder.getFloatParam("device.stationfinder.maxEuclideanDistance");
147 myRepeatInterval = holder.getTimeParam("device.stationfinder.repeat");
148 myMaxChargePower = holder.getFloatParam("device.stationfinder.maxChargePower");
149 myChargeType = CHARGETYPE_CHARGING;
150
151 myWaitForCharge = holder.getTimeParam("device.stationfinder.waitForCharge");
152 myTargetSoC = MAX2(0., MIN2(holder.getFloatParam("device.stationfinder.saturatedChargeLevel"), 1.));
153 mySearchSoC = MAX2(0., MIN2(holder.getFloatParam("device.stationfinder.needToChargeLevel"), 1.));
154 if (mySearchSoC <= myEmptySoC) {
155 WRITE_WARNINGF(TL("Vehicle '%' searches for charging stations only in the rescue case due to search threshold % <= rescue threshold %."), myHolder.getID(), mySearchSoC, myEmptySoC);
156 }
157 myReplacePlannedStop = MAX2(0., holder.getFloatParam("device.stationfinder.replacePlannedStop"));
158 myDistanceToOriginalStop = holder.getFloatParam("device.stationfinder.maxDistanceToReplacedStop");
159 myUpdateSoC = -1.; // MAX2(0., mySearchSoC - DEFAULT_SOC_INTERVAL);
160}
161
162
164 // make the rescue command invalid if there is one
165 if (myRescueCommand != nullptr) {
167 }
168 if (myChargeLimitCommand != nullptr) {
170 }
171}
172
173
174bool
175MSDevice_StationFinder::notifyMove(SUMOTrafficObject& veh, double /*oldPos*/, double /*newPos*/, double /*newSpeed*/) {
176 if (myBattery->getEnergyCharged() > 0. && myChargingStation != nullptr) {
178 myChargingStation = nullptr;
180 return true;
181 } else if (mySearchState == SEARCHSTATE_CHARGING) {
182 if (myBattery->getChargingStationID() == "") {
184 } else {
185 return true;
186 }
187 }
188 // check if the vehicle travels at most an edge length to the charging station after jump/teleport
190 return true;
191 }
192 const SUMOTime now = SIMSTEP;
193 if (myChargingStation != nullptr) {
195 // waited for too long, try another charging station
196 if (rerouteToChargingStation(true)) {
197 WRITE_MESSAGE(TLF("Rerouted vehicle '%' after waiting too long at the previous charging station at time=%.", veh.getID(), toString(SIMTIME)));
198 }
200 // remember when the vehicle arrived close to the target charging station
203 }
204 }
206 if (currentSoC > mySearchSoC || mySearchState == SEARCHSTATE_BROKEN_DOWN) {
207 // battery SoC is too high to look for charging facilities or the vehicle is already in rescue mode
208 return true;
209 }
210 // only check once per second
211 if (now - myLastChargeCheck < 1000) {
212 return true;
213 } else if (myRescueAction != RESCUEACTION_NONE && (currentSoC < myEmptySoC || currentSoC < NUMERICAL_EPS)) {
214
215 // vehicle has to stop at the end of the because battery SoC is too low
216 double brakeGap = myVeh.getCarFollowModel().brakeGap(myVeh.getSpeed());
217 std::pair<const MSLane*, double> stopPos = myVeh.getLanePosAfterDist(brakeGap);
218 if (stopPos.first != nullptr) {
219 const MSLane* stopLane = (stopPos.first->isInternal()) ? stopPos.first->getNormalSuccessorLane() : stopPos.first;
220 double endPos = stopPos.second;
221 if (stopLane != stopPos.first) {
222 endPos = MIN2(POSITION_EPS, stopLane->getLength());
223 }
224 // remove possibly scheduled charging stop
225 if (myVeh.hasStops() && myVeh.getStop(0).chargingStation != nullptr) {
227 }
228
229 // schedule the rescue stop
231 rescueStop.index = 0;
232 rescueStop.edge = stopLane->getEdge().getID();
233 rescueStop.lane = stopLane->getID();
234 rescueStop.startPos = MAX2(endPos - 2 * myHolder.getVehicleType().getLength(), 0.);
235 rescueStop.endPos = endPos;
237 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));
238
240 // remove vehicle from network
241 rescueStop.until = SUMOTime_MAX;
242 rescueStop.breakDown = true;
243 std::string errorMsg = "Could not insert the rescue stop.";
244 if (!myVeh.insertStop(0, rescueStop, "stationfinder:rescue", false, errorMsg)) {
245 WRITE_ERROR(errorMsg);
246 }
248 return true;
249 } else if (myRescueAction == RESCUEACTION_TOW) {
250 // wait next to the road and get teleported to a charging station
251 SUMOTime rescueTime = TIME2STEPS(myRescueTime);
252 rescueStop.duration = rescueTime;
253 rescueStop.parking = ParkingType::ONROAD;
254 rescueStop.jump = 0;
255 std::string errorMsg = "Could not insert the rescue stop.";
256 if (!myVeh.insertStop(0, rescueStop, "stationfinder:rescue", false, errorMsg)) {
257 WRITE_ERROR(errorMsg);
258 }
262 return true;
263 }
264 }
265 } else if (myChargingStation == nullptr &&
266 (myUpdateSoC < 0. || myUpdateSoC - currentSoC > DEFAULT_SOC_INTERVAL || (mySearchState == SEARCHSTATE_UNSUCCESSFUL &&
268 // check if a charging stop is already planned without the device, otherwise reroute inside this device
269 if (!alreadyPlannedCharging() && now > myHolder.getDeparture()) {
271 }
272 myUpdateSoC = currentSoC;
273 }
275 return true;
276}
277
278
279bool
283
284
285void
289 std::vector<std::string> internals;
290 internals.push_back(toString(myLastChargeCheck));
291 internals.push_back(toString(myUpdateSoC));
292 internals.push_back(toString(mySearchSoC));
293 internals.push_back(toString(myTargetSoC));
294 internals.push_back(toString(myWaitForCharge));
295 internals.push_back(toString(myRepeatInterval));
296 internals.push_back(toString(myRadius));
297 internals.push_back(toString(myLastSearch));
298 internals.push_back(toString(myReserveFactor));
299 internals.push_back(toString(mySearchState));
300 internals.push_back(toString(myArrivalAtChargingStation));
301 internals.push_back((myChargingStation == nullptr) ? "NULL" : myChargingStation->getID());
302 internals.push_back(toString(myChargeLimits.size()));
303 for (auto chargeLimit : myChargeLimits) {
304 internals.push_back(toString(chargeLimit.first));
305 internals.push_back(toString(chargeLimit.second));
306 }
307 out.writeAttr(SUMO_ATTR_STATE, toString(internals));
308 out.closeTag();
309}
310
311
312void
314 std::istringstream bis(attrs.getString(SUMO_ATTR_STATE));
315 bis >> myLastChargeCheck;
316 bis >> myUpdateSoC;
317 bis >> mySearchSoC;
318 bis >> myTargetSoC;
319 bis >> myWaitForCharge;
320 bis >> myRepeatInterval;
321 bis >> myRadius;
322 bis >> myLastSearch;
323 bis >> myReserveFactor;
324 int searchState;
325 bis >> searchState;
326 mySearchState = (SearchState)searchState;
328 std::string csID;
329 bis >> csID;
330 if (csID != "NULL") {
332 }
333 int chargeLimitCount = 0;
334 bis >> chargeLimitCount;
335 for (int i = 0; i < chargeLimitCount; ++i) {
336 SUMOTime t = 0;
337 double limit = 0.;
338 bis >> t;
339 bis >> limit;
340 myChargeLimits.push_back({ t, limit });
341 }
342}
343
344
345void
347 const double /* frontOnLane */,
348 const double /* timeOnLane */,
349 const double /* meanSpeedFrontOnLane */,
350 const double /* meanSpeedVehicleOnLane */,
351 const double /* travelledDistanceFrontOnLane */,
352 const double /* travelledDistanceVehicleOnLane */,
353 const double /* meanLengthOnLane */) {
354
355 // called by meso (see MSMeanData_Emissions::MSLaneMeanDataValues::notifyMoveInternal)
356}
357
358
360MSDevice_StationFinder::findChargingStation(SUMOAbstractRouter<MSEdge, SUMOVehicle>& /*router*/, double expectedConsumption, StoppingPlaceParamMap_t& scores, bool constrainTT, bool skipVisited, bool skipOccupied) {
361 MSChargingStation* minStation = nullptr;
362 std::vector<StoppingPlaceVisible> candidates;
363 const StoppingPlaceMemory* chargingMemory = myVeh.getChargingMemory();
364 if (chargingMemory == nullptr) {
365 skipVisited = false;
366 }
367 const SUMOTime stoppingPlaceMemory = TIME2STEPS(getWeight(myHolder, "memory", 600));
369 MSChargingStation* cs = static_cast<MSChargingStation*>(stop.second);
370 if (cs->getEfficency() < NUMERICAL_EPS || cs->getChargingPower(false) < NUMERICAL_EPS) {
371 continue;
372 }
373 if (cs->getParkingArea() != nullptr && !cs->getParkingArea()->accepts(&myVeh)) {
374 // skip stations where the linked parking area does not grant access to the device holder
375 continue;
376 }
377 if (skipOccupied && freeSpaceAtChargingStation(cs) < 1.) {
378 continue;
379 }
380 if (skipVisited && chargingMemory->sawBlockedStoppingPlace(cs, false) > 0 && SIMSTEP - chargingMemory->sawBlockedStoppingPlace(cs, false) < stoppingPlaceMemory) {
381 // skip recently visited
382 continue;
383 }
384 if (constrainTT && myMaxEuclideanDistance > 0 && stop.second->getLane().geometryPositionAtOffset(stop.second->getBeginLanePosition()).distanceTo2D(myHolder.getPosition()) > myMaxEuclideanDistance) {
385 // skip probably too distant charging stations
386 continue;
387 }
388 candidates.push_back({cs, false});
389 }
390 ConstMSEdgeVector newRoute;
391 scores["expectedConsumption"] = expectedConsumption;
392 std::vector<double> probs(candidates.size(), 1.);
393 bool newDestination;
394 myCheckValidity = constrainTT;
395 MSStoppingPlace* bestCandidate = reroute(candidates, probs, myHolder, newDestination, newRoute, scores);
396 myCheckValidity = true;
397 minStation = dynamic_cast<MSChargingStation*>(bestCandidate);
398 return minStation;
399}
400
401
402bool
405 if (myBattery->getActualBatteryCapacity() < expectedConsumption) {
408 StoppingPlaceParamMap_t scores = {};
409 MSChargingStation* cs = findChargingStation(router, expectedConsumption, scores);
410 if (cs != nullptr) {
411 // integrate previously planned stops which do not have charging facilities
414 stopPar.chargingStation = cs->getID();
415 if (cs->getParkingArea() != nullptr) {
416 stopPar.parkingarea = cs->getParkingArea()->getID();
418 }
419 stopPar.edge = cs->getLane().getEdge().getID();
420 stopPar.lane = cs->getLane().getID();
421 stopPar.duration = TIME2STEPS(expectedConsumption / (cs->getChargingPower(false) * cs->getEfficency()));
423 if (myReplacePlannedStop > 0) {
424 // "reuse" a previously planned stop (stop at charging station instead of a different stop)
425 // what if the charging station is skipped due to long waiting time?
427 // compare the distance to the original target
428 if (scores["distfrom"] < myDistanceToOriginalStop /*actualDist < myDistanceToOriginalStop*/) {
429 // compute the arrival time at the original stop
430 const SUMOTime timeToOriginalStop = TIME2STEPS(scores["timefrom"]);
431 const SUMOTime originalUntil = myHolder.getNextStopParameter()->until;
432 if (timeToOriginalStop + myLastSearch < originalUntil) {
433 const SUMOTime delta = originalUntil - (timeToOriginalStop + myLastSearch);
434 stopPar.until = timeToOriginalStop + myLastSearch + (SUMOTime)((double)delta * MIN2(myReplacePlannedStop, 1.));
435 stopPar.parametersSet |= STOP_UNTIL_SET;
436 if (myReplacePlannedStop > 1.) {
438 }
439 // optionally implement a charging strategy by adjusting the accepted charging rates
441 // the charging strategy should actually only be computed at the arrival at the charging station
442 implementChargingStrategy(myLastSearch + TIME2STEPS(scores["timeto"]), stopPar.until, expectedConsumption, cs);
443 }
444 }
445 }
446 }
447 }
448 stopPar.startPos = cs->getBeginLanePosition();
449 stopPar.endPos = cs->getEndLanePosition();
450 std::string errorMsg;
451#ifdef DEBUG_STATIONFINDER_REROUTE
452 std::ostringstream os;
453 const ConstMSEdgeVector edgesBefore = myVeh.getRoute().getEdges();
454 for (auto edge : edgesBefore) {
455 os << edge->getID() << " ";
456 }
457 std::cout << "MSDevice_StationFinder::rerouteToChargingStation: \n\tRoute before scheduling the charging station: " << os.str() << "\n";
458#endif
459 if ((replace && !myVeh.replaceStop(0, stopPar, "stationfinder:search", false, errorMsg)) || (!replace && !myVeh.insertStop(0, stopPar, "stationfinder:search", false, errorMsg))) {
460 WRITE_MESSAGE(TLF("Problem with inserting the charging station stop for vehicle %.", myHolder.getID()));
461 WRITE_ERROR(errorMsg);
462 }
463
464#ifdef DEBUG_STATIONFINDER_REROUTE
465 std::ostringstream os2;
466 const ConstMSEdgeVector edgesAfter = myVeh.getRoute().getEdges();
467 for (auto edge : edgesAfter) {
468 os2 << edge->getID() << " ";
469 }
470 std::cout << "\tRoute after scheduling the charging station: " << os2.str() << "\n";
471#endif
474#ifdef DEBUG_STATIONFINDER_REROUTE
475 std::cout << "\tVehicle " << myHolder.getID() << " gets rerouted to charging station " << cs->getID() << " on edge " << stopPar.edge << " at time " << SIMTIME << "\n";
476#endif
477 return true;
478 }
480 WRITE_MESSAGEF(TL("Vehicle '%' wants to charge at time=% but does not find any charging station nearby."), myHolder.getID(), toString(SIMTIME));
481 }
482 return false;
483}
484
485
488 // find closest charging station
490 double expectedConsumption = MIN2(estimateConsumption(nullptr, true, STEPS2TIME(myVeh.getStops().front().pars.duration)) * myReserveFactor, myBattery->getMaximumBatteryCapacity() * myTargetSoC);
491 StoppingPlaceParamMap_t scores = {};
492 MSChargingStation* cs = findChargingStation(router, expectedConsumption, scores, false, false, true);
493 if (cs == nullptr) {
494 // continue waiting if all charging stations are occupied
495#ifdef DEBUG_STATIONFINDER_RESCUE
496 std::cout << "MSDevice_StationFinder::teleportToChargingStation: No charging station available to teleport the broken-down vehicle " << myHolder.getID() << " to at time " << SIMTIME << ".\n.";
497#endif
498 // remove the vehicle if teleport to a charging station fails
499 if (myHolder.isStopped()) {
500 MSStop& currentStop = myHolder.getNextStop();
501 currentStop.duration += DELTA_T;
502 SUMOVehicleParameter::Stop& stopPar = const_cast<SUMOVehicleParameter::Stop&>(currentStop.pars);
503 stopPar.jump = -1;
504 stopPar.breakDown = true;
506 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));
507 }
508#ifdef DEBUG_STATIONFINDER_RESCUE
509 else {
510#ifdef DEBUG_STATIONFINDER_RESCUE
511 std::cout << "MSDevice_StationFinder::teleportToChargingStation: Rescue stop of " << myHolder.getID() << " ended prematurely before regular end at " << SIMTIME << ".\n.";
512#endif
513 }
514#endif
515 return myRepeatInterval;
516 }
517
518 // teleport to the charging station, stop there for charging
521 stopPar.chargingStation = cs->getID();
522 if (cs->getParkingArea() != nullptr) {
523 stopPar.parkingarea = cs->getParkingArea()->getID();
525 }
526 stopPar.edge = cs->getLane().getEdge().getID();
527 stopPar.lane = cs->getLane().getID();
528 stopPar.startPos = cs->getBeginLanePosition();
529 stopPar.endPos = cs->getEndLanePosition();
530 stopPar.duration = TIME2STEPS(expectedConsumption / (cs->getChargingPower(false) * cs->getEfficency()));
531 std::string errorMsg;
532 if (!myVeh.insertStop(1, stopPar, "stationfinder:search", true, errorMsg)) {
533 WRITE_ERROR(errorMsg);
534 }
536 myRescueCommand = nullptr;
537 return 0;
538}
539
540
541double
542MSDevice_StationFinder::estimateConsumption(const MSEdge* target, const bool includeEmptySoC, const double stopDiscount) const {
543 const SUMOTime now = SIMSTEP;
545 const ConstMSEdgeVector& route = myHolder.getRoute().getEdges();
546 ConstMSEdgeVector::const_iterator targetIt = (target == nullptr) ? route.end() : std::find(route.begin(), route.end(), target) + 1;
547 const ConstMSEdgeVector remainingRoute(route.begin() + myHolder.getRoutePosition(), targetIt);
548 const double remainingTime = router.recomputeCosts(remainingRoute, &myHolder, now);
549 if (now > myHolder.getDeparture()) {
550 const double totalConsumption = myBattery->getTotalConsumption();
551 double expectedConsumption = 0.;
552 double passedTime = STEPS2TIME(now - myHolder.getDeparture());
553 if (totalConsumption > 0. && passedTime - stopDiscount > DEFAULT_CONSUMPTION_ESTIMATE_HISTORY) {
554 expectedConsumption = totalConsumption / (passedTime - stopDiscount) * remainingTime;
555 } else {
556 // fallback consumption rate for vehicles starting with low battery
557 const double speed = MIN2(myHolder.getMaxSpeed(), myHolder.getLane()->getSpeedLimit());
560 speed * 0.8, 0., 0., params) * (remainingTime - passedTime);
561 }
562 if (includeEmptySoC) {
564 }
566 return expectedConsumption;
567 }
568 return 0.;
569}
570
571
572double
576
577
578bool
580 if (myChargingStation == nullptr) {
581 auto stops = myHolder.getStops();
582 for (auto stop : stops) {
583 if (stop.chargingStation != nullptr) {
584 // compare whether we'll make it there without intermediate charging
585 double expectedConsumption = estimateConsumption(*stop.edge);
586 if (myBattery->getActualBatteryCapacity() < expectedConsumption) {
587 myChargingStation = stop.chargingStation;
588 return true;
589 }
590 }
591 }
592 }
593 return false;
594}
595
596
597void
603
604
605void
611
612
615 if (myChargeLimits.size() > 0 && myChargeLimits.begin()->first < currentTime - DELTA_T) {
616 myChargeLimits.clear();
617 }
618 if (myChargeLimits.size() > 0) {
619 double chargeLimit = myChargeLimits.begin()->second;
620 myBattery->setChargeLimit(chargeLimit);
621 if (chargeLimit < 0) {
622 WRITE_MESSAGEF(TL("The charging rate limit of vehicle '%' is lifted at time=%"), myHolder.getID(), STEPS2TIME(SIMSTEP));
623 } else {
624 WRITE_MESSAGEF(TL("The charging rate of vehicle '%' is limited to % at time=%"), myHolder.getID(), chargeLimit, STEPS2TIME(SIMSTEP));
625 }
626 myChargeLimits.erase(myChargeLimits.begin());
627 }
628 if (myChargeLimits.size() == 0) {
630 myChargeLimitCommand = nullptr;
631 return 0;
632 } else {
633 return myChargeLimits.begin()->first - currentTime;
634 }
635}
636
637
638void
640 myChargeLimits.clear();
642 const double balancedCharge = plannedCharge / STEPS2TIME(end - begin);
643 myChargeLimits.push_back({ begin, balancedCharge });
644 myChargeLimits.push_back({ end, -1});
645 } else { // CHARGINGSTRATEGY_LATEST
646 SUMOTime expectedDuration = myBattery->estimateChargingDuration(plannedCharge, cs->getChargingPower(false) * cs->getEfficency());
647 if (end - expectedDuration > begin) {
648 myChargeLimits.push_back({ begin, 0 });
649 myChargeLimits.push_back({ end - expectedDuration, -1 });
650 }
651 }
652 if (myChargeLimits.size() > 0) {
655 }
656}
657
658
659void
661 if (tripinfoOut != nullptr && myChargingStation != nullptr) {
662 tripinfoOut->openTag("stationfinder");
663 tripinfoOut->writeAttr("chargingStation", myChargingStation->getID());
664 tripinfoOut->closeTag();
665 }
666}
667
668
669std::string
670MSDevice_StationFinder::getParameter(const std::string& key) const {
671 if (key == "chargingStation") { // eventually abstract with enum
672 return (myChargingStation == nullptr) ? "" : myChargingStation->getID();
673 } else if (key == "batteryNeed") {
675 } else if (key == "needToChargeLevel") {
676 return toString(myRadius);
677 } else if (key == "saturatedChargeLevel") {
678 return toString(myRadius);
679 } else if (key == "waitForCharge") {
680 return toString(myRadius);
681 } else if (key == "repeat") {
682 return toString(myRadius);
683 } else if (key == "radius") {
684 return toString(myRadius);
685 } else if (key == "reserveFactor") {
686 return toString(myRadius);
687 }
688 throw InvalidArgument(TLF("Parameter '%' is not supported for device of type '%'", key, deviceName()));
689}
690
691
692void
693MSDevice_StationFinder::setParameter(const std::string& key, const std::string& value) {
694 double doubleValue;
695 try {
696 doubleValue = StringUtils::toDouble(value);
697 } catch (NumberFormatException&) {
698 throw InvalidArgument(TLF("Setting parameter '%' requires a number for device of type '%'", key, deviceName()));
699 }
700 if (key == "needToChargeLevel") {
701 mySearchSoC = MAX2(0., MIN2(1., doubleValue));
702 } else if (key == "saturatedChargeLevel") {
703 myTargetSoC = MAX2(0., MIN2(1., doubleValue));
704 } else if (key == "waitForCharge") {
705 myWaitForCharge = TIME2STEPS(MAX2(0., doubleValue));
706 } else if (key == "repeat") {
707 myRepeatInterval = TIME2STEPS(MAX2(0., doubleValue));
708 } else if (key == "radius") {
709 myRadius = TIME2STEPS(MAX2(0., doubleValue));
710 } else if (key == "reserveFactor") {
711 myReserveFactor = MAX2(1., doubleValue);
712 } else {
713 throw InvalidArgument(TLF("Setting parameter '%' is not supported for device of type '%'", key, deviceName()));
714 }
715}
716
717
718bool
719MSDevice_StationFinder::evaluateCustomComponents(SUMOVehicle& /* veh */, double /* brakeGap */, bool /* newDestination */,
720 MSStoppingPlace* alternative, double /* occupancy */, double /* prob */,
722 StoppingPlaceParamMap_t& stoppingPlaceValues,
723 ConstMSEdgeVector& /* newRoute */, ConstMSEdgeVector& /* stoppingPlaceApproach */,
724 StoppingPlaceParamMap_t& /* maxValues */, StoppingPlaceParamMap_t& addInput) {
725 // estimated waiting time and charging time
726 MSChargingStation* cs = dynamic_cast<MSChargingStation*>(alternative);
727 double parkingCapacity = (cs->getParkingArea() != nullptr) ? cs->getParkingArea()->getCapacity() : (cs->getEndLanePosition() - cs->getBeginLanePosition()) / myHolder.getVehicleType().getParameter().length;
728 double freeParkingCapacity = freeSpaceAtChargingStation(cs);
729 stoppingPlaceValues["waitingTime"] = (freeParkingCapacity < 1.) ? DEFAULT_AVG_WAITING_TIME / parkingCapacity : 0.;
730 stoppingPlaceValues["chargingTime"] = STEPS2TIME(cs->getChargeDelay()) + addInput["expectedConsumption"] / cs->getChargingPower(false);
731 return true;
732}
733
734
735bool
737 if (stoppingPlaceValues["timeto"] > STEPS2TIME(myRadius)) {
738 return false;
739 }
740 return true;
741}
742
743
744bool
746 return true;
747}
748
749
753
754
755double
757 MSChargingStation* cs = dynamic_cast<MSChargingStation*>(stoppingPlace);
758 if (cs->getParkingArea() != nullptr) {
759 return cs->getParkingArea()->getOccupancy();
760 }
762}
763
764
765double
767 MSChargingStation* cs = dynamic_cast<MSChargingStation*>(stoppingPlace);
768 if (cs->getParkingArea() != nullptr) {
769 return cs->getParkingArea()->getLastStepOccupancy();
770 }
772}
773
774
775double
777 MSChargingStation* cs = dynamic_cast<MSChargingStation*>(stoppingPlace);
778 if (cs->getParkingArea() != nullptr) {
779 return cs->getParkingArea()->getCapacity();
780 }
782}
783
784
785void
787 veh.rememberBlockedChargingStation(stoppingPlace, blocked);
788}
789
790
791void
793 veh.rememberChargingStationScore(place, score);
794}
795
796
797void
801
802
807
808
809int
813
814
815void
818
819
820/****************************************************************************/
long long int SUMOTime
Definition GUI.h:36
#define DEFAULT_CONSUMPTION_ESTIMATE_HISTORY
#define DEFAULT_SOC_INTERVAL
#define DEFAULT_AVG_WAITING_TIME
#define DEFAULT_CHARGINGSTATION_VIEW_DIST
std::vector< const MSEdge * > ConstMSEdgeVector
Definition MSEdge.h:74
std::vector< MSEdge * > MSEdgeVector
Definition MSEdge.h:73
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:296
#define WRITE_MESSAGEF(...)
Definition MsgHandler.h:298
#define WRITE_ERRORF(...)
Definition MsgHandler.h:305
#define WRITE_MESSAGE(msg)
Definition MsgHandler.h:297
#define WRITE_ERROR(msg)
Definition MsgHandler.h:304
#define TL(string)
Definition MsgHandler.h:315
#define TLF(string,...)
Definition MsgHandler.h:317
SUMOTime DELTA_T
Definition SUMOTime.cpp:38
#define STEPS2TIME(x)
Definition SUMOTime.h:55
#define SIMSTEP
Definition SUMOTime.h:61
#define SUMOTime_MAX
Definition SUMOTime.h:34
#define SIMTIME
Definition SUMOTime.h:62
#define TIME2STEPS(x)
Definition SUMOTime.h:57
const int STOP_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: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.
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
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:380
double getChargingPower(bool usingFuel) const
Get charging station's charging power.
SUMOTime getChargeDelay() const
Get Charge Delay.
double getEfficency() const
Get efficiency of the charging station.
const MSParkingArea * getParkingArea() const
Get the parking area the charging station is placed on.
double getActualBatteryCapacity() const
Get the actual vehicle's Battery Capacity in Wh.
void setChargeLimit(const double limit)
Set (temporary) charge limit.
double getMaximumBatteryCapacity() const
Get the total vehicle's Battery Capacity in Wh.
SUMOTime estimateChargingDuration(const double toCharge, const double csPower) const
Estimate the charging duration given the current battery state.
double getTotalConsumption() const
Get total consumption.
double getEnergyCharged() const
Get charged energy.
std::string getChargingStationID() const
Get current Charging Station ID.
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)
MSDevice_StationFinder(SUMOVehicle &holder)
Constructor.
ChargingStrategy myChargingStrategy
The chosen charging strategy.
SUMOTime teleportToChargingStation(const SUMOTime currentTime)
search for a charging station and teleport the vehicle there as a rescue measure
double myDistanceToOriginalStop
The distance in meters to the original stop replaced by the charging stop (models charging close to t...
MSVehicle & myVeh
myHolder cast to needed type
double getStoppingPlaceOccupancy(MSStoppingPlace *stoppingPlace) override
Return the number of occupied places of the StoppingPlace.
MSStoppingPlace * myChargingStation
To which station we are currently travelling.
WrappingCommand< MSDevice_StationFinder > * myChargeLimitCommand
The command responsible for limiting the charging rate (~ implement charging strategies)
static void insertOptions(OptionsCont &oc)
Inserts MSDevice_StationFinder-options.
int getNumberStoppingPlaceReroutes(SUMOVehicle &veh) override
ask how many times already the vehicle has been rerouted to another stopping place
double myTargetSoC
The target state of charge where the vehicle stops charging.
const std::string deviceName() const override
return the name for this type of device
std::string getParameter(const std::string &key) const override
try to retrieve the given parameter from this device. Throw exception for unsupported key
bool rerouteToChargingStation(bool replace=false)
reroute to a charging station
double myRescueTime
The time to wait for a rescue vehicle in case the battery is empty.
SUMOTime myLastChargeCheck
Last time the SoC was checked.
static void buildVehicleDevices(SUMOVehicle &v, std::vector< MSVehicleDevice * > &into)
Build devices for the given vehicle, if needed.
void initRescueCommand()
create the event command for teleporting in case of brake-down
bool useStoppingPlace(MSStoppingPlace *stoppingPlace) override
Whether the stopping place should be included in the search (can be used to add an additional filter)
double getLastStepStoppingPlaceOccupancy(MSStoppingPlace *stoppingPlace) override
Return the number of occupied places of the StoppingPlace from the previous time step.
double getStoppingPlaceCapacity(MSStoppingPlace *stoppingPlace) override
Return the number of places the StoppingPlace provides.
void rememberStoppingPlaceScore(SUMOVehicle &veh, MSStoppingPlace *place, const std::string &score) override
store the stopping place score in the vehicle
void saveState(OutputDevice &out) const override
Saves the state of the device.
SUMOTime myWaitForCharge
Accepted waiting time at the charging station before a place becomes available.
SUMOTime myLastSearch
Last time charging stations have been searched.
void setNumberStoppingPlaceReroutes(SUMOVehicle &veh, int value) override
update the number of reroutes for the vehicle
SUMOTime sawBlockedStoppingPlace(SUMOVehicle &veh, MSStoppingPlace *place, bool local) override
ask the vehicle when it has seen the stopping place
double mySearchSoC
The state of charge at which the vehicle starts looking for charging stations.
SUMOTime myArrivalAtChargingStation
Arrival time in the vicinity of the target charging station (to track the waiting time before accessi...
double myEmptySoC
The state of charge threshold below which rescue mode is activated.
double myMaxEuclideanDistance
The maximum euclidean distance between the vehicle and the charging station (-1 deactivates the condi...
bool validComponentValues(StoppingPlaceParamMap_t &stoppingPlaceValues) override
Whether the stopping place should be discarded due to its results from the component evaluation.
bool notifyIdle(SUMOTrafficObject &veh) override
Computes idling emission values and adds them to the emission sums.
void generateOutput(OutputDevice *tripinfoOut) const override
Called on writing tripinfo output.
SUMOAbstractRouter< MSEdge, SUMOVehicle > & getRouter(SUMOVehicle &veh, const MSEdgeVector &prohibited) override
Provide the router to use (MSNet::getRouterTT or MSRoutingEngine)
MSDevice_Battery * myBattery
The corresponding battery device.
MSChargingStation * findChargingStation(SUMOAbstractRouter< MSEdge, SUMOVehicle > &router, double expectedConsumption, StoppingPlaceParamMap_t &scores, bool constrainTT=true, bool skipVisited=true, bool skipOccupied=false)
central search function for close charging stations
bool alreadyPlannedCharging()
adopt a planned charging stop outside of the device
double freeSpaceAtChargingStation(MSChargingStation *cs) const
compute the free space at a charging station
std::vector< std::pair< SUMOTime, double > > myChargeLimits
The next charging rates to set via myChargingRateCommand.
SUMOTime myRadius
The max travel time to the next charging station.
SearchState mySearchState
The current state of the charging search (remember for decision logic)
SUMOTime myRepeatInterval
Time interval to search again for a charging station if the first attempt failed.
bool evaluateCustomComponents(SUMOVehicle &veh, double brakeGap, bool newDestination, MSStoppingPlace *alternative, double occupancy, double prob, SUMOAbstractRouter< MSEdge, SUMOVehicle > &router, StoppingPlaceParamMap_t &stoppingPlaceValues, ConstMSEdgeVector &newRoute, ConstMSEdgeVector &stoppingPlaceApproach, StoppingPlaceParamMap_t &maxValues, StoppingPlaceParamMap_t &addInput) override
Compute some custom target function components.
SUMOTime updateChargeLimit(const SUMOTime currentTime)
update the maximum charge rate of the battery to simulate charging strategies
double myReplacePlannedStop
The share of stopping time a charging stop should take from the next regulr (non-charging) stop under...
RescueAction myRescueAction
What to do when the state of charge gets very low.
bool notifyMove(SUMOTrafficObject &veh, double oldPos, double newPos, double newSpeed) override
Computes current emission values and adds them to their sums.
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
static void insertDefaultAssignmentOptions(const std::string &deviceName, const std::string &optionsTopic, OptionsCont &oc, const bool isPerson=false)
Adds common command options that allow to assign devices to vehicles.
Definition MSDevice.cpp:155
static bool equippedByDefaultAssignmentOptions(const OptionsCont &oc, const std::string &deviceName, DEVICEHOLDER &v, bool outputOptionSet, const bool isPerson=false)
Determines whether a vehicle should get a certain device.
Definition MSDevice.h:195
A road/street connecting two junctions.
Definition MSEdge.h:77
virtual void addEvent(Command *operation, SUMOTime execTimeStep=-1)
Adds an Event.
Representation of a lane in the micro simulation.
Definition MSLane.h:84
const MSLane * getNormalSuccessorLane() const
get normal lane following this internal lane, for normal lanes, the lane itself is returned
Definition MSLane.cpp:3170
double getSpeedLimit() const
Returns the lane's maximum allowed speed.
Definition MSLane.h:592
double getLength() const
Returns the lane's length.
Definition MSLane.h:606
MSEdge & getEdge() const
Returns the lane's edge.
Definition MSLane.h:764
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:185
MSEventControl * getBeginOfTimestepEvents()
Returns the event control for events executed at the begin of a time step.
Definition MSNet.h:471
MSStoppingPlace * getStoppingPlace(const std::string &id, const SumoXMLTag category) const
Returns the named stopping place of the given category.
Definition MSNet.cpp:1380
const NamedObjectCont< MSStoppingPlace * > & getStoppingPlaces(SumoXMLTag category) const
Definition MSNet.cpp:1415
int getCapacity() const
Returns the area capacity.
bool parkOnRoad() const
whether vehicles park on the road
bool accepts(MSBaseVehicle *veh) const
Return the parking accepts the vehicle (due to its given badges)
int getLastStepOccupancy() const
Returns the area occupancy at the end of the last simulation step.
int getOccupancy() const
Returns the area occupancy.
const ConstMSEdgeVector & getEdges() const
Definition MSRoute.h:125
static MSVehicleRouter & getRouterTT(const int rngIndex, SUMOVehicleClass svc, const MSEdgeVector &prohibited=MSEdgeVector())
return the vehicle router instance
MSStoppingPlace * chargingStation
(Optional) charging station if one is assigned to the stop
Definition MSStop.h:60
SUMOTime duration
The stopping duration.
Definition MSStop.h:67
const SUMOVehicleParameter::Stop pars
The stop parameter.
Definition MSStop.h:65
A lane area vehicles can halt at.
double getBeginLanePosition() const
Returns the begin position of this stop.
double getEndLanePosition() const
Returns the end position of this stop.
const MSLane & getLane() const
Returns the lane this stop is located at.
double getLastFreePos(const SUMOVehicle &forVehicle, double brakePos=0) const
Returns the last free position on this stop.
MSStoppingPlace * reroute(std::vector< StoppingPlaceVisible > &stoppingPlaceCandidates, const std::vector< double > &probs, SUMOVehicle &veh, bool &newDestination, ConstMSEdgeVector &newRoute, StoppingPlaceParamMap_t &scores, const MSEdgeVector &closedEdges={})
main method to trigger the rerouting to the "best" StoppingPlace according to the custom evaluation f...
std::map< std::string, double > StoppingPlaceParamMap_t
double getWeight(SUMOVehicle &veh, const std::string param, const double defaultWeight, const bool warn=false)
read the value of a stopping place search param, e.g. a component weight factor
Abstract in-vehicle device.
SUMOVehicle & myHolder
The vehicle that stores the device.
Representation of a vehicle in the micro simulation.
Definition MSVehicle.h:77
bool willStop() const
Returns whether the vehicle will stop on the current edge.
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:969
double getMinGap() const
Get the free space in front of vehicles of this class.
SUMOEmissionClass getEmissionClass() const
Get this vehicle type's emission class.
double getLength() const
Get vehicle's length [m].
const SUMOVTypeParameter & getParameter() const
const std::string & getID() const
Returns the id.
Definition Named.h:74
A storage for options typed value containers)
Definition OptionsCont.h:89
void addDescription(const std::string &name, const std::string &subtopic, const std::string &description)
Adds a description for an option.
void doRegister(const std::string &name, Option *o)
Adds an option under the given name.
static OptionsCont & getOptions()
Retrieves the options.
Static storage of an output device and its base (abstract) implementation.
OutputDevice & writeAttr(const SumoXMLAttr attr, const T &val)
writes a named attribute
OutputDevice & openTag(const std::string &xmlElement)
Opens an XML tag.
bool closeTag(const std::string &comment="")
Closes the most recently opened tag and optionally adds a comment.
static double compute(const SUMOEmissionClass c, const EmissionType e, const double v, const double a, const double slope, const EnergyParams *param)
Returns the amount of the emitted pollutant given the vehicle type and state (in mg/s or ml/s for fue...
virtual double recomputeCosts(const std::vector< const E * > &edges, const V *const v, SUMOTime msTime, double *lengthp=nullptr) const
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
double length
The physical vehicle length.
Representation of a vehicle.
Definition SUMOVehicle.h:62
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 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 MSStop & getNextStop()=0
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.