new type Settings as struct
parent
25959f7302
commit
e2842157da
18
CHANGELOG.md
18
CHANGELOG.md
|
@ -9,6 +9,24 @@ Categories: Added, Changed, Deprecated, Removed, Fixed, and Security.
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
* dependency JSONSchema
|
||||||
|
* validation of YAML input via JSON schema
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
* replaced settings::Dict with type Settings as struct
|
||||||
|
* restructured examples/ and data/ in docs/ and test/
|
||||||
|
* modified test to work with Julia Testsets and with simplier naming of input files
|
||||||
|
* renamed Validate.jl into types.jl
|
||||||
|
* renamed TrainRunCalc.jl into calc.jl
|
||||||
|
* changed capital letter of include files to lower letter
|
||||||
|
* changed seperation of submodules into a single module with file include
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
* dependency Plots
|
||||||
|
* AdditionalOutput.jl
|
||||||
|
* EnergySaving.jl
|
||||||
|
* test/testEnums.jl
|
||||||
|
|
||||||
## Version [0.8] 2022-01-20
|
## Version [0.8] 2022-01-20
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,15 @@ email, or any other method with the owners of this repository before making a ch
|
||||||
|
|
||||||
Please note we have a code of conduct, please follow it in all your interactions with the project.
|
Please note we have a code of conduct, please follow it in all your interactions with the project.
|
||||||
|
|
||||||
|
# Julia Development Environment
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ln -s ~/path/to/TrainRun.jl ~/.julia/dev/TrainRun
|
||||||
|
```
|
||||||
|
|
||||||
|
and use `Revise.jl`
|
||||||
|
|
||||||
|
|
||||||
# Pull Request Process
|
# Pull Request Process
|
||||||
|
|
||||||
* add your changes to the CHANGELOG.md under [Unreleased]
|
* add your changes to the CHANGELOG.md under [Unreleased]
|
||||||
|
|
14
Project.toml
14
Project.toml
|
@ -1,12 +1,20 @@
|
||||||
name = "TrainRun"
|
name = "TrainRun"
|
||||||
uuid = "e4541106-d44c-4e00-b50b-ecdf479fcf92"
|
uuid = "e4541106-d44c-4e00-b50b-ecdf479fcf92"
|
||||||
authors = ["Max Kannenberg"]
|
authors = ["Max Kannenberg, Martin Scheidt, and contributors"]
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
|
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
|
||||||
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
|
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
|
||||||
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
|
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
|
||||||
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
|
JSONSchema = "7d188eb4-7ad8-530c-ae41-71a32a6d4692"
|
||||||
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
|
||||||
YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"
|
YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"
|
||||||
|
|
||||||
|
[compat]
|
||||||
|
julia = "1.7"
|
||||||
|
|
||||||
|
[extras]
|
||||||
|
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
||||||
|
|
||||||
|
[targets]
|
||||||
|
test = ["Test"]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# TrainRun
|
# TrainRun
|
||||||
|
|
||||||
[![License: ISC](https://img.shields.io/badge/license-ISC-green.svg)](https://opensource.org/licenses/ISC) [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6448563.svg)](https://doi.org/10.5281/zenodo.6448563)
|
[![License: ISC](https://img.shields.io/badge/license-ISC-green.svg)](https://opensource.org/licenses/ISC) [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6448563.svg)](https://doi.org/10.5281/zenodo.6448563)
|
||||||
|
[![Build Status](https://github.com/railtoolkit/TrainRun.jl/actions/workflows/CI.yml/badge.svg?branch=master)](https://github.com/railtoolkit/TrainRun.jl/actions/workflows/CI.yml?query=branch%3Amaster)
|
||||||
|
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
%YAML 1.2
|
|
||||||
---
|
|
||||||
settings:
|
|
||||||
# settings for the simulation
|
|
||||||
massModel: "homogeneous strip" # model type of train mass "mass point" or "homogeneous strip"
|
|
||||||
stepVariable: "s in m" # step variable of the step method "s in m", "t in s" or "v in m/s"
|
|
||||||
stepSize: 10 # step size (unit depends on stepVariable s in m, t in s and v in m/s)
|
|
||||||
operationModeMinimumRunningTime: true # operation mode "minimum running time"
|
|
||||||
operationModeMinimumEnergyConsumption: false # operation mode "minimum energy consumption"
|
|
||||||
typeOfOutput: "julia dictionary" # output as "julia dictionary" or as "CSV"
|
|
||||||
detailOfOutput: "driving course" # should the output be only the value of the "running time" or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
|
|
||||||
csvDirectory: "~/Desktop/TrainRun"
|
|
|
@ -1,12 +0,0 @@
|
||||||
%YAML 1.2
|
|
||||||
---
|
|
||||||
settings:
|
|
||||||
# settings for the simulation
|
|
||||||
massModel: "mass point" # model type of train mass "mass point" or "homogeneous strip"
|
|
||||||
stepVariable: "s in m" # step variable of the step method "s in m", "t in s" or "v in m/s"
|
|
||||||
stepSize: 10 # step size (unit depends on stepVariable s in m, t in s and v in m/s)
|
|
||||||
operationModeMinimumRunningTime: true # operation mode "minimum running time"
|
|
||||||
operationModeMinimumEnergyConsumption: false # operation mode "minimum energy consumption"
|
|
||||||
typeOfOutput: "julia dictionary" # output as "julia dictionary" or as "CSV"
|
|
||||||
detailOfOutput: "driving course" # should the output be only the value of the "running time" or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
|
|
||||||
csvDirectory: "~/Desktop/TrainRun"
|
|
|
@ -1,12 +0,0 @@
|
||||||
%YAML 1.2
|
|
||||||
---
|
|
||||||
settings:
|
|
||||||
# settings for the simulation
|
|
||||||
massModel: "mass point" # model type of train mass "mass point" or "homogeneous strip"
|
|
||||||
stepVariable: "s in m" # step variable of the step method "s in m", "t in s" or "v in m/s"
|
|
||||||
stepSize: 10 # step size (unit depends on stepVariable s in m, t in s and v in m/s)
|
|
||||||
operationModeMinimumRunningTime: true # operation mode "minimum running time"
|
|
||||||
operationModeMinimumEnergyConsumption: false # operation mode "minimum energy consumption"
|
|
||||||
typeOfOutput: "CSV" # output as "julia dictionary" or as "CSV"
|
|
||||||
detailOfOutput: "running time" # should the output be only the value of the "running time" or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
|
|
||||||
csvDirectory: "~/Desktop/TrainRun"
|
|
|
@ -1,12 +0,0 @@
|
||||||
%YAML 1.2
|
|
||||||
---
|
|
||||||
settings:
|
|
||||||
# settings for the simulation
|
|
||||||
massModel: "homogeneous strip" # model type of train mass "mass point" or "homogeneous strip"
|
|
||||||
stepVariable: "t in s" # step variable of the step method "s in m", "t in s" or "v in m/s"
|
|
||||||
stepSize: 3.0 # step size (unit depends on stepVariable s in m, t in s and v in m/s)
|
|
||||||
operationModeMinimumRunningTime: true # operation mode "minimum running time"
|
|
||||||
operationModeMinimumEnergyConsumption: false # operation mode "minimum energy consumption"
|
|
||||||
typeOfOutput: "julia dictionary" # output as "julia dictionary" or as "CSV"
|
|
||||||
detailOfOutput: "driving course" # should the output be only the value of the "running time" or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
|
|
||||||
csvDirectory: "~/Desktop/TrainRun"
|
|
|
@ -1,12 +0,0 @@
|
||||||
%YAML 1.2
|
|
||||||
---
|
|
||||||
settings:
|
|
||||||
# settings for the simulation
|
|
||||||
massModel: "mass point" # model type of train mass "mass point" or "homogeneous strip"
|
|
||||||
stepVariable: "t in s" # step variable of the step method "s in m", "t in s" or "v in m/s"
|
|
||||||
stepSize: 3.0 # step size (unit depends on stepVariable s in m, t in s and v in m/s)
|
|
||||||
operationModeMinimumRunningTime: true # operation mode "minimum running time"
|
|
||||||
operationModeMinimumEnergyConsumption: false # operation mode "minimum energy consumption"
|
|
||||||
typeOfOutput: "julia dictionary" # output as "julia dictionary" or as "CSV"
|
|
||||||
detailOfOutput: "driving course" # should the output be only the value of the "running time" or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
|
|
||||||
csvDirectory: "~/Desktop/TrainRun"
|
|
|
@ -1,12 +0,0 @@
|
||||||
%YAML 1.2
|
|
||||||
---
|
|
||||||
settings:
|
|
||||||
# settings for the simulation
|
|
||||||
massModel: "mass point" # model type of train mass "mass point" or "homogeneous strip"
|
|
||||||
stepVariable: "v in m/s" # step variable of the step method "s in m", "t in s" or "v in m/s"
|
|
||||||
stepSize: 0.1 # step size (unit depends on stepVariable s in m, t in s and v in m/s)
|
|
||||||
operationModeMinimumRunningTime: true # operation mode "minimum running time"
|
|
||||||
operationModeMinimumEnergyConsumption: false # operation mode "minimum energy consumption"
|
|
||||||
typeOfOutput: "julia dictionary" # output as "julia dictionary" or as "CSV"
|
|
||||||
detailOfOutput: "driving course" # should the output be only the value of the "running time" or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
|
|
||||||
csvDirectory: "~/Desktop/TrainRun"
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
settings:
|
||||||
|
# default settings for the calculation
|
||||||
|
massModel: "mass_point" # type of train model used: "mass_point" or "homogeneous_strip"
|
||||||
|
stepVariable: "distance" # variable of the linear multistep method: "distance", "time" or "velocity"
|
||||||
|
stepSize: 20 # step size, unit depends on stepVariable - distance in meter, time in seconds and velocity in meter/second.
|
||||||
|
approxLevel: 3 # value for approximation; used when rounding or interating
|
||||||
|
outputDetail: "running_time" # single value "running_time", array of "points_of_interest",complete array "driving_course", or dict() "everything"
|
||||||
|
outputFormat: "julia_dict" # output as "julia_dict" or as "csv"
|
||||||
|
outputDir: "." # used if other outputFormat than "julia dict"
|
|
@ -0,0 +1,32 @@
|
||||||
|
#!/usr/bin/env julia
|
||||||
|
|
||||||
|
import TrainRun
|
||||||
|
|
||||||
|
paths=[]
|
||||||
|
push!(paths, importFromYaml(:path, "data/paths/path_1_10km_nConst_vConst.yaml"))
|
||||||
|
push!(paths, importFromYaml(:path, "data/paths/path_2_10km_nVar_vConst.yaml"))
|
||||||
|
push!(paths, importFromYaml(:path, "data/paths/path_3_10km_nConst_vVar.yaml"))
|
||||||
|
push!(paths, importFromYaml(:path, "data/paths/path_4_real_Germany_EastSaxony_DG-DN.yaml"))
|
||||||
|
|
||||||
|
settings=[]
|
||||||
|
push!(settings, importFromYaml(:settings, "data/settings/settings_distanceStep_massPoint.yaml"))
|
||||||
|
|
||||||
|
trains=[]
|
||||||
|
push!(trains, importFromYaml(:train, "data/trains/train_freight_V90withOreConsist.yaml"))
|
||||||
|
push!(trains, importFromYaml(:train, "data/trains/train_passenger_SiemensDesiroClassic.yaml"))
|
||||||
|
push!(trains, importFromYaml(:train, "data/trains/train_passenger_IC2.yaml"))
|
||||||
|
|
||||||
|
for path in paths
|
||||||
|
# println(" - - - - - - - - -")
|
||||||
|
# println("path: ", path[:name])
|
||||||
|
for train in trains
|
||||||
|
# println("train: ", train[:name])
|
||||||
|
for settings in settings
|
||||||
|
resultsDict = trainRun(train, path, settings)
|
||||||
|
if haskey(settings, :outputFormat) && settings[:outputFormat] == "CSV"
|
||||||
|
exportToCsv(resultsDict, settings)
|
||||||
|
sleep(2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,10 @@
|
||||||
|
#!/usr/bin/env julia
|
||||||
|
|
||||||
|
import TrainRun
|
||||||
|
|
||||||
|
train = Train("data/trains/train_freight_V90withOreConsist.yaml")
|
||||||
|
path = Path("data/paths/path_1_10km_nConst_vConst.yaml")
|
||||||
|
|
||||||
|
runtime = trainRun(train, path)
|
||||||
|
|
||||||
|
println("The train needs $runtime seconds for the running path.")
|
|
@ -1,44 +0,0 @@
|
||||||
#!/usr/bin/env julia
|
|
||||||
# -*- coding: UTF-8 -*-
|
|
||||||
# __julia-version__ = 1.7.0
|
|
||||||
# __author__ = "Max Kannenberg"
|
|
||||||
# __copyright__ = "2021"
|
|
||||||
# __license__ = "ISC"
|
|
||||||
|
|
||||||
include("../src/TrainRun.jl")
|
|
||||||
using .TrainRun
|
|
||||||
|
|
||||||
allPaths=[]
|
|
||||||
push!(allPaths, importFromYaml(:path, "data/paths/path_1_10km_nConst_vConst.yaml"))
|
|
||||||
push!(allPaths, importFromYaml(:path, "data/paths/path_2_10km_nVar_vConst.yaml"))
|
|
||||||
push!(allPaths, importFromYaml(:path, "data/paths/path_3_10km_nConst_vVar.yaml"))
|
|
||||||
push!(allPaths, importFromYaml(:path, "data/paths/path_4_real_Germany_EastSaxony_DG-DN.yaml"))
|
|
||||||
|
|
||||||
allSettings=[]
|
|
||||||
push!(allSettings, importFromYaml(:settings, "data/settings/settings_distanceStep_massPoint.yaml"))
|
|
||||||
|
|
||||||
allTrains=[]
|
|
||||||
push!(allTrains, importFromYaml(:train, "data/trains/train_freight_V90withOreConsist.yaml"))
|
|
||||||
push!(allTrains, importFromYaml(:train, "data/trains/train_passenger_SiemensDesiroClassic.yaml"))
|
|
||||||
push!(allTrains, importFromYaml(:train, "data/trains/train_passenger_IC2.yaml"))
|
|
||||||
|
|
||||||
for path in allPaths
|
|
||||||
# println(" - - - - - - - - -")
|
|
||||||
# println("path: ", path[:name])
|
|
||||||
for train in allTrains
|
|
||||||
# println("train: ", train[:name])
|
|
||||||
for settings in allSettings
|
|
||||||
resultsDict = trainRun(train, path, settings)
|
|
||||||
if haskey(settings, :typeOfOutput) && settings[:typeOfOutput] == "CSV"
|
|
||||||
exportToCsv(resultsDict, settings)
|
|
||||||
sleep(2)
|
|
||||||
end
|
|
||||||
# println("")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
# println("")
|
|
||||||
end
|
|
||||||
|
|
||||||
# println("")
|
|
||||||
# println("________________________")
|
|
||||||
# println("")
|
|
|
@ -1,19 +0,0 @@
|
||||||
#!/usr/bin/env julia
|
|
||||||
# -*- coding: UTF-8 -*-
|
|
||||||
# __julia-version__ = 1.7.0
|
|
||||||
# __author__ = "Max Kannenberg"
|
|
||||||
# __copyright__ = "2021"
|
|
||||||
# __license__ = "ISC"
|
|
||||||
|
|
||||||
include("../src/TrainRun.jl")
|
|
||||||
using .TrainRun
|
|
||||||
|
|
||||||
train_directory = "data/trains/train_freight_V90withOreConsist.yaml"
|
|
||||||
running_path_directory = "data/paths/path_1_10km_nConst_vConst.yaml"
|
|
||||||
setting_directory = "data/settings/settings_distanceStep_massPoint_runningTime.yaml"
|
|
||||||
(train, running_path, settings) = importYamlFiles(train_directory, running_path_directory, setting_directory)
|
|
||||||
|
|
||||||
runtime = trainRun(train, running_path, settings)
|
|
||||||
|
|
||||||
exportToCsv(runtime, settings)
|
|
||||||
println("The V 90 with 10 ore wagons needs $runtime seconds for 10 km with no gradient.")
|
|
|
@ -1,210 +0,0 @@
|
||||||
#!/usr/bin/env julia
|
|
||||||
# -*- coding: UTF-8 -*-
|
|
||||||
# __julia-version__ = 1.7.2
|
|
||||||
# __author__ = "Max Kannenberg"
|
|
||||||
# __copyright__ = "2020-2022"
|
|
||||||
# __license__ = "ISC"
|
|
||||||
|
|
||||||
# INFO: AdditionalOutput should not be used because it is not completed yet. It was used to show first results during development.
|
|
||||||
# TODO: It has to be optimized so that the created plots and printed information is clear and understandable.
|
|
||||||
|
|
||||||
module AdditionalOutput
|
|
||||||
|
|
||||||
using Plots
|
|
||||||
|
|
||||||
export plotResults, plotDrivingCourse, printImportantValues, printSectionInformation
|
|
||||||
|
|
||||||
function plotResults(output::Dict)
|
|
||||||
opModeMinTime = output[:settings][:operationModeMinimumRunningTime]
|
|
||||||
opModeMinEnergy = output[:settings][:operationModeMinimumEnergyConsumption]
|
|
||||||
|
|
||||||
if opModeMinTime == true && opModeMinEnergy == true
|
|
||||||
plotDrivingCourse(output[:drivingCourseMinimumRunningTime], output[:drivingCourseMinimumEnergyConsumption])
|
|
||||||
elseif opModeMinTime == true
|
|
||||||
plotDrivingCourse(output[:drivingCourseMinimumRunningTime])
|
|
||||||
elseif opModeMinEnergy == true
|
|
||||||
plotDrivingCourse(output[:drivingCourseMinimumEnergyConsumption])
|
|
||||||
else
|
|
||||||
output[:settings][:detailOfOutput] == "everything" && println("No Output was demanded. So no plot is created.")
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
|
||||||
end #function plotResults
|
|
||||||
|
|
||||||
function plotResults(drivingCourse::Vector{Dict})
|
|
||||||
plotDrivingCourse(drivingCourse)
|
|
||||||
|
|
||||||
return true
|
|
||||||
end #function plotResults
|
|
||||||
|
|
||||||
function plotResults(singleValue::AbstractFloat)
|
|
||||||
println("Not able to plot the single value ",singleValue)
|
|
||||||
|
|
||||||
return false
|
|
||||||
end #function plotResults
|
|
||||||
|
|
||||||
function plotDrivingCourse(drivingCourse::Vector{Dict})
|
|
||||||
a=[]
|
|
||||||
E=[]
|
|
||||||
s=[]
|
|
||||||
t=[]
|
|
||||||
v=[]
|
|
||||||
for i in 1:length(drivingCourse)
|
|
||||||
push!(a, drivingCourse[i][:a])
|
|
||||||
push!(E, drivingCourse[i][:E])
|
|
||||||
push!(s, drivingCourse[i][:s])
|
|
||||||
push!(t, drivingCourse[i][:t])
|
|
||||||
push!(v, drivingCourse[i][:v])
|
|
||||||
end #for
|
|
||||||
|
|
||||||
# p1=plot([s], [v], title = "v in m/s", label = ["v"], xlabel = "s in m")
|
|
||||||
p1=plot([s/1000], [v*3.6], title = "v in km/h", label = ["v"], xlabel = "s in km")
|
|
||||||
|
|
||||||
# p2=plot([t], [v], title = "v in m/s", label = ["v"], xlabel = "t in s")
|
|
||||||
p2=plot([t/60], [v*3.6], title = "v in km/h", label = ["v"], xlabel = "t in min")
|
|
||||||
|
|
||||||
# p3=plot([s], [t], title = "t in s", label = ["t"], xlabel = "s in m")
|
|
||||||
|
|
||||||
# p4=plot([t], [s], title = "s in m", label = ["s"], xlabel = "t in s")
|
|
||||||
|
|
||||||
#p5=plot([s], [E], title = "E in Ws", label = ["E"], xlabel = "s in m")
|
|
||||||
p5=plot([s/1000], [E], title = "E in Ws", label = ["E"], xlabel = "s in km")
|
|
||||||
|
|
||||||
#p6=plot([t], [E], title = "E in Ws", label = ["E"], xlabel = "t in s")
|
|
||||||
p6=plot([t/60], [E], title = "E in Ws", label = ["E"], xlabel = "t in min")
|
|
||||||
|
|
||||||
all=plot(p1, p2, p5, p6, layout = (2, 2), legend = false)
|
|
||||||
#=
|
|
||||||
# p5=plot([s], [E], title = "E in Ws", label = ["E"], xlabel = "s in m")
|
|
||||||
|
|
||||||
# p6=plot([t], [E], title = "E in Ws", label = ["E"], xlabel = "t in s")
|
|
||||||
|
|
||||||
all=plot(p1, p2, layout = (1, 2), legend = false)=#
|
|
||||||
# all=plot(p1, p2, p3, p4, p5, p6, layout = (3, 2), legend = false)
|
|
||||||
display(all)
|
|
||||||
println("Plots for different variables have been created.")
|
|
||||||
end #function plotDrivingCourse
|
|
||||||
|
|
||||||
function plotDrivingCourse(drivingCourseMinimumRunningTime::Vector{Dict},drivingCourseMinimumEnergyConsumption::Vector{Dict})
|
|
||||||
a_minTime=[]
|
|
||||||
E_minTime=[]
|
|
||||||
s_minTime=[]
|
|
||||||
t_minTime=[]
|
|
||||||
v_minTime=[]
|
|
||||||
for i in 1:length(drivingCourseMinimumRunningTime)
|
|
||||||
push!(a_minTime, drivingCourseMinimumRunningTime[i][:a])
|
|
||||||
push!(E_minTime, drivingCourseMinimumRunningTime[i][:E])
|
|
||||||
push!(s_minTime, drivingCourseMinimumRunningTime[i][:s])
|
|
||||||
push!(t_minTime, drivingCourseMinimumRunningTime[i][:t])
|
|
||||||
push!(v_minTime, drivingCourseMinimumRunningTime[i][:v])
|
|
||||||
end #for
|
|
||||||
|
|
||||||
a_minEnergy=[]
|
|
||||||
E_minEnergy=[]
|
|
||||||
s_minEnergy=[]
|
|
||||||
t_minEnergy=[]
|
|
||||||
v_minEnergy=[]
|
|
||||||
for i in 1:length(drivingCourseMinimumEnergyConsumption)
|
|
||||||
push!(a_minEnergy, drivingCourseMinimumEnergyConsumption[i][:a])
|
|
||||||
push!(E_minEnergy, drivingCourseMinimumEnergyConsumption[i][:E])
|
|
||||||
push!(s_minEnergy, drivingCourseMinimumEnergyConsumption[i][:s])
|
|
||||||
push!(t_minEnergy, drivingCourseMinimumEnergyConsumption[i][:t])
|
|
||||||
push!(v_minEnergy, drivingCourseMinimumEnergyConsumption[i][:v])
|
|
||||||
end #for
|
|
||||||
|
|
||||||
p1=plot([s_minTime,s_minEnergy],
|
|
||||||
[v_minTime,v_minEnergy],
|
|
||||||
title = "v in m/s",
|
|
||||||
label = ["v for t_min" "v for E_min"],
|
|
||||||
xlabel = "s in m")# lw = 3)
|
|
||||||
|
|
||||||
p2=plot([t_minTime,t_minEnergy],
|
|
||||||
[v_minTime,v_minEnergy],
|
|
||||||
title = "v in m/s",
|
|
||||||
label = ["v for t_min" "v for E_min"],
|
|
||||||
xlabel = "t in s")
|
|
||||||
|
|
||||||
# p3=plot([s_minTime,s_minEnergy],
|
|
||||||
# [t_minTime,t_minEnergy],
|
|
||||||
# title = "t in s",
|
|
||||||
# label = ["t for t_min" "t for E_min"],
|
|
||||||
# xlabel = "s in m")
|
|
||||||
|
|
||||||
# p4=plot([t_minTime,t_minEnergy],
|
|
||||||
# [s_minTime,s_minEnergy],
|
|
||||||
# title = "s in m",
|
|
||||||
# label = ["s for t_min" "s for E_min"],
|
|
||||||
# xlabel = "t in s")
|
|
||||||
|
|
||||||
p5=plot([s_minTime,s_minEnergy],
|
|
||||||
[E_minTime,E_minEnergy],
|
|
||||||
title = "E in Ws",
|
|
||||||
label = ["E for t_min" "E for E_min"],
|
|
||||||
xlabel = "s in m")
|
|
||||||
|
|
||||||
p6=plot([t_minTime,t_minEnergy],
|
|
||||||
[E_minTime,E_minEnergy],
|
|
||||||
title = "E in Ws",
|
|
||||||
label = ["E for t_min" "E for E_min"],
|
|
||||||
xlabel = "t in s")
|
|
||||||
|
|
||||||
# all=plot(p1, p2, p3, p4, p5, p6, layout = (3, 2), legend = false)
|
|
||||||
all=plot(p1, p2, p5, p6, layout = (2, 2), legend = false)
|
|
||||||
display(all)
|
|
||||||
println("Plots for different variables have been created.")
|
|
||||||
end #function plotDrivingCourse
|
|
||||||
|
|
||||||
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")
|
|
||||||
for i in 1:length(dataPoints)
|
|
||||||
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
|
|
||||||
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
|
|
||||||
|
|
||||||
function printSectionInformation(movingSection::Dict)
|
|
||||||
CSs::Vector{Dict} = movingSection[:characteristicSections]
|
|
||||||
|
|
||||||
println("MS with length=", movingSection[:length]," with t=", movingSection[:t])
|
|
||||||
#allBSs=[:breakFree, :clearing, :accelerating, :clearing2, :accelerating2, :clearing3, :accelerating3, :cruising, :downhillBraking, :diminishing, :coasting, :braking, :standstill]
|
|
||||||
for csId in 1:length(CSs)
|
|
||||||
println("CS ",csId," with length=", CSs[csId][:length]," with t=", CSs[csId][:t])
|
|
||||||
# for bs in 1: length(allBSs)
|
|
||||||
# if haskey(CSs[csId][:behaviorSections], allBSs[bs])
|
|
||||||
# println("BS ",allBSs[bs], " with s_entry=", CSs[csId][:behaviorSections][allBSs[bs]][:s_entry], " and length=",CSs[csId][:behaviorSections][allBSs[bs]][:length]) # and t=", CSs[csId][:behaviorSections][allBSs[bs]][:t])
|
|
||||||
# # for point in 1:length(CSs[csId][:behaviorSections][allBSs[bs]][:dataPoints])
|
|
||||||
# # println(CSs[csId][:behaviorSections][allBSs[bs]][:dataPoints][point])
|
|
||||||
# # end
|
|
||||||
# end #if
|
|
||||||
# end #for
|
|
||||||
|
|
||||||
tempBSs = collect(keys(CSs[csId][:behaviorSections]))
|
|
||||||
while length(tempBSs) > 0
|
|
||||||
currentBS = :default
|
|
||||||
for bs in 1: length(tempBSs)
|
|
||||||
if currentBS == :default
|
|
||||||
currentBS = tempBSs[bs]
|
|
||||||
else
|
|
||||||
if CSs[csId][:behaviorSections][currentBS][:s_entry] > CSs[csId][:behaviorSections][tempBSs[bs]][:s_entry]
|
|
||||||
currentBS = tempBSs[bs]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end #for
|
|
||||||
|
|
||||||
println("BS ",currentBS, " with s_entry=", CSs[csId][:behaviorSections][currentBS][:s_entry], " and length=",CSs[csId][:behaviorSections][currentBS][:length]) # and t=", CSs[csId][:behaviorSections][currentBS][:t])
|
|
||||||
# for point in 1:length(CSs[csId][:behaviorSections][currentBS][:dataPoints])
|
|
||||||
# println(CSs[csId][:behaviorSections][currentBS][:dataPoints][point])
|
|
||||||
# end
|
|
||||||
|
|
||||||
newTempBSs = []
|
|
||||||
for bs in 1: length(tempBSs)
|
|
||||||
if currentBS != tempBSs[bs]
|
|
||||||
push!(newTempBSs, tempBSs[bs])
|
|
||||||
end #if
|
|
||||||
end #for
|
|
||||||
tempBSs = newTempBSs
|
|
||||||
end #while
|
|
||||||
end #for
|
|
||||||
end #function printSectionInformation
|
|
||||||
|
|
||||||
end # module AdditionalOutput
|
|
225
src/Behavior.jl
225
src/Behavior.jl
|
@ -5,22 +5,6 @@
|
||||||
# __copyright__ = "2020-2022"
|
# __copyright__ = "2020-2022"
|
||||||
# __license__ = "ISC"
|
# __license__ = "ISC"
|
||||||
|
|
||||||
module Behavior
|
|
||||||
|
|
||||||
include("./Formulary.jl")
|
|
||||||
using .Formulary
|
|
||||||
|
|
||||||
export addBreakFreeSection!, addClearingSection!, addAcceleratingSection!, addCruisingSection!, addDiminishingSection!, addCoastingSection!, addBrakingSection!, addStandstill!,
|
|
||||||
# addBrakingSectionInOneStep! is not used in the current version of the tool
|
|
||||||
calculateForces!, createDataPoint,
|
|
||||||
|
|
||||||
# export functions from Formulary
|
|
||||||
calcBrakingDistance, calcBrakingStartVelocity, calc_Δs_with_Δt
|
|
||||||
|
|
||||||
|
|
||||||
approximationLevel = 6 # value for approximation to intersections TODO further explanation (e.g. approximationLevel = 3 -> with stepSize 10 m the approximation will be calculated accurate on 10 mm ; 1s -> 1 ms; 1 km/h -> 3.6 mm/s)
|
|
||||||
# TODO: define it in TrainRun and give it to each function?
|
|
||||||
|
|
||||||
## functions for calculating tractive effort and resisting forces
|
## functions for calculating tractive effort and resisting forces
|
||||||
"""
|
"""
|
||||||
calculateTractiveEffort(v, tractiveEffortVelocityPairs)
|
calculateTractiveEffort(v, tractiveEffortVelocityPairs)
|
||||||
|
@ -62,10 +46,11 @@ end #function calculateTractiveEffort
|
||||||
"""
|
"""
|
||||||
calculate and return the path resistance dependend on the trains position and mass model
|
calculate and return the path resistance dependend on the trains position and mass model
|
||||||
"""
|
"""
|
||||||
function calculatePathResistance(CSs::Vector{Dict}, csId::Integer, s::Real, massModel::String, train::Dict)
|
function calculatePathResistance(CSs::Vector{Dict}, csId::Integer, s::Real, massModel, train::Dict)
|
||||||
if massModel == "mass point"
|
|
||||||
|
if massModel == :mass_point
|
||||||
pathResistance = calcForceFromCoefficient(CSs[csId][:r_path], train[:m_train])
|
pathResistance = calcForceFromCoefficient(CSs[csId][:r_path], train[:m_train])
|
||||||
elseif massModel == "homogeneous strip"
|
elseif massModel == :homogeneous_strip
|
||||||
pathResistance = 0.0
|
pathResistance = 0.0
|
||||||
s_rear = s - train[:length] # position of the rear of the train
|
s_rear = s - train[:length] # position of the rear of the train
|
||||||
while csId > 0 && s_rear < CSs[csId][:s_exit]
|
while csId > 0 && s_rear < CSs[csId][:s_exit]
|
||||||
|
@ -84,7 +69,7 @@ end #function calculatePathResistance
|
||||||
"""
|
"""
|
||||||
calculate and return tractive and resisting forces for a data point
|
calculate and return tractive and resisting forces for a data point
|
||||||
"""
|
"""
|
||||||
function calculateForces!(dataPoint::Dict, CSs::Vector{Dict}, csId::Integer, bsType::String, train::Dict, massModel::String)
|
function calculateForces!(dataPoint::Dict, CSs::Vector{Dict}, csId::Integer, bsType::String, train::Dict, massModel)
|
||||||
# calculate resisting forces
|
# calculate resisting forces
|
||||||
dataPoint[:R_traction] = calcTractionUnitResistance(dataPoint[:v], train)
|
dataPoint[:R_traction] = calcTractionUnitResistance(dataPoint[:v], train)
|
||||||
dataPoint[:R_wagons] = calcWagonsResistance(dataPoint[:v], train)
|
dataPoint[:R_wagons] = calcWagonsResistance(dataPoint[:v], train)
|
||||||
|
@ -108,7 +93,7 @@ end #function calculateForces!
|
||||||
"""
|
"""
|
||||||
TODO
|
TODO
|
||||||
"""
|
"""
|
||||||
function moveAStep(previousPoint::Dict, stepVariable::String, stepSize::Real, csId::Integer)
|
function moveAStep(previousPoint::Dict, stepVariable::Symbol, stepSize::Real, csId::Integer)
|
||||||
# stepSize is the currentStepSize depending on the accessing function
|
# stepSize is the currentStepSize depending on the accessing function
|
||||||
# TODO: csId is only for error messages. Should it be removed?
|
# TODO: csId is only for error messages. Should it be removed?
|
||||||
#= 08/31 TODO: How to check if the train stopps during this step? I should throw an error myself that I catch in higher hierarchies. =#
|
#= 08/31 TODO: How to check if the train stopps during this step? I should throw an error myself that I catch in higher hierarchies. =#
|
||||||
|
@ -118,7 +103,7 @@ 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 stepVariable == "s in m" # distance step method
|
if stepVariable == :distance # 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] == 0.0
|
if previousPoint[:v] == 0.0
|
||||||
|
@ -138,12 +123,12 @@ function moveAStep(previousPoint::Dict, stepVariable::String, stepSize::Real, cs
|
||||||
newPoint[:Δv] = calc_Δv_with_Δs(newPoint[:Δs], previousPoint[:a], previousPoint[:v]) # step size (in m/s)
|
newPoint[:Δv] = calc_Δv_with_Δs(newPoint[:Δs], previousPoint[:a], previousPoint[:v]) # step size (in m/s)
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif stepVariable == "t in s" # time step method
|
elseif stepVariable == :time # time step method
|
||||||
newPoint[:Δt] = stepSize # step size (in s)
|
newPoint[:Δt] = stepSize # step size (in s)
|
||||||
newPoint[:Δs] = calc_Δs_with_Δt(newPoint[:Δt], previousPoint[:a], previousPoint[:v]) # step size (in m)
|
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)
|
newPoint[:Δv] = calc_Δv_with_Δt(newPoint[:Δt], previousPoint[:a]) # step size (in m/s)
|
||||||
|
|
||||||
elseif stepVariable == "v in m/s" # velocity step method
|
elseif stepVariable == :velocity # velocity step method
|
||||||
if previousPoint[:a] == 0.0
|
if previousPoint[:a] == 0.0
|
||||||
if previousPoint[:v] == 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,".")
|
error("ERROR: The train tries to cruise at v=0.0 m/s at s=",previousPoint[:s]," in CS",csId,".")
|
||||||
|
@ -203,7 +188,7 @@ end #function getNextPointOfInterest
|
||||||
## This function calculates the data points of the breakFree section.
|
## This function calculates the data points of the breakFree section.
|
||||||
# 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 accelerating section
|
# Info: currently the values of the breakFree section will be calculated like in the accelerating section
|
||||||
function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, settings::Dict, train::Dict, CSs::Vector{Dict})
|
function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, settings::Settings, train::Dict, CSs::Vector{Dict})
|
||||||
# conditions for the break free section
|
# conditions for the break free section
|
||||||
endOfCSReached = drivingCourse[end][:s] >= CS[:s_exit] || stateFlags[:endOfCSReached]
|
endOfCSReached = drivingCourse[end][:s] >= CS[:s_exit] || stateFlags[:endOfCSReached]
|
||||||
trainIsHalting = drivingCourse[end][:v] == 0.0
|
trainIsHalting = drivingCourse[end][:v] == 0.0
|
||||||
|
@ -213,7 +198,7 @@ function addBreakFreeSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags:
|
||||||
drivingCourse[end][:behavior] = BS[:type]
|
drivingCourse[end][:behavior] = BS[:type]
|
||||||
|
|
||||||
# traction effort and resisting forces (in N)
|
# traction effort and resisting forces (in N)
|
||||||
calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings[:massModel]) # currently the tractive effort is calculated like in the accelerating section
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings.massModel) # currently the tractive effort is calculated like in the accelerating section
|
||||||
|
|
||||||
# calculate the breakFree section with calculating the accelerating section and just using the first step and removing the rest
|
# calculate the breakFree section with calculating the accelerating section and just using the first step and removing the rest
|
||||||
try (CS, drivingCourse, stateFlags) = addAcceleratingSection!(CS, drivingCourse, stateFlags, settings, train, CSs)
|
try (CS, drivingCourse, stateFlags) = addAcceleratingSection!(CS, drivingCourse, stateFlags, settings, train, CSs)
|
||||||
|
@ -272,7 +257,7 @@ end #function addBreakFreeSection!
|
||||||
|
|
||||||
## This function calculates the data points of the clearing section.
|
## This function calculates the data points of the clearing section.
|
||||||
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the clearing section.
|
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the clearing section.
|
||||||
function addClearingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, settings::Dict, train::Dict, CSs::Vector{Dict})
|
function addClearingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, settings::Settings, train::Dict, CSs::Vector{Dict})
|
||||||
if stateFlags[:previousSpeedLimitReached]
|
if stateFlags[:previousSpeedLimitReached]
|
||||||
currentSpeedLimit = getCurrentSpeedLimit(CSs, CS[:id], drivingCourse[end][:s], train[:length])
|
currentSpeedLimit = getCurrentSpeedLimit(CSs, CS[:id], drivingCourse[end][:s], train[:length])
|
||||||
|
|
||||||
|
@ -287,7 +272,7 @@ function addClearingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::
|
||||||
s_clearing = min(CS[:s_exit]-drivingCourse[end][:s]-s_braking, currentSpeedLimit[:s_end] - drivingCourse[end][:s])
|
s_clearing = min(CS[:s_exit]-drivingCourse[end][:s]-s_braking, currentSpeedLimit[:s_end] - drivingCourse[end][:s])
|
||||||
if s_clearing > 0.0
|
if s_clearing > 0.0
|
||||||
(CS, drivingCourse, stateFlags) = addCruisingSection!(CS, drivingCourse, stateFlags, s_clearing, settings, train, CSs, "clearing")
|
(CS, drivingCourse, stateFlags) = addCruisingSection!(CS, drivingCourse, stateFlags, s_clearing, settings, train, CSs, "clearing")
|
||||||
calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings[:massModel])
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings.massModel)
|
||||||
# stateFlags[:brakingStartReached] = brakingStartReached
|
# stateFlags[:brakingStartReached] = brakingStartReached
|
||||||
# stateFlags[:endOfCSReached] = stateFlags[:endOfCSReached] || drivingCourse[end][:s] == CS[:s_exit]
|
# stateFlags[:endOfCSReached] = stateFlags[:endOfCSReached] || drivingCourse[end][:s] == CS[:s_exit]
|
||||||
else
|
else
|
||||||
|
@ -305,14 +290,14 @@ end #function addClearingSection
|
||||||
|
|
||||||
## This function calculates the data points of the accelerating section.
|
## This function calculates the data points of the accelerating section.
|
||||||
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the accelerating section
|
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the accelerating section
|
||||||
function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, settings::Dict, train::Dict, CSs::Vector{Dict})
|
function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, settings::Settings, train::Dict, CSs::Vector{Dict})
|
||||||
#function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict}, ignoreBraking::Bool)
|
#function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, settings::Settings, train::Dict, CSs::Vector{Dict}, ignoreBraking::Bool)
|
||||||
#=if drivingCourse would also be part of movingSectiong: function addAcceleratingSection!(movingSection::Dict, stateFlags::Dict, csId::Integer, settings::Dict, train::Dict)
|
#=if drivingCourse would also be part of movingSectiong: function addAcceleratingSection!(movingSection::Dict, stateFlags::Dict, csId::Integer, settings::Settings, train::Dict)
|
||||||
CSs = movingSection[:characteristicSections]
|
CSs = movingSection[:characteristicSections]
|
||||||
CS = CSs[csId]
|
CS = CSs[csId]
|
||||||
drivingCourse = movingSection[:drivingCourse]=#
|
drivingCourse = movingSection[:drivingCourse]=#
|
||||||
|
|
||||||
calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings[:massModel])
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "accelerating", train, settings.massModel)
|
||||||
|
|
||||||
if haskey(stateFlags, :usedForDefiningCharacteristics) && stateFlags[:usedForDefiningCharacteristics]
|
if haskey(stateFlags, :usedForDefiningCharacteristics) && stateFlags[:usedForDefiningCharacteristics]
|
||||||
ignoreBraking = true
|
ignoreBraking = true
|
||||||
|
@ -340,11 +325,11 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFla
|
||||||
#speedLimitReached = drivingCourse[end][:v] > currentSpeedLimit[:v]
|
#speedLimitReached = drivingCourse[end][:v] > currentSpeedLimit[:v]
|
||||||
#targetSpeedReached = speedLimitReached
|
#targetSpeedReached = speedLimitReached
|
||||||
while !targetSpeedReached && !endOfCSReached && tractionSurplus && !brakingStartReached && !previousSpeedLimitReached
|
while !targetSpeedReached && !endOfCSReached && tractionSurplus && !brakingStartReached && !previousSpeedLimitReached
|
||||||
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])
|
||||||
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
||||||
|
|
||||||
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
|
for cycle in 1:settings.approxLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
|
||||||
if !ignoreBraking
|
if !ignoreBraking
|
||||||
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
||||||
end
|
end
|
||||||
|
@ -360,11 +345,11 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFla
|
||||||
drivingCourse[end][:a] = calcAcceleration(drivingCourse[end][:F_T], drivingCourse[end][:F_R], train[:m_train], train[:ξ_train])
|
drivingCourse[end][:a] = calcAcceleration(drivingCourse[end][:F_T], drivingCourse[end][:F_R], train[:m_train], train[:ξ_train])
|
||||||
|
|
||||||
# create the next data point
|
# create the next data point
|
||||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
|
push!(drivingCourse, moveAStep(drivingCourse[end], settings.stepVariable, currentStepSize, CS[:id]))
|
||||||
drivingCourse[end][:behavior] = BS[:type]
|
drivingCourse[end][:behavior] = BS[:type]
|
||||||
push!(BS[:dataPoints], drivingCourse[end][:i])
|
push!(BS[:dataPoints], drivingCourse[end][:i])
|
||||||
|
|
||||||
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
|
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings.massModel)
|
||||||
|
|
||||||
# conditions for the next while cycle
|
# conditions for the next while cycle
|
||||||
if !ignoreBraking
|
if !ignoreBraking
|
||||||
|
@ -386,41 +371,41 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFla
|
||||||
end
|
end
|
||||||
|
|
||||||
# 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 < settings.approxLevel+1
|
||||||
if drivingCourse[end][:F_T] <= drivingCourse[end][:F_R]
|
if drivingCourse[end][:F_T] <= drivingCourse[end][:F_R]
|
||||||
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: F_T=", drivingCourse[end][:F_T]," <= F_R=",drivingCourse[end][:F_R]) # for testing
|
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: F_T=", drivingCourse[end][:F_T]," <= F_R=",drivingCourse[end][:F_R]) # for testing
|
||||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
currentStepSize = settings.stepSize / 10.0^cycle
|
||||||
|
|
||||||
elseif s_braking > 0.0 && drivingCourse[end][:s] + s_braking > CS[:s_exit]
|
elseif s_braking > 0.0 && drivingCourse[end][:s] + s_braking > CS[:s_exit]
|
||||||
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],",+",s_braking," = ",drivingCourse[end][:s] +s_braking," > s_exit=",CS[:s_exit]) # for testing
|
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],",+",s_braking," = ",drivingCourse[end][:s] +s_braking," > s_exit=",CS[:s_exit]) # for testing
|
||||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
currentStepSize = settings.stepSize / 10.0^cycle
|
||||||
|
|
||||||
elseif drivingCourse[end][:s] > nextPointOfInterest
|
elseif drivingCourse[end][:s] > nextPointOfInterest
|
||||||
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: s=", drivingCourse[end][:s]," > nextPOI=",nextPointOfInterest) # for testing
|
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: s=", drivingCourse[end][:s]," > nextPOI=",nextPointOfInterest) # for testing
|
||||||
if settings[:stepVariable] == "s in m"
|
if settings.stepVariable == :distance
|
||||||
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
|
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
|
||||||
else
|
else
|
||||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
currentStepSize = settings.stepSize / 10.0^cycle
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif drivingCourse[end][:v] > CS[:v_peak]
|
elseif drivingCourse[end][:v] > CS[:v_peak]
|
||||||
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," > v_peak=",CS[:v_peak]) # for testing
|
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," > v_peak=",CS[:v_peak]) # for testing
|
||||||
if settings[:stepVariable] == "v in m/s"
|
if settings.stepVariable == :speed
|
||||||
currentStepSize = CS[:v_peak]-drivingCourse[end-1][:v]
|
currentStepSize = CS[:v_peak]-drivingCourse[end-1][:v]
|
||||||
else
|
else
|
||||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
currentStepSize = settings.stepSize / 10.0^cycle
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif drivingCourse[end][:v] > currentSpeedLimit[:v]
|
elseif drivingCourse[end][:v] > currentSpeedLimit[:v]
|
||||||
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," > v_limitCurrent=",currentSpeedLimit[:v]) # for testing
|
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: v=", drivingCourse[end][:v]," > v_limitCurrent=",currentSpeedLimit[:v]) # for testing
|
||||||
if settings[:stepVariable] == "v in m/s"
|
if settings.stepVariable == :velocity
|
||||||
currentStepSize = currentSpeedLimit[:v]-drivingCourse[end-1][:v]
|
currentStepSize = currentSpeedLimit[:v]-drivingCourse[end-1][:v]
|
||||||
|
|
||||||
else
|
else
|
||||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
currentStepSize = settings.stepSize / 10.0^cycle
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif drivingCourse[end][:s] +s_braking == CS[:s_exit]
|
elseif drivingCourse[end][:s] + s_braking == CS[:s_exit]
|
||||||
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],",+",s_braking," = ",drivingCourse[end][:s] +s_braking," == s_exit=",CS[:s_exit]) # for testing
|
testFlag && println("in CS",CS[:id]," accelerating cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],",+",s_braking," = ",drivingCourse[end][:s] +s_braking," == s_exit=",CS[:s_exit]) # for testing
|
||||||
if s_braking == 0.0
|
if s_braking == 0.0
|
||||||
endOfCSReached = true
|
endOfCSReached = true
|
||||||
|
@ -447,7 +432,7 @@ function addAcceleratingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFla
|
||||||
println("s=" ,drivingCourse[end][:s]," s_exit=", CS[:s_exit], " s+s_braking=", drivingCourse[end][:s] +s_braking," nextPOI=",nextPointOfInterest)
|
println("s=" ,drivingCourse[end][:s]," s_exit=", CS[:s_exit], " s+s_braking=", drivingCourse[end][:s] +s_braking," nextPOI=",nextPointOfInterest)
|
||||||
println("F_T=",drivingCourse[end][:F_T] ," F_R=", drivingCourse[end][:F_R])
|
println("F_T=",drivingCourse[end][:F_T] ," F_R=", drivingCourse[end][:F_R])
|
||||||
|
|
||||||
error("ERROR at accelerating section: With the step variable ",settings[:stepVariable]," the while loop will be left although v<v_peak and s<s_exit in CS",CS[:id]," with s=" ,drivingCourse[end][:s]," m and v=",drivingCourse[end][:v]," m/s")
|
error("ERROR at accelerating section: With the step variable ",settings.stepVariable," the while loop will be left although v<v_peak and s<s_exit in CS",CS[:id]," with s=" ,drivingCourse[end][:s]," m and v=",drivingCourse[end][:v]," m/s")
|
||||||
end
|
end
|
||||||
# delete last data point for recalculating the last step with reduced step size
|
# delete last data point for recalculating the last step with reduced step size
|
||||||
pop!(drivingCourse)
|
pop!(drivingCourse)
|
||||||
|
@ -551,15 +536,15 @@ end #function addAcceleratingSection!
|
||||||
|
|
||||||
## This function calculates the data points of the cruising section.
|
## This function calculates the data points of the cruising section.
|
||||||
# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for cruising if needed.
|
# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the behavior section for cruising if needed.
|
||||||
function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, s_cruising::Real, settings::Dict, train::Dict, CSs::Vector{Dict}, cruisingType::String)
|
function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, s_cruising::Real, settings::Settings, train::Dict, CSs::Vector{Dict}, cruisingType::String)
|
||||||
trainIsClearing = cruisingType == "clearing"
|
trainIsClearing = cruisingType == "clearing"
|
||||||
trainIsBrakingDownhill = cruisingType == "downhillBraking"
|
trainIsBrakingDownhill = cruisingType == "downhillBraking"
|
||||||
|
|
||||||
# traction effort and resisting forces (in N)
|
# traction effort and resisting forces (in N)
|
||||||
if !trainIsBrakingDownhill # TODO: or just give BS[:type] instead of "cruising"/"braking"?
|
if !trainIsBrakingDownhill # TODO: or just give BS[:type] instead of "cruising"/"braking"?
|
||||||
calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings.massModel)
|
||||||
else
|
else
|
||||||
calculateForces!(drivingCourse[end], CSs, CS[:id], "braking", train, settings[:massModel])
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "braking", train, settings.massModel)
|
||||||
end
|
end
|
||||||
|
|
||||||
if haskey(stateFlags, :usedForDefiningCharacteristics) && stateFlags[:usedForDefiningCharacteristics]
|
if haskey(stateFlags, :usedForDefiningCharacteristics) && stateFlags[:usedForDefiningCharacteristics]
|
||||||
|
@ -587,14 +572,14 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::
|
||||||
s_cruising = min(s_cruising, CS[:s_exit]-BS[:s_entry])
|
s_cruising = min(s_cruising, CS[:s_exit]-BS[:s_entry])
|
||||||
|
|
||||||
# traction effort and resisting forces (in N)
|
# traction effort and resisting forces (in N)
|
||||||
#03/25 calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
|
#03/25 calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings.massModel)
|
||||||
if !trainIsBrakingDownhill
|
if !trainIsBrakingDownhill
|
||||||
calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings.massModel)
|
||||||
else
|
else
|
||||||
calculateForces!(drivingCourse[end], CSs, CS[:id], "braking", train, settings[:massModel])
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "braking", train, settings.massModel)
|
||||||
end
|
end
|
||||||
|
|
||||||
if settings[:massModel]=="homogeneous strip" && CS[:id] > 1
|
if settings.massModel == :homogeneous_strip && CS[:id] > 1
|
||||||
# conditions for cruising section
|
# conditions for cruising section
|
||||||
trainInPreviousCS = drivingCourse[end][:s] < CS[:s_entry] + train[:length]
|
trainInPreviousCS = drivingCourse[end][:s] < CS[:s_entry] + train[:length]
|
||||||
targetPositionReached = drivingCourse[end][:s] >= BS[:s_entry] +s_cruising
|
targetPositionReached = drivingCourse[end][:s] >= BS[:s_entry] +s_cruising
|
||||||
|
@ -604,11 +589,11 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::
|
||||||
#&& targetSpeedReached
|
#&& targetSpeedReached
|
||||||
# use the conditions for the cruising section
|
# use the conditions for the cruising section
|
||||||
while trainInPreviousCS && !targetPositionReached && !tractionDeficit && (trainIsClearing || (trainIsBrakingDownhill == resistingForceNegative)) # while clearing tractive or braking force can be used
|
while trainInPreviousCS && !targetPositionReached && !tractionDeficit && (trainIsClearing || (trainIsBrakingDownhill == resistingForceNegative)) # while clearing tractive or braking force can be used
|
||||||
currentStepSize = settings[:stepSize]
|
currentStepSize = settings.stepSize
|
||||||
nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])
|
nextPointOfInterest = getNextPointOfInterest(CS[:pointsOfInterest], drivingCourse[end][:s])
|
||||||
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
||||||
|
|
||||||
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
|
for cycle in 1:settings.approxLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
|
||||||
while trainInPreviousCS && !targetPositionReached && !pointOfInterestReached && !tractionDeficit && (trainIsClearing || (trainIsBrakingDownhill == resistingForceNegative)) # while clearing tractive or braking force can be used
|
while trainInPreviousCS && !targetPositionReached && !pointOfInterestReached && !tractionDeficit && (trainIsClearing || (trainIsBrakingDownhill == resistingForceNegative)) # while clearing tractive or braking force can be used
|
||||||
# 03/09 old: while drivingCourse[end][:s] < CS[:s_entry] + train[:length] && drivingCourse[end][:s] < BS[:s_entry] +s_cruising && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:F_T]>=drivingCourse[end][:F_R]
|
# 03/09 old: while drivingCourse[end][:s] < CS[:s_entry] + train[:length] && drivingCourse[end][:s] < BS[:s_entry] +s_cruising && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:F_T]>=drivingCourse[end][:F_R]
|
||||||
# the tractive effort is lower than the resisiting forces and the train has use the highest possible effort to try to stay at v_peak OR the mass model homogeneous strip is used and parts of the train are still in former CS
|
# the tractive effort is lower than the resisiting forces and the train has use the highest possible effort to try to stay at v_peak OR the mass model homogeneous strip is used and parts of the train are still in former CS
|
||||||
|
@ -626,21 +611,21 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::
|
||||||
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" || settings[:stepVariable] =="t in s"
|
if settings.stepVariable == :distance || settings.stepVariable == time
|
||||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
|
push!(drivingCourse, moveAStep(drivingCourse[end], settings.stepVariable, currentStepSize, CS[:id]))
|
||||||
else
|
else
|
||||||
push!(drivingCourse, moveAStep(drivingCourse[end], "s in m", train[:length]/(10.0^cycle), CS[:id])) # TODO which step size should be used?
|
push!(drivingCourse, moveAStep(drivingCourse[end], position, 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])
|
||||||
|
|
||||||
# traction effort and resisting forces (in N)
|
# traction effort and resisting forces (in N)
|
||||||
calculateForces!(drivingCourse[end], CSs, CS[:id], "default", train, settings[:massModel])
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "default", train, settings.massModel)
|
||||||
# calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
|
# calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings.massModel)
|
||||||
#if !trainIsBrakingDownhill
|
#if !trainIsBrakingDownhill
|
||||||
# calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
|
# calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings.massModel)
|
||||||
#else
|
#else
|
||||||
# calculateForces!(drivingCourse[end], CSs, CS[:id], "braking", train, settings[:massModel])
|
# calculateForces!(drivingCourse[end], CSs, CS[:id], "braking", train, settings.massModel)
|
||||||
#end
|
#end
|
||||||
|
|
||||||
# conditions for the next while cycle
|
# conditions for the next while cycle
|
||||||
|
@ -652,28 +637,28 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::
|
||||||
end #while
|
end #while
|
||||||
|
|
||||||
# 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 < settings.approxLevel+1
|
||||||
if drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
|
if drivingCourse[end][:F_T] < drivingCourse[end][:F_R]
|
||||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
currentStepSize = settings.stepSize / 10.0^cycle
|
||||||
|
|
||||||
elseif !trainIsBrakingDownhill && resistingForceNegative
|
elseif !trainIsBrakingDownhill && resistingForceNegative
|
||||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
currentStepSize = settings.stepSize / 10.0^cycle
|
||||||
|
|
||||||
elseif trainIsBrakingDownhill && !resistingForceNegative
|
elseif trainIsBrakingDownhill && !resistingForceNegative
|
||||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
currentStepSize = settings.stepSize / 10.0^cycle
|
||||||
|
|
||||||
elseif drivingCourse[end][:s] > nextPointOfInterest
|
elseif drivingCourse[end][:s] > nextPointOfInterest
|
||||||
if settings[:stepVariable] == "s in m"
|
if settings.stepVariable == :distance
|
||||||
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
|
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
|
||||||
else
|
else
|
||||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
currentStepSize = settings.stepSize / 10.0^cycle
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif drivingCourse[end][:s] > BS[:s_entry] + s_cruising # TODO also the following? drivingCourse[end][:s] > CSs[CS[:id]][:s_entry] + train[:length]))
|
elseif drivingCourse[end][:s] > BS[:s_entry] + s_cruising # TODO also the following? drivingCourse[end][:s] > CSs[CS[:id]][:s_entry] + train[:length]))
|
||||||
if settings[:stepVariable] == "s in m"
|
if settings.stepVariable == :distance
|
||||||
currentStepSize=BS[:s_entry] + s_cruising-drivingCourse[end-1][:s]
|
currentStepSize=BS[:s_entry] + s_cruising-drivingCourse[end-1][:s]
|
||||||
else
|
else
|
||||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
currentStepSize = settings.stepSize / 10.0^cycle
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif drivingCourse[end][:s] == BS[:s_entry] + s_cruising # || drivingCourse[end][:s]==CS[:s_exit]
|
elseif drivingCourse[end][:s] == BS[:s_entry] + s_cruising # || drivingCourse[end][:s]==CS[:s_exit]
|
||||||
|
@ -689,7 +674,7 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::
|
||||||
break
|
break
|
||||||
|
|
||||||
else
|
else
|
||||||
error("ERROR at cruising section: With the step variable ",settings[:stepVariable]," the while loop will be left although the if cases don't apply in CS",CS[:id]," with s=" ,drivingCourse[end][:s]," m and v=",drivingCourse[end][:v]," m/s")
|
error("ERROR at cruising section: With the step variable ",settings.stepVariable," the while loop will be left although the if cases don't apply in CS",CS[:id]," with s=" ,drivingCourse[end][:s]," m and v=",drivingCourse[end][:v]," m/s")
|
||||||
end
|
end
|
||||||
|
|
||||||
# delete last data point for recalculating the last step with reduced step size
|
# delete last data point for recalculating the last step with reduced step size
|
||||||
|
@ -757,16 +742,16 @@ function addCruisingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::
|
||||||
s_cruisingRemaining = min(nextPointOfInterest -drivingCourse[end][:s], BS[:s_entry] +s_cruising -drivingCourse[end][:s])
|
s_cruisingRemaining = min(nextPointOfInterest -drivingCourse[end][:s], BS[:s_entry] +s_cruising -drivingCourse[end][:s])
|
||||||
|
|
||||||
# create the next data point
|
# create the next data point
|
||||||
push!(drivingCourse, moveAStep(drivingCourse[end], "s in m", s_cruisingRemaining, CS[:id]))
|
push!(drivingCourse, moveAStep(drivingCourse[end], :distance, 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])
|
||||||
|
|
||||||
calculateForces!(drivingCourse[end], CSs, CS[:id], "default", train, settings[:massModel])
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "default", train, settings.massModel)
|
||||||
# calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
|
# calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings.massModel)
|
||||||
#if !trainIsBrakingDownhill
|
#if !trainIsBrakingDownhill
|
||||||
# calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings[:massModel])
|
# calculateForces!(drivingCourse[end], CSs, CS[:id], "cruising", train, settings.massModel)
|
||||||
#else
|
#else
|
||||||
# calculateForces!(drivingCourse[end], CSs, CS[:id], "braking", train, settings[:massModel])
|
# calculateForces!(drivingCourse[end], CSs, CS[:id], "braking", train, settings.massModel)
|
||||||
#end
|
#end
|
||||||
|
|
||||||
# conditions for the next while cycle
|
# conditions for the next while cycle
|
||||||
|
@ -808,8 +793,8 @@ end #function addCruisingSection!
|
||||||
|
|
||||||
|
|
||||||
## This function calculates the data points for diminishing run when using maximum tractive effort and still getting slower
|
## This function calculates the data points for diminishing run when using maximum tractive effort and still getting slower
|
||||||
function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, settings::Dict, train::Dict, CSs::Vector{Dict})
|
function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, settings::Settings, train::Dict, CSs::Vector{Dict})
|
||||||
calculateForces!(drivingCourse[end], CSs, CS[:id], "diminishing", train, settings[:massModel])
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "diminishing", train, settings.massModel)
|
||||||
|
|
||||||
if haskey(stateFlags, :usedForDefiningCharacteristics) && stateFlags[:usedForDefiningCharacteristics]
|
if haskey(stateFlags, :usedForDefiningCharacteristics) && stateFlags[:usedForDefiningCharacteristics]
|
||||||
ignoreBraking = true
|
ignoreBraking = true
|
||||||
|
@ -832,22 +817,22 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlag
|
||||||
drivingCourse[end][:behavior] = BS[:type]
|
drivingCourse[end][:behavior] = BS[:type]
|
||||||
|
|
||||||
while tractionDeficit && !targetSpeedReached && !endOfCSReached && !brakingStartReached
|
while tractionDeficit && !targetSpeedReached && !endOfCSReached && !brakingStartReached
|
||||||
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])
|
||||||
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
||||||
|
|
||||||
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
|
for cycle in 1:settings.approxLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
|
||||||
while tractionDeficit && !brakingStartReached && !pointOfInterestReached && !targetSpeedReached
|
while tractionDeficit && !brakingStartReached && !pointOfInterestReached && !targetSpeedReached
|
||||||
# 03/09 old: while drivingCourse[end][:F_T] < drivingCourse[end][:F_R] && !brakingStartReached && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:v]>0.0 # as long as s_i + s_braking < s_end
|
# 03/09 old: while drivingCourse[end][:F_T] < drivingCourse[end][:F_R] && !brakingStartReached && drivingCourse[end][:s] < nextPointOfInterest && drivingCourse[end][:v]>0.0 # as long as s_i + s_braking < s_end
|
||||||
# acceleration (in m/s^2):
|
# acceleration (in m/s^2):
|
||||||
drivingCourse[end][:a] = calcAcceleration(drivingCourse[end][:F_T], drivingCourse[end][:F_R], train[:m_train], train[:ξ_train])
|
drivingCourse[end][:a] = calcAcceleration(drivingCourse[end][:F_T], drivingCourse[end][:F_R], train[:m_train], train[:ξ_train])
|
||||||
|
|
||||||
# create the next data point
|
# create the next data point
|
||||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
|
push!(drivingCourse, moveAStep(drivingCourse[end], settings.stepVariable, currentStepSize, CS[:id]))
|
||||||
drivingCourse[end][:behavior] = BS[:type]
|
drivingCourse[end][:behavior] = BS[:type]
|
||||||
push!(BS[:dataPoints], drivingCourse[end][:i])
|
push!(BS[:dataPoints], drivingCourse[end][:i])
|
||||||
|
|
||||||
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
|
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings.massModel)
|
||||||
|
|
||||||
# conditions for the next while cycle
|
# conditions for the next while cycle
|
||||||
if !ignoreBraking
|
if !ignoreBraking
|
||||||
|
@ -867,27 +852,27 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlag
|
||||||
end
|
end
|
||||||
|
|
||||||
# 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 < settings.approxLevel+1
|
||||||
if drivingCourse[end][:v] < 0.0
|
if drivingCourse[end][:v] < 0.0
|
||||||
if settings[:stepVariable] == "v in m/s"
|
if settings.stepVariable == velocity
|
||||||
currentStepSize = drivingCourse[end-1][:v]
|
currentStepSize = drivingCourse[end-1][:v]
|
||||||
else
|
else
|
||||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
currentStepSize = settings.stepSize / 10.0^cycle
|
||||||
end
|
end
|
||||||
elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
|
elseif drivingCourse[end][:F_T] > drivingCourse[end][:F_R]
|
||||||
testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: F_T=", drivingCourse[end][:F_T]," > F_R=",drivingCourse[end][:F_R]) # for testing
|
testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: F_T=", drivingCourse[end][:F_T]," > F_R=",drivingCourse[end][:F_R]) # for testing
|
||||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
currentStepSize = settings.stepSize / 10.0^cycle
|
||||||
|
|
||||||
elseif s_braking > 0.0 && drivingCourse[end][:s] + s_braking > CS[:s_exit]
|
elseif s_braking > 0.0 && drivingCourse[end][:s] + s_braking > CS[:s_exit]
|
||||||
testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],"+",s_braking," = ",drivingCourse[end][:s] +s_braking," > s_exit=",CS[:s_exit]) # for testing
|
testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],"+",s_braking," = ",drivingCourse[end][:s] +s_braking," > s_exit=",CS[:s_exit]) # for testing
|
||||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
currentStepSize = settings.stepSize / 10.0^cycle
|
||||||
|
|
||||||
elseif drivingCourse[end][:s] > nextPointOfInterest
|
elseif drivingCourse[end][:s] > nextPointOfInterest
|
||||||
testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: s=", drivingCourse[end][:s]," > nextPOI=",nextPointOfInterest) # for testing
|
testFlag && println("in CS",CS[:id]," diminishing cycle",cycle," case: s=", drivingCourse[end][:s]," > nextPOI=",nextPointOfInterest) # for testing
|
||||||
if settings[:stepVariable] == "s in m"
|
if settings.stepVariable == :distance
|
||||||
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
|
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
|
||||||
else
|
else
|
||||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
currentStepSize = settings.stepSize / 10.0^cycle
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif drivingCourse[end][:s] + s_braking == CS[:s_exit]
|
elseif drivingCourse[end][:s] + s_braking == CS[:s_exit]
|
||||||
|
@ -908,7 +893,7 @@ function addDiminishingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlag
|
||||||
" 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.")
|
" 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
|
||||||
# delete last data point for recalculating the last step with reduced step size
|
# delete last data point for recalculating the last step with reduced step size
|
||||||
pop!(drivingCourse)
|
pop!(drivingCourse)
|
||||||
|
@ -995,7 +980,7 @@ end #function addDiminishingSection!
|
||||||
|
|
||||||
## This function calculates the data points of the coasting section.
|
## This function calculates the data points of the coasting section.
|
||||||
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the coasting section
|
# Therefore it gets its previous driving course and the characteristic section and returns the characteristic section and driving course including the coasting section
|
||||||
function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, settings::Dict, train::Dict, CSs::Vector{Dict})
|
function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, settings::Settings, train::Dict, CSs::Vector{Dict})
|
||||||
# TODO: if the rear of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
|
# TODO: if the rear of the train is still located in a former characteristic section it has to be checked if its speed limit can be kept
|
||||||
# with getCurrentSpeedLimit
|
# with getCurrentSpeedLimit
|
||||||
|
|
||||||
|
@ -1012,21 +997,21 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::
|
||||||
drivingCourse[end][:behavior] = BS[:type]
|
drivingCourse[end][:behavior] = BS[:type]
|
||||||
|
|
||||||
while !targetSpeedReached && !endOfCSReached && !brakingStartReached
|
while !targetSpeedReached && !endOfCSReached && !brakingStartReached
|
||||||
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])
|
||||||
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
||||||
|
|
||||||
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
|
for cycle in 1:settings.approxLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
|
||||||
while !targetSpeedReached && !brakingStartReached && !pointOfInterestReached
|
while !targetSpeedReached && !brakingStartReached && !pointOfInterestReached
|
||||||
# 03/09 old : while drivingCourse[end][:v] > CS[:v_exit] && drivingCourse[end][:v] <= CS[:v_peak] && !brakingStartReached && drivingCourse[end][:s] < nextPointOfInterest
|
# 03/09 old : while drivingCourse[end][:v] > CS[:v_exit] && drivingCourse[end][:v] <= CS[:v_peak] && !brakingStartReached && drivingCourse[end][:s] < nextPointOfInterest
|
||||||
# traction effort and resisting forces (in N):
|
# traction effort and resisting forces (in N):
|
||||||
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
|
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings.massModel)
|
||||||
|
|
||||||
# acceleration (in m/s^2):
|
# acceleration (in m/s^2):
|
||||||
drivingCourse[end][:a] = calcAcceleration(drivingCourse[end][:F_T], drivingCourse[end][:F_R], train[:m_train], train[:ξ_train])
|
drivingCourse[end][:a] = calcAcceleration(drivingCourse[end][:F_T], drivingCourse[end][:F_R], train[:m_train], train[:ξ_train])
|
||||||
|
|
||||||
# create the next data point
|
# create the next data point
|
||||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
|
push!(drivingCourse, moveAStep(drivingCourse[end], settings.stepVariable, currentStepSize, CS[:id]))
|
||||||
drivingCourse[end][:behavior] = BS[:type]
|
drivingCourse[end][:behavior] = BS[:type]
|
||||||
push!(BS[:dataPoints], drivingCourse[end][:i])
|
push!(BS[:dataPoints], drivingCourse[end][:i])
|
||||||
|
|
||||||
|
@ -1040,33 +1025,33 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::
|
||||||
testFlag = false
|
testFlag = false
|
||||||
|
|
||||||
# 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 < settings.approxLevel+1
|
||||||
if drivingCourse[end][:s] + s_braking > CS[:s_exit]
|
if drivingCourse[end][:s] + s_braking > CS[:s_exit]
|
||||||
testFlag && println("in CS",CS[:id]," coasting cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],"+",s_braking," = ",drivingCourse[end][:s] +s_braking," > s_exit=",CS[:s_exit]) # for testing
|
testFlag && println("in CS",CS[:id]," coasting cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],"+",s_braking," = ",drivingCourse[end][:s] +s_braking," > s_exit=",CS[:s_exit]) # for testing
|
||||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
currentStepSize = settings.stepSize / 10.0^cycle
|
||||||
|
|
||||||
elseif drivingCourse[end][:s] > nextPointOfInterest
|
elseif drivingCourse[end][:s] > nextPointOfInterest
|
||||||
testFlag && println("in CS",CS[:id]," coasting cycle",cycle," case: s=", drivingCourse[end][:s]," > nextPointOfInterest=",nextPointOfInterest) # for testing
|
testFlag && println("in CS",CS[:id]," coasting cycle",cycle," case: s=", drivingCourse[end][:s]," > nextPointOfInterest=",nextPointOfInterest) # for testing
|
||||||
|
|
||||||
if settings[:stepVariable] == "s in m"
|
if settings.stepVariable == :distance
|
||||||
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
|
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
|
||||||
else
|
else
|
||||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
currentStepSize = settings.stepSize / 10.0^cycle
|
||||||
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
|
||||||
testFlag && println("in CS",CS[:id]," coasting cycle",cycle," case: v=", drivingCourse[end][:v]," < v_exit=", CS[:v_exit]) # for testing
|
testFlag && println("in CS",CS[:id]," coasting cycle",cycle," case: v=", drivingCourse[end][:v]," < v_exit=", CS[:v_exit]) # for testing
|
||||||
if settings[:stepVariable] == "v in m/s"
|
if settings.stepVariable == velocity
|
||||||
currentStepSize = drivingCourse[end-1][:v] - CS[:v_exit]
|
currentStepSize = drivingCourse[end-1][:v] - CS[:v_exit]
|
||||||
else
|
else
|
||||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
currentStepSize = settings.stepSize / 10.0^cycle
|
||||||
end
|
end
|
||||||
elseif drivingCourse[end][:v] > CS[:v_peak]
|
elseif drivingCourse[end][:v] > CS[:v_peak]
|
||||||
testFlag && println("in CS",CS[:id]," coasting cycle",cycle," case: v=", drivingCourse[end][:v]," > v_peak=", CS[:v_peak]) # for testing
|
testFlag && println("in CS",CS[:id]," coasting cycle",cycle," case: v=", drivingCourse[end][:v]," > v_peak=", CS[:v_peak]) # for testing
|
||||||
if settings[:stepVariable] == "v in m/s"
|
if settings.stepVariable == velocity
|
||||||
currentStepSize = CS[:v_peak] - drivingCourse[end-1][:v]
|
currentStepSize = CS[:v_peak] - drivingCourse[end-1][:v]
|
||||||
else
|
else
|
||||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
currentStepSize = settings.stepSize / 10.0^cycle
|
||||||
end
|
end
|
||||||
elseif drivingCourse[end][:s] + s_braking == CS[:s_exit]
|
elseif drivingCourse[end][:s] + s_braking == CS[:s_exit]
|
||||||
testFlag && println("in CS",CS[:id]," coasting cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],"+",s_braking," = ",drivingCourse[end][:s] +s_braking," == s_exit=",CS[:s_exit]) # for testing
|
testFlag && println("in CS",CS[:id]," coasting cycle",cycle," case: s +s_braking=", drivingCourse[end][:s],"+",s_braking," = ",drivingCourse[end][:s] +s_braking," == s_exit=",CS[:s_exit]) # for testing
|
||||||
|
@ -1082,7 +1067,7 @@ function addCoastingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::
|
||||||
|
|
||||||
else
|
else
|
||||||
# TODO: not needed. just for testing
|
# TODO: not needed. just for testing
|
||||||
error("ERROR at coasting until braking section: With the step variable ",settings[:stepVariable]," the while loop will be left although v<v_peak and s+s_braking<s_exit in CS",CS[:id]," with s=" ,drivingCourse[end][:s]," m and v=",drivingCourse[end][:v]," m/s")
|
error("ERROR at coasting until braking section: With the step variable ",settings.stepVariable," the while loop will be left although v<v_peak and s+s_braking<s_exit in CS",CS[:id]," with s=" ,drivingCourse[end][:s]," m and v=",drivingCourse[end][:v]," m/s")
|
||||||
end
|
end
|
||||||
# delete last data point for recalculating the last step with reduced step size
|
# delete last data point for recalculating the last step with reduced step size
|
||||||
pop!(drivingCourse)
|
pop!(drivingCourse)
|
||||||
|
@ -1158,7 +1143,7 @@ end #function addCoastingSection!
|
||||||
|
|
||||||
## This function calculates the data points of the braking section.
|
## This function calculates the data points of the braking section.
|
||||||
# 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}, stateFlags::Dict, settings::Dict, train::Dict, CSs::Vector{Dict})
|
function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::Dict, settings::Settings, train::Dict, CSs::Vector{Dict})
|
||||||
# conditions for braking section
|
# conditions for braking section
|
||||||
targetSpeedReached = drivingCourse[end][:v] <= CS[:v_exit]
|
targetSpeedReached = drivingCourse[end][:v] <= CS[:v_exit]
|
||||||
endOfCSReached = drivingCourse[end][:s] >= CS[:s_exit] || stateFlags[:endOfCSReached]
|
endOfCSReached = drivingCourse[end][:s] >= CS[:s_exit] || stateFlags[:endOfCSReached]
|
||||||
|
@ -1169,21 +1154,21 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::D
|
||||||
drivingCourse[end][:behavior] = BS[:type]
|
drivingCourse[end][:behavior] = BS[:type]
|
||||||
|
|
||||||
while !targetSpeedReached && !endOfCSReached
|
while !targetSpeedReached && !endOfCSReached
|
||||||
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])
|
||||||
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
pointOfInterestReached = drivingCourse[end][:s] >= nextPointOfInterest
|
||||||
|
|
||||||
for cycle in 1:approximationLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
|
for cycle in 1:settings.approxLevel+1 # first cycle with normal step size followed by cycles with reduced step size depending on the level of approximation
|
||||||
while !targetSpeedReached && !endOfCSReached && !pointOfInterestReached
|
while !targetSpeedReached && !endOfCSReached && !pointOfInterestReached
|
||||||
# 03/09 old: while drivingCourse[end][:v] > CS[:v_exit] && !targetSpeedReached && drivingCourse[end][:s] < CS[:s_exit] && drivingCourse[end][:s] < nextPointOfInterest
|
# 03/09 old: while drivingCourse[end][:v] > CS[:v_exit] && !targetSpeedReached && drivingCourse[end][:s] < CS[:s_exit] && drivingCourse[end][:s] < nextPointOfInterest
|
||||||
# traction effort and resisting forces (in N):
|
# traction effort and resisting forces (in N):
|
||||||
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
|
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])
|
||||||
|
|
||||||
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
|
if settings.stepVariable == :distance && ((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
|
||||||
# create empty data point and set it for the values of s_exit and v_exit
|
# create empty data point and set it for the values of s_exit 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
|
||||||
|
@ -1192,7 +1177,7 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::D
|
||||||
recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
recalculateLastBrakingPoint!(drivingCourse, CS[:s_exit], CS[:v_exit])
|
||||||
else
|
else
|
||||||
# create the next data point
|
# create the next data point
|
||||||
push!(drivingCourse, moveAStep(drivingCourse[end], settings[:stepVariable], currentStepSize, CS[:id]))
|
push!(drivingCourse, moveAStep(drivingCourse[end], settings.stepVariable, currentStepSize, CS[:id]))
|
||||||
drivingCourse[end][:behavior] = BS[:type]
|
drivingCourse[end][:behavior] = BS[:type]
|
||||||
push!(BS[:dataPoints], drivingCourse[end][:i])
|
push!(BS[:dataPoints], drivingCourse[end][:i])
|
||||||
end
|
end
|
||||||
|
@ -1206,18 +1191,18 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::D
|
||||||
|
|
||||||
# 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
|
||||||
# TODO: is there a better way than rounding like in the following?
|
# TODO: is there a better way than rounding like in the following?
|
||||||
if cycle < approximationLevel+1
|
if cycle < settings.approxLevel+1
|
||||||
if drivingCourse[end][:v] < CS[:v_exit]
|
if drivingCourse[end][:v] < CS[:v_exit]
|
||||||
if settings[:stepVariable] == "v in m/s"
|
if settings.stepVariable == velocity
|
||||||
currentStepSize = drivingCourse[end-1][:v] - CS[:v_exit]
|
currentStepSize = drivingCourse[end-1][:v] - CS[:v_exit]
|
||||||
else
|
else
|
||||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
currentStepSize = settings.stepSize / 10.0^cycle
|
||||||
end
|
end
|
||||||
elseif drivingCourse[end][:s] > nextPointOfInterest
|
elseif drivingCourse[end][:s] > nextPointOfInterest
|
||||||
if settings[:stepVariable] == "s in m"
|
if settings.stepVariable == :distance
|
||||||
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
|
currentStepSize = nextPointOfInterest - drivingCourse[end-1][:s]
|
||||||
else
|
else
|
||||||
currentStepSize = settings[:stepSize] / 10.0^cycle
|
currentStepSize = settings.stepSize / 10.0^cycle
|
||||||
end
|
end
|
||||||
elseif drivingCourse[end][:v] == CS[:v_exit] && drivingCourse[end][:s] == CS[:s_exit]
|
elseif drivingCourse[end][:v] == CS[:v_exit] && drivingCourse[end][:s] == CS[:s_exit]
|
||||||
break
|
break
|
||||||
|
@ -1306,7 +1291,7 @@ function addBrakingSection!(CS::Dict, drivingCourse::Vector{Dict}, stateFlags::D
|
||||||
stateFlags[:speedLimitReached] = drivingCourse[end][:v] >= CS[:v_exit]
|
stateFlags[:speedLimitReached] = drivingCourse[end][:v] >= CS[:v_exit]
|
||||||
stateFlags[:endOfCSReached] = endOfCSReached
|
stateFlags[:endOfCSReached] = endOfCSReached
|
||||||
stateFlags[:error] = !(endOfCSReached)
|
stateFlags[:error] = !(endOfCSReached)
|
||||||
calculateForces!(drivingCourse[end], CSs, CS[:id], "default", train, settings[:massModel])
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "default", train, settings.massModel)
|
||||||
stateFlags[:resistingForceNegative] = drivingCourse[end][:F_R] < 0
|
stateFlags[:resistingForceNegative] = drivingCourse[end][:F_R] < 0
|
||||||
|
|
||||||
return (CS, drivingCourse, stateFlags)
|
return (CS, drivingCourse, stateFlags)
|
||||||
|
@ -1315,7 +1300,7 @@ end #function addBrakingSection!
|
||||||
|
|
||||||
## This function calculates the data point of the standstill.
|
## This function calculates the data point of the standstill.
|
||||||
# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the standstill if needed.
|
# Therefore it gets its first data point and the characteristic section and returns the characteristic section including the standstill if needed.
|
||||||
function addStandstill!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, train::Dict, CSs::Vector{Dict})
|
function addStandstill!(CS::Dict, drivingCourse::Vector{Dict}, settings::Settings, train::Dict, CSs::Vector{Dict})
|
||||||
if drivingCourse[end][:v] == 0.0
|
if drivingCourse[end][:v] == 0.0
|
||||||
BS = createBehaviorSection("standstill", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
|
BS = createBehaviorSection("standstill", drivingCourse[end][:s], drivingCourse[end][:v], drivingCourse[end][:i])
|
||||||
merge!(BS, Dict(:length => 0.0, # total length (in m)
|
merge!(BS, Dict(:length => 0.0, # total length (in m)
|
||||||
|
@ -1326,7 +1311,7 @@ function addStandstill!(CS::Dict, drivingCourse::Vector{Dict}, settings::Dict, t
|
||||||
drivingCourse[end][:behavior] = BS[:type]
|
drivingCourse[end][:behavior] = BS[:type]
|
||||||
|
|
||||||
# traction effort and resisting forces (in N)
|
# traction effort and resisting forces (in N)
|
||||||
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings[:massModel])
|
calculateForces!(drivingCourse[end], CSs, CS[:id], BS[:type], train, settings.massModel)
|
||||||
|
|
||||||
merge!(CS[:behaviorSections], Dict(:standstill => BS))
|
merge!(CS[:behaviorSections], Dict(:standstill => BS))
|
||||||
end # else: return the characteristic section without a standstillSection section
|
end # else: return the characteristic section without a standstillSection section
|
||||||
|
@ -1411,5 +1396,3 @@ function recalculateLastBrakingPoint!(drivingCourse, s_target, v_target)
|
||||||
currentPoint[:ΔE] = currentPoint[:ΔW] # energy consumption in this step (in Ws)
|
currentPoint[:ΔE] = currentPoint[:ΔW] # energy consumption in this step (in Ws)
|
||||||
currentPoint[:E] = previousPoint[:E] + currentPoint[:ΔE] # energy consumption (in Ws)
|
currentPoint[:E] = previousPoint[:E] + currentPoint[:ΔE] # energy consumption (in Ws)
|
||||||
end #function recalculateLastBrakingPoint
|
end #function recalculateLastBrakingPoint
|
||||||
|
|
||||||
end #module Behavior
|
|
||||||
|
|
|
@ -5,83 +5,55 @@
|
||||||
# __copyright__ = "2020-2022"
|
# __copyright__ = "2020-2022"
|
||||||
# __license__ = "ISC"
|
# __license__ = "ISC"
|
||||||
|
|
||||||
module TrainRunCalc
|
|
||||||
|
|
||||||
# include modules of TrainRunCalc
|
|
||||||
include("./Validate.jl")
|
|
||||||
include("./Characteristics.jl")
|
|
||||||
include("./Behavior.jl")
|
|
||||||
include("./Output.jl")
|
|
||||||
|
|
||||||
|
|
||||||
# use modules of TrainRunCalc
|
|
||||||
using .Validate
|
|
||||||
using .Characteristics
|
|
||||||
using .Behavior
|
|
||||||
using .Output
|
|
||||||
|
|
||||||
# export main function
|
|
||||||
export trainRun
|
|
||||||
|
|
||||||
approximationLevel = 6 # value for approximation to intersections and precisely calculated digits
|
|
||||||
# TODO: define it here and give it to each function? (Behavior, ...)
|
|
||||||
|
|
||||||
# Calculate the driving dynamics of a train run on a path with special settings with information from the corresponding YAML files with the file paths `trainDirectory`, `pathDirectory`, `settingsDirectory`.
|
# Calculate the driving dynamics of a train run on a path with special settings with information from the corresponding YAML files with the file paths `trainDirectory`, `pathDirectory`, `settingsDirectory`.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
trainRun(train::Dict, path::Dict, settings::Dict)
|
trainRun(train::Dict, path::Dict, settings::Settings)
|
||||||
|
|
||||||
Calculate the driving dynamics of a train run on a path with special settings with information from the corresponding dictionaries `train`, `path`, `settings`.
|
Calculate the driving dynamics of a train run on a path with special settings with information from the corresponding dictionaries `train`, `path`, `settings`.
|
||||||
|
|
||||||
# Examples
|
# Examples
|
||||||
```julia-repl
|
```julia-repl
|
||||||
julia> trainRun(trainDict, pathDict, settingsDict)
|
julia> trainRun(trainDict, pathDict)
|
||||||
todo !!!
|
todo !!!
|
||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
function trainRun(trainInput::Dict, pathInput::Dict, settingsInput::Dict)
|
function trainRun(trainInput::Dict, pathInput::Dict, settings=Settings()::Settings)
|
||||||
# copy Input data for not changing them
|
# copy Input data for not changing them
|
||||||
# TODO: or should they be changed? normally it would only make it "better" except for settings[:detailOfOutput] == "points of interest" && !haskey(path, :pointsOfInterest)
|
# TODO: or should they be changed? normally it would only make it "better" except for settings.outputDetail == :points_of_interest && !haskey(path, :pointsOfInterest)
|
||||||
train = copy(trainInput)
|
train = copy(trainInput)
|
||||||
path = copy(pathInput)
|
path = copy(pathInput)
|
||||||
settings = copy(settingsInput)
|
|
||||||
|
|
||||||
# check the input data
|
# check the input data
|
||||||
(train, path, settings) = checkAndSetInput!(train, path, settings)
|
(train, path) = checkAndSetInput!(train, path, settings)
|
||||||
settings[:detailOfOutput] == "everything" && println("The input has been checked.")
|
settings.outputDetail == :everything && println("The input has been checked.")
|
||||||
|
|
||||||
# prepare the input data
|
# prepare the input data
|
||||||
movingSection = determineCharacteristics(path, train, settings)
|
movingSection = determineCharacteristics(path, train, settings)
|
||||||
settings[:detailOfOutput] == "everything" && println("The moving section has been prepared.")
|
settings.outputDetail == :everything && println("The moving section has been prepared.")
|
||||||
|
|
||||||
# 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]
|
(movingSection, drivingCourse) = calculateMinimumRunningTime!(movingSection, settings, train)
|
||||||
(movingSection, drivingCourse) = calculateMinimumRunningTime!(movingSection, settings, train)
|
settings.outputDetail == :everything && println("The driving course for the shortest running time has been calculated.")
|
||||||
settings[:detailOfOutput] == "everything" && println("The driving course for the shortest running time has been calculated.")
|
|
||||||
|
|
||||||
# accumulate data and create an output dictionary
|
# accumulate data and create an output dictionary
|
||||||
output = createOutput(train, settings, path, movingSection, drivingCourse)
|
output = createOutput(train, settings, path, movingSection, drivingCourse)
|
||||||
# 30/31 old: output = createOutputDict(train, settings, path, movingSection, drivingCourse)
|
|
||||||
else
|
|
||||||
output = nothing
|
|
||||||
# 30/31 old: output = Dict()
|
|
||||||
end #if
|
|
||||||
|
|
||||||
return output
|
return output
|
||||||
end # function trainRun
|
end # function trainRun
|
||||||
|
|
||||||
# calculate a train run focussing on using the minimum possible running time
|
# calculate a train run focussing on using the minimum possible running time
|
||||||
function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train::Dict)
|
function calculateMinimumRunningTime!(movingSection::Dict, settings::Settings, train::Dict)
|
||||||
CSs::Vector{Dict} = movingSection[:characteristicSections]
|
CSs::Vector{Dict} = movingSection[:characteristicSections]
|
||||||
|
|
||||||
if settings[:massModel] == "homogeneous strip" && settings[:stepVariable] == "v in m/s"
|
if settings.massModel == :homogeneous_strip && settings.stepVariable == speed
|
||||||
println("WARNING: ! ! ! TrainRun.jl doesn't work reliably for the mass model homogeneous strip with step size v in m/s. The calculation time can be extremely high when calcutlating paths with steep gradients ! ! !")
|
println("WARNING: ! ! ! TrainRun.jl doesn't work reliably for the mass model homogeneous strip with step size v in m/s. The calculation time can be extremely high when calcutlating paths with steep gradients ! ! !")
|
||||||
end
|
end
|
||||||
|
|
||||||
startingPoint=createDataPoint()
|
startingPoint=createDataPoint()
|
||||||
startingPoint[:i]=1
|
startingPoint[:i]=1
|
||||||
startingPoint[:s]=CSs[1][:s_entry]
|
startingPoint[:s]=CSs[1][:s_entry]
|
||||||
calculateForces!(startingPoint, CSs, 1, "default", train, settings[:massModel]) # traction effort and resisting forces (in N)
|
calculateForces!(startingPoint, CSs, 1, "default", train, settings.massModel) # traction effort and resisting forces (in N)
|
||||||
drivingCourse::Vector{Dict} = [startingPoint] # List of data points
|
drivingCourse::Vector{Dict} = [startingPoint] # List of data points
|
||||||
|
|
||||||
for csId in 1:length(CSs)
|
for csId in 1:length(CSs)
|
||||||
|
@ -96,7 +68,7 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
|
||||||
|
|
||||||
# determine the different flags for switching between the states for creatinge moving phases
|
# determine the different flags for switching between the states for creatinge moving phases
|
||||||
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
||||||
calculateForces!(drivingCourse[end], CSs, CS[:id], "default", train, settings[:massModel]) # tractive effort and resisting forces (in N)
|
calculateForces!(drivingCourse[end], CSs, CS[:id], "default", train, settings.massModel) # tractive effort and resisting forces (in N)
|
||||||
|
|
||||||
previousSpeedLimitReached = false
|
previousSpeedLimitReached = false
|
||||||
stateFlags = Dict(:endOfCSReached => drivingCourse[end][:s] > CS[:s_exit],
|
stateFlags = Dict(:endOfCSReached => drivingCourse[end][:s] > CS[:s_exit],
|
||||||
|
@ -122,11 +94,11 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
|
||||||
|
|
||||||
elseif drivingCourse[end][:F_T] == drivingCourse[end][:F_R] && !stateFlags[:speedLimitReached]
|
elseif drivingCourse[end][:F_T] == drivingCourse[end][:F_R] && !stateFlags[:speedLimitReached]
|
||||||
# cruise only one step
|
# cruise only one step
|
||||||
if settings[:stepVariable] =="s in m"
|
if settings.stepVariable == :distance
|
||||||
s_cruising = settings[:stepSize]
|
s_cruising = settings.stepSize
|
||||||
elseif settings[:stepVariable] =="t in s"
|
elseif settings.stepVariable == time
|
||||||
s_cruising = calc_Δs_with_Δt(settings[:stepSize], drivingCourse[end][:a], drivingCourse[end][:v])
|
s_cruising = calc_Δs_with_Δt(settings.stepSize, drivingCourse[end][:a], drivingCourse[end][:v])
|
||||||
elseif settings[:stepVariable] =="v in m/s"
|
elseif settings.stepVariable == velocity
|
||||||
s_cruising = train[:length]/(10.0) # TODO which step size should be used?
|
s_cruising = train[:length]/(10.0) # TODO which step size should be used?
|
||||||
end
|
end
|
||||||
(CS, drivingCourse, stateFlags) = addCruisingSection!(CS, drivingCourse, stateFlags, s_cruising, settings, train, CSs, "cruising")
|
(CS, drivingCourse, stateFlags) = addCruisingSection!(CS, drivingCourse, stateFlags, s_cruising, settings, train, CSs, "cruising")
|
||||||
|
@ -186,5 +158,3 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
|
||||||
|
|
||||||
return (movingSection, drivingCourse)
|
return (movingSection, drivingCourse)
|
||||||
end #function calculateMinimumRunningTime
|
end #function calculateMinimumRunningTime
|
||||||
|
|
||||||
end # module TrainRunCalc
|
|
|
@ -5,15 +5,8 @@
|
||||||
# __copyright__ = "2020-2022"
|
# __copyright__ = "2020-2022"
|
||||||
# __license__ = "ISC"
|
# __license__ = "ISC"
|
||||||
|
|
||||||
module Characteristics
|
|
||||||
|
|
||||||
include("./Behavior.jl")
|
|
||||||
using .Behavior
|
|
||||||
|
|
||||||
export determineCharacteristics
|
|
||||||
|
|
||||||
## create a moving section and its containing characteristic sections with secured braking, accelerating and cruising behavior
|
## create a moving section and its containing characteristic sections with secured braking, accelerating and cruising behavior
|
||||||
function determineCharacteristics(path::Dict, train::Dict, settings::Dict)
|
function determineCharacteristics(path::Dict, train::Dict, settings::Settings)
|
||||||
movingSection = createMovingSection(path, train[:v_limit])
|
movingSection = createMovingSection(path, train[:v_limit])
|
||||||
movingSection = secureBrakingBehavior!(movingSection, train[:a_braking])
|
movingSection = secureBrakingBehavior!(movingSection, train[:a_braking])
|
||||||
movingSection = secureAcceleratingBehavior!(movingSection, settings, train)
|
movingSection = secureAcceleratingBehavior!(movingSection, settings, train)
|
||||||
|
@ -123,7 +116,7 @@ function secureBrakingBehavior!(movingSection::Dict, a_braking::Real)
|
||||||
end #function secureBrakingBehavior!
|
end #function secureBrakingBehavior!
|
||||||
|
|
||||||
## define the intersection velocities between the characterisitc sections to secure accelerating behavior
|
## define the intersection velocities between the characterisitc sections to secure accelerating behavior
|
||||||
function secureAcceleratingBehavior!(movingSection::Dict, settings::Dict, train::Dict)
|
function secureAcceleratingBehavior!(movingSection::Dict, settings::Settings, train::Dict)
|
||||||
# this function limits the entry and exit velocity of the characteristic sections in case that the train accelerates in every section and cruises aterwards
|
# this function limits the entry and exit velocity of the characteristic sections in case that the train accelerates in every section and cruises aterwards
|
||||||
CSs = movingSection[:characteristicSections]
|
CSs = movingSection[:characteristicSections]
|
||||||
|
|
||||||
|
@ -136,7 +129,7 @@ function secureAcceleratingBehavior!(movingSection::Dict, settings::Dict, train:
|
||||||
CS[:v_entry] = min(CS[:v_entry], previousCSv_exit)
|
CS[:v_entry] = min(CS[:v_entry], previousCSv_exit)
|
||||||
startingPoint[:s] = CS[:s_entry]
|
startingPoint[:s] = CS[:s_entry]
|
||||||
startingPoint[:v] = CS[:v_entry]
|
startingPoint[:v] = CS[:v_entry]
|
||||||
calculateForces!(startingPoint, CSs, CS[:id], "accelerating", train, settings[:massModel]) # traction effort and resisting forces (in N)
|
calculateForces!(startingPoint, CSs, CS[:id], "accelerating", train, settings.massModel) # traction effort and resisting forces (in N)
|
||||||
acceleratingCourse::Vector{Dict} = [startingPoint] # List of data points
|
acceleratingCourse::Vector{Dict} = [startingPoint] # List of data points
|
||||||
|
|
||||||
if CS[:v_entry] < CS[:v_peak]
|
if CS[:v_entry] < CS[:v_peak]
|
||||||
|
@ -160,7 +153,7 @@ function secureAcceleratingBehavior!(movingSection::Dict, settings::Dict, train:
|
||||||
(CS, acceleratingCourse, stateFlags) = addClearingSection!(CS, acceleratingCourse, stateFlags, settings, train, CSs) # this function is needed in case the train is not allowed to accelerate because of a previous speed limit
|
(CS, acceleratingCourse, stateFlags) = addClearingSection!(CS, acceleratingCourse, stateFlags, settings, train, CSs) # this function is needed in case the train is not allowed to accelerate because of a previous speed limit
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if settings[:massModel] == "mass point" || acceleratingCourse[end][:s] > CS[:s_entry] + train[:length]
|
if settings.massModel == :mass_point || acceleratingCourse[end][:s] > CS[:s_entry] + train[:length]
|
||||||
break
|
break
|
||||||
else
|
else
|
||||||
(CS, acceleratingCourse, stateFlags) = addDiminishingSection!(CS, acceleratingCourse, stateFlags, settings, train, CSs) # this function is needed in case the resisitng forces are higher than the maximum possible tractive effort
|
(CS, acceleratingCourse, stateFlags) = addDiminishingSection!(CS, acceleratingCourse, stateFlags, settings, train, CSs) # this function is needed in case the resisitng forces are higher than the maximum possible tractive effort
|
||||||
|
@ -190,7 +183,7 @@ end #function secureAcceleratingBehavior!
|
||||||
|
|
||||||
#=
|
#=
|
||||||
## define the intersection velocities between the characterisitc sections to secure cruising behavior
|
## define the intersection velocities between the characterisitc sections to secure cruising behavior
|
||||||
function secureCruisingBehavior!(movingSection::Dict, settings::Dict, train::Dict)
|
function secureCruisingBehavior!(movingSection::Dict, settings::Settings, train::Dict)
|
||||||
# limit the exit velocity of the characteristic sections in case that the train cruises in every section at v_peak
|
# limit the exit velocity of the characteristic sections in case that the train cruises in every section at v_peak
|
||||||
CSs = movingSection[:characteristicSections]
|
CSs = movingSection[:characteristicSections]
|
||||||
|
|
||||||
|
@ -225,7 +218,7 @@ function secureCruisingBehavior!(movingSection::Dict, settings::Dict, train::Dic
|
||||||
(CS, cruisingCourse, stateFlags) = addCruisingSection!(CS, cruisingCourse, stateFlags, s_cruising, settings, train, CSs, "downhillBraking")
|
(CS, cruisingCourse, stateFlags) = addCruisingSection!(CS, cruisingCourse, stateFlags, s_cruising, settings, train, CSs, "downhillBraking")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if settings[:massModel] == "mass point" || cruisingCourse[end][:s] > CS[:s_entry] + train[:length]
|
if settings.massModel == :mass_point || cruisingCourse[end][:s] > CS[:s_entry] + train[:length]
|
||||||
break
|
break
|
||||||
else
|
else
|
||||||
(CS, cruisingCourse, stateFlags) = addDiminishingSection!(CS, cruisingCourse, stateFlags, settings, train, CSs) # this function is needed in case the resisitng forces are higher than the maximum possible tractive effort
|
(CS, cruisingCourse, stateFlags) = addDiminishingSection!(CS, cruisingCourse, stateFlags, settings, train, CSs) # this function is needed in case the resisitng forces are higher than the maximum possible tractive effort
|
||||||
|
@ -246,4 +239,3 @@ function secureCruisingBehavior!(movingSection::Dict, settings::Dict, train::Dic
|
||||||
return movingSection
|
return movingSection
|
||||||
end #function secureCruisingBehavior!
|
end #function secureCruisingBehavior!
|
||||||
=#
|
=#
|
||||||
end #module Characteristics
|
|
||||||
|
|
1045
src/EnergySaving.jl
1045
src/EnergySaving.jl
File diff suppressed because it is too large
Load Diff
|
@ -5,32 +5,26 @@
|
||||||
# __copyright__ = "2020-2022"
|
# __copyright__ = "2020-2022"
|
||||||
# __license__ = "ISC"
|
# __license__ = "ISC"
|
||||||
|
|
||||||
module Export
|
function exportToCsv(runningTime::AbstractFloat, settings::Settings)
|
||||||
|
|
||||||
using CSV, DataFrames, Dates
|
|
||||||
|
|
||||||
export exportToCsv
|
|
||||||
|
|
||||||
function exportToCsv(runningTime::AbstractFloat, settings::Dict)
|
|
||||||
createCsvFile(runningTime, settings)
|
createCsvFile(runningTime, settings)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function exportToCsv(dataPointsToExport::Vector{Dict}, settings::Dict)
|
function exportToCsv(dataPointsToExport::Vector{Dict}, settings::Settings)
|
||||||
createCsvFile(dataPointsToExport, settings)
|
createCsvFile(dataPointsToExport, settings)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function exportToCsv(output::Dict)
|
function exportToCsv(output::Dict)
|
||||||
if output[:settings][:typeOfOutput] == "CSV"
|
if output[:settings][:outputFormat] == "CSV"
|
||||||
pathName = output[:path][:name]
|
pathName = output[:path][:name]
|
||||||
trainName = output[:train][:name]
|
trainName = output[:train][:name]
|
||||||
|
|
||||||
if output[:settings][:operationModeMinimumRunningTime] == true
|
if output[:settings][:operationModeMinimumRunningTime] == true
|
||||||
operationMode = "minimum running time"
|
operationMode = "minimum running time"
|
||||||
if output[:settings][:detailOfOutput] == "points of interest"
|
if output[:settings][:outputDetail] == "points of interest"
|
||||||
dataPointsToExport = output[:pointsOfInterestMinimumRunningTime]
|
dataPointsToExport = output[:pointsOfInterestMinimumRunningTime]
|
||||||
else
|
else
|
||||||
dataPointsToExport = output[:drivingCourseMinimumRunningTime]
|
dataPointsToExport = output[:drivingCourseMinimumRunningTime]
|
||||||
|
@ -39,7 +33,7 @@ function exportToCsv(output::Dict)
|
||||||
end
|
end
|
||||||
if output[:settings][:operationModeMinimumEnergyConsumption] == true
|
if output[:settings][:operationModeMinimumEnergyConsumption] == true
|
||||||
operationMode = "minimum energy consumption"
|
operationMode = "minimum energy consumption"
|
||||||
if output[:settings][:detailOfOutput] == "points of interest"
|
if output[:settings][:outputDetail] == "points of interest"
|
||||||
dataPointsToExport = output[:pointsOfInterestMinimumEnergyConsumption]
|
dataPointsToExport = output[:pointsOfInterestMinimumEnergyConsumption]
|
||||||
else
|
else
|
||||||
dataPointsToExport = output[:drivingCourseMinimumEnergyConsumption]
|
dataPointsToExport = output[:drivingCourseMinimumEnergyConsumption]
|
||||||
|
@ -51,15 +45,15 @@ function exportToCsv(output::Dict)
|
||||||
return false
|
return false
|
||||||
end #function exportToCsv
|
end #function exportToCsv
|
||||||
|
|
||||||
function createCsvFile(runningTime::AbstractFloat, settings::Dict)
|
function createCsvFile(runningTime::AbstractFloat, settings::Settings)
|
||||||
# create DataFrame with running time information
|
# create DataFrame with running time information
|
||||||
df = DataFrame(column1=["t (in s)", runningTime])
|
df = DataFrame(column1=["t (in s)", runningTime])
|
||||||
|
|
||||||
# save DataFrame as a CSV-file at csvDirectory
|
# save DataFrame as a CSV-file at outputDir
|
||||||
date = Dates.now()
|
date = Dates.now()
|
||||||
dateString = Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
|
dateString = Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
|
||||||
|
|
||||||
csvFilePath = settings[:csvDirectory]*"/"*dateString*"_RunningTime.csv"
|
csvFilePath = settings[:outputDir]*"/"*dateString*"_RunningTime.csv"
|
||||||
|
|
||||||
CSV.write(csvFilePath, df, header=false)
|
CSV.write(csvFilePath, df, header=false)
|
||||||
println("The output CSV file has been created at ",csvFilePath)
|
println("The output CSV file has been created at ",csvFilePath)
|
||||||
|
@ -68,8 +62,8 @@ function createCsvFile(runningTime::AbstractFloat, settings::Dict)
|
||||||
end #function createCsvFile
|
end #function createCsvFile
|
||||||
|
|
||||||
|
|
||||||
function createCsvFile(dataPointsToExport::Vector{Dict}, settings::Dict)
|
function createCsvFile(dataPointsToExport::Vector{Dict}, settings::Settings)
|
||||||
detailOfOutput = settings[:detailOfOutput]
|
outputDetail = settings[:outputDetail]
|
||||||
|
|
||||||
header = ["i", "behavior", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_wagons (in N)", "ΔW (in Ws)","W (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]
|
header = ["i", "behavior", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_wagons (in N)", "ΔW (in Ws)","W (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]
|
||||||
columnSymbols = [:i, :behavior, :Δs, :s, :Δt, :t, :Δv, :v, :F_T, :F_R, :R_path, :R_train, :R_traction, :R_wagons, :ΔW, :W, :ΔE, :E, :a]
|
columnSymbols = [:i, :behavior, :Δs, :s, :Δt, :t, :Δv, :v, :F_T, :F_R, :R_path, :R_train, :R_traction, :R_wagons, :ΔW, :W, :ΔE, :E, :a]
|
||||||
|
@ -85,8 +79,8 @@ function createCsvFile(dataPointsToExport::Vector{Dict}, settings::Dict)
|
||||||
end # for
|
end # for
|
||||||
|
|
||||||
|
|
||||||
# combine the columns in a data frame and saving it as a CSV-file at csvDirectory
|
# combine the columns in a data frame and saving it as a CSV-file at outputDir
|
||||||
if detailOfOutput == "driving course" || detailOfOutput == "points of interest"
|
if outputDetail == "driving course" || outputDetail == "points of interest"
|
||||||
df = DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3], c4=allColumns[4], c5=allColumns[5], c6=allColumns[6], c7=allColumns[7], c8=allColumns[8], c9=allColumns[9], c10=allColumns[10], c11=allColumns[11], c12=allColumns[12], c13=allColumns[13], c14=allColumns[14], c15=allColumns[15], c16=allColumns[16], c17=allColumns[17], c18=allColumns[18], c19=allColumns[19])
|
df = DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3], c4=allColumns[4], c5=allColumns[5], c6=allColumns[6], c7=allColumns[7], c8=allColumns[8], c9=allColumns[9], c10=allColumns[10], c11=allColumns[11], c12=allColumns[12], c13=allColumns[13], c14=allColumns[14], c15=allColumns[15], c16=allColumns[16], c17=allColumns[17], c18=allColumns[18], c19=allColumns[19])
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -95,7 +89,7 @@ function createCsvFile(dataPointsToExport::Vector{Dict}, settings::Dict)
|
||||||
|
|
||||||
date = Dates.now()
|
date = Dates.now()
|
||||||
dateString=Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
|
dateString=Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
|
||||||
csvFilePath=settings[:csvDirectory]*"/"*dateString*"_DataPoints.csv"
|
csvFilePath=settings[:outputDir]*"/"*dateString*"_DataPoints.csv"
|
||||||
CSV.write(csvFilePath, df, header=false)
|
CSV.write(csvFilePath, df, header=false)
|
||||||
println("The output CSV file has been created at ",csvFilePath)
|
println("The output CSV file has been created at ",csvFilePath)
|
||||||
|
|
||||||
|
@ -103,12 +97,12 @@ function createCsvFile(dataPointsToExport::Vector{Dict}, settings::Dict)
|
||||||
end #function createCsvFile
|
end #function createCsvFile
|
||||||
|
|
||||||
|
|
||||||
function createCsvFile(dataPointsToExport::Vector{Dict}, operationMode::String, pathName::String, trainName::String, settings::Dict)
|
function createCsvFile(dataPointsToExport::Vector{Dict}, operationMode::String, pathName::String, trainName::String, settings::Settings)
|
||||||
detailOfOutput = settings[:detailOfOutput]
|
outputDetail = settings[:outputDetail]
|
||||||
|
|
||||||
massModel = settings[:massModel]
|
massModel = settings.massModel
|
||||||
stepVariable = settings[:stepVariable]
|
stepVariable = settings.stepVariable
|
||||||
stepSize = string(settings[:stepSize])
|
stepSize = string(settings.stepSize)
|
||||||
|
|
||||||
# create accumulated data block
|
# create accumulated data block
|
||||||
accumulatedData = Array{Any, 1}[]
|
accumulatedData = Array{Any, 1}[]
|
||||||
|
@ -135,15 +129,15 @@ function createCsvFile(dataPointsToExport::Vector{Dict}, operationMode::String,
|
||||||
end
|
end
|
||||||
end # for
|
end # for
|
||||||
|
|
||||||
# combine the columns in a data frame and saving it as a CSV-file at csvDirectory
|
# combine the columns in a data frame and saving it as a CSV-file at outputDir
|
||||||
df = DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3], c4=allColumns[4], c5=allColumns[5], c6=allColumns[6], c7=allColumns[7], c8=allColumns[8], c9=allColumns[9], c10=allColumns[10], c11=allColumns[11], c12=allColumns[12], c13=allColumns[13], c14=allColumns[14], c15=allColumns[15], c16=allColumns[16], c17=allColumns[17], c18=allColumns[18], c19=allColumns[19])
|
df = DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3], c4=allColumns[4], c5=allColumns[5], c6=allColumns[6], c7=allColumns[7], c8=allColumns[8], c9=allColumns[9], c10=allColumns[10], c11=allColumns[11], c12=allColumns[12], c13=allColumns[13], c14=allColumns[14], c15=allColumns[15], c16=allColumns[16], c17=allColumns[17], c18=allColumns[18], c19=allColumns[19])
|
||||||
|
|
||||||
date = Dates.now()
|
date = Dates.now()
|
||||||
dateString=Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
|
dateString=Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
|
||||||
if operationMode == "minimum running time"
|
if operationMode == "minimum running time"
|
||||||
csvFilePath=settings[:csvDirectory]*"/"*dateString*"_MinimumRunningTime.csv"
|
csvFilePath=settings[:outputDir]*"/"*dateString*"_MinimumRunningTime.csv"
|
||||||
elseif operationMode == "minimum energy consumption"
|
elseif operationMode == "minimum energy consumption"
|
||||||
csvFilePath=settings[:csvDirectory]*"/"*dateString*"_MinimumEnergyConsumption.csv"
|
csvFilePath=settings[:outputDir]*"/"*dateString*"_MinimumEnergyConsumption.csv"
|
||||||
else
|
else
|
||||||
# should not be possible
|
# should not be possible
|
||||||
end
|
end
|
||||||
|
@ -156,20 +150,20 @@ end #function createCsvFile
|
||||||
|
|
||||||
|
|
||||||
#=
|
#=
|
||||||
function createCsvFile(movingSection::Dict, dataPointsToExport::Vector{Dict}, operationMode::String, pathName::String, trainName::String, settings::Dict)
|
function createCsvFile(movingSection::Dict, dataPointsToExport::Vector{Dict}, operationMode::String, pathName::String, trainName::String, settings::Settings)
|
||||||
detailOfOutput = settings[:detailOfOutput]
|
outputDetail = settings[:outputDetail]
|
||||||
|
|
||||||
massModel = settings[:massModel]
|
massModel = settings.massModel
|
||||||
stepVariable = settings[:stepVariable]
|
stepVariable = settings.stepVariable
|
||||||
stepSize = string(settings[:stepSize])
|
stepSize = string(settings.stepSize)
|
||||||
|
|
||||||
# create accumulated data block
|
# create accumulated data block
|
||||||
accumulatedData = Array{Any, 1}[]
|
accumulatedData = Array{Any, 1}[]
|
||||||
if detailOfOutput == "minimal"
|
if outputDetail == "minimal"
|
||||||
push!(accumulatedData, ["s (in m)", "t (in s)","E (in Ws)"]) # push header to accumulatedData
|
push!(accumulatedData, ["s (in m)", "t (in s)","E (in Ws)"]) # push header to accumulatedData
|
||||||
row = [movingSection[:length], movingSection[:t], movingSection[:E]]
|
row = [movingSection[:length], movingSection[:t], movingSection[:E]]
|
||||||
push!(accumulatedData, row) # push row to accumulatedData
|
push!(accumulatedData, row) # push row to accumulatedData
|
||||||
elseif detailOfOutput == "driving course" || detailOfOutput == "points of interest"
|
elseif outputDetail == "driving course" || outputDetail == "points of interest"
|
||||||
push!(accumulatedData, ["i", "behavior", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_wagons (in N)", "ΔW (in Ws)","W (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]) # push header to accumulatedData
|
push!(accumulatedData, ["i", "behavior", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_wagons (in N)", "ΔW (in Ws)","W (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]) # push header to accumulatedData
|
||||||
for point in dataPointsToExport
|
for point in dataPointsToExport
|
||||||
row = [point[:i], point[:behavior], point[:Δs], point[:s], point[:Δt], point[:t], point[:Δv], point[:v], point[:F_T], point[:F_R], point[:R_path], point[:R_train], point[:R_traction], point[:R_wagons], point[:ΔW], point[:W], point[:ΔE], point[:E], point[:a]]
|
row = [point[:i], point[:behavior], point[:Δs], point[:s], point[:Δt], point[:t], point[:Δv], point[:v], point[:F_T], point[:F_R], point[:R_path], point[:R_train], point[:R_traction], point[:R_wagons], point[:ΔW], point[:W], point[:ΔE], point[:E], point[:a]]
|
||||||
|
@ -194,19 +188,19 @@ function createCsvFile(movingSection::Dict, dataPointsToExport::Vector{Dict}, op
|
||||||
end
|
end
|
||||||
end # for
|
end # for
|
||||||
|
|
||||||
# combine the columns in a data frame and saving it as a CSV-file at csvDirectory
|
# combine the columns in a data frame and saving it as a CSV-file at outputDir
|
||||||
if detailOfOutput == "minimal"
|
if outputDetail == "minimal"
|
||||||
df = DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3])
|
df = DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3])
|
||||||
elseif detailOfOutput=="driving course" || detailOfOutput == "points of interest"
|
elseif outputDetail=="driving course" || outputDetail == "points of interest"
|
||||||
df = DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3], c4=allColumns[4], c5=allColumns[5], c6=allColumns[6], c7=allColumns[7], c8=allColumns[8], c9=allColumns[9], c10=allColumns[10], c11=allColumns[11], c12=allColumns[12], c13=allColumns[13], c14=allColumns[14], c15=allColumns[15], c16=allColumns[16], c17=allColumns[17], c18=allColumns[18], c19=allColumns[19])
|
df = DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3], c4=allColumns[4], c5=allColumns[5], c6=allColumns[6], c7=allColumns[7], c8=allColumns[8], c9=allColumns[9], c10=allColumns[10], c11=allColumns[11], c12=allColumns[12], c13=allColumns[13], c14=allColumns[14], c15=allColumns[15], c16=allColumns[16], c17=allColumns[17], c18=allColumns[18], c19=allColumns[19])
|
||||||
end
|
end
|
||||||
|
|
||||||
date = Dates.now()
|
date = Dates.now()
|
||||||
dateString=Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
|
dateString=Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
|
||||||
if operationMode == "minimum running time"
|
if operationMode == "minimum running time"
|
||||||
csvFilePath=settings[:csvDirectory]*"/"*dateString*"_MinimumRunningTime.csv"
|
csvFilePath=settings[:outputDir]*"/"*dateString*"_MinimumRunningTime.csv"
|
||||||
elseif operationMode == "minimum energy consumption"
|
elseif operationMode == "minimum energy consumption"
|
||||||
csvFilePath=settings[:csvDirectory]*"/"*dateString*"_MinimumEnergyConsumption.csv"
|
csvFilePath=settings[:outputDir]*"/"*dateString*"_MinimumEnergyConsumption.csv"
|
||||||
else
|
else
|
||||||
# should not be possible
|
# should not be possible
|
||||||
end
|
end
|
||||||
|
@ -216,5 +210,3 @@ function createCsvFile(movingSection::Dict, dataPointsToExport::Vector{Dict}, op
|
||||||
return true
|
return true
|
||||||
end #function createCsvFile
|
end #function createCsvFile
|
||||||
=#
|
=#
|
||||||
|
|
||||||
end #module Export
|
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
# __copyright__ = "2022"
|
# __copyright__ = "2022"
|
||||||
# __license__ = "ISC"
|
# __license__ = "ISC"
|
||||||
|
|
||||||
module Formulary
|
|
||||||
|
|
||||||
#########################
|
#########################
|
||||||
## literature the driving dynamics equations are based on:
|
## literature the driving dynamics equations are based on:
|
||||||
##
|
##
|
||||||
|
@ -21,17 +19,6 @@ module Formulary
|
||||||
## isbn = {978-3-777-10462-1},
|
## isbn = {978-3-777-10462-1},
|
||||||
## publisher = {Eurailpress DVV Media Group},
|
## publisher = {Eurailpress DVV Media Group},
|
||||||
## }
|
## }
|
||||||
## @article{Jaekel:2014,
|
|
||||||
## author = {Jaekel, Birgit and Albrecht, Thomas},
|
|
||||||
## year = {2014},
|
|
||||||
## title = {Comparative analysis of algorithms and models for train running simulation},
|
|
||||||
## journal = {Journal of Rail Transport Planning \& Management},
|
|
||||||
## doi = {10.1016/j.jrtpm.2014.06.002},
|
|
||||||
## volume = {4},
|
|
||||||
## number = {1-2},
|
|
||||||
## pages = {14--27},
|
|
||||||
## publisher = {Elsevier},
|
|
||||||
## }
|
|
||||||
## @Book{Wende:2003,
|
## @Book{Wende:2003,
|
||||||
## author = {Wende, Dietrich},
|
## author = {Wende, Dietrich},
|
||||||
## date = {2003},
|
## date = {2003},
|
||||||
|
@ -41,25 +28,10 @@ module Formulary
|
||||||
## }
|
## }
|
||||||
#########################
|
#########################
|
||||||
|
|
||||||
# export resisting forces and acceleration
|
approxLevel = 6
|
||||||
export calcTractionUnitResistance, calcWagonsResistance, calcForceFromCoefficient, calcAcceleration,
|
|
||||||
|
|
||||||
# export step sizes in different units
|
|
||||||
calc_Δs_with_Δt, calc_Δs_with_Δv,
|
|
||||||
calc_Δt_with_Δs, calc_Δt_with_Δv, calc_Δt_with_constant_v,
|
|
||||||
calc_Δv_with_Δs, calc_Δv_with_Δt,
|
|
||||||
calc_ΔW, calc_ΔE,
|
|
||||||
|
|
||||||
# export braking information
|
|
||||||
calcBrakingDistance, calcBrakingStartVelocity, calcBrakingAcceleration
|
|
||||||
|
|
||||||
v00 = 100/3.6 # velocity factor (in m/s)
|
v00 = 100/3.6 # velocity factor (in m/s)
|
||||||
g = 9.81 # acceleration due to gravity (in m/s^2) # TODO: should more digits of g be used? g=9,80665 m/s^2
|
g = 9.81 # acceleration due to gravity (in m/s^2) # TODO: should more digits of g be used? g=9,80665 m/s^2
|
||||||
|
|
||||||
approximationLevel = 6 # value for approximation to intersections TODO further explanation (e.g. approximationLevel = 3 -> with stepSize 10 m the approximation will be calculated accurate on 10 mm ; 1s -> 1 ms; 1 km/h -> 3.6 mm/s)
|
|
||||||
# TODO: necessary here?
|
|
||||||
|
|
||||||
|
|
||||||
## calculate forces
|
## calculate forces
|
||||||
|
|
||||||
#TODO: replace the ? ? ?
|
#TODO: replace the ? ? ?
|
||||||
|
@ -213,8 +185,8 @@ function calc_ΔW(F_T_prev::Real, Δs::Real)
|
||||||
end #function calc_ΔW
|
end #function calc_ΔW
|
||||||
|
|
||||||
function calc_ΔE(ΔW::Real)
|
function calc_ΔE(ΔW::Real)
|
||||||
# simplified equation is based on [Jaekel:2014, page 6]
|
# simplified equation
|
||||||
|
# TODO!
|
||||||
# ΔW: mechanical work in this step (in Ws)
|
# ΔW: mechanical work in this step (in Ws)
|
||||||
ΔE = ΔW # energy consumption in this step (in Ws)
|
ΔE = ΔW # energy consumption in this step (in Ws)
|
||||||
return ΔE
|
return ΔE
|
||||||
|
@ -228,8 +200,8 @@ function calcBrakingDistance(v_start::Real, v_end::Real, a_braking::Real)
|
||||||
# a_braking: constant braking acceleration (in m/s^2)
|
# a_braking: constant braking acceleration (in m/s^2)
|
||||||
s_braking = (v_end^2 - v_start^2) /2 /a_braking # braking distance (in m)
|
s_braking = (v_end^2 - v_start^2) /2 /a_braking # braking distance (in m)
|
||||||
# TODO: also possible: calc_Δs_with_Δv(v_end-v_start, a_braking, v_start)
|
# TODO: also possible: calc_Δs_with_Δv(v_end-v_start, a_braking, v_start)
|
||||||
# return max(0.0, ceil(s_braking, digits=approximationLevel)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
|
# return max(0.0, ceil(s_braking, digits=approxLevel)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
|
||||||
return max(0.0, ceil(s_braking, digits=approximationLevel +1)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
|
return max(0.0, ceil(s_braking, digits=approxLevel +1)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
|
||||||
end #function calcBrakingDistance
|
end #function calcBrakingDistance
|
||||||
|
|
||||||
function calcBrakingStartVelocity(v_end::Real, a_braking::Real, s_braking::Real)
|
function calcBrakingStartVelocity(v_end::Real, a_braking::Real, s_braking::Real)
|
||||||
|
@ -239,8 +211,8 @@ function calcBrakingStartVelocity(v_end::Real, a_braking::Real, s_braking::Real)
|
||||||
# a_braking: constant braking acceleration (in m/s^2)
|
# a_braking: constant braking acceleration (in m/s^2)
|
||||||
# s_braking: braking distance (in Ws)
|
# s_braking: braking distance (in Ws)
|
||||||
v_start = sqrt(v_end^2 - 2*a_braking *s_braking) # braking start velocity (in m/s)
|
v_start = sqrt(v_end^2 - 2*a_braking *s_braking) # braking start velocity (in m/s)
|
||||||
# return floor(v_start, digits=approximationLevel)
|
# return floor(v_start, digits=approxLevel)
|
||||||
return floor(v_start, digits=approximationLevel +1)
|
return floor(v_start, digits=approxLevel +1)
|
||||||
end #function calcBrakingStartVelocity
|
end #function calcBrakingStartVelocity
|
||||||
|
|
||||||
function calcBrakingAcceleration(v_start::Real, v_end::Real, s_braking::Real)
|
function calcBrakingAcceleration(v_start::Real, v_end::Real, s_braking::Real)
|
||||||
|
@ -252,5 +224,3 @@ function calcBrakingAcceleration(v_start::Real, v_end::Real, s_braking::Real)
|
||||||
a_braking = (v_end^2 - v_start^2) /2 /s_braking # constant braking acceleration (in m/s^2)
|
a_braking = (v_end^2 - v_start^2) /2 /s_braking # constant braking acceleration (in m/s^2)
|
||||||
return a_braking
|
return a_braking
|
||||||
end #function calcBrakingAcceleration
|
end #function calcBrakingAcceleration
|
||||||
|
|
||||||
end #module Formulary
|
|
||||||
|
|
|
@ -5,21 +5,14 @@
|
||||||
# __copyright__ = "2020-2022"
|
# __copyright__ = "2020-2022"
|
||||||
# __license__ = "ISC"
|
# __license__ = "ISC"
|
||||||
|
|
||||||
module Import
|
|
||||||
|
|
||||||
import YAML
|
|
||||||
|
|
||||||
export importYamlFiles, importFromYaml
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
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)
|
||||||
train = importFromYaml(:train, trainDirectory)
|
train = importFromYaml(:train, trainDirectory)
|
||||||
path = importFromYaml(:path, pathDirectory)
|
path = importFromYaml(:path, pathDirectory)
|
||||||
settings = importFromYaml(:settings, settingsDirectory)
|
|
||||||
|
|
||||||
return (train, path, settings)
|
return (train, path)
|
||||||
end #function importYamlFiles
|
end #function importYamlFiles
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -40,5 +33,3 @@ function importFromYaml(dataType::Symbol, directory::String)
|
||||||
end
|
end
|
||||||
return dictionary
|
return dictionary
|
||||||
end # function importFromYaml
|
end # function importFromYaml
|
||||||
|
|
||||||
end # module Input
|
|
||||||
|
|
|
@ -5,15 +5,11 @@
|
||||||
# __copyright__ = "2020-2022"
|
# __copyright__ = "2020-2022"
|
||||||
# __license__ = "ISC"
|
# __license__ = "ISC"
|
||||||
|
|
||||||
module Output
|
function createOutput(train::Dict, settings::Settings, path::Dict, movingSection::Dict, drivingCourse::Vector{Dict})
|
||||||
|
if settings.outputDetail == :running_time
|
||||||
export createOutput
|
|
||||||
|
|
||||||
function createOutput(train::Dict, settings::Dict, path::Dict, movingSection::Dict, drivingCourse::Vector{Dict})
|
|
||||||
if settings[:detailOfOutput] == "running time"
|
|
||||||
output = movingSection[:t] # TODO: or use drivingCourse[end][:t]
|
output = movingSection[:t] # TODO: or use drivingCourse[end][:t]
|
||||||
|
|
||||||
elseif settings[:detailOfOutput] == "points of interest"
|
elseif settings.outputDetail == :points_of_interest
|
||||||
# add points of interest
|
# add points of interest
|
||||||
if haskey(path, :pointsOfInterest)
|
if haskey(path, :pointsOfInterest)
|
||||||
output = Vector{Dict}()
|
output = Vector{Dict}()
|
||||||
|
@ -28,10 +24,10 @@ function createOutput(train::Dict, settings::Dict, path::Dict, movingSection::Di
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif settings[:detailOfOutput] == "driving course"
|
elseif settings.outputDetail == :driving_course
|
||||||
output = drivingCourse
|
output = drivingCourse
|
||||||
|
|
||||||
elseif settings[:detailOfOutput] == "everything"
|
elseif settings.outputDetail == :everything
|
||||||
output = Dict{Symbol,Any}()
|
output = Dict{Symbol,Any}()
|
||||||
merge!(output, Dict(:train => train, :path => path, :settings => settings))
|
merge!(output, Dict(:train => train, :path => path, :settings => settings))
|
||||||
|
|
||||||
|
@ -71,7 +67,7 @@ function createOutput(train::Dict, settings::Dict, path::Dict, movingSection::Di
|
||||||
end
|
end
|
||||||
|
|
||||||
#=
|
#=
|
||||||
function createOutputDict(train::Dict, settings::Dict, path::Dict, movingSection::Dict, drivingCourse::Vector{Dict})
|
function createOutputDict(train::Dict, settings::Settings, 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))
|
||||||
|
|
||||||
|
@ -108,5 +104,3 @@ function createOutputDict(train::Dict, settings::Dict, path::Dict, movingSection
|
||||||
return outputDict
|
return outputDict
|
||||||
end # function createOutputDict
|
end # function createOutputDict
|
||||||
=#
|
=#
|
||||||
|
|
||||||
end # module Output
|
|
||||||
|
|
|
@ -1,55 +1,30 @@
|
||||||
#!/usr/bin/env julia
|
#!/usr/bin/env julia
|
||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
# __julia-version__ = 1.7.2
|
# __julia-version__ = 1.7.2
|
||||||
# __author__ = "Max Kannenberg"
|
# __author__ = "Max Kannenberg, Martin Scheidt"
|
||||||
# __copyright__ = "2020-2022"
|
# __copyright__ = "2020-2022"
|
||||||
# __license__ = "ISC"
|
# __license__ = "ISC"
|
||||||
|
__precompile__(true)
|
||||||
|
|
||||||
module TrainRun
|
module TrainRun
|
||||||
|
|
||||||
# include main module TrainRunCalc
|
## loading external packages
|
||||||
include("./TrainRunCalc.jl")
|
using YAML, JSONSchema, CSV, DataFrames, Dates
|
||||||
|
|
||||||
# include additional modules
|
## include package files
|
||||||
include("./Import.jl")
|
include("types.jl")
|
||||||
include("./Export.jl")
|
include("formulary.jl")
|
||||||
|
include("characteristics.jl")
|
||||||
|
include("behavior.jl")
|
||||||
|
include("output.jl")
|
||||||
|
include("import.jl")
|
||||||
|
include("export.jl")
|
||||||
|
include("calc.jl")
|
||||||
|
|
||||||
# include additional modules that are not recommended to use in this state
|
export
|
||||||
include("./AdditionalOutput.jl")
|
## Interface
|
||||||
include("./EnergySaving.jl")
|
trainRun, Settings, exportToCsv
|
||||||
|
|
||||||
# use main module TrainRunCalc
|
|
||||||
using .TrainRunCalc
|
|
||||||
|
|
||||||
# use additional modules
|
|
||||||
using .Import
|
|
||||||
using .Export
|
|
||||||
|
|
||||||
# use additional modules that are not recommended to use in this state
|
|
||||||
using .AdditionalOutput
|
|
||||||
using .EnergySaving
|
|
||||||
|
|
||||||
# main function
|
|
||||||
export trainRun,
|
|
||||||
|
|
||||||
# import functions
|
|
||||||
importYamlFiles, importFromYaml,
|
|
||||||
|
|
||||||
# functions for saving energy that are not recommended to use in this state
|
|
||||||
addOperationModeEnergySaving!,
|
|
||||||
|
|
||||||
# export functions
|
|
||||||
exportToCsv,
|
|
||||||
|
|
||||||
# functions for visualising results that are not recommended to use in this state
|
|
||||||
plotResults, plotDrivingCourse, printImportantValues, printSectionInformation
|
|
||||||
|
|
||||||
# approximationLevel = 6 # value for approximation to intersections
|
|
||||||
# TODO: define it here and give it to each function? (Behavior, EnergySaving, ..)
|
|
||||||
|
|
||||||
"""
|
|
||||||
TODO: Package description
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
## main functions
|
||||||
|
|
||||||
end # module TrainRun
|
end # module TrainRun
|
||||||
|
|
|
@ -1,31 +1,120 @@
|
||||||
#!/usr/bin/env julia
|
#!/usr/bin/env julia
|
||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
# __julia-version__ = 1.7.2
|
# __julia-version__ = 1.7.2
|
||||||
# __author__ = "Max Kannenberg"
|
# __author__ = "Max Kannenberg, Martin Scheidt"
|
||||||
# __copyright__ = "2022"
|
# __copyright__ = "2022"
|
||||||
# __license__ = "ISC"
|
# __license__ = "ISC"
|
||||||
|
|
||||||
# TODO: 2022-04-07: if EnergySaving should be used. The train type has do be defined and checked
|
"""
|
||||||
module Validate
|
Settings(file)
|
||||||
|
|
||||||
export checkAndSetInput!
|
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
|
||||||
|
|
||||||
approximationLevel = 6 # value for approximation to intersections TODO further explanation
|
massModel::Symbol # model type of train mass ":mass_point" or ":homogeneous_strip".
|
||||||
|
stepVariable::Symbol # variable of the linear multistep method: ":distance", ":time" or ":velocity".
|
||||||
|
stepSize::Real # step size, unit depends on stepVariable - :distance in meter, time in seconds and velocity in meter/second.
|
||||||
|
approxLevel::Int # value for approximation; used when rounding or interating.
|
||||||
|
outputDetail::Symbol # single Float() ":running_time", Array() of ":points_of_interest",
|
||||||
|
# complete Array() ":driving_course", or Dict() ":everything".
|
||||||
|
outputFormat::Symbol # output as ":julia_dict" or as ":csv".
|
||||||
|
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 = "."
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
"""
|
"""
|
||||||
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 checkAndSetInput!(train::Dict, path::Dict, settings::Dict)
|
function checkAndSetInput!(train::Dict, path::Dict, settings::Settings)
|
||||||
checkAndSetTrain!(train)
|
checkAndSetTrain!(train)
|
||||||
checkAndSetPath!(path)
|
checkAndSetPath!(path)
|
||||||
checkAndSetSettings!(settings)
|
|
||||||
|
|
||||||
if settings[:detailOfOutput] == "points of interest" && !haskey(path, :pointsOfInterest)
|
if settings.outputDetail == :points_of_interest && !haskey(path, :pointsOfInterest)
|
||||||
settings[:detailOfOutput] = "driving course"
|
throw(DomainError(settings.outputDetail, "INFO at checking the input for settings and path:\n
|
||||||
println("INFO at checking the input for settings and path: settings[:detailOfOutput] is 'points of interest' but the path does not have a list for pointsOfInterest. Therefore the detailOfOut is changed to 'driving course'.")
|
settings[:outputDetail] is 'points of interest' but the path does not for pointsOfInterest."))
|
||||||
end
|
end
|
||||||
return (train, path, settings)
|
return (train, path)
|
||||||
end #function checkAndSetInput!
|
end #function checkAndSetInput!
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -102,39 +191,6 @@ function checkAndSetPath!(path::Dict)
|
||||||
return path
|
return path
|
||||||
end # function checkAndSetPath!
|
end # function checkAndSetPath!
|
||||||
|
|
||||||
|
|
||||||
## settings for the calculation
|
|
||||||
function checkAndSetSettings!(settings::Dict)
|
|
||||||
# check settings information from input dictionary
|
|
||||||
|
|
||||||
checkAndSetString!(settings, "settings", :massModel, "mass point", ["mass point", "homogeneous strip"]) # model type of the train's mass "mass point" or "homogeneous strip"
|
|
||||||
checkAndSetString!(settings, "settings", :stepVariable, "s in m", ["s in m", "t in s", "v in m/s"]) # step variable of the step method "s in m", "t in s" or "v in m/s"
|
|
||||||
|
|
||||||
checkAndSetPositiveNumber!(settings, "settings", :stepSize, "("*settings[:stepVariable]*")", getDefaultStepSize(settings[:stepVariable])) # step size (unit depends on stepVariable: s in m, t in s and v in m/s)
|
|
||||||
checkAndSetBool!(settings, "settings", :operationModeMinimumRunningTime, true) # operation mode "minimum running time"
|
|
||||||
checkAndSetBool!(settings, "settings", :operationModeMinimumEnergyConsumption, false) # operation mode "minimum energy consumption"
|
|
||||||
checkAndSetString!(settings, "settings", :typeOfOutput, "julia dictionary", ["julia dictionary", "CSV"]) # output as "julia dictionary" or as "CSV"
|
|
||||||
|
|
||||||
if settings[:typeOfOutput] == "CSV"
|
|
||||||
checkAndSetString!(settings, "settings", :csvDirectory, "~/Desktop/TrainRun")
|
|
||||||
# TODO use correct default directory
|
|
||||||
# TODO: it could be checked if the path is existing on the pc
|
|
||||||
end # if
|
|
||||||
|
|
||||||
checkAndSetString!(settings, "settings", :detailOfOutput, "running time", ["running time", "points of interest", "driving course", "everything"]) # should the output be only the value of the "running time", or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
|
|
||||||
|
|
||||||
# inform the user about keys of the input dictionary that are not used in this tool
|
|
||||||
usedKeys = [:massModel, :stepVariable, :stepSize,
|
|
||||||
:operationModeMinimumRunningTime, :operationModeMinimumEnergyConsumption,
|
|
||||||
:typeOfOutput, :detailOfOutput]
|
|
||||||
if settings[:typeOfOutput] == "CSV"
|
|
||||||
push!(usedKeys, :csvDirectory)
|
|
||||||
end
|
|
||||||
informAboutUnusedKeys(collect(keys(settings)), usedKeys::Vector{Symbol}, "settings")
|
|
||||||
|
|
||||||
return settings
|
|
||||||
end # function checkAndSetSettings!
|
|
||||||
|
|
||||||
function checkAndSetBool!(dictionary::Dict, dictionaryType::String, key::Symbol, defaultValue::Bool)
|
function checkAndSetBool!(dictionary::Dict, dictionaryType::String, key::Symbol, defaultValue::Bool)
|
||||||
if haskey(dictionary,key) && dictionary[key]!=nothing
|
if haskey(dictionary,key) && dictionary[key]!=nothing
|
||||||
if typeof(dictionary[key]) != Bool
|
if typeof(dictionary[key]) != Bool
|
||||||
|
@ -186,7 +242,7 @@ function checkAndSetPositiveNumberWithDifferentNames!(dictionary::Dict, dictiona
|
||||||
|
|
||||||
if mainKey_temp >= 0.0 && alternativeKey_temp >= 0.0
|
if mainKey_temp >= 0.0 && alternativeKey_temp >= 0.0
|
||||||
difference = abs(mainKey_temp - alternativeKey_temp)
|
difference = abs(mainKey_temp - alternativeKey_temp)
|
||||||
if difference > 1/(10^approximationLevel) # TODO or use difference > 0.0 ?
|
if difference > 1/(10^approxLevel) # TODO or use difference > 0.0 ?
|
||||||
delete!(dictionary, alternativeKey)
|
delete!(dictionary, alternativeKey)
|
||||||
println("WARNING at checking the input for the ",dictionaryType,": The values of ",mainKey," and ",alternativeKey," differ by ",difference," ",unit,". The value ",String(mainKey),"=",default," ",unit," is used." )
|
println("WARNING at checking the input for the ",dictionaryType,": The values of ",mainKey," and ",alternativeKey," differ by ",difference," ",unit,". The value ",String(mainKey),"=",default," ",unit," is used." )
|
||||||
end
|
end
|
||||||
|
@ -226,7 +282,7 @@ function checkAndSetPositiveNumberWithDifferentNames!(dictionary::Dict, dictiona
|
||||||
|
|
||||||
if mainKey_temp >= 0.0 && alternativeKey_temp >= 0.0
|
if mainKey_temp >= 0.0 && alternativeKey_temp >= 0.0
|
||||||
difference = abs(mainKey_temp - alternativeKey_temp)
|
difference = abs(mainKey_temp - alternativeKey_temp)
|
||||||
if difference > 1/(10^approximationLevel) # TODO or use difference > 0.0 ?
|
if difference > 1/(10^approxLevel) # TODO or use difference > 0.0 ?
|
||||||
delete!(dictionary, alternativeKey)
|
delete!(dictionary, alternativeKey)
|
||||||
println("WARNING at checking the input for the ",dictionaryType,": The values of ",mainKey," and ",alternativeKey," differ by ",difference," ",unit,". The value ",String(mainKey),"=",default," ",unit," is used." )
|
println("WARNING at checking the input for the ",dictionaryType,": The values of ",mainKey," and ",alternativeKey," differ by ",difference," ",unit,". The value ",String(mainKey),"=",default," ",unit," is used." )
|
||||||
end
|
end
|
||||||
|
@ -261,7 +317,7 @@ function checkAndSetSum!(dictionary::Dict, dictionaryType::String, sum::Symbol,
|
||||||
if haskey(dictionary,sum) && dictionary[sum]!=nothing
|
if haskey(dictionary,sum) && dictionary[sum]!=nothing
|
||||||
if typeof(dictionary[sum]) <: Real && dictionary[sum] >= 0.0
|
if typeof(dictionary[sum]) <: Real && dictionary[sum] >= 0.0
|
||||||
difference = abs(dictionary[sum] - (dictionary[summand1]+dictionary[summand2]))
|
difference = abs(dictionary[sum] - (dictionary[summand1]+dictionary[summand2]))
|
||||||
if difference > 1/(10^approximationLevel)
|
if difference > 1/(10^approxLevel)
|
||||||
error("ERROR at checking the input for the ",dictionaryType,": The value of ",String(sum)," is not exactly the sum of ",String(summand1)," and ",String(summand2),". It differs by ",difference,".")
|
error("ERROR at checking the input for the ",dictionaryType,": The value of ",String(sum)," is not exactly the sum of ",String(summand1)," and ",String(summand2),". It differs by ",difference,".")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
@ -332,7 +388,7 @@ function checkAndSetSpeedLimit!(train::Dict)
|
||||||
|
|
||||||
if v_limit_temp > 0.0 && v_limit_kmh_temp > 0.0
|
if v_limit_temp > 0.0 && v_limit_kmh_temp > 0.0
|
||||||
difference = abs(v_limit_temp - v_limit_kmh_temp/3.6)
|
difference = abs(v_limit_temp - v_limit_kmh_temp/3.6)
|
||||||
if difference > 1/(10^approximationLevel) # TODO or use difference > 0.0 ?
|
if difference > 1/(10^approxLevel) # TODO or use difference > 0.0 ?
|
||||||
delete!(train, :v_limit_kmh)
|
delete!(train, :v_limit_kmh)
|
||||||
println("WARNING at checking the input for the train: The values of v_limit and v_limit_kmh differ by ",difference," m/s. The value v_limit=",v_limit_temp," m/s is used." )
|
println("WARNING at checking the input for the train: The values of v_limit and v_limit_kmh differ by ",difference," m/s. The value v_limit=",v_limit_temp," m/s is used." )
|
||||||
end
|
end
|
||||||
|
@ -388,7 +444,7 @@ function checkAndSetRotationMassFactors!(train::Dict)
|
||||||
if haskey(train, :ξ_t) && train[:ξ_t]!=nothing && train[:ξ_t]>0.0 && (train[:m_w]==0.0 || (haskey(train, :ξ_w) && train[:ξ_w]!=nothing))
|
if haskey(train, :ξ_t) && train[:ξ_t]!=nothing && train[:ξ_t]>0.0 && (train[:m_w]==0.0 || (haskey(train, :ξ_w) && train[:ξ_w]!=nothing))
|
||||||
# TODO: is && train[:ξ_t]>0.0 necessary here?
|
# TODO: is && train[:ξ_t]>0.0 necessary here?
|
||||||
difference = abs(train[:ξ_train] - (train[:ξ_t]*train[:m_t] + train[:ξ_w]*train[:m_w])/train[:m_train])
|
difference = abs(train[:ξ_train] - (train[:ξ_t]*train[:m_t] + train[:ξ_w]*train[:m_w])/train[:m_train])
|
||||||
if difference > 1/(10^approximationLevel)
|
if difference > 1/(10^approxLevel)
|
||||||
error("ERROR at checking the input for the train: The value of ξ_train is not exactly ξ_train=(ξ_t*m_t + ξ_w*m_w)/m_train. It differs by ",difference,".")
|
error("ERROR at checking the input for the train: The value of ξ_train is not exactly ξ_train=(ξ_t*m_t + ξ_w*m_w)/m_train. It differs by ",difference,".")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -717,18 +773,6 @@ function checkAndSetPOIs!(path::Dict)
|
||||||
return path
|
return path
|
||||||
end #function checkAndSetPOIs!
|
end #function checkAndSetPOIs!
|
||||||
|
|
||||||
function getDefaultStepSize(stepVariable::String)
|
|
||||||
if stepVariable == "s in m"
|
|
||||||
return 10.0
|
|
||||||
elseif stepVariable == "t in s"
|
|
||||||
return 3.0
|
|
||||||
elseif stepVariable == "v in m/s"
|
|
||||||
return 0.1
|
|
||||||
#else
|
|
||||||
# error("ERROR at getting a default step size. The step variable ",stepVariable," can not be used.")
|
|
||||||
end
|
|
||||||
end #function getDefaultStepSize
|
|
||||||
|
|
||||||
#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
|
||||||
function informAboutUnusedKeys(allKeys::AbstractVector, usedKeys::Vector{Symbol}, dictionaryType::String) # inform the user which Symbols of the input dictionary are not used in this tool
|
function informAboutUnusedKeys(allKeys::AbstractVector, usedKeys::Vector{Symbol}, dictionaryType::String) # inform the user which Symbols of the input dictionary are not used in this tool
|
||||||
unusedKeys = []
|
unusedKeys = []
|
||||||
|
@ -753,5 +797,3 @@ function informAboutUnusedKeys(allKeys::AbstractVector, usedKeys::Vector{Symbol}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end #function informAboutUnusedKeys
|
end #function informAboutUnusedKeys
|
||||||
|
|
||||||
end # module Validate
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
settings:
|
||||||
|
outputFormat: "csv" # output as "julia_dict" or as "csv"
|
||||||
|
outputDir: "." # used if other outputFormat than "julia dict"
|
|
@ -0,0 +1,9 @@
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
settings:
|
||||||
|
# default settings for the calculation
|
||||||
|
stepSize: 5 # step size, unit depends on stepVariable - distance in meter, time in seconds and velocity in meter/second.
|
||||||
|
approxLevel: 6 # value for approximation; used when rounding or interating
|
||||||
|
outputDetail: "running_time" # single value "running_time", array of "points_of_interest",complete array "driving_course", or dict() "everything"
|
||||||
|
outputFormat: "julia_dict" # output as "julia_dict" or as "csv"
|
||||||
|
outputDir: "." # used if other outputFormat than "julia dict"
|
|
@ -0,0 +1,4 @@
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
settings:
|
||||||
|
outputDetail: "driving_course" # single value "running_time", array of "points_of_interest",complete array "driving_course", or dict() "everything"
|
|
@ -0,0 +1,4 @@
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
settings:
|
||||||
|
massModel: "homogeneous_strip" # type of train model used: "mass_point" or "homogeneous_strip"
|
|
@ -0,0 +1,4 @@
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
settings:
|
||||||
|
stepVariable: "time" # variable of the linear multistep method: "distance", "time" or "velocity"
|
|
@ -0,0 +1,5 @@
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
settings:
|
||||||
|
stepVariable: "time" # variable of the linear multistep method: "distance", "time" or "velocity"
|
||||||
|
massModel: "homogeneous_strip" # type of train model used: "mass_point" or "homogeneous_strip"
|
|
@ -0,0 +1,5 @@
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
settings:
|
||||||
|
stepVariable: "velocity" # variable of the linear multistep method: "distance", "time" or "velocity"
|
||||||
|
stepSize: 0.1 # step size, unit depends on stepVariable - position in meter, time in seconds and velocity in meter/second
|
|
@ -1,40 +1,69 @@
|
||||||
#!/usr/bin/env julia
|
#!/usr/bin/env julia
|
||||||
# -*- coding: UTF-8 -*-
|
# -*- coding: UTF-8 -*-
|
||||||
# __julia-version__ = 1.7.0
|
# __julia-version__ = 1.7.0
|
||||||
# __author__ = "Max Kannenberg"
|
# __author__ = "Max Kannenberg, Martin Scheidt"
|
||||||
# __copyright__ = "2021"
|
# __copyright__ = "2021"
|
||||||
# __license__ = "ISC"
|
# __license__ = "ISC"
|
||||||
|
|
||||||
using TrainRun, Test
|
using TrainRun, Test
|
||||||
|
|
||||||
allPaths=[]
|
paths=Dict()
|
||||||
push!(allPaths, importYamlFile(:path, "data/paths/path_1_10km_nConst_vConst.yaml"))
|
push!(paths, "const" => TrainRun.importFromYaml(:path, "test/data/paths/const.yaml"))
|
||||||
push!(allPaths, importYamlFile(:path, "data/paths/path_2_10km_nVar_vConst.yaml"))
|
push!(paths, "slope" => TrainRun.importFromYaml(:path, "test/data/paths/slope.yaml"))
|
||||||
push!(allPaths, importYamlFile(:path, "data/paths/path_3_10km_nConst_vVar.yaml"))
|
push!(paths, "speed" => TrainRun.importFromYaml(:path, "test/data/paths/speed.yaml"))
|
||||||
push!(allPaths, importYamlFile(:path, "data/paths/path_4_real_Germany_EastSaxony_DG-DN.yaml"))
|
push!(paths, "realworld" => TrainRun.importFromYaml(:path, "test/data/paths/realworld.yaml"))
|
||||||
|
|
||||||
|
settings=Dict()
|
||||||
|
push!(settings, "default" => Settings())
|
||||||
|
push!(settings, "detail" => Settings("test/data/settings/detail.yaml"))
|
||||||
|
push!(settings, "driving_course" => Settings("test/data/settings/driving_course.yaml"))
|
||||||
|
push!(settings, "strip" => Settings("test/data/settings/strip.yaml"))
|
||||||
|
push!(settings, "time" => Settings("test/data/settings/time.yaml"))
|
||||||
|
push!(settings, "time_strip" => Settings("test/data/settings/time_strip.yaml"))
|
||||||
|
push!(settings, "velocity" => Settings("test/data/settings/velocity.yaml"))
|
||||||
|
push!(settings, "csv_export" => Settings("test/data/settings/csv_export.yaml"))
|
||||||
|
|
||||||
allSettings=[]
|
trains=Dict()
|
||||||
push!(allSettings, importYamlFile(:settings, "data/settings.yaml"))
|
push!(trains, TrainRun.importFromYaml(:train, "test/data/trains/freight.yaml"))
|
||||||
|
push!(trains, TrainRun.importFromYaml(:train, "test/data/trains/local.yaml"))
|
||||||
|
push!(trains, TrainRun.importFromYaml(:train, "test/data/trains/longdistance.yaml"))
|
||||||
|
|
||||||
allTrains=[]
|
@testset "TrainRun.jl" begin
|
||||||
push!(allTrains, importYamlFile(:train, "data/trains/train_freight_V90withOreConsist.yaml"))
|
|
||||||
push!(allTrains, importYamlFile(:train, "data/trains/train_passenger_SiemensDesiroClassic.yaml"))
|
|
||||||
push!(allTrains, importYamlFile(:train, "data/trains/train_passenger_IC2.yaml"))
|
|
||||||
|
|
||||||
for path in allPaths
|
@testset "Default settings" begin
|
||||||
for train in allTrains
|
|
||||||
for settings in allSettings
|
@test typeof(Settings()) == Settings
|
||||||
testDict=trainRun(train, path, settings)
|
|
||||||
exportToCsv(testDict)
|
@testset "const path" begin
|
||||||
sleep(2)
|
|
||||||
|
path = TrainRun.importFromYaml(:path, "test/data/paths/const.yaml")
|
||||||
|
@test typeof(path) == Dict{Any,Any}
|
||||||
|
|
||||||
|
@testset "freight train - const path" begin
|
||||||
|
train = TrainRun.importFromYaml(:train, "test/data/trains/freight.yaml")
|
||||||
|
data = trainRun(train, path)
|
||||||
|
expected = 727.796900196972
|
||||||
|
# compare result to test data set
|
||||||
|
@test isapprox(data, expected, atol=0.01)
|
||||||
|
end
|
||||||
|
|
||||||
|
@testset "local train - const path" begin
|
||||||
|
train = TrainRun.importFromYaml(:train, "test/data/trains/local.yaml")
|
||||||
|
data = trainRun(train, path)
|
||||||
|
expected = 392.723361763612
|
||||||
|
# compare result to test data set
|
||||||
|
@test isapprox(data, expected, atol=0.01)
|
||||||
|
end
|
||||||
|
|
||||||
|
@testset "long distance train - const path" begin
|
||||||
|
train = TrainRun.importFromYaml(:train, "test/data/trains/longdistance.yaml")
|
||||||
|
data = trainRun(train, path)
|
||||||
|
expected = 328.83487704779117
|
||||||
|
# compare result to test data set
|
||||||
|
@test isapprox(data, expected, atol=0.01)
|
||||||
|
end
|
||||||
|
|
||||||
# TODO:
|
|
||||||
# compare result to test data set
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
println("test finished")
|
end
|
||||||
# TODO:
|
|
||||||
# print test results
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
#!/usr/bin/env julia
|
|
||||||
# -*- coding: UTF-8 -*-
|
|
||||||
# __julia-version__ = 1.7.0
|
|
||||||
# __author__ = "Martin Scheidt"
|
|
||||||
# __copyright__ = "2021"
|
|
||||||
# __license__ = "ISC"
|
|
||||||
|
|
||||||
include("../src/types.jl")
|
|
||||||
include("../src/Validate.jl")
|
|
||||||
|
|
||||||
using .Input
|
|
||||||
using YAML, Test
|
|
||||||
|
|
||||||
@enum trainType passenger=1 freight=2 motorCoachTrain=3
|
|
||||||
|
|
||||||
@test Input.getEnum("passenger", trainType) == passenger::trainType
|
|
||||||
@test Input.getEnum("freight", trainType) == freight::trainType
|
|
||||||
@test Input.getEnum("motorCoachTrain", trainType) == motorCoachTrain::trainType
|
|
||||||
|
|
||||||
data = YAML.load(open("data/trains/train_passenger_IC2.yaml"))
|
|
||||||
@test Input.getEnum(data["train"]["trainType"], trainType) == passenger::trainType
|
|
||||||
|
|
||||||
data = YAML.load(open("data/trains/train_freight_V90withOreConsist.yaml"))
|
|
||||||
@test Input.getEnum(data["train"]["trainType"], trainType) == freight::trainType
|
|
Loading…
Reference in New Issue