parent
6f3a391ab0
commit
a57944b166
|
@ -1,7 +1,7 @@
|
|||
name = "RailwayDrivingDynamics"
|
||||
name = "TrainRun"
|
||||
uuid = "e4541106-d44c-4e00-b50b-ecdf479fcf92"
|
||||
authors = ["Max Kannenberg"]
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
|
||||
[deps]
|
||||
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# RailwayDrivingDynamics
|
||||
# TrainRun
|
||||
|
||||
------------
|
||||
|
||||
|
@ -23,6 +23,11 @@ See folder examples.
|
|||
|
||||
# History
|
||||
|
||||
## Version 0.2
|
||||
|
||||
Modules and variables were renamed.
|
||||
|
||||
|
||||
## Version 0.1
|
||||
|
||||
Proof of concept and master thesis submission.
|
||||
|
|
|
@ -8,4 +8,4 @@ settings:
|
|||
operationModeMinimumEnergyConsumption: true # operation mode "minimum energy consumption"
|
||||
typeOfOutput: "CSV" # output as "julia dictionary" or as "CSV"
|
||||
detailOfOutput: "driving course" # should the output be "reduced" or "driving course"?
|
||||
csvFolderPath: "~/Desktop/RailwayDrivingDynamics"
|
||||
csvFolderPath: "~/Desktop/TrainRun"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
vehicle:
|
||||
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)
|
||||
m_td: 80000 # mass on driving axles of the traction unit in kg (source: https://de.wikipedia.org/wiki/DB-Baureihe_V_90)
|
||||
|
@ -9,7 +9,7 @@ vehicle:
|
|||
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)
|
||||
vehicleType: freight # "freight" or "passenger" or "motor coach train" (source: https://dybas.de/dybas/gw/gw_f_1/g124.html)
|
||||
trainType: freight # "freight" or "passenger" or "motor coach train" (source: https://dybas.de/dybas/gw/gw_f_1/g124.html)
|
||||
v_limit: # in m/s
|
||||
v_limit_kmh: 80 # in km/h (source: https://de.wikipedia.org/wiki/DB-Baureihe_V_90)
|
||||
a_braking: -0.4124 # in m/s^2 (source: FBS -> using the information from the "Fahrschaubild" of a long path without gradient or speed limit for DB 290 with with 10x Facs124)
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
vehicle:
|
||||
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)
|
||||
m_td: 84000 # mass on driving axles of the traction unit in kg (source: FBS: DB146.5)
|
||||
|
@ -9,7 +9,7 @@ vehicle:
|
|||
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)
|
||||
vehicleType: passenger # "freight" or "passenger" or "motor coach train" (source: https://de.wikipedia.org/wiki/Intercity_2_(Deutsche_Bahn))
|
||||
trainType: passenger # "freight" or "passenger" or "motor coach train" (source: https://de.wikipedia.org/wiki/Intercity_2_(Deutsche_Bahn))
|
||||
v_limit: # in m/s
|
||||
v_limit_kmh: 160 # in km/h (source: https://de.wikipedia.org/wiki/Intercity_2_(Deutsche_Bahn)#Gemeinsame_Merkmale)
|
||||
a_braking: -0.3507 # in m/s^2 (source: FBS -> using the information from the "Fahrschaubild" of a long path without gradient or speed limit for DB146.5 with 1x DApza687.2, 3x DBpza668.2, 1x DBpbzfa668.2)
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
vehicle:
|
||||
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)
|
||||
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)
|
||||
|
@ -9,7 +9,7 @@ vehicle:
|
|||
rotationMassFactor_t:
|
||||
rotationMassFactor_w:
|
||||
powerType: diesel # diesel or electric (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
|
||||
vehicleType: motor coach train # "freight" or "passenger" or "motor coach train" (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
|
||||
trainType: motor coach train # "freight" or "passenger" or "motor coach train" (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
|
||||
v_limit: # in m/s
|
||||
v_limit_kmh: 120 # in km/h (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
|
||||
a_braking: -0.4253 # in m/s^2 (source: FBS -> using the information from the "Fahrschaubild" of a long path without gradient or speed limit for DB 642)
|
|
@ -1,34 +1,40 @@
|
|||
include("../src/RailwayDrivingDynamics.jl")
|
||||
using .RailwayDrivingDynamics
|
||||
include("../src/TrainRun.jl")
|
||||
using .TrainRun
|
||||
|
||||
|
||||
# println("")
|
||||
# println("________________________")
|
||||
# println("")
|
||||
|
||||
allPaths=["../data/paths/path_1_10km_nConst_vConst.yaml" , "../data/paths/path_2_10km_nVar_vConst.yaml", "../data/paths/path_3_10km_nConst_vVar.yaml", "../data/paths/path_4_real_Ostsachsen_DG-DN_spp_5.yaml"]
|
||||
|
||||
settingsFilePath="../data/settings.yaml"
|
||||
allPaths=[]
|
||||
push!(allPaths, "../data/paths/path_1_10km_nConst_vConst.yaml")
|
||||
push!(allPaths, "../data/paths/path_2_10km_nVar_vConst.yaml")
|
||||
push!(allPaths, "../data/paths/path_3_10km_nConst_vVar.yaml")
|
||||
push!(allPaths, "../data/paths/path_4_real_Ostsachsen_DG-DN_spp_5.yaml")
|
||||
|
||||
for pathFilePath in allPaths
|
||||
allSettings=[]
|
||||
push!(allSettings, "../data/settings.yaml")
|
||||
|
||||
allTrains=[]
|
||||
push!(allTrains, "../data/trains/train_freight_V90withOreConsist.yaml")
|
||||
push!(allTrains, "../data/trains/train_yaml_files\\train_passenger_SiemensDesiroClassic.yaml")
|
||||
push!(allTrains, "../data/trains/train_passenger_IC2.yaml")
|
||||
|
||||
for pathDirectory in allPaths
|
||||
# println("")
|
||||
# println(" - - - - - - - - -")
|
||||
# println("path: ", pathFilePath)
|
||||
# println("path: ", pathDirectory)
|
||||
for trainDirectory in allTrains
|
||||
# println("train: ", trainDirectory)
|
||||
for settingsDirectory in allSettings
|
||||
testDict=calculateDrivingDynamics(trainDirectory, pathDirectory, settingsDirectory)
|
||||
|
||||
vehicleFilePath="../data/vehicles/vehicle_passenger_intercity.yaml"
|
||||
testDict1=calculateDrivingDynamics(vehicleFilePath, pathFilePath, settingsFilePath)
|
||||
sleep(2)
|
||||
|
||||
sleep(2)
|
||||
vehicleFilePath="../data/vehicles/vehicle_passenger_suburban.yaml"
|
||||
testDict2=calculateDrivingDynamics(vehicleFilePath, pathFilePath, settingsFilePath)
|
||||
|
||||
|
||||
sleep(2)
|
||||
vehicleFilePath="../data/vehicles/vehicle_freight.yaml"
|
||||
testDict3=calculateDrivingDynamics(vehicleFilePath, pathFilePath, settingsFilePath)
|
||||
|
||||
|
||||
# println("")
|
||||
# println("")
|
||||
# println("")
|
||||
# println("")
|
||||
# println("")
|
||||
# println("")
|
||||
# println("")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,92 +1,92 @@
|
|||
module RailwayDrivingDynamicsEnergySaving
|
||||
module EnergySaving
|
||||
|
||||
using ..types
|
||||
using ..RailwayDrivingDynamicsMovingPhases
|
||||
using ..MovingPhases
|
||||
|
||||
export calculateRecoveryTime, increaseCostingSection, decreaseMaximumVelocity, combineEnergySavingMethods
|
||||
export calculateRecoveryTime, increaseCoastingSection, decreaseMaximumVelocity, combineEnergySavingMethods
|
||||
|
||||
function calculateRecoveryTime(s_MS::AbstractFloat, t_MS::AbstractFloat, vehicle::Vehicle)
|
||||
function calculateRecoveryTime(s_MS::AbstractFloat, t_MS::AbstractFloat, train::Train)
|
||||
# function for calculating the recovery time that can be used for energy saving
|
||||
if vehicle.vehicleType=="motor coach train"
|
||||
if train.trainType=="motor coach train"
|
||||
if s_MS<= 30000
|
||||
c_s=0.0
|
||||
else s_MS> 30000
|
||||
c_s=0.0006
|
||||
end # if s_MS
|
||||
|
||||
if vehicle.v_limit<=140/3.6 # unit is m/s
|
||||
if train.v_limit<=140/3.6 # unit is m/s
|
||||
c_t=0.03
|
||||
elseif vehicle.v_limit<=160/3.6 # unit is m/s
|
||||
elseif train.v_limit<=160/3.6 # unit is m/s
|
||||
c_t=0.04
|
||||
elseif vehicle.v_limit<=200/3.6 # unit is m/s
|
||||
elseif train.v_limit<=200/3.6 # unit is m/s
|
||||
c_t=0.05
|
||||
elseif vehicle.v_limit<=250/3.6 # unit is m/s
|
||||
elseif train.v_limit<=250/3.6 # unit is m/s
|
||||
c_t=0.06
|
||||
else # vehicle.v_limit>120/3.6 # unit is m/s
|
||||
else # train.v_limit>120/3.6 # unit is m/s
|
||||
c_t=0.07
|
||||
end # if vehicle.v_limit
|
||||
end # if train.v_limit
|
||||
|
||||
t_recovery=s_MS*c_s+t_MS*c_t
|
||||
return t_recovery
|
||||
elseif vehicle.vehicleType=="freight" && vehicle.v_limit<=120/3.6 # unit is m/s
|
||||
elseif train.trainType=="freight" && train.v_limit<=120/3.6 # unit is m/s
|
||||
t_recovery1=s_MS*0.0006 +t_MS*0.03
|
||||
t_recovery2=s_MS*0.0018 +t_MS*0.0
|
||||
t_recovery3=s_MS*0.0 +t_MS*0.04
|
||||
t_recovery=max(t_recovery1, t_recovery2, t_recovery3)
|
||||
|
||||
return t_recovery
|
||||
else # vehicle.vehicleType=="passenger" || (vehicle.vehicleType=="freight" && vehicle.v_limit>120/3.6) # unit is m/s
|
||||
else # train.trainType=="passenger" || (train.trainType=="freight" && train.v_limit>120/3.6) # unit is m/s
|
||||
if s_MS<= 30000
|
||||
c_s=0.0
|
||||
else s_MS> 30000
|
||||
c_s=0.0009
|
||||
end # if s_MS
|
||||
if vehicle.v_limit<=140/3.6 # unit is m/s
|
||||
if vehicle.m_union<=300000 # unit is kg
|
||||
if train.v_limit<=140/3.6 # unit is m/s
|
||||
if train.m_union<=300000 # unit is kg
|
||||
c_t=0.03
|
||||
elseif vehicle.m_union<=500000 # unit is kg
|
||||
elseif train.m_union<=500000 # unit is kg
|
||||
c_t=0.04
|
||||
elseif vehicle.m_union<=700000 # unit is kg
|
||||
elseif train.m_union<=700000 # unit is kg
|
||||
c_t=0.04
|
||||
else # vehicle.m_union>700000 # unit is kg
|
||||
else # train.m_union>700000 # unit is kg
|
||||
c_t=0.05
|
||||
end # if vehicle.m_union
|
||||
elseif vehicle.v_limit<=160/3.6 # unit is m/s
|
||||
if vehicle.m_union<=300000 # unit is kg
|
||||
end # if train.m_union
|
||||
elseif train.v_limit<=160/3.6 # unit is m/s
|
||||
if train.m_union<=300000 # unit is kg
|
||||
c_t=0.03
|
||||
elseif vehicle.m_union<=500000 # unit is kg
|
||||
elseif train.m_union<=500000 # unit is kg
|
||||
c_t=0.04
|
||||
else # vehicle.m_union>500000 # unit is kg
|
||||
else # train.m_union>500000 # unit is kg
|
||||
c_t=0.0
|
||||
end # if vehicle.m_union
|
||||
elseif vehicle.v_limit<=200/3.6 # unit is m/s
|
||||
if vehicle.m_union<=300000 # unit is kg
|
||||
end # if train.m_union
|
||||
elseif train.v_limit<=200/3.6 # unit is m/s
|
||||
if train.m_union<=300000 # unit is kg
|
||||
c_t=0.04
|
||||
elseif vehicle.m_union<=500000 # unit is kg
|
||||
elseif train.m_union<=500000 # unit is kg
|
||||
c_t=0.05
|
||||
else # vehicle.m_union>500000 # unit is kg
|
||||
else # train.m_union>500000 # unit is kg
|
||||
c_t=0.06
|
||||
end # if vehicle.m_union
|
||||
else # vehicle.v_limit>200/3.6 # unit is m/s
|
||||
if vehicle.m_union<=300000 # unit is kg
|
||||
end # if train.m_union
|
||||
else # train.v_limit>200/3.6 # unit is m/s
|
||||
if train.m_union<=300000 # unit is kg
|
||||
c_t=0.05
|
||||
elseif vehicle.m_union<=500000 # unit is kg
|
||||
elseif train.m_union<=500000 # unit is kg
|
||||
c_t=0.06
|
||||
else # vehicle.m_union>500000 # unit is kg
|
||||
else # train.m_union>500000 # unit is kg
|
||||
c_t=0.07
|
||||
end # if vehicle.m_union
|
||||
end # if vehicle.v_limit
|
||||
end # if train.m_union
|
||||
end # if train.v_limit
|
||||
|
||||
c_tMin=s_MS/t_MS*0.0012
|
||||
c_t=max(c_t, c_tMin)
|
||||
|
||||
t_recovery=s_MS*c_s+t_MS*c_t
|
||||
return t_recovery
|
||||
end # if vehicle.vehicleType
|
||||
end # if train.trainType
|
||||
end #function calculateRecoveryTime
|
||||
|
||||
|
||||
function increaseCostingSection(csOriginal::CharacteristicSection, drivingCourse::Vector{Waypoint}, settings::Settings, vehicle::Vehicle, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||
function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCourse::Vector{Waypoint}, settings::Settings, train::Train, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||
if haskey(csOriginal.behaviorSections, "cruising") && haskey(csOriginal.behaviorSections, "braking")
|
||||
cruisingReduction=settings.stepSize
|
||||
while cruisingReduction>=settings.stepSize/100
|
||||
|
@ -97,8 +97,10 @@ function increaseCostingSection(csOriginal::CharacteristicSection, drivingCourse
|
|||
if energySavingStartId==0
|
||||
error("ERROR at creating a new driving course for energy saving with coasting !")
|
||||
end
|
||||
# tried to insert copy on 15.07.2021 drivingCourseModified=[copy(drivingCourse[1])]
|
||||
drivingCourseModified=[Waypoint(drivingCourse[1])]
|
||||
for i in 2:energySavingStartId
|
||||
# tried to insert copy on 15.07.2021 push!(drivingCourseModified, copy(drivingCourse[i])) # List of waypoints till the start of energy saving
|
||||
push!(drivingCourseModified, Waypoint(drivingCourse[i])) # List of waypoints till the start of energy saving
|
||||
end
|
||||
|
||||
|
@ -121,7 +123,7 @@ function increaseCostingSection(csOriginal::CharacteristicSection, drivingCourse
|
|||
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
|
||||
end
|
||||
if haskey(csOriginal.behaviorSections, "cruisingBeforeAcceleration") # this section is needed before acceleration if the mass strip model is used and if the vehicle wants to accelerate to a velocity higher than the limit in the other CS where parts of the union are still located
|
||||
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
|
||||
|
@ -136,13 +138,13 @@ function increaseCostingSection(csOriginal::CharacteristicSection, drivingCourse
|
|||
|
||||
# calculating the new and now shorter cruising section
|
||||
if s_cruising>0.0
|
||||
(csModified, drivingCourseModified)=addCruisingPhase!(csModified, drivingCourseModified, s_cruising, settings, vehicle, allCSs, "cruising")
|
||||
(csModified, drivingCourseModified)=addCruisingPhase!(csModified, drivingCourseModified, s_cruising, settings, train, allCSs, "cruising")
|
||||
end
|
||||
|
||||
(csModified, drivingCourseModified)=addCoastingPhaseWithIntersection!(csModified, drivingCourseModified, settings, vehicle, allCSs)
|
||||
(csModified, drivingCourseModified)=addCoastingPhaseUntilBraking!(csModified, drivingCourseModified, settings, train, allCSs)
|
||||
|
||||
if drivingCourseModified[end].v<csModified.v_exit || drivingCourseModified[end].s>csModified.s_end
|
||||
# the vehicle 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)
|
||||
# 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)
|
||||
cruisingReduction=cruisingReduction/10
|
||||
else
|
||||
break
|
||||
|
@ -150,11 +152,11 @@ function increaseCostingSection(csOriginal::CharacteristicSection, drivingCourse
|
|||
end # while cruisingReduction
|
||||
|
||||
if drivingCourseModified[end].v>csModified.v_exit
|
||||
(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings.massModel, vehicle, allCSs)
|
||||
(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings.massModel, train, allCSs)
|
||||
elseif drivingCourseModified[end].v==csModified.v_exit && drivingCourseModified[end].s<csModified.s_end
|
||||
# v_exit is already reached. Now cruising till the end of the CS
|
||||
s_cruisingAfterCoasting=csModified.s_end-drivingCourseModified[end].s
|
||||
(csModified, drivingCourseModified)=addCruisingPhase!(csModified, drivingCourseModified, s_cruisingAfterCoasting, settings, vehicle, allCSs, "cruisingAfterCoasting")
|
||||
(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
|
||||
|
@ -169,13 +171,13 @@ function increaseCostingSection(csOriginal::CharacteristicSection, drivingCourse
|
|||
# there is no energy saving modification for this CS because a cruising section AND a braking section are needed to be transformed into a coasting section
|
||||
return (CharacteristicSection(), [], false)
|
||||
end
|
||||
end # function increaseCostingSection
|
||||
end # function increaseCoastingSection
|
||||
|
||||
|
||||
|
||||
# method 2 with shortening the acceleration by stepsize
|
||||
function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse, settings::Settings, vehicle::Vehicle, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||
#function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse::Vector{Waypoint}, settings::Settings, vehicle::Vehicle, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||
function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse, settings::Settings, train::Train, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||
#function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse::Vector{Waypoint}, 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
|
||||
# instead of calculating the new final velocity of the acceleration phase with the step sizes for the different step variables, the velocity of the point before the last will be the new v_reach
|
||||
# because it it easier at the moment (TODO)
|
||||
|
@ -197,6 +199,7 @@ function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCours
|
|||
|
||||
drivingCourseModified=Vector{Waypoint}()
|
||||
for i in 1:energySavingStartId
|
||||
# tried to insert copy on 15.07.2021 push!(drivingCourseModified, copy(drivingCourse[i])) # List of waypoints till the start of energy saving
|
||||
push!(drivingCourseModified, Waypoint(drivingCourse[i])) # List of waypoints till the start of energy saving
|
||||
end
|
||||
|
||||
|
@ -204,20 +207,20 @@ function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCours
|
|||
|
||||
# calculation of the new and now shorter acceleration section
|
||||
if drivingCourseModified[end].v<csModified.v_reach
|
||||
(csModified, drivingCourseModified)=addAccelerationPhase!(csModified, drivingCourseModified, settings, vehicle, allCSs)
|
||||
(csModified, drivingCourseModified)=addAccelerationPhase!(csModified, drivingCourseModified, settings, train, allCSs)
|
||||
end #if
|
||||
# TODO: instead of copying the drivingCourse till the start of acceleration and calculating the acceleration again till the point before the last it would be possible to copy the drivingCouse until this point. Then it would not be necessary to calculate the accelerationPhase again. But then it is difficult to reduce accelerationReduction.
|
||||
|
||||
s_braking=max(0.0, ceil((csModified.v_exit^2-csModified.v_reach^2)/2/vehicle.a_braking, digits=10)) # ceil is used to be sure that the vehicle stops at s_end in spite of rounding errors
|
||||
s_braking=max(0.0, ceil((csModified.v_exit^2-csModified.v_reach^2)/2/train.a_braking, digits=10)) # 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
|
||||
|
||||
if s_cruising >0.001
|
||||
(csModified, drivingCourseModified)=addCruisingPhase!(csModified, drivingCourseModified, s_cruising, settings, vehicle, allCSs, "cruising")
|
||||
(csModified, drivingCourseModified)=addCruisingPhase!(csModified, drivingCourseModified, s_cruising, settings, train, allCSs, "cruising")
|
||||
end #if
|
||||
|
||||
# s_brakingAfterCruising=ceil((csModified.v_exit^2-drivingCourseModified[end].v^2)/2/vehicle.a_braking, digits=10) # TODO: check if s_braking and s_brakingAfterCruising are really always the same
|
||||
# s_brakingAfterCruising=ceil((csModified.v_exit^2-drivingCourseModified[end].v^2)/2/train.a_braking, digits=10) # TODO: check if s_braking and s_brakingAfterCruising are really always the same
|
||||
if drivingCourseModified[end].v>csModified.v_exit
|
||||
(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings.massModel, vehicle, allCSs)
|
||||
(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings.massModel, train, allCSs)
|
||||
elseif drivingCourseModified[end].s<csModified.s_end
|
||||
if (csModified.s_end-drivingCourseModified[end].s)>0.001
|
||||
println("WARNING: The end of new CS",csModified.id," is not reached while saving energy with lowering v_reach.")
|
||||
|
@ -243,23 +246,24 @@ function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCours
|
|||
end # function decreaseMaximumVelocity
|
||||
|
||||
# combination of method 1 and method 2
|
||||
function combineEnergySavingMethods(csOriginal::CharacteristicSection, drivingCourse::Vector{Waypoint}, settings::Settings, vehicle::Vehicle, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||
function combineEnergySavingMethods(csOriginal::CharacteristicSection, drivingCourse::Vector{Waypoint}, 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
|
||||
csCombined=CharacteristicSection(csOriginal)
|
||||
drivingCourseCombined=Vector{Waypoint}()
|
||||
for i in 1:length(drivingCourse)
|
||||
# tried to insert copy on 15.07.2021 push!(drivingCourseCombined, copy(drivingCourse[i]))
|
||||
push!(drivingCourseCombined, Waypoint(drivingCourse[i]))
|
||||
end
|
||||
ΔE=0.0 # saved energy (in Ws)
|
||||
Δt=0.0 # time loss (in s)
|
||||
while (Δt<t_recoveryAvailable && ΔE<=0.0)
|
||||
(csCombined, drivingCourseCombined, newMaximumVelocity)=decreaseMaximumVelocity(csCombined, drivingCourseCombined, settings, vehicle, allCSs, t_recoveryAvailable)
|
||||
(csCombined, drivingCourseCombined, newMaximumVelocity)=decreaseMaximumVelocity(csCombined, drivingCourseCombined, settings, train, allCSs, t_recoveryAvailable)
|
||||
if newMaximumVelocity
|
||||
ΔE=csOriginal.E_total-csCombined.E_total # saved energy (in Ws)
|
||||
Δt=csCombined.t_total-csOriginal.t_total # time loss (in s)
|
||||
|
||||
while (haskey(csOriginal.behaviorSections, "cruising") && (Δt<=0.0 || ΔE<=0.0)) #Δt<=0.0) #&& ΔE<=0.0) # && Δt<=0.0)
|
||||
(csCombined, drivingCourseCombined, newCoasting)=increaseCostingSection(csCombined, drivingCourseCombined, settings, vehicle, allCSs, t_recoveryAvailable-Δt)
|
||||
(csCombined, drivingCourseCombined, newCoasting)=increaseCoastingSection(csCombined, drivingCourseCombined, settings, train, allCSs, t_recoveryAvailable-Δt)
|
||||
if newCoasting
|
||||
ΔE=csOriginal.E_total-csCombined.E_total # saved energy (in Ws)
|
||||
Δt=csCombined.t_total-csOriginal.t_total # time loss (in s)
|
||||
|
@ -278,4 +282,4 @@ function combineEnergySavingMethods(csOriginal::CharacteristicSection, drivingCo
|
|||
end #if
|
||||
end #function combineEnergySavingMethods
|
||||
|
||||
end #module RailwayDrivingDynamicsEnergySaving
|
||||
end #module EnergySaving
|
|
@ -0,0 +1,634 @@
|
|||
module Input
|
||||
|
||||
import YAML
|
||||
using ..types
|
||||
|
||||
export readInput
|
||||
|
||||
"""
|
||||
Read the input information from YAML files for train, path and settings, save it in different objects and return them.
|
||||
"""
|
||||
function readInput(trainFilePath::String, pathFilePath::String, settingsFilePath::String)
|
||||
train=inputTrain(trainFilePath)
|
||||
path=inputPath(pathFilePath)
|
||||
settings=inputSettings(settingsFilePath)
|
||||
|
||||
return (train, path, settings)
|
||||
end #function readInput
|
||||
|
||||
"""
|
||||
Read the train information from a YAML file, save it in a Train object and return it.
|
||||
"""
|
||||
function inputTrain(trainFilePath::String)
|
||||
data = YAML.load(open(trainFilePath))
|
||||
collect(keys(data))
|
||||
collect(values(data))
|
||||
|
||||
train=Train()
|
||||
if haskey(data["train"],"name")
|
||||
train.name=data["train"]["name"] # trains name
|
||||
delete!(data["train"], "name")
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The keyword name is missing. It has to be added.")
|
||||
end
|
||||
train.id=1 # trains identifier
|
||||
|
||||
if haskey(data["train"],"trainType")
|
||||
if typeof(data["train"]["trainType"])==String && (data["train"]["trainType"]=="freight" || data["train"]["trainType"]=="motor coach train" || data["train"]["trainType"]=="passenger")
|
||||
train.trainType=data["train"]["trainType"] # "passenger" or "freight" or "motor coach train"
|
||||
delete!(data["train"], "trainType")
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of trainType is wrong. It has to be freight, motor coach train or passenger.")
|
||||
end
|
||||
else
|
||||
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")
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of the length is no real number >0.0.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The keyword length is missing. It has to be added with a value of type real floating point number >0.0.")
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
# speed limit: # trains speed limit (in m/s)
|
||||
v_limit_temp=0.0
|
||||
v_limit_kmh_temp=0.0
|
||||
if haskey(data["train"],"v_limit") && data["train"]["v_limit"]!=nothing
|
||||
if typeof(data["train"]["v_limit"]) <: Real && data["train"]["v_limit"]>0.0
|
||||
v_limit_temp=data["train"]["v_limit"] # trains speed limit (in m/s)
|
||||
delete!(data["train"], "v_limit")
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of v_limit is no real floating point number >0.0.")
|
||||
end
|
||||
end
|
||||
|
||||
if haskey(data["train"],"v_limit_kmh") && data["train"]["v_limit_kmh"]!=nothing
|
||||
if typeof(data["train"]["v_limit_kmh"]) <: Real && data["train"]["v_limit_kmh"]>0.0
|
||||
v_limit_kmh_temp=data["train"]["v_limit_kmh"] # trains speed limit (in km/h)
|
||||
delete!(data["train"], "v_limit_kmh")
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of v_limit is no real floating point number >0.0.")
|
||||
end
|
||||
end
|
||||
|
||||
if v_limit_temp > 0.0 && v_limit_kmh_temp > 0.0
|
||||
train.v_limit=v_limit_temp
|
||||
difference=abs(v_limit_temp-v_limit_kmh_temp/3.6)
|
||||
if difference >0.0
|
||||
println("WARNING at reading the train yaml file: The values of v_limit and v_limit_kmh differ by ",difference," m/s. The value v_limit=",train.v_limit," m/s is used." )
|
||||
end
|
||||
elseif v_limit_temp > 0.0
|
||||
train.v_limit=v_limit_temp
|
||||
elseif v_limit_kmh_temp > 0.0
|
||||
train.v_limit=v_limit_kmh_temp/3.6
|
||||
else
|
||||
train.v_limit=1000/3.6
|
||||
println("WARNING at reading the train yaml file: There is no value for the trains speed limit (v_limit or v_limit_kmh). The value v_limit=1000 km/h =",train.v_limit," m/s is used." )
|
||||
end
|
||||
|
||||
|
||||
# a_braking
|
||||
if haskey(data["train"],"a_braking")
|
||||
if typeof(data["train"]["a_braking"]) <: Real
|
||||
train.a_braking=data["train"]["a_braking"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of the a_braking is no real floating point number <0.0.")
|
||||
end
|
||||
delete!(data["train"], "a_braking")
|
||||
|
||||
if train.a_braking > 0.0
|
||||
train.a_braking =-train.a_braking
|
||||
println("WARNING at reading the train yaml file: The value for a_braking is >0.0. The braking acceleration has to be <0.0. Therefore a_braking =",train.a_braking," m/s^2 is used." )
|
||||
elseif train.a_braking == 0.0
|
||||
error("ERROR at reading the train yaml file: The value for a_braking is 0.0. The braking acceleration has to be <0.0.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The keyword a_braking is missing. It has to be added with a value of type real floating point number <0.0.")
|
||||
end
|
||||
|
||||
# mass on the traction units driving axles (in kg)
|
||||
if haskey(data["train"],"m_td")
|
||||
if typeof(data["train"]["m_td"]) <: Real && data["train"]["m_td"]>0.0
|
||||
train.m_td=data["train"]["m_td"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of m_td is no real floating point number >0.0.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The keyword m_td is missing. It has to be added with a value of type real floating point number >0.0.")
|
||||
end
|
||||
delete!(data["train"], "m_td")
|
||||
|
||||
|
||||
# mass on the traction units carrying axles (in kg)
|
||||
if haskey(data["train"],"m_tc")
|
||||
if typeof(data["train"]["m_tc"]) <: Real && data["train"]["m_tc"]>=0.0
|
||||
train.m_tc=data["train"]["m_tc"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of m_tc is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The keyword m_tc is missing. It has to be added with a value of type real floating point number >=0.0.")
|
||||
end
|
||||
delete!(data["train"], "m_tc")
|
||||
|
||||
# mass of the traction unit (in kg)
|
||||
train.m_t=train.m_td+train.m_tc
|
||||
|
||||
|
||||
# mass of the consist (set of wagons) (in kg)
|
||||
if haskey(data["train"],"m_w")
|
||||
if typeof(data["train"]["m_w"]) <: Real && data["train"]["m_w"]>=0.0
|
||||
train.m_w=data["train"]["m_w"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of m_w is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
train.m_w=0.0
|
||||
println("WARNING at reading the train yaml file: The keyword m_w is missing. Therefore m_w =",train.m_w," kg is used.")
|
||||
end
|
||||
delete!(data["train"], "m_w")
|
||||
|
||||
# total mass (in kg)
|
||||
train.m_union=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"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of rotationMassFactor_union 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
|
||||
train.ξ_t=data["train"]["rotationMassFactor_t"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of rotationMassFactor_t is no real floating point number >0.0.")
|
||||
end
|
||||
if train.m_w>0.0
|
||||
if data["train"]["rotationMassFactor_w"]>=0.0
|
||||
train.ξ_w=data["train"]["rotationMassFactor_w"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of rotationMassFactor_w is no real floating point number >=0.0.")
|
||||
end
|
||||
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)
|
||||
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.")
|
||||
end
|
||||
delete!(data["train"], "rotationMassFactor_union")
|
||||
delete!(data["train"], "rotationMassFactor_t")
|
||||
delete!(data["train"], "rotationMassFactor_w")
|
||||
|
||||
|
||||
# input for function tractiveEffort(v)
|
||||
# TODO: Should the arrays check and the arrays copy be in the same "for" loop?
|
||||
if haskey(data["train"],"F_T_pairs") && data["train"]["F_T_pairs"]!=nothing
|
||||
F_T_pairs=data["train"]["F_T_pairs"]
|
||||
|
||||
# check if the elements of the array have the correct type
|
||||
errorDetected=false
|
||||
for row in 1:length(F_T_pairs)
|
||||
if typeof(F_T_pairs[row][1]) <: Real && F_T_pairs[row][1]>=0.0
|
||||
else
|
||||
errorDetected=true
|
||||
println("ERROR at reading the train yaml file: The speed value of F_T_pairs in row ", row ," is no real floating point number >=0.0.")
|
||||
end
|
||||
if typeof(F_T_pairs[row][2]) <: Real && F_T_pairs[row][2]>=0.0
|
||||
else
|
||||
errorDetected=true
|
||||
println("ERROR at reading the train yaml file: The tractive effort value of F_T_pairs in row ", row ," is no real floating point number >=0.0.")
|
||||
end
|
||||
end # for
|
||||
if errorDetected
|
||||
error("ERROR at reading the train yaml file: Only real floating point number >=0.0 are allowed for speed and tractive effort.")
|
||||
end
|
||||
|
||||
# create tractiveEffortArray
|
||||
train.tractiveEffortArray=[]
|
||||
if F_T_pairs[1][1]==0.0
|
||||
push!(train.tractiveEffortArray, [F_T_pairs[1][1], F_T_pairs[1][1], F_T_pairs[1][2]])
|
||||
elseif F_T_pairs[1][1]>0.0 # if there is no F_T for v=0.0, the first value is used
|
||||
push!(train.tractiveEffortArray, [0.0, F_T_pairs[1][1]/3.6, F_T_pairs[1][2]])
|
||||
println("WARNING at reading the train yaml file: The tractive effort for v=0 m/s is missing. Therefore the first given value F_T(v=",F_T_pairs[1][1]," m/s)=",F_T_pairs[1][2]," N will be used." )
|
||||
else
|
||||
error("ERROR at reading the train yaml file: There is a negative speed value in the list. Only positive values for speed and tractive effort are allowed in F_T_pairs.")
|
||||
end
|
||||
|
||||
for row in 2:length(F_T_pairs)
|
||||
if F_T_pairs[row][1]>F_T_pairs[row-1][1]
|
||||
if F_T_pairs[row][2]==train.tractiveEffortArray[end][3]
|
||||
train.tractiveEffortArray[end][2]=F_T_pairs[row][1]
|
||||
else
|
||||
push!(train.tractiveEffortArray, [F_T_pairs[row][1], F_T_pairs[row][1], F_T_pairs[row][2]])
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The F_T_pairs are not in the correct order. They have to be arranged by speed values from low to high.")
|
||||
end
|
||||
end # for
|
||||
if length(F_T_pairs[1])>2
|
||||
println("INFO according the train yaml file: Only the first two columns of F_T_pairs are used in this tool.")
|
||||
end
|
||||
|
||||
if haskey(data["train"],"F_T_pairs_kmh") && data["train"]["F_T_pairs_kmh"]!=nothing
|
||||
println("WARNING at reading the train yaml file: There are values for F_T_pairs and F_T_pairs_kmh. The values for F_T_pairs are used." )
|
||||
end
|
||||
|
||||
elseif haskey(data["train"],"F_T_pairs_kmh") && data["train"]["F_T_pairs_kmh"]!=nothing
|
||||
F_T_pairs_kmh=data["train"]["F_T_pairs_kmh"]
|
||||
|
||||
# check if the elements of the array have the correct type
|
||||
errorDetected=false
|
||||
for row in 1:length(F_T_pairs_kmh)
|
||||
if typeof(F_T_pairs_kmh[row][1]) <: Real && F_T_pairs_kmh[row][1]>=0.0
|
||||
else
|
||||
errorDetected=true
|
||||
println("ERROR at reading the train yaml file: The speed value of F_T_pairs_kmh in row ", row ," is no real floating point number >=0.0.")
|
||||
end
|
||||
if typeof(F_T_pairs_kmh[row][2]) <: Real && F_T_pairs_kmh[row][2]>=0.0
|
||||
else
|
||||
errorDetected=true
|
||||
println("ERROR at reading the train yaml file: The tractive effort value of F_T_pairs_kmh in row ", row ," is no real floating point number >=0.0.")
|
||||
end
|
||||
end # for
|
||||
if errorDetected
|
||||
error("ERROR at reading the train yaml file: Only real floating point number >=0.0 are allowed for speed and tractive effort in F_T_pairs_kmh.")
|
||||
end
|
||||
|
||||
# create tractiveEffortArray
|
||||
train.tractiveEffortArray=[]
|
||||
if F_T_pairs_kmh[1][1]==0.0
|
||||
push!(train.tractiveEffortArray, [F_T_pairs_kmh[1][1]/3.6, F_T_pairs_kmh[1][1]/3.6, F_T_pairs_kmh[1][2]])
|
||||
elseif F_T_pairs_kmh[1][1]>0.0 # if there is no F_T for v=0.0, the first value is used
|
||||
push!(train.tractiveEffortArray, [0.0, F_T_pairs_kmh[1][1]/3.6, F_T_pairs_kmh[1][2]])
|
||||
println("WARNING at reading the train yaml file: The tractive effort for v=0 km/h is missing. Therefore the first given value F_T(v=",F_T_pairs_kmh[1][1]," km/h)=",F_T_pairs_kmh[1][2]," N will be used." )
|
||||
end
|
||||
for row in 2:length(F_T_pairs_kmh)
|
||||
if F_T_pairs_kmh[row][1]>F_T_pairs_kmh[row-1][1]
|
||||
if F_T_pairs_kmh[row][2]==train.tractiveEffortArray[end][3]
|
||||
train.tractiveEffortArray[end][2]=F_T_pairs_kmh[row][1]/3.6
|
||||
else
|
||||
push!(train.tractiveEffortArray, [F_T_pairs_kmh[row][1]/3.6, F_T_pairs_kmh[row][1]/3.6, F_T_pairs_kmh[row][2]])
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The F_T_pairs_kmh are not in the correct order. They have to be arranged by speed values from low to high.")
|
||||
end
|
||||
end # for
|
||||
if length(F_T_pairs_kmh[1])>2
|
||||
println("INFO at reading the train yaml file: Only the first two columns of F_T_pairs_kmh are used in this tool.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the train yaml file: There has to be one of the keywords F_T_pairs or F_T_pairs_kmh filled with a list of pairs of velocity and tractive effort.")
|
||||
end # if
|
||||
delete!(data["train"], "F_T_pairs")
|
||||
delete!(data["train"], "F_T_pairs_kmh")
|
||||
|
||||
|
||||
# coefficients for the vehicle resistance of the traction unit
|
||||
|
||||
# coefficient for velocitiy difference between traction unit and outdoor air
|
||||
train.Δv_t=15.0/3.6
|
||||
|
||||
# coefficient for basic resistance due to the traction units driving axles (in ‰)
|
||||
if haskey(data["train"],"f_Rtd0") && data["train"]["f_Rtd0"]!=nothing
|
||||
if typeof(data["train"]["f_Rtd0"]) <: Real && data["train"]["f_Rtd0"]>=0.0
|
||||
train.f_Rtd0=data["train"]["f_Rtd0"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of f_Rtd0 is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
train.f_Rtd0=0.0
|
||||
println("WARNING at reading the train yaml file: The keyword f_Rtd0 is missing. Therefore f_Rtd0=0.0 ‰ will be assumed and used." )
|
||||
end
|
||||
delete!(data["train"], "f_Rtd0")
|
||||
|
||||
# coefficient for basic resistance due to the traction units carring axles (in ‰)
|
||||
if haskey(data["train"],"f_Rtc0") && data["train"]["f_Rtc0"]!=nothing
|
||||
if typeof(data["train"]["f_Rtc0"]) <: Real && data["train"]["f_Rtc0"]>=0.0
|
||||
train.f_Rtc0=data["train"]["f_Rtc0"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of f_Rtc0 is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
train.f_Rtc0=0.0
|
||||
println("WARNING at reading the train yaml file: The keyword f_Rtc0 is missing. Therefore f_Rtc0=0.0 ‰ will be assumed and used." )
|
||||
end
|
||||
delete!(data["train"], "f_Rtc0")
|
||||
|
||||
# coefficient for air resistance of the traction units (in N)
|
||||
if haskey(data["train"],"F_Rt2") && data["train"]["F_Rt2"]!=nothing
|
||||
if typeof(data["train"]["F_Rt2"]) <: Real && data["train"]["F_Rt2"]>=0.0
|
||||
train.F_Rt2=data["train"]["F_Rt2"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of F_Rt2 is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
train.F_Rt2=0.0
|
||||
println("WARNING at reading the train yaml file: The keyword F_Rt2 is missing. Therefore F_Rt2=0.0 N will be assumed and used." )
|
||||
end
|
||||
delete!(data["train"], "F_Rt2")
|
||||
|
||||
|
||||
|
||||
# coefficients for the vehicle resistance of the consist (set of wagons)
|
||||
|
||||
# coefficient for velocitiy difference between consist (set of wagons) and outdoor air (in m/s)
|
||||
if train.trainType=="passenger" || train.trainType=="motor coach train"
|
||||
train.Δv_w=15.0/3.6
|
||||
elseif train.trainType== "freight"
|
||||
train.Δv_w=0.0
|
||||
end # if
|
||||
|
||||
# coefficient for basic resistance of the consist (set of wagons) (in ‰)
|
||||
if haskey(data["train"],"f_Rw0") && data["train"]["f_Rw0"]!=nothing
|
||||
if typeof(data["train"]["f_Rw0"]) <: Real && data["train"]["f_Rw0"]>=0.0
|
||||
train.f_Rw0=data["train"]["f_Rw0"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of f_Rw0 is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
train.f_Rw0=0.0
|
||||
println("WARNING at reading the train yaml file: The keyword f_Rw0 is missing. Therefore f_Rw0=0.0 ‰ will be assumed and used." )
|
||||
end
|
||||
delete!(data["train"], "f_Rw0")
|
||||
|
||||
# coefficient for basic resistance of the consist (set of wagons) (in ‰)
|
||||
if haskey(data["train"],"f_Rw1") && data["train"]["f_Rw1"]!=nothing
|
||||
if typeof(data["train"]["f_Rw1"]) <: Real && data["train"]["f_Rw1"]>=0.0
|
||||
train.f_Rw1=data["train"]["f_Rw1"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of f_Rw1 is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
train.f_Rw1=0.0
|
||||
println("WARNING at reading the train yaml file: The keyword f_Rw1 is missing. Therefore f_Rw1=0.0 ‰ will be assumed and used." )
|
||||
end
|
||||
delete!(data["train"], "f_Rw1")
|
||||
|
||||
# coefficient for basic resistance of the consist (set of wagons) (in ‰)
|
||||
if haskey(data["train"],"f_Rw2") && data["train"]["f_Rw2"]!=nothing
|
||||
if typeof(data["train"]["f_Rw2"]) <: Real && data["train"]["f_Rw2"]>=0.0
|
||||
train.f_Rw2=data["train"]["f_Rw2"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of f_Rw2 is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
train.f_Rw2=0.0
|
||||
println("WARNING at reading the train yaml file: The keyword f_Rw2 is missing. Therefore f_Rw2=0.0 ‰ will be assumed and used." )
|
||||
end
|
||||
delete!(data["train"], "f_Rw2")
|
||||
|
||||
|
||||
# inform the user, which keywords of the input data are not used in this tool:
|
||||
if length(data["train"])>0
|
||||
println("INFO at reading the train yaml file: The following Keywords are not used in this tool:")
|
||||
for key in keys(data["train"])
|
||||
println(" - ",key)
|
||||
end
|
||||
end
|
||||
|
||||
return train
|
||||
end #function inputTrain
|
||||
|
||||
|
||||
function inputPath(pathFilePath::String)
|
||||
# this function reads path information from a YAML file, saves it in a Path object and returns it
|
||||
data = YAML.load(open(pathFilePath))
|
||||
collect(keys(data))
|
||||
collect(values(data))
|
||||
|
||||
|
||||
if haskey(data["path"],"name") && data["path"]["name"]!=nothing
|
||||
name=data["path"]["name"] # path name
|
||||
else
|
||||
error("ERROR at reading the path yaml file: The keyword name is missing. It has to be added.")
|
||||
end
|
||||
delete!(data["path"], "name")
|
||||
|
||||
id=1 # path identifier
|
||||
path=Path(name, id, [])
|
||||
|
||||
# read the section starting positions and corresponding information
|
||||
if haskey(data["path"],"sectionStarts") && data["path"]["sectionStarts"]!=nothing
|
||||
sectionStartsArray=data["path"]["sectionStarts"]
|
||||
conversionFactor=1.0 # conversion factor between the units m/s and m/s
|
||||
valueKey="sectionStarts" # necessary for error messages
|
||||
|
||||
if haskey(data["train"],"sectionStarts") && data["train"]["sectionStarts_kmh"]!=nothing
|
||||
println("WARNING at reading the path yaml file: There are values for sectionStarts and sectionStarts_kmh. The values for sectionStarts are used." )
|
||||
end
|
||||
elseif haskey(data["path"],"sectionStarts_kmh") && data["path"]["sectionStarts_kmh"]!=nothing
|
||||
sectionStartsArray=data["path"]["sectionStarts_kmh"]
|
||||
conversionFactor=1/3.6 # conversion factor between the units km/h and m/s
|
||||
valueKey="sectionStarts_kmh" # necessary for error messages
|
||||
else
|
||||
error("ERROR at reading the path yaml file: The keyword sectionStarts or sectionStarts_kmh is missing. It has to be added.")
|
||||
end # if
|
||||
delete!(data["path"], "sectionStarts")
|
||||
delete!(data["path"], "sectionStarts_kmh")
|
||||
|
||||
# check if the array is correct and if elements of the array have the correct type and plausible values
|
||||
errorDetected=false
|
||||
if length(sectionStartsArray)>=2
|
||||
else
|
||||
error("ERROR at reading the path yaml file: The keyword ",valueKey," needs at least two rows for two points each with the three columns [s, v_limit, gradient].")
|
||||
end
|
||||
|
||||
for row in 1:length(sectionStartsArray)
|
||||
if length(sectionStartsArray[row])>=3
|
||||
if length(sectionStartsArray[row])>3
|
||||
println("INFO at reading the path yaml file: Only the first three columns of sectionStartsArray are used in this tool.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the path yaml file: The keyword ",valueKey," needs to be filled with the three columns [s, v_limit, gradient].")
|
||||
end
|
||||
|
||||
if typeof(sectionStartsArray[row][1]) <: Real
|
||||
if row > 1
|
||||
if sectionStartsArray[row][1]>sectionStartsArray[row-1][1]
|
||||
else
|
||||
errorDetected=true
|
||||
println("ERROR at reading the path yaml file: The postion value of ",valueKey," in row ", row ," (",sectionStartsArray[row][1]," m) has to be higher than the value in the row above (",sectionStartsArray[row-1][1]," m).")
|
||||
end
|
||||
end
|
||||
else
|
||||
errorDetected=true
|
||||
println("ERROR at reading the path yaml file: The position value (column 1) of ",valueKey," in row ", row ," is no real floating point number.")
|
||||
end
|
||||
|
||||
if typeof(sectionStartsArray[row][2]) <: Real && sectionStartsArray[row][2]>=0.0
|
||||
else
|
||||
errorDetected=true
|
||||
println("ERROR at reading the path yaml file: The speed limit (column 2) of ",valueKey," in row ", row ," is no real floating point number >=0.0.")
|
||||
end
|
||||
if typeof(sectionStartsArray[row][3]) <: Real
|
||||
else
|
||||
errorDetected=true
|
||||
println("ERROR at reading the path yaml file: The tractive effort value (column 3) of ",valueKey," in row ", row ," is no real floating point number.")
|
||||
end
|
||||
end # for
|
||||
if errorDetected
|
||||
error("ERROR at reading the path yaml file: The values of ",valueKey," have to be corrected.")
|
||||
end
|
||||
|
||||
# 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)
|
||||
push!(path.sections, section)
|
||||
end # for
|
||||
|
||||
|
||||
# inform the user which keywords of the input data are not used in this tool:
|
||||
if length(data["path"])>0
|
||||
println("INFO at reading the path yaml file: The following Keywords are not used in this tool:")
|
||||
for key in keys(data["path"])
|
||||
println(" - ",key)
|
||||
end
|
||||
end
|
||||
return path
|
||||
end # function inputPath
|
||||
|
||||
|
||||
|
||||
|
||||
function inputSettings(settingsFilePath::String)
|
||||
# this function reads setting information from a YAML file, saves it in a Setting object and returns it
|
||||
data = YAML.load(open(settingsFilePath))
|
||||
collect(keys(data))
|
||||
collect(values(data))
|
||||
|
||||
settings=Settings()
|
||||
|
||||
# model type of the unions 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"
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of massModel is wrong. It has to be mass point or homogeneous strip.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The keyword massModel is missing. It has to be added with the value mass point or homogeneous strip.")
|
||||
end
|
||||
delete!(data["settings"], "massModel")
|
||||
|
||||
|
||||
|
||||
# step variable of the step method "s in m", "t in s" or "v in m/s"
|
||||
if haskey(data["settings"],"stepVariable")
|
||||
if typeof(data["settings"]["stepVariable"])==String && (data["settings"]["stepVariable"]=="s in m" || data["settings"]["stepVariable"]=="t in s" || data["settings"]["stepVariable"]=="v in m/s")
|
||||
settings.stepVariable=data["settings"]["stepVariable"] # "s in m", "t in s" or "v in m/s"
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of stepVariable is wrong. It has to be s in m, t in s or v in m/s.")
|
||||
end
|
||||
else
|
||||
error("ERROR for the settings yaml file: The keyword stepVariable is missing. It has to be added with the value s in m, t in s or v in m/s.")
|
||||
end
|
||||
delete!(data["settings"], "stepVariable")
|
||||
|
||||
|
||||
# step size (unit depends on steapVariable: s in m, t in s and v in m/s)
|
||||
if haskey(data["settings"],"stepSize")
|
||||
if typeof(data["settings"]["stepSize"]) <: Real && data["settings"]["stepSize"]>0.0
|
||||
settings.stepSize=data["settings"]["stepSize"]
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of the stepSize is no real floating point number >0.0.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The keyword stepSize is missing. It has to be added with a value of type real floating point number >0.0.")
|
||||
end
|
||||
delete!(data["settings"], "stepSize")
|
||||
|
||||
|
||||
|
||||
# operation mode "minimum running time"
|
||||
if haskey(data["settings"],"operationModeMinimumRunningTime") && data["settings"]["operationModeMinimumRunningTime"]!=nothing
|
||||
if typeof(data["settings"]["operationModeMinimumRunningTime"])==Bool
|
||||
settings.operationModeMinimumRunningTime=data["settings"]["operationModeMinimumRunningTime"]
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of the keyword operationModeMinimumRunningTime is not correct. The value has to be of type boolean.")
|
||||
end
|
||||
else
|
||||
settings.operationModeMinimumRunningTime=false
|
||||
println("WARNING at reading the settings yaml file: The keyword operationModeMinimumRunningTime or its value is missing. Therefore operationModeMinimumRunningTime=",settings.operationModeMinimumRunningTime," is assumed and used.")
|
||||
end
|
||||
delete!(data["settings"], "operationModeMinimumRunningTime")
|
||||
|
||||
|
||||
# operation mode "minimum energy consumption"
|
||||
if haskey(data["settings"],"operationModeMinimumEnergyConsumption") && data["settings"]["operationModeMinimumEnergyConsumption"]!=nothing
|
||||
if typeof(data["settings"]["operationModeMinimumEnergyConsumption"])==Bool
|
||||
settings.operationModeMinimumEnergyConsumption=data["settings"]["operationModeMinimumEnergyConsumption"]
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of the keyword operationModeMinimumEnergyConsumption is not correct. The value has to be of type boolean.")
|
||||
end
|
||||
else
|
||||
settings.operationModeMinimumEnergyConsumption=false
|
||||
println("WARNING at reading the settings yaml file: The keyword operationModeMinimumEnergyConsumption or its value is missing. Therefore operationModeMinimumEnergyConsumption=",settings.operationModeMinimumEnergyConsumption," is assumed and used.")
|
||||
end
|
||||
delete!(data["settings"], "operationModeMinimumEnergyConsumption")
|
||||
|
||||
# output as "julia dictionary" or as "CSV"
|
||||
if haskey(data["settings"],"typeOfOutput")
|
||||
if typeof(data["settings"]["typeOfOutput"])==String && (data["settings"]["typeOfOutput"]=="julia dictionary" || data["settings"]["typeOfOutput"]=="CSV")
|
||||
settings.typeOfOutput=data["settings"]["typeOfOutput"] # "julia dictionary" or "CSV"
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of typeOfOutput is wrong. It has to be julia dictionary or CSV.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The keyword typeOfOutput is missing. It has to be added with the value julia dictionary or CSV.")
|
||||
end
|
||||
delete!(data["settings"], "typeOfOutput")
|
||||
|
||||
# TODO: it could be checked if the path is existing on the pc
|
||||
if settings.typeOfOutput=="CSV"
|
||||
if haskey(data["settings"],"csvFolderPath")
|
||||
if typeof(data["settings"]["csvFolderPath"])==String
|
||||
settings.csvFolderPath=data["settings"]["csvFolderPath"]
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of csvFolderPath is wrong. It has to be of type String.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The keyword csvFolderPath is missing. It has to be added.")
|
||||
end
|
||||
delete!(data["settings"], "csvFolderPath")
|
||||
end # if
|
||||
|
||||
|
||||
# should the output be "reduced" 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"
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of detailOfOutput is wrong. It has to be reduced 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.")
|
||||
end
|
||||
delete!(data["settings"], "detailOfOutput")
|
||||
|
||||
|
||||
# inform the user, which keywords of the input data are not used in this tool:
|
||||
if length(data["settings"])>0
|
||||
println("INFO at reading the settings yaml file: The following Keywords are not used in this tool:")
|
||||
for key in keys(data["settings"])
|
||||
println(" - ",key)
|
||||
end
|
||||
end
|
||||
|
||||
return settings
|
||||
end # function inputSettings
|
||||
|
||||
end # module Input
|
|
@ -1,14 +1,16 @@
|
|||
module RailwayDrivingDynamicsMovingPhases
|
||||
module MovingPhases
|
||||
|
||||
using ..types
|
||||
export addAccelerationPhase!, addAccelerationPhaseWithIntersection!, addCruisingPhase!, addCoastingPhaseWithIntersection!, addBrakingPhase!
|
||||
export addAccelerationPhase!, addAccelerationPhaseUntilBraking!, addCruisingPhase!, addCoastingPhaseUntilBraking!, addBrakingPhase!
|
||||
|
||||
v00=100/3.6 # velocity constant (in m/s)
|
||||
g=9.81 # acceleration due to gravity (in m/s^2) # TODO: should more digits of g be used? g=9,80665 m/s^2
|
||||
|
||||
## functions for calculating tractive effort and resisting forces
|
||||
"""
|
||||
calculate the trains tractive effort dependend on the velocity
|
||||
"""
|
||||
function calculateTractiveEffort(v::AbstractFloat, tractiveEffortArray)
|
||||
# this function calculates the vehicles tractive effort dependend on the velocity
|
||||
for row in 1:length(tractiveEffortArray)
|
||||
if tractiveEffortArray[row][1]<=v && v<=tractiveEffortArray[row][2]
|
||||
return tractiveEffortArray[row][3]
|
||||
|
@ -24,18 +26,25 @@ function calculateTractiveEffort(v::AbstractFloat, tractiveEffortArray)
|
|||
end #for
|
||||
end #function calculateTractiveEffort
|
||||
|
||||
function calculateTractionUnitResistance(v::AbstractFloat, vehicle::Vehicle)
|
||||
# this function calculates and returns the traction units vehicle resistance dependend on the velocity
|
||||
return vehicle.f_Rtd0/1000*vehicle.m_td*g+vehicle.f_Rtc0/1000*vehicle.m_tc*g+vehicle.F_Rt2*((v+vehicle.Δv_t)/v00)^2 # /1000 because of the unit ‰
|
||||
"""
|
||||
calculate and return the traction units vehicle resistance dependend on the velocity
|
||||
"""
|
||||
function calculateTractionUnitResistance(v::AbstractFloat, train::Train)
|
||||
return train.f_Rtd0/1000*train.m_td*g+train.f_Rtc0/1000*train.m_tc*g+train.F_Rt2*((v+train.Δv_t)/v00)^2 # /1000 because of the unit ‰
|
||||
end #function calculateTractionUnitResistance
|
||||
|
||||
function calculateWagonsResistance(v::AbstractFloat, vehicle::Vehicle)
|
||||
# this function calculates and returns the wagons vehicle resistance dependend on the velocity
|
||||
return vehicle.m_w*g*(vehicle.f_Rw0/1000+vehicle.f_Rw1/1000*v/v00+vehicle.f_Rw2/1000*((v+vehicle.Δv_w)/v00)^2) # /1000 because of the unit ‰
|
||||
"""
|
||||
calculate and return the wagons vehicle resistance dependend on the velocity
|
||||
"""
|
||||
function calculateWagonsResistance(v::AbstractFloat, train::Train)
|
||||
return train.m_w*g*(train.f_Rw0/1000+train.f_Rw1/1000*v/v00+train.f_Rw2/1000*((v+train.Δv_w)/v00)^2) # /1000 because of the unit ‰
|
||||
end #function calculateWagonsResistance
|
||||
|
||||
function calculatePathResistance(s::AbstractFloat, massModel::String, vehicle::Vehicle, allCs::Vector{CharacteristicSection})
|
||||
# looking for the characteristic section with the unions head position
|
||||
"""
|
||||
calculate and return the path resistance dependend on the trains position and mass model
|
||||
"""
|
||||
function calculatePathResistance(s::AbstractFloat, massModel::String, train::Train, allCs::Vector{CharacteristicSection})
|
||||
# looking for the characteristic section with the trains head position
|
||||
id=length(allCs)
|
||||
while s<allCs[id].s_start
|
||||
id=id-1
|
||||
|
@ -45,15 +54,15 @@ function calculatePathResistance(s::AbstractFloat, massModel::String, vehicle::V
|
|||
end #while
|
||||
|
||||
if massModel=="mass point"
|
||||
pathResistance=allCs[id].f_Rp/1000*vehicle.m_union*g # /1000 because of the unit ‰
|
||||
pathResistance=allCs[id].f_Rp/1000*train.m_union*g # /1000 because of the unit ‰
|
||||
elseif massModel=="homogeneous strip"
|
||||
pathResistance=0.0
|
||||
while id>0 && s-vehicle.l_union<allCs[id].s_end
|
||||
pathResistance=pathResistance+(min(s, allCs[id].s_end)-max(s-vehicle.l_union, allCs[id].s_start))/vehicle.l_union*(allCs[id].f_Rp/1000*vehicle.m_union*g) # /1000 because of the unit ‰
|
||||
while id>0 && s-train.l_union<allCs[id].s_end
|
||||
pathResistance=pathResistance+(min(s, allCs[id].s_end)-max(s-train.l_union, allCs[id].s_start))/train.l_union*(allCs[id].f_Rp/1000*train.m_union*g) # /1000 because of the unit ‰
|
||||
id=id-1
|
||||
if id==0
|
||||
# TODO: currently for values < movingSection.s_start the values of movingSection.s_start will be used
|
||||
return pathResistance+(allCs[1].s_start-(s-vehicle.l_union))/vehicle.l_union*(allCs[1].f_Rp/1000*vehicle.m_union*g) # /1000 because of the unit ‰
|
||||
return pathResistance+(allCs[1].s_start-(s-train.l_union))/train.l_union*(allCs[1].f_Rp/1000*train.m_union*g) # /1000 because of the unit ‰
|
||||
end #if
|
||||
end #while
|
||||
else
|
||||
|
@ -63,12 +72,33 @@ function calculatePathResistance(s::AbstractFloat, massModel::String, vehicle::V
|
|||
return pathResistance
|
||||
end #function pathResistance
|
||||
|
||||
"""
|
||||
calculate and return tractive and resisting forces for a waypoint
|
||||
"""
|
||||
function calculateForces!(waypoint::Waypoint, train::Train, massModel::String, allCs::Vector{CharacteristicSection}, bsType::String)
|
||||
# calculate resisting forces
|
||||
waypoint.F_Rt=calculateTractionUnitResistance(waypoint.v, train)
|
||||
waypoint.F_Rw=calculateWagonsResistance(waypoint.v, train)
|
||||
waypoint.F_Runion=waypoint.F_Rt+waypoint.F_Rw
|
||||
waypoint.F_Rp=calculatePathResistance(waypoint.s, massModel, train, allCs)
|
||||
waypoint.F_R=waypoint.F_Runion+waypoint.F_Rp
|
||||
|
||||
#calculate tractive effort
|
||||
if bsType == "acceleration"
|
||||
waypoint.F_T = calculateTractiveEffort(waypoint.v, train.tractiveEffortArray)
|
||||
elseif bsType == "cruising"
|
||||
waypoint.F_T = min(max(0.0, waypoint.F_R), calculateTractiveEffort(waypoint.v, train.tractiveEffortArray))
|
||||
else
|
||||
waypoint.F_T = 0.0
|
||||
end
|
||||
return waypoint
|
||||
end #function calculateForces
|
||||
|
||||
|
||||
## This function calculates the waypoints of the starting phase.
|
||||
# Therefore it gets its first waypoint and the characteristic section and returns the characteristic section including the behavior section for starting if needed.
|
||||
# TODO: currently the values of the starting phase will be calculated like in the acceleration phase
|
||||
function addStartingPhase!(characteristicSection::CharacteristicSection, drivingCourse::Vector{Waypoint}, settings::Settings, vehicle::Vehicle, allCs::Vector{CharacteristicSection})
|
||||
|
||||
# Info: currently the values of the starting phase will be calculated like in the acceleration phase
|
||||
function addStartingPhase!(characteristicSection::CharacteristicSection, drivingCourse::Vector{Waypoint}, settings::Settings, train::Train, allCs::Vector{CharacteristicSection})
|
||||
if drivingCourse[end].v==0.0 && drivingCourse[end].s<characteristicSection.s_end
|
||||
startingSection=BehaviorSection()
|
||||
startingSection.type="starting" # type of behavior section
|
||||
|
@ -76,16 +106,19 @@ function addStartingPhase!(characteristicSection::CharacteristicSection, driving
|
|||
startingSection.v_entry=drivingCourse[end].v # entry speed (in m/s)
|
||||
push!(startingSection.waypoints, drivingCourse[end].i) # list of containing waypoints
|
||||
|
||||
|
||||
|
||||
# traction effort and resisting forces (in N):
|
||||
drivingCourse[end].F_T=calculateTractiveEffort(drivingCourse[end].v, vehicle.tractiveEffortArray)
|
||||
drivingCourse[end].F_Rt=calculateTractionUnitResistance(drivingCourse[end].v, vehicle)
|
||||
drivingCourse[end].F_Rw=calculateWagonsResistance(drivingCourse[end].v, vehicle)
|
||||
drivingCourse[end].F_Runion=drivingCourse[end].F_Rt+drivingCourse[end].F_Rw
|
||||
drivingCourse[end].F_Rp=calculatePathResistance(drivingCourse[end].s, settings.massModel, vehicle, allCs)
|
||||
drivingCourse[end].F_R=drivingCourse[end].F_Runion+drivingCourse[end].F_Rp
|
||||
drivingCourse[end]=Waypoint(calculateForces!(drivingCourse[end], train, settings.massModel, allCs, "acceleration")) # currently the tractive effort is calculated like in the acceleration phase
|
||||
#07/16 drivingCourse[end].F_T=calculateTractiveEffort(drivingCourse[end].v, train.tractiveEffortArray)
|
||||
#07/16 drivingCourse[end].F_Rt=calculateTractionUnitResistance(drivingCourse[end].v, train)
|
||||
#07/16 drivingCourse[end].F_Rw=calculateWagonsResistance(drivingCourse[end].v, train)
|
||||
#07/16 drivingCourse[end].F_Runion=drivingCourse[end].F_Rt+drivingCourse[end].F_Rw
|
||||
#07/16 drivingCourse[end].F_Rp=calculatePathResistance(drivingCourse[end].s, settings.massModel, train, allCs)
|
||||
#07/16 drivingCourse[end].F_R=drivingCourse[end].F_Runion+drivingCourse[end].F_Rp
|
||||
|
||||
# acceleration (in m/s^2):
|
||||
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/vehicle.m_union/vehicle.ξ_union
|
||||
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train.m_union/train.ξ_union
|
||||
if drivingCourse[end].a<0.0
|
||||
error("ERROR: a<0 m/s^2 in the starting phase !")
|
||||
elseif drivingCourse[end].a==0.0
|
||||
|
@ -141,27 +174,27 @@ end #function addStartingPhase!
|
|||
|
||||
## This function calculates the waypoints of the acceleration phase.
|
||||
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the acceleration section
|
||||
function addAccelerationPhase!(characteristicSection::CharacteristicSection, drivingCourse::Vector{Waypoint}, settings::Settings, vehicle::Vehicle, allCs::Vector{CharacteristicSection})
|
||||
function addAccelerationPhase!(characteristicSection::CharacteristicSection, drivingCourse::Vector{Waypoint}, settings::Settings, train::Train, allCs::Vector{CharacteristicSection})
|
||||
if drivingCourse[end].v==0.0
|
||||
(characteristicSection, drivingCourse)=addStartingPhase!(characteristicSection, drivingCourse, settings, vehicle, allCs)
|
||||
(characteristicSection, drivingCourse)=addStartingPhase!(characteristicSection, drivingCourse, settings, train, allCs)
|
||||
end #if
|
||||
|
||||
# if the tail of the vehicle is still in a former characteristic section it has to be checked if its speed limit can be kept
|
||||
# if the tail of the train is still in a former characteristic section it has to be checked if its speed limit can be kept
|
||||
formerSpeedLimits=[]
|
||||
if characteristicSection.id>1 && drivingCourse[end].s-vehicle.l_union<characteristicSection.s_start
|
||||
if characteristicSection.id>1 && drivingCourse[end].s-train.l_union<characteristicSection.s_start
|
||||
if abs(allCs[characteristicSection.id-1].v_limit-drivingCourse[end].v)<0.000001
|
||||
s_braking=max(0.0, ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/vehicle.a_braking, digits=10))
|
||||
s_cruisingBeforeAcceleration=min(characteristicSection.s_end-drivingCourse[end].s-s_braking, vehicle.l_union)
|
||||
s_braking=max(0.0, ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=10))
|
||||
s_cruisingBeforeAcceleration=min(characteristicSection.s_end-drivingCourse[end].s-s_braking, train.l_union)
|
||||
|
||||
if s_cruisingBeforeAcceleration>0.0
|
||||
(characteristicSection, drivingCourse)=addCruisingPhase!(characteristicSection, drivingCourse, s_cruisingBeforeAcceleration, settings, vehicle, allCs, "cruisingBeforeAcceleration")
|
||||
(characteristicSection, drivingCourse)=addCruisingPhase!(characteristicSection, drivingCourse, s_cruisingBeforeAcceleration, settings, train, allCs, "cruisingBeforeAcceleration")
|
||||
else
|
||||
error("ERROR: cruisingBeforeAcceleration <=0.0 although it has to be >0.0 in CS ",characteristicSection.id)
|
||||
end
|
||||
else # detecting the lower speed limits of former sections
|
||||
csId=characteristicSection.id-1
|
||||
while csId>0 && drivingCourse[end].s-vehicle.l_union<allCs[csId].s_end
|
||||
if allCs[csId].v_limit<characteristicSection.v_limit # TODO: is the position of vehicles tail < movingSection.s_start, v_limit of the first CS is used
|
||||
while csId>0 && drivingCourse[end].s-train.l_union<allCs[csId].s_end
|
||||
if allCs[csId].v_limit<characteristicSection.v_limit # TODO: is the position of trains tail < movingSection.s_start, v_limit of the first CS is used
|
||||
push!(formerSpeedLimits, [allCs[csId].s_end, allCs[csId].v_limit])
|
||||
for i in 1:length(formerSpeedLimits)-1
|
||||
if formerSpeedLimits[i][2]<=formerSpeedLimits[end][2]
|
||||
|
@ -186,15 +219,18 @@ function addAccelerationPhase!(characteristicSection::CharacteristicSection, dri
|
|||
# in the fifth cycle the interpolated values are corrected in case v_reach is still to high although s==s_end
|
||||
while length(formerSpeedLimits)>0 && drivingCourse[end].v<characteristicSection.v_reach && drivingCourse[end].s<characteristicSection.s_end && drivingCourse[end].v>0.0
|
||||
push!(accelerationSection.waypoints, drivingCourse[end].i)
|
||||
drivingCourse[end].F_T=calculateTractiveEffort(drivingCourse[end].v, vehicle.tractiveEffortArray)
|
||||
drivingCourse[end].F_Rt=calculateTractionUnitResistance(drivingCourse[end].v, vehicle)
|
||||
drivingCourse[end].F_Rw=calculateWagonsResistance(drivingCourse[end].v, vehicle)
|
||||
drivingCourse[end].F_Runion=drivingCourse[end].F_Rt+drivingCourse[end].F_Rw
|
||||
drivingCourse[end].F_Rp=calculatePathResistance(drivingCourse[end].s, settings.massModel, vehicle, allCs)
|
||||
drivingCourse[end].F_R=drivingCourse[end].F_Runion+drivingCourse[end].F_Rp
|
||||
|
||||
drivingCourse[end]=Waypoint(calculateForces!(drivingCourse[end], train, settings.massModel, allCs, accelerationSection.type))
|
||||
#07/16 drivingCourse[end].F_T=calculateTractiveEffort(drivingCourse[end].v, train.tractiveEffortArray)
|
||||
#07/16 drivingCourse[end].F_Rt=calculateTractionUnitResistance(drivingCourse[end].v, train)
|
||||
#07/16 drivingCourse[end].F_Rw=calculateWagonsResistance(drivingCourse[end].v, train)
|
||||
#07/16 drivingCourse[end].F_Runion=drivingCourse[end].F_Rt+drivingCourse[end].F_Rw
|
||||
#07/16 drivingCourse[end].F_Rp=calculatePathResistance(drivingCourse[end].s, settings.massModel, train, allCs)
|
||||
#07/16 drivingCourse[end].F_R=drivingCourse[end].F_Runion+drivingCourse[end].F_Rp
|
||||
|
||||
|
||||
# acceleration (in m/s^2):
|
||||
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/vehicle.m_union/vehicle.ξ_union
|
||||
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train.m_union/train.ξ_union
|
||||
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)
|
||||
end
|
||||
|
@ -207,7 +243,7 @@ function addAccelerationPhase!(characteristicSection::CharacteristicSection, dri
|
|||
if settings.stepVariable=="s in m" # distance step method
|
||||
drivingCourse[end].Δs=currentStepSize # step size (in m)
|
||||
if ((drivingCourse[end-1].v/drivingCourse[end-1].a)^2+2*drivingCourse[end].Δs/drivingCourse[end-1].a)<0.0 || (drivingCourse[end-1].v^2+2*drivingCourse[end].Δs*drivingCourse[end-1].a)<0.0 # checking if the parts of the following square roots will be <0.0
|
||||
error("ERROR: The vehicle stops during the acceleration phase in CS",characteristicSection.id," m because the tractive effort is lower than the resistant forces.",
|
||||
error("ERROR: The train stops during the acceleration phase in CS",characteristicSection.id," m because the tractive effort is lower than the resistant forces.",
|
||||
" Before the stop the last point has the values s=",drivingCourse[end-1].s," 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.")
|
||||
end
|
||||
|
@ -231,7 +267,7 @@ function addAccelerationPhase!(characteristicSection::CharacteristicSection, dri
|
|||
drivingCourse[end].ΔE=drivingCourse[end].ΔW_T # energy consumption in this step (in Ws)
|
||||
drivingCourse[end].E=drivingCourse[end-1].E+drivingCourse[end].ΔE # energy consumption (in Ws)
|
||||
|
||||
while length(formerSpeedLimits)>0 && drivingCourse[end].s-vehicle.l_union>=formerSpeedLimits[end][1]
|
||||
while length(formerSpeedLimits)>0 && drivingCourse[end].s-train.l_union>=formerSpeedLimits[end][1]
|
||||
pop!(formerSpeedLimits)
|
||||
end
|
||||
|
||||
|
@ -247,11 +283,11 @@ function addAccelerationPhase!(characteristicSection::CharacteristicSection, dri
|
|||
end
|
||||
|
||||
# creating a cruisingBeforeAcceleration section
|
||||
s_braking=max(0.0, ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/vehicle.a_braking, digits=10))
|
||||
s_cruisingBeforeAcceleration=min(characteristicSection.s_end-drivingCourse[end].s-s_braking, formerSpeedLimits[end][1]-(drivingCourse[end].s-vehicle.l_union))
|
||||
s_braking=max(0.0, ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=10))
|
||||
s_cruisingBeforeAcceleration=min(characteristicSection.s_end-drivingCourse[end].s-s_braking, formerSpeedLimits[end][1]-(drivingCourse[end].s-train.l_union))
|
||||
|
||||
if s_cruisingBeforeAcceleration>0.0
|
||||
(characteristicSection, drivingCourse)=addCruisingPhase!(characteristicSection, drivingCourse, s_cruisingBeforeAcceleration, settings, vehicle, allCs, "cruisingBeforeAcceleration")
|
||||
(characteristicSection, drivingCourse)=addCruisingPhase!(characteristicSection, drivingCourse, s_cruisingBeforeAcceleration, settings, train, allCs, "cruisingBeforeAcceleration")
|
||||
else
|
||||
error("ERROR: cruisingBeforeAcceleration <=0.0 although it has to be >0.0 in CS ",characteristicSection.id)
|
||||
end
|
||||
|
@ -269,22 +305,23 @@ function addAccelerationPhase!(characteristicSection::CharacteristicSection, dri
|
|||
end
|
||||
end
|
||||
|
||||
# from here on the head and tail of the union are located in the current characteristic section
|
||||
# from here on the head and tail of the train are located in the current characteristic section
|
||||
|
||||
# acceleration with all parts of the vehicle in the current characteristic section
|
||||
# acceleration with all parts of the train inside the current characteristic section
|
||||
while drivingCourse[end].v<characteristicSection.v_reach && drivingCourse[end].s<characteristicSection.s_end && drivingCourse[end].v>0.0
|
||||
push!(accelerationSection.waypoints, drivingCourse[end].i)
|
||||
|
||||
# traction effort and resisting forces (in N):
|
||||
drivingCourse[end].F_T=calculateTractiveEffort(drivingCourse[end].v, vehicle.tractiveEffortArray)
|
||||
drivingCourse[end].F_Rt=calculateTractionUnitResistance(drivingCourse[end].v, vehicle)
|
||||
drivingCourse[end].F_Rw=calculateWagonsResistance(drivingCourse[end].v, vehicle)
|
||||
drivingCourse[end].F_Runion=drivingCourse[end].F_Rt+drivingCourse[end].F_Rw
|
||||
drivingCourse[end].F_Rp=calculatePathResistance(drivingCourse[end].s, settings.massModel, vehicle, allCs)
|
||||
drivingCourse[end].F_R=drivingCourse[end].F_Runion+drivingCourse[end].F_Rp
|
||||
drivingCourse[end]=Waypoint(calculateForces!(drivingCourse[end], train, settings.massModel, allCs, accelerationSection.type))
|
||||
#07/16 drivingCourse[end].F_T=calculateTractiveEffort(drivingCourse[end].v, train.tractiveEffortArray)
|
||||
#07/16 drivingCourse[end].F_Rt=calculateTractionUnitResistance(drivingCourse[end].v, train)
|
||||
#07/16 drivingCourse[end].F_Rw=calculateWagonsResistance(drivingCourse[end].v, train)
|
||||
#07/16 drivingCourse[end].F_Runion=drivingCourse[end].F_Rt+drivingCourse[end].F_Rw
|
||||
#07/16 drivingCourse[end].F_Rp=calculatePathResistance(drivingCourse[end].s, settings.massModel, train, allCs)
|
||||
#07/16 drivingCourse[end].F_R=drivingCourse[end].F_Runion+drivingCourse[end].F_Rp
|
||||
|
||||
# acceleration (in m/s^2):
|
||||
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/vehicle.m_union/vehicle.ξ_union
|
||||
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train.m_union/train.ξ_union
|
||||
if drivingCourse[end].a==0.0
|
||||
error("ERROR: a=0.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)
|
||||
end
|
||||
|
@ -297,7 +334,7 @@ function addAccelerationPhase!(characteristicSection::CharacteristicSection, dri
|
|||
if settings.stepVariable=="s in m" # distance step method
|
||||
drivingCourse[end].Δs=currentStepSize # step size (in m)
|
||||
if ((drivingCourse[end-1].v/drivingCourse[end-1].a)^2+2*drivingCourse[end].Δs/drivingCourse[end-1].a)<0.0 || (drivingCourse[end-1].v^2+2*drivingCourse[end].Δs*drivingCourse[end-1].a)<0.0 # checking if the parts of the following square roots will be <0.0
|
||||
error("ERROR: The vehicle stops during the acceleration phase in CS",characteristicSection.id," m because the tractive effort is lower than the resistant forces.",
|
||||
error("ERROR: The train stops during the acceleration phase in CS",characteristicSection.id," m because the tractive effort is lower than the resistant forces.",
|
||||
" Before the stop the last point has the values s=",drivingCourse[end-1].s," 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.")
|
||||
end
|
||||
|
@ -330,7 +367,7 @@ function addAccelerationPhase!(characteristicSection::CharacteristicSection, dri
|
|||
elseif cycle==3 || cycle==4 # new step size is calculated with interpolation
|
||||
currentStepSize=abs((characteristicSection.v_reach-drivingCourse[end-1].v)*(drivingCourse[end].s-drivingCourse[end-1].s)/(drivingCourse[end].v-drivingCourse[end-1].v)) # step size (in m/s)
|
||||
elseif cycle==5
|
||||
error("ERROR: The vehicle stops during the acceleration phase in CS",characteristicSection.id," m because the tractive effort is lower than the resistant forces.",
|
||||
error("ERROR: The train stops during the acceleration phase in CS",characteristicSection.id," m because the tractive effort is lower than the resistant forces.",
|
||||
" Before the stop the last point has the values s=",drivingCourse[end-1].s," 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.")
|
||||
end
|
||||
|
@ -442,27 +479,27 @@ end #function addAccelerationPhase!
|
|||
|
||||
|
||||
## This function calculates the waypoints of the acceleration phase.
|
||||
function addAccelerationPhaseWithIntersection!(characteristicSection::CharacteristicSection, drivingCourse::Vector{Waypoint}, settings::Settings, vehicle::Vehicle, allCs::Vector{CharacteristicSection})
|
||||
function addAccelerationPhaseUntilBraking!(characteristicSection::CharacteristicSection, drivingCourse::Vector{Waypoint}, settings::Settings, train::Train, allCs::Vector{CharacteristicSection})
|
||||
if drivingCourse[end].v==0.0
|
||||
(characteristicSection, drivingCourse)=addStartingPhase!(characteristicSection, drivingCourse, settings, vehicle, allCs)
|
||||
(characteristicSection, drivingCourse)=addStartingPhase!(characteristicSection, drivingCourse, settings, train, allCs)
|
||||
end #if
|
||||
|
||||
# if the tail of the vehicle is still in a former characteristic section it has to be checked if its speed limit can be kept
|
||||
# if the tail of the train is still in a former characteristic section it has to be checked if its speed limit can be kept
|
||||
formerSpeedLimits=[]
|
||||
if characteristicSection.id>1 && drivingCourse[end].s-vehicle.l_union<characteristicSection.s_start
|
||||
if characteristicSection.id>1 && drivingCourse[end].s-train.l_union<characteristicSection.s_start
|
||||
if abs(allCs[characteristicSection.id-1].v_limit-drivingCourse[end].v)<0.000001
|
||||
s_braking=max(0.0, ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/vehicle.a_braking, digits=10))
|
||||
s_cruisingBeforeAcceleration=min(characteristicSection.s_end-drivingCourse[end].s-s_braking, vehicle.l_union)
|
||||
s_braking=max(0.0, ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=10))
|
||||
s_cruisingBeforeAcceleration=min(characteristicSection.s_end-drivingCourse[end].s-s_braking, train.l_union)
|
||||
|
||||
if s_cruisingBeforeAcceleration>0.0
|
||||
(characteristicSection, drivingCourse)=addCruisingPhase!(characteristicSection, drivingCourse, s_cruisingBeforeAcceleration, settings, vehicle, allCs, "cruisingBeforeAcceleration")
|
||||
(characteristicSection, drivingCourse)=addCruisingPhase!(characteristicSection, drivingCourse, s_cruisingBeforeAcceleration, settings, train, allCs, "cruisingBeforeAcceleration")
|
||||
else
|
||||
error("ERROR: cruisingBeforeAcceleration <=0.0 although it has to be >0.0 in CS ",characteristicSection.id)
|
||||
end
|
||||
else # detecting the lower speed limits of former sections
|
||||
csId=characteristicSection.id-1
|
||||
while csId>0 && drivingCourse[end].s-vehicle.l_union<allCs[csId].s_end
|
||||
if allCs[csId].v_limit<characteristicSection.v_limit # TODO: is the position of vehicles end < movingSection.s_start, v_limit of the first CS is used
|
||||
while csId>0 && drivingCourse[end].s-train.l_union<allCs[csId].s_end
|
||||
if allCs[csId].v_limit<characteristicSection.v_limit # TODO: is the position of trains end < movingSection.s_start, v_limit of the first CS is used
|
||||
push!(formerSpeedLimits, [allCs[csId].s_end, allCs[csId].v_limit])
|
||||
for i in 1:length(formerSpeedLimits)-1
|
||||
if formerSpeedLimits[i][2]<=formerSpeedLimits[end][2]
|
||||
|
@ -484,21 +521,22 @@ function addAccelerationPhaseWithIntersection!(characteristicSection::Characteri
|
|||
|
||||
currentStepSize=settings.stepSize # initializing the step size that can be reduced near intersections
|
||||
for cycle in 1:5 # first cycle with normal step size, second cycle with reduced step size, third cycle with more reduced step size. fourth and fith are needed in case the velocity approaches 0.0 or v_reach
|
||||
s_braking=max(0.0, ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/vehicle.a_braking, digits=10))
|
||||
s_braking=max(0.0, ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=10))
|
||||
|
||||
while length(formerSpeedLimits)>0 && drivingCourse[end].v<characteristicSection.v_reach && drivingCourse[end].s<characteristicSection.s_end && drivingCourse[end].v>0.0
|
||||
push!(accelerationSection.waypoints, drivingCourse[end].i)
|
||||
|
||||
# traction effort and resisting forces (in N):
|
||||
drivingCourse[end].F_T=calculateTractiveEffort(drivingCourse[end].v, vehicle.tractiveEffortArray)
|
||||
drivingCourse[end].F_Rt=calculateTractionUnitResistance(drivingCourse[end].v, vehicle)
|
||||
drivingCourse[end].F_Rw=calculateWagonsResistance(drivingCourse[end].v, vehicle)
|
||||
drivingCourse[end].F_Runion=drivingCourse[end].F_Rt+drivingCourse[end].F_Rw
|
||||
drivingCourse[end].F_Rp=calculatePathResistance(drivingCourse[end].s, settings.massModel, vehicle, allCs)
|
||||
drivingCourse[end].F_R=drivingCourse[end].F_Runion+drivingCourse[end].F_Rp
|
||||
drivingCourse[end]=Waypoint(calculateForces!(drivingCourse[end], train, settings.massModel, allCs, accelerationSection.type))
|
||||
#07/16 drivingCourse[end].F_T=calculateTractiveEffort(drivingCourse[end].v, train.tractiveEffortArray)
|
||||
#07/16 drivingCourse[end].F_Rt=calculateTractionUnitResistance(drivingCourse[end].v, train)
|
||||
#07/16 drivingCourse[end].F_Rw=calculateWagonsResistance(drivingCourse[end].v, train)
|
||||
#07/16 drivingCourse[end].F_Runion=drivingCourse[end].F_Rt+drivingCourse[end].F_Rw
|
||||
#07/16 drivingCourse[end].F_Rp=calculatePathResistance(drivingCourse[end].s, settings.massModel, train, allCs)
|
||||
#07/16 drivingCourse[end].F_R=drivingCourse[end].F_Runion+drivingCourse[end].F_Rp
|
||||
|
||||
# acceleration (in m/s^2):
|
||||
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/vehicle.m_union/vehicle.ξ_union
|
||||
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train.m_union/train.ξ_union
|
||||
if drivingCourse[end].a==0.0
|
||||
error("ERROR: a=0.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)
|
||||
end
|
||||
|
@ -511,7 +549,7 @@ function addAccelerationPhaseWithIntersection!(characteristicSection::Characteri
|
|||
if settings.stepVariable=="s in m" # distance step method
|
||||
drivingCourse[end].Δs=currentStepSize # step size (in m)
|
||||
if ((drivingCourse[end-1].v/drivingCourse[end-1].a)^2+2*drivingCourse[end].Δs/drivingCourse[end-1].a)<0.0 || (drivingCourse[end-1].v^2+2*drivingCourse[end].Δs*drivingCourse[end-1].a)<0.0 # checking if the parts of the following square roots will be <0.0
|
||||
error("ERROR: The vehicle stops during the acceleration phase in CS",characteristicSection.id," m because the tractive effort is lower than the resistant forces.",
|
||||
error("ERROR: The train stops during the acceleration phase in CS",characteristicSection.id," m because the tractive effort is lower than the resistant forces.",
|
||||
" Before the stop the last point has the values s=",drivingCourse[end-1].s," 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.")
|
||||
end
|
||||
|
@ -531,7 +569,7 @@ function addAccelerationPhaseWithIntersection!(characteristicSection::Characteri
|
|||
drivingCourse[end].t=drivingCourse[end-1].t+drivingCourse[end].Δt # point in time (in s)
|
||||
drivingCourse[end].v=drivingCourse[end-1].v+drivingCourse[end].Δv # velocity (in m/s)
|
||||
if drivingCourse[end].v<=0.0
|
||||
error("ERROR: The vehicle stops during the acceleration phase in CS",characteristicSection.id," m because the tractive effort is lower than the resistant forces.",
|
||||
error("ERROR: The train stops during the acceleration phase in CS",characteristicSection.id," m because the tractive effort is lower than the resistant forces.",
|
||||
" Before the stop the last point has the values s=",drivingCourse[end-1].s," 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.")
|
||||
end
|
||||
|
@ -540,7 +578,7 @@ function addAccelerationPhaseWithIntersection!(characteristicSection::Characteri
|
|||
drivingCourse[end].ΔE=drivingCourse[end].ΔW_T # energy consumption in this step (in Ws)
|
||||
drivingCourse[end].E=drivingCourse[end-1].E+drivingCourse[end].ΔE # energy consumption (in Ws)
|
||||
|
||||
while length(formerSpeedLimits)>0 && drivingCourse[end].s-vehicle.l_union>=formerSpeedLimits[end][1]
|
||||
while length(formerSpeedLimits)>0 && drivingCourse[end].s-train.l_union>=formerSpeedLimits[end][1]
|
||||
pop!(formerSpeedLimits)
|
||||
end
|
||||
if length(formerSpeedLimits)>0 && drivingCourse[end].v>formerSpeedLimits[end][2]
|
||||
|
@ -553,11 +591,11 @@ function addAccelerationPhaseWithIntersection!(characteristicSection::Characteri
|
|||
delete!(characteristicSection.behaviorSections, "cruisingBeforeAcceleration")
|
||||
end
|
||||
|
||||
s_braking=max(0.0, ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/vehicle.a_braking, digits=10))
|
||||
s_cruisingBeforeAcceleration=min(characteristicSection.s_end-drivingCourse[end].s-s_braking, formerSpeedLimits[end][1]-(drivingCourse[end].s-vehicle.l_union))
|
||||
s_braking=max(0.0, ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=10))
|
||||
s_cruisingBeforeAcceleration=min(characteristicSection.s_end-drivingCourse[end].s-s_braking, formerSpeedLimits[end][1]-(drivingCourse[end].s-train.l_union))
|
||||
|
||||
if s_cruisingBeforeAcceleration>0.0
|
||||
(characteristicSection, drivingCourse)=addCruisingPhase!(characteristicSection, drivingCourse, s_cruisingBeforeAcceleration, settings, vehicle, allCs, "cruisingBeforeAcceleration")
|
||||
(characteristicSection, drivingCourse)=addCruisingPhase!(characteristicSection, drivingCourse, s_cruisingBeforeAcceleration, settings, train, allCs, "cruisingBeforeAcceleration")
|
||||
else
|
||||
println("Error: cruisingBeforeAcceleration <=0.0 ")
|
||||
end
|
||||
|
@ -573,25 +611,26 @@ function addAccelerationPhaseWithIntersection!(characteristicSection::Characteri
|
|||
return (characteristicSection, drivingCourse)
|
||||
end
|
||||
end
|
||||
s_braking=max(0.0, ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/vehicle.a_braking, digits=10))
|
||||
s_braking=max(0.0, ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=10))
|
||||
end
|
||||
|
||||
# from here on the head and tail of the union are located in the current characteristic section
|
||||
# from here on the head and tail of the train are located in the current characteristic section
|
||||
|
||||
# acceleration with all parts of the vehicle in the current characteristic section
|
||||
# acceleration with all parts of the train in the current characteristic section
|
||||
while drivingCourse[end].v<characteristicSection.v_reach && (drivingCourse[end].s+s_braking)<characteristicSection.s_end && drivingCourse[end].v>0.0 # as long as s_i + s_braking < s_CSend
|
||||
push!(accelerationSection.waypoints, drivingCourse[end].i)
|
||||
|
||||
# traction effort and resisting forces (in N):
|
||||
drivingCourse[end].F_T=calculateTractiveEffort(drivingCourse[end].v, vehicle.tractiveEffortArray)
|
||||
drivingCourse[end].F_Rt=calculateTractionUnitResistance(drivingCourse[end].v, vehicle)
|
||||
drivingCourse[end].F_Rw=calculateWagonsResistance(drivingCourse[end].v, vehicle)
|
||||
drivingCourse[end].F_Runion=drivingCourse[end].F_Rt+drivingCourse[end].F_Rw
|
||||
drivingCourse[end].F_Rp=calculatePathResistance(drivingCourse[end].s, settings.massModel, vehicle, allCs)
|
||||
drivingCourse[end].F_R=drivingCourse[end].F_Runion+drivingCourse[end].F_Rp
|
||||
drivingCourse[end]=Waypoint(calculateForces!(drivingCourse[end], train, settings.massModel, allCs, accelerationSection.type))
|
||||
#07/16 drivingCourse[end].F_T=calculateTractiveEffort(drivingCourse[end].v, train.tractiveEffortArray)
|
||||
#07/16 drivingCourse[end].F_Rt=calculateTractionUnitResistance(drivingCourse[end].v, train)
|
||||
#07/16 drivingCourse[end].F_Rw=calculateWagonsResistance(drivingCourse[end].v, train)
|
||||
#07/16 drivingCourse[end].F_Runion=drivingCourse[end].F_Rt+drivingCourse[end].F_Rw
|
||||
#07/16 drivingCourse[end].F_Rp=calculatePathResistance(drivingCourse[end].s, settings.massModel, train, allCs)
|
||||
#07/16 drivingCourse[end].F_R=drivingCourse[end].F_Runion+drivingCourse[end].F_Rp
|
||||
|
||||
# acceleration (in m/s^2):
|
||||
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/vehicle.m_union/vehicle.ξ_union
|
||||
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train.m_union/train.ξ_union
|
||||
if drivingCourse[end].a==0.0
|
||||
error("ERROR: a=0.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)
|
||||
end
|
||||
|
@ -604,7 +643,7 @@ function addAccelerationPhaseWithIntersection!(characteristicSection::Characteri
|
|||
if settings.stepVariable=="s in m" # distance step method
|
||||
drivingCourse[end].Δs=currentStepSize # step size (in m)
|
||||
if ((drivingCourse[end-1].v/drivingCourse[end-1].a)^2+2*drivingCourse[end].Δs/drivingCourse[end-1].a)<0.0 || (drivingCourse[end-1].v^2+2*drivingCourse[end].Δs*drivingCourse[end-1].a)<0.0 # checking if the parts of the following square roots will be <0.0
|
||||
error("ERROR: The vehicle stops during the acceleration phase in CS",characteristicSection.id," m because the tractive effort is lower than the resistant forces.",
|
||||
error("ERROR: The train stops during the acceleration phase in CS",characteristicSection.id," m because the tractive effort is lower than the resistant forces.",
|
||||
" Before the stop the last point has the values s=",drivingCourse[end-1].s," 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.")
|
||||
end
|
||||
|
@ -628,7 +667,7 @@ function addAccelerationPhaseWithIntersection!(characteristicSection::Characteri
|
|||
drivingCourse[end].ΔE=drivingCourse[end].ΔW_T # energy consumption in this step (in Ws)
|
||||
drivingCourse[end].E=drivingCourse[end-1].E+drivingCourse[end].ΔE # energy consumption (in Ws)
|
||||
|
||||
s_braking=max(0.0, ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/vehicle.a_braking, digits=10))
|
||||
s_braking=max(0.0, ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=10))
|
||||
end #while
|
||||
|
||||
# checking which limit was reached and adjusting the currentStepSize for the next cycle
|
||||
|
@ -638,7 +677,7 @@ function addAccelerationPhaseWithIntersection!(characteristicSection::Characteri
|
|||
elseif cycle==3 || cycle==4 # new step size is calculated with interpolation
|
||||
currentStepSize=abs((characteristicSection.v_reach-drivingCourse[end-1].v)*(drivingCourse[end].s-drivingCourse[end-1].s)/(drivingCourse[end].v-drivingCourse[end-1].v)) # step size (in m/s)
|
||||
elseif cycle==5
|
||||
error("ERROR: The vehicle stops during the acceleration phase in CS",characteristicSection.id," m because the tractive effort is lower than the resistant forces.",
|
||||
error("ERROR: The train stops during the acceleration phase in CS",characteristicSection.id," m because the tractive effort is lower than the resistant forces.",
|
||||
" Before the stop the last point has the values s=",drivingCourse[end-1].s," 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.")
|
||||
end
|
||||
|
@ -653,9 +692,9 @@ function addAccelerationPhaseWithIntersection!(characteristicSection::Characteri
|
|||
elseif cycle==3
|
||||
## for the intersection:
|
||||
# correcting the step size for the last waypoint
|
||||
v_intersection=vehicle.a_braking*((drivingCourse[end].s-drivingCourse[end-1].s)/(drivingCourse[end].v-drivingCourse[end-1].v))+sign(drivingCourse[end].v-drivingCourse[end-1].v)*sqrt(vehicle.a_braking^2*((drivingCourse[end].s-drivingCourse[end-1].s)/(drivingCourse[end].v-drivingCourse[end-1].v))^2-2*vehicle.a_braking*(characteristicSection.s_end-drivingCourse[end-1].s+drivingCourse[end-1].v*((drivingCourse[end].s-drivingCourse[end-1].s)/(drivingCourse[end].v-drivingCourse[end-1].v)))+characteristicSection.v_exit^2)
|
||||
v_intersection=train.a_braking*((drivingCourse[end].s-drivingCourse[end-1].s)/(drivingCourse[end].v-drivingCourse[end-1].v))+sign(drivingCourse[end].v-drivingCourse[end-1].v)*sqrt(train.a_braking^2*((drivingCourse[end].s-drivingCourse[end-1].s)/(drivingCourse[end].v-drivingCourse[end-1].v))^2-2*train.a_braking*(characteristicSection.s_end-drivingCourse[end-1].s+drivingCourse[end-1].v*((drivingCourse[end].s-drivingCourse[end-1].s)/(drivingCourse[end].v-drivingCourse[end-1].v)))+characteristicSection.v_exit^2)
|
||||
|
||||
s_intersection=characteristicSection.s_end-(characteristicSection.v_exit^2-v_intersection^2)/2/vehicle.a_braking
|
||||
s_intersection=characteristicSection.s_end-(characteristicSection.v_exit^2-v_intersection^2)/2/train.a_braking
|
||||
# s_intersection_2=(v_intersection-drivingCourse[end-1].v)*(drivingCourse[end].s-drivingCourse[end-1].s)/(drivingCourse[end].v-drivingCourse[end-1].v)+drivingCourse[end-1].s
|
||||
|
||||
drivingCourse[end].v=v_intersection
|
||||
|
@ -729,12 +768,12 @@ function addAccelerationPhaseWithIntersection!(characteristicSection::Characteri
|
|||
merge!(characteristicSection.behaviorSections, Dict("acceleration"=>accelerationSection))
|
||||
end # else: just return the given waypoint number without changes due to the acceleration phase
|
||||
return (characteristicSection, drivingCourse)
|
||||
end #function addAccelerationPhaseWithIntersection!
|
||||
end #function addAccelerationPhaseUntilBraking!
|
||||
|
||||
|
||||
## This function calculates the waypoints of the cruising phase.
|
||||
# Therefore it gets its first waypoint and the characteristic section and returns the characteristic section including the behavior section for cruising if needed.
|
||||
function addCruisingPhase!(characteristicSection::CharacteristicSection, drivingCourse::Vector{Waypoint}, s_cruising::AbstractFloat, settings::Settings, vehicle::Vehicle, allCs::Vector{CharacteristicSection}, cruisingType::String)
|
||||
function addCruisingPhase!(characteristicSection::CharacteristicSection, drivingCourse::Vector{Waypoint}, s_cruising::AbstractFloat, settings::Settings, train::Train, allCs::Vector{CharacteristicSection}, cruisingType::String)
|
||||
if drivingCourse[end].v>0.0 && drivingCourse[end].v<=characteristicSection.v_reach && drivingCourse[end].s<characteristicSection.s_end
|
||||
cruisingSection=BehaviorSection()
|
||||
cruisingSection.type=cruisingType # type of behavior section
|
||||
|
@ -752,12 +791,13 @@ function addCruisingPhase!(characteristicSection::CharacteristicSection, driving
|
|||
push!(cruisingSection.waypoints, drivingCourse[end].i)
|
||||
|
||||
# traction effort and resisting forces (in N)
|
||||
drivingCourse[end].F_Rt=calculateTractionUnitResistance(drivingCourse[end].v, vehicle)
|
||||
drivingCourse[end].F_Rw=calculateWagonsResistance(drivingCourse[end].v, vehicle)
|
||||
drivingCourse[end].F_Runion=drivingCourse[end].F_Rt+drivingCourse[end].F_Rw
|
||||
drivingCourse[end].F_Rp=calculatePathResistance(drivingCourse[end].s, settings.massModel, vehicle, allCs)
|
||||
drivingCourse[end].F_R=drivingCourse[end].F_Runion+drivingCourse[end].F_Rp
|
||||
drivingCourse[end].F_T=min(max(0.0, drivingCourse[end].F_R), calculateTractiveEffort(drivingCourse[end].v, vehicle.tractiveEffortArray))
|
||||
drivingCourse[end]=Waypoint(calculateForces!(drivingCourse[end], train, settings.massModel, allCs, "cruising")) # TODO: or give cruisingSection.type instead of "cruising"?
|
||||
#07/16 drivingCourse[end].F_Rt=calculateTractionUnitResistance(drivingCourse[end].v, train)
|
||||
#07/16 drivingCourse[end].F_Rw=calculateWagonsResistance(drivingCourse[end].v, train)
|
||||
#07/16 drivingCourse[end].F_Runion=drivingCourse[end].F_Rt+drivingCourse[end].F_Rw
|
||||
#07/16 drivingCourse[end].F_Rp=calculatePathResistance(drivingCourse[end].s, settings.massModel, train, allCs)
|
||||
#07/16 drivingCourse[end].F_R=drivingCourse[end].F_Runion+drivingCourse[end].F_Rp
|
||||
#07/16 drivingCourse[end].F_T=min(max(0.0, drivingCourse[end].F_R), calculateTractiveEffort(drivingCourse[end].v, train.tractiveEffortArray))
|
||||
|
||||
|
||||
if drivingCourse[end].F_T>=drivingCourse[end].F_R
|
||||
|
@ -780,7 +820,7 @@ function addCruisingPhase!(characteristicSection::CharacteristicSection, driving
|
|||
drivingCourse[end].ΔE=drivingCourse[end].ΔW_T # energy consumption in this step (in Ws)
|
||||
drivingCourse[end].E=drivingCourse[end-1].E+drivingCourse[end].ΔE # energy consumption (in Ws)
|
||||
else
|
||||
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/vehicle.m_union/vehicle.ξ_union
|
||||
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train.m_union/train.ξ_union
|
||||
|
||||
# creating the next waypoint
|
||||
push!(drivingCourse, Waypoint())
|
||||
|
@ -821,7 +861,7 @@ function addCruisingPhase!(characteristicSection::CharacteristicSection, driving
|
|||
if currentStepSize>settings.stepSize/100.0
|
||||
currentStepSize=currentStepSize/10.0
|
||||
else
|
||||
error("ERROR: The vehicle stops during the acceleration phase in CS",characteristicSection.id," m because the tractive effort is lower than the resistant forces.",
|
||||
error("ERROR: The train stops during the acceleration phase in CS",characteristicSection.id," m because the tractive effort is lower than the resistant forces.",
|
||||
" Before the stop the last point has the values s=",drivingCourse[end-1].s," 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.")
|
||||
end
|
||||
|
@ -852,7 +892,7 @@ end #function addCruisingPhase!
|
|||
|
||||
## This function calculates the waypoints of the coasting phase.
|
||||
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the coasting section
|
||||
function addCoastingPhaseWithIntersection!(characteristicSection::CharacteristicSection, drivingCourse::Vector{Waypoint}, settings::Settings, vehicle::Vehicle, allCs::Vector{CharacteristicSection})
|
||||
function addCoastingPhaseUntilBraking!(characteristicSection::CharacteristicSection, drivingCourse::Vector{Waypoint}, settings::Settings, train::Train, allCs::Vector{CharacteristicSection})
|
||||
if drivingCourse[end].v>characteristicSection.v_exit && drivingCourse[end].s<characteristicSection.s_end
|
||||
coastingSection=BehaviorSection()
|
||||
coastingSection.type="coasting" # type of behavior section
|
||||
|
@ -861,20 +901,21 @@ function addCoastingPhaseWithIntersection!(characteristicSection::Characteristic
|
|||
|
||||
currentStepSize=settings.stepSize # initializing the step size that can be reduced near intersections
|
||||
for cycle in 1:3 # first cycle with normal step size, second cycle with reduced step size, third cycle with more reduced step size
|
||||
s_braking=ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/vehicle.a_braking, digits=10)
|
||||
s_braking=ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=10)
|
||||
while drivingCourse[end].v>characteristicSection.v_exit && drivingCourse[end].v<=characteristicSection.v_reach && (drivingCourse[end].s+s_braking)<characteristicSection.s_end # as long as s_i + s_braking < s_CSend
|
||||
push!(coastingSection.waypoints, drivingCourse[end].i)
|
||||
|
||||
# traction effort and resisting forces (in N):
|
||||
drivingCourse[end].F_T=0
|
||||
drivingCourse[end].F_Rt=calculateTractionUnitResistance(drivingCourse[end].v, vehicle)
|
||||
drivingCourse[end].F_Rw=calculateWagonsResistance(drivingCourse[end].v, vehicle)
|
||||
drivingCourse[end].F_Runion=drivingCourse[end].F_Rt+drivingCourse[end].F_Rw
|
||||
drivingCourse[end].F_Rp=calculatePathResistance(drivingCourse[end].s, settings.massModel, vehicle, allCs)
|
||||
drivingCourse[end].F_R=drivingCourse[end].F_Runion+drivingCourse[end].F_Rp
|
||||
drivingCourse[end]=Waypoint(calculateForces!(drivingCourse[end], train, settings.massModel, allCs, coastingSection.type))
|
||||
#07/16 drivingCourse[end].F_T=0
|
||||
#07/16 drivingCourse[end].F_Rt=calculateTractionUnitResistance(drivingCourse[end].v, train)
|
||||
#07/16 drivingCourse[end].F_Rw=calculateWagonsResistance(drivingCourse[end].v, train)
|
||||
#07/16 drivingCourse[end].F_Runion=drivingCourse[end].F_Rt+drivingCourse[end].F_Rw
|
||||
#07/16 drivingCourse[end].F_Rp=calculatePathResistance(drivingCourse[end].s, settings.massModel, train, allCs)
|
||||
#07/16 drivingCourse[end].F_R=drivingCourse[end].F_Runion+drivingCourse[end].F_Rp
|
||||
|
||||
# acceleration (in m/s^2):
|
||||
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/vehicle.m_union/vehicle.ξ_union
|
||||
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train.m_union/train.ξ_union
|
||||
|
||||
# creating the next waypoint
|
||||
push!(drivingCourse, Waypoint())
|
||||
|
@ -896,7 +937,7 @@ function addCoastingPhaseWithIntersection!(characteristicSection::Characteristic
|
|||
end #if
|
||||
|
||||
drivingCourse[end].v=drivingCourse[end-1].v+drivingCourse[end].Δv # velocity (in m/s)
|
||||
if drivingCourse[end].v>characteristicSection.v_reach # if the vehicle gets to fast, it will brake
|
||||
if drivingCourse[end].v>characteristicSection.v_reach # if the train gets to fast, it will brake
|
||||
drivingCourse[end].v=characteristicSection.v_reach
|
||||
drivingCourse[end].Δv=characteristicSection.v_reach-drivingCourse[end-1].v # step size (in m/s)
|
||||
if drivingCourse[end].Δv==0.0
|
||||
|
@ -921,7 +962,7 @@ function addCoastingPhaseWithIntersection!(characteristicSection::Characteristic
|
|||
drivingCourse[end].ΔE=drivingCourse[end].ΔW_T # energy consumption in this step (in Ws)
|
||||
drivingCourse[end].E=drivingCourse[end-1].E+drivingCourse[end].ΔE # energy consumption (in Ws)
|
||||
|
||||
s_braking=ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/vehicle.a_braking)
|
||||
s_braking=ceil((characteristicSection.v_exit^2-drivingCourse[end].v^2)/2/train.a_braking)
|
||||
end # while
|
||||
|
||||
# checking which limit was reached and adjusting the currentStepSize for the next cycle
|
||||
|
@ -931,9 +972,9 @@ function addCoastingPhaseWithIntersection!(characteristicSection::Characteristic
|
|||
pop!(drivingCourse)
|
||||
pop!(coastingSection.waypoints) # TODO: hier soll wohl ein leeres Array gepoppt werden ..
|
||||
elseif cycle==3
|
||||
v_intersection=vehicle.a_braking*((drivingCourse[end].s-drivingCourse[end-1].s)/(drivingCourse[end].v-drivingCourse[end-1].v))+sign(drivingCourse[end].v-drivingCourse[end-1].v)*sqrt(vehicle.a_braking^2*((drivingCourse[end].s-drivingCourse[end-1].s)/(drivingCourse[end].v-drivingCourse[end-1].v))^2-2*vehicle.a_braking*(characteristicSection.s_end-drivingCourse[end-1].s+drivingCourse[end-1].v*((drivingCourse[end].s-drivingCourse[end-1].s)/(drivingCourse[end].v-drivingCourse[end-1].v)))+characteristicSection.v_exit^2)
|
||||
v_intersection=train.a_braking*((drivingCourse[end].s-drivingCourse[end-1].s)/(drivingCourse[end].v-drivingCourse[end-1].v))+sign(drivingCourse[end].v-drivingCourse[end-1].v)*sqrt(train.a_braking^2*((drivingCourse[end].s-drivingCourse[end-1].s)/(drivingCourse[end].v-drivingCourse[end-1].v))^2-2*train.a_braking*(characteristicSection.s_end-drivingCourse[end-1].s+drivingCourse[end-1].v*((drivingCourse[end].s-drivingCourse[end-1].s)/(drivingCourse[end].v-drivingCourse[end-1].v)))+characteristicSection.v_exit^2)
|
||||
|
||||
s_intersection=characteristicSection.s_end-(characteristicSection.v_exit^2-v_intersection^2)/2/vehicle.a_braking
|
||||
s_intersection=characteristicSection.s_end-(characteristicSection.v_exit^2-v_intersection^2)/2/train.a_braking
|
||||
# s_intersection_2=(v_intersection-drivingCourse[end-1].v)*(drivingCourse[end].s-drivingCourse[end-1].s)/(drivingCourse[end].v-drivingCourse[end-1].v)+drivingCourse[end-1].s
|
||||
|
||||
drivingCourse[end].v=v_intersection
|
||||
|
@ -998,11 +1039,11 @@ function addCoastingPhaseWithIntersection!(characteristicSection::Characteristic
|
|||
merge!(characteristicSection.behaviorSections, Dict("coasting"=>coastingSection))
|
||||
end ## else: just return the given waypoint number without changes due to the coasting phase
|
||||
return (characteristicSection, drivingCourse)
|
||||
end #function addCoastingPhaseWithIntersection!
|
||||
end #function addCoastingPhaseUntilBraking!
|
||||
|
||||
## This function calculates the waypoints of the braking phase.
|
||||
# Therefore it gets its first waypoint and the characteristic section and returns the characteristic section including the behavior section for braking if needed.
|
||||
function addBrakingPhase!(characteristicSection::CharacteristicSection, drivingCourse::Vector{Waypoint}, massModel::String, vehicle::Vehicle, allCs::Vector{CharacteristicSection}) #, s_braking::AbstractFloat)
|
||||
function addBrakingPhase!(characteristicSection::CharacteristicSection, drivingCourse::Vector{Waypoint}, massModel::String, train::Train, allCs::Vector{CharacteristicSection}) #, s_braking::AbstractFloat)
|
||||
if drivingCourse[end].v>characteristicSection.v_exit && drivingCourse[end].s<characteristicSection.s_end
|
||||
brakingSection=BehaviorSection()
|
||||
brakingSection.type="braking" # type of behavior section
|
||||
|
@ -1012,12 +1053,13 @@ function addBrakingPhase!(characteristicSection::CharacteristicSection, drivingC
|
|||
push!(brakingSection.waypoints, drivingCourse[end].i) # refering from the breaking section to the first of its waypoints
|
||||
|
||||
# traction effort and resisting forces (in N)
|
||||
drivingCourse[end].F_Rt=calculateTractionUnitResistance(drivingCourse[end].v, vehicle)
|
||||
drivingCourse[end].F_Rw=calculateWagonsResistance(drivingCourse[end].v, vehicle)
|
||||
drivingCourse[end].F_Runion=drivingCourse[end].F_Rt+drivingCourse[end].F_Rw
|
||||
drivingCourse[end].F_Rp=calculatePathResistance(drivingCourse[end].s, massModel, vehicle, allCs)
|
||||
drivingCourse[end].F_R=drivingCourse[end].F_Runion+drivingCourse[end].F_Rp
|
||||
drivingCourse[end].F_T=0.0
|
||||
drivingCourse[end]=Waypoint(calculateForces!(drivingCourse[end], train, massModel, allCs, brakingSection.type))
|
||||
#07/16 drivingCourse[end].F_Rt=calculateTractionUnitResistance(drivingCourse[end].v, train)
|
||||
#07/16 drivingCourse[end].F_Rw=calculateWagonsResistance(drivingCourse[end].v, train)
|
||||
#07/16 drivingCourse[end].F_Runion=drivingCourse[end].F_Rt+drivingCourse[end].F_Rw
|
||||
#07/16 drivingCourse[end].F_Rp=calculatePathResistance(drivingCourse[end].s, massModel, train, allCs)
|
||||
#07/16 drivingCourse[end].F_R=drivingCourse[end].F_Runion+drivingCourse[end].F_Rp
|
||||
#07/16 drivingCourse[end].F_T=0.0
|
||||
|
||||
push!(drivingCourse, Waypoint())
|
||||
drivingCourse[end].i=drivingCourse[end-1].i+1 # incrementing the number of the waypoint
|
||||
|
@ -1029,8 +1071,8 @@ function addBrakingPhase!(characteristicSection::CharacteristicSection, drivingC
|
|||
drivingCourse[end].Δv=drivingCourse[end].v-drivingCourse[end-1].v # step size (in m/s)
|
||||
|
||||
drivingCourse[end-1].a=round((drivingCourse[end].v^2-drivingCourse[end-1].v^2)/2/drivingCourse[end].Δs, digits=10) # acceleration (in m/s^2) (rounding because it should not be less than a_braking
|
||||
if drivingCourse[end-1].a<vehicle.a_braking || drivingCourse[end-1].a>=0.0
|
||||
println("Warning: a_braking gets to high in CS ",characteristicSection.id, " with a=",drivingCourse[end-1].a ," > ",vehicle.a_braking)
|
||||
if drivingCourse[end-1].a<train.a_braking || drivingCourse[end-1].a>=0.0
|
||||
println("Warning: a_braking gets to high in CS ",characteristicSection.id, " with a=",drivingCourse[end-1].a ," > ",train.a_braking)
|
||||
end
|
||||
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)
|
||||
|
@ -1055,4 +1097,4 @@ function addBrakingPhase!(characteristicSection::CharacteristicSection, drivingC
|
|||
end #function addBrakingPhase!
|
||||
|
||||
|
||||
end #module
|
||||
end #module MovingPhases
|
|
@ -0,0 +1,344 @@
|
|||
module OperationModes
|
||||
|
||||
using ..types
|
||||
|
||||
include("./MovingPhases.jl")
|
||||
include("./EnergySaving.jl")
|
||||
using .MovingPhases
|
||||
using .EnergySaving
|
||||
|
||||
export simulateMinimumRunningTime!, simulateMinimumEnergyConsumption
|
||||
|
||||
function simulateMinimumRunningTime!(movingSection::MovingSection, settings::Settings, train::Train)
|
||||
# simulate a train run focussing on using the minimum possible running time
|
||||
startingPoint=Waypoint()
|
||||
startingPoint.i=1
|
||||
startingPoint.s=movingSection.characteristicSections[1].s_start
|
||||
drivingCourse=[startingPoint] # List of waypoints
|
||||
|
||||
for csId in 1:length(movingSection.characteristicSections)
|
||||
# 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=10)) # ceil is used to be sure that the train stops at s_end 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
|
||||
|
||||
# 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")
|
||||
delete!(movingSection.characteristicSections[csId].behaviorSections, "acceleration")
|
||||
delete!(movingSection.characteristicSections[csId].behaviorSections, "cruising")
|
||||
movingSection.characteristicSections[csId].E_total=0.0
|
||||
movingSection.characteristicSections[csId].t_total=0.0
|
||||
|
||||
if s_cruisingBeforeAcceleration == movingSection.characteristicSections[csId].s_total
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruisingBeforeAcceleration, settings, train, movingSection.characteristicSections, "cruisingBeforeAcceleration")
|
||||
elseif s_cruising == movingSection.characteristicSections[csId].s_total
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruising, settings, train, movingSection.characteristicSections, "cruising")
|
||||
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
|
||||
(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
|
||||
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)
|
||||
end
|
||||
|
||||
s_braking=max(0.0, ceil((movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=10)) # 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
|
||||
|
||||
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
|
||||
(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=10)) # ceil is used to be sure that the train stops at s_end 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)
|
||||
end #if
|
||||
|
||||
if drivingCourse[end].s < movingSection.characteristicSections[csId].s_end
|
||||
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)
|
||||
end
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruising, settings, train, movingSection.characteristicSections, "cruising")
|
||||
end
|
||||
end #for
|
||||
|
||||
movingSection.t_total=drivingCourse[end].t # total running time (in s)
|
||||
movingSection.E_total=drivingCourse[end].E # total energy consumption (in Ws)
|
||||
|
||||
# TODO: calculate some values of the last waypoint
|
||||
|
||||
return (movingSection, drivingCourse)
|
||||
end #function simulateMinimumRunningTime
|
||||
|
||||
|
||||
function simulateMinimumEnergyConsumption(movingSectionMinimumRunningTime::MovingSection, drivingCourseMinimumRunningTime::Vector{Waypoint}, settings::Settings, train::Train)
|
||||
# simulate a train run focussing on using the minimum possible energy consumption
|
||||
# booleans for choosing which methods are used for saving energy
|
||||
doMethod1=true
|
||||
doMethod2=true
|
||||
doCombinationOfMethods=true
|
||||
|
||||
#create a new moving section for the minimum energy consumption
|
||||
movingSectionOriginal=MovingSection(movingSectionMinimumRunningTime)
|
||||
|
||||
# create a new driving course for the minimum energy consumption
|
||||
drivingCourseOriginal=Waypoint[]
|
||||
for i in 1:length(drivingCourseMinimumRunningTime)
|
||||
push!(drivingCourseOriginal, Waypoint(drivingCourseMinimumRunningTime[i])) # List of waypoints till the start of energy saving
|
||||
end
|
||||
|
||||
# calculate the recovery time
|
||||
movingSectionOriginal.t_recovery=calculateRecoveryTime(movingSectionOriginal.s_total, movingSectionOriginal.t_total, train)
|
||||
movingSectionOriginal.t_recoveryAvailable=movingSectionOriginal.t_recovery
|
||||
|
||||
# create arrays for each method with all the available energy saving modifications
|
||||
energySavingModificationsWithCoasting=EnergySavingModification[]
|
||||
energySavingModificationsWithMaximumSpeed=EnergySavingModification[]
|
||||
energySavingModificationsWithCombination=EnergySavingModification[]
|
||||
|
||||
for csId in 1:length(movingSectionOriginal.characteristicSections)
|
||||
# method 1: increase coasting
|
||||
if doMethod1 == true
|
||||
modificationType = "increasing coasting"
|
||||
energySavingModification = modifyCs(movingSectionOriginal, drivingCourseOriginal, csId, modificationType, settings, train)
|
||||
push!(energySavingModificationsWithCoasting, energySavingModification)
|
||||
end #if doMethod1
|
||||
|
||||
# method 2: accelerate to a lower v_reach
|
||||
if doMethod2 == true
|
||||
modificationType = "decreasing maximum velocity"
|
||||
energySavingModification = modifyCs(movingSectionOriginal, drivingCourseOriginal, csId, modificationType, settings, train)
|
||||
push!(energySavingModificationsWithMaximumSpeed, energySavingModification)
|
||||
end #if doMethod2
|
||||
|
||||
# calculate the combination of the previous methods
|
||||
if doCombinationOfMethods == true
|
||||
modificationType = "combination of energy saving methods"
|
||||
energySavingModification = modifyCs(movingSectionOriginal, drivingCourseOriginal, csId, modificationType, settings, train)
|
||||
push!(energySavingModificationsWithCombination, energySavingModification)
|
||||
end #if
|
||||
end # for
|
||||
|
||||
while movingSectionOriginal.t_recoveryAvailable > 0.0
|
||||
# comparison of modifications
|
||||
ratioMax=0.0
|
||||
csIdMax=0
|
||||
typeMax="none"
|
||||
(energySavingModificationsWithMaximumSpeed, ratioMax, csIdMax, typeMax) = findBestModification(energySavingModificationsWithMaximumSpeed, ratioMax, csIdMax, typeMax, movingSectionOriginal.t_recoveryAvailable)
|
||||
(energySavingModificationsWithCoasting, ratioMax, csIdMax, typeMax) = findBestModification(energySavingModificationsWithCoasting, ratioMax, csIdMax, typeMax, movingSectionOriginal.t_recoveryAvailable)
|
||||
(energySavingModificationsWithCombination, ratioMax, csIdMax, typeMax) = findBestModification(energySavingModificationsWithCombination, ratioMax, csIdMax, typeMax, movingSectionOriginal.t_recoveryAvailable)
|
||||
|
||||
# select the most efficient modification and update the original characteristicSection, drivingCourse and movingSection
|
||||
# in case none of the modifications has a ratio>0 stop the calculation
|
||||
if typeMax=="none"
|
||||
break
|
||||
elseif typeMax=="increasing coasting"
|
||||
# println("Energy saving modification number ",length(movingSectionOriginal.energySavingModifications)+1," (coasting) in CS ",csIdMax ," Δt=",energySavingModificationsWithCoasting[csIdMax].Δt," ΔE=", energySavingModificationsWithCoasting[csIdMax].ΔE," t_recoveryAvailable=", movingSectionOriginal.t_recoveryAvailable-energySavingModificationsWithCoasting[csIdMax].Δt)
|
||||
push!(movingSectionOriginal.energySavingModifications, energySavingModificationsWithCoasting[csIdMax])
|
||||
elseif typeMax=="decreasing maximum velocity"
|
||||
push!(movingSectionOriginal.energySavingModifications, energySavingModificationsWithMaximumSpeed[csIdMax])
|
||||
elseif typeMax=="combination of energy saving methods"
|
||||
push!(movingSectionOriginal.energySavingModifications, energySavingModificationsWithCombination[csIdMax])
|
||||
end #if
|
||||
|
||||
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()))))))).waypoints[end]
|
||||
|
||||
# create new driving course
|
||||
drivingCourseNew=Vector{Waypoint}()
|
||||
for i in 1:length(movingSectionOriginal.energySavingModifications[end].drivingCourseModified)
|
||||
push!(drivingCourseNew, Waypoint(movingSectionOriginal.energySavingModifications[end].drivingCourseModified[i]))
|
||||
end
|
||||
|
||||
# # for testing if the modifications driving course and the original one have the same speed value at their transition point
|
||||
# if lastIdOfSelectedCsOriginal+1<=drivingCourseOriginal[end].i
|
||||
# if drivingCourseOriginal[lastIdOfSelectedCsOriginal].v-drivingCourseNew[end].v!=0.0
|
||||
# println("INFO: Inconsistency while adding the CS",csIdMax," that has been modified for consuming less energy. The difference at its end is ",(drivingCourseOriginal[lastIdOfSelectedCsOriginal].v-drivingCourseNew[end].v)," m/s."
|
||||
# end
|
||||
# end # for testing
|
||||
|
||||
#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].F_R=drivingCourseOriginal[lastIdOfSelectedCsOriginal].F_R
|
||||
drivingCourseNew[end].a=drivingCourseOriginal[lastIdOfSelectedCsOriginal].a
|
||||
|
||||
endOfModificationId=drivingCourseNew[end].i # is needed for updating the other modified driving courses
|
||||
difference=endOfModificationId-lastIdOfSelectedCsOriginal
|
||||
|
||||
i=lastIdOfSelectedCsOriginal+1
|
||||
while i <= length(drivingCourseOriginal)
|
||||
push!(drivingCourseNew, Waypoint(drivingCourseOriginal[i]))
|
||||
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
|
||||
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)
|
||||
|
||||
# update all the waypoint references in the behaviour sections of the following characteristic sections and the other modified characteristic sections
|
||||
if difference!= 0
|
||||
# update the waypoint references in the behaviour sections of the following characteristic sections
|
||||
allBs=["starting", "cruisingBeforeAcceleration", "acceleration", "cruising", "coasting", "cruisingAfterCoasting", "braking"]
|
||||
for csId in csIdMax+1:length(movingSectionOriginal.characteristicSections)
|
||||
for bs in 1: length(allBs)
|
||||
if haskey(movingSectionOriginal.characteristicSections[csId].behaviorSections, allBs[bs])
|
||||
for point in 1:length(get(movingSectionOriginal.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).waypoints)
|
||||
get(movingSectionOriginal.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).waypoints[point]=get(movingSectionOriginal.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).waypoints[point]+difference
|
||||
end
|
||||
end #if
|
||||
end #for
|
||||
end #for
|
||||
|
||||
# update the waypoints in the following modified charateristic sections and the following points in the driving course
|
||||
energySavingModificationsWithCoasting = updateEnergySavingModifications(energySavingModificationsWithCoasting, csIdMax, drivingCourseNew, endOfModificationId, lastIdOfSelectedCsOriginal)
|
||||
energySavingModificationsWithMaximumSpeed = updateEnergySavingModifications(energySavingModificationsWithMaximumSpeed, csIdMax, drivingCourseNew, endOfModificationId, lastIdOfSelectedCsOriginal)
|
||||
energySavingModificationsWithCombination = updateEnergySavingModifications(energySavingModificationsWithCombination, csIdMax, drivingCourseNew, endOfModificationId, lastIdOfSelectedCsOriginal)
|
||||
end # if difference
|
||||
|
||||
# modify new CS for the considered methods
|
||||
# method 1: increase coasting
|
||||
if doMethod1==true
|
||||
modificationType = "increasing coasting"
|
||||
energySavingModification = modifyCs(movingSectionOriginal, drivingCourseOriginal, csIdMax, modificationType, settings, train)
|
||||
energySavingModificationsWithCoasting[csIdMax]=energySavingModification
|
||||
end #if if doMethod1
|
||||
|
||||
# method 2: accelerate to a lower v_reach
|
||||
if doMethod2==true
|
||||
modificationType = "decreasing maximum velocity"
|
||||
energySavingModification = modifyCs(movingSectionOriginal, drivingCourseOriginal, csIdMax, modificationType, settings, train)
|
||||
energySavingModificationsWithMaximumSpeed[csIdMax]=energySavingModification
|
||||
end #if if doMethod
|
||||
|
||||
# combination of both methods
|
||||
if doCombinationOfMethods==true
|
||||
modificationType = "combination of energy saving methods"
|
||||
energySavingModification = modifyCs(movingSectionOriginal, drivingCourseOriginal, csIdMax, modificationType, settings, train)
|
||||
energySavingModificationsWithCombination[csIdMax]=energySavingModification
|
||||
end #if doCombinationOfMethods
|
||||
end # while
|
||||
|
||||
# TODO: calculate some values of the last waypoint
|
||||
# println("t_recoveryAvailable=",movingSectionOriginal.t_recoveryAvailable)
|
||||
return (movingSectionOriginal, drivingCourseOriginal)
|
||||
end #function simulateMinimumEnergyConsumption
|
||||
|
||||
|
||||
function modifyCs(movingSectionOriginal::MovingSection, drivingCourseOriginal::Vector{Waypoint}, csId::Integer, modificationType::String, settings::Settings, train::Train)
|
||||
#println("drin: ",modificationType)
|
||||
if modificationType == "increasing coasting"
|
||||
# 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
|
||||
(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
|
||||
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=combineEnergySavingMethods(movingSectionOriginal.characteristicSections[csId], drivingCourseOriginal, settings, train, movingSectionOriginal.characteristicSections, movingSectionOriginal.t_recoveryAvailable)
|
||||
else
|
||||
return EnergySavingModification()
|
||||
end
|
||||
|
||||
energySavingModification = EnergySavingModification()
|
||||
if new
|
||||
energySavingModification.csId = csId # identifier of the characteristic section
|
||||
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)
|
||||
if energySavingModification.Δt <= movingSectionOriginal.t_recoveryAvailable && energySavingModification.ΔE >= 0.0
|
||||
#*** TODO: check why "sign" is needed here
|
||||
# if modificationType == "combination of energy saving methods"
|
||||
energySavingModification.ratio=sign(energySavingModification.Δt)*energySavingModification.ΔE/energySavingModification.Δt # ratio of ΔE and Δt (in Ws/s)
|
||||
# else
|
||||
# energySavingModification.ratio = energySavingModification.ΔE / energySavingModification.Δt # ratio of ΔE and Δt (in Ws/s)
|
||||
# end
|
||||
# ***
|
||||
elseif energySavingModification.Δt == 0.0
|
||||
energySavingModification.ratio = energySavingModification.ΔE/0.000000001
|
||||
else # Δt is to high or ΔE < 0.0 Ws
|
||||
energySavingModification.ratio = 0.0
|
||||
end
|
||||
end
|
||||
return energySavingModification
|
||||
end #function modifyCs
|
||||
|
||||
|
||||
function findBestModification(energySavingModifications::Vector{EnergySavingModification}, ratioMax::AbstractFloat, csIdMax::Integer, typeMax::String, t_recoveryAvailable::AbstractFloat)
|
||||
for modNr in 1:length(energySavingModifications)
|
||||
if energySavingModifications[modNr].ratio > ratioMax
|
||||
if energySavingModifications[modNr].Δt <= t_recoveryAvailable
|
||||
ratioMax=energySavingModifications[modNr].ratio
|
||||
csIdMax=energySavingModifications[modNr].csId
|
||||
typeMax=energySavingModifications[modNr].type
|
||||
else # Δt is to high
|
||||
energySavingModifications[modNr].ratio=0.0
|
||||
end #if
|
||||
end #if
|
||||
end #for
|
||||
return (energySavingModifications, ratioMax, csIdMax, typeMax)
|
||||
end #function findBestModification
|
||||
|
||||
function updateEnergySavingModifications(energySavingModifications::Vector{EnergySavingModification}, csIdMax::Integer, drivingCourseNew::Vector{Waypoint}, endOfModificationId::Integer, lastIdOfSelectedCsOriginal::Integer)
|
||||
allBs = ["starting", "cruisingBeforeAcceleration", "acceleration", "cruising", "coasting", "cruisingAfterCoasting", "braking"]
|
||||
difference = endOfModificationId-lastIdOfSelectedCsOriginal
|
||||
for modNr in csIdMax+1:length(energySavingModifications)
|
||||
if energySavingModifications[modNr].ratio>0
|
||||
# update the behavior sections of the modified charateristic section
|
||||
for bs in 1: length(allBs)
|
||||
if haskey(energySavingModifications[modNr].csModified.behaviorSections, allBs[bs])
|
||||
for point in 1:length(get(energySavingModifications[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).waypoints)
|
||||
get(energySavingModifications[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).waypoints[point] = get(energySavingModifications[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).waypoints[point]+difference
|
||||
end
|
||||
end #if
|
||||
end #for
|
||||
|
||||
# correct the points of previous CS in the modified driving course. Copy the new driving course till the beginning of the current CS and change total values of the current modified CS waypoints accordingly
|
||||
drivingCourseModifiedNew=Vector{Waypoint}()
|
||||
for i in 1:endOfModificationId
|
||||
push!(drivingCourseModifiedNew, Waypoint(drivingCourseNew[i]))
|
||||
end # for
|
||||
i=lastIdOfSelectedCsOriginal+1
|
||||
while i <= length(energySavingModifications[modNr].drivingCourseModified)
|
||||
push!(drivingCourseModifiedNew, Waypoint(energySavingModifications[modNr].drivingCourseModified[i]))
|
||||
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
|
||||
i=i+1
|
||||
end # while
|
||||
|
||||
energySavingModifications[modNr].drivingCourseModified = drivingCourseModifiedNew
|
||||
end #if
|
||||
end #for
|
||||
|
||||
return energySavingModifications
|
||||
end #function updateEnergySavingModifications
|
||||
|
||||
end #module OperationModes
|
|
@ -1,4 +1,4 @@
|
|||
module RailwayDrivingDynamicsOutput
|
||||
module Output
|
||||
|
||||
using ..types
|
||||
using Plots
|
||||
|
@ -7,26 +7,26 @@ using CSV, DataFrames, Dates
|
|||
export createOutput
|
||||
export plotDrivingCourse, printImportantValues, printSectionInformation # functions for showing results during the development
|
||||
|
||||
function createOutput(settings::Settings, pathName::String, vehicleName::String, drivingCourse::Vector{Waypoint}, movingSection::MovingSection)
|
||||
function createOutput(settings::Settings, pathName::String, trainName::String, drivingCourse::Vector{Waypoint}, movingSection::MovingSection)
|
||||
# method of function createOutput for one operation mode
|
||||
if settings.typeOfOutput == "CSV"
|
||||
return createOutputCsv(settings, pathName, vehicleName, drivingCourse, movingSection)
|
||||
return createOutputCsv(settings, pathName, trainName, drivingCourse, movingSection)
|
||||
else
|
||||
return createOutputDict(settings, pathName, vehicleName, drivingCourse, movingSection)
|
||||
return createOutputDict(settings, pathName, trainName, drivingCourse, movingSection)
|
||||
end
|
||||
end # funtion createOutput
|
||||
|
||||
function createOutput(settings::Settings, pathName::String, vehicleName::String, drivingCourseMinimumRunningTime::Vector{Waypoint}, movingSectionMinimumRunningTime::MovingSection, drivingCourseMinimumEnergyConsumption::Vector{Waypoint}, movingSectionMinimumEnergyConsumption::MovingSection)
|
||||
function createOutput(settings::Settings, pathName::String, trainName::String, drivingCourseMinimumRunningTime::Vector{Waypoint}, movingSectionMinimumRunningTime::MovingSection, drivingCourseMinimumEnergyConsumption::Vector{Waypoint}, movingSectionMinimumEnergyConsumption::MovingSection)
|
||||
# method of function createOutput for two operation modes
|
||||
if settings.typeOfOutput == "CSV"
|
||||
return createOutputCsv(settings, pathName, vehicleName, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||
return createOutputCsv(settings, pathName, trainName, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||
else
|
||||
return createOutputDict(settings, pathName, vehicleName, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||
return createOutputDict(settings, pathName, trainName, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||
end
|
||||
end # funtion createOutput
|
||||
|
||||
|
||||
function createOutputDict(settings::Settings, pathName::String, vehicleName::String, drivingCourse::Vector{Waypoint}, movingSection::MovingSection)
|
||||
function createOutputDict(settings::Settings, pathName::String, trainName::String, drivingCourse::Vector{Waypoint}, movingSection::MovingSection)
|
||||
# method of function createOutputDict for one operation mode
|
||||
if settings.operationModeMinimumRunningTime
|
||||
if settings.operationModeMinimumEnergyConsumption
|
||||
|
@ -44,7 +44,7 @@ function createOutputDict(settings::Settings, pathName::String, vehicleName::Str
|
|||
end
|
||||
end
|
||||
|
||||
outputDict=Dict([("path name", pathName), ("vehicle name", vehicleName), ("operation mode", operationMode), ("mass model", settings.massModel), ("step variable", settings.stepVariable), ("step size", settings.stepSize)])
|
||||
outputDict=Dict([("path name", pathName), ("train name", trainName), ("operation mode", operationMode), ("mass model", settings.massModel), ("step variable", settings.stepVariable), ("step size", settings.stepSize)])
|
||||
|
||||
# creating an output array
|
||||
outputArray=Array{Any, 1}[]
|
||||
|
@ -72,10 +72,10 @@ function createOutputDict(settings::Settings, pathName::String, vehicleName::Str
|
|||
return outputDict
|
||||
end # function createOutputDict
|
||||
|
||||
function createOutputDict(settings::Settings, pathName::String, vehicleName::String, drivingCourseMinimumRunningTime::Vector{Waypoint}, movingSectionMinimumRunningTime::MovingSection, drivingCourseMinimumEnergyConsumption::Vector{Waypoint}, movingSectionMinimumEnergyConsumption::MovingSection)
|
||||
function createOutputDict(settings::Settings, pathName::String, trainName::String, drivingCourseMinimumRunningTime::Vector{Waypoint}, movingSectionMinimumRunningTime::MovingSection, drivingCourseMinimumEnergyConsumption::Vector{Waypoint}, movingSectionMinimumEnergyConsumption::MovingSection)
|
||||
# method of function createOutputDict for two operation modes
|
||||
if settings.operationModeMinimumRunningTime
|
||||
outputDict=createOutputDict(settings, pathName, vehicleName, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime)
|
||||
outputDict=createOutputDict(settings, pathName, trainName, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime)
|
||||
|
||||
if settings.operationModeMinimumEnergyConsumption
|
||||
# creating the second output array
|
||||
|
@ -95,7 +95,7 @@ function createOutputDict(settings::Settings, pathName::String, vehicleName::Str
|
|||
merge!(outputDict, Dict("outputArrayMinimumEnergyConsumption"=>outputArrayMinimumEnergyConsumption))
|
||||
end
|
||||
else
|
||||
outputDict=createOutputDict(settings, pathName, vehicleName, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||
outputDict=createOutputDict(settings, pathName, trainName, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||
end
|
||||
|
||||
# println("The output dictionary has been created for minimum running time and minimum energy consumption.")
|
||||
|
@ -103,9 +103,9 @@ function createOutputDict(settings::Settings, pathName::String, vehicleName::Str
|
|||
end # function createOutputDict
|
||||
|
||||
|
||||
function createOutputCsv(settings::Settings, pathName::String, vehicleName::String, drivingCourse::Vector{Waypoint}, movingSection::MovingSection)
|
||||
function createOutputCsv(settings::Settings, pathName::String, trainName::String, drivingCourse::Vector{Waypoint}, movingSection::MovingSection)
|
||||
# method of function createOutputDict for one operation mode
|
||||
outputDict=createOutputDict(settings, pathName, vehicleName, drivingCourse, movingSection)
|
||||
outputDict=createOutputDict(settings, pathName, trainName, drivingCourse, movingSection)
|
||||
|
||||
if length(movingSection.energySavingModifications)>0 # if the moving section hast energy saving modifications the moving section is modified for minimum energy consumption
|
||||
operationMode="minimum energy consumption"
|
||||
|
@ -123,8 +123,8 @@ function createOutputCsv(settings::Settings, pathName::String, vehicleName::Stri
|
|||
|
||||
# creating information block
|
||||
infoColumns=Array{Any,1}[]
|
||||
push!(infoColumns, ["path name", "vehicle name", "operation mode", "mass model", "step variable", "step size", ""])
|
||||
push!(infoColumns, [pathName, vehicleName, operationMode, settings.massModel, settings.stepVariable, string(settings.stepSize), ""])
|
||||
push!(infoColumns, ["path name", "train name", "operation mode", "mass model", "step variable", "step size", ""])
|
||||
push!(infoColumns, [pathName, trainName, operationMode, settings.massModel, settings.stepVariable, string(settings.stepSize), ""])
|
||||
for column in 3:length(outputDict[outputArray][1])
|
||||
push!(infoColumns, ["", "", "", "", "", "", ""])
|
||||
end # for
|
||||
|
@ -156,16 +156,16 @@ function createOutputCsv(settings::Settings, pathName::String, vehicleName::Stri
|
|||
return outputDict
|
||||
end #function createOutputCsv
|
||||
|
||||
function createOutputCsv(settings::Settings, pathName::String, vehicleName::String, drivingCourseMinimumRunningTime::Vector{Waypoint}, movingSectionMinimumRunningTime::MovingSection, drivingCourseMinimumEnergyConsumption::Vector{Waypoint}, movingSectionMinimumEnergyConsumption::MovingSection)
|
||||
function createOutputCsv(settings::Settings, pathName::String, trainName::String, drivingCourseMinimumRunningTime::Vector{Waypoint}, movingSectionMinimumRunningTime::MovingSection, drivingCourseMinimumEnergyConsumption::Vector{Waypoint}, movingSectionMinimumEnergyConsumption::MovingSection)
|
||||
# method of function createOutputDict for two operation modes
|
||||
outputDict=createOutputDict(settings, pathName, vehicleName, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||
outputDict=createOutputDict(settings, pathName, trainName, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||
|
||||
if settings.operationModeMinimumRunningTime
|
||||
#creating information block
|
||||
infoColumns=Array{Any,1}[]
|
||||
push!(infoColumns, ["path name", "vehicle name", "operation mode", "mass model", "step variable", "step size", ""])
|
||||
#push!(infoColumns, [pathName, vehicleName, "minimum running time", settings.massModel, settings.stepVariable, settings.stepSize, ""])
|
||||
push!(infoColumns, [pathName, vehicleName, "minimum running time", settings.massModel, settings.stepVariable, string(settings.stepSize), ""])
|
||||
push!(infoColumns, ["path name", "train name", "operation mode", "mass model", "step variable", "step size", ""])
|
||||
#push!(infoColumns, [pathName, trainName, "minimum running time", settings.massModel, settings.stepVariable, settings.stepSize, ""])
|
||||
push!(infoColumns, [pathName, trainName, "minimum running time", settings.massModel, settings.stepVariable, string(settings.stepSize), ""])
|
||||
|
||||
for column in 3:length(outputDict["outputArrayMinimumRunningTime"][1])
|
||||
push!(infoColumns, ["", "", "", "", "", "", ""])
|
||||
|
@ -204,8 +204,8 @@ function createOutputCsv(settings::Settings, pathName::String, vehicleName::Stri
|
|||
if settings.operationModeMinimumEnergyConsumption
|
||||
#creating information block
|
||||
infoColumns=Array{Any,1}[]
|
||||
push!(infoColumns, ["path name", "vehicle name", "operation mode", "mass model", "step variable", "step size", ""])
|
||||
push!(infoColumns, [pathName, vehicleName, "minimum energy consumption", settings.massModel, settings.stepVariable, settings.stepSize, ""])
|
||||
push!(infoColumns, ["path name", "train name", "operation mode", "mass model", "step variable", "step size", ""])
|
||||
push!(infoColumns, [pathName, trainName, "minimum energy consumption", settings.massModel, settings.stepVariable, settings.stepSize, ""])
|
||||
for column in 3:length(outputDict["outputArrayMinimumEnergyConsumption"][1])
|
||||
push!(infoColumns, ["", "", "", "", "", "", ""])
|
||||
end # for
|
||||
|
@ -287,15 +287,16 @@ function plotDrivingCourse(drivingCourse::Vector{Waypoint})
|
|||
|
||||
p2=plot([t], [v], title = "v in m/s", label = ["v"], xlabel = "t in s")
|
||||
|
||||
p3=plot([s], [t], title = "t in s", label = ["t"], xlabel = "s in m")
|
||||
# p3=plot([s], [t], title = "t in s", label = ["t"], xlabel = "s in m")
|
||||
|
||||
p4=plot([t], [s], title = "s in m", label = ["s"], xlabel = "t in s")
|
||||
# p4=plot([t], [s], title = "s in m", label = ["s"], xlabel = "t in s")
|
||||
|
||||
p5=plot([s], [E], title = "E in Ws", label = ["E"], xlabel = "s in m")
|
||||
|
||||
p6=plot([t], [E], title = "E in Ws", label = ["E"], xlabel = "t in s")
|
||||
|
||||
all=plot(p1, p2, p3, p4, p5, p6, layout = (3, 2), legend = false)
|
||||
all=plot(p1, p2, p5, p6, layout = (2, 2), legend = false)
|
||||
# all=plot(p1, p2, p3, p4, p5, p6, layout = (3, 2), legend = false)
|
||||
display(all)
|
||||
println("Plots for different variables have been created.")
|
||||
end #function plotDrivingCourse
|
||||
|
@ -339,17 +340,17 @@ function plotDrivingCourse(drivingCourseMinimumRunningTime::Vector{Waypoint},dri
|
|||
label = ["v for t_min" "v for E_min"],
|
||||
xlabel = "t in s")
|
||||
|
||||
p3=plot([s_minTime,s_minEnergy],
|
||||
[t_minTime,t_minEnergy],
|
||||
title = "t in s",
|
||||
label = ["t for t_min" "t for E_min"],
|
||||
xlabel = "s in m")
|
||||
# p3=plot([s_minTime,s_minEnergy],
|
||||
# [t_minTime,t_minEnergy],
|
||||
# title = "t in s",
|
||||
# label = ["t for t_min" "t for E_min"],
|
||||
# xlabel = "s in m")
|
||||
|
||||
p4=plot([t_minTime,t_minEnergy],
|
||||
[s_minTime,s_minEnergy],
|
||||
title = "s in m",
|
||||
label = ["s for t_min" "s for E_min"],
|
||||
xlabel = "t in s")
|
||||
# p4=plot([t_minTime,t_minEnergy],
|
||||
# [s_minTime,s_minEnergy],
|
||||
# title = "s in m",
|
||||
# label = ["s for t_min" "s for E_min"],
|
||||
# xlabel = "t in s")
|
||||
|
||||
p5=plot([s_minTime,s_minEnergy],
|
||||
[E_minTime,E_minEnergy],
|
||||
|
@ -363,9 +364,10 @@ function plotDrivingCourse(drivingCourseMinimumRunningTime::Vector{Waypoint},dri
|
|||
label = ["E for t_min" "E for E_min"],
|
||||
xlabel = "t in s")
|
||||
|
||||
all=plot(p1, p2, p3, p4, p5, p6, layout = (3, 2), legend = false)
|
||||
# all=plot(p1, p2, p3, p4, p5, p6, layout = (3, 2), legend = false)
|
||||
all=plot(p1, p2, p5, p6, layout = (2, 2), legend = false)
|
||||
display(all)
|
||||
println("Plots for different variables have been created.")
|
||||
end #function plotDrivingCourse
|
||||
|
||||
end # module RailwayDrivingDynamicsOutput
|
||||
end # module Output
|
|
@ -1,21 +1,22 @@
|
|||
module RailwayDrivingDynamicsPreparation
|
||||
module Preparation
|
||||
|
||||
using ..types
|
||||
include("./RailwayDrivingDynamicsMovingPhases.jl")
|
||||
using .RailwayDrivingDynamicsMovingPhases
|
||||
include("./MovingPhases.jl")
|
||||
using .MovingPhases
|
||||
|
||||
export preparateSections
|
||||
|
||||
## creating a moving section and its containing characteristic sections which braking and acceleration behavior is secured
|
||||
function preparateSections(path::Path, vehicle::Vehicle, settings::Settings)
|
||||
movingSection=createMovingSection(path, vehicle.v_limit)
|
||||
movingSection=secureBrakingBehavior!(movingSection, vehicle.a_braking)
|
||||
movingSection=secureAccelerationBehavior!(movingSection, settings, vehicle)
|
||||
## create a moving section and its containing characteristic sections with securedd braking, acceleration and cruising behavior
|
||||
function preparateSections(path::Path, train::Train, settings::Settings)
|
||||
movingSection=createMovingSection(path, train.v_limit)
|
||||
movingSection=secureBrakingBehavior!(movingSection, train.a_braking)
|
||||
movingSection=secureAccelerationBehavior!(movingSection, settings, train)
|
||||
movingSection=secureCruisingBehavior!(movingSection, settings, train)
|
||||
return movingSection
|
||||
end #function preparateSections
|
||||
|
||||
## creating a moving section containing characteristic sections
|
||||
function createMovingSection(path::Path, v_vehicleLimit::AbstractFloat)
|
||||
## create a moving section containing characteristic sections
|
||||
function createMovingSection(path::Path, v_trainLimit::AbstractFloat)
|
||||
# this function creates and returns a moving section dependent on the paths attributes
|
||||
movingSection=MovingSection()
|
||||
|
||||
|
@ -30,19 +31,19 @@ function createMovingSection(path::Path, v_vehicleLimit::AbstractFloat)
|
|||
s_csStart=movingSection.s_start
|
||||
csId=1
|
||||
for row in 2:length(path.sections)
|
||||
if min(path.sections[row-1].v_limit, v_vehicleLimit) != min(path.sections[row].v_limit, v_vehicleLimit) || path.sections[row-1].f_Rp != path.sections[row].f_Rp
|
||||
push!(movingSection.characteristicSections, createCharacteristicSection(csId, s_csStart, path.sections[row-1], min(path.sections[row-1].v_limit, v_vehicleLimit)))
|
||||
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
|
||||
push!(movingSection.characteristicSections, createCharacteristicSection(csId, s_csStart, path.sections[row-1], min(path.sections[row-1].v_limit, v_trainLimit)))
|
||||
s_csStart=path.sections[row].s_start
|
||||
csId=csId+1
|
||||
end #if
|
||||
end #for
|
||||
push!(movingSection.characteristicSections, createCharacteristicSection(csId, s_csStart, path.sections[end], min(path.sections[end].v_limit, v_vehicleLimit)))
|
||||
push!(movingSection.characteristicSections, createCharacteristicSection(csId, s_csStart, path.sections[end], min(path.sections[end].v_limit, v_trainLimit)))
|
||||
|
||||
return movingSection
|
||||
end #function createMovingSection
|
||||
|
||||
|
||||
##
|
||||
## create a characteristic section for a path section
|
||||
function createCharacteristicSection(csId::Integer, s_csStart::AbstractFloat, section::PathSection, v_csLimit::AbstractFloat)
|
||||
# this function creates and returns a characteristic section dependent on the paths attributes
|
||||
characteristicSection=CharacteristicSection()
|
||||
|
@ -64,9 +65,9 @@ function createCharacteristicSection(csId::Integer, s_csStart::AbstractFloat, se
|
|||
return characteristicSection
|
||||
end #function createCharacteristicSection
|
||||
|
||||
## defining the intersection velocities between the characterisitc sections
|
||||
## define the intersection velocities between the characterisitc sections to secure braking behavior
|
||||
function secureBrakingBehavior!(movingSection::MovingSection, a_braking::AbstractFloat)
|
||||
# this function limits the entry and exit velocity of the characteristic sections to secure that the vehicle stops at the moving sections end
|
||||
# this function limits the entry and exit velocity of the characteristic sections to secure that the train stops at the moving sections end
|
||||
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
|
||||
|
@ -83,9 +84,74 @@ function secureBrakingBehavior!(movingSection::MovingSection, a_braking::Abstrac
|
|||
return movingSection
|
||||
end #function secureBrakingBehavior!
|
||||
|
||||
##
|
||||
function secureAccelerationBehavior!(movingSection::MovingSection, settings::Settings, vehicle::Vehicle)
|
||||
# this function limits the entry and exit velocity of the characteristic sections for case that the vehicle accelerates in every section and cruises aterwards
|
||||
## define the intersection velocities between the characterisitc sections to secure acceleration behavior
|
||||
function secureAccelerationBehavior!(movingSection::MovingSection, settings::Settings, train::Train)
|
||||
# this function limits the entry and exit velocity of the characteristic sections in case that the train accelerates in every section and cruises aterwards
|
||||
movingSection.characteristicSections[1].v_entry=0.0 # the entry velocity of the first characteristic section is 0.0 m/s
|
||||
startingPoint=Waypoint()
|
||||
startingPoint.i=1
|
||||
|
||||
previousCSv_exit=movingSection.characteristicSections[1].v_entry
|
||||
|
||||
for csId in 1:length(movingSection.characteristicSections)
|
||||
movingSection.characteristicSections[csId].v_entry=min(movingSection.characteristicSections[csId].v_entry, previousCSv_exit)
|
||||
|
||||
startingPoint.s=movingSection.characteristicSections[csId].s_start
|
||||
startingPoint.v=movingSection.characteristicSections[csId].v_entry
|
||||
accelerationCourse=[startingPoint] # List of waypoints
|
||||
|
||||
if movingSection.characteristicSections[csId].v_entry<movingSection.characteristicSections[csId].v_reach
|
||||
(movingSection.characteristicSections[csId], accelerationCourse)=addAccelerationPhase!(movingSection.characteristicSections[csId], accelerationCourse, settings, train, movingSection.characteristicSections) # this function changes the accelerationCourse
|
||||
movingSection.characteristicSections[csId].v_reach=accelerationCourse[end].v
|
||||
movingSection.characteristicSections[csId].v_exit=min(movingSection.characteristicSections[csId].v_exit, movingSection.characteristicSections[csId].v_reach)
|
||||
else #movingSection.characteristicSections[csId].v_entry==movingSection.characteristicSections[csId].v_reach
|
||||
# v_exit stays the same
|
||||
end #if
|
||||
|
||||
previousCSv_exit=movingSection.characteristicSections[csId].v_exit
|
||||
end #for
|
||||
|
||||
return movingSection
|
||||
end #function secureAccelerationBehavior!
|
||||
|
||||
|
||||
|
||||
## define the intersection velocities between the characterisitc sections to secure cruising behavior
|
||||
function secureCruisingBehavior!(movingSection::MovingSection, settings::Settings, train::Train)
|
||||
# limit the exit velocity of the characteristic sections in case that the train cruises in every section at v_reach
|
||||
startingPoint=Waypoint()
|
||||
startingPoint.i=1
|
||||
|
||||
previousCSv_exit=movingSection.characteristicSections[1].v_entry
|
||||
|
||||
for csId in 1:length(movingSection.characteristicSections)
|
||||
movingSection.characteristicSections[csId].v_entry=min(movingSection.characteristicSections[csId].v_entry, previousCSv_exit)
|
||||
|
||||
startingPoint.s=movingSection.characteristicSections[csId].s_start
|
||||
startingPoint.v=movingSection.characteristicSections[csId].v_reach
|
||||
cruisingCourse=[startingPoint] # List of waypoints
|
||||
|
||||
(movingSection.characteristicSections[csId], cruisingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], cruisingCourse, movingSection.characteristicSections[csId].s_total, settings, train, movingSection.characteristicSections, "cruising") # this function changes the cruisingCourse
|
||||
movingSection.characteristicSections[csId].v_exit=min(movingSection.characteristicSections[csId].v_exit, cruisingCourse[end].v)
|
||||
|
||||
previousCSv_exit=movingSection.characteristicSections[csId].v_exit
|
||||
end #for
|
||||
|
||||
return movingSection
|
||||
end #function secureCruisingBehavior!
|
||||
|
||||
|
||||
|
||||
end #module Preparation
|
||||
|
||||
|
||||
|
||||
|
||||
#= 22.06.2021: acceleration an cruising behavior seperated in two functions
|
||||
|
||||
## define the intersection velocities between the characterisitc sections to secure acceleration behavior
|
||||
function secureAccelerationBehavior!(movingSection::MovingSection, settings::Settings, train::Train)
|
||||
# this function limits the entry and exit velocity of the characteristic sections in case that the train accelerates in every section and cruises aterwards
|
||||
movingSection.characteristicSections[1].v_entry=0.0 # the entry velocity of the first characteristic section is 0.0 m/s
|
||||
startingPoint=Waypoint()
|
||||
startingPoint.i=1
|
||||
|
@ -97,15 +163,15 @@ function secureAccelerationBehavior!(movingSection::MovingSection, settings::Set
|
|||
|
||||
startingPoint.s=movingSection.characteristicSections[csId].s_start
|
||||
startingPoint.v=movingSection.characteristicSections[csId].v_entry
|
||||
accelerationCourse=[startingPoint] # List of waypoints
|
||||
cruisingCourse=[startingPoint] # List of waypoints
|
||||
|
||||
|
||||
if movingSection.characteristicSections[csId].v_entry<movingSection.characteristicSections[csId].v_reach
|
||||
(movingSection.characteristicSections[csId], accelerationCourse)=addAccelerationPhase!(movingSection.characteristicSections[csId], accelerationCourse, settings, vehicle, movingSection.characteristicSections) # this function changes the accelerationCourse
|
||||
(movingSection.characteristicSections[csId], accelerationCourse)=addAccelerationPhase!(movingSection.characteristicSections[csId], accelerationCourse, settings, train, movingSection.characteristicSections) # this function changes the accelerationCourse
|
||||
movingSection.characteristicSections[csId].v_reach=accelerationCourse[end].v
|
||||
movingSection.characteristicSections[csId].v_exit=min(movingSection.characteristicSections[csId].v_exit, movingSection.characteristicSections[csId].v_reach)
|
||||
|
||||
if settings.stepVariable=="v in m/s" # with the new v_reach the calculation will be defferent a second time. Therefore the CS has to be calculated again for velocity step method to refresh the length of the acceleration section for further simulation
|
||||
if settings.stepVariable=="v in m/s" # with the new v_reach the calculation will be different a second time. Therefore the CS has to be calculated again for velocity step method to refresh the length of the acceleration section for further simulation
|
||||
delete!(movingSection.characteristicSections[csId].behaviorSections, "starting")
|
||||
delete!(movingSection.characteristicSections[csId].behaviorSections, "cruisingBeforeAcceleration")
|
||||
delete!(movingSection.characteristicSections[csId].behaviorSections, "acceleration")
|
||||
|
@ -113,19 +179,19 @@ function secureAccelerationBehavior!(movingSection::MovingSection, settings::Set
|
|||
movingSection.characteristicSections[csId].t_total=0.0
|
||||
accelerationCourse=[startingPoint] # List of waypoints
|
||||
|
||||
(movingSection.characteristicSections[csId], accelerationCourse)=addAccelerationPhase!(movingSection.characteristicSections[csId], accelerationCourse, settings, vehicle, movingSection.characteristicSections) # this function changes the accelerationCourse
|
||||
(movingSection.characteristicSections[csId], accelerationCourse)=addAccelerationPhase!(movingSection.characteristicSections[csId], accelerationCourse, settings, train, movingSection.characteristicSections) # this function changes the accelerationCourse
|
||||
end
|
||||
else #movingSection.characteristicSections[csId].v_entry==movingSection.characteristicSections[csId].v_reach
|
||||
# v_exit stays the same
|
||||
end #if
|
||||
|
||||
# securing cruising behavior
|
||||
# is need if the path resistance is too high, the vehicle can not cruise at v_reach and is getting slower
|
||||
s_cruisingMax=movingSection.characteristicSections[csId].s_end-accelerationCourse[end].s
|
||||
if s_cruisingMax>0.0
|
||||
(movingSection.characteristicSections[csId], accelerationCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], accelerationCourse, s_cruisingMax, settings, vehicle, movingSection.characteristicSections, "cruising")
|
||||
movingSection.characteristicSections[csId].v_exit=min(movingSection.characteristicSections[csId].v_exit, accelerationCourse[end].v)
|
||||
end
|
||||
# securing cruising behavior
|
||||
# is need if the path resistance is too high, the train can not cruise at v_reach and is getting slower
|
||||
s_cruisingMax=movingSection.characteristicSections[csId].s_end-accelerationCourse[end].s
|
||||
if s_cruisingMax>0.0
|
||||
(movingSection.characteristicSections[csId], accelerationCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], accelerationCourse, s_cruisingMax, settings, train, movingSection.characteristicSections, "cruising")
|
||||
movingSection.characteristicSections[csId].v_exit=min(movingSection.characteristicSections[csId].v_exit, accelerationCourse[end].v)
|
||||
end
|
||||
|
||||
previousCSv_exit=movingSection.characteristicSections[csId].v_exit
|
||||
# println("CS",csId,": s_start: ",movingSection.characteristicSections[csId].s_start," v_entry: ", round(movingSection.characteristicSections[csId].v_entry*3.6, digits=5), ", v_reach: ", round(movingSection.characteristicSections[csId].v_reach*3.6, digits=5), " v_exit: ", round(movingSection.characteristicSections[csId].v_exit*3.6, digits=5))
|
||||
|
@ -133,5 +199,4 @@ function secureAccelerationBehavior!(movingSection::MovingSection, settings::Set
|
|||
|
||||
return movingSection
|
||||
end #function secureAccelerationBehavior!
|
||||
|
||||
end #module RailwayDrivingDynamicsPreparation
|
||||
=#
|
|
@ -1,600 +0,0 @@
|
|||
module RailwayDrivingDynamicsInput
|
||||
|
||||
import YAML
|
||||
using ..types
|
||||
|
||||
export readInput
|
||||
|
||||
function readInput(vehicleFilePath::String, pathFilePath::String, settingsFilePath::String)
|
||||
# this function reads the input information from YAML files, saves it in a different objects and returns them
|
||||
vehicle=inputVehicle(vehicleFilePath)
|
||||
path=inputPath(pathFilePath)
|
||||
settings=inputSettings(settingsFilePath)
|
||||
|
||||
return (vehicle, path, settings)
|
||||
end #function readInput
|
||||
|
||||
|
||||
function inputVehicle(vehicleFilePath::String)
|
||||
# this function reads vehicle information from a YAML file, saves it in a Vehicle object and returns it
|
||||
data = YAML.load(open(vehicleFilePath))
|
||||
collect(keys(data))
|
||||
collect(values(data))
|
||||
|
||||
vehicle=Vehicle()
|
||||
if haskey(data["vehicle"],"name")
|
||||
vehicle.name=data["vehicle"]["name"] # vehicles name
|
||||
delete!(data["vehicle"], "name")
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The keyword name is missing. It has to be added.")
|
||||
end
|
||||
vehicle.id=1 # vehicles identifier
|
||||
|
||||
if haskey(data["vehicle"],"vehicleType")
|
||||
if typeof(data["vehicle"]["vehicleType"])==String && (data["vehicle"]["vehicleType"]=="freight" || data["vehicle"]["vehicleType"]=="motor coach train" || data["vehicle"]["vehicleType"]=="passenger")
|
||||
vehicle.vehicleType=data["vehicle"]["vehicleType"] # "passenger" or "freight" or "motor coach train"
|
||||
delete!(data["vehicle"], "vehicleType")
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The value of vehicleType is wrong. It has to be freight, motor coach train or passenger.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The keyword vehicleType is missing. It has to be added with the value freight, motor coach train or passenger.")
|
||||
end
|
||||
|
||||
if haskey(data["vehicle"],"l_union")
|
||||
if typeof(data["vehicle"]["l_union"])==Float64 && data["vehicle"]["l_union"]>0.0
|
||||
vehicle.l_union=data["vehicle"]["l_union"] # total length (in m)
|
||||
delete!(data["vehicle"], "l_union")
|
||||
elseif typeof(data["vehicle"]["l_union"])==Int64 && data["vehicle"]["l_union"]>0
|
||||
vehicle.l_union=convert(AbstractFloat, data["vehicle"]["l_union"]) # total length (in m)
|
||||
delete!(data["vehicle"], "l_union")
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The value of the length is no real floating point number >0.0.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The keyword length is missing. It has to be added with a value of type real floating point number >0.0.")
|
||||
end
|
||||
|
||||
# speed limit: # vehicles speed limit (in m/s)
|
||||
if haskey(data["vehicle"],"v_limit") && haskey(data["vehicle"],"v_limit_kmh")
|
||||
if data["vehicle"]["v_limit"]!=nothing
|
||||
if typeof(data["vehicle"]["v_limit"])==Float64 && data["vehicle"]["v_limit"]>0.0
|
||||
vehicle.v_limit=data["vehicle"]["v_limit"] # vehicles speed limit (in m/s)
|
||||
delete!(data["vehicle"], "v_limit")
|
||||
elseif typeof(data["vehicle"]["v_limit"])==Int64 && data["vehicle"]["v_limit"]>0
|
||||
vehicle.v_limit=convert(AbstractFloat, data["vehicle"]["v_limit"]) # vehicles speed limit (in m/s)
|
||||
delete!(data["vehicle"], "v_limit")
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The value of v_limit is no real floating point number >0.0.")
|
||||
end
|
||||
|
||||
if data["vehicle"]["v_limit_kmh"]!=nothing
|
||||
v_limit_kmh=data["vehicle"]["v_limit_kmh"]
|
||||
if abs(vehicle.v_limit-v_limit_kmh/3.6)>0.001
|
||||
println("WARNING: at reading the vehicle yaml file: The values of v_limit and v_limit_kmh differ by more than 0.001 m/s. The value v_limit=",vehicle.v_limit," m/s is used." )
|
||||
end
|
||||
end
|
||||
|
||||
elseif data["vehicle"]["v_limit_kmh"]!=nothing
|
||||
if typeof(data["vehicle"]["v_limit_kmh"])==Float64 && data["vehicle"]["v_limit_kmh"]>0.0
|
||||
vehicle.v_limit=data["vehicle"]["v_limit_kmh"]/3.6 # vehicles speed limit (from km/h to m/s)
|
||||
elseif typeof(data["vehicle"]["v_limit_kmh"])==Int64 && data["vehicle"]["v_limit_kmh"]>0
|
||||
vehicle.v_limit=convert(AbstractFloat, data["vehicle"]["v_limit_kmh"])/3.6 # vehicles speed limit (from km/h to m/s)
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The value of the v_limit_kmh is no real floating point number >0.0.")
|
||||
end
|
||||
else
|
||||
vehicle.v_limit=1000/3.6
|
||||
println("WARNING at reading the vehicle yaml file: There is no value for v_limit. The value v_limit=1000 km/h =",vehicle.v_limit," m/s is used." )
|
||||
end # if
|
||||
elseif haskey(data["vehicle"],"v_limit")
|
||||
if typeof(data["vehicle"]["v_limit"])==Float64 && data["vehicle"]["v_limit"]>0.0
|
||||
vehicle.v_limit=data["vehicle"]["v_limit"] # vehicles speed limit (in m/s)
|
||||
elseif typeof(data["vehicle"]["v_limit"])==Int64 && data["vehicle"]["v_limit"]>0
|
||||
vehicle.v_limit=convert(AbstractFloat, data["vehicle"]["v_limit"]) # vehicles speed limit (in m/s)
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The value of v_limit is no real floating point number >0.0.")
|
||||
end
|
||||
elseif haskey(data["vehicle"],"v_limit_kmh")
|
||||
if typeof(data["vehicle"]["v_limit_kmh"])==Float64 && data["vehicle"]["v_limit_kmh"]>0.0
|
||||
vehicle.v_limit=data["vehicle"]["v_limit_kmh"]/3.6 # vehicles speed limit (from km/h to m/s)
|
||||
elseif typeof(data["vehicle"]["v_limit_kmh"])==Int64 && data["vehicle"]["v_limit_kmh"]>0
|
||||
vehicle.v_limit=convert(AbstractFloat, data["vehicle"]["v_limit_kmh"])/3.6 # vehicles speed limit (from km/h to m/s)
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The value of v_limit_kmh is no real floating point number >0.0.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The keyword v_limit or v_limit_kmh is missing. It has to be added with a value of type real floating point number >0.0.")
|
||||
end
|
||||
delete!(data["vehicle"], "v_limit")
|
||||
delete!(data["vehicle"], "v_limit_kmh")
|
||||
|
||||
|
||||
# a_braking
|
||||
if haskey(data["vehicle"],"a_braking")
|
||||
if typeof(data["vehicle"]["a_braking"])==Float64
|
||||
vehicle.a_braking=data["vehicle"]["a_braking"]
|
||||
elseif typeof(data["vehicle"]["a_braking"])==Int64
|
||||
vehicle.a_braking=convert(AbstractFloat, data["vehicle"]["a_braking"])
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The value of the a_braking is no real floating point number <0.0.")
|
||||
end
|
||||
delete!(data["vehicle"], "a_braking")
|
||||
|
||||
if vehicle.a_braking > 0.0
|
||||
vehicle.a_braking =-vehicle.a_braking
|
||||
println("WARNING at reading the vehicle yaml file: The value for a_braking is >0.0. The braking acceleration has to be <0.0. Therefore a_braking =",vehicle.a_braking," m/s^2 is used." )
|
||||
elseif vehicle.a_braking == 0.0
|
||||
error("ERROR at reading the vehicle yaml file: The value for a_braking is 0.0. The braking acceleration has to be <0.0.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The keyword a_braking is missing. It has to be added with a value of type real floating point number <0.0.")
|
||||
end
|
||||
|
||||
# mass on the traction units driving axles (in kg)
|
||||
if haskey(data["vehicle"],"m_td")
|
||||
if typeof(data["vehicle"]["m_td"])==Float64 && data["vehicle"]["m_td"]>0.0
|
||||
vehicle.m_td=data["vehicle"]["m_td"]
|
||||
elseif typeof(data["vehicle"]["m_td"])==Int64 && data["vehicle"]["m_td"]>0
|
||||
vehicle.m_td=convert(AbstractFloat, data["vehicle"]["m_td"])
|
||||
delete!(data["vehicle"], "m_td")
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The value of m_td is no real floating point number >0.0.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The keyword m_td is missing. It has to be added with a value of type real floating point number >0.0.")
|
||||
end
|
||||
delete!(data["vehicle"], "m_td")
|
||||
|
||||
|
||||
# mass on the traction units carrying axles (in kg)
|
||||
if haskey(data["vehicle"],"m_tc")
|
||||
if typeof(data["vehicle"]["m_tc"])==Float64 && data["vehicle"]["m_tc"]>=0.0
|
||||
vehicle.m_tc=data["vehicle"]["m_tc"]
|
||||
elseif typeof(data["vehicle"]["m_tc"])==Int64 && data["vehicle"]["m_tc"]>=0
|
||||
vehicle.m_tc=convert(AbstractFloat, data["vehicle"]["m_tc"])
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The value of m_tc is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The keyword m_tc is missing. It has to be added with a value of type real floating point number >=0.0.")
|
||||
end
|
||||
delete!(data["vehicle"], "m_tc")
|
||||
|
||||
# mass of the traction unit (in kg)
|
||||
vehicle.m_t=vehicle.m_td+vehicle.m_tc
|
||||
|
||||
|
||||
# mass of theconsist (set of wagons) (in kg)
|
||||
if haskey(data["vehicle"],"m_w")
|
||||
if typeof(data["vehicle"]["m_w"])==Float64 && data["vehicle"]["m_w"]>=0.0
|
||||
vehicle.m_w=data["vehicle"]["m_w"]
|
||||
elseif typeof(data["vehicle"]["m_w"])==Int64 && data["vehicle"]["m_w"]>=0
|
||||
vehicle.m_w=convert(AbstractFloat, data["vehicle"]["m_w"])
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The value of m_w is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
vehicle.m_w=0.0
|
||||
println("WARNING at reading the vehicle yaml file: The keyword m_w is missing. Therefore m_w =",vehicle.m_w," kg is used.")
|
||||
end
|
||||
delete!(data["vehicle"], "m_w")
|
||||
|
||||
# total mass (in kg)
|
||||
vehicle.m_union=vehicle.m_t+vehicle.m_w
|
||||
|
||||
if haskey(data["vehicle"],"rotationMassFactor_union") && (typeof(data["vehicle"]["rotationMassFactor_union"])==Float64 || typeof(data["vehicle"]["rotationMassFactor_union"])==Int64)
|
||||
if typeof(data["vehicle"]["rotationMassFactor_union"])==Float64 && data["vehicle"]["rotationMassFactor_union"]>0.0
|
||||
vehicle.ξ_union=data["vehicle"]["rotationMassFactor_union"]
|
||||
elseif typeof(data["vehicle"]["rotationMassFactor_union"])==Int64 && data["vehicle"]["rotationMassFactor_union"]>0
|
||||
vehicle.ξ_union=convert(AbstractFloat, data["vehicle"]["rotationMassFactor_union"])
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The value of rotationMassFactor_union is no real floating point number >0.0.")
|
||||
end
|
||||
elseif haskey(data["vehicle"],"rotationMassFactor_t") && (typeof(data["vehicle"]["rotationMassFactor_t"])==Float64 || typeof(data["vehicle"]["rotationMassFactor_t"])==Int64) && (vehicle.m_w==0.0 || haskey(data["vehicle"],"rotationMassFactor_w") && (typeof(data["vehicle"]["rotationMassFactor_w"])==Float64 || typeof(data["vehicle"]["rotationMassFactor_w"])==Int64))
|
||||
if typeof(data["vehicle"]["rotationMassFactor_t"])==Float64 && data["vehicle"]["rotationMassFactor_t"]>0.0
|
||||
vehicle.ξ_t=data["vehicle"]["rotationMassFactor_t"]
|
||||
elseif typeof(data["vehicle"]["rotationMassFactor_t"])==Int64 && data["vehicle"]["rotationMassFactor_t"]>0
|
||||
vehicle.ξ_t=convert(AbstractFloat, data["vehicle"]["rotationMassFactor_t"])
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The value of rotationMassFactor_t is no real floating point number >0.0.")
|
||||
end
|
||||
if vehicle.m_w>0.0
|
||||
if typeof(data["vehicle"]["rotationMassFactor_w"])==Float64 && data["vehicle"]["rotationMassFactor_w"]>=0.0
|
||||
vehicle.ξ_w=data["vehicle"]["rotationMassFactor_w"]
|
||||
elseif typeof(data["vehicle"]["rotationMassFactor_w"])==Int64 && data["vehicle"]["rotationMassFactor_w"]>=0
|
||||
vehicle.ξ_w=convert(AbstractFloat, data["vehicle"]["rotationMassFactor_w"])
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The value of rotationMassFactor_w is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
vehicle.ξ_w=0.0
|
||||
end
|
||||
vehicle.ξ_union=(vehicle.ξ_t*vehicle.m_t + vehicle.ξ_w*vehicle.m_w)/vehicle.m_union # rotation mass factor of the whole vehicle (without unit)
|
||||
else
|
||||
error("ERROR at reading the vehicle 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.")
|
||||
end
|
||||
delete!(data["vehicle"], "rotationMassFactor_union")
|
||||
delete!(data["vehicle"], "rotationMassFactor_t")
|
||||
delete!(data["vehicle"], "rotationMassFactor_w")
|
||||
|
||||
|
||||
# input for function tractiveEffort(v)
|
||||
# TODO: The types of the lists elements can be checked and the user can get warnings or error messages
|
||||
# TODO: What if there are values in F_T_pairs and in F_T_pairs_kmh. That should be checked and the user should be informed
|
||||
# TODO: It could be checked if all the array elements are correct.
|
||||
if haskey(data["vehicle"],"F_T_pairs") && data["vehicle"]["F_T_pairs"]!=nothing
|
||||
F_T_pairs=data["vehicle"]["F_T_pairs"]
|
||||
vehicle.tractiveEffortArray=[]
|
||||
if F_T_pairs[1][1]==0.0
|
||||
push!(vehicle.tractiveEffortArray, [F_T_pairs[1][1], F_T_pairs[1][1], F_T_pairs[1][2]])
|
||||
elseif F_T_pairs[1][1]>0.0 # if there is no F_T for v=0.0, the first value is used
|
||||
push!(vehicle.tractiveEffortArray, [0.0, F_T_pairs[1][1]/3.6, F_T_pairs[1][2]])
|
||||
println("WARNING at reading the vehicle yaml file: The tractive effort for v=0 m/s is missing. Therefore the first given value F_T(v=",F_T_pairs[1][1]," m/s)=",F_T_pairs[1][2]," N will be used." )
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: There is a negative speed value in the list. Only positive values for speed and tractive effort are allowed. ")
|
||||
end
|
||||
for row in 2:length(F_T_pairs)
|
||||
if F_T_pairs[row][1]>F_T_pairs[row-1][1]
|
||||
if F_T_pairs[row][2]==vehicle.tractiveEffortArray[end][3]
|
||||
vehicle.tractiveEffortArray[end][2]=F_T_pairs[row][1]
|
||||
else
|
||||
push!(vehicle.tractiveEffortArray, [F_T_pairs[row][1], F_T_pairs[row][1], F_T_pairs[row][2]])
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The F_T_pairs are not in the correct order. They have to be arranged by speed values from low to high.")
|
||||
end
|
||||
end # for
|
||||
if length(F_T_pairs[1])>2
|
||||
println("INFO according the vehicle yaml file: Only the first two columns of F_T_pairs are used in this tool.")
|
||||
end
|
||||
|
||||
|
||||
elseif haskey(data["vehicle"],"F_T_pairs_kmh") && data["vehicle"]["F_T_pairs_kmh"]!=nothing
|
||||
F_T_pairs_kmh=data["vehicle"]["F_T_pairs_kmh"]
|
||||
vehicle.tractiveEffortArray=[]
|
||||
if F_T_pairs_kmh[1][1]==0.0
|
||||
push!(vehicle.tractiveEffortArray, [F_T_pairs_kmh[1][1]/3.6, F_T_pairs_kmh[1][1]/3.6, F_T_pairs_kmh[1][2]])
|
||||
elseif F_T_pairs_kmh[1][1]>0.0 # if there is no F_T for v=0.0, the first value is used
|
||||
push!(vehicle.tractiveEffortArray, [0.0, F_T_pairs_kmh[1][1]/3.6, F_T_pairs_kmh[1][2]])
|
||||
println("WARNING at reading the vehicle yaml file: The tractive effort for v=0 km/h is missing. Therefore the first given value F_T(v=",F_T_pairs_kmh[1][1]," km/h)=",F_T_pairs_kmh[1][2]," N will be used." )
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: There is a negative speed value in the list. Only positive values for speed and tractive effort are allowed. ")
|
||||
end
|
||||
for row in 2:length(F_T_pairs_kmh)
|
||||
if F_T_pairs_kmh[row][1]>F_T_pairs_kmh[row-1][1]
|
||||
if F_T_pairs_kmh[row][2]==vehicle.tractiveEffortArray[end][3]
|
||||
vehicle.tractiveEffortArray[end][2]=F_T_pairs_kmh[row][1]/3.6
|
||||
else
|
||||
push!(vehicle.tractiveEffortArray, [F_T_pairs_kmh[row][1]/3.6, F_T_pairs_kmh[row][1]/3.6, F_T_pairs_kmh[row][2]])
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The F_T_pairs_kmh are not in the correct order. They have to be arranged by speed values from low to high.")
|
||||
end
|
||||
end # for
|
||||
if length(F_T_pairs_kmh[1])>2
|
||||
println("INFO at reading the vehicle yaml file: Only the first two columns of F_T_pairs_kmh are used in this tool.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: There has to be one of the keywords F_T_pairs or F_T_pairs_kmh filled with a list of pairs of velocity and tractive effort.")
|
||||
end # if
|
||||
delete!(data["vehicle"], "F_T_pairs")
|
||||
delete!(data["vehicle"], "F_T_pairs_kmh")
|
||||
|
||||
|
||||
# coefficients for the vehicle resistance of the traction unit
|
||||
vehicle.Δv_t=15.0/3.6 # coefficient for velocitiy difference between traction unit and outdoor air
|
||||
|
||||
# coefficient for basic resistance due to the traction units driving axles (in ‰)
|
||||
if haskey(data["vehicle"],"f_Rtd0") && data["vehicle"]["f_Rtd0"]!=nothing
|
||||
if typeof(data["vehicle"]["f_Rtd0"])==Float64 && data["vehicle"]["f_Rtd0"]>=0.0
|
||||
vehicle.f_Rtd0=data["vehicle"]["f_Rtd0"]
|
||||
elseif typeof(data["vehicle"]["f_Rtd0"])==Int64 && data["vehicle"]["f_Rtd0"]>=0
|
||||
vehicle.f_Rtd0=convert(AbstractFloat, data["vehicle"]["f_Rtd0"])
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The value of f_Rtd0 is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
vehicle.f_Rtd0=0.0
|
||||
println("WARNING at reading the vehicle yaml file: The keyword f_Rtd0 is missing. Therefore f_Rtd0=0.0 ‰ will be assumed and used." )
|
||||
end
|
||||
delete!(data["vehicle"], "f_Rtd0")
|
||||
|
||||
# coefficient for basic resistance due to the traction units carring axles (in ‰)
|
||||
if haskey(data["vehicle"],"f_Rtc0") && data["vehicle"]["f_Rtc0"]!=nothing
|
||||
if typeof(data["vehicle"]["f_Rtc0"])==Float64 && data["vehicle"]["f_Rtc0"]>=0.0
|
||||
vehicle.f_Rtc0=data["vehicle"]["f_Rtc0"]
|
||||
elseif typeof(data["vehicle"]["f_Rtc0"])==Int64 && data["vehicle"]["f_Rtc0"]>=0
|
||||
vehicle.f_Rtc0=convert(AbstractFloat, data["vehicle"]["f_Rtc0"])
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The value of f_Rtc0 is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
vehicle.f_Rtc0=0.0
|
||||
println("WARNING at reading the vehicle yaml file: The keyword f_Rtc0 is missing. Therefore f_Rtc0=0.0 ‰ will be assumed and used." )
|
||||
end
|
||||
delete!(data["vehicle"], "f_Rtc0")
|
||||
|
||||
# coefficient for air resistance of the traction units (in N)
|
||||
if haskey(data["vehicle"],"F_Rt2") && data["vehicle"]["F_Rt2"]!=nothing
|
||||
if typeof(data["vehicle"]["F_Rt2"])==Float64 && data["vehicle"]["F_Rt2"]>=0.0
|
||||
vehicle.F_Rt2=data["vehicle"]["F_Rt2"]
|
||||
elseif typeof(data["vehicle"]["F_Rt2"])==Int64 && data["vehicle"]["F_Rt2"]>=0
|
||||
vehicle.F_Rt2=convert(AbstractFloat, data["vehicle"]["F_Rt2"])
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The value of F_Rt2 is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
vehicle.F_Rt2=0.0
|
||||
println("WARNING at reading the vehicle yaml file: The keyword F_Rt2 is missing. Therefore F_Rt2=0.0 N will be assumed and used." )
|
||||
end
|
||||
delete!(data["vehicle"], "F_Rt2")
|
||||
|
||||
|
||||
|
||||
# coefficients for the vehicle resistance of the consist (set of wagons)
|
||||
# coefficient for velocitiy difference betweenconsist (set of wagons) and outdoor air (in m/s)
|
||||
if vehicle.vehicleType=="passenger" || vehicle.vehicleType=="motor coach train"
|
||||
vehicle.Δv_w=15.0/3.6
|
||||
elseif vehicle.vehicleType== "freight"
|
||||
vehicle.Δv_w=0.0
|
||||
end # if
|
||||
|
||||
# coefficient for basic resistance of theconsist (set of wagons) (in ‰)
|
||||
if haskey(data["vehicle"],"f_Rw0") && data["vehicle"]["f_Rw0"]!=nothing
|
||||
if typeof(data["vehicle"]["f_Rw0"])==Float64 && data["vehicle"]["f_Rw0"]>=0.0
|
||||
vehicle.f_Rw0=data["vehicle"]["f_Rw0"]
|
||||
elseif typeof(data["vehicle"]["f_Rw0"])==Int64 && data["vehicle"]["f_Rw0"]>=0
|
||||
vehicle.f_Rw0=convert(AbstractFloat, data["vehicle"]["f_Rw0"])
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The value of f_Rw0 is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
vehicle.f_Rw0=0.0
|
||||
println("WARNING at reading the vehicle yaml file: The keyword f_Rw0 is missing. Therefore f_Rw0=0.0 ‰ will be assumed and used." )
|
||||
end
|
||||
delete!(data["vehicle"], "f_Rw0")
|
||||
|
||||
# coefficient for basic resistance of theconsist (set of wagons) (in ‰)
|
||||
if haskey(data["vehicle"],"f_Rw1") && data["vehicle"]["f_Rw1"]!=nothing
|
||||
if typeof(data["vehicle"]["f_Rw1"])==Float64 && data["vehicle"]["f_Rw1"]>=0.0
|
||||
vehicle.f_Rw1=data["vehicle"]["f_Rw1"]
|
||||
elseif typeof(data["vehicle"]["f_Rw1"])==Int64 && data["vehicle"]["f_Rw1"]>=0
|
||||
vehicle.f_Rw1=convert(AbstractFloat, data["vehicle"]["f_Rw1"])
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The value of f_Rw1 is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
vehicle.f_Rw1=0.0
|
||||
println("WARNING at reading the vehicle yaml file: The keyword f_Rw1 is missing. Therefore f_Rw1=0.0 ‰ will be assumed and used." )
|
||||
end
|
||||
delete!(data["vehicle"], "f_Rw1")
|
||||
|
||||
# coefficient for basic resistance of the consist (set of wagons) (in ‰)
|
||||
if haskey(data["vehicle"],"f_Rw2") && data["vehicle"]["f_Rw2"]!=nothing
|
||||
if typeof(data["vehicle"]["f_Rw2"])==Float64 && data["vehicle"]["f_Rw2"]>=0.0
|
||||
vehicle.f_Rw2=data["vehicle"]["f_Rw2"]
|
||||
elseif typeof(data["vehicle"]["f_Rw2"])==Int64 && data["vehicle"]["f_Rw2"]>=0
|
||||
vehicle.f_Rw2=convert(AbstractFloat, data["vehicle"]["f_Rw2"])
|
||||
else
|
||||
error("ERROR at reading the vehicle yaml file: The value of f_Rw2 is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
vehicle.f_Rw2=0.0
|
||||
println("WARNING at reading the vehicle yaml file: The keyword f_Rw2 is missing. Therefore f_Rw2=0.0 ‰ will be assumed and used." )
|
||||
end
|
||||
delete!(data["vehicle"], "f_Rw2")
|
||||
|
||||
|
||||
# informing the user, which keywords of the input data are not used in this tool:
|
||||
if length(data["vehicle"])>0
|
||||
println("INFO at reading the vehicle yaml file: The following Keywords are not used in this tool:")
|
||||
for key in keys(data["vehicle"])
|
||||
println(" - ",key)
|
||||
end
|
||||
end
|
||||
|
||||
return vehicle
|
||||
end #function inputVehicle
|
||||
|
||||
|
||||
function inputPath(pathFilePath::String)
|
||||
# this function reads path information from a YAML file, saves it in a Path object and returns it
|
||||
data = YAML.load(open(pathFilePath))
|
||||
collect(keys(data))
|
||||
collect(values(data))
|
||||
|
||||
|
||||
if haskey(data["path"],"name") && data["path"]["name"]!=nothing
|
||||
name=data["path"]["name"] # path name
|
||||
else
|
||||
error("ERROR at reading the path yaml file: The keyword name is missing. It has to be added.")
|
||||
end
|
||||
delete!(data["path"], "name")
|
||||
|
||||
id=1 # path identifier
|
||||
path=Path(name, id, [])
|
||||
|
||||
|
||||
# TODO: It could be checked if all the array elements are correct.
|
||||
# TODO: The types of the lists elements can be checked and the user can get warnings or error messages
|
||||
# TODO: What if there are values in sectionStarts and in sectionStarts_kmh? The user should be informed
|
||||
if haskey(data["path"],"sectionStarts") && data["path"]["sectionStarts"]!=nothing
|
||||
sectionStartsArray=data["path"]["sectionStarts"]
|
||||
conversionFactor=1.0 # conversion factor between the units m/s and m/s
|
||||
elseif haskey(data["path"],"sectionStarts_kmh") && data["path"]["sectionStarts_kmh"]!=nothing
|
||||
sectionStartsArray=data["path"]["sectionStarts_kmh"]
|
||||
conversionFactor=1/3.6 # conversion factor between the units km/h and m/s
|
||||
else
|
||||
error("ERROR at reading the path yaml file: The keyword sectionStarts oder sectionStarts_kmh is missing. It has to be added.")
|
||||
end # if
|
||||
delete!(data["path"], "sectionStarts")
|
||||
delete!(data["path"], "sectionStarts_kmh")
|
||||
|
||||
if length(sectionStartsArray)>=2
|
||||
if length(sectionStartsArray[1])>=3
|
||||
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)
|
||||
if s_startNext<s_start
|
||||
error("ERROR at reading the path yaml file: The keyword sectionStartsArray needs to be filled with the three columns [s, v_limit, gradient].")
|
||||
end
|
||||
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)
|
||||
push!(path.sections, section)
|
||||
end # for
|
||||
if length(sectionStartsArray[1])>3
|
||||
println("INFO at reading the path yaml file: Only the first three columns of sectionStartsArray are used in this tool.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the path yaml file: The keyword sectionStartsArray needs to be filled with the three columns [s, v_limit, gradient].")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the path yaml file: The keyword sectionStartsArray needs at least two rows for two points each with the three columns [s, v_limit, gradient].")
|
||||
end
|
||||
|
||||
# informing the user, which keywords of the input data are not used in this tool:
|
||||
if length(data["path"])>0
|
||||
println("INFO at reading the path yaml file: The following Keywords are not used in this tool:")
|
||||
for key in keys(data["path"])
|
||||
println(" - ",key)
|
||||
end
|
||||
end
|
||||
return path
|
||||
end # function inputPath
|
||||
|
||||
|
||||
|
||||
|
||||
function inputSettings(settingsFilePath::String)
|
||||
# this function reads setting information from a YAML file, saves it in a Setting object and returns it
|
||||
data = YAML.load(open(settingsFilePath))
|
||||
collect(keys(data))
|
||||
collect(values(data))
|
||||
|
||||
settings=Settings()
|
||||
|
||||
# model type of the unions 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"
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of massModel is wrong. It has to be mass point or homogeneous strip.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The keyword massModel is missing. It has to be added with the value mass point or homogeneous strip.")
|
||||
end
|
||||
delete!(data["settings"], "massModel")
|
||||
|
||||
|
||||
|
||||
# step variable of the step method "s in m", "t in s" or "v in m/s"
|
||||
if haskey(data["settings"],"stepVariable")
|
||||
if typeof(data["settings"]["stepVariable"])==String && (data["settings"]["stepVariable"]=="s in m" || data["settings"]["stepVariable"]=="t in s" || data["settings"]["stepVariable"]=="v in m/s")
|
||||
settings.stepVariable=data["settings"]["stepVariable"] # "s in m", "t in s" or "v in m/s"
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of stepVariable is wrong. It has to be s in m, t in s or v in m/s.")
|
||||
end
|
||||
else
|
||||
error("ERROR for the settings yaml file: The keyword stepVariable is missing. It has to be added with the value s in m, t in s or v in m/s.")
|
||||
end
|
||||
delete!(data["settings"], "stepVariable")
|
||||
|
||||
|
||||
# step size (unit depends on steapVariable: s in m, t in s and v in m/s)
|
||||
if haskey(data["settings"],"stepSize")
|
||||
if typeof(data["settings"]["stepSize"])==Float64 && data["settings"]["stepSize"]>0.0
|
||||
settings.stepSize=data["settings"]["stepSize"]
|
||||
elseif typeof(data["settings"]["stepSize"])==Int64 && data["settings"]["stepSize"]>0
|
||||
settings.stepSize=convert(AbstractFloat, data["settings"]["stepSize"])
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of the stepSize is no real floating point number >0.0.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The keyword stepSize is missing. It has to be added with a value of type real floating point number >0.0.")
|
||||
end
|
||||
delete!(data["settings"], "stepSize")
|
||||
|
||||
|
||||
|
||||
# operation mode "minimum running time"
|
||||
if haskey(data["settings"],"operationModeMinimumRunningTime") && data["settings"]["operationModeMinimumRunningTime"]!=nothing
|
||||
if typeof(data["settings"]["operationModeMinimumRunningTime"])==Bool
|
||||
settings.operationModeMinimumRunningTime=data["settings"]["operationModeMinimumRunningTime"]
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of the keyword operationModeMinimumRunningTime is not correct. The value has to be of type boolean.")
|
||||
end
|
||||
else
|
||||
settings.operationModeMinimumRunningTime=false
|
||||
println("WARNING at reading the settings yaml file: The keyword operationModeMinimumRunningTime or its value is missing. Therefore operationModeMinimumRunningTime=",settings.operationModeMinimumRunningTime," is assumed and used.")
|
||||
end
|
||||
delete!(data["settings"], "operationModeMinimumRunningTime")
|
||||
|
||||
|
||||
# operation mode "minimum energy consumption"
|
||||
if haskey(data["settings"],"operationModeMinimumEnergyConsumption") && data["settings"]["operationModeMinimumEnergyConsumption"]!=nothing
|
||||
if typeof(data["settings"]["operationModeMinimumEnergyConsumption"])==Bool
|
||||
settings.operationModeMinimumEnergyConsumption=data["settings"]["operationModeMinimumEnergyConsumption"]
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of the keyword operationModeMinimumEnergyConsumption is not correct. The value has to be of type boolean.")
|
||||
end
|
||||
else
|
||||
settings.operationModeMinimumEnergyConsumption=false
|
||||
println("WARNING at reading the settings yaml file: The keyword operationModeMinimumEnergyConsumption or its value is missing. Therefore operationModeMinimumEnergyConsumption=",settings.operationModeMinimumEnergyConsumption," is assumed and used.")
|
||||
end
|
||||
delete!(data["settings"], "operationModeMinimumEnergyConsumption")
|
||||
|
||||
# output as "julia dictionary" or as "CSV"
|
||||
if haskey(data["settings"],"typeOfOutput")
|
||||
if typeof(data["settings"]["typeOfOutput"])==String && (data["settings"]["typeOfOutput"]=="julia dictionary" || data["settings"]["typeOfOutput"]=="CSV")
|
||||
settings.typeOfOutput=data["settings"]["typeOfOutput"] # "julia dictionary" or "CSV"
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of typeOfOutput is wrong. It has to be julia dictionary or CSV.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The keyword typeOfOutput is missing. It has to be added with the value julia dictionary or CSV.")
|
||||
end
|
||||
delete!(data["settings"], "typeOfOutput")
|
||||
|
||||
# TODO: it could be checked if the path is existing on the pc
|
||||
if settings.typeOfOutput=="CSV"
|
||||
if haskey(data["settings"],"csvFolderPath")
|
||||
if typeof(data["settings"]["csvFolderPath"])==String
|
||||
settings.csvFolderPath=data["settings"]["csvFolderPath"]
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of csvFolderPath is wrong. It has to be of type String.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The keyword csvFolderPath is missing. It has to be added.")
|
||||
end
|
||||
delete!(data["settings"], "csvFolderPath")
|
||||
end # if
|
||||
|
||||
|
||||
# should the output be "reduced" 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"
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of detailOfOutput is wrong. It has to be reduced 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.")
|
||||
end
|
||||
delete!(data["settings"], "detailOfOutput")
|
||||
|
||||
|
||||
# informing the user, which keywords of the input data are not used in this tool:
|
||||
if length(data["settings"])>0
|
||||
println("INFO at reading the settings yaml file: The following Keywords are not used in this tool:")
|
||||
for key in keys(data["settings"])
|
||||
println(" - ",key)
|
||||
end
|
||||
end
|
||||
|
||||
return settings
|
||||
end # function inputSettings
|
||||
|
||||
end # module RailwayDrivingDynamicsInput
|
|
@ -1,478 +0,0 @@
|
|||
module RailwayDrivingDynamicsOperationModes
|
||||
|
||||
using ..types
|
||||
|
||||
include("./RailwayDrivingDynamicsMovingPhases.jl")
|
||||
include("./RailwayDrivingDynamicsEnergySaving.jl")
|
||||
using .RailwayDrivingDynamicsMovingPhases
|
||||
using .RailwayDrivingDynamicsEnergySaving
|
||||
|
||||
export simulateMinimumRunningTime!, simulateMinimumEnergyConsumption
|
||||
|
||||
function simulateMinimumRunningTime!(movingSection::MovingSection, settings::Settings, vehicle::Vehicle)
|
||||
# this function simulates a train run focussing on using the minimum possible running time
|
||||
startingPoint=Waypoint()
|
||||
startingPoint.i=1
|
||||
drivingCourse=[startingPoint] # List of waypoints
|
||||
drivingCourse[end].s=movingSection.characteristicSections[1].s_start
|
||||
|
||||
for csId in 1:length(movingSection.characteristicSections)
|
||||
# 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/vehicle.a_braking, digits=10)) # ceil is used to be sure that the vehicle stops at s_end in spite of rounding errors
|
||||
|
||||
s_cruising=movingSection.characteristicSections[csId].s_total-s_starting-s_cruisingBeforeAcceleration-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")
|
||||
delete!(movingSection.characteristicSections[csId].behaviorSections, "acceleration")
|
||||
delete!(movingSection.characteristicSections[csId].behaviorSections, "cruising")
|
||||
movingSection.characteristicSections[csId].E_total=0.0
|
||||
movingSection.characteristicSections[csId].t_total=0.0
|
||||
|
||||
if s_cruisingBeforeAcceleration == movingSection.characteristicSections[csId].s_total
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruisingBeforeAcceleration, settings, vehicle, movingSection.characteristicSections, "cruisingBeforeAcceleration")
|
||||
|
||||
elseif s_cruising == movingSection.characteristicSections[csId].s_total
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruising, settings, vehicle, movingSection.characteristicSections, "cruising")
|
||||
|
||||
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
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addAccelerationPhase!(movingSection.characteristicSections[csId], drivingCourse, settings, vehicle, 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/vehicle.a_braking))<-0.001 # ceil is used to be sure that the vehicle stops at s_end 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/vehicle.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)
|
||||
end
|
||||
|
||||
s_braking=max(0.0, ceil((movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/vehicle.a_braking, digits=10)) # ceil is used to be sure that the vehicle stops at s_end in spite of rounding errors
|
||||
s_cruising=movingSection.characteristicSections[csId].s_end-drivingCourse[end].s-s_braking
|
||||
|
||||
if s_cruising>0
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruising, settings, vehicle, movingSection.characteristicSections, "cruising")
|
||||
end
|
||||
else
|
||||
if movingSection.characteristicSections[csId].v_entry<movingSection.characteristicSections[csId].v_reach
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addAccelerationPhaseWithIntersection!(movingSection.characteristicSections[csId], drivingCourse, settings, vehicle, movingSection.characteristicSections)
|
||||
end #if
|
||||
end #if
|
||||
|
||||
|
||||
s_braking=max(0.0, ceil((movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/vehicle.a_braking, digits=10)) # ceil is used to be sure that the vehicle stops at s_end 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, vehicle, movingSection.characteristicSections)
|
||||
end #if
|
||||
|
||||
if drivingCourse[end].s < movingSection.characteristicSections[csId].s_end
|
||||
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)
|
||||
end
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruising, settings, vehicle, movingSection.characteristicSections, "cruising")
|
||||
end
|
||||
end #for
|
||||
|
||||
movingSection.t_total=drivingCourse[end].t # total running time (in s)
|
||||
movingSection.E_total=drivingCourse[end].E # total energy consumption (in Ws)
|
||||
|
||||
return (movingSection, drivingCourse)
|
||||
end #function simulateMinimumRunningTime
|
||||
|
||||
|
||||
function simulateMinimumEnergyConsumption(movingSectionMinimumRunningTime::MovingSection, drivingCourseMinimumRunningTime::Vector{Waypoint}, settings::Settings, vehicle::Vehicle)
|
||||
# this function simulates a train run focussing on using the minimum possible energy consumption
|
||||
# booleans for choosing which methods are used for saving energy
|
||||
doMethod1=true
|
||||
doMethod2=true
|
||||
doCombinationOfMethods=true
|
||||
|
||||
#creating a new moving section for the minimum energy consumption
|
||||
movingSectionOriginal=MovingSection(movingSectionMinimumRunningTime)
|
||||
|
||||
# creating a new driving course for the minimum energy consumption
|
||||
drivingCourseOriginal=Waypoint[]
|
||||
for i in 1:length(drivingCourseMinimumRunningTime)
|
||||
push!(drivingCourseOriginal, Waypoint(drivingCourseMinimumRunningTime[i])) # List of waypoints till the start of energy saving
|
||||
end
|
||||
|
||||
# calculation the recovery time
|
||||
movingSectionOriginal.t_recovery=calculateRecoveryTime(movingSectionOriginal.s_total, movingSectionOriginal.t_total, vehicle)
|
||||
movingSectionOriginal.t_recoveryAvailable=movingSectionOriginal.t_recovery
|
||||
# println("t_recovery=",movingSectionOriginal.t_recovery)
|
||||
|
||||
# creating arrays for each method with all the available energy saving modifications
|
||||
energySavingModificationsWithCoasting=EnergySavingModification[]
|
||||
energySavingModificationsWithMaximumSpeed=EnergySavingModification[]
|
||||
energySavingModificationsWithCombination=EnergySavingModification[]
|
||||
|
||||
for csId in 1:length(movingSectionOriginal.characteristicSections)
|
||||
# method 1: increase coasting
|
||||
if doMethod1==true
|
||||
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=increaseCostingSection(movingSectionOriginal.characteristicSections[csId], drivingCourseOriginal, settings, vehicle, movingSectionOriginal.characteristicSections, movingSectionOriginal.t_recoveryAvailable)
|
||||
if new
|
||||
energySavingModification=EnergySavingModification()
|
||||
energySavingModification.csId=csId # identifier of the characteristic section
|
||||
energySavingModification.type="increasing coasting" # 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)
|
||||
if energySavingModification.Δt<=movingSectionOriginal.t_recoveryAvailable && energySavingModification.ΔE>=0.0
|
||||
energySavingModification.ratio=energySavingModification.ΔE/energySavingModification.Δt # ratio of ΔE and Δt (in Ws/s)
|
||||
elseif energySavingModification.Δt==0.0 #
|
||||
energySavingModification.ratio=energySavingModification.ΔE/0.000000001
|
||||
else # Δt is to high
|
||||
energySavingModification.ratio=0.0
|
||||
end
|
||||
push!(energySavingModificationsWithCoasting, energySavingModification)
|
||||
else # there is no modification possible for the current CS
|
||||
push!(energySavingModificationsWithCoasting, EnergySavingModification())
|
||||
end
|
||||
end #if doMethod1
|
||||
|
||||
# method 2: accelerate to a lower v_reach
|
||||
if doMethod2==true
|
||||
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=decreaseMaximumVelocity(movingSectionOriginal.characteristicSections[csId], drivingCourseOriginal, settings, vehicle, movingSectionOriginal.characteristicSections, movingSectionOriginal.t_recoveryAvailable)
|
||||
if new
|
||||
energySavingModification=EnergySavingModification()
|
||||
energySavingModification.csId=csId # identifier of the characteristic section
|
||||
energySavingModification.type="decreasing maximum velocity" # 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)
|
||||
if energySavingModification.Δt<=movingSectionOriginal.t_recoveryAvailable && energySavingModification.ΔE>=0.0
|
||||
energySavingModification.ratio=energySavingModification.ΔE/energySavingModification.Δt # ratio of ΔE and Δt (in Ws/s)
|
||||
elseif energySavingModification.Δt==0.0
|
||||
energySavingModification.ratio=energySavingModification.ΔE/0.000000001
|
||||
else # Δt is to high or ΔE < 0.0 Ws
|
||||
energySavingModification.ratio=0.0
|
||||
end
|
||||
push!(energySavingModificationsWithMaximumSpeed, energySavingModification)
|
||||
else # there is no modification possible for the current CS
|
||||
push!(energySavingModificationsWithMaximumSpeed, EnergySavingModification())
|
||||
end
|
||||
end #if doMethod2
|
||||
|
||||
|
||||
if doCombinationOfMethods==true
|
||||
# calculating the combination of methods
|
||||
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=combineEnergySavingMethods(movingSectionOriginal.characteristicSections[csId], drivingCourseOriginal, settings, vehicle, movingSectionOriginal.characteristicSections, movingSectionOriginal.t_recoveryAvailable)
|
||||
if new
|
||||
energySavingModification=EnergySavingModification()
|
||||
energySavingModification.csId=csId # identifier of the characteristic section
|
||||
energySavingModification.type="combination of energy saving methods" # 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)
|
||||
if energySavingModification.Δt<=movingSectionOriginal.t_recoveryAvailable && energySavingModification.ΔE>=0.0
|
||||
energySavingModification.ratio=sign(energySavingModification.Δt)*energySavingModification.ΔE/energySavingModification.Δt # ratio of ΔE and Δt (in Ws/s)
|
||||
elseif energySavingModification.Δt==0.0 #
|
||||
energySavingModification.ratio=energySavingModification.ΔE/0.000000001
|
||||
else # Δt is to high or ΔE < 0.0 Ws
|
||||
energySavingModification.ratio=0.0
|
||||
end
|
||||
push!(energySavingModificationsWithCombination, energySavingModification)
|
||||
else # there is no modification possible for the current CS
|
||||
push!(energySavingModificationsWithCombination, EnergySavingModification())
|
||||
end
|
||||
end #if
|
||||
end # for
|
||||
|
||||
|
||||
while (movingSectionOriginal.t_recoveryAvailable>0.0)
|
||||
# comparison of modifications
|
||||
ratioMax=0.0
|
||||
csIdMax=0
|
||||
typeMax="none"
|
||||
for modNr in 1:length(energySavingModificationsWithMaximumSpeed)
|
||||
if energySavingModificationsWithMaximumSpeed[modNr].ratio>ratioMax
|
||||
if energySavingModificationsWithMaximumSpeed[modNr].Δt<=movingSectionOriginal.t_recoveryAvailable
|
||||
ratioMax=energySavingModificationsWithMaximumSpeed[modNr].ratio
|
||||
csIdMax=energySavingModificationsWithMaximumSpeed[modNr].csId
|
||||
typeMax=energySavingModificationsWithMaximumSpeed[modNr].type
|
||||
else # Δt is to high
|
||||
energySavingModificationsWithMaximumSpeed[modNr].ratio=0.0
|
||||
end #if
|
||||
end #if
|
||||
end #for
|
||||
|
||||
for modNr in 1:length(energySavingModificationsWithCoasting)
|
||||
if energySavingModificationsWithCoasting[modNr].ratio>ratioMax
|
||||
if energySavingModificationsWithCoasting[modNr].Δt<=movingSectionOriginal.t_recoveryAvailable
|
||||
ratioMax=energySavingModificationsWithCoasting[modNr].ratio
|
||||
csIdMax=energySavingModificationsWithCoasting[modNr].csId
|
||||
typeMax=energySavingModificationsWithCoasting[modNr].type
|
||||
else # Δt is to high
|
||||
energySavingModificationsWithCoasting[modNr].ratio=0.0
|
||||
end #if
|
||||
end #if
|
||||
end #for
|
||||
|
||||
for modNr in 1:length(energySavingModificationsWithCombination)
|
||||
if energySavingModificationsWithCombination[modNr].ratio>ratioMax
|
||||
if energySavingModificationsWithCombination[modNr].Δt<=movingSectionOriginal.t_recoveryAvailable
|
||||
ratioMax=energySavingModificationsWithCombination[modNr].ratio
|
||||
csIdMax=energySavingModificationsWithCombination[modNr].csId
|
||||
typeMax=energySavingModificationsWithCombination[modNr].type
|
||||
else # Δt is to high
|
||||
energySavingModificationsWithCombination[modNr].ratio=0.0
|
||||
end #if
|
||||
end #if
|
||||
end #for
|
||||
|
||||
|
||||
# selection of most efficient modification and update the original characteristicSection, drivingCourse and movingSection
|
||||
# in case none of the modifications has a ratio>0 stop the calculation
|
||||
if typeMax=="none"
|
||||
break
|
||||
elseif typeMax=="increasing coasting"
|
||||
# println("Energy saving modification number ",length(movingSectionOriginal.energySavingModifications)+1," (coasting) in CS ",csIdMax ," Δt=",energySavingModificationsWithCoasting[csIdMax].Δt," ΔE=", energySavingModificationsWithCoasting[csIdMax].ΔE," t_recoveryAvailable=", movingSectionOriginal.t_recoveryAvailable-energySavingModificationsWithCoasting[csIdMax].Δt)
|
||||
push!(movingSectionOriginal.energySavingModifications, energySavingModificationsWithCoasting[csIdMax])
|
||||
elseif typeMax=="decreasing maximum velocity"
|
||||
# println("Energy saving modification number ",length(movingSectionOriginal.energySavingModifications)+1," (lowering v_reach) in CS ",csIdMax ," Δt=",energySavingModificationsWithCoasting[csIdMax].Δt," ΔE=", energySavingModificationsWithCoasting[csIdMax].ΔE," t_recoveryAvailable=", movingSectionOriginal.t_recoveryAvailable-energySavingModificationsWithCoasting[csIdMax].Δt)
|
||||
push!(movingSectionOriginal.energySavingModifications, energySavingModificationsWithMaximumSpeed[csIdMax])
|
||||
elseif typeMax=="combination of energy saving methods"
|
||||
# println("Energy saving modification number ",length(movingSectionOriginal.energySavingModifications)+1," (combination) in CS ",csIdMax ," Δt=",energySavingModificationsWithCoasting[csIdMax].Δt," ΔE=", energySavingModificationsWithCoasting[csIdMax].ΔE," t_recoveryAvailable=", movingSectionOriginal.t_recoveryAvailable-energySavingModificationsWithCoasting[csIdMax].Δt)
|
||||
push!(movingSectionOriginal.energySavingModifications, energySavingModificationsWithCombination[csIdMax])
|
||||
end #if
|
||||
|
||||
movingSectionOriginal.t_recoveryAvailable=movingSectionOriginal.t_recoveryAvailable-movingSectionOriginal.energySavingModifications[end].Δt
|
||||
|
||||
lastIdOfModifiedCs=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()))))))).waypoints[end]
|
||||
|
||||
drivingCourseNew=Vector{Waypoint}()
|
||||
for i in 1:length(movingSectionOriginal.energySavingModifications[end].drivingCourseModified)
|
||||
push!(drivingCourseNew, Waypoint(movingSectionOriginal.energySavingModifications[end].drivingCourseModified[i]))
|
||||
end
|
||||
|
||||
# # for testing if the modifications driving course and the original one have the same speed value at their transition point
|
||||
# if lastIdOfModifiedCs+1<=drivingCourseOriginal[end].i
|
||||
# if drivingCourseOriginal[lastIdOfModifiedCs].v-drivingCourseNew[end].v!=0.0
|
||||
# println("INFO: Inconsistency while adding the CS",csIdMax," that has been modified for consuming less energy. The difference at its end is ",(drivingCourseOriginal[lastIdOfModifiedCs].v-drivingCourseNew[end].v)," m/s."
|
||||
# end
|
||||
# end # for testing
|
||||
|
||||
#filling up the rest of the driving course
|
||||
drivingCourseNew[end].F_T=drivingCourseOriginal[lastIdOfModifiedCs].F_T
|
||||
drivingCourseNew[end].F_Rt=drivingCourseOriginal[lastIdOfModifiedCs].F_Rt
|
||||
drivingCourseNew[end].F_Rw=drivingCourseOriginal[lastIdOfModifiedCs].F_Rw
|
||||
drivingCourseNew[end].F_Runion=drivingCourseOriginal[lastIdOfModifiedCs].F_Runion
|
||||
drivingCourseNew[end].F_Rp=drivingCourseOriginal[lastIdOfModifiedCs].F_Rp
|
||||
drivingCourseNew[end].F_R=drivingCourseOriginal[lastIdOfModifiedCs].F_R
|
||||
drivingCourseNew[end].a=drivingCourseOriginal[lastIdOfModifiedCs].a
|
||||
|
||||
endOfModificationId=drivingCourseNew[end].i # is needed for updating the other modified driving courses
|
||||
difference=drivingCourseNew[end].i-lastIdOfModifiedCs
|
||||
|
||||
i=lastIdOfModifiedCs+1
|
||||
while (i<=length(drivingCourseOriginal))
|
||||
push!(drivingCourseNew, Waypoint(drivingCourseOriginal[i]))
|
||||
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
|
||||
i=i+1
|
||||
end # while
|
||||
|
||||
# updating all the waypoint references in the behaviour sections of the following characteristic sections and the other modified characteristic sections
|
||||
if difference!= 0
|
||||
allBs=["starting", "cruisingBeforeAcceleration", "acceleration", "cruising", "coasting", "cruisingAfterCoasting", "braking"]
|
||||
for csId in csIdMax+1:length(movingSectionOriginal.characteristicSections)
|
||||
for bs in 1: length(allBs)
|
||||
if haskey(movingSectionOriginal.characteristicSections[csId].behaviorSections, allBs[bs])
|
||||
for point in 1:length(get(movingSectionOriginal.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).waypoints)
|
||||
get(movingSectionOriginal.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).waypoints[point]=get(movingSectionOriginal.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).waypoints[point]+difference
|
||||
end
|
||||
end #if
|
||||
end #for
|
||||
end #for
|
||||
|
||||
# updating the waypoints in the following modified charateristic sections and the following points in the driving course
|
||||
for modNr in csIdMax+1:length(energySavingModificationsWithCoasting)
|
||||
if energySavingModificationsWithCoasting[modNr].ratio>0
|
||||
# updating the behavior sections of the modified charateristic section
|
||||
for bs in 1: length(allBs)
|
||||
if haskey(energySavingModificationsWithCoasting[modNr].csModified.behaviorSections, allBs[bs])
|
||||
for point in 1:length(get(energySavingModificationsWithCoasting[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).waypoints)
|
||||
get(energySavingModificationsWithCoasting[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).waypoints[point]=get(energySavingModificationsWithCoasting[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).waypoints[point]+difference
|
||||
end
|
||||
end #if
|
||||
end #for
|
||||
|
||||
# correctig the points of the modified driving course
|
||||
drivingCourseModifiedNew=Vector{Waypoint}()
|
||||
for i in 1:endOfModificationId
|
||||
push!(drivingCourseModifiedNew, Waypoint(drivingCourseNew[i]))
|
||||
end # while
|
||||
i=lastIdOfModifiedCs+1
|
||||
while (i<=length(energySavingModificationsWithCoasting[modNr].drivingCourseModified))
|
||||
push!(drivingCourseModifiedNew, Waypoint(energySavingModificationsWithCoasting[modNr].drivingCourseModified[i]))
|
||||
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
|
||||
i=i+1
|
||||
end # while
|
||||
|
||||
energySavingModificationsWithCoasting[modNr].drivingCourseModified=drivingCourseModifiedNew
|
||||
end #if
|
||||
end #for
|
||||
|
||||
for modNr in csIdMax+1:length(energySavingModificationsWithMaximumSpeed)
|
||||
if energySavingModificationsWithMaximumSpeed[modNr].ratio>0
|
||||
# updating the behavior sections of the modified charateristic section
|
||||
for bs in 1: length(allBs)
|
||||
if haskey(energySavingModificationsWithMaximumSpeed[modNr].csModified.behaviorSections, allBs[bs])
|
||||
for point in 1:length(get(energySavingModificationsWithMaximumSpeed[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).waypoints)
|
||||
get(energySavingModificationsWithMaximumSpeed[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).waypoints[point]=get(energySavingModificationsWithMaximumSpeed[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).waypoints[point]+difference
|
||||
end
|
||||
end #if
|
||||
end #for
|
||||
|
||||
# correctig the points of the modified driving course
|
||||
drivingCourseModifiedNew=Vector{Waypoint}()
|
||||
for i in 1:endOfModificationId
|
||||
push!(drivingCourseModifiedNew, Waypoint(drivingCourseNew[i]))
|
||||
end # while
|
||||
i=lastIdOfModifiedCs+1
|
||||
while (i<=length(energySavingModificationsWithMaximumSpeed[modNr].drivingCourseModified))
|
||||
push!(drivingCourseModifiedNew, Waypoint(energySavingModificationsWithMaximumSpeed[modNr].drivingCourseModified[i]))
|
||||
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
|
||||
i=i+1
|
||||
end # while
|
||||
|
||||
energySavingModificationsWithMaximumSpeed[modNr].drivingCourseModified=drivingCourseModifiedNew
|
||||
end #if
|
||||
end #for
|
||||
|
||||
|
||||
for modNr in csIdMax+1:length(energySavingModificationsWithCombination)
|
||||
if energySavingModificationsWithCombination[modNr].ratio>0
|
||||
# updating the behavior sections of the modified charateristic section
|
||||
for bs in 1: length(allBs)
|
||||
if haskey(energySavingModificationsWithCombination[modNr].csModified.behaviorSections, allBs[bs])
|
||||
for point in 1:length(get(energySavingModificationsWithCombination[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).waypoints)
|
||||
get(energySavingModificationsWithCombination[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).waypoints[point]=get(energySavingModificationsWithCombination[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).waypoints[point]+difference
|
||||
end
|
||||
end #if
|
||||
end #for
|
||||
|
||||
# updating the points of the modified driving course
|
||||
drivingCourseModifiedNew=Vector{Waypoint}()
|
||||
for i in 1:endOfModificationId
|
||||
push!(drivingCourseModifiedNew, Waypoint(drivingCourseNew[i]))
|
||||
end # while
|
||||
i=lastIdOfModifiedCs+1
|
||||
while (i<=length(energySavingModificationsWithCombination[modNr].drivingCourseModified))
|
||||
push!(drivingCourseModifiedNew, Waypoint(energySavingModificationsWithCombination[modNr].drivingCourseModified[i]))
|
||||
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
|
||||
i=i+1
|
||||
end # while
|
||||
|
||||
energySavingModificationsWithCombination[modNr].drivingCourseModified=drivingCourseModifiedNew
|
||||
end #if
|
||||
end #for
|
||||
end # if difference
|
||||
|
||||
|
||||
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)
|
||||
|
||||
|
||||
# modify new CS for the considered methods
|
||||
# method 1: increase coasting
|
||||
if doMethod1==true
|
||||
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=increaseCostingSection(movingSectionOriginal.characteristicSections[csIdMax], drivingCourseOriginal, settings, vehicle, movingSectionOriginal.characteristicSections, movingSectionOriginal.t_recoveryAvailable)
|
||||
if new
|
||||
energySavingModification=EnergySavingModification()
|
||||
energySavingModification.csId=csIdMax # identifier of the characteristic section
|
||||
energySavingModification.type="increasing coasting" # 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[csIdMax].E_total-energySavingModification.csModified.E_total # saved energy (in Ws)
|
||||
energySavingModification.Δt=energySavingModification.csModified.t_total-movingSectionOriginal.characteristicSections[csIdMax].t_total # time loss (in s)
|
||||
if energySavingModification.Δt<=movingSectionOriginal.t_recoveryAvailable && energySavingModification.ΔE>=0.0 #&& energySavingModification.Δt>0.0
|
||||
energySavingModification.ratio=energySavingModification.ΔE/energySavingModification.Δt # ratio of ΔE and Δt (in Ws/s)
|
||||
elseif energySavingModification.Δt==0.0
|
||||
energySavingModification.ratio=energySavingModification.ΔE/0.000000001
|
||||
else # Δt is to high
|
||||
energySavingModification.ratio=0.0
|
||||
end
|
||||
energySavingModificationsWithCoasting[csIdMax]=energySavingModification
|
||||
else # there is no modification possible for the current CS
|
||||
energySavingModificationsWithCoasting[csIdMax]=EnergySavingModification()
|
||||
end
|
||||
end #if if doMethod1
|
||||
|
||||
# method 2: accelerate to a lower v_reach
|
||||
if doMethod2==true
|
||||
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=decreaseMaximumVelocity(movingSectionOriginal.characteristicSections[csIdMax], drivingCourseOriginal, settings, vehicle, movingSectionOriginal.characteristicSections, movingSectionOriginal.t_recoveryAvailable)
|
||||
if new
|
||||
energySavingModification=EnergySavingModification()
|
||||
energySavingModification.csId=csIdMax # identifier of the characteristic section
|
||||
energySavingModification.type="decreasing maximum velocity" # 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[csIdMax].E_total-energySavingModification.csModified.E_total # saved energy (in Ws)
|
||||
energySavingModification.Δt=energySavingModification.csModified.t_total-movingSectionOriginal.characteristicSections[csIdMax].t_total # time loss (in s)
|
||||
if energySavingModification.Δt<=movingSectionOriginal.t_recoveryAvailable && energySavingModification.ΔE>=0.0
|
||||
energySavingModification.ratio=energySavingModification.ΔE/energySavingModification.Δt # ratio of ΔE and Δt (in Ws/s)
|
||||
elseif energySavingModification.Δt==0.0
|
||||
energySavingModification.ratio=energySavingModification.ΔE/0.000000001
|
||||
else # Δt is to high
|
||||
energySavingModification.ratio=0.0
|
||||
end
|
||||
energySavingModificationsWithMaximumSpeed[csIdMax]=energySavingModification
|
||||
else # there is no modification possible for the current CS
|
||||
energySavingModificationsWithMaximumSpeed[csIdMax]=EnergySavingModification()
|
||||
end
|
||||
end #if if doMethod
|
||||
|
||||
|
||||
# combination of both methods
|
||||
if doCombinationOfMethods==true
|
||||
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=combineEnergySavingMethods(movingSectionOriginal.characteristicSections[csIdMax], drivingCourseOriginal, settings, vehicle, movingSectionOriginal.characteristicSections, movingSectionOriginal.t_recoveryAvailable)
|
||||
if new
|
||||
energySavingModification=EnergySavingModification()
|
||||
energySavingModification.csId=csIdMax # identifier of the characteristic section
|
||||
energySavingModification.type="combination of energy saving methods" # 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[csIdMax].E_total-energySavingModification.csModified.E_total # saved energy (in Ws)
|
||||
energySavingModification.Δt=energySavingModification.csModified.t_total-movingSectionOriginal.characteristicSections[csIdMax].t_total # time loss (in s)
|
||||
if energySavingModification.Δt<=movingSectionOriginal.t_recoveryAvailable && energySavingModification.ΔE>=0.0
|
||||
energySavingModification.ratio=energySavingModification.ΔE/energySavingModification.Δt # ratio of ΔE and Δt (in Ws/s)
|
||||
elseif energySavingModification.Δt==0.0 #
|
||||
println("Energiesparanpassung durch Kombination bei CS ",csIdMax," ist 0 s. Das kann eigentlich nicht sein!")
|
||||
energySavingModification.ratio=energySavingModification.ΔE/0.000000001
|
||||
else # Δt is to high
|
||||
energySavingModification.ratio=0.0
|
||||
end
|
||||
energySavingModificationsWithCombination[csIdMax]=energySavingModification
|
||||
else # there is no modification possible for the current CS
|
||||
energySavingModificationsWithCombination[csIdMax]=EnergySavingModification()
|
||||
end
|
||||
end #if doCombinationOfMethods
|
||||
end # while
|
||||
|
||||
# println("t_recoveryAvailable=",movingSectionOriginal.t_recoveryAvailable)
|
||||
return (movingSectionOriginal, drivingCourseOriginal)
|
||||
end #function simulateMinimumEnergyConsumption
|
||||
|
||||
end #module RailwayDrivingDynamicsOperationModes
|
|
@ -1,37 +1,45 @@
|
|||
module RailwayDrivingDynamics
|
||||
module TrainRun
|
||||
|
||||
include("./types.jl")
|
||||
include("./RailwayDrivingDynamicsInput.jl")
|
||||
include("./RailwayDrivingDynamicsPreparation.jl")
|
||||
include("./RailwayDrivingDynamicsOperationModes.jl")
|
||||
include("./RailwayDrivingDynamicsOutput.jl")
|
||||
include("./Input.jl")
|
||||
include("./Preparation.jl")
|
||||
include("./OperationModes.jl")
|
||||
include("./Output.jl")
|
||||
|
||||
|
||||
using .types
|
||||
using .RailwayDrivingDynamicsInput
|
||||
using .RailwayDrivingDynamicsPreparation
|
||||
using .RailwayDrivingDynamicsOperationModes
|
||||
using .RailwayDrivingDynamicsOutput
|
||||
using .Input
|
||||
using .Preparation
|
||||
using .OperationModes
|
||||
using .Output
|
||||
|
||||
export calculateDrivingDynamics
|
||||
|
||||
function calculateDrivingDynamics(vehicleFilePath::String, pathFilePath::String, settingsFilePath::String)
|
||||
# main function for calculating the driving dynamics
|
||||
println("")
|
||||
println("")
|
||||
println("")
|
||||
"""
|
||||
calculateDrivingDynamics(trainFilePath::String, pathFilePath::String, settingsFilePath::String)
|
||||
|
||||
Calculate the driving dynamics of a train run on a path with special settings with information from the corresponding YAML files with the file paths `trainFilePath`, `pathFilePath`, `settingsFilePath`.
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> calculateDrivingDynamics(C:\\folder\\train.yaml, C:\\folder\\path.yaml, C:\\folder\\settings.yaml)
|
||||
todo !!!
|
||||
```
|
||||
"""
|
||||
function calculateDrivingDynamics(trainFilePath::String, pathFilePath::String, settingsFilePath::String)
|
||||
print("\n\n\n")
|
||||
|
||||
# input
|
||||
(vehicle, path, settings)=readInput(vehicleFilePath, pathFilePath, settingsFilePath)
|
||||
(train, path, settings)=readInput(trainFilePath, pathFilePath, settingsFilePath)
|
||||
println("The input has been saved.")
|
||||
|
||||
|
||||
# preparing the input data
|
||||
movingSection=preparateSections(path, vehicle, settings)
|
||||
println("The moving section has been preparated.")
|
||||
movingSection=preparateSections(path, train, settings)
|
||||
println("The moving section has been prepared.")
|
||||
|
||||
if settings.operationModeMinimumRunningTime==true || settings.operationModeMinimumEnergyConsumption==true
|
||||
(movingSectionMinimumRunningTime, drivingCourseMinimumRunningTime)=simulateMinimumRunningTime!(movingSection, settings, vehicle)
|
||||
(movingSectionMinimumRunningTime, drivingCourseMinimumRunningTime)=simulateMinimumRunningTime!(movingSection, settings, train)
|
||||
# println("t_total=", drivingCourseMinimumRunningTime[end].t)
|
||||
# printSectionInformation(movingSectionMinimumRunningTime)
|
||||
println("The driving course for the shortest running time has been calculated.")
|
||||
|
@ -40,25 +48,25 @@ function calculateDrivingDynamics(vehicleFilePath::String, pathFilePath::String,
|
|||
|
||||
# oparation mode "minimum energy consumption"
|
||||
if settings.operationModeMinimumEnergyConsumption==true
|
||||
(movingSectionMinimumEnergyConsumption, drivingCourseMinimumEnergyConsumption)=simulateMinimumEnergyConsumption(movingSectionMinimumRunningTime, drivingCourseMinimumRunningTime, settings, vehicle)
|
||||
(movingSectionMinimumEnergyConsumption, drivingCourseMinimumEnergyConsumption)=simulateMinimumEnergyConsumption(movingSectionMinimumRunningTime, drivingCourseMinimumRunningTime, settings, train)
|
||||
# printSectionInformation(movingSectionMinimumEnergyConsumption)
|
||||
println("The driving course for the energy consumption has been calculated.")
|
||||
println("The driving course for lowest the energy consumption has been calculated.")
|
||||
end #if
|
||||
|
||||
#output
|
||||
if settings.operationModeMinimumRunningTime==true && settings.operationModeMinimumEnergyConsumption==true
|
||||
plotDrivingCourse(drivingCourseMinimumRunningTime, drivingCourseMinimumEnergyConsumption)
|
||||
return createOutput(settings, path.name, vehicle.name, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||
return createOutput(settings, path.name, train.name, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||
elseif settings.operationModeMinimumRunningTime==true
|
||||
plotDrivingCourse(drivingCourseMinimumRunningTime)
|
||||
return createOutput(settings, path.name, vehicle.name, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime)
|
||||
return createOutput(settings, path.name, train.name, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime)
|
||||
elseif settings.operationModeMinimumEnergyConsumption==true
|
||||
plotDrivingCourse(drivingCourseMinimumEnergyConsumption)
|
||||
return createOutput(settings, path.name, vehicle.name, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||
return createOutput(settings, path.name, train.name, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||
else
|
||||
println("No Output was demanded. So no output is created.")
|
||||
return Dict()
|
||||
end
|
||||
end # function calculateDrivingDynamics
|
||||
|
||||
end # module RailwayDrivingDynamics
|
||||
end # module TrainRun
|
21
src/types.jl
21
src/types.jl
|
@ -1,6 +1,6 @@
|
|||
module types
|
||||
# definition of all the additional types and their constructors
|
||||
export Settings, Vehicle, PathSection, Path, Waypoint, BehaviorSection, CharacteristicSection, EnergySavingModification, MovingSection
|
||||
export Settings, Train, PathSection, Path, Waypoint, BehaviorSection, CharacteristicSection, EnergySavingModification, MovingSection # tried to insert copy on 15.07.2021 , copy
|
||||
|
||||
## settings for the simulation
|
||||
mutable struct Settings
|
||||
|
@ -17,16 +17,16 @@ end # mutable struct Settings
|
|||
Settings()=Settings("", "", 0.0, false, false, "", "", "")
|
||||
|
||||
|
||||
## vehicle
|
||||
mutable struct Vehicle
|
||||
name::String # vehicles name
|
||||
id # vehicles identifier
|
||||
vehicleType::String # type of vehicle "passenger" or "freight" or "motor coach train"
|
||||
## train
|
||||
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)
|
||||
v_limit::AbstractFloat # vehicles speed limit (in m/s)
|
||||
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)
|
||||
ξ_union::AbstractFloat # rotation mass factor of the whole vehicle union (without unit)
|
||||
ξ_union::AbstractFloat # rotation mass factor of the whole train union (without unit)
|
||||
# if not available use ξ_t and ξ_w
|
||||
|
||||
# traction unit
|
||||
|
@ -51,8 +51,8 @@ mutable struct Vehicle
|
|||
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 ‰)
|
||||
Δv_w::AbstractFloat # coefficient for velocitiy difference between set of wagons and outdoor air (in m/s)
|
||||
end # mutable struct Vehicle
|
||||
Vehicle()=Vehicle("", 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, 0.0, 0.0)
|
||||
end # mutable struct Train
|
||||
Train()=Train("", 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, 0.0, 0.0)
|
||||
|
||||
|
||||
## path separated in smaler sections
|
||||
|
@ -100,6 +100,7 @@ mutable struct Waypoint
|
|||
F_Rw::AbstractFloat # set of wagons resistance (in N)
|
||||
end # mutable struct Waypoint
|
||||
Waypoint()=Waypoint(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::Waypoint)=Waypoint(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)
|
||||
Waypoint(original::Waypoint)=Waypoint(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)
|
||||
|
||||
|
||||
|
|
|
@ -1,70 +1,38 @@
|
|||
# Ausführen im pkg mode mit >>>>> ] test RailwayDrivingDynamics <<<<
|
||||
# access in pkg mode with >>>>> ] test TrainRun <<<<
|
||||
|
||||
using RailwayDrivingDynamics, Test
|
||||
using TrainRun, Test
|
||||
|
||||
|
||||
# das hier waren die zu testenden Funktionen:
|
||||
#foo(x::T, y::T) where T <: Real = x + y - 5
|
||||
#bar(z::Float64) = foo(sqrt(z), z)
|
||||
#=
|
||||
That file may typically contain calls to other
|
||||
test files via include(fname). In our case there
|
||||
is only two functions to test, so we will just
|
||||
write in runtests.jl directly:
|
||||
=#
|
||||
allPaths=[]
|
||||
push!(allPaths, "../data/paths/path_1_10km_nConst_vConst.yaml")
|
||||
push!(allPaths, "../data/paths/path_2_10km_nVar_vConst.yaml")
|
||||
push!(allPaths, "../data/paths/path_3_10km_nConst_vVar.yaml")
|
||||
push!(allPaths, "../data/paths/path_4_real_Ostsachsen_DG-DN_spp_5.yaml")
|
||||
|
||||
# todo: Beispiel:
|
||||
#=
|
||||
@testset "foo" begin
|
||||
x, y = 5, 7
|
||||
@test foo(x, y) == 7
|
||||
x = "blah"
|
||||
@test_throws MethodError foo(x, y)
|
||||
allSettings=[]
|
||||
push!(allSettings, "../data/settings.yaml")
|
||||
|
||||
allTrains=[]
|
||||
push!(allTrains, "../data/trains/train_freight_V90withOreConsist.yaml")
|
||||
push!(allTrains, "../data/trains/train_yaml_files\\train_passenger_SiemensDesiroClassic.yaml")
|
||||
push!(allTrains, "../data/trains/train_passenger_IC2.yaml")
|
||||
|
||||
for pathDirectory in allPaths
|
||||
# println("")
|
||||
# println(" - - - - - - - - -")
|
||||
# println("path: ", pathDirectory)
|
||||
for trainDirectory in allTrains
|
||||
# println("train: ", trainDirectory)
|
||||
for settingsDirectory in allSettings
|
||||
testDict=calculateDrivingDynamics(trainDirectory, pathDirectory, settingsDirectory)
|
||||
|
||||
sleep(2)
|
||||
|
||||
# println("")
|
||||
# println("")
|
||||
# println("")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@testset "bar" begin
|
||||
z = 4.
|
||||
@test bar(z) == 1.
|
||||
end =#
|
||||
|
||||
|
||||
|
||||
#vehicleFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Fahrzeug- und Streckendaten\\Fahrzeuge\\vehicle_passenger_IC2.yaml"
|
||||
#vehicleFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Fahrzeug- und Streckendaten\\Fahrzeuge\\vehicle_passenger_SiemensDesiroClassic.yaml"
|
||||
vehicleFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Fahrzeug- und Streckendaten\\Fahrzeuge\\vehicle_freight_V90withOreConsist.yaml"
|
||||
|
||||
#pathFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Fahrzeug- und Streckendaten\\Strecken\\path_10km_noGradient.yaml"
|
||||
pathFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Fahrzeug- und Streckendaten\\Strecken\\path_10km_differentGradient.yaml"
|
||||
#pathFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Fahrzeug- und Streckendaten\\Strecken\\path_10km_different_v_limits.yaml"
|
||||
#pathFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Fahrzeug- und Streckendaten\\Strecken\\path_real_Ostsachsen_V220_DG-DN_spp_5.yaml"
|
||||
|
||||
settingsFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Julia-Files\\settings.yaml"
|
||||
#settingsFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Julia-Files\\settings_s.yaml"
|
||||
|
||||
testDict=calculateDrivingDynamics(vehicleFilePath, pathFilePath, settingsFilePath)
|
||||
|
||||
println("Vergleichswerte für FBS berechnet")
|
||||
|
||||
#=
|
||||
|
||||
#pathFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Julia-Files\\track_DAFW_DAFN.yaml"
|
||||
#pathFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Julia-Files\\test.yaml"
|
||||
settingsFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Julia-Files\\settings.yaml"
|
||||
testDict=calculateDrivingDynamics(vehicleFilePath, pathFilePath, settingsFilePath)
|
||||
|
||||
vehicleFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Julia-Files\\vehicle.yaml"
|
||||
pathFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Julia-Files\\track_DAFW_DAFN.yaml"
|
||||
#pathFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Julia-Files\\path_Heilbronn.yaml"
|
||||
|
||||
settingsFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Julia-Files\\settings.yaml"
|
||||
|
||||
calculateDrivingDynamics(vehicleFilePath, pathFilePath, settingsFilePath)
|
||||
|
||||
=#
|
||||
println("test finished")
|
||||
|
||||
|
||||
|
||||
# toto: einfach so ausführen geht nicht.
|
||||
# da muss ich wahrscheilich noch anders importieren oder auf das Modul verweisen?
|
||||
# Ausführen kann ich es aber auch mit>>>>> test RailwayDrivingDynamics <<<< im pkg mode. Das geht.
|
||||
|
|
Loading…
Reference in New Issue