Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
MSDevice_ElecHybrid.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2002-2023 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// The ElecHybrid device simulates internal electric parameters of an
20// battery-assisted electric vehicle (typically a trolleybus), i.e. a vehicle
21// that is being powered by overhead wires and has also a battery pack
22// installed, that is being charged from the overhead wires.
23/****************************************************************************/
24#include <config.h>
25
26#include <string.h> //due to strncmp
27#include <ctime> //due to clock()
35#include <microsim/MSNet.h>
36#include <microsim/MSLane.h>
37#include <microsim/MSEdge.h>
38#include <microsim/MSVehicle.h>
39#include <microsim/MSGlobals.h>
41#include <mesosim/MEVehicle.h>
42#include "MSDevice_Tripinfo.h"
43#include "MSDevice_Emissions.h"
44#include "MSDevice_ElecHybrid.h"
45
46
47// ===========================================================================
48// method definitions
49// ===========================================================================
50// ---------------------------------------------------------------------------
51// static initialisation methods
52// ---------------------------------------------------------------------------
53void
55 oc.addOptionSubTopic("ElecHybrid Device");
56 insertDefaultAssignmentOptions("elechybrid", "ElecHybrid Device", oc);
57}
58
59
60void
61MSDevice_ElecHybrid::buildVehicleDevices(SUMOVehicle& v, std::vector<MSVehicleDevice*>& into) {
62 // Check if vehicle should get an 'elecHybrid' device.
64 if (equippedByDefaultAssignmentOptions(oc, "elechybrid", v, false)) {
65 // Yes, build the device.
66 // Fetch the battery capacity (if present) from the vehicle descriptor.
67 const SUMOVTypeParameter& typeParams = v.getVehicleType().getParameter();
68 const SUMOVehicleParameter& vehicleParams = v.getParameter();
69 double actualBatteryCapacity = 0;
70 /* The actual battery capacity can be a parameter of the vehicle or its vehicle type.
71 The vehicle parameter takes precedence over the type parameter. */
72 std::string attrName = toString(SUMO_ATTR_ACTUALBATTERYCAPACITY);
73 if (vehicleParams.knowsParameter(attrName)) {
74 const std::string abc = vehicleParams.getParameter(attrName, "-1");
75 try {
76 actualBatteryCapacity = StringUtils::toDouble(abc);
77 } catch (...) {
78 WRITE_WARNING("Invalid value '" + abc + "'for vehicle parameter '" + attrName + "'. Using the default of " + std::to_string(actualBatteryCapacity));
79 }
80 } else {
81 if (typeParams.knowsParameter(attrName)) {
82 const std::string abc = typeParams.getParameter(attrName, "-1");
83 try {
84 actualBatteryCapacity = StringUtils::toDouble(abc);
85 WRITE_WARNING("Vehicle '" + v.getID() + "' does not provide vehicle parameter '" + attrName + "'. Using the vehicle type value of " + std::to_string(actualBatteryCapacity));
86 } catch (...) {
87 WRITE_WARNING("Invalid value '" + abc + "'for vehicle type parameter '" + attrName + "'. Using the default of " + std::to_string(actualBatteryCapacity));
88 }
89 } else {
90 WRITE_WARNING("Vehicle '" + v.getID() + "' does not provide vehicle or vehicle type parameter '" + attrName + "'. Using the default of " + std::to_string(actualBatteryCapacity));
91 }
92 }
93
94 // obtain maximumBatteryCapacity
95 double maximumBatteryCapacity = 0;
97 if (typeParams.knowsParameter(attrName)) {
98 const std::string mbc = typeParams.getParameter(attrName, "-1");
99 try {
100 maximumBatteryCapacity = StringUtils::toDouble(mbc);
101 } catch (...) {
102 WRITE_WARNINGF(TL("Invalid value '%'for vType parameter '%'"), mbc, attrName);
103 }
104 } else {
105 WRITE_WARNING("Vehicle '" + v.getID() + "' is missing the vType parameter '" + attrName + "'. Using the default of " + std::to_string(maximumBatteryCapacity));
106 }
107
108 // obtain overheadWireChargingPower
109 double overheadWireChargingPower = 0;
111 if (typeParams.knowsParameter(attrName)) {
112 const std::string ocp = typeParams.getParameter(attrName, "-1");
113 try {
114 overheadWireChargingPower = StringUtils::toDouble(ocp);
115 } catch (...) {
116 WRITE_WARNINGF(TL("Invalid value '%'for vType parameter '%'"), ocp, attrName);
117 }
118 } else {
119 WRITE_WARNING("Vehicle '" + v.getID() + "' is missing the vType parameter '" + attrName + "'. Using the default of " + std::to_string(overheadWireChargingPower));
120 }
121
122 // elecHybrid constructor
123 MSDevice_ElecHybrid* device = new MSDevice_ElecHybrid(v, "elecHybrid_" + v.getID(),
124 actualBatteryCapacity, maximumBatteryCapacity, overheadWireChargingPower);
125
126 // Add device to vehicle
127 into.push_back(device);
128 }
129}
130
131
132// ---------------------------------------------------------------------------
133// MSDevice_ElecHybrid-methods
134// ---------------------------------------------------------------------------
136 const double actualBatteryCapacity, const double maximumBatteryCapacity, const double overheadWireChargingPower) :
137 MSVehicleDevice(holder, id),
138 myActualBatteryCapacity(0), // [actualBatteryCapacity <= maximumBatteryCapacity]
139 myMaximumBatteryCapacity(0), // [maximumBatteryCapacity >= 0]t
140 myOverheadWireChargingPower(0),
141 myLastAngle(NAN),
142 myConsum(0),
143 myBatteryDischargedLogic(false),
144 myCharging(false), // Initially vehicle don't charge
145 myEnergyCharged(0), // Initially the energy charged is zero
146 myCircuitCurrent(NAN), // Initially the current is unknown
147 myCircuitVoltage(NAN), // Initially the voltage is unknown as well
148 myMaxBatteryCharge(NAN), // Initial maximum of the the battery energy during the simulation is unknown
149 myMinBatteryCharge(NAN), // Initial minimum of the the battery energy during the simulation is unknown
150 myTotalEnergyConsumed(0), // No energy spent yet
151 myTotalEnergyRegenerated(0), // No energy regenerated
152 myTotalEnergyWasted(0), // No energy wasted on resistors
153 // RICE_TODO: make these two parameters user configurable
154 mySOCMin(0.005), // Minimum SOC of the battery
155 mySOCMax(0.980), // Maximum SOC of the battery
156 myActOverheadWireSegment(nullptr), // Initially the vehicle isn't under any overhead wire segment
157 myPreviousOverheadWireSegment(nullptr), // Initially the vehicle wasn't under any overhead wire segment
158 veh_elem(nullptr),
159 veh_pos_tail_elem(nullptr),
160 pos_veh_node(nullptr) {
161
164
165 if (maximumBatteryCapacity < 0) {
166 WRITE_WARNINGF(TL("ElecHybrid builder: Vehicle '%' doesn't have a valid value for parameter % (%)."), getID(), toString(SUMO_ATTR_MAXIMUMBATTERYCAPACITY), toString(maximumBatteryCapacity));
167 } else {
168 myMaximumBatteryCapacity = maximumBatteryCapacity;
169 }
170
171 if (actualBatteryCapacity > maximumBatteryCapacity) {
172 WRITE_WARNING("ElecHybrid builder: Vehicle '" + getID() + "' has a " + toString(SUMO_ATTR_ACTUALBATTERYCAPACITY) + " (" + toString(actualBatteryCapacity) + ") greater than it's " + toString(SUMO_ATTR_MAXIMUMBATTERYCAPACITY) + " (" + toString(maximumBatteryCapacity) + "). A max battery capacity value will be asigned");
174 } else {
175 myActualBatteryCapacity = actualBatteryCapacity;
176 }
177
178 if (overheadWireChargingPower < 0) {
179 WRITE_WARNINGF(TL("ElecHybrid builder: Vehicle '%' doesn't have a valid value for parameter % (%)."), getID(), toString(SUMO_ATTR_OVERHEADWIRECHARGINGPOWER), toString(overheadWireChargingPower));
180 } else {
181 myOverheadWireChargingPower = overheadWireChargingPower;
182 }
183
195}
196
197
200
201
202bool
203MSDevice_ElecHybrid::notifyMove(SUMOTrafficObject& tObject, double /* oldPos */, double /* newPos */, double /* newSpeed */) {
204 if (!tObject.isVehicle()) {
205 return false;
206 }
207 SUMOVehicle& veh = static_cast<SUMOVehicle&>(tObject);
208 // Do not compute the current consumption here anymore:
209 // myConsum is (non-systematically, we agree) set in MSVehicle so that the vehicle `vNext` value can
210 // be influenced by the maximum traction power of the vehicle (i.e. installing a 80 kWh powertrain will
211 // limit the acceleration regardless of the acceleration specified in vehicleType params, in case that
212 // the vehicleType acceleration is too high).
213 //
214 // myParam[SUMO_ATTR_ANGLE] = myLastAngle == std::numeric_limits<double>::infinity() ? 0. : GeomHelper::angleDiff(myLastAngle, veh.getAngle());
215 // myConsum = PollutantsInterface::getEnergyHelper().compute(0, PollutantsInterface::ELEC, veh.getSpeed(), veh.getAcceleration(), veh.getSlope(), &myParam);
216 assert(!std::isnan(myConsum));
217
218 // is battery pack discharged (from previous timestep)
221 } else {
223 }
224
225 /* If battery is discharged we will force the vehicle to slowly come to
226 a halt (freewheel motion). It could still happen that some energy will
227 be recovered in later steps due to regenerative braking. */
228 if (isBatteryDischarged()) {
229 std::vector<std::pair<SUMOTime, double> > speedTimeLine;
233 double accel = acceleration(veh, 0, veh.getSpeed()); // or use veh.getAcceleration() method???
234 const double nextSpeed = MAX2(0., veh.getSpeed() + ACCEL2SPEED(accel));
235 speedTimeLine.push_back(
236 std::make_pair(
237 MSNet::getInstance()->getCurrentTimeStep(),
238 veh.getSpeed()));
239 speedTimeLine.push_back(
240 std::make_pair(
241 MSNet::getInstance()->getCurrentTimeStep() + DELTA_T,
242 nextSpeed));
243
244 static_cast<MSVehicle*>(&veh)->getInfluencer().setSpeedTimeLine(speedTimeLine);
245 }
246
247 /* Check if there is an overhead wire either over the lane where the vehicle is or over a
248 neighbouring lanes. This check has to be performed at every simulation step as the
249 overhead wires for trolleybuses will typically end at a bus stop that is located somewhere
250 in the middle of the lane. */
251 std::string overheadWireSegmentID = MSNet::getInstance()->getStoppingPlaceID(veh.getLane(), veh.getPositionOnLane(), SUMO_TAG_OVERHEAD_WIRE_SEGMENT);
252
253 //check overhead line on the left neighbouring lane
254 if (overheadWireSegmentID == "" && veh.getEdge()->leftLane(veh.getLane()) != nullptr) {
256 }
257 //check overhead line on the right neighbouring lane
258 if (overheadWireSegmentID == "" && veh.getEdge()->rightLane(veh.getLane()) != nullptr) {
260 }
261
262 /* Store the amount of power that could not be recuperated. */
263 double energyWasted = 0.0;
264 /* If vehicle has access to an overhead wire (including the installation on neighbouring lanes) */
265 if (overheadWireSegmentID != "") {
266 /* Update the actual overhead wire segment of this device */
269 /* Store the traction substation of the actual overhead wire segment */
271
272 /* Disable charging from previous (not the actual) overhead wire segment.
273 REASON:
274 If there is no gap between two different overhead wire segments that are
275 places on the same lane, the vehicle switches from the one segment to another
276 in one timestep. */
278 if (myPreviousOverheadWireSegment != nullptr) {
279 /* Remove the vehicle from the list of vehicles powered by the previous segment. */
282 if (ts != nullptr) {
284 ts->eraseVehicle(this);
285 }
286 }
287 /* Add the vehicle reference to the current segment. */
289 if (actualSubstation != nullptr) {
290 actualSubstation->increaseElecHybridCount();
291 actualSubstation->addVehicle(this);
292 }
293 }
294
295 /* Do we simulate the behaviour of the overhead wire electric circuit? */
297#ifdef HAVE_EIGEN
299 /* Circuit update due to vehicle movement:
300 Delete vehicle resistor element, vehicle resistor nodes and vehicle resistor
301 tails in the circuit used in the previous timestep. */
303
304 /* Add the vehicle to the circuit in case that there is a substation that provides
305 power to it. */
306 if (actualSubstation != nullptr) {
307 /* Add a resistor (current source in the future?) representing trolleybus
308 vehicle to the circuit.
309 pos/neg_veh_node elements
310 [0] .... vehicle_resistor
311 [1] .... leading resistor
312 [2] .... tail resistor pos/neg_tail_vehID
313 */
314
315 // pos_veh_node and veh_elem should be NULL
316 if (pos_veh_node != nullptr || veh_elem != nullptr) {
317 WRITE_WARNING("pos_veh_node or neg_veh_node or veh_elem is not NULL (and they should be at the beginning of adding elecHybrid to the circuit)");
318 }
319
320 // create pos and veh_elem
322 pos_veh_node = owc->addNode("pos_" + veh.getID());
323 assert(pos_veh_node != nullptr);
324 // adding current source element representing elecHybrid vehicle. The value of current is computed from wantedPower later by circuit solver. Thus NAN is used as an initial value.
325 veh_elem = owc->addElement("currentSrc" + veh.getID(), NAN,
326 pos_veh_node, owc->getNode("negNode_ground"),
328
329 // Connect vehicle to an existing overhead wire segment = add elecHybridVehicle to the myActOverheadWireSegment circuit
330 // Find pos resistor element of the actual overhead line section and their end nodes
331 Element* element_pos = owc->getElement("pos_" + myActOverheadWireSegment->getID());
332 Node* node_pos = element_pos->getNegNode();
333 double resistance = element_pos->getResistance();
334
335 /* Find the correct position of the vehicle at the overhead line.
336 We start the while loop at the end of the actual overhead line section and go against the direction of vehicle movement.
337 The decision rule is based on the resistance value:
338 * from the vehicle position to the end of lane,
339 * sum of resistance of elements (going from the end of ovehead line section in the contrary direction).
340
341 The original solution runs into problems when a vehicle is going on a neigboring lane and the two lanes have different lengths:
342 while (resistance < (veh.getLane()->getLength() - veh.getPositionOnLane())*WIRE_RESISTIVITY) {
343 Improvement: take the relative distance of the vehicle to the end of its lane and map it to the segment's lane length. (This works also in case that the segment's lane and the vehicle's lane are identical.)
344 */
345 double relativePosOnSegment =
347 (veh.getPositionOnLane() / veh.getLane()->getLength()));
348
349 while (resistance < relativePosOnSegment * WIRE_RESISTIVITY) {
350 node_pos = element_pos->getPosNode();
351 element_pos = node_pos->getElements()->at(2);
352 resistance += element_pos->getResistance();
353 if (strncmp(element_pos->getName().c_str(), "pos_tail_", 9) != 0) {
354 WRITE_WARNING("splitting element is not 'pos_tail_XXX'")
355 }
356 }
357
358 node_pos = element_pos->getPosNode();
359 //resistance of vehicle tail nodes
360 resistance -= relativePosOnSegment * WIRE_RESISTIVITY;
361
362 /* dividing element_pos
363 before: |node_pos|---------------------------------------------|element_pos|----
364 after: |node_pos|----|veh_pos_tail_elem|----|pos_veh_node|----|element_pos|----
365 */
366 element_pos->setPosNode(pos_veh_node);
367 node_pos->eraseElement(element_pos);
368 pos_veh_node->addElement(element_pos);
369
370 veh_pos_tail_elem = owc->addElement("pos_tail_" + veh.getID(),
372
373 if (element_pos->getResistance() - resistance < 0) {
374 WRITE_WARNINGF(TL("The resistivity of overhead wire segment connected to vehicle % is < 0. Set to 1e-6."), veh.getID());
375 }
376
377 element_pos->setResistance(element_pos->getResistance() - resistance);
378
379
380 // Set the power requirement to the consumption + charging power.
381 // RICE_TODO: The charging power could be different when moving and when not. Add a parameter.
382 // Note that according to PMDP data, the charging power seems to be the same in both situations,
383 // ignoreing the potential benefits of using a higher charging power when the vehicle is moving.
386 } else {
388 }
389
390 // No recuperation to overheadwire (only to the batterypack)
392 // the value of energyWasted is properly computed and updated after solving circuit by the solver
393 // energyWasted = 0;
395 }
396
397 // RICE_TODO: The voltage in the solver should never exceed or drop below some limits. Maximum allowed voltage is typicallty 800 V.
398 // The numerical solver that computes the circuit state needs initial values of electric currents and
399 // voltages from which it will start the iterative solving process. We prefer to reuse the "old" values
400 // as it is likely that the new values will not be far away from the old ones. The safety limits of
401 // 10 and 1500 Volts that are used below are chosen fairly arbitrarily to keep the initial values within
402 // reasonable limits.
403 double voltage = myCircuitVoltage;
404 if (voltage < 10.0 || voltage > 1500.0 || std::isnan(voltage)) {
405 // RICE_TODO : It seems to output warning whenever a vehicle is appearing under the overhead wire for the first time?
406 // WRITE_WARNINGF(TL("The initial voltage is was % V, replacing it with substation voltage % V."), toString(voltage), toString(actualSubstation->getSubstationVoltage()));
407 voltage = actualSubstation->getSubstationVoltage();
408 }
409 // Initial value of the electric current flowing into the vehilce that will be used by the solver
410 double current = -(veh_elem->getPowerWanted() / voltage);
411 veh_elem->setCurrent(current);
412
413 // Set the device as charging the battery by default
414 myCharging = true;
415
416 // And register the call to solver at the end of the simulation step
417 actualSubstation->addSolvingCirucitToEndOfTimestepEvents();
418 } else {
419 /*
420 No substation on this wire ...
421 */
422 // RICE_TODO myCharging = false; current 0 or nan, voltage 0 or nan, maybe write warning that the overhead wire is not connected to any substation,
423
424 // Energy flowing to/from the battery pack [Wh] has to completely cover vehicle consumption.
426 // Update Battery charge
428 // No substation is connected to this segmenr and the charging output is therefore zero.
430 }
431#else
432 WRITE_ERROR(TL("Overhead wire solver is on, but the Eigen library has not been compiled in!"))
433#endif
434 } else {
435 /*
436 Faster approximaion without circuit solving at every simulation step.
437 */
438
439 // First check that there is a traction substation connected to the overhead wire
440 double voltage = 0.0;
441 if (actualSubstation != nullptr) {
442 voltage = actualSubstation->getSubstationVoltage();
443 }
444
445 // At this point the volate can be (a) NAN if the substation voltage was not specified,
446 // (b) 0 if no substation powers the current segment or if someone put its power to zero,
447 // (c) >0 if the substation can provide energy to the circuit.
448 if (voltage > 0.0) {
449 // There is a power source connected to this segment.
450 // Set the simplified power requirement to the consumption + charging power.
451 // RICE_TODO: The charging power could be different when moving and when not. Add a parameter. See a similar code snippet above.
452 // Note that according to PMDP data, the charging power seems to be the same in both situations,
453 // ignoreing the potential benefits of using a higher charging power when the vehicle is moving.
454 double powerWanted = WATTHR2WATT(myConsum);
456 // Additional `myOverheadWireChargingPower` due to charging of battery pack
457 powerWanted += myOverheadWireChargingPower;
458 }
459
460 // No recuperation to overhead wire (only to the battery pack)
461 // RICE_TODO: How to recuperate into the circuit without solver? (energy balance?)
462 // - solution: assume, that any power is possible to recuperate
463 if (!MSGlobals::gOverheadWireRecuperation && powerWanted < 0.0) {
464 // the value of energyWasted is properly computed and updated below
465 powerWanted = 0.0;
466 }
467
468 // Set the actual current and voltage of the global circuit
469 // RICE_TODO: Process the traction stataion current limiting here as well.
470 myCircuitCurrent = powerWanted / voltage;
471 myCircuitVoltage = voltage;
472
473 // Calulate energy charged
474 double energyIn = WATT2WATTHR(powerWanted);
475
476 // Calulate energy flowing to/from the battery in this step [Wh]
477 // RICE_TODO: It should be possible to define different efficiency values for direction overhead wire -> battery; motor -> battery.
478 // We use a simplification here. The biggest contributor to the total losses is the battery pack itself
479 // (the input LC filter is probably more efficient -- eta_LC ~ 0.99 -- compared to the induction motor
480 // with eta_motor ~ 0.95).
482
483 // Update the energy that has been stored in the battery pack and return the real energy charged in this step
484 // considering SOC limits of the battery pack.
485 double realEnergyCharged = storeEnergyToBattery(myEnergyCharged);
486 // Set energy wasted
487 energyWasted = myEnergyCharged - realEnergyCharged;
488
489 // Add the energy provided by the overhead wire segment to the output of the segment
491 } else {
492 /*
493 Overhead wire without a connected substation
494 */
495 // RICE_TODO myCharging = false; current 0 or nan, voltage 0 or nan, maybe write warning that the overhead wire is not connected to any substation,
496
497 // Energy for the powertrain is provided by the battery pack
499 // Update battery charge
501 // No energy was provided by the overhead wire segment
503 }
504 }
505 assert(myActOverheadWireSegment != nullptr);
507 } else {
508 /*
509 No overhead wires, no charging.
510 */
511
512 // Disable charing flag
513 myCharging = false;
514
515 // Invalidate the circuit voltage and current
516 myCircuitCurrent = NAN;
517 myCircuitVoltage = NAN;
518
519 // Additional bookkeeping in case that the circuit solver is used
521#ifdef HAVE_EIGEN
522 /*
523 Delete vehicle resistor element, vehicle resistor nodes and vehicle resistor tails
524 in the previous circuit (i.e. the circuit used in the previous timestep)
525 */
527#else
528 WRITE_ERROR(TL("Overhead wire solver is on, but the Eigen library has not been compiled in!"))
529#endif
530 }
531
532 // Vehicle is not under an overhead wire
533 myActOverheadWireSegment = nullptr;
534
535 // Remove the vehicle from overhead wire if it was under it in the previous step.
536 // This has to be called afer deleteVehicleFromCircuit() as the file uses myPreviousOverheadWire.
537 if (myPreviousOverheadWireSegment != nullptr) {
540 if (ts != nullptr) {
542 ts->eraseVehicle(this);
543 }
545 }
546
547 // Energy for the powertrain is provided by the battery pack
549 // Update battery charge
551 }
552
553 // Update the statistical values
554 // RICE_TODO: update these statistical values also after solving circuit by electric circuit
557 }
560 }
561
562 if (myConsum > 0.0) {
564 } else {
566 }
567 myTotalEnergyWasted += energyWasted;
568
569 myLastAngle = veh.getAngle();
570 return true; // keep the device
571}
572
573// Note: This is called solely in the mesoscopic mode to mimic the `notifyMove()` reminder
574void
576 const SUMOTrafficObject& tObject,
577 const double frontOnLane,
578 const double timeOnLane,
579 const double meanSpeedFrontOnLane,
580 const double meanSpeedVehicleOnLane,
581 const double travelledDistanceFrontOnLane,
582 const double travelledDistanceVehicleOnLane,
583 const double meanLengthOnLane) {
584 UNUSED_PARAMETER(tObject);
585 UNUSED_PARAMETER(frontOnLane);
586 UNUSED_PARAMETER(timeOnLane);
587 UNUSED_PARAMETER(meanSpeedFrontOnLane);
588 UNUSED_PARAMETER(meanSpeedVehicleOnLane);
589 UNUSED_PARAMETER(travelledDistanceFrontOnLane);
590 UNUSED_PARAMETER(travelledDistanceVehicleOnLane);
591 UNUSED_PARAMETER(meanLengthOnLane);
592}
593
594void
596 if (myPreviousOverheadWireSegment != nullptr) {
598 //check if all pointers to vehicle elements and nodes are not nullptr
599 if (veh_elem == nullptr || veh_pos_tail_elem == nullptr || pos_veh_node == nullptr) {
600 WRITE_ERRORF("During deleting vehicle '%' from circuit some init previous Nodes or Elements was not assigned.", veh.getID());
601 }
602 //check if pos_veh_node has 3 elements - they should be: veh_elem, veh_pos_tail_elem and an overhead line resistor element "ahead" of vehicle.
603 if (pos_veh_node->getElements()->size() != 3) {
604 WRITE_ERRORF("During deleting vehicle '%' from circuit the size of element-vector of pNode or nNode was not 3. It should be 3 by Jakub's opinion.", veh.getID());
605 }
606 //delete vehicle resistor element "veh_elem" in the previous circuit,
609 delete veh_elem;
610 veh_elem = nullptr;
611
612 //eraising of tail elements (the element connected to the veh_node is afterthen only the ahead overhead line resistor element)
614
615 if (pos_veh_node->getElements()->size() != 1) {
616 WRITE_ERRORF("During deleting vehicle '%' from circuit the size of element-vector of pNode or nNode was not 1. It should be 1 by Jakub's opinion.", veh.getID());
617 }
618
619 // add the resistance value of veh_tail element to the resistance value of the ahead overhead line element
620 pos_veh_node->getElements()->front()->setResistance(pos_veh_node->getElements()->front()->getResistance() + veh_pos_tail_elem->getResistance());
621 //set PosNode of the ahead overhead line element to the posNode value of tail element
622 Element* aux = pos_veh_node->getElements()->front();
623 //set node = 3 operations
625 aux->getPosNode()->eraseElement(aux);
627
628 // erase tail element from its PosNode
630 // delete veh_pos_tail_elem
632 delete veh_pos_tail_elem;
633 veh_pos_tail_elem = nullptr;
634
635 //erase pos_veh_node
637 //modify id of other elements (the id of erasing element should be the greatest)
639 if (pos_veh_node->getId() != lastId) {
640 Node* node_last = myPreviousOverheadWireSegment->getCircuit()->getNode(lastId);
641 if (node_last != nullptr) {
642 node_last->setId(pos_veh_node->getId());
643 } else {
645 if (elem_last != nullptr) {
646 elem_last->setId(pos_veh_node->getId());
647 } else {
648 WRITE_ERROR(TL("The element or node with the last Id was not found in the circuit!"));
649 }
650 }
651 }
653 delete pos_veh_node;
654 pos_veh_node = nullptr;
655 }
656 }
657}
658
659bool
661 SUMOTrafficObject& tObject,
662 MSMoveReminder::Notification /* reason */,
663 const MSLane* /* enteredLane */) {
664 if (!tObject.isVehicle()) {
665 return false;
666 }
667#ifdef ELECHYBRID_MESOSCOPIC_DEBUG
668 SUMOVehicle& veh = static_cast<SUMOVehicle&>(tObject);
669 std::cout << "device '" << getID() << "' notifyEnter: reason=" << reason << " currentEdge=" << veh.getEdge()->getID() << "\n";
670#endif
671
672 return true; // keep the device
673}
674
675bool
677 SUMOTrafficObject& tObject,
678 double /*lastPos*/,
680 const MSLane* /* enteredLane */) {
681 if (!tObject.isVehicle()) {
682 return false;
683 }
684 SUMOVehicle& veh = static_cast<SUMOVehicle&>(tObject);
685#ifdef ELECHYBRID_MESOSCOPIC_DEBUG
686 SUMOVehicle& veh = static_cast<SUMOVehicle&>(tObject);
687 std::cout << "device '" << getID() << "' notifyLeave: reason=" << reason << " currentEdge=" << veh.getEdge()->getID() << "\n";
688 SUMOVehicle* sumoVehicle = *veh;
690 MEVehicle& v = dynamic_cast<MEVehicle&>(veh);
691 std::cout << "***************** MESO - notifyLeave*** START ****************** '" << v.getID() << "' \n";
692 //TODO the second argument of getStoptime should change
693 std::cout << "getSpeed: '" << v.getSpeed() << "' | getAverageSpeed: '" << v.getAverageSpeed() << "' | getStoptime: '" << v.getStoptime(v.getSegment(), 0) << "' \n";
694 std::cout << "getStopEdges: '" << "' | getLastEntryTime: '" << v.getLastEntryTime() << "' | getBlockTimeSeconds: '" << v.getBlockTimeSeconds() << "' \n";
695 std::cout << "getWaitingTime: '" << v.getWaitingTime() << "' | getAccumulatedWaitingTime: '" << v.getAccumulatedWaitingTime() << "' | getLastEntryTimeSeconds: '" << v.getLastEntryTimeSeconds() << "' \n";
696 std::cout << "***************** MESO - notifyLeave*** END ****************** '" << v.getID() << "' \n";
697 }
698#endif
699
700 // The MSMoveReminders are sorted so that we can do `<`. See also BTreceiver and BTsender devices...
702 return true;
703 }
704
706#ifdef HAVE_EIGEN
707 // ------- *** ------- delete vehicle resistor element, vehicle resistor nodes and vehicle resistor tails in the previous circuit (circuit used in the previous timestep)------- *** -------
709#else
710 UNUSED_PARAMETER(veh);
711 WRITE_ERROR(TL("Overhead wire solver is on, but the Eigen library has not been compiled in!"))
712#endif
713 }
714 // disable charging vehicle from overhead wire and segment and traction station
715 if (myPreviousOverheadWireSegment != nullptr) {
718 if (prevSubstation != nullptr) {
719 prevSubstation->decreaseElecHybridCount();
720 prevSubstation->eraseVehicle(this);
721 }
723 }
724 return true;
725}
726
727
728void
730 if (tripinfoOut != nullptr) {
731 // Write the summary elecHybrid information into tripinfo output
732 tripinfoOut->openTag("elechybrid");
733 tripinfoOut->writeAttr("maxBatteryCharge", myMaxBatteryCharge);
734 tripinfoOut->writeAttr("minBatteryCharge", myMinBatteryCharge);
735 tripinfoOut->writeAttr("totalEnergyConsumed", myTotalEnergyConsumed);
736 tripinfoOut->writeAttr("totalEnergyRegenerated", myTotalEnergyRegenerated);
737 tripinfoOut->writeAttr("totalEnergyWasted", myTotalEnergyWasted);
738 tripinfoOut->closeTag();
739 }
740}
741
742
743double
747
748
749double
753
754std::string
755MSDevice_ElecHybrid::getParameter(const std::string& key) const {
756 // RICE_TODO: full traci support
759 } else if (key == toString(SUMO_ATTR_ENERGYCONSUMED)) {
760 return toString(myConsum);
761 } else if (key == toString(SUMO_ATTR_ENERGYCHARGED)) {
763 } else if (key == toString(SUMO_ATTR_MAXIMUMBATTERYCAPACITY)) {
765 } else if (key == toString(SUMO_ATTR_OVERHEADWIREID)) {
767 } else if (key == toString(SUMO_ATTR_SUBSTATIONID)) {
769 } else if (key == toString(SUMO_ATTR_VEHICLEMASS)) {
771 }
772 throw InvalidArgument("Parameter '" + key + "' is not supported for device of type '" + deviceName() + "'");
773}
774
775
776double
777MSDevice_ElecHybrid::getParameterDouble(const std::string& key) const {
778 if (key == toString(SUMO_ATTR_MAXIMUMPOWER)) {
780 } else if (key == toString(SUMO_ATTR_RECUPERATIONEFFICIENCY)) {
782 }
783 throw InvalidArgument("Parameter '" + key + "' is not supported for device of type '" + deviceName() + "'");
784}
785
786
788 double energyCharged = energyIn - myConsum;
789 /*
790 Apply recuperation or propulsion efficiency if necessary
791 1. if (energyIn > 0.0 && energyCharged > 0 && it->getConsum() >= 0) = > recuper eff for energyCharged
792 2. if (energyIn > 0.0 && energyCharged > 0 && it->getConsum() < 0) => recuper eff only for energyIn
793 3. if (energyIn < 0.0 && it->getConsum() > 0) => 1/propulsion eff only for energyIn
794 4. if (energyIn < 0.0 && energyCharged < 0 && it->getConsum() < 0) => 1/propulsion eff only for energyCharged
795 */
796 if (energyIn > 0.0 && energyCharged > 0.0) {
797 // the vehicle is charging battery from overhead wire
798 if (myConsum >= 0) {
800 } else {
802 }
803 } else if (energyIn < 0.0 && energyCharged < 0.0) {
804 // the vehicle is recuperating energy into the overhead wire and discharging batterypack at the same time
805 if (myConsum >= 0) {
807 } else {
809 }
810 }
811 return energyCharged;
812}
813
814double
816 return myConsum;
817}
818
819void
820MSDevice_ElecHybrid::setConsum(const double consumption) {
822}
823
824void
826 myTotalEnergyWasted += energyWasted;
827}
828
829double
833
834void
836 myEnergyCharged = energyCharged;
837}
838
839double
842#ifdef HAVE_EIGEN
844 if (owc != nullptr) {
845 return owc->getAlphaBest() ;
846 }
847#else
848 WRITE_ERROR(TL("Overhead wire solver is on, but the Eigen library has not been compiled in!"))
849#endif
850 }
851 return NAN;
852}
853
854double
856 if (veh_elem != nullptr) {
857 return veh_elem->getPowerWanted();
858 }
859 return NAN;
860}
861
862double
866
867void
871
872double
876
877void
881
882std::string
884 if (myActOverheadWireSegment != nullptr) {
886 } else {
887 return "";
888 }
889}
890
891std::string
893 if (myActOverheadWireSegment != nullptr) {
895 if (ts != nullptr) {
896 return ts->getID();
897 }
898 }
899 return "";
900}
901
902bool
906
907double
909 // Original energy state of the battery pack
910 double previousEnergyInBattery = myActualBatteryCapacity;
911 // Push as much energy as the battery pack can accomodate.
912 // The battery has SOC limits that will prevent it from being overcharged, hence some energy may remain "free".
914 // The "free" energy that still remains and has to be stored elsewhere or burned on resistors is the difference.
915 return myActualBatteryCapacity - previousEnergyInBattery;
916}
917
918void
919MSDevice_ElecHybrid::setActualBatteryCapacity(const double actualBatteryCapacity) {
920 // Use the SOC limits to cap the actual battery capacity
921 if (actualBatteryCapacity < mySOCMin * myMaximumBatteryCapacity) {
922 //WRITE_WARNINGF(TL("The Battery of vehicle '%' has been exhausted."), getID());
924 } else if (actualBatteryCapacity > mySOCMax * myMaximumBatteryCapacity) {
926 } else {
927 myActualBatteryCapacity = actualBatteryCapacity;
928 }
929}
930
931void
932MSDevice_ElecHybrid::setParameter(const std::string& key, const std::string& value) {
933 double doubleValue;
934 try {
935 doubleValue = StringUtils::toDouble(value);
936 } catch (NumberFormatException&) {
937 throw InvalidArgument("Setting parameter '" + key + "' requires a number for device of type '" + deviceName() + "'");
938 }
940 myActualBatteryCapacity = doubleValue;
941 } else if (key == toString(SUMO_ATTR_MAXIMUMBATTERYCAPACITY)) {
942 myMaximumBatteryCapacity = doubleValue;
944 myOverheadWireChargingPower = doubleValue;
945 } else if (key == toString(SUMO_ATTR_VEHICLEMASS)) {
947 } else {
948 throw InvalidArgument("Setting parameter '" + key + "' is not supported for device of type '" + deviceName() + "'");
949 }
950}
951
952double
957
958double
963
964
965/****************************************************************************/
#define WATT2WATTHR(_x)
#define WATTHR2WATT(_x)
const double WIRE_RESISTIVITY
#define WRITE_WARNINGF(...)
Definition MsgHandler.h:271
#define WRITE_ERRORF(...)
Definition MsgHandler.h:280
#define WRITE_ERROR(msg)
Definition MsgHandler.h:279
#define WRITE_WARNING(msg)
Definition MsgHandler.h:270
#define TL(string)
Definition MsgHandler.h:287
SUMOTime DELTA_T
Definition SUMOTime.cpp:38
#define ACCEL2SPEED(x)
Definition SUMOTime.h:51
#define TS
Definition SUMOTime.h:42
@ SUMO_TAG_OVERHEAD_WIRE_SEGMENT
An overhead wire segment.
@ SUMO_ATTR_MAXIMUMPOWER
Maximum Power.
@ SUMO_ATTR_ENERGYCONSUMED
Energy consumed.
@ SUMO_ATTR_SUBSTATIONID
id of a traction substation substation
@ SUMO_ATTR_MAXIMUMBATTERYCAPACITY
Maxium battery capacity.
@ SUMO_ATTR_ROLLDRAGCOEFFICIENT
Roll Drag coefficient.
@ SUMO_ATTR_CONSTANTPOWERINTAKE
Constant Power Intake.
@ SUMO_ATTR_RECUPERATIONEFFICIENCY_BY_DECELERATION
Recuperation efficiency (by deceleration)
@ SUMO_ATTR_RECUPERATIONEFFICIENCY
Recuperation efficiency (constant)
@ SUMO_ATTR_AIRDRAGCOEFFICIENT
Air drag coefficient.
@ SUMO_ATTR_ANGLE
@ SUMO_ATTR_ACTUALBATTERYCAPACITY
@ SUMO_ATTR_VEHICLEMASS
Vehicle mass.
@ SUMO_ATTR_RADIALDRAGCOEFFICIENT
Radial drag coefficient.
@ SUMO_ATTR_ENERGYCHARGED
tgotal of Energy charged
@ SUMO_ATTR_OVERHEADWIREID
@ SUMO_ATTR_PROPULSIONEFFICIENCY
Propulsion efficiency.
@ SUMO_ATTR_INTERNALMOMENTOFINERTIA
Internal moment of inertia.
@ SUMO_ATTR_FRONTSURFACEAREA
Front surface area.
@ SUMO_ATTR_OVERHEADWIRECHARGINGPOWER
#define UNUSED_PARAMETER(x)
Definition StdDefs.h:30
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
double getAlphaBest()
return alphaBest variable, the best alpha scaling value
Definition Circuit.h:127
Node * addNode(std::string name)
Definition Circuit.cpp:42
Element * addElement(std::string name, double value, Node *pNode, Node *nNode, Element::ElementType et)
Definition Circuit.cpp:790
void eraseNode(Node *node)
Definition Circuit.cpp:62
int getLastId()
Definition Circuit.h:240
Element * getElement(std::string name)
Definition Circuit.cpp:116
Element * getVoltageSource(int id)
Definition Circuit.cpp:139
Node * getNode(std::string name)
Definition Circuit.cpp:98
void descreaseLastId()
Definition Circuit.h:245
void eraseElement(Element *element)
Definition Circuit.cpp:834
void setId(int id)
Definition Element.cpp:133
double getResistance()
Definition Element.cpp:99
void setCurrent(double current)
Definition Element.cpp:63
double getPowerWanted()
Definition Element.cpp:102
Node * getNegNode()
Definition Element.cpp:115
std::string getName()
Definition Element.cpp:122
void setPosNode(Node *node)
Definition Element.cpp:126
Node * getPosNode()
Definition Element.cpp:112
void setResistance(double resistance)
Definition Element.cpp:66
void setPowerWanted(double powerWanted)
Definition Element.cpp:73
@ RESISTOR_traction_wire
Definition Element.h:54
@ CURRENT_SOURCE_traction_wire
Definition Element.h:55
An upper class for objects with additional parameters.
double getDouble(SumoXMLAttr attr) const
void setDouble(SumoXMLAttr attr, double value)
Sets a parameter.
void checkParam(const SumoXMLAttr paramKey, const std::string &id, const double lower=0., const double upper=std::numeric_limits< double >::infinity())
static double angleDiff(const double angle1, const double angle2)
Returns the difference of the second angle to the first angle in radiants.
double compute(const SUMOEmissionClass c, const PollutantsInterface::EmissionType e, const double v, const double a, const double slope, const EnergyParams *param) const
Computes the emitted pollutant amount using the given speed and acceleration.
double acceleration(const SUMOEmissionClass c, const PollutantsInterface::EmissionType e, const double v, const double P, const double slope, const EnergyParams *param) const
Computes the achievable acceleration using the given speed and amount of consumed electric power.
A vehicle from the mesoscopic point of view.
Definition MEVehicle.h:42
double getLastEntryTimeSeconds() const
Returns the entry time for the current segment.
Definition MEVehicle.h:292
double getBlockTimeSeconds() const
Returns the time at which the vehicle was blocked on the current segment.
Definition MEVehicle.h:297
double getAverageSpeed() const
Returns the vehicle's estimated average speed on the segment assuming no further delays.
SUMOTime getAccumulatedWaitingTime() const
Returns the duration for which the vehicle was blocked.
Definition MEVehicle.h:281
SUMOTime getLastEntryTime() const
Returns the time the vehicle entered the current segment.
Definition MEVehicle.h:248
MESegment * getSegment() const
Returns the current segment the vehicle is on.
Definition MEVehicle.h:218
SUMOTime getWaitingTime() const
Returns the duration for which the vehicle was blocked.
Definition MEVehicle.h:271
double getSpeed() const
Returns the vehicle's estimated speed assuming no delays.
A device which collects info on the vehicle trip (mainly on departure and arrival)
void setEnergyCharged(double energyCharged)
bool myCharging
Parameter, Flag: Vehicle is charging (by default is false)
MSDevice_ElecHybrid(SUMOVehicle &holder, const std::string &id, const double actualBatteryCapacity, const double maximumBatteryCapacity, const double overheadWireChargingPower)
Constructor.
void setCurrentFromOverheadWire(double current)
double myMaximumBatteryCapacity
Parameter, The total vehicles's Battery Capacity in Wh, [myMaximumBatteryCapacity >= 0].
MSOverheadWire * myPreviousOverheadWireSegment
Parameter, Pointer to the act overhead wire segment in previous step (by default is nullptr),...
static void buildVehicleDevices(SUMOVehicle &v, std::vector< MSVehicleDevice * > &into)
Build devices for the given vehicle, if needed.
void deleteVehicleFromCircuit(SUMOVehicle &veh)
double getVoltageOfOverheadWire() const
Get actual voltage on the overhead wire segment.
double myEnergyCharged
Energy flowing into (+) or from (-) the battery pack in the given timestep.
bool notifyLeave(SUMOTrafficObject &tObject, double lastPos, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Saves arrival info.
double mySOCMax
Maximal SOC of the battery pack, battery will not be charged above this level. (But the buffer may st...
double getMaximumBatteryCapacity() const
Get the total vehicle's Battery Capacity in kWh.
double consumption(SUMOVehicle &veh, double a, double newSpeed)
return energy consumption in Wh (power multiplied by TS)
double computeChargedEnergy(double energyIn)
compute charged energy properly considering recuperation and propulsion efficiency during charging ba...
double getParameterDouble(const std::string &key) const
double myTotalEnergyWasted
Energy that could not be stored back to the battery or traction station and was wasted on resistors....
void setConsum(const double consumption)
bool isBatteryDischarged() const
Get consum.
void generateOutput(OutputDevice *tripinfoOut) const
Called on writing tripinfo output.
double myConsum
Parameter, Vehicle consumption during a time step (by default is 0.)
void setActualBatteryCapacity(const double actualBatteryCapacity)
Set actual vehicle's Battery Capacity in kWh.
std::string getParameter(const std::string &key) const
try to retrieve the given parameter from this device. Throw exception for unsupported key
double acceleration(SUMOVehicle &veh, double power, double oldSpeed)
double storeEnergyToBattery(const double energy)
Attempt to store energy into battery pack and return the energy that could not be accomodated due to ...
void updateTotalEnergyWasted(const double energyWasted)
Add energyWasted to the total sum myTotalEnergyWasted.
double myLastAngle
Parameter, Vehicle's last angle.
double getCurrentFromOverheadWire() const
Get actual current in the overhead wire segment.
bool myBatteryDischargedLogic
Parameter, Flag: Battery of Vehicle is fully discharged (by default is false)
const std::string deviceName() const
return the name for this type of device
bool notifyMove(SUMOTrafficObject &tObject, double oldPos, double newPos, double newSpeed)
Checks for waiting steps when the vehicle moves.
double myOverheadWireChargingPower
Parameter, overhead wire charging power to battery, if the battery SoC is not full (in Watt)
void setVoltageOfOverheadWire(double voltage)
static void insertOptions(OptionsCont &oc)
Inserts MSDevice_ElecHybrid-options.
MSOverheadWire * myActOverheadWireSegment
Parameter, Pointer to the actual overhead wire segment in which vehicle is placed (by default is null...
double myActualBatteryCapacity
Parameter, The actual vehicles's Battery Capacity in Wh, [myActualBatteryCapacity <= myMaximumBattery...
double getEnergyCharged() const
Get charged energy.
std::string getTractionSubstationID() const
Get actual traction substationn ID.
virtual void notifyMoveInternal(const SUMOTrafficObject &tObject, const double frontOnLane, const double timeOnLane, const double meanSpeedFrontOnLane, const double meanSpeedVehicleOnLane, const double travelledDistanceFrontOnLane, const double travelledDistanceVehicleOnLane, const double meanLengthOnLane)
Internal notification about the vehicle moves.
bool notifyEnter(SUMOTrafficObject &tObject, MSMoveReminder::Notification reason, const MSLane *enteredLane=0)
Saves departure info on insertion.
double getActualBatteryCapacity() const
Get the actual vehicle's Battery Capacity in kWh.
double getConsum() const
Get consum.
double myCircuitCurrent
Parameter, Current wanted at overhead wire in next timestep.
std::string getOverheadWireSegmentID() const
Get actual overhead wire segment ID.
void setParameter(const std::string &key, const std::string &value)
try to set the given parameter for this device. Throw exception for unsupported key
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:148
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:202
MSLane * leftLane(const MSLane *const lane) const
Returns the lane left to the one given, 0 if the given lane is leftmost.
Definition MSEdge.cpp:410
MSLane * rightLane(const MSLane *const lane) const
Returns the lane right to the one given, 0 if the given lane is rightmost.
Definition MSEdge.cpp:416
static bool gUseMesoSim
Definition MSGlobals.h:103
static bool gOverheadWireRecuperation
Definition MSGlobals.h:121
static bool gOverheadWireSolver
Definition MSGlobals.h:118
Representation of a lane in the micro simulation.
Definition MSLane.h:84
double getLength() const
Returns the lane's length.
Definition MSLane.h:593
Notification
Definition of a vehicle state.
@ NOTIFICATION_TELEPORT
The vehicle is being teleported.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition MSNet.cpp:183
std::string getStoppingPlaceID(const MSLane *lane, const double pos, const SumoXMLTag category) const
Returns the stop of the given category close to the given position.
Definition MSNet.cpp:1372
MSStoppingPlace * getStoppingPlace(const std::string &id, const SumoXMLTag category) const
Returns the named stopping place of the given category.
Definition MSNet.cpp:1363
Definition of overhead wire segment.
Circuit * getCircuit() const
void addChargeValueForOutput(double WCharged, MSDevice_ElecHybrid *elecHybrid, bool ischarging=1)
add charge value for output
MSTractionSubstation * getTractionSubstation() const
void eraseVehicle(SUMOVehicle &veh)
void addVehicle(SUMOVehicle &veh)
const MSLane & getLane() const
Returns the lane this stop is located at.
Traction substaction powering one or more overhead wire sections.
void eraseVehicle(MSDevice_ElecHybrid *elecHybrid)
double getSubstationVoltage() const
void addSolvingCirucitToEndOfTimestepEvents()
void addVehicle(MSDevice_ElecHybrid *elecHybrid)
Abstract in-vehicle device.
SUMOVehicle & myHolder
The vehicle that stores the device.
Representation of a vehicle in the micro simulation.
Definition MSVehicle.h:77
const SUMOVTypeParameter & getParameter() const
const std::string & getID() const
Returns the id.
Definition Named.h:74
Definition Node.h:39
int getId()
Definition Node.cpp:77
void addElement(Element *element)
Definition Node.cpp:44
void eraseElement(Element *element)
Definition Node.cpp:48
void setId(int id)
Definition Node.cpp:81
std::vector< Element * > * getElements()
Definition Node.cpp:101
A storage for options typed value containers)
Definition OptionsCont.h:89
void addOptionSubTopic(const std::string &topic)
Adds an option subtopic.
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.
double getDouble(const std::string &key, const double defaultValue) const
Returns the value for a given key converted to a double.
virtual const std::string getParameter(const std::string &key, const std::string defaultValue="") const
Returns the value for a given key.
bool knowsParameter(const std::string &key) const
Returns whether the parameter is known.
static const HelpersEnergy & getEnergyHelper()
get energy helper
Representation of a vehicle, person, or container.
virtual bool isVehicle() const
Whether it is a vehicle.
virtual const MSVehicleType & getVehicleType() const =0
Returns the object's "vehicle" type.
virtual double getSlope() const =0
Returns the slope of the road at object's position in degrees.
virtual const MSLane * getLane() const =0
Returns the lane the object is currently at.
virtual double getSpeed() const =0
Returns the object's current speed.
virtual const SUMOVehicleParameter & getParameter() const =0
Returns the vehicle's parameter (including departure definition)
virtual const MSEdge * getEdge() const =0
Returns the edge the object is currently at.
virtual double getPositionOnLane() const =0
Get the object's position along the lane.
Structure representing possible vehicle parameter.
Representation of a vehicle.
Definition SUMOVehicle.h:62
virtual EnergyParams * getEmissionParameters() const =0
Returns the vehicle's emission model parameter.
virtual double getAngle() const =0
Get the vehicle's angle.
Structure representing possible vehicle parameter.
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter