• Dateigröße:3 KB
  • Bereitgestellt:03.08.2014
  • Downloads:2763

Diese Schattenbahnhofssteuerung ist ein Lua-Modul, das einfach in eigene Anlagen eingebunden und konfiguriert werden kann. Das Schattenbahnhofs­modul übernimmt bei der Einfahrt die Suche nach dem ersten freien Gleis und stellt die Weichen dorthin, bei der Ausfahrt kümmert es sich um die zufällige Auswahl eines Zuges im Schattenbahnhof und schickt diesen los.

Die Konfiguration ist für den Standardfall eines Schattenbahnhofs extrem einfach gehalten, und auch kleinere Abweichungen können durch wenige zusätzliche Parameter berücksichtigt werden. Wer es ganz individuell mag, kann auch alles bis ins kleinste Detail selbst konfigurieren.

Schnellstartanleitung

1. Installation

Nach dem Download die zip-Datei entpacken und die Installation.eep aufrufen, oder die Schattenbahnhofssteuerung_BH2.lua von Hand ins EEP-Verzeichnis in den Unterordner LUA kopieren.

2. Einbinden

Achtung! Vor diesem Schritt unbedingt die aktuelle Anlage speichern. Wenn das angegebene Skriptfile nicht gefunden wird (weil es nicht existiert, oder man sich verschrieben hat), kann es zum Absturz von EEP kommen!

Füge diese Zeile an den Anfang des Anlagen-Skripts ein:

Schattenbahnhof = require("Schattenbahnhofssteuerung_BH2")

Hat das Einbinden geklappt, erscheint nach dem Neuladen des Skripts im EEP-Ereignis-Fenster der Hinweis Schattenbahnhofssteuerung_BH2 v0.1 wurde eingebunden.

3. Initialisieren

Die Konfiguration des Schattenbahnhofs wird in einer einzigen Variablen gespeichert. Wie du sie nennst, bleibt dir überlassen. Hier im Beispiel nenne ich sie sbf. (Wenn du mehrere Schattenbahnhöfe auf der Anlage hast, kannst du natürlich auch mehrere Variablen mit unterschiedlichen Namen anlegen).

Folgender Code kommt (natürlich in angepasster Form, siehe unten unter „Konfiguration“) irgendwo in den Rumpf des Anlagen-Skripts (nicht in die EEPMain-Funktion):

sbf = Schattenbahnhof:new{
  create={
    numTracks=9,
    signalIdStart=11,
    switchIdStart=1,
  },
}

Ganz so kurz ist die Konfiguration natürlich nur dann, wenn der Schattenbahnhof „ideal“ aufgebaut ist. Aber auch nur „halbideale“ Schattenbahnhöfe lassen sich mit nur ein paar mehr Befehlen konfigurieren. Mehr dazu, wie gesagt, weiter unten im Abschnitt „Konfiguration“.

4. Verwenden

Durch den Aufruf der Funktion sbf:einfahrt() wird das erste freie Gleis im Schattenbahnhof gesucht und die Weichen dorthin gestellt. War dies erfolgreich, gibt die Funktion true zurück, andernfalls false (zum Beispiel dann, wenn alle Gleise schon belegt sind).

Durch den Aufruf der Funktion sbf:ausfahrt() wird ein zufälliges Gleis mit abfahrbereitem Zug im Schattenbahnhof ausgesucht, und das Ausfahrsignal auf Fahrt gestellt. War dies erfolgreich, gibt die Funktion true zurück, andernfalls false (zum Beispiel dann, wenn alle Gleise leer sind).

Da EEP die Verwendung der Funktionen sbf:einfahrt und sbf:ausfahrt innerhalb von Kontaktpunkten mit einer Fehlermeldung quittiert, ist es sinnvoll, wenn du dir zwei Hilfsfunktionen anlegst, die du dann innerhalb von Kontaktpunkten verwenden kannst:

function SbfEinfahrt() sbf:einfahrt() end
function SbfAusfahrt() sbf:ausfahrt() end

Mit einem gewissen Trick (siehe „Funktionsparameter (und noch mehr) in Kontaktpunkten“) kann man sich diese Hilfsfunktionen aber auch sparen und direkt sbf:einfahrt() und sbf:ausfahrt() in die Kontaktpunkte schreiben.

Weiterhin gibt es noch die Funktion sbf:print(), die den Status des Schattenbahnhofs mit allen zugehörigen Gleisen, Signalen und Weichen im Ereignis-Fenster ausgibt. Ohne Parameter wird nur die Anzahl der zu schaltenden Weichen pro Gleis ausgegeben, da diese Weichenliste bei größeren Schattenbahnhöfen ziemlich lang werden kann.

Die Ausgabe von sbf:print() kann beispielsweise so aussehen:

Schattenbahnhof NEBENSTRECKE mit 4 Schattenbahnhofs-Gleisen: (Debug-Level 2)
Gleis 1  |  __  frei   |  Signal-ID: 81, Block-ID: 81, Ready-ID: 81  |  1 Weichen
Gleis 2  |  ## belegt  |  Signal-ID: 82, Block-ID: 82, Ready-ID: 82  |  2 Weichen
Gleis 3  |  ## belegt  |  Signal-ID: 83, Block-ID: 83, Ready-ID: 83  |  3 Weichen
Gleis 4  |  __  frei   |  Signal-ID: 84, Block-ID: 84, Ready-ID: 84  |  4 Weichen

Will man nicht nur die Anzahl der Weichen, sondern eine genaue Auflistung, werden mittels sbf:print(true) zusätzlich alle Weichen-IDs samt benötigter Stellung für jedes Gleis ausgegeben.

Der Aufruf von sbf:print(true) ergibt beispielsweise folgende Ausgabe:

Schattenbahnhof NEBENSTRECKE mit 4 Schattenbahnhofs-Gleisen: (Debug-Level 2)
Gleis 1  |  __  frei   |  Signal-ID: 81, Block-ID: 81, Ready-ID: 81  |  1 Weichen: ID:76->2
Gleis 2  |  ## belegt  |  Signal-ID: 82, Block-ID: 82, Ready-ID: 82  |  2 Weichen: ID:76->1 ID:77->2
Gleis 3  |  ## belegt  |  Signal-ID: 83, Block-ID: 83, Ready-ID: 83  |  3 Weichen: ID:78->2 ID:76->1 ID:77->1
Gleis 4  |  __  frei   |  Signal-ID: 84, Block-ID: 84, Ready-ID: 84  |  4 Weichen: ID:78->1 ID:76->1 ID:77->1 ID:79->2 

Konzept

Die Schattenbahnhofssteuerung besteht aus genau einer Lua-Tabelle, die neben allen wichtigen Informationen auch ein paar Funktionen enthält (nämlich einfahrt(), ausfahrt() und print()).

Um diese Schattenbahnhofs-Informations-Tabelle zu erzeugen, wird eine (einfachere) Tabelle an die Funktion Schattenbahnhof:new() übergeben. In der Funktion wird dann aus den gegebenen Parametern (im create-Schlüssel) entweder die komplette Tabelle neu aufgebaut oder die bereits enthaltenen Informationen werden „nur“ (mehr oder weniger) intelligent um alle anderen Parameter ergänzt. Auf diese Weise kann die Konfiguration einerseits sehr minimalistisch sein, andererseits kann man auch, wenn es nötig ist, alles ganz exakt konfigurieren. Den restlichen Funktionen steht dann immer der volle Informationssatz in der Tabelle zur Verfügung, sodass dort nichts mehr aufwendig „erraten“ werden muss.

Die Schattenbahnhofssteuerung baut darauf auf, den Belegungsstatus der Schattenbahnhofsgleise jederzeit „aus der Anlage auslesen“ zu können, also die benötigten Information durch das Abfragen von Weichen und/oder Signalen zu erhalten.

Dabei wird zwischen bis zu drei verschiedenen Signalen pro Gleis unterschieden:

  • signalID: Das ganz normale Signal, das auf dem Gleis steht und die Züge beeinflusst. Dieses wird bei der Einfahrt auf Halt gestellt, und bei der Ausfahrt wieder auf Fahrt.
  • blockID: Ein Zustandssignal, dass das Gleis als „blockiert“ bzw. „besetzt“ markiert. Dieses wird bei der Einfahrt automatisch auf „Gleis besetzt“ gestellt. Die „Freimeldung“ muss manuell über einen Zugschluss-KP am Ende des Gleises erfolgen.
  • readyID: Noch ein Zustandssignal, dass das Gleis (bzw. den Zug darauf) als abfahrtsbereit markiert. Bei der Abfahrt wird es automatisch auf „nicht bereit“ gestellt (der Zug ist ja gerade abgefahren), die „bereit“-Meldung muss wiederum mit einem Kontaktpunkt erfolgen, wenn der Zug vor dem Signal zu stehen gekommen ist (evtl. mit Zeitverzögerung).

Drei Signale pro Gleis klingen nach ziemlich viel, in den meisten Fällen werden aber gar nicht alle benötigt. Mit leichten Abstrichen in der Sicherheit genügt bereits das eine normale Signal der Zugbeeinflussung, dieses wird dann auch zur Statusbestimmung für die anderen Funktionen herangezogen.

Warum leichte Abstriche? Angenommen, ein Zug erhält Einfahrt auf Gleis 1. Das Signal in Gleis 1 wird dabei auf Halt gestellt, das Gleis gilt als belegt. Wird nun zeitgleich oder kurz danach eine Ausfahrt angefordert, kann es passieren, dass Gleis 1 ausgewählt wird, und das Signal wird wieder auf Fahrt gestellt, bevor der Zug es überhaupt erreichen konnte. Das ist soweit noch nicht so schlimm, dann kann er ohne Halt gleich durchfahren. Wenn jetzt aber kurz darauf noch ein weiterer Zug Einfahrt in den Schattenbahnhof beantragt, wird Gleis 1 als „frei“ erkannt (das Signal steht ja schon wieder auf Fahrt), die Einfahrt dorthin sowie das Signal wieder auf Halt gestellt. Jetzt haben wir die Situation, dass zwei Züge auf das selbe Gleis geleitet werden, wo sie mehr oder weniger „rempelnd“ am Signal halten. Der an der Ausfahrt erwartete Zug wird dort jedoch nie ankommen, solange man nicht von Hand eingreift.

Je nach Zugfolgedichte wird diese Sitation aus Einfahrt, Ausfahrt und nächste Einfahrt kurz hintereinander fast nie auftreten. Dann ist die Lösung mit einem Signal völlig ausreichend.

Will man es ganz sicher haben, braucht man noch ein zweites Signal. Ob man als zweites die Belegtmeldung nimmt oder die Ausfahrbereitschaft, spielt für die Sicherheit keine Rolle. Mit Belegtmeldung können keine zwei Züge gleichzeitig aufs Gleis (aber die Ausfahrt weiterhin schon dann geschaltet werden, wenn der Zug noch unterwegs ist), mit der Abfahrtsbereitschaft kann das Ausfahrsignal nicht zu früh auf Fahrt gestellt werden, kurz danach aber schon ein weiterer Zug in das Gleis einfahren und dem losfahrenden Zug „von hinten Druck machen“. Wenn die Kupplungen auf Abstoßen gestellt sind, ist das aber nur eine optische Sache.

Will man es ganz schön haben, kann man natürlich auch alle drei Signale pro Gleis aufstellen. Nicht vorhandene Signale werden jeweils durch das Zugsignal vertreten.

Konfigurationsmöglichkeiten

Hier erstmal eine Übersicht über alle möglichen Schlüssel in der Schattenbahnhofstabelle, die in der Funktion Schattenbahnhof:new(...) unterstützt, verarbeitet oder ergänzt werden:

sbf = Schattenbahnhof:new{
    create={
        numTracks=3,
        signalIdStart=11,
        signalIdIncrement=1,
        blockIdStart=21,
        blockIdIncrement=1,
        readyIdStart=31,
        readyIdIncrement=1,
        switchIdStart=101,
        switchIdIncrement=1,
        switchPosToTrack=2,
        flipFirstSwitch=false,
        switchForLastTrack=false,
    }
    tracks={
        {
            signalID=11,
            signalPosGo=1,
            signalPosStop=2,
            blockID=21,
            blockPosFree=1,
            blockPosBlocked=2,
            readyID=31,
            readyPosReady=1,
            readyPosWait=2,
            switches={{id=101,pos=2},{id=102,pos=2},{id=103,pos=1}},
            name="Gleis 1",
        },
        {
--          ...,
            switches={{101,2},{102,2},{103,1}}, -- {ID,Stellung}
        },
        {
--          ...,
            switches={[101]=2,[102]=2,[103]=1}, -- [ID]=Stellung
        },
    },
    debugLevel=1, -- 0: no output, 1: only errors, 2: errors and infos
    name="",
}

Kleiner Hinweis am Rande: Lua ist es egal, ob man Schattenbahnhof:new({...}) schreibt, oder die runden Klammern einfach weglässt: Schattenbahnhof:new{...}

In der ersten Ebene der Tabelle gibt es neben den beiden Parametern debugLevel und name (siehe unten) noch zwei große Einträge, die wiederum Tabellen sind: create und tracks. Letzteres ist ein Array, in dem alle betriebsrelevanten Informationen zum Schattenbahnhof gespeichert werden. Jeder Eintrag enthält alle Informationen zu einem Gleis. Dazu später mehr.

Der Eintrag create ist nur ein „Hilfseintrag“ für alle, die sich die manuelle Konfiguration jedes einzelnen Gleises sparen wollen. Alle hierin enthaltenen Informationen werden von der Funktion Schattenbahnhof:new(...) verarbeitet und in den Eintrag tracks einsortiert. Anschließend wird der komplette Eintrag create gelöscht.

Folgende Parameter werden im Eintrag create unterstützt und verarbeitet:

  • numTracks: Anzahl der Gleise des Schattenbahnhofs. Falls der tracks-Array schon gefüllt ist und nur noch ein paar Informationen ergänzt werden sollen, kann dieser Eintrag weggelassen werden, dann wird die Anzahl der Gleiseinträge aus tracks übernommen.
  • signalIdStart: Signal-ID des Signals auf dem ersten Gleis. Pflichtfeld, wenn die Signal-IDs nicht schon manuell im tracks-Array eingetragen.
  • blockIdStart, readyIdStart: Signal-IDs der beiden Zustandssignale für das erste Gleis. Können weggelassen werden, wenn nicht benötigt.
  • switchIdStart: Weichen-ID der ersten Weiche des Schattenbahnhofs. Pflichtfeld, wenn die Weichenstellungen nicht schon manuell im tracks-Array eingetragen sind.
  • signalIdIncrement, blockIdIncrement, readyIdIncrement, switchIdIncrement: Schrittweite zwischen den Signal/Weichen-IDs benachbarter Gleise. Beispiel: Die Signal-ID des Signals auf dem dritten Gleis berechnet sich durch signalIdStart+2*signalIdIncrement. Können weggelassen werden, Standardwert ist 1.
  • switchPosToTrack: Weichenstellung, mit der jeweils die einzelnen Gleise erreicht werden. Die jeweils andere Weichenstellung (es werden hier keine Dreiwegweichen unterstützt) führt zur nächsten Weiche. Kann weggelassen werden, Standardwert ist 2 („Abzweig“).
  • flipFirstSwitch: Gibt an, ob die erste Weiche ihre Stellungen vertauscht hat. Beispiel für switchPosToTrack=2: Bei der ersten Weiche führt der gerade Strang („Fahrt“/Stellung 1) zum ersten Gleis, der abzweigende Strang zu den folgenden Weichen. Kann weggelassen werden, Standardwert ist false.
  • switchForLastTrack: Gibt an, ob es für das letzte Gleis auch noch eine eigene Weiche zu berücksichtigen ist (deren anderer Strang dann auf einen Prellbock oder sonstwohin führt). Kann weggelassen werden, Standardwert ist false.

Soweit nicht durch entsprechende create-Einträge erzeugt, können alle Informationen auch manuell für jedes Gleis im tracks-Array abgelegt werden. Diese werden, soweit möglich, von den create-Einträgen nicht überschrieben. Fehlende Einträge werden, soweit möglich, in der Funktion Schattenbahnhof:new(...) automatisch ergänzt. Jedes Gleis innerhalb des tracks-Arrays enthält folgende Informationen (wiederum als Tabelleneinträge):

  • signalID: Signal-ID des Signals zur Zugbeeinflussung.
  • signalPosGo: Signal-Position für „Fahrt“. In diese Stellung wird das Signal bei der Ausfahrt gebracht. Kann weggelassen werden, Standard-Wert ist 1 („Fahrt“ bei normalen, nicht mehrbegriffigen Signalen).
  • signalPosStop: Signal-Position für „Halt“. In diese Stellung wird das Signal bei der Einfahrt gebracht. Kann weggelassen werden, Standard-Wert ist 2 („Halt“ bei normalen, nicht mehrbegriffigen Signalen).
  • blockID: Signal-ID des Zustandsignals zur Belegtmeldung des Gleises. Kann weggelassen werden, dann wird die signalID des Gleise übernommen.
  • blockPosFree: Signal-Position für „Gleis frei“. Steht das Zustandssignal bei der Einfahrt in dieser Stellung, gilt das Gleis als frei. Kann weggelassen werden, Standard-Wert ist 1 („Fahrt“ bei normalen, nicht mehrbegriffigen Signalen). Wenn die blockID nicht angegeben wurde, ist der Standardwert signalPosGo.
  • blockPosBlocked: Signal-Position für „Gleis belegt“. In diese Stellung wird das Signal bei der Einfahrt gebracht. Kann weggelassen werden, Standard-Wert ist 2 („Halt“ bei normalen, nicht mehrbegriffigen Signalen). Wenn die blockID nicht angegeben wurde, ist der Standardwert 0 (ungültige Signalstellung, Signal wird nicht doppelt umgestellt).
  • readyID: Signal-ID des Zustandsignals zur Fertigmeldung („Bereit zur Ausfahrt“) des Gleises. Kann weggelassen werden, dann wird die signalID des Gleise übernommen.
  • readyPosReady: Signal-Position für „Bereit zur Ausfahrt“. Steht das Zustandssignal bei der Ausfahrt in dieser Stellung, gilt das Gleis als ausfahrbereit. Kann weggelassen werden, Standard-Wert ist 1 („Fahrt“ bei normalen, nicht mehrbegriffigen Signalen). Wenn die blockID nicht angegeben wurde, ist der Standardwert signalPosStop.
  • readyPosWait: Signal-Position für „keine Ausfahrt möglich“. In diese Stellung wird das Signal bei der Ausfahrt gebracht. Kann weggelassen werden, Standard-Wert ist 2 („Halt“ bei normalen, nicht mehrbegriffigen Signalen). Wenn die blockID nicht angegeben wurde, ist der Standardwert 0 (ungültige Signalstellung, Signal wird nicht doppelt umgestellt).
  • switches: Array mit allen Weichen-IDs und -Stellungen, die bei der Einfahrt in dieses Gleis gestellt werden sollen. Es gibt drei verschiedene Notationsmöglichkeiten:
    1. switches={{id=101,pos=2},{id=102,pos=2},{id=103,pos=1}}, jeder Eintrag nach dem Schema {id=ID,pos=Stellung}. In dieses Schema werden alle Einträge umgewandelt.
    2. switches={{101,2},{102,2},{103,1}}, jeder Eintrag nach dem Schema {ID,Stellung}. Kürzer, die Reihenfolge bleibt erhalten.
    3. switches={[101]=2,[102]=2,[103]=1}, jeder Eintrag nach dem Schema [ID]=Stellung. Ebenfalls kürzer, aber die Reihenfolge wird nicht beibehalten (das hat Lua-interne Gründe).
    Die verschiedenen Varianten können auch gemischt werden, allerdings kann dabei die Reihenfolge durcheinandergeworfen werden.
  • name: Name des Gleises, wird bei der Ausgabe im EEP-Ereignisfenster verwendet. Kann weggelassen werden, Standardwert ist Gleis # mit eingesetzter Gleisnummer.

Bleiben noch die beiden Parameter debugLevel und name, die für den gesamten Schattenbahnhof gelten:

Der Parameter debugLevel gibt an, wie oft bzw. ausführlich Meldungen im Ereignis-Fenster ausgegeben werden sollen. Standardwert ist 1 (nur Fehlermeldungen).

  • debugLevel=0: Von diesem Schattenbahnhof werden keinerlei Ausgaben in das Ereignisfenster geschrieben.
  • debugLevel=1: Es werden nur Fehlermeldungen ausgegeben (also wenn es bei der Einfahrt kein freies bzw. bei der Ausfahrt kein belegtes Gleis gab).
  • debugLevel=2: Neben den Fehlermeldungen werden zusätzlich auch noch Statusmeldungen ausgegeben, wenn eine Einfahrt oder Ausfahrt geschaltet wurde.

Mit dem Parameter name lässt sich ein Name für den Schattenbahnhof vergeben, der für die Ausgaben im Ereignisfenster verwendet wird.

Beispielkonfigurationen

Nachfolgend ein paar Beispielkonfigurationen (die natürlich eine entsprechende Gleisanlage voraussetzen):

sbf = Schattenbahnhof:new{create={numTracks=9,signalIdStart=11,switchIdStart=1}}

Minimaler Konfigurationsaufwand (kompakt in eine Zeile geschrieben), aber trotzdem neun Gleise!


sbf = Schattenbahnhof:new{
  create={
    numTracks=9,
    signalIdStart=65,
    blockIdStart=142,
    blockIdIncrement=-1,
    switchIdStart=43,
    switchForLastTrack=true,
    flipFirstSwitch=true,
  },
  debugLevel=2,
  name="Hauptstrecke",
}

Echtes Beispiel: Konfiguration des Hauptstrecken-Schattenbahnhofs auf meiner Anlage „Bahnhof Falls“. Die Belegtmeldesignale wurden in der falschen Reihenfolge eingesetzt, deshalb blockIdIncrement=-1.


sbfNebenbahn = Schattenbahnhof:new{
  tracks={
    {signalID=81,switches={[76]=2}},
    {signalID=82,switches={[76]=1,[77]=2}},
    {signalID=83,switches={[76]=1,[77]=1,[78]=2}},
    {signalID=84,switches={[76]=1,[77]=1,[78]=1,[79]=2}},
  },
  debugLevel=2,
  name="NEBENSTRECKE",
}

Echtes Beispiel: Konfiguration des Nebenstrecken-Schattenbahnhofs auf meiner Anlage „Bahnhof Falls“. Bei vier Gleisen war auch die „manuelle Konfiguration“ noch machbar.


Changelog

v0.1 vom 03.08.2014:
  • Schattenbahnhofssteuerung mit geordneter Einfahrt und zufälliger Ausfahrt
  • Einfache Konfiguration mit vielen Konfigurationsmöglichkeiten
  • Bis zu drei verschiedene Zustandssignale pro Gleis: Eins für den Zug (Halt bei Einfahrt, Fahrt bei Ausfahrt), eins zur Belegtmeldung (Halt bei Einfahrt, Fahrt manuell per Zugschluss-KP am Ende des Gleises) und eins zur Anmeldung der Ausfahrtsbereitschaft (Fahrt manuell per KP nach Ankunft im Gleis plus evtl. Verzögerung, Halt bei Ausfahrt)