|
|
@ -10,7 +10,7 @@ module Behavior
|
|
|
|
include("./DrivingDynamics.jl")
|
|
|
|
include("./DrivingDynamics.jl")
|
|
|
|
using .DrivingDynamics
|
|
|
|
using .DrivingDynamics
|
|
|
|
|
|
|
|
|
|
|
|
export addBreakFreeSection!, addAcceleratingSection!, addCruisingSection!, addDiminishingSection!, addCoastingSection!, addBrakingSection!, addStandstill!,
|
|
|
|
export addBreakFreeSection!, addClearingSection!, addAcceleratingSection!, addCruisingSection!, addDiminishingSection!, addCoastingSection!, addBrakingSection!, addStandstill!,
|
|
|
|
# addBrakingSectionInOneStep! is not used in the current version of the tool
|
|
|
|
# addBrakingSectionInOneStep! is not used in the current version of the tool
|
|
|
|
calculateForces!, createDataPoint,
|
|
|
|
calculateForces!, createDataPoint,
|
|
|
|
|
|
|
|
|
|
|
@ -171,43 +171,6 @@ function moveAStep(previousPoint::Dict, stepVariable::String, stepSize::Real, cs
|
|
|
|
return newPoint
|
|
|
|
return newPoint
|
|
|
|
end #function moveAStep
|
|
|
|
end #function moveAStep
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function considerFormerSpeedLimit!(CS::Dict, drivingCourse::Vector{Dict}, acceleratingSection::Dict, settings::Dict, train::Dict, CSs::Vector{Dict}, currentSpeedLimit::Dict)
|
|
|
|
|
|
|
|
# if a former speed limit has been exceeded the accelerating steps of this CS will be removed and a clearing section will be inserted before accelerating
|
|
|
|
|
|
|
|
if drivingCourse[end][:v] > currentSpeedLimit[:v]
|
|
|
|
|
|
|
|
# delete existing clearing section that is not long enough
|
|
|
|
|
|
|
|
while drivingCourse[end][:s] > get(CS[:behaviorSections], :clearing, acceleratingSection)[:s_entry]
|
|
|
|
|
|
|
|
pop!(drivingCourse)
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if haskey(CS[:behaviorSections], :clearing)
|
|
|
|
|
|
|
|
CS[:t] = CS[:t]-CS[:behaviorSections][:clearing][:t] # reducing the total running time (in s)
|
|
|
|
|
|
|
|
CS[:E] = CS[:E]-CS[:behaviorSections][:clearing][:E] # reducing the total energy consumption (in Ws)
|
|
|
|
|
|
|
|
delete!(CS[:behaviorSections], :clearing)
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# create a (new and longer) clearing section
|
|
|
|
|
|
|
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
|
|
|
|
|
|
|
s_clearing = min(CS[:s_exit]-drivingCourse[end][:s]-s_braking, currentSpeedLimit[:s_end] - drivingCourse[end][:s])
|
|
|
|
|
|
|
|
if s_clearing > 0.0
|
|
|
|
|
|
|
|
(CS, drivingCourse, brakingStartReached) = addCruisingSection!(CS, drivingCourse, s_clearing, settings, train, CSs, "clearing")
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
error("ERROR: clearing <=0.0 although it has to be >0.0 in CS ",CS[:id])
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
calculateForces!(drivingCourse[end], CSs, CS[:id], acceleratingSection[:type], train, settings[:massModel])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# reset the acceleratingSection
|
|
|
|
|
|
|
|
acceleratingSection = createBehaviorSection("accelerating", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if drivingCourse[end][:s] + s_braking >= CS[:s_exit]
|
|
|
|
|
|
|
|
CS[:v_peak] = drivingCourse[end][:v]
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (CS, drivingCourse, acceleratingSection)
|
|
|
|
|
|
|
|
end # function considerFormerSpeedLimit!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
# 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
|
|
|
|
# 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
|
|
|
|
"""
|
|
|
|
"""
|
|
|
@ -240,12 +203,12 @@ end #function getNextPointOfInterest
|
|
|
|
## This function calculates the data points of the breakFree section.
|
|
|
|
## 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.
|
|
|
|
# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for breakFree if needed.
|
|
|
|
# Info: currently the values of the breakFree section will be calculated like in the accelerating section
|
|
|
|
# Info: currently the values of the breakFree section will be calculated like in the accelerating section
|
|
|
|
function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, ignoreBraking::Bool)
|
|
|
|
function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, settings::Dict, train::Dict, CSs::Vector{Dict})
|
|
|
|
# conditions for the break free section
|
|
|
|
# conditions for the break free section
|
|
|
|
targetPositionReached = drivingCourse[end][:s] >= CS[:s_exit]
|
|
|
|
endOfCSReached = drivingCourse[end][:s] >= CS[:s_exit] || stateFlags[:endOfCSReached]
|
|
|
|
trainIsHalting = drivingCourse[end][:v] == 0.0
|
|
|
|
trainIsHalting = drivingCourse[end][:v] == 0.0
|
|
|
|
|
|
|
|
|
|
|
|
if trainIsHalting && !targetPositionReached
|
|
|
|
if trainIsHalting && !endOfCSReached
|
|
|
|
BS = createBehaviorSection("breakFree", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
|
|
|
|
BS = createBehaviorSection("breakFree", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
|
|
|
|
drivingCourse[end][:behavior] = BS[:type]
|
|
|
|
drivingCourse[end][:behavior] = BS[:type]
|
|
|
|
|
|
|
|
|
|
|
@ -253,7 +216,7 @@ function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::D
|
|
|
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings[:massModel]) # currently the tractive effort is calculated like in the accelerating section
|
|
|
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings[:massModel]) # currently the tractive effort is calculated like in the accelerating section
|
|
|
|
|
|
|
|
|
|
|
|
# calculate the breakFree section with calculating the accelerating section and just using the first step and removing the rest
|
|
|
|
# calculate the breakFree section with calculating the accelerating section and just using the first step and removing the rest
|
|
|
|
try (CS, drivingCourse, brakingStartReached) = addAcceleratingSection!(CS, drivingCourse, settings, train, CSs, false)
|
|
|
|
try (CS, drivingCourse, stateFlags) = addAcceleratingSection!(CS, drivingCourse, stateFlags, settings, train, CSs)
|
|
|
|
catch(acceleratingError)
|
|
|
|
catch(acceleratingError)
|
|
|
|
println("This error happened during the break free phase that is using the accelerating function:")
|
|
|
|
println("This error happened during the break free phase that is using the accelerating function:")
|
|
|
|
rethrow(acceleratingError)
|
|
|
|
rethrow(acceleratingError)
|
|
|
@ -286,41 +249,97 @@ function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::D
|
|
|
|
|
|
|
|
|
|
|
|
merge!(CS[:behaviorSections], Dict(:breakFree => BS))
|
|
|
|
merge!(CS[:behaviorSections], Dict(:breakFree => BS))
|
|
|
|
end # else: return the characteristic section without a breakFree section
|
|
|
|
end # else: return the characteristic section without a breakFree section
|
|
|
|
return (CS, drivingCourse)
|
|
|
|
|
|
|
|
|
|
|
|
# determine state flags
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if haskey(stateFlags, :usedForDefiningCharacteristics) && stateFlags[:usedForDefiningCharacteristics]
|
|
|
|
|
|
|
|
s_braking = 0.0
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# reset state flags
|
|
|
|
|
|
|
|
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[:resistingForceNegative] = drivingCourse[end][:F_R] < 0
|
|
|
|
|
|
|
|
stateFlags[:previousSpeedLimitReached] = false
|
|
|
|
|
|
|
|
stateFlags[:speedLimitReached] = drivingCourse[end][:v] >= CS[:v_limit]
|
|
|
|
|
|
|
|
stateFlags[:error] = !(stateFlags[:endOfCSReached] || stateFlags[:brakingStartReached] || stateFlags[:tractionDeficit] || stateFlags[:previousSpeedLimitReached] || stateFlags[:speedLimitReached])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (CS, drivingCourse, stateFlags)
|
|
|
|
end #function addBreakFreeSection!
|
|
|
|
end #function addBreakFreeSection!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## This function calculates the data 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::Dict, train::Dict, CSs::Vector{Dict})
|
|
|
|
|
|
|
|
if stateFlags[:previousSpeedLimitReached]
|
|
|
|
|
|
|
|
currentSpeedLimit = getCurrentSpeedLimit(CSs, CS[:id], drivingCourse[end][:s], train[:length])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if haskey(stateFlags, :usedForDefiningCharacteristics) && stateFlags[:usedForDefiningCharacteristics]
|
|
|
|
|
|
|
|
ignoreBraking = true
|
|
|
|
|
|
|
|
s_braking = 0.0
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
ignoreBraking = false
|
|
|
|
|
|
|
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
s_clearing = min(CS[:s_exit]-drivingCourse[end][:s]-s_braking, currentSpeedLimit[:s_end] - drivingCourse[end][:s])
|
|
|
|
|
|
|
|
if s_clearing > 0.0
|
|
|
|
|
|
|
|
(CS, drivingCourse, stateFlags) = addCruisingSection!(CS, drivingCourse, stateFlags, s_clearing, settings, train, CSs, "clearing")
|
|
|
|
|
|
|
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings[:massModel])
|
|
|
|
|
|
|
|
# stateFlags[:brakingStartReached] = brakingStartReached
|
|
|
|
|
|
|
|
# stateFlags[:endOfCSReached] = stateFlags[:endOfCSReached] || drivingCourse[end][:s] == CS[:s_exit]
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
error("ERROR: clearing <=0.0 although it has to be >0.0 in CS ",CS[:id])
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
#stateFlags[:previousSpeedLimitReached] = false
|
|
|
|
|
|
|
|
currentSpeedLimit = getCurrentSpeedLimit(CSs, CS[:id], drivingCourse[end][:s], train[:length])
|
|
|
|
|
|
|
|
stateFlags[:previousSpeedLimitReached] = currentSpeedLimit[:v] != CS[:v_limit] && drivingCourse[end][:v] >= currentSpeedLimit[:v]
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
stateFlags[:error] = true
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (CS, drivingCourse, stateFlags)
|
|
|
|
|
|
|
|
end #function addClearingSection
|
|
|
|
|
|
|
|
|
|
|
|
## This function calculates the data points of the accelerating section.
|
|
|
|
## This function calculates the data points of the accelerating section.
|
|
|
|
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the accelerating section
|
|
|
|
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the accelerating section
|
|
|
|
function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, ignoreBraking::Bool)
|
|
|
|
function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, settings::Dict, train::Dict, CSs::Vector{Dict})
|
|
|
|
#=if drivingCourse would also be part of movingSectiong: function addAcceleratingSection!(movingSection::Dict, csId::Integer, settings::Dict, train::Dict, ignoreBraking::Bool)
|
|
|
|
#function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, ignoreBraking::Bool)
|
|
|
|
|
|
|
|
#=if drivingCourse would also be part of movingSectiong: function addAcceleratingSection!(movingSection::Dict, stateFlags::Dict, csId::Integer, settings::Dict, train::Dict)
|
|
|
|
CSs = movingSection[:characteristicSections]
|
|
|
|
CSs = movingSection[:characteristicSections]
|
|
|
|
CS = CSs[csId]
|
|
|
|
CS = CSs[csId]
|
|
|
|
drivingCourse = movingSection[:drivingCourse]=#
|
|
|
|
drivingCourse = movingSection[:drivingCourse]=#
|
|
|
|
|
|
|
|
|
|
|
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings[:massModel])
|
|
|
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings[:massModel])
|
|
|
|
|
|
|
|
|
|
|
|
if ignoreBraking
|
|
|
|
if haskey(stateFlags, :usedForDefiningCharacteristics) && stateFlags[:usedForDefiningCharacteristics]
|
|
|
|
|
|
|
|
ignoreBraking = true
|
|
|
|
s_braking = 0.0
|
|
|
|
s_braking = 0.0
|
|
|
|
else
|
|
|
|
else
|
|
|
|
|
|
|
|
ignoreBraking = false
|
|
|
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
|
|
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
# conditions for the accelerating section
|
|
|
|
# conditions for the accelerating section
|
|
|
|
targetSpeedReached = drivingCourse[end][:v] >= CS[:v_peak]
|
|
|
|
targetSpeedReached = drivingCourse[end][:v] >= CS[:v_peak] || stateFlags[:speedLimitReached]
|
|
|
|
targetPositionReached = drivingCourse[end][:s] >= CS[:s_exit]
|
|
|
|
endOfCSReached = drivingCourse[end][:s] >= CS[:s_exit] || stateFlags[:endOfCSReached]
|
|
|
|
tractionSurplus = drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
|
|
|
|
tractionSurplus = drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
|
|
|
|
brakingStartReached = drivingCourse[end][:s] +s_braking >= CS[:s_exit]
|
|
|
|
brakingStartReached = drivingCourse[end][:s] +s_braking >= CS[:s_exit] || stateFlags[:brakingStartReached]
|
|
|
|
|
|
|
|
previousSpeedLimitReached = stateFlags[:previousSpeedLimitReached]
|
|
|
|
|
|
|
|
|
|
|
|
# use the conditions for the accelerating section
|
|
|
|
# use the conditions for the accelerating section
|
|
|
|
if !targetSpeedReached && !targetPositionReached && tractionSurplus && !brakingStartReached
|
|
|
|
if !targetSpeedReached && !endOfCSReached && tractionSurplus && !brakingStartReached
|
|
|
|
BS = createBehaviorSection("accelerating", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
|
|
|
|
BS = createBehaviorSection("accelerating", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
|
|
|
|
drivingCourse[end][:behavior] = BS[:type]
|
|
|
|
drivingCourse[end][:behavior] = BS[:type]
|
|
|
|
|
|
|
|
|
|
|
|
currentSpeedLimit = getCurrentSpeedLimit(CSs, CS[:id], drivingCourse[end][:s], train[:length])
|
|
|
|
currentSpeedLimit = getCurrentSpeedLimit(CSs, CS[:id], drivingCourse[end][:s], train[:length])
|
|
|
|
speedLimitReached = drivingCourse[end][:v] > currentSpeedLimit[:v]
|
|
|
|
previousSpeedLimitReached = currentSpeedLimit[:v] != CS[:v_limit] && drivingCourse[end][:v] >= currentSpeedLimit[:v]
|
|
|
|
|
|
|
|
speedLimitReached = drivingCourse[end][:v] >= CS[:v_limit]
|
|
|
|
|
|
|
|
#speedLimitReached = drivingCourse[end][:v] > currentSpeedLimit[:v]
|
|
|
|
#targetSpeedReached = speedLimitReached
|
|
|
|
#targetSpeedReached = speedLimitReached
|
|
|
|
while !targetSpeedReached && !targetPositionReached && tractionSurplus && !brakingStartReached
|
|
|
|
while !targetSpeedReached && !endOfCSReached && tractionSurplus && !brakingStartReached && !previousSpeedLimitReached
|
|
|
|
currentStepSize = settings[:stepSize] # initialize the step size that can be reduced near intersections
|
|
|
|
currentStepSize = settings[:stepSize] # initialize the step size that can be reduced near intersections
|
|
|
|
nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])
|
|
|
|
nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])
|
|
|
|
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
|
|
|
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
|
|
@ -330,7 +349,7 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
|
|
|
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
|
|
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
while !targetSpeedReached && !speedLimitReached && !brakingStartReached && !pointOfInterestReached && tractionSurplus
|
|
|
|
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 && drivingCourse[end][:F_T] > drivingCourse[end][:F_R] # as long as s_i + s_braking < s_CSexit
|
|
|
|
# 03/08 old: while drivingCourse[end][:v] < CS[:v_peak] && drivingCourse[end][:v] <= currentSpeedLimit[:v] && !brakingStartReached && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:F_T] > drivingCourse[end][:F_R] # as long as s_i + s_braking < s_CSexit
|
|
|
|
if drivingCourse[end][:s] >= currentSpeedLimit[:s_end]
|
|
|
|
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 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
|
|
|
@ -352,7 +371,8 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
|
|
|
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
|
|
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
brakingStartReached = drivingCourse[end][:s] +s_braking >= CS[:s_exit]
|
|
|
|
brakingStartReached = drivingCourse[end][:s] +s_braking >= CS[:s_exit]
|
|
|
|
speedLimitReached = drivingCourse[end][:v] > currentSpeedLimit[:v]
|
|
|
|
speedLimitReached = drivingCourse[end][:v] > CS[:v_limit]
|
|
|
|
|
|
|
|
previousSpeedLimitReached = currentSpeedLimit[:v] < CS[:v_limit] && (drivingCourse[end][:v] > currentSpeedLimit[:v] || (drivingCourse[end][:v] == currentSpeedLimit[:v] && drivingCourse[end][:s] < currentSpeedLimit[:s_end]))
|
|
|
|
targetSpeedReached = drivingCourse[end][:v] >= CS[:v_peak]
|
|
|
|
targetSpeedReached = drivingCourse[end][:v] >= CS[:v_peak]
|
|
|
|
#targetSpeedReached = speedLimitReached
|
|
|
|
#targetSpeedReached = speedLimitReached
|
|
|
|
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest # POIs include s_exit as well
|
|
|
|
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest # POIs include s_exit as well
|
|
|
@ -393,36 +413,32 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
|
|
|
|
|
|
|
|
|
|
|
|
elseif drivingCourse[end][:v] > currentSpeedLimit[:v]
|
|
|
|
elseif drivingCourse[end][:v] > currentSpeedLimit[:v]
|
|
|
|
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," > v_limitCurrent=",currentSpeedLimit[:v]) # for testing
|
|
|
|
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," > v_limitCurrent=",currentSpeedLimit[:v]) # for testing
|
|
|
|
(CS, drivingCourse, BS) = considerFormerSpeedLimit!(CS, drivingCourse, BS, settings, train, CSs, currentSpeedLimit)
|
|
|
|
if settings[:stepVariable] == "v in m/s"
|
|
|
|
# conditions for the next for cycle
|
|
|
|
currentStepSize = currentSpeedLimit[:v]-drivingCourse[end-1][:v]
|
|
|
|
if !ignoreBraking
|
|
|
|
|
|
|
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
brakingStartReached = drivingCourse[end][:s] +s_braking >= CS[:s_exit]
|
|
|
|
|
|
|
|
speedLimitReached = false
|
|
|
|
|
|
|
|
targetSpeedReached = drivingCourse[end][:v] >= CS[:v_peak]
|
|
|
|
|
|
|
|
#targetSpeedReached = speedLimitReached
|
|
|
|
|
|
|
|
tractionSurplus = drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
break
|
|
|
|
else
|
|
|
|
# TODO: think about alternative: handle the the position where the rear of the train leaves a CS similar to a POI. Then it will be calculated exactly and even a minimal exceedance of speed limit will be noticed
|
|
|
|
currentStepSize = settings[:stepSize] / 10.0^cycle
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
elseif drivingCourse[end][:s] +s_braking == CS[:s_exit]
|
|
|
|
elseif drivingCourse[end][:s] +s_braking == CS[:s_exit]
|
|
|
|
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
|
|
|
|
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
|
|
|
|
if s_braking == 0.0
|
|
|
|
targetPositionReached = true
|
|
|
|
endOfCSReached = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
break
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
elseif drivingCourse[end][:v] == CS[:v_peak]
|
|
|
|
elseif 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
|
|
|
|
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," == v_peak=",CS[:v_peak]) # for testing
|
|
|
|
# targetSpeedReached = true
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
elseif drivingCourse[end][:v] == currentSpeedLimit[:v] && drivingCourse[end][:s] < currentSpeedLimit[:s_end]
|
|
|
|
|
|
|
|
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," == v_limitCurrent=",currentSpeedLimit[:v]) # for testing
|
|
|
|
break
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
elseif drivingCourse[end][:s] == nextPointOfInterest
|
|
|
|
elseif drivingCourse[end][:s] == nextPointOfInterest
|
|
|
|
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: s=", drivingCourse[end][:s]," == nextPOI=",nextPointOfInterest) # for testing
|
|
|
|
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: s=", drivingCourse[end][:s]," == nextPOI=",nextPointOfInterest) # for testing
|
|
|
|
if nextPointOfInterest == CS[:s_exit]
|
|
|
|
if nextPointOfInterest == CS[:s_exit]
|
|
|
|
targetPositionReached = true
|
|
|
|
endOfCSReached = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
break
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
@ -439,63 +455,67 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
|
|
|
|
|
|
|
|
|
|
|
|
# conditions for the next for cycle
|
|
|
|
# conditions for the next for cycle
|
|
|
|
brakingStartReached = false
|
|
|
|
brakingStartReached = false
|
|
|
|
|
|
|
|
previousSpeedLimitReached = false
|
|
|
|
speedLimitReached = false
|
|
|
|
speedLimitReached = false
|
|
|
|
targetSpeedReached = false
|
|
|
|
targetSpeedReached = false
|
|
|
|
targetPositionReached = false
|
|
|
|
endOfCSReached = false
|
|
|
|
pointOfInterestReached = false
|
|
|
|
pointOfInterestReached = false
|
|
|
|
tractionSurplus = true
|
|
|
|
tractionSurplus = true
|
|
|
|
|
|
|
|
|
|
|
|
else # if the level of approximation is reached
|
|
|
|
else # if the level of approximation is reached
|
|
|
|
if drivingCourse[end][:v] > CS[:v_peak]
|
|
|
|
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
|
|
|
|
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," > v_peak=",CS[:v_peak]) # for testing
|
|
|
|
targetSpeedReached = true
|
|
|
|
|
|
|
|
pop!(drivingCourse)
|
|
|
|
pop!(drivingCourse)
|
|
|
|
pop!(BS[:dataPoints])
|
|
|
|
pop!(BS[:dataPoints])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# conditions for the next section
|
|
|
|
brakingStartReached = false
|
|
|
|
brakingStartReached = false
|
|
|
|
|
|
|
|
|
|
|
|
elseif drivingCourse[end][:s] + s_braking > CS[:s_exit]
|
|
|
|
elseif drivingCourse[end][:s] + s_braking > CS[:s_exit]
|
|
|
|
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
|
|
|
|
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
|
|
|
|
#brakingStartReached = true
|
|
|
|
|
|
|
|
if s_braking > 0.0
|
|
|
|
if s_braking > 0.0
|
|
|
|
pop!(drivingCourse)
|
|
|
|
pop!(drivingCourse)
|
|
|
|
pop!(BS[:dataPoints])
|
|
|
|
pop!(BS[:dataPoints])
|
|
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
else
|
|
|
|
drivingCourse[end][:s] = CS[:s_exit] # round s down to CS[:s_exit]
|
|
|
|
drivingCourse[end][:s] = CS[:s_exit] # round s down to CS[:s_exit]
|
|
|
|
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s]
|
|
|
|
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
elseif drivingCourse[end][:s] > nextPointOfInterest
|
|
|
|
elseif drivingCourse[end][:s] > nextPointOfInterest
|
|
|
|
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: F_T=", drivingCourse[end][:s]," > nextPointOfInterest",nextPointOfInterest) # for testing
|
|
|
|
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: s=", drivingCourse[end][:s]," > nextPointOfInterest=",nextPointOfInterest) # for testing
|
|
|
|
drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
|
|
|
|
drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
|
|
|
|
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s]
|
|
|
|
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s]
|
|
|
|
|
|
|
|
|
|
|
|
elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R]
|
|
|
|
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
|
|
|
|
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: F_T=", drivingCourse[end][:F_T]," <= F_R=",drivingCourse[end][:F_R]) # for testing
|
|
|
|
#tractionSurplus = false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
elseif drivingCourse[end][:v] > currentSpeedLimit[:v]
|
|
|
|
elseif drivingCourse[end][:v] > currentSpeedLimit[:v]
|
|
|
|
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," > v_limitCurrent=",currentSpeedLimit[:v]) # for testing
|
|
|
|
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," > v_limitCurrent=",currentSpeedLimit[:v]) # for testing
|
|
|
|
(CS, drivingCourse, BS) = considerFormerSpeedLimit!(CS, drivingCourse, BS, settings, train, CSs, currentSpeedLimit)
|
|
|
|
previousSpeedLimitReached = true
|
|
|
|
speedLimitReached = false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: think about alternative: handle the the position where the rear of the train leaves a CS similar to a POI. Then it will be calculated exactly and the train start accelerating immediately and not only at the next data point.
|
|
|
|
pop!(drivingCourse)
|
|
|
|
|
|
|
|
pop!(BS[:dataPoints])
|
|
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
else
|
|
|
|
if drivingCourse[end][:s] + s_braking == CS[:s_exit]
|
|
|
|
if drivingCourse[end][:s] + s_braking == CS[:s_exit]
|
|
|
|
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," else case and there: s +s_braking=", drivingCourse[end][:s],",+",s_braking," = ",drivingCourse[end][:s] +s_braking," > s_exit=",CS[:s_exit]) # for testing
|
|
|
|
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," else case and there: s +s_braking=", drivingCourse[end][:s],",+",s_braking," = ",drivingCourse[end][:s] +s_braking," > s_exit=",CS[:s_exit]) # for testing
|
|
|
|
|
|
|
|
elseif drivingCourse[end][:v] == currentSpeedLimit[:v]
|
|
|
|
|
|
|
|
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," == v_limitCurrent=",currentSpeedLimit[:v]) # for testing
|
|
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
# TODO is it possible to put this into to the if-fork?
|
|
|
|
# TODO is it possible to put this into to the if-fork?
|
|
|
|
if drivingCourse[end][:s] == CS[:s_exit]
|
|
|
|
if drivingCourse[end][:s] == CS[:s_exit]
|
|
|
|
targetPositionReached = true
|
|
|
|
endOfCSReached = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end #for
|
|
|
|
end #for
|
|
|
|
|
|
|
|
|
|
|
|
if drivingCourse[end][:s] == CS[:s_exit]
|
|
|
|
if drivingCourse[end][:s] == CS[:s_exit]
|
|
|
|
targetPositionReached = true
|
|
|
|
endOfCSReached = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
end #while
|
|
|
|
end #while
|
|
|
@ -508,7 +528,7 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
|
|
|
|
:E => drivingCourse[end][:E] - drivingCourse[BS[:dataPoints][1]][:E], # total energy consumption (in Ws)
|
|
|
|
:E => drivingCourse[end][:E] - drivingCourse[BS[:dataPoints][1]][:E], # total energy consumption (in Ws)
|
|
|
|
:v_exit => drivingCourse[end][:v])) # exit speed (in m/s)))
|
|
|
|
:v_exit => drivingCourse[end][:v])) # exit speed (in m/s)))
|
|
|
|
|
|
|
|
|
|
|
|
CS[:v_peak] = max(drivingCourse[end][:v], CS[:v_entry]) # setting v_peak to the last data points velocity which is the highest reachable value in this characteristic section or to v_entry in case it is higher when 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 data points velocity which is the highest reachable value in this characteristic section or to v_entry in case it is higher when running on a path with high resistances
|
|
|
|
CS[:t] = CS[:t] + BS[:t] # total running time (in s)
|
|
|
|
CS[:t] = CS[:t] + BS[:t] # total running time (in s)
|
|
|
|
CS[:E] = CS[:E] + BS[:E] # total energy consumption (in Ws)
|
|
|
|
CS[:E] = CS[:E] + BS[:E] # total energy consumption (in Ws)
|
|
|
|
|
|
|
|
|
|
|
@ -516,26 +536,38 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
return (CS, drivingCourse, brakingStartReached)
|
|
|
|
# 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[:resistingForceNegative] = drivingCourse[end][:F_R] < 0
|
|
|
|
|
|
|
|
stateFlags[:previousSpeedLimitReached] = previousSpeedLimitReached
|
|
|
|
|
|
|
|
stateFlags[:speedLimitReached] = targetSpeedReached
|
|
|
|
|
|
|
|
stateFlags[:error] = !(endOfCSReached || brakingStartReached || stateFlags[:tractionDeficit] || previousSpeedLimitReached || targetSpeedReached)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (CS, drivingCourse, stateFlags)
|
|
|
|
end #function addAcceleratingSection!
|
|
|
|
end #function addAcceleratingSection!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## This function calculates the data points of the cruising section.
|
|
|
|
## 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.
|
|
|
|
# Therefore it gets its first data 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}, s_cruising::Real, settings::Dict, train::Dict, CSs::Vector{Dict}, cruisingType::String)
|
|
|
|
function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, s_cruising::Real, settings::Dict, train::Dict, CSs::Vector{Dict}, cruisingType::String)
|
|
|
|
# traction effort and resisting forces (in N)
|
|
|
|
# traction effort and resisting forces (in N)
|
|
|
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
|
|
|
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
|
|
|
|
|
|
|
|
|
|
|
|
# conditions for cruising section
|
|
|
|
# conditions for cruising section
|
|
|
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
|
|
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
|
|
|
brakingStartReached = drivingCourse[end][:s] + s_braking >= CS[:s_exit]
|
|
|
|
brakingStartReached = drivingCourse[end][:s] + s_braking >= CS[:s_exit] || stateFlags[:brakingStartReached]
|
|
|
|
speedIsValid = drivingCourse[end][:v]>0.0 && drivingCourse[end][:v]<=CS[:v_peak]
|
|
|
|
speedIsValid = drivingCourse[end][:v]>0.0 && drivingCourse[end][:v]<=CS[:v_peak]
|
|
|
|
tractionSurplus = drivingCourse[end][:F_T] >= drivingCourse[end][:F_R]
|
|
|
|
tractionDeficit = drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
|
|
|
|
|
|
|
|
targetPositionReached = s_cruising == 0.0
|
|
|
|
|
|
|
|
|
|
|
|
if speedIsValid && !brakingStartReached && tractionSurplus
|
|
|
|
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]
|
|
|
|
# 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 = createBehaviorSection(cruisingType, drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
|
|
|
|
BS = createBehaviorSection(cruisingType, drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
|
|
|
|
drivingCourse[end][:behavior] = BS[:type]
|
|
|
|
drivingCourse[end][:behavior] = BS[:type]
|
|
|
|
|
|
|
|
trainIsClearing = BS[:type] == "clearing"
|
|
|
|
|
|
|
|
trainIsBrakingDownhill = BS[:type] == "downhillBraking"
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: necessary?
|
|
|
|
# TODO: necessary?
|
|
|
|
s_cruising = min(s_cruising, CS[:s_exit]-BS[:s_entry])
|
|
|
|
s_cruising = min(s_cruising, CS[:s_exit]-BS[:s_entry])
|
|
|
@ -547,14 +579,16 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
|
|
|
|
# conditions for cruising section
|
|
|
|
# conditions for cruising section
|
|
|
|
trainInPreviousCS = drivingCourse[end][:s] < CS[:s_entry] + train[:length]
|
|
|
|
trainInPreviousCS = drivingCourse[end][:s] < CS[:s_entry] + train[:length]
|
|
|
|
targetPositionReached = drivingCourse[end][:s] >= BS[:s_entry] +s_cruising
|
|
|
|
targetPositionReached = drivingCourse[end][:s] >= BS[:s_entry] +s_cruising
|
|
|
|
|
|
|
|
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
|
|
|
|
# use the conditions for the cruising section
|
|
|
|
while trainInPreviousCS && !targetPositionReached && tractionSurplus
|
|
|
|
while trainInPreviousCS && !targetPositionReached && !tractionDeficit && (trainIsClearing || (trainIsBrakingDownhill == resistingForceNegative)) # while clearing tractive or braking force can be used
|
|
|
|
currentStepSize = settings[:stepSize]
|
|
|
|
currentStepSize = settings[:stepSize]
|
|
|
|
nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])
|
|
|
|
nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])
|
|
|
|
|
|
|
|
|
|
|
|
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
|
|
|
|
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
|
|
|
|
while trainInPreviousCS && targetPositionReached && !pointOfInterestReached && tractionSurplus
|
|
|
|
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 && drivingCourse[end][:F_T]>=drivingCourse[end][:F_R]
|
|
|
|
# 03/09 old: while drivingCourse[end][:s] < CS[:s_entry] + train[:length] && drivingCourse[end][:s] < BS[:s_entry] +s_cruising && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:F_T]>=drivingCourse[end][:F_R]
|
|
|
|
# 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
|
|
|
|
# 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?
|
|
|
|
#TODO: maybe just consider former CS with different path resistance?
|
|
|
@ -576,9 +610,10 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
|
|
|
|
|
|
|
|
|
|
|
|
# conditions for the next while cycle
|
|
|
|
# conditions for the next while cycle
|
|
|
|
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest # POIs include s_exit as well
|
|
|
|
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest # POIs include s_exit as well
|
|
|
|
tractionSurplus = drivingCourse[end][:F_T] >= drivingCourse[end][:F_R]
|
|
|
|
tractionDeficit = drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
|
|
|
|
targetPositionReached = drivingCourse[end][:s] >= BS[:s_entry] +s_cruising
|
|
|
|
targetPositionReached = drivingCourse[end][:s] >= BS[:s_entry] +s_cruising
|
|
|
|
trainInPreviousCS = drivingCourse[end][:s] < CS[:s_entry] + train[:length]
|
|
|
|
trainInPreviousCS = drivingCourse[end][:s] < CS[:s_entry] + train[:length]
|
|
|
|
|
|
|
|
resistingForceNegative = drivingCourse[end][:F_R] < 0.0
|
|
|
|
end #while
|
|
|
|
end #while
|
|
|
|
|
|
|
|
|
|
|
|
# check which limit was reached and adjust the currentStepSize for the next cycle
|
|
|
|
# check which limit was reached and adjust the currentStepSize for the next cycle
|
|
|
@ -586,6 +621,9 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
|
|
|
|
if drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
|
|
|
|
if drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
|
|
|
|
currentStepSize = settings[:stepSize] / 10.0^cycle
|
|
|
|
currentStepSize = settings[:stepSize] / 10.0^cycle
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
elseif drivingCourse[end][:F_R] < 0.0
|
|
|
|
|
|
|
|
currentStepSize = settings[:stepSize] / 10.0^cycle
|
|
|
|
|
|
|
|
|
|
|
|
elseif drivingCourse[end][:s] > nextPointOfInterest
|
|
|
|
elseif drivingCourse[end][:s] > nextPointOfInterest
|
|
|
|
if settings[:stepVariable] == "s in m"
|
|
|
|
if settings[:stepVariable] == "s in m"
|
|
|
|
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
|
|
|
|
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
|
|
|
@ -619,7 +657,7 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
|
|
|
|
|
|
|
|
|
|
|
|
# conditions for the next for cycle
|
|
|
|
# conditions for the next for cycle
|
|
|
|
pointOfInterestReached = false
|
|
|
|
pointOfInterestReached = false
|
|
|
|
tractionSurplus = true
|
|
|
|
tractionDeficit = false
|
|
|
|
targetPositionReached = false
|
|
|
|
targetPositionReached = false
|
|
|
|
trainInPreviousCS = true
|
|
|
|
trainInPreviousCS = true
|
|
|
|
|
|
|
|
|
|
|
@ -636,6 +674,8 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
|
|
|
|
break
|
|
|
|
break
|
|
|
|
elseif drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
|
|
|
|
elseif drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
|
|
|
|
break
|
|
|
|
break
|
|
|
|
|
|
|
|
elseif drivingCourse[end][:F_R] < 0.0
|
|
|
|
|
|
|
|
break
|
|
|
|
else
|
|
|
|
else
|
|
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
@ -646,9 +686,10 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
|
|
|
|
|
|
|
|
|
|
|
|
# conditions for the next while cycle
|
|
|
|
# conditions for the next while cycle
|
|
|
|
targetPositionReached = drivingCourse[end][:s] >= BS[:s_entry] +s_cruising
|
|
|
|
targetPositionReached = drivingCourse[end][:s] >= BS[:s_entry] +s_cruising
|
|
|
|
tractionSurplus = drivingCourse[end][:F_T] >= drivingCourse[end][:F_R]
|
|
|
|
tractionDeficit = drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
|
|
|
|
|
|
|
|
resistingForceNegative = drivingCourse[end][:F_R] < 0.0
|
|
|
|
|
|
|
|
|
|
|
|
while !targetPositionReached && tractionSurplus
|
|
|
|
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] < BS[:s_entry]+s_cruising && drivingCourse[end][:F_T] >= drivingCourse[end][:F_R]
|
|
|
|
nextPointOfInterest = min(BS[:s_entry]+s_cruising, getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s]))
|
|
|
|
nextPointOfInterest = min(BS[:s_entry]+s_cruising, getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s]))
|
|
|
|
drivingCourse[end][:a] = 0.0 # acceleration (in m/s^2)
|
|
|
|
drivingCourse[end][:a] = 0.0 # acceleration (in m/s^2)
|
|
|
@ -666,7 +707,8 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
|
|
|
|
|
|
|
|
|
|
|
|
# conditions for the next while cycle
|
|
|
|
# conditions for the next while cycle
|
|
|
|
targetPositionReached = drivingCourse[end][:s] >= BS[:s_entry] +s_cruising
|
|
|
|
targetPositionReached = drivingCourse[end][:s] >= BS[:s_entry] +s_cruising
|
|
|
|
tractionSurplus = drivingCourse[end][:F_T] >= drivingCourse[end][:F_R]
|
|
|
|
tractionDeficit = drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
|
|
|
|
|
|
|
|
resistingForceNegative = drivingCourse[end][:F_R] < 0
|
|
|
|
end #while
|
|
|
|
end #while
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: realize this better inside the upper loops?
|
|
|
|
# TODO: realize this better inside the upper loops?
|
|
|
@ -686,33 +728,43 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
|
|
|
|
mergeBehaviorSection!(CS[:behaviorSections], BS)
|
|
|
|
mergeBehaviorSection!(CS[:behaviorSections], BS)
|
|
|
|
end # else: return the characteristic section without a cruising section
|
|
|
|
end # else: return the characteristic section without a cruising section
|
|
|
|
|
|
|
|
|
|
|
|
return (CS, drivingCourse, brakingStartReached)
|
|
|
|
# set state flags
|
|
|
|
|
|
|
|
stateFlags[:endOfCSReached] = drivingCourse[end][:s] == CS[:s_exit]
|
|
|
|
|
|
|
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
|
|
|
|
|
|
|
stateFlags[:brakingStartReached] = brakingStartReached || drivingCourse[end][:s] + s_braking >= CS[:s_exit]
|
|
|
|
|
|
|
|
stateFlags[:tractionDeficit] = tractionDeficit
|
|
|
|
|
|
|
|
stateFlags[:resistingForceNegative] = drivingCourse[end][:F_R] < 0.0
|
|
|
|
|
|
|
|
currentSpeedLimit = getCurrentSpeedLimit(CSs, CS[:id], drivingCourse[end][:s], train[:length])
|
|
|
|
|
|
|
|
stateFlags[:previousSpeedLimitReached] = currentSpeedLimit[:v] != CS[:v_limit] && drivingCourse[end][:v] >= currentSpeedLimit[:v]
|
|
|
|
|
|
|
|
stateFlags[:error] = !(targetPositionReached || tractionDeficit || !(cruisingType == "clearing" || ((cruisingType == "downhillBraking") == resistingForceNegative)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (CS, drivingCourse, stateFlags)
|
|
|
|
end #function addCruisingSection!
|
|
|
|
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 data points for diminishing run when using maximum tractive effort and still getting slower
|
|
|
|
function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict})
|
|
|
|
function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, settings::Dict, train::Dict, CSs::Vector{Dict})
|
|
|
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "diminishing", train, settings[:massModel])
|
|
|
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "diminishing", train, settings[:massModel])
|
|
|
|
|
|
|
|
|
|
|
|
# conditions for diminishing section
|
|
|
|
# conditions for diminishing section
|
|
|
|
targetSpeedReached = drivingCourse[end][:v] <= 0.0
|
|
|
|
targetSpeedReached = drivingCourse[end][:v] <= 0.0
|
|
|
|
targetPositionReached = drivingCourse[end][:s] >= CS[:s_exit]
|
|
|
|
endOfCSReached = drivingCourse[end][:s] >= CS[:s_exit] || stateFlags[:endOfCSReached]
|
|
|
|
tractionSurplus = drivingCourse[end][:F_T] >= drivingCourse[end][:F_R]
|
|
|
|
tractionDeficit = drivingCourse[end][:F_T] < drivingCourse[end][:F_R] #|| stateFlags[:tractionDeficit]
|
|
|
|
|
|
|
|
|
|
|
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
|
|
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
|
|
|
brakingStartReached = drivingCourse[end][:s] + s_braking >= CS[:s_exit]
|
|
|
|
brakingStartReached = drivingCourse[end][:s] + s_braking >= CS[:s_exit] || stateFlags[:brakingStartReached]
|
|
|
|
|
|
|
|
|
|
|
|
# use the conditions for the diminishing section
|
|
|
|
# use the conditions for the diminishing section
|
|
|
|
if !tractionSurplus && !targetSpeedReached && !targetPositionReached
|
|
|
|
if tractionDeficit && !targetSpeedReached && !endOfCSReached
|
|
|
|
BS = createBehaviorSection("diminishing", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
|
|
|
|
BS = createBehaviorSection("diminishing", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
|
|
|
|
drivingCourse[end][:behavior] = BS[:type]
|
|
|
|
drivingCourse[end][:behavior] = BS[:type]
|
|
|
|
|
|
|
|
|
|
|
|
while !tractionSurplus && !targetSpeedReached && !targetPositionReached && !brakingStartReached
|
|
|
|
while tractionDeficit && !targetSpeedReached && !endOfCSReached && !brakingStartReached
|
|
|
|
currentStepSize=settings[:stepSize] # initialize the step size that can be reduced near intersections
|
|
|
|
currentStepSize=settings[:stepSize] # initialize the step size that can be reduced near intersections
|
|
|
|
nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])
|
|
|
|
nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])
|
|
|
|
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
|
|
|
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
|
|
|
|
|
|
|
|
|
|
|
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
|
|
|
|
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
|
|
|
|
while !tractionSurplus && !brakingStartReached && !pointOfInterestReached && !targetSpeedReached
|
|
|
|
while tractionDeficit && !brakingStartReached && !pointOfInterestReached && !targetSpeedReached
|
|
|
|
# 03/09 old: while drivingCourse[end][:F_T] < drivingCourse[end][:F_R] && !brakingStartReached && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:v]>0.0 # as long as s_i + s_braking < s_end
|
|
|
|
# 03/09 old: while drivingCourse[end][:F_T] < drivingCourse[end][:F_R] && !brakingStartReached && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:v]>0.0 # as long as s_i + s_braking < s_end
|
|
|
|
# acceleration (in m/s^2):
|
|
|
|
# acceleration (in m/s^2):
|
|
|
|
drivingCourse[end][:a] = calcAcceleration(drivingCourse[end][:F_T], drivingCourse[end][:F_R], train[:m_train], train[:Îľ_train])
|
|
|
|
drivingCourse[end][:a] = calcAcceleration(drivingCourse[end][:F_T], drivingCourse[end][:F_R], train[:m_train], train[:Îľ_train])
|
|
|
@ -729,7 +781,7 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
|
|
|
|
brakingStartReached = drivingCourse[end][:s] +s_braking >= CS[:s_exit]
|
|
|
|
brakingStartReached = drivingCourse[end][:s] +s_braking >= CS[:s_exit]
|
|
|
|
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
|
|
|
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
|
|
|
targetSpeedReached = drivingCourse[end][:v] <= 0.0
|
|
|
|
targetSpeedReached = drivingCourse[end][:v] <= 0.0
|
|
|
|
tractionSurplus = drivingCourse[end][:F_T] >= drivingCourse[end][:F_R]
|
|
|
|
tractionDeficit = drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
|
|
|
|
end #while
|
|
|
|
end #while
|
|
|
|
|
|
|
|
|
|
|
|
if CS[:id]==0
|
|
|
|
if CS[:id]==0
|
|
|
@ -790,7 +842,7 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
|
|
|
|
brakingStartReached = false
|
|
|
|
brakingStartReached = false
|
|
|
|
pointOfInterestReached = false
|
|
|
|
pointOfInterestReached = false
|
|
|
|
targetSpeedReached = false
|
|
|
|
targetSpeedReached = false
|
|
|
|
tractionSurplus = false
|
|
|
|
tractionDeficit = true
|
|
|
|
|
|
|
|
|
|
|
|
else # if the level of approximation is reached
|
|
|
|
else # if the level of approximation is reached
|
|
|
|
if drivingCourse[end][:v] <= 0.0
|
|
|
|
if drivingCourse[end][:v] <= 0.0
|
|
|
@ -807,7 +859,7 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
|
|
|
|
|
|
|
|
|
|
|
|
pointOfInterestReached = false
|
|
|
|
pointOfInterestReached = false
|
|
|
|
targetSpeedReached = false
|
|
|
|
targetSpeedReached = false
|
|
|
|
tractionSurplus = false
|
|
|
|
tractionDeficit = true
|
|
|
|
|
|
|
|
|
|
|
|
elseif drivingCourse[end][:s] > nextPointOfInterest
|
|
|
|
elseif drivingCourse[end][:s] > nextPointOfInterest
|
|
|
|
testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: s=", drivingCourse[end][:s]," > nextPointOfInterest=",nextPointOfInterest) # for testing
|
|
|
|
testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: s=", drivingCourse[end][:s]," > nextPointOfInterest=",nextPointOfInterest) # for testing
|
|
|
@ -830,7 +882,7 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
|
|
|
|
|
|
|
|
|
|
|
|
# TODO is it possible to put this into to the if-fork?
|
|
|
|
# TODO is it possible to put this into to the if-fork?
|
|
|
|
if drivingCourse[end][:s] == CS[:s_exit]
|
|
|
|
if drivingCourse[end][:s] == CS[:s_exit]
|
|
|
|
targetPositionReached = true
|
|
|
|
endOfCSReached = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end #if
|
|
|
|
end #if
|
|
|
|
end #for
|
|
|
|
end #for
|
|
|
@ -851,29 +903,37 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
return (CS, drivingCourse, brakingStartReached)
|
|
|
|
# set state flags
|
|
|
|
|
|
|
|
stateFlags[:endOfCSReached] = endOfCSReached
|
|
|
|
|
|
|
|
stateFlags[:brakingStartReached] = brakingStartReached
|
|
|
|
|
|
|
|
stateFlags[:tractionDeficit] = tractionDeficit
|
|
|
|
|
|
|
|
stateFlags[:resistingForceNegative] = drivingCourse[end][:F_R] < 0
|
|
|
|
|
|
|
|
stateFlags[:speedLimitReached] = drivingCourse[end][:v] >= CS[:v_exit]
|
|
|
|
|
|
|
|
stateFlags[:error] = !(endOfCSReached || brakingStartReached || !tractionDeficit)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (CS, drivingCourse, stateFlags)
|
|
|
|
end #function addDiminishingSection!
|
|
|
|
end #function addDiminishingSection!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## This function calculates the data points of the coasting section.
|
|
|
|
## This function calculates the data points of the coasting section.
|
|
|
|
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the coasting section
|
|
|
|
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the coasting section
|
|
|
|
function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict})
|
|
|
|
function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, settings::Dict, train::Dict, 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
|
|
|
|
# TODO: if the rear of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
|
|
|
|
# with getCurrentSpeedLimit
|
|
|
|
# with getCurrentSpeedLimit
|
|
|
|
|
|
|
|
|
|
|
|
# conditions for coasting section
|
|
|
|
# conditions for coasting section
|
|
|
|
targetSpeedReached = drivingCourse[end][:v] <= CS[:v_exit]
|
|
|
|
targetSpeedReached = drivingCourse[end][:v] <= CS[:v_exit]
|
|
|
|
targetPositionReached = drivingCourse[end][:s] >= CS[:s_exit]
|
|
|
|
endOfCSReached = drivingCourse[end][:s] >= CS[:s_exit] || stateFlags[:endOfCSReached]
|
|
|
|
|
|
|
|
|
|
|
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
|
|
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
|
|
|
brakingStartReached = drivingCourse[end][:s] + s_braking >= CS[:s_exit]
|
|
|
|
brakingStartReached = drivingCourse[end][:s] + s_braking >= CS[:s_exit] || stateFlags[:brakingStartReached]
|
|
|
|
|
|
|
|
|
|
|
|
# use the conditions for the coasting section
|
|
|
|
# use the conditions for the coasting section
|
|
|
|
if !targetSpeedReached && !targetPositionReached
|
|
|
|
if !targetSpeedReached && !endOfCSReached
|
|
|
|
BS = createBehaviorSection("coasting", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
|
|
|
|
BS = createBehaviorSection("coasting", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
|
|
|
|
drivingCourse[end][:behavior] = BS[:type]
|
|
|
|
drivingCourse[end][:behavior] = BS[:type]
|
|
|
|
|
|
|
|
|
|
|
|
while !targetSpeedReached && !targetPositionReached && !brakingStartReached
|
|
|
|
while !targetSpeedReached && !endOfCSReached && !brakingStartReached
|
|
|
|
currentStepSize=settings[:stepSize] # initialize the step size that can be reduced near intersections
|
|
|
|
currentStepSize=settings[:stepSize] # initialize the step size that can be reduced near intersections
|
|
|
|
nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])
|
|
|
|
nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])
|
|
|
|
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
|
|
|
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
|
|
@ -967,20 +1027,20 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Di
|
|
|
|
pop!(drivingCourse)
|
|
|
|
pop!(drivingCourse)
|
|
|
|
pop!(BS[:dataPoints])
|
|
|
|
pop!(BS[:dataPoints])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# conditions for the next for cycle
|
|
|
|
|
|
|
|
brakingStartReached = false
|
|
|
|
|
|
|
|
pointOfInterestReached = false
|
|
|
|
|
|
|
|
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
|
|
|
|
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 data point because it went to far
|
|
|
|
pop!(drivingCourse)
|
|
|
|
pop!(drivingCourse)
|
|
|
|
pop!(BS[:dataPoints])
|
|
|
|
pop!(BS[:dataPoints])
|
|
|
|
|
|
|
|
|
|
|
|
# while coasting the train brakes to hold v_peak (only one data point in the end of coasting is calculated like cruising at v_peak)
|
|
|
|
# conditions for the next for cycle
|
|
|
|
drivingCourse[end][:a] = 0.0
|
|
|
|
brakingStartReached = false
|
|
|
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
|
|
|
pointOfInterestReached = false
|
|
|
|
|
|
|
|
targetSpeedReached = true
|
|
|
|
# recalculate s, t, v, E
|
|
|
|
|
|
|
|
s_constantCoasting = min(currentStepSize, CS[:s_exit] - (drivingCourse[end-1][:s] + s_braking)) # TODO: if settings[:stepVariable]=="s in m"
|
|
|
|
|
|
|
|
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], s_constantCoasting, CS[:id]))
|
|
|
|
|
|
|
|
drivingCourse[end][:behavior] = BS[:type]
|
|
|
|
|
|
|
|
push!(BS[:dataPoints], drivingCourse[end][:i])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
elseif drivingCourse[end][:s] > nextPointOfInterest
|
|
|
|
elseif drivingCourse[end][:s] > nextPointOfInterest
|
|
|
|
drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
|
|
|
|
drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
|
|
|
@ -992,6 +1052,8 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Di
|
|
|
|
end #for
|
|
|
|
end #for
|
|
|
|
end #while
|
|
|
|
end #while
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stateFlags[:speedLimitReached] = false
|
|
|
|
|
|
|
|
|
|
|
|
# calculate the accumulated coasting section information
|
|
|
|
# calculate the accumulated coasting section information
|
|
|
|
merge!(BS, Dict(:length => drivingCourse[end][:s] - BS[:s_entry], # total length (in m)
|
|
|
|
merge!(BS, Dict(:length => drivingCourse[end][:s] - BS[:s_entry], # total length (in m)
|
|
|
|
:s_exit => drivingCourse[end][:s], # last position (in m)
|
|
|
|
:s_exit => drivingCourse[end][:s], # last position (in m)
|
|
|
@ -1005,29 +1067,36 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Di
|
|
|
|
merge!(CS[:behaviorSections], Dict(:coasting=>BS))
|
|
|
|
merge!(CS[:behaviorSections], Dict(:coasting=>BS))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
return (CS, drivingCourse, brakingStartReached)
|
|
|
|
# set state flags
|
|
|
|
|
|
|
|
stateFlags[:endOfCSReached] = endOfCSReached
|
|
|
|
|
|
|
|
stateFlags[:brakingStartReached] = brakingStartReached
|
|
|
|
|
|
|
|
stateFlags[:tractionDeficit] = drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
|
|
|
|
|
|
|
|
stateFlags[:resistingForceNegative] = drivingCourse[end][:F_R] < 0
|
|
|
|
|
|
|
|
stateFlags[:error] = !(endOfCSReached || brakingStartReached || stateFlags[:tractionDeficit] || previousSpeedLimitReached || targetSpeedReached)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (CS, drivingCourse, stateFlags)
|
|
|
|
end #function addCoastingSection!
|
|
|
|
end #function addCoastingSection!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## This function calculates the data points of the braking section.
|
|
|
|
## 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.
|
|
|
|
# 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})
|
|
|
|
function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, settings::Dict, train::Dict, CSs::Vector{Dict})
|
|
|
|
# conditions for braking section
|
|
|
|
# conditions for braking section
|
|
|
|
targetSpeedReached = drivingCourse[end][:v] <= CS[:v_exit]
|
|
|
|
targetSpeedReached = drivingCourse[end][:v] <= CS[:v_exit]
|
|
|
|
targetPositionReached = drivingCourse[end][:s] >= CS[:s_exit]
|
|
|
|
endOfCSReached = drivingCourse[end][:s] >= CS[:s_exit] || stateFlags[:endOfCSReached]
|
|
|
|
|
|
|
|
|
|
|
|
# use the conditions for the braking section
|
|
|
|
# use the conditions for the braking section
|
|
|
|
if !targetSpeedReached && !targetPositionReached
|
|
|
|
if !targetSpeedReached && !endOfCSReached
|
|
|
|
BS = createBehaviorSection("braking", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
|
|
|
|
BS = createBehaviorSection("braking", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
|
|
|
|
drivingCourse[end][:behavior] = BS[:type]
|
|
|
|
drivingCourse[end][:behavior] = BS[:type]
|
|
|
|
|
|
|
|
|
|
|
|
while !targetSpeedReached && !targetPositionReached
|
|
|
|
while !targetSpeedReached && !endOfCSReached
|
|
|
|
currentStepSize = settings[:stepSize] # initialize the step size that can be reduced near intersections
|
|
|
|
currentStepSize = settings[:stepSize] # initialize the step size that can be reduced near intersections
|
|
|
|
nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])
|
|
|
|
nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])
|
|
|
|
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
|
|
|
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
|
|
|
|
|
|
|
|
|
|
|
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
|
|
|
|
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
|
|
|
|
while !targetSpeedReached && !targetPositionReached && !pointOfInterestReached
|
|
|
|
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
|
|
|
|
# 03/09 old: 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):
|
|
|
|
# traction effort and resisting forces (in N):
|
|
|
|
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
|
|
|
|
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
|
|
|
@ -1053,7 +1122,7 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic
|
|
|
|
|
|
|
|
|
|
|
|
# conditions for the next while cycle
|
|
|
|
# conditions for the next while cycle
|
|
|
|
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
|
|
|
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
|
|
|
targetPositionReached = drivingCourse[end][:s] >= CS[:s_exit]
|
|
|
|
endOfCSReached = drivingCourse[end][:s] >= CS[:s_exit]
|
|
|
|
targetSpeedReached = drivingCourse[end][:v] <= CS[:v_exit]
|
|
|
|
targetSpeedReached = drivingCourse[end][:v] <= CS[:v_exit]
|
|
|
|
end # while
|
|
|
|
end # while
|
|
|
|
|
|
|
|
|
|
|
@ -1076,7 +1145,7 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic
|
|
|
|
break
|
|
|
|
break
|
|
|
|
elseif drivingCourse[end][:v] == CS[:v_exit]
|
|
|
|
elseif drivingCourse[end][:v] == CS[:v_exit]
|
|
|
|
recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
|
|
|
recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
|
|
|
targetPositionReached = true
|
|
|
|
endOfCSReached = true
|
|
|
|
# println(" with a=", drivingCourse[end-1][:a]) # for testing
|
|
|
|
# println(" with a=", drivingCourse[end-1][:a]) # for testing
|
|
|
|
break
|
|
|
|
break
|
|
|
|
elseif drivingCourse[end][:s] == CS[:s_exit]
|
|
|
|
elseif drivingCourse[end][:s] == CS[:s_exit]
|
|
|
@ -1095,7 +1164,7 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic
|
|
|
|
|
|
|
|
|
|
|
|
# conditions for the next for cycle
|
|
|
|
# conditions for the next for cycle
|
|
|
|
pointOfInterestReached = false
|
|
|
|
pointOfInterestReached = false
|
|
|
|
targetPositionReached = false
|
|
|
|
endOfCSReached = false
|
|
|
|
targetSpeedReached = false
|
|
|
|
targetSpeedReached = false
|
|
|
|
|
|
|
|
|
|
|
|
else # if the level of approximation is reached
|
|
|
|
else # if the level of approximation is reached
|
|
|
@ -1104,8 +1173,7 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic
|
|
|
|
# reset last point with setting v=v_exit
|
|
|
|
# reset last point with setting v=v_exit
|
|
|
|
# println("during braking section in CS",CS[:id],": rounding v up from ", drivingCourse[end][:v] ," to ", CS[:v_exit]) # for testing
|
|
|
|
# println("during braking section in CS",CS[:id],": rounding v up from ", drivingCourse[end][:v] ," to ", CS[:v_exit]) # for testing
|
|
|
|
recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], 0.0)
|
|
|
|
recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], 0.0)
|
|
|
|
targetPositionReached = true
|
|
|
|
endOfCSReached = true
|
|
|
|
# println(" with a=", drivingCourse[end-1][:a]) # for testing
|
|
|
|
|
|
|
|
break
|
|
|
|
break
|
|
|
|
elseif drivingCourse[end][:s] > CS[:s_exit]
|
|
|
|
elseif drivingCourse[end][:s] > CS[:s_exit]
|
|
|
|
# println("during braking section in CS",CS[:id],": rounding s down from ", drivingCourse[end][:s] ," to ", CS[:s_exit]) # for testing
|
|
|
|
# println("during braking section in CS",CS[:id],": rounding s down from ", drivingCourse[end][:s] ," to ", CS[:s_exit]) # for testing
|
|
|
@ -1122,20 +1190,17 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic
|
|
|
|
# reset last point with setting v=v_exit
|
|
|
|
# reset last point with setting v=v_exit
|
|
|
|
# println("during braking section in CS",CS[:id],": rounding s up from ", drivingCourse[end][:s] ," to ", CS[:s_exit]) # for testing
|
|
|
|
# println("during braking section in CS",CS[:id],": rounding s up from ", drivingCourse[end][:s] ," to ", CS[:s_exit]) # for testing
|
|
|
|
recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
|
|
|
recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
|
|
|
targetPositionReached = true
|
|
|
|
endOfCSReached = true
|
|
|
|
# println(" with a=", drivingCourse[end-1][:a]) # for testing
|
|
|
|
|
|
|
|
break
|
|
|
|
break
|
|
|
|
elseif drivingCourse[end][:v] == CS[:v_exit]
|
|
|
|
elseif drivingCourse[end][:v] == CS[:v_exit]
|
|
|
|
# println("during braking section in CS",CS[:id],": rounding s up from ", drivingCourse[end][:s] ," to ", CS[:s_exit]) # for testing
|
|
|
|
# println("during braking section in CS",CS[:id],": rounding s up from ", drivingCourse[end][:s] ," to ", CS[:s_exit]) # for testing
|
|
|
|
recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
|
|
|
recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
|
|
|
targetPositionReached = true
|
|
|
|
endOfCSReached = true
|
|
|
|
# println(" with a=", drivingCourse[end-1][:a]) # for testing
|
|
|
|
|
|
|
|
break
|
|
|
|
break
|
|
|
|
elseif drivingCourse[end][:s] == CS[:s_exit]
|
|
|
|
elseif drivingCourse[end][:s] == CS[:s_exit]
|
|
|
|
# println("during braking section in CS",CS[:id],": rounding v down from ", drivingCourse[end][:v] ," to ", CS[:v_exit]) # for testing
|
|
|
|
# println("during braking section in CS",CS[:id],": rounding v down from ", drivingCourse[end][:v] ," to ", CS[:v_exit]) # for testing
|
|
|
|
recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
|
|
|
recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
|
|
|
targetSpeedReached = true
|
|
|
|
targetSpeedReached = true
|
|
|
|
# println(" with a=", drivingCourse[end-1][:a]) # for testing
|
|
|
|
|
|
|
|
break
|
|
|
|
break
|
|
|
|
else
|
|
|
|
else
|
|
|
|
# do nothing for example for drivingCourse[end][:s]==nextPointOfInterest
|
|
|
|
# do nothing for example for drivingCourse[end][:s]==nextPointOfInterest
|
|
|
@ -1157,7 +1222,16 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic
|
|
|
|
merge!(CS[:behaviorSections], Dict(:braking=>BS))
|
|
|
|
merge!(CS[:behaviorSections], Dict(:braking=>BS))
|
|
|
|
end # else: return the characteristic section without a braking section
|
|
|
|
end # else: return the characteristic section without a braking section
|
|
|
|
|
|
|
|
|
|
|
|
return (CS, drivingCourse)
|
|
|
|
# set state flags
|
|
|
|
|
|
|
|
currentSpeedLimit = getCurrentSpeedLimit(CSs, CS[:id], drivingCourse[end][:s], train[:length])
|
|
|
|
|
|
|
|
stateFlags[:previousSpeedLimitReached] = currentSpeedLimit[:v] != CS[:v_limit] && drivingCourse[end][:v] >= currentSpeedLimit[:v]
|
|
|
|
|
|
|
|
stateFlags[:speedLimitReached] = drivingCourse[end][:v] >= CS[:v_exit]
|
|
|
|
|
|
|
|
stateFlags[:endOfCSReached] = endOfCSReached
|
|
|
|
|
|
|
|
stateFlags[:error] = !(endOfCSReached)
|
|
|
|
|
|
|
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "default", train, settings[:massModel])
|
|
|
|
|
|
|
|
stateFlags[:resistingForceNegative] = drivingCourse[end][:F_R] < 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (CS, drivingCourse, stateFlags)
|
|
|
|
end #function addBrakingSection!
|
|
|
|
end #function addBrakingSection!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -1190,14 +1264,14 @@ function mergeBehaviorSection!(BSs::Dict, BS::Dict)
|
|
|
|
number = string(parse(Int, number)+1)
|
|
|
|
number = string(parse(Int, number)+1)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
merge!(BSs, Dict(Symbol(BS[:type]*number) => BS))
|
|
|
|
merge!(BSs, Dict(Symbol(BS[:type]*number) => BS))
|
|
|
|
println("INFO: The ",number,". ",BS[:type]," section has been created. ! ! ! ! ! ! ! ! !")
|
|
|
|
# println("INFO: The ",number,". ",BS[:type]," section has been created. ! ! ! ! ! ! ! ! !")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return BSs
|
|
|
|
return BSs
|
|
|
|
end #function mergeBehaviorSection!
|
|
|
|
end #function mergeBehaviorSection!
|
|
|
|
|
|
|
|
|
|
|
|
function createBehaviorSection(type::String, s_entry::Real, v_entry::Real, startingPoint::Integer)
|
|
|
|
function createBehaviorSection(type::String, s_entry::Real, v_entry::Real, startingPoint::Integer)
|
|
|
|
BS= Dict(#:type => behavior, # type of behavior section: breakFree, clearing, accelerating, cruising, diminishing, coasting, braking or standstill
|
|
|
|
BS= Dict(#:type => behavior, # type of behavior section: breakFree, clearing, accelerating, cruising, diminishing, coasting, braking or standstill
|
|
|
|
:type => type, # type of behavior section: "breakFree", "clearing", "accelerating", "cruising", "diminishing", "coasting", "braking" or "standstill"
|
|
|
|
:type => type, # type of behavior section: "breakFree", "clearing", "accelerating", "cruising", "downhillBraking", "diminishing", "coasting", "braking" or "standstill"
|
|
|
|
:length => 0.0, # total length (in m)
|
|
|
|
:length => 0.0, # total length (in m)
|
|
|
|
:s_entry => s_entry, # first position (in m)
|
|
|
|
:s_entry => s_entry, # first position (in m)
|
|
|
|
:s_exit => 0.0, # last position (in m)
|
|
|
|
:s_exit => 0.0, # last position (in m)
|
|
|
|