Refactor the call for adding breakFree and diminshing sections

development
Max Kannenberg 2022-03-04 02:20:33 +01:00
parent be54089917
commit 1dc6f8345a
4 changed files with 195 additions and 347 deletions

View File

@ -10,7 +10,7 @@ module Behavior
include("./DrivingDynamics.jl") include("./DrivingDynamics.jl")
using .DrivingDynamics using .DrivingDynamics
export addAcceleratingSection!, addCruisingSection!, addCoastingSection!, addBrakingSection!, addStandstill!, export addBreakFreeSection!, addAcceleratingSection!, addCruisingSection!, addDiminishingSection!, 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,
@ -92,13 +92,14 @@ function calculateForces!(dataPoint::Dict, CSs::Vector{Dict}, csId::Integer, bs
dataPoint[:F_R] = dataPoint[:R_train] + dataPoint[:R_path] dataPoint[:F_R] = dataPoint[:R_train] + dataPoint[:R_path]
# calculate tractive effort # calculate tractive effort
if bsType == "accelerating" || bsType == "diminishing" if bsType == "braking" || bsType == "coasting"
dataPoint[:F_T] = calculateTractiveEffort(dataPoint[:v], train[:tractiveEffortVelocityPairs]) dataPoint[:F_T] = 0.0
elseif bsType == "cruising" elseif bsType == "cruising"
dataPoint[:F_T] = min(max(0.0, dataPoint[:F_R]), calculateTractiveEffort(dataPoint[:v], train[:tractiveEffortVelocityPairs])) dataPoint[:F_T] = min(max(0.0, dataPoint[:F_R]), calculateTractiveEffort(dataPoint[:v], train[:tractiveEffortVelocityPairs]))
else else # bsType == "accelerating" || bsType == "diminishing" || 'default'
dataPoint[:F_T] = 0.0 dataPoint[:F_T] = calculateTractiveEffort(dataPoint[:v], train[:tractiveEffortVelocityPairs])
end end
return dataPoint return dataPoint
end #function calculateForces! end #function calculateForces!
@ -168,74 +169,6 @@ function moveAStep(previousPoint::Dict, stepVariable::String, stepSize::Real, cs
end #function moveAStep end #function moveAStep
"""
# if the rear of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
"""
#=
function detectFormerSpeedLimits(CSs::Vector{Dict}, csWithTrainHeadId::Integer, currentPoint::Dict, trainLength::Real)
formerSpeedLimits=[]
if csWithTrainHeadId > 1 && currentPoint[:s] - trainLength < CSs[csWithTrainHeadId][:s_entry]
formerCsId=csWithTrainHeadId-1
while formerCsId > 0 && currentPoint[:s] - trainLength < CSs[formerCsId][:s_exit]
if CSs[formerCsId][:v_limit] < CSs[csWithTrainHeadId][:v_limit] # TODO: is the position of train's rear < movingSection[:s_entry], v_limit of the first CS is used
push!(formerSpeedLimits, [CSs[formerCsId][:s_exit], CSs[formerCsId][:v_limit]])
for i in 1:length(formerSpeedLimits)-1
if formerSpeedLimits[i][2]<=formerSpeedLimits[end][2]
pop!(formerSpeedLimits)
break
end
end
end
formerCsId=formerCsId-1
end
end
return formerSpeedLimits
end # function detectFormerSpeedLimits
function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, formerSpeedLimits, acceleratingSection::Dict)
# TODO: What is the type of formerSpeedLimits? function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, formerSpeedLimits::Array{Array{AbstractFloat,1},1}, acceleratingSection::Dict)
# would work: function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, formerSpeedLimits::Array{Any,1}, acceleratingSection::Dict)
if length(formerSpeedLimits) > 0
# if a former speed limit has been exceeded the accelerating steps of this CS will be removed and a clearing section will be inserted before accelerating
if drivingCourse[end][:v] > formerSpeedLimits[end][2]
while drivingCourse[end][:s] > get(CS[:behaviorSections], :clearing, acceleratingSection)[:s_entry]
pop!(drivingCourse)
end
if haskey(CS[:behaviorSections], :clearing)
CS[:t] = CS[:t]-CS[:behaviorSections][:clearing][:t] # reducing the total running time (in s)
CS[:E] = CS[:E]-CS[:behaviorSections][:clearing][:E] # reducing the total energy consumption (in Ws)
delete!(CS[:behaviorSections], :clearing)
end
# create a (new and longer) clearing section
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
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) = addCruisingSection!(CS, drivingCourse, s_clearing, settings, train, CSs, "clearing")
else
error("ERROR: clearing <=0.0 although it has to be >0.0 in CS ",CS[:id])
end
# 09/22: if drivingCourse[end][:s] < CS[:s_exit]
if drivingCourse[end][:s] < CS[:s_exit] - s_braking
# reset the acceleratingSection
acceleratingSection = createBehaviorSection("accelerating", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
else
return (CS, drivingCourse, formerSpeedLimits, acceleratingSection, 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[:length] >= formerSpeedLimits[end][1]
pop!(formerSpeedLimits)
end
end
return (CS, drivingCourse, formerSpeedLimits, acceleratingSection, false)
end # function considerFormerSpeedLimits!
=#
function considerFormerSpeedLimit!(CS::Dict, drivingCourse::Vector{Dict}, acceleratingSection::Dict, settings::Dict, train::Dict, CSs::Vector{Dict}, currentSpeedLimit::Dict) function considerFormerSpeedLimit!(CS::Dict, drivingCourse::Vector{Dict}, acceleratingSection::Dict, settings::Dict, train::Dict, CSs::Vector{Dict}, currentSpeedLimit::Dict)
# if a former speed limit has been exceeded the accelerating steps of this CS will be removed and a clearing section will be inserted before accelerating # if a former speed limit has been exceeded the accelerating steps of this CS will be removed and a clearing section will be inserted before accelerating
if drivingCourse[end][:v] > currentSpeedLimit[:v] if drivingCourse[end][:v] > currentSpeedLimit[:v]
@ -254,7 +187,7 @@ function considerFormerSpeedLimit!(CS::Dict, drivingCourse::Vector{Dict}, accele
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
s_clearing = min(CS[:s_exit]-drivingCourse[end][:s]-s_braking, currentSpeedLimit[:s_end] - drivingCourse[end][:s]) s_clearing = min(CS[:s_exit]-drivingCourse[end][:s]-s_braking, currentSpeedLimit[:s_end] - drivingCourse[end][:s])
if s_clearing > 0.0 if s_clearing > 0.0
(CS, drivingCourse) = addCruisingSection!(CS, drivingCourse, s_clearing, settings, train, CSs, "clearing") (CS, drivingCourse, brakingStartReached) = addCruisingSection!(CS, drivingCourse, s_clearing, settings, train, CSs, "clearing")
else else
error("ERROR: clearing <=0.0 although it has to be >0.0 in CS ",CS[:id]) error("ERROR: clearing <=0.0 although it has to be >0.0 in CS ",CS[:id])
end end
@ -272,6 +205,9 @@ function considerFormerSpeedLimit!(CS::Dict, drivingCourse::Vector{Dict}, accele
return (CS, drivingCourse, acceleratingSection) return (CS, drivingCourse, acceleratingSection)
end # function considerFormerSpeedLimit! end # function considerFormerSpeedLimit!
"""
# if the rear of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
"""
function getCurrentSpeedLimit(CSs::Vector{Dict}, csWithTrainHeadId::Integer, s::Real, trainLength::Real) function getCurrentSpeedLimit(CSs::Vector{Dict}, csWithTrainHeadId::Integer, s::Real, trainLength::Real)
v_limit = CSs[csWithTrainHeadId][:v_limit] v_limit = CSs[csWithTrainHeadId][:v_limit]
s_exit = CSs[csWithTrainHeadId][:s_exit] s_exit = CSs[csWithTrainHeadId][:s_exit]
@ -301,66 +237,35 @@ end #function getNextPointOfInterest
## This function calculates the data points of the breakFree section. ## This function calculates the data points of the breakFree section.
# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for breakFree if needed. # Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for breakFree if needed.
# Info: currently the values of the breakFree section will be calculated like in the accelerating section # Info: currently the values of the breakFree section will be calculated like in the accelerating 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}, ignoreBraking::Bool)
if settings[:stepVariable] == "v in m/s"
println("WARNING: ! ! ! TrainRun.jl doesn't work reliably for the step variable v. Therefore v should not be used ! ! !")
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])
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
# traction effort and resisting forces (in N): # traction effort and resisting forces (in N)
calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings[:massModel]) # currently the tractive effort is calculated like in the accelerating section calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings[:massModel]) # currently the tractive effort is calculated like in the accelerating section
# acceleration (in m/s^2): # calculate the breakFree section with calculating the accelerating section and just using the first step and removing the rest
drivingCourse[end][:a] = calcAcceleration(drivingCourse[end][:F_T], drivingCourse[end][:F_R], train[:m_train], train[:ξ_train]) try (CS, drivingCourse, brakingStartReached) = addAcceleratingSection!(CS, drivingCourse, settings, train, CSs, false)
if drivingCourse[end][:a]<0.0 catch(acceleratingError)
error("ERROR: a<0 m/s^2 in the breakFree section !") println("This error happened during the break free phase that is using the accelerating function:")
elseif drivingCourse[end][:a] == 0.0 rethrow(acceleratingError)
error("ERROR: a=0 m/s^2 in the breakFree section !")
end end
brokenFree = false # delete every dataPoint except the first two
calculationCycle = 1 while drivingCourse[end][:i] > drivingCourse[BS[:dataPoints][1]][:i] +1
nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s]) pop!(drivingCourse)
while !brokenFree end
# create the next data point
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], settings[:stepSize], CS[:id])) # change the accelerating data to break free
drivingCourse[end-1][:behavior] = BS[:type]
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
push!(BS[:dataPoints], drivingCourse[end][:i]) push!(BS[:dataPoints], drivingCourse[end][:i])
# check if a point of interest was missed # remove the accelerating section from the CS
if drivingCourse[end][:s] > nextPointOfInterest CS[:t] = CS[:t] - get(CS[:behaviorSections], :accelerating, Dict(:t=>0.0))[:t] # total running time (in s)
if settings[:stepVariable] == "s in m" CS[:E] = CS[:E] - get(CS[:behaviorSections], :accelerating, Dict(:E=>0.0))[:E] # total energy consumption (in Ws)
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s] delete!(CS[:behaviorSections], :accelerating)
else
currentStepSize = settings[:stepSize] / 10.0^cycle
end
if calculationCycle <= approximationLevel
calculationCycle = calculationCycle +1
# delete last data point for recalculating the last step with reduced step size
pop!(drivingCourse)
pop!(BS[:dataPoints])
else
drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s]
brokenFree = true
break#free
end
elseif drivingCourse[end][:v] > CS[:v_peak]
if settings[:stepVariable] == "v in m/s"
currentStepSize = CS[:v_peak]-drivingCourse[end-1][:v]
else
currentStepSize = settings[:stepSize] / 10.0^cycle
end
else #if drivingCourse[end][:s] == nextPointOfInterest || drivingCourse[end][:v] == CS[:v_peak]
brokenFree = true
break#free
end #if
end #while
# calculate the accumulated breakFree section information # calculate the accumulated breakFree section information
merge!(BS, Dict(:length => drivingCourse[end][:s] - BS[:s_entry], # total length (in m) merge!(BS, Dict(:length => drivingCourse[end][:s] - BS[:s_entry], # total length (in m)
@ -386,33 +291,30 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
CS = CSs[csId] CS = CSs[csId]
drivingCourse = movingSection[:drivingCourse]=# drivingCourse = movingSection[:drivingCourse]=#
if drivingCourse[end][:v] == 0.0
(CS, drivingCourse) = addBreakFreeSection!(CS, drivingCourse, settings, train, CSs)
end #if
calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings[:massModel]) calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings[:massModel])
if drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
(CS, drivingCourse) = addDiminishingSection!(CS, drivingCourse, settings, train, CSs)
calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings[:massModel])
end
if ignoreBraking if ignoreBraking
s_braking = 0.0 s_braking = 0.0
else
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
end end
# # if the rear of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept # conditions for the accelerating section
# formerSpeedLimits = detectFormerSpeedLimits(CSs, CS[:id], drivingCourse[end], train[:length])
# conditions for accelerating section
targetSpeedReached = drivingCourse[end][:v] >= CS[:v_peak] targetSpeedReached = drivingCourse[end][:v] >= CS[:v_peak]
trainAtEnd = drivingCourse[end][:s] >= CS[:s_exit] trainAtEnd = drivingCourse[end][:s] >= CS[:s_exit]
tractionSurplus = drivingCourse[end][:F_T] > drivingCourse[end][:F_R] tractionSurplus = drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
if ignoreBraking
s_braking = 0.0
else
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
end
brakingStartReached = drivingCourse[end][:s] +s_braking >= CS[:s_exit]
# use the conditions for the accelerating section # use the conditions for the accelerating section
if !targetSpeedReached && !trainAtEnd && tractionSurplus if !targetSpeedReached && !trainAtEnd && tractionSurplus
BS = createBehaviorSection("accelerating", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) BS = createBehaviorSection("accelerating", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
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])
@ -423,7 +325,8 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
end end
while drivingCourse[end][:v] < CS[:v_peak] && drivingCourse[end][:v] <= currentSpeedLimit[:v] && 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][:v] <= currentSpeedLimit[:v] && !brakingStartReached && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:F_T] > drivingCourse[end][:F_R] # as long as s_i + s_braking < s_CSexit
# 03/02 old: while drivingCourse[end][:v] < CS[:v_peak] && drivingCourse[end][:v] <= currentSpeedLimit[:v] && 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
# 02/23 old: 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 # 02/23 old: 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
if drivingCourse[end][:s] >= currentSpeedLimit[:s_end] if drivingCourse[end][:s] >= currentSpeedLimit[:s_end]
# could be asked after creating an data point. This way here prevents even a minimal exceedance of speed limit will be noticed. On the other hand the train cruises possibly a little to long # could be asked after creating an data point. This way here prevents even a minimal exceedance of speed limit will be noticed. On the other hand the train cruises possibly a little to long
@ -439,37 +342,31 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
push!(BS[:dataPoints], drivingCourse[end][:i]) push!(BS[:dataPoints], drivingCourse[end][:i])
# if length(formerSpeedLimits) > 0 # If the rear 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, BS, endOfCsReached) = considerFormerSpeedLimits!(CS, drivingCourse, settings, train, CSs, formerSpeedLimits, BS)
# if endOfCsReached
# return (CS, drivingCourse)
# end
# # TODO: do the following that was done here in addAcceleratingSection_without_Braking! ? currentStepSize = settings[:stepSize] # initialize the step size that can be reduced near intersections
# end
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel]) calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
if !ignoreBraking if !ignoreBraking
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
brakingStartReached = drivingCourse[end][:s] +s_braking >= CS[:s_exit]
end end
end #while end #while
if CS[:id]==0
testFlag = true
else
testFlag = false # for testing
end
# 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
if cycle < approximationLevel+1 if cycle < approximationLevel+1
if drivingCourse[end][:v] <= 0.0 if drivingCourse[end][:F_T] <= drivingCourse[end][:F_R]
#println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," <= 0.0") # for testing testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: F_T=", drivingCourse[end][:F_T]," <= F_R=",drivingCourse[end][:F_R]) # for testing
currentStepSize = settings[:stepSize] / 10.0^cycle
# TODO 01/21 should not be needed anymore with diminishing.
elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R]
#println("in CS",CS[:id]," accelerating cycle",cycle," case: F_T=", drivingCourse[end][:F_T]," <= F_R=",drivingCourse[end][:F_R]) # for testing
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
elseif s_braking > 0.0 && drivingCourse[end][:s] + s_braking > CS[:s_exit] elseif s_braking > 0.0 && drivingCourse[end][:s] + s_braking > CS[:s_exit]
#println("in CS",CS[:id]," accelerating cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],",+",s_braking," = ",drivingCourse[end][:s] +s_braking," > s_exit=",CS[:s_exit]) # for testing testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],",+",s_braking," = ",drivingCourse[end][:s] +s_braking," > s_exit=",CS[:s_exit]) # for testing
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
elseif drivingCourse[end][:s] > nextPointOfInterest elseif drivingCourse[end][:s] > nextPointOfInterest
#println("in CS",CS[:id]," accelerating cycle",cycle," case: s=", drivingCourse[end][:s]," > nextPOI=",nextPointOfInterest) # for testing testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: s=", drivingCourse[end][:s]," > nextPOI=",nextPointOfInterest) # for testing
if settings[:stepVariable] == "s in m" if settings[:stepVariable] == "s in m"
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s] currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
else else
@ -477,7 +374,7 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
end end
elseif drivingCourse[end][:v] > CS[:v_peak] elseif drivingCourse[end][:v] > CS[:v_peak]
#println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," > v_peak=",CS[:v_peak]) # for testing testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," > v_peak=",CS[:v_peak]) # for testing
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
@ -485,34 +382,26 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
end end
elseif drivingCourse[end][:v] > currentSpeedLimit[:v] elseif drivingCourse[end][:v] > currentSpeedLimit[:v]
#if drivingCourse[end][:s] < currentSpeedLimit[:s_end] testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," > v_limitCurrent=",currentSpeedLimit[:v]) # for testing
#if drivingCourse[end][:s] - train[:length] < currentSpeedLimit[:s_end]
#println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," > v_limitCurrent=",currentSpeedLimit[:v]) # for testing
(CS, drivingCourse, BS) = considerFormerSpeedLimit!(CS, drivingCourse, BS, settings, train, CSs, currentSpeedLimit) (CS, drivingCourse, BS) = considerFormerSpeedLimit!(CS, drivingCourse, BS, settings, train, CSs, currentSpeedLimit)
#end
break break
# TODO: think about alternative: handle the the position where the rear of the train leaves a CS similar to a POI. Then it will be calculated exactly and even a minimal exceedance of speed limit will be noticed # TODO: think about alternative: handle the the position where the rear of the train leaves a CS similar to a POI. Then it will be calculated exactly and even a minimal exceedance of speed limit will be noticed
elseif drivingCourse[end][:s] +s_braking == CS[:s_exit] elseif drivingCourse[end][:s] +s_braking == CS[:s_exit]
#println("in CS",CS[:id]," accelerating cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],",+",s_braking," = ",drivingCourse[end][:s] +s_braking," == s_exit=",CS[:s_exit]) # for testing testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],",+",s_braking," = ",drivingCourse[end][:s] +s_braking," == s_exit=",CS[:s_exit]) # for testing
brakingStartReached = true brakingStartReached = true
if s_braking == 0.0 if s_braking == 0.0
trainAtEnd = true trainAtEnd = true
end end
break break
elseif drivingCourse[end][:s] == CS[:s_exit]
#println("in CS",CS[:id]," accelerating cycle",cycle," case: s=", drivingCourse[end][:s]," == s_exit=",CS[:s_exit]) # for testing
trainAtEnd = true
break
elseif drivingCourse[end][:v] == CS[:v_peak] elseif drivingCourse[end][:v] == CS[:v_peak]
#println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," == v_peak=",CS[:v_peak]) # for testing testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," == v_peak=",CS[:v_peak]) # for testing
targetSpeedReached = true targetSpeedReached = true
break break
elseif drivingCourse[end][:s] == nextPointOfInterest elseif drivingCourse[end][:s] == nextPointOfInterest
#println("in CS",CS[:id]," accelerating cycle",cycle," case: s=", drivingCourse[end][:s]," == nextPOI=",nextPointOfInterest) # for testing testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: s=", drivingCourse[end][:s]," == nextPOI=",nextPointOfInterest) # for testing
break break
else else
@ -525,23 +414,20 @@ function addAcceleratingSection!(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])
brakingStartReached = false
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] > CS[:v_peak]
# 01/21 should not be needed anymore with diminishing. testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," > v_peak=",CS[:v_peak]) # for testing
# push!(BS[:dataPoints], drivingCourse[end][:i])
error("ERROR: The train stops during the accelerating 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",
" 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]
targetSpeedReached = true targetSpeedReached = true
pop!(drivingCourse) pop!(drivingCourse)
pop!(BS[:dataPoints]) pop!(BS[:dataPoints])
brakingStartReached = false
elseif drivingCourse[end][:s] + s_braking > CS[:s_exit] elseif drivingCourse[end][:s] + s_braking > CS[:s_exit]
if s_braking > 0.0 testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],",+",s_braking," = ",drivingCourse[end][:s] +s_braking," > s_exit=",CS[:s_exit]) # for testing
brakingStartReached = true brakingStartReached = true
if s_braking > 0.0
pop!(drivingCourse) pop!(drivingCourse)
pop!(BS[:dataPoints]) pop!(BS[:dataPoints])
else else
@ -550,22 +436,24 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
end end
elseif drivingCourse[end][:s] > nextPointOfInterest elseif drivingCourse[end][:s] > nextPointOfInterest
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: F_T=", drivingCourse[end][:s]," > nextPointOfInterest",nextPointOfInterest) # for testing
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] 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]
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: F_T=", drivingCourse[end][:F_T]," <= F_R=",drivingCourse[end][:F_R]) # for testing
tractionSurplus = false tractionSurplus = false
(CS, drivingCourse) = addDiminishingSection!(CS, drivingCourse, settings, train, CSs)
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
elseif drivingCourse[end][:v] > currentSpeedLimit[:v] elseif drivingCourse[end][:v] > currentSpeedLimit[:v]
#if drivingCourse[end][:s] - train[:length] < currentSpeedLimit[:s_end] testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," > v_limitCurrent=",currentSpeedLimit[:v]) # for testing
(CS, drivingCourse, BS) = considerFormerSpeedLimit!(CS, drivingCourse, BS, settings, train, CSs, currentSpeedLimit) (CS, drivingCourse, BS) = considerFormerSpeedLimit!(CS, drivingCourse, BS, settings, train, CSs, currentSpeedLimit)
# end
# TODO: think about alternative: handle the the position where the rear of the train leaves a CS similar to a POI. Then it will be calculated exactly and the train start accelerating immediately and not only at the next data point. # TODO: think about alternative: handle the the position where the rear of the train leaves a CS similar to a POI. Then it will be calculated exactly and the train start accelerating immediately and not only at the next data point.
else else
if drivingCourse[end][:s] + s_braking == CS[:s_exit]
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," else case and there: s +s_braking=", drivingCourse[end][:s],",+",s_braking," = ",drivingCourse[end][:s] +s_braking," > s_exit=",CS[:s_exit]) # for testing
brakingStartReached = true
end
end end
# TODO is it possible to put this into to the if-fork? # TODO is it possible to put this into to the if-fork?
@ -592,11 +480,11 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
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(:accelerating => BS)) mergeBehaviorSection!(CS[:behaviorSections], BS)
end end
end end
return (CS, drivingCourse) return (CS, drivingCourse, brakingStartReached)
end #function addAcceleratingSection! end #function addAcceleratingSection!
@ -606,18 +494,11 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
# traction effort and resisting forces (in N) # traction effort and resisting forces (in N)
calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel]) calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
if drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
(CS, drivingCourse) = addDiminishingSection!(CS, drivingCourse, settings, train, CSs)
# 01/08 old with DataPoint as struct: old drivingCourse[end] = DataPoint(calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel]))
calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
s_cruising = CS[:s_exit] - drivingCourse[end][:s] - s_braking # may not work with EnergySaving when decreasing the length of cruising and adding coasting brakingStartReached = drivingCourse[end][:s] + s_braking >= CS[:s_exit]
# s_cruising = max(0.0, CS[:s_exit] - drivingCourse[end][:s] - s_braking) # may not work with EnergySaving when decreasing the length of cruising and adding coasting
# 02/25 old: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] && !brakingStartReached && drivingCourse[end][:F_T] >= drivingCourse[end][:F_R]
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] # old: 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]
BS = createBehaviorSection(cruisingType, drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) BS = createBehaviorSection(cruisingType, drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
@ -712,10 +593,6 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
break break
elseif drivingCourse[end][:F_T] < drivingCourse[end][:F_R] elseif drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
tractionSurplus = false tractionSurplus = false
(CS, drivingCourse) = addDiminishingSection!(CS, drivingCourse, settings, train, CSs)
calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
# s_cruising=max(0.0, s_cruising-get(CS[:behaviorSections], :diminishing, Dict(length=>0.0))[:length])
else else
@ -733,10 +610,9 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
# calculate the remaining cruising way # calculate the remaining cruising way
#s_cruisingRemaining=BS[:s_entry] + s_cruising-drivingCourse[end][:s] #s_cruisingRemaining=BS[:s_entry] + s_cruising-drivingCourse[end][:s]
s_cruisingRemaining = nextPointOfInterest - drivingCourse[end][:s] s_cruisingRemaining = min(nextPointOfInterest -drivingCourse[end][:s], BS[:s_entry] +s_cruising -drivingCourse[end][:s])
# create the next data point # create the next data point
# 02/18 old push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", s_cruisingRemaining, CS[:id]))
push!(drivingCourse, moveAStep(drivingCourse[end], "s in m", s_cruisingRemaining, CS[:id])) push!(drivingCourse, moveAStep(drivingCourse[end], "s in m", s_cruisingRemaining, CS[:id]))
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
push!(BS[:dataPoints], drivingCourse[end][:i]) push!(BS[:dataPoints], drivingCourse[end][:i])
@ -744,6 +620,10 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel]) calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
end #while end #while
# TODO: realize this better inside the upper loops?
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
brakingStartReached = drivingCourse[end][:s] + s_braking >= CS[:s_exit]
# calculate the accumulated cruising section information # calculate the accumulated cruising section information
merge!(BS, Dict(:length => drivingCourse[end][:s] - BS[:s_entry], # total length (in m) merge!(BS, Dict(:length => drivingCourse[end][:s] - BS[:s_entry], # total length (in m)
:s_exit => drivingCourse[end][:s], # last position (in m) :s_exit => drivingCourse[end][:s], # last position (in m)
@ -754,10 +634,10 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
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(Symbol(BS[:type]) => BS)) mergeBehaviorSection!(CS[:behaviorSections], BS)
end # else: return the characteristic section without a cruising section end # else: return the characteristic section without a cruising section
return (CS, drivingCourse) return (CS, drivingCourse, brakingStartReached)
end #function addCruisingSection! end #function addCruisingSection!
@ -769,11 +649,13 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
trainAtEnd = drivingCourse[end][:s] >= CS[:s_exit] trainAtEnd = drivingCourse[end][:s] >= CS[:s_exit]
tractionSurplus = drivingCourse[end][:F_T] > drivingCourse[end][:F_R] tractionSurplus = drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
brakingStartReached = drivingCourse[end][:s] + s_braking >= CS[:s_exit]
# use the conditions for the diminishing section # use the conditions for the diminishing section
if !tractionSurplus && !targetSpeedReached && !trainAtEnd if !tractionSurplus && !targetSpeedReached && !trainAtEnd
BS = createBehaviorSection("diminishing", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) BS = createBehaviorSection("diminishing", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
brakingStartReached = false
while !tractionSurplus && !targetSpeedReached && !trainAtEnd && !brakingStartReached while !tractionSurplus && !targetSpeedReached && !trainAtEnd && !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
@ -781,7 +663,9 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
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]) s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
while drivingCourse[end][:F_T] <= drivingCourse[end][:F_R] && drivingCourse[end][:s] + s_braking < CS[:s_exit] && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:v]>0.0 # as long as s_i + s_braking < s_end #while drivingCourse[end][:F_T] <= drivingCourse[end][:F_R] && drivingCourse[end][:s] + s_braking < CS[:s_exit] && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:v]>0.0 # as long as s_i + s_braking < s_end
#while drivingCourse[end][:F_T] < drivingCourse[end][:F_R] && drivingCourse[end][:s] + s_braking < CS[:s_exit] && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:v]>0.0 # as long as s_i + s_braking < s_end
while drivingCourse[end][:F_T] < drivingCourse[end][:F_R] && !brakingStartReached && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:v]>0.0 # as long as s_i + s_braking < s_end
# acceleration (in m/s^2): # acceleration (in m/s^2):
drivingCourse[end][:a] = calcAcceleration(drivingCourse[end][:F_T], drivingCourse[end][:F_R], train[:m_train], train[:ξ_train]) drivingCourse[end][:a] = calcAcceleration(drivingCourse[end][:F_T], drivingCourse[end][:F_R], train[:m_train], train[:ξ_train])
@ -791,9 +675,16 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
push!(BS[:dataPoints], drivingCourse[end][:i]) push!(BS[:dataPoints], drivingCourse[end][:i])
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
brakingStartReached = drivingCourse[end][:s] +s_braking >= CS[:s_exit]
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel]) calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
end #while end #while
if CS[:id]==0
testFlag = true
else
testFlag = false # for testing
end
# 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
if cycle < approximationLevel+1 if cycle < approximationLevel+1
if drivingCourse[end][:v] < 0.0 if drivingCourse[end][:v] < 0.0
@ -803,15 +694,15 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
end end
elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R] elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
#println("in CS",CS[:id]," diminishing cycle",cycle," case: F_T=", drivingCourse[end][:F_T]," > F_R=",drivingCourse[end][:F_R]) # for testing testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: F_T=", drivingCourse[end][:F_T]," > F_R=",drivingCourse[end][:F_R]) # for testing
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
elseif s_braking > 0.0 && drivingCourse[end][:s] + s_braking > CS[:s_exit] elseif s_braking > 0.0 && drivingCourse[end][:s] + s_braking > CS[:s_exit]
#println("in CS",CS[:id]," diminishing cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],"+",s_braking," = ",drivingCourse[end][:s] +s_braking," > s_exit=",CS[:s_exit]) # for testing testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],"+",s_braking," = ",drivingCourse[end][:s] +s_braking," > s_exit=",CS[:s_exit]) # for testing
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
elseif drivingCourse[end][:s] > nextPointOfInterest elseif drivingCourse[end][:s] > nextPointOfInterest
#println("in CS",CS[:id]," diminishing cycle",cycle," case: s=", drivingCourse[end][:s]," > nextPOI=",nextPointOfInterest) # for testing testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: s=", drivingCourse[end][:s]," > nextPOI=",nextPointOfInterest) # for testing
if settings[:stepVariable] == "s in m" if settings[:stepVariable] == "s in m"
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s] currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
else else
@ -819,12 +710,17 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
end end
elseif drivingCourse[end][:s] + s_braking == CS[:s_exit] elseif drivingCourse[end][:s] + s_braking == CS[:s_exit]
#println("in CS",CS[:id]," diminishing cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],"+",s_braking," = ",drivingCourse[end][:s] +s_braking," == s_exit=",CS[:s_exit]) # for testing testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],"+",s_braking," = ",drivingCourse[end][:s] +s_braking," == s_exit=",CS[:s_exit]) # for testing
brakingStartReached = true brakingStartReached = true
break break
elseif drivingCourse[end][:s] == nextPointOfInterest elseif drivingCourse[end][:s] == nextPointOfInterest
#println("in CS",CS[:id]," diminishing cycle",cycle," case: s=", drivingCourse[end][:s]," == nextPOI=",nextPointOfInterest) # for testing testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: s=", drivingCourse[end][:s]," == nextPOI=",nextPointOfInterest) # for testing
break
elseif drivingCourse[end][:F_T] == drivingCourse[end][:F_R]
testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: F_T=", drivingCourse[end][:F_T]," == F_R=",drivingCourse[end][:F_R]) # for testing
tractionSurplus = true
break break
elseif drivingCourse[end][:v] == 0.0 elseif drivingCourse[end][:v] == 0.0
@ -839,9 +735,11 @@ function addDiminishingSection!(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])
brakingStartReached = false
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
testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: v=", drivingCourse[end][:v]," <= 0.0") # for testing
targetSpeedReached = true targetSpeedReached = true
# push!(BS[: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.", error("ERROR: The train stops during diminishing run in CS",CS[:id]," because the maximum tractive effort is lower than the resistant forces.",
@ -849,20 +747,29 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
" 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 s_braking > 0.0 && drivingCourse[end][:s] + s_braking > CS[:s_exit] elseif s_braking > 0.0 && drivingCourse[end][:s] + s_braking > CS[:s_exit]
testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],"+",s_braking," = ",drivingCourse[end][:s] +s_braking," > s_exit=",CS[:s_exit]) # for testing
brakingStartReached = true brakingStartReached = true
pop!(drivingCourse) pop!(drivingCourse)
pop!(BS[:dataPoints]) pop!(BS[:dataPoints])
elseif drivingCourse[end][:s] > nextPointOfInterest elseif drivingCourse[end][:s] > nextPointOfInterest
testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: s=", drivingCourse[end][:s]," > nextPointOfInterest=",nextPointOfInterest) # for testing
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] 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]
testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: F_T=", drivingCourse[end][:F_T]," >= F_R=", drivingCourse[end][:F_R]) # for testing
tractionSurplus = true tractionSurplus = true
break break
else else
testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: else with v=", drivingCourse[end][:v]," > 0.0 and F_T=", drivingCourse[end][:F_T]," <= F_R=", drivingCourse[end][:F_R]) # for testing
#println(" and s +s_braking=", drivingCourse[end][:s],"+",s_braking," = ",drivingCourse[end][:s] +s_braking," <= s_exit=",CS[:s_exit]) # for testing
#println(" and s=", drivingCourse[end][:s]," <= nextPointOfInterest=",nextPointOfInterest) # for testing
if drivingCourse[end][:s] + s_braking == CS[:s_exit]
brakingStartReached = true
end
end #if end #if
# TODO is it possible to put this into to the if-fork? # TODO is it possible to put this into to the if-fork?
@ -884,11 +791,11 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
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(:diminishing=>BS)) mergeBehaviorSection!(CS[:behaviorSections], BS)
end end
end end
return (CS, drivingCourse) return (CS, drivingCourse, brakingStartReached)
end #function addDiminishingSection! end #function addDiminishingSection!
@ -902,11 +809,13 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Di
targetSpeedReached = drivingCourse[end][:v] <= CS[:v_exit] targetSpeedReached = drivingCourse[end][:v] <= CS[:v_exit]
trainAtEnd = drivingCourse[end][:s] >= CS[:s_exit] trainAtEnd = drivingCourse[end][:s] >= CS[:s_exit]
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
brakingStartReached = drivingCourse[end][:s] + s_braking >= CS[:s_exit]
# use the conditions for the coasting section # use the conditions for the coasting section
if !targetSpeedReached && !trainAtEnd if !targetSpeedReached && !trainAtEnd
BS = createBehaviorSection("coasting", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) BS = createBehaviorSection("coasting", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
brakingStartReached = false
while !targetSpeedReached && !trainAtEnd && !brakingStartReached while !targetSpeedReached && !trainAtEnd && !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
@ -914,7 +823,7 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Di
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]) s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
while drivingCourse[end][:v] > CS[:v_exit] && drivingCourse[end][:v] <= CS[:v_peak] && drivingCourse[end][:s] + s_braking < CS[:s_exit] && drivingCourse[end][:s] < nextPointOfInterest # as long as s_i + s_braking < s_end while drivingCourse[end][:v] > CS[:v_exit] && drivingCourse[end][:v] <= CS[:v_peak] && !brakingStartReached && drivingCourse[end][:s] < nextPointOfInterest # as long as s_i + s_braking < s_end
# traction effort and resisting forces (in N): # traction effort and resisting forces (in N):
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel]) calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
@ -927,6 +836,7 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Di
push!(BS[:dataPoints], drivingCourse[end][:i]) push!(BS[:dataPoints], drivingCourse[end][:i])
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
brakingStartReached = drivingCourse[end][:s] + s_braking >= CS[:s_exit]
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
@ -971,6 +881,7 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Di
# 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])
brakingStartReached = false
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
@ -1004,7 +915,9 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Di
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] drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s]
else else
if drivingCourse[end][:s] + s_braking == CS[:s_exit]
brakingStartReached = true
end
end end
end end
end #for end #for
@ -1023,14 +936,13 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Di
merge!(CS[:behaviorSections], Dict(:coasting=>BS)) merge!(CS[:behaviorSections], Dict(:coasting=>BS))
end end
return (CS, drivingCourse) return (CS, drivingCourse, brakingStartReached)
end #function addCoastingSection! end #function addCoastingSection!
## This function calculates the data points of the braking section. # 09/07 new braking section with more than two data points ## This function calculates the data points of the braking section.
# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for braking if needed. # 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 addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}) function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict})
#function addBrakingSectionStepwise!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict})
# conditions for braking section # conditions for braking section
targetSpeedReached = drivingCourse[end][:v] <= CS[:v_exit] targetSpeedReached = drivingCourse[end][:v] <= CS[:v_exit]
trainAtEnd = drivingCourse[end][:s] >= CS[:s_exit] trainAtEnd = drivingCourse[end][:s] >= CS[:s_exit]
@ -1054,16 +966,12 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic
# TODO or: drivingCourse[end][:a] = calcBrakingAcceleration(drivingCourse[end][:v], CS[:v_exit], CS[:s_exit]-drivingCourse[end][:s]) # TODO or: drivingCourse[end][:a] = calcBrakingAcceleration(drivingCourse[end][:v], CS[:v_exit], CS[:s_exit]-drivingCourse[end][:s])
if settings[:stepVariable] == "s in m" && ((drivingCourse[end][:v]/drivingCourse[end][:a])^2+2*currentStepSize/drivingCourse[end][:a])<0.0 || (drivingCourse[end][:v]^2+2*currentStepSize*drivingCourse[end][:a])<0.0 if settings[:stepVariable] == "s in m" && ((drivingCourse[end][:v]/drivingCourse[end][:a])^2+2*currentStepSize/drivingCourse[end][:a])<0.0 || (drivingCourse[end][:v]^2+2*currentStepSize*drivingCourse[end][:a])<0.0
# targetSpeedReached = true
# create empty data point and set it for the values of s_exit and v_exit # create empty data point and set it for the values of s_exit and v_exit
push!(drivingCourse, createDataPoint()) push!(drivingCourse, createDataPoint())
drivingCourse[end][:i] = drivingCourse[end-1][:i]+1 drivingCourse[end][:i] = drivingCourse[end-1][:i]+1
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
push!(BS[:dataPoints], drivingCourse[end][:i]) push!(BS[:dataPoints], drivingCourse[end][:i])
recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit]) recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
# break
# end
else else
# create the next data point # create the next data point
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id])) push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
@ -1082,12 +990,6 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic
else else
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
end end
#=elseif drivingCourse[end][:s] > CS[:s_exit]
if settings[:stepVariable] == "s in m"
currentStepSize = CS[:s_exit] - drivingCourse[end-1][:s]
else
currentStepSize = settings[:stepSize] / 10.0^cycle
end=#
elseif drivingCourse[end][:s] > nextPointOfInterest elseif drivingCourse[end][:s] > nextPointOfInterest
if settings[:stepVariable] == "s in m" if settings[:stepVariable] == "s in m"
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s] currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
@ -1210,6 +1112,20 @@ function addStandstill!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, t
return (CS, drivingCourse) return (CS, drivingCourse)
end #function addStandstill! end #function addStandstill!
function mergeBehaviorSection!(BSs::Dict, BS::Dict)
if !haskey(BSs, Symbol(BS[:type]))
merge!(BSs, Dict(Symbol(BS[:type]) => BS))
else
number = "2"
while haskey(BSs, Symbol(BS[:type]*number))
number = string(parse(Int, number)+1)
end
merge!(BSs, Dict(Symbol(BS[:type]*number) => BS))
println("INFO: The ",number,". ",BS[:type]," section has been created. ! ! ! ! ! ! ! ! !")
end
return BSs
end #function mergeBehaviorSection!
function createBehaviorSection(type::String, s_entry::Real, v_entry::Real, startingPoint::Integer) function createBehaviorSection(type::String, s_entry::Real, v_entry::Real, startingPoint::Integer)
BS= Dict(#:type => behavior, # type of behavior section: breakFree, clearing, accelerating, cruising, diminishing, coasting, braking or standstill BS= Dict(#:type => behavior, # type of behavior section: breakFree, clearing, accelerating, cruising, diminishing, coasting, braking or standstill
:type => type, # type of behavior section: "breakFree", "clearing", "accelerating", "cruising", "diminishing", "coasting", "braking" or "standstill" :type => type, # type of behavior section: "breakFree", "clearing", "accelerating", "cruising", "diminishing", "coasting", "braking" or "standstill"

View File

@ -137,6 +137,7 @@ function secureAcceleratingBehavior!(movingSection::Dict, settings::Dict, train:
acceleratingCourse::Vector{Dict} = [startingPoint] # List of data points acceleratingCourse::Vector{Dict} = [startingPoint] # List of data points
if CS[:v_entry] < CS[:v_peak] if CS[:v_entry] < CS[:v_peak]
(CS, acceleratingCourse) = addBreakFreeSection!(CS, acceleratingCourse, settings, train, CSs, true)
(CS, acceleratingCourse) = addAcceleratingSection!(CS, acceleratingCourse, settings, train, CSs, true) # this function changes the acceleratingCourse (CS, acceleratingCourse) = addAcceleratingSection!(CS, acceleratingCourse, settings, train, CSs, true) # this function changes the acceleratingCourse
CS[:v_peak] = max(CS[:v_entry], acceleratingCourse[end][:v]) CS[:v_peak] = max(CS[:v_entry], acceleratingCourse[end][:v])
CS[:v_exit] = min(CS[:v_exit], CS[:v_peak], acceleratingCourse[end][:v]) CS[:v_exit] = min(CS[:v_exit], CS[:v_peak], acceleratingCourse[end][:v])

View File

@ -228,7 +228,8 @@ function calcBrakingDistance(v_start::Real, v_end::Real, a_braking::Real)
# a_braking: constant braking acceleration (in m/s^2) # a_braking: constant braking acceleration (in m/s^2)
s_braking = (v_end^2 - v_start^2) /2 /a_braking # braking distance (in m) s_braking = (v_end^2 - v_start^2) /2 /a_braking # braking distance (in m)
# TODO: also possible: calc_Δs_with_Δv(v_end-v_start, a_braking, v_start) # TODO: also possible: calc_Δs_with_Δv(v_end-v_start, a_braking, v_start)
return max(0.0, ceil(s_braking, digits=approximationLevel)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors # return max(0.0, ceil(s_braking, digits=approximationLevel)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
return max(0.0, ceil(s_braking, digits=approximationLevel +1)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
end #function calcBrakingDistance end #function calcBrakingDistance
function calcBrakingStartVelocity(v_end::Real, a_braking::Real, s_braking::Real) function calcBrakingStartVelocity(v_end::Real, a_braking::Real, s_braking::Real)
@ -238,7 +239,8 @@ function calcBrakingStartVelocity(v_end::Real, a_braking::Real, s_braking::Real)
# a_braking: constant braking acceleration (in m/s^2) # a_braking: constant braking acceleration (in m/s^2)
# s_braking: braking distance (in Ws) # s_braking: braking distance (in Ws)
v_start = sqrt(v_end^2 - 2*a_braking *s_braking) # braking start velocity (in m/s) v_start = sqrt(v_end^2 - 2*a_braking *s_braking) # braking start velocity (in m/s)
return floor(v_start, digits=approximationLevel) # return floor(v_start, digits=approximationLevel)
return floor(v_start, digits=approximationLevel +1)
end #function calcBrakingStartVelocity end #function calcBrakingStartVelocity
function calcBrakingAcceleration(v_start::Real, v_end::Real, s_braking::Real) function calcBrakingAcceleration(v_start::Real, v_end::Real, s_braking::Real)

View File

@ -26,10 +26,6 @@ export calculateDrivingDynamics
approximationLevel = 6 # value for approximation to intersections and precisely calculated digits approximationLevel = 6 # value for approximation to intersections and precisely calculated digits
# TODO: define it here and give it to each function? (Behavior, ...) # TODO: define it here and give it to each function? (Behavior, ...)
# INFO for diminishing and cruising: if v decreases to a value where F_T-F_R is positive the train could accelerate to a value of v where F_T-F_R is negative and so forth and so on. In Behavior.jl it is realized not oscillating with accelerating and diminishing but just with cruising instead of accelerating und therefore keeping the velocity value where F_T-F_R>0.
# Calculate the driving dynamics of a train run on a path with special settings with information from the corresponding YAML files with the file paths `trainDirectory`, `pathDirectory`, `settingsDirectory`. # Calculate the driving dynamics of a train run on a path with special settings with information from the corresponding YAML files with the file paths `trainDirectory`, `pathDirectory`, `settingsDirectory`.
""" """
@ -76,9 +72,14 @@ end # function calculateDrivingDynamics
function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train::Dict) function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train::Dict)
CSs::Vector{Dict} = movingSection[:characteristicSections] CSs::Vector{Dict} = movingSection[:characteristicSections]
if settings[:massModel] == "homogeneous strip"
println("WARNING: ! ! ! TrainRun.jl doesn't work reliably for the mass model homogeneous strip. This mass model should not be used ! ! !")
end
startingPoint=createDataPoint() startingPoint=createDataPoint()
startingPoint[:i]=1 startingPoint[:i]=1
startingPoint[:s]=CSs[1][:s_entry] startingPoint[:s]=CSs[1][:s_entry]
calculateForces!(startingPoint, CSs, 1, "default", train, settings[:massModel]) # traction effort and resisting forces (in N)
drivingCourse::Vector{Dict} = [startingPoint] # List of data points drivingCourse::Vector{Dict} = [startingPoint] # List of data points
for csId in 1:length(CSs) for csId in 1:length(CSs)
@ -92,120 +93,50 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
println("ERROR: In CS", csId," the train run ends with v=",drivingCourse[end][:v]," and not with v_entry=",CS[:v_entry]) println("ERROR: In CS", csId," the train run ends with v=",drivingCourse[end][:v]," and not with v_entry=",CS[:v_entry])
end end
if drivingCourse[end][:v] < CS[:v_peak] if drivingCourse[end][:v] == 0.0
(CS, drivingCourse) = addAcceleratingSection!(CS, drivingCourse, settings, train, CSs, false) (CS, drivingCourse) = addBreakFreeSection!(CS, drivingCourse, settings, train, CSs, false)
end #if end #if
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
brakingStartReached = drivingCourse[end][:s] + s_braking == CS[:s_exit]
testFlag = false # for testing
while !brakingStartReached && drivingCourse[end][:s] +s_braking < CS[:s_exit]
calculateForces!(drivingCourse[end], CSs, CS[:id], "default", train, settings[:massModel]) # traction effort and resisting forces (in N)
if drivingCourse[end][:F_T] >= drivingCourse[end][:F_R]
if drivingCourse[end][:v] < CS[:v_peak] - 1/10^approximationLevel * settings[:stepSize] # TODO: check if multiplying with stepSize is necessary
(CS, drivingCourse, brakingStartReached) = addAcceleratingSection!(CS, drivingCourse, settings, train, CSs, false)
#s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
# testFlag && println("in CS",CS[:id]," after accelerating s +s_braking=", drivingCourse[end][:s],"+",s_braking," = ",drivingCourse[end][:s] +s_braking," <= s_exit=",CS[:s_exit]) # for testing
else
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
s_cruising = CS[:s_exit] - drivingCourse[end][:s] - s_braking s_cruising = CS[:s_exit] - drivingCourse[end][:s] - s_braking
if s_cruising > 0.0 # TODO: define a minimum cruising length? if s_cruising > 0.0 # TODO: define a minimum cruising length?
(CS, drivingCourse) = addCruisingSection!(CS, drivingCourse, s_cruising, settings, train, CSs, "cruising")
end
if drivingCourse[end][:v] > CS[:v_exit]
(CS, drivingCourse)=addBrakingSection!(CS, drivingCourse, settings, train, CSs)
end #if
# for testing:
if drivingCourse[end][:s] != 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
if drivingCourse[end][:v] > CS[:v_exit]
println("ERROR: In CS", csId," the train run ends with v=",drivingCourse[end][:v]," and not with v_exit=",CS[:v_exit])
end
end #for
(CSs[end], drivingCourse) = addStandstill!(CSs[end], drivingCourse, settings, train, CSs)
movingSection[:t] = drivingCourse[end][:t] # total running time (in s)
movingSection[:E] = drivingCourse[end][:E] # total energy consumption (in Ws)
return (movingSection, drivingCourse)
end #function calculateMinimumRunningTime
end # module TrainRunCalc
#=
# calculate a train run focussing on using the minimum possible running time
function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train::Dict)
CSs::Vector{Dict} = movingSection[:characteristicSections]
startingPoint=createDataPoint()
startingPoint[:i]=1
startingPoint[:s]=CSs[1][:s_entry]
drivingCourse::Vector{Dict} = [startingPoint] # List of data points
for csId in 1:length(CSs)
CS = CSs[csId]
BSs = CS[:behaviorSections]
# for testing:
if drivingCourse[end][:s] != CS[:s_entry]
println("ERROR: In CS", csId," the train run starts at s=",drivingCourse[end][:s]," and not s_entry=",CS[:s_entry])
end
if drivingCourse[end][:v] > CS[:v_entry]
println("ERROR: In CS", csId," the train run ends with v=",drivingCourse[end][:v]," and not with v_entry=",CS[:v_entry])
end
# check if the CS has a cruising section
s_breakFree = get(BSs, :breakFree, Dict(:length=>0.0))[:length]
s_clearing = get(BSs, :clearing, Dict(:length=>0.0))[:length]
s_accelerating = get(BSs, :accelerating, Dict(:length=>0.0))[:length]
s_braking = calcBrakingDistance(CS[:v_peak], CS[:v_exit], train[:a_braking])
# old: 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 = max(0.0, CS[:length] - s_breakFree - s_clearing - s_accelerating - s_braking)
# reset the characteristic section (CS), delete behavior sections (BS) that were used during the preperation for setting v_entry, v_peak and v_exit
CS[:behaviorSections] = Dict()
CS[:E] = 0.0
CS[:t] = 0.0
# TODO 02/09: could there be a better structure for processing the different moving phases? (this if fork was added on 2022/09/02)
if s_clearing > 0.0 && s_breakFree + s_accelerating == 0.0
(CS, drivingCourse)=addCruisingSection!(CS, drivingCourse, s_clearing, settings, train, CSs, "clearing")
end
if s_cruising == CS[:length]
(CS, drivingCourse)=addCruisingSection!(CS, drivingCourse, s_cruising, settings, train, CSs, "cruising")
elseif s_cruising > 0.0 || s_braking == 0.0
if drivingCourse[end][:v] < CS[:v_peak]
(CS, drivingCourse) = addAcceleratingSection!(CS, drivingCourse, settings, train, CSs, false) # TODO or better ignoreBraking = true?
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
println("ERROR: After accelerating in CS ",csId," the braking distance is too short!")
println(" before accelerating in CS",csId, " with s=",drivingCourse[end][:s]," s_braking=",((CS[:v_exit]^2-drivingCourse[end][:v]^2)/2/train[:a_braking])," s_exit=",CS[:s_exit])
println(" and v=",drivingCourse[end][:v]," v_peak=",CS[:v_peak]," v_exit=",CS[:v_exit])
end
s_braking=max(0.0, ceil((CS[:v_exit]^2-drivingCourse[end][:v]^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
s_cruising=CS[:s_exit]-drivingCourse[end][:s]-s_braking
if s_cruising > 0.0
(CS, drivingCourse)=addCruisingSection!(CS, drivingCourse, s_cruising, settings, train, CSs, "cruising")
end
else
if CS[:v_entry] < CS[:v_peak] || s_accelerating > 0.0 # or instead of " || s_accelerating > 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]
# old 02/22 (CS, drivingCourse)=addAcceleratingSectionUntilBraking!(CS, drivingCourse, settings, train, CSs)
(CS, drivingCourse) = addAcceleratingSection!(CS, drivingCourse, settings, train, CSs, false)
end #if
end #if
(CS, drivingCourse, brakingStartReached) = addCruisingSection!(CS, drivingCourse, s_cruising, settings, train, CSs, "cruising")
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
testFlag && println("in CS",CS[:id]," after cruising s +s_braking=", drivingCourse[end][:s],"+",s_braking," = ",drivingCourse[end][:s] +s_braking," <= s_exit=",CS[:s_exit]) # for testing
# TODO: add downhillBraking as a special cruising Section:
# (CS, drivingCourse, brakingStartReached) = addCruisingSection!(CS, drivingCourse, s_cruising, settings, train, CSs, "downhillBraking")
end
end #if
else
(CS, drivingCourse, brakingStartReached) = addDiminishingSection!(CS, drivingCourse, settings, train, CSs)
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
# testFlag && println("in CS",CS[:id]," after diminishing s +s_braking=", drivingCourse[end][:s],"+",s_braking," = ",drivingCourse[end][:s] +s_braking," <= s_exit=",CS[:s_exit]) # for testing
end
end
if drivingCourse[end][:v] > CS[:v_exit] if drivingCourse[end][:v] > CS[:v_exit]
#(CS, drivingCourse)=addBrakingSection!(CS, drivingCourse, settings[:massModel], train, CSs)
(CS, drivingCourse)=addBrakingSection!(CS, drivingCourse, settings, train, CSs) (CS, drivingCourse)=addBrakingSection!(CS, drivingCourse, settings, train, CSs)
end #if end #if
# for testing: # for testing:
if drivingCourse[end][:s] != CS[:s_exit] if drivingCourse[end][:s] != CS[:s_exit]
println("ERROR: In CS", csId," the train run ends at s=",drivingCourse[end][:s]," and not 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])
@ -213,7 +144,6 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
if drivingCourse[end][:v] > CS[:v_exit] if drivingCourse[end][:v] > CS[:v_exit]
println("ERROR: In CS", csId," the train run ends with v=",drivingCourse[end][:v]," and not with v_exit=",CS[:v_exit]) 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)
@ -225,4 +155,3 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
end #function calculateMinimumRunningTime end #function calculateMinimumRunningTime
end # module TrainRunCalc end # module TrainRunCalc
=#