Rename variables in every .jl an .yaml file

pull/1/head v0.5.3
Max Kannenberg 2021-12-14 14:06:56 +01:00
parent 7218b9d718
commit dab7e3495a
18 changed files with 547 additions and 617 deletions

View File

@ -1,7 +1,7 @@
name = "TrainRun"
uuid = "e4541106-d44c-4e00-b50b-ecdf479fcf92"
authors = ["Max Kannenberg"]
version = "0.5.2"
version = "0.5.3"
[deps]
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"

View File

@ -31,10 +31,16 @@ train_run = calculateDrivingDynamics(train, running_path, settings)
# History
## Version 0.5.3
Rename variables in every .jl an .yaml file
## Version 0.5.2
Merge fixing branches
## Version 0.5.1
Rename the real world path file
## Version 0.5

View File

@ -2,7 +2,7 @@
---
path:
name: "10 km, no gradient, 160 km/h"
sectionStarts: # with path speed limt (in m/s)
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, n in ‰]
sectionStarts: # with path speed limt (in m/s) # [s in m, v_limit in m/s, f_Rp in ‰]
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp in ‰]
- [0, 160, 0]
- [10000, 160, 0]

View File

@ -2,8 +2,8 @@
---
path:
name: "10 km, different gradient, 160 km/h"
sectionStarts: # with path speed limt (in m/s)
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, n in ‰]
sectionStarts: # with path speed limt (in m/s) # [s in m, v_limit in m/s, f_Rp in ‰]
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp in ‰]
- [0, 160, 0]
- [1000, 160, 1]
- [2000, 160, 2]

View File

@ -2,8 +2,8 @@
---
path:
name: "10 km, no gradient, different speed limits"
sectionStarts: # with path speed limt (in m/s)
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, n in ‰]
sectionStarts: # with path speed limt (in m/s) # [s in m, v_limit in m/s, f_Rp in ‰]
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp in ‰]
- [0, 160, 0.0]
- [3000, 60, 0.0]
- [4000, 160, 0.0]

View File

@ -3,8 +3,8 @@
path:
name: "'infra_Ostsachsen': track id='tr_80.6212_2' name='DG-DN' -> spp_5"
# source: https://www.railml.org/en/user/exampledata.html -> "Real world railway examples from professional tools" -> "East Saxony railway network by FBS" -> "Ostsachsen_V220.railml" -> 'infra_Ostsachsen': track id='tr_80.6212_2' name='DG-DN' -> spp_5
sectionStarts: # with path speed limt (in m/s)
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, n in ‰]
sectionStarts: # with path speed limt (in m/s) # [s in m, v_limit in m/s, f_Rp in ‰]
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp in ‰]
- [0.0, 40, 0]
- [318.0, 40, 2]
- [399.0, 40, -3]

View File

@ -8,5 +8,5 @@ settings:
operationModeMinimumRunningTime: true # operation mode "minimum running time"
operationModeMinimumEnergyConsumption: true # operation mode "minimum energy consumption"
typeOfOutput: "julia dictionary" # output as "julia dictionary" or as "CSV"
detailOfOutput: "driving course" # should the output be "reduced" or "driving course"?
detailOfOutput: "driving course" # should the output be "minimal" or "driving course"?
csvDirectory: "~/Desktop/TrainRun"

View File

@ -2,11 +2,11 @@
---
train:
name: "V 90 with 10 ore wagons of type Facs 124" # (source: https://de.wikipedia.org/wiki/DB-Baureihe_V_90 and https://dybas.de/dybas/gw/gw_f_1/g124.html)
l_union: 205.3 # in m (source: FBS: DB 290 with 10x Facs124)
l_train: 205.3 # in m (source: FBS: DB 290 with 10x Facs124)
m_td: 80000 # mass on driving axles of the traction unit in kg (source: https://de.wikipedia.org/wiki/DB-Baureihe_V_90)
m_tc: 0 # mass on carrying axles of the traction unit in kg (no carrying axles; source: https://de.wikipedia.org/wiki/DB-Baureihe_V_90)
m_w: 850000 # mass of the consist (set of wagons) in kg (source: FBS: 10x Facs124)
rotationMassFactor_union:
rotationMassFactor_train:
rotationMassFactor_t: 1.09 # (source: "Railway Timetabling & Operations" by Hansen, et al., 2014, p. 71 for the traction unit)
rotationMassFactor_w: 1.03 # (source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 13 for "Güterwagenzug beladen" -> 1.03 to 1.04)
powerType: diesel # diesel or electric (source: https://de.wikipedia.org/wiki/DB-Baureihe_V_90)

View File

@ -2,11 +2,11 @@
---
train:
name: "Intercity 2 (Traxx P160 AC2 + double deck coaches)" # (source: https://de.wikipedia.org/wiki/Bombardier_Twindexx_Vario#Intercity_2 and https://de.wikipedia.org/wiki/Intercity_2_(Deutsche_Bahn))
l_union: 152 # in m (source: FBS: DB146.5 with 1x DApza687.2, 3x DBpza668.2, 1x DBpbzfa668.2)
l_train: 152 # in m (source: FBS: DB146.5 with 1x DApza687.2, 3x DBpza668.2, 1x DBpbzfa668.2)
m_td: 84000 # mass on driving axles of the traction unit in kg (source: FBS: DB146.5)
m_tc: 0 # mass on carrying axles of the traction unit in kg (no carrying axles; source: FBS: DB146.5)
m_w: 309000 # mass of the consist (set of wagons) in kg (source: FBS: 1x DApza687.2, 3x DBpza668.2, 1x DBpbzfa668.2)
rotationMassFactor_union:
rotationMassFactor_train:
rotationMassFactor_t: 1.09 # (source: "Railway Timetabling & Operations" by Hansen, et al., 2014, p. 71 for the traction unit)
rotationMassFactor_w: 1.06 # (source: "Railway Timetabling & Operations" by Hansen, et al., 2014, p. 71 for freight wagons)
powerType: electric # diesel or electric (source: https://de.wikipedia.org/wiki/Intercity_2_(Deutsche_Bahn)#Gemeinsame_Merkmale)

View File

@ -2,11 +2,11 @@
---
train:
name: "Siemens Desiro Classic" # (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
l_union: 41.7 # in m (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
l_train: 41.7 # in m (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
m_td: 52800 # mass on driving axles of the traction unit in kg (source: FBS: DB 642; proportionately to the number of axles: 4 to 2, see: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
m_tc: 35200 # mass on carrying axles of the traction unit in kg (source: FBS: DB 642; proportionately to the number of axles: 4 to 2, see: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
m_w: 0 # mass of the consist (set of wagons) in kg (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic -> no separate wagons)
rotationMassFactor_union: 1.08 # (source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 13 for "Zug, überschlägliche Berechnung")
rotationMassFactor_train: 1.08 # (source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 13 for "Zug, überschlägliche Berechnung")
rotationMassFactor_t:
rotationMassFactor_w:
powerType: diesel # diesel or electric (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)

View File

@ -46,39 +46,39 @@ function calculateRecoveryTime(s_MS::AbstractFloat, t_MS::AbstractFloat, train::
c_s=0.0009
end # if s_MS
if train.v_limit<=140/3.6 # unit is m/s
if train.m_union<=300000 # unit is kg
if train.m_train<=300000 # unit is kg
c_t=0.03
elseif train.m_union<=500000 # unit is kg
elseif train.m_train<=500000 # unit is kg
c_t=0.04
elseif train.m_union<=700000 # unit is kg
elseif train.m_train<=700000 # unit is kg
c_t=0.04
else # train.m_union>700000 # unit is kg
else # train.m_train>700000 # unit is kg
c_t=0.05
end # if train.m_union
end # if train.m_train
elseif train.v_limit<=160/3.6 # unit is m/s
if train.m_union<=300000 # unit is kg
if train.m_train<=300000 # unit is kg
c_t=0.03
elseif train.m_union<=500000 # unit is kg
elseif train.m_train<=500000 # unit is kg
c_t=0.04
else # train.m_union>500000 # unit is kg
else # train.m_train>500000 # unit is kg
c_t=0.0
end # if train.m_union
end # if train.m_train
elseif train.v_limit<=200/3.6 # unit is m/s
if train.m_union<=300000 # unit is kg
if train.m_train<=300000 # unit is kg
c_t=0.04
elseif train.m_union<=500000 # unit is kg
elseif train.m_train<=500000 # unit is kg
c_t=0.05
else # train.m_union>500000 # unit is kg
else # train.m_train>500000 # unit is kg
c_t=0.06
end # if train.m_union
end # if train.m_train
else # train.v_limit>200/3.6 # unit is m/s
if train.m_union<=300000 # unit is kg
if train.m_train<=300000 # unit is kg
c_t=0.05
elseif train.m_union<=500000 # unit is kg
elseif train.m_train<=500000 # unit is kg
c_t=0.06
else # train.m_union>500000 # unit is kg
else # train.m_train>500000 # unit is kg
c_t=0.07
end # if train.m_union
end # if train.m_train
end # if train.v_limit
c_tMin=s_MS/t_MS*0.0012
@ -114,7 +114,7 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
cruisingReduction=settings.stepSize
while cruisingReduction>=settings.stepSize/10^approximationLevel
#while cruisingReduction>=settings.stepSize/100
while cruisingReduction>=settings.stepSize/10^approximationLevel # will be done once and then depending on approximationLevel repeated with smaller cruisingReduction unless !(drivingCourseModified[end].v<=csModified.v_exit && drivingCourseModified[end].s<csModified.s_end) -> see below at the end of the while loop
while cruisingReduction>=settings.stepSize/10^approximationLevel # will be done once and then depending on approximationLevel repeated with smaller cruisingReduction unless !(drivingCourseModified[end].v<=csModified.v_exit && drivingCourseModified[end].s<csModified.s_exit) -> see below at the end of the while loop
# create a copy for the characteristic sections drivingCourse
energySavingStartId=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).dataPoints[1]
@ -131,45 +131,45 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
# calculating the new length of the cruising section
if settings.stepVariable=="s in m" # distance step method
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).s_total-cruisingReduction
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).length-cruisingReduction
elseif settings.stepVariable=="t in s" # time step method
# 09/20 old: doesn't work for non constant cruising
# t_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).t_total-cruisingReduction
# t_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).t-cruisingReduction
# s_cruising=t_cruising*drivingCourseModified[end].v
wayReduction=drivingCourse(get(csOriginal.behaviorSections, "cruising", BehaviorSection()).dataPoints[end]).v*cruisingReduction
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).s_total-wayReduction
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).length-wayReduction
elseif settings.stepVariable=="v in m/s" # velocity step method
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).s_total-cruisingReduction*10 # TODO: or better: *100 ?
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).length-cruisingReduction*10 # TODO: or better: *100 ?
end #if
s_cruising=max(0.0, s_cruising)
# copy csOriginal to csModified
csModified=CharacteristicSection(csOriginal.id, csOriginal.s_total, csOriginal.s_start, csOriginal.s_end, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_reach, csOriginal.v_entry, csOriginal.v_exit, csOriginal.f_Rp, Dict{String, BehaviorSection}())
if haskey(csOriginal.behaviorSections, "starting")
startingSection=BehaviorSection(get(csOriginal.behaviorSections, "starting", BehaviorSection()))
merge!(csModified.behaviorSections, Dict("starting"=>startingSection))
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "starting", BehaviorSection()).E_total
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "starting", BehaviorSection()).t_total
csModified=CharacteristicSection(csOriginal.id, csOriginal.length, csOriginal.s_entry, csOriginal.s_exit, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_target, csOriginal.v_entry, csOriginal.v_exit, csOriginal.f_Rp, Dict{String, BehaviorSection}())
if haskey(csOriginal.behaviorSections, "breakFree")
breakFreeSection=BehaviorSection(get(csOriginal.behaviorSections, "breakFree", BehaviorSection()))
merge!(csModified.behaviorSections, Dict("breakFree"=>breakFreeSection))
csModified.E=csModified.E+get(csModified.behaviorSections, "breakFree", BehaviorSection()).E
csModified.t=csModified.t+get(csModified.behaviorSections, "breakFree", BehaviorSection()).t
end
if haskey(csOriginal.behaviorSections, "cruisingBeforeAcceleration") # this section is needed before acceleration if the mass strip model is used and if the train wants to accelerate to a velocity higher than the limit in the other CS where parts of the union are still located
cruisingBeforeAccelerationSection=BehaviorSection(get(csOriginal.behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()))
merge!(csModified.behaviorSections, Dict("cruisingBeforeAcceleration"=>cruisingBeforeAccelerationSection))
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()).E_total
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()).t_total
if haskey(csOriginal.behaviorSections, "clearing") # this section is needed before acceleration if the train wants to accelerate to a speed higher than the limit in a previous CS where parts of the train are still located
clearingSection=BehaviorSection(get(csOriginal.behaviorSections, "clearing", BehaviorSection()))
merge!(csModified.behaviorSections, Dict("clearing"=>clearingSection))
csModified.E=csModified.E+get(csModified.behaviorSections, "clearing", BehaviorSection()).E
csModified.t=csModified.t+get(csModified.behaviorSections, "clearing", BehaviorSection()).t
end
if haskey(csOriginal.behaviorSections, "acceleration")
accelerationSection=BehaviorSection(get(csOriginal.behaviorSections, "acceleration", BehaviorSection()))
merge!(csModified.behaviorSections, Dict("acceleration"=>accelerationSection))
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "acceleration", BehaviorSection()).E_total
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "acceleration", BehaviorSection()).t_total
csModified.E=csModified.E+get(csModified.behaviorSections, "acceleration", BehaviorSection()).E
csModified.t=csModified.t+get(csModified.behaviorSections, "acceleration", BehaviorSection()).t
end
if haskey(csOriginal.behaviorSections, "diminishing")
diminishingSection=BehaviorSection(get(csOriginal.behaviorSections, "diminishing", BehaviorSection()))
merge!(csModified.behaviorSections, Dict("diminishing"=>diminishingSection))
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "diminishing", BehaviorSection()).E_total
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "diminishing", BehaviorSection()).t_total
csModified.E=csModified.E+get(csModified.behaviorSections, "diminishing", BehaviorSection()).E
csModified.t=csModified.t+get(csModified.behaviorSections, "diminishing", BehaviorSection()).t
end
@ -181,8 +181,8 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
# calculate the coasting phase until the point the train needs to brake
(csModified, drivingCourseModified)=addCoastingPhaseUntilBraking!(csModified, drivingCourseModified, settings, train, allCSs)
if drivingCourseModified[end].v < csModified.v_exit || drivingCourseModified[end].s > csModified.s_end
# the train reaches v_exit before reaching s_end. The cruising and coasting sections have to be calculated again with a larger cruising section (so with a smaller reduction of the cruising section)
if drivingCourseModified[end].v < csModified.v_exit || drivingCourseModified[end].s > csModified.s_exit
# the train reaches v_exit before reaching s_exit. The cruising and coasting sections have to be calculated again with a larger cruising section (so with a smaller reduction of the cruising section)
cruisingReduction=cruisingReduction/10
else
break
@ -193,13 +193,13 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
if drivingCourseModified[end].v > csModified.v_exit
#(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings.massModel, train, allCSs)
(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings, train, allCSs)
elseif drivingCourseModified[end].v == csModified.v_exit && drivingCourseModified[end].s < csModified.s_end
elseif drivingCourseModified[end].v == csModified.v_exit && drivingCourseModified[end].s < csModified.s_exit
# v_exit is already reached. Now cruise till the end of the CS
s_cruisingAfterCoasting=csModified.s_end-drivingCourseModified[end].s
s_cruisingAfterCoasting=csModified.s_exit-drivingCourseModified[end].s
(csModified, drivingCourseModified)=addCruisingPhase!(csModified, drivingCourseModified, s_cruisingAfterCoasting, settings, train, allCSs, "cruisingAfterCoasting")
end
if t_recoveryAvailable < csModified.t_total-csOriginal.t_total || drivingCourseModified[end].v != csModified.v_exit || drivingCourseModified[end].s != csModified.s_end # time loss is to high and the CS has to be calculated again with larger cruising section (so with a smaller reduction of the cruising section) or v_exit or s_end are not reached excatly
if t_recoveryAvailable < csModified.t-csOriginal.t || drivingCourseModified[end].v != csModified.v_exit || drivingCourseModified[end].s != csModified.s_exit # time loss is to high and the CS has to be calculated again with larger cruising section (so with a smaller reduction of the cruising section) or v_exit or s_exit are not reached excatly
cruisingReduction=cruisingReduction/10
else
return (csModified, drivingCourseModified, true)
@ -211,33 +211,33 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
# TODO: At the moment diminishing is reduced like the acceleration in decreaseMaximumVelocity. To reduce code, the methods for reducing cruising phase an reducing the diminishing pahse can be combined in some parts.
# copy csOriginal to csModified
csModified=CharacteristicSection(csOriginal.id, csOriginal.s_total, csOriginal.s_start, csOriginal.s_end, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_reach, csOriginal.v_entry, csOriginal.v_exit, csOriginal.f_Rp, Dict{String, BehaviorSection}())
csModified=CharacteristicSection(csOriginal.id, csOriginal.length, csOriginal.s_entry, csOriginal.s_exit, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_target, csOriginal.v_entry, csOriginal.v_exit, csOriginal.f_Rp, Dict{String, BehaviorSection}())
if haskey(csOriginal.behaviorSections, "starting")
startingSection=BehaviorSection(get(csOriginal.behaviorSections, "starting", BehaviorSection()))
merge!(csModified.behaviorSections, Dict("starting"=>startingSection))
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "starting", BehaviorSection()).E_total
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "starting", BehaviorSection()).t_total
if haskey(csOriginal.behaviorSections, "breakFree")
breakFreeSection=BehaviorSection(get(csOriginal.behaviorSections, "breakFree", BehaviorSection()))
merge!(csModified.behaviorSections, Dict("breakFree"=>breakFreeSection))
csModified.E=csModified.E+get(csModified.behaviorSections, "breakFree", BehaviorSection()).E
csModified.t=csModified.t+get(csModified.behaviorSections, "breakFree", BehaviorSection()).t
end
if haskey(csOriginal.behaviorSections, "cruisingBeforeAcceleration") # this section is needed before acceleration if the mass strip model is used and if the train wants to accelerate to a velocity higher than the limit in the other CS where parts of the union are still located
cruisingBeforeAccelerationSection=BehaviorSection(get(csOriginal.behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()))
merge!(csModified.behaviorSections, Dict("cruisingBeforeAcceleration"=>cruisingBeforeAccelerationSection))
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()).E_total
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()).t_total
if haskey(csOriginal.behaviorSections, "clearing") # this section is needed before acceleration if the train wants to accelerate to a speed higher than the limit in a previous CS where parts of the train are still located
clearingSection=BehaviorSection(get(csOriginal.behaviorSections, "clearing", BehaviorSection()))
merge!(csModified.behaviorSections, Dict("clearing"=>clearingSection))
csModified.E=csModified.E+get(csModified.behaviorSections, "clearing", BehaviorSection()).E
csModified.t=csModified.t+get(csModified.behaviorSections, "clearing", BehaviorSection()).t
end
if haskey(csOriginal.behaviorSections, "acceleration")
accelerationSection=BehaviorSection(get(csOriginal.behaviorSections, "acceleration", BehaviorSection()))
merge!(csModified.behaviorSections, Dict("acceleration"=>accelerationSection))
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "acceleration", BehaviorSection()).E_total
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "acceleration", BehaviorSection()).t_total
csModified.E=csModified.E+get(csModified.behaviorSections, "acceleration", BehaviorSection()).E
csModified.t=csModified.t+get(csModified.behaviorSections, "acceleration", BehaviorSection()).t
end
if haskey(csOriginal.behaviorSections, "cruising")
cruisingSection=BehaviorSection(get(csOriginal.behaviorSections, "cruising", BehaviorSection()))
merge!(csModified.behaviorSections, Dict("cruising"=>cruisingSection))
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "cruising", BehaviorSection()).E_total
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "cruising", BehaviorSection()).t_total
csModified.E=csModified.E+get(csModified.behaviorSections, "cruising", BehaviorSection()).E
csModified.t=csModified.t+get(csModified.behaviorSections, "cruising", BehaviorSection()).t
end
diminishingSection=BehaviorSection(get(csOriginal.behaviorSections, "diminishing", BehaviorSection()))
@ -246,19 +246,19 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
pop!(diminishingSection.dataPoints)
diminishingSection.v_exit=drivingCourse[diminishingSection.dataPoints[end]].v # exit speed (in m/s)
diminishingSection.s_end=drivingCourse[diminishingSection.dataPoints[end]].s # last position (in m)
diminishingSection.s_total=diminishingSection.s_end-diminishingSection.s_start # total length (in m)
diminishingSection.t_total=drivingCourse[diminishingSection.dataPoints[end]].t-drivingCourse[diminishingSection.dataPoints[1]].t # total running time (in s)
diminishingSection.E_total=drivingCourse[diminishingSection.dataPoints[end]].E-drivingCourse[diminishingSection.dataPoints[1]].E # total energy consumption (in Ws)
diminishingSection.s_exit=drivingCourse[diminishingSection.dataPoints[end]].s # last position (in m)
diminishingSection.length=diminishingSection.s_exit-diminishingSection.s_entry # total length (in m)
diminishingSection.t=drivingCourse[diminishingSection.dataPoints[end]].t-drivingCourse[diminishingSection.dataPoints[1]].t # total running time (in s)
diminishingSection.E=drivingCourse[diminishingSection.dataPoints[end]].E-drivingCourse[diminishingSection.dataPoints[1]].E # total energy consumption (in Ws)
merge!(csModified.behaviorSections, Dict("diminishing"=>diminishingSection))
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "diminishing", BehaviorSection()).E_total
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "diminishing", BehaviorSection()).t_total
csModified.E=csModified.E+get(csModified.behaviorSections, "diminishing", BehaviorSection()).E
csModified.t=csModified.t+get(csModified.behaviorSections, "diminishing", BehaviorSection()).t
energySavingStartId=diminishingSection.dataPoints[end]
else
# The diminishing section is only one step. This step is removed and if there is a cruisingBeforeAcceleration section it will be combined with the new cruising section.
energySavingStartId=get(csOriginal.behaviorSections, "cruisingBeforeAcceleration", get(csOriginal.behaviorSections, "diminishing", BehaviorSection())).dataPoints[1]
# The diminishing section is only one step. This step is removed and if there is a clearing section it will be combined with the new cruising section.
energySavingStartId=get(csOriginal.behaviorSections, "clearing", get(csOriginal.behaviorSections, "diminishing", BehaviorSection())).dataPoints[1]
end
# copy the driving course till the beginning of energy saving
@ -273,14 +273,14 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
# calculate the moving phase between coasting and the end of the CS
if drivingCourseModified[end].v > csModified.v_exit
(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings, train, allCSs)
elseif drivingCourseModified[end].v == csModified.v_exit && drivingCourseModified[end].s < csModified.s_end
elseif drivingCourseModified[end].v == csModified.v_exit && drivingCourseModified[end].s < csModified.s_exit
# v_exit is already reached. Now cruise till the end of the CS
s_cruisingAfterCoasting=csModified.s_end-drivingCourseModified[end].s
s_cruisingAfterCoasting=csModified.s_exit-drivingCourseModified[end].s
(csModified, drivingCourseModified)=addCruisingPhase!(csModified, drivingCourseModified, s_cruisingAfterCoasting, settings, train, allCSs, "cruisingAfterCoasting")
end
if t_recoveryAvailable>=(csModified.t_total-csOriginal.t_total)
if t_recoveryAvailable>=(csModified.t-csOriginal.t)
return (csModified, drivingCourseModified, true)
else # time loss is to high. so there is no energy saving modification for this CS with the available recovery time
# TODO: just return false or take smaller steps?
@ -302,7 +302,7 @@ end # function increaseCoastingSection
cruisingReduction=settings.stepSize
while cruisingReduction>=settings.stepSize/10^approximationLevel
#while cruisingReduction>=settings.stepSize/100
while cruisingReduction>=settings.stepSize/10^approximationLevel # will be done once and then depending on approximationLevel repeated with smaller cruisingReduction unless !(drivingCourseModified[end].v<=csModified.v_exit && drivingCourseModified[end].s<csModified.s_end) -> see below at the end of the while loop
while cruisingReduction>=settings.stepSize/10^approximationLevel # will be done once and then depending on approximationLevel repeated with smaller cruisingReduction unless !(drivingCourseModified[end].v<=csModified.v_exit && drivingCourseModified[end].s<csModified.s_exit) -> see below at the end of the while loop
# create a copy for the characteristic sections drivingCourse
energySavingStartId=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).dataPoints[1]
@ -320,49 +320,49 @@ end # function increaseCoastingSection
# calculating the new length of the cruising section
if settings.stepVariable=="s in m" # distance step method
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).s_total-cruisingReduction
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).length-cruisingReduction
elseif settings.stepVariable=="t in s" # time step method
# 09/20 old: doesn't work for non constant cruising
# t_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).t_total-cruisingReduction
# t_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).t-cruisingReduction
# s_cruising=t_cruising*drivingCourseModified[end].v
wayReduction=drivingCourse(get(csOriginal.behaviorSections, "cruising", BehaviorSection()).dataPoints[end]).v*cruisingReduction
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).s_total-wayReduction
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).length-wayReduction
elseif settings.stepVariable=="v in m/s" # velocity step method
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).s_total-cruisingReduction*10 # TODO: or better: *100 ?
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).length-cruisingReduction*10 # TODO: or better: *100 ?
end #if
s_cruising=max(0.0, s_cruising)
# copy csOriginal to csModified
csModified=CharacteristicSection(csOriginal.id, csOriginal.s_total, csOriginal.s_start, csOriginal.s_end, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_reach, csOriginal.v_entry, csOriginal.v_exit, csOriginal.f_Rp, Dict{String, BehaviorSection}())
if haskey(csOriginal.behaviorSections, "starting")
startingSection=BehaviorSection(get(csOriginal.behaviorSections, "starting", BehaviorSection()))
merge!(csModified.behaviorSections, Dict("starting"=>startingSection))
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "starting", BehaviorSection()).E_total
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "starting", BehaviorSection()).t_total
csModified=CharacteristicSection(csOriginal.id, csOriginal.length, csOriginal.s_entry, csOriginal.s_exit, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_target, csOriginal.v_entry, csOriginal.v_exit, csOriginal.f_Rp, Dict{String, BehaviorSection}())
if haskey(csOriginal.behaviorSections, "breakFree")
breakFreeSection=BehaviorSection(get(csOriginal.behaviorSections, "breakFree", BehaviorSection()))
merge!(csModified.behaviorSections, Dict("breakFree"=>breakFreeSection))
csModified.E=csModified.E+get(csModified.behaviorSections, "breakFree", BehaviorSection()).E
csModified.t=csModified.t+get(csModified.behaviorSections, "breakFree", BehaviorSection()).t
end
if haskey(csOriginal.behaviorSections, "cruisingBeforeAcceleration") # this section is needed before acceleration if the mass strip model is used and if the train wants to accelerate to a velocity higher than the limit in the other CS where parts of the union are still located
cruisingBeforeAccelerationSection=BehaviorSection(get(csOriginal.behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()))
merge!(csModified.behaviorSections, Dict("cruisingBeforeAcceleration"=>cruisingBeforeAccelerationSection))
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()).E_total
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()).t_total
if haskey(csOriginal.behaviorSections, "clearing") # this section is needed before acceleration if the train wants to accelerate to a speed higher than the limit in a previous CS where parts of the train are still located
clearingSection=BehaviorSection(get(csOriginal.behaviorSections, "clearing", BehaviorSection()))
merge!(csModified.behaviorSections, Dict("clearing"=>clearingSection))
csModified.E=csModified.E+get(csModified.behaviorSections, "clearing", BehaviorSection()).E
csModified.t=csModified.t+get(csModified.behaviorSections, "clearing", BehaviorSection()).t
end
if haskey(csOriginal.behaviorSections, "acceleration")
accelerationSection=BehaviorSection(get(csOriginal.behaviorSections, "acceleration", BehaviorSection()))
merge!(csModified.behaviorSections, Dict("acceleration"=>accelerationSection))
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "acceleration", BehaviorSection()).E_total
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "acceleration", BehaviorSection()).t_total
csModified.E=csModified.E+get(csModified.behaviorSections, "acceleration", BehaviorSection()).E
csModified.t=csModified.t+get(csModified.behaviorSections, "acceleration", BehaviorSection()).t
end
# simulate the new and now shorter cruising section
# calculate the new and now shorter cruising section
if s_cruising>0.0
(csModified, drivingCourseModified)=addCruisingPhase!(csModified, drivingCourseModified, s_cruising, settings, train, allCSs, "cruising")
end
(csModified, drivingCourseModified)=addCoastingPhaseUntilBraking!(csModified, drivingCourseModified, settings, train, allCSs)
if drivingCourseModified[end].v < csModified.v_exit || drivingCourseModified[end].s > csModified.s_end
# the train reaches v_exit before reaching s_end. The cruising and coasting sections have to be calculated again with a larger cruising section (so with a smaller reduction of the cruising section)
if drivingCourseModified[end].v < csModified.v_exit || drivingCourseModified[end].s > csModified.s_exit
# the train reaches v_exit before reaching s_exit. The cruising and coasting sections have to be calculated again with a larger cruising section (so with a smaller reduction of the cruising section)
cruisingReduction=cruisingReduction/10
else
break
@ -372,13 +372,13 @@ end # function increaseCoastingSection
if drivingCourseModified[end].v > csModified.v_exit
#(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings.massModel, train, allCSs)
(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings, train, allCSs)
elseif drivingCourseModified[end].v == csModified.v_exit && drivingCourseModified[end].s < csModified.s_end
elseif drivingCourseModified[end].v == csModified.v_exit && drivingCourseModified[end].s < csModified.s_exit
# v_exit is already reached. Now cruise till the end of the CS
s_cruisingAfterCoasting=csModified.s_end-drivingCourseModified[end].s
s_cruisingAfterCoasting=csModified.s_exit-drivingCourseModified[end].s
(csModified, drivingCourseModified)=addCruisingPhase!(csModified, drivingCourseModified, s_cruisingAfterCoasting, settings, train, allCSs, "cruisingAfterCoasting")
end
if t_recoveryAvailable < csModified.t_total-csOriginal.t_total || drivingCourseModified[end].v != csModified.v_exit || drivingCourseModified[end].s != csModified.s_end # time loss is to high and the CS has to be calculated again with larger cruising section (so with a smaller reduction of the cruising section) or v_exit or s_end are not reached excatly
if t_recoveryAvailable < csModified.t-csOriginal.t || drivingCourseModified[end].v != csModified.v_exit || drivingCourseModified[end].s != csModified.s_exit # time loss is to high and the CS has to be calculated again with larger cruising section (so with a smaller reduction of the cruising section) or v_exit or s_exit are not reached excatly
cruisingReduction=cruisingReduction/10
else
return (csModified, drivingCourseModified, true)
@ -397,54 +397,54 @@ end # function increaseCoastingSection
# method 2 with shortening the acceleration by stepsize
function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse, settings::Settings, train::Train, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
#function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Settings, train::Train, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
if haskey(csOriginal.behaviorSections, "acceleration") && csOriginal.v_reach > csOriginal.v_entry && csOriginal.v_reach > csOriginal.v_exit
if haskey(csOriginal.behaviorSections, "acceleration") && csOriginal.v_target > csOriginal.v_entry && csOriginal.v_target > csOriginal.v_exit
accelerationSection=BehaviorSection(get(csOriginal.behaviorSections, "acceleration", BehaviorSection()))
if drivingCourse[accelerationSection.dataPoints[end]-1].v < csOriginal.v_exit
return (CharacteristicSection(), [], false)
# TODO: or calculate a new acceleration phase with v_exit as v_reach? it will be very short, shorter than the step size.
# TODO: or calculate a new acceleration phase with v_exit as v_target? it will be very short, shorter than the step size.
end
# copy csOriginal to csModified
csModified=CharacteristicSection(csOriginal.id, csOriginal.s_total, csOriginal.s_start, csOriginal.s_end, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_reach, csOriginal.v_entry, csOriginal.v_exit, csOriginal.f_Rp, Dict{String, BehaviorSection}())
csModified=CharacteristicSection(csOriginal.id, csOriginal.length, csOriginal.s_entry, csOriginal.s_exit, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_target, csOriginal.v_entry, csOriginal.v_exit, csOriginal.f_Rp, Dict{String, BehaviorSection}())
if haskey(csOriginal.behaviorSections, "starting")
startingSection=BehaviorSection(get(csOriginal.behaviorSections, "starting", BehaviorSection()))
merge!(csModified.behaviorSections, Dict("starting"=>startingSection))
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "starting", BehaviorSection()).E_total
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "starting", BehaviorSection()).t_total
if haskey(csOriginal.behaviorSections, "breakFree")
breakFreeSection=BehaviorSection(get(csOriginal.behaviorSections, "breakFree", BehaviorSection()))
merge!(csModified.behaviorSections, Dict("breakFree"=>breakFreeSection))
csModified.E=csModified.E+get(csModified.behaviorSections, "breakFree", BehaviorSection()).E
csModified.t=csModified.t+get(csModified.behaviorSections, "breakFree", BehaviorSection()).t
end
#accelerationSection=BehaviorSection(get(csOriginal.behaviorSections, "acceleration", BehaviorSection()))
if length(accelerationSection.dataPoints) > 2
if haskey(csOriginal.behaviorSections, "cruisingBeforeAcceleration")
cruisingBeforeAccelerationSection=BehaviorSection(get(csOriginal.behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()))
merge!(csModified.behaviorSections, Dict("cruisingBeforeAcceleration"=>cruisingBeforeAccelerationSection))
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()).E_total
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()).t_total
if haskey(csOriginal.behaviorSections, "clearing")
clearingSection=BehaviorSection(get(csOriginal.behaviorSections, "clearing", BehaviorSection()))
merge!(csModified.behaviorSections, Dict("clearing"=>clearingSection))
csModified.E=csModified.E+get(csModified.behaviorSections, "clearing", BehaviorSection()).E
csModified.t=csModified.t+get(csModified.behaviorSections, "clearing", BehaviorSection()).t
end
# remove the last acceleration waypoint
pop!(accelerationSection.dataPoints)
accelerationSection.v_exit=drivingCourse[accelerationSection.dataPoints[end]].v # exit speed (in m/s)
accelerationSection.s_end=drivingCourse[accelerationSection.dataPoints[end]].s # last position (in m)
accelerationSection.s_total=accelerationSection.s_end-accelerationSection.s_start # total length (in m)
accelerationSection.t_total=drivingCourse[accelerationSection.dataPoints[end]].t-drivingCourse[accelerationSection.dataPoints[1]].t # total running time (in s)
accelerationSection.E_total=drivingCourse[accelerationSection.dataPoints[end]].E-drivingCourse[accelerationSection.dataPoints[1]].E # total energy consumption (in Ws)
accelerationSection.s_exit=drivingCourse[accelerationSection.dataPoints[end]].s # last position (in m)
accelerationSection.length=accelerationSection.s_exit-accelerationSection.s_entry # total length (in m)
accelerationSection.t=drivingCourse[accelerationSection.dataPoints[end]].t-drivingCourse[accelerationSection.dataPoints[1]].t # total running time (in s)
accelerationSection.E=drivingCourse[accelerationSection.dataPoints[end]].E-drivingCourse[accelerationSection.dataPoints[1]].E # total energy consumption (in Ws)
merge!(csModified.behaviorSections, Dict("acceleration"=>accelerationSection))
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "acceleration", BehaviorSection()).E_total
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "acceleration", BehaviorSection()).t_total
csModified.E=csModified.E+get(csModified.behaviorSections, "acceleration", BehaviorSection()).E
csModified.t=csModified.t+get(csModified.behaviorSections, "acceleration", BehaviorSection()).t
energySavingStartId=accelerationSection.dataPoints[end]
else
# The acceleration section is only one step. This step is removed and if there is a cruisingBeforeAcceleration section it will be combined with the new cruising section.
energySavingStartId=get(csOriginal.behaviorSections, "cruisingBeforeAcceleration", get(csOriginal.behaviorSections, "acceleration", BehaviorSection())).dataPoints[1]
# The acceleration section is only one step. This step is removed and if there is a clearing section it will be combined with the new cruising section.
energySavingStartId=get(csOriginal.behaviorSections, "clearing", get(csOriginal.behaviorSections, "acceleration", BehaviorSection())).dataPoints[1]
end
# TODO: should v_reach be reduced or is it enough to pop the data points?
# characteristicSection.v_reach=drivingCourse[end].v # setting v_reach to the last data points velocity which is the highest reachable value in this characteristic section
# TODO: should v_target be reduced or is it enough to pop the data points?
# characteristicSection.v_target=drivingCourse[end].v # setting v_target to the last data point's velocity which is the highest reachable value in this characteristic section
# copy the drivingCourse till the beginning of energy saving
drivingCourseModified=Vector{DataPoint}()
@ -452,9 +452,9 @@ function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCours
push!(drivingCourseModified, DataPoint(drivingCourse[i])) # List of data points till the start of energy saving
end
#s_braking=max(0.0, ceil((csModified.v_exit^2-csModified.v_reach^2)/2/train.a_braking, digits=approximationLevel)) # ceil is used to be sure that the train stops at s_end in spite of rounding errors
s_braking=max(0.0, ceil((csModified.v_exit^2-drivingCourseModified[end].v^2)/2/train.a_braking, digits=approximationLevel)) # ceil is used to be sure that the train stops at s_end in spite of rounding errors
s_cruising=csModified.s_end-drivingCourseModified[end].s-s_braking
#s_braking=max(0.0, ceil((csModified.v_exit^2-csModified.v_target^2)/2/train.a_braking, digits=approximationLevel)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
s_braking=max(0.0, ceil((csModified.v_exit^2-drivingCourseModified[end].v^2)/2/train.a_braking, digits=approximationLevel)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
s_cruising=csModified.s_exit-drivingCourseModified[end].s-s_braking
if s_cruising >0.001
(csModified, drivingCourseModified)=addCruisingPhase!(csModified, drivingCourseModified, s_cruising, settings, train, allCSs, "cruising")
@ -464,25 +464,25 @@ function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCours
if drivingCourseModified[end].v>csModified.v_exit
#(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings.massModel, train, allCSs)
(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings, train, allCSs)
elseif drivingCourseModified[end].s<csModified.s_end
if (csModified.s_end-drivingCourseModified[end].s)>0.001
# if (csModified.s_end-drivingCourseModified[end].s)>10^(-approximationLevel)
# println("INFO: The end of new CS",csModified.id," is not reached while saving energy with lowering v_reach.")
elseif drivingCourseModified[end].s<csModified.s_exit
if (csModified.s_exit-drivingCourseModified[end].s)>0.001
# if (csModified.s_exit-drivingCourseModified[end].s)>10^(-approximationLevel)
# println("INFO: The end of new CS",csModified.id," is not reached while saving energy with lowering v_target.")
# println(" Therefore the calculation of this method can not continue for this CS.")
return (CharacteristicSection(), [], false)
end
println("WARNING: The end of new CS",csModified.id," is not reached while saving energy with lowering v_reach.")
println(" Therefore s=",drivingCourseModified[end].s," will be set s_end=",csModified.s_end," because the difference is only ",csModified.s_end-drivingCourseModified[end].s," m.")
println("WARNING: The end of new CS",csModified.id," is not reached while saving energy with lowering v_target.")
println(" Therefore s=",drivingCourseModified[end].s," will be set s_exit=",csModified.s_exit," because the difference is only ",csModified.s_exit-drivingCourseModified[end].s," m.")
println(" v=",drivingCourseModified[end].v," m/s v_exit=",csOriginal.v_exit ," m/s")
drivingCourseModified[end].s=csModified.s_end # rounding up to s_end
drivingCourseModified[end].s=csModified.s_exit # rounding up to s_exit
end #if
if t_recoveryAvailable>=(csModified.t_total-csOriginal.t_total)
if t_recoveryAvailable>=(csModified.t-csOriginal.t)
return (csModified, drivingCourseModified, true)
else # time loss is to high. so there is no energy saving modification for this CS with the available recovery time
# 09/06 old: else # time loss is to high and the CS has to be calculated again with larger acceleration section (so with a smaller reduction of the acceleration section)
# 09/06 old: accelerationReduction=min(accelerationReduction/10, csModified.v_reach-csModified.v_entry, csModified.v_reach-csModified.v_exit)
# 09/06 old: accelerationReduction=min(accelerationReduction/10, csModified.v_target-csModified.v_entry, csModified.v_target-csModified.v_exit)
# TODO: just return false or take smaller steps?
return (CharacteristicSection(), [], false)
@ -494,14 +494,14 @@ function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCours
# 09/06 old: return (CharacteristicSection(), [], false)
else
# there is no energy saving modification for this CS because v_reach can not be lowered below v_entry or v_exit or because there is no acceleration section that can be transformed into a cruising section
# there is no energy saving modification for this CS because v_target can not be lowered below v_entry or v_exit or because there is no acceleration section that can be transformed into a cruising section
return (CharacteristicSection(), [], false)
end #if haskey
end # function decreaseMaximumVelocity
# combination of method 1 and method 2
function combineEnergySavingMethods(csOriginal::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Settings, train::Train, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
# if haskey(csOriginal.behaviorSections, "acceleration") && (haskey(csOriginal.behaviorSections, "braking") || haskey(csOriginal.behaviorSections, "coasting")) && csOriginal.v_reach>csOriginal.v_entry && csOriginal.v_reach>csOriginal.v_exit
# if haskey(csOriginal.behaviorSections, "acceleration") && (haskey(csOriginal.behaviorSections, "braking") || haskey(csOriginal.behaviorSections, "coasting")) && csOriginal.v_target>csOriginal.v_entry && csOriginal.v_target>csOriginal.v_exit
if haskey(csOriginal.behaviorSections, "acceleration") && (haskey(csOriginal.behaviorSections, "braking") || haskey(csOriginal.behaviorSections, "coasting")) && drivingCourse[get(csOriginal.behaviorSections, "acceleration", BehaviorSection()).dataPoints[end]].v > max(csOriginal.v_entry, csOriginal.v_exit)
csCombined=CharacteristicSection(csOriginal)
drivingCourseCombined=Vector{DataPoint}()
@ -515,14 +515,14 @@ function combineEnergySavingMethods(csOriginal::CharacteristicSection, drivingCo
while (Δt<t_recoveryAvailable && (Δt<=0.0 || ΔE<=0.0)) #ΔE<=0.0)
(csCombined, drivingCourseCombined, newMaximumVelocity)=decreaseMaximumVelocity(csCombined, drivingCourseCombined, settings, train, allCSs, t_recoveryAvailable)
if newMaximumVelocity
ΔE=csOriginal.E_total-csCombined.E_total # saved energy (in Ws)
Δt=csCombined.t_total-csOriginal.t_total # time loss (in s)
ΔE=csOriginal.E-csCombined.E # saved energy (in Ws)
Δt=csCombined.t-csOriginal.t # time loss (in s)
while (haskey(csOriginal.behaviorSections, "cruising") && (Δt<=0.0 || ΔE<=0.0)) #Δt<=0.0) #&& ΔE<=0.0) # && Δt<=0.0)
(csCombined, drivingCourseCombined, newCoasting)=increaseCoastingSection(csCombined, drivingCourseCombined, settings, train, allCSs, t_recoveryAvailable-Δt)
if newCoasting
ΔE=csOriginal.E_total-csCombined.E_total # saved energy (in Ws)
Δt=csCombined.t_total-csOriginal.t_total # time loss (in s)
ΔE=csOriginal.E-csCombined.E # saved energy (in Ws)
Δt=csCombined.t-csOriginal.t # time loss (in s)
else
break
end # if newCoasting
@ -533,7 +533,7 @@ function combineEnergySavingMethods(csOriginal::CharacteristicSection, drivingCo
end # while
return (csCombined, drivingCourseCombined, (ΔE>0.0))# && Δt>0.0))
else
# there is no energy saving modification for this CS because v_reach can not be lowered below v_entry or v_exit or because there is no acceleration section and braking section or coasting section that can be transformed into a cruising section or coasting section
# there is no energy saving modification for this CS because v_target can not be lowered below v_entry or v_exit or because there is no acceleration section and braking section or coasting section that can be transformed into a cruising section or coasting section
return (CharacteristicSection(), [], false)
end #if
end #function combineEnergySavingMethods

View File

@ -44,10 +44,10 @@ function inputTrain(trainDirectory::String)
error("ERROR at reading the train yaml file: The keyword trainType is missing. It has to be added with the value freight, motor coach train or passenger.")
end
if haskey(data["train"],"l_union")
if typeof(data["train"]["l_union"]) <: Real && data["train"]["l_union"]>0.0
train.l_union=data["train"]["l_union"] # total length (in m)
delete!(data["train"], "l_union")
if haskey(data["train"],"l_train")
if typeof(data["train"]["l_train"]) <: Real && data["train"]["l_train"]>0.0
train.l_train=data["train"]["l_train"] # total length (in m)
delete!(data["train"], "l_train")
else
error("ERROR at reading the train yaml file: The value of the length is no real number >0.0.")
end
@ -155,13 +155,13 @@ function inputTrain(trainDirectory::String)
delete!(data["train"], "m_w")
# total mass (in kg)
train.m_union=train.m_t+train.m_w
train.m_train=train.m_t+train.m_w
if haskey(data["train"],"rotationMassFactor_union") && typeof(data["train"]["rotationMassFactor_union"]) <: Real
if data["train"]["rotationMassFactor_union"]>0.0
train.ξ_union=data["train"]["rotationMassFactor_union"]
if haskey(data["train"],"rotationMassFactor_train") && typeof(data["train"]["rotationMassFactor_train"]) <: Real
if data["train"]["rotationMassFactor_train"]>0.0
train.ξ_train=data["train"]["rotationMassFactor_train"]
else
error("ERROR at reading the train yaml file: The value of rotationMassFactor_union is no real floating point number >0.0.")
error("ERROR at reading the train yaml file: The value of rotationMassFactor_train is no real floating point number >0.0.")
end
elseif haskey(data["train"],"rotationMassFactor_t") && typeof(data["train"]["rotationMassFactor_t"]) <: Real && (train.m_w==0.0 || (haskey(data["train"],"rotationMassFactor_w") && typeof(data["train"]["rotationMassFactor_w"]) <: Real))
if data["train"]["rotationMassFactor_t"]>0.0
@ -178,11 +178,11 @@ function inputTrain(trainDirectory::String)
else
train.ξ_w=0.0
end
train.ξ_union=(train.ξ_t*train.m_t + train.ξ_w*train.m_w)/train.m_union # rotation mass factor of the whole train (without unit)
train.ξ_train=(train.ξ_t*train.m_t + train.ξ_w*train.m_w)/train.m_train # rotation mass factor of the whole train (without unit)
else
error("ERROR at reading the train yaml file: The keywords rotationMassFactor_union or rotationMassFactor_t and rotationMassFactor_w are missing. They has to be added with a value of type real floating point number.")
error("ERROR at reading the train yaml file: The keywords rotationMassFactor_train or rotationMassFactor_t and rotationMassFactor_w are missing. They has to be added with a value of type real floating point number.")
end
delete!(data["train"], "rotationMassFactor_union")
delete!(data["train"], "rotationMassFactor_train")
delete!(data["train"], "rotationMassFactor_t")
delete!(data["train"], "rotationMassFactor_w")
@ -546,12 +546,11 @@ function inputPath(pathDirectory::String)
# save values in the path object
for row in 2:length(sectionStartsArray)
s_start=sectionStartsArray[row-1][1] # starting point of the section (in m)
s_startNext=sectionStartsArray[row][1] # starting point of the next section (in m)
v_limit=sectionStartsArray[row-1][2]*conversionFactor # paths speed limt (in m/s)
n=sectionStartsArray[row-1][3] # gradient (in ‰)
f_Rp=n # specific path resistance of the section (in ‰)
section=PathSection(s_start, s_startNext, v_limit, n, f_Rp)
s_start=sectionStartsArray[row-1][1] # first point of the section (in m)
s_end=sectionStartsArray[row][1] # first point of the next section (in m)
v_limit=sectionStartsArray[row-1][2]*conversionFactor # paths speed limt (in m/s)
f_Rp=sectionStartsArray[row-1][3] # specific path resistance of the section (in ‰)
section=PathSection(s_start, s_end, v_limit, f_Rp)
push!(path.sections, section)
end # for
@ -577,7 +576,7 @@ function inputSettings(settingsDirectory::String)
settings=Settings()
# model type of the unions mass "mass point" or "homogeneous strip"
# model type of the train's mass "mass point" or "homogeneous strip"
if haskey(data["settings"],"massModel")
if typeof(data["settings"]["massModel"])==String && (data["settings"]["massModel"]=="mass point" || data["settings"]["massModel"]=="homogeneous strip")
settings.massModel=data["settings"]["massModel"] # "mass point" or "homogeneous strip"
@ -672,15 +671,15 @@ function inputSettings(settingsDirectory::String)
end # if
# should the output be "reduced" or "driving course"
# should the output be "minimal" or "driving course"
if haskey(data["settings"],"detailOfOutput")
if typeof(data["settings"]["detailOfOutput"])==String && (data["settings"]["detailOfOutput"]=="reduced" || data["settings"]["detailOfOutput"]=="driving course")
settings.detailOfOutput=data["settings"]["detailOfOutput"] # "reduced" or "driving course"
if typeof(data["settings"]["detailOfOutput"])==String && (data["settings"]["detailOfOutput"]=="minimal" || data["settings"]["detailOfOutput"]=="driving course")
settings.detailOfOutput=data["settings"]["detailOfOutput"] # "minimal" or "driving course"
else
error("ERROR at reading the settings yaml file: The value of detailOfOutput is wrong. It has to be reduced or driving course.")
error("ERROR at reading the settings yaml file: The value of detailOfOutput is wrong. It has to be minimal or driving course.")
end
else
error("ERROR at reading the settings yaml file: The keyword detailOfOutput is missing. It has to be added with the value reduced or driving course.")
error("ERROR at reading the settings yaml file: The keyword detailOfOutput is missing. It has to be added with the value minimal or driving course.")
end
delete!(data["settings"], "detailOfOutput")

View File

@ -104,23 +104,23 @@ calculate and return the path resistance dependend on the trains position and ma
function calculatePathResistance(s::AbstractFloat, massModel::String, train::Train, allCs::Vector{CharacteristicSection})
# looking for the characteristic section with the trains head position
id=length(allCs)
while s<allCs[id].s_start
while s<allCs[id].s_entry
id=id-1
if id==0
println("s=",s," MS.s_start=",allCs[1].s_start)
println("s=",s," MS.s_entry=",allCs[1].s_entry)
end
end #while
if massModel=="mass point"
pathResistance=allCs[id].f_Rp/1000*train.m_union*g # /1000 because of the unit ‰
pathResistance=allCs[id].f_Rp/1000*train.m_train*g # /1000 because of the unit ‰
elseif massModel=="homogeneous strip"
pathResistance=0.0
while id>0 && s-train.l_union<allCs[id].s_end
pathResistance=pathResistance+(min(s, allCs[id].s_end)-max(s-train.l_union, allCs[id].s_start))/train.l_union*(allCs[id].f_Rp/1000*train.m_union*g) # /1000 because of the unit ‰
while id>0 && s-train.l_train<allCs[id].s_exit
pathResistance=pathResistance+(min(s, allCs[id].s_exit)-max(s-train.l_train, allCs[id].s_entry))/train.l_train*(allCs[id].f_Rp/1000*train.m_train*g) # /1000 because of the unit ‰
id=id-1
if id==0
# TODO: currently for values < movingSection.s_start the values of movingSection.s_start will be used
return pathResistance+(allCs[1].s_start-(s-train.l_union))/train.l_union*(allCs[1].f_Rp/1000*train.m_union*g) # /1000 because of the unit ‰
# TODO: currently for values < movingSection.s_entry the values of movingSection.s_entry will be used
return pathResistance+(allCs[1].s_entry-(s-train.l_train))/train.l_train*(allCs[1].f_Rp/1000*train.m_train*g) # /1000 because of the unit ‰
end #if
end #while
else
@ -135,11 +135,11 @@ calculate and return tractive and resisting forces for a data point
"""
function calculateForces!(dataPoint::DataPoint, train::Train, massModel::String, allCs::Vector{CharacteristicSection}, bsType::String)
# calculate resisting forces
dataPoint.F_Rt=calculateTractionUnitResistance(dataPoint.v, train)
dataPoint.F_Rw=calculateWagonsResistance(dataPoint.v, train)
dataPoint.F_Runion=dataPoint.F_Rt+dataPoint.F_Rw
dataPoint.F_Rp=calculatePathResistance(dataPoint.s, massModel, train, allCs)
dataPoint.F_R=dataPoint.F_Runion+dataPoint.F_Rp
dataPoint.R_traction=calculateTractionUnitResistance(dataPoint.v, train)
dataPoint.R_consist=calculateWagonsResistance(dataPoint.v, train)
dataPoint.R_train=dataPoint.R_traction+dataPoint.R_consist
dataPoint.R_path=calculatePathResistance(dataPoint.s, massModel, train, allCs)
dataPoint.F_R=dataPoint.R_train+dataPoint.R_path
# calculate tractive effort
if bsType == "acceleration" || bsType == "diminishing"
@ -180,7 +180,7 @@ function moveAStep(previousPoint::DataPoint, stepVariable::String, stepSize::Abs
if ((previousPoint.v/previousPoint.a)^2+2*newPoint.Δs/previousPoint.a)<0.0 || (previousPoint.v^2+2*newPoint.Δs*previousPoint.a)<0.0 # checking if the parts of the following square roots will be <0.0
error("ERROR: The train stops during the acceleration phase in CS",csId," because the tractive effort is lower than the resistant forces.",
" Before the stop the last point has the values s=",previousPoint.s," m, v=",previousPoint.v," m/s, a=",previousPoint.a," m/s^2,",
" F_T=",previousPoint.F_T," N, F_Rt=",previousPoint.F_Rt," N, F_Rw=",previousPoint.F_Rw," N, F_Rp=",previousPoint.F_Rp," N.")
" F_T=",previousPoint.F_T," N, R_traction=",previousPoint.R_traction," N, R_consist=",previousPoint.R_consist," N, R_path=",previousPoint.R_path," N.")
end
end
# 11/21 ->|
@ -199,9 +199,9 @@ function moveAStep(previousPoint::DataPoint, stepVariable::String, stepSize::Abs
newPoint.s=previousPoint.s+newPoint.Δs # position (in m)
newPoint.t=previousPoint.t+newPoint.Δt # point in time (in s)
newPoint.v=previousPoint.v+newPoint.Δv # velocity (in m/s)
newPoint.ΔW_T=previousPoint.F_T*newPoint.Δs # mechanical work in this step (in Ws)
newPoint.W_T=previousPoint.W_T+newPoint.ΔW_T # mechanical work (in Ws)
newPoint.ΔE=newPoint.ΔW_T # energy consumption in this step (in Ws)
newPoint.ΔW=previousPoint.F_T*newPoint.Δs # mechanical work in this step (in Ws)
newPoint.W=previousPoint.W+newPoint.ΔW # mechanical work (in Ws)
newPoint.ΔE=newPoint.ΔW # energy consumption in this step (in Ws)
newPoint.E=previousPoint.E+newPoint.ΔE # energy consumption (in Ws)
@ -212,13 +212,13 @@ end #function moveAStep
"""
# if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
"""
function detectFormerSpeedLimits(allCs::Vector{CharacteristicSection}, csWithTrainHeadId::Integer, currentPoint::DataPoint, l_union::AbstractFloat)
function detectFormerSpeedLimits(allCs::Vector{CharacteristicSection}, csWithTrainHeadId::Integer, currentPoint::DataPoint, l_train::AbstractFloat)
formerSpeedLimits=[]
if csWithTrainHeadId > 1 && currentPoint.s - l_union < allCs[csWithTrainHeadId].s_start
if csWithTrainHeadId > 1 && currentPoint.s - l_train < allCs[csWithTrainHeadId].s_entry
formerCsId=csWithTrainHeadId-1
while formerCsId > 0 && currentPoint.s - l_union < allCs[formerCsId].s_end
if allCs[formerCsId].v_limit < allCs[csWithTrainHeadId].v_limit # TODO: is the position of trains tail < movingSection.s_start, v_limit of the first CS is used
push!(formerSpeedLimits, [allCs[formerCsId].s_end, allCs[formerCsId].v_limit])
while formerCsId > 0 && currentPoint.s - l_train < allCs[formerCsId].s_exit
if allCs[formerCsId].v_limit < allCs[csWithTrainHeadId].v_limit # TODO: is the position of trains tail < movingSection.s_entry, v_limit of the first CS is used
push!(formerSpeedLimits, [allCs[formerCsId].s_exit, allCs[formerCsId].v_limit])
for i in 1:length(formerSpeedLimits)-1
if formerSpeedLimits[i][2]<=formerSpeedLimits[end][2]
pop!(formerSpeedLimits)
@ -236,35 +236,35 @@ function considerFormerSpeedLimits!(characteristicSection::CharacteristicSection
# TODO: What is the type of formerSpeedLimits? function considerFormerSpeedLimits!(characteristicSection::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Settings, train::Train, allCs::Vector{CharacteristicSection}, formerSpeedLimits::Array{Array{AbstractFloat,1},1}, accelerationSection::BehaviorSection)
# would work: function considerFormerSpeedLimits!(characteristicSection::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Settings, train::Train, allCs::Vector{CharacteristicSection}, formerSpeedLimits::Array{Any,1}, accelerationSection::BehaviorSection)
if length(formerSpeedLimits) > 0
# if a former speed limit has been exceeded the acceleration steps of this CS will be removed and a cruising phase will be inserted before acceleration
# if a former speed limit has been exceeded the acceleration steps of this CS will be removed and a clearing phase will be inserted before acceleration
if drivingCourse[end].v > formerSpeedLimits[end][2]
# while drivingCourse[end].s > get(characteristicSection.behaviorSections, "cruisingBeforeAcceleration", accelerationSection).s_start
while drivingCourse[end].s > get(characteristicSection.behaviorSections, "cruisingBeforeAcceleration", accelerationSection).s_start
# while drivingCourse[end].s > get(characteristicSection.behaviorSections, "clearing", accelerationSection).s_entry
while drivingCourse[end].s > get(characteristicSection.behaviorSections, "clearing", accelerationSection).s_entry
pop!(drivingCourse)
end
if haskey(characteristicSection.behaviorSections, "cruisingBeforeAcceleration")
characteristicSection.t_total=characteristicSection.t_total-get(characteristicSection.behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()).t_total # reducing the total running time (in s)
characteristicSection.E_total=characteristicSection.E_total-get(characteristicSection.behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()).E_total # reducing the total energy consumption (in Ws)
delete!(characteristicSection.behaviorSections, "cruisingBeforeAcceleration")
if haskey(characteristicSection.behaviorSections, "clearing")
characteristicSection.t=characteristicSection.t-characteristicSection.behaviorSections["clearing"].t # reducing the total running time (in s)
characteristicSection.E=characteristicSection.E-characteristicSection.behaviorSections["clearing"].E # reducing the total energy consumption (in Ws)
delete!(characteristicSection.behaviorSections, "clearing")
end
# create a (new and longer) cruisingBeforeAcceleration section
# create a (new and longer) clearing section
s_braking=max(0.0, ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=approximationLevel))
s_cruisingBeforeAcceleration=min(characteristicSection.s_end-drivingCourse[end].s-s_braking, formerSpeedLimits[end][1]-(drivingCourse[end].s-train.l_union))
s_clearing=min(characteristicSection.s_exit-drivingCourse[end].s-s_braking, formerSpeedLimits[end][1]-(drivingCourse[end].s-train.l_train))
if s_cruisingBeforeAcceleration>0.0
(characteristicSection, drivingCourse)=addCruisingPhase!(characteristicSection, drivingCourse, s_cruisingBeforeAcceleration, settings, train, allCs, "cruisingBeforeAcceleration")
if s_clearing>0.0
(characteristicSection, drivingCourse)=addCruisingPhase!(characteristicSection, drivingCourse, s_clearing, settings, train, allCs, "clearing")
else
error("ERROR: cruisingBeforeAcceleration <=0.0 although it has to be >0.0 in CS ",characteristicSection.id)
error("ERROR: clearing <=0.0 although it has to be >0.0 in CS ",characteristicSection.id)
end
# 09/22: if drivingCourse[end].s < characteristicSection.s_end
if drivingCourse[end].s < characteristicSection.s_end-s_braking
# 09/22: if drivingCourse[end].s < characteristicSection.s_exit
if drivingCourse[end].s < characteristicSection.s_exit-s_braking
# reset the accelerationSection
accelerationSection=BehaviorSection()
accelerationSection.type="acceleration" # type of behavior section
accelerationSection.s_start=drivingCourse[end].s # first position (in m)
accelerationSection.s_entry=drivingCourse[end].s # first position (in m)
accelerationSection.v_entry=drivingCourse[end].v # entry speed (in m/s)
#currentStepSize=settings.stepSize # initializing the step size that can be reduced near intersections
@ -274,33 +274,33 @@ function considerFormerSpeedLimits!(characteristicSection::CharacteristicSection
end
# remove former speed limits of characteristic sections the train has left during the last step from the list
while length(formerSpeedLimits) > 0 && drivingCourse[end].s - train.l_union >= formerSpeedLimits[end][1]
while length(formerSpeedLimits) > 0 && drivingCourse[end].s - train.l_train >= formerSpeedLimits[end][1]
pop!(formerSpeedLimits)
end
end
return (characteristicSection, drivingCourse, formerSpeedLimits, accelerationSection, false)
end # function considerFormerSpeedLimits!
## This function calculates the data points of the starting phase.
# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for starting if needed.
# Info: currently the values of the starting phase will be calculated like in the acceleration phase
## This function calculates the data points of the breakFree phase.
# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for breakFree if needed.
# Info: currently the values of the breakFree phase will be calculated like in the acceleration phase
function addStartingPhase!(characteristicSection::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Settings, train::Train, allCs::Vector{CharacteristicSection})
if drivingCourse[end].v==0.0 && drivingCourse[end].s<characteristicSection.s_end
startingSection=BehaviorSection()
startingSection.type="starting" # type of behavior section
startingSection.s_start=drivingCourse[end].s # first position (in m)
startingSection.v_entry=drivingCourse[end].v # entry speed (in m/s)
push!(startingSection.dataPoints, drivingCourse[end].i) # list of containing data points
if drivingCourse[end].v==0.0 && drivingCourse[end].s<characteristicSection.s_exit
breakFreeSection=BehaviorSection()
breakFreeSection.type="breakFree" # type of behavior section
breakFreeSection.s_entry=drivingCourse[end].s # first position (in m)
breakFreeSection.v_entry=drivingCourse[end].v # entry speed (in m/s)
push!(breakFreeSection.dataPoints, drivingCourse[end].i) # list of containing data points
# traction effort and resisting forces (in N):
drivingCourse[end]=DataPoint(calculateForces!(drivingCourse[end], train, settings.massModel, allCs, "acceleration")) # currently the tractive effort is calculated like in the acceleration phase
# acceleration (in m/s^2):
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train.m_union/train.ξ_union
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train.m_train/train.ξ_train
if drivingCourse[end].a<0.0
error("ERROR: a<0 m/s^2 in the starting phase !")
error("ERROR: a<0 m/s^2 in the breakFree phase !")
elseif drivingCourse[end].a==0.0
error("ERROR: a=0 m/s^2 in the starting phase !")
error("ERROR: a=0 m/s^2 in the breakFree phase !")
end
# creating the next data point
@ -328,25 +328,25 @@ function addStartingPhase!(characteristicSection::CharacteristicSection, driving
drivingCourse[end].s=drivingCourse[end-1].s+drivingCourse[end].Δs # position (in m)
drivingCourse[end].t=drivingCourse[end-1].t+drivingCourse[end].Δt # point in time (in s)
drivingCourse[end].v=drivingCourse[end-1].v+drivingCourse[end].Δv # velocity (in m/s)
drivingCourse[end].ΔW_T=drivingCourse[end-1].F_T*drivingCourse[end].Δs # mechanical work in this step (in Ws)
drivingCourse[end].W_T=drivingCourse[end-1].W_T+drivingCourse[end].ΔW_T # mechanical work (in Ws)
drivingCourse[end].ΔE=drivingCourse[end].ΔW_T # energy consumption in this step (in Ws)
drivingCourse[end].ΔW=drivingCourse[end-1].F_T*drivingCourse[end].Δs # mechanical work in this step (in Ws)
drivingCourse[end].W=drivingCourse[end-1].W+drivingCourse[end].ΔW # mechanical work (in Ws)
drivingCourse[end].ΔE=drivingCourse[end].ΔW # energy consumption in this step (in Ws)
drivingCourse[end].E=drivingCourse[end-1].E+drivingCourse[end].ΔE # energy consumption (in Ws)
=#
push!(startingSection.dataPoints, drivingCourse[end].i)
push!(breakFreeSection.dataPoints, drivingCourse[end].i)
# calculate the accumulated starting section information
startingSection.s_end=drivingCourse[end].s # last position (in m)
startingSection.s_total=startingSection.s_end-startingSection.s_start # total length (in m)
startingSection.v_exit=drivingCourse[end].v # exit speed (in m/s)
startingSection.t_total=drivingCourse[end].t-drivingCourse[startingSection.dataPoints[1]].t # total running time (in s)
startingSection.E_total=drivingCourse[end].E-drivingCourse[startingSection.dataPoints[1]].E # total energy consumption (in Ws)
# calculate the accumulated breakFree section information
breakFreeSection.s_exit=drivingCourse[end].s # last position (in m)
breakFreeSection.length=breakFreeSection.s_exit-breakFreeSection.s_entry # total length (in m)
breakFreeSection.v_exit=drivingCourse[end].v # exit speed (in m/s)
breakFreeSection.t=drivingCourse[end].t-drivingCourse[breakFreeSection.dataPoints[1]].t # total running time (in s)
breakFreeSection.E=drivingCourse[end].E-drivingCourse[breakFreeSection.dataPoints[1]].E # total energy consumption (in Ws)
characteristicSection.t_total=characteristicSection.t_total+startingSection.t_total # total running time (in s)
characteristicSection.E_total=characteristicSection.E_total+startingSection.E_total # total energy consumption (in Ws)
characteristicSection.t=characteristicSection.t+breakFreeSection.t # total running time (in s)
characteristicSection.E=characteristicSection.E+breakFreeSection.E # total energy consumption (in Ws)
merge!(characteristicSection.behaviorSections, Dict("starting"=>startingSection))
end # else: return the characteristic section without a starting section
merge!(characteristicSection.behaviorSections, Dict("breakFree"=>breakFreeSection))
end # else: return the characteristic section without a breakFree section
return (characteristicSection, drivingCourse)
end #function addStartingPhase!
@ -365,31 +365,31 @@ function addAccelerationPhase!(characteristicSection::CharacteristicSection, dri
end
# if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
formerSpeedLimits = detectFormerSpeedLimits(allCs, characteristicSection.id, drivingCourse[end], train.l_union)
formerSpeedLimits = detectFormerSpeedLimits(allCs, characteristicSection.id, drivingCourse[end], train.l_train)
# conditions for acceleration phase
targetSpeedReached = drivingCourse[end].v >= characteristicSection.v_reach
trainAtEnd = drivingCourse[end].s >= characteristicSection.s_end
targetSpeedReached = drivingCourse[end].v >= characteristicSection.v_target
trainAtEnd = drivingCourse[end].s >= characteristicSection.s_exit
tractionSurplus = drivingCourse[end].F_T > drivingCourse[end].F_R
# use the conditions for the acceleration phase
if !targetSpeedReached && !trainAtEnd && tractionSurplus
#11/23 old without F_T > F_R: if drivingCourse[end].v < characteristicSection.v_reach && drivingCourse[end].s <characteristicSection.s_end && drivingCourse[end].F_T > drivingCourse[end].F_R
#11/23 old without F_T > F_R: if drivingCourse[end].v < characteristicSection.v_target && drivingCourse[end].s <characteristicSection.s_exit && drivingCourse[end].F_T > drivingCourse[end].F_R
accelerationSection=BehaviorSection()
accelerationSection.type="acceleration" # type of behavior section
accelerationSection.s_start=drivingCourse[end].s # first position (in m)
accelerationSection.s_entry=drivingCourse[end].s # first position (in m)
accelerationSection.v_entry=drivingCourse[end].v # entry speed (in m/s)
push!(accelerationSection.dataPoints, drivingCourse[end].i)
currentStepSize=settings.stepSize # initializing the step size that can be reduced near intersections
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
while drivingCourse[end].v<characteristicSection.v_reach && drivingCourse[end].s<characteristicSection.s_end && drivingCourse[end].F_T > drivingCourse[end].F_R
# 12/03 old with v>0.0: while drivingCourse[end].v<characteristicSection.v_reach && drivingCourse[end].s<characteristicSection.s_end && drivingCourse[end].v>0.0 && drivingCourse[end].F_T > drivingCourse[end].F_R
while drivingCourse[end].v<characteristicSection.v_target && drivingCourse[end].s<characteristicSection.s_exit && drivingCourse[end].F_T > drivingCourse[end].F_R
# 12/03 old with v>0.0: while drivingCourse[end].v<characteristicSection.v_target && drivingCourse[end].s<characteristicSection.s_exit && drivingCourse[end].v>0.0 && drivingCourse[end].F_T > drivingCourse[end].F_R
# traction effort and resisting forces (in N)
# 11/22 drivingCourse[end]=DataPoint(calculateForces!(drivingCourse[end], train, settings.massModel, allCs, accelerationSection.type))
# acceleration (in m/s^2):
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train.m_union/train.ξ_union
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train.m_train/train.ξ_train
# create the next data point
push!(drivingCourse, moveAStep(drivingCourse[end], settings.stepVariable, currentStepSize, characteristicSection.id))
@ -412,30 +412,30 @@ function addAccelerationPhase!(characteristicSection::CharacteristicSection, dri
if drivingCourse[end].v<=0.0
currentStepSize = settings.stepSize / 10.0^cycle
elseif drivingCourse[end].s>characteristicSection.s_end
elseif drivingCourse[end].s>characteristicSection.s_exit
if settings.stepVariable == "s in m"
currentStepSize=characteristicSection.s_end-drivingCourse[end-1].s
currentStepSize=characteristicSection.s_exit-drivingCourse[end-1].s
else
currentStepSize = settings.stepSize / 10.0^cycle
end
elseif drivingCourse[end].v>characteristicSection.v_reach
elseif drivingCourse[end].v>characteristicSection.v_target
if settings.stepVariable=="v in m/s"
currentStepSize=characteristicSection.v_reach-drivingCourse[end-1].v
currentStepSize=characteristicSection.v_target-drivingCourse[end-1].v
else
currentStepSize = settings.stepSize / 10.0^cycle
end
elseif drivingCourse[end].s==characteristicSection.s_end
elseif drivingCourse[end].s==characteristicSection.s_exit
break
elseif drivingCourse[end].v==characteristicSection.v_reach
elseif drivingCourse[end].v==characteristicSection.v_target
break
elseif drivingCourse[end].F_T <= drivingCourse[end].F_R
currentStepSize = settings.stepSize / 10.0^cycle
else
error("ERROR at acceleration phase: With the step variable ",settings.stepVariable," the while loop will be left although v<v_reach and s<s_end in CS",characteristicSection.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
error("ERROR at acceleration phase: With the step variable ",settings.stepVariable," the while loop will be left although v<v_target and s<s_exit in CS",characteristicSection.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
end
# delete last data point for recalculating the last step with reduced step size
pop!(drivingCourse)
@ -446,13 +446,13 @@ function addAccelerationPhase!(characteristicSection::CharacteristicSection, dri
# push!(accelerationSection.dataPoints, drivingCourse[end].i)
error("ERROR: The train stops during the acceleration phase in CS",characteristicSection.id," because the tractive effort is lower than the resistant forces.",
" Before the stop the last point has the values s=",drivingCourse[end-1].s," m v=",drivingCourse[end-1].v," m/s a=",drivingCourse[end-1].a," m/s^2",
" F_T=",drivingCourse[end-1].F_T," N F_Rt=",drivingCourse[end-1].F_Rt," N F_Rw=",drivingCourse[end-1].F_Rw," N F_Rp=",drivingCourse[end-1].F_Rp," N.")
" F_T=",drivingCourse[end-1].F_T," N R_traction=",drivingCourse[end-1].R_traction," N R_consist=",drivingCourse[end-1].R_consist," N R_path=",drivingCourse[end-1].R_path," N.")
elseif drivingCourse[end].v>characteristicSection.v_reach
elseif drivingCourse[end].v>characteristicSection.v_target
pop!(drivingCourse)
pop!(accelerationSection.dataPoints)
elseif drivingCourse[end].s>characteristicSection.s_end
drivingCourse[end].s=characteristicSection.s_end # rounding s down to s_end
elseif drivingCourse[end].s>characteristicSection.s_exit
drivingCourse[end].s=characteristicSection.s_exit # rounding s down to s_exit
elseif drivingCourse[end].F_T <= drivingCourse[end].F_R
(characteristicSection, drivingCourse)=addDiminishingPhase!(characteristicSection, drivingCourse, settings, train, allCs)
@ -464,19 +464,19 @@ function addAccelerationPhase!(characteristicSection::CharacteristicSection, dri
end
end #for
if length(accelerationSection.dataPoints) > 1 # 11/21 new: it is possible that the acceleration starts at v_reach, accelerates a step, is to high and drops the last point. then there is only one data point which is not a section.
if length(accelerationSection.dataPoints) > 1 # 11/21 new: it is possible that the acceleration starts at v_target, accelerates a step, is to high and drops the last point. then there is only one data point which is not a section.
# calculate the accumulated acceleration section information
accelerationSection.v_exit=drivingCourse[end].v # exit speed (in m/s)
accelerationSection.s_end=drivingCourse[end].s # last position (in m)
accelerationSection.s_total=accelerationSection.s_end-accelerationSection.s_start # total length (in m)
accelerationSection.t_total=drivingCourse[end].t-drivingCourse[accelerationSection.dataPoints[1]].t # total running time (in s)
accelerationSection.E_total=drivingCourse[end].E-drivingCourse[accelerationSection.dataPoints[1]].E # total energy consumption (in Ws)
characteristicSection.t_total=characteristicSection.t_total+accelerationSection.t_total # total running time (in s)
characteristicSection.E_total=characteristicSection.E_total+accelerationSection.E_total # total energy consumption (in Ws)
accelerationSection.s_exit=drivingCourse[end].s # last position (in m)
accelerationSection.length=accelerationSection.s_exit-accelerationSection.s_entry # total length (in m)
accelerationSection.t=drivingCourse[end].t-drivingCourse[accelerationSection.dataPoints[1]].t # total running time (in s)
accelerationSection.E=drivingCourse[end].E-drivingCourse[accelerationSection.dataPoints[1]].E # total energy consumption (in Ws)
characteristicSection.t=characteristicSection.t+accelerationSection.t # total running time (in s)
characteristicSection.E=characteristicSection.E+accelerationSection.E # total energy consumption (in Ws)
# TODO: this warning schould not be needed. just for testing
if characteristicSection.v_reach < drivingCourse[end].v
println("WARNING, v is getting to high at the end of the acceleration phase. v=",drivingCourse[end].v ," > v_reach=",characteristicSection.v_reach)
if characteristicSection.v_target < drivingCourse[end].v
println("WARNING, v is getting to high at the end of the acceleration phase. v=",drivingCourse[end].v ," > v_target=",characteristicSection.v_target)
end
merge!(characteristicSection.behaviorSections, Dict("acceleration"=>accelerationSection))
@ -500,29 +500,29 @@ function addAccelerationPhaseUntilBraking!(characteristicSection::Characteristic
end
# if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
formerSpeedLimits = detectFormerSpeedLimits(allCs, characteristicSection.id, drivingCourse[end], train.l_union)
formerSpeedLimits = detectFormerSpeedLimits(allCs, characteristicSection.id, drivingCourse[end], train.l_train)
# 11/23 old without F_T>F_R: if drivingCourse[end].v < characteristicSection.v_reach && drivingCourse[end].s<characteristicSection.s_end
if drivingCourse[end].v < characteristicSection.v_reach && drivingCourse[end].s<characteristicSection.s_end && drivingCourse[end].F_T > drivingCourse[end].F_R
# 11/23 old without F_T>F_R: if drivingCourse[end].v < characteristicSection.v_target && drivingCourse[end].s<characteristicSection.s_exit
if drivingCourse[end].v < characteristicSection.v_target && drivingCourse[end].s<characteristicSection.s_exit && drivingCourse[end].F_T > drivingCourse[end].F_R
accelerationSection=BehaviorSection()
accelerationSection.type="acceleration" # type of behavior section
accelerationSection.s_start=drivingCourse[end].s # first position (in m)
accelerationSection.s_entry=drivingCourse[end].s # first position (in m)
accelerationSection.v_entry=drivingCourse[end].v # entry speed (in m/s)
push!(accelerationSection.dataPoints, drivingCourse[end].i)
currentStepSize=settings.stepSize # initializing the step size that can be reduced near intersections
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
s_braking=max(0.0, ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=approximationLevel))
while drivingCourse[end].v < characteristicSection.v_reach && drivingCourse[end].s+s_braking<characteristicSection.s_end && drivingCourse[end].F_T > drivingCourse[end].F_R # as long as s_i + s_braking < s_CSend
# 12/03 old with v>0 while drivingCourse[end].v < characteristicSection.v_reach && drivingCourse[end].s+s_braking<characteristicSection.s_end && drivingCourse[end].v>0.0 && drivingCourse[end].F_T > drivingCourse[end].F_R # as long as s_i + s_braking < s_CSend
while drivingCourse[end].v < characteristicSection.v_target && drivingCourse[end].s+s_braking<characteristicSection.s_exit && drivingCourse[end].F_T > drivingCourse[end].F_R # as long as s_i + s_braking < s_CSend
# 12/03 old with v>0 while drivingCourse[end].v < characteristicSection.v_target && drivingCourse[end].s+s_braking<characteristicSection.s_exit && drivingCourse[end].v>0.0 && drivingCourse[end].F_T > drivingCourse[end].F_R # as long as s_i + s_braking < s_CSend
#11/22 drivingCourse[end]=DataPoint(calculateForces!(drivingCourse[end], train, settings.massModel, allCs, accelerationSection.type))
# acceleration (in m/s^2):
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train.m_union/train.ξ_union
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train.m_train/train.ξ_train
# if drivingCourse[end].a==0.0
# error("ERROR: a=0 m/s^2 in the acceleration phase ! with F_T=",drivingCourse[end].F_T," F_Rt=",drivingCourse[end].F_Rt," F_Rw=",drivingCourse[end].F_Rw," F_Rp=",drivingCourse[end].F_Rp)
# error("ERROR: a=0 m/s^2 in the acceleration phase ! with F_T=",drivingCourse[end].F_T," R_traction=",drivingCourse[end].R_traction," R_consist=",drivingCourse[end].R_consist," R_path=",drivingCourse[end].R_path)
# end
# create the next data point
@ -545,27 +545,27 @@ function addAccelerationPhaseUntilBraking!(characteristicSection::Characteristic
if drivingCourse[end].v<=0.0
currentStepSize = settings.stepSize / 10.0^cycle
elseif drivingCourse[end].s +s_braking > characteristicSection.s_end
elseif drivingCourse[end].s +s_braking > characteristicSection.s_exit
currentStepSize = settings.stepSize / 10.0^cycle
elseif drivingCourse[end].v>characteristicSection.v_reach
elseif drivingCourse[end].v>characteristicSection.v_target
if settings.stepVariable=="v in m/s"
currentStepSize= characteristicSection.v_reach-drivingCourse[end-1].v
currentStepSize= characteristicSection.v_target-drivingCourse[end-1].v
else
currentStepSize = settings.stepSize / 10.0^cycle
end
elseif drivingCourse[end].s==characteristicSection.s_end
elseif drivingCourse[end].s==characteristicSection.s_exit
break
elseif drivingCourse[end].v==characteristicSection.v_reach
elseif drivingCourse[end].v==characteristicSection.v_target
break
elseif drivingCourse[end].F_T <= drivingCourse[end].F_R
currentStepSize = settings.stepSize / 10.0^cycle
else
error("ERROR at acceleration until braking phase: With the step variable ",settings.stepVariable," the while loop will be left although v<v_reach and s<s_end in CS",characteristicSection.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
error("ERROR at acceleration until braking phase: With the step variable ",settings.stepVariable," the while loop will be left although v<v_target and s<s_exit in CS",characteristicSection.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
end
# delete last data point for recalculating the last step with reduced step size
pop!(drivingCourse)
@ -576,12 +576,12 @@ function addAccelerationPhaseUntilBraking!(characteristicSection::Characteristic
# push!(accelerationSection.dataPoints, drivingCourse[end].i)
error("ERROR: The train stops during the acceleration phase in CS",characteristicSection.id," because the tractive effort is lower than the resistant forces.",
" Before the stop the last point has the values s=",drivingCourse[end-1].s," m v=",drivingCourse[end-1].v," m/s a=",drivingCourse[end-1].a," m/s^2",
" F_T=",drivingCourse[end-1].F_T," N F_Rt=",drivingCourse[end-1].F_Rt," N F_Rw=",drivingCourse[end-1].F_Rw," N F_Rp=",drivingCourse[end-1].F_Rp," N.")
" F_T=",drivingCourse[end-1].F_T," N R_traction=",drivingCourse[end-1].R_traction," N R_consist=",drivingCourse[end-1].R_consist," N R_path=",drivingCourse[end-1].R_path," N.")
elseif drivingCourse[end].v>characteristicSection.v_reach
elseif drivingCourse[end].v>characteristicSection.v_target
pop!(drivingCourse)
pop!(accelerationSection.dataPoints)
elseif drivingCourse[end].s + s_braking > characteristicSection.s_end
elseif drivingCourse[end].s + s_braking > characteristicSection.s_exit
pop!(drivingCourse)
pop!(accelerationSection.dataPoints)
@ -595,17 +595,17 @@ function addAccelerationPhaseUntilBraking!(characteristicSection::Characteristic
end
end #for
if length(accelerationSection.dataPoints) > 1 # 09/09 new: it is possible that the acceleration starts at v_reach, accelerates a step, is to high and drops the last point. then there is only one data point which is not a section.
if length(accelerationSection.dataPoints) > 1 # TODO: is it still possible that it is <=1 although there is a sepaate diminishing phase?
# calculate the accumulated acceleration section information
accelerationSection.v_exit=drivingCourse[end].v # exit speed (in m/s)
accelerationSection.s_end=drivingCourse[end].s # last position (in m)
accelerationSection.s_total=accelerationSection.s_end-accelerationSection.s_start # total length (in m)
accelerationSection.t_total=drivingCourse[end].t-drivingCourse[accelerationSection.dataPoints[1]].t # total running time (in s)
accelerationSection.E_total=drivingCourse[end].E-drivingCourse[accelerationSection.dataPoints[1]].E # total energy consumption (in Ws)
accelerationSection.s_exit=drivingCourse[end].s # last position (in m)
accelerationSection.length=accelerationSection.s_exit-accelerationSection.s_entry # total length (in m)
accelerationSection.t=drivingCourse[end].t-drivingCourse[accelerationSection.dataPoints[1]].t # total running time (in s)
accelerationSection.E=drivingCourse[end].E-drivingCourse[accelerationSection.dataPoints[1]].E # total energy consumption (in Ws)
characteristicSection.v_reach=max(drivingCourse[end].v, characteristicSection.v_entry) # setting v_reach to the last data points velocity which is the highest reachable value in this characteristic section or to v_entry in case it is higher when driveng on a path with high resistances
characteristicSection.t_total=characteristicSection.t_total+accelerationSection.t_total # total running time (in s)
characteristicSection.E_total=characteristicSection.E_total+accelerationSection.E_total # total energy consumption (in Ws)
characteristicSection.v_target=max(drivingCourse[end].v, characteristicSection.v_entry) # setting v_target to the last data points velocity which is the highest reachable value in this characteristic section or to v_entry in case it is higher when driving on a path with high resistances
characteristicSection.t=characteristicSection.t+accelerationSection.t # total running time (in s)
characteristicSection.E=characteristicSection.E+accelerationSection.E # total energy consumption (in Ws)
merge!(characteristicSection.behaviorSections, Dict("acceleration"=>accelerationSection))
end
@ -623,19 +623,19 @@ function addCruisingPhase!(characteristicSection::CharacteristicSection, driving
if drivingCourse[end].F_T < drivingCourse[end].F_R
(characteristicSection, drivingCourse)=addDiminishingPhase!(characteristicSection, drivingCourse, settings, train, allCs)
drivingCourse[end]=DataPoint(calculateForces!(drivingCourse[end], train, settings.massModel, allCs, "cruising"))
s_cruising=max(0.0, s_cruising-get(characteristicSection.behaviorSections, "diminishing", BehaviorSection()).s_total)
s_cruising=max(0.0, s_cruising-get(characteristicSection.behaviorSections, "diminishing", BehaviorSection()).length)
end
if drivingCourse[end].v>0.0 && drivingCourse[end].v<=characteristicSection.v_reach && drivingCourse[end].s<characteristicSection.s_end && drivingCourse[end].F_T >= drivingCourse[end].F_R
# 11/22 old: if drivingCourse[end].v>0.0 && drivingCourse[end].v<=characteristicSection.v_reach && drivingCourse[end].s<characteristicSection.s_end
if drivingCourse[end].v>0.0 && drivingCourse[end].v<=characteristicSection.v_target && drivingCourse[end].s<characteristicSection.s_exit && drivingCourse[end].F_T >= drivingCourse[end].F_R
# 11/22 old: if drivingCourse[end].v>0.0 && drivingCourse[end].v<=characteristicSection.v_target && drivingCourse[end].s<characteristicSection.s_exit
cruisingSection=BehaviorSection()
cruisingSection.type=cruisingType # type of behavior section
cruisingSection.s_start=drivingCourse[end].s # first position (in m)
# 11/22: now it is at the end of the BS: cruisingSection.s_end=min(drivingCourse[end].s+s_cruising, characteristicSection.s_end) # last position (in m)
cruisingSection.s_entry=drivingCourse[end].s # first position (in m)
# 11/22: now it is at the end of the BS: cruisingSection.s_exit=min(drivingCourse[end].s+s_cruising, characteristicSection.s_exit) # last position (in m)
cruisingSection.v_entry=drivingCourse[end].v # entry speed (in m/s)
push!(cruisingSection.dataPoints, drivingCourse[end].i)
# TODO: necessary?
s_cruising=min(s_cruising, characteristicSection.s_end-cruisingSection.s_start)
s_cruising=min(s_cruising, characteristicSection.s_exit-cruisingSection.s_entry)
# traction effort and resisting forces (in N)
calculateForces!(drivingCourse[end], train, settings.massModel, allCs, "cruising") # TODO: or give cruisingSection.type instead of "cruising"?
@ -644,11 +644,11 @@ function addCruisingPhase!(characteristicSection::CharacteristicSection, driving
if settings.massModel=="homogeneous strip" && characteristicSection.id > 1
currentStepSize=settings.stepSize
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
while drivingCourse[end].s < characteristicSection.s_start + train.l_union && drivingCourse[end].s<cruisingSection.s_start+s_cruising && drivingCourse[end].F_T>=drivingCourse[end].F_R #&& drivingCourse[end].v<=characteristicSection.v_reach && drivingCourse[end].s<characteristicSection.s_end
# TODO: whithout allCs should work as well, no? while drivingCourse[end].s < allCs[characteristicSection.id].s_start + train.l_union && drivingCourse[end].s<cruisingSection.s_start+s_cruising && drivingCourse[end].F_T>=drivingCourse[end].F_R #&& drivingCourse[end].v<=characteristicSection.v_reach && drivingCourse[end].s<characteristicSection.s_end
# the tractive effort is lower than the resisiting forces and the train has use the highest possible effort to try to stay at v_reach OR the mass model homogeneous strip is used and parts of the train are still in former CS
while drivingCourse[end].s < characteristicSection.s_entry + train.l_train && drivingCourse[end].s<cruisingSection.s_entry+s_cruising && drivingCourse[end].F_T>=drivingCourse[end].F_R #&& drivingCourse[end].v<=characteristicSection.v_target && drivingCourse[end].s<characteristicSection.s_exit
# TODO: whithout allCs should work as well, no? while drivingCourse[end].s < allCs[characteristicSection.id].s_entry + train.l_train && drivingCourse[end].s<cruisingSection.s_entry+s_cruising && drivingCourse[end].F_T>=drivingCourse[end].F_R #&& drivingCourse[end].v<=characteristicSection.v_target && drivingCourse[end].s<characteristicSection.s_exit
# the tractive effort is lower than the resisiting forces and the train has use the highest possible effort to try to stay at v_target OR the mass model homogeneous strip is used and parts of the train are still in former CS
#TODO: maybe just consider former CS with different path resistance?
#TODO: what about the case: After leaving a former CS with steep gradient the train can accelerate. Now in this tool the train will cruise at v_i. Just accelerating until v_reach could make problems for energy saving by shortening the acceleration phase
#TODO: what about the case: After leaving a former CS with steep gradient the train can accelerate. Now in this tool the train will cruise at v_i. Just accelerating until v_target could make problems for energy saving by shortening the acceleration phase
# acceleration (in m/s^2):
drivingCourse[end].a=0.0
@ -657,7 +657,7 @@ function addCruisingPhase!(characteristicSection::CharacteristicSection, driving
if settings.stepVariable=="s in m"
push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", currentStepSize, characteristicSection.id))
else
push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", train.l_union/(10.0^cycle), characteristicSection.id)) # TODO which step size should be used?
push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", train.l_train/(10.0^cycle), characteristicSection.id)) # TODO which step size should be used?
end
push!(cruisingSection.dataPoints, drivingCourse[end].i)
@ -672,22 +672,22 @@ function addCruisingPhase!(characteristicSection::CharacteristicSection, driving
# check which limit was reached and adjust the currentStepSize for the next cycle
if cycle < approximationLevel+1
if drivingCourse[end].s>cruisingSection.s_start+s_cruising # TODO also the following? drivingCourse[end].s > allCs[characteristicSection.id].s_start + train.l_union))
if drivingCourse[end].s>cruisingSection.s_entry+s_cruising # TODO also the following? drivingCourse[end].s > allCs[characteristicSection.id].s_entry + train.l_train))
if settings.stepVariable == "s in m"
currentStepSize=cruisingSection.s_start+s_cruising-drivingCourse[end-1].s
currentStepSize=cruisingSection.s_entry+s_cruising-drivingCourse[end-1].s
else
currentStepSize = settings.stepSize / 10.0^cycle
end
elseif drivingCourse[end].s==cruisingSection.s_start+s_cruising # || drivingCourse[end].s==characteristicSection.s_end
elseif drivingCourse[end].s==cruisingSection.s_entry+s_cruising # || drivingCourse[end].s==characteristicSection.s_exit
break
elseif drivingCourse[end].F_T < drivingCourse[end].F_R
# if settings.stepVariable == "s in m"
# currentStepSize=cruisingSection.s_start+s_cruising-drivingCourse[end-1].s
# currentStepSize=cruisingSection.s_entry+s_cruising-drivingCourse[end-1].s
# else
currentStepSize = settings.stepSize / 10.0^cycle
# end
elseif drivingCourse[end].s >= characteristicSection.s_start + train.l_union
# TODO: whithout allCs should work as well, no? elseif drivingCourse[end].s >= allCs[characteristicSection.id].s_start + train.l_union
elseif drivingCourse[end].s >= characteristicSection.s_entry + train.l_train
# TODO: whithout allCs should work as well, no? elseif drivingCourse[end].s >= allCs[characteristicSection.id].s_entry + train.l_train
break
else # TODO copied from addAccelerationPhase -> probably not needed here !?
error("ERROR at cruising phase: With the step variable ",settings.stepVariable," the while loop will be left although the if cases don't apply in CS",characteristicSection.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
@ -698,14 +698,14 @@ function addCruisingPhase!(characteristicSection::CharacteristicSection, driving
pop!(cruisingSection.dataPoints)
else # if the level of approximation is reached
if drivingCourse[end].s>cruisingSection.s_start+s_cruising
if cruisingSection.type == "cruisingBeforeAcceleration"
if drivingCourse[end].s>cruisingSection.s_entry+s_cruising
if cruisingSection.type == "clearing"
else
pop!(drivingCourse)
pop!(cruisingSection.dataPoints)
end
# 11/21 |->
elseif drivingCourse[end].s==cruisingSection.s_start+s_cruising
elseif drivingCourse[end].s==cruisingSection.s_entry+s_cruising
break
# 11/21 ->|
elseif drivingCourse[end].F_T < drivingCourse[end].F_R
@ -713,7 +713,7 @@ function addCruisingPhase!(characteristicSection::CharacteristicSection, driving
(characteristicSection, drivingCourse)=addDiminishingPhase!(characteristicSection, drivingCourse, settings, train, allCs)
drivingCourse[end]=DataPoint(calculateForces!(drivingCourse[end], train, settings.massModel, allCs, "cruising"))
# s_cruising=max(0.0, s_cruising-get(characteristicSection.behaviorSections, "diminishing", BehaviorSection()).s_total)
# s_cruising=max(0.0, s_cruising-get(characteristicSection.behaviorSections, "diminishing", BehaviorSection()).length)
else
@ -723,12 +723,12 @@ function addCruisingPhase!(characteristicSection::CharacteristicSection, driving
end #if
# TODO oder soll das lieber nach oben in den else des letzten Durchlaufs. Noch mal genauer ansehen, ob hier was doppelt gemoppelt ist
# if drivingCourse[end].s<cruisingSection.s_start+s_cruising
if drivingCourse[end].s<cruisingSection.s_start+s_cruising && drivingCourse[end].F_T >= drivingCourse[end].F_R
# if drivingCourse[end].s<cruisingSection.s_entry+s_cruising
if drivingCourse[end].s<cruisingSection.s_entry+s_cruising && drivingCourse[end].F_T >= drivingCourse[end].F_R
drivingCourse[end].a=0.0 # acceleration (in m/s^2)
# calculate the remaining cruising way
s_cruisingRemaining=cruisingSection.s_start+s_cruising-drivingCourse[end].s
s_cruisingRemaining=cruisingSection.s_entry+s_cruising-drivingCourse[end].s
# create the next data point
push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", s_cruisingRemaining, characteristicSection.id))
@ -737,19 +737,19 @@ function addCruisingPhase!(characteristicSection::CharacteristicSection, driving
## new 09/06 TODO: if no acceleration is following the cruising it could be called cruising
#if cruisingSection.type == "cruisingBeforeAcceleration" && drivingCourse[end].s == characteristicSection.s_end
#if cruisingSection.type == "clearing" && drivingCourse[end].s == characteristicSection.s_exit
# cruisingSection.type = "cruising"
#end
# calculate the accumulated cruising section information
cruisingSection.v_exit=drivingCourse[end].v # exit speed (in m/s)
cruisingSection.s_end=drivingCourse[end].s # last position (in m)
cruisingSection.s_total=cruisingSection.s_end-cruisingSection.s_start # total length (in m)
cruisingSection.t_total=drivingCourse[end].t-drivingCourse[cruisingSection.dataPoints[1]].t # total running time (in s)
cruisingSection.E_total=drivingCourse[end].E-drivingCourse[cruisingSection.dataPoints[1]].E # total energy consumption (in Ws)
cruisingSection.s_exit=drivingCourse[end].s # last position (in m)
cruisingSection.length=cruisingSection.s_exit-cruisingSection.s_entry # total length (in m)
cruisingSection.t=drivingCourse[end].t-drivingCourse[cruisingSection.dataPoints[1]].t # total running time (in s)
cruisingSection.E=drivingCourse[end].E-drivingCourse[cruisingSection.dataPoints[1]].E # total energy consumption (in Ws)
characteristicSection.t_total=characteristicSection.t_total+cruisingSection.t_total # total running time (in s)
characteristicSection.E_total=characteristicSection.E_total+cruisingSection.E_total # total energy consumption (in Ws)
characteristicSection.t=characteristicSection.t+cruisingSection.t # total running time (in s)
characteristicSection.E=characteristicSection.E+cruisingSection.E # total energy consumption (in Ws)
merge!(characteristicSection.behaviorSections, Dict(cruisingSection.type=>cruisingSection))
end # else: return the characteristic section without a cruising section
@ -762,12 +762,12 @@ end #function addCruisingPhase!
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the coasting section
function addCoastingPhaseUntilBraking!(characteristicSection::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Settings, train::Train, allCs::Vector{CharacteristicSection})
## if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
#formerSpeedLimits = detectFormerSpeedLimits(allCs, characteristicSection.id, drivingCourse[end], train.l_union)
#formerSpeedLimits = detectFormerSpeedLimits(allCs, characteristicSection.id, drivingCourse[end], train.l_train)
if drivingCourse[end].v>characteristicSection.v_exit && drivingCourse[end].s<characteristicSection.s_end
if drivingCourse[end].v>characteristicSection.v_exit && drivingCourse[end].s<characteristicSection.s_exit
coastingSection=BehaviorSection()
coastingSection.type="coasting" # type of behavior section
coastingSection.s_start=drivingCourse[end].s # first position (in m)
coastingSection.s_entry=drivingCourse[end].s # first position (in m)
coastingSection.v_entry=drivingCourse[end].v # entry speed (in m/s)
push!(coastingSection.dataPoints, drivingCourse[end].i)
@ -775,12 +775,12 @@ function addCoastingPhaseUntilBraking!(characteristicSection::CharacteristicSect
# 08/24 old for cycle in 1:3 # first cycle with normal step size, second cycle with reduced step size, third cycle with more reduced step size
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
s_braking=ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=approximationLevel)
while drivingCourse[end].v>characteristicSection.v_exit && drivingCourse[end].v<=characteristicSection.v_reach && drivingCourse[end].s + s_braking < characteristicSection.s_end # as long as s_i + s_braking < s_CSend
while drivingCourse[end].v>characteristicSection.v_exit && drivingCourse[end].v<=characteristicSection.v_target && drivingCourse[end].s + s_braking < characteristicSection.s_exit # as long as s_i + s_braking < s_CSend
# traction effort and resisting forces (in N):
drivingCourse[end]=DataPoint(calculateForces!(drivingCourse[end], train, settings.massModel, allCs, coastingSection.type))
# acceleration (in m/s^2):
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train.m_union/train.ξ_union
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train.m_train/train.ξ_train
# creating the next data point
push!(drivingCourse, moveAStep(drivingCourse[end], settings.stepVariable, currentStepSize, characteristicSection.id))
@ -793,19 +793,19 @@ function addCoastingPhaseUntilBraking!(characteristicSection::CharacteristicSect
# check which limit was reached and adjust the currentStepSize for the next cycle
if cycle < approximationLevel+1
if drivingCourse[end].s + s_braking > characteristicSection.s_end
if drivingCourse[end].s + s_braking > characteristicSection.s_exit
currentStepSize = settings.stepSize / 10.0^cycle
elseif drivingCourse[end].v < characteristicSection.v_exit # TODO: if accelereation and coasting functions will be combined this case is only for coasting
currentStepSize = settings.stepSize / 10.0^cycle
elseif drivingCourse[end].v > characteristicSection.v_reach
elseif drivingCourse[end].v > characteristicSection.v_target
if settings.stepVariable=="v in m/s"
currentStepSize = characteristicSection.v_reach-drivingCourse[end-1].v
currentStepSize = characteristicSection.v_target-drivingCourse[end-1].v
else
currentStepSize = settings.stepSize / 10.0^cycle
end
elseif drivingCourse[end].s + s_braking == characteristicSection.s_end
elseif drivingCourse[end].s + s_braking == characteristicSection.s_exit
break
elseif drivingCourse[end].v == characteristicSection.v_exit
@ -813,7 +813,7 @@ function addCoastingPhaseUntilBraking!(characteristicSection::CharacteristicSect
else
# TODO: not needed. just for testing
error("ERROR at coasting until braking phase: With the step variable ",settings.stepVariable," the while loop will be left although v<v_reach and s+s_braking<s_end in CS",characteristicSection.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
error("ERROR at coasting until braking phase: With the step variable ",settings.stepVariable," the while loop will be left although v<v_target and s+s_braking<s_exit in CS",characteristicSection.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
end
# delete last data point for recalculating the last step with reduced step size
pop!(drivingCourse)
@ -823,21 +823,21 @@ function addCoastingPhaseUntilBraking!(characteristicSection::CharacteristicSect
if drivingCourse[end].v<=0.0
println("INFO: The train stops during the coasting phase in CS",characteristicSection.id," ",
" Before the stop the last point has the values s=",drivingCourse[end-1].s," m v=",drivingCourse[end-1].v," m/s a=",drivingCourse[end-1].a," m/s^2",
" F_T=",drivingCourse[end-1].F_T," N F_Rt=",drivingCourse[end-1].F_Rt," N F_Rw=",drivingCourse[end-1].F_Rw," N F_Rp=",drivingCourse[end-1].F_Rp," N and s_braking=",s_braking,"m.")
" F_T=",drivingCourse[end-1].F_T," N R_traction=",drivingCourse[end-1].R_traction," N R_consist=",drivingCourse[end-1].R_consist," N R_path=",drivingCourse[end-1].R_path," N and s_braking=",s_braking,"m.")
elseif drivingCourse[end].s + s_braking > characteristicSection.s_end
elseif drivingCourse[end].s + s_braking > characteristicSection.s_exit
# delete last data point because it went to far
pop!(drivingCourse)
pop!(coastingSection.dataPoints)
elseif drivingCourse[end].v > characteristicSection.v_reach # if the train gets to fast it has to brake # TODO: if accelereation and coasting functions will be combined this case is different for coasting and also the order of if cases is different
# while coasting the train brakes to hold v_reach (only one data point in the end of coasting is calculated like cruising at v_reach)
elseif drivingCourse[end].v > characteristicSection.v_target # if the train gets to fast it has to brake # TODO: if accelereation and coasting functions will be combined this case is different for coasting and also the order of if cases is different
# while coasting the train brakes to hold v_target (only one data point in the end of coasting is calculated like cruising at v_target)
drivingCourse[end-1].a=0.0
s_braking=ceil((characteristicSection.v_exit^2-drivingCourse[end-1].v^2)/2/train.a_braking)
# recalculate s, t, v, E
#drivingCourse[end].Δs= characteristicSection.s_end-drivingCourse[end-1].s - s_braking # step size (in m) # TODO: the coasting section is currently realised with using distance steps. For example t_braking could also be used
drivingCourse[end].Δs=min(currentStepSize, characteristicSection.s_end-(drivingCourse[end-1].s+s_braking)) # TODO: if settings.stepVariable=="s in m"
#drivingCourse[end].Δs= characteristicSection.s_exit-drivingCourse[end-1].s - s_braking # step size (in m) # TODO: the coasting section is currently realised with using distance steps. For example t_braking could also be used
drivingCourse[end].Δs=min(currentStepSize, characteristicSection.s_exit-(drivingCourse[end-1].s+s_braking)) # TODO: if settings.stepVariable=="s in m"
drivingCourse[end].Δt=drivingCourse[end].Δs/drivingCourse[end-1].v # step size (in s)
drivingCourse[end].Δv=0.0 # step size (in m/s)
@ -845,11 +845,11 @@ function addCoastingPhaseUntilBraking!(characteristicSection::CharacteristicSect
drivingCourse[end].t=drivingCourse[end-1].t+drivingCourse[end].Δt # point in time (in s)
drivingCourse[end].v=drivingCourse[end-1].v # velocity (in m/s)
drivingCourse[end].ΔW_T=drivingCourse[end-1].F_T*drivingCourse[end].Δs # mechanical work in this step (in Ws)
drivingCourse[end].ΔW=drivingCourse[end-1].F_T*drivingCourse[end].Δs # mechanical work in this step (in Ws)
# =0.0
drivingCourse[end].W_T=drivingCourse[end-1].W_T+drivingCourse[end].ΔW_T # mechanical work (in Ws)
# =drivingCourse[end-1].W_T
drivingCourse[end].ΔE=drivingCourse[end].ΔW_T # energy consumption in this step (in Ws)
drivingCourse[end].W=drivingCourse[end-1].W+drivingCourse[end].ΔW # mechanical work (in Ws)
# =drivingCourse[end-1].W
drivingCourse[end].ΔE=drivingCourse[end].ΔW # energy consumption in this step (in Ws)
# =0.0
drivingCourse[end].E=drivingCourse[end-1].E+drivingCourse[end].ΔE # energy consumption (in Ws)
# =drivingCourse[end-1].E
@ -861,13 +861,13 @@ function addCoastingPhaseUntilBraking!(characteristicSection::CharacteristicSect
# calculate the accumulated coasting section information
coastingSection.v_exit=drivingCourse[end].v # exit speed (in m/s)
coastingSection.s_end=drivingCourse[end].s # last position (in m)
coastingSection.s_total=coastingSection.s_end-coastingSection.s_start # total length (in m)
coastingSection.t_total=drivingCourse[end].t-drivingCourse[coastingSection.dataPoints[1]].t # total running time (in s)
coastingSection.E_total=drivingCourse[end].E-drivingCourse[coastingSection.dataPoints[1]].E # total energy consumption (in Ws)
coastingSection.s_exit=drivingCourse[end].s # last position (in m)
coastingSection.length=coastingSection.s_exit-coastingSection.s_entry # total length (in m)
coastingSection.t=drivingCourse[end].t-drivingCourse[coastingSection.dataPoints[1]].t # total running time (in s)
coastingSection.E=drivingCourse[end].E-drivingCourse[coastingSection.dataPoints[1]].E # total energy consumption (in Ws)
characteristicSection.t_total=characteristicSection.t_total+coastingSection.t_total # total running time (in s)
characteristicSection.E_total=characteristicSection.E_total+coastingSection.E_total # total energy consumption (in Ws)
characteristicSection.t=characteristicSection.t+coastingSection.t # total running time (in s)
characteristicSection.E=characteristicSection.E+coastingSection.E # total energy consumption (in Ws)
merge!(characteristicSection.behaviorSections, Dict("coasting"=>coastingSection))
end ## else: just return the given data point number without changes due to the coasting phase
@ -880,11 +880,11 @@ end #function addCoastingPhaseUntilBraking!
# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for braking if needed.
function addBrakingPhase!(characteristicSection::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Settings, train::Train, allCs::Vector{CharacteristicSection}) #, s_braking::AbstractFloat)
# function addBrakingPhase!(characteristicSection::CharacteristicSection, drivingCourse::Vector{DataPoint}, massModel::String, train::Train, allCs::Vector{CharacteristicSection}) #, s_braking::AbstractFloat)
if drivingCourse[end].v>characteristicSection.v_exit && drivingCourse[end].s<characteristicSection.s_end
if drivingCourse[end].v>characteristicSection.v_exit && drivingCourse[end].s<characteristicSection.s_exit
brakingSection=BehaviorSection()
brakingSection.type="braking" # type of behavior section
brakingSection.s_start=drivingCourse[end].s # first position (in m)
brakingSection.s_end=characteristicSection.s_end # last position (in m)
brakingSection.s_entry=drivingCourse[end].s # first position (in m)
brakingSection.s_exit=characteristicSection.s_exit # last position (in m)
brakingSection.v_entry=drivingCourse[end].v # entry speed (in m/s)
push!(brakingSection.dataPoints, drivingCourse[end].i) # refering from the breaking section to the first of its data points
@ -896,7 +896,7 @@ function addBrakingPhase!(characteristicSection::CharacteristicSection, drivingC
push!(brakingSection.dataPoints, drivingCourse[end].i) # refering from the breaking section to the last of its data points
# calculate s, t, v
drivingCourse[end].s=brakingSection.s_end # position (in m)
drivingCourse[end].s=brakingSection.s_exit # position (in m)
drivingCourse[end].v=characteristicSection.v_exit # velocity (in m/s)
drivingCourse[end].Δs=drivingCourse[end].s-drivingCourse[end-1].s # step size (in m)
drivingCourse[end].Δv=drivingCourse[end].v-drivingCourse[end-1].v # step size (in m/s)
@ -913,18 +913,18 @@ function addBrakingPhase!(characteristicSection::CharacteristicSection, drivingC
drivingCourse[end].Δt=drivingCourse[end].Δv/drivingCourse[end-1].a # step size (in s)
drivingCourse[end].t=drivingCourse[end-1].t+drivingCourse[end].Δt # point in time (in s)
drivingCourse[end].ΔW_T=0.0 # mechanical work in this step (in Ws)
drivingCourse[end].W_T=drivingCourse[end-1].W_T+drivingCourse[end].ΔW_T # mechanical work (in Ws)
drivingCourse[end].ΔE=drivingCourse[end].ΔW_T # energy consumption in this step (in Ws)
drivingCourse[end].ΔW=0.0 # mechanical work in this step (in Ws)
drivingCourse[end].W=drivingCourse[end-1].W+drivingCourse[end].ΔW # mechanical work (in Ws)
drivingCourse[end].ΔE=drivingCourse[end].ΔW # energy consumption in this step (in Ws)
drivingCourse[end].E=drivingCourse[end-1].E+drivingCourse[end].ΔE # energy consumption (in Ws)
brakingSection.v_exit=drivingCourse[end].v # exit speed (in m/s)
brakingSection.s_total=drivingCourse[end].Δs # total length (in m)
brakingSection.t_total=drivingCourse[end].Δt # total running time (in s)
brakingSection.E_total=drivingCourse[end].ΔE # total energy consumption (in Ws)
brakingSection.length=drivingCourse[end].Δs # total length (in m)
brakingSection.t=drivingCourse[end].Δt # total running time (in s)
brakingSection.E=drivingCourse[end].ΔE # total energy consumption (in Ws)
characteristicSection.t_total=characteristicSection.t_total+brakingSection.t_total # total running time (in s)
characteristicSection.E_total=characteristicSection.E_total+brakingSection.E_total # total energy consumption (in Ws)
characteristicSection.t=characteristicSection.t+brakingSection.t # total running time (in s)
characteristicSection.E=characteristicSection.E+brakingSection.E # total energy consumption (in Ws)
merge!(characteristicSection.behaviorSections, Dict("braking"=>brakingSection))
end # else: return the characteristic section without a braking section
@ -936,16 +936,16 @@ end #function addBrakingPhase!
## This function calculates the data points of the braking phase. # 09/07 new braking phase with more than two data points
# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for braking if needed.
function addBrakingPhaseStepwise!(characteristicSection::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Settings, train::Train, allCs::Vector{CharacteristicSection}) #, s_braking::AbstractFloat)
if drivingCourse[end].v>characteristicSection.v_exit && drivingCourse[end].s<characteristicSection.s_end
if drivingCourse[end].v > characteristicSection.v_exit && drivingCourse[end].s < characteristicSection.s_exit
brakingSection=BehaviorSection()
brakingSection.type="braking" # type of behavior section
brakingSection.s_start=drivingCourse[end].s # first position (in m)
brakingSection.s_entry=drivingCourse[end].s # first position (in m)
brakingSection.v_entry=drivingCourse[end].v # entry speed (in m/s)
push!(brakingSection.dataPoints, drivingCourse[end].i) # refering from the breaking section to the first of its data points
currentStepSize=settings.stepSize # initializing the step size that can be reduced near intersections
velocityIsPositive=true
while drivingCourse[end].v>characteristicSection.v_exit && drivingCourse[end].s < characteristicSection.s_end && velocityIsPositive
while drivingCourse[end].v > characteristicSection.v_exit && drivingCourse[end].s < characteristicSection.s_exit && velocityIsPositive
# traction effort and resisting forces (in N):
drivingCourse[end]=DataPoint(calculateForces!(drivingCourse[end], train, settings.massModel, allCs, brakingSection.type))
@ -970,7 +970,7 @@ function addBrakingPhaseStepwise!(characteristicSection::CharacteristicSection,
if drivingCourse[end].v < characteristicSection.v_exit || !velocityIsPositive
# calculate s, t, v
drivingCourse[end].s=characteristicSection.s_end # position (in m)
drivingCourse[end].s=characteristicSection.s_exit # position (in m)
drivingCourse[end].v=characteristicSection.v_exit # velocity (in m/s)
drivingCourse[end].Δs=drivingCourse[end].s-drivingCourse[end-1].s # step size (in m)
drivingCourse[end].Δv=drivingCourse[end].v-drivingCourse[end-1].v # step size (in m/s)
@ -985,11 +985,11 @@ function addBrakingPhaseStepwise!(characteristicSection::CharacteristicSection,
drivingCourse[end].Δt=drivingCourse[end].Δv/drivingCourse[end-1].a # step size (in s)
drivingCourse[end].t=drivingCourse[end-1].t+drivingCourse[end].Δt # point in time (in s)
drivingCourse[end].ΔW_T=0.0 # mechanical work in this step (in Ws)
drivingCourse[end].W_T=drivingCourse[end-1].W_T+drivingCourse[end].ΔW_T # mechanical work (in Ws)
drivingCourse[end].ΔE=drivingCourse[end].ΔW_T # energy consumption in this step (in Ws)
drivingCourse[end].ΔW=0.0 # mechanical work in this step (in Ws)
drivingCourse[end].W=drivingCourse[end-1].W+drivingCourse[end].ΔW # mechanical work (in Ws)
drivingCourse[end].ΔE=drivingCourse[end].ΔW # energy consumption in this step (in Ws)
drivingCourse[end].E=drivingCourse[end-1].E+drivingCourse[end].ΔE # energy consumption (in Ws)
elseif drivingCourse[end].s > characteristicSection.s_end
elseif drivingCourse[end].s > characteristicSection.s_exit
error("Beim Bremsen wurde das CS-Ende überschritten, aber nicht v_exit unterschritten !!")
else
@ -997,13 +997,13 @@ function addBrakingPhaseStepwise!(characteristicSection::CharacteristicSection,
# calculate the accumulated coasting section information
brakingSection.v_exit=drivingCourse[end].v # exit speed (in m/s)
brakingSection.s_end=drivingCourse[end].s # last position (in m)
brakingSection.s_total=brakingSection.s_end-brakingSection.s_start # total length (in m)
brakingSection.t_total=drivingCourse[end].t-drivingCourse[brakingSection.dataPoints[1]].t # total running time (in s)
brakingSection.E_total=drivingCourse[end].E-drivingCourse[brakingSection.dataPoints[1]].E # total energy consumption (in Ws)
brakingSection.s_exit=drivingCourse[end].s # last position (in m)
brakingSection.length=brakingSection.s_exit-brakingSection.s_entry # total length (in m)
brakingSection.t=drivingCourse[end].t-drivingCourse[brakingSection.dataPoints[1]].t # total running time (in s)
brakingSection.E=drivingCourse[end].E-drivingCourse[brakingSection.dataPoints[1]].E # total energy consumption (in Ws)
characteristicSection.t_total=characteristicSection.t_total+brakingSection.t_total # total running time (in s)
characteristicSection.E_total=characteristicSection.E_total+brakingSection.E_total # total energy consumption (in Ws)
characteristicSection.t=characteristicSection.t+brakingSection.t # total running time (in s)
characteristicSection.E=characteristicSection.E+brakingSection.E # total energy consumption (in Ws)
merge!(characteristicSection.behaviorSections, Dict("braking"=>brakingSection))
end # else: return the characteristic section without a braking section
@ -1015,11 +1015,11 @@ end #function addBrakingPhaseStepwise!
function addDiminishingPhase!(characteristicSection::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Settings, train::Train, allCs::Vector{CharacteristicSection})
drivingCourse[end]=DataPoint(calculateForces!(drivingCourse[end], train, settings.massModel, allCs, "diminishing"))
if drivingCourse[end].F_T <= drivingCourse[end].F_R && drivingCourse[end].v > 0.0 && drivingCourse[end].s<characteristicSection.s_end
#drivingCourse[end].v>0.0 && drivingCourse[end].v<=characteristicSection.v_reach && drivingCourse[end].s<characteristicSection.s_end
if drivingCourse[end].F_T <= drivingCourse[end].F_R && drivingCourse[end].v > 0.0 && drivingCourse[end].s<characteristicSection.s_exit
#drivingCourse[end].v>0.0 && drivingCourse[end].v<=characteristicSection.v_target && drivingCourse[end].s<characteristicSection.s_exit
diminishingSection=BehaviorSection()
diminishingSection.type="diminishing" # type of behavior section
diminishingSection.s_start=drivingCourse[end].s # first position (in m)
diminishingSection.s_entry=drivingCourse[end].s # first position (in m)
diminishingSection.v_entry=drivingCourse[end].v # entry speed (in m/s)
push!(diminishingSection.dataPoints, drivingCourse[end].i)
@ -1027,16 +1027,16 @@ function addDiminishingPhase!(characteristicSection::CharacteristicSection, driv
currentStepSize=settings.stepSize # initializing the step size that can be reduced near intersections
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
s_braking=max(0.0, ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=approximationLevel))
while drivingCourse[end].F_T <= drivingCourse[end].F_R && drivingCourse[end].s+s_braking<characteristicSection.s_end && drivingCourse[end].v>0.0 # as long as s_i + s_braking < s_CSend
# 11/22 old without F_T<=F_R while drivingCourse[end].s+s_braking<characteristicSection.s_end && drivingCourse[end].v>0.0 # as long as s_i + s_braking < s_CSend
while drivingCourse[end].F_T <= drivingCourse[end].F_R && drivingCourse[end].s+s_braking<characteristicSection.s_exit && drivingCourse[end].v>0.0 # as long as s_i + s_braking < s_CSend
# 11/22 old without F_T<=F_R while drivingCourse[end].s+s_braking<characteristicSection.s_exit && drivingCourse[end].v>0.0 # as long as s_i + s_braking < s_CSend
#11/22 drivingCourse[end]=DataPoint(calculateForces!(drivingCourse[end], train, settings.massModel, allCs, diminishingSection.type))
# acceleration (in m/s^2):
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train.m_union/train.ξ_union
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train.m_train/train.ξ_train
# 11/21: old, only for cruising:
#if drivingCourse[end].a==0.0
# error("ERROR: a=0 m/s^2 in the diminishing phase ! with F_T=",drivingCourse[end].F_T," F_Rt=",drivingCourse[end].F_Rt," F_Rw=",drivingCourse[end].F_Rw," F_Rp=",drivingCourse[end].F_Rp)
# error("ERROR: a=0 m/s^2 in the diminishing phase ! with F_T=",drivingCourse[end].F_T," R_traction=",drivingCourse[end].R_traction," R_consist=",drivingCourse[end].R_consist," R_path=",drivingCourse[end].R_path)
#end
# create the next data point
@ -1052,18 +1052,18 @@ function addDiminishingPhase!(characteristicSection::CharacteristicSection, driv
if drivingCourse[end].v<=0.0
currentStepSize = settings.stepSize / 10.0^cycle
elseif drivingCourse[end].s + s_braking > characteristicSection.s_end
elseif drivingCourse[end].s + s_braking > characteristicSection.s_exit
currentStepSize = settings.stepSize / 10.0^cycle
elseif drivingCourse[end].s + s_braking==characteristicSection.s_end
# 11/21 old without s_braking: elseif drivingCourse[end].s==characteristicSection.s_end
elseif drivingCourse[end].s + s_braking==characteristicSection.s_exit
# 11/21 old without s_braking: elseif drivingCourse[end].s==characteristicSection.s_exit
break
elseif drivingCourse[end].F_T > drivingCourse[end].F_R
currentStepSize = settings.stepSize / 10.0^cycle
else
error("ERROR during diminishing run: With the step variable ",settings.stepVariable," the while loop will be left although s+s_braking<s_end && v>0.0 in CS",characteristicSection.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
error("ERROR during diminishing run: With the step variable ",settings.stepVariable," the while loop will be left although s+s_braking<s_exit && v>0.0 in CS",characteristicSection.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
end
# delete last data point for recalculating the last step with reduced step size
pop!(drivingCourse)
@ -1074,9 +1074,9 @@ function addDiminishingPhase!(characteristicSection::CharacteristicSection, driv
# push!(diminishingSection.dataPoints, drivingCourse[end].i)
error("ERROR: The train stops during diminishing run in CS",characteristicSection.id," because the maximum tractive effort is lower than the resistant forces.",
" Before the stop the last point has the values s=",drivingCourse[end-1].s," m v=",drivingCourse[end-1].v," m/s a=",drivingCourse[end-1].a," m/s^2",
" F_T=",drivingCourse[end-1].F_T," N F_Rt=",drivingCourse[end-1].F_Rt," N F_Rw=",drivingCourse[end-1].F_Rw," N F_Rp=",drivingCourse[end-1].F_Rp," N.")
" F_T=",drivingCourse[end-1].F_T," N R_traction=",drivingCourse[end-1].R_traction," N R_consist=",drivingCourse[end-1].R_consist," N R_path=",drivingCourse[end-1].R_path," N.")
elseif drivingCourse[end].s + s_braking > characteristicSection.s_end
elseif drivingCourse[end].s + s_braking > characteristicSection.s_exit
pop!(drivingCourse)
pop!(diminishingSection.dataPoints)
@ -1092,12 +1092,12 @@ function addDiminishingPhase!(characteristicSection::CharacteristicSection, driv
if length(diminishingSection.dataPoints) > 1 # TODO: necessary? May it be possible that there is no diminishing because braking has to start
# calculate the accumulated diminishing section information
diminishingSection.v_exit=drivingCourse[end].v # exit speed (in m/s)
diminishingSection.s_end=drivingCourse[end].s # last position (in m)
diminishingSection.s_total=diminishingSection.s_end-diminishingSection.s_start # total length (in m)
diminishingSection.t_total=drivingCourse[end].t-drivingCourse[diminishingSection.dataPoints[1]].t # total running time (in s)
diminishingSection.E_total=drivingCourse[end].E-drivingCourse[diminishingSection.dataPoints[1]].E # total energy consumption (in Ws)
characteristicSection.t_total=characteristicSection.t_total+diminishingSection.t_total # total running time (in s)
characteristicSection.E_total=characteristicSection.E_total+diminishingSection.E_total # total energy consumption (in Ws)
diminishingSection.s_exit=drivingCourse[end].s # last position (in m)
diminishingSection.length=diminishingSection.s_exit-diminishingSection.s_entry # total length (in m)
diminishingSection.t=drivingCourse[end].t-drivingCourse[diminishingSection.dataPoints[1]].t # total running time (in s)
diminishingSection.E=drivingCourse[end].E-drivingCourse[diminishingSection.dataPoints[1]].E # total energy consumption (in Ws)
characteristicSection.t=characteristicSection.t+diminishingSection.t # total running time (in s)
characteristicSection.E=characteristicSection.E+diminishingSection.E # total energy consumption (in Ws)
merge!(characteristicSection.behaviorSections, Dict("diminishing"=>diminishingSection))
end

View File

@ -7,74 +7,74 @@ include("./EnergySaving.jl")
using .MovingPhases
using .EnergySaving
export simulateMinimumRunningTime!, simulateMinimumEnergyConsumption
export calculateMinimumRunningTime!, calculateMinimumEnergyConsumption
approximationLevel = 6 # TODO: define it in TrainRun and give it to each function?
# simulate a train run focussing on using the minimum possible running time
function simulateMinimumRunningTime!(movingSection::MovingSection, settings::Settings, train::Train)
# calculate a train run focussing on using the minimum possible running time
function calculateMinimumRunningTime!(movingSection::MovingSection, settings::Settings, train::Train)
# CSs=movingSection.characteristicSections
startingPoint=DataPoint()
startingPoint.i=1
startingPoint.s=movingSection.characteristicSections[1].s_start
startingPoint.s=movingSection.characteristicSections[1].s_entry
drivingCourse=[startingPoint] # List of data points
# for CS in CSs
for csId in 1:length(movingSection.characteristicSections)
# println("CS",csId)
# check if the CS has a cruising section
s_starting=get(movingSection.characteristicSections[csId].behaviorSections, "starting", BehaviorSection()).s_total
s_cruisingBeforeAcceleration=get(movingSection.characteristicSections[csId].behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()).s_total
s_acceleration=get(movingSection.characteristicSections[csId].behaviorSections, "acceleration", BehaviorSection()).s_total
s_braking=max(0.0, ceil((movingSection.characteristicSections[csId].v_exit^2-movingSection.characteristicSections[csId].v_reach^2)/2/train.a_braking, digits=approximationLevel)) # ceil is used to be sure that the train stops at s_end in spite of rounding errors
s_breakFree=get(movingSection.characteristicSections[csId].behaviorSections, "breakFree", BehaviorSection()).length
s_clearing=get(movingSection.characteristicSections[csId].behaviorSections, "clearing", BehaviorSection()).length
s_acceleration=get(movingSection.characteristicSections[csId].behaviorSections, "acceleration", BehaviorSection()).length
s_braking=max(0.0, ceil((movingSection.characteristicSections[csId].v_exit^2-movingSection.characteristicSections[csId].v_target^2)/2/train.a_braking, digits=approximationLevel)) # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
# calculate the cruising sections length
s_cruising=movingSection.characteristicSections[csId].s_total-s_starting-s_cruisingBeforeAcceleration-s_acceleration-s_braking
s_cruising=movingSection.characteristicSections[csId].length-s_breakFree-s_clearing-s_acceleration-s_braking
# reset the moving section (MS), delete characteristic sections (CS) that were used during the preperation for setting v_entry, v_reach and v_exit
delete!(movingSection.characteristicSections[csId].behaviorSections, "starting")
delete!(movingSection.characteristicSections[csId].behaviorSections, "cruisingBeforeAcceleration")
# reset the moving section (MS), delete characteristic sections (CS) that were used during the preperation for setting v_entry, v_target and v_exit
delete!(movingSection.characteristicSections[csId].behaviorSections, "breakFree")
delete!(movingSection.characteristicSections[csId].behaviorSections, "clearing")
delete!(movingSection.characteristicSections[csId].behaviorSections, "acceleration")
delete!(movingSection.characteristicSections[csId].behaviorSections, "diminishing") # 11/22 added new
delete!(movingSection.characteristicSections[csId].behaviorSections, "diminishing")
delete!(movingSection.characteristicSections[csId].behaviorSections, "cruising")
movingSection.characteristicSections[csId].E_total=0.0
movingSection.characteristicSections[csId].t_total=0.0
movingSection.characteristicSections[csId].E=0.0
movingSection.characteristicSections[csId].t=0.0
if s_cruisingBeforeAcceleration == movingSection.characteristicSections[csId].s_total
# 09/06 TODO: thought about using "cruising" because it is used in EnergySaving and not cruisingBeforeAcceleration (movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruisingBeforeAcceleration, settings, train, movingSection.characteristicSections, "cruising")
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruisingBeforeAcceleration, settings, train, movingSection.characteristicSections, "cruisingBeforeAcceleration")
elseif s_cruising == movingSection.characteristicSections[csId].s_total
if s_clearing == movingSection.characteristicSections[csId].length
# 09/06 TODO: thought about using "cruising" because it is used in EnergySaving and not clearing (movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_clearing, settings, train, movingSection.characteristicSections, "cruising")
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_clearing, settings, train, movingSection.characteristicSections, "clearing")
elseif s_cruising == movingSection.characteristicSections[csId].length
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruising, settings, train, movingSection.characteristicSections, "cruising")
elseif s_cruising > 0.0 || s_braking == 0.0
# 09/21 elseif s_cruising > 0.0
# 09/21 elseif s_cruising > 0.01 # if the cruising section is longer than 1 cm (because of rounding issues not >0.0)
if drivingCourse[end].v < movingSection.characteristicSections[csId].v_reach
if drivingCourse[end].v < movingSection.characteristicSections[csId].v_target
(movingSection.characteristicSections[csId], drivingCourse)=addAccelerationPhase!(movingSection.characteristicSections[csId], drivingCourse, settings, train, movingSection.characteristicSections)
end #if
if movingSection.characteristicSections[csId].s_end-drivingCourse[end].s-max(0.0, (movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/train.a_braking) < -0.001 # ceil is used to be sure that the train stops at s_end in spite of rounding errors
if movingSection.characteristicSections[csId].s_exit-drivingCourse[end].s-max(0.0, (movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/train.a_braking) < -0.001 # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
println("ERROR: After accelerating in CS ",csId," the braking distance is too short!")
println(" before acceleration in CS",csId, " with s=",drivingCourse[end].s," s_braking=",((movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/train.a_braking)," s_end=",movingSection.characteristicSections[csId].s_end)
println(" and v=",drivingCourse[end].v," v_reach=",movingSection.characteristicSections[csId].v_reach," v_exit=",movingSection.characteristicSections[csId].v_exit)
println(" before acceleration in CS",csId, " with s=",drivingCourse[end].s," s_braking=",((movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/train.a_braking)," s_exit=",movingSection.characteristicSections[csId].s_exit)
println(" and v=",drivingCourse[end].v," v_target=",movingSection.characteristicSections[csId].v_target," v_exit=",movingSection.characteristicSections[csId].v_exit)
end
s_braking=max(0.0, ceil((movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=approximationLevel)) # ceil is used to be sure that the train stops at s_end in spite of rounding errors
s_cruising=movingSection.characteristicSections[csId].s_end-drivingCourse[end].s-s_braking
s_braking=max(0.0, ceil((movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=approximationLevel)) # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
s_cruising=movingSection.characteristicSections[csId].s_exit-drivingCourse[end].s-s_braking
if s_cruising > 0.0
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruising, settings, train, movingSection.characteristicSections, "cruising")
end
else
if movingSection.characteristicSections[csId].v_entry < movingSection.characteristicSections[csId].v_reach || s_acceleration > 0.0 # or instead of " || s_acceleration > 0.0" use "v_entry <= v_reach" or "v_i <= v_reach"
# 09/09 old (not sufficient for steep gradients): if movingSection.characteristicSections[csId].v_entry < movingSection.characteristicSections[csId].v_reach
if movingSection.characteristicSections[csId].v_entry < movingSection.characteristicSections[csId].v_target || s_acceleration > 0.0 # or instead of " || s_acceleration > 0.0" use "v_entry <= v_target" or "v_i <= v_target"
# 09/09 old (not sufficient for steep gradients): if movingSection.characteristicSections[csId].v_entry < movingSection.characteristicSections[csId].v_target
(movingSection.characteristicSections[csId], drivingCourse)=addAccelerationPhaseUntilBraking!(movingSection.characteristicSections[csId], drivingCourse, settings, train, movingSection.characteristicSections)
end #if
end #if
s_braking=max(0.0, ceil((movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=approximationLevel)) # ceil is used to be sure that the train stops at s_end in spite of rounding errors
s_braking=max(0.0, ceil((movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=approximationLevel)) # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
if drivingCourse[end].v > movingSection.characteristicSections[csId].v_exit
#(movingSection.characteristicSections[csId], drivingCourse)=addBrakingPhase!(movingSection.characteristicSections[csId], drivingCourse, settings.massModel, train, movingSection.characteristicSections)
@ -82,9 +82,9 @@ function simulateMinimumRunningTime!(movingSection::MovingSection, settings::Set
end #if
#= 09/20 old and should never be used:
if drivingCourse[end].s < movingSection.characteristicSections[csId].s_end
if drivingCourse[end].s < movingSection.characteristicSections[csId].s_exit
if haskey(movingSection.characteristicSections[csId].behaviorSections, "cruising")
println("INFO: A second cruising section has been added to CS ", csId," from s=",drivingCourse[end].s," to s_end=",movingSection.characteristicSections[csId].s_end)
println("INFO: A second cruising section has been added to CS ", csId," from s=",drivingCourse[end].s," to s_exit=",movingSection.characteristicSections[csId].s_exit)
end
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruising, settings, train, movingSection.characteristicSections, "cruising")
end =#
@ -93,15 +93,15 @@ function simulateMinimumRunningTime!(movingSection::MovingSection, settings::Set
# calculate the last data points resiting forces
drivingCourse[end]=DataPoint(calculateForces!(drivingCourse[end], train, settings.massModel, movingSection.characteristicSections, "braking"))
movingSection.t_total=drivingCourse[end].t # total running time (in s)
movingSection.E_total=drivingCourse[end].E # total energy consumption (in Ws)
movingSection.t=drivingCourse[end].t # total running time (in s)
movingSection.E=drivingCourse[end].E # total energy consumption (in Ws)
return (movingSection, drivingCourse)
end #function simulateMinimumRunningTime
end #function calculateMinimumRunningTime
function simulateMinimumEnergyConsumption(movingSectionMinimumRunningTime::MovingSection, drivingCourseMinimumRunningTime::Vector{DataPoint}, settings::Settings, train::Train)
# simulate a train run focussing on using the minimum possible energy consumption
function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::MovingSection, drivingCourseMinimumRunningTime::Vector{DataPoint}, settings::Settings, train::Train)
# calculate a train run focussing on using the minimum possible energy consumption
# booleans for choosing which methods are used for saving energy
doMethod1=true
#doMethod1=false
@ -120,7 +120,7 @@ function simulateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Movin
end
# calculate the recovery time
movingSectionOriginal.t_recovery=calculateRecoveryTime(movingSectionOriginal.s_total, movingSectionOriginal.t_total, train)
movingSectionOriginal.t_recovery=calculateRecoveryTime(movingSectionOriginal.length, movingSectionOriginal.t, train)
movingSectionOriginal.t_recoveryAvailable=movingSectionOriginal.t_recovery
# create arrays for each method with all the available energy saving modifications
@ -136,7 +136,7 @@ function simulateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Movin
push!(energySavingModificationsWithCoasting, energySavingModification)
end #if doMethod1
# method 2: accelerate to a lower v_reach
# method 2: accelerate to a lower v_target
if doMethod2 == true
modificationType = "decreasing maximum velocity"
energySavingModification = modifyCs(movingSectionOriginal, drivingCourseOriginal, csId, modificationType, settings, train)
@ -227,7 +227,7 @@ function simulateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Movin
movingSectionOriginal.t_recoveryAvailable = movingSectionOriginal.t_recoveryAvailable - movingSectionOriginal.energySavingModifications[end].Δt
lastIdOfSelectedCsOriginal = get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "braking", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "cruisingAfterCoasting", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "coasting", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "cruising", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "acceleration", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "cruisingBeforeAcceleration", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "starting", BehaviorSection()))))))).dataPoints[end]
lastIdOfSelectedCsOriginal = get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "braking", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "cruisingAfterCoasting", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "coasting", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "cruising", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "acceleration", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "clearing", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "breakFree", BehaviorSection()))))))).dataPoints[end]
# create new driving course
drivingCourseNew=Vector{DataPoint}()
@ -265,10 +265,10 @@ function simulateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Movin
#fill up the rest of the driving course with information from the original course
drivingCourseNew[end].F_T=drivingCourseOriginal[lastIdOfSelectedCsOriginal].F_T
drivingCourseNew[end].F_Rt=drivingCourseOriginal[lastIdOfSelectedCsOriginal].F_Rt
drivingCourseNew[end].F_Rw=drivingCourseOriginal[lastIdOfSelectedCsOriginal].F_Rw
drivingCourseNew[end].F_Runion=drivingCourseOriginal[lastIdOfSelectedCsOriginal].F_Runion
drivingCourseNew[end].F_Rp=drivingCourseOriginal[lastIdOfSelectedCsOriginal].F_Rp
drivingCourseNew[end].R_traction=drivingCourseOriginal[lastIdOfSelectedCsOriginal].R_traction
drivingCourseNew[end].R_consist=drivingCourseOriginal[lastIdOfSelectedCsOriginal].R_consist
drivingCourseNew[end].R_train=drivingCourseOriginal[lastIdOfSelectedCsOriginal].R_train
drivingCourseNew[end].R_path=drivingCourseOriginal[lastIdOfSelectedCsOriginal].R_path
drivingCourseNew[end].F_R=drivingCourseOriginal[lastIdOfSelectedCsOriginal].F_R
drivingCourseNew[end].a=drivingCourseOriginal[lastIdOfSelectedCsOriginal].a
@ -281,20 +281,20 @@ function simulateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Movin
drivingCourseNew[end].i=length(drivingCourseNew)
drivingCourseNew[end].t=drivingCourseNew[end-1].t+drivingCourseNew[end].Δt
drivingCourseNew[end].E=drivingCourseNew[end-1].E+drivingCourseNew[end].ΔE
drivingCourseNew[end].W_T=drivingCourseNew[end-1].W_T+drivingCourseNew[end].ΔW_T
drivingCourseNew[end].W=drivingCourseNew[end-1].W+drivingCourseNew[end].ΔW
i=i+1
end # while
# replace the original driving course and CS with the new modified ones
drivingCourseOriginal=drivingCourseNew
movingSectionOriginal.characteristicSections[csIdMax]=CharacteristicSection(movingSectionOriginal.energySavingModifications[end].csModified)
movingSectionOriginal.t_total=drivingCourseOriginal[end].t # total running time (in s)
movingSectionOriginal.E_total=drivingCourseOriginal[end].E # total energy consumption (in Ws)
movingSectionOriginal.t=drivingCourseOriginal[end].t # total running time (in s)
movingSectionOriginal.E=drivingCourseOriginal[end].E # total energy consumption (in Ws)
# update all the data point references in the behaviour sections of the following characteristic sections and the other modified characteristic sections
if difference!= 0
# update the data point references in the behaviour sections of the following characteristic sections
allBs=["starting", "cruisingBeforeAcceleration", "acceleration", "cruising", "coasting", "cruisingAfterCoasting", "braking"]
allBs=["breakFree", "clearing", "acceleration", "cruising", "diminishing", "coasting","cruisingAfterCoasting", "braking", "standStill"]
for csId in csIdMax+1:length(movingSectionOriginal.characteristicSections)
for bs in 1: length(allBs)
if haskey(movingSectionOriginal.characteristicSections[csId].behaviorSections, allBs[bs])
@ -319,7 +319,7 @@ function simulateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Movin
energySavingModificationsWithCoasting[csIdMax]=energySavingModification
end #if if doMethod1
# method 2: accelerate to a lower v_reach
# method 2: accelerate to a lower v_target
if doMethod2==true
modificationType = "decreasing maximum velocity"
energySavingModification = modifyCs(movingSectionOriginal, drivingCourseOriginal, csIdMax, modificationType, settings, train)
@ -337,7 +337,7 @@ function simulateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Movin
println("t_recoveryAvailable=",movingSectionOriginal.t_recoveryAvailable)
return (movingSectionOriginal, drivingCourseOriginal)
end #function simulateMinimumEnergyConsumption
end #function calculateMinimumEnergyConsumption
function modifyCs(movingSectionOriginal::MovingSection, drivingCourseOriginal::Vector{DataPoint}, csId::Integer, modificationType::String, settings::Settings, train::Train)
@ -346,7 +346,7 @@ function modifyCs(movingSectionOriginal::MovingSection, drivingCourseOriginal::V
# method 1: increase coasting
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=increaseCoastingSection(movingSectionOriginal.characteristicSections[csId], drivingCourseOriginal, settings, train, movingSectionOriginal.characteristicSections, movingSectionOriginal.t_recoveryAvailable)
elseif modificationType == "decreasing maximum velocity"
# method 2: accelerate to a lower v_reach
# method 2: accelerate to a lower v_target
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=decreaseMaximumVelocity(movingSectionOriginal.characteristicSections[csId], drivingCourseOriginal, settings, train, movingSectionOriginal.characteristicSections, movingSectionOriginal.t_recoveryAvailable)
elseif modificationType == "combination of energy saving methods"
# calculate the combination of the previous methods
@ -361,8 +361,8 @@ function modifyCs(movingSectionOriginal::MovingSection, drivingCourseOriginal::V
energySavingModification.type = modificationType # type of energy saving modification: "increasing coasting" or "decreasing maximum velocity" or "combination of energy saving methods"
energySavingModification.csModified = characteristicSectionModified # the modified characteristic section
energySavingModification.drivingCourseModified = drivingCourseModifiedUntilEndOfModifiedCS # drivingCourse of the modified characteristic section
energySavingModification.ΔE = movingSectionOriginal.characteristicSections[csId].E_total - energySavingModification.csModified.E_total # saved energy (in Ws)
energySavingModification.Δt = energySavingModification.csModified.t_total - movingSectionOriginal.characteristicSections[csId].t_total # time loss (in s)
energySavingModification.ΔE = movingSectionOriginal.characteristicSections[csId].E - energySavingModification.csModified.E # saved energy (in Ws)
energySavingModification.Δt = energySavingModification.csModified.t - movingSectionOriginal.characteristicSections[csId].t # time loss (in s)
if energySavingModification.Δt <= movingSectionOriginal.t_recoveryAvailable && energySavingModification.ΔE >= 0.0
#*** TODO: check why "sign" is needed here
# if modificationType == "combination of energy saving methods"
@ -397,7 +397,7 @@ function findBestModification(energySavingModifications::Vector{EnergySavingModi
end #function findBestModification
function updateEnergySavingModifications(energySavingModifications::Vector{EnergySavingModification}, csIdMax::Integer, drivingCourseNew::Vector{DataPoint}, endOfModificationId::Integer, lastIdOfSelectedCsOriginal::Integer)
allBs = ["starting", "cruisingBeforeAcceleration", "acceleration", "cruising", "coasting", "cruisingAfterCoasting", "braking"]
allBs=["breakFree", "clearing", "acceleration", "cruising", "diminishing", "coasting","cruisingAfterCoasting", "braking", "standStill"]
difference = endOfModificationId-lastIdOfSelectedCsOriginal
for modNr in csIdMax+1:length(energySavingModifications)
if energySavingModifications[modNr].ratio>0
@ -421,7 +421,7 @@ function updateEnergySavingModifications(energySavingModifications::Vector{Energ
drivingCourseModifiedNew[end].i=length(drivingCourseModifiedNew)
drivingCourseModifiedNew[end].t=drivingCourseModifiedNew[end-1].t+drivingCourseModifiedNew[end].Δt
drivingCourseModifiedNew[end].E=drivingCourseModifiedNew[end-1].E+drivingCourseModifiedNew[end].ΔE
drivingCourseModifiedNew[end].W_T=drivingCourseModifiedNew[end-1].W_T+drivingCourseModifiedNew[end].ΔW_T
drivingCourseModifiedNew[end].W=drivingCourseModifiedNew[end-1].W+drivingCourseModifiedNew[end].ΔW
i=i+1
end # while

View File

@ -48,16 +48,16 @@ function createOutputDict(settings::Settings, pathName::String, trainName::Strin
# creating an output array
outputArray=Array{Any, 1}[]
if settings.detailOfOutput=="reduced"
if settings.detailOfOutput=="minimal"
push!(outputArray, ["s_total (in m)", "t_total (in s)","E_total (in Ws)"]) # push header to outputArray
push!(outputArray, ["s (in m)", "t (in s)","E (in Ws)"]) # push header to outputArray
row=[movingSection.s_total, movingSection.t_total, movingSection.E_total]
row=[movingSection.length, movingSection.t, movingSection.E]
push!(outputArray, row) # push row to outputArray
elseif settings.detailOfOutput=="driving course"
push!(outputArray, ["i", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","F_Rp (in N)","F_Runion (in N)","F_Rt (in N)","F_Rw (in N)", "ΔW_T (in Ws)","W_T (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]) # push header to outputArray
push!(outputArray, ["i", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_consist (in N)", "ΔW (in Ws)","W (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]) # push header to outputArray
for point in drivingCourse
row=[point.i, point.Δs, point.s, point.Δt, point.t, point.Δv, point.v, point.F_T, point.F_R, point.F_Rp, point.F_Runion, point.F_Rt, point.F_Rw, point.ΔW_T, point.W_T, point.ΔE, point.E, point.a]
row=[point.i, point.Δs, point.s, point.Δt, point.t, point.Δv, point.v, point.F_T, point.F_R, point.R_path, point.R_train, point.R_traction, point.R_consist, point.ΔW, point.W, point.ΔE, point.E, point.a]
push!(outputArray, row) # push row to outputArray
end
end
@ -80,14 +80,14 @@ function createOutputDict(settings::Settings, pathName::String, trainName::Strin
if settings.operationModeMinimumEnergyConsumption
# creating the second output array
outputArrayMinimumEnergyConsumption=Array{Any, 1}[]
if settings.detailOfOutput=="reduced"
push!(outputArrayMinimumEnergyConsumption, ["s_total (in m)", "t_total (in s)","E_total (in Ws)"]) # push header to outputArrayMinimumEnergyConsumption
row=[movingSectionMinimumEnergyConsumption.s_total, movingSectionMinimumEnergyConsumption.t_total, movingSectionMinimumEnergyConsumption.E_total]
if settings.detailOfOutput=="minimal"
push!(outputArrayMinimumEnergyConsumption, ["s (in m)", "t (in s)","E (in Ws)"]) # push header to outputArrayMinimumEnergyConsumption
row=[movingSectionMinimumEnergyConsumption.length, movingSectionMinimumEnergyConsumption.t, movingSectionMinimumEnergyConsumption.E]
push!(outputArrayMinimumEnergyConsumption, row) # push row to outputArrayMinimumEnergyConsumption
elseif settings.detailOfOutput=="driving course"
push!(outputArrayMinimumEnergyConsumption, ["i", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","F_Rp (in N)","F_Runion (in N)","F_Rt (in N)","F_Rw (in N)", "ΔW_T (in Ws)","W_T (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]) # push header to outputArrayMinimumEnergyConsumption
push!(outputArrayMinimumEnergyConsumption, ["i", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_consist (in N)", "ΔW (in Ws)","W (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]) # push header to outputArrayMinimumEnergyConsumption
for point in drivingCourseMinimumEnergyConsumption
row=[point.i, point.Δs, point.s, point.Δt, point.t, point.Δv, point.v, point.F_T, point.F_R, point.F_Rp, point.F_Runion, point.F_Rt, point.F_Rw, point.ΔW_T, point.W_T, point.ΔE, point.E, point.a]
row=[point.i, point.Δs, point.s, point.Δt, point.t, point.Δv, point.v, point.F_T, point.F_R, point.R_path, point.R_train, point.R_traction, point.R_consist, point.ΔW, point.W, point.ΔE, point.E, point.a]
push!(outputArrayMinimumEnergyConsumption, row) # push row to outputArrayMinimumEnergyConsumption
end
end
@ -130,10 +130,10 @@ function createOutputCsv(settings::Settings, pathName::String, trainName::String
end # for
allColumns=Array{Any,1}[]
if settings.detailOfOutput=="reduced"
if settings.detailOfOutput=="minimal"
header=outputDict["outputArrayMinimumRunningTime"][1]
elseif settings.detailOfOutput=="driving course"
header=["i", "Delta s (in m)", "s (in m)", "Delta t (in s)","t (in s)","Delta v (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","F_Rp (in N)","F_Runion (in N)","F_Rt (in N)","F_Rw (in N)"," Delta W_T (in Ws)","W_T (in Ws)","Delta E (in Ws)","E (in Ws)","a (in m/s^2)"]
header=["i", "Delta s (in m)", "s (in m)", "Delta t (in s)","t (in s)","Delta v (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_consist (in N)"," Delta W (in Ws)","W (in Ws)","Delta E (in Ws)","E (in Ws)","a (in m/s^2)"]
end
for column in 1:length(outputDict[outputArray][1])
push!(infoColumns[column], header[column])
@ -145,7 +145,7 @@ function createOutputCsv(settings::Settings, pathName::String, trainName::String
# combining the columns in a data frame and saving it as a CSV-file at csvDirectory
if settings.detailOfOutput=="reduced"
if settings.detailOfOutput=="minimal"
df=DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3])
elseif settings.detailOfOutput=="driving course"
df=DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3], c4=allColumns[4], c5=allColumns[5], c6=allColumns[6], c7=allColumns[7], c8=allColumns[8], c9=allColumns[9], c10=allColumns[10], c11=allColumns[11], c12=allColumns[12], c13=allColumns[13], c14=allColumns[14], c15=allColumns[15], c16=allColumns[16], c17=allColumns[17], c18=allColumns[18])
@ -173,10 +173,10 @@ function createOutputCsv(settings::Settings, pathName::String, trainName::String
end # for
allColumns=Array{Any,1}[]
if settings.detailOfOutput=="reduced"
if settings.detailOfOutput=="minimal"
header=outputDict["outputArrayMinimumRunningTime"][1]
elseif settings.detailOfOutput=="driving course"
header=["i", "Delta s (in m)", "s (in m)", "Delta t (in s)","t (in s)","Delta v (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","F_Rp (in N)","F_Runion (in N)","F_Rt (in N)","F_Rw (in N)"," Delta W_T (in Ws)","W_T (in Ws)","Delta E (in Ws)","E (in Ws)","a (in m/s^2)"]
header=["i", "Delta s (in m)", "s (in m)", "Delta t (in s)","t (in s)","Delta v (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_consist (in N)"," Delta W (in Ws)","W (in Ws)","Delta E (in Ws)","E (in Ws)","a (in m/s^2)"]
end
for column in 1:length(outputDict["outputArrayMinimumRunningTime"][1])
@ -188,7 +188,7 @@ function createOutputCsv(settings::Settings, pathName::String, trainName::String
end # for
#combining the columns in a data frame and saving it as a CSV-file at csvDirectory
if settings.detailOfOutput=="reduced"
if settings.detailOfOutput=="minimal"
df=DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3])
elseif settings.detailOfOutput=="driving course"
df=DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3], c4=allColumns[4], c5=allColumns[5], c6=allColumns[6], c7=allColumns[7], c8=allColumns[8], c9=allColumns[9], c10=allColumns[10], c11=allColumns[11], c12=allColumns[12], c13=allColumns[13], c14=allColumns[14], c15=allColumns[15], c16=allColumns[16], c17=allColumns[17], c18=allColumns[18])
@ -211,10 +211,10 @@ function createOutputCsv(settings::Settings, pathName::String, trainName::String
end # for
allColumns=Array{Any,1}[]
if settings.detailOfOutput=="reduced"
if settings.detailOfOutput=="minimal"
header=outputDict["outputArrayMinimumRunningTime"][1]
elseif settings.detailOfOutput=="driving course"
header=["i", "Delta s (in m)", "s (in m)", "Delta t (in s)","t (in s)","Delta v (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","F_Rp (in N)","F_Runion (in N)","F_Rt (in N)","F_Rw (in N)"," Delta W_T (in Ws)","W_T (in Ws)","Delta E (in Ws)","E (in Ws)","a (in m/s^2)"]
header=["i", "Delta s (in m)", "s (in m)", "Delta t (in s)","t (in s)","Delta v (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_consist (in N)"," Delta W (in Ws)","W (in Ws)","Delta E (in Ws)","E (in Ws)","a (in m/s^2)"]
end
for column in 1:length(outputDict["outputArrayMinimumEnergyConsumption"][1])
@ -226,7 +226,7 @@ function createOutputCsv(settings::Settings, pathName::String, trainName::String
end # for
#combining the columns in a data frame
if settings.detailOfOutput=="reduced"
if settings.detailOfOutput=="minimal"
df=DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3])
elseif settings.detailOfOutput=="driving course"
df=DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3], c4=allColumns[4], c5=allColumns[5], c6=allColumns[6], c7=allColumns[7], c8=allColumns[8], c9=allColumns[9], c10=allColumns[10], c11=allColumns[11], c12=allColumns[12], c13=allColumns[13], c14=allColumns[14], c15=allColumns[15], c16=allColumns[16], c17=allColumns[17], c18=allColumns[18])
@ -254,13 +254,13 @@ function printImportantValues(drivingCourse::Vector{DataPoint})
end #function printImportantValues
function printSectionInformation(movingSection::MovingSection)
println("MS mit s_total=", movingSection.s_total," mit t_total=", movingSection.t_total)
allBs=["starting", "cruisingBeforeAcceleration","acceleration", "cruising", "diminishing", "coasting","cruisingAfterCoasting", "braking"]
println("MS mit length=", movingSection.length," mit t=", movingSection.t)
allBs=["breakFree", "clearing", "acceleration", "cruising", "diminishing", "coasting","cruisingAfterCoasting", "braking", "standStill"]
for csId in 1:length(movingSection.characteristicSections)
println("CS ",csId," mit s_total=", movingSection.characteristicSections[csId].s_total," mit t_total=", movingSection.characteristicSections[csId].t_total)
println("CS ",csId," mit length=", movingSection.characteristicSections[csId].length," mit t=", movingSection.characteristicSections[csId].t)
for bs in 1: length(allBs)
if haskey(movingSection.characteristicSections[csId].behaviorSections, allBs[bs])
println("BS ",allBs[bs], " mit s_start=",get(movingSection.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).s_start, " und t_total=",get(movingSection.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).t_total)
println("BS ",allBs[bs], " mit s_entry=",get(movingSection.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).s_entry, " und t=",get(movingSection.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).t)
# for point in 1:length(get(movingSection.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).dataPoints)
# println(get(movingSection.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).dataPoints[point])
# end

View File

@ -21,14 +21,14 @@ function createMovingSection(path::Path, v_trainLimit::AbstractFloat)
movingSection=MovingSection()
movingSection.id=1 # identifier # if there is more than one moving section in a later version of this tool the id should not be constant anymore
movingSection.t_total=0.0 # total running time (in s)
movingSection.E_total=0.0 # total energy consumption (in Ws)
movingSection.t=0.0 # total running time (in s)
movingSection.E=0.0 # total energy consumption (in Ws)
movingSection.s_start=path.sections[1].s_start # first position (in m)
movingSection.s_end=path.sections[length(path.sections)].s_startNext # last position (in m)
movingSection.s_total=movingSection.s_end-movingSection.s_start # total length (in m)
movingSection.s_entry=path.sections[1].s_start # first position (in m)
movingSection.s_exit=path.sections[length(path.sections)].s_end # last position (in m)
movingSection.length=movingSection.s_exit-movingSection.s_entry # total length (in m)
s_csStart=movingSection.s_start
s_csStart=movingSection.s_entry
csId=1
for row in 2:length(path.sections)
if min(path.sections[row-1].v_limit, v_trainLimit) != min(path.sections[row].v_limit, v_trainLimit) || path.sections[row-1].f_Rp != path.sections[row].f_Rp
@ -48,15 +48,15 @@ function createCharacteristicSection(csId::Integer, s_csStart::AbstractFloat, se
# this function creates and returns a characteristic section dependent on the paths attributes
characteristicSection=CharacteristicSection()
characteristicSection.id=csId # identifier
characteristicSection.s_start=s_csStart # first position (in m)
characteristicSection.s_end=section.s_startNext # last position (in m)
characteristicSection.s_total=characteristicSection.s_end-characteristicSection.s_start # total length (in m)
characteristicSection.t_total=0.0 # total running time (in s)
characteristicSection.E_total=0.0 # total energy consumption (in Ws)
characteristicSection.s_entry=s_csStart # first position (in m)
characteristicSection.s_exit=section.s_end # last position (in m)
characteristicSection.length=characteristicSection.s_exit-characteristicSection.s_entry # total length (in m)
characteristicSection.t=0.0 # total running time (in s)
characteristicSection.E=0.0 # total energy consumption (in Ws)
characteristicSection.v_limit=v_csLimit # speed limit (in m/s)
# initializing v_entry, v_reach and v_exit with v_limit
characteristicSection.v_reach=characteristicSection.v_limit # maximum reachable speed (in m/s)
# initializing v_entry, v_target and v_exit with v_limit
characteristicSection.v_target=characteristicSection.v_limit # maximum target speed (in m/s)
characteristicSection.v_entry=characteristicSection.v_limit # maximum entry speed (in m/s)
characteristicSection.v_exit=characteristicSection.v_limit # maximum exit speed (in m/s)
@ -71,11 +71,11 @@ function secureBrakingBehavior!(movingSection::MovingSection, a_braking::Abstrac
csId=length(movingSection.characteristicSections)
movingSection.characteristicSections[csId].v_exit=0.0 # the exit velocity of the last characteristic section is 0.0 m/s
while csId >= 1
v_entryMax=sqrt(movingSection.characteristicSections[csId].v_exit^2-2*a_braking*movingSection.characteristicSections[csId].s_total)
v_entryMax=sqrt(movingSection.characteristicSections[csId].v_exit^2-2*a_braking*movingSection.characteristicSections[csId].length)
v_entryMax=floor(v_entryMax, digits=12)
movingSection.characteristicSections[csId].v_entry=min(movingSection.characteristicSections[csId].v_limit, v_entryMax)
movingSection.characteristicSections[csId].v_reach=movingSection.characteristicSections[csId].v_entry
movingSection.characteristicSections[csId].v_target=movingSection.characteristicSections[csId].v_entry
csId=csId-1
if csId >= 1
movingSection.characteristicSections[csId].v_exit=min(movingSection.characteristicSections[csId].v_limit, movingSection.characteristicSections[csId+1].v_entry)
@ -95,16 +95,16 @@ function secureAccelerationBehavior!(movingSection::MovingSection, settings::Set
for csId in 1:length(movingSection.characteristicSections)
movingSection.characteristicSections[csId].v_entry=min(movingSection.characteristicSections[csId].v_entry, previousCSv_exit)
startingPoint.s=movingSection.characteristicSections[csId].s_start
startingPoint.s=movingSection.characteristicSections[csId].s_entry
startingPoint.v=movingSection.characteristicSections[csId].v_entry
accelerationCourse=[startingPoint] # List of data points
if movingSection.characteristicSections[csId].v_entry<movingSection.characteristicSections[csId].v_reach
if movingSection.characteristicSections[csId].v_entry<movingSection.characteristicSections[csId].v_target
(movingSection.characteristicSections[csId], accelerationCourse)=addAccelerationPhase!(movingSection.characteristicSections[csId], accelerationCourse, settings, train, movingSection.characteristicSections) # this function changes the accelerationCourse
movingSection.characteristicSections[csId].v_reach=max(movingSection.characteristicSections[csId].v_entry,accelerationCourse[end].v)
movingSection.characteristicSections[csId].v_target=max(movingSection.characteristicSections[csId].v_entry,accelerationCourse[end].v)
movingSection.characteristicSections[csId].v_exit=min(movingSection.characteristicSections[csId].v_exit, movingSection.characteristicSections[csId].v_reach, accelerationCourse[end].v)
else #movingSection.characteristicSections[csId].v_entry==movingSection.characteristicSections[csId].v_reach
movingSection.characteristicSections[csId].v_exit=min(movingSection.characteristicSections[csId].v_exit, movingSection.characteristicSections[csId].v_target, accelerationCourse[end].v)
else #movingSection.characteristicSections[csId].v_entry==movingSection.characteristicSections[csId].v_target
# v_exit stays the same
end #if
@ -118,7 +118,7 @@ end #function secureAccelerationBehavior!
## define the intersection velocities between the characterisitc sections to secure cruising behavior
function secureCruisingBehavior!(movingSection::MovingSection, settings::Settings, train::Train)
# limit the exit velocity of the characteristic sections in case that the train cruises in every section at v_reach
# limit the exit velocity of the characteristic sections in case that the train cruises in every section at v_target
startingPoint=DataPoint()
startingPoint.i=1
@ -127,11 +127,11 @@ function secureCruisingBehavior!(movingSection::MovingSection, settings::Setting
for csId in 1:length(movingSection.characteristicSections)
movingSection.characteristicSections[csId].v_entry=min(movingSection.characteristicSections[csId].v_entry, previousCSv_exit)
startingPoint.s=movingSection.characteristicSections[csId].s_start
startingPoint.v=movingSection.characteristicSections[csId].v_reach
startingPoint.s=movingSection.characteristicSections[csId].s_entry
startingPoint.v=movingSection.characteristicSections[csId].v_target
cruisingCourse=[startingPoint] # List of data points
(movingSection.characteristicSections[csId], cruisingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], cruisingCourse, movingSection.characteristicSections[csId].s_total, settings, train, movingSection.characteristicSections, "cruising") # this function changes the cruisingCourse
(movingSection.characteristicSections[csId], cruisingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], cruisingCourse, movingSection.characteristicSections[csId].length, settings, train, movingSection.characteristicSections, "cruising") # this function changes the cruisingCourse
movingSection.characteristicSections[csId].v_exit=min(movingSection.characteristicSections[csId].v_exit, cruisingCourse[end].v)
previousCSv_exit=movingSection.characteristicSections[csId].v_exit
@ -141,60 +141,3 @@ function secureCruisingBehavior!(movingSection::MovingSection, settings::Setting
end #function secureCruisingBehavior!
end #module Preparation
#= 22.06.2021: acceleration an cruising behavior seperated in two functions
## define the intersection velocities between the characterisitc sections to secure acceleration behavior
function secureAccelerationBehavior!(movingSection::MovingSection, settings::Settings, train::Train)
# this function limits the entry and exit velocity of the characteristic sections in case that the train accelerates in every section and cruises aterwards
movingSection.characteristicSections[1].v_entry=0.0 # the entry velocity of the first characteristic section is 0.0 m/s
startingPoint=DataPoint()
startingPoint.i=1
previousCSv_exit=0.0
for csId in 1:length(movingSection.characteristicSections)
movingSection.characteristicSections[csId].v_entry=min(movingSection.characteristicSections[csId].v_entry, previousCSv_exit)
startingPoint.s=movingSection.characteristicSections[csId].s_start
startingPoint.v=movingSection.characteristicSections[csId].v_entry
cruisingCourse=[startingPoint] # List of data points
if movingSection.characteristicSections[csId].v_entry<movingSection.characteristicSections[csId].v_reach
(movingSection.characteristicSections[csId], accelerationCourse)=addAccelerationPhase!(movingSection.characteristicSections[csId], accelerationCourse, settings, train, movingSection.characteristicSections) # this function changes the accelerationCourse
movingSection.characteristicSections[csId].v_reach=accelerationCourse[end].v
movingSection.characteristicSections[csId].v_exit=min(movingSection.characteristicSections[csId].v_exit, movingSection.characteristicSections[csId].v_reach)
if settings.stepVariable=="v in m/s" # with the new v_reach the calculation will be different a second time. Therefore the CS has to be calculated again for velocity step method to refresh the length of the acceleration section for further simulation
delete!(movingSection.characteristicSections[csId].behaviorSections, "starting")
delete!(movingSection.characteristicSections[csId].behaviorSections, "cruisingBeforeAcceleration")
delete!(movingSection.characteristicSections[csId].behaviorSections, "acceleration")
movingSection.characteristicSections[csId].E_total=0.0
movingSection.characteristicSections[csId].t_total=0.0
accelerationCourse=[startingPoint] # List of data points
(movingSection.characteristicSections[csId], accelerationCourse)=addAccelerationPhase!(movingSection.characteristicSections[csId], accelerationCourse, settings, train, movingSection.characteristicSections) # this function changes the accelerationCourse
end
else #movingSection.characteristicSections[csId].v_entry==movingSection.characteristicSections[csId].v_reach
# v_exit stays the same
end #if
# securing cruising behavior
# is need if the path resistance is too high, the train can not cruise at v_reach and is getting slower
s_cruisingMax=movingSection.characteristicSections[csId].s_end-accelerationCourse[end].s
if s_cruisingMax>0.0
(movingSection.characteristicSections[csId], accelerationCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], accelerationCourse, s_cruisingMax, settings, train, movingSection.characteristicSections, "cruising")
movingSection.characteristicSections[csId].v_exit=min(movingSection.characteristicSections[csId].v_exit, accelerationCourse[end].v)
end
previousCSv_exit=movingSection.characteristicSections[csId].v_exit
# println("CS",csId,": s_start: ",movingSection.characteristicSections[csId].s_start," v_entry: ", round(movingSection.characteristicSections[csId].v_entry*3.6, digits=5), ", v_reach: ", round(movingSection.characteristicSections[csId].v_reach*3.6, digits=5), " v_exit: ", round(movingSection.characteristicSections[csId].v_exit*3.6, digits=5))
end #for
return movingSection
end #function secureAccelerationBehavior!
=#

View File

@ -42,8 +42,8 @@ function calculateDrivingDynamics(trainDirectory::String, pathDirectory::String,
println("The moving section has been prepared.")
if settings.operationModeMinimumRunningTime==true || settings.operationModeMinimumEnergyConsumption==true
(movingSectionMinimumRunningTime, drivingCourseMinimumRunningTime)=simulateMinimumRunningTime!(movingSection, settings, train)
# println("t_total=", drivingCourseMinimumRunningTime[end].t)
(movingSectionMinimumRunningTime, drivingCourseMinimumRunningTime)=calculateMinimumRunningTime!(movingSection, settings, train)
# println("t=", drivingCourseMinimumRunningTime[end].t)
# printSectionInformation(movingSectionMinimumRunningTime)
println("The driving course for the shortest running time has been calculated.")
end #if
@ -51,7 +51,7 @@ function calculateDrivingDynamics(trainDirectory::String, pathDirectory::String,
# oparation mode "minimum energy consumption"
if settings.operationModeMinimumEnergyConsumption==true
(movingSectionMinimumEnergyConsumption, drivingCourseMinimumEnergyConsumption)=simulateMinimumEnergyConsumption(movingSectionMinimumRunningTime, drivingCourseMinimumRunningTime, settings, train)
(movingSectionMinimumEnergyConsumption, drivingCourseMinimumEnergyConsumption)=calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime, drivingCourseMinimumRunningTime, settings, train)
# printSectionInformation(movingSectionMinimumEnergyConsumption)
println("The driving course for the lowest energy consumption has been calculated.")
end #if

View File

@ -2,17 +2,18 @@ module types
# definition of all the additional types and their constructors
export Settings, Train, PathSection, Path, DataPoint, BehaviorSection, CharacteristicSection, EnergySavingModification, MovingSection # tried to insert copy on 15.07.2021 , copy
## settings for the simulation
## settings for the calculation
mutable struct Settings
massModel::String # model type of the unions mass "mass point" or "homogeneous strip"
massModel::String # model type of the trains mass "mass point" or "homogeneous strip"
stepVariable::String # step variable of the step method "s in m", "t in s" or "v in m/s"
stepSize::AbstractFloat # step size (unit depends on steapVariable s in m, t in s and v in m/s)
stepSize::AbstractFloat # step size (unit depends on steapVariable s in m, t in s and v in m/s)
operationModeMinimumRunningTime::Bool # operation mode "minimum running time"
operationModeMinimumEnergyConsumption::Bool # operation mode "minimum energy consumption"
# output:
typeOfOutput::String # output as "julia dictionary" or as "CSV"
csvDirectory::String # directory in which the CSV files will be saved
detailOfOutput::String # detail of output "reduced" or "everything"
detailOfOutput::String # detail of output "minimal" or "driving course"
end # mutable struct Settings
Settings()=Settings("", "", 0.0, false, false, "", "", "")
@ -21,34 +22,32 @@ Settings()=Settings("", "", 0.0, false, false, "", "", "")
mutable struct Train
name::String # trains name
id # trains identifier
trainType::String # type of train "passenger" or "freight" or "motor coach train"
l_union::AbstractFloat # total length (in m)
trainType::String # type of train "passenger" or "freight" or "motor coach train"
l_train::AbstractFloat # total length (in m)
v_limit::AbstractFloat # trains speed limit (in m/s)
a_braking::AbstractFloat # braking acceleration (in m/s^2)
m_union::AbstractFloat # total mass (in kg)
# m_train
ξ_union::AbstractFloat # rotation mass factor of the whole train union (without unit)
m_train::AbstractFloat # total mass (in kg)
ξ_train::AbstractFloat # rotation mass factor of the whole train (without unit)
# if not available use ξ_t and ξ_w
# ξ_train
# traction unit
m_t::AbstractFloat # mass of the traction unit (in kg)
m_td::AbstractFloat # mass on the traction units driving axles (in kg)
m_tc::AbstractFloat # mass on the traction units carrying axles (in kg)
ξ_t::AbstractFloat # rotation mass factor of the traction unit (without unit)
# in case ξ_union is not available
# in case ξ_train is not available
tractiveEffortVelocityPairs # list of velocities and their corresponding tractive effort (in [m/s , N])
f_Rtd0::AbstractFloat # coefficient for basic resistance due to the traction units driving axles (in ‰)
f_Rtc0::AbstractFloat # coefficient for basic resistance due to the traction units carring axles (in ‰)
F_Rt2::AbstractFloat #todo: war mal:forceRT2 # coefficient for air resistance of the traction units (in N)
F_Rt2::AbstractFloat # coefficient for air resistance of the traction units (in N)
Δv_t::AbstractFloat # coefficient for velocitiy difference between traction unit and outdoor air
# set of wagons
m_w::AbstractFloat # mass of the set of wagons (in kg)
ξ_w::AbstractFloat # rotation mass factor of the set of wagons (without unit)
# in case ξ_union is not available
# in case ξ_train is not available
f_Rw0::AbstractFloat # coefficient for basic resistance of the set of wagons (in ‰)
f_Rw1::AbstractFloat # coefficient for resistance to rolling of the set of wagons (in ‰)
f_Rw2::AbstractFloat # coefficient for air resistance of the set of wagons (in ‰)
@ -60,22 +59,18 @@ Train()=Train("", 0, "", 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, [], 0.0, 0
## path separated in smaler sections
struct PathSection
s_start::AbstractFloat # starting point of the section (in m)
s_startNext::AbstractFloat # starting point of the next section (in m)
s_end::AbstractFloat # starting point of the next section (in m)
v_limit::AbstractFloat # paths speed limt (in m/s)
n::AbstractFloat # gradient (in ‰)
# TODO: curve radius
# TODO: turnout
# TODO: tunnel
f_Rp::AbstractFloat # specific path resistance of the section (in ‰)
end # struct pathSection
PathSection()=(0.0, 0.0, 0.0, 0.0, 0.0)
PathSection()=(0.0, 0.0, 0.0, 0.0)
struct Path
name::String # paths name
id # paths identifier
sections::Vector{PathSection} # list of PathSection elements
# s_start in firt entry defines the paths beginning
# s_startNext in last entry defines the paths ending
# s_start in first entry defines the path's beginning
# s_end in last entry defines the path's ending
end # struct Path
Path()=("", 0, Vector{PathSection}())
@ -90,42 +85,35 @@ mutable struct DataPoint
v::AbstractFloat # velocity (in m/s)
Δv::AbstractFloat # step size (in m/s)
a::AbstractFloat # acceleration (in m/s^2)
W_T::AbstractFloat # mechanical work (in Ws)
# W
ΔW_T::AbstractFloat # mechanical work in this step (in Ws)
# ΔW
W::AbstractFloat # mechanical work (in Ws)
ΔW::AbstractFloat # mechanical work in this step (in Ws)
E::AbstractFloat # energy consumption (in Ws)
ΔE::AbstractFloat # energy consumption in this step (in Ws)
F_T::AbstractFloat # tractive effort (in N)
F_R::AbstractFloat # resisting force (in N)
F_Rp::AbstractFloat # path resistance (in N)
# R_path
F_Runion::AbstractFloat # train resistance (in N)
# R_train
F_Rt::AbstractFloat # traction unit resistance (in N)
# R_traction
F_Rw::AbstractFloat # set of wagons resistance (in N)
# R_consist
R_path::AbstractFloat # path resistance (in N)
R_train::AbstractFloat # train resistance (in N)
R_traction::AbstractFloat # traction unit resistance (in N)
R_consist::AbstractFloat # set of wagons resistance (in N)
end # mutable struct DataPoint
DataPoint()=DataPoint(0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
# tried to insert copy on 15.07.2021 copy(original::DataPoint)=DataPoint(original.i, original.s, original.Δs, original.t, original.Δt, original.v, original.Δv, original.a, original.W_T, original.ΔW_T, original.E, original.ΔE, original.F_T, original.F_R, original.F_Rp, original.F_Runion, original.F_Rt, original.F_Rw)
DataPoint(original::DataPoint)=DataPoint(original.i, original.s, original.Δs, original.t, original.Δt, original.v, original.Δv, original.a, original.W_T, original.ΔW_T, original.E, original.ΔE, original.F_T, original.F_R, original.F_Rp, original.F_Runion, original.F_Rt, original.F_Rw)
# tried to insert copy on 15.07.2021 copy(original::DataPoint)=DataPoint(original.i, original.s, original.Δs, original.t, original.Δt, original.v, original.Δv, original.a, original.W, original.ΔW, original.E, original.ΔE, original.F_T, original.F_R, original.R_path, original.R_train, original.R_traction, original.R_consist)
DataPoint(original::DataPoint)=DataPoint(original.i, original.s, original.Δs, original.t, original.Δt, original.v, original.Δv, original.a, original.W, original.ΔW, original.E, original.ΔE, original.F_T, original.F_R, original.R_path, original.R_train, original.R_traction, original.R_consist)
## different sections the whole path can be devided in the following
## smallest section of the path is the behavior section. It relates to the containing data points via their identifier.
mutable struct BehaviorSection
type::String # type of behavior section: "starting", "cruisingBeforeAcceleration", "acceleration", "cruising", "coasting", "cruisingAfterCoasting" or "braking"
# enum-type. breakFree, clearing, diminishing, standStill, "acceleration", "cruising", "coasting", "braking"
s_total::AbstractFloat # total length (in m)
s_start::AbstractFloat # first position (in m)
s_end::AbstractFloat # last position (in m)
t_total::AbstractFloat # total running time (in s)
E_total::AbstractFloat # total energy consumption (in Ws)
type::String # type of behavior section: "breakFree", "clearing", "acceleration", "cruising", "diminishing", "coasting", "cruisingAfterCoasting","braking" or "standStill"
length::AbstractFloat # total length (in m)
s_entry::AbstractFloat # first position (in m)
s_exit::AbstractFloat # last position (in m)
t::AbstractFloat # total running time (in s)
E::AbstractFloat # total energy consumption (in Ws)
v_entry::AbstractFloat # entry speed (in m/s)
v_exit::AbstractFloat # exit speed (in m/s)
dataPoints::Vector{Integer} # list of identifiers of the containing data points
dataPoints::Vector{Integer} # list of identifiers of the containing data points
end # mutable struct BehaviorSection
BehaviorSection()=BehaviorSection("", 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, [])
function BehaviorSection(original::BehaviorSection)
@ -133,25 +121,19 @@ function BehaviorSection(original::BehaviorSection)
for i in 1:length(original.dataPoints)
push!(bsDataPoints, original.dataPoints[i])
end
return BehaviorSection(original.type, original.s_total, original.s_start, original.s_end, original.t_total, original.E_total, original.v_entry, original.v_exit, bsDataPoints)
return BehaviorSection(original.type, original.length, original.s_entry, original.s_exit, original.t, original.E, original.v_entry, original.v_exit, bsDataPoints)
end
## a characteristic section is a part of the moving section. It contains behavior sections.
mutable struct CharacteristicSection
id::Integer # identifier
s_total::AbstractFloat # total length (in m)
# length::AbstractFloat # total length (in m)
s_start::AbstractFloat # first position (in m)
# s_entry
s_end::AbstractFloat # last position (in m)
# s_exit
t_total::AbstractFloat # total running time (in s)
# t
E_total::AbstractFloat # total energy consumption (in Ws)
# E
length::AbstractFloat # total length (in m)
s_entry::AbstractFloat # first position (in m)
s_exit::AbstractFloat # last position (in m)
t::AbstractFloat # total running time (in s)
E::AbstractFloat # total energy consumption (in Ws)
v_limit::AbstractFloat # speed limit (in m/s)
v_reach::AbstractFloat # maximum reachable speed (in m/s)
# v_target
v_target::AbstractFloat # maximum target speed (in m/s)
v_entry::AbstractFloat # maximum entry speed (in m/s)
v_exit::AbstractFloat # maximum exit speed (in m/s)
f_Rp::AbstractFloat # spedific path resistance (in ‰)
@ -159,8 +141,8 @@ mutable struct CharacteristicSection
end # mutable struct CharacteristicSection
CharacteristicSection()=CharacteristicSection(0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Dict{String, BehaviorSection}())
function CharacteristicSection(original::CharacteristicSection)
copy=CharacteristicSection(original.id, original.s_total, original.s_start, original.s_end, original.t_total, original.E_total, original.v_limit, original.v_reach, original.v_entry, original.v_exit, original.f_Rp, Dict{String, BehaviorSection}())
allBs=["starting", "cruisingBeforeAcceleration","acceleration", "cruising", "coasting","cruisingAfterCoasting", "braking"]
copy=CharacteristicSection(original.id, original.length, original.s_entry, original.s_exit, original.t, original.E, original.v_limit, original.v_target, original.v_entry, original.v_exit, original.f_Rp, Dict{String, BehaviorSection}())
allBs=["breakFree", "clearing", "acceleration", "cruising", "diminishing", "coasting", "cruisingAfterCoasting", "braking", "standStill"]
for bs in 1: length(allBs)
if haskey(original.behaviorSections, allBs[bs])
merge!(copy.behaviorSections, Dict(allBs[bs]=>BehaviorSection(get(original.behaviorSections, allBs[bs], BehaviorSection()))))
@ -177,7 +159,7 @@ mutable struct EnergySavingModification
Δt::AbstractFloat # time loss (in s)
ratio::AbstractFloat # ratio of ΔE and Δt (in Ws/s)
csModified::CharacteristicSection # the modified characteristic section
drivingCourseModified::Vector{DataPoint} #drivingCourse for the modified characteristic section
drivingCourseModified::Vector{DataPoint} # drivingCourse for the modified characteristic section
end # mutable struct EnergySavingModification
EnergySavingModification()=EnergySavingModification(0, "", 0.0, 0.0, 0.0, CharacteristicSection(), [])
function EnergySavingModification(original::EnergySavingModification)
@ -193,11 +175,11 @@ end #function EnergySavingModification
## a moving section contains all the smaller sections from one stop to an other
mutable struct MovingSection
id # identifier
s_total::AbstractFloat # total length (in m)
s_start::AbstractFloat # first position (in m)
s_end::AbstractFloat # last position (in m)
t_total::AbstractFloat # total running time (in s)
E_total::AbstractFloat # total energy consumption (in Ws)
length::AbstractFloat # total length (in m)
s_entry::AbstractFloat # first position (in m)
s_exit::AbstractFloat # last position (in m)
t::AbstractFloat # total running time (in s)
E::AbstractFloat # total energy consumption (in Ws)
t_recovery::AbstractFloat # total recovery time for energy-saving modifications (in s)
t_recoveryAvailable::AbstractFloat # still available recovery time for energy-saving modifications (in s)
characteristicSections::Vector{CharacteristicSection} # list of containing characteristic sections
@ -206,7 +188,7 @@ end # mutable struct MovingSection
MovingSection()=MovingSection(0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, [], [])
function MovingSection(original::MovingSection)
copy=MovingSection(original.id, original.s_total, original.s_start, original.s_end, original.t_total, original.E_total, original.t_recovery, original.t_recoveryAvailable, [], [])
copy=MovingSection(original.id, original.length, original.s_entry, original.s_exit, original.t, original.E, original.t_recovery, original.t_recoveryAvailable, [], [])
for csId in 1:length(original.characteristicSections)
push!(copy.characteristicSections, CharacteristicSection(original.characteristicSections[csId]))
end #for