Compare commits
5 Commits
01a3ccf672
...
70410e7985
Author | SHA1 | Date |
---|---|---|
Max Kannenberg | 70410e7985 | |
Max Kannenberg | 2f463a4a92 | |
Max Kannenberg | da1f641839 | |
Max Kannenberg | 5c5fa14f46 | |
github-actions[bot] | 71778ac715 |
|
@ -1,7 +1,7 @@
|
|||
name = "TrainRuns"
|
||||
uuid = "e4541106-d44c-4e00-b50b-ecdf479fcf92"
|
||||
authors = ["Max Kannenberg", "Martin Scheidt", "contributors"]
|
||||
version = "1.0.1"
|
||||
version = "1.0.2"
|
||||
|
||||
[deps]
|
||||
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
|
||||
|
|
280
src/behavior.jl
280
src/behavior.jl
|
@ -4,10 +4,29 @@
|
|||
# __copyright__ = "2020-2022"
|
||||
# __license__ = "ISC"
|
||||
|
||||
## 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
|
||||
"""
|
||||
addBreakFreeSection!(drivingCourse, stateFlags, CSs, csId, settings, train)
|
||||
|
||||
Calculate the support points of the breakFree section and add them to `drivingCourse`.
|
||||
|
||||
See also [`addClearingSection!`](@ref), [`addAcceleratingSection!`](@ref), [`addCruisingSection!`](@ref), [`addDiminishingSection!`](@ref), [`addCoastingSection!`](@ref), [`addBrakingSection!`](@ref), [`addHalt!`](@ref).
|
||||
|
||||
# Arguments
|
||||
- `drivingCourse::Vector{Dict}`: the Vector containing dictionaries for all support points.
|
||||
- `stateFlags::Dict`: the Dictionary containing different states for `drivingCourse`'s values.
|
||||
- `CSs::Vector{Dict}`: the Vector containing dictionaries for all characteristic sections.
|
||||
- `csId::Integer`: the number of characteristic section in the Vector `CSs`.
|
||||
- `settings::Settings`: the Settings object containing settings used for calculation.
|
||||
- `train::Train`: the Train object containing attributes with technical train data.
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> addBreakFreeSection(drivingCourse_with_starting_point, stateFlags, CSs, 1, settings_default, train_longdistance)
|
||||
(Dict[Dict{Symbol, Any}(:label => "", :behavior => "breakFree", :F_T => 300000, :R_wagons => 7309.09433933, :R_path => 0.0, :s => 0, :v => 0.0, :R_train => 9505.53877308, :R_traction => 2196.44443375, :a => 0.6143175668391081, :t => 0.0, :F_R => 9505.53877308), Dict{Symbol, Any}(:label => "", :behavior => "breakFree", :F_T => 300000.0, :R_wagons => 8848.180631278232, :R_path => 0.0, :s => 20, :v => 4.957086107136361, :R_train => 11471.657638238565, :R_traction => 2623.4770069603337, :a => 0.6101597548372565, :t => 8.069256643013498, :F_R => 11471.657638238565)], Dict{Symbol, Bool}(:previousSpeedLimitReached => 0, :speedLimitReached => 0, :brakingStartReached => 0, :resistingForceNegative => 0, :endOfCSReached => 0, :tractionDeficit => 0, :error => 0))
|
||||
```
|
||||
"""
|
||||
function addBreakFreeSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs::Vector{Dict}, csId::Integer, settings::Settings, train::Train)
|
||||
# INFO: currently the values of the breakFree section will be calculated like in the accelerating section
|
||||
CS = CSs[csId]
|
||||
|
||||
# conditions for the break free section
|
||||
|
@ -44,7 +63,7 @@ function addBreakFreeSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs
|
|||
|
||||
stateFlags[:endOfCSReached] = drivingCourse[end][:s] >= CS[:s_exit]
|
||||
stateFlags[:brakingStartReached] = drivingCourse[end][:s] +s_braking >= CS[:s_exit]
|
||||
stateFlags[:tractionDeficit] = drivingCourse[end][:F_T] < drivingCourse[end][:F_R] # or add another flag for equal forces?
|
||||
stateFlags[:tractionDeficit] = drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
|
||||
stateFlags[:resistingForceNegative] = drivingCourse[end][:F_R] < 0
|
||||
stateFlags[:previousSpeedLimitReached] = false
|
||||
stateFlags[:speedLimitReached] = drivingCourse[end][:v] >= CS[:v_limit]
|
||||
|
@ -53,8 +72,25 @@ function addBreakFreeSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs
|
|||
return (drivingCourse, stateFlags)
|
||||
end #function addBreakFreeSection!
|
||||
|
||||
## 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.
|
||||
|
||||
"""
|
||||
addClearingSection!(drivingCourse, stateFlags, CSs, csId, settings, train)
|
||||
|
||||
Calculate the support points of the clearing section and add them to `drivingCourse`.
|
||||
|
||||
See also [`addBreakFreeSection!`](@ref), [`addCruisingSection!`](@ref).
|
||||
|
||||
# Arguments
|
||||
- `drivingCourse::Vector{Dict}`: the Vector containing dictionaries for all support points.
|
||||
- `stateFlags::Dict`: the Dictionary containing different states for `drivingCourse`'s values.
|
||||
- `CSs::Vector{Dict}`: the Vector containing dictionaries for all characteristic sections.
|
||||
- `csId::Integer`: the number of characteristic section in the Vector `CSs`.
|
||||
- `settings::Settings`: the Settings object containing settings used for calculation.
|
||||
- `train::Train`: the Train object containing attributes with technical train data.
|
||||
|
||||
# Examples
|
||||
See [`addBreakFreeSection!`](@ref).
|
||||
"""
|
||||
function addClearingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs::Vector{Dict}, csId::Integer, settings::Settings, train::Train)
|
||||
CS = CSs[csId]
|
||||
|
||||
|
@ -79,8 +115,25 @@ function addClearingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs:
|
|||
return (drivingCourse, stateFlags)
|
||||
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
|
||||
|
||||
"""
|
||||
addAcceleratingSection!(drivingCourse, stateFlags, CSs, csId, settings, train)
|
||||
|
||||
Calculate the support points of the accelerating section and add them to `drivingCourse`.
|
||||
|
||||
See also [`addBreakFreeSection!`](@ref), [`addClearingSection!`](@ref), [`addCruisingSection!`](@ref), [`addDiminishingSection!`](@ref), [`addCoastingSection!`](@ref), [`addBrakingSection!`](@ref), [`addHalt!`](@ref).
|
||||
|
||||
# Arguments
|
||||
- `drivingCourse::Vector{Dict}`: the Vector containing dictionaries for all support points.
|
||||
- `stateFlags::Dict`: the Dictionary containing different states for `drivingCourse`'s values.
|
||||
- `CSs::Vector{Dict}`: the Vector containing dictionaries for all characteristic sections.
|
||||
- `csId::Integer`: the number of characteristic section in the Vector `CSs`.
|
||||
- `settings::Settings`: the Settings object containing settings used for calculation.
|
||||
- `train::Train`: the Train object containing attributes with technical train data.
|
||||
|
||||
# Examples
|
||||
See [`addBreakFreeSection!`](@ref).
|
||||
"""
|
||||
function addAcceleratingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs::Vector{Dict}, csId::Integer, settings::Settings, train::Train)
|
||||
CS = CSs[csId]
|
||||
|
||||
|
@ -133,10 +186,11 @@ function addAcceleratingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict,
|
|||
tractionSurplus = drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
|
||||
end #while
|
||||
|
||||
# for testing change the csId to the CS to be analysed
|
||||
if csId==0
|
||||
testFlag = true
|
||||
else
|
||||
testFlag = false # for testing
|
||||
testFlag = false
|
||||
end
|
||||
|
||||
# check which limit was reached and adjust the currentStepSize for the next cycle
|
||||
|
@ -243,7 +297,7 @@ function addAcceleratingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict,
|
|||
# set state flags
|
||||
stateFlags[:endOfCSReached] = endOfCSReached
|
||||
stateFlags[:brakingStartReached] = brakingStartReached
|
||||
stateFlags[:tractionDeficit] = !(tractionSurplus || drivingCourse[end][:F_T] == drivingCourse[end][:F_R]) # or add another flag for equal forces?
|
||||
stateFlags[:tractionDeficit] = !(tractionSurplus || drivingCourse[end][:F_T] == drivingCourse[end][:F_R])
|
||||
stateFlags[:resistingForceNegative] = drivingCourse[end][:F_R] < 0
|
||||
stateFlags[:previousSpeedLimitReached] = previousSpeedLimitReached
|
||||
stateFlags[:speedLimitReached] = speedLimitReached
|
||||
|
@ -253,8 +307,26 @@ function addAcceleratingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict,
|
|||
end #function addAcceleratingSection!
|
||||
|
||||
|
||||
## 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.
|
||||
"""
|
||||
addCruisingSection!(drivingCourse, stateFlags, CSs, csId, settings, train, cruisingType, s_cruising)
|
||||
|
||||
Calculate the support points of the cruising section and add them to `drivingCourse`.
|
||||
|
||||
See also [`addBreakFreeSection!`](@ref), [`addClearingSection!`](@ref), [`addAcceleratingSection!`](@ref), [`addDiminishingSection!`](@ref), [`addCoastingSection!`](@ref), [`addBrakingSection!`](@ref), [`addHalt!`](@ref).
|
||||
|
||||
# Arguments
|
||||
- `drivingCourse::Vector{Dict}`: the Vector containing dictionaries for all support points.
|
||||
- `stateFlags::Dict`: the Dictionary containing different states for `drivingCourse`'s values.
|
||||
- `CSs::Vector{Dict}`: the Vector containing dictionaries for all characteristic sections.
|
||||
- `csId::Integer`: the number of characteristic section in the Vector `CSs`.
|
||||
- `settings::Settings`: the Settings object containing settings used for calculation.
|
||||
- `train::Train`: the Train object containing attributes with technical train data.
|
||||
- `cruisingType::String`: the type of crusing respectively if applicable the reason why the train has to cruise
|
||||
- `s_cruising::Real`: the planned maximum crusing distance
|
||||
|
||||
# Examples
|
||||
See [`addBreakFreeSection!`](@ref).
|
||||
"""
|
||||
function addCruisingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs::Vector{Dict}, csId::Integer, settings::Settings, train::Train, cruisingType::String, s_cruising::Real)
|
||||
CS = CSs[csId]
|
||||
|
||||
|
@ -262,7 +334,7 @@ function addCruisingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs:
|
|||
trainIsBrakingDownhill = cruisingType == "downhillBraking"
|
||||
|
||||
# traction effort and resisting forces (in N)
|
||||
if !trainIsBrakingDownhill # TODO: or just give drivingMode instead of "cruising"/"braking"?
|
||||
if !trainIsBrakingDownhill
|
||||
calculateForces!(drivingCourse[end], CSs, csId, "cruising", train, settings.massModel)
|
||||
else
|
||||
calculateForces!(drivingCourse[end], CSs, csId, "braking", train, settings.massModel)
|
||||
|
@ -271,7 +343,6 @@ function addCruisingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs:
|
|||
s_braking = brakingDistance(drivingCourse[end][:v], CS[:v_exit], train.a_braking, settings.approxLevel)
|
||||
|
||||
# conditions for cruising section
|
||||
#s_braking = brakingDistance(drivingCourse[end][:v], CS[:v_exit], train.a_braking, settings.approxLevel)
|
||||
brakingStartReached = drivingCourse[end][:s] + s_braking >= CS[:s_exit] || stateFlags[:brakingStartReached]
|
||||
speedIsValid = drivingCourse[end][:v] > 0.0 && drivingCourse[end][:v] <= CS[:v_limit]
|
||||
tractionDeficit = drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
|
||||
|
@ -281,9 +352,7 @@ function addCruisingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs:
|
|||
if speedIsValid && !brakingStartReached && !tractionDeficit && !targetPositionReached
|
||||
drivingMode = cruisingType
|
||||
drivingCourse[end][:behavior] = drivingMode
|
||||
# TODO: necessary?
|
||||
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)
|
||||
if !trainIsBrakingDownhill
|
||||
|
@ -297,7 +366,6 @@ function addCruisingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs:
|
|||
trainInPreviousCS = drivingCourse[end][:s] < CS[:s_entry] + train.length
|
||||
targetPositionReached = drivingCourse[end][:s] >= targetPosition
|
||||
resistingForceNegative = drivingCourse[end][:F_R] < 0.0
|
||||
# TODO: change? to: correctCruisingType = (trainIsClearing || (trainIsBrakingDownhill == drivingCourse[end][:F_R] < 0)) # while clearing tractive or braking force can be used
|
||||
|
||||
# use the conditions for the cruising section
|
||||
while trainInPreviousCS && !targetPositionReached && !tractionDeficit && (trainIsClearing || (trainIsBrakingDownhill == resistingForceNegative)) # while clearing tractive or braking force can be used
|
||||
|
@ -307,8 +375,6 @@ function addCruisingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs:
|
|||
|
||||
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
|
||||
# the tractive effort is lower than the resisting forces and the train has to use the highest possible effort to try to stay at v_limit 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):
|
||||
if !trainIsBrakingDownhill
|
||||
drivingCourse[end][:F_T] = min(drivingCourse[end][:F_T], max(0.0, drivingCourse[end][:F_R]))
|
||||
|
@ -316,7 +382,6 @@ function addCruisingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs:
|
|||
drivingCourse[end][:F_T] = 0.0
|
||||
end
|
||||
|
||||
|
||||
# acceleration (in m/s^2):
|
||||
drivingCourse[end][:a] = 0.0
|
||||
|
||||
|
@ -324,7 +389,7 @@ function addCruisingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs:
|
|||
if settings.stepVariable == :distance || settings.stepVariable == :time
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings.stepVariable, currentStepSize, csId))
|
||||
else
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings.stepVariable, train.length/(10.0^cycle), csId)) # TODO which step size should be used?
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings.stepVariable, train.length/(10.0^cycle), csId))
|
||||
end
|
||||
drivingCourse[end][:behavior] = drivingMode
|
||||
|
||||
|
@ -357,14 +422,14 @@ function addCruisingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs:
|
|||
currentStepSize = settings.stepSize / 10.0^cycle
|
||||
end
|
||||
|
||||
elseif drivingCourse[end][:s] > targetPosition # TODO also the following? drivingCourse[end][:s] > CS[:s_entry] + train.length))
|
||||
elseif drivingCourse[end][:s] > targetPosition
|
||||
if settings.stepVariable == :distance
|
||||
currentStepSize = targetPosition - drivingCourse[end-1][:s]
|
||||
else
|
||||
currentStepSize = settings.stepSize / 10.0^cycle
|
||||
end
|
||||
|
||||
elseif drivingCourse[end][:s] == targetPosition # || drivingCourse[end][:s]==CS[:s_exit]
|
||||
elseif drivingCourse[end][:s] == targetPosition
|
||||
break
|
||||
|
||||
elseif drivingCourse[end][:s] >= CS[:s_entry] + train.length
|
||||
|
@ -429,7 +494,7 @@ function addCruisingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs:
|
|||
while !targetPositionReached && !tractionDeficit && (trainIsClearing || (trainIsBrakingDownhill == resistingForceNegative)) # while clearing tractive or braking force can be used
|
||||
nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])
|
||||
if nextPointOfInterest[:s] > targetPosition
|
||||
nextPointOfInterest = (s = targetPosition, label = "") #[targetPosition, ""]
|
||||
nextPointOfInterest = (s = targetPosition, label = "")
|
||||
end
|
||||
|
||||
# tractive effort (in N):
|
||||
|
@ -444,7 +509,6 @@ function addCruisingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs:
|
|||
drivingCourse[end][:a] = 0.0 # acceleration (in m/s^2)
|
||||
|
||||
# calculate the remaining cruising way
|
||||
#s_cruisingRemaining=targetPosition-drivingCourse[end][:s]
|
||||
s_cruisingRemaining = min(nextPointOfInterest[:s] -drivingCourse[end][:s], targetPosition -drivingCourse[end][:s])
|
||||
|
||||
# create the next support point
|
||||
|
@ -479,7 +543,24 @@ function addCruisingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs:
|
|||
end #function addCruisingSection!
|
||||
|
||||
|
||||
## This function calculates the support points for diminishing run when using maximum tractive effort and still getting slower
|
||||
"""
|
||||
addDiminishingSection!(drivingCourse, stateFlags, CSs, csId, settings, train)
|
||||
|
||||
Calculate the support points of the diminishing section (when using maximum tractive effort and still getting slower) and add them to `drivingCourse`.
|
||||
|
||||
See also [`addBreakFreeSection!`](@ref), [`addClearingSection!`](@ref), [`addAcceleratingSection!`](@ref), [`addCruisingSection!`](@ref), [`addCoastingSection!`](@ref), [`addBrakingSection!`](@ref), [`addHalt!`](@ref).
|
||||
|
||||
# Arguments
|
||||
- `drivingCourse::Vector{Dict}`: the Vector containing dictionaries for all support points.
|
||||
- `stateFlags::Dict`: the Dictionary containing different states for `drivingCourse`'s values.
|
||||
- `CSs::Vector{Dict}`: the Vector containing dictionaries for all characteristic sections.
|
||||
- `csId::Integer`: the number of characteristic section in the Vector `CSs`.
|
||||
- `settings::Settings`: the Settings object containing settings used for calculation.
|
||||
- `train::Train`: the Train object containing attributes with technical train data.
|
||||
|
||||
# Examples
|
||||
See [`addBreakFreeSection!`](@ref).
|
||||
"""
|
||||
function addDiminishingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs::Vector{Dict}, csId::Integer, settings::Settings, train::Train)
|
||||
CS = CSs[csId]
|
||||
|
||||
|
@ -633,8 +714,24 @@ function addDiminishingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, C
|
|||
end #function addDiminishingSection!
|
||||
|
||||
|
||||
## 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
|
||||
"""
|
||||
addCoastingSection!(drivingCourse, stateFlags, CSs, csId, settings, train)
|
||||
|
||||
Calculate the support points of the coasting section and add them to `drivingCourse`.
|
||||
|
||||
See also [`addBreakFreeSection!`](@ref), [`addClearingSection!`](@ref), [`addAcceleratingSection!`](@ref), [`addCruisingSection!`](@ref), [`addDiminishingSection!`](@ref), [`addBrakingSection!`](@ref), [`addHalt!`](@ref).
|
||||
|
||||
# Arguments
|
||||
- `drivingCourse::Vector{Dict}`: the Vector containing dictionaries for all support points.
|
||||
- `stateFlags::Dict`: the Dictionary containing different states for `drivingCourse`'s values.
|
||||
- `CSs::Vector{Dict}`: the Vector containing dictionaries for all characteristic sections.
|
||||
- `csId::Integer`: the number of characteristic section in the Vector `CSs`.
|
||||
- `settings::Settings`: the Settings object containing settings used for calculation.
|
||||
- `train::Train`: the Train object containing attributes with technical train data.
|
||||
|
||||
# Examples
|
||||
See [`addBreakFreeSection!`](@ref).
|
||||
"""
|
||||
function addCoastingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs::Vector{Dict}, csId::Integer, settings::Settings, train::Train)
|
||||
CS = CSs[csId]
|
||||
|
||||
|
@ -698,7 +795,7 @@ function addCoastingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs:
|
|||
currentStepSize = settings.stepSize / 10.0^cycle
|
||||
end
|
||||
|
||||
elseif drivingCourse[end][:v] < CS[:v_exit] # TODO: if accelereation and coasting functions will be combined this case is only for coasting
|
||||
elseif drivingCourse[end][:v] < CS[:v_exit]
|
||||
testFlag && println("in CS",csId," coasting cycle",cycle," case: v=", drivingCourse[end][:v]," < v_exit=", CS[:v_exit]) # for testing
|
||||
if settings.stepVariable == :velocity
|
||||
currentStepSize = drivingCourse[end-1][:v] - CS[:v_exit]
|
||||
|
@ -727,8 +824,7 @@ function addCoastingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs:
|
|||
break
|
||||
|
||||
else
|
||||
# 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<v_limit and s+s_braking<s_exit in CS",csId," with s=" ,drivingCourse[end][:s]," m and v=",drivingCourse[end][:v]," m/s")
|
||||
|
||||
end
|
||||
# delete last support point for recalculating the last step with reduced step size
|
||||
pop!(drivingCourse)
|
||||
|
@ -796,8 +892,24 @@ function addCoastingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs:
|
|||
end #function addCoastingSection!
|
||||
|
||||
|
||||
## 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.
|
||||
"""
|
||||
addBrakingSection!(drivingCourse, stateFlags, CSs, csId, settings, train)
|
||||
|
||||
Calculate the support points of the braking section and add them to `drivingCourse`.
|
||||
|
||||
See also [`addBreakFreeSection!`](@ref), [`addClearingSection!`](@ref), [`addAcceleratingSection!`](@ref), [`addCruisingSection!`](@ref), [`addDiminishingSection!`](@ref), [`addCoastingSection!`](@ref), [`addHalt!`](@ref).
|
||||
|
||||
# Arguments
|
||||
- `drivingCourse::Vector{Dict}`: the Vector containing dictionaries for all support points.
|
||||
- `stateFlags::Dict`: the Dictionary containing different states for `drivingCourse`'s values.
|
||||
- `CSs::Vector{Dict}`: the Vector containing dictionaries for all characteristic sections.
|
||||
- `csId::Integer`: the number of characteristic section in the Vector `CSs`.
|
||||
- `settings::Settings`: the Settings object containing settings used for calculation.
|
||||
- `train::Train`: the Train object containing attributes with technical train data.
|
||||
|
||||
# Examples
|
||||
See [`addBreakFreeSection!`](@ref).
|
||||
"""
|
||||
function addBrakingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs::Vector{Dict}, csId::Integer, settings::Settings, train::Train)
|
||||
CS = CSs[csId]
|
||||
|
||||
|
@ -822,13 +934,14 @@ function addBrakingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs::
|
|||
|
||||
# acceleration (in m/s^2):
|
||||
drivingCourse[end][:a] = train.a_braking
|
||||
# TODO or: drivingCourse[end][:a] = brakingAcceleration(drivingCourse[end][:v], CS[:v_exit], CS[:s_exit]-drivingCourse[end][:s])
|
||||
|
||||
# Check if the train stops during this braking step. Therefore check if parts of square roots in moveAStep will be <0.0.
|
||||
# If it ist the case calculate the exact braking acceleration for the fix end position and velocity.
|
||||
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 support point and set it for the values of s_exit and v_exit
|
||||
push!(drivingCourse, SupportPoint())
|
||||
drivingCourse[end][:behavior] = drivingMode
|
||||
recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
||||
drivingCourse = recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
||||
else
|
||||
# create the next support point
|
||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings.stepVariable, currentStepSize, csId))
|
||||
|
@ -842,7 +955,6 @@ function addBrakingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs::
|
|||
end # while
|
||||
|
||||
# check which limit was reached and adjust the currentStepSize for the next cycle
|
||||
# TODO: is there a better way than rounding like in the following?
|
||||
if cycle < settings.approxLevel+1
|
||||
if drivingCourse[end][:v] < CS[:v_exit]
|
||||
if settings.stepVariable == :velocity
|
||||
|
@ -862,12 +974,12 @@ function addBrakingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs::
|
|||
break
|
||||
|
||||
elseif drivingCourse[end][:v] == CS[:v_exit]
|
||||
recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
||||
drivingCourse = recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
||||
endOfCSReached = true
|
||||
break
|
||||
|
||||
elseif drivingCourse[end][:s] == CS[:s_exit]
|
||||
recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
||||
drivingCourse = recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
||||
targetSpeedReached = true
|
||||
break
|
||||
|
||||
|
@ -885,15 +997,12 @@ function addBrakingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs::
|
|||
|
||||
else # if the level of approximation is reached
|
||||
if drivingCourse[end][:v] < 0.0
|
||||
# TODO: drivingCourse[end][:v] < CS[:v_exit] should be enough
|
||||
# reset last point with setting v=v_exit. still possible with v_exit now meaning v_exitMax?
|
||||
# println("during braking section in CS",csId,": rounding v up from ", drivingCourse[end][:v] ," to ", CS[:v_exit]) # for testing
|
||||
recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], 0.0)
|
||||
# println("during braking section in CS",csId,": rounding v up from ", drivingCourse[end][:v] ," to ", CS[:v_exit]) # for testing
|
||||
drivingCourse = recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], 0.0)
|
||||
endOfCSReached = true
|
||||
break
|
||||
elseif drivingCourse[end][:s] > CS[:s_exit]
|
||||
# println("during braking section in CS",csId,": rounding s down from ", drivingCourse[end][:s] ," to ", CS[:s_exit]) # for testing
|
||||
# recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
||||
# println("during braking section in CS",csId,": rounding s down from ", drivingCourse[end][:s] ," to ", CS[:s_exit]) # for testing
|
||||
drivingCourse[end][:s] = CS[:s_exit]
|
||||
break
|
||||
elseif drivingCourse[end][:s] > nextPointOfInterest[:s]
|
||||
|
@ -903,18 +1012,18 @@ function addBrakingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs::
|
|||
break
|
||||
elseif drivingCourse[end][:v] < CS[:v_exit]
|
||||
# reset last point with setting v=v_exit
|
||||
# println("during braking section in CS",csId,": rounding s up from ", drivingCourse[end][:s] ," to ", CS[:s_exit]) # for testing
|
||||
recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
||||
# println("during braking section in CS",csId,": rounding s up from ", drivingCourse[end][:s] ," to ", CS[:s_exit]) # for testing
|
||||
drivingCourse = recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
||||
endOfCSReached = true
|
||||
break
|
||||
elseif drivingCourse[end][:v] == CS[:v_exit]
|
||||
# println("during braking section in CS",csId,": rounding s up from ", drivingCourse[end][:s] ," to ", CS[:s_exit]) # for testing
|
||||
recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
||||
# println("during braking section in CS",csId,": rounding s up from ", drivingCourse[end][:s] ," to ", CS[:s_exit]) # for testing
|
||||
drivingCourse = recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
||||
endOfCSReached = true
|
||||
break
|
||||
elseif drivingCourse[end][:s] == CS[:s_exit]
|
||||
# println("during braking section in CS",csId,": rounding v down from ", drivingCourse[end][:v] ," to ", CS[:v_exit]) # for testing
|
||||
recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
||||
# println("during braking section in CS",csId,": rounding v down from ", drivingCourse[end][:v] ," to ", CS[:v_exit]) # for testing
|
||||
drivingCourse = recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
||||
targetSpeedReached = true
|
||||
break
|
||||
else
|
||||
|
@ -943,10 +1052,25 @@ function addBrakingSection!(drivingCourse::Vector{Dict}, stateFlags::Dict, CSs::
|
|||
end #function addBrakingSection!
|
||||
|
||||
|
||||
## 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.
|
||||
"""
|
||||
addHalt!(drivingCourse, stateFlags, CSs, csId, settings, train)
|
||||
|
||||
Calculate the support points of the halt section and add them to `drivingCourse`.
|
||||
|
||||
See also [`addBreakFreeSection!`](@ref), [`addClearingSection!`](@ref), [`addAcceleratingSection!`](@ref), [`addCruisingSection!`](@ref), [`addDiminishingSection!`](@ref), [`addCoastingSection!`](@ref), [`addBrakingSection!`](@ref).
|
||||
|
||||
# Arguments
|
||||
- `drivingCourse::Vector{Dict}`: the Vector containing dictionaries for all support points.
|
||||
- `stateFlags::Dict`: the Dictionary containing different states for `drivingCourse`'s values.
|
||||
- `CSs::Vector{Dict}`: the Vector containing dictionaries for all characteristic sections.
|
||||
- `csId::Integer`: the number of characteristic section in the Vector `CSs`.
|
||||
- `settings::Settings`: the Settings object containing settings used for calculation.
|
||||
- `train::Train`: the Train object containing attributes with technical train data.
|
||||
|
||||
# Examples
|
||||
See [`addBreakFreeSection!`](@ref).
|
||||
"""
|
||||
function addHalt!(drivingCourse::Vector{Dict}, CSs::Vector{Dict}, csId::Integer, settings::Settings, train::Train)
|
||||
# CS = CSs[csId] # is not needed here
|
||||
if drivingCourse[end][:v] == 0.0
|
||||
drivingMode = "halt"
|
||||
drivingCourse[end][:behavior] = drivingMode
|
||||
|
@ -957,23 +1081,55 @@ function addHalt!(drivingCourse::Vector{Dict}, CSs::Vector{Dict}, csId::Integer,
|
|||
return drivingCourse
|
||||
end #function addHalt!
|
||||
|
||||
function recalculateLastBrakingPoint!(drivingCourse, s_target, v_target)
|
||||
|
||||
"""
|
||||
recalculateLastBrakingPoint!(drivingCourse, s_target, v_target)
|
||||
|
||||
Realculate the last step of the `drivingCourse` depending on new position and velocity.
|
||||
|
||||
# Arguments
|
||||
- `drivingCourse::Vector{Dict}`: the Vector containing dictionaries for all support points.
|
||||
- `s_target::Real`: the new positon for the last support point in m.
|
||||
- `v_target::Real`: the new velocity for the last support point in m/s.
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> recalculateLastBrakingPoint(drivingCourse_with_two_points_near_5000m, 5000.0, 23.333333333333332)
|
||||
Dict{Symbol, Any}[Dict(:label => "", :behavior => "braking", :F_T => 0.0, :R_wagons => 21655.0, :R_path => 0.0, :s => 4999.999980000006, :v => 23.333333441372545, :R_train => 28640.8, :R_traction => 6985.8, :a => -0.126, :t => 235.16501930395856, :F_R => 28640.8), Dict(:label => "", :behavior => "braking", :F_T => 0.0, :R_wagons => 0.0, :R_path => 0.0, :s => 5000.0, :v => 23.333333333333332, :R_train => 0.0, :R_traction => 0.0, :a => 0.0, :t => 235.16502016110115, :F_R => 0.0)]
|
||||
```
|
||||
"""
|
||||
function recalculateLastBrakingPoint!(drivingCourse::Vector{Dict}, s_target::Real, v_target::Real)
|
||||
currentPoint = drivingCourse[end]
|
||||
previousPoint = drivingCourse[end-1]
|
||||
|
||||
# set s and v
|
||||
currentPoint[:s] = s_target # position (in m)
|
||||
currentPoint[:v] = v_target # velocity (in m/s)
|
||||
|
||||
# calculate other values
|
||||
previousPoint[:a] = brakingAcceleration(previousPoint[:v], currentPoint[:v], currentPoint[:s]-previousPoint[:s])
|
||||
# # TODO: just for testing
|
||||
# if previousPoint[:a]<train.a_braking || previousPoint[:a]>=0.0
|
||||
# println("Warning: a_braking gets to high in CS ",csId, " with a=",previousPoint[:a] ," > ",train.a_braking)
|
||||
# end
|
||||
currentPoint[:t] = previousPoint[:t] + Δt_with_Δv(currentPoint[:v]-previousPoint[:v], previousPoint[:a]) # point in time (in s)
|
||||
# calculate other values
|
||||
previousPoint[:a] = brakingAcceleration(previousPoint[:v], currentPoint[:v], currentPoint[:s]-previousPoint[:s])
|
||||
currentPoint[:t] = previousPoint[:t] + Δt_with_Δv(currentPoint[:v]-previousPoint[:v], previousPoint[:a]) # point in time (in s)
|
||||
|
||||
return drivingCourse
|
||||
end #function recalculateLastBrakingPoint
|
||||
|
||||
## define the intersection velocities between the characterisitc sections to secure braking behavior
|
||||
|
||||
"""
|
||||
secureBrakingBehavior!(CSs, a_braking, approxLevel)
|
||||
|
||||
Calculate the velocities between the characterisitc sections to secure braking behavior.
|
||||
|
||||
# Arguments
|
||||
- `CSs::Vector{Dict}`: the Vector containing dictionaries for all characteristic sections.
|
||||
- `a_braking::Real`: the constant braking acceleration in m/s^2.
|
||||
- `approxLevel::Integer`: the last position behind the decimal point that is not rounded.
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> secureBrakingBehavior!(CSs, -0.375, 3)
|
||||
Dict[Dict{Symbol, Any}(:s_entry => 0.0, :v_exit => 19.3649, :v_limit => 25.0, :r_path => 0.0, :pointsOfInterest => NamedTuple[(s = 9500.0, label = "")], :s_exit => 9500.0), Dict{Symbol, Any}(:s_entry => 0.0, :v_exit => 0.0, :v_limit => 25.0, :r_path => 1.0, :pointsOfInterest => NamedTuple[(s = 10000.0, label = "")], :s_exit => 10000.0)]
|
||||
```
|
||||
"""
|
||||
function secureBrakingBehavior!(CSs::Vector{Dict}, a_braking::Real, approxLevel::Integer)
|
||||
# limit the entry and exit velocities of the characteristic sections to secure that the train stops at the moving sections end
|
||||
|
||||
|
|
23
src/calc.jl
23
src/calc.jl
|
@ -322,8 +322,25 @@ function determineCharacteristics(path::Path, train::Train, settings::Settings)
|
|||
sort!(pointsOfInterest, by = x -> x[:s])
|
||||
end
|
||||
|
||||
characteristicSections = CharacteristicSections(path, train.v_limit, train.length, pointsOfInterest)
|
||||
characteristicSections = secureBrakingBehavior!(characteristicSections, train.a_braking, settings.approxLevel)
|
||||
# create the characteristic sections of a moving section 'CSs' dependent on the paths attributes
|
||||
CSs = Vector{Dict}()
|
||||
s_csStart = path.sections[1][:s_start] # first position (in m)
|
||||
|
||||
return (characteristicSections, pointsOfInterest)
|
||||
for row in 2:length(path.sections)
|
||||
previousSection = path.sections[row-1]
|
||||
currentSection = path.sections[row]
|
||||
|
||||
speedLimitIsDifferent = min(previousSection[:v_limit], train.v_limit) != min(currentSection[:v_limit], train.v_limit)
|
||||
pathResistanceIsDifferent = previousSection[:f_Rp] != currentSection[:f_Rp]
|
||||
if speedLimitIsDifferent || pathResistanceIsDifferent
|
||||
push!(CSs, CharacteristicSection(s_csStart, previousSection, min(previousSection[:v_limit], train.v_limit), train.length, pointsOfInterest))
|
||||
s_csStart = currentSection[:s_start]
|
||||
end #if
|
||||
end #for
|
||||
push!(CSs, CharacteristicSection(s_csStart, path.sections[end], min(path.sections[end][:v_limit], train.v_limit), train.length, pointsOfInterest))
|
||||
|
||||
# secure that the train is able to brake sufficiently and keeps speed limits
|
||||
CSs = secureBrakingBehavior!(CSs, train.a_braking, settings.approxLevel)
|
||||
|
||||
return (CSs, pointsOfInterest)
|
||||
end #function determineCharacteristics
|
||||
|
|
|
@ -613,28 +613,6 @@ function Train(file, type = :YAML)
|
|||
|
||||
end #function Train() # outer constructor
|
||||
|
||||
## create the moving section's characteristic sections
|
||||
function CharacteristicSections(path::Path, v_trainLimit::Real, s_trainLength::Real, MS_poi::Vector{NamedTuple})
|
||||
# create and return the characteristic sections of a moving section dependent on the paths attributes
|
||||
|
||||
CSs = Vector{Dict}()
|
||||
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(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(s_csStart, path.sections[end], min(path.sections[end][:v_limit], v_trainLimit), s_trainLength, MS_poi))
|
||||
|
||||
return CSs
|
||||
end #function CharacteristicSections
|
||||
|
||||
## create a characteristic section for a path section.
|
||||
function CharacteristicSection(s_entry::Real, section::Dict, v_limit::Real, s_trainLength::Real, MS_poi::Vector{NamedTuple})
|
||||
|
|
294
src/formulary.jl
294
src/formulary.jl
|
@ -27,27 +27,23 @@
|
|||
## }
|
||||
#########################
|
||||
|
||||
#approxLevel = 6
|
||||
v00 = 100/3.6 # velocity factor (in m/s)
|
||||
|
||||
## calculate forces
|
||||
## calculate forces:
|
||||
|
||||
#TODO: replace the ? ? ?
|
||||
"""
|
||||
tractionUnitResistance(v, train)
|
||||
|
||||
Calculate the vehicle resistance for the traction unit of the `train` dependend on the velocity `v`.
|
||||
Calculate the vehicle resistance in N for the traction unit of the `train` dependend on the velocity `v`.
|
||||
|
||||
...
|
||||
# Arguments
|
||||
- `v::AbstractFloat`: the current velocity in m/s.
|
||||
- `train::Train`: ? ? ?
|
||||
...
|
||||
- `train::Train`: the struct defined in types.jl containing attributes with technical data.
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> tractionUnitResistance(30.0, ? ? ?)
|
||||
? ? ?
|
||||
julia> tractionUnitResistance(15.0, freight_train)
|
||||
5461.127252
|
||||
```
|
||||
"""
|
||||
function tractionUnitResistance(v::AbstractFloat, train::Train)
|
||||
|
@ -58,32 +54,52 @@ function tractionUnitResistance(v::AbstractFloat, train::Train)
|
|||
m_td = train.m_td # mass on the traction unit's driving axles (in kg)
|
||||
m_tc = train.m_tc # mass on the traction unit's carrying axles (in kg)
|
||||
|
||||
|
||||
F_R_tractionUnit = f_Rtd0/1000 * m_td * g + f_Rtc0/1000 * m_tc * g + f_Rt2/1000 * (m_td+m_tc) * g * ((v + Δv_air) /v00)^2 # vehicle resistance of the traction unit (in N) # /1000 because of the unit ‰
|
||||
# TODO: use forceFromCoefficient? F_R_tractionUnit = forceFromCoefficient(f_Rtd0, m_td) + forceFromCoefficient(f_Rtc0, m_tc) + forceFromCoefficient(f_Rt2, m_td+m_tc) * ((v + Δv_air) /v00)^2 # vehicle resistance of the traction unit (in N)
|
||||
|
||||
return F_R_tractionUnit
|
||||
#TODO: same variable name like in the rest of TrainRuns? return R_traction
|
||||
end #function tractionUnitResistance
|
||||
|
||||
|
||||
"""
|
||||
TODO
|
||||
calculate and return the freight wagons' vehicle resistance dependend on the velocity
|
||||
freightWagonsResistance(v, train)
|
||||
|
||||
Calculate the vehicle resistance in N for the freight wagons of the `train` dependend on the velocity `v`.
|
||||
|
||||
# Arguments
|
||||
- `v::AbstractFloat`: the current velocity in m/s.
|
||||
- `train::Train`: the struct defined in types.jl containing attributes with technical data.
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> freightWagonsResistance(15.0, freight_train)
|
||||
20900.732702639998
|
||||
```
|
||||
"""
|
||||
function freightWagonsResistance(v::AbstractFloat, train::Train)
|
||||
# equation is based on a combination of the equations of Strahl and Sauthoff [Wende:2003, page 153]
|
||||
# equation is based on the equation of Strahl [Wende:2003, page 153]
|
||||
f_Rw0 = train.f_Rw0 # coefficient for basic resistance of the set of wagons (consist) (in ‰)
|
||||
f_Rw2 = train.f_Rw2 # coefficient fo the consistsr air resistance (in ‰)
|
||||
m_w = train.m_w # mass of the set of wagons (consist) (in kg)
|
||||
|
||||
F_R_wagons = m_w *g *(f_Rw0/1000 + f_Rw2/1000 * (v /v00)^2) # vehicle resistance of freight wagons (in N) with Strahl # /1000 because of the unit ‰
|
||||
|
||||
# TODO: use forceFromCoefficient? F_R_wagons = forceFromCoefficient(f_Rw0, m_w) + ...
|
||||
return F_R_wagons
|
||||
end #function calcWagonsResistance
|
||||
|
||||
|
||||
"""
|
||||
TODO
|
||||
calculate and return the passenger wagons' vehicle resistance dependend on the velocity
|
||||
passengerWagonsResistance(v, train)
|
||||
|
||||
Calculate the vehicle resistance in N for the passenger wagons of the `train` dependend on the velocity `v`.
|
||||
|
||||
# Arguments
|
||||
- `v::AbstractFloat`: the current velocity in m/s.
|
||||
- `train::Train`: the struct defined in types.jl containing attributes with technical data.
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> passengerWagonsResistance(15.0, longdistance_passenger_train)
|
||||
14461.2708244928
|
||||
```
|
||||
"""
|
||||
function passengerWagonsResistance(v::AbstractFloat, train::Train)
|
||||
# equation is based on the equations of Sauthoff [Wende:2003, page 153]
|
||||
|
@ -94,129 +110,277 @@ function passengerWagonsResistance(v::AbstractFloat, train::Train)
|
|||
|
||||
F_R_wagons = m_w *g *(f_Rw0/1000 + f_Rw1/1000 *v /v00 + f_Rw2/1000 * ((v + Δv_air) /v00)^2) # vehicle resistance of passenger wagons (in N) with Sauthoff # /1000 because of the unit ‰
|
||||
|
||||
# TODO: use forceFromCoefficient? F_R_wagons = forceFromCoefficient(f_Rw0, m_w) + ...
|
||||
return F_R_wagons
|
||||
end #function calcWagonsResistance
|
||||
|
||||
function forceFromCoefficient(f_R::Real, m::Real)
|
||||
"""
|
||||
forceFromCoefficient(f, m)
|
||||
|
||||
Calculate the force in N with the coefficient `f` in ‰ and the vehicle's mass `m` in kg.
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> forceFromCoefficient(1.5, 68000.0)
|
||||
1000.2783
|
||||
```
|
||||
"""
|
||||
function forceFromCoefficient(f::Real, m::Real)
|
||||
# equation is based on [Wende:2003, page 8]
|
||||
|
||||
# f_R: specific resistance (in ‰)
|
||||
# m: vehicle's mass (in kg)
|
||||
|
||||
F_R = f_R /1000 *m *g # Resisting Force (in N) # /1000 because of the unit ‰
|
||||
return F_R
|
||||
F = f /1000 *m *g # force (in N) # /1000 because of the unit ‰
|
||||
return F
|
||||
end #function forceFromCoefficient
|
||||
|
||||
|
||||
|
||||
## calculate acceleration:
|
||||
|
||||
"""
|
||||
acceleration(F_T, F_R, m_train, ξ_train)
|
||||
|
||||
Calculate the acceleration in m/s^2 with train characteristics and forces.
|
||||
|
||||
# Arguments
|
||||
- `F_T::Real`: the tractive effort in N.
|
||||
- `F_R::Real`: the resisting forces in N.
|
||||
- `m_train::Real`: the train's mass in kg.
|
||||
- `ξ_train::Real`: the train's rotation mass factor (without unit).
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> acceleration(94400.0, 1700.0, 88000.0, 1.08)
|
||||
0.9753787878787878
|
||||
```
|
||||
"""
|
||||
function acceleration(F_T::Real, F_R::Real, m_train::Real, ξ_train::Real)
|
||||
# equation is based on [Bruenger:2014, page 72] with a=dv/dt
|
||||
|
||||
# F_T: tractive effort (in N)
|
||||
# F_R: resisting forces (in N)
|
||||
# m_train: train's mass (in kg)
|
||||
# ξ_train: train's rotation mass factor (without unit)
|
||||
|
||||
a = (F_T - F_R) /m_train /ξ_train # acceleration (in m/s)
|
||||
a = (F_T - F_R) /m_train /ξ_train # acceleration (in m/s^2)
|
||||
return a
|
||||
end #function acceleration
|
||||
|
||||
|
||||
## calculate step sizes:
|
||||
|
||||
"""
|
||||
Δs_with_Δt(Δt, a_prev, v_prev)
|
||||
|
||||
Calculate the distance step in m with the time step in s, acceleration in m/s^2 and velocity in m/s.
|
||||
|
||||
See also [`Δs_with_Δv`](@ref), [`Δt_with_Δs`](@ref), [`Δt_with_Δv`](@ref), [`Δt_with_constant_v`](@ref), [`Δv_with_Δs`](@ref), [`Δv_with_Δt`](@ref).
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> Δs_with_Δt(3.0, 0.5, 25.0)
|
||||
77.25
|
||||
```
|
||||
"""
|
||||
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 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
|
||||
|
||||
|
||||
"""
|
||||
Δs_with_Δv(Δv, a_prev, v_prev)
|
||||
|
||||
Calculate the distance step in m with the velocity step in m/s, acceleration in m/s^2 and velocity in m/s.
|
||||
|
||||
See also [`Δs_with_Δt`](@ref), [`Δt_with_Δs`](@ref), [`Δt_with_Δv`](@ref), [`Δt_with_constant_v`](@ref), [`Δv_with_Δs`](@ref), [`Δv_with_Δt`](@ref).
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> Δs_with_Δv(1.0, 0.5, 25.0)
|
||||
51.0
|
||||
```
|
||||
"""
|
||||
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 support point
|
||||
# v_prev: velocitiy from previous support point
|
||||
Δs = ((v_prev + Δv)^2 - v_prev^2)/2/a_prev # step size (in m)
|
||||
Δs = ((v_prev + Δv)^2 - v_prev^2) /2 /a_prev # step size (in m)
|
||||
return Δs
|
||||
end #function Δs_with_Δv
|
||||
|
||||
|
||||
"""
|
||||
Δt_with_Δs(Δs, a_prev, v_prev)
|
||||
|
||||
Calculate the time step in s with the distance step in m, acceleration in m/s^2 and velocity in m/s.
|
||||
|
||||
See also [`Δs_with_Δt`](@ref), [`Δs_with_Δv`](@ref), [`Δt_with_Δv`](@ref), [`Δt_with_constant_v`](@ref), [`Δv_with_Δs`](@ref), [`Δv_with_Δt`](@ref).
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> Δt_with_Δs(10.0, 0.5, 25.0)
|
||||
0.39841267341660824
|
||||
```
|
||||
"""
|
||||
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 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)
|
||||
Δt = sign(a_prev) *sqrt((v_prev /a_prev)^2 + 2 *Δs /a_prev) - v_prev /a_prev # step size (in s)
|
||||
return Δt
|
||||
end #function Δt_with_Δs
|
||||
|
||||
|
||||
"""
|
||||
Δt_with_Δv(Δv, a_prev)
|
||||
|
||||
Calculate the time step in s with the velocity step in m/s and the acceleration in m/s^2.
|
||||
|
||||
See also [`Δs_with_Δt`](@ref), [`Δs_with_Δv`](@ref), [`Δt_with_Δs`](@ref), [`Δt_with_constant_v`](@ref), [`Δv_with_Δs`](@ref), [`Δv_with_Δt`](@ref).
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> Δt_with_Δv(1.0, 0.5)
|
||||
2.0
|
||||
```
|
||||
"""
|
||||
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 support point
|
||||
Δt = Δv /a_prev # step size (in s)
|
||||
return Δt
|
||||
end #function Δt_with_Δv
|
||||
|
||||
|
||||
"""
|
||||
Δt_with_constant_v(Δs, v)
|
||||
|
||||
Calculate the time step in s with the distance step in m and constant velocity in m/s.
|
||||
|
||||
See also [`Δs_with_Δt`](@ref), [`Δs_with_Δv`](@ref), [`Δt_with_Δs`](@ref), [`Δt_with_Δv`](@ref), [`Δv_with_Δs`](@ref), [`Δv_with_Δt`](@ref).
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> Δt_with_constant_v(10.0, 25.0)
|
||||
0.4
|
||||
```
|
||||
"""
|
||||
function Δt_with_constant_v(Δs::Real, v::Real)
|
||||
# equation is based on [Wende:2003, page 37]
|
||||
|
||||
# Δs: distance step (in m)
|
||||
# v: constant velocity (in m/s)
|
||||
Δt = Δs /v # step size (in s)
|
||||
return Δt
|
||||
end #function Δt_with_constant_v
|
||||
|
||||
|
||||
"""
|
||||
Δv_with_Δs(Δs, a_prev, v_prev)
|
||||
|
||||
Calculate the velocity step in m/s with the distance step in m, acceleration in m/s^2 and velocity in m/s.
|
||||
|
||||
See also [`Δs_with_Δt`](@ref), [`Δs_with_Δv`](@ref), [`Δt_with_Δs`](@ref), [`Δt_with_Δv`](@ref), [`Δt_with_constant_v`](@ref), [`Δv_with_Δt`](@ref).
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> Δv_with_Δs(10.0, 0.5, 25.0)
|
||||
0.19920633670830412
|
||||
```
|
||||
"""
|
||||
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 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
|
||||
|
||||
|
||||
"""
|
||||
Δv_with_Δt(Δt, a_prev, v_prev)
|
||||
|
||||
Calculate the velocity step in m/s with the time step in s and acceleration in m/s^2.
|
||||
|
||||
See also [`Δs_with_Δt`](@ref), [`Δs_with_Δv`](@ref), [`Δt_with_Δs`](@ref), [`Δt_with_Δv`](@ref), [`Δt_with_constant_v`](@ref), [`Δv_with_Δs`](@ref).
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> Δv_with_Δt(3.0, 0.5)
|
||||
1.5
|
||||
```
|
||||
"""
|
||||
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 support point
|
||||
Δv = Δt * a_prev # step size (in m/s)
|
||||
return Δv
|
||||
end #function Δv_with_Δt
|
||||
|
||||
|
||||
|
||||
## calculate values for braking
|
||||
|
||||
"""
|
||||
brakingDistance(v_start, v_end, a_braking, approxLevel)
|
||||
|
||||
Calculate the braking distance in m with velocities in m/s and acceleration in m/s^2.
|
||||
|
||||
See also [`brakingAcceleration`](@ref), [`brakingStartVelocity`](@ref).
|
||||
|
||||
# Arguments
|
||||
- `v_start::Real`: the velocity at the start of braking in m/s.
|
||||
- `v_end::Real`: the target velocity at the end of braking in m/s.
|
||||
- `a_braking::Real`: the constant braking acceleration in m/s^2.
|
||||
- `approxLevel::Integer`: the last position behind the decimal point that is not rounded
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> brakingDistance(25.0, 15.0, -0.4253, 3)
|
||||
470.2563
|
||||
```
|
||||
"""
|
||||
function brakingDistance(v_start::Real, v_end::Real, a_braking::Real, approxLevel::Integer)
|
||||
# equation is based on [Wende:2003, page 37]
|
||||
|
||||
# v_start: velocity at the start of braking (in m/s)
|
||||
# v_end: target velocity at the end of braking (in m/s)
|
||||
# a_braking: constant braking acceleration (in m/s^2)
|
||||
s_braking = (v_end^2 - v_start^2) /2 /a_braking # braking distance (in m)
|
||||
# TODO: also possible: Δs_with_Δv(v_end-v_start, a_braking, v_start)
|
||||
# return max(0.0, ceil(s_braking, digits=approxLevel)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
|
||||
return max(0.0, ceil(s_braking, digits= approxLevel +1)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
|
||||
end #function brakingDistance
|
||||
|
||||
"""
|
||||
brakingStartVelocity(v_end, a_braking, s_braking, approxLevel)
|
||||
|
||||
Calculate the maximum velocity in m/s where the train can start to brake to reach `v_end`.
|
||||
|
||||
See also [`brakingAcceleration`](@ref), [`brakingDistance`](@ref).
|
||||
|
||||
# Arguments
|
||||
- `v_end::Real`: the target velocity at the end of braking in m/s.
|
||||
- `a_braking::Real`: the constant braking acceleration in m/s^2.
|
||||
- `s_braking::Real`: the braking distance in m.
|
||||
- `approxLevel::Integer`: the last position behind the decimal point that is not rounded
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> brakingStartVelocity(15.0, -0.4253, 500, 3)
|
||||
25.4656
|
||||
```
|
||||
"""
|
||||
function brakingStartVelocity(v_end::Real, a_braking::Real, s_braking::Real, approxLevel::Integer)
|
||||
# equation is based on [Wende:2003, page 37]
|
||||
|
||||
# v_end: target velocity at the end of braking (in m/s)
|
||||
# a_braking: constant braking acceleration (in m/s^2)
|
||||
# s_braking: braking distance (in Ws)
|
||||
v_start = sqrt(v_end^2 - 2*a_braking *s_braking) # braking start velocity (in m/s)
|
||||
# return floor(v_start, digits= approxLevel)
|
||||
return floor(v_start, digits= approxLevel +1)
|
||||
end #function brakingStartVelocity
|
||||
|
||||
|
||||
"""
|
||||
brakingAcceleration(v_start, v_end, s_braking)
|
||||
|
||||
Calculate the acceleration in m/s^2 to decelerate from `v_start` to `v_end` in m/s on `s_braking` in m.
|
||||
|
||||
See also [`brakingDistance`](@ref), [`brakingStartVelocity`](@ref).
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> brakingAcceleration(25.0, 15.0, 500)
|
||||
-0.4
|
||||
```
|
||||
"""
|
||||
function brakingAcceleration(v_start::Real, v_end::Real, s_braking::Real)
|
||||
# equation is based on [Wende:2003, page 37]
|
||||
|
||||
# v_start: braking start velocity (in m/s)
|
||||
# v_end: target velocity at the end of braking (in m/s)
|
||||
# s_braking: braking distance (in Ws)
|
||||
a_braking = (v_end^2 - v_start^2) /2 /s_braking # constant braking acceleration (in m/s^2)
|
||||
return a_braking
|
||||
end #function brakingAcceleration
|
||||
|
|
|
@ -4,6 +4,32 @@
|
|||
# __copyright__ = "2020-2022"
|
||||
# __license__ = "ISC"
|
||||
|
||||
"""
|
||||
createOutput(settings, drivingCourse, pointsOfInterest)
|
||||
|
||||
Create output information depending on `settings`, `drivingCourse` and `pointsOfInterest`.
|
||||
|
||||
See also [`createOutput`](@ref).
|
||||
|
||||
# Arguments
|
||||
- `settings::Settings`: the Settings object containing settings for output format and detail.
|
||||
- `drivingCourse::Vector{Dict}`: the Vector containing dictionaries for all support points.
|
||||
- `pointsOfInterest::Vector{NamedTuple}`: the Vector containing tuples for the paths' points of interest.
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> createOutput(settings_poi, drivingCourse_longdistance, pointsOfInterest_pathWithSlope)
|
||||
5×11 DataFrame
|
||||
Row │ label driving_mode s v t a F_T F_R R_path R_traction R_wagons
|
||||
│ String String Real Real Real Real Real Real Real Real Real
|
||||
─────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
1 │ view_point_1 accelerating 850.0 28.707 54.049 0.331 1.93049e5 36602.1 0.0 9088.56 27513.6
|
||||
2 │ distant_signal_1 accelerating 1000.0 30.325 59.129 0.294 1.82746e5 43604.7 4344.35 9795.13 29465.2
|
||||
3 │ main_signal_1 accelerating 2000.0 37.356 88.468 0.185 1.48352e5 60899.4 8688.69 13259.1 38951.5
|
||||
4 │ main_signal_3 braking 9000.0 27.386 258.578 -0.375 0.0 34522.1 0.0 8537.05 25985.0
|
||||
5 │ clearing_point_1 braking 9203.37 24.443 266.426 -0.375 0.0 30176.2 0.0 7389.44 22786.8
|
||||
```
|
||||
"""
|
||||
function createOutput(settings::Settings, drivingCourse::Vector{Dict}, pointsOfInterest::Vector{NamedTuple})
|
||||
if settings.outputDetail == :running_time
|
||||
output::Vector{Dict} = [Dict(:t => drivingCourse[end][:t])]
|
||||
|
@ -52,7 +78,34 @@ function createOutput(settings::Settings, drivingCourse::Vector{Dict}, pointsOfI
|
|||
end
|
||||
|
||||
|
||||
function createDataFrame(output_vector::Vector{Dict}, outputDetail, approxLevel::Int)
|
||||
"""
|
||||
createDataFrame(output_vector, outputDetail, approxLevel)
|
||||
|
||||
Create a DataFrame from `output_vector` with `outputDetail` and `approxLevel`.
|
||||
|
||||
See also [`createOutput`](@ref).
|
||||
|
||||
# Arguments
|
||||
|
||||
- `output_vector::Vector{Dict}`: the Vector containing all data to be outputted.
|
||||
- `outputDetail::Symbol`: the detail level the DataFrame is created for.
|
||||
- `approxLevel::Int`: the number of digits for rounding each Number in the DataFrame.
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> createDataFrame(vector_pointsOfInterest, detail_data_points, approxLevel_default)
|
||||
5×11 DataFrame
|
||||
Row │ label driving_mode s v t a F_T F_R R_path R_traction R_wagons
|
||||
│ String String Real Real Real Real Real Real Real Real Real
|
||||
─────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
|
||||
1 │ view_point_1 accelerating 850.0 28.707 54.049 0.331 1.93049e5 36602.1 0.0 9088.56 27513.6
|
||||
2 │ distant_signal_1 accelerating 1000.0 30.325 59.129 0.294 1.82746e5 43604.7 4344.35 9795.13 29465.2
|
||||
3 │ main_signal_1 accelerating 2000.0 37.356 88.468 0.185 1.48352e5 60899.4 8688.69 13259.1 38951.5
|
||||
4 │ main_signal_3 braking 9000.0 27.386 258.578 -0.375 0.0 34522.1 0.0 8537.05 25985.0
|
||||
5 │ clearing_point_1 braking 9203.37 24.443 266.426 -0.375 0.0 30176.2 0.0 7389.44 22786.8
|
||||
```
|
||||
"""
|
||||
function createDataFrame(output_vector::Vector{Dict}, outputDetail::Symbol, approxLevel::Int)
|
||||
if outputDetail == :running_time
|
||||
# create a DataFrame with running time information
|
||||
dataFrame = DataFrame(t=[round(output_vector[end][:t], digits=approxLevel)])
|
||||
|
|
Loading…
Reference in New Issue