Refactor the handling of former section's speed limits and rename the moving phase "acceleration"

development
Max Kannenberg 2022-02-25 23:36:05 +01:00
parent fde1027b92
commit be54089917
6 changed files with 281 additions and 221 deletions

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: AdditionalOutput should not be used because it is not completed yet. It was used to show first results during development. # INFO: AdditionalOutput should not be used because it is not completed yet. It was used to show first results during development.
# TODO: It has to be optimized so that the created plots and printed information is clear and understandable. # TODO: It has to be optimized so that the created plots and printed information is clear and understandable.
@ -38,9 +45,11 @@ function plotDrivingCourse(drivingCourse::Vector{Dict})
push!(v, drivingCourse[i][:v]) push!(v, drivingCourse[i][:v])
end #for end #for
p1=plot([s], [v], title = "v in m/s", label = ["v"], xlabel = "s in m") # p1=plot([s], [v], title = "v in m/s", label = ["v"], xlabel = "s in m")
p1=plot([s/1000], [v*3.6], title = "v in km/h", label = ["v"], xlabel = "s in km")
p2=plot([t], [v], title = "v in m/s", label = ["v"], xlabel = "t in s") # p2=plot([t], [v], title = "v in m/s", label = ["v"], xlabel = "t in s")
p2=plot([t/60], [v*3.6], title = "v in km/h", label = ["v"], xlabel = "t in min")
# p3=plot([s], [t], title = "t in s", label = ["t"], xlabel = "s in m") # p3=plot([s], [t], title = "t in s", label = ["t"], xlabel = "s in m")
@ -137,7 +146,7 @@ function printSectionInformation(movingSection::Dict)
CSs::Vector{Dict} = movingSection[:characteristicSections] CSs::Vector{Dict} = movingSection[:characteristicSections]
println("MS with length=", movingSection[:length]," with t=", movingSection[:t]) println("MS with length=", movingSection[:length]," with t=", movingSection[:t])
allBs=[:breakFree, :clearing, :acceleration, :cruising, :diminishing, :coasting, :braking, :standstill] allBs=[:breakFree, :clearing, :accelerating, :cruising, :diminishing, :coasting, :braking, :standstill]
for csId in 1:length(CSs) for csId in 1:length(CSs)
println("CS ",csId," with length=", CSs[csId][:length]," with t=", CSs[csId][:t]) println("CS ",csId," with length=", CSs[csId][:length]," with t=", CSs[csId][:t])
for bs in 1: length(allBs) for bs in 1: length(allBs)

View File

@ -10,7 +10,7 @@ module Behavior
include("./DrivingDynamics.jl") include("./DrivingDynamics.jl")
using .DrivingDynamics using .DrivingDynamics
export addAccelerationSection!, addCruisingSection!, addCoastingSection!, addBrakingSection!, addStandstill!, export addAcceleratingSection!, 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,
@ -92,7 +92,7 @@ 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 == "acceleration" || bsType == "diminishing" if bsType == "accelerating" || bsType == "diminishing"
dataPoint[:F_T] = calculateTractiveEffort(dataPoint[:v], train[:tractiveEffortVelocityPairs]) dataPoint[:F_T] = calculateTractiveEffort(dataPoint[:v], train[:tractiveEffortVelocityPairs])
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]))
@ -126,7 +126,7 @@ function moveAStep(previousPoint::Dict, stepVariable::String, stepSize::Real, cs
newPoint[:Δv] = 0.0 # step size (in m/s) newPoint[:Δv] = 0.0 # step size (in m/s)
else else
if previousPoint[:a] < 0.0 && ((previousPoint[:v]/previousPoint[:a])^2+2*newPoint[:Δs]/previousPoint[:a])<0.0 || (previousPoint[:v]^2+2*newPoint[:Δs]*previousPoint[:a])<0.0 # checking if the parts of the following square roots will be <0.0 if previousPoint[:a] < 0.0 && ((previousPoint[:v]/previousPoint[:a])^2+2*newPoint[:Δs]/previousPoint[:a])<0.0 || (previousPoint[:v]^2+2*newPoint[:Δs]*previousPoint[:a])<0.0 # checking if the parts of the following square roots will be <0.0
error("ERROR: The train stops during the acceleration section in CS",csId," because the tractive effort is lower than the resistant forces.", error("ERROR: The train stops during the accelerating section in CS",csId," because the tractive effort is lower than the resistant forces.",
" Before the stop the last point has the values s=",previousPoint[:s]," m, v=",previousPoint[:v]," m/s, a=",previousPoint[:a]," m/s^2,", " Before the stop the last point has the values s=",previousPoint[:s]," m, v=",previousPoint[:v]," m/s, a=",previousPoint[:a]," m/s^2,",
" F_T=",previousPoint[:F_T]," N, R_traction=",previousPoint[:R_traction]," N, R_wagons=",previousPoint[:R_wagons]," N, R_path=",previousPoint[:R_path]," N.") " F_T=",previousPoint[:F_T]," N, R_traction=",previousPoint[:R_traction]," N, R_wagons=",previousPoint[:R_wagons]," N, R_path=",previousPoint[:R_path]," N.")
end end
@ -169,14 +169,15 @@ end #function moveAStep
""" """
# if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept # 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) function detectFormerSpeedLimits(CSs::Vector{Dict}, csWithTrainHeadId::Integer, currentPoint::Dict, trainLength::Real)
formerSpeedLimits=[] formerSpeedLimits=[]
if csWithTrainHeadId > 1 && currentPoint[:s] - trainLength < CSs[csWithTrainHeadId][:s_entry] if csWithTrainHeadId > 1 && currentPoint[:s] - trainLength < CSs[csWithTrainHeadId][:s_entry]
formerCsId=csWithTrainHeadId-1 formerCsId=csWithTrainHeadId-1
while formerCsId > 0 && currentPoint[:s] - trainLength < CSs[formerCsId][:s_exit] while formerCsId > 0 && currentPoint[:s] - trainLength < CSs[formerCsId][:s_exit]
if CSs[formerCsId][:v_limit] < CSs[csWithTrainHeadId][:v_limit] # TODO: is the position of trains tail < movingSection[:s_entry], v_limit of the first CS is used 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]]) push!(formerSpeedLimits, [CSs[formerCsId][:s_exit], CSs[formerCsId][:v_limit]])
for i in 1:length(formerSpeedLimits)-1 for i in 1:length(formerSpeedLimits)-1
if formerSpeedLimits[i][2]<=formerSpeedLimits[end][2] if formerSpeedLimits[i][2]<=formerSpeedLimits[end][2]
@ -191,13 +192,13 @@ function detectFormerSpeedLimits(CSs::Vector{Dict}, csWithTrainHeadId::Integer,
return formerSpeedLimits return formerSpeedLimits
end # function detectFormerSpeedLimits end # function detectFormerSpeedLimits
function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, formerSpeedLimits, accelerationSection::Dict) 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}, accelerationSection::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}, accelerationSection::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 length(formerSpeedLimits) > 0
# if a former speed limit has been exceeded the acceleration steps of this CS will be removed and a clearing section will be inserted before acceleration # 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] if drivingCourse[end][:v] > formerSpeedLimits[end][2]
while drivingCourse[end][:s] > get(CS[:behaviorSections], :clearing, accelerationSection)[:s_entry] while drivingCourse[end][:s] > get(CS[:behaviorSections], :clearing, acceleratingSection)[:s_entry]
pop!(drivingCourse) pop!(drivingCourse)
end end
@ -219,10 +220,10 @@ function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{Dict}, setti
# 09/22: if drivingCourse[end][:s] < CS[:s_exit] # 09/22: if drivingCourse[end][:s] < CS[:s_exit]
if drivingCourse[end][:s] < CS[:s_exit] - s_braking if drivingCourse[end][:s] < CS[:s_exit] - s_braking
# reset the accelerationSection # reset the acceleratingSection
accelerationSection = createBehaviorSection("acceleration", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) acceleratingSection = createBehaviorSection("accelerating", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
else else
return (CS, drivingCourse, formerSpeedLimits, accelerationSection, true) return (CS, drivingCourse, formerSpeedLimits, acceleratingSection, true)
end end
end end
@ -231,9 +232,62 @@ function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{Dict}, setti
pop!(formerSpeedLimits) pop!(formerSpeedLimits)
end end
end end
return (CS, drivingCourse, formerSpeedLimits, accelerationSection, false) return (CS, drivingCourse, formerSpeedLimits, acceleratingSection, false)
end # function considerFormerSpeedLimits! end # function considerFormerSpeedLimits!
=#
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 drivingCourse[end][:v] > currentSpeedLimit[:v]
# delete existing clearing section that is not long enough
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, currentSpeedLimit[:s_end] - drivingCourse[end][:s])
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
calculateForces!(drivingCourse[end], CSs, CS[:id], acceleratingSection[:type], train, settings[:massModel])
# reset the acceleratingSection
acceleratingSection = createBehaviorSection("accelerating", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
if drivingCourse[end][:s] + s_braking >= CS[:s_exit]
CS[:v_peak] = drivingCourse[end][:v]
end
end
return (CS, drivingCourse, acceleratingSection)
end # function considerFormerSpeedLimit!
function getCurrentSpeedLimit(CSs::Vector{Dict}, csWithTrainHeadId::Integer, s::Real, trainLength::Real)
v_limit = CSs[csWithTrainHeadId][:v_limit]
s_exit = CSs[csWithTrainHeadId][:s_exit]
if csWithTrainHeadId > 1 && s -trainLength < CSs[csWithTrainHeadId][:s_entry]
formerCsId = csWithTrainHeadId-1
while formerCsId > 0 && s -trainLength < CSs[formerCsId][:s_exit]
if CSs[formerCsId][:v_limit] < v_limit # TODO: is the position of the train's rear < movingSection[:s_entry], v_limit of the first CS is used
v_limit = CSs[formerCsId][:v_limit]
s_exit = CSs[formerCsId][:s_exit]
end
formerCsId = formerCsId -1
end
end
currentSpeedLimit = Dict(:v => v_limit, :s_end => s_exit + trainLength)
return currentSpeedLimit
end #function getCurrentSpeedLimit
function getNextPointOfInterest(pointsOfInterest::Vector{Real}, s::Real) function getNextPointOfInterest(pointsOfInterest::Vector{Real}, s::Real)
for POI in pointsOfInterest for POI in pointsOfInterest
@ -246,7 +300,7 @@ 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 acceleration 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})
if settings[:stepVariable] == "v in m/s" 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 ! ! !") println("WARNING: ! ! ! TrainRun.jl doesn't work reliably for the step variable v. Therefore v should not be used ! ! !")
@ -256,7 +310,7 @@ function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::D
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], "acceleration", train, settings[:massModel]) # currently the tractive effort is calculated like in the acceleration 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): # 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])
@ -324,10 +378,10 @@ function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::D
end #function addBreakFreeSection! end #function addBreakFreeSection!
## This function calculates the data points of the acceleration section. ## This function calculates the data points of the accelerating 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 accelerating section
function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, ignoreBraking::Bool) function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, ignoreBraking::Bool)
#=if drivingCourse would also be part of movingSectiong: function addAccelerationSection!(movingSection::Dict, csId::Integer, settings::Dict, train::Dict, ignoreBraking::Bool) #=if drivingCourse would also be part of movingSectiong: function addAcceleratingSection!(movingSection::Dict, csId::Integer, settings::Dict, train::Dict, ignoreBraking::Bool)
CSs = movingSection[:characteristicSections] CSs = movingSection[:characteristicSections]
CS = CSs[csId] CS = CSs[csId]
drivingCourse = movingSection[:drivingCourse]=# drivingCourse = movingSection[:drivingCourse]=#
@ -336,40 +390,46 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
(CS, drivingCourse) = addBreakFreeSection!(CS, drivingCourse, settings, train, CSs) (CS, drivingCourse) = addBreakFreeSection!(CS, drivingCourse, settings, train, CSs)
end #if end #if
calculateForces!(drivingCourse[end], CSs, CS[:id], "acceleration", train, settings[:massModel]) calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings[:massModel])
if drivingCourse[end][:F_T] < drivingCourse[end][:F_R] if drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
(CS, drivingCourse) = addDiminishingSection!(CS, drivingCourse, settings, train, CSs) (CS, drivingCourse) = addDiminishingSection!(CS, drivingCourse, settings, train, CSs)
calculateForces!(drivingCourse[end], CSs, CS[:id], "acceleration", train, settings[:massModel]) calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings[:massModel])
end end
if ignoreBraking if ignoreBraking
s_braking = 0.0 s_braking = 0.0
end 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 rear 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])
# conditions for acceleration section # 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]
# use the conditions for the acceleration section # use the conditions for the accelerating section
if !targetSpeedReached && !trainAtEnd && tractionSurplus if !targetSpeedReached && !trainAtEnd && tractionSurplus
BS = createBehaviorSection("acceleration", 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 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])
currentSpeedLimit = getCurrentSpeedLimit(CSs, CS[:id], drivingCourse[end][:s], train[:length])
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
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])
end 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][: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
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
currentSpeedLimit = getCurrentSpeedLimit(CSs, CS[:id], drivingCourse[end][:s], train[:length])
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])
@ -379,13 +439,13 @@ function addAccelerationSection!(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 tail of the train is located in a former characteristic section with lower speed limit check if is is possible to accelerate as normal # 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) # (CS, drivingCourse, formerSpeedLimits, BS, endOfCsReached) = considerFormerSpeedLimits!(CS, drivingCourse, settings, train, CSs, formerSpeedLimits, BS)
if endOfCsReached # if endOfCsReached
return (CS, drivingCourse) # return (CS, drivingCourse)
end # end
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
# 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 # 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
@ -396,16 +456,20 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
# 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
#println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," <= 0.0") # for testing
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
# TODO 01/21 should not be needed anymore with diminishing. # TODO 01/21 should not be needed anymore with diminishing.
elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R] 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 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
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
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
@ -413,25 +477,50 @@ function addAccelerationSection!(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
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
end end
elseif drivingCourse[end][:v] > currentSpeedLimit[:v]
#if drivingCourse[end][:s] < currentSpeedLimit[:s_end]
#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)
#end
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
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
brakingStartReached = true
if s_braking == 0.0
trainAtEnd = true
end
break
elseif drivingCourse[end][:s] == CS[:s_exit] 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 trainAtEnd = true
break 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
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
break break
else else
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") println("v=",drivingCourse[end][:v]," v_peak= ", CS[:v_peak] , " v_cLimit=", currentSpeedLimit[:v])
println("s=" ,drivingCourse[end][:s]," s_exit=", CS[:s_exit], " s+s_braking=", drivingCourse[end][:s] +s_braking," nextPOI=",nextPointOfInterest)
println("F_T=",drivingCourse[end][:F_T] ," F_R=", drivingCourse[end][:F_R])
error("ERROR at accelerating 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)
@ -441,7 +530,7 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
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]," between the positions ",drivingCourse[end-1][:s]," m and ",drivingCourse[end][:s]," m because the tractive effort is lower than the resistant forces.", 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", " 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.")
@ -451,9 +540,14 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
pop!(BS[:dataPoints]) pop!(BS[:dataPoints])
elseif drivingCourse[end][:s] + s_braking > CS[:s_exit] elseif drivingCourse[end][:s] + s_braking > CS[:s_exit]
brakingStartReached = true if s_braking > 0.0
pop!(drivingCourse) brakingStartReached = true
pop!(BS[:dataPoints]) pop!(drivingCourse)
pop!(BS[:dataPoints])
else
drivingCourse[end][:s] = CS[:s_exit] # round s down to CS[:s_exit]
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s]
end
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
@ -464,6 +558,12 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
(CS, drivingCourse) = addDiminishingSection!(CS, drivingCourse, settings, train, CSs) (CS, drivingCourse) = addDiminishingSection!(CS, drivingCourse, settings, train, CSs)
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel]) calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
elseif drivingCourse[end][:v] > currentSpeedLimit[:v]
#if drivingCourse[end][:s] - train[:length] < currentSpeedLimit[:s_end]
(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.
else else
end end
@ -474,10 +574,14 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
end end
end end
end #for end #for
if drivingCourse[end][:s] == CS[:s_exit]
trainAtEnd = true
end
end #while end #while
if length(BS[:dataPoints]) > 1 # TODO: is it still possible that it is <=1 although there is a separate diminishing section? if length(BS[:dataPoints]) > 1
# calculate the accumulated acceleration section information # calculate the accumulated accelerating 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)
:t => drivingCourse[end][:t] - drivingCourse[BS[:dataPoints][1]][:t], # total running time (in s) :t => drivingCourse[end][:t] - drivingCourse[BS[:dataPoints][1]][:t], # total running time (in s)
@ -488,12 +592,12 @@ function addAccelerationSection!(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(:acceleration => BS)) merge!(CS[:behaviorSections], Dict(:accelerating => BS))
end end
end end
return (CS, drivingCourse) return (CS, drivingCourse)
end #function addAccelerationSection! end #function addAcceleratingSection!
## This function calculates the data points of the cruising section. ## This function calculates the data points of the cruising section.
@ -506,10 +610,14 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
(CS, drivingCourse) = addDiminishingSection!(CS, drivingCourse, settings, train, CSs) (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])) # 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]) 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])
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
# 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 end
if drivingCourse[end][:v]>0.0 && drivingCourse[end][:v]<=CS[:v_peak] && drivingCourse[end][:s]<CS[:s_exit] && drivingCourse[end][:F_T] >= drivingCourse[end][:F_R] if drivingCourse[end][:v]>0.0 && drivingCourse[end][:v]<=CS[:v_peak] && drivingCourse[end][:s]<CS[:s_exit] && drivingCourse[end][:F_T] >= drivingCourse[end][:F_R]
# 11/22 old: if drivingCourse[end][:v]>0.0 && drivingCourse[end][:v]<=CS[:v_peak] && drivingCourse[end][:s]<CS[:s_exit]
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]
@ -518,7 +626,6 @@ 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]) # TODO: or give BS[:type] instead of "cruising"? calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel]) # TODO: or give BS[:type] instead of "cruising"?
# 11/05 old: drivingCourse[end]=DataPoint(calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel]))
if settings[:massModel]=="homogeneous strip" && CS[:id] > 1 if settings[:massModel]=="homogeneous strip" && CS[:id] > 1
# conditions for cruising section # conditions for cruising section
@ -530,25 +637,16 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
while trainInPreviousCS && !trainAtEnd && tractionSurplus while trainInPreviousCS && !trainAtEnd && tractionSurplus
currentStepSize = settings[:stepSize] currentStepSize = settings[:stepSize]
nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s]) nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])
# better? nextPointOfInterest = min(BS[:s_entry]+s_cruising, 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
while drivingCourse[end][:s] < CS[:s_entry] + train[:length] && drivingCourse[end][:s] < BS[:s_entry] +s_cruising && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:F_T]>=drivingCourse[end][:F_R] while drivingCourse[end][:s] < CS[:s_entry] + train[:length] && drivingCourse[end][:s] < BS[:s_entry] +s_cruising && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:F_T]>=drivingCourse[end][:F_R]
# TODO: whithout CSs should work as well, no? while drivingCourse[end][:s] < CSs[CS[:id]][:s_entry] + train[:length] && drivingCourse[end][:s]<BS[:s_entry]+s_cruising && drivingCourse[end][:F_T]>=drivingCourse[end][:F_R] #&& drivingCourse[end][:v]<=CS[:v_peak] && drivingCourse[end][:s]<CS[:s_exit]
# the tractive effort is lower than the resisiting forces and the train has use the highest possible effort to try to stay at v_peak OR the mass model homogeneous strip is used and parts of the train are still in former CS # the tractive effort is lower than the resisiting forces and the train has use the highest possible effort to try to stay at v_peak OR the mass model homogeneous strip is used and parts of the train are still in former CS
#TODO: maybe just consider former CS with different path resistance? #TODO: maybe just consider former CS with different path resistance?
#TODO: what about the case: After leaving a former CS with steep gradient the train can accelerate. Now in this tool the train will cruise at v_i. Just accelerating until v_peak could make problems for energy saving by shortening the acceleration section
# acceleration (in m/s^2): # acceleration (in m/s^2):
drivingCourse[end][:a] = 0.0 drivingCourse[end][:a] = 0.0
# create the next data point # create the next data point
#= 02/18 old if settings[:stepVariable]=="s in m"
push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", currentStepSize, CS[:id]))
else
push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", train[:length]/(10.0^cycle), CS[:id])) # TODO which step size should be used?
end =#
# create the next data point
if settings[:stepVariable] =="s in m" || settings[:stepVariable] =="t in s" if settings[:stepVariable] =="s in m" || settings[:stepVariable] =="t in s"
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id])) push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
else else
@ -591,7 +689,7 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
elseif drivingCourse[end][:s] == nextPointOfInterest elseif drivingCourse[end][:s] == nextPointOfInterest
break break
else # TODO copied from addAccelerationSection -> probably not needed here !? else # TODO copied from addAcceleratingSection -> probably not needed here !?
error("ERROR at cruising section: With the step variable ",settings[:stepVariable]," the while loop will be left although the if cases don't apply in CS",CS[:id]," with s=" ,drivingCourse[end][:s]," m and v=",drivingCourse[end][:v]," m/s") error("ERROR at cruising section: With the step variable ",settings[:stepVariable]," the while loop will be left although the if cases don't apply in CS",CS[:id]," with s=" ,drivingCourse[end][:s]," m and v=",drivingCourse[end][:v]," m/s")
end end
@ -699,19 +797,21 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
# 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
# 02/18 old: currentStepSize = settings[:stepSize] / 10.0^cycle
if settings[:stepVariable] == "v in m/s" if settings[:stepVariable] == "v in m/s"
currentStepSize = drivingCourse[end-1][:v] currentStepSize = drivingCourse[end-1][:v]
else else
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
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
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
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
@ -719,10 +819,12 @@ 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
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
break break
elseif drivingCourse[end][:v] == 0.0 elseif drivingCourse[end][:v] == 0.0
@ -731,7 +833,6 @@ 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.")
else else
error("ERROR during diminishing run: With the step variable ",settings[:stepVariable]," the while loop will be left although s+s_braking<s_exit && v>0.0 in CS",CS[:id]," with s=" ,drivingCourse[end][:s]," m and v=",drivingCourse[end][:v]," m/s") error("ERROR during diminishing run: With the step variable ",settings[:stepVariable]," the while loop will be left although s+s_braking<s_exit && v>0.0 in CS",CS[:id]," with s=" ,drivingCourse[end][:s]," m and v=",drivingCourse[end][:v]," m/s")
end end
@ -794,8 +895,8 @@ 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 addCoastingSection!(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 # TODO: 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
#formerSpeedLimits = detectFormerSpeedLimits(CSs, CS[:id], drivingCourse[end], train[:length]) # with getCurrentSpeedLimit
# conditions for coasting section # conditions for coasting section
targetSpeedReached = drivingCourse[end][:v] <= CS[:v_exit] targetSpeedReached = drivingCourse[end][:v] <= CS[:v_exit]
@ -953,26 +1054,28 @@ 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 # targetSpeedReached = true
# create empty data point and set ist for the values of s_ext 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 # break
# end
else
# create the next data point
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
drivingCourse[end][:behavior] = BS[:type]
push!(BS[:dataPoints], drivingCourse[end][:i])
end end
#println(drivingCourse[end][:i],". s=",drivingCourse[end][:s]," s_exit=", CS[:s_exit]," v_exit=", CS[:v_exit]," v=",drivingCourse[end][:v])
# create the next data point
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
drivingCourse[end][:behavior] = BS[:type]
push!(BS[:dataPoints], drivingCourse[end][:i])
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
# TODO: is there a better way than rounding like in the following? # TODO: is there a better way than rounding like in the following?
if cycle < approximationLevel+1 && !targetSpeedReached if cycle < approximationLevel+1
if drivingCourse[end][:v] < CS[:v_exit] if drivingCourse[end][:v] < CS[:v_exit]
if settings[:stepVariable] == "v in m/s" if settings[:stepVariable] == "v in m/s"
currentStepSize = drivingCourse[end-1][:v] - CS[:v_exit] currentStepSize = drivingCourse[end-1][:v] - CS[:v_exit]
@ -986,7 +1089,6 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
end=# end=#
elseif drivingCourse[end][:s] > nextPointOfInterest elseif drivingCourse[end][:s] > nextPointOfInterest
# reset last point with lowering s to the 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]
else else
@ -1068,68 +1170,6 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic
# do nothing for example for drivingCourse[end][:s]==nextPointOfInterest # do nothing for example for drivingCourse[end][:s]==nextPointOfInterest
end end
end end
#=
if drivingCourse[end][:v] < CS[:v_exit] || targetSpeedReached
# reset last point with setting v=v_exit
targetSpeedReached = true
trainAtEnd = true
# calculate s, t, v
drivingCourse[end][:s] = CS[:s_exit] # position (in m)
drivingCourse[end][:v] = CS[:v_exit] # velocity (in m/s)
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s] # step size (in m)
drivingCourse[end][:Δv] = drivingCourse[end][:v] - drivingCourse[end-1][:v] # step size (in m/s)
drivingCourse[end-1][:a] = calcBrakingAcceleration(drivingCourse[end-1][:v], drivingCourse[end][:v], drivingCourse[end][:Δs])
# TODO: just for testing
if drivingCourse[end-1][:a]<train[:a_braking] || drivingCourse[end-1][:a]>=0.0
println("Warning: a_braking gets to high in CS ",CS[:id], " with a=",drivingCourse[end-1][:a] ," > ",train[:a_braking])
end
drivingCourse[end][:Δt] = calc_Δt_with_Δv(drivingCourse[end][:Δv], drivingCourse[end-1][:a]) # step size (in s)
drivingCourse[end][:t] = drivingCourse[end-1][:t] + drivingCourse[end][:Δt] # point in time (in s)
drivingCourse[end][:ΔW] = 0.0 # mechanical work in this step (in Ws)
drivingCourse[end][:W] = drivingCourse[end-1][:W] + drivingCourse[end][:ΔW] # mechanical work (in Ws)
drivingCourse[end][:ΔE] = drivingCourse[end][:ΔW] # energy consumption in this step (in Ws)
drivingCourse[end][:E] = drivingCourse[end-1][:E] + drivingCourse[end][:ΔE] # energy consumption (in Ws)
elseif drivingCourse[end][:s] > CS[:s_exit]
trainAtEnd = true
error("At the end of braking: s>s_exit but v>v_exit")
elseif drivingCourse[end][:s] > nextPointOfInterest
# reset last point with lowering s to the nextPointOfInterest
# calculate s, t, v
if settings[:stepVariable] == "s in m"
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s] # step size (in m)
else
# TODO
end
pop!(drivingCourse)
pop!(BS[:dataPoints])
# create the next data point
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
drivingCourse[end][:behavior] = BS[:type]
push!(BS[:dataPoints], drivingCourse[end][:i])
elseif drivingCourse[end][:v] == CS[:v_exit] && drivingCourse[end][:s] == CS[:s_exit]
targetSpeedReached = true
trainAtEnd = true
elseif drivingCourse[end][:v] == CS[:v_exit]
targetSpeedReached = true
error("At the end of braking: s<s_exit but v=v_exit")
elseif drivingCourse[end][:s] == CS[:s_exit]
trainAtEnd = true
error("At the end of braking: s=s_exit but v>v_exit")
else
# do nothing for example for drivingCourse[end][:s]==nextPointOfInterest
end
=#
end #for end #for
end #while end #while
@ -1171,8 +1211,8 @@ function addStandstill!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, t
end #function addStandstill! end #function addStandstill!
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, acceleration, 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", "acceleration", "cruising", "diminishing", "coasting", "braking" or "standstill" :type => type, # type of behavior section: "breakFree", "clearing", "accelerating", "cruising", "diminishing", "coasting", "braking" or "standstill"
:length => 0.0, # total length (in m) :length => 0.0, # total length (in m)
:s_entry => s_entry, # first position (in m) :s_entry => s_entry, # first position (in m)
:s_exit => 0.0, # last position (in m) :s_exit => 0.0, # last position (in m)
@ -1189,7 +1229,7 @@ a data point is the smallest element of the driving course. One step of the step
""" """
function createDataPoint() function createDataPoint()
dataPoint = Dict(:i => 0, # identifier and counter variable of the dricing course dataPoint = Dict(:i => 0, # identifier and counter variable of the dricing course
:behavior => "", # type of behavior section the data point is part of ("breakFree", "clearing", "acceleration", "cruising", "diminishing", "coasting", "braking" or "standstill") :behavior => "", # type of behavior section the data point is part of ("breakFree", "clearing", "accelerating", "cruising", "diminishing", "coasting", "braking" or "standstill")
# a data point which is the last point of one behavior section and the first point of the next behavior section will be attached to the latter # a data point which is the last point of one behavior section and the first point of the next behavior section will be attached to the latter
:s => 0.0, # position (in m) :s => 0.0, # position (in m)
:Δs => 0.0, # step size (in m) :Δs => 0.0, # step size (in m)

View File

@ -12,11 +12,11 @@ using .Behavior
export preparateSections export preparateSections
## create a moving section and its containing characteristic sections with secured braking, acceleration and cruising behavior ## create a moving section and its containing characteristic sections with secured braking, accelerating and cruising behavior
function preparateSections(path::Dict, train::Dict, settings::Dict) function preparateSections(path::Dict, train::Dict, settings::Dict)
movingSection = createMovingSection(path, train[:v_limit]) movingSection = createMovingSection(path, train[:v_limit])
movingSection = secureBrakingBehavior!(movingSection, train[:a_braking]) movingSection = secureBrakingBehavior!(movingSection, train[:a_braking])
movingSection = secureAccelerationBehavior!(movingSection, settings, train) movingSection = secureAcceleratingBehavior!(movingSection, settings, train)
movingSection = secureCruisingBehavior!(movingSection, settings, train) movingSection = secureCruisingBehavior!(movingSection, settings, train)
return movingSection return movingSection
@ -119,8 +119,8 @@ function secureBrakingBehavior!(movingSection::Dict, a_braking::Real)
return movingSection return movingSection
end #function secureBrakingBehavior! end #function secureBrakingBehavior!
## define the intersection velocities between the characterisitc sections to secure acceleration behavior ## define the intersection velocities between the characterisitc sections to secure accelerating behavior
function secureAccelerationBehavior!(movingSection::Dict, settings::Dict, train::Dict) function secureAcceleratingBehavior!(movingSection::Dict, settings::Dict, train::Dict)
# this function limits the entry and exit velocity of the characteristic sections in case that the train accelerates in every section and cruises aterwards # this function limits the entry and exit velocity of the characteristic sections in case that the train accelerates in every section and cruises aterwards
CSs = movingSection[:characteristicSections] CSs = movingSection[:characteristicSections]
@ -134,12 +134,12 @@ function secureAccelerationBehavior!(movingSection::Dict, settings::Dict, train:
startingPoint[:s] = CS[:s_entry] startingPoint[:s] = CS[:s_entry]
startingPoint[:v] = CS[:v_entry] startingPoint[:v] = CS[:v_entry]
accelerationCourse::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, accelerationCourse) = addAccelerationSection!(CS, accelerationCourse, settings, train, CSs, true) # this function changes the accelerationCourse (CS, acceleratingCourse) = addAcceleratingSection!(CS, acceleratingCourse, settings, train, CSs, true) # this function changes the acceleratingCourse
CS[:v_peak] = max(CS[:v_entry], accelerationCourse[end][:v]) CS[:v_peak] = max(CS[:v_entry], acceleratingCourse[end][:v])
CS[:v_exit] = min(CS[:v_exit], CS[:v_peak], accelerationCourse[end][:v]) CS[:v_exit] = min(CS[:v_exit], CS[:v_peak], acceleratingCourse[end][:v])
else #CS[:v_entry] == CS[:v_peak] else #CS[:v_entry] == CS[:v_peak]
# v_exit stays the same # v_exit stays the same
end #if end #if
@ -153,7 +153,7 @@ function secureAccelerationBehavior!(movingSection::Dict, settings::Dict, train:
end #for end #for
return movingSection return movingSection
end #function secureAccelerationBehavior! end #function secureAcceleratingBehavior!

View File

@ -136,13 +136,13 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict
get(CSsOrig[csIdMax][:behaviorSections], :braking, get(CSsOrig[csIdMax][:behaviorSections], :braking,
get(CSsOrig[csIdMax][:behaviorSections], :coasting, get(CSsOrig[csIdMax][:behaviorSections], :coasting,
get(CSsOrig[csIdMax][:behaviorSections], :cruising, get(CSsOrig[csIdMax][:behaviorSections], :cruising,
get(CSsOrig[csIdMax][:behaviorSections], :acceleration, get(CSsOrig[csIdMax][:behaviorSections], :accelerating,
get(CSsOrig[csIdMax][:behaviorSections], :clearing, get(CSsOrig[csIdMax][:behaviorSections], :clearing,
get(CSsOrig[csIdMax][:behaviorSections], :breakFree, get(CSsOrig[csIdMax][:behaviorSections], :breakFree,
get(CSsOrig[csIdMax][:behaviorSections], :diminishing, get(CSsOrig[csIdMax][:behaviorSections], :diminishing,
Dict(:dataPoints => [0])))))))))[:dataPoints][end] Dict(:dataPoints => [0])))))))))[:dataPoints][end]
# if there is a diminishing phase its location must be analysed seperately because it could be before acceleration, between acceleration and cruising or after cruising. All the other behavior sections occure in a fixed order. # if there is a diminishing phase its location must be analysed seperately because it could be before accelerating, between accelerating and cruising or after cruising. All the other behavior sections occure in a fixed order.
if haskey(CSsOrig[csIdMax][:behaviorSections], :diminishing) if haskey(CSsOrig[csIdMax][:behaviorSections], :diminishing)
lastIdOfSelectedCsOriginal = max(lastIdOfSelectedCsOriginal, CSsOrig[csIdMax][:behaviorSections][:diminishing][:dataPoints][end]) lastIdOfSelectedCsOriginal = max(lastIdOfSelectedCsOriginal, CSsOrig[csIdMax][:behaviorSections][:diminishing][:dataPoints][end])
end end
@ -182,7 +182,7 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict
# update all the data point references in the behaviour sections of the following characteristic sections and the other modified characteristic sections # update all the data point references in the behaviour sections of the following characteristic sections and the other modified characteristic sections
if difference!= 0 if difference!= 0
# update the data point references in the behaviour sections of the following characteristic sections # update the data point references in the behaviour sections of the following characteristic sections
allBs=[:breakFree, :clearing, :acceleration, :cruising, :diminishing, :coasting, :braking, :standstill] allBs=[:breakFree, :clearing, :accelerating, :cruising, :diminishing, :coasting, :braking, :standstill]
for csId in csIdMax+1:length(CSsOrig) for csId in csIdMax+1:length(CSsOrig)
for bs in 1: length(allBs) for bs in 1: length(allBs)
if haskey(CSsOrig[csId][:behaviorSections], allBs[bs]) if haskey(CSsOrig[csId][:behaviorSections], allBs[bs])
@ -263,7 +263,7 @@ function copyMovingSection(original::Dict)
end #function copyMovingSection end #function copyMovingSection
function copyCharacteristicSection(originalCS::Dict) function copyCharacteristicSection(originalCS::Dict)
allBs=[:breakFree, :clearing, :acceleration, :cruising, :diminishing, :coasting, :braking, :standstill] allBs=[:breakFree, :clearing, :accelerating, :cruising, :diminishing, :coasting, :braking, :standstill]
copiedBSs = Dict() copiedBSs = Dict()
for bs in 1: length(allBs) for bs in 1: length(allBs)
if haskey(originalCS[:behaviorSections], allBs[bs]) if haskey(originalCS[:behaviorSections], allBs[bs])
@ -295,8 +295,8 @@ function copyBehaviorSection(original::Dict)
for i in 1:length(original[:dataPoints]) for i in 1:length(original[:dataPoints])
push!(bsDataPoints, original[:dataPoints][i]) push!(bsDataPoints, original[:dataPoints][i])
end end
copiedBS = Dict(#:type => behavior, # type of behavior section: breakFree, clearing, acceleration, cruising, diminishing, coasting, braking or standstill copiedBS = Dict(#:type => behavior, # type of behavior section: breakFree, clearing, accelerating, cruising, diminishing, coasting, braking or standstill
:type => original[:type], # type of behavior section: "breakFree", "clearing", "acceleration", "cruising", "diminishing", "coasting", "braking" or "standstill" :type => original[:type], # type of behavior section: "breakFree", "clearing", "accelerating", "cruising", "diminishing", "coasting", "braking" or "standstill"
:length => original[:length], # total length (in m) :length => original[:length], # total length (in m)
:s_entry => original[:s_entry], # first position (in m) :s_entry => original[:s_entry], # first position (in m)
:s_exit => original[:s_exit], # last position (in m) :s_exit => original[:s_exit], # last position (in m)
@ -320,7 +320,7 @@ function createEnergySavingModification()
end #createEnergySavingModification end #createEnergySavingModification
function updateEnergySavingModifications!(energySavingModifications::Vector{Dict}, csIdMax::Integer, drivingCourseNew::Vector{Dict}, endOfModificationId::Integer, lastIdOfSelectedCsOriginal::Integer) function updateEnergySavingModifications!(energySavingModifications::Vector{Dict}, csIdMax::Integer, drivingCourseNew::Vector{Dict}, endOfModificationId::Integer, lastIdOfSelectedCsOriginal::Integer)
allBs=[:breakFree, :clearing, :acceleration, :cruising, :diminishing, :coasting, :braking, :standstill] allBs=[:breakFree, :clearing, :accelerating, :cruising, :diminishing, :coasting, :braking, :standstill]
difference = endOfModificationId-lastIdOfSelectedCsOriginal difference = endOfModificationId-lastIdOfSelectedCsOriginal
for modNr in csIdMax+1:length(energySavingModifications) for modNr in csIdMax+1:length(energySavingModifications)
if energySavingModifications[modNr][:ratio]>0 if energySavingModifications[modNr][:ratio]>0
@ -522,7 +522,7 @@ end #function calculateRecoveryTime
# TODO: a refactoring caused worse drivingsCourses. see the commented function below # TODO: a refactoring caused worse drivingsCourses. see the commented function below
function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, allCSs::Vector{Dict}, t_recoveryAvailable::AbstractFloat) function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, allCSs::Vector{Dict}, t_recoveryAvailable::AbstractFloat)
BSsOriginal = csOriginal[:behaviorSections] BSsOriginal = csOriginal[:behaviorSections]
if (haskey(BSsOriginal, :cruising) || (haskey(BSsOriginal, :diminishing) && get(BSsOriginal, :diminishing, Dict(:dataPoints =>[0]))[:dataPoints][1] > get(BSsOriginal, :acceleration, Dict(:dataPoints =>[0]))[:dataPoints][1])) && haskey(BSsOriginal, :braking) if (haskey(BSsOriginal, :cruising) || (haskey(BSsOriginal, :diminishing) && get(BSsOriginal, :diminishing, Dict(:dataPoints =>[0]))[:dataPoints][1] > get(BSsOriginal, :accelerating, Dict(:dataPoints =>[0]))[:dataPoints][1])) && haskey(BSsOriginal, :braking)
# check if cruising or diminishing should be reduced for coasting # check if cruising or diminishing should be reduced for coasting
if haskey(BSsOriginal, :cruising) && haskey(BSsOriginal, :diminishing) if haskey(BSsOriginal, :cruising) && haskey(BSsOriginal, :diminishing)
if BSsOriginal[:cruising][:dataPoints][1] > BSsOriginal[:diminishing][:dataPoints][1] if BSsOriginal[:cruising][:dataPoints][1] > BSsOriginal[:diminishing][:dataPoints][1]
@ -546,7 +546,7 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
csModifiedInitial = copyCharacteristicSection(csOriginal) csModifiedInitial = copyCharacteristicSection(csOriginal)
BSsModified = csModifiedInitial[:behaviorSections] BSsModified = csModifiedInitial[:behaviorSections]
# delete bahavior sections that will be recalculated except breakFree, clearing, acceleration, diminishing # delete bahavior sections that will be recalculated except breakFree, clearing, accelerating, diminishing
# and rest total running time and energy consumption # and rest total running time and energy consumption
if haskey(BSsModified, :coasting) if haskey(BSsModified, :coasting)
csModifiedInitial[:E] = csModifiedInitial[:E] - BSsModified[:coasting][:E] csModifiedInitial[:E] = csModifiedInitial[:E] - BSsModified[:coasting][:E]
@ -635,11 +635,11 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
elseif reduceDiminishing elseif reduceDiminishing
# TODO: At the moment diminishing is reduced similar to the acceleration in decreaseMaximumVelocity. To reduce code the methods for reducing cruising phase and reducing the diminishing phase can be combined in some parts. # TODO: At the moment diminishing is reduced similar to the accelerating in decreaseMaximumVelocity. To reduce code the methods for reducing cruising phase and reducing the diminishing phase can be combined in some parts.
csModified = csModifiedInitial csModified = csModifiedInitial
diminishingSection = BSsModified[:diminishing] diminishingSection = BSsModified[:diminishing]
# remove the last diminishing waypoint # remove the last diminishing data point
t_diff = drivingCourse[diminishingSection[:dataPoints][end]][:t] - drivingCourse[diminishingSection[:dataPoints][end-1]][:t] t_diff = drivingCourse[diminishingSection[:dataPoints][end]][:t] - drivingCourse[diminishingSection[:dataPoints][end-1]][:t]
E_diff = drivingCourse[diminishingSection[:dataPoints][end]][:E] - drivingCourse[diminishingSection[:dataPoints][end-1]][:E] E_diff = drivingCourse[diminishingSection[:dataPoints][end]][:E] - drivingCourse[diminishingSection[:dataPoints][end-1]][:E]
pop!(diminishingSection[:dataPoints]) pop!(diminishingSection[:dataPoints])
@ -718,17 +718,17 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
csModified[:E] = csModified[:E] + BSsModified[:breakFree][:E] csModified[:E] = csModified[:E] + BSsModified[:breakFree][:E]
csModified[:t] = csModified[:t] + BSsModified[:breakFree][:t] csModified[:t] = csModified[:t] + BSsModified[:breakFree][:t]
end end
if haskey(BSsOriginal, :clearing) # this section is needed before acceleration if the train wants to accelerate to a speed higher than the limit in a previous CS where parts of the train are still located if haskey(BSsOriginal, :clearing) # this section is needed before accelerating if the train wants to accelerate to a speed higher than the limit in a previous CS where parts of the train are still located
clearingSection=copyBehaviorSection(BSsOriginal[:clearing]) clearingSection=copyBehaviorSection(BSsOriginal[:clearing])
merge!(BSsModified, Dict(:clearing=>clearingSection)) merge!(BSsModified, Dict(:clearing=>clearingSection))
csModified[:E] = csModified[:E] + BSsModified[:clearing][:E] csModified[:E] = csModified[:E] + BSsModified[:clearing][:E]
csModified[:t] = csModified[:t] + BSsModified[:clearing][:t] csModified[:t] = csModified[:t] + BSsModified[:clearing][:t]
end end
if haskey(BSsOriginal, :acceleration) if haskey(BSsOriginal, :accelerating)
accelerationSection=copyBehaviorSection(BSsOriginal[:acceleration]) acceleratingSection=copyBehaviorSection(BSsOriginal[:accelerating])
merge!(BSsModified, Dict(:acceleration=>accelerationSection)) merge!(BSsModified, Dict(:accelerating=>acceleratingSection))
csModified[:E] = csModified[:E] + BSsModified[:acceleration][:E] csModified[:E] = csModified[:E] + BSsModified[:accelerating][:E]
csModified[:t] = csModified[:t] + BSsModified[:acceleration][:t] csModified[:t] = csModified[:t] + BSsModified[:accelerating][:t]
end end
if haskey(BSsOriginal, :diminishing) if haskey(BSsOriginal, :diminishing)
diminishingSection=copyBehaviorSection(BSsOriginal[:diminishing]) diminishingSection=copyBehaviorSection(BSsOriginal[:diminishing])
@ -769,7 +769,7 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
elseif reduceDiminishing elseif reduceDiminishing
# TODO: At the moment diminishing is reduced like the acceleration in decreaseMaximumVelocity. To reduce code the methods for reducing cruising phase and reducing the diminishing phase can be combined in some parts. # TODO: At the moment diminishing is reduced like the accelerating in decreaseMaximumVelocity. To reduce code the methods for reducing cruising phase and reducing the diminishing phase can be combined in some parts.
# copy csOriginal to csModified # copy csOriginal to csModified
# 12/28 old: csModified=CharacteristicSection(csOriginal[:id], csOriginal[:length], csOriginal[:s_entry], csOriginal[:s_exit], 0.0, 0.0, csOriginal[:v_limit], csOriginal[:v_peak], csOriginal[:v_entry], csOriginal[:v_exit], csOriginal[:r_path], Dict{Symbol, Dict}()) # 12/28 old: csModified=CharacteristicSection(csOriginal[:id], csOriginal[:length], csOriginal[:s_entry], csOriginal[:s_exit], 0.0, 0.0, csOriginal[:v_limit], csOriginal[:v_peak], csOriginal[:v_entry], csOriginal[:v_exit], csOriginal[:r_path], Dict{Symbol, Dict}())
@ -794,17 +794,17 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
csModified[:E] = csModified[:E] + BSsModified[:breakFree][:E] csModified[:E] = csModified[:E] + BSsModified[:breakFree][:E]
csModified[:t] = csModified[:t] + BSsModified[:breakFree][:t] csModified[:t] = csModified[:t] + BSsModified[:breakFree][:t]
end end
if haskey(BSsOriginal, :clearing) # this section is needed before acceleration if the train wants to accelerate to a speed higher than the limit in a previous CS where parts of the train are still located if haskey(BSsOriginal, :clearing) # this section is needed before accelerating if the train wants to accelerate to a speed higher than the limit in a previous CS where parts of the train are still located
clearingSection=copyBehaviorSection(BSsOriginal[:clearing]) clearingSection=copyBehaviorSection(BSsOriginal[:clearing])
merge!(BSsModified, Dict(:clearing=>clearingSection)) merge!(BSsModified, Dict(:clearing=>clearingSection))
csModified[:E] = csModified[:E] + BSsModified[:clearing][:E] csModified[:E] = csModified[:E] + BSsModified[:clearing][:E]
csModified[:t] = csModified[:t] + BSsModified[:clearing][:t] csModified[:t] = csModified[:t] + BSsModified[:clearing][:t]
end end
if haskey(BSsOriginal, :acceleration) if haskey(BSsOriginal, :accelerating)
accelerationSection=copyBehaviorSection(BSsOriginal[:acceleration]) acceleratingSection=copyBehaviorSection(BSsOriginal[:accelerating])
merge!(BSsModified, Dict(:acceleration=>accelerationSection)) merge!(BSsModified, Dict(:accelerating=>acceleratingSection))
csModified[:E] = csModified[:E] + BSsModified[:acceleration][:E] csModified[:E] = csModified[:E] + BSsModified[:accelerating][:E]
csModified[:t] = csModified[:t] + BSsModified[:acceleration][:t] csModified[:t] = csModified[:t] + BSsModified[:accelerating][:t]
end end
if haskey(BSsOriginal, :cruising) if haskey(BSsOriginal, :cruising)
cruisingSection=copyBehaviorSection(BSsOriginal[:cruising]) cruisingSection=copyBehaviorSection(BSsOriginal[:cruising])
@ -815,7 +815,7 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
diminishingSection=copyBehaviorSection(BSsOriginal[:diminishing]) diminishingSection=copyBehaviorSection(BSsOriginal[:diminishing])
if length(diminishingSection[:dataPoints]) > 2 if length(diminishingSection[:dataPoints]) > 2
# remove the last diminishing waypoint # remove the last diminishing data point
pop!(diminishingSection[:dataPoints]) pop!(diminishingSection[:dataPoints])
diminishingSection[:v_exit]=drivingCourse[diminishingSection[:dataPoints][end]][:v] # exit speed (in m/s) diminishingSection[:v_exit]=drivingCourse[diminishingSection[:dataPoints][end]][:v] # exit speed (in m/s)
@ -865,18 +865,18 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
end end
end # function increaseCoastingSection end # function increaseCoastingSection
# method 2 with shortening the acceleration by stepsize # method 2 with shortening the accelerating by stepsize
function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict, train::Dict, allCSs::Vector{Dict}, t_recoveryAvailable::AbstractFloat) function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict, train::Dict, allCSs::Vector{Dict}, t_recoveryAvailable::AbstractFloat)
# TODO doesn't work that well alone. works better with combineEnergySavingMethods. why? does a while loop end to early or something like this? # TODO doesn't work that well alone. works better with combineEnergySavingMethods. why? does a while loop end to early or something like this?
#function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat) #function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
BSsOriginal = csOriginal[:behaviorSections] BSsOriginal = csOriginal[:behaviorSections]
if haskey(BSsOriginal, :acceleration) && csOriginal[:v_peak] > csOriginal[:v_entry] && csOriginal[:v_peak] > csOriginal[:v_exit] if haskey(BSsOriginal, :accelerating) && csOriginal[:v_peak] > csOriginal[:v_entry] && csOriginal[:v_peak] > csOriginal[:v_exit]
accelerationSection = copyBehaviorSection(BSsOriginal[:acceleration]) acceleratingSection = copyBehaviorSection(BSsOriginal[:accelerating])
if drivingCourse[accelerationSection[:dataPoints][end]-1][:v] < csOriginal[:v_exit] if drivingCourse[acceleratingSection[:dataPoints][end]-1][:v] < csOriginal[:v_exit]
# 12/29 old, now not with empty but with original CS and DC: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes? # 12/29 old, now not with empty but with original CS and DC: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes?
return (csOriginal, drivingCourse, false) return (csOriginal, drivingCourse, false)
# TODO: or calculate a new acceleration phase with v_exit as v_peak? it will be very short, shorter than the step size. # TODO: or calculate a new accelerating phase with v_exit as v_peak? it will be very short, shorter than the step size.
end end
# copy csOriginal to csModified # copy csOriginal to csModified
@ -902,14 +902,14 @@ function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict
csModified[:E] = csModified[:E] + BSsModified[:breakFree][:E] csModified[:E] = csModified[:E] + BSsModified[:breakFree][:E]
csModified[:t] = csModified[:t] + BSsModified[:breakFree][:t] csModified[:t] = csModified[:t] + BSsModified[:breakFree][:t]
end end
if haskey(BSsOriginal, :diminishing) && BSsModified[:diminishing][:dataPoints][1] < BSsModified[:acceleration][:dataPoints][1] if haskey(BSsOriginal, :diminishing) && BSsModified[:diminishing][:dataPoints][1] < BSsModified[:accelerating][:dataPoints][1]
diminishingSection=copyBehaviorSection(BSsOriginal[:diminishing]) diminishingSection=copyBehaviorSection(BSsOriginal[:diminishing])
merge!(BSsModified, Dict(:diminishing=>diminishingSection)) merge!(BSsModified, Dict(:diminishing=>diminishingSection))
csModified[:E] = csModified[:E] + BSsModified[:diminishing][:E] csModified[:E] = csModified[:E] + BSsModified[:diminishing][:E]
csModified[:t] = csModified[:t] + BSsModified[:diminishing][:t] csModified[:t] = csModified[:t] + BSsModified[:diminishing][:t]
end end
if length(accelerationSection[:dataPoints]) > 2 if length(acceleratingSection[:dataPoints]) > 2
if haskey(BSsOriginal, :clearing) if haskey(BSsOriginal, :clearing)
clearingSection=copyBehaviorSection(BSsOriginal[:clearing]) clearingSection=copyBehaviorSection(BSsOriginal[:clearing])
merge!(BSsModified, Dict(:clearing=>clearingSection)) merge!(BSsModified, Dict(:clearing=>clearingSection))
@ -917,23 +917,23 @@ function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict
csModified[:t] = csModified[:t] + BSsModified[:clearing][:t] csModified[:t] = csModified[:t] + BSsModified[:clearing][:t]
end end
# remove the last acceleration waypoint from the accelerationSection # remove the last data point from the acceleratingSection
pop!(accelerationSection[:dataPoints]) pop!(acceleratingSection[:dataPoints])
energySavingStartId = accelerationSection[:dataPoints][end] energySavingStartId = acceleratingSection[:dataPoints][end]
accelerationSection[:v_exit]=drivingCourse[energySavingStartId][:v] # exit speed (in m/s) acceleratingSection[:v_exit]=drivingCourse[energySavingStartId][:v] # exit speed (in m/s)
accelerationSection[:s_exit]=drivingCourse[energySavingStartId][:s] # last position (in m) acceleratingSection[:s_exit]=drivingCourse[energySavingStartId][:s] # last position (in m)
accelerationSection[:length]=accelerationSection[:s_exit]-accelerationSection[:s_entry] # total length (in m) acceleratingSection[:length]=acceleratingSection[:s_exit]-acceleratingSection[:s_entry] # total length (in m)
accelerationSection[:t]=drivingCourse[energySavingStartId][:t]-drivingCourse[accelerationSection[:dataPoints][1]][:t] # total running time (in s) acceleratingSection[:t]=drivingCourse[energySavingStartId][:t]-drivingCourse[acceleratingSection[:dataPoints][1]][:t] # total running time (in s)
accelerationSection[:E]=drivingCourse[energySavingStartId][:E]-drivingCourse[accelerationSection[:dataPoints][1]][:E] # total energy consumption (in Ws) acceleratingSection[:E]=drivingCourse[energySavingStartId][:E]-drivingCourse[acceleratingSection[:dataPoints][1]][:E] # total energy consumption (in Ws)
merge!(BSsModified, Dict(:acceleration=>accelerationSection)) merge!(BSsModified, Dict(:accelerating=>acceleratingSection))
csModified[:E] = csModified[:E] + accelerationSection[:E] csModified[:E] = csModified[:E] + acceleratingSection[:E]
csModified[:t] = csModified[:t] + accelerationSection[:t] csModified[:t] = csModified[:t] + acceleratingSection[:t]
else else
# The acceleration section is only one step. This step is removed and if there is a clearing section it will be combined with the new cruising section. # The accelerating section is only one step. This step is removed and if there is a clearing section it will be combined with the new cruising section.
energySavingStartId=get(BSsOriginal, :clearing, get(BSsOriginal, :acceleration, Dict(:dataPoints =>[0])))[:dataPoints][1] energySavingStartId=get(BSsOriginal, :clearing, get(BSsOriginal, :accelerating, Dict(:dataPoints =>[0])))[:dataPoints][1]
end end
# TODO: should v_peak be reduced or is it enough to pop the data points? # TODO: should v_peak be reduced or is it enough to pop the data points?
@ -976,8 +976,8 @@ function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict
return (csModified, drivingCourseModified, true) return (csModified, drivingCourseModified, true)
else # time loss is to high. so there is no energy saving modification for this CS with the available recovery time else # time loss is to high. so there is no energy saving modification for this CS with the available recovery time
# 09/06 old: else # time loss is to high and the CS has to be calculated again with larger acceleration section (so with a smaller reduction of the acceleration section) # 09/06 old: else # time loss is to high and the CS has to be calculated again with larger accelerating section (so with a smaller reduction of the accelerating section)
# 09/06 old: accelerationReduction=min(accelerationReduction/10, csModified[:v_peak]-csModified[:v_entry], csModified[:v_peak]-csModified[:v_exit]) # 09/06 old: acceleratingReduction=min(acceleratingReduction/10, csModified[:v_peak]-csModified[:v_entry], csModified[:v_peak]-csModified[:v_exit])
# TODO: just return false or take smaller steps? # TODO: just return false or take smaller steps?
# 12/29 old, now not with empty but with original CS and DC: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes? # 12/29 old, now not with empty but with original CS and DC: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes?
@ -992,7 +992,7 @@ function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict
else else
# there is no energy saving modification for this CS because v_peak can not be lowered below v_entry or v_exit or because there is no acceleration section that can be transformed into a cruising section # there is no energy saving modification for this CS because v_peak can not be lowered below v_entry or v_exit or because there is no accelerating section that can be transformed into a cruising section
# 12/29 old, now not with empty but with original CS and DC: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes? # 12/29 old, now not with empty but with original CS and DC: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes?
return (csOriginal, drivingCourse, false) return (csOriginal, drivingCourse, false)
end #if haskey end #if haskey
@ -1001,8 +1001,8 @@ end # function decreaseMaximumVelocity
# combination of method 1 and method 2 # combination of method 1 and method 2
function combineEnergySavingMethods(csOriginal::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, allCSs::Vector{Dict}, t_recoveryAvailable::AbstractFloat) function combineEnergySavingMethods(csOriginal::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, allCSs::Vector{Dict}, t_recoveryAvailable::AbstractFloat)
BSsOriginal = csOriginal[:behaviorSections] BSsOriginal = csOriginal[:behaviorSections]
# if haskey(BSsOriginal, :acceleration) && (haskey(BSsOriginal, :braking) || haskey(BSsOriginal, :coasting)) && csOriginal[:v_peak]>csOriginal[:v_entry] && csOriginal[:v_peak]>csOriginal[:v_exit] # if haskey(BSsOriginal, :accelerating) && (haskey(BSsOriginal, :braking) || haskey(BSsOriginal, :coasting)) && csOriginal[:v_peak]>csOriginal[:v_entry] && csOriginal[:v_peak]>csOriginal[:v_exit]
if haskey(BSsOriginal, :acceleration) && (haskey(BSsOriginal, :braking) || haskey(BSsOriginal, :coasting)) && drivingCourse[get(BSsOriginal, :acceleration, Dict(:dataPoints =>[0]))[:dataPoints][end]][:v] > max(csOriginal[:v_entry], csOriginal[:v_exit]) if haskey(BSsOriginal, :accelerating) && (haskey(BSsOriginal, :braking) || haskey(BSsOriginal, :coasting)) && drivingCourse[get(BSsOriginal, :accelerating, Dict(:dataPoints =>[0]))[:dataPoints][end]][:v] > max(csOriginal[:v_entry], csOriginal[:v_exit])
# copy the characteristic section # copy the characteristic section
csCombined = copyCharacteristicSection(csOriginal) csCombined = copyCharacteristicSection(csOriginal)
@ -1034,7 +1034,7 @@ function combineEnergySavingMethods(csOriginal::Dict, drivingCourse::Vector{Dict
end # while end # while
return (csCombined, drivingCourseCombined, (ΔE>0.0))# && Δt>0.0)) return (csCombined, drivingCourseCombined, (ΔE>0.0))# && Δt>0.0))
else else
# there is no energy saving modification for this CS because v_peak can not be lowered below v_entry or v_exit or because there is no acceleration section and braking section or coasting section that can be transformed into a cruising section or coasting section # there is no energy saving modification for this CS because v_peak can not be lowered below v_entry or v_exit or because there is no accelerating section and braking section or coasting section that can be transformed into a cruising section or coasting section
# 12/29 old, now not with empty but with original CS and DC: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes? # 12/29 old, now not with empty but with original CS and DC: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes?
return (csOriginal, drivingCourse, false) return (csOriginal, drivingCourse, false)
end #if end #if

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 Export module Export
using CSV, DataFrames, Dates using CSV, DataFrames, Dates
@ -39,17 +46,17 @@ function createCsvFile(movingSection::Dict, dataPointsToExport::Vector{Dict}, op
stepVariable = settings[:stepVariable] stepVariable = settings[:stepVariable]
stepSize = string(settings[:stepSize]) stepSize = string(settings[:stepSize])
# create summarized data block # create accumulated data block
summarizedData = Array{Any, 1}[] accumulatedData = Array{Any, 1}[]
if detailOfOutput == "minimal" if detailOfOutput == "minimal"
push!(summarizedData, ["s (in m)", "t (in s)","E (in Ws)"]) # push header to summarizedData push!(accumulatedData, ["s (in m)", "t (in s)","E (in Ws)"]) # push header to accumulatedData
row = [movingSection[:length], movingSection[:t], movingSection[:E]] row = [movingSection[:length], movingSection[:t], movingSection[:E]]
push!(summarizedData, row) # push row to summarizedData push!(accumulatedData, row) # push row to accumulatedData
elseif detailOfOutput == "driving course" || detailOfOutput == "points of interest" elseif detailOfOutput == "driving course" || detailOfOutput == "points of interest"
push!(summarizedData, ["i", "behavior", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_wagons (in N)", "ΔW (in Ws)","W (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]) # push header to summarizedData push!(accumulatedData, ["i", "behavior", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_wagons (in N)", "ΔW (in Ws)","W (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]) # push header to accumulatedData
for point in dataPointsToExport for point in dataPointsToExport
row = [point[:i], point[:behavior], point[:Δs], point[:s], point[:Δt], point[:t], point[:Δv], point[:v], point[:F_T], point[:F_R], point[:R_path], point[:R_train], point[:R_traction], point[:R_wagons], point[:ΔW], point[:W], point[:ΔE], point[:E], point[:a]] row = [point[:i], point[:behavior], point[:Δs], point[:s], point[:Δt], point[:t], point[:Δv], point[:v], point[:F_T], point[:F_R], point[:R_path], point[:R_train], point[:R_traction], point[:R_wagons], point[:ΔW], point[:W], point[:ΔE], point[:E], point[:a]]
push!(summarizedData, row) # push row to summarizedData push!(accumulatedData, row) # push row to accumulatedData
end end
end end
@ -57,15 +64,15 @@ function createCsvFile(movingSection::Dict, dataPointsToExport::Vector{Dict}, op
allColumns=Array{Any,1}[] allColumns=Array{Any,1}[]
push!(allColumns, ["path name", "train name", "operation mode", "mass model", "step variable", "step size", ""]) push!(allColumns, ["path name", "train name", "operation mode", "mass model", "step variable", "step size", ""])
push!(allColumns, [pathName, trainName, operationMode, massModel, stepVariable, stepSize, ""]) push!(allColumns, [pathName, trainName, operationMode, massModel, stepVariable, stepSize, ""])
for column in 3:length(summarizedData[1]) for column in 3:length(accumulatedData[1])
push!(allColumns, ["", "", "", "", "", "", ""]) push!(allColumns, ["", "", "", "", "", "", ""])
end # for end # for
# add driving data to the array # add driving data to the array
header = summarizedData[1] header = accumulatedData[1]
for column in 1:length(summarizedData[1]) for column in 1:length(accumulatedData[1])
push!(allColumns[column], header[column]) push!(allColumns[column], header[column])
for row in summarizedData[2:end] for row in accumulatedData[2:end]
push!(allColumns[column], row[column]) push!(allColumns[column], row[column])
end end
end # for end # for

View File

@ -26,6 +26,10 @@ 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`.
""" """
@ -89,7 +93,7 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
end end
if drivingCourse[end][:v] < CS[:v_peak] if drivingCourse[end][:v] < CS[:v_peak]
(CS, drivingCourse) = addAccelerationSection!(CS, drivingCourse, settings, train, CSs, false) (CS, drivingCourse) = addAcceleratingSection!(CS, drivingCourse, settings, train, CSs, false)
end #if end #if
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
@ -150,12 +154,12 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
# check if the CS has a cruising section # 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_accelerating = get(BSs, :accelerating, Dict(:length=>0.0))[:length]
s_braking = calcBrakingDistance(CS[:v_peak], CS[:v_exit], train[:a_braking]) 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 # 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 # calculate the cruising sections length
s_cruising = max(0.0, CS[:length] - s_breakFree - s_clearing - s_acceleration - s_braking) 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 # 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[:behaviorSections] = Dict()
@ -163,7 +167,7 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
CS[:t] = 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) # 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_acceleration == 0.0 if s_clearing > 0.0 && s_breakFree + s_accelerating == 0.0
(CS, drivingCourse)=addCruisingSection!(CS, drivingCourse, s_clearing, settings, train, CSs, "clearing") (CS, drivingCourse)=addCruisingSection!(CS, drivingCourse, s_clearing, settings, train, CSs, "clearing")
end end
@ -172,12 +176,12 @@ 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, false) # TODO or better ignoreBraking = true? (CS, drivingCourse) = addAcceleratingSection!(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
println("ERROR: After accelerating in CS ",csId," the braking distance is too short!") println("ERROR: After accelerating in CS ",csId," the braking distance is too short!")
println(" before acceleration in CS",csId, " with s=",drivingCourse[end][:s]," s_braking=",((CS[:v_exit]^2-drivingCourse[end][:v]^2)/2/train[:a_braking])," s_exit=",CS[:s_exit]) 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]) println(" and v=",drivingCourse[end][:v]," v_peak=",CS[:v_peak]," v_exit=",CS[:v_exit])
end end
@ -188,10 +192,10 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
(CS, drivingCourse)=addCruisingSection!(CS, drivingCourse, s_cruising, settings, train, CSs, "cruising") (CS, drivingCourse)=addCruisingSection!(CS, drivingCourse, s_cruising, settings, train, CSs, "cruising")
end end
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_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] # 09/09 old (not sufficient for steep gradients): if CS[:v_entry] < CS[:v_peak]
# old 02/22 (CS, drivingCourse)=addAccelerationSectionUntilBraking!(CS, drivingCourse, settings, train, CSs) # old 02/22 (CS, drivingCourse)=addAcceleratingSectionUntilBraking!(CS, drivingCourse, settings, train, CSs)
(CS, drivingCourse) = addAccelerationSection!(CS, drivingCourse, settings, train, CSs, false) (CS, drivingCourse) = addAcceleratingSection!(CS, drivingCourse, settings, train, CSs, false)
end #if end #if
end #if end #if