parent
dab7e3495a
commit
bee38ec311
|
@ -1,7 +1,7 @@
|
|||
name = "TrainRun"
|
||||
uuid = "e4541106-d44c-4e00-b50b-ecdf479fcf92"
|
||||
authors = ["Max Kannenberg"]
|
||||
version = "0.5.3"
|
||||
version = "0.6.0"
|
||||
|
||||
[deps]
|
||||
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
|
||||
|
|
|
@ -31,6 +31,14 @@ train_run = calculateDrivingDynamics(train, running_path, settings)
|
|||
|
||||
# History
|
||||
|
||||
## Version 0.6
|
||||
Refactor some of the mutable structs from types.jl as Dictionaries
|
||||
|
||||
- Remove the mutable structs Train, Path, PathSection, Settings and MovingSection
|
||||
- Create Dictionaries for train, path an settings in Input.jl
|
||||
- Create a Dictionary for the whole moving section in Preperation.jl and a function for copying the moving section in OperationModes.jl
|
||||
- Change the type of existing Dictionary keys from String to Symbol
|
||||
|
||||
## Version 0.5.3
|
||||
|
||||
Rename variables in every .jl an .yaml file
|
||||
|
|
|
@ -13,6 +13,6 @@ running_path = "data/paths/path_1_10km_nConst_vConst.yaml"
|
|||
settings = "data/settings.yaml"
|
||||
|
||||
train_run = calculateDrivingDynamics(train, running_path, settings)
|
||||
runtime = last(train_run["outputArrayMinimumRunningTime"])[5]
|
||||
runtime = last(train_run[:outputArrayMinimumRunningTime])[5]
|
||||
|
||||
println("The V 90 with 10 ore wagons needs $runtime seconds for 10 km with no gradient.")
|
||||
|
|
|
@ -8,102 +8,102 @@ export calculateRecoveryTime, increaseCoastingSection, decreaseMaximumVelocity,
|
|||
approximationLevel = 6 # value for approximation to intersections
|
||||
# TODO: define it in TrainRun and give it to each function?
|
||||
|
||||
function calculateRecoveryTime(s_MS::AbstractFloat, t_MS::AbstractFloat, train::Train)
|
||||
function calculateRecoveryTime(s_MS::Real, t_MS::AbstractFloat, train::Dict)
|
||||
# function for calculating the recovery time that can be used for energy saving
|
||||
# MS: Moving Section
|
||||
if train.trainType=="motor coach train"
|
||||
if train[:trainType]=="motor coach train"
|
||||
if s_MS<= 30000
|
||||
c_s=0.0
|
||||
else s_MS> 30000
|
||||
c_s=0.0006
|
||||
end # if s_MS
|
||||
|
||||
if train.v_limit<=140/3.6 # unit is m/s
|
||||
if train[:v_limit]<=140/3.6 # unit is m/s
|
||||
c_t=0.03
|
||||
elseif train.v_limit<=160/3.6 # unit is m/s
|
||||
elseif train[:v_limit]<=160/3.6 # unit is m/s
|
||||
c_t=0.04
|
||||
elseif train.v_limit<=200/3.6 # unit is m/s
|
||||
elseif train[:v_limit]<=200/3.6 # unit is m/s
|
||||
c_t=0.05
|
||||
elseif train.v_limit<=250/3.6 # unit is m/s
|
||||
elseif train[:v_limit]<=250/3.6 # unit is m/s
|
||||
c_t=0.06
|
||||
else # train.v_limit>120/3.6 # unit is m/s
|
||||
else # train[:v_limit]>120/3.6 # unit is m/s
|
||||
c_t=0.07
|
||||
end # if train.v_limit
|
||||
end # if train[:v_limit]
|
||||
|
||||
t_recovery=s_MS*c_s+t_MS*c_t
|
||||
return t_recovery
|
||||
elseif train.trainType=="freight" && train.v_limit<=120/3.6 # unit is m/s
|
||||
elseif train[:trainType]=="freight" && train[:v_limit]<=120/3.6 # unit is m/s
|
||||
t_recovery1=s_MS*0.0006 +t_MS*0.03
|
||||
t_recovery2=s_MS*0.0018 +t_MS*0.0
|
||||
t_recovery3=s_MS*0.0 +t_MS*0.04
|
||||
t_recovery=max(t_recovery1, t_recovery2, t_recovery3)
|
||||
|
||||
return t_recovery
|
||||
else # train.trainType=="passenger" || (train.trainType=="freight" && train.v_limit>120/3.6) # unit is m/s
|
||||
else # train[:trainType]=="passenger" || (train[:trainType]=="freight" && train[:v_limit]>120/3.6) # unit is m/s
|
||||
if s_MS<= 30000
|
||||
c_s=0.0
|
||||
else s_MS> 30000
|
||||
c_s=0.0009
|
||||
end # if s_MS
|
||||
if train.v_limit<=140/3.6 # unit is m/s
|
||||
if train.m_train<=300000 # unit is kg
|
||||
if train[:v_limit]<=140/3.6 # unit is m/s
|
||||
if train[:m_train]<=300000 # unit is kg
|
||||
c_t=0.03
|
||||
elseif train.m_train<=500000 # unit is kg
|
||||
elseif train[:m_train]<=500000 # unit is kg
|
||||
c_t=0.04
|
||||
elseif train.m_train<=700000 # unit is kg
|
||||
elseif train[:m_train]<=700000 # unit is kg
|
||||
c_t=0.04
|
||||
else # train.m_train>700000 # unit is kg
|
||||
else # train[:m_train]>700000 # unit is kg
|
||||
c_t=0.05
|
||||
end # if train.m_train
|
||||
elseif train.v_limit<=160/3.6 # unit is m/s
|
||||
if train.m_train<=300000 # unit is kg
|
||||
end # if train[:m_train]
|
||||
elseif train[:v_limit]<=160/3.6 # unit is m/s
|
||||
if train[:m_train]<=300000 # unit is kg
|
||||
c_t=0.03
|
||||
elseif train.m_train<=500000 # unit is kg
|
||||
elseif train[:m_train]<=500000 # unit is kg
|
||||
c_t=0.04
|
||||
else # train.m_train>500000 # unit is kg
|
||||
else # train[:m_train]>500000 # unit is kg
|
||||
c_t=0.0
|
||||
end # if train.m_train
|
||||
elseif train.v_limit<=200/3.6 # unit is m/s
|
||||
if train.m_train<=300000 # unit is kg
|
||||
end # if train[:m_train]
|
||||
elseif train[:v_limit]<=200/3.6 # unit is m/s
|
||||
if train[:m_train]<=300000 # unit is kg
|
||||
c_t=0.04
|
||||
elseif train.m_train<=500000 # unit is kg
|
||||
elseif train[:m_train]<=500000 # unit is kg
|
||||
c_t=0.05
|
||||
else # train.m_train>500000 # unit is kg
|
||||
else # train[:m_train]>500000 # unit is kg
|
||||
c_t=0.06
|
||||
end # if train.m_train
|
||||
else # train.v_limit>200/3.6 # unit is m/s
|
||||
if train.m_train<=300000 # unit is kg
|
||||
end # if train[:m_train]
|
||||
else # train[:v_limit]>200/3.6 # unit is m/s
|
||||
if train[:m_train]<=300000 # unit is kg
|
||||
c_t=0.05
|
||||
elseif train.m_train<=500000 # unit is kg
|
||||
elseif train[:m_train]<=500000 # unit is kg
|
||||
c_t=0.06
|
||||
else # train.m_train>500000 # unit is kg
|
||||
else # train[:m_train]>500000 # unit is kg
|
||||
c_t=0.07
|
||||
end # if train.m_train
|
||||
end # if train.v_limit
|
||||
end # if train[:m_train]
|
||||
end # if train[:v_limit]
|
||||
|
||||
c_tMin=s_MS/t_MS*0.0012
|
||||
c_t=max(c_t, c_tMin)
|
||||
|
||||
t_recovery=s_MS*c_s+t_MS*c_t
|
||||
return t_recovery
|
||||
end # if train.trainType
|
||||
end # if train[:trainType]
|
||||
end #function calculateRecoveryTime
|
||||
|
||||
function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Settings, train::Train, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||
if (haskey(csOriginal.behaviorSections, "cruising") || haskey(csOriginal.behaviorSections, "diminishing")) && haskey(csOriginal.behaviorSections, "braking")
|
||||
function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||
if (haskey(csOriginal.behaviorSections, :cruising) || haskey(csOriginal.behaviorSections, :diminishing)) && haskey(csOriginal.behaviorSections, :braking)
|
||||
# check if cruising or diminishing should be reduced for coasting
|
||||
if haskey(csOriginal.behaviorSections, "cruising") && haskey(csOriginal.behaviorSections, "diminishing")
|
||||
if get(csOriginal.behaviorSections, "cruising", BehaviorSection()).dataPoints[1] > get(csOriginal.behaviorSections, "diminishing", BehaviorSection()).dataPoints[1]
|
||||
if haskey(csOriginal.behaviorSections, :cruising) && haskey(csOriginal.behaviorSections, :diminishing)
|
||||
if csOriginal.behaviorSections[:cruising].dataPoints[1] > csOriginal.behaviorSections[:diminishing].dataPoints[1]
|
||||
reduceCruising=true
|
||||
reduceDiminishing=false
|
||||
else
|
||||
reduceDiminishing=true
|
||||
reduceCruising=false
|
||||
end
|
||||
elseif haskey(csOriginal.behaviorSections, "cruising")
|
||||
elseif haskey(csOriginal.behaviorSections, :cruising)
|
||||
reduceCruising=true
|
||||
reduceDiminishing=false
|
||||
elseif haskey(csOriginal.behaviorSections, "diminishing")
|
||||
elseif haskey(csOriginal.behaviorSections, :diminishing)
|
||||
reduceDiminishing=true
|
||||
reduceCruising=false
|
||||
end
|
||||
|
@ -111,13 +111,13 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
|
|||
|
||||
|
||||
if reduceCruising
|
||||
cruisingReduction=settings.stepSize
|
||||
while cruisingReduction>=settings.stepSize/10^approximationLevel
|
||||
#while cruisingReduction>=settings.stepSize/100
|
||||
while cruisingReduction>=settings.stepSize/10^approximationLevel # will be done once and then depending on approximationLevel repeated with smaller cruisingReduction unless !(drivingCourseModified[end].v<=csModified.v_exit && drivingCourseModified[end].s<csModified.s_exit) -> see below at the end of the while loop
|
||||
cruisingReduction = settings[:stepSize]
|
||||
while cruisingReduction>=settings[:stepSize]/10^approximationLevel
|
||||
#while cruisingReduction>=settings[:stepSize]/100
|
||||
while cruisingReduction>=settings[:stepSize]/10^approximationLevel # will be done once and then depending on approximationLevel repeated with smaller cruisingReduction unless !(drivingCourseModified[end].v<=csModified.v_exit && drivingCourseModified[end].s<csModified.s_exit) -> see below at the end of the while loop
|
||||
|
||||
# create a copy for the characteristic sections drivingCourse
|
||||
energySavingStartId=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).dataPoints[1]
|
||||
energySavingStartId=get(csOriginal.behaviorSections, :cruising, BehaviorSection()).dataPoints[1]
|
||||
if energySavingStartId==0
|
||||
error("ERROR at creating a new driving course for energy saving with coasting !")
|
||||
end
|
||||
|
@ -130,46 +130,45 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
|
|||
end
|
||||
|
||||
# calculating the new length of the cruising section
|
||||
if settings.stepVariable=="s in m" # distance step method
|
||||
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).length-cruisingReduction
|
||||
elseif settings.stepVariable=="t in s" # time step method
|
||||
# 09/20 old: doesn't work for non constant cruising
|
||||
# t_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).t-cruisingReduction
|
||||
if settings[:stepVariable]=="s in m" # distance step method
|
||||
s_cruising = csOriginal.behaviorSections[:cruising].length - cruisingReduction
|
||||
elseif settings[:stepVariable]=="t in s" # time step method
|
||||
# 09/20 old: doesn't work for non constant cruising -> TODO: should work now
|
||||
# t_cruising=csOriginal.behaviorSections[:cruising].t-cruisingReduction
|
||||
# s_cruising=t_cruising*drivingCourseModified[end].v
|
||||
wayReduction=drivingCourse(get(csOriginal.behaviorSections, "cruising", BehaviorSection()).dataPoints[end]).v*cruisingReduction
|
||||
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).length-wayReduction
|
||||
distanceReduction = drivingCourse(csOriginal.behaviorSections[:cruising].dataPoints[end]).v*cruisingReduction
|
||||
s_cruising = csOriginal.behaviorSections[:cruising].length-distanceReduction
|
||||
|
||||
elseif settings.stepVariable=="v in m/s" # velocity step method
|
||||
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).length-cruisingReduction*10 # TODO: or better: *100 ?
|
||||
elseif settings[:stepVariable]=="v in m/s" # velocity step method
|
||||
s_cruising=csOriginal.behaviorSections[:cruising].length-cruisingReduction*10 # TODO: or better: *100 ?
|
||||
end #if
|
||||
s_cruising=max(0.0, s_cruising)
|
||||
|
||||
# copy csOriginal to csModified
|
||||
csModified=CharacteristicSection(csOriginal.id, csOriginal.length, csOriginal.s_entry, csOriginal.s_exit, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_target, csOriginal.v_entry, csOriginal.v_exit, csOriginal.f_Rp, Dict{String, BehaviorSection}())
|
||||
if haskey(csOriginal.behaviorSections, "breakFree")
|
||||
breakFreeSection=BehaviorSection(get(csOriginal.behaviorSections, "breakFree", BehaviorSection()))
|
||||
merge!(csModified.behaviorSections, Dict("breakFree"=>breakFreeSection))
|
||||
csModified.E=csModified.E+get(csModified.behaviorSections, "breakFree", BehaviorSection()).E
|
||||
csModified.t=csModified.t+get(csModified.behaviorSections, "breakFree", BehaviorSection()).t
|
||||
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}())
|
||||
if haskey(csOriginal.behaviorSections, :breakFree)
|
||||
breakFreeSection=BehaviorSection(csOriginal.behaviorSections[:breakFree])
|
||||
merge!(csModified.behaviorSections, Dict(:breakFree=>breakFreeSection))
|
||||
csModified.E = csModified.E + csModified.behaviorSections[:breakFree].E
|
||||
csModified.t = csModified.t + csModified.behaviorSections[:breakFree].t
|
||||
end
|
||||
if haskey(csOriginal.behaviorSections, "clearing") # this section is needed before acceleration if the train wants to accelerate to a speed higher than the limit in a previous CS where parts of the train are still located
|
||||
clearingSection=BehaviorSection(get(csOriginal.behaviorSections, "clearing", BehaviorSection()))
|
||||
merge!(csModified.behaviorSections, Dict("clearing"=>clearingSection))
|
||||
csModified.E=csModified.E+get(csModified.behaviorSections, "clearing", BehaviorSection()).E
|
||||
csModified.t=csModified.t+get(csModified.behaviorSections, "clearing", BehaviorSection()).t
|
||||
if haskey(csOriginal.behaviorSections, :clearing) # this section is needed before acceleration if the train wants to accelerate to a speed higher than the limit in a previous CS where parts of the train are still located
|
||||
clearingSection=BehaviorSection(csOriginal.behaviorSections[:clearing])
|
||||
merge!(csModified.behaviorSections, Dict(:clearing=>clearingSection))
|
||||
csModified.E = csModified.E + csModified.behaviorSections[:clearing].E
|
||||
csModified.t = csModified.t + csModified.behaviorSections[:clearing].t
|
||||
end
|
||||
if haskey(csOriginal.behaviorSections, "acceleration")
|
||||
accelerationSection=BehaviorSection(get(csOriginal.behaviorSections, "acceleration", BehaviorSection()))
|
||||
merge!(csModified.behaviorSections, Dict("acceleration"=>accelerationSection))
|
||||
csModified.E=csModified.E+get(csModified.behaviorSections, "acceleration", BehaviorSection()).E
|
||||
csModified.t=csModified.t+get(csModified.behaviorSections, "acceleration", BehaviorSection()).t
|
||||
if haskey(csOriginal.behaviorSections, :acceleration)
|
||||
accelerationSection=BehaviorSection(csOriginal.behaviorSections[:acceleration])
|
||||
merge!(csModified.behaviorSections, Dict(:acceleration=>accelerationSection))
|
||||
csModified.E = csModified.E + csModified.behaviorSections[:acceleration].E
|
||||
csModified.t = csModified.t + csModified.behaviorSections[:acceleration].t
|
||||
end
|
||||
|
||||
if haskey(csOriginal.behaviorSections, "diminishing")
|
||||
diminishingSection=BehaviorSection(get(csOriginal.behaviorSections, "diminishing", BehaviorSection()))
|
||||
merge!(csModified.behaviorSections, Dict("diminishing"=>diminishingSection))
|
||||
csModified.E=csModified.E+get(csModified.behaviorSections, "diminishing", BehaviorSection()).E
|
||||
csModified.t=csModified.t+get(csModified.behaviorSections, "diminishing", BehaviorSection()).t
|
||||
if haskey(csOriginal.behaviorSections, :diminishing)
|
||||
diminishingSection=BehaviorSection(csOriginal.behaviorSections[:diminishing])
|
||||
merge!(csModified.behaviorSections, Dict(:diminishing=>diminishingSection))
|
||||
csModified.E = csModified.E + csModified.behaviorSections[:diminishing].E
|
||||
csModified.t = csModified.t + csModified.behaviorSections[:diminishing].t
|
||||
end
|
||||
|
||||
|
||||
|
@ -191,7 +190,7 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
|
|||
|
||||
# calculate the moving phase between coasting and the end of the CS
|
||||
if drivingCourseModified[end].v > csModified.v_exit
|
||||
#(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings.massModel, train, allCSs)
|
||||
#(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings[:massModel], train, allCSs)
|
||||
(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings, train, allCSs)
|
||||
elseif drivingCourseModified[end].v == csModified.v_exit && drivingCourseModified[end].s < csModified.s_exit
|
||||
# v_exit is already reached. Now cruise till the end of the CS
|
||||
|
@ -208,39 +207,36 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
|
|||
|
||||
|
||||
elseif reduceDiminishing
|
||||
# TODO: At the moment diminishing is reduced like the acceleration in decreaseMaximumVelocity. To reduce code, the methods for reducing cruising phase an reducing the diminishing pahse can be combined in some parts.
|
||||
# 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
|
||||
csModified=CharacteristicSection(csOriginal.id, csOriginal.length, csOriginal.s_entry, csOriginal.s_exit, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_target, csOriginal.v_entry, csOriginal.v_exit, csOriginal.f_Rp, Dict{String, BehaviorSection}())
|
||||
|
||||
if haskey(csOriginal.behaviorSections, "breakFree")
|
||||
breakFreeSection=BehaviorSection(get(csOriginal.behaviorSections, "breakFree", BehaviorSection()))
|
||||
merge!(csModified.behaviorSections, Dict("breakFree"=>breakFreeSection))
|
||||
csModified.E=csModified.E+get(csModified.behaviorSections, "breakFree", BehaviorSection()).E
|
||||
csModified.t=csModified.t+get(csModified.behaviorSections, "breakFree", BehaviorSection()).t
|
||||
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}())
|
||||
if haskey(csOriginal.behaviorSections, :breakFree)
|
||||
breakFreeSection=BehaviorSection(csOriginal.behaviorSections[:breakFree])
|
||||
merge!(csModified.behaviorSections, Dict(:breakFree=>breakFreeSection))
|
||||
csModified.E = csModified.E + csModified.behaviorSections[:breakFree].E
|
||||
csModified.t = csModified.t + csModified.behaviorSections[:breakFree].t
|
||||
end
|
||||
if haskey(csOriginal.behaviorSections, :clearing) # this section is needed before acceleration if the train wants to accelerate to a speed higher than the limit in a previous CS where parts of the train are still located
|
||||
clearingSection=BehaviorSection(csOriginal.behaviorSections[:clearing])
|
||||
merge!(csModified.behaviorSections, Dict(:clearing=>clearingSection))
|
||||
csModified.E = csModified.E + csModified.behaviorSections[:clearing].E
|
||||
csModified.t = csModified.t + csModified.behaviorSections[:clearing].t
|
||||
end
|
||||
if haskey(csOriginal.behaviorSections, :acceleration)
|
||||
accelerationSection=BehaviorSection(csOriginal.behaviorSections[:acceleration])
|
||||
merge!(csModified.behaviorSections, Dict(:acceleration=>accelerationSection))
|
||||
csModified.E = csModified.E + csModified.behaviorSections[:acceleration].E
|
||||
csModified.t = csModified.t + csModified.behaviorSections[:acceleration].t
|
||||
end
|
||||
if haskey(csOriginal.behaviorSections, :cruising)
|
||||
cruisingSection=BehaviorSection(csOriginal.behaviorSections[:cruising])
|
||||
merge!(csModified.behaviorSections, Dict(:cruising=>cruisingSection))
|
||||
csModified.E = csModified.E + csModified.behaviorSections[:cruising].E
|
||||
csModified.t = csModified.t + csModified.behaviorSections[:cruising].t
|
||||
end
|
||||
|
||||
if haskey(csOriginal.behaviorSections, "clearing") # this section is needed before acceleration if the train wants to accelerate to a speed higher than the limit in a previous CS where parts of the train are still located
|
||||
clearingSection=BehaviorSection(get(csOriginal.behaviorSections, "clearing", BehaviorSection()))
|
||||
merge!(csModified.behaviorSections, Dict("clearing"=>clearingSection))
|
||||
csModified.E=csModified.E+get(csModified.behaviorSections, "clearing", BehaviorSection()).E
|
||||
csModified.t=csModified.t+get(csModified.behaviorSections, "clearing", BehaviorSection()).t
|
||||
end
|
||||
if haskey(csOriginal.behaviorSections, "acceleration")
|
||||
accelerationSection=BehaviorSection(get(csOriginal.behaviorSections, "acceleration", BehaviorSection()))
|
||||
merge!(csModified.behaviorSections, Dict("acceleration"=>accelerationSection))
|
||||
csModified.E=csModified.E+get(csModified.behaviorSections, "acceleration", BehaviorSection()).E
|
||||
csModified.t=csModified.t+get(csModified.behaviorSections, "acceleration", BehaviorSection()).t
|
||||
end
|
||||
|
||||
if haskey(csOriginal.behaviorSections, "cruising")
|
||||
cruisingSection=BehaviorSection(get(csOriginal.behaviorSections, "cruising", BehaviorSection()))
|
||||
merge!(csModified.behaviorSections, Dict("cruising"=>cruisingSection))
|
||||
csModified.E=csModified.E+get(csModified.behaviorSections, "cruising", BehaviorSection()).E
|
||||
csModified.t=csModified.t+get(csModified.behaviorSections, "cruising", BehaviorSection()).t
|
||||
end
|
||||
|
||||
diminishingSection=BehaviorSection(get(csOriginal.behaviorSections, "diminishing", BehaviorSection()))
|
||||
diminishingSection=BehaviorSection(csOriginal.behaviorSections[:diminishing])
|
||||
if length(diminishingSection.dataPoints) > 2
|
||||
# remove the last diminishing waypoint
|
||||
pop!(diminishingSection.dataPoints)
|
||||
|
@ -251,14 +247,14 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
|
|||
diminishingSection.t=drivingCourse[diminishingSection.dataPoints[end]].t-drivingCourse[diminishingSection.dataPoints[1]].t # total running time (in s)
|
||||
diminishingSection.E=drivingCourse[diminishingSection.dataPoints[end]].E-drivingCourse[diminishingSection.dataPoints[1]].E # total energy consumption (in Ws)
|
||||
|
||||
merge!(csModified.behaviorSections, Dict("diminishing"=>diminishingSection))
|
||||
csModified.E=csModified.E+get(csModified.behaviorSections, "diminishing", BehaviorSection()).E
|
||||
csModified.t=csModified.t+get(csModified.behaviorSections, "diminishing", BehaviorSection()).t
|
||||
merge!(csModified.behaviorSections, Dict(:diminishing => diminishingSection))
|
||||
csModified.E = csModified.E + csModified.behaviorSections[:diminishing].E
|
||||
csModified.t = csModified.t + csModified.behaviorSections[:diminishing].t
|
||||
|
||||
energySavingStartId=diminishingSection.dataPoints[end]
|
||||
else
|
||||
# The diminishing section is only one step. This step is removed and if there is a clearing section it will be combined with the new cruising section.
|
||||
energySavingStartId=get(csOriginal.behaviorSections, "clearing", get(csOriginal.behaviorSections, "diminishing", BehaviorSection())).dataPoints[1]
|
||||
energySavingStartId=get(csOriginal.behaviorSections, :clearing, get(csOriginal.behaviorSections, :diminishing, BehaviorSection())).dataPoints[1]
|
||||
end
|
||||
|
||||
# copy the driving course till the beginning of energy saving
|
||||
|
@ -297,131 +293,34 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
|
|||
end
|
||||
end # function increaseCoastingSection
|
||||
|
||||
#= 12/03 old without diminishing: function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Settings, train::Train, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||
if haskey(csOriginal.behaviorSections, "cruising") && haskey(csOriginal.behaviorSections, "braking")
|
||||
cruisingReduction=settings.stepSize
|
||||
while cruisingReduction>=settings.stepSize/10^approximationLevel
|
||||
#while cruisingReduction>=settings.stepSize/100
|
||||
while cruisingReduction>=settings.stepSize/10^approximationLevel # will be done once and then depending on approximationLevel repeated with smaller cruisingReduction unless !(drivingCourseModified[end].v<=csModified.v_exit && drivingCourseModified[end].s<csModified.s_exit) -> see below at the end of the while loop
|
||||
|
||||
# create a copy for the characteristic sections drivingCourse
|
||||
energySavingStartId=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).dataPoints[1]
|
||||
if energySavingStartId==0
|
||||
error("ERROR at creating a new driving course for energy saving with coasting !")
|
||||
end
|
||||
|
||||
drivingCourseModified=[DataPoint(drivingCourse[1])]
|
||||
# TODO: tried to insert copy on 15.07.2021 drivingCourseModified=[copy(drivingCourse[1])]
|
||||
for i in 2:energySavingStartId
|
||||
push!(drivingCourseModified, DataPoint(drivingCourse[i])) # List of data points till the start of energy saving
|
||||
# TODO: tried to insert copy on 15.07.2021 push!(drivingCourseModified, copy(drivingCourse[i])) # List of data points till the start of energy saving
|
||||
|
||||
end
|
||||
|
||||
# calculating the new length of the cruising section
|
||||
if settings.stepVariable=="s in m" # distance step method
|
||||
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).length-cruisingReduction
|
||||
elseif settings.stepVariable=="t in s" # time step method
|
||||
# 09/20 old: doesn't work for non constant cruising
|
||||
# t_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).t-cruisingReduction
|
||||
# s_cruising=t_cruising*drivingCourseModified[end].v
|
||||
wayReduction=drivingCourse(get(csOriginal.behaviorSections, "cruising", BehaviorSection()).dataPoints[end]).v*cruisingReduction
|
||||
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).length-wayReduction
|
||||
|
||||
elseif settings.stepVariable=="v in m/s" # velocity step method
|
||||
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).length-cruisingReduction*10 # TODO: or better: *100 ?
|
||||
end #if
|
||||
s_cruising=max(0.0, s_cruising)
|
||||
|
||||
# copy csOriginal to csModified
|
||||
csModified=CharacteristicSection(csOriginal.id, csOriginal.length, csOriginal.s_entry, csOriginal.s_exit, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_target, csOriginal.v_entry, csOriginal.v_exit, csOriginal.f_Rp, Dict{String, BehaviorSection}())
|
||||
if haskey(csOriginal.behaviorSections, "breakFree")
|
||||
breakFreeSection=BehaviorSection(get(csOriginal.behaviorSections, "breakFree", BehaviorSection()))
|
||||
merge!(csModified.behaviorSections, Dict("breakFree"=>breakFreeSection))
|
||||
csModified.E=csModified.E+get(csModified.behaviorSections, "breakFree", BehaviorSection()).E
|
||||
csModified.t=csModified.t+get(csModified.behaviorSections, "breakFree", BehaviorSection()).t
|
||||
end
|
||||
if haskey(csOriginal.behaviorSections, "clearing") # this section is needed before acceleration if the train wants to accelerate to a speed higher than the limit in a previous CS where parts of the train are still located
|
||||
clearingSection=BehaviorSection(get(csOriginal.behaviorSections, "clearing", BehaviorSection()))
|
||||
merge!(csModified.behaviorSections, Dict("clearing"=>clearingSection))
|
||||
csModified.E=csModified.E+get(csModified.behaviorSections, "clearing", BehaviorSection()).E
|
||||
csModified.t=csModified.t+get(csModified.behaviorSections, "clearing", BehaviorSection()).t
|
||||
end
|
||||
if haskey(csOriginal.behaviorSections, "acceleration")
|
||||
accelerationSection=BehaviorSection(get(csOriginal.behaviorSections, "acceleration", BehaviorSection()))
|
||||
merge!(csModified.behaviorSections, Dict("acceleration"=>accelerationSection))
|
||||
csModified.E=csModified.E+get(csModified.behaviorSections, "acceleration", BehaviorSection()).E
|
||||
csModified.t=csModified.t+get(csModified.behaviorSections, "acceleration", BehaviorSection()).t
|
||||
end
|
||||
|
||||
# calculate the new and now shorter cruising section
|
||||
if s_cruising>0.0
|
||||
(csModified, drivingCourseModified)=addCruisingPhase!(csModified, drivingCourseModified, s_cruising, settings, train, allCSs, "cruising")
|
||||
end
|
||||
|
||||
(csModified, drivingCourseModified)=addCoastingPhaseUntilBraking!(csModified, drivingCourseModified, settings, train, allCSs)
|
||||
|
||||
if drivingCourseModified[end].v < csModified.v_exit || drivingCourseModified[end].s > csModified.s_exit
|
||||
# the train reaches v_exit before reaching s_exit. The cruising and coasting sections have to be calculated again with a larger cruising section (so with a smaller reduction of the cruising section)
|
||||
cruisingReduction=cruisingReduction/10
|
||||
else
|
||||
break
|
||||
end
|
||||
end # while cruisingReduction
|
||||
|
||||
if drivingCourseModified[end].v > csModified.v_exit
|
||||
#(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings.massModel, train, allCSs)
|
||||
(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings, train, allCSs)
|
||||
elseif drivingCourseModified[end].v == csModified.v_exit && drivingCourseModified[end].s < csModified.s_exit
|
||||
# v_exit is already reached. Now cruise till the end of the CS
|
||||
s_cruisingAfterCoasting=csModified.s_exit-drivingCourseModified[end].s
|
||||
(csModified, drivingCourseModified)=addCruisingPhase!(csModified, drivingCourseModified, s_cruisingAfterCoasting, settings, train, allCSs, "cruisingAfterCoasting")
|
||||
end
|
||||
|
||||
if t_recoveryAvailable < csModified.t-csOriginal.t || drivingCourseModified[end].v != csModified.v_exit || drivingCourseModified[end].s != csModified.s_exit # time loss is to high and the CS has to be calculated again with larger cruising section (so with a smaller reduction of the cruising section) or v_exit or s_exit are not reached excatly
|
||||
cruisingReduction=cruisingReduction/10
|
||||
else
|
||||
return (csModified, drivingCourseModified, true)
|
||||
end
|
||||
end #while
|
||||
# there is no energy saving modification for this CS with the available recovery time
|
||||
return (CharacteristicSection(), [], false)
|
||||
else
|
||||
# there is no energy saving modification for this CS because a cruising section AND a braking section are needed to be transformed into a coasting section
|
||||
return (CharacteristicSection(), [], false)
|
||||
end
|
||||
end # function increaseCoastingSection
|
||||
|
||||
=#
|
||||
|
||||
# method 2 with shortening the acceleration by stepsize
|
||||
function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse, settings::Settings, train::Train, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||
#function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Settings, train::Train, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||
if haskey(csOriginal.behaviorSections, "acceleration") && csOriginal.v_target > csOriginal.v_entry && csOriginal.v_target > csOriginal.v_exit
|
||||
accelerationSection=BehaviorSection(get(csOriginal.behaviorSections, "acceleration", BehaviorSection()))
|
||||
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)
|
||||
if haskey(csOriginal.behaviorSections, :acceleration) && csOriginal.v_target > csOriginal.v_entry && csOriginal.v_target > csOriginal.v_exit
|
||||
accelerationSection = BehaviorSection(csOriginal.behaviorSections[:acceleration])
|
||||
if drivingCourse[accelerationSection.dataPoints[end]-1].v < csOriginal.v_exit
|
||||
return (CharacteristicSection(), [], false)
|
||||
# TODO: or calculate a new acceleration phase with v_exit as v_target? it will be very short, shorter than the step size.
|
||||
end
|
||||
|
||||
# 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{String, BehaviorSection}())
|
||||
csModified=CharacteristicSection(csOriginal.id, csOriginal.length, csOriginal.s_entry, csOriginal.s_exit, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_target, csOriginal.v_entry, csOriginal.v_exit, csOriginal.f_Rp, Dict{Symbol, BehaviorSection}())
|
||||
|
||||
if haskey(csOriginal.behaviorSections, "breakFree")
|
||||
breakFreeSection=BehaviorSection(get(csOriginal.behaviorSections, "breakFree", BehaviorSection()))
|
||||
merge!(csModified.behaviorSections, Dict("breakFree"=>breakFreeSection))
|
||||
csModified.E=csModified.E+get(csModified.behaviorSections, "breakFree", BehaviorSection()).E
|
||||
csModified.t=csModified.t+get(csModified.behaviorSections, "breakFree", BehaviorSection()).t
|
||||
if haskey(csOriginal.behaviorSections, :breakFree)
|
||||
breakFreeSection=BehaviorSection(csOriginal.behaviorSections[:breakFree])
|
||||
merge!(csModified.behaviorSections, Dict(:breakFree=>breakFreeSection))
|
||||
csModified.E = csModified.E + csModified.behaviorSections[:breakFree].E
|
||||
csModified.t = csModified.t + csModified.behaviorSections[:breakFree].t
|
||||
end
|
||||
|
||||
#accelerationSection=BehaviorSection(get(csOriginal.behaviorSections, "acceleration", BehaviorSection()))
|
||||
#accelerationSection = BehaviorSection(get(csOriginal.behaviorSections, :acceleration, BehaviorSection()))
|
||||
|
||||
if length(accelerationSection.dataPoints) > 2
|
||||
if haskey(csOriginal.behaviorSections, "clearing")
|
||||
clearingSection=BehaviorSection(get(csOriginal.behaviorSections, "clearing", BehaviorSection()))
|
||||
merge!(csModified.behaviorSections, Dict("clearing"=>clearingSection))
|
||||
csModified.E=csModified.E+get(csModified.behaviorSections, "clearing", BehaviorSection()).E
|
||||
csModified.t=csModified.t+get(csModified.behaviorSections, "clearing", BehaviorSection()).t
|
||||
if haskey(csOriginal.behaviorSections, :clearing)
|
||||
clearingSection=BehaviorSection(csOriginal.behaviorSections[:clearing])
|
||||
merge!(csModified.behaviorSections, Dict(:clearing=>clearingSection))
|
||||
csModified.E = csModified.E + csModified.behaviorSections[:clearing].E
|
||||
csModified.t = csModified.t + csModified.behaviorSections[:clearing].t
|
||||
end
|
||||
|
||||
# remove the last acceleration waypoint
|
||||
|
@ -433,14 +332,14 @@ function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCours
|
|||
accelerationSection.t=drivingCourse[accelerationSection.dataPoints[end]].t-drivingCourse[accelerationSection.dataPoints[1]].t # total running time (in s)
|
||||
accelerationSection.E=drivingCourse[accelerationSection.dataPoints[end]].E-drivingCourse[accelerationSection.dataPoints[1]].E # total energy consumption (in Ws)
|
||||
|
||||
merge!(csModified.behaviorSections, Dict("acceleration"=>accelerationSection))
|
||||
csModified.E=csModified.E+get(csModified.behaviorSections, "acceleration", BehaviorSection()).E
|
||||
csModified.t=csModified.t+get(csModified.behaviorSections, "acceleration", BehaviorSection()).t
|
||||
merge!(csModified.behaviorSections, Dict(:acceleration=>accelerationSection))
|
||||
csModified.E = csModified.E + csModified.behaviorSections[:acceleration].E
|
||||
csModified.t = csModified.t + csModified.behaviorSections[:acceleration].t
|
||||
|
||||
energySavingStartId=accelerationSection.dataPoints[end]
|
||||
else
|
||||
# The acceleration section is only one step. This step is removed and if there is a clearing section it will be combined with the new cruising section.
|
||||
energySavingStartId=get(csOriginal.behaviorSections, "clearing", get(csOriginal.behaviorSections, "acceleration", BehaviorSection())).dataPoints[1]
|
||||
energySavingStartId=get(csOriginal.behaviorSections, :clearing, get(csOriginal.behaviorSections, :acceleration, BehaviorSection())).dataPoints[1]
|
||||
end
|
||||
|
||||
# TODO: should v_target be reduced or is it enough to pop the data points?
|
||||
|
@ -452,17 +351,17 @@ function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCours
|
|||
push!(drivingCourseModified, DataPoint(drivingCourse[i])) # List of data points till the start of energy saving
|
||||
end
|
||||
|
||||
#s_braking=max(0.0, ceil((csModified.v_exit^2-csModified.v_target^2)/2/train.a_braking, digits=approximationLevel)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
|
||||
s_braking=max(0.0, ceil((csModified.v_exit^2-drivingCourseModified[end].v^2)/2/train.a_braking, digits=approximationLevel)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
|
||||
#s_braking=max(0.0, ceil((csModified.v_exit^2-csModified.v_target^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
|
||||
s_braking=max(0.0, ceil((csModified.v_exit^2-drivingCourseModified[end].v^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
|
||||
s_cruising=csModified.s_exit-drivingCourseModified[end].s-s_braking
|
||||
|
||||
if s_cruising >0.001
|
||||
(csModified, drivingCourseModified)=addCruisingPhase!(csModified, drivingCourseModified, s_cruising, settings, train, allCSs, "cruising")
|
||||
end #if
|
||||
|
||||
# s_brakingAfterCruising=ceil((csModified.v_exit^2-drivingCourseModified[end].v^2)/2/train.a_braking, digits=10) # TODO: check if s_braking and s_brakingAfterCruising are really always the same
|
||||
# s_brakingAfterCruising=ceil((csModified.v_exit^2-drivingCourseModified[end].v^2)/2/train[:a_braking], digits=10) # TODO: check if s_braking and s_brakingAfterCruising are really always the same
|
||||
if drivingCourseModified[end].v>csModified.v_exit
|
||||
#(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings.massModel, train, allCSs)
|
||||
#(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings[:massModel], train, allCSs)
|
||||
(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings, train, allCSs)
|
||||
elseif drivingCourseModified[end].s<csModified.s_exit
|
||||
if (csModified.s_exit-drivingCourseModified[end].s)>0.001
|
||||
|
@ -500,9 +399,9 @@ function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCours
|
|||
end # function decreaseMaximumVelocity
|
||||
|
||||
# combination of method 1 and method 2
|
||||
function combineEnergySavingMethods(csOriginal::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Settings, train::Train, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||
# if haskey(csOriginal.behaviorSections, "acceleration") && (haskey(csOriginal.behaviorSections, "braking") || haskey(csOriginal.behaviorSections, "coasting")) && csOriginal.v_target>csOriginal.v_entry && csOriginal.v_target>csOriginal.v_exit
|
||||
if haskey(csOriginal.behaviorSections, "acceleration") && (haskey(csOriginal.behaviorSections, "braking") || haskey(csOriginal.behaviorSections, "coasting")) && drivingCourse[get(csOriginal.behaviorSections, "acceleration", BehaviorSection()).dataPoints[end]].v > max(csOriginal.v_entry, csOriginal.v_exit)
|
||||
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)) && drivingCourse[get(csOriginal.behaviorSections, :acceleration, BehaviorSection()).dataPoints[end]].v > max(csOriginal.v_entry, csOriginal.v_exit)
|
||||
csCombined=CharacteristicSection(csOriginal)
|
||||
drivingCourseCombined=Vector{DataPoint}()
|
||||
for i in 1:length(drivingCourse)
|
||||
|
@ -518,7 +417,7 @@ function combineEnergySavingMethods(csOriginal::CharacteristicSection, drivingCo
|
|||
ΔE=csOriginal.E-csCombined.E # saved energy (in Ws)
|
||||
Δt=csCombined.t-csOriginal.t # time loss (in s)
|
||||
|
||||
while (haskey(csOriginal.behaviorSections, "cruising") && (Δt<=0.0 || ΔE<=0.0)) #Δt<=0.0) #&& ΔE<=0.0) # && Δt<=0.0)
|
||||
while (haskey(csOriginal.behaviorSections, :cruising) && (Δt<=0.0 || ΔE<=0.0)) #Δt<=0.0) #&& ΔE<=0.0) # && Δt<=0.0)
|
||||
(csCombined, drivingCourseCombined, newCoasting)=increaseCoastingSection(csCombined, drivingCourseCombined, settings, train, allCSs, t_recoveryAvailable-Δt)
|
||||
if newCoasting
|
||||
ΔE=csOriginal.E-csCombined.E # saved energy (in Ws)
|
||||
|
|
318
src/Input.jl
318
src/Input.jl
|
@ -6,7 +6,7 @@ using ..types
|
|||
export readInput
|
||||
|
||||
"""
|
||||
Read the input information from YAML files for train, path and settings, save it in different objects and return them.
|
||||
Read the input information from YAML files for train, path and settings, save it in different dictionaries and return them.
|
||||
"""
|
||||
function readInput(trainDirectory::String, pathDirectory::String, settingsDirectory::String)
|
||||
train=inputTrain(trainDirectory)
|
||||
|
@ -17,25 +17,25 @@ function readInput(trainDirectory::String, pathDirectory::String, settingsDirect
|
|||
end #function readInput
|
||||
|
||||
"""
|
||||
Read the train information from a YAML file, save it in a Train object and return it.
|
||||
Read the train information from a YAML file, save it in a train Dict and return it.
|
||||
"""
|
||||
function inputTrain(trainDirectory::String)
|
||||
data = YAML.load(open(trainDirectory))
|
||||
collect(keys(data))
|
||||
collect(values(data))
|
||||
|
||||
train=Train()
|
||||
if haskey(data["train"],"name")
|
||||
train.name=data["train"]["name"] # trains name
|
||||
name=data["train"]["name"] # trains name
|
||||
delete!(data["train"], "name")
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The keyword name is missing. It has to be added.")
|
||||
end
|
||||
train.id=1 # trains identifier
|
||||
|
||||
id=1 # trains identifier
|
||||
|
||||
if haskey(data["train"],"trainType")
|
||||
if typeof(data["train"]["trainType"])==String && (data["train"]["trainType"]=="freight" || data["train"]["trainType"]=="motor coach train" || data["train"]["trainType"]=="passenger")
|
||||
train.trainType=data["train"]["trainType"] # "passenger" or "freight" or "motor coach train"
|
||||
trainType=data["train"]["trainType"] # "passenger" or "freight" or "motor coach train"
|
||||
delete!(data["train"], "trainType")
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of trainType is wrong. It has to be freight, motor coach train or passenger.")
|
||||
|
@ -46,7 +46,7 @@ function inputTrain(trainDirectory::String)
|
|||
|
||||
if haskey(data["train"],"l_train")
|
||||
if typeof(data["train"]["l_train"]) <: Real && data["train"]["l_train"]>0.0
|
||||
train.l_train=data["train"]["l_train"] # total length (in m)
|
||||
l_train=data["train"]["l_train"] # total length (in m)
|
||||
delete!(data["train"], "l_train")
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of the length is no real number >0.0.")
|
||||
|
@ -78,34 +78,34 @@ function inputTrain(trainDirectory::String)
|
|||
end
|
||||
|
||||
if v_limit_temp > 0.0 && v_limit_kmh_temp > 0.0
|
||||
train.v_limit=v_limit_temp
|
||||
v_limit=v_limit_temp
|
||||
difference=abs(v_limit_temp-v_limit_kmh_temp/3.6)
|
||||
if difference >0.0
|
||||
println("WARNING at reading the train yaml file: The values of v_limit and v_limit_kmh differ by ",difference," m/s. The value v_limit=",train.v_limit," m/s is used." )
|
||||
println("WARNING at reading the train yaml file: The values of v_limit and v_limit_kmh differ by ",difference," m/s. The value v_limit=",v_limit," m/s is used." )
|
||||
end
|
||||
elseif v_limit_temp > 0.0
|
||||
train.v_limit=v_limit_temp
|
||||
v_limit=v_limit_temp
|
||||
elseif v_limit_kmh_temp > 0.0
|
||||
train.v_limit=v_limit_kmh_temp/3.6
|
||||
v_limit=v_limit_kmh_temp/3.6
|
||||
else
|
||||
train.v_limit=1000/3.6
|
||||
println("WARNING at reading the train yaml file: There is no value for the trains speed limit (v_limit or v_limit_kmh). The value v_limit=1000 km/h =",train.v_limit," m/s is used." )
|
||||
v_limit=1000/3.6
|
||||
println("WARNING at reading the train yaml file: There is no value for the trains speed limit (v_limit or v_limit_kmh). The value v_limit=1000 km/h =",v_limit," m/s is used." )
|
||||
end
|
||||
|
||||
|
||||
# a_braking
|
||||
if haskey(data["train"],"a_braking")
|
||||
if typeof(data["train"]["a_braking"]) <: Real
|
||||
train.a_braking=data["train"]["a_braking"]
|
||||
a_braking=data["train"]["a_braking"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of the a_braking is no real floating point number <0.0.")
|
||||
end
|
||||
delete!(data["train"], "a_braking")
|
||||
|
||||
if train.a_braking > 0.0
|
||||
train.a_braking =-train.a_braking
|
||||
println("WARNING at reading the train yaml file: The value for a_braking is >0.0. The braking acceleration has to be <0.0. Therefore a_braking =",train.a_braking," m/s^2 is used." )
|
||||
elseif train.a_braking == 0.0
|
||||
if a_braking > 0.0
|
||||
a_braking =-a_braking
|
||||
println("WARNING at reading the train yaml file: The value for a_braking is >0.0. The braking acceleration has to be <0.0. Therefore a_braking =",a_braking," m/s^2 is used." )
|
||||
elseif a_braking == 0.0
|
||||
error("ERROR at reading the train yaml file: The value for a_braking is 0.0. The braking acceleration has to be <0.0.")
|
||||
end
|
||||
else
|
||||
|
@ -115,7 +115,7 @@ function inputTrain(trainDirectory::String)
|
|||
# mass on the traction units driving axles (in kg)
|
||||
if haskey(data["train"],"m_td")
|
||||
if typeof(data["train"]["m_td"]) <: Real && data["train"]["m_td"]>0.0
|
||||
train.m_td=data["train"]["m_td"]
|
||||
m_td=data["train"]["m_td"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of m_td is no real floating point number >0.0.")
|
||||
end
|
||||
|
@ -128,7 +128,7 @@ function inputTrain(trainDirectory::String)
|
|||
# mass on the traction units carrying axles (in kg)
|
||||
if haskey(data["train"],"m_tc")
|
||||
if typeof(data["train"]["m_tc"]) <: Real && data["train"]["m_tc"]>=0.0
|
||||
train.m_tc=data["train"]["m_tc"]
|
||||
m_tc=data["train"]["m_tc"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of m_tc is no real floating point number >=0.0.")
|
||||
end
|
||||
|
@ -138,47 +138,49 @@ function inputTrain(trainDirectory::String)
|
|||
delete!(data["train"], "m_tc")
|
||||
|
||||
# mass of the traction unit (in kg)
|
||||
train.m_t=train.m_td+train.m_tc
|
||||
m_t=m_td+m_tc
|
||||
|
||||
|
||||
# mass of the consist (set of wagons) (in kg)
|
||||
if haskey(data["train"],"m_w")
|
||||
if typeof(data["train"]["m_w"]) <: Real && data["train"]["m_w"]>=0.0
|
||||
train.m_w=data["train"]["m_w"]
|
||||
m_w=data["train"]["m_w"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of m_w is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
train.m_w=0.0
|
||||
println("WARNING at reading the train yaml file: The keyword m_w is missing. Therefore m_w =",train.m_w," kg is used.")
|
||||
m_w=0.0
|
||||
println("WARNING at reading the train yaml file: The keyword m_w is missing. Therefore m_w =",m_w," kg is used.")
|
||||
end
|
||||
delete!(data["train"], "m_w")
|
||||
|
||||
# total mass (in kg)
|
||||
train.m_train=train.m_t+train.m_w
|
||||
m_train=m_t+m_w
|
||||
|
||||
if haskey(data["train"],"rotationMassFactor_train") && typeof(data["train"]["rotationMassFactor_train"]) <: Real
|
||||
if data["train"]["rotationMassFactor_train"]>0.0
|
||||
train.ξ_train=data["train"]["rotationMassFactor_train"]
|
||||
ξ_train=data["train"]["rotationMassFactor_train"]
|
||||
ξ_t=0.0
|
||||
ξ_w=0.0
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of rotationMassFactor_train is no real floating point number >0.0.")
|
||||
end
|
||||
elseif haskey(data["train"],"rotationMassFactor_t") && typeof(data["train"]["rotationMassFactor_t"]) <: Real && (train.m_w==0.0 || (haskey(data["train"],"rotationMassFactor_w") && typeof(data["train"]["rotationMassFactor_w"]) <: Real))
|
||||
elseif haskey(data["train"],"rotationMassFactor_t") && typeof(data["train"]["rotationMassFactor_t"]) <: Real && (m_w==0.0 || (haskey(data["train"],"rotationMassFactor_w") && typeof(data["train"]["rotationMassFactor_w"]) <: Real))
|
||||
if data["train"]["rotationMassFactor_t"]>0.0
|
||||
train.ξ_t=data["train"]["rotationMassFactor_t"]
|
||||
ξ_t=data["train"]["rotationMassFactor_t"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of rotationMassFactor_t is no real floating point number >0.0.")
|
||||
end
|
||||
if train.m_w>0.0
|
||||
if m_w>0.0
|
||||
if data["train"]["rotationMassFactor_w"]>=0.0
|
||||
train.ξ_w=data["train"]["rotationMassFactor_w"]
|
||||
ξ_w=data["train"]["rotationMassFactor_w"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of rotationMassFactor_w is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
train.ξ_w=0.0
|
||||
ξ_w=0.0
|
||||
end
|
||||
train.ξ_train=(train.ξ_t*train.m_t + train.ξ_w*train.m_w)/train.m_train # rotation mass factor of the whole train (without unit)
|
||||
ξ_train=(ξ_t*m_t + ξ_w*m_w)/m_train # rotation mass factor of the whole train (without unit)
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The keywords rotationMassFactor_train or rotationMassFactor_t and rotationMassFactor_w are missing. They has to be added with a value of type real floating point number.")
|
||||
end
|
||||
|
@ -191,70 +193,7 @@ function inputTrain(trainDirectory::String)
|
|||
if haskey(data["train"],"F_T_pairs") && data["train"]["F_T_pairs"]!=nothing
|
||||
F_T_pairs=data["train"]["F_T_pairs"]
|
||||
|
||||
train.tractiveEffortVelocityPairs=checkAndDefineTractiveEffortInput(F_T_pairs, 1.0)
|
||||
|
||||
#= old 2021-11-04: now it is pairs and no scope
|
||||
# check if the elements of the array have the correct type
|
||||
errorDetected=false
|
||||
for row in 1:length(F_T_pairs)
|
||||
if typeof(F_T_pairs[row][1]) <: Real && F_T_pairs[row][1]>=0.0
|
||||
else
|
||||
errorDetected=true
|
||||
println("ERROR at reading the train yaml file: The speed value of F_T_pairs in row ", row ," is no real floating point number >=0.0.")
|
||||
end
|
||||
if typeof(F_T_pairs[row][2]) <: Real && F_T_pairs[row][2]>=0.0
|
||||
else
|
||||
errorDetected=true
|
||||
println("ERROR at reading the train yaml file: The tractive effort value of F_T_pairs in row ", row ," is no real floating point number >=0.0.")
|
||||
end
|
||||
|
||||
if row>=2 && F_T_pairs[row][1] <= F_T_pairs[row-1][1]
|
||||
errorDetected=true
|
||||
println("ERROR at reading the train yaml file: The speed value of F_T_pairs in row ", row ," (v=",F_T_pairs[row][1]," m/s) is not higher than the speed value in the previous row (v=",F_T_pairs[row-1][1]," m/s).")
|
||||
end
|
||||
end # for
|
||||
if errorDetected
|
||||
error("ERROR at reading the train yaml file: Only real floating point number >=0.0 are allowed for speed and tractive effort. The speed values have to be listed from low to high.")
|
||||
end
|
||||
|
||||
# create tractiveEffortVelocityPairs
|
||||
if F_T_pairs[1][1]>0.0 # if there is no F_T for v=0.0, the first known value is used
|
||||
push!(train.tractiveEffortVelocityPairs, [0.0, F_T_pairs[1][2]])
|
||||
println("WARNING at reading the train yaml file: The tractive effort for v=0 m/s is missing. Therefore the first given value F_T(v=",F_T_pairs[1][1]," m/s)=",F_T_pairs[1][2]," N will be used." )
|
||||
end
|
||||
|
||||
for row in 1:length(F_T_pairs)
|
||||
push!(train.tractiveEffortVelocityPairs, [F_T_pairs[row][1]], F_T_pairs[row][2]])
|
||||
end # for
|
||||
|
||||
|
||||
# create tractiveEffortArray
|
||||
train.tractiveEffortArray=[]
|
||||
if F_T_pairs[1][1]==0.0
|
||||
push!(train.tractiveEffortArray, [F_T_pairs[1][1], F_T_pairs[1][1], F_T_pairs[1][2]])
|
||||
elseif F_T_pairs[1][1]>0.0 # if there is no F_T for v=0.0, the first value is used
|
||||
push!(train.tractiveEffortArray, [0.0, F_T_pairs[1][1], F_T_pairs[1][2]])
|
||||
println("WARNING at reading the train yaml file: The tractive effort for v=0 m/s is missing. Therefore the first given value F_T(v=",F_T_pairs[1][1]," m/s)=",F_T_pairs[1][2]," N will be used." )
|
||||
else
|
||||
error("ERROR at reading the train yaml file: There is a negative speed value in the list. Only positive values for speed and tractive effort are allowed in F_T_pairs.")
|
||||
end
|
||||
|
||||
for row in 2:length(F_T_pairs)
|
||||
if F_T_pairs[row][1]>F_T_pairs[row-1][1]
|
||||
if F_T_pairs[row][2]==train.tractiveEffortArray[end][3]
|
||||
train.tractiveEffortArray[end][2]=F_T_pairs[row][1]
|
||||
else
|
||||
push!(train.tractiveEffortArray, [F_T_pairs[row][1], F_T_pairs[row][1], F_T_pairs[row][2]])
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The F_T_pairs are not in the correct order. They have to be arranged by speed values from low to high.")
|
||||
end
|
||||
end # for
|
||||
|
||||
if length(F_T_pairs[1])>2
|
||||
println("INFO according the train yaml file: Only the first two columns of F_T_pairs are used in this tool.")
|
||||
end
|
||||
=#
|
||||
tractiveEffortVelocityPairs=checkAndDefineTractiveEffortInput(F_T_pairs, 1.0)
|
||||
|
||||
if haskey(data["train"],"F_T_pairs_kmh") && data["train"]["F_T_pairs_kmh"]!=nothing
|
||||
println("WARNING at reading the train yaml file: There are values for F_T_pairs and F_T_pairs_kmh. The values for F_T_pairs are used." )
|
||||
|
@ -263,50 +202,7 @@ function inputTrain(trainDirectory::String)
|
|||
elseif haskey(data["train"],"F_T_pairs_kmh") && data["train"]["F_T_pairs_kmh"]!=nothing
|
||||
F_T_pairs_kmh=data["train"]["F_T_pairs_kmh"]
|
||||
|
||||
train.tractiveEffortVelocityPairs=checkAndDefineTractiveEffortInput(F_T_pairs_kmh, 1000/3600)
|
||||
|
||||
#= old 2021-11-04: now it is pairs and no scope
|
||||
# check if the elements of the array have the correct type
|
||||
errorDetected=false
|
||||
for row in 1:length(F_T_pairs_kmh)
|
||||
if typeof(F_T_pairs_kmh[row][1]) <: Real && F_T_pairs_kmh[row][1]>=0.0
|
||||
else
|
||||
errorDetected=true
|
||||
println("ERROR at reading the train yaml file: The speed value of F_T_pairs_kmh in row ", row ," is no real floating point number >=0.0.")
|
||||
end
|
||||
if typeof(F_T_pairs_kmh[row][2]) <: Real && F_T_pairs_kmh[row][2]>=0.0
|
||||
else
|
||||
errorDetected=true
|
||||
println("ERROR at reading the train yaml file: The tractive effort value of F_T_pairs_kmh in row ", row ," is no real floating point number >=0.0.")
|
||||
end
|
||||
end # for
|
||||
if errorDetected
|
||||
error("ERROR at reading the train yaml file: Only real floating point number >=0.0 are allowed for speed and tractive effort in F_T_pairs_kmh.")
|
||||
end
|
||||
|
||||
# create tractiveEffortArray
|
||||
train.tractiveEffortArray=[]
|
||||
if F_T_pairs_kmh[1][1]==0.0
|
||||
push!(train.tractiveEffortArray, [F_T_pairs_kmh[1][1]/3.6, F_T_pairs_kmh[1][1]/3.6, F_T_pairs_kmh[1][2]])
|
||||
elseif F_T_pairs_kmh[1][1]>0.0 # if there is no F_T for v=0.0, the first value is used
|
||||
push!(train.tractiveEffortArray, [0.0, F_T_pairs_kmh[1][1]/3.6, F_T_pairs_kmh[1][2]])
|
||||
println("WARNING at reading the train yaml file: The tractive effort for v=0 km/h is missing. Therefore the first given value F_T(v=",F_T_pairs_kmh[1][1]," km/h)=",F_T_pairs_kmh[1][2]," N will be used." )
|
||||
end
|
||||
for row in 2:length(F_T_pairs_kmh)
|
||||
if F_T_pairs_kmh[row][1]>F_T_pairs_kmh[row-1][1]
|
||||
if F_T_pairs_kmh[row][2]==train.tractiveEffortArray[end][3]
|
||||
train.tractiveEffortArray[end][2]=F_T_pairs_kmh[row][1]/3.6
|
||||
else
|
||||
push!(train.tractiveEffortArray, [F_T_pairs_kmh[row][1]/3.6, F_T_pairs_kmh[row][1]/3.6, F_T_pairs_kmh[row][2]])
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The F_T_pairs_kmh are not in the correct order. They have to be arranged by speed values from low to high.")
|
||||
end
|
||||
end # for
|
||||
if length(F_T_pairs_kmh[1])>2
|
||||
println("INFO at reading the train yaml file: Only the first two columns of F_T_pairs_kmh are used in this tool.")
|
||||
end
|
||||
=#
|
||||
tractiveEffortVelocityPairs=checkAndDefineTractiveEffortInput(F_T_pairs_kmh, 1000/3600)
|
||||
else
|
||||
error("ERROR at reading the train yaml file: There has to be one of the keywords F_T_pairs or F_T_pairs_kmh filled with a list of pairs of velocity and tractive effort.")
|
||||
end # if
|
||||
|
@ -317,17 +213,17 @@ function inputTrain(trainDirectory::String)
|
|||
# coefficients for the vehicle resistance of the traction unit
|
||||
|
||||
# coefficient for velocitiy difference between traction unit and outdoor air
|
||||
train.Δv_t=15.0/3.6
|
||||
Δv_t=15.0/3.6
|
||||
|
||||
# coefficient for basic resistance due to the traction units driving axles (in ‰)
|
||||
if haskey(data["train"],"f_Rtd0") && data["train"]["f_Rtd0"]!=nothing
|
||||
if typeof(data["train"]["f_Rtd0"]) <: Real && data["train"]["f_Rtd0"]>=0.0
|
||||
train.f_Rtd0=data["train"]["f_Rtd0"]
|
||||
f_Rtd0=data["train"]["f_Rtd0"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of f_Rtd0 is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
train.f_Rtd0=0.0
|
||||
f_Rtd0=0.0
|
||||
println("WARNING at reading the train yaml file: The keyword f_Rtd0 is missing. Therefore f_Rtd0=0.0 ‰ will be assumed and used." )
|
||||
end
|
||||
delete!(data["train"], "f_Rtd0")
|
||||
|
@ -335,12 +231,12 @@ function inputTrain(trainDirectory::String)
|
|||
# coefficient for basic resistance due to the traction units carring axles (in ‰)
|
||||
if haskey(data["train"],"f_Rtc0") && data["train"]["f_Rtc0"]!=nothing
|
||||
if typeof(data["train"]["f_Rtc0"]) <: Real && data["train"]["f_Rtc0"]>=0.0
|
||||
train.f_Rtc0=data["train"]["f_Rtc0"]
|
||||
f_Rtc0=data["train"]["f_Rtc0"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of f_Rtc0 is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
train.f_Rtc0=0.0
|
||||
f_Rtc0=0.0
|
||||
println("WARNING at reading the train yaml file: The keyword f_Rtc0 is missing. Therefore f_Rtc0=0.0 ‰ will be assumed and used." )
|
||||
end
|
||||
delete!(data["train"], "f_Rtc0")
|
||||
|
@ -348,12 +244,12 @@ function inputTrain(trainDirectory::String)
|
|||
# coefficient for air resistance of the traction units (in N)
|
||||
if haskey(data["train"],"F_Rt2") && data["train"]["F_Rt2"]!=nothing
|
||||
if typeof(data["train"]["F_Rt2"]) <: Real && data["train"]["F_Rt2"]>=0.0
|
||||
train.F_Rt2=data["train"]["F_Rt2"]
|
||||
F_Rt2=data["train"]["F_Rt2"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of F_Rt2 is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
train.F_Rt2=0.0
|
||||
F_Rt2=0.0
|
||||
println("WARNING at reading the train yaml file: The keyword F_Rt2 is missing. Therefore F_Rt2=0.0 N will be assumed and used." )
|
||||
end
|
||||
delete!(data["train"], "F_Rt2")
|
||||
|
@ -363,21 +259,21 @@ function inputTrain(trainDirectory::String)
|
|||
# coefficients for the vehicle resistance of the consist (set of wagons)
|
||||
|
||||
# coefficient for velocitiy difference between consist (set of wagons) and outdoor air (in m/s)
|
||||
if train.trainType=="passenger" || train.trainType=="motor coach train"
|
||||
train.Δv_w=15.0/3.6
|
||||
elseif train.trainType== "freight"
|
||||
train.Δv_w=0.0
|
||||
if trainType=="passenger" || trainType=="motor coach train"
|
||||
Δv_w=15.0/3.6
|
||||
elseif trainType== "freight"
|
||||
Δv_w=0.0
|
||||
end # if
|
||||
|
||||
# coefficient for basic resistance of the consist (set of wagons) (in ‰)
|
||||
if haskey(data["train"],"f_Rw0") && data["train"]["f_Rw0"]!=nothing
|
||||
if typeof(data["train"]["f_Rw0"]) <: Real && data["train"]["f_Rw0"]>=0.0
|
||||
train.f_Rw0=data["train"]["f_Rw0"]
|
||||
f_Rw0=data["train"]["f_Rw0"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of f_Rw0 is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
train.f_Rw0=0.0
|
||||
f_Rw0=0.0
|
||||
println("WARNING at reading the train yaml file: The keyword f_Rw0 is missing. Therefore f_Rw0=0.0 ‰ will be assumed and used." )
|
||||
end
|
||||
delete!(data["train"], "f_Rw0")
|
||||
|
@ -385,12 +281,12 @@ function inputTrain(trainDirectory::String)
|
|||
# coefficient for basic resistance of the consist (set of wagons) (in ‰)
|
||||
if haskey(data["train"],"f_Rw1") && data["train"]["f_Rw1"]!=nothing
|
||||
if typeof(data["train"]["f_Rw1"]) <: Real && data["train"]["f_Rw1"]>=0.0
|
||||
train.f_Rw1=data["train"]["f_Rw1"]
|
||||
f_Rw1=data["train"]["f_Rw1"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of f_Rw1 is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
train.f_Rw1=0.0
|
||||
f_Rw1=0.0
|
||||
println("WARNING at reading the train yaml file: The keyword f_Rw1 is missing. Therefore f_Rw1=0.0 ‰ will be assumed and used." )
|
||||
end
|
||||
delete!(data["train"], "f_Rw1")
|
||||
|
@ -398,12 +294,12 @@ function inputTrain(trainDirectory::String)
|
|||
# coefficient for basic resistance of the consist (set of wagons) (in ‰)
|
||||
if haskey(data["train"],"f_Rw2") && data["train"]["f_Rw2"]!=nothing
|
||||
if typeof(data["train"]["f_Rw2"]) <: Real && data["train"]["f_Rw2"]>=0.0
|
||||
train.f_Rw2=data["train"]["f_Rw2"]
|
||||
f_Rw2=data["train"]["f_Rw2"]
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of f_Rw2 is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
train.f_Rw2=0.0
|
||||
f_Rw2=0.0
|
||||
println("WARNING at reading the train yaml file: The keyword f_Rw2 is missing. Therefore f_Rw2=0.0 ‰ will be assumed and used." )
|
||||
end
|
||||
delete!(data["train"], "f_Rw2")
|
||||
|
@ -417,6 +313,39 @@ function inputTrain(trainDirectory::String)
|
|||
end
|
||||
end
|
||||
|
||||
# create the train Dictionary
|
||||
train= Dict(:name => name, # train's name
|
||||
:id => id, # train's identifier
|
||||
:trainType => trainType, # type of train "passenger" or "freight" or "motor coach train"
|
||||
:l_train => l_train, # total length (in m)
|
||||
:v_limit => v_limit, # trains speed limit (in m/s)
|
||||
:a_braking => a_braking, # braking acceleration (in m/s^2)
|
||||
:m_train => m_train, # total mass (in kg)
|
||||
:ξ_train => ξ_train, # rotation mass factor of the whole train (without unit)
|
||||
# if not available use ξ_t and ξ_w
|
||||
|
||||
# traction unit
|
||||
:m_t => m_t, # mass of the traction unit (in kg)
|
||||
:m_td => m_td, # mass on the traction units driving axles (in kg)
|
||||
:m_tc => m_tc, # mass on the traction units carrying axles (in kg)
|
||||
:ξ_t => ξ_t, # rotation mass factor of the traction unit (without unit)
|
||||
# in case ξ_train is not available
|
||||
:tractiveEffortVelocityPairs => tractiveEffortVelocityPairs, # list of velocities and their corresponding tractive effort (in [m/s , N])
|
||||
|
||||
:f_Rtd0 => f_Rtd0, # coefficient for basic resistance due to the traction units driving axles (in ‰)
|
||||
:f_Rtc0 => f_Rtc0, # coefficient for basic resistance due to the traction units carring axles (in ‰)
|
||||
:F_Rt2 => F_Rt2, # coefficient for air resistance of the traction units (in N)
|
||||
:Δv_t => Δv_t, # coefficient for velocitiy difference between traction unit and outdoor air
|
||||
|
||||
# set of wagons
|
||||
:m_w => m_w, # mass of the set of wagons (in kg)
|
||||
:ξ_w => ξ_w, # rotation mass factor of the set of wagons (without unit)
|
||||
# in case ξ_train is not available
|
||||
:f_Rw0 => f_Rw0, # coefficient for basic resistance of the set of wagons (in ‰)
|
||||
:f_Rw1 => f_Rw1, # coefficient for resistance to rolling of the set of wagons (in ‰)
|
||||
:f_Rw2 => f_Rw2, # coefficient for air resistance of the set of wagons (in ‰)
|
||||
:Δv_w => Δv_w) # coefficient for velocitiy difference between set of wagons and outdoor air (in m/s)
|
||||
|
||||
return train
|
||||
end #function inputTrain
|
||||
|
||||
|
@ -465,7 +394,7 @@ end #function checkAndDefineTractiveEffortInput
|
|||
|
||||
|
||||
function inputPath(pathDirectory::String)
|
||||
# this function reads path information from a YAML file, saves it in a Path object and returns it
|
||||
# read path information from a YAML file, save it in a path Dict and return it
|
||||
data = YAML.load(open(pathDirectory))
|
||||
collect(keys(data))
|
||||
collect(values(data))
|
||||
|
@ -479,7 +408,6 @@ function inputPath(pathDirectory::String)
|
|||
delete!(data["path"], "name")
|
||||
|
||||
id=1 # path identifier
|
||||
path=Path(name, id, [])
|
||||
|
||||
# read the section starting positions and corresponding information
|
||||
if haskey(data["path"],"sectionStarts") && data["path"]["sectionStarts"]!=nothing
|
||||
|
@ -544,16 +472,22 @@ function inputPath(pathDirectory::String)
|
|||
error("ERROR at reading the path yaml file: The values of ",valueKey," have to be corrected.")
|
||||
end
|
||||
|
||||
# save values in the path object
|
||||
# save values in the path Dict
|
||||
sections=[]
|
||||
for row in 2:length(sectionStartsArray)
|
||||
s_start=sectionStartsArray[row-1][1] # first point of the section (in m)
|
||||
s_end=sectionStartsArray[row][1] # first point of the next section (in m)
|
||||
v_limit=sectionStartsArray[row-1][2]*conversionFactor # paths speed limt (in m/s)
|
||||
f_Rp=sectionStartsArray[row-1][3] # specific path resistance of the section (in ‰)
|
||||
section=PathSection(s_start, s_end, v_limit, f_Rp)
|
||||
push!(path.sections, section)
|
||||
section=Dict(:s_start => s_start, :s_end => s_end, :v_limit => v_limit, :f_Rp => f_Rp)
|
||||
push!(sections, section)
|
||||
end # for
|
||||
# s_start in first entry defines the path's beginning
|
||||
# s_end in last entry defines the path's ending
|
||||
|
||||
path = Dict(:name => name,
|
||||
:id => id,
|
||||
:sections => sections)
|
||||
|
||||
# inform the user which keywords of the input data are not used in this tool:
|
||||
if length(data["path"])>0
|
||||
|
@ -567,19 +501,28 @@ end # function inputPath
|
|||
|
||||
|
||||
|
||||
|
||||
## settings for the calculation
|
||||
function inputSettings(settingsDirectory::String)
|
||||
# this function reads setting information from a YAML file, saves it in a Setting object and returns it
|
||||
# read setting information from a YAML file, save it in a settings Dict and return it
|
||||
data = YAML.load(open(settingsDirectory))
|
||||
collect(keys(data))
|
||||
collect(values(data))
|
||||
|
||||
settings=Settings()
|
||||
# initialize the settings Dictionary
|
||||
settings = Dict(:massModel => "", # model type of the unions mass "mass point" or "homogeneous strip"
|
||||
:stepVariable => "", # step variable of the step method "s in m", "t in s" or "v in m/s"
|
||||
:stepSize => 0.0, # step size (unit depends on steapVariable s in m, t in s and v in m/s)
|
||||
:operationModeMinimumRunningTime => false, # operation mode "minimum running time"
|
||||
:operationModeMinimumEnergyConsumption => false, # operation mode "minimum energy consumption"
|
||||
:typeOfOutput => "", # output as "julia dictionary" or as "CSV"
|
||||
:csvDirectory => "", # path of the folder in which the CSV files willl be saved
|
||||
:detailOfOutput => "") # detail of output "minimal" or "everything"
|
||||
|
||||
# model type of the train's mass "mass point" or "homogeneous strip"
|
||||
if haskey(data["settings"],"massModel")
|
||||
if typeof(data["settings"]["massModel"])==String && (data["settings"]["massModel"]=="mass point" || data["settings"]["massModel"]=="homogeneous strip")
|
||||
settings.massModel=data["settings"]["massModel"] # "mass point" or "homogeneous strip"
|
||||
if typeof(data["settings"]["massModel"])==String && (data["settings"]["massModel"]=="mass point" || data["settings"]["massModel"]=="homogeneous strip")
|
||||
# 12/15 old, not needed if already initialized: merge!(settings, Dict(:massModel => data["settings"]["massModel"])) # "mass point" or "homogeneous strip"
|
||||
settings[:massModel] = data["settings"]["massModel"] # "mass point" or "homogeneous strip"
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of massModel is wrong. It has to be mass point or homogeneous strip.")
|
||||
end
|
||||
|
@ -589,11 +532,11 @@ function inputSettings(settingsDirectory::String)
|
|||
delete!(data["settings"], "massModel")
|
||||
|
||||
|
||||
|
||||
# step variable of the step method "s in m", "t in s" or "v in m/s"
|
||||
if haskey(data["settings"],"stepVariable")
|
||||
if typeof(data["settings"]["stepVariable"])==String && (data["settings"]["stepVariable"]=="s in m" || data["settings"]["stepVariable"]=="t in s" || data["settings"]["stepVariable"]=="v in m/s")
|
||||
settings.stepVariable=data["settings"]["stepVariable"] # "s in m", "t in s" or "v in m/s"
|
||||
if typeof(data["settings"]["stepVariable"])==String && (data["settings"]["stepVariable"]=="s in m" || data["settings"]["stepVariable"]=="t in s" || data["settings"]["stepVariable"]=="v in m/s")
|
||||
# 12/15 old, not needed if already initialized: merge!(settings, Dict(:stepVariable => data["settings"]["stepVariable"])) # "s in m", "t in s" or "v in m/s"
|
||||
settings[:stepVariable] = data["settings"]["stepVariable"] # "s in m", "t in s" or "v in m/s"
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of stepVariable is wrong. It has to be s in m, t in s or v in m/s.")
|
||||
end
|
||||
|
@ -603,10 +546,11 @@ function inputSettings(settingsDirectory::String)
|
|||
delete!(data["settings"], "stepVariable")
|
||||
|
||||
|
||||
# step size (unit depends on steapVariable: s in m, t in s and v in m/s)
|
||||
# step size (unit depends on steapVariable: s in m, t in s and v in m/s)
|
||||
if haskey(data["settings"],"stepSize")
|
||||
if typeof(data["settings"]["stepSize"]) <: Real && data["settings"]["stepSize"]>0.0
|
||||
settings.stepSize=data["settings"]["stepSize"]
|
||||
# 12/15 old, not needed if already initialized: merge!(settings, Dict(:stepSize => data["settings"]["stepSize"]))
|
||||
settings[:stepSize] = data["settings"]["stepSize"]
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of the stepSize is no real floating point number >0.0.")
|
||||
end
|
||||
|
@ -616,17 +560,17 @@ function inputSettings(settingsDirectory::String)
|
|||
delete!(data["settings"], "stepSize")
|
||||
|
||||
|
||||
|
||||
# operation mode "minimum running time"
|
||||
if haskey(data["settings"],"operationModeMinimumRunningTime") && data["settings"]["operationModeMinimumRunningTime"]!=nothing
|
||||
if typeof(data["settings"]["operationModeMinimumRunningTime"])==Bool
|
||||
settings.operationModeMinimumRunningTime=data["settings"]["operationModeMinimumRunningTime"]
|
||||
# 12/15 old, not needed if already initialized: merge!(settings, Dict(:operationModeMinimumRunningTime => data["settings"]["operationModeMinimumRunningTime"]))
|
||||
settings[:operationModeMinimumRunningTime] = data["settings"]["operationModeMinimumRunningTime"]
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of the keyword operationModeMinimumRunningTime is not correct. The value has to be of type boolean.")
|
||||
end
|
||||
else
|
||||
settings.operationModeMinimumRunningTime=false
|
||||
println("WARNING at reading the settings yaml file: The keyword operationModeMinimumRunningTime or its value is missing. Therefore operationModeMinimumRunningTime=",settings.operationModeMinimumRunningTime," is assumed and used.")
|
||||
settings[:operationModeMinimumRunningTime]=false
|
||||
println("WARNING at reading the settings yaml file: The keyword operationModeMinimumRunningTime or its value is missing. Therefore operationModeMinimumRunningTime=",settings[:operationModeMinimumRunningTime]," is assumed and used.")
|
||||
end
|
||||
delete!(data["settings"], "operationModeMinimumRunningTime")
|
||||
|
||||
|
@ -634,20 +578,22 @@ function inputSettings(settingsDirectory::String)
|
|||
# operation mode "minimum energy consumption"
|
||||
if haskey(data["settings"],"operationModeMinimumEnergyConsumption") && data["settings"]["operationModeMinimumEnergyConsumption"]!=nothing
|
||||
if typeof(data["settings"]["operationModeMinimumEnergyConsumption"])==Bool
|
||||
settings.operationModeMinimumEnergyConsumption=data["settings"]["operationModeMinimumEnergyConsumption"]
|
||||
# 12/15 old, not needed if already initialized: merge!(settings, Dict(:operationModeMinimumEnergyConsumption => data["settings"]["operationModeMinimumEnergyConsumption"]))
|
||||
settings[:operationModeMinimumEnergyConsumption] = data["settings"]["operationModeMinimumEnergyConsumption"]
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of the keyword operationModeMinimumEnergyConsumption is not correct. The value has to be of type boolean.")
|
||||
end
|
||||
else
|
||||
settings.operationModeMinimumEnergyConsumption=false
|
||||
println("WARNING at reading the settings yaml file: The keyword operationModeMinimumEnergyConsumption or its value is missing. Therefore operationModeMinimumEnergyConsumption=",settings.operationModeMinimumEnergyConsumption," is assumed and used.")
|
||||
settings[:operationModeMinimumEnergyConsumption] = false
|
||||
println("WARNING at reading the settings yaml file: The keyword operationModeMinimumEnergyConsumption or its value is missing. Therefore operationModeMinimumEnergyConsumption=", settings[:operationModeMinimumEnergyConsumption]," is assumed and used.")
|
||||
end
|
||||
delete!(data["settings"], "operationModeMinimumEnergyConsumption")
|
||||
|
||||
# output as "julia dictionary" or as "CSV"
|
||||
if haskey(data["settings"],"typeOfOutput")
|
||||
if typeof(data["settings"]["typeOfOutput"])==String && (data["settings"]["typeOfOutput"]=="julia dictionary" || data["settings"]["typeOfOutput"]=="CSV")
|
||||
settings.typeOfOutput=data["settings"]["typeOfOutput"] # "julia dictionary" or "CSV"
|
||||
# 12/15 old, not needed if already initialized: merge!(settings, Dict(:typeOfOutput => data["settings"]["typeOfOutput"])) # "julia dictionary" or "CSV"
|
||||
settings[:typeOfOutput] = data["settings"]["typeOfOutput"] # "julia dictionary" or "CSV"
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of typeOfOutput is wrong. It has to be julia dictionary or CSV.")
|
||||
end
|
||||
|
@ -657,10 +603,11 @@ function inputSettings(settingsDirectory::String)
|
|||
delete!(data["settings"], "typeOfOutput")
|
||||
|
||||
# TODO: it could be checked if the path is existing on the pc
|
||||
if settings.typeOfOutput=="CSV"
|
||||
if settings[:typeOfOutput] == "CSV"
|
||||
if haskey(data["settings"],"csvDirectory")
|
||||
if typeof(data["settings"]["csvDirectory"])==String
|
||||
settings.csvDirectory=data["settings"]["csvDirectory"]
|
||||
if typeof(data["settings"]["csvDirectory"])==String
|
||||
# 12/15 old, not needed if already initialized: merge!(settings, Dict(:csvDirectory => data["settings"]["csvDirectory"]))
|
||||
settings[:csvDirectory] = data["settings"]["csvDirectory"]
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of csvDirectory is wrong. It has to be of type String.")
|
||||
end
|
||||
|
@ -673,8 +620,9 @@ function inputSettings(settingsDirectory::String)
|
|||
|
||||
# should the output be "minimal" or "driving course"
|
||||
if haskey(data["settings"],"detailOfOutput")
|
||||
if typeof(data["settings"]["detailOfOutput"])==String && (data["settings"]["detailOfOutput"]=="minimal" || data["settings"]["detailOfOutput"]=="driving course")
|
||||
settings.detailOfOutput=data["settings"]["detailOfOutput"] # "minimal" or "driving course"
|
||||
if typeof(data["settings"]["detailOfOutput"])==String && (data["settings"]["detailOfOutput"]=="minimal" || data["settings"]["detailOfOutput"]=="driving course")
|
||||
# 12/15 old, not needed if already initialized: merge!(settings, Dict(:detailOfOutput => data["settings"]["detailOfOutput"])) # "minimal" or "driving course"
|
||||
settings[:detailOfOutput] = data["settings"]["detailOfOutput"]
|
||||
else
|
||||
error("ERROR at reading the settings yaml file: The value of detailOfOutput is wrong. It has to be minimal or driving course.")
|
||||
end
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -12,95 +12,96 @@ export calculateMinimumRunningTime!, calculateMinimumEnergyConsumption
|
|||
approximationLevel = 6 # TODO: define it in TrainRun and give it to each function?
|
||||
|
||||
# calculate a train run focussing on using the minimum possible running time
|
||||
function calculateMinimumRunningTime!(movingSection::MovingSection, settings::Settings, train::Train)
|
||||
# CSs=movingSection.characteristicSections
|
||||
function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train::Dict)
|
||||
CSs::Vector{CharacteristicSection} = movingSection[:characteristicSections]
|
||||
|
||||
startingPoint=DataPoint()
|
||||
startingPoint.i=1
|
||||
startingPoint.s=movingSection.characteristicSections[1].s_entry
|
||||
startingPoint.s=CSs[1].s_entry
|
||||
drivingCourse=[startingPoint] # List of data points
|
||||
|
||||
# for CS in CSs
|
||||
for csId in 1:length(movingSection.characteristicSections)
|
||||
for csId in 1:length(CSs)
|
||||
# println("CS",csId)
|
||||
# check if the CS has a cruising section
|
||||
s_breakFree=get(movingSection.characteristicSections[csId].behaviorSections, "breakFree", BehaviorSection()).length
|
||||
s_clearing=get(movingSection.characteristicSections[csId].behaviorSections, "clearing", BehaviorSection()).length
|
||||
s_acceleration=get(movingSection.characteristicSections[csId].behaviorSections, "acceleration", BehaviorSection()).length
|
||||
s_braking=max(0.0, ceil((movingSection.characteristicSections[csId].v_exit^2-movingSection.characteristicSections[csId].v_target^2)/2/train.a_braking, digits=approximationLevel)) # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
|
||||
s_breakFree = get(CSs[csId].behaviorSections, :breakFree, BehaviorSection()).length
|
||||
s_clearing = get(CSs[csId].behaviorSections, :clearing, 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
|
||||
|
||||
# calculate the cruising sections length
|
||||
s_cruising=movingSection.characteristicSections[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
|
||||
delete!(movingSection.characteristicSections[csId].behaviorSections, "breakFree")
|
||||
delete!(movingSection.characteristicSections[csId].behaviorSections, "clearing")
|
||||
delete!(movingSection.characteristicSections[csId].behaviorSections, "acceleration")
|
||||
delete!(movingSection.characteristicSections[csId].behaviorSections, "diminishing")
|
||||
delete!(movingSection.characteristicSections[csId].behaviorSections, "cruising")
|
||||
movingSection.characteristicSections[csId].E=0.0
|
||||
movingSection.characteristicSections[csId].t=0.0
|
||||
delete!(CSs[csId].behaviorSections, :breakFree)
|
||||
delete!(CSs[csId].behaviorSections, :clearing)
|
||||
delete!(CSs[csId].behaviorSections, :acceleration)
|
||||
delete!(CSs[csId].behaviorSections, :diminishing)
|
||||
delete!(CSs[csId].behaviorSections, :cruising)
|
||||
CSs[csId].E=0.0
|
||||
CSs[csId].t=0.0
|
||||
|
||||
|
||||
if s_clearing == movingSection.characteristicSections[csId].length
|
||||
# 09/06 TODO: thought about using "cruising" because it is used in EnergySaving and not clearing (movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_clearing, settings, train, movingSection.characteristicSections, "cruising")
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_clearing, settings, train, movingSection.characteristicSections, "clearing")
|
||||
elseif s_cruising == movingSection.characteristicSections[csId].length
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruising, settings, train, movingSection.characteristicSections, "cruising")
|
||||
if s_clearing == CSs[csId].length
|
||||
# 09/06 TODO: thought about using "cruising" because it is used in EnergySaving and not clearing (CSs[csId], drivingCourse)=addCruisingPhase!(CSs[csId], drivingCourse, s_clearing, settings, train, CSs, "cruising")
|
||||
(CSs[csId], drivingCourse)=addCruisingPhase!(CSs[csId], drivingCourse, s_clearing, settings, train, CSs, "clearing")
|
||||
elseif s_cruising == CSs[csId].length
|
||||
(CSs[csId], drivingCourse)=addCruisingPhase!(CSs[csId], drivingCourse, s_cruising, settings, train, CSs, "cruising")
|
||||
elseif s_cruising > 0.0 || s_braking == 0.0
|
||||
# 09/21 elseif s_cruising > 0.0
|
||||
# 09/21 elseif s_cruising > 0.01 # if the cruising section is longer than 1 cm (because of rounding issues not >0.0)
|
||||
if drivingCourse[end].v < movingSection.characteristicSections[csId].v_target
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addAccelerationPhase!(movingSection.characteristicSections[csId], drivingCourse, settings, train, movingSection.characteristicSections)
|
||||
if drivingCourse[end].v < CSs[csId].v_target
|
||||
(CSs[csId], drivingCourse)=addAccelerationPhase!(CSs[csId], drivingCourse, settings, train, CSs)
|
||||
end #if
|
||||
|
||||
if movingSection.characteristicSections[csId].s_exit-drivingCourse[end].s-max(0.0, (movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/train.a_braking) < -0.001 # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
|
||||
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(" before acceleration in CS",csId, " with s=",drivingCourse[end].s," s_braking=",((movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/train.a_braking)," s_exit=",movingSection.characteristicSections[csId].s_exit)
|
||||
println(" and v=",drivingCourse[end].v," v_target=",movingSection.characteristicSections[csId].v_target," v_exit=",movingSection.characteristicSections[csId].v_exit)
|
||||
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)
|
||||
end
|
||||
|
||||
s_braking=max(0.0, ceil((movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=approximationLevel)) # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
|
||||
s_cruising=movingSection.characteristicSections[csId].s_exit-drivingCourse[end].s-s_braking
|
||||
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_cruising=CSs[csId].s_exit-drivingCourse[end].s-s_braking
|
||||
|
||||
if s_cruising > 0.0
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruising, settings, train, movingSection.characteristicSections, "cruising")
|
||||
(CSs[csId], drivingCourse)=addCruisingPhase!(CSs[csId], drivingCourse, s_cruising, settings, train, CSs, "cruising")
|
||||
end
|
||||
else
|
||||
|
||||
if movingSection.characteristicSections[csId].v_entry < movingSection.characteristicSections[csId].v_target || s_acceleration > 0.0 # or instead of " || s_acceleration > 0.0" use "v_entry <= v_target" or "v_i <= v_target"
|
||||
# 09/09 old (not sufficient for steep gradients): if movingSection.characteristicSections[csId].v_entry < movingSection.characteristicSections[csId].v_target
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addAccelerationPhaseUntilBraking!(movingSection.characteristicSections[csId], drivingCourse, settings, train, movingSection.characteristicSections)
|
||||
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"
|
||||
# 09/09 old (not sufficient for steep gradients): if CSs[csId].v_entry < CSs[csId].v_target
|
||||
(CSs[csId], drivingCourse)=addAccelerationPhaseUntilBraking!(CSs[csId], drivingCourse, settings, train, CSs)
|
||||
end #if
|
||||
end #if
|
||||
|
||||
|
||||
s_braking=max(0.0, ceil((movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=approximationLevel)) # ceil is used to be sure that the train 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
|
||||
|
||||
if drivingCourse[end].v > movingSection.characteristicSections[csId].v_exit
|
||||
#(movingSection.characteristicSections[csId], drivingCourse)=addBrakingPhase!(movingSection.characteristicSections[csId], drivingCourse, settings.massModel, train, movingSection.characteristicSections)
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addBrakingPhase!(movingSection.characteristicSections[csId], drivingCourse, settings, train, movingSection.characteristicSections)
|
||||
if drivingCourse[end].v > CSs[csId].v_exit
|
||||
#(CSs[csId], drivingCourse)=addBrakingPhase!(CSs[csId], drivingCourse, settings[:massModel], train, CSs)
|
||||
(CSs[csId], drivingCourse)=addBrakingPhase!(CSs[csId], drivingCourse, settings, train, CSs)
|
||||
end #if
|
||||
|
||||
#= 09/20 old and should never be used:
|
||||
if drivingCourse[end].s < movingSection.characteristicSections[csId].s_exit
|
||||
if haskey(movingSection.characteristicSections[csId].behaviorSections, "cruising")
|
||||
println("INFO: A second cruising section has been added to CS ", csId," from s=",drivingCourse[end].s," to s_exit=",movingSection.characteristicSections[csId].s_exit)
|
||||
if drivingCourse[end].s < CSs[csId].s_exit
|
||||
if haskey(CSs[csId].behaviorSections, :cruising)
|
||||
println("INFO: A second cruising section has been added to CS ", csId," from s=",drivingCourse[end].s," to s_exit=",CSs[csId].s_exit)
|
||||
end
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruising, settings, train, movingSection.characteristicSections, "cruising")
|
||||
(CSs[csId], drivingCourse)=addCruisingPhase!(CSs[csId], drivingCourse, s_cruising, settings, train, CSs, "cruising")
|
||||
end =#
|
||||
end #for
|
||||
|
||||
# calculate the last data points resiting forces
|
||||
drivingCourse[end]=DataPoint(calculateForces!(drivingCourse[end], train, settings.massModel, movingSection.characteristicSections, "braking"))
|
||||
drivingCourse[end]=DataPoint(calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "braking"))
|
||||
|
||||
movingSection.t=drivingCourse[end].t # total running time (in s)
|
||||
movingSection.E=drivingCourse[end].E # total energy consumption (in Ws)
|
||||
movingSection[:t] = drivingCourse[end].t # total running time (in s)
|
||||
movingSection[:E] = drivingCourse[end].E # total energy consumption (in Ws)
|
||||
|
||||
return (movingSection, drivingCourse)
|
||||
end #function calculateMinimumRunningTime
|
||||
|
||||
|
||||
function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::MovingSection, drivingCourseMinimumRunningTime::Vector{DataPoint}, settings::Settings, train::Train)
|
||||
function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict, drivingCourseMinimumRunningTime::Vector{DataPoint}, settings::Dict, train::Dict)
|
||||
# calculate a train run focussing on using the minimum possible energy consumption
|
||||
# booleans for choosing which methods are used for saving energy
|
||||
doMethod1=true
|
||||
|
@ -111,7 +112,8 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Movi
|
|||
#doCombinationOfMethods=false
|
||||
|
||||
#create a new moving section for the minimum energy consumption
|
||||
movingSectionOriginal=MovingSection(movingSectionMinimumRunningTime)
|
||||
movingSectionOriginal=copyMovingSection(movingSectionMinimumRunningTime)
|
||||
CSsOrig::Vector{CharacteristicSection} = movingSectionOriginal[:characteristicSections]
|
||||
|
||||
# create a new driving course for the minimum energy consumption
|
||||
drivingCourseOriginal=DataPoint[]
|
||||
|
@ -120,15 +122,15 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Movi
|
|||
end
|
||||
|
||||
# calculate the recovery time
|
||||
movingSectionOriginal.t_recovery=calculateRecoveryTime(movingSectionOriginal.length, movingSectionOriginal.t, train)
|
||||
movingSectionOriginal.t_recoveryAvailable=movingSectionOriginal.t_recovery
|
||||
movingSectionOriginal[:t_recovery]=calculateRecoveryTime(movingSectionOriginal[:length], movingSectionOriginal[:t], train)
|
||||
movingSectionOriginal[:t_recoveryAvailable]=movingSectionOriginal[:t_recovery]
|
||||
|
||||
# create arrays for each method with all the available energy saving modifications
|
||||
energySavingModificationsWithCoasting=EnergySavingModification[]
|
||||
energySavingModificationsWithMaximumSpeed=EnergySavingModification[]
|
||||
energySavingModificationsWithCombination=EnergySavingModification[]
|
||||
|
||||
for csId in 1:length(movingSectionOriginal.characteristicSections)
|
||||
for csId in 1:length(CSsOrig)
|
||||
# method 1: increase coasting
|
||||
if doMethod1 == true
|
||||
modificationType = "increasing coasting"
|
||||
|
@ -151,62 +153,14 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Movi
|
|||
end #if
|
||||
end # for
|
||||
|
||||
while movingSectionOriginal.t_recoveryAvailable > 0.0
|
||||
while movingSectionOriginal[:t_recoveryAvailable] > 0.0
|
||||
# comparison of modifications
|
||||
ratioMax=0.0
|
||||
csIdMax=0
|
||||
typeMax="none"
|
||||
(energySavingModificationsWithMaximumSpeed, ratioMax, csIdMax, typeMax) = findBestModification(energySavingModificationsWithMaximumSpeed, ratioMax, csIdMax, typeMax, movingSectionOriginal.t_recoveryAvailable)
|
||||
# 09/14 Three if cases for testing:
|
||||
#= if length(movingSectionOriginal.energySavingModifications)==895 && ratioMax>0.0
|
||||
println("")
|
||||
println("typeMax=",typeMax)
|
||||
println("ratioMax=",ratioMax)
|
||||
println("csIdMax=",csIdMax)
|
||||
println("---")
|
||||
|
||||
|
||||
println("type=",energySavingModificationsWithMaximumSpeed[csIdMax].type)
|
||||
println(" csId=",energySavingModificationsWithMaximumSpeed[csIdMax].csId)
|
||||
println(" ΔE=",energySavingModificationsWithMaximumSpeed[csIdMax].ΔE)
|
||||
println(" Δt=",energySavingModificationsWithMaximumSpeed[csIdMax].Δt)
|
||||
println(" ratio=",energySavingModificationsWithMaximumSpeed[csIdMax].ratio)
|
||||
println(" DC-length=",length(energySavingModificationsWithMaximumSpeed[csIdMax].drivingCourseModified))
|
||||
end
|
||||
=#
|
||||
(energySavingModificationsWithCoasting, ratioMax, csIdMax, typeMax) = findBestModification(energySavingModificationsWithCoasting, ratioMax, csIdMax, typeMax, movingSectionOriginal.t_recoveryAvailable)
|
||||
#= if length(movingSectionOriginal.energySavingModifications)==895 && ratioMax>0.0
|
||||
println("typeMax=",typeMax)
|
||||
println("ratioMax=",ratioMax)
|
||||
println("csIdMax=",csIdMax)
|
||||
println("---")
|
||||
|
||||
|
||||
println("type=",energySavingModificationsWithCoasting[csIdMax].type)
|
||||
println(" csId=",energySavingModificationsWithCoasting[csIdMax].csId)
|
||||
println(" ΔE=",energySavingModificationsWithCoasting[csIdMax].ΔE)
|
||||
println(" Δt=",energySavingModificationsWithCoasting[csIdMax].Δt)
|
||||
println(" ratio=",energySavingModificationsWithCoasting[csIdMax].ratio)
|
||||
println(" DC-length=",length(energySavingModificationsWithCoasting[csIdMax].drivingCourseModified))
|
||||
end
|
||||
|
||||
=#
|
||||
(energySavingModificationsWithCombination, ratioMax, csIdMax, typeMax) = findBestModification(energySavingModificationsWithCombination, ratioMax, csIdMax, typeMax, movingSectionOriginal.t_recoveryAvailable)
|
||||
#= if length(movingSectionOriginal.energySavingModifications)==895 && ratioMax>0.0
|
||||
println("typeMax=",typeMax)
|
||||
println("ratioMax=",ratioMax)
|
||||
println("csIdMax=",csIdMax)
|
||||
println("---")
|
||||
|
||||
|
||||
println("type=",energySavingModificationsWithCombination[csIdMax].type)
|
||||
println(" csId=",energySavingModificationsWithCombination[csIdMax].csId)
|
||||
println(" ΔE=",energySavingModificationsWithCombination[csIdMax].ΔE)
|
||||
println(" Δt=",energySavingModificationsWithCombination[csIdMax].Δt)
|
||||
println(" ratio=",energySavingModificationsWithCombination[csIdMax].ratio)
|
||||
println(" DC-length=",length(energySavingModificationsWithCombination[csIdMax].drivingCourseModified))
|
||||
end
|
||||
=#
|
||||
(energySavingModificationsWithMaximumSpeed, ratioMax, csIdMax, typeMax) = findBestModification(energySavingModificationsWithMaximumSpeed, ratioMax, csIdMax, typeMax, movingSectionOriginal[:t_recoveryAvailable])
|
||||
(energySavingModificationsWithCoasting, ratioMax, csIdMax, typeMax) = findBestModification(energySavingModificationsWithCoasting, ratioMax, csIdMax, typeMax, movingSectionOriginal[:t_recoveryAvailable])
|
||||
(energySavingModificationsWithCombination, ratioMax, csIdMax, typeMax) = findBestModification(energySavingModificationsWithCombination, ratioMax, csIdMax, typeMax, movingSectionOriginal[:t_recoveryAvailable])
|
||||
|
||||
|
||||
# select the most efficient modification and update the original characteristicSection, drivingCourse and movingSection
|
||||
|
@ -214,53 +168,39 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Movi
|
|||
if typeMax=="none"
|
||||
break
|
||||
elseif typeMax=="increasing coasting"
|
||||
# println("Energy saving modification number ",length(movingSectionOriginal.energySavingModifications)+1," (coasting) in CS ",csIdMax ," Δt=",energySavingModificationsWithCoasting[csIdMax].Δt," ΔE=", energySavingModificationsWithCoasting[csIdMax].ΔE," t_recoveryAvailable=", movingSectionOriginal.t_recoveryAvailable-energySavingModificationsWithCoasting[csIdMax].Δt)
|
||||
push!(movingSectionOriginal.energySavingModifications, energySavingModificationsWithCoasting[csIdMax])
|
||||
# println("Nr. ",length(movingSectionOriginal.energySavingModifications),": typeMax=increasing coasting")
|
||||
# println("Energy saving modification number ",length(movingSectionOriginal[:energySavingModifications])+1," (coasting) in CS ",csIdMax ," Δt=",energySavingModificationsWithCoasting[csIdMax].Δt," ΔE=", energySavingModificationsWithCoasting[csIdMax].ΔE," t_recoveryAvailable=", movingSectionOriginal[:t_recoveryAvailable]-energySavingModificationsWithCoasting[csIdMax].Δt)
|
||||
push!(movingSectionOriginal[:energySavingModifications], energySavingModificationsWithCoasting[csIdMax])
|
||||
# println("Nr. ",length(movingSectionOriginal[:energySavingModifications]),": typeMax=increasing coasting")
|
||||
elseif typeMax=="decreasing maximum velocity"
|
||||
push!(movingSectionOriginal.energySavingModifications, energySavingModificationsWithMaximumSpeed[csIdMax])
|
||||
# println("Nr. ",length(movingSectionOriginal.energySavingModifications),": typeMax=decreasing maximum velocity")
|
||||
push!(movingSectionOriginal[:energySavingModifications], energySavingModificationsWithMaximumSpeed[csIdMax])
|
||||
# println("Nr. ",length(movingSectionOriginal[:energySavingModifications]),": typeMax=decreasing maximum velocity")
|
||||
elseif typeMax=="combination of energy saving methods"
|
||||
push!(movingSectionOriginal.energySavingModifications, energySavingModificationsWithCombination[csIdMax])
|
||||
# println("Nr. ",length(movingSectionOriginal.energySavingModifications),": typeMax=combination of energy saving methods")
|
||||
push!(movingSectionOriginal[:energySavingModifications], energySavingModificationsWithCombination[csIdMax])
|
||||
# println("Nr. ",length(movingSectionOriginal[:energySavingModifications]),": typeMax=combination of energy saving methods")
|
||||
end #if
|
||||
|
||||
movingSectionOriginal.t_recoveryAvailable = movingSectionOriginal.t_recoveryAvailable - movingSectionOriginal.energySavingModifications[end].Δt
|
||||
movingSectionOriginal[:t_recoveryAvailable] = movingSectionOriginal[:t_recoveryAvailable] - movingSectionOriginal[:energySavingModifications][end].Δt
|
||||
|
||||
lastIdOfSelectedCsOriginal = get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "braking", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "cruisingAfterCoasting", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "coasting", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "cruising", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "acceleration", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "clearing", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "breakFree", BehaviorSection()))))))).dataPoints[end]
|
||||
lastIdOfSelectedCsOriginal = get(CSsOrig[csIdMax].behaviorSections, :standStill,
|
||||
get(CSsOrig[csIdMax].behaviorSections, :braking,
|
||||
get(CSsOrig[csIdMax].behaviorSections, :cruisingAfterCoasting,
|
||||
get(CSsOrig[csIdMax].behaviorSections, :coasting,
|
||||
get(CSsOrig[csIdMax].behaviorSections, :cruising,
|
||||
get(CSsOrig[csIdMax].behaviorSections, :acceleration,
|
||||
get(CSsOrig[csIdMax].behaviorSections, :clearing,
|
||||
get(CSsOrig[csIdMax].behaviorSections, :breakFree,
|
||||
get(CSsOrig[csIdMax].behaviorSections, :diminishing,
|
||||
BehaviorSection()))))))))).dataPoints[end]
|
||||
|
||||
# if there is a diminishing phase its location must be analysed seperately because it could be before acceleration, between acceleration and cruising or after cruising. All the other behavior sections occur in a fixed order.
|
||||
if haskey(CSsOrig[csIdMax].behaviorSections, :diminishing)
|
||||
lastIdOfSelectedCsOriginal = max(lastIdOfSelectedCsOriginal, CSsOrig[csIdMax].behaviorSections[:diminishing].dataPoints[end])
|
||||
end
|
||||
|
||||
# create new driving course
|
||||
drivingCourseNew=Vector{DataPoint}()
|
||||
for i in 1:length(movingSectionOriginal.energySavingModifications[end].drivingCourseModified)
|
||||
push!(drivingCourseNew, DataPoint(movingSectionOriginal.energySavingModifications[end].drivingCourseModified[i]))
|
||||
end
|
||||
|
||||
# # for testing if the modifications driving course and the original one have the same speed value at their transition point
|
||||
# if lastIdOfSelectedCsOriginal+1<=drivingCourseOriginal[end].i
|
||||
# if drivingCourseOriginal[lastIdOfSelectedCsOriginal].v-drivingCourseNew[end].v!=0.0
|
||||
# println("INFO: Inconsistency while adding the CS",csIdMax," that has been modified for consuming less energy. The difference at its end is ",(drivingCourseOriginal[lastIdOfSelectedCsOriginal].v-drivingCourseNew[end].v)," m/s."
|
||||
# end
|
||||
# end # for testing
|
||||
|
||||
# for testing 09/09
|
||||
if length(drivingCourseNew) == 0
|
||||
#= println("typeMax=",typeMax)
|
||||
println("ratioMax=",ratioMax)
|
||||
println("csIdMax=",csIdMax)
|
||||
println("---")
|
||||
|
||||
|
||||
println("type=",energySavingModificationsWithCombination[csIdMax].type)
|
||||
println(" csId=",energySavingModificationsWithCombination[csIdMax].csId)
|
||||
println(" ΔE=",energySavingModificationsWithCombination[csIdMax].ΔE)
|
||||
println(" Δt=",energySavingModificationsWithCombination[csIdMax].Δt)
|
||||
println(" ratio=",energySavingModificationsWithCombination[csIdMax].ratio)
|
||||
println(" DC-length=",length(energySavingModificationsWithCombination[csIdMax].drivingCourseModified))
|
||||
=#
|
||||
println("---")
|
||||
println("energySavingModificationsWithCoasting:",length(energySavingModificationsWithCoasting[csIdMax].drivingCourseModified))
|
||||
println("energySavingModificationsWithMaximumSpeed:",length(energySavingModificationsWithMaximumSpeed[csIdMax].drivingCourseModified))
|
||||
println("energySavingModificationsWithCombination:",length(energySavingModificationsWithCombination[csIdMax].drivingCourseModified))
|
||||
for i in 1:length(movingSectionOriginal[:energySavingModifications][end].drivingCourseModified)
|
||||
push!(drivingCourseNew, DataPoint(movingSectionOriginal[:energySavingModifications][end].drivingCourseModified[i]))
|
||||
end
|
||||
|
||||
#fill up the rest of the driving course with information from the original course
|
||||
|
@ -287,19 +227,19 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Movi
|
|||
|
||||
# replace the original driving course and CS with the new modified ones
|
||||
drivingCourseOriginal=drivingCourseNew
|
||||
movingSectionOriginal.characteristicSections[csIdMax]=CharacteristicSection(movingSectionOriginal.energySavingModifications[end].csModified)
|
||||
movingSectionOriginal.t=drivingCourseOriginal[end].t # total running time (in s)
|
||||
movingSectionOriginal.E=drivingCourseOriginal[end].E # total energy consumption (in Ws)
|
||||
CSsOrig[csIdMax]=CharacteristicSection(movingSectionOriginal[:energySavingModifications][end].csModified)
|
||||
movingSectionOriginal[:t]=drivingCourseOriginal[end].t # total running time (in s)
|
||||
movingSectionOriginal[:E]=drivingCourseOriginal[end].E # total energy consumption (in Ws)
|
||||
|
||||
# update all the data point references in the behaviour sections of the following characteristic sections and the other modified characteristic sections
|
||||
if difference!= 0
|
||||
# update the data point references in the behaviour sections of the following characteristic sections
|
||||
allBs=["breakFree", "clearing", "acceleration", "cruising", "diminishing", "coasting","cruisingAfterCoasting", "braking", "standStill"]
|
||||
for csId in csIdMax+1:length(movingSectionOriginal.characteristicSections)
|
||||
allBs=[:breakFree, :clearing, :acceleration, :cruising, :diminishing, :coasting, :cruisingAfterCoasting, :braking, :standStill]
|
||||
for csId in csIdMax+1:length(CSsOrig)
|
||||
for bs in 1: length(allBs)
|
||||
if haskey(movingSectionOriginal.characteristicSections[csId].behaviorSections, allBs[bs])
|
||||
for point in 1:length(get(movingSectionOriginal.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).dataPoints)
|
||||
get(movingSectionOriginal.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).dataPoints[point]=get(movingSectionOriginal.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).dataPoints[point]+difference
|
||||
if haskey(CSsOrig[csId].behaviorSections, allBs[bs])
|
||||
for point in 1:length(CSsOrig[csId].behaviorSections[allBs[bs]].dataPoints)
|
||||
CSsOrig[csId].behaviorSections[allBs[bs]].dataPoints[point] = CSsOrig[csId].behaviorSections[allBs[bs]].dataPoints[point]+difference
|
||||
end
|
||||
end #if
|
||||
end #for
|
||||
|
@ -335,22 +275,23 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Movi
|
|||
end # while
|
||||
|
||||
|
||||
println("t_recoveryAvailable=",movingSectionOriginal.t_recoveryAvailable)
|
||||
println("t_recoveryAvailable=",movingSectionOriginal[:t_recoveryAvailable])
|
||||
return (movingSectionOriginal, drivingCourseOriginal)
|
||||
end #function calculateMinimumEnergyConsumption
|
||||
|
||||
|
||||
function modifyCs(movingSectionOriginal::MovingSection, drivingCourseOriginal::Vector{DataPoint}, csId::Integer, modificationType::String, settings::Settings, train::Train)
|
||||
#println("drin: ",modificationType)
|
||||
function modifyCs(movingSectionOriginal::Dict, drivingCourseOriginal::Vector{DataPoint}, csId::Integer, modificationType::String, settings::Dict, train::Dict)
|
||||
CSsOrig::Vector{CharacteristicSection} = movingSectionOriginal[:characteristicSections]
|
||||
|
||||
if modificationType == "increasing coasting"
|
||||
# method 1: increase coasting
|
||||
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=increaseCoastingSection(movingSectionOriginal.characteristicSections[csId], drivingCourseOriginal, settings, train, movingSectionOriginal.characteristicSections, movingSectionOriginal.t_recoveryAvailable)
|
||||
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=increaseCoastingSection(CSsOrig[csId], drivingCourseOriginal, settings, train, CSsOrig, movingSectionOriginal[:t_recoveryAvailable])
|
||||
elseif modificationType == "decreasing maximum velocity"
|
||||
# method 2: accelerate to a lower v_target
|
||||
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=decreaseMaximumVelocity(movingSectionOriginal.characteristicSections[csId], drivingCourseOriginal, settings, train, movingSectionOriginal.characteristicSections, movingSectionOriginal.t_recoveryAvailable)
|
||||
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=decreaseMaximumVelocity(CSsOrig[csId], drivingCourseOriginal, settings, train, CSsOrig, movingSectionOriginal[:t_recoveryAvailable])
|
||||
elseif modificationType == "combination of energy saving methods"
|
||||
# calculate the combination of the previous methods
|
||||
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=combineEnergySavingMethods(movingSectionOriginal.characteristicSections[csId], drivingCourseOriginal, settings, train, movingSectionOriginal.characteristicSections, movingSectionOriginal.t_recoveryAvailable)
|
||||
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=combineEnergySavingMethods(CSsOrig[csId], drivingCourseOriginal, settings, train, CSsOrig, movingSectionOriginal[:t_recoveryAvailable])
|
||||
else
|
||||
return EnergySavingModification()
|
||||
end
|
||||
|
@ -361,9 +302,9 @@ function modifyCs(movingSectionOriginal::MovingSection, drivingCourseOriginal::V
|
|||
energySavingModification.type = modificationType # type of energy saving modification: "increasing coasting" or "decreasing maximum velocity" or "combination of energy saving methods"
|
||||
energySavingModification.csModified = characteristicSectionModified # the modified characteristic section
|
||||
energySavingModification.drivingCourseModified = drivingCourseModifiedUntilEndOfModifiedCS # drivingCourse of the modified characteristic section
|
||||
energySavingModification.ΔE = movingSectionOriginal.characteristicSections[csId].E - energySavingModification.csModified.E # saved energy (in Ws)
|
||||
energySavingModification.Δt = energySavingModification.csModified.t - movingSectionOriginal.characteristicSections[csId].t # time loss (in s)
|
||||
if energySavingModification.Δt <= movingSectionOriginal.t_recoveryAvailable && energySavingModification.ΔE >= 0.0
|
||||
energySavingModification.ΔE = CSsOrig[csId].E - energySavingModification.csModified.E # saved energy (in Ws)
|
||||
energySavingModification.Δ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
|
||||
# if modificationType == "combination of energy saving methods"
|
||||
energySavingModification.ratio=sign(energySavingModification.Δt)*energySavingModification.ΔE/energySavingModification.Δt # ratio of ΔE and Δt (in Ws/s)
|
||||
|
@ -397,15 +338,15 @@ function findBestModification(energySavingModifications::Vector{EnergySavingModi
|
|||
end #function findBestModification
|
||||
|
||||
function updateEnergySavingModifications(energySavingModifications::Vector{EnergySavingModification}, 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
|
||||
for modNr in csIdMax+1:length(energySavingModifications)
|
||||
if energySavingModifications[modNr].ratio>0
|
||||
# update the behavior sections of the modified charateristic section
|
||||
for bs in 1: length(allBs)
|
||||
if haskey(energySavingModifications[modNr].csModified.behaviorSections, allBs[bs])
|
||||
for point in 1:length(get(energySavingModifications[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).dataPoints)
|
||||
get(energySavingModifications[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).dataPoints[point] = get(energySavingModifications[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).dataPoints[point]+difference
|
||||
for point in 1:length(energySavingModifications[modNr].csModified.behaviorSections[allBs[bs]].dataPoints)
|
||||
energySavingModifications[modNr].csModified.behaviorSections[allBs[bs]].dataPoints[point] = energySavingModifications[modNr].csModified.behaviorSections[allBs[bs]].dataPoints[point]+difference
|
||||
end
|
||||
end #if
|
||||
end #for
|
||||
|
@ -432,4 +373,28 @@ function updateEnergySavingModifications(energySavingModifications::Vector{Energ
|
|||
return energySavingModifications
|
||||
end #function updateEnergySavingModifications
|
||||
|
||||
function copyMovingSection(original::Dict)
|
||||
CSsCopy = Vector{CharacteristicSection}()
|
||||
for csId in 1:length(original[:characteristicSections])
|
||||
push!(CSsCopy, CharacteristicSection(original[:characteristicSections][csId]))
|
||||
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
|
||||
:length => original[:length], # total length (in m)
|
||||
:s_entry => original[:s_entry], # first position (in m)
|
||||
:s_exit => original[:s_exit], # last position (in m)
|
||||
:t => original[:t], # total running time (in s)
|
||||
:E => original[:E], # total energy consumption (in Ws)
|
||||
:t_recovery => original[:t_recovery], # total recovery time for energy-saving modifications (in s)
|
||||
:t_recoveryAvailable => original[:t_recoveryAvailable], # still available recovery time for energy-saving modifications (in s)
|
||||
:characteristicSections => CSsCopy, # list of containing characteristic sections
|
||||
:energySavingModifications => ModificationsCopy) # list of containing all the used energy saving modifications
|
||||
return copy
|
||||
end #function copyMovingSection
|
||||
|
||||
end #module OperationModes
|
||||
|
|
173
src/Output.jl
173
src/Output.jl
|
@ -7,18 +7,18 @@ using CSV, DataFrames, Dates
|
|||
export createOutput
|
||||
export plotDrivingCourse, printImportantValues, printSectionInformation # functions for showing results during the development
|
||||
|
||||
function createOutput(settings::Settings, pathName::String, trainName::String, drivingCourse::Vector{DataPoint}, movingSection::MovingSection)
|
||||
function createOutput(settings::Dict, pathName::String, trainName::String, drivingCourse::Vector{DataPoint}, movingSection::Dict)
|
||||
# method of function createOutput for one operation mode
|
||||
if settings.typeOfOutput == "CSV"
|
||||
if settings[:typeOfOutput] == "CSV"
|
||||
return createOutputCsv(settings, pathName, trainName, drivingCourse, movingSection)
|
||||
else
|
||||
return createOutputDict(settings, pathName, trainName, drivingCourse, movingSection)
|
||||
end
|
||||
end # funtion createOutput
|
||||
|
||||
function createOutput(settings::Settings, pathName::String, trainName::String, drivingCourseMinimumRunningTime::Vector{DataPoint}, movingSectionMinimumRunningTime::MovingSection, drivingCourseMinimumEnergyConsumption::Vector{DataPoint}, movingSectionMinimumEnergyConsumption::MovingSection)
|
||||
function createOutput(settings::Dict, pathName::String, trainName::String, drivingCourseMinimumRunningTime::Vector{DataPoint}, movingSectionMinimumRunningTime::Dict, drivingCourseMinimumEnergyConsumption::Vector{DataPoint}, movingSectionMinimumEnergyConsumption::Dict)
|
||||
# method of function createOutput for two operation modes
|
||||
if settings.typeOfOutput == "CSV"
|
||||
if settings[:typeOfOutput] == "CSV"
|
||||
return createOutputCsv(settings, pathName, trainName, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||
else
|
||||
return createOutputDict(settings, pathName, trainName, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||
|
@ -26,16 +26,16 @@ function createOutput(settings::Settings, pathName::String, trainName::String, d
|
|||
end # funtion createOutput
|
||||
|
||||
|
||||
function createOutputDict(settings::Settings, pathName::String, trainName::String, drivingCourse::Vector{DataPoint}, movingSection::MovingSection)
|
||||
function createOutputDict(settings::Dict, pathName::String, trainName::String, drivingCourse::Vector{DataPoint}, movingSection::Dict)
|
||||
# method of function createOutputDict for one operation mode
|
||||
if settings.operationModeMinimumRunningTime
|
||||
if settings.operationModeMinimumEnergyConsumption
|
||||
if settings[:operationModeMinimumRunningTime]
|
||||
if settings[:operationModeMinimumEnergyConsumption]
|
||||
operationMode="minimum running time and minimum energy consumption"
|
||||
else
|
||||
operationMode="minimum running time"
|
||||
end
|
||||
else
|
||||
if settings.operationModeMinimumEnergyConsumption
|
||||
if settings[:operationModeMinimumEnergyConsumption]
|
||||
operationMode="minimum energy consumption"
|
||||
else
|
||||
# should never be the case
|
||||
|
@ -44,17 +44,18 @@ function createOutputDict(settings::Settings, pathName::String, trainName::Strin
|
|||
end
|
||||
end
|
||||
|
||||
outputDict=Dict([("path name", pathName), ("train name", trainName), ("operation mode", operationMode), ("mass model", settings.massModel), ("step variable", settings.stepVariable), ("step size", settings.stepSize)])
|
||||
outputDict=Dict([(:pathName, pathName), (:trainName, trainName), (:operationMode, operationMode), (:massModel, settings[:massModel]), (:stepVariable, settings[:stepVariable]), (:stepSize, settings[:stepSize])])
|
||||
#outputDict=Dict([("path name", pathName), ("train name", trainName), ("operation mode", operationMode), ("mass model", settings[:massModel]), ("step variable", settings[:stepVariable]), ("step size", settings[:stepSize])])
|
||||
|
||||
# creating an output array
|
||||
outputArray=Array{Any, 1}[]
|
||||
if settings.detailOfOutput=="minimal"
|
||||
if settings[:detailOfOutput]=="minimal"
|
||||
|
||||
push!(outputArray, ["s (in m)", "t (in s)","E (in Ws)"]) # push header to outputArray
|
||||
|
||||
row=[movingSection.length, movingSection.t, movingSection.E]
|
||||
row=[movingSection[:length], movingSection[:t], movingSection[:E]]
|
||||
push!(outputArray, row) # push row to outputArray
|
||||
elseif settings.detailOfOutput=="driving course"
|
||||
elseif settings[:detailOfOutput]=="driving course"
|
||||
push!(outputArray, ["i", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_consist (in N)", "ΔW (in Ws)","W (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]) # push header to outputArray
|
||||
for point in drivingCourse
|
||||
row=[point.i, point.Δs, point.s, point.Δt, point.t, point.Δv, point.v, point.F_T, point.F_R, point.R_path, point.R_train, point.R_traction, point.R_consist, point.ΔW, point.W, point.ΔE, point.E, point.a]
|
||||
|
@ -62,29 +63,29 @@ function createOutputDict(settings::Settings, pathName::String, trainName::Strin
|
|||
end
|
||||
end
|
||||
|
||||
if 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))
|
||||
if 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))
|
||||
else
|
||||
merge!(outputDict, Dict("outputArrayMinimumRunningTime"=>outputArray))
|
||||
merge!(outputDict, Dict(:outputArrayMinimumRunningTime => outputArray))
|
||||
end
|
||||
|
||||
println("The output dictionary has been created for ",operationMode,".")
|
||||
println("The output dictionary has been created for ", operationMode,".")
|
||||
return outputDict
|
||||
end # function createOutputDict
|
||||
|
||||
function createOutputDict(settings::Settings, pathName::String, trainName::String, drivingCourseMinimumRunningTime::Vector{DataPoint}, movingSectionMinimumRunningTime::MovingSection, drivingCourseMinimumEnergyConsumption::Vector{DataPoint}, movingSectionMinimumEnergyConsumption::MovingSection)
|
||||
function createOutputDict(settings::Dict, pathName::String, trainName::String, drivingCourseMinimumRunningTime::Vector{DataPoint}, movingSectionMinimumRunningTime::Dict, drivingCourseMinimumEnergyConsumption::Vector{DataPoint}, movingSectionMinimumEnergyConsumption::Dict)
|
||||
# method of function createOutputDict for two operation modes
|
||||
if settings.operationModeMinimumRunningTime
|
||||
if settings[:operationModeMinimumRunningTime]
|
||||
outputDict=createOutputDict(settings, pathName, trainName, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime)
|
||||
|
||||
if settings.operationModeMinimumEnergyConsumption
|
||||
if settings[:operationModeMinimumEnergyConsumption]
|
||||
# creating the second output array
|
||||
outputArrayMinimumEnergyConsumption=Array{Any, 1}[]
|
||||
if settings.detailOfOutput=="minimal"
|
||||
if settings[:detailOfOutput]=="minimal"
|
||||
push!(outputArrayMinimumEnergyConsumption, ["s (in m)", "t (in s)","E (in Ws)"]) # push header to outputArrayMinimumEnergyConsumption
|
||||
row=[movingSectionMinimumEnergyConsumption.length, movingSectionMinimumEnergyConsumption.t, movingSectionMinimumEnergyConsumption.E]
|
||||
row=[movingSectionMinimumEnergyConsumption[:length], movingSectionMinimumEnergyConsumption[:t], movingSectionMinimumEnergyConsumption[:E]]
|
||||
push!(outputArrayMinimumEnergyConsumption, row) # push row to outputArrayMinimumEnergyConsumption
|
||||
elseif settings.detailOfOutput=="driving course"
|
||||
elseif settings[:detailOfOutput]=="driving course"
|
||||
push!(outputArrayMinimumEnergyConsumption, ["i", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_consist (in N)", "ΔW (in Ws)","W (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]) # push header to outputArrayMinimumEnergyConsumption
|
||||
for point in drivingCourseMinimumEnergyConsumption
|
||||
row=[point.i, point.Δs, point.s, point.Δt, point.t, point.Δv, point.v, point.F_T, point.F_R, point.R_path, point.R_train, point.R_traction, point.R_consist, point.ΔW, point.W, point.ΔE, point.E, point.a]
|
||||
|
@ -92,7 +93,7 @@ function createOutputDict(settings::Settings, pathName::String, trainName::Strin
|
|||
end
|
||||
end
|
||||
|
||||
merge!(outputDict, Dict("outputArrayMinimumEnergyConsumption"=>outputArrayMinimumEnergyConsumption))
|
||||
merge!(outputDict, Dict(:outputArrayMinimumEnergyConsumption => outputArrayMinimumEnergyConsumption))
|
||||
end
|
||||
else
|
||||
outputDict=createOutputDict(settings, pathName, trainName, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||
|
@ -103,36 +104,36 @@ function createOutputDict(settings::Settings, pathName::String, trainName::Strin
|
|||
end # function createOutputDict
|
||||
|
||||
|
||||
function createOutputCsv(settings::Settings, pathName::String, trainName::String, drivingCourse::Vector{DataPoint}, movingSection::MovingSection)
|
||||
function createOutputCsv(settings::Dict, pathName::String, trainName::String, drivingCourse::Vector{DataPoint}, movingSection::Dict)
|
||||
# method of function createOutputDict for one operation mode
|
||||
outputDict=createOutputDict(settings, pathName, trainName, drivingCourse, movingSection)
|
||||
|
||||
if length(movingSection.energySavingModifications)>0 # if the moving section hast energy saving modifications the moving section is modified for minimum energy consumption
|
||||
if length(movingSection[:energySavingModifications])>0 # if the moving section hast energy saving modifications the moving section is modified for minimum energy consumption
|
||||
operationMode="minimum energy consumption"
|
||||
outputArray="outputArrayMinimumEnergyConsumption"
|
||||
outputArray=:outputArrayMinimumEnergyConsumption
|
||||
date = Dates.now()
|
||||
dateString=Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
|
||||
csvFilePath=settings.csvDirectory*"/"*dateString*"_MinimumEnergyConsumption.csv"
|
||||
csvFilePath=settings[:csvDirectory]*"/"*dateString*"_MinimumEnergyConsumption.csv"
|
||||
else
|
||||
operationMode="minimum running time"
|
||||
outputArray="outputArrayMinimumRunningTime"
|
||||
outputArray=:outputArrayMinimumRunningTime
|
||||
date = Dates.now()
|
||||
dateString=Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
|
||||
csvFilePath=settings.csvDirectory*"/"*dateString*"_MinimumRunningTime.csv"
|
||||
csvFilePath=settings[:csvDirectory]*"/"*dateString*"_MinimumRunningTime.csv"
|
||||
end
|
||||
|
||||
# creating information block
|
||||
infoColumns=Array{Any,1}[]
|
||||
push!(infoColumns, ["path name", "train name", "operation mode", "mass model", "step variable", "step size", ""])
|
||||
push!(infoColumns, [pathName, trainName, operationMode, settings.massModel, settings.stepVariable, string(settings.stepSize), ""])
|
||||
push!(infoColumns, [pathName, trainName, operationMode, settings[:massModel], settings[:stepVariable], string(settings[:stepSize]), ""])
|
||||
for column in 3:length(outputDict[outputArray][1])
|
||||
push!(infoColumns, ["", "", "", "", "", "", ""])
|
||||
end # for
|
||||
|
||||
allColumns=Array{Any,1}[]
|
||||
if settings.detailOfOutput=="minimal"
|
||||
header=outputDict["outputArrayMinimumRunningTime"][1]
|
||||
elseif settings.detailOfOutput=="driving course"
|
||||
if settings[:detailOfOutput]=="minimal"
|
||||
header=outputDict[:outputArrayMinimumRunningTime][1]
|
||||
elseif settings[:detailOfOutput]=="driving course"
|
||||
header=["i", "Delta s (in m)", "s (in m)", "Delta t (in s)","t (in s)","Delta v (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_consist (in N)"," Delta W (in Ws)","W (in Ws)","Delta E (in Ws)","E (in Ws)","a (in m/s^2)"]
|
||||
end
|
||||
for column in 1:length(outputDict[outputArray][1])
|
||||
|
@ -145,9 +146,9 @@ function createOutputCsv(settings::Settings, pathName::String, trainName::String
|
|||
|
||||
|
||||
# combining the columns in a data frame and saving it as a CSV-file at csvDirectory
|
||||
if settings.detailOfOutput=="minimal"
|
||||
if settings[:detailOfOutput]=="minimal"
|
||||
df=DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3])
|
||||
elseif settings.detailOfOutput=="driving course"
|
||||
elseif settings[:detailOfOutput]=="driving course"
|
||||
df=DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3], c4=allColumns[4], c5=allColumns[5], c6=allColumns[6], c7=allColumns[7], c8=allColumns[8], c9=allColumns[9], c10=allColumns[10], c11=allColumns[11], c12=allColumns[12], c13=allColumns[13], c14=allColumns[14], c15=allColumns[15], c16=allColumns[16], c17=allColumns[17], c18=allColumns[18])
|
||||
end
|
||||
CSV.write(csvFilePath, df, header=false)
|
||||
|
@ -156,89 +157,89 @@ function createOutputCsv(settings::Settings, pathName::String, trainName::String
|
|||
return outputDict
|
||||
end #function createOutputCsv
|
||||
|
||||
function createOutputCsv(settings::Settings, pathName::String, trainName::String, drivingCourseMinimumRunningTime::Vector{DataPoint}, movingSectionMinimumRunningTime::MovingSection, drivingCourseMinimumEnergyConsumption::Vector{DataPoint}, movingSectionMinimumEnergyConsumption::MovingSection)
|
||||
function createOutputCsv(settings::Dict, pathName::String, trainName::String, drivingCourseMinimumRunningTime::Vector{DataPoint}, movingSectionMinimumRunningTime::Dict, drivingCourseMinimumEnergyConsumption::Vector{DataPoint}, movingSectionMinimumEnergyConsumption::Dict)
|
||||
# method of function createOutputDict for two operation modes
|
||||
outputDict=createOutputDict(settings, pathName, trainName, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||
|
||||
if settings.operationModeMinimumRunningTime
|
||||
if settings[:operationModeMinimumRunningTime]
|
||||
#creating information block
|
||||
infoColumns=Array{Any,1}[]
|
||||
push!(infoColumns, ["path name", "train name", "operation mode", "mass model", "step variable", "step size", ""])
|
||||
#push!(infoColumns, [pathName, trainName, "minimum running time", settings.massModel, settings.stepVariable, settings.stepSize, ""])
|
||||
push!(infoColumns, [pathName, trainName, "minimum running time", settings.massModel, settings.stepVariable, string(settings.stepSize), ""])
|
||||
#push!(infoColumns, [pathName, trainName, "minimum running time", settings[:massModel], settings[:stepVariable], settings[:stepSize], ""])
|
||||
push!(infoColumns, [pathName, trainName, "minimum running time", settings[:massModel], settings[:stepVariable], string(settings[:stepSize]), ""])
|
||||
|
||||
for column in 3:length(outputDict["outputArrayMinimumRunningTime"][1])
|
||||
for column in 3:length(outputDict[:outputArrayMinimumRunningTime][1])
|
||||
push!(infoColumns, ["", "", "", "", "", "", ""])
|
||||
# println("push wird ausgeführt")
|
||||
end # for
|
||||
|
||||
allColumns=Array{Any,1}[]
|
||||
if settings.detailOfOutput=="minimal"
|
||||
header=outputDict["outputArrayMinimumRunningTime"][1]
|
||||
elseif settings.detailOfOutput=="driving course"
|
||||
if settings[:detailOfOutput]=="minimal"
|
||||
header=outputDict[:outputArrayMinimumRunningTime][1]
|
||||
elseif settings[:detailOfOutput]=="driving course"
|
||||
header=["i", "Delta s (in m)", "s (in m)", "Delta t (in s)","t (in s)","Delta v (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_consist (in N)"," Delta W (in Ws)","W (in Ws)","Delta E (in Ws)","E (in Ws)","a (in m/s^2)"]
|
||||
end
|
||||
|
||||
for column in 1:length(outputDict["outputArrayMinimumRunningTime"][1])
|
||||
for column in 1:length(outputDict[:outputArrayMinimumRunningTime][1])
|
||||
push!(infoColumns[column], header[column])
|
||||
for row in outputDict["outputArrayMinimumRunningTime"][2:end]
|
||||
for row in outputDict[:outputArrayMinimumRunningTime][2:end]
|
||||
push!(infoColumns[column], row[column])
|
||||
end
|
||||
push!(allColumns, infoColumns[column])
|
||||
end # for
|
||||
|
||||
#combining the columns in a data frame and saving it as a CSV-file at csvDirectory
|
||||
if settings.detailOfOutput=="minimal"
|
||||
if settings[:detailOfOutput]=="minimal"
|
||||
df=DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3])
|
||||
elseif settings.detailOfOutput=="driving course"
|
||||
elseif settings[:detailOfOutput]=="driving course"
|
||||
df=DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3], c4=allColumns[4], c5=allColumns[5], c6=allColumns[6], c7=allColumns[7], c8=allColumns[8], c9=allColumns[9], c10=allColumns[10], c11=allColumns[11], c12=allColumns[12], c13=allColumns[13], c14=allColumns[14], c15=allColumns[15], c16=allColumns[16], c17=allColumns[17], c18=allColumns[18])
|
||||
end
|
||||
date = Dates.now()
|
||||
dateString=Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
|
||||
csvFilePath=settings.csvDirectory*"/"*dateString*"_dataMinimumRunningTime.csv"
|
||||
csvFilePath=settings[:csvDirectory]*"/"*dateString*"_dataMinimumRunningTime.csv"
|
||||
CSV.write(csvFilePath, df, header=false)
|
||||
println("The output CSV file has been created for minimum running time at ",csvFilePath)
|
||||
end #if settings.operationModeMinimumRunningTime
|
||||
end #if settings[:operationModeMinimumRunningTime]
|
||||
|
||||
|
||||
if settings.operationModeMinimumEnergyConsumption
|
||||
if settings[:operationModeMinimumEnergyConsumption]
|
||||
#creating information block
|
||||
infoColumns=Array{Any,1}[]
|
||||
push!(infoColumns, ["path name", "train name", "operation mode", "mass model", "step variable", "step size", ""])
|
||||
push!(infoColumns, [pathName, trainName, "minimum energy consumption", settings.massModel, settings.stepVariable, settings.stepSize, ""])
|
||||
for column in 3:length(outputDict["outputArrayMinimumEnergyConsumption"][1])
|
||||
push!(infoColumns, [pathName, trainName, "minimum energy consumption", settings[:massModel], settings[:stepVariable], settings[:stepSize], ""])
|
||||
for column in 3:length(outputDict[:outputArrayMinimumEnergyConsumption][1])
|
||||
push!(infoColumns, ["", "", "", "", "", "", ""])
|
||||
end # for
|
||||
|
||||
allColumns=Array{Any,1}[]
|
||||
if settings.detailOfOutput=="minimal"
|
||||
header=outputDict["outputArrayMinimumRunningTime"][1]
|
||||
elseif settings.detailOfOutput=="driving course"
|
||||
if settings[:detailOfOutput]=="minimal"
|
||||
header=outputDict[:outputArrayMinimumRunningTime][1]
|
||||
elseif settings[:detailOfOutput]=="driving course"
|
||||
header=["i", "Delta s (in m)", "s (in m)", "Delta t (in s)","t (in s)","Delta v (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_consist (in N)"," Delta W (in Ws)","W (in Ws)","Delta E (in Ws)","E (in Ws)","a (in m/s^2)"]
|
||||
end
|
||||
|
||||
for column in 1:length(outputDict["outputArrayMinimumEnergyConsumption"][1])
|
||||
for column in 1:length(outputDict[:outputArrayMinimumEnergyConsumption][1])
|
||||
push!(infoColumns[column], header[column])
|
||||
for row in outputDict["outputArrayMinimumEnergyConsumption"][2:end]
|
||||
for row in outputDict[:outputArrayMinimumEnergyConsumption][2:end]
|
||||
push!(infoColumns[column], row[column])
|
||||
end
|
||||
push!(allColumns, infoColumns[column])
|
||||
end # for
|
||||
|
||||
#combining the columns in a data frame
|
||||
if settings.detailOfOutput=="minimal"
|
||||
if settings[:detailOfOutput]=="minimal"
|
||||
df=DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3])
|
||||
elseif settings.detailOfOutput=="driving course"
|
||||
elseif settings[:detailOfOutput]=="driving course"
|
||||
df=DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3], c4=allColumns[4], c5=allColumns[5], c6=allColumns[6], c7=allColumns[7], c8=allColumns[8], c9=allColumns[9], c10=allColumns[10], c11=allColumns[11], c12=allColumns[12], c13=allColumns[13], c14=allColumns[14], c15=allColumns[15], c16=allColumns[16], c17=allColumns[17], c18=allColumns[18])
|
||||
end
|
||||
|
||||
# creating a CSV-file at csvDirectory
|
||||
date = Dates.now()
|
||||
dateString=Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
|
||||
csvFilePath=settings.csvDirectory*"/"*dateString*"_dataMinimumEnergyConsumption.csv"
|
||||
csvFilePath=settings[:csvDirectory]*"/"*dateString*"_dataMinimumEnergyConsumption.csv"
|
||||
CSV.write(csvFilePath, df, header=false)
|
||||
println("The output CSV file has been created for minimum energy consumption at ",csvFilePath)
|
||||
end # if settings.operationModeMinimumEnergyConsumption
|
||||
end # if settings[:operationModeMinimumEnergyConsumption]
|
||||
|
||||
return outputDict
|
||||
end #function createOutputCsv
|
||||
|
@ -253,16 +254,18 @@ function printImportantValues(drivingCourse::Vector{DataPoint})
|
|||
println("i s in m v in km/h t in min a in m/s^2 F_R in k N F_T in k N E in k Wh")
|
||||
end #function printImportantValues
|
||||
|
||||
function printSectionInformation(movingSection::MovingSection)
|
||||
println("MS mit length=", movingSection.length," mit t=", movingSection.t)
|
||||
allBs=["breakFree", "clearing", "acceleration", "cruising", "diminishing", "coasting","cruisingAfterCoasting", "braking", "standStill"]
|
||||
for csId in 1:length(movingSection.characteristicSections)
|
||||
println("CS ",csId," mit length=", movingSection.characteristicSections[csId].length," mit t=", movingSection.characteristicSections[csId].t)
|
||||
function printSectionInformation(movingSection::Dict)
|
||||
CSs::Vector{CharacteristicSection} = movingSection[:characteristicSections]
|
||||
|
||||
println("MS mit length=", movingSection[:length]," mit t=", movingSection[:t])
|
||||
allBs=[:breakFree, :clearing, :acceleration, :cruising, :diminishing, :coasting, :cruisingAfterCoasting, :braking, :standStill]
|
||||
for csId in 1:length(CSs)
|
||||
println("CS ",csId," mit length=", CSs[csId].length," mit t=", CSs[csId].t)
|
||||
for bs in 1: length(allBs)
|
||||
if haskey(movingSection.characteristicSections[csId].behaviorSections, allBs[bs])
|
||||
println("BS ",allBs[bs], " mit s_entry=",get(movingSection.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).s_entry, " und t=",get(movingSection.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).t)
|
||||
# for point in 1:length(get(movingSection.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).dataPoints)
|
||||
# println(get(movingSection.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).dataPoints[point])
|
||||
if haskey(CSs[csId].behaviorSections, allBs[bs])
|
||||
println("BS ",allBs[bs], " mit s_entry=", CSs[csId].behaviorSections[allBs[bs]].s_entry, " und t=", CSs[csId].behaviorSections[allBs[bs]].t)
|
||||
# for point in 1:length(CSs[csId].behaviorSections[allBs[bs]].dataPoints)
|
||||
# println(CSs[csId].behaviorSections[allBs[bs]].dataPoints[point])
|
||||
# end
|
||||
end #if
|
||||
end #for
|
||||
|
@ -287,21 +290,21 @@ function plotDrivingCourse(drivingCourse::Vector{DataPoint})
|
|||
|
||||
p2=plot([t], [v], title = "v in m/s", label = ["v"], xlabel = "t in s")
|
||||
|
||||
# p3=plot([s], [t], title = "t in s", label = ["t"], xlabel = "s in m")
|
||||
# p3=plot([s], [t], title = "t in s", label = ["t"], xlabel = "s in m")
|
||||
|
||||
# p4=plot([t], [s], title = "s in m", label = ["s"], xlabel = "t in s")
|
||||
# p4=plot([t], [s], title = "s in m", label = ["s"], xlabel = "t in s")
|
||||
|
||||
p5=plot([s], [E], title = "E in Ws", label = ["E"], xlabel = "s in m")
|
||||
|
||||
p6=plot([t], [E], title = "E in Ws", label = ["E"], xlabel = "t in s")
|
||||
|
||||
all=plot(p1, p2, p5, p6, layout = (2, 2), legend = false)
|
||||
# all=plot(p1, p2, p3, p4, p5, p6, layout = (3, 2), legend = false)
|
||||
# all=plot(p1, p2, p3, p4, p5, p6, layout = (3, 2), legend = false)
|
||||
display(all)
|
||||
println("Plots for different variables have been created.")
|
||||
end #function plotDrivingCourse
|
||||
|
||||
function plotDrivingCourse(drivingCourseMinimumRunningTime::Vector{DataPoint},drivingCourseMinimumEnergyConsumption::Vector{DataPoint}) #,movingSection1::MovingSection,movingSection2::MovingSection)
|
||||
function plotDrivingCourse(drivingCourseMinimumRunningTime::Vector{DataPoint},drivingCourseMinimumEnergyConsumption::Vector{DataPoint})
|
||||
a_minTime=[]
|
||||
E_minTime=[]
|
||||
s_minTime=[]
|
||||
|
@ -340,17 +343,17 @@ function plotDrivingCourse(drivingCourseMinimumRunningTime::Vector{DataPoint},dr
|
|||
label = ["v for t_min" "v for E_min"],
|
||||
xlabel = "t in s")
|
||||
|
||||
# p3=plot([s_minTime,s_minEnergy],
|
||||
# [t_minTime,t_minEnergy],
|
||||
# title = "t in s",
|
||||
# label = ["t for t_min" "t for E_min"],
|
||||
# xlabel = "s in m")
|
||||
# p3=plot([s_minTime,s_minEnergy],
|
||||
# [t_minTime,t_minEnergy],
|
||||
# title = "t in s",
|
||||
# label = ["t for t_min" "t for E_min"],
|
||||
# xlabel = "s in m")
|
||||
|
||||
# p4=plot([t_minTime,t_minEnergy],
|
||||
# [s_minTime,s_minEnergy],
|
||||
# title = "s in m",
|
||||
# label = ["s for t_min" "s for E_min"],
|
||||
# xlabel = "t in s")
|
||||
# p4=plot([t_minTime,t_minEnergy],
|
||||
# [s_minTime,s_minEnergy],
|
||||
# title = "s in m",
|
||||
# label = ["s for t_min" "s for E_min"],
|
||||
# xlabel = "t in s")
|
||||
|
||||
p5=plot([s_minTime,s_minEnergy],
|
||||
[E_minTime,E_minEnergy],
|
||||
|
@ -364,7 +367,7 @@ function plotDrivingCourse(drivingCourseMinimumRunningTime::Vector{DataPoint},dr
|
|||
label = ["E for t_min" "E for E_min"],
|
||||
xlabel = "t in s")
|
||||
|
||||
# all=plot(p1, p2, p3, p4, p5, p6, layout = (3, 2), legend = false)
|
||||
# all=plot(p1, p2, p3, p4, p5, p6, layout = (3, 2), legend = false)
|
||||
all=plot(p1, p2, p5, p6, layout = (2, 2), legend = false)
|
||||
display(all)
|
||||
println("Plots for different variables have been created.")
|
||||
|
|
|
@ -7,49 +7,56 @@ using .MovingPhases
|
|||
export preparateSections
|
||||
|
||||
## create a moving section and its containing characteristic sections with securedd braking, acceleration and cruising behavior
|
||||
function preparateSections(path::Path, train::Train, settings::Settings)
|
||||
movingSection=createMovingSection(path, train.v_limit)
|
||||
movingSection=secureBrakingBehavior!(movingSection, train.a_braking)
|
||||
function preparateSections(path::Dict, train::Dict, settings::Dict)
|
||||
movingSection=createMovingSection(path, train[:v_limit])
|
||||
movingSection=secureBrakingBehavior!(movingSection, train[:a_braking])
|
||||
movingSection=secureAccelerationBehavior!(movingSection, settings, train)
|
||||
movingSection=secureCruisingBehavior!(movingSection, settings, train)
|
||||
return movingSection
|
||||
end #function preparateSections
|
||||
|
||||
## create a moving section containing characteristic sections
|
||||
function createMovingSection(path::Path, v_trainLimit::AbstractFloat)
|
||||
function createMovingSection(path::Dict, v_trainLimit::Real)
|
||||
# this function creates and returns a moving section dependent on the paths attributes
|
||||
movingSection=MovingSection()
|
||||
|
||||
movingSection.id=1 # identifier # if there is more than one moving section in a later version of this tool the id should not be constant anymore
|
||||
movingSection.t=0.0 # total running time (in s)
|
||||
movingSection.E=0.0 # total energy consumption (in Ws)
|
||||
s_entry = path[:sections][1][:s_start] # first position (in m)
|
||||
s_exit = path[:sections][end][:s_end] # last position (in m)
|
||||
pathLength = s_exit - s_entry # total length (in m)
|
||||
|
||||
movingSection.s_entry=path.sections[1].s_start # first position (in m)
|
||||
movingSection.s_exit=path.sections[length(path.sections)].s_end # last position (in m)
|
||||
movingSection.length=movingSection.s_exit-movingSection.s_entry # total length (in m)
|
||||
|
||||
s_csStart=movingSection.s_entry
|
||||
CSs=[]
|
||||
s_csStart=s_entry
|
||||
csId=1
|
||||
for row in 2:length(path.sections)
|
||||
if min(path.sections[row-1].v_limit, v_trainLimit) != min(path.sections[row].v_limit, v_trainLimit) || path.sections[row-1].f_Rp != path.sections[row].f_Rp
|
||||
push!(movingSection.characteristicSections, createCharacteristicSection(csId, s_csStart, path.sections[row-1], min(path.sections[row-1].v_limit, v_trainLimit)))
|
||||
s_csStart=path.sections[row].s_start
|
||||
for row in 2:length(path[:sections])
|
||||
if min(path[:sections][row-1][:v_limit], v_trainLimit) != min(path[:sections][row][:v_limit], v_trainLimit) || path[:sections][row-1][:f_Rp] != path[:sections][row][:f_Rp]
|
||||
push!(CSs, createCharacteristicSection(csId, s_csStart, path[:sections][row-1], min(path[:sections][row-1][:v_limit], v_trainLimit)))
|
||||
s_csStart=path[:sections][row][:s_start]
|
||||
csId=csId+1
|
||||
end #if
|
||||
end #for
|
||||
push!(movingSection.characteristicSections, createCharacteristicSection(csId, s_csStart, path.sections[end], min(path.sections[end].v_limit, v_trainLimit)))
|
||||
push!(CSs, createCharacteristicSection(csId, s_csStart, path[:sections][end], min(path[:sections][end][:v_limit], v_trainLimit)))
|
||||
|
||||
movingSection= Dict(:id => 1, # identifier # if there is more than one moving section in a later version of this tool the id should not be constant anymore
|
||||
:length => pathLength, # total length (in m)
|
||||
:s_entry => s_entry, # first position (in m)
|
||||
:s_exit => s_exit, # last position (in m)
|
||||
:t => 0.0, # total running time (in s)
|
||||
:E => 0.0, # total energy consumption (in Ws)
|
||||
:t_recovery => 0.0, # total recovery time for energy-saving modifications (in s)
|
||||
: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
|
||||
end #function createMovingSection
|
||||
|
||||
|
||||
## create a characteristic section for a path section
|
||||
function createCharacteristicSection(csId::Integer, s_csStart::AbstractFloat, section::PathSection, v_csLimit::AbstractFloat)
|
||||
function createCharacteristicSection(csId::Integer, s_csStart::Real, section::Dict, v_csLimit::Real)
|
||||
# this function creates and returns a characteristic section dependent on the paths attributes
|
||||
characteristicSection=CharacteristicSection()
|
||||
characteristicSection.id=csId # identifier
|
||||
characteristicSection.s_entry=s_csStart # first position (in m)
|
||||
characteristicSection.s_exit=section.s_end # last position (in m)
|
||||
characteristicSection.s_exit=section[:s_end] # last position (in m)
|
||||
characteristicSection.length=characteristicSection.s_exit-characteristicSection.s_entry # total length (in m)
|
||||
characteristicSection.t=0.0 # total running time (in s)
|
||||
characteristicSection.E=0.0 # total energy consumption (in Ws)
|
||||
|
@ -60,55 +67,59 @@ function createCharacteristicSection(csId::Integer, s_csStart::AbstractFloat, se
|
|||
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.f_Rp=section.f_Rp # path resistance (in ‰)
|
||||
characteristicSection.f_Rp=section[:f_Rp] # path resistance (in ‰)
|
||||
|
||||
return characteristicSection
|
||||
end #function createCharacteristicSection
|
||||
|
||||
## define the intersection velocities between the characterisitc sections to secure braking behavior
|
||||
function secureBrakingBehavior!(movingSection::MovingSection, a_braking::AbstractFloat)
|
||||
function secureBrakingBehavior!(movingSection::Dict, a_braking::Real)
|
||||
# this function limits the entry and exit velocity of the characteristic sections to secure that the train stops at the moving sections end
|
||||
csId=length(movingSection.characteristicSections)
|
||||
movingSection.characteristicSections[csId].v_exit=0.0 # the exit velocity of the last characteristic section is 0.0 m/s
|
||||
CSs::Vector{CharacteristicSection} = movingSection[:characteristicSections]
|
||||
|
||||
csId=length(CSs)
|
||||
CSs[csId].v_exit=0.0 # the exit velocity of the last characteristic section is 0.0 m/s
|
||||
while csId >= 1
|
||||
v_entryMax=sqrt(movingSection.characteristicSections[csId].v_exit^2-2*a_braking*movingSection.characteristicSections[csId].length)
|
||||
v_entryMax=sqrt(CSs[csId].v_exit^2-2*a_braking*CSs[csId].length)
|
||||
v_entryMax=floor(v_entryMax, digits=12)
|
||||
|
||||
movingSection.characteristicSections[csId].v_entry=min(movingSection.characteristicSections[csId].v_limit, v_entryMax)
|
||||
movingSection.characteristicSections[csId].v_target=movingSection.characteristicSections[csId].v_entry
|
||||
CSs[csId].v_entry=min(CSs[csId].v_limit, v_entryMax)
|
||||
CSs[csId].v_target=CSs[csId].v_entry
|
||||
csId=csId-1
|
||||
if csId >= 1
|
||||
movingSection.characteristicSections[csId].v_exit=min(movingSection.characteristicSections[csId].v_limit, movingSection.characteristicSections[csId+1].v_entry)
|
||||
CSs[csId].v_exit=min(CSs[csId].v_limit, CSs[csId+1].v_entry)
|
||||
end #if
|
||||
end #while
|
||||
return movingSection
|
||||
end #function secureBrakingBehavior!
|
||||
|
||||
## define the intersection velocities between the characterisitc sections to secure acceleration behavior
|
||||
function secureAccelerationBehavior!(movingSection::MovingSection, settings::Settings, train::Train)
|
||||
function secureAccelerationBehavior!(movingSection::Dict, settings::Dict, train::Dict)
|
||||
# this function limits the entry and exit velocity of the characteristic sections in case that the train accelerates in every section and cruises aterwards
|
||||
movingSection.characteristicSections[1].v_entry=0.0 # the entry velocity of the first characteristic section is 0.0 m/s
|
||||
CSs::Vector{CharacteristicSection} = movingSection[:characteristicSections]
|
||||
|
||||
CSs[1].v_entry=0.0 # the entry velocity of the first characteristic section is 0.0 m/s
|
||||
startingPoint=DataPoint()
|
||||
startingPoint.i=1
|
||||
|
||||
previousCSv_exit=movingSection.characteristicSections[1].v_entry
|
||||
for csId in 1:length(movingSection.characteristicSections)
|
||||
movingSection.characteristicSections[csId].v_entry=min(movingSection.characteristicSections[csId].v_entry, previousCSv_exit)
|
||||
previousCSv_exit=CSs[1].v_entry
|
||||
for csId in 1:length(CSs)
|
||||
CSs[csId].v_entry=min(CSs[csId].v_entry, previousCSv_exit)
|
||||
|
||||
startingPoint.s=movingSection.characteristicSections[csId].s_entry
|
||||
startingPoint.v=movingSection.characteristicSections[csId].v_entry
|
||||
startingPoint.s=CSs[csId].s_entry
|
||||
startingPoint.v=CSs[csId].v_entry
|
||||
accelerationCourse=[startingPoint] # List of data points
|
||||
|
||||
if movingSection.characteristicSections[csId].v_entry<movingSection.characteristicSections[csId].v_target
|
||||
(movingSection.characteristicSections[csId], accelerationCourse)=addAccelerationPhase!(movingSection.characteristicSections[csId], accelerationCourse, settings, train, movingSection.characteristicSections) # this function changes the accelerationCourse
|
||||
movingSection.characteristicSections[csId].v_target=max(movingSection.characteristicSections[csId].v_entry,accelerationCourse[end].v)
|
||||
if CSs[csId].v_entry<CSs[csId].v_target
|
||||
(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)
|
||||
|
||||
movingSection.characteristicSections[csId].v_exit=min(movingSection.characteristicSections[csId].v_exit, movingSection.characteristicSections[csId].v_target, accelerationCourse[end].v)
|
||||
else #movingSection.characteristicSections[csId].v_entry==movingSection.characteristicSections[csId].v_target
|
||||
CSs[csId].v_exit=min(CSs[csId].v_exit, CSs[csId].v_target, accelerationCourse[end].v)
|
||||
else #CSs[csId].v_entry==CSs[csId].v_target
|
||||
# v_exit stays the same
|
||||
end #if
|
||||
|
||||
previousCSv_exit=movingSection.characteristicSections[csId].v_exit
|
||||
previousCSv_exit=CSs[csId].v_exit
|
||||
end #for
|
||||
|
||||
return movingSection
|
||||
|
@ -117,24 +128,26 @@ end #function secureAccelerationBehavior!
|
|||
|
||||
|
||||
## define the intersection velocities between the characterisitc sections to secure cruising behavior
|
||||
function secureCruisingBehavior!(movingSection::MovingSection, settings::Settings, train::Train)
|
||||
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
|
||||
CSs::Vector{CharacteristicSection} = movingSection[:characteristicSections]
|
||||
|
||||
startingPoint=DataPoint()
|
||||
startingPoint.i=1
|
||||
|
||||
previousCSv_exit=movingSection.characteristicSections[1].v_entry
|
||||
previousCSv_exit=CSs[1].v_entry
|
||||
|
||||
for csId in 1:length(movingSection.characteristicSections)
|
||||
movingSection.characteristicSections[csId].v_entry=min(movingSection.characteristicSections[csId].v_entry, previousCSv_exit)
|
||||
for csId in 1:length(CSs)
|
||||
CSs[csId].v_entry=min(CSs[csId].v_entry, previousCSv_exit)
|
||||
|
||||
startingPoint.s=movingSection.characteristicSections[csId].s_entry
|
||||
startingPoint.v=movingSection.characteristicSections[csId].v_target
|
||||
startingPoint.s=CSs[csId].s_entry
|
||||
startingPoint.v=CSs[csId].v_target
|
||||
cruisingCourse=[startingPoint] # List of data points
|
||||
|
||||
(movingSection.characteristicSections[csId], cruisingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], cruisingCourse, movingSection.characteristicSections[csId].length, settings, train, movingSection.characteristicSections, "cruising") # this function changes the cruisingCourse
|
||||
movingSection.characteristicSections[csId].v_exit=min(movingSection.characteristicSections[csId].v_exit, cruisingCourse[end].v)
|
||||
(CSs[csId], cruisingCourse)=addCruisingPhase!(CSs[csId], cruisingCourse, CSs[csId].length, settings, train, CSs, "cruising") # this function changes the cruisingCourse
|
||||
CSs[csId].v_exit=min(CSs[csId].v_exit, cruisingCourse[end].v)
|
||||
|
||||
previousCSv_exit=movingSection.characteristicSections[csId].v_exit
|
||||
previousCSv_exit=CSs[csId].v_exit
|
||||
end #for
|
||||
|
||||
return movingSection
|
||||
|
|
|
@ -41,7 +41,7 @@ function calculateDrivingDynamics(trainDirectory::String, pathDirectory::String,
|
|||
movingSection=preparateSections(path, train, settings)
|
||||
println("The moving section has been prepared.")
|
||||
|
||||
if settings.operationModeMinimumRunningTime==true || settings.operationModeMinimumEnergyConsumption==true
|
||||
if settings[:operationModeMinimumRunningTime] ==true || settings[:operationModeMinimumEnergyConsumption] ==true
|
||||
(movingSectionMinimumRunningTime, drivingCourseMinimumRunningTime)=calculateMinimumRunningTime!(movingSection, settings, train)
|
||||
# println("t=", drivingCourseMinimumRunningTime[end].t)
|
||||
# printSectionInformation(movingSectionMinimumRunningTime)
|
||||
|
@ -50,22 +50,22 @@ function calculateDrivingDynamics(trainDirectory::String, pathDirectory::String,
|
|||
|
||||
|
||||
# oparation mode "minimum energy consumption"
|
||||
if settings.operationModeMinimumEnergyConsumption==true
|
||||
if settings[:operationModeMinimumEnergyConsumption] == true
|
||||
(movingSectionMinimumEnergyConsumption, drivingCourseMinimumEnergyConsumption)=calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime, drivingCourseMinimumRunningTime, settings, train)
|
||||
# printSectionInformation(movingSectionMinimumEnergyConsumption)
|
||||
println("The driving course for the lowest energy consumption has been calculated.")
|
||||
end #if
|
||||
|
||||
#output
|
||||
if settings.operationModeMinimumRunningTime==true && settings.operationModeMinimumEnergyConsumption==true
|
||||
if settings[:operationModeMinimumRunningTime] == true && settings[:operationModeMinimumEnergyConsumption] == true
|
||||
plotDrivingCourse(drivingCourseMinimumRunningTime, drivingCourseMinimumEnergyConsumption)
|
||||
return createOutput(settings, path.name, train.name, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||
elseif settings.operationModeMinimumRunningTime==true
|
||||
return createOutput(settings, path[:name], train[:name], drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||
elseif settings[:operationModeMinimumRunningTime] == true
|
||||
plotDrivingCourse(drivingCourseMinimumRunningTime)
|
||||
return createOutput(settings, path.name, train.name, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime)
|
||||
elseif settings.operationModeMinimumEnergyConsumption==true
|
||||
return createOutput(settings, path[:name], train[:name], drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime)
|
||||
elseif settings[:operationModeMinimumEnergyConsumption] == true
|
||||
plotDrivingCourse(drivingCourseMinimumEnergyConsumption)
|
||||
return createOutput(settings, path.name, train.name, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||
return createOutput(settings, path[:name], train[:name], drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||
else
|
||||
println("No Output was demanded. So no output is created.")
|
||||
return Dict()
|
||||
|
|
111
src/types.jl
111
src/types.jl
|
@ -1,78 +1,6 @@
|
|||
module types
|
||||
# definition of all the additional types and their constructors
|
||||
export Settings, Train, PathSection, Path, DataPoint, BehaviorSection, CharacteristicSection, EnergySavingModification, MovingSection # tried to insert copy on 15.07.2021 , copy
|
||||
|
||||
## settings for the calculation
|
||||
mutable struct Settings
|
||||
massModel::String # model type of the trains mass "mass point" or "homogeneous strip"
|
||||
stepVariable::String # step variable of the step method "s in m", "t in s" or "v in m/s"
|
||||
stepSize::AbstractFloat # step size (unit depends on steapVariable s in m, t in s and v in m/s)
|
||||
operationModeMinimumRunningTime::Bool # operation mode "minimum running time"
|
||||
operationModeMinimumEnergyConsumption::Bool # operation mode "minimum energy consumption"
|
||||
|
||||
# output:
|
||||
typeOfOutput::String # output as "julia dictionary" or as "CSV"
|
||||
csvDirectory::String # directory in which the CSV files will be saved
|
||||
detailOfOutput::String # detail of output "minimal" or "driving course"
|
||||
end # mutable struct Settings
|
||||
Settings()=Settings("", "", 0.0, false, false, "", "", "")
|
||||
|
||||
|
||||
## train
|
||||
mutable struct Train
|
||||
name::String # trains name
|
||||
id # trains identifier
|
||||
trainType::String # type of train "passenger" or "freight" or "motor coach train"
|
||||
l_train::AbstractFloat # total length (in m)
|
||||
v_limit::AbstractFloat # trains speed limit (in m/s)
|
||||
a_braking::AbstractFloat # braking acceleration (in m/s^2)
|
||||
m_train::AbstractFloat # total mass (in kg)
|
||||
ξ_train::AbstractFloat # rotation mass factor of the whole train (without unit)
|
||||
# if not available use ξ_t and ξ_w
|
||||
|
||||
# traction unit
|
||||
m_t::AbstractFloat # mass of the traction unit (in kg)
|
||||
m_td::AbstractFloat # mass on the traction units driving axles (in kg)
|
||||
m_tc::AbstractFloat # mass on the traction units carrying axles (in kg)
|
||||
ξ_t::AbstractFloat # rotation mass factor of the traction unit (without unit)
|
||||
# in case ξ_train is not available
|
||||
tractiveEffortVelocityPairs # list of velocities and their corresponding tractive effort (in [m/s , N])
|
||||
|
||||
f_Rtd0::AbstractFloat # coefficient for basic resistance due to the traction units driving axles (in ‰)
|
||||
f_Rtc0::AbstractFloat # coefficient for basic resistance due to the traction units carring axles (in ‰)
|
||||
F_Rt2::AbstractFloat # coefficient for air resistance of the traction units (in N)
|
||||
Δv_t::AbstractFloat # coefficient for velocitiy difference between traction unit and outdoor air
|
||||
|
||||
|
||||
# set of wagons
|
||||
m_w::AbstractFloat # mass of the set of wagons (in kg)
|
||||
ξ_w::AbstractFloat # rotation mass factor of the set of wagons (without unit)
|
||||
# in case ξ_train is not available
|
||||
f_Rw0::AbstractFloat # coefficient for basic resistance of the set of wagons (in ‰)
|
||||
f_Rw1::AbstractFloat # coefficient for resistance to rolling of the set of wagons (in ‰)
|
||||
f_Rw2::AbstractFloat # coefficient for air resistance of the set of wagons (in ‰)
|
||||
Δv_w::AbstractFloat # coefficient for velocitiy difference between set of wagons and outdoor air (in m/s)
|
||||
end # mutable struct Train
|
||||
Train()=Train("", 0, "", 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, [], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
|
||||
|
||||
|
||||
## path separated in smaler sections
|
||||
struct PathSection
|
||||
s_start::AbstractFloat # starting point of the section (in m)
|
||||
s_end::AbstractFloat # starting point of the next section (in m)
|
||||
v_limit::AbstractFloat # paths speed limt (in m/s)
|
||||
f_Rp::AbstractFloat # specific path resistance of the section (in ‰)
|
||||
end # struct pathSection
|
||||
PathSection()=(0.0, 0.0, 0.0, 0.0)
|
||||
|
||||
struct Path
|
||||
name::String # paths name
|
||||
id # paths identifier
|
||||
sections::Vector{PathSection} # list of PathSection elements
|
||||
# s_start in first entry defines the path's beginning
|
||||
# s_end in last entry defines the path's ending
|
||||
end # struct Path
|
||||
Path()=("", 0, Vector{PathSection}())
|
||||
export DataPoint, BehaviorSection, CharacteristicSection, EnergySavingModification
|
||||
|
||||
|
||||
## a data point is the smallest element of the driving course. One step of the step approach is between two data points
|
||||
|
@ -137,15 +65,15 @@ mutable struct CharacteristicSection
|
|||
v_entry::AbstractFloat # maximum entry speed (in m/s)
|
||||
v_exit::AbstractFloat # maximum exit speed (in m/s)
|
||||
f_Rp::AbstractFloat # spedific path resistance (in ‰)
|
||||
behaviorSections::AbstractDict{String, BehaviorSection} # list of containing behavior sections
|
||||
behaviorSections::AbstractDict{Symbol, BehaviorSection} # list of containing behavior sections
|
||||
end # mutable struct CharacteristicSection
|
||||
CharacteristicSection()=CharacteristicSection(0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Dict{String, BehaviorSection}())
|
||||
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)
|
||||
copy=CharacteristicSection(original.id, original.length, original.s_entry, original.s_exit, original.t, original.E, original.v_limit, original.v_target, original.v_entry, original.v_exit, original.f_Rp, Dict{String, BehaviorSection}())
|
||||
allBs=["breakFree", "clearing", "acceleration", "cruising", "diminishing", "coasting", "cruisingAfterCoasting", "braking", "standStill"]
|
||||
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}())
|
||||
allBs=[:breakFree, :clearing, :acceleration, :cruising, :diminishing, :coasting, :cruisingAfterCoasting, :braking, :standStill]
|
||||
for bs in 1: length(allBs)
|
||||
if haskey(original.behaviorSections, allBs[bs])
|
||||
merge!(copy.behaviorSections, Dict(allBs[bs]=>BehaviorSection(get(original.behaviorSections, allBs[bs], BehaviorSection()))))
|
||||
merge!(copy.behaviorSections, Dict(allBs[bs] => BehaviorSection(original.behaviorSections[allBs[bs]])))
|
||||
end #if
|
||||
end #for
|
||||
return copy
|
||||
|
@ -171,31 +99,4 @@ function EnergySavingModification(original::EnergySavingModification)
|
|||
return copy
|
||||
end #function EnergySavingModification
|
||||
|
||||
|
||||
## a moving section contains all the smaller sections from one stop to an other
|
||||
mutable struct MovingSection
|
||||
id # identifier
|
||||
length::AbstractFloat # total length (in m)
|
||||
s_entry::AbstractFloat # first position (in m)
|
||||
s_exit::AbstractFloat # last position (in m)
|
||||
t::AbstractFloat # total running time (in s)
|
||||
E::AbstractFloat # total energy consumption (in Ws)
|
||||
t_recovery::AbstractFloat # total recovery time for energy-saving modifications (in s)
|
||||
t_recoveryAvailable::AbstractFloat # still available recovery time for energy-saving modifications (in s)
|
||||
characteristicSections::Vector{CharacteristicSection} # list of containing characteristic sections
|
||||
energySavingModifications::Vector{EnergySavingModification} # list of containing all the used energy saving modifications
|
||||
end # mutable struct MovingSection
|
||||
MovingSection()=MovingSection(0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, [], [])
|
||||
|
||||
function MovingSection(original::MovingSection)
|
||||
copy=MovingSection(original.id, original.length, original.s_entry, original.s_exit, original.t, original.E, original.t_recovery, original.t_recoveryAvailable, [], [])
|
||||
for csId in 1:length(original.characteristicSections)
|
||||
push!(copy.characteristicSections, CharacteristicSection(original.characteristicSections[csId]))
|
||||
end #for
|
||||
for modId in 1:length(original.energySavingModifications)
|
||||
push!(copy.energySavingModifications, EnergySavingModification(original.energySavingModifications[modId]))
|
||||
end #for
|
||||
return copy
|
||||
end #function CharacteristicSection
|
||||
|
||||
end #module
|
||||
|
|
Loading…
Reference in New Issue