Refactor the mutable struct CharacteristicSection as a Dictionary
parent
e1ad3f917d
commit
28605abd4c
|
@ -89,35 +89,34 @@ function calculateRecoveryTime(s_MS::Real, t_MS::AbstractFloat, train::Dict)
|
|||
end # if train[:trainType]
|
||||
end #function calculateRecoveryTime
|
||||
|
||||
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)
|
||||
function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, allCSs::Vector{Dict}, t_recoveryAvailable::AbstractFloat)
|
||||
BSsOriginal = csOriginal[:behaviorSections]
|
||||
if (haskey(BSsOriginal, :cruising) || haskey(BSsOriginal, :diminishing)) && haskey(BSsOriginal, :braking)
|
||||
# check if cruising or diminishing should be reduced for coasting
|
||||
if haskey(csOriginal.behaviorSections, :cruising) && haskey(csOriginal.behaviorSections, :diminishing)
|
||||
if csOriginal.behaviorSections[:cruising].dataPoints[1] > csOriginal.behaviorSections[:diminishing].dataPoints[1]
|
||||
if haskey(BSsOriginal, :cruising) && haskey(BSsOriginal, :diminishing)
|
||||
if BSsOriginal[:cruising].dataPoints[1] > BSsOriginal[:diminishing].dataPoints[1]
|
||||
reduceCruising=true
|
||||
reduceDiminishing=false
|
||||
else
|
||||
reduceDiminishing=true
|
||||
reduceCruising=false
|
||||
end
|
||||
elseif haskey(csOriginal.behaviorSections, :cruising)
|
||||
elseif haskey(BSsOriginal, :cruising)
|
||||
reduceCruising=true
|
||||
reduceDiminishing=false
|
||||
elseif haskey(csOriginal.behaviorSections, :diminishing)
|
||||
elseif haskey(BSsOriginal, :diminishing)
|
||||
reduceDiminishing=true
|
||||
reduceCruising=false
|
||||
end
|
||||
|
||||
|
||||
|
||||
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
|
||||
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(BSsOriginal, :cruising, BehaviorSection()).dataPoints[1]
|
||||
if energySavingStartId==0
|
||||
error("ERROR at creating a new driving course for energy saving with coasting !")
|
||||
end
|
||||
|
@ -131,44 +130,59 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
|
|||
|
||||
# calculating the new length of the cruising section
|
||||
if settings[:stepVariable]=="s in m" # distance step method
|
||||
s_cruising = csOriginal.behaviorSections[:cruising].length - cruisingReduction
|
||||
s_cruising = BSsOriginal[: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
|
||||
# t_cruising=BSsOriginal[:cruising].t-cruisingReduction
|
||||
# s_cruising=t_cruising*drivingCourseModified[end].v
|
||||
distanceReduction = drivingCourse(csOriginal.behaviorSections[:cruising].dataPoints[end]).v*cruisingReduction
|
||||
s_cruising = csOriginal.behaviorSections[:cruising].length-distanceReduction
|
||||
distanceReduction = drivingCourse(BSsOriginal[:cruising].dataPoints[end]).v*cruisingReduction
|
||||
s_cruising = BSsOriginal[:cruising].length-distanceReduction
|
||||
|
||||
elseif settings[:stepVariable]=="v in m/s" # velocity step method
|
||||
s_cruising=csOriginal.behaviorSections[:cruising].length-cruisingReduction*10 # TODO: or better: *100 ?
|
||||
s_cruising=BSsOriginal[: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_peak, csOriginal.v_entry, csOriginal.v_exit, csOriginal.r_path, 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
|
||||
# 12/28 old: csModified=CharacteristicSection(csOriginal[:id], csOriginal[:length], csOriginal[:s_entry], csOriginal[:s_exit], 0.0, 0.0, csOriginal[:v_limit], csOriginal[:v_peak], csOriginal[:v_entry], csOriginal[:v_exit], csOriginal[:r_path], Dict{Symbol, BehaviorSection}())
|
||||
#TODO after removing the mutable structs: Is it possible to just "copy"? with some changes
|
||||
csModified=Dict(:id => csOriginal[:id], # identifier
|
||||
:s_entry => csOriginal[:s_entry], # first position (in m)
|
||||
:s_exit => csOriginal[:s_exit], # last position (in m)
|
||||
:length => csOriginal[:length], # total length (in m)
|
||||
:r_path => csOriginal[:r_path], # path resistance (in ‰)
|
||||
:behaviorSections => Dict(), # empty list of containing behavior sections
|
||||
:t => 0.0, # total running time (in s)
|
||||
:E => 0.0, # total energy consumption (in Ws)
|
||||
:v_limit => csOriginal[:v_limit], # speed limit (in m/s)
|
||||
:v_peak => csOriginal[:v_peak], # maximum reachable speed (in m/s)
|
||||
:v_entry => csOriginal[:v_entry], # maximum entry speed (in m/s)
|
||||
:v_exit => csOriginal[:v_exit]) # maximum exit speed (in m/s)
|
||||
|
||||
BSsModified = csModified[:behaviorSections]
|
||||
if haskey(BSsOriginal, :breakFree)
|
||||
breakFreeSection=BehaviorSection(BSsOriginal[:breakFree])
|
||||
merge!(BSsModified, Dict(:breakFree=>breakFreeSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:breakFree].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[: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
|
||||
if haskey(BSsOriginal, :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(BSsOriginal[:clearing])
|
||||
merge!(BSsModified, Dict(:clearing=>clearingSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:clearing].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[: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
|
||||
if haskey(BSsOriginal, :acceleration)
|
||||
accelerationSection=BehaviorSection(BSsOriginal[:acceleration])
|
||||
merge!(BSsModified, Dict(:acceleration=>accelerationSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:acceleration].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[:acceleration].t
|
||||
end
|
||||
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
|
||||
if haskey(BSsOriginal, :diminishing)
|
||||
diminishingSection=BehaviorSection(BSsOriginal[:diminishing])
|
||||
merge!(BSsModified, Dict(:diminishing=>diminishingSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:diminishing].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[:diminishing].t
|
||||
end
|
||||
|
||||
|
||||
|
@ -180,7 +194,7 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
|
|||
# calculate the coasting phase until the point the train needs to brake
|
||||
(csModified, drivingCourseModified)=addCoastingPhaseUntilBraking!(csModified, drivingCourseModified, settings, train, allCSs)
|
||||
|
||||
if drivingCourseModified[end].v < csModified.v_exit || drivingCourseModified[end].s > csModified.s_exit
|
||||
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
|
||||
|
@ -189,16 +203,16 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
|
|||
end # while cruisingReduction
|
||||
|
||||
# calculate the moving phase between coasting and the end of the CS
|
||||
if drivingCourseModified[end].v > csModified.v_exit
|
||||
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
|
||||
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
|
||||
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
|
||||
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)
|
||||
|
@ -210,33 +224,47 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
|
|||
# TODO: At the moment diminishing is reduced like the acceleration in decreaseMaximumVelocity. To reduce code the methods for reducing cruising phase and reducing the diminishing phase can be combined in some parts.
|
||||
|
||||
# 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_peak, csOriginal.v_entry, csOriginal.v_exit, csOriginal.r_path, 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
|
||||
# 12/28 old: csModified=CharacteristicSection(csOriginal[:id], csOriginal[:length], csOriginal[:s_entry], csOriginal[:s_exit], 0.0, 0.0, csOriginal[:v_limit], csOriginal[:v_peak], csOriginal[:v_entry], csOriginal[:v_exit], csOriginal[:r_path], Dict{Symbol, BehaviorSection}())
|
||||
csModified=Dict(:id => csOriginal[:id], # identifier
|
||||
:s_entry => csOriginal[:s_entry], # first position (in m)
|
||||
:s_exit => csOriginal[:s_exit], # last position (in m)
|
||||
:length => csOriginal[:length], # total length (in m)
|
||||
:r_path => csOriginal[:r_path], # path resistance (in ‰)
|
||||
:behaviorSections => Dict(), # empty list of containing behavior sections
|
||||
:t => 0.0, # total running time (in s)
|
||||
:E => 0.0, # total energy consumption (in Ws)
|
||||
:v_limit => csOriginal[:v_limit], # speed limit (in m/s)
|
||||
:v_peak => csOriginal[:v_peak], # maximum reachable speed (in m/s)
|
||||
:v_entry => csOriginal[:v_entry], # maximum entry speed (in m/s)
|
||||
:v_exit => csOriginal[:v_exit]) # maximum exit speed (in m/s)
|
||||
|
||||
BSsModified = csModified[:behaviorSections]
|
||||
if haskey(BSsOriginal, :breakFree)
|
||||
breakFreeSection=BehaviorSection(BSsOriginal[:breakFree])
|
||||
merge!(BSsModified, Dict(:breakFree=>breakFreeSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:breakFree].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[: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
|
||||
if haskey(BSsOriginal, :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(BSsOriginal[:clearing])
|
||||
merge!(BSsModified, Dict(:clearing=>clearingSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:clearing].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[: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
|
||||
if haskey(BSsOriginal, :acceleration)
|
||||
accelerationSection=BehaviorSection(BSsOriginal[:acceleration])
|
||||
merge!(BSsModified, Dict(:acceleration=>accelerationSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:acceleration].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[: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
|
||||
if haskey(BSsOriginal, :cruising)
|
||||
cruisingSection=BehaviorSection(BSsOriginal[:cruising])
|
||||
merge!(BSsModified, Dict(:cruising=>cruisingSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:cruising].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[:cruising].t
|
||||
end
|
||||
|
||||
diminishingSection=BehaviorSection(csOriginal.behaviorSections[:diminishing])
|
||||
diminishingSection=BehaviorSection(BSsOriginal[:diminishing])
|
||||
if length(diminishingSection.dataPoints) > 2
|
||||
# remove the last diminishing waypoint
|
||||
pop!(diminishingSection.dataPoints)
|
||||
|
@ -247,14 +275,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 + csModified.behaviorSections[:diminishing].E
|
||||
csModified.t = csModified.t + csModified.behaviorSections[:diminishing].t
|
||||
merge!(BSsModified, Dict(:diminishing => diminishingSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:diminishing].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[: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(BSsOriginal, :clearing, get(BSsOriginal, :diminishing, BehaviorSection())).dataPoints[1]
|
||||
end
|
||||
|
||||
# copy the driving course till the beginning of energy saving
|
||||
|
@ -267,60 +295,77 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
|
|||
(csModified, drivingCourseModified)=addCoastingPhaseUntilBraking!(csModified, drivingCourseModified, settings, train, allCSs)
|
||||
|
||||
# calculate the moving phase between coasting and the end of the CS
|
||||
if drivingCourseModified[end].v > csModified.v_exit
|
||||
if drivingCourseModified[end].v > csModified[:v_exit]
|
||||
(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings, train, allCSs)
|
||||
elseif drivingCourseModified[end].v == csModified.v_exit && drivingCourseModified[end].s < csModified.s_exit
|
||||
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
|
||||
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)
|
||||
if t_recoveryAvailable>=(csModified[:t]-csOriginal[:t])
|
||||
return (csModified, drivingCourseModified, true)
|
||||
else # time loss is to high. so there is no energy saving modification for this CS with the available recovery time
|
||||
# TODO: just return false or take smaller steps?
|
||||
|
||||
return (CharacteristicSection(), [], false)
|
||||
# 12/29 old, now not with empty but with original CS and DC: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes?
|
||||
return (csOriginal, drivingCourse, false)
|
||||
end
|
||||
end
|
||||
|
||||
# there is no energy saving modification for this CS with the available recovery time
|
||||
return (CharacteristicSection(), [], false)
|
||||
# 12/29 old, now not with empty but with original CS and DC: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes?
|
||||
return (csOriginal, drivingCourse, 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)
|
||||
# 12/29 old, now not with empty but with original CS and DC: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes?
|
||||
return (csOriginal, drivingCourse, false)
|
||||
end
|
||||
end # function increaseCoastingSection
|
||||
|
||||
# method 2 with shortening the acceleration by stepsize
|
||||
function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse, settings::Dict, train::Dict, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||
#function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||
if haskey(csOriginal.behaviorSections, :acceleration) && csOriginal.v_peak > csOriginal.v_entry && csOriginal.v_peak > csOriginal.v_exit
|
||||
accelerationSection = BehaviorSection(csOriginal.behaviorSections[:acceleration])
|
||||
if drivingCourse[accelerationSection.dataPoints[end]-1].v < csOriginal.v_exit
|
||||
return (CharacteristicSection(), [], false)
|
||||
function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict, train::Dict, allCSs::Vector{Dict}, t_recoveryAvailable::AbstractFloat)
|
||||
#function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||
BSsOriginal = csOriginal[:behaviorSections]
|
||||
if haskey(BSsOriginal, :acceleration) && csOriginal[:v_peak] > csOriginal[:v_entry] && csOriginal[:v_peak] > csOriginal[:v_exit]
|
||||
accelerationSection = BehaviorSection(BSsOriginal[:acceleration])
|
||||
if drivingCourse[accelerationSection.dataPoints[end]-1].v < csOriginal[:v_exit]
|
||||
# 12/29 old, now not with empty but with original CS and DC: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes?
|
||||
return (csOriginal, drivingCourse, false)
|
||||
# TODO: or calculate a new acceleration phase with v_exit as v_peak? 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_peak, csOriginal.v_entry, csOriginal.v_exit, csOriginal.r_path, 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
|
||||
# 12/28 old: csModified=CharacteristicSection(csOriginal[:id], csOriginal[:length], csOriginal[:s_entry], csOriginal[:s_exit], 0.0, 0.0, csOriginal[:v_limit], csOriginal[:v_peak], csOriginal[:v_entry], csOriginal[:v_exit], csOriginal[:r_path], Dict{Symbol, BehaviorSection}())
|
||||
csModified=Dict(:id => csOriginal[:id], # identifier
|
||||
:s_entry => csOriginal[:s_entry], # first position (in m)
|
||||
:s_exit => csOriginal[:s_exit], # last position (in m)
|
||||
:length => csOriginal[:length], # total length (in m)
|
||||
:r_path => csOriginal[:r_path], # path resistance (in ‰)
|
||||
:behaviorSections => Dict(), # empty list of containing behavior sections
|
||||
:t => 0.0, # total running time (in s)
|
||||
:E => 0.0, # total energy consumption (in Ws)
|
||||
:v_limit => csOriginal[:v_limit], # speed limit (in m/s)
|
||||
:v_peak => csOriginal[:v_peak], # maximum reachable speed (in m/s)
|
||||
:v_entry => csOriginal[:v_entry], # maximum entry speed (in m/s)
|
||||
:v_exit => csOriginal[:v_exit]) # maximum exit speed (in m/s)
|
||||
BSsModified = csModified[:behaviorSections]
|
||||
if haskey(BSsOriginal, :breakFree)
|
||||
breakFreeSection=BehaviorSection(BSsOriginal[:breakFree])
|
||||
merge!(BSsModified, Dict(:breakFree=>breakFreeSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:breakFree].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[:breakFree].t
|
||||
end
|
||||
|
||||
#accelerationSection = BehaviorSection(get(csOriginal.behaviorSections, :acceleration, BehaviorSection()))
|
||||
#accelerationSection = BehaviorSection(get(BSsOriginal, :acceleration, BehaviorSection()))
|
||||
|
||||
if length(accelerationSection.dataPoints) > 2
|
||||
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
|
||||
if haskey(BSsOriginal, :clearing)
|
||||
clearingSection=BehaviorSection(BSsOriginal[:clearing])
|
||||
merge!(BSsModified, Dict(:clearing=>clearingSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:clearing].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[:clearing].t
|
||||
end
|
||||
|
||||
# remove the last acceleration waypoint
|
||||
|
@ -332,14 +377,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 + csModified.behaviorSections[:acceleration].E
|
||||
csModified.t = csModified.t + csModified.behaviorSections[:acceleration].t
|
||||
merge!(BSsModified, Dict(:acceleration=>accelerationSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:acceleration].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[: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(BSsOriginal, :clearing, get(BSsOriginal, :acceleration, BehaviorSection())).dataPoints[1]
|
||||
end
|
||||
|
||||
# TODO: should v_peak be reduced or is it enough to pop the data points?
|
||||
|
@ -351,58 +396,85 @@ 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_peak^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
|
||||
s_braking=max(0.0, ceil((csModified.v_exit^2-drivingCourseModified[end].v^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
|
||||
s_cruising=csModified.s_exit-drivingCourseModified[end].s-s_braking
|
||||
#s_braking=max(0.0, ceil((csModified[:v_exit]^2-csModified[:v_peak]^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
|
||||
s_braking=max(0.0, ceil((csModified[:v_exit]^2-drivingCourseModified[end].v^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
|
||||
s_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
|
||||
if drivingCourseModified[end].v>csModified.v_exit
|
||||
# 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, train, allCSs)
|
||||
elseif drivingCourseModified[end].s<csModified.s_exit
|
||||
if (csModified.s_exit-drivingCourseModified[end].s)>0.001
|
||||
# if (csModified.s_exit-drivingCourseModified[end].s)>10^(-approximationLevel)
|
||||
# println("INFO: The end of new CS",csModified.id," is not reached while saving energy with lowering v_peak.")
|
||||
elseif drivingCourseModified[end].s<csModified[:s_exit]
|
||||
if (csModified[:s_exit]-drivingCourseModified[end].s)>0.001
|
||||
# if (csModified[:s_exit]-drivingCourseModified[end].s)>10^(-approximationLevel)
|
||||
# println("INFO: The end of new CS",csModified[:id]," is not reached while saving energy with lowering v_peak.")
|
||||
# println(" Therefore the calculation of this method can not continue for this CS.")
|
||||
return (CharacteristicSection(), [], false)
|
||||
# 12/29 old, now not with empty but with original CS and DC: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes?
|
||||
return (csOriginal, drivingCourse, false)
|
||||
end
|
||||
println("WARNING: The end of new CS",csModified.id," is not reached while saving energy with lowering v_peak.")
|
||||
println(" Therefore s=",drivingCourseModified[end].s," will be set s_exit=",csModified.s_exit," because the difference is only ",csModified.s_exit-drivingCourseModified[end].s," m.")
|
||||
println(" v=",drivingCourseModified[end].v," m/s v_exit=",csOriginal.v_exit ," m/s")
|
||||
println("WARNING: The end of new CS",csModified[:id]," is not reached while saving energy with lowering v_peak.")
|
||||
println(" Therefore s=",drivingCourseModified[end].s," will be set s_exit=",csModified[:s_exit]," because the difference is only ",csModified[:s_exit]-drivingCourseModified[end].s," m.")
|
||||
println(" v=",drivingCourseModified[end].v," m/s v_exit=",csOriginal[:v_exit] ," m/s")
|
||||
|
||||
drivingCourseModified[end].s=csModified.s_exit # rounding up to s_exit
|
||||
drivingCourseModified[end].s=csModified[:s_exit] # rounding up to s_exit
|
||||
end #if
|
||||
|
||||
if t_recoveryAvailable>=(csModified.t-csOriginal.t)
|
||||
if t_recoveryAvailable>=(csModified[:t]-csOriginal[:t])
|
||||
return (csModified, drivingCourseModified, true)
|
||||
else # time loss is to high. so there is no energy saving modification for this CS with the available recovery time
|
||||
# 09/06 old: else # time loss is to high and the CS has to be calculated again with larger acceleration section (so with a smaller reduction of the acceleration section)
|
||||
# 09/06 old: accelerationReduction=min(accelerationReduction/10, csModified.v_peak-csModified.v_entry, csModified.v_peak-csModified.v_exit)
|
||||
# 09/06 old: accelerationReduction=min(accelerationReduction/10, csModified[:v_peak]-csModified[:v_entry], csModified[:v_peak]-csModified[:v_exit])
|
||||
# TODO: just return false or take smaller steps?
|
||||
|
||||
return (CharacteristicSection(), [], false)
|
||||
# 12/29 old, now not with empty but with original CS and DC: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes?
|
||||
return (csOriginal, drivingCourse, false)
|
||||
end
|
||||
|
||||
# 09/06 old: end #while
|
||||
#
|
||||
# 09/06 old: # there is no energy saving modification for this CS with the available recovery time
|
||||
# 09/06 old: return (CharacteristicSection(), [], false)
|
||||
# 09/06 old: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes?
|
||||
# 12/29 new, now not with empty but with original CS and DC: return (csOriginal, drivingCourse, false)
|
||||
|
||||
|
||||
else
|
||||
# there is no energy saving modification for this CS because v_peak can not be lowered below v_entry or v_exit or because there is no acceleration section that can be transformed into a cruising section
|
||||
return (CharacteristicSection(), [], false)
|
||||
# 12/29 old, now not with empty but with original CS and DC: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes?
|
||||
return (csOriginal, drivingCourse, false)
|
||||
end #if haskey
|
||||
end # function decreaseMaximumVelocity
|
||||
|
||||
# combination of method 1 and method 2
|
||||
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_peak>csOriginal.v_entry && csOriginal.v_peak>csOriginal.v_exit
|
||||
if haskey(csOriginal.behaviorSections, :acceleration) && (haskey(csOriginal.behaviorSections, :braking) || haskey(csOriginal.behaviorSections, :coasting)) && drivingCourse[get(csOriginal.behaviorSections, :acceleration, BehaviorSection()).dataPoints[end]].v > max(csOriginal.v_entry, csOriginal.v_exit)
|
||||
csCombined=CharacteristicSection(csOriginal)
|
||||
function combineEnergySavingMethods(csOriginal::Dict, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, allCSs::Vector{Dict}, t_recoveryAvailable::AbstractFloat)
|
||||
BSsOriginal = csOriginal[:behaviorSections]
|
||||
# if haskey(BSsOriginal, :acceleration) && (haskey(BSsOriginal, :braking) || haskey(BSsOriginal, :coasting)) && csOriginal[:v_peak]>csOriginal[:v_entry] && csOriginal[:v_peak]>csOriginal[:v_exit]
|
||||
if haskey(BSsOriginal, :acceleration) && (haskey(BSsOriginal, :braking) || haskey(BSsOriginal, :coasting)) && drivingCourse[get(BSsOriginal, :acceleration, BehaviorSection()).dataPoints[end]].v > max(csOriginal[:v_entry], csOriginal[:v_exit])
|
||||
# 12/28 old: csCombined=CharacteristicSection(csOriginal)
|
||||
#TODO after removing the mutable structs: Is it possible to just "copy"?
|
||||
csCombined=Dict(:id => csOriginal[:id], # identifier
|
||||
:s_entry => csOriginal[:s_entry], # first position (in m)
|
||||
:s_exit => csOriginal[:s_exit], # last position (in m)
|
||||
:length => csOriginal[:length], # total length (in m)
|
||||
:r_path => csOriginal[:r_path], # path resistance (in ‰)
|
||||
:behaviorSections => Dict(), # empty list of containing behavior sections
|
||||
:t => csOriginal[:t], # total running time (in s)
|
||||
:E => csOriginal[:E], # total energy consumption (in Ws)
|
||||
:v_limit => csOriginal[:v_limit], # speed limit (in m/s)
|
||||
:v_peak => csOriginal[:v_peak], # maximum reachable speed (in m/s)
|
||||
:v_entry => csOriginal[:v_entry], # maximum entry speed (in m/s)
|
||||
:v_exit => csOriginal[:v_exit]) # maximum exit speed (in m/s)
|
||||
|
||||
allBs=[:breakFree, :clearing, :acceleration, :cruising, :diminishing, :coasting, :cruisingAfterCoasting, :braking, :standstill]
|
||||
for bs in 1: length(allBs)
|
||||
if haskey(BSsOriginal, allBs[bs])
|
||||
merge!(csCombined[:behaviorSections], Dict(allBs[bs] => BehaviorSection(BSsOriginal[allBs[bs]])))
|
||||
end #if
|
||||
end #for
|
||||
|
||||
drivingCourseCombined=Vector{DataPoint}()
|
||||
for i in 1:length(drivingCourse)
|
||||
# TODO: tried to insert copy on 15.07.2021 push!(drivingCourseCombined, copy(drivingCourse[i]))
|
||||
|
@ -414,26 +486,28 @@ function combineEnergySavingMethods(csOriginal::CharacteristicSection, drivingCo
|
|||
while (Δt<t_recoveryAvailable && (Δt<=0.0 || ΔE<=0.0)) #ΔE<=0.0)
|
||||
(csCombined, drivingCourseCombined, newMaximumVelocity)=decreaseMaximumVelocity(csCombined, drivingCourseCombined, settings, train, allCSs, t_recoveryAvailable)
|
||||
if newMaximumVelocity
|
||||
ΔE=csOriginal.E-csCombined.E # saved energy (in Ws)
|
||||
Δt=csCombined.t-csOriginal.t # time loss (in s)
|
||||
ΔE=csOriginal[:E]-csCombined[:E] # saved energy (in Ws)
|
||||
Δt=csCombined[:t]-csOriginal[:t] # time loss (in s)
|
||||
|
||||
while (haskey(csOriginal.behaviorSections, :cruising) && (Δt<=0.0 || ΔE<=0.0)) #Δt<=0.0) #&& ΔE<=0.0) # && Δt<=0.0)
|
||||
while (haskey(BSsOriginal, :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)
|
||||
Δt=csCombined.t-csOriginal.t # time loss (in s)
|
||||
ΔE=csOriginal[:E]-csCombined[:E] # saved energy (in Ws)
|
||||
Δt=csCombined[:t]-csOriginal[:t] # time loss (in s)
|
||||
else
|
||||
break
|
||||
end # if newCoasting
|
||||
end # while haskey
|
||||
else
|
||||
return (CharacteristicSection(), [], false)
|
||||
# 12/29 old, now not with empty but with original CS and DC: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes?
|
||||
return (csOriginal, drivingCourse, false)
|
||||
end # if newMaximumVelocity
|
||||
end # while
|
||||
return (csCombined, drivingCourseCombined, (ΔE>0.0))# && Δt>0.0))
|
||||
else
|
||||
# there is no energy saving modification for this CS because v_peak can not be lowered below v_entry or v_exit or because there is no acceleration section and braking section or coasting section that can be transformed into a cruising section or coasting section
|
||||
return (CharacteristicSection(), [], false)
|
||||
# 12/29 old, now not with empty but with original CS and DC: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes?
|
||||
return (csOriginal, drivingCourse, false)
|
||||
end #if
|
||||
end #function combineEnergySavingMethods
|
||||
|
||||
|
|
|
@ -317,7 +317,7 @@ function inputTrain(trainDirectory::String)
|
|||
train= Dict(:name => name, # train's name
|
||||
:id => id, # train's identifier
|
||||
:trainType => trainType, # type of train "passenger" or "freight" or "motor coach train"
|
||||
:trainLength => trainLength, # total length (in m)
|
||||
:trainLength => trainLength,# 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)
|
||||
|
|
|
@ -80,10 +80,10 @@ end #function calculateWagonsResistance
|
|||
"""
|
||||
calculate and return the path resistance dependend on the trains position and mass model
|
||||
"""
|
||||
function calculatePathResistance(s::AbstractFloat, massModel::String, train::Dict, CSs::Vector{CharacteristicSection})
|
||||
function calculatePathResistance(s::Real, massModel::String, train::Dict, CSs::Vector{Dict})
|
||||
# looking for the characteristic section with the trains head position
|
||||
id=length(CSs)
|
||||
while s<CSs[id].s_entry
|
||||
while s<CSs[id][:s_entry]
|
||||
id=id-1
|
||||
if id==0
|
||||
println("s=",s," MS.s_entry=",CSs[1].s_entry)
|
||||
|
@ -91,11 +91,11 @@ function calculatePathResistance(s::AbstractFloat, massModel::String, train::Dic
|
|||
end #while
|
||||
|
||||
if massModel=="mass point"
|
||||
pathResistance=CSs[id].r_path/1000*train[:m_train]*g # /1000 because of the unit ‰
|
||||
pathResistance=CSs[id][:r_path]/1000*train[:m_train]*g # /1000 because of the unit ‰
|
||||
elseif massModel=="homogeneous strip"
|
||||
pathResistance=0.0
|
||||
while id>0 && s-train[:trainLength]<CSs[id].s_exit
|
||||
pathResistance=pathResistance+(min(s, CSs[id].s_exit)-max(s-train[:trainLength], CSs[id].s_entry))/train[:trainLength]*(CSs[id].r_path/1000*train[:m_train]*g) # /1000 because of the unit ‰
|
||||
while id>0 && s-train[:trainLength]<CSs[id][:s_exit]
|
||||
pathResistance=pathResistance+(min(s, CSs[id][:s_exit])-max(s-train[:trainLength], CSs[id][:s_entry]))/train[:trainLength]*(CSs[id][:r_path]/1000*train[:m_train]*g) # /1000 because of the unit ‰
|
||||
id=id-1
|
||||
if id==0
|
||||
# TODO: currently for values < movingSection[:s_entry] the values of movingSection[:s_entry] will be used
|
||||
|
@ -112,7 +112,7 @@ end #function pathResistance
|
|||
"""
|
||||
calculate and return tractive and resisting forces for a data point
|
||||
"""
|
||||
function calculateForces!(dataPoint::DataPoint, train::Dict, massModel::String, CSs::Vector{CharacteristicSection}, bsType::String)
|
||||
function calculateForces!(dataPoint::DataPoint, train::Dict, massModel::String, CSs::Vector{Dict}, bsType::String)
|
||||
# calculate resisting forces
|
||||
dataPoint.R_traction=calculateTractionUnitResistance(dataPoint.v, train)
|
||||
dataPoint.R_wagons=calculateWagonsResistance(dataPoint.v, train)
|
||||
|
@ -189,13 +189,13 @@ end #function moveAStep
|
|||
"""
|
||||
# if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
|
||||
"""
|
||||
function detectFormerSpeedLimits(CSs::Vector{CharacteristicSection}, csWithTrainHeadId::Integer, currentPoint::DataPoint, trainLength::Real)
|
||||
function detectFormerSpeedLimits(CSs::Vector{Dict}, csWithTrainHeadId::Integer, currentPoint::DataPoint, trainLength::Real)
|
||||
formerSpeedLimits=[]
|
||||
if csWithTrainHeadId > 1 && currentPoint.s - trainLength < CSs[csWithTrainHeadId].s_entry
|
||||
if csWithTrainHeadId > 1 && currentPoint.s - trainLength < CSs[csWithTrainHeadId][:s_entry]
|
||||
formerCsId=csWithTrainHeadId-1
|
||||
while formerCsId > 0 && currentPoint.s - trainLength < CSs[formerCsId].s_exit
|
||||
if CSs[formerCsId].v_limit < CSs[csWithTrainHeadId].v_limit # TODO: is the position of trains tail < movingSection[:s_entry], v_limit of the first CS is used
|
||||
push!(formerSpeedLimits, [CSs[formerCsId].s_exit, CSs[formerCsId].v_limit])
|
||||
while formerCsId > 0 && currentPoint.s - trainLength < CSs[formerCsId][:s_exit]
|
||||
if CSs[formerCsId][:v_limit] < CSs[csWithTrainHeadId][:v_limit] # TODO: is the position of trains tail < movingSection[:s_entry], v_limit of the first CS is used
|
||||
push!(formerSpeedLimits, [CSs[formerCsId][:s_exit], CSs[formerCsId][:v_limit]])
|
||||
for i in 1:length(formerSpeedLimits)-1
|
||||
if formerSpeedLimits[i][2]<=formerSpeedLimits[end][2]
|
||||
pop!(formerSpeedLimits)
|
||||
|
@ -209,34 +209,34 @@ function detectFormerSpeedLimits(CSs::Vector{CharacteristicSection}, csWithTrain
|
|||
return formerSpeedLimits
|
||||
end # function detectFormerSpeedLimits
|
||||
|
||||
function considerFormerSpeedLimits!(CS::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{CharacteristicSection}, formerSpeedLimits, accelerationSection::BehaviorSection)
|
||||
# TODO: What is the type of formerSpeedLimits? function considerFormerSpeedLimits!(CS::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{CharacteristicSection}, formerSpeedLimits::Array{Array{AbstractFloat,1},1}, accelerationSection::BehaviorSection)
|
||||
# would work: function considerFormerSpeedLimits!(CS::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{CharacteristicSection}, formerSpeedLimits::Array{Any,1}, accelerationSection::BehaviorSection)
|
||||
function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{Dict}, formerSpeedLimits, accelerationSection::BehaviorSection)
|
||||
# TODO: What is the type of formerSpeedLimits? function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{Dict}, formerSpeedLimits::Array{Array{AbstractFloat,1},1}, accelerationSection::BehaviorSection)
|
||||
# would work: function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{Dict}, formerSpeedLimits::Array{Any,1}, accelerationSection::BehaviorSection)
|
||||
if length(formerSpeedLimits) > 0
|
||||
# if a former speed limit has been exceeded the acceleration steps of this CS will be removed and a clearing phase will be inserted before acceleration
|
||||
if drivingCourse[end].v > formerSpeedLimits[end][2]
|
||||
while drivingCourse[end].s > get(CS.behaviorSections, :clearing, accelerationSection).s_entry
|
||||
while drivingCourse[end].s > get(CS[:behaviorSections], :clearing, accelerationSection).s_entry
|
||||
pop!(drivingCourse)
|
||||
end
|
||||
|
||||
if haskey(CS.behaviorSections, :clearing)
|
||||
CS.t = CS.t-CS.behaviorSections[:clearing].t # reducing the total running time (in s)
|
||||
CS.E = CS.E-CS.behaviorSections[:clearing].E # reducing the total energy consumption (in Ws)
|
||||
delete!(CS.behaviorSections, :clearing)
|
||||
if haskey(CS[:behaviorSections], :clearing)
|
||||
CS[:t] = CS[:t]-CS[:behaviorSections][:clearing].t # reducing the total running time (in s)
|
||||
CS[:E] = CS[:E]-CS[:behaviorSections][:clearing].E # reducing the total energy consumption (in Ws)
|
||||
delete!(CS[:behaviorSections], :clearing)
|
||||
end
|
||||
|
||||
# create a (new and longer) clearing section
|
||||
s_braking=max(0.0, ceil((CS.v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel))
|
||||
s_clearing=min(CS.s_exit-drivingCourse[end].s-s_braking, formerSpeedLimits[end][1]-(drivingCourse[end].s-train[:trainLength]))
|
||||
s_braking=max(0.0, ceil((CS[:v_exit]^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel))
|
||||
s_clearing=min(CS[:s_exit]-drivingCourse[end].s-s_braking, formerSpeedLimits[end][1]-(drivingCourse[end].s-train[:trainLength]))
|
||||
|
||||
if s_clearing>0.0
|
||||
(CS, drivingCourse)=addCruisingPhase!(CS, drivingCourse, s_clearing, settings, train, CSs, "clearing")
|
||||
else
|
||||
error("ERROR: clearing <=0.0 although it has to be >0.0 in CS ",CS.id)
|
||||
error("ERROR: clearing <=0.0 although it has to be >0.0 in CS ",CS[:id])
|
||||
end
|
||||
|
||||
# 09/22: if drivingCourse[end].s < CS.s_exit
|
||||
if drivingCourse[end].s < CS.s_exit-s_braking
|
||||
# 09/22: if drivingCourse[end].s < CS[:s_exit]
|
||||
if drivingCourse[end].s < CS[:s_exit]-s_braking
|
||||
# reset the accelerationSection
|
||||
accelerationSection=BehaviorSection()
|
||||
accelerationSection.type="acceleration" # type of behavior section
|
||||
|
@ -260,8 +260,8 @@ end # function considerFormerSpeedLimits!
|
|||
## This function calculates the data points of the breakFree phase.
|
||||
# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for breakFree if needed.
|
||||
# Info: currently the values of the breakFree phase will be calculated like in the acceleration phase
|
||||
function addBreakFreePhase!(CS::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{CharacteristicSection})
|
||||
if drivingCourse[end].v==0.0 && drivingCourse[end].s<CS.s_exit
|
||||
function addBreakFreePhase!(CS::Dict, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{Dict})
|
||||
if drivingCourse[end].v==0.0 && drivingCourse[end].s<CS[:s_exit]
|
||||
breakFreeSection=BehaviorSection()
|
||||
breakFreeSection.type="breakFree" # type of behavior section
|
||||
breakFreeSection.s_entry=drivingCourse[end].s # first position (in m)
|
||||
|
@ -281,7 +281,7 @@ function addBreakFreePhase!(CS::CharacteristicSection, drivingCourse::Vector{Dat
|
|||
end
|
||||
|
||||
# creating the next data point
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], settings[:stepSize], CS.id))
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], settings[:stepSize], CS[:id]))
|
||||
drivingCourse[end].behavior = breakFreeSection.type
|
||||
#= 07/30 TODO: the calculation is easier with these lines because the values that are 0 in the first step are not used in calculation but all in all the code gets easier without these lines:
|
||||
push!(drivingCourse, DataPoint())
|
||||
|
@ -320,10 +320,10 @@ function addBreakFreePhase!(CS::CharacteristicSection, drivingCourse::Vector{Dat
|
|||
breakFreeSection.t=drivingCourse[end].t-drivingCourse[breakFreeSection.dataPoints[1]].t # total running time (in s)
|
||||
breakFreeSection.E=drivingCourse[end].E-drivingCourse[breakFreeSection.dataPoints[1]].E # total energy consumption (in Ws)
|
||||
|
||||
CS.t=CS.t+breakFreeSection.t # total running time (in s)
|
||||
CS.E=CS.E+breakFreeSection.E # total energy consumption (in Ws)
|
||||
CS[:t]=CS[:t]+breakFreeSection.t # total running time (in s)
|
||||
CS[:E]=CS[:E]+breakFreeSection.E # total energy consumption (in Ws)
|
||||
|
||||
merge!(CS.behaviorSections, Dict(:breakFree => breakFreeSection))
|
||||
merge!(CS[:behaviorSections], Dict(:breakFree => breakFreeSection))
|
||||
end # else: return the characteristic section without a breakFree section
|
||||
return (CS, drivingCourse)
|
||||
end #function addBreakFreePhase!
|
||||
|
@ -331,7 +331,7 @@ end #function addBreakFreePhase!
|
|||
|
||||
## This function calculates the data points of the acceleration phase.
|
||||
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the acceleration section
|
||||
function addAccelerationPhase!(CS::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{CharacteristicSection})
|
||||
function addAccelerationPhase!(CS::Dict, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{Dict})
|
||||
if drivingCourse[end].v==0.0
|
||||
(CS, drivingCourse)=addBreakFreePhase!(CS, drivingCourse, settings, train, CSs)
|
||||
end #if
|
||||
|
@ -343,16 +343,16 @@ function addAccelerationPhase!(CS::CharacteristicSection, drivingCourse::Vector{
|
|||
end
|
||||
|
||||
# if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
|
||||
formerSpeedLimits = detectFormerSpeedLimits(CSs, CS.id, drivingCourse[end], train[:trainLength])
|
||||
formerSpeedLimits = detectFormerSpeedLimits(CSs, CS[:id], drivingCourse[end], train[:trainLength])
|
||||
|
||||
# conditions for acceleration phase
|
||||
targetSpeedReached = drivingCourse[end].v >= CS.v_peak
|
||||
trainAtEnd = drivingCourse[end].s >= CS.s_exit
|
||||
targetSpeedReached = drivingCourse[end].v >= CS[:v_peak]
|
||||
trainAtEnd = drivingCourse[end].s >= CS[:s_exit]
|
||||
tractionSurplus = drivingCourse[end].F_T > drivingCourse[end].F_R
|
||||
|
||||
# use the conditions for the acceleration phase
|
||||
if !targetSpeedReached && !trainAtEnd && tractionSurplus
|
||||
#11/23 long version: if drivingCourse[end].v < CS.v_peak && drivingCourse[end].s <CS.s_exit && drivingCourse[end].F_T > drivingCourse[end].F_R
|
||||
#11/23 long version: if drivingCourse[end].v < CS[:v_peak] && drivingCourse[end].s <CS[:s_exit] && drivingCourse[end].F_T > drivingCourse[end].F_R
|
||||
accelerationSection=BehaviorSection()
|
||||
accelerationSection.type="acceleration" # type of behavior section
|
||||
accelerationSection.s_entry=drivingCourse[end].s # first position (in m)
|
||||
|
@ -362,7 +362,7 @@ function addAccelerationPhase!(CS::CharacteristicSection, drivingCourse::Vector{
|
|||
|
||||
currentStepSize=settings[:stepSize] # initializing the step size that can be reduced near intersections
|
||||
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
|
||||
while drivingCourse[end].v<CS.v_peak && drivingCourse[end].s<CS.s_exit && drivingCourse[end].F_T > drivingCourse[end].F_R
|
||||
while drivingCourse[end].v<CS[:v_peak] && drivingCourse[end].s<CS[:s_exit] && drivingCourse[end].F_T > drivingCourse[end].F_R
|
||||
# traction effort and resisting forces (in N)
|
||||
# 11/22 calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, accelerationSection.type)
|
||||
|
||||
|
@ -370,7 +370,7 @@ function addAccelerationPhase!(CS::CharacteristicSection, drivingCourse::Vector{
|
|||
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train[:m_train]/train[:ξ_train]
|
||||
|
||||
# create the next data point
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS.id))
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
|
||||
drivingCourse[end].behavior = accelerationSection.type
|
||||
push!(accelerationSection.dataPoints, drivingCourse[end].i)
|
||||
# calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, accelerationSection.type)
|
||||
|
@ -391,30 +391,30 @@ function addAccelerationPhase!(CS::CharacteristicSection, drivingCourse::Vector{
|
|||
if drivingCourse[end].v<=0.0
|
||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||
|
||||
elseif drivingCourse[end].s>CS.s_exit
|
||||
elseif drivingCourse[end].s>CS[:s_exit]
|
||||
if settings[:stepVariable] == "s in m"
|
||||
currentStepSize=CS.s_exit-drivingCourse[end-1].s
|
||||
currentStepSize=CS[:s_exit]-drivingCourse[end-1].s
|
||||
else
|
||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||
end
|
||||
|
||||
elseif drivingCourse[end].v>CS.v_peak
|
||||
elseif drivingCourse[end].v>CS[:v_peak]
|
||||
if settings[:stepVariable]=="v in m/s"
|
||||
currentStepSize=CS.v_peak-drivingCourse[end-1].v
|
||||
currentStepSize=CS[:v_peak]-drivingCourse[end-1].v
|
||||
else
|
||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||
end
|
||||
|
||||
elseif drivingCourse[end].s==CS.s_exit
|
||||
elseif drivingCourse[end].s==CS[:s_exit]
|
||||
break
|
||||
|
||||
elseif drivingCourse[end].v==CS.v_peak
|
||||
elseif drivingCourse[end].v==CS[:v_peak]
|
||||
break
|
||||
elseif drivingCourse[end].F_T <= drivingCourse[end].F_R
|
||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||
|
||||
else
|
||||
error("ERROR at acceleration phase: With the step variable ", settings[:stepVariable]," the while loop will be left although v<v_peak and s<s_exit in CS",CS.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
|
||||
error("ERROR at acceleration phase: With the step variable ", settings[:stepVariable]," the while loop will be left although v<v_peak and s<s_exit in CS",CS[:id]," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
|
||||
end
|
||||
# delete last data point for recalculating the last step with reduced step size
|
||||
pop!(drivingCourse)
|
||||
|
@ -423,15 +423,15 @@ function addAccelerationPhase!(CS::CharacteristicSection, drivingCourse::Vector{
|
|||
else # if the level of approximation is reached
|
||||
if drivingCourse[end].v<=0.0
|
||||
# push!(accelerationSection.dataPoints, drivingCourse[end].i)
|
||||
error("ERROR: The train stops during the acceleration phase in CS",CS.id," because the tractive effort is lower than the resistant forces.",
|
||||
error("ERROR: The train stops during the acceleration phase in CS",CS[:id]," because the tractive effort is lower than the resistant forces.",
|
||||
" Before the stop the last point has the values s=",drivingCourse[end-1].s," m v=",drivingCourse[end-1].v," m/s a=",drivingCourse[end-1].a," m/s^2",
|
||||
" F_T=",drivingCourse[end-1].F_T," N R_traction=",drivingCourse[end-1].R_traction," N R_wagons=",drivingCourse[end-1].R_wagons," N R_path=",drivingCourse[end-1].R_path," N.")
|
||||
|
||||
elseif drivingCourse[end].v>CS.v_peak
|
||||
elseif drivingCourse[end].v>CS[:v_peak]
|
||||
pop!(drivingCourse)
|
||||
pop!(accelerationSection.dataPoints)
|
||||
elseif drivingCourse[end].s>CS.s_exit
|
||||
drivingCourse[end].s=CS.s_exit # rounding s down to s_exit
|
||||
elseif drivingCourse[end].s>CS[:s_exit]
|
||||
drivingCourse[end].s=CS[:s_exit] # rounding s down to s_exit
|
||||
|
||||
elseif drivingCourse[end].F_T <= drivingCourse[end].F_R
|
||||
(CS, drivingCourse)=addDiminishingPhase!(CS, drivingCourse, settings, train, CSs)
|
||||
|
@ -450,15 +450,15 @@ function addAccelerationPhase!(CS::CharacteristicSection, drivingCourse::Vector{
|
|||
accelerationSection.length=accelerationSection.s_exit-accelerationSection.s_entry # total length (in m)
|
||||
accelerationSection.t=drivingCourse[end].t-drivingCourse[accelerationSection.dataPoints[1]].t # total running time (in s)
|
||||
accelerationSection.E=drivingCourse[end].E-drivingCourse[accelerationSection.dataPoints[1]].E # total energy consumption (in Ws)
|
||||
CS.t=CS.t+accelerationSection.t # total running time (in s)
|
||||
CS.E=CS.E+accelerationSection.E # total energy consumption (in Ws)
|
||||
CS[:t]=CS[:t]+accelerationSection.t # total running time (in s)
|
||||
CS[:E]=CS[:E]+accelerationSection.E # total energy consumption (in Ws)
|
||||
|
||||
# TODO: this warning schould not be needed. just for testing
|
||||
if CS.v_peak < drivingCourse[end].v
|
||||
println("WARNING, v is getting to high at the end of the acceleration phase. v=",drivingCourse[end].v ," > v_peak=",CS.v_peak)
|
||||
if CS[:v_peak] < drivingCourse[end].v
|
||||
println("WARNING, v is getting to high at the end of the acceleration phase. v=",drivingCourse[end].v ," > v_peak=",CS[:v_peak])
|
||||
end
|
||||
|
||||
merge!(CS.behaviorSections, Dict(:acceleration=>accelerationSection))
|
||||
merge!(CS[:behaviorSections], Dict(:acceleration=>accelerationSection))
|
||||
end
|
||||
end # else: just return the given data point number without changes due to the acceleration phase
|
||||
|
||||
|
@ -467,7 +467,7 @@ end #function addAccelerationPhase!
|
|||
|
||||
|
||||
## This function calculates the data points of the acceleration phase.
|
||||
function addAccelerationPhaseUntilBraking!(CS::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{CharacteristicSection})
|
||||
function addAccelerationPhaseUntilBraking!(CS::Dict, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{Dict})
|
||||
if drivingCourse[end].v==0.0
|
||||
(CS, drivingCourse)=addBreakFreePhase!(CS, drivingCourse, settings, train, CSs)
|
||||
end #if
|
||||
|
@ -479,11 +479,11 @@ function addAccelerationPhaseUntilBraking!(CS::CharacteristicSection, drivingCou
|
|||
end
|
||||
|
||||
# if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
|
||||
formerSpeedLimits = detectFormerSpeedLimits(CSs, CS.id, drivingCourse[end], train[:trainLength])
|
||||
formerSpeedLimits = detectFormerSpeedLimits(CSs, CS[:id], drivingCourse[end], train[:trainLength])
|
||||
|
||||
|
||||
# 11/23 old without F_T>F_R: if drivingCourse[end].v < CS.v_peak && drivingCourse[end].s<CS.s_exit
|
||||
if drivingCourse[end].v < CS.v_peak && drivingCourse[end].s<CS.s_exit && drivingCourse[end].F_T > drivingCourse[end].F_R
|
||||
# 11/23 old without F_T>F_R: if drivingCourse[end].v < CS[:v_peak] && drivingCourse[end].s<CS[:s_exit]
|
||||
if drivingCourse[end].v < CS[:v_peak] && drivingCourse[end].s<CS[:s_exit] && drivingCourse[end].F_T > drivingCourse[end].F_R
|
||||
accelerationSection=BehaviorSection()
|
||||
accelerationSection.type="acceleration" # type of behavior section
|
||||
accelerationSection.s_entry=drivingCourse[end].s # first position (in m)
|
||||
|
@ -493,9 +493,9 @@ function addAccelerationPhaseUntilBraking!(CS::CharacteristicSection, drivingCou
|
|||
|
||||
currentStepSize=settings[:stepSize] # initializing the step size that can be reduced near intersections
|
||||
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
|
||||
s_braking=max(0.0, ceil((CS.v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel))
|
||||
while drivingCourse[end].v < CS.v_peak && drivingCourse[end].s+s_braking<CS.s_exit && drivingCourse[end].F_T > drivingCourse[end].F_R # as long as s_i + s_braking < s_CSend
|
||||
# 12/03 old with v>0 while drivingCourse[end].v < CS.v_peak && drivingCourse[end].s+s_braking<CS.s_exit && drivingCourse[end].v>0.0 && drivingCourse[end].F_T > drivingCourse[end].F_R # as long as s_i + s_braking < s_CSend
|
||||
s_braking=max(0.0, ceil((CS[:v_exit]^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel))
|
||||
while drivingCourse[end].v < CS[:v_peak] && drivingCourse[end].s+s_braking<CS[:s_exit] && drivingCourse[end].F_T > drivingCourse[end].F_R # as long as s_i + s_braking < s_CSend
|
||||
# 12/03 old with v>0 while drivingCourse[end].v < CS[:v_peak] && drivingCourse[end].s+s_braking<CS[:s_exit] && drivingCourse[end].v>0.0 && drivingCourse[end].F_T > drivingCourse[end].F_R # as long as s_i + s_braking < s_CSend
|
||||
|
||||
#11/22 calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, accelerationSection.type)
|
||||
|
||||
|
@ -506,7 +506,7 @@ function addAccelerationPhaseUntilBraking!(CS::CharacteristicSection, drivingCou
|
|||
# end
|
||||
|
||||
# create the next data point
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS.id))
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
|
||||
drivingCourse[end].behavior = accelerationSection.type
|
||||
push!(accelerationSection.dataPoints, drivingCourse[end].i)
|
||||
# 12/03: was moved behind considerFormerSpeedLimits: calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, accelerationSection.type)
|
||||
|
@ -518,7 +518,7 @@ function addAccelerationPhaseUntilBraking!(CS::CharacteristicSection, drivingCou
|
|||
end
|
||||
end
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, accelerationSection.type)
|
||||
s_braking=max(0.0, ceil((CS.v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel))
|
||||
s_braking=max(0.0, ceil((CS[:v_exit]^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel))
|
||||
end #while
|
||||
|
||||
# check which limit was reached and adjust the currentStepSize for the next cycle
|
||||
|
@ -526,27 +526,27 @@ function addAccelerationPhaseUntilBraking!(CS::CharacteristicSection, drivingCou
|
|||
if drivingCourse[end].v<=0.0
|
||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||
|
||||
elseif drivingCourse[end].s +s_braking > CS.s_exit
|
||||
elseif drivingCourse[end].s +s_braking > CS[:s_exit]
|
||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||
|
||||
elseif drivingCourse[end].v>CS.v_peak
|
||||
elseif drivingCourse[end].v>CS[:v_peak]
|
||||
if settings[:stepVariable]=="v in m/s"
|
||||
currentStepSize= CS.v_peak-drivingCourse[end-1].v
|
||||
currentStepSize= CS[:v_peak]-drivingCourse[end-1].v
|
||||
else
|
||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||
end
|
||||
|
||||
elseif drivingCourse[end].s==CS.s_exit
|
||||
elseif drivingCourse[end].s==CS[:s_exit]
|
||||
break
|
||||
|
||||
elseif drivingCourse[end].v==CS.v_peak
|
||||
elseif drivingCourse[end].v==CS[:v_peak]
|
||||
break
|
||||
|
||||
elseif drivingCourse[end].F_T <= drivingCourse[end].F_R
|
||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||
|
||||
else
|
||||
error("ERROR at acceleration until braking phase: With the step variable ",settings[:stepVariable]," the while loop will be left although v<v_peak and s<s_exit in CS",CS.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
|
||||
error("ERROR at acceleration until braking phase: With the step variable ",settings[:stepVariable]," the while loop will be left although v<v_peak and s<s_exit in CS",CS[:id]," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
|
||||
end
|
||||
# delete last data point for recalculating the last step with reduced step size
|
||||
pop!(drivingCourse)
|
||||
|
@ -555,14 +555,14 @@ function addAccelerationPhaseUntilBraking!(CS::CharacteristicSection, drivingCou
|
|||
else # if the level of approximation is reached
|
||||
if drivingCourse[end].v<=0.0
|
||||
# push!(accelerationSection.dataPoints, drivingCourse[end].i)
|
||||
error("ERROR: The train stops during the acceleration phase in CS",CS.id," because the tractive effort is lower than the resistant forces.",
|
||||
error("ERROR: The train stops during the acceleration phase in CS",CS[:id]," because the tractive effort is lower than the resistant forces.",
|
||||
" Before the stop the last point has the values s=",drivingCourse[end-1].s," m v=",drivingCourse[end-1].v," m/s a=",drivingCourse[end-1].a," m/s^2",
|
||||
" F_T=",drivingCourse[end-1].F_T," N R_traction=",drivingCourse[end-1].R_traction," N R_wagons=",drivingCourse[end-1].R_wagons," N R_path=",drivingCourse[end-1].R_path," N.")
|
||||
|
||||
elseif drivingCourse[end].v>CS.v_peak
|
||||
elseif drivingCourse[end].v>CS[:v_peak]
|
||||
pop!(drivingCourse)
|
||||
pop!(accelerationSection.dataPoints)
|
||||
elseif drivingCourse[end].s + s_braking > CS.s_exit
|
||||
elseif drivingCourse[end].s + s_braking > CS[:s_exit]
|
||||
pop!(drivingCourse)
|
||||
pop!(accelerationSection.dataPoints)
|
||||
|
||||
|
@ -584,11 +584,11 @@ function addAccelerationPhaseUntilBraking!(CS::CharacteristicSection, drivingCou
|
|||
accelerationSection.t=drivingCourse[end].t-drivingCourse[accelerationSection.dataPoints[1]].t # total running time (in s)
|
||||
accelerationSection.E=drivingCourse[end].E-drivingCourse[accelerationSection.dataPoints[1]].E # total energy consumption (in Ws)
|
||||
|
||||
CS.v_peak=max(drivingCourse[end].v, CS.v_entry) # setting v_peak to the last data points velocity which is the highest reachable value in this characteristic section or to v_entry in case it is higher when driving on a path with high resistances
|
||||
CS.t=CS.t+accelerationSection.t # total running time (in s)
|
||||
CS.E=CS.E+accelerationSection.E # total energy consumption (in Ws)
|
||||
CS[:v_peak]=max(drivingCourse[end].v, CS[:v_entry]) # setting v_peak to the last data points velocity which is the highest reachable value in this characteristic section or to v_entry in case it is higher when driving on a path with high resistances
|
||||
CS[:t]=CS[:t]+accelerationSection.t # total running time (in s)
|
||||
CS[:E]=CS[:E]+accelerationSection.E # total energy consumption (in Ws)
|
||||
|
||||
merge!(CS.behaviorSections, Dict(:acceleration=>accelerationSection))
|
||||
merge!(CS[:behaviorSections], Dict(:acceleration=>accelerationSection))
|
||||
end
|
||||
end # else: just return the given data point number without changes due to the acceleration phase
|
||||
return (CS, drivingCourse)
|
||||
|
@ -597,37 +597,37 @@ end #function addAccelerationPhaseUntilBraking!
|
|||
|
||||
## This function calculates the data points of the cruising phase.
|
||||
# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for cruising if needed.
|
||||
function addCruisingPhase!(CS::CharacteristicSection, drivingCourse::Vector{DataPoint}, s_cruising::AbstractFloat, settings::Dict, train::Dict, CSs::Vector{CharacteristicSection}, cruisingType::String)
|
||||
function addCruisingPhase!(CS::Dict, drivingCourse::Vector{DataPoint}, s_cruising::Real, settings::Dict, train::Dict, CSs::Vector{Dict}, cruisingType::String)
|
||||
# traction effort and resisting forces (in N)
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "cruising") # TODO: or give cruisingSection.type instead of "cruising"?
|
||||
|
||||
if drivingCourse[end].F_T < drivingCourse[end].F_R
|
||||
(CS, drivingCourse) = addDiminishingPhase!(CS, drivingCourse, settings, train, CSs)
|
||||
drivingCourse[end] = DataPoint(calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "cruising"))
|
||||
s_cruising = max(0.0, s_cruising-get(CS.behaviorSections, :diminishing, BehaviorSection()).length)
|
||||
s_cruising = max(0.0, s_cruising-get(CS[:behaviorSections], :diminishing, BehaviorSection()).length)
|
||||
end
|
||||
if drivingCourse[end].v>0.0 && drivingCourse[end].v<=CS.v_peak && drivingCourse[end].s<CS.s_exit && drivingCourse[end].F_T >= drivingCourse[end].F_R
|
||||
# 11/22 old: if drivingCourse[end].v>0.0 && drivingCourse[end].v<=CS.v_peak && drivingCourse[end].s<CS.s_exit
|
||||
if drivingCourse[end].v>0.0 && drivingCourse[end].v<=CS[:v_peak] && drivingCourse[end].s<CS[:s_exit] && drivingCourse[end].F_T >= drivingCourse[end].F_R
|
||||
# 11/22 old: if drivingCourse[end].v>0.0 && drivingCourse[end].v<=CS[:v_peak] && drivingCourse[end].s<CS[:s_exit]
|
||||
cruisingSection=BehaviorSection()
|
||||
cruisingSection.type=cruisingType # type of behavior section
|
||||
cruisingSection.s_entry=drivingCourse[end].s # first position (in m)
|
||||
# 11/22: now it is at the end of the BS: cruisingSection.s_exit=min(drivingCourse[end].s+s_cruising, CS.s_exit) # last position (in m)
|
||||
# 11/22: now it is at the end of the BS: cruisingSection.s_exit=min(drivingCourse[end].s+s_cruising, CS[:s_exit]) # last position (in m)
|
||||
cruisingSection.v_entry=drivingCourse[end].v # entry speed (in m/s)
|
||||
push!(cruisingSection.dataPoints, drivingCourse[end].i)
|
||||
drivingCourse[end].behavior = cruisingSection.type
|
||||
|
||||
# TODO: necessary?
|
||||
s_cruising=min(s_cruising, CS.s_exit-cruisingSection.s_entry)
|
||||
s_cruising=min(s_cruising, CS[:s_exit]-cruisingSection.s_entry)
|
||||
|
||||
# traction effort and resisting forces (in N)
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "cruising") # TODO: or give cruisingSection.type instead of "cruising"?
|
||||
# 11/05 old: drivingCourse[end]=DataPoint(calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "cruising"))
|
||||
|
||||
if settings[:massModel]=="homogeneous strip" && CS.id > 1
|
||||
if settings[:massModel]=="homogeneous strip" && CS[:id] > 1
|
||||
currentStepSize=settings[:stepSize]
|
||||
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
|
||||
while drivingCourse[end].s < CS.s_entry + train[:trainLength] && drivingCourse[end].s<cruisingSection.s_entry+s_cruising && drivingCourse[end].F_T>=drivingCourse[end].F_R #&& drivingCourse[end].v<=CS.v_peak && drivingCourse[end].s<CS.s_exit
|
||||
# TODO: whithout CSs should work as well, no? while drivingCourse[end].s < CSs[CS.id].s_entry + train[:trainLength] && drivingCourse[end].s<cruisingSection.s_entry+s_cruising && drivingCourse[end].F_T>=drivingCourse[end].F_R #&& drivingCourse[end].v<=CS.v_peak && drivingCourse[end].s<CS.s_exit
|
||||
while drivingCourse[end].s < CS[:s_entry] + train[:trainLength] && drivingCourse[end].s<cruisingSection.s_entry+s_cruising && drivingCourse[end].F_T>=drivingCourse[end].F_R #&& drivingCourse[end].v<=CS[:v_peak] && drivingCourse[end].s<CS[:s_exit]
|
||||
# TODO: whithout CSs should work as well, no? while drivingCourse[end].s < CSs[CS[:id]].s_entry + train[:trainLength] && drivingCourse[end].s<cruisingSection.s_entry+s_cruising && drivingCourse[end].F_T>=drivingCourse[end].F_R #&& drivingCourse[end].v<=CS[:v_peak] && drivingCourse[end].s<CS[:s_exit]
|
||||
# the tractive effort is lower than the resisiting forces and the train has use the highest possible effort to try to stay at v_peak OR the mass model homogeneous strip is used and parts of the train are still in former CS
|
||||
#TODO: maybe just consider former CS with different path resistance?
|
||||
#TODO: what about the case: After leaving a former CS with steep gradient the train can accelerate. Now in this tool the train will cruise at v_i. Just accelerating until v_peak could make problems for energy saving by shortening the acceleration phase
|
||||
|
@ -637,9 +637,9 @@ function addCruisingPhase!(CS::CharacteristicSection, drivingCourse::Vector{Data
|
|||
|
||||
# create the next data point
|
||||
if settings[:stepVariable]=="s in m"
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", currentStepSize, CS.id))
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", currentStepSize, CS[:id]))
|
||||
else
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", train[:trainLength]/(10.0^cycle), CS.id)) # TODO which step size should be used?
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", train[:trainLength]/(10.0^cycle), CS[:id])) # TODO which step size should be used?
|
||||
end
|
||||
drivingCourse[end].behavior = cruisingSection.type
|
||||
push!(cruisingSection.dataPoints, drivingCourse[end].i)
|
||||
|
@ -655,13 +655,13 @@ function addCruisingPhase!(CS::CharacteristicSection, drivingCourse::Vector{Data
|
|||
|
||||
# check which limit was reached and adjust the currentStepSize for the next cycle
|
||||
if cycle < approximationLevel+1
|
||||
if drivingCourse[end].s>cruisingSection.s_entry+s_cruising # TODO also the following? drivingCourse[end].s > CSs[CS.id].s_entry + train[:trainLength]))
|
||||
if drivingCourse[end].s>cruisingSection.s_entry+s_cruising # TODO also the following? drivingCourse[end].s > CSs[CS[:id]].s_entry + train[:trainLength]))
|
||||
if settings[:stepVariable] == "s in m"
|
||||
currentStepSize=cruisingSection.s_entry+s_cruising-drivingCourse[end-1].s
|
||||
else
|
||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||
end
|
||||
elseif drivingCourse[end].s==cruisingSection.s_entry+s_cruising # || drivingCourse[end].s==CS.s_exit
|
||||
elseif drivingCourse[end].s==cruisingSection.s_entry+s_cruising # || drivingCourse[end].s==CS[:s_exit]
|
||||
break
|
||||
elseif drivingCourse[end].F_T < drivingCourse[end].F_R
|
||||
# if settings[:stepVariable] == "s in m"
|
||||
|
@ -669,11 +669,11 @@ function addCruisingPhase!(CS::CharacteristicSection, drivingCourse::Vector{Data
|
|||
# else
|
||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||
# end
|
||||
elseif drivingCourse[end].s >= CS.s_entry + train[:trainLength]
|
||||
# TODO: whithout CSs should work as well, no? elseif drivingCourse[end].s >= CSs[CS.id].s_entry + train[:trainLength]
|
||||
elseif drivingCourse[end].s >= CS[:s_entry] + train[:trainLength]
|
||||
# TODO: whithout CSs should work as well, no? elseif drivingCourse[end].s >= CSs[CS[:id]].s_entry + train[:trainLength]
|
||||
break
|
||||
else # TODO copied from addAccelerationPhase -> probably not needed here !?
|
||||
error("ERROR at cruising phase: With the step variable ",settings[:stepVariable]," the while loop will be left although the if cases don't apply in CS",CS.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
|
||||
error("ERROR at cruising phase: With the step variable ",settings[:stepVariable]," the while loop will be left although the if cases don't apply in CS",CS[:id]," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
|
||||
end
|
||||
|
||||
# delete last data point for recalculating the last step with reduced step size
|
||||
|
@ -696,7 +696,7 @@ function addCruisingPhase!(CS::CharacteristicSection, drivingCourse::Vector{Data
|
|||
(CS, drivingCourse)=addDiminishingPhase!(CS, drivingCourse, settings, train, CSs)
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "cruising")
|
||||
|
||||
# s_cruising=max(0.0, s_cruising-get(CS.behaviorSections, :diminishing, BehaviorSection()).length)
|
||||
# s_cruising=max(0.0, s_cruising-get(CS[:behaviorSections], :diminishing, BehaviorSection()).length)
|
||||
|
||||
else
|
||||
|
||||
|
@ -714,7 +714,7 @@ function addCruisingPhase!(CS::CharacteristicSection, drivingCourse::Vector{Data
|
|||
s_cruisingRemaining=cruisingSection.s_entry+s_cruising-drivingCourse[end].s
|
||||
|
||||
# create the next data point
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", s_cruisingRemaining, CS.id))
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", s_cruisingRemaining, CS[:id]))
|
||||
drivingCourse[end].behavior = cruisingSection.type
|
||||
push!(cruisingSection.dataPoints, drivingCourse[end].i)
|
||||
end
|
||||
|
@ -726,10 +726,10 @@ function addCruisingPhase!(CS::CharacteristicSection, drivingCourse::Vector{Data
|
|||
cruisingSection.t=drivingCourse[end].t-drivingCourse[cruisingSection.dataPoints[1]].t # total running time (in s)
|
||||
cruisingSection.E=drivingCourse[end].E-drivingCourse[cruisingSection.dataPoints[1]].E # total energy consumption (in Ws)
|
||||
|
||||
CS.t=CS.t+cruisingSection.t # total running time (in s)
|
||||
CS.E=CS.E+cruisingSection.E # total energy consumption (in Ws)
|
||||
CS[:t]=CS[:t]+cruisingSection.t # total running time (in s)
|
||||
CS[:E]=CS[:E]+cruisingSection.E # total energy consumption (in Ws)
|
||||
|
||||
merge!(CS.behaviorSections, Dict(Symbol(cruisingSection.type) => cruisingSection))
|
||||
merge!(CS[:behaviorSections], Dict(Symbol(cruisingSection.type) => cruisingSection))
|
||||
end # else: return the characteristic section without a cruising section
|
||||
|
||||
return (CS, drivingCourse)
|
||||
|
@ -737,11 +737,11 @@ end #function addCruisingPhase!
|
|||
|
||||
|
||||
## This function calculates the data points for diminishing run when using maximum tractive effort and still getting slower
|
||||
function addDiminishingPhase!(CS::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{CharacteristicSection})
|
||||
function addDiminishingPhase!(CS::Dict, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{Dict})
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "diminishing")
|
||||
|
||||
if drivingCourse[end].F_T <= drivingCourse[end].F_R && drivingCourse[end].v > 0.0 && drivingCourse[end].s<CS.s_exit
|
||||
#drivingCourse[end].v>0.0 && drivingCourse[end].v<=CS.v_peak && drivingCourse[end].s<CS.s_exit
|
||||
if drivingCourse[end].F_T <= drivingCourse[end].F_R && drivingCourse[end].v > 0.0 && drivingCourse[end].s<CS[:s_exit]
|
||||
#drivingCourse[end].v>0.0 && drivingCourse[end].v<=CS[:v_peak] && drivingCourse[end].s<CS[:s_exit]
|
||||
diminishingSection=BehaviorSection()
|
||||
diminishingSection.type="diminishing" # type of behavior section
|
||||
diminishingSection.s_entry=drivingCourse[end].s # first position (in m)
|
||||
|
@ -751,9 +751,9 @@ function addDiminishingPhase!(CS::CharacteristicSection, drivingCourse::Vector{D
|
|||
|
||||
currentStepSize=settings[:stepSize] # initializing the step size that can be reduced near intersections
|
||||
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
|
||||
s_braking=max(0.0, ceil((CS.v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel))
|
||||
while drivingCourse[end].F_T <= drivingCourse[end].F_R && drivingCourse[end].s+s_braking<CS.s_exit && drivingCourse[end].v>0.0 # as long as s_i + s_braking < s_CSend
|
||||
# 11/22 old without F_T<=F_R while drivingCourse[end].s+s_braking<CS.s_exit && drivingCourse[end].v>0.0 # as long as s_i + s_braking < s_CSend
|
||||
s_braking=max(0.0, ceil((CS[:v_exit]^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel))
|
||||
while drivingCourse[end].F_T <= drivingCourse[end].F_R && drivingCourse[end].s+s_braking<CS[:s_exit] && drivingCourse[end].v>0.0 # as long as s_i + s_braking < s_CSend
|
||||
# 11/22 old without F_T<=F_R while drivingCourse[end].s+s_braking<CS[:s_exit] && drivingCourse[end].v>0.0 # as long as s_i + s_braking < s_CSend
|
||||
|
||||
#11/22 calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, diminishingSection.type)
|
||||
|
||||
|
@ -765,11 +765,11 @@ function addDiminishingPhase!(CS::CharacteristicSection, drivingCourse::Vector{D
|
|||
#end
|
||||
|
||||
# create the next data point
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS.id))
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
|
||||
drivingCourse[end].behavior = diminishingSection.type
|
||||
push!(diminishingSection.dataPoints, drivingCourse[end].i)
|
||||
|
||||
s_braking=max(0.0, ceil((CS.v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel))
|
||||
s_braking=max(0.0, ceil((CS[:v_exit]^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel))
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, diminishingSection.type)
|
||||
end #while
|
||||
|
||||
|
@ -778,18 +778,18 @@ function addDiminishingPhase!(CS::CharacteristicSection, drivingCourse::Vector{D
|
|||
if drivingCourse[end].v<=0.0
|
||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||
|
||||
elseif drivingCourse[end].s + s_braking > CS.s_exit
|
||||
elseif drivingCourse[end].s + s_braking > CS[:s_exit]
|
||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||
|
||||
elseif drivingCourse[end].s + s_braking==CS.s_exit
|
||||
# 11/21 old without s_braking: elseif drivingCourse[end].s==CS.s_exit
|
||||
elseif drivingCourse[end].s + s_braking==CS[:s_exit]
|
||||
# 11/21 old without s_braking: elseif drivingCourse[end].s==CS[:s_exit]
|
||||
break
|
||||
|
||||
elseif drivingCourse[end].F_T > drivingCourse[end].F_R
|
||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||
|
||||
else
|
||||
error("ERROR during diminishing run: With the step variable ",settings[:stepVariable]," the while loop will be left although s+s_braking<s_exit && v>0.0 in CS",CS.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
|
||||
error("ERROR during diminishing run: With the step variable ",settings[:stepVariable]," the while loop will be left although s+s_braking<s_exit && v>0.0 in CS",CS[:id]," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
|
||||
end
|
||||
# delete last data point for recalculating the last step with reduced step size
|
||||
pop!(drivingCourse)
|
||||
|
@ -798,11 +798,11 @@ function addDiminishingPhase!(CS::CharacteristicSection, drivingCourse::Vector{D
|
|||
else # if the level of approximation is reached
|
||||
if drivingCourse[end].v<=0.0
|
||||
# push!(diminishingSection.dataPoints, drivingCourse[end].i)
|
||||
error("ERROR: The train stops during diminishing run in CS",CS.id," because the maximum tractive effort is lower than the resistant forces.",
|
||||
error("ERROR: The train stops during diminishing run in CS",CS[:id]," because the maximum tractive effort is lower than the resistant forces.",
|
||||
" Before the stop the last point has the values s=",drivingCourse[end-1].s," m v=",drivingCourse[end-1].v," m/s a=",drivingCourse[end-1].a," m/s^2",
|
||||
" F_T=",drivingCourse[end-1].F_T," N R_traction=",drivingCourse[end-1].R_traction," N R_wagons=",drivingCourse[end-1].R_wagons," N R_path=",drivingCourse[end-1].R_path," N.")
|
||||
|
||||
elseif drivingCourse[end].s + s_braking > CS.s_exit
|
||||
elseif drivingCourse[end].s + s_braking > CS[:s_exit]
|
||||
pop!(drivingCourse)
|
||||
pop!(diminishingSection.dataPoints)
|
||||
|
||||
|
@ -822,10 +822,10 @@ function addDiminishingPhase!(CS::CharacteristicSection, drivingCourse::Vector{D
|
|||
diminishingSection.length=diminishingSection.s_exit-diminishingSection.s_entry # total length (in m)
|
||||
diminishingSection.t=drivingCourse[end].t-drivingCourse[diminishingSection.dataPoints[1]].t # total running time (in s)
|
||||
diminishingSection.E=drivingCourse[end].E-drivingCourse[diminishingSection.dataPoints[1]].E # total energy consumption (in Ws)
|
||||
CS.t=CS.t+diminishingSection.t # total running time (in s)
|
||||
CS.E=CS.E+diminishingSection.E # total energy consumption (in Ws)
|
||||
CS[:t]=CS[:t]+diminishingSection.t # total running time (in s)
|
||||
CS[:E]=CS[:E]+diminishingSection.E # total energy consumption (in Ws)
|
||||
|
||||
merge!(CS.behaviorSections, Dict(:diminishing=>diminishingSection))
|
||||
merge!(CS[:behaviorSections], Dict(:diminishing=>diminishingSection))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -835,11 +835,11 @@ end #function addDiminishingPhase!
|
|||
|
||||
## This function calculates the data points of the coasting phase.
|
||||
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the coasting section
|
||||
function addCoastingPhaseUntilBraking!(CS::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{CharacteristicSection})
|
||||
function addCoastingPhaseUntilBraking!(CS::Dict, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{Dict})
|
||||
## if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
|
||||
#formerSpeedLimits = detectFormerSpeedLimits(CSs, CS.id, drivingCourse[end], train[:trainLength])
|
||||
#formerSpeedLimits = detectFormerSpeedLimits(CSs, CS[:id], drivingCourse[end], train[:trainLength])
|
||||
|
||||
if drivingCourse[end].v>CS.v_exit && drivingCourse[end].s<CS.s_exit
|
||||
if drivingCourse[end].v>CS[:v_exit] && drivingCourse[end].s<CS[:s_exit]
|
||||
coastingSection=BehaviorSection()
|
||||
coastingSection.type="coasting" # type of behavior section
|
||||
coastingSection.s_entry=drivingCourse[end].s # first position (in m)
|
||||
|
@ -850,8 +850,8 @@ function addCoastingPhaseUntilBraking!(CS::CharacteristicSection, drivingCourse:
|
|||
currentStepSize=settings[:stepSize] # initializing the step size that can be reduced near intersections
|
||||
# 08/24 old for cycle in 1:3 # first cycle with normal step size, second cycle with reduced step size, third cycle with more reduced step size
|
||||
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
|
||||
s_braking=ceil((CS.v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel)
|
||||
while drivingCourse[end].v>CS.v_exit && drivingCourse[end].v<=CS.v_peak && drivingCourse[end].s + s_braking < CS.s_exit # as long as s_i + s_braking < s_CSend
|
||||
s_braking=ceil((CS[:v_exit]^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel)
|
||||
while drivingCourse[end].v>CS[:v_exit] && drivingCourse[end].v<=CS[:v_peak] && drivingCourse[end].s + s_braking < CS[:s_exit] # as long as s_i + s_braking < s_CSend
|
||||
# traction effort and resisting forces (in N):
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, coastingSection.type)
|
||||
|
||||
|
@ -859,38 +859,38 @@ function addCoastingPhaseUntilBraking!(CS::CharacteristicSection, drivingCourse:
|
|||
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train[:m_train]/train[:ξ_train]
|
||||
|
||||
# creating the next data point
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS.id))
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
|
||||
drivingCourse[end].behavior = coastingSection.type
|
||||
push!(coastingSection.dataPoints, drivingCourse[end].i)
|
||||
|
||||
s_braking=ceil((CS.v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking])
|
||||
s_braking=ceil((CS[:v_exit]^2-drivingCourse[end].v^2)/2/train[:a_braking])
|
||||
|
||||
|
||||
end # while
|
||||
|
||||
# check which limit was reached and adjust the currentStepSize for the next cycle
|
||||
if cycle < approximationLevel+1
|
||||
if drivingCourse[end].s + s_braking > CS.s_exit
|
||||
if drivingCourse[end].s + s_braking > CS[:s_exit]
|
||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||
|
||||
elseif drivingCourse[end].v < CS.v_exit # TODO: if accelereation and coasting functions will be combined this case is only for coasting
|
||||
elseif drivingCourse[end].v < CS[:v_exit] # TODO: if accelereation and coasting functions will be combined this case is only for coasting
|
||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||
|
||||
elseif drivingCourse[end].v > CS.v_peak
|
||||
elseif drivingCourse[end].v > CS[:v_peak]
|
||||
if settings[:stepVariable]=="v in m/s"
|
||||
currentStepSize = CS.v_peak-drivingCourse[end-1].v
|
||||
currentStepSize = CS[:v_peak]-drivingCourse[end-1].v
|
||||
else
|
||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||
end
|
||||
elseif drivingCourse[end].s + s_braking == CS.s_exit
|
||||
elseif drivingCourse[end].s + s_braking == CS[:s_exit]
|
||||
break
|
||||
|
||||
elseif drivingCourse[end].v == CS.v_exit
|
||||
elseif drivingCourse[end].v == CS[:v_exit]
|
||||
break
|
||||
|
||||
else
|
||||
# TODO: not needed. just for testing
|
||||
error("ERROR at coasting until braking phase: With the step variable ",settings[:stepVariable]," the while loop will be left although v<v_peak and s+s_braking<s_exit in CS",CS.id," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
|
||||
error("ERROR at coasting until braking phase: With the step variable ",settings[:stepVariable]," the while loop will be left although v<v_peak and s+s_braking<s_exit in CS",CS[:id]," with s=" ,drivingCourse[end].s," m and v=",drivingCourse[end].v," m/s")
|
||||
end
|
||||
# delete last data point for recalculating the last step with reduced step size
|
||||
pop!(drivingCourse)
|
||||
|
@ -898,23 +898,23 @@ function addCoastingPhaseUntilBraking!(CS::CharacteristicSection, drivingCourse:
|
|||
|
||||
else # if the level of approximation is reached
|
||||
if drivingCourse[end].v<=0.0
|
||||
println("INFO: The train stops during the coasting phase in CS",CS.id," ",
|
||||
println("INFO: The train stops during the coasting phase in CS",CS[:id]," ",
|
||||
" Before the stop the last point has the values s=",drivingCourse[end-1].s," m v=",drivingCourse[end-1].v," m/s a=",drivingCourse[end-1].a," m/s^2",
|
||||
" F_T=",drivingCourse[end-1].F_T," N R_traction=",drivingCourse[end-1].R_traction," N R_wagons=",drivingCourse[end-1].R_wagons," N R_path=",drivingCourse[end-1].R_path," N and s_braking=",s_braking,"m.")
|
||||
|
||||
elseif drivingCourse[end].s + s_braking > CS.s_exit
|
||||
elseif drivingCourse[end].s + s_braking > CS[:s_exit]
|
||||
# delete last data point because it went to far
|
||||
pop!(drivingCourse)
|
||||
pop!(coastingSection.dataPoints)
|
||||
|
||||
elseif drivingCourse[end].v > CS.v_peak # if the train gets to fast it has to brake # TODO: if accelereation and coasting functions will be combined this case is different for coasting and also the order of if cases is different
|
||||
elseif drivingCourse[end].v > CS[:v_peak] # if the train gets to fast it has to brake # TODO: if accelereation and coasting functions will be combined this case is different for coasting and also the order of if cases is different
|
||||
# while coasting the train brakes to hold v_peak (only one data point in the end of coasting is calculated like cruising at v_peak)
|
||||
drivingCourse[end-1].a=0.0
|
||||
s_braking=ceil((CS.v_exit^2-drivingCourse[end-1].v^2)/2/train[:a_braking])
|
||||
s_braking=ceil((CS[:v_exit]^2-drivingCourse[end-1].v^2)/2/train[:a_braking])
|
||||
|
||||
# recalculate s, t, v, E
|
||||
#drivingCourse[end].Δs= CS.s_exit-drivingCourse[end-1].s - s_braking # step size (in m) # TODO: the coasting section is currently realised with using distance steps. For example t_braking could also be used
|
||||
drivingCourse[end].Δs=min(currentStepSize, CS.s_exit-(drivingCourse[end-1].s+s_braking)) # TODO: if settings[:stepVariable]=="s in m"
|
||||
#drivingCourse[end].Δs= CS[:s_exit]-drivingCourse[end-1].s - s_braking # step size (in m) # TODO: the coasting section is currently realised with using distance steps. For example t_braking could also be used
|
||||
drivingCourse[end].Δs=min(currentStepSize, CS[:s_exit]-(drivingCourse[end-1].s+s_braking)) # TODO: if settings[:stepVariable]=="s in m"
|
||||
drivingCourse[end].Δt=drivingCourse[end].Δs/drivingCourse[end-1].v # step size (in s)
|
||||
drivingCourse[end].Δv=0.0 # step size (in m/s)
|
||||
|
||||
|
@ -943,10 +943,10 @@ function addCoastingPhaseUntilBraking!(CS::CharacteristicSection, drivingCourse:
|
|||
coastingSection.t=drivingCourse[end].t-drivingCourse[coastingSection.dataPoints[1]].t # total running time (in s)
|
||||
coastingSection.E=drivingCourse[end].E-drivingCourse[coastingSection.dataPoints[1]].E # total energy consumption (in Ws)
|
||||
|
||||
CS.t=CS.t+coastingSection.t # total running time (in s)
|
||||
CS.E=CS.E+coastingSection.E # total energy consumption (in Ws)
|
||||
CS[:t]=CS[:t]+coastingSection.t # total running time (in s)
|
||||
CS[:E]=CS[:E]+coastingSection.E # total energy consumption (in Ws)
|
||||
|
||||
merge!(CS.behaviorSections, Dict(:coasting=>coastingSection))
|
||||
merge!(CS[:behaviorSections], Dict(:coasting=>coastingSection))
|
||||
end ## else: just return the given data point number without changes due to the coasting phase
|
||||
return (CS, drivingCourse)
|
||||
end #function addCoastingPhaseUntilBraking!
|
||||
|
@ -954,13 +954,13 @@ end #function addCoastingPhaseUntilBraking!
|
|||
|
||||
## This function calculates the data points of the braking phase. (standard braking phase with only two data points)
|
||||
# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for braking if needed.
|
||||
function addBrakingPhase!(CS::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{CharacteristicSection}) #, s_braking::AbstractFloat)
|
||||
# function addBrakingPhase!(CS::CharacteristicSection, drivingCourse::Vector{DataPoint}, massModel::String, train::Dict, CSs::Vector{CharacteristicSection}) #, s_braking::AbstractFloat)
|
||||
if drivingCourse[end].v>CS.v_exit && drivingCourse[end].s<CS.s_exit
|
||||
function addBrakingPhase!(CS::Dict, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{Dict}) #, s_braking::AbstractFloat)
|
||||
# function addBrakingPhase!(CS::Dict, drivingCourse::Vector{DataPoint}, massModel::String, train::Dict, CSs::Vector{Dict}) #, s_braking::AbstractFloat)
|
||||
if drivingCourse[end].v>CS[:v_exit] && drivingCourse[end].s<CS[:s_exit]
|
||||
brakingSection=BehaviorSection()
|
||||
brakingSection.type="braking" # type of behavior section
|
||||
brakingSection.s_entry=drivingCourse[end].s # first position (in m)
|
||||
brakingSection.s_exit=CS.s_exit # last position (in m)
|
||||
brakingSection.s_exit=CS[:s_exit] # last position (in m)
|
||||
brakingSection.v_entry=drivingCourse[end].v # entry speed (in m/s)
|
||||
push!(brakingSection.dataPoints, drivingCourse[end].i) # refering from the breaking section to the first of its data points
|
||||
drivingCourse[end].behavior = brakingSection.type
|
||||
|
@ -975,7 +975,7 @@ function addBrakingPhase!(CS::CharacteristicSection, drivingCourse::Vector{DataP
|
|||
|
||||
# calculate s, t, v
|
||||
drivingCourse[end].s=brakingSection.s_exit # position (in m)
|
||||
drivingCourse[end].v=CS.v_exit # velocity (in m/s)
|
||||
drivingCourse[end].v=CS[:v_exit] # velocity (in m/s)
|
||||
drivingCourse[end].Δs=drivingCourse[end].s-drivingCourse[end-1].s # step size (in m)
|
||||
drivingCourse[end].Δv=drivingCourse[end].v-drivingCourse[end-1].v # step size (in m/s)
|
||||
|
||||
|
@ -983,9 +983,9 @@ function addBrakingPhase!(CS::CharacteristicSection, drivingCourse::Vector{DataP
|
|||
drivingCourse[end-1].a=(drivingCourse[end].v^2-drivingCourse[end-1].v^2)/2/drivingCourse[end].Δs
|
||||
#= if drivingCourse[end-1].a<train[:a_braking] || drivingCourse[end-1].a>=0.0
|
||||
println("")
|
||||
println("Warning: a_braking gets to high in CS ",CS.id, " with a=",drivingCourse[end-1].a ," > ",train[:a_braking])
|
||||
println("Warning: a_braking gets to high in CS ",CS[:id], " with a=",drivingCourse[end-1].a ," > ",train[:a_braking])
|
||||
println(" v=",drivingCourse[end].v," v_i-1=",drivingCourse[end-1].v, " Δs=",drivingCourse[end].Δs)
|
||||
println(" v_exit=",CS.v_exit)
|
||||
println(" v_exit=",CS[:v_exit])
|
||||
println("")
|
||||
end =#
|
||||
drivingCourse[end].Δt=drivingCourse[end].Δv/drivingCourse[end-1].a # step size (in s)
|
||||
|
@ -1001,10 +1001,10 @@ function addBrakingPhase!(CS::CharacteristicSection, drivingCourse::Vector{DataP
|
|||
brakingSection.t=drivingCourse[end].Δt # total running time (in s)
|
||||
brakingSection.E=drivingCourse[end].ΔE # total energy consumption (in Ws)
|
||||
|
||||
CS.t=CS.t+brakingSection.t # total running time (in s)
|
||||
CS.E=CS.E+brakingSection.E # total energy consumption (in Ws)
|
||||
CS[:t]=CS[:t]+brakingSection.t # total running time (in s)
|
||||
CS[:E]=CS[:E]+brakingSection.E # total energy consumption (in Ws)
|
||||
|
||||
merge!(CS.behaviorSections, Dict(:braking=>brakingSection))
|
||||
merge!(CS[:behaviorSections], Dict(:braking=>brakingSection))
|
||||
end # else: return the characteristic section without a braking section
|
||||
return (CS, drivingCourse)
|
||||
end #function addBrakingPhase!
|
||||
|
@ -1012,8 +1012,8 @@ end #function addBrakingPhase!
|
|||
|
||||
## This function calculates the data points of the braking phase. # 09/07 new braking phase with more than two data points
|
||||
# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for braking if needed.
|
||||
function addBrakingPhaseStepwise!(CS::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{CharacteristicSection}) #, s_braking::AbstractFloat)
|
||||
if drivingCourse[end].v > CS.v_exit && drivingCourse[end].s < CS.s_exit
|
||||
function addBrakingPhaseStepwise!(CS::Dict, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{Dict}) #, s_braking::AbstractFloat)
|
||||
if drivingCourse[end].v > CS[:v_exit] && drivingCourse[end].s < CS[:s_exit]
|
||||
brakingSection=BehaviorSection()
|
||||
brakingSection.type="braking" # type of behavior section
|
||||
brakingSection.s_entry=drivingCourse[end].s # first position (in m)
|
||||
|
@ -1023,7 +1023,7 @@ function addBrakingPhaseStepwise!(CS::CharacteristicSection, drivingCourse::Vect
|
|||
|
||||
currentStepSize=settings[:stepSize] # initializing the step size that can be reduced near intersections
|
||||
velocityIsPositive=true
|
||||
while drivingCourse[end].v > CS.v_exit && drivingCourse[end].s < CS.s_exit && velocityIsPositive
|
||||
while drivingCourse[end].v > CS[:v_exit] && drivingCourse[end].s < CS[:s_exit] && velocityIsPositive
|
||||
# traction effort and resisting forces (in N):
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, brakingSection.type)
|
||||
|
||||
|
@ -1040,17 +1040,17 @@ function addBrakingPhaseStepwise!(CS::CharacteristicSection, drivingCourse::Vect
|
|||
break
|
||||
end
|
||||
end
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS.id))
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
|
||||
drivingCourse[end].behavior = brakingSection.type
|
||||
push!(brakingSection.dataPoints, drivingCourse[end].i)
|
||||
|
||||
# s_braking=ceil((CS.v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking])
|
||||
# s_braking=ceil((CS[:v_exit]^2-drivingCourse[end].v^2)/2/train[:a_braking])
|
||||
end # while
|
||||
|
||||
if drivingCourse[end].v < CS.v_exit || !velocityIsPositive
|
||||
if drivingCourse[end].v < CS[:v_exit] || !velocityIsPositive
|
||||
# calculate s, t, v
|
||||
drivingCourse[end].s=CS.s_exit # position (in m)
|
||||
drivingCourse[end].v=CS.v_exit # velocity (in m/s)
|
||||
drivingCourse[end].s=CS[:s_exit] # position (in m)
|
||||
drivingCourse[end].v=CS[:v_exit] # velocity (in m/s)
|
||||
drivingCourse[end].Δs=drivingCourse[end].s-drivingCourse[end-1].s # step size (in m)
|
||||
drivingCourse[end].Δv=drivingCourse[end].v-drivingCourse[end-1].v # step size (in m/s)
|
||||
|
||||
|
@ -1059,7 +1059,7 @@ function addBrakingPhaseStepwise!(CS::CharacteristicSection, drivingCourse::Vect
|
|||
# println("a_braking_last=",drivingCourse[end-1].a," m/s^2 und a_braking_standard=" , train[:a_braking])
|
||||
|
||||
# if drivingCourse[end-1].a<train[:a_braking] || drivingCourse[end-1].a>=0.0
|
||||
# println("Warning: a_braking gets to high in CS ",CS.id, " with a=",drivingCourse[end-1].a ," > ",train[:a_braking])
|
||||
# println("Warning: a_braking gets to high in CS ",CS[:id], " with a=",drivingCourse[end-1].a ," > ",train[:a_braking])
|
||||
# end
|
||||
drivingCourse[end].Δt=drivingCourse[end].Δv/drivingCourse[end-1].a # step size (in s)
|
||||
drivingCourse[end].t=drivingCourse[end-1].t+drivingCourse[end].Δt # point in time (in s)
|
||||
|
@ -1068,7 +1068,7 @@ function addBrakingPhaseStepwise!(CS::CharacteristicSection, drivingCourse::Vect
|
|||
drivingCourse[end].W=drivingCourse[end-1].W+drivingCourse[end].ΔW # mechanical work (in Ws)
|
||||
drivingCourse[end].ΔE=drivingCourse[end].ΔW # energy consumption in this step (in Ws)
|
||||
drivingCourse[end].E=drivingCourse[end-1].E+drivingCourse[end].ΔE # energy consumption (in Ws)
|
||||
elseif drivingCourse[end].s > CS.s_exit
|
||||
elseif drivingCourse[end].s > CS[:s_exit]
|
||||
error("Beim Bremsen wurde das CS-Ende überschritten, aber nicht v_exit unterschritten !!")
|
||||
else
|
||||
|
||||
|
@ -1081,10 +1081,10 @@ function addBrakingPhaseStepwise!(CS::CharacteristicSection, drivingCourse::Vect
|
|||
brakingSection.t=drivingCourse[end].t-drivingCourse[brakingSection.dataPoints[1]].t # total running time (in s)
|
||||
brakingSection.E=drivingCourse[end].E-drivingCourse[brakingSection.dataPoints[1]].E # total energy consumption (in Ws)
|
||||
|
||||
CS.t=CS.t+brakingSection.t # total running time (in s)
|
||||
CS.E=CS.E+brakingSection.E # total energy consumption (in Ws)
|
||||
CS[:t]=CS[:t]+brakingSection.t # total running time (in s)
|
||||
CS[:E]=CS[:E]+brakingSection.E # total energy consumption (in Ws)
|
||||
|
||||
merge!(CS.behaviorSections, Dict(:braking=>brakingSection))
|
||||
merge!(CS[:behaviorSections], Dict(:braking=>brakingSection))
|
||||
end # else: return the characteristic section without a braking section
|
||||
return (CS, drivingCourse)
|
||||
end #function addBrakingPhaseStepwise!
|
||||
|
@ -1092,7 +1092,7 @@ end #function addBrakingPhaseStepwise!
|
|||
|
||||
## This function calculates the data point of the standstill.
|
||||
# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the standstill if needed.
|
||||
function addStandstill!(CS::CharacteristicSection, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{CharacteristicSection})
|
||||
function addStandstill!(CS::Dict, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{Dict})
|
||||
|
||||
if drivingCourse[end].v == 0.0
|
||||
standstillSection=BehaviorSection()
|
||||
|
@ -1112,7 +1112,7 @@ function addStandstill!(CS::CharacteristicSection, drivingCourse::Vector{DataPoi
|
|||
# traction effort and resisting forces (in N)
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, standstillSection.type)
|
||||
|
||||
merge!(CS.behaviorSections, Dict(:standstill => standstillSection))
|
||||
merge!(CS[:behaviorSections], Dict(:standstill => standstillSection))
|
||||
end # else: return the characteristic section without a standstillSection section
|
||||
return (CS, drivingCourse)
|
||||
end #function addStandstill!
|
||||
|
|
|
@ -13,81 +13,82 @@ approximationLevel = 6 # TODO: define it in TrainRun and give it to each fu
|
|||
|
||||
# calculate a train run focussing on using the minimum possible running time
|
||||
function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train::Dict)
|
||||
CSs::Vector{CharacteristicSection} = movingSection[:characteristicSections]
|
||||
CSs::Vector{Dict} = movingSection[:characteristicSections]
|
||||
|
||||
startingPoint=DataPoint()
|
||||
startingPoint.i=1
|
||||
startingPoint.s=CSs[1].s_entry
|
||||
startingPoint.s=CSs[1][:s_entry]
|
||||
drivingCourse=[startingPoint] # List of data points
|
||||
|
||||
# for CS in CSs
|
||||
for csId in 1:length(CSs)
|
||||
# println("CS",csId)
|
||||
# check if the CS has a cruising section
|
||||
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_peak^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
|
||||
CS = CSs[csId]
|
||||
BSs = CS[:behaviorSections]
|
||||
s_breakFree = get(BSs, :breakFree, BehaviorSection()).length
|
||||
s_clearing = get(BSs, :clearing, BehaviorSection()).length
|
||||
s_acceleration = get(BSs, :acceleration, BehaviorSection()).length
|
||||
s_braking = max(0.0, ceil((CS[:v_exit]^2-CS[:v_peak]^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
|
||||
|
||||
# calculate the cruising sections length
|
||||
s_cruising=CSs[csId].length-s_breakFree-s_clearing-s_acceleration-s_braking
|
||||
s_cruising=CS[: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_peak and v_exit
|
||||
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
|
||||
delete!(BSs, :breakFree)
|
||||
delete!(BSs, :clearing)
|
||||
delete!(BSs, :acceleration)
|
||||
delete!(BSs, :diminishing)
|
||||
delete!(BSs, :cruising)
|
||||
CS[:E]=0.0
|
||||
CS[:t]=0.0
|
||||
|
||||
|
||||
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")
|
||||
if s_clearing == CS[:length]
|
||||
# 09/06 TODO: thought about using "cruising" because it is used in EnergySaving and not clearing (CS, drivingCourse)=addCruisingPhase!(CS, drivingCourse, s_clearing, settings, train, CSs, "cruising")
|
||||
(CS, drivingCourse)=addCruisingPhase!(CS, drivingCourse, s_clearing, settings, train, CSs, "clearing")
|
||||
elseif s_cruising == CS[:length]
|
||||
(CS, drivingCourse)=addCruisingPhase!(CS, 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 < CSs[csId].v_peak
|
||||
(CSs[csId], drivingCourse)=addAccelerationPhase!(CSs[csId], drivingCourse, settings, train, CSs)
|
||||
if drivingCourse[end].v < CS[:v_peak]
|
||||
(CS, drivingCourse)=addAccelerationPhase!(CS, drivingCourse, settings, train, CSs)
|
||||
end #if
|
||||
|
||||
if CSs[csId].s_exit-drivingCourse[end].s-max(0.0, (CSs[csId].v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking]) < -0.001 # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
|
||||
if CS[:s_exit]-drivingCourse[end].s-max(0.0, (CS[: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=",((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_peak=",CSs[csId].v_peak," v_exit=",CSs[csId].v_exit)
|
||||
println(" before acceleration in CS",csId, " with s=",drivingCourse[end].s," s_braking=",((CS[:v_exit]^2-drivingCourse[end].v^2)/2/train[:a_braking])," s_exit=",CS[:s_exit])
|
||||
println(" and v=",drivingCourse[end].v," v_peak=",CS[:v_peak]," v_exit=",CS[:v_exit])
|
||||
end
|
||||
|
||||
s_braking=max(0.0, ceil((CSs[csId].v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
|
||||
s_cruising=CSs[csId].s_exit-drivingCourse[end].s-s_braking
|
||||
s_braking=max(0.0, ceil((CS[: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=CS[:s_exit]-drivingCourse[end].s-s_braking
|
||||
|
||||
if s_cruising > 0.0
|
||||
(CSs[csId], drivingCourse)=addCruisingPhase!(CSs[csId], drivingCourse, s_cruising, settings, train, CSs, "cruising")
|
||||
(CS, drivingCourse)=addCruisingPhase!(CS, drivingCourse, s_cruising, settings, train, CSs, "cruising")
|
||||
end
|
||||
else
|
||||
|
||||
if CSs[csId].v_entry < CSs[csId].v_peak || s_acceleration > 0.0 # or instead of " || s_acceleration > 0.0" use "v_entry <= v_peak" or "v_i <= v_peak"
|
||||
# 09/09 old (not sufficient for steep gradients): if CSs[csId].v_entry < CSs[csId].v_peak
|
||||
(CSs[csId], drivingCourse)=addAccelerationPhaseUntilBraking!(CSs[csId], drivingCourse, settings, train, CSs)
|
||||
if CS[:v_entry] < CS[:v_peak] || s_acceleration > 0.0 # or instead of " || s_acceleration > 0.0" use "v_entry <= v_peak" or "v_i <= v_peak"
|
||||
# 09/09 old (not sufficient for steep gradients): if CS[:v_entry] < CS[:v_peak]
|
||||
(CS, drivingCourse)=addAccelerationPhaseUntilBraking!(CS, drivingCourse, settings, train, CSs)
|
||||
end #if
|
||||
end #if
|
||||
|
||||
|
||||
s_braking=max(0.0, ceil((CSs[csId].v_exit^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
|
||||
s_braking=max(0.0, ceil((CS[: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 > 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)
|
||||
if drivingCourse[end].v > CS[:v_exit]
|
||||
#(CS, drivingCourse)=addBrakingPhase!(CS, drivingCourse, settings[:massModel], train, CSs)
|
||||
(CS, drivingCourse)=addBrakingPhase!(CS, drivingCourse, settings, train, CSs)
|
||||
end #if
|
||||
|
||||
#= 09/20 old and should never be used:
|
||||
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)
|
||||
if drivingCourse[end].s < CS[:s_exit]
|
||||
if haskey(BSs, :cruising)
|
||||
println("INFO: A second cruising section has been added to CS ", csId," from s=",drivingCourse[end].s," to s_exit=",CS[:s_exit])
|
||||
end
|
||||
(CSs[csId], drivingCourse)=addCruisingPhase!(CSs[csId], drivingCourse, s_cruising, settings, train, CSs, "cruising")
|
||||
(CS, drivingCourse)=addCruisingPhase!(CS, drivingCourse, s_cruising, settings, train, CSs, "cruising")
|
||||
end =#
|
||||
end #for
|
||||
|
||||
|
@ -112,7 +113,7 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict
|
|||
|
||||
#create a new moving section for the minimum energy consumption
|
||||
movingSectionOriginal=copyMovingSection(movingSectionMinimumRunningTime)
|
||||
CSsOrig::Vector{CharacteristicSection} = movingSectionOriginal[:characteristicSections]
|
||||
CSsOrig::Vector{Dict} = movingSectionOriginal[:characteristicSections]
|
||||
merge!(movingSectionOriginal, Dict(:energySavingModifications => [])) # list containing all the used energy saving modifications
|
||||
|
||||
# create a new driving course for the minimum energy consumption
|
||||
|
@ -154,7 +155,11 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict
|
|||
end #if
|
||||
end # for
|
||||
|
||||
while movingSectionOriginal[:t_recoveryAvailable] > 0.0
|
||||
# testNr=0
|
||||
# 01/03 old wit too long calculation time: while movingSectionOriginal[:t_recoveryAvailable] > 0.0
|
||||
while movingSectionOriginal[:t_recoveryAvailable] >= 1/(10^approximationLevel)
|
||||
# testNr=testNr+1
|
||||
# println("while in OpModes: ", testNr, " mit t_recoveryAvailable=",movingSectionOriginal[:t_recoveryAvailable])
|
||||
# comparison of modifications
|
||||
ratioMax=0.0
|
||||
csIdMax=0
|
||||
|
@ -182,20 +187,20 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict
|
|||
|
||||
movingSectionOriginal[:t_recoveryAvailable] = movingSectionOriginal[:t_recoveryAvailable] - movingSectionOriginal[:energySavingModifications][end][:Δt]
|
||||
|
||||
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,
|
||||
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])
|
||||
if haskey(CSsOrig[csIdMax][:behaviorSections], :diminishing)
|
||||
lastIdOfSelectedCsOriginal = max(lastIdOfSelectedCsOriginal, CSsOrig[csIdMax][:behaviorSections][:diminishing].dataPoints[end])
|
||||
end
|
||||
|
||||
# create new driving course
|
||||
|
@ -228,7 +233,7 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict
|
|||
|
||||
# replace the original driving course and CS with the new modified ones
|
||||
drivingCourseOriginal=drivingCourseNew
|
||||
CSsOrig[csIdMax]=CharacteristicSection(movingSectionOriginal[:energySavingModifications][end][:csModified])
|
||||
CSsOrig[csIdMax]=copyCharacteristicSection(movingSectionOriginal[:energySavingModifications][end][:csModified])
|
||||
movingSectionOriginal[:t]=drivingCourseOriginal[end].t # total running time (in s)
|
||||
movingSectionOriginal[:E]=drivingCourseOriginal[end].E # total energy consumption (in Ws)
|
||||
|
||||
|
@ -238,9 +243,9 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict
|
|||
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(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
|
||||
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
|
||||
|
@ -283,8 +288,8 @@ end #function calculateMinimumEnergyConsumption
|
|||
|
||||
|
||||
function modifyCs(movingSectionOriginal::Dict, drivingCourseOriginal::Vector{DataPoint}, csId::Integer, modificationType::String, settings::Dict, train::Dict)
|
||||
# TODO: refctor and sort this function
|
||||
CSsOrig::Vector{CharacteristicSection} = movingSectionOriginal[:characteristicSections]
|
||||
# TODO: refactor and sort this function
|
||||
CSsOrig::Vector{Dict} = movingSectionOriginal[:characteristicSections]
|
||||
|
||||
if modificationType == "increasing coasting"
|
||||
# method 1: increase coasting
|
||||
|
@ -306,8 +311,8 @@ function modifyCs(movingSectionOriginal::Dict, drivingCourseOriginal::Vector{Dat
|
|||
:csModified => characteristicSectionModified, # the modified characteristic section
|
||||
:drivingCourseModified => drivingCourseModifiedUntilEndOfModifiedCS) # drivingCourse for the modified characteristic section
|
||||
|
||||
merge!(energySavingModification, Dict(:ΔE => CSsOrig[csId].E - energySavingModification[:csModified].E)) # saved energy (in Ws)
|
||||
merge!(energySavingModification, Dict(:Δt => energySavingModification[:csModified].t - CSsOrig[csId].t)) # time loss (in s)
|
||||
merge!(energySavingModification, Dict(:ΔE => CSsOrig[csId][:E] - energySavingModification[:csModified][:E])) # saved energy (in Ws)
|
||||
merge!(energySavingModification, Dict(:Δt => energySavingModification[:csModified][:t] - CSsOrig[csId][:t])) # time loss (in s)
|
||||
|
||||
|
||||
if energySavingModification[:Δt] <= movingSectionOriginal[:t_recoveryAvailable] && energySavingModification[:ΔE] >= 0.0
|
||||
|
@ -355,7 +360,7 @@ function createEnergySavingModification()
|
|||
:ΔE => 0.0, # saved energy (in Ws)
|
||||
:Δt => 0.0, # time loss (in s)
|
||||
:ratio => 0.0, # ratio of ΔE and Δt (in Ws/s)
|
||||
:csModified => CharacteristicSection(), # the modified characteristic section
|
||||
:csModified => Dict(), # the modified characteristic section
|
||||
:drivingCourseModified => []) # drivingCourse for the modified characteristic section
|
||||
end #createEnergySavingModification
|
||||
|
||||
|
@ -365,7 +370,7 @@ function copyEnergySavingModification(original::Dict)
|
|||
:ΔE => original[:ΔE], # saved energy (in Ws)
|
||||
:Δt => original[:Δt], # time loss (in s)
|
||||
:ratio => original[:ratio], # ratio of ΔE and Δt (in Ws/s)
|
||||
:csModified => CharacteristicSection(original[:csModified])) # the modified characteristic section
|
||||
:csModified => copyCharacteristicSection(original[:csModified])) # the modified characteristic section
|
||||
|
||||
drivingCourseModified = DataPoint[]
|
||||
for i in 1:length(original[:drivingCourseModified])
|
||||
|
@ -381,7 +386,7 @@ function updateEnergySavingModifications!(energySavingModifications::Vector{Dict
|
|||
difference = endOfModificationId-lastIdOfSelectedCsOriginal
|
||||
for modNr in csIdMax+1:length(energySavingModifications)
|
||||
if energySavingModifications[modNr][:ratio]>0
|
||||
BSs = energySavingModifications[modNr][:csModified].behaviorSections
|
||||
BSs = energySavingModifications[modNr][:csModified][:behaviorSections]
|
||||
# update the behavior sections of the modified charateristic section
|
||||
for bs in 1: length(allBs)
|
||||
if haskey(BSs, allBs[bs])
|
||||
|
@ -415,9 +420,10 @@ end #function updateEnergySavingModifications!
|
|||
|
||||
|
||||
function copyMovingSection(original::Dict)
|
||||
CSsCopy = Vector{CharacteristicSection}()
|
||||
#TODO after removing the mutable structs: Is it possible to just "copy"?
|
||||
CSsCopy = Vector{Dict}()
|
||||
for csId in 1:length(original[:characteristicSections])
|
||||
push!(CSsCopy, CharacteristicSection(original[:characteristicSections][csId]))
|
||||
push!(CSsCopy, copyCharacteristicSection(original[:characteristicSections][csId]))
|
||||
end #for
|
||||
|
||||
copy = Dict(:id => original[:id], # identifier
|
||||
|
@ -443,8 +449,31 @@ function copyMovingSection(original::Dict)
|
|||
if haskey(original, :t_recoveryAvailable) # still available recovery time for energy-saving modifications (in s)
|
||||
merge!(copy, Dict(:t_recoveryAvailable => original[:t_recoveryAvailable]))
|
||||
end
|
||||
|
||||
return copy
|
||||
end #function copyMovingSection
|
||||
|
||||
function copyCharacteristicSection(original::Dict)
|
||||
#TODO after removing the mutable structs: Is it possible to just "copy"?
|
||||
copy = Dict(:id => original[:id], # identifier
|
||||
:s_entry => original[:s_entry], # first position (in m)
|
||||
:s_exit => original[:s_exit], # last position (in m)
|
||||
:length => original[:length], # total length (in m)
|
||||
:r_path => original[:r_path], # path resistance (in ‰)
|
||||
:behaviorSections => Dict(), # empty list of containing behavior sections
|
||||
:t => original[:t], # total running time (in s)
|
||||
:E => original[:E], # total energy consumption (in Ws)
|
||||
:v_limit => original[:v_limit], # speed limit (in m/s)
|
||||
:v_peak => original[:v_peak], # maximum reachable speed (in m/s)
|
||||
:v_entry => original[:v_entry], # maximum entry speed (in m/s)
|
||||
:v_exit => original[:v_exit]) # maximum exit speed (in m/s)
|
||||
|
||||
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(original[:behaviorSections][allBs[bs]])))
|
||||
end #if
|
||||
end #for
|
||||
return copy
|
||||
end #function copyCharacteristicSection
|
||||
|
||||
end #module OperationModes
|
||||
|
|
|
@ -255,17 +255,17 @@ function printImportantValues(drivingCourse::Vector{DataPoint})
|
|||
end #function printImportantValues
|
||||
|
||||
function printSectionInformation(movingSection::Dict)
|
||||
CSs::Vector{CharacteristicSection} = movingSection[:characteristicSections]
|
||||
CSs::Vector{Dict} = 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)
|
||||
println("CS ",csId," mit length=", CSs[csId][:length]," mit t=", CSs[csId][:t])
|
||||
for bs in 1: length(allBs)
|
||||
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])
|
||||
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
|
||||
|
|
|
@ -23,7 +23,7 @@ function createMovingSection(path::Dict, v_trainLimit::Real)
|
|||
s_exit = path[:sections][end][:s_end] # last position (in m)
|
||||
pathLength = s_exit - s_entry # total length (in m)
|
||||
|
||||
CSs=[]
|
||||
CSs=Vector{Dict}()
|
||||
s_csStart=s_entry
|
||||
csId=1
|
||||
for row in 2:length(path[:sections])
|
||||
|
@ -47,44 +47,41 @@ function createMovingSection(path::Dict, v_trainLimit::Real)
|
|||
end #function createMovingSection
|
||||
|
||||
|
||||
## create a characteristic section for a path section
|
||||
## create a characteristic section for a path section. A characteristic section is a part of the moving section. It contains behavior sections.
|
||||
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.length=characteristicSection.s_exit-characteristicSection.s_entry # total length (in m)
|
||||
characteristicSection.t=0.0 # total running time (in s)
|
||||
characteristicSection.E=0.0 # total energy consumption (in Ws)
|
||||
characteristicSection.v_limit=v_csLimit # speed limit (in m/s)
|
||||
|
||||
# initializing v_entry, v_peak and v_exit with v_limit
|
||||
characteristicSection.v_peak=characteristicSection.v_limit # maximum reachable speed (in m/s)
|
||||
characteristicSection.v_entry=characteristicSection.v_limit # maximum entry speed (in m/s)
|
||||
characteristicSection.v_exit=characteristicSection.v_limit # maximum exit speed (in m/s)
|
||||
|
||||
characteristicSection.r_path=section[:f_Rp] # path resistance (in ‰)
|
||||
|
||||
# Create and return a characteristic section dependent on the paths attributes
|
||||
characteristicSection= Dict(:id => csId, # identifier
|
||||
:s_entry => s_csStart, # first position (in m)
|
||||
:s_exit => section[:s_end], # last position (in m)
|
||||
:length => section[:s_end]-s_csStart, # total length (in m)
|
||||
:r_path => section[:f_Rp], # path resistance (in ‰)
|
||||
:behaviorSections => Dict(), # list of containing behavior sections
|
||||
:t => 0.0, # total running time (in s)
|
||||
:E => 0.0, # total energy consumption (in Ws)
|
||||
:v_limit => v_csLimit, # speed limit (in m/s)
|
||||
# initializing :v_entry, :v_peak and :v_exit with :v_limit
|
||||
:v_peak => v_csLimit, # maximum reachable speed (in m/s)
|
||||
:v_entry => v_csLimit, # maximum entry speed (in m/s)
|
||||
:v_exit => v_csLimit) # maximum exit speed (in m/s)
|
||||
return characteristicSection
|
||||
end #function createCharacteristicSection
|
||||
|
||||
## define the intersection velocities between the characterisitc sections to secure braking behavior
|
||||
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
|
||||
CSs::Vector{CharacteristicSection} = movingSection[:characteristicSections]
|
||||
CSs = movingSection[:characteristicSections]
|
||||
|
||||
csId=length(CSs)
|
||||
CSs[csId].v_exit=0.0 # the exit velocity of the last characteristic section is 0.0 m/s
|
||||
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(CSs[csId].v_exit^2-2*a_braking*CSs[csId].length)
|
||||
v_entryMax=sqrt(CSs[csId][:v_exit]^2-2*a_braking*CSs[csId][:length])
|
||||
v_entryMax=floor(v_entryMax, digits=12)
|
||||
|
||||
CSs[csId].v_entry=min(CSs[csId].v_limit, v_entryMax)
|
||||
CSs[csId].v_peak=CSs[csId].v_entry
|
||||
CSs[csId][:v_entry]=min(CSs[csId][:v_limit], v_entryMax)
|
||||
CSs[csId][:v_peak]=CSs[csId][:v_entry]
|
||||
csId=csId-1
|
||||
if csId >= 1
|
||||
CSs[csId].v_exit=min(CSs[csId].v_limit, CSs[csId+1].v_entry)
|
||||
CSs[csId][:v_exit]=min(CSs[csId][:v_limit], CSs[csId+1][:v_entry])
|
||||
end #if
|
||||
end #while
|
||||
return movingSection
|
||||
|
@ -93,30 +90,30 @@ end #function secureBrakingBehavior!
|
|||
## define the intersection velocities between the characterisitc sections to secure acceleration behavior
|
||||
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
|
||||
CSs::Vector{CharacteristicSection} = movingSection[:characteristicSections]
|
||||
CSs = movingSection[:characteristicSections]
|
||||
|
||||
CSs[1].v_entry=0.0 # the entry velocity of the first characteristic section is 0.0 m/s
|
||||
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=CSs[1].v_entry
|
||||
previousCSv_exit=CSs[1][:v_entry]
|
||||
for csId in 1:length(CSs)
|
||||
CSs[csId].v_entry=min(CSs[csId].v_entry, previousCSv_exit)
|
||||
CSs[csId][:v_entry]=min(CSs[csId][:v_entry], previousCSv_exit)
|
||||
|
||||
startingPoint.s=CSs[csId].s_entry
|
||||
startingPoint.v=CSs[csId].v_entry
|
||||
startingPoint.s=CSs[csId][:s_entry]
|
||||
startingPoint.v=CSs[csId][:v_entry]
|
||||
accelerationCourse=[startingPoint] # List of data points
|
||||
|
||||
if CSs[csId].v_entry<CSs[csId].v_peak
|
||||
if CSs[csId][:v_entry]<CSs[csId][:v_peak]
|
||||
(CSs[csId], accelerationCourse)=addAccelerationPhase!(CSs[csId], accelerationCourse, settings, train, CSs) # this function changes the accelerationCourse
|
||||
CSs[csId].v_peak=max(CSs[csId].v_entry,accelerationCourse[end].v)
|
||||
CSs[csId][:v_peak]=max(CSs[csId][:v_entry],accelerationCourse[end].v)
|
||||
|
||||
CSs[csId].v_exit=min(CSs[csId].v_exit, CSs[csId].v_peak, accelerationCourse[end].v)
|
||||
else #CSs[csId].v_entry==CSs[csId].v_peak
|
||||
CSs[csId][:v_exit]=min(CSs[csId][:v_exit], CSs[csId][:v_peak], accelerationCourse[end].v)
|
||||
else #CSs[csId][:v_entry]==CSs[csId][:v_peak]
|
||||
# v_exit stays the same
|
||||
end #if
|
||||
|
||||
previousCSv_exit=CSs[csId].v_exit
|
||||
previousCSv_exit=CSs[csId][:v_exit]
|
||||
end #for
|
||||
|
||||
return movingSection
|
||||
|
@ -127,24 +124,24 @@ end #function secureAccelerationBehavior!
|
|||
## define the intersection velocities between the characterisitc sections to secure cruising behavior
|
||||
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_peak
|
||||
CSs::Vector{CharacteristicSection} = movingSection[:characteristicSections]
|
||||
CSs = movingSection[:characteristicSections]
|
||||
|
||||
startingPoint=DataPoint()
|
||||
startingPoint.i=1
|
||||
|
||||
previousCSv_exit=CSs[1].v_entry
|
||||
previousCSv_exit=CSs[1][:v_entry]
|
||||
|
||||
for csId in 1:length(CSs)
|
||||
CSs[csId].v_entry=min(CSs[csId].v_entry, previousCSv_exit)
|
||||
CSs[csId][:v_entry]=min(CSs[csId][:v_entry], previousCSv_exit)
|
||||
|
||||
startingPoint.s=CSs[csId].s_entry
|
||||
startingPoint.v=CSs[csId].v_peak
|
||||
startingPoint.s=CSs[csId][:s_entry]
|
||||
startingPoint.v=CSs[csId][:v_peak]
|
||||
cruisingCourse=[startingPoint] # List of data points
|
||||
|
||||
(CSs[csId], cruisingCourse)=addCruisingPhase!(CSs[csId], cruisingCourse, CSs[csId].length, settings, train, CSs, "cruising") # this function changes the cruisingCourse
|
||||
CSs[csId].v_exit=min(CSs[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=CSs[csId].v_exit
|
||||
previousCSv_exit=CSs[csId][:v_exit]
|
||||
end #for
|
||||
|
||||
return movingSection
|
||||
|
|
24
src/types.jl
24
src/types.jl
|
@ -1,6 +1,6 @@
|
|||
module types
|
||||
# definition of all the additional types and their constructors
|
||||
export DataPoint, BehaviorSection, CharacteristicSection, EnergySavingModification
|
||||
export DataPoint, BehaviorSection #, CharacteristicSection
|
||||
|
||||
|
||||
## a data point is the smallest element of the driving course. One step of the step approach is between two data points
|
||||
|
@ -54,7 +54,7 @@ function BehaviorSection(original::BehaviorSection)
|
|||
return BehaviorSection(original.type, original.length, original.s_entry, original.s_exit, original.t, original.E, original.v_entry, original.v_exit, bsDataPoints)
|
||||
end
|
||||
|
||||
## a characteristic section is a part of the moving section. It contains behavior sections.
|
||||
#= # a characteristic section is a part of the moving section. It contains behavior sections.
|
||||
mutable struct CharacteristicSection
|
||||
id::Integer # identifier
|
||||
length::AbstractFloat # total length (in m)
|
||||
|
@ -80,26 +80,6 @@ function CharacteristicSection(original::CharacteristicSection)
|
|||
end #for
|
||||
return copy
|
||||
end #function CharacteristicSection
|
||||
|
||||
#= for the energy saving operation mode it is nesserary to compare different energy saving modifications. These are part of the moving section.
|
||||
mutable struct EnergySavingModification
|
||||
csId::Integer # identifier of the characteristic section
|
||||
type::String # type of energy saving modification: "increasing coasting" "decreasing maximum velocity" or "combination of decreasing maximum velocity and coasting"
|
||||
ΔE::AbstractFloat # saved energy (in Ws)
|
||||
Δt::AbstractFloat # time loss (in s)
|
||||
ratio::AbstractFloat # ratio of ΔE and Δt (in Ws/s)
|
||||
csModified::CharacteristicSection # the modified characteristic section
|
||||
drivingCourseModified::Vector{DataPoint} # drivingCourse for the modified characteristic section
|
||||
end # mutable struct EnergySavingModification
|
||||
EnergySavingModification()=EnergySavingModification(0, "", 0.0, 0.0, 0.0, CharacteristicSection(), [])
|
||||
function EnergySavingModification(original::EnergySavingModification)
|
||||
copy=EnergySavingModification(original.csId, original.type, original.ΔE, original.Δt, original.ratio, CharacteristicSection(), DataPoint[])
|
||||
copy.csModified=CharacteristicSection(original.csModified)
|
||||
for i in 1:length(original.drivingCourseModified)
|
||||
push!(copy.drivingCourseModified, DataPoint(original.drivingCourseModified[i]))
|
||||
end
|
||||
return copy
|
||||
end #function EnergySavingModification
|
||||
=#
|
||||
|
||||
end #module
|
||||
|
|
Loading…
Reference in New Issue