diff --git a/.gitignore b/.gitignore index f124cea..07955e1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,34 @@ +# Created by https://www.toptal.com/developers/gitignore/api/macos,linux,windows,node,tex +# Edit at https://www.toptal.com/developers/gitignore?templates=macos,linux,windows,node,tex + ### Linux ### *~ + # temporary files which can be created if a process still has a handle open of a deleted file .fuse_hidden* + # KDE directory preferences .directory + # Linux trash folder which might appear on any partition or disk .Trash-* + # .nfs files are created when an open file is removed but is still being accessed .nfs* -### OSX ### +### macOS ### # General .DS_Store .AppleDouble .LSOverride + # Icon must end with two \r Icon + + # Thumbnails ._* + # Files that might appear in the root of a volume .DocumentRevisions-V100 .fseventsd @@ -26,6 +37,7 @@ Icon .Trashes .VolumeIcon.icns .com.apple.timemachine.donotpresent + # Directories potentially created on remote AFP share .AppleDB .AppleDesktop @@ -33,25 +45,484 @@ Network Trash Folder Temporary Items .apdisk +### macOS Patch ### +# iCloud generated files +*.icloud + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +### Node Patch ### +# Serverless Webpack directories +.webpack/ + +# Optional stylelint cache + +# SvelteKit build / generate output +.svelte-kit + +### TeX ### +.tex +## Core latex/pdflatex auxiliary files: +*.aux +*.lof +*.lot +*.fls +*.out +*.toc +*.fmt +*.fot +*.cb +*.cb2 +.*.lb + +## Intermediate documents: +*.dvi +*.xdv +*-converted-to.* +# these rules might exclude image files for figures etc. +# *.ps +# *.eps +# *.pdf + +## Generated if empty string is given at "Please type another file name for output:" +.pdf + +## Bibliography auxiliary files (bibtex/biblatex/biber): +*.bbl +*.bcf +*.blg +*-blx.aux +*-blx.bib +*.run.xml + +## Build tool auxiliary files: +*.fdb_latexmk +*.synctex +*.synctex(busy) +*.synctex.gz +*.synctex.gz(busy) +*.pdfsync + +## Build tool directories for auxiliary files +# latexrun +latex.out/ + +## Auxiliary and intermediate files from other packages: +# algorithms +*.alg +*.loa + +# achemso +acs-*.bib + +# amsthm +*.thm + +# beamer +*.nav +*.pre +*.snm +*.vrb + +# changes +*.soc + +# comment +*.cut + +# cprotect +*.cpt + +# elsarticle (documentclass of Elsevier journals) +*.spl + +# endnotes +*.ent + +# fixme +*.lox + +# feynmf/feynmp +*.mf +*.mp +*.t[1-9] +*.t[1-9][0-9] +*.tfm + +#(r)(e)ledmac/(r)(e)ledpar +*.end +*.?end +*.[1-9] +*.[1-9][0-9] +*.[1-9][0-9][0-9] +*.[1-9]R +*.[1-9][0-9]R +*.[1-9][0-9][0-9]R +*.eledsec[1-9] +*.eledsec[1-9]R +*.eledsec[1-9][0-9] +*.eledsec[1-9][0-9]R +*.eledsec[1-9][0-9][0-9] +*.eledsec[1-9][0-9][0-9]R + +# glossaries +*.acn +*.acr +*.glg +*.glo +*.gls +*.glsdefs +*.lzo +*.lzs +*.slg +*.slo +*.sls + +# uncomment this for glossaries-extra (will ignore makeindex's style files!) +# *.ist + +# gnuplot +*.gnuplot +*.table + +# gnuplottex +*-gnuplottex-* + +# gregoriotex +*.gaux +*.glog +*.gtex + +# htlatex +*.4ct +*.4tc +*.idv +*.lg +*.trc +*.xref + +# hyperref +*.brf + +# knitr +*-concordance.tex +# TODO Uncomment the next line if you use knitr and want to ignore its generated tikz files +# *.tikz +*-tikzDictionary + +# listings +*.lol + +# luatexja-ruby +*.ltjruby + +# makeidx +*.idx +*.ilg +*.ind + +# minitoc +*.maf +*.mlf +*.mlt +*.mtc[0-9]* +*.slf[0-9]* +*.slt[0-9]* +*.stc[0-9]* + +# minted +_minted* +*.pyg + +# morewrites +*.mw + +# newpax +*.newpax + +# nomencl +*.nlg +*.nlo +*.nls + +# pax +*.pax + +# pdfpcnotes +*.pdfpc + +# sagetex +*.sagetex.sage +*.sagetex.py +*.sagetex.scmd + +# scrwfile +*.wrt + +# svg +svg-inkscape/ + +# sympy +*.sout +*.sympy +sympy-plots-for-*.tex/ + +# pdfcomment +*.upa +*.upb + +# pythontex +*.pytxcode +pythontex-files-*/ + +# tcolorbox +*.listing + +# thmtools +*.loe + +# TikZ & PGF +*.dpth +*.md5 +*.auxlock + +# titletoc +*.ptc + +# todonotes +*.tdo + +# vhistory +*.hst +*.ver + +# easy-todo +*.lod + +# xcolor +*.xcp + +# xmpincl +*.xmpi + +# xindy +*.xdy + +# xypic precompiled matrices and outlines +*.xyc +*.xyd + +# endfloat +*.ttt +*.fff + +# Latexian +TSWLatexianTemp* + +## Editors: +# WinEdt +*.bak +*.sav + +# Texpad +.texpadtmp + +# LyX +*.lyx~ + +# Kile +*.backup + +# gummi +.*.swp + +# KBibTeX +*~[0-9]* + +# TeXnicCenter +*.tps + +# auto folder when using emacs and auctex +./auto/* +*.el + +# expex forward references with \gathertags +*-tags.tex + +# standalone packages +*.sta + +# Makeindex log files +*.lpz + +# xwatermark package +*.xwm + +# REVTeX puts footnotes in the bibliography by default, unless the nofootinbib +# option is specified. Footnotes are the stored in a file with suffix Notes.bib. +# Uncomment the next line to have this generated file ignored. +#*Notes.bib + +### TeX Patch ### +# LIPIcs / OASIcs +*.vtc + +# glossaries +*.glstex + ### Windows ### # Windows thumbnail cache files Thumbs.db Thumbs.db:encryptable ehthumbs.db ehthumbs_vista.db + # Dump file *.stackdump + # Folder config file [Dd]esktop.ini + # Recycle Bin used on file shares $RECYCLE.BIN/ + # Windows Installer files *.cab *.msi *.msix *.msm *.msp + # Windows shortcuts *.lnk -node_modules \ No newline at end of file +# End of https://www.toptal.com/developers/gitignore/api/macos,linux,windows,node,tex \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 5144056..7c147e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,17 +11,47 @@ Categories: Added, Changed, Deprecated, Removed, Fixed, and Security. ### Added * running path: * added `description` attribute (see Issue #5) + * added `track` to characteristic sections for grouping track sections + * added `groups` array to points_of_interest for categorizing points + * added comprehensive test suite with valid and invalid test cases + * added example file with block sections and signals +* rolling stock: + * added `description` attribute to trains and vehicles (see Issue #5) + * added `hydraulic` and `misc` to power_type options + * added `non-revenue` to vehicle_type options + * added complete schema for `simplified_characteristics` with required fields and constraints + * added `coasting` parameter to simplified characteristics + * added `emergency_deceleration` to simplified characteristics + * added `model_fidelity` attribute on different levels + * added comprehensive brake model configuration with multiple fidelity levels + * added detailed brake types: eddy_current_brake, electrodynamic_brake, and friction_brake + * added brake timing parameters: reaction_time, response_time, threshold_time + * added new train types: snow_removal, construction, emergency + * added comprehensive documentation for all attributes and model fidelity levels ### Changed * running path: * running path arrays now contain named attributes (see Issue #4) - * when using `characteristic_sections` only one optional attribute (`speed` or `resistance`) must be specified + * characteristic sections now require at least one of `speed`, `resistance`, or `track` attributes * measures for `points_of_interest` can now take three values: "front", "middle", and "rear" +* rolling stock: + * changed tractive_effort to require at least 3 unique pairs + * changed rotation_mass description to specify >= 1 + * changed train requirements to need either `formation` or `simplified_characteristics` + * changed `train_type` to include comprehensive list of train service types + * changed brake modeling to support multiple fidelity levels + * changed model_fidelity to be required at top level and component levels + * refined train_type categories into passenger, freight, and special groups + * improved documentation with detailed explanations of model fidelity rationale ### Removed * running path: * removed `name` attribute (see Issue #5) * removed `UUID` attribute (see Issue #5) +* rolling stock: + * removed `name` attribute from trains and vehicles (see Issue #5) + * removed `UUID` attribute from trains and vehicles (see Issue #5) + * removed `diesel` from power_type options ## Version [2022.05] @@ -34,15 +64,12 @@ Categories: Added, Changed, Deprecated, Removed, Fixed, and Security. * renamed `train` into `trains` and changed type to array (see Issue #2) * renamed `path` into `paths` and changed type to array (see Issue #2) - ## Version [2022.04] ### Added - * initial rolling-stock schema * initial running-path Schema - [Unreleased]: https://github.com/railtoolkit/schema/compare/2022.05...main [2022.05]: https://github.com/railtoolkit/schema/compare/2022.04...2022.05 [2022.04]: https://github.com/railtoolkit/schema/releases/tag/2022.04 \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9ab65c9..d7201e8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,20 +5,35 @@ 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 +## Pull Request Process -## Minor Changes and Fixes +### Minor Changes and Fixes -TODO: DESCRIPTION +For minor changes and fixes: +1. Ensure your code follows the existing style and conventions +2. Update the documentation if necessary +3. Add tests for any new functionality +4. Make sure all tests pass locally +5. Create a Pull Request with a clear description of the changes -## Breaking Changes +### Breaking Changes -TODO: DESCRIPTION +For breaking changes: +1. Open an issue first to discuss the proposed changes +2. Document all breaking changes clearly in your Pull Request +3. Update all relevant documentation +4. Add or update tests to cover the changes +5. Update the version number according to [Calendar Versioning](https://calver.org) +6. Provide migration instructions if applicable ## Roadmap - * include breaking model in rolling-stock schema - * fallback with constant acceleration and deceleration +Current development priorities: +* test braking model in rolling-stock schema +* improve braking model in rolling-stock schema +* add model for interlocking +* add model for topology +* add model for timetbling and blocking times ## Add yourself as a contributor diff --git a/LICENSE b/LICENSE index 5d6f1b4..d65d51d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ ISC License -Copyright (c) 2022, Martin Scheidt \ +Copyright (c) 2022 - 2025, Martin Scheidt (orcid.org/0000-0002-9384-8945) 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. diff --git a/README.md b/README.md index ec95285..7dca0ea 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# RailToolKit Schema +# RailToolKit/schema [![License: ISC][license-img]][license-url] [![DOI][zenodo-img]][zenodo-url] [![Build Status][ci-img]][ci-url] [![All Contributors][Contributors-img]][Contributors-url] @@ -6,49 +6,88 @@ ## About - This repo collects the descriptions of the structure and the validation constraints of tools in the railtoolkit in JSON schemas. It is, therefore, an alternative to [RailML](https://www.railml.org/). The JSON schemas enable the validation of YAML files in [TrainRun.jl](https://github.com/railtoolkit/TrainRun.jl.git) and [rolling-stock](https://github.com/railtoolkit/rolling-stock.git). +The RailToolkit/schema provides JSON schemas for railway operations data, offering a lightweight alternative to RailML. It focuses on two main aspects: + +1. Rolling Stock Schema + - Defines train and vehicle characteristics + - Supports both simplified and detailed modeling approaches + - Includes parameters like speed, mass, resistance, and tractive effort + +2. Running Path Schema + - Describes railway paths with speed limits and track resistance + - Supports points of interest (signals, platforms, etc.) + - Enables precise position-based path descriptions + +The schemas use standardized railway units and can be validated using standard JSON schema tools. They are designed to support railway simulation and planning tools while maintaining simplicity and ease of use. ## Prerequisite - You will need a validator to validate the schema against data. This package provides a helper script that uses the [Ajv JSON schema validator](https://ajv.js.org). - Ajv rquires to have [node](https://nodejs.org/) installed. +You will need a validator to validate the schema against data. This package provides a helper script that uses the [Ajv JSON schema validator](https://ajv.js.org). +Ajv requires to have [node](https://nodejs.org/) installed. - ```bash - $ node --version # test if node is installed - ``` +```bash +$ node --version # test if node is installed +``` ## Usage - You will need the schema and some data. The repo contains among others the rolling-stock schema and example data: - ```bash - $ git clone https://github.com/railtoolkit/schema.git && cd schema - ``` - - Install all project dependencies: - ```bash - $ npm install - ``` - - You can now validate if the data follows the schema: - ```bash - $ npm run validate:rolling-stock doc/rolling-stock.example.yaml - ``` - This will return: - ```bash - $ doc/rolling-stock.example.yaml valid - ``` - Or: - ```bash - $ npm run validate:running-path doc/running-path.example.yaml - ``` - This will return: - ```bash - $ doc/running-path.example.yaml valid - ``` +You will need the schema and some data. The repo contains among others the rolling-stock schema and example data: +```bash +$ git clone https://github.com/railtoolkit/schema.git && cd schema +``` + +Install all project dependencies: +```bash +$ npm install +``` + +You can validate if the data follows the schema: +```bash +$ npm run validate:rolling-stock doc/rolling-stock.example.yaml +$ npm run validate:running-path doc/running-path.example.yaml +``` + +## Testing + +The repository includes comprehensive test suites for both schemas: + +```bash +$ npm run test # Run all tests +$ npm run test:stock # Run rolling-stock tests only +$ npm run test:paths # Run running-path tests only +``` + +Each test suite includes: +- Example file validation +- Valid test cases +- Invalid test cases ## Documentation - see [Rolling-Stock.md](https://github.com/railtoolkit/schema/blob/main/doc/Rolling-Stock.md) and [Running-Path.md](https://github.com/railtoolkit/schema/blob/main/doc/Running-Path.md) for information about the used attributes. +### Sub schemas + +See +* [Rolling-Stock.md](doc/Rolling-Stock.md) and +* [Running-Path.md](doc/Running-Path.md) + +for information about the used attributes in the sub schemas. + +### Units + +The schema uses common railway units for all numerical values: + +| Quantity | Unit | Description | +|------------------|------|-------------| +| Speed | km/h | Kilometers per hour | +| Mass | t | Metric tons | +| Length | m | Meters | +| Time | s | Seconds | +| Force | kN | Kilonewton | +| Power | kW | Kilowatt | +| Acceleration | m/s² | Meters per second squared | +| Resistance | ‰ | Per mille (mm/m) | +| Unit-less | - | Dimensionless values | + ## Contributors @@ -64,13 +103,11 @@ - - -See [CONTRIBUTING.md](https://github.com/railtoolkit/schema/blob/main/CONTRIBUTING.md) file if you are interested to contribute. +See [CONTRIBUTING.md](CONTRIBUTING.md) file if you are interested to contribute. ------------ @@ -78,7 +115,7 @@ See [CONTRIBUTING.md](https://github.com/railtoolkit/schema/blob/main/CONTRIBUTI [![Open Source Initiative Approved License logo](https://149753425.v2.pressablecdn.com/wp-content/uploads/2009/06/OSIApproved_100X125.png "Open Source Initiative Approved License logo")](https://opensource.org) - Copyright (c) 2022, Martin Scheidt \ (ISC License) + Copyright (c) 2022 - 2025, Martin Scheidt (orcid.org/0000-0002-9384-8945) (ISC License) 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. diff --git a/doc/Rolling-Stock.md b/doc/Rolling-Stock.md index 75b2f9a..16e0cca 100644 --- a/doc/Rolling-Stock.md +++ b/doc/Rolling-Stock.md @@ -6,46 +6,208 @@ ## Preamble -| Attributes | Necessity | Description | -| -------------------- | ------------ | ----------- | -| `schema` | required | Identifier of the JSON schema. | -| `schema_version` | required | Version of the JSON schema. | -| `trains` | optional[^1] | An array of [trains](#Attributes-in-trains). | -| `vehicles` | optional[^1] | An array of [vehicles](#Attributes-in-vehicles). | +| Attributes | Data Type | Necessity | Description | +| -------------------- | ------------ | ------------ | ----------- | +| `schema` | string | required | Identifier of the JSON schema. | +| `schema_version` | string | required | Version of the JSON schema (current version `2024.07`). | +| `model_fidelity` | string | required | Level of detail for train dynamics modeling. Values: `simplified`, `detailed`. | +| `trains` | array | optional[^1] | A list of [trains](#Attributes-in-trains). | +| `vehicles` | array | optional[^1] | A list of [vehicles](#Attributes-in-vehicles). | [^1]: At least one of attributes `trains` or `vehicles` must be present. +### Model Fidelity Rationale + +The `model_fidelity` attribute specifies the level of detail for train dynamics modeling: + +- `simplified`: Uses basic acceleration and deceleration parameters. Suitable for high-level planning and simple simulations where detailed dynamics are not required. Parameters are defined in `trains.simplified_characteristics`. + +- `detailed`: Uses detailed vehicle parameters including physical properties and effort tables. Appropriate for precise simulations where accurate force calculations are needed. Parameters are defined in `vehicles`. + +A file may contain data for both fidelity levels, but only values from the selected level will be used in calculations. The attribute `model_fidelity` acts as a switch to select which level of detail to use, ensuring that the appropriate parameters are applied based on the chosen fidelity level. + +The `model_fidelity` attribute is not only used at the top level but also plays a crucial role in lower-level objects such as `resistance`, `traction`, and `brakes`. This allows for varying levels of detail in the modeling of these components, ensuring that the appropriate parameters are applied based on the selected fidelity level. + ## Attributes in "trains" -All attributes for a train are collected under the array `trains: -` in alphabetical order: +All attributes for a train are collected under `trains: -` in alphabetical order: + +| Attributes | Data Type | Necessity | Description | +| ---------------------------- | ------------ | ------------ | ----------- | +| `id` | string | required | Identifier of the train. | +| `description` | string | optional | Description of the train. | +| `train_type` | string | optional | Type of train service. See [Train Types](#train-types) below. | +| `simplified_characteristics` | object | optional[^2] | Basic motion parameters when using `simplified_characteristics` model fidelity. See [Simplified Characteristics](#simplified-characteristics) below. | +| `formation` | array | optional[^2] | A Collection of vehicles that form the train referenced by vehicle `id`. Front and rear end of the train are defined by the first and last vehicle in the array. | +| `loading_factor` | array | optional | Ratio (between 0 and 1) of the actual load to the maximum load capacity of the train. Using the `load_limit` attribute of the vehicles in the `formation` array. | + +[^2]: At least one of attributes `formation` or `simplified_characteristics` must be present, depending on the selected `model_fidelity`. + +### Train Types + +The `train_type` attribute categorizes trains into three main groups: + +#### 1. Passenger Trains +- `long_distance` - Fast, long-distance trains with few stops (e.g., ICE, TGV) +- `regional` - Medium speed trains for mid-range distances (e.g., RE, RB) +- `suburban` - Short-distance trains with frequent stops (e.g., S-Bahn) +- `metro` - Urban trains with high frequency (e.g., Metro, Trams) -| Attributes | Necessity | Description | -| -------------------- | --------- | ----------- | -| `id` | required | Identifier of the train. | -| `name` | required | Name of the train. | -| `UUID` | optional | The unique identifier of the train. | -| `formation` | required | A Collection of vehicles that form the train referenced by vehicle `id`. | +#### 2. Freight Trains +- `intermodal` - Container transport trains with medium speed +- `heavy_freight` - High axle load trains for bulk cargo (e.g., coal, ore) +- `block_freight` - Single cargo type trains with direct routes + +#### 3. Special Trains +- `shunting` - Low speed trains for wagon formation +- `maintenance` - Infrastructure maintenance trains +- `construction` - Construction site supply trains +- `emergency` - Fire, rescue, and emergency response trains +- `snow_removal` - Seasonal service trains + +### Simplified Characteristics + +When using `model_fidelity: "simplified"`, the following attributes define the basic motion parameters of a train: + +| Attributes | Data Type | Necessity | Description | +| ---------------------------- | ------------ | --------- | ----------- | +| `speed_limit` | number | required | Maximum permitted speed (km/h) | +| `length` | number | required | Total length of the train (m) | +| `acceleration` | number | required | Constant acceleration rate (m/s²) | +| `deceleration` | number | required | Constant service braking rate (m/s²) (negative value) | +| `emergency_deceleration` | number | optional | Emergency braking rate (m/s²) (negative value). If not specified, defaults to the value of `deceleration` | +| `coasting` | number | optional | Deceleration rate when coasting (m/s²) (negative value). Defaults to 0 if not specified | +These simplified characteristics are used when detailed vehicle dynamics are not required or available. They provide a basic but efficient way to model train movement for high-level planning and simple simulations. ## Attributes in "vehicles" -All attributes for a vehicle are collected under the array `vehicles: -` in alphabetical order: - -| Attributes | Necessity | Description | -| -------------------- | --------- | ----------- | -| `air_resistance` | optional | Coefficient for air resistance in permil. | -| `base_resistance` | optional | Coefficient for basic resistance in permil. | -| `id` | required | Identifier of the vehicle. | -| `length` | required | The length of the vehicle in meter. | -| `load_limit` | optional | The maximum permitted load of the vehicle in metric ton. | -| `mass_traction` | optional | The mass on the powered axles of the vehicle in metric ton. | -| `mass` | required | The empty mass (dead weight) of the vehicle in metric ton. | -| `name` | required | Name of the vehicle. | -| `picture` | optional | A [URI](https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) with a picture for humans. | -| `power_type` | optional | Type of propulsion; values: `diesel`, `electric`, or `steam`. | -| `rolling_resistance` | optional | Coefficient for resistance of rolling axles in permil. | -| `rotation_mass` | optional | Factor for rotating mass; larger then 1. | -| `speed_limit` | optional | Maximum permitted speed in kilometers per hour. | -| `tractive_effort` | optional | Tractive effort as pairs of speed in kilometers per hour and tractive force in newton. | -| `UUID` | optional | The unique identifier for a vehicle. | -| `vehicle_type` | required | Type of vehicle; values: `traction unit`, `freight`, `passenger`, or `multiple unit`. | +All attributes for a vehicle are collected under `vehicles: -` in alphabetical order: + +| Attributes | Data Type | Necessity | Description | +| -------------------- | ------------ | --------- | ----------- | +| `id` | string | required | Identifier of the vehicle | +| `vehicle_type` | string | required | Type of vehicle; values: `traction_unit`, `freight`, `passenger`, `multiple_unit`, or `non-revenue` | +| `mass` | number | required | Empty mass (dead weight) (t)| +| `length` | number | required | Length of the vehicle (m) | +| `load_limit` | number | optional | Maximum permitted load (t), Defaults to 0 if not specified | +| `speed_limit` | number | optional | Maximum permitted speed (km/h) | +| `description` | string | optional | Description of the vehicle | +| `power_type` | string | optional | Type of propulsion; values: `hydraulic`, `electric`, `steam`, or `misc` | +| `mass_traction` | number | optional | Mass on powered axles (t), Defaults to 0 if not specified | +| `picture` | string | optional | A [URI](https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) with a picture for humans | +| `resistance` | object | optional | Vehicle resistance characteristics. See [Resistance Configuration](#resistance-configuration) below. | +| `traction` | object | optional | Traction characteristics. See [Traction Configuration](#traction-configuration) below. | +| `brakes` | object | optional | Braking system configuration. See [Brakes Configuration](#brakes-configuration) below. In a Train formation, at least one vehicle must have a `brakes` object. |Data Type + +### Resistance Configuration + +The `resistance` object defines the vehicle's resistance characteristics: + +| Attributes | Data Type | Necessity | Description | +| -------------------- | ------------ | ------------- | ----------- | +| `model_fidelity` | string | required | Type of resistance model; values: `table` or `calculated`. | +| `rotation_mass` | number | optional[^3] | Factor for rotating mass (-), greater or equal to 1. | +| `base_resistance` | number | optional[^3] | Basic resistance coefficient (‰). | +| `rolling_resistance` | number | optional[^3] | Rolling resistance coefficient (-). | +| `air_resistance` | number | optional[^3] | Air resistance coefficient (-). | +| `resistance_effort` | array | optional[^4] | [List of speed-force pairs](#list-of-speed-force-pairs) defining resistance. | + +[^3]: Required when using `model_fidelity: "calculated"` +[^4]: Required when using `model_fidelity: "table"` + +### Traction Configuration + +The `traction` object defines the vehicle's traction characteristics: + +| Attributes | Data Type | Necessity | Description | +| ----------------------- | ------------ | ------------- | ----------- | +| `model_fidelity` | string | required | Type of traction model; values: `table` or `calculated`. | +| `rated_power` | number | optional[^5] | Rated power of the vehicle (kW). | +| `initial_tractive_force`| number | optional[^5] | Initial tractive force (kN). | +| `tractive_effort` | array | optional[^6] | [List of speed-force pairs](#list-of-speed-force-pairs) defining tractive effort. | + +[^5]: Required when using `model_fidelity: "calculated"` +[^6]: Required when using `model_fidelity: "table"` + +### Brakes Configuration + +The `brakes` object defines the vehicle's braking characteristics: + +| Attributes | Data Type | Necessity | Description | +| ----------------------- | ------------ | --------- | ----------- | +| `model_fidelity` | string | required | Type of brake model; values: `force`, `one-part-deceleration`, `two-part-deceleration`, `three-part-deceleration` | +| `deceleration` | number | optional[^7] | Final/maximum braking deceleration (m/s²). Negative value. | +| `emergency_deceleration`| number | optional | Maximum emergency braking deceleration (m/s²). Negative value. If not specified, defaults to the value of `deceleration`| +| `reaction_time` | number | optional[^8] | Time between need recognition and control activation (s) | +| `response_time` | number | optional[^9] | Time to reach 5% of final braking deceleration (s) | +| `threshold_time` | number | optional[^9] | Time to develop from 5% to 95% of final deceleration (s) | +| `eddy_current_brake` | object | optional[^10] | Eddy current brake characteristics | +| `electrodynamic_brake` | object | optional[^10] | Electrodynamic brake characteristics | +| `friction_brake` | object | optional[^10] | Friction brake characteristics | + +[^7]: Required when using `model_fidelity: "one-part-deceleration"`, `model_fidelity: "two-part-deceleration"`, or `model_fidelity: "three-part-deceleration"` +[^8]: Required when using `model_fidelity: "two-part-deceleration"` or `model_fidelity: "three-part-deceleration"` +[^9]: Required when using `model_fidelity: "three-part-deceleration"` +[^10]: Only used when using `model_fidelity: "force"`, at least one of `eddy_current_brake`, `electrodynamic_brake`, or `friction_brake` is required for `model_fidelity: "force"` + +The braking system can include one or more of these brake types: + +- `eddy_current_brake` + | Attributes | Data Type | Necessity | Description | + | ----------------------- | ------------ | ------------- | ----------- | + | `model_fidelity` | string | required | Type of eddy current brake model; values: `table` or `calculated`. | + | `min_speed` | number | optional[^11] | Minimum speed for the brake to engage (km/h). Minimum value is 0. | + | `max_brake_effort` | number | optional[^11] | Maximum brake effort (kN). Minimum value is 0. | + | `power` | number | optional[^11] | Power of the brake (kW). Minimum value is 0. | + | `brake_effort` | array | optional[^12] | [List of speed-force pairs](#list-of-speed-force-pairs) defining brake effort | + +- `electrodynamic_brake` + | Attributes | Data Type | Necessity | Description | + | ----------------------- | ------------ | ------------- | ----------- | + | `model_fidelity` | string | required | Type of electrodynamic brake model; values: `table` or `calculated`. | + | `max_brake_force` | number | optional[^11] | Maximum brake force (kN). Minimum value is 0. | + | `speed_control_range` | number | optional[^11] | Speed range for control (km/h). Minimum value is 0. | + | `speed_power_limit` | number | optional[^11] | Speed limit for power (km/h). Minimum value is 0. | + | `speed_field_weakening` | number | optional[^11] | Field weakening speed (km/h). Minimum value is 0. | + | `brake_effort` | array | optional[^12] | [List of speed-force pairs](#list-of-speed-force-pairs) defining brake effort | + +- `friction_brake` + | Attributes | Data Type | Necessity | Description | + | ----------------------- | ------------ | ------------- | ----------- | + | `model_fidelity` | string | required | Type of friction brake model; values: `table` or `calculated`. | + | `service_brake_effort` | number | optional[^11] | Full service brake force (kN). Minimum value is 0. | + | `emergency_brake_effort`| number | optional[^11] | Full emergency brake force (kN). Minimum value is 0. | + | `brake_regime` | string | optional[^11] | Brake regime type; values: `P`, `G`, or `R` | + | `brake_effort` | array | optional[^12] | [List of speed-force pairs](#list-of-speed-force-pairs) defining brake effort | + +[^11]: Required when using `model_fidelity: "calculated"` +[^12]: Required when using `model_fidelity: "table"` + +### List of speed-force pairs + +| Attributes | Data Type | Necessity | Description | +| ----------------------- | ------------ | ------------- | ----------- | +| `speed` | number | required | Speed at which the brake effort is applied (km/h) | +| `force` | number | required | Brake force applied at the specified speed (kN) | + +# Units + +The schema uses common railway units for all numerical values: + +| Quantity | Unit | Description | +|------------------|------|-------------| +| Speed | km/h | Kilometers per hour | +| Mass | t | Metric tons | +| Length | m | Meters | +| Time | s | Seconds | +| Force | kN | Kilonewton | +| Power | kW | Kilowatt | +| Acceleration | m/s² | Meters per second squared | +| Resistance | ‰ | Per mille (mm/m) | +| Unit-less | - | Dimensionless values | + +# Examples + +An example file showing a train with model_fidelity `simplified` vehicle dynamics can be found in [rolling-stock.example.simplified.yaml](rolling-stock.example.simplified.yaml). +An example file showing a train with model_fidelity `detailed` vehicle dynamics can be found in [rolling-stock.example.detailed.yaml](rolling-stock.example.detailed.yaml). The example includes various vehicle types with different characteristics, including resistance, traction, and braking systems. diff --git a/doc/Running-Path.md b/doc/Running-Path.md index e95f510..c029a53 100644 --- a/doc/Running-Path.md +++ b/doc/Running-Path.md @@ -6,39 +6,60 @@ ## Preamble -| Attributes | Necessity | Description | -| -------------------- | --------- | ------------------------------------------------------ | -| `schema` | required | Identifier of the JSON schema. | -| `schema_version` | required | Version of the JSON schema. | -| `paths` | required | An array of at least one [path](#Attributes-in-paths). | +| Attributes | Data Type | Necessity | Description | +| -------------------- | --------- | --------- | ------------------------------------------------------ | +| `schema` | string | required | Identifier of the JSON schema. | +| `schema_version` | string | required | Version of the JSON schema. | +| `paths` | array | required | An array of at least one[^1] [path](#Attributes-in-paths). | + +[^1]: At least one item in `paths` should be present. For scaffolding purposes, `paths` can be empty. ## Attributes in "paths" -All attributes for paths are collected under the array `paths: -` in alphabetical order: -| Attributes | Necessity | Description | -| ------------------------- | --------- | ------------------------------------------------------------------------------ | -| `characteristic_sections` | required | An array of [characteristic sections](#Attributes-in-characteristic-sections). | -| `id` | required | Identifier of the path (can be a UUID). | -| `description` | optional | Description of the path. | -| `points_of_interest` | optional | An array of [points of interest](#Attributes-in-points-of-interest). | +All attributes for a path are collected under the array `paths: -` in alphabetical order: + +| Attributes | Data Type | Necessity | Description | +| ------------------------ | --------- | --------- | ----------- | +| `id` | string | required | Identifier of the running path. | +| `description` | string | optional | Description of the running path. | +| `characteristic_sections`| array | required | An array of [characteristic sections](#Attributes-in-characteristic_sections). | +| `points_of_interest` | array | optional | An array of [points of interest](#Attributes-in-points_of_interest). | + +## Attributes in "characteristic_sections" + +Characteristic sections are sections of a running path within which properties, such as permitted speed or track resistances, do not change. + +| Attributes | Data Type | Necessity | Description | +| -------------------- | --------- | --------- | ----------- | +| `position` | number | required | Position along the path (m) | +| `speed` | number | optional[^2] | Maximum permitted speed (km/h) | +| `resistance` | number | optional[^2] | Track resistance (‰) | + +[^2]: At least one of attributes `speed` or `resistance` must be present. + +## Attributes in "points_of_interest" + +Points of interest mark specific locations along the path where measurements or observations should be taken. -## Attributes in "characteristic sections" +| Attributes | Data Type | Necessity | Description | +| -------------------- | --------- | --------- | ----------- | +| `position` | number | required | Position along the path (m) | +| `id` | string | required | Identifier of the point of interest | +| `description` | string | optional | Description of the point of interest | +| `groups` | array | optional | Groups this point belongs to; an array of unique string identifiers | +| `measure` | enum | required | Position on train to measure; values: `front`, `middle`, or `rear` | -All attributes for a characteristic section are collected under the array `characteristic_sections: -` sorted in ascending or descending order: +# Units -| Attributes | Necessity | Description | -| ------------ | ------------ | ---------------------------------- | -| `position` | required | mileage in meter | -| `speed` | optional[^1] | speed limit in kilometers per hour | -| `resistance` | optional[^1] | resistance in permil | +The schema uses common railway units for all numerical values: -[^1]: At least one optional attribute must be present. +| Quantity | Unit | Description | +|------------------|------|-------------| +| Position | m | Meters | +| Speed | km/h | Kilometers per hour | +| Resistance | ‰ | Per mille (mm/m) | -## Attributes in "points of interest" -All attributes for a point of interest (poi) are collected under the array `points_of_interest: -` sorted in ascending or descending order: +# Example +An example file showing a running path with block sections, signals, and platforms can be found in [running-path.example.yaml](running-path.example.yaml). The example includes various points of interest such as platform tracks, route signals, and clearing points, each with specific positions and descriptions. Below is a visual representation of the YAML structure: -| Attributes | Necessity | Description | -| ------------ | --------- | -------------------------------------------------------------------| -| `position` | required | mileage in meter | -| `label` | required | name for the point | -| `measure` | required | measurement applies to the `front` , `middle` or `rear` of a train | +![Running Path Example](running-path.example.png) diff --git a/doc/rolling-stock.example.detailed.yaml b/doc/rolling-stock.example.detailed.yaml new file mode 100644 index 0000000..71dae48 --- /dev/null +++ b/doc/rolling-stock.example.detailed.yaml @@ -0,0 +1,152 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "2024.07" +model_fidelity: "detailed" # Options: "simplified", "detailed" +trains: + - id: IC2000-detailed + description: "Intercity with locomotive BR193, 2 first class, 1 dining car and 5 second class coaches" + train_type: long_distance + formation: [Vectron,Avmmz,Avmmz,WRkmz,Bpmmz,Bpmmz,Bpmmz,Bpmmz,Bpmmz] + loading_factor: [1.0,0.6,0.6,0.4,0.8,0.8,0.8,0.8,0.8] + +vehicles: + - id: Vectron + vehicle_type: traction_unit + power_type: electric + picture: https://commons.wikimedia.org/wiki/File:Siemens_Vectron_193_837.jpg + description: "Siemens Vectron MS" + # Main attributes + length: 18.98 # m + mass: 89.0 # t + mass_traction: 89.0 # t + speed_limit: 200 # km/h + resistance: # Resistance coefficients (optional) + model_fidelity: "table" # "table" or "calculated" + rotation_mass: 1.09 # - + base_resistance: 2.2 # ‰ + rolling_resistance: 1.4 # - + air_resistance: 6.0 # - + resistance_effort: + - speed: 0.0 # in km/h + force: 2.2 # in ‰ + - speed: 60.0 + force: 2.2 + - speed: 100.0 + force: 2.2 + - speed: 160.0 + force: 2.2 + - speed: 200.0 + force: 2.2 + traction: # Traction characteristics (optional) + model_fidelity: "table" # "table" or "calculated" + rated_power: 8000.0 # kW + initial_tractive_force: 94.400 # kN + tractive_effort: + - speed: 0.0 # in km/h + force: 94.400 # in kN + - speed: 60.0 + force: 80.000 + - speed: 100.0 + force: 80.000 + - speed: 160.0 + force: 80.000 + - speed: 200.0 + force: 80.000 + brakes: # Braking system configuration (optional) + model_fidelity: "force" # "force", "deceleration-one-part", "deceleration-two-part" or "deceleration-three-part" + + reaction_time: 3 # in s the time span between recognizing the need to initiate a braking action and the actual activation of the control (required for model_fidelity: "deceleration-two-part", "deceleration-three-part") + response_time: 1.5 # in s the time span between the activation of the controls and the establishment of 5% of the final braking deceleration (required for model_fidelity: "deceleration-three-part") + threshold_time: 4 # in s the time span to develop the braking deceleration from 5% of the final/maximum deceleration to 95% of the final/maximum deceleration (required for model_fidelity: "deceleration-three-part") + deceleration: -0.95 # in m/s² the final/maximum braking deceleration (required for model_fidelity: "deceleration-one-part", "deceleration-two-part", "deceleration-three-part") + emergency_deceleration: -1.5 # in m/s² the final/maximum deceleration during emergency braking (required for model_fidelity: "deceleration-one-part", "deceleration-two-part", "deceleration-three-part") + + eddy_current_brake: # Eddy current brake characteristics (at least one of eddy_current_brake, electrodynamic_brake or friction_brake is required for model_fidelity: "force") + model_fidelity: "calculated" # "table" or "calculated" + min_speed: 10.0 # in km/h + max_brake_effort: 94.400 # in kN + power: 1000.0 # in kW + brake_effort: + - speed: 0.0 # in km/h + force: 94.400 # in kN + - speed: 10.0 # in km/h + force: 80.000 # in kN + electrodynamic_brake: # Electrodynamic brake characteristics (at least one of eddy_current_brake, electrodynamic_brake or friction_brake is required for model_fidelity: "force") + model_fidelity: "calculated" # "table" or "calculated" + max_brake_force: 94.400 # in kN + speed_control_range: 10.0 # in km/h + speed_power_limit: 160.0 # in km/h + speed_field_weakening: 200.0 # in km/h, optional, field weakening of the three-phase field + brake_effort: + - speed: 0.0 # in km/h + force: 94.400 # in kN + - speed: 10.0 # in km/h + force: 80.000 # in kN + friction_brake: # Friction brake characteristics (at least one of eddy_current_brake, electrodynamic_brake or friction_brake is required for model_fidelity: "force") + model_fidelity: "table" # "table" or "calculated" + service_brake_effort: 20.0 # Full service brake force in kN + emergency_brake_effort: 100.0 # Full emergency brake force in kN + brake_regime: "P" # "P","G" or "R" + brake_effort: + - speed: 0.0 # in km/h + force: 94.400 # in kN + - speed: 10.0 # in km/h + force: 80.000 # in kN + - id: Avmmz + description: "First class coach" + vehicle_type: passenger + length: 26.4 # m + mass: 47.0 # t + load_limit: 10.8 # t + speed_limit: 200 # km/h + brakes: + model_fidelity: "force" # "force", "deceleration-one-part", "deceleration-two-part", "deceleration-three-part" + friction_brake: + model_fidelity: "table" # "table" or "calculated" + service_brake_effort: 20.0 # Full service brake force in kN + emergency_brake_effort: 100.0 # Full emergency brake force in kN + brake_regime: "P" # "P","G" or "R" + brake_effort: + - speed: 0.0 # in km/h + force: 94.400 # in kN + - speed: 10.0 # in km/h + force: 80.000 # in kN + - id: WRkmz + description: "Dining car" + vehicle_type: passenger + length: 26.4 # m + mass: 52.0 # t + load_limit: 12.0 # t + speed_limit: 200 # km/h + brakes: + model_fidelity: "force" # "force", "deceleration-one-part", "deceleration-two-part", "deceleration-three-part" + friction_brake: + model_fidelity: "table" # "table" or "calculated" + service_brake_effort: 20.0 # Full service brake force in kN + emergency_brake_effort: 100.0 # Full emergency brake force in kN + brake_regime: "P" # "P","G" or "R" + brake_effort: + - speed: 0.0 # in km/h + force: 94.400 # in kN + - speed: 10.0 # in km/h + force: 80.000 # in kN + - id: Bpmmz + description: "Second class coach" + vehicle_type: passenger + length: 26.4 # m + mass: 45.0 # t + load_limit: 16.0 # t + speed_limit: 200 # km/h + brakes: + model_fidelity: "force" # "force", "deceleration-one-part", "deceleration-two-part", "deceleration-three-part" + friction_brake: + model_fidelity: "table" # "table" or "calculated" + service_brake_effort: 20.0 # Full service brake force in kN + emergency_brake_effort: 100.0 # Full emergency brake force in kN + brake_regime: "P" # "P","G" or "R" + brake_effort: + - speed: 0.0 # in km/h + force: 94.400 # in kN + - speed: 10.0 # in km/h + force: 80.000 # in kN diff --git a/doc/rolling-stock.example.simplified.yaml b/doc/rolling-stock.example.simplified.yaml new file mode 100644 index 0000000..3886a0b --- /dev/null +++ b/doc/rolling-stock.example.simplified.yaml @@ -0,0 +1,16 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "2024.07" +model_fidelity: "simplified" # Options: "simplified", "detailed" +trains: + - id: IC2000-simplified + description: "Intercity with a Vectron locomotive, 2 first class, 1 dining car and 5 second class coaches" + train_type: long_distance + simplified_characteristics: + speed_limit: 160 # km/h + length: 207.4 # m + acceleration: 0.5 # m/s² + deceleration: -0.65 # m/s² + emergency_deceleration: -1.55 # m/s² + coasting: -0.04 # m/s² diff --git a/doc/rolling-stock.example.yaml b/doc/rolling-stock.example.yaml deleted file mode 100644 index 294a4dc..0000000 --- a/doc/rolling-stock.example.yaml +++ /dev/null @@ -1,44 +0,0 @@ -%YAML 1.2 ---- -schema: https://railtoolkit.org/schema/rolling-stock.json -schema_version: "2022.05" -trains: - - name: Regional Train - id: RB50-1 - formation: [BR642,BR642] -vehicles: - - name: Siemens Desiro Classic # (source: https://de.wikipedia.org/wiki/Siemens_Desiro_Classic) - id: BR642 - UUID: bb53ecc8-35ff-4c63-b480-a342f99e973b - picture: https://commons.wikimedia.org/wiki/File:Liesel_28-11-10_642_055-8_im_Bahnhof_Scharfenstein.JPG - vehicle_type: multiple unit # "freight", "passenger", "traction unit" or "multiple unit" - power_type: diesel # "diesel", "electric", or "steam" - - ## main attributes - length: 41.7 # in m - mass: 68.0 # in t - load_limit: 20.0 # in t - mass_traction: 52.8 # in t # mass on driving axles of the traction unit - speed_limit: 120 # in km/h - a_braking: -0.4253 # in m/s^2 # TODO see Roadmap in README.md - - ## coefficients for the vehicle resistance - rotation_mass: 1.08 # without dimension - base_resistance: 3.0 # in ‰ # coefficient for basic resistance - rolling_resistance: 1.4 # in ‰ # coefficient for resistance of rolling axles - air_resistance: 0.003 # in ‰ # coefficient for air resistance - - ## tractive effort as pairs of speed and tractive force - tractive_effort: - # [ v in km/h, F_T in N ] - - [ 0.0, 94400 ] - - [ 10.0, 80000 ] - - [ 20.0, 61330 ] - - [ 30.0, 42630 ] - - [ 40.0, 35600 ] - - [ 50.0, 32220 ] - - [ 60.0, 25540 ] - - [ 70.0, 22990 ] - - [ 80.0, 19400 ] - - [ 100.0, 14810 ] - - [ 120.0, 13380 ] diff --git a/doc/running-path.example.png b/doc/running-path.example.png new file mode 100644 index 0000000..10f0f66 Binary files /dev/null and b/doc/running-path.example.png differ diff --git a/doc/running-path.example.tex b/doc/running-path.example.tex new file mode 100644 index 0000000..a16fa9a --- /dev/null +++ b/doc/running-path.example.tex @@ -0,0 +1,292 @@ +%!TEX TS-program = pdflatexmk + +% Copyright (c) 2025, Martin Scheidt (ISC license) +% Permission to use, copy, modify, and/or distribute this file for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. + +\documentclass[tikz,convert={density=300,outext=.png}]{standalone} +\usepackage{tikz-trackschematic} +\usepackage{etoolbox} +\newtoggle{DEBUG} +\settoggle{DEBUG}{false} + +\begin{document} + \begin{tikzpicture}[font=\sffamily] + % coordinates + \coordinate (E01) at ( 0, 0); + \coordinate (P01) at ([shift={( 1, 0)}] E01); + \coordinate (S01) at ([shift={( 1, 0)}] P01); + \coordinate (CP01) at ([shift={( 1, 0)}] S01); + \coordinate (T01) at ([shift={( 1, 0)}] CP01); + % + \coordinate (CP02) at ([shift={(-1, 1)}] T01); + \coordinate (S02) at ([shift={(-1, 0)}] CP02); + \coordinate (P02) at ([shift={(-1, 0)}] S02); + \coordinate (E02) at ([shift={(-1, 0)}] P02); + % + \coordinate (CP03) at ([shift={( 1, 0)}] T01); + \coordinate (S03) at ([shift={( 1, 0)}] CP03); + \coordinate (G01) at ([shift={( 1, 0)}] S03); + \coordinate (VP04) at ([shift={( 1, 0)}] G01); + \coordinate (DS03) at ([shift={( 1, 0)}] VP04); + \coordinate (DS04) at ([shift={( 1, 0)}] DS03); + \coordinate (VP03) at ([shift={( 1, 0)}] DS04); + \coordinate (G02) at ([shift={( 1, 0)}] VP03); + \coordinate (S04) at ([shift={( 1, 0)}] G02); + \coordinate (CP04) at ([shift={( 1, 0)}] S04); + \coordinate (S05) at ([shift={( 1, 0)}] CP04); + \coordinate (G03) at ([shift={( 1, 0)}] S05); + \coordinate (VP06) at ([shift={( 1, 0)}] G03); + \coordinate (DS05) at ([shift={( 1, 0)}] VP06); + \coordinate (G04) at (DS05); + \coordinate (DS06) at ([shift={( 1, 0)}] DS05); + \coordinate (VP05) at ([shift={( 1, 0)}] DS06); + \coordinate (VP09) at ([shift={( 1, 0)}] VP05); + \coordinate (S06) at ([shift={( 1, 0)}] VP09); + \coordinate (CP05) at ([shift={( 1, 0)}] S06); + \coordinate (T02) at ([shift={( 1, 0)}] CP05); + \coordinate (CP06) at ([shift={( 1, 0)}] T02); + \coordinate (S07) at ([shift={( 1, 0)}] CP06); + % + \coordinate (CP07) at ([shift={( 1, 1)}] T02); + \coordinate (S08) at ([shift={( 1, 0)}] CP07); + \coordinate (P04) at ([shift={( 1, 0)}] S08); + \coordinate (S10) at ([shift={( 1, 0)}] P04); + \coordinate (CP09) at ([shift={( 1, 0)}] S10); + % + \coordinate (P03) at ([shift={( 1, 0)}] S07); + \coordinate (S09) at ([shift={( 1, 0)}] P03); + \coordinate (CP08) at ([shift={( 1, 0)}] S09); + \coordinate (T03) at ([shift={( 1, 0)}] CP08); + \coordinate (CP10) at ([shift={( 1, 0)}] T03); + \coordinate (VP12) at ([shift={( 1, 0)}] CP10); + \coordinate (S11) at ([shift={( 1, 0)}] VP12); + \coordinate (G05) at ([shift={( 1, 0)}] S11); + \coordinate (DS12) at ([shift={( 1, 0)}] G05); + \coordinate (VP07) at ([shift={( 1, 0)}] DS12); + \coordinate (DS11) at ([shift={( 1, 0)}] VP07); + \coordinate (G06) at ([shift={( 1, 0)}] DS11); + \coordinate (S12) at ([shift={( 1, 0)}] G06); + \coordinate (VP11) at ([shift={( 1, 0)}] S12); + \coordinate (CP11) at ([shift={( 1, 0)}] VP11); + \coordinate (S13) at ([shift={( 1, 0)}] CP11); + \coordinate (G07) at ([shift={( 1, 0)}] S13); + \coordinate (VP14) at ([shift={( 1, 0)}] G07); + \coordinate (DS13) at ([shift={( 1, 0)}] VP14); + \coordinate (DS14) at ([shift={( 1, 0)}] DS13); + \coordinate (G08) at ([shift={( 1, 0)}] DS14); + \coordinate (VP13) at ([shift={( 1, 0)}] G08); + \coordinate (S14) at ([shift={( 1, 0)}] VP13); + \coordinate (CP12) at ([shift={( 1, 0)}] S14); + \coordinate (T04) at ([shift={( 1, 0)}] CP12); + \coordinate (CP13) at ([shift={( 1, 0)}] T04); + \coordinate (S15) at ([shift={( 1, 0)}] CP13); + \coordinate (CP14) at ([shift={( 1, 1)}] T04); + \coordinate (S16) at ([shift={( 1, 0)}] CP14); + \coordinate (P05) at ([shift={( 1, 0)}] S15); + \coordinate (E03) at ([shift={( 1, 0)}] P05); + \coordinate (P06) at ([shift={( 1, 0)}] S16); + \coordinate (E04) at ([shift={( 1, 0)}] P06); + + { %% topology + % tracks + \maintrack (E01) -- (P01) -- (S01) -- (CP01) -- (T01) -- (CP03) -- (S03) -- (G01) -- (VP04) -- (DS03) -- (DS04) -- (VP03) -- (G02) -- (S04) -- (CP04) -- (S05) -- (G03) -- (VP06) -- (DS05) -- (G04) -- (VP05) -- (VP09) -- (S06) -- (CP05) -- (T02) -- (CP06) -- (S07) -- (P03) -- (S09) -- (CP08) -- (T03) -- (CP10) -- (VP12) -- (S11) -- (G05) -- (DS12) -- (VP07) -- (DS11) -- (G06) -- (S12) -- (VP11) -- (CP11) -- (S13) -- (G07) -- (VP14) -- (DS13) -- (DS14) -- (G08) -- (VP13) -- (S14) -- (CP12) -- (T04) -- (CP13) -- (S15) -- (P05) -- (E03); + \maintrack (T01) -- (CP02) -- (S02) -- (P02) -- (E02); + \maintrack (T02) -- (CP07) -- (S08) -- (P04) -- (S10) -- (CP09) -- (T03); + \maintrack (T04) -- (CP14) -- (S16) -- (P06) -- (E04); + \tracklabel at (P01) label (A1); + \tracklabel at (P02) label (A2); + \tracklabel at (P03) label (B1); + \tracklabel at (P04) label (B2); + \tracklabel at (P05) label (C1); + \tracklabel at (P06) label (C2); + \tracklabel at (G01) label (AB1); + \tracklabel at (G03) label (AB2); + \tracklabel at (G05) label (BC1); + \tracklabel at (G07) label (BC2); + + % turnouts + \turnout[backward,branch=left] at (T01) label (T1); + \turnout[forward ,branch=left] at (T02) label (T2); + \turnout[backward,branch=left] at (T03) label (T3); + \turnout[forward ,branch=left] at (T04) label (T4); + + % bufferstops + \bufferstop[backward] at (E01); + \bufferstop[backward] at (E02); + \bufferstop[forward] at (E03); + \bufferstop[forward] at (E04); + } + { %% traffic control + % signals + \signal[route,forward] at (S01) label (S1); + \signal[route,forward,shift label={(0.5,-0.2)}] at (S02) label (S2); + \signal[route,backward] at (S03) label (S3); + \signal[distant,backward] at (DS03) label (dS3); + \signal[distant,forward] at (DS04) label (dS4); + \signal[block,forward] at (S04) label (S4); + \signal[block,backward] at (S05) label (S5); + \signal[distant,backward] at (DS05) label (dS5); + \signal[distant,forward] at (DS06) label (dS6); + \signal[route,distant,forward] at (S06) label (S6); + \signal[route,backward,shift label={(-0.5,0.2)}] at (S07) label (S7); + \signal[route,backward] at (S08) label (S8); + \signal[route,forward] at (S09) label (S9); + \signal[route,forward,shift label={(0.5,-0.2)}] at (S10) label (S10); + \signal[route,distant,backward] at (S11) label (S11); + \signal[distant,forward] at (DS12) label (dS12); + \signal[distant,backward] at (DS11) label (dS11); + \signal[block,forward] at (S12) label (S12); + \signal[block,backward] at (S13) label (S13); + \signal[distant,backward] at (DS13) label (dS13); + \signal[distant,forward] at (DS14) label (dS14); + \signal[route,forward] at (S14) label (S14); + \signal[route,backward,shift label={(-0.5,0.2)}] at (S15) label (S15); + \signal[route,backward] at (S16) label (S16); + + \viewpoint[forward] at (VP04); + \viewpoint[forward] at (VP06); + \viewpoint[forward] at (VP09); + \viewpoint[forward] at (VP12); + \viewpoint[forward] at (VP14); + \viewpoint[backward] at (VP03); + \viewpoint[backward] at (VP05); + \viewpoint[backward] at (VP07); + \viewpoint[backward] at (VP11); + \viewpoint[backward] at (VP13); + + % clearing points + \tikzset{every node/.style={backward}}; + \clearingpoint[shift label={( 0 ,0.5)}] at (CP01) label (CP1); + \clearingpoint[shift label={( 0 ,0.5)}] at (CP02) label (CP2); + \clearingpoint[shift label={( 0 ,0 )}] at (CP03) label (CP3); + \clearingpoint[shift label={(-0.5,0.5)}] at (CP04) label (CP4); + \clearingpoint[shift label={( 0 ,0.5)}] at (CP05) label (CP5); + \clearingpoint[shift label={( 0 ,0 )}] at (CP06) label (CP6); + \clearingpoint[shift label={(-0.5,0.5)}] at (CP07) label (CP7); + \clearingpoint[shift label={( 0 ,0.5)}] at (CP08) label (CP8); + \clearingpoint[shift label={( 0 ,0.5)}] at (CP09) label (CP9); + \clearingpoint[shift label={( 0 ,0 )}] at (CP10) label (CP10); + \clearingpoint[shift label={(-0.5,0.5)}] at (CP11) label (CP11); + \clearingpoint[shift label={( 0 ,0.5)}] at (CP12) label (CP12); + \clearingpoint[shift label={( 0 ,0 )}] at (CP13) label (CP13); + \clearingpoint[shift label={(-0.5,0.5)}] at (CP14) label (CP14); + } + { %% constructions + % platforms + \tikzset{every node/.style={length=1.7cm}}; + \platform[side=left ] at (P01); + \platform[side=right] at (P02); + \platform[side=left ] at (P03); + \platform[side=right] at (P04); + \platform[side=left ] at (P05); + \platform[side=right] at (P06); + } + { %% measures + % legend resistance + \coordinate (UPPER) at (0,-0.75); + \coordinate (LOWER) at (0,-3.75); + \xdef\min{-10} + \xdef\max{20} + \tikzstyle{legend_resistance}=[\hectometercolor,line width=0.07pt] + \draw[legend_resistance] let \p1=(E01),\p2=(E03),\n{value}={-10},\n{min}={\min},\n{max}={\max},\n{range}={\n{max} - \n{min}},\p{UPPER}=(UPPER),\p{LOWER}=(LOWER),\n{scaledY}={(\n{value} - \n{min}) / \n{range} * (\y{UPPER} - \y{LOWER}) + \y{LOWER}} in (\x1,\n{scaledY}) coordinate (L1) -- ++(-0.2,0) node[left,align=right] {\n{value}} -- (\x2,\n{scaledY}); + \draw[legend_resistance] let \p1=(E01),\p2=(E03),\n{value}={ -5},\n{min}={\min},\n{max}={\max},\n{range}={\n{max} - \n{min}},\p{UPPER}=(UPPER),\p{LOWER}=(LOWER),\n{scaledY}={(\n{value} - \n{min}) / \n{range} * (\y{UPPER} - \y{LOWER}) + \y{LOWER}} in (\x1,\n{scaledY}) coordinate (L2) -- ++(-0.2,0) node[left,align=right] {\n{value}} -- (\x2,\n{scaledY}); + \draw[legend_resistance] let \p1=(E01),\p2=(E03),\n{value}={0.0},\n{min}={\min},\n{max}={\max},\n{range}={\n{max} - \n{min}},\p{UPPER}=(UPPER),\p{LOWER}=(LOWER),\n{scaledY}={(\n{value} - \n{min}) / \n{range} * (\y{UPPER} - \y{LOWER}) + \y{LOWER}} in (\x1,\n{scaledY}) coordinate (L3) -- ++(-0.2,0) node[left,align=right] {\n{value}} -- (\x2,\n{scaledY}); + \draw[legend_resistance] let \p1=(E01),\p2=(E03),\n{value}={5.0},\n{min}={\min},\n{max}={\max},\n{range}={\n{max} - \n{min}},\p{UPPER}=(UPPER),\p{LOWER}=(LOWER),\n{scaledY}={(\n{value} - \n{min}) / \n{range} * (\y{UPPER} - \y{LOWER}) + \y{LOWER}} in (\x1,\n{scaledY}) coordinate (L4) -- ++(-0.2,0) node[left,align=right] {\n{value}} -- (\x2,\n{scaledY}); + \draw[legend_resistance] let \p1=(E01),\p2=(E03),\n{value}={10.0},\n{min}={\min},\n{max}={\max},\n{range}={\n{max} - \n{min}},\p{UPPER}=(UPPER),\p{LOWER}=(LOWER),\n{scaledY}={(\n{value} - \n{min}) / \n{range} * (\y{UPPER} - \y{LOWER}) + \y{LOWER}} in (\x1,\n{scaledY}) coordinate (L5) -- ++(-0.2,0) node[left,align=right] {\n{value}} -- (\x2,\n{scaledY}); + \draw[legend_resistance] let \p1=(E01),\p2=(E03),\n{value}={15.0},\n{min}={\min},\n{max}={\max},\n{range}={\n{max} - \n{min}},\p{UPPER}=(UPPER),\p{LOWER}=(LOWER),\n{scaledY}={(\n{value} - \n{min}) / \n{range} * (\y{UPPER} - \y{LOWER}) + \y{LOWER}} in (\x1,\n{scaledY}) coordinate (L6) -- ++(-0.2,0) node[left,align=right] {\n{value}} -- (\x2,\n{scaledY}); + \draw[legend_resistance] let \p1=(E01),\p2=(E03),\n{value}={20.0},\n{min}={\min},\n{max}={\max},\n{range}={\n{max} - \n{min}},\p{UPPER}=(UPPER),\p{LOWER}=(LOWER),\n{scaledY}={(\n{value} - \n{min}) / \n{range} * (\y{UPPER} - \y{LOWER}) + \y{LOWER}} in (\x1,\n{scaledY}) coordinate (L7) -- ++(-0.2,0) node[left,align=right] {\n{value}} -- (\x2,\n{scaledY}); + + % resistance + \path let \p1=(E01),\n{value}={0},\n{min}={\min},\n{max}={\max},\n{range}={\n{max} - \n{min}},\p{UPPER}=(UPPER),\p{LOWER}=(LOWER),\n{scaledY}={(\n{value} - \n{min}) / \n{range} * (\y{UPPER} - \y{LOWER}) + \y{LOWER}} in coordinate (R01) at (\x1,\n{scaledY}); + \path let \p1=(G01),\n{value}={1},\n{min}={\min},\n{max}={\max},\n{range}={\n{max} - \n{min}},\p{UPPER}=(UPPER),\p{LOWER}=(LOWER),\n{scaledY}={(\n{value} - \n{min}) / \n{range} * (\y{UPPER} - \y{LOWER}) + \y{LOWER}} in coordinate (R02) at (\x1,\n{scaledY}); + \path let \p1=(G02),\n{value}={2},\n{min}={\min},\n{max}={\max},\n{range}={\n{max} - \n{min}},\p{UPPER}=(UPPER),\p{LOWER}=(LOWER),\n{scaledY}={(\n{value} - \n{min}) / \n{range} * (\y{UPPER} - \y{LOWER}) + \y{LOWER}} in coordinate (R03) at (\x1,\n{scaledY}); + \path let \p1=(G03),\n{value}={5},\n{min}={\min},\n{max}={\max},\n{range}={\n{max} - \n{min}},\p{UPPER}=(UPPER),\p{LOWER}=(LOWER),\n{scaledY}={(\n{value} - \n{min}) / \n{range} * (\y{UPPER} - \y{LOWER}) + \y{LOWER}} in coordinate (R04) at (\x1,\n{scaledY}); + \path let \p1=(DS06),\n{value}={-3},\n{min}={\min},\n{max}={\max},\n{range}={\n{max} - \n{min}},\p{UPPER}=(UPPER),\p{LOWER}=(LOWER),\n{scaledY}={(\n{value} - \n{min}) / \n{range} * (\y{UPPER} - \y{LOWER}) + \y{LOWER}} in coordinate (R05) at (\x1,\n{scaledY}); + \path let \p1=(S06),\n{value}={2},\n{min}={\min},\n{max}={\max},\n{range}={\n{max} - \n{min}},\p{UPPER}=(UPPER),\p{LOWER}=(LOWER),\n{scaledY}={(\n{value} - \n{min}) / \n{range} * (\y{UPPER} - \y{LOWER}) + \y{LOWER}} in coordinate (R06) at (\x1,\n{scaledY}); + \path let \p1=(G05),\n{value}={-10},\n{min}={\min},\n{max}={\max},\n{range}={\n{max} - \n{min}},\p{UPPER}=(UPPER),\p{LOWER}=(LOWER),\n{scaledY}={(\n{value} - \n{min}) / \n{range} * (\y{UPPER} - \y{LOWER}) + \y{LOWER}} in coordinate (R07) at (\x1,\n{scaledY}); + \path let \p1=(G06),\n{value}={15},\n{min}={\min},\n{max}={\max},\n{range}={\n{max} - \n{min}},\p{UPPER}=(UPPER),\p{LOWER}=(LOWER),\n{scaledY}={(\n{value} - \n{min}) / \n{range} * (\y{UPPER} - \y{LOWER}) + \y{LOWER}} in coordinate (R08) at (\x1,\n{scaledY}); + \path let \p1=(G07),\n{value}={-10},\n{min}={\min},\n{max}={\max},\n{range}={\n{max} - \n{min}},\p{UPPER}=(UPPER),\p{LOWER}=(LOWER),\n{scaledY}={(\n{value} - \n{min}) / \n{range} * (\y{UPPER} - \y{LOWER}) + \y{LOWER}} in coordinate (R09) at (\x1,\n{scaledY}); + \path let \p1=(G08),\n{value}={20},\n{min}={\min},\n{max}={\max},\n{range}={\n{max} - \n{min}},\p{UPPER}=(UPPER),\p{LOWER}=(LOWER),\n{scaledY}={(\n{value} - \n{min}) / \n{range} * (\y{UPPER} - \y{LOWER}) + \y{LOWER}} in coordinate (R10) at (\x1,\n{scaledY}); + \path let \p1=(S14),\n{value}={-1},\n{min}={\min},\n{max}={\max},\n{range}={\n{max} - \n{min}},\p{UPPER}=(UPPER),\p{LOWER}=(LOWER),\n{scaledY}={(\n{value} - \n{min}) / \n{range} * (\y{UPPER} - \y{LOWER}) + \y{LOWER}} in coordinate (R11) at (\x1,\n{scaledY}); + \path let \p1=(E03),\n{value}={-1},\n{min}={\min},\n{max}={\max},\n{range}={\n{max} - \n{min}},\p{UPPER}=(UPPER),\p{LOWER}=(LOWER),\n{scaledY}={(\n{value} - \n{min}) / \n{range} * (\y{UPPER} - \y{LOWER}) + \y{LOWER}} in coordinate (R12) at (\x1,\n{scaledY}); + + \draw[blue,line width=1pt] (R01) -| (R02) -| (R03) -| (R04) -| (R05) -| (R06) -| (R07) -| (R08) -| (R09) -| (R10) -| (R11) -| (R12); + + % hectometer posts + \coordinate (HM) at (0,-4); + \tikzset{hectometer base={(HM)},orientation=right}; + \hectometer[] at (E01) label ( 0.000); + \hectometer[] at (P01) label ( 0.100); + \hectometer[] at (S01) label ( 0.220); + \hectometer[] at (CP01) label ( 0.320); + \hectometer[] at (T01) label ( 0.350); + \hectometer[] at (CP03) label ( 0.390); + \hectometer[] at (S03) label ( 0.500); + \hectometer[] at (G01) label ( 1.000); + \hectometer[] at (VP04) label ( 1.450); + \hectometer[] at (DS03) label ( 1.500); + \hectometer[] at (DS04) label ( 1.700); + \hectometer[] at (VP03) label ( 1.750); + \hectometer[] at (G02) label ( 2.000); + \hectometer[] at (S04) label ( 2.700); + \hectometer[] at (CP04) label ( 2.800); + \hectometer[] at (S05) label ( 2.900); + \hectometer[] at (G03) label ( 3.000); + \hectometer[] at (VP06) label ( 3.750); + \hectometer[] at (DS05) label ( 3.900); + \hectometer[] at (DS06) label ( 4.000); + \hectometer[] at (VP05) label ( 4.150); + \hectometer[] at (VP09) label ( 4.750); + \hectometer[] at (S06) label ( 5.000); + \hectometer[] at (CP05) label ( 5.100); + \hectometer[] at (T02) label ( 5.130); + \hectometer[] at (CP06) label ( 5.170); + \hectometer[] at (S07) label ( 5.270); + \hectometer[] at (P03) label ( 5.500); + \hectometer[] at (S09) label ( 5.650); + \hectometer[] at (CP08) label ( 5.750); + \hectometer[] at (T03) label ( 5.780); + \hectometer[] at (VP12) label ( 5.800); + \hectometer[] at (CP10) label ( 5.810); + \hectometer[] at (S11) label ( 5.910); + \hectometer[] at (G05) label ( 6.000); + \hectometer[] at (DS12) label ( 6.100); + \hectometer[] at (VP07) label ( 6.160); + \hectometer[] at (DS11) label ( 6.910); + \hectometer[] at (G06) label ( 7.000); + \hectometer[] at (S12) label ( 7.100); + \hectometer[] at (VP11) label ( 7.160); + \hectometer[] at (CP11) label ( 7.200); + \hectometer[] at (S13) label ( 7.300); + \hectometer[] at (G07) label ( 8.000); + \hectometer[] at (VP14) label ( 8.150); + \hectometer[] at (DS13) label ( 8.300); + \hectometer[] at (DS14) label ( 8.400); + \hectometer[] at (G08) label ( 8.500); + \hectometer[] at (VP13) label ( 8.550); + \hectometer[] at (S14) label ( 9.400); + \hectometer[] at (CP12) label ( 9.500); + \hectometer[] at (T04) label ( 9.530); + \hectometer[] at (CP13) label ( 9.560); + \hectometer[] at (S15) label ( 9.660); + \hectometer[] at (P05) label ( 9.800); + \hectometer[] at (E03) label ( 9.950); + + } + \iftoggle{DEBUG}{ + % help lines and points + \foreach \point in { + E01,E02,E03,E04, + CP01,CP02,CP03,CP04,CP05,CP06,CP07,CP08,CP09,CP10,CP11,CP12,CP13,CP14, + S01,S02,S03,S04,S05,S06,S07,S08,S09,S10,S11,S12,S13,S14,S15,S16, + P01,P02,P03,P04,P05,P06, + T01,T02,T03,T04, + G01,G02,G03,G04,G05,G06,G07,G08, + VP03,VP04,VP05,VP06,VP07,VP09,VP11,VP12,VP13,VP14, + DS03,DS04,DS05,DS06,DS11,DS12,DS13,DS14, + UPPER,LOWER,HM, + R01,R02,R03,R04,R05,R06,R07,R08,R09,R10,R11,R12} + \fill[magenta,thin,font=\tiny] (\point) circle (0.05) node[above] {\point}; + }{} + \end{tikzpicture} +\end{document} \ No newline at end of file diff --git a/doc/running-path.example.yaml b/doc/running-path.example.yaml index d14d490..0998b5c 100644 --- a/doc/running-path.example.yaml +++ b/doc/running-path.example.yaml @@ -4,60 +4,177 @@ schema: https://railtoolkit.org/schema/running-path.json schema_version: "2024.07" paths: - id: example - description: "Example" - points_of_interest: - - position: 850.00 # mileage in meter - label: "1:view point" # label name - measure: front # front, middle or rear of the passing train - - position: 1000.00 - label: "1:distant signal" - measure: front - - position: 2000.00 - label: "1:main signal" - measure: front - - position: 5500.00 - label: "A:platform" - measure: middle - - position: 9000.00 - label: "3:main signal" - measure: front - - position: 9050.00 - label: "1:clearing point" - measure: rear + description: "Example path via track A1-AB1-AB2-B1-BC1-BC2-C1" characteristic_sections: - - position: 0.0 # mileage in meter - speed: 160 # speed limit in km/h, - resistance: 0.00 # resistance in permil - - position: 1000.0 - speed: 160 - resistance: 1.00 - - position: 2000.0 - speed: 160 - resistance: 2.00 - - position: 3000.0 - speed: 160 - resistance: 5.00 - - position: 4000.0 - speed: 160 - resistance: -3.00 - - position: 5000.0 - speed: 160 - resistance: 5.00 - - position: 6000.0 - speed: 160 - resistance: -10.00 - - position: 7000.0 - speed: 80 - resistance: 15.00 - - position: 8000.0 - speed: 120 - resistance: -10.00 - - position: 8500.0 - speed: 120 - resistance: 20.00 - - position: 9000.0 - speed: 160 - resistance: 0.00 - - position: 10000.0 - speed: 160 - resistance: 0.00 + - position: 0.0 # m + speed: 60 # km/h + resistance: 0.00 # ‰ + - position: 390.0 # m + speed: 160 # km/h + - position: 1000.0 # m + resistance: 1.00 # ‰ + - position: 2000.0 # m + resistance: 2.00 # ‰ + - position: 3000.0 # m + resistance: 5.00 # ‰ + - position: 4000.0 # m + resistance: -3.00 # ‰ + - position: 5000.0 # m + speed: 120 # km/h + resistance: 2.00 # ‰ + - position: 5810.0 # m + speed: 160 # km/h + - position: 6000.0 # m + resistance: -10.00 # ‰ + - position: 7000.0 # m + resistance: 15.00 # ‰ + - position: 8000.0 # m + resistance: -10.00 # ‰ + - position: 8500.0 # m + resistance: 20.00 # ‰ + - position: 9400.0 # m + speed: 40 # km/h + resistance: -1.00 # ‰ + - position: 9950.0 # m + speed: 0 # km/h + points_of_interest: + - id: "a1" + position: 100.00 # m + description: "plattform track 1" + groups: ["station A"] + measure: middle + - id: "s1" + position: 220.00 # m + description: "route signal 1" + groups: ["station A", "block 1", "route 1"] + measure: front + - id: "cp1" + position: 320.00 # m + description: "block clearing point" + groups: ["station A"] + measure: rear + - id: "cp3" + position: 320.00 # m + description: "route clearing point" + groups: ["station A", "block 1", "route 1"] + measure: rear + - id: "vp4" + position: 1450.00 # m + description: "view point distant signal 4" + groups: ["block 2"] + measure: front + - id: "ds4" + position: 1700.00 # m + description: "distant signal 4" + groups: ["block 2"] + measure: front + - id: "s4" + position: 2700.00 # m + description: "block signal 4" + groups: ["block 2"] + measure: front + - id: "cp4" + position: 2800.00 # m + description: "block clearing point" + groups: ["block 1"] + measure: rear + - id: "vp6" + position: 3750.00 # m + description: "view point distant signal 6" + groups: ["station B", "route 2"] + measure: front + - id: "ds6" + position: 4000.00 # m + description: "distant signal 6" + groups: ["station B", "route 2"] + measure: front + - id: "vp9" + position: 4750.00 # m + description: "view point distant signal 9" + groups: ["block 3"] + measure: front + - id: "s6" + position: 5000.00 # m + description: "route signal 6 and distant signal 9" + groups: ["station B", "route 2", "route 3", "block 3"] + measure: front + - id: "cp5" + position: 5100.00 # m + description: "block clearing point" + groups: ["block 2", "station B"] + measure: rear + - id: "cp6" + position: 5170.00 # m + description: "route clearing point" + groups: ["route 2", "station B"] + measure: rear + - id: "b1" + position: 5500.00 # m + description: "plattform track 1" + groups: ["station B"] + measure: middle + - id: "s9" + position: 5650.00 # m + description: "route signal 9" + groups: ["station B", "block 3", "route 3"] + measure: front + - id: "cp8" + position: 5750.00 # m + description: "block clearing point" + groups: ["station B"] + measure: rear + - id: "vp12" + position: 5800.00 # m + description: "view point distant signal 12" + groups: ["block 4"] + measure: front + - id: "cp10" + position: 5810.00 # m + description: "route clearing point" + groups: ["station B", "block 3", "route 3"] + measure: rear + - id: "ds12" + position: 6100.00 # m + description: "distant signal 12" + groups: ["block 4"] + measure: front + - id: "s12" + position: 7100.00 # m + description: "block signal 12" + groups: ["block 4"] + measure: front + - id: "cp11" + position: 7200.00 # m + description: "block clearing point" + groups: ["block 3"] + measure: rear + - id: "vp14" + position: 8100.00 # m + description: "view point distant signal 14" + groups: ["station C", "route 4"] + measure: front + - id: "ds14" + position: 8400.00 # m + description: "distant signal 14" + groups: ["station C", "route 4"] + measure: front + - id: "s14" + position: 9400.00 # m + description: "block signal 14" + groups: ["station C", "route 4"] + measure: front + - id: "cp12" + position: 9500.00 # m + description: "block clearing point" + groups: ["block 4"] + measure: rear + - id: "cp13" + position: 9560.00 # m + description: "route clearing point" + groups: ["route 4"] + measure: rear + - id: "c1" + position: 9800.00 # m + description: "plattform track 1" + groups: ["station C"] + measure: middle diff --git a/package.json b/package.json index 4b003b5..1dd5b8d 100644 --- a/package.json +++ b/package.json @@ -4,12 +4,14 @@ "validate:rolling-stock": "ajv --spec=draft2020 -c ajv-formats -s src/rolling-stock.json -d ", "validate:running-path": "ajv --spec=draft2020 -c ajv-formats -s src/running-path.json -d ", "test": "npm-run-all test:**", - "test:stock:example": "ajv test --spec=draft2020 -c ajv-formats -s src/rolling-stock.json -d doc/rolling-stock.example.yaml --valid", + "test:stock:example": "ajv test --spec=draft2020 -c ajv-formats -s src/rolling-stock.json -d \"doc/rolling-stock.example.*.yaml\" --valid", "test:stock:valid": "ajv test --spec=draft2020 -c ajv-formats -s src/rolling-stock.json -d \"test/rolling-stock/valid/*.yaml\" --valid", "test:stock:invalid": "ajv test --spec=draft2020 -c ajv-formats -s src/rolling-stock.json -d \"test/rolling-stock/invalid/*.yaml\" --invalid", + "test:stock": "npm-run-all test:stock:**", "test:paths:example": "ajv test --spec=draft2020 -c ajv-formats -s src/running-path.json -d doc/running-path.example.yaml --valid", "test:paths:valid": "ajv test --spec=draft2020 -c ajv-formats -s src/running-path.json -d \"test/running-path/valid/*.yaml\" --valid", - "test:paths:invalid": "ajv test --spec=draft2020 -c ajv-formats -s src/running-path.json -d \"test/running-path/invalid/*.yaml\" --invalid" + "test:paths:invalid": "ajv test --spec=draft2020 -c ajv-formats -s src/running-path.json -d \"test/running-path/invalid/*.yaml\" --invalid", + "test:paths": "npm-run-all test:paths:**" }, "repository": { "type": "git", diff --git a/src/rolling-stock.json b/src/rolling-stock.json index 7cd2f6e..20cd780 100644 --- a/src/rolling-stock.json +++ b/src/rolling-stock.json @@ -1,46 +1,103 @@ { - "$comment": "================[HEADER]=====================", "$id": "https://railtoolkit.org/schema/rolling-stock.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Rolling Stock", "description": "Rolling stock data", "type": "object", - "$comment": "=================[BODY]======================", - "required": [ "schema", "schema_version" ], + "required": [ "schema", "schema_version", "model_fidelity" ], "anyOf": [ {"required": [ "trains" ] }, {"required": [ "vehicles" ] } ], - "$comment": "in alphabetical order", + "$defs": { + "id": { + "type": "string", + "description": "Identifier of the train or vehicle" + }, + "speed": { + "type": "number", + "description": "Speed in kilometers per hour" + }, + "time": { + "type": "number", + "description": "Time in seconds" + }, + "length": { + "type": "number", + "description": "Length in meters" + }, + "mass": { + "type": "number", + "description": "Mass in metric tons" + }, + "force": { + "type": "number", + "description": "Force in kN" + }, + "power": { + "type": "number", + "description": "Power in kW" + }, + "resistance": { + "type": "number", + "description": "Resistance in per mille" + }, + "acceleration": { + "type": "number", + "description": "Acceleration in m/s²" + }, + "effort": { + "type": "array", + "items": { + "type": "object", + "required": ["speed", "force"], + "properties": { + "speed": { "$ref": "#/$defs/speed", "minimum": 0 }, + "force": { "$ref": "#/$defs/force" } + } + } + } + }, "properties": { "schema": { "description": "Identifier of the schema", - "enum": [ "https://railtoolkit.org/schema/rolling-stock.json" ] + "const": "https://railtoolkit.org/schema/rolling-stock.json" }, "schema_version": { "description": "Version of the schema", "type": "string", + "const": "2024.07", "pattern": "[2-9][0-9][0-9][0-9].[0-1][0-9]" }, + "model_fidelity": { + "description": "Level of detail for train dynamics modeling. Defaults to 'detailed' if not specified", + "type": "string", + "enum": [ "simplified", "detailed" ] + }, "trains": { "type": "array", "minItems": 1, "items": { - "required": [ "name", "id", "formation" ], "type": "object", + "required": [ "id" ], + "anyOf": [ + {"required": [ "formation" ]}, + {"required": [ "simplified_characteristics" ]} + ], "properties": { - "id": { - "description": "Identifier of the train", - "type": "string" - }, - "name": { - "description": "Name of the train", + "id": { "$ref": "#/$defs/id" }, + "description": { + "description": "Description of the train", "type": "string" }, - "UUID": { - "description": "The unique identifier for a train", + "train_type": { + "description": "Type of train service", "type": "string", - "format": "uuid" + "enum": [ + "long_distance", "regional", "suburban", "metro", + "intermodal", "heavy_freight", "block_freight", "shunting", + "maintenance", "construction", "emergency", "snow_removal" + ] }, "formation": { "description": "Collection of vehicles that form the train", @@ -50,53 +107,88 @@ "items": { "type": "string" } + }, + "loading_factor": { + "description": "Loading factor of the train", + "type": "array", + "minItems": 1, + "uniqueItems": false, + "items": { + "type": "number", + "minimum": 0, + "maximum": 1 + } + }, + "simplified_characteristics": { + "description": "Basic motion parameters when using simplified model fidelity", + "type": "object", + "required": ["speed_limit", "length", "acceleration", "deceleration"], + "properties": { + "speed_limit": { + "$ref": "#/$defs/speed", + "exclusiveMinimum": 0 + }, + "length": { + "$ref": "#/$defs/length", + "exclusiveMinimum": 0 + }, + "acceleration": { + "$ref": "#/$defs/acceleration", + "exclusiveMinimum": 0 + }, + "deceleration": { + "$ref": "#/$defs/acceleration", + "exclusiveMaximum": 0 + }, + "emergency_deceleration": { + "$ref": "#/$defs/acceleration", + "exclusiveMaximum": 0 + }, + "coasting": { + "$ref": "#/$defs/acceleration", + "exclusiveMaximum": 0, + "default": 0 + } + } } } } }, "vehicles": { - "type": "array", + "type": "array", "minItems": 1, "items": { - "required": [ "name", "id", "vehicle_type", "length", "mass" ], + "required": ["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": { "$ref": "#/$defs/id" }, + "load_limit": { + "$ref": "#/$defs/mass", + "default": 0 }, - "id": { - "description": "Identifier of the vehicle", - "type": "string" + "vehicle_type": { + "description": "Type of vehicle", + "enum": ["traction_unit", "freight", "passenger", "multiple_unit", "non-revenue"] }, "length": { - "description": "The length of the vehicle in meter", - "type": "number", + "$ref": "#/$defs/length", "exclusiveMinimum": 0 }, - "load_limit": { - "description": "The maximum permitted load of the vehicle in metric ton", - "type": "number", + "mass": { + "$ref": "#/$defs/mass", "exclusiveMinimum": 0 }, "mass_traction": { - "description": "The mass on the powered axles of the vehicle in metric ton", - "type": "number", - "exclusiveMinimum": 0 + "$ref": "#/$defs/mass", + "exclusiveMinimum": 0, + "default": 0 }, - "mass": { - "description": "The empty mass of the vehicle in metric ton", - "type": "number", + "speed_limit": { + "$ref": "#/$defs/speed", "exclusiveMinimum": 0 }, - "name": { - "description": "Name of the vehicle", + "description": { + "description": "Description of the vehicle", "type": "string" }, "picture": { @@ -106,47 +198,146 @@ }, "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 + "enum": ["hydraulic", "electric", "steam", "misc"] }, - "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": { + "resistance": { + "type": "object", + "required": ["model_fidelity"], + "anyOf": [ + {"required": [ "rotation_mass", "base_resistance", "rolling_resistance", "air_resistance" ] }, + {"required": [ "resistance_effort" ] } + ], + "properties": { + "model_fidelity": { + "type": "string", + "enum": ["table", "calculated"] + }, + "rotation_mass": { + "type": "number", + "minimum": 1 + }, + "base_resistance": { + "type": "number", + "minimum": 0 + }, + "rolling_resistance": { + "type": "number", + "minimum": 0 + }, + "air_resistance": { "type": "number", "minimum": 0 + }, + "resistance_effort": { + "$ref": "#/$defs/effort" } } }, - "UUID": { - "description": "The unique identifier for a vehicle", - "type": "string", - "format": "uuid" + "traction": { + "type": "object", + "required": ["model_fidelity"], + "properties": { + "model_fidelity": { + "type": "string", + "enum": ["table", "calculated"] + }, + "rated_power": { + "$ref": "#/$defs/power", + "minimum": 0 + }, + "initial_tractive_force": { + "$ref": "#/$defs/force", + "minimum": 0 + }, + "tractive_effort": { + "$ref": "#/$defs/effort" + } + } }, - "vehicle_type": { - "description": "Type of vehicle", - "enum": [ "traction unit", "freight", "passenger", "multiple unit" ] + "brakes": { + "type": "object", + "required": ["model_fidelity"], + "anyOf": [ + {"required": [ "deceleration" ] }, + {"required": [ "eddy_current_brake" ] }, + {"required": [ "electrodynamic_brake" ] }, + {"required": [ "friction_brake" ] } + ], + "properties": { + "model_fidelity": { + "type": "string", + "enum": ["force", "one-part-deceleration", "two-part-deceleration", "three-part-deceleration"] + }, + "reaction_time": { "$ref": "#/$defs/time", "minimum": 0 }, + "response_time": { "$ref": "#/$defs/time", "minimum": 0 }, + "threshold_time": { "$ref": "#/$defs/time", "minimum": 0 }, + "deceleration": { "$ref": "#/$defs/acceleration", "maximum": 0 }, + "emergency_deceleration": { "$ref": "#/$defs/acceleration", "maximum": 0 }, + "eddy_current_brake": { + "type": "object", + "required": ["model_fidelity"], + "anyOf": [ + {"required": [ "min_speed", "max_brake_effort", "power", "brake_effort" ] }, + {"required": [ "brake_effort" ] } + ], + "properties": { + "model_fidelity": { + "type": "string", + "enum": ["table", "calculated"] + }, + "min_speed": { "type": "number", "minimum": 0 }, + "max_brake_effort": { "type": "number", "minimum": 0 }, + "power": { "type": "number", "minimum": 0 }, + "brake_effort": { + "$ref": "#/$defs/effort" + } + } + }, + "electrodynamic_brake": { + "type": "object", + "required": ["model_fidelity"], + "anyOf": [ + {"required": [ "max_brake_force", "speed_control_range", "speed_power_limit", "speed_field_weakening", "brake_effort" ] }, + {"required": [ "brake_effort" ] } + ], + "properties": { + "model_fidelity": { + "type": "string", + "enum": ["table", "calculated"] + }, + "max_brake_force": { "type": "number", "minimum": 0 }, + "speed_control_range": { "type": "number", "minimum": 0 }, + "speed_power_limit": { "type": "number", "minimum": 0 }, + "speed_field_weakening": { "type": "number", "minimum": 0 }, + "brake_effort": { + "$ref": "#/$defs/effort" + } + } + }, + "friction_brake": { + "type": "object", + "required": ["model_fidelity"], + "anyOf": [ + {"required": [ "service_brake_effort", "emergency_brake_effort", "brake_regime" ] }, + {"required": [ "brake_effort" ] } + ], + "properties": { + "model_fidelity": { + "type": "string", + "enum": ["table", "calculated"] + }, + "service_brake_effort": { "type": "number", "minimum": 0 }, + "emergency_brake_effort": { "type": "number", "minimum": 0 }, + "brake_regime": { + "type": "string", + "enum": ["P", "G", "R"] + }, + "brake_effort": { + "$ref": "#/$defs/effort" + } + } + } + } } } } diff --git a/src/running-path.json b/src/running-path.json index 2060801..64e6d94 100644 --- a/src/running-path.json +++ b/src/running-path.json @@ -4,6 +4,24 @@ "title": "Running Path", "description": "Consecutive values of permitted speed and resistance", "type": "object", + "$defs": { + "id": { + "type": "string", + "description": "Identifier of the train or vehicle" + }, + "speed": { + "type": "number", + "description": "Speed in kilometers per hour" + }, + "length": { + "type": "number", + "description": "Length in meters" + }, + "resistance": { + "type": "number", + "description": "Resistance in per mille" + } + }, "required": [ "schema", "schema_version", "paths" ], "properties": { "schema": { @@ -18,16 +36,13 @@ }, "paths": { "type": "array", - "minItems": 1, + "minItems": 0, "uniqueItems": true, "items": { "required": [ "id", "characteristic_sections" ], "type": "object", "properties": { - "id": { - "description": "Identifier of the running path", - "type": "string" - }, + "id": { "$ref": "#/$defs/id" }, "description": { "description": "Description of the running path", "type": "string" @@ -39,25 +54,20 @@ "uniqueItems": true, "items": { "type": "object", - "anyOf": [ - {"required": [ "position", "speed" ] }, - {"required": [ "position", "resistance" ] }, - {"required": [ "position", "speed", "resistance" ] } + "allOf": [ + {"required": ["position"]}, + {"anyOf": [ + {"required": ["speed"]}, + {"required": ["resistance"]} + ]} ], "properties": { - "position": { - "description": "mileage in meter", - "type": "number" - }, + "position": { "$ref": "#/$defs/length" }, "speed": { - "description": "speed in kilometers per hour", - "type": "number", - "exclusiveMinimum": 0 + "$ref": "#/$defs/speed", + "minimum": 0 }, - "resistance": { - "description": "resistance in permil", - "type": "number" - } + "resistance": { "$ref": "#/$defs/resistance" } } } }, @@ -69,17 +79,24 @@ "type": "object", "required": [ "position", - "label", + "id", "measure" ], "properties": { - "position": { - "description": "mileage in meter", - "type": "number" - }, - "label": { + "id": { "$ref": "#/$defs/id" }, + "position": { "$ref": "#/$defs/length" }, + "description": { + "description": "Description of the point of interest", "type": "string" }, + "groups": { + "description": "Groups this point belongs to", + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + }, "measure": { "enum": [ "front", "middle", "rear" ] } diff --git a/test/rolling-stock/invalid/formation_empty.yaml b/test/rolling-stock/invalid/formation_empty.yaml index c539e1c..839fb09 100644 --- a/test/rolling-stock/invalid/formation_empty.yaml +++ b/test/rolling-stock/invalid/formation_empty.yaml @@ -1,8 +1,8 @@ %YAML 1.2 --- schema: https://railtoolkit.org/schema/rolling-stock.json -schema_version: "2022.05" +schema_version: "2024.07" +model_fidelity: "detailed" trains: - - name: test - id: "1" - formation: [] + - id: "1" + formation: [] # Invalid: formation array must have at least 1 item diff --git a/test/rolling-stock/invalid/formation_missing.yaml b/test/rolling-stock/invalid/formation_missing.yaml index 73cc5ae..fd2111e 100644 --- a/test/rolling-stock/invalid/formation_missing.yaml +++ b/test/rolling-stock/invalid/formation_missing.yaml @@ -1,7 +1,7 @@ %YAML 1.2 --- schema: https://railtoolkit.org/schema/rolling-stock.json -schema_version: "2022.05" +schema_version: "2024.07" +model_fidelity: "detailed" trains: - - name: test - id: "1" + - id: "1" # Invalid: missing either formation or simplified_characteristics diff --git a/test/rolling-stock/invalid/invalid_brake_model.yaml b/test/rolling-stock/invalid/invalid_brake_model.yaml new file mode 100644 index 0000000..39d10fa --- /dev/null +++ b/test/rolling-stock/invalid/invalid_brake_model.yaml @@ -0,0 +1,13 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "2024.07" +vehicles: + - id: "vehicle1" + vehicle_type: "traction unit" + length: 20 + mass: 80 + brakes: + model_fidelity: "invalid_type" # Invalid brake model type + reaction_time: 1.0 + deceleration: -0.5 \ No newline at end of file diff --git a/test/rolling-stock/invalid/invalid_deceleration.yaml b/test/rolling-stock/invalid/invalid_deceleration.yaml new file mode 100644 index 0000000..cba00cb --- /dev/null +++ b/test/rolling-stock/invalid/invalid_deceleration.yaml @@ -0,0 +1,14 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "2024.07" +model_fidelity: "simplified" +trains: + - id: "train1" + train_type: "regional" + simplified_characteristics: + speed_limit: 160 + length: 200 + acceleration: 0.5 + deceleration: 0.65 # Invalid: should be negative + coasting: -0.1 \ No newline at end of file diff --git a/test/rolling-stock/invalid/invalid_emergency_brake.yaml b/test/rolling-stock/invalid/invalid_emergency_brake.yaml new file mode 100644 index 0000000..10cac1c --- /dev/null +++ b/test/rolling-stock/invalid/invalid_emergency_brake.yaml @@ -0,0 +1,14 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "2024.07" +model_fidelity: "simplified" +trains: + - id: "train1" + train_type: "regional" + simplified_characteristics: + speed_limit: 160 + length: 200 + acceleration: 0.5 + deceleration: -0.65 + emergency_deceleration: 1.55 # should be negative \ No newline at end of file diff --git a/test/rolling-stock/invalid/invalid_loading_factor.yaml b/test/rolling-stock/invalid/invalid_loading_factor.yaml new file mode 100644 index 0000000..8755925 --- /dev/null +++ b/test/rolling-stock/invalid/invalid_loading_factor.yaml @@ -0,0 +1,9 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "2024.07" +trains: + - id: "train1" + train_type: "regional" + formation: ["vehicle1"] + loading_factor: [] # Invalid: array must have at least 1 item \ No newline at end of file diff --git a/test/rolling-stock/invalid/invalid_model_fidelity.yaml b/test/rolling-stock/invalid/invalid_model_fidelity.yaml new file mode 100644 index 0000000..bd1d99a --- /dev/null +++ b/test/rolling-stock/invalid/invalid_model_fidelity.yaml @@ -0,0 +1,9 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "2024.07" +model_fidelity: "effort_tables" # invalid value +trains: + - id: "train1" + train_type: "regional" + formation: ["vehicle1"] \ No newline at end of file diff --git a/test/rolling-stock/invalid/invalid_power_type.yaml b/test/rolling-stock/invalid/invalid_power_type.yaml new file mode 100644 index 0000000..15088b9 --- /dev/null +++ b/test/rolling-stock/invalid/invalid_power_type.yaml @@ -0,0 +1,10 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "2024.07" +vehicles: + - id: "vehicle1" + vehicle_type: "traction_unit" + length: 20 + mass: 80 + power_type: "diesel" # Invalid power type - not in enum \ No newline at end of file diff --git a/test/rolling-stock/invalid/invalid_resistance_model.yaml b/test/rolling-stock/invalid/invalid_resistance_model.yaml new file mode 100644 index 0000000..3e90dd1 --- /dev/null +++ b/test/rolling-stock/invalid/invalid_resistance_model.yaml @@ -0,0 +1,12 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "2024.07" +vehicles: + - id: "vehicle1" + vehicle_type: "traction_unit" + length: 20 + mass: 80 + resistance: + model_fidelity: "invalid_model" # Invalid model_fidelity + rotation_mass: 1.1 \ No newline at end of file diff --git a/test/rolling-stock/invalid/invalid_schema_version.yaml b/test/rolling-stock/invalid/invalid_schema_version.yaml new file mode 100644 index 0000000..6d7df86 --- /dev/null +++ b/test/rolling-stock/invalid/invalid_schema_version.yaml @@ -0,0 +1,8 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "24.7" # Invalid format - should be YYYY.MM +trains: + - id: "train1" + train_type: "regional" + formation: ["vehicle1"] \ No newline at end of file diff --git a/test/rolling-stock/invalid/invalid_tractive_effort.yaml b/test/rolling-stock/invalid/invalid_tractive_effort.yaml new file mode 100644 index 0000000..9cc0790 --- /dev/null +++ b/test/rolling-stock/invalid/invalid_tractive_effort.yaml @@ -0,0 +1,13 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "2024.07" +vehicles: + - id: "vehicle1" + vehicle_type: "traction_unit" + length: 20 + mass: 80 + tractive_effort: [ + [0, 300], # Invalid: needs at least 3 points + [50, 200] + ] \ No newline at end of file diff --git a/test/rolling-stock/invalid/invalid_train_type.yaml b/test/rolling-stock/invalid/invalid_train_type.yaml new file mode 100644 index 0000000..ae10ea7 --- /dev/null +++ b/test/rolling-stock/invalid/invalid_train_type.yaml @@ -0,0 +1,13 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "2024.07" +model_fidelity: "simplified_characteristics" +trains: + - id: "train1" + train_type: "high_speed" + simplified_characteristics: + v_max: 160 + length: 200 + acceleration: 0.5 + deceleration: -0.65 \ No newline at end of file diff --git a/test/rolling-stock/invalid/length.yaml b/test/rolling-stock/invalid/length.yaml index 2bacdbc..fd3e0f6 100644 --- a/test/rolling-stock/invalid/length.yaml +++ b/test/rolling-stock/invalid/length.yaml @@ -1,9 +1,12 @@ %YAML 1.2 --- schema: https://railtoolkit.org/schema/rolling-stock.json -schema_version: "2022.05" +schema_version: "2024.07" +model_fidelity: "detailed" vehicles: - - name: test - id: "1" - vehicle_type: freight - mass: 1 + - id: "1" + vehicle_type: "freight" + mass: 80 + speed_limit: 100 + load_limit: 100 + # length missing - required field diff --git a/test/rolling-stock/invalid/mass.yaml b/test/rolling-stock/invalid/mass.yaml index 05a0370..b393e5b 100644 --- a/test/rolling-stock/invalid/mass.yaml +++ b/test/rolling-stock/invalid/mass.yaml @@ -1,9 +1,12 @@ %YAML 1.2 --- schema: https://railtoolkit.org/schema/rolling-stock.json -schema_version: "2022.05" +schema_version: "2024.07" +model_fidelity: "detailed" vehicles: - - name: test - id: "1" - vehicle_type: freight - length: 1 + - id: "1" + vehicle_type: "freight" + length: 20 + speed_limit: 100 + load_limit: 100 + # mass missing - required field diff --git a/test/rolling-stock/invalid/minimal.yaml b/test/rolling-stock/invalid/minimal.yaml index 49a646e..9961afb 100644 --- a/test/rolling-stock/invalid/minimal.yaml +++ b/test/rolling-stock/invalid/minimal.yaml @@ -1,4 +1,5 @@ %YAML 1.2 --- schema: https://railtoolkit.org/schema/rolling-stock.json -schema_version: "2022.05" +schema_version: "2024.07" +# Invalid: missing required fields model_fidelity and either trains or vehicles diff --git a/test/rolling-stock/invalid/missing_model_fidelity.yaml b/test/rolling-stock/invalid/missing_model_fidelity.yaml new file mode 100644 index 0000000..218dda0 --- /dev/null +++ b/test/rolling-stock/invalid/missing_model_fidelity.yaml @@ -0,0 +1,9 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "2024.07" +# model_fidelity missing - required field +trains: + - id: "train1" + train_type: "regional" + formation: ["vehicle1"] \ No newline at end of file diff --git a/test/rolling-stock/invalid/missing_simplified_chars.yaml b/test/rolling-stock/invalid/missing_simplified_chars.yaml new file mode 100644 index 0000000..943654d --- /dev/null +++ b/test/rolling-stock/invalid/missing_simplified_chars.yaml @@ -0,0 +1,13 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "2024.07" +model_fidelity: "simplified" +trains: + - id: "train1" + train_type: "regional" + simplified_characteristics: + speed_limit: 160 + length: 200 + acceleration: 0.5 + # missing required deceleration \ No newline at end of file diff --git a/test/rolling-stock/invalid/neither_formation_nor_simplified.yaml b/test/rolling-stock/invalid/neither_formation_nor_simplified.yaml new file mode 100644 index 0000000..53e91cd --- /dev/null +++ b/test/rolling-stock/invalid/neither_formation_nor_simplified.yaml @@ -0,0 +1,9 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "2024.07" +model_fidelity: "detailed" +trains: + - id: "train1" + train_type: "regional" + description: "Missing both formation and simplified_characteristics" \ No newline at end of file diff --git a/test/rolling-stock/invalid/vehicle_type.yaml b/test/rolling-stock/invalid/vehicle_type.yaml index cc353c3..74eb9d2 100644 --- a/test/rolling-stock/invalid/vehicle_type.yaml +++ b/test/rolling-stock/invalid/vehicle_type.yaml @@ -1,10 +1,12 @@ %YAML 1.2 --- schema: https://railtoolkit.org/schema/rolling-stock.json -schema_version: "2022.05" +schema_version: "2024.07" +model_fidelity: "detailed" vehicles: - - name: test - id: "1" - vehicle_type: cargo - length: 1 - mass: 1 + - id: "1" + vehicle_type: "cargo" # Invalid - not in enum + length: 20 + mass: 80 + speed_limit: 100 + load_limit: 100 diff --git a/test/rolling-stock/valid/default_model_fidelity.yaml b/test/rolling-stock/valid/default_model_fidelity.yaml new file mode 100644 index 0000000..96c569e --- /dev/null +++ b/test/rolling-stock/valid/default_model_fidelity.yaml @@ -0,0 +1,14 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "2024.07" +model_fidelity: "detailed" +trains: + - id: "train1" + train_type: "regional" + formation: ["vehicle1"] +vehicles: + - id: "vehicle1" + vehicle_type: "traction_unit" + length: 20 + mass: 80 \ No newline at end of file diff --git a/test/rolling-stock/valid/detailed_vehicle.yaml b/test/rolling-stock/valid/detailed_vehicle.yaml new file mode 100644 index 0000000..5eb5081 --- /dev/null +++ b/test/rolling-stock/valid/detailed_vehicle.yaml @@ -0,0 +1,35 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "2024.07" +model_fidelity: "detailed" +vehicles: + - id: "vehicle1" + vehicle_type: "traction_unit" + length: 20 + mass: 80 + load_limit: 100 + speed_limit: 160 + power_type: "electric" + resistance: + model_fidelity: "calculated" + rotation_mass: 1.1 + base_resistance: 2.5 + rolling_resistance: 0.001 + air_resistance: 0.004 + traction: + model_fidelity: "table" + tractive_effort: + - speed: 0 + force: 300 + - speed: 50 + force: 200 + - speed: 100 + force: 100 + brakes: + model_fidelity: "force" + friction_brake: + model_fidelity: "calculated" + service_brake_effort: 150 + emergency_brake_effort: 200 + brake_regime: "P" \ No newline at end of file diff --git a/test/rolling-stock/valid/formation.yaml b/test/rolling-stock/valid/formation.yaml new file mode 100644 index 0000000..27e68ac --- /dev/null +++ b/test/rolling-stock/valid/formation.yaml @@ -0,0 +1,21 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "2024.07" +model_fidelity: "detailed" +trains: + - id: "train1" + train_type: "regional" + description: "Test train with formation" + formation: ["vehicle1", "vehicle2"] +vehicles: + - id: "vehicle1" + vehicle_type: "traction_unit" + length: 20 + mass: 80 + load_limit: 0 + - id: "vehicle2" + vehicle_type: "passenger" + length: 26.4 + mass: 32 + load_limit: 10 \ No newline at end of file diff --git a/test/rolling-stock/valid/mixed_fidelity.yaml b/test/rolling-stock/valid/mixed_fidelity.yaml new file mode 100644 index 0000000..fbb2f71 --- /dev/null +++ b/test/rolling-stock/valid/mixed_fidelity.yaml @@ -0,0 +1,21 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "2024.07" +model_fidelity: "simplified" +trains: + - id: "train1" + train_type: "regional" + simplified_characteristics: + speed_limit: 140 + length: 150 + acceleration: 0.4 + deceleration: -0.6 + - id: "train2" + train_type: "long_distance" + formation: ["vehicle1"] +vehicles: + - id: "vehicle1" + vehicle_type: "multiple_unit" + length: 25 + mass: 85 \ No newline at end of file diff --git a/test/rolling-stock/valid/simplified_characteristics.yaml b/test/rolling-stock/valid/simplified_characteristics.yaml new file mode 100644 index 0000000..13c5dc1 --- /dev/null +++ b/test/rolling-stock/valid/simplified_characteristics.yaml @@ -0,0 +1,15 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "2024.07" +model_fidelity: "simplified" +trains: + - id: "train1" + train_type: "long_distance" + description: "Test train with simplified characteristics" + simplified_characteristics: + speed_limit: 160 + length: 200 + acceleration: 0.5 + deceleration: -0.65 + coasting: -0.04 \ No newline at end of file diff --git a/test/rolling-stock/valid/simplified_train.yaml b/test/rolling-stock/valid/simplified_train.yaml new file mode 100644 index 0000000..96ea825 --- /dev/null +++ b/test/rolling-stock/valid/simplified_train.yaml @@ -0,0 +1,15 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "2024.07" +model_fidelity: "simplified" +trains: + - id: "train1" + train_type: "regional" + simplified_characteristics: + speed_limit: 160 + length: 200 + acceleration: 0.5 + deceleration: -0.65 + emergency_deceleration: -1.2 + coasting: -0.1 \ No newline at end of file diff --git a/test/rolling-stock/valid/simplified_with_emergency_brake.yaml b/test/rolling-stock/valid/simplified_with_emergency_brake.yaml new file mode 100644 index 0000000..38f0c9d --- /dev/null +++ b/test/rolling-stock/valid/simplified_with_emergency_brake.yaml @@ -0,0 +1,15 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/rolling-stock.json +schema_version: "2024.07" +model_fidelity: "simplified" +trains: + - id: "train1" + train_type: "long_distance" + simplified_characteristics: + speed_limit: 160 + length: 200 + acceleration: 0.5 + deceleration: -0.65 + emergency_deceleration: -1.55 + coasting: -0.04 \ No newline at end of file diff --git a/test/rolling-stock/valid/trains.yaml b/test/rolling-stock/valid/trains.yaml index d30aece..3841a35 100644 --- a/test/rolling-stock/valid/trains.yaml +++ b/test/rolling-stock/valid/trains.yaml @@ -1,8 +1,10 @@ %YAML 1.2 --- schema: https://railtoolkit.org/schema/rolling-stock.json -schema_version: "2022.05" +schema_version: "2024.07" +model_fidelity: "detailed" trains: - name: test id: "1" formation: ["1"] + train_type: "maintenance" diff --git a/test/rolling-stock/valid/vehicles.yaml b/test/rolling-stock/valid/vehicles.yaml index 1988129..48d03eb 100644 --- a/test/rolling-stock/valid/vehicles.yaml +++ b/test/rolling-stock/valid/vehicles.yaml @@ -1,7 +1,8 @@ %YAML 1.2 --- schema: https://railtoolkit.org/schema/rolling-stock.json -schema_version: "2022.05" +schema_version: "2024.07" +model_fidelity: "detailed" vehicles: - name: test id: "1" diff --git a/test/running-path/invalid/invalid-enums.yaml b/test/running-path/invalid/invalid-enums.yaml new file mode 100644 index 0000000..dcf9017 --- /dev/null +++ b/test/running-path/invalid/invalid-enums.yaml @@ -0,0 +1,11 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/running-path.json +schema_version: "2024.07" +paths: + - id: "invalid-enums" + points_of_interest: + - position: 1000.0 + id: "point1" + measure: invalid # Invalid measure value + groups: [] # Empty groups array \ No newline at end of file diff --git a/test/running-path/invalid/logical-errors.yaml b/test/running-path/invalid/logical-errors.yaml new file mode 100644 index 0000000..9da06e9 --- /dev/null +++ b/test/running-path/invalid/logical-errors.yaml @@ -0,0 +1,10 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/running-path.json +schema_version: "2024.07" +paths: + - id: "logical-errors" + characteristic_sections: + - position: 0.0 # m + speed: -160 # km/h (invalid negative speed) + resistance: 1.00 # ‰ \ No newline at end of file diff --git a/test/running-path/invalid/missing-required.yaml b/test/running-path/invalid/missing-required.yaml new file mode 100644 index 0000000..8e4ecd8 --- /dev/null +++ b/test/running-path/invalid/missing-required.yaml @@ -0,0 +1,8 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/running-path.json +paths: + - id: "missing-required" + characteristic_sections: + - position: 0.0 + speed: 160 \ No newline at end of file diff --git a/test/running-path/invalid/not_null_speed.yaml b/test/running-path/invalid/not_null_speed.yaml index b746867..b510441 100644 --- a/test/running-path/invalid/not_null_speed.yaml +++ b/test/running-path/invalid/not_null_speed.yaml @@ -7,6 +7,6 @@ paths: id: "1" characteristic_sections: - position: 0.0 - speed: 0 + speed: -0.1 - position: 0.1 speed: 0 diff --git a/test/running-path/invalid/wrong-types.yaml b/test/running-path/invalid/wrong-types.yaml new file mode 100644 index 0000000..8baa6de --- /dev/null +++ b/test/running-path/invalid/wrong-types.yaml @@ -0,0 +1,11 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/running-path.json +schema_version: "2024.07" +paths: + - id: "wrong-types" + characteristic_sections: + - position: "not a number" + speed: "160" + - position: 1000.0 + resistance: "invalid" \ No newline at end of file diff --git a/test/running-path/valid/basic.yaml b/test/running-path/valid/basic.yaml new file mode 100644 index 0000000..20dc786 --- /dev/null +++ b/test/running-path/valid/basic.yaml @@ -0,0 +1,12 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/running-path.json +schema_version: "2024.07" +paths: + - id: "test-path" + characteristic_sections: + - position: 0.0 # m + speed: 160 # km/h + - position: 1000.0 # m + speed: 120 # km/h + resistance: 2.0 # ‰ \ No newline at end of file diff --git a/test/running-path/valid/complete.yaml b/test/running-path/valid/complete.yaml new file mode 100644 index 0000000..6764da2 --- /dev/null +++ b/test/running-path/valid/complete.yaml @@ -0,0 +1,27 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/running-path.json +schema_version: "2024.07" +paths: + - id: "complete" + description: "Complete test case with all fields" + points_of_interest: + - position: 850.00 + id: "vp11" + description: "Viewpoint" + groups: ["block 11", "view points"] + measure: front + - position: 1000.00 + id: "ds11" + description: "Signal" + groups: ["block 11", "signals"] + measure: middle + characteristic_sections: + - position: 0.0 + speed: 160 + resistance: 0.00 + section_id: "line_1" + - position: 1000.0 + speed: 120 + resistance: 1.00 + section_id: "line_1" \ No newline at end of file diff --git a/test/running-path/valid/consistency.yaml b/test/running-path/valid/consistency.yaml new file mode 100644 index 0000000..076fd96 --- /dev/null +++ b/test/running-path/valid/consistency.yaml @@ -0,0 +1,20 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/running-path.json +schema_version: "2024.07" +paths: + - id: "consistency" + points_of_interest: + - position: 2000.0 # Position within characteristic sections range + id: "point1" + measure: front + - position: 500.0 + id: "point2" + measure: front + characteristic_sections: + - position: 0.0 + speed: 160 + - position: 1000.0 + speed: 160 + - position: 500.0 # Decreasing position value (invalid) + speed: 160 \ No newline at end of file diff --git a/test/running-path/valid/edge-cases.yaml b/test/running-path/valid/edge-cases.yaml new file mode 100644 index 0000000..3a4f6f9 --- /dev/null +++ b/test/running-path/valid/edge-cases.yaml @@ -0,0 +1,23 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/running-path.json +schema_version: "2024.07" +paths: + - id: "edge-cases" + description: "Test with edge cases" + points_of_interest: + - position: 1000.00 + id: "point1" + description: "Unicode test: äöüß" + groups: ["group1", "group2", "group3"] + measure: front + - position: 1000.00 + id: "point2" + measure: rear + characteristic_sections: + - position: 0.0 + speed: 999999 + resistance: 0.00 + - position: 999999.999 + speed: 0.1 + resistance: -999.99 \ No newline at end of file diff --git a/test/running-path/valid/minimal.yaml b/test/running-path/valid/minimal.yaml new file mode 100644 index 0000000..6f9bb01 --- /dev/null +++ b/test/running-path/valid/minimal.yaml @@ -0,0 +1,11 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/running-path.json +schema_version: "2024.07" +paths: + - id: "minimal" + characteristic_sections: + - position: 0.0 + speed: 160 + - position: 1000.0 + speed: 160 \ No newline at end of file diff --git a/test/running-path/valid/with_points.yaml b/test/running-path/valid/with_points.yaml new file mode 100644 index 0000000..eb0dd7a --- /dev/null +++ b/test/running-path/valid/with_points.yaml @@ -0,0 +1,16 @@ +%YAML 1.2 +--- +schema: https://railtoolkit.org/schema/running-path.json +schema_version: "2024.07" +paths: + - id: "test-path" + description: "Test path with points of interest" + characteristic_sections: + - position: 0.0 # m + speed: 160 # km/h + - position: 1000.0 # m + speed: 120 # km/h + points_of_interest: + - position: 500.0 # m + id: "point-1" + measure: "front" \ No newline at end of file