commit
6f3a391ab0
|
@ -0,0 +1,51 @@
|
||||||
|
# Files generated by invoking Julia with --code-coverage
|
||||||
|
*.jl.cov
|
||||||
|
*.jl.*.cov
|
||||||
|
|
||||||
|
# Files generated by invoking Julia with --track-allocation
|
||||||
|
*.jl.mem
|
||||||
|
|
||||||
|
# System-specific files and directories generated by the BinaryProvider and BinDeps packages
|
||||||
|
# They contain absolute paths specific to the host computer, and so should not be committed
|
||||||
|
deps/deps.jl
|
||||||
|
deps/build.log
|
||||||
|
deps/downloads/
|
||||||
|
deps/usr/
|
||||||
|
deps/src/
|
||||||
|
|
||||||
|
# Build artifacts for creating documentation generated by the Documenter package
|
||||||
|
docs/build/
|
||||||
|
docs/site/
|
||||||
|
|
||||||
|
# File generated by Pkg, the package manager, based on a corresponding Project.toml
|
||||||
|
# It records a fixed state of all packages used by the project. As such, it should not be
|
||||||
|
# committed for packages, but should be committed for applications that require a static
|
||||||
|
# environment.
|
||||||
|
Manifest.toml
|
||||||
|
|
||||||
|
# General
|
||||||
|
.DS_Store
|
||||||
|
.AppleDouble
|
||||||
|
.LSOverride
|
||||||
|
|
||||||
|
# Icon must end with two \r
|
||||||
|
Icon
|
||||||
|
|
||||||
|
# Thumbnails
|
||||||
|
._*
|
||||||
|
|
||||||
|
# Files that might appear in the root of a volume
|
||||||
|
.DocumentRevisions-V100
|
||||||
|
.fseventsd
|
||||||
|
.Spotlight-V100
|
||||||
|
.TemporaryItems
|
||||||
|
.Trashes
|
||||||
|
.VolumeIcon.icns
|
||||||
|
.com.apple.timemachine.donotpresent
|
||||||
|
|
||||||
|
# Directories potentially created on remote AFP share
|
||||||
|
.AppleDB
|
||||||
|
.AppleDesktop
|
||||||
|
Network Trash Folder
|
||||||
|
Temporary Items
|
||||||
|
.apdisk
|
|
@ -0,0 +1,15 @@
|
||||||
|
ISC License (ISC)
|
||||||
|
|
||||||
|
Copyright 2021 Max Kannenberg
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||||
|
with or without fee is hereby granted, provided that the above copyright notice
|
||||||
|
and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||||
|
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||||
|
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
THIS SOFTWARE.
|
|
@ -0,0 +1,12 @@
|
||||||
|
name = "RailwayDrivingDynamics"
|
||||||
|
uuid = "e4541106-d44c-4e00-b50b-ecdf479fcf92"
|
||||||
|
authors = ["Max Kannenberg"]
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[deps]
|
||||||
|
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
|
||||||
|
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
|
||||||
|
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
|
||||||
|
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
|
||||||
|
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
||||||
|
YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"
|
|
@ -0,0 +1,48 @@
|
||||||
|
# RailwayDrivingDynamics
|
||||||
|
|
||||||
|
------------
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
|
||||||
|
The required julia packages are
|
||||||
|
- YAML.jl
|
||||||
|
- Dates.jl
|
||||||
|
- DataFrames.jl
|
||||||
|
- CSV.jl
|
||||||
|
- Plots.jl
|
||||||
|
|
||||||
|
Review the settings.yaml file for your appropriate settings.
|
||||||
|
|
||||||
|
------------
|
||||||
|
|
||||||
|
# Minimal working example
|
||||||
|
|
||||||
|
See folder examples.
|
||||||
|
|
||||||
|
------------
|
||||||
|
|
||||||
|
# History
|
||||||
|
|
||||||
|
## Version 0.1
|
||||||
|
|
||||||
|
Proof of concept and master thesis submission.
|
||||||
|
|
||||||
|
------------
|
||||||
|
|
||||||
|
# Acknowledgement
|
||||||
|
|
||||||
|
This work was supervides by South Westphalia University of Applied Sciences and Technical University Braunschweig.
|
||||||
|
|
||||||
|
------------
|
||||||
|
|
||||||
|
# License
|
||||||
|
|
||||||
|
[![Open Source Initiative Approved License logo](https://opensource.org/files/OSIApproved_100X125.png "Open Source Initiative Approved License logo")](https://opensource.org)
|
||||||
|
|
||||||
|
ISC License (ISC)
|
||||||
|
|
||||||
|
Copyright 2021 Max Kannenberg
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
path:
|
||||||
|
name: "10 km, no gradient, 160 km/h"
|
||||||
|
sectionStarts: # with path speed limt (in m/s)
|
||||||
|
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, n in ‰]
|
||||||
|
- [0, 160, 0]
|
||||||
|
- [10000, 160, 0]
|
|
@ -0,0 +1,17 @@
|
||||||
|
---
|
||||||
|
path:
|
||||||
|
name: "10 km, different gradient, 160 km/h"
|
||||||
|
sectionStarts: # with path speed limt (in m/s)
|
||||||
|
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, n in ‰]
|
||||||
|
- [0, 160, 0]
|
||||||
|
- [1000, 160, 1]
|
||||||
|
- [2000, 160, 2]
|
||||||
|
- [3000, 160, 5]
|
||||||
|
- [4000, 160, -3]
|
||||||
|
- [5000, 160, 5]
|
||||||
|
- [6000, 160, -10]
|
||||||
|
- [7000, 160, 15]
|
||||||
|
- [8000, 160, -10]
|
||||||
|
- [8500, 160, 20]
|
||||||
|
- [9000, 160, 0]
|
||||||
|
- [10000, 160, 0]
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
path:
|
||||||
|
name: "10 km, no gradient, different speed limits"
|
||||||
|
sectionStarts: # with path speed limt (in m/s)
|
||||||
|
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, n in ‰]
|
||||||
|
- [0, 160, 0.0]
|
||||||
|
- [3000, 60, 0.0]
|
||||||
|
- [4000, 160, 0.0]
|
||||||
|
- [5000, 60, 0.0]
|
||||||
|
- [6000, 160, 0.0]
|
||||||
|
- [6500, 60, 0.0]
|
||||||
|
- [6700, 65, 0.0]
|
||||||
|
- [6800, 70, 0.0]
|
||||||
|
- [7000, 120.00, 0]
|
||||||
|
- [10000, 160.00, 0.0]
|
|
@ -0,0 +1,354 @@
|
||||||
|
---
|
||||||
|
path:
|
||||||
|
name: "'infra_Ostsachsen': track id='tr_80.6212_2' name='DG-DN' -> spp_5"
|
||||||
|
# source: https://www.railml.org/en/user/exampledata.html -> "Real world railway examples from professional tools" -> "East Saxony railway network by FBS" -> "Ostsachsen_V220.railml" -> 'infra_Ostsachsen': track id='tr_80.6212_2' name='DG-DN' -> spp_5
|
||||||
|
sectionStarts: # with path speed limt (in m/s)
|
||||||
|
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, n in ‰]
|
||||||
|
- [0.0, 40, 0]
|
||||||
|
- [318.0, 40, 2]
|
||||||
|
- [399.0, 40, -3]
|
||||||
|
- [500.0, 40, 0]
|
||||||
|
- [579.0, 40, 1]
|
||||||
|
- [784.0, 40, 5.3]
|
||||||
|
- [868.0, 40, 20]
|
||||||
|
- [1082.0, 40, 16.1]
|
||||||
|
- [1287.0, 40, 18.1]
|
||||||
|
- [1800.0, 110, 18.1]
|
||||||
|
- [2242.0, 110, 15.4]
|
||||||
|
- [3295.0, 110, 11]
|
||||||
|
- [3880.0, 110, 11.1]
|
||||||
|
- [4680.0, 45, 11.1]
|
||||||
|
- [4686.0, 90, 11.1]
|
||||||
|
- [6122.0, 90, 0]
|
||||||
|
- [6487.0, 90, 1.5]
|
||||||
|
- [6588.0, 70, 1.5]
|
||||||
|
- [6589.0, 70, 2.4]
|
||||||
|
- [6608.0, 130, 2.4]
|
||||||
|
- [6723.0, 150, 1.3]
|
||||||
|
- [6928.0, 160, 1.3]
|
||||||
|
- [7030.0, 160, 7.5]
|
||||||
|
- [7300.0, 160, 8]
|
||||||
|
- [7552.0, 160, 5]
|
||||||
|
- [7675.0, 160, 6.7]
|
||||||
|
- [7800.0, 160, 7.4]
|
||||||
|
- [7920.0, 160, 7]
|
||||||
|
- [8020.0, 140, 7]
|
||||||
|
- [8100.0, 140, 6.3]
|
||||||
|
- [8168.0, 140, 7.4]
|
||||||
|
- [8226.0, 140, 8.4]
|
||||||
|
- [8300.0, 140, 7.4]
|
||||||
|
- [8381.0, 150, 7.4]
|
||||||
|
- [8600.0, 150, 7.8]
|
||||||
|
- [8900.0, 150, 6.7]
|
||||||
|
- [9100.0, 150, 7.8]
|
||||||
|
- [9600.0, 150, 8]
|
||||||
|
- [9845.0, 150, 7.3]
|
||||||
|
- [10005.0, 160, 7.3]
|
||||||
|
- [10600.0, 160, 6]
|
||||||
|
- [10748.0, 160, 7.3]
|
||||||
|
- [11100.0, 160, 4.5]
|
||||||
|
- [11280.0, 160, 3.6]
|
||||||
|
- [11450.0, 160, 7.2]
|
||||||
|
- [11800.0, 160, 6.8]
|
||||||
|
- [12100.0, 160, 7.3]
|
||||||
|
- [12590.0, 160, 7.6]
|
||||||
|
- [13100.0, 160, 7.3]
|
||||||
|
- [13500.0, 160, 7.1]
|
||||||
|
- [13800.0, 160, 7.3]
|
||||||
|
- [14138.0, 150, 7.3]
|
||||||
|
- [14330.0, 150, 0.3]
|
||||||
|
- [14640.0, 150, -1.8]
|
||||||
|
- [14764.0, 160, -2.8]
|
||||||
|
- [15000.0, 160, -3.3]
|
||||||
|
- [15500.0, 160, -0.9]
|
||||||
|
- [16000.0, 160, 0]
|
||||||
|
- [16470.0, 160, 1.2]
|
||||||
|
- [16572.0, 160, 2.2]
|
||||||
|
- [16700.0, 160, 3.8]
|
||||||
|
- [16949.0, 160, 3.5]
|
||||||
|
- [17086.0, 160, 3.2]
|
||||||
|
- [17232.0, 160, 1.3]
|
||||||
|
- [17339.0, 160, 4.5]
|
||||||
|
- [17406.0, 160, 3.4]
|
||||||
|
- [17727.0, 150, 3.4]
|
||||||
|
- [17807.0, 150, 4.6]
|
||||||
|
- [18049.0, 150, 3]
|
||||||
|
- [18210.0, 140, 3]
|
||||||
|
- [18300.0, 140, 4.6]
|
||||||
|
- [18680.0, 140, 3.2]
|
||||||
|
- [18761.0, 150, 3.2]
|
||||||
|
- [19047.0, 150, 5.1]
|
||||||
|
- [19305.0, 150, 3]
|
||||||
|
- [19406.0, 160, 3]
|
||||||
|
- [19414.0, 160, -0.3]
|
||||||
|
- [19900.0, 160, 3]
|
||||||
|
- [20150.0, 160, 1.8]
|
||||||
|
- [20470.0, 160, -4]
|
||||||
|
- [20940.0, 160, -3.6]
|
||||||
|
- [21150.0, 160, -1.5]
|
||||||
|
- [21390.0, 160, 0]
|
||||||
|
- [21702.0, 160, 1.5]
|
||||||
|
- [22188.0, 150, 1.5]
|
||||||
|
- [22294.0, 150, 1.8]
|
||||||
|
- [22383.0, 160, 1.8]
|
||||||
|
- [22500.0, 160, 2.6]
|
||||||
|
- [22900.0, 160, 4.6]
|
||||||
|
- [23542.0, 160, 0.2]
|
||||||
|
- [23736.0, 160, 0.9]
|
||||||
|
- [24124.0, 160, 7]
|
||||||
|
- [24918.0, 160, 7.6]
|
||||||
|
- [25100.0, 150, 7.6]
|
||||||
|
- [25100.0, 150, 7.1]
|
||||||
|
- [25580.0, 150, 7.4]
|
||||||
|
- [25708.0, 160, 7.4]
|
||||||
|
- [25810.0, 160, 7.1]
|
||||||
|
- [26040.0, 160, 3.2]
|
||||||
|
- [26330.0, 160, 1.8]
|
||||||
|
- [26593.0, 160, 2.1]
|
||||||
|
- [27020.0, 160, 3.5]
|
||||||
|
- [27195.0, 160, 5.8]
|
||||||
|
- [27253.0, 160, 1.1]
|
||||||
|
- [27310.0, 160, 3.5]
|
||||||
|
- [27595.0, 160, 3.4]
|
||||||
|
- [28530.0, 160, 4.6]
|
||||||
|
- [29115.0, 160, 0]
|
||||||
|
- [29700.0, 160, -5.2]
|
||||||
|
- [30055.0, 120, -4.3]
|
||||||
|
- [30301.0, 120, -6.2]
|
||||||
|
- [30487.0, 160, -6.2]
|
||||||
|
- [30537.0, 160, -4.8]
|
||||||
|
- [31130.0, 160, -0.3]
|
||||||
|
- [31293.0, 160, 3.7]
|
||||||
|
- [31400.0, 160, 2.9]
|
||||||
|
- [31640.0, 160, 4.1]
|
||||||
|
- [31795.0, 120, 4.1]
|
||||||
|
- [32010.0, 120, 3.2]
|
||||||
|
- [32138.0, 130, 3.2]
|
||||||
|
- [32365.0, 130, -4]
|
||||||
|
- [33000.0, 130, 6.1]
|
||||||
|
- [33426.0, 160, 6.1]
|
||||||
|
- [33907.0, 160, 7.1]
|
||||||
|
- [34220.0, 160, 8.4]
|
||||||
|
- [34300.0, 160, 7.9]
|
||||||
|
- [34440.0, 160, 7.1]
|
||||||
|
- [34610.0, 160, 4.4]
|
||||||
|
- [35000.0, 160, 5.6]
|
||||||
|
- [35173.0, 150, 5.6]
|
||||||
|
- [35400.0, 150, -0.2]
|
||||||
|
- [35597.0, 160, -0.2]
|
||||||
|
- [35900.0, 160, 0]
|
||||||
|
- [36700.0, 160, 3.9]
|
||||||
|
- [36938.0, 160, 0]
|
||||||
|
- [37700.0, 160, -0.3]
|
||||||
|
- [37978.0, 150, -5.6]
|
||||||
|
- [38063.0, 150, -1.9]
|
||||||
|
- [38141.0, 150, -3.1]
|
||||||
|
- [38210.0, 150, 0]
|
||||||
|
- [38406.0, 150, -7]
|
||||||
|
- [38900.0, 150, -7.5]
|
||||||
|
- [39200.0, 150, -8.7]
|
||||||
|
- [39298.0, 150, -6.4]
|
||||||
|
- [39476.0, 150, -7.2]
|
||||||
|
- [40400.0, 150, -6.9]
|
||||||
|
- [40676.0, 130, -6.9]
|
||||||
|
- [41000.0, 130, -7.3]
|
||||||
|
- [41406.0, 130, -7.5]
|
||||||
|
- [41571.0, 160, -7.3]
|
||||||
|
- [41816.0, 160, -6.8]
|
||||||
|
- [41923.0, 160, -7.1]
|
||||||
|
- [42139.0, 160, -1.3]
|
||||||
|
- [42343.0, 160, -2.4]
|
||||||
|
- [42432.0, 150, -2.4]
|
||||||
|
- [42952.0, 160, -2.4]
|
||||||
|
- [43000.0, 160, -4.6]
|
||||||
|
- [43264.0, 160, -2.5]
|
||||||
|
- [43388.0, 160, -0.6]
|
||||||
|
- [43700.0, 160, 0.8]
|
||||||
|
- [44030.0, 160, 2.7]
|
||||||
|
- [44430.0, 160, 0]
|
||||||
|
- [44708.0, 160, -7.2]
|
||||||
|
- [45477.0, 160, -7.8]
|
||||||
|
- [45890.0, 160, -1]
|
||||||
|
- [46562.0, 160, -1.6]
|
||||||
|
- [47000.0, 160, -6.9]
|
||||||
|
- [47500.0, 160, -7.7]
|
||||||
|
- [47800.0, 160, -6.8]
|
||||||
|
- [48700.0, 160, -4.3]
|
||||||
|
- [49218.0, 160, -5.3]
|
||||||
|
- [49514.0, 160, -2.5]
|
||||||
|
- [50000.0, 160, -2.2]
|
||||||
|
- [51150.0, 160, -5.7]
|
||||||
|
- [51406.0, 160, -6.3]
|
||||||
|
- [51710.0, 150, -5.8]
|
||||||
|
- [52000.0, 150, -6.7]
|
||||||
|
- [52215.0, 150, -6.1]
|
||||||
|
- [53213.0, 150, -6.8]
|
||||||
|
- [53567.0, 150, -5.6]
|
||||||
|
- [53943.0, 150, -6.5]
|
||||||
|
- [54129.0, 140, -6.5]
|
||||||
|
- [54212.0, 140, -10.5]
|
||||||
|
- [54247.0, 140, -5.4]
|
||||||
|
- [54326.0, 140, -6.1]
|
||||||
|
- [54450.0, 140, -6.5]
|
||||||
|
- [54482.0, 120, -6.5]
|
||||||
|
- [54550.0, 120, -6.2]
|
||||||
|
- [54855.0, 140, -6.2]
|
||||||
|
- [55307.0, 140, -0.3]
|
||||||
|
- [55651.0, 140, -1.2]
|
||||||
|
- [55788.0, 140, 0]
|
||||||
|
- [55918.0, 100, 0]
|
||||||
|
- [56433.0, 150, 0]
|
||||||
|
- [56560.0, 150, -2.1]
|
||||||
|
- [56624.0, 150, -6.7]
|
||||||
|
- [57012.0, 150, 1.3]
|
||||||
|
- [57260.0, 150, 6.6]
|
||||||
|
- [57800.0, 150, 5.3]
|
||||||
|
- [57987.0, 150, 0]
|
||||||
|
- [57990.0, 150, 7.6]
|
||||||
|
- [58321.0, 150, 6.4]
|
||||||
|
- [59090.0, 150, 6.9]
|
||||||
|
- [59468.0, 150, 9.2]
|
||||||
|
- [59600.0, 150, 0.2]
|
||||||
|
- [60683.0, 150, 4.1]
|
||||||
|
- [61156.0, 150, 2.3]
|
||||||
|
- [61181.0, 130, 2.3]
|
||||||
|
- [61325.0, 130, 0]
|
||||||
|
- [61605.0, 130, 7.3]
|
||||||
|
- [62108.0, 150, 7.3]
|
||||||
|
- [62246.0, 150, 6.6]
|
||||||
|
- [62279.0, 150, 5.1]
|
||||||
|
- [62454.0, 150, 0.9]
|
||||||
|
- [62777.0, 150, 5.5]
|
||||||
|
- [63802.0, 150, 4.6]
|
||||||
|
- [64344.0, 150, 0.2]
|
||||||
|
- [64932.0, 150, -0.6]
|
||||||
|
- [65100.0, 150, 0]
|
||||||
|
- [65690.0, 150, 1.8]
|
||||||
|
- [65878.0, 150, 2.5]
|
||||||
|
- [66266.0, 150, -1]
|
||||||
|
- [66339.0, 150, 6.3]
|
||||||
|
- [66448.0, 160, 6.3]
|
||||||
|
- [66587.0, 160, 0]
|
||||||
|
- [66856.0, 160, 3.2]
|
||||||
|
- [67480.0, 160, 3.6]
|
||||||
|
- [67697.0, 160, 2.2]
|
||||||
|
- [67800.0, 160, 6]
|
||||||
|
- [67851.0, 130, 6]
|
||||||
|
- [68027.0, 130, 2.7]
|
||||||
|
- [68172.0, 130, 0.6]
|
||||||
|
- [68328.0, 130, 2.5]
|
||||||
|
- [68357.0, 130, 0]
|
||||||
|
- [68479.0, 130, 7.1]
|
||||||
|
- [68783.0, 130, 7.4]
|
||||||
|
- [69056.0, 150, 7.4]
|
||||||
|
- [69500.0, 150, 6.8]
|
||||||
|
- [69741.0, 160, 6.8]
|
||||||
|
- [69900.0, 160, 6.6]
|
||||||
|
- [70757.0, 160, 3.6]
|
||||||
|
- [71384.0, 160, 6]
|
||||||
|
- [71568.0, 160, 7.1]
|
||||||
|
- [71800.0, 160, 7.4]
|
||||||
|
- [72100.0, 160, 7.3]
|
||||||
|
- [73919.0, 150, 7.3]
|
||||||
|
- [74317.0, 140, 7.3]
|
||||||
|
- [74448.0, 140, 1.5]
|
||||||
|
- [74590.0, 140, -1.5]
|
||||||
|
- [74620.0, 140, -5]
|
||||||
|
- [74950.0, 140, -4.3]
|
||||||
|
- [75100.0, 140, -1.8]
|
||||||
|
- [75154.0, 130, -1.8]
|
||||||
|
- [75260.0, 130, -6.2]
|
||||||
|
- [75873.0, 130, -5.6]
|
||||||
|
- [76062.0, 100, -5.6]
|
||||||
|
- [76100.0, 100, -6.4]
|
||||||
|
- [76350.0, 100, -5.7]
|
||||||
|
- [76476.0, 100, -7]
|
||||||
|
- [76600.0, 100, -6.4]
|
||||||
|
- [76601.0, 90, -6.4]
|
||||||
|
- [76726.0, 90, -6.2]
|
||||||
|
- [77256.0, 90, -2.1]
|
||||||
|
- [77285.0, 80, -2.1]
|
||||||
|
- [77299.0, 80, -14]
|
||||||
|
- [77331.0, 80, -1.6]
|
||||||
|
- [77379.0, 90, -1.6]
|
||||||
|
- [77425.0, 110, -1.6]
|
||||||
|
- [77455.0, 110, -4.9]
|
||||||
|
- [77498.0, 110, 0]
|
||||||
|
- [77505.0, 160, 0]
|
||||||
|
- [77555.0, 160, -5.6]
|
||||||
|
- [77662.0, 160, 0]
|
||||||
|
- [78085.0, 160, -4]
|
||||||
|
- [78223.0, 160, -6.8]
|
||||||
|
- [78337.0, 130, -6.8]
|
||||||
|
- [78856.0, 130, -6.6]
|
||||||
|
- [78875.0, 130, -7.2]
|
||||||
|
- [79345.0, 150, -7.2]
|
||||||
|
- [79600.0, 150, -6.5]
|
||||||
|
- [79792.0, 150, -0.2]
|
||||||
|
- [80537.0, 150, -5.2]
|
||||||
|
- [81300.0, 150, -4.8]
|
||||||
|
- [81634.0, 110, -4.8]
|
||||||
|
- [81943.0, 110, -5.4]
|
||||||
|
- [82166.0, 110, 0]
|
||||||
|
- [82408.0, 110, 4.8]
|
||||||
|
- [82790.0, 110, 5.9]
|
||||||
|
- [83137.0, 120, 5.9]
|
||||||
|
- [83300.0, 120, 0]
|
||||||
|
- [83519.0, 150, 0]
|
||||||
|
- [83597.0, 150, -7.8]
|
||||||
|
- [83827.0, 150, -8.1]
|
||||||
|
- [84150.0, 150, -7.2]
|
||||||
|
- [84391.0, 150, 0]
|
||||||
|
- [84966.0, 150, -4]
|
||||||
|
- [85529.0, 130, -2.3]
|
||||||
|
- [85589.0, 130, -4]
|
||||||
|
- [86081.0, 130, 0]
|
||||||
|
- [86514.0, 130, 7.8]
|
||||||
|
- [86577.0, 120, 7.8]
|
||||||
|
- [87554.0, 90, 7.8]
|
||||||
|
- [87690.0, 90, 7.9]
|
||||||
|
- [87842.0, 90, 1.7]
|
||||||
|
- [88007.0, 110, 1.7]
|
||||||
|
- [88100.0, 110, 3.4]
|
||||||
|
- [88260.0, 110, 5.3]
|
||||||
|
- [88376.0, 160, 5.3]
|
||||||
|
- [88450.0, 160, 6.7]
|
||||||
|
- [89050.0, 160, 7.4]
|
||||||
|
- [89350.0, 160, -7.1]
|
||||||
|
- [90365.0, 160, 0]
|
||||||
|
- [90700.0, 160, -7.3]
|
||||||
|
- [92000.0, 160, -7.9]
|
||||||
|
- [92166.0, 160, -4]
|
||||||
|
- [92460.0, 160, -5.4]
|
||||||
|
- [93330.0, 160, 0]
|
||||||
|
- [93901.0, 160, 0.7]
|
||||||
|
- [94156.0, 160, 5.2]
|
||||||
|
- [94440.0, 160, -2.8]
|
||||||
|
- [94530.0, 160, -0.8]
|
||||||
|
- [94630.0, 160, -6.8]
|
||||||
|
- [94830.0, 160, -4.4]
|
||||||
|
- [95090.0, 160, -4.6]
|
||||||
|
- [95500.0, 160, -4.8]
|
||||||
|
- [96500.0, 160, -4.4]
|
||||||
|
- [96700.0, 160, -5.6]
|
||||||
|
- [97000.0, 160, -4.6]
|
||||||
|
- [97590.0, 160, 0]
|
||||||
|
- [97858.0, 120, 0]
|
||||||
|
- [98224.0, 120, -1.5]
|
||||||
|
- [98264.0, 120, 0]
|
||||||
|
- [98577.0, 120, 7.5]
|
||||||
|
- [98738.0, 120, 0]
|
||||||
|
- [99055.0, 130, 0]
|
||||||
|
- [99427.0, 130, -2]
|
||||||
|
- [99610.0, 130, -3.1]
|
||||||
|
- [99906.0, 120, -3.1]
|
||||||
|
- [99980.0, 120, -1.3]
|
||||||
|
- [100190.0, 120, -6.8]
|
||||||
|
- [100832.0, 120, -7.2]
|
||||||
|
- [100980.0, 120, -8.1]
|
||||||
|
- [101100.0, 120, -7.4]
|
||||||
|
- [101245.0, 120, -6.3]
|
||||||
|
- [101332.0, 100, -6.3]
|
||||||
|
- [101365.0, 100, -2.4]
|
||||||
|
- [101551.0, 110, -2.4]
|
||||||
|
- [101800.0, 110, 0]
|
|
@ -0,0 +1,11 @@
|
||||||
|
---
|
||||||
|
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: true # operation mode "minimum energy consumption"
|
||||||
|
typeOfOutput: "CSV" # output as "julia dictionary" or as "CSV"
|
||||||
|
detailOfOutput: "driving course" # should the output be "reduced" or "driving course"?
|
||||||
|
csvFolderPath: "~/Desktop/RailwayDrivingDynamics"
|
|
@ -0,0 +1,111 @@
|
||||||
|
---
|
||||||
|
vehicle:
|
||||||
|
name: "V 90 with 10 ore wagons of type Facs 124" # (source: https://de.wikipedia.org/wiki/DB-Baureihe_V_90 and https://dybas.de/dybas/gw/gw_f_1/g124.html)
|
||||||
|
l_union: 205.3 # in m (source: FBS: DB 290 with 10x Facs124)
|
||||||
|
m_td: 80000 # mass on driving axles of the traction unit in kg (source: https://de.wikipedia.org/wiki/DB-Baureihe_V_90)
|
||||||
|
m_tc: 0 # mass on carrying axles of the traction unit in kg (no carrying axles; source: https://de.wikipedia.org/wiki/DB-Baureihe_V_90)
|
||||||
|
m_w: 850000 # mass of the consist (set of wagons) in kg (source: FBS: 10x Facs124)
|
||||||
|
rotationMassFactor_union:
|
||||||
|
rotationMassFactor_t: 1.09 # (source: "Railway Timetabling & Operations" by Hansen, et al., 2014, p. 71 for the traction unit)
|
||||||
|
rotationMassFactor_w: 1.03 # (source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 13 for "Güterwagenzug beladen" -> 1.03 to 1.04)
|
||||||
|
powerType: diesel # diesel or electric (source: https://de.wikipedia.org/wiki/DB-Baureihe_V_90)
|
||||||
|
vehicleType: freight # "freight" or "passenger" or "motor coach train" (source: https://dybas.de/dybas/gw/gw_f_1/g124.html)
|
||||||
|
v_limit: # in m/s
|
||||||
|
v_limit_kmh: 80 # in km/h (source: https://de.wikipedia.org/wiki/DB-Baureihe_V_90)
|
||||||
|
a_braking: -0.4124 # in m/s^2 (source: FBS -> using the information from the "Fahrschaubild" of a long path without gradient or speed limit for DB 290 with with 10x Facs124)
|
||||||
|
|
||||||
|
# coefficients for the vehicle resistance
|
||||||
|
# for the traction unit (F_Rt=f_Rtd0*m_td*g+f_Rtc0*m_tc*g+F_Rt2*((v+Δv_t)/v00)^2)
|
||||||
|
f_Rtd0: 2.2 # coefficient for basic resistance due to the traction units driving axles (in ‰) (source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 151 for "4-achsige Diesellokomot." -> 2.2 ‰ to 3.5 ‰)
|
||||||
|
f_Rtc0: 0 # coefficient for basic resistance due to the traction units carring axles (in ‰) (source: no carrying axles; source: https://de.wikipedia.org/wiki/DB-Baureihe_V_90)
|
||||||
|
F_Rt2: 7500 # coefficient for air resistance of the traction units (in N) (source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 151 for "MittelfUhrerstand" -> 5000 N to 10000 N)
|
||||||
|
|
||||||
|
# for the consist (set of wagons) (F_Rw=m_w*g*(f_Rw0+f_Rw1*v/v00+f_Rw2*((v+Δv_w)/v00)^2))
|
||||||
|
f_Rw0: 1.4 # coefficient for the consists basic resistance (in ‰) (source: "Railway Timetabling & Operations" by Hansen, et al., 2014, p. 71 for "roller bearings")
|
||||||
|
f_Rw1: 0 # coefficient for the consists resistance to rolling (in ‰) (source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 153 -> no f_Rw1 for freight consists)
|
||||||
|
f_Rw2: 3.9 # coefficient fo the consistsr air resistance (in ‰) (source: "Railway Timetabling & Operations" by Hansen, et al., 2014, p. 71 for "full train loads of coal or ore" modified for the used formula)
|
||||||
|
|
||||||
|
# tractive effort as pairs of speed and tractive effort
|
||||||
|
F_T_pairs: # [v in m/s, F_T in N]
|
||||||
|
F_T_pairs_kmh: # [v in km/h, F_T in N] (source: FBS -> using the information from the "Fahrschaubild" of a long path without gradient or speed limit for DB 290 with with 10x Facs124)
|
||||||
|
- [0.0, 186940]
|
||||||
|
- [1.0, 186940]
|
||||||
|
- [2.0, 182310]
|
||||||
|
- [3.0, 177680]
|
||||||
|
- [4.0, 173050]
|
||||||
|
- [5.0, 168420]
|
||||||
|
- [6.0, 163790]
|
||||||
|
- [7.0, 159160]
|
||||||
|
- [8.0, 154530]
|
||||||
|
- [9.0, 149240]
|
||||||
|
- [10.0, 144120]
|
||||||
|
- [11.0, 139150]
|
||||||
|
- [12.0, 134340]
|
||||||
|
- [13.0, 129690]
|
||||||
|
- [14.0, 125200]
|
||||||
|
- [15.0, 120860]
|
||||||
|
- [16.0, 116680]
|
||||||
|
- [17.0, 112660]
|
||||||
|
- [18.0, 108790]
|
||||||
|
- [19.0, 105080]
|
||||||
|
- [20.0, 101530]
|
||||||
|
- [21.0, 98120]
|
||||||
|
- [22.0, 94840]
|
||||||
|
- [23.0, 91700]
|
||||||
|
- [24.0, 88700]
|
||||||
|
- [25.0, 85840]
|
||||||
|
- [26.0, 83110]
|
||||||
|
- [27.0, 80520]
|
||||||
|
- [28.0, 78070]
|
||||||
|
- [29.0, 75750]
|
||||||
|
- [30.0, 73580]
|
||||||
|
- [31.0, 71600]
|
||||||
|
- [32.0, 69660]
|
||||||
|
- [33.0, 67770]
|
||||||
|
- [34.0, 65930]
|
||||||
|
- [35.0, 64130]
|
||||||
|
- [36.0, 62380]
|
||||||
|
- [37.0, 60670]
|
||||||
|
- [38.0, 59010]
|
||||||
|
- [39.0, 57400]
|
||||||
|
- [40.0, 55830]
|
||||||
|
- [41.0, 54300]
|
||||||
|
- [42.0, 52820]
|
||||||
|
- [43.0, 51390]
|
||||||
|
- [44.0, 50000]
|
||||||
|
- [45.0, 48660]
|
||||||
|
- [46.0, 48080]
|
||||||
|
- [47.0, 47220]
|
||||||
|
- [48.0, 46380]
|
||||||
|
- [49.0, 45550]
|
||||||
|
- [50.0, 44730]
|
||||||
|
- [51.0, 43930]
|
||||||
|
- [52.0, 43140]
|
||||||
|
- [53.0, 42370]
|
||||||
|
- [54.0, 41610]
|
||||||
|
- [55.0, 40870]
|
||||||
|
- [56.0, 40140]
|
||||||
|
- [57.0, 39430]
|
||||||
|
- [58.0, 38730]
|
||||||
|
- [59.0, 38040]
|
||||||
|
- [60.0, 37370]
|
||||||
|
- [61.0, 36720]
|
||||||
|
- [62.0, 36070]
|
||||||
|
- [63.0, 35450]
|
||||||
|
- [64.0, 34830]
|
||||||
|
- [65.0, 34230]
|
||||||
|
- [66.0, 33650]
|
||||||
|
- [67.0, 33080]
|
||||||
|
- [68.0, 32520]
|
||||||
|
- [69.0, 31980]
|
||||||
|
- [70.0, 31450]
|
||||||
|
- [71.0, 30940]
|
||||||
|
- [72.0, 30440]
|
||||||
|
- [73.0, 29960]
|
||||||
|
- [74.0, 29490]
|
||||||
|
- [75.0, 29030]
|
||||||
|
- [76.0, 28590]
|
||||||
|
- [77.0, 28170]
|
||||||
|
- [78.0, 27760]
|
||||||
|
- [79.0, 27360]
|
||||||
|
- [80.0, 26980]
|
|
@ -0,0 +1,191 @@
|
||||||
|
---
|
||||||
|
vehicle:
|
||||||
|
name: "Intercity 2 (Traxx P160 AC2 + double deck coaches)" # (source: https://de.wikipedia.org/wiki/Bombardier_Twindexx_Vario#Intercity_2 and https://de.wikipedia.org/wiki/Intercity_2_(Deutsche_Bahn))
|
||||||
|
l_union: 152 # in m (source: FBS: DB146.5 with 1x DApza687.2, 3x DBpza668.2, 1x DBpbzfa668.2)
|
||||||
|
m_td: 84000 # mass on driving axles of the traction unit in kg (source: FBS: DB146.5)
|
||||||
|
m_tc: 0 # mass on carrying axles of the traction unit in kg (no carrying axles; source: FBS: DB146.5)
|
||||||
|
m_w: 309000 # mass of the consist (set of wagons) in kg (source: FBS: 1x DApza687.2, 3x DBpza668.2, 1x DBpbzfa668.2)
|
||||||
|
rotationMassFactor_union:
|
||||||
|
rotationMassFactor_t: 1.09 # (source: "Railway Timetabling & Operations" by Hansen, et al., 2014, p. 71 for the traction unit)
|
||||||
|
rotationMassFactor_w: 1.06 # (source: "Railway Timetabling & Operations" by Hansen, et al., 2014, p. 71 for freight wagons)
|
||||||
|
powerType: electric # diesel or electric (source: https://de.wikipedia.org/wiki/Intercity_2_(Deutsche_Bahn)#Gemeinsame_Merkmale)
|
||||||
|
vehicleType: passenger # "freight" or "passenger" or "motor coach train" (source: https://de.wikipedia.org/wiki/Intercity_2_(Deutsche_Bahn))
|
||||||
|
v_limit: # in m/s
|
||||||
|
v_limit_kmh: 160 # in km/h (source: https://de.wikipedia.org/wiki/Intercity_2_(Deutsche_Bahn)#Gemeinsame_Merkmale)
|
||||||
|
a_braking: -0.3507 # in m/s^2 (source: FBS -> using the information from the "Fahrschaubild" of a long path without gradient or speed limit for DB146.5 with 1x DApza687.2, 3x DBpza668.2, 1x DBpbzfa668.2)
|
||||||
|
|
||||||
|
# coefficients for the vehicle resistance
|
||||||
|
# for the traction unit (F_Rt=f_Rtd0*m_td*g+f_Rtc0*m_tc*g+F_Rt2*((v+Δv_t)/v00)^2)
|
||||||
|
f_Rtd0: 2.5 # coefficient for basic resistance due to the traction units driving axles (in ‰) (source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 151 for "Hochgeschwindigkeitslok."" -> 2.0 ‰ to 3.0 ‰)
|
||||||
|
f_Rtc0: 0 # coefficient for basic resistance due to the traction units carring axles (in ‰) (source: no carrying axles; source: FBS: DB146.5)
|
||||||
|
F_Rt2: 5000 # coefficient for air resistance of the traction units (in N) (source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 151 for "4-achsig, eckige Kopfform"with "Stromabnehmer" -> 5000 N to 6000 N)
|
||||||
|
|
||||||
|
# for the consist (set of wagons) (F_Rw=m_w*g*(f_Rw0+f_Rw1*v/v00+f_Rw2*((v+Δv_w)/v00)^2))
|
||||||
|
f_Rw0: 2.0 # coefficient for the consists basic resistance (in ‰) (source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 153 for "Doppelstockgliederzüge")
|
||||||
|
f_Rw1: 0.715 # coefficient for the consists resistance to rolling (in ‰) (source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 153 for "Doppelstockgliederzüge")
|
||||||
|
f_Rw2: 3.64 # coefficient fo the consistsr air resistance (in ‰) (source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 153 for "Doppelstockgliederzüge")
|
||||||
|
|
||||||
|
# tractive effort as pairs of speed and tractive effort
|
||||||
|
F_T_pairs: # [v in m/s, F_T in N]
|
||||||
|
F_T_pairs_kmh: # [v in km/h, F_T in N] (source: FBS -> using the information from the "Fahrschaubild" of a long path without gradient or speed limit for DB146.5 with 1x DApza687.2, 3x DBpza668.2, 1x DBpbzfa668.2)
|
||||||
|
- [0.0, 300000]
|
||||||
|
- [1.0, 300000]
|
||||||
|
- [2.0, 300000]
|
||||||
|
- [3.0, 300000]
|
||||||
|
- [4.0, 300000]
|
||||||
|
- [5.0, 300000]
|
||||||
|
- [6.0, 300000]
|
||||||
|
- [7.0, 300000]
|
||||||
|
- [8.0, 300000]
|
||||||
|
- [9.0, 300000]
|
||||||
|
- [10.0, 300000]
|
||||||
|
- [11.0, 300000]
|
||||||
|
- [12.0, 300000]
|
||||||
|
- [13.0, 300000]
|
||||||
|
- [14.0, 300000]
|
||||||
|
- [15.0, 300000]
|
||||||
|
- [16.0, 300000]
|
||||||
|
- [17.0, 300000]
|
||||||
|
- [18.0, 300000]
|
||||||
|
- [19.0, 300000]
|
||||||
|
- [20.0, 300000]
|
||||||
|
- [21.0, 300000]
|
||||||
|
- [22.0, 300000]
|
||||||
|
- [23.0, 300000]
|
||||||
|
- [24.0, 300000]
|
||||||
|
- [25.0, 300000]
|
||||||
|
- [26.0, 300000]
|
||||||
|
- [27.0, 300000]
|
||||||
|
- [28.0, 300000]
|
||||||
|
- [29.0, 300000]
|
||||||
|
- [30.0, 300000]
|
||||||
|
- [31.0, 300000]
|
||||||
|
- [32.0, 300000]
|
||||||
|
- [33.0, 300000]
|
||||||
|
- [34.0, 300000]
|
||||||
|
- [35.0, 300000]
|
||||||
|
- [36.0, 300000]
|
||||||
|
- [37.0, 300000]
|
||||||
|
- [38.0, 300000]
|
||||||
|
- [39.0, 300000]
|
||||||
|
- [40.0, 300000]
|
||||||
|
- [41.0, 300000]
|
||||||
|
- [42.0, 300000]
|
||||||
|
- [43.0, 300000]
|
||||||
|
- [44.0, 300000]
|
||||||
|
- [45.0, 300000]
|
||||||
|
- [46.0, 300000]
|
||||||
|
- [47.0, 300000]
|
||||||
|
- [48.0, 300000]
|
||||||
|
- [49.0, 300000]
|
||||||
|
- [50.0, 300000]
|
||||||
|
- [51.0, 300000]
|
||||||
|
- [52.0, 300000]
|
||||||
|
- [53.0, 300000]
|
||||||
|
- [54.0, 300000]
|
||||||
|
- [55.0, 300000]
|
||||||
|
- [56.0, 300000]
|
||||||
|
- [57.0, 300000]
|
||||||
|
- [58.0, 300000]
|
||||||
|
- [59.0, 300000]
|
||||||
|
- [60.0, 300000]
|
||||||
|
- [61.0, 300000]
|
||||||
|
- [62.0, 300000]
|
||||||
|
- [63.0, 300000]
|
||||||
|
- [64.0, 300000]
|
||||||
|
- [65.0, 300000]
|
||||||
|
- [66.0, 300000]
|
||||||
|
- [67.0, 297760]
|
||||||
|
- [68.0, 293380]
|
||||||
|
- [69.0, 289130]
|
||||||
|
- [70.0, 285000]
|
||||||
|
- [71.0, 280990]
|
||||||
|
- [72.0, 277080]
|
||||||
|
- [73.0, 273290]
|
||||||
|
- [74.0, 269590]
|
||||||
|
- [75.0, 266000]
|
||||||
|
- [76.0, 262500]
|
||||||
|
- [77.0, 259090]
|
||||||
|
- [78.0, 255770]
|
||||||
|
- [79.0, 252530]
|
||||||
|
- [80.0, 249380]
|
||||||
|
- [81.0, 246300]
|
||||||
|
- [82.0, 243290]
|
||||||
|
- [83.0, 240360]
|
||||||
|
- [84.0, 237500]
|
||||||
|
- [85.0, 234710]
|
||||||
|
- [86.0, 231980]
|
||||||
|
- [87.0, 229310]
|
||||||
|
- [88.0, 226700]
|
||||||
|
- [89.0, 224160]
|
||||||
|
- [90.0, 221670]
|
||||||
|
- [91.0, 219230]
|
||||||
|
- [92.0, 216850]
|
||||||
|
- [93.0, 214520]
|
||||||
|
- [94.0, 212230]
|
||||||
|
- [95.0, 210000]
|
||||||
|
- [96.0, 207810]
|
||||||
|
- [97.0, 205670]
|
||||||
|
- [98.0, 203570]
|
||||||
|
- [99.0, 201520]
|
||||||
|
- [100.0, 199500]
|
||||||
|
- [101.0, 197520]
|
||||||
|
- [102.0, 195590]
|
||||||
|
- [103.0, 193690]
|
||||||
|
- [104.0, 191830]
|
||||||
|
- [105.0, 190000]
|
||||||
|
- [106.0, 188210]
|
||||||
|
- [107.0, 186450]
|
||||||
|
- [108.0, 184720]
|
||||||
|
- [109.0, 183030]
|
||||||
|
- [110.0, 181360]
|
||||||
|
- [111.0, 179730]
|
||||||
|
- [112.0, 178130]
|
||||||
|
- [113.0, 176550]
|
||||||
|
- [114.0, 175000]
|
||||||
|
- [115.0, 173480]
|
||||||
|
- [116.0, 171980]
|
||||||
|
- [117.0, 170510]
|
||||||
|
- [118.0, 169070]
|
||||||
|
- [119.0, 167650]
|
||||||
|
- [120.0, 166250]
|
||||||
|
- [121.0, 164880]
|
||||||
|
- [122.0, 163520]
|
||||||
|
- [123.0, 162200]
|
||||||
|
- [124.0, 160890]
|
||||||
|
- [125.0, 159600]
|
||||||
|
- [126.0, 158330]
|
||||||
|
- [127.0, 157090]
|
||||||
|
- [128.0, 155860]
|
||||||
|
- [129.0, 154650]
|
||||||
|
- [130.0, 153460]
|
||||||
|
- [131.0, 152290]
|
||||||
|
- [132.0, 151140]
|
||||||
|
- [133.0, 150000]
|
||||||
|
- [134.0, 148880]
|
||||||
|
- [135.0, 147780]
|
||||||
|
- [136.0, 146690]
|
||||||
|
- [137.0, 145620]
|
||||||
|
- [138.0, 144570]
|
||||||
|
- [139.0, 143530]
|
||||||
|
- [140.0, 142500]
|
||||||
|
- [141.0, 141490]
|
||||||
|
- [142.0, 140490]
|
||||||
|
- [143.0, 139510]
|
||||||
|
- [144.0, 138540]
|
||||||
|
- [145.0, 137590]
|
||||||
|
- [146.0, 136640]
|
||||||
|
- [147.0, 135710]
|
||||||
|
- [148.0, 134800]
|
||||||
|
- [149.0, 133890]
|
||||||
|
- [150.0, 133000]
|
||||||
|
- [151.0, 132120]
|
||||||
|
- [152.0, 131250]
|
||||||
|
- [153.0, 130390]
|
||||||
|
- [154.0, 129550]
|
||||||
|
- [155.0, 128710]
|
||||||
|
- [156.0, 127880]
|
||||||
|
- [157.0, 127070]
|
||||||
|
- [158.0, 126270]
|
||||||
|
- [159.0, 125470]
|
||||||
|
- [160.0, 124690]
|
|
@ -0,0 +1,151 @@
|
||||||
|
---
|
||||||
|
vehicle:
|
||||||
|
name: "Siemens Desiro Classic" # (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
|
||||||
|
l_union: 41.7 # in m (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
|
||||||
|
m_td: 52800 # mass on driving axles of the traction unit in kg (source: FBS: DB 642; proportionately to the number of axles: 4 to 2, see: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
|
||||||
|
m_tc: 35200 # mass on carrying axles of the traction unit in kg (source: FBS: DB 642; proportionately to the number of axles: 4 to 2, see: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
|
||||||
|
m_w: 0 # mass of the consist (set of wagons) in kg (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic -> no separate wagons)
|
||||||
|
rotationMassFactor_union: 1.08 # (source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 13 for "Zug, überschlägliche Berechnung")
|
||||||
|
rotationMassFactor_t:
|
||||||
|
rotationMassFactor_w:
|
||||||
|
powerType: diesel # diesel or electric (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
|
||||||
|
vehicleType: motor coach train # "freight" or "passenger" or "motor coach train" (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
|
||||||
|
v_limit: # in m/s
|
||||||
|
v_limit_kmh: 120 # in km/h (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
|
||||||
|
a_braking: -0.4253 # in m/s^2 (source: FBS -> using the information from the "Fahrschaubild" of a long path without gradient or speed limit for DB 642)
|
||||||
|
|
||||||
|
# coefficients for the vehicle resistance
|
||||||
|
# for the traction unit (F_Rt=f_Rtd0*m_td*g+f_Rtc0*m_tc*g+F_Rt2*((v+Δv_t)/v00)^2)
|
||||||
|
f_Rtd0: 3.0 # coefficient for basic resistance due to the traction units driving axles (in ‰) (source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 151 for "f_WL0" -> 2.5 ‰ to 3.5 ‰)
|
||||||
|
f_Rtc0: 1.4 # coefficient for basic resistance due to the traction units carring axles (in ‰) (source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 151 for "f_WW0" -> 1.2 ‰ to 1.6 ‰)
|
||||||
|
F_Rt2: 2600 # coefficient for air resistance of the traction units (in N) (source: the closest parameters are used: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 151 for "Fzg. vierachsig, abgerundeter Kopf" plus "Sektion bei Mehrteiligkeit" -> 2200 N to 400 N)
|
||||||
|
|
||||||
|
# for the consist (set of wagons) (F_Rw=m_w*g*(f_Rw0+f_Rw1*v/v00+f_Rw2*((v+Δv_w)/v00)^2))
|
||||||
|
f_Rw0: # coefficient for basic resistance of the set of wagons (in ‰) (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic -> no separate wagons)
|
||||||
|
f_Rw1: # coefficient for resistance to rolling of the set of wagons (in ‰) (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic -> no separate wagons)
|
||||||
|
f_Rw2: # coefficient for air resistance of the set of wagons (in ‰) (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic -> no separate wagons)
|
||||||
|
|
||||||
|
# tractive effort as pairs of speed and tractive effort
|
||||||
|
F_T_pairs: # [v in m/s, F_T in N]
|
||||||
|
F_T_pairs_kmh: # [v in km/h, F_T in N] (source: FBS -> using the information from the "Fahrschaubild" of a long path without gradient or speed limit for DB 642)
|
||||||
|
- [0.0, 94400]
|
||||||
|
- [1.0, 94400]
|
||||||
|
- [2.0, 92800]
|
||||||
|
- [3.0, 91200]
|
||||||
|
- [4.0, 89600]
|
||||||
|
- [5.0, 88000]
|
||||||
|
- [6.0, 86400]
|
||||||
|
- [7.0, 84800]
|
||||||
|
- [8.0, 83200]
|
||||||
|
- [9.0, 81600]
|
||||||
|
- [10.0, 80000]
|
||||||
|
- [11.0, 78160]
|
||||||
|
- [12.0, 76290]
|
||||||
|
- [13.0, 74420]
|
||||||
|
- [14.0, 72550]
|
||||||
|
- [15.0, 70680]
|
||||||
|
- [16.0, 68810]
|
||||||
|
- [17.0, 66940]
|
||||||
|
- [18.0, 65070]
|
||||||
|
- [19.0, 63200]
|
||||||
|
- [20.0, 61330]
|
||||||
|
- [21.0, 59460]
|
||||||
|
- [22.0, 57590]
|
||||||
|
- [23.0, 55720]
|
||||||
|
- [24.0, 53850]
|
||||||
|
- [25.0, 51980]
|
||||||
|
- [26.0, 50110]
|
||||||
|
- [27.0, 48240]
|
||||||
|
- [28.0, 46370]
|
||||||
|
- [29.0, 44500]
|
||||||
|
- [30.0, 42630]
|
||||||
|
- [31.0, 40760]
|
||||||
|
- [32.0, 38890]
|
||||||
|
- [33.0, 38110]
|
||||||
|
- [34.0, 37330]
|
||||||
|
- [35.0, 36550]
|
||||||
|
- [36.0, 35770]
|
||||||
|
- [37.0, 35600]
|
||||||
|
- [38.0, 35600]
|
||||||
|
- [39.0, 35600]
|
||||||
|
- [40.0, 35600]
|
||||||
|
- [41.0, 35600]
|
||||||
|
- [42.0, 35600]
|
||||||
|
- [43.0, 35550]
|
||||||
|
- [44.0, 35280]
|
||||||
|
- [45.0, 35010]
|
||||||
|
- [46.0, 34740]
|
||||||
|
- [47.0, 34280]
|
||||||
|
- [48.0, 33560]
|
||||||
|
- [49.0, 32880]
|
||||||
|
- [50.0, 32220]
|
||||||
|
- [51.0, 31590]
|
||||||
|
- [52.0, 26300]
|
||||||
|
- [53.0, 26300]
|
||||||
|
- [54.0, 26300]
|
||||||
|
- [55.0, 26300]
|
||||||
|
- [56.0, 26300]
|
||||||
|
- [57.0, 25990]
|
||||||
|
- [58.0, 25840]
|
||||||
|
- [59.0, 25690]
|
||||||
|
- [60.0, 25540]
|
||||||
|
- [61.0, 25390]
|
||||||
|
- [62.0, 25240]
|
||||||
|
- [63.0, 25090]
|
||||||
|
- [64.0, 25140]
|
||||||
|
- [65.0, 24760]
|
||||||
|
- [66.0, 24380]
|
||||||
|
- [67.0, 24020]
|
||||||
|
- [68.0, 23660]
|
||||||
|
- [69.0, 23320]
|
||||||
|
- [70.0, 22990]
|
||||||
|
- [71.0, 19400]
|
||||||
|
- [72.0, 19400]
|
||||||
|
- [73.0, 19400]
|
||||||
|
- [74.0, 19400]
|
||||||
|
- [75.0, 19400]
|
||||||
|
- [76.0, 19400]
|
||||||
|
- [77.0, 19400]
|
||||||
|
- [78.0, 19400]
|
||||||
|
- [79.0, 19400]
|
||||||
|
- [80.0, 19400]
|
||||||
|
- [81.0, 19440]
|
||||||
|
- [82.0, 19310]
|
||||||
|
- [83.0, 19180]
|
||||||
|
- [84.0, 19050]
|
||||||
|
- [85.0, 18920]
|
||||||
|
- [86.0, 18670]
|
||||||
|
- [87.0, 18460]
|
||||||
|
- [88.0, 18250]
|
||||||
|
- [89.0, 15360]
|
||||||
|
- [90.0, 15310]
|
||||||
|
- [91.0, 15260]
|
||||||
|
- [92.0, 15210]
|
||||||
|
- [93.0, 15160]
|
||||||
|
- [94.0, 15110]
|
||||||
|
- [95.0, 15060]
|
||||||
|
- [96.0, 15010]
|
||||||
|
- [97.0, 14960]
|
||||||
|
- [98.0, 14910]
|
||||||
|
- [99.0, 14860]
|
||||||
|
- [100.0, 14810]
|
||||||
|
- [101.0, 14760]
|
||||||
|
- [102.0, 14710]
|
||||||
|
- [103.0, 14660]
|
||||||
|
- [104.0, 14610]
|
||||||
|
- [105.0, 14560]
|
||||||
|
- [106.0, 14510]
|
||||||
|
- [107.0, 14460]
|
||||||
|
- [108.0, 14410]
|
||||||
|
- [109.0, 14360]
|
||||||
|
- [110.0, 14310]
|
||||||
|
- [111.0, 14460]
|
||||||
|
- [112.0, 14340]
|
||||||
|
- [113.0, 14210]
|
||||||
|
- [114.0, 14080]
|
||||||
|
- [115.0, 13960]
|
||||||
|
- [116.0, 13840]
|
||||||
|
- [117.0, 13720]
|
||||||
|
- [118.0, 13610]
|
||||||
|
- [119.0, 13490]
|
||||||
|
- [120.0, 13380]
|
|
@ -0,0 +1,34 @@
|
||||||
|
include("../src/RailwayDrivingDynamics.jl")
|
||||||
|
using .RailwayDrivingDynamics
|
||||||
|
|
||||||
|
# println("")
|
||||||
|
# println("________________________")
|
||||||
|
# println("")
|
||||||
|
|
||||||
|
allPaths=["../data/paths/path_1_10km_nConst_vConst.yaml" , "../data/paths/path_2_10km_nVar_vConst.yaml", "../data/paths/path_3_10km_nConst_vVar.yaml", "../data/paths/path_4_real_Ostsachsen_DG-DN_spp_5.yaml"]
|
||||||
|
|
||||||
|
settingsFilePath="../data/settings.yaml"
|
||||||
|
|
||||||
|
for pathFilePath in allPaths
|
||||||
|
# println("")
|
||||||
|
# println(" - - - - - - - - -")
|
||||||
|
# println("path: ", pathFilePath)
|
||||||
|
|
||||||
|
vehicleFilePath="../data/vehicles/vehicle_passenger_intercity.yaml"
|
||||||
|
testDict1=calculateDrivingDynamics(vehicleFilePath, pathFilePath, settingsFilePath)
|
||||||
|
|
||||||
|
sleep(2)
|
||||||
|
vehicleFilePath="../data/vehicles/vehicle_passenger_suburban.yaml"
|
||||||
|
testDict2=calculateDrivingDynamics(vehicleFilePath, pathFilePath, settingsFilePath)
|
||||||
|
|
||||||
|
|
||||||
|
sleep(2)
|
||||||
|
vehicleFilePath="../data/vehicles/vehicle_freight.yaml"
|
||||||
|
testDict3=calculateDrivingDynamics(vehicleFilePath, pathFilePath, settingsFilePath)
|
||||||
|
|
||||||
|
|
||||||
|
# println("")
|
||||||
|
# println("")
|
||||||
|
# println("")
|
||||||
|
# println("")
|
||||||
|
end
|
|
@ -0,0 +1,64 @@
|
||||||
|
module RailwayDrivingDynamics
|
||||||
|
|
||||||
|
include("./types.jl")
|
||||||
|
include("./RailwayDrivingDynamicsInput.jl")
|
||||||
|
include("./RailwayDrivingDynamicsPreparation.jl")
|
||||||
|
include("./RailwayDrivingDynamicsOperationModes.jl")
|
||||||
|
include("./RailwayDrivingDynamicsOutput.jl")
|
||||||
|
|
||||||
|
|
||||||
|
using .types
|
||||||
|
using .RailwayDrivingDynamicsInput
|
||||||
|
using .RailwayDrivingDynamicsPreparation
|
||||||
|
using .RailwayDrivingDynamicsOperationModes
|
||||||
|
using .RailwayDrivingDynamicsOutput
|
||||||
|
|
||||||
|
export calculateDrivingDynamics
|
||||||
|
|
||||||
|
function calculateDrivingDynamics(vehicleFilePath::String, pathFilePath::String, settingsFilePath::String)
|
||||||
|
# main function for calculating the driving dynamics
|
||||||
|
println("")
|
||||||
|
println("")
|
||||||
|
println("")
|
||||||
|
|
||||||
|
# input
|
||||||
|
(vehicle, path, settings)=readInput(vehicleFilePath, pathFilePath, settingsFilePath)
|
||||||
|
println("The input has been saved.")
|
||||||
|
|
||||||
|
|
||||||
|
# preparing the input data
|
||||||
|
movingSection=preparateSections(path, vehicle, settings)
|
||||||
|
println("The moving section has been preparated.")
|
||||||
|
|
||||||
|
if settings.operationModeMinimumRunningTime==true || settings.operationModeMinimumEnergyConsumption==true
|
||||||
|
(movingSectionMinimumRunningTime, drivingCourseMinimumRunningTime)=simulateMinimumRunningTime!(movingSection, settings, vehicle)
|
||||||
|
# println("t_total=", drivingCourseMinimumRunningTime[end].t)
|
||||||
|
# printSectionInformation(movingSectionMinimumRunningTime)
|
||||||
|
println("The driving course for the shortest running time has been calculated.")
|
||||||
|
end #if
|
||||||
|
|
||||||
|
|
||||||
|
# oparation mode "minimum energy consumption"
|
||||||
|
if settings.operationModeMinimumEnergyConsumption==true
|
||||||
|
(movingSectionMinimumEnergyConsumption, drivingCourseMinimumEnergyConsumption)=simulateMinimumEnergyConsumption(movingSectionMinimumRunningTime, drivingCourseMinimumRunningTime, settings, vehicle)
|
||||||
|
# printSectionInformation(movingSectionMinimumEnergyConsumption)
|
||||||
|
println("The driving course for the energy consumption has been calculated.")
|
||||||
|
end #if
|
||||||
|
|
||||||
|
#output
|
||||||
|
if settings.operationModeMinimumRunningTime==true && settings.operationModeMinimumEnergyConsumption==true
|
||||||
|
plotDrivingCourse(drivingCourseMinimumRunningTime, drivingCourseMinimumEnergyConsumption)
|
||||||
|
return createOutput(settings, path.name, vehicle.name, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||||
|
elseif settings.operationModeMinimumRunningTime==true
|
||||||
|
plotDrivingCourse(drivingCourseMinimumRunningTime)
|
||||||
|
return createOutput(settings, path.name, vehicle.name, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime)
|
||||||
|
elseif settings.operationModeMinimumEnergyConsumption==true
|
||||||
|
plotDrivingCourse(drivingCourseMinimumEnergyConsumption)
|
||||||
|
return createOutput(settings, path.name, vehicle.name, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||||
|
else
|
||||||
|
println("No Output was demanded. So no output is created.")
|
||||||
|
return Dict()
|
||||||
|
end
|
||||||
|
end # function calculateDrivingDynamics
|
||||||
|
|
||||||
|
end # module RailwayDrivingDynamics
|
|
@ -0,0 +1,281 @@
|
||||||
|
module RailwayDrivingDynamicsEnergySaving
|
||||||
|
|
||||||
|
using ..types
|
||||||
|
using ..RailwayDrivingDynamicsMovingPhases
|
||||||
|
|
||||||
|
export calculateRecoveryTime, increaseCostingSection, decreaseMaximumVelocity, combineEnergySavingMethods
|
||||||
|
|
||||||
|
function calculateRecoveryTime(s_MS::AbstractFloat, t_MS::AbstractFloat, vehicle::Vehicle)
|
||||||
|
# function for calculating the recovery time that can be used for energy saving
|
||||||
|
if vehicle.vehicleType=="motor coach train"
|
||||||
|
if s_MS<= 30000
|
||||||
|
c_s=0.0
|
||||||
|
else s_MS> 30000
|
||||||
|
c_s=0.0006
|
||||||
|
end # if s_MS
|
||||||
|
|
||||||
|
if vehicle.v_limit<=140/3.6 # unit is m/s
|
||||||
|
c_t=0.03
|
||||||
|
elseif vehicle.v_limit<=160/3.6 # unit is m/s
|
||||||
|
c_t=0.04
|
||||||
|
elseif vehicle.v_limit<=200/3.6 # unit is m/s
|
||||||
|
c_t=0.05
|
||||||
|
elseif vehicle.v_limit<=250/3.6 # unit is m/s
|
||||||
|
c_t=0.06
|
||||||
|
else # vehicle.v_limit>120/3.6 # unit is m/s
|
||||||
|
c_t=0.07
|
||||||
|
end # if vehicle.v_limit
|
||||||
|
|
||||||
|
t_recovery=s_MS*c_s+t_MS*c_t
|
||||||
|
return t_recovery
|
||||||
|
elseif vehicle.vehicleType=="freight" && vehicle.v_limit<=120/3.6 # unit is m/s
|
||||||
|
t_recovery1=s_MS*0.0006 +t_MS*0.03
|
||||||
|
t_recovery2=s_MS*0.0018 +t_MS*0.0
|
||||||
|
t_recovery3=s_MS*0.0 +t_MS*0.04
|
||||||
|
t_recovery=max(t_recovery1, t_recovery2, t_recovery3)
|
||||||
|
|
||||||
|
return t_recovery
|
||||||
|
else # vehicle.vehicleType=="passenger" || (vehicle.vehicleType=="freight" && vehicle.v_limit>120/3.6) # unit is m/s
|
||||||
|
if s_MS<= 30000
|
||||||
|
c_s=0.0
|
||||||
|
else s_MS> 30000
|
||||||
|
c_s=0.0009
|
||||||
|
end # if s_MS
|
||||||
|
if vehicle.v_limit<=140/3.6 # unit is m/s
|
||||||
|
if vehicle.m_union<=300000 # unit is kg
|
||||||
|
c_t=0.03
|
||||||
|
elseif vehicle.m_union<=500000 # unit is kg
|
||||||
|
c_t=0.04
|
||||||
|
elseif vehicle.m_union<=700000 # unit is kg
|
||||||
|
c_t=0.04
|
||||||
|
else # vehicle.m_union>700000 # unit is kg
|
||||||
|
c_t=0.05
|
||||||
|
end # if vehicle.m_union
|
||||||
|
elseif vehicle.v_limit<=160/3.6 # unit is m/s
|
||||||
|
if vehicle.m_union<=300000 # unit is kg
|
||||||
|
c_t=0.03
|
||||||
|
elseif vehicle.m_union<=500000 # unit is kg
|
||||||
|
c_t=0.04
|
||||||
|
else # vehicle.m_union>500000 # unit is kg
|
||||||
|
c_t=0.0
|
||||||
|
end # if vehicle.m_union
|
||||||
|
elseif vehicle.v_limit<=200/3.6 # unit is m/s
|
||||||
|
if vehicle.m_union<=300000 # unit is kg
|
||||||
|
c_t=0.04
|
||||||
|
elseif vehicle.m_union<=500000 # unit is kg
|
||||||
|
c_t=0.05
|
||||||
|
else # vehicle.m_union>500000 # unit is kg
|
||||||
|
c_t=0.06
|
||||||
|
end # if vehicle.m_union
|
||||||
|
else # vehicle.v_limit>200/3.6 # unit is m/s
|
||||||
|
if vehicle.m_union<=300000 # unit is kg
|
||||||
|
c_t=0.05
|
||||||
|
elseif vehicle.m_union<=500000 # unit is kg
|
||||||
|
c_t=0.06
|
||||||
|
else # vehicle.m_union>500000 # unit is kg
|
||||||
|
c_t=0.07
|
||||||
|
end # if vehicle.m_union
|
||||||
|
end # if vehicle.v_limit
|
||||||
|
|
||||||
|
c_tMin=s_MS/t_MS*0.0012
|
||||||
|
c_t=max(c_t, c_tMin)
|
||||||
|
|
||||||
|
t_recovery=s_MS*c_s+t_MS*c_t
|
||||||
|
return t_recovery
|
||||||
|
end # if vehicle.vehicleType
|
||||||
|
end #function calculateRecoveryTime
|
||||||
|
|
||||||
|
|
||||||
|
function increaseCostingSection(csOriginal::CharacteristicSection, drivingCourse::Vector{Waypoint}, settings::Settings, vehicle::Vehicle, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||||
|
if haskey(csOriginal.behaviorSections, "cruising") && haskey(csOriginal.behaviorSections, "braking")
|
||||||
|
cruisingReduction=settings.stepSize
|
||||||
|
while cruisingReduction>=settings.stepSize/100
|
||||||
|
while cruisingReduction>=settings.stepSize/100 # will be done once and repeated twice with smaller cruisingReduction unless !(drivingCourseModified[end].v<=csModified.v_exit && drivingCourseModified[end].s<csModified.s_end) -> see below at the end of the while loop
|
||||||
|
|
||||||
|
# creating a drivingCourse for the characteristic section
|
||||||
|
energySavingStartId=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).waypoints[1]
|
||||||
|
if energySavingStartId==0
|
||||||
|
error("ERROR at creating a new driving course for energy saving with coasting !")
|
||||||
|
end
|
||||||
|
drivingCourseModified=[Waypoint(drivingCourse[1])]
|
||||||
|
for i in 2:energySavingStartId
|
||||||
|
push!(drivingCourseModified, Waypoint(drivingCourse[i])) # List of waypoints till the start of energy saving
|
||||||
|
end
|
||||||
|
|
||||||
|
# calculating the new length of the cruising section
|
||||||
|
if settings.stepVariable=="s in m" # distance step method
|
||||||
|
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).s_total-cruisingReduction
|
||||||
|
elseif settings.stepVariable=="t in s" # time step method
|
||||||
|
t_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).t_total-cruisingReduction
|
||||||
|
s_cruising=t_cruising*drivingCourseModified[end].v
|
||||||
|
elseif settings.stepVariable=="v in m/s" # velocity step method
|
||||||
|
s_cruising=get(csOriginal.behaviorSections, "cruising", BehaviorSection()).s_total-cruisingReduction*10 # TODO: or better: *100 ?
|
||||||
|
end #if
|
||||||
|
s_cruising=max(0.0, s_cruising)
|
||||||
|
|
||||||
|
# copying csOriginal to csModified
|
||||||
|
csModified=CharacteristicSection(csOriginal.id, csOriginal.s_total, csOriginal.s_start, csOriginal.s_end, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_reach, csOriginal.v_entry, csOriginal.v_exit, csOriginal.f_Rp, Dict{String, BehaviorSection}())
|
||||||
|
if haskey(csOriginal.behaviorSections, "starting")
|
||||||
|
startingSection=BehaviorSection(get(csOriginal.behaviorSections, "starting", BehaviorSection()))
|
||||||
|
merge!(csModified.behaviorSections, Dict("starting"=>startingSection))
|
||||||
|
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "starting", BehaviorSection()).E_total
|
||||||
|
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "starting", BehaviorSection()).t_total
|
||||||
|
end
|
||||||
|
if haskey(csOriginal.behaviorSections, "cruisingBeforeAcceleration") # this section is needed before acceleration if the mass strip model is used and if the vehicle wants to accelerate to a velocity higher than the limit in the other CS where parts of the union are still located
|
||||||
|
cruisingBeforeAccelerationSection=BehaviorSection(get(csOriginal.behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()))
|
||||||
|
merge!(csModified.behaviorSections, Dict("cruisingBeforeAcceleration"=>cruisingBeforeAccelerationSection))
|
||||||
|
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()).E_total
|
||||||
|
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()).t_total
|
||||||
|
end
|
||||||
|
if haskey(csOriginal.behaviorSections, "acceleration")
|
||||||
|
accelerationSection=BehaviorSection(get(csOriginal.behaviorSections, "acceleration", BehaviorSection()))
|
||||||
|
merge!(csModified.behaviorSections, Dict("acceleration"=>accelerationSection))
|
||||||
|
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "acceleration", BehaviorSection()).E_total
|
||||||
|
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "acceleration", BehaviorSection()).t_total
|
||||||
|
end
|
||||||
|
|
||||||
|
# calculating the new and now shorter cruising section
|
||||||
|
if s_cruising>0.0
|
||||||
|
(csModified, drivingCourseModified)=addCruisingPhase!(csModified, drivingCourseModified, s_cruising, settings, vehicle, allCSs, "cruising")
|
||||||
|
end
|
||||||
|
|
||||||
|
(csModified, drivingCourseModified)=addCoastingPhaseWithIntersection!(csModified, drivingCourseModified, settings, vehicle, allCSs)
|
||||||
|
|
||||||
|
if drivingCourseModified[end].v<csModified.v_exit || drivingCourseModified[end].s>csModified.s_end
|
||||||
|
# the vehicle reaches v_exit before reaching s_end. The cruising and coasting sections have to be calculated again with a larger cruising section (so with a smaller reduction of the cruising section)
|
||||||
|
cruisingReduction=cruisingReduction/10
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end # while cruisingReduction
|
||||||
|
|
||||||
|
if drivingCourseModified[end].v>csModified.v_exit
|
||||||
|
(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings.massModel, vehicle, allCSs)
|
||||||
|
elseif drivingCourseModified[end].v==csModified.v_exit && drivingCourseModified[end].s<csModified.s_end
|
||||||
|
# v_exit is already reached. Now cruising till the end of the CS
|
||||||
|
s_cruisingAfterCoasting=csModified.s_end-drivingCourseModified[end].s
|
||||||
|
(csModified, drivingCourseModified)=addCruisingPhase!(csModified, drivingCourseModified, s_cruisingAfterCoasting, settings, vehicle, allCSs, "cruisingAfterCoasting")
|
||||||
|
end
|
||||||
|
|
||||||
|
if t_recoveryAvailable<(csModified.t_total-csOriginal.t_total) || drivingCourseModified[end].v!=csModified.v_exit || drivingCourseModified[end].s!=csModified.s_end # time loss is to high and the CS has to be calculated again with larger cruising section (so with a smaller reduction of the cruising section) or v_exit or s_end are not reached excatly
|
||||||
|
cruisingReduction=cruisingReduction/10
|
||||||
|
else
|
||||||
|
return (csModified, drivingCourseModified, true)
|
||||||
|
end
|
||||||
|
end #while
|
||||||
|
# there is no energy saving modification for this CS with the available recovery time
|
||||||
|
return (CharacteristicSection(), [], false)
|
||||||
|
else
|
||||||
|
# there is no energy saving modification for this CS because a cruising section AND a braking section are needed to be transformed into a coasting section
|
||||||
|
return (CharacteristicSection(), [], false)
|
||||||
|
end
|
||||||
|
end # function increaseCostingSection
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# method 2 with shortening the acceleration by stepsize
|
||||||
|
function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse, settings::Settings, vehicle::Vehicle, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||||
|
#function decreaseMaximumVelocity(csOriginal::CharacteristicSection, drivingCourse::Vector{Waypoint}, settings::Settings, vehicle::Vehicle, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||||
|
if haskey(csOriginal.behaviorSections, "acceleration") && csOriginal.v_reach>csOriginal.v_entry && csOriginal.v_reach>csOriginal.v_exit
|
||||||
|
# instead of calculating the new final velocity of the acceleration phase with the step sizes for the different step variables, the velocity of the point before the last will be the new v_reach
|
||||||
|
# because it it easier at the moment (TODO)
|
||||||
|
lastIdOfOldAccelerationSection=get(csOriginal.behaviorSections, "acceleration", BehaviorSection()).waypoints[end]
|
||||||
|
accelerationReduction=drivingCourse[lastIdOfOldAccelerationSection].Δv # with step size it would be accelerationReduction=settings.stepSize
|
||||||
|
|
||||||
|
while accelerationReduction>=drivingCourse[lastIdOfOldAccelerationSection].Δv/100 # will be done once and repeated twice with smaller accelerationReduction unless t_recoveryAvailable>=(csModified.t_total-csOriginal.t_total) && 0.0<(csModified.t_total-csOriginal.t_total) -> see below at the end of the while loop
|
||||||
|
# copying csOriginal to csModified
|
||||||
|
csModified=CharacteristicSection(csOriginal.id, csOriginal.s_total, csOriginal.s_start, csOriginal.s_end, 0.0, 0.0, csOriginal.v_limit, csOriginal.v_reach, csOriginal.v_entry, csOriginal.v_exit, csOriginal.f_Rp, Dict{String, BehaviorSection}())
|
||||||
|
if haskey(csOriginal.behaviorSections, "starting")
|
||||||
|
startingSection=BehaviorSection(get(csOriginal.behaviorSections, "starting", BehaviorSection()))
|
||||||
|
merge!(csModified.behaviorSections, Dict("starting"=>startingSection))
|
||||||
|
csModified.E_total=csModified.E_total+get(csModified.behaviorSections, "starting", BehaviorSection()).E_total
|
||||||
|
csModified.t_total=csModified.t_total+get(csModified.behaviorSections, "starting", BehaviorSection()).t_total
|
||||||
|
end
|
||||||
|
|
||||||
|
# creating a drivingCourse for the characteristic section
|
||||||
|
energySavingStartId=get(csOriginal.behaviorSections, "cruisingBeforeAcceleration", get(csOriginal.behaviorSections, "acceleration", BehaviorSection())).waypoints[1]
|
||||||
|
|
||||||
|
drivingCourseModified=Vector{Waypoint}()
|
||||||
|
for i in 1:energySavingStartId
|
||||||
|
push!(drivingCourseModified, Waypoint(drivingCourse[i])) # List of waypoints till the start of energy saving
|
||||||
|
end
|
||||||
|
|
||||||
|
csModified.v_reach=max(csModified.v_entry, csModified.v_exit, csOriginal.v_reach-accelerationReduction)
|
||||||
|
|
||||||
|
# calculation of the new and now shorter acceleration section
|
||||||
|
if drivingCourseModified[end].v<csModified.v_reach
|
||||||
|
(csModified, drivingCourseModified)=addAccelerationPhase!(csModified, drivingCourseModified, settings, vehicle, allCSs)
|
||||||
|
end #if
|
||||||
|
# TODO: instead of copying the drivingCourse till the start of acceleration and calculating the acceleration again till the point before the last it would be possible to copy the drivingCouse until this point. Then it would not be necessary to calculate the accelerationPhase again. But then it is difficult to reduce accelerationReduction.
|
||||||
|
|
||||||
|
s_braking=max(0.0, ceil((csModified.v_exit^2-csModified.v_reach^2)/2/vehicle.a_braking, digits=10)) # ceil is used to be sure that the vehicle stops at s_end in spite of rounding errors
|
||||||
|
s_cruising=csModified.s_end-drivingCourseModified[end].s-s_braking
|
||||||
|
|
||||||
|
if s_cruising >0.001
|
||||||
|
(csModified, drivingCourseModified)=addCruisingPhase!(csModified, drivingCourseModified, s_cruising, settings, vehicle, allCSs, "cruising")
|
||||||
|
end #if
|
||||||
|
|
||||||
|
# s_brakingAfterCruising=ceil((csModified.v_exit^2-drivingCourseModified[end].v^2)/2/vehicle.a_braking, digits=10) # TODO: check if s_braking and s_brakingAfterCruising are really always the same
|
||||||
|
if drivingCourseModified[end].v>csModified.v_exit
|
||||||
|
(csModified, drivingCourseModified)=addBrakingPhase!(csModified, drivingCourseModified, settings.massModel, vehicle, allCSs)
|
||||||
|
elseif drivingCourseModified[end].s<csModified.s_end
|
||||||
|
if (csModified.s_end-drivingCourseModified[end].s)>0.001
|
||||||
|
println("WARNING: The end of new CS",csModified.id," is not reached while saving energy with lowering v_reach.")
|
||||||
|
println(" Therefore s=",drivingCourseModified[end].s," will be set s_end=",csModified.s_end," because the difference is only ",csModified.s_end-drivingCourseModified[end].s," m.")
|
||||||
|
end
|
||||||
|
drivingCourseModified[end].s=csModified.s_end # rounding up to s_end
|
||||||
|
end #if
|
||||||
|
|
||||||
|
if t_recoveryAvailable>=(csModified.t_total-csOriginal.t_total)
|
||||||
|
return (csModified, drivingCourseModified, true)
|
||||||
|
else # time loss is to high and the CS has to be calculated again with larger acceleration section (so with a smaller reduction of the acceleration section)
|
||||||
|
accelerationReduction=min(accelerationReduction/10, csModified.v_reach-csModified.v_entry, csModified.v_reach-csModified.v_exit)
|
||||||
|
end
|
||||||
|
end #while
|
||||||
|
|
||||||
|
# there is no energy saving modification for this CS with the available recovery time
|
||||||
|
return (CharacteristicSection(), [], false)
|
||||||
|
|
||||||
|
else
|
||||||
|
# there is no energy saving modification for this CS because v_reach can not be lowered below v_entry or v_exit or because there is no acceleration section that can be transformed into a cruising section
|
||||||
|
return (CharacteristicSection(), [], false)
|
||||||
|
end #if haskey
|
||||||
|
end # function decreaseMaximumVelocity
|
||||||
|
|
||||||
|
# combination of method 1 and method 2
|
||||||
|
function combineEnergySavingMethods(csOriginal::CharacteristicSection, drivingCourse::Vector{Waypoint}, settings::Settings, vehicle::Vehicle, allCSs::Vector{CharacteristicSection}, t_recoveryAvailable::AbstractFloat)
|
||||||
|
if haskey(csOriginal.behaviorSections, "acceleration") && (haskey(csOriginal.behaviorSections, "braking") || haskey(csOriginal.behaviorSections, "coasting")) && csOriginal.v_reach>csOriginal.v_entry && csOriginal.v_reach>csOriginal.v_exit
|
||||||
|
csCombined=CharacteristicSection(csOriginal)
|
||||||
|
drivingCourseCombined=Vector{Waypoint}()
|
||||||
|
for i in 1:length(drivingCourse)
|
||||||
|
push!(drivingCourseCombined, Waypoint(drivingCourse[i]))
|
||||||
|
end
|
||||||
|
ΔE=0.0 # saved energy (in Ws)
|
||||||
|
Δt=0.0 # time loss (in s)
|
||||||
|
while (Δt<t_recoveryAvailable && ΔE<=0.0)
|
||||||
|
(csCombined, drivingCourseCombined, newMaximumVelocity)=decreaseMaximumVelocity(csCombined, drivingCourseCombined, settings, vehicle, allCSs, t_recoveryAvailable)
|
||||||
|
if newMaximumVelocity
|
||||||
|
ΔE=csOriginal.E_total-csCombined.E_total # saved energy (in Ws)
|
||||||
|
Δt=csCombined.t_total-csOriginal.t_total # time loss (in s)
|
||||||
|
|
||||||
|
while (haskey(csOriginal.behaviorSections, "cruising") && (Δt<=0.0 || ΔE<=0.0)) #Δt<=0.0) #&& ΔE<=0.0) # && Δt<=0.0)
|
||||||
|
(csCombined, drivingCourseCombined, newCoasting)=increaseCostingSection(csCombined, drivingCourseCombined, settings, vehicle, allCSs, t_recoveryAvailable-Δt)
|
||||||
|
if newCoasting
|
||||||
|
ΔE=csOriginal.E_total-csCombined.E_total # saved energy (in Ws)
|
||||||
|
Δt=csCombined.t_total-csOriginal.t_total # time loss (in s)
|
||||||
|
else
|
||||||
|
break
|
||||||
|
end # if newCoasting
|
||||||
|
end # while haskey
|
||||||
|
else
|
||||||
|
return (CharacteristicSection(), [], false)
|
||||||
|
end # if newMaximumVelocity
|
||||||
|
end # while
|
||||||
|
return (csCombined, drivingCourseCombined, (ΔE>0.0))# && Δt>0.0))
|
||||||
|
else
|
||||||
|
# there is no energy saving modification for this CS because v_reach can not be lowered below v_entry or v_exit or because there is no acceleration section and braking section or coasting section that can be transformed into a cruising section or coasting section
|
||||||
|
return (CharacteristicSection(), [], false)
|
||||||
|
end #if
|
||||||
|
end #function combineEnergySavingMethods
|
||||||
|
|
||||||
|
end #module RailwayDrivingDynamicsEnergySaving
|
|
@ -0,0 +1,600 @@
|
||||||
|
module RailwayDrivingDynamicsInput
|
||||||
|
|
||||||
|
import YAML
|
||||||
|
using ..types
|
||||||
|
|
||||||
|
export readInput
|
||||||
|
|
||||||
|
function readInput(vehicleFilePath::String, pathFilePath::String, settingsFilePath::String)
|
||||||
|
# this function reads the input information from YAML files, saves it in a different objects and returns them
|
||||||
|
vehicle=inputVehicle(vehicleFilePath)
|
||||||
|
path=inputPath(pathFilePath)
|
||||||
|
settings=inputSettings(settingsFilePath)
|
||||||
|
|
||||||
|
return (vehicle, path, settings)
|
||||||
|
end #function readInput
|
||||||
|
|
||||||
|
|
||||||
|
function inputVehicle(vehicleFilePath::String)
|
||||||
|
# this function reads vehicle information from a YAML file, saves it in a Vehicle object and returns it
|
||||||
|
data = YAML.load(open(vehicleFilePath))
|
||||||
|
collect(keys(data))
|
||||||
|
collect(values(data))
|
||||||
|
|
||||||
|
vehicle=Vehicle()
|
||||||
|
if haskey(data["vehicle"],"name")
|
||||||
|
vehicle.name=data["vehicle"]["name"] # vehicles name
|
||||||
|
delete!(data["vehicle"], "name")
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The keyword name is missing. It has to be added.")
|
||||||
|
end
|
||||||
|
vehicle.id=1 # vehicles identifier
|
||||||
|
|
||||||
|
if haskey(data["vehicle"],"vehicleType")
|
||||||
|
if typeof(data["vehicle"]["vehicleType"])==String && (data["vehicle"]["vehicleType"]=="freight" || data["vehicle"]["vehicleType"]=="motor coach train" || data["vehicle"]["vehicleType"]=="passenger")
|
||||||
|
vehicle.vehicleType=data["vehicle"]["vehicleType"] # "passenger" or "freight" or "motor coach train"
|
||||||
|
delete!(data["vehicle"], "vehicleType")
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The value of vehicleType is wrong. It has to be freight, motor coach train or passenger.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The keyword vehicleType is missing. It has to be added with the value freight, motor coach train or passenger.")
|
||||||
|
end
|
||||||
|
|
||||||
|
if haskey(data["vehicle"],"l_union")
|
||||||
|
if typeof(data["vehicle"]["l_union"])==Float64 && data["vehicle"]["l_union"]>0.0
|
||||||
|
vehicle.l_union=data["vehicle"]["l_union"] # total length (in m)
|
||||||
|
delete!(data["vehicle"], "l_union")
|
||||||
|
elseif typeof(data["vehicle"]["l_union"])==Int64 && data["vehicle"]["l_union"]>0
|
||||||
|
vehicle.l_union=convert(AbstractFloat, data["vehicle"]["l_union"]) # total length (in m)
|
||||||
|
delete!(data["vehicle"], "l_union")
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The value of the length is no real floating point number >0.0.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The keyword length is missing. It has to be added with a value of type real floating point number >0.0.")
|
||||||
|
end
|
||||||
|
|
||||||
|
# speed limit: # vehicles speed limit (in m/s)
|
||||||
|
if haskey(data["vehicle"],"v_limit") && haskey(data["vehicle"],"v_limit_kmh")
|
||||||
|
if data["vehicle"]["v_limit"]!=nothing
|
||||||
|
if typeof(data["vehicle"]["v_limit"])==Float64 && data["vehicle"]["v_limit"]>0.0
|
||||||
|
vehicle.v_limit=data["vehicle"]["v_limit"] # vehicles speed limit (in m/s)
|
||||||
|
delete!(data["vehicle"], "v_limit")
|
||||||
|
elseif typeof(data["vehicle"]["v_limit"])==Int64 && data["vehicle"]["v_limit"]>0
|
||||||
|
vehicle.v_limit=convert(AbstractFloat, data["vehicle"]["v_limit"]) # vehicles speed limit (in m/s)
|
||||||
|
delete!(data["vehicle"], "v_limit")
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The value of v_limit is no real floating point number >0.0.")
|
||||||
|
end
|
||||||
|
|
||||||
|
if data["vehicle"]["v_limit_kmh"]!=nothing
|
||||||
|
v_limit_kmh=data["vehicle"]["v_limit_kmh"]
|
||||||
|
if abs(vehicle.v_limit-v_limit_kmh/3.6)>0.001
|
||||||
|
println("WARNING: at reading the vehicle yaml file: The values of v_limit and v_limit_kmh differ by more than 0.001 m/s. The value v_limit=",vehicle.v_limit," m/s is used." )
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif data["vehicle"]["v_limit_kmh"]!=nothing
|
||||||
|
if typeof(data["vehicle"]["v_limit_kmh"])==Float64 && data["vehicle"]["v_limit_kmh"]>0.0
|
||||||
|
vehicle.v_limit=data["vehicle"]["v_limit_kmh"]/3.6 # vehicles speed limit (from km/h to m/s)
|
||||||
|
elseif typeof(data["vehicle"]["v_limit_kmh"])==Int64 && data["vehicle"]["v_limit_kmh"]>0
|
||||||
|
vehicle.v_limit=convert(AbstractFloat, data["vehicle"]["v_limit_kmh"])/3.6 # vehicles speed limit (from km/h to m/s)
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The value of the v_limit_kmh is no real floating point number >0.0.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
vehicle.v_limit=1000/3.6
|
||||||
|
println("WARNING at reading the vehicle yaml file: There is no value for v_limit. The value v_limit=1000 km/h =",vehicle.v_limit," m/s is used." )
|
||||||
|
end # if
|
||||||
|
elseif haskey(data["vehicle"],"v_limit")
|
||||||
|
if typeof(data["vehicle"]["v_limit"])==Float64 && data["vehicle"]["v_limit"]>0.0
|
||||||
|
vehicle.v_limit=data["vehicle"]["v_limit"] # vehicles speed limit (in m/s)
|
||||||
|
elseif typeof(data["vehicle"]["v_limit"])==Int64 && data["vehicle"]["v_limit"]>0
|
||||||
|
vehicle.v_limit=convert(AbstractFloat, data["vehicle"]["v_limit"]) # vehicles speed limit (in m/s)
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The value of v_limit is no real floating point number >0.0.")
|
||||||
|
end
|
||||||
|
elseif haskey(data["vehicle"],"v_limit_kmh")
|
||||||
|
if typeof(data["vehicle"]["v_limit_kmh"])==Float64 && data["vehicle"]["v_limit_kmh"]>0.0
|
||||||
|
vehicle.v_limit=data["vehicle"]["v_limit_kmh"]/3.6 # vehicles speed limit (from km/h to m/s)
|
||||||
|
elseif typeof(data["vehicle"]["v_limit_kmh"])==Int64 && data["vehicle"]["v_limit_kmh"]>0
|
||||||
|
vehicle.v_limit=convert(AbstractFloat, data["vehicle"]["v_limit_kmh"])/3.6 # vehicles speed limit (from km/h to m/s)
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The value of v_limit_kmh is no real floating point number >0.0.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The keyword v_limit or v_limit_kmh is missing. It has to be added with a value of type real floating point number >0.0.")
|
||||||
|
end
|
||||||
|
delete!(data["vehicle"], "v_limit")
|
||||||
|
delete!(data["vehicle"], "v_limit_kmh")
|
||||||
|
|
||||||
|
|
||||||
|
# a_braking
|
||||||
|
if haskey(data["vehicle"],"a_braking")
|
||||||
|
if typeof(data["vehicle"]["a_braking"])==Float64
|
||||||
|
vehicle.a_braking=data["vehicle"]["a_braking"]
|
||||||
|
elseif typeof(data["vehicle"]["a_braking"])==Int64
|
||||||
|
vehicle.a_braking=convert(AbstractFloat, data["vehicle"]["a_braking"])
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The value of the a_braking is no real floating point number <0.0.")
|
||||||
|
end
|
||||||
|
delete!(data["vehicle"], "a_braking")
|
||||||
|
|
||||||
|
if vehicle.a_braking > 0.0
|
||||||
|
vehicle.a_braking =-vehicle.a_braking
|
||||||
|
println("WARNING at reading the vehicle yaml file: The value for a_braking is >0.0. The braking acceleration has to be <0.0. Therefore a_braking =",vehicle.a_braking," m/s^2 is used." )
|
||||||
|
elseif vehicle.a_braking == 0.0
|
||||||
|
error("ERROR at reading the vehicle yaml file: The value for a_braking is 0.0. The braking acceleration has to be <0.0.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The keyword a_braking is missing. It has to be added with a value of type real floating point number <0.0.")
|
||||||
|
end
|
||||||
|
|
||||||
|
# mass on the traction units driving axles (in kg)
|
||||||
|
if haskey(data["vehicle"],"m_td")
|
||||||
|
if typeof(data["vehicle"]["m_td"])==Float64 && data["vehicle"]["m_td"]>0.0
|
||||||
|
vehicle.m_td=data["vehicle"]["m_td"]
|
||||||
|
elseif typeof(data["vehicle"]["m_td"])==Int64 && data["vehicle"]["m_td"]>0
|
||||||
|
vehicle.m_td=convert(AbstractFloat, data["vehicle"]["m_td"])
|
||||||
|
delete!(data["vehicle"], "m_td")
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The value of m_td is no real floating point number >0.0.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The keyword m_td is missing. It has to be added with a value of type real floating point number >0.0.")
|
||||||
|
end
|
||||||
|
delete!(data["vehicle"], "m_td")
|
||||||
|
|
||||||
|
|
||||||
|
# mass on the traction units carrying axles (in kg)
|
||||||
|
if haskey(data["vehicle"],"m_tc")
|
||||||
|
if typeof(data["vehicle"]["m_tc"])==Float64 && data["vehicle"]["m_tc"]>=0.0
|
||||||
|
vehicle.m_tc=data["vehicle"]["m_tc"]
|
||||||
|
elseif typeof(data["vehicle"]["m_tc"])==Int64 && data["vehicle"]["m_tc"]>=0
|
||||||
|
vehicle.m_tc=convert(AbstractFloat, data["vehicle"]["m_tc"])
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The value of m_tc is no real floating point number >=0.0.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The keyword m_tc is missing. It has to be added with a value of type real floating point number >=0.0.")
|
||||||
|
end
|
||||||
|
delete!(data["vehicle"], "m_tc")
|
||||||
|
|
||||||
|
# mass of the traction unit (in kg)
|
||||||
|
vehicle.m_t=vehicle.m_td+vehicle.m_tc
|
||||||
|
|
||||||
|
|
||||||
|
# mass of theconsist (set of wagons) (in kg)
|
||||||
|
if haskey(data["vehicle"],"m_w")
|
||||||
|
if typeof(data["vehicle"]["m_w"])==Float64 && data["vehicle"]["m_w"]>=0.0
|
||||||
|
vehicle.m_w=data["vehicle"]["m_w"]
|
||||||
|
elseif typeof(data["vehicle"]["m_w"])==Int64 && data["vehicle"]["m_w"]>=0
|
||||||
|
vehicle.m_w=convert(AbstractFloat, data["vehicle"]["m_w"])
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The value of m_w is no real floating point number >=0.0.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
vehicle.m_w=0.0
|
||||||
|
println("WARNING at reading the vehicle yaml file: The keyword m_w is missing. Therefore m_w =",vehicle.m_w," kg is used.")
|
||||||
|
end
|
||||||
|
delete!(data["vehicle"], "m_w")
|
||||||
|
|
||||||
|
# total mass (in kg)
|
||||||
|
vehicle.m_union=vehicle.m_t+vehicle.m_w
|
||||||
|
|
||||||
|
if haskey(data["vehicle"],"rotationMassFactor_union") && (typeof(data["vehicle"]["rotationMassFactor_union"])==Float64 || typeof(data["vehicle"]["rotationMassFactor_union"])==Int64)
|
||||||
|
if typeof(data["vehicle"]["rotationMassFactor_union"])==Float64 && data["vehicle"]["rotationMassFactor_union"]>0.0
|
||||||
|
vehicle.ξ_union=data["vehicle"]["rotationMassFactor_union"]
|
||||||
|
elseif typeof(data["vehicle"]["rotationMassFactor_union"])==Int64 && data["vehicle"]["rotationMassFactor_union"]>0
|
||||||
|
vehicle.ξ_union=convert(AbstractFloat, data["vehicle"]["rotationMassFactor_union"])
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The value of rotationMassFactor_union is no real floating point number >0.0.")
|
||||||
|
end
|
||||||
|
elseif haskey(data["vehicle"],"rotationMassFactor_t") && (typeof(data["vehicle"]["rotationMassFactor_t"])==Float64 || typeof(data["vehicle"]["rotationMassFactor_t"])==Int64) && (vehicle.m_w==0.0 || haskey(data["vehicle"],"rotationMassFactor_w") && (typeof(data["vehicle"]["rotationMassFactor_w"])==Float64 || typeof(data["vehicle"]["rotationMassFactor_w"])==Int64))
|
||||||
|
if typeof(data["vehicle"]["rotationMassFactor_t"])==Float64 && data["vehicle"]["rotationMassFactor_t"]>0.0
|
||||||
|
vehicle.ξ_t=data["vehicle"]["rotationMassFactor_t"]
|
||||||
|
elseif typeof(data["vehicle"]["rotationMassFactor_t"])==Int64 && data["vehicle"]["rotationMassFactor_t"]>0
|
||||||
|
vehicle.ξ_t=convert(AbstractFloat, data["vehicle"]["rotationMassFactor_t"])
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The value of rotationMassFactor_t is no real floating point number >0.0.")
|
||||||
|
end
|
||||||
|
if vehicle.m_w>0.0
|
||||||
|
if typeof(data["vehicle"]["rotationMassFactor_w"])==Float64 && data["vehicle"]["rotationMassFactor_w"]>=0.0
|
||||||
|
vehicle.ξ_w=data["vehicle"]["rotationMassFactor_w"]
|
||||||
|
elseif typeof(data["vehicle"]["rotationMassFactor_w"])==Int64 && data["vehicle"]["rotationMassFactor_w"]>=0
|
||||||
|
vehicle.ξ_w=convert(AbstractFloat, data["vehicle"]["rotationMassFactor_w"])
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The value of rotationMassFactor_w is no real floating point number >=0.0.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
vehicle.ξ_w=0.0
|
||||||
|
end
|
||||||
|
vehicle.ξ_union=(vehicle.ξ_t*vehicle.m_t + vehicle.ξ_w*vehicle.m_w)/vehicle.m_union # rotation mass factor of the whole vehicle (without unit)
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The keywords rotationMassFactor_union or rotationMassFactor_t and rotationMassFactor_w are missing. They has to be added with a value of type real floating point number.")
|
||||||
|
end
|
||||||
|
delete!(data["vehicle"], "rotationMassFactor_union")
|
||||||
|
delete!(data["vehicle"], "rotationMassFactor_t")
|
||||||
|
delete!(data["vehicle"], "rotationMassFactor_w")
|
||||||
|
|
||||||
|
|
||||||
|
# input for function tractiveEffort(v)
|
||||||
|
# TODO: The types of the lists elements can be checked and the user can get warnings or error messages
|
||||||
|
# TODO: What if there are values in F_T_pairs and in F_T_pairs_kmh. That should be checked and the user should be informed
|
||||||
|
# TODO: It could be checked if all the array elements are correct.
|
||||||
|
if haskey(data["vehicle"],"F_T_pairs") && data["vehicle"]["F_T_pairs"]!=nothing
|
||||||
|
F_T_pairs=data["vehicle"]["F_T_pairs"]
|
||||||
|
vehicle.tractiveEffortArray=[]
|
||||||
|
if F_T_pairs[1][1]==0.0
|
||||||
|
push!(vehicle.tractiveEffortArray, [F_T_pairs[1][1], F_T_pairs[1][1], F_T_pairs[1][2]])
|
||||||
|
elseif F_T_pairs[1][1]>0.0 # if there is no F_T for v=0.0, the first value is used
|
||||||
|
push!(vehicle.tractiveEffortArray, [0.0, F_T_pairs[1][1]/3.6, F_T_pairs[1][2]])
|
||||||
|
println("WARNING at reading the vehicle yaml file: The tractive effort for v=0 m/s is missing. Therefore the first given value F_T(v=",F_T_pairs[1][1]," m/s)=",F_T_pairs[1][2]," N will be used." )
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: There is a negative speed value in the list. Only positive values for speed and tractive effort are allowed. ")
|
||||||
|
end
|
||||||
|
for row in 2:length(F_T_pairs)
|
||||||
|
if F_T_pairs[row][1]>F_T_pairs[row-1][1]
|
||||||
|
if F_T_pairs[row][2]==vehicle.tractiveEffortArray[end][3]
|
||||||
|
vehicle.tractiveEffortArray[end][2]=F_T_pairs[row][1]
|
||||||
|
else
|
||||||
|
push!(vehicle.tractiveEffortArray, [F_T_pairs[row][1], F_T_pairs[row][1], F_T_pairs[row][2]])
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The F_T_pairs are not in the correct order. They have to be arranged by speed values from low to high.")
|
||||||
|
end
|
||||||
|
end # for
|
||||||
|
if length(F_T_pairs[1])>2
|
||||||
|
println("INFO according the vehicle yaml file: Only the first two columns of F_T_pairs are used in this tool.")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
elseif haskey(data["vehicle"],"F_T_pairs_kmh") && data["vehicle"]["F_T_pairs_kmh"]!=nothing
|
||||||
|
F_T_pairs_kmh=data["vehicle"]["F_T_pairs_kmh"]
|
||||||
|
vehicle.tractiveEffortArray=[]
|
||||||
|
if F_T_pairs_kmh[1][1]==0.0
|
||||||
|
push!(vehicle.tractiveEffortArray, [F_T_pairs_kmh[1][1]/3.6, F_T_pairs_kmh[1][1]/3.6, F_T_pairs_kmh[1][2]])
|
||||||
|
elseif F_T_pairs_kmh[1][1]>0.0 # if there is no F_T for v=0.0, the first value is used
|
||||||
|
push!(vehicle.tractiveEffortArray, [0.0, F_T_pairs_kmh[1][1]/3.6, F_T_pairs_kmh[1][2]])
|
||||||
|
println("WARNING at reading the vehicle yaml file: The tractive effort for v=0 km/h is missing. Therefore the first given value F_T(v=",F_T_pairs_kmh[1][1]," km/h)=",F_T_pairs_kmh[1][2]," N will be used." )
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: There is a negative speed value in the list. Only positive values for speed and tractive effort are allowed. ")
|
||||||
|
end
|
||||||
|
for row in 2:length(F_T_pairs_kmh)
|
||||||
|
if F_T_pairs_kmh[row][1]>F_T_pairs_kmh[row-1][1]
|
||||||
|
if F_T_pairs_kmh[row][2]==vehicle.tractiveEffortArray[end][3]
|
||||||
|
vehicle.tractiveEffortArray[end][2]=F_T_pairs_kmh[row][1]/3.6
|
||||||
|
else
|
||||||
|
push!(vehicle.tractiveEffortArray, [F_T_pairs_kmh[row][1]/3.6, F_T_pairs_kmh[row][1]/3.6, F_T_pairs_kmh[row][2]])
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The F_T_pairs_kmh are not in the correct order. They have to be arranged by speed values from low to high.")
|
||||||
|
end
|
||||||
|
end # for
|
||||||
|
if length(F_T_pairs_kmh[1])>2
|
||||||
|
println("INFO at reading the vehicle yaml file: Only the first two columns of F_T_pairs_kmh are used in this tool.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: There has to be one of the keywords F_T_pairs or F_T_pairs_kmh filled with a list of pairs of velocity and tractive effort.")
|
||||||
|
end # if
|
||||||
|
delete!(data["vehicle"], "F_T_pairs")
|
||||||
|
delete!(data["vehicle"], "F_T_pairs_kmh")
|
||||||
|
|
||||||
|
|
||||||
|
# coefficients for the vehicle resistance of the traction unit
|
||||||
|
vehicle.Δv_t=15.0/3.6 # coefficient for velocitiy difference between traction unit and outdoor air
|
||||||
|
|
||||||
|
# coefficient for basic resistance due to the traction units driving axles (in ‰)
|
||||||
|
if haskey(data["vehicle"],"f_Rtd0") && data["vehicle"]["f_Rtd0"]!=nothing
|
||||||
|
if typeof(data["vehicle"]["f_Rtd0"])==Float64 && data["vehicle"]["f_Rtd0"]>=0.0
|
||||||
|
vehicle.f_Rtd0=data["vehicle"]["f_Rtd0"]
|
||||||
|
elseif typeof(data["vehicle"]["f_Rtd0"])==Int64 && data["vehicle"]["f_Rtd0"]>=0
|
||||||
|
vehicle.f_Rtd0=convert(AbstractFloat, data["vehicle"]["f_Rtd0"])
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The value of f_Rtd0 is no real floating point number >=0.0.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
vehicle.f_Rtd0=0.0
|
||||||
|
println("WARNING at reading the vehicle yaml file: The keyword f_Rtd0 is missing. Therefore f_Rtd0=0.0 ‰ will be assumed and used." )
|
||||||
|
end
|
||||||
|
delete!(data["vehicle"], "f_Rtd0")
|
||||||
|
|
||||||
|
# coefficient for basic resistance due to the traction units carring axles (in ‰)
|
||||||
|
if haskey(data["vehicle"],"f_Rtc0") && data["vehicle"]["f_Rtc0"]!=nothing
|
||||||
|
if typeof(data["vehicle"]["f_Rtc0"])==Float64 && data["vehicle"]["f_Rtc0"]>=0.0
|
||||||
|
vehicle.f_Rtc0=data["vehicle"]["f_Rtc0"]
|
||||||
|
elseif typeof(data["vehicle"]["f_Rtc0"])==Int64 && data["vehicle"]["f_Rtc0"]>=0
|
||||||
|
vehicle.f_Rtc0=convert(AbstractFloat, data["vehicle"]["f_Rtc0"])
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The value of f_Rtc0 is no real floating point number >=0.0.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
vehicle.f_Rtc0=0.0
|
||||||
|
println("WARNING at reading the vehicle yaml file: The keyword f_Rtc0 is missing. Therefore f_Rtc0=0.0 ‰ will be assumed and used." )
|
||||||
|
end
|
||||||
|
delete!(data["vehicle"], "f_Rtc0")
|
||||||
|
|
||||||
|
# coefficient for air resistance of the traction units (in N)
|
||||||
|
if haskey(data["vehicle"],"F_Rt2") && data["vehicle"]["F_Rt2"]!=nothing
|
||||||
|
if typeof(data["vehicle"]["F_Rt2"])==Float64 && data["vehicle"]["F_Rt2"]>=0.0
|
||||||
|
vehicle.F_Rt2=data["vehicle"]["F_Rt2"]
|
||||||
|
elseif typeof(data["vehicle"]["F_Rt2"])==Int64 && data["vehicle"]["F_Rt2"]>=0
|
||||||
|
vehicle.F_Rt2=convert(AbstractFloat, data["vehicle"]["F_Rt2"])
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The value of F_Rt2 is no real floating point number >=0.0.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
vehicle.F_Rt2=0.0
|
||||||
|
println("WARNING at reading the vehicle yaml file: The keyword F_Rt2 is missing. Therefore F_Rt2=0.0 N will be assumed and used." )
|
||||||
|
end
|
||||||
|
delete!(data["vehicle"], "F_Rt2")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# coefficients for the vehicle resistance of the consist (set of wagons)
|
||||||
|
# coefficient for velocitiy difference betweenconsist (set of wagons) and outdoor air (in m/s)
|
||||||
|
if vehicle.vehicleType=="passenger" || vehicle.vehicleType=="motor coach train"
|
||||||
|
vehicle.Δv_w=15.0/3.6
|
||||||
|
elseif vehicle.vehicleType== "freight"
|
||||||
|
vehicle.Δv_w=0.0
|
||||||
|
end # if
|
||||||
|
|
||||||
|
# coefficient for basic resistance of theconsist (set of wagons) (in ‰)
|
||||||
|
if haskey(data["vehicle"],"f_Rw0") && data["vehicle"]["f_Rw0"]!=nothing
|
||||||
|
if typeof(data["vehicle"]["f_Rw0"])==Float64 && data["vehicle"]["f_Rw0"]>=0.0
|
||||||
|
vehicle.f_Rw0=data["vehicle"]["f_Rw0"]
|
||||||
|
elseif typeof(data["vehicle"]["f_Rw0"])==Int64 && data["vehicle"]["f_Rw0"]>=0
|
||||||
|
vehicle.f_Rw0=convert(AbstractFloat, data["vehicle"]["f_Rw0"])
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The value of f_Rw0 is no real floating point number >=0.0.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
vehicle.f_Rw0=0.0
|
||||||
|
println("WARNING at reading the vehicle yaml file: The keyword f_Rw0 is missing. Therefore f_Rw0=0.0 ‰ will be assumed and used." )
|
||||||
|
end
|
||||||
|
delete!(data["vehicle"], "f_Rw0")
|
||||||
|
|
||||||
|
# coefficient for basic resistance of theconsist (set of wagons) (in ‰)
|
||||||
|
if haskey(data["vehicle"],"f_Rw1") && data["vehicle"]["f_Rw1"]!=nothing
|
||||||
|
if typeof(data["vehicle"]["f_Rw1"])==Float64 && data["vehicle"]["f_Rw1"]>=0.0
|
||||||
|
vehicle.f_Rw1=data["vehicle"]["f_Rw1"]
|
||||||
|
elseif typeof(data["vehicle"]["f_Rw1"])==Int64 && data["vehicle"]["f_Rw1"]>=0
|
||||||
|
vehicle.f_Rw1=convert(AbstractFloat, data["vehicle"]["f_Rw1"])
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The value of f_Rw1 is no real floating point number >=0.0.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
vehicle.f_Rw1=0.0
|
||||||
|
println("WARNING at reading the vehicle yaml file: The keyword f_Rw1 is missing. Therefore f_Rw1=0.0 ‰ will be assumed and used." )
|
||||||
|
end
|
||||||
|
delete!(data["vehicle"], "f_Rw1")
|
||||||
|
|
||||||
|
# coefficient for basic resistance of the consist (set of wagons) (in ‰)
|
||||||
|
if haskey(data["vehicle"],"f_Rw2") && data["vehicle"]["f_Rw2"]!=nothing
|
||||||
|
if typeof(data["vehicle"]["f_Rw2"])==Float64 && data["vehicle"]["f_Rw2"]>=0.0
|
||||||
|
vehicle.f_Rw2=data["vehicle"]["f_Rw2"]
|
||||||
|
elseif typeof(data["vehicle"]["f_Rw2"])==Int64 && data["vehicle"]["f_Rw2"]>=0
|
||||||
|
vehicle.f_Rw2=convert(AbstractFloat, data["vehicle"]["f_Rw2"])
|
||||||
|
else
|
||||||
|
error("ERROR at reading the vehicle yaml file: The value of f_Rw2 is no real floating point number >=0.0.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
vehicle.f_Rw2=0.0
|
||||||
|
println("WARNING at reading the vehicle yaml file: The keyword f_Rw2 is missing. Therefore f_Rw2=0.0 ‰ will be assumed and used." )
|
||||||
|
end
|
||||||
|
delete!(data["vehicle"], "f_Rw2")
|
||||||
|
|
||||||
|
|
||||||
|
# informing the user, which keywords of the input data are not used in this tool:
|
||||||
|
if length(data["vehicle"])>0
|
||||||
|
println("INFO at reading the vehicle yaml file: The following Keywords are not used in this tool:")
|
||||||
|
for key in keys(data["vehicle"])
|
||||||
|
println(" - ",key)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return vehicle
|
||||||
|
end #function inputVehicle
|
||||||
|
|
||||||
|
|
||||||
|
function inputPath(pathFilePath::String)
|
||||||
|
# this function reads path information from a YAML file, saves it in a Path object and returns it
|
||||||
|
data = YAML.load(open(pathFilePath))
|
||||||
|
collect(keys(data))
|
||||||
|
collect(values(data))
|
||||||
|
|
||||||
|
|
||||||
|
if haskey(data["path"],"name") && data["path"]["name"]!=nothing
|
||||||
|
name=data["path"]["name"] # path name
|
||||||
|
else
|
||||||
|
error("ERROR at reading the path yaml file: The keyword name is missing. It has to be added.")
|
||||||
|
end
|
||||||
|
delete!(data["path"], "name")
|
||||||
|
|
||||||
|
id=1 # path identifier
|
||||||
|
path=Path(name, id, [])
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: It could be checked if all the array elements are correct.
|
||||||
|
# TODO: The types of the lists elements can be checked and the user can get warnings or error messages
|
||||||
|
# TODO: What if there are values in sectionStarts and in sectionStarts_kmh? The user should be informed
|
||||||
|
if haskey(data["path"],"sectionStarts") && data["path"]["sectionStarts"]!=nothing
|
||||||
|
sectionStartsArray=data["path"]["sectionStarts"]
|
||||||
|
conversionFactor=1.0 # conversion factor between the units m/s and m/s
|
||||||
|
elseif haskey(data["path"],"sectionStarts_kmh") && data["path"]["sectionStarts_kmh"]!=nothing
|
||||||
|
sectionStartsArray=data["path"]["sectionStarts_kmh"]
|
||||||
|
conversionFactor=1/3.6 # conversion factor between the units km/h and m/s
|
||||||
|
else
|
||||||
|
error("ERROR at reading the path yaml file: The keyword sectionStarts oder sectionStarts_kmh is missing. It has to be added.")
|
||||||
|
end # if
|
||||||
|
delete!(data["path"], "sectionStarts")
|
||||||
|
delete!(data["path"], "sectionStarts_kmh")
|
||||||
|
|
||||||
|
if length(sectionStartsArray)>=2
|
||||||
|
if length(sectionStartsArray[1])>=3
|
||||||
|
for row in 2:length(sectionStartsArray)
|
||||||
|
s_start=sectionStartsArray[row-1][1] # starting point of the section (in m)
|
||||||
|
s_startNext=sectionStartsArray[row][1] # starting point of the next section (in m)
|
||||||
|
if s_startNext<s_start
|
||||||
|
error("ERROR at reading the path yaml file: The keyword sectionStartsArray needs to be filled with the three columns [s, v_limit, gradient].")
|
||||||
|
end
|
||||||
|
v_limit=sectionStartsArray[row-1][2]*conversionFactor # paths speed limt (in m/s)
|
||||||
|
n=sectionStartsArray[row-1][3] # gradient (in ‰)
|
||||||
|
f_Rp=n # specific path resistance of the section (in ‰)
|
||||||
|
section=PathSection(s_start, s_startNext, v_limit, n, f_Rp)
|
||||||
|
push!(path.sections, section)
|
||||||
|
end # for
|
||||||
|
if length(sectionStartsArray[1])>3
|
||||||
|
println("INFO at reading the path yaml file: Only the first three columns of sectionStartsArray are used in this tool.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("ERROR at reading the path yaml file: The keyword sectionStartsArray needs to be filled with the three columns [s, v_limit, gradient].")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("ERROR at reading the path yaml file: The keyword sectionStartsArray needs at least two rows for two points each with the three columns [s, v_limit, gradient].")
|
||||||
|
end
|
||||||
|
|
||||||
|
# informing the user, which keywords of the input data are not used in this tool:
|
||||||
|
if length(data["path"])>0
|
||||||
|
println("INFO at reading the path yaml file: The following Keywords are not used in this tool:")
|
||||||
|
for key in keys(data["path"])
|
||||||
|
println(" - ",key)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return path
|
||||||
|
end # function inputPath
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function inputSettings(settingsFilePath::String)
|
||||||
|
# this function reads setting information from a YAML file, saves it in a Setting object and returns it
|
||||||
|
data = YAML.load(open(settingsFilePath))
|
||||||
|
collect(keys(data))
|
||||||
|
collect(values(data))
|
||||||
|
|
||||||
|
settings=Settings()
|
||||||
|
|
||||||
|
# model type of the unions mass "mass point" or "homogeneous strip"
|
||||||
|
if haskey(data["settings"],"massModel")
|
||||||
|
if typeof(data["settings"]["massModel"])==String && (data["settings"]["massModel"]=="mass point" || data["settings"]["massModel"]=="homogeneous strip")
|
||||||
|
settings.massModel=data["settings"]["massModel"] # "mass point" or "homogeneous strip"
|
||||||
|
else
|
||||||
|
error("ERROR at reading the settings yaml file: The value of massModel is wrong. It has to be mass point or homogeneous strip.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("ERROR at reading the settings yaml file: The keyword massModel is missing. It has to be added with the value mass point or homogeneous strip.")
|
||||||
|
end
|
||||||
|
delete!(data["settings"], "massModel")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# step variable of the step method "s in m", "t in s" or "v in m/s"
|
||||||
|
if haskey(data["settings"],"stepVariable")
|
||||||
|
if typeof(data["settings"]["stepVariable"])==String && (data["settings"]["stepVariable"]=="s in m" || data["settings"]["stepVariable"]=="t in s" || data["settings"]["stepVariable"]=="v in m/s")
|
||||||
|
settings.stepVariable=data["settings"]["stepVariable"] # "s in m", "t in s" or "v in m/s"
|
||||||
|
else
|
||||||
|
error("ERROR at reading the settings yaml file: The value of stepVariable is wrong. It has to be s in m, t in s or v in m/s.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("ERROR for the settings yaml file: The keyword stepVariable is missing. It has to be added with the value s in m, t in s or v in m/s.")
|
||||||
|
end
|
||||||
|
delete!(data["settings"], "stepVariable")
|
||||||
|
|
||||||
|
|
||||||
|
# step size (unit depends on steapVariable: s in m, t in s and v in m/s)
|
||||||
|
if haskey(data["settings"],"stepSize")
|
||||||
|
if typeof(data["settings"]["stepSize"])==Float64 && data["settings"]["stepSize"]>0.0
|
||||||
|
settings.stepSize=data["settings"]["stepSize"]
|
||||||
|
elseif typeof(data["settings"]["stepSize"])==Int64 && data["settings"]["stepSize"]>0
|
||||||
|
settings.stepSize=convert(AbstractFloat, data["settings"]["stepSize"])
|
||||||
|
else
|
||||||
|
error("ERROR at reading the settings yaml file: The value of the stepSize is no real floating point number >0.0.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("ERROR at reading the settings yaml file: The keyword stepSize is missing. It has to be added with a value of type real floating point number >0.0.")
|
||||||
|
end
|
||||||
|
delete!(data["settings"], "stepSize")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# operation mode "minimum running time"
|
||||||
|
if haskey(data["settings"],"operationModeMinimumRunningTime") && data["settings"]["operationModeMinimumRunningTime"]!=nothing
|
||||||
|
if typeof(data["settings"]["operationModeMinimumRunningTime"])==Bool
|
||||||
|
settings.operationModeMinimumRunningTime=data["settings"]["operationModeMinimumRunningTime"]
|
||||||
|
else
|
||||||
|
error("ERROR at reading the settings yaml file: The value of the keyword operationModeMinimumRunningTime is not correct. The value has to be of type boolean.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
settings.operationModeMinimumRunningTime=false
|
||||||
|
println("WARNING at reading the settings yaml file: The keyword operationModeMinimumRunningTime or its value is missing. Therefore operationModeMinimumRunningTime=",settings.operationModeMinimumRunningTime," is assumed and used.")
|
||||||
|
end
|
||||||
|
delete!(data["settings"], "operationModeMinimumRunningTime")
|
||||||
|
|
||||||
|
|
||||||
|
# operation mode "minimum energy consumption"
|
||||||
|
if haskey(data["settings"],"operationModeMinimumEnergyConsumption") && data["settings"]["operationModeMinimumEnergyConsumption"]!=nothing
|
||||||
|
if typeof(data["settings"]["operationModeMinimumEnergyConsumption"])==Bool
|
||||||
|
settings.operationModeMinimumEnergyConsumption=data["settings"]["operationModeMinimumEnergyConsumption"]
|
||||||
|
else
|
||||||
|
error("ERROR at reading the settings yaml file: The value of the keyword operationModeMinimumEnergyConsumption is not correct. The value has to be of type boolean.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
settings.operationModeMinimumEnergyConsumption=false
|
||||||
|
println("WARNING at reading the settings yaml file: The keyword operationModeMinimumEnergyConsumption or its value is missing. Therefore operationModeMinimumEnergyConsumption=",settings.operationModeMinimumEnergyConsumption," is assumed and used.")
|
||||||
|
end
|
||||||
|
delete!(data["settings"], "operationModeMinimumEnergyConsumption")
|
||||||
|
|
||||||
|
# output as "julia dictionary" or as "CSV"
|
||||||
|
if haskey(data["settings"],"typeOfOutput")
|
||||||
|
if typeof(data["settings"]["typeOfOutput"])==String && (data["settings"]["typeOfOutput"]=="julia dictionary" || data["settings"]["typeOfOutput"]=="CSV")
|
||||||
|
settings.typeOfOutput=data["settings"]["typeOfOutput"] # "julia dictionary" or "CSV"
|
||||||
|
else
|
||||||
|
error("ERROR at reading the settings yaml file: The value of typeOfOutput is wrong. It has to be julia dictionary or CSV.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("ERROR at reading the settings yaml file: The keyword typeOfOutput is missing. It has to be added with the value julia dictionary or CSV.")
|
||||||
|
end
|
||||||
|
delete!(data["settings"], "typeOfOutput")
|
||||||
|
|
||||||
|
# TODO: it could be checked if the path is existing on the pc
|
||||||
|
if settings.typeOfOutput=="CSV"
|
||||||
|
if haskey(data["settings"],"csvFolderPath")
|
||||||
|
if typeof(data["settings"]["csvFolderPath"])==String
|
||||||
|
settings.csvFolderPath=data["settings"]["csvFolderPath"]
|
||||||
|
else
|
||||||
|
error("ERROR at reading the settings yaml file: The value of csvFolderPath is wrong. It has to be of type String.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("ERROR at reading the settings yaml file: The keyword csvFolderPath is missing. It has to be added.")
|
||||||
|
end
|
||||||
|
delete!(data["settings"], "csvFolderPath")
|
||||||
|
end # if
|
||||||
|
|
||||||
|
|
||||||
|
# should the output be "reduced" or "driving course"
|
||||||
|
if haskey(data["settings"],"detailOfOutput")
|
||||||
|
if typeof(data["settings"]["detailOfOutput"])==String && (data["settings"]["detailOfOutput"]=="reduced" || data["settings"]["detailOfOutput"]=="driving course")
|
||||||
|
settings.detailOfOutput=data["settings"]["detailOfOutput"] # "reduced" or "driving course"
|
||||||
|
else
|
||||||
|
error("ERROR at reading the settings yaml file: The value of detailOfOutput is wrong. It has to be reduced or driving course.")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
error("ERROR at reading the settings yaml file: The keyword detailOfOutput is missing. It has to be added with the value reduced or driving course.")
|
||||||
|
end
|
||||||
|
delete!(data["settings"], "detailOfOutput")
|
||||||
|
|
||||||
|
|
||||||
|
# informing the user, which keywords of the input data are not used in this tool:
|
||||||
|
if length(data["settings"])>0
|
||||||
|
println("INFO at reading the settings yaml file: The following Keywords are not used in this tool:")
|
||||||
|
for key in keys(data["settings"])
|
||||||
|
println(" - ",key)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return settings
|
||||||
|
end # function inputSettings
|
||||||
|
|
||||||
|
end # module RailwayDrivingDynamicsInput
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,478 @@
|
||||||
|
module RailwayDrivingDynamicsOperationModes
|
||||||
|
|
||||||
|
using ..types
|
||||||
|
|
||||||
|
include("./RailwayDrivingDynamicsMovingPhases.jl")
|
||||||
|
include("./RailwayDrivingDynamicsEnergySaving.jl")
|
||||||
|
using .RailwayDrivingDynamicsMovingPhases
|
||||||
|
using .RailwayDrivingDynamicsEnergySaving
|
||||||
|
|
||||||
|
export simulateMinimumRunningTime!, simulateMinimumEnergyConsumption
|
||||||
|
|
||||||
|
function simulateMinimumRunningTime!(movingSection::MovingSection, settings::Settings, vehicle::Vehicle)
|
||||||
|
# this function simulates a train run focussing on using the minimum possible running time
|
||||||
|
startingPoint=Waypoint()
|
||||||
|
startingPoint.i=1
|
||||||
|
drivingCourse=[startingPoint] # List of waypoints
|
||||||
|
drivingCourse[end].s=movingSection.characteristicSections[1].s_start
|
||||||
|
|
||||||
|
for csId in 1:length(movingSection.characteristicSections)
|
||||||
|
# check if the CS has a cruising section
|
||||||
|
s_starting=get(movingSection.characteristicSections[csId].behaviorSections, "starting", BehaviorSection()).s_total
|
||||||
|
s_cruisingBeforeAcceleration=get(movingSection.characteristicSections[csId].behaviorSections, "cruisingBeforeAcceleration", BehaviorSection()).s_total
|
||||||
|
s_acceleration=get(movingSection.characteristicSections[csId].behaviorSections, "acceleration", BehaviorSection()).s_total
|
||||||
|
s_braking=max(0.0, ceil((movingSection.characteristicSections[csId].v_exit^2-movingSection.characteristicSections[csId].v_reach^2)/2/vehicle.a_braking, digits=10)) # ceil is used to be sure that the vehicle stops at s_end in spite of rounding errors
|
||||||
|
|
||||||
|
s_cruising=movingSection.characteristicSections[csId].s_total-s_starting-s_cruisingBeforeAcceleration-s_acceleration-s_braking
|
||||||
|
|
||||||
|
# reset the moving section (MS), delete characteristic sections (CS) that were used during the preperation for setting v_entry, v_reach and v_exit
|
||||||
|
delete!(movingSection.characteristicSections[csId].behaviorSections, "starting")
|
||||||
|
delete!(movingSection.characteristicSections[csId].behaviorSections, "cruisingBeforeAcceleration")
|
||||||
|
delete!(movingSection.characteristicSections[csId].behaviorSections, "acceleration")
|
||||||
|
delete!(movingSection.characteristicSections[csId].behaviorSections, "cruising")
|
||||||
|
movingSection.characteristicSections[csId].E_total=0.0
|
||||||
|
movingSection.characteristicSections[csId].t_total=0.0
|
||||||
|
|
||||||
|
if s_cruisingBeforeAcceleration == movingSection.characteristicSections[csId].s_total
|
||||||
|
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruisingBeforeAcceleration, settings, vehicle, movingSection.characteristicSections, "cruisingBeforeAcceleration")
|
||||||
|
|
||||||
|
elseif s_cruising == movingSection.characteristicSections[csId].s_total
|
||||||
|
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruising, settings, vehicle, movingSection.characteristicSections, "cruising")
|
||||||
|
|
||||||
|
elseif s_cruising >0.01 # if the cruising section is longer than 1 cm (because of rounding issues not >0.0)
|
||||||
|
if drivingCourse[end].v<movingSection.characteristicSections[csId].v_reach
|
||||||
|
(movingSection.characteristicSections[csId], drivingCourse)=addAccelerationPhase!(movingSection.characteristicSections[csId], drivingCourse, settings, vehicle, movingSection.characteristicSections)
|
||||||
|
end #if
|
||||||
|
|
||||||
|
if (movingSection.characteristicSections[csId].s_end-drivingCourse[end].s-max(0.0, (movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/vehicle.a_braking))<-0.001 # ceil is used to be sure that the vehicle stops at s_end in spite of rounding errors
|
||||||
|
println("ERROR: After accelerating in CS ",csId," the braking distance is too short!")
|
||||||
|
println(" before acceleration in CS",csId, " with s=",drivingCourse[end].s," s_braking=",((movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/vehicle.a_braking)," s_end=",movingSection.characteristicSections[csId].s_end)
|
||||||
|
println(" and v=",drivingCourse[end].v," v_reach=",movingSection.characteristicSections[csId].v_reach," v_exit=",movingSection.characteristicSections[csId].v_exit)
|
||||||
|
end
|
||||||
|
|
||||||
|
s_braking=max(0.0, ceil((movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/vehicle.a_braking, digits=10)) # ceil is used to be sure that the vehicle stops at s_end in spite of rounding errors
|
||||||
|
s_cruising=movingSection.characteristicSections[csId].s_end-drivingCourse[end].s-s_braking
|
||||||
|
|
||||||
|
if s_cruising>0
|
||||||
|
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruising, settings, vehicle, movingSection.characteristicSections, "cruising")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if movingSection.characteristicSections[csId].v_entry<movingSection.characteristicSections[csId].v_reach
|
||||||
|
(movingSection.characteristicSections[csId], drivingCourse)=addAccelerationPhaseWithIntersection!(movingSection.characteristicSections[csId], drivingCourse, settings, vehicle, movingSection.characteristicSections)
|
||||||
|
end #if
|
||||||
|
end #if
|
||||||
|
|
||||||
|
|
||||||
|
s_braking=max(0.0, ceil((movingSection.characteristicSections[csId].v_exit^2-drivingCourse[end].v^2)/2/vehicle.a_braking, digits=10)) # ceil is used to be sure that the vehicle stops at s_end in spite of rounding errors
|
||||||
|
|
||||||
|
if drivingCourse[end].v>movingSection.characteristicSections[csId].v_exit
|
||||||
|
(movingSection.characteristicSections[csId], drivingCourse)=addBrakingPhase!(movingSection.characteristicSections[csId], drivingCourse, settings.massModel, vehicle, movingSection.characteristicSections)
|
||||||
|
end #if
|
||||||
|
|
||||||
|
if drivingCourse[end].s < movingSection.characteristicSections[csId].s_end
|
||||||
|
if haskey(movingSection.characteristicSections[csId].behaviorSections, "cruising")
|
||||||
|
println("INFO: A second cruising section has been added to CS ", csId," from s=",drivingCourse[end].s," to s_end=",movingSection.characteristicSections[csId].s_end)
|
||||||
|
end
|
||||||
|
(movingSection.characteristicSections[csId], drivingCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], drivingCourse, s_cruising, settings, vehicle, movingSection.characteristicSections, "cruising")
|
||||||
|
end
|
||||||
|
end #for
|
||||||
|
|
||||||
|
movingSection.t_total=drivingCourse[end].t # total running time (in s)
|
||||||
|
movingSection.E_total=drivingCourse[end].E # total energy consumption (in Ws)
|
||||||
|
|
||||||
|
return (movingSection, drivingCourse)
|
||||||
|
end #function simulateMinimumRunningTime
|
||||||
|
|
||||||
|
|
||||||
|
function simulateMinimumEnergyConsumption(movingSectionMinimumRunningTime::MovingSection, drivingCourseMinimumRunningTime::Vector{Waypoint}, settings::Settings, vehicle::Vehicle)
|
||||||
|
# this function simulates a train run focussing on using the minimum possible energy consumption
|
||||||
|
# booleans for choosing which methods are used for saving energy
|
||||||
|
doMethod1=true
|
||||||
|
doMethod2=true
|
||||||
|
doCombinationOfMethods=true
|
||||||
|
|
||||||
|
#creating a new moving section for the minimum energy consumption
|
||||||
|
movingSectionOriginal=MovingSection(movingSectionMinimumRunningTime)
|
||||||
|
|
||||||
|
# creating a new driving course for the minimum energy consumption
|
||||||
|
drivingCourseOriginal=Waypoint[]
|
||||||
|
for i in 1:length(drivingCourseMinimumRunningTime)
|
||||||
|
push!(drivingCourseOriginal, Waypoint(drivingCourseMinimumRunningTime[i])) # List of waypoints till the start of energy saving
|
||||||
|
end
|
||||||
|
|
||||||
|
# calculation the recovery time
|
||||||
|
movingSectionOriginal.t_recovery=calculateRecoveryTime(movingSectionOriginal.s_total, movingSectionOriginal.t_total, vehicle)
|
||||||
|
movingSectionOriginal.t_recoveryAvailable=movingSectionOriginal.t_recovery
|
||||||
|
# println("t_recovery=",movingSectionOriginal.t_recovery)
|
||||||
|
|
||||||
|
# creating arrays for each method with all the available energy saving modifications
|
||||||
|
energySavingModificationsWithCoasting=EnergySavingModification[]
|
||||||
|
energySavingModificationsWithMaximumSpeed=EnergySavingModification[]
|
||||||
|
energySavingModificationsWithCombination=EnergySavingModification[]
|
||||||
|
|
||||||
|
for csId in 1:length(movingSectionOriginal.characteristicSections)
|
||||||
|
# method 1: increase coasting
|
||||||
|
if doMethod1==true
|
||||||
|
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=increaseCostingSection(movingSectionOriginal.characteristicSections[csId], drivingCourseOriginal, settings, vehicle, movingSectionOriginal.characteristicSections, movingSectionOriginal.t_recoveryAvailable)
|
||||||
|
if new
|
||||||
|
energySavingModification=EnergySavingModification()
|
||||||
|
energySavingModification.csId=csId # identifier of the characteristic section
|
||||||
|
energySavingModification.type="increasing coasting" # type of energy saving modification: "increasing coasting" or "decreasing maximum velocity" or "combination of energy saving methods"
|
||||||
|
energySavingModification.csModified=characteristicSectionModified # the modified characteristic section
|
||||||
|
energySavingModification.drivingCourseModified=drivingCourseModifiedUntilEndOfModifiedCS # drivingCourse of the modified characteristic section
|
||||||
|
energySavingModification.ΔE=movingSectionOriginal.characteristicSections[csId].E_total-energySavingModification.csModified.E_total # saved energy (in Ws)
|
||||||
|
energySavingModification.Δt=energySavingModification.csModified.t_total-movingSectionOriginal.characteristicSections[csId].t_total # time loss (in s)
|
||||||
|
if energySavingModification.Δt<=movingSectionOriginal.t_recoveryAvailable && energySavingModification.ΔE>=0.0
|
||||||
|
energySavingModification.ratio=energySavingModification.ΔE/energySavingModification.Δt # ratio of ΔE and Δt (in Ws/s)
|
||||||
|
elseif energySavingModification.Δt==0.0 #
|
||||||
|
energySavingModification.ratio=energySavingModification.ΔE/0.000000001
|
||||||
|
else # Δt is to high
|
||||||
|
energySavingModification.ratio=0.0
|
||||||
|
end
|
||||||
|
push!(energySavingModificationsWithCoasting, energySavingModification)
|
||||||
|
else # there is no modification possible for the current CS
|
||||||
|
push!(energySavingModificationsWithCoasting, EnergySavingModification())
|
||||||
|
end
|
||||||
|
end #if doMethod1
|
||||||
|
|
||||||
|
# method 2: accelerate to a lower v_reach
|
||||||
|
if doMethod2==true
|
||||||
|
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=decreaseMaximumVelocity(movingSectionOriginal.characteristicSections[csId], drivingCourseOriginal, settings, vehicle, movingSectionOriginal.characteristicSections, movingSectionOriginal.t_recoveryAvailable)
|
||||||
|
if new
|
||||||
|
energySavingModification=EnergySavingModification()
|
||||||
|
energySavingModification.csId=csId # identifier of the characteristic section
|
||||||
|
energySavingModification.type="decreasing maximum velocity" # type of energy saving modification: "increasing coasting" or "decreasing maximum velocity" or "combination of energy saving methods"
|
||||||
|
energySavingModification.csModified=characteristicSectionModified # the modified characteristic section
|
||||||
|
energySavingModification.drivingCourseModified=drivingCourseModifiedUntilEndOfModifiedCS # drivingCourse of the modified characteristic section
|
||||||
|
energySavingModification.ΔE=movingSectionOriginal.characteristicSections[csId].E_total-energySavingModification.csModified.E_total # saved energy (in Ws)
|
||||||
|
energySavingModification.Δt=energySavingModification.csModified.t_total-movingSectionOriginal.characteristicSections[csId].t_total # time loss (in s)
|
||||||
|
if energySavingModification.Δt<=movingSectionOriginal.t_recoveryAvailable && energySavingModification.ΔE>=0.0
|
||||||
|
energySavingModification.ratio=energySavingModification.ΔE/energySavingModification.Δt # ratio of ΔE and Δt (in Ws/s)
|
||||||
|
elseif energySavingModification.Δt==0.0
|
||||||
|
energySavingModification.ratio=energySavingModification.ΔE/0.000000001
|
||||||
|
else # Δt is to high or ΔE < 0.0 Ws
|
||||||
|
energySavingModification.ratio=0.0
|
||||||
|
end
|
||||||
|
push!(energySavingModificationsWithMaximumSpeed, energySavingModification)
|
||||||
|
else # there is no modification possible for the current CS
|
||||||
|
push!(energySavingModificationsWithMaximumSpeed, EnergySavingModification())
|
||||||
|
end
|
||||||
|
end #if doMethod2
|
||||||
|
|
||||||
|
|
||||||
|
if doCombinationOfMethods==true
|
||||||
|
# calculating the combination of methods
|
||||||
|
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=combineEnergySavingMethods(movingSectionOriginal.characteristicSections[csId], drivingCourseOriginal, settings, vehicle, movingSectionOriginal.characteristicSections, movingSectionOriginal.t_recoveryAvailable)
|
||||||
|
if new
|
||||||
|
energySavingModification=EnergySavingModification()
|
||||||
|
energySavingModification.csId=csId # identifier of the characteristic section
|
||||||
|
energySavingModification.type="combination of energy saving methods" # type of energy saving modification: "increasing coasting" or "decreasing maximum velocity" or "combination of energy saving methods"
|
||||||
|
energySavingModification.csModified=characteristicSectionModified # the modified characteristic section
|
||||||
|
energySavingModification.drivingCourseModified=drivingCourseModifiedUntilEndOfModifiedCS # drivingCourse of the modified characteristic section
|
||||||
|
energySavingModification.ΔE=movingSectionOriginal.characteristicSections[csId].E_total-energySavingModification.csModified.E_total # saved energy (in Ws)
|
||||||
|
energySavingModification.Δt=energySavingModification.csModified.t_total-movingSectionOriginal.characteristicSections[csId].t_total # time loss (in s)
|
||||||
|
if energySavingModification.Δt<=movingSectionOriginal.t_recoveryAvailable && energySavingModification.ΔE>=0.0
|
||||||
|
energySavingModification.ratio=sign(energySavingModification.Δt)*energySavingModification.ΔE/energySavingModification.Δt # ratio of ΔE and Δt (in Ws/s)
|
||||||
|
elseif energySavingModification.Δt==0.0 #
|
||||||
|
energySavingModification.ratio=energySavingModification.ΔE/0.000000001
|
||||||
|
else # Δt is to high or ΔE < 0.0 Ws
|
||||||
|
energySavingModification.ratio=0.0
|
||||||
|
end
|
||||||
|
push!(energySavingModificationsWithCombination, energySavingModification)
|
||||||
|
else # there is no modification possible for the current CS
|
||||||
|
push!(energySavingModificationsWithCombination, EnergySavingModification())
|
||||||
|
end
|
||||||
|
end #if
|
||||||
|
end # for
|
||||||
|
|
||||||
|
|
||||||
|
while (movingSectionOriginal.t_recoveryAvailable>0.0)
|
||||||
|
# comparison of modifications
|
||||||
|
ratioMax=0.0
|
||||||
|
csIdMax=0
|
||||||
|
typeMax="none"
|
||||||
|
for modNr in 1:length(energySavingModificationsWithMaximumSpeed)
|
||||||
|
if energySavingModificationsWithMaximumSpeed[modNr].ratio>ratioMax
|
||||||
|
if energySavingModificationsWithMaximumSpeed[modNr].Δt<=movingSectionOriginal.t_recoveryAvailable
|
||||||
|
ratioMax=energySavingModificationsWithMaximumSpeed[modNr].ratio
|
||||||
|
csIdMax=energySavingModificationsWithMaximumSpeed[modNr].csId
|
||||||
|
typeMax=energySavingModificationsWithMaximumSpeed[modNr].type
|
||||||
|
else # Δt is to high
|
||||||
|
energySavingModificationsWithMaximumSpeed[modNr].ratio=0.0
|
||||||
|
end #if
|
||||||
|
end #if
|
||||||
|
end #for
|
||||||
|
|
||||||
|
for modNr in 1:length(energySavingModificationsWithCoasting)
|
||||||
|
if energySavingModificationsWithCoasting[modNr].ratio>ratioMax
|
||||||
|
if energySavingModificationsWithCoasting[modNr].Δt<=movingSectionOriginal.t_recoveryAvailable
|
||||||
|
ratioMax=energySavingModificationsWithCoasting[modNr].ratio
|
||||||
|
csIdMax=energySavingModificationsWithCoasting[modNr].csId
|
||||||
|
typeMax=energySavingModificationsWithCoasting[modNr].type
|
||||||
|
else # Δt is to high
|
||||||
|
energySavingModificationsWithCoasting[modNr].ratio=0.0
|
||||||
|
end #if
|
||||||
|
end #if
|
||||||
|
end #for
|
||||||
|
|
||||||
|
for modNr in 1:length(energySavingModificationsWithCombination)
|
||||||
|
if energySavingModificationsWithCombination[modNr].ratio>ratioMax
|
||||||
|
if energySavingModificationsWithCombination[modNr].Δt<=movingSectionOriginal.t_recoveryAvailable
|
||||||
|
ratioMax=energySavingModificationsWithCombination[modNr].ratio
|
||||||
|
csIdMax=energySavingModificationsWithCombination[modNr].csId
|
||||||
|
typeMax=energySavingModificationsWithCombination[modNr].type
|
||||||
|
else # Δt is to high
|
||||||
|
energySavingModificationsWithCombination[modNr].ratio=0.0
|
||||||
|
end #if
|
||||||
|
end #if
|
||||||
|
end #for
|
||||||
|
|
||||||
|
|
||||||
|
# selection of most efficient modification and update the original characteristicSection, drivingCourse and movingSection
|
||||||
|
# in case none of the modifications has a ratio>0 stop the calculation
|
||||||
|
if typeMax=="none"
|
||||||
|
break
|
||||||
|
elseif typeMax=="increasing coasting"
|
||||||
|
# println("Energy saving modification number ",length(movingSectionOriginal.energySavingModifications)+1," (coasting) in CS ",csIdMax ," Δt=",energySavingModificationsWithCoasting[csIdMax].Δt," ΔE=", energySavingModificationsWithCoasting[csIdMax].ΔE," t_recoveryAvailable=", movingSectionOriginal.t_recoveryAvailable-energySavingModificationsWithCoasting[csIdMax].Δt)
|
||||||
|
push!(movingSectionOriginal.energySavingModifications, energySavingModificationsWithCoasting[csIdMax])
|
||||||
|
elseif typeMax=="decreasing maximum velocity"
|
||||||
|
# println("Energy saving modification number ",length(movingSectionOriginal.energySavingModifications)+1," (lowering v_reach) in CS ",csIdMax ," Δt=",energySavingModificationsWithCoasting[csIdMax].Δt," ΔE=", energySavingModificationsWithCoasting[csIdMax].ΔE," t_recoveryAvailable=", movingSectionOriginal.t_recoveryAvailable-energySavingModificationsWithCoasting[csIdMax].Δt)
|
||||||
|
push!(movingSectionOriginal.energySavingModifications, energySavingModificationsWithMaximumSpeed[csIdMax])
|
||||||
|
elseif typeMax=="combination of energy saving methods"
|
||||||
|
# println("Energy saving modification number ",length(movingSectionOriginal.energySavingModifications)+1," (combination) in CS ",csIdMax ," Δt=",energySavingModificationsWithCoasting[csIdMax].Δt," ΔE=", energySavingModificationsWithCoasting[csIdMax].ΔE," t_recoveryAvailable=", movingSectionOriginal.t_recoveryAvailable-energySavingModificationsWithCoasting[csIdMax].Δt)
|
||||||
|
push!(movingSectionOriginal.energySavingModifications, energySavingModificationsWithCombination[csIdMax])
|
||||||
|
end #if
|
||||||
|
|
||||||
|
movingSectionOriginal.t_recoveryAvailable=movingSectionOriginal.t_recoveryAvailable-movingSectionOriginal.energySavingModifications[end].Δt
|
||||||
|
|
||||||
|
lastIdOfModifiedCs=get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "braking", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "cruisingAfterCoasting", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "coasting", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "cruising", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "acceleration", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "cruisingBeforeAcceleration", get(movingSectionOriginal.characteristicSections[csIdMax].behaviorSections, "starting", BehaviorSection()))))))).waypoints[end]
|
||||||
|
|
||||||
|
drivingCourseNew=Vector{Waypoint}()
|
||||||
|
for i in 1:length(movingSectionOriginal.energySavingModifications[end].drivingCourseModified)
|
||||||
|
push!(drivingCourseNew, Waypoint(movingSectionOriginal.energySavingModifications[end].drivingCourseModified[i]))
|
||||||
|
end
|
||||||
|
|
||||||
|
# # for testing if the modifications driving course and the original one have the same speed value at their transition point
|
||||||
|
# if lastIdOfModifiedCs+1<=drivingCourseOriginal[end].i
|
||||||
|
# if drivingCourseOriginal[lastIdOfModifiedCs].v-drivingCourseNew[end].v!=0.0
|
||||||
|
# println("INFO: Inconsistency while adding the CS",csIdMax," that has been modified for consuming less energy. The difference at its end is ",(drivingCourseOriginal[lastIdOfModifiedCs].v-drivingCourseNew[end].v)," m/s."
|
||||||
|
# end
|
||||||
|
# end # for testing
|
||||||
|
|
||||||
|
#filling up the rest of the driving course
|
||||||
|
drivingCourseNew[end].F_T=drivingCourseOriginal[lastIdOfModifiedCs].F_T
|
||||||
|
drivingCourseNew[end].F_Rt=drivingCourseOriginal[lastIdOfModifiedCs].F_Rt
|
||||||
|
drivingCourseNew[end].F_Rw=drivingCourseOriginal[lastIdOfModifiedCs].F_Rw
|
||||||
|
drivingCourseNew[end].F_Runion=drivingCourseOriginal[lastIdOfModifiedCs].F_Runion
|
||||||
|
drivingCourseNew[end].F_Rp=drivingCourseOriginal[lastIdOfModifiedCs].F_Rp
|
||||||
|
drivingCourseNew[end].F_R=drivingCourseOriginal[lastIdOfModifiedCs].F_R
|
||||||
|
drivingCourseNew[end].a=drivingCourseOriginal[lastIdOfModifiedCs].a
|
||||||
|
|
||||||
|
endOfModificationId=drivingCourseNew[end].i # is needed for updating the other modified driving courses
|
||||||
|
difference=drivingCourseNew[end].i-lastIdOfModifiedCs
|
||||||
|
|
||||||
|
i=lastIdOfModifiedCs+1
|
||||||
|
while (i<=length(drivingCourseOriginal))
|
||||||
|
push!(drivingCourseNew, Waypoint(drivingCourseOriginal[i]))
|
||||||
|
drivingCourseNew[end].i=length(drivingCourseNew)
|
||||||
|
drivingCourseNew[end].t=drivingCourseNew[end-1].t+drivingCourseNew[end].Δt
|
||||||
|
drivingCourseNew[end].E=drivingCourseNew[end-1].E+drivingCourseNew[end].ΔE
|
||||||
|
drivingCourseNew[end].W_T=drivingCourseNew[end-1].W_T+drivingCourseNew[end].ΔW_T
|
||||||
|
i=i+1
|
||||||
|
end # while
|
||||||
|
|
||||||
|
# updating all the waypoint references in the behaviour sections of the following characteristic sections and the other modified characteristic sections
|
||||||
|
if difference!= 0
|
||||||
|
allBs=["starting", "cruisingBeforeAcceleration", "acceleration", "cruising", "coasting", "cruisingAfterCoasting", "braking"]
|
||||||
|
for csId in csIdMax+1:length(movingSectionOriginal.characteristicSections)
|
||||||
|
for bs in 1: length(allBs)
|
||||||
|
if haskey(movingSectionOriginal.characteristicSections[csId].behaviorSections, allBs[bs])
|
||||||
|
for point in 1:length(get(movingSectionOriginal.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).waypoints)
|
||||||
|
get(movingSectionOriginal.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).waypoints[point]=get(movingSectionOriginal.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).waypoints[point]+difference
|
||||||
|
end
|
||||||
|
end #if
|
||||||
|
end #for
|
||||||
|
end #for
|
||||||
|
|
||||||
|
# updating the waypoints in the following modified charateristic sections and the following points in the driving course
|
||||||
|
for modNr in csIdMax+1:length(energySavingModificationsWithCoasting)
|
||||||
|
if energySavingModificationsWithCoasting[modNr].ratio>0
|
||||||
|
# updating the behavior sections of the modified charateristic section
|
||||||
|
for bs in 1: length(allBs)
|
||||||
|
if haskey(energySavingModificationsWithCoasting[modNr].csModified.behaviorSections, allBs[bs])
|
||||||
|
for point in 1:length(get(energySavingModificationsWithCoasting[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).waypoints)
|
||||||
|
get(energySavingModificationsWithCoasting[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).waypoints[point]=get(energySavingModificationsWithCoasting[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).waypoints[point]+difference
|
||||||
|
end
|
||||||
|
end #if
|
||||||
|
end #for
|
||||||
|
|
||||||
|
# correctig the points of the modified driving course
|
||||||
|
drivingCourseModifiedNew=Vector{Waypoint}()
|
||||||
|
for i in 1:endOfModificationId
|
||||||
|
push!(drivingCourseModifiedNew, Waypoint(drivingCourseNew[i]))
|
||||||
|
end # while
|
||||||
|
i=lastIdOfModifiedCs+1
|
||||||
|
while (i<=length(energySavingModificationsWithCoasting[modNr].drivingCourseModified))
|
||||||
|
push!(drivingCourseModifiedNew, Waypoint(energySavingModificationsWithCoasting[modNr].drivingCourseModified[i]))
|
||||||
|
drivingCourseModifiedNew[end].i=length(drivingCourseModifiedNew)
|
||||||
|
drivingCourseModifiedNew[end].t=drivingCourseModifiedNew[end-1].t+drivingCourseModifiedNew[end].Δt
|
||||||
|
drivingCourseModifiedNew[end].E=drivingCourseModifiedNew[end-1].E+drivingCourseModifiedNew[end].ΔE
|
||||||
|
drivingCourseModifiedNew[end].W_T=drivingCourseModifiedNew[end-1].W_T+drivingCourseModifiedNew[end].ΔW_T
|
||||||
|
i=i+1
|
||||||
|
end # while
|
||||||
|
|
||||||
|
energySavingModificationsWithCoasting[modNr].drivingCourseModified=drivingCourseModifiedNew
|
||||||
|
end #if
|
||||||
|
end #for
|
||||||
|
|
||||||
|
for modNr in csIdMax+1:length(energySavingModificationsWithMaximumSpeed)
|
||||||
|
if energySavingModificationsWithMaximumSpeed[modNr].ratio>0
|
||||||
|
# updating the behavior sections of the modified charateristic section
|
||||||
|
for bs in 1: length(allBs)
|
||||||
|
if haskey(energySavingModificationsWithMaximumSpeed[modNr].csModified.behaviorSections, allBs[bs])
|
||||||
|
for point in 1:length(get(energySavingModificationsWithMaximumSpeed[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).waypoints)
|
||||||
|
get(energySavingModificationsWithMaximumSpeed[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).waypoints[point]=get(energySavingModificationsWithMaximumSpeed[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).waypoints[point]+difference
|
||||||
|
end
|
||||||
|
end #if
|
||||||
|
end #for
|
||||||
|
|
||||||
|
# correctig the points of the modified driving course
|
||||||
|
drivingCourseModifiedNew=Vector{Waypoint}()
|
||||||
|
for i in 1:endOfModificationId
|
||||||
|
push!(drivingCourseModifiedNew, Waypoint(drivingCourseNew[i]))
|
||||||
|
end # while
|
||||||
|
i=lastIdOfModifiedCs+1
|
||||||
|
while (i<=length(energySavingModificationsWithMaximumSpeed[modNr].drivingCourseModified))
|
||||||
|
push!(drivingCourseModifiedNew, Waypoint(energySavingModificationsWithMaximumSpeed[modNr].drivingCourseModified[i]))
|
||||||
|
drivingCourseModifiedNew[end].i=length(drivingCourseModifiedNew)
|
||||||
|
drivingCourseModifiedNew[end].t=drivingCourseModifiedNew[end-1].t+drivingCourseModifiedNew[end].Δt
|
||||||
|
drivingCourseModifiedNew[end].E=drivingCourseModifiedNew[end-1].E+drivingCourseModifiedNew[end].ΔE
|
||||||
|
drivingCourseModifiedNew[end].W_T=drivingCourseModifiedNew[end-1].W_T+drivingCourseModifiedNew[end].ΔW_T
|
||||||
|
i=i+1
|
||||||
|
end # while
|
||||||
|
|
||||||
|
energySavingModificationsWithMaximumSpeed[modNr].drivingCourseModified=drivingCourseModifiedNew
|
||||||
|
end #if
|
||||||
|
end #for
|
||||||
|
|
||||||
|
|
||||||
|
for modNr in csIdMax+1:length(energySavingModificationsWithCombination)
|
||||||
|
if energySavingModificationsWithCombination[modNr].ratio>0
|
||||||
|
# updating the behavior sections of the modified charateristic section
|
||||||
|
for bs in 1: length(allBs)
|
||||||
|
if haskey(energySavingModificationsWithCombination[modNr].csModified.behaviorSections, allBs[bs])
|
||||||
|
for point in 1:length(get(energySavingModificationsWithCombination[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).waypoints)
|
||||||
|
get(energySavingModificationsWithCombination[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).waypoints[point]=get(energySavingModificationsWithCombination[modNr].csModified.behaviorSections, allBs[bs], BehaviorSection()).waypoints[point]+difference
|
||||||
|
end
|
||||||
|
end #if
|
||||||
|
end #for
|
||||||
|
|
||||||
|
# updating the points of the modified driving course
|
||||||
|
drivingCourseModifiedNew=Vector{Waypoint}()
|
||||||
|
for i in 1:endOfModificationId
|
||||||
|
push!(drivingCourseModifiedNew, Waypoint(drivingCourseNew[i]))
|
||||||
|
end # while
|
||||||
|
i=lastIdOfModifiedCs+1
|
||||||
|
while (i<=length(energySavingModificationsWithCombination[modNr].drivingCourseModified))
|
||||||
|
push!(drivingCourseModifiedNew, Waypoint(energySavingModificationsWithCombination[modNr].drivingCourseModified[i]))
|
||||||
|
drivingCourseModifiedNew[end].i=length(drivingCourseModifiedNew)
|
||||||
|
drivingCourseModifiedNew[end].t=drivingCourseModifiedNew[end-1].t+drivingCourseModifiedNew[end].Δt
|
||||||
|
drivingCourseModifiedNew[end].E=drivingCourseModifiedNew[end-1].E+drivingCourseModifiedNew[end].ΔE
|
||||||
|
drivingCourseModifiedNew[end].W_T=drivingCourseModifiedNew[end-1].W_T+drivingCourseModifiedNew[end].ΔW_T
|
||||||
|
i=i+1
|
||||||
|
end # while
|
||||||
|
|
||||||
|
energySavingModificationsWithCombination[modNr].drivingCourseModified=drivingCourseModifiedNew
|
||||||
|
end #if
|
||||||
|
end #for
|
||||||
|
end # if difference
|
||||||
|
|
||||||
|
|
||||||
|
drivingCourseOriginal=drivingCourseNew
|
||||||
|
movingSectionOriginal.characteristicSections[csIdMax]=CharacteristicSection(movingSectionOriginal.energySavingModifications[end].csModified)
|
||||||
|
|
||||||
|
movingSectionOriginal.t_total=drivingCourseOriginal[end].t # total running time (in s)
|
||||||
|
movingSectionOriginal.E_total=drivingCourseOriginal[end].E # total energy consumption (in Ws)
|
||||||
|
|
||||||
|
|
||||||
|
# modify new CS for the considered methods
|
||||||
|
# method 1: increase coasting
|
||||||
|
if doMethod1==true
|
||||||
|
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=increaseCostingSection(movingSectionOriginal.characteristicSections[csIdMax], drivingCourseOriginal, settings, vehicle, movingSectionOriginal.characteristicSections, movingSectionOriginal.t_recoveryAvailable)
|
||||||
|
if new
|
||||||
|
energySavingModification=EnergySavingModification()
|
||||||
|
energySavingModification.csId=csIdMax # identifier of the characteristic section
|
||||||
|
energySavingModification.type="increasing coasting" # type of energy saving modification: "increasing coasting" or "decreasing maximum velocity" or "combination of energy saving methods"
|
||||||
|
energySavingModification.csModified=characteristicSectionModified # the modified characteristic section
|
||||||
|
energySavingModification.drivingCourseModified=drivingCourseModifiedUntilEndOfModifiedCS # drivingCourse of the modified characteristic section
|
||||||
|
energySavingModification.ΔE=movingSectionOriginal.characteristicSections[csIdMax].E_total-energySavingModification.csModified.E_total # saved energy (in Ws)
|
||||||
|
energySavingModification.Δt=energySavingModification.csModified.t_total-movingSectionOriginal.characteristicSections[csIdMax].t_total # time loss (in s)
|
||||||
|
if energySavingModification.Δt<=movingSectionOriginal.t_recoveryAvailable && energySavingModification.ΔE>=0.0 #&& energySavingModification.Δt>0.0
|
||||||
|
energySavingModification.ratio=energySavingModification.ΔE/energySavingModification.Δt # ratio of ΔE and Δt (in Ws/s)
|
||||||
|
elseif energySavingModification.Δt==0.0
|
||||||
|
energySavingModification.ratio=energySavingModification.ΔE/0.000000001
|
||||||
|
else # Δt is to high
|
||||||
|
energySavingModification.ratio=0.0
|
||||||
|
end
|
||||||
|
energySavingModificationsWithCoasting[csIdMax]=energySavingModification
|
||||||
|
else # there is no modification possible for the current CS
|
||||||
|
energySavingModificationsWithCoasting[csIdMax]=EnergySavingModification()
|
||||||
|
end
|
||||||
|
end #if if doMethod1
|
||||||
|
|
||||||
|
# method 2: accelerate to a lower v_reach
|
||||||
|
if doMethod2==true
|
||||||
|
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=decreaseMaximumVelocity(movingSectionOriginal.characteristicSections[csIdMax], drivingCourseOriginal, settings, vehicle, movingSectionOriginal.characteristicSections, movingSectionOriginal.t_recoveryAvailable)
|
||||||
|
if new
|
||||||
|
energySavingModification=EnergySavingModification()
|
||||||
|
energySavingModification.csId=csIdMax # identifier of the characteristic section
|
||||||
|
energySavingModification.type="decreasing maximum velocity" # type of energy saving modification: "increasing coasting" or "decreasing maximum velocity" or "combination of energy saving methods"
|
||||||
|
energySavingModification.csModified=characteristicSectionModified # the modified characteristic section
|
||||||
|
energySavingModification.drivingCourseModified=drivingCourseModifiedUntilEndOfModifiedCS # drivingCourse of the modified characteristic section
|
||||||
|
energySavingModification.ΔE=movingSectionOriginal.characteristicSections[csIdMax].E_total-energySavingModification.csModified.E_total # saved energy (in Ws)
|
||||||
|
energySavingModification.Δt=energySavingModification.csModified.t_total-movingSectionOriginal.characteristicSections[csIdMax].t_total # time loss (in s)
|
||||||
|
if energySavingModification.Δt<=movingSectionOriginal.t_recoveryAvailable && energySavingModification.ΔE>=0.0
|
||||||
|
energySavingModification.ratio=energySavingModification.ΔE/energySavingModification.Δt # ratio of ΔE and Δt (in Ws/s)
|
||||||
|
elseif energySavingModification.Δt==0.0
|
||||||
|
energySavingModification.ratio=energySavingModification.ΔE/0.000000001
|
||||||
|
else # Δt is to high
|
||||||
|
energySavingModification.ratio=0.0
|
||||||
|
end
|
||||||
|
energySavingModificationsWithMaximumSpeed[csIdMax]=energySavingModification
|
||||||
|
else # there is no modification possible for the current CS
|
||||||
|
energySavingModificationsWithMaximumSpeed[csIdMax]=EnergySavingModification()
|
||||||
|
end
|
||||||
|
end #if if doMethod
|
||||||
|
|
||||||
|
|
||||||
|
# combination of both methods
|
||||||
|
if doCombinationOfMethods==true
|
||||||
|
(characteristicSectionModified, drivingCourseModifiedUntilEndOfModifiedCS, new)=combineEnergySavingMethods(movingSectionOriginal.characteristicSections[csIdMax], drivingCourseOriginal, settings, vehicle, movingSectionOriginal.characteristicSections, movingSectionOriginal.t_recoveryAvailable)
|
||||||
|
if new
|
||||||
|
energySavingModification=EnergySavingModification()
|
||||||
|
energySavingModification.csId=csIdMax # identifier of the characteristic section
|
||||||
|
energySavingModification.type="combination of energy saving methods" # type of energy saving modification: "increasing coasting" or "decreasing maximum velocity" or "combination of energy saving methods"
|
||||||
|
energySavingModification.csModified=characteristicSectionModified # the modified characteristic section
|
||||||
|
energySavingModification.drivingCourseModified=drivingCourseModifiedUntilEndOfModifiedCS # drivingCourse of the modified characteristic section
|
||||||
|
energySavingModification.ΔE=movingSectionOriginal.characteristicSections[csIdMax].E_total-energySavingModification.csModified.E_total # saved energy (in Ws)
|
||||||
|
energySavingModification.Δt=energySavingModification.csModified.t_total-movingSectionOriginal.characteristicSections[csIdMax].t_total # time loss (in s)
|
||||||
|
if energySavingModification.Δt<=movingSectionOriginal.t_recoveryAvailable && energySavingModification.ΔE>=0.0
|
||||||
|
energySavingModification.ratio=energySavingModification.ΔE/energySavingModification.Δt # ratio of ΔE and Δt (in Ws/s)
|
||||||
|
elseif energySavingModification.Δt==0.0 #
|
||||||
|
println("Energiesparanpassung durch Kombination bei CS ",csIdMax," ist 0 s. Das kann eigentlich nicht sein!")
|
||||||
|
energySavingModification.ratio=energySavingModification.ΔE/0.000000001
|
||||||
|
else # Δt is to high
|
||||||
|
energySavingModification.ratio=0.0
|
||||||
|
end
|
||||||
|
energySavingModificationsWithCombination[csIdMax]=energySavingModification
|
||||||
|
else # there is no modification possible for the current CS
|
||||||
|
energySavingModificationsWithCombination[csIdMax]=EnergySavingModification()
|
||||||
|
end
|
||||||
|
end #if doCombinationOfMethods
|
||||||
|
end # while
|
||||||
|
|
||||||
|
# println("t_recoveryAvailable=",movingSectionOriginal.t_recoveryAvailable)
|
||||||
|
return (movingSectionOriginal, drivingCourseOriginal)
|
||||||
|
end #function simulateMinimumEnergyConsumption
|
||||||
|
|
||||||
|
end #module RailwayDrivingDynamicsOperationModes
|
|
@ -0,0 +1,371 @@
|
||||||
|
module RailwayDrivingDynamicsOutput
|
||||||
|
|
||||||
|
using ..types
|
||||||
|
using Plots
|
||||||
|
using CSV, DataFrames, Dates
|
||||||
|
|
||||||
|
export createOutput
|
||||||
|
export plotDrivingCourse, printImportantValues, printSectionInformation # functions for showing results during the development
|
||||||
|
|
||||||
|
function createOutput(settings::Settings, pathName::String, vehicleName::String, drivingCourse::Vector{Waypoint}, movingSection::MovingSection)
|
||||||
|
# method of function createOutput for one operation mode
|
||||||
|
if settings.typeOfOutput == "CSV"
|
||||||
|
return createOutputCsv(settings, pathName, vehicleName, drivingCourse, movingSection)
|
||||||
|
else
|
||||||
|
return createOutputDict(settings, pathName, vehicleName, drivingCourse, movingSection)
|
||||||
|
end
|
||||||
|
end # funtion createOutput
|
||||||
|
|
||||||
|
function createOutput(settings::Settings, pathName::String, vehicleName::String, drivingCourseMinimumRunningTime::Vector{Waypoint}, movingSectionMinimumRunningTime::MovingSection, drivingCourseMinimumEnergyConsumption::Vector{Waypoint}, movingSectionMinimumEnergyConsumption::MovingSection)
|
||||||
|
# method of function createOutput for two operation modes
|
||||||
|
if settings.typeOfOutput == "CSV"
|
||||||
|
return createOutputCsv(settings, pathName, vehicleName, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||||
|
else
|
||||||
|
return createOutputDict(settings, pathName, vehicleName, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||||
|
end
|
||||||
|
end # funtion createOutput
|
||||||
|
|
||||||
|
|
||||||
|
function createOutputDict(settings::Settings, pathName::String, vehicleName::String, drivingCourse::Vector{Waypoint}, movingSection::MovingSection)
|
||||||
|
# method of function createOutputDict for one operation mode
|
||||||
|
if settings.operationModeMinimumRunningTime
|
||||||
|
if settings.operationModeMinimumEnergyConsumption
|
||||||
|
operationMode="minimum running time and minimum energy consumption"
|
||||||
|
else
|
||||||
|
operationMode="minimum running time"
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if settings.operationModeMinimumEnergyConsumption
|
||||||
|
operationMode="minimum energy consumption"
|
||||||
|
else
|
||||||
|
# should never be the case
|
||||||
|
println("No Output was demanded. So no output dictionary is created")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
outputDict=Dict([("path name", pathName), ("vehicle name", vehicleName), ("operation mode", operationMode), ("mass model", settings.massModel), ("step variable", settings.stepVariable), ("step size", settings.stepSize)])
|
||||||
|
|
||||||
|
# creating an output array
|
||||||
|
outputArray=Array{Any, 1}[]
|
||||||
|
if settings.detailOfOutput=="reduced"
|
||||||
|
|
||||||
|
push!(outputArray, ["s_total (in m)", "t_total (in s)","E_total (in Ws)"]) # push header to outputArray
|
||||||
|
|
||||||
|
row=[movingSection.s_total, movingSection.t_total, movingSection.E_total]
|
||||||
|
push!(outputArray, row) # push row to outputArray
|
||||||
|
elseif settings.detailOfOutput=="driving course"
|
||||||
|
push!(outputArray, ["i", "Δ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)","F_Rp (in N)","F_Runion (in N)","F_Rt (in N)","F_Rw (in N)", "ΔW_T (in Ws)","W_T (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]) # push header to outputArray
|
||||||
|
for point in drivingCourse
|
||||||
|
row=[point.i, point.Δs, point.s, point.Δt, point.t, point.Δv, point.v, point.F_T, point.F_R, point.F_Rp, point.F_Runion, point.F_Rt, point.F_Rw, point.ΔW_T, point.W_T, point.ΔE, point.E, point.a]
|
||||||
|
push!(outputArray, row) # push row to outputArray
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if length(movingSection.energySavingModifications)>0 # if the moving section hast energy saving modifications the moving section is modified for minimum energy consumption
|
||||||
|
merge!(outputDict, Dict("outputArrayMinimumEnergyConsumption"=>outputArray))
|
||||||
|
else
|
||||||
|
merge!(outputDict, Dict("outputArrayMinimumRunningTime"=>outputArray))
|
||||||
|
end
|
||||||
|
|
||||||
|
println("The output dictionary has been created for ",operationMode,".")
|
||||||
|
return outputDict
|
||||||
|
end # function createOutputDict
|
||||||
|
|
||||||
|
function createOutputDict(settings::Settings, pathName::String, vehicleName::String, drivingCourseMinimumRunningTime::Vector{Waypoint}, movingSectionMinimumRunningTime::MovingSection, drivingCourseMinimumEnergyConsumption::Vector{Waypoint}, movingSectionMinimumEnergyConsumption::MovingSection)
|
||||||
|
# method of function createOutputDict for two operation modes
|
||||||
|
if settings.operationModeMinimumRunningTime
|
||||||
|
outputDict=createOutputDict(settings, pathName, vehicleName, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime)
|
||||||
|
|
||||||
|
if settings.operationModeMinimumEnergyConsumption
|
||||||
|
# creating the second output array
|
||||||
|
outputArrayMinimumEnergyConsumption=Array{Any, 1}[]
|
||||||
|
if settings.detailOfOutput=="reduced"
|
||||||
|
push!(outputArrayMinimumEnergyConsumption, ["s_total (in m)", "t_total (in s)","E_total (in Ws)"]) # push header to outputArrayMinimumEnergyConsumption
|
||||||
|
row=[movingSectionMinimumEnergyConsumption.s_total, movingSectionMinimumEnergyConsumption.t_total, movingSectionMinimumEnergyConsumption.E_total]
|
||||||
|
push!(outputArrayMinimumEnergyConsumption, row) # push row to outputArrayMinimumEnergyConsumption
|
||||||
|
elseif settings.detailOfOutput=="driving course"
|
||||||
|
push!(outputArrayMinimumEnergyConsumption, ["i", "Δ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)","F_Rp (in N)","F_Runion (in N)","F_Rt (in N)","F_Rw (in N)", "ΔW_T (in Ws)","W_T (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]) # push header to outputArrayMinimumEnergyConsumption
|
||||||
|
for point in drivingCourseMinimumEnergyConsumption
|
||||||
|
row=[point.i, point.Δs, point.s, point.Δt, point.t, point.Δv, point.v, point.F_T, point.F_R, point.F_Rp, point.F_Runion, point.F_Rt, point.F_Rw, point.ΔW_T, point.W_T, point.ΔE, point.E, point.a]
|
||||||
|
push!(outputArrayMinimumEnergyConsumption, row) # push row to outputArrayMinimumEnergyConsumption
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
merge!(outputDict, Dict("outputArrayMinimumEnergyConsumption"=>outputArrayMinimumEnergyConsumption))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
outputDict=createOutputDict(settings, pathName, vehicleName, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||||
|
end
|
||||||
|
|
||||||
|
# println("The output dictionary has been created for minimum running time and minimum energy consumption.")
|
||||||
|
return outputDict
|
||||||
|
end # function createOutputDict
|
||||||
|
|
||||||
|
|
||||||
|
function createOutputCsv(settings::Settings, pathName::String, vehicleName::String, drivingCourse::Vector{Waypoint}, movingSection::MovingSection)
|
||||||
|
# method of function createOutputDict for one operation mode
|
||||||
|
outputDict=createOutputDict(settings, pathName, vehicleName, drivingCourse, movingSection)
|
||||||
|
|
||||||
|
if length(movingSection.energySavingModifications)>0 # if the moving section hast energy saving modifications the moving section is modified for minimum energy consumption
|
||||||
|
operationMode="minimum energy consumption"
|
||||||
|
outputArray="outputArrayMinimumEnergyConsumption"
|
||||||
|
date = Dates.now()
|
||||||
|
dateString=Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
|
||||||
|
csvFilePath=settings.csvFolderPath*"\\"*dateString*"_MinimumEnergyConsumption.csv"
|
||||||
|
else
|
||||||
|
operationMode="minimum running time"
|
||||||
|
outputArray="outputArrayMinimumRunningTime"
|
||||||
|
date = Dates.now()
|
||||||
|
dateString=Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
|
||||||
|
csvFilePath=settings.csvFolderPath*"\\"*dateString*"_MinimumRunningTime.csv"
|
||||||
|
end
|
||||||
|
|
||||||
|
# creating information block
|
||||||
|
infoColumns=Array{Any,1}[]
|
||||||
|
push!(infoColumns, ["path name", "vehicle name", "operation mode", "mass model", "step variable", "step size", ""])
|
||||||
|
push!(infoColumns, [pathName, vehicleName, operationMode, settings.massModel, settings.stepVariable, string(settings.stepSize), ""])
|
||||||
|
for column in 3:length(outputDict[outputArray][1])
|
||||||
|
push!(infoColumns, ["", "", "", "", "", "", ""])
|
||||||
|
end # for
|
||||||
|
|
||||||
|
allColumns=Array{Any,1}[]
|
||||||
|
if settings.detailOfOutput=="reduced"
|
||||||
|
header=outputDict["outputArrayMinimumRunningTime"][1]
|
||||||
|
elseif settings.detailOfOutput=="driving course"
|
||||||
|
header=["i", "Delta s (in m)", "s (in m)", "Delta t (in s)","t (in s)","Delta v (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","F_Rp (in N)","F_Runion (in N)","F_Rt (in N)","F_Rw (in N)"," Delta W_T (in Ws)","W_T (in Ws)","Delta E (in Ws)","E (in Ws)","a (in m/s^2)"]
|
||||||
|
end
|
||||||
|
for column in 1:length(outputDict[outputArray][1])
|
||||||
|
push!(infoColumns[column], header[column])
|
||||||
|
for row in outputDict[outputArray][2:end]
|
||||||
|
push!(infoColumns[column], row[column])
|
||||||
|
end
|
||||||
|
push!(allColumns, infoColumns[column])
|
||||||
|
end # for
|
||||||
|
|
||||||
|
|
||||||
|
# combining the columns in a data frame and saving it as a CSV-file at csvFolderPath
|
||||||
|
if settings.detailOfOutput=="reduced"
|
||||||
|
df=DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3])
|
||||||
|
elseif settings.detailOfOutput=="driving course"
|
||||||
|
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])
|
||||||
|
end
|
||||||
|
CSV.write(csvFilePath, df, header=false)
|
||||||
|
|
||||||
|
println("The output CSV file has been created for ",operationMode," at ",csvFilePath)
|
||||||
|
return outputDict
|
||||||
|
end #function createOutputCsv
|
||||||
|
|
||||||
|
function createOutputCsv(settings::Settings, pathName::String, vehicleName::String, drivingCourseMinimumRunningTime::Vector{Waypoint}, movingSectionMinimumRunningTime::MovingSection, drivingCourseMinimumEnergyConsumption::Vector{Waypoint}, movingSectionMinimumEnergyConsumption::MovingSection)
|
||||||
|
# method of function createOutputDict for two operation modes
|
||||||
|
outputDict=createOutputDict(settings, pathName, vehicleName, drivingCourseMinimumRunningTime, movingSectionMinimumRunningTime, drivingCourseMinimumEnergyConsumption, movingSectionMinimumEnergyConsumption)
|
||||||
|
|
||||||
|
if settings.operationModeMinimumRunningTime
|
||||||
|
#creating information block
|
||||||
|
infoColumns=Array{Any,1}[]
|
||||||
|
push!(infoColumns, ["path name", "vehicle name", "operation mode", "mass model", "step variable", "step size", ""])
|
||||||
|
#push!(infoColumns, [pathName, vehicleName, "minimum running time", settings.massModel, settings.stepVariable, settings.stepSize, ""])
|
||||||
|
push!(infoColumns, [pathName, vehicleName, "minimum running time", settings.massModel, settings.stepVariable, string(settings.stepSize), ""])
|
||||||
|
|
||||||
|
for column in 3:length(outputDict["outputArrayMinimumRunningTime"][1])
|
||||||
|
push!(infoColumns, ["", "", "", "", "", "", ""])
|
||||||
|
# println("push wird ausgeführt")
|
||||||
|
end # for
|
||||||
|
|
||||||
|
allColumns=Array{Any,1}[]
|
||||||
|
if settings.detailOfOutput=="reduced"
|
||||||
|
header=outputDict["outputArrayMinimumRunningTime"][1]
|
||||||
|
elseif settings.detailOfOutput=="driving course"
|
||||||
|
header=["i", "Delta s (in m)", "s (in m)", "Delta t (in s)","t (in s)","Delta v (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","F_Rp (in N)","F_Runion (in N)","F_Rt (in N)","F_Rw (in N)"," Delta W_T (in Ws)","W_T (in Ws)","Delta E (in Ws)","E (in Ws)","a (in m/s^2)"]
|
||||||
|
end
|
||||||
|
|
||||||
|
for column in 1:length(outputDict["outputArrayMinimumRunningTime"][1])
|
||||||
|
push!(infoColumns[column], header[column])
|
||||||
|
for row in outputDict["outputArrayMinimumRunningTime"][2:end]
|
||||||
|
push!(infoColumns[column], row[column])
|
||||||
|
end
|
||||||
|
push!(allColumns, infoColumns[column])
|
||||||
|
end # for
|
||||||
|
|
||||||
|
#combining the columns in a data frame and saving it as a CSV-file at csvFolderPath
|
||||||
|
if settings.detailOfOutput=="reduced"
|
||||||
|
df=DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3])
|
||||||
|
elseif settings.detailOfOutput=="driving course"
|
||||||
|
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])
|
||||||
|
end
|
||||||
|
date = Dates.now()
|
||||||
|
dateString=Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
|
||||||
|
csvFilePath=settings.csvFolderPath*"\\"*dateString*"_dataMinimumRunningTime.csv"
|
||||||
|
CSV.write(csvFilePath, df, header=false)
|
||||||
|
println("The output CSV file has been created for minimum running time at ",csvFilePath)
|
||||||
|
end #if settings.operationModeMinimumRunningTime
|
||||||
|
|
||||||
|
|
||||||
|
if settings.operationModeMinimumEnergyConsumption
|
||||||
|
#creating information block
|
||||||
|
infoColumns=Array{Any,1}[]
|
||||||
|
push!(infoColumns, ["path name", "vehicle name", "operation mode", "mass model", "step variable", "step size", ""])
|
||||||
|
push!(infoColumns, [pathName, vehicleName, "minimum energy consumption", settings.massModel, settings.stepVariable, settings.stepSize, ""])
|
||||||
|
for column in 3:length(outputDict["outputArrayMinimumEnergyConsumption"][1])
|
||||||
|
push!(infoColumns, ["", "", "", "", "", "", ""])
|
||||||
|
end # for
|
||||||
|
|
||||||
|
allColumns=Array{Any,1}[]
|
||||||
|
if settings.detailOfOutput=="reduced"
|
||||||
|
header=outputDict["outputArrayMinimumRunningTime"][1]
|
||||||
|
elseif settings.detailOfOutput=="driving course"
|
||||||
|
header=["i", "Delta s (in m)", "s (in m)", "Delta t (in s)","t (in s)","Delta v (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","F_Rp (in N)","F_Runion (in N)","F_Rt (in N)","F_Rw (in N)"," Delta W_T (in Ws)","W_T (in Ws)","Delta E (in Ws)","E (in Ws)","a (in m/s^2)"]
|
||||||
|
end
|
||||||
|
|
||||||
|
for column in 1:length(outputDict["outputArrayMinimumEnergyConsumption"][1])
|
||||||
|
push!(infoColumns[column], header[column])
|
||||||
|
for row in outputDict["outputArrayMinimumEnergyConsumption"][2:end]
|
||||||
|
push!(infoColumns[column], row[column])
|
||||||
|
end
|
||||||
|
push!(allColumns, infoColumns[column])
|
||||||
|
end # for
|
||||||
|
|
||||||
|
#combining the columns in a data frame
|
||||||
|
if settings.detailOfOutput=="reduced"
|
||||||
|
df=DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3])
|
||||||
|
elseif settings.detailOfOutput=="driving course"
|
||||||
|
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])
|
||||||
|
end
|
||||||
|
|
||||||
|
# creating a CSV-file at csvFolderPath
|
||||||
|
date = Dates.now()
|
||||||
|
dateString=Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
|
||||||
|
csvFilePath=settings.csvFolderPath*"\\"*dateString*"_dataMinimumEnergyConsumption.csv"
|
||||||
|
CSV.write(csvFilePath, df, header=false)
|
||||||
|
println("The output CSV file has been created for minimum energy consumption at ",csvFilePath)
|
||||||
|
end # if settings.operationModeMinimumEnergyConsumption
|
||||||
|
|
||||||
|
return outputDict
|
||||||
|
end #function createOutputCsv
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function printImportantValues(drivingCourse::Vector{Waypoint})
|
||||||
|
println("i s in m v in km/h t in min a in m/s^2 F_R in k N F_T in k N E in k Wh")
|
||||||
|
for i in 1:length(drivingCourse)
|
||||||
|
println(drivingCourse[i].i,". ",drivingCourse[i].s," ",drivingCourse[i].v*3.6," ",drivingCourse[i].t/60," ",drivingCourse[i].a," ",drivingCourse[i].F_R/1000," ",drivingCourse[i].F_T/1000," ",drivingCourse[i].E/3600/1000)
|
||||||
|
end #for
|
||||||
|
println("i 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::MovingSection)
|
||||||
|
println("MS mit s_total=", movingSection.s_total," mit t_total=", movingSection.t_total)
|
||||||
|
allBs=["starting", "cruisingBeforeAcceleration","acceleration", "cruising", "coasting","cruisingAfterCoasting", "braking"]
|
||||||
|
for csId in 1:length(movingSection.characteristicSections)
|
||||||
|
println("CS ",csId," mit s_total=", movingSection.characteristicSections[csId].s_total," mit t_total=", movingSection.characteristicSections[csId].t_total)
|
||||||
|
for bs in 1: length(allBs)
|
||||||
|
if haskey(movingSection.characteristicSections[csId].behaviorSections, allBs[bs])
|
||||||
|
println("BS ",allBs[bs], " mit s_start=",get(movingSection.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).s_start, " und t_total=",get(movingSection.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).t_total)
|
||||||
|
# for point in 1:length(get(movingSection.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).waypoints)
|
||||||
|
# println(get(movingSection.characteristicSections[csId].behaviorSections, allBs[bs], BehaviorSection()).waypoints[point])
|
||||||
|
# end
|
||||||
|
end #if
|
||||||
|
end #for
|
||||||
|
end #for
|
||||||
|
end #function printSectionInformation
|
||||||
|
|
||||||
|
function plotDrivingCourse(drivingCourse::Vector{Waypoint})
|
||||||
|
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")
|
||||||
|
|
||||||
|
p2=plot([t], [v], title = "v in m/s", label = ["v"], xlabel = "t in s")
|
||||||
|
|
||||||
|
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")
|
||||||
|
|
||||||
|
p6=plot([t], [E], title = "E in Ws", label = ["E"], xlabel = "t in s")
|
||||||
|
|
||||||
|
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{Waypoint},drivingCourseMinimumEnergyConsumption::Vector{Waypoint}) #,movingSection1::MovingSection,movingSection2::MovingSection)
|
||||||
|
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)
|
||||||
|
display(all)
|
||||||
|
println("Plots for different variables have been created.")
|
||||||
|
end #function plotDrivingCourse
|
||||||
|
|
||||||
|
end # module RailwayDrivingDynamicsOutput
|
|
@ -0,0 +1,137 @@
|
||||||
|
module RailwayDrivingDynamicsPreparation
|
||||||
|
|
||||||
|
using ..types
|
||||||
|
include("./RailwayDrivingDynamicsMovingPhases.jl")
|
||||||
|
using .RailwayDrivingDynamicsMovingPhases
|
||||||
|
|
||||||
|
export preparateSections
|
||||||
|
|
||||||
|
## creating a moving section and its containing characteristic sections which braking and acceleration behavior is secured
|
||||||
|
function preparateSections(path::Path, vehicle::Vehicle, settings::Settings)
|
||||||
|
movingSection=createMovingSection(path, vehicle.v_limit)
|
||||||
|
movingSection=secureBrakingBehavior!(movingSection, vehicle.a_braking)
|
||||||
|
movingSection=secureAccelerationBehavior!(movingSection, settings, vehicle)
|
||||||
|
return movingSection
|
||||||
|
end #function preparateSections
|
||||||
|
|
||||||
|
## creating a moving section containing characteristic sections
|
||||||
|
function createMovingSection(path::Path, v_vehicleLimit::AbstractFloat)
|
||||||
|
# this function creates and returns a moving section dependent on the paths attributes
|
||||||
|
movingSection=MovingSection()
|
||||||
|
|
||||||
|
movingSection.id=1 # identifier # if there is more than one moving section in a later version of this tool the id should not be constant anymore
|
||||||
|
movingSection.t_total=0.0 # total running time (in s)
|
||||||
|
movingSection.E_total=0.0 # total energy consumption (in Ws)
|
||||||
|
|
||||||
|
movingSection.s_start=path.sections[1].s_start # first position (in m)
|
||||||
|
movingSection.s_end=path.sections[length(path.sections)].s_startNext # last position (in m)
|
||||||
|
movingSection.s_total=movingSection.s_end-movingSection.s_start # total length (in m)
|
||||||
|
|
||||||
|
s_csStart=movingSection.s_start
|
||||||
|
csId=1
|
||||||
|
for row in 2:length(path.sections)
|
||||||
|
if min(path.sections[row-1].v_limit, v_vehicleLimit) != min(path.sections[row].v_limit, v_vehicleLimit) || path.sections[row-1].f_Rp != path.sections[row].f_Rp
|
||||||
|
push!(movingSection.characteristicSections, createCharacteristicSection(csId, s_csStart, path.sections[row-1], min(path.sections[row-1].v_limit, v_vehicleLimit)))
|
||||||
|
s_csStart=path.sections[row].s_start
|
||||||
|
csId=csId+1
|
||||||
|
end #if
|
||||||
|
end #for
|
||||||
|
push!(movingSection.characteristicSections, createCharacteristicSection(csId, s_csStart, path.sections[end], min(path.sections[end].v_limit, v_vehicleLimit)))
|
||||||
|
|
||||||
|
return movingSection
|
||||||
|
end #function createMovingSection
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
function createCharacteristicSection(csId::Integer, s_csStart::AbstractFloat, section::PathSection, v_csLimit::AbstractFloat)
|
||||||
|
# this function creates and returns a characteristic section dependent on the paths attributes
|
||||||
|
characteristicSection=CharacteristicSection()
|
||||||
|
characteristicSection.id=csId # identifier
|
||||||
|
characteristicSection.s_start=s_csStart # first position (in m)
|
||||||
|
characteristicSection.s_end=section.s_startNext # last position (in m)
|
||||||
|
characteristicSection.s_total=characteristicSection.s_end-characteristicSection.s_start # total length (in m)
|
||||||
|
characteristicSection.t_total=0.0 # total running time (in s)
|
||||||
|
characteristicSection.E_total=0.0 # total energy consumption (in Ws)
|
||||||
|
characteristicSection.v_limit=v_csLimit # speed limit (in m/s)
|
||||||
|
|
||||||
|
# initializing v_entry, v_reach and v_exit with v_limit
|
||||||
|
characteristicSection.v_reach=characteristicSection.v_limit # maximum reachable speed (in m/s)
|
||||||
|
characteristicSection.v_entry=characteristicSection.v_limit # maximum entry speed (in m/s)
|
||||||
|
characteristicSection.v_exit=characteristicSection.v_limit # maximum exit speed (in m/s)
|
||||||
|
|
||||||
|
characteristicSection.f_Rp=section.f_Rp # path resistance (in ‰)
|
||||||
|
|
||||||
|
return characteristicSection
|
||||||
|
end #function createCharacteristicSection
|
||||||
|
|
||||||
|
## defining the intersection velocities between the characterisitc sections
|
||||||
|
function secureBrakingBehavior!(movingSection::MovingSection, a_braking::AbstractFloat)
|
||||||
|
# this function limits the entry and exit velocity of the characteristic sections to secure that the vehicle stops at the moving sections end
|
||||||
|
csId=length(movingSection.characteristicSections)
|
||||||
|
movingSection.characteristicSections[csId].v_exit=0.0 # the exit velocity of the last characteristic section is 0.0 m/s
|
||||||
|
while csId >= 1
|
||||||
|
v_entryMax=sqrt(movingSection.characteristicSections[csId].v_exit^2-2*a_braking*movingSection.characteristicSections[csId].s_total)
|
||||||
|
v_entryMax=floor(v_entryMax, digits=12)
|
||||||
|
|
||||||
|
movingSection.characteristicSections[csId].v_entry=min(movingSection.characteristicSections[csId].v_limit, v_entryMax)
|
||||||
|
movingSection.characteristicSections[csId].v_reach=movingSection.characteristicSections[csId].v_entry
|
||||||
|
csId=csId-1
|
||||||
|
if csId >= 1
|
||||||
|
movingSection.characteristicSections[csId].v_exit=min(movingSection.characteristicSections[csId].v_limit, movingSection.characteristicSections[csId+1].v_entry)
|
||||||
|
end #if
|
||||||
|
end #while
|
||||||
|
return movingSection
|
||||||
|
end #function secureBrakingBehavior!
|
||||||
|
|
||||||
|
##
|
||||||
|
function secureAccelerationBehavior!(movingSection::MovingSection, settings::Settings, vehicle::Vehicle)
|
||||||
|
# this function limits the entry and exit velocity of the characteristic sections for case that the vehicle accelerates in every section and cruises aterwards
|
||||||
|
movingSection.characteristicSections[1].v_entry=0.0 # the entry velocity of the first characteristic section is 0.0 m/s
|
||||||
|
startingPoint=Waypoint()
|
||||||
|
startingPoint.i=1
|
||||||
|
|
||||||
|
previousCSv_exit=0.0
|
||||||
|
|
||||||
|
for csId in 1:length(movingSection.characteristicSections)
|
||||||
|
movingSection.characteristicSections[csId].v_entry=min(movingSection.characteristicSections[csId].v_entry, previousCSv_exit)
|
||||||
|
|
||||||
|
startingPoint.s=movingSection.characteristicSections[csId].s_start
|
||||||
|
startingPoint.v=movingSection.characteristicSections[csId].v_entry
|
||||||
|
accelerationCourse=[startingPoint] # List of waypoints
|
||||||
|
|
||||||
|
|
||||||
|
if movingSection.characteristicSections[csId].v_entry<movingSection.characteristicSections[csId].v_reach
|
||||||
|
(movingSection.characteristicSections[csId], accelerationCourse)=addAccelerationPhase!(movingSection.characteristicSections[csId], accelerationCourse, settings, vehicle, movingSection.characteristicSections) # this function changes the accelerationCourse
|
||||||
|
movingSection.characteristicSections[csId].v_reach=accelerationCourse[end].v
|
||||||
|
movingSection.characteristicSections[csId].v_exit=min(movingSection.characteristicSections[csId].v_exit, movingSection.characteristicSections[csId].v_reach)
|
||||||
|
|
||||||
|
if settings.stepVariable=="v in m/s" # with the new v_reach the calculation will be defferent a second time. Therefore the CS has to be calculated again for velocity step method to refresh the length of the acceleration section for further simulation
|
||||||
|
delete!(movingSection.characteristicSections[csId].behaviorSections, "starting")
|
||||||
|
delete!(movingSection.characteristicSections[csId].behaviorSections, "cruisingBeforeAcceleration")
|
||||||
|
delete!(movingSection.characteristicSections[csId].behaviorSections, "acceleration")
|
||||||
|
movingSection.characteristicSections[csId].E_total=0.0
|
||||||
|
movingSection.characteristicSections[csId].t_total=0.0
|
||||||
|
accelerationCourse=[startingPoint] # List of waypoints
|
||||||
|
|
||||||
|
(movingSection.characteristicSections[csId], accelerationCourse)=addAccelerationPhase!(movingSection.characteristicSections[csId], accelerationCourse, settings, vehicle, movingSection.characteristicSections) # this function changes the accelerationCourse
|
||||||
|
end
|
||||||
|
else #movingSection.characteristicSections[csId].v_entry==movingSection.characteristicSections[csId].v_reach
|
||||||
|
# v_exit stays the same
|
||||||
|
end #if
|
||||||
|
|
||||||
|
# securing cruising behavior
|
||||||
|
# is need if the path resistance is too high, the vehicle can not cruise at v_reach and is getting slower
|
||||||
|
s_cruisingMax=movingSection.characteristicSections[csId].s_end-accelerationCourse[end].s
|
||||||
|
if s_cruisingMax>0.0
|
||||||
|
(movingSection.characteristicSections[csId], accelerationCourse)=addCruisingPhase!(movingSection.characteristicSections[csId], accelerationCourse, s_cruisingMax, settings, vehicle, movingSection.characteristicSections, "cruising")
|
||||||
|
movingSection.characteristicSections[csId].v_exit=min(movingSection.characteristicSections[csId].v_exit, accelerationCourse[end].v)
|
||||||
|
end
|
||||||
|
|
||||||
|
previousCSv_exit=movingSection.characteristicSections[csId].v_exit
|
||||||
|
# println("CS",csId,": s_start: ",movingSection.characteristicSections[csId].s_start," v_entry: ", round(movingSection.characteristicSections[csId].v_entry*3.6, digits=5), ", v_reach: ", round(movingSection.characteristicSections[csId].v_reach*3.6, digits=5), " v_exit: ", round(movingSection.characteristicSections[csId].v_exit*3.6, digits=5))
|
||||||
|
end #for
|
||||||
|
|
||||||
|
return movingSection
|
||||||
|
end #function secureAccelerationBehavior!
|
||||||
|
|
||||||
|
end #module RailwayDrivingDynamicsPreparation
|
|
@ -0,0 +1,202 @@
|
||||||
|
module types
|
||||||
|
# definition of all the additional types and their constructors
|
||||||
|
export Settings, Vehicle, PathSection, Path, Waypoint, BehaviorSection, CharacteristicSection, EnergySavingModification, MovingSection
|
||||||
|
|
||||||
|
## settings for the simulation
|
||||||
|
mutable struct Settings
|
||||||
|
massModel::String # model type of the unions mass "mass point" or "homogeneous strip"
|
||||||
|
stepVariable::String # step variable of the step method "s in m", "t in s" or "v in m/s"
|
||||||
|
stepSize::AbstractFloat # step size (unit depends on steapVariable s in m, t in s and v in m/s)
|
||||||
|
operationModeMinimumRunningTime::Bool # operation mode "minimum running time"
|
||||||
|
operationModeMinimumEnergyConsumption::Bool # operation mode "minimum energy consumption"
|
||||||
|
# output:
|
||||||
|
typeOfOutput::String # output as "julia dictionary" or as "CSV"
|
||||||
|
csvFolderPath::String # path of the folder in which the CSV fiiles willl be saved
|
||||||
|
detailOfOutput::String # detail of output "reduced" or "everything"
|
||||||
|
end # mutable struct Settings
|
||||||
|
Settings()=Settings("", "", 0.0, false, false, "", "", "")
|
||||||
|
|
||||||
|
|
||||||
|
## vehicle
|
||||||
|
mutable struct Vehicle
|
||||||
|
name::String # vehicles name
|
||||||
|
id # vehicles identifier
|
||||||
|
vehicleType::String # type of vehicle "passenger" or "freight" or "motor coach train"
|
||||||
|
l_union::AbstractFloat # total length (in m)
|
||||||
|
v_limit::AbstractFloat # vehicles speed limit (in m/s)
|
||||||
|
a_braking::AbstractFloat # braking acceleration (in m/s^2)
|
||||||
|
m_union::AbstractFloat # total mass (in kg)
|
||||||
|
ξ_union::AbstractFloat # rotation mass factor of the whole vehicle union (without unit)
|
||||||
|
# if not available use ξ_t and ξ_w
|
||||||
|
|
||||||
|
# traction unit
|
||||||
|
m_t::AbstractFloat # mass of the traction unit (in kg)
|
||||||
|
m_td::AbstractFloat # mass on the traction units driving axles (in kg)
|
||||||
|
m_tc::AbstractFloat # mass on the traction units carrying axles (in kg)
|
||||||
|
ξ_t::AbstractFloat # rotation mass factor of the traction unit (without unit)
|
||||||
|
# in case ξ_union is not available
|
||||||
|
tractiveEffortArray # list values for tractive effort (in [m/s , N])
|
||||||
|
|
||||||
|
f_Rtd0::AbstractFloat # coefficient for basic resistance due to the traction units driving axles (in ‰)
|
||||||
|
f_Rtc0::AbstractFloat # coefficient for basic resistance due to the traction units carring axles (in ‰)
|
||||||
|
F_Rt2::AbstractFloat #todo: war mal:forceRT2 # coefficient for air resistance of the traction units (in N)
|
||||||
|
Δv_t::AbstractFloat # coefficient for velocitiy difference between traction unit and outdoor air
|
||||||
|
|
||||||
|
|
||||||
|
# set of wagons
|
||||||
|
m_w::AbstractFloat # mass of the set of wagons (in kg)
|
||||||
|
ξ_w::AbstractFloat # rotation mass factor of the set of wagons (without unit)
|
||||||
|
# in case ξ_union is not available
|
||||||
|
f_Rw0::AbstractFloat # coefficient for basic resistance of the set of wagons (in ‰)
|
||||||
|
f_Rw1::AbstractFloat # coefficient for resistance to rolling of the set of wagons (in ‰)
|
||||||
|
f_Rw2::AbstractFloat # coefficient for air resistance of the set of wagons (in ‰)
|
||||||
|
Δv_w::AbstractFloat # coefficient for velocitiy difference between set of wagons and outdoor air (in m/s)
|
||||||
|
end # mutable struct Vehicle
|
||||||
|
Vehicle()=Vehicle("", 0, "", 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, [], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
|
||||||
|
|
||||||
|
|
||||||
|
## path separated in smaler sections
|
||||||
|
struct PathSection
|
||||||
|
s_start::AbstractFloat # starting point of the section (in m)
|
||||||
|
s_startNext::AbstractFloat # starting point of the next section (in m)
|
||||||
|
v_limit::AbstractFloat # paths speed limt (in m/s)
|
||||||
|
n::AbstractFloat # gradient (in ‰)
|
||||||
|
# TODO: curve radius
|
||||||
|
# TODO: turnout
|
||||||
|
# TODO: tunnel
|
||||||
|
f_Rp::AbstractFloat # specific path resistance of the section (in ‰)
|
||||||
|
end # struct pathSection
|
||||||
|
PathSection()=(0.0, 0.0, 0.0, 0.0, 0.0)
|
||||||
|
|
||||||
|
struct Path
|
||||||
|
name::String # paths name
|
||||||
|
id # paths identifier
|
||||||
|
sections::Vector{PathSection} # list of PathSection elements
|
||||||
|
# s_start in firt entry defines the paths beginning
|
||||||
|
# s_startNext in last entry defines the paths ending
|
||||||
|
end # struct Path
|
||||||
|
Path()=("", 0, Vector{PathSection}())
|
||||||
|
|
||||||
|
|
||||||
|
## a waypoint is the smallest element of the driving course. A step of the step approach is between two waypoints
|
||||||
|
mutable struct Waypoint
|
||||||
|
i::Integer # identifier and counter variable of the dricing course
|
||||||
|
s::AbstractFloat # position (in m)
|
||||||
|
Δs::AbstractFloat # step size (in m)
|
||||||
|
t::AbstractFloat # point in time (in s)
|
||||||
|
Δt::AbstractFloat # step size (in s)
|
||||||
|
v::AbstractFloat # velocity (in m/s)
|
||||||
|
Δv::AbstractFloat # step size (in m/s)
|
||||||
|
a::AbstractFloat # acceleration (in m/s^2)
|
||||||
|
W_T::AbstractFloat # mechanical work (in Ws)
|
||||||
|
ΔW_T::AbstractFloat # mechanical work in this step (in Ws)
|
||||||
|
E::AbstractFloat # energy consumption (in Ws)
|
||||||
|
ΔE::AbstractFloat # energy consumption in this step (in Ws)
|
||||||
|
F_T::AbstractFloat # tractive effort (in N)
|
||||||
|
F_R::AbstractFloat # resisting force (in N)
|
||||||
|
F_Rp::AbstractFloat # line resistanc (in N)
|
||||||
|
F_Runion::AbstractFloat # vehicle resistance (in N)
|
||||||
|
F_Rt::AbstractFloat # traction unit resistance (in N)
|
||||||
|
F_Rw::AbstractFloat # set of wagons resistance (in N)
|
||||||
|
end # mutable struct Waypoint
|
||||||
|
Waypoint()=Waypoint(0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
|
||||||
|
Waypoint(original::Waypoint)=Waypoint(original.i, original.s, original.Δs, original.t, original.Δt, original.v, original.Δv, original.a, original.W_T, original.ΔW_T, original.E, original.ΔE, original.F_T, original.F_R, original.F_Rp, original.F_Runion, original.F_Rt, original.F_Rw)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## different sections the whole path can be devided in the following
|
||||||
|
## smallest section of the path is the behavior section. It relates to the containing waypoints via their identifier.
|
||||||
|
mutable struct BehaviorSection
|
||||||
|
type::String # type of behavior section: "starting", "cruisingBeforeAcceleration", "acceleration", "cruising", "coasting", "cruisingAfterCoasting" or "braking"
|
||||||
|
s_total::AbstractFloat # total length (in m)
|
||||||
|
s_start::AbstractFloat # first position (in m)
|
||||||
|
s_end::AbstractFloat # last position (in m)
|
||||||
|
t_total::AbstractFloat # total running time (in s)
|
||||||
|
E_total::AbstractFloat # total energy consumption (in Ws)
|
||||||
|
v_entry::AbstractFloat # entry speed (in m/s)
|
||||||
|
v_exit::AbstractFloat # exit speed (in m/s)
|
||||||
|
waypoints::Vector{Integer} # list of identifiers of the containing waypoints
|
||||||
|
end # mutable struct BehaviorSection
|
||||||
|
BehaviorSection()=BehaviorSection("", 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, [])
|
||||||
|
function BehaviorSection(original::BehaviorSection)
|
||||||
|
bsWaypoints=[]
|
||||||
|
for i in 1:length(original.waypoints)
|
||||||
|
push!(bsWaypoints, original.waypoints[i])
|
||||||
|
end
|
||||||
|
return BehaviorSection(original.type, original.s_total, original.s_start, original.s_end, original.t_total, original.E_total, original.v_entry, original.v_exit, bsWaypoints)
|
||||||
|
end
|
||||||
|
|
||||||
|
## a characteristic section is a part of the moving section. It contains behavior sections.
|
||||||
|
mutable struct CharacteristicSection
|
||||||
|
id::Integer # identifier
|
||||||
|
s_total::AbstractFloat # total length (in m)
|
||||||
|
s_start::AbstractFloat # first position (in m)
|
||||||
|
s_end::AbstractFloat # last position (in m)
|
||||||
|
t_total::AbstractFloat # total running time (in s)
|
||||||
|
E_total::AbstractFloat # total energy consumption (in Ws)
|
||||||
|
v_limit::AbstractFloat # speed limit (in m/s)
|
||||||
|
v_reach::AbstractFloat # maximum reachable speed (in m/s)
|
||||||
|
v_entry::AbstractFloat # maximum entry speed (in m/s)
|
||||||
|
v_exit::AbstractFloat # maximum exit speed (in m/s)
|
||||||
|
f_Rp::AbstractFloat # spedific line resistance (in ‰)
|
||||||
|
behaviorSections::AbstractDict{String, BehaviorSection} # list of containing behavior sections
|
||||||
|
end # mutable struct CharacteristicSection
|
||||||
|
CharacteristicSection()=CharacteristicSection(0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Dict{String, BehaviorSection}())
|
||||||
|
function CharacteristicSection(original::CharacteristicSection)
|
||||||
|
copy=CharacteristicSection(original.id, original.s_total, original.s_start, original.s_end, original.t_total, original.E_total, original.v_limit, original.v_reach, original.v_entry, original.v_exit, original.f_Rp, Dict{String, BehaviorSection}())
|
||||||
|
allBs=["starting", "cruisingBeforeAcceleration","acceleration", "cruising", "coasting","cruisingAfterCoasting", "braking"]
|
||||||
|
for bs in 1: length(allBs)
|
||||||
|
if haskey(original.behaviorSections, allBs[bs])
|
||||||
|
merge!(copy.behaviorSections, Dict(allBs[bs]=>BehaviorSection(get(original.behaviorSections, allBs[bs], BehaviorSection()))))
|
||||||
|
end #if
|
||||||
|
end #for
|
||||||
|
return copy
|
||||||
|
end #function CharacteristicSection
|
||||||
|
|
||||||
|
## for the energy saving operation mode it is nesserary to compare different energy saving modifications. These are part of the moving section.
|
||||||
|
mutable struct EnergySavingModification
|
||||||
|
csId::Integer # identifier of the characteristic section
|
||||||
|
type::String # type of energy saving modification: "increasing coasting" "decreasing maximum velocity" or "combination of decreasing maximum velocity and coasting"
|
||||||
|
ΔE::AbstractFloat # saved energy (in Ws)
|
||||||
|
Δt::AbstractFloat # time loss (in s)
|
||||||
|
ratio::AbstractFloat # ratio of ΔE and Δt (in Ws/s)
|
||||||
|
csModified::CharacteristicSection # the modified characteristic section
|
||||||
|
drivingCourseModified::Vector{Waypoint} #drivingCourse for the modified characteristic section
|
||||||
|
end # mutable struct EnergySavingModification
|
||||||
|
EnergySavingModification()=EnergySavingModification(0, "", 0.0, 0.0, 0.0, CharacteristicSection(), [])
|
||||||
|
function EnergySavingModification(original::EnergySavingModification)
|
||||||
|
copy=EnergySavingModification(original.csId, original.type, original.ΔE, original.Δt, original.ratio, CharacteristicSection(), Waypoint[])
|
||||||
|
copy.csModified=CharacteristicSection(original.csModified)
|
||||||
|
for i in 1:length(original.drivingCourseModified)
|
||||||
|
push!(copy.drivingCourseModified, Waypoint(original.drivingCourseModified[i]))
|
||||||
|
end
|
||||||
|
return copy
|
||||||
|
end #function EnergySavingModification
|
||||||
|
|
||||||
|
|
||||||
|
## a moving section contains all the smaller sections from one stop to an other
|
||||||
|
mutable struct MovingSection
|
||||||
|
id # identifier
|
||||||
|
s_total::AbstractFloat # total length (in m)
|
||||||
|
s_start::AbstractFloat # first position (in m)
|
||||||
|
s_end::AbstractFloat # last position (in m)
|
||||||
|
t_total::AbstractFloat # total running time (in s)
|
||||||
|
E_total::AbstractFloat # total energy consumption (in Ws)
|
||||||
|
t_recovery::AbstractFloat # total recovery time for energy-saving modifications (in s)
|
||||||
|
t_recoveryAvailable::AbstractFloat # still available recovery time for energy-saving modifications (in s)
|
||||||
|
characteristicSections::Vector{CharacteristicSection} # list of containing characteristic sections
|
||||||
|
energySavingModifications::Vector{EnergySavingModification} # list of containing all the used energy saving modifications
|
||||||
|
end # mutable struct MovingSection
|
||||||
|
MovingSection()=MovingSection(0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, [], [])
|
||||||
|
function MovingSection(original::MovingSection)
|
||||||
|
copy=MovingSection(original.id, original.s_total, original.s_start, original.s_end, original.t_total, original.E_total, original.t_recovery, original.t_recoveryAvailable, [], [])
|
||||||
|
for csId in 1:length(original.characteristicSections)
|
||||||
|
push!(copy.characteristicSections, CharacteristicSection(original.characteristicSections[csId]))
|
||||||
|
end #for
|
||||||
|
for modId in 1:length(original.energySavingModifications)
|
||||||
|
push!(copy.energySavingModifications, EnergySavingModification(original.energySavingModifications[modId]))
|
||||||
|
end #for
|
||||||
|
return copy
|
||||||
|
end #function CharacteristicSection
|
||||||
|
|
||||||
|
end #module
|
|
@ -0,0 +1,70 @@
|
||||||
|
# Ausführen im pkg mode mit >>>>> ] test RailwayDrivingDynamics <<<<
|
||||||
|
|
||||||
|
using RailwayDrivingDynamics, Test
|
||||||
|
|
||||||
|
|
||||||
|
# das hier waren die zu testenden Funktionen:
|
||||||
|
#foo(x::T, y::T) where T <: Real = x + y - 5
|
||||||
|
#bar(z::Float64) = foo(sqrt(z), z)
|
||||||
|
#=
|
||||||
|
That file may typically contain calls to other
|
||||||
|
test files via include(fname). In our case there
|
||||||
|
is only two functions to test, so we will just
|
||||||
|
write in runtests.jl directly:
|
||||||
|
=#
|
||||||
|
|
||||||
|
# todo: Beispiel:
|
||||||
|
#=
|
||||||
|
@testset "foo" begin
|
||||||
|
x, y = 5, 7
|
||||||
|
@test foo(x, y) == 7
|
||||||
|
x = "blah"
|
||||||
|
@test_throws MethodError foo(x, y)
|
||||||
|
end
|
||||||
|
|
||||||
|
@testset "bar" begin
|
||||||
|
z = 4.
|
||||||
|
@test bar(z) == 1.
|
||||||
|
end =#
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#vehicleFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Fahrzeug- und Streckendaten\\Fahrzeuge\\vehicle_passenger_IC2.yaml"
|
||||||
|
#vehicleFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Fahrzeug- und Streckendaten\\Fahrzeuge\\vehicle_passenger_SiemensDesiroClassic.yaml"
|
||||||
|
vehicleFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Fahrzeug- und Streckendaten\\Fahrzeuge\\vehicle_freight_V90withOreConsist.yaml"
|
||||||
|
|
||||||
|
#pathFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Fahrzeug- und Streckendaten\\Strecken\\path_10km_noGradient.yaml"
|
||||||
|
pathFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Fahrzeug- und Streckendaten\\Strecken\\path_10km_differentGradient.yaml"
|
||||||
|
#pathFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Fahrzeug- und Streckendaten\\Strecken\\path_10km_different_v_limits.yaml"
|
||||||
|
#pathFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Fahrzeug- und Streckendaten\\Strecken\\path_real_Ostsachsen_V220_DG-DN_spp_5.yaml"
|
||||||
|
|
||||||
|
settingsFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Julia-Files\\settings.yaml"
|
||||||
|
#settingsFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Julia-Files\\settings_s.yaml"
|
||||||
|
|
||||||
|
testDict=calculateDrivingDynamics(vehicleFilePath, pathFilePath, settingsFilePath)
|
||||||
|
|
||||||
|
println("Vergleichswerte für FBS berechnet")
|
||||||
|
|
||||||
|
#=
|
||||||
|
|
||||||
|
#pathFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Julia-Files\\track_DAFW_DAFN.yaml"
|
||||||
|
#pathFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Julia-Files\\test.yaml"
|
||||||
|
settingsFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Julia-Files\\settings.yaml"
|
||||||
|
testDict=calculateDrivingDynamics(vehicleFilePath, pathFilePath, settingsFilePath)
|
||||||
|
|
||||||
|
vehicleFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Julia-Files\\vehicle.yaml"
|
||||||
|
pathFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Julia-Files\\track_DAFW_DAFN.yaml"
|
||||||
|
#pathFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Julia-Files\\path_Heilbronn.yaml"
|
||||||
|
|
||||||
|
settingsFilePath="C:\\Users\\Offline-Konto\\Dateien\\Masterarbeit\\TU-BS_IfEV\\Julia-Files\\settings.yaml"
|
||||||
|
|
||||||
|
calculateDrivingDynamics(vehicleFilePath, pathFilePath, settingsFilePath)
|
||||||
|
|
||||||
|
=#
|
||||||
|
println("test finished")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# toto: einfach so ausführen geht nicht.
|
||||||
|
# da muss ich wahrscheilich noch anders importieren oder auf das Modul verweisen?
|
||||||
|
# Ausführen kann ich es aber auch mit>>>>> test RailwayDrivingDynamics <<<< im pkg mode. Das geht.
|
Loading…
Reference in New Issue