Line data Source code
1 : /****************************************************************************/
2 : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 : // Copyright (C) 2002-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 : /****************************************************************************/
14 : /// @file MSOverheadWire.h
15 : /// @author Jakub Sevcik (RICE)
16 : /// @author Jan Prikryl (RICE)
17 : /// @date 2019-12-15
18 : ///
19 : // Overhead wires for Electric (equipped with elecHybrid device) vehicles (Overhead wire segments, overhead wire sections, traction substations)
20 : /****************************************************************************/
21 : #pragma once
22 : #include <config.h>
23 :
24 : #include <list>
25 : #include <string>
26 : #include <iostream>
27 : #include <fstream>
28 : #include <sstream>
29 : #include <microsim/MSStoppingPlace.h>
30 : #include <utils/common/Named.h>
31 : #include <utils/vehicle/SUMOVehicle.h>
32 : #include <utils/common/WrappingCommand.h>
33 : #include <utils/traction_wire/Circuit.h>
34 :
35 : // Resistivity of Cu is 1.69*10^-8 Ohm*m. A cross-section S of the overhead wire used in Pilsen is 150 mm^2. So the "resistivity/S" is 0.000113 Ohm/m.
36 : const double WIRE_RESISTIVITY = (double)2 * 0.000113;
37 :
38 : // Conversion macros
39 : #define WATTHR2JOULE(_x) ((_x)*3600.0)
40 : #define JOULE2WATTHR(_x) ((_x)/3600.0)
41 : #define WATTHR2WATT(_x) ((_x)*3600.0/TS)
42 : #define WATT2WATTHR(_x) ((_x)*TS/3600.0)
43 :
44 : // ===========================================================================
45 : // class declarations
46 : // ===========================================================================
47 : class MSLane;
48 : class MSBusStop;
49 : class OptionsCont;
50 : class MSDevice_ElecHybrid;
51 : class MSTractionSubstation;
52 : class Named;
53 :
54 :
55 : // ===========================================================================
56 : // class definitions
57 : // ===========================================================================
58 : /**
59 : * @class MSOverheadWire
60 : * @brief Definition of overhead wire segment
61 : */
62 :
63 : class MSOverheadWire : public MSStoppingPlace {
64 : public:
65 :
66 : /// @brief constructor
67 : MSOverheadWire(const std::string& overheadWireSegmentID, MSLane& lane, double startPos, double endPos,
68 : bool voltageSource);
69 :
70 : /// @brief destructor
71 : ~MSOverheadWire();
72 :
73 : /// @brief Get overhead wire's voltage
74 : double getVoltage() const;
75 :
76 : /// @brief Set overhead wire's voltage
77 : void setVoltage(double voltage);
78 :
79 : /// @brief enable or disable charging vehicle
80 : void setChargingVehicle(bool value);
81 :
82 : /** @brief Check if a vehicle is inside in the Charge Station
83 : * @param[in] position Position of vehicle in the LANE
84 : * @return true if is between StartPostion and EndPostion
85 : */
86 : bool vehicleIsInside(const double position) const;
87 :
88 : /// @brief Return true if in the current time step charging station is charging a vehicle
89 : bool isCharging() const;
90 :
91 : void addVehicle(SUMOVehicle& veh);
92 :
93 : void eraseVehicle(SUMOVehicle& veh);
94 :
95 : int getElecHybridCount() const {
96 36 : return (int)myChargingVehicles.size();
97 : }
98 :
99 : const std::vector<SUMOVehicle*>& getChargingVehicles() const {
100 : return myChargingVehicles;
101 : }
102 :
103 : double getTotalCharged() const {
104 0 : return myTotalCharge;
105 : }
106 :
107 : /// @brief add charge value for output
108 : void addChargeValueForOutput(double WCharged, MSDevice_ElecHybrid* elecHybrid, bool ischarging = 1);
109 :
110 : /// @brief write overhead wire segment values
111 : void writeOverheadWireSegmentOutput(OutputDevice& output);
112 :
113 : std::string getOverheadWireSegmentName();
114 :
115 : MSTractionSubstation* getTractionSubstation() const {
116 3404 : return myTractionSubstation;
117 : }
118 :
119 : void setTractionSubstation(MSTractionSubstation* substation) {
120 118 : myTractionSubstation = substation;
121 : }
122 :
123 : Circuit* getCircuit() const;
124 :
125 : void setCircuitStartNodePos(Node* node) {
126 38 : myCircuitStartNodePos = node;
127 15 : }
128 :
129 : void setCircuitEndNodePos(Node* node) {
130 38 : myCircuitEndNodePos = node;
131 4 : }
132 :
133 : void setCircuitElementPos(Element* element) {
134 38 : myCircuitElementPos = element;
135 : }
136 :
137 : Node* getCircuitStartNodePos() const {
138 71 : return myCircuitStartNodePos;
139 : }
140 :
141 : Node* getCircuitEndNodePos() const {
142 106 : return myCircuitEndNodePos;
143 : }
144 :
145 : Element* getCircuitElementPos() const {
146 : return myCircuitElementPos;
147 : }
148 :
149 : bool isThereVoltageSource() const {
150 38 : return myVoltageSource;
151 : }
152 :
153 : void lock() const;
154 : void unlock() const;
155 :
156 : protected:
157 :
158 : /// @brief struct to save information for the overhead wire segment output
159 : struct Charge {
160 : /// @brief constructor
161 816 : Charge(SUMOTime _timeStep, std::string _vehicleID, std::string _vehicleType, std::string _status,
162 : double _WCharged, double _actualBatteryCapacity, double _maxBatteryCapacity, double _voltage,
163 816 : double _totalEnergyCharged) :
164 816 : timeStep(_timeStep),
165 816 : vehicleID(_vehicleID),
166 816 : vehicleType(_vehicleType),
167 816 : status(_status),
168 816 : WCharged(_WCharged),
169 816 : actualBatteryCapacity(_actualBatteryCapacity),
170 816 : maxBatteryCapacity(_maxBatteryCapacity),
171 816 : voltage(_voltage),
172 816 : totalEnergyCharged(_totalEnergyCharged) {}
173 :
174 : // @brief vehicle TimeStep
175 : SUMOTime timeStep;
176 : // @brief vehicle ID
177 : std::string vehicleID;
178 : // @brief vehicle Type
179 : std::string vehicleType;
180 : /// @brief status
181 : std::string status;
182 : // @brief W charged
183 : double WCharged;
184 : // @brief actual battery capacity AFTER charging
185 : double actualBatteryCapacity;
186 : // @brief battery max capacity
187 : double maxBatteryCapacity;
188 : // @brief current charging power of charging station
189 : double voltage;
190 : // @brief current efficiency of charging station
191 : double chargingEfficiency;
192 : // @brief current energy charged by charging stations AFTER charging
193 : double totalEnergyCharged;
194 : };
195 :
196 : /** @brief A class for sorting vehicle on lane under the overhead wire segment */
197 : class vehicle_position_sorter {
198 : public:
199 : /// @brief Constructor
200 : explicit vehicle_position_sorter() { }
201 :
202 : /// @brief Sorting function; compares RODFRouteDesc::distance2Last
203 : int operator()(SUMOVehicle* v1, SUMOVehicle* v2) {
204 60 : return v1->getPositionOnLane() > v2->getPositionOnLane();
205 : }
206 : };
207 :
208 : void static writeVehicle(OutputDevice& out, const std::vector<Charge>& chargeSteps, int iStart, int iEnd, double charged);
209 :
210 : /// @brief Overhead wire's voltage
211 : double myVoltage;
212 :
213 : /// @brief Check if in the current TimeStep overheadWireSegment is charging a vehicle
214 : bool myChargingVehicle;
215 :
216 : /// @brief total energy charged by this charging station
217 : double myTotalCharge;
218 :
219 : /// @brief map with the charges of this charging station (key = vehicleID)
220 : std::map<std::string, std::vector<Charge> > myChargeValues;
221 : /// @brief order vehicles by time of first charge
222 : std::vector<std::string> myChargedVehicles;
223 :
224 : std::vector<SUMOVehicle*> myChargingVehicles;
225 :
226 : /// @brief Parameter, Pointer to the electrical substation (by default is nullptr)
227 : MSTractionSubstation* myTractionSubstation;
228 :
229 : bool myVoltageSource;
230 :
231 : Element* myCircuitElementPos;
232 : Node* myCircuitStartNodePos;
233 : Node* myCircuitEndNodePos;
234 :
235 : private:
236 : /// @brief Invalidated copy constructor.
237 : MSOverheadWire(const MSOverheadWire&);
238 :
239 : /// @brief Invalidated assignment operator.
240 : MSOverheadWire& operator=(const MSOverheadWire&);
241 : };
242 :
243 :
244 : /**
245 : * @class MSTractionSubstation
246 : * @brief Traction substaction powering one or more overhead wire sections
247 : */
248 : class MSTractionSubstation : public Named {
249 : public:
250 :
251 : /// @brief Constructor instantiates a substation providing certain voltage and a maximum current
252 : MSTractionSubstation(const std::string& substationId, double voltage, double currentLimit);
253 :
254 : /// @brief destructor
255 : ~MSTractionSubstation();
256 :
257 : Circuit* getCircuit() const {
258 1612 : return myCircuit;
259 : }
260 : void addOverheadWireSegmentToCircuit(MSOverheadWire* newOverheadWireSegment);
261 :
262 : void addOverheadWireClampToCircuit(const std::string id, MSOverheadWire* startSegment, MSOverheadWire* endSegment);
263 :
264 : void eraseOverheadWireSegmentFromCircuit(MSOverheadWire* oldWireSegment);
265 :
266 : void writeOut();
267 : std::size_t numberOfOverheadSegments() const {
268 : return myOverheadWireSegments.size();
269 : }
270 :
271 : /// @brief enable or disable charging vehicle
272 : void setChargingVehicle(bool value);
273 :
274 : /// @brief Return true if in the current time step the substation (overhead wire section) is charging a vehicle
275 : bool isCharging() const;
276 :
277 : void increaseElecHybridCount();
278 :
279 : void decreaseElecHybridCount();
280 :
281 : void addForbiddenLane(MSLane* lane);
282 :
283 : bool isForbidden(const MSLane* lane);
284 :
285 : void addClamp(const std::string& id, MSOverheadWire* startPos, MSOverheadWire* endPos);
286 :
287 : int getElecHybridCount() const {
288 24 : return myElecHybridCount;
289 : }
290 :
291 : void addVehicle(MSDevice_ElecHybrid* elecHybrid);
292 :
293 : void eraseVehicle(MSDevice_ElecHybrid* elecHybrid);
294 :
295 : double getSubstationVoltage() const {
296 6 : return mySubstationVoltage;
297 : }
298 :
299 : bool isAnySectionPreviouslyDefined();
300 :
301 : void addSolvingCirucitToEndOfTimestepEvents();
302 : SUMOTime solveCircuit(SUMOTime currentTime);
303 :
304 : /// @brief add charge value for output
305 : void addChargeValueForOutput(double energy, double current, double alpha, Circuit::alphaFlag alphaReason);
306 :
307 : /// @brief write traction substation values
308 : void writeTractionSubstationOutput(OutputDevice& output);
309 :
310 : protected:
311 : /// @brief struct to save information for the traction substation output
312 : struct chargeTS {
313 : /// @brief constructor
314 180 : chargeTS(SUMOTime _timeStep, std::string _substationID, std::string _vehicleIDs, double _energy,
315 : double _current, std::string _currentsString, double _voltage, std::string _status,
316 180 : int _numVehicle, int _numVoltageSources, double _alpha, Circuit::alphaFlag _alphaReason) :
317 180 : timeStep(_timeStep),
318 180 : substationID(_substationID),
319 180 : vehicleIDs(_vehicleIDs),
320 180 : energy(_energy),
321 180 : current(_current),
322 180 : currentsString(_currentsString),
323 180 : voltage(_voltage),
324 180 : status(_status),
325 180 : numVehicles(_numVehicle),
326 180 : numVoltageSources(_numVoltageSources),
327 180 : alpha(_alpha),
328 180 : alphaReason(_alphaReason) {}
329 :
330 : // @brief vehicle TimeStep
331 : SUMOTime timeStep;
332 : // @brief substation ID
333 : std::string substationID;
334 : // @brief vehicle IDs
335 : std::string vehicleIDs;
336 : // @brief total power from voltage sources
337 : double energy;
338 : //@brief total current through voltage sources
339 : double current;
340 : // @brief list of all voltage currents
341 : std::string currentsString;
342 : //@brief voltage of voltage sources
343 : double voltage;
344 : /// @brief status
345 : std::string status;
346 : //@brief number of vehicles connected to the circuit
347 : int numVehicles;
348 : //@brief number of votlage sources connected to the section
349 : int numVoltageSources;
350 : //@brief best alpha scaling value
351 : double alpha;
352 : Circuit::alphaFlag alphaReason;
353 : };
354 : std::vector<chargeTS> myChargeValues;
355 :
356 : public:
357 : //preparation of overhead wire clamp
358 6 : struct OverheadWireClamp {
359 : // @todo: 'MSTractionSubstation::overheadWireClamp' : no appropriate default constructor available
360 : // provide default constructor for vector construction below
361 : OverheadWireClamp() :
362 : id("undefined"),
363 : start(nullptr),
364 : end(nullptr),
365 : usage(false) {}
366 :
367 11 : OverheadWireClamp(const std::string _id, MSOverheadWire* _start, MSOverheadWire* _end, bool _usage):
368 : id(_id),
369 11 : start(_start),
370 11 : end(_end),
371 11 : usage(_usage) {}
372 :
373 : const std::string id;
374 : MSOverheadWire* start;
375 : MSOverheadWire* end;
376 : bool usage;
377 : };
378 :
379 : /// @brief Find an overhead wire clamp by its ID
380 : OverheadWireClamp* findClamp(std::string id);
381 :
382 : private:
383 : void addOverheadWireInnerSegmentToCircuit(MSOverheadWire* incomingSegment, MSOverheadWire* outgoingSegment,
384 : const MSLane* connection, const MSLane* frontConnection, const MSLane* behindConnection);
385 :
386 : protected:
387 : /// @brief Check if in the current TimeStep substation (overhead wire section) is charging a vehicle
388 : bool myChargingVehicle;
389 : int myElecHybridCount;
390 :
391 : private:
392 : double mySubstationVoltage;
393 : Circuit* myCircuit;
394 : std::vector<MSOverheadWire*> myOverheadWireSegments;
395 : std::vector<MSDevice_ElecHybrid*> myElecHybrid;
396 : std::vector<MSLane*> myForbiddenLanes;
397 : static Command* myCommandForSolvingCircuit;
398 : double myTotalEnergy;
399 :
400 : // RICE_TODO: Does this cause the "'MSTractionSubstation::overheadWireClamp' : no appropriate default
401 : // constructor available" error in MSVC2013?
402 : // This is probably an issue with gitHub build chain
403 : std::vector<OverheadWireClamp> myOverheadWireClamps;
404 :
405 : };
|