Skip to content

anjo0803/schrankenwaerter

Repository files navigation

Installer Version Licence

schrankenwaerter

🇩🇪 // 🇬🇧

Deutsch

Der Schrankenwärter ist ein Lua-Skript zur Steuerung von Bahnübergängen im Eisenbahnsimulator EEP - vom einfachen BÜ mit zwei Schranken bis hin zu komplexen Systemen aus vielen separaten Lichtzeichen, Schranken, Immobilien und Sounds samt Zeitpuffern dazwischen!

Einbinden des Skripts

Um das Schrankenwärter-Skript zu installieren, kannst Du einfach hier die neueste Schrankenwaerter.zip-Datei herunterladen und dann mittels des EEP-Modellinstallers installieren. Dadurch wird das Skript automatisch im "LUA"-Ordner Deiner EEP-Installation platziert. Alternativ kann auch die Datei Schrankenwaerter.lua direkt heruntergeladen und manuell im "LUA"-Ordner gespeichert werden.

Im Lua-Skript der Anlagen kann das Skript dann durch die Lua-Funktion require eingebunden werden:

SW = require("Schrankenwaerter")

Außerdem muss die Funktion SW.main() in der EEPMain()-Funktion aufgerufen werden, damit das Skript auch tatsächlich ausgeführt wird:

function EEPMain()
	SW.main()
	return 1
end

Konfigurieren eines BÜs

Bahnübergänge kannst Du nach Einbindung des Skripts jeweils einzeln mit der Funktion SW.define bzw. SW.definiere konfigurieren - die meisten Funktionen des Skripts haben sowohl einen englischen als auch einen deutschen Namen. Dabei muss dem BÜ zuerst eine ID gegeben werden, über die er im folgenden angesteuert werden soll.

SW.definiere("Beispiel-Bue")

Direkt danach kannst Du die gewünschten Eigenschaften des BÜ beschreiben.

Zuweisen von Speicher-Slots

Optional lässt sich jedem BÜ ein EEPSaveData-Slot zuweisen. Dieser wird dann genutzt, um Zustandsdaten des BÜs (bspw. Anzahl der nahenden Züge) zu sichern, sodass diese nicht beim Neuladen des Skripts oder der Anlage verloren gehen.

SW.definiere("Beispiel-Bue")
	:speichern(1)

Schließ- und Öffnungsvorgang

Den Kern der BÜ-Konfiguration bilden Schließ- und Öffnungsvorgang, die über die Funktionen :schliessen bzw. oeffnen eingestellt werden. Darin kannst Du mittels einer Kette von "Aktionen" detailliert beschreiben, wie diese Vorgänge konkret ablaufen sollen.

SW.definiere("Beispiel-Bue")
	:speichern(1)
	:schliessen(aktion1, aktion2, ...)
	:oeffnen(aktion1, aktion2, ...)

Die angegebenen Aktionen werden während des jeweiligen Vorgangs nacheinander abgearbeitet. Momentan stehen folgende Aktionen zur Verfügung:

Name Effekt Parameter
SW.signal(signal_id, stellung) Setzt ein Signal in eine Stellung. signal_id: ID des Signals, das gesetzt werden soll.
stellung: ID der Stellung, in die das Signal gesetzt werden soll.
SW.immo(immo_id, achse, schritte) Bewegt eine Achse an einer Immobilie. immo_id: Lua-Name der Ziel-Immobilie.
achse: Name der zu bewegenden Achse.
schritte: Anzahl der Schritte, die die Achse bewegt werden soll.
SW.sound(sound_id, anschalten) Schaltet einen Sound an oder aus. sound_id: Lua-Name des Ziel-Sounds.
anschalten: true, um den Sound anzuschalten; false, um ihn auszuschalten.
SW.pause(zyklen) Pausiert die Aktionsausführung. zyklen: Anzahl der Lua-Zyklen, für die die Ausführung ruhen soll. Ein Zyklus entspricht einem Aufruf der SW.main()-Funktion, d.h. wenn diese in jedem Aufruf der EEPMain()-Funktion aufgerufen wird, dauert jeder Zyklus 200ms.

Doppelaktivierung

Neben :schliessen und :oeffnen lässt sich optional ein Vorgang definieren, der ausgeführt werden soll, wenn ein zweiter Zug sich am bereits geschlossenen BÜ anmeldet. So lässt sich bspw. die Aktivierung einer "2 ZÜGE"-Leuchtschrift verwirklichen. Ein solcher Vorgang wird über die Funktion :doppelt definiert, wobei wie bei Schließ- und Öffnungsvorgang Aktionen benutzt werden:

SW.definiere("Beispiel-Bue")
	:schliessen(aktion1, aktion2, ...)
	:oeffnen(aktion1, aktion2, ...)
	:doppelt(aktion1, aktion2, ...)

Reversieren

Wird ein BÜ von einem neuen Zug erneut eingeschaltet, während der Öffnungsvorgang noch läuft, führt er diesen normalerweise zunächst vollständig durch und beginnt danach erst den üblichen Schließvorgang. Soll er stattdessen den Öffnungsvorgang reversieren (wie es z.B. WSSB-Anlagen tun), kannst Du dafür mit der Funktion :reversieren einen speziellen Vorgang beschreiben:

SW.definiere("Beispiel-Bue")
	:schliessen(aktion1, aktion2, ...)
	:oeffnen(aktion1, aktion2, ...)
	:reversieren(aktion1, aktion2, ...)

Anrufschranken

Möchtest Du einen Bahnübergang als Anrufschranke einrichten, musst Du in der BÜ-Definition nur die entsprechende Funktion aufrufen:

SW.definiere("Beispiel-Bue")
	:anrufschranke()
	:schliessen(aktion1, aktion2, ...)
	:oeffnen(aktion1, aktion2, ...)

Beispiele

Beispielkonfigurationen für BÜs gibt es hier! Anm.: Die Beispiele nutzen die englischen Namen der Funktionen.

Kontaktpunkte

Um einen BÜ dann tatsächlich zu schließen und zu öffnen, müssen sich Züge einfach über die Funktionen SW.schliesse(bue_id) und SW.oeffne(bue_id) am BÜ an- bzw. abmelden Die bue_id entspricht dabei der zuvor von Dir gewählten BÜ-ID.

Zur straßenseitigen Steuerung von Anrufschranken werden zusätzlich die Funktionen SW.anrufen(bue_id) und SW.freimelden(bue_id) benutzt. Durch sie kann ein Verkehrsteilnehmer die Öffnung der Schranke anfordern bzw. melden, dass der Übergang wieder geräumt ist.

Mittels BetterContacts ist es möglich, diese Funktionen direkt aus Kontaktpunkten heraus aufzurufen. Ansonsten müssen für jeden BÜ spezifische Funktionen eingefügt werden, die dann ihrerseits die Schrankenwärter-Funktionen aufrufen:

function schliesse_beispiel()
	SW.schliesse("Beispiel-Bue")
end
function oeffne_beispiel()
	SW.oeffne("Beispiel-Bue")
end

Natürlich können die Öffnungs- und Schließungsfunktionen auch außerhalb von Kontaktpunkten, bspw. an anderer Stelle des Anlagen-Skripts, aufgerufen werden.

Lizenz

Ich habe das Skript für faktisch gemeinfrei erklärt (Unlicense).

English

Schrankenwaerter is a Lua script for controlling railroad crossings in the train simulator EEP - from a simple crossing of just two signals to complex setups of many separate lights, barriers, structures, and sounds plus time buffers in between!

Using the script

To use the Schrankenwaerter script in your layouts, you can simply download the latest Schrankenwaerter.zip file here and install it using the EEP Model Installer. This will automatically place the script in the "LUA" folder of your EEP installation. Alternatively, you can also download the Schrankenwaerter.lua file directly and place it in the "LUA" folder yourself.

You can then integrate the Schrankenwaerter script into the Lua script of a layout using the Lua require function:

SW = require("Schrankenwaerter")

Please also add a call to the SW.main() function in your EEPMain() function in order for the script to actually be executed:

function EEPMain()
	SW.main()
	return 1
end

Crossing setup

After integrating the Schrankenwaerter script, you can define your railroad crossings using the SW.define function. You must pass an ID value to this function, which you can then use to address this specific crossing:

SW = require("Schrankenwaerter")
SW.define("Example Crossing")

All other relevant data is described right afterwards using additional functions.

Assigning save slots

Optionally, you can assign the crossing one of the EEPSaveData slots. This will then be used to save the crossing's live data (e.g. number of trains approaching the crossing), so that this isn't lost during reloads of the script or your layout.

SW.define("Example Crossing")
	:save(1)

Opening and closing sequences

Using the functions :closing and :opening, you can describe in detail how you want the closing and opening sequences of the respective crossing to look.

SW.define("Example Crossing")
	:save(1)
	:closing(action1, action2, ...)
	:opening(action1, action2, ...)

These functions each require a list of "actions", which will be executed one after another during the respective sequence. For example, you can set a signal or turn a sound on or off. Currently, the script provides the following actions:

Name Effect Parameters
SW.signal(signal_id, position) Set a signal. signal_id: ID of the target signal.
position: ID of the position that the signal should be set to.
SW.immo(immo_id, axis, steps) Moves an axis on a structure. immo_id: Lua name of the target structure.
axis: Name of the axis to move.
steps: Number of steps to move the axis.
SW.sound(sound_id, turn_on) Turns a sound on or off. sound_id: Lua name of the target sound.
turn_on: true to turn on the sound; false to turn it off.
SW.pause(cycles) Pauses execution of actions. cycles: Number of Lua cycles to pause. One cycle is equivalent to one call of the SW.main() function, so if it is called with every call of the EEPMain() function, one cycle is 200ms.

Double activation

In addition to :closing and :opening, you can optionally define a routine to be executed when a second train activates the already closed crossing. This e.g. allows for the activation of a "2 ZÜGE" display. To create such a routine, use the :twice function with actions, just as above.

SW.define("Example Crossing")
	:closing(action1, action2, ...)
	:opening(action1, action2, ...)
	:twice(action1, action2, ...)

Reversing

When a crossing is activated again by another train while the opening sequence is still ongoing, it normally finishes the opening and only thereafter starts the usual closing sequence. If you want it to stop opening and reverse instead, use the :reverse function to describe the sequence you would like to happen:

SW.define("Example Crossing")
	:closing(action1, action2, ...)
	:opening(action1, action2, ...)
	:reverse(action1, action2, ...)

Call-only crossings

If you want to run a crossing like a British MCB-OC type - having the barriers down permanently and only opening them if a road user requests it - you just need to chain the corresponding function during the crossing setup:

SW.define("Example Crossing")
	:call_only()
	:closing(action1, action2, ...)
	:opening(action1, action2, ...)

Examples

You can find example configurations for crossings here.

Contact points

Trains can strike in and pass the crossing using the SW.close(crossing_id) and SW.open(crossing_id) functions. The crossing_id is the ID you chose earlier for the respective crossing.

For controlling a call-only crossing on the side of the road users, the SW.call_request(crossing_id) and SW.call_clear(crossing_id) functions are used additionally. They signal that a road user requests opening the barriers and that they have cleared the crossing again, respectively.

Using BetterContacts, it is possible to call these functions directly from the contact points set for the crossing. Alternatively, you naturally can just define another function, which itself calls SW.close(crossing_id), and use that.

function close_example()
	SW.close("Example Crossing")
end
function open_example()
	SW.open("Example Crossing")
end

Naturally, you can also call the opening and closing functions outside of contact points from another part of your layout's script.

Licence

Public domain (Unlicense).

About

Bahnübergang-Manager für EEP // Railroad crossing manager for EEP

Topics

Resources

License

Stars

Watchers

Forks