Beiträge von Pandemist

    Hi,


    bitte gib uns mehr Informationen zu deinem Problem.

    - Mit welchem Fahrzeug, IBIS-Gerät & Anzeigen-Modulen hast du es ausprobiert?

    - Tritt das Problem bei verschiedenen Fahrzeugen, IBIS-Geräten & Anzeigen-Modulen auf? (Wenn ja, bei welchen)


    Teile bitte auch einmal Screenshots deiner FIS-Datei, auf dem mind. eine Linie erkennbar ist, bei der das Sonderzeichen funktioniert und einmal eine Linie, bei der das Problem auftritt.

    Sowas geht nicht einfach universell. Zeilenweise invertieren muss eine Anzeige unterstützen. Die "Standard"-FlipDot Anzeige unterstützt diese Funktion zum Beispiel gar nicht.

    Mit den LED-Anzeigen von Teneberus ist das z.B. möglich. Wie es sich da umsetzen lässt, kannst du HIER nachlesen.

    Es ist durchaus sinnvoll, dass Fahrzeuge, wenn sie asynchron gekuppelt werden, auch die Türen auf der falschen Fahrzeuge. So gibt es in der Realität Fahrzeuge, die erkennen, von wo das Signal kam und somit immer auf der richtigen Seite öffnen. Aber es gibt auch Fahrzeuge die nicht erkennen, von wo das Signal kommt und bei asynchroner Kupplung tatsächlich auf der falschen Seite öffnen.

    Hat, denke ich, wenig mit der behandelten Message zu tun. Die Message dient nur dazu, Module über den Tür-öffne Zustand und die Türseite zu informieren. Falls z.B. eine Innenanzeige einen Ausstiegspfeil anzeigen soll. Wie ein Fahrzeug jetzt ermittelt, auf welcher Seite es die Türen öffnet, ist darin überhaupt nicht enthalten. Das kann jedes Fahrzeug bzw. jeder Entwickler selber entscheiden. Wenn du also DB Reisezugwagen umsetzt, hält dich keiner davon ab, diese Ansteuerung und den Seitenberichtigungsschalter so umzusetzen.


    Bei Stadt- und Straßenbahnen mit automatischen Mittelpufferkupplungen mit E-Teilen wird sowas meines Wissens nach auch ganz anders umgesetzt.

    Hi,

    Sind das jetzt die Internen Patchnotes wie weit die neuen Skripte schon sind?

    Patchnotes sind in diesem Beitrag erstmal keine. Die Patchnotes zur aktuellen internen Version werden automatisiert im Lotus Discord im Kanal #update_news_en gepostet.

    Da vor kurzem das Thema Messages und Mehrfachtraktion neu in die interne Version gekommen sind, haben wir uns dazu entschieden, das Thema gleich mit neuen Standards zu beackern. Am effektivsten sind Standards natürlich bevor alle in verschiedene Richtungen entwickeln. Wie weit also einzelne Scripte sind, kann man daraus noch nicht wirklich ableiten.

    Ich bin kein Scriptexperte, aber es scheint ja schon erste Fortschritte bei den Grundfunktionen zu geben. Das ist ja schon mal ein kleiner Schritt zum nächsten Update.

    Ich würde schätzen, dass schon ein Großteil der Grundfunktion von Script (also reine Basic, ohne Features wie Fahrplan, FIS, etc.) vorhanden sind. Animationen, Lichter, Sounds etc. können größtenteils angesteuert werden. Man kann Fahren und Bremsen, Script-Texturen sind möglich und wie gesagt, das Versenden von Nachrichten ist möglich.

    Aber als Disclaimer. Daraus kann man jetzt erstmal keinen direkten Zusammenhang zu einem Patch ableiten. Es gibt noch viele andere Parts, an der NG Version, wie die Physik, die Shader oder das Laden des Contents, an denen genauso gearbeitet werden muss.

    Müssen dann eigentlich alle alten Scripte angepasst werden?

    Klingt jetzt etwas ernüchternd, aber zumindest zum aktuellen Zeitpunkt: Ja. Aktuell wird nur Rust als Sprache für Scripte unterstützt. (Grund dafür habe ich im * im Hauptbeitrag etwas angerissen). Solange also auch kein Konverter von Pascal zu Rust (oder einer anderen kompatiblen Sprache) existiert, wird man da also neu/ um schreiben müssen. Ich für meinen Teil sehe das aber als gar nicht so schlecht. So kann man seine Scripte nochmal überholen, ausmisten und das eine oder andere neue Feature einbauen.


    ===============================

    Spontan fällt mir hinsichtlich der Batteriespannung ein, dass Fahrzeuge mit getrennten Stromkreisen in Batterie+ und Wagen+ nicht dargestellt werden können. Konkret wäre hier zB das IBIS zu nennen, was bei Düsseldorfer Fahrzeugen am Batteriehauptschalter vorbei gespeist wird.

    Wenn ich das richtig verstehe, würde es dafür reichen, wenn man einmal die Batteriespannung vor und nach dem Hauptschalter abgreifen würde?

    Meine spontane Idee wäre, in deinem Fall dem IBIS zu Beginn einmal On(f32) zu senden und danach nur noch die Batteriespannung zu aktualisieren. Beim Senden der Batteriespannung an alle anderen Module müsste dann natürlich der/ die IBIS-Slot(s) ausgenommen werden. Ich habe dafür direkt den "Send Helper" angepasst, dass man für diesen ein Target festlegen kann. Dann könntest du 2 dieser Sender deklarieren, einen an das IBIS mit der Batteriespannung vor dem Batteriehauptschalter und einmal einen an alle anderen mit der Batteriespannung nach dem Batteriehauptschalter.


    Glaubst du, das würde für deinem Anwendungsfall helfen?

    Hi, danke für das Feedback.

    Da hatten wir schon mal im Discord drüber gesprochen; Hierarchie der Anzeigen. Also welche Anzeige von Fahrgästen beachtet wird. (Im Hinblick auf erzwungenen Ausstieg oder generell Zugziel). Also in etwa Außenanzeige<Innenanzeige<Steckschild

    Das Thema steht tatsächlich auf der Liste. Eine Unterscheidung zwischen einsteigenden und aussteigenden Fahrgästen fände ich interessant. Aktuell haben wir erstmal nur eine Quelle für die Fahrgäste in Betracht gezogen. Aktuell habe ich die grundlegenden Strukturen in Rust schon hinterlegt (aber noch ohne Priorität). Wenn der Umfang steht, will ich auch Strukturen entwickeln, die Module und das Fahrzeug inkludieren können, damit sowas eben nicht jeder selber bauen muss. Hierzu mehr, können wir bestimmt besser Details diskutieren, wenn ein erster Vorschlag steht.


    Eine einfache, standardisierte Kupplungs-Kommunikationsgrundlage, die alle Fahrzeuge verstehen. Ich denke da an Blinker, Bremsleuchten und so etwas wie "alle Bremsen lösen", zum Abschleppen.

    Auf den Vorschlag wurde ich an anderer Stelle schonmal gebracht. Weswegen ich darüber auch schonmal nachgedacht habe. Bisher bin ich da aber noch nicht auf einen Ansatz gekommen, an dem man zumindest ein bisschen "Standard" drüber stülpen könnte. Um einige der verschiedenen Konfliktpunkte mal an deinen Beispielen zu vertiefen:

    • Blinker => Hier sind mir alleine 2 Vorgehensweisen bei Fahrzeugen bekannt. Einmal die, bei welcher die Ansteuersignale übertragen wird und jeder Wagen darüber seine Blinkeranlage ansteuert, oder die Variante, wo direkt der Blinkerpuls übertragen und auf die Lampen gelegt wird. Würde man sich bei einem solchen "Standard" Signal jetzt auf eine der beiden Lösungen einigen und die anderen Fahrzeugzeuge müssten sich "beugen" oder würde man sowas parallel zur eigentlichen Ansteuerung übertragen? Dazu kommt die Frage nach der Übertragung bei asymmetrisch gekuppelten Fahrzeugen.
    • Bremsleuchten => Von den Fahrzeugen, mit deren Kupplungsbelegung ich mich bisher beschäftigt habe, wird dort dieses Signal nicht übertragen. Ein Wagen generiert es selbst, aus z.B. Sollwertgeberansteuerung über die Kupplung, Ausgang aus einem Wagensteuergerät, oder über einen Beschleunigungssensor. Müsste ich bei solch einem Standard, so eine Funktion jetzt zur Verfügung stellen, auch wenn mein Fahrzeug in real anders arbeitet? Oder bei einem Fahrzeug ohne Rücklichter. Müsste ich diesen Standard dann auch implementieren, um ein Signal weiterzuleiten?
    • "Alle Bremsen lösen" => Hier hätte man meiner Meinung nach einen höchst unrealistischen Eingriff in die Logik der Fahrzeuge. (Bremsanlage = wichtig) Ein Kupplungsbefehl, der z.B. mechanische angedrehte Handbremsen, oder Druckluftbremsen gegen den anliegen HL-Druck löst, hat zumindest für mich nicht mehr viel mit "Simulation" zu tun. Ich kenne es von mehreren Fahrzeugen so, dass die Bremsen im ab zu schleppenden Fahrzeug selbst Not-gelöst werden müssen. Dort bräuchte man so einen extra Kupplungsbefehl gar nicht. (Funktioniert aber vermutlich auch wieder nicht für alle Fahrzeuge) Die Frage wäre hier, ob damit alle Bremsenarten gelöst werden, oder nur bestimmte? Oder mit welcher Priorität die Bremsen gelöst werden. (Werden z.B. nur Betriebsbremsungen überschrieben, der auch Festhaltebremsen, Gefahrenbremsen, etc.)

    Das soll explizit kein direktes "Nein" zu der Idee sein, sondern soll nur verdeutlichen, wie groß hier die Kompromisse seien müssten, wie stark oder schwach die Standardisierung sein kann und vor allem, wie groß hier der Diskussionsbedarf wäre. Nichtsdestotrotz, können wir gerne darüber diskutieren und gucken, ob sich da eine Lösung anbietet.


    Das geht etwas mehr in Richtung Programmfunktionen: Eine Art Datenbank (vermutlich in der FIS definiert), in der der Anzeigestring für jede Haltestelle in möglichst vielen Längen definiert wird. Dann können sich die Anzeigen im Fahrzeug und auch die Anzeigen am Bahnhof die passende Länge heraussuchen.

    Das ist auf jeden Fall eine interessante Idee. Bei der Recherche zum Thema FIS in den Standards (VDV 300 & Produktspezifikationen für Anzeigen, Bordrechner, stationäre Anzeiger, etc.) sind wir bisher immer auf bestimmte Fix-Werte gestoßen. So ein Zusammenspiel ist natürlich immer noch einen Tick komplizierter, da man Anzeigen und Bordrechner frei kombinieren kann. Am ehesten ließe sich so eine "Datenbank" vermutlich mit einer Standardisierten speziellen FIS-Datei umsetzen. Darüber habe zumindest ich noch nicht weiter nachgedacht. Vielleicht hat Teneberus da schon Ideen. Er ist ja wesentlich stärker in dem Thema Anzeigen involviert.

    :flag_ger:


    Hallo alle zusammen,


    im Rahmen der Umstellung auf die neue Engine, ist euch sicher bekannt, dass auch die Scriptsprache umgestellt wird. (Vorerst) kann bei Scripten (nur) mit Rust gearbeitet werden*.

    Aus diesem Grund haben Teneberus und ich uns mal hingesetzt und überlegt, was wir aufgrund unserer Erfahrungen mit dem bisherigen Script-System im Bereich der Kommunikation (Fahrzeug <> Fahrzeug, Fahrzeug <> Modul, Modul <> Modul) verbessern können. Auch wollten wir auf die neuen Möglichkeiten, die Rust uns bietet, zurückgreifen. Weil wir nicht allwissend sind und auch nicht jeden Anwendungsfall kennen, wollen wir hier unsere Vorschläge präsentieren und Feedback/ Verbesserungsvorschläge sammeln.


    Grundlagen Erklärung

    Als Erstes möchte ich für alle einmal das grundlegende Konzept für die neue Script Kommunikation erklären:

    Die wichtigste Änderung gegenüber dem System in Pascal ist es, dass in Zukunft nicht mehr zwischen MessageToChild, MessageToParent, Broadcast, Kupplungsvariablen, etc. unterschieden wird. In Rust wird alles unter einer Message zusammengefasst. Dies bietet die Vorteile, dass Nachrichten flexibler an verschiedene Ziele zugestellt werden können und spart auch den Aufwand verschiedene Empfangsfunktionen im Script definieren zu müssen. In Zukunft können alle Messages über eine Funktion fn on_message(&mut self, msg: Message); empfangen werden.

    Darüber hinaus kann die Beschränkung auf die drei Datentypen String, Single, Integer wegfallen. Eine Nachricht kann ab jetzt jeden beliebigen Inhalt haben, solange dieser die Traits [Serialize, Deserialize] erfüllt.** Darüber hinaus verfügt eine Message über 2 bzw. 3 Parameter, welche namespace, identifier, [bus] sind.

    Der Identifier bildet dabei wie bisher den Namen der Nachricht. Dieser kann frei gewählt. Mit dem Namespace wird eine Nachricht einer bestimmten Kategorie zugeordnet. Dies ist auch wichtig, dass wenn 2 Personen denselben Namen für eine Nachricht werden, diese sich nicht überschreiben und es zu Fehlern kommt. Namespaces können z.B. Std für Lotus Standard Messages sein, oder man kann sein eigenes Kürzel, bzw. den Nickname verwenden. Der Wert Bus ist optional bei der Definition einer Message. Die Hauptfunktion ist es, anhand der Bus-Id das Versenden von Nachrichten auf einem bestimmten Bus über die Kupplung zu erlauben oder zu verhindern. Analog zu dieser Funktionsweise im alten System.

    Das Letzte, was ich noch als Grundsatz erklären will, ist das Versenden von Messages. Hierzu wird es eine Funktion geben, welcher man als Parameter die zu versendende Message und eine Liste mit Empfängern übergibt. Die Neuerungen hierbei sind, einerseits, dass man direkt an mehrere Empfänger senden kann und andererseits nur noch eine allgemeine Sende-Funktion hat und nicht mehr wie bisher verschiedene, je nach Empfänger. Als Empfänger für Messages gibt es einige Optionen, die ich hier nur mal kurz anreißen will: ***

    • Myself (Sendet an den Absender der Nachricht)
    • ChildByIndex (Sendet an einen bestimmten Modulslot)
    • Broadcast (Sendet an alle)
    • AcrossCoupling (Sendet über die vordere oder hintere Kupplung)
    • Parent (Sendet von Modulen an der übergeordnete Fahrzeug)
    • ...


    Mit diesen Grundlagen über das neue Message-System möchte ich als Nächstes vorstellen, welche Änderungen wir uns bei den Standard-Messages überlegt haben. Dabei geht es in diesem ersten Beitrag erstmal nur um die wirklichen Basics. Funktionen und Features, welche noch nicht implementiert sind, folgen zu einem späteren Zeitpunkt.

    Die hier vorgestellten Messages werden alle im Standardumfang definiert sein und können direkt als Struktur verwendet werden. Außerdem wird es Helfer-Funktionen geben, mit welchen das Versenden dieser Messages vereinfacht wird.


    Fahrzeugnummer

    Bisher wurde hier ein String unter dem Namen VEH_NUMBER versendet. Dies wollen wir auch so beibehalten. Die neue Message in Rust sieht wie folgt aus:

    Code
    1. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
    2. pub struct MsgVehNumber {
    3. pub value: String,
    4. }
    5. message_type!(MsgVehNumber, "Std", "Vehiclenumber"); // Namespace: "Std", Identifier: "Vehiclenumber" (Bus wird nicht definiert)

    Diese wird/ soll beim Versenden per Broadcast an das eigene Fahrzeug und alle Module versendet werden. Es findet keine Übertragung per Bus über die Kupplung statt.


    Batteriehauptschalter & Batteriespannung

    Hierfür haben wir uns dazu entschieden, diese beiden Informationen zusammenzulegen. Rust bietet die Möglichkeit, dass Varianten eines Enums einen Datenpayload tragen. Dieses wollen wir hierfür nutzen, um so beide Informationen zusammen zu übertragen. Wir man im Codeausschnitt für enum Batteryvoltage sehen kann, wird mit dem Zustand On auch eine Float Zahl mitübertragen. Diese stellt die normierte Batteriespannung dar (Also 0.0 = Keine Spannung, 1.0 = Sollspannung) Im Zustand Off muss keine Spannung übertragen werden, da die Batterie getrennt ist.

    Mit dieser Message ersetzen wir die bisherigen BATTERYSWITCH (integer) und VOLTAGE (single). Hier der passende Ausschnitt aus dem Code:

    Wie auch bei der Wagennummer werden diese Informationen nur an alle Empfänger in einem einzigen Fahrzeug versendet.

    Eine Wichtige weitere Sache ist, dass Batterie = Aus für alle Objekte der Standard ist. Wird ein Fahrzeug zu Beginn bereits mit eingeschalteter Batterie gespawnt, muss diese Information initial einmal versendet werden.


    Modulansteuerung

    Diese Message wird die alte Message MAINSWITCH (integer) ersetzen und erweitern. Wir wollen den Informationsgehalt wie folgt erweitern. Zum einen gibt es für jede Ein/ Ausschaltnachricht eine Information, wo gerade der Zustand geändert wurde. So können z.B. zentale Bordrechner, die Script technisch mit in einem IBIS-Terminal enthalten sind auch korrket ein und ausschalten. Die Werte ACab und BCab geben dabei an, ob im jeweiligen Fahrzeug einer der beiden Fahrerstände aufgerüstet wurde. Mit dem Zustand NoCab kriegen auch die Module in den geführten Fahrzeugen die Information, dass im Zugverband jetzt ein Fahrerstand aufgerüstet wurde. Die andere Änderung ist ein Boolean Parameter in der Einschaltnachricht. Mit dieser kann der Befehl "Quickstart" (Wert = true) übermittelt werden. Dadurch sollen Module den Boot-Prozess überspringen und direkt im Dauerbetrieb laufen. Dies bietet unter anderem die Vorteile, dass man beim Debuggen des Moduls nicht lange Startprozeduren abwarten muss und sorgt gleichzeitig dafür, dass bei der "Fahrzeug platzieren" Startoption "Fahrbereit" auch das Modul im aktiven Fahrerstand direkt verfügbar ist. Bisher musste man hier ja ein wenig schummeln. Hier, der Code (gekürzt) dazu zum draufgucken:

    Durch die enthaltene Information über den Fahrerstand, wir diese Message auch direkt per Broadcast an alle Module (und das eigene Fahrzeug) versendet. Durch die Möglichkeit, dass Module in Zukunft wissen, welchem Fahrerstand sie zugehörigen sind, können diese passend reagieren. Die Nachricht wird ebenfalls NICHT über die Kupplung übertragen und muss von jedem Fahrzeug selbstständig für seine Module generiert werden. Auch hier ist für alle Objekte der Standardzustand ausgeschaltet.


    Modulbeleuchtung

    Hier haben wir wieder weniger vorzuschlagen. Wir ersetzen hiermit den bisherigen Broadcast LIGHT (single). Dieser ist nun ein Wert vom Typ f32. Der Wertebereicht soll dabei die normierte Helligkeit sein, also 0.0 = Licht aus & 1.0 = Sollhelligkeit.

    Code
    1. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
    2. pub struct MsgLight {
    3. pub value: f32,
    4. }
    5. message_type!(MsgLight, "Std", "Light"); // Namespace: "Std", Identifier: "Light" (Bus wird nicht definiert)

    Grundsätzlich sollen alle Module diese Information erhalten. Eine Abweichung, wenn verschiedene Module z.B. an verschiedenen Lichtkreisen hängen, ist auch möglich. Die Message wird explizit NICHT über die Kupplung übertragen und muss in/ für jedes Fahrzeug im Zugverband selbst versendet werden.


    Haltewunsch

    Bisher wurde hier der Boradcast STOPREQUEST (single) verwendet. In unserem Vorschlag bleibt die Funktion erhalten, nur der Datentyp wird zu Boolean verändert.

    Code
    1. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
    2. pub struct MsgStopRequest {
    3. pub value: bool,
    4. }
    5. message_type!(MsgStopRequest, "Std", "StopRequest"); // Namespace: "Std", Identifier: "StopRequest" (Bus wird nicht definiert)

    Wie auch bei den vorherigen Messages wird diese NICHT über die Kupplung übertragen. Soll aber ansonsten alle Module im Fahrzeug erreichen. Sollte es in einem Fahrzeug mehrere Haltewunsch-Kreise geben (z.B. eine einem Bus im Vorderwagen und im Nachläufer), können natürlich Messages mit verschiedenen Empfängern gesendet werden. Fahrzeuge ohne Haltewunsch (z.B. historische Züge oder U-Bahnen) müssen diese Information natürlich nicht bereitstellen.


    Geschwindigkeit

    Über dieses Thema haben wir etwas länger nachgedacht. Wir greifen hier die Idee der Message VELOCITY (single) auf, welche bisher nur den Bordrechner erreicht hat. In unserer Überlegung kam auch die Idee auf, statt der Geschwindigkeit des Fahrzeugs, die gefahrene Wegstrecke oder direkt einen festgelegten Wegimpuls zu verwenden. Von diesen Ideen sind wir jedoch wieder abgerückt, da die Geschwindigkeit einfach am vielseitigsten einsetzbar ist und gleichzeitig auch die meiste Informationsmenge bereitstellt.

    Code
    1. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
    2. pub struct MsgVelocity {
    3. pub value: f32,
    4. }
    5. message_type!(MsgVelocity, "Std", "Velocity"); // Namespace: "Std", Identifier: "Velocity" (Bus wird nicht definiert)

    Der Wert wird im Metern pro Sekunde versendet. Das Vorzeichen bildet dabei die Fahrtrichtung ab. Auch diese Message wird NICHT über die Kupplung versandt, muss aber in jedem Fahrzeug gesendet werden. Wichtig ist hier, dass verschiedene Module auch verschiedene Geschwindigkeiten bekommen.


    Türzustand

    Kommen wir abschließend noch zur Information des Tüerzustands. Im bisherigen Lotus wurden hier zwei verschiedene Nachrichten verwendet. Einmal ATBUSSTOP (integer) und DOORSOPEN (integer). Diese wollen wir jetzt zusammen führen. Dabei wird nun nicht mehr nur die Information "Türfreigabe" ja/nein enthalten sein, sondern auch der Zustand ob die Türen zentral geöffnet wurden und auf welcher Seite die Türen freigegeben/ geöffnet sind.

    Wie auch die anderen Messages zuvor wird diese Information NICHT über die Kupplung übertragen, um so bei asymetrisch gekuppelten Fahrzeugen die Türseite nicht zu verdrehen. Hier kann es natürlich auch mehrere Kreise geben, z.B. in Bussen für den Vorderwagen und den Nachläufer. Wichtig ist nur, dass alle Module einmal diese Info bekommen.


    Feedback

    Damit wären wir am Ende der ersten Runde der Präsentation unseres Vorschlags. Gebt bitte Feedback und vorallem Veränderungs-, Verbesserungsvorschläge oder stellt auch Rückfragen, wenn nötig. Teneberus und ich können das alles nur aus unserer Perspektive betrachten und haben vielleicht bestimmte Aspekte garnicht im Blickfeld gehabt. Damit wir mit der neuen Version von Lotus aktualiserte Standards bekommen, die hoffentlich alle mit nutzen um so eine möglichst große Kompatibilität erreichen zu können.

    Die nächsten Themen, die wir be-/ überarbeiten wollen, sind der Zugbus und als Teil davon die FIS-Nachrichten zwischen Bordrechnern und Modulen. Falls es hier schon im vorhinein Input git, könnt ihr den auch gerne schon äußern.



    Und damit danke für die Aufmerktsamkeit.



    * = Grund dafür ist, dass die API/ Schnittstelle erstmal vollständig entwickelt werden muss. Da ist es nur unnötiger Mehraufwand, gleichzeitig Schnittstellen zu mehreren Sprachen gleichzeitig zu bearbeiten. Weitere Sprachen werden bestimmt in Zukunft möglich sein, dazu kann ich aber keine Aussagen treffen.

    ** = Wer mit diesen Begriffen noch nichts anfangen kann, dem empfehle ich hier das Offizielle Rust Book (Offizielles Tutorial der Sprache), ist auch auf Deutsch verfügbar.

    *** = Kein Anspruch auf Vollständigkeit, und teilweise gekürzt

    ===========================================================================
    :flag_gb:

    Hello everyone,


    As part of the changeover to the new engine, you are probably aware that the scripting language is also being changed. (For the time being) scripts will (only) be able to be created in Rust*.

    For this reason, Teneberus and I sat together and thought about what we could improve in the area of messaging (vehicle <> vehicle, vehicle <> module, module <> module) based on our experience with the previous script system. We also wanted to make use of the new possibilities that Rust offers us. Because we are not omniscient and do not know every use case, we want to present our suggestions here and collect feedback/suggestions for improvement.

    Basic explanation

    Firstly, I would like to explain the basic concept of the new script communication to everyone:

    The most important change compared to the system in Pascal is that in future there will no longer be a distinction between MessageToChild, MessageToParent, Broadcast, clutch variables, etc.. In Rust, everything is combined under one Message. This offers the advantage that messages can be delivered more flexibly to different destinations and also saves the effort of the need to define different receive functions in the script. In future, all Messages can be received via a function fn on_message(&mut self, msg: Message);.

    In addition, the restriction to the three data types String, Single, Integer no longer exists. From now on, a message can have any content as long as it fulfils the [Serialize, Deserialize] traits.** In addition, a message has 2 or 3 parameters, which are namespace, identifier, [bus].

    As before, the identifier is the name of the message. This can be freely chosen. The namespace is used to assign a message to a specific category. This is also important so that if two people use the same name for a message, they do not overwrite each other and errors occur. Namespaces can be e.g. Std for Lotus Standard Messages, or you can use your own acronym or nickname. The Bus value is optional when defining a message. The main purpose is to allow or prevent the sending of messages on a specific bus via the coupling based on the bus ID. Similar to this function in the old system.

    The last thing I want to explain as a basic principle is the sending of messages. For this purpose, there will be a function to which you pass the message to be sent and a list of destinations as parameters. The new features here are, on the one hand, that you can send directly to several recipients and, on the other hand, that you only have one general send function and no longer different ones depending on the recipient as before. There are several options as destinations for messages, which I will only briefly outline here: ***


    • Myself (Sends to the sender of the message)
    • ChildByIndex (Sends to a specific module slot)
    • Broadcast (Sends to all)
    • AcrossCoupling (Sends via the front or rear coupling)
    • Parent (Sends from modules to the parent vehicle)
    • ...


    With these basics about the new message system, I would next like to present the changes we have considered for the standard messages. This first article is only about the real basics. Functions and features that have not yet been implemented will follow at a later date.

    The messages presented here will all be defined in the standard scope and can be used directly as a structure. There will also be helper functions to simplify the sending of these messages.


    Vehicle number

    Previously, a string was sent here under the name VEH_NUMBER. We want to keep this as it is. The new message in Rust looks like this:

    Code
    1. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
    2. pub struct MsgVehNumber {
    3. pub value: String,
    4. }
    5. message_type!(MsgVehNumber, "Std", "Vehiclenumber"); // Namespace: "Std", Identifier: "Vehiclenumber" (Bus is not defined)

    This is/ should be sent via broadcast to the own vehicle and all modules when sending. There is no transmission by bus via the coupler.


    Main battery switch & battery voltage

    We have decided to merge these two pieces of information. Rust offers the option of variants of an enum carrying a data payload. We want to use this to transfer both pieces of information together. As you can see in the code snippet for enum Batteryvoltage, a float number is also transmitted with the On state. This represents the normalised battery voltage (i.e. 0.0 = no voltage, 1.0 = default voltage) In the Off state, no voltage needs to be transmitted as the battery is disconnected.

    This message replaces the previous BATTERYSWITCH (integer) and VOLTAGE (single). Here is the appropriate excerpt from the code:

    As with the car number, this information is only sent to all recipients in a single vehicle.

    Another important thing to note is that Battery = Off is the default for all objects. If a vehicle is spawned with the battery switched on at the start, this information must be sent once initially.


    Module power control

    This message will replace and extend the old message MAINSWITCH (integer). We want to extend the information content as follows. Firstly, for each switch-on/switch-off message there is information on where the status has just been changed. For example, central on-board computers that are technically included in an IBIS terminal can also switch on and off correctly. The values ACab and BCab indicate whether one of the two driver's cabs has been activated in the respective vehicle. With the NoCab status, the modules in the accompanied wagons also receive the information that a driver's cab has now been upgraded in the train set. The other change is a Boolean parameter in the switch-on message. This can be used to transmit the ‘Quickstart’ command (value = true). As a result, modules should skip the boot process and run directly in steady operation. One of the advantages of this is that you don't have to wait for long start procedures when debugging the module and it also ensures that the module is directly available in the active driver's cab when the ‘Place vehicle’ start option ‘Ready to drive’ is selected. Previously, you had to cheat a little here. Here is the code (shortened) for you to look at:

    The included information about the driver's cab means that this message is also sent directly to all modules (and the driver's own vehicle) via broadcast. The possibility of modules knowing in future which driver's cab they belong to means that they can react appropriately. The message is also NOT transmitted via the coupling and must be generated independently by each vehicle for its modules. Here too, the default status is switched off for all objects.


    Module lighting

    Here again we have less to suggest. We are replacing the previous broadcast LIGHT (single). This is now a value of type f32. The value range should be the normalised brightness, i.e. 0.0 = light off & 1.0 = default brightness.

    Code
    1. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
    2. pub struct MsgLight {
    3. pub value: f32,
    4. }
    5. message_type!(MsgLight, "Std", "Light"); // Namespace: "Std", Identifier: "Light" (Bus is not defined)

    In principle, all modules should receive this information. A deviation is also possible if different modules are connected to different lighting circuits, for example. The message is explicitly NOT transmitted via the coupling and must be sent in/for each vehicle in the train itself.


    Stop request

    The boradcast STOPREQUEST (single) was previously used here. In our proposal, the function is retained, only the data type is changed to Boolean.

    Code
    1. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
    2. pub struct MsgStopRequest {
    3. pub value: bool,
    4. }
    5. message_type!(MsgStopRequest, "Std", "StopRequest"); // Namespace: "Std", Identifier: "StopRequest" (Bus is not defined)

    As with the previous messages, this is NOT transmitted via the coupler. However, it should otherwise reach all modules in the vehicle. If there are several stop request circuits in a vehicle (e.g. a bus in the front vehicle and in the rear vehicle), messages can of course be sent with different receivers. Vehicles without a stop request (e.g. historic trains or underground trains) do not have to provide this information.


    Speed


    We have been thinking about this topic for a while. We are taking up the idea of the message VELOCITY (single), which has so far only reached the on-board computer. We also considered the idea of using the distance travelled or a fixed distance pulse instead of the vehicle's speed. However, we abandoned these ideas, as speed is simply the most versatile and also provides the most information.

    Code
    1. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
    2. pub struct MsgVelocity {
    3. pub value: f32,
    4. }
    5. message_type!(MsgVelocity, "Std", "Velocity"); // Namespace: "Std", Identifier: "Velocity" (Bus is not defined)

    The value is sent in metres per second. The +/- sign represents the direction of travel. This message is also NOT sent via the coupling, but must be sent in every vehicle. It is important here that different modules also receive different speeds


    Door condition

    Finally, we come to the door status information. Two different messages were used here in the previous Lotus. One is ATBUSSTOP (integer) and the other is DOORSOPEN (integer). We now want to merge these. This will no longer only contain the information ‘door release’ yes/no, but also the status of whether the doors have generally been opened and on which side the doors are released/opened.

    As with the other messages before, this information is NOT transmitted via the coupling so that the door side is not twisted in the case of asymmetrically coupled vehicles. Of course, there can also be several circuits here, e.g. in buses for the front end and the rear end. It is only important that all modules receive this information once.


    Feedback

    This brings us to the end of the first round of the presentation of our proposal. Please provide feedback and, above all, suggestions for changes and improvements or ask questions if necessary. Teneberus and I can only look at this from our perspective and may not have focussed on certain aspects. So that we get updated standards with the new version of Lotus, which hopefully everyone will use in order to achieve the greatest possible compatibility.

    The next topics we want to work on/revise are the train bus and, as part of this, the FIS messages between on-board computers and modules. If you have any input in advance, please feel free to let us know.



    And thank you for your attention.



    * = The reason for this is that the API/interface has to be fully developed first. It is just unnecessary extra work to work on interfaces for several languages at the same time. Other languages will certainly be possible in the future, but I cannot make any statements on this.

    ** = If you are not yet familiar with these terms, I recommend the Official Rust Book (official tutorial for the language).

    *** = No claim to completeness, and partly shortened

    Da zwischen den Lotus Scripten (der Plugin-Schnittstelle) und der angebundenen seriellen Schnittstelle eh ein Plugin stehen muss, kannst du dir ja gerne selber etwas Passendes schreiben, um deine Peripherie nach deinen wünschen anzusteuern.


    Sich hier einfach nur laut zu beschweren, dass sich der Simulator nicht deinen Wünschen beugt, ist schon etwas egoistisch. Die Kommunikation von Objekten in Lotus hat ganz andere Anforderungen und Funktionsweisen, als es in z.B. einer VDV 300 definiert ist. Wir haben und werden auch in der Zukunft immer versuchen, für Script-Standards ein passendes Maß an Realismus zu berücksichtigen, es aber nicht zum Maß aller Dinge machen. Eine detaillierte Umsetzung von einem realen Protokolle wäre ein massiver Mehraufwand für alle Entwickler von Content für den Simulator, dafür dass ein paar einzelne mit individuellen Anforderungen es leichter haben.

    Wie schon gesagt, steht für individuelle Lösungen die Plugin-Schnittstelle zur Verfügung.

    Wenn du schon nach 2 Monaten ohne Update hektisches Zucken bekommst, wird der gesamte Prozess hier für dich noch sehr zermürbend.

    Nach meinem letzten Wissensstand sind gerade die physikalischen Kräfte, die auf die Schienenfahrzeuge wirken, in Arbeit.

    Was das Thema GitHub angeht, kann ich dir versichern, dass noch alle Repos da sind. Wenn das Thema spruchreif wird, werden die bestimmt auch offiziell bekannt gegeben.