From 892b84251af905946d8c78ae548982c19f2b5759 Mon Sep 17 00:00:00 2001 From: Max Kannenberg <95709892+MaxKannenberg@users.noreply.github.com> Date: Wed, 22 Jun 2022 11:11:44 +0200 Subject: [PATCH 1/7] Rename 'data points' to 'support points' --- src/behavior.jl | 124 ++++++++++++++++++++++---------------------- src/calc.jl | 38 +++++++------- src/constructors.jl | 18 +++---- src/formulary.jl | 20 +++---- src/output.jl | 14 ++--- 5 files changed, 107 insertions(+), 107 deletions(-) diff --git a/src/behavior.jl b/src/behavior.jl index eadaa8c..f97c5c1 100644 --- a/src/behavior.jl +++ b/src/behavior.jl @@ -4,8 +4,8 @@ # __copyright__ = "2020-2022" # __license__ = "ISC" -## 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. +## This function calculates the support points of the breakFree section. +# Therefore it gets its first support 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 accelerating section function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, settings::Settings, train::Train, CSs::Vector{Dict}) # conditions for the break free section @@ -26,15 +26,15 @@ function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags: rethrow(acceleratingError) end - # delete every dataPoint except the first two - while drivingCourse[end][:i] > drivingCourse[BS[:dataPoints][1]][:i] +1 + # delete every supportPoint except the first two + while drivingCourse[end][:i] > drivingCourse[BS[:supportPoints][1]][:i] +1 pop!(drivingCourse) end # change the accelerating data to break free drivingCourse[end-1][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type] - push!(BS[:dataPoints], drivingCourse[end][:i]) + push!(BS[:supportPoints], drivingCourse[end][:i]) # remove the accelerating section from the CS CS[:t] = CS[:t] - get(CS[:behaviorSections], :accelerating, Dict(:t=>0.0))[:t] # total running time (in s) @@ -43,7 +43,7 @@ function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags: # calculate the accumulated breakFree section information merge!(BS, Dict(:length => drivingCourse[end][:s] - BS[:s_entry], # total length (in m) :s_exit => drivingCourse[end][:s], # last position (in m) - :t => drivingCourse[end][:t] - drivingCourse[BS[:dataPoints][1]][:t], # total running time (in s) + :t => drivingCourse[end][:t] - drivingCourse[BS[:supportPoints][1]][:t], # total running time (in s) :v_exit => drivingCourse[end][:v])) # exit speed (in m/s))) CS[:t] = CS[:t] + BS[:t] # total running time (in s) @@ -71,7 +71,7 @@ function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags: return (CS, drivingCourse, stateFlags) end #function addBreakFreeSection! -## This function calculates the data points of the clearing section. +## This function calculates the support points of the clearing section. # Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the clearing section. function addClearingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, settings::Settings, train::Train, CSs::Vector{Dict}) if stateFlags[:previousSpeedLimitReached] @@ -104,7 +104,7 @@ function addClearingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: return (CS, drivingCourse, stateFlags) end #function addClearingSection -## This function calculates the data points of the accelerating section. +## This function calculates the support 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}, stateFlags::Dict, settings::Settings, train::Train, CSs::Vector{Dict}) #function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Settings, train::Train, CSs::Vector{Dict}, ignoreBraking::Bool) @@ -153,17 +153,17 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFla while !targetSpeedReached && !speedLimitReached && !brakingStartReached && !pointOfInterestReached && tractionSurplus && !previousSpeedLimitReached # 03/08 old: while drivingCourse[end][:v] < CS[:v_peak] && drivingCourse[end][:v] <= currentSpeedLimit[:v] && !brakingStartReached && drivingCourse[end][:s] < nextPointOfInterest[1] && 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 + # could be asked after creating an support 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] = acceleration(drivingCourse[end][:F_T], drivingCourse[end][:F_R], train.m_train_full, train.ξ_train) - # create the next data point + # create the next support point push!(drivingCourse, moveAStep(drivingCourse[end], settings.stepVariable, currentStepSize, CS[:id])) drivingCourse[end][:behavior] = BS[:type] - push!(BS[:dataPoints], drivingCourse[end][:i]) + push!(BS[:supportPoints], drivingCourse[end][:i]) calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings.massModel) @@ -250,9 +250,9 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFla error("ERROR at accelerating section: With the step variable ",settings.stepVariable," the while loop will be left although v CS[:v_peak] testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," > v_peak=",CS[:v_peak]) # for testing pop!(drivingCourse) - pop!(BS[:dataPoints]) + pop!(BS[:supportPoints]) # conditions for the next section brakingStartReached = false @@ -276,7 +276,7 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFla testFlag && 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 if s_braking > 0.0 pop!(drivingCourse) - pop!(BS[:dataPoints]) + pop!(BS[:supportPoints]) else drivingCourse[end][:s] = CS[:s_exit] # round s down to CS[:s_exit] @@ -296,7 +296,7 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFla previousSpeedLimitReached = true pop!(drivingCourse) - pop!(BS[:dataPoints]) + pop!(BS[:supportPoints]) else if drivingCourse[end][:s] + s_braking == CS[:s_exit] @@ -324,14 +324,14 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFla end #while - if length(BS[:dataPoints]) > 1 + if length(BS[:supportPoints]) > 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) + :t => drivingCourse[end][:t] - drivingCourse[BS[:supportPoints][1]][:t], # total running time (in s) :v_exit => drivingCourse[end][:v])) # exit speed (in m/s))) - # 03/10 old: 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 + # 03/10 old: CS[:v_peak] = max(drivingCourse[end][:v], CS[:v_entry]) # setting v_peak to the last support 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) mergeBehaviorSection!(CS[:behaviorSections], BS) @@ -351,8 +351,8 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFla end #function addAcceleratingSection! -## This function calculates the data points of the cruising section. -# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for cruising if needed. +## This function calculates the support points of the cruising section. +# Therefore it gets its first support point and the characteristic section and returns the characteristic section including the behavior section for cruising if needed. function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, s_cruising::Real, settings::Settings, train::Train, CSs::Vector{Dict}, cruisingType::String) trainIsClearing = cruisingType == "clearing" trainIsBrakingDownhill = cruisingType == "downhillBraking" @@ -427,14 +427,14 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: # acceleration (in m/s^2): drivingCourse[end][:a] = 0.0 - # create the next data point + # create the next support point if settings.stepVariable == :distance || settings.stepVariable == time push!(drivingCourse, moveAStep(drivingCourse[end], settings.stepVariable, currentStepSize, CS[:id])) else push!(drivingCourse, moveAStep(drivingCourse[end], position, train.length/(10.0^cycle), CS[:id])) # TODO which step size should be used? end drivingCourse[end][:behavior] = BS[:type] - push!(BS[:dataPoints], drivingCourse[end][:i]) + push!(BS[:supportPoints], drivingCourse[end][:i]) # traction effort and resisting forces (in N) calculateForces!(drivingCourse[end], CSs, CS[:id], "default", train, settings.massModel) @@ -494,9 +494,9 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: 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 - # delete last data point for recalculating the last step with reduced step size + # delete last support point for recalculating the last step with reduced step size pop!(drivingCourse) - pop!(BS[:dataPoints]) + pop!(BS[:supportPoints]) # conditions for the next for cycle pointOfInterestReached = false @@ -512,7 +512,7 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: elseif drivingCourse[end][:s] > BS[:s_entry]+s_cruising if BS[:type] != "clearing" pop!(drivingCourse) - pop!(BS[:dataPoints]) + pop!(BS[:supportPoints]) end elseif drivingCourse[end][:s] == BS[:s_entry]+s_cruising break @@ -566,13 +566,13 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: #s_cruisingRemaining=BS[:s_entry] + s_cruising-drivingCourse[end][:s] s_cruisingRemaining = min(nextPointOfInterest[1] -drivingCourse[end][:s], BS[:s_entry] +s_cruising -drivingCourse[end][:s]) - # create the next data point + # create the next support point push!(drivingCourse, moveAStep(drivingCourse[end], :distance, s_cruisingRemaining, CS[:id])) drivingCourse[end][:behavior] = BS[:type] if drivingCourse[end][:s] == nextPointOfInterest[1] drivingCourse[end][:label] = nextPointOfInterest[2] end - push!(BS[:dataPoints], drivingCourse[end][:i]) + push!(BS[:supportPoints], drivingCourse[end][:i]) calculateForces!(drivingCourse[end], CSs, CS[:id], "default", train, settings.massModel) # calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings.massModel) @@ -594,7 +594,7 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: # calculate the accumulated cruising 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) + :t => drivingCourse[end][:t] - drivingCourse[BS[:supportPoints][1]][:t], # total running time (in s) :v_exit => drivingCourse[end][:v])) # exit speed (in m/s))) CS[:t] = CS[:t] + BS[:t] # total running time (in s) @@ -618,7 +618,7 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: end #function addCruisingSection! -## This function calculates the data points for diminishing run when using maximum tractive effort and still getting slower +## This function calculates the support points for diminishing run when using maximum tractive effort and still getting slower function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, settings::Settings, train::Train, CSs::Vector{Dict}) calculateForces!(drivingCourse[end], CSs, CS[:id], "diminishing", train, settings.massModel) @@ -653,10 +653,10 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlag # acceleration (in m/s^2): drivingCourse[end][:a] = acceleration(drivingCourse[end][:F_T], drivingCourse[end][:F_R], train.m_train_full, train.ξ_train) - # create the next data point + # create the next support point push!(drivingCourse, moveAStep(drivingCourse[end], settings.stepVariable, currentStepSize, CS[:id])) drivingCourse[end][:behavior] = BS[:type] - push!(BS[:dataPoints], drivingCourse[end][:i]) + push!(BS[:supportPoints], drivingCourse[end][:i]) calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings.massModel) @@ -721,9 +721,9 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlag 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 - # delete last data point for recalculating the last step with reduced step size + # delete last support point for recalculating the last step with reduced step size pop!(drivingCourse) - pop!(BS[:dataPoints]) + pop!(BS[:supportPoints]) # conditions for the next for cycle brakingStartReached = false @@ -735,7 +735,7 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlag else # if the level of approximation is reached if drivingCourse[end][:v] <= 0.0 testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: v=", drivingCourse[end][:v]," <= 0.0") # for testing - # push!(BS[:dataPoints], drivingCourse[end][:i]) + # push!(BS[:supportPoints], drivingCourse[end][:i]) error("ERROR: The train stops during diminishing run in CS",CS[:id]," because the maximum tractive effort is lower than the resistant forces.", " Before the stop the last point has the values s=",drivingCourse[end-1][:s]," m v=",drivingCourse[end-1][:v]," m/s a=",drivingCourse[end-1][:a]," m/s^2", " F_T=",drivingCourse[end-1][:F_T]," N R_traction=",drivingCourse[end-1][:R_traction]," N R_wagons=",drivingCourse[end-1][:R_wagons]," N R_path=",drivingCourse[end-1][:R_path]," N.") @@ -743,7 +743,7 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlag elseif s_braking > 0.0 && drivingCourse[end][:s] + s_braking > CS[:s_exit] testFlag && 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 pop!(drivingCourse) - pop!(BS[:dataPoints]) + pop!(BS[:supportPoints]) pointOfInterestReached = false targetSpeedReached = false @@ -781,11 +781,11 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlag end end #while - if length(BS[:dataPoints]) > 1 # TODO: necessary? May it be possible that there is no diminishing because braking has to start? + if length(BS[:supportPoints]) > 1 # TODO: necessary? May it be possible that there is no diminishing because braking has to start? # calculate the accumulated diminishing 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) + :t => drivingCourse[end][:t] - drivingCourse[BS[:supportPoints][1]][:t], # total running time (in s) :v_exit => drivingCourse[end][:v])) # exit speed (in m/s))) CS[:t] = CS[:t] + BS[:t] # total running time (in s) @@ -806,7 +806,7 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlag end #function addDiminishingSection! -## This function calculates the data points of the coasting section. +## This function calculates the support 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}, stateFlags::Dict, settings::Settings, train::Train, CSs::Vector{Dict}) # 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 @@ -838,10 +838,10 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: # acceleration (in m/s^2): drivingCourse[end][:a] = acceleration(drivingCourse[end][:F_T], drivingCourse[end][:F_R], train.m_train_full, train.ξ_train) - # create the next data point + # create the next support point push!(drivingCourse, moveAStep(drivingCourse[end], settings.stepVariable, currentStepSize, CS[:id])) drivingCourse[end][:behavior] = BS[:type] - push!(BS[:dataPoints], drivingCourse[end][:i]) + push!(BS[:supportPoints], drivingCourse[end][:i]) # conditions for the next while cycle s_braking = brakingDistance(drivingCourse[end][:v], CS[:v_exit], train.a_braking, settings.approxLevel) @@ -897,9 +897,9 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: # TODO: not needed. just for testing error("ERROR at coasting until braking section: With the step variable ",settings.stepVariable," the while loop will be left although v CS[:s_exit] - # delete last data point because it went to far + # delete last support point because it went to far pop!(drivingCourse) - pop!(BS[:dataPoints]) + pop!(BS[:supportPoints]) # conditions for the next for cycle # brakingStartReached = true @@ -924,9 +924,9 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: targetSpeedReached = false elseif drivingCourse[end][:v] > CS[:v_peak] # if the train gets to fast it has to brake # TODO: if accelereation and coasting functions will be combined this case is different for coasting and also the order of if cases is different - # delete last data point because it went to far + # delete last support point because it went to far pop!(drivingCourse) - pop!(BS[:dataPoints]) + pop!(BS[:supportPoints]) # conditions for the next for cycle brakingStartReached = false @@ -953,7 +953,7 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: # calculate the accumulated coasting 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) + :t => drivingCourse[end][:t] - drivingCourse[BS[:supportPoints][1]][:t], # total running time (in s) :v_exit => drivingCourse[end][:v])) # exit speed (in m/s))) CS[:t] = CS[:t] + BS[:t] # total running time (in s) @@ -972,8 +972,8 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: end #function addCoastingSection! -## This function calculates the data points of the braking section. -# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for braking if needed. +## This function calculates the support points of the braking section. +# Therefore it gets its first support point and the characteristic section and returns the characteristic section including the behavior section for braking if needed. function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, settings::Settings, train::Train, CSs::Vector{Dict}) # conditions for braking section targetSpeedReached = drivingCourse[end][:v] <= CS[:v_exit] @@ -1000,17 +1000,17 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::D # TODO or: drivingCourse[end][:a] = brakingAcceleration(drivingCourse[end][:v], CS[:v_exit], CS[:s_exit]-drivingCourse[end][:s]) if settings.stepVariable == :distance && ((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 - # create empty data point and set it for the values of s_exit and v_exit - push!(drivingCourse, DataPoint()) + # create empty support point and set it for the values of s_exit and v_exit + push!(drivingCourse, SupportPoint()) drivingCourse[end][:i] = drivingCourse[end-1][:i]+1 drivingCourse[end][:behavior] = BS[:type] - push!(BS[:dataPoints], drivingCourse[end][:i]) + push!(BS[:supportPoints], drivingCourse[end][:i]) recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit]) else - # create the next data point + # create the next support point push!(drivingCourse, moveAStep(drivingCourse[end], settings.stepVariable, currentStepSize, CS[:id])) drivingCourse[end][:behavior] = BS[:type] - push!(BS[:dataPoints], drivingCourse[end][:i]) + push!(BS[:supportPoints], drivingCourse[end][:i]) end #println(drivingCourse[end][:i],". s=",drivingCourse[end][:s]," s_exit=", CS[:s_exit]," v_exit=", CS[:v_exit]," v=",drivingCourse[end][:v]) @@ -1052,9 +1052,9 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::D break end - # delete last data point for recalculating the last step with reduced step size + # delete last support point for recalculating the last step with reduced step size pop!(drivingCourse) - pop!(BS[:dataPoints]) + pop!(BS[:supportPoints]) # conditions for the next for cycle pointOfInterestReached = false @@ -1111,7 +1111,7 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::D # calculate the accumulated coasting 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) + :t => drivingCourse[end][:t] - drivingCourse[BS[:supportPoints][1]][:t], # total running time (in s) :v_exit => drivingCourse[end][:v])) # exit speed (in m/s))) CS[:t] = CS[:t] + BS[:t] # total running time (in s) @@ -1132,8 +1132,8 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::D end #function addBrakingSection! -## This function calculates the data point of the halt. -# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the halt if needed. +## This function calculates the support point of the halt. +# Therefore it gets its first support point and the characteristic section and returns the characteristic section including the halt if needed. function addHalt!(CS::Dict, drivingCourse::Vector{Dict}, settings::Settings, train::Train, CSs::Vector{Dict}) if drivingCourse[end][:v] == 0.0 BS = BehaviorSection("standstill", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) @@ -1218,7 +1218,7 @@ function secureAcceleratingBehavior!(movingSection::Dict, settings::Settings, tr CSs = movingSection[:characteristicSections] CSs[1][:v_entry] = 0.0 # the entry velocity of the first characteristic section is 0.0 m/s - startingPoint = DataPoint() + startingPoint = SupportPoint() startingPoint[:i] = 1 previousCSv_exit = CSs[1][:v_entry] @@ -1227,7 +1227,7 @@ function secureAcceleratingBehavior!(movingSection::Dict, settings::Settings, tr startingPoint[:s] = CS[:s_entry] startingPoint[:v] = CS[:v_entry] calculateForces!(startingPoint, CSs, CS[:id], "accelerating", train, settings.massModel) # traction effort and resisting forces (in N) - acceleratingCourse::Vector{Dict} = [startingPoint] # List of data points + acceleratingCourse::Vector{Dict} = [startingPoint] # List of support points if CS[:v_entry] < CS[:v_peak] # conditions for entering the accelerating phase diff --git a/src/calc.jl b/src/calc.jl index b37d8c1..3307b04 100644 --- a/src/calc.jl +++ b/src/calc.jl @@ -14,11 +14,11 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Settings, t println("WARNING: ! ! ! TrainRuns.jl doesn't work reliably for the mass model homogeneous strip with step size v in m/s. The calculation time can be extremely high when calcutlating paths with steep gradients ! ! !") end - startingPoint=DataPoint() - startingPoint[:i]=1 - startingPoint[:s]=CSs[1][:s_entry] + startingPoint = SupportPoint() + startingPoint[:i] = 1 + startingPoint[:s] = CSs[1][:s_entry] calculateForces!(startingPoint, CSs, 1, "default", train, settings.massModel) # traction effort and resisting forces (in N) - drivingCourse::Vector{Dict} = [startingPoint] # List of data points + drivingCourse::Vector{Dict} = [startingPoint] # List of support points for csId in 1:length(CSs) CS = CSs[csId] @@ -30,7 +30,7 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Settings, t println("ERROR: In CS", csId," the train run ends with v=",drivingCourse[end][:v]," and not with v_entry=",CS[:v_entry]) end - # determine the different flags for switching between the states for creatinge moving phases + # determine the different flags for switching between the states for creating moving phases s_braking = brakingDistance(drivingCourse[end][:v], CS[:v_exit], train.a_braking, settings.approxLevel) calculateForces!(drivingCourse[end], CSs, CS[:id], "default", train, settings.massModel) # tractive effort and resisting forces (in N) @@ -191,30 +191,30 @@ end #function calculatePathResistance """ -calculate and return tractive and resisting forces for a data point +calculate and return tractive and resisting forces for a support point """ -function calculateForces!(dataPoint::Dict, CSs::Vector{Dict}, csId::Integer, bsType::String, train::Train, massModel) +function calculateForces!(supportPoint::Dict, CSs::Vector{Dict}, csId::Integer, bsType::String, train::Train, massModel) # calculate resisting forces - dataPoint[:R_traction] = tractionUnitResistance(dataPoint[:v], train) + supportPoint[:R_traction] = tractionUnitResistance(supportPoint[:v], train) if train.transportType == :freight - dataPoint[:R_wagons] = freightWagonsResistance(dataPoint[:v], train) + supportPoint[:R_wagons] = freightWagonsResistance(supportPoint[:v], train) elseif train.transportType == :passenger - dataPoint[:R_wagons] = passengerWagonsResistance(dataPoint[:v], train) + supportPoint[:R_wagons] = passengerWagonsResistance(supportPoint[:v], train) end - dataPoint[:R_train] = dataPoint[:R_traction] + dataPoint[:R_wagons] - dataPoint[:R_path] = calculatePathResistance(CSs, csId, dataPoint[:s], massModel, train) - dataPoint[:F_R] = dataPoint[:R_train] + dataPoint[:R_path] + supportPoint[:R_train] = supportPoint[:R_traction] + supportPoint[:R_wagons] + supportPoint[:R_path] = calculatePathResistance(CSs, csId, supportPoint[:s], massModel, train) + supportPoint[:F_R] = supportPoint[:R_train] + supportPoint[:R_path] # calculate tractive effort if bsType == "braking" || bsType == "coasting" || bsType == "halt" - dataPoint[:F_T] = 0.0 + supportPoint[:F_T] = 0.0 elseif bsType == "cruising" - dataPoint[:F_T] = min(max(0.0, dataPoint[:F_R]), calculateTractiveEffort(dataPoint[:v], train.tractiveEffort)) + supportPoint[:F_T] = min(max(0.0, supportPoint[:F_R]), calculateTractiveEffort(supportPoint[:v], train.tractiveEffort)) else # bsType == "accelerating" || bsType == "diminishing" || 'default' - dataPoint[:F_T] = calculateTractiveEffort(dataPoint[:v], train.tractiveEffort) + supportPoint[:F_T] = calculateTractiveEffort(supportPoint[:v], train.tractiveEffort) end - return dataPoint + return supportPoint end #function calculateForces! @@ -226,8 +226,8 @@ function moveAStep(previousPoint::Dict, stepVariable::Symbol, stepSize::Real, cs # TODO: csId is only for error messages. Should it be removed? #= 08/31 TODO: How to check if the train stopps during this step? I should throw an error myself that I catch in higher hierarchies. =# - # create the next data point - newPoint = DataPoint() + # create the next support point + newPoint = SupportPoint() newPoint[:i] = previousPoint[:i]+1 # identifier # calculate s, t, v, E diff --git a/src/constructors.jl b/src/constructors.jl index 539e8eb..148eb5f 100644 --- a/src/constructors.jl +++ b/src/constructors.jl @@ -677,7 +677,7 @@ function CharacteristicSection(id::Integer, s_entry::Real, section::Dict, v_limi :v_entry => v_limit, # maximum entry speed (in m/s) :v_exit => v_limit) # maximum exit speed (in m/s) - # list of positions of every point of interest (POI) in this charateristic section for which data points should be calculated + # list of positions of every point of interest (POI) in this charateristic section for which support points should be calculated s_exit = characteristicSection[:s_exit] ##TODO: use a tuple with naming @@ -711,19 +711,19 @@ function BehaviorSection(type::String, s_entry::Real, v_entry::Real, startingPoi :E => 0.0, # total energy consumption (in Ws) :v_entry => v_entry, # entry speed (in m/s) :v_exit => 0.0, # exit speed (in m/s) - :dataPoints => [startingPoint] # list of identifiers of the containing data points starting with the initial point + :supportPoints => [startingPoint] # list of identifiers of the containing support points starting with the initial point ) return BS end #function BehaviorSection """ -a DataPoint is the smallest element of the driving course. One step of the step approach is between two data points +a SupportPoint is the smallest element of the driving course. One step of the step approach is between two support points """ -function DataPoint() - dataPoint = Dict( +function SupportPoint() + supportPoint = Dict( :i => 0, # identifier and counter variable of the driving course - :behavior => "", # type of behavior section the data point is part of - see BehaviorSection() - # 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 + :behavior => "", # type of behavior section the support point is part of - see BehaviorSection() + # a support 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) :t => 0.0, # point in time (in s) @@ -743,5 +743,5 @@ function DataPoint() :R_wagons => 0.0, # set of wagons resistance (in N) :label => "" # a label for important points ) - return dataPoint -end #function DataPoint + return supportPoint +end #function SupportPoint diff --git a/src/formulary.jl b/src/formulary.jl index fffa909..64a4a18 100644 --- a/src/formulary.jl +++ b/src/formulary.jl @@ -124,8 +124,8 @@ function Δs_with_Δt(Δt::Real, a_prev::Real, v_prev::Real) # equation is based on [Wende:2003, page 37] # Δt: time step (in s) - # a_prev: acceleration from previous data point - # v_prev: velocitiy from previous data point + # a_prev: acceleration from previous support point + # v_prev: velocitiy from previous support point Δs = Δt * (2*v_prev + Δt*a_prev) /2 # step size (in m) return Δs end #function Δs_with_Δt @@ -134,8 +134,8 @@ function Δs_with_Δv(Δv::Real, a_prev::Real, v_prev::Real) # equation is based on [Wende:2003, page 37] # Δv: velocity step (in m/s) - # a_prev: acceleration from previous data point - # v_prev: velocitiy from previous data point + # a_prev: acceleration from previous support point + # v_prev: velocitiy from previous support point Δs = ((v_prev + Δv)^2 - v_prev^2)/2/a_prev # step size (in m) return Δs end #function Δs_with_Δv @@ -144,8 +144,8 @@ function Δt_with_Δs(Δs::Real, a_prev::Real, v_prev::Real) # equation is based on [Wende:2003, page 37] # Δs: distance step (in m) - # a_prev: acceleration from previous data point - # v_prev: velocitiy from previous data point + # a_prev: acceleration from previous support point + # v_prev: velocitiy from previous support point Δt = sign(a_prev) *sqrt((v_prev /a_prev)^2 + 2 *Δs /a_prev) - v_prev /a_prev # step size (in m/s) return Δt @@ -155,7 +155,7 @@ function Δt_with_Δv(Δv::Real, a_prev::Real) # equation is based on [Wende:2003, page 37] # Δv: velocity step (in m/s) - # a_prev: acceleration from previous data point + # a_prev: acceleration from previous support point Δt = Δv /a_prev # step size (in s) return Δt end #function Δt_with_Δv @@ -173,8 +173,8 @@ function Δv_with_Δs(Δs::Real, a_prev::Real, v_prev::Real) # equation is based on [Wende:2003, page 37] # Δs: distance step (in m) - # a_prev: acceleration from previous data point - # v_prev: velocitiy from previous data point + # a_prev: acceleration from previous support point + # v_prev: velocitiy from previous support point Δv = sqrt(v_prev^2 + 2*Δs*a_prev) - v_prev # step size (in m/s) return Δv end #function Δv_with_Δs @@ -183,7 +183,7 @@ function Δv_with_Δt(Δt::Real, a_prev::Real) # equation is based on [Wende:2003, page 37] # Δt: time step (in s) - # a_prev: acceleration from previous data point + # a_prev: acceleration from previous support point Δv = Δt * a_prev # step size (in m/s) return Δv end #function Δv_with_Δt diff --git a/src/output.jl b/src/output.jl index cf63e93..ccfb981 100644 --- a/src/output.jl +++ b/src/output.jl @@ -9,16 +9,16 @@ function createOutput(settings::Settings, drivingCourse::Vector{Dict}, pointsOfI output::Vector{Dict} = [Dict(:t => drivingCourse[end][:t])] elseif settings.outputDetail == :points_of_interest && !isempty(pointsOfInterest) - # get only the driving course's data points with POI labels + # get only the driving course's support points with POI labels output = Dict[] - dataPoint = 1 + supportPoint = 1 for POI in 1:length(pointsOfInterest) - while dataPoint <= length(drivingCourse) - if pointsOfInterest[POI][1] == drivingCourse[dataPoint][:s] - push!(output, drivingCourse[dataPoint]) + while supportPoint <= length(drivingCourse) + if pointsOfInterest[POI][1] == drivingCourse[supportPoint][:s] + push!(output, drivingCourse[supportPoint]) break end - dataPoint += 1 + supportPoint += 1 end end @@ -63,4 +63,4 @@ function createDataFrame(output_vector::Vector{Dict}, outputDetail) end return dataFrame -end #createDataFrameForDrivingCourse +end #createDataFrame From a3a68e555372e2faea0b010d93954713bda4b326 Mon Sep 17 00:00:00 2001 From: Max Kannenberg <95709892+MaxKannenberg@users.noreply.github.com> Date: Wed, 22 Jun 2022 13:04:54 +0200 Subject: [PATCH 2/7] Add output detail 'data_points' with starting points of the driving modes --- src/constructors.jl | 2 +- src/output.jl | 14 +++++++++++++- src/types.jl | 2 +- test/data/settings/driving_course.yaml | 2 +- test/data/settings/points_of_interest.yaml | 2 +- 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/constructors.jl b/src/constructors.jl index 148eb5f..0cedf61 100644 --- a/src/constructors.jl +++ b/src/constructors.jl @@ -51,7 +51,7 @@ function Settings( "outputDetail": { "description": "Selecting the detail of the result", "type": "string", - "enum": [ "running_time", "points_of_interest", "driving_course" ] + "enum": [ "running_time", "points_of_interest", "data_points", "driving_course" ] }, "outputFormat": { "description": "Output format", diff --git a/src/output.jl b/src/output.jl index ccfb981..d18fdb9 100644 --- a/src/output.jl +++ b/src/output.jl @@ -22,6 +22,18 @@ function createOutput(settings::Settings, drivingCourse::Vector{Dict}, pointsOfI end end + elseif settings.outputDetail == :data_points + # get the driving course's support points where a new behavior section starts and the driving mode changes + output = Dict[] + # the first support point is the first data point + push!(output, drivingCourse[1]) + + for supportPoint in 2:length(drivingCourse) + if drivingCourse[supportPoint-1][:behavior] != drivingCourse[supportPoint][:behavior] + push!(output, drivingCourse[supportPoint]) + end + end + else #if settings.outputDetail == :driving_course || (settings.outputDetail == :points_of_interest && !isempty(path.poi)) output = drivingCourse end @@ -38,7 +50,7 @@ function createDataFrame(output_vector::Vector{Dict}, outputDetail) if outputDetail == :running_time # create a DataFrame with running time information dataFrame = DataFrame(t=[output_vector[end][:t]]) - else # :points_of_interest or :driving_course + else # :points_of_interest, :data_points or :driving_course columnSymbols = [:label, :behavior, :s, :v, :t, :a, :F_T, :F_R, :R_path, :R_traction, :R_wagons] allColumns = [] diff --git a/src/types.jl b/src/types.jl index f74a9cc..da620e9 100644 --- a/src/types.jl +++ b/src/types.jl @@ -10,7 +10,7 @@ struct Settings stepVariable::Symbol # variable of the linear multistep method: ":distance", ":time" or ":velocity". stepSize::Real # step size, unit depends on stepVariable - :distance in meter, time in seconds and velocity in meter/second. approxLevel::Int # value for approximation; used when rounding or iterating. - outputDetail::Symbol # single Float() ":running_time", Vector() of ":points_of_interest", + outputDetail::Symbol # single Float() ":running_time", Vector() of ":points_of_interest", Vector() of ":data_points" # or complete Vector() ":driving_course" outputFormat::Symbol # output as ":dataframe" or as ":vector". diff --git a/test/data/settings/driving_course.yaml b/test/data/settings/driving_course.yaml index 3b5bae5..6c2928f 100644 --- a/test/data/settings/driving_course.yaml +++ b/test/data/settings/driving_course.yaml @@ -1,4 +1,4 @@ %YAML 1.2 --- settings: - outputDetail: "driving_course" # single value "running_time", list of "points_of_interest", complete "driving_course" + outputDetail: "driving_course" # single value "running_time", list of "points_of_interest", list of "data_points", complete "driving_course" diff --git a/test/data/settings/points_of_interest.yaml b/test/data/settings/points_of_interest.yaml index d5e9bed..74c1772 100644 --- a/test/data/settings/points_of_interest.yaml +++ b/test/data/settings/points_of_interest.yaml @@ -1,4 +1,4 @@ %YAML 1.2 --- settings: - outputDetail: "points_of_interest" # single value "running_time", list of "points_of_interest", complete "driving_course" + outputDetail: "points_of_interest" # single value "running_time", list of "points_of_interest", list of "data_points", complete "driving_course" From b7e0f21ffb44a5f220eba00572f0414e952c6b98 Mon Sep 17 00:00:00 2001 From: Max Kannenberg <95709892+MaxKannenberg@users.noreply.github.com> Date: Thu, 30 Jun 2022 18:42:35 +0200 Subject: [PATCH 3/7] Remove step sizes from 'SupportPoint' --- src/behavior.jl | 13 ++----------- src/calc.jl | 36 ++++++++++++++++++------------------ src/constructors.jl | 8 -------- 3 files changed, 20 insertions(+), 37 deletions(-) diff --git a/src/behavior.jl b/src/behavior.jl index f97c5c1..2c05027 100644 --- a/src/behavior.jl +++ b/src/behavior.jl @@ -280,13 +280,11 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFla 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[1] testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: s=", drivingCourse[end][:s]," > nextPointOfInterest[1]=",nextPointOfInterest[1]) # for testing drivingCourse[end][:s] = nextPointOfInterest[1] # round s down to nextPointOfInterest - drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s] elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R] testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: F_T=", drivingCourse[end][:F_T]," <= F_R=",drivingCourse[end][:F_R]) # for testing @@ -508,7 +506,6 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: else # if the level of approximation is reached if drivingCourse[end][:s] > nextPointOfInterest[1] drivingCourse[end][:s] = nextPointOfInterest[1] # round s down to nextPointOfInterest - drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s] elseif drivingCourse[end][:s] > BS[:s_entry]+s_cruising if BS[:type] != "clearing" pop!(drivingCourse) @@ -753,7 +750,6 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlag elseif drivingCourse[end][:s] > nextPointOfInterest[1] testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: s=", drivingCourse[end][:s]," > nextPointOfInterest[1]=",nextPointOfInterest[1]) # for testing drivingCourse[end][:s] = nextPointOfInterest[1] # round s down to nextPointOfInterest - drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s] elseif drivingCourse[end][:F_T] >= drivingCourse[end][:F_R] testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: F_T=", drivingCourse[end][:F_T]," >= F_R=", drivingCourse[end][:F_R]) # for testing @@ -935,7 +931,6 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: elseif drivingCourse[end][:s] > nextPointOfInterest[1] drivingCourse[end][:s] = nextPointOfInterest[1] # round s down to nextPointOfInterest - drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s] else # do nothing for example for drivingCourse[end][:s] + s_braking == CS[:s_exit] end @@ -1076,7 +1071,6 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::D break elseif drivingCourse[end][:s] > nextPointOfInterest[1] drivingCourse[end][:s] = nextPointOfInterest[1] # 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] break @@ -1171,17 +1165,14 @@ function recalculateLastBrakingPoint!(drivingCourse, s_target, v_target) # set s and v currentPoint[:s] = s_target # position (in m) currentPoint[:v] = v_target # velocity (in m/s) - currentPoint[:Δs] = currentPoint[:s] - previousPoint[:s] # step size (in m) - currentPoint[:Δv] = currentPoint[:v] - previousPoint[:v] # step size (in m/s) # calculate other values - previousPoint[:a] = brakingAcceleration(previousPoint[:v], currentPoint[:v], currentPoint[:Δs]) + previousPoint[:a] = brakingAcceleration(previousPoint[:v], currentPoint[:v], currentPoint[:s]-previousPoint[:s]) # # TODO: just for testing # if previousPoint[:a]=0.0 # println("Warning: a_braking gets to high in CS ",CS[:id], " with a=",previousPoint[:a] ," > ",train.a_braking) # end - currentPoint[:Δt] = Δt_with_Δv(currentPoint[:Δv], previousPoint[:a]) # step size (in s) - currentPoint[:t] = previousPoint[:t] + currentPoint[:Δt] # point in time (in s) + currentPoint[:t] = previousPoint[:t] + Δt_with_Δv(currentPoint[:v]-previousPoint[:v], previousPoint[:a]) # point in time (in s) end #function recalculateLastBrakingPoint ## define the intersection velocities between the characterisitc sections to secure braking behavior diff --git a/src/calc.jl b/src/calc.jl index 3307b04..66d52e8 100644 --- a/src/calc.jl +++ b/src/calc.jl @@ -232,49 +232,49 @@ function moveAStep(previousPoint::Dict, stepVariable::Symbol, stepSize::Real, cs # calculate s, t, v, E if stepVariable == :distance # distance step method - newPoint[:Δs] = stepSize # step size (in m) + Δs = stepSize # step size (in m) if previousPoint[:a] == 0.0 if previousPoint[:v] == 0.0 error("ERROR: The train tries to cruise at v=0.0 m/s at s=",previousPoint[:s]," in CS",csId,".") end - newPoint[:Δt] = Δt_with_constant_v(newPoint[:Δs], previousPoint[:v]) # step size (in s) - newPoint[:Δv] = 0.0 # step size (in m/s) + Δt = Δt_with_constant_v(Δs, previousPoint[:v]) # step size (in s) + Δv = 0.0 # step size (in m/s) else # check if the parts of the following square roots will be <0.0 in the functions Δt_with_Δs and Δv_with_Δs - squareRootPartIsNegative = (previousPoint[:v]/previousPoint[:a])^2+2*newPoint[:Δs]/previousPoint[:a] < 0.0 || previousPoint[:v]^2+2*newPoint[:Δs]*previousPoint[:a] < 0.0 + squareRootPartIsNegative = (previousPoint[:v]/previousPoint[:a])^2+2*Δs/previousPoint[:a] < 0.0 || previousPoint[:v]^2+2*Δs*previousPoint[:a] < 0.0 if previousPoint[:a] < 0.0 && squareRootPartIsNegative 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 - newPoint[:Δt] = Δt_with_Δs(newPoint[:Δs], previousPoint[:a], previousPoint[:v]) # step size (in s) - newPoint[:Δv] = Δv_with_Δs(newPoint[:Δs], previousPoint[:a], previousPoint[:v]) # step size (in m/s) + Δt = Δt_with_Δs(Δs, previousPoint[:a], previousPoint[:v]) # step size (in s) + Δv = Δv_with_Δs(Δs, previousPoint[:a], previousPoint[:v]) # step size (in m/s) end elseif stepVariable == :time # time step method - newPoint[:Δt] = stepSize # step size (in s) - newPoint[:Δs] = Δs_with_Δt(newPoint[:Δt], previousPoint[:a], previousPoint[:v]) # step size (in m) - newPoint[:Δv] = Δv_with_Δt(newPoint[:Δt], previousPoint[:a]) # step size (in m/s) + Δt = stepSize # step size (in s) + Δs = Δs_with_Δt(Δt, previousPoint[:a], previousPoint[:v]) # step size (in m) + Δv = Δv_with_Δt(Δt, previousPoint[:a]) # step size (in m/s) elseif stepVariable == :velocity # velocity step method if previousPoint[:a] == 0.0 if previousPoint[:v] == 0.0 error("ERROR: The train tries to cruise at v=0.0 m/s at s=",previousPoint[:s]," in CS",csId,".") end - newPoint[:Δs] = stepSize # step size (in m) + Δs = stepSize # step size (in m) # TODO what is the best default step size for constant v? define Δs or Δt? - newPoint[:Δt] = Δt_with_constant_v(newPoint[:Δs], previousPoint[:v]) # step size (in s) - newPoint[:Δv] = 0.0 # step size (in m/s) + Δt = Δt_with_constant_v(Δs, previousPoint[:v]) # step size (in s) + Δv = 0.0 # step size (in m/s) else - newPoint[:Δv] = stepSize * sign(previousPoint[:a]) # step size (in m/s) - newPoint[:Δs] = Δs_with_Δv(newPoint[:Δv], previousPoint[:a], previousPoint[:v]) # step size (in m) - newPoint[:Δt] = Δt_with_Δv(newPoint[:Δv], previousPoint[:a]) # step size (in s) + Δv = stepSize * sign(previousPoint[:a]) # step size (in m/s) + Δs = Δs_with_Δv(Δv, previousPoint[:a], previousPoint[:v]) # step size (in m) + Δt = Δt_with_Δv(Δv, previousPoint[:a]) # step size (in s) end end #if - newPoint[:s] = previousPoint[:s] + newPoint[:Δs] # position (in m) - newPoint[:t] = previousPoint[:t] + newPoint[:Δt] # point in time (in s) - newPoint[:v] = previousPoint[:v] + newPoint[:Δv] # velocity (in m/s) + newPoint[:s] = previousPoint[:s] + Δs # position (in m) + newPoint[:t] = previousPoint[:t] + Δt # point in time (in s) + newPoint[:v] = previousPoint[:v] + Δv # velocity (in m/s) return newPoint end #function moveAStep diff --git a/src/constructors.jl b/src/constructors.jl index 0cedf61..fe90a88 100644 --- a/src/constructors.jl +++ b/src/constructors.jl @@ -708,7 +708,6 @@ function BehaviorSection(type::String, s_entry::Real, v_entry::Real, startingPoi :s_entry => s_entry, # first position (in m) :s_exit => 0.0, # last position (in m) :t => 0.0, # total running time (in s) - :E => 0.0, # total energy consumption (in Ws) :v_entry => v_entry, # entry speed (in m/s) :v_exit => 0.0, # exit speed (in m/s) :supportPoints => [startingPoint] # list of identifiers of the containing support points starting with the initial point @@ -725,16 +724,9 @@ function SupportPoint() :behavior => "", # type of behavior section the support point is part of - see BehaviorSection() # a support 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) :t => 0.0, # point in time (in s) - :Δt => 0.0, # step size (in s) :v => 0.0, # velocity (in m/s) - :Δv => 0.0, # step size (in m/s) :a => 0.0, # acceleration (in m/s^2) - :W => 0.0, # mechanical work (in Ws) - :ΔW => 0.0, # mechanical work in this step (in Ws) - :E => 0.0, # energy consumption (in Ws) - :ΔE => 0.0, # energy consumption in this step (in Ws) :F_T => 0.0, # tractive effort (in N) :F_R => 0.0, # resisting force (in N) :R_path => 0.0, # path resistance (in N) From 99a07094fcf7ab2f8db52582e6824a27a3890fd2 Mon Sep 17 00:00:00 2001 From: Max Kannenberg <95709892+MaxKannenberg@users.noreply.github.com> Date: Tue, 12 Jul 2022 16:59:45 +0200 Subject: [PATCH 4/7] Remove the Dictionary for the moving section --- src/TrainRuns.jl | 12 +++++------ src/behavior.jl | 21 ++++++++----------- src/calc.jl | 42 +++++++++++++++++++++++--------------- src/constructors.jl | 49 +++++++++++---------------------------------- 4 files changed, 52 insertions(+), 72 deletions(-) diff --git a/src/TrainRuns.jl b/src/TrainRuns.jl index 754a3e6..5cf5801 100644 --- a/src/TrainRuns.jl +++ b/src/TrainRuns.jl @@ -46,15 +46,15 @@ xxx.xx # in seconds """ function trainrun(train::Train, path::Path, settings=Settings()::Settings) # prepare the input data - movingSection = determineCharacteristics(path, train, settings) - # settings.outputDetail == :verbose && println("The moving section has been prepared.") + (characteristicSections, pointsOfInterest) = determineCharacteristics(path, train, settings) + # TODO settings.outputDetail == :verbose && println("The characteristics haven been determined.") - # calculate the train run for oparation mode "minimum running time" - (movingSection, drivingCourse) = calculateMinimumRunningTime!(movingSection, settings, train) - # settings.outputDetail == :verbose && println("The driving course for the shortest running time has been calculated.") + # calculate the train run with the minimum running time + (characteristicSections, drivingCourse) = calculateMinimumRunningTime!(characteristicSections, settings, train) + # TODO settings.outputDetail == :verbose && println("The driving course for the shortest running time has been calculated.") # accumulate data and create an output dictionary - output = createOutput(settings, drivingCourse, movingSection[:pointsOfInterest]) + output = createOutput(settings, drivingCourse, pointsOfInterest) return output end # function trainrun diff --git a/src/behavior.jl b/src/behavior.jl index 2c05027..f64d817 100644 --- a/src/behavior.jl +++ b/src/behavior.jl @@ -107,11 +107,8 @@ end #function addClearingSection ## This function calculates the support 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}, stateFlags::Dict, settings::Settings, train::Train, CSs::Vector{Dict}) - #function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Settings, train::Train, CSs::Vector{Dict}, ignoreBraking::Bool) - #=if drivingCourse would also be part of movingSectiong: function addAcceleratingSection!(movingSection::Dict, stateFlags::Dict, csId::Integer, settings::Settings, train::Train) - CSs = movingSection[:characteristicSections] - CS = CSs[csId] - drivingCourse = movingSection[:drivingCourse]=# +#= TODO: instead of CS just give csId? + -> CS = CSs[csId] =# calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings.massModel) @@ -1176,9 +1173,8 @@ function recalculateLastBrakingPoint!(drivingCourse, s_target, v_target) end #function recalculateLastBrakingPoint ## define the intersection velocities between the characterisitc sections to secure braking behavior -function secureBrakingBehavior!(movingSection::Dict, a_braking::Real, approxLevel::Integer) - # this function limits the entry and exit velocity of the characteristic sections to secure that the train stops at the moving sections end - CSs = movingSection[:characteristicSections] +function secureBrakingBehavior!(CSs::Vector{Dict}, a_braking::Real, approxLevel::Integer) + # limit the entry and exit velocity of the characteristic sections to secure that the train stops at the moving sections end csId = length(CSs) followingCSv_entry = 0.0 # the exit velocity of the last characteristic section is 0.0 m/s @@ -1200,13 +1196,12 @@ function secureBrakingBehavior!(movingSection::Dict, a_braking::Real, approxLeve followingCSv_entry = CS[:v_entry] csId = csId - 1 end #while - return movingSection + return CSs end #function secureBrakingBehavior! ## define the intersection velocities between the characterisitc sections to secure accelerating behavior -function secureAcceleratingBehavior!(movingSection::Dict, settings::Settings, train::Train) - # 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] +function secureAcceleratingBehavior!(CSs::Vector{Dict}, settings::Settings, train::Train) + # limit the entry and exit velocity of the characteristic sections in case that the train accelerates in every section and cruises afterwards CSs[1][:v_entry] = 0.0 # the entry velocity of the first characteristic section is 0.0 m/s startingPoint = SupportPoint() @@ -1264,5 +1259,5 @@ function secureAcceleratingBehavior!(movingSection::Dict, settings::Settings, tr CS[:t] = 0.0 end #for - return movingSection + return CSs end #function secureAcceleratingBehavior! diff --git a/src/calc.jl b/src/calc.jl index 66d52e8..349766f 100644 --- a/src/calc.jl +++ b/src/calc.jl @@ -7,12 +7,11 @@ # Calculate the running time of a train run on a path with special settings with information from the corresponding YAML files with the file paths `trainDirectory`, `pathDirectory`, `settingsDirectory`. # calculate a train run focussing on using the minimum possible running time -function calculateMinimumRunningTime!(movingSection::Dict, settings::Settings, train::Train) - CSs::Vector{Dict} = movingSection[:characteristicSections] +function calculateMinimumRunningTime!(CSs::Vector{Dict}, settings::Settings, train::Train) if settings.massModel == :homogeneous_strip && settings.stepVariable == speed println("WARNING: ! ! ! TrainRuns.jl doesn't work reliably for the mass model homogeneous strip with step size v in m/s. The calculation time can be extremely high when calcutlating paths with steep gradients ! ! !") - end + end # TODO startingPoint = SupportPoint() startingPoint[:i] = 1 @@ -22,7 +21,7 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Settings, t for csId in 1:length(CSs) CS = CSs[csId] - # for testing + # for testing: # TODO if drivingCourse[end][:s] != CS[:s_entry] println("ERROR: In CS", csId," the train run starts at s=",drivingCourse[end][:s]," and not s_entry=",CS[:s_entry]) end @@ -106,7 +105,7 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Settings, t #end - # for testing: + # for testing: # TODO if drivingCourse[end][:s] != 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 @@ -117,9 +116,7 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Settings, t (CSs[end], drivingCourse) = addHalt!(CSs[end], drivingCourse, settings, train, CSs) - movingSection[:t] = drivingCourse[end][:t] # total running time (in s) - - return (movingSection, drivingCourse) + return (CSs, drivingCourse) end #function calculateMinimumRunningTime @@ -180,7 +177,7 @@ function calculatePathResistance(CSs::Vector{Dict}, csId::Integer, s::Real, mass pathResistance = pathResistance + (min(s, CSs[csId][:s_exit]) - max(s_rear, CSs[csId][:s_entry])) / train.length * forceFromCoefficient(CSs[csId][:r_path], train.m_train_full) csId = csId-1 if csId == 0 - # TODO: currently for values < movingSection[:s_entry] the values of movingSection[:s_entry] will be used + # TODO: currently for values < s_trainrun_start the values of s_trainrun_start will be used return pathResistance + (CSs[1][:s_entry] - s_rear) / train.length * forceFromCoefficient(CSs[1][:r_path], train.m_train_full) end #if end #while @@ -289,7 +286,7 @@ function getCurrentSpeedLimit(CSs::Vector{Dict}, csWithTrainHeadId::Integer, s:: 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 + if CSs[formerCsId][:v_limit] < v_limit # TODO: is the position of the train's rear < s_trainrun_start, v_limit of the first CS is used v_limit = CSs[formerCsId][:v_limit] s_exit = CSs[formerCsId][:s_exit] end @@ -314,12 +311,25 @@ function getNextPointOfInterest(pointsOfInterest::Vector{Tuple}, s::Real) end #function getNextPointOfInterest -## create a moving section and its containing characteristic sections with secured braking, accelerating and cruising behavior +## create vectors with the moving section's points of interest and with the characteristic sections with secured braking and accelerating behavior function determineCharacteristics(path::Path, train::Train, settings::Settings) - movingSection = MovingSection(path, train.v_limit, train.length) - movingSection = secureBrakingBehavior!(movingSection, train.a_braking, settings.approxLevel) - movingSection = secureAcceleratingBehavior!(movingSection, settings, train) - #movingSection = secureCruisingBehavior!(movingSection, settings, train) + # determine the positions of the points of interest depending on the interesting part of the train (front/rear) and the train's length + ##TODO: use a tuple with naming + pointsOfInterest = Tuple[] + if !isempty(path.poi) + for POI in path.poi + s_poi = POI[:station] + if POI[:measure] == "rear" + s_poi += train.length + end + push!(pointsOfInterest, (s_poi, POI[:label]) ) + end + sort!(pointsOfInterest, by = x -> x[1]) + end - return movingSection + characteristicSections = CharacteristicSections(path, train.v_limit, train.length, pointsOfInterest) + characteristicSections = secureBrakingBehavior!(characteristicSections, train.a_braking, settings.approxLevel) + characteristicSections = secureAcceleratingBehavior!(characteristicSections, settings, train) + + return (characteristicSections, pointsOfInterest) end #function determineCharacteristics diff --git a/src/constructors.jl b/src/constructors.jl index fe90a88..2b89c4d 100644 --- a/src/constructors.jl +++ b/src/constructors.jl @@ -254,9 +254,9 @@ function Path(file, type = :YAML) if POI_PRESENT sort!(tmp_points, by = x -> x[1]) for elem in tmp_points - station = elem[1] # first point of the section (in m) - label = elem[2] # paths speed limt (in m/s) - measure = elem[3] # specific path resistance of the section (in ‰) + station = elem[1] # station in m + label = elem[2] # name + measure = elem[3] # front or rear point = Dict(:station => station, :label => label, @@ -613,53 +613,28 @@ function Train(file, type = :YAML) end #function Train() # outer constructor -## create a moving section containing characteristic sections -function MovingSection(path::Path, v_trainLimit::Real, s_trainLength::Real) - # this function creates and returns a moving section dependent on the paths attributes - - s_entry = path.sections[1][:s_start] # first position (in m) - s_exit = path.sections[end][:s_end] # last position (in m) - pathLength = s_exit - s_entry # total length (in m) - - ##TODO: use a tuple with naming - pointsOfInterest = Tuple[] - if !isempty(path.poi) - for POI in path.poi - s_poi = POI[:station] - if POI[:measure] == "rear" - s_poi += s_trainLength - end - push!(pointsOfInterest, (s_poi, POI[:label]) ) - end - sort!(pointsOfInterest, by = x -> x[1]) - end +## create the moving section's characteristic sections +function CharacteristicSections(path::Path, v_trainLimit::Real, s_trainLength::Real, MS_poi::Vector{Tuple}) + # create and return the characteristic sections of a moving section dependent on the paths attributes CSs=Vector{Dict}() - s_csStart=s_entry - csId=1 + s_csStart = path.sections[1][:s_start] # first position (in m) + csId = 1 for row in 2:length(path.sections) previousSection = path.sections[row-1] currentSection = path.sections[row] speedLimitIsDifferent = min(previousSection[:v_limit], v_trainLimit) != min(currentSection[:v_limit], v_trainLimit) pathResistanceIsDifferent = previousSection[:f_Rp] != currentSection[:f_Rp] if speedLimitIsDifferent || pathResistanceIsDifferent - push!(CSs, CharacteristicSection(csId, s_csStart, previousSection, min(previousSection[:v_limit], v_trainLimit), s_trainLength, pointsOfInterest)) + push!(CSs, CharacteristicSection(csId, s_csStart, previousSection, min(previousSection[:v_limit], v_trainLimit), s_trainLength, MS_poi)) s_csStart = currentSection[:s_start] csId = csId+1 end #if end #for - push!(CSs, CharacteristicSection(csId, s_csStart, path.sections[end], min(path.sections[end][:v_limit], v_trainLimit), s_trainLength, pointsOfInterest)) + push!(CSs, CharacteristicSection(csId, s_csStart, path.sections[end], min(path.sections[end][:v_limit], v_trainLimit), s_trainLength, MS_poi)) - movingSection= Dict(:id => 1, # identifier # if there is more than one moving section in a later version of this tool the id should not be constant anymore - :length => pathLength, # total length (in m) - :s_entry => s_entry, # first position (in m) - :s_exit => s_exit, # last position (in m) - :t => 0.0, # total running time (in s) - :characteristicSections => CSs, # list of containing characteristic sections - :pointsOfInterest => pointsOfInterest) # list of containing points of interest - - return movingSection -end #function MovingSection + return CSs +end #function CharacteristicSections ## create a characteristic section for a path section. A characteristic section is a part of the moving section. It contains behavior sections. function CharacteristicSection(id::Integer, s_entry::Real, section::Dict, v_limit::Real, s_trainLength::Real, MS_poi::Vector{Tuple}) From acf8cd0c3b1a72eda63fa05d55791a1085b1dd18 Mon Sep 17 00:00:00 2001 From: Max Kannenberg <95709892+MaxKannenberg@users.noreply.github.com> Date: Wed, 13 Jul 2022 00:15:57 +0200 Subject: [PATCH 5/7] Remove the Dictionary for the behavior sections --- src/behavior.jl | 221 ++++++++++---------------------------------- src/constructors.jl | 39 ++------ 2 files changed, 59 insertions(+), 201 deletions(-) diff --git a/src/behavior.jl b/src/behavior.jl index f64d817..4649260 100644 --- a/src/behavior.jl +++ b/src/behavior.jl @@ -13,8 +13,9 @@ function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags: trainIsHalting = drivingCourse[end][:v] == 0.0 if trainIsHalting && !endOfCSReached - BS = BehaviorSection("breakFree", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) - drivingCourse[end][:behavior] = BS[:type] + drivingMode = "breakFree" + drivingCourse[end][:behavior] = drivingMode + startingPoint = drivingCourse[end][:i] # traction effort and resisting forces (in N) calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings.massModel) # currently the tractive effort is calculated like in the accelerating section @@ -27,28 +28,13 @@ function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags: end # delete every supportPoint except the first two - while drivingCourse[end][:i] > drivingCourse[BS[:supportPoints][1]][:i] +1 + while drivingCourse[end][:i] > startingPoint +1 pop!(drivingCourse) end # change the accelerating data to break free - drivingCourse[end-1][:behavior] = BS[:type] - drivingCourse[end][:behavior] = BS[:type] - push!(BS[:supportPoints], drivingCourse[end][:i]) - - # remove the accelerating section from the CS - CS[:t] = CS[:t] - get(CS[:behaviorSections], :accelerating, Dict(:t=>0.0))[:t] # total running time (in s) - delete!(CS[:behaviorSections], :accelerating) - - # calculate the accumulated breakFree section information - merge!(BS, Dict(:length => drivingCourse[end][:s] - BS[:s_entry], # total length (in m) - :s_exit => drivingCourse[end][:s], # last position (in m) - :t => drivingCourse[end][:t] - drivingCourse[BS[:supportPoints][1]][:t], # total running time (in s) - :v_exit => drivingCourse[end][:v])) # exit speed (in m/s))) - - CS[:t] = CS[:t] + BS[:t] # total running time (in s) - - merge!(CS[:behaviorSections], Dict(:breakFree => BS)) + drivingCourse[end-1][:behavior] = drivingMode + drivingCourse[end][:behavior] = drivingMode end # else: return the characteristic section without a breakFree section # determine state flags @@ -107,7 +93,7 @@ end #function addClearingSection ## This function calculates the support 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}, stateFlags::Dict, settings::Settings, train::Train, CSs::Vector{Dict}) -#= TODO: instead of CS just give csId? + #= TODO: instead of CS just give csId? -> CS = CSs[csId] =# calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings.massModel) @@ -129,8 +115,8 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFla # use the conditions for the accelerating section if !targetSpeedReached && !endOfCSReached && tractionSurplus && !brakingStartReached - BS = BehaviorSection("accelerating", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) - drivingCourse[end][:behavior] = BS[:type] + drivingMode = "accelerating" + drivingCourse[end][:behavior] = drivingMode currentSpeedLimit = getCurrentSpeedLimit(CSs, CS[:id], drivingCourse[end][:s], train.length) previousSpeedLimitReached = currentSpeedLimit[:v] != CS[:v_limit] && drivingCourse[end][:v] >= currentSpeedLimit[:v] @@ -159,10 +145,9 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFla # create the next support point push!(drivingCourse, moveAStep(drivingCourse[end], settings.stepVariable, currentStepSize, CS[:id])) - drivingCourse[end][:behavior] = BS[:type] - push!(BS[:supportPoints], drivingCourse[end][:i]) + drivingCourse[end][:behavior] = drivingMode - calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings.massModel) + calculateForces!(drivingCourse[end], CSs, CS[:id], drivingMode, train, settings.massModel) # conditions for the next while cycle if !ignoreBraking @@ -249,7 +234,6 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFla end # delete last support point for recalculating the last step with reduced step size pop!(drivingCourse) - pop!(BS[:supportPoints]) # conditions for the next for cycle brakingStartReached = false @@ -264,7 +248,6 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFla if drivingCourse[end][:v] > CS[:v_peak] testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," > v_peak=",CS[:v_peak]) # for testing pop!(drivingCourse) - pop!(BS[:supportPoints]) # conditions for the next section brakingStartReached = false @@ -273,7 +256,6 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFla testFlag && 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 if s_braking > 0.0 pop!(drivingCourse) - pop!(BS[:supportPoints]) else drivingCourse[end][:s] = CS[:s_exit] # round s down to CS[:s_exit] @@ -291,7 +273,6 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFla previousSpeedLimitReached = true pop!(drivingCourse) - pop!(BS[:supportPoints]) else if drivingCourse[end][:s] + s_braking == CS[:s_exit] @@ -318,19 +299,6 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFla end end #while - - if length(BS[:supportPoints]) > 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[:supportPoints][1]][:t], # total running time (in s) - :v_exit => drivingCourse[end][:v])) # exit speed (in m/s))) - - # 03/10 old: CS[:v_peak] = max(drivingCourse[end][:v], CS[:v_entry]) # setting v_peak to the last support 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) - - mergeBehaviorSection!(CS[:behaviorSections], BS) - end end # set state flags @@ -353,7 +321,7 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: trainIsBrakingDownhill = cruisingType == "downhillBraking" # traction effort and resisting forces (in N) - if !trainIsBrakingDownhill # TODO: or just give BS[:type] instead of "cruising"/"braking"? + if !trainIsBrakingDownhill # TODO: or just give drivingMode instead of "cruising"/"braking"? calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings.massModel) else calculateForces!(drivingCourse[end], CSs, CS[:id], "braking", train, settings.massModel) @@ -374,17 +342,16 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: tractionDeficit = drivingCourse[end][:F_T] < drivingCourse[end][:F_R] targetPositionReached = s_cruising == 0.0 resistingForceNegative = drivingCourse[end][:F_R] < 0 -#println(" vor if speedIsValid=",speedIsValid ," brakingStartReached=", brakingStartReached," tractionDeficit=", tractionDeficit," targetPositionReached=", targetPositionReached) if speedIsValid && !brakingStartReached && !tractionDeficit && !targetPositionReached # 03/04 old: if drivingCourse[end][:v]>0.0 && drivingCourse[end][:v]<=CS[:v_peak] && !brakingStartReached && drivingCourse[end][:F_T] >= drivingCourse[end][:F_R] - BS = BehaviorSection(cruisingType, drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) - drivingCourse[end][:behavior] = BS[:type] + drivingMode = cruisingType + drivingCourse[end][:behavior] = drivingMode # TODO: necessary? - s_cruising = min(s_cruising, CS[:s_exit]-BS[:s_entry]) + targetPosition = min(drivingCourse[end][:s] + s_cruising, CS[:s_exit]) + # 07/12 old: s_cruising = min(s_cruising, CS[:s_exit]-drivingCourse[end][:s]) # traction effort and resisting forces (in N) -#03/25 calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings.massModel) if !trainIsBrakingDownhill calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings.massModel) else @@ -394,7 +361,7 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: if settings.massModel == :homogeneous_strip && CS[:id] > 1 # conditions for cruising section trainInPreviousCS = drivingCourse[end][:s] < CS[:s_entry] + train.length - targetPositionReached = drivingCourse[end][:s] >= BS[:s_entry] +s_cruising + targetPositionReached = drivingCourse[end][:s] >= targetPosition resistingForceNegative = drivingCourse[end][:F_R] < 0.0 # targetSpeedReached = stateFlags[:speedLimitReached] || drivingCourse[end][:v] >= CS[:v_peak] # TODO: change? to correctCruisingType = (trainIsClearing || (trainIsBrakingDownhill == drivingCourse[end][:F_R] < 0)) # while clearing tractive or braking force can be used @@ -407,11 +374,9 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: for cycle in 1:settings.approxLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation while trainInPreviousCS && !targetPositionReached && !pointOfInterestReached && !tractionDeficit && (trainIsClearing || (trainIsBrakingDownhill == resistingForceNegative)) # while clearing tractive or braking force can be used - # 03/09 old: while drivingCourse[end][:s] < CS[:s_entry] + train.length && drivingCourse[end][:s] < BS[:s_entry] +s_cruising && drivingCourse[end][:s] < nextPointOfInterest[1] && drivingCourse[end][:F_T]>=drivingCourse[end][:F_R] # the tractive effort is lower than the resisiting forces and the train has use the highest possible effort to try to stay at v_peak OR the mass model homogeneous strip is used and parts of the train are still in former CS #TODO: maybe just consider former CS with different path resistance? # tractive effort (in N): -#03/25 drivingCourse[end][:F_T] = min(drivingCourse[end][:F_T], max(0.0, drivingCourse[end][:F_R])) if !trainIsBrakingDownhill drivingCourse[end][:F_T] = min(drivingCourse[end][:F_T], max(0.0, drivingCourse[end][:F_R])) else @@ -428,8 +393,7 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: else push!(drivingCourse, moveAStep(drivingCourse[end], position, train.length/(10.0^cycle), CS[:id])) # TODO which step size should be used? end - drivingCourse[end][:behavior] = BS[:type] - push!(BS[:supportPoints], drivingCourse[end][:i]) + drivingCourse[end][:behavior] = drivingMode # traction effort and resisting forces (in N) calculateForces!(drivingCourse[end], CSs, CS[:id], "default", train, settings.massModel) @@ -443,7 +407,7 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: # conditions for the next while cycle pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest[1] # POIs include s_exit as well tractionDeficit = drivingCourse[end][:F_T] < drivingCourse[end][:F_R] - targetPositionReached = drivingCourse[end][:s] >= BS[:s_entry] +s_cruising + targetPositionReached = drivingCourse[end][:s] >= targetPosition trainInPreviousCS = drivingCourse[end][:s] < CS[:s_entry] + train.length resistingForceNegative = drivingCourse[end][:F_R] < 0.0 end #while @@ -466,14 +430,14 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: currentStepSize = settings.stepSize / 10.0^cycle end - elseif drivingCourse[end][:s] > BS[:s_entry] + s_cruising # TODO also the following? drivingCourse[end][:s] > CSs[CS[:id]][:s_entry] + train.length)) + elseif drivingCourse[end][:s] > targetPosition # TODO also the following? drivingCourse[end][:s] > CSs[CS[:id]][:s_entry] + train.length)) if settings.stepVariable == :distance - currentStepSize=BS[:s_entry] + s_cruising-drivingCourse[end-1][:s] + currentStepSize = targetPosition - drivingCourse[end-1][:s] else currentStepSize = settings.stepSize / 10.0^cycle end - elseif drivingCourse[end][:s] == BS[:s_entry] + s_cruising # || drivingCourse[end][:s]==CS[:s_exit] + elseif drivingCourse[end][:s] == targetPosition # || drivingCourse[end][:s]==CS[:s_exit] break elseif drivingCourse[end][:s] >= CS[:s_entry] + train.length @@ -491,7 +455,6 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: # delete last support point for recalculating the last step with reduced step size pop!(drivingCourse) - pop!(BS[:supportPoints]) # conditions for the next for cycle pointOfInterestReached = false @@ -503,12 +466,11 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: else # if the level of approximation is reached if drivingCourse[end][:s] > nextPointOfInterest[1] drivingCourse[end][:s] = nextPointOfInterest[1] # round s down to nextPointOfInterest - elseif drivingCourse[end][:s] > BS[:s_entry]+s_cruising - if BS[:type] != "clearing" + elseif drivingCourse[end][:s] > targetPosition + if drivingMode != "clearing" pop!(drivingCourse) - pop!(BS[:supportPoints]) end - elseif drivingCourse[end][:s] == BS[:s_entry]+s_cruising + elseif drivingCourse[end][:s] == targetPosition break elseif drivingCourse[end][:F_T] < drivingCourse[end][:F_R] break @@ -533,15 +495,15 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: end #if # conditions for the next while cycle - targetPositionReached = drivingCourse[end][:s] >= BS[:s_entry] +s_cruising + targetPositionReached = drivingCourse[end][:s] >= targetPosition tractionDeficit = drivingCourse[end][:F_T] < drivingCourse[end][:F_R] resistingForceNegative = drivingCourse[end][:F_R] < 0.0 while !targetPositionReached && !tractionDeficit && (trainIsClearing || (trainIsBrakingDownhill == resistingForceNegative)) # while clearing tractive or braking force can be used - # 03/09 old: while drivingCourse[end][:s] < BS[:s_entry]+s_cruising && drivingCourse[end][:F_T] >= drivingCourse[end][:F_R] + # 03/09 old: while drivingCourse[end][:s] < targetPosition && drivingCourse[end][:F_T] >= drivingCourse[end][:F_R] nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s]) - if nextPointOfInterest[1] > BS[:s_entry]+s_cruising - nextPointOfInterest = [BS[:s_entry]+s_cruising, ""] + if nextPointOfInterest[1] > targetPosition + nextPointOfInterest = [targetPosition, ""] end # tractive effort (in N): @@ -557,16 +519,15 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: drivingCourse[end][:a] = 0.0 # acceleration (in m/s^2) # calculate the remaining cruising way - #s_cruisingRemaining=BS[:s_entry] + s_cruising-drivingCourse[end][:s] - s_cruisingRemaining = min(nextPointOfInterest[1] -drivingCourse[end][:s], BS[:s_entry] +s_cruising -drivingCourse[end][:s]) + #s_cruisingRemaining=targetPosition-drivingCourse[end][:s] + s_cruisingRemaining = min(nextPointOfInterest[1] -drivingCourse[end][:s], targetPosition -drivingCourse[end][:s]) # create the next support point push!(drivingCourse, moveAStep(drivingCourse[end], :distance, s_cruisingRemaining, CS[:id])) - drivingCourse[end][:behavior] = BS[:type] + drivingCourse[end][:behavior] = drivingMode if drivingCourse[end][:s] == nextPointOfInterest[1] drivingCourse[end][:label] = nextPointOfInterest[2] end - push!(BS[:supportPoints], drivingCourse[end][:i]) calculateForces!(drivingCourse[end], CSs, CS[:id], "default", train, settings.massModel) # calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings.massModel) @@ -577,23 +538,11 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: #end # conditions for the next while cycle - targetPositionReached = drivingCourse[end][:s] >= BS[:s_entry] +s_cruising + targetPositionReached = drivingCourse[end][:s] >= targetPosition tractionDeficit = drivingCourse[end][:F_T] < drivingCourse[end][:F_R] resistingForceNegative = drivingCourse[end][:F_R] < 0 end #while - # TODO: realize this better inside the upper loops? - - - # calculate the accumulated cruising 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[:supportPoints][1]][:t], # total running time (in s) - :v_exit => drivingCourse[end][:v])) # exit speed (in m/s))) - - CS[:t] = CS[:t] + BS[:t] # total running time (in s) - - mergeBehaviorSection!(CS[:behaviorSections], BS) end # else: return the characteristic section without a cruising section # set state flags @@ -633,8 +582,8 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlag # use the conditions for the diminishing section if tractionDeficit && !targetSpeedReached && !endOfCSReached - BS = BehaviorSection("diminishing", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) - drivingCourse[end][:behavior] = BS[:type] + drivingMode = "diminishing" + drivingCourse[end][:behavior] = drivingMode while tractionDeficit && !targetSpeedReached && !endOfCSReached && !brakingStartReached currentStepSize=settings.stepSize # initialize the step size that can be reduced near intersections @@ -649,10 +598,9 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlag # create the next support point push!(drivingCourse, moveAStep(drivingCourse[end], settings.stepVariable, currentStepSize, CS[:id])) - drivingCourse[end][:behavior] = BS[:type] - push!(BS[:supportPoints], drivingCourse[end][:i]) + drivingCourse[end][:behavior] = drivingMode - calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings.massModel) + calculateForces!(drivingCourse[end], CSs, CS[:id], drivingMode, train, settings.massModel) # conditions for the next while cycle if !ignoreBraking @@ -717,7 +665,6 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlag end # delete last support point for recalculating the last step with reduced step size pop!(drivingCourse) - pop!(BS[:supportPoints]) # conditions for the next for cycle brakingStartReached = false @@ -729,7 +676,6 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlag else # if the level of approximation is reached if drivingCourse[end][:v] <= 0.0 testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: v=", drivingCourse[end][:v]," <= 0.0") # for testing - # push!(BS[:supportPoints], drivingCourse[end][:i]) error("ERROR: The train stops during diminishing run in CS",CS[:id]," because the maximum tractive effort is lower than the resistant forces.", " Before the stop the last point has the values s=",drivingCourse[end-1][:s]," m v=",drivingCourse[end-1][:v]," m/s a=",drivingCourse[end-1][:a]," m/s^2", " F_T=",drivingCourse[end-1][:F_T]," N R_traction=",drivingCourse[end-1][:R_traction]," N R_wagons=",drivingCourse[end-1][:R_wagons]," N R_path=",drivingCourse[end-1][:R_path]," N.") @@ -737,7 +683,6 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlag elseif s_braking > 0.0 && drivingCourse[end][:s] + s_braking > CS[:s_exit] testFlag && 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 pop!(drivingCourse) - pop!(BS[:supportPoints]) pointOfInterestReached = false targetSpeedReached = false @@ -773,18 +718,6 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlag drivingCourse[end][:label] = nextPointOfInterest[2] end end #while - - if length(BS[:supportPoints]) > 1 # TODO: necessary? May it be possible that there is no diminishing because braking has to start? - # calculate the accumulated diminishing 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[:supportPoints][1]][:t], # total running time (in s) - :v_exit => drivingCourse[end][:v])) # exit speed (in m/s))) - - CS[:t] = CS[:t] + BS[:t] # total running time (in s) - - mergeBehaviorSection!(CS[:behaviorSections], BS) - end end # set state flags @@ -814,8 +747,8 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: # use the conditions for the coasting section if !targetSpeedReached && !endOfCSReached - BS = BehaviorSection("coasting", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) - drivingCourse[end][:behavior] = BS[:type] + drivingMode = "coasting" + drivingCourse[end][:behavior] = drivingMode while !targetSpeedReached && !endOfCSReached && !brakingStartReached currentStepSize=settings.stepSize # initialize the step size that can be reduced near intersections @@ -826,15 +759,14 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: while !targetSpeedReached && !brakingStartReached && !pointOfInterestReached # 03/09 old : while drivingCourse[end][:v] > CS[:v_exit] && drivingCourse[end][:v] <= CS[:v_peak] && !brakingStartReached && drivingCourse[end][:s] < nextPointOfInterest[1] # traction effort and resisting forces (in N): - calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings.massModel) + calculateForces!(drivingCourse[end], CSs, CS[:id], drivingMode, train, settings.massModel) # acceleration (in m/s^2): drivingCourse[end][:a] = acceleration(drivingCourse[end][:F_T], drivingCourse[end][:F_R], train.m_train_full, train.ξ_train) # create the next support point push!(drivingCourse, moveAStep(drivingCourse[end], settings.stepVariable, currentStepSize, CS[:id])) - drivingCourse[end][:behavior] = BS[:type] - push!(BS[:supportPoints], drivingCourse[end][:i]) + drivingCourse[end][:behavior] = drivingMode # conditions for the next while cycle s_braking = brakingDistance(drivingCourse[end][:v], CS[:v_exit], train.a_braking, settings.approxLevel) @@ -892,7 +824,6 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: end # delete last support point for recalculating the last step with reduced step size pop!(drivingCourse) - pop!(BS[:supportPoints]) # conditions for the next for cycle brakingStartReached = false @@ -909,7 +840,6 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: elseif drivingCourse[end][:s] + s_braking > CS[:s_exit] # delete last support point because it went to far pop!(drivingCourse) - pop!(BS[:supportPoints]) # conditions for the next for cycle # brakingStartReached = true @@ -919,7 +849,6 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: elseif drivingCourse[end][:v] > CS[:v_peak] # if the train gets to fast it has to brake # TODO: if accelereation and coasting functions will be combined this case is different for coasting and also the order of if cases is different # delete last support point because it went to far pop!(drivingCourse) - pop!(BS[:supportPoints]) # conditions for the next for cycle brakingStartReached = false @@ -941,16 +870,6 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:: end #while stateFlags[:speedLimitReached] = false - - # calculate the accumulated coasting 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[:supportPoints][1]][:t], # total running time (in s) - :v_exit => drivingCourse[end][:v])) # exit speed (in m/s))) - - CS[:t] = CS[:t] + BS[:t] # total running time (in s) - - merge!(CS[:behaviorSections], Dict(:coasting=>BS)) end # set state flags @@ -973,8 +892,8 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::D # use the conditions for the braking section if !targetSpeedReached && !endOfCSReached - BS = BehaviorSection("braking", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) - drivingCourse[end][:behavior] = BS[:type] + drivingMode = "braking" + drivingCourse[end][:behavior] = drivingMode while !targetSpeedReached && !endOfCSReached currentStepSize = settings.stepSize # initialize the step size that can be reduced near intersections @@ -985,7 +904,7 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::D while !targetSpeedReached && !endOfCSReached && !pointOfInterestReached # 03/09 old: while drivingCourse[end][:v] > CS[:v_exit] && !targetSpeedReached && drivingCourse[end][:s] < CS[:s_exit] && drivingCourse[end][:s] < nextPointOfInterest[1] # traction effort and resisting forces (in N): - calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings.massModel) + calculateForces!(drivingCourse[end], CSs, CS[:id], drivingMode, train, settings.massModel) # acceleration (in m/s^2): drivingCourse[end][:a] = train.a_braking @@ -995,14 +914,12 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::D # create empty support point and set it for the values of s_exit and v_exit push!(drivingCourse, SupportPoint()) drivingCourse[end][:i] = drivingCourse[end-1][:i]+1 - drivingCourse[end][:behavior] = BS[:type] - push!(BS[:supportPoints], drivingCourse[end][:i]) + drivingCourse[end][:behavior] = drivingMode recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit]) else # create the next support point push!(drivingCourse, moveAStep(drivingCourse[end], settings.stepVariable, currentStepSize, CS[:id])) - drivingCourse[end][:behavior] = BS[:type] - push!(BS[:supportPoints], drivingCourse[end][:i]) + drivingCourse[end][:behavior] = drivingMode end #println(drivingCourse[end][:i],". s=",drivingCourse[end][:s]," s_exit=", CS[:s_exit]," v_exit=", CS[:v_exit]," v=",drivingCourse[end][:v]) @@ -1046,7 +963,6 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::D # delete last support point for recalculating the last step with reduced step size pop!(drivingCourse) - pop!(BS[:supportPoints]) # conditions for the next for cycle pointOfInterestReached = false @@ -1098,16 +1014,6 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::D end end #while - - # calculate the accumulated coasting 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[:supportPoints][1]][:t], # total running time (in s) - :v_exit => drivingCourse[end][:v])) # exit speed (in m/s))) - - CS[:t] = CS[:t] + BS[:t] # total running time (in s) - - merge!(CS[:behaviorSections], Dict(:braking=>BS)) end # else: return the characteristic section without a braking section # set state flags @@ -1127,35 +1033,15 @@ end #function addBrakingSection! # Therefore it gets its first support point and the characteristic section and returns the characteristic section including the halt if needed. function addHalt!(CS::Dict, drivingCourse::Vector{Dict}, settings::Settings, train::Train, CSs::Vector{Dict}) if drivingCourse[end][:v] == 0.0 - BS = BehaviorSection("standstill", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i]) - merge!(BS, Dict(:length => 0.0, # total length (in m) - :t => 0.0, # total running time (in s) - :s_exit => drivingCourse[end][:s], # last position (in m) - :v_exit => drivingCourse[end][:v])) # exit speed (in m/s))) - drivingCourse[end][:behavior] = BS[:type] + drivingMode = "halt" + drivingCourse[end][:behavior] = drivingMode # traction effort and resisting forces (in N) - calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings.massModel) - - merge!(CS[:behaviorSections], Dict(:halt => BS)) + calculateForces!(drivingCourse[end], CSs, CS[:id], drivingMode, train, settings.massModel) end # else: return the characteristic section without a halt section section return (CS, drivingCourse) end #function addHalt! -function mergeBehaviorSection!(BSs::Dict, BS::Dict) - if !haskey(BSs, Symbol(BS[:type])) - merge!(BSs, Dict(Symbol(BS[:type]) => BS)) - else - number = "2" - while haskey(BSs, Symbol(BS[:type]*number)) - number = string(parse(Int, number)+1) - end - merge!(BSs, Dict(Symbol(BS[:type]*number) => BS)) - # println("INFO: The ",number,". ",BS[:type]," section has been created. ! ! ! ! ! ! ! ! !") - end - return BSs -end #function mergeBehaviorSection! - function recalculateLastBrakingPoint!(drivingCourse, s_target, v_target) currentPoint = drivingCourse[end] previousPoint = drivingCourse[end-1] @@ -1188,11 +1074,6 @@ function secureBrakingBehavior!(CSs::Vector{Dict}, a_braking::Real, approxLevel: CS[:v_entry] = min(CS[:v_limit], v_entryMax) CS[:v_peak] = CS[:v_entry] - - # 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() - CS[:t] = 0.0 - followingCSv_entry = CS[:v_entry] csId = csId - 1 end #while @@ -1253,10 +1134,6 @@ function secureAcceleratingBehavior!(CSs::Vector{Dict}, settings::Settings, trai end #if previousCSv_exit = CS[:v_exit] - - # 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() - CS[:t] = 0.0 end #for return CSs diff --git a/src/constructors.jl b/src/constructors.jl index 2b89c4d..7d93711 100644 --- a/src/constructors.jl +++ b/src/constructors.jl @@ -639,18 +639,16 @@ end #function CharacteristicSections ## create a characteristic section for a path section. A characteristic section is a part of the moving section. It contains behavior sections. function CharacteristicSection(id::Integer, s_entry::Real, section::Dict, v_limit::Real, s_trainLength::Real, MS_poi::Vector{Tuple}) # Create and return a characteristic section dependent on the paths attributes - characteristicSection= Dict(:id => id, # identifier - :s_entry => s_entry, # first position (in m) - :s_exit => section[:s_end], # last position (in m) - :length => section[:s_end] -s_entry, # total length (in m) - :r_path => section[:f_Rp], # path resistance (in ‰) - :behaviorSections => Dict(), # list of containing behavior sections - :t => 0.0, # total running time (in s) - :v_limit => v_limit, # speed limit (in m/s) - # initializing :v_entry, :v_peak and :v_exit with :v_limit - :v_peak => v_limit, # maximum reachable speed (in m/s) - :v_entry => v_limit, # maximum entry speed (in m/s) - :v_exit => v_limit) # maximum exit speed (in m/s) + characteristicSection::Dict{Symbol, Any} = Dict(:id => id, # identifier + :s_entry => s_entry, # first position (in m) + :s_exit => section[:s_end], # last position (in m) + :length => section[:s_end] -s_entry, # total length (in m) + :r_path => section[:f_Rp], # path resistance (in ‰) + :v_limit => v_limit, # speed limit (in m/s) + # initializing :v_entry, :v_peak and :v_exit with :v_limit + :v_peak => v_limit, # maximum reachable speed (in m/s) + :v_entry => v_limit, # maximum entry speed (in m/s) + :v_exit => v_limit) # maximum exit speed (in m/s) # list of positions of every point of interest (POI) in this charateristic section for which support points should be calculated s_exit = characteristicSection[:s_exit] @@ -673,23 +671,6 @@ function CharacteristicSection(id::Integer, s_entry::Real, section::Dict, v_limi return characteristicSection end #function CharacteristicSection -""" -BehaviorSection() TODO! -""" -function BehaviorSection(type::String, s_entry::Real, v_entry::Real, startingPoint::Integer) - BS= Dict( - :type => type, # type of behavior section: "breakFree", "clearing", "accelerating", "cruising", "downhillBraking", "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) - :t => 0.0, # total running time (in s) - :v_entry => v_entry, # entry speed (in m/s) - :v_exit => 0.0, # exit speed (in m/s) - :supportPoints => [startingPoint] # list of identifiers of the containing support points starting with the initial point - ) - return BS -end #function BehaviorSection - """ a SupportPoint is the smallest element of the driving course. One step of the step approach is between two support points """ From 5e33e62a79c78513dcea0a9ca65b87376a8fb669 Mon Sep 17 00:00:00 2001 From: Max Kannenberg <95709892+MaxKannenberg@users.noreply.github.com> Date: Mon, 8 Aug 2022 16:10:38 +0200 Subject: [PATCH 6/7] Change output for outputDetail=:points_of_interest for a path without POI --- src/output.jl | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/output.jl b/src/output.jl index d18fdb9..7775049 100644 --- a/src/output.jl +++ b/src/output.jl @@ -8,17 +8,23 @@ function createOutput(settings::Settings, drivingCourse::Vector{Dict}, pointsOfI if settings.outputDetail == :running_time output::Vector{Dict} = [Dict(:t => drivingCourse[end][:t])] - elseif settings.outputDetail == :points_of_interest && !isempty(pointsOfInterest) + elseif settings.outputDetail == :points_of_interest # get only the driving course's support points with POI labels + # if there is no point with POI label return the information of departure and arrival (first and last points) output = Dict[] - supportPoint = 1 - for POI in 1:length(pointsOfInterest) - while supportPoint <= length(drivingCourse) - if pointsOfInterest[POI][1] == drivingCourse[supportPoint][:s] - push!(output, drivingCourse[supportPoint]) - break + if isempty(pointsOfInterest) + push!(output, drivingCourse[1]) + push!(output, drivingCourse[end]) + else + supportPoint = 1 + for POI in 1:length(pointsOfInterest) + while supportPoint <= length(drivingCourse) + if pointsOfInterest[POI][1] == drivingCourse[supportPoint][:s] + push!(output, drivingCourse[supportPoint]) + break + end + supportPoint += 1 end - supportPoint += 1 end end @@ -34,7 +40,7 @@ function createOutput(settings::Settings, drivingCourse::Vector{Dict}, pointsOfI end end - else #if settings.outputDetail == :driving_course || (settings.outputDetail == :points_of_interest && !isempty(path.poi)) + elseif settings.outputDetail == :driving_course output = drivingCourse end From cbd4e7f97fab64716ae20cee81d20658382d903f Mon Sep 17 00:00:00 2001 From: Max Kannenberg <95709892+MaxKannenberg@users.noreply.github.com> Date: Mon, 8 Aug 2022 16:12:08 +0200 Subject: [PATCH 7/7] Round output data depending on the settings' approximation level --- src/output.jl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/output.jl b/src/output.jl index 7775049..a77688a 100644 --- a/src/output.jl +++ b/src/output.jl @@ -45,17 +45,17 @@ function createOutput(settings::Settings, drivingCourse::Vector{Dict}, pointsOfI end if settings.outputFormat == :dataframe - return createDataFrame(output, settings.outputDetail) + return createDataFrame(output, settings.outputDetail, settings.approxLevel) elseif settings.outputFormat == :vector return output end end -function createDataFrame(output_vector::Vector{Dict}, outputDetail) +function createDataFrame(output_vector::Vector{Dict}, outputDetail, approxLevel::Int) if outputDetail == :running_time # create a DataFrame with running time information - dataFrame = DataFrame(t=[output_vector[end][:t]]) + dataFrame = DataFrame(t=[round(output_vector[end][:t], digits=approxLevel)]) else # :points_of_interest, :data_points or :driving_course columnSymbols = [:label, :behavior, :s, :v, :t, :a, :F_T, :F_R, :R_path, :R_traction, :R_wagons] @@ -72,6 +72,7 @@ function createDataFrame(output_vector::Vector{Dict}, outputDetail) for point in output_vector push!(currentRealColumn, point[columnSymbols[column]]) end + currentRealColumn = round.(currentRealColumn, digits=approxLevel) push!(allColumns, currentRealColumn) end end # for