Integrate calculation for additional points of interest
parent
8802ef7bc7
commit
917a16782d
|
@ -21,9 +21,10 @@ Review the settings.yaml file for your appropriate settings.
|
||||||
include("../src/TrainRun.jl")
|
include("../src/TrainRun.jl")
|
||||||
using .TrainRun
|
using .TrainRun
|
||||||
|
|
||||||
train = "data/trains/train_freight_V90withOreConsist.yaml"
|
train_directory = "data/trains/train_freight_V90withOreConsist.yaml"
|
||||||
running_path = "data/paths/path_1_10km_nConst_vConst.yaml"
|
running_path_directory = "data/paths/path_1_10km_nConst_vConst.yaml"
|
||||||
settings = "data/settings.yaml"
|
settings_directory = "data/settings.yaml"
|
||||||
|
(train, running_path, settings) = importYamlFiles(train_directory, running_path_directory, setting_directory)
|
||||||
|
|
||||||
train_run = calculateDrivingDynamics(train, running_path, settings)
|
train_run = calculateDrivingDynamics(train, running_path, settings)
|
||||||
```
|
```
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
---
|
---
|
||||||
path:
|
path:
|
||||||
name: "10 km, no gradient, 160 km/h"
|
name: "10 km, no gradient, 160 km/h"
|
||||||
|
pointsOfInterest: [999, 2000, 3333.3, 5000, 7777, 9000, 9500.95] # points of interest: positions in m
|
||||||
sectionStarts: # with path speed limt (in m/s) # [s in m, v_limit in m/s, f_Rp in ‰]
|
sectionStarts: # with path speed limt (in m/s) # [s in m, v_limit in m/s, f_Rp in ‰]
|
||||||
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp in ‰]
|
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp in ‰]
|
||||||
- [0, 160, 0]
|
- [0, 160, 0]
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
---
|
---
|
||||||
path:
|
path:
|
||||||
name: "10 km, different gradient, 160 km/h"
|
name: "10 km, different gradient, 160 km/h"
|
||||||
|
pointsOfInterest: [999, 2000, 3333.3, 5000, 7777, 9000, 9500.95] # points of interest: positions in m
|
||||||
sectionStarts: # with path speed limt (in m/s) # [s in m, v_limit in m/s, f_Rp in ‰]
|
sectionStarts: # with path speed limt (in m/s) # [s in m, v_limit in m/s, f_Rp in ‰]
|
||||||
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp in ‰]
|
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp in ‰]
|
||||||
- [0, 160, 0]
|
- [0, 160, 0]
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
---
|
---
|
||||||
path:
|
path:
|
||||||
name: "10 km, no gradient, different speed limits"
|
name: "10 km, no gradient, different speed limits"
|
||||||
|
pointsOfInterest: [999, 2000, 3333.3, 5000, 7777, 9000, 9500.95] # points of interest: positions in m
|
||||||
sectionStarts: # with path speed limt (in m/s) # [s in m, v_limit in m/s, f_Rp in ‰]
|
sectionStarts: # with path speed limt (in m/s) # [s in m, v_limit in m/s, f_Rp in ‰]
|
||||||
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp in ‰]
|
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp in ‰]
|
||||||
- [0, 160, 0.0]
|
- [0, 160, 0.0]
|
||||||
|
|
|
@ -125,10 +125,10 @@ function plotDrivingCourse(drivingCourseMinimumRunningTime::Vector{Dict},driving
|
||||||
println("Plots for different variables have been created.")
|
println("Plots for different variables have been created.")
|
||||||
end #function plotDrivingCourse
|
end #function plotDrivingCourse
|
||||||
|
|
||||||
function printImportantValues(drivingCourse::Vector{Dict})
|
function printImportantValues(dataPoints::Vector{Dict})
|
||||||
println("i behavior s in m v in km/h t in min a in m/s^2 F_R in k N F_T in k N E in k Wh")
|
println("i behavior s in m v in km/h t in min a in m/s^2 F_R in k N F_T in k N E in k Wh")
|
||||||
for i in 1:length(drivingCourse)
|
for i in 1:length(dataPoints)
|
||||||
println(drivingCourse[i][:i],". ",drivingCourse[i][:s]," ",drivingCourse[i][:v]*3.6," ",drivingCourse[i][:t]/60," ",drivingCourse[i][:a]," ",drivingCourse[i][:F_R]/1000," ",drivingCourse[i][:F_T]/1000," ",drivingCourse[i][:E]/3600/1000)
|
println(dataPoints[i][:i],". ",dataPoints[i][:behavior]," ",dataPoints[i][:s]," ",dataPoints[i][:v]*3.6," ",dataPoints[i][:t]/60," ",dataPoints[i][:a]," ",dataPoints[i][:F_R]/1000," ",dataPoints[i][:F_T]/1000," ",dataPoints[i][:E]/3600/1000)
|
||||||
end #for
|
end #for
|
||||||
println("i behavior s in m v in km/h t in min a in m/s^2 F_R in k N F_T in k N E in k Wh")
|
println("i behavior s in m v in km/h t in min a in m/s^2 F_R in k N F_T in k N E in k Wh")
|
||||||
end #function printImportantValues
|
end #function printImportantValues
|
||||||
|
@ -136,13 +136,13 @@ end #function printImportantValues
|
||||||
function printSectionInformation(movingSection::Dict)
|
function printSectionInformation(movingSection::Dict)
|
||||||
CSs::Vector{Dict} = movingSection[:characteristicSections]
|
CSs::Vector{Dict} = movingSection[:characteristicSections]
|
||||||
|
|
||||||
println("MS mit length=", movingSection[:length]," mit t=", movingSection[:t])
|
println("MS with length=", movingSection[:length]," with t=", movingSection[:t])
|
||||||
allBs=[:breakFree, :clearing, :acceleration, :cruising, :diminishing, :coasting, :braking, :standstill]
|
allBs=[:breakFree, :clearing, :acceleration, :cruising, :diminishing, :coasting, :braking, :standstill]
|
||||||
for csId in 1:length(CSs)
|
for csId in 1:length(CSs)
|
||||||
println("CS ",csId," mit length=", CSs[csId][:length]," mit t=", CSs[csId][:t])
|
println("CS ",csId," with length=", CSs[csId][:length]," with t=", CSs[csId][:t])
|
||||||
for bs in 1: length(allBs)
|
for bs in 1: length(allBs)
|
||||||
if haskey(CSs[csId][:behaviorSections], allBs[bs])
|
if haskey(CSs[csId][:behaviorSections], allBs[bs])
|
||||||
println("BS ",allBs[bs], " mit s_entry=", CSs[csId][:behaviorSections][allBs[bs]][:s_entry], " und t=", CSs[csId][:behaviorSections][allBs[bs]][:t])
|
println("BS ",allBs[bs], " with s_entry=", CSs[csId][:behaviorSections][allBs[bs]][:s_entry], " and t=", CSs[csId][:behaviorSections][allBs[bs]][:t])
|
||||||
# for point in 1:length(CSs[csId][:behaviorSections][allBs[bs]][:dataPoints])
|
# for point in 1:length(CSs[csId][:behaviorSections][allBs[bs]][:dataPoints])
|
||||||
# println(CSs[csId][:behaviorSections][allBs[bs]][:dataPoints][point])
|
# println(CSs[csId][:behaviorSections][allBs[bs]][:dataPoints][point])
|
||||||
# end
|
# end
|
||||||
|
|
989
src/Behavior.jl
989
src/Behavior.jl
File diff suppressed because it is too large
Load Diff
|
@ -29,12 +29,12 @@ function createMovingSection(path::Dict, v_trainLimit::Real)
|
||||||
previousSection = path[:sections][row-1]
|
previousSection = path[:sections][row-1]
|
||||||
currentSection = path[:sections][row]
|
currentSection = path[:sections][row]
|
||||||
if min(previousSection[:v_limit], v_trainLimit) != min(currentSection[:v_limit], v_trainLimit) || previousSection[:f_Rp] != currentSection[:f_Rp]
|
if min(previousSection[:v_limit], v_trainLimit) != min(currentSection[:v_limit], v_trainLimit) || previousSection[:f_Rp] != currentSection[:f_Rp]
|
||||||
push!(CSs, createCharacteristicSection(csId, s_csStart, previousSection, min(previousSection[:v_limit], v_trainLimit)))
|
push!(CSs, createCharacteristicSection(csId, s_csStart, previousSection, min(previousSection[:v_limit], v_trainLimit), path))
|
||||||
s_csStart = currentSection[:s_start]
|
s_csStart = currentSection[:s_start]
|
||||||
csId = csId+1
|
csId = csId+1
|
||||||
end #if
|
end #if
|
||||||
end #for
|
end #for
|
||||||
push!(CSs, createCharacteristicSection(csId, s_csStart, path[:sections][end], min(path[:sections][end][:v_limit], v_trainLimit)))
|
push!(CSs, createCharacteristicSection(csId, s_csStart, path[:sections][end], min(path[:sections][end][:v_limit], v_trainLimit), path))
|
||||||
|
|
||||||
movingSection= Dict(:id => 1, # identifier # if there is more than one moving section in a later version of this tool the id should not be constant anymore
|
movingSection= Dict(:id => 1, # identifier # if there is more than one moving section in a later version of this tool the id should not be constant anymore
|
||||||
:length => pathLength, # total length (in m)
|
:length => pathLength, # total length (in m)
|
||||||
|
@ -49,21 +49,36 @@ end #function createMovingSection
|
||||||
|
|
||||||
|
|
||||||
## create a characteristic section for a path section. A characteristic section is a part of the moving section. It contains behavior sections.
|
## create a characteristic section for a path section. A characteristic section is a part of the moving section. It contains behavior sections.
|
||||||
function createCharacteristicSection(csId::Integer, s_csStart::Real, section::Dict, v_csLimit::Real)
|
function createCharacteristicSection(id::Integer, s_entry::Real, section::Dict, v_limit::Real, path::Dict)
|
||||||
# Create and return a characteristic section dependent on the paths attributes
|
# Create and return a characteristic section dependent on the paths attributes
|
||||||
characteristicSection= Dict(:id => csId, # identifier
|
characteristicSection= Dict(:id => id, # identifier
|
||||||
:s_entry => s_csStart, # first position (in m)
|
:s_entry => s_entry, # first position (in m)
|
||||||
:s_exit => section[:s_end], # last position (in m)
|
:s_exit => section[:s_end], # last position (in m)
|
||||||
:length => section[:s_end]-s_csStart, # total length (in m)
|
:length => section[:s_end] -s_entry, # total length (in m)
|
||||||
:r_path => section[:f_Rp], # path resistance (in ‰)
|
:r_path => section[:f_Rp], # path resistance (in ‰)
|
||||||
:behaviorSections => Dict(), # list of containing behavior sections
|
:behaviorSections => Dict(), # list of containing behavior sections
|
||||||
:t => 0.0, # total running time (in s)
|
:t => 0.0, # total running time (in s)
|
||||||
:E => 0.0, # total energy consumption (in Ws)
|
:E => 0.0, # total energy consumption (in Ws)
|
||||||
:v_limit => v_csLimit, # speed limit (in m/s)
|
:v_limit => v_limit, # speed limit (in m/s)
|
||||||
# initializing :v_entry, :v_peak and :v_exit with :v_limit
|
# initializing :v_entry, :v_peak and :v_exit with :v_limit
|
||||||
:v_peak => v_csLimit, # maximum reachable speed (in m/s)
|
:v_peak => v_limit, # maximum reachable speed (in m/s)
|
||||||
:v_entry => v_csLimit, # maximum entry speed (in m/s)
|
:v_entry => v_limit, # maximum entry speed (in m/s)
|
||||||
:v_exit => v_csLimit) # maximum exit speed (in m/s)
|
:v_exit => v_limit) # maximum exit speed (in m/s)
|
||||||
|
|
||||||
|
# list of positions of every point of interest (POI) in this charateristic section for which data points should be calculated
|
||||||
|
s_exit = characteristicSection[:s_exit]
|
||||||
|
pointsOfInterest = Vector{Real}()
|
||||||
|
if haskey(path, :pointsOfInterest)
|
||||||
|
for POI in path[:pointsOfInterest]
|
||||||
|
if s_entry < POI && POI < s_exit
|
||||||
|
push!(pointsOfInterest, POI)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
push!(pointsOfInterest, s_exit) # s_exit has to be the last POI so that there will always be a POI to campare the current position with
|
||||||
|
|
||||||
|
merge!(characteristicSection, Dict(:pointsOfInterest => pointsOfInterest))
|
||||||
|
|
||||||
return characteristicSection
|
return characteristicSection
|
||||||
end #function createCharacteristicSection
|
end #function createCharacteristicSection
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
# TODO: calculation time for passenger trains on path1 is very long and should be reduced
|
# TODO: calculation time for passenger trains on path1 is very long and should be reduced
|
||||||
# TODO from 2022/01/18: Test if enum trainType is working correctly in function calculateRecoveryTime or if only the else-pathis taken
|
# TODO from 2022/01/18: Test if enum trainType is working correctly in function calculateRecoveryTime or if only the else-pathis taken
|
||||||
# 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
|
||||||
|
|
||||||
module EnergySaving
|
module EnergySaving
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ function addOperationModeEnergySaving!(summarizedDict::Dict)
|
||||||
# summarize data and create an output dictionary
|
# summarize data and create an output dictionary
|
||||||
merge!(summarizedDict, Dict(:movingSectionMinimumEnergyConsumption => movingSectionMinimumEnergyConsumption, :drivingCourseMinimumEnergyConsumption => drivingCourseMinimumEnergyConsumption))
|
merge!(summarizedDict, Dict(:movingSectionMinimumEnergyConsumption => movingSectionMinimumEnergyConsumption, :drivingCourseMinimumEnergyConsumption => drivingCourseMinimumEnergyConsumption))
|
||||||
else
|
else
|
||||||
println("No output for minimum energy consumption has been demanded and so none will be calculated")
|
println("No output for minimum energy consumption has been demanded and so none will be calculated.")
|
||||||
end #if
|
end #if
|
||||||
|
|
||||||
return summarizedDict
|
return summarizedDict
|
||||||
|
@ -275,7 +276,8 @@ function copyCharacteristicSection(originalCS::Dict)
|
||||||
:v_limit => originalCS[:v_limit], # speed limit (in m/s)
|
:v_limit => originalCS[:v_limit], # speed limit (in m/s)
|
||||||
:v_peak => originalCS[:v_peak], # maximum reachable speed (in m/s)
|
:v_peak => originalCS[:v_peak], # maximum reachable speed (in m/s)
|
||||||
:v_entry => originalCS[:v_entry], # maximum entry speed (in m/s)
|
:v_entry => originalCS[:v_entry], # maximum entry speed (in m/s)
|
||||||
:v_exit => originalCS[:v_exit]) # maximum exit speed (in m/s)
|
:v_exit => originalCS[:v_exit], # maximum exit speed (in m/s)
|
||||||
|
:pointsOfInterest => originalCS[:pointsOfInterest]) # points of interest for which data points should be calculated
|
||||||
|
|
||||||
return copiedCS
|
return copiedCS
|
||||||
end # CharacteristicSection
|
end # CharacteristicSection
|
||||||
|
@ -699,7 +701,8 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
|
||||||
:v_limit => csOriginal[:v_limit], # speed limit (in m/s)
|
:v_limit => csOriginal[:v_limit], # speed limit (in m/s)
|
||||||
:v_peak => csOriginal[:v_peak], # maximum reachable speed (in m/s)
|
:v_peak => csOriginal[:v_peak], # maximum reachable speed (in m/s)
|
||||||
:v_entry => csOriginal[:v_entry], # maximum entry speed (in m/s)
|
:v_entry => csOriginal[:v_entry], # maximum entry speed (in m/s)
|
||||||
:v_exit => csOriginal[:v_exit]) # maximum exit speed (in m/s)
|
:v_exit => csOriginal[:v_exit], # maximum exit speed (in m/s)
|
||||||
|
:pointsOfInterest => csOriginal[:pointsOfInterest]) # points of interest for which data points should be calculated
|
||||||
|
|
||||||
BSsModified = csModified[:behaviorSections]
|
BSsModified = csModified[:behaviorSections]
|
||||||
if haskey(BSsOriginal, :breakFree)
|
if haskey(BSsOriginal, :breakFree)
|
||||||
|
@ -774,7 +777,8 @@ function increaseCoastingSection(csOriginal::Dict, drivingCourse::Vector{Dict},
|
||||||
:v_limit => csOriginal[:v_limit], # speed limit (in m/s)
|
:v_limit => csOriginal[:v_limit], # speed limit (in m/s)
|
||||||
:v_peak => csOriginal[:v_peak], # maximum reachable speed (in m/s)
|
:v_peak => csOriginal[:v_peak], # maximum reachable speed (in m/s)
|
||||||
:v_entry => csOriginal[:v_entry], # maximum entry speed (in m/s)
|
:v_entry => csOriginal[:v_entry], # maximum entry speed (in m/s)
|
||||||
:v_exit => csOriginal[:v_exit]) # maximum exit speed (in m/s)
|
:v_exit => csOriginal[:v_exit], # maximum exit speed (in m/s)
|
||||||
|
:pointsOfInterest => csOriginal[:pointsOfInterest]) # points of interest for which data points should be calculated
|
||||||
|
|
||||||
BSsModified = csModified[:behaviorSections]
|
BSsModified = csModified[:behaviorSections]
|
||||||
if haskey(BSsOriginal, :breakFree)
|
if haskey(BSsOriginal, :breakFree)
|
||||||
|
@ -881,7 +885,9 @@ function decreaseMaximumVelocity(csOriginal::Dict, drivingCourse, settings::Dict
|
||||||
:v_limit => csOriginal[:v_limit], # speed limit (in m/s)
|
:v_limit => csOriginal[:v_limit], # speed limit (in m/s)
|
||||||
:v_peak => csOriginal[:v_peak], # maximum reachable speed (in m/s)
|
:v_peak => csOriginal[:v_peak], # maximum reachable speed (in m/s)
|
||||||
:v_entry => csOriginal[:v_entry], # maximum entry speed (in m/s)
|
:v_entry => csOriginal[:v_entry], # maximum entry speed (in m/s)
|
||||||
:v_exit => csOriginal[:v_exit]) # maximum exit speed (in m/s)
|
:v_exit => csOriginal[:v_exit], # maximum exit speed (in m/s)
|
||||||
|
:pointsOfInterest => csOriginal[:pointsOfInterest]) # points of interest for which data points should be calculated
|
||||||
|
|
||||||
BSsModified = csModified[:behaviorSections]
|
BSsModified = csModified[:behaviorSections]
|
||||||
if haskey(BSsOriginal, :breakFree)
|
if haskey(BSsOriginal, :breakFree)
|
||||||
breakFreeSection=copyBehaviorSection(BSsOriginal[:breakFree])
|
breakFreeSection=copyBehaviorSection(BSsOriginal[:breakFree])
|
||||||
|
|
|
@ -10,9 +10,9 @@ export importYamlFiles, importYamlFile
|
||||||
Read the input information from YAML files for train, path and settings, save it in different dictionaries and return them.
|
Read the input information from YAML files for train, path and settings, save it in different dictionaries and return them.
|
||||||
"""
|
"""
|
||||||
function importYamlFiles(trainDirectory::String, pathDirectory::String, settingsDirectory::String)
|
function importYamlFiles(trainDirectory::String, pathDirectory::String, settingsDirectory::String)
|
||||||
train=importTrainFromYaml(trainDirectory)
|
train = importTrainFromYaml(trainDirectory)
|
||||||
path=importPathFromYaml(pathDirectory)
|
path = importPathFromYaml(pathDirectory)
|
||||||
settings=importSettingsFromYaml(settingsDirectory)
|
settings = importSettingsFromYaml(settingsDirectory)
|
||||||
|
|
||||||
return (train, path, settings)
|
return (train, path, settings)
|
||||||
end #function importYamlFiles
|
end #function importYamlFiles
|
||||||
|
@ -114,7 +114,7 @@ function importPathFromYaml(pathDirectory::String)
|
||||||
data = YAML.load(open(pathDirectory))
|
data = YAML.load(open(pathDirectory))
|
||||||
|
|
||||||
name = getString!(data, "path", "name")
|
name = getString!(data, "path", "name")
|
||||||
id=1 # path identifier
|
id=1 # path identifier
|
||||||
sections = getSections!(data)
|
sections = getSections!(data)
|
||||||
|
|
||||||
# save values in the path Dict
|
# save values in the path Dict
|
||||||
|
@ -122,6 +122,8 @@ function importPathFromYaml(pathDirectory::String)
|
||||||
:id => id,
|
:id => id,
|
||||||
:sections => sections)
|
:sections => sections)
|
||||||
|
|
||||||
|
addPointsOfInterest!(path, data)
|
||||||
|
|
||||||
informAboutUnusedKeys(data, "path") # inform the user, which keywords of the imported data are not used in this tool
|
informAboutUnusedKeys(data, "path") # inform the user, which keywords of the imported data are not used in this tool
|
||||||
|
|
||||||
return path
|
return path
|
||||||
|
@ -502,6 +504,48 @@ function getSections!(data::Dict)
|
||||||
return sections
|
return sections
|
||||||
end #function getSections!
|
end #function getSections!
|
||||||
|
|
||||||
|
function addPointsOfInterest!(path::Dict, data::Dict)
|
||||||
|
# read the section starting positions and corresponding information
|
||||||
|
if haskey(data["path"],"pointsOfInterest") && data["path"]["pointsOfInterest"]!=nothing
|
||||||
|
pointsOfInterest = data["path"]["pointsOfInterest"]
|
||||||
|
delete!(data["path"], "pointsOfInterest")
|
||||||
|
|
||||||
|
sortingNeeded = false
|
||||||
|
errorDetected = false
|
||||||
|
for element in 1:length(pointsOfInterest)
|
||||||
|
if typeof(pointsOfInterest[element]) <: Real
|
||||||
|
if element > 1
|
||||||
|
if pointsOfInterest[element] < pointsOfInterest[element-1]
|
||||||
|
sortingNeeded = true
|
||||||
|
println("INFO at reading the path yaml file: The point of interest in element ", element ," (",pointsOfInterest[element]," m) has to be higher than the value of the previous element (",pointsOfInterest[element-1]," m). The points of interest will be sorted.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
errorDetected = true
|
||||||
|
println("ERROR at reading the path yaml file: The point of interest in element ", element ," is no real floating point number.")
|
||||||
|
end
|
||||||
|
end # for
|
||||||
|
|
||||||
|
if errorDetected
|
||||||
|
error("ERROR at reading the path yaml file: The values of the point of interest have to be corrected.")
|
||||||
|
end
|
||||||
|
if sortingNeeded == true
|
||||||
|
sort!(pointsOfInterest)
|
||||||
|
end
|
||||||
|
|
||||||
|
copiedPOIs = []
|
||||||
|
for element in 1:length(pointsOfInterest)
|
||||||
|
if element == 1
|
||||||
|
push!(copiedPOIs, pointsOfInterest[element])
|
||||||
|
elseif element > 1 && pointsOfInterest[element] > pointsOfInterest[element-1]
|
||||||
|
push!(copiedPOIs, pointsOfInterest[element])
|
||||||
|
end
|
||||||
|
end # for
|
||||||
|
merge!(path, Dict(:pointsOfInterest => copiedPOIs))
|
||||||
|
end
|
||||||
|
return (path, data)
|
||||||
|
end #function addPointsOfInterest!
|
||||||
|
|
||||||
function informAboutUnusedKeys(data::Dict, dataSet::String) # inform the user which keywords of the imported data are not used in this tool
|
function informAboutUnusedKeys(data::Dict, dataSet::String) # inform the user which keywords of the imported data are not used in this tool
|
||||||
if length(data[dataSet])>0
|
if length(data[dataSet])>0
|
||||||
println("INFO at reading the ",dataSet," yaml file: The following Keywords are not used in this tool:")
|
println("INFO at reading the ",dataSet," yaml file: The following Keywords are not used in this tool:")
|
||||||
|
|
47
src/Input.jl
47
src/Input.jl
|
@ -68,6 +68,7 @@ function checkAndSetPath!(path::Dict)
|
||||||
checkString(path, "path", :name)
|
checkString(path, "path", :name)
|
||||||
# TODO checkId ? path[:id] # path identifier
|
# TODO checkId ? path[:id] # path identifier
|
||||||
checkAndSetSections!(path)
|
checkAndSetSections!(path)
|
||||||
|
checkAndSetPOIs!(path)
|
||||||
|
|
||||||
# TODO: informAboutUnusedKeys(path, "path") # inform the user, which Symbols of the input dictionary are not used in this tool
|
# TODO: informAboutUnusedKeys(path, "path") # inform the user, which Symbols of the input dictionary are not used in this tool
|
||||||
|
|
||||||
|
@ -400,6 +401,52 @@ function checkAndSetSections!(path::Dict)
|
||||||
return path
|
return path
|
||||||
end #function checkAndSetSections!
|
end #function checkAndSetSections!
|
||||||
|
|
||||||
|
function checkAndSetPOIs!(path::Dict)
|
||||||
|
# read the section starting positions and corresponding information
|
||||||
|
if haskey(path,:pointsOfInterest)
|
||||||
|
if path[:pointsOfInterest] != nothing
|
||||||
|
pointsOfInterest = path[:pointsOfInterest]
|
||||||
|
|
||||||
|
sortingNeeded = false
|
||||||
|
errorDetected = false
|
||||||
|
for element in 1:length(pointsOfInterest)
|
||||||
|
if typeof(pointsOfInterest[element]) <: Real
|
||||||
|
if element > 1
|
||||||
|
if pointsOfInterest[element] < pointsOfInterest[element-1]
|
||||||
|
sortingNeeded = true
|
||||||
|
println("INFO at checking the input dictionary for the path: The point of interest in element ", element ," (",pointsOfInterest[element]," m) has to be higher than the value of the previous element (",pointsOfInterest[element-1]," m). The points of interest will be sorted.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
errorDetected = true
|
||||||
|
println("ERROR at checking the input dictionary for the path: The point of interest in element ", element ," is no real floating point number.")
|
||||||
|
end
|
||||||
|
end # for
|
||||||
|
|
||||||
|
if errorDetected
|
||||||
|
error("ERROR at checking the input dictionary for the path: The values of the point of interest have to be corrected.")
|
||||||
|
end
|
||||||
|
if sortingNeeded == true
|
||||||
|
sort!(pointsOfInterest)
|
||||||
|
end
|
||||||
|
|
||||||
|
copiedPOIs = []
|
||||||
|
for element in 1:length(pointsOfInterest)
|
||||||
|
if element == 1
|
||||||
|
push!(copiedPOIs, pointsOfInterest[element])
|
||||||
|
elseif element > 1 && pointsOfInterest[element] > pointsOfInterest[element-1]
|
||||||
|
push!(copiedPOIs, pointsOfInterest[element])
|
||||||
|
end
|
||||||
|
end # for
|
||||||
|
path[:pointsOfInterest] = copiedPOIs
|
||||||
|
end
|
||||||
|
else
|
||||||
|
delete!(path, :pointsOfInterest)
|
||||||
|
end
|
||||||
|
|
||||||
|
return path
|
||||||
|
end #function checkAndSetPOIs!
|
||||||
|
|
||||||
function informAboutUnusedKeys(dictionary::Dict, dictionaryType::String) # inform the user which Symbols of the input dictionary are not used in this tool
|
function informAboutUnusedKeys(dictionary::Dict, dictionaryType::String) # inform the user which Symbols of the input dictionary are not used in this tool
|
||||||
#= if length(dictionary)>0
|
#= if length(dictionary)>0
|
||||||
println("INFO at checking the input dictionary for the ",dictionaryType,": The following Keywords are not used in this tool:")
|
println("INFO at checking the input dictionary for the ",dictionaryType,": The following Keywords are not used in this tool:")
|
||||||
|
|
|
@ -3,14 +3,37 @@ module Output
|
||||||
export createOutputDict
|
export createOutputDict
|
||||||
|
|
||||||
function createOutputDict(train::Dict, settings::Dict, path::Dict, movingSection::Dict, drivingCourse::Vector{Dict})
|
function createOutputDict(train::Dict, settings::Dict, path::Dict, movingSection::Dict, drivingCourse::Vector{Dict})
|
||||||
outputDict=Dict{Symbol,Any}()
|
outputDict = Dict{Symbol,Any}()
|
||||||
merge!(outputDict, Dict(:train => train, :path => path, :settings => settings))
|
merge!(outputDict, Dict(:train => train, :path => path, :settings => settings))
|
||||||
|
|
||||||
# adding moving section and drving courses
|
|
||||||
|
# add moving section and driving courses
|
||||||
if settings[:operationModeMinimumRunningTime] == true
|
if settings[:operationModeMinimumRunningTime] == true
|
||||||
merge!(outputDict, Dict(:movingSectionMinimumRunningTime => movingSection, :drivingCourseMinimumRunningTime => drivingCourse))
|
merge!(outputDict, Dict(:movingSectionMinimumRunningTime => movingSection,
|
||||||
|
:drivingCourseMinimumRunningTime => drivingCourse))
|
||||||
elseif settings[:operationModeMinimumEnergyConsumption] == true
|
elseif settings[:operationModeMinimumEnergyConsumption] == true
|
||||||
merge!(outputDict, Dict(:movingSectionMinimumEnergyConsumption => movingSection, :drivingCourseMinimumEnergyConsumption => drivingCourse))
|
merge!(outputDict, Dict(:movingSectionMinimumEnergyConsumption => movingSection,
|
||||||
|
:drivingCourseMinimumEnergyConsumption => drivingCourse))
|
||||||
|
end
|
||||||
|
|
||||||
|
# add points of interest
|
||||||
|
if haskey(path, :pointsOfInterest)
|
||||||
|
pointsOfInterest = Vector{Dict}()
|
||||||
|
POI = 1
|
||||||
|
i = 1
|
||||||
|
while(POI <= length(path[:pointsOfInterest]) && i <= drivingCourse[end][:i])
|
||||||
|
if path[:pointsOfInterest][POI] == drivingCourse[i][:s]
|
||||||
|
push!(pointsOfInterest, drivingCourse[i])
|
||||||
|
POI = POI+1
|
||||||
|
end
|
||||||
|
i = i+1
|
||||||
|
end
|
||||||
|
|
||||||
|
if settings[:operationModeMinimumRunningTime] == true
|
||||||
|
merge!(outputDict, Dict(:pointsOfInterestMinimumRunningTime => pointsOfInterest))
|
||||||
|
elseif settings[:operationModeMinimumEnergyConsumption] == true
|
||||||
|
merge!(outputDict, Dict(:pointsOfInterestMinimumEnergyConsumption => pointsOfInterest))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return outputDict
|
return outputDict
|
||||||
|
|
|
@ -43,7 +43,7 @@ function calculateDrivingDynamics(train::Dict, path::Dict, settings::Dict)
|
||||||
|
|
||||||
# calculate the train run for oparation mode "minimum running time"
|
# calculate the train run for oparation mode "minimum running time"
|
||||||
if settings[:operationModeMinimumRunningTime] || settings[:operationModeMinimumEnergyConsumption]
|
if settings[:operationModeMinimumRunningTime] || settings[:operationModeMinimumEnergyConsumption]
|
||||||
(movingSection, drivingCourse)=calculateMinimumRunningTime!(movingSection, settings, train)
|
(movingSection, drivingCourse) = calculateMinimumRunningTime!(movingSection, settings, train)
|
||||||
println("The driving course for the shortest running time has been calculated.")
|
println("The driving course for the shortest running time has been calculated.")
|
||||||
|
|
||||||
# summarize data and create an output dictionary
|
# summarize data and create an output dictionary
|
||||||
|
@ -79,11 +79,6 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
|
||||||
s_cruising = CS[:length] - s_breakFree - s_clearing - s_acceleration - s_braking
|
s_cruising = CS[:length] - s_breakFree - s_clearing - s_acceleration - s_braking
|
||||||
|
|
||||||
# reset the characteristic section (CS), delete behavior sections (BS) that were used during the preperation for setting v_entry, v_peak and v_exit
|
# reset the characteristic section (CS), delete behavior sections (BS) that were used during the preperation for setting v_entry, v_peak and v_exit
|
||||||
# 01/07 old: delete!(BSs, :breakFree)
|
|
||||||
# 01/07 old: delete!(BSs, :clearing)
|
|
||||||
# 01/07 old: delete!(BSs, :acceleration)
|
|
||||||
# 01/07 old: delete!(BSs, :diminishing)
|
|
||||||
# 01/07 old: delete!(BSs, :cruising)
|
|
||||||
CS[:behaviorSections] = Dict()
|
CS[:behaviorSections] = Dict()
|
||||||
CS[:E] = 0.0
|
CS[:E] = 0.0
|
||||||
CS[:t] = 0.0
|
CS[:t] = 0.0
|
||||||
|
@ -98,7 +93,7 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
|
||||||
# 09/21 elseif s_cruising > 0.0
|
# 09/21 elseif s_cruising > 0.0
|
||||||
# 09/21 elseif s_cruising > 0.01 # if the cruising section is longer than 1 cm (because of rounding issues not >0.0)
|
# 09/21 elseif s_cruising > 0.01 # if the cruising section is longer than 1 cm (because of rounding issues not >0.0)
|
||||||
if drivingCourse[end][:v] < CS[:v_peak]
|
if drivingCourse[end][:v] < CS[:v_peak]
|
||||||
(CS, drivingCourse)=addAccelerationSection!(CS, drivingCourse, settings, train, CSs)
|
(CS, drivingCourse) = addAccelerationSection!(CS, drivingCourse, settings, train, CSs)
|
||||||
end #if
|
end #if
|
||||||
|
|
||||||
if CS[:s_exit]-drivingCourse[end][:s]-max(0.0, (CS[:v_exit]^2-drivingCourse[end][:v]^2)/2/train[:a_braking]) < -0.001 # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
|
if CS[:s_exit]-drivingCourse[end][:s]-max(0.0, (CS[:v_exit]^2-drivingCourse[end][:v]^2)/2/train[:a_braking]) < -0.001 # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
|
||||||
|
@ -121,8 +116,7 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
|
||||||
end #if
|
end #if
|
||||||
end #if
|
end #if
|
||||||
|
|
||||||
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
||||||
s_braking=max(0.0, ceil((CS[:v_exit]^2-drivingCourse[end][:v]^2)/2/train[:a_braking], digits=approximationLevel)) # ceil is used to be sure that the train reaches v_exit at s_exit in spite of rounding errors
|
|
||||||
|
|
||||||
if drivingCourse[end][:v] > CS[:v_exit]
|
if drivingCourse[end][:v] > CS[:v_exit]
|
||||||
#(CS, drivingCourse)=addBrakingSection!(CS, drivingCourse, settings[:massModel], train, CSs)
|
#(CS, drivingCourse)=addBrakingSection!(CS, drivingCourse, settings[:massModel], train, CSs)
|
||||||
|
@ -138,7 +132,7 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
|
||||||
end =#
|
end =#
|
||||||
end #for
|
end #for
|
||||||
|
|
||||||
(CSs[end], drivingCourse)=addStandstill!(CSs[end], drivingCourse, settings, train, CSs)
|
(CSs[end], drivingCourse) = addStandstill!(CSs[end], drivingCourse, settings, train, CSs)
|
||||||
|
|
||||||
movingSection[:t] = drivingCourse[end][:t] # total running time (in s)
|
movingSection[:t] = drivingCourse[end][:t] # total running time (in s)
|
||||||
movingSection[:E] = drivingCourse[end][:E] # total energy consumption (in Ws)
|
movingSection[:E] = drivingCourse[end][:E] # total energy consumption (in Ws)
|
||||||
|
|
|
@ -8,24 +8,25 @@
|
||||||
using TrainRun, Test
|
using TrainRun, Test
|
||||||
|
|
||||||
allPaths=[]
|
allPaths=[]
|
||||||
push!(allPaths, "data/paths/path_1_10km_nConst_vConst.yaml")
|
push!(allPaths, importYamlFile(:path, "data/paths/path_1_10km_nConst_vConst.yaml"))
|
||||||
push!(allPaths, "data/paths/path_2_10km_nVar_vConst.yaml")
|
push!(allPaths, importYamlFile(:path, "data/paths/path_2_10km_nVar_vConst.yaml"))
|
||||||
push!(allPaths, "data/paths/path_3_10km_nConst_vVar.yaml")
|
push!(allPaths, importYamlFile(:path, "data/paths/path_3_10km_nConst_vVar.yaml"))
|
||||||
push!(allPaths, "data/paths/path_4_real_Ostsachsen_DG-DN_spp_5.yaml")
|
push!(allPaths, importYamlFile(:path, "data/paths/path_4_real_Germany_EastSaxony_DG-DN.yaml"))
|
||||||
|
|
||||||
|
|
||||||
allSettings=[]
|
allSettings=[]
|
||||||
push!(allSettings, "data/settings.yaml")
|
push!(allSettings, importYamlFile(:settings, "data/settings.yaml"))
|
||||||
|
|
||||||
allTrains=[]
|
allTrains=[]
|
||||||
push!(allTrains, "data/trains/train_freight_V90withOreConsist.yaml")
|
push!(allTrains, importYamlFile(:train, "data/trains/train_freight_V90withOreConsist.yaml"))
|
||||||
push!(allTrains, "data/trains/train_passenger_SiemensDesiroClassic.yaml")
|
push!(allTrains, importYamlFile(:train, "data/trains/train_passenger_SiemensDesiroClassic.yaml"))
|
||||||
push!(allTrains, "data/trains/train_passenger_IC2.yaml")
|
push!(allTrains, importYamlFile(:train, "data/trains/train_passenger_IC2.yaml"))
|
||||||
|
|
||||||
for pathDirectory in allPaths
|
|
||||||
for trainDirectory in allTrains
|
|
||||||
for settingsDirectory in allSettings
|
|
||||||
testDict=calculateDrivingDynamics(trainDirectory, pathDirectory, settingsDirectory)
|
|
||||||
|
|
||||||
|
for path in allPaths
|
||||||
|
for train in allTrains
|
||||||
|
for settings in allSettings
|
||||||
|
testDict=calculateDrivingDynamics(train, path, settings)
|
||||||
|
exportToCsv(testDict)
|
||||||
sleep(2)
|
sleep(2)
|
||||||
|
|
||||||
# TODO:
|
# TODO:
|
||||||
|
|
Loading…
Reference in New Issue