Refactor and fix modules EnergySaving, OperationModes and MovingPhases
parent
5c9bb29aa6
commit
d71a1e882b
16
README.md
16
README.md
|
@ -23,6 +23,20 @@ See folder examples.
|
|||
|
||||
# History
|
||||
|
||||
## Version 0.4
|
||||
|
||||
Refactor and fix modules EnergySaving, OperationModes and MovingPhases
|
||||
|
||||
The general used level of accuracy from v0.3 was added to EnergySaving and OperationModes. OperationModes and MovingPhases were fixed for steep ascents were a train runs with maximum tractive effort while the driving resistances are even higher.
|
||||
|
||||
|
||||
## Version 0.3
|
||||
|
||||
Refactor module MovingPhases
|
||||
|
||||
Repeatedly occuring code lines were extracted and smaller functions created (e.g. the function moveAStep). A new approach for calculating the waypoints near intersections was integrated (e.g. including an editable level of accuracy).
|
||||
|
||||
|
||||
## Version 0.2
|
||||
|
||||
Modules and variables were renamed.
|
||||
|
@ -36,7 +50,7 @@ Proof of concept and master thesis submission.
|
|||
|
||||
# Acknowledgement
|
||||
|
||||
This work was supervides by South Westphalia University of Applied Sciences and Technical University Braunschweig.
|
||||
This work was supervised by South Westphalia University of Applied Sciences and Technical University Braunschweig.
|
||||
|
||||
------------
|
||||
|
||||
|
|
|
@ -5,6 +5,9 @@ using ..MovingPhases
|
|||
|
||||
export calculateRecoveryTime, increaseCoastingSection, decreaseMaximumVelocity, combineEnergySavingMethods
|
||||
|
||||
approximationLevel = 6 # value for approximation to intersections
|
||||
# TODO: define it in TrainRun and give it to each function?
|
||||
|
||||
function calculateRecoveryTime(s_MS::AbstractFloat, t_MS::AbstractFloat, train::Train)
|
||||
# function for calculating the recovery time that can be used for energy saving
|
||||
# MS: Moving Section
|
||||
|
@ -86,22 +89,22 @@ function calculateRecoveryTime(s_MS::AbstractFloat, t_MS::AbstractFloat, train::
|
|||
end # if train.trainType
|
||||
end #function calculateRecoveryTime
|
||||
|
||||
|
||||
function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCourse::Vector{Waypoint}, settings::Settings, train::Train, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||
if haskey(csOriginal.behaviorSections, "cruising") && haskey(csOriginal.behaviorSections, "braking")
|
||||
cruisingReduction=settings.stepSize
|
||||
while cruisingReduction>=settings.stepSize/100
|
||||
while cruisingReduction>=settings.stepSize/100 # will be done once and repeated twice with smaller cruisingReduction unless !(drivingCourseModified[end].v<=csModified.v_exit && drivingCourseModified[end].s<csModified.s_end) -> see below at the end of the while loop
|
||||
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_end) -> see below at the end of the while loop
|
||||
|
||||
# creating a drivingCourse for the characteristic section
|
||||
# create a copy for the characteristic sections drivingCourse
|
||||
energySavingStartId=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).waypoints[1]
|
||||
if energySavingStartId==0
|
||||
error("ERROR at creating a new driving course for energy saving with coasting !")
|
||||
end
|
||||
# tried to insert copy on 15.07.2021 drivingCourseModified=[copy(drivingCourse[1])]
|
||||
# TODO: tried to insert copy on 15.07.2021 drivingCourseModified=[copy(drivingCourse[1])]
|
||||
drivingCourseModified=[Waypoint(drivingCourse[1])]
|
||||
for i in 2:energySavingStartId
|
||||
# tried to insert copy on 15.07.2021 push!(drivingCourseModified, copy(drivingCourse[i])) # List of waypoints till the start of energy saving
|
||||
# TODO: tried to insert copy on 15.07.2021 push!(drivingCourseModified, copy(drivingCourse[i])) # List of waypoints till the start of energy saving
|
||||
push!(drivingCourseModified, Waypoint(drivingCourse[i])) # List of waypoints till the start of energy saving
|
||||
end
|
||||
|
||||
|
@ -109,14 +112,18 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
|
|||
if settings.stepVariable=="s in m" # distance step method
|
||||
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).s_total-cruisingReduction
|
||||
elseif settings.stepVariable=="t in s" # time step method
|
||||
t_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).t_total-cruisingReduction
|
||||
s_cruising=t_cruising*drivingCourseModified[end].v
|
||||
# 09/20 old: doesn't work for non constant cruising
|
||||
# t_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).t_total-cruisingReduction
|
||||
# s_cruising=t_cruising*drivingCourseModified[end].v
|
||||
wayReduction=drivingCourse(get(csOriginal.behaviorSections, "cruising", BehaviorSection()).waypoints[end]).v*cruisingReduction
|
||||
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).s_total-wayReduction
|
||||
|
||||
elseif settings.stepVariable=="v in m/s" # velocity step method
|
||||
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).s_total-cruisingReduction*10 # TODO: or better: *100 ?
|
||||
end #if
|
||||
s_cruising=max(0.0, s_cruising)
|
||||
|
||||
# copying csOriginal to csModified
|
||||
# copy csOriginal to csModified
|
||||
csModified=CharacteristicSection(csOriginal.id, csOriginal.s_total, csOriginal.s_start, csOriginal.s_end, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_reach, csOriginal.v_entry, csOriginal.v_exit, csOriginal.f_Rp, Dict{String, BehaviorSection}())
|
||||
if haskey(csOriginal.behaviorSections, "starting")
|
||||
startingSection=BehaviorSection(get(csOriginal.behaviorSections, "starting", BehaviorSection()))
|
||||
|
@ -137,14 +144,14 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
|
|||
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "acceleration", BehaviorSection()).t_total
|
||||
end
|
||||
|
||||
# calculating the new and now shorter cruising section
|
||||
# simulate the new and now shorter cruising section
|
||||
if s_cruising>0.0
|
||||
(csModified, drivingCourseModified)=addCruisingPhase!(csModified, drivingCourseModified, s_cruising, settings, train, allCSs, "cruising")
|
||||
end
|
||||
|
||||
(csModified, drivingCourseModified)=addCoastingPhaseUntilBraking!(csModified, drivingCourseModified, settings, train, allCSs)
|
||||
|
||||
if drivingCourseModified[end].v<csModified.v_exit || drivingCourseModified[end].s>csModified.s_end
|
||||
if drivingCourseModified[end].v < csModified.v_exit || drivingCourseModified[end].s > csModified.s_end
|
||||
# the train reaches v_exit before reaching s_end. The cruising and coasting sections have to be calculated again with a larger cruising section (so with a smaller reduction of the cruising section)
|
||||
cruisingReduction=cruisingReduction/10
|
||||
else
|
||||
|
@ -152,15 +159,16 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
|
|||
end
|
||||
end # while cruisingReduction
|
||||
|
||||
if drivingCourseModified[end].v>csModified.v_exit
|
||||
(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings.massModel, train, allCSs)
|
||||
elseif drivingCourseModified[end].v==csModified.v_exit && drivingCourseModified[end].s<csModified.s_end
|
||||
# v_exit is already reached. Now cruising till the end of the CS
|
||||
if drivingCourseModified[end].v > csModified.v_exit
|
||||
#(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings.massModel, train, allCSs)
|
||||
(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings, train, allCSs)
|
||||
elseif drivingCourseModified[end].v == csModified.v_exit && drivingCourseModified[end].s < csModified.s_end
|
||||
# v_exit is already reached. Now cruise till the end of the CS
|
||||
s_cruisingAfterCoasting=csModified.s_end-drivingCourseModified[end].s
|
||||
(csModified, drivingCourseModified)=addCruisingPhase!(csModified, drivingCourseModified, s_cruisingAfterCoasting, settings, train, allCSs, "cruisingAfterCoasting")
|
||||
end
|
||||
|
||||
if t_recoveryAvailable<(csModified.t_total-csOriginal.t_total) || drivingCourseModified[end].v!=csModified.v_exit || drivingCourseModified[end].s!=csModified.s_end # time loss is to high and the CS has to be calculated again with larger cruising section (so with a smaller reduction of the cruising section) or v_exit or s_end are not reached excatly
|
||||
if t_recoveryAvailable < csModified.t_total-csOriginal.t_total || drivingCourseModified[end].v != csModified.v_exit || drivingCourseModified[end].s != csModified.s_end # time loss is to high and the CS has to be calculated again with larger cruising section (so with a smaller reduction of the cruising section) or v_exit or s_end are not reached excatly
|
||||
cruisingReduction=cruisingReduction/10
|
||||
else
|
||||
return (csModified, drivingCourseModified, true)
|
||||
|
@ -175,70 +183,104 @@ function increaseCoastingSection(csOriginal::CharacteristicSection, drivingCours
|
|||
end # function increaseCoastingSection
|
||||
|
||||
|
||||
|
||||
# method 2 with shortening the acceleration by stepsize
|
||||
function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse, settings::Settings, train::Train, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||
#function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse::Vector{Waypoint}, settings::Settings, train::Train, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||
if haskey(csOriginal.behaviorSections, "acceleration") && csOriginal.v_reach>csOriginal.v_entry && csOriginal.v_reach>csOriginal.v_exit
|
||||
# instead of calculating the new final velocity of the acceleration phase with the step sizes for the different step variables, the velocity of the point before the last will be the new v_reach
|
||||
# because it it easier at the moment (TODO)
|
||||
lastIdOfOldAccelerationSection=get(csOriginal.behaviorSections, "acceleration", BehaviorSection()).waypoints[end]
|
||||
accelerationReduction=drivingCourse[lastIdOfOldAccelerationSection].Δv # with step size it would be accelerationReduction=settings.stepSize
|
||||
if haskey(csOriginal.behaviorSections, "acceleration") && csOriginal.v_reach > csOriginal.v_entry && csOriginal.v_reach > csOriginal.v_exit
|
||||
accelerationSection=BehaviorSection(get(csOriginal.behaviorSections, "acceleration", BehaviorSection()))
|
||||
if drivingCourse[accelerationSection.waypoints[end]-1].v < csOriginal.v_exit
|
||||
return (CharacteristicSection(), [], false)
|
||||
# TODO: or calculate a new acceleration phase with v_exit as v_reach? it will be very short, shorter than the step size.
|
||||
end
|
||||
|
||||
while accelerationReduction>=drivingCourse[lastIdOfOldAccelerationSection].Δv/100 # will be done once and repeated twice with smaller accelerationReduction unless t_recoveryAvailable>=(csModified.t_total-csOriginal.t_total) && 0.0<(csModified.t_total-csOriginal.t_total) -> see below at the end of the while loop
|
||||
# copying csOriginal to csModified
|
||||
csModified=CharacteristicSection(csOriginal.id, csOriginal.s_total, csOriginal.s_start, csOriginal.s_end, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_reach, csOriginal.v_entry, csOriginal.v_exit, csOriginal.f_Rp, Dict{String, BehaviorSection}())
|
||||
if haskey(csOriginal.behaviorSections, "starting")
|
||||
startingSection=BehaviorSection(get(csOriginal.behaviorSections, "starting", BehaviorSection()))
|
||||
merge!(csModified.behaviorSections, Dict("starting"=>startingSection))
|
||||
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "starting", BehaviorSection()).E_total
|
||||
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "starting", BehaviorSection()).t_total
|
||||
# copy csOriginal to csModified
|
||||
csModified=CharacteristicSection(csOriginal.id, csOriginal.s_total, csOriginal.s_start, csOriginal.s_end, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_reach, csOriginal.v_entry, csOriginal.v_exit, csOriginal.f_Rp, Dict{String, BehaviorSection}())
|
||||
|
||||
if haskey(csOriginal.behaviorSections, "starting")
|
||||
startingSection=BehaviorSection(get(csOriginal.behaviorSections, "starting", BehaviorSection()))
|
||||
merge!(csModified.behaviorSections, Dict("starting"=>startingSection))
|
||||
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "starting", BehaviorSection()).E_total
|
||||
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "starting", BehaviorSection()).t_total
|
||||
end
|
||||
|
||||
#accelerationSection=BehaviorSection(get(csOriginal.behaviorSections, "acceleration", BehaviorSection()))
|
||||
|
||||
if length(accelerationSection.waypoints) > 2
|
||||
if haskey(csOriginal.behaviorSections, "cruisingBeforeAcceleration")
|
||||
cruisingBeforeAccelerationSection=BehaviorSection(get(csOriginal.behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()))
|
||||
merge!(csModified.behaviorSections, Dict("cruisingBeforeAcceleration"=>cruisingBeforeAccelerationSection))
|
||||
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()).E_total
|
||||
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()).t_total
|
||||
end
|
||||
|
||||
# creating a drivingCourse for the characteristic section
|
||||
# remove the last acceleration waypoint
|
||||
pop!(accelerationSection.waypoints)
|
||||
|
||||
accelerationSection.v_exit=drivingCourse[accelerationSection.waypoints[end]].v # exit speed (in m/s)
|
||||
accelerationSection.s_end=drivingCourse[accelerationSection.waypoints[end]].s # last position (in m)
|
||||
accelerationSection.s_total=accelerationSection.s_end-accelerationSection.s_start # total length (in m)
|
||||
accelerationSection.t_total=drivingCourse[accelerationSection.waypoints[end]].t-drivingCourse[accelerationSection.waypoints[1]].t # total running time (in s)
|
||||
accelerationSection.E_total=drivingCourse[accelerationSection.waypoints[end]].E-drivingCourse[accelerationSection.waypoints[1]].E # total energy consumption (in Ws)
|
||||
|
||||
merge!(csModified.behaviorSections, Dict("acceleration"=>accelerationSection))
|
||||
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "acceleration", BehaviorSection()).E_total
|
||||
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "acceleration", BehaviorSection()).t_total
|
||||
|
||||
energySavingStartId=accelerationSection.waypoints[end]
|
||||
else
|
||||
# The acceleration section is only one step. This step is removed and if ther ist a cruisingBeforeAcceleration section it will be combined with the new cruising section.
|
||||
energySavingStartId=get(csOriginal.behaviorSections, "cruisingBeforeAcceleration", get(csOriginal.behaviorSections, "acceleration", BehaviorSection())).waypoints[1]
|
||||
end
|
||||
|
||||
drivingCourseModified=Vector{Waypoint}()
|
||||
for i in 1:energySavingStartId
|
||||
# tried to insert copy on 15.07.2021 push!(drivingCourseModified, copy(drivingCourse[i])) # List of waypoints till the start of energy saving
|
||||
push!(drivingCourseModified, Waypoint(drivingCourse[i])) # List of waypoints till the start of energy saving
|
||||
# TODO: should v_reach be reduced or is it enough to pop the waypoints?
|
||||
# characteristicSection.v_reach=drivingCourse[end].v # setting v_reach to the last waypoints velocity which is the highest reachable value in this characteristic section
|
||||
|
||||
# copy the drivingCourse till the beginning of energy saving
|
||||
drivingCourseModified=Vector{Waypoint}()
|
||||
for i in 1:energySavingStartId
|
||||
push!(drivingCourseModified, Waypoint(drivingCourse[i])) # List of waypoints till the start of energy saving
|
||||
end
|
||||
|
||||
#s_braking=max(0.0, ceil((csModified.v_exit^2-csModified.v_reach^2)/2/train.a_braking, digits=approximationLevel)) # ceil is used to be sure that the train stops at s_end in spite of rounding errors
|
||||
s_braking=max(0.0, ceil((csModified.v_exit^2-drivingCourseModified[end].v^2)/2/train.a_braking, digits=approximationLevel)) # ceil is used to be sure that the train stops at s_end in spite of rounding errors
|
||||
s_cruising=csModified.s_end-drivingCourseModified[end].s-s_braking
|
||||
|
||||
if s_cruising >0.001
|
||||
(csModified, drivingCourseModified)=addCruisingPhase!(csModified, drivingCourseModified, s_cruising, settings, train, allCSs, "cruising")
|
||||
end #if
|
||||
|
||||
# s_brakingAfterCruising=ceil((csModified.v_exit^2-drivingCourseModified[end].v^2)/2/train.a_braking, digits=10) # TODO: check if s_braking and s_brakingAfterCruising are really always the same
|
||||
if drivingCourseModified[end].v>csModified.v_exit
|
||||
#(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings.massModel, train, allCSs)
|
||||
(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings, train, allCSs)
|
||||
elseif drivingCourseModified[end].s<csModified.s_end
|
||||
if (csModified.s_end-drivingCourseModified[end].s)>0.001
|
||||
# if (csModified.s_end-drivingCourseModified[end].s)>10^(-approximationLevel)
|
||||
# println("INFO: The end of new CS",csModified.id," is not reached while saving energy with lowering v_reach.")
|
||||
# println(" Therefore the calculation of this method can not continue for this CS.")
|
||||
return (CharacteristicSection(), [], false)
|
||||
end
|
||||
println("WARNING: The end of new CS",csModified.id," is not reached while saving energy with lowering v_reach.")
|
||||
println(" Therefore s=",drivingCourseModified[end].s," will be set s_end=",csModified.s_end," because the difference is only ",csModified.s_end-drivingCourseModified[end].s," m.")
|
||||
println(" v=",drivingCourseModified[end].v," m/s v_exit=",csOriginal.v_exit ," m/s")
|
||||
|
||||
csModified.v_reach=max(csModified.v_entry, csModified.v_exit, csOriginal.v_reach-accelerationReduction)
|
||||
drivingCourseModified[end].s=csModified.s_end # rounding up to s_end
|
||||
end #if
|
||||
|
||||
# calculation of the new and now shorter acceleration section
|
||||
if drivingCourseModified[end].v<csModified.v_reach
|
||||
(csModified, drivingCourseModified)=addAccelerationPhase!(csModified, drivingCourseModified, settings, train, allCSs)
|
||||
end #if
|
||||
# TODO: instead of copying the drivingCourse till the start of acceleration and calculating the acceleration again till the point before the last it would be possible to copy the drivingCouse until this point. Then it would not be necessary to calculate the accelerationPhase again. But then it is difficult to reduce accelerationReduction.
|
||||
if t_recoveryAvailable>=(csModified.t_total-csOriginal.t_total)
|
||||
return (csModified, drivingCourseModified, true)
|
||||
else # time loss is to high. so there is no energy saving modification for this CS with the available recovery time
|
||||
# 09/06 old: else # time loss is to high and the CS has to be calculated again with larger acceleration section (so with a smaller reduction of the acceleration section)
|
||||
# 09/06 old: accelerationReduction=min(accelerationReduction/10, csModified.v_reach-csModified.v_entry, csModified.v_reach-csModified.v_exit)
|
||||
# TODO: just return false or take smaller steps?
|
||||
|
||||
s_braking=max(0.0, ceil((csModified.v_exit^2-csModified.v_reach^2)/2/train.a_braking, digits=10)) # ceil is used to be sure that the train stops at s_end in spite of rounding errors
|
||||
s_cruising=csModified.s_end-drivingCourseModified[end].s-s_braking
|
||||
return (CharacteristicSection(), [], false)
|
||||
end
|
||||
|
||||
if s_cruising >0.001
|
||||
(csModified, drivingCourseModified)=addCruisingPhase!(csModified, drivingCourseModified, s_cruising, settings, train, allCSs, "cruising")
|
||||
end #if
|
||||
|
||||
# s_brakingAfterCruising=ceil((csModified.v_exit^2-drivingCourseModified[end].v^2)/2/train.a_braking, digits=10) # TODO: check if s_braking and s_brakingAfterCruising are really always the same
|
||||
if drivingCourseModified[end].v>csModified.v_exit
|
||||
(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings.massModel, train, allCSs)
|
||||
elseif drivingCourseModified[end].s<csModified.s_end
|
||||
if (csModified.s_end-drivingCourseModified[end].s)>0.001
|
||||
println("WARNING: The end of new CS",csModified.id," is not reached while saving energy with lowering v_reach.")
|
||||
println(" Therefore s=",drivingCourseModified[end].s," will be set s_end=",csModified.s_end," because the difference is only ",csModified.s_end-drivingCourseModified[end].s," m.")
|
||||
end
|
||||
drivingCourseModified[end].s=csModified.s_end # rounding up to s_end
|
||||
end #if
|
||||
|
||||
if t_recoveryAvailable>=(csModified.t_total-csOriginal.t_total)
|
||||
return (csModified, drivingCourseModified, true)
|
||||
else # time loss is to high and the CS has to be calculated again with larger acceleration section (so with a smaller reduction of the acceleration section)
|
||||
accelerationReduction=min(accelerationReduction/10, csModified.v_reach-csModified.v_entry, csModified.v_reach-csModified.v_exit)
|
||||
end
|
||||
end #while
|
||||
|
||||
# there is no energy saving modification for this CS with the available recovery time
|
||||
return (CharacteristicSection(), [], false)
|
||||
# 09/06 old: end #while
|
||||
#
|
||||
# 09/06 old: # there is no energy saving modification for this CS with the available recovery time
|
||||
# 09/06 old: return (CharacteristicSection(), [], false)
|
||||
|
||||
else
|
||||
# there is no energy saving modification for this CS because v_reach can not be lowered below v_entry or v_exit or because there is no acceleration section that can be transformed into a cruising section
|
||||
|
@ -248,16 +290,18 @@ end # function decreaseMaximumVelocity
|
|||
|
||||
# combination of method 1 and method 2
|
||||
function combineEnergySavingMethods(csOriginal::CharacteristicSection, drivingCourse::Vector{Waypoint}, settings::Settings, train::Train, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||
if haskey(csOriginal.behaviorSections, "acceleration") && (haskey(csOriginal.behaviorSections, "braking") || haskey(csOriginal.behaviorSections, "coasting")) && csOriginal.v_reach>csOriginal.v_entry && csOriginal.v_reach>csOriginal.v_exit
|
||||
# if haskey(csOriginal.behaviorSections, "acceleration") && (haskey(csOriginal.behaviorSections, "braking") || haskey(csOriginal.behaviorSections, "coasting")) && csOriginal.v_reach>csOriginal.v_entry && csOriginal.v_reach>csOriginal.v_exit
|
||||
if haskey(csOriginal.behaviorSections, "acceleration") && (haskey(csOriginal.behaviorSections, "braking") || haskey(csOriginal.behaviorSections, "coasting")) && drivingCourse[get(csOriginal.behaviorSections, "acceleration", BehaviorSection()).waypoints[end]].v > max(csOriginal.v_entry, csOriginal.v_exit)
|
||||
csCombined=CharacteristicSection(csOriginal)
|
||||
drivingCourseCombined=Vector{Waypoint}()
|
||||
for i in 1:length(drivingCourse)
|
||||
# tried to insert copy on 15.07.2021 push!(drivingCourseCombined, copy(drivingCourse[i]))
|
||||
# TODO: tried to insert copy on 15.07.2021 push!(drivingCourseCombined, copy(drivingCourse[i]))
|
||||
push!(drivingCourseCombined, Waypoint(drivingCourse[i]))
|
||||
end
|
||||
ΔE=0.0 # saved energy (in Ws)
|
||||
Δt=0.0 # time loss (in s)
|
||||
while (Δt<t_recoveryAvailable && ΔE<=0.0)
|
||||
#while (Δt<t_recoveryAvailable && ΔE<=0.0)
|
||||
while (Δt<t_recoveryAvailable && (Δt<=0.0 || ΔE<=0.0)) #ΔE<=0.0)
|
||||
(csCombined, drivingCourseCombined, newMaximumVelocity)=decreaseMaximumVelocity(csCombined, drivingCourseCombined, settings, train, allCSs, t_recoveryAvailable)
|
||||
if newMaximumVelocity
|
||||
ΔE=csOriginal.E_total-csCombined.E_total # saved energy (in Ws)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -9,6 +9,8 @@ using .EnergySaving
|
|||
|
||||
export simulateMinimumRunningTime!, simulateMinimumEnergyConsumption
|
||||
|
||||
approximationLevel = 6 # TODO: define it in TrainRun and give it to each function?
|
||||
|
||||
function simulateMinimumRunningTime!(movingSection::MovingSection, settings::Settings, train::Train)
|
||||
# simulate a train run focussing on using the minimum possible running time
|
||||
startingPoint=Waypoint()
|
||||
|
@ -17,11 +19,12 @@ function simulateMinimumRunningTime!(movingSection::MovingSection, settings::Set
|
|||
drivingCourse=[startingPoint] # List of waypoints
|
||||
|
||||
for csId in 1:length(movingSection.characteristicSections)
|
||||
# println("CS",csId)
|
||||
# check if the CS has a cruising section
|
||||
s_starting=get(movingSection.characteristicSections[csId].behaviorSections, "starting", BehaviorSection()).s_total
|
||||
s_cruisingBeforeAcceleration=get(movingSection.characteristicSections[csId].behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()).s_total
|
||||
s_acceleration=get(movingSection.characteristicSections[csId].behaviorSections, "acceleration", BehaviorSection()).s_total
|
||||
s_braking=max(0.0, ceil((movingSection.characteristicSections[csId].v_exit^2-movingSection.characteristicSections[csId].v_reach^2)/2/train.a_braking, digits=10)) # ceil is used to be sure that the train stops at s_end in spite of rounding errors
|
||||
s_braking=max(0.0, ceil((movingSection.characteristicSections[csId].v_exit^2-movingSection.characteristicSections[csId].v_reach^2)/2/train.a_braking, digits=approximationLevel)) # ceil is used to be sure that the train stops at s_end in spite of rounding errors
|
||||
|
||||
# calculate the cruising sections length
|
||||
s_cruising=movingSection.characteristicSections[csId].s_total-s_starting-s_cruisingBeforeAcceleration-s_acceleration-s_braking
|
||||
|
@ -34,12 +37,15 @@ function simulateMinimumRunningTime!(movingSection::MovingSection, settings::Set
|
|||
movingSection.characteristicSections[csId].E_total=0.0
|
||||
movingSection.characteristicSections[csId].t_total=0.0
|
||||
|
||||
|
||||
if s_cruisingBeforeAcceleration == movingSection.characteristicSections[csId].s_total
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruisingBeforeAcceleration, settings, train, movingSection.characteristicSections, "cruising")
|
||||
# 09/06 "cruising" is used in EnergySaving and not cruisingBeforeAcceleration (movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruisingBeforeAcceleration, settings, train, movingSection.characteristicSections, "cruisingBeforeAcceleration")
|
||||
# 09/06 TODO: thought about using "cruising" because it is used in EnergySaving and not cruisingBeforeAcceleration (movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruisingBeforeAcceleration, settings, train, movingSection.characteristicSections, "cruising")
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruisingBeforeAcceleration, settings, train, movingSection.characteristicSections, "cruisingBeforeAcceleration")
|
||||
elseif s_cruising == movingSection.characteristicSections[csId].s_total
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruising, settings, train, movingSection.characteristicSections, "cruising")
|
||||
elseif s_cruising > 0.01 # if the cruising section is longer than 1 cm (because of rounding issues not >0.0)
|
||||
elseif s_cruising > 0.0 || s_braking == 0.0
|
||||
# 09/21 elseif s_cruising > 0.0
|
||||
# 09/21 elseif s_cruising > 0.01 # if the cruising section is longer than 1 cm (because of rounding issues not >0.0)
|
||||
if drivingCourse[end].v < movingSection.characteristicSections[csId].v_reach
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addAccelerationPhase!(movingSection.characteristicSections[csId], drivingCourse, settings, train, movingSection.characteristicSections)
|
||||
end #if
|
||||
|
@ -50,38 +56,43 @@ function simulateMinimumRunningTime!(movingSection::MovingSection, settings::Set
|
|||
println(" and v=",drivingCourse[end].v," v_reach=",movingSection.characteristicSections[csId].v_reach," v_exit=",movingSection.characteristicSections[csId].v_exit)
|
||||
end
|
||||
|
||||
s_braking=max(0.0, ceil((movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=10)) # ceil is used to be sure that the train stops at s_end in spite of rounding errors
|
||||
s_braking=max(0.0, ceil((movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=approximationLevel)) # ceil is used to be sure that the train stops at s_end in spite of rounding errors
|
||||
s_cruising=movingSection.characteristicSections[csId].s_end-drivingCourse[end].s-s_braking
|
||||
|
||||
if s_cruising > 0.0
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruising, settings, train, movingSection.characteristicSections, "cruising")
|
||||
end
|
||||
else
|
||||
if movingSection.characteristicSections[csId].v_entry < movingSection.characteristicSections[csId].v_reach
|
||||
|
||||
if movingSection.characteristicSections[csId].v_entry < movingSection.characteristicSections[csId].v_reach || s_acceleration > 0.0 # or instead of " || s_acceleration > 0.0" use "v_entry <= v_reach" or "v_i <= v_reach"
|
||||
# 09/09 old (not sufficient for steep gradients): if movingSection.characteristicSections[csId].v_entry < movingSection.characteristicSections[csId].v_reach
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addAccelerationPhaseUntilBraking!(movingSection.characteristicSections[csId], drivingCourse, settings, train, movingSection.characteristicSections)
|
||||
end #if
|
||||
end #if
|
||||
|
||||
|
||||
s_braking=max(0.0, ceil((movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=10)) # ceil is used to be sure that the train stops at s_end in spite of rounding errors
|
||||
s_braking=max(0.0, ceil((movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/train.a_braking, digits=approximationLevel)) # ceil is used to be sure that the train stops at s_end in spite of rounding errors
|
||||
|
||||
if drivingCourse[end].v > movingSection.characteristicSections[csId].v_exit
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addBrakingPhase!(movingSection.characteristicSections[csId], drivingCourse, settings.massModel, train, movingSection.characteristicSections)
|
||||
#(movingSection.characteristicSections[csId], drivingCourse)=addBrakingPhase!(movingSection.characteristicSections[csId], drivingCourse, settings.massModel, train, movingSection.characteristicSections)
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addBrakingPhase!(movingSection.characteristicSections[csId], drivingCourse, settings, train, movingSection.characteristicSections)
|
||||
end #if
|
||||
|
||||
#= 09/20 old and should never be used:
|
||||
if drivingCourse[end].s < movingSection.characteristicSections[csId].s_end
|
||||
if haskey(movingSection.characteristicSections[csId].behaviorSections, "cruising")
|
||||
println("INFO: A second cruising section has been added to CS ", csId," from s=",drivingCourse[end].s," to s_end=",movingSection.characteristicSections[csId].s_end)
|
||||
end
|
||||
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruising, settings, train, movingSection.characteristicSections, "cruising")
|
||||
end
|
||||
end =#
|
||||
end #for
|
||||
|
||||
# calculate the last waypoints resiting forces
|
||||
drivingCourse[end]=Waypoint(calculateForces!(drivingCourse[end], train, settings.massModel, movingSection.characteristicSections, "braking"))
|
||||
|
||||
movingSection.t_total=drivingCourse[end].t # total running time (in s)
|
||||
movingSection.E_total=drivingCourse[end].E # total energy consumption (in Ws)
|
||||
|
||||
# TODO: calculate some values of the last waypoint
|
||||
|
||||
return (movingSection, drivingCourse)
|
||||
end #function simulateMinimumRunningTime
|
||||
|
||||
|
@ -90,6 +101,8 @@ function simulateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Movin
|
|||
# simulate a train run focussing on using the minimum possible energy consumption
|
||||
# booleans for choosing which methods are used for saving energy
|
||||
doMethod1=true
|
||||
#doMethod1=false
|
||||
#doMethod2=false
|
||||
doMethod2=true
|
||||
doCombinationOfMethods=true
|
||||
#doCombinationOfMethods=false
|
||||
|
@ -141,8 +154,57 @@ function simulateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Movin
|
|||
csIdMax=0
|
||||
typeMax="none"
|
||||
(energySavingModificationsWithMaximumSpeed, ratioMax, csIdMax, typeMax) = findBestModification(energySavingModificationsWithMaximumSpeed, ratioMax, csIdMax, typeMax, movingSectionOriginal.t_recoveryAvailable)
|
||||
# 09/14 Three if cases for testing:
|
||||
#= if length(movingSectionOriginal.energySavingModifications)==895 && ratioMax>0.0
|
||||
println("")
|
||||
println("typeMax=",typeMax)
|
||||
println("ratioMax=",ratioMax)
|
||||
println("csIdMax=",csIdMax)
|
||||
println("---")
|
||||
|
||||
|
||||
println("type=",energySavingModificationsWithMaximumSpeed[csIdMax].type)
|
||||
println(" csId=",energySavingModificationsWithMaximumSpeed[csIdMax].csId)
|
||||
println(" ΔE=",energySavingModificationsWithMaximumSpeed[csIdMax].ΔE)
|
||||
println(" Δt=",energySavingModificationsWithMaximumSpeed[csIdMax].Δt)
|
||||
println(" ratio=",energySavingModificationsWithMaximumSpeed[csIdMax].ratio)
|
||||
println(" DC-length=",length(energySavingModificationsWithMaximumSpeed[csIdMax].drivingCourseModified))
|
||||
end
|
||||
=#
|
||||
(energySavingModificationsWithCoasting, ratioMax, csIdMax, typeMax) = findBestModification(energySavingModificationsWithCoasting, ratioMax, csIdMax, typeMax, movingSectionOriginal.t_recoveryAvailable)
|
||||
#= if length(movingSectionOriginal.energySavingModifications)==895 && ratioMax>0.0
|
||||
println("typeMax=",typeMax)
|
||||
println("ratioMax=",ratioMax)
|
||||
println("csIdMax=",csIdMax)
|
||||
println("---")
|
||||
|
||||
|
||||
println("type=",energySavingModificationsWithCoasting[csIdMax].type)
|
||||
println(" csId=",energySavingModificationsWithCoasting[csIdMax].csId)
|
||||
println(" ΔE=",energySavingModificationsWithCoasting[csIdMax].ΔE)
|
||||
println(" Δt=",energySavingModificationsWithCoasting[csIdMax].Δt)
|
||||
println(" ratio=",energySavingModificationsWithCoasting[csIdMax].ratio)
|
||||
println(" DC-length=",length(energySavingModificationsWithCoasting[csIdMax].drivingCourseModified))
|
||||
end
|
||||
|
||||
=#
|
||||
(energySavingModificationsWithCombination, ratioMax, csIdMax, typeMax) = findBestModification(energySavingModificationsWithCombination, ratioMax, csIdMax, typeMax, movingSectionOriginal.t_recoveryAvailable)
|
||||
#= if length(movingSectionOriginal.energySavingModifications)==895 && ratioMax>0.0
|
||||
println("typeMax=",typeMax)
|
||||
println("ratioMax=",ratioMax)
|
||||
println("csIdMax=",csIdMax)
|
||||
println("---")
|
||||
|
||||
|
||||
println("type=",energySavingModificationsWithCombination[csIdMax].type)
|
||||
println(" csId=",energySavingModificationsWithCombination[csIdMax].csId)
|
||||
println(" ΔE=",energySavingModificationsWithCombination[csIdMax].ΔE)
|
||||
println(" Δt=",energySavingModificationsWithCombination[csIdMax].Δt)
|
||||
println(" ratio=",energySavingModificationsWithCombination[csIdMax].ratio)
|
||||
println(" DC-length=",length(energySavingModificationsWithCombination[csIdMax].drivingCourseModified))
|
||||
end
|
||||
=#
|
||||
|
||||
|
||||
# select the most efficient modification and update the original characteristicSection, drivingCourse and movingSection
|
||||
# in case none of the modifications has a ratio>0 stop the calculation
|
||||
|
@ -151,10 +213,13 @@ function simulateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Movin
|
|||
elseif typeMax=="increasing coasting"
|
||||
# println("Energy saving modification number ",length(movingSectionOriginal.energySavingModifications)+1," (coasting) in CS ",csIdMax ," Δt=",energySavingModificationsWithCoasting[csIdMax].Δt," ΔE=", energySavingModificationsWithCoasting[csIdMax].ΔE," t_recoveryAvailable=", movingSectionOriginal.t_recoveryAvailable-energySavingModificationsWithCoasting[csIdMax].Δt)
|
||||
push!(movingSectionOriginal.energySavingModifications, energySavingModificationsWithCoasting[csIdMax])
|
||||
# println("Nr. ",length(movingSectionOriginal.energySavingModifications),": typeMax=increasing coasting")
|
||||
elseif typeMax=="decreasing maximum velocity"
|
||||
push!(movingSectionOriginal.energySavingModifications, energySavingModificationsWithMaximumSpeed[csIdMax])
|
||||
# println("Nr. ",length(movingSectionOriginal.energySavingModifications),": typeMax=decreasing maximum velocity")
|
||||
elseif typeMax=="combination of energy saving methods"
|
||||
push!(movingSectionOriginal.energySavingModifications, energySavingModificationsWithCombination[csIdMax])
|
||||
# println("Nr. ",length(movingSectionOriginal.energySavingModifications),": typeMax=combination of energy saving methods")
|
||||
end #if
|
||||
|
||||
movingSectionOriginal.t_recoveryAvailable = movingSectionOriginal.t_recoveryAvailable - movingSectionOriginal.energySavingModifications[end].Δt
|
||||
|
@ -174,6 +239,27 @@ function simulateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Movin
|
|||
# end
|
||||
# end # for testing
|
||||
|
||||
# for testing 09/09
|
||||
if length(drivingCourseNew) == 0
|
||||
#= println("typeMax=",typeMax)
|
||||
println("ratioMax=",ratioMax)
|
||||
println("csIdMax=",csIdMax)
|
||||
println("---")
|
||||
|
||||
|
||||
println("type=",energySavingModificationsWithCombination[csIdMax].type)
|
||||
println(" csId=",energySavingModificationsWithCombination[csIdMax].csId)
|
||||
println(" ΔE=",energySavingModificationsWithCombination[csIdMax].ΔE)
|
||||
println(" Δt=",energySavingModificationsWithCombination[csIdMax].Δt)
|
||||
println(" ratio=",energySavingModificationsWithCombination[csIdMax].ratio)
|
||||
println(" DC-length=",length(energySavingModificationsWithCombination[csIdMax].drivingCourseModified))
|
||||
=#
|
||||
println("---")
|
||||
println("energySavingModificationsWithCoasting:",length(energySavingModificationsWithCoasting[csIdMax].drivingCourseModified))
|
||||
println("energySavingModificationsWithMaximumSpeed:",length(energySavingModificationsWithMaximumSpeed[csIdMax].drivingCourseModified))
|
||||
println("energySavingModificationsWithCombination:",length(energySavingModificationsWithCombination[csIdMax].drivingCourseModified))
|
||||
end
|
||||
|
||||
#fill up the rest of the driving course with information from the original course
|
||||
drivingCourseNew[end].F_T=drivingCourseOriginal[lastIdOfSelectedCsOriginal].F_T
|
||||
drivingCourseNew[end].F_Rt=drivingCourseOriginal[lastIdOfSelectedCsOriginal].F_Rt
|
||||
|
@ -245,8 +331,8 @@ function simulateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Movin
|
|||
end #if doCombinationOfMethods
|
||||
end # while
|
||||
|
||||
# TODO: calculate some values of the last waypoint
|
||||
# println("t_recoveryAvailable=",movingSectionOriginal.t_recoveryAvailable)
|
||||
|
||||
println("t_recoveryAvailable=",movingSectionOriginal.t_recoveryAvailable)
|
||||
return (movingSectionOriginal, drivingCourseOriginal)
|
||||
end #function simulateMinimumEnergyConsumption
|
||||
|
||||
|
|
Loading…
Reference in New Issue