Fix mass model "homogeneous strip" for distance and time step methods

development
Max Kannenberg 2022-03-30 22:10:21 +02:00
parent 7d56c707c1
commit 2983b2c2e1
6 changed files with 183 additions and 49 deletions

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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