diff --git a/Project.toml b/Project.toml index 91c0ae2..f8b7267 100644 --- a/Project.toml +++ b/Project.toml @@ -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" diff --git a/README.md b/README.md index 0c18e03..8844c61 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/data/paths/path_1_10km_nConst_vConst.yaml b/data/paths/path_1_10km_nConst_vConst.yaml index 25a1516..15dc56a 100644 --- a/data/paths/path_1_10km_nConst_vConst.yaml +++ b/data/paths/path_1_10km_nConst_vConst.yaml @@ -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] diff --git a/data/paths/path_2_10km_nVar_vConst.yaml b/data/paths/path_2_10km_nVar_vConst.yaml index a5b77ed..35a5271 100644 --- a/data/paths/path_2_10km_nVar_vConst.yaml +++ b/data/paths/path_2_10km_nVar_vConst.yaml @@ -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] diff --git a/data/paths/path_3_10km_nConst_vVar.yaml b/data/paths/path_3_10km_nConst_vVar.yaml index 6e8c29f..6a9e670 100644 --- a/data/paths/path_3_10km_nConst_vVar.yaml +++ b/data/paths/path_3_10km_nConst_vVar.yaml @@ -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] diff --git a/data/paths/path_4_real_Germany_EastSaxony_DG-DN.yaml b/data/paths/path_4_real_Germany_EastSaxony_DG-DN.yaml index c5196a2..aa5cf35 100644 --- a/data/paths/path_4_real_Germany_EastSaxony_DG-DN.yaml +++ b/data/paths/path_4_real_Germany_EastSaxony_DG-DN.yaml @@ -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] diff --git a/data/settings.yaml b/data/settings.yaml index b64c490..ba0b159 100644 --- a/data/settings.yaml +++ b/data/settings.yaml @@ -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" diff --git a/data/trains/train_freight_V90withOreConsist.yaml b/data/trains/train_freight_V90withOreConsist.yaml index 5857095..b2e1ee9 100644 --- a/data/trains/train_freight_V90withOreConsist.yaml +++ b/data/trains/train_freight_V90withOreConsist.yaml @@ -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) diff --git a/data/trains/train_passenger_IC2.yaml b/data/trains/train_passenger_IC2.yaml index 516efbc..929643f 100644 --- a/data/trains/train_passenger_IC2.yaml +++ b/data/trains/train_passenger_IC2.yaml @@ -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) diff --git a/data/trains/train_passenger_SiemensDesiroClassic.yaml b/data/trains/train_passenger_SiemensDesiroClassic.yaml index f755adb..a233ded 100644 --- a/data/trains/train_passenger_SiemensDesiroClassic.yaml +++ b/data/trains/train_passenger_SiemensDesiroClassic.yaml @@ -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) diff --git a/src/EnergySaving.jl b/src/EnergySaving.jl index 7bfc6bc..26f0da7 100644 --- a/src/EnergySaving.jl +++ b/src/EnergySaving.jl @@ -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 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 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 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 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].s0.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].s0.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 (Δt0.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 diff --git a/src/Input.jl b/src/Input.jl index 2b9e41e..054d49f 100644 --- a/src/Input.jl +++ b/src/Input.jl @@ -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") diff --git a/src/MovingPhases.jl b/src/MovingPhases.jl index 96e4867..f3a509a 100644 --- a/src/MovingPhases.jl +++ b/src/MovingPhases.jl @@ -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 s0 && s-train.l_union0 && s-train.l_train| @@ -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].sstartingSection)) - 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 drivingCourse[end].F_R + #11/23 old without F_T > F_R: if drivingCourse[end].v < characteristicSection.v_target && drivingCourse[end].s 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 drivingCourse[end].F_R - # 12/03 old with v>0.0: while drivingCourse[end].v0.0 && drivingCourse[end].F_T > drivingCourse[end].F_R + while drivingCourse[end].v drivingCourse[end].F_R + # 12/03 old with v>0.0: while drivingCourse[end].v0.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 vcharacteristicSection.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 drivingCourse[end].F_R + # 11/23 old without F_T>F_R: if drivingCourse[end].v < characteristicSection.v_target && drivingCourse[end].s 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 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_braking0.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 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_braking0.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 vcharacteristicSection.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= drivingCourse[end].F_R - # 11/22 old: if drivingCourse[end].v>0.0 && drivingCourse[end].v<=characteristicSection.v_reach && drivingCourse[end].s0.0 && drivingCourse[end].v<=characteristicSection.v_target && drivingCourse[end].s= drivingCourse[end].F_R + # 11/22 old: if drivingCourse[end].v>0.0 && drivingCourse[end].v<=characteristicSection.v_target && drivingCourse[end].s 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=drivingCourse[end].F_R #&& drivingCourse[end].v<=characteristicSection.v_reach && drivingCourse[end].s=drivingCourse[end].F_R #&& drivingCourse[end].v<=characteristicSection.v_reach && drivingCourse[end].s=drivingCourse[end].F_R #&& drivingCourse[end].v<=characteristicSection.v_target && drivingCourse[end].s=drivingCourse[end].F_R #&& drivingCourse[end].v<=characteristicSection.v_target && drivingCourse[end].scruisingSection.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= drivingCourse[end].F_R + # if drivingCourse[end].s= 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].scharacteristicSection.v_exit && drivingCourse[end].scharacteristicSection.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 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].scharacteristicSection.v_exit && drivingCourse[end].sbrakingSection)) 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.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].s0.0 && drivingCourse[end].v<=characteristicSection.v_reach && drivingCourse[end].s 0.0 && drivingCourse[end].s0.0 && drivingCourse[end].v<=characteristicSection.v_target && drivingCourse[end].s0.0 # as long as s_i + s_braking < s_CSend - # 11/22 old without F_T<=F_R while drivingCourse[end].s+s_braking0.0 # as long as s_i + s_braking < s_CSend + while drivingCourse[end].F_T <= drivingCourse[end].F_R && drivingCourse[end].s+s_braking0.0 # as long as s_i + s_braking < s_CSend + # 11/22 old without F_T<=F_R while drivingCourse[end].s+s_braking0.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_braking0.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_braking0.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 diff --git a/src/OperationModes.jl b/src/OperationModes.jl index 565218f..cc8783f 100644 --- a/src/OperationModes.jl +++ b/src/OperationModes.jl @@ -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 diff --git a/src/Output.jl b/src/Output.jl index a9878d4..491ea89 100644 --- a/src/Output.jl +++ b/src/Output.jl @@ -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 diff --git a/src/Preparation.jl b/src/Preparation.jl index fa3342a..6f5db28 100644 --- a/src/Preparation.jl +++ b/src/Preparation.jl @@ -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_entry0.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! -=# diff --git a/src/TrainRun.jl b/src/TrainRun.jl index 40265ff..31b9caf 100644 --- a/src/TrainRun.jl +++ b/src/TrainRun.jl @@ -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 diff --git a/src/types.jl b/src/types.jl index b7fef80..2b2764b 100644 --- a/src/types.jl +++ b/src/types.jl @@ -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