Refactor the mutable struct EnergySaving and rename some variables

pull/1/head
Max Kannenberg 2021-12-22 15:10:36 +01:00
parent fd0476ad1f
commit e1ad3f917d
8 changed files with 234 additions and 188 deletions

View File

@ -145,7 +145,7 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
s_cruising=max(0.0, s_cruising) s_cruising=max(0.0, s_cruising)
# copy csOriginal to csModified # copy csOriginal to csModified
csModified=CharacteristicSection(csOriginal.id, csOriginal.length, csOriginal.s_entry, csOriginal.s_exit, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_target, csOriginal.v_entry, csOriginal.v_exit, csOriginal.f_Rp, Dict{Symbol, BehaviorSection}()) csModified=CharacteristicSection(csOriginal.id, csOriginal.length, csOriginal.s_entry, csOriginal.s_exit, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_peak, csOriginal.v_entry, csOriginal.v_exit, csOriginal.r_path, Dict{Symbol, BehaviorSection}())
if haskey(csOriginal.behaviorSections, :breakFree) if haskey(csOriginal.behaviorSections, :breakFree)
breakFreeSection=BehaviorSection(csOriginal.behaviorSections[:breakFree]) breakFreeSection=BehaviorSection(csOriginal.behaviorSections[:breakFree])
merge!(csModified.behaviorSections, Dict(:breakFree=>breakFreeSection)) merge!(csModified.behaviorSections, Dict(:breakFree=>breakFreeSection))
@ -210,7 +210,7 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
# TODO: At the moment diminishing is reduced like the acceleration in decreaseMaximumVelocity. To reduce code the methods for reducing cruising phase and reducing the diminishing phase can be combined in some parts. # TODO: At the moment diminishing is reduced like the acceleration in decreaseMaximumVelocity. To reduce code the methods for reducing cruising phase and reducing the diminishing phase can be combined in some parts.
# copy csOriginal to csModified # copy csOriginal to csModified
csModified=CharacteristicSection(csOriginal.id, csOriginal.length, csOriginal.s_entry, csOriginal.s_exit, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_target, csOriginal.v_entry, csOriginal.v_exit, csOriginal.f_Rp, Dict{Symbol, BehaviorSection}()) csModified=CharacteristicSection(csOriginal.id, csOriginal.length, csOriginal.s_entry, csOriginal.s_exit, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_peak, csOriginal.v_entry, csOriginal.v_exit, csOriginal.r_path, Dict{Symbol, BehaviorSection}())
if haskey(csOriginal.behaviorSections, :breakFree) if haskey(csOriginal.behaviorSections, :breakFree)
breakFreeSection=BehaviorSection(csOriginal.behaviorSections[:breakFree]) breakFreeSection=BehaviorSection(csOriginal.behaviorSections[:breakFree])
merge!(csModified.behaviorSections, Dict(:breakFree=>breakFreeSection)) merge!(csModified.behaviorSections, Dict(:breakFree=>breakFreeSection))
@ -296,15 +296,15 @@ end # function increaseCoastingSection
# method 2 with shortening the acceleration by stepsize # method 2 with shortening the acceleration by stepsize
function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse, settings::Dict, train::Dict, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat) function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse, settings::Dict, train::Dict, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
#function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat) #function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
if haskey(csOriginal.behaviorSections, :acceleration) && csOriginal.v_target > csOriginal.v_entry && csOriginal.v_target > csOriginal.v_exit if haskey(csOriginal.behaviorSections, :acceleration) && csOriginal.v_peak > csOriginal.v_entry && csOriginal.v_peak > csOriginal.v_exit
accelerationSection = BehaviorSection(csOriginal.behaviorSections[:acceleration]) accelerationSection = BehaviorSection(csOriginal.behaviorSections[:acceleration])
if drivingCourse[accelerationSection.dataPoints[end]-1].v < csOriginal.v_exit if drivingCourse[accelerationSection.dataPoints[end]-1].v < csOriginal.v_exit
return (CharacteristicSection(), [], false) return (CharacteristicSection(), [], false)
# TODO: or calculate a new acceleration phase with v_exit as v_target? it will be very short, shorter than the step size. # TODO: or calculate a new acceleration phase with v_exit as v_peak? it will be very short, shorter than the step size.
end end
# copy csOriginal to csModified # copy csOriginal to csModified
csModified=CharacteristicSection(csOriginal.id, csOriginal.length, csOriginal.s_entry, csOriginal.s_exit, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_target, csOriginal.v_entry, csOriginal.v_exit, csOriginal.f_Rp, Dict{Symbol, BehaviorSection}()) csModified=CharacteristicSection(csOriginal.id, csOriginal.length, csOriginal.s_entry, csOriginal.s_exit, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_peak, csOriginal.v_entry, csOriginal.v_exit, csOriginal.r_path, Dict{Symbol, BehaviorSection}())
if haskey(csOriginal.behaviorSections, :breakFree) if haskey(csOriginal.behaviorSections, :breakFree)
breakFreeSection=BehaviorSection(csOriginal.behaviorSections[:breakFree]) breakFreeSection=BehaviorSection(csOriginal.behaviorSections[:breakFree])
@ -342,8 +342,8 @@ function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCours
energySavingStartId=get(csOriginal.behaviorSections, :clearing, get(csOriginal.behaviorSections, :acceleration, BehaviorSection())).dataPoints[1] energySavingStartId=get(csOriginal.behaviorSections, :clearing, get(csOriginal.behaviorSections, :acceleration, BehaviorSection())).dataPoints[1]
end end
# TODO: should v_target be reduced or is it enough to pop the data points? # TODO: should v_peak be reduced or is it enough to pop the data points?
# characteristicSection.v_target=drivingCourse[end].v # setting v_target to the last data point's velocity which is the highest reachable value in this characteristic section # characteristicSection.v_peak=drivingCourse[end].v # setting v_peak to the last data point's velocity which is the highest reachable value in this characteristic section
# copy the drivingCourse till the beginning of energy saving # copy the drivingCourse till the beginning of energy saving
drivingCourseModified=Vector{DataPoint}() drivingCourseModified=Vector{DataPoint}()
@ -351,7 +351,7 @@ function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCours
push!(drivingCourseModified, DataPoint(drivingCourse[i])) # List of data points till the start of energy saving push!(drivingCourseModified, DataPoint(drivingCourse[i])) # List of data points till the start of energy saving
end end
#s_braking=max(0.0, ceil((csModified.v_exit^2-csModified.v_target^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors #s_braking=max(0.0, ceil((csModified.v_exit^2-csModified.v_peak^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
s_braking=max(0.0, ceil((csModified.v_exit^2-drivingCourseModified[end].v^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors s_braking=max(0.0, ceil((csModified.v_exit^2-drivingCourseModified[end].v^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
s_cruising=csModified.s_exit-drivingCourseModified[end].s-s_braking s_cruising=csModified.s_exit-drivingCourseModified[end].s-s_braking
@ -366,11 +366,11 @@ function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCours
elseif drivingCourseModified[end].s<csModified.s_exit elseif drivingCourseModified[end].s<csModified.s_exit
if (csModified.s_exit-drivingCourseModified[end].s)>0.001 if (csModified.s_exit-drivingCourseModified[end].s)>0.001
# if (csModified.s_exit-drivingCourseModified[end].s)>10^(-approximationLevel) # if (csModified.s_exit-drivingCourseModified[end].s)>10^(-approximationLevel)
# println("INFO: The end of new CS",csModified.id," is not reached while saving energy with lowering v_target.") # println("INFO: The end of new CS",csModified.id," is not reached while saving energy with lowering v_peak.")
# println(" Therefore the calculation of this method can not continue for this CS.") # println(" Therefore the calculation of this method can not continue for this CS.")
return (CharacteristicSection(), [], false) return (CharacteristicSection(), [], false)
end end
println("WARNING: The end of new CS",csModified.id," is not reached while saving energy with lowering v_target.") println("WARNING: The end of new CS",csModified.id," is not reached while saving energy with lowering v_peak.")
println(" Therefore s=",drivingCourseModified[end].s," will be set s_exit=",csModified.s_exit," because the difference is only ",csModified.s_exit-drivingCourseModified[end].s," m.") println(" Therefore s=",drivingCourseModified[end].s," will be set s_exit=",csModified.s_exit," because the difference is only ",csModified.s_exit-drivingCourseModified[end].s," m.")
println(" v=",drivingCourseModified[end].v," m/s v_exit=",csOriginal.v_exit ," m/s") println(" v=",drivingCourseModified[end].v," m/s v_exit=",csOriginal.v_exit ," m/s")
@ -381,7 +381,7 @@ function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCours
return (csModified, drivingCourseModified, true) return (csModified, drivingCourseModified, true)
else # time loss is to high. so there is no energy saving modification for this CS with the available recovery time else # time loss is to high. so there is no energy saving modification for this CS with the available recovery time
# 09/06 old: else # time loss is to high and the CS has to be calculated again with larger acceleration section (so with a smaller reduction of the acceleration section) # 09/06 old: else # time loss is to high and the CS has to be calculated again with larger acceleration section (so with a smaller reduction of the acceleration section)
# 09/06 old: accelerationReduction=min(accelerationReduction/10, csModified.v_target-csModified.v_entry, csModified.v_target-csModified.v_exit) # 09/06 old: accelerationReduction=min(accelerationReduction/10, csModified.v_peak-csModified.v_entry, csModified.v_peak-csModified.v_exit)
# TODO: just return false or take smaller steps? # TODO: just return false or take smaller steps?
return (CharacteristicSection(), [], false) return (CharacteristicSection(), [], false)
@ -393,14 +393,14 @@ function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCours
# 09/06 old: return (CharacteristicSection(), [], false) # 09/06 old: return (CharacteristicSection(), [], false)
else else
# there is no energy saving modification for this CS because v_target can not be lowered below v_entry or v_exit or because there is no acceleration section that can be transformed into a cruising section # there is no energy saving modification for this CS because v_peak can not be lowered below v_entry or v_exit or because there is no acceleration section that can be transformed into a cruising section
return (CharacteristicSection(), [], false) return (CharacteristicSection(), [], false)
end #if haskey end #if haskey
end # function decreaseMaximumVelocity end # function decreaseMaximumVelocity
# combination of method 1 and method 2 # combination of method 1 and method 2
function combineEnergySavingMethods(csOriginal::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat) function combineEnergySavingMethods(csOriginal::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
# if haskey(csOriginal.behaviorSections, :acceleration) && (haskey(csOriginal.behaviorSections, :braking) || haskey(csOriginal.behaviorSections, :coasting)) && csOriginal.v_target>csOriginal.v_entry && csOriginal.v_target>csOriginal.v_exit # if haskey(csOriginal.behaviorSections, :acceleration) && (haskey(csOriginal.behaviorSections, :braking) || haskey(csOriginal.behaviorSections, :coasting)) && csOriginal.v_peak>csOriginal.v_entry && csOriginal.v_peak>csOriginal.v_exit
if haskey(csOriginal.behaviorSections, :acceleration) && (haskey(csOriginal.behaviorSections, :braking) || haskey(csOriginal.behaviorSections, :coasting)) && drivingCourse[get(csOriginal.behaviorSections, :acceleration, BehaviorSection()).dataPoints[end]].v > max(csOriginal.v_entry, csOriginal.v_exit) if haskey(csOriginal.behaviorSections, :acceleration) && (haskey(csOriginal.behaviorSections, :braking) || haskey(csOriginal.behaviorSections, :coasting)) && drivingCourse[get(csOriginal.behaviorSections, :acceleration, BehaviorSection()).dataPoints[end]].v > max(csOriginal.v_entry, csOriginal.v_exit)
csCombined=CharacteristicSection(csOriginal) csCombined=CharacteristicSection(csOriginal)
drivingCourseCombined=Vector{DataPoint}() drivingCourseCombined=Vector{DataPoint}()
@ -432,7 +432,7 @@ function combineEnergySavingMethods(csOriginal::CharacteristicSection, drivingCo
end # while end # while
return (csCombined, drivingCourseCombined, (ΔE>0.0))# && Δt>0.0)) return (csCombined, drivingCourseCombined, (ΔE>0.0))# && Δt>0.0))
else else
# there is no energy saving modification for this CS because v_target can not be lowered below v_entry or v_exit or because there is no acceleration section and braking section or coasting section that can be transformed into a cruising section or coasting section # there is no energy saving modification for this CS because v_peak can not be lowered below v_entry or v_exit or because there is no acceleration section and braking section or coasting section that can be transformed into a cruising section or coasting section
return (CharacteristicSection(), [], false) return (CharacteristicSection(), [], false)
end #if end #if
end #function combineEnergySavingMethods end #function combineEnergySavingMethods

View File

@ -21,11 +21,11 @@ Read the train information from a YAML file, save it in a train Dict and return
""" """
function inputTrain(trainDirectory::String) function inputTrain(trainDirectory::String)
data = YAML.load(open(trainDirectory)) data = YAML.load(open(trainDirectory))
collect(keys(data)) #collect(keys(data))
collect(values(data)) #collect(values(data))
if haskey(data["train"],"name") if haskey(data["train"],"name")
name=data["train"]["name"] # trains name name=data["train"]["name"] # train's name
delete!(data["train"], "name") delete!(data["train"], "name")
else else
error("ERROR at reading the train yaml file: The keyword name is missing. It has to be added.") error("ERROR at reading the train yaml file: The keyword name is missing. It has to be added.")
@ -46,7 +46,7 @@ function inputTrain(trainDirectory::String)
if haskey(data["train"],"l_train") if haskey(data["train"],"l_train")
if typeof(data["train"]["l_train"]) <: Real && data["train"]["l_train"]>0.0 if typeof(data["train"]["l_train"]) <: Real && data["train"]["l_train"]>0.0
l_train=data["train"]["l_train"] # total length (in m) trainLength=data["train"]["l_train"] # total length (in m)
delete!(data["train"], "l_train") delete!(data["train"], "l_train")
else else
error("ERROR at reading the train yaml file: The value of the length is no real number >0.0.") error("ERROR at reading the train yaml file: The value of the length is no real number >0.0.")
@ -141,7 +141,7 @@ function inputTrain(trainDirectory::String)
m_t=m_td+m_tc m_t=m_td+m_tc
# mass of the consist (set of wagons) (in kg) # mass of the set of wagons (consist) (in kg)
if haskey(data["train"],"m_w") if haskey(data["train"],"m_w")
if typeof(data["train"]["m_w"]) <: Real && data["train"]["m_w"]>=0.0 if typeof(data["train"]["m_w"]) <: Real && data["train"]["m_w"]>=0.0
m_w=data["train"]["m_w"] m_w=data["train"]["m_w"]
@ -256,16 +256,16 @@ function inputTrain(trainDirectory::String)
# coefficients for the vehicle resistance of the consist (set of wagons) # coefficients for the vehicle resistance of the set of wagons (consist)
# coefficient for velocitiy difference between consist (set of wagons) and outdoor air (in m/s) # coefficient for velocitiy difference between set of wagons (consist) and outdoor air (in m/s)
if trainType=="passenger" || trainType=="motor coach train" if trainType=="passenger" || trainType=="motor coach train"
Δv_w=15.0/3.6 Δv_w=15.0/3.6
elseif trainType== "freight" elseif trainType== "freight"
Δv_w=0.0 Δv_w=0.0
end # if end # if
# coefficient for basic resistance of the consist (set of wagons) (in ‰) # coefficient for basic resistance of the set of wagons (consist) (in ‰)
if haskey(data["train"],"f_Rw0") && data["train"]["f_Rw0"]!=nothing if haskey(data["train"],"f_Rw0") && data["train"]["f_Rw0"]!=nothing
if typeof(data["train"]["f_Rw0"]) <: Real && data["train"]["f_Rw0"]>=0.0 if typeof(data["train"]["f_Rw0"]) <: Real && data["train"]["f_Rw0"]>=0.0
f_Rw0=data["train"]["f_Rw0"] f_Rw0=data["train"]["f_Rw0"]
@ -278,7 +278,7 @@ function inputTrain(trainDirectory::String)
end end
delete!(data["train"], "f_Rw0") delete!(data["train"], "f_Rw0")
# coefficient for basic resistance of the consist (set of wagons) (in ‰) # coefficient for basic resistance of the set of wagons (consist) (in ‰)
if haskey(data["train"],"f_Rw1") && data["train"]["f_Rw1"]!=nothing if haskey(data["train"],"f_Rw1") && data["train"]["f_Rw1"]!=nothing
if typeof(data["train"]["f_Rw1"]) <: Real && data["train"]["f_Rw1"]>=0.0 if typeof(data["train"]["f_Rw1"]) <: Real && data["train"]["f_Rw1"]>=0.0
f_Rw1=data["train"]["f_Rw1"] f_Rw1=data["train"]["f_Rw1"]
@ -291,7 +291,7 @@ function inputTrain(trainDirectory::String)
end end
delete!(data["train"], "f_Rw1") delete!(data["train"], "f_Rw1")
# coefficient for basic resistance of the consist (set of wagons) (in ‰) # coefficient for basic resistance of the set of wagons (consist) (in ‰)
if haskey(data["train"],"f_Rw2") && data["train"]["f_Rw2"]!=nothing if haskey(data["train"],"f_Rw2") && data["train"]["f_Rw2"]!=nothing
if typeof(data["train"]["f_Rw2"]) <: Real && data["train"]["f_Rw2"]>=0.0 if typeof(data["train"]["f_Rw2"]) <: Real && data["train"]["f_Rw2"]>=0.0
f_Rw2=data["train"]["f_Rw2"] f_Rw2=data["train"]["f_Rw2"]
@ -317,7 +317,7 @@ function inputTrain(trainDirectory::String)
train= Dict(:name => name, # train's name train= Dict(:name => name, # train's name
:id => id, # train's identifier :id => id, # train's identifier
:trainType => trainType, # type of train "passenger" or "freight" or "motor coach train" :trainType => trainType, # type of train "passenger" or "freight" or "motor coach train"
:l_train => l_train, # total length (in m) :trainLength => trainLength, # total length (in m)
:v_limit => v_limit, # trains speed limit (in m/s) :v_limit => v_limit, # trains speed limit (in m/s)
:a_braking => a_braking, # braking acceleration (in m/s^2) :a_braking => a_braking, # braking acceleration (in m/s^2)
:m_train => m_train, # total mass (in kg) :m_train => m_train, # total mass (in kg)
@ -396,8 +396,8 @@ end #function checkAndDefineTractiveEffortInput
function inputPath(pathDirectory::String) function inputPath(pathDirectory::String)
# read path information from a YAML file, save it in a path Dict and return it # read path information from a YAML file, save it in a path Dict and return it
data = YAML.load(open(pathDirectory)) data = YAML.load(open(pathDirectory))
collect(keys(data)) #collect(keys(data))
collect(values(data)) #collect(values(data))
if haskey(data["path"],"name") && data["path"]["name"]!=nothing if haskey(data["path"],"name") && data["path"]["name"]!=nothing
@ -505,8 +505,8 @@ end # function inputPath
function inputSettings(settingsDirectory::String) function inputSettings(settingsDirectory::String)
# read setting information from a YAML file, save it in a settings Dict and return it # read setting information from a YAML file, save it in a settings Dict and return it
data = YAML.load(open(settingsDirectory)) data = YAML.load(open(settingsDirectory))
collect(keys(data)) #collect(keys(data))
collect(values(data)) #collect(values(data))
# initialize the settings Dictionary # initialize the settings Dictionary
settings = Dict(:massModel => "", # model type of the unions mass "mass point" or "homogeneous strip" settings = Dict(:massModel => "", # model type of the unions mass "mass point" or "homogeneous strip"

View File

@ -91,15 +91,15 @@ function calculatePathResistance(s::AbstractFloat, massModel::String, train::Dic
end #while end #while
if massModel=="mass point" if massModel=="mass point"
pathResistance=CSs[id].f_Rp/1000*train[:m_train]*g # /1000 because of the unit ‰ pathResistance=CSs[id].r_path/1000*train[:m_train]*g # /1000 because of the unit ‰
elseif massModel=="homogeneous strip" elseif massModel=="homogeneous strip"
pathResistance=0.0 pathResistance=0.0
while id>0 && s-train[:l_train]<CSs[id].s_exit while id>0 && s-train[:trainLength]<CSs[id].s_exit
pathResistance=pathResistance+(min(s, CSs[id].s_exit)-max(s-train[:l_train], CSs[id].s_entry))/train[:l_train]*(CSs[id].f_Rp/1000*train[:m_train]*g) # /1000 because of the unit ‰ pathResistance=pathResistance+(min(s, CSs[id].s_exit)-max(s-train[:trainLength], CSs[id].s_entry))/train[:trainLength]*(CSs[id].r_path/1000*train[:m_train]*g) # /1000 because of the unit ‰
id=id-1 id=id-1
if id==0 if id==0
# TODO: currently for values < movingSection[:s_entry] the values of movingSection[:s_entry] will be used # TODO: currently for values < movingSection[:s_entry] the values of movingSection[:s_entry] will be used
return pathResistance+(CSs[1].s_entry-(s-train[:l_train]))/train[:l_train]*(CSs[1].f_Rp/1000*train[:m_train]*g) # /1000 because of the unit ‰ return pathResistance+(CSs[1].s_entry-(s-train[:trainLength]))/train[:trainLength]*(CSs[1].r_path/1000*train[:m_train]*g) # /1000 because of the unit ‰
end #if end #if
end #while end #while
else else
@ -115,8 +115,8 @@ calculate and return tractive and resisting forces for a data point
function calculateForces!(dataPoint::DataPoint, train::Dict, massModel::String, CSs::Vector{CharacteristicSection}, bsType::String) function calculateForces!(dataPoint::DataPoint, train::Dict, massModel::String, CSs::Vector{CharacteristicSection}, bsType::String)
# calculate resisting forces # calculate resisting forces
dataPoint.R_traction=calculateTractionUnitResistance(dataPoint.v, train) dataPoint.R_traction=calculateTractionUnitResistance(dataPoint.v, train)
dataPoint.R_consist=calculateWagonsResistance(dataPoint.v, train) dataPoint.R_wagons=calculateWagonsResistance(dataPoint.v, train)
dataPoint.R_train=dataPoint.R_traction+dataPoint.R_consist dataPoint.R_train=dataPoint.R_traction+dataPoint.R_wagons
dataPoint.R_path=calculatePathResistance(dataPoint.s, massModel, train, CSs) dataPoint.R_path=calculatePathResistance(dataPoint.s, massModel, train, CSs)
dataPoint.F_R=dataPoint.R_train+dataPoint.R_path dataPoint.F_R=dataPoint.R_train+dataPoint.R_path
@ -157,7 +157,7 @@ function moveAStep(previousPoint::DataPoint, stepVariable::String, stepSize::Rea
if ((previousPoint.v/previousPoint.a)^2+2*newPoint.Δs/previousPoint.a)<0.0 || (previousPoint.v^2+2*newPoint.Δs*previousPoint.a)<0.0 # checking if the parts of the following square roots will be <0.0 if ((previousPoint.v/previousPoint.a)^2+2*newPoint.Δs/previousPoint.a)<0.0 || (previousPoint.v^2+2*newPoint.Δs*previousPoint.a)<0.0 # checking if the parts of the following square roots will be <0.0
error("ERROR: The train stops during the acceleration phase in CS",csId," because the tractive effort is lower than the resistant forces.", error("ERROR: The train stops during the acceleration phase in CS",csId," because the tractive effort is lower than the resistant forces.",
" Before the stop the last point has the values s=",previousPoint.s," m, v=",previousPoint.v," m/s, a=",previousPoint.a," m/s^2,", " Before the stop the last point has the values s=",previousPoint.s," m, v=",previousPoint.v," m/s, a=",previousPoint.a," m/s^2,",
" F_T=",previousPoint.F_T," N, R_traction=",previousPoint.R_traction," N, R_consist=",previousPoint.R_consist," N, R_path=",previousPoint.R_path," N.") " F_T=",previousPoint.F_T," N, R_traction=",previousPoint.R_traction," N, R_wagons=",previousPoint.R_wagons," N, R_path=",previousPoint.R_path," N.")
end end
end end
# 11/21 ->| # 11/21 ->|
@ -189,11 +189,11 @@ end #function moveAStep
""" """
# if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept # if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
""" """
function detectFormerSpeedLimits(CSs::Vector{CharacteristicSection}, csWithTrainHeadId::Integer, currentPoint::DataPoint, l_train::Real) function detectFormerSpeedLimits(CSs::Vector{CharacteristicSection}, csWithTrainHeadId::Integer, currentPoint::DataPoint, trainLength::Real)
formerSpeedLimits=[] formerSpeedLimits=[]
if csWithTrainHeadId > 1 && currentPoint.s - l_train < CSs[csWithTrainHeadId].s_entry if csWithTrainHeadId > 1 && currentPoint.s - trainLength < CSs[csWithTrainHeadId].s_entry
formerCsId=csWithTrainHeadId-1 formerCsId=csWithTrainHeadId-1
while formerCsId > 0 && currentPoint.s - l_train < CSs[formerCsId].s_exit while formerCsId > 0 && currentPoint.s - trainLength < CSs[formerCsId].s_exit
if CSs[formerCsId].v_limit < CSs[csWithTrainHeadId].v_limit # TODO: is the position of trains tail < movingSection[:s_entry], v_limit of the first CS is used if CSs[formerCsId].v_limit < CSs[csWithTrainHeadId].v_limit # TODO: is the position of trains tail < movingSection[:s_entry], v_limit of the first CS is used
push!(formerSpeedLimits, [CSs[formerCsId].s_exit, CSs[formerCsId].v_limit]) push!(formerSpeedLimits, [CSs[formerCsId].s_exit, CSs[formerCsId].v_limit])
for i in 1:length(formerSpeedLimits)-1 for i in 1:length(formerSpeedLimits)-1
@ -227,7 +227,7 @@ function considerFormerSpeedLimits!(CS::CharacteristicSection, drivingCourse::Ve
# create a (new and longer) clearing section # create a (new and longer) clearing section
s_braking=max(0.0, ceil((CS.v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel)) s_braking=max(0.0, ceil((CS.v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel))
s_clearing=min(CS.s_exit-drivingCourse[end].s-s_braking, formerSpeedLimits[end][1]-(drivingCourse[end].s-train[:l_train])) s_clearing=min(CS.s_exit-drivingCourse[end].s-s_braking, formerSpeedLimits[end][1]-(drivingCourse[end].s-train[:trainLength]))
if s_clearing>0.0 if s_clearing>0.0
(CS, drivingCourse)=addCruisingPhase!(CS, drivingCourse, s_clearing, settings, train, CSs, "clearing") (CS, drivingCourse)=addCruisingPhase!(CS, drivingCourse, s_clearing, settings, train, CSs, "clearing")
@ -250,7 +250,7 @@ function considerFormerSpeedLimits!(CS::CharacteristicSection, drivingCourse::Ve
end end
# remove former speed limits of characteristic sections the train has left during the last step from the list # remove former speed limits of characteristic sections the train has left during the last step from the list
while length(formerSpeedLimits) > 0 && drivingCourse[end].s - train[:l_train] >= formerSpeedLimits[end][1] while length(formerSpeedLimits) > 0 && drivingCourse[end].s - train[:trainLength] >= formerSpeedLimits[end][1]
pop!(formerSpeedLimits) pop!(formerSpeedLimits)
end end
end end
@ -343,16 +343,16 @@ function addAccelerationPhase!(CS::CharacteristicSection, drivingCourse::Vector{
end end
# if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept # if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
formerSpeedLimits = detectFormerSpeedLimits(CSs, CS.id, drivingCourse[end], train[:l_train]) formerSpeedLimits = detectFormerSpeedLimits(CSs, CS.id, drivingCourse[end], train[:trainLength])
# conditions for acceleration phase # conditions for acceleration phase
targetSpeedReached = drivingCourse[end].v >= CS.v_target targetSpeedReached = drivingCourse[end].v >= CS.v_peak
trainAtEnd = drivingCourse[end].s >= CS.s_exit trainAtEnd = drivingCourse[end].s >= CS.s_exit
tractionSurplus = drivingCourse[end].F_T > drivingCourse[end].F_R tractionSurplus = drivingCourse[end].F_T > drivingCourse[end].F_R
# use the conditions for the acceleration phase # use the conditions for the acceleration phase
if !targetSpeedReached && !trainAtEnd && tractionSurplus if !targetSpeedReached && !trainAtEnd && tractionSurplus
#11/23 long version: if drivingCourse[end].v < CS.v_target && drivingCourse[end].s <CS.s_exit && drivingCourse[end].F_T > drivingCourse[end].F_R #11/23 long version: if drivingCourse[end].v < CS.v_peak && drivingCourse[end].s <CS.s_exit && drivingCourse[end].F_T > drivingCourse[end].F_R
accelerationSection=BehaviorSection() accelerationSection=BehaviorSection()
accelerationSection.type="acceleration" # type of behavior section accelerationSection.type="acceleration" # type of behavior section
accelerationSection.s_entry=drivingCourse[end].s # first position (in m) accelerationSection.s_entry=drivingCourse[end].s # first position (in m)
@ -362,7 +362,7 @@ function addAccelerationPhase!(CS::CharacteristicSection, drivingCourse::Vector{
currentStepSize=settings[:stepSize] # initializing the step size that can be reduced near intersections currentStepSize=settings[:stepSize] # initializing the step size that can be reduced near intersections
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
while drivingCourse[end].v<CS.v_target && drivingCourse[end].s<CS.s_exit && drivingCourse[end].F_T > drivingCourse[end].F_R while drivingCourse[end].v<CS.v_peak && drivingCourse[end].s<CS.s_exit && drivingCourse[end].F_T > drivingCourse[end].F_R
# traction effort and resisting forces (in N) # traction effort and resisting forces (in N)
# 11/22 calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, accelerationSection.type) # 11/22 calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, accelerationSection.type)
@ -398,9 +398,9 @@ function addAccelerationPhase!(CS::CharacteristicSection, drivingCourse::Vector{
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
end end
elseif drivingCourse[end].v>CS.v_target elseif drivingCourse[end].v>CS.v_peak
if settings[:stepVariable]=="v in m/s" if settings[:stepVariable]=="v in m/s"
currentStepSize=CS.v_target-drivingCourse[end-1].v currentStepSize=CS.v_peak-drivingCourse[end-1].v
else else
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
end end
@ -408,13 +408,13 @@ function addAccelerationPhase!(CS::CharacteristicSection, drivingCourse::Vector{
elseif drivingCourse[end].s==CS.s_exit elseif drivingCourse[end].s==CS.s_exit
break break
elseif drivingCourse[end].v==CS.v_target elseif drivingCourse[end].v==CS.v_peak
break break
elseif drivingCourse[end].F_T <= drivingCourse[end].F_R elseif drivingCourse[end].F_T <= drivingCourse[end].F_R
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
else else
error("ERROR at acceleration phase: With the step variable ", settings[:stepVariable]," the while loop will be left although v<v_target and s<s_exit in CS",CS.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s") error("ERROR at acceleration phase: With the step variable ", settings[:stepVariable]," the while loop will be left although v<v_peak and s<s_exit in CS",CS.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
end end
# delete last data point for recalculating the last step with reduced step size # delete last data point for recalculating the last step with reduced step size
pop!(drivingCourse) pop!(drivingCourse)
@ -425,9 +425,9 @@ function addAccelerationPhase!(CS::CharacteristicSection, drivingCourse::Vector{
# push!(accelerationSection.dataPoints, drivingCourse[end].i) # push!(accelerationSection.dataPoints, drivingCourse[end].i)
error("ERROR: The train stops during the acceleration phase in CS",CS.id," because the tractive effort is lower than the resistant forces.", error("ERROR: The train stops during the acceleration phase in CS",CS.id," because the tractive effort is lower than the resistant forces.",
" Before the stop the last point has the values s=",drivingCourse[end-1].s," m v=",drivingCourse[end-1].v," m/s a=",drivingCourse[end-1].a," m/s^2", " Before the stop the last point has the values s=",drivingCourse[end-1].s," m v=",drivingCourse[end-1].v," m/s a=",drivingCourse[end-1].a," m/s^2",
" F_T=",drivingCourse[end-1].F_T," N R_traction=",drivingCourse[end-1].R_traction," N R_consist=",drivingCourse[end-1].R_consist," N R_path=",drivingCourse[end-1].R_path," N.") " F_T=",drivingCourse[end-1].F_T," N R_traction=",drivingCourse[end-1].R_traction," N R_wagons=",drivingCourse[end-1].R_wagons," N R_path=",drivingCourse[end-1].R_path," N.")
elseif drivingCourse[end].v>CS.v_target elseif drivingCourse[end].v>CS.v_peak
pop!(drivingCourse) pop!(drivingCourse)
pop!(accelerationSection.dataPoints) pop!(accelerationSection.dataPoints)
elseif drivingCourse[end].s>CS.s_exit elseif drivingCourse[end].s>CS.s_exit
@ -443,7 +443,7 @@ function addAccelerationPhase!(CS::CharacteristicSection, drivingCourse::Vector{
end end
end #for end #for
if length(accelerationSection.dataPoints) > 1 # 11/21 new: it is possible that the acceleration starts at v_target, accelerates a step, is to high and drops the last point. then there is only one data point which is not a section. if length(accelerationSection.dataPoints) > 1 # 11/21 new: it is possible that the acceleration starts at v_peak, accelerates a step, is to high and drops the last point. then there is only one data point which is not a section.
# calculate the accumulated acceleration section information # calculate the accumulated acceleration section information
accelerationSection.v_exit=drivingCourse[end].v # exit speed (in m/s) accelerationSection.v_exit=drivingCourse[end].v # exit speed (in m/s)
accelerationSection.s_exit=drivingCourse[end].s # last position (in m) accelerationSection.s_exit=drivingCourse[end].s # last position (in m)
@ -454,8 +454,8 @@ function addAccelerationPhase!(CS::CharacteristicSection, drivingCourse::Vector{
CS.E=CS.E+accelerationSection.E # total energy consumption (in Ws) CS.E=CS.E+accelerationSection.E # total energy consumption (in Ws)
# TODO: this warning schould not be needed. just for testing # TODO: this warning schould not be needed. just for testing
if CS.v_target < drivingCourse[end].v if CS.v_peak < drivingCourse[end].v
println("WARNING, v is getting to high at the end of the acceleration phase. v=",drivingCourse[end].v ," > v_target=",CS.v_target) println("WARNING, v is getting to high at the end of the acceleration phase. v=",drivingCourse[end].v ," > v_peak=",CS.v_peak)
end end
merge!(CS.behaviorSections, Dict(:acceleration=>accelerationSection)) merge!(CS.behaviorSections, Dict(:acceleration=>accelerationSection))
@ -479,11 +479,11 @@ function addAccelerationPhaseUntilBraking!(CS::CharacteristicSection, drivingCou
end end
# if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept # if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
formerSpeedLimits = detectFormerSpeedLimits(CSs, CS.id, drivingCourse[end], train[:l_train]) formerSpeedLimits = detectFormerSpeedLimits(CSs, CS.id, drivingCourse[end], train[:trainLength])
# 11/23 old without F_T>F_R: if drivingCourse[end].v < CS.v_target && drivingCourse[end].s<CS.s_exit # 11/23 old without F_T>F_R: if drivingCourse[end].v < CS.v_peak && drivingCourse[end].s<CS.s_exit
if drivingCourse[end].v < CS.v_target && drivingCourse[end].s<CS.s_exit && drivingCourse[end].F_T > drivingCourse[end].F_R if drivingCourse[end].v < CS.v_peak && drivingCourse[end].s<CS.s_exit && drivingCourse[end].F_T > drivingCourse[end].F_R
accelerationSection=BehaviorSection() accelerationSection=BehaviorSection()
accelerationSection.type="acceleration" # type of behavior section accelerationSection.type="acceleration" # type of behavior section
accelerationSection.s_entry=drivingCourse[end].s # first position (in m) accelerationSection.s_entry=drivingCourse[end].s # first position (in m)
@ -494,15 +494,15 @@ function addAccelerationPhaseUntilBraking!(CS::CharacteristicSection, drivingCou
currentStepSize=settings[:stepSize] # initializing the step size that can be reduced near intersections currentStepSize=settings[:stepSize] # initializing the step size that can be reduced near intersections
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
s_braking=max(0.0, ceil((CS.v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel)) s_braking=max(0.0, ceil((CS.v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel))
while drivingCourse[end].v < CS.v_target && drivingCourse[end].s+s_braking<CS.s_exit && drivingCourse[end].F_T > drivingCourse[end].F_R # as long as s_i + s_braking < s_CSend while drivingCourse[end].v < CS.v_peak && drivingCourse[end].s+s_braking<CS.s_exit && drivingCourse[end].F_T > drivingCourse[end].F_R # as long as s_i + s_braking < s_CSend
# 12/03 old with v>0 while drivingCourse[end].v < CS.v_target && drivingCourse[end].s+s_braking<CS.s_exit && drivingCourse[end].v>0.0 && drivingCourse[end].F_T > drivingCourse[end].F_R # as long as s_i + s_braking < s_CSend # 12/03 old with v>0 while drivingCourse[end].v < CS.v_peak && drivingCourse[end].s+s_braking<CS.s_exit && drivingCourse[end].v>0.0 && drivingCourse[end].F_T > drivingCourse[end].F_R # as long as s_i + s_braking < s_CSend
#11/22 calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, accelerationSection.type) #11/22 calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, accelerationSection.type)
# acceleration (in m/s^2): # acceleration (in m/s^2):
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train[:m_train]/train[:ξ_train] drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train[:m_train]/train[:ξ_train]
# if drivingCourse[end].a==0.0 # if drivingCourse[end].a==0.0
# error("ERROR: a=0 m/s^2 in the acceleration phase ! with F_T=",drivingCourse[end].F_T," R_traction=",drivingCourse[end].R_traction," R_consist=",drivingCourse[end].R_consist," R_path=",drivingCourse[end].R_path) # error("ERROR: a=0 m/s^2 in the acceleration phase ! with F_T=",drivingCourse[end].F_T," R_traction=",drivingCourse[end].R_traction," R_wagons=",drivingCourse[end].R_wagons," R_path=",drivingCourse[end].R_path)
# end # end
# create the next data point # create the next data point
@ -529,9 +529,9 @@ function addAccelerationPhaseUntilBraking!(CS::CharacteristicSection, drivingCou
elseif drivingCourse[end].s +s_braking > CS.s_exit elseif drivingCourse[end].s +s_braking > CS.s_exit
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
elseif drivingCourse[end].v>CS.v_target elseif drivingCourse[end].v>CS.v_peak
if settings[:stepVariable]=="v in m/s" if settings[:stepVariable]=="v in m/s"
currentStepSize= CS.v_target-drivingCourse[end-1].v currentStepSize= CS.v_peak-drivingCourse[end-1].v
else else
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
end end
@ -539,14 +539,14 @@ function addAccelerationPhaseUntilBraking!(CS::CharacteristicSection, drivingCou
elseif drivingCourse[end].s==CS.s_exit elseif drivingCourse[end].s==CS.s_exit
break break
elseif drivingCourse[end].v==CS.v_target elseif drivingCourse[end].v==CS.v_peak
break break
elseif drivingCourse[end].F_T <= drivingCourse[end].F_R elseif drivingCourse[end].F_T <= drivingCourse[end].F_R
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
else else
error("ERROR at acceleration until braking phase: With the step variable ",settings[:stepVariable]," the while loop will be left although v<v_target and s<s_exit in CS",CS.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s") error("ERROR at acceleration until braking phase: With the step variable ",settings[:stepVariable]," the while loop will be left although v<v_peak and s<s_exit in CS",CS.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
end end
# delete last data point for recalculating the last step with reduced step size # delete last data point for recalculating the last step with reduced step size
pop!(drivingCourse) pop!(drivingCourse)
@ -557,9 +557,9 @@ function addAccelerationPhaseUntilBraking!(CS::CharacteristicSection, drivingCou
# push!(accelerationSection.dataPoints, drivingCourse[end].i) # push!(accelerationSection.dataPoints, drivingCourse[end].i)
error("ERROR: The train stops during the acceleration phase in CS",CS.id," because the tractive effort is lower than the resistant forces.", error("ERROR: The train stops during the acceleration phase in CS",CS.id," because the tractive effort is lower than the resistant forces.",
" Before the stop the last point has the values s=",drivingCourse[end-1].s," m v=",drivingCourse[end-1].v," m/s a=",drivingCourse[end-1].a," m/s^2", " Before the stop the last point has the values s=",drivingCourse[end-1].s," m v=",drivingCourse[end-1].v," m/s a=",drivingCourse[end-1].a," m/s^2",
" F_T=",drivingCourse[end-1].F_T," N R_traction=",drivingCourse[end-1].R_traction," N R_consist=",drivingCourse[end-1].R_consist," N R_path=",drivingCourse[end-1].R_path," N.") " F_T=",drivingCourse[end-1].F_T," N R_traction=",drivingCourse[end-1].R_traction," N R_wagons=",drivingCourse[end-1].R_wagons," N R_path=",drivingCourse[end-1].R_path," N.")
elseif drivingCourse[end].v>CS.v_target elseif drivingCourse[end].v>CS.v_peak
pop!(drivingCourse) pop!(drivingCourse)
pop!(accelerationSection.dataPoints) pop!(accelerationSection.dataPoints)
elseif drivingCourse[end].s + s_braking > CS.s_exit elseif drivingCourse[end].s + s_braking > CS.s_exit
@ -584,7 +584,7 @@ function addAccelerationPhaseUntilBraking!(CS::CharacteristicSection, drivingCou
accelerationSection.t=drivingCourse[end].t-drivingCourse[accelerationSection.dataPoints[1]].t # total running time (in s) accelerationSection.t=drivingCourse[end].t-drivingCourse[accelerationSection.dataPoints[1]].t # total running time (in s)
accelerationSection.E=drivingCourse[end].E-drivingCourse[accelerationSection.dataPoints[1]].E # total energy consumption (in Ws) accelerationSection.E=drivingCourse[end].E-drivingCourse[accelerationSection.dataPoints[1]].E # total energy consumption (in Ws)
CS.v_target=max(drivingCourse[end].v, CS.v_entry) # setting v_target to the last data points velocity which is the highest reachable value in this characteristic section or to v_entry in case it is higher when driving on a path with high resistances CS.v_peak=max(drivingCourse[end].v, CS.v_entry) # setting v_peak to the last data points velocity which is the highest reachable value in this characteristic section or to v_entry in case it is higher when driving on a path with high resistances
CS.t=CS.t+accelerationSection.t # total running time (in s) CS.t=CS.t+accelerationSection.t # total running time (in s)
CS.E=CS.E+accelerationSection.E # total energy consumption (in Ws) CS.E=CS.E+accelerationSection.E # total energy consumption (in Ws)
@ -606,8 +606,8 @@ function addCruisingPhase!(CS::CharacteristicSection, drivingCourse::Vector{Data
drivingCourse[end] = DataPoint(calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "cruising")) drivingCourse[end] = DataPoint(calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "cruising"))
s_cruising = max(0.0, s_cruising-get(CS.behaviorSections, :diminishing, BehaviorSection()).length) s_cruising = max(0.0, s_cruising-get(CS.behaviorSections, :diminishing, BehaviorSection()).length)
end end
if drivingCourse[end].v>0.0 && drivingCourse[end].v<=CS.v_target && drivingCourse[end].s<CS.s_exit && drivingCourse[end].F_T >= drivingCourse[end].F_R if drivingCourse[end].v>0.0 && drivingCourse[end].v<=CS.v_peak && drivingCourse[end].s<CS.s_exit && drivingCourse[end].F_T >= drivingCourse[end].F_R
# 11/22 old: if drivingCourse[end].v>0.0 && drivingCourse[end].v<=CS.v_target && drivingCourse[end].s<CS.s_exit # 11/22 old: if drivingCourse[end].v>0.0 && drivingCourse[end].v<=CS.v_peak && drivingCourse[end].s<CS.s_exit
cruisingSection=BehaviorSection() cruisingSection=BehaviorSection()
cruisingSection.type=cruisingType # type of behavior section cruisingSection.type=cruisingType # type of behavior section
cruisingSection.s_entry=drivingCourse[end].s # first position (in m) cruisingSection.s_entry=drivingCourse[end].s # first position (in m)
@ -626,11 +626,11 @@ function addCruisingPhase!(CS::CharacteristicSection, drivingCourse::Vector{Data
if settings[:massModel]=="homogeneous strip" && CS.id > 1 if settings[:massModel]=="homogeneous strip" && CS.id > 1
currentStepSize=settings[:stepSize] currentStepSize=settings[:stepSize]
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
while drivingCourse[end].s < CS.s_entry + train[:l_train] && drivingCourse[end].s<cruisingSection.s_entry+s_cruising && drivingCourse[end].F_T>=drivingCourse[end].F_R #&& drivingCourse[end].v<=CS.v_target && drivingCourse[end].s<CS.s_exit while drivingCourse[end].s < CS.s_entry + train[:trainLength] && drivingCourse[end].s<cruisingSection.s_entry+s_cruising && drivingCourse[end].F_T>=drivingCourse[end].F_R #&& drivingCourse[end].v<=CS.v_peak && drivingCourse[end].s<CS.s_exit
# TODO: whithout CSs should work as well, no? while drivingCourse[end].s < CSs[CS.id].s_entry + train[:l_train] && drivingCourse[end].s<cruisingSection.s_entry+s_cruising && drivingCourse[end].F_T>=drivingCourse[end].F_R #&& drivingCourse[end].v<=CS.v_target && drivingCourse[end].s<CS.s_exit # TODO: whithout CSs should work as well, no? while drivingCourse[end].s < CSs[CS.id].s_entry + train[:trainLength] && drivingCourse[end].s<cruisingSection.s_entry+s_cruising && drivingCourse[end].F_T>=drivingCourse[end].F_R #&& drivingCourse[end].v<=CS.v_peak && drivingCourse[end].s<CS.s_exit
# the tractive effort is lower than the resisiting forces and the train has use the highest possible effort to try to stay at v_target OR the mass model homogeneous strip is used and parts of the train are still in former CS # the tractive effort is lower than the resisiting forces and the train has use the highest possible effort to try to stay at v_peak OR the mass model homogeneous strip is used and parts of the train are still in former CS
#TODO: maybe just consider former CS with different path resistance? #TODO: maybe just consider former CS with different path resistance?
#TODO: what about the case: After leaving a former CS with steep gradient the train can accelerate. Now in this tool the train will cruise at v_i. Just accelerating until v_target could make problems for energy saving by shortening the acceleration phase #TODO: what about the case: After leaving a former CS with steep gradient the train can accelerate. Now in this tool the train will cruise at v_i. Just accelerating until v_peak could make problems for energy saving by shortening the acceleration phase
# acceleration (in m/s^2): # acceleration (in m/s^2):
drivingCourse[end].a=0.0 drivingCourse[end].a=0.0
@ -639,7 +639,7 @@ function addCruisingPhase!(CS::CharacteristicSection, drivingCourse::Vector{Data
if settings[:stepVariable]=="s in m" if settings[:stepVariable]=="s in m"
push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", currentStepSize, CS.id)) push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", currentStepSize, CS.id))
else else
push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", train[:l_train]/(10.0^cycle), CS.id)) # TODO which step size should be used? push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", train[:trainLength]/(10.0^cycle), CS.id)) # TODO which step size should be used?
end end
drivingCourse[end].behavior = cruisingSection.type drivingCourse[end].behavior = cruisingSection.type
push!(cruisingSection.dataPoints, drivingCourse[end].i) push!(cruisingSection.dataPoints, drivingCourse[end].i)
@ -655,7 +655,7 @@ function addCruisingPhase!(CS::CharacteristicSection, drivingCourse::Vector{Data
# check which limit was reached and adjust the currentStepSize for the next cycle # check which limit was reached and adjust the currentStepSize for the next cycle
if cycle < approximationLevel+1 if cycle < approximationLevel+1
if drivingCourse[end].s>cruisingSection.s_entry+s_cruising # TODO also the following? drivingCourse[end].s > CSs[CS.id].s_entry + train[:l_train])) if drivingCourse[end].s>cruisingSection.s_entry+s_cruising # TODO also the following? drivingCourse[end].s > CSs[CS.id].s_entry + train[:trainLength]))
if settings[:stepVariable] == "s in m" if settings[:stepVariable] == "s in m"
currentStepSize=cruisingSection.s_entry+s_cruising-drivingCourse[end-1].s currentStepSize=cruisingSection.s_entry+s_cruising-drivingCourse[end-1].s
else else
@ -669,8 +669,8 @@ function addCruisingPhase!(CS::CharacteristicSection, drivingCourse::Vector{Data
# else # else
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
# end # end
elseif drivingCourse[end].s >= CS.s_entry + train[:l_train] elseif drivingCourse[end].s >= CS.s_entry + train[:trainLength]
# TODO: whithout CSs should work as well, no? elseif drivingCourse[end].s >= CSs[CS.id].s_entry + train[:l_train] # TODO: whithout CSs should work as well, no? elseif drivingCourse[end].s >= CSs[CS.id].s_entry + train[:trainLength]
break break
else # TODO copied from addAccelerationPhase -> probably not needed here !? else # TODO copied from addAccelerationPhase -> probably not needed here !?
error("ERROR at cruising phase: With the step variable ",settings[:stepVariable]," the while loop will be left although the if cases don't apply in CS",CS.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s") error("ERROR at cruising phase: With the step variable ",settings[:stepVariable]," the while loop will be left although the if cases don't apply in CS",CS.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
@ -741,7 +741,7 @@ function addDiminishingPhase!(CS::CharacteristicSection, drivingCourse::Vector{D
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "diminishing") calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "diminishing")
if drivingCourse[end].F_T <= drivingCourse[end].F_R && drivingCourse[end].v > 0.0 && drivingCourse[end].s<CS.s_exit if drivingCourse[end].F_T <= drivingCourse[end].F_R && drivingCourse[end].v > 0.0 && drivingCourse[end].s<CS.s_exit
#drivingCourse[end].v>0.0 && drivingCourse[end].v<=CS.v_target && drivingCourse[end].s<CS.s_exit #drivingCourse[end].v>0.0 && drivingCourse[end].v<=CS.v_peak && drivingCourse[end].s<CS.s_exit
diminishingSection=BehaviorSection() diminishingSection=BehaviorSection()
diminishingSection.type="diminishing" # type of behavior section diminishingSection.type="diminishing" # type of behavior section
diminishingSection.s_entry=drivingCourse[end].s # first position (in m) diminishingSection.s_entry=drivingCourse[end].s # first position (in m)
@ -761,7 +761,7 @@ function addDiminishingPhase!(CS::CharacteristicSection, drivingCourse::Vector{D
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train[:m_train]/train[:ξ_train] drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train[:m_train]/train[:ξ_train]
# 11/21: old, only for cruising: # 11/21: old, only for cruising:
#if drivingCourse[end].a==0.0 #if drivingCourse[end].a==0.0
# error("ERROR: a=0 m/s^2 in the diminishing phase ! with F_T=",drivingCourse[end].F_T," R_traction=",drivingCourse[end].R_traction," R_consist=",drivingCourse[end].R_consist," R_path=",drivingCourse[end].R_path) # error("ERROR: a=0 m/s^2 in the diminishing phase ! with F_T=",drivingCourse[end].F_T," R_traction=",drivingCourse[end].R_traction," R_wagons=",drivingCourse[end].R_wagons," R_path=",drivingCourse[end].R_path)
#end #end
# create the next data point # create the next data point
@ -800,7 +800,7 @@ function addDiminishingPhase!(CS::CharacteristicSection, drivingCourse::Vector{D
# push!(diminishingSection.dataPoints, drivingCourse[end].i) # push!(diminishingSection.dataPoints, drivingCourse[end].i)
error("ERROR: The train stops during diminishing run in CS",CS.id," because the maximum tractive effort is lower than the resistant forces.", error("ERROR: The train stops during diminishing run in CS",CS.id," because the maximum tractive effort is lower than the resistant forces.",
" Before the stop the last point has the values s=",drivingCourse[end-1].s," m v=",drivingCourse[end-1].v," m/s a=",drivingCourse[end-1].a," m/s^2", " Before the stop the last point has the values s=",drivingCourse[end-1].s," m v=",drivingCourse[end-1].v," m/s a=",drivingCourse[end-1].a," m/s^2",
" F_T=",drivingCourse[end-1].F_T," N R_traction=",drivingCourse[end-1].R_traction," N R_consist=",drivingCourse[end-1].R_consist," N R_path=",drivingCourse[end-1].R_path," N.") " F_T=",drivingCourse[end-1].F_T," N R_traction=",drivingCourse[end-1].R_traction," N R_wagons=",drivingCourse[end-1].R_wagons," N R_path=",drivingCourse[end-1].R_path," N.")
elseif drivingCourse[end].s + s_braking > CS.s_exit elseif drivingCourse[end].s + s_braking > CS.s_exit
pop!(drivingCourse) pop!(drivingCourse)
@ -837,7 +837,7 @@ end #function addDiminishingPhase!
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the coasting section # Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the coasting section
function addCoastingPhaseUntilBraking!(CS::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{CharacteristicSection}) function addCoastingPhaseUntilBraking!(CS::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{CharacteristicSection})
## if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept ## if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
#formerSpeedLimits = detectFormerSpeedLimits(CSs, CS.id, drivingCourse[end], train[:l_train]) #formerSpeedLimits = detectFormerSpeedLimits(CSs, CS.id, drivingCourse[end], train[:trainLength])
if drivingCourse[end].v>CS.v_exit && drivingCourse[end].s<CS.s_exit if drivingCourse[end].v>CS.v_exit && drivingCourse[end].s<CS.s_exit
coastingSection=BehaviorSection() coastingSection=BehaviorSection()
@ -851,7 +851,7 @@ function addCoastingPhaseUntilBraking!(CS::CharacteristicSection, drivingCourse:
# 08/24 old for cycle in 1:3 # first cycle with normal step size, second cycle with reduced step size, third cycle with more reduced step size # 08/24 old for cycle in 1:3 # first cycle with normal step size, second cycle with reduced step size, third cycle with more reduced step size
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
s_braking=ceil((CS.v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel) s_braking=ceil((CS.v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel)
while drivingCourse[end].v>CS.v_exit && drivingCourse[end].v<=CS.v_target && drivingCourse[end].s + s_braking < CS.s_exit # as long as s_i + s_braking < s_CSend while drivingCourse[end].v>CS.v_exit && drivingCourse[end].v<=CS.v_peak && drivingCourse[end].s + s_braking < CS.s_exit # as long as s_i + s_braking < s_CSend
# traction effort and resisting forces (in N): # traction effort and resisting forces (in N):
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, coastingSection.type) calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, coastingSection.type)
@ -876,9 +876,9 @@ function addCoastingPhaseUntilBraking!(CS::CharacteristicSection, drivingCourse:
elseif drivingCourse[end].v < CS.v_exit # TODO: if accelereation and coasting functions will be combined this case is only for coasting elseif drivingCourse[end].v < CS.v_exit # TODO: if accelereation and coasting functions will be combined this case is only for coasting
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
elseif drivingCourse[end].v > CS.v_target elseif drivingCourse[end].v > CS.v_peak
if settings[:stepVariable]=="v in m/s" if settings[:stepVariable]=="v in m/s"
currentStepSize = CS.v_target-drivingCourse[end-1].v currentStepSize = CS.v_peak-drivingCourse[end-1].v
else else
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
end end
@ -890,7 +890,7 @@ function addCoastingPhaseUntilBraking!(CS::CharacteristicSection, drivingCourse:
else else
# TODO: not needed. just for testing # TODO: not needed. just for testing
error("ERROR at coasting until braking phase: With the step variable ",settings[:stepVariable]," the while loop will be left although v<v_target and s+s_braking<s_exit in CS",CS.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s") error("ERROR at coasting until braking phase: With the step variable ",settings[:stepVariable]," the while loop will be left although v<v_peak and s+s_braking<s_exit in CS",CS.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
end end
# delete last data point for recalculating the last step with reduced step size # delete last data point for recalculating the last step with reduced step size
pop!(drivingCourse) pop!(drivingCourse)
@ -900,15 +900,15 @@ function addCoastingPhaseUntilBraking!(CS::CharacteristicSection, drivingCourse:
if drivingCourse[end].v<=0.0 if drivingCourse[end].v<=0.0
println("INFO: The train stops during the coasting phase in CS",CS.id," ", println("INFO: The train stops during the coasting phase in CS",CS.id," ",
" Before the stop the last point has the values s=",drivingCourse[end-1].s," m v=",drivingCourse[end-1].v," m/s a=",drivingCourse[end-1].a," m/s^2", " Before the stop the last point has the values s=",drivingCourse[end-1].s," m v=",drivingCourse[end-1].v," m/s a=",drivingCourse[end-1].a," m/s^2",
" F_T=",drivingCourse[end-1].F_T," N R_traction=",drivingCourse[end-1].R_traction," N R_consist=",drivingCourse[end-1].R_consist," N R_path=",drivingCourse[end-1].R_path," N and s_braking=",s_braking,"m.") " F_T=",drivingCourse[end-1].F_T," N R_traction=",drivingCourse[end-1].R_traction," N R_wagons=",drivingCourse[end-1].R_wagons," N R_path=",drivingCourse[end-1].R_path," N and s_braking=",s_braking,"m.")
elseif drivingCourse[end].s + s_braking > CS.s_exit elseif drivingCourse[end].s + s_braking > CS.s_exit
# delete last data point because it went to far # delete last data point because it went to far
pop!(drivingCourse) pop!(drivingCourse)
pop!(coastingSection.dataPoints) pop!(coastingSection.dataPoints)
elseif drivingCourse[end].v > CS.v_target # if the train gets to fast it has to brake # TODO: if accelereation and coasting functions will be combined this case is different for coasting and also the order of if cases is different elseif drivingCourse[end].v > CS.v_peak # if the train gets to fast it has to brake # TODO: if accelereation and coasting functions will be combined this case is different for coasting and also the order of if cases is different
# while coasting the train brakes to hold v_target (only one data point in the end of coasting is calculated like cruising at v_target) # while coasting the train brakes to hold v_peak (only one data point in the end of coasting is calculated like cruising at v_peak)
drivingCourse[end-1].a=0.0 drivingCourse[end-1].a=0.0
s_braking=ceil((CS.v_exit^2-drivingCourse[end-1].v^2)/2/train[:a_braking]) s_braking=ceil((CS.v_exit^2-drivingCourse[end-1].v^2)/2/train[:a_braking])

View File

@ -27,12 +27,12 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
s_breakFree = get(CSs[csId].behaviorSections, :breakFree, BehaviorSection()).length s_breakFree = get(CSs[csId].behaviorSections, :breakFree, BehaviorSection()).length
s_clearing = get(CSs[csId].behaviorSections, :clearing, BehaviorSection()).length s_clearing = get(CSs[csId].behaviorSections, :clearing, BehaviorSection()).length
s_acceleration = get(CSs[csId].behaviorSections, :acceleration, BehaviorSection()).length s_acceleration = get(CSs[csId].behaviorSections, :acceleration, BehaviorSection()).length
s_braking = max(0.0, ceil((CSs[csId].v_exit^2-CSs[csId].v_target^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors s_braking = max(0.0, ceil((CSs[csId].v_exit^2-CSs[csId].v_peak^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
# calculate the cruising sections length # calculate the cruising sections length
s_cruising=CSs[csId].length-s_breakFree-s_clearing-s_acceleration-s_braking s_cruising=CSs[csId].length-s_breakFree-s_clearing-s_acceleration-s_braking
# reset the moving section (MS), delete characteristic sections (CS) that were used during the preperation for setting v_entry, v_target and v_exit # reset the moving section (MS), delete characteristic sections (CS) that were used during the preperation for setting v_entry, v_peak and v_exit
delete!(CSs[csId].behaviorSections, :breakFree) delete!(CSs[csId].behaviorSections, :breakFree)
delete!(CSs[csId].behaviorSections, :clearing) delete!(CSs[csId].behaviorSections, :clearing)
delete!(CSs[csId].behaviorSections, :acceleration) delete!(CSs[csId].behaviorSections, :acceleration)
@ -50,14 +50,14 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
elseif s_cruising > 0.0 || s_braking == 0.0 elseif s_cruising > 0.0 || s_braking == 0.0
# 09/21 elseif s_cruising > 0.0 # 09/21 elseif s_cruising > 0.0
# 09/21 elseif s_cruising > 0.01 # if the cruising section is longer than 1 cm (because of rounding issues not >0.0) # 09/21 elseif s_cruising > 0.01 # if the cruising section is longer than 1 cm (because of rounding issues not >0.0)
if drivingCourse[end].v < CSs[csId].v_target if drivingCourse[end].v < CSs[csId].v_peak
(CSs[csId], drivingCourse)=addAccelerationPhase!(CSs[csId], drivingCourse, settings, train, CSs) (CSs[csId], drivingCourse)=addAccelerationPhase!(CSs[csId], drivingCourse, settings, train, CSs)
end #if end #if
if CSs[csId].s_exit-drivingCourse[end].s-max(0.0, (CSs[csId].v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking]) < -0.001 # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors if CSs[csId].s_exit-drivingCourse[end].s-max(0.0, (CSs[csId].v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking]) < -0.001 # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
println("ERROR: After accelerating in CS ",csId," the braking distance is too short!") println("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=",((CSs[csId].v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking])," s_exit=",CSs[csId].s_exit) println(" before acceleration in CS",csId, " with s=",drivingCourse[end].s," s_braking=",((CSs[csId].v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking])," s_exit=",CSs[csId].s_exit)
println(" and v=",drivingCourse[end].v," v_target=",CSs[csId].v_target," v_exit=",CSs[csId].v_exit) println(" and v=",drivingCourse[end].v," v_peak=",CSs[csId].v_peak," v_exit=",CSs[csId].v_exit)
end end
s_braking=max(0.0, ceil((CSs[csId].v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors s_braking=max(0.0, ceil((CSs[csId].v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
@ -68,8 +68,8 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
end end
else else
if CSs[csId].v_entry < CSs[csId].v_target || s_acceleration > 0.0 # or instead of " || s_acceleration > 0.0" use "v_entry <= v_target" or "v_i <= v_target" if CSs[csId].v_entry < CSs[csId].v_peak || s_acceleration > 0.0 # or instead of " || s_acceleration > 0.0" use "v_entry <= v_peak" or "v_i <= v_peak"
# 09/09 old (not sufficient for steep gradients): if CSs[csId].v_entry < CSs[csId].v_target # 09/09 old (not sufficient for steep gradients): if CSs[csId].v_entry < CSs[csId].v_peak
(CSs[csId], drivingCourse)=addAccelerationPhaseUntilBraking!(CSs[csId], drivingCourse, settings, train, CSs) (CSs[csId], drivingCourse)=addAccelerationPhaseUntilBraking!(CSs[csId], drivingCourse, settings, train, CSs)
end #if end #if
end #if end #if
@ -113,6 +113,7 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict
#create a new moving section for the minimum energy consumption #create a new moving section for the minimum energy consumption
movingSectionOriginal=copyMovingSection(movingSectionMinimumRunningTime) movingSectionOriginal=copyMovingSection(movingSectionMinimumRunningTime)
CSsOrig::Vector{CharacteristicSection} = movingSectionOriginal[:characteristicSections] CSsOrig::Vector{CharacteristicSection} = movingSectionOriginal[:characteristicSections]
merge!(movingSectionOriginal, Dict(:energySavingModifications => [])) # list containing all the used energy saving modifications
# create a new driving course for the minimum energy consumption # create a new driving course for the minimum energy consumption
drivingCourseOriginal=DataPoint[] drivingCourseOriginal=DataPoint[]
@ -121,13 +122,14 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict
end end
# calculate the recovery time # calculate the recovery time
movingSectionOriginal[:t_recovery]=calculateRecoveryTime(movingSectionOriginal[:length], movingSectionOriginal[:t], train) t_recovery=calculateRecoveryTime(movingSectionOriginal[:length], movingSectionOriginal[:t], train)
movingSectionOriginal[:t_recoveryAvailable]=movingSectionOriginal[:t_recovery] merge!(movingSectionOriginal, Dict(:t_recovery=>t_recovery)) # total recovery time for energy-saving modifications (in s)
merge!(movingSectionOriginal, Dict(:t_recoveryAvailable => t_recovery)) # still available recovery time for energy-saving modifications (in s) initialized with the total recovery time
# create arrays for each method with all the available energy saving modifications # create arrays for each method with all the available energy saving modifications
energySavingModificationsWithCoasting=EnergySavingModification[] energySavingModificationsWithCoasting=Dict[]
energySavingModificationsWithMaximumSpeed=EnergySavingModification[] energySavingModificationsWithMaximumSpeed=Dict[]
energySavingModificationsWithCombination=EnergySavingModification[] energySavingModificationsWithCombination=Dict[]
for csId in 1:length(CSsOrig) for csId in 1:length(CSsOrig)
# method 1: increase coasting # method 1: increase coasting
@ -137,7 +139,7 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict
push!(energySavingModificationsWithCoasting, energySavingModification) push!(energySavingModificationsWithCoasting, energySavingModification)
end #if doMethod1 end #if doMethod1
# method 2: accelerate to a lower v_target # method 2: accelerate to a lower v_peak
if doMethod2 == true if doMethod2 == true
modificationType = "decreasing maximum velocity" modificationType = "decreasing maximum velocity"
energySavingModification = modifyCs(movingSectionOriginal, drivingCourseOriginal, csId, modificationType, settings, train) energySavingModification = modifyCs(movingSectionOriginal, drivingCourseOriginal, csId, modificationType, settings, train)
@ -167,7 +169,7 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict
if typeMax=="none" if typeMax=="none"
break break
elseif typeMax=="increasing coasting" 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) # 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]) push!(movingSectionOriginal[:energySavingModifications], energySavingModificationsWithCoasting[csIdMax])
# println("Nr. ",length(movingSectionOriginal[:energySavingModifications]),": typeMax=increasing coasting") # println("Nr. ",length(movingSectionOriginal[:energySavingModifications]),": typeMax=increasing coasting")
elseif typeMax=="decreasing maximum velocity" elseif typeMax=="decreasing maximum velocity"
@ -178,7 +180,7 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict
# println("Nr. ",length(movingSectionOriginal[:energySavingModifications]),": typeMax=combination of energy saving methods") # println("Nr. ",length(movingSectionOriginal[:energySavingModifications]),": typeMax=combination of energy saving methods")
end #if end #if
movingSectionOriginal[:t_recoveryAvailable] = movingSectionOriginal[:t_recoveryAvailable] - movingSectionOriginal[:energySavingModifications][end].Δt movingSectionOriginal[:t_recoveryAvailable] = movingSectionOriginal[:t_recoveryAvailable] - movingSectionOriginal[:energySavingModifications][end][:Δt]
lastIdOfSelectedCsOriginal = get(CSsOrig[csIdMax].behaviorSections, :standstill, lastIdOfSelectedCsOriginal = get(CSsOrig[csIdMax].behaviorSections, :standstill,
get(CSsOrig[csIdMax].behaviorSections, :braking, get(CSsOrig[csIdMax].behaviorSections, :braking,
@ -197,15 +199,15 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict
end end
# create new driving course # create new driving course
drivingCourseNew=Vector{DataPoint}() drivingCourseNew=DataPoint[]
for i in 1:length(movingSectionOriginal[:energySavingModifications][end].drivingCourseModified) for i in 1:length(movingSectionOriginal[:energySavingModifications][end][:drivingCourseModified])
push!(drivingCourseNew, DataPoint(movingSectionOriginal[:energySavingModifications][end].drivingCourseModified[i])) push!(drivingCourseNew, DataPoint(movingSectionOriginal[:energySavingModifications][end][:drivingCourseModified][i]))
end end
#fill up the rest of the driving course with information from the original course #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_T=drivingCourseOriginal[lastIdOfSelectedCsOriginal].F_T
drivingCourseNew[end].R_traction=drivingCourseOriginal[lastIdOfSelectedCsOriginal].R_traction drivingCourseNew[end].R_traction=drivingCourseOriginal[lastIdOfSelectedCsOriginal].R_traction
drivingCourseNew[end].R_consist=drivingCourseOriginal[lastIdOfSelectedCsOriginal].R_consist drivingCourseNew[end].R_wagons=drivingCourseOriginal[lastIdOfSelectedCsOriginal].R_wagons
drivingCourseNew[end].R_train=drivingCourseOriginal[lastIdOfSelectedCsOriginal].R_train drivingCourseNew[end].R_train=drivingCourseOriginal[lastIdOfSelectedCsOriginal].R_train
drivingCourseNew[end].R_path=drivingCourseOriginal[lastIdOfSelectedCsOriginal].R_path drivingCourseNew[end].R_path=drivingCourseOriginal[lastIdOfSelectedCsOriginal].R_path
drivingCourseNew[end].F_R=drivingCourseOriginal[lastIdOfSelectedCsOriginal].F_R drivingCourseNew[end].F_R=drivingCourseOriginal[lastIdOfSelectedCsOriginal].F_R
@ -226,7 +228,7 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict
# replace the original driving course and CS with the new modified ones # replace the original driving course and CS with the new modified ones
drivingCourseOriginal=drivingCourseNew drivingCourseOriginal=drivingCourseNew
CSsOrig[csIdMax]=CharacteristicSection(movingSectionOriginal[:energySavingModifications][end].csModified) CSsOrig[csIdMax]=CharacteristicSection(movingSectionOriginal[:energySavingModifications][end][:csModified])
movingSectionOriginal[:t]=drivingCourseOriginal[end].t # total running time (in s) movingSectionOriginal[:t]=drivingCourseOriginal[end].t # total running time (in s)
movingSectionOriginal[:E]=drivingCourseOriginal[end].E # total energy consumption (in Ws) movingSectionOriginal[:E]=drivingCourseOriginal[end].E # total energy consumption (in Ws)
@ -245,9 +247,9 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict
end #for end #for
# update the data points in the following modified charateristic sections and the following points in the driving course # update the data points in the following modified charateristic sections and the following points in the driving course
energySavingModificationsWithCoasting = updateEnergySavingModifications(energySavingModificationsWithCoasting, csIdMax, drivingCourseNew, endOfModificationId, lastIdOfSelectedCsOriginal) energySavingModificationsWithCoasting = updateEnergySavingModifications!(energySavingModificationsWithCoasting, csIdMax, drivingCourseNew, endOfModificationId, lastIdOfSelectedCsOriginal)
energySavingModificationsWithMaximumSpeed = updateEnergySavingModifications(energySavingModificationsWithMaximumSpeed, csIdMax, drivingCourseNew, endOfModificationId, lastIdOfSelectedCsOriginal) energySavingModificationsWithMaximumSpeed = updateEnergySavingModifications!(energySavingModificationsWithMaximumSpeed, csIdMax, drivingCourseNew, endOfModificationId, lastIdOfSelectedCsOriginal)
energySavingModificationsWithCombination = updateEnergySavingModifications(energySavingModificationsWithCombination, csIdMax, drivingCourseNew, endOfModificationId, lastIdOfSelectedCsOriginal) energySavingModificationsWithCombination = updateEnergySavingModifications!(energySavingModificationsWithCombination, csIdMax, drivingCourseNew, endOfModificationId, lastIdOfSelectedCsOriginal)
end # if difference end # if difference
# modify new CS for the considered methods # modify new CS for the considered methods
@ -258,7 +260,7 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict
energySavingModificationsWithCoasting[csIdMax]=energySavingModification energySavingModificationsWithCoasting[csIdMax]=energySavingModification
end #if if doMethod1 end #if if doMethod1
# method 2: accelerate to a lower v_target # method 2: accelerate to a lower v_peak
if doMethod2==true if doMethod2==true
modificationType = "decreasing maximum velocity" modificationType = "decreasing maximum velocity"
energySavingModification = modifyCs(movingSectionOriginal, drivingCourseOriginal, csIdMax, modificationType, settings, train) energySavingModification = modifyCs(movingSectionOriginal, drivingCourseOriginal, csIdMax, modificationType, settings, train)
@ -281,72 +283,110 @@ end #function calculateMinimumEnergyConsumption
function modifyCs(movingSectionOriginal::Dict, drivingCourseOriginal::Vector{DataPoint}, csId::Integer, modificationType::String, settings::Dict, train::Dict) function modifyCs(movingSectionOriginal::Dict, drivingCourseOriginal::Vector{DataPoint}, csId::Integer, modificationType::String, settings::Dict, train::Dict)
# TODO: refctor and sort this function
CSsOrig::Vector{CharacteristicSection} = movingSectionOriginal[:characteristicSections] CSsOrig::Vector{CharacteristicSection} = movingSectionOriginal[:characteristicSections]
if modificationType == "increasing coasting" if modificationType == "increasing coasting"
# method 1: increase coasting # method 1: increase coasting
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=increaseCoastingSection(CSsOrig[csId], drivingCourseOriginal, settings, train, CSsOrig, movingSectionOriginal[:t_recoveryAvailable]) (characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=increaseCoastingSection(CSsOrig[csId], drivingCourseOriginal, settings, train, CSsOrig, movingSectionOriginal[:t_recoveryAvailable])
elseif modificationType == "decreasing maximum velocity" elseif modificationType == "decreasing maximum velocity"
# method 2: accelerate to a lower v_target # method 2: accelerate to a lower v_peak
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=decreaseMaximumVelocity(CSsOrig[csId], drivingCourseOriginal, settings, train, CSsOrig, movingSectionOriginal[:t_recoveryAvailable]) (characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=decreaseMaximumVelocity(CSsOrig[csId], drivingCourseOriginal, settings, train, CSsOrig, movingSectionOriginal[:t_recoveryAvailable])
elseif modificationType == "combination of energy saving methods" elseif modificationType == "combination of energy saving methods"
# calculate the combination of the previous methods # calculate the combination of the previous methods
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=combineEnergySavingMethods(CSsOrig[csId], drivingCourseOriginal, settings, train, CSsOrig, movingSectionOriginal[:t_recoveryAvailable]) (characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=combineEnergySavingMethods(CSsOrig[csId], drivingCourseOriginal, settings, train, CSsOrig, movingSectionOriginal[:t_recoveryAvailable])
else else
return EnergySavingModification() return createEnergySavingModification()
end end
energySavingModification = EnergySavingModification() #energySavingModification = createEnergySavingModification()
if new if new
energySavingModification.csId = csId # identifier of the characteristic section energySavingModification = Dict(: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" :type => modificationType, # type of energy saving modification: "increasing coasting" "decreasing maximum velocity" or "combination of decreasing maximum velocity and coasting"
energySavingModification.csModified = characteristicSectionModified # the modified characteristic section :csModified => characteristicSectionModified, # the modified characteristic section
energySavingModification.drivingCourseModified = drivingCourseModifiedUntilEndOfModifiedCS # drivingCourse of the modified characteristic section :drivingCourseModified => drivingCourseModifiedUntilEndOfModifiedCS) # drivingCourse for the modified characteristic section
energySavingModification.ΔE = CSsOrig[csId].E - energySavingModification.csModified.E # saved energy (in Ws)
energySavingModification.Δt = energySavingModification.csModified.t - CSsOrig[csId].t # time loss (in s) merge!(energySavingModification, Dict(:ΔE => CSsOrig[csId].E - energySavingModification[:csModified].E)) # saved energy (in Ws)
if energySavingModification.Δt <= movingSectionOriginal[:t_recoveryAvailable] && energySavingModification.ΔE >= 0.0 merge!(energySavingModification, Dict(:Δt => energySavingModification[:csModified].t - CSsOrig[csId].t)) # time loss (in s)
if energySavingModification[:Δt] <= movingSectionOriginal[:t_recoveryAvailable] && energySavingModification[:ΔE] >= 0.0
#*** TODO: check why "sign" is needed here #*** TODO: check why "sign" is needed here
# if modificationType == "combination of energy saving methods" # if modificationType == "combination of energy saving methods"
energySavingModification.ratio=sign(energySavingModification.Δt)*energySavingModification.ΔE/energySavingModification.Δt # ratio of ΔE and Δt (in Ws/s) ratio=sign(energySavingModification[:Δt])*energySavingModification[:ΔE]/energySavingModification[:Δt] # ratio of ΔE and Δt (in Ws/s)
# else # else
# energySavingModification.ratio = energySavingModification.ΔE / energySavingModification.Δt # ratio of ΔE and Δt (in Ws/s) # ratio = energySavingModification[:ΔE] / energySavingModification[:Δt] # ratio of ΔE and Δt (in Ws/s)
# end # end
# *** # ***
elseif energySavingModification.Δt == 0.0 elseif energySavingModification[:Δt] == 0.0
energySavingModification.ratio = energySavingModification.ΔE/0.000000001 ratio = energySavingModification[:ΔE]/0.000000001
else # Δt is to high or ΔE < 0.0 Ws else # Δt is to high or ΔE < 0.0 Ws
energySavingModification.ratio = 0.0 ratio = 0.0
end end
merge!(energySavingModification, Dict(:ratio => ratio)) # ratio of ΔE and Δt (in Ws/s)
return energySavingModification
else
return createEnergySavingModification()
end end
return energySavingModification
end #function modifyCs end #function modifyCs
function findBestModification(energySavingModifications::Vector{EnergySavingModification}, ratioMax::AbstractFloat, csIdMax::Integer, typeMax::String, t_recoveryAvailable::AbstractFloat) function findBestModification(energySavingModifications::Vector{Dict}, ratioMax::AbstractFloat, csIdMax::Integer, typeMax::String, t_recoveryAvailable::AbstractFloat)
for modNr in 1:length(energySavingModifications) for modNr in 1:length(energySavingModifications)
if energySavingModifications[modNr].ratio > ratioMax if energySavingModifications[modNr][:ratio] > ratioMax
if energySavingModifications[modNr].Δt <= t_recoveryAvailable if energySavingModifications[modNr][:Δt] <= t_recoveryAvailable
ratioMax=energySavingModifications[modNr].ratio ratioMax = energySavingModifications[modNr][:ratio]
csIdMax=energySavingModifications[modNr].csId csIdMax = energySavingModifications[modNr][:csId]
typeMax=energySavingModifications[modNr].type typeMax = energySavingModifications[modNr][:type]
else # Δt is to high else # Δt is to high
energySavingModifications[modNr].ratio=0.0 energySavingModifications[modNr][:ratio]=0.0
end #if end #if
end #if end #if
end #for end #for
return (energySavingModifications, ratioMax, csIdMax, typeMax) return (energySavingModifications, ratioMax, csIdMax, typeMax)
end #function findBestModification end #function findBestModification
function updateEnergySavingModifications(energySavingModifications::Vector{EnergySavingModification}, csIdMax::Integer, drivingCourseNew::Vector{DataPoint}, endOfModificationId::Integer, lastIdOfSelectedCsOriginal::Integer)
## for the energy saving operation mode it is nesserary to compare different energy saving modifications. These are part of the moving section.
function createEnergySavingModification()
energySavingModification = Dict(:csId => 0, # identifier of the characteristic section
:type => "", # type of energy saving modification: "increasing coasting" "decreasing maximum velocity" or "combination of decreasing maximum velocity and coasting"
:ΔE => 0.0, # saved energy (in Ws)
:Δt => 0.0, # time loss (in s)
:ratio => 0.0, # ratio of ΔE and Δt (in Ws/s)
:csModified => CharacteristicSection(), # the modified characteristic section
:drivingCourseModified => []) # drivingCourse for the modified characteristic section
end #createEnergySavingModification
function copyEnergySavingModification(original::Dict)
copy = Dict(:csId => original[:csId], # identifier of the characteristic section
:type => original[:type], # type of energy saving modification: "increasing coasting" "decreasing maximum velocity" or "combination of decreasing maximum velocity and coasting"
:ΔE => original[:ΔE], # saved energy (in Ws)
:Δt => original[:Δt], # time loss (in s)
:ratio => original[:ratio], # ratio of ΔE and Δt (in Ws/s)
:csModified => CharacteristicSection(original[:csModified])) # the modified characteristic section
drivingCourseModified = DataPoint[]
for i in 1:length(original[:drivingCourseModified])
push!(drivingCourseModified, DataPoint(original[:drivingCourseModified][i]))
end
merge!(copy, Dict(:drivingCourseModified => drivingCourseModified)) # drivingCourse for the modified characteristic section
return copy
end #function EnergySavingModification
function updateEnergySavingModifications!(energySavingModifications::Vector{Dict}, csIdMax::Integer, drivingCourseNew::Vector{DataPoint}, endOfModificationId::Integer, lastIdOfSelectedCsOriginal::Integer)
allBs=[:breakFree, :clearing, :acceleration, :cruising, :diminishing, :coasting, :cruisingAfterCoasting, :braking, :standstill] allBs=[:breakFree, :clearing, :acceleration, :cruising, :diminishing, :coasting, :cruisingAfterCoasting, :braking, :standstill]
difference = endOfModificationId-lastIdOfSelectedCsOriginal difference = endOfModificationId-lastIdOfSelectedCsOriginal
for modNr in csIdMax+1:length(energySavingModifications) for modNr in csIdMax+1:length(energySavingModifications)
if energySavingModifications[modNr].ratio>0 if energySavingModifications[modNr][:ratio]>0
BSs = energySavingModifications[modNr][:csModified].behaviorSections
# update the behavior sections of the modified charateristic section # update the behavior sections of the modified charateristic section
for bs in 1: length(allBs) for bs in 1: length(allBs)
if haskey(energySavingModifications[modNr].csModified.behaviorSections, allBs[bs]) if haskey(BSs, allBs[bs])
for point in 1:length(energySavingModifications[modNr].csModified.behaviorSections[allBs[bs]].dataPoints) for point in 1:length(BSs[allBs[bs]].dataPoints)
energySavingModifications[modNr].csModified.behaviorSections[allBs[bs]].dataPoints[point] = energySavingModifications[modNr].csModified.behaviorSections[allBs[bs]].dataPoints[point]+difference BSs[allBs[bs]].dataPoints[point] = BSs[allBs[bs]].dataPoints[point] + difference
end end
end #if end #if
end #for end #for
@ -357,8 +397,8 @@ function updateEnergySavingModifications(energySavingModifications::Vector{Energ
push!(drivingCourseModifiedNew, DataPoint(drivingCourseNew[i])) push!(drivingCourseModifiedNew, DataPoint(drivingCourseNew[i]))
end # for end # for
i=lastIdOfSelectedCsOriginal+1 i=lastIdOfSelectedCsOriginal+1
while i <= length(energySavingModifications[modNr].drivingCourseModified) while i <= length(energySavingModifications[modNr][:drivingCourseModified])
push!(drivingCourseModifiedNew, DataPoint(energySavingModifications[modNr].drivingCourseModified[i])) push!(drivingCourseModifiedNew, DataPoint(energySavingModifications[modNr][:drivingCourseModified][i]))
drivingCourseModifiedNew[end].i=length(drivingCourseModifiedNew) drivingCourseModifiedNew[end].i=length(drivingCourseModifiedNew)
drivingCourseModifiedNew[end].t=drivingCourseModifiedNew[end-1].t+drivingCourseModifiedNew[end].Δt drivingCourseModifiedNew[end].t=drivingCourseModifiedNew[end-1].t+drivingCourseModifiedNew[end].Δt
drivingCourseModifiedNew[end].E=drivingCourseModifiedNew[end-1].E+drivingCourseModifiedNew[end].ΔE drivingCourseModifiedNew[end].E=drivingCourseModifiedNew[end-1].E+drivingCourseModifiedNew[end].ΔE
@ -366,12 +406,13 @@ function updateEnergySavingModifications(energySavingModifications::Vector{Energ
i=i+1 i=i+1
end # while end # while
energySavingModifications[modNr].drivingCourseModified = drivingCourseModifiedNew energySavingModifications[modNr][:drivingCourseModified] = drivingCourseModifiedNew
end #if end #if
end #for end #for
return energySavingModifications return energySavingModifications
end #function updateEnergySavingModifications end #function updateEnergySavingModifications!
function copyMovingSection(original::Dict) function copyMovingSection(original::Dict)
CSsCopy = Vector{CharacteristicSection}() CSsCopy = Vector{CharacteristicSection}()
@ -379,21 +420,30 @@ function copyMovingSection(original::Dict)
push!(CSsCopy, CharacteristicSection(original[:characteristicSections][csId])) push!(CSsCopy, CharacteristicSection(original[:characteristicSections][csId]))
end #for end #for
ModificationsCopy = Vector{EnergySavingModification}()
for modId in 1:length(original[:energySavingModifications])
push!(ModificationsCopy, EnergySavingModification(original[:energySavingModifications][modId]))
end #for
copy = Dict(:id => original[:id], # identifier copy = Dict(:id => original[:id], # identifier
:length => original[:length], # total length (in m) :length => original[:length], # total length (in m)
:s_entry => original[:s_entry], # first position (in m) :s_entry => original[:s_entry], # first position (in m)
:s_exit => original[:s_exit], # last position (in m) :s_exit => original[:s_exit], # last position (in m)
:t => original[:t], # total running time (in s) :t => original[:t], # total running time (in s)
:E => original[:E], # total energy consumption (in Ws) :E => original[:E], # total energy consumption (in Ws)
:t_recovery => original[:t_recovery], # total recovery time for energy-saving modifications (in s) :characteristicSections => CSsCopy) # list of containing characteristic sections
:t_recoveryAvailable => original[:t_recoveryAvailable], # still available recovery time for energy-saving modifications (in s)
:characteristicSections => CSsCopy, # list of containing characteristic sections if haskey(original, :energySavingModifications) # list of containing all the used energy saving modifications
:energySavingModifications => ModificationsCopy) # list of containing all the used energy saving modifications ModificationsCopy = Dict[]
for modId in 1:length(original[:energySavingModifications])
push!(ModificationsCopy, EnergySavingModification(original[:energySavingModifications][modId]))
end #for
merge!(copy, Dict(:energySavingModifications => ModificationsCopy))
end
if haskey(original, :t_recovery) # total recovery time for energy-saving modifications (in s)
merge!(copy, Dict(:t_recovery => original[:t_recovery]))
end
if haskey(original, :t_recoveryAvailable) # still available recovery time for energy-saving modifications (in s)
merge!(copy, Dict(:t_recoveryAvailable => original[:t_recoveryAvailable]))
end
return copy return copy
end #function copyMovingSection end #function copyMovingSection

View File

@ -56,14 +56,14 @@ function createOutputDict(settings::Dict, pathName::String, trainName::String, d
row=[movingSection[:length], movingSection[:t], movingSection[:E]] row=[movingSection[:length], movingSection[:t], movingSection[:E]]
push!(outputArray, row) # push row to outputArray push!(outputArray, row) # push row to outputArray
elseif settings[:detailOfOutput]=="driving course" elseif settings[:detailOfOutput]=="driving course"
push!(outputArray, ["i", "behavior", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_consist (in N)", "ΔW (in Ws)","W (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]) # push header to outputArray push!(outputArray, ["i", "behavior", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_wagons (in N)", "ΔW (in Ws)","W (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]) # push header to outputArray
for point in drivingCourse for point in drivingCourse
row=[point.i, point.behavior, point.Δs, point.s, point.Δt, point.t, point.Δv, point.v, point.F_T, point.F_R, point.R_path, point.R_train, point.R_traction, point.R_consist, point.ΔW, point.W, point.ΔE, point.E, point.a] row=[point.i, point.behavior, point.Δs, point.s, point.Δt, point.t, point.Δv, point.v, point.F_T, point.F_R, point.R_path, point.R_train, point.R_traction, point.R_wagons, point.ΔW, point.W, point.ΔE, point.E, point.a]
push!(outputArray, row) # push row to outputArray push!(outputArray, row) # push row to outputArray
end end
end end
if length(movingSection[:energySavingModifications])>0 # if the moving section hast energy saving modifications the moving section is modified for minimum energy consumption if haskey(movingSection, :energySavingModifications) && length(movingSection[:energySavingModifications])>0 # if the moving section hast energy saving modifications the moving section is modified for minimum energy consumption
merge!(outputDict, Dict(:outputArrayMinimumEnergyConsumption => outputArray)) merge!(outputDict, Dict(:outputArrayMinimumEnergyConsumption => outputArray))
else else
merge!(outputDict, Dict(:outputArrayMinimumRunningTime => outputArray)) merge!(outputDict, Dict(:outputArrayMinimumRunningTime => outputArray))
@ -86,9 +86,9 @@ function createOutputDict(settings::Dict, pathName::String, trainName::String, d
row=[movingSectionMinimumEnergyConsumption[:length], movingSectionMinimumEnergyConsumption[:t], movingSectionMinimumEnergyConsumption[:E]] row=[movingSectionMinimumEnergyConsumption[:length], movingSectionMinimumEnergyConsumption[:t], movingSectionMinimumEnergyConsumption[:E]]
push!(outputArrayMinimumEnergyConsumption, row) # push row to outputArrayMinimumEnergyConsumption push!(outputArrayMinimumEnergyConsumption, row) # push row to outputArrayMinimumEnergyConsumption
elseif settings[:detailOfOutput]=="driving course" elseif settings[:detailOfOutput]=="driving course"
push!(outputArrayMinimumEnergyConsumption, ["i", "behavior", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_consist (in N)", "ΔW (in Ws)","W (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]) # push header to outputArrayMinimumEnergyConsumption push!(outputArrayMinimumEnergyConsumption, ["i", "behavior", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_wagons (in N)", "ΔW (in Ws)","W (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]) # push header to outputArrayMinimumEnergyConsumption
for point in drivingCourseMinimumEnergyConsumption for point in drivingCourseMinimumEnergyConsumption
row=[point.i, point.behavior, point.Δs, point.s, point.Δt, point.t, point.Δv, point.v, point.F_T, point.F_R, point.R_path, point.R_train, point.R_traction, point.R_consist, point.ΔW, point.W, point.ΔE, point.E, point.a] row=[point.i, point.behavior, point.Δs, point.s, point.Δt, point.t, point.Δv, point.v, point.F_T, point.F_R, point.R_path, point.R_train, point.R_traction, point.R_wagons, point.ΔW, point.W, point.ΔE, point.E, point.a]
push!(outputArrayMinimumEnergyConsumption, row) # push row to outputArrayMinimumEnergyConsumption push!(outputArrayMinimumEnergyConsumption, row) # push row to outputArrayMinimumEnergyConsumption
end end
end end
@ -134,7 +134,7 @@ function createOutputCsv(settings::Dict, pathName::String, trainName::String, dr
if settings[:detailOfOutput]=="minimal" if settings[:detailOfOutput]=="minimal"
header=outputDict[:outputArrayMinimumRunningTime][1] header=outputDict[:outputArrayMinimumRunningTime][1]
elseif settings[:detailOfOutput]=="driving course" elseif settings[:detailOfOutput]=="driving course"
header=["i", "behavior", "Delta s (in m)", "s (in m)", "Delta t (in s)","t (in s)","Delta v (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_consist (in N)"," Delta W (in Ws)","W (in Ws)","Delta E (in Ws)","E (in Ws)","a (in m/s^2)"] header=["i", "behavior", "Delta s (in m)", "s (in m)", "Delta t (in s)","t (in s)","Delta v (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_wagons (in N)"," Delta W (in Ws)","W (in Ws)","Delta E (in Ws)","E (in Ws)","a (in m/s^2)"]
end end
for column in 1:length(outputDict[outputArray][1]) for column in 1:length(outputDict[outputArray][1])
push!(infoColumns[column], header[column]) push!(infoColumns[column], header[column])
@ -177,7 +177,7 @@ function createOutputCsv(settings::Dict, pathName::String, trainName::String, dr
if settings[:detailOfOutput]=="minimal" if settings[:detailOfOutput]=="minimal"
header=outputDict[:outputArrayMinimumRunningTime][1] header=outputDict[:outputArrayMinimumRunningTime][1]
elseif settings[:detailOfOutput]=="driving course" elseif settings[:detailOfOutput]=="driving course"
header=["i", "behavior", "Delta s (in m)", "s (in m)", "Delta t (in s)","t (in s)","Delta v (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_consist (in N)"," Delta W (in Ws)","W (in Ws)","Delta E (in Ws)","E (in Ws)","a (in m/s^2)"] header=["i", "behavior", "Delta s (in m)", "s (in m)", "Delta t (in s)","t (in s)","Delta v (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_wagons (in N)"," Delta W (in Ws)","W (in Ws)","Delta E (in Ws)","E (in Ws)","a (in m/s^2)"]
end end
for column in 1:length(outputDict[:outputArrayMinimumRunningTime][1]) for column in 1:length(outputDict[:outputArrayMinimumRunningTime][1])
@ -215,7 +215,7 @@ function createOutputCsv(settings::Dict, pathName::String, trainName::String, dr
if settings[:detailOfOutput]=="minimal" if settings[:detailOfOutput]=="minimal"
header=outputDict[:outputArrayMinimumRunningTime][1] header=outputDict[:outputArrayMinimumRunningTime][1]
elseif settings[:detailOfOutput]=="driving course" elseif settings[:detailOfOutput]=="driving course"
header=["i", "behavior", "Delta s (in m)", "s (in m)", "Delta t (in s)","t (in s)","Delta v (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_consist (in N)"," Delta W (in Ws)","W (in Ws)","Delta E (in Ws)","E (in Ws)","a (in m/s^2)"] header=["i", "behavior", "Delta s (in m)", "s (in m)", "Delta t (in s)","t (in s)","Delta v (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_wagons (in N)"," Delta W (in Ws)","W (in Ws)","Delta E (in Ws)","E (in Ws)","a (in m/s^2)"]
end end
for column in 1:length(outputDict[:outputArrayMinimumEnergyConsumption][1]) for column in 1:length(outputDict[:outputArrayMinimumEnergyConsumption][1])

View File

@ -41,10 +41,7 @@ function createMovingSection(path::Dict, v_trainLimit::Real)
:s_exit => s_exit, # last position (in m) :s_exit => s_exit, # last position (in m)
:t => 0.0, # total running time (in s) :t => 0.0, # total running time (in s)
:E => 0.0, # total energy consumption (in Ws) :E => 0.0, # total energy consumption (in Ws)
:t_recovery => 0.0, # total recovery time for energy-saving modifications (in s) :characteristicSections => CSs) # list of containing characteristic sections
:t_recoveryAvailable => 0.0, # still available recovery time for energy-saving modifications (in s)
:characteristicSections => CSs, # list of containing characteristic sections
:energySavingModifications => EnergySavingModification[]) # list of containing all the used energy saving modifications
return movingSection return movingSection
end #function createMovingSection end #function createMovingSection
@ -62,12 +59,12 @@ function createCharacteristicSection(csId::Integer, s_csStart::Real, section::Di
characteristicSection.E=0.0 # total energy consumption (in Ws) characteristicSection.E=0.0 # total energy consumption (in Ws)
characteristicSection.v_limit=v_csLimit # speed limit (in m/s) characteristicSection.v_limit=v_csLimit # speed limit (in m/s)
# initializing v_entry, v_target and v_exit with v_limit # initializing v_entry, v_peak and v_exit with v_limit
characteristicSection.v_target=characteristicSection.v_limit # maximum target speed (in m/s) characteristicSection.v_peak=characteristicSection.v_limit # maximum reachable speed (in m/s)
characteristicSection.v_entry=characteristicSection.v_limit # maximum entry speed (in m/s) characteristicSection.v_entry=characteristicSection.v_limit # maximum entry speed (in m/s)
characteristicSection.v_exit=characteristicSection.v_limit # maximum exit speed (in m/s) characteristicSection.v_exit=characteristicSection.v_limit # maximum exit speed (in m/s)
characteristicSection.f_Rp=section[:f_Rp] # path resistance (in ‰) characteristicSection.r_path=section[:f_Rp] # path resistance (in ‰)
return characteristicSection return characteristicSection
end #function createCharacteristicSection end #function createCharacteristicSection
@ -84,7 +81,7 @@ function secureBrakingBehavior!(movingSection::Dict, a_braking::Real)
v_entryMax=floor(v_entryMax, digits=12) v_entryMax=floor(v_entryMax, digits=12)
CSs[csId].v_entry=min(CSs[csId].v_limit, v_entryMax) CSs[csId].v_entry=min(CSs[csId].v_limit, v_entryMax)
CSs[csId].v_target=CSs[csId].v_entry CSs[csId].v_peak=CSs[csId].v_entry
csId=csId-1 csId=csId-1
if csId >= 1 if csId >= 1
CSs[csId].v_exit=min(CSs[csId].v_limit, CSs[csId+1].v_entry) CSs[csId].v_exit=min(CSs[csId].v_limit, CSs[csId+1].v_entry)
@ -110,12 +107,12 @@ function secureAccelerationBehavior!(movingSection::Dict, settings::Dict, train:
startingPoint.v=CSs[csId].v_entry startingPoint.v=CSs[csId].v_entry
accelerationCourse=[startingPoint] # List of data points accelerationCourse=[startingPoint] # List of data points
if CSs[csId].v_entry<CSs[csId].v_target if CSs[csId].v_entry<CSs[csId].v_peak
(CSs[csId], accelerationCourse)=addAccelerationPhase!(CSs[csId], accelerationCourse, settings, train, CSs) # this function changes the accelerationCourse (CSs[csId], accelerationCourse)=addAccelerationPhase!(CSs[csId], accelerationCourse, settings, train, CSs) # this function changes the accelerationCourse
CSs[csId].v_target=max(CSs[csId].v_entry,accelerationCourse[end].v) CSs[csId].v_peak=max(CSs[csId].v_entry,accelerationCourse[end].v)
CSs[csId].v_exit=min(CSs[csId].v_exit, CSs[csId].v_target, accelerationCourse[end].v) CSs[csId].v_exit=min(CSs[csId].v_exit, CSs[csId].v_peak, accelerationCourse[end].v)
else #CSs[csId].v_entry==CSs[csId].v_target else #CSs[csId].v_entry==CSs[csId].v_peak
# v_exit stays the same # v_exit stays the same
end #if end #if
@ -129,7 +126,7 @@ end #function secureAccelerationBehavior!
## define the intersection velocities between the characterisitc sections to secure cruising behavior ## define the intersection velocities between the characterisitc sections to secure cruising behavior
function secureCruisingBehavior!(movingSection::Dict, settings::Dict, train::Dict) function secureCruisingBehavior!(movingSection::Dict, settings::Dict, train::Dict)
# limit the exit velocity of the characteristic sections in case that the train cruises in every section at v_target # limit the exit velocity of the characteristic sections in case that the train cruises in every section at v_peak
CSs::Vector{CharacteristicSection} = movingSection[:characteristicSections] CSs::Vector{CharacteristicSection} = movingSection[:characteristicSections]
startingPoint=DataPoint() startingPoint=DataPoint()
@ -141,7 +138,7 @@ function secureCruisingBehavior!(movingSection::Dict, settings::Dict, train::Dic
CSs[csId].v_entry=min(CSs[csId].v_entry, previousCSv_exit) CSs[csId].v_entry=min(CSs[csId].v_entry, previousCSv_exit)
startingPoint.s=CSs[csId].s_entry startingPoint.s=CSs[csId].s_entry
startingPoint.v=CSs[csId].v_target startingPoint.v=CSs[csId].v_peak
cruisingCourse=[startingPoint] # List of data points cruisingCourse=[startingPoint] # List of data points
(CSs[csId], cruisingCourse)=addCruisingPhase!(CSs[csId], cruisingCourse, CSs[csId].length, settings, train, CSs, "cruising") # this function changes the cruisingCourse (CSs[csId], cruisingCourse)=addCruisingPhase!(CSs[csId], cruisingCourse, CSs[csId].length, settings, train, CSs, "cruising") # this function changes the cruisingCourse

View File

@ -30,8 +30,6 @@ todo !!!
``` ```
""" """
function calculateDrivingDynamics(trainDirectory::String, pathDirectory::String, settingsDirectory::String) function calculateDrivingDynamics(trainDirectory::String, pathDirectory::String, settingsDirectory::String)
print("\n\n\n")
# input # input
(train, path, settings)=readInput(trainDirectory, pathDirectory, settingsDirectory) (train, path, settings)=readInput(trainDirectory, pathDirectory, settingsDirectory)
println("The input has been saved.") println("The input has been saved.")

View File

@ -19,16 +19,16 @@ mutable struct DataPoint
ΔW::AbstractFloat # mechanical work in this step (in Ws) ΔW::AbstractFloat # mechanical work in this step (in Ws)
E::AbstractFloat # energy consumption (in Ws) E::AbstractFloat # energy consumption (in Ws)
ΔE::AbstractFloat # energy consumption in this step (in Ws) ΔE::AbstractFloat # energy consumption in this step (in Ws)
F_T::AbstractFloat # tractive effort (in N) F_T::AbstractFloat # tractive effort (in N)
F_R::AbstractFloat # resisting force (in N) F_R::AbstractFloat # resisting force (in N)
R_path::AbstractFloat # path resistance (in N) R_path::AbstractFloat # path resistance (in N)
R_train::AbstractFloat # train resistance (in N) R_train::AbstractFloat # train resistance (in N)
R_traction::AbstractFloat # traction unit resistance (in N) R_traction::AbstractFloat # traction unit resistance (in N)
R_consist::AbstractFloat # set of wagons resistance (in N) R_wagons::AbstractFloat # set of wagons resistance (in N)
end # mutable struct DataPoint end # mutable struct DataPoint
DataPoint()=DataPoint(0, "", 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) DataPoint()=DataPoint(0, "", 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
# tried to insert copy on 15.07.2021 copy(original::DataPoint)=DataPoint(original.i, original.s, original.Δs, original.t, original.Δt, original.v, original.Δv, original.a, original.W, original.ΔW, original.E, original.ΔE, original.F_T, original.F_R, original.R_path, original.R_train, original.R_traction, original.R_consist) # tried to insert copy on 15.07.2021 copy(original::DataPoint)=DataPoint(original.i, original.s, original.Δs, original.t, original.Δt, original.v, original.Δv, original.a, original.W, original.ΔW, original.E, original.ΔE, original.F_T, original.F_R, original.R_path, original.R_train, original.R_traction, original.R_wagons)
DataPoint(original::DataPoint)=DataPoint(original.i, original.behavior, original.s, original.Δs, original.t, original.Δt, original.v, original.Δv, original.a, original.W, original.ΔW, original.E, original.ΔE, original.F_T, original.F_R, original.R_path, original.R_train, original.R_traction, original.R_consist) DataPoint(original::DataPoint)=DataPoint(original.i, original.behavior, original.s, original.Δs, original.t, original.Δt, original.v, original.Δv, original.a, original.W, original.ΔW, original.E, original.ΔE, original.F_T, original.F_R, original.R_path, original.R_train, original.R_traction, original.R_wagons)
@ -63,15 +63,15 @@ mutable struct CharacteristicSection
t::AbstractFloat # total running time (in s) t::AbstractFloat # total running time (in s)
E::AbstractFloat # total energy consumption (in Ws) E::AbstractFloat # total energy consumption (in Ws)
v_limit::AbstractFloat # speed limit (in m/s) v_limit::AbstractFloat # speed limit (in m/s)
v_target::AbstractFloat # maximum target speed (in m/s) v_peak::AbstractFloat # maximum reachable speed (in m/s)
v_entry::AbstractFloat # maximum entry speed (in m/s) v_entry::AbstractFloat # maximum entry speed (in m/s)
v_exit::AbstractFloat # maximum exit speed (in m/s) v_exit::AbstractFloat # maximum exit speed (in m/s)
f_Rp::AbstractFloat # spedific path resistance (in ‰) r_path::AbstractFloat # spedific path resistance (in ‰)
behaviorSections::AbstractDict{Symbol, BehaviorSection} # list of containing behavior sections behaviorSections::AbstractDict{Symbol, BehaviorSection} # list of containing behavior sections
end # mutable struct CharacteristicSection end # mutable struct CharacteristicSection
CharacteristicSection()=CharacteristicSection(0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Dict{Symbol, BehaviorSection}()) CharacteristicSection()=CharacteristicSection(0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Dict{Symbol, BehaviorSection}())
function CharacteristicSection(original::CharacteristicSection) function CharacteristicSection(original::CharacteristicSection)
copy=CharacteristicSection(original.id, original.length, original.s_entry, original.s_exit, original.t, original.E, original.v_limit, original.v_target, original.v_entry, original.v_exit, original.f_Rp, Dict{Symbol, BehaviorSection}()) copy=CharacteristicSection(original.id, original.length, original.s_entry, original.s_exit, original.t, original.E, original.v_limit, original.v_peak, original.v_entry, original.v_exit, original.r_path, Dict{Symbol, BehaviorSection}())
allBs=[:breakFree, :clearing, :acceleration, :cruising, :diminishing, :coasting, :cruisingAfterCoasting, :braking, :standstill] allBs=[:breakFree, :clearing, :acceleration, :cruising, :diminishing, :coasting, :cruisingAfterCoasting, :braking, :standstill]
for bs in 1: length(allBs) for bs in 1: length(allBs)
if haskey(original.behaviorSections, allBs[bs]) if haskey(original.behaviorSections, allBs[bs])
@ -81,7 +81,7 @@ function CharacteristicSection(original::CharacteristicSection)
return copy return copy
end #function CharacteristicSection end #function CharacteristicSection
## for the energy saving operation mode it is nesserary to compare different energy saving modifications. These are part of the moving section. #= for the energy saving operation mode it is nesserary to compare different energy saving modifications. These are part of the moving section.
mutable struct EnergySavingModification mutable struct EnergySavingModification
csId::Integer # identifier of the characteristic section csId::Integer # identifier of the characteristic section
type::String # type of energy saving modification: "increasing coasting" "decreasing maximum velocity" or "combination of decreasing maximum velocity and coasting" type::String # type of energy saving modification: "increasing coasting" "decreasing maximum velocity" or "combination of decreasing maximum velocity and coasting"
@ -100,5 +100,6 @@ function EnergySavingModification(original::EnergySavingModification)
end end
return copy return copy
end #function EnergySavingModification end #function EnergySavingModification
=#
end #module end #module