separate file for constructors

development
Martin Scheidt 2022-05-08 21:43:21 +02:00
parent f10d20b0b1
commit d4e7806efc
4 changed files with 414 additions and 403 deletions

View File

@ -34,9 +34,15 @@ julia> # use the ] key
(TrainRuns) pkg> (TrainRuns) pkg>
``` ```
## TrainRuns files ## Files in TrainRuns
TODO! | file | concern |
| --------------- | ------------------------------ |
| TrainRuns.jl | main file and function |
| types.jl | special TrainRuns types |
| constructors.jl | type constructors |
| formulary.jl | formulars from literature |
| output.jl | transformation into DataFrames |
## Reporting Issues ## Reporting Issues

View File

@ -19,6 +19,7 @@ trainrun, Path, Settings, exportToCsv
## include package files ## include package files
include("types.jl") include("types.jl")
include("constructors.jl")
include("formulary.jl") include("formulary.jl")
include("characteristics.jl") include("characteristics.jl")
include("behavior.jl") include("behavior.jl")

405
src/constructors.jl Normal file
View File

@ -0,0 +1,405 @@
#!/usr/bin/env julia
# -*- coding: UTF-8 -*-
# __julia-version__ = 1.7.2
# __author__ = "Martin Scheidt"
# __copyright__ = "2022"
# __license__ = "ISC"
"""
Settings(file)
Settings is a datastruture for calculation context.
The function Settings() will create a set of settings for the train run calculation.
`file` is optinal may be used to load settings in the YAML format.
# Example
```jldoctest
julia> my_settings = Settings() # will generate default settings
Settings(mass_point, :distance, 20, 3, running_time, julia_dict, ".")
```
"""
function Settings(file="DEFAULT")
## default values
massModel = :mass_point
stepVariable = :distance
stepSize = 20
approxLevel = 3
outputDetail = :running_time
outputFormat = :julia_dict
outputDir = "."
## load from file
if file != "DEFAULT"
## JSON schema for YAML-file validation
schema = Schema("""{
"properties": {
"massModel": {
"description": "type of train model",
"type": "string",
"enum": [ "mass_point", "homogeneous_strip" ]
},
"stepVariable": {
"description": "variable of the linear multistep method",
"type": "string",
"enum": [ "distance", "time", "velocity" ]
},
"stepSize": {
"description": "step size acording to stepVariable",
"type": "number",
"exclusiveMinimum": 0
},
"outputDetail": {
"description": "Selecting the detail of the result",
"type": "string",
"enum": [ "running_time", "points_of_interest", "driving_course", "everything" ]
},
"outputFormat": {
"description": "Output format",
"type": "string",
"enum": [ "julia_dict", "csv" ]
},
"outputDir": {
"description": "Path for the CSV export",
"type": "string"
}
}
}""")
settings = YAML.load(open(file))["settings"]
## validate the loaded file
try
validate(schema, settings)
catch err
println("Could not load settings file '$file'.\n Format is not recognized - using default as fall back.")
settings = Dict()
end
## set the variables if they exist in "settings"
haskey(settings, "massModel") ? massModel = Symbol(settings["massModel"]) : nothing
haskey(settings, "stepVariable") ? stepVariable = Symbol(settings["stepVariable"]) : nothing
haskey(settings, "stepSize") ? stepSize = settings["stepSize"] : nothing
haskey(settings, "approxLevel") ? approxLevel = settings["approxLevel"] : nothing
haskey(settings, "outputDetail") ? outputDetail = Symbol(settings["outputDetail"]) : nothing
haskey(settings, "outputFormat") ? outputFormat = Symbol(settings["outputFormat"]) : nothing
haskey(settings, "outputDir") ? outputDir = settings["outputDir"] : nothing
end
Settings(massModel, stepVariable, stepSize, approxLevel, outputDetail, outputFormat, outputDir)
end #function Settings() # constructor
"""
Path(file, type = :YAML)
Path is a datastruture for calculation context.
The function Path() will create a running path for the train.
Supported formats are: railtoolkit/schema (2022.05)
# Example
```jldoctest
julia> my_path = Path("file.yaml") # will generate a path from a YAML file.
Path(variables)
```
"""
function Path(file, type = :YAML)
## default values
name = ""
id = ""
uuid = UUIDs.uuid4()
poi = []
sections = []
## process flags
POI_PRESENT = false
## load from file
if type == :YAML
data = YAML.load(open(file))
if data["schema"] != "https://railtoolkit.org/schema/running-path.json"
error("Could not load path file '$file'.\n
YAML format is not recognized.
Currently supported: railtoolkit/schema/running-path (2022.05)")
end
if data["schema_version"] != "2022.05"
error("Could not load path file '$file'.\n
YAML format is not recognized.
Currently supported: railtoolkit/schema/running-path (2022.05)")
end
## JSON schema for YAML-file validation
railtoolkit_schema = Schema("""{
"required": [ "schema", "schema_version", "paths" ],
"properties": {
"schema": {
"description": "Identifier of the schema",
"enum": [ "https://railtoolkit.org/schema/running-path.json" ]
},
"schema_version": {
"description": "Version of the schema",
"type": "string",
"pattern": "[2-9][0-9][0-9][0-9].[0-1][0-9]"
},
"paths": {
"type": "array",
"minItems": 1,
"items": {
"required": [ "name", "id", "characteristic_sections" ],
"type": "object",
"properties": {
"characteristic_sections": {
"description": "",
"type": "array",
"minItems": 2,
"uniqueItems": true,
"items": {
"type": "array",
"minItems": 3,
"maxItems": 3,
"description": "",
"prefixItems": [
{
"description": "milage in meter",
"type": "number"
},
{
"description": "speed in kilometers per hour",
"type": "number",
"exclusiveMinimum": 0
},
{
"description": "resistance in permil",
"type": "number"
}
]
}
},
"id": {
"description": "Identifier of the path",
"type": "string"
},
"name": {
"description": "Name of the path",
"type": "string"
},
"points_of_interest": {
"description": "",
"type": "array",
"uniqueItems": true,
"items": {
"type": "array",
"minItems": 3,
"maxItems": 3,
"description": "",
"prefixItems": [
{ "type": "number" },
{ "type": "string" },
{ "enum": [ "front", "rear" ] }
]
}
},
"UUID": {
"description": "The unique identifier for a path",
"type": "string",
"format": "uuid"
}
}
}
}
}
}""")
paths = data["paths"]
try
validate(railtoolkit_schema, paths)
catch err
error("Could not load path file '$file'.\n
YAML format is not recognized.
Currently supported: railtoolkit/schema/running-path (2022.05)")
end
if length(paths) > 1
println("WARNING: the loaded file contains more than one path. Using only the first!")
end
path = paths[1]
## set the variables if they exist in "settings"
# required
name = path["name"]
id = path["id"]
tmp_sec = path["characteristic_sections"]
# optional
haskey(path, "UUID") ? uuid = parse(UUID, path["UUID"] ) : nothing
haskey(path, "points_of_interest") ? POI_PRESENT = true : nothing
haskey(path, "points_of_interest") ? tmp_points = path["points_of_interest"] : nothing
else
error("Unknown file type '$type'")
end #if type
## process characteristic sections
sort!(tmp_sec, by = x -> x[1])
for row in 2:length(tmp_sec)
s_start = tmp_sec[row-1][1] # first point of the section (in m)
s_end = tmp_sec[row][1] # first point of the next section (in m)
v_limit = tmp_sec[row-1][2]/3.6 # paths speed limt (in m/s)
f_Rp = tmp_sec[row-1][3] # specific path resistance of the section (in ‰)
section = Dict(:s_start => s_start,
:s_end => s_end,
:v_limit => v_limit,
:f_Rp => f_Rp)
push!(sections, section)
end #for row
# s_start in first entry defines the path's beginning
# s_end in last entry defines the path's ending
## process points of interest
if POI_PRESENT
sort!(tmp_points, by = x -> x[1])
for elem in tmp_points
station = elem[1] # first point of the section (in m)
label = elem[2] # paths speed limt (in m/s)
measure = elem[3] # specific path resistance of the section (in ‰)
point = Dict(:station => station,
:label => label,
:measure => measure)
push!(poi, point)
end #for elem
end #if !isempty(points)
Path(name, id, uuid, poi, sections)
end #function Path() # constructor
## create a moving section containing characteristic sections
function createMovingSection(path::Path, v_trainLimit::Real, s_trainLength::Real)
# this function creates and returns a moving section dependent on the paths attributes
s_entry = path.sections[1][:s_start] # first position (in m)
s_exit = path.sections[end][:s_end] # last position (in m)
pathLength = s_exit - s_entry # total length (in m)
CSs=Vector{Dict}()
s_csStart=s_entry
csId=1
for row in 2:length(path.sections)
previousSection = path.sections[row-1]
currentSection = path.sections[row]
speedLimitIsDifferent = min(previousSection[:v_limit], v_trainLimit) != min(currentSection[:v_limit], v_trainLimit)
pathResistanceIsDifferent = previousSection[:f_Rp] != currentSection[:f_Rp]
if speedLimitIsDifferent || pathResistanceIsDifferent
# 03/09 old: 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), s_trainLength, path))
s_csStart = currentSection[:s_start]
csId = csId+1
end #if
end #for
push!(CSs, createCharacteristicSection(csId, s_csStart, path.sections[end], min(path.sections[end][:v_limit], v_trainLimit), s_trainLength, 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
:length => pathLength, # total length (in m)
:s_entry => s_entry, # first position (in m)
:s_exit => s_exit, # last position (in m)
:t => 0.0, # total running time (in s)
:E => 0.0, # total energy consumption (in Ws)
:characteristicSections => CSs) # list of containing characteristic sections
return movingSection
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.
function createCharacteristicSection(id::Integer, s_entry::Real, section::Dict, v_limit::Real, s_trainLength::Real, path::Path)
# Create and return a characteristic section dependent on the paths attributes
characteristicSection= Dict(:id => id, # identifier
:s_entry => s_entry, # first position (in m)
:s_exit => section[:s_end], # last position (in m)
:length => section[:s_end] -s_entry, # total length (in m)
:r_path => section[:f_Rp], # path resistance (in ‰)
:behaviorSections => Dict(), # list of containing behavior sections
:t => 0.0, # total running time (in s)
:E => 0.0, # total energy consumption (in Ws)
:v_limit => v_limit, # speed limit (in m/s)
# initializing :v_entry, :v_peak and :v_exit with :v_limit
:v_peak => v_limit, # maximum reachable speed (in m/s)
:v_entry => v_limit, # maximum entry 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]
##TODO: use a tuple with naming
pointsOfInterest = Tuple[]
# pointsOfInterest = Real[]
if !isempty(path.poi)
for POI in path.poi
s_poi = POI[:station]
if POI[:measure] == "rear"
s_poi -= s_trainLength
end
if s_entry < s_poi && s_poi < s_exit
push!(pointsOfInterest, (s_poi, POI[:label]) )
# push!(pointsOfInterest, s_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
# 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
end #function createCharacteristicSection
"""
a DataPoint is the smallest element of the driving course. One step of the step approach is between two data points
"""
function createDataPoint()
dataPoint = Dict(
:i => 0, # identifier and counter variable of the driving course
:behavior => "", # type of behavior section the data point is part of - see createBehaviorSection()
# a data point which is the last point of one behavior section and the first point of the next behavior section will be attached to the latter
:s => 0.0, # position (in m)
:Δs => 0.0, # step size (in m)
:t => 0.0, # point in time (in s)
:Δt => 0.0, # step size (in s)
:v => 0.0, # velocity (in m/s)
:Δv => 0.0, # step size (in m/s)
:a => 0.0, # acceleration (in m/s^2)
:W => 0.0, # mechanical work (in Ws)
:ΔW => 0.0, # mechanical work in this step (in Ws)
:E => 0.0, # energy consumption (in Ws)
:ΔE => 0.0, # energy consumption in this step (in Ws)
:F_T => 0.0, # tractive effort (in N)
:F_R => 0.0, # resisting force (in N)
:R_path => 0.0, # path resistance (in N)
:R_train => 0.0, # train resistance (in N)
:R_traction => 0.0, # traction unit resistance (in N)
:R_wagons => 0.0, # set of wagons resistance (in N)
:label => "" # a label for importend points
)
return dataPoint
end #function createDataPoint
"""
BehaviorSection() TODO!
"""
function createBehaviorSection(type::String, s_entry::Real, v_entry::Real, startingPoint::Integer)
BS= Dict(
:type => type, # type of behavior section: "breakFree", "clearing", "accelerating", "cruising", "downhillBraking", "diminishing", "coasting", "braking" or "standstill"
:length => 0.0, # total length (in m)
:s_entry => s_entry, # first position (in m)
:s_exit => 0.0, # last position (in m)
:t => 0.0, # total running time (in s)
:E => 0.0, # total energy consumption (in Ws)
:v_entry => v_entry, # entry speed (in m/s)
:v_exit => 0.0, # exit speed (in m/s)
:dataPoints => [startingPoint] # list of identifiers of the containing data points starting with the initial point
)
return BS
end #function createBehaviorSection

View File

@ -5,19 +5,6 @@
# __copyright__ = "2022" # __copyright__ = "2022"
# __license__ = "ISC" # __license__ = "ISC"
"""
Settings(file)
Settings is a datastruture for calculation context.
The function Settings() will create a set of settings for the train run calculation.
`file` is optinal may be used to load settings in the YAML format.
# Example
```jldoctest
julia> my_settings = Settings() # will generate default settings
Settings(mass_point, :distance, 20, 3, running_time, julia_dict, ".")
```
"""
struct Settings struct Settings
massModel::Symbol # model type of train mass ":mass_point" or ":homogeneous_strip". massModel::Symbol # model type of train mass ":mass_point" or ":homogeneous_strip".
@ -29,95 +16,8 @@ struct Settings
outputFormat::Symbol # output as ":julia_dict" or as ":csv". outputFormat::Symbol # output as ":julia_dict" or as ":csv".
outputDir::String # if outputFormat is not ":julia_dict". outputDir::String # if outputFormat is not ":julia_dict".
## constructor
function Settings(file="DEFAULT")
## default values
massModel = :mass_point
stepVariable = :distance
stepSize = 20
approxLevel = 3
outputDetail = :running_time
outputFormat = :julia_dict
outputDir = "."
## load from file
if file != "DEFAULT"
## JSON schema for YAML-file validation
schema = Schema("""{
"properties": {
"massModel": {
"description": "type of train model",
"type": "string",
"enum": [ "mass_point", "homogeneous_strip" ]
},
"stepVariable": {
"description": "variable of the linear multistep method",
"type": "string",
"enum": [ "distance", "time", "velocity" ]
},
"stepSize": {
"description": "step size acording to stepVariable",
"type": "number",
"exclusiveMinimum": 0
},
"outputDetail": {
"description": "Selecting the detail of the result",
"type": "string",
"enum": [ "running_time", "points_of_interest", "driving_course", "everything" ]
},
"outputFormat": {
"description": "Output format",
"type": "string",
"enum": [ "julia_dict", "csv" ]
},
"outputDir": {
"description": "Path for the CSV export",
"type": "string"
}
}
}""")
settings = YAML.load(open(file))["settings"]
## validate the loaded file
try
validate(schema, settings)
catch err
println("Could not load settings file '$file'.\n Format is not recognized - using default as fall back.")
settings = Dict()
end
## set the variables if they exist in "settings"
haskey(settings, "massModel") ? massModel = Symbol(settings["massModel"]) : nothing
haskey(settings, "stepVariable") ? stepVariable = Symbol(settings["stepVariable"]) : nothing
haskey(settings, "stepSize") ? stepSize = settings["stepSize"] : nothing
haskey(settings, "approxLevel") ? approxLevel = settings["approxLevel"] : nothing
haskey(settings, "outputDetail") ? outputDetail = Symbol(settings["outputDetail"]) : nothing
haskey(settings, "outputFormat") ? outputFormat = Symbol(settings["outputFormat"]) : nothing
haskey(settings, "outputDir") ? outputDir = settings["outputDir"] : nothing
end
new(massModel, stepVariable, stepSize, approxLevel, outputDetail, outputFormat, outputDir)
end #function Settings() # constructor
end #struct Settings end #struct Settings
"""
Path(file, type = :YAML)
Path is a datastruture for calculation context.
The function Path() will create a running path for the train.
Supported formats are: railtoolkit/schema (2022.05)
# Example
```jldoctest
julia> my_path = Path("file.yaml") # will generate a path from a YAML file.
Path(variables)
```
"""
struct Path struct Path
name::String # a name or description of the path name::String # a name or description of the path
@ -126,309 +26,8 @@ struct Path
poi::Vector # a vector of triples with points along the path poi::Vector # a vector of triples with points along the path
sections::Vector # a vector of the characteristic sections sections::Vector # a vector of the characteristic sections
## constructor
function Path(file, type = :YAML)
## default values
name = ""
id = ""
uuid = UUIDs.uuid4()
poi = []
sections = []
## process flags
POI_PRESENT = false
## load from file
if type == :YAML
data = YAML.load(open(file))
if data["schema"] != "https://railtoolkit.org/schema/running-path.json"
error("Could not load path file '$file'.\n
YAML format is not recognized.
Currently supported: railtoolkit/schema/running-path (2022.05)")
end
if data["schema_schema"] != "2022.05"
error("Could not load path file '$file'.\n
YAML format is not recognized.
Currently supported: railtoolkit/schema/running-path (2022.05)")
end
## JSON schema for YAML-file validation
railtoolkit_schema = Schema("""{
"required": [ "schema", "schema_version", "paths" ],
"properties": {
"schema": {
"description": "Identifier of the schema",
"enum": [ "https://railtoolkit.org/schema/running-path.json" ]
},
"schema_version": {
"description": "Version of the schema",
"type": "string",
"pattern": "[2-9][0-9][0-9][0-9].[0-1][0-9]"
},
"paths": {
"type": "array",
"minItems": 1,
"items": {
"required": [ "name", "id", "characteristic_sections" ],
"type": "object",
"properties": {
"characteristic_sections": {
"description": "",
"type": "array",
"minItems": 2,
"uniqueItems": true,
"items": {
"type": "array",
"minItems": 3,
"maxItems": 3,
"description": "",
"prefixItems": [
{
"description": "milage in meter",
"type": "number"
},
{
"description": "speed in kilometers per hour",
"type": "number",
"exclusiveMinimum": 0
},
{
"description": "resistance in permil",
"type": "number"
}
]
}
},
"id": {
"description": "Identifier of the path",
"type": "string"
},
"name": {
"description": "Name of the path",
"type": "string"
},
"points_of_interest": {
"description": "",
"type": "array",
"uniqueItems": true,
"items": {
"type": "array",
"minItems": 3,
"maxItems": 3,
"description": "",
"prefixItems": [
{ "type": "number" },
{ "type": "string" },
{ "enum": [ "front", "rear" ] }
]
}
},
"UUID": {
"description": "The unique identifier for a path",
"type": "string",
"format": "uuid"
}
}
}
}
}
}""")
paths = data["paths"]
try
validate(railtoolkit_schema, paths)
catch err
error("Could not load path file '$file'.\n
YAML format is not recognized.
Currently supported: railtoolkit/schema/running-path (2022.05)")
end
if length(paths) > 1
println("WARNING: the loaded file contains more than one path. Using only the first!")
end
path = paths[1]
## set the variables if they exist in "settings"
# required
name = path["name"]
id = path["id"]
tmp_sec = path["characteristic_sections"]
# optional
haskey(path, "UUID") ? uuid = parse(UUID, path["UUID"] ) : nothing
haskey(path, "points_of_interest") ? POI_PRESENT = true : nothing
haskey(path, "points_of_interest") ? tmp_points = path["points_of_interest"] : nothing
else
error("Unknown file type '$type'")
end #if type
## process characteristic sections
sort!(tmp_sec, by = x -> x[1])
for row in 2:length(tmp_sec)
s_start = tmp_sec[row-1][1] # first point of the section (in m)
s_end = tmp_sec[row][1] # first point of the next section (in m)
v_limit = tmp_sec[row-1][2]/3.6 # paths speed limt (in m/s)
f_Rp = tmp_sec[row-1][3] # specific path resistance of the section (in ‰)
section = Dict(:s_start => s_start,
:s_end => s_end,
:v_limit => v_limit,
:f_Rp => f_Rp)
push!(sections, section)
end #for row
# s_start in first entry defines the path's beginning
# s_end in last entry defines the path's ending
## process points of interest
if POI_PRESENT
sort!(tmp_points, by = x -> x[1])
for elem in tmp_points
station = elem[1] # first point of the section (in m)
label = elem[2] # paths speed limt (in m/s)
measure = elem[3] # specific path resistance of the section (in ‰)
point = Dict(:station => station,
:label => label,
:measure => measure)
push!(poi, point)
end #for elem
end #if !isempty(points)
new(name, id, uuid, poi, sections)
end #function Path
end #struct Path end #struct Path
"""
a DataPoint is the smallest element of the driving course. One step of the step approach is between two data points
"""
function createDataPoint()
dataPoint = Dict(
:i => 0, # identifier and counter variable of the driving course
:behavior => "", # type of behavior section the data point is part of - see createBehaviorSection()
# a data point which is the last point of one behavior section and the first point of the next behavior section will be attached to the latter
:s => 0.0, # position (in m)
:Δs => 0.0, # step size (in m)
:t => 0.0, # point in time (in s)
:Δt => 0.0, # step size (in s)
:v => 0.0, # velocity (in m/s)
:Δv => 0.0, # step size (in m/s)
:a => 0.0, # acceleration (in m/s^2)
:W => 0.0, # mechanical work (in Ws)
:ΔW => 0.0, # mechanical work in this step (in Ws)
:E => 0.0, # energy consumption (in Ws)
:ΔE => 0.0, # energy consumption in this step (in Ws)
:F_T => 0.0, # tractive effort (in N)
:F_R => 0.0, # resisting force (in N)
:R_path => 0.0, # path resistance (in N)
:R_train => 0.0, # train resistance (in N)
:R_traction => 0.0, # traction unit resistance (in N)
:R_wagons => 0.0, # set of wagons resistance (in N)
:label => "" # a label for importend points
)
return dataPoint
end #function createDataPoint
"""
BehaviorSection() TODO!
"""
function createBehaviorSection(type::String, s_entry::Real, v_entry::Real, startingPoint::Integer)
BS= Dict(
:type => type, # type of behavior section: "breakFree", "clearing", "accelerating", "cruising", "downhillBraking", "diminishing", "coasting", "braking" or "standstill"
:length => 0.0, # total length (in m)
:s_entry => s_entry, # first position (in m)
:s_exit => 0.0, # last position (in m)
:t => 0.0, # total running time (in s)
:E => 0.0, # total energy consumption (in Ws)
:v_entry => v_entry, # entry speed (in m/s)
:v_exit => 0.0, # exit speed (in m/s)
:dataPoints => [startingPoint] # list of identifiers of the containing data points starting with the initial point
)
return BS
end #function createBehaviorSection
## create a moving section containing characteristic sections
function createMovingSection(path::Path, v_trainLimit::Real, s_trainLength::Real)
# this function creates and returns a moving section dependent on the paths attributes
s_entry = path.sections[1][:s_start] # first position (in m)
s_exit = path.sections[end][:s_end] # last position (in m)
pathLength = s_exit - s_entry # total length (in m)
CSs=Vector{Dict}()
s_csStart=s_entry
csId=1
for row in 2:length(path.sections)
previousSection = path.sections[row-1]
currentSection = path.sections[row]
speedLimitIsDifferent = min(previousSection[:v_limit], v_trainLimit) != min(currentSection[:v_limit], v_trainLimit)
pathResistanceIsDifferent = previousSection[:f_Rp] != currentSection[:f_Rp]
if speedLimitIsDifferent || pathResistanceIsDifferent
# 03/09 old: 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), s_trainLength, path))
s_csStart = currentSection[:s_start]
csId = csId+1
end #if
end #for
push!(CSs, createCharacteristicSection(csId, s_csStart, path.sections[end], min(path.sections[end][:v_limit], v_trainLimit), s_trainLength, 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
:length => pathLength, # total length (in m)
:s_entry => s_entry, # first position (in m)
:s_exit => s_exit, # last position (in m)
:t => 0.0, # total running time (in s)
:E => 0.0, # total energy consumption (in Ws)
:characteristicSections => CSs) # list of containing characteristic sections
return movingSection
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.
function createCharacteristicSection(id::Integer, s_entry::Real, section::Dict, v_limit::Real, s_trainLength::Real, path::Path)
# Create and return a characteristic section dependent on the paths attributes
characteristicSection= Dict(:id => id, # identifier
:s_entry => s_entry, # first position (in m)
:s_exit => section[:s_end], # last position (in m)
:length => section[:s_end] -s_entry, # total length (in m)
:r_path => section[:f_Rp], # path resistance (in ‰)
:behaviorSections => Dict(), # list of containing behavior sections
:t => 0.0, # total running time (in s)
:E => 0.0, # total energy consumption (in Ws)
:v_limit => v_limit, # speed limit (in m/s)
# initializing :v_entry, :v_peak and :v_exit with :v_limit
:v_peak => v_limit, # maximum reachable speed (in m/s)
:v_entry => v_limit, # maximum entry 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]
##TODO: use a tuple with naming
pointsOfInterest = Tuple[]
# pointsOfInterest = Real[]
if !isempty(path.poi)
for POI in path.poi
s_poi = POI[:station]
if POI[:measure] == "rear"
s_poi -= s_trainLength
end
if s_entry < s_poi && s_poi < s_exit
push!(pointsOfInterest, (s_poi, POI[:label]) )
# push!(pointsOfInterest, s_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
# 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
end #function createCharacteristicSection
""" """
Read the train information from a YAML file, save it in a train Dict and return it. Read the train information from a YAML file, save it in a train Dict and return it.
""" """