From 29c4ec0d5bd4fbd585dca74edc6936747d8f1713 Mon Sep 17 00:00:00 2001 From: Max Kannenberg <95709892+MaxKannenberg@users.noreply.github.com> Date: Wed, 23 Feb 2022 01:19:19 +0100 Subject: [PATCH] Merge functions addAccelerationSection! and addAccelerationSectionUntilBraking! --- src/Behavior.jl | 79 +++++++++++++++++++++++++++++++----------- src/Characteristics.jl | 10 +++++- src/DrivingDynamics.jl | 5 ++- src/EnergySaving.jl | 34 +++++++++++------- src/TrainRunCalc.jl | 45 ++++++++++++++++++------ 5 files changed, 125 insertions(+), 48 deletions(-) diff --git a/src/Behavior.jl b/src/Behavior.jl index 010ee60..4fa4575 100644 --- a/src/Behavior.jl +++ b/src/Behavior.jl @@ -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] 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]) @@ -496,11 +516,14 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic brakingStartReached = false while !targetSpeedReached && !trainAtEnd && tractionSurplus && !brakingStartReached - currentStepSize=settings[:stepSize] # initialize the step size that can be reduced near intersections + currentStepSize = settings[:stepSize] # initialize the step size that can be reduced near intersections nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s]) for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation - s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) + 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]) - s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) + 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 @@ -541,7 +568,7 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic end elseif drivingCourse[end][:v] > CS[:v_peak] - if settings[:stepVariable]=="v in m/s" + if settings[:stepVariable] == "v in m/s" currentStepSize = CS[:v_peak]-drivingCourse[end-1][:v] else currentStepSize = settings[:stepSize] / 10.0^cycle @@ -559,17 +586,17 @@ 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 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,16 +639,16 @@ 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) - merge!(CS[:behaviorSections], Dict(:acceleration=>BS)) + merge!(CS[:behaviorSections], Dict(:acceleration => BS)) end 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]) @@ -967,7 +1002,7 @@ function addCoastingSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict}, currentStepSize = settings[:stepSize] / 10.0^cycle end elseif drivingCourse[end][:v] > CS[:v_peak] - if settings[:stepVariable]=="v in m/s" + if settings[:stepVariable] == "v in m/s" currentStepSize = CS[:v_peak] - drivingCourse[end-1][:v] else currentStepSize = settings[:stepSize] / 10.0^cycle @@ -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 diff --git a/src/Characteristics.jl b/src/Characteristics.jl index 8cd5261..7ec3006 100644 --- a/src/Characteristics.jl +++ b/src/Characteristics.jl @@ -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] diff --git a/src/DrivingDynamics.jl b/src/DrivingDynamics.jl index 409255e..5946e0e 100644 --- a/src/DrivingDynamics.jl +++ b/src/DrivingDynamics.jl @@ -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 diff --git a/src/EnergySaving.jl b/src/EnergySaving.jl index e0a52ee..6ec9305 100644 --- a/src/EnergySaving.jl +++ b/src/EnergySaving.jl @@ -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] @@ -961,7 +968,8 @@ function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict println(" Therefore s=",drivingCourseModified[end][:s]," will be set s_exit=",csModified[:s_exit]," because the difference is only ",csModified[:s_exit]-drivingCourseModified[end][:s]," m.") 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] = 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] diff --git a/src/TrainRunCalc.jl b/src/TrainRunCalc.jl index 25e3527..e7fbaec 100644 --- a/src/TrainRunCalc.jl +++ b/src/TrainRunCalc.jl @@ -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)