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")
using .TrainRun
train = "data/trains/train_freight_V90withOreConsist.yaml"
running_path = "data/paths/path_1_10km_nConst_vConst.yaml"
settings = "data/settings.yaml"
train_directory = "data/trains/train_freight_V90withOreConsist.yaml"
running_path_directory = "data/paths/path_1_10km_nConst_vConst.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)
```

View File

@ -2,6 +2,7 @@
---
path:
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_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp in ‰]
- [0, 160, 0]

View File

@ -2,6 +2,7 @@
---
path:
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_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp in ‰]
- [0, 160, 0]

View File

@ -2,6 +2,7 @@
---
path:
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_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp in ‰]
- [0, 160, 0.0]

View File

@ -125,10 +125,10 @@ function plotDrivingCourse(drivingCourseMinimumRunningTime::Vector{Dict},driving
println("Plots for different variables have been created.")
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")
for i in 1:length(drivingCourse)
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)
for i in 1:length(dataPoints)
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
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
@ -136,13 +136,13 @@ end #function printImportantValues
function printSectionInformation(movingSection::Dict)
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]
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)
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])
# println(CSs[csId][:behaviorSections][allBs[bs]][:dataPoints][point])
# end

View File

@ -8,7 +8,7 @@ export addAccelerationSection!, addAccelerationSectionUntilBraking!, addCruising
calculateForces!, createDataPoint,
# 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)
@ -55,24 +55,15 @@ end #function calculateTractiveEffort
"""
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})
# 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
function calculatePathResistance(CSs::Vector{Dict}, csId::Integer, s::Real, massModel::String, train::Dict)
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"
pathResistance = 0.0
while id > 0 && s-train[:length] < CSs[id][: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])
id = id-1
if id == 0
while csId > 0 && s-train[:length] < CSs[csId][:s_exit]
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])
csId = csId-1
if csId == 0
# 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])
end #if
@ -85,12 +76,12 @@ end #function calculatePathResistance
"""
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
dataPoint[:R_traction] = calcTractionUnitResistance(dataPoint[:v], train)
dataPoint[:R_wagons] = calcWagonsResistance(dataPoint[:v], train)
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]
# calculate tractive effort
@ -102,14 +93,13 @@ function calculateForces!(dataPoint::Dict, train::Dict, massModel::String, CSs:
dataPoint[:F_T] = 0.0
end
return dataPoint
end #function calculateForces
end #function calculateForces!
"""
TODO
"""
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
# 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. =#
@ -223,6 +213,16 @@ function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{Dict}, setti
return (CS, drivingCourse, formerSpeedLimits, accelerationSection, false)
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.
# 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
@ -232,7 +232,7 @@ function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::D
drivingCourse[end][:behavior] = BS[:type]
# traction effort and resisting forces (in N):
calculateForces!(drivingCourse[end], 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):
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 !")
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]))
drivingCourse[end][:behavior] = BS[:type]
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
merge!(BS, Dict(:length => drivingCourse[end][:s] - BS[:s_entry], # total length (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.
# 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})
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)
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]
(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
# 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])
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
while drivingCourse[end][:v] < CS[:v_peak] && drivingCourse[end][:s] < CS[:s_exit] && 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])
while drivingCourse[end][:v] < CS[:v_peak] && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
# acceleration (in m/s^2):
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]))
drivingCourse[end][:behavior] = BS[:type]
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
(CS, drivingCourse, formerSpeedLimits, BS, endOfCsReached) = considerFormerSpeedLimits!(CS, drivingCourse, settings, train, CSs, formerSpeedLimits, BS)
if endOfCsReached
return (CS, drivingCourse)
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
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
# 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
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"
currentStepSize=CS[:s_exit]-drivingCourse[end-1][:s]
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
else
currentStepSize = settings[:stepSize] / 10.0^cycle
end
elseif drivingCourse[end][:v] > CS[:v_peak]
if settings[:stepVariable] == "v in m/s"
currentStepSize=CS[:v_peak]-drivingCourse[end-1][:v]
currentStepSize = CS[:v_peak]-drivingCourse[end-1][:v]
else
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
elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R]
currentStepSize = settings[:stepSize] / 10.0^cycle
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")
@ -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
pop!(drivingCourse)
pop!(BS[:dataPoints])
else # if the level of approximation is reached
if drivingCourse[end][:v] <= 0.0
# 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.")
elseif drivingCourse[end][:v] > CS[:v_peak]
targetSpeedReached = true
pop!(drivingCourse)
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]
tractionSurplus = false
(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
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 #if
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.
# 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])
end
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
return (CS, drivingCourse)
end #function addAccelerationSection!
@ -398,44 +448,45 @@ end #function addAccelerationSection!
## This function calculates the data points of the acceleration section.
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)
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]
(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
# 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])
# 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]
if drivingCourse[end][:v] < CS[:v_peak] && drivingCourse[end][:s] < CS[:s_exit] && drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
# use the conditions for the acceleration section
if !targetSpeedReached && !trainAtEnd && tractionSurplus
BS = createBehaviorSection("acceleration", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
drivingCourse[end][:behavior] = BS[:type]
brakingStartReached = false
while !targetSpeedReached && !trainAtEnd && tractionSurplus && !brakingStartReached
currentStepSize=settings[:stepSize] # initialize the step size that can be reduced near intersections
nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])
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])
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
# 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])
while drivingCourse[end][:v] < CS[:v_peak] && drivingCourse[end][:s] +s_braking < CS[:s_exit] && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:F_T] > drivingCourse[end][:F_R] # as long as s_i + s_braking < s_CSexit
# acceleration (in m/s^2):
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
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
drivingCourse[end][:behavior] = BS[:type]
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
(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)
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])
end #while
# check which limit was reached and adjust the currentStepSize for the next cycle
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
elseif drivingCourse[end][:s] +s_braking > CS[:s_exit]
currentStepSize = settings[:stepSize] / 10.0^cycle
elseif drivingCourse[end][:v]>CS[:v_peak]
if settings[:stepVariable]=="v in m/s"
currentStepSize= CS[:v_peak]-drivingCourse[end-1][:v]
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]==CS[:s_exit]
break
elseif drivingCourse[end][:v]==CS[:v_peak]
break
elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R]
elseif drivingCourse[end][:v] > CS[:v_peak]
if settings[:stepVariable]=="v in m/s"
currentStepSize = CS[:v_peak]-drivingCourse[end-1][:v]
else
currentStepSize = settings[:stepSize] / 10.0^cycle
end
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
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
if drivingCourse[end][:v]<=0.0
# 01/21 should not be needed anymore with diminishing.
# push!(BS[:dataPoints], drivingCourse[end][:i])
error("ERROR: The train stops during the acceleration section in CS",CS[:id]," because the tractive effort is lower than the resistant forces.",
" Before the stop the last point has the values s=",drivingCourse[end-1][:s]," m v=",drivingCourse[end-1][:v]," m/s a=",drivingCourse[end-1][:a]," m/s^2",
" F_T=",drivingCourse[end-1][:F_T]," N R_traction=",drivingCourse[end-1][:R_traction]," N R_wagons=",drivingCourse[end-1][:R_wagons]," N R_path=",drivingCourse[end-1][:R_path]," N.")
elseif drivingCourse[end][:v]>CS[:v_peak]
pop!(drivingCourse)
pop!(BS[:dataPoints])
elseif drivingCourse[end][:s] + s_braking > CS[:s_exit]
elseif drivingCourse[end][:v] > CS[:v_peak]
targetSpeedReached = true
pop!(drivingCourse)
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]
tractionSurplus = false
(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
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 #for
end #while
if length(BS[:dataPoints]) > 1 # TODO: is it still possible that it is <=1 although there is a separate diminishing section?
# calculate the accumulated acceleration section information
@ -516,7 +594,8 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
merge!(CS[:behaviorSections], Dict(:acceleration=>BS))
end
end # else: just return the given data point number without changes due to the acceleration section
end
return (CS, drivingCourse)
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.
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)
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]
(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"))
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], CSs, CS[:id], "cruising", train, settings[:massModel])
s_cruising = max(0.0, s_cruising-get(CS[:behaviorSections], :diminishing, Dict(:length=>0.0))[:length])
end
if drivingCourse[end][:v]>0.0 && drivingCourse[end][:v]<=CS[:v_peak] && drivingCourse[end][:s]<CS[:s_exit] && drivingCourse[end][:F_T] >= drivingCourse[end][:F_R]
@ -542,13 +621,23 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
s_cruising = min(s_cruising, CS[:s_exit]-BS[:s_entry])
# traction effort and resisting forces (in N)
calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "cruising") # TODO: or give BS[:type] instead of "cruising"?
# 11/05 old: drivingCourse[end]=DataPoint(calculateForces!(drivingCourse[end], train, settings[:massModel], CSs, "cruising"))
calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel]) # TODO: or give BS[:type] instead of "cruising"?
# 11/05 old: drivingCourse[end]=DataPoint(calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel]))
if settings[:massModel]=="homogeneous strip" && CS[:id] > 1
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
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]
# 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?
@ -567,28 +656,39 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
push!(BS[:dataPoints], drivingCourse[end][:i])
# 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
# check which limit was reached and adjust the currentStepSize for the next cycle
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"
currentStepSize=BS[:s_entry] + s_cruising-drivingCourse[end-1][:s]
else
currentStepSize = settings[:stepSize] / 10.0^cycle
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
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]
# TODO: whithout CSs should work as well, no? elseif drivingCourse[end][:s] >= CSs[CS[:id]][:s_entry] + train[:length]
trainInPreviousCS = false
break
elseif drivingCourse[end][:s] == nextPointOfInterest
break
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")
end
@ -598,17 +698,21 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
pop!(BS[:dataPoints])
else # if the level of approximation is reached
if drivingCourse[end][:s] > BS[:s_entry]+s_cruising
if BS[:type] == "clearing"
else
if drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:s] = nextPointOfInterest # rounding s down to nextPointOfInterest
elseif drivingCourse[end][:s] > BS[:s_entry]+s_cruising
trainAtEnd = true
if BS[:type] != "clearing"
pop!(drivingCourse)
pop!(BS[:dataPoints])
end
elseif drivingCourse[end][:s] == BS[:s_entry]+s_cruising
trainAtEnd = true
break
elseif drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
tractionSurplus = false
(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])
@ -617,21 +721,26 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
end
end
end #for
end #while
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
# 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)
# 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
push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", s_cruisingRemaining, CS[:id]))
drivingCourse[end][:behavior] = BS[:type]
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
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
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])
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
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
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):
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])
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
# 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
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]
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]
# 11/21 old without s_braking: elseif drivingCourse[end][:s]==CS[:s_exit]
brakingStartReached = true
break
elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
currentStepSize = settings[:stepSize] / 10.0^cycle
elseif drivingCourse[end][:s] == nextPointOfInterest
break
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")
@ -698,23 +826,30 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
else # if the level of approximation is reached
if drivingCourse[end][:v] <= 0.0
targetSpeedReached = true
# 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.",
" Before the stop the last point has the values s=",drivingCourse[end-1][:s]," m v=",drivingCourse[end-1][:v]," m/s a=",drivingCourse[end-1][:a]," m/s^2",
" F_T=",drivingCourse[end-1][:F_T]," N R_traction=",drivingCourse[end-1][:R_traction]," N R_wagons=",drivingCourse[end-1][:R_wagons]," N R_path=",drivingCourse[end-1][:R_path]," N.")
elseif drivingCourse[end][: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]
tractionSurplus = true
break
else
end
end
end #if
end #if
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?
# 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
#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])
drivingCourse[end][:behavior] = BS[:type]
brakingStartReached = false
while !targetSpeedReached && !trainAtEnd && !brakingStartReached
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
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):
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):
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])
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
end # while
# 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]
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
currentStepSize = settings[:stepSize] / 10.0^cycle
elseif drivingCourse[end][:v] > CS[:v_peak]
if settings[:stepVariable]=="v in m/s"
currentStepSize = CS[:v_peak]-drivingCourse[end-1][:v]
currentStepSize = CS[:v_peak] - drivingCourse[end-1][:v]
else
currentStepSize = settings[:stepSize] / 10.0^cycle
end
elseif drivingCourse[end][:s] + s_braking == CS[:s_exit]
trainAtEnd = true
break
elseif drivingCourse[end][:v] == CS[:v_exit]
targetSpeedReached = true
break
elseif drivingCourse[end][:s] == nextPointOfInterest
break
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.")
elseif drivingCourse[end][:s] + s_braking > CS[:s_exit]
brakingStartReached = true
# delete last data point because it went to far
pop!(drivingCourse)
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
targetSpeedReached = true
# delete last data point because it went to far
pop!(drivingCourse)
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]))
drivingCourse[end][:behavior] = BS[:type]
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)
drivingCourse[end][:t] = drivingCourse[end-1][:t] + drivingCourse[end][:Δt] # point in time (in s)
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]
=#
elseif drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:s] = nextPointOfInterest # rounding s down to nextPointOfInterest
else
end
end
end #for
end #while
# calculate the accumulated coasting section information
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)
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)
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.
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)
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[:s_exit] = CS[:s_exit] # last position (in m)
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)
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())
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][:Δ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])
#= 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] = 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-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)
#:s_exit => drivingCourse[end][:s], # last position (in m)
: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
# 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)
#= TODO from 2022/01/22: integrate points of interest
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])
drivingCourse[end][:behavior] = BS[:type]
@ -926,7 +1084,7 @@ function addBrakingSectionStepwise!(CS::Dict, drivingCourse::Vector{Dict}, setti
velocityIsPositive = true
while drivingCourse[end][:v] > CS[:v_exit] && drivingCourse[end][:s] < CS[:s_exit] && velocityIsPositive
# 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):
drivingCourse[end][:a] = train[:a_braking]
@ -985,6 +1143,7 @@ function addBrakingSectionStepwise!(CS::Dict, drivingCourse::Vector{Dict}, setti
merge!(CS[:behaviorSections], Dict(:braking=>BS))
end # else: return the characteristic section without a braking section
=#
return (CS, drivingCourse)
end #function addBrakingSectionStepwise!
@ -1002,7 +1161,7 @@ function addStandstill!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, t
drivingCourse[end][:behavior] = BS[:type]
# 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))
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]
currentSection = path[:sections][row]
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]
csId = csId+1
end #if
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
: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.
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
characteristicSection= Dict(:id => csId, # identifier
:s_entry => s_csStart, # first position (in m)
characteristicSection= Dict(:id => id, # identifier
:s_entry => s_entry, # first 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 ‰)
:behaviorSections => Dict(), # list of containing behavior sections
:t => 0.0, # total running time (in s)
: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
:v_peak => v_csLimit, # maximum reachable speed (in m/s)
:v_entry => v_csLimit, # maximum entry speed (in m/s)
:v_exit => v_csLimit) # maximum exit speed (in m/s)
:v_peak => v_limit, # maximum reachable speed (in m/s)
:v_entry => v_limit, # maximum entry 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
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 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/22: use always copyCharacteristicSection and don't do it manually like "csModified=Dict(:id => csOriginal[:id], ..." three times
module EnergySaving
@ -35,7 +36,7 @@ function addOperationModeEnergySaving!(summarizedDict::Dict)
# summarize data and create an output dictionary
merge!(summarizedDict, Dict(:movingSectionMinimumEnergyConsumption => movingSectionMinimumEnergyConsumption, :drivingCourseMinimumEnergyConsumption => drivingCourseMinimumEnergyConsumption))
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
return summarizedDict
@ -275,7 +276,8 @@ function copyCharacteristicSection(originalCS::Dict)
:v_limit => originalCS[:v_limit], # speed limit (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_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
end # CharacteristicSection
@ -699,7 +701,8 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
:v_limit => csOriginal[:v_limit], # speed limit (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_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]
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_peak => csOriginal[:v_peak], # maximum reachable 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]
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_peak => csOriginal[:v_peak], # maximum reachable 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]
if haskey(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.
"""
function importYamlFiles(trainDirectory::String, pathDirectory::String, settingsDirectory::String)
train=importTrainFromYaml(trainDirectory)
path=importPathFromYaml(pathDirectory)
settings=importSettingsFromYaml(settingsDirectory)
train = importTrainFromYaml(trainDirectory)
path = importPathFromYaml(pathDirectory)
settings = importSettingsFromYaml(settingsDirectory)
return (train, path, settings)
end #function importYamlFiles
@ -122,6 +122,8 @@ function importPathFromYaml(pathDirectory::String)
:id => id,
:sections => sections)
addPointsOfInterest!(path, data)
informAboutUnusedKeys(data, "path") # inform the user, which keywords of the imported data are not used in this tool
return path
@ -502,6 +504,48 @@ function getSections!(data::Dict)
return sections
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
if length(data[dataSet])>0
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)
# TODO checkId ? path[:id] # path identifier
checkAndSetSections!(path)
checkAndSetPOIs!(path)
# 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
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
#= if length(dictionary)>0
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
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))
# adding moving section and drving courses
# add moving section and driving courses
if settings[:operationModeMinimumRunningTime] == true
merge!(outputDict, Dict(:movingSectionMinimumRunningTime => movingSection, :drivingCourseMinimumRunningTime => drivingCourse))
merge!(outputDict, Dict(:movingSectionMinimumRunningTime => movingSection,
:drivingCourseMinimumRunningTime => drivingCourse))
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
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"
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.")
# 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
# 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[:E] = 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.01 # if the cruising section is longer than 1 cm (because of rounding issues not >0.0)
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
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
s_braking=max(0.0, ceil((CS[:v_exit]^2-drivingCourse[end][:v]^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
if drivingCourse[end][:v] > CS[:v_exit]
#(CS, drivingCourse)=addBrakingSection!(CS, drivingCourse, settings[:massModel], train, CSs)
@ -138,7 +132,7 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
end =#
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[:E] = drivingCourse[end][:E] # total energy consumption (in Ws)

View File

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