Integrate calculation for additional points of interest
parent
8802ef7bc7
commit
917a16782d
|
@ -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)
|
||||
```
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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
|
||||
|
|
413
src/Behavior.jl
413
src/Behavior.jl
|
@ -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 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]
|
||||
|
||||
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,7 +338,6 @@ 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)
|
||||
|
@ -312,7 +346,9 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
|
|||
end #if
|
||||
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,9 +356,12 @@ 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
|
||||
|
@ -335,12 +374,15 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
|
|||
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
|
||||
|
@ -390,7 +440,7 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
|
|||
|
||||
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 addAccelerationSection!
|
||||
|
@ -402,40 +452,41 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
|
|||
(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,7 +494,7 @@ 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
|
||||
|
||||
|
@ -451,10 +502,21 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
|
|||
if cycle < approximationLevel+1
|
||||
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][: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_peak]
|
||||
if settings[:stepVariable]=="v in m/s"
|
||||
currentStepSize = CS[:v_peak]-drivingCourse[end-1][:v]
|
||||
|
@ -463,13 +525,15 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
|
|||
end
|
||||
|
||||
elseif drivingCourse[end][:s] == CS[:s_exit]
|
||||
trainAtEnd = true
|
||||
break
|
||||
|
||||
elseif drivingCourse[end][:v] == CS[:v_peak]
|
||||
targetSpeedReached = 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 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]
|
||||
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
|
||||
# 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]
|
||||
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,6 +912,13 @@ 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
|
||||
|
||||
|
@ -781,9 +929,14 @@ function addCoastingSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict},
|
|||
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!
|
||||
|
||||
|
@ -869,8 +1010,28 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic
|
|||
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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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])
|
||||
|
|
|
@ -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:")
|
||||
|
|
47
src/Input.jl
47
src/Input.jl
|
@ -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:")
|
||||
|
|
|
@ -6,11 +6,34 @@ function createOutputDict(train::Dict, settings::Dict, path::Dict, movingSection
|
|||
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
|
||||
|
|
|
@ -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
|
||||
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue