Change braking calculation from all in one step to multiple steps
parent
1a5cf9b822
commit
fd05d25910
|
@ -19,7 +19,7 @@ train:
|
|||
# for the traction unit (F_Rt=f_Rtd0*m_td*g+f_Rtc0*m_tc*g+F_Rt2*((v+Δv_t)/v00)^2)
|
||||
f_Rtd0: 3.0 # coefficient for basic resistance due to the traction units driving axles (in ‰) (source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 151 for "f_WL0" -> 2.5 ‰ to 3.5 ‰)
|
||||
f_Rtc0: 1.4 # coefficient for basic resistance due to the traction units carring axles (in ‰) (source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 151 for "f_WW0" -> 1.2 ‰ to 1.6 ‰)
|
||||
F_Rt2: 2600 # coefficient for air resistance of the traction units (in N) (source: the closest parameters are used: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 151 for "Fzg. vierachsig, abgerundeter Kopf" plus "Sektion bei Mehrteiligkeit" -> 2200 N to 400 N)
|
||||
F_Rt2: 2600 # coefficient for air resistance of the traction units (in N) (source: the closest parameters are used: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 151 for "Fzg. vierachsig, abgerundeter Kopf" plus "Sektion bei Mehrteiligkeit" -> 2200 N + 400 N)
|
||||
|
||||
# for the consist (set of wagons) (F_Rw=m_w*g*(f_Rw0+f_Rw1*v/v00+f_Rw2*((v+Δv_w)/v00)^2))
|
||||
f_Rw0: # coefficient for basic resistance of the set of wagons (in ‰) (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic -> no separate wagons)
|
||||
|
|
114
src/Behavior.jl
114
src/Behavior.jl
|
@ -104,7 +104,7 @@ function moveAStep(previousPoint::Dict, stepVariable::String, 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. =#
|
||||
|
||||
# creating the next data point
|
||||
# create the next data point
|
||||
newPoint = createDataPoint()
|
||||
newPoint[:i] = previousPoint[:i]+1 # identifier
|
||||
|
||||
|
@ -220,7 +220,7 @@ function getNextPointOfInterest(pointsOfInterest::Vector{Real}, s::Real)
|
|||
return POI
|
||||
end
|
||||
end
|
||||
error("ERROR in getNextPointOfInterest: There is no POI ist higher than s.")
|
||||
error("ERROR in getNextPointOfInterest: There is no POI higher than s.")
|
||||
end #function getNextPointOfInterest
|
||||
|
||||
## This function calculates the data points of the breakFree section.
|
||||
|
@ -393,7 +393,7 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
|
|||
else # if the level of approximation is reached
|
||||
if drivingCourse[end][:v] <= 0.0
|
||||
# push!(BS[:dataPoints], drivingCourse[end][:i])
|
||||
error("ERROR: The train stops during the acceleration section in CS",CS[:id]," because the tractive effort is lower than the resistant forces.",
|
||||
error("ERROR: The train stops during the acceleration section in CS",CS[:id]," between the positions ",drivingCourse[end-1][:s]," m and ",drivingCourse[end][:s]," m because the tractive effort is lower than the resistant forces.",
|
||||
" Before the stop the last point has the values s=",drivingCourse[end-1][:s]," m v=",drivingCourse[end-1][:v]," m/s a=",drivingCourse[end-1][:a]," m/s^2",
|
||||
" F_T=",drivingCourse[end-1][:F_T]," N R_traction=",drivingCourse[end-1][:R_traction]," N R_wagons=",drivingCourse[end-1][:R_wagons]," N R_path=",drivingCourse[end-1][:R_path]," N.")
|
||||
|
||||
|
@ -433,9 +433,9 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
|
|||
CS[:t] = CS[:t] + BS[:t] # total running time (in s)
|
||||
CS[:E] = CS[:E] + BS[:E] # total energy consumption (in Ws)
|
||||
|
||||
# TODO: this warning schould not be needed. just for testing
|
||||
if CS[:v_peak] < drivingCourse[end][:v]
|
||||
println("WARNING, v is getting to high at the end of the acceleration section. v=",drivingCourse[end][:v] ," > v_peak=",CS[:v_peak])
|
||||
println("WARNING: v is getting to high at the end of the acceleration section. v=",drivingCourse[end][:v] ," > v_peak=",CS[:v_peak])
|
||||
# TODO: this warning should not be needed. just for testing
|
||||
end
|
||||
|
||||
merge!(CS[:behaviorSections], Dict(:acceleration => BS))
|
||||
|
@ -899,7 +899,7 @@ function addCoastingSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict},
|
|||
# acceleration (in m/s^2):
|
||||
drivingCourse[end][:a] = calcAcceleration(drivingCourse[end][:F_T], drivingCourse[end][:F_R], train[:m_train], train[:ξ_train])
|
||||
|
||||
# creating the next data point
|
||||
# create the next data point
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
|
||||
drivingCourse[end][:behavior] = BS[:type]
|
||||
push!(BS[:dataPoints], drivingCourse[end][:i])
|
||||
|
@ -1003,7 +1003,8 @@ end #function addCoastingSectionUntilBraking!
|
|||
|
||||
## This function calculates the data points of the braking section. (standard braking section with only two data points)
|
||||
# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for braking if needed.
|
||||
function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}) #, s_braking::AbstractFloat)
|
||||
function addBrakingSectionInOneStep!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict})
|
||||
#function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict})
|
||||
# function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, massModel::String, train::Dict, CSs::Vector{Dict}) #, s_braking::AbstractFloat)
|
||||
if drivingCourse[end][:v] > CS[:v_exit] && drivingCourse[end][:s] < CS[:s_exit]
|
||||
BS = createBehaviorSection("braking", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
|
||||
|
@ -1018,7 +1019,7 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic
|
|||
# traction effort and resisting forces (in N)
|
||||
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
|
||||
drivingCourse[end][:a] = calcBrakingAcceleration(drivingCourse[end][:v], CS[:v_exit], BS[:s_exit]-drivingCourse[end][:s])
|
||||
# TODO: or just take train[:a_braking]? difference ist by 0.0000000001 m/s^2: drivingCourse[end][:a] = train[:a_braking]
|
||||
# TODO: or just take train[:a_braking]? difference is by 0.0000000001 m/s^2: drivingCourse[end][:a] = train[:a_braking]
|
||||
# println("a_braking till ",nextPointOfInterest,": ", calcBrakingAcceleration(drivingCourse[end][:v], CS[:v_exit], BS[:s_exit]-drivingCourse[end][:s]), ". It should be: ",train[:a_braking])
|
||||
|
||||
# calculate the braking distance to the next point of interest
|
||||
|
@ -1069,55 +1070,77 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic
|
|||
merge!(CS[:behaviorSections], Dict(:braking=>BS))
|
||||
end # else: return the characteristic section without a braking section
|
||||
return (CS, drivingCourse)
|
||||
end #function addBrakingSection!
|
||||
end #function addBrakingSectionInOneStep!
|
||||
|
||||
|
||||
## This function calculates the data points of the braking section. # 09/07 new braking section with more than two data points
|
||||
# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for braking if needed.
|
||||
function addBrakingSectionStepwise!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}) #, s_braking::AbstractFloat)
|
||||
#= TODO from 2022/01/22: integrate points of interest
|
||||
if drivingCourse[end][:v] > CS[:v_exit] && drivingCourse[end][:s] < CS[:s_exit]
|
||||
function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict})
|
||||
#function addBrakingSectionStepwise!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict})
|
||||
if settings[:stepVariable] != "s in m"
|
||||
error("addBrakingSectionStepwise! does not work with other step variables than 's in m' right now.")
|
||||
end
|
||||
# TODO: add for loop to realize calculations with step variables t and v
|
||||
|
||||
# conditions for braking section
|
||||
targetSpeedReached = drivingCourse[end][:v] <= CS[:v_exit]
|
||||
trainAtEnd = drivingCourse[end][:s] >= CS[:s_exit]
|
||||
|
||||
# use the conditions for the braking section
|
||||
if !targetSpeedReached && !trainAtEnd
|
||||
BS = createBehaviorSection("braking", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
|
||||
drivingCourse[end][:behavior] = BS[:type]
|
||||
|
||||
while !targetSpeedReached && !trainAtEnd
|
||||
currentStepSize = settings[:stepSize] # initialize the step size that can be reduced near intersections
|
||||
velocityIsPositive = true
|
||||
while drivingCourse[end][:v] > CS[:v_exit] && drivingCourse[end][:s] < CS[:s_exit] && velocityIsPositive
|
||||
nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])
|
||||
|
||||
while drivingCourse[end][:v] > CS[:v_exit] && !targetSpeedReached && drivingCourse[end][:s] < CS[:s_exit] && drivingCourse[end][:s] < nextPointOfInterest
|
||||
# traction effort and resisting forces (in N):
|
||||
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
|
||||
|
||||
# acceleration (in m/s^2):
|
||||
drivingCourse[end][:a] = train[:a_braking]
|
||||
# TODO or: drivingCourse[end][:a] = calcBrakingAcceleration(drivingCourse[end][:v], CS[:v_exit], CS[:s_exit]-drivingCourse[end][:s])
|
||||
|
||||
# creating the next data point
|
||||
|
||||
# create the next data point
|
||||
#TODO moveAStep should give back true or false for success or failure e.g. with dropping below v=0 m/s
|
||||
#at the moment it is only for stepVariable=="s in m"
|
||||
#at the moment it can only be used for stepVariable == "s in m"
|
||||
if settings[:stepVariable] == "s in m"
|
||||
if ((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
|
||||
velocityIsPositive=false
|
||||
targetSpeedReached = true
|
||||
|
||||
# create empty data point for setting the values after the while loop
|
||||
push!(drivingCourse, createDataPoint())
|
||||
drivingCourse[end][:i] = drivingCourse[end-1][:i]+1
|
||||
drivingCourse[end][:behavior] = BS[:type]
|
||||
push!(BS[:dataPoints], drivingCourse[end][:i])
|
||||
break
|
||||
end
|
||||
else
|
||||
error("Stepwise braking can currently be used with stepVariable=='s in m' only. Otherwise errors may not be detected.")
|
||||
end
|
||||
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
|
||||
drivingCourse[end][:behavior] = BS[:type]
|
||||
push!(BS[:dataPoints], drivingCourse[end][:i])
|
||||
|
||||
# s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
||||
end # while
|
||||
|
||||
if drivingCourse[end][:v] < CS[:v_exit] || !velocityIsPositive
|
||||
if drivingCourse[end][:v] < CS[:v_exit] || targetSpeedReached
|
||||
# reset last point with setting v=v_exit
|
||||
targetSpeedReached = true
|
||||
trainAtEnd = true
|
||||
|
||||
# calculate s, t, v
|
||||
drivingCourse[end][:s] = CS[:s_exit] # position (in m)
|
||||
drivingCourse[end][:v] = CS[:v_exit] # velocity (in m/s)
|
||||
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s] # step size (in m)
|
||||
drivingCourse[end][:Δv] = drivingCourse[end][:v] - drivingCourse[end-1][:v] # step size (in m/s)
|
||||
|
||||
#drivingCourse[end-1][:a]=round(calcBrakingAcceleration(drivingCourse[end-1][:v], drivingCourse[end][:v], drivingCourse[end][:Δs]), digits=approximationLevel) # acceleration (in m/s^2) (rounding because it should not be less than a_braking)
|
||||
drivingCourse[end-1][:a] = calcBrakingAcceleration(drivingCourse[end-1][:v], drivingCourse[end][:v], drivingCourse[end][:Δs])
|
||||
# if drivingCourse[end-1][:a]<train[:a_braking] || drivingCourse[end-1][:a]>=0.0
|
||||
# println("Warning: a_braking gets to high in CS ",CS[:id], " with a=",drivingCourse[end-1][:a] ," > ",train[:a_braking])
|
||||
# end
|
||||
if drivingCourse[end-1][:a]<train[:a_braking] || drivingCourse[end-1][:a]>=0.0
|
||||
println("Warning: a_braking gets to high in CS ",CS[:id], " with a=",drivingCourse[end-1][:a] ," > ",train[:a_braking])
|
||||
end
|
||||
drivingCourse[end][:Δt] = calc_Δt_with_Δv(drivingCourse[end][:Δv], drivingCourse[end-1][:a]) # step size (in s)
|
||||
drivingCourse[end][:t] = drivingCourse[end-1][:t] + drivingCourse[end][:Δt] # point in time (in s)
|
||||
|
||||
|
@ -1125,10 +1148,41 @@ function addBrakingSectionStepwise!(CS::Dict, drivingCourse::Vector{Dict}, setti
|
|||
drivingCourse[end][:W] = drivingCourse[end-1][:W] + drivingCourse[end][:ΔW] # mechanical work (in Ws)
|
||||
drivingCourse[end][:ΔE] = drivingCourse[end][:ΔW] # energy consumption in this step (in Ws)
|
||||
drivingCourse[end][:E] = drivingCourse[end-1][:E] + drivingCourse[end][:ΔE] # energy consumption (in Ws)
|
||||
elseif drivingCourse[end][:s] > CS[:s_exit]
|
||||
error("At the end of braking: s>s_exit but v>v_exit")
|
||||
else
|
||||
|
||||
|
||||
|
||||
elseif drivingCourse[end][:s] > CS[:s_exit]
|
||||
trainAtEnd = true
|
||||
error("At the end of braking: s>s_exit but v>v_exit")
|
||||
elseif drivingCourse[end][:s] > nextPointOfInterest
|
||||
# reset last point with lowering s to the nextPointOfInterest
|
||||
|
||||
# calculate s, t, v
|
||||
if settings[:stepVariable] == "s in m"
|
||||
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s] # step size (in m)
|
||||
else
|
||||
# TODO
|
||||
end
|
||||
pop!(drivingCourse)
|
||||
pop!(BS[:dataPoints])
|
||||
|
||||
# create the next data point
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
|
||||
drivingCourse[end][:behavior] = BS[:type]
|
||||
push!(BS[:dataPoints], drivingCourse[end][:i])
|
||||
|
||||
elseif drivingCourse[end][:v] == CS[:v_exit] && drivingCourse[end][:s] == CS[:s_exit]
|
||||
targetSpeedReached = true
|
||||
trainAtEnd = true
|
||||
elseif drivingCourse[end][:v] == CS[:v_exit]
|
||||
targetSpeedReached = true
|
||||
error("At the end of braking: s<s_exit but v=v_exit")
|
||||
elseif drivingCourse[end][:s] == CS[:s_exit]
|
||||
trainAtEnd = true
|
||||
error("At the end of braking: s=s_exit but v>v_exit")
|
||||
else
|
||||
# do nothing for example for drivingCourse[end][:s]==nextPointOfInterest
|
||||
end
|
||||
end
|
||||
|
||||
# calculate the accumulated coasting section information
|
||||
|
@ -1143,9 +1197,9 @@ function addBrakingSectionStepwise!(CS::Dict, drivingCourse::Vector{Dict}, setti
|
|||
|
||||
merge!(CS[:behaviorSections], Dict(:braking=>BS))
|
||||
end # else: return the characteristic section without a braking section
|
||||
=#
|
||||
|
||||
return (CS, drivingCourse)
|
||||
end #function addBrakingSectionStepwise!
|
||||
end #function addBrakingSection!
|
||||
|
||||
|
||||
## This function calculates the data point of the standstill.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# INFO: EnergySaving should not be used because it is not completed yet. It was used to show the possiility of calculating different operation modes.
|
||||
# INFO: EnergySaving should not be used because it is not completed yet. It was used to show the possibility of calculating different operation modes.
|
||||
# TODO: It has to be optimized so that each ernergy saving method is working individually for every train on every path.
|
||||
|
||||
# TODO: calculation time for passenger trains on path1 is very long and should be reduced
|
||||
|
|
|
@ -61,7 +61,7 @@ function checkAndSetTrain!(train::Dict)
|
|||
checkAndSetPositiveNumber!(train, "train", :f_Rw1, "‰", 0.0) # coefficient for the consists resistance to rolling (in ‰)
|
||||
checkAndSetPositiveNumber!(train, "train", :f_Rw2, "‰", 0.0) # coefficient fo the consistsr air resistance (in ‰)
|
||||
|
||||
# informAboutUnusedKeys(train, "train") # inform the user, which Symbols of the input dictionary are not used in this tool
|
||||
# TODO: informAboutUnusedKeys(train, "train") # inform the user, which Symbols of the input dictionary are not used in this tool
|
||||
|
||||
return train
|
||||
end #function checkAndSetTrain!
|
||||
|
@ -394,7 +394,7 @@ function checkAndSetSections!(path::Dict)
|
|||
|
||||
|
||||
if length(checkedSections)>1 && sections[section][:s_start] != checkedSections[end-1][:s_end]
|
||||
error("ERROR at checking the input dictionary for the path[:sections]: The starting position of the ",section,". section does not euqaul the last position of the previous section. The sections have to be sequential.")
|
||||
error("ERROR at checking the input dictionary for the path[:sections]: The starting position of the ",section,". section (s=",sections[section][:s_start]," m) does not euqal the last position of the previous section(s=",checkedSections[end-1][:s_end]," m). The sections have to be sequential.")
|
||||
# TODO: maybe if there is a gab create a new section and only if there a jumps in the wrong direction throw an error?
|
||||
end
|
||||
end #for
|
||||
|
|
|
@ -79,25 +79,26 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
|
|||
s_breakFree = get(BSs, :breakFree, Dict(:length=>0.0))[:length]
|
||||
s_clearing = get(BSs, :clearing, Dict(:length=>0.0))[:length]
|
||||
s_acceleration = get(BSs, :acceleration, Dict(:length=>0.0))[:length]
|
||||
s_braking = max(0.0, ceil((CS[:v_exit]^2-CS[:v_peak]^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
|
||||
s_braking = calcBrakingDistance(CS[:v_peak], CS[:v_exit], train[:a_braking])
|
||||
# old: s_braking = max(0.0, ceil((CS[:v_exit]^2-CS[:v_peak]^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
|
||||
|
||||
# calculate the cruising sections length
|
||||
s_cruising = CS[:length] - s_breakFree - s_clearing - s_acceleration - s_braking
|
||||
s_cruising = max(0.0, CS[:length] - s_breakFree - s_clearing - s_acceleration - s_braking)
|
||||
|
||||
# reset the characteristic section (CS), delete behavior sections (BS) that were used during the preperation for setting v_entry, v_peak and v_exit
|
||||
CS[:behaviorSections] = Dict()
|
||||
CS[:E] = 0.0
|
||||
CS[:t] = 0.0
|
||||
|
||||
|
||||
if s_clearing == CS[:length]
|
||||
# 09/06 TODO: thought about using "cruising" because it is used in EnergySaving and not clearing (CS, drivingCourse)=addCruisingSection!(CS, drivingCourse, s_clearing, settings, train, CSs, "cruising")
|
||||
# TODO 02/09: could there be a better structure for processing the different moving phases? (this if fork was added on 2022/09/02)
|
||||
if s_clearing > 0.0 && s_breakFree + s_acceleration == 0.0
|
||||
(CS, drivingCourse)=addCruisingSection!(CS, drivingCourse, s_clearing, settings, train, CSs, "clearing")
|
||||
elseif s_cruising == CS[:length]
|
||||
end
|
||||
|
||||
if s_cruising == CS[:length]
|
||||
(CS, drivingCourse)=addCruisingSection!(CS, drivingCourse, s_cruising, settings, train, CSs, "cruising")
|
||||
elseif s_cruising > 0.0 || s_braking == 0.0
|
||||
# 09/21 elseif s_cruising > 0.0
|
||||
# 09/21 elseif s_cruising > 0.01 # if the cruising section is longer than 1 cm (because of rounding issues not >0.0)
|
||||
|
||||
if drivingCourse[end][:v] < CS[:v_peak]
|
||||
(CS, drivingCourse) = addAccelerationSection!(CS, drivingCourse, settings, train, CSs)
|
||||
end #if
|
||||
|
@ -115,7 +116,6 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
|
|||
(CS, drivingCourse)=addCruisingSection!(CS, drivingCourse, s_cruising, settings, train, CSs, "cruising")
|
||||
end
|
||||
else
|
||||
|
||||
if CS[:v_entry] < CS[:v_peak] || s_acceleration > 0.0 # or instead of " || s_acceleration > 0.0" use "v_entry <= v_peak" or "v_i <= v_peak"
|
||||
# 09/09 old (not sufficient for steep gradients): if CS[:v_entry] < CS[:v_peak]
|
||||
(CS, drivingCourse)=addAccelerationSectionUntilBraking!(CS, drivingCourse, settings, train, CSs)
|
||||
|
|
Loading…
Reference in New Issue