Refactor the handling of former section's speed limits and rename the moving phase "acceleration"
parent
fde1027b92
commit
be54089917
|
@ -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.
|
||||
# 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])
|
||||
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")
|
||||
|
||||
|
@ -137,7 +146,7 @@ function printSectionInformation(movingSection::Dict)
|
|||
CSs::Vector{Dict} = movingSection[:characteristicSections]
|
||||
|
||||
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)
|
||||
println("CS ",csId," with length=", CSs[csId][:length]," with t=", CSs[csId][:t])
|
||||
for bs in 1: length(allBs)
|
||||
|
|
318
src/Behavior.jl
318
src/Behavior.jl
|
@ -10,7 +10,7 @@ module Behavior
|
|||
include("./DrivingDynamics.jl")
|
||||
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
|
||||
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]
|
||||
|
||||
# calculate tractive effort
|
||||
if bsType == "acceleration" || bsType == "diminishing"
|
||||
if bsType == "accelerating" || bsType == "diminishing"
|
||||
dataPoint[:F_T] = calculateTractiveEffort(dataPoint[:v], train[:tractiveEffortVelocityPairs])
|
||||
elseif bsType == "cruising"
|
||||
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)
|
||||
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
|
||||
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,",
|
||||
" 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
|
||||
|
@ -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)
|
||||
formerSpeedLimits=[]
|
||||
if csWithTrainHeadId > 1 && currentPoint[:s] - trainLength < CSs[csWithTrainHeadId][:s_entry]
|
||||
formerCsId=csWithTrainHeadId-1
|
||||
while formerCsId > 0 && currentPoint[:s] - trainLength < CSs[formerCsId][:s_exit]
|
||||
if CSs[formerCsId][:v_limit] < CSs[csWithTrainHeadId][:v_limit] # TODO: is the position of 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]])
|
||||
for i in 1:length(formerSpeedLimits)-1
|
||||
if formerSpeedLimits[i][2]<=formerSpeedLimits[end][2]
|
||||
|
@ -191,13 +192,13 @@ function detectFormerSpeedLimits(CSs::Vector{Dict}, csWithTrainHeadId::Integer,
|
|||
return formerSpeedLimits
|
||||
end # function detectFormerSpeedLimits
|
||||
|
||||
function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, formerSpeedLimits, 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}, accelerationSection::Dict)
|
||||
# would work: function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, formerSpeedLimits::Array{Any,1}, 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}, acceleratingSection::Dict)
|
||||
# would work: function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, formerSpeedLimits::Array{Any,1}, acceleratingSection::Dict)
|
||||
if length(formerSpeedLimits) > 0
|
||||
# if a former speed limit has been exceeded the 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]
|
||||
while drivingCourse[end][:s] > get(CS[:behaviorSections], :clearing, accelerationSection)[:s_entry]
|
||||
while drivingCourse[end][:s] > get(CS[:behaviorSections], :clearing, acceleratingSection)[:s_entry]
|
||||
pop!(drivingCourse)
|
||||
end
|
||||
|
||||
|
@ -219,10 +220,10 @@ function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{Dict}, setti
|
|||
|
||||
# 09/22: if drivingCourse[end][:s] < CS[:s_exit]
|
||||
if drivingCourse[end][:s] < CS[:s_exit] - s_braking
|
||||
# reset the accelerationSection
|
||||
accelerationSection = createBehaviorSection("acceleration", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
|
||||
# reset the acceleratingSection
|
||||
acceleratingSection = createBehaviorSection("accelerating", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
|
||||
else
|
||||
return (CS, drivingCourse, formerSpeedLimits, accelerationSection, true)
|
||||
return (CS, drivingCourse, formerSpeedLimits, acceleratingSection, true)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -231,9 +232,62 @@ function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{Dict}, setti
|
|||
pop!(formerSpeedLimits)
|
||||
end
|
||||
end
|
||||
return (CS, drivingCourse, formerSpeedLimits, accelerationSection, false)
|
||||
return (CS, drivingCourse, formerSpeedLimits, acceleratingSection, false)
|
||||
end # function considerFormerSpeedLimits!
|
||||
=#
|
||||
|
||||
function considerFormerSpeedLimit!(CS::Dict, drivingCourse::Vector{Dict}, acceleratingSection::Dict, settings::Dict, train::Dict, CSs::Vector{Dict}, currentSpeedLimit::Dict)
|
||||
# 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)
|
||||
for POI in pointsOfInterest
|
||||
|
@ -246,7 +300,7 @@ end #function getNextPointOfInterest
|
|||
|
||||
## 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.
|
||||
# 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})
|
||||
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 ! ! !")
|
||||
|
@ -256,7 +310,7 @@ function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::D
|
|||
drivingCourse[end][:behavior] = BS[:type]
|
||||
|
||||
# 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):
|
||||
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!
|
||||
|
||||
|
||||
## This function calculates the data points of the acceleration section.
|
||||
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the acceleration section
|
||||
function addAccelerationSection!(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)
|
||||
## 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 accelerating section
|
||||
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 addAcceleratingSection!(movingSection::Dict, csId::Integer, settings::Dict, train::Dict, ignoreBraking::Bool)
|
||||
CSs = movingSection[:characteristicSections]
|
||||
CS = CSs[csId]
|
||||
drivingCourse = movingSection[:drivingCourse]=#
|
||||
|
@ -336,40 +390,46 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
|
|||
(CS, drivingCourse) = addBreakFreeSection!(CS, drivingCourse, settings, train, CSs)
|
||||
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]
|
||||
(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
|
||||
|
||||
if ignoreBraking
|
||||
s_braking = 0.0
|
||||
end
|
||||
|
||||
# if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
|
||||
formerSpeedLimits = detectFormerSpeedLimits(CSs, CS[:id], drivingCourse[end], train[:length])
|
||||
# # 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])
|
||||
|
||||
# conditions for acceleration section
|
||||
# conditions for accelerating section
|
||||
targetSpeedReached = drivingCourse[end][:v] >= CS[:v_peak]
|
||||
trainAtEnd = drivingCourse[end][:s] >= CS[:s_exit]
|
||||
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
|
||||
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]
|
||||
brakingStartReached = false
|
||||
|
||||
while !targetSpeedReached && !trainAtEnd && tractionSurplus && !brakingStartReached
|
||||
currentStepSize = settings[:stepSize] # initialize the step size that can be reduced near intersections
|
||||
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
|
||||
if !ignoreBraking
|
||||
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
||||
end
|
||||
|
||||
while drivingCourse[end][:v] < CS[:v_peak] && drivingCourse[end][:s] +s_braking < CS[:s_exit] && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:F_T] > drivingCourse[end][:F_R] # as long as s_i + s_braking < s_CSexit
|
||||
while drivingCourse[end][:v] < CS[:v_peak] && drivingCourse[end][: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):
|
||||
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]
|
||||
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
|
||||
(CS, drivingCourse, formerSpeedLimits, BS, endOfCsReached) = considerFormerSpeedLimits!(CS, drivingCourse, settings, train, CSs, formerSpeedLimits, BS)
|
||||
if endOfCsReached
|
||||
return (CS, drivingCourse)
|
||||
end
|
||||
end
|
||||
# TODO: do the following that was done here in addAccelerationSection_without_Braking! currentStepSize = settings[:stepSize] # initialize the step size that can be reduced near intersections
|
||||
# if length(formerSpeedLimits) > 0 # If the rear of the train is located in a former characteristic section with lower speed limit check if is is possible to accelerate as normal
|
||||
# (CS, drivingCourse, formerSpeedLimits, BS, endOfCsReached) = considerFormerSpeedLimits!(CS, drivingCourse, settings, train, CSs, formerSpeedLimits, BS)
|
||||
# if endOfCsReached
|
||||
# return (CS, drivingCourse)
|
||||
# end
|
||||
# # TODO: do the following that was done here in addAcceleratingSection_without_Braking! ? currentStepSize = settings[:stepSize] # initialize the step size that can be reduced near intersections
|
||||
# end
|
||||
|
||||
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
|
||||
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
|
||||
if cycle < approximationLevel+1
|
||||
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
|
||||
# TODO 01/21 should not be needed anymore with diminishing.
|
||||
|
||||
elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R]
|
||||
#println("in CS",CS[:id]," accelerating cycle",cycle," case: F_T=", drivingCourse[end][:F_T]," <= F_R=",drivingCourse[end][:F_R]) # for testing
|
||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||
|
||||
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
|
||||
|
||||
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"
|
||||
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
|
||||
else
|
||||
|
@ -413,25 +477,50 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
|
|||
end
|
||||
|
||||
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"
|
||||
currentStepSize = CS[:v_peak]-drivingCourse[end-1][:v]
|
||||
else
|
||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||
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]
|
||||
#println("in CS",CS[:id]," accelerating cycle",cycle," case: s=", drivingCourse[end][:s]," == s_exit=",CS[:s_exit]) # for testing
|
||||
trainAtEnd = true
|
||||
break
|
||||
|
||||
elseif drivingCourse[end][:v] == CS[:v_peak]
|
||||
#println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," == v_peak=",CS[:v_peak]) # for testing
|
||||
targetSpeedReached = true
|
||||
break
|
||||
|
||||
elseif drivingCourse[end][:s] == nextPointOfInterest
|
||||
#println("in CS",CS[:id]," accelerating cycle",cycle," case: s=", drivingCourse[end][:s]," == nextPOI=",nextPointOfInterest) # for testing
|
||||
break
|
||||
|
||||
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
|
||||
# delete last data point for recalculating the last step with reduced step size
|
||||
pop!(drivingCourse)
|
||||
|
@ -441,7 +530,7 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
|
|||
if drivingCourse[end][:v] <= 0.0
|
||||
# 01/21 should not be needed anymore with diminishing.
|
||||
# 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",
|
||||
" 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])
|
||||
|
||||
elseif drivingCourse[end][:s] + s_braking > CS[:s_exit]
|
||||
brakingStartReached = true
|
||||
pop!(drivingCourse)
|
||||
pop!(BS[:dataPoints])
|
||||
if s_braking > 0.0
|
||||
brakingStartReached = true
|
||||
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
|
||||
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)
|
||||
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
|
||||
|
||||
end
|
||||
|
@ -474,10 +574,14 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
|
|||
end
|
||||
end
|
||||
end #for
|
||||
|
||||
if drivingCourse[end][:s] == CS[:s_exit]
|
||||
trainAtEnd = true
|
||||
end
|
||||
end #while
|
||||
|
||||
if length(BS[:dataPoints]) > 1 # TODO: is it still possible that it is <=1 although there is a separate diminishing section?
|
||||
# calculate the accumulated acceleration section information
|
||||
if length(BS[:dataPoints]) > 1
|
||||
# calculate the accumulated accelerating section information
|
||||
merge!(BS, Dict(:length => drivingCourse[end][:s] - BS[:s_entry], # total length (in m)
|
||||
:s_exit => drivingCourse[end][:s], # last position (in m)
|
||||
:t => drivingCourse[end][:t] - drivingCourse[BS[:dataPoints][1]][:t], # total running time (in s)
|
||||
|
@ -488,12 +592,12 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
|
|||
CS[:t] = CS[:t] + BS[:t] # total running time (in s)
|
||||
CS[:E] = CS[:E] + BS[:E] # total energy consumption (in Ws)
|
||||
|
||||
merge!(CS[:behaviorSections], Dict(:acceleration => BS))
|
||||
merge!(CS[:behaviorSections], Dict(:accelerating => BS))
|
||||
end
|
||||
end
|
||||
|
||||
return (CS, drivingCourse)
|
||||
end #function addAccelerationSection!
|
||||
end #function addAcceleratingSection!
|
||||
|
||||
|
||||
## 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)
|
||||
# 01/08 old with DataPoint as struct: old drivingCourse[end] = DataPoint(calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel]))
|
||||
calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
|
||||
s_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
|
||||
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])
|
||||
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)
|
||||
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
|
||||
# conditions for cruising section
|
||||
|
@ -530,25 +637,16 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
|
|||
while trainInPreviousCS && !trainAtEnd && tractionSurplus
|
||||
currentStepSize = settings[:stepSize]
|
||||
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
|
||||
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
|
||||
#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
|
||||
#TODO: maybe just consider former CS with different path resistance?
|
||||
|
||||
# acceleration (in m/s^2):
|
||||
drivingCourse[end][:a] = 0.0
|
||||
|
||||
# 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"
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
|
||||
else
|
||||
|
@ -591,7 +689,7 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
|
|||
elseif drivingCourse[end][:s] == nextPointOfInterest
|
||||
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")
|
||||
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
|
||||
if cycle < approximationLevel+1
|
||||
if drivingCourse[end][:v] < 0.0
|
||||
# 02/18 old: currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||
if settings[:stepVariable] == "v in m/s"
|
||||
currentStepSize = drivingCourse[end-1][:v]
|
||||
else
|
||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||
end
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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"
|
||||
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
|
||||
else
|
||||
|
@ -719,10 +819,12 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
|
|||
end
|
||||
|
||||
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
|
||||
break
|
||||
|
||||
elseif drivingCourse[end][:s] == nextPointOfInterest
|
||||
#println("in CS",CS[:id]," diminishing cycle",cycle," case: s=", drivingCourse[end][:s]," == nextPOI=",nextPointOfInterest) # for testing
|
||||
break
|
||||
|
||||
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",
|
||||
" 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
|
||||
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
|
||||
|
@ -794,8 +895,8 @@ end #function addDiminishingSection!
|
|||
## 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
|
||||
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
|
||||
#formerSpeedLimits = detectFormerSpeedLimits(CSs, CS[:id], drivingCourse[end], train[:length])
|
||||
# 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
|
||||
# with getCurrentSpeedLimit
|
||||
|
||||
# conditions for coasting section
|
||||
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])
|
||||
|
||||
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())
|
||||
drivingCourse[end][:i] = drivingCourse[end-1][:i]+1
|
||||
drivingCourse[end][:behavior] = BS[:type]
|
||||
push!(BS[:dataPoints], drivingCourse[end][:i])
|
||||
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
|
||||
|
||||
# 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])
|
||||
#println(drivingCourse[end][:i],". s=",drivingCourse[end][:s]," s_exit=", CS[:s_exit]," v_exit=", CS[:v_exit]," v=",drivingCourse[end][:v])
|
||||
end # while
|
||||
|
||||
# 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?
|
||||
if cycle < approximationLevel+1 && !targetSpeedReached
|
||||
if cycle < approximationLevel+1
|
||||
if drivingCourse[end][:v] < CS[:v_exit]
|
||||
if settings[:stepVariable] == "v in m/s"
|
||||
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
|
||||
end=#
|
||||
elseif drivingCourse[end][:s] > nextPointOfInterest
|
||||
# reset last point with lowering s to the nextPointOfInterest
|
||||
if settings[:stepVariable] == "s in m"
|
||||
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
|
||||
else
|
||||
|
@ -1068,68 +1170,6 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic
|
|||
# do nothing for example for drivingCourse[end][:s]==nextPointOfInterest
|
||||
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 #while
|
||||
|
||||
|
@ -1171,8 +1211,8 @@ function addStandstill!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, t
|
|||
end #function addStandstill!
|
||||
|
||||
function createBehaviorSection(type::String, s_entry::Real, v_entry::Real, startingPoint::Integer)
|
||||
BS= Dict(#:type => behavior, # type of behavior section: breakFree, clearing, acceleration, cruising, diminishing, coasting, braking or standstill
|
||||
:type => type, # 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", "accelerating", "cruising", "diminishing", "coasting", "braking" or "standstill"
|
||||
:length => 0.0, # total length (in m)
|
||||
:s_entry => s_entry, # first position (in m)
|
||||
:s_exit => 0.0, # last position (in m)
|
||||
|
@ -1189,7 +1229,7 @@ a data point is the smallest element of the driving course. One step of the step
|
|||
"""
|
||||
function createDataPoint()
|
||||
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
|
||||
:s => 0.0, # position (in m)
|
||||
:Δs => 0.0, # step size (in m)
|
||||
|
|
|
@ -12,11 +12,11 @@ using .Behavior
|
|||
|
||||
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)
|
||||
movingSection = createMovingSection(path, train[:v_limit])
|
||||
movingSection = secureBrakingBehavior!(movingSection, train[:a_braking])
|
||||
movingSection = secureAccelerationBehavior!(movingSection, settings, train)
|
||||
movingSection = secureAcceleratingBehavior!(movingSection, settings, train)
|
||||
movingSection = secureCruisingBehavior!(movingSection, settings, train)
|
||||
|
||||
return movingSection
|
||||
|
@ -119,8 +119,8 @@ function secureBrakingBehavior!(movingSection::Dict, a_braking::Real)
|
|||
return movingSection
|
||||
end #function secureBrakingBehavior!
|
||||
|
||||
## define the intersection velocities between the characterisitc sections to secure acceleration behavior
|
||||
function secureAccelerationBehavior!(movingSection::Dict, settings::Dict, train::Dict)
|
||||
## define the intersection velocities between the characterisitc sections to secure accelerating behavior
|
||||
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
|
||||
CSs = movingSection[:characteristicSections]
|
||||
|
||||
|
@ -134,12 +134,12 @@ function secureAccelerationBehavior!(movingSection::Dict, settings::Dict, train:
|
|||
|
||||
startingPoint[:s] = CS[:s_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]
|
||||
(CS, accelerationCourse) = addAccelerationSection!(CS, accelerationCourse, settings, train, CSs, true) # this function changes the accelerationCourse
|
||||
CS[:v_peak] = max(CS[:v_entry], accelerationCourse[end][:v])
|
||||
CS[:v_exit] = min(CS[:v_exit], CS[:v_peak], accelerationCourse[end][:v])
|
||||
(CS, acceleratingCourse) = addAcceleratingSection!(CS, acceleratingCourse, settings, train, CSs, true) # this function changes the acceleratingCourse
|
||||
CS[:v_peak] = max(CS[:v_entry], acceleratingCourse[end][:v])
|
||||
CS[:v_exit] = min(CS[:v_exit], CS[:v_peak], acceleratingCourse[end][:v])
|
||||
else #CS[:v_entry] == CS[:v_peak]
|
||||
# v_exit stays the same
|
||||
end #if
|
||||
|
@ -153,7 +153,7 @@ function secureAccelerationBehavior!(movingSection::Dict, settings::Dict, train:
|
|||
end #for
|
||||
|
||||
return movingSection
|
||||
end #function secureAccelerationBehavior!
|
||||
end #function secureAcceleratingBehavior!
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -136,13 +136,13 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict
|
|||
get(CSsOrig[csIdMax][:behaviorSections], :braking,
|
||||
get(CSsOrig[csIdMax][:behaviorSections], :coasting,
|
||||
get(CSsOrig[csIdMax][:behaviorSections], :cruising,
|
||||
get(CSsOrig[csIdMax][:behaviorSections], :acceleration,
|
||||
get(CSsOrig[csIdMax][:behaviorSections], :accelerating,
|
||||
get(CSsOrig[csIdMax][:behaviorSections], :clearing,
|
||||
get(CSsOrig[csIdMax][:behaviorSections], :breakFree,
|
||||
get(CSsOrig[csIdMax][:behaviorSections], :diminishing,
|
||||
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)
|
||||
lastIdOfSelectedCsOriginal = max(lastIdOfSelectedCsOriginal, CSsOrig[csIdMax][:behaviorSections][:diminishing][:dataPoints][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
|
||||
if difference!= 0
|
||||
# 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 bs in 1: length(allBs)
|
||||
if haskey(CSsOrig[csId][:behaviorSections], allBs[bs])
|
||||
|
@ -263,7 +263,7 @@ function copyMovingSection(original::Dict)
|
|||
end #function copyMovingSection
|
||||
|
||||
function copyCharacteristicSection(originalCS::Dict)
|
||||
allBs=[:breakFree, :clearing, :acceleration, :cruising, :diminishing, :coasting, :braking, :standstill]
|
||||
allBs=[:breakFree, :clearing, :accelerating, :cruising, :diminishing, :coasting, :braking, :standstill]
|
||||
copiedBSs = Dict()
|
||||
for bs in 1: length(allBs)
|
||||
if haskey(originalCS[:behaviorSections], allBs[bs])
|
||||
|
@ -295,8 +295,8 @@ function copyBehaviorSection(original::Dict)
|
|||
for i in 1:length(original[:dataPoints])
|
||||
push!(bsDataPoints, original[:dataPoints][i])
|
||||
end
|
||||
copiedBS = Dict(#:type => behavior, # type of behavior section: breakFree, clearing, acceleration, cruising, diminishing, coasting, braking or standstill
|
||||
:type => original[:type], # 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", "accelerating", "cruising", "diminishing", "coasting", "braking" or "standstill"
|
||||
:length => original[:length], # total length (in m)
|
||||
:s_entry => original[:s_entry], # first position (in m)
|
||||
:s_exit => original[:s_exit], # last position (in m)
|
||||
|
@ -320,7 +320,7 @@ function createEnergySavingModification()
|
|||
end #createEnergySavingModification
|
||||
|
||||
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
|
||||
for modNr in csIdMax+1:length(energySavingModifications)
|
||||
if energySavingModifications[modNr][:ratio]>0
|
||||
|
@ -522,7 +522,7 @@ end #function calculateRecoveryTime
|
|||
# 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)
|
||||
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
|
||||
if haskey(BSsOriginal, :cruising) && haskey(BSsOriginal, :diminishing)
|
||||
if BSsOriginal[:cruising][:dataPoints][1] > BSsOriginal[:diminishing][:dataPoints][1]
|
||||
|
@ -546,7 +546,7 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
|
|||
csModifiedInitial = copyCharacteristicSection(csOriginal)
|
||||
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
|
||||
if haskey(BSsModified, :coasting)
|
||||
csModifiedInitial[:E] = csModifiedInitial[:E] - BSsModified[:coasting][:E]
|
||||
|
@ -635,11 +635,11 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
|
|||
|
||||
|
||||
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
|
||||
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]
|
||||
E_diff = drivingCourse[diminishingSection[:dataPoints][end]][:E] - drivingCourse[diminishingSection[:dataPoints][end-1]][:E]
|
||||
pop!(diminishingSection[:dataPoints])
|
||||
|
@ -718,17 +718,17 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
|
|||
csModified[:E] = csModified[:E] + BSsModified[:breakFree][:E]
|
||||
csModified[:t] = csModified[:t] + BSsModified[:breakFree][:t]
|
||||
end
|
||||
if haskey(BSsOriginal, :clearing) # this section is needed before acceleration if the train wants to accelerate to a speed higher than the limit in a previous CS where parts of the train are still located
|
||||
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])
|
||||
merge!(BSsModified, Dict(:clearing=>clearingSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:clearing][:E]
|
||||
csModified[:t] = csModified[:t] + BSsModified[:clearing][:t]
|
||||
end
|
||||
if haskey(BSsOriginal, :acceleration)
|
||||
accelerationSection=copyBehaviorSection(BSsOriginal[:acceleration])
|
||||
merge!(BSsModified, Dict(:acceleration=>accelerationSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:acceleration][:E]
|
||||
csModified[:t] = csModified[:t] + BSsModified[:acceleration][:t]
|
||||
if haskey(BSsOriginal, :accelerating)
|
||||
acceleratingSection=copyBehaviorSection(BSsOriginal[:accelerating])
|
||||
merge!(BSsModified, Dict(:accelerating=>acceleratingSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:accelerating][:E]
|
||||
csModified[:t] = csModified[:t] + BSsModified[:accelerating][:t]
|
||||
end
|
||||
if haskey(BSsOriginal, :diminishing)
|
||||
diminishingSection=copyBehaviorSection(BSsOriginal[:diminishing])
|
||||
|
@ -769,7 +769,7 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
|
|||
|
||||
|
||||
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
|
||||
# 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[:t] = csModified[:t] + BSsModified[:breakFree][:t]
|
||||
end
|
||||
if haskey(BSsOriginal, :clearing) # this section is needed before acceleration if the train wants to accelerate to a speed higher than the limit in a previous CS where parts of the train are still located
|
||||
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])
|
||||
merge!(BSsModified, Dict(:clearing=>clearingSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:clearing][:E]
|
||||
csModified[:t] = csModified[:t] + BSsModified[:clearing][:t]
|
||||
end
|
||||
if haskey(BSsOriginal, :acceleration)
|
||||
accelerationSection=copyBehaviorSection(BSsOriginal[:acceleration])
|
||||
merge!(BSsModified, Dict(:acceleration=>accelerationSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:acceleration][:E]
|
||||
csModified[:t] = csModified[:t] + BSsModified[:acceleration][:t]
|
||||
if haskey(BSsOriginal, :accelerating)
|
||||
acceleratingSection=copyBehaviorSection(BSsOriginal[:accelerating])
|
||||
merge!(BSsModified, Dict(:accelerating=>acceleratingSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:accelerating][:E]
|
||||
csModified[:t] = csModified[:t] + BSsModified[:accelerating][:t]
|
||||
end
|
||||
if haskey(BSsOriginal, :cruising)
|
||||
cruisingSection=copyBehaviorSection(BSsOriginal[:cruising])
|
||||
|
@ -815,7 +815,7 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
|
|||
|
||||
diminishingSection=copyBehaviorSection(BSsOriginal[:diminishing])
|
||||
if length(diminishingSection[:dataPoints]) > 2
|
||||
# remove the last diminishing waypoint
|
||||
# remove the last diminishing data point
|
||||
pop!(diminishingSection[:dataPoints])
|
||||
|
||||
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 # 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)
|
||||
# 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)
|
||||
BSsOriginal = csOriginal[:behaviorSections]
|
||||
if haskey(BSsOriginal, :acceleration) && csOriginal[:v_peak] > csOriginal[:v_entry] && csOriginal[:v_peak] > csOriginal[:v_exit]
|
||||
accelerationSection = copyBehaviorSection(BSsOriginal[:acceleration])
|
||||
if haskey(BSsOriginal, :accelerating) && csOriginal[:v_peak] > csOriginal[:v_entry] && csOriginal[:v_peak] > csOriginal[:v_exit]
|
||||
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?
|
||||
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
|
||||
|
||||
# copy csOriginal to csModified
|
||||
|
@ -902,14 +902,14 @@ function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict
|
|||
csModified[:E] = csModified[:E] + BSsModified[:breakFree][:E]
|
||||
csModified[:t] = csModified[:t] + BSsModified[:breakFree][:t]
|
||||
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])
|
||||
merge!(BSsModified, Dict(:diminishing=>diminishingSection))
|
||||
csModified[:E] = csModified[:E] + BSsModified[:diminishing][:E]
|
||||
csModified[:t] = csModified[:t] + BSsModified[:diminishing][:t]
|
||||
end
|
||||
|
||||
if length(accelerationSection[:dataPoints]) > 2
|
||||
if length(acceleratingSection[:dataPoints]) > 2
|
||||
if haskey(BSsOriginal, :clearing)
|
||||
clearingSection=copyBehaviorSection(BSsOriginal[:clearing])
|
||||
merge!(BSsModified, Dict(:clearing=>clearingSection))
|
||||
|
@ -917,23 +917,23 @@ function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict
|
|||
csModified[:t] = csModified[:t] + BSsModified[:clearing][:t]
|
||||
end
|
||||
|
||||
# remove the last acceleration waypoint from the accelerationSection
|
||||
pop!(accelerationSection[:dataPoints])
|
||||
energySavingStartId = accelerationSection[:dataPoints][end]
|
||||
# remove the last data point from the acceleratingSection
|
||||
pop!(acceleratingSection[:dataPoints])
|
||||
energySavingStartId = acceleratingSection[:dataPoints][end]
|
||||
|
||||
accelerationSection[:v_exit]=drivingCourse[energySavingStartId][:v] # exit speed (in m/s)
|
||||
accelerationSection[:s_exit]=drivingCourse[energySavingStartId][:s] # last position (in m)
|
||||
accelerationSection[:length]=accelerationSection[:s_exit]-accelerationSection[:s_entry] # total length (in m)
|
||||
accelerationSection[:t]=drivingCourse[energySavingStartId][:t]-drivingCourse[accelerationSection[:dataPoints][1]][:t] # total running time (in s)
|
||||
accelerationSection[:E]=drivingCourse[energySavingStartId][:E]-drivingCourse[accelerationSection[:dataPoints][1]][:E] # total energy consumption (in Ws)
|
||||
acceleratingSection[:v_exit]=drivingCourse[energySavingStartId][:v] # exit speed (in m/s)
|
||||
acceleratingSection[:s_exit]=drivingCourse[energySavingStartId][:s] # last position (in m)
|
||||
acceleratingSection[:length]=acceleratingSection[:s_exit]-acceleratingSection[:s_entry] # total length (in m)
|
||||
acceleratingSection[:t]=drivingCourse[energySavingStartId][:t]-drivingCourse[acceleratingSection[:dataPoints][1]][:t] # total running time (in s)
|
||||
acceleratingSection[:E]=drivingCourse[energySavingStartId][:E]-drivingCourse[acceleratingSection[:dataPoints][1]][:E] # total energy consumption (in Ws)
|
||||
|
||||
merge!(BSsModified, Dict(:acceleration=>accelerationSection))
|
||||
csModified[:E] = csModified[:E] + accelerationSection[:E]
|
||||
csModified[:t] = csModified[:t] + accelerationSection[:t]
|
||||
merge!(BSsModified, Dict(:accelerating=>acceleratingSection))
|
||||
csModified[:E] = csModified[:E] + acceleratingSection[:E]
|
||||
csModified[:t] = csModified[:t] + acceleratingSection[:t]
|
||||
|
||||
else
|
||||
# The acceleration section is only one step. This step is removed and if there is a clearing section it will be combined with the new cruising section.
|
||||
energySavingStartId=get(BSsOriginal, :clearing, get(BSsOriginal, :acceleration, Dict(:dataPoints =>[0])))[:dataPoints][1]
|
||||
# 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, :accelerating, Dict(:dataPoints =>[0])))[:dataPoints][1]
|
||||
end
|
||||
|
||||
# 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)
|
||||
else # time loss is to high. so there is no energy saving modification for this CS with the available recovery time
|
||||
# 09/06 old: else # time loss is to high and the CS has to be calculated again with larger acceleration section (so with a smaller reduction of the acceleration section)
|
||||
# 09/06 old: accelerationReduction=min(accelerationReduction/10, csModified[:v_peak]-csModified[:v_entry], csModified[:v_peak]-csModified[:v_exit])
|
||||
# 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: acceleratingReduction=min(acceleratingReduction/10, csModified[:v_peak]-csModified[:v_entry], csModified[:v_peak]-csModified[:v_exit])
|
||||
# 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?
|
||||
|
@ -992,7 +992,7 @@ function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict
|
|||
|
||||
|
||||
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?
|
||||
return (csOriginal, drivingCourse, false)
|
||||
end #if haskey
|
||||
|
@ -1001,8 +1001,8 @@ end # function decreaseMaximumVelocity
|
|||
# combination of method 1 and method 2
|
||||
function combineEnergySavingMethods(csOriginal::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, allCSs::Vector{Dict}, t_recoveryAvailable::AbstractFloat)
|
||||
BSsOriginal = csOriginal[:behaviorSections]
|
||||
# if haskey(BSsOriginal, :acceleration) && (haskey(BSsOriginal, :braking) || haskey(BSsOriginal, :coasting)) && csOriginal[:v_peak]>csOriginal[:v_entry] && csOriginal[:v_peak]>csOriginal[:v_exit]
|
||||
if haskey(BSsOriginal, :acceleration) && (haskey(BSsOriginal, :braking) || haskey(BSsOriginal, :coasting)) && drivingCourse[get(BSsOriginal, :acceleration, Dict(:dataPoints =>[0]))[:dataPoints][end]][:v] > max(csOriginal[:v_entry], 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, :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
|
||||
csCombined = copyCharacteristicSection(csOriginal)
|
||||
|
||||
|
@ -1034,7 +1034,7 @@ function combineEnergySavingMethods(csOriginal::Dict, drivingCourse::Vector{Dict
|
|||
end # while
|
||||
return (csCombined, drivingCourseCombined, (ΔE>0.0))# && Δt>0.0))
|
||||
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?
|
||||
return (csOriginal, drivingCourse, false)
|
||||
end #if
|
||||
|
|
|
@ -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
|
||||
|
||||
using CSV, DataFrames, Dates
|
||||
|
@ -39,17 +46,17 @@ function createCsvFile(movingSection::Dict, dataPointsToExport::Vector{Dict}, op
|
|||
stepVariable = settings[:stepVariable]
|
||||
stepSize = string(settings[:stepSize])
|
||||
|
||||
# create summarized data block
|
||||
summarizedData = Array{Any, 1}[]
|
||||
# create accumulated data block
|
||||
accumulatedData = Array{Any, 1}[]
|
||||
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]]
|
||||
push!(summarizedData, row) # push row to summarizedData
|
||||
push!(accumulatedData, row) # push row to accumulatedData
|
||||
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
|
||||
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
|
||||
|
||||
|
@ -57,15 +64,15 @@ function createCsvFile(movingSection::Dict, dataPointsToExport::Vector{Dict}, op
|
|||
allColumns=Array{Any,1}[]
|
||||
push!(allColumns, ["path name", "train name", "operation mode", "mass model", "step variable", "step size", ""])
|
||||
push!(allColumns, [pathName, trainName, operationMode, massModel, stepVariable, stepSize, ""])
|
||||
for column in 3:length(summarizedData[1])
|
||||
for column in 3:length(accumulatedData[1])
|
||||
push!(allColumns, ["", "", "", "", "", "", ""])
|
||||
end # for
|
||||
|
||||
# add driving data to the array
|
||||
header = summarizedData[1]
|
||||
for column in 1:length(summarizedData[1])
|
||||
header = accumulatedData[1]
|
||||
for column in 1:length(accumulatedData[1])
|
||||
push!(allColumns[column], header[column])
|
||||
for row in summarizedData[2:end]
|
||||
for row in accumulatedData[2:end]
|
||||
push!(allColumns[column], row[column])
|
||||
end
|
||||
end # for
|
||||
|
|
|
@ -26,6 +26,10 @@ export calculateDrivingDynamics
|
|||
approximationLevel = 6 # value for approximation to intersections and precisely calculated digits
|
||||
# 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`.
|
||||
|
||||
"""
|
||||
|
@ -89,7 +93,7 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
s_breakFree = get(BSs, :breakFree, Dict(:length=>0.0))[:length]
|
||||
s_clearing = get(BSs, :clearing, Dict(:length=>0.0))[:length]
|
||||
s_acceleration = get(BSs, :acceleration, Dict(:length=>0.0))[:length]
|
||||
s_accelerating = get(BSs, :accelerating, Dict(:length=>0.0))[:length]
|
||||
s_braking = calcBrakingDistance(CS[:v_peak], CS[:v_exit], train[:a_braking])
|
||||
# old: s_braking = max(0.0, ceil((CS[:v_exit]^2-CS[:v_peak]^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
|
||||
|
||||
# calculate the cruising sections length
|
||||
s_cruising = max(0.0, CS[:length] - s_breakFree - s_clearing - s_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
|
||||
CS[:behaviorSections] = Dict()
|
||||
|
@ -163,7 +167,7 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
|
|||
CS[:t] = 0.0
|
||||
|
||||
# TODO 02/09: could there be a better structure for processing the different moving phases? (this if fork was added on 2022/09/02)
|
||||
if s_clearing > 0.0 && s_breakFree + s_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")
|
||||
end
|
||||
|
||||
|
@ -172,12 +176,12 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
|
|||
elseif s_cruising > 0.0 || s_braking == 0.0
|
||||
|
||||
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
|
||||
|
||||
if CS[:s_exit]-drivingCourse[end][:s]-max(0.0, (CS[:v_exit]^2-drivingCourse[end][:v]^2)/2/train[:a_braking]) < -0.001 # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
|
||||
println("ERROR: After accelerating in CS ",csId," the braking distance is too short!")
|
||||
println(" before 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])
|
||||
end
|
||||
|
||||
|
@ -188,10 +192,10 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
|
|||
(CS, drivingCourse)=addCruisingSection!(CS, drivingCourse, s_cruising, settings, train, CSs, "cruising")
|
||||
end
|
||||
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]
|
||||
# old 02/22 (CS, drivingCourse)=addAccelerationSectionUntilBraking!(CS, drivingCourse, settings, train, CSs)
|
||||
(CS, drivingCourse) = addAccelerationSection!(CS, drivingCourse, settings, train, CSs, false)
|
||||
# old 02/22 (CS, drivingCourse)=addAcceleratingSectionUntilBraking!(CS, drivingCourse, settings, train, CSs)
|
||||
(CS, drivingCourse) = addAcceleratingSection!(CS, drivingCourse, settings, train, CSs, false)
|
||||
end #if
|
||||
end #if
|
||||
|
||||
|
|
Loading…
Reference in New Issue