Merge functions addAccelerationSection! and addAccelerationSectionUntilBraking!

development
Max Kannenberg 2022-02-23 01:19:19 +01:00
parent 9081b61903
commit 29c4ec0d5b
5 changed files with 125 additions and 48 deletions

View File

@ -1,9 +1,16 @@
#!/usr/bin/env julia
# -*- coding: UTF-8 -*-
# __julia-version__ = 1.7.2
# __author__ = "Max Kannenberg"
# __copyright__ = "2020-2022"
# __license__ = "ISC"
module Behavior
include("./DrivingDynamics.jl")
using .DrivingDynamics
export addAccelerationSection!, addAccelerationSectionUntilBraking!, addCruisingSection!, addCoastingSectionUntilBraking!, addBrakingSection!, addBrakingSectionInOneStep!, addStandstill!,
export addAccelerationSection!, addCruisingSection!, addCoastingSection!, addBrakingSection!, addStandstill!,
# addBrakingSectionInOneStep! is not used in the current version of the tool
calculateForces!, createDataPoint,
@ -234,7 +241,7 @@ function getNextPointOfInterest(pointsOfInterest::Vector{Real}, s::Real)
return POI
end
end
error("ERROR in getNextPointOfInterest: There is no POI higher than s.")
error("ERROR in getNextPointOfInterest: There is no POI higher than s=",s," m.")
end #function getNextPointOfInterest
## This function calculates the data points of the breakFree section.
@ -242,7 +249,7 @@ end #function getNextPointOfInterest
# Info: currently the values of the breakFree section will be calculated like in the acceleration section
function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict})
if settings[:stepVariable] == "v in m/s"
println("WARNING: ! ! ! TrainRun doesn't work reliably for the step variable v. Therefore v should not be used ! ! !")
println("WARNING: ! ! ! TrainRun.jl doesn't work reliably for the step variable v. Therefore v should not be used ! ! !")
end
if drivingCourse[end][:v]==0.0 && drivingCourse[end][:s]<CS[:s_exit]
BS = createBehaviorSection("breakFree", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
@ -283,6 +290,7 @@ function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::D
pop!(BS[:dataPoints])
else
drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s]
brokenFree = true
break#free
end
@ -318,7 +326,7 @@ 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})
function addAccelerationSectionWithoutBraking!(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]
@ -413,6 +421,7 @@ 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])
@ -427,6 +436,7 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
elseif drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s]
elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R]
tractionSurplus = false
@ -466,11 +476,17 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
end
return (CS, drivingCourse)
end #function addAccelerationSection!
end #function addAccelerationSectionWithoutBraking!
## This function calculates the data points of the acceleration section.
function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict})
function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, ignoreBraking::Bool)
#function addAccelerationSectionUntilBraking!(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
@ -481,6 +497,10 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
calculateForces!(drivingCourse[end], CSs, CS[:id], "acceleration", train, settings[:massModel])
end
if ignoreBraking
s_braking = 0.0
end
# if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
formerSpeedLimits = detectFormerSpeedLimits(CSs, CS[:id], drivingCourse[end], train[:length])
@ -500,7 +520,10 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
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
if !ignoreBraking
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
end
while drivingCourse[end][:v] < CS[:v_peak] && drivingCourse[end][:s] +s_braking < CS[:s_exit] && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:F_T] > drivingCourse[end][:F_R] # as long as s_i + s_braking < s_CSexit
# acceleration (in m/s^2):
@ -517,8 +540,12 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
return (CS, drivingCourse)
end
end
# TODO: do the following that was done here in addAccelerationSection_without_Braking! currentStepSize = settings[:stepSize] # initialize the step size that can be reduced near intersections
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
if !ignoreBraking
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
end
end #while
# check which limit was reached and adjust the currentStepSize for the next cycle
@ -559,7 +586,7 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
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")
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")
end
# delete last data point for recalculating the last step with reduced step size
pop!(drivingCourse)
@ -569,7 +596,7 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
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.",
error("ERROR: The train stops during the acceleration section in CS",CS[:id]," between the positions ",drivingCourse[end-1][:s]," m and ",drivingCourse[end][:s]," m because the tractive effort is lower than the resistant forces.",
" 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.")
@ -585,6 +612,7 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
elseif drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s]
elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R]
tractionSurplus = false
@ -611,7 +639,7 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
:E => drivingCourse[end][:E] - drivingCourse[BS[:dataPoints][1]][:E], # total energy consumption (in Ws)
:v_exit => drivingCourse[end][:v])) # exit speed (in m/s)))
CS[:v_peak] = max(drivingCourse[end][:v], CS[:v_entry]) # setting v_peak to the last data points velocity which is the highest reachable value in this characteristic section or to v_entry in case it is higher when driving on a path with high resistances
CS[:v_peak] = max(drivingCourse[end][:v], CS[:v_entry]) # setting v_peak to the last data points velocity which is the highest reachable value in this characteristic section or to v_entry in case it is higher when running on a path with high resistances
CS[:t] = CS[:t] + BS[:t] # total running time (in s)
CS[:E] = CS[:E] + BS[:E] # total energy consumption (in Ws)
@ -620,7 +648,7 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
end
return (CS, drivingCourse)
end #function addAccelerationSectionUntilBraking!
end #function addAccelerationSection!
## This function calculates the data points of the cruising section.
@ -729,6 +757,7 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
else # if the level of approximation is reached
if drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s]
elseif drivingCourse[end][:s] > BS[:s_entry]+s_cruising
trainAtEnd = true
if BS[:type] != "clearing"
@ -834,7 +863,7 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
currentStepSize = settings[:stepSize] / 10.0^cycle
elseif drivingCourse[end][:s] + s_braking > CS[:s_exit]
elseif s_braking > 0.0 && drivingCourse[end][:s] + s_braking > CS[:s_exit]
currentStepSize = settings[:stepSize] / 10.0^cycle
elseif drivingCourse[end][:s] > nextPointOfInterest
@ -873,13 +902,14 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
" Before the stop the last point has the values s=",drivingCourse[end-1][:s]," m v=",drivingCourse[end-1][:v]," m/s a=",drivingCourse[end-1][:a]," m/s^2",
" F_T=",drivingCourse[end-1][:F_T]," N R_traction=",drivingCourse[end-1][:R_traction]," N R_wagons=",drivingCourse[end-1][:R_wagons]," N R_path=",drivingCourse[end-1][:R_path]," N.")
elseif drivingCourse[end][:s] + s_braking > CS[:s_exit]
elseif s_braking > 0.0 && drivingCourse[end][:s] + s_braking > CS[:s_exit]
brakingStartReached = true
pop!(drivingCourse)
pop!(BS[:dataPoints])
elseif drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s]
elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
tractionSurplus = true
@ -888,6 +918,11 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
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 #if
end #for
end #while
@ -913,7 +948,7 @@ end #function addDiminishingSection!
## This function calculates the data points of the coasting section.
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the coasting section
function addCoastingSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict})
function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict})
## if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
#formerSpeedLimits = detectFormerSpeedLimits(CSs, CS[:id], drivingCourse[end], train[:length])
@ -1021,6 +1056,7 @@ function addCoastingSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict},
elseif drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s]
else
end
@ -1042,7 +1078,7 @@ function addCoastingSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict},
end
return (CS, drivingCourse)
end #function addCoastingSectionUntilBraking!
end #function addCoastingSection!
## This function calculates the data points of the braking section. (standard braking section with only two data points)
@ -1227,6 +1263,7 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic
break
elseif drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s]
break
elseif drivingCourse[end][:v] == CS[:v_exit] && drivingCourse[end][:s] == CS[:s_exit]
targetSpeedReached = true

View File

@ -1,3 +1,10 @@
#!/usr/bin/env julia
# -*- coding: UTF-8 -*-
# __julia-version__ = 1.7.2
# __author__ = "Max Kannenberg"
# __copyright__ = "2020-2022"
# __license__ = "ISC"
module Characteristics
include("./Behavior.jl")
@ -121,7 +128,8 @@ function secureAccelerationBehavior!(movingSection::Dict, settings::Dict, train:
accelerationCourse::Vector{Dict} = [startingPoint] # List of data points
if CSs[csId][:v_entry] < CSs[csId][:v_peak]
(CSs[csId], accelerationCourse) = addAccelerationSection!(CSs[csId], accelerationCourse, settings, train, CSs) # this function changes the accelerationCourse
# 02/22 old (CSs[csId], accelerationCourse) = addAccelerationSection!(CSs[csId], accelerationCourse, settings, train, CSs) # this function changes the accelerationCourse
(CSs[csId], accelerationCourse) = addAccelerationSection!(CSs[csId], accelerationCourse, settings, train, CSs, true) # this function changes the accelerationCourse
CSs[csId][:v_peak] = max(CSs[csId][:v_entry], accelerationCourse[end][:v])
CSs[csId][:v_exit] = min(CSs[csId][:v_exit], CSs[csId][:v_peak], accelerationCourse[end][:v])
else #CSs[csId][:v_entry]==CSs[csId][:v_peak]

View File

@ -1,6 +1,6 @@
#!/usr/bin/env julia
# -*- coding: UTF-8 -*-
# __julia-version__ = 1.7.0
# __julia-version__ = 1.7.2
# __author__ = "Max Kannenberg"
# __copyright__ = "2022"
# __license__ = "ISC"
@ -53,7 +53,7 @@ calc_ΔW, calc_ΔE,
# export braking information
calcBrakingDistance, calcBrakingStartVelocity, calcBrakingAcceleration
v00 = 100/3.6 # velocity constant (in m/s)
v00 = 100/3.6 # velocity factor (in m/s)
g = 9.81 # acceleration due to gravity (in m/s^2) # TODO: should more digits of g be used? g=9,80665 m/s^2
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)
@ -199,7 +199,6 @@ function calc_Δv_with_Δt(Δt::Real, a_prev::Real)
# Δt: time step (in s)
# a_prev: acceleration from previous data point
# v_prev: velocitiy from previous data point
Δv = Δt * a_prev # step size (in m/s)
return Δv
end #function calc_Δv_with_Δt

View File

@ -1,3 +1,10 @@
#!/usr/bin/env julia
# -*- coding: UTF-8 -*-
# __julia-version__ = 1.7.2
# __author__ = "Max Kannenberg"
# __copyright__ = "2020-2022"
# __license__ = "ISC"
# INFO: EnergySaving should not be used because it is not completed yet. It was used to show the possibility of calculating different operation modes.
# TODO: It has to be optimized so that each ernergy saving method is working individually for every train on every path.
@ -24,22 +31,22 @@ approximationLevel = 6 # value for approximation to intersections
## functions for calculating the operation mode for the minimum energy consumption
# calculate the train run for operation mode "minimum energy consumption"
function addOperationModeEnergySaving!(summarizedDict::Dict)
if summarizedDict[:settings][:operationModeMinimumEnergyConsumption] == true
movingSectionMinimumRunningTime = summarizedDict[:movingSectionMinimumRunningTime]
drivingCourseMinimumRunningTime = summarizedDict[:drivingCourseMinimumRunningTime]
settings = summarizedDict[:settings]
train = summarizedDict[:train]
function addOperationModeEnergySaving!(accumulatedDict::Dict)
if accumulatedDict[:settings][:operationModeMinimumEnergyConsumption] == true
movingSectionMinimumRunningTime = accumulatedDict[:movingSectionMinimumRunningTime]
drivingCourseMinimumRunningTime = accumulatedDict[:drivingCourseMinimumRunningTime]
settings = accumulatedDict[:settings]
train = accumulatedDict[:train]
(movingSectionMinimumEnergyConsumption, drivingCourseMinimumEnergyConsumption)=calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime, drivingCourseMinimumRunningTime, settings, train)
println("The driving course for the lowest energy consumption has been calculated.")
# summarize data and create an output dictionary
merge!(summarizedDict, Dict(:movingSectionMinimumEnergyConsumption => movingSectionMinimumEnergyConsumption, :drivingCourseMinimumEnergyConsumption => drivingCourseMinimumEnergyConsumption))
# accumulate data and create an output dictionary
merge!(accumulatedDict, Dict(:movingSectionMinimumEnergyConsumption => movingSectionMinimumEnergyConsumption, :drivingCourseMinimumEnergyConsumption => drivingCourseMinimumEnergyConsumption))
else
println("No output for minimum energy consumption has been demanded and so none will be calculated.")
end #if
return summarizedDict
return accumulatedDict
end #function addOperationModeEnergySaving!
function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict, drivingCourseMinimumRunningTime::Vector{Dict}, settings::Dict, train::Dict)
@ -603,7 +610,7 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
end
# calculate the coasting phase until the point the train needs to brake
(csModified, drivingCourseModified)=addCoastingSectionUntilBraking!(csModified, drivingCourseModified, settings, train, allCSs)
(csModified, drivingCourseModified)=addCoastingSection!(csModified, drivingCourseModified, settings, train, allCSs)
if drivingCourseModified[end][:v] < csModified[:v_exit] || drivingCourseModified[end][:s] > csModified[:s_exit]
# the train reaches v_exit before reaching s_exit. The cruising and coasting sections have to be calculated again with a larger cruising section (so with a smaller reduction of the cruising section)
@ -737,7 +744,7 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
end
# calculate the coasting phase until the point the train needs to brake
(csModified, drivingCourseModified)=addCoastingSectionUntilBraking!(csModified, drivingCourseModified, settings, train, allCSs)
(csModified, drivingCourseModified)=addCoastingSection!(csModified, drivingCourseModified, settings, train, allCSs)
if drivingCourseModified[end][:v] < csModified[:v_exit] || drivingCourseModified[end][:s] > csModified[:s_exit]
# the train reaches v_exit before reaching s_exit. The cruising and coasting sections have to be calculated again with a larger cruising section (so with a smaller reduction of the cruising section)
@ -831,7 +838,7 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
drivingCourseModified = copy(drivingCourse[1:energySavingStartId]) # List of data points till the start of energy saving
# calculate the coasting phase until the point the train needs to brake
(csModified, drivingCourseModified)=addCoastingSectionUntilBraking!(csModified, drivingCourseModified, settings, train, allCSs)
(csModified, drivingCourseModified)=addCoastingSection!(csModified, drivingCourseModified, settings, train, allCSs)
# calculate the moving phase between coasting and the end of the CS
if drivingCourseModified[end][:v] > csModified[:v_exit]
@ -962,6 +969,7 @@ function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict
println(" v=",drivingCourseModified[end][:v]," m/s v_exit=",csOriginal[:v_exit] ," m/s")
drivingCourseModified[end][:s] = csModified[:s_exit] # rounding up to s_exit
drivingCourseModified[end][:Δs] = drivingCourseModified[end][:s] - drivingCourseModified[end-1][:s]
end #if
if t_recoveryAvailable >= csModified[:t] - csOriginal[:t]

View File

@ -1,3 +1,10 @@
#!/usr/bin/env julia
# -*- coding: UTF-8 -*-
# __julia-version__ = 1.7.2
# __author__ = "Max Kannenberg"
# __copyright__ = "2020-2022"
# __license__ = "ISC"
module TrainRunCalc
# include modules of TrainRunCalc
@ -34,7 +41,7 @@ todo !!!
"""
function calculateDrivingDynamics(trainInput::Dict, pathInput::Dict, settingsInput::Dict)
# copy Input data for not changing them
# TODO: or should they be changed? enormally it would only make it "better" except for settings[:detailOfOutput] == "points of interest" && !haskey(path, :pointsOfInterest)
# TODO: or should they be changed? normally it would only make it "better" except for settings[:detailOfOutput] == "points of interest" && !haskey(path, :pointsOfInterest)
train = copy(trainInput)
path = copy(pathInput)
settings = copy(settingsInput)
@ -52,7 +59,7 @@ function calculateDrivingDynamics(trainInput::Dict, pathInput::Dict, settingsInp
(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
# accumulate data and create an output dictionary
output = createOutputDict(train, settings, path, movingSection, drivingCourse)
else
output = Dict()
@ -72,10 +79,22 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
# for CS in CSs
for csId in 1:length(CSs)
# check if the CS has a cruising section
CS = CSs[csId]
BSs = CS[:behaviorSections]
# for testing:
if drivingCourse[end][:s] != CS[:s_entry]
if haskey(BSs, :cruising)
println("ERROR: In CS", csId," the train run starts at s=",drivingCourse[end][:s]," and not s_entry=",CS[:s_entry])
end
end
if drivingCourse[end][:v] > CS[:v_entry]
if haskey(BSs, :cruising)
println("ERROR: In CS", csId," the train run ends with v=",drivingCourse[end][:v]," and not with v_entry=",CS[:v_entry])
end
end
# check if the CS has a cruising section
s_breakFree = get(BSs, :breakFree, Dict(:length=>0.0))[:length]
s_clearing = get(BSs, :clearing, Dict(:length=>0.0))[:length]
s_acceleration = get(BSs, :acceleration, Dict(:length=>0.0))[:length]
@ -100,7 +119,7 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
elseif s_cruising > 0.0 || s_braking == 0.0
if drivingCourse[end][:v] < CS[:v_peak]
(CS, drivingCourse) = addAccelerationSection!(CS, drivingCourse, settings, train, CSs)
(CS, drivingCourse) = addAccelerationSection!(CS, drivingCourse, settings, train, CSs, false) # TODO or better ignoreBraking = true?
end #if
if CS[:s_exit]-drivingCourse[end][:s]-max(0.0, (CS[:v_exit]^2-drivingCourse[end][:v]^2)/2/train[:a_braking]) < -0.001 # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
@ -118,7 +137,8 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
else
if CS[:v_entry] < CS[:v_peak] || s_acceleration > 0.0 # or instead of " || s_acceleration > 0.0" use "v_entry <= v_peak" or "v_i <= v_peak"
# 09/09 old (not sufficient for steep gradients): if CS[:v_entry] < CS[:v_peak]
(CS, drivingCourse)=addAccelerationSectionUntilBraking!(CS, drivingCourse, settings, train, CSs)
# old 02/22 (CS, drivingCourse)=addAccelerationSectionUntilBraking!(CS, drivingCourse, settings, train, CSs)
(CS, drivingCourse) = addAccelerationSection!(CS, drivingCourse, settings, train, CSs, false)
end #if
end #if
@ -129,13 +149,18 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
(CS, drivingCourse)=addBrakingSection!(CS, drivingCourse, settings, train, CSs)
end #if
#= 09/20 old and should never be used:
if drivingCourse[end][:s] < CS[:s_exit]
# for testing:
if drivingCourse[end][:s] != CS[:s_exit]
if haskey(BSs, :cruising)
println("INFO: A second cruising section has been added to CS ", csId," from s=",drivingCourse[end][:s]," to s_exit=",CS[:s_exit])
println("ERROR: In CS", csId," the train run ends at s=",drivingCourse[end][:s]," and not s_exit=",CS[:s_exit])
end
(CS, drivingCourse)=addCruisingSection!(CS, drivingCourse, s_cruising, settings, train, CSs, "cruising")
end =#
end
if drivingCourse[end][:v] > CS[:v_exit]
if haskey(BSs, :cruising)
println("ERROR: In CS", csId," the train run ends with v=",drivingCourse[end][:v]," and not with v_exit=",CS[:v_exit])
end
end
end #for
(CSs[end], drivingCourse) = addStandstill!(CSs[end], drivingCourse, settings, train, CSs)