Fix Behavior.jl for using the time step method

development
Max Kannenberg 2022-02-18 20:20:42 +01:00
parent fd05d25910
commit 9081b61903
1 changed files with 275 additions and 113 deletions

View File

@ -3,8 +3,8 @@ module Behavior
include("./DrivingDynamics.jl") include("./DrivingDynamics.jl")
using .DrivingDynamics using .DrivingDynamics
export addAccelerationSection!, addAccelerationSectionUntilBraking!, addCruisingSection!, addCoastingSectionUntilBraking!, addBrakingSection!, addBrakingSectionStepwise!, addStandstill!, export addAccelerationSection!, addAccelerationSectionUntilBraking!, addCruisingSection!, addCoastingSectionUntilBraking!, addBrakingSection!, addBrakingSectionInOneStep!, addStandstill!,
# addBrakingSectionStepwise! 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,
# export functions from DrivingDynamics # export functions from DrivingDynamics
@ -109,29 +109,43 @@ function moveAStep(previousPoint::Dict, stepVariable::String, stepSize::Real, cs
newPoint[:i] = previousPoint[:i]+1 # identifier newPoint[:i] = previousPoint[:i]+1 # identifier
# calculate s, t, v, E # calculate s, t, v, E
if previousPoint[:a] == 0.0 # TODO: or better stepVariable=="s_cruising in m" ? if stepVariable == "s in m" # distance step method
newPoint[:Δs] = stepSize # step size (in m)
newPoint[:Δt] = calc_Δt_with_constant_v(newPoint[:Δs], previousPoint[:v]) # step size (in s)
newPoint[:Δv] = 0.0 # step size (in m/s)
elseif stepVariable == "s in m" # distance step method
newPoint[:Δs] = stepSize # step size (in m) newPoint[:Δs] = stepSize # step size (in m)
if previousPoint[:a] < 0.0 if previousPoint[:a] == 0.0
if ((previousPoint[:v]/previousPoint[:a])^2+2*newPoint[:Δs]/previousPoint[:a])<0.0 || (previousPoint[:v]^2+2*newPoint[:Δs]*previousPoint[:a])<0.0 # checking if the parts of the following square roots will be <0.0 if previousPoint[:v] == 0.0
error("ERROR: The train tries to cruise at v=0.0 m/s at s=",previousPoint[:s]," in CS",csId,".")
end
newPoint[:Δt] = calc_Δt_with_constant_v(newPoint[:Δs], previousPoint[:v]) # step size (in s)
newPoint[:Δv] = 0.0 # step size (in m/s)
else
if previousPoint[:a] < 0.0 && ((previousPoint[:v]/previousPoint[:a])^2+2*newPoint[:Δs]/previousPoint[:a])<0.0 || (previousPoint[:v]^2+2*newPoint[:Δs]*previousPoint[:a])<0.0 # checking if the parts of the following square roots will be <0.0
error("ERROR: The train stops during the acceleration section in CS",csId," because the tractive effort is lower than the resistant forces.", error("ERROR: The train stops during the acceleration section in CS",csId," because the tractive effort is lower than the resistant forces.",
" Before the stop the last point has the values s=",previousPoint[:s]," m, v=",previousPoint[:v]," m/s, a=",previousPoint[:a]," m/s^2,", " Before the stop the last point has the values s=",previousPoint[:s]," m, v=",previousPoint[:v]," m/s, a=",previousPoint[:a]," m/s^2,",
" F_T=",previousPoint[:F_T]," N, R_traction=",previousPoint[:R_traction]," N, R_wagons=",previousPoint[:R_wagons]," N, R_path=",previousPoint[:R_path]," N.") " F_T=",previousPoint[:F_T]," N, R_traction=",previousPoint[:R_traction]," N, R_wagons=",previousPoint[:R_wagons]," N, R_path=",previousPoint[:R_path]," N.")
end end
newPoint[:Δt] = calc_Δt_with_Δs(newPoint[:Δs], previousPoint[:a], previousPoint[:v]) # step size (in s)
newPoint[:Δv] = calc_Δv_with_Δs(newPoint[:Δs], previousPoint[:a], previousPoint[:v]) # step size (in m/s)
end
elseif stepVariable == "t in s" # time step method
newPoint[:Δt] = stepSize # step size (in s)
newPoint[:Δs] = calc_Δs_with_Δt(newPoint[:Δt], previousPoint[:a], previousPoint[:v]) # step size (in m)
newPoint[:Δv] = calc_Δv_with_Δt(newPoint[:Δt], previousPoint[:a]) # step size (in m/s)
elseif stepVariable == "v in m/s" # velocity step method
if previousPoint[:a] == 0.0
if previousPoint[:v] == 0.0
error("ERROR: The train tries to cruise at v=0.0 m/s at s=",previousPoint[:s]," in CS",csId,".")
end
newPoint[:Δs] = stepSize # step size (in m)
# TODO what is the best default step size for constant v? define Δs or Δt?
newPoint[:Δt] = calc_Δt_with_constant_v(newPoint[:Δs], previousPoint[:v]) # step size (in s)
newPoint[:Δv] = 0.0 # step size (in m/s)
else
newPoint[:Δv] = stepSize * sign(previousPoint[:a]) # step size (in m/s)
newPoint[:Δs] = calc_Δs_with_Δv(newPoint[:Δv], previousPoint[:a], previousPoint[:v]) # step size (in m)
newPoint[:Δt] = calc_Δt_with_Δv(newPoint[:Δv], previousPoint[:a]) # step size (in s)
end end
newPoint[:Δt] = calc_Δt_with_Δs(newPoint[:Δs], previousPoint[:a], previousPoint[:v]) # step size (in s)
newPoint[:Δv] = calc_Δv_with_Δs(newPoint[:Δs], previousPoint[:a], previousPoint[:v]) # step size (in m/s)
elseif stepVariable =="t in s" # time step method
newPoint[:Δt] =stepSize # step size (in s)
newPoint[:Δs] = calc_Δs_with_Δt(newPoint[:Δs], previousPoint[:a], previousPoint[:v]) # step size (in m)
newPoint[:Δv] = calc_Δv_with_Δt(newPoint[:Δs], previousPoint[:a]) # step size (in m/s)
elseif stepVariable =="v in m/s" # velocity step method
newPoint[:Δv] = stepSize * sign(previousPoint[:a]) # step size (in m/s)
newPoint[:Δs] = calc_Δs_with_Δv(newPoint[:Δs], previousPoint[:a], previousPoint[:v]) # step size (in m)
newPoint[:Δt] = calc_Δt_with_Δv(newPoint[:Δs], previousPoint[:a]) # step size (in s)
end #if end #if
newPoint[:s] = previousPoint[:s] + newPoint[:Δs] # position (in m) newPoint[:s] = previousPoint[:s] + newPoint[:Δs] # position (in m)
@ -227,6 +241,9 @@ end #function getNextPointOfInterest
# 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 acceleration section # Info: currently the values of the breakFree section will be calculated like in the acceleration section
function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}) function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict})
if settings[:stepVariable] == "v in m/s"
println("WARNING: ! ! ! TrainRun doesn't work reliably for the step variable v. Therefore v should not be used ! ! !")
end
if drivingCourse[end][:v]==0.0 && drivingCourse[end][:s]<CS[:s_exit] if drivingCourse[end][:v]==0.0 && drivingCourse[end][:s]<CS[:s_exit]
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]
@ -247,8 +264,6 @@ function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::D
nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s]) nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])
while !brokenFree while !brokenFree
# create the next data point # create the next data point
#TODO: instead of the while loop this two line would also be enough for stepVariale s: stepSize = min(settings[:stepSize], getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])-BS[:s_entry])
#push!(drivingCourse, moveAStep(drivingCourse[end], "s in m", stepSize, CS[:id]))
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], settings[:stepSize], CS[:id])) push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], settings[:stepSize], CS[:id]))
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
push!(BS[:dataPoints], drivingCourse[end][:i]) push!(BS[:dataPoints], drivingCourse[end][:i])
@ -267,11 +282,19 @@ function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::D
pop!(drivingCourse) pop!(drivingCourse)
pop!(BS[:dataPoints]) pop!(BS[:dataPoints])
else else
drivingCourse[end][:s] = nextPointOfInterest # rounding s down to nextPointOfInterest drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
brokenFree = true brokenFree = true
break#free break#free
end end
else
elseif drivingCourse[end][:v] > CS[:v_peak]
if settings[:stepVariable] == "v in m/s"
currentStepSize = CS[:v_peak]-drivingCourse[end-1][:v]
else
currentStepSize = settings[:stepSize] / 10.0^cycle
end
else #if drivingCourse[end][:s] == nextPointOfInterest || drivingCourse[end][:v] == CS[:v_peak]
brokenFree = true brokenFree = true
break#free break#free
end #if end #if
@ -403,7 +426,7 @@ function addAccelerationSection!(CS::Dict, drivingCourse::Vector{Dict}, settings
pop!(BS[:dataPoints]) pop!(BS[:dataPoints])
elseif drivingCourse[end][:s] > nextPointOfInterest elseif drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:s] = nextPointOfInterest # rounding s down to nextPointOfInterest drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R] elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R]
tractionSurplus = false tractionSurplus = false
@ -561,7 +584,7 @@ function addAccelerationSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dic
pop!(BS[:dataPoints]) pop!(BS[:dataPoints])
elseif drivingCourse[end][:s] > nextPointOfInterest elseif drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:s] = nextPointOfInterest # rounding s down to nextPointOfInterest drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R] elseif drivingCourse[end][:F_T] <= drivingCourse[end][:F_R]
tractionSurplus = false tractionSurplus = false
@ -647,10 +670,16 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
drivingCourse[end][:a] = 0.0 drivingCourse[end][:a] = 0.0
# create the next data point # create the next data point
if settings[:stepVariable]=="s in m" #= 02/18 old if settings[:stepVariable]=="s in m"
push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", currentStepSize, CS[:id])) push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", currentStepSize, CS[:id]))
else else
push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", train[:length]/(10.0^cycle), CS[:id])) # TODO which step size should be used? push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", train[:length]/(10.0^cycle), CS[:id])) # TODO which step size should be used?
end =#
# create the next data point
if settings[:stepVariable] =="s in m" || settings[:stepVariable] =="t in s"
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
else
push!(drivingCourse, moveAStep(drivingCourse[end], "s in m", train[:length]/(10.0^cycle), CS[:id])) # TODO which step size should be used?
end end
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
push!(BS[:dataPoints], drivingCourse[end][:i]) push!(BS[:dataPoints], drivingCourse[end][:i])
@ -699,7 +728,7 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
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
drivingCourse[end][:s] = nextPointOfInterest # rounding s down to nextPointOfInterest drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
elseif drivingCourse[end][:s] > BS[:s_entry]+s_cruising elseif drivingCourse[end][:s] > BS[:s_entry]+s_cruising
trainAtEnd = true trainAtEnd = true
if BS[:type] != "clearing" if BS[:type] != "clearing"
@ -735,7 +764,8 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, s_cruising::
s_cruisingRemaining = nextPointOfInterest - drivingCourse[end][:s] s_cruisingRemaining = nextPointOfInterest - drivingCourse[end][:s]
# create the next data point # create the next data point
push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", s_cruisingRemaining, CS[:id])) # 02/18 old push!(drivingCourse, moveAStep(drivingCourse[end], "s_cruising in m", s_cruisingRemaining, CS[:id]))
push!(drivingCourse, moveAStep(drivingCourse[end], "s in m", s_cruisingRemaining, CS[:id]))
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
push!(BS[:dataPoints], drivingCourse[end][:i]) push!(BS[:dataPoints], drivingCourse[end][:i])
@ -794,9 +824,13 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
# 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
if cycle < approximationLevel+1 if cycle < approximationLevel+1
if drivingCourse[end][:v] <= 0.0 if drivingCourse[end][:v] < 0.0
currentStepSize = settings[:stepSize] / 10.0^cycle # 02/18 old: currentStepSize = settings[:stepSize] / 10.0^cycle
if settings[:stepVariable] == "v in m/s"
currentStepSize = drivingCourse[end-1][:v]
else
currentStepSize = settings[:stepSize] / 10.0^cycle
end
elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R] elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
currentStepSize = settings[:stepSize] / 10.0^cycle currentStepSize = settings[:stepSize] / 10.0^cycle
@ -817,6 +851,13 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
elseif drivingCourse[end][:s] == nextPointOfInterest elseif drivingCourse[end][:s] == nextPointOfInterest
break break
elseif drivingCourse[end][:v] == 0.0
targetSpeedReached = true
error("ERROR: The train stops during diminishing run in CS",CS[:id]," at position s=",drivingCourse[end][:s]," m because the maximum tractive effort is lower than the resistant forces.",
" Before the stop the last point has the values s=",drivingCourse[end-1][:s]," m v=",drivingCourse[end-1][:v]," m/s a=",drivingCourse[end-1][:a]," m/s^2",
" F_T=",drivingCourse[end-1][:F_T]," N R_traction=",drivingCourse[end-1][:R_traction]," N R_wagons=",drivingCourse[end-1][:R_wagons]," N R_path=",drivingCourse[end-1][:R_path]," N.")
else else
error("ERROR during diminishing run: With the step variable ",settings[:stepVariable]," the while loop will be left although s+s_braking<s_exit && v>0.0 in CS",CS[:id]," with s=" ,drivingCourse[end][:s]," m and v=",drivingCourse[end][:v]," m/s") error("ERROR during diminishing run: With the step variable ",settings[:stepVariable]," the while loop will be left although s+s_braking<s_exit && v>0.0 in CS",CS[:id]," with s=" ,drivingCourse[end][:s]," m and v=",drivingCourse[end][:v]," m/s")
end end
@ -838,7 +879,7 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings:
pop!(BS[:dataPoints]) pop!(BS[:dataPoints])
elseif drivingCourse[end][:s] > nextPointOfInterest elseif drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:s] = nextPointOfInterest # rounding s down to nextPointOfInterest drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R] elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
tractionSurplus = true tractionSurplus = true
@ -920,8 +961,11 @@ function addCoastingSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict},
end end
elseif drivingCourse[end][:v] < CS[:v_exit] # TODO: if accelereation and coasting functions will be combined this case is only for coasting elseif drivingCourse[end][:v] < CS[:v_exit] # TODO: if accelereation and coasting functions will be combined this case is only for coasting
currentStepSize = settings[:stepSize] / 10.0^cycle if settings[:stepVariable] == "v in m/s"
currentStepSize = drivingCourse[end-1][:v] - CS[:v_exit]
else
currentStepSize = settings[:stepSize] / 10.0^cycle
end
elseif drivingCourse[end][:v] > CS[:v_peak] elseif drivingCourse[end][:v] > CS[:v_peak]
if settings[:stepVariable]=="v in m/s" if settings[:stepVariable]=="v in m/s"
currentStepSize = CS[:v_peak] - drivingCourse[end-1][:v] currentStepSize = CS[:v_peak] - drivingCourse[end-1][:v]
@ -948,7 +992,7 @@ function addCoastingSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict},
pop!(BS[:dataPoints]) pop!(BS[:dataPoints])
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
println("INFO: The train stops during the coasting section in CS",CS[:id]," ", println("INFO: The train stops during the coasting section in CS",CS[:id]," ",
" Before the stop the last point has the values s=",drivingCourse[end-1][:s]," m v=",drivingCourse[end-1][:v]," m/s a=",drivingCourse[end-1][:a]," m/s^2", " Before the stop the last point has the values s=",drivingCourse[end-1][:s]," m v=",drivingCourse[end-1][:v]," m/s a=",drivingCourse[end-1][:a]," m/s^2",
" F_T=",drivingCourse[end-1][:F_T]," N R_traction=",drivingCourse[end-1][:R_traction]," N R_wagons=",drivingCourse[end-1][:R_wagons]," N R_path=",drivingCourse[end-1][:R_path]," N and s_braking=",s_braking,"m.") " F_T=",drivingCourse[end-1][:F_T]," N R_traction=",drivingCourse[end-1][:R_traction]," N R_wagons=",drivingCourse[end-1][:R_wagons]," N R_path=",drivingCourse[end-1][:R_path]," N and s_braking=",s_braking,"m.")
@ -976,13 +1020,13 @@ function addCoastingSectionUntilBraking!(CS::Dict, drivingCourse::Vector{Dict},
push!(BS[:dataPoints], drivingCourse[end][:i]) push!(BS[:dataPoints], drivingCourse[end][:i])
elseif drivingCourse[end][:s] > nextPointOfInterest elseif drivingCourse[end][:s] > nextPointOfInterest
drivingCourse[end][:s] = nextPointOfInterest # rounding s down to nextPointOfInterest drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
else else
end end
end end
end #for end #for
end #while end #while
# 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)
@ -1077,11 +1121,6 @@ end #function addBrakingSectionInOneStep!
# 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}, settings::Dict, train::Dict, CSs::Vector{Dict})
#function addBrakingSectionStepwise!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}) #function addBrakingSectionStepwise!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict})
if settings[:stepVariable] != "s in m"
error("addBrakingSectionStepwise! does not work with other step variables than 's in m' right now.")
end
# TODO: add for loop to realize calculations with step variables t and v
# conditions for braking section # conditions for braking section
targetSpeedReached = drivingCourse[end][:v] <= CS[:v_exit] targetSpeedReached = drivingCourse[end][:v] <= CS[:v_exit]
trainAtEnd = drivingCourse[end][:s] >= CS[:s_exit] trainAtEnd = drivingCourse[end][:s] >= CS[:s_exit]
@ -1095,95 +1134,194 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dic
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])
while drivingCourse[end][:v] > CS[:v_exit] && !targetSpeedReached && drivingCourse[end][:s] < CS[:s_exit] && 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
# traction effort and resisting forces (in N): while drivingCourse[end][:v] > CS[:v_exit] && !targetSpeedReached && drivingCourse[end][:s] < CS[:s_exit] && drivingCourse[end][:s] < nextPointOfInterest
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel]) # traction effort and resisting forces (in N):
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
# acceleration (in m/s^2): # acceleration (in m/s^2):
drivingCourse[end][:a] = train[:a_braking] drivingCourse[end][:a] = train[:a_braking]
# TODO or: drivingCourse[end][:a] = calcBrakingAcceleration(drivingCourse[end][:v], CS[:v_exit], CS[:s_exit]-drivingCourse[end][:s]) # TODO or: drivingCourse[end][:a] = calcBrakingAcceleration(drivingCourse[end][:v], CS[:v_exit], CS[:s_exit]-drivingCourse[end][:s])
# create the next data point if settings[:stepVariable] == "s in m" && ((drivingCourse[end][:v]/drivingCourse[end][:a])^2+2*currentStepSize/drivingCourse[end][:a])<0.0 || (drivingCourse[end][:v]^2+2*currentStepSize*drivingCourse[end][:a])<0.0
#TODO moveAStep should give back true or false for success or failure e.g. with dropping below v=0 m/s
#at the moment it can only be used for stepVariable == "s in m"
if settings[:stepVariable] == "s in m"
if ((drivingCourse[end][:v]/drivingCourse[end][:a])^2+2*currentStepSize/drivingCourse[end][:a])<0.0 || (drivingCourse[end][:v]^2+2*currentStepSize*drivingCourse[end][:a])<0.0
targetSpeedReached = true targetSpeedReached = true
# create empty data point for setting the values after the while loop # create empty data point and set ist for the values of s_ext and v_exit
push!(drivingCourse, createDataPoint()) push!(drivingCourse, createDataPoint())
drivingCourse[end][:i] = drivingCourse[end-1][:i]+1 drivingCourse[end][:i] = drivingCourse[end-1][:i]+1
drivingCourse[end][:behavior] = BS[:type] drivingCourse[end][:behavior] = BS[:type]
push!(BS[:dataPoints], drivingCourse[end][:i]) push!(BS[:dataPoints], drivingCourse[end][:i])
recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
break break
end end
else
error("Stepwise braking can currently be used with stepVariable=='s in m' only. Otherwise errors may not be detected.")
end
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id])) # create the next data point
drivingCourse[end][:behavior] = BS[:type] push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
push!(BS[:dataPoints], drivingCourse[end][:i]) drivingCourse[end][:behavior] = BS[:type]
end # while push!(BS[:dataPoints], drivingCourse[end][:i])
end # while
if drivingCourse[end][:v] < CS[:v_exit] || targetSpeedReached # check which limit was reached and adjust the currentStepSize for the next cycle
# reset last point with setting v=v_exit # TODO: is there a better way than rounding like in the following?
targetSpeedReached = true if cycle < approximationLevel+1 && !targetSpeedReached
trainAtEnd = true if drivingCourse[end][:v] < CS[:v_exit]
if settings[:stepVariable] == "v in m/s"
currentStepSize = drivingCourse[end-1][:v] - CS[:v_exit]
else
currentStepSize = settings[:stepSize] / 10.0^cycle
end
#=elseif drivingCourse[end][:s] > CS[:s_exit]
if settings[:stepVariable] == "s in m"
currentStepSize = CS[:s_exit] - drivingCourse[end-1][:s]
else
currentStepSize = settings[:stepSize] / 10.0^cycle
end=#
elseif drivingCourse[end][:s] > nextPointOfInterest
# reset last point with lowering s to the nextPointOfInterest
if settings[:stepVariable] == "s in m"
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
else
currentStepSize = settings[:stepSize] / 10.0^cycle
end
elseif drivingCourse[end][:v] == CS[:v_exit] && drivingCourse[end][:s] == CS[:s_exit]
targetSpeedReached = true
trainAtEnd = true
break
elseif drivingCourse[end][:v] == CS[:v_exit]
targetSpeedReached = true
trainAtEnd = true
# 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])
# println(" with a=", drivingCourse[end-1][:a]) # for testing
break
elseif drivingCourse[end][:s] == CS[:s_exit]
targetSpeedReached = true
trainAtEnd = true
# 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])
# println(" with a=", drivingCourse[end-1][:a]) # for testing
break
elseif drivingCourse[end][:s] == nextPointOfInterest
break
end
# calculate s, t, v # delete last data point for recalculating the last step with reduced step size
drivingCourse[end][:s] = CS[:s_exit] # position (in m) pop!(drivingCourse)
drivingCourse[end][:v] = CS[:v_exit] # velocity (in m/s) pop!(BS[:dataPoints])
drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s] # step size (in m)
drivingCourse[end][:Δv] = drivingCourse[end][:v] - drivingCourse[end-1][:v] # step size (in m/s)
drivingCourse[end-1][:a] = calcBrakingAcceleration(drivingCourse[end-1][:v], drivingCourse[end][:v], drivingCourse[end][:Δs]) else # if the level of approximation is reached
if drivingCourse[end-1][:a]<train[:a_braking] || drivingCourse[end-1][:a]>=0.0 if drivingCourse[end][:v] < 0.0
println("Warning: a_braking gets to high in CS ",CS[:id], " with a=",drivingCourse[end-1][:a] ," > ",train[:a_braking]) # reset last point with setting v=v_exit
end targetSpeedReached = true
drivingCourse[end][:Δt] = calc_Δt_with_Δv(drivingCourse[end][:Δv], drivingCourse[end-1][:a]) # step size (in s) trainAtEnd = true
drivingCourse[end][:t] = drivingCourse[end-1][:t] + drivingCourse[end][:Δt] # point in time (in s) # 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)
drivingCourse[end][:ΔW] = 0.0 # mechanical work in this step (in Ws) # println(" with a=", drivingCourse[end-1][:a]) # for testing
drivingCourse[end][:W] = drivingCourse[end-1][:W] + drivingCourse[end][:ΔW] # mechanical work (in Ws) break
drivingCourse[end][:ΔE] = drivingCourse[end][:ΔW] # energy consumption in this step (in Ws) elseif drivingCourse[end][:s] > CS[:s_exit]
drivingCourse[end][:E] = drivingCourse[end-1][:E] + drivingCourse[end][:ΔE] # energy consumption (in Ws) targetSpeedReached = true
trainAtEnd = true
# println("during braking section in CS",CS[:id],": rounding s down from ", drivingCourse[end][:s] ," to ", CS[:s_exit]) # for testing
# recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
elseif drivingCourse[end][:s] > CS[:s_exit] drivingCourse[end][:s] = CS[:s_exit]
trainAtEnd = true break
error("At the end of braking: s>s_exit but v>v_exit") elseif drivingCourse[end][:s] > nextPointOfInterest
elseif drivingCourse[end][:s] > nextPointOfInterest drivingCourse[end][:s] = nextPointOfInterest # round s down to nextPointOfInterest
# reset last point with lowering s to the nextPointOfInterest break
elseif drivingCourse[end][:v] == CS[:v_exit] && drivingCourse[end][:s] == CS[:s_exit]
# calculate s, t, v targetSpeedReached = true
if settings[:stepVariable] == "s in m" trainAtEnd = true
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s] # step size (in m) break
else elseif drivingCourse[end][:v] < CS[:v_exit]
# TODO # reset last point with setting v=v_exit
targetSpeedReached = true
trainAtEnd = true
# 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])
# println(" with a=", drivingCourse[end-1][:a]) # for testing
break
elseif drivingCourse[end][:v] == CS[:v_exit]
targetSpeedReached = true
trainAtEnd = true
# 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])
# println(" with a=", drivingCourse[end-1][:a]) # for testing
break
elseif drivingCourse[end][:s] == CS[:s_exit]
targetSpeedReached = true
trainAtEnd = true
# 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])
# println(" with a=", drivingCourse[end-1][:a]) # for testing
break
else
# do nothing for example for drivingCourse[end][:s]==nextPointOfInterest
end
end end
pop!(drivingCourse)
pop!(BS[:dataPoints])
# create the next data point #=
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id])) if drivingCourse[end][:v] < CS[:v_exit] || targetSpeedReached
drivingCourse[end][:behavior] = BS[:type] # reset last point with setting v=v_exit
push!(BS[:dataPoints], drivingCourse[end][:i]) targetSpeedReached = true
trainAtEnd = true
elseif drivingCourse[end][:v] == CS[:v_exit] && drivingCourse[end][:s] == CS[:s_exit] # calculate s, t, v
targetSpeedReached = true drivingCourse[end][:s] = CS[:s_exit] # position (in m)
trainAtEnd = true drivingCourse[end][:v] = CS[:v_exit] # velocity (in m/s)
elseif drivingCourse[end][:v] == CS[:v_exit] drivingCourse[end][:Δs] = drivingCourse[end][:s] - drivingCourse[end-1][:s] # step size (in m)
targetSpeedReached = true drivingCourse[end][:Δv] = drivingCourse[end][:v] - drivingCourse[end-1][:v] # step size (in m/s)
error("At the end of braking: s<s_exit but v=v_exit")
elseif drivingCourse[end][:s] == CS[:s_exit] drivingCourse[end-1][:a] = calcBrakingAcceleration(drivingCourse[end-1][:v], drivingCourse[end][:v], drivingCourse[end][:Δs])
trainAtEnd = true # TODO: just for testing
error("At the end of braking: s=s_exit but v>v_exit") if drivingCourse[end-1][:a]<train[:a_braking] || drivingCourse[end-1][:a]>=0.0
else println("Warning: a_braking gets to high in CS ",CS[:id], " with a=",drivingCourse[end-1][:a] ," > ",train[:a_braking])
# do nothing for example for drivingCourse[end][:s]==nextPointOfInterest
end end
end drivingCourse[end][:Δt] = calc_Δt_with_Δv(drivingCourse[end][:Δv], drivingCourse[end-1][:a]) # step size (in s)
drivingCourse[end][:t] = drivingCourse[end-1][:t] + drivingCourse[end][:Δt] # point in time (in s)
drivingCourse[end][:ΔW] = 0.0 # mechanical work in this step (in Ws)
drivingCourse[end][:W] = drivingCourse[end-1][:W] + drivingCourse[end][:ΔW] # mechanical work (in Ws)
drivingCourse[end][:ΔE] = drivingCourse[end][:ΔW] # energy consumption in this step (in Ws)
drivingCourse[end][:E] = drivingCourse[end-1][:E] + drivingCourse[end][:ΔE] # energy consumption (in Ws)
elseif drivingCourse[end][:s] > CS[:s_exit]
trainAtEnd = true
error("At the end of braking: s>s_exit but v>v_exit")
elseif drivingCourse[end][:s] > nextPointOfInterest
# reset last point with lowering s to the nextPointOfInterest
# calculate s, t, v
if settings[:stepVariable] == "s in m"
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s] # step size (in m)
else
# TODO
end
pop!(drivingCourse)
pop!(BS[:dataPoints])
# create the next data point
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
drivingCourse[end][:behavior] = BS[:type]
push!(BS[:dataPoints], drivingCourse[end][:i])
elseif drivingCourse[end][:v] == CS[:v_exit] && drivingCourse[end][:s] == CS[:s_exit]
targetSpeedReached = true
trainAtEnd = true
elseif drivingCourse[end][:v] == CS[:v_exit]
targetSpeedReached = true
error("At the end of braking: s<s_exit but v=v_exit")
elseif drivingCourse[end][:s] == CS[:s_exit]
trainAtEnd = true
error("At the end of braking: s=s_exit but v>v_exit")
else
# do nothing for example for drivingCourse[end][:s]==nextPointOfInterest
end
=#
end #for
end #while
# 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)
@ -1263,4 +1401,28 @@ function createDataPoint()
return dataPoint return dataPoint
end #function createDataPoint end #function createDataPoint
function recalculateLastBrakingPoint!(drivingCourse, s_target, v_target)
currentPoint = drivingCourse[end]
previousPoint = drivingCourse[end-1]
# set s and v
currentPoint[:s] = s_target # position (in m)
currentPoint[:v] = v_target # velocity (in m/s)
currentPoint[:Δs] = currentPoint[:s] - previousPoint[:s] # step size (in m)
currentPoint[:Δv] = currentPoint[:v] - previousPoint[:v] # step size (in m/s)
# calculate other values
previousPoint[:a] = calcBrakingAcceleration(previousPoint[:v], currentPoint[:v], currentPoint[:Δs])
# # TODO: just for testing
# if previousPoint[:a]<train[:a_braking] || previousPoint[:a]>=0.0
# println("Warning: a_braking gets to high in CS ",CS[:id], " with a=",previousPoint[:a] ," > ",train[:a_braking])
# end
currentPoint[:Δt] = calc_Δt_with_Δv(currentPoint[:Δv], previousPoint[:a]) # step size (in s)
currentPoint[:t] = previousPoint[:t] + currentPoint[:Δt] # point in time (in s)
currentPoint[:ΔW] = 0.0 # mechanical work in this step (in Ws)
currentPoint[:W] = previousPoint[:W] + currentPoint[:ΔW] # mechanical work (in Ws)
currentPoint[:ΔE] = currentPoint[:ΔW] # energy consumption in this step (in Ws)
currentPoint[:E] = previousPoint[:E] + currentPoint[:ΔE] # energy consumption (in Ws)
end #function recalculateLastBrakingPoint
end #module Behavior end #module Behavior