Fix mass model "homogeneous strip" for distance and time step methods
parent
7d56c707c1
commit
2983b2c2e1
|
@ -0,0 +1,12 @@
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
settings:
|
||||||
|
# settings for the simulation
|
||||||
|
massModel: "homogeneous strip" # model type of train mass "mass point" or "homogeneous strip"
|
||||||
|
stepVariable: "s in m" # step variable of the step method "s in m", "t in s" or "v in m/s"
|
||||||
|
stepSize: 10 # step size (unit depends on stepVariable s in m, t in s and v in m/s)
|
||||||
|
operationModeMinimumRunningTime: true # operation mode "minimum running time"
|
||||||
|
operationModeMinimumEnergyConsumption: false # operation mode "minimum energy consumption"
|
||||||
|
typeOfOutput: "julia dictionary" # output as "julia dictionary" or as "CSV"
|
||||||
|
detailOfOutput: "driving course" # should the output be "minimal", "points of interest" or "driving course"?
|
||||||
|
csvDirectory: "~/Desktop/TrainRun"
|
|
@ -0,0 +1,12 @@
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
settings:
|
||||||
|
# settings for the simulation
|
||||||
|
massModel: "homogeneous strip" # model type of train mass "mass point" or "homogeneous strip"
|
||||||
|
stepVariable: "t in s" # step variable of the step method "s in m", "t in s" or "v in m/s"
|
||||||
|
stepSize: 3.0 # step size (unit depends on stepVariable s in m, t in s and v in m/s)
|
||||||
|
operationModeMinimumRunningTime: true # operation mode "minimum running time"
|
||||||
|
operationModeMinimumEnergyConsumption: false # operation mode "minimum energy consumption"
|
||||||
|
typeOfOutput: "julia dictionary" # output as "julia dictionary" or as "CSV"
|
||||||
|
detailOfOutput: "driving course" # should the output be "minimal", "points of interest" or "driving course"?
|
||||||
|
csvDirectory: "~/Desktop/TrainRun"
|
130
src/Behavior.jl
130
src/Behavior.jl
|
@ -15,7 +15,7 @@ export addBreakFreeSection!, addClearingSection!, addAcceleratingSection!, addCr
|
||||||
calculateForces!, createDataPoint,
|
calculateForces!, createDataPoint,
|
||||||
|
|
||||||
# export functions from DrivingDynamics
|
# export functions from DrivingDynamics
|
||||||
calcBrakingDistance, calcBrakingStartVelocity
|
calcBrakingDistance, calcBrakingStartVelocity, calc_Δs_with_Δt
|
||||||
|
|
||||||
|
|
||||||
approximationLevel = 6 # value for approximation to intersections TODO further explanation (e.g. approximationLevel = 3 -> with stepSize 10 m the approximation will be calculated accurate on 10 mm ; 1s -> 1 ms; 1 km/h -> 3.6 mm/s)
|
approximationLevel = 6 # value for approximation to intersections TODO further explanation (e.g. approximationLevel = 3 -> with stepSize 10 m the approximation will be calculated accurate on 10 mm ; 1s -> 1 ms; 1 km/h -> 3.6 mm/s)
|
||||||
|
@ -552,46 +552,75 @@ 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}, stateFlags::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)
|
||||||
|
trainIsClearing = cruisingType == "clearing"
|
||||||
|
trainIsBrakingDownhill = cruisingType == "downhillBraking"
|
||||||
|
|
||||||
# traction effort and resisting forces (in N)
|
# traction effort and resisting forces (in N)
|
||||||
calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
|
if !trainIsBrakingDownhill # TODO: or just give BS[:type] instead of "cruising"/"braking"?
|
||||||
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
|
||||||
|
else
|
||||||
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "braking", train, settings[:massModel])
|
||||||
|
end
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
# 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] || stateFlags[:brakingStartReached]
|
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]
|
||||||
tractionDeficit = drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
|
tractionDeficit = drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
|
||||||
targetPositionReached = s_cruising == 0.0
|
targetPositionReached = s_cruising == 0.0
|
||||||
|
resistingForceNegative = drivingCourse[end][:F_R] < 0
|
||||||
|
#println(" vor if speedIsValid=",speedIsValid ," brakingStartReached=", brakingStartReached," tractionDeficit=", tractionDeficit," targetPositionReached=", targetPositionReached)
|
||||||
|
|
||||||
if speedIsValid && !brakingStartReached && !tractionDeficit && !targetPositionReached
|
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])
|
||||||
|
|
||||||
# traction effort and resisting forces (in N)
|
# traction effort and resisting forces (in N)
|
||||||
calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel]) # TODO: or give BS[:type] instead of "cruising"?
|
#03/25 calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
|
||||||
|
if !trainIsBrakingDownhill
|
||||||
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
|
||||||
|
else
|
||||||
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "braking", train, settings[:massModel])
|
||||||
|
end
|
||||||
|
|
||||||
if settings[:massModel]=="homogeneous strip" && CS[:id] > 1
|
if settings[:massModel]=="homogeneous strip" && CS[:id] > 1
|
||||||
# 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
|
resistingForceNegative = drivingCourse[end][:F_R] < 0.0
|
||||||
|
# targetSpeedReached = stateFlags[:speedLimitReached] || drivingCourse[end][:v] >= CS[:v_peak]
|
||||||
# TODO: change? to correctCruisingType = (trainIsClearing || (trainIsBrakingDownhill == drivingCourse[end][:F_R] < 0)) # while clearing tractive or braking force can be used
|
# TODO: change? to correctCruisingType = (trainIsClearing || (trainIsBrakingDownhill == drivingCourse[end][:F_R] < 0)) # while clearing tractive or braking force can be used
|
||||||
|
#&& targetSpeedReached
|
||||||
# use the conditions for the cruising section
|
# use the conditions for the cruising section
|
||||||
while trainInPreviousCS && !targetPositionReached && !tractionDeficit && (trainIsClearing || (trainIsBrakingDownhill == resistingForceNegative)) # while clearing tractive or braking force can be used
|
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])
|
||||||
|
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 trainInPreviousCS && targetPositionReached && !pointOfInterestReached && !tractionDeficit && (trainIsClearing || (trainIsBrakingDownhill == resistingForceNegative)) # while clearing tractive or braking force can be used
|
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?
|
||||||
|
# tractive effort (in N):
|
||||||
|
#03/25 drivingCourse[end][:F_T] = min(drivingCourse[end][:F_T], max(0.0, drivingCourse[end][:F_R]))
|
||||||
|
if !trainIsBrakingDownhill
|
||||||
|
drivingCourse[end][:F_T] = min(drivingCourse[end][:F_T], max(0.0, drivingCourse[end][:F_R]))
|
||||||
|
else
|
||||||
|
drivingCourse[end][:F_T] = 0.0
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
# acceleration (in m/s^2):
|
# acceleration (in m/s^2):
|
||||||
drivingCourse[end][:a] = 0.0
|
drivingCourse[end][:a] = 0.0
|
||||||
|
@ -606,7 +635,13 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::
|
||||||
push!(BS[:dataPoints], drivingCourse[end][:i])
|
push!(BS[:dataPoints], drivingCourse[end][:i])
|
||||||
|
|
||||||
# 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], "default", train, settings[:massModel])
|
||||||
|
# calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
|
||||||
|
#if !trainIsBrakingDownhill
|
||||||
|
# calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
|
||||||
|
#else
|
||||||
|
# calculateForces!(drivingCourse[end], CSs, CS[:id], "braking", train, settings[:massModel])
|
||||||
|
#end
|
||||||
|
|
||||||
# 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
|
||||||
|
@ -621,7 +656,10 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::
|
||||||
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
|
elseif !trainIsBrakingDownhill && resistingForceNegative
|
||||||
|
currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||||
|
|
||||||
|
elseif trainIsBrakingDownhill && !resistingForceNegative
|
||||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
currentStepSize = settings[:stepSize] / 10.0^cycle
|
||||||
|
|
||||||
elseif drivingCourse[end][:s] > nextPointOfInterest
|
elseif drivingCourse[end][:s] > nextPointOfInterest
|
||||||
|
@ -647,7 +685,10 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::
|
||||||
elseif drivingCourse[end][:s] == nextPointOfInterest
|
elseif drivingCourse[end][:s] == nextPointOfInterest
|
||||||
break
|
break
|
||||||
|
|
||||||
else # TODO copied from addAcceleratingSection -> probably not needed here !?
|
elseif !trainInPreviousCS
|
||||||
|
break
|
||||||
|
|
||||||
|
else
|
||||||
error("ERROR at cruising section: With the step variable ",settings[:stepVariable]," the while loop will be left although the if cases don't apply in CS",CS[:id]," with s=" ,drivingCourse[end][:s]," m and v=",drivingCourse[end][:v]," m/s")
|
error("ERROR at cruising section: With the step variable ",settings[:stepVariable]," the while loop will be left although the if cases don't apply in CS",CS[:id]," with s=" ,drivingCourse[end][:s]," m and v=",drivingCourse[end][:v]," m/s")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -660,6 +701,7 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::
|
||||||
tractionDeficit = false
|
tractionDeficit = false
|
||||||
targetPositionReached = false
|
targetPositionReached = false
|
||||||
trainInPreviousCS = true
|
trainInPreviousCS = true
|
||||||
|
resistingForceNegative = drivingCourse[end][:F_R] < 0.0
|
||||||
|
|
||||||
else # if the level of approximation is reached
|
else # if the level of approximation is reached
|
||||||
if drivingCourse[end][:s] > nextPointOfInterest
|
if drivingCourse[end][:s] > nextPointOfInterest
|
||||||
|
@ -674,8 +716,13 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::
|
||||||
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
|
elseif !trainIsBrakingDownhill && resistingForceNegative
|
||||||
break
|
break
|
||||||
|
elseif trainIsBrakingDownhill && !resistingForceNegative
|
||||||
|
break
|
||||||
|
elseif !trainInPreviousCS
|
||||||
|
break
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -692,6 +739,17 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::
|
||||||
while !targetPositionReached && !tractionDeficit && (trainIsClearing || (trainIsBrakingDownhill == resistingForceNegative)) # while clearing tractive or braking force can be used
|
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]))
|
||||||
|
|
||||||
|
# tractive effort (in N):
|
||||||
|
#03/25 drivingCourse[end][:F_T] = min(drivingCourse[end][:F_T], max(0.0, drivingCourse[end][:F_R]))
|
||||||
|
if !trainIsBrakingDownhill
|
||||||
|
drivingCourse[end][:F_T] = min(drivingCourse[end][:F_T], max(0.0, drivingCourse[end][:F_R]))
|
||||||
|
else
|
||||||
|
drivingCourse[end][:F_T] = 0.0
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
drivingCourse[end][:a] = 0.0 # acceleration (in m/s^2)
|
drivingCourse[end][:a] = 0.0 # acceleration (in m/s^2)
|
||||||
|
|
||||||
# calculate the remaining cruising way
|
# calculate the remaining cruising way
|
||||||
|
@ -703,7 +761,13 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::
|
||||||
drivingCourse[end][:behavior] = BS[:type]
|
drivingCourse[end][:behavior] = BS[:type]
|
||||||
push!(BS[:dataPoints], drivingCourse[end][:i])
|
push!(BS[:dataPoints], drivingCourse[end][:i])
|
||||||
|
|
||||||
calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "default", train, settings[:massModel])
|
||||||
|
# calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
|
||||||
|
#if !trainIsBrakingDownhill
|
||||||
|
# calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
|
||||||
|
#else
|
||||||
|
# calculateForces!(drivingCourse[end], CSs, CS[:id], "braking", train, settings[:massModel])
|
||||||
|
#end
|
||||||
|
|
||||||
# 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
|
||||||
|
@ -712,8 +776,7 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::
|
||||||
end #while
|
end #while
|
||||||
|
|
||||||
# TODO: realize this better inside the upper loops?
|
# TODO: realize this better inside the upper loops?
|
||||||
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
|
||||||
brakingStartReached = drivingCourse[end][:s] + s_braking >= CS[:s_exit]
|
|
||||||
|
|
||||||
# calculate the accumulated cruising section information
|
# calculate the accumulated cruising 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)
|
||||||
|
@ -730,7 +793,9 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::
|
||||||
|
|
||||||
# set state flags
|
# set state flags
|
||||||
stateFlags[:endOfCSReached] = drivingCourse[end][:s] == CS[:s_exit]
|
stateFlags[:endOfCSReached] = drivingCourse[end][:s] == CS[:s_exit]
|
||||||
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
if !ignoreBraking
|
||||||
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
||||||
|
end
|
||||||
stateFlags[:brakingStartReached] = brakingStartReached || drivingCourse[end][:s] + s_braking >= CS[:s_exit]
|
stateFlags[:brakingStartReached] = brakingStartReached || drivingCourse[end][:s] + s_braking >= CS[:s_exit]
|
||||||
stateFlags[:tractionDeficit] = tractionDeficit
|
stateFlags[:tractionDeficit] = tractionDeficit
|
||||||
stateFlags[:resistingForceNegative] = drivingCourse[end][:F_R] < 0.0
|
stateFlags[:resistingForceNegative] = drivingCourse[end][:F_R] < 0.0
|
||||||
|
@ -746,11 +811,19 @@ end #function addCruisingSection!
|
||||||
function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::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])
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
# conditions for diminishing section
|
# conditions for diminishing section
|
||||||
targetSpeedReached = drivingCourse[end][:v] <= 0.0
|
targetSpeedReached = drivingCourse[end][:v] <= 0.0
|
||||||
endOfCSReached = drivingCourse[end][:s] >= CS[:s_exit] || stateFlags[:endOfCSReached]
|
endOfCSReached = drivingCourse[end][:s] >= CS[:s_exit] || stateFlags[:endOfCSReached]
|
||||||
tractionDeficit = drivingCourse[end][:F_T] < drivingCourse[end][:F_R] #|| stateFlags[:tractionDeficit]
|
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] || stateFlags[:brakingStartReached]
|
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
|
||||||
|
@ -777,11 +850,14 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlag
|
||||||
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
|
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
|
||||||
|
|
||||||
# conditions for the next while cycle
|
# conditions for the next while cycle
|
||||||
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
if !ignoreBraking
|
||||||
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
||||||
|
end
|
||||||
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
|
||||||
tractionDeficit = drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
|
tractionDeficit = drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
|
||||||
|
endOfCSReached = drivingCourse[end][:s] == CS[:s_exit]
|
||||||
end #while
|
end #while
|
||||||
|
|
||||||
if CS[:id]==0
|
if CS[:id]==0
|
||||||
|
@ -843,6 +919,7 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlag
|
||||||
pointOfInterestReached = false
|
pointOfInterestReached = false
|
||||||
targetSpeedReached = false
|
targetSpeedReached = false
|
||||||
tractionDeficit = true
|
tractionDeficit = true
|
||||||
|
endOfCSReached = false
|
||||||
|
|
||||||
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
|
||||||
|
@ -860,6 +937,7 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlag
|
||||||
pointOfInterestReached = false
|
pointOfInterestReached = false
|
||||||
targetSpeedReached = false
|
targetSpeedReached = false
|
||||||
tractionDeficit = true
|
tractionDeficit = true
|
||||||
|
endOfCSReached = false
|
||||||
|
|
||||||
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
|
||||||
|
@ -880,10 +958,10 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlag
|
||||||
# end
|
# end
|
||||||
end #if
|
end #if
|
||||||
|
|
||||||
# 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]
|
||||||
endOfCSReached = true
|
# endOfCSReached = true
|
||||||
end
|
# end
|
||||||
end #if
|
end #if
|
||||||
end #for
|
end #for
|
||||||
end #while
|
end #while
|
||||||
|
@ -908,7 +986,7 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlag
|
||||||
stateFlags[:brakingStartReached] = brakingStartReached
|
stateFlags[:brakingStartReached] = brakingStartReached
|
||||||
stateFlags[:tractionDeficit] = tractionDeficit
|
stateFlags[:tractionDeficit] = tractionDeficit
|
||||||
stateFlags[:resistingForceNegative] = drivingCourse[end][:F_R] < 0
|
stateFlags[:resistingForceNegative] = drivingCourse[end][:F_R] < 0
|
||||||
stateFlags[:speedLimitReached] = drivingCourse[end][:v] >= CS[:v_exit]
|
stateFlags[:speedLimitReached] = drivingCourse[end][:v] >= CS[:v_peak]
|
||||||
stateFlags[:error] = !(endOfCSReached || brakingStartReached || !tractionDeficit)
|
stateFlags[:error] = !(endOfCSReached || brakingStartReached || !tractionDeficit)
|
||||||
|
|
||||||
return (CS, drivingCourse, stateFlags)
|
return (CS, drivingCourse, stateFlags)
|
||||||
|
@ -1028,7 +1106,7 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::
|
||||||
pop!(BS[:dataPoints])
|
pop!(BS[:dataPoints])
|
||||||
|
|
||||||
# conditions for the next for cycle
|
# conditions for the next for cycle
|
||||||
brakingStartReached = false
|
# brakingStartReached = true
|
||||||
pointOfInterestReached = false
|
pointOfInterestReached = false
|
||||||
targetSpeedReached = false
|
targetSpeedReached = false
|
||||||
|
|
||||||
|
@ -1040,7 +1118,7 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::
|
||||||
# conditions for the next for cycle
|
# conditions for the next for cycle
|
||||||
brakingStartReached = false
|
brakingStartReached = false
|
||||||
pointOfInterestReached = false
|
pointOfInterestReached = false
|
||||||
targetSpeedReached = true
|
# targetSpeedReached = true
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -17,7 +17,7 @@ function determineCharacteristics(path::Dict, train::Dict, settings::Dict)
|
||||||
movingSection = createMovingSection(path, train[:v_limit])
|
movingSection = createMovingSection(path, train[:v_limit])
|
||||||
movingSection = secureBrakingBehavior!(movingSection, train[:a_braking])
|
movingSection = secureBrakingBehavior!(movingSection, train[:a_braking])
|
||||||
movingSection = secureAcceleratingBehavior!(movingSection, settings, train)
|
movingSection = secureAcceleratingBehavior!(movingSection, settings, train)
|
||||||
movingSection = secureCruisingBehavior!(movingSection, settings, train)
|
#movingSection = secureCruisingBehavior!(movingSection, settings, train)
|
||||||
|
|
||||||
return movingSection
|
return movingSection
|
||||||
end #function determineCharacteristics
|
end #function determineCharacteristics
|
||||||
|
@ -149,17 +149,28 @@ function secureAcceleratingBehavior!(movingSection::Dict, settings::Dict, train:
|
||||||
:speedLimitReached => false,
|
:speedLimitReached => false,
|
||||||
:error => false,
|
:error => false,
|
||||||
:usedForDefiningCharacteristics => true) # because usedForDefiningCharacteristics == true the braking distance will be ignored during securing the accelerating phase
|
:usedForDefiningCharacteristics => true) # because usedForDefiningCharacteristics == true the braking distance will be ignored during securing the accelerating phase
|
||||||
|
v_peak = CS[:v_entry]
|
||||||
(CS, acceleratingCourse, stateFlags) = addBreakFreeSection!(CS, acceleratingCourse, stateFlags, settings, train, CSs)
|
(CS, acceleratingCourse, stateFlags) = addBreakFreeSection!(CS, acceleratingCourse, stateFlags, settings, train, CSs)
|
||||||
while !stateFlags[:speedLimitReached] && !stateFlags[:endOfCSReached] && !stateFlags[:tractionDeficit]
|
while !stateFlags[:speedLimitReached] && !stateFlags[:endOfCSReached]
|
||||||
if !stateFlags[:previousSpeedLimitReached]
|
if !stateFlags[:tractionDeficit]
|
||||||
|
if !stateFlags[:previousSpeedLimitReached]
|
||||||
(CS, acceleratingCourse, stateFlags) = addAcceleratingSection!(CS, acceleratingCourse, stateFlags, settings, train, CSs) # this function changes the acceleratingCourse
|
(CS, acceleratingCourse, stateFlags) = addAcceleratingSection!(CS, acceleratingCourse, stateFlags, settings, train, CSs) # this function changes the acceleratingCourse
|
||||||
|
|
||||||
elseif stateFlags[:previousSpeedLimitReached]
|
elseif stateFlags[:previousSpeedLimitReached]
|
||||||
(CS, acceleratingCourse, stateFlags) = addClearingSection!(CS, acceleratingCourse, stateFlags, settings, train, CSs)
|
(CS, acceleratingCourse, stateFlags) = addClearingSection!(CS, acceleratingCourse, stateFlags, settings, train, CSs) # this function is needed in case the train is not allowed to accelerate because of a previous speed limit
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if settings[:massModel] == "mass point" || acceleratingCourse[end][:s] > CS[:s_entry] + train[:length]
|
||||||
|
break
|
||||||
|
else
|
||||||
|
(CS, acceleratingCourse, stateFlags) = addDiminishingSection!(CS, acceleratingCourse, stateFlags, settings, train, CSs) # this function is needed in case the resisitng forces are higher than the maximum possible tractive effort
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
v_peak = max(v_peak, acceleratingCourse[end][:v])
|
||||||
end
|
end
|
||||||
|
|
||||||
CS[:v_peak] = max(CS[:v_entry], acceleratingCourse[end][:v])
|
# CS[:v_peak] = max(CS[:v_entry], acceleratingCourse[end][:v])
|
||||||
|
CS[:v_peak] = v_peak
|
||||||
CS[:v_exit] = min(CS[:v_exit], CS[:v_peak], acceleratingCourse[end][:v])
|
CS[:v_exit] = min(CS[:v_exit], CS[:v_peak], acceleratingCourse[end][:v])
|
||||||
else #CS[:v_entry] == CS[:v_peak]
|
else #CS[:v_entry] == CS[:v_peak]
|
||||||
# v_exit stays the same
|
# v_exit stays the same
|
||||||
|
@ -171,14 +182,13 @@ function secureAcceleratingBehavior!(movingSection::Dict, settings::Dict, train:
|
||||||
CS[:behaviorSections] = Dict()
|
CS[:behaviorSections] = Dict()
|
||||||
CS[:E] = 0.0
|
CS[:E] = 0.0
|
||||||
CS[:t] = 0.0
|
CS[:t] = 0.0
|
||||||
|
|
||||||
end #for
|
end #for
|
||||||
|
|
||||||
return movingSection
|
return movingSection
|
||||||
end #function secureAcceleratingBehavior!
|
end #function secureAcceleratingBehavior!
|
||||||
|
|
||||||
|
|
||||||
|
#=
|
||||||
## define the intersection velocities between the characterisitc sections to secure cruising behavior
|
## define the intersection velocities between the characterisitc sections to secure cruising behavior
|
||||||
function secureCruisingBehavior!(movingSection::Dict, settings::Dict, train::Dict)
|
function secureCruisingBehavior!(movingSection::Dict, settings::Dict, train::Dict)
|
||||||
# limit the exit velocity of the characteristic sections in case that the train cruises in every section at v_peak
|
# limit the exit velocity of the characteristic sections in case that the train cruises in every section at v_peak
|
||||||
|
@ -198,7 +208,7 @@ function secureCruisingBehavior!(movingSection::Dict, settings::Dict, train::Dic
|
||||||
:previousSpeedLimitReached => false,
|
:previousSpeedLimitReached => false,
|
||||||
:speedLimitReached => false,
|
:speedLimitReached => false,
|
||||||
:error => false,
|
:error => false,
|
||||||
:usedForDefiningCharacteristics => true) # currently only used during the definition of the accelerating characteristics
|
:usedForDefiningCharacteristics => true)
|
||||||
|
|
||||||
CS[:v_entry] = min(CS[:v_entry], previousCSv_exit)
|
CS[:v_entry] = min(CS[:v_entry], previousCSv_exit)
|
||||||
|
|
||||||
|
@ -206,7 +216,23 @@ function secureCruisingBehavior!(movingSection::Dict, settings::Dict, train::Dic
|
||||||
startingPoint[:v] = CS[:v_peak]
|
startingPoint[:v] = CS[:v_peak]
|
||||||
cruisingCourse::Vector{Dict} = [startingPoint] # List of data points
|
cruisingCourse::Vector{Dict} = [startingPoint] # List of data points
|
||||||
|
|
||||||
(CS, cruisingCourse, stateFlags) = addCruisingSection!(CS, cruisingCourse, stateFlags, CS[:length], settings, train, CSs, "cruising") # this function changes the cruisingCourse
|
while !stateFlags[:endOfCSReached] #&& s_cruising > 0.0
|
||||||
|
if !stateFlags[:tractionDeficit]
|
||||||
|
s_cruising = CS[:s_exit] - cruisingCourse[end][:s]
|
||||||
|
if !stateFlags[:resistingForceNegative]# cruisingCourse[end][:F_R] >= 0
|
||||||
|
(CS, cruisingCourse, stateFlags) = addCruisingSection!(CS, cruisingCourse, stateFlags, s_cruising, settings, train, CSs, "cruising") # this function changes the cruisingCourse
|
||||||
|
else
|
||||||
|
(CS, cruisingCourse, stateFlags) = addCruisingSection!(CS, cruisingCourse, stateFlags, s_cruising, settings, train, CSs, "downhillBraking")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if settings[:massModel] == "mass point" || cruisingCourse[end][:s] > CS[:s_entry] + train[:length]
|
||||||
|
break
|
||||||
|
else
|
||||||
|
(CS, cruisingCourse, stateFlags) = addDiminishingSection!(CS, cruisingCourse, stateFlags, settings, train, CSs) # this function is needed in case the resisitng forces are higher than the maximum possible tractive effort
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
CS[:v_exit] = min(CS[:v_exit], cruisingCourse[end][:v])
|
CS[:v_exit] = min(CS[:v_exit], cruisingCourse[end][:v])
|
||||||
|
|
||||||
previousCSv_exit = CS[:v_exit]
|
previousCSv_exit = CS[:v_exit]
|
||||||
|
@ -219,5 +245,5 @@ function secureCruisingBehavior!(movingSection::Dict, settings::Dict, train::Dic
|
||||||
|
|
||||||
return movingSection
|
return movingSection
|
||||||
end #function secureCruisingBehavior!
|
end #function secureCruisingBehavior!
|
||||||
|
=#
|
||||||
end #module Characteristics
|
end #module Characteristics
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
# TODO from 2022/01/19: Are here calculations that should be transferred to DrivingDynamics.jl?
|
# TODO from 2022/01/19: Are here calculations that should be transferred to DrivingDynamics.jl?
|
||||||
# TODO from 2022/01/22: use always copyCharacteristicSection and don't do it manually like "csModified=Dict(:id => csOriginal[:id], ..." three times
|
# TODO from 2022/01/22: use always copyCharacteristicSection and don't do it manually like "csModified=Dict(:id => csOriginal[:id], ..." three times
|
||||||
# TODO from 2022/03/18: stateFlags need to be added to functions that add behavior sections
|
# TODO from 2022/03/18: stateFlags need to be added to functions that add behavior sections
|
||||||
|
# TODO from 2022/03/21: consider previous speed limits during the coasting section in case F_R < 0.0 and the train is getting faster
|
||||||
|
|
||||||
module EnergySaving
|
module EnergySaving
|
||||||
|
|
||||||
|
|
|
@ -72,8 +72,8 @@ end # function calculateDrivingDynamics
|
||||||
function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train::Dict)
|
function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train::Dict)
|
||||||
CSs::Vector{Dict} = movingSection[:characteristicSections]
|
CSs::Vector{Dict} = movingSection[:characteristicSections]
|
||||||
|
|
||||||
if settings[:massModel] == "homogeneous strip"
|
if settings[:massModel] == "homogeneous strip" && settings[:stepVariable] == "v in m/s"
|
||||||
println("WARNING: ! ! ! TrainRun.jl doesn't work reliably for the mass model homogeneous strip. This mass model should not be used ! ! !")
|
println("WARNING: ! ! ! TrainRun.jl doesn't work reliably for the mass model homogeneous strip with step size v in m/s. The calculation time can be extremely high when calcutlating paths with steep gradients ! ! !")
|
||||||
end
|
end
|
||||||
|
|
||||||
startingPoint=createDataPoint()
|
startingPoint=createDataPoint()
|
||||||
|
@ -115,20 +115,25 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
|
||||||
elseif stateFlags[:previousSpeedLimitReached]
|
elseif stateFlags[:previousSpeedLimitReached]
|
||||||
(CS, drivingCourse, stateFlags) = addClearingSection!(CS, drivingCourse, stateFlags, settings, train, CSs)
|
(CS, drivingCourse, stateFlags) = addClearingSection!(CS, drivingCourse, stateFlags, settings, train, CSs)
|
||||||
|
|
||||||
elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R] && !stateFlags[:speedLimitReached] # v < v_limit
|
elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R] && !stateFlags[:speedLimitReached]
|
||||||
(CS, drivingCourse, stateFlags) = addAcceleratingSection!(CS, drivingCourse, stateFlags, settings, train, CSs)
|
(CS, drivingCourse, stateFlags) = addAcceleratingSection!(CS, drivingCourse, stateFlags, settings, train, CSs)
|
||||||
|
|
||||||
elseif drivingCourse[end][:F_R] < 0 && stateFlags[:speedLimitReached] # v < v_limit
|
elseif drivingCourse[end][:F_T] == drivingCourse[end][:F_R] && !stateFlags[:speedLimitReached]
|
||||||
if settings[:massModel] == "mass point"
|
# cruise only one step
|
||||||
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
if settings[:stepVariable] =="s in m"
|
||||||
s_cruising = CS[:s_exit] - drivingCourse[end][:s] - s_braking
|
s_cruising = settings[:stepSize]
|
||||||
elseif settings[:massModel] == "homogeneous strip"
|
elseif settings[:stepVariable] =="t in s"
|
||||||
# TODO: Add downhillBraking for homogeneous strip
|
s_cruising = calc_Δs_with_Δt(settings[:stepSize], drivingCourse[end][:a], drivingCourse[end][:v])
|
||||||
error("Add downhillBraking for homogeneous strip !")
|
elseif settings[:stepVariable] =="v in m/s"
|
||||||
# cruise until F_R >= 0.0
|
s_cruising = train[:length]/(10.0) # TODO which step size should be used?
|
||||||
end
|
end
|
||||||
|
(CS, drivingCourse, stateFlags) = addCruisingSection!(CS, drivingCourse, stateFlags, s_cruising, settings, train, CSs, "cruising")
|
||||||
|
|
||||||
if s_cruising > 0.0 # TODO: define a minimum cruising length?
|
elseif drivingCourse[end][:F_R] < 0 && stateFlags[:speedLimitReached]
|
||||||
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
||||||
|
s_cruising = CS[:s_exit] - drivingCourse[end][:s] - s_braking
|
||||||
|
|
||||||
|
if s_cruising > 0.0
|
||||||
(CS, drivingCourse, stateFlags) = addCruisingSection!(CS, drivingCourse, stateFlags, s_cruising, settings, train, CSs, "downhillBraking")
|
(CS, drivingCourse, stateFlags) = addCruisingSection!(CS, drivingCourse, stateFlags, s_cruising, settings, train, CSs, "downhillBraking")
|
||||||
else
|
else
|
||||||
stateFlags[:brakingStartReached] = true
|
stateFlags[:brakingStartReached] = true
|
||||||
|
|
Loading…
Reference in New Issue