diff --git a/src/AdditionalOutput.jl b/src/AdditionalOutput.jl index e3f3c09..99c6b2f 100644 --- a/src/AdditionalOutput.jl +++ b/src/AdditionalOutput.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: AdditionalOutput should not be used because it is not completed yet. It was used to show first results during development. # TODO: It has to be optimized so that the created plots and printed information is clear and understandable. @@ -38,9 +45,11 @@ function plotDrivingCourse(drivingCourse::Vector{Dict}) push!(v, drivingCourse[i][:v]) end #for - p1=plot([s], [v], title = "v in m/s", label = ["v"], xlabel = "s in m") +# p1=plot([s], [v], title = "v in m/s", label = ["v"], xlabel = "s in m") + p1=plot([s/1000], [v*3.6], title = "v in km/h", label = ["v"], xlabel = "s in km") - p2=plot([t], [v], title = "v in m/s", label = ["v"], xlabel = "t in s") +# p2=plot([t], [v], title = "v in m/s", label = ["v"], xlabel = "t in s") + p2=plot([t/60], [v*3.6], title = "v in km/h", label = ["v"], xlabel = "t in min") # p3=plot([s], [t], title = "t in s", label = ["t"], xlabel = "s in m") @@ -137,7 +146,7 @@ function printSectionInformation(movingSection::Dict) CSs::Vector{Dict} = movingSection[:characteristicSections] println("MS with length=", movingSection[:length]," with t=", movingSection[:t]) - allBs=[:breakFree, :clearing, :acceleration, :cruising, :diminishing, :coasting, :braking, :standstill] + allBs=[:breakFree, :clearing, :accelerating, :cruising, :diminishing, :coasting, :braking, :standstill] for csId in 1:length(CSs) println("CS ",csId," with length=", CSs[csId][:length]," with t=", CSs[csId][:t]) for bs in 1: length(allBs) diff --git a/src/Behavior.jl b/src/Behavior.jl index 5198b8f..1dde12f 100644 --- a/src/Behavior.jl +++ b/src/Behavior.jl @@ -10,7 +10,7 @@ module Behavior include("./DrivingDynamics.jl") using .DrivingDynamics -export addAccelerationSection!, addCruisingSection!, addCoastingSection!, addBrakingSection!, addStandstill!, +export addAcceleratingSection!, addCruisingSection!, addCoastingSection!, addBrakingSection!, addStandstill!, # addBrakingSectionInOneStep! is not used in the current version of the tool calculateForces!, createDataPoint, @@ -92,7 +92,7 @@ function calculateForces!(dataPoint::Dict, CSs::Vector{Dict}, csId::Integer, bs dataPoint[:F_R] = dataPoint[:R_train] + dataPoint[:R_path] # calculate tractive effort - if bsType == "acceleration" || bsType == "diminishing" + if bsType == "accelerating" || bsType == "diminishing" dataPoint[:F_T] = calculateTractiveEffort(dataPoint[:v], train[:tractiveEffortVelocityPairs]) elseif bsType == "cruising" dataPoint[:F_T] = min(max(0.0, dataPoint[:F_R]), calculateTractiveEffort(dataPoint[:v], train[:tractiveEffortVelocityPairs])) @@ -126,7 +126,7 @@ function moveAStep(previousPoint::Dict, stepVariable::String, stepSize::Real, cs newPoint[:Δv] = 0.0 # step size (in m/s) else if previousPoint[:a] < 0.0 && ((previousPoint[:v]/previousPoint[:a])^2+2*newPoint[:Δs]/previousPoint[:a])<0.0 || (previousPoint[:v]^2+2*newPoint[:Δs]*previousPoint[:a])<0.0 # checking if the parts of the following square roots will be <0.0 - error("ERROR: The train stops during the acceleration section in CS",csId," because the tractive effort is lower than the resistant forces.", + error("ERROR: The train stops during the accelerating section in CS",csId," because the tractive effort is lower than the resistant forces.", " Before the stop the last point has the values s=",previousPoint[:s]," m, v=",previousPoint[:v]," m/s, a=",previousPoint[:a]," m/s^2,", " F_T=",previousPoint[:F_T]," N, R_traction=",previousPoint[:R_traction]," N, R_wagons=",previousPoint[:R_wagons]," N, R_path=",previousPoint[:R_path]," N.") end @@ -169,14 +169,15 @@ end #function moveAStep """ -# if the tail of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept +# if the rear of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept """ +#= function detectFormerSpeedLimits(CSs::Vector{Dict}, csWithTrainHeadId::Integer, currentPoint::Dict, trainLength::Real) formerSpeedLimits=[] if csWithTrainHeadId > 1 && currentPoint[:s] - trainLength < CSs[csWithTrainHeadId][:s_entry] formerCsId=csWithTrainHeadId-1 while formerCsId > 0 && currentPoint[:s] - trainLength < CSs[formerCsId][:s_exit] - if CSs[formerCsId][:v_limit] < CSs[csWithTrainHeadId][:v_limit] # TODO: is the position of trains tail < movingSection[:s_entry], v_limit of the first CS is used + if CSs[formerCsId][:v_limit] < CSs[csWithTrainHeadId][:v_limit] # TODO: is the position of train's rear < movingSection[:s_entry], v_limit of the first CS is used push!(formerSpeedLimits, [CSs[formerCsId][:s_exit], CSs[formerCsId][:v_limit]]) for i in 1:length(formerSpeedLimits)-1 if formerSpeedLimits[i][2]<=formerSpeedLimits[end][2] @@ -191,13 +192,13 @@ function detectFormerSpeedLimits(CSs::Vector{Dict}, csWithTrainHeadId::Integer, return formerSpeedLimits end # function detectFormerSpeedLimits -function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, formerSpeedLimits, accelerationSection::Dict) - # TODO: What is the type of formerSpeedLimits? function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, formerSpeedLimits::Array{Array{AbstractFloat,1},1}, accelerationSection::Dict) - # would work: function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, formerSpeedLimits::Array{Any,1}, accelerationSection::Dict) +function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, formerSpeedLimits, acceleratingSection::Dict) + # TODO: What is the type of formerSpeedLimits? function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, formerSpeedLimits::Array{Array{AbstractFloat,1},1}, acceleratingSection::Dict) + # would work: function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, formerSpeedLimits::Array{Any,1}, acceleratingSection::Dict) if length(formerSpeedLimits) > 0 - # if a former speed limit has been exceeded the acceleration steps of this CS will be removed and a clearing section will be inserted before acceleration + # if a former speed limit has been exceeded the accelerating steps of this CS will be removed and a clearing section will be inserted before accelerating if drivingCourse[end][:v] > formerSpeedLimits[end][2] - while drivingCourse[end][:s] > get(CS[:behaviorSections], :clearing, accelerationSection)[:s_entry] + while drivingCourse[end][:s] > get(CS[:behaviorSections], :clearing, acceleratingSection)[:s_entry] pop!(drivingCourse) end @@ -219,10 +220,10 @@ function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{Dict}, setti # 09/22: if drivingCourse[end][:s] < CS[:s_exit] if drivingCourse[end][:s] < CS[:s_exit] - s_braking - # reset the accelerationSection - accelerationSection = createBehaviorSection("acceleration", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) + # reset the acceleratingSection + acceleratingSection = createBehaviorSection("accelerating", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) else - return (CS, drivingCourse, formerSpeedLimits, accelerationSection, true) + return (CS, drivingCourse, formerSpeedLimits, acceleratingSection, true) end end @@ -231,9 +232,62 @@ function considerFormerSpeedLimits!(CS::Dict, drivingCourse::Vector{Dict}, setti pop!(formerSpeedLimits) end end - return (CS, drivingCourse, formerSpeedLimits, accelerationSection, false) + return (CS, drivingCourse, formerSpeedLimits, acceleratingSection, false) end # function considerFormerSpeedLimits! +=# +function considerFormerSpeedLimit!(CS::Dict, drivingCourse::Vector{Dict}, acceleratingSection::Dict, settings::Dict, train::Dict, CSs::Vector{Dict}, currentSpeedLimit::Dict) + # if a former speed limit has been exceeded the accelerating steps of this CS will be removed and a clearing section will be inserted before accelerating + if drivingCourse[end][:v] > currentSpeedLimit[:v] + # delete existing clearing section that is not long enough + while drivingCourse[end][:s] > get(CS[:behaviorSections], :clearing, acceleratingSection)[:s_entry] + pop!(drivingCourse) + end + + if haskey(CS[:behaviorSections], :clearing) + CS[:t] = CS[:t]-CS[:behaviorSections][:clearing][:t] # reducing the total running time (in s) + CS[:E] = CS[:E]-CS[:behaviorSections][:clearing][:E] # reducing the total energy consumption (in Ws) + delete!(CS[:behaviorSections], :clearing) + end + + # create a (new and longer) clearing section + s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) + s_clearing = min(CS[:s_exit]-drivingCourse[end][:s]-s_braking, currentSpeedLimit[:s_end] - drivingCourse[end][:s]) + if s_clearing > 0.0 + (CS, drivingCourse) = addCruisingSection!(CS, drivingCourse, s_clearing, settings, train, CSs, "clearing") + else + error("ERROR: clearing <=0.0 although it has to be >0.0 in CS ",CS[:id]) + end + + calculateForces!(drivingCourse[end], CSs, CS[:id], acceleratingSection[:type], train, settings[:massModel]) + + # reset the acceleratingSection + acceleratingSection = createBehaviorSection("accelerating", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) + + if drivingCourse[end][:s] + s_braking >= CS[:s_exit] + CS[:v_peak] = drivingCourse[end][:v] + end + end + + return (CS, drivingCourse, acceleratingSection) +end # function considerFormerSpeedLimit! + +function getCurrentSpeedLimit(CSs::Vector{Dict}, csWithTrainHeadId::Integer, s::Real, trainLength::Real) + v_limit = CSs[csWithTrainHeadId][:v_limit] + s_exit = CSs[csWithTrainHeadId][:s_exit] + if csWithTrainHeadId > 1 && s -trainLength < CSs[csWithTrainHeadId][:s_entry] + formerCsId = csWithTrainHeadId-1 + while formerCsId > 0 && s -trainLength < CSs[formerCsId][:s_exit] + if CSs[formerCsId][:v_limit] < v_limit # TODO: is the position of the train's rear < movingSection[:s_entry], v_limit of the first CS is used + v_limit = CSs[formerCsId][:v_limit] + s_exit = CSs[formerCsId][:s_exit] + end + formerCsId = formerCsId -1 + end + end + currentSpeedLimit = Dict(:v => v_limit, :s_end => s_exit + trainLength) + return currentSpeedLimit +end #function getCurrentSpeedLimit function getNextPointOfInterest(pointsOfInterest::Vector{Real}, s::Real) for POI in pointsOfInterest @@ -246,7 +300,7 @@ 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 +# Info: currently the values of the breakFree section will be calculated like in the accelerating 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.jl doesn't work reliably for the step variable v. Therefore v should not be used ! ! !") @@ -256,7 +310,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], CSs, CS[:id], "acceleration", train, settings[:massModel]) # currently the tractive effort is calculated like in the acceleration section + calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings[:massModel]) # currently the tractive effort is calculated like in the accelerating section # acceleration (in m/s^2): drivingCourse[end][:a] = calcAcceleration(drivingCourse[end][:F_T], drivingCourse[end][:F_R], train[:m_train], train[:ξ_train]) @@ -324,10 +378,10 @@ function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::D 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}, ignoreBraking::Bool) - #=if drivingCourse would also be part of movingSectiong: function addAccelerationSection!(movingSection::Dict, csId::Integer, settings::Dict, train::Dict, ignoreBraking::Bool) +## This function calculates the data points of the accelerating section. + # Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the accelerating section +function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, ignoreBraking::Bool) + #=if drivingCourse would also be part of movingSectiong: function addAcceleratingSection!(movingSection::Dict, csId::Integer, settings::Dict, train::Dict, ignoreBraking::Bool) CSs = movingSection[:characteristicSections] CS = CSs[csId] drivingCourse = movingSection[:drivingCourse]=# @@ -336,40 +390,46 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings (CS, drivingCourse) = addBreakFreeSection!(CS, drivingCourse, settings, train, CSs) end #if - calculateForces!(drivingCourse[end], CSs, CS[:id], "acceleration", train, settings[:massModel]) + calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings[:massModel]) if drivingCourse[end][:F_T] < drivingCourse[end][:F_R] (CS, drivingCourse) = addDiminishingSection!(CS, drivingCourse, settings, train, CSs) - calculateForces!(drivingCourse[end], CSs, CS[:id], "acceleration", train, settings[:massModel]) + calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", 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]) +# # if the rear 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 + # conditions for accelerating section targetSpeedReached = drivingCourse[end][:v] >= CS[:v_peak] trainAtEnd = drivingCourse[end][:s] >= CS[:s_exit] tractionSurplus = drivingCourse[end][:F_T] > drivingCourse[end][:F_R] - # use the conditions for the acceleration section + # use the conditions for the accelerating section if !targetSpeedReached && !trainAtEnd && tractionSurplus - BS = createBehaviorSection("acceleration", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) + BS = createBehaviorSection("accelerating", 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]) + currentSpeedLimit = getCurrentSpeedLimit(CSs, CS[:id], drivingCourse[end][:s], train[:length]) 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 + while drivingCourse[end][:v] < CS[:v_peak] && drivingCourse[end][:v] <= currentSpeedLimit[:v] && 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 + # 02/23 old: 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 + if drivingCourse[end][:s] >= currentSpeedLimit[:s_end] + # could be asked after creating an data point. This way here prevents even a minimal exceedance of speed limit will be noticed. On the other hand the train cruises possibly a little to long + currentSpeedLimit = getCurrentSpeedLimit(CSs, CS[:id], drivingCourse[end][:s], train[:length]) + end + # acceleration (in m/s^2): drivingCourse[end][:a] = calcAcceleration(drivingCourse[end][:F_T], drivingCourse[end][:F_R], train[:m_train], train[:ξ_train]) @@ -379,13 +439,13 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings drivingCourse[end][:behavior] = BS[:type] push!(BS[:dataPoints], drivingCourse[end][:i]) - if length(formerSpeedLimits) > 0 # If the tail of the train is located in a former characteristic section with lower speed limit check if is is possible to accelerate as normal - (CS, drivingCourse, formerSpeedLimits, BS, endOfCsReached) = considerFormerSpeedLimits!(CS, drivingCourse, settings, train, CSs, formerSpeedLimits, BS) - if endOfCsReached - return (CS, drivingCourse) - end - 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 + # if length(formerSpeedLimits) > 0 # If the rear of the train is located in a former characteristic section with lower speed limit check if is is possible to accelerate as normal + # (CS, drivingCourse, formerSpeedLimits, BS, endOfCsReached) = considerFormerSpeedLimits!(CS, drivingCourse, settings, train, CSs, formerSpeedLimits, BS) + # if endOfCsReached + # return (CS, drivingCourse) + # end + # # TODO: do the following that was done here in addAcceleratingSection_without_Braking! ? currentStepSize = settings[:stepSize] # initialize the step size that can be reduced near intersections + # end calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel]) if !ignoreBraking @@ -396,16 +456,20 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings # check which limit was reached and adjust the currentStepSize for the next cycle if cycle < approximationLevel+1 if drivingCourse[end][:v] <= 0.0 + #println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," <= 0.0") # for testing 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] + #println("in CS",CS[:id]," accelerating cycle",cycle," case: F_T=", drivingCourse[end][:F_T]," <= F_R=",drivingCourse[end][:F_R]) # for testing 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] + #println("in CS",CS[:id]," accelerating cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],",+",s_braking," = ",drivingCourse[end][:s] +s_braking," > s_exit=",CS[:s_exit]) # for testing currentStepSize = settings[:stepSize] / 10.0^cycle elseif drivingCourse[end][:s] > nextPointOfInterest + #println("in CS",CS[:id]," accelerating cycle",cycle," case: s=", drivingCourse[end][:s]," > nextPOI=",nextPointOfInterest) # for testing if settings[:stepVariable] == "s in m" currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s] else @@ -413,25 +477,50 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings end elseif drivingCourse[end][:v] > CS[:v_peak] + #println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," > v_peak=",CS[:v_peak]) # for testing if settings[:stepVariable] == "v in m/s" currentStepSize = CS[:v_peak]-drivingCourse[end-1][:v] else currentStepSize = settings[:stepSize] / 10.0^cycle end + elseif drivingCourse[end][:v] > currentSpeedLimit[:v] + #if drivingCourse[end][:s] < currentSpeedLimit[:s_end] + #if drivingCourse[end][:s] - train[:length] < currentSpeedLimit[:s_end] + #println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," > v_limitCurrent=",currentSpeedLimit[:v]) # for testing + (CS, drivingCourse, BS) = considerFormerSpeedLimit!(CS, drivingCourse, BS, settings, train, CSs, currentSpeedLimit) + #end + break + # TODO: think about alternative: handle the the position where the rear of the train leaves a CS similar to a POI. Then it will be calculated exactly and even a minimal exceedance of speed limit will be noticed + + elseif drivingCourse[end][:s] +s_braking == CS[:s_exit] + #println("in CS",CS[:id]," accelerating cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],",+",s_braking," = ",drivingCourse[end][:s] +s_braking," == s_exit=",CS[:s_exit]) # for testing + brakingStartReached = true + if s_braking == 0.0 + trainAtEnd = true + end + break + elseif drivingCourse[end][:s] == CS[:s_exit] + #println("in CS",CS[:id]," accelerating cycle",cycle," case: s=", drivingCourse[end][:s]," == s_exit=",CS[:s_exit]) # for testing trainAtEnd = true break elseif drivingCourse[end][:v] == CS[:v_peak] + #println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," == v_peak=",CS[:v_peak]) # for testing targetSpeedReached = true break elseif drivingCourse[end][:s] == nextPointOfInterest + #println("in CS",CS[:id]," accelerating cycle",cycle," case: s=", drivingCourse[end][:s]," == nextPOI=",nextPointOfInterest) # for testing break else - error("ERROR at acceleration section: With the step variable ",settings[:stepVariable]," the while loop will be left although v CS[:s_exit] - brakingStartReached = true - pop!(drivingCourse) - pop!(BS[:dataPoints]) + if s_braking > 0.0 + brakingStartReached = true + pop!(drivingCourse) + pop!(BS[:dataPoints]) + else + drivingCourse[end][:s] = CS[:s_exit] # round s down to CS[:s_exit] + drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s] + end elseif drivingCourse[end][:s] > nextPointOfInterest drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest @@ -464,6 +558,12 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings (CS, drivingCourse) = addDiminishingSection!(CS, drivingCourse, settings, train, CSs) calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel]) + elseif drivingCourse[end][:v] > currentSpeedLimit[:v] + #if drivingCourse[end][:s] - train[:length] < currentSpeedLimit[:s_end] + (CS, drivingCourse, BS) = considerFormerSpeedLimit!(CS, drivingCourse, BS, settings, train, CSs, currentSpeedLimit) + # end + # TODO: think about alternative: handle the the position where the rear of the train leaves a CS similar to a POI. Then it will be calculated exactly and the train start accelerating immediately and not only at the next data point. + else end @@ -474,10 +574,14 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings end end end #for + + if drivingCourse[end][:s] == CS[:s_exit] + trainAtEnd = true + end 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 + if length(BS[:dataPoints]) > 1 + # calculate the accumulated accelerating 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) :t => drivingCourse[end][:t] - drivingCourse[BS[:dataPoints][1]][:t], # total running time (in s) @@ -488,12 +592,12 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings 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(:accelerating => BS)) end end return (CS, drivingCourse) -end #function addAccelerationSection! +end #function addAcceleratingSection! ## This function calculates the data points of the cruising section. @@ -506,10 +610,14 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising:: (CS, drivingCourse) = addDiminishingSection!(CS, drivingCourse, settings, train, CSs) # 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]) + + s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) + s_cruising = CS[:s_exit] - drivingCourse[end][:s] - s_braking # may not work with EnergySaving when decreasing the length of cruising and adding coasting + # s_cruising = max(0.0, CS[:s_exit] - drivingCourse[end][:s] - s_braking) # may not work with EnergySaving when decreasing the length of cruising and adding coasting + # 02/25 old: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]= drivingCourse[end][:F_R] - # 11/22 old: if drivingCourse[end][:v]>0.0 && drivingCourse[end][:v]<=CS[:v_peak] && drivingCourse[end][:s] 1 # conditions for cruising section @@ -530,25 +637,16 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising:: 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][: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]=drivingCourse[end][:F_R] #&& drivingCourse[end][:v]<=CS[:v_peak] && drivingCourse[end][:s] probably not needed here !? + else # TODO copied from addAcceleratingSection -> 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 @@ -699,19 +797,21 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings: # check which limit was reached and adjust the currentStepSize for the next cycle if cycle < approximationLevel+1 if drivingCourse[end][:v] < 0.0 - # 02/18 old: currentStepSize = settings[:stepSize] / 10.0^cycle if settings[:stepVariable] == "v in m/s" currentStepSize = drivingCourse[end-1][:v] else currentStepSize = settings[:stepSize] / 10.0^cycle end elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R] + #println("in CS",CS[:id]," diminishing cycle",cycle," case: F_T=", drivingCourse[end][:F_T]," > F_R=",drivingCourse[end][:F_R]) # for testing currentStepSize = settings[:stepSize] / 10.0^cycle elseif s_braking > 0.0 && drivingCourse[end][:s] + s_braking > CS[:s_exit] + #println("in CS",CS[:id]," diminishing cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],"+",s_braking," = ",drivingCourse[end][:s] +s_braking," > s_exit=",CS[:s_exit]) # for testing currentStepSize = settings[:stepSize] / 10.0^cycle elseif drivingCourse[end][:s] > nextPointOfInterest + #println("in CS",CS[:id]," diminishing cycle",cycle," case: s=", drivingCourse[end][:s]," > nextPOI=",nextPointOfInterest) # for testing if settings[:stepVariable] == "s in m" currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s] else @@ -719,10 +819,12 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings: end elseif drivingCourse[end][:s] + s_braking == CS[:s_exit] + #println("in CS",CS[:id]," diminishing cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],"+",s_braking," = ",drivingCourse[end][:s] +s_braking," == s_exit=",CS[:s_exit]) # for testing brakingStartReached = true break elseif drivingCourse[end][:s] == nextPointOfInterest + #println("in CS",CS[:id]," diminishing cycle",cycle," case: s=", drivingCourse[end][:s]," == nextPOI=",nextPointOfInterest) # for testing break elseif drivingCourse[end][:v] == 0.0 @@ -731,7 +833,6 @@ 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.") - else error("ERROR during diminishing run: With the step variable ",settings[:stepVariable]," the while loop will be left although s+s_braking0.0 in CS",CS[:id]," with s=" ,drivingCourse[end][:s]," m and v=",drivingCourse[end][:v]," m/s") end @@ -794,8 +895,8 @@ 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 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]) + # TODO: if the rear of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept + # with getCurrentSpeedLimit # conditions for coasting section targetSpeedReached = drivingCourse[end][:v] <= CS[:v_exit] @@ -953,26 +1054,28 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic # TODO or: drivingCourse[end][:a] = calcBrakingAcceleration(drivingCourse[end][:v], CS[:v_exit], CS[:s_exit]-drivingCourse[end][:s]) if settings[:stepVariable] == "s in m" && ((drivingCourse[end][:v]/drivingCourse[end][:a])^2+2*currentStepSize/drivingCourse[end][:a])<0.0 || (drivingCourse[end][:v]^2+2*currentStepSize*drivingCourse[end][:a])<0.0 - targetSpeedReached = true + # targetSpeedReached = true - # create empty data point and set ist for the values of s_ext and v_exit + # create empty data point and set it for the values of s_exit and v_exit push!(drivingCourse, createDataPoint()) drivingCourse[end][:i] = drivingCourse[end-1][:i]+1 drivingCourse[end][:behavior] = BS[:type] push!(BS[:dataPoints], drivingCourse[end][:i]) recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit]) - break + # break + # end + else + # 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]) 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]) + #println(drivingCourse[end][:i],". s=",drivingCourse[end][:s]," s_exit=", CS[:s_exit]," v_exit=", CS[:v_exit]," v=",drivingCourse[end][:v]) end # while # check which limit was reached and adjust the currentStepSize for the next cycle # TODO: is there a better way than rounding like in the following? - if cycle < approximationLevel+1 && !targetSpeedReached + if cycle < approximationLevel+1 if drivingCourse[end][:v] < CS[:v_exit] if settings[:stepVariable] == "v in m/s" currentStepSize = drivingCourse[end-1][:v] - CS[:v_exit] @@ -986,7 +1089,6 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic currentStepSize = settings[:stepSize] / 10.0^cycle end=# elseif drivingCourse[end][:s] > nextPointOfInterest - # reset last point with lowering s to the nextPointOfInterest if settings[:stepVariable] == "s in m" currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s] else @@ -1068,68 +1170,6 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic # do nothing for example for drivingCourse[end][:s]==nextPointOfInterest end end - - #= - if drivingCourse[end][:v] < CS[:v_exit] || targetSpeedReached - # reset last point with setting v=v_exit - targetSpeedReached = true - trainAtEnd = true - - # calculate s, t, v - drivingCourse[end][:s] = CS[:s_exit] # position (in m) - drivingCourse[end][:v] = CS[:v_exit] # velocity (in m/s) - drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s] # step size (in m) - drivingCourse[end][:Δv] = drivingCourse[end][:v] - drivingCourse[end-1][:v] # step size (in m/s) - - drivingCourse[end-1][:a] = calcBrakingAcceleration(drivingCourse[end-1][:v], drivingCourse[end][:v], drivingCourse[end][:Δs]) - # TODO: just for testing - if drivingCourse[end-1][:a]=0.0 - println("Warning: a_braking gets to high in CS ",CS[:id], " with a=",drivingCourse[end-1][:a] ," > ",train[:a_braking]) - 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) - - drivingCourse[end][:ΔW] = 0.0 # mechanical work in this step (in Ws) - drivingCourse[end][:W] = drivingCourse[end-1][:W] + drivingCourse[end][:ΔW] # mechanical work (in Ws) - drivingCourse[end][:ΔE] = drivingCourse[end][:ΔW] # energy consumption in this step (in Ws) - drivingCourse[end][:E] = drivingCourse[end-1][:E] + drivingCourse[end][:ΔE] # energy consumption (in Ws) - - - - elseif drivingCourse[end][:s] > CS[:s_exit] - trainAtEnd = true - error("At the end of braking: s>s_exit but v>v_exit") - elseif drivingCourse[end][:s] > nextPointOfInterest - # reset last point with lowering s to the nextPointOfInterest - - # calculate s, t, v - if settings[:stepVariable] == "s in m" - currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s] # step size (in m) - else - # TODO - end - pop!(drivingCourse) - pop!(BS[:dataPoints]) - - # 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]) - - elseif drivingCourse[end][:v] == CS[:v_exit] && drivingCourse[end][:s] == CS[:s_exit] - targetSpeedReached = true - trainAtEnd = true - elseif drivingCourse[end][:v] == CS[:v_exit] - targetSpeedReached = true - error("At the end of braking: sv_exit") - else - # do nothing for example for drivingCourse[end][:s]==nextPointOfInterest - end - - =# end #for end #while @@ -1171,8 +1211,8 @@ function addStandstill!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, t end #function addStandstill! function createBehaviorSection(type::String, s_entry::Real, v_entry::Real, startingPoint::Integer) - BS= Dict(#:type => behavior, # type of behavior section: breakFree, clearing, acceleration, cruising, diminishing, coasting, braking or standstill - :type => type, # type of behavior section: "breakFree", "clearing", "acceleration", "cruising", "diminishing", "coasting", "braking" or "standstill" + BS= Dict(#:type => behavior, # type of behavior section: breakFree, clearing, accelerating, cruising, diminishing, coasting, braking or standstill + :type => type, # type of behavior section: "breakFree", "clearing", "accelerating", "cruising", "diminishing", "coasting", "braking" or "standstill" :length => 0.0, # total length (in m) :s_entry => s_entry, # first position (in m) :s_exit => 0.0, # last position (in m) @@ -1189,7 +1229,7 @@ a data point is the smallest element of the driving course. One step of the step """ function createDataPoint() dataPoint = Dict(:i => 0, # identifier and counter variable of the dricing course - :behavior => "", # type of behavior section the data point is part of ("breakFree", "clearing", "acceleration", "cruising", "diminishing", "coasting", "braking" or "standstill") + :behavior => "", # type of behavior section the data point is part of ("breakFree", "clearing", "accelerating", "cruising", "diminishing", "coasting", "braking" or "standstill") # a data point which is the last point of one behavior section and the first point of the next behavior section will be attached to the latter :s => 0.0, # position (in m) :Δs => 0.0, # step size (in m) diff --git a/src/Characteristics.jl b/src/Characteristics.jl index 3d4db14..b79a1b3 100644 --- a/src/Characteristics.jl +++ b/src/Characteristics.jl @@ -12,11 +12,11 @@ using .Behavior export preparateSections -## create a moving section and its containing characteristic sections with secured braking, acceleration and cruising behavior +## create a moving section and its containing characteristic sections with secured braking, accelerating and cruising behavior function preparateSections(path::Dict, train::Dict, settings::Dict) movingSection = createMovingSection(path, train[:v_limit]) movingSection = secureBrakingBehavior!(movingSection, train[:a_braking]) - movingSection = secureAccelerationBehavior!(movingSection, settings, train) + movingSection = secureAcceleratingBehavior!(movingSection, settings, train) movingSection = secureCruisingBehavior!(movingSection, settings, train) return movingSection @@ -119,8 +119,8 @@ function secureBrakingBehavior!(movingSection::Dict, a_braking::Real) return movingSection end #function secureBrakingBehavior! -## define the intersection velocities between the characterisitc sections to secure acceleration behavior -function secureAccelerationBehavior!(movingSection::Dict, settings::Dict, train::Dict) +## define the intersection velocities between the characterisitc sections to secure accelerating behavior +function secureAcceleratingBehavior!(movingSection::Dict, settings::Dict, train::Dict) # this function limits the entry and exit velocity of the characteristic sections in case that the train accelerates in every section and cruises aterwards CSs = movingSection[:characteristicSections] @@ -134,12 +134,12 @@ function secureAccelerationBehavior!(movingSection::Dict, settings::Dict, train: startingPoint[:s] = CS[:s_entry] startingPoint[:v] = CS[:v_entry] - accelerationCourse::Vector{Dict} = [startingPoint] # List of data points + acceleratingCourse::Vector{Dict} = [startingPoint] # List of data points if CS[:v_entry] < CS[:v_peak] - (CS, accelerationCourse) = addAccelerationSection!(CS, accelerationCourse, settings, train, CSs, true) # this function changes the accelerationCourse - CS[:v_peak] = max(CS[:v_entry], accelerationCourse[end][:v]) - CS[:v_exit] = min(CS[:v_exit], CS[:v_peak], accelerationCourse[end][:v]) + (CS, acceleratingCourse) = addAcceleratingSection!(CS, acceleratingCourse, settings, train, CSs, true) # this function changes the acceleratingCourse + CS[:v_peak] = max(CS[:v_entry], acceleratingCourse[end][:v]) + CS[:v_exit] = min(CS[:v_exit], CS[:v_peak], acceleratingCourse[end][:v]) else #CS[:v_entry] == CS[:v_peak] # v_exit stays the same end #if @@ -153,7 +153,7 @@ function secureAccelerationBehavior!(movingSection::Dict, settings::Dict, train: end #for return movingSection -end #function secureAccelerationBehavior! +end #function secureAcceleratingBehavior! diff --git a/src/EnergySaving.jl b/src/EnergySaving.jl index 6ec9305..1983dca 100644 --- a/src/EnergySaving.jl +++ b/src/EnergySaving.jl @@ -136,13 +136,13 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict get(CSsOrig[csIdMax][:behaviorSections], :braking, get(CSsOrig[csIdMax][:behaviorSections], :coasting, get(CSsOrig[csIdMax][:behaviorSections], :cruising, - get(CSsOrig[csIdMax][:behaviorSections], :acceleration, + get(CSsOrig[csIdMax][:behaviorSections], :accelerating, get(CSsOrig[csIdMax][:behaviorSections], :clearing, get(CSsOrig[csIdMax][:behaviorSections], :breakFree, get(CSsOrig[csIdMax][:behaviorSections], :diminishing, Dict(:dataPoints => [0])))))))))[:dataPoints][end] - # if there is a diminishing phase its location must be analysed seperately because it could be before acceleration, between acceleration and cruising or after cruising. All the other behavior sections occure in a fixed order. + # if there is a diminishing phase its location must be analysed seperately because it could be before accelerating, between accelerating and cruising or after cruising. All the other behavior sections occure in a fixed order. if haskey(CSsOrig[csIdMax][:behaviorSections], :diminishing) lastIdOfSelectedCsOriginal = max(lastIdOfSelectedCsOriginal, CSsOrig[csIdMax][:behaviorSections][:diminishing][:dataPoints][end]) end @@ -182,7 +182,7 @@ function calculateMinimumEnergyConsumption(movingSectionMinimumRunningTime::Dict # update all the data point references in the behaviour sections of the following characteristic sections and the other modified characteristic sections if difference!= 0 # update the data point references in the behaviour sections of the following characteristic sections - allBs=[:breakFree, :clearing, :acceleration, :cruising, :diminishing, :coasting, :braking, :standstill] + allBs=[:breakFree, :clearing, :accelerating, :cruising, :diminishing, :coasting, :braking, :standstill] for csId in csIdMax+1:length(CSsOrig) for bs in 1: length(allBs) if haskey(CSsOrig[csId][:behaviorSections], allBs[bs]) @@ -263,7 +263,7 @@ function copyMovingSection(original::Dict) end #function copyMovingSection function copyCharacteristicSection(originalCS::Dict) - allBs=[:breakFree, :clearing, :acceleration, :cruising, :diminishing, :coasting, :braking, :standstill] + allBs=[:breakFree, :clearing, :accelerating, :cruising, :diminishing, :coasting, :braking, :standstill] copiedBSs = Dict() for bs in 1: length(allBs) if haskey(originalCS[:behaviorSections], allBs[bs]) @@ -295,8 +295,8 @@ function copyBehaviorSection(original::Dict) for i in 1:length(original[:dataPoints]) push!(bsDataPoints, original[:dataPoints][i]) end - copiedBS = Dict(#:type => behavior, # type of behavior section: breakFree, clearing, acceleration, cruising, diminishing, coasting, braking or standstill - :type => original[:type], # type of behavior section: "breakFree", "clearing", "acceleration", "cruising", "diminishing", "coasting", "braking" or "standstill" + copiedBS = Dict(#:type => behavior, # type of behavior section: breakFree, clearing, accelerating, cruising, diminishing, coasting, braking or standstill + :type => original[:type], # type of behavior section: "breakFree", "clearing", "accelerating", "cruising", "diminishing", "coasting", "braking" or "standstill" :length => original[:length], # total length (in m) :s_entry => original[:s_entry], # first position (in m) :s_exit => original[:s_exit], # last position (in m) @@ -320,7 +320,7 @@ function createEnergySavingModification() end #createEnergySavingModification function updateEnergySavingModifications!(energySavingModifications::Vector{Dict}, csIdMax::Integer, drivingCourseNew::Vector{Dict}, endOfModificationId::Integer, lastIdOfSelectedCsOriginal::Integer) - allBs=[:breakFree, :clearing, :acceleration, :cruising, :diminishing, :coasting, :braking, :standstill] + allBs=[:breakFree, :clearing, :accelerating, :cruising, :diminishing, :coasting, :braking, :standstill] difference = endOfModificationId-lastIdOfSelectedCsOriginal for modNr in csIdMax+1:length(energySavingModifications) if energySavingModifications[modNr][:ratio]>0 @@ -522,7 +522,7 @@ end #function calculateRecoveryTime # TODO: a refactoring caused worse drivingsCourses. see the commented function below function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, allCSs::Vector{Dict}, t_recoveryAvailable::AbstractFloat) BSsOriginal = csOriginal[:behaviorSections] - if (haskey(BSsOriginal, :cruising) || (haskey(BSsOriginal, :diminishing) && get(BSsOriginal, :diminishing, Dict(:dataPoints =>[0]))[:dataPoints][1] > get(BSsOriginal, :acceleration, Dict(:dataPoints =>[0]))[:dataPoints][1])) && haskey(BSsOriginal, :braking) + if (haskey(BSsOriginal, :cruising) || (haskey(BSsOriginal, :diminishing) && get(BSsOriginal, :diminishing, Dict(:dataPoints =>[0]))[:dataPoints][1] > get(BSsOriginal, :accelerating, Dict(:dataPoints =>[0]))[:dataPoints][1])) && haskey(BSsOriginal, :braking) # check if cruising or diminishing should be reduced for coasting if haskey(BSsOriginal, :cruising) && haskey(BSsOriginal, :diminishing) if BSsOriginal[:cruising][:dataPoints][1] > BSsOriginal[:diminishing][:dataPoints][1] @@ -546,7 +546,7 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict}, csModifiedInitial = copyCharacteristicSection(csOriginal) BSsModified = csModifiedInitial[:behaviorSections] - # delete bahavior sections that will be recalculated except breakFree, clearing, acceleration, diminishing + # delete bahavior sections that will be recalculated except breakFree, clearing, accelerating, diminishing # and rest total running time and energy consumption if haskey(BSsModified, :coasting) csModifiedInitial[:E] = csModifiedInitial[:E] - BSsModified[:coasting][:E] @@ -635,11 +635,11 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict}, elseif reduceDiminishing - # TODO: At the moment diminishing is reduced similar to the acceleration in decreaseMaximumVelocity. To reduce code the methods for reducing cruising phase and reducing the diminishing phase can be combined in some parts. + # TODO: At the moment diminishing is reduced similar to the accelerating in decreaseMaximumVelocity. To reduce code the methods for reducing cruising phase and reducing the diminishing phase can be combined in some parts. csModified = csModifiedInitial diminishingSection = BSsModified[:diminishing] - # remove the last diminishing waypoint + # remove the last diminishing data point t_diff = drivingCourse[diminishingSection[:dataPoints][end]][:t] - drivingCourse[diminishingSection[:dataPoints][end-1]][:t] E_diff = drivingCourse[diminishingSection[:dataPoints][end]][:E] - drivingCourse[diminishingSection[:dataPoints][end-1]][:E] pop!(diminishingSection[:dataPoints]) @@ -718,17 +718,17 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict}, csModified[:E] = csModified[:E] + BSsModified[:breakFree][:E] csModified[:t] = csModified[:t] + BSsModified[:breakFree][:t] end - if haskey(BSsOriginal, :clearing) # this section is needed before acceleration if the train wants to accelerate to a speed higher than the limit in a previous CS where parts of the train are still located + if haskey(BSsOriginal, :clearing) # this section is needed before accelerating if the train wants to accelerate to a speed higher than the limit in a previous CS where parts of the train are still located clearingSection=copyBehaviorSection(BSsOriginal[:clearing]) merge!(BSsModified, Dict(:clearing=>clearingSection)) csModified[:E] = csModified[:E] + BSsModified[:clearing][:E] csModified[:t] = csModified[:t] + BSsModified[:clearing][:t] end - if haskey(BSsOriginal, :acceleration) - accelerationSection=copyBehaviorSection(BSsOriginal[:acceleration]) - merge!(BSsModified, Dict(:acceleration=>accelerationSection)) - csModified[:E] = csModified[:E] + BSsModified[:acceleration][:E] - csModified[:t] = csModified[:t] + BSsModified[:acceleration][:t] + if haskey(BSsOriginal, :accelerating) + acceleratingSection=copyBehaviorSection(BSsOriginal[:accelerating]) + merge!(BSsModified, Dict(:accelerating=>acceleratingSection)) + csModified[:E] = csModified[:E] + BSsModified[:accelerating][:E] + csModified[:t] = csModified[:t] + BSsModified[:accelerating][:t] end if haskey(BSsOriginal, :diminishing) diminishingSection=copyBehaviorSection(BSsOriginal[:diminishing]) @@ -769,7 +769,7 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict}, elseif reduceDiminishing - # TODO: At the moment diminishing is reduced like the acceleration in decreaseMaximumVelocity. To reduce code the methods for reducing cruising phase and reducing the diminishing phase can be combined in some parts. + # TODO: At the moment diminishing is reduced like the accelerating in decreaseMaximumVelocity. To reduce code the methods for reducing cruising phase and reducing the diminishing phase can be combined in some parts. # copy csOriginal to csModified # 12/28 old: csModified=CharacteristicSection(csOriginal[:id], csOriginal[:length], csOriginal[:s_entry], csOriginal[:s_exit], 0.0, 0.0, csOriginal[:v_limit], csOriginal[:v_peak], csOriginal[:v_entry], csOriginal[:v_exit], csOriginal[:r_path], Dict{Symbol, Dict}()) @@ -794,17 +794,17 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict}, csModified[:E] = csModified[:E] + BSsModified[:breakFree][:E] csModified[:t] = csModified[:t] + BSsModified[:breakFree][:t] end - if haskey(BSsOriginal, :clearing) # this section is needed before acceleration if the train wants to accelerate to a speed higher than the limit in a previous CS where parts of the train are still located + if haskey(BSsOriginal, :clearing) # this section is needed before accelerating if the train wants to accelerate to a speed higher than the limit in a previous CS where parts of the train are still located clearingSection=copyBehaviorSection(BSsOriginal[:clearing]) merge!(BSsModified, Dict(:clearing=>clearingSection)) csModified[:E] = csModified[:E] + BSsModified[:clearing][:E] csModified[:t] = csModified[:t] + BSsModified[:clearing][:t] end - if haskey(BSsOriginal, :acceleration) - accelerationSection=copyBehaviorSection(BSsOriginal[:acceleration]) - merge!(BSsModified, Dict(:acceleration=>accelerationSection)) - csModified[:E] = csModified[:E] + BSsModified[:acceleration][:E] - csModified[:t] = csModified[:t] + BSsModified[:acceleration][:t] + if haskey(BSsOriginal, :accelerating) + acceleratingSection=copyBehaviorSection(BSsOriginal[:accelerating]) + merge!(BSsModified, Dict(:accelerating=>acceleratingSection)) + csModified[:E] = csModified[:E] + BSsModified[:accelerating][:E] + csModified[:t] = csModified[:t] + BSsModified[:accelerating][:t] end if haskey(BSsOriginal, :cruising) cruisingSection=copyBehaviorSection(BSsOriginal[:cruising]) @@ -815,7 +815,7 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict}, diminishingSection=copyBehaviorSection(BSsOriginal[:diminishing]) if length(diminishingSection[:dataPoints]) > 2 - # remove the last diminishing waypoint + # remove the last diminishing data point pop!(diminishingSection[:dataPoints]) diminishingSection[:v_exit]=drivingCourse[diminishingSection[:dataPoints][end]][:v] # exit speed (in m/s) @@ -865,18 +865,18 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict}, end end # function increaseCoastingSection -# method 2 with shortening the acceleration by stepsize +# method 2 with shortening the accelerating by stepsize function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict, train::Dict, allCSs::Vector{Dict}, t_recoveryAvailable::AbstractFloat) # TODO doesn't work that well alone. works better with combineEnergySavingMethods. why? does a while loop end to early or something like this? #function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat) BSsOriginal = csOriginal[:behaviorSections] - if haskey(BSsOriginal, :acceleration) && csOriginal[:v_peak] > csOriginal[:v_entry] && csOriginal[:v_peak] > csOriginal[:v_exit] - accelerationSection = copyBehaviorSection(BSsOriginal[:acceleration]) + if haskey(BSsOriginal, :accelerating) && csOriginal[:v_peak] > csOriginal[:v_entry] && csOriginal[:v_peak] > csOriginal[:v_exit] + acceleratingSection = copyBehaviorSection(BSsOriginal[:accelerating]) - if drivingCourse[accelerationSection[:dataPoints][end]-1][:v] < csOriginal[:v_exit] + if drivingCourse[acceleratingSection[:dataPoints][end]-1][:v] < csOriginal[:v_exit] # 12/29 old, now not with empty but with original CS and DC: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes? return (csOriginal, drivingCourse, false) - # TODO: or calculate a new acceleration phase with v_exit as v_peak? it will be very short, shorter than the step size. + # TODO: or calculate a new accelerating phase with v_exit as v_peak? it will be very short, shorter than the step size. end # copy csOriginal to csModified @@ -902,14 +902,14 @@ function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict csModified[:E] = csModified[:E] + BSsModified[:breakFree][:E] csModified[:t] = csModified[:t] + BSsModified[:breakFree][:t] end - if haskey(BSsOriginal, :diminishing) && BSsModified[:diminishing][:dataPoints][1] < BSsModified[:acceleration][:dataPoints][1] + if haskey(BSsOriginal, :diminishing) && BSsModified[:diminishing][:dataPoints][1] < BSsModified[:accelerating][:dataPoints][1] diminishingSection=copyBehaviorSection(BSsOriginal[:diminishing]) merge!(BSsModified, Dict(:diminishing=>diminishingSection)) csModified[:E] = csModified[:E] + BSsModified[:diminishing][:E] csModified[:t] = csModified[:t] + BSsModified[:diminishing][:t] end - if length(accelerationSection[:dataPoints]) > 2 + if length(acceleratingSection[:dataPoints]) > 2 if haskey(BSsOriginal, :clearing) clearingSection=copyBehaviorSection(BSsOriginal[:clearing]) merge!(BSsModified, Dict(:clearing=>clearingSection)) @@ -917,23 +917,23 @@ function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict csModified[:t] = csModified[:t] + BSsModified[:clearing][:t] end - # remove the last acceleration waypoint from the accelerationSection - pop!(accelerationSection[:dataPoints]) - energySavingStartId = accelerationSection[:dataPoints][end] + # remove the last data point from the acceleratingSection + pop!(acceleratingSection[:dataPoints]) + energySavingStartId = acceleratingSection[:dataPoints][end] - accelerationSection[:v_exit]=drivingCourse[energySavingStartId][:v] # exit speed (in m/s) - accelerationSection[:s_exit]=drivingCourse[energySavingStartId][:s] # last position (in m) - accelerationSection[:length]=accelerationSection[:s_exit]-accelerationSection[:s_entry] # total length (in m) - accelerationSection[:t]=drivingCourse[energySavingStartId][:t]-drivingCourse[accelerationSection[:dataPoints][1]][:t] # total running time (in s) - accelerationSection[:E]=drivingCourse[energySavingStartId][:E]-drivingCourse[accelerationSection[:dataPoints][1]][:E] # total energy consumption (in Ws) + acceleratingSection[:v_exit]=drivingCourse[energySavingStartId][:v] # exit speed (in m/s) + acceleratingSection[:s_exit]=drivingCourse[energySavingStartId][:s] # last position (in m) + acceleratingSection[:length]=acceleratingSection[:s_exit]-acceleratingSection[:s_entry] # total length (in m) + acceleratingSection[:t]=drivingCourse[energySavingStartId][:t]-drivingCourse[acceleratingSection[:dataPoints][1]][:t] # total running time (in s) + acceleratingSection[:E]=drivingCourse[energySavingStartId][:E]-drivingCourse[acceleratingSection[:dataPoints][1]][:E] # total energy consumption (in Ws) - merge!(BSsModified, Dict(:acceleration=>accelerationSection)) - csModified[:E] = csModified[:E] + accelerationSection[:E] - csModified[:t] = csModified[:t] + accelerationSection[:t] + merge!(BSsModified, Dict(:accelerating=>acceleratingSection)) + csModified[:E] = csModified[:E] + acceleratingSection[:E] + csModified[:t] = csModified[:t] + acceleratingSection[:t] else - # The acceleration section is only one step. This step is removed and if there is a clearing section it will be combined with the new cruising section. - energySavingStartId=get(BSsOriginal, :clearing, get(BSsOriginal, :acceleration, Dict(:dataPoints =>[0])))[:dataPoints][1] + # The accelerating section is only one step. This step is removed and if there is a clearing section it will be combined with the new cruising section. + energySavingStartId=get(BSsOriginal, :clearing, get(BSsOriginal, :accelerating, Dict(:dataPoints =>[0])))[:dataPoints][1] end # TODO: should v_peak be reduced or is it enough to pop the data points? @@ -976,8 +976,8 @@ function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict return (csModified, drivingCourseModified, true) else # time loss is to high. so there is no energy saving modification for this CS with the available recovery time - # 09/06 old: else # time loss is to high and the CS has to be calculated again with larger acceleration section (so with a smaller reduction of the acceleration section) - # 09/06 old: accelerationReduction=min(accelerationReduction/10, csModified[:v_peak]-csModified[:v_entry], csModified[:v_peak]-csModified[:v_exit]) + # 09/06 old: else # time loss is to high and the CS has to be calculated again with larger accelerating section (so with a smaller reduction of the accelerating section) + # 09/06 old: acceleratingReduction=min(acceleratingReduction/10, csModified[:v_peak]-csModified[:v_entry], csModified[:v_peak]-csModified[:v_exit]) # TODO: just return false or take smaller steps? # 12/29 old, now not with empty but with original CS and DC: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes? @@ -992,7 +992,7 @@ function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict else - # there is no energy saving modification for this CS because v_peak can not be lowered below v_entry or v_exit or because there is no acceleration section that can be transformed into a cruising section + # there is no energy saving modification for this CS because v_peak can not be lowered below v_entry or v_exit or because there is no accelerating section that can be transformed into a cruising section # 12/29 old, now not with empty but with original CS and DC: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes? return (csOriginal, drivingCourse, false) end #if haskey @@ -1001,8 +1001,8 @@ end # function decreaseMaximumVelocity # combination of method 1 and method 2 function combineEnergySavingMethods(csOriginal::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, allCSs::Vector{Dict}, t_recoveryAvailable::AbstractFloat) BSsOriginal = csOriginal[:behaviorSections] - # if haskey(BSsOriginal, :acceleration) && (haskey(BSsOriginal, :braking) || haskey(BSsOriginal, :coasting)) && csOriginal[:v_peak]>csOriginal[:v_entry] && csOriginal[:v_peak]>csOriginal[:v_exit] - if haskey(BSsOriginal, :acceleration) && (haskey(BSsOriginal, :braking) || haskey(BSsOriginal, :coasting)) && drivingCourse[get(BSsOriginal, :acceleration, Dict(:dataPoints =>[0]))[:dataPoints][end]][:v] > max(csOriginal[:v_entry], csOriginal[:v_exit]) + # if haskey(BSsOriginal, :accelerating) && (haskey(BSsOriginal, :braking) || haskey(BSsOriginal, :coasting)) && csOriginal[:v_peak]>csOriginal[:v_entry] && csOriginal[:v_peak]>csOriginal[:v_exit] + if haskey(BSsOriginal, :accelerating) && (haskey(BSsOriginal, :braking) || haskey(BSsOriginal, :coasting)) && drivingCourse[get(BSsOriginal, :accelerating, Dict(:dataPoints =>[0]))[:dataPoints][end]][:v] > max(csOriginal[:v_entry], csOriginal[:v_exit]) # copy the characteristic section csCombined = copyCharacteristicSection(csOriginal) @@ -1034,7 +1034,7 @@ function combineEnergySavingMethods(csOriginal::Dict, drivingCourse::Vector{Dict end # while return (csCombined, drivingCourseCombined, (ΔE>0.0))# && Δt>0.0)) else - # there is no energy saving modification for this CS because v_peak can not be lowered below v_entry or v_exit or because there is no acceleration section and braking section or coasting section that can be transformed into a cruising section or coasting section + # there is no energy saving modification for this CS because v_peak can not be lowered below v_entry or v_exit or because there is no accelerating section and braking section or coasting section that can be transformed into a cruising section or coasting section # 12/29 old, now not with empty but with original CS and DC: return (Dict(), [], false) # TODO: Does the empty CS-Dict need default attributes? return (csOriginal, drivingCourse, false) end #if diff --git a/src/Export.jl b/src/Export.jl index c5858fe..f0b01ce 100644 --- a/src/Export.jl +++ b/src/Export.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 Export using CSV, DataFrames, Dates @@ -39,17 +46,17 @@ function createCsvFile(movingSection::Dict, dataPointsToExport::Vector{Dict}, op stepVariable = settings[:stepVariable] stepSize = string(settings[:stepSize]) - # create summarized data block - summarizedData = Array{Any, 1}[] + # create accumulated data block + accumulatedData = Array{Any, 1}[] if detailOfOutput == "minimal" - push!(summarizedData, ["s (in m)", "t (in s)","E (in Ws)"]) # push header to summarizedData + push!(accumulatedData, ["s (in m)", "t (in s)","E (in Ws)"]) # push header to accumulatedData row = [movingSection[:length], movingSection[:t], movingSection[:E]] - push!(summarizedData, row) # push row to summarizedData + push!(accumulatedData, row) # push row to accumulatedData elseif detailOfOutput == "driving course" || detailOfOutput == "points of interest" - push!(summarizedData, ["i", "behavior", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_wagons (in N)", "ΔW (in Ws)","W (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]) # push header to summarizedData + push!(accumulatedData, ["i", "behavior", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_wagons (in N)", "ΔW (in Ws)","W (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]) # push header to accumulatedData for point in dataPointsToExport row = [point[:i], point[:behavior], point[:Δs], point[:s], point[:Δt], point[:t], point[:Δv], point[:v], point[:F_T], point[:F_R], point[:R_path], point[:R_train], point[:R_traction], point[:R_wagons], point[:ΔW], point[:W], point[:ΔE], point[:E], point[:a]] - push!(summarizedData, row) # push row to summarizedData + push!(accumulatedData, row) # push row to accumulatedData end end @@ -57,15 +64,15 @@ function createCsvFile(movingSection::Dict, dataPointsToExport::Vector{Dict}, op allColumns=Array{Any,1}[] push!(allColumns, ["path name", "train name", "operation mode", "mass model", "step variable", "step size", ""]) push!(allColumns, [pathName, trainName, operationMode, massModel, stepVariable, stepSize, ""]) - for column in 3:length(summarizedData[1]) + for column in 3:length(accumulatedData[1]) push!(allColumns, ["", "", "", "", "", "", ""]) end # for # add driving data to the array - header = summarizedData[1] - for column in 1:length(summarizedData[1]) + header = accumulatedData[1] + for column in 1:length(accumulatedData[1]) push!(allColumns[column], header[column]) - for row in summarizedData[2:end] + for row in accumulatedData[2:end] push!(allColumns[column], row[column]) end end # for diff --git a/src/TrainRunCalc.jl b/src/TrainRunCalc.jl index 1aed9a0..d9d3ef3 100644 --- a/src/TrainRunCalc.jl +++ b/src/TrainRunCalc.jl @@ -26,6 +26,10 @@ export calculateDrivingDynamics approximationLevel = 6 # value for approximation to intersections and precisely calculated digits # TODO: define it here and give it to each function? (Behavior, ...) + + # INFO for diminishing and cruising: if v decreases to a value where F_T-F_R is positive the train could accelerate to a value of v where F_T-F_R is negative and so forth and so on. In Behavior.jl it is realized not oscillating with accelerating and diminishing but just with cruising instead of accelerating und therefore keeping the velocity value where F_T-F_R>0. + + # Calculate the driving dynamics of a train run on a path with special settings with information from the corresponding YAML files with the file paths `trainDirectory`, `pathDirectory`, `settingsDirectory`. """ @@ -89,7 +93,7 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train end if drivingCourse[end][:v] < CS[:v_peak] - (CS, drivingCourse) = addAccelerationSection!(CS, drivingCourse, settings, train, CSs, false) + (CS, drivingCourse) = addAcceleratingSection!(CS, drivingCourse, settings, train, CSs, false) end #if s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking]) @@ -150,12 +154,12 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train # 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] + s_accelerating = get(BSs, :accelerating, Dict(:length=>0.0))[:length] s_braking = calcBrakingDistance(CS[:v_peak], CS[:v_exit], train[:a_braking]) # old: s_braking = max(0.0, ceil((CS[:v_exit]^2-CS[:v_peak]^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 # calculate the cruising sections length - s_cruising = max(0.0, CS[:length] - s_breakFree - s_clearing - s_acceleration - s_braking) + s_cruising = max(0.0, CS[:length] - s_breakFree - s_clearing - s_accelerating - 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 CS[:behaviorSections] = Dict() @@ -163,7 +167,7 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train CS[:t] = 0.0 # TODO 02/09: could there be a better structure for processing the different moving phases? (this if fork was added on 2022/09/02) - if s_clearing > 0.0 && s_breakFree + s_acceleration == 0.0 + if s_clearing > 0.0 && s_breakFree + s_accelerating == 0.0 (CS, drivingCourse)=addCruisingSection!(CS, drivingCourse, s_clearing, settings, train, CSs, "clearing") end @@ -172,12 +176,12 @@ 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, false) # TODO or better ignoreBraking = true? + (CS, drivingCourse) = addAcceleratingSection!(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 println("ERROR: After accelerating in CS ",csId," the braking distance is too short!") - println(" before acceleration in CS",csId, " with s=",drivingCourse[end][:s]," s_braking=",((CS[:v_exit]^2-drivingCourse[end][:v]^2)/2/train[:a_braking])," s_exit=",CS[:s_exit]) + println(" before accelerating in CS",csId, " with s=",drivingCourse[end][:s]," s_braking=",((CS[:v_exit]^2-drivingCourse[end][:v]^2)/2/train[:a_braking])," s_exit=",CS[:s_exit]) println(" and v=",drivingCourse[end][:v]," v_peak=",CS[:v_peak]," v_exit=",CS[:v_exit]) end @@ -188,10 +192,10 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train (CS, drivingCourse)=addCruisingSection!(CS, drivingCourse, s_cruising, settings, train, CSs, "cruising") end 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" + if CS[:v_entry] < CS[:v_peak] || s_accelerating > 0.0 # or instead of " || s_accelerating > 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] - # old 02/22 (CS, drivingCourse)=addAccelerationSectionUntilBraking!(CS, drivingCourse, settings, train, CSs) - (CS, drivingCourse) = addAccelerationSection!(CS, drivingCourse, settings, train, CSs, false) + # old 02/22 (CS, drivingCourse)=addAcceleratingSectionUntilBraking!(CS, drivingCourse, settings, train, CSs) + (CS, drivingCourse) = addAcceleratingSection!(CS, drivingCourse, settings, train, CSs, false) end #if end #if