Merge functions addAccelerationSection! and addAccelerationSectionUntilBraking!

development
Max Kannenberg 2022-02-23 01:19:19 +01:00
parent 9081b61903
commit 29c4ec0d5b
5 changed files with 125 additions and 48 deletions

View File

@ -1,9 +1,16 @@
#!/usr/bin/env julia
# -*- coding: UTF-8 -*-
# __julia-version__ = 1.7.2
# __author__ = "Max Kannenberg"
# __copyright__ = "2020-2022"
# __license__ = "ISC"
module Behavior module Behavior
include("./DrivingDynamics.jl") include("./DrivingDynamics.jl")
using .DrivingDynamics using .DrivingDynamics
export addAccelerationSection!, addAccelerationSectionUntilBraking!, addCruisingSection!, addCoastingSectionUntilBraking!, addBrakingSection!, addBrakingSectionInOneStep!, addStandstill!, export addAccelerationSection!, addCruisingSection!, addCoastingSection!, addBrakingSection!, addStandstill!,
# addBrakingSectionInOneStep! is not used in the current version of the tool # addBrakingSectionInOneStep! is not used in the current version of the tool
calculateForces!, createDataPoint, calculateForces!, createDataPoint,
@ -234,7 +241,7 @@ function getNextPointOfInterest(pointsOfInterest::Vector{Real}, s::Real)
return POI return POI
end end
end end
error("ERROR in getNextPointOfInterest: There is no POI higher than s.") error("ERROR in getNextPointOfInterest: There is no POI higher than s=",s," m.")
end #function getNextPointOfInterest end #function getNextPointOfInterest
## This function calculates the data points of the breakFree section. ## This function calculates the data points of the breakFree section.
@ -242,7 +249,7 @@ end #function getNextPointOfInterest
# Info: currently the values of the breakFree section will be calculated like in the acceleration section # Info: currently the values of the breakFree section will be calculated like in the acceleration section
function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}) function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict})
if settings[:stepVariable] == "v in m/s" if settings[:stepVariable] == "v in m/s"
println("WARNING: ! ! ! TrainRun doesn't work reliably for the step variable v. Therefore v should not be used ! ! !") println("WARNING: ! ! ! TrainRun.jl doesn't work reliably for the step variable v. Therefore v should not be used ! ! !")
end end
if drivingCourse[end][:v]==0.0 && drivingCourse[end][:s]<CS[:s_exit] if drivingCourse[end][:v]==0.0 && drivingCourse[end][:s]<CS[:s_exit]
BS = createBehaviorSection("breakFree", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) BS = createBehaviorSection("breakFree", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
@ -283,6 +290,7 @@ function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::D
pop!(BS[:dataPoints]) pop!(BS[:dataPoints])
else else
drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s]
brokenFree = true brokenFree = true
break#free break#free
end end
@ -318,7 +326,7 @@ end #function addBreakFreeSection!
## This function calculates the data points of the acceleration section. ## This function calculates the data points of the acceleration section.
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the acceleration section # Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the acceleration section
function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}) function addAccelerationSectionWithoutBraking!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict})
#=if drivingCourse would also be part of movingSectiong: function addAccelerationSection!(movingSection::Dict, csId::Integer, settings::Dict, train::Dict) #=if drivingCourse would also be part of movingSectiong: function addAccelerationSection!(movingSection::Dict, csId::Integer, settings::Dict, train::Dict)
CSs = movingSection[:characteristicSections] CSs = movingSection[:characteristicSections]
CS = CSs[csId] CS = CSs[csId]
@ -413,6 +421,7 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
# delete last data point for recalculating the last step with reduced step size # delete last data point for recalculating the last step with reduced step size
pop!(drivingCourse) pop!(drivingCourse)
pop!(BS[:dataPoints]) pop!(BS[:dataPoints])
else # if the level of approximation is reached else # if the level of approximation is reached
if drivingCourse[end][:v] <= 0.0 if drivingCourse[end][:v] <= 0.0
# push!(BS[:dataPoints], drivingCourse[end][:i]) # push!(BS[:dataPoints], drivingCourse[end][:i])
@ -427,6 +436,7 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
elseif drivingCourse[end][:s] > nextPointOfInterest elseif drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s]
elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R] elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R]
tractionSurplus = false tractionSurplus = false
@ -466,11 +476,17 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
end end
return (CS, drivingCourse) return (CS, drivingCourse)
end #function addAccelerationSection! end #function addAccelerationSectionWithoutBraking!
## This function calculates the data points of the acceleration section. ## This function calculates the data points of the acceleration section.
function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}) function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, ignoreBraking::Bool)
#function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict})
#=if drivingCourse would also be part of movingSectiong: function addAccelerationSection!(movingSection::Dict, csId::Integer, settings::Dict, train::Dict)
CSs = movingSection[:characteristicSections]
CS = CSs[csId]
drivingCourse = movingSection[:drivingCourse]=#
if drivingCourse[end][:v] == 0.0 if drivingCourse[end][:v] == 0.0
(CS, drivingCourse) = addBreakFreeSection!(CS, drivingCourse, settings, train, CSs) (CS, drivingCourse) = addBreakFreeSection!(CS, drivingCourse, settings, train, CSs)
end #if end #if
@ -481,6 +497,10 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
calculateForces!(drivingCourse[end], CSs, CS[:id], "acceleration", train, settings[:massModel]) calculateForces!(drivingCourse[end], CSs, CS[:id], "acceleration", train, settings[:massModel])
end end
if ignoreBraking
s_braking = 0.0
end
# if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept # if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
formerSpeedLimits = detectFormerSpeedLimits(CSs, CS[:id], drivingCourse[end], train[:length]) formerSpeedLimits = detectFormerSpeedLimits(CSs, CS[:id], drivingCourse[end], train[:length])
@ -496,11 +516,14 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
brakingStartReached = false brakingStartReached = false
while !targetSpeedReached && !trainAtEnd && tractionSurplus && !brakingStartReached while !targetSpeedReached && !trainAtEnd && tractionSurplus && !brakingStartReached
currentStepSize=settings[:stepSize] # initialize the step size that can be reduced near intersections currentStepSize = settings[:stepSize] # initialize the step size that can be reduced near intersections
nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s]) nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) if !ignoreBraking
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
end
while drivingCourse[end][:v] < CS[:v_peak] && drivingCourse[end][:s] +s_braking < CS[:s_exit] && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:F_T] > drivingCourse[end][:F_R] # as long as s_i + s_braking < s_CSexit while drivingCourse[end][:v] < CS[:v_peak] && drivingCourse[end][:s] +s_braking < CS[:s_exit] && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:F_T] > drivingCourse[end][:F_R] # as long as s_i + s_braking < s_CSexit
# acceleration (in m/s^2): # acceleration (in m/s^2):
@ -517,8 +540,12 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
return (CS, drivingCourse) return (CS, drivingCourse)
end end
end end
# TODO: do the following that was done here in addAccelerationSection_without_Braking! currentStepSize = settings[:stepSize] # initialize the step size that can be reduced near intersections
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel]) calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) if !ignoreBraking
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
end
end #while end #while
# check which limit was reached and adjust the currentStepSize for the next cycle # check which limit was reached and adjust the currentStepSize for the next cycle
@ -541,7 +568,7 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
end end
elseif drivingCourse[end][:v] > CS[:v_peak] elseif drivingCourse[end][:v] > CS[:v_peak]
if settings[:stepVariable]=="v in m/s" if settings[:stepVariable] == "v in m/s"
currentStepSize = CS[:v_peak]-drivingCourse[end-1][:v] currentStepSize = CS[:v_peak]-drivingCourse[end-1][:v]
else else
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
@ -559,17 +586,17 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
break break
else else
error("ERROR at acceleration until braking section: With the step variable ",settings[:stepVariable]," the while loop will be left although v<v_peak and s<s_exit in CS",CS[:id]," with s=" ,drivingCourse[end][:s]," m and v=",drivingCourse[end][:v]," m/s") error("ERROR at acceleration section: With the step variable ",settings[:stepVariable]," the while loop will be left although v<v_peak and s<s_exit in CS",CS[:id]," with s=" ,drivingCourse[end][:s]," m and v=",drivingCourse[end][:v]," m/s")
end end
# delete last data point for recalculating the last step with reduced step size # delete last data point for recalculating the last step with reduced step size
pop!(drivingCourse) pop!(drivingCourse)
pop!(BS[:dataPoints]) pop!(BS[:dataPoints])
else # if the level of approximation is reached else # if the level of approximation is reached
if drivingCourse[end][:v]<=0.0 if drivingCourse[end][:v] <= 0.0
# 01/21 should not be needed anymore with diminishing. # 01/21 should not be needed anymore with diminishing.
# push!(BS[:dataPoints], drivingCourse[end][:i]) # push!(BS[:dataPoints], drivingCourse[end][:i])
error("ERROR: The train stops during the acceleration section in CS",CS[:id]," because the tractive effort is lower than the resistant forces.", error("ERROR: The train stops during the acceleration section in CS",CS[:id]," between the positions ",drivingCourse[end-1][:s]," m and ",drivingCourse[end][:s]," m because the tractive effort is lower than the resistant forces.",
" Before the stop the last point has the values s=",drivingCourse[end-1][:s]," m v=",drivingCourse[end-1][:v]," m/s a=",drivingCourse[end-1][:a]," m/s^2", " Before the stop the last point has the values s=",drivingCourse[end-1][:s]," m v=",drivingCourse[end-1][:v]," m/s a=",drivingCourse[end-1][:a]," m/s^2",
" F_T=",drivingCourse[end-1][:F_T]," N R_traction=",drivingCourse[end-1][:R_traction]," N R_wagons=",drivingCourse[end-1][:R_wagons]," N R_path=",drivingCourse[end-1][:R_path]," N.") " F_T=",drivingCourse[end-1][:F_T]," N R_traction=",drivingCourse[end-1][:R_traction]," N R_wagons=",drivingCourse[end-1][:R_wagons]," N R_path=",drivingCourse[end-1][:R_path]," N.")
@ -585,6 +612,7 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
elseif drivingCourse[end][:s] > nextPointOfInterest elseif drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s]
elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R] elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R]
tractionSurplus = false tractionSurplus = false
@ -611,16 +639,16 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
:E => drivingCourse[end][:E] - drivingCourse[BS[:dataPoints][1]][:E], # total energy consumption (in Ws) :E => drivingCourse[end][:E] - drivingCourse[BS[:dataPoints][1]][:E], # total energy consumption (in Ws)
:v_exit => drivingCourse[end][:v])) # exit speed (in m/s))) :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[: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 running on a path with high resistances
CS[:t] = CS[:t] + BS[:t] # total running time (in s) CS[:t] = CS[:t] + BS[:t] # total running time (in s)
CS[:E] = CS[:E] + BS[:E] # total energy consumption (in Ws) CS[:E] = CS[:E] + BS[:E] # total energy consumption (in Ws)
merge!(CS[:behaviorSections], Dict(:acceleration=>BS)) merge!(CS[:behaviorSections], Dict(:acceleration => BS))
end end
end end
return (CS, drivingCourse) return (CS, drivingCourse)
end #function addAccelerationSectionUntilBraking! end #function addAccelerationSection!
## This function calculates the data points of the cruising section. ## This function calculates the data points of the cruising section.
@ -729,6 +757,7 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
else # if the level of approximation is reached else # if the level of approximation is reached
if drivingCourse[end][:s] > nextPointOfInterest if drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s]
elseif drivingCourse[end][:s] > BS[:s_entry]+s_cruising elseif drivingCourse[end][:s] > BS[:s_entry]+s_cruising
trainAtEnd = true trainAtEnd = true
if BS[:type] != "clearing" if BS[:type] != "clearing"
@ -834,7 +863,7 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R] elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
elseif drivingCourse[end][:s] + s_braking > CS[:s_exit] elseif s_braking > 0.0 && drivingCourse[end][:s] + s_braking > CS[:s_exit]
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
elseif drivingCourse[end][:s] > nextPointOfInterest elseif drivingCourse[end][:s] > nextPointOfInterest
@ -873,13 +902,14 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
" Before the stop the last point has the values s=",drivingCourse[end-1][:s]," m v=",drivingCourse[end-1][:v]," m/s a=",drivingCourse[end-1][:a]," m/s^2", " Before the stop the last point has the values s=",drivingCourse[end-1][:s]," m v=",drivingCourse[end-1][:v]," m/s a=",drivingCourse[end-1][:a]," m/s^2",
" F_T=",drivingCourse[end-1][:F_T]," N R_traction=",drivingCourse[end-1][:R_traction]," N R_wagons=",drivingCourse[end-1][:R_wagons]," N R_path=",drivingCourse[end-1][:R_path]," N.") " F_T=",drivingCourse[end-1][:F_T]," N R_traction=",drivingCourse[end-1][:R_traction]," N R_wagons=",drivingCourse[end-1][:R_wagons]," N R_path=",drivingCourse[end-1][:R_path]," N.")
elseif drivingCourse[end][:s] + s_braking > CS[:s_exit] elseif s_braking > 0.0 && drivingCourse[end][:s] + s_braking > CS[:s_exit]
brakingStartReached = true brakingStartReached = true
pop!(drivingCourse) pop!(drivingCourse)
pop!(BS[:dataPoints]) pop!(BS[:dataPoints])
elseif drivingCourse[end][:s] > nextPointOfInterest elseif drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s]
elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R] elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
tractionSurplus = true tractionSurplus = true
@ -888,6 +918,11 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
else else
end #if end #if
# TODO is it possible to put this into to the if-fork?
if drivingCourse[end][:s] == CS[:s_exit]
trainAtEnd = true
end
end #if end #if
end #for end #for
end #while end #while
@ -913,7 +948,7 @@ end #function addDiminishingSection!
## This function calculates the data points of the coasting section. ## This function calculates the data points of the coasting section.
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the coasting section # Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the coasting section
function addCoastingSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}) function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, 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 ## 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[:length]) #formerSpeedLimits = detectFormerSpeedLimits(CSs, CS[:id], drivingCourse[end], train[:length])
@ -967,7 +1002,7 @@ function addCoastingSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict},
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
end end
elseif drivingCourse[end][:v] > CS[:v_peak] elseif drivingCourse[end][:v] > CS[:v_peak]
if settings[:stepVariable]=="v in m/s" if settings[:stepVariable] == "v in m/s"
currentStepSize = CS[:v_peak] - drivingCourse[end-1][:v] currentStepSize = CS[:v_peak] - drivingCourse[end-1][:v]
else else
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
@ -1021,6 +1056,7 @@ function addCoastingSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict},
elseif drivingCourse[end][:s] > nextPointOfInterest elseif drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s]
else else
end end
@ -1042,7 +1078,7 @@ function addCoastingSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict},
end end
return (CS, drivingCourse) return (CS, drivingCourse)
end #function addCoastingSectionUntilBraking! end #function addCoastingSection!
## This function calculates the data points of the braking section. (standard braking section with only two data points) ## This function calculates the data points of the braking section. (standard braking section with only two data points)
@ -1227,6 +1263,7 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic
break break
elseif drivingCourse[end][:s] > nextPointOfInterest elseif drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s]
break break
elseif drivingCourse[end][:v] == CS[:v_exit] && drivingCourse[end][:s] == CS[:s_exit] elseif drivingCourse[end][:v] == CS[:v_exit] && drivingCourse[end][:s] == CS[:s_exit]
targetSpeedReached = true targetSpeedReached = true

View File

@ -1,3 +1,10 @@
#!/usr/bin/env julia
# -*- coding: UTF-8 -*-
# __julia-version__ = 1.7.2
# __author__ = "Max Kannenberg"
# __copyright__ = "2020-2022"
# __license__ = "ISC"
module Characteristics module Characteristics
include("./Behavior.jl") include("./Behavior.jl")
@ -121,7 +128,8 @@ function secureAccelerationBehavior!(movingSection::Dict, settings::Dict, train:
accelerationCourse::Vector{Dict} = [startingPoint] # List of data points accelerationCourse::Vector{Dict} = [startingPoint] # List of data points
if CSs[csId][:v_entry] < CSs[csId][:v_peak] if CSs[csId][:v_entry] < CSs[csId][:v_peak]
(CSs[csId], accelerationCourse) = addAccelerationSection!(CSs[csId], accelerationCourse, settings, train, CSs) # this function changes the accelerationCourse # 02/22 old (CSs[csId], accelerationCourse) = addAccelerationSection!(CSs[csId], accelerationCourse, settings, train, CSs) # this function changes the accelerationCourse
(CSs[csId], accelerationCourse) = addAccelerationSection!(CSs[csId], accelerationCourse, settings, train, CSs, true) # this function changes the accelerationCourse
CSs[csId][:v_peak] = max(CSs[csId][:v_entry], accelerationCourse[end][:v]) CSs[csId][:v_peak] = max(CSs[csId][:v_entry], accelerationCourse[end][:v])
CSs[csId][:v_exit] = min(CSs[csId][:v_exit], CSs[csId][:v_peak], accelerationCourse[end][:v]) 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] else #CSs[csId][:v_entry]==CSs[csId][:v_peak]

View File

@ -1,6 +1,6 @@
#!/usr/bin/env julia #!/usr/bin/env julia
# -*- coding: UTF-8 -*- # -*- coding: UTF-8 -*-
# __julia-version__ = 1.7.0 # __julia-version__ = 1.7.2
# __author__ = "Max Kannenberg" # __author__ = "Max Kannenberg"
# __copyright__ = "2022" # __copyright__ = "2022"
# __license__ = "ISC" # __license__ = "ISC"
@ -53,7 +53,7 @@ calc_ΔW, calc_ΔE,
# export braking information # export braking information
calcBrakingDistance, calcBrakingStartVelocity, calcBrakingAcceleration calcBrakingDistance, calcBrakingStartVelocity, calcBrakingAcceleration
v00 = 100/3.6 # velocity constant (in m/s) v00 = 100/3.6 # velocity factor (in m/s)
g = 9.81 # acceleration due to gravity (in m/s^2) # TODO: should more digits of g be used? g=9,80665 m/s^2 g = 9.81 # acceleration due to gravity (in m/s^2) # TODO: should more digits of g be used? g=9,80665 m/s^2
approximationLevel = 6 # value for approximation to intersections TODO further explanation (e.g. approximationLevel = 3 -> with stepSize 10 m the approximation will be calculated accurate on 10 mm ; 1s -> 1 ms; 1 km/h -> 3.6 mm/s) approximationLevel = 6 # value for approximation to intersections TODO further explanation (e.g. approximationLevel = 3 -> with stepSize 10 m the approximation will be calculated accurate on 10 mm ; 1s -> 1 ms; 1 km/h -> 3.6 mm/s)
@ -199,7 +199,6 @@ function calc_Δv_with_Δt(Δt::Real, a_prev::Real)
# Δt: time step (in s) # Δt: time step (in s)
# a_prev: acceleration from previous data point # a_prev: acceleration from previous data point
# v_prev: velocitiy from previous data point
Δv = Δt * a_prev # step size (in m/s) Δv = Δt * a_prev # step size (in m/s)
return Δv return Δv
end #function calc_Δv_with_Δt end #function calc_Δv_with_Δt

View File

@ -1,3 +1,10 @@
#!/usr/bin/env julia
# -*- coding: UTF-8 -*-
# __julia-version__ = 1.7.2
# __author__ = "Max Kannenberg"
# __copyright__ = "2020-2022"
# __license__ = "ISC"
# INFO: EnergySaving should not be used because it is not completed yet. It was used to show the possibility of calculating different operation modes. # INFO: EnergySaving should not be used because it is not completed yet. It was used to show the possibility of calculating different operation modes.
# TODO: It has to be optimized so that each ernergy saving method is working individually for every train on every path. # TODO: It has to be optimized so that each ernergy saving method is working individually for every train on every path.
@ -24,22 +31,22 @@ approximationLevel = 6 # value for approximation to intersections
## functions for calculating the operation mode for the minimum energy consumption ## functions for calculating the operation mode for the minimum energy consumption
# calculate the train run for operation mode "minimum energy consumption" # calculate the train run for operation mode "minimum energy consumption"
function addOperationModeEnergySaving!(summarizedDict::Dict) function addOperationModeEnergySaving!(accumulatedDict::Dict)
if summarizedDict[:settings][:operationModeMinimumEnergyConsumption] == true if accumulatedDict[:settings][:operationModeMinimumEnergyConsumption] == true
movingSectionMinimumRunningTime = summarizedDict[:movingSectionMinimumRunningTime] movingSectionMinimumRunningTime = accumulatedDict[:movingSectionMinimumRunningTime]
drivingCourseMinimumRunningTime = summarizedDict[:drivingCourseMinimumRunningTime] drivingCourseMinimumRunningTime = accumulatedDict[:drivingCourseMinimumRunningTime]
settings = summarizedDict[:settings] settings = accumulatedDict[:settings]
train = summarizedDict[:train] train = accumulatedDict[:train]
(movingSectionMinimumEnergyConsumption, drivingCourseMinimumEnergyConsumption)=calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime, drivingCourseMinimumRunningTime, settings, train) (movingSectionMinimumEnergyConsumption, drivingCourseMinimumEnergyConsumption)=calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime, drivingCourseMinimumRunningTime, settings, train)
println("The driving course for the lowest energy consumption has been calculated.") println("The driving course for the lowest energy consumption has been calculated.")
# summarize data and create an output dictionary # accumulate data and create an output dictionary
merge!(summarizedDict, Dict(:movingSectionMinimumEnergyConsumption => movingSectionMinimumEnergyConsumption, :drivingCourseMinimumEnergyConsumption => drivingCourseMinimumEnergyConsumption)) merge!(accumulatedDict, Dict(:movingSectionMinimumEnergyConsumption => movingSectionMinimumEnergyConsumption, :drivingCourseMinimumEnergyConsumption => drivingCourseMinimumEnergyConsumption))
else else
println("No output for minimum energy consumption has been demanded and so none will be calculated.") println("No output for minimum energy consumption has been demanded and so none will be calculated.")
end #if end #if
return summarizedDict return accumulatedDict
end #function addOperationModeEnergySaving! end #function addOperationModeEnergySaving!
function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict, drivingCourseMinimumRunningTime::Vector{Dict}, settings::Dict, train::Dict) function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict, drivingCourseMinimumRunningTime::Vector{Dict}, settings::Dict, train::Dict)
@ -603,7 +610,7 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
end end
# calculate the coasting phase until the point the train needs to brake # calculate the coasting phase until the point the train needs to brake
(csModified, drivingCourseModified)=addCoastingSectionUntilBraking!(csModified, drivingCourseModified, settings, train, allCSs) (csModified, drivingCourseModified)=addCoastingSection!(csModified, drivingCourseModified, settings, train, allCSs)
if drivingCourseModified[end][:v] < csModified[:v_exit] || drivingCourseModified[end][:s] > csModified[:s_exit] if drivingCourseModified[end][:v] < csModified[:v_exit] || drivingCourseModified[end][:s] > csModified[:s_exit]
# the train reaches v_exit before reaching s_exit. The cruising and coasting sections have to be calculated again with a larger cruising section (so with a smaller reduction of the cruising section) # the train reaches v_exit before reaching s_exit. The cruising and coasting sections have to be calculated again with a larger cruising section (so with a smaller reduction of the cruising section)
@ -737,7 +744,7 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
end end
# calculate the coasting phase until the point the train needs to brake # calculate the coasting phase until the point the train needs to brake
(csModified, drivingCourseModified)=addCoastingSectionUntilBraking!(csModified, drivingCourseModified, settings, train, allCSs) (csModified, drivingCourseModified)=addCoastingSection!(csModified, drivingCourseModified, settings, train, allCSs)
if drivingCourseModified[end][:v] < csModified[:v_exit] || drivingCourseModified[end][:s] > csModified[:s_exit] if drivingCourseModified[end][:v] < csModified[:v_exit] || drivingCourseModified[end][:s] > csModified[:s_exit]
# the train reaches v_exit before reaching s_exit. The cruising and coasting sections have to be calculated again with a larger cruising section (so with a smaller reduction of the cruising section) # the train reaches v_exit before reaching s_exit. The cruising and coasting sections have to be calculated again with a larger cruising section (so with a smaller reduction of the cruising section)
@ -831,7 +838,7 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
drivingCourseModified = copy(drivingCourse[1:energySavingStartId]) # List of data points till the start of energy saving drivingCourseModified = copy(drivingCourse[1:energySavingStartId]) # List of data points till the start of energy saving
# calculate the coasting phase until the point the train needs to brake # calculate the coasting phase until the point the train needs to brake
(csModified, drivingCourseModified)=addCoastingSectionUntilBraking!(csModified, drivingCourseModified, settings, train, allCSs) (csModified, drivingCourseModified)=addCoastingSection!(csModified, drivingCourseModified, settings, train, allCSs)
# calculate the moving phase between coasting and the end of the CS # calculate the moving phase between coasting and the end of the CS
if drivingCourseModified[end][:v] > csModified[:v_exit] if drivingCourseModified[end][:v] > csModified[:v_exit]
@ -961,7 +968,8 @@ function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict
println(" Therefore s=",drivingCourseModified[end][:s]," will be set s_exit=",csModified[:s_exit]," because the difference is only ",csModified[:s_exit]-drivingCourseModified[end][:s]," m.") println(" Therefore s=",drivingCourseModified[end][:s]," will be set s_exit=",csModified[:s_exit]," because the difference is only ",csModified[:s_exit]-drivingCourseModified[end][:s]," m.")
println(" v=",drivingCourseModified[end][:v]," m/s v_exit=",csOriginal[:v_exit] ," m/s") println(" v=",drivingCourseModified[end][:v]," m/s v_exit=",csOriginal[:v_exit] ," m/s")
drivingCourseModified[end][:s]=csModified[:s_exit] # rounding up to s_exit drivingCourseModified[end][:s] = csModified[:s_exit] # rounding up to s_exit
drivingCourseModified[end][:Δs] = drivingCourseModified[end][:s] - drivingCourseModified[end-1][:s]
end #if end #if
if t_recoveryAvailable >= csModified[:t] - csOriginal[:t] if t_recoveryAvailable >= csModified[:t] - csOriginal[:t]

View File

@ -1,3 +1,10 @@
#!/usr/bin/env julia
# -*- coding: UTF-8 -*-
# __julia-version__ = 1.7.2
# __author__ = "Max Kannenberg"
# __copyright__ = "2020-2022"
# __license__ = "ISC"
module TrainRunCalc module TrainRunCalc
# include modules of TrainRunCalc # include modules of TrainRunCalc
@ -34,7 +41,7 @@ todo !!!
""" """
function calculateDrivingDynamics(trainInput::Dict, pathInput::Dict, settingsInput::Dict) function calculateDrivingDynamics(trainInput::Dict, pathInput::Dict, settingsInput::Dict)
# copy Input data for not changing them # copy Input data for not changing them
# TODO: or should they be changed? enormally it would only make it "better" except for settings[:detailOfOutput] == "points of interest" && !haskey(path, :pointsOfInterest) # TODO: or should they be changed? normally it would only make it "better" except for settings[:detailOfOutput] == "points of interest" && !haskey(path, :pointsOfInterest)
train = copy(trainInput) train = copy(trainInput)
path = copy(pathInput) path = copy(pathInput)
settings = copy(settingsInput) settings = copy(settingsInput)
@ -52,7 +59,7 @@ function calculateDrivingDynamics(trainInput::Dict, pathInput::Dict, settingsInp
(movingSection, drivingCourse) = calculateMinimumRunningTime!(movingSection, settings, train) (movingSection, drivingCourse) = calculateMinimumRunningTime!(movingSection, settings, train)
println("The driving course for the shortest running time has been calculated.") println("The driving course for the shortest running time has been calculated.")
# summarize data and create an output dictionary # accumulate data and create an output dictionary
output = createOutputDict(train, settings, path, movingSection, drivingCourse) output = createOutputDict(train, settings, path, movingSection, drivingCourse)
else else
output = Dict() output = Dict()
@ -72,10 +79,22 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
# for CS in CSs # for CS in CSs
for csId in 1:length(CSs) for csId in 1:length(CSs)
# check if the CS has a cruising section
CS = CSs[csId] CS = CSs[csId]
BSs = CS[:behaviorSections] BSs = CS[:behaviorSections]
# for testing:
if drivingCourse[end][:s] != CS[:s_entry]
if haskey(BSs, :cruising)
println("ERROR: In CS", csId," the train run starts at s=",drivingCourse[end][:s]," and not s_entry=",CS[:s_entry])
end
end
if drivingCourse[end][:v] > CS[:v_entry]
if haskey(BSs, :cruising)
println("ERROR: In CS", csId," the train run ends with v=",drivingCourse[end][:v]," and not with v_entry=",CS[:v_entry])
end
end
# check if the CS has a cruising section
s_breakFree = get(BSs, :breakFree, Dict(:length=>0.0))[:length] s_breakFree = get(BSs, :breakFree, Dict(:length=>0.0))[:length]
s_clearing = get(BSs, :clearing, 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_acceleration = get(BSs, :acceleration, Dict(:length=>0.0))[:length]
@ -100,7 +119,7 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
elseif s_cruising > 0.0 || s_braking == 0.0 elseif s_cruising > 0.0 || s_braking == 0.0
if drivingCourse[end][:v] < CS[:v_peak] if drivingCourse[end][:v] < CS[:v_peak]
(CS, drivingCourse) = addAccelerationSection!(CS, drivingCourse, settings, train, CSs) (CS, drivingCourse) = addAccelerationSection!(CS, drivingCourse, settings, train, CSs, false) # TODO or better ignoreBraking = true?
end #if end #if
if CS[:s_exit]-drivingCourse[end][:s]-max(0.0, (CS[:v_exit]^2-drivingCourse[end][:v]^2)/2/train[:a_braking]) < -0.001 # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors if CS[:s_exit]-drivingCourse[end][:s]-max(0.0, (CS[:v_exit]^2-drivingCourse[end][:v]^2)/2/train[:a_braking]) < -0.001 # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
@ -118,7 +137,8 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
else else
if CS[:v_entry] < CS[:v_peak] || s_acceleration > 0.0 # or instead of " || s_acceleration > 0.0" use "v_entry <= v_peak" or "v_i <= v_peak" if CS[:v_entry] < CS[:v_peak] || s_acceleration > 0.0 # or instead of " || s_acceleration > 0.0" use "v_entry <= v_peak" or "v_i <= v_peak"
# 09/09 old (not sufficient for steep gradients): if CS[:v_entry] < CS[:v_peak] # 09/09 old (not sufficient for steep gradients): if CS[:v_entry] < CS[:v_peak]
(CS, drivingCourse)=addAccelerationSectionUntilBraking!(CS, drivingCourse, settings, train, CSs) # old 02/22 (CS, drivingCourse)=addAccelerationSectionUntilBraking!(CS, drivingCourse, settings, train, CSs)
(CS, drivingCourse) = addAccelerationSection!(CS, drivingCourse, settings, train, CSs, false)
end #if end #if
end #if end #if
@ -129,13 +149,18 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
(CS, drivingCourse)=addBrakingSection!(CS, drivingCourse, settings, train, CSs) (CS, drivingCourse)=addBrakingSection!(CS, drivingCourse, settings, train, CSs)
end #if end #if
#= 09/20 old and should never be used: # for testing:
if drivingCourse[end][:s] < CS[:s_exit] if drivingCourse[end][:s] != CS[:s_exit]
if haskey(BSs, :cruising) if haskey(BSs, :cruising)
println("INFO: A second cruising section has been added to CS ", csId," from s=",drivingCourse[end][:s]," to s_exit=",CS[:s_exit]) println("ERROR: In CS", csId," the train run ends at s=",drivingCourse[end][:s]," and not s_exit=",CS[:s_exit])
end end
(CS, drivingCourse)=addCruisingSection!(CS, drivingCourse, s_cruising, settings, train, CSs, "cruising") end
end =# if drivingCourse[end][:v] > CS[:v_exit]
if haskey(BSs, :cruising)
println("ERROR: In CS", csId," the train run ends with v=",drivingCourse[end][:v]," and not with v_exit=",CS[:v_exit])
end
end
end #for end #for
(CSs[end], drivingCourse) = addStandstill!(CSs[end], drivingCourse, settings, train, CSs) (CSs[end], drivingCourse) = addStandstill!(CSs[end], drivingCourse, settings, train, CSs)