Lua Tabelle innerhalb einer Funktion

!!! Please ensure, that your contribution or question is placed into the relevant section !!!
Questions about rolling stock, for example, do not belong in "Questions about the Forum". Following is perhaps the right area where your question will be better looked after:
General questions to EEP , Splines, rolling stock, Structures in EEP, landscape elements, Signalling system and controlling, designers, Europe-wide EEP meetings , Gossip
Your cooperation to keep the forum clear is appreciated.
In the case of pictures that are attached to the article, the source must also be stated. This also applies to your own pictures, which were taken by you. Pictures without source information will be deleted!
  • Fried

    Hallo Fried,

    ich wünsche Dir noch ein gutes neues Jahr.

    Ich habe eine Frage zu einem Thema mit TagTexten in Verbindung mit Lua Tabellen.

    Vorgang:

    Ich lese TagTexte aus einer ausgewählten Lok aus und die Daten sollen in die Tabelle eingetragen werden zwecks Steuerung von Signalen und Fahrstraßen.

    Hier dazu der Teil des Skripts.

    Wieso funktioniert die Tabelle nur richtig wenn sie innerhalb der Funktion angelegt ist?

    Wenn ich die Tabelle außerhalb der Funktion anlege wird sie einmal mit Werten beschrieben.

    Bei einem erneuten Einlesen von Daten in die gleiche Tabelle werden die Daten nicht mehr überschrieben und es bleiben die vorher eingefügten Daten erhalten.

    Der Nachteil bei der Tabelle innerhalb der Funktion ist auch, dass ich jedes mal die Daten wieder neu einlesen muss wenn der Zug die selbe Strecke ein weiteres mal fahren soll, also keine Änderung der Fahrstrecke vorgenommen werden soll

    Mit dieser Funktion werden dann die Signale gestellt.

    Code
    -- Stellen der Signale und Fahrstrassen und Geschwindigkeit der Loks
    function Schaltung(Zugname)
            EEPSetSignal(words[Zugname][3], words[Zugname][4])     -- Ausfahrtsignal auf Halt stellen
            EEPSetSignal(words[Zugname][1], words[Zugname][2])     -- Fahrstrasse 1 stellen
            EEPSetSignal(words[Zugname][5], words[Zugname][6])     -- Fahrstrasse 2 stellen
            EEPSetTrainSpeed(Zugname, words[Zugname][7])           -- Geschwindigkeit einstellen
    end

    Der komplette Skript sieht so aus:

    Viele Grüße

    Karl Heinz

    Benutzte Programme und Hardware

    EEP 17.2 Expert [x64], Patch 1, PlugIn 1, 2

    HomeNos 17.0

    Tauschmanager, Model Multiplier, Modell Explorer

    Acer Nitro 5 AN517-41

    AMD Ryzen 7 5800H with Radeon Graphics

    64 GB RAM, nVidia Geforce RTX3080 Laptop GPU7552

    Windows 11 Home, Version 23H2, Betriebssystembuild 22631.3085

    Windows Defender

  • Hallo Karl Heinz Schmiermax ,

    ich schicke dir eine PN.

    Fried-liche Grüße:aq_1:

    Rentner sein ist wie Urlaub, nur 365 Tage im Jahr.

    Wen es interessiert ...

    PC: AMD Ryzen 5 5600X 6x3,7GHz; 32GB RAM; GeForce RTX3060XC 12GB; 2x 1TB SSD; Windows10Pro 64bit;

    Monitore: 2560x1440 (ASUS) + 1920x1080 (alt)

    Laptop: i7-4710HQ 2,5GHz; 8GB RAM; NVIDIA GeForce GTX860M; 125GB SSD + 1TB HDD; W10Pro64bit

    EEP: Aktuell 15.1.2 Plug-in 1, 17.2.1 Plug-in 1 + 2; HN17; AnlVerb17; MK; ME; ZE; TM; ...

  • Fried

    Vielen Dank für Deine schnelle Antwort.

    Viele Grüße

    Karl Heinz

    Benutzte Programme und Hardware

    EEP 17.2 Expert [x64], Patch 1, PlugIn 1, 2

    HomeNos 17.0

    Tauschmanager, Model Multiplier, Modell Explorer

    Acer Nitro 5 AN517-41

    AMD Ryzen 7 5800H with Radeon Graphics

    64 GB RAM, nVidia Geforce RTX3080 Laptop GPU7552

    Windows 11 Home, Version 23H2, Betriebssystembuild 22631.3085

    Windows Defender

  • Hallo Fried ,

    Die Antwort auf diese Frage ist doch auch für andere intressant.

    Gruß Gerd

    Hardwarekonfiguration:

    Laptop: Intel Core i5-9300H, 3,7 GHz, 8GB RAM, Win10 64 bit,

    NVIDIA GeForce GTX 1650

    EEP 12.1 Expert Plugin 1, EEP 16.4, EEP 17.

  • Hallo ghhb und alle, die das auch interessiert, wie z.B. Fussel ,

    ich habe vollstes Verständnis, dass das auch andere interessiert. Doch jetzt kommt das große ABER.

    Um manche Fragen beantworten zu können, muss man häufig Rückfragen stellen. Hier z.B., warum Karl Heinz überhaupt die Tabelle außerhalb der Funktion anlegen will. Warum will er die Texte ändern? Machen dann TagTexte überhaupt noch Sinn? Und, und und ...

    Natürlich kann man das "öffentlich" abklären. Aber häufig führen viele Wege nach Rom. Und wenn man das öffentlich abstimmt und Vorschläge macht, werden zum Teil Kommentare gepostet, die einen anderen Weg gehen. Die müssen nicht falsch sein, führen dann häufig aber zu Verwirrungen. Aus diesem Grund gibt es zwischen einigen (Lua-)Usern die stillschweigende Absprache, wenn einer sagt "Ich kümmere mich drum", halten die anderen die Füße still. Leider machen das nicht alle. Außerdem war die Frage in diesem Fall persönlich an mich gerichtet.

    Aus all diesen Gründen habe ich dieses Thema zumindest vorläufig geschlossen. Wenn ich die Frage letztlich nicht beantworten konnte oder wir keine Lösung gefunden haben, werde ich ihn wieder öffnen, damit andere zum Zug kommen können. Und wenn wir eine Lösung gefunden haben, gibt es 3 Möglichkeiten, entweder ich öffne hier wieder und einer von uns beiden schreibt sie hier oder wir veröffentlichen sie unter einem anderen (dann aussagekräftigeren) Titel oder beides mit Querlink.

    Fried-liche Grüße:aq_1:

    Rentner sein ist wie Urlaub, nur 365 Tage im Jahr.

    Wen es interessiert ...

    PC: AMD Ryzen 5 5600X 6x3,7GHz; 32GB RAM; GeForce RTX3060XC 12GB; 2x 1TB SSD; Windows10Pro 64bit;

    Monitore: 2560x1440 (ASUS) + 1920x1080 (alt)

    Laptop: i7-4710HQ 2,5GHz; 8GB RAM; NVIDIA GeForce GTX860M; 125GB SSD + 1TB HDD; W10Pro64bit

    EEP: Aktuell 15.1.2 Plug-in 1, 17.2.1 Plug-in 1 + 2; HN17; AnlVerb17; MK; ME; ZE; TM; ...

  • An alle an diesem Thema Interessierten, (Karl Heinz Schmiermax hat eine PN)

    Die eigentliche Frage hätte ich schon vorgestern Abend beantworten können. Aber da sah ich bereits, dass in dem Code meiner Meinung nach noch einiges im Argen war und ich ihn etwas umbauen musste. Dazu bin ich aber wegen anderer Verpflichtungen erst heute gekommen.

    Zur eigentlichen Frage "Warum funktioniert die Tabelle in der Funktion aber nicht außerhalb?":

    In der Funktion wurde jedes Mal eine sauberen Doppel-Tabelle definiert

    Lua
    words = { 
      ["#DB_120_110",] = {},
      ["#DB_216_beige"] = {}, 
    }

    In diese wurde dann nacheinander in die Untertabellen jeweils 7 Werte geschrieben.

    Lua
    for w in string.gmatch(Ausgabe, "[^, ]+") do
       table.insert(words[Fahrzeug], w)
    end

    Diese wurden später wieder abgefragt. Im nächsten Funktionsaufruf beginnt es wieder mit einer sauberen Tabelle, usw.

    Definiert man words außerhalb der Tabelle, also global, passiert folgendes. Beim ersten Aufruf der Funktion gibt es keinen Unterschied. Man schreibst jeweils die Werte 1 bis 7 in die entsprechende Untertabelle. Alles noch ok.

    Doch ab dem 2. Funktionsaufruf kommt ein Irrtum von Karl Heinz zum Tragen. table.insert ÜBERSCHREIBT NICHT sondern HÄNGT HINTEN AN. Da bereits Werte in den Tabellen bestehen, fügt er also in die jeweilige Tabelle die Werte 8 bis 14 ein und im 3. Aufruf die Werte 15 bis 21, usw. Abfragen tust er aber immer die Werte 1 bis 7.

    Zum übrigen Code:

    1. Die Funktion EEPOnSignal_X(Stellung) hat nur einen Parameter!

    2. Schmiermax schreibst einen TagText und liest ihn im selben Atemzug – sprich EEPMain-Zyklus – wieder aus. Das macht keinen Sinn! Es sei denn, man möchte die beiden Funktionen grundsätzlich testen. Dazu benötigt man aber das Brimborium drum herum nicht. TagTexte speichert man irgendwann (im Prinzip wie Slots) und liest sie dann aus, wenn man sie benötigt. D.h., aus den 4 Funktionen mach 2.

    3. Zu beachten ist, dass TagTexte – wie der Name schon sagt – Strings/Zeichenketten sind. Für die Signal- und Geschwindigkeitssteuerung werden aber Zahlen benötigt. D.h. die (entsprechenden / hier alle) Werte müssen mit der Lua-Funktion tonumber() in Zahlen umgewandelt werden.

    Noch ein paar persönliche Anmerkungen zu dem Code:

    Variablen kann man natürlich nach gut dünken benennen. Ich bin ein Freund von eindeutigen Namen, so dass ich selbst nach langer Zeit noch weiß, was die Variable beinhaltet. "w" oder "words" z.B. aber auch in diesem Fall Pos_1 und Pos_2 sind mir zu allgemein, zu bezugslos.

    Ganz schlimm finde ich persönlich aber, wenn man Zugnamen als "Fahrzeug" oder "Lok" bezeichnet. Zugnamen und Fahrzeugnamen unterscheiden sich mindestens durch das vorangestellte #-Zeichen. Und wenn man nach der xten Weitergabe in Funktionen nicht mehr sieht, dass das Fahrzeug eigentlich ein Zug ist, dann ist eine fehlerhafte Programmierung quasi vorprogrammiert.

    Dass die TagTexte in den Loks seiner beiden Züge ablegt werden, ist purer Zufall. Wäre einer der Züge z.B. ein Wendezug, könnte der TagText auch im Steuerwagen stecken. Schmiermax schreibst ihn immer in das Fahrzeug 0 des Zuges. Das ist sehr gut (!!!), denn jeder Zug (auch wenn er nur aus einer Lok besteht) hat ein Fahrzeug 0. Und das Fahrzeug 0 bleibt Nummer 0, auch wenn der Zug gewendet wird. Aber – wie gesagt – es muss nicht die Lok sein.

    Alle Variablen in dem Code sind global. Dass frisst Speicherplatz. Variablen, die nur innerhalb einer Funktion benötigt werden, sollte man "local" deklarieren. Das gilt auch, wenn man in einer Funktion die Variable XYZ in einen TagText schreibt und in einer anderen den TagText in eine Variable XYZ schreibt. Beide "local" deklarieren. Durch den gleichen Namen kann man den Code lesbarer machen. Durch die jeweilige local-Deklarierung werden es aber 2 unabhängige Variablen, die ihren Speicherplatz jeweils am Ende der Funktion wieder freigeben.

    Aber auch print-Befehle belasten EEP. Daher sollte man sie nur dann verwenden, 1.) wenn sie unbedingt nötigt sind (um z.B. anschließend im GBS händisch entsprechende Signale/Weichen zu stellen) und 2.) zur Fehlersuche. Dann aber nur wenn man wirklich auf Fehlersuche ist, danach dann sofort wieder kommentieren. Deswegen habe ich die prints belassen aber kommentiert.

    Hier mein angepasster Code:

    Ich kennzeichne dieses Thema von Schmiermax mit Frage beantwortet, öffne es aber wieder für kurze Zeit, damit Fragen zum eigentlichen Thema und zum Code gestellt werden können.

    Bitte keine Fragen zum Sinn und Zweck stellen, denn bei der Anlage handelt es sich um eine Test-Anlage, mit der Karl Heinz irgendetwas für sein "Saarbrücken" ausprobieren möchte. Nur WAS ist nicht bekannt. Spekulieren lohnt sich nicht. Dazu kann es ggf. einen eigenen Beitrag gebe.

    Fried-liche Grüße:aq_1:

    Rentner sein ist wie Urlaub, nur 365 Tage im Jahr.

    Wen es interessiert ...

    PC: AMD Ryzen 5 5600X 6x3,7GHz; 32GB RAM; GeForce RTX3060XC 12GB; 2x 1TB SSD; Windows10Pro 64bit;

    Monitore: 2560x1440 (ASUS) + 1920x1080 (alt)

    Laptop: i7-4710HQ 2,5GHz; 8GB RAM; NVIDIA GeForce GTX860M; 125GB SSD + 1TB HDD; W10Pro64bit

    EEP: Aktuell 15.1.2 Plug-in 1, 17.2.1 Plug-in 1 + 2; HN17; AnlVerb17; MK; ME; ZE; TM; ...

  • table.insert ÜBERSCHREIBT NICHT sondern HÄNGT HINTEN AN.

    Hallo :)

    richtig, deswegen heißt die Funktion ja auch nicht table.replace. Siehe dazu auch in der Doku das Kapitel 19.2 – Insert and Remove.

    Gruß Ingo

    Threema - Sicherer und privater Messenger

    Meine Threema-ID

    Warum Threema?

    Win 11x64 Professional, Gigabyte B360M AORUS, Intel Core i7-8700K, 32GB RAM, NVIDIA GeForce GTX 1050 Ti 4GB, Philips 273V7QDAB Full HD

    Windows Firewall und Defender
    EEP 15.1 Expert Patch 2, Plugins: 1

    EEP 16.4 Expert, Plugins: 1,2,3,4

    EEP 17.2 Expert, Plugins: 1,2

    alter PC

    Win 7x64 Professional SP1, Intel Core i5-3570, 16GB RAM, nVIDIA GeForce GT630, 2GB, 1920x1200 auf 26" TFT

    EEP6; EEP8-14; EEP 15.1 Expert Patch 2, Plugins: 1

  • Fried

    Vielen Dank für Deine gute Abarbeitung meines Problems mit Lua.

    Bin da nicht so der Experte, aber durch Fehler wird man schlauer.

    Doch ab dem 2. Funktionsaufruf kommt ein Irrtum von Karl Heinz zum Tragen. table.insert ÜBERSCHREIBT NICHT sondern HÄNGT HINTEN AN.

    Hallo Fried,

    das hätte mir eigentlich auch klar sein müssen dass table.insert nicht überschreibt sondern hinten an hängt. Habe da zu viel deutsch gedacht und nicht auf den englischen Begriff von insert geachtet.
    Hätte das leicht prüfen können indem ich einen Platz in der Tabelle abgefragt hätte der eigentlich gar nicht da sein sollte und was dann auch ohne die Ausgabe nil funktioniert hätte.

    Deinen abgeänderten Skript werde ich übernehmen mit einigen kleinen Änderungen:

    Den letzten Teil, welcher für das Stellen der Signale zuständig ist, werde ich in eine separate Funktion legen.

    Diese wird dann durch die auf den Gleisen liegenden Kontakten aufgerufen.

    So habe ich die Möglichkeit mit den Zählsignalen den TagText in den Loks so oft zu ändern wie ich will und die Ausführung erst zu aktivieren wenn der Zug los fährt und durch einen Kontakt aktiviert.

    Auch die Zählsignale werde ich erst auf Null zurück setzen wenn der Zug abgefahren ist.

    Das gibt mir die Möglichkeit die TagTexte zu überprüfen und zu ändern ohne das es Auswirkung auf die Lok hat solange sie nicht einen Kontaktpunkt überfährt welcher die Fahrstraßen und alles dazu gehörende dann schaltet.

    schlingo

    Hallo Ingo,

    vielen Dank für den Hinweis auf das Kapitel 19.2.

    Darauf bin ich bisher noch nicht gestoßen, habe da aber auch bisher zu wenig nachgelesen.

    Muss vielleicht einen anderen Begriff für insert benutzen um die Daten in der außerhalb der Funktion liegenden Tabelle zu überschreiben und diese dann erhalten bleiben. Bin noch nicht sicher welche Version ich benutzen werde.

    Viele Grüße

    Karl Heinz

    Benutzte Programme und Hardware

    EEP 17.2 Expert [x64], Patch 1, PlugIn 1, 2

    HomeNos 17.0

    Tauschmanager, Model Multiplier, Modell Explorer

    Acer Nitro 5 AN517-41

    AMD Ryzen 7 5800H with Radeon Graphics

    64 GB RAM, nVidia Geforce RTX3080 Laptop GPU7552

    Windows 11 Home, Version 23H2, Betriebssystembuild 22631.3085

    Windows Defender

  • hätte mir eigentlich auch klar sein müssen dass table.insert nicht überschreibt sondern hinten an hängt

    Hallo Karl-Heinz :)

    nein, auch da irrst Du. Dann würde die Funktion nämlich table.append heißen. table.insert hängt nur dann hinten an, wenn Du keine Position angibst.

    Gruß Ingo

    Threema - Sicherer und privater Messenger

    Meine Threema-ID

    Warum Threema?

    Win 11x64 Professional, Gigabyte B360M AORUS, Intel Core i7-8700K, 32GB RAM, NVIDIA GeForce GTX 1050 Ti 4GB, Philips 273V7QDAB Full HD

    Windows Firewall und Defender
    EEP 15.1 Expert Patch 2, Plugins: 1

    EEP 16.4 Expert, Plugins: 1,2,3,4

    EEP 17.2 Expert, Plugins: 1,2

    alter PC

    Win 7x64 Professional SP1, Intel Core i5-3570, 16GB RAM, nVIDIA GeForce GT630, 2GB, 1920x1200 auf 26" TFT

    EEP6; EEP8-14; EEP 15.1 Expert Patch 2, Plugins: 1

  • schlingo

    Hallo Ingo,

    ist die Position nicht durch die for Schleife vorgegeben?

    Dann müsste vor jedem neuen Eintrag durch die Schleife geprüft werden wo der letzte Eintrag war.

    Oder geschieht das durch string.gmatch?

    Werde da noch verschiedene Versuche machen um genau zu sehen was da abläuft.

    Viele Grüße

    Karl Heinz

    Benutzte Programme und Hardware

    EEP 17.2 Expert [x64], Patch 1, PlugIn 1, 2

    HomeNos 17.0

    Tauschmanager, Model Multiplier, Modell Explorer

    Acer Nitro 5 AN517-41

    AMD Ryzen 7 5800H with Radeon Graphics

    64 GB RAM, nVidia Geforce RTX3080 Laptop GPU7552

    Windows 11 Home, Version 23H2, Betriebssystembuild 22631.3085

    Windows Defender

  • Hallo Karl Heinz Schmiermax ,

    table.insert(t, [i,] v) fügt v am numerischen Index i [Standard: nach dem Ende] in die Tabelle t ein.

    Da i optional ist und du i auch nicht verwendet hast, habe ich es oben vereinfacht als hinten anhängt beschrieben, was ja auch der Default-Vorgehensweise entspricht.

    Hat also weder etwas mit der for-Schleife noch mit string.gmatch zu tun.

    Fried-liche Grüße:aq_1:

    Rentner sein ist wie Urlaub, nur 365 Tage im Jahr.

    Wen es interessiert ...

    PC: AMD Ryzen 5 5600X 6x3,7GHz; 32GB RAM; GeForce RTX3060XC 12GB; 2x 1TB SSD; Windows10Pro 64bit;

    Monitore: 2560x1440 (ASUS) + 1920x1080 (alt)

    Laptop: i7-4710HQ 2,5GHz; 8GB RAM; NVIDIA GeForce GTX860M; 125GB SSD + 1TB HDD; W10Pro64bit

    EEP: Aktuell 15.1.2 Plug-in 1, 17.2.1 Plug-in 1 + 2; HN17; AnlVerb17; MK; ME; ZE; TM; ...