Integrate calculation for additional points of interest

development
Max Kannenberg 2022-01-22 03:11:43 +01:00
parent 8802ef7bc7
commit 917a16782d
13 changed files with 763 additions and 470 deletions

View File

@ -21,9 +21,10 @@ Review the settings.yaml file for your appropriate settings.
include("../src/TrainRun.jl") include("../src/TrainRun.jl")
using .TrainRun using .TrainRun
train = "data/trains/train_freight_V90withOreConsist.yaml" train_directory = "data/trains/train_freight_V90withOreConsist.yaml"
running_path = "data/paths/path_1_10km_nConst_vConst.yaml" running_path_directory = "data/paths/path_1_10km_nConst_vConst.yaml"
settings = "data/settings.yaml" settings_directory = "data/settings.yaml"
(train, running_path, settings) = importYamlFiles(train_directory, running_path_directory, setting_directory)
train_run = calculateDrivingDynamics(train, running_path, settings) train_run = calculateDrivingDynamics(train, running_path, settings)
``` ```

View File

@ -2,6 +2,7 @@
--- ---
path: path:
name: "10 km, no gradient, 160 km/h" name: "10 km, no gradient, 160 km/h"
pointsOfInterest: [999, 2000, 3333.3, 5000, 7777, 9000, 9500.95] # points of interest: positions in m
sectionStarts: # with path speed limt (in m/s) # [s in m, v_limit in m/s, f_Rp in ‰] sectionStarts: # with path speed limt (in m/s) # [s in m, v_limit in m/s, f_Rp in ‰]
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp in ‰] sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp in ‰]
- [0, 160, 0] - [0, 160, 0]

View File

@ -2,6 +2,7 @@
--- ---
path: path:
name: "10 km, different gradient, 160 km/h" name: "10 km, different gradient, 160 km/h"
pointsOfInterest: [999, 2000, 3333.3, 5000, 7777, 9000, 9500.95] # points of interest: positions in m
sectionStarts: # with path speed limt (in m/s) # [s in m, v_limit in m/s, f_Rp in ‰] sectionStarts: # with path speed limt (in m/s) # [s in m, v_limit in m/s, f_Rp in ‰]
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp in ‰] sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp in ‰]
- [0, 160, 0] - [0, 160, 0]

View File

@ -2,6 +2,7 @@
--- ---
path: path:
name: "10 km, no gradient, different speed limits" name: "10 km, no gradient, different speed limits"
pointsOfInterest: [999, 2000, 3333.3, 5000, 7777, 9000, 9500.95] # points of interest: positions in m
sectionStarts: # with path speed limt (in m/s) # [s in m, v_limit in m/s, f_Rp in ‰] sectionStarts: # with path speed limt (in m/s) # [s in m, v_limit in m/s, f_Rp in ‰]
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp in ‰] sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp in ‰]
- [0, 160, 0.0] - [0, 160, 0.0]

View File

@ -125,10 +125,10 @@ function plotDrivingCourse(drivingCourseMinimumRunningTime::Vector{Dict},driving
println("Plots for different variables have been created.") println("Plots for different variables have been created.")
end #function plotDrivingCourse end #function plotDrivingCourse
function printImportantValues(drivingCourse::Vector{Dict}) function printImportantValues(dataPoints::Vector{Dict})
println("i behavior s in m v in km/h t in min a in m/s^2 F_R in k N F_T in k N E in k Wh") println("i behavior s in m v in km/h t in min a in m/s^2 F_R in k N F_T in k N E in k Wh")
for i in 1:length(drivingCourse) for i in 1:length(dataPoints)
println(drivingCourse[i][:i],". ",drivingCourse[i][:s]," ",drivingCourse[i][:v]*3.6," ",drivingCourse[i][:t]/60," ",drivingCourse[i][:a]," ",drivingCourse[i][:F_R]/1000," ",drivingCourse[i][:F_T]/1000," ",drivingCourse[i][:E]/3600/1000) println(dataPoints[i][:i],". ",dataPoints[i][:behavior]," ",dataPoints[i][:s]," ",dataPoints[i][:v]*3.6," ",dataPoints[i][:t]/60," ",dataPoints[i][:a]," ",dataPoints[i][:F_R]/1000," ",dataPoints[i][:F_T]/1000," ",dataPoints[i][:E]/3600/1000)
end #for end #for
println("i behavior s in m v in km/h t in min a in m/s^2 F_R in k N F_T in k N E in k Wh") println("i behavior s in m v in km/h t in min a in m/s^2 F_R in k N F_T in k N E in k Wh")
end #function printImportantValues end #function printImportantValues
@ -136,13 +136,13 @@ end #function printImportantValues
function printSectionInformation(movingSection::Dict) function printSectionInformation(movingSection::Dict)
CSs::Vector{Dict} = movingSection[:characteristicSections] CSs::Vector{Dict} = movingSection[:characteristicSections]
println("MS mit length=", movingSection[:length]," mit 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, :acceleration, :cruising, :diminishing, :coasting, :braking, :standstill]
for csId in 1:length(CSs) for csId in 1:length(CSs)
println("CS ",csId," mit length=", CSs[csId][:length]," mit 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)
if haskey(CSs[csId][:behaviorSections], allBs[bs]) if haskey(CSs[csId][:behaviorSections], allBs[bs])
println("BS ",allBs[bs], " mit s_entry=", CSs[csId][:behaviorSections][allBs[bs]][:s_entry], " und t=", CSs[csId][:behaviorSections][allBs[bs]][:t]) println("BS ",allBs[bs], " with s_entry=", CSs[csId][:behaviorSections][allBs[bs]][:s_entry], " and t=", CSs[csId][:behaviorSections][allBs[bs]][:t])
# for point in 1:length(CSs[csId][:behaviorSections][allBs[bs]][:dataPoints]) # for point in 1:length(CSs[csId][:behaviorSections][allBs[bs]][:dataPoints])
# println(CSs[csId][:behaviorSections][allBs[bs]][:dataPoints][point]) # println(CSs[csId][:behaviorSections][allBs[bs]][:dataPoints][point])
# end # end

View File

@ -8,7 +8,7 @@ export addAccelerationSection!, addAccelerationSectionUntilBraking!, addCruising
calculateForces!, createDataPoint, calculateForces!, createDataPoint,
# export functions from DrivingDynamics # export functions from DrivingDynamics
calcBrakingStartVelocity, calcBrakingDistance calcBrakingDistance, calcBrakingStartVelocity
approximationLevel = 6 # value for approximation to intersections TODO further explanation (e.g. approximationLevel = 3 -> with stepSize 10 m the approximation will be calculated accurate on 10 mm ; 1s -> 1 ms; 1 km/h -> 3.6 mm/s) approximationLevel = 6 # value for approximation to intersections TODO further explanation (e.g. approximationLevel = 3 -> with stepSize 10 m the approximation will be calculated accurate on 10 mm ; 1s -> 1 ms; 1 km/h -> 3.6 mm/s)
@ -55,24 +55,15 @@ end #function calculateTractiveEffort
""" """
calculate and return the path resistance dependend on the trains position and mass model calculate and return the path resistance dependend on the trains position and mass model
""" """
function calculatePathResistance(s::Real, massModel::String, train::Dict, CSs::Vector{Dict}) function calculatePathResistance(CSs::Vector{Dict}, csId::Integer, s::Real, massModel::String, train::Dict)
# looking for the characteristic section with the trains head position
id=length(CSs)
while s<CSs[id][:s_entry]
id=id-1
if id==0
println("s=",s," MS[:s_entry]=",CSs[1][:s_entry])
end
end #while
if massModel == "mass point" if massModel == "mass point"
pathResistance = calcForceFromCoefficient(CSs[id][:r_path], train[:m_train]) pathResistance = calcForceFromCoefficient(CSs[csId][:r_path], train[:m_train])
elseif massModel == "homogeneous strip" elseif massModel == "homogeneous strip"
pathResistance = 0.0 pathResistance = 0.0
while id > 0 && s-train[:length] < CSs[id][:s_exit] while csId > 0 && s-train[:length] < CSs[csId][:s_exit]
pathResistance = pathResistance + (min(s, CSs[id][:s_exit]) - max(s-train[:length], CSs[id][:s_entry])) / train[:length] * calcForceFromCoefficient(CSs[id][:r_path], train[:m_train]) pathResistance = pathResistance + (min(s, CSs[csId][:s_exit]) - max(s-train[:length], CSs[csId][:s_entry])) / train[:length] * calcForceFromCoefficient(CSs[csId][:r_path], train[:m_train])
id = id-1 csId = csId-1
if id == 0 if csId == 0
# TODO: currently for values < movingSection[:s_entry] the values of movingSection[:s_entry] will be used # TODO: currently for values < movingSection[:s_entry] the values of movingSection[:s_entry] will be used
return pathResistance + (CSs[1][:s_entry] - (s-train[:length])) / train[:length] * calcForceFromCoefficient(CSs[1][:r_path], train[:m_train]) return pathResistance + (CSs[1][:s_entry] - (s-train[:length])) / train[:length] * calcForceFromCoefficient(CSs[1][:r_path], train[:m_train])
end #if end #if
@ -85,12 +76,12 @@ end #function calculatePathResistance
""" """
calculate and return tractive and resisting forces for a data point calculate and return tractive and resisting forces for a data point
""" """
function calculateForces!(dataPoint::Dict, train::Dict, massModel::String, CSs::Vector{Dict}, bsType::String) function calculateForces!(dataPoint::Dict, CSs::Vector{Dict}, csId::Integer, bsType::String, train::Dict, massModel::String)
# calculate resisting forces # calculate resisting forces
dataPoint[:R_traction] = calcTractionUnitResistance(dataPoint[:v], train) dataPoint[:R_traction] = calcTractionUnitResistance(dataPoint[:v], train)
dataPoint[:R_wagons] = calcWagonsResistance(dataPoint[:v], train) dataPoint[:R_wagons] = calcWagonsResistance(dataPoint[:v], train)
dataPoint[:R_train] = dataPoint[:R_traction] + dataPoint[:R_wagons] dataPoint[:R_train] = dataPoint[:R_traction] + dataPoint[:R_wagons]
dataPoint[:R_path] = calculatePathResistance(dataPoint[:s], massModel, train, CSs) dataPoint[:R_path] = calculatePathResistance(CSs, csId, dataPoint[:s], massModel, train)
dataPoint[:F_R] = dataPoint[:R_train] + dataPoint[:R_path] dataPoint[:F_R] = dataPoint[:R_train] + dataPoint[:R_path]
# calculate tractive effort # calculate tractive effort
@ -102,14 +93,13 @@ function calculateForces!(dataPoint::Dict, train::Dict, massModel::String, CSs:
dataPoint[:F_T] = 0.0 dataPoint[:F_T] = 0.0
end end
return dataPoint return dataPoint
end #function calculateForces end #function calculateForces!
""" """
TODO TODO
""" """
function moveAStep(previousPoint::Dict, stepVariable::String, stepSize::Real, csId::Integer) function moveAStep(previousPoint::Dict, stepVariable::String, stepSize::Real, csId::Integer)
# 12/15 old with float stepsize function moveAStep(previousPoint::Dict, stepVariable::String, stepSize::AbstractFloat, csId::Integer)
# stepSize is the currentStepSize depending on the accessing function # stepSize is the currentStepSize depending on the accessing function
# TODO: csId is only for error messages. Should it be removed? # TODO: csId is only for error messages. Should it be removed?
#= 08/31 TODO: How to check if the train stopps during this step? I should throw an error myself that I catch in higher hierarchies. =# #= 08/31 TODO: How to check if the train stopps during this step? I should throw an error myself that I catch in higher hierarchies. =#
@ -223,6 +213,16 @@ function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{Dict}, setti
return (CS, drivingCourse, formerSpeedLimits, accelerationSection, false) return (CS, drivingCourse, formerSpeedLimits, accelerationSection, false)
end # function considerFormerSpeedLimits! end # function considerFormerSpeedLimits!
function getNextPointOfInterest(pointsOfInterest::Vector{Real}, s::Real)
for POI in pointsOfInterest
if POI > s
return POI
end
end
error("ERROR in getNextPointOfInterest: There is no POI ist higher than s.")
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 acceleration section
@ -232,7 +232,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], train, settings[:massModel], CSs, "acceleration") # currently the tractive effort is calculated like in the acceleration section calculateForces!(drivingCourse[end], CSs, CS[:id], "acceleration", train, settings[:massModel]) # currently the tractive effort is calculated like in the acceleration 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])
@ -242,11 +242,41 @@ function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::D
error("ERROR: a=0 m/s^2 in the breakFree section !") error("ERROR: a=0 m/s^2 in the breakFree section !")
end end
# creating the next data point brokenFree = false
calculationCycle = 1
nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])
while !brokenFree
# create the next data point
#TODO: instead of the while loop this two line would also be enough for stepVariale s: stepSize = min(settings[:stepSize], getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])-BS[:s_entry])
#push!(drivingCourse, moveAStep(drivingCourse[end], "s in m", stepSize, CS[:id]))
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], settings[:stepSize], CS[:id])) push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], settings[:stepSize], CS[:id]))
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
push!(BS[:dataPoints], drivingCourse[end][:i]) push!(BS[:dataPoints], drivingCourse[end][:i])
# check if a point of interest was missed
if drivingCourse[end][:s] > nextPointOfInterest
if settings[:stepVariable] == "s in m"
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
else
currentStepSize = settings[:stepSize] / 10.0^cycle
end
if calculationCycle <= approximationLevel
calculationCycle = calculationCycle +1
# delete last data point for recalculating the last step with reduced step size
pop!(drivingCourse)
pop!(BS[:dataPoints])
else
drivingCourse[end][:s] = nextPointOfInterest # rounding s down to nextPointOfInterest
brokenFree = true
break#free
end
else
brokenFree = true
break#free
end #if
end #while
# calculate the accumulated breakFree section information # calculate the accumulated breakFree section information
merge!(BS, Dict(:length => drivingCourse[end][:s] - BS[:s_entry], # total length (in m) merge!(BS, Dict(:length => drivingCourse[end][:s] - BS[:s_entry], # total length (in m)
:s_exit => drivingCourse[end][:s], # last position (in m) :s_exit => drivingCourse[end][:s], # last position (in m)
@ -266,14 +296,19 @@ end #function addBreakFreeSection!
## This function calculates the data points of the acceleration section. ## This function calculates the data points of the acceleration section.
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the acceleration section # Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the acceleration section
function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}) function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict})
if drivingCourse[end][:v]==0.0 #=if drivingCourse would also be part of movingSectiong: function addAccelerationSection!(movingSection::Dict, csId::Integer, settings::Dict, train::Dict)
CSs = movingSection[:characteristicSections]
CS = CSs[csId]
drivingCourse = movingSection[:drivingCourse]=#
if drivingCourse[end][:v] == 0.0
(CS, drivingCourse) = addBreakFreeSection!(CS, drivingCourse, settings, train, CSs) (CS, drivingCourse) = addBreakFreeSection!(CS, drivingCourse, settings, train, CSs)
end #if end #if
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "acceleration") calculateForces!(drivingCourse[end], CSs, CS[:id], "acceleration", 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], train, settings[:massModel], CSs, "acceleration") calculateForces!(drivingCourse[end], CSs, CS[:id], "acceleration", train, settings[:massModel])
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 tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
@ -290,11 +325,11 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
BS = createBehaviorSection("acceleration", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) BS = createBehaviorSection("acceleration", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
currentStepSize=settings[:stepSize] # initialize the step size that can be reduced near intersections while !targetSpeedReached && !trainAtEnd && tractionSurplus
currentStepSize = settings[:stepSize] # initialize the step size that can be reduced near intersections
nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
while drivingCourse[end][:v] < CS[:v_peak] && drivingCourse[end][:s] < CS[:s_exit] && drivingCourse[end][:F_T] > drivingCourse[end][:F_R] while drivingCourse[end][:v] < CS[:v_peak] && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
# traction effort and resisting forces (in N)
# 11/22 calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type])
# 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])
@ -303,16 +338,17 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id])) push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
push!(BS[:dataPoints], drivingCourse[end][:i]) push!(BS[:dataPoints], drivingCourse[end][:i])
# calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type])
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 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) (CS, drivingCourse, formerSpeedLimits, BS, endOfCsReached) = considerFormerSpeedLimits!(CS, drivingCourse, settings, train, CSs, formerSpeedLimits, BS)
if endOfCsReached if endOfCsReached
return (CS, drivingCourse) return (CS, drivingCourse)
end #if end #if
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
end #if end #if
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type])
# traction effort and resisting forces (in N)
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
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
@ -320,27 +356,33 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
if drivingCourse[end][:v] <= 0.0 if drivingCourse[end][:v] <= 0.0
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
elseif drivingCourse[end][:s]>CS[:s_exit] elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R]
currentStepSize = settings[:stepSize] / 10.0^cycle
elseif drivingCourse[end][:s] > nextPointOfInterest
if settings[:stepVariable] == "s in m" if settings[:stepVariable] == "s in m"
currentStepSize=CS[:s_exit]-drivingCourse[end-1][:s] currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
else else
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
end end
elseif drivingCourse[end][:v] > CS[:v_peak] elseif drivingCourse[end][:v] > CS[:v_peak]
if settings[:stepVariable] == "v in m/s" if settings[:stepVariable] == "v in m/s"
currentStepSize=CS[:v_peak]-drivingCourse[end-1][:v] currentStepSize = CS[:v_peak]-drivingCourse[end-1][:v]
else else
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
end end
elseif drivingCourse[end][:s] == CS[:s_exit] elseif drivingCourse[end][:s] == CS[:s_exit]
trainAtEnd = true
break break
elseif drivingCourse[end][:v] == CS[:v_peak] elseif drivingCourse[end][:v] == CS[:v_peak]
targetSpeedReached = true
break
elseif drivingCourse[end][:s] == nextPointOfInterest
break break
elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R]
currentStepSize = settings[:stepSize] / 10.0^cycle
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") 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")
@ -348,7 +390,6 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
# delete last data point for recalculating the last step with reduced step size # delete last data point for recalculating the last step with reduced step size
pop!(drivingCourse) pop!(drivingCourse)
pop!(BS[:dataPoints]) pop!(BS[:dataPoints])
else # if the level of approximation is reached else # if the level of approximation is reached
if drivingCourse[end][:v] <= 0.0 if drivingCourse[end][:v] <= 0.0
# push!(BS[:dataPoints], drivingCourse[end][:i]) # push!(BS[:dataPoints], drivingCourse[end][:i])
@ -357,20 +398,29 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
" F_T=",drivingCourse[end-1][:F_T]," N R_traction=",drivingCourse[end-1][:R_traction]," N R_wagons=",drivingCourse[end-1][:R_wagons]," N R_path=",drivingCourse[end-1][:R_path]," N.") " F_T=",drivingCourse[end-1][:F_T]," N R_traction=",drivingCourse[end-1][:R_traction]," N R_wagons=",drivingCourse[end-1][:R_wagons]," N R_path=",drivingCourse[end-1][:R_path]," N.")
elseif drivingCourse[end][:v] > CS[:v_peak] elseif drivingCourse[end][:v] > CS[:v_peak]
targetSpeedReached = true
pop!(drivingCourse) pop!(drivingCourse)
pop!(BS[:dataPoints]) pop!(BS[:dataPoints])
elseif drivingCourse[end][:s] > CS[:s_exit]
drivingCourse[end][:s] = CS[:s_exit] # rounding s down to s_exit elseif drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:s] = nextPointOfInterest # rounding s down to nextPointOfInterest
elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R] elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R]
tractionSurplus = false
(CS, drivingCourse) = addDiminishingSection!(CS, drivingCourse, settings, train, CSs) (CS, drivingCourse) = addDiminishingSection!(CS, drivingCourse, settings, train, CSs)
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type]) calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
else else
end #if
# TODO is it possible to put this into to the if-fork?
if drivingCourse[end][:s] == CS[:s_exit]
trainAtEnd = true
end end
end end #if
end #for end #for
end #while
if length(BS[:dataPoints]) > 1 # it is possible that the acceleration starts at v_peak, accelerates a step, is to high and drops the last point. then there is only one data point which is not a section. if length(BS[:dataPoints]) > 1 # it is possible that the acceleration starts at v_peak, accelerates a step, is to high and drops the last point. then there is only one data point which is not a section.
# calculate the accumulated acceleration section information # calculate the accumulated acceleration section information
@ -388,9 +438,9 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
println("WARNING, v is getting to high at the end of the acceleration section. v=",drivingCourse[end][:v] ," > v_peak=",CS[:v_peak]) println("WARNING, v is getting to high at the end of the acceleration section. v=",drivingCourse[end][:v] ," > v_peak=",CS[:v_peak])
end end
merge!(CS[:behaviorSections], Dict(:acceleration=>BS)) merge!(CS[:behaviorSections], Dict(:acceleration => BS))
end
end end
end # else: just return the given data point number without changes due to the acceleration section
return (CS, drivingCourse) return (CS, drivingCourse)
end #function addAccelerationSection! end #function addAccelerationSection!
@ -398,44 +448,45 @@ end #function addAccelerationSection!
## This function calculates the data points of the acceleration section. ## This function calculates the data points of the acceleration section.
function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}) function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict})
if drivingCourse[end][:v]==0.0 if drivingCourse[end][:v] == 0.0
(CS, drivingCourse) = addBreakFreeSection!(CS, drivingCourse, settings, train, CSs) (CS, drivingCourse) = addBreakFreeSection!(CS, drivingCourse, settings, train, CSs)
end #if end #if
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "acceleration") calculateForces!(drivingCourse[end], CSs, CS[:id], "acceleration", 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], train, settings[:massModel], CSs, "acceleration") calculateForces!(drivingCourse[end], CSs, CS[:id], "acceleration", train, settings[:massModel])
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 tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
formerSpeedLimits = detectFormerSpeedLimits(CSs, CS[:id], drivingCourse[end], train[:length]) formerSpeedLimits = detectFormerSpeedLimits(CSs, CS[:id], drivingCourse[end], train[:length])
# conditions for acceleration section
targetSpeedReached = drivingCourse[end][:v] >= CS[:v_peak]
trainAtEnd = drivingCourse[end][:s] >= CS[:s_exit]
tractionSurplus = drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
# 11/23 old without F_T>F_R: if drivingCourse[end][:v] < CS[:v_peak] && drivingCourse[end][:s]<CS[:s_exit] # use the conditions for the acceleration section
if drivingCourse[end][:v] < CS[:v_peak] && drivingCourse[end][:s] < CS[:s_exit] && drivingCourse[end][:F_T] > drivingCourse[end][:F_R] if !targetSpeedReached && !trainAtEnd && tractionSurplus
BS = createBehaviorSection("acceleration", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) BS = createBehaviorSection("acceleration", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
brakingStartReached = false
while !targetSpeedReached && !trainAtEnd && tractionSurplus && !brakingStartReached
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])
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
while drivingCourse[end][:v] < CS[:v_peak] && drivingCourse[end][:s] + s_braking<CS[:s_exit] && drivingCourse[end][:F_T] > drivingCourse[end][:F_R] # as long as s_i + s_braking < s_CSend 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
# 12/03 old with v>0 while drivingCourse[end][:v] < CS[:v_peak] && drivingCourse[end][:s]+s_braking<CS[:s_exit] && drivingCourse[end][:v]>0.0 && drivingCourse[end][:F_T] > drivingCourse[end][:F_R] # as long as s_i + s_braking < s_CSend
#11/22 calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type])
# 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])
# if drivingCourse[end][:a] == 0.0
# error("ERROR: a=0 m/s^2 in the acceleration section ! with F_T=",drivingCourse[end][:F_T]," R_traction=",drivingCourse[end][:R_traction]," R_wagons=",drivingCourse[end][:R_wagons]," R_path=",drivingCourse[end][:R_path])
# end
# create the next data point # create the next data point
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id])) push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
push!(BS[:dataPoints], drivingCourse[end][:i]) push!(BS[:dataPoints], drivingCourse[end][:i])
# 12/03: was moved behind considerFormerSpeedLimits: calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type])
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 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) (CS, drivingCourse, formerSpeedLimits, BS, endOfCsReached) = considerFormerSpeedLimits!(CS, drivingCourse, settings, train, CSs, formerSpeedLimits, BS)
@ -443,33 +494,46 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
return (CS, drivingCourse) return (CS, drivingCourse)
end end
end end
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type]) calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
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
if cycle < approximationLevel+1 if cycle < approximationLevel+1
if drivingCourse[end][:v]<=0.0 if drivingCourse[end][:v] <= 0.0
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]
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
elseif drivingCourse[end][:s] +s_braking > CS[:s_exit] elseif drivingCourse[end][:s] +s_braking > CS[:s_exit]
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
elseif drivingCourse[end][:v]>CS[:v_peak] elseif drivingCourse[end][:s] > nextPointOfInterest
if settings[:stepVariable]=="v in m/s" if settings[:stepVariable] == "s in m"
currentStepSize= CS[:v_peak]-drivingCourse[end-1][:v] currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
else else
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
end end
elseif drivingCourse[end][:s]==CS[:s_exit] elseif drivingCourse[end][:v] > CS[:v_peak]
break if settings[:stepVariable]=="v in m/s"
currentStepSize = CS[:v_peak]-drivingCourse[end-1][:v]
elseif drivingCourse[end][:v]==CS[:v_peak] else
break
elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R]
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
end
elseif drivingCourse[end][:s] == CS[:s_exit]
trainAtEnd = true
break
elseif drivingCourse[end][:v] == CS[:v_peak]
targetSpeedReached = true
break
elseif drivingCourse[end][:s] == nextPointOfInterest
break
else else
error("ERROR at acceleration until braking section: With the step variable ",settings[:stepVariable]," the while loop will be left although v<v_peak and s<s_exit in CS",CS[:id]," with s=" ,drivingCourse[end][:s]," m and v=",drivingCourse[end][:v]," m/s") error("ERROR at acceleration until braking section: With the step variable ",settings[:stepVariable]," the while loop will be left although v<v_peak and s<s_exit in CS",CS[:id]," with s=" ,drivingCourse[end][:s]," m and v=",drivingCourse[end][:v]," m/s")
@ -480,27 +544,41 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
else # if the level of approximation is reached else # if the level of approximation is reached
if drivingCourse[end][:v]<=0.0 if drivingCourse[end][:v]<=0.0
# 01/21 should not be needed anymore with diminishing.
# push!(BS[:dataPoints], drivingCourse[end][:i]) # push!(BS[:dataPoints], drivingCourse[end][:i])
error("ERROR: The train stops during the acceleration section in CS",CS[:id]," because the tractive effort is lower than the resistant forces.", error("ERROR: The train stops during the acceleration section in CS",CS[:id]," 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.")
elseif drivingCourse[end][:v]>CS[:v_peak] elseif drivingCourse[end][:v] > CS[:v_peak]
pop!(drivingCourse) targetSpeedReached = true
pop!(BS[:dataPoints])
elseif drivingCourse[end][:s] + s_braking > CS[:s_exit]
pop!(drivingCourse) pop!(drivingCourse)
pop!(BS[:dataPoints]) pop!(BS[:dataPoints])
elseif drivingCourse[end][:s] + s_braking > CS[:s_exit]
brakingStartReached = true
pop!(drivingCourse)
pop!(BS[:dataPoints])
elseif drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:s] = nextPointOfInterest # rounding s down to nextPointOfInterest
elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R] elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R]
tractionSurplus = false
(CS, drivingCourse) = addDiminishingSection!(CS, drivingCourse, settings, train, CSs) (CS, drivingCourse) = addDiminishingSection!(CS, drivingCourse, settings, train, CSs)
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type]) calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
else else
end end
# TODO is it possible to put this into to the if-fork?
if drivingCourse[end][:s] == CS[:s_exit]
trainAtEnd = true
end
end end
end #for end #for
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 # TODO: is it still possible that it is <=1 although there is a separate diminishing section?
# calculate the accumulated acceleration section information # calculate the accumulated acceleration section information
@ -516,7 +594,8 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
merge!(CS[:behaviorSections], Dict(:acceleration=>BS)) merge!(CS[:behaviorSections], Dict(:acceleration=>BS))
end end
end # else: just return the given data point number without changes due to the acceleration section end
return (CS, drivingCourse) return (CS, drivingCourse)
end #function addAccelerationSectionUntilBraking! end #function addAccelerationSectionUntilBraking!
@ -525,12 +604,12 @@ end #function addAccelerationSectionUntilBraking!
# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for cruising if needed. # Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for cruising if needed.
function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::Real, settings::Dict, train::Dict, CSs::Vector{Dict}, cruisingType::String) function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::Real, settings::Dict, train::Dict, CSs::Vector{Dict}, cruisingType::String)
# traction effort and resisting forces (in N) # traction effort and resisting forces (in N)
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "cruising") calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", 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)
# 01/08 old with DataPoint as struct: old drivingCourse[end] = DataPoint(calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "cruising")) # 01/08 old with DataPoint as struct: old drivingCourse[end] = DataPoint(calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel]))
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "cruising") 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_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]
@ -542,13 +621,23 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
s_cruising = min(s_cruising, CS[:s_exit]-BS[:s_entry]) s_cruising = min(s_cruising, CS[:s_exit]-BS[:s_entry])
# traction effort and resisting forces (in N) # traction effort and resisting forces (in N)
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "cruising") # 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], train, settings[:massModel], CSs, "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
currentStepSize=settings[:stepSize] # conditions for cruising section
trainInPreviousCS = drivingCourse[end][:s] < CS[:s_entry] + train[:length]
trainAtEnd = drivingCourse[end][:s] >= BS[:s_entry] +s_cruising
tractionSurplus = drivingCourse[end][:F_T] >= drivingCourse[end][:F_R]
# use the conditions for the cruising section
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 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][:F_T]>=drivingCourse[end][:F_R] #&& drivingCourse[end][:v]<=CS[:v_peak] && drivingCourse[end][:s]<CS[:s_exit] 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] # 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?
@ -567,28 +656,39 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
push!(BS[:dataPoints], drivingCourse[end][:i]) push!(BS[:dataPoints], drivingCourse[end][:i])
# traction effort and resisting forces (in N) # traction effort and resisting forces (in N)
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "cruising") calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
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
if cycle < approximationLevel+1 if cycle < approximationLevel+1
if drivingCourse[end][:s] > BS[:s_entry]+s_cruising # TODO also the following? drivingCourse[end][:s] > CSs[CS[:id]][:s_entry] + train[:length])) if drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
currentStepSize = settings[:stepSize] / 10.0^cycle
elseif drivingCourse[end][:s] > nextPointOfInterest
if settings[:stepVariable] == "s in m"
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
else
currentStepSize = settings[:stepSize] / 10.0^cycle
end
elseif drivingCourse[end][:s] > BS[:s_entry] + s_cruising # TODO also the following? drivingCourse[end][:s] > CSs[CS[:id]][:s_entry] + train[:length]))
if settings[:stepVariable] == "s in m" if settings[:stepVariable] == "s in m"
currentStepSize=BS[:s_entry] + s_cruising-drivingCourse[end-1][:s] currentStepSize=BS[:s_entry] + s_cruising-drivingCourse[end-1][:s]
else else
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
end end
elseif drivingCourse[end][:s] == BS[:s_entry]+s_cruising # || drivingCourse[end][:s]==CS[:s_exit]
elseif drivingCourse[end][:s] == BS[:s_entry] + s_cruising # || drivingCourse[end][:s]==CS[:s_exit]
trainAtEnd = true
break break
elseif drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
# if settings[:stepVariable] == "s in m"
# currentStepSize=BS[:s_entry]+s_cruising-drivingCourse[end-1][:s]
# else
currentStepSize = settings[:stepSize] / 10.0^cycle
# end
elseif drivingCourse[end][:s] >= CS[:s_entry] + train[:length] elseif drivingCourse[end][:s] >= CS[:s_entry] + train[:length]
# TODO: whithout CSs should work as well, no? elseif drivingCourse[end][:s] >= CSs[CS[:id]][:s_entry] + train[:length] trainInPreviousCS = false
break break
elseif drivingCourse[end][:s] == nextPointOfInterest
break
else # TODO copied from addAccelerationSection -> probably not needed here !? else # TODO copied from addAccelerationSection -> 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
@ -598,17 +698,21 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
pop!(BS[:dataPoints]) pop!(BS[:dataPoints])
else # if the level of approximation is reached else # if the level of approximation is reached
if drivingCourse[end][:s] > BS[:s_entry]+s_cruising if drivingCourse[end][:s] > nextPointOfInterest
if BS[:type] == "clearing" drivingCourse[end][:s] = nextPointOfInterest # rounding s down to nextPointOfInterest
else elseif drivingCourse[end][:s] > BS[:s_entry]+s_cruising
trainAtEnd = true
if BS[:type] != "clearing"
pop!(drivingCourse) pop!(drivingCourse)
pop!(BS[:dataPoints]) pop!(BS[:dataPoints])
end end
elseif drivingCourse[end][:s] == BS[:s_entry]+s_cruising elseif drivingCourse[end][:s] == BS[:s_entry]+s_cruising
trainAtEnd = true
break break
elseif drivingCourse[end][:F_T] < drivingCourse[end][:F_R] elseif drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
tractionSurplus = false
(CS, drivingCourse) = addDiminishingSection!(CS, drivingCourse, settings, train, CSs) (CS, drivingCourse) = addDiminishingSection!(CS, drivingCourse, settings, train, CSs)
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "cruising") 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_cruising=max(0.0, s_cruising-get(CS[:behaviorSections], :diminishing, Dict(length=>0.0))[:length])
@ -617,21 +721,26 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
end end
end end
end #for end #for
end #while
end #if end #if
# TODO oder soll das lieber nach oben in den else des letzten Durchlaufs. Noch mal genauer ansehen, ob hier was doppelt gemoppelt ist # TODO oder soll das lieber nach oben in den else des letzten Durchlaufs. Noch mal genauer ansehen, ob hier was doppelt gemoppelt ist
# if drivingCourse[end][:s]<BS[:s_entry]+s_cruising #if drivingCourse[end][:s] < BS[:s_entry]+s_cruising && drivingCourse[end][:F_T] >= drivingCourse[end][:F_R]
if drivingCourse[end][:s] < BS[:s_entry]+s_cruising && drivingCourse[end][:F_T] >= drivingCourse[end][:F_R] while drivingCourse[end][:s] < BS[:s_entry]+s_cruising && drivingCourse[end][:F_T] >= drivingCourse[end][:F_R]
nextPointOfInterest = min(BS[:s_entry]+s_cruising, getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s]))
drivingCourse[end][:a] = 0.0 # acceleration (in m/s^2) drivingCourse[end][:a] = 0.0 # acceleration (in m/s^2)
# calculate the remaining cruising way # calculate the remaining cruising way
s_cruisingRemaining=BS[:s_entry] + s_cruising-drivingCourse[end][:s] #s_cruisingRemaining=BS[:s_entry] + s_cruising-drivingCourse[end][:s]
s_cruisingRemaining = nextPointOfInterest - drivingCourse[end][:s]
# create the next data point # create the next data point
push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", s_cruisingRemaining, CS[:id])) push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", s_cruisingRemaining, CS[:id]))
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
push!(BS[:dataPoints], drivingCourse[end][:i]) push!(BS[:dataPoints], drivingCourse[end][:i])
end
calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
end #while
# calculate the accumulated cruising section information # calculate the accumulated cruising section information
merge!(BS, Dict(:length => drivingCourse[end][:s] - BS[:s_entry], # total length (in m) merge!(BS, Dict(:length => drivingCourse[end][:s] - BS[:s_entry], # total length (in m)
@ -652,16 +761,25 @@ end #function addCruisingSection!
## This function calculates the data points for diminishing run when using maximum tractive effort and still getting slower ## This function calculates the data points for diminishing run when using maximum tractive effort and still getting slower
function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}) function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict})
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "diminishing") calculateForces!(drivingCourse[end], CSs, CS[:id], "diminishing", train, settings[:massModel])
# conditions for diminishing section
targetSpeedReached = drivingCourse[end][:v] <= 0.0
trainAtEnd = drivingCourse[end][:s] >= CS[:s_exit]
tractionSurplus = drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
if drivingCourse[end][:F_T] <= drivingCourse[end][:F_R] && drivingCourse[end][:v] > 0.0 && drivingCourse[end][:s] < CS[:s_exit] # use the conditions for the diminishing section
if !tractionSurplus && !targetSpeedReached && !trainAtEnd
BS = createBehaviorSection("diminishing", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) BS = createBehaviorSection("diminishing", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
brakingStartReached = false
while !tractionSurplus && !targetSpeedReached && !trainAtEnd && !brakingStartReached
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])
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
while drivingCourse[end][:F_T] <= drivingCourse[end][:F_R] && drivingCourse[end][:s] + s_braking < CS[:s_exit] && drivingCourse[end][:v]>0.0 # as long as s_i + s_braking < s_CSend while drivingCourse[end][:F_T] <= drivingCourse[end][:F_R] && drivingCourse[end][:s] + s_braking < CS[:s_exit] && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:v]>0.0 # as long as s_i + s_braking < s_end
# 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])
@ -671,7 +789,7 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
push!(BS[:dataPoints], drivingCourse[end][:i]) push!(BS[:dataPoints], drivingCourse[end][:i])
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type]) calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
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
@ -679,15 +797,25 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
if drivingCourse[end][:v] <= 0.0 if drivingCourse[end][:v] <= 0.0
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
currentStepSize = settings[:stepSize] / 10.0^cycle
elseif drivingCourse[end][:s] + s_braking > CS[:s_exit] elseif drivingCourse[end][:s] + s_braking > CS[:s_exit]
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
elseif drivingCourse[end][:s] > nextPointOfInterest
if settings[:stepVariable] == "s in m"
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
else
currentStepSize = settings[:stepSize] / 10.0^cycle
end
elseif drivingCourse[end][:s] + s_braking == CS[:s_exit] elseif drivingCourse[end][:s] + s_braking == CS[:s_exit]
# 11/21 old without s_braking: elseif drivingCourse[end][:s]==CS[:s_exit] brakingStartReached = true
break break
elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R] elseif drivingCourse[end][:s] == nextPointOfInterest
currentStepSize = settings[:stepSize] / 10.0^cycle break
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")
@ -698,23 +826,30 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
else # if the level of approximation is reached else # if the level of approximation is reached
if drivingCourse[end][:v] <= 0.0 if drivingCourse[end][:v] <= 0.0
targetSpeedReached = true
# push!(BS[:dataPoints], drivingCourse[end][:i]) # push!(BS[:dataPoints], drivingCourse[end][:i])
error("ERROR: The train stops during diminishing run in CS",CS[:id]," because the maximum tractive effort is lower than the resistant forces.", error("ERROR: The train stops during diminishing run in CS",CS[:id]," because the maximum tractive effort is lower than the resistant forces.",
" Before the stop the last point has the values s=",drivingCourse[end-1][:s]," m v=",drivingCourse[end-1][:v]," m/s a=",drivingCourse[end-1][:a]," m/s^2", " Before the stop the last point has the values s=",drivingCourse[end-1][:s]," m v=",drivingCourse[end-1][:v]," m/s a=",drivingCourse[end-1][:a]," m/s^2",
" F_T=",drivingCourse[end-1][:F_T]," N R_traction=",drivingCourse[end-1][:R_traction]," N R_wagons=",drivingCourse[end-1][:R_wagons]," N R_path=",drivingCourse[end-1][:R_path]," N.") " F_T=",drivingCourse[end-1][:F_T]," N R_traction=",drivingCourse[end-1][:R_traction]," N R_wagons=",drivingCourse[end-1][:R_wagons]," N R_path=",drivingCourse[end-1][:R_path]," N.")
elseif drivingCourse[end][:s] + s_braking > CS[:s_exit] elseif drivingCourse[end][:s] + s_braking > CS[:s_exit]
brakingStartReached = true
pop!(drivingCourse) pop!(drivingCourse)
pop!(BS[:dataPoints]) pop!(BS[:dataPoints])
elseif drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:s] = nextPointOfInterest # rounding s down to nextPointOfInterest
elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R] elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
tractionSurplus = true
break break
else else
end end #if
end end #if
end #for end #for
end #while
if length(BS[:dataPoints]) > 1 # TODO: necessary? May it be possible that there is no diminishing because braking has to start? if length(BS[:dataPoints]) > 1 # TODO: necessary? May it be possible that there is no diminishing because braking has to start?
# calculate the accumulated diminishing section information # calculate the accumulated diminishing section information
@ -741,17 +876,25 @@ function addCoastingSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict},
## if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept ## if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
#formerSpeedLimits = detectFormerSpeedLimits(CSs, CS[:id], drivingCourse[end], train[:length]) #formerSpeedLimits = detectFormerSpeedLimits(CSs, CS[:id], drivingCourse[end], train[:length])
if drivingCourse[end][:v]>CS[:v_exit] && drivingCourse[end][:s]<CS[:s_exit] # conditions for coasting section
targetSpeedReached = drivingCourse[end][:v] <= CS[:v_exit]
trainAtEnd = drivingCourse[end][:s] >= CS[:s_exit]
# use the conditions for the coasting section
if !targetSpeedReached && !trainAtEnd
BS = createBehaviorSection("coasting", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) BS = createBehaviorSection("coasting", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
brakingStartReached = false
while !targetSpeedReached && !trainAtEnd && !brakingStartReached
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
# 08/24 old for cycle in 1:3 # first cycle with normal step size, second cycle with reduced step size, third cycle with more reduced step size nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
while drivingCourse[end][:v] > CS[:v_exit] && drivingCourse[end][:v] <= CS[:v_peak] && drivingCourse[end][:s] + s_braking < CS[:s_exit] # as long as s_i + s_braking < s_CSend while drivingCourse[end][:v] > CS[:v_exit] && drivingCourse[end][:v] <= CS[:v_peak] && drivingCourse[end][:s] + s_braking < CS[:s_exit] && drivingCourse[end][:s] < nextPointOfInterest # as long as s_i + s_braking < s_end
# traction effort and resisting forces (in N): # traction effort and resisting forces (in N):
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type]) calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
# 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])
@ -762,8 +905,6 @@ function addCoastingSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict},
push!(BS[:dataPoints], drivingCourse[end][:i]) push!(BS[:dataPoints], drivingCourse[end][:i])
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
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
@ -771,19 +912,31 @@ function addCoastingSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict},
if drivingCourse[end][:s] + s_braking > CS[:s_exit] if drivingCourse[end][:s] + s_braking > CS[:s_exit]
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
elseif drivingCourse[end][:s] > nextPointOfInterest
if settings[:stepVariable] == "s in m"
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
else
currentStepSize = settings[:stepSize] / 10.0^cycle
end
elseif drivingCourse[end][:v] < CS[:v_exit] # TODO: if accelereation and coasting functions will be combined this case is only for coasting elseif drivingCourse[end][:v] < CS[:v_exit] # TODO: if accelereation and coasting functions will be combined this case is only for coasting
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
elseif drivingCourse[end][:v] > CS[:v_peak] elseif drivingCourse[end][:v] > CS[:v_peak]
if settings[:stepVariable]=="v in m/s" if settings[:stepVariable]=="v in m/s"
currentStepSize = CS[:v_peak]-drivingCourse[end-1][:v] currentStepSize = CS[:v_peak] - drivingCourse[end-1][:v]
else else
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
end end
elseif drivingCourse[end][:s] + s_braking == CS[:s_exit] elseif drivingCourse[end][:s] + s_braking == CS[:s_exit]
trainAtEnd = true
break break
elseif drivingCourse[end][:v] == CS[:v_exit] elseif drivingCourse[end][:v] == CS[:v_exit]
targetSpeedReached = true
break
elseif drivingCourse[end][:s] == nextPointOfInterest
break break
else else
@ -801,11 +954,13 @@ function addCoastingSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict},
" 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 and s_braking=",s_braking,"m.") " 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 and s_braking=",s_braking,"m.")
elseif drivingCourse[end][:s] + s_braking > CS[:s_exit] elseif drivingCourse[end][:s] + s_braking > CS[:s_exit]
brakingStartReached = true
# delete last data point because it went to far # delete last data point because it went to far
pop!(drivingCourse) pop!(drivingCourse)
pop!(BS[:dataPoints]) pop!(BS[:dataPoints])
elseif drivingCourse[end][:v] > CS[:v_peak] # if the train gets to fast it has to brake # TODO: if accelereation and coasting functions will be combined this case is different for coasting and also the order of if cases is different elseif drivingCourse[end][:v] > CS[:v_peak] # if the train gets to fast it has to brake # TODO: if accelereation and coasting functions will be combined this case is different for coasting and also the order of if cases is different
targetSpeedReached = true
# delete last data point because it went to far # delete last data point because it went to far
pop!(drivingCourse) pop!(drivingCourse)
pop!(BS[:dataPoints]) pop!(BS[:dataPoints])
@ -819,30 +974,15 @@ function addCoastingSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict},
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], s_constantCoasting, CS[:id])) push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], s_constantCoasting, CS[:id]))
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
push!(BS[:dataPoints], drivingCourse[end][:i]) push!(BS[:dataPoints], drivingCourse[end][:i])
#=
#drivingCourse[end][:Δs]= CS[:s_exit]-drivingCourse[end-1][:s] - s_braking # step size (in m) # TODO: the coasting section is currently realised with using distance steps. For example t_braking could also be used
drivingCourse[end][:Δs] = min(currentStepSize, CS[:s_exit] - (drivingCourse[end-1][:s] + s_braking)) # TODO: if settings[:stepVariable]=="s in m"
drivingCourse[end][:Δt] = calc_Δt_with_constant_v(drivingCourse[end][:Δs], drivingCourse[end-1][:v]) # step size (in s)
drivingCourse[end][:Δv] = 0.0 # step size (in m/s)
drivingCourse[end][:s] = drivingCourse[end-1][:s] + drivingCourse[end][:Δs] # position (in m) elseif drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:t] = drivingCourse[end-1][:t] + drivingCourse[end][:Δt] # point in time (in s) drivingCourse[end][:s] = nextPointOfInterest # rounding s down to nextPointOfInterest
drivingCourse[end][:v] = drivingCourse[end-1][:v] # velocity (in m/s)
drivingCourse[end][:ΔW]=drivingCourse[end-1][:F_T]*drivingCourse[end][:Δs] # mechanical work in this step (in Ws)
# =0.0
drivingCourse[end][:W]=drivingCourse[end-1][:W]+drivingCourse[end][:ΔW] # mechanical work (in Ws)
# =drivingCourse[end-1][:W]
drivingCourse[end][:ΔE]=drivingCourse[end][:ΔW] # energy consumption in this step (in Ws)
# =0.0
drivingCourse[end][:E]=drivingCourse[end-1][:E]+drivingCourse[end][:ΔE] # energy consumption (in Ws)
# =drivingCourse[end-1][:E]
=#
else else
end end
end end
end #for end #for
end #while
# calculate the accumulated coasting section information # calculate the accumulated coasting 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)
@ -855,7 +995,8 @@ function addCoastingSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict},
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(:coasting=>BS)) merge!(CS[:behaviorSections], Dict(:coasting=>BS))
end ## else: just return the given data point number without changes due to the coasting section end
return (CS, drivingCourse) return (CS, drivingCourse)
end #function addCoastingSectionUntilBraking! end #function addCoastingSectionUntilBraking!
@ -864,13 +1005,33 @@ end #function addCoastingSectionUntilBraking!
# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for braking if needed. # Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for braking if needed.
function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}) #, s_braking::AbstractFloat) function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}) #, s_braking::AbstractFloat)
# function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, massModel::String, train::Dict, CSs::Vector{Dict}) #, s_braking::AbstractFloat) # function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, massModel::String, train::Dict, CSs::Vector{Dict}) #, s_braking::AbstractFloat)
if drivingCourse[end][:v]>CS[:v_exit] && drivingCourse[end][:s]<CS[:s_exit] if drivingCourse[end][:v] > CS[:v_exit] && drivingCourse[end][:s] < CS[:s_exit]
BS = createBehaviorSection("braking", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) BS = createBehaviorSection("braking", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
BS[:s_exit] = CS[:s_exit] # last position (in m) BS[:s_exit] = CS[:s_exit] # last position (in m)
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
while drivingCourse[end][:v] > CS[:v_exit] && drivingCourse[end][:s] < BS[:s_exit]
nextPointOfInterest = min(BS[:s_exit], getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s]))
if nextPointOfInterest < BS[:s_exit]
# traction effort and resisting forces (in N) # traction effort and resisting forces (in N)
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type]) calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
drivingCourse[end][:a] = calcBrakingAcceleration(drivingCourse[end][:v], CS[:v_exit], BS[:s_exit]-drivingCourse[end][:s])
# TODO: or just take train[:a_braking]? difference ist by 0.0000000001 m/s^2: drivingCourse[end][:a] = train[:a_braking]
# println("a_braking till ",nextPointOfInterest,": ", calcBrakingAcceleration(drivingCourse[end][:v], CS[:v_exit], BS[:s_exit]-drivingCourse[end][:s]), ". It should be: ",train[:a_braking])
# calculate the braking distance to the next point of interest
stepSize = nextPointOfInterest - drivingCourse[end][:s]
# create the next data point
push!(drivingCourse, moveAStep(drivingCourse[end], "s in m", stepSize, CS[:id]))
drivingCourse[end][:behavior] = BS[:type]
push!(BS[:dataPoints], drivingCourse[end][:i])
else # so if nextPointOfInterest == BS[:s_exit]
# traction effort and resisting forces (in N)
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
push!(drivingCourse, createDataPoint()) push!(drivingCourse, createDataPoint())
drivingCourse[end][:i] = drivingCourse[end-1][:i]+1 # incrementing the number of the data point drivingCourse[end][:i] = drivingCourse[end-1][:i]+1 # incrementing the number of the data point
@ -883,15 +1044,7 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s] # step size (in m) 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][:Δv] = drivingCourse[end][:v] - drivingCourse[end-1][:v] # step size (in m/s)
# 09/21 old: rounding is not necessary. drivingCourse[end-1][:a]=round((drivingCourse[end][:v]^2-drivingCourse[end-1][:v]^2)/2/drivingCourse[end][:Δs], digits=approximationLevel) # acceleration (in m/s^2) (rounding because it should not be less than a_braking)
drivingCourse[end-1][:a] = calcBrakingAcceleration(drivingCourse[end-1][:v], drivingCourse[end][:v], drivingCourse[end][:Δs]) drivingCourse[end-1][:a] = calcBrakingAcceleration(drivingCourse[end-1][:v], drivingCourse[end][:v], drivingCourse[end][:Δs])
#= if drivingCourse[end-1][:a]<train[:a_braking] || drivingCourse[end-1][:a]>=0.0
println("")
println("Warning: a_braking gets to high in CS ",CS[:id], " with a=",drivingCourse[end-1][:a] ," > ",train[:a_braking])
println(" v=",drivingCourse[end][:v]," v_i-1=",drivingCourse[end-1][:v], " Δs=",drivingCourse[end][:Δs])
println(" v_exit=",CS[:v_exit])
println("")
end =#
drivingCourse[end][:Δt] = calc_Δt_with_Δv(drivingCourse[end][:Δv], drivingCourse[end-1][:a]) # step size (in s) 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][:t] = drivingCourse[end-1][:t] + drivingCourse[end][:Δt] # point in time (in s)
@ -900,6 +1053,10 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic
drivingCourse[end][:ΔE] = drivingCourse[end][:ΔW] # energy consumption in this step (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) drivingCourse[end][:E] = drivingCourse[end-1][:E] + drivingCourse[end][:ΔE] # energy consumption (in Ws)
break
end #if
end #while
merge!(BS, Dict(:length => drivingCourse[end][:Δs], # total length (in m) merge!(BS, Dict(:length => drivingCourse[end][:Δs], # 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], # total running time (in s) :t => drivingCourse[end][:Δt], # total running time (in s)
@ -918,6 +1075,7 @@ end #function addBrakingSection!
## This function calculates the data points of the braking section. # 09/07 new braking section with more than two data points ## This function calculates the data points of the braking section. # 09/07 new braking section with more than two data points
# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for braking if needed. # Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for braking if needed.
function addBrakingSectionStepwise!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}) #, s_braking::AbstractFloat) function addBrakingSectionStepwise!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}) #, s_braking::AbstractFloat)
#= TODO from 2022/01/22: integrate points of interest
if drivingCourse[end][:v] > CS[:v_exit] && drivingCourse[end][:s] < CS[:s_exit] if drivingCourse[end][:v] > CS[:v_exit] && drivingCourse[end][:s] < CS[:s_exit]
BS = createBehaviorSection("braking", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) BS = createBehaviorSection("braking", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
@ -926,7 +1084,7 @@ function addBrakingSectionStepwise!(CS::Dict, drivingCourse::Vector{Dict}, setti
velocityIsPositive = true velocityIsPositive = true
while drivingCourse[end][:v] > CS[:v_exit] && drivingCourse[end][:s] < CS[:s_exit] && velocityIsPositive while drivingCourse[end][:v] > CS[:v_exit] && drivingCourse[end][:s] < CS[:s_exit] && velocityIsPositive
# traction effort and resisting forces (in N): # traction effort and resisting forces (in N):
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, BS[:type]) calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
# acceleration (in m/s^2): # acceleration (in m/s^2):
drivingCourse[end][:a] = train[:a_braking] drivingCourse[end][:a] = train[:a_braking]
@ -985,6 +1143,7 @@ function addBrakingSectionStepwise!(CS::Dict, drivingCourse::Vector{Dict}, setti
merge!(CS[:behaviorSections], Dict(:braking=>BS)) merge!(CS[:behaviorSections], Dict(:braking=>BS))
end # else: return the characteristic section without a braking section end # else: return the characteristic section without a braking section
=#
return (CS, drivingCourse) return (CS, drivingCourse)
end #function addBrakingSectionStepwise! end #function addBrakingSectionStepwise!
@ -1002,7 +1161,7 @@ function addStandstill!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, t
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], train, settings[:massModel], CSs, BS[:type]) calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
merge!(CS[:behaviorSections], Dict(:standstill => BS)) merge!(CS[:behaviorSections], Dict(:standstill => BS))
end # else: return the characteristic section without a standstillSection section end # else: return the characteristic section without a standstillSection section

View File

@ -29,12 +29,12 @@ function createMovingSection(path::Dict, v_trainLimit::Real)
previousSection = path[:sections][row-1] previousSection = path[:sections][row-1]
currentSection = path[:sections][row] currentSection = path[:sections][row]
if min(previousSection[:v_limit], v_trainLimit) != min(currentSection[:v_limit], v_trainLimit) || previousSection[:f_Rp] != currentSection[:f_Rp] if min(previousSection[:v_limit], v_trainLimit) != min(currentSection[:v_limit], v_trainLimit) || previousSection[:f_Rp] != currentSection[:f_Rp]
push!(CSs, createCharacteristicSection(csId, s_csStart, previousSection, min(previousSection[:v_limit], v_trainLimit))) push!(CSs, createCharacteristicSection(csId, s_csStart, previousSection, min(previousSection[:v_limit], v_trainLimit), path))
s_csStart = currentSection[:s_start] s_csStart = currentSection[:s_start]
csId = csId+1 csId = csId+1
end #if end #if
end #for end #for
push!(CSs, createCharacteristicSection(csId, s_csStart, path[:sections][end], min(path[:sections][end][:v_limit], v_trainLimit))) push!(CSs, createCharacteristicSection(csId, s_csStart, path[:sections][end], min(path[:sections][end][:v_limit], v_trainLimit), path))
movingSection= Dict(:id => 1, # identifier # if there is more than one moving section in a later version of this tool the id should not be constant anymore movingSection= Dict(:id => 1, # identifier # if there is more than one moving section in a later version of this tool the id should not be constant anymore
:length => pathLength, # total length (in m) :length => pathLength, # total length (in m)
@ -49,21 +49,36 @@ end #function createMovingSection
## create a characteristic section for a path section. A characteristic section is a part of the moving section. It contains behavior sections. ## create a characteristic section for a path section. A characteristic section is a part of the moving section. It contains behavior sections.
function createCharacteristicSection(csId::Integer, s_csStart::Real, section::Dict, v_csLimit::Real) function createCharacteristicSection(id::Integer, s_entry::Real, section::Dict, v_limit::Real, path::Dict)
# Create and return a characteristic section dependent on the paths attributes # Create and return a characteristic section dependent on the paths attributes
characteristicSection= Dict(:id => csId, # identifier characteristicSection= Dict(:id => id, # identifier
:s_entry => s_csStart, # first position (in m) :s_entry => s_entry, # first position (in m)
:s_exit => section[:s_end], # last position (in m) :s_exit => section[:s_end], # last position (in m)
:length => section[:s_end]-s_csStart, # total length (in m) :length => section[:s_end] -s_entry, # total length (in m)
:r_path => section[:f_Rp], # path resistance (in ‰) :r_path => section[:f_Rp], # path resistance (in ‰)
:behaviorSections => Dict(), # list of containing behavior sections :behaviorSections => Dict(), # list of containing behavior sections
:t => 0.0, # total running time (in s) :t => 0.0, # total running time (in s)
:E => 0.0, # total energy consumption (in Ws) :E => 0.0, # total energy consumption (in Ws)
:v_limit => v_csLimit, # speed limit (in m/s) :v_limit => v_limit, # speed limit (in m/s)
# initializing :v_entry, :v_peak and :v_exit with :v_limit # initializing :v_entry, :v_peak and :v_exit with :v_limit
:v_peak => v_csLimit, # maximum reachable speed (in m/s) :v_peak => v_limit, # maximum reachable speed (in m/s)
:v_entry => v_csLimit, # maximum entry speed (in m/s) :v_entry => v_limit, # maximum entry speed (in m/s)
:v_exit => v_csLimit) # maximum exit speed (in m/s) :v_exit => v_limit) # maximum exit speed (in m/s)
# list of positions of every point of interest (POI) in this charateristic section for which data points should be calculated
s_exit = characteristicSection[:s_exit]
pointsOfInterest = Vector{Real}()
if haskey(path, :pointsOfInterest)
for POI in path[:pointsOfInterest]
if s_entry < POI && POI < s_exit
push!(pointsOfInterest, POI)
end
end
end
push!(pointsOfInterest, s_exit) # s_exit has to be the last POI so that there will always be a POI to campare the current position with
merge!(characteristicSection, Dict(:pointsOfInterest => pointsOfInterest))
return characteristicSection return characteristicSection
end #function createCharacteristicSection end #function createCharacteristicSection

View File

@ -4,6 +4,7 @@
# TODO: calculation time for passenger trains on path1 is very long and should be reduced # TODO: calculation time for passenger trains on path1 is very long and should be reduced
# TODO from 2022/01/18: Test if enum trainType is working correctly in function calculateRecoveryTime or if only the else-pathis taken # TODO from 2022/01/18: Test if enum trainType is working correctly in function calculateRecoveryTime or if only the else-pathis taken
# TODO from 2022/01/19: Are here calculations that should be transferred to DrivingDynamics.jl? # TODO from 2022/01/19: Are here calculations that should be transferred to DrivingDynamics.jl?
# TODO from 2022/01/22: use always copyCharacteristicSection and don't do it manually like "csModified=Dict(:id => csOriginal[:id], ..." three times
module EnergySaving module EnergySaving
@ -35,7 +36,7 @@ function addOperationModeEnergySaving!(summarizedDict::Dict)
# summarize data and create an output dictionary # summarize data and create an output dictionary
merge!(summarizedDict, Dict(:movingSectionMinimumEnergyConsumption => movingSectionMinimumEnergyConsumption, :drivingCourseMinimumEnergyConsumption => drivingCourseMinimumEnergyConsumption)) merge!(summarizedDict, Dict(:movingSectionMinimumEnergyConsumption => movingSectionMinimumEnergyConsumption, :drivingCourseMinimumEnergyConsumption => drivingCourseMinimumEnergyConsumption))
else else
println("No output for minimum energy consumption has been demanded and so none will be calculated") println("No output for minimum energy consumption has been demanded and so none will be calculated.")
end #if end #if
return summarizedDict return summarizedDict
@ -275,7 +276,8 @@ function copyCharacteristicSection(originalCS::Dict)
:v_limit => originalCS[:v_limit], # speed limit (in m/s) :v_limit => originalCS[:v_limit], # speed limit (in m/s)
:v_peak => originalCS[:v_peak], # maximum reachable speed (in m/s) :v_peak => originalCS[:v_peak], # maximum reachable speed (in m/s)
:v_entry => originalCS[:v_entry], # maximum entry speed (in m/s) :v_entry => originalCS[:v_entry], # maximum entry speed (in m/s)
:v_exit => originalCS[:v_exit]) # maximum exit speed (in m/s) :v_exit => originalCS[:v_exit], # maximum exit speed (in m/s)
:pointsOfInterest => originalCS[:pointsOfInterest]) # points of interest for which data points should be calculated
return copiedCS return copiedCS
end # CharacteristicSection end # CharacteristicSection
@ -699,7 +701,8 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
:v_limit => csOriginal[:v_limit], # speed limit (in m/s) :v_limit => csOriginal[:v_limit], # speed limit (in m/s)
:v_peak => csOriginal[:v_peak], # maximum reachable speed (in m/s) :v_peak => csOriginal[:v_peak], # maximum reachable speed (in m/s)
:v_entry => csOriginal[:v_entry], # maximum entry speed (in m/s) :v_entry => csOriginal[:v_entry], # maximum entry speed (in m/s)
:v_exit => csOriginal[:v_exit]) # maximum exit speed (in m/s) :v_exit => csOriginal[:v_exit], # maximum exit speed (in m/s)
:pointsOfInterest => csOriginal[:pointsOfInterest]) # points of interest for which data points should be calculated
BSsModified = csModified[:behaviorSections] BSsModified = csModified[:behaviorSections]
if haskey(BSsOriginal, :breakFree) if haskey(BSsOriginal, :breakFree)
@ -774,7 +777,8 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
:v_limit => csOriginal[:v_limit], # speed limit (in m/s) :v_limit => csOriginal[:v_limit], # speed limit (in m/s)
:v_peak => csOriginal[:v_peak], # maximum reachable speed (in m/s) :v_peak => csOriginal[:v_peak], # maximum reachable speed (in m/s)
:v_entry => csOriginal[:v_entry], # maximum entry speed (in m/s) :v_entry => csOriginal[:v_entry], # maximum entry speed (in m/s)
:v_exit => csOriginal[:v_exit]) # maximum exit speed (in m/s) :v_exit => csOriginal[:v_exit], # maximum exit speed (in m/s)
:pointsOfInterest => csOriginal[:pointsOfInterest]) # points of interest for which data points should be calculated
BSsModified = csModified[:behaviorSections] BSsModified = csModified[:behaviorSections]
if haskey(BSsOriginal, :breakFree) if haskey(BSsOriginal, :breakFree)
@ -881,7 +885,9 @@ function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict
:v_limit => csOriginal[:v_limit], # speed limit (in m/s) :v_limit => csOriginal[:v_limit], # speed limit (in m/s)
:v_peak => csOriginal[:v_peak], # maximum reachable speed (in m/s) :v_peak => csOriginal[:v_peak], # maximum reachable speed (in m/s)
:v_entry => csOriginal[:v_entry], # maximum entry speed (in m/s) :v_entry => csOriginal[:v_entry], # maximum entry speed (in m/s)
:v_exit => csOriginal[:v_exit]) # maximum exit speed (in m/s) :v_exit => csOriginal[:v_exit], # maximum exit speed (in m/s)
:pointsOfInterest => csOriginal[:pointsOfInterest]) # points of interest for which data points should be calculated
BSsModified = csModified[:behaviorSections] BSsModified = csModified[:behaviorSections]
if haskey(BSsOriginal, :breakFree) if haskey(BSsOriginal, :breakFree)
breakFreeSection=copyBehaviorSection(BSsOriginal[:breakFree]) breakFreeSection=copyBehaviorSection(BSsOriginal[:breakFree])

View File

@ -10,9 +10,9 @@ export importYamlFiles, importYamlFile
Read the input information from YAML files for train, path and settings, save it in different dictionaries and return them. Read the input information from YAML files for train, path and settings, save it in different dictionaries and return them.
""" """
function importYamlFiles(trainDirectory::String, pathDirectory::String, settingsDirectory::String) function importYamlFiles(trainDirectory::String, pathDirectory::String, settingsDirectory::String)
train=importTrainFromYaml(trainDirectory) train = importTrainFromYaml(trainDirectory)
path=importPathFromYaml(pathDirectory) path = importPathFromYaml(pathDirectory)
settings=importSettingsFromYaml(settingsDirectory) settings = importSettingsFromYaml(settingsDirectory)
return (train, path, settings) return (train, path, settings)
end #function importYamlFiles end #function importYamlFiles
@ -122,6 +122,8 @@ function importPathFromYaml(pathDirectory::String)
:id => id, :id => id,
:sections => sections) :sections => sections)
addPointsOfInterest!(path, data)
informAboutUnusedKeys(data, "path") # inform the user, which keywords of the imported data are not used in this tool informAboutUnusedKeys(data, "path") # inform the user, which keywords of the imported data are not used in this tool
return path return path
@ -502,6 +504,48 @@ function getSections!(data::Dict)
return sections return sections
end #function getSections! end #function getSections!
function addPointsOfInterest!(path::Dict, data::Dict)
# read the section starting positions and corresponding information
if haskey(data["path"],"pointsOfInterest") && data["path"]["pointsOfInterest"]!=nothing
pointsOfInterest = data["path"]["pointsOfInterest"]
delete!(data["path"], "pointsOfInterest")
sortingNeeded = false
errorDetected = false
for element in 1:length(pointsOfInterest)
if typeof(pointsOfInterest[element]) <: Real
if element > 1
if pointsOfInterest[element] < pointsOfInterest[element-1]
sortingNeeded = true
println("INFO at reading the path yaml file: The point of interest in element ", element ," (",pointsOfInterest[element]," m) has to be higher than the value of the previous element (",pointsOfInterest[element-1]," m). The points of interest will be sorted.")
end
end
else
errorDetected = true
println("ERROR at reading the path yaml file: The point of interest in element ", element ," is no real floating point number.")
end
end # for
if errorDetected
error("ERROR at reading the path yaml file: The values of the point of interest have to be corrected.")
end
if sortingNeeded == true
sort!(pointsOfInterest)
end
copiedPOIs = []
for element in 1:length(pointsOfInterest)
if element == 1
push!(copiedPOIs, pointsOfInterest[element])
elseif element > 1 && pointsOfInterest[element] > pointsOfInterest[element-1]
push!(copiedPOIs, pointsOfInterest[element])
end
end # for
merge!(path, Dict(:pointsOfInterest => copiedPOIs))
end
return (path, data)
end #function addPointsOfInterest!
function informAboutUnusedKeys(data::Dict, dataSet::String) # inform the user which keywords of the imported data are not used in this tool function informAboutUnusedKeys(data::Dict, dataSet::String) # inform the user which keywords of the imported data are not used in this tool
if length(data[dataSet])>0 if length(data[dataSet])>0
println("INFO at reading the ",dataSet," yaml file: The following Keywords are not used in this tool:") println("INFO at reading the ",dataSet," yaml file: The following Keywords are not used in this tool:")

View File

@ -68,6 +68,7 @@ function checkAndSetPath!(path::Dict)
checkString(path, "path", :name) checkString(path, "path", :name)
# TODO checkId ? path[:id] # path identifier # TODO checkId ? path[:id] # path identifier
checkAndSetSections!(path) checkAndSetSections!(path)
checkAndSetPOIs!(path)
# TODO: informAboutUnusedKeys(path, "path") # inform the user, which Symbols of the input dictionary are not used in this tool # TODO: informAboutUnusedKeys(path, "path") # inform the user, which Symbols of the input dictionary are not used in this tool
@ -400,6 +401,52 @@ function checkAndSetSections!(path::Dict)
return path return path
end #function checkAndSetSections! end #function checkAndSetSections!
function checkAndSetPOIs!(path::Dict)
# read the section starting positions and corresponding information
if haskey(path,:pointsOfInterest)
if path[:pointsOfInterest] != nothing
pointsOfInterest = path[:pointsOfInterest]
sortingNeeded = false
errorDetected = false
for element in 1:length(pointsOfInterest)
if typeof(pointsOfInterest[element]) <: Real
if element > 1
if pointsOfInterest[element] < pointsOfInterest[element-1]
sortingNeeded = true
println("INFO at checking the input dictionary for the path: The point of interest in element ", element ," (",pointsOfInterest[element]," m) has to be higher than the value of the previous element (",pointsOfInterest[element-1]," m). The points of interest will be sorted.")
end
end
else
errorDetected = true
println("ERROR at checking the input dictionary for the path: The point of interest in element ", element ," is no real floating point number.")
end
end # for
if errorDetected
error("ERROR at checking the input dictionary for the path: The values of the point of interest have to be corrected.")
end
if sortingNeeded == true
sort!(pointsOfInterest)
end
copiedPOIs = []
for element in 1:length(pointsOfInterest)
if element == 1
push!(copiedPOIs, pointsOfInterest[element])
elseif element > 1 && pointsOfInterest[element] > pointsOfInterest[element-1]
push!(copiedPOIs, pointsOfInterest[element])
end
end # for
path[:pointsOfInterest] = copiedPOIs
end
else
delete!(path, :pointsOfInterest)
end
return path
end #function checkAndSetPOIs!
function informAboutUnusedKeys(dictionary::Dict, dictionaryType::String) # inform the user which Symbols of the input dictionary are not used in this tool function informAboutUnusedKeys(dictionary::Dict, dictionaryType::String) # inform the user which Symbols of the input dictionary are not used in this tool
#= if length(dictionary)>0 #= if length(dictionary)>0
println("INFO at checking the input dictionary for the ",dictionaryType,": The following Keywords are not used in this tool:") println("INFO at checking the input dictionary for the ",dictionaryType,": The following Keywords are not used in this tool:")

View File

@ -3,14 +3,37 @@ module Output
export createOutputDict export createOutputDict
function createOutputDict(train::Dict, settings::Dict, path::Dict, movingSection::Dict, drivingCourse::Vector{Dict}) function createOutputDict(train::Dict, settings::Dict, path::Dict, movingSection::Dict, drivingCourse::Vector{Dict})
outputDict=Dict{Symbol,Any}() outputDict = Dict{Symbol,Any}()
merge!(outputDict, Dict(:train => train, :path => path, :settings => settings)) merge!(outputDict, Dict(:train => train, :path => path, :settings => settings))
# adding moving section and drving courses
# add moving section and driving courses
if settings[:operationModeMinimumRunningTime] == true if settings[:operationModeMinimumRunningTime] == true
merge!(outputDict, Dict(:movingSectionMinimumRunningTime => movingSection, :drivingCourseMinimumRunningTime => drivingCourse)) merge!(outputDict, Dict(:movingSectionMinimumRunningTime => movingSection,
:drivingCourseMinimumRunningTime => drivingCourse))
elseif settings[:operationModeMinimumEnergyConsumption] == true elseif settings[:operationModeMinimumEnergyConsumption] == true
merge!(outputDict, Dict(:movingSectionMinimumEnergyConsumption => movingSection, :drivingCourseMinimumEnergyConsumption => drivingCourse)) merge!(outputDict, Dict(:movingSectionMinimumEnergyConsumption => movingSection,
:drivingCourseMinimumEnergyConsumption => drivingCourse))
end
# add points of interest
if haskey(path, :pointsOfInterest)
pointsOfInterest = Vector{Dict}()
POI = 1
i = 1
while(POI <= length(path[:pointsOfInterest]) && i <= drivingCourse[end][:i])
if path[:pointsOfInterest][POI] == drivingCourse[i][:s]
push!(pointsOfInterest, drivingCourse[i])
POI = POI+1
end
i = i+1
end
if settings[:operationModeMinimumRunningTime] == true
merge!(outputDict, Dict(:pointsOfInterestMinimumRunningTime => pointsOfInterest))
elseif settings[:operationModeMinimumEnergyConsumption] == true
merge!(outputDict, Dict(:pointsOfInterestMinimumEnergyConsumption => pointsOfInterest))
end
end end
return outputDict return outputDict

View File

@ -43,7 +43,7 @@ function calculateDrivingDynamics(train::Dict, path::Dict, settings::Dict)
# calculate the train run for oparation mode "minimum running time" # calculate the train run for oparation mode "minimum running time"
if settings[:operationModeMinimumRunningTime] || settings[:operationModeMinimumEnergyConsumption] if settings[:operationModeMinimumRunningTime] || settings[:operationModeMinimumEnergyConsumption]
(movingSection, drivingCourse)=calculateMinimumRunningTime!(movingSection, settings, train) (movingSection, drivingCourse) = calculateMinimumRunningTime!(movingSection, settings, train)
println("The driving course for the shortest running time has been calculated.") println("The driving course for the shortest running time has been calculated.")
# summarize data and create an output dictionary # summarize data and create an output dictionary
@ -79,11 +79,6 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
s_cruising = CS[:length] - s_breakFree - s_clearing - s_acceleration - s_braking s_cruising = CS[:length] - s_breakFree - s_clearing - s_acceleration - 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
# 01/07 old: delete!(BSs, :breakFree)
# 01/07 old: delete!(BSs, :clearing)
# 01/07 old: delete!(BSs, :acceleration)
# 01/07 old: delete!(BSs, :diminishing)
# 01/07 old: delete!(BSs, :cruising)
CS[:behaviorSections] = Dict() CS[:behaviorSections] = Dict()
CS[:E] = 0.0 CS[:E] = 0.0
CS[:t] = 0.0 CS[:t] = 0.0
@ -98,7 +93,7 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
# 09/21 elseif s_cruising > 0.0 # 09/21 elseif s_cruising > 0.0
# 09/21 elseif s_cruising > 0.01 # if the cruising section is longer than 1 cm (because of rounding issues not >0.0) # 09/21 elseif s_cruising > 0.01 # if the cruising section is longer than 1 cm (because of rounding issues not >0.0)
if drivingCourse[end][:v] < CS[:v_peak] if drivingCourse[end][:v] < CS[:v_peak]
(CS, drivingCourse)=addAccelerationSection!(CS, drivingCourse, settings, train, CSs) (CS, drivingCourse) = addAccelerationSection!(CS, drivingCourse, settings, train, CSs)
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
@ -121,8 +116,7 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
end #if end #if
end #if end #if
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
s_braking=max(0.0, ceil((CS[:v_exit]^2-drivingCourse[end][:v]^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
if drivingCourse[end][:v] > CS[:v_exit] if drivingCourse[end][:v] > CS[:v_exit]
#(CS, drivingCourse)=addBrakingSection!(CS, drivingCourse, settings[:massModel], train, CSs) #(CS, drivingCourse)=addBrakingSection!(CS, drivingCourse, settings[:massModel], train, CSs)
@ -138,7 +132,7 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
end =# end =#
end #for end #for
(CSs[end], drivingCourse)=addStandstill!(CSs[end], drivingCourse, settings, train, CSs) (CSs[end], drivingCourse) = addStandstill!(CSs[end], drivingCourse, settings, train, CSs)
movingSection[:t] = drivingCourse[end][:t] # total running time (in s) movingSection[:t] = drivingCourse[end][:t] # total running time (in s)
movingSection[:E] = drivingCourse[end][:E] # total energy consumption (in Ws) movingSection[:E] = drivingCourse[end][:E] # total energy consumption (in Ws)

View File

@ -8,24 +8,25 @@
using TrainRun, Test using TrainRun, Test
allPaths=[] allPaths=[]
push!(allPaths, "data/paths/path_1_10km_nConst_vConst.yaml") push!(allPaths, importYamlFile(:path, "data/paths/path_1_10km_nConst_vConst.yaml"))
push!(allPaths, "data/paths/path_2_10km_nVar_vConst.yaml") push!(allPaths, importYamlFile(:path, "data/paths/path_2_10km_nVar_vConst.yaml"))
push!(allPaths, "data/paths/path_3_10km_nConst_vVar.yaml") push!(allPaths, importYamlFile(:path, "data/paths/path_3_10km_nConst_vVar.yaml"))
push!(allPaths, "data/paths/path_4_real_Ostsachsen_DG-DN_spp_5.yaml") push!(allPaths, importYamlFile(:path, "data/paths/path_4_real_Germany_EastSaxony_DG-DN.yaml"))
allSettings=[] allSettings=[]
push!(allSettings, "data/settings.yaml") push!(allSettings, importYamlFile(:settings, "data/settings.yaml"))
allTrains=[] allTrains=[]
push!(allTrains, "data/trains/train_freight_V90withOreConsist.yaml") push!(allTrains, importYamlFile(:train, "data/trains/train_freight_V90withOreConsist.yaml"))
push!(allTrains, "data/trains/train_passenger_SiemensDesiroClassic.yaml") push!(allTrains, importYamlFile(:train, "data/trains/train_passenger_SiemensDesiroClassic.yaml"))
push!(allTrains, "data/trains/train_passenger_IC2.yaml") push!(allTrains, importYamlFile(:train, "data/trains/train_passenger_IC2.yaml"))
for pathDirectory in allPaths
for trainDirectory in allTrains
for settingsDirectory in allSettings
testDict=calculateDrivingDynamics(trainDirectory, pathDirectory, settingsDirectory)
for path in allPaths
for train in allTrains
for settings in allSettings
testDict=calculateDrivingDynamics(train, path, settings)
exportToCsv(testDict)
sleep(2) sleep(2)
# TODO: # TODO: