Refactor the mutable struct BehaviorSection as a Dictionary
parent
792bfea614
commit
f590206226
|
@ -10,7 +10,7 @@ train:
|
|||
rotationMassFactor_t: 1.09 # (source: "Railway Timetabling & Operations" by Hansen, et al., 2014, p. 71 for the traction unit)
|
||||
rotationMassFactor_w: 1.03 # (source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 13 for "Güterwagenzug beladen" -> 1.03 to 1.04)
|
||||
powerType: diesel # diesel or electric (source: https://de.wikipedia.org/wiki/DB-Baureihe_V_90)
|
||||
trainType: freight # "freight" or "passenger" or "motor coach train" (source: https://dybas.de/dybas/gw/gw_f_1/g124.html)
|
||||
trainType: freight # "freight" or "passenger" or "motorCoachTrain" (source: https://dybas.de/dybas/gw/gw_f_1/g124.html)
|
||||
v_limit: # in m/s
|
||||
v_limit_kmh: 80 # in km/h (source: https://de.wikipedia.org/wiki/DB-Baureihe_V_90)
|
||||
a_braking: -0.4124 # in m/s^2 (source: FBS -> using the information from the "Fahrschaubild" of a long path without gradient or speed limit for DB 290 with with 10x Facs124)
|
||||
|
|
|
@ -10,7 +10,7 @@ train:
|
|||
rotationMassFactor_t: 1.09 # (source: "Railway Timetabling & Operations" by Hansen, et al., 2014, p. 71 for the traction unit)
|
||||
rotationMassFactor_w: 1.06 # (source: "Railway Timetabling & Operations" by Hansen, et al., 2014, p. 71 for freight wagons)
|
||||
powerType: electric # diesel or electric (source: https://de.wikipedia.org/wiki/Intercity_2_(Deutsche_Bahn)#Gemeinsame_Merkmale)
|
||||
trainType: passenger # "freight" or "passenger" or "motor coach train" (source: https://de.wikipedia.org/wiki/Intercity_2_(Deutsche_Bahn))
|
||||
trainType: passenger # "freight" or "passenger" or "motorCoachTrain" (source: https://de.wikipedia.org/wiki/Intercity_2_(Deutsche_Bahn))
|
||||
v_limit: # in m/s
|
||||
v_limit_kmh: 160 # in km/h (source: https://de.wikipedia.org/wiki/Intercity_2_(Deutsche_Bahn)#Gemeinsame_Merkmale)
|
||||
a_braking: -0.3507 # in m/s^2 (source: FBS -> using the information from the "Fahrschaubild" of a long path without gradient or speed limit for DB146.5 with 1x DApza687.2, 3x DBpza668.2, 1x DBpbzfa668.2)
|
||||
|
|
|
@ -10,7 +10,7 @@ train:
|
|||
rotationMassFactor_t:
|
||||
rotationMassFactor_w:
|
||||
powerType: diesel # diesel or electric (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
|
||||
trainType: motor coach train # "freight" or "passenger" or "motor coach train" (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
|
||||
trainType: motorCoachTrain # "freight" or "passenger" or "motorCoachTrain" (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
|
||||
v_limit: # in m/s
|
||||
v_limit_kmh: 120 # in km/h (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
|
||||
a_braking: -0.4253 # in m/s^2 (source: FBS -> using the information from the "Fahrschaubild" of a long path without gradient or speed limit for DB 642)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# TODO: calculation time for passenger trains on path1 is very long and should be reduced
|
||||
|
||||
module EnergySaving
|
||||
|
||||
using ..types
|
||||
|
@ -5,13 +7,16 @@ using ..MovingPhases
|
|||
|
||||
export calculateRecoveryTime, increaseCoastingSection, decreaseMaximumVelocity, combineEnergySavingMethods
|
||||
|
||||
@enum trainType passenger=1 freight=2 motorCoachTrain=3
|
||||
|
||||
approximationLevel = 6 # value for approximation to intersections
|
||||
# TODO: define it in TrainRun and give it to each function?
|
||||
|
||||
function calculateRecoveryTime(s_MS::Real, t_MS::AbstractFloat, train::Dict)
|
||||
# function for calculating the recovery time that can be used for energy saving
|
||||
# MS: Moving Section
|
||||
if train[:trainType]=="motor coach train"
|
||||
# 01/05 old without enum: if train[:type]=="motor coach train"
|
||||
if train[:type] == motorCoachTrain::trainType
|
||||
if s_MS<= 30000
|
||||
c_s=0.0
|
||||
else s_MS> 30000
|
||||
|
@ -32,14 +37,16 @@ function calculateRecoveryTime(s_MS::Real, t_MS::AbstractFloat, train::Dict)
|
|||
|
||||
t_recovery=s_MS*c_s+t_MS*c_t
|
||||
return t_recovery
|
||||
elseif train[:trainType]=="freight" && train[:v_limit]<=120/3.6 # unit is m/s
|
||||
t_recovery1=s_MS*0.0006 +t_MS*0.03
|
||||
t_recovery2=s_MS*0.0018 +t_MS*0.0
|
||||
t_recovery3=s_MS*0.0 +t_MS*0.04
|
||||
t_recovery=max(t_recovery1, t_recovery2, t_recovery3)
|
||||
# 01/05 old without enum: elseif train[:type]=="freight" && train[:v_limit]<=120/3.6 # unit is m/s
|
||||
elseif train[:type] == freight::trainType && train[:v_limit] <= 120/3.6 # unit is m/s
|
||||
t_recovery1=s_MS*0.0006 +t_MS*0.03
|
||||
t_recovery2=s_MS*0.0018 +t_MS*0.0
|
||||
t_recovery3=s_MS*0.0 +t_MS*0.04
|
||||
t_recovery=max(t_recovery1, t_recovery2, t_recovery3)
|
||||
|
||||
return t_recovery
|
||||
else # train[:trainType]=="passenger" || (train[:trainType]=="freight" && train[:v_limit]>120/3.6) # unit is m/s
|
||||
return t_recovery
|
||||
# 01/05 old without enum: else # train[:trainType]=="passenger" || (train[:trainType]=="freight" && train[:v_limit]>120/3.6) # unit is m/s
|
||||
else # train[:type] == passenger::trainType || (train[:type] == freight::trainType && train[:v_limit]>120/3.6) # unit is m/s
|
||||
if s_MS<= 30000
|
||||
c_s=0.0
|
||||
else s_MS> 30000
|
||||
|
@ -86,7 +93,7 @@ function calculateRecoveryTime(s_MS::Real, t_MS::AbstractFloat, train::Dict)
|
|||
|
||||
t_recovery=s_MS*c_s+t_MS*c_t
|
||||
return t_recovery
|
||||
end # if train[:trainType]
|
||||
end # if train[:type]
|
||||
end #function calculateRecoveryTime
|
||||
|
||||
function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, allCSs::Vector{Dict}, t_recoveryAvailable::AbstractFloat)
|
||||
|
@ -94,7 +101,7 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{DataPoi
|
|||
if (haskey(BSsOriginal, :cruising) || haskey(BSsOriginal, :diminishing)) && haskey(BSsOriginal, :braking)
|
||||
# check if cruising or diminishing should be reduced for coasting
|
||||
if haskey(BSsOriginal, :cruising) && haskey(BSsOriginal, :diminishing)
|
||||
if BSsOriginal[:cruising].dataPoints[1] > BSsOriginal[:diminishing].dataPoints[1]
|
||||
if BSsOriginal[:cruising][:dataPoints][1] > BSsOriginal[:diminishing][:dataPoints][1]
|
||||
reduceCruising=true
|
||||
reduceDiminishing=false
|
||||
else
|
||||
|
@ -111,12 +118,13 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{DataPoi
|
|||
|
||||
if reduceCruising
|
||||
cruisingReduction = settings[:stepSize]
|
||||
# 01/07 test for a better calculation time: cruisingReduction = settings[:stepSize]*100
|
||||
while cruisingReduction>=settings[:stepSize]/10^approximationLevel
|
||||
#while cruisingReduction>=settings[:stepSize]/100
|
||||
while cruisingReduction>=settings[:stepSize]/10^approximationLevel # will be done once and then depending on approximationLevel repeated with smaller cruisingReduction unless !(drivingCourseModified[end].v<=csModified[:v_exit] && drivingCourseModified[end].s<csModified[:s_exit]) -> see below at the end of the while loop
|
||||
|
||||
# create a copy for the characteristic sections drivingCourse
|
||||
energySavingStartId=get(BSsOriginal, :cruising, BehaviorSection()).dataPoints[1]
|
||||
energySavingStartId=get(BSsOriginal, :cruising, Dict(:dataPoints=>[0]))[:dataPoints][1]
|
||||
if energySavingStartId==0
|
||||
error("ERROR at creating a new driving course for energy saving with coasting !")
|
||||
end
|
||||
|
@ -130,21 +138,21 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{DataPoi
|
|||
|
||||
# calculating the new length of the cruising section
|
||||
if settings[:stepVariable]=="s in m" # distance step method
|
||||
s_cruising = BSsOriginal[: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=BSsOriginal[:cruising].t-cruisingReduction
|
||||
# t_cruising=BSsOriginal[:cruising][:t]-cruisingReduction
|
||||
# s_cruising=t_cruising*drivingCourseModified[end].v
|
||||
distanceReduction = drivingCourse(BSsOriginal[:cruising].dataPoints[end]).v*cruisingReduction
|
||||
s_cruising = BSsOriginal[: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=BSsOriginal[: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
|
||||
# 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}())
|
||||
# 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, Dict}())
|
||||
#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)
|
||||
|
@ -161,28 +169,28 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{DataPoi
|
|||
|
||||
BSsModified = csModified[:behaviorSections]
|
||||
if haskey(BSsOriginal, :breakFree)
|
||||
breakFreeSection=BehaviorSection(BSsOriginal[:breakFree])
|
||||
breakFreeSection=copyBehaviorSection(BSsOriginal[:breakFree])
|
||||
merge!(BSsModified, Dict(:breakFree=>breakFreeSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:breakFree].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[:breakFree].t
|
||||
csModified[:E] = csModified[:E] + BSsModified[:breakFree][:E]
|
||||
csModified[:t] = csModified[:t] + BSsModified[:breakFree][:t]
|
||||
end
|
||||
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])
|
||||
clearingSection=copyBehaviorSection(BSsOriginal[:clearing])
|
||||
merge!(BSsModified, Dict(:clearing=>clearingSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:clearing].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[:clearing].t
|
||||
csModified[:E] = csModified[:E] + BSsModified[:clearing][:E]
|
||||
csModified[:t] = csModified[:t] + BSsModified[:clearing][:t]
|
||||
end
|
||||
if haskey(BSsOriginal, :acceleration)
|
||||
accelerationSection=BehaviorSection(BSsOriginal[:acceleration])
|
||||
accelerationSection=copyBehaviorSection(BSsOriginal[:acceleration])
|
||||
merge!(BSsModified, Dict(:acceleration=>accelerationSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:acceleration].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[:acceleration].t
|
||||
csModified[:E] = csModified[:E] + BSsModified[:acceleration][:E]
|
||||
csModified[:t] = csModified[:t] + BSsModified[:acceleration][:t]
|
||||
end
|
||||
if haskey(BSsOriginal, :diminishing)
|
||||
diminishingSection=BehaviorSection(BSsOriginal[:diminishing])
|
||||
diminishingSection=copyBehaviorSection(BSsOriginal[:diminishing])
|
||||
merge!(BSsModified, Dict(:diminishing=>diminishingSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:diminishing].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[:diminishing].t
|
||||
csModified[:E] = csModified[:E] + BSsModified[:diminishing][:E]
|
||||
csModified[:t] = csModified[:t] + BSsModified[:diminishing][:t]
|
||||
end
|
||||
|
||||
|
||||
|
@ -224,7 +232,7 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{DataPoi
|
|||
# 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
|
||||
# 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}())
|
||||
# 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, Dict}())
|
||||
csModified=Dict(:id => csOriginal[:id], # identifier
|
||||
:s_entry => csOriginal[:s_entry], # first position (in m)
|
||||
:s_exit => csOriginal[:s_exit], # last position (in m)
|
||||
|
@ -240,49 +248,49 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{DataPoi
|
|||
|
||||
BSsModified = csModified[:behaviorSections]
|
||||
if haskey(BSsOriginal, :breakFree)
|
||||
breakFreeSection=BehaviorSection(BSsOriginal[:breakFree])
|
||||
breakFreeSection=copyBehaviorSection(BSsOriginal[:breakFree])
|
||||
merge!(BSsModified, Dict(:breakFree=>breakFreeSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:breakFree].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[:breakFree].t
|
||||
csModified[:E] = csModified[:E] + BSsModified[:breakFree][:E]
|
||||
csModified[:t] = csModified[:t] + BSsModified[:breakFree][:t]
|
||||
end
|
||||
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])
|
||||
clearingSection=copyBehaviorSection(BSsOriginal[:clearing])
|
||||
merge!(BSsModified, Dict(:clearing=>clearingSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:clearing].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[:clearing].t
|
||||
csModified[:E] = csModified[:E] + BSsModified[:clearing][:E]
|
||||
csModified[:t] = csModified[:t] + BSsModified[:clearing][:t]
|
||||
end
|
||||
if haskey(BSsOriginal, :acceleration)
|
||||
accelerationSection=BehaviorSection(BSsOriginal[:acceleration])
|
||||
accelerationSection=copyBehaviorSection(BSsOriginal[:acceleration])
|
||||
merge!(BSsModified, Dict(:acceleration=>accelerationSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:acceleration].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[:acceleration].t
|
||||
csModified[:E] = csModified[:E] + BSsModified[:acceleration][:E]
|
||||
csModified[:t] = csModified[:t] + BSsModified[:acceleration][:t]
|
||||
end
|
||||
if haskey(BSsOriginal, :cruising)
|
||||
cruisingSection=BehaviorSection(BSsOriginal[:cruising])
|
||||
cruisingSection=copyBehaviorSection(BSsOriginal[:cruising])
|
||||
merge!(BSsModified, Dict(:cruising=>cruisingSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:cruising].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[:cruising].t
|
||||
csModified[:E] = csModified[:E] + BSsModified[:cruising][:E]
|
||||
csModified[:t] = csModified[:t] + BSsModified[:cruising][:t]
|
||||
end
|
||||
|
||||
diminishingSection=BehaviorSection(BSsOriginal[:diminishing])
|
||||
if length(diminishingSection.dataPoints) > 2
|
||||
diminishingSection=copyBehaviorSection(BSsOriginal[:diminishing])
|
||||
if length(diminishingSection[:dataPoints]) > 2
|
||||
# remove the last diminishing waypoint
|
||||
pop!(diminishingSection.dataPoints)
|
||||
pop!(diminishingSection[:dataPoints])
|
||||
|
||||
diminishingSection.v_exit=drivingCourse[diminishingSection.dataPoints[end]].v # exit speed (in m/s)
|
||||
diminishingSection.s_exit=drivingCourse[diminishingSection.dataPoints[end]].s # last position (in m)
|
||||
diminishingSection.length=diminishingSection.s_exit-diminishingSection.s_entry # total length (in m)
|
||||
diminishingSection.t=drivingCourse[diminishingSection.dataPoints[end]].t-drivingCourse[diminishingSection.dataPoints[1]].t # total running time (in s)
|
||||
diminishingSection.E=drivingCourse[diminishingSection.dataPoints[end]].E-drivingCourse[diminishingSection.dataPoints[1]].E # total energy consumption (in Ws)
|
||||
diminishingSection[:v_exit]=drivingCourse[diminishingSection[:dataPoints][end]].v # exit speed (in m/s)
|
||||
diminishingSection[:s_exit]=drivingCourse[diminishingSection[:dataPoints][end]].s # last position (in m)
|
||||
diminishingSection[:length]=diminishingSection[:s_exit]-diminishingSection[:s_entry] # total length (in m)
|
||||
diminishingSection[:t]=drivingCourse[diminishingSection[:dataPoints][end]].t-drivingCourse[diminishingSection[:dataPoints][1]].t # total running time (in s)
|
||||
diminishingSection[:E]=drivingCourse[diminishingSection[:dataPoints][end]].E-drivingCourse[diminishingSection[:dataPoints][1]].E # total energy consumption (in Ws)
|
||||
|
||||
merge!(BSsModified, Dict(:diminishing => diminishingSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:diminishing].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[:diminishing].t
|
||||
csModified[:E] = csModified[:E] + BSsModified[:diminishing][:E]
|
||||
csModified[:t] = csModified[:t] + BSsModified[:diminishing][:t]
|
||||
|
||||
energySavingStartId=diminishingSection.dataPoints[end]
|
||||
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(BSsOriginal, :clearing, get(BSsOriginal, :diminishing, BehaviorSection())).dataPoints[1]
|
||||
energySavingStartId=get(BSsOriginal, :clearing, get(BSsOriginal, :diminishing, Dict(:dataPoints =>[0])))[:dataPoints][1]
|
||||
end
|
||||
|
||||
# copy the driving course till the beginning of energy saving
|
||||
|
@ -329,15 +337,15 @@ function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict
|
|||
#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]
|
||||
accelerationSection = copyBehaviorSection(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
|
||||
# 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}())
|
||||
# 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, Dict}())
|
||||
csModified=Dict(:id => csOriginal[:id], # identifier
|
||||
:s_entry => csOriginal[:s_entry], # first position (in m)
|
||||
:s_exit => csOriginal[:s_exit], # last position (in m)
|
||||
|
@ -352,43 +360,43 @@ function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict
|
|||
:v_exit => csOriginal[:v_exit]) # maximum exit speed (in m/s)
|
||||
BSsModified = csModified[:behaviorSections]
|
||||
if haskey(BSsOriginal, :breakFree)
|
||||
breakFreeSection=BehaviorSection(BSsOriginal[:breakFree])
|
||||
breakFreeSection=copyBehaviorSection(BSsOriginal[:breakFree])
|
||||
merge!(BSsModified, Dict(:breakFree=>breakFreeSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:breakFree].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[:breakFree].t
|
||||
csModified[:E] = csModified[:E] + BSsModified[:breakFree][:E]
|
||||
csModified[:t] = csModified[:t] + BSsModified[:breakFree][:t]
|
||||
end
|
||||
|
||||
#accelerationSection = BehaviorSection(get(BSsOriginal, :acceleration, BehaviorSection()))
|
||||
#accelerationSection = copyBehaviorSection(get(BSsOriginal, :acceleration, Dict()))
|
||||
|
||||
if length(accelerationSection.dataPoints) > 2
|
||||
if length(accelerationSection[:dataPoints]) > 2
|
||||
if haskey(BSsOriginal, :clearing)
|
||||
clearingSection=BehaviorSection(BSsOriginal[:clearing])
|
||||
clearingSection=copyBehaviorSection(BSsOriginal[:clearing])
|
||||
merge!(BSsModified, Dict(:clearing=>clearingSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:clearing].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[:clearing].t
|
||||
csModified[:E] = csModified[:E] + BSsModified[:clearing][:E]
|
||||
csModified[:t] = csModified[:t] + BSsModified[:clearing][:t]
|
||||
end
|
||||
|
||||
# remove the last acceleration waypoint
|
||||
pop!(accelerationSection.dataPoints)
|
||||
pop!(accelerationSection[:dataPoints])
|
||||
|
||||
accelerationSection.v_exit=drivingCourse[accelerationSection.dataPoints[end]].v # exit speed (in m/s)
|
||||
accelerationSection.s_exit=drivingCourse[accelerationSection.dataPoints[end]].s # last position (in m)
|
||||
accelerationSection.length=accelerationSection.s_exit-accelerationSection.s_entry # total length (in m)
|
||||
accelerationSection.t=drivingCourse[accelerationSection.dataPoints[end]].t-drivingCourse[accelerationSection.dataPoints[1]].t # total running time (in s)
|
||||
accelerationSection.E=drivingCourse[accelerationSection.dataPoints[end]].E-drivingCourse[accelerationSection.dataPoints[1]].E # total energy consumption (in Ws)
|
||||
accelerationSection[:v_exit]=drivingCourse[accelerationSection[:dataPoints][end]].v # exit speed (in m/s)
|
||||
accelerationSection[:s_exit]=drivingCourse[accelerationSection[:dataPoints][end]].s # last position (in m)
|
||||
accelerationSection[:length]=accelerationSection[:s_exit]-accelerationSection[:s_entry] # total length (in m)
|
||||
accelerationSection[:t]=drivingCourse[accelerationSection[:dataPoints][end]].t-drivingCourse[accelerationSection[:dataPoints][1]].t # total running time (in s)
|
||||
accelerationSection[:E]=drivingCourse[accelerationSection[:dataPoints][end]].E-drivingCourse[accelerationSection[:dataPoints][1]].E # total energy consumption (in Ws)
|
||||
|
||||
merge!(BSsModified, Dict(:acceleration=>accelerationSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:acceleration].E
|
||||
csModified[:t] = csModified[:t] + BSsModified[:acceleration].t
|
||||
csModified[:E] = csModified[:E] + BSsModified[:acceleration][:E]
|
||||
csModified[:t] = csModified[:t] + BSsModified[:acceleration][:t]
|
||||
|
||||
energySavingStartId=accelerationSection.dataPoints[end]
|
||||
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(BSsOriginal, :clearing, get(BSsOriginal, :acceleration, BehaviorSection())).dataPoints[1]
|
||||
energySavingStartId=get(BSsOriginal, :clearing, get(BSsOriginal, :acceleration, Dict(:dataPoints =>[0])))[:dataPoints][1]
|
||||
end
|
||||
|
||||
# TODO: should v_peak be reduced or is it enough to pop the data points?
|
||||
# characteristicSection.v_peak=drivingCourse[end].v # setting v_peak to the last data point's velocity which is the highest reachable value in this characteristic section
|
||||
# characteristicSection[:v_peak]=drivingCourse[end].v # setting v_peak to the last data point's velocity which is the highest reachable value in this characteristic section
|
||||
|
||||
# copy the drivingCourse till the beginning of energy saving
|
||||
drivingCourseModified=Vector{DataPoint}()
|
||||
|
@ -452,7 +460,7 @@ end # function decreaseMaximumVelocity
|
|||
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])
|
||||
if haskey(BSsOriginal, :acceleration) && (haskey(BSsOriginal, :braking) || haskey(BSsOriginal, :coasting)) && drivingCourse[get(BSsOriginal, :acceleration, Dict(:dataPoints =>[0]))[: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
|
||||
|
@ -471,7 +479,7 @@ function combineEnergySavingMethods(csOriginal::Dict, drivingCourse::Vector{Data
|
|||
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]])))
|
||||
merge!(csCombined[:behaviorSections], Dict(allBs[bs] => copyBehaviorSection(BSsOriginal[allBs[bs]])))
|
||||
end #if
|
||||
end #for
|
||||
|
||||
|
|
37
src/Input.jl
37
src/Input.jl
|
@ -5,6 +5,8 @@ using ..types
|
|||
|
||||
export readInput
|
||||
|
||||
@enum trainType passenger=1 freight=2 motorCoachTrain=3
|
||||
|
||||
"""
|
||||
Read the input information from YAML files for train, path and settings, save it in different dictionaries and return them.
|
||||
"""
|
||||
|
@ -34,14 +36,17 @@ function inputTrain(trainDirectory::String)
|
|||
id=1 # trains identifier
|
||||
|
||||
if haskey(data["train"],"trainType")
|
||||
if typeof(data["train"]["trainType"])==String && (data["train"]["trainType"]=="freight" || data["train"]["trainType"]=="motor coach train" || data["train"]["trainType"]=="passenger")
|
||||
trainType=data["train"]["trainType"] # "passenger" or "freight" or "motor coach train"
|
||||
# @enum trainType passenger=1 freight=2 motorCoachTrain=3
|
||||
if typeof(data["train"]["trainType"])==String && (data["train"]["trainType"]=="freight" || data["train"]["trainType"]=="motorCoachTrain" || data["train"]["trainType"]=="passenger")
|
||||
# 01/05 old without enum: if typeof(data["train"]["trainType"])==String && (data["train"]["trainType"]=="freight" || data["train"]["trainType"]=="motor coach train" || data["train"]["trainType"]=="passenger")
|
||||
# 01/05 old without enum: trainType=data["train"]["trainType"] # "passenger" or "freight" or "motor coach train"
|
||||
type = getEnum(data["train"]["trainType"], trainType) # "passenger" or "freight" or "motorCoachTrain"
|
||||
delete!(data["train"], "trainType")
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The value of trainType is wrong. It has to be freight, motor coach train or passenger.")
|
||||
error("ERROR at reading the train yaml file: The value of trainType is wrong. It has to be freight, motorCoachTrain or passenger.")
|
||||
end
|
||||
else
|
||||
error("ERROR at reading the train yaml file: The keyword trainType is missing. It has to be added with the value freight, motor coach train or passenger.")
|
||||
error("ERROR at reading the train yaml file: The keyword trainType is missing. It has to be added with the value freight, motorCoachTrain or passenger.")
|
||||
end
|
||||
|
||||
if haskey(data["train"],"l_train")
|
||||
|
@ -259,11 +264,24 @@ function inputTrain(trainDirectory::String)
|
|||
# coefficients for the vehicle resistance of the set of wagons (consist)
|
||||
|
||||
# coefficient for velocitiy difference between set of wagons (consist) and outdoor air (in m/s)
|
||||
# if type == getEnum("passenger", trainType) || type == getEnum("motorCoachTrain", trainType)
|
||||
if type == passenger::trainType || type == motorCoachTrain::trainType
|
||||
# TODO: if type == trainType(:passenger) || type == trainType(:motorCoachTrain)
|
||||
# TODO: ODER if trainType(type) == trainType(:passenger) || trainType(type) == trainType(:motorCoachTrain)
|
||||
Δv_w=15.0/3.6
|
||||
# elseif type == getEnum("freight", trainType)
|
||||
elseif type == freight::trainType
|
||||
Δv_w=0.0
|
||||
end # if
|
||||
|
||||
#= 01/05 old without enum
|
||||
# coefficient for velocitiy difference between set of wagons (consist) and outdoor air (in m/s)
|
||||
if trainType=="passenger" || trainType=="motor coach train"
|
||||
Δv_w=15.0/3.6
|
||||
elseif trainType== "freight"
|
||||
Δv_w=0.0
|
||||
end # if
|
||||
=#
|
||||
|
||||
# coefficient for basic resistance of the set of wagons (consist) (in ‰)
|
||||
if haskey(data["train"],"f_Rw0") && data["train"]["f_Rw0"]!=nothing
|
||||
|
@ -316,8 +334,9 @@ function inputTrain(trainDirectory::String)
|
|||
# create the train Dictionary
|
||||
train= Dict(:name => name, # train's name
|
||||
:id => id, # train's identifier
|
||||
:trainType => trainType, # type of train "passenger" or "freight" or "motor coach train"
|
||||
:trainLength => trainLength,# total length (in m)
|
||||
:type => type, # type of train "passenger" or "freight" or "motorCoachTrain"
|
||||
#= 01/05 old without enum :trainType => trainType, # type of train "passenger" or "freight" or "motor coach train" =#
|
||||
:length => 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)
|
||||
|
@ -651,13 +670,13 @@ But only if the string matches an enumerated value.
|
|||
|
||||
# Example
|
||||
```jldoctest
|
||||
julia> @enum trainTypes passenger freight
|
||||
julia> @enum trainType passenger freight
|
||||
|
||||
julia> myTrain = "passenger"
|
||||
"passenger"
|
||||
|
||||
julia> myTrainType = getEnum(myTrain, trainTypes)
|
||||
passenger::trainTypes = 0
|
||||
julia> myTrainType = getEnum(myTrain, trainType)
|
||||
passenger::trainType = 0
|
||||
```
|
||||
"""
|
||||
function getEnum(string::String, enum_type::DataType)
|
||||
|
|
|
@ -86,7 +86,7 @@ function calculatePathResistance(s::Real, massModel::String, train::Dict, CSs::V
|
|||
while s<CSs[id][:s_entry]
|
||||
id=id-1
|
||||
if id==0
|
||||
println("s=",s," MS.s_entry=",CSs[1].s_entry)
|
||||
println("s=",s," MS[:s_entry]=",CSs[1][:s_entry])
|
||||
end
|
||||
end #while
|
||||
|
||||
|
@ -94,12 +94,12 @@ function calculatePathResistance(s::Real, massModel::String, train::Dict, CSs::V
|
|||
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[:length]<CSs[id][:s_exit]
|
||||
pathResistance=pathResistance+(min(s, CSs[id][:s_exit])-max(s-train[:length], CSs[id][:s_entry]))/train[:length]*(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
|
||||
return pathResistance+(CSs[1].s_entry-(s-train[:trainLength]))/train[:trainLength]*(CSs[1].r_path/1000*train[:m_train]*g) # /1000 because of the unit ‰
|
||||
return pathResistance+(CSs[1][:s_entry]-(s-train[:length]))/train[:length]*(CSs[1].r_path/1000*train[:m_train]*g) # /1000 because of the unit ‰
|
||||
end #if
|
||||
end #while
|
||||
else
|
||||
|
@ -209,25 +209,25 @@ function detectFormerSpeedLimits(CSs::Vector{Dict}, csWithTrainHeadId::Integer,
|
|||
return formerSpeedLimits
|
||||
end # function detectFormerSpeedLimits
|
||||
|
||||
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)
|
||||
function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{Dict}, formerSpeedLimits, accelerationSection::Dict)
|
||||
# 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::Dict)
|
||||
# would work: function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{Dict}, formerSpeedLimits::Array{Any,1}, accelerationSection::Dict)
|
||||
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)
|
||||
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_clearing=min(CS[:s_exit]-drivingCourse[end].s-s_braking, formerSpeedLimits[end][1]-(drivingCourse[end].s-train[:length]))
|
||||
|
||||
if s_clearing>0.0
|
||||
(CS, drivingCourse)=addCruisingPhase!(CS, drivingCourse, s_clearing, settings, train, CSs, "clearing")
|
||||
|
@ -238,19 +238,14 @@ function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{DataPoint},
|
|||
# 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
|
||||
accelerationSection.s_entry=drivingCourse[end].s # first position (in m)
|
||||
accelerationSection.v_entry=drivingCourse[end].v # entry speed (in m/s)
|
||||
|
||||
#currentStepSize=settings[:stepSize] # initializing the step size that can be reduced near intersections
|
||||
accelerationSection = createBehaviorSection("acceleration", drivingCourse[end].s, drivingCourse[end].v, drivingCourse[end].i)
|
||||
else
|
||||
return (CS, drivingCourse, formerSpeedLimits, accelerationSection, true)
|
||||
end
|
||||
end
|
||||
|
||||
# remove former speed limits of characteristic sections the train has left during the last step from the list
|
||||
while length(formerSpeedLimits) > 0 && drivingCourse[end].s - train[:trainLength] >= formerSpeedLimits[end][1]
|
||||
while length(formerSpeedLimits) > 0 && drivingCourse[end].s - train[:length] >= formerSpeedLimits[end][1]
|
||||
pop!(formerSpeedLimits)
|
||||
end
|
||||
end
|
||||
|
@ -262,13 +257,9 @@ end # function considerFormerSpeedLimits!
|
|||
# Info: currently the values of the breakFree phase will be calculated like in the acceleration phase
|
||||
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)
|
||||
breakFreeSection.v_entry=drivingCourse[end].v # entry speed (in m/s)
|
||||
push!(breakFreeSection.dataPoints, drivingCourse[end].i) # list of containing data points
|
||||
BS = createBehaviorSection("breakFree", drivingCourse[end].s, drivingCourse[end].v, drivingCourse[end].i)
|
||||
drivingCourse[end].behavior = BS[:type]
|
||||
|
||||
drivingCourse[end].behavior = breakFreeSection.type
|
||||
# traction effort and resisting forces (in N):
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "acceleration") # currently the tractive effort is calculated like in the acceleration phase
|
||||
|
||||
|
@ -282,7 +273,7 @@ function addBreakFreePhase!(CS::Dict, drivingCourse::Vector{DataPoint}, settings
|
|||
|
||||
# creating the next data point
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], settings[:stepSize], CS[:id]))
|
||||
drivingCourse[end].behavior = breakFreeSection.type
|
||||
drivingCourse[end].behavior = BS[: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())
|
||||
drivingCourse[end].i=drivingCourse[end-1].i+1 # incrementing the number of the data point
|
||||
|
@ -311,19 +302,19 @@ function addBreakFreePhase!(CS::Dict, drivingCourse::Vector{DataPoint}, settings
|
|||
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)
|
||||
=#
|
||||
push!(breakFreeSection.dataPoints, drivingCourse[end].i)
|
||||
push!(BS[:dataPoints], drivingCourse[end].i)
|
||||
|
||||
# calculate the accumulated breakFree section information
|
||||
breakFreeSection.s_exit=drivingCourse[end].s # last position (in m)
|
||||
breakFreeSection.length=breakFreeSection.s_exit-breakFreeSection.s_entry # total length (in m)
|
||||
breakFreeSection.v_exit=drivingCourse[end].v # exit speed (in m/s)
|
||||
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)
|
||||
merge!(BS, Dict(:length => drivingCourse[end].s - BS[:s_entry], # total length (in m)
|
||||
:s_exit => drivingCourse[end].s, # last position (in m)
|
||||
:t => drivingCourse[end].t - drivingCourse[BS[:dataPoints][1]].t, # total running time (in s)
|
||||
:E => drivingCourse[end].E - drivingCourse[BS[:dataPoints][1]].E, # total energy consumption (in Ws)
|
||||
:v_exit => drivingCourse[end].v)) # exit speed (in m/s)))
|
||||
|
||||
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]+BS[:t] # total running time (in s)
|
||||
CS[:E]=CS[:E]+BS[:E] # total energy consumption (in Ws)
|
||||
|
||||
merge!(CS[:behaviorSections], Dict(:breakFree => breakFreeSection))
|
||||
merge!(CS[:behaviorSections], Dict(:breakFree => BS))
|
||||
end # else: return the characteristic section without a breakFree section
|
||||
return (CS, drivingCourse)
|
||||
end #function addBreakFreePhase!
|
||||
|
@ -343,7 +334,7 @@ function addAccelerationPhase!(CS::Dict, drivingCourse::Vector{DataPoint}, setti
|
|||
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[:length])
|
||||
|
||||
# conditions for acceleration phase
|
||||
targetSpeedReached = drivingCourse[end].v >= CS[:v_peak]
|
||||
|
@ -353,37 +344,33 @@ function addAccelerationPhase!(CS::Dict, drivingCourse::Vector{DataPoint}, setti
|
|||
# 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
|
||||
accelerationSection=BehaviorSection()
|
||||
accelerationSection.type="acceleration" # type of behavior section
|
||||
accelerationSection.s_entry=drivingCourse[end].s # first position (in m)
|
||||
accelerationSection.v_entry=drivingCourse[end].v # entry speed (in m/s)
|
||||
push!(accelerationSection.dataPoints, drivingCourse[end].i)
|
||||
drivingCourse[end].behavior = accelerationSection.type
|
||||
BS = createBehaviorSection("acceleration", drivingCourse[end].s, drivingCourse[end].v, drivingCourse[end].i)
|
||||
drivingCourse[end].behavior = BS[:type]
|
||||
|
||||
currentStepSize=settings[:stepSize] # initializing the step size that can be reduced near intersections
|
||||
currentStepSize=settings[:stepSize] # initialize 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
|
||||
# traction effort and resisting forces (in N)
|
||||
# 11/22 calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, accelerationSection.type)
|
||||
# 11/22 calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type])
|
||||
|
||||
# acceleration (in m/s^2):
|
||||
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]))
|
||||
drivingCourse[end].behavior = accelerationSection.type
|
||||
push!(accelerationSection.dataPoints, drivingCourse[end].i)
|
||||
# calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, accelerationSection.type)
|
||||
drivingCourse[end].behavior = BS[:type]
|
||||
push!(BS[:dataPoints], drivingCourse[end].i)
|
||||
# calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type])
|
||||
|
||||
|
||||
if length(formerSpeedLimits) > 0 # If the tail of the train is located in a former characteristic section with lower speed limit check if is is possible to accelerate as normal
|
||||
(CS, drivingCourse, formerSpeedLimits, accelerationSection, endOfCsReached) = considerFormerSpeedLimits!(CS, drivingCourse, settings, train, CSs, formerSpeedLimits, accelerationSection)
|
||||
(CS, drivingCourse, formerSpeedLimits, BS, endOfCsReached) = considerFormerSpeedLimits!(CS, drivingCourse, settings, train, CSs, formerSpeedLimits, BS)
|
||||
if endOfCsReached
|
||||
return (CS, drivingCourse)
|
||||
end #if
|
||||
currentStepSize=settings[:stepSize] # initializing the step size that can be reduced near intersections
|
||||
currentStepSize=settings[:stepSize] # initialize the step size that can be reduced near intersections
|
||||
end #if
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, accelerationSection.type)
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type])
|
||||
end #while
|
||||
|
||||
# check which limit was reached and adjust the currentStepSize for the next cycle
|
||||
|
@ -418,24 +405,24 @@ function addAccelerationPhase!(CS::Dict, drivingCourse::Vector{DataPoint}, setti
|
|||
end
|
||||
# delete last data point for recalculating the last step with reduced step size
|
||||
pop!(drivingCourse)
|
||||
pop!(accelerationSection.dataPoints)
|
||||
pop!(BS[:dataPoints])
|
||||
|
||||
else # if the level of approximation is reached
|
||||
if drivingCourse[end].v<=0.0
|
||||
# push!(accelerationSection.dataPoints, drivingCourse[end].i)
|
||||
# push!(BS[: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.",
|
||||
" 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]
|
||||
pop!(drivingCourse)
|
||||
pop!(accelerationSection.dataPoints)
|
||||
pop!(BS[:dataPoints])
|
||||
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)
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, accelerationSection.type)
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type])
|
||||
|
||||
else
|
||||
|
||||
|
@ -443,22 +430,23 @@ function addAccelerationPhase!(CS::Dict, drivingCourse::Vector{DataPoint}, setti
|
|||
end
|
||||
end #for
|
||||
|
||||
if length(accelerationSection.dataPoints) > 1 # 11/21 new: it is possible that the acceleration starts at v_peak, accelerates a step, is to high and drops the last point. then there is only one data point which is not a section.
|
||||
if length(BS[:dataPoints]) > 1 # 11/21 new: it is possible that the acceleration starts at v_peak, accelerates a step, is to high and drops the last point. then there is only one data point which is not a section.
|
||||
# calculate the accumulated acceleration section information
|
||||
accelerationSection.v_exit=drivingCourse[end].v # exit speed (in m/s)
|
||||
accelerationSection.s_exit=drivingCourse[end].s # last position (in m)
|
||||
accelerationSection.length=accelerationSection.s_exit-accelerationSection.s_entry # total length (in m)
|
||||
accelerationSection.t=drivingCourse[end].t-drivingCourse[accelerationSection.dataPoints[1]].t # total running time (in s)
|
||||
accelerationSection.E=drivingCourse[end].E-drivingCourse[accelerationSection.dataPoints[1]].E # total energy consumption (in Ws)
|
||||
CS[:t]=CS[:t]+accelerationSection.t # total running time (in s)
|
||||
CS[:E]=CS[:E]+accelerationSection.E # total energy consumption (in Ws)
|
||||
merge!(BS, Dict(:length => drivingCourse[end].s - BS[:s_entry], # total length (in m)
|
||||
:s_exit => drivingCourse[end].s, # last position (in m)
|
||||
:t => drivingCourse[end].t - drivingCourse[BS[:dataPoints][1]].t, # total running time (in s)
|
||||
:E => drivingCourse[end].E - drivingCourse[BS[:dataPoints][1]].E, # total energy consumption (in Ws)
|
||||
:v_exit => drivingCourse[end].v)) # exit speed (in m/s)))
|
||||
|
||||
CS[:t]=CS[:t]+BS[:t] # total running time (in s)
|
||||
CS[:E]=CS[:E]+BS[: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])
|
||||
end
|
||||
|
||||
merge!(CS[:behaviorSections], Dict(:acceleration=>accelerationSection))
|
||||
merge!(CS[:behaviorSections], Dict(:acceleration=>BS))
|
||||
end
|
||||
end # else: just return the given data point number without changes due to the acceleration phase
|
||||
|
||||
|
@ -479,25 +467,21 @@ function addAccelerationPhaseUntilBraking!(CS::Dict, drivingCourse::Vector{DataP
|
|||
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[:length])
|
||||
|
||||
|
||||
# 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)
|
||||
accelerationSection.v_entry=drivingCourse[end].v # entry speed (in m/s)
|
||||
push!(accelerationSection.dataPoints, drivingCourse[end].i)
|
||||
drivingCourse[end].behavior = accelerationSection.type
|
||||
BS = createBehaviorSection("acceleration", drivingCourse[end].s, drivingCourse[end].v, drivingCourse[end].i)
|
||||
drivingCourse[end].behavior = BS[:type]
|
||||
|
||||
currentStepSize=settings[:stepSize] # initializing the step size that can be reduced near intersections
|
||||
currentStepSize=settings[:stepSize] # initialize 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
|
||||
|
||||
#11/22 calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, accelerationSection.type)
|
||||
#11/22 calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type])
|
||||
|
||||
# acceleration (in m/s^2):
|
||||
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train[:m_train]/train[:ξ_train]
|
||||
|
@ -507,17 +491,17 @@ function addAccelerationPhaseUntilBraking!(CS::Dict, drivingCourse::Vector{DataP
|
|||
|
||||
# create the next data point
|
||||
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)
|
||||
drivingCourse[end].behavior = BS[:type]
|
||||
push!(BS[:dataPoints], drivingCourse[end].i)
|
||||
# 12/03: was moved behind considerFormerSpeedLimits: calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type])
|
||||
|
||||
if length(formerSpeedLimits) > 0 # If the tail of the train is located in a former characteristic section with lower speed limit check if is is possible to accelerate as normal
|
||||
(CS, drivingCourse, formerSpeedLimits, accelerationSection, endOfCsReached) = considerFormerSpeedLimits!(CS, drivingCourse, settings, train, CSs, formerSpeedLimits, accelerationSection)
|
||||
(CS, drivingCourse, formerSpeedLimits, BS, endOfCsReached) = considerFormerSpeedLimits!(CS, drivingCourse, settings, train, CSs, formerSpeedLimits, BS)
|
||||
if endOfCsReached
|
||||
return (CS, drivingCourse)
|
||||
end
|
||||
end
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, accelerationSection.type)
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type])
|
||||
s_braking=max(0.0, ceil((CS[:v_exit]^2-drivingCourse[end].v^2)/2/train[:a_braking], digits=approximationLevel))
|
||||
end #while
|
||||
|
||||
|
@ -550,25 +534,25 @@ function addAccelerationPhaseUntilBraking!(CS::Dict, drivingCourse::Vector{DataP
|
|||
end
|
||||
# delete last data point for recalculating the last step with reduced step size
|
||||
pop!(drivingCourse)
|
||||
pop!(accelerationSection.dataPoints)
|
||||
pop!(BS[:dataPoints])
|
||||
|
||||
else # if the level of approximation is reached
|
||||
if drivingCourse[end].v<=0.0
|
||||
# push!(accelerationSection.dataPoints, drivingCourse[end].i)
|
||||
# push!(BS[: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.",
|
||||
" 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]
|
||||
pop!(drivingCourse)
|
||||
pop!(accelerationSection.dataPoints)
|
||||
pop!(BS[:dataPoints])
|
||||
elseif drivingCourse[end].s + s_braking > CS[:s_exit]
|
||||
pop!(drivingCourse)
|
||||
pop!(accelerationSection.dataPoints)
|
||||
pop!(BS[:dataPoints])
|
||||
|
||||
elseif drivingCourse[end].F_T <= drivingCourse[end].F_R
|
||||
(CS, drivingCourse)=addDiminishingPhase!(CS, drivingCourse, settings, train, CSs)
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, accelerationSection.type)
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type])
|
||||
|
||||
else
|
||||
|
||||
|
@ -576,19 +560,19 @@ function addAccelerationPhaseUntilBraking!(CS::Dict, drivingCourse::Vector{DataP
|
|||
end
|
||||
end #for
|
||||
|
||||
if length(accelerationSection.dataPoints) > 1 # TODO: is it still possible that it is <=1 although there is a sepaate diminishing phase?
|
||||
if length(BS[:dataPoints]) > 1 # TODO: is it still possible that it is <=1 although there is a separate diminishing phase?
|
||||
# calculate the accumulated acceleration section information
|
||||
accelerationSection.v_exit=drivingCourse[end].v # exit speed (in m/s)
|
||||
accelerationSection.s_exit=drivingCourse[end].s # last position (in m)
|
||||
accelerationSection.length=accelerationSection.s_exit-accelerationSection.s_entry # total length (in m)
|
||||
accelerationSection.t=drivingCourse[end].t-drivingCourse[accelerationSection.dataPoints[1]].t # total running time (in s)
|
||||
accelerationSection.E=drivingCourse[end].E-drivingCourse[accelerationSection.dataPoints[1]].E # total energy consumption (in Ws)
|
||||
merge!(BS, Dict(:length => drivingCourse[end].s - BS[:s_entry], # total length (in m)
|
||||
:s_exit => drivingCourse[end].s, # last position (in m)
|
||||
:t => drivingCourse[end].t - drivingCourse[BS[:dataPoints][1]].t, # total running time (in s)
|
||||
:E => drivingCourse[end].E - drivingCourse[BS[:dataPoints][1]].E, # total energy consumption (in Ws)
|
||||
:v_exit => drivingCourse[end].v)) # exit speed (in m/s)))
|
||||
|
||||
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[:t]=CS[:t]+BS[:t] # total running time (in s)
|
||||
CS[:E]=CS[:E]+BS[:E] # total energy consumption (in Ws)
|
||||
|
||||
merge!(CS[:behaviorSections], Dict(:acceleration=>accelerationSection))
|
||||
merge!(CS[:behaviorSections], Dict(:acceleration=>BS))
|
||||
end
|
||||
end # else: just return the given data point number without changes due to the acceleration phase
|
||||
return (CS, drivingCourse)
|
||||
|
@ -599,35 +583,30 @@ end #function addAccelerationPhaseUntilBraking!
|
|||
# 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::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"?
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "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, Dict(:length=>0.0))[: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]
|
||||
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)
|
||||
cruisingSection.v_entry=drivingCourse[end].v # entry speed (in m/s)
|
||||
push!(cruisingSection.dataPoints, drivingCourse[end].i)
|
||||
drivingCourse[end].behavior = cruisingSection.type
|
||||
BS = createBehaviorSection(cruisingType, drivingCourse[end].s, drivingCourse[end].v, drivingCourse[end].i)
|
||||
drivingCourse[end].behavior = BS[:type]
|
||||
|
||||
# TODO: necessary?
|
||||
s_cruising=min(s_cruising, CS[:s_exit]-cruisingSection.s_entry)
|
||||
s_cruising=min(s_cruising, CS[:s_exit]-BS[: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"?
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "cruising") # TODO: or give BS[: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
|
||||
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[:length] && drivingCourse[end].s<BS[: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[:length] && drivingCourse[end].s<BS[: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
|
||||
|
@ -639,15 +618,10 @@ function addCruisingPhase!(CS::Dict, drivingCourse::Vector{DataPoint}, s_cruisin
|
|||
if settings[:stepVariable]=="s in m"
|
||||
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?
|
||||
end
|
||||
drivingCourse[end].behavior = cruisingSection.type
|
||||
push!(cruisingSection.dataPoints, drivingCourse[end].i)
|
||||
|
||||
# for testing
|
||||
if drivingCourse[end].F_T > drivingCourse[end].F_R && drivingCourse[end].F_R > 0.0
|
||||
error("In the cruising phase of CS",cruisingSection.id,": F_T=",drivingCourse[end].F_T," != F_R=",drivingCourse[end].F_R)
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", train[:length]/(10.0^cycle), CS[:id])) # TODO which step size should be used?
|
||||
end
|
||||
drivingCourse[end].behavior = BS[:type]
|
||||
push!(BS[:dataPoints], drivingCourse[end].i)
|
||||
|
||||
# traction effort and resisting forces (in N)
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "cruising")
|
||||
|
@ -655,22 +629,22 @@ function addCruisingPhase!(CS::Dict, drivingCourse::Vector{DataPoint}, s_cruisin
|
|||
|
||||
# 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>BS[:s_entry]+s_cruising # TODO also the following? drivingCourse[end].s > CSs[CS[:id]][:s_entry] + train[:length]))
|
||||
if settings[:stepVariable] == "s in m"
|
||||
currentStepSize=cruisingSection.s_entry+s_cruising-drivingCourse[end-1].s
|
||||
currentStepSize=BS[: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==BS[: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"
|
||||
# currentStepSize=cruisingSection.s_entry+s_cruising-drivingCourse[end-1].s
|
||||
# currentStepSize=BS[:s_entry]+s_cruising-drivingCourse[end-1].s
|
||||
# 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[:length]
|
||||
# TODO: whithout CSs should work as well, no? elseif drivingCourse[end].s >= CSs[CS[:id]][:s_entry] + train[:length]
|
||||
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")
|
||||
|
@ -678,17 +652,17 @@ function addCruisingPhase!(CS::Dict, drivingCourse::Vector{DataPoint}, s_cruisin
|
|||
|
||||
# delete last data point for recalculating the last step with reduced step size
|
||||
pop!(drivingCourse)
|
||||
pop!(cruisingSection.dataPoints)
|
||||
pop!(BS[:dataPoints])
|
||||
|
||||
else # if the level of approximation is reached
|
||||
if drivingCourse[end].s>cruisingSection.s_entry+s_cruising
|
||||
if cruisingSection.type == "clearing"
|
||||
if drivingCourse[end].s>BS[:s_entry]+s_cruising
|
||||
if BS[:type] == "clearing"
|
||||
else
|
||||
pop!(drivingCourse)
|
||||
pop!(cruisingSection.dataPoints)
|
||||
pop!(BS[:dataPoints])
|
||||
end
|
||||
# 11/21 |->
|
||||
elseif drivingCourse[end].s==cruisingSection.s_entry+s_cruising
|
||||
elseif drivingCourse[end].s==BS[:s_entry]+s_cruising
|
||||
break
|
||||
# 11/21 ->|
|
||||
elseif drivingCourse[end].F_T < drivingCourse[end].F_R
|
||||
|
@ -696,7 +670,7 @@ function addCruisingPhase!(CS::Dict, drivingCourse::Vector{DataPoint}, s_cruisin
|
|||
(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, Dict(length=>0.0))[:length])
|
||||
|
||||
else
|
||||
|
||||
|
@ -706,30 +680,30 @@ function addCruisingPhase!(CS::Dict, drivingCourse::Vector{DataPoint}, s_cruisin
|
|||
end #if
|
||||
|
||||
# TODO oder soll das lieber nach oben in den else des letzten Durchlaufs. Noch mal genauer ansehen, ob hier was doppelt gemoppelt ist
|
||||
# if drivingCourse[end].s<cruisingSection.s_entry+s_cruising
|
||||
if drivingCourse[end].s<cruisingSection.s_entry+s_cruising && drivingCourse[end].F_T >= drivingCourse[end].F_R
|
||||
# if drivingCourse[end].s<BS[:s_entry]+s_cruising
|
||||
if drivingCourse[end].s<BS[:s_entry]+s_cruising && drivingCourse[end].F_T >= drivingCourse[end].F_R
|
||||
drivingCourse[end].a=0.0 # acceleration (in m/s^2)
|
||||
|
||||
# calculate the remaining cruising way
|
||||
s_cruisingRemaining=cruisingSection.s_entry+s_cruising-drivingCourse[end].s
|
||||
s_cruisingRemaining=BS[: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]))
|
||||
drivingCourse[end].behavior = cruisingSection.type
|
||||
push!(cruisingSection.dataPoints, drivingCourse[end].i)
|
||||
drivingCourse[end].behavior = BS[:type]
|
||||
push!(BS[:dataPoints], drivingCourse[end].i)
|
||||
end
|
||||
|
||||
# calculate the accumulated cruising section information
|
||||
cruisingSection.v_exit=drivingCourse[end].v # exit speed (in m/s)
|
||||
cruisingSection.s_exit=drivingCourse[end].s # last position (in m)
|
||||
cruisingSection.length=cruisingSection.s_exit-cruisingSection.s_entry # total length (in m)
|
||||
cruisingSection.t=drivingCourse[end].t-drivingCourse[cruisingSection.dataPoints[1]].t # total running time (in s)
|
||||
cruisingSection.E=drivingCourse[end].E-drivingCourse[cruisingSection.dataPoints[1]].E # total energy consumption (in Ws)
|
||||
merge!(BS, Dict(:length => drivingCourse[end].s - BS[:s_entry], # total length (in m)
|
||||
:s_exit => drivingCourse[end].s, # last position (in m)
|
||||
:t => drivingCourse[end].t - drivingCourse[BS[:dataPoints][1]].t, # total running time (in s)
|
||||
:E => drivingCourse[end].E - drivingCourse[BS[:dataPoints][1]].E, # total energy consumption (in Ws)
|
||||
:v_exit => drivingCourse[end].v)) # exit speed (in m/s)))
|
||||
|
||||
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]+BS[:t] # total running time (in s)
|
||||
CS[:E]=CS[:E]+BS[:E] # total energy consumption (in Ws)
|
||||
|
||||
merge!(CS[:behaviorSections], Dict(Symbol(cruisingSection.type) => cruisingSection))
|
||||
merge!(CS[:behaviorSections], Dict(Symbol(BS[:type]) => BS))
|
||||
end # else: return the characteristic section without a cruising section
|
||||
|
||||
return (CS, drivingCourse)
|
||||
|
@ -741,21 +715,16 @@ function addDiminishingPhase!(CS::Dict, drivingCourse::Vector{DataPoint}, settin
|
|||
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]
|
||||
diminishingSection=BehaviorSection()
|
||||
diminishingSection.type="diminishing" # type of behavior section
|
||||
diminishingSection.s_entry=drivingCourse[end].s # first position (in m)
|
||||
diminishingSection.v_entry=drivingCourse[end].v # entry speed (in m/s)
|
||||
push!(diminishingSection.dataPoints, drivingCourse[end].i)
|
||||
drivingCourse[end].behavior = diminishingSection.type
|
||||
BS = createBehaviorSection("diminishing", drivingCourse[end].s, drivingCourse[end].v, drivingCourse[end].i)
|
||||
drivingCourse[end].behavior = BS[:type]
|
||||
|
||||
currentStepSize=settings[:stepSize] # initializing the step size that can be reduced near intersections
|
||||
currentStepSize=settings[:stepSize] # initialize 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
|
||||
|
||||
#11/22 calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, diminishingSection.type)
|
||||
#11/22 calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type])
|
||||
|
||||
# acceleration (in m/s^2):
|
||||
drivingCourse[end].a=(drivingCourse[end].F_T-drivingCourse[end].F_R)/train[:m_train]/train[:ξ_train]
|
||||
|
@ -766,11 +735,11 @@ function addDiminishingPhase!(CS::Dict, drivingCourse::Vector{DataPoint}, settin
|
|||
|
||||
# create the next data point
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
|
||||
drivingCourse[end].behavior = diminishingSection.type
|
||||
push!(diminishingSection.dataPoints, drivingCourse[end].i)
|
||||
drivingCourse[end].behavior = BS[:type]
|
||||
push!(BS[:dataPoints], drivingCourse[end].i)
|
||||
|
||||
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)
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type])
|
||||
end #while
|
||||
|
||||
# check which limit was reached and adjust the currentStepSize for the next cycle
|
||||
|
@ -793,18 +762,18 @@ function addDiminishingPhase!(CS::Dict, drivingCourse::Vector{DataPoint}, settin
|
|||
end
|
||||
# delete last data point for recalculating the last step with reduced step size
|
||||
pop!(drivingCourse)
|
||||
pop!(diminishingSection.dataPoints)
|
||||
pop!(BS[:dataPoints])
|
||||
|
||||
else # if the level of approximation is reached
|
||||
if drivingCourse[end].v<=0.0
|
||||
# push!(diminishingSection.dataPoints, drivingCourse[end].i)
|
||||
# push!(BS[: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.",
|
||||
" 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]
|
||||
pop!(drivingCourse)
|
||||
pop!(diminishingSection.dataPoints)
|
||||
pop!(BS[:dataPoints])
|
||||
|
||||
elseif drivingCourse[end].F_T > drivingCourse[end].F_R
|
||||
break
|
||||
|
@ -815,17 +784,18 @@ function addDiminishingPhase!(CS::Dict, drivingCourse::Vector{DataPoint}, settin
|
|||
end
|
||||
end #for
|
||||
|
||||
if length(diminishingSection.dataPoints) > 1 # TODO: necessary? May it be possible that there is no diminishing because braking has to start
|
||||
if length(BS[:dataPoints]) > 1 # TODO: necessary? May it be possible that there is no diminishing because braking has to start
|
||||
# calculate the accumulated diminishing section information
|
||||
diminishingSection.v_exit=drivingCourse[end].v # exit speed (in m/s)
|
||||
diminishingSection.s_exit=drivingCourse[end].s # last position (in m)
|
||||
diminishingSection.length=diminishingSection.s_exit-diminishingSection.s_entry # total length (in m)
|
||||
diminishingSection.t=drivingCourse[end].t-drivingCourse[diminishingSection.dataPoints[1]].t # total running time (in s)
|
||||
diminishingSection.E=drivingCourse[end].E-drivingCourse[diminishingSection.dataPoints[1]].E # total energy consumption (in Ws)
|
||||
CS[:t]=CS[:t]+diminishingSection.t # total running time (in s)
|
||||
CS[:E]=CS[:E]+diminishingSection.E # total energy consumption (in Ws)
|
||||
merge!(BS, Dict(:length => drivingCourse[end].s - BS[:s_entry], # total length (in m)
|
||||
:s_exit => drivingCourse[end].s, # last position (in m)
|
||||
:t => drivingCourse[end].t - drivingCourse[BS[:dataPoints][1]].t, # total running time (in s)
|
||||
:E => drivingCourse[end].E - drivingCourse[BS[:dataPoints][1]].E, # total energy consumption (in Ws)
|
||||
:v_exit => drivingCourse[end].v)) # exit speed (in m/s)))
|
||||
|
||||
merge!(CS[:behaviorSections], Dict(:diminishing=>diminishingSection))
|
||||
CS[:t]=CS[:t]+BS[:t] # total running time (in s)
|
||||
CS[:E]=CS[:E]+BS[:E] # total energy consumption (in Ws)
|
||||
|
||||
merge!(CS[:behaviorSections], Dict(:diminishing=>BS))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -837,31 +807,27 @@ end #function addDiminishingPhase!
|
|||
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the coasting section
|
||||
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[:length])
|
||||
|
||||
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)
|
||||
coastingSection.v_entry=drivingCourse[end].v # entry speed (in m/s)
|
||||
push!(coastingSection.dataPoints, drivingCourse[end].i)
|
||||
drivingCourse[end].behavior = coastingSection.type
|
||||
BS = createBehaviorSection("coasting", drivingCourse[end].s, drivingCourse[end].v, drivingCourse[end].i)
|
||||
drivingCourse[end].behavior = BS[:type]
|
||||
|
||||
currentStepSize=settings[:stepSize] # initializing the step size that can be reduced near intersections
|
||||
currentStepSize=settings[:stepSize] # initialize 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
|
||||
# traction effort and resisting forces (in N):
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, coastingSection.type)
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type])
|
||||
|
||||
# acceleration (in m/s^2):
|
||||
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]))
|
||||
drivingCourse[end].behavior = coastingSection.type
|
||||
push!(coastingSection.dataPoints, drivingCourse[end].i)
|
||||
drivingCourse[end].behavior = BS[:type]
|
||||
push!(BS[:dataPoints], drivingCourse[end].i)
|
||||
|
||||
s_braking=ceil((CS[:v_exit]^2-drivingCourse[end].v^2)/2/train[:a_braking])
|
||||
|
||||
|
@ -894,7 +860,7 @@ function addCoastingPhaseUntilBraking!(CS::Dict, drivingCourse::Vector{DataPoint
|
|||
end
|
||||
# delete last data point for recalculating the last step with reduced step size
|
||||
pop!(drivingCourse)
|
||||
pop!(coastingSection.dataPoints)
|
||||
pop!(BS[:dataPoints])
|
||||
|
||||
else # if the level of approximation is reached
|
||||
if drivingCourse[end].v<=0.0
|
||||
|
@ -905,7 +871,7 @@ function addCoastingPhaseUntilBraking!(CS::Dict, drivingCourse::Vector{DataPoint
|
|||
elseif drivingCourse[end].s + s_braking > CS[:s_exit]
|
||||
# delete last data point because it went to far
|
||||
pop!(drivingCourse)
|
||||
pop!(coastingSection.dataPoints)
|
||||
pop!(BS[: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
|
||||
# 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)
|
||||
|
@ -937,16 +903,16 @@ function addCoastingPhaseUntilBraking!(CS::Dict, drivingCourse::Vector{DataPoint
|
|||
end #for
|
||||
|
||||
# calculate the accumulated coasting section information
|
||||
coastingSection.v_exit=drivingCourse[end].v # exit speed (in m/s)
|
||||
coastingSection.s_exit=drivingCourse[end].s # last position (in m)
|
||||
coastingSection.length=coastingSection.s_exit-coastingSection.s_entry # total length (in m)
|
||||
coastingSection.t=drivingCourse[end].t-drivingCourse[coastingSection.dataPoints[1]].t # total running time (in s)
|
||||
coastingSection.E=drivingCourse[end].E-drivingCourse[coastingSection.dataPoints[1]].E # total energy consumption (in Ws)
|
||||
merge!(BS, Dict(:length => drivingCourse[end].s - BS[:s_entry], # total length (in m)
|
||||
:s_exit => drivingCourse[end].s, # last position (in m)
|
||||
:t => drivingCourse[end].t - drivingCourse[BS[:dataPoints][1]].t, # total running time (in s)
|
||||
:E => drivingCourse[end].E - drivingCourse[BS[:dataPoints][1]].E, # total energy consumption (in Ws)
|
||||
:v_exit => drivingCourse[end].v)) # exit speed (in m/s)))
|
||||
|
||||
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]+BS[:t] # total running time (in s)
|
||||
CS[:E]=CS[:E]+BS[:E] # total energy consumption (in Ws)
|
||||
|
||||
merge!(CS[:behaviorSections], Dict(:coasting=>coastingSection))
|
||||
merge!(CS[:behaviorSections], Dict(:coasting=>BS))
|
||||
end ## else: just return the given data point number without changes due to the coasting phase
|
||||
return (CS, drivingCourse)
|
||||
end #function addCoastingPhaseUntilBraking!
|
||||
|
@ -957,24 +923,20 @@ end #function addCoastingPhaseUntilBraking!
|
|||
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.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
|
||||
BS = createBehaviorSection("braking", drivingCourse[end].s, drivingCourse[end].v, drivingCourse[end].i)
|
||||
BS[:s_exit]=CS[:s_exit] # last position (in m)
|
||||
drivingCourse[end].behavior = BS[:type]
|
||||
|
||||
# traction effort and resisting forces (in N)
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, brakingSection.type)
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type])
|
||||
|
||||
push!(drivingCourse, DataPoint())
|
||||
drivingCourse[end].i = drivingCourse[end-1].i+1 # incrementing the number of the data point
|
||||
drivingCourse[end].behavior = brakingSection.type
|
||||
push!(brakingSection.dataPoints, drivingCourse[end].i) # refering from the breaking section to the last of its data points
|
||||
drivingCourse[end].behavior = BS[:type]
|
||||
push!(BS[:dataPoints], drivingCourse[end].i) # refering from the breaking section to the last of its data points
|
||||
|
||||
# calculate s, t, v
|
||||
drivingCourse[end].s=brakingSection.s_exit # position (in m)
|
||||
drivingCourse[end].s=BS[: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)
|
||||
|
@ -996,15 +958,16 @@ function addBrakingPhase!(CS::Dict, drivingCourse::Vector{DataPoint}, settings::
|
|||
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)
|
||||
|
||||
brakingSection.v_exit=drivingCourse[end].v # exit speed (in m/s)
|
||||
brakingSection.length=drivingCourse[end].Δs # total length (in m)
|
||||
brakingSection.t=drivingCourse[end].Δt # total running time (in s)
|
||||
brakingSection.E=drivingCourse[end].ΔE # total energy consumption (in Ws)
|
||||
merge!(BS, Dict(:length => drivingCourse[end].Δs, # total length (in m)
|
||||
#:s_exit => drivingCourse[end].s, # last position (in m)
|
||||
:t => drivingCourse[end].Δt, # total running time (in s)
|
||||
:E => drivingCourse[end].ΔE, # total energy consumption (in Ws)
|
||||
:v_exit => drivingCourse[end].v)) # exit speed (in m/s)))
|
||||
|
||||
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]+BS[:t] # total running time (in s)
|
||||
CS[:E]=CS[:E]+BS[:E] # total energy consumption (in Ws)
|
||||
|
||||
merge!(CS[:behaviorSections], Dict(:braking=>brakingSection))
|
||||
merge!(CS[:behaviorSections], Dict(:braking=>BS))
|
||||
end # else: return the characteristic section without a braking section
|
||||
return (CS, drivingCourse)
|
||||
end #function addBrakingPhase!
|
||||
|
@ -1014,18 +977,14 @@ end #function addBrakingPhase!
|
|||
# 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::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)
|
||||
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
|
||||
BS = createBehaviorSection("braking", drivingCourse[end].s, drivingCourse[end].v, drivingCourse[end].i)
|
||||
drivingCourse[end].behavior = BS[:type]
|
||||
|
||||
currentStepSize=settings[:stepSize] # initializing the step size that can be reduced near intersections
|
||||
currentStepSize=settings[:stepSize] # initialize 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
|
||||
# traction effort and resisting forces (in N):
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, brakingSection.type)
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type])
|
||||
|
||||
# acceleration (in m/s^2):
|
||||
drivingCourse[end].a=train[:a_braking]
|
||||
|
@ -1041,8 +1000,8 @@ function addBrakingPhaseStepwise!(CS::Dict, drivingCourse::Vector{DataPoint}, se
|
|||
end
|
||||
end
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
|
||||
drivingCourse[end].behavior = brakingSection.type
|
||||
push!(brakingSection.dataPoints, drivingCourse[end].i)
|
||||
drivingCourse[end].behavior = BS[:type]
|
||||
push!(BS[:dataPoints], drivingCourse[end].i)
|
||||
|
||||
# s_braking=ceil((CS[:v_exit]^2-drivingCourse[end].v^2)/2/train[:a_braking])
|
||||
end # while
|
||||
|
@ -1056,7 +1015,6 @@ function addBrakingPhaseStepwise!(CS::Dict, drivingCourse::Vector{DataPoint}, se
|
|||
|
||||
#drivingCourse[end-1].a=round((drivingCourse[end].v^2-drivingCourse[end-1].v^2)/2/drivingCourse[end].Δs, digits=approximationLevel) # acceleration (in m/s^2) (rounding because it should not be less than a_braking)
|
||||
drivingCourse[end-1].a=(drivingCourse[end].v^2-drivingCourse[end-1].v^2)/2/drivingCourse[end].Δs # acceleration (in m/s^2)
|
||||
# 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])
|
||||
|
@ -1075,16 +1033,16 @@ function addBrakingPhaseStepwise!(CS::Dict, drivingCourse::Vector{DataPoint}, se
|
|||
end
|
||||
|
||||
# calculate the accumulated coasting section information
|
||||
brakingSection.v_exit=drivingCourse[end].v # exit speed (in m/s)
|
||||
brakingSection.s_exit=drivingCourse[end].s # last position (in m)
|
||||
brakingSection.length=brakingSection.s_exit-brakingSection.s_entry # total length (in m)
|
||||
brakingSection.t=drivingCourse[end].t-drivingCourse[brakingSection.dataPoints[1]].t # total running time (in s)
|
||||
brakingSection.E=drivingCourse[end].E-drivingCourse[brakingSection.dataPoints[1]].E # total energy consumption (in Ws)
|
||||
merge!(BS, Dict(:length => drivingCourse[end].s - BS[:s_entry], # total length (in m)
|
||||
:s_exit => drivingCourse[end].s, # last position (in m)
|
||||
:t => drivingCourse[end].t - drivingCourse[BS[:dataPoints][1]].t, # total running time (in s)
|
||||
:E => drivingCourse[end].E - drivingCourse[BS[:dataPoints][1]].E, # total energy consumption (in Ws)
|
||||
:v_exit => drivingCourse[end].v)) # exit speed (in m/s)))
|
||||
|
||||
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]+BS[:t] # total running time (in s)
|
||||
CS[:E]=CS[:E]+BS[:E] # total energy consumption (in Ws)
|
||||
|
||||
merge!(CS[:behaviorSections], Dict(:braking=>brakingSection))
|
||||
merge!(CS[:behaviorSections], Dict(:braking=>BS))
|
||||
end # else: return the characteristic section without a braking section
|
||||
return (CS, drivingCourse)
|
||||
end #function addBrakingPhaseStepwise!
|
||||
|
@ -1095,26 +1053,34 @@ end #function addBrakingPhaseStepwise!
|
|||
function addStandstill!(CS::Dict, drivingCourse::Vector{DataPoint}, settings::Dict, train::Dict, CSs::Vector{Dict})
|
||||
|
||||
if drivingCourse[end].v == 0.0
|
||||
standstillSection=BehaviorSection()
|
||||
standstillSection.type="standstill" # type of behavior section
|
||||
standstillSection.s_entry=drivingCourse[end].s # first position (in m)
|
||||
standstillSection.s_exit=drivingCourse[end].s # last position (in m)
|
||||
standstillSection.v_entry=drivingCourse[end].v # entry speed (in m/s)
|
||||
standstillSection.v_exit=drivingCourse[end].v # exit speed (in m/s)
|
||||
standstillSection.length=0.0 # total length (in m)
|
||||
standstillSection.t=0.0 # total running time (in s)
|
||||
standstillSection.E=0.0 # total energy consumption (in Ws)
|
||||
push!(standstillSection.dataPoints, drivingCourse[end].i) # refering from the breaking section to the first of its data points
|
||||
|
||||
|
||||
drivingCourse[end].behavior = standstillSection.type
|
||||
BS = createBehaviorSection("standstill", drivingCourse[end].s, drivingCourse[end].v, drivingCourse[end].i)
|
||||
merge!(BS, Dict(:length => 0.0, # total length (in m)
|
||||
:t => 0.0, # total running time (in s)
|
||||
:E => 0.0, # total energy consumption (in Ws)
|
||||
:s_exit => drivingCourse[end].s, # last position (in m)
|
||||
:v_exit => drivingCourse[end].v)) # exit speed (in m/s)))
|
||||
drivingCourse[end].behavior = BS[:type]
|
||||
|
||||
# traction effort and resisting forces (in N)
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, standstillSection.type)
|
||||
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type])
|
||||
|
||||
merge!(CS[:behaviorSections], Dict(:standstill => standstillSection))
|
||||
merge!(CS[:behaviorSections], Dict(:standstill => BS))
|
||||
end # else: return the characteristic section without a standstillSection section
|
||||
return (CS, drivingCourse)
|
||||
end #function addStandstill!
|
||||
|
||||
function createBehaviorSection(type::String, s_entry::Real, v_entry::Real, startingPoint::Integer)
|
||||
BS= Dict(#:type => behavior, # type of behavior section: breakFree, clearing, acceleration, cruising, diminishing, coasting, cruisingAfterCoasting, braking or standstill
|
||||
:type => type, # type of behavior section: "breakFree", "clearing", "acceleration", "cruising", "diminishing", "coasting", "cruisingAfterCoasting", "braking" or "standstill"
|
||||
:length => 0.0, # total length (in m)
|
||||
:s_entry => s_entry, # first position (in m)
|
||||
:s_exit => 0.0, # last position (in m)
|
||||
:t => 0.0, # total running time (in s)
|
||||
:E => 0.0, # total energy consumption (in Ws)
|
||||
:v_entry => v_entry, # entry speed (in m/s)
|
||||
:v_exit => 0.0, # exit speed (in m/s)
|
||||
:dataPoints => [startingPoint]) # list of identifiers of the containing data points starting with the initial point
|
||||
return BS
|
||||
end #function createBehaviorSection
|
||||
|
||||
end #module MovingPhases
|
||||
|
|
|
@ -25,22 +25,24 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
|
|||
# check if the CS has a cruising section
|
||||
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_breakFree = get(BSs, :breakFree, Dict(:length=>0.0))[:length]
|
||||
s_clearing = get(BSs, :clearing, Dict(:length=>0.0))[:length]
|
||||
s_acceleration = get(BSs, :acceleration, Dict(:length=>0.0))[: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=CS[: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!(BSs, :breakFree)
|
||||
delete!(BSs, :clearing)
|
||||
delete!(BSs, :acceleration)
|
||||
delete!(BSs, :diminishing)
|
||||
delete!(BSs, :cruising)
|
||||
CS[:E]=0.0
|
||||
CS[:t]=0.0
|
||||
# reset the characteristic section (CS), delete behavior sections (BS) that were used during the preperation for setting v_entry, v_peak and v_exit
|
||||
# 01/07 old: delete!(BSs, :breakFree)
|
||||
# 01/07 old: delete!(BSs, :clearing)
|
||||
# 01/07 old: delete!(BSs, :acceleration)
|
||||
# 01/07 old: delete!(BSs, :diminishing)
|
||||
# 01/07 old: delete!(BSs, :cruising)
|
||||
CS[:behaviorSections] = Dict()
|
||||
CS[:E] = 0.0
|
||||
CS[:t] = 0.0
|
||||
|
||||
|
||||
if s_clearing == CS[:length]
|
||||
|
@ -113,6 +115,7 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict
|
|||
|
||||
#create a new moving section for the minimum energy consumption
|
||||
movingSectionOriginal=copyMovingSection(movingSectionMinimumRunningTime)
|
||||
# 01/01 new when Datapoint is a Dict: movingSectionOriginal=copy(movingSectionMinimumRunningTime)
|
||||
CSsOrig::Vector{Dict} = movingSectionOriginal[:characteristicSections]
|
||||
merge!(movingSectionOriginal, Dict(:energySavingModifications => [])) # list containing all the used energy saving modifications
|
||||
|
||||
|
@ -196,11 +199,11 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict
|
|||
get(CSsOrig[csIdMax][:behaviorSections], :clearing,
|
||||
get(CSsOrig[csIdMax][:behaviorSections], :breakFree,
|
||||
get(CSsOrig[csIdMax][:behaviorSections], :diminishing,
|
||||
BehaviorSection()))))))))).dataPoints[end]
|
||||
Dict(:dataPoints => [0]))))))))))[: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 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 occure in a fixed order.
|
||||
if haskey(CSsOrig[csIdMax][:behaviorSections], :diminishing)
|
||||
lastIdOfSelectedCsOriginal = max(lastIdOfSelectedCsOriginal, CSsOrig[csIdMax][:behaviorSections][:diminishing].dataPoints[end])
|
||||
lastIdOfSelectedCsOriginal = max(lastIdOfSelectedCsOriginal, CSsOrig[csIdMax][:behaviorSections][:diminishing][:dataPoints][end])
|
||||
end
|
||||
|
||||
# create new driving course
|
||||
|
@ -233,7 +236,8 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict
|
|||
|
||||
# replace the original driving course and CS with the new modified ones
|
||||
drivingCourseOriginal=drivingCourseNew
|
||||
CSsOrig[csIdMax]=copyCharacteristicSection(movingSectionOriginal[:energySavingModifications][end][:csModified])
|
||||
CSsOrig[csIdMax]=copy(movingSectionOriginal[:energySavingModifications][end][:csModified])
|
||||
# 01/07 old without copy: 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)
|
||||
|
||||
|
@ -244,8 +248,8 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict
|
|||
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
|
||||
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
|
||||
|
@ -370,7 +374,8 @@ 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 => copyCharacteristicSection(original[:csModified])) # the modified characteristic section
|
||||
:csModified => copy(original[:csModified])) # the modified characteristic section
|
||||
# 01/07 old without copy: csModified => copyCharacteristicSection(original[:csModified])) # the modified characteristic section
|
||||
|
||||
drivingCourseModified = DataPoint[]
|
||||
for i in 1:length(original[:drivingCourseModified])
|
||||
|
@ -378,8 +383,7 @@ function copyEnergySavingModification(original::Dict)
|
|||
end
|
||||
merge!(copy, Dict(:drivingCourseModified => drivingCourseModified)) # drivingCourse for the modified characteristic section
|
||||
return copy
|
||||
end #function EnergySavingModification
|
||||
|
||||
end #function copyEnergySavingModification
|
||||
|
||||
function updateEnergySavingModifications!(energySavingModifications::Vector{Dict}, csIdMax::Integer, drivingCourseNew::Vector{DataPoint}, endOfModificationId::Integer, lastIdOfSelectedCsOriginal::Integer)
|
||||
allBs=[:breakFree, :clearing, :acceleration, :cruising, :diminishing, :coasting, :cruisingAfterCoasting, :braking, :standstill]
|
||||
|
@ -390,8 +394,8 @@ function updateEnergySavingModifications!(energySavingModifications::Vector{Dict
|
|||
# update the behavior sections of the modified charateristic section
|
||||
for bs in 1: length(allBs)
|
||||
if haskey(BSs, allBs[bs])
|
||||
for point in 1:length(BSs[allBs[bs]].dataPoints)
|
||||
BSs[allBs[bs]].dataPoints[point] = BSs[allBs[bs]].dataPoints[point] + difference
|
||||
for point in 1:length(BSs[allBs[bs]][:dataPoints])
|
||||
BSs[allBs[bs]][:dataPoints][point] = BSs[allBs[bs]][:dataPoints][point] + difference
|
||||
end
|
||||
end #if
|
||||
end #for
|
||||
|
@ -423,10 +427,11 @@ function copyMovingSection(original::Dict)
|
|||
#TODO after removing the mutable structs: Is it possible to just "copy"?
|
||||
CSsCopy = Vector{Dict}()
|
||||
for csId in 1:length(original[:characteristicSections])
|
||||
push!(CSsCopy, copyCharacteristicSection(original[:characteristicSections][csId]))
|
||||
push!(CSsCopy, copy(original[:characteristicSections][csId]))
|
||||
# 01/07 old without copy: push!(CSsCopy, copyCharacteristicSection(original[:characteristicSections][csId]))
|
||||
end #for
|
||||
|
||||
copy = Dict(:id => original[:id], # identifier
|
||||
copiedMS = Dict(:id => original[:id], # identifier
|
||||
:length => original[:length], # total length (in m)
|
||||
:s_entry => original[:s_entry], # first position (in m)
|
||||
:s_exit => original[:s_exit], # last position (in m)
|
||||
|
@ -437,28 +442,29 @@ function copyMovingSection(original::Dict)
|
|||
if haskey(original, :energySavingModifications) # list of containing all the used energy saving modifications
|
||||
ModificationsCopy = Dict[]
|
||||
for modId in 1:length(original[:energySavingModifications])
|
||||
push!(ModificationsCopy, EnergySavingModification(original[:energySavingModifications][modId]))
|
||||
push!(ModificationsCopy, copyEnergySavingModification(original[:energySavingModifications][modId])) # TODO or should it be copyEnergySavingModification
|
||||
# 01/07 new when DataPoint is a Dict: push!(ModificationsCopy, copy(original[:energySavingModifications][modId]))
|
||||
end #for
|
||||
merge!(copy, Dict(:energySavingModifications => ModificationsCopy))
|
||||
merge!(copiedMS, Dict(:energySavingModifications => ModificationsCopy))
|
||||
end
|
||||
|
||||
if haskey(original, :t_recovery) # total recovery time for energy-saving modifications (in s)
|
||||
merge!(copy, Dict(:t_recovery => original[:t_recovery]))
|
||||
merge!(copiedMS, Dict(:t_recovery => original[:t_recovery]))
|
||||
end
|
||||
|
||||
if haskey(original, :t_recoveryAvailable) # still available recovery time for energy-saving modifications (in s)
|
||||
merge!(copy, Dict(:t_recoveryAvailable => original[:t_recoveryAvailable]))
|
||||
merge!(copiedMS, Dict(:t_recoveryAvailable => original[:t_recoveryAvailable]))
|
||||
end
|
||||
return copy
|
||||
return copiedMS
|
||||
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
|
||||
copiedCS = 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 ‰)
|
||||
: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)
|
||||
|
@ -470,10 +476,11 @@ function copyCharacteristicSection(original::Dict)
|
|||
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]])))
|
||||
#merge!(copiedCS[:behaviorSections], Dict(allBs[bs] => copyBehaviorSection(original[:behaviorSections][allBs[bs]])))
|
||||
merge!(copiedCS[:behaviorSections], Dict(allBs[bs] => copy(original[:behaviorSections][allBs[bs]])))
|
||||
end #if
|
||||
end #for
|
||||
return copy
|
||||
return copiedCS
|
||||
end #function copyCharacteristicSection
|
||||
|
||||
=#
|
||||
end #module OperationModes
|
||||
|
|
|
@ -263,9 +263,9 @@ function printSectionInformation(movingSection::Dict)
|
|||
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])
|
||||
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
|
||||
|
|
|
@ -6,7 +6,7 @@ using .MovingPhases
|
|||
|
||||
export preparateSections
|
||||
|
||||
## create a moving section and its containing characteristic sections with securedd braking, acceleration and cruising behavior
|
||||
## create a moving section and its containing characteristic sections with secured braking, acceleration and cruising behavior
|
||||
function preparateSections(path::Dict, train::Dict, settings::Dict)
|
||||
movingSection=createMovingSection(path, train[:v_limit])
|
||||
movingSection=secureBrakingBehavior!(movingSection, train[:a_braking])
|
||||
|
@ -104,11 +104,10 @@ function secureAccelerationBehavior!(movingSection::Dict, settings::Dict, train:
|
|||
startingPoint.v=CSs[csId][:v_entry]
|
||||
accelerationCourse=[startingPoint] # List of data points
|
||||
|
||||
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_exit]=min(CSs[csId][:v_exit], CSs[csId][:v_peak], accelerationCourse[end].v)
|
||||
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_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
|
||||
|
|
70
src/types.jl
70
src/types.jl
|
@ -1,13 +1,16 @@
|
|||
module types
|
||||
# definition of all the additional types and their constructors
|
||||
export DataPoint, BehaviorSection #, CharacteristicSection
|
||||
|
||||
export DataPoint#, BehaviorSection
|
||||
export copyBehaviorSection # TODO is it still necessary if there is no more mutable struct? can just copy(original) be used?
|
||||
#export trainType
|
||||
|
||||
#@enum trainType passenger=1 freight=2 motorCoachTrain=3
|
||||
#@enum behavior breakFree=1 clearing=2 acceleration=3 cruising=4diminishing=6 coasting=7 cruisingAfterCoasting=8 braking=9 standstill=10
|
||||
## a data point is the smallest element of the driving course. One step of the step approach is between two data points
|
||||
mutable struct DataPoint
|
||||
i::Integer # identifier and counter variable of the dricing course
|
||||
behavior::String # type of BehaviorSection the DataPoint ist part of ("breakFree", "clearing", "acceleration", "cruising", "diminishing", "coasting", "cruisingAfterCoasting","braking" or "standstill")
|
||||
# a data point which is the last point of one BehaviorSection and the first point of the next BehaviorSection will be attached to the latter
|
||||
behavior::String # type of behavior section the DataPoint ist part of ("breakFree", "clearing", "acceleration", "cruising", "diminishing", "coasting", "cruisingAfterCoasting", "braking" or "standstill")
|
||||
# a data point which is the last point of one behavior section and the first point of the next behavior section will be attached to the latter
|
||||
s::AbstractFloat # position (in m)
|
||||
Δs::AbstractFloat # step size (in m)
|
||||
t::AbstractFloat # point in time (in s)
|
||||
|
@ -31,55 +34,24 @@ DataPoint()=DataPoint(0, "", 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0
|
|||
DataPoint(original::DataPoint)=DataPoint(original.i, original.behavior, original.s, original.Δs, original.t, original.Δt, original.v, original.Δv, original.a, original.W, original.ΔW, original.E, original.ΔE, original.F_T, original.F_R, original.R_path, original.R_train, original.R_traction, original.R_wagons)
|
||||
|
||||
|
||||
|
||||
## different sections the whole path can be devided in the following
|
||||
## smallest section of the path is the behavior section. It relates to the containing data points via their identifier.
|
||||
mutable struct BehaviorSection
|
||||
type::String # type of behavior section: "breakFree", "clearing", "acceleration", "cruising", "diminishing", "coasting", "cruisingAfterCoasting","braking" or "standstill"
|
||||
length::AbstractFloat # total length (in m)
|
||||
s_entry::AbstractFloat # first position (in m)
|
||||
s_exit::AbstractFloat # last position (in m)
|
||||
t::AbstractFloat # total running time (in s)
|
||||
E::AbstractFloat # total energy consumption (in Ws)
|
||||
v_entry::AbstractFloat # entry speed (in m/s)
|
||||
v_exit::AbstractFloat # exit speed (in m/s)
|
||||
dataPoints::Vector{Integer} # list of identifiers of the containing data points
|
||||
end # mutable struct BehaviorSection
|
||||
BehaviorSection()=BehaviorSection("", 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, [])
|
||||
function BehaviorSection(original::BehaviorSection)
|
||||
function copyBehaviorSection(original::Dict)
|
||||
bsDataPoints=[]
|
||||
for i in 1:length(original.dataPoints)
|
||||
push!(bsDataPoints, original.dataPoints[i])
|
||||
for i in 1:length(original[:dataPoints])
|
||||
push!(bsDataPoints, original[:dataPoints][i])
|
||||
end
|
||||
return BehaviorSection(original.type, original.length, original.s_entry, original.s_exit, original.t, original.E, original.v_entry, original.v_exit, bsDataPoints)
|
||||
copiedBS = Dict(#:type => behavior, # type of behavior section: breakFree, clearing, acceleration, cruising, diminishing, coasting, cruisingAfterCoasting, braking or standstill
|
||||
:type => original[:type], # type of behavior section: "breakFree", "clearing", "acceleration", "cruising", "diminishing", "coasting", "cruisingAfterCoasting", "braking" or "standstill"
|
||||
:length => original[:length], # total length (in m)
|
||||
:s_entry => original[:s_entry], # first position (in m)
|
||||
:s_exit => original[:s_exit], # last position (in m)
|
||||
:t => original[:t], # total running time (in s)
|
||||
:E => original[:E], # total energy consumption (in Ws)
|
||||
:v_entry => original[:v_entry], # entry speed (in m/s)
|
||||
:v_exit => original[:v_exit], # exit speed (in m/s)
|
||||
:dataPoints => bsDataPoints) # list of identifiers of the containing data points
|
||||
return copiedBS
|
||||
end
|
||||
|
||||
#= # 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)
|
||||
s_entry::AbstractFloat # first position (in m)
|
||||
s_exit::AbstractFloat # last position (in m)
|
||||
t::AbstractFloat # total running time (in s)
|
||||
E::AbstractFloat # total energy consumption (in Ws)
|
||||
v_limit::AbstractFloat # speed limit (in m/s)
|
||||
v_peak::AbstractFloat # maximum reachable speed (in m/s)
|
||||
v_entry::AbstractFloat # maximum entry speed (in m/s)
|
||||
v_exit::AbstractFloat # maximum exit speed (in m/s)
|
||||
r_path::AbstractFloat # spedific path resistance (in ‰)
|
||||
behaviorSections::AbstractDict{Symbol, BehaviorSection} # list of containing behavior sections
|
||||
end # mutable struct CharacteristicSection
|
||||
CharacteristicSection()=CharacteristicSection(0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Dict{Symbol, BehaviorSection}())
|
||||
function CharacteristicSection(original::CharacteristicSection)
|
||||
copy=CharacteristicSection(original.id, original.length, original.s_entry, original.s_exit, original.t, original.E, original.v_limit, original.v_peak, original.v_entry, original.v_exit, original.r_path, Dict{Symbol, BehaviorSection}())
|
||||
allBs=[:breakFree, :clearing, :acceleration, :cruising, :diminishing, :coasting, :cruisingAfterCoasting, :braking, :standstill]
|
||||
for bs in 1: length(allBs)
|
||||
if haskey(original.behaviorSections, allBs[bs])
|
||||
merge!(copy.behaviorSections, Dict(allBs[bs] => BehaviorSection(original.behaviorSections[allBs[bs]])))
|
||||
end #if
|
||||
end #for
|
||||
return copy
|
||||
end #function CharacteristicSection
|
||||
=#
|
||||
|
||||
end #module
|
||||
|
|
|
@ -11,14 +11,14 @@ include("../src/Input.jl")
|
|||
using .Input
|
||||
using YAML, Test
|
||||
|
||||
@enum trainTypes passenger=1 freight=2 motorCoachTrain=3
|
||||
@enum trainType passenger=1 freight=2 motorCoachTrain=3
|
||||
|
||||
@test Input.getEnum("passenger", trainTypes) == passenger::trainTypes
|
||||
@test Input.getEnum("freight", trainTypes) == freight::trainTypes
|
||||
@test Input.getEnum("motorCoachTrain", trainTypes) == motorCoachTrain::trainTypes
|
||||
@test Input.getEnum("passenger", trainType) == passenger::trainType
|
||||
@test Input.getEnum("freight", trainType) == freight::trainType
|
||||
@test Input.getEnum("motorCoachTrain", trainType) == motorCoachTrain::trainType
|
||||
|
||||
data = YAML.load(open("data/trains/train_passenger_IC2.yaml"))
|
||||
@test Input.getEnum(data["train"]["trainType"], trainTypes) == passenger::trainTypes
|
||||
@test Input.getEnum(data["train"]["trainType"], trainType) == passenger::trainType
|
||||
|
||||
data = YAML.load(open("data/trains/train_freight_V90withOreConsist.yaml"))
|
||||
@test Input.getEnum(data["train"]["trainType"], trainTypes) == freight::trainTypes
|
||||
@test Input.getEnum(data["train"]["trainType"], trainType) == freight::trainType
|
||||
|
|
Loading…
Reference in New Issue