commit
f09a5cac9a
|
@ -0,0 +1,59 @@
|
|||
name: CI
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
tags: '*'
|
||||
pull_request:
|
||||
concurrency:
|
||||
# Skip intermediate builds: always.
|
||||
# Cancel intermediate builds: only if it is a pull request build.
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }}
|
||||
jobs:
|
||||
test:
|
||||
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
version:
|
||||
- '1.6'
|
||||
- '1.7'
|
||||
- 'nightly'
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- macOS-latest
|
||||
- windows-latest
|
||||
arch:
|
||||
# - x86
|
||||
- x64
|
||||
# - aarch64
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: julia-actions/setup-julia@v1
|
||||
with:
|
||||
version: ${{ matrix.version }}
|
||||
arch: ${{ matrix.arch }}
|
||||
- uses: julia-actions/cache@v1
|
||||
- uses: julia-actions/julia-buildpkg@v1
|
||||
- uses: julia-actions/julia-runtest@v1
|
||||
docs:
|
||||
name: Documentation
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: julia-actions/setup-julia@v1
|
||||
with:
|
||||
version: '1'
|
||||
- uses: julia-actions/julia-buildpkg@v1
|
||||
- uses: julia-actions/julia-docdeploy@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}
|
||||
- run: |
|
||||
julia --project=docs -e '
|
||||
using Documenter: DocMeta, doctest
|
||||
using TrainRuns
|
||||
DocMeta.setdocmeta!(TrainRuns, :DocTestSetup, :(using TrainRuns); recursive=true)
|
||||
doctest(TrainRuns)'
|
|
@ -0,0 +1,16 @@
|
|||
name: CompatHelper
|
||||
on:
|
||||
schedule:
|
||||
- cron: 0 0 * * *
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
CompatHelper:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Pkg.add("CompatHelper")
|
||||
run: julia -e 'using Pkg; Pkg.add("CompatHelper")'
|
||||
- name: CompatHelper.main()
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
COMPATHELPER_PRIV: ${{ secrets.DOCUMENTER_KEY }}
|
||||
run: julia -e 'using CompatHelper; CompatHelper.main()'
|
|
@ -0,0 +1,15 @@
|
|||
name: TagBot
|
||||
on:
|
||||
issue_comment:
|
||||
types:
|
||||
- created
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
TagBot:
|
||||
if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: JuliaRegistries/TagBot@v1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
ssh: ${{ secrets.DOCUMENTER_KEY }}
|
|
@ -0,0 +1,14 @@
|
|||
name: Register Package
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: Version to register or component to bump
|
||||
required: true
|
||||
jobs:
|
||||
register:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: julia-actions/RegisterAction@latest
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
60
CHANGELOG.md
60
CHANGELOG.md
|
@ -9,6 +9,36 @@ Categories: Added, Changed, Deprecated, Removed, Fixed, and Security.
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
* dependency JSONSchema
|
||||
* validation of YAML input via JSON schema
|
||||
|
||||
### Changed
|
||||
* renamed TrainRun into TrainRuns
|
||||
* replaced settings::Dict with type Settings as struct
|
||||
* replaced path::Dict with type Path as struct
|
||||
* replaced train::Dict with type Train as struct
|
||||
* restructured examples/ and data/ in docs/ and test/
|
||||
* modified test to work with Julia Testsets and with simplier naming of input files
|
||||
* renamed Validate.jl into types.jl
|
||||
* renamed TrainRunCalc.jl into calc.jl
|
||||
* moved trainrun function from calc.jl to TrainRun.jl
|
||||
* moved createDataPoint() from behavior.jl to types.jl
|
||||
* moved createBehaviorSection() from behavior.jl to types.jl
|
||||
* moved createMovingSection() from characteristics.jl to types.jl
|
||||
* moved createCharacteristicSection() from characteristics.jl to types.jl
|
||||
* changed title of include files from upper case to lower case
|
||||
* changed seperation of submodules into a single module with file include
|
||||
* updated test files to railtoolkit/schema (2022.05)
|
||||
|
||||
### Removed
|
||||
* dependency Plots and CSV
|
||||
* AdditionalOutput.jl
|
||||
* EnergySaving.jl
|
||||
* test/testEnums.jl
|
||||
* import.jl
|
||||
* export.jl
|
||||
* settings for CSV export
|
||||
|
||||
## Version [0.8] 2022-01-20
|
||||
|
||||
|
@ -142,18 +172,18 @@ Modules and variables were renamed.
|
|||
Proof of concept and master thesis submission.
|
||||
|
||||
|
||||
[Unreleased]: https://github.com/railtoolkit/TrainRun.jl/compare/v0.8...master
|
||||
[0.8]: https://github.com/railtoolkit/TrainRun.jl/compare/v0.7...v0.8
|
||||
[0.7]: https://github.com/railtoolkit/TrainRun.jl/compare/v0.6.2...v0.7
|
||||
[0.6.2]: https://github.com/railtoolkit/TrainRun.jl/compare/v0.6.1...v0.6.2
|
||||
[0.6.1]: https://github.com/railtoolkit/TrainRun.jl/compare/v0.6...v0.6.1
|
||||
[0.6]: https://github.com/railtoolkit/TrainRun.jl/compare/v0.5.3...v0.6
|
||||
[0.5.3]: https://github.com/railtoolkit/TrainRun.jl/compare/v0.5.2...v0.5.3
|
||||
[0.5.2]: https://github.com/railtoolkit/TrainRun.jl/compare/v0.5.1...v0.5.2
|
||||
[0.5.1]: https://github.com/railtoolkit/TrainRun.jl/compare/v0.5...v0.5.1
|
||||
[0.5]: https://github.com/railtoolkit/TrainRun.jl/compare/v0.4.1...v0.5
|
||||
[0.4.1]: https://github.com/railtoolkit/TrainRun.jl/compare/v0.4...v0.4.1
|
||||
[0.4]: https://github.com/railtoolkit/TrainRun.jl/compare/v0.3...v0.4
|
||||
[0.3]: https://github.com/railtoolkit/TrainRun.jl/compare/v0.2...v0.3
|
||||
[0.2]: https://github.com/railtoolkit/TrainRun.jl/compare/v0.1...v0.2
|
||||
[0.1]: https://github.com/railtoolkit/TrainRun.jl/releases/tag/v0.1
|
||||
[Unreleased]: https://github.com/railtoolkit/TrainRuns.jl/compare/v0.8...main
|
||||
[0.8]: https://github.com/railtoolkit/TrainRuns.jl/compare/v0.7...v0.8
|
||||
[0.7]: https://github.com/railtoolkit/TrainRuns.jl/compare/v0.6.2...v0.7
|
||||
[0.6.2]: https://github.com/railtoolkit/TrainRuns.jl/compare/v0.6.1...v0.6.2
|
||||
[0.6.1]: https://github.com/railtoolkit/TrainRuns.jl/compare/v0.6...v0.6.1
|
||||
[0.6]: https://github.com/railtoolkit/TrainRuns.jl/compare/v0.5.3...v0.6
|
||||
[0.5.3]: https://github.com/railtoolkit/TrainRuns.jl/compare/v0.5.2...v0.5.3
|
||||
[0.5.2]: https://github.com/railtoolkit/TrainRuns.jl/compare/v0.5.1...v0.5.2
|
||||
[0.5.1]: https://github.com/railtoolkit/TrainRuns.jl/compare/v0.5...v0.5.1
|
||||
[0.5]: https://github.com/railtoolkit/TrainRuns.jl/compare/v0.4.1...v0.5
|
||||
[0.4.1]: https://github.com/railtoolkit/TrainRuns.jl/compare/v0.4...v0.4.1
|
||||
[0.4]: https://github.com/railtoolkit/TrainRuns.jl/compare/v0.3...v0.4
|
||||
[0.3]: https://github.com/railtoolkit/TrainRuns.jl/compare/v0.2...v0.3
|
||||
[0.2]: https://github.com/railtoolkit/TrainRuns.jl/compare/v0.1...v0.2
|
||||
[0.1]: https://github.com/railtoolkit/TrainRuns.jl/releases/tag/v0.1
|
10
CITATION.cff
10
CITATION.cff
|
@ -3,7 +3,7 @@
|
|||
# Visit https://bit.ly/cffinit to generate yours today!
|
||||
---
|
||||
cff-version: 1.2.0
|
||||
title: TrainRun.jl
|
||||
title: TrainRuns.jl
|
||||
message: 'If you use this software, please cite it using these metadata.'
|
||||
type: software
|
||||
authors:
|
||||
|
@ -22,12 +22,12 @@ identifiers:
|
|||
- type: doi
|
||||
value: 10.5281/zenodo.6448564
|
||||
description: Current version
|
||||
url: 'https://www.railtoolkit.org/projects/TrainRun.jl/'
|
||||
repository: 'https://github.com/railtoolkit/TrainRun.jl'
|
||||
url: 'https://www.railtoolkit.org/projects/TrainRuns.jl/'
|
||||
repository: 'https://github.com/railtoolkit/TrainRuns.jl'
|
||||
abstract: >-
|
||||
TrainRun.jl is a step towards open science and open data in railway engineering.
|
||||
TrainRuns.jl is a step towards open science and open data in railway engineering.
|
||||
Its modular design offers the possibility to serve as a basis for future
|
||||
optimization and development. TrainRun.jl is suitable for qualitative
|
||||
optimization and development. TrainRuns.jl is suitable for qualitative
|
||||
calculations to compare different trains, and it is publicly available, and we
|
||||
invite others to collaborate.
|
||||
keywords:
|
||||
|
|
|
@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
|
|||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at [INSERT EMAIL ADDRESS]. All
|
||||
reported by contacting the project team at railtoolkit@ownx.net. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
|
|
|
@ -5,7 +5,83 @@ email, or any other method with the owners of this repository before making a ch
|
|||
|
||||
Please note we have a code of conduct, please follow it in all your interactions with the project.
|
||||
|
||||
# Pull Request Process
|
||||
## Julia Development Environment
|
||||
|
||||
* add your changes to the CHANGELOG.md under [Unreleased]
|
||||
* TODO!
|
||||
Link your local git repository to Julia:
|
||||
```console
|
||||
$ ln -s ~/path/to/TrainRuns.jl ~/.julia/dev/TrainRuns
|
||||
```
|
||||
|
||||
Have a look how to develop Julia packages: https://github.com/ShozenD/julia-pkg-dev
|
||||
You might want to use `Revise.jl` as well:
|
||||
```julia
|
||||
Pkg.add("Revise")
|
||||
```
|
||||
and then just load with `using Revise` (preferably by putting it in the `~/.julia/config/startup.jl` file).
|
||||
|
||||
You can overide the standard TrainRuns package with the local development branch (see linking above) with:
|
||||
```julia
|
||||
julia> # use the ] key
|
||||
(@v1.x) pkg> develop TrainRuns
|
||||
(@v1.x) pkg> # use backspace
|
||||
julia> using TrainRuns # local development branch will be loaded
|
||||
```
|
||||
|
||||
If you want to add a dependency use:
|
||||
```julia
|
||||
julia> # use the ] key
|
||||
(@v1.x) pkg> activate TrainRuns
|
||||
(TrainRuns) pkg>
|
||||
```
|
||||
|
||||
## Files in TrainRuns
|
||||
|
||||
| file | concern |
|
||||
| --------------- | ------------------------------ |
|
||||
| TrainRuns.jl | main file and function |
|
||||
| types.jl | special TrainRuns types |
|
||||
| constructors.jl | type constructors |
|
||||
| formulary.jl | formulars from literature |
|
||||
| output.jl | transformation into DataFrames |
|
||||
|
||||
## Reporting Issues
|
||||
|
||||
* It's always good to start with a quick search for an existing issue to post on,
|
||||
or related issues for context, before opening a new issue
|
||||
* Including minimal examples is greatly appreciated
|
||||
* If it's a bug, or unexpected behaviour, reproducing on the latest development version
|
||||
(`Pkg.add(name="TrainRuns", rev="main")`) is a good gut check and can streamline the process,
|
||||
along with including the first two lines of output from `versioninfo()`
|
||||
|
||||
## Style Guidelines
|
||||
|
||||
TODO
|
||||
|
||||
## Git Recommendations For Pull Requests
|
||||
|
||||
* Avoid working from the `main` branch of your fork, creating a new branch will make it
|
||||
easier if TrainRuns.jl `main` branch changes and you need to update your pull request;
|
||||
* All PRs and issues should be opened against the `main` branch not against the current release;
|
||||
* Run tests of your code before sending any commit to GitHub. Only push changes when
|
||||
the tests of the change are passing locally. In particular note that it is not a problem
|
||||
if you send several commits in one push command to GitHub as CI will be run only once then;
|
||||
* If any conflicts arise due to changes in TrainRuns.jl `main` branch, prefer updating your pull
|
||||
request branch with `git rebase` (rather than `git merge`), since the latter will introduce a merge
|
||||
commit that might confuse GitHub when displaying the diff of your PR, which makes your changes more
|
||||
difficult to review. Alternatively use conflict resolution tool available at GitHub;
|
||||
* Please try to use descriptive commit messages to simplify the review process;
|
||||
* Using `git add -p` or `git add -i` can be useful to avoid accidently committing unrelated changes;
|
||||
* Maintainers get notified of all changes made on GitHub. However, what is useful is writing a short
|
||||
message after a sequence of changes is made summarizing what has changed and that the PR is ready
|
||||
for a review;
|
||||
* When linking to specific lines of code in discussion of an issue or pull request, hit the `y` key
|
||||
while viewing code on GitHub to reload the page with a URL that includes the specific commit that
|
||||
you're viewing. That way any lines of code that you refer to will still be correct in the future, even
|
||||
if additional commits are pushed to the branch you are reviewing;
|
||||
* Please make sure you follow the code formatting guidelines when submitting a PR;
|
||||
Also preferably do not modify parts of code that you are not editing as this makes
|
||||
reviewing the PR harder (it is better to open a separate maintenance PR
|
||||
if e.g. code layout can be improved);
|
||||
* If a PR is not finished yet and should not be reviewed yet then it should be opened as DRAFT
|
||||
(in this way maintainers will know that they can ignore such PR until it is made non-draft or the author
|
||||
asks for a review).
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
ISC License (ISC)
|
||||
|
||||
Copyright 2021 Max Kannenberg
|
||||
Copyright 2022 Max Kannenberg, Martin Scheidt
|
||||
|
||||
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
|
||||
|
|
22
Project.toml
22
Project.toml
|
@ -1,12 +1,24 @@
|
|||
name = "TrainRun"
|
||||
name = "TrainRuns"
|
||||
uuid = "e4541106-d44c-4e00-b50b-ecdf479fcf92"
|
||||
authors = ["Max Kannenberg"]
|
||||
authors = ["Max Kannenberg", "Martin Scheidt", "contributors"]
|
||||
version = "0.8.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"
|
||||
JSONSchema = "7d188eb4-7ad8-530c-ae41-71a32a6d4692"
|
||||
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
|
||||
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
|
||||
YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"
|
||||
|
||||
[compat]
|
||||
DataFrames = "^1"
|
||||
JSONSchema = "^1"
|
||||
YAML = "^0"
|
||||
julia = "^1.6"
|
||||
|
||||
[extras]
|
||||
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
||||
|
||||
[targets]
|
||||
test = ["Test"]
|
||||
|
|
41
README.md
41
README.md
|
@ -1,40 +1,43 @@
|
|||
# TrainRun
|
||||
# TrainRuns
|
||||
|
||||
[![License: ISC](https://img.shields.io/badge/license-ISC-green.svg)](https://opensource.org/licenses/ISC) [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6448563.svg)](https://doi.org/10.5281/zenodo.6448563)
|
||||
[![License: ISC](https://img.shields.io/badge/license-ISC-green.svg)](https://opensource.org/licenses/ISC) [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.6448563.svg)](https://doi.org/10.5281/zenodo.6448563) [![Build Status](https://github.com/railtoolkit/TrainRuns.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/railtoolkit/TrainRuns.jl/actions/workflows/CI.yml?query=branch%3Amain)
|
||||
|
||||
------------
|
||||
|
||||
# About
|
||||
|
||||
TrainRun.jl is a step towards open science and open data in railway engineering. Its modular design offers the possibility to serve as a basis for future optimization and development. TrainRun.jl is suitable for qualitative calculations to compare different trains, and it is publicly available, and we invite others to collaborate.
|
||||
TrainRuns.jl is a step towards open science and open data in railway engineering. Its modular design offers the possibility to serve as a basis for future optimization and development. TrainRuns.jl is suitable for qualitative calculations to compare different trains, and it is publicly available, and we invite others to collaborate.
|
||||
|
||||
------------
|
||||
|
||||
# Installation
|
||||
|
||||
The required julia packages are
|
||||
- YAML.jl
|
||||
- Dates.jl
|
||||
- DataFrames.jl
|
||||
- CSV.jl
|
||||
- Plots.jl
|
||||
Use the package manager provided by julia:
|
||||
```julia
|
||||
julia> # use the ] key
|
||||
(@v1.x) pkg> add TrainRuns
|
||||
(@v1.x) pkg> # use backspace
|
||||
julia> using TrainRuns
|
||||
```
|
||||
|
||||
Review the settings.yaml file for your appropriate settings.
|
||||
The required julia packages are
|
||||
- YAML.jl
|
||||
- JSONSchema.jl
|
||||
- DataFrames.jl
|
||||
|
||||
------------
|
||||
|
||||
# Minimal working example
|
||||
|
||||
```julia
|
||||
include("../src/TrainRun.jl")
|
||||
using .TrainRun
|
||||
using TrainRuns
|
||||
|
||||
train_directory = "data/trains/train_freight_V90withOreConsist.yaml"
|
||||
running_path_directory = "data/paths/path_1_10km_nConst_vConst.yaml"
|
||||
settings_directory = "data/settings.yaml"
|
||||
(train, running_path, settings) = importYamlFiles(train_directory, running_path_directory, setting_directory)
|
||||
train = Train("test/data/trains/freight.yaml")
|
||||
path = Path("test/data/paths/const.yaml")
|
||||
|
||||
train_run = trainRun(train, running_path, settings)
|
||||
runtime = trainrun(train, path)
|
||||
|
||||
println("The train needs $runtime seconds for the running path.")
|
||||
```
|
||||
|
||||
------------
|
||||
|
@ -47,11 +50,11 @@ This work was supervised by South Westphalia University of Applied Sciences and
|
|||
|
||||
# License
|
||||
|
||||
[![Open Source Initiative Approved License logo](https://opensource.org/files/OSIApproved_100X125.png "Open Source Initiative Approved License logo")](https://opensource.org)
|
||||
[![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
|
||||
Copyright 2022 Max Kannenberg, Martin Scheidt
|
||||
|
||||
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.
|
||||
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
path:
|
||||
name: "10 km, no gradient, 160 km/h"
|
||||
pointsOfInterest: [999, 2000, 3333.3, 5000, 7777, 9000, 9500.95] # points of interest: positions in m
|
||||
sectionStarts: # with path speed limt (in m/s) # [s in m, v_limit in m/s, f_Rp in ‰]
|
||||
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp in ‰]
|
||||
- [0, 160, 0]
|
||||
- [10000, 160, 0]
|
|
@ -1,19 +0,0 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
path:
|
||||
name: "10 km, different gradient, 160 km/h"
|
||||
pointsOfInterest: [999, 2000, 3333.3, 5000, 7777, 9000, 9500.95] # points of interest: positions in m
|
||||
sectionStarts: # with path speed limt (in m/s) # [s in m, v_limit in m/s, f_Rp in ‰]
|
||||
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp 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]
|
|
@ -1,17 +0,0 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
path:
|
||||
name: "10 km, no gradient, different speed limits"
|
||||
pointsOfInterest: [999, 2000, 3333.3, 5000, 7777, 9000, 9500.95] # points of interest: positions in m
|
||||
sectionStarts: # with path speed limt (in m/s) # [s in m, v_limit in m/s, f_Rp in ‰]
|
||||
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp 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]
|
|
@ -1,354 +0,0 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
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) # [s in m, v_limit in m/s, f_Rp in ‰]
|
||||
sectionStarts_kmh: # with path speed limt (in km/h) # [s in m, v_limit in km/h, f_Rp in ‰]
|
||||
- [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.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]
|
|
@ -1,12 +0,0 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
settings:
|
||||
# settings for the simulation
|
||||
massModel: "homogeneous strip" # model type of train mass "mass point" or "homogeneous strip"
|
||||
stepVariable: "s in m" # step variable of the step method "s in m", "t in s" or "v in m/s"
|
||||
stepSize: 10 # step size (unit depends on stepVariable s in m, t in s and v in m/s)
|
||||
operationModeMinimumRunningTime: true # operation mode "minimum running time"
|
||||
operationModeMinimumEnergyConsumption: false # operation mode "minimum energy consumption"
|
||||
typeOfOutput: "julia dictionary" # output as "julia dictionary" or as "CSV"
|
||||
detailOfOutput: "driving course" # should the output be only the value of the "running time" or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
|
||||
csvDirectory: "~/Desktop/TrainRun"
|
|
@ -1,12 +0,0 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
settings:
|
||||
# settings for the simulation
|
||||
massModel: "mass point" # model type of train mass "mass point" or "homogeneous strip"
|
||||
stepVariable: "s in m" # step variable of the step method "s in m", "t in s" or "v in m/s"
|
||||
stepSize: 10 # step size (unit depends on stepVariable s in m, t in s and v in m/s)
|
||||
operationModeMinimumRunningTime: true # operation mode "minimum running time"
|
||||
operationModeMinimumEnergyConsumption: false # operation mode "minimum energy consumption"
|
||||
typeOfOutput: "julia dictionary" # output as "julia dictionary" or as "CSV"
|
||||
detailOfOutput: "driving course" # should the output be only the value of the "running time" or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
|
||||
csvDirectory: "~/Desktop/TrainRun"
|
|
@ -1,12 +0,0 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
settings:
|
||||
# settings for the simulation
|
||||
massModel: "mass point" # model type of train mass "mass point" or "homogeneous strip"
|
||||
stepVariable: "s in m" # step variable of the step method "s in m", "t in s" or "v in m/s"
|
||||
stepSize: 10 # step size (unit depends on stepVariable s in m, t in s and v in m/s)
|
||||
operationModeMinimumRunningTime: true # operation mode "minimum running time"
|
||||
operationModeMinimumEnergyConsumption: false # operation mode "minimum energy consumption"
|
||||
typeOfOutput: "CSV" # output as "julia dictionary" or as "CSV"
|
||||
detailOfOutput: "running time" # should the output be only the value of the "running time" or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
|
||||
csvDirectory: "~/Desktop/TrainRun"
|
|
@ -1,12 +0,0 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
settings:
|
||||
# settings for the simulation
|
||||
massModel: "homogeneous strip" # model type of train mass "mass point" or "homogeneous strip"
|
||||
stepVariable: "t in s" # step variable of the step method "s in m", "t in s" or "v in m/s"
|
||||
stepSize: 3.0 # step size (unit depends on stepVariable s in m, t in s and v in m/s)
|
||||
operationModeMinimumRunningTime: true # operation mode "minimum running time"
|
||||
operationModeMinimumEnergyConsumption: false # operation mode "minimum energy consumption"
|
||||
typeOfOutput: "julia dictionary" # output as "julia dictionary" or as "CSV"
|
||||
detailOfOutput: "driving course" # should the output be only the value of the "running time" or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
|
||||
csvDirectory: "~/Desktop/TrainRun"
|
|
@ -1,12 +0,0 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
settings:
|
||||
# settings for the simulation
|
||||
massModel: "mass point" # model type of train mass "mass point" or "homogeneous strip"
|
||||
stepVariable: "t in s" # step variable of the step method "s in m", "t in s" or "v in m/s"
|
||||
stepSize: 3.0 # step size (unit depends on stepVariable s in m, t in s and v in m/s)
|
||||
operationModeMinimumRunningTime: true # operation mode "minimum running time"
|
||||
operationModeMinimumEnergyConsumption: false # operation mode "minimum energy consumption"
|
||||
typeOfOutput: "julia dictionary" # output as "julia dictionary" or as "CSV"
|
||||
detailOfOutput: "driving course" # should the output be only the value of the "running time" or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
|
||||
csvDirectory: "~/Desktop/TrainRun"
|
|
@ -1,12 +0,0 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
settings:
|
||||
# settings for the simulation
|
||||
massModel: "mass point" # model type of train mass "mass point" or "homogeneous strip"
|
||||
stepVariable: "v in m/s" # step variable of the step method "s in m", "t in s" or "v in m/s"
|
||||
stepSize: 0.1 # step size (unit depends on stepVariable s in m, t in s and v in m/s)
|
||||
operationModeMinimumRunningTime: true # operation mode "minimum running time"
|
||||
operationModeMinimumEnergyConsumption: false # operation mode "minimum energy consumption"
|
||||
typeOfOutput: "julia dictionary" # output as "julia dictionary" or as "CSV"
|
||||
detailOfOutput: "driving course" # should the output be only the value of the "running time" or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
|
||||
csvDirectory: "~/Desktop/TrainRun"
|
|
@ -1,112 +0,0 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
train:
|
||||
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)
|
||||
length: 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_train:
|
||||
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)
|
||||
type: freight # "freight" or "passenger" (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]
|
|
@ -1,192 +0,0 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
train:
|
||||
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))
|
||||
length: 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_train:
|
||||
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)
|
||||
type: passenger # "freight" or "passenger" (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]
|
|
@ -1,152 +0,0 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
train:
|
||||
name: "Siemens Desiro Classic" # (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
|
||||
length: 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_train: 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)
|
||||
type: passenger # "freight" or "passenger" (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 + 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,10 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
settings:
|
||||
# default settings for the calculation
|
||||
massModel: "mass_point" # type of train model used: "mass_point" or "homogeneous_strip"
|
||||
stepVariable: "distance" # variable of the linear multistep method: "distance", "time" or "velocity"
|
||||
stepSize: 20 # step size, unit depends on stepVariable - distance in meter, time in seconds and velocity in meter/second.
|
||||
approxLevel: 3 # value for approximation; used when rounding or interating
|
||||
outputDetail: "running_time" # single value "running_time", array of "points_of_interest",complete array "driving_course", or dict() "everything"
|
||||
outputFormat: "dataframe" # output as "dataframe" or as "dict"
|
|
@ -0,0 +1,3 @@
|
|||
[deps]
|
||||
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
|
||||
TrainRuns = "e4541106-d44c-4e00-b50b-ecdf479fcf92"
|
|
@ -0,0 +1,32 @@
|
|||
#!/usr/bin/env julia
|
||||
|
||||
import TrainRuns
|
||||
|
||||
paths=[]
|
||||
push!(paths, importFromYaml(:path, "data/paths/path_1_10km_nConst_vConst.yaml"))
|
||||
push!(paths, importFromYaml(:path, "data/paths/path_2_10km_nVar_vConst.yaml"))
|
||||
push!(paths, importFromYaml(:path, "data/paths/path_3_10km_nConst_vVar.yaml"))
|
||||
push!(paths, importFromYaml(:path, "data/paths/path_4_real_Germany_EastSaxony_DG-DN.yaml"))
|
||||
|
||||
settings=[]
|
||||
push!(settings, importFromYaml(:settings, "data/settings/settings_distanceStep_massPoint.yaml"))
|
||||
|
||||
trains=[]
|
||||
push!(trains, importFromYaml(:train, "data/trains/train_freight_V90withOreConsist.yaml"))
|
||||
push!(trains, importFromYaml(:train, "data/trains/train_passenger_SiemensDesiroClassic.yaml"))
|
||||
push!(trains, importFromYaml(:train, "data/trains/train_passenger_IC2.yaml"))
|
||||
|
||||
for path in paths
|
||||
# println(" - - - - - - - - -")
|
||||
# println("path: ", path[:name])
|
||||
for train in trains
|
||||
# println("train: ", train[:name])
|
||||
for settings in settings
|
||||
resultsDict = trainrun(train, path, settings)
|
||||
if haskey(settings, :outputFormat) && settings[:outputFormat] == "CSV"
|
||||
exportToCsv(resultsDict, settings)
|
||||
sleep(2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env julia
|
||||
|
||||
using TrainRuns
|
||||
|
||||
train = Train("test/data/trains/freight.yaml")
|
||||
path = Path("test/data/paths/const.yaml")
|
||||
|
||||
runtime = trainrun(train, path)
|
||||
|
||||
println("The train needs $runtime seconds for the running path.")
|
|
@ -0,0 +1,24 @@
|
|||
using TrainRuns
|
||||
using Documenter
|
||||
|
||||
DocMeta.setdocmeta!(TrainRuns, :DocTestSetup, :(using TrainRuns); recursive=true)
|
||||
|
||||
makedocs(;
|
||||
modules=[TrainRuns],
|
||||
authors="Max Kannenberg, Martin Scheidt, and contributors",
|
||||
repo="https://github.com/railtoolkit/TrainRuns.jl/blob/{commit}{path}#{line}",
|
||||
sitename="TrainRuns.jl",
|
||||
format=Documenter.HTML(;
|
||||
prettyurls=get(ENV, "CI", "false") == "true",
|
||||
canonical="https://railtoolkit.github.io/TrainRuns.jl",
|
||||
assets=String[],
|
||||
),
|
||||
pages=[
|
||||
"Home" => "index.md",
|
||||
],
|
||||
)
|
||||
|
||||
deploydocs(;
|
||||
repo="github.com/railtoolkit/TrainRuns.jl",
|
||||
devbranch="development",
|
||||
)
|
|
@ -0,0 +1,14 @@
|
|||
```@meta
|
||||
CurrentModule = TrainRuns
|
||||
```
|
||||
|
||||
# TrainRuns
|
||||
|
||||
Documentation for [TrainRuns](https://github.com/railtoolkit/TrainRuns.jl).
|
||||
|
||||
```@index
|
||||
```
|
||||
|
||||
```@autodocs
|
||||
Modules = [TrainRuns]
|
||||
```
|
|
@ -1,44 +0,0 @@
|
|||
#!/usr/bin/env julia
|
||||
# -*- coding: UTF-8 -*-
|
||||
# __julia-version__ = 1.7.0
|
||||
# __author__ = "Max Kannenberg"
|
||||
# __copyright__ = "2021"
|
||||
# __license__ = "ISC"
|
||||
|
||||
include("../src/TrainRun.jl")
|
||||
using .TrainRun
|
||||
|
||||
allPaths=[]
|
||||
push!(allPaths, importFromYaml(:path, "data/paths/path_1_10km_nConst_vConst.yaml"))
|
||||
push!(allPaths, importFromYaml(:path, "data/paths/path_2_10km_nVar_vConst.yaml"))
|
||||
push!(allPaths, importFromYaml(:path, "data/paths/path_3_10km_nConst_vVar.yaml"))
|
||||
push!(allPaths, importFromYaml(:path, "data/paths/path_4_real_Germany_EastSaxony_DG-DN.yaml"))
|
||||
|
||||
allSettings=[]
|
||||
push!(allSettings, importFromYaml(:settings, "data/settings/settings_distanceStep_massPoint.yaml"))
|
||||
|
||||
allTrains=[]
|
||||
push!(allTrains, importFromYaml(:train, "data/trains/train_freight_V90withOreConsist.yaml"))
|
||||
push!(allTrains, importFromYaml(:train, "data/trains/train_passenger_SiemensDesiroClassic.yaml"))
|
||||
push!(allTrains, importFromYaml(:train, "data/trains/train_passenger_IC2.yaml"))
|
||||
|
||||
for path in allPaths
|
||||
# println(" - - - - - - - - -")
|
||||
# println("path: ", path[:name])
|
||||
for train in allTrains
|
||||
# println("train: ", train[:name])
|
||||
for settings in allSettings
|
||||
resultsDict = trainRun(train, path, settings)
|
||||
if haskey(settings, :typeOfOutput) && settings[:typeOfOutput] == "CSV"
|
||||
exportToCsv(resultsDict, settings)
|
||||
sleep(2)
|
||||
end
|
||||
# println("")
|
||||
end
|
||||
end
|
||||
# println("")
|
||||
end
|
||||
|
||||
# println("")
|
||||
# println("________________________")
|
||||
# println("")
|
|
@ -1,19 +0,0 @@
|
|||
#!/usr/bin/env julia
|
||||
# -*- coding: UTF-8 -*-
|
||||
# __julia-version__ = 1.7.0
|
||||
# __author__ = "Max Kannenberg"
|
||||
# __copyright__ = "2021"
|
||||
# __license__ = "ISC"
|
||||
|
||||
include("../src/TrainRun.jl")
|
||||
using .TrainRun
|
||||
|
||||
train_directory = "data/trains/train_freight_V90withOreConsist.yaml"
|
||||
running_path_directory = "data/paths/path_1_10km_nConst_vConst.yaml"
|
||||
setting_directory = "data/settings/settings_distanceStep_massPoint_runningTime.yaml"
|
||||
(train, running_path, settings) = importYamlFiles(train_directory, running_path_directory, setting_directory)
|
||||
|
||||
runtime = trainRun(train, running_path, settings)
|
||||
|
||||
exportToCsv(runtime, settings)
|
||||
println("The V 90 with 10 ore wagons needs $runtime seconds for 10 km with no gradient.")
|
|
@ -1,210 +0,0 @@
|
|||
#!/usr/bin/env julia
|
||||
# -*- coding: UTF-8 -*-
|
||||
# __julia-version__ = 1.7.2
|
||||
# __author__ = "Max Kannenberg"
|
||||
# __copyright__ = "2020-2022"
|
||||
# __license__ = "ISC"
|
||||
|
||||
# INFO: AdditionalOutput should not be used because it is not completed yet. It was used to show first results during development.
|
||||
# TODO: It has to be optimized so that the created plots and printed information is clear and understandable.
|
||||
|
||||
module AdditionalOutput
|
||||
|
||||
using Plots
|
||||
|
||||
export plotResults, plotDrivingCourse, printImportantValues, printSectionInformation
|
||||
|
||||
function plotResults(output::Dict)
|
||||
opModeMinTime = output[:settings][:operationModeMinimumRunningTime]
|
||||
opModeMinEnergy = output[:settings][:operationModeMinimumEnergyConsumption]
|
||||
|
||||
if opModeMinTime == true && opModeMinEnergy == true
|
||||
plotDrivingCourse(output[:drivingCourseMinimumRunningTime], output[:drivingCourseMinimumEnergyConsumption])
|
||||
elseif opModeMinTime == true
|
||||
plotDrivingCourse(output[:drivingCourseMinimumRunningTime])
|
||||
elseif opModeMinEnergy == true
|
||||
plotDrivingCourse(output[:drivingCourseMinimumEnergyConsumption])
|
||||
else
|
||||
output[:settings][:detailOfOutput] == "everything" && println("No Output was demanded. So no plot is created.")
|
||||
end
|
||||
|
||||
return true
|
||||
end #function plotResults
|
||||
|
||||
function plotResults(drivingCourse::Vector{Dict})
|
||||
plotDrivingCourse(drivingCourse)
|
||||
|
||||
return true
|
||||
end #function plotResults
|
||||
|
||||
function plotResults(singleValue::AbstractFloat)
|
||||
println("Not able to plot the single value ",singleValue)
|
||||
|
||||
return false
|
||||
end #function plotResults
|
||||
|
||||
function plotDrivingCourse(drivingCourse::Vector{Dict})
|
||||
a=[]
|
||||
E=[]
|
||||
s=[]
|
||||
t=[]
|
||||
v=[]
|
||||
for i in 1:length(drivingCourse)
|
||||
push!(a, drivingCourse[i][:a])
|
||||
push!(E, drivingCourse[i][:E])
|
||||
push!(s, drivingCourse[i][:s])
|
||||
push!(t, drivingCourse[i][:t])
|
||||
push!(v, drivingCourse[i][:v])
|
||||
end #for
|
||||
|
||||
# p1=plot([s], [v], title = "v in m/s", label = ["v"], xlabel = "s in m")
|
||||
p1=plot([s/1000], [v*3.6], title = "v in km/h", label = ["v"], xlabel = "s in km")
|
||||
|
||||
# p2=plot([t], [v], title = "v in m/s", label = ["v"], xlabel = "t in s")
|
||||
p2=plot([t/60], [v*3.6], title = "v in km/h", label = ["v"], xlabel = "t in min")
|
||||
|
||||
# p3=plot([s], [t], title = "t in s", label = ["t"], xlabel = "s in m")
|
||||
|
||||
# p4=plot([t], [s], title = "s in m", label = ["s"], xlabel = "t in s")
|
||||
|
||||
#p5=plot([s], [E], title = "E in Ws", label = ["E"], xlabel = "s in m")
|
||||
p5=plot([s/1000], [E], title = "E in Ws", label = ["E"], xlabel = "s in km")
|
||||
|
||||
#p6=plot([t], [E], title = "E in Ws", label = ["E"], xlabel = "t in s")
|
||||
p6=plot([t/60], [E], title = "E in Ws", label = ["E"], xlabel = "t in min")
|
||||
|
||||
all=plot(p1, p2, p5, p6, layout = (2, 2), legend = false)
|
||||
#=
|
||||
# p5=plot([s], [E], title = "E in Ws", label = ["E"], xlabel = "s in m")
|
||||
|
||||
# p6=plot([t], [E], title = "E in Ws", label = ["E"], xlabel = "t in s")
|
||||
|
||||
all=plot(p1, p2, layout = (1, 2), legend = false)=#
|
||||
# all=plot(p1, p2, p3, p4, p5, p6, layout = (3, 2), legend = false)
|
||||
display(all)
|
||||
println("Plots for different variables have been created.")
|
||||
end #function plotDrivingCourse
|
||||
|
||||
function plotDrivingCourse(drivingCourseMinimumRunningTime::Vector{Dict},drivingCourseMinimumEnergyConsumption::Vector{Dict})
|
||||
a_minTime=[]
|
||||
E_minTime=[]
|
||||
s_minTime=[]
|
||||
t_minTime=[]
|
||||
v_minTime=[]
|
||||
for i in 1:length(drivingCourseMinimumRunningTime)
|
||||
push!(a_minTime, drivingCourseMinimumRunningTime[i][:a])
|
||||
push!(E_minTime, drivingCourseMinimumRunningTime[i][:E])
|
||||
push!(s_minTime, drivingCourseMinimumRunningTime[i][:s])
|
||||
push!(t_minTime, drivingCourseMinimumRunningTime[i][:t])
|
||||
push!(v_minTime, drivingCourseMinimumRunningTime[i][:v])
|
||||
end #for
|
||||
|
||||
a_minEnergy=[]
|
||||
E_minEnergy=[]
|
||||
s_minEnergy=[]
|
||||
t_minEnergy=[]
|
||||
v_minEnergy=[]
|
||||
for i in 1:length(drivingCourseMinimumEnergyConsumption)
|
||||
push!(a_minEnergy, drivingCourseMinimumEnergyConsumption[i][:a])
|
||||
push!(E_minEnergy, drivingCourseMinimumEnergyConsumption[i][:E])
|
||||
push!(s_minEnergy, drivingCourseMinimumEnergyConsumption[i][:s])
|
||||
push!(t_minEnergy, drivingCourseMinimumEnergyConsumption[i][:t])
|
||||
push!(v_minEnergy, drivingCourseMinimumEnergyConsumption[i][:v])
|
||||
end #for
|
||||
|
||||
p1=plot([s_minTime,s_minEnergy],
|
||||
[v_minTime,v_minEnergy],
|
||||
title = "v in m/s",
|
||||
label = ["v for t_min" "v for E_min"],
|
||||
xlabel = "s in m")# lw = 3)
|
||||
|
||||
p2=plot([t_minTime,t_minEnergy],
|
||||
[v_minTime,v_minEnergy],
|
||||
title = "v in m/s",
|
||||
label = ["v for t_min" "v for E_min"],
|
||||
xlabel = "t in s")
|
||||
|
||||
# p3=plot([s_minTime,s_minEnergy],
|
||||
# [t_minTime,t_minEnergy],
|
||||
# title = "t in s",
|
||||
# label = ["t for t_min" "t for E_min"],
|
||||
# xlabel = "s in m")
|
||||
|
||||
# p4=plot([t_minTime,t_minEnergy],
|
||||
# [s_minTime,s_minEnergy],
|
||||
# title = "s in m",
|
||||
# label = ["s for t_min" "s for E_min"],
|
||||
# xlabel = "t in s")
|
||||
|
||||
p5=plot([s_minTime,s_minEnergy],
|
||||
[E_minTime,E_minEnergy],
|
||||
title = "E in Ws",
|
||||
label = ["E for t_min" "E for E_min"],
|
||||
xlabel = "s in m")
|
||||
|
||||
p6=plot([t_minTime,t_minEnergy],
|
||||
[E_minTime,E_minEnergy],
|
||||
title = "E in Ws",
|
||||
label = ["E for t_min" "E for E_min"],
|
||||
xlabel = "t in s")
|
||||
|
||||
# all=plot(p1, p2, p3, p4, p5, p6, layout = (3, 2), legend = false)
|
||||
all=plot(p1, p2, p5, p6, layout = (2, 2), legend = false)
|
||||
display(all)
|
||||
println("Plots for different variables have been created.")
|
||||
end #function plotDrivingCourse
|
||||
|
||||
function printImportantValues(dataPoints::Vector{Dict})
|
||||
println("i behavior s in m v in km/h t in min a in m/s^2 F_R in k N F_T in k N E in k Wh")
|
||||
for i in 1:length(dataPoints)
|
||||
println(dataPoints[i][:i],". ",dataPoints[i][:behavior]," ",dataPoints[i][:s]," ",dataPoints[i][:v]*3.6," ",dataPoints[i][:t]/60," ",dataPoints[i][:a]," ",dataPoints[i][:F_R]/1000," ",dataPoints[i][:F_T]/1000," ",dataPoints[i][:E]/3600/1000)
|
||||
end #for
|
||||
println("i behavior s in m v in km/h t in min a in m/s^2 F_R in k N F_T in k N E in k Wh")
|
||||
end #function printImportantValues
|
||||
|
||||
function printSectionInformation(movingSection::Dict)
|
||||
CSs::Vector{Dict} = movingSection[:characteristicSections]
|
||||
|
||||
println("MS with length=", movingSection[:length]," with t=", movingSection[:t])
|
||||
#allBSs=[:breakFree, :clearing, :accelerating, :clearing2, :accelerating2, :clearing3, :accelerating3, :cruising, :downhillBraking, :diminishing, :coasting, :braking, :standstill]
|
||||
for csId in 1:length(CSs)
|
||||
println("CS ",csId," with length=", CSs[csId][:length]," with t=", CSs[csId][:t])
|
||||
# for bs in 1: length(allBSs)
|
||||
# if haskey(CSs[csId][:behaviorSections], allBSs[bs])
|
||||
# println("BS ",allBSs[bs], " with s_entry=", CSs[csId][:behaviorSections][allBSs[bs]][:s_entry], " and length=",CSs[csId][:behaviorSections][allBSs[bs]][:length]) # and t=", CSs[csId][:behaviorSections][allBSs[bs]][:t])
|
||||
# # for point in 1:length(CSs[csId][:behaviorSections][allBSs[bs]][:dataPoints])
|
||||
# # println(CSs[csId][:behaviorSections][allBSs[bs]][:dataPoints][point])
|
||||
# # end
|
||||
# end #if
|
||||
# end #for
|
||||
|
||||
tempBSs = collect(keys(CSs[csId][:behaviorSections]))
|
||||
while length(tempBSs) > 0
|
||||
currentBS = :default
|
||||
for bs in 1: length(tempBSs)
|
||||
if currentBS == :default
|
||||
currentBS = tempBSs[bs]
|
||||
else
|
||||
if CSs[csId][:behaviorSections][currentBS][:s_entry] > CSs[csId][:behaviorSections][tempBSs[bs]][:s_entry]
|
||||
currentBS = tempBSs[bs]
|
||||
end
|
||||
end
|
||||
end #for
|
||||
|
||||
println("BS ",currentBS, " with s_entry=", CSs[csId][:behaviorSections][currentBS][:s_entry], " and length=",CSs[csId][:behaviorSections][currentBS][:length]) # and t=", CSs[csId][:behaviorSections][currentBS][:t])
|
||||
# for point in 1:length(CSs[csId][:behaviorSections][currentBS][:dataPoints])
|
||||
# println(CSs[csId][:behaviorSections][currentBS][:dataPoints][point])
|
||||
# end
|
||||
|
||||
newTempBSs = []
|
||||
for bs in 1: length(tempBSs)
|
||||
if currentBS != tempBSs[bs]
|
||||
push!(newTempBSs, tempBSs[bs])
|
||||
end #if
|
||||
end #for
|
||||
tempBSs = newTempBSs
|
||||
end #while
|
||||
end #for
|
||||
end #function printSectionInformation
|
||||
|
||||
end # module AdditionalOutput
|
1045
src/EnergySaving.jl
1045
src/EnergySaving.jl
File diff suppressed because it is too large
Load Diff
220
src/Export.jl
220
src/Export.jl
|
@ -1,220 +0,0 @@
|
|||
#!/usr/bin/env julia
|
||||
# -*- coding: UTF-8 -*-
|
||||
# __julia-version__ = 1.7.2
|
||||
# __author__ = "Max Kannenberg"
|
||||
# __copyright__ = "2020-2022"
|
||||
# __license__ = "ISC"
|
||||
|
||||
module Export
|
||||
|
||||
using CSV, DataFrames, Dates
|
||||
|
||||
export exportToCsv
|
||||
|
||||
function exportToCsv(runningTime::AbstractFloat, settings::Dict)
|
||||
createCsvFile(runningTime, settings)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function exportToCsv(dataPointsToExport::Vector{Dict}, settings::Dict)
|
||||
createCsvFile(dataPointsToExport, settings)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function exportToCsv(output::Dict)
|
||||
if output[:settings][:typeOfOutput] == "CSV"
|
||||
pathName = output[:path][:name]
|
||||
trainName = output[:train][:name]
|
||||
|
||||
if output[:settings][:operationModeMinimumRunningTime] == true
|
||||
operationMode = "minimum running time"
|
||||
if output[:settings][:detailOfOutput] == "points of interest"
|
||||
dataPointsToExport = output[:pointsOfInterestMinimumRunningTime]
|
||||
else
|
||||
dataPointsToExport = output[:drivingCourseMinimumRunningTime]
|
||||
end
|
||||
createCsvFile(dataPointsToExport, operationMode, pathName, trainName, output[:settings])
|
||||
end
|
||||
if output[:settings][:operationModeMinimumEnergyConsumption] == true
|
||||
operationMode = "minimum energy consumption"
|
||||
if output[:settings][:detailOfOutput] == "points of interest"
|
||||
dataPointsToExport = output[:pointsOfInterestMinimumEnergyConsumption]
|
||||
else
|
||||
dataPointsToExport = output[:drivingCourseMinimumEnergyConsumption]
|
||||
end
|
||||
createCsvFile(dataPointsToExport, operationMode, pathName, trainName, output[:settings])
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end #function exportToCsv
|
||||
|
||||
function createCsvFile(runningTime::AbstractFloat, settings::Dict)
|
||||
# create DataFrame with running time information
|
||||
df = DataFrame(column1=["t (in s)", runningTime])
|
||||
|
||||
# save DataFrame as a CSV-file at csvDirectory
|
||||
date = Dates.now()
|
||||
dateString = Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
|
||||
|
||||
csvFilePath = settings[:csvDirectory]*"/"*dateString*"_RunningTime.csv"
|
||||
|
||||
CSV.write(csvFilePath, df, header=false)
|
||||
println("The output CSV file has been created at ",csvFilePath)
|
||||
|
||||
return true
|
||||
end #function createCsvFile
|
||||
|
||||
|
||||
function createCsvFile(dataPointsToExport::Vector{Dict}, settings::Dict)
|
||||
detailOfOutput = settings[:detailOfOutput]
|
||||
|
||||
header = ["i", "behavior", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_wagons (in N)", "ΔW (in Ws)","W (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]
|
||||
columnSymbols = [:i, :behavior, :Δs, :s, :Δt, :t, :Δv, :v, :F_T, :F_R, :R_path, :R_train, :R_traction, :R_wagons, :ΔW, :W, :ΔE, :E, :a]
|
||||
|
||||
allColumns = Array{Any,1}[]
|
||||
for column in 1:length(header)
|
||||
currentColumn = Any[]
|
||||
push!(currentColumn, header[column])
|
||||
for point in dataPointsToExport
|
||||
push!(currentColumn, point[columnSymbols[column]])
|
||||
end
|
||||
push!(allColumns, currentColumn)
|
||||
end # for
|
||||
|
||||
|
||||
# combine the columns in a data frame and saving it as a CSV-file at csvDirectory
|
||||
if detailOfOutput == "driving course" || detailOfOutput == "points of interest"
|
||||
df = DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3], c4=allColumns[4], c5=allColumns[5], c6=allColumns[6], c7=allColumns[7], c8=allColumns[8], c9=allColumns[9], c10=allColumns[10], c11=allColumns[11], c12=allColumns[12], c13=allColumns[13], c14=allColumns[14], c15=allColumns[15], c16=allColumns[16], c17=allColumns[17], c18=allColumns[18], c19=allColumns[19])
|
||||
|
||||
else
|
||||
println("")
|
||||
end
|
||||
|
||||
date = Dates.now()
|
||||
dateString=Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
|
||||
csvFilePath=settings[:csvDirectory]*"/"*dateString*"_DataPoints.csv"
|
||||
CSV.write(csvFilePath, df, header=false)
|
||||
println("The output CSV file has been created at ",csvFilePath)
|
||||
|
||||
return true
|
||||
end #function createCsvFile
|
||||
|
||||
|
||||
function createCsvFile(dataPointsToExport::Vector{Dict}, operationMode::String, pathName::String, trainName::String, settings::Dict)
|
||||
detailOfOutput = settings[:detailOfOutput]
|
||||
|
||||
massModel = settings[:massModel]
|
||||
stepVariable = settings[:stepVariable]
|
||||
stepSize = string(settings[:stepSize])
|
||||
|
||||
# create accumulated data block
|
||||
accumulatedData = Array{Any, 1}[]
|
||||
push!(accumulatedData, ["i", "behavior", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_wagons (in N)", "ΔW (in Ws)","W (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]) # push header to accumulatedData
|
||||
for point in dataPointsToExport
|
||||
row = [point[:i], point[:behavior], point[:Δs], point[:s], point[:Δt], point[:t], point[:Δv], point[:v], point[:F_T], point[:F_R], point[:R_path], point[:R_train], point[:R_traction], point[:R_wagons], point[:ΔW], point[:W], point[:ΔE], point[:E], point[:a]]
|
||||
push!(accumulatedData, row) # push row to accumulatedData
|
||||
end
|
||||
|
||||
#create information block
|
||||
allColumns=Array{Any,1}[]
|
||||
push!(allColumns, ["path name", "train name", "operation mode", "mass model", "step variable", "step size", ""])
|
||||
push!(allColumns, [pathName, trainName, operationMode, massModel, stepVariable, stepSize, ""])
|
||||
for column in 3:length(accumulatedData[1])
|
||||
push!(allColumns, ["", "", "", "", "", "", ""])
|
||||
end # for
|
||||
|
||||
# add driving data to the array
|
||||
header = accumulatedData[1]
|
||||
for column in 1:length(accumulatedData[1])
|
||||
push!(allColumns[column], header[column])
|
||||
for row in accumulatedData[2:end]
|
||||
push!(allColumns[column], row[column])
|
||||
end
|
||||
end # for
|
||||
|
||||
# combine the columns in a data frame and saving it as a CSV-file at csvDirectory
|
||||
df = DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3], c4=allColumns[4], c5=allColumns[5], c6=allColumns[6], c7=allColumns[7], c8=allColumns[8], c9=allColumns[9], c10=allColumns[10], c11=allColumns[11], c12=allColumns[12], c13=allColumns[13], c14=allColumns[14], c15=allColumns[15], c16=allColumns[16], c17=allColumns[17], c18=allColumns[18], c19=allColumns[19])
|
||||
|
||||
date = Dates.now()
|
||||
dateString=Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
|
||||
if operationMode == "minimum running time"
|
||||
csvFilePath=settings[:csvDirectory]*"/"*dateString*"_MinimumRunningTime.csv"
|
||||
elseif operationMode == "minimum energy consumption"
|
||||
csvFilePath=settings[:csvDirectory]*"/"*dateString*"_MinimumEnergyConsumption.csv"
|
||||
else
|
||||
# should not be possible
|
||||
end
|
||||
CSV.write(csvFilePath, df, header=false)
|
||||
println("The output CSV file has been created for ",operationMode," at ",csvFilePath)
|
||||
|
||||
return true
|
||||
end #function createCsvFile
|
||||
|
||||
|
||||
|
||||
#=
|
||||
function createCsvFile(movingSection::Dict, dataPointsToExport::Vector{Dict}, operationMode::String, pathName::String, trainName::String, settings::Dict)
|
||||
detailOfOutput = settings[:detailOfOutput]
|
||||
|
||||
massModel = settings[:massModel]
|
||||
stepVariable = settings[:stepVariable]
|
||||
stepSize = string(settings[:stepSize])
|
||||
|
||||
# create accumulated data block
|
||||
accumulatedData = Array{Any, 1}[]
|
||||
if detailOfOutput == "minimal"
|
||||
push!(accumulatedData, ["s (in m)", "t (in s)","E (in Ws)"]) # push header to accumulatedData
|
||||
row = [movingSection[:length], movingSection[:t], movingSection[:E]]
|
||||
push!(accumulatedData, row) # push row to accumulatedData
|
||||
elseif detailOfOutput == "driving course" || detailOfOutput == "points of interest"
|
||||
push!(accumulatedData, ["i", "behavior", "Δs (in m)", "s (in m)", "Δt (in s)","t (in s)","Δv (in m/s)","v (in m/s)","F_T (in N)","F_R (in N)","R_path (in N)","R_train (in N)","R_traction (in N)","R_wagons (in N)", "ΔW (in Ws)","W (in Ws)","ΔE (in Ws)","E (in Ws)","a (in m/s^2)"]) # push header to accumulatedData
|
||||
for point in dataPointsToExport
|
||||
row = [point[:i], point[:behavior], point[:Δs], point[:s], point[:Δt], point[:t], point[:Δv], point[:v], point[:F_T], point[:F_R], point[:R_path], point[:R_train], point[:R_traction], point[:R_wagons], point[:ΔW], point[:W], point[:ΔE], point[:E], point[:a]]
|
||||
push!(accumulatedData, row) # push row to accumulatedData
|
||||
end
|
||||
end
|
||||
|
||||
#create information block
|
||||
allColumns=Array{Any,1}[]
|
||||
push!(allColumns, ["path name", "train name", "operation mode", "mass model", "step variable", "step size", ""])
|
||||
push!(allColumns, [pathName, trainName, operationMode, massModel, stepVariable, stepSize, ""])
|
||||
for column in 3:length(accumulatedData[1])
|
||||
push!(allColumns, ["", "", "", "", "", "", ""])
|
||||
end # for
|
||||
|
||||
# add driving data to the array
|
||||
header = accumulatedData[1]
|
||||
for column in 1:length(accumulatedData[1])
|
||||
push!(allColumns[column], header[column])
|
||||
for row in accumulatedData[2:end]
|
||||
push!(allColumns[column], row[column])
|
||||
end
|
||||
end # for
|
||||
|
||||
# combine the columns in a data frame and saving it as a CSV-file at csvDirectory
|
||||
if detailOfOutput == "minimal"
|
||||
df = DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3])
|
||||
elseif detailOfOutput=="driving course" || detailOfOutput == "points of interest"
|
||||
df = DataFrame(c1=allColumns[1], c2=allColumns[2],c3=allColumns[3], c4=allColumns[4], c5=allColumns[5], c6=allColumns[6], c7=allColumns[7], c8=allColumns[8], c9=allColumns[9], c10=allColumns[10], c11=allColumns[11], c12=allColumns[12], c13=allColumns[13], c14=allColumns[14], c15=allColumns[15], c16=allColumns[16], c17=allColumns[17], c18=allColumns[18], c19=allColumns[19])
|
||||
end
|
||||
|
||||
date = Dates.now()
|
||||
dateString=Dates.format(date, "yyyy-mm-dd_HH.MM.SS")
|
||||
if operationMode == "minimum running time"
|
||||
csvFilePath=settings[:csvDirectory]*"/"*dateString*"_MinimumRunningTime.csv"
|
||||
elseif operationMode == "minimum energy consumption"
|
||||
csvFilePath=settings[:csvDirectory]*"/"*dateString*"_MinimumEnergyConsumption.csv"
|
||||
else
|
||||
# should not be possible
|
||||
end
|
||||
CSV.write(csvFilePath, df, header=false)
|
||||
println("The output CSV file has been created for ",operationMode," at ",csvFilePath)
|
||||
|
||||
return true
|
||||
end #function createCsvFile
|
||||
=#
|
||||
|
||||
end #module Export
|
|
@ -1,44 +0,0 @@
|
|||
#!/usr/bin/env julia
|
||||
# -*- coding: UTF-8 -*-
|
||||
# __julia-version__ = 1.7.2
|
||||
# __author__ = "Max Kannenberg"
|
||||
# __copyright__ = "2020-2022"
|
||||
# __license__ = "ISC"
|
||||
|
||||
module Import
|
||||
|
||||
import YAML
|
||||
|
||||
export importYamlFiles, importFromYaml
|
||||
|
||||
"""
|
||||
Read the input information from YAML files for train, path and settings, save it in different dictionaries and return them.
|
||||
"""
|
||||
function importYamlFiles(trainDirectory::String, pathDirectory::String, settingsDirectory::String)
|
||||
train = importFromYaml(:train, trainDirectory)
|
||||
path = importFromYaml(:path, pathDirectory)
|
||||
settings = importFromYaml(:settings, settingsDirectory)
|
||||
|
||||
return (train, path, settings)
|
||||
end #function importYamlFiles
|
||||
|
||||
"""
|
||||
Read the train information from a YAML file, save it in a Dict and return it.
|
||||
"""
|
||||
function importFromYaml(dataType::Symbol, directory::String)
|
||||
dataSet = String(dataType)
|
||||
data = YAML.load(open(directory))
|
||||
if collect(keys(data))[1] != dataSet
|
||||
error("ERROR at reading the ", dataSet, " yaml file: The data set is called ", collect(keys(data))[1]," and not ", dataSet, ".")
|
||||
end
|
||||
dataKeys = collect(keys(data[dataSet]))
|
||||
dataKeys = collect(keys(data[dataSet]))
|
||||
dataValues = collect(values(data[dataSet]))
|
||||
dictionary = Dict()
|
||||
for number in 1:length(dataKeys)
|
||||
merge!(dictionary, Dict(Symbol(dataKeys[number]) => dataValues[number]))
|
||||
end
|
||||
return dictionary
|
||||
end # function importFromYaml
|
||||
|
||||
end # module Input
|
|
@ -1,55 +0,0 @@
|
|||
#!/usr/bin/env julia
|
||||
# -*- coding: UTF-8 -*-
|
||||
# __julia-version__ = 1.7.2
|
||||
# __author__ = "Max Kannenberg"
|
||||
# __copyright__ = "2020-2022"
|
||||
# __license__ = "ISC"
|
||||
|
||||
module TrainRun
|
||||
|
||||
# include main module TrainRunCalc
|
||||
include("./TrainRunCalc.jl")
|
||||
|
||||
# include additional modules
|
||||
include("./Import.jl")
|
||||
include("./Export.jl")
|
||||
|
||||
# include additional modules that are not recommended to use in this state
|
||||
include("./AdditionalOutput.jl")
|
||||
include("./EnergySaving.jl")
|
||||
|
||||
# use main module TrainRunCalc
|
||||
using .TrainRunCalc
|
||||
|
||||
# use additional modules
|
||||
using .Import
|
||||
using .Export
|
||||
|
||||
# use additional modules that are not recommended to use in this state
|
||||
using .AdditionalOutput
|
||||
using .EnergySaving
|
||||
|
||||
# main function
|
||||
export trainRun,
|
||||
|
||||
# import functions
|
||||
importYamlFiles, importFromYaml,
|
||||
|
||||
# functions for saving energy that are not recommended to use in this state
|
||||
addOperationModeEnergySaving!,
|
||||
|
||||
# export functions
|
||||
exportToCsv,
|
||||
|
||||
# functions for visualising results that are not recommended to use in this state
|
||||
plotResults, plotDrivingCourse, printImportantValues, printSectionInformation
|
||||
|
||||
# approximationLevel = 6 # value for approximation to intersections
|
||||
# TODO: define it here and give it to each function? (Behavior, EnergySaving, ..)
|
||||
|
||||
"""
|
||||
TODO: Package description
|
||||
"""
|
||||
|
||||
|
||||
end # module TrainRun
|
|
@ -0,0 +1,64 @@
|
|||
#!/usr/bin/env julia
|
||||
# -*- coding: UTF-8 -*-
|
||||
# __julia-version__ = 1.7.2
|
||||
# __author__ = "Max Kannenberg, Martin Scheidt"
|
||||
# __copyright__ = "2020-2022"
|
||||
# __license__ = "ISC"
|
||||
__precompile__(true)
|
||||
|
||||
module TrainRuns
|
||||
|
||||
## loading standard library packages
|
||||
using UUIDs, Dates, Statistics
|
||||
## loading external packages
|
||||
using YAML, JSONSchema, DataFrames
|
||||
|
||||
export
|
||||
## Interface
|
||||
trainrun, Train, Path, Settings
|
||||
|
||||
## global variables
|
||||
global g = 9.80665 # acceleration due to gravity (in m/s^2)
|
||||
global μ = 0.2 # friction as constant, todo: implement as function
|
||||
global Δv_air = 15.0/3.6 # coefficient for velocitiy difference between train and outdoor air (in m/s)
|
||||
|
||||
## include package files
|
||||
include("types.jl")
|
||||
include("constructors.jl")
|
||||
include("formulary.jl")
|
||||
include("calc.jl")
|
||||
include("characteristics.jl")
|
||||
include("behavior.jl")
|
||||
include("output.jl")
|
||||
|
||||
## main function
|
||||
"""
|
||||
trainrun(train::Train, path::Path, settings::Settings)
|
||||
|
||||
Calculate the running time of a `train` on a `path`.
|
||||
The `settings` provides the choice of models for the calculation.
|
||||
`settings` can be omitted. If so, a default is used.
|
||||
The running time will be return in seconds.
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> trainrun(train, path)
|
||||
xxx.xx # in seconds
|
||||
```
|
||||
"""
|
||||
function trainrun(train::Train, path::Path, settings=Settings()::Settings)
|
||||
# prepare the input data
|
||||
movingSection = determineCharacteristics(path, train, settings)
|
||||
settings.outputDetail == :everything && println("The moving section has been prepared.")
|
||||
|
||||
# calculate the train run for oparation mode "minimum running time"
|
||||
(movingSection, drivingCourse) = calculateMinimumRunningTime!(movingSection, settings, train)
|
||||
settings.outputDetail == :everything && println("The driving course for the shortest running time has been calculated.")
|
||||
|
||||
# accumulate data and create an output dictionary
|
||||
output = createOutput(train, settings, path, movingSection, drivingCourse)
|
||||
|
||||
return output
|
||||
end # function trainrun
|
||||
|
||||
end # module TrainRuns
|
757
src/Validate.jl
757
src/Validate.jl
|
@ -1,757 +0,0 @@
|
|||
#!/usr/bin/env julia
|
||||
# -*- coding: UTF-8 -*-
|
||||
# __julia-version__ = 1.7.2
|
||||
# __author__ = "Max Kannenberg"
|
||||
# __copyright__ = "2022"
|
||||
# __license__ = "ISC"
|
||||
|
||||
# TODO: 2022-04-07: if EnergySaving should be used. The train type has do be defined and checked
|
||||
module Validate
|
||||
|
||||
export checkAndSetInput!
|
||||
|
||||
|
||||
approximationLevel = 6 # value for approximation to intersections TODO further explanation
|
||||
|
||||
"""
|
||||
Read the input information from YAML files for train, path and settings, save it in different dictionaries and return them.
|
||||
"""
|
||||
function checkAndSetInput!(train::Dict, path::Dict, settings::Dict)
|
||||
checkAndSetTrain!(train)
|
||||
checkAndSetPath!(path)
|
||||
checkAndSetSettings!(settings)
|
||||
|
||||
if settings[:detailOfOutput] == "points of interest" && !haskey(path, :pointsOfInterest)
|
||||
settings[:detailOfOutput] = "driving course"
|
||||
println("INFO at checking the input for settings and path: settings[:detailOfOutput] is 'points of interest' but the path does not have a list for pointsOfInterest. Therefore the detailOfOut is changed to 'driving course'.")
|
||||
end
|
||||
return (train, path, settings)
|
||||
end #function checkAndSetInput!
|
||||
|
||||
"""
|
||||
Read the train information from a YAML file, save it in a train Dict and return it.
|
||||
"""
|
||||
function checkAndSetTrain!(train::Dict)
|
||||
# check train information from input dictionary
|
||||
|
||||
checkAndSetString!(train, "train", :name, "") # train's name
|
||||
# add train's identifier if not existing
|
||||
if !(haskey(train, :id) && train[:id]!=nothing)
|
||||
merge!(train, Dict(:id =>1))
|
||||
end
|
||||
checkAndSetString!(train, "train", :type, "passenger", ["passenger", "freight"]) # train type "passenger" or "freight"
|
||||
|
||||
checkAndSetPositiveNumberWithDifferentNames!(train, "train", :length, :l_train, "m", 20.0) # total length (in m)
|
||||
# TODO: or just use: checkAndSetPositiveNumber!(train, "train", :length, "m", 20.0)
|
||||
|
||||
checkAndSetSpeedLimit!(train) # train's speed limit (in m/s)
|
||||
checkAndSetBrakingAcceleration!(train) # a_braking
|
||||
|
||||
checkAndSetPositiveNumber!(train, "train", :m_td, "kg", 80000) # mass on the traction unit's driving axles (in kg)
|
||||
checkAndSetPositiveNumber!(train, "train", :m_tc, "kg", 0.0) # mass on the traction unit's carrying axles (in kg)
|
||||
checkAndSetSum!(train, "train", :m_t, :m_td, :m_tc) # mass of the traction unit (in kg)
|
||||
|
||||
checkAndSetPositiveNumber!(train, "train", :m_w, "kg", 0.0) # mass of the set of wagons (consist) (in kg)
|
||||
checkAndSetSum!(train, "train", :m_train, :m_t, :m_w) # total mass (in kg)
|
||||
if train[:m_train] <= 0.0
|
||||
error("ERROR at checking the input for the train: The train's mass has to be higher than 0.0 kg.")
|
||||
end
|
||||
|
||||
checkAndSetRotationMassFactors!(train)
|
||||
checkAndSetTractiveEffortVelocityPairs!(train) # pairs of velocity and tractive effort
|
||||
|
||||
# coefficients for the vehicle resistance of the traction unit
|
||||
checkAndSetRealNumber!(train, "train", :Δv_t, "m/s", 15.0/3.6) # coefficient for velocitiy difference between traction unit and outdoor air (in m/s)
|
||||
checkAndSetPositiveNumber!(train, "train", :f_Rtd0, "‰", 0.0) # coefficient for basic resistance due to the traction units driving axles (in ‰)
|
||||
checkAndSetPositiveNumber!(train, "train", :f_Rtc0, "‰", 0.0) # coefficient for basic resistance due to the traction units carring axles (in ‰)
|
||||
checkAndSetPositiveNumber!(train, "train", :F_Rt2, "N", 0.0) # coefficient for air resistance of the traction units (in N)
|
||||
|
||||
# coefficients for the vehicle resistance of the set of wagons (consist)
|
||||
checkAndSetRealNumber!(train, "train", :Δv_w, "m/s", getDefault_Δv_w(train[:type])) # coefficient for velocitiy difference between set of wagons (consist) and outdoor air (in m/s)
|
||||
checkAndSetPositiveNumber!(train, "train", :f_Rw0, "‰", 0.0) # coefficient for basic resistance of the set of wagons (consist) (in ‰)
|
||||
checkAndSetPositiveNumber!(train, "train", :f_Rw1, "‰", 0.0) # coefficient for the consists resistance to rolling (in ‰)
|
||||
checkAndSetPositiveNumber!(train, "train", :f_Rw2, "‰", 0.0) # coefficient fo the consistsr air resistance (in ‰)
|
||||
|
||||
# inform the user about keys of the input dictionary that are not used in this tool
|
||||
usedKeys = [:name, :id, :type,
|
||||
:length, :l_train, :v_limit, :v_limit_kmh, :a_braking,
|
||||
:m_train, :m_t, :m_td, :m_tc, :m_w,
|
||||
:ξ_train, :ξ_t, :ξ_w, :rotationMassFactor_train, :rotationMassFactor_t, :rotationMassFactor_w,
|
||||
:tractiveEffortVelocityPairs, :F_T_pairs, :F_T_pairs_kmh,
|
||||
:f_Rtd0, :f_Rtc0, :F_Rt2, :Δv_t,
|
||||
:f_Rw0, :f_Rw1, :f_Rw2, :Δv_w]
|
||||
informAboutUnusedKeys(collect(keys(train)), usedKeys::Vector{Symbol}, "train")
|
||||
|
||||
return train
|
||||
end #function checkAndSetTrain!
|
||||
|
||||
function checkAndSetPath!(path::Dict)
|
||||
# check path information from input dictionary
|
||||
|
||||
checkAndSetString!(path, "path", :name, "")
|
||||
# TODO checkId ? path[:id] # path identifier
|
||||
checkAndSetSections!(path)
|
||||
checkAndSetPOIs!(path)
|
||||
|
||||
# inform the user about keys of the input dictionary that are not used in this tool
|
||||
usedKeys = [:name,
|
||||
:sections, :sectionStarts, :sectionStarts_kmh,
|
||||
:pointsOfInterest]
|
||||
informAboutUnusedKeys(collect(keys(path)), usedKeys::Vector{Symbol}, "path")
|
||||
|
||||
return path
|
||||
end # function checkAndSetPath!
|
||||
|
||||
|
||||
## settings for the calculation
|
||||
function checkAndSetSettings!(settings::Dict)
|
||||
# check settings information from input dictionary
|
||||
|
||||
checkAndSetString!(settings, "settings", :massModel, "mass point", ["mass point", "homogeneous strip"]) # model type of the train's mass "mass point" or "homogeneous strip"
|
||||
checkAndSetString!(settings, "settings", :stepVariable, "s in m", ["s in m", "t in s", "v in m/s"]) # step variable of the step method "s in m", "t in s" or "v in m/s"
|
||||
|
||||
checkAndSetPositiveNumber!(settings, "settings", :stepSize, "("*settings[:stepVariable]*")", getDefaultStepSize(settings[:stepVariable])) # step size (unit depends on stepVariable: s in m, t in s and v in m/s)
|
||||
checkAndSetBool!(settings, "settings", :operationModeMinimumRunningTime, true) # operation mode "minimum running time"
|
||||
checkAndSetBool!(settings, "settings", :operationModeMinimumEnergyConsumption, false) # operation mode "minimum energy consumption"
|
||||
checkAndSetString!(settings, "settings", :typeOfOutput, "julia dictionary", ["julia dictionary", "CSV"]) # output as "julia dictionary" or as "CSV"
|
||||
|
||||
if settings[:typeOfOutput] == "CSV"
|
||||
checkAndSetString!(settings, "settings", :csvDirectory, "~/Desktop/TrainRun")
|
||||
# TODO use correct default directory
|
||||
# TODO: it could be checked if the path is existing on the pc
|
||||
end # if
|
||||
|
||||
checkAndSetString!(settings, "settings", :detailOfOutput, "running time", ["running time", "points of interest", "driving course", "everything"]) # should the output be only the value of the "running time", or an array of "points of interest" or the complete "driving course" as array or a dictionary with "everything"?
|
||||
|
||||
# inform the user about keys of the input dictionary that are not used in this tool
|
||||
usedKeys = [:massModel, :stepVariable, :stepSize,
|
||||
:operationModeMinimumRunningTime, :operationModeMinimumEnergyConsumption,
|
||||
:typeOfOutput, :detailOfOutput]
|
||||
if settings[:typeOfOutput] == "CSV"
|
||||
push!(usedKeys, :csvDirectory)
|
||||
end
|
||||
informAboutUnusedKeys(collect(keys(settings)), usedKeys::Vector{Symbol}, "settings")
|
||||
|
||||
return settings
|
||||
end # function checkAndSetSettings!
|
||||
|
||||
function checkAndSetBool!(dictionary::Dict, dictionaryType::String, key::Symbol, defaultValue::Bool)
|
||||
if haskey(dictionary,key) && dictionary[key]!=nothing
|
||||
if typeof(dictionary[key]) != Bool
|
||||
error("ERROR at checking the input for the ",dictionaryType,": The value of the key ",String(key)," is not correct. The value has to be of type Bool.")
|
||||
end
|
||||
else
|
||||
merge!(dictionary, Dict(key => defaultValue))
|
||||
defaultValue && println("INFO at checking the input for the ",dictionaryType,": The key ",String(key)," or its value is missing. Therefore ",String(key),"=",dictionary[key]," is assumed and used.")
|
||||
end
|
||||
return dictionary
|
||||
end #function checkAndSetBool!
|
||||
|
||||
function checkAndSetPositiveNumber!(dictionary::Dict, dictionaryType::String, key::Symbol, unit::String, default::Real)
|
||||
if haskey(dictionary,key) && dictionary[key]!=nothing
|
||||
if typeof(dictionary[key]) <: Real && dictionary[key] >= 0.0
|
||||
else
|
||||
error("ERROR at checking the input for the ",dictionaryType,": The value of ",String(key)," is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
merge!(dictionary, Dict(key => default))
|
||||
println("INFO at checking the input for the ",dictionaryType,": The key ",String(key)," is missing. Therefore ",String(key),"=",default," ",unit," will be assumed and used." )
|
||||
end
|
||||
|
||||
return dictionary
|
||||
end #function checkAndSetPositiveNumber!
|
||||
|
||||
# first method without a default value
|
||||
function checkAndSetPositiveNumberWithDifferentNames!(dictionary::Dict, dictionaryType::String, mainKey::Symbol, alternativeKey::Symbol, unit::String)
|
||||
mainKey_temp = -1.0
|
||||
alternativeKey_temp = -1.0
|
||||
|
||||
if haskey(dictionary, mainKey) && dictionary[mainKey]!=nothing
|
||||
if typeof(dictionary[mainKey]) <: Real && dictionary[mainKey] >= 0.0
|
||||
mainKey_temp = dictionary[mainKey]
|
||||
else
|
||||
error("ERROR at checking the input for the ",dictionaryType,": The value of ",mainKey," is no real floating point number >=0.0.")
|
||||
end
|
||||
end
|
||||
|
||||
if haskey(dictionary, alternativeKey) && dictionary[alternativeKey]!=nothing
|
||||
if typeof(dictionary[alternativeKey]) <: Real && dictionary[alternativeKey] >= 0.0
|
||||
alternativeKey_temp = dictionary[alternativeKey]
|
||||
else
|
||||
error("ERROR at checking the input for the ",dictionaryType,": The value of ",alternativeKey," is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
delete!(dictionary, alternativeKey)
|
||||
end
|
||||
|
||||
if mainKey_temp >= 0.0 && alternativeKey_temp >= 0.0
|
||||
difference = abs(mainKey_temp - alternativeKey_temp)
|
||||
if difference > 1/(10^approximationLevel) # TODO or use difference > 0.0 ?
|
||||
delete!(dictionary, alternativeKey)
|
||||
println("WARNING at checking the input for the ",dictionaryType,": The values of ",mainKey," and ",alternativeKey," differ by ",difference," ",unit,". The value ",String(mainKey),"=",default," ",unit," is used." )
|
||||
end
|
||||
elseif mainKey_temp >= 0.0
|
||||
# do nothing
|
||||
elseif alternativeKey_temp >= 0.0
|
||||
merge!(dictionary, Dict(mainKey => alternativeKey_temp))
|
||||
else
|
||||
# do nothing
|
||||
end
|
||||
|
||||
return dictionary
|
||||
end #function checkAndSetPositiveNumberWithDifferentNames!
|
||||
|
||||
# second method with a default value
|
||||
function checkAndSetPositiveNumberWithDifferentNames!(dictionary::Dict, dictionaryType::String, mainKey::Symbol, alternativeKey::Symbol, unit::String, default::Real)
|
||||
mainKey_temp = -1.0
|
||||
alternativeKey_temp = -1.0
|
||||
|
||||
if haskey(dictionary, mainKey) && dictionary[mainKey]!=nothing
|
||||
if typeof(dictionary[mainKey]) <: Real && dictionary[mainKey] >= 0.0
|
||||
mainKey_temp = dictionary[mainKey]
|
||||
else
|
||||
error("ERROR at checking the input for the ",dictionaryType,": The value of ",mainKey," is no real floating point number >=0.0.")
|
||||
end
|
||||
end
|
||||
|
||||
if haskey(dictionary, alternativeKey) && dictionary[alternativeKey]!=nothing
|
||||
if typeof(dictionary[alternativeKey]) <: Real && dictionary[alternativeKey] >= 0.0
|
||||
alternativeKey_temp = dictionary[alternativeKey]
|
||||
else
|
||||
error("ERROR at checking the input for the ",dictionaryType,": The value of ",alternativeKey," is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
delete!(dictionary, alternativeKey)
|
||||
end
|
||||
|
||||
if mainKey_temp >= 0.0 && alternativeKey_temp >= 0.0
|
||||
difference = abs(mainKey_temp - alternativeKey_temp)
|
||||
if difference > 1/(10^approximationLevel) # TODO or use difference > 0.0 ?
|
||||
delete!(dictionary, alternativeKey)
|
||||
println("WARNING at checking the input for the ",dictionaryType,": The values of ",mainKey," and ",alternativeKey," differ by ",difference," ",unit,". The value ",String(mainKey),"=",default," ",unit," is used." )
|
||||
end
|
||||
elseif mainKey_temp >= 0.0
|
||||
# do nothing
|
||||
elseif alternativeKey_temp >= 0.0
|
||||
merge!(dictionary, Dict(mainKey => alternativeKey_temp))
|
||||
else
|
||||
# set a default value
|
||||
merge!(dictionary, Dict(mainKey, default))
|
||||
println("INFO at checking the input for the ",dictionaryType,": The key ",mainKey," or its value is missing. Therefore the value ",String(mainKey),"=",default," ",unit," is used." )
|
||||
end
|
||||
|
||||
return dictionary
|
||||
end #function checkAndSetPositiveNumberWithDifferentNames!
|
||||
|
||||
function checkAndSetRealNumber!(dictionary::Dict, dictionaryType::String, key::Symbol, unit::String, default::Real)
|
||||
if haskey(dictionary,key) && dictionary[key]!=nothing
|
||||
if typeof(dictionary[key]) <: Real
|
||||
else
|
||||
error("ERROR at checking the input for the ",dictionaryType,": The value of ",String(key)," is no real number.")
|
||||
end
|
||||
else
|
||||
merge!(dictionary, Dict(key => default))
|
||||
println("INFO at checking the input for the ",dictionaryType,": The key ",String(key)," is missing. Therefore ",String(key),"=",default," ",unit," will be assumed and used." )
|
||||
end
|
||||
|
||||
return dictionary
|
||||
end #function checkAndSetRealNumber!
|
||||
|
||||
function checkAndSetSum!(dictionary::Dict, dictionaryType::String, sum::Symbol, summand1::Symbol, summand2::Symbol)
|
||||
if haskey(dictionary,sum) && dictionary[sum]!=nothing
|
||||
if typeof(dictionary[sum]) <: Real && dictionary[sum] >= 0.0
|
||||
difference = abs(dictionary[sum] - (dictionary[summand1]+dictionary[summand2]))
|
||||
if difference > 1/(10^approximationLevel)
|
||||
error("ERROR at checking the input for the ",dictionaryType,": The value of ",String(sum)," is not exactly the sum of ",String(summand1)," and ",String(summand2),". It differs by ",difference,".")
|
||||
end
|
||||
else
|
||||
error("ERROR at checking the input for the ",dictionaryType,": The value of ",String(sum)," is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
merge!(dictionary, Dict(sum => dictionary[summand1]+dictionary[summand2]))
|
||||
println("INFO at checking the input for the ",dictionaryType,": The key ",String(sum)," is missing. Therefore ",String(sum)," = ",String(summand1)," + ",String(summand2)," = ",dictionary[sum]," was calculated and will be used." )
|
||||
end
|
||||
|
||||
return dictionary
|
||||
end #function checkAndSetSum!
|
||||
|
||||
function checkAndSetString!(dictionary::Dict, dictionaryType::String, key::Symbol, defaultValue::String, validValues::Vector{String})
|
||||
# TODO change checkAndAddString! to checkAndAddSymbol! ?
|
||||
if haskey(dictionary,key) && dictionary[key]!=nothing
|
||||
value = dictionary[key]
|
||||
if typeof(value) == String
|
||||
for validValue in validValues
|
||||
if value == validValue
|
||||
return dictionary
|
||||
end
|
||||
end
|
||||
end
|
||||
error("ERROR at checking the input for the ",dictionaryType,": The value of ",String(key)," is wrong. It has to be one of the following String values: ", validValues)
|
||||
else
|
||||
println("INFO at checking the input for the ",dictionaryType,": The key ",String(key)," is missing. It has to be one of the following String values: ", validValues,". For this calculation the default value '",defaultValue,"' will be used.")
|
||||
merge!(dictionary, Dict(key => defaultValue))
|
||||
end
|
||||
return dictionary
|
||||
end #function checkAndSetString!
|
||||
# second method of function checkAndSetString! without validValues
|
||||
function checkAndSetString!(dictionary::Dict, dictionaryType::String, key::Symbol, defaultValue::String)
|
||||
if haskey(dictionary,key) && dictionary[key]!=nothing
|
||||
value = dictionary[key]
|
||||
if typeof(value) == String
|
||||
return dictionary
|
||||
end
|
||||
error("ERROR at checking the input for the ",dictionaryType,": The value of ",String(key)," is wrong. It has to be of type String.")
|
||||
else
|
||||
println("INFO at checking the input for the ",dictionaryType,": The key ",String(key)," is missing. For this calculation the default value '",defaultValue,"' will be used.")
|
||||
merge!(dictionary, Dict(key => defaultValue))
|
||||
end
|
||||
return dictionary
|
||||
end #function checkAndSetString!
|
||||
|
||||
function checkAndSetSpeedLimit!(train::Dict)
|
||||
v_limit_temp = 0.0
|
||||
v_limit_kmh_temp = 0.0
|
||||
|
||||
if haskey(train, :v_limit) && train[:v_limit]!=nothing
|
||||
if typeof(train[:v_limit]) <: Real && train[:v_limit] >= 0.0
|
||||
v_limit_temp = train[:v_limit]
|
||||
else
|
||||
error("ERROR at checking the input for the train: The value of v_limit is no real floating point number >=0.0.")
|
||||
end
|
||||
end
|
||||
|
||||
if haskey(train, :v_limit_kmh) && train[:v_limit_kmh]!=nothing
|
||||
if typeof(train[:v_limit_kmh]) <: Real && train[:v_limit_kmh] >= 0.0
|
||||
v_limit_kmh_temp = train[:v_limit_kmh]
|
||||
else
|
||||
error("ERROR at checking the input for the train: The value of v_limit_kmh is no real floating point number >=0.0.")
|
||||
end
|
||||
else
|
||||
delete!(train, :v_limit_kmh)
|
||||
end
|
||||
|
||||
if v_limit_temp > 0.0 && v_limit_kmh_temp > 0.0
|
||||
difference = abs(v_limit_temp - v_limit_kmh_temp/3.6)
|
||||
if difference > 1/(10^approximationLevel) # TODO or use difference > 0.0 ?
|
||||
delete!(train, :v_limit_kmh)
|
||||
println("WARNING at checking the input for the train: The values of v_limit and v_limit_kmh differ by ",difference," m/s. The value v_limit=",v_limit_temp," m/s is used." )
|
||||
end
|
||||
elseif v_limit_temp > 0.0
|
||||
# do nothing
|
||||
elseif v_limit_kmh_temp > 0.0
|
||||
merge!(train, Dict(:v_limit => v_limit_kmh_temp/3.6))
|
||||
else
|
||||
# set a default value
|
||||
merge!(train, Dict(:v_limit, 1000.0/3.6)) # set speed limit to 1000 km/h
|
||||
println("INFO at checking the input for the train: There is no value for the trains speed limit (v_limit or v_limit_kmh). The value v_limit=1000 km/h =",train[:v_limit]," m/s is used." )
|
||||
end
|
||||
|
||||
return train
|
||||
end #function checkAndSetSpeedLimit!
|
||||
|
||||
function checkAndSetBrakingAcceleration!(train::Dict)
|
||||
if haskey(train, :a_braking) && train[:a_braking]!=nothing
|
||||
if typeof(train[:a_braking]) <: Real
|
||||
if train[:a_braking] > 0.0
|
||||
train[:a_braking] =-train[:a_braking]
|
||||
println("INFO at checking the input for the train: The value for a_braking is >0.0. The braking acceleration has to be <0.0. Therefore a_braking=",train[:a_braking]," m/s^2 is used." )
|
||||
elseif train[:a_braking] == 0.0
|
||||
error("ERROR at checking the input for the train: The value for a_braking is 0.0. The braking acceleration has to be <0.0.")
|
||||
end
|
||||
else
|
||||
error("ERROR at checking the input for the train: The value for a_braking is no real floating point number <0.0.")
|
||||
end
|
||||
else
|
||||
# set a default value depending on the train type
|
||||
if train[:type] == "freight"
|
||||
a_braking = -0.225
|
||||
elseif train[:type] == "passenger"
|
||||
a_braking = -0.375
|
||||
#elseif train[:type] == "passengerSuburban"
|
||||
# a_braking = -0.525
|
||||
# TODO: add suburban trains to train type?
|
||||
end
|
||||
|
||||
merge!(train, Dict(:a_braking => a_braking))
|
||||
println("INFO at checking the input for the train: The key for a_braking is missing. Because of the train type ",train[:type]," a_braking=",a_braking," m/s^2 will be assumed and used." )
|
||||
end
|
||||
|
||||
return train
|
||||
end #function checkAndSetBrakingAcceleration!
|
||||
|
||||
function checkAndSetRotationMassFactors!(train::Dict)
|
||||
checkAndSetPositiveNumberWithDifferentNames!(train, "train", :ξ_train, :rotationMassFactor_train, "")
|
||||
checkAndSetPositiveNumberWithDifferentNames!(train, "train", :ξ_t, :rotationMassFactor_t, "")
|
||||
checkAndSetPositiveNumberWithDifferentNames!(train, "train", :ξ_w, :rotationMassFactor_w, "")
|
||||
if haskey(train, :ξ_train) && train[:ξ_train]!=nothing
|
||||
if train[:ξ_train]>0.0
|
||||
if haskey(train, :ξ_t) && train[:ξ_t]!=nothing && train[:ξ_t]>0.0 && (train[:m_w]==0.0 || (haskey(train, :ξ_w) && train[:ξ_w]!=nothing))
|
||||
# TODO: is && train[:ξ_t]>0.0 necessary here?
|
||||
difference = abs(train[:ξ_train] - (train[:ξ_t]*train[:m_t] + train[:ξ_w]*train[:m_w])/train[:m_train])
|
||||
if difference > 1/(10^approximationLevel)
|
||||
error("ERROR at checking the input for the train: The value of ξ_train is not exactly ξ_train=(ξ_t*m_t + ξ_w*m_w)/m_train. It differs by ",difference,".")
|
||||
end
|
||||
end
|
||||
else
|
||||
error("ERROR at checking the input for the train: The value of :ξ_train is no real floating point number >0.0.")
|
||||
end
|
||||
else
|
||||
checkAndSetPositiveNumber!(train, "train", :ξ_t, "", 1.09)
|
||||
|
||||
if train[:m_w]>0.0
|
||||
default_ξ_w = 1.06
|
||||
else
|
||||
default_ξ_w = 0.0
|
||||
end
|
||||
checkAndSetPositiveNumber!(train, "train", :ξ_w, "", default_ξ_w)
|
||||
|
||||
|
||||
ξ_train=(train[:ξ_t]*train[:m_t] + train[:ξ_w]*train[:m_w])/train[:m_train] # rotation mass factor of the whole train (without unit)
|
||||
if ξ_train <= 0.0
|
||||
error("ERROR at checking the input for the train: The train's rotations mass factor has to be higher than 0.0 kg.")
|
||||
end
|
||||
merge!(train, Dict(:ξ_train => ξ_train))
|
||||
end
|
||||
|
||||
return train
|
||||
end #function checkAndSetRotationMassFactors!
|
||||
|
||||
function checkAndSetTractiveEffortVelocityPairs!(train::Dict) # pairs of velocity and tractive effort
|
||||
if haskey(train,:tractiveEffortVelocityPairs) && train[:tractiveEffortVelocityPairs]!=nothing
|
||||
pairs = train[:tractiveEffortVelocityPairs]
|
||||
velocityMultiplier = 1.0
|
||||
|
||||
if (haskey(train,:F_T_pairs) && train[:F_T_pairs]!=nothing) && (haskey(train,:F_T_pairs_kmh) && train[:F_T_pairs_kmh]!=nothing)
|
||||
println("WARNING at checking the input for the train: There are values for tractiveEffortVelocityPairs, F_T_pairs and F_T_pairs_kmh. The values for tractiveEffortVelocityPairs are used." )
|
||||
|
||||
elseif haskey(train,:F_T_pairs) && train[:F_T_pairs]!=nothing
|
||||
println("WARNING at checking the input for the train: There are values for tractiveEffortVelocityPairs and F_T_pairs. The values for tractiveEffortVelocityPairs are used." )
|
||||
|
||||
elseif haskey(train,:F_T_pairs_kmh) && train[:F_T_pairs_kmh]!=nothing
|
||||
println("WARNING at checking the input for the train: There are values for tractiveEffortVelocityPairs and F_T_pairs_kmh. The values for tractiveEffortVelocityPairs are used." )
|
||||
end
|
||||
|
||||
elseif haskey(train,:F_T_pairs) && train[:F_T_pairs]!=nothing
|
||||
pairs = train[:F_T_pairs]
|
||||
velocityMultiplier = 1.0
|
||||
|
||||
if haskey(train,:F_T_pairs_kmh) && train[:F_T_pairs_kmh]!=nothing
|
||||
println("WARNING at checking the input for the train: There are values for F_T_pairs and F_T_pairs_kmh. The values for F_T_pairs are used." )
|
||||
end
|
||||
|
||||
elseif haskey(train,:F_T_pairs_kmh) && train[:F_T_pairs_kmh]!=nothing
|
||||
velocityMultiplier = 1000/3600
|
||||
pairs=[]
|
||||
for row in 1:length(train[:F_T_pairs_kmh])
|
||||
push!(pairs, [train[:F_T_pairs_kmh][row][1]*velocityMultiplier, train[:F_T_pairs_kmh][row][2]])
|
||||
end # for
|
||||
|
||||
else
|
||||
error("ERROR at checking the input for the train: There has to be the key tractiveEffortVelocityPairs filled with a list of pairs of velocity and tractive effort.")
|
||||
end # if
|
||||
|
||||
# check if the elements of the array have the correct type
|
||||
errorDetected=false
|
||||
|
||||
for row in 1:length(pairs)
|
||||
if typeof(pairs[row][1]) <: Real && pairs[row][1]>=0.0
|
||||
else
|
||||
errorDetected=true
|
||||
println("ERROR at checking the input for the train: The speed value of train[:tractiveEffortVelocityPairs] in row ", row ," is no real floating point number >=0.0.")
|
||||
end
|
||||
if typeof(pairs[row][2]) <: Real && pairs[row][2]>=0.0
|
||||
else
|
||||
errorDetected=true
|
||||
println("ERROR at checking the input for the train: The tractive effort value of train[:tractiveEffortVelocityPairs] in row ", row ," is no real floating point number >=0.0.")
|
||||
end
|
||||
|
||||
if row>=2 && pairs[row][1] <= pairs[row-1][1]
|
||||
errorDetected=true
|
||||
println("ERROR at checking the input for the train: The speed value of train[:tractiveEffortVelocityPairs] in row ", row ," (v=",pairs[row][1]," m/s) is not higher than the speed value in the previous row (v=",pairs[row-1][1]," m/s).")
|
||||
end
|
||||
end # for
|
||||
if errorDetected
|
||||
error("ERROR at checking the input for the train: Only real floating point number >=0.0 are allowed for speed and tractive effort. The speed values have to be listed from low to high.")
|
||||
end
|
||||
|
||||
# create tractiveEffortVelocityPairs
|
||||
if pairs[1][1]>0.0 # if there is no F_T for v=0.0, the first known value is used
|
||||
newPairs=[]
|
||||
push!(newPairs, [0.0, pairs[1][2]])
|
||||
println("INFO at checking the input for the train: The tractive effort for v=0.0 m/s is missing. Therefore the first given value F_T(v=",pairs[1][1]," m/s)=",pairs[1][2]," N will be used." )
|
||||
for row in 1:length(pairs)
|
||||
push!(newPairs, [pairs[row][1], pairs[row][2]])
|
||||
end # for
|
||||
merge!(train, Dict(:tractiveEffortVelocityPairs => newPairs))
|
||||
else
|
||||
merge!(train, Dict(:tractiveEffortVelocityPairs => pairs))
|
||||
end
|
||||
|
||||
if length(pairs[1])>2
|
||||
println("INFO according the train dictionary: Only the first two columns of train[:tractiveEffortVelocityPairs] are used in this tool.")
|
||||
end
|
||||
|
||||
return train
|
||||
end #function checkAndSetTractiveEffortVelocityPairs!
|
||||
|
||||
function getDefault_Δv_w(type::String) # coefficient for velocitiy difference between set of wagons (consist) and outdoor air (in m/s)
|
||||
if type == "passenger"
|
||||
# TODO if different passenger or freight trains are posiible, use: if startswith(type, "passenger"). exanples: passengerLocomotivehauled and passengerMotorCoachTrain
|
||||
Δv_w=15.0/3.6
|
||||
elseif type == "freight"
|
||||
Δv_w=0.0
|
||||
end # if
|
||||
|
||||
return Δv_w
|
||||
end #function getDefault_Δv_w!
|
||||
|
||||
function checkAndSetSections!(path::Dict)
|
||||
# check the section information
|
||||
if haskey(path,:sections) && path[:sections]!=nothing
|
||||
# TODO: check typeof(path[:sections]) == Dict
|
||||
if (haskey(path, :sectionStarts) && path[:sectionStarts]!=nothing) && (haskey(path,:sectionStarts_kmh) && path[:sectionStarts_kmh]!=nothing)
|
||||
println("WARNING at checking the input for the path: There are values for sections, sectionStarts and sectionStarts_kmh. The dictionary sections is used." )
|
||||
|
||||
elseif haskey(path,:sectionStarts) && path[:sectionStarts]!=nothing
|
||||
println("WARNING at checking the input for the path: There are values for sections and sectionStarts. The dictionary sections is used." )
|
||||
|
||||
elseif haskey(path,:sectionStarts_kmh) && path[:sectionStarts_kmh]!=nothing
|
||||
println("WARNING at checking the input for the path: There are values for sections and sectionStarts_kmh. The dictionary sections is used." )
|
||||
end
|
||||
elseif haskey(path,:sectionStarts) && path[:sectionStarts]!=nothing
|
||||
# TODO: check typeof(path[:sections]) == Array
|
||||
createSections!(path, :sectionStarts)
|
||||
|
||||
if haskey(path,:sectionStarts_kmh) && path[:sectionStarts_kmh]!=nothing
|
||||
println("WARNING at checking the input for the path: There are values for sectionStarts and sectionStarts_kmh. The array sectionStarts is used." )
|
||||
end
|
||||
elseif haskey(path,:sectionStarts_kmh) && path[:sectionStarts_kmh]!=nothing
|
||||
# TODO: check typeof(path[:sections]) == Array
|
||||
createSections!(path, :sectionStarts_kmh)
|
||||
else
|
||||
error("ERROR at checking the input for the path: The Symbol :sections is missing. It has to be added with a list of sections. Each has to be a dictionary with the keys :s_tart, :s_end, :v_limit and :f_Rp.")
|
||||
section = Dict(:s_start => 0.0,
|
||||
:s_end => 15.0,
|
||||
:v_limit => 1000.0/3.6,
|
||||
:f_Rp => 0.0)
|
||||
merge!(path, Dict(:sections => [section]))
|
||||
return path
|
||||
end
|
||||
|
||||
sections = path[:sections]
|
||||
|
||||
checkedSections = []
|
||||
increasing = false
|
||||
decreasing = false
|
||||
|
||||
#TODO: throw error for each issue or collect the issues and use the Bool errorDetected like in createSections?
|
||||
|
||||
# check values for section==1
|
||||
checkAndSetRealNumber!(sections[1], "path[:sections][1]", :s_start, "m", 0.0) # first point of the section (in m)
|
||||
checkAndSetRealNumber!(sections[1], "path[:sections][1]", :s_end, "m", 0.0) # first point of the next section (in m)
|
||||
checkAndSetPositiveNumber!(sections[1], "path[:sections][1]", :v_limit, "m/s", 1000.0/3.6) # paths speed limt (in m/s)
|
||||
checkAndSetRealNumber!(sections[1], "path[:sections][1]", :f_Rp, "‰", 0.0) # specific path resistance of the section (in ‰)
|
||||
|
||||
push!(checkedSections, sections[1])
|
||||
|
||||
if sections[1][:s_start] < sections[1][:s_end]
|
||||
increasing = true
|
||||
elseif sections[1][:s_start] > sections[1][:s_end]
|
||||
decreasing = true
|
||||
else
|
||||
pop!(checkedSections)
|
||||
println("WARNING at checking the input for the path: The first section of :sections has the same position for starting and end point. The section will be deleted and not used in the tool.")
|
||||
end
|
||||
|
||||
|
||||
for sectionNr in 2:length(sections)
|
||||
checkAndSetRealNumber!(sections[sectionNr], "path[:sections]["*string(sectionNr)*"]", :s_start, "m", sections[sectionNr-1][:s_end]) # first point of the section (in m)
|
||||
# TODO how to define default values? which has to be checked and defined fist? s_end-1 and s_start need each other as default values
|
||||
#if sectionNr < length(sections) && haskey(sections[sectionNr], :s_start) && sections[sectionNr][:s_start]!=nothing && typeof(sections[sectionNr][:s_start]) <: Real
|
||||
# defaultEnd = sections[sectionNr+1][:s_start]
|
||||
#end
|
||||
defaultEnd = sections[sectionNr][:s_start] # so the default value for s_end creates a sections of lenght=0.0 #TODO should be changed!
|
||||
checkAndSetRealNumber!(sections[sectionNr], "path[:sections]["*string(sectionNr)*"]", :s_end, "m", defaultEnd) # first point of the next section (in m)
|
||||
checkAndSetPositiveNumber!(sections[sectionNr], "path[:sections]["*string(sectionNr)*"]", :v_limit, "m/s", 1000.0/3.6) # paths speed limt (in m/s)
|
||||
checkAndSetRealNumber!(sections[sectionNr], "path[:sections]["*string(sectionNr)*"]", :f_Rp, "‰", 0.0) # specific path resistance of the section (in ‰)
|
||||
|
||||
push!(checkedSections, sections[sectionNr])
|
||||
|
||||
# compare the section's start and end position
|
||||
if sections[sectionNr][:s_start] < sections[sectionNr][:s_end]
|
||||
increasing = true
|
||||
elseif sections[sectionNr][:s_start] > sections[sectionNr][:s_end]
|
||||
decreasing = true
|
||||
else
|
||||
pop!(checkedSections)
|
||||
println("INFO at checking the input for the path: The ",sectionNr,". section of :sections has the same position for starting and end point. The section will be deleted and not used in the tool.")
|
||||
end
|
||||
if increasing && decreasing
|
||||
error("ERROR at checking the input for the path: The positions of the :sections are not increasing/decreasing consistently. The direction in the ",sectionNr,". section differs from the previous.")
|
||||
end
|
||||
|
||||
|
||||
if length(checkedSections)>1 && sections[sectionNr][:s_start] != checkedSections[end-1][:s_end]
|
||||
error("ERROR at checking the input for the path[:sections]: The starting position of the ",section,". section (s=",sections[sectionNr][:s_start]," m) does not euqal the last position of the previous section(s=",checkedSections[end-1][:s_end]," m). The sections have to be sequential.")
|
||||
# TODO: maybe if there is a gab create a new section and only if there a jumps in the wrong direction throw an error?
|
||||
end
|
||||
end #for
|
||||
|
||||
return path
|
||||
end #function checkAndSetSections!
|
||||
|
||||
function createSections!(path::Dict, key::Symbol)
|
||||
# read the section starting positions and corresponding information
|
||||
if key == :sectionStarts
|
||||
sectionStartsArray = path[:sectionStarts]
|
||||
conversionFactor = 1.0 # conversion factor between the units m/s and m/s
|
||||
|
||||
if haskey(path,:sectionStarts) && path[:sectionStarts_kmh]!=nothing
|
||||
println("WARNING at checking the input for the path: There are values for sectionStarts and sectionStarts_kmh. The values for sectionStarts are used." )
|
||||
end
|
||||
elseif key == :sectionStarts_kmh
|
||||
sectionStartsArray = path[:sectionStarts_kmh]
|
||||
conversionFactor = 1/3.6 # conversion factor between the units km/h and m/s
|
||||
else
|
||||
error("ERROR at checking the input for the path: The keyword sectionStarts or sectionStarts_kmh is missing. The sections can not be created without them.")
|
||||
end # if
|
||||
|
||||
# check if the array is correct and if elements of the array have the correct type and valid values
|
||||
errorDetected = false
|
||||
if length(sectionStartsArray)<2
|
||||
error("ERROR at checking the input for the path: The keyword ",key," needs at least two rows for two points each with the three columns [s, v_limit, f_Rp].")
|
||||
end
|
||||
|
||||
for row in 1:length(sectionStartsArray)
|
||||
if length(sectionStartsArray[row])>=3
|
||||
if length(sectionStartsArray[row])>3
|
||||
println("INFO at checking the input for the path: Only the first three columns of sectionStartsArray are used in this tool.")
|
||||
end
|
||||
else
|
||||
error("ERROR at checking the input for the path: The keyword ",key," needs to be filled with the three columns [s, v_limit, f_Rp].")
|
||||
end
|
||||
|
||||
if !(typeof(sectionStartsArray[row][1]) <: Real)
|
||||
errorDetected=true
|
||||
println("ERROR at checking the input for the path: The position value (column 1) of ",key," in row ", row ," is no real floating point number.")
|
||||
end
|
||||
if !(typeof(sectionStartsArray[row][2]) <: Real && sectionStartsArray[row][2] >= 0.0)
|
||||
errorDetected=true
|
||||
println("ERROR at checking the input for the path: The speed limit (column 2) of ",key," in row ", row ," is no real floating point number >=0.0.")
|
||||
end
|
||||
if !(typeof(sectionStartsArray[row][3]) <: Real)
|
||||
errorDetected=true
|
||||
println("ERROR at checking the input for the path: The tractive effort value (column 3) of ",key," in row ", row ," is no real floating point number.")
|
||||
end
|
||||
end # for
|
||||
if errorDetected
|
||||
error("ERROR at checking the input for the path: The values of ",key," have to be corrected.")
|
||||
end
|
||||
|
||||
|
||||
sections = []
|
||||
for row in 2:length(sectionStartsArray)
|
||||
s_start = sectionStartsArray[row-1][1] # first point of the section (in m)
|
||||
s_end = sectionStartsArray[row][1] # first point of the next section (in m)
|
||||
v_limit = sectionStartsArray[row-1][2]*conversionFactor # paths speed limt (in m/s)
|
||||
f_Rp = sectionStartsArray[row-1][3] # specific path resistance of the section (in ‰)
|
||||
|
||||
section = Dict(:s_start => s_start,
|
||||
:s_end => s_end,
|
||||
:v_limit => v_limit,
|
||||
:f_Rp => f_Rp)
|
||||
push!(sections, section)
|
||||
end # for
|
||||
# s_start in first entry defines the path's beginning
|
||||
# s_end in last entry defines the path's ending
|
||||
|
||||
merge!(path, Dict(:sections => sections))
|
||||
return path
|
||||
end #function createSections!
|
||||
|
||||
function checkAndSetPOIs!(path::Dict)
|
||||
# read the section starting positions and corresponding information
|
||||
if haskey(path, :pointsOfInterest)
|
||||
if path[:pointsOfInterest] != nothing
|
||||
pointsOfInterest = path[:pointsOfInterest]
|
||||
|
||||
sortingNeeded = false
|
||||
errorDetected = false
|
||||
for element in 1:length(pointsOfInterest)
|
||||
if typeof(pointsOfInterest[element]) <: Real
|
||||
if element > 1
|
||||
if pointsOfInterest[element] < pointsOfInterest[element-1]
|
||||
sortingNeeded = true
|
||||
println("INFO at checking the input for the path: The point of interest in element ", element ," (",pointsOfInterest[element]," m) has to be higher than the value of the previous element (",pointsOfInterest[element-1]," m). The points of interest will be sorted.")
|
||||
end
|
||||
end
|
||||
else
|
||||
errorDetected = true
|
||||
println("ERROR at checking the input for the path: The point of interest in element ", element ," is no real floating point number.")
|
||||
end
|
||||
end # for
|
||||
|
||||
if errorDetected
|
||||
error("ERROR at checking the input for the path: The values of pointsOfInterest have to be corrected.")
|
||||
end
|
||||
if sortingNeeded == true
|
||||
sort!(pointsOfInterest)
|
||||
end
|
||||
|
||||
copiedPOIs = []
|
||||
for element in 1:length(pointsOfInterest)
|
||||
if element == 1
|
||||
push!(copiedPOIs, pointsOfInterest[element])
|
||||
elseif element > 1 && pointsOfInterest[element] > pointsOfInterest[element-1]
|
||||
push!(copiedPOIs, pointsOfInterest[element])
|
||||
end
|
||||
end # for
|
||||
path[:pointsOfInterest] = copiedPOIs
|
||||
|
||||
else
|
||||
println("INFO at checking the input for the path: The key pointsOfInterest exists but without values.")
|
||||
delete!(path, :pointsOfInterest)
|
||||
end
|
||||
end
|
||||
|
||||
return path
|
||||
end #function checkAndSetPOIs!
|
||||
|
||||
function getDefaultStepSize(stepVariable::String)
|
||||
if stepVariable == "s in m"
|
||||
return 10.0
|
||||
elseif stepVariable == "t in s"
|
||||
return 3.0
|
||||
elseif stepVariable == "v in m/s"
|
||||
return 0.1
|
||||
#else
|
||||
# error("ERROR at getting a default step size. The step variable ",stepVariable," can not be used.")
|
||||
end
|
||||
end #function getDefaultStepSize
|
||||
|
||||
#function informAboutUnusedKeys(dictionary::Dict, dictionaryType::String) # inform the user which Symbols of the input dictionary are not used in this tool
|
||||
function informAboutUnusedKeys(allKeys::AbstractVector, usedKeys::Vector{Symbol}, dictionaryType::String) # inform the user which Symbols of the input dictionary are not used in this tool
|
||||
unusedKeys = []
|
||||
# find unused keys in allKeys
|
||||
for key in allKeys
|
||||
used = false
|
||||
for usedKey in usedKeys
|
||||
if key == usedKey
|
||||
used = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if !used
|
||||
push!(unusedKeys, key)
|
||||
end
|
||||
end
|
||||
|
||||
if length(unusedKeys)>0
|
||||
println("INFO at checking the input for the ",dictionaryType,": The following Keywords are not used in this tool:")
|
||||
for key in unusedKeys
|
||||
println(" - ",key)
|
||||
end
|
||||
end
|
||||
end #function informAboutUnusedKeys
|
||||
|
||||
end # module Validate
|
File diff suppressed because it is too large
Load Diff
|
@ -5,83 +5,20 @@
|
|||
# __copyright__ = "2020-2022"
|
||||
# __license__ = "ISC"
|
||||
|
||||
module TrainRunCalc
|
||||
|
||||
# include modules of TrainRunCalc
|
||||
include("./Validate.jl")
|
||||
include("./Characteristics.jl")
|
||||
include("./Behavior.jl")
|
||||
include("./Output.jl")
|
||||
|
||||
|
||||
# use modules of TrainRunCalc
|
||||
using .Validate
|
||||
using .Characteristics
|
||||
using .Behavior
|
||||
using .Output
|
||||
|
||||
# export main function
|
||||
export trainRun
|
||||
|
||||
approximationLevel = 6 # value for approximation to intersections and precisely calculated digits
|
||||
# TODO: define it here and give it to each function? (Behavior, ...)
|
||||
|
||||
# Calculate the driving dynamics of a train run on a path with special settings with information from the corresponding YAML files with the file paths `trainDirectory`, `pathDirectory`, `settingsDirectory`.
|
||||
|
||||
"""
|
||||
trainRun(train::Dict, path::Dict, settings::Dict)
|
||||
|
||||
Calculate the driving dynamics of a train run on a path with special settings with information from the corresponding dictionaries `train`, `path`, `settings`.
|
||||
|
||||
# Examples
|
||||
```julia-repl
|
||||
julia> trainRun(trainDict, pathDict, settingsDict)
|
||||
todo !!!
|
||||
```
|
||||
"""
|
||||
function trainRun(trainInput::Dict, pathInput::Dict, settingsInput::Dict)
|
||||
# copy Input data for not changing them
|
||||
# TODO: or should they be changed? normally it would only make it "better" except for settings[:detailOfOutput] == "points of interest" && !haskey(path, :pointsOfInterest)
|
||||
train = copy(trainInput)
|
||||
path = copy(pathInput)
|
||||
settings = copy(settingsInput)
|
||||
|
||||
# check the input data
|
||||
(train, path, settings) = checkAndSetInput!(train, path, settings)
|
||||
settings[:detailOfOutput] == "everything" && println("The input has been checked.")
|
||||
|
||||
# prepare the input data
|
||||
movingSection = determineCharacteristics(path, train, settings)
|
||||
settings[:detailOfOutput] == "everything" && println("The moving section has been prepared.")
|
||||
|
||||
# calculate the train run for oparation mode "minimum running time"
|
||||
if settings[:operationModeMinimumRunningTime] || settings[:operationModeMinimumEnergyConsumption]
|
||||
(movingSection, drivingCourse) = calculateMinimumRunningTime!(movingSection, settings, train)
|
||||
settings[:detailOfOutput] == "everything" && println("The driving course for the shortest running time has been calculated.")
|
||||
|
||||
# accumulate data and create an output dictionary
|
||||
output = createOutput(train, settings, path, movingSection, drivingCourse)
|
||||
# 30/31 old: output = createOutputDict(train, settings, path, movingSection, drivingCourse)
|
||||
else
|
||||
output = nothing
|
||||
# 30/31 old: output = Dict()
|
||||
end #if
|
||||
|
||||
return output
|
||||
end # function trainRun
|
||||
# Calculate the running time of a train run on a path with special settings with information from the corresponding YAML files with the file paths `trainDirectory`, `pathDirectory`, `settingsDirectory`.
|
||||
|
||||
# calculate a train run focussing on using the minimum possible running time
|
||||
function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train::Dict)
|
||||
function calculateMinimumRunningTime!(movingSection::Dict, settings::Settings, train::Train)
|
||||
CSs::Vector{Dict} = movingSection[:characteristicSections]
|
||||
|
||||
if settings[:massModel] == "homogeneous strip" && settings[:stepVariable] == "v in m/s"
|
||||
if settings.massModel == :homogeneous_strip && settings.stepVariable == speed
|
||||
println("WARNING: ! ! ! TrainRun.jl doesn't work reliably for the mass model homogeneous strip with step size v in m/s. The calculation time can be extremely high when calcutlating paths with steep gradients ! ! !")
|
||||
end
|
||||
|
||||
startingPoint=createDataPoint()
|
||||
startingPoint[:i]=1
|
||||
startingPoint[:s]=CSs[1][:s_entry]
|
||||
calculateForces!(startingPoint, CSs, 1, "default", train, settings[:massModel]) # traction effort and resisting forces (in N)
|
||||
calculateForces!(startingPoint, CSs, 1, "default", train, settings.massModel) # traction effort and resisting forces (in N)
|
||||
drivingCourse::Vector{Dict} = [startingPoint] # List of data points
|
||||
|
||||
for csId in 1:length(CSs)
|
||||
|
@ -95,8 +32,8 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
|
|||
end
|
||||
|
||||
# determine the different flags for switching between the states for creatinge moving phases
|
||||
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
||||
calculateForces!(drivingCourse[end], CSs, CS[:id], "default", train, settings[:massModel]) # tractive effort and resisting forces (in N)
|
||||
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train.a_braking)
|
||||
calculateForces!(drivingCourse[end], CSs, CS[:id], "default", train, settings.massModel) # tractive effort and resisting forces (in N)
|
||||
|
||||
previousSpeedLimitReached = false
|
||||
stateFlags = Dict(:endOfCSReached => drivingCourse[end][:s] > CS[:s_exit],
|
||||
|
@ -122,17 +59,17 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
|
|||
|
||||
elseif drivingCourse[end][:F_T] == drivingCourse[end][:F_R] && !stateFlags[:speedLimitReached]
|
||||
# cruise only one step
|
||||
if settings[:stepVariable] =="s in m"
|
||||
s_cruising = settings[:stepSize]
|
||||
elseif settings[:stepVariable] =="t in s"
|
||||
s_cruising = calc_Δs_with_Δt(settings[:stepSize], drivingCourse[end][:a], drivingCourse[end][:v])
|
||||
elseif settings[:stepVariable] =="v in m/s"
|
||||
s_cruising = train[:length]/(10.0) # TODO which step size should be used?
|
||||
if settings.stepVariable == :distance
|
||||
s_cruising = settings.stepSize
|
||||
elseif settings.stepVariable == time
|
||||
s_cruising = calc_Δs_with_Δt(settings.stepSize, drivingCourse[end][:a], drivingCourse[end][:v])
|
||||
elseif settings.stepVariable == velocity
|
||||
s_cruising = train.length/(10.0) # TODO which step size should be used?
|
||||
end
|
||||
(CS, drivingCourse, stateFlags) = addCruisingSection!(CS, drivingCourse, stateFlags, s_cruising, settings, train, CSs, "cruising")
|
||||
|
||||
elseif drivingCourse[end][:F_R] < 0 && stateFlags[:speedLimitReached]
|
||||
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
||||
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train.a_braking)
|
||||
s_cruising = CS[:s_exit] - drivingCourse[end][:s] - s_braking
|
||||
|
||||
if s_cruising > 0.0
|
||||
|
@ -142,7 +79,7 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
|
|||
end
|
||||
|
||||
elseif drivingCourse[end][:F_T] == drivingCourse[end][:F_R] || stateFlags[:speedLimitReached]
|
||||
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train[:a_braking])
|
||||
s_braking = calcBrakingDistance(drivingCourse[end][:v], CS[:v_exit], train.a_braking)
|
||||
s_cruising = CS[:s_exit] - drivingCourse[end][:s] - s_braking
|
||||
|
||||
if s_cruising > 0.0 # TODO: define a minimum cruising length?
|
||||
|
@ -186,5 +123,3 @@ function calculateMinimumRunningTime!(movingSection::Dict, settings::Dict, train
|
|||
|
||||
return (movingSection, drivingCourse)
|
||||
end #function calculateMinimumRunningTime
|
||||
|
||||
end # module TrainRunCalc
|
|
@ -5,94 +5,16 @@
|
|||
# __copyright__ = "2020-2022"
|
||||
# __license__ = "ISC"
|
||||
|
||||
module Characteristics
|
||||
|
||||
include("./Behavior.jl")
|
||||
using .Behavior
|
||||
|
||||
export determineCharacteristics
|
||||
|
||||
## create a moving section and its containing characteristic sections with secured braking, accelerating and cruising behavior
|
||||
function determineCharacteristics(path::Dict, train::Dict, settings::Dict)
|
||||
movingSection = createMovingSection(path, train[:v_limit])
|
||||
movingSection = secureBrakingBehavior!(movingSection, train[:a_braking])
|
||||
function determineCharacteristics(path::Path, train::Train, settings::Settings)
|
||||
movingSection = createMovingSection(path, train.v_limit, train.length)
|
||||
movingSection = secureBrakingBehavior!(movingSection, train.a_braking)
|
||||
movingSection = secureAcceleratingBehavior!(movingSection, settings, train)
|
||||
#movingSection = secureCruisingBehavior!(movingSection, settings, train)
|
||||
|
||||
return movingSection
|
||||
end #function determineCharacteristics
|
||||
|
||||
## create a moving section containing characteristic sections
|
||||
function createMovingSection(path::Dict, v_trainLimit::Real)
|
||||
# this function creates and returns a moving section dependent on the paths attributes
|
||||
|
||||
s_entry = path[:sections][1][:s_start] # first position (in m)
|
||||
s_exit = path[:sections][end][:s_end] # last position (in m)
|
||||
pathLength = s_exit - s_entry # total length (in m)
|
||||
|
||||
CSs=Vector{Dict}()
|
||||
s_csStart=s_entry
|
||||
csId=1
|
||||
for row in 2:length(path[:sections])
|
||||
previousSection = path[:sections][row-1]
|
||||
currentSection = path[:sections][row]
|
||||
speedLimitIsDifferent = min(previousSection[:v_limit], v_trainLimit) != min(currentSection[:v_limit], v_trainLimit)
|
||||
pathResistanceIsDifferent = previousSection[:f_Rp] != currentSection[:f_Rp]
|
||||
if speedLimitIsDifferent || pathResistanceIsDifferent
|
||||
# 03/09 old: if min(previousSection[:v_limit], v_trainLimit) != min(currentSection[:v_limit], v_trainLimit) || previousSection[:f_Rp] != currentSection[:f_Rp]
|
||||
push!(CSs, createCharacteristicSection(csId, s_csStart, previousSection, min(previousSection[:v_limit], v_trainLimit), path))
|
||||
s_csStart = currentSection[:s_start]
|
||||
csId = csId+1
|
||||
end #if
|
||||
end #for
|
||||
push!(CSs, createCharacteristicSection(csId, s_csStart, path[:sections][end], min(path[:sections][end][:v_limit], v_trainLimit), path))
|
||||
|
||||
movingSection= Dict(:id => 1, # identifier # if there is more than one moving section in a later version of this tool the id should not be constant anymore
|
||||
:length => pathLength, # total length (in m)
|
||||
:s_entry => s_entry, # first position (in m)
|
||||
:s_exit => s_exit, # last position (in m)
|
||||
:t => 0.0, # total running time (in s)
|
||||
:E => 0.0, # total energy consumption (in Ws)
|
||||
:characteristicSections => CSs) # list of containing characteristic sections
|
||||
|
||||
return movingSection
|
||||
end #function createMovingSection
|
||||
|
||||
|
||||
## create a characteristic section for a path section. A characteristic section is a part of the moving section. It contains behavior sections.
|
||||
function createCharacteristicSection(id::Integer, s_entry::Real, section::Dict, v_limit::Real, path::Dict)
|
||||
# Create and return a characteristic section dependent on the paths attributes
|
||||
characteristicSection= Dict(:id => id, # identifier
|
||||
:s_entry => s_entry, # first position (in m)
|
||||
:s_exit => section[:s_end], # last position (in m)
|
||||
:length => section[:s_end] -s_entry, # total length (in m)
|
||||
:r_path => section[:f_Rp], # path resistance (in ‰)
|
||||
:behaviorSections => Dict(), # list of containing behavior sections
|
||||
:t => 0.0, # total running time (in s)
|
||||
:E => 0.0, # total energy consumption (in Ws)
|
||||
:v_limit => v_limit, # speed limit (in m/s)
|
||||
# initializing :v_entry, :v_peak and :v_exit with :v_limit
|
||||
:v_peak => v_limit, # maximum reachable speed (in m/s)
|
||||
:v_entry => v_limit, # maximum entry speed (in m/s)
|
||||
:v_exit => v_limit) # maximum exit speed (in m/s)
|
||||
|
||||
# list of positions of every point of interest (POI) in this charateristic section for which data points should be calculated
|
||||
s_exit = characteristicSection[:s_exit]
|
||||
pointsOfInterest = Vector{Real}()
|
||||
if haskey(path, :pointsOfInterest)
|
||||
for POI in path[:pointsOfInterest]
|
||||
if s_entry < POI && POI < s_exit
|
||||
push!(pointsOfInterest, POI)
|
||||
end
|
||||
end
|
||||
end
|
||||
push!(pointsOfInterest, s_exit) # s_exit has to be the last POI so that there will always be a POI to campare the current position with
|
||||
|
||||
merge!(characteristicSection, Dict(:pointsOfInterest => pointsOfInterest))
|
||||
|
||||
return characteristicSection
|
||||
end #function createCharacteristicSection
|
||||
|
||||
## define the intersection velocities between the characterisitc sections to secure braking behavior
|
||||
function secureBrakingBehavior!(movingSection::Dict, a_braking::Real)
|
||||
# this function limits the entry and exit velocity of the characteristic sections to secure that the train stops at the moving sections end
|
||||
|
@ -123,7 +45,7 @@ function secureBrakingBehavior!(movingSection::Dict, a_braking::Real)
|
|||
end #function secureBrakingBehavior!
|
||||
|
||||
## define the intersection velocities between the characterisitc sections to secure accelerating behavior
|
||||
function secureAcceleratingBehavior!(movingSection::Dict, settings::Dict, train::Dict)
|
||||
function secureAcceleratingBehavior!(movingSection::Dict, settings::Settings, train::Train)
|
||||
# this function limits the entry and exit velocity of the characteristic sections in case that the train accelerates in every section and cruises aterwards
|
||||
CSs = movingSection[:characteristicSections]
|
||||
|
||||
|
@ -136,7 +58,7 @@ function secureAcceleratingBehavior!(movingSection::Dict, settings::Dict, train:
|
|||
CS[:v_entry] = min(CS[:v_entry], previousCSv_exit)
|
||||
startingPoint[:s] = CS[:s_entry]
|
||||
startingPoint[:v] = CS[:v_entry]
|
||||
calculateForces!(startingPoint, CSs, CS[:id], "accelerating", train, settings[:massModel]) # traction effort and resisting forces (in N)
|
||||
calculateForces!(startingPoint, CSs, CS[:id], "accelerating", train, settings.massModel) # traction effort and resisting forces (in N)
|
||||
acceleratingCourse::Vector{Dict} = [startingPoint] # List of data points
|
||||
|
||||
if CS[:v_entry] < CS[:v_peak]
|
||||
|
@ -160,7 +82,7 @@ function secureAcceleratingBehavior!(movingSection::Dict, settings::Dict, train:
|
|||
(CS, acceleratingCourse, stateFlags) = addClearingSection!(CS, acceleratingCourse, stateFlags, settings, train, CSs) # this function is needed in case the train is not allowed to accelerate because of a previous speed limit
|
||||
end
|
||||
else
|
||||
if settings[:massModel] == "mass point" || acceleratingCourse[end][:s] > CS[:s_entry] + train[:length]
|
||||
if settings.massModel == :mass_point || acceleratingCourse[end][:s] > CS[:s_entry] + train.length
|
||||
break
|
||||
else
|
||||
(CS, acceleratingCourse, stateFlags) = addDiminishingSection!(CS, acceleratingCourse, stateFlags, settings, train, CSs) # this function is needed in case the resisitng forces are higher than the maximum possible tractive effort
|
||||
|
@ -190,7 +112,7 @@ end #function secureAcceleratingBehavior!
|
|||
|
||||
#=
|
||||
## define the intersection velocities between the characterisitc sections to secure cruising behavior
|
||||
function secureCruisingBehavior!(movingSection::Dict, settings::Dict, train::Dict)
|
||||
function secureCruisingBehavior!(movingSection::Dict, settings::Settings, train::Train)
|
||||
# limit the exit velocity of the characteristic sections in case that the train cruises in every section at v_peak
|
||||
CSs = movingSection[:characteristicSections]
|
||||
|
||||
|
@ -225,7 +147,7 @@ function secureCruisingBehavior!(movingSection::Dict, settings::Dict, train::Dic
|
|||
(CS, cruisingCourse, stateFlags) = addCruisingSection!(CS, cruisingCourse, stateFlags, s_cruising, settings, train, CSs, "downhillBraking")
|
||||
end
|
||||
else
|
||||
if settings[:massModel] == "mass point" || cruisingCourse[end][:s] > CS[:s_entry] + train[:length]
|
||||
if settings.massModel == :mass_point || cruisingCourse[end][:s] > CS[:s_entry] + train.length
|
||||
break
|
||||
else
|
||||
(CS, cruisingCourse, stateFlags) = addDiminishingSection!(CS, cruisingCourse, stateFlags, settings, train, CSs) # this function is needed in case the resisitng forces are higher than the maximum possible tractive effort
|
||||
|
@ -246,4 +168,3 @@ function secureCruisingBehavior!(movingSection::Dict, settings::Dict, train::Dic
|
|||
return movingSection
|
||||
end #function secureCruisingBehavior!
|
||||
=#
|
||||
end #module Characteristics
|
|
@ -0,0 +1,741 @@
|
|||
#!/usr/bin/env julia
|
||||
# -*- coding: UTF-8 -*-
|
||||
# __julia-version__ = 1.7.2
|
||||
# __author__ = "Martin Scheidt, Max Kannenberg"
|
||||
# __copyright__ = "2022"
|
||||
# __license__ = "ISC"
|
||||
|
||||
"""
|
||||
Settings(file)
|
||||
|
||||
Settings is a datastruture for calculation context.
|
||||
The function Settings() will create a set of settings for the train run calculation.
|
||||
`file` is optinal may be used to load settings in the YAML format.
|
||||
|
||||
# Example
|
||||
```jldoctest
|
||||
julia> my_settings = Settings() # will generate default settings
|
||||
Settings(mass_point, :distance, 20, 3, running_time, :dataframe)
|
||||
```
|
||||
"""
|
||||
function Settings(file="DEFAULT")
|
||||
|
||||
## default values
|
||||
massModel = :mass_point
|
||||
stepVariable = :distance
|
||||
stepSize = 20
|
||||
approxLevel = 3
|
||||
outputDetail = :running_time
|
||||
outputFormat = :dataframe
|
||||
|
||||
## load from file
|
||||
if file != "DEFAULT"
|
||||
|
||||
## JSON schema for YAML-file validation
|
||||
schema = Schema("""{
|
||||
"properties": {
|
||||
"massModel": {
|
||||
"description": "type of train model",
|
||||
"type": "string",
|
||||
"enum": [ "mass_point", "homogeneous_strip" ]
|
||||
},
|
||||
"stepVariable": {
|
||||
"description": "variable of the linear multistep method",
|
||||
"type": "string",
|
||||
"enum": [ "distance", "time", "velocity" ]
|
||||
},
|
||||
"stepSize": {
|
||||
"description": "step size acording to stepVariable",
|
||||
"type": "number",
|
||||
"exclusiveMinimum": 0
|
||||
},
|
||||
"outputDetail": {
|
||||
"description": "Selecting the detail of the result",
|
||||
"type": "string",
|
||||
"enum": [ "running_time", "points_of_interest", "driving_course", "everything" ]
|
||||
},
|
||||
"outputFormat": {
|
||||
"description": "Output format",
|
||||
"type": "string",
|
||||
"enum": [ "dataframe", "dict" ]
|
||||
}
|
||||
}
|
||||
}""")
|
||||
|
||||
settings = YAML.load(open(file))["settings"]
|
||||
|
||||
## validate the loaded file
|
||||
try
|
||||
validate(schema, settings)
|
||||
catch err
|
||||
println("Could not load settings file '$file'.\n Format is not recognized - using default as fall back.")
|
||||
settings = Dict()
|
||||
end
|
||||
|
||||
## set the variables in "settings"
|
||||
haskey(settings, "massModel") ? massModel = Symbol(settings["massModel"]) : nothing
|
||||
haskey(settings, "stepVariable") ? stepVariable = Symbol(settings["stepVariable"]) : nothing
|
||||
haskey(settings, "stepSize") ? stepSize = settings["stepSize"] : nothing
|
||||
haskey(settings, "approxLevel") ? approxLevel = settings["approxLevel"] : nothing
|
||||
haskey(settings, "outputDetail") ? outputDetail = Symbol(settings["outputDetail"]) : nothing
|
||||
haskey(settings, "outputFormat") ? outputFormat = Symbol(settings["outputFormat"]) : nothing
|
||||
end
|
||||
|
||||
Settings(massModel, stepVariable, stepSize, approxLevel, outputDetail, outputFormat)
|
||||
|
||||
end #function Settings() # outer constructor
|
||||
|
||||
"""
|
||||
Path(file, type = :YAML)
|
||||
|
||||
Path is a datastruture for calculation context.
|
||||
The function Path() will create a running path for the train.
|
||||
Supported formats are: railtoolkit/schema (2022.05)
|
||||
|
||||
# Example
|
||||
```jldoctest
|
||||
julia> my_path = Path("file.yaml") # will generate a path from a YAML file.
|
||||
Path(variables)
|
||||
```
|
||||
"""
|
||||
function Path(file, type = :YAML)
|
||||
|
||||
## default values
|
||||
name = ""
|
||||
id = ""
|
||||
uuid = UUIDs.uuid4()
|
||||
poi = []
|
||||
sections = []
|
||||
|
||||
## process flags
|
||||
POI_PRESENT = false
|
||||
|
||||
## load from file
|
||||
if type == :YAML
|
||||
|
||||
data = YAML.load(open(file))
|
||||
if data["schema"] != "https://railtoolkit.org/schema/running-path.json"
|
||||
error("Could not load path file '$file'.\n
|
||||
YAML format is not recognized.
|
||||
Currently supported: railtoolkit/schema/running-path (2022.05)")
|
||||
end
|
||||
if data["schema_version"] != "2022.05"
|
||||
error("Could not load path file '$file'.\n
|
||||
YAML format is not recognized.
|
||||
Currently supported: railtoolkit/schema/running-path (2022.05)")
|
||||
end
|
||||
|
||||
## JSON schema for YAML-file validation
|
||||
railtoolkit_schema = Schema("""{
|
||||
"required": [ "schema", "schema_version", "paths" ],
|
||||
"properties": {
|
||||
"schema": {
|
||||
"description": "Identifier of the schema",
|
||||
"enum": [ "https://railtoolkit.org/schema/running-path.json" ]
|
||||
},
|
||||
"schema_version": {
|
||||
"description": "Version of the schema",
|
||||
"type": "string",
|
||||
"pattern": "[2-9][0-9][0-9][0-9].[0-1][0-9]"
|
||||
},
|
||||
"paths": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"required": [ "name", "id", "characteristic_sections" ],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"characteristic_sections": {
|
||||
"description": "",
|
||||
"type": "array",
|
||||
"minItems": 2,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": "array",
|
||||
"minItems": 3,
|
||||
"maxItems": 3,
|
||||
"description": "",
|
||||
"prefixItems": [
|
||||
{
|
||||
"description": "milage in meter",
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"description": "speed in kilometers per hour",
|
||||
"type": "number",
|
||||
"exclusiveMinimum": 0
|
||||
},
|
||||
{
|
||||
"description": "resistance in permil",
|
||||
"type": "number"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"id": {
|
||||
"description": "Identifier of the path",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "Name of the path",
|
||||
"type": "string"
|
||||
},
|
||||
"points_of_interest": {
|
||||
"description": "",
|
||||
"type": "array",
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": "array",
|
||||
"minItems": 3,
|
||||
"maxItems": 3,
|
||||
"description": "",
|
||||
"prefixItems": [
|
||||
{ "type": "number" },
|
||||
{ "type": "string" },
|
||||
{ "enum": [ "front", "rear" ] }
|
||||
]
|
||||
}
|
||||
},
|
||||
"UUID": {
|
||||
"description": "The unique identifier for a path",
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}""")
|
||||
|
||||
paths = data["paths"]
|
||||
try
|
||||
validate(railtoolkit_schema, paths)
|
||||
catch err
|
||||
error("Could not load path file '$file'.\n
|
||||
YAML format is not recognized.
|
||||
Currently supported: railtoolkit/schema/running-path (2022.05)")
|
||||
end
|
||||
if length(paths) > 1
|
||||
println("WARNING: the loaded file contains more than one path. Using only the first!")
|
||||
end
|
||||
path = paths[1]
|
||||
|
||||
## set the variables in "path"
|
||||
# required
|
||||
name = path["name"]
|
||||
id = path["id"]
|
||||
tmp_sec = path["characteristic_sections"]
|
||||
# optional
|
||||
haskey(path, "UUID") ? uuid = parse(UUID, path["UUID"] ) : nothing
|
||||
haskey(path, "points_of_interest") ? POI_PRESENT = true : nothing
|
||||
haskey(path, "points_of_interest") ? tmp_points = path["points_of_interest"] : nothing
|
||||
|
||||
else
|
||||
error("Unknown file type '$type'")
|
||||
end #if type
|
||||
|
||||
## process characteristic sections
|
||||
sort!(tmp_sec, by = x -> x[1])
|
||||
for row in 2:length(tmp_sec)
|
||||
s_start = tmp_sec[row-1][1] # first point of the section (in m)
|
||||
s_end = tmp_sec[row][1] # first point of the next section (in m)
|
||||
v_limit = tmp_sec[row-1][2]/3.6 # paths speed limt (in m/s)
|
||||
f_Rp = tmp_sec[row-1][3] # specific path resistance of the section (in ‰)
|
||||
|
||||
section = Dict(:s_start => s_start,
|
||||
:s_end => s_end,
|
||||
:v_limit => v_limit,
|
||||
:f_Rp => f_Rp)
|
||||
push!(sections, section)
|
||||
end #for row
|
||||
# s_start in first entry defines the path's beginning
|
||||
# s_end in last entry defines the path's ending
|
||||
|
||||
## process points of interest
|
||||
if POI_PRESENT
|
||||
sort!(tmp_points, by = x -> x[1])
|
||||
for elem in tmp_points
|
||||
station = elem[1] # first point of the section (in m)
|
||||
label = elem[2] # paths speed limt (in m/s)
|
||||
measure = elem[3] # specific path resistance of the section (in ‰)
|
||||
|
||||
point = Dict(:station => station,
|
||||
:label => label,
|
||||
:measure => measure)
|
||||
push!(poi, point)
|
||||
end #for elem
|
||||
end #if !isempty(points)
|
||||
|
||||
Path(name, id, uuid, poi, sections)
|
||||
|
||||
end #function Path() # outer constructor
|
||||
|
||||
"""
|
||||
Train(file, type = :YAML)
|
||||
|
||||
Train is a datastruture for calculation context.
|
||||
The function Train() will create a train to use in calculations.
|
||||
Supported formats for the YAML files are: railtoolkit/schema (2022.05)
|
||||
|
||||
# Example
|
||||
```jldoctest
|
||||
julia> my_train = Train("file.yaml") # will generate a train from a YAML file.
|
||||
Train(variables)
|
||||
```
|
||||
"""
|
||||
function Train(file, type = :YAML)
|
||||
|
||||
## default values
|
||||
name = "" #
|
||||
id = "" #
|
||||
uuid = UUIDs.uuid4() #
|
||||
length = 0 # in meter
|
||||
m_train_full = 0 # in kilogram
|
||||
m_train_empty = 0 # in kilogram
|
||||
m_loco = 0 # in kilogram
|
||||
m_td = 0 # in kilogram
|
||||
m_tc = 0 # in kilogram
|
||||
m_car_full = 0 # in kilogram
|
||||
m_car_empty = 0 # in kilogram
|
||||
ξ_train = 1.08 # rotation mass factor, source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 13 for "Zug, überschlägliche Berechnung"
|
||||
ξ_loco = 1.09 # rotation mass factor
|
||||
ξ_cars = 1.06 # rotation mass factor
|
||||
transportType = :freight # "freight" or "passenger" for resistance calculation
|
||||
v_limit = 140 # in m/s (default 504 km/h)
|
||||
a_braking = 0 # in m/s^2, todo: implement as function
|
||||
f_Rtd0 = 0 # coefficient for basic resistance due to the traction units driving axles (in ‰)
|
||||
f_Rtc0 = 0 # coefficient for basic resistance due to the traction units carring axles (in ‰)
|
||||
F_Rt2 = 3000 # coefficient for air resistance of the traction units (in N)
|
||||
f_Rw0 = 0 # coefficient for the consists basic resistance (in ‰)
|
||||
f_Rw1 = 0 # coefficient for the consists resistance to rolling (in ‰)
|
||||
f_Rw2 = 0 # coefficient fo the consistsr air resistance (in ‰)
|
||||
F_v_pairs = [] # [v in m/s, F_T in N]
|
||||
|
||||
## load from file
|
||||
if type == :YAML
|
||||
|
||||
data = YAML.load(open(file))
|
||||
if data["schema"] != "https://railtoolkit.org/schema/rolling-stock.json"
|
||||
error("Could not load path file '$file'.\n
|
||||
YAML format is not recognized.
|
||||
Currently supported: railtoolkit/schema/rolling-stock (2022.05)")
|
||||
end
|
||||
if data["schema_version"] != "2022.05"
|
||||
error("Could not load path file '$file'.\n
|
||||
YAML format is not recognized.
|
||||
Currently supported: railtoolkit/schema/rolling-stock (2022.05)")
|
||||
end
|
||||
|
||||
## JSON schema for YAML-file validation
|
||||
railtoolkit_schema = Schema("""{
|
||||
"required": [ "schema", "schema_version" ],
|
||||
"anyOf": [
|
||||
{"required": [ "trains" ] },
|
||||
{"required": [ "vehicles" ] }
|
||||
],
|
||||
"properties": {
|
||||
"schema": {
|
||||
"description": "Identifier of the schema",
|
||||
"enum": [ "https://railtoolkit.org/schema/rolling-stock.json" ]
|
||||
},
|
||||
"schema_version": {
|
||||
"description": "Version of the schema",
|
||||
"type": "string",
|
||||
"pattern": "[2-9][0-9][0-9][0-9].[0-1][0-9]"
|
||||
},
|
||||
"trains": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"required": [ "name", "id", "formation" ],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"description": "Identifier of the train",
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"description": "Name of the train",
|
||||
"type": "string"
|
||||
},
|
||||
"UUID": {
|
||||
"description": "The unique identifier for a train",
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"formation": {
|
||||
"description": "Collection of vehicles that form the train",
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"uniqueItems": false,
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"vehicles": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"required": [ "name", "id", "vehicle_type", "length", "mass" ],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"air_resistance": {
|
||||
"description": "coefficient for air resistance in permil",
|
||||
"type": "number",
|
||||
"exclusiveMinimum": 0
|
||||
},
|
||||
"base_resistance": {
|
||||
"description": "coefficient for basic resistance in permil",
|
||||
"type": "number",
|
||||
"exclusiveMinimum": 0
|
||||
},
|
||||
"id": {
|
||||
"description": "Identifier of the vehicle",
|
||||
"type": "string"
|
||||
},
|
||||
"length": {
|
||||
"description": "The length of the vehicle in meter",
|
||||
"type": "number",
|
||||
"exclusiveMinimum": 0
|
||||
},
|
||||
"load_limit": {
|
||||
"description": "The maximum permitted load of the vehicle in metric ton",
|
||||
"type": "number",
|
||||
"exclusiveMinimum": 0
|
||||
},
|
||||
"mass_traction": {
|
||||
"description": "The mass on the powered axles of the vehicle in metric ton",
|
||||
"type": "number",
|
||||
"exclusiveMinimum": 0
|
||||
},
|
||||
"mass": {
|
||||
"description": "The empty mass of the vehicle in metric ton",
|
||||
"type": "number",
|
||||
"exclusiveMinimum": 0
|
||||
},
|
||||
"name": {
|
||||
"description": "Name of the vehicle",
|
||||
"type": "string"
|
||||
},
|
||||
"picture": {
|
||||
"description": "A URI with a picture for humans",
|
||||
"type": "string",
|
||||
"format": "uri"
|
||||
},
|
||||
"power_type": {
|
||||
"description": "Type of propulsion",
|
||||
"enum": [ "diesel", "electric", "steam" ]
|
||||
},
|
||||
"rolling_resistance": {
|
||||
"description": "coefficient for resistance of rolling axles in permil",
|
||||
"type": "number",
|
||||
"exclusiveMinimum": 0
|
||||
},
|
||||
"rotation_mass": {
|
||||
"description": "Factor for rotating mass; >= 1",
|
||||
"type": "number",
|
||||
"minimum": 1
|
||||
},
|
||||
"speed_limit": {
|
||||
"description": "Maximum permitted speed in kilometers per hour",
|
||||
"type": "number",
|
||||
"exclusiveMinimum": 0
|
||||
},
|
||||
"tractive_effort": {
|
||||
"description": "Tractive effort as pairs of speed in kilometers per hour and tractive force in newton",
|
||||
"type": "array",
|
||||
"minItems": 3,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": "array",
|
||||
"minItems": 2,
|
||||
"maxItems": 2,
|
||||
"uniqueItems": true,
|
||||
"items": {
|
||||
"type": "number",
|
||||
"minimum": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"UUID": {
|
||||
"description": "The unique identifier for a vehicle",
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"vehicle_type": {
|
||||
"description": "Type of vehicle",
|
||||
"enum": [ "traction unit", "freight", "passenger", "multiple unit" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}""")
|
||||
|
||||
try
|
||||
validate(railtoolkit_schema, data)
|
||||
catch err
|
||||
error("Could not load path file '$file'.\n
|
||||
YAML format is not recognized.
|
||||
Currently supported: railtoolkit/schema/rolling-stock (2022.05)")
|
||||
end
|
||||
|
||||
else
|
||||
error("Unknown file type '$type'")
|
||||
end #if type
|
||||
|
||||
trains = data["trains"]
|
||||
Base.length(trains) > 1 ? println("WARNING: the loaded file contains more than one train. Using only the first!") : nothing
|
||||
Base.length(trains) == 0 ? error("No train present in file '$file'") : nothing
|
||||
train = trains[1]
|
||||
used_vehicles = unique(train["formation"])
|
||||
|
||||
included_vehicles = []
|
||||
for vehicle in data["vehicles"]
|
||||
push!(included_vehicles,vehicle["id"])
|
||||
end
|
||||
|
||||
## test if all vehicles of the formation are avilable
|
||||
for vehicle in used_vehicles
|
||||
vehicle ∉ included_vehicles ? error("'$vehicle' is not present in '$file'") : nothing
|
||||
end
|
||||
|
||||
## gather the count of vehicles and usage in the formation
|
||||
vehicles = NamedTuple[]
|
||||
for vehicle in data["vehicles"]
|
||||
if vehicle["id"] in used_vehicles
|
||||
n = count(==(vehicle["id"]),train["formation"])
|
||||
type = vehicle["vehicle_type"]
|
||||
type == "traction unit" || type == "multiple unit" ? propulsion = true : propulsion = false
|
||||
type == "passenger" || type == "multiple unit" ? transportType = :passenger : nothing
|
||||
push!(vehicles, (data=vehicle, n=n, propulsion=propulsion) )
|
||||
end
|
||||
end
|
||||
|
||||
## set the variables in "train"
|
||||
name = train["name"]
|
||||
id = train["id"]
|
||||
haskey(train, "UUID") ? uuid = parse(UUID, train["UUID"] ) : nothing
|
||||
transportType == :freight ? a_braking = -0.225 : a_braking = -0.375 # set a default a_braking value depending on the train type
|
||||
|
||||
## set the variables for all vehicles
|
||||
for vehicle in vehicles
|
||||
length += vehicle.data["length"] * vehicle.n
|
||||
m_train_full += vehicle.data["mass"] * vehicle.n * 1000 # in kg
|
||||
m_train_empty += vehicle.data["mass"] * vehicle.n * 1000 # in kg
|
||||
haskey(vehicle.data, "load_limit") ?
|
||||
m_train_full += vehicle.data["load_limit"] * vehicle.n * 1000 : # in kg
|
||||
nothing
|
||||
haskey(vehicle.data, "speed_limit") ?
|
||||
v_limit > vehicle.data["speed_limit"]/3.6 ? v_limit = vehicle.data["speed_limit"]/3.6 : nothing :
|
||||
nothing
|
||||
end
|
||||
|
||||
## divide vehicles in propulsion and non-propulsion
|
||||
loco = []
|
||||
for i in 1:Base.length(vehicles)
|
||||
if vehicles[i].propulsion
|
||||
push!(loco, vehicles[i])
|
||||
deleteat!(vehicles, i)
|
||||
end
|
||||
end
|
||||
Base.length(loco) > 1 ? println("WARNING: the loaded file contains more than one traction unit or multiple unit. Using only the first!") : nothing
|
||||
loco[1].n > 1 ? println("WARNING: the loaded file contains more than one traction unit or multiple unit. Using only one!") : nothing
|
||||
Base.length(loco) == 0 ? error("No traction unit or multiple unit present in file '$file'") : nothing
|
||||
loco = loco[1].data
|
||||
cars = vehicles
|
||||
|
||||
## set the variables for locos
|
||||
m_loco= loco["mass"] * 1000
|
||||
haskey(loco, "a_braking") ? a_braking = loco["a_braking"] : nothing
|
||||
haskey(loco, "base_resistance") ? f_Rtd0 = loco["base_resistance"] : nothing
|
||||
haskey(loco, "rolling_resistance") ? f_Rtc0 = loco["rolling_resistance"] : nothing
|
||||
haskey(loco, "air_resistance") ? F_Rt2 = loco["air_resistance"] * g * m_loco : nothing
|
||||
haskey(loco, "mass_traction") ? m_td = loco["mass_traction"] * 1000 : m_td = m_t
|
||||
haskey(loco, "rotation_mass") ? ξ_loco = loco["rotation_mass"] : nothing
|
||||
m_tc = m_loco- m_td
|
||||
haskey(loco, "tractive_effort") ? F_v_pairs = loco["tractive_effort"] : F_v_pairs = [ [0.0, m_td * g * μ],[v_limit*3.6, m_td * g * μ] ]
|
||||
F_v_pairs = reduce(hcat,F_v_pairs)' # convert to matrix
|
||||
F_v_pairs[:,1] ./= 3.6 # convert km/h to m/s
|
||||
F_v_pairs = tuple.(eachcol(F_v_pairs)...) # convert each row to tuples
|
||||
|
||||
## set the variables for cars
|
||||
if !isempty(cars)
|
||||
resis_base = []
|
||||
resis_roll = []
|
||||
resis_air = []
|
||||
rotMassFac = []
|
||||
for car in cars
|
||||
haskey(car.data, "base_resistance") ?
|
||||
append!(resis_base,repeat([car.data["base_resistance"]],car.n)) :
|
||||
append!(resis_base,repeat([f_Rw0],car.n))
|
||||
haskey(car.data, "rolling_resistance") ?
|
||||
append!(resis_roll,repeat([car.data["rolling_resistance"]],car.n)) :
|
||||
append!(resis_roll,repeat([f_Rw1],car.n))
|
||||
haskey(car.data, "air_resistance") ?
|
||||
append!(resis_air,repeat([car.data["air_resistance"]],car.n)) :
|
||||
append!(resis_air, repeat([f_Rw2],car.n))
|
||||
haskey(car.data, "rotation_mass") ?
|
||||
append!(rotMassFac,repeat([(car.data["rotation_mass"],car.data["mass"])],car.n)) :
|
||||
append!(rotMassFac,repeat([(ξ_cars ,car.data["mass"])],car.n))
|
||||
m_car_empty += car.data["mass"] * car.n * 1000 # in kg
|
||||
m_car_full += car.data["mass"] * car.n * 1000 # in kg
|
||||
haskey(car.data, "load_limit") ?
|
||||
m_car_full += car.data["load_limit"] * car.n * 1000 : # in kg
|
||||
nothing
|
||||
end
|
||||
f_Rw0 = Statistics.mean(resis_base)
|
||||
f_Rw1 = Statistics.mean(resis_roll)
|
||||
f_Rw2 = Statistics.mean(resis_air)
|
||||
carRotMass = 0
|
||||
for elem in rotMassFac
|
||||
carRotMass += elem[1]*elem[2] * 1000 # in kg
|
||||
end
|
||||
ξ_cars = carRotMass/m_car_empty
|
||||
ξ_train = (ξ_loco * m_loco+ carRotMass)/m_train_empty
|
||||
else
|
||||
ξ_cars = 0
|
||||
ξ_train = ξ_loco
|
||||
end
|
||||
|
||||
Train(
|
||||
name, id, uuid, length,
|
||||
m_train_full, m_td, m_tc, m_car_full,
|
||||
ξ_train, ξ_loco, ξ_cars,
|
||||
transportType, v_limit,
|
||||
a_braking,
|
||||
f_Rtd0, f_Rtc0, F_Rt2, f_Rw0, f_Rw1, f_Rw2,
|
||||
F_v_pairs
|
||||
)
|
||||
|
||||
end #function Train() # outer constructor
|
||||
|
||||
## create a moving section containing characteristic sections
|
||||
function createMovingSection(path::Path, v_trainLimit::Real, s_trainLength::Real)
|
||||
# this function creates and returns a moving section dependent on the paths attributes
|
||||
|
||||
s_entry = path.sections[1][:s_start] # first position (in m)
|
||||
s_exit = path.sections[end][:s_end] # last position (in m)
|
||||
pathLength = s_exit - s_entry # total length (in m)
|
||||
|
||||
CSs=Vector{Dict}()
|
||||
s_csStart=s_entry
|
||||
csId=1
|
||||
for row in 2:length(path.sections)
|
||||
previousSection = path.sections[row-1]
|
||||
currentSection = path.sections[row]
|
||||
speedLimitIsDifferent = min(previousSection[:v_limit], v_trainLimit) != min(currentSection[:v_limit], v_trainLimit)
|
||||
pathResistanceIsDifferent = previousSection[:f_Rp] != currentSection[:f_Rp]
|
||||
if speedLimitIsDifferent || pathResistanceIsDifferent
|
||||
# 03/09 old: if min(previousSection[:v_limit], v_trainLimit) != min(currentSection[:v_limit], v_trainLimit) || previousSection[:f_Rp] != currentSection[:f_Rp]
|
||||
push!(CSs, createCharacteristicSection(csId, s_csStart, previousSection, min(previousSection[:v_limit], v_trainLimit), s_trainLength, path))
|
||||
s_csStart = currentSection[:s_start]
|
||||
csId = csId+1
|
||||
end #if
|
||||
end #for
|
||||
push!(CSs, createCharacteristicSection(csId, s_csStart, path.sections[end], min(path.sections[end][:v_limit], v_trainLimit), s_trainLength, path))
|
||||
|
||||
movingSection= Dict(:id => 1, # identifier # if there is more than one moving section in a later version of this tool the id should not be constant anymore
|
||||
:length => pathLength, # total length (in m)
|
||||
:s_entry => s_entry, # first position (in m)
|
||||
:s_exit => s_exit, # last position (in m)
|
||||
:t => 0.0, # total running time (in s)
|
||||
:E => 0.0, # total energy consumption (in Ws)
|
||||
:characteristicSections => CSs) # list of containing characteristic sections
|
||||
|
||||
return movingSection
|
||||
end #function createMovingSection
|
||||
|
||||
## create a characteristic section for a path section. A characteristic section is a part of the moving section. It contains behavior sections.
|
||||
function createCharacteristicSection(id::Integer, s_entry::Real, section::Dict, v_limit::Real, s_trainLength::Real, path::Path)
|
||||
# Create and return a characteristic section dependent on the paths attributes
|
||||
characteristicSection= Dict(:id => id, # identifier
|
||||
:s_entry => s_entry, # first position (in m)
|
||||
:s_exit => section[:s_end], # last position (in m)
|
||||
:length => section[:s_end] -s_entry, # total length (in m)
|
||||
:r_path => section[:f_Rp], # path resistance (in ‰)
|
||||
:behaviorSections => Dict(), # list of containing behavior sections
|
||||
:t => 0.0, # total running time (in s)
|
||||
:E => 0.0, # total energy consumption (in Ws)
|
||||
:v_limit => v_limit, # speed limit (in m/s)
|
||||
# initializing :v_entry, :v_peak and :v_exit with :v_limit
|
||||
:v_peak => v_limit, # maximum reachable speed (in m/s)
|
||||
:v_entry => v_limit, # maximum entry speed (in m/s)
|
||||
:v_exit => v_limit) # maximum exit speed (in m/s)
|
||||
|
||||
# list of positions of every point of interest (POI) in this charateristic section for which data points should be calculated
|
||||
s_exit = characteristicSection[:s_exit]
|
||||
|
||||
##TODO: use a tuple with naming
|
||||
pointsOfInterest = Tuple[]
|
||||
# pointsOfInterest = Real[]
|
||||
if !isempty(path.poi)
|
||||
for POI in path.poi
|
||||
s_poi = POI[:station]
|
||||
if POI[:measure] == "rear"
|
||||
s_poi -= s_trainLength
|
||||
end
|
||||
if s_entry < s_poi && s_poi < s_exit
|
||||
push!(pointsOfInterest, (s_poi, POI[:label]) )
|
||||
# push!(pointsOfInterest, s_poi )
|
||||
end
|
||||
end
|
||||
end
|
||||
push!(pointsOfInterest, (s_exit,"")) # s_exit has to be the last POI so that there will always be a POI to campare the current position with
|
||||
# push!(pointsOfInterest, s_exit) # s_exit has to be the last POI so that there will always be a POI to campare the current position with
|
||||
|
||||
merge!(characteristicSection, Dict(:pointsOfInterest => pointsOfInterest))
|
||||
|
||||
return characteristicSection
|
||||
end #function createCharacteristicSection
|
||||
|
||||
"""
|
||||
a DataPoint is the smallest element of the driving course. One step of the step approach is between two data points
|
||||
"""
|
||||
function createDataPoint()
|
||||
dataPoint = Dict(
|
||||
:i => 0, # identifier and counter variable of the driving course
|
||||
:behavior => "", # type of behavior section the data point is part of - see createBehaviorSection()
|
||||
# a data point which is the last point of one behavior section and the first point of the next behavior section will be attached to the latter
|
||||
:s => 0.0, # position (in m)
|
||||
:Δs => 0.0, # step size (in m)
|
||||
:t => 0.0, # point in time (in s)
|
||||
:Δt => 0.0, # step size (in s)
|
||||
:v => 0.0, # velocity (in m/s)
|
||||
:Δv => 0.0, # step size (in m/s)
|
||||
:a => 0.0, # acceleration (in m/s^2)
|
||||
:W => 0.0, # mechanical work (in Ws)
|
||||
:ΔW => 0.0, # mechanical work in this step (in Ws)
|
||||
:E => 0.0, # energy consumption (in Ws)
|
||||
:ΔE => 0.0, # energy consumption in this step (in Ws)
|
||||
:F_T => 0.0, # tractive effort (in N)
|
||||
:F_R => 0.0, # resisting force (in N)
|
||||
:R_path => 0.0, # path resistance (in N)
|
||||
:R_train => 0.0, # train resistance (in N)
|
||||
:R_traction => 0.0, # traction unit resistance (in N)
|
||||
:R_wagons => 0.0, # set of wagons resistance (in N)
|
||||
:label => "" # a label for importend points
|
||||
)
|
||||
return dataPoint
|
||||
end #function createDataPoint
|
||||
|
||||
"""
|
||||
BehaviorSection() TODO!
|
||||
"""
|
||||
function createBehaviorSection(type::String, s_entry::Real, v_entry::Real, startingPoint::Integer)
|
||||
BS= Dict(
|
||||
:type => type, # type of behavior section: "breakFree", "clearing", "accelerating", "cruising", "downhillBraking", "diminishing", "coasting", "braking" or "standstill"
|
||||
:length => 0.0, # total length (in m)
|
||||
:s_entry => s_entry, # first position (in m)
|
||||
:s_exit => 0.0, # last position (in m)
|
||||
:t => 0.0, # total running time (in s)
|
||||
:E => 0.0, # total energy consumption (in Ws)
|
||||
:v_entry => v_entry, # entry speed (in m/s)
|
||||
:v_exit => 0.0, # exit speed (in m/s)
|
||||
:dataPoints => [startingPoint] # list of identifiers of the containing data points starting with the initial point
|
||||
)
|
||||
return BS
|
||||
end #function createBehaviorSection
|
|
@ -5,8 +5,6 @@
|
|||
# __copyright__ = "2022"
|
||||
# __license__ = "ISC"
|
||||
|
||||
module Formulary
|
||||
|
||||
#########################
|
||||
## literature the driving dynamics equations are based on:
|
||||
##
|
||||
|
@ -21,17 +19,6 @@ module Formulary
|
|||
## isbn = {978-3-777-10462-1},
|
||||
## publisher = {Eurailpress DVV Media Group},
|
||||
## }
|
||||
## @article{Jaekel:2014,
|
||||
## author = {Jaekel, Birgit and Albrecht, Thomas},
|
||||
## year = {2014},
|
||||
## title = {Comparative analysis of algorithms and models for train running simulation},
|
||||
## journal = {Journal of Rail Transport Planning \& Management},
|
||||
## doi = {10.1016/j.jrtpm.2014.06.002},
|
||||
## volume = {4},
|
||||
## number = {1-2},
|
||||
## pages = {14--27},
|
||||
## publisher = {Elsevier},
|
||||
## }
|
||||
## @Book{Wende:2003,
|
||||
## author = {Wende, Dietrich},
|
||||
## date = {2003},
|
||||
|
@ -41,24 +28,8 @@ module Formulary
|
|||
## }
|
||||
#########################
|
||||
|
||||
# export resisting forces and acceleration
|
||||
export calcTractionUnitResistance, calcWagonsResistance, calcForceFromCoefficient, calcAcceleration,
|
||||
|
||||
# export step sizes in different units
|
||||
calc_Δs_with_Δt, calc_Δs_with_Δv,
|
||||
calc_Δt_with_Δs, calc_Δt_with_Δv, calc_Δt_with_constant_v,
|
||||
calc_Δv_with_Δs, calc_Δv_with_Δt,
|
||||
calc_ΔW, calc_ΔE,
|
||||
|
||||
# export braking information
|
||||
calcBrakingDistance, calcBrakingStartVelocity, calcBrakingAcceleration
|
||||
|
||||
approxLevel = 6
|
||||
v00 = 100/3.6 # velocity factor (in m/s)
|
||||
g = 9.81 # acceleration due to gravity (in m/s^2) # TODO: should more digits of g be used? g=9,80665 m/s^2
|
||||
|
||||
approximationLevel = 6 # value for approximation to intersections TODO further explanation (e.g. approximationLevel = 3 -> with stepSize 10 m the approximation will be calculated accurate on 10 mm ; 1s -> 1 ms; 1 km/h -> 3.6 mm/s)
|
||||
# TODO: necessary here?
|
||||
|
||||
|
||||
## calculate forces
|
||||
|
||||
|
@ -71,7 +42,7 @@ Calculate the vehicle resistance for the traction unit of the `train` dependend
|
|||
...
|
||||
# Arguments
|
||||
- `v::AbstractFloat`: the current velocity in m/s.
|
||||
- `train::Dict`: ? ? ?
|
||||
- `train::Train`: ? ? ?
|
||||
...
|
||||
|
||||
# Examples
|
||||
|
@ -80,36 +51,34 @@ julia> calcTractionUnitResistance(30.0, ? ? ?)
|
|||
? ? ?
|
||||
```
|
||||
"""
|
||||
function calcTractionUnitResistance(v::AbstractFloat, train::Dict)
|
||||
function calcTractionUnitResistance(v::AbstractFloat, train::Train)
|
||||
# equation is based on [Wende:2003, page 151]
|
||||
f_Rtd0 = train[:f_Rtd0] # coefficient for basic resistance due to the traction units driving axles (in ‰)
|
||||
f_Rtc0 = train[:f_Rtc0] # coefficient for basic resistance due to the traction units carring axles (in ‰)
|
||||
F_Rt2 = train[:F_Rt2] # coefficient for air resistance of the traction units (in N)
|
||||
m_td = train[:m_td] # mass on the traction unit's driving axles (in kg)
|
||||
m_tc = train[:m_tc] # mass on the traction unit's carrying axles (in kg)
|
||||
Δv_t = train[:Δv_t] # coefficient for velocitiy difference between traction unit and outdoor air (in m/s)
|
||||
f_Rtd0 = train.f_Rtd0 # coefficient for basic resistance due to the traction units driving axles (in ‰)
|
||||
f_Rtc0 = train.f_Rtc0 # coefficient for basic resistance due to the traction units carring axles (in ‰)
|
||||
F_Rt2 = train.F_Rt2 # coefficient for air resistance of the traction units (in N)
|
||||
m_td = train.m_td # mass on the traction unit's driving axles (in kg)
|
||||
m_tc = train.m_tc # mass on the traction unit's carrying axles (in kg)
|
||||
|
||||
F_R_tractionUnit = f_Rtd0/1000 * m_td * g + f_Rtc0/1000 * m_tc * g + F_Rt2 * ((v + Δv_t) /v00)^2 # vehicle resistance of the traction unit (in N) # /1000 because of the unit ‰
|
||||
# TODO: use calcForceFromCoefficient? F_R_tractionUnit = calcForceFromCoefficient(f_Rtd0, m_td) + calcForceFromCoefficient(f_Rtc0, m_tc) + F_Rt2 * ((v + Δv_t) /v00)^2 # vehicle resistance of the traction unit (in N)
|
||||
F_R_tractionUnit = f_Rtd0/1000 * m_td * g + f_Rtc0/1000 * m_tc * g + F_Rt2 * ((v + Δv_air) /v00)^2 # vehicle resistance of the traction unit (in N) # /1000 because of the unit ‰
|
||||
# TODO: use calcForceFromCoefficient? F_R_tractionUnit = calcForceFromCoefficient(f_Rtd0, m_td) + calcForceFromCoefficient(f_Rtc0, m_tc) + F_Rt2 * ((v + Δv_air) /v00)^2 # vehicle resistance of the traction unit (in N)
|
||||
return F_R_tractionUnit
|
||||
#TODO: same variable name like in the rest of the tool? return R_traction
|
||||
#TODO: just one line? return train[:f_Rtd0]/1000*train[:m_td]*g+train[:f_Rtc0]/1000*train[:m_tc]*g+train[:F_Rt2]*((v+train[:Δv_t])/v00)^2 # /1000 because of the unit ‰
|
||||
#TODO: just one line? return train.f_Rtd0/1000*train.m_td*g+train.f_Rtc0/1000*train.m_tc*g+train.F_Rt2*((v+train.Δv_air)/v00)^2 # /1000 because of the unit ‰
|
||||
end #function calcTractionUnitResistance
|
||||
|
||||
"""
|
||||
TODO
|
||||
calculate and return the wagons vehicle resistance dependend on the velocity
|
||||
"""
|
||||
function calcWagonsResistance(v::AbstractFloat, train::Dict)
|
||||
function calcWagonsResistance(v::AbstractFloat, train::Train)
|
||||
# equation is based on a combination of the equations of Strahl and Sauthoff [Wende:2003, page 153] with more detailled factors (Lehmann, page 135)
|
||||
f_Rw0 = train[:f_Rw0] # coefficient for basic resistance of the set of wagons (consist) (in ‰)
|
||||
f_Rw1 = train[:f_Rw1] # coefficient for the consists resistance to rolling (in ‰)
|
||||
f_Rw2 = train[:f_Rw2] # coefficient fo the consistsr air resistance (in ‰)
|
||||
m_w = train[:m_w] # mass of the set of wagons (consist) (in kg)
|
||||
Δv_w = train[:Δv_w] # coefficient for velocitiy difference between set of wagons (consist) and outdoor air (in m/s)
|
||||
f_Rw0 = train.f_Rw0 # coefficient for basic resistance of the set of wagons (consist) (in ‰)
|
||||
f_Rw1 = train.f_Rw1 # coefficient for the consists resistance to rolling (in ‰)
|
||||
f_Rw2 = train.f_Rw2 # coefficient fo the consistsr air resistance (in ‰)
|
||||
m_w = train.m_w # mass of the set of wagons (consist) (in kg)
|
||||
|
||||
F_R_wagons = m_w *g *(f_Rw0/1000 + f_Rw1/1000 *v /v00 + f_Rw2/1000 * ((v + Δv_w) /v00)^2) # vehicle resistance of the wagons (in N) # /1000 because of the unit ‰
|
||||
# TODO: use calcForceFromCoefficient? F_R_wagons = calcForceFromCoefficient(f_Rw0, m_w) + calcForceFromCoefficient(f_Rw1, m_w) *v /v00 + calcForceFromCoefficient(f_Rw2, m_w) * ((v + Δv_w) /v00)^2 # vehicle resistance of the wagons (in N)
|
||||
F_R_wagons = m_w *g *(f_Rw0/1000 + f_Rw1/1000 *v /v00 + f_Rw2/1000 * ((v + Δv_air) /v00)^2) # vehicle resistance of the wagons (in N) # /1000 because of the unit ‰
|
||||
# TODO: use calcForceFromCoefficient? F_R_wagons = calcForceFromCoefficient(f_Rw0, m_w) + calcForceFromCoefficient(f_Rw1, m_w) *v /v00 + calcForceFromCoefficient(f_Rw2, m_w) * ((v + Δv_air) /v00)^2 # vehicle resistance of the wagons (in N)
|
||||
return F_R_wagons
|
||||
end #function calcWagonsResistance
|
||||
|
||||
|
@ -213,8 +182,8 @@ function calc_ΔW(F_T_prev::Real, Δs::Real)
|
|||
end #function calc_ΔW
|
||||
|
||||
function calc_ΔE(ΔW::Real)
|
||||
# simplified equation is based on [Jaekel:2014, page 6]
|
||||
|
||||
# simplified equation
|
||||
# TODO!
|
||||
# ΔW: mechanical work in this step (in Ws)
|
||||
ΔE = ΔW # energy consumption in this step (in Ws)
|
||||
return ΔE
|
||||
|
@ -228,8 +197,8 @@ function calcBrakingDistance(v_start::Real, v_end::Real, a_braking::Real)
|
|||
# a_braking: constant braking acceleration (in m/s^2)
|
||||
s_braking = (v_end^2 - v_start^2) /2 /a_braking # braking distance (in m)
|
||||
# TODO: also possible: calc_Δs_with_Δv(v_end-v_start, a_braking, v_start)
|
||||
# return max(0.0, ceil(s_braking, digits=approximationLevel)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
|
||||
return max(0.0, ceil(s_braking, digits=approximationLevel +1)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
|
||||
# return max(0.0, ceil(s_braking, digits=approxLevel)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
|
||||
return max(0.0, ceil(s_braking, digits=approxLevel +1)) # ceil is used to be sure that the train stops at s_exit in spite of rounding errors
|
||||
end #function calcBrakingDistance
|
||||
|
||||
function calcBrakingStartVelocity(v_end::Real, a_braking::Real, s_braking::Real)
|
||||
|
@ -239,8 +208,8 @@ function calcBrakingStartVelocity(v_end::Real, a_braking::Real, s_braking::Real)
|
|||
# a_braking: constant braking acceleration (in m/s^2)
|
||||
# s_braking: braking distance (in Ws)
|
||||
v_start = sqrt(v_end^2 - 2*a_braking *s_braking) # braking start velocity (in m/s)
|
||||
# return floor(v_start, digits=approximationLevel)
|
||||
return floor(v_start, digits=approximationLevel +1)
|
||||
# return floor(v_start, digits=approxLevel)
|
||||
return floor(v_start, digits=approxLevel +1)
|
||||
end #function calcBrakingStartVelocity
|
||||
|
||||
function calcBrakingAcceleration(v_start::Real, v_end::Real, s_braking::Real)
|
||||
|
@ -252,5 +221,3 @@ function calcBrakingAcceleration(v_start::Real, v_end::Real, s_braking::Real)
|
|||
a_braking = (v_end^2 - v_start^2) /2 /s_braking # constant braking acceleration (in m/s^2)
|
||||
return a_braking
|
||||
end #function calcBrakingAcceleration
|
||||
|
||||
end #module Formulary
|
|
@ -5,22 +5,22 @@
|
|||
# __copyright__ = "2020-2022"
|
||||
# __license__ = "ISC"
|
||||
|
||||
module Output
|
||||
|
||||
export createOutput
|
||||
|
||||
function createOutput(train::Dict, settings::Dict, path::Dict, movingSection::Dict, drivingCourse::Vector{Dict})
|
||||
if settings[:detailOfOutput] == "running time"
|
||||
function createOutput(train::Train, settings::Settings, path::Path, movingSection::Dict, drivingCourse::Vector{Dict})
|
||||
if settings.outputDetail == :running_time
|
||||
output = movingSection[:t] # TODO: or use drivingCourse[end][:t]
|
||||
|
||||
elseif settings[:detailOfOutput] == "points of interest"
|
||||
elseif settings.outputDetail == :points_of_interest
|
||||
# add points of interest
|
||||
if haskey(path, :pointsOfInterest)
|
||||
output = Vector{Dict}()
|
||||
if !isempty(path.poi)
|
||||
|
||||
# for elem in 1:length(driving_course)
|
||||
# end
|
||||
|
||||
output = Dict[]
|
||||
POI = 1
|
||||
i = 1
|
||||
while POI <= length(path[:pointsOfInterest]) && i <= drivingCourse[end][:i]
|
||||
if path[:pointsOfInterest][POI] == drivingCourse[i][:s]
|
||||
while POI <= length(path.poi) && i <= drivingCourse[end][:i]
|
||||
if path.poi[POI][:station] == drivingCourse[i][:s]
|
||||
push!(output, drivingCourse[i])
|
||||
POI = POI+1
|
||||
end
|
||||
|
@ -28,10 +28,10 @@ function createOutput(train::Dict, settings::Dict, path::Dict, movingSection::Di
|
|||
end
|
||||
end
|
||||
|
||||
elseif settings[:detailOfOutput] == "driving course"
|
||||
elseif settings.outputDetail == :driving_course
|
||||
output = drivingCourse
|
||||
|
||||
elseif settings[:detailOfOutput] == "everything"
|
||||
elseif settings.outputDetail == :everything
|
||||
output = Dict{Symbol,Any}()
|
||||
merge!(output, Dict(:train => train, :path => path, :settings => settings))
|
||||
|
||||
|
@ -46,12 +46,12 @@ function createOutput(train::Dict, settings::Dict, path::Dict, movingSection::Di
|
|||
end
|
||||
|
||||
# add points of interest
|
||||
if haskey(path, :pointsOfInterest)
|
||||
if !isempty(path.poi)
|
||||
pointsOfInterest = Vector{Dict}()
|
||||
POI = 1
|
||||
i = 1
|
||||
while POI <= length(path[:pointsOfInterest]) && i <= drivingCourse[end][:i]
|
||||
if path[:pointsOfInterest][POI] == drivingCourse[i][:s]
|
||||
while POI <= length(path.poi) && i <= drivingCourse[end][:i]
|
||||
if path.poi[POI] == drivingCourse[i][:s]
|
||||
push!(pointsOfInterest, drivingCourse[i])
|
||||
POI = POI+1
|
||||
end
|
||||
|
@ -71,7 +71,7 @@ function createOutput(train::Dict, settings::Dict, path::Dict, movingSection::Di
|
|||
end
|
||||
|
||||
#=
|
||||
function createOutputDict(train::Dict, settings::Dict, path::Dict, movingSection::Dict, drivingCourse::Vector{Dict})
|
||||
function createOutputDict(train::Train, settings::Settings, path::Path, movingSection::Dict, drivingCourse::Vector{Dict})
|
||||
outputDict = Dict{Symbol,Any}()
|
||||
merge!(outputDict, Dict(:train => train, :path => path, :settings => settings))
|
||||
|
||||
|
@ -86,12 +86,12 @@ function createOutputDict(train::Dict, settings::Dict, path::Dict, movingSection
|
|||
end
|
||||
|
||||
# add points of interest
|
||||
if haskey(path, :pointsOfInterest)
|
||||
if !isempty(path.poi)
|
||||
pointsOfInterest = Vector{Dict}()
|
||||
POI = 1
|
||||
i = 1
|
||||
while POI <= length(path[:pointsOfInterest]) && i <= drivingCourse[end][:i]
|
||||
if path[:pointsOfInterest][POI] == drivingCourse[i][:s]
|
||||
while POI <= length(path.poi) && i <= drivingCourse[end][:i]
|
||||
if path.poi[POI] == drivingCourse[i][:s]
|
||||
push!(pointsOfInterest, drivingCourse[i])
|
||||
POI = POI+1
|
||||
end
|
||||
|
@ -108,5 +108,3 @@ function createOutputDict(train::Dict, settings::Dict, path::Dict, movingSection
|
|||
return outputDict
|
||||
end # function createOutputDict
|
||||
=#
|
||||
|
||||
end # module Output
|
|
@ -0,0 +1,61 @@
|
|||
#!/usr/bin/env julia
|
||||
# -*- coding: UTF-8 -*-
|
||||
# __julia-version__ = 1.7.2
|
||||
# __author__ = "Martin Scheidt, Max Kannenberg"
|
||||
# __copyright__ = "2022"
|
||||
# __license__ = "ISC"
|
||||
|
||||
struct Settings
|
||||
|
||||
massModel::Symbol # model type of train mass ":mass_point" or ":homogeneous_strip".
|
||||
stepVariable::Symbol # variable of the linear multistep method: ":distance", ":time" or ":velocity".
|
||||
stepSize::Real # step size, unit depends on stepVariable - :distance in meter, time in seconds and velocity in meter/second.
|
||||
approxLevel::Int # value for approximation; used when rounding or interating.
|
||||
outputDetail::Symbol # single Float() ":running_time", Array() of ":points_of_interest",
|
||||
# complete Array() ":driving_course", or Dict() ":everything".
|
||||
outputFormat::Symbol # output as ":dataframe" or as ":dict".
|
||||
|
||||
end #struct Settings
|
||||
|
||||
struct Path
|
||||
|
||||
name::String # a name or description of the path
|
||||
id::String # a short string as identifier
|
||||
uuid::UUID # a unique identifier
|
||||
poi::Vector # a vector of triples with points along the path
|
||||
sections::Vector # a vector of the characteristic sections
|
||||
|
||||
end #struct Path
|
||||
|
||||
struct Train
|
||||
|
||||
name::String # a name or description of the train
|
||||
id::String # a short string as identifier
|
||||
uuid::UUID # a unique identifier
|
||||
length::Real # train length in meter
|
||||
m_train_full::Real # mass of the full loaded train in kilogram
|
||||
m_td::Real # mass on driving axles of the traction unit in kilogram
|
||||
m_tc::Real # mass on the traction unit's carrying axles in kilogram
|
||||
m_w::Real # mass of the set of wagons/cars/consist in kilogram
|
||||
ξ_train::Real # rotation mass factor
|
||||
ξ_loco::Real # rotation mass factor
|
||||
ξ_cars::Real # rotation mass factor
|
||||
transportType::Symbol # ":freight" or ":passenger" for resistance calculation
|
||||
v_limit::Real # in m/s
|
||||
a_braking::Real # in m/s^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_air)/v00)^2)
|
||||
f_Rtd0::Real # coefficient for basic resistance due to the traction units driving axles (in ‰)
|
||||
f_Rtc0::Real # coefficient for basic resistance due to the traction units carring axles (in ‰)
|
||||
F_Rt2::Real # coefficient for air resistance of the traction units (in N)
|
||||
|
||||
# for the consist (set of wagons) (F_Rw=m_w*g*(f_Rw0+f_Rw1*v/v00+f_Rw2*((v+Δv_air)/v00)^2))
|
||||
f_Rw0::Real # coefficient for the consists basic resistance (in ‰)
|
||||
f_Rw1::Real # coefficient for the consists resistance to rolling (in ‰)
|
||||
f_Rw2::Real # coefficient fo the consistsr air resistance (in ‰)
|
||||
|
||||
# tractive effort as pairs of speed and tractive effort
|
||||
tractiveEffort::Vector{Tuple{Real, Real}} # [v in m/s, F_T in N]
|
||||
|
||||
end #struct Train
|
|
@ -0,0 +1,21 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
schema: https://railtoolkit.org/schema/running-path.json
|
||||
schema_version: "2022.05"
|
||||
paths:
|
||||
- name: "10 km, no gradient, 160 km/h"
|
||||
id: const
|
||||
UUID: 23ff336e-9b9a-4535-bdb6-9db488b10945
|
||||
points_of_interest:
|
||||
# [ station in m, name, front or rear ]
|
||||
- [ 999.00, point_1, front ]
|
||||
- [ 2000.00, point_2, front ]
|
||||
- [ 3333.30, point_3, rear ]
|
||||
- [ 5000.00, point_4, front ]
|
||||
- [ 7777.00, point_5, front ]
|
||||
- [ 9000.00, point_6, front ]
|
||||
- [ 9500.95, point_7, front ]
|
||||
characteristic_sections:
|
||||
# [ station in m, speed limit in km/h, resistance in ‰ ]
|
||||
- [ 0.0, 160, 0.00 ]
|
||||
- [ 10000.0, 160, 0.00 ]
|
|
@ -0,0 +1,362 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
schema: https://railtoolkit.org/schema/running-path.json
|
||||
schema_version: "2022.05"
|
||||
paths:
|
||||
- name: "'infra_Ostsachsen': track id='tr_80.6212_2' name='DG-DN' -> spp_5"
|
||||
id: realworld
|
||||
UUID: 2b31a0c5-85bc-4721-b7e0-66f9df95f7b6
|
||||
# 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
|
||||
characteristic_sections:
|
||||
# [ s in m, v_limit in km/h, f_Rp in ‰ ]
|
||||
- [ 0.0, 40, 0.0 ]
|
||||
- [ 318.0, 40, 2.0 ]
|
||||
- [ 399.0, 40, -3.0 ]
|
||||
- [ 500.0, 40, 0.0 ]
|
||||
- [ 579.0, 40, 1.0 ]
|
||||
- [ 784.0, 40, 5.3 ]
|
||||
- [ 868.0, 40, 20.0 ]
|
||||
- [ 1082.0, 40, 16.1 ]
|
||||
- [ 1287.0, 40, 18.1 ]
|
||||
- [ 1800.0, 110, 18.1 ]
|
||||
- [ 2242.0, 110, 15.4 ]
|
||||
- [ 3295.0, 110, 11.0 ]
|
||||
- [ 3880.0, 110, 11.1 ]
|
||||
- [ 4680.0, 45, 11.1 ]
|
||||
- [ 4686.0, 90, 11.1 ]
|
||||
- [ 6122.0, 90, 0.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.0 ]
|
||||
- [ 7552.0, 160, 5.0 ]
|
||||
- [ 7675.0, 160, 6.7 ]
|
||||
- [ 7800.0, 160, 7.4 ]
|
||||
- [ 7920.0, 160, 7.0 ]
|
||||
- [ 8020.0, 140, 7.0 ]
|
||||
- [ 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.0 ]
|
||||
- [ 9845.0, 150, 7.3 ]
|
||||
- [ 10005.0, 160, 7.3 ]
|
||||
- [ 10600.0, 160, 6.0 ]
|
||||
- [ 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.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.0 ]
|
||||
- [ 18210.0, 140, 3.0 ]
|
||||
- [ 18300.0, 140, 4.6 ]
|
||||
- [ 18680.0, 140, 3.2 ]
|
||||
- [ 18761.0, 150, 3.2 ]
|
||||
- [ 19047.0, 150, 5.1 ]
|
||||
- [ 19305.0, 150, 3.0 ]
|
||||
- [ 19406.0, 160, 3.0 ]
|
||||
- [ 19414.0, 160, -0.3 ]
|
||||
- [ 19900.0, 160, 3.0 ]
|
||||
- [ 20150.0, 160, 1.8 ]
|
||||
- [ 20470.0, 160, -4.0 ]
|
||||
- [ 20940.0, 160, -3.6 ]
|
||||
- [ 21150.0, 160, -1.5 ]
|
||||
- [ 21390.0, 160, 0.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.0 ]
|
||||
- [ 24918.0, 160, 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.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.0 ]
|
||||
- [ 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.0 ]
|
||||
- [ 36700.0, 160, 3.9 ]
|
||||
- [ 36938.0, 160, 0.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.0 ]
|
||||
- [ 38406.0, 150, -7.0 ]
|
||||
- [ 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.0 ]
|
||||
- [ 44708.0, 160, -7.2 ]
|
||||
- [ 45477.0, 160, -7.8 ]
|
||||
- [ 45890.0, 160, -1.0 ]
|
||||
- [ 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.0 ]
|
||||
- [ 55918.0, 100, 0.0 ]
|
||||
- [ 56433.0, 150, 0.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.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.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.0 ]
|
||||
- [ 65690.0, 150, 1.8 ]
|
||||
- [ 65878.0, 150, 2.5 ]
|
||||
- [ 66266.0, 150, -1.0 ]
|
||||
- [ 66339.0, 150, 6.3 ]
|
||||
- [ 66448.0, 160, 6.3 ]
|
||||
- [ 66587.0, 160, 0.0 ]
|
||||
- [ 66856.0, 160, 3.2 ]
|
||||
- [ 67480.0, 160, 3.6 ]
|
||||
- [ 67697.0, 160, 2.2 ]
|
||||
- [ 67800.0, 160, 6.0 ]
|
||||
- [ 67851.0, 130, 6.0 ]
|
||||
- [ 68027.0, 130, 2.7 ]
|
||||
- [ 68172.0, 130, 0.6 ]
|
||||
- [ 68328.0, 130, 2.5 ]
|
||||
- [ 68357.0, 130, 0.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.0 ]
|
||||
- [ 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.0 ]
|
||||
- [ 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.0 ]
|
||||
- [ 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.0 ]
|
||||
- [ 77331.0, 80, -1.6 ]
|
||||
- [ 77379.0, 90, -1.6 ]
|
||||
- [ 77425.0, 110, -1.6 ]
|
||||
- [ 77455.0, 110, -4.9 ]
|
||||
- [ 77498.0, 110, 0.0 ]
|
||||
- [ 77505.0, 160, 0.0 ]
|
||||
- [ 77555.0, 160, -5.6 ]
|
||||
- [ 77662.0, 160, 0.0 ]
|
||||
- [ 78085.0, 160, -4.0 ]
|
||||
- [ 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.0 ]
|
||||
- [ 82408.0, 110, 4.8 ]
|
||||
- [ 82790.0, 110, 5.9 ]
|
||||
- [ 83137.0, 120, 5.9 ]
|
||||
- [ 83300.0, 120, 0.0 ]
|
||||
- [ 83519.0, 150, 0.0 ]
|
||||
- [ 83597.0, 150, -7.8 ]
|
||||
- [ 83827.0, 150, -8.1 ]
|
||||
- [ 84150.0, 150, -7.2 ]
|
||||
- [ 84391.0, 150, 0.0 ]
|
||||
- [ 84966.0, 150, -4.0 ]
|
||||
- [ 85529.0, 130, -2.3 ]
|
||||
- [ 85589.0, 130, -4.0 ]
|
||||
- [ 86081.0, 130, 0.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.0 ]
|
||||
- [ 90700.0, 160, -7.3 ]
|
||||
- [ 92000.0, 160, -7.9 ]
|
||||
- [ 92166.0, 160, -4.0 ]
|
||||
- [ 92460.0, 160, -5.4 ]
|
||||
- [ 93330.0, 160, 0.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.0 ]
|
||||
- [ 97858.0, 120, 0.0 ]
|
||||
- [ 98224.0, 120, -1.5 ]
|
||||
- [ 98264.0, 120, 0.0 ]
|
||||
- [ 98577.0, 120, 7.5 ]
|
||||
- [ 98738.0, 120, 0.0 ]
|
||||
- [ 99055.0, 130, 0.0 ]
|
||||
- [ 99427.0, 130, -2.0 ]
|
||||
- [ 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,0 +1,29 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
schema: https://railtoolkit.org/schema/running-path.json
|
||||
schema_version: "2022.05"
|
||||
paths:
|
||||
- name: "10 km, different gradient, 160 km/h"
|
||||
id: slope
|
||||
UUID: ffd243a9-0223-4210-8c7d-e6c90fde70d3
|
||||
points_of_interest:
|
||||
# [ station in m, name, front or rear ]
|
||||
- [ 850.00, view_point_1, front ]
|
||||
- [ 1000.00, distant_signal_1, front ]
|
||||
- [ 2000.00, main_signal_1, front ]
|
||||
- [ 9000.00, main_signal_3, front ]
|
||||
- [ 9050.00, clearing_point_1, rear ]
|
||||
characteristic_sections:
|
||||
# [ station in m, speed limit in km/h, resistance in ‰ ]
|
||||
- [ 0.0, 160, 0.00 ]
|
||||
- [ 1000.0, 160, 1.00 ]
|
||||
- [ 2000.0, 160, 2.00 ]
|
||||
- [ 3000.0, 160, 5.00 ]
|
||||
- [ 4000.0, 160, -3.00 ]
|
||||
- [ 5000.0, 160, 5.00 ]
|
||||
- [ 6000.0, 160, -10.00 ]
|
||||
- [ 7000.0, 160, 15.00 ]
|
||||
- [ 8000.0, 160, -10.00 ]
|
||||
- [ 8500.0, 160, 20.00 ]
|
||||
- [ 9000.0, 160, 0.00 ]
|
||||
- [ 10000.0, 160, 0.00 ]
|
|
@ -0,0 +1,29 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
schema: https://railtoolkit.org/schema/running-path.json
|
||||
schema_version: "2022.05"
|
||||
paths:
|
||||
- name: "10 km, no gradient, different speed limits"
|
||||
id: speed
|
||||
UUID: 401b8ce7-fa75-4576-8a4a-43be2eb55e50
|
||||
points_of_interest:
|
||||
# [ station in m, name, front or rear ]
|
||||
- [ 999.00, point_1, front ]
|
||||
- [ 2000.00, point_2, front ]
|
||||
- [ 3333.30, point_3, rear ]
|
||||
- [ 5000.00, point_4, front ]
|
||||
- [ 7777.00, point_5, front ]
|
||||
- [ 9000.00, point_6, front ]
|
||||
- [ 9500.95, point_7, front ]
|
||||
characteristic_sections:
|
||||
# [ station in m, speed limit in km/h, resistance in ‰ ]
|
||||
- [ 0.0, 160, 0.00 ]
|
||||
- [ 3000.0, 60, 0.00 ]
|
||||
- [ 4000.0, 160, 0.00 ]
|
||||
- [ 5000.0, 60, 0.00 ]
|
||||
- [ 6000.0, 160, 0.00 ]
|
||||
- [ 6500.0, 60, 0.00 ]
|
||||
- [ 6700.0, 65, 0.00 ]
|
||||
- [ 6800.0, 70, 0.00 ]
|
||||
- [ 7000.0, 120, 0.00 ]
|
||||
- [ 10000.0, 160, 0.00 ]
|
|
@ -0,0 +1,4 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
settings:
|
||||
outputDetail: "driving_course" # single value "running_time", array of "points_of_interest",complete array "driving_course", or dict() "everything"
|
|
@ -0,0 +1,4 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
settings:
|
||||
outputDetail: "everything" # single value "running_time", array of "points_of_interest",complete array "driving_course", or dict() "everything"
|
|
@ -0,0 +1,4 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
settings:
|
||||
outputDetail: "points_of_interest" # single value "running_time", array of "points_of_interest",complete array "driving_course", or dict() "everything"
|
|
@ -0,0 +1,4 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
settings:
|
||||
massModel: "homogeneous_strip" # type of train model used: "mass_point" or "homogeneous_strip"
|
|
@ -0,0 +1,4 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
settings:
|
||||
stepVariable: "time" # variable of the linear multistep method: "distance", "time" or "velocity"
|
|
@ -0,0 +1,5 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
settings:
|
||||
stepVariable: "time" # variable of the linear multistep method: "distance", "time" or "velocity"
|
||||
massModel: "homogeneous_strip" # type of train model used: "mass_point" or "homogeneous_strip"
|
|
@ -0,0 +1,5 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
settings:
|
||||
stepVariable: "velocity" # variable of the linear multistep method: "distance", "time" or "velocity"
|
||||
stepSize: 0.1 # step size, unit depends on stepVariable - position in meter, time in seconds and velocity in meter/second
|
|
@ -0,0 +1,123 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
schema: https://railtoolkit.org/schema/rolling-stock.json
|
||||
schema_version: "2022.05"
|
||||
trains:
|
||||
- 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)
|
||||
id: Fr100
|
||||
formation: [DB_V90,Facs124,Facs124,Facs124,Facs124,Facs124,Facs124,Facs124,Facs124,Facs124,Facs124]
|
||||
|
||||
vehicles:
|
||||
- name: "Facs 124" # source: https://dybas.de/dybas/gw/gw_f_1/g124.html
|
||||
id: Facs124
|
||||
UUID: 30abe88d-5be7-4c9c-b6a2-61c6b0e9f9bc
|
||||
picture: https://dybas.de/dybas/gw/gw_f_1/image/124_0042.jpg
|
||||
vehicle_type: freight # "freight", "passenger", "traction unit" or "multiple unit"
|
||||
|
||||
length: 19.04 # source: https://dybas.de/dybas/gw/gw_f_1/g124.html
|
||||
mass: 25.00 # source: https://dybas.de/dybas/gw/gw_f_1/g124.html
|
||||
load_limit: 59.0 # source: https://dybas.de/dybas/gw/gw_f_1/g124.html
|
||||
speed_limit: 100 # source: https://dybas.de/dybas/gw/gw_f_1/g124.html
|
||||
|
||||
rotation_mass: 1.03 # source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 13 for "Güterwagenzug beladen" -> 1.03 to 1.04)
|
||||
base_resistance: 1.4 # source: "Railway Timetabling & Operations" by Hansen, et al., 2014, p. 71 for "roller bearings")
|
||||
air_resistance: 3.9 # source: "Railway Timetabling & Operations" by Hansen, et al., 2014, p. 71 for "full train loads of coal or ore" modified for the used formula
|
||||
|
||||
- name: "DB V90" # source: https://de.wikipedia.org/wiki/DB-Baureihe_V_90
|
||||
id: DB_V90
|
||||
UUID: 48b99596-98b2-40c8-b31a-3f9266013803
|
||||
picture: https://commons.wikimedia.org/wiki/File:DB_294_-_594_side_view.jpg
|
||||
vehicle_type: traction unit # "freight", "passenger", "traction unit" or "multiple unit"
|
||||
power_type: diesel # "diesel", "electric", or "steam"
|
||||
|
||||
length: 14.32 # source: https://de.wikipedia.org/wiki/DB-Baureihe_V_90
|
||||
mass: 80 # source: https://de.wikipedia.org/wiki/DB-Baureihe_V_90
|
||||
mass_traction: 80 # in t # mass on driving axles of the traction unit
|
||||
speed_limit: 80 # in km/h
|
||||
|
||||
rotation_mass: 1.09 # source: "Railway Timetabling & Operations" by Hansen, et al., 2014, p. 71 for the traction unit
|
||||
base_resistance: 2.2 # source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 151 for "4-achsige Diesellokomot." -> 2.2 ‰ to 3.5 ‰
|
||||
air_resistance: 0.01 # source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 151 for "MittelfUhrerstand" -> 5000 N to 10000 N; modified for the used formula
|
||||
|
||||
tractive_effort:
|
||||
- [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,153 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
schema: https://railtoolkit.org/schema/rolling-stock.json
|
||||
schema_version: "2022.05"
|
||||
trains:
|
||||
- name: Regional Train
|
||||
id: RB50-1
|
||||
formation: [DB_BR_642]
|
||||
|
||||
vehicles:
|
||||
- name: Siemens Desiro Classic # source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic
|
||||
id: DB_BR_642
|
||||
UUID: c915c80d-c63d-490b-879f-c481e4b62b55
|
||||
picture: https://commons.wikimedia.org/wiki/File:Liesel_28-11-10_642_055-8_im_Bahnhof_Scharfenstein.JPG
|
||||
power_type: diesel # source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic
|
||||
vehicle_type: multiple unit # source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic
|
||||
|
||||
length: 41.7 # source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic
|
||||
mass: 68.0 # source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic
|
||||
load_limit: 20.0 # source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic
|
||||
mass_traction: 45.333 # proportionately to the number of axles: 4 to 2, see: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic)
|
||||
speed_limit: 120 # source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic
|
||||
a_braking: -0.4253 #
|
||||
|
||||
# coefficients for the vehicle resistance
|
||||
rotation_mass: 1.08 # source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 13 for "Zug, überschlägliche Berechnung"
|
||||
base_resistance: 3.0 # source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 151 for "f_WL0" -> 2.5 ‰ to 3.5 ‰
|
||||
rolling_resistance: 1.4 # source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 151 for "f_WW0" -> 1.2 ‰ to 1.6 ‰
|
||||
air_resistance: 0.0039 # 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 + 400 N
|
||||
|
||||
# tractive effort as pairs of speed and tractive effort
|
||||
tractive_effort:
|
||||
- [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,220 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
schema: https://railtoolkit.org/schema/rolling-stock.json
|
||||
schema_version: "2022.05"
|
||||
trains:
|
||||
- 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))
|
||||
id: IC1011
|
||||
formation: [Bombardier_Traxx_2_P160,DABpza68,DABpza68,DABpza68,DABpza68,DABpza668]
|
||||
|
||||
vehicles:
|
||||
- name: "DBpbzfa 668.2" # source: https://de.wikipedia.org/wiki/Bombardier_Twindexx_Vario
|
||||
id: DABpza668
|
||||
UUID: a186ea2c-daeb-429b-8254-89e0d6700519
|
||||
picture: https://commons.wikimedia.org/wiki/File:Bombardier_IC_Doppelstocksteuerwagen_Innotrans_2014.JPG
|
||||
vehicle_type: passenger # "freight", "passenger", "traction unit" or "multiple unit"
|
||||
|
||||
length: 27.27 # source: https://de.wikipedia.org/wiki/Bombardier_Twindexx_Vario
|
||||
mass: 58.00 # source: https://de.wikipedia.org/wiki/Bombardier_Twindexx_Vario
|
||||
load_limit: 20.0 # source: https://de.wikipedia.org/wiki/Bombardier_Twindexx_Vario
|
||||
speed_limit: 160 # source: https://de.wikipedia.org/wiki/Bombardier_Twindexx_Vario
|
||||
|
||||
rotation_mass: 1.06 # source: "Railway Timetabling & Operations" by Hansen, et al., 2014, p. 71 for freight wagons
|
||||
base_resistance: 2.0 # source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 153 for "Doppelstockgliederzüge"
|
||||
rolling_resistance: 0.715 # source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 153 for "Doppelstockgliederzüge"
|
||||
air_resistance: 3.64 # source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 153 for "Doppelstockgliederzüge"
|
||||
|
||||
- name: "DApza 687.2 and DBpza 682.2" # source: https://de.wikipedia.org/wiki/Bombardier_Twindexx_Vario
|
||||
id: DABpza68
|
||||
UUID: 45e83b27-7952-4f34-ad8d-1affcacfe6f2
|
||||
picture: https://commons.wikimedia.org/wiki/File:D-DB_50_80_26-81_456-8_DBpza_682.2_Bremen_Hbf_14.11.2015.jpg
|
||||
vehicle_type: passenger # "freight", "passenger", "traction unit" or "multiple unit"
|
||||
|
||||
length: 26.8 # source: https://de.wikipedia.org/wiki/Bombardier_Twindexx_Vario
|
||||
mass: 50.00 # source: https://de.wikipedia.org/wiki/Bombardier_Twindexx_Vario
|
||||
load_limit: 20.0 # source: https://de.wikipedia.org/wiki/Bombardier_Twindexx_Vario
|
||||
speed_limit: 160 # source: https://de.wikipedia.org/wiki/Bombardier_Twindexx_Vario
|
||||
|
||||
rotation_mass: 1.06 # source: "Railway Timetabling & Operations" by Hansen, et al., 2014, p. 71 for freight wagons
|
||||
base_resistance: 2.0 # source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 153 for "Doppelstockgliederzüge"
|
||||
rolling_resistance: 0.715 # source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 153 for "Doppelstockgliederzüge"
|
||||
air_resistance: 3.64 # source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 153 for "Doppelstockgliederzüge"
|
||||
|
||||
- name: "Bombardier Traxx 2 (P160)" # source: https://en.wikipedia.org/wiki/Bombardier_TRAXX#TRAXX_P160_AC2
|
||||
id: Bombardier_Traxx_2_P160
|
||||
UUID: bc62a03e-9ec9-41f2-913c-6b315e86cc61
|
||||
picture: https://commons.wikimedia.org/wiki/File:146_560-8_(Flickr_26502799445).jpg
|
||||
vehicle_type: traction unit # "freight", "passenger", "traction unit" or "multiple unit"
|
||||
power_type: electric # "diesel", "electric", or "steam"
|
||||
|
||||
length: 18.9 # source: https://de.wikipedia.org/wiki/Bombardier_Traxx#P160_AC2
|
||||
mass: 85 # source: https://de.wikipedia.org/wiki/Bombardier_Traxx#P160_AC2
|
||||
mass_traction: 85 # in t # mass on driving axles of the traction unit
|
||||
speed_limit: 160 # in km/h
|
||||
|
||||
rotation_mass: 1.09 # source: "Railway Timetabling & Operations" by Hansen, et al., 2014, p. 71 for the traction unit
|
||||
base_resistance: 2.5 # source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 151 for "4-achsige Diesellokomot." -> 2.2 ‰ to 3.5 ‰
|
||||
air_resistance: 0.006 # source: "Fahrdynamik des Schienenverkehrs" by Wende, 2003, p. 151 for "4-achsig, eckige Kopfform" with "Stromabnehmer" -> 5000 N to 6000 N; modified for the used formula
|
||||
|
||||
tractive_effort:
|
||||
- [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]
|
100
test/runtests.jl
100
test/runtests.jl
|
@ -1,40 +1,88 @@
|
|||
#!/usr/bin/env julia
|
||||
# -*- coding: UTF-8 -*-
|
||||
# __julia-version__ = 1.7.0
|
||||
# __author__ = "Max Kannenberg"
|
||||
# __author__ = "Max Kannenberg, Martin Scheidt"
|
||||
# __copyright__ = "2021"
|
||||
# __license__ = "ISC"
|
||||
|
||||
using TrainRun, Test
|
||||
using TrainRuns, Test
|
||||
|
||||
allPaths=[]
|
||||
push!(allPaths, importYamlFile(:path, "data/paths/path_1_10km_nConst_vConst.yaml"))
|
||||
push!(allPaths, importYamlFile(:path, "data/paths/path_2_10km_nVar_vConst.yaml"))
|
||||
push!(allPaths, importYamlFile(:path, "data/paths/path_3_10km_nConst_vVar.yaml"))
|
||||
push!(allPaths, importYamlFile(:path, "data/paths/path_4_real_Germany_EastSaxony_DG-DN.yaml"))
|
||||
trains = Dict()
|
||||
paths = Dict()
|
||||
settings = Dict()
|
||||
|
||||
@testset "load data" begin
|
||||
|
||||
allSettings=[]
|
||||
push!(allSettings, importYamlFile(:settings, "data/settings.yaml"))
|
||||
println("testing load train data")
|
||||
push!(trains, :freight => @time Train("data/trains/freight.yaml"))
|
||||
push!(trains, :local => @time Train("data/trains/local.yaml"))
|
||||
push!(trains, :longdistance => @time Train("data/trains/longdistance.yaml"))
|
||||
|
||||
allTrains=[]
|
||||
push!(allTrains, importYamlFile(:train, "data/trains/train_freight_V90withOreConsist.yaml"))
|
||||
push!(allTrains, importYamlFile(:train, "data/trains/train_passenger_SiemensDesiroClassic.yaml"))
|
||||
push!(allTrains, importYamlFile(:train, "data/trains/train_passenger_IC2.yaml"))
|
||||
println("testing load path data")
|
||||
push!(paths, :const => @time Path("data/paths/const.yaml"))
|
||||
push!(paths, :slope => @time Path("data/paths/slope.yaml"))
|
||||
push!(paths, :speed => @time Path("data/paths/speed.yaml"))
|
||||
push!(paths, :realworld => @time Path("data/paths/realworld.yaml"))
|
||||
|
||||
for path in allPaths
|
||||
for train in allTrains
|
||||
for settings in allSettings
|
||||
testDict=trainRun(train, path, settings)
|
||||
exportToCsv(testDict)
|
||||
sleep(2)
|
||||
println("testing load settings data")
|
||||
push!(settings, "default" => @time Settings())
|
||||
push!(settings, "poi" => @time Settings("data/settings/points_of_interest.yaml"))
|
||||
push!(settings, "drivingcourse" => @time Settings("data/settings/driving_course.yaml"))
|
||||
push!(settings, "everything" => @time Settings("data/settings/everything.yaml"))
|
||||
push!(settings, "strip" => @time Settings("data/settings/strip.yaml"))
|
||||
push!(settings, "time" => @time Settings("data/settings/time.yaml"))
|
||||
push!(settings, "timestrip" => @time Settings("data/settings/time_strip.yaml"))
|
||||
push!(settings, "velocity" => @time Settings("data/settings/velocity.yaml"))
|
||||
|
||||
@test typeof(first(paths)[2]) == Path
|
||||
@test typeof(first(settings)[2]) == Settings
|
||||
|
||||
# TODO:
|
||||
# compare result to test data set
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
println("test finished")
|
||||
# TODO:
|
||||
# print test results
|
||||
println("====================")
|
||||
|
||||
tests = Base.Iterators.product(trains,paths)
|
||||
|
||||
## routine to generate the anticipated Dict()
|
||||
# anticipated = Dict()
|
||||
# for test in tests
|
||||
# println(test[1][1],"-",test[2][1])
|
||||
# result = @time trainrun(test[1][2],test[2][2])
|
||||
# push!(anticipated, Symbol(String(test[1][1]) * "_" * String(test[2][1])) => result )
|
||||
# end
|
||||
|
||||
anticipated = Dict(
|
||||
:default => Dict(
|
||||
:longdistance_speed => 499.96109564970516,
|
||||
:freight_slope => 831.4768274141168,
|
||||
:local_slope => 396.99313307033276,
|
||||
:longdistance_const => 328.83479381353095,
|
||||
:freight_realworld => 8971.50124080998,
|
||||
:longdistance_slope => 329.22915822053164,
|
||||
:freight_const => 727.7969403041934,
|
||||
:longdistance_realworld => 2900.1198723158523,
|
||||
:local_speed => 524.3948201513945,
|
||||
:local_realworld => 3443.917823618831,
|
||||
:freight_speed => 733.2610572579886,
|
||||
:local_const => 392.7234008268302
|
||||
)
|
||||
)
|
||||
|
||||
@testset "function trainrun()" begin
|
||||
|
||||
@testset "Default settings" begin
|
||||
|
||||
for test in tests
|
||||
test_name = String(test[1][1]) * "_" * String(test[2][1])
|
||||
println("testing $test_name")
|
||||
@time result = trainrun(test[1][2],test[2][2])
|
||||
expected = anticipated[:default][Symbol(test_name)]
|
||||
# compare result to test data set
|
||||
@test isapprox(result, expected, rtol=0.01)
|
||||
println("--------------------")
|
||||
end
|
||||
|
||||
end
|
||||
println("====================")
|
||||
|
||||
end
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
#!/usr/bin/env julia
|
||||
# -*- coding: UTF-8 -*-
|
||||
# __julia-version__ = 1.7.0
|
||||
# __author__ = "Martin Scheidt"
|
||||
# __copyright__ = "2021"
|
||||
# __license__ = "ISC"
|
||||
|
||||
include("../src/types.jl")
|
||||
include("../src/Validate.jl")
|
||||
|
||||
using .Input
|
||||
using YAML, Test
|
||||
|
||||
@enum trainType passenger=1 freight=2 motorCoachTrain=3
|
||||
|
||||
@test Input.getEnum("passenger", trainType) == passenger::trainType
|
||||
@test Input.getEnum("freight", trainType) == freight::trainType
|
||||
@test Input.getEnum("motorCoachTrain", trainType) == motorCoachTrain::trainType
|
||||
|
||||
data = YAML.load(open("data/trains/train_passenger_IC2.yaml"))
|
||||
@test Input.getEnum(data["train"]["trainType"], trainType) == passenger::trainType
|
||||
|
||||
data = YAML.load(open("data/trains/train_freight_V90withOreConsist.yaml"))
|
||||
@test Input.getEnum(data["train"]["trainType"], trainType) == freight::trainType
|
Loading…
Reference in New Issue