EASY Geschrieben 17. Februar Autor Geschrieben 17. Februar Hallo, vor 4 Stunden schrieb Hawkeye: An einer Ampel z.B. muss jeder "virtuelle" Fahrer eines Fahrzeuges beim Umschalten von Grün auf Gelb eine Entscheidung in Abhängigkeit seiner Geschwindigkeit und dem aktuellen Abstand zur Ampel treffen. Soller er bremsen, um noch rechtzeitig an der Haltelinie der Ampel zum Stehen zu kommen oder soll er beschleunigen, um vor dem Umschalten der Ampelphase von Gelb auf Rot noch über die Ampel zu huschen. vor 4 Stunden schrieb Hawkeye: Hast du nicht Lust, dich auch mal mit solchen Aufgabestellungen zu beschäftigen? ... habe ich mal aus Spaß an der Freude gemacht... --[[ * -> in die Klammer entsprechende Referenzspur eintragen ** Verknüpfte Objekte mit Referenzspur: (Gleiskontakte und Fahrzeuge werden mit der Referenzspur automalisch verknüpft!) Gleiskontakt "GKe" mit Schlagwort "GKref" sehr nahe am Ende der Referenzspur (nicht am Übergang) plazieren, so daß die Zuordnung zu Referenzspur eindeutig gegeben ist. *** wenn zu stark abgebremst werden müßte -> durchfahren --]] local blink=layout:getEntitiesLinkedTo($("Bremsspur 1"))-- * ; ** local ref=0 -- Dummyeintrag local auto=0 -- Dummyeintrag for i,v in ipairs(blink) do -- verknüpfte Objekte if v.variables["GKref"]==keyword then -- Referenzkontakt? ref=v end local res=false res,auto=pcall(function(x) x:hasEngine() return x end,v)-- Fahrzeug mit Antrieb? end if auto~=0 and ref~=0 then auto.currentSpeed=auto.currentSpeed -- evtl. Beschleunigung abbrechen -- Bremsweg berechnen (Vorderkante Auto -> Ende Spur) local pos1=ref.transformation.position local pos2=auto.transformation.position local dx=pos1.x-pos2.x local dy=pos1.y-pos2.y local la=auto.length/2 local l=math.sqrt(dx^2+dy^2)-la -- benötigte Verzögerung berechnen... local v=auto.currentSpeedAbs v=v/3.6 local a=(v^2)/(2*l) vehicle.deceleration=a if a<20 then -- *** vehicle.targetSpeed=0 end end Bremsversuch 01.mbp Gruß EASY
Hawkeye Geschrieben 17. Februar Geschrieben 17. Februar (bearbeitet) vor 31 Minuten schrieb EASY: habe ich mal aus Spaß an der Freude gemacht... 😁👍 @Neo Die Berechnung des Bremsweges über die Position könnte man sich sparen, wenn es die Möglichkeit gäbe, den Abstand eines Fahrzeuges zu einem Gleiskontakt per Lua abzufragen. Dann könnten auch in Kurven tatsächliche Spurlängen ausgelesen werden und nicht nur der lineare Abstand zweier Punkte. Dieser Punkt wurde schon häufig gewünscht und trotz verschiedener Ansätze dieses auf anderem Wege zu lösen komme ich immer wieder auf die Notwendigkeit einer solchen Funktion zurück. Läßt sich das nicht doch realisieren? VG, Hawkeye Bearbeitet 17. Februar von Hawkeye
BahnLand Geschrieben 17. Februar Geschrieben 17. Februar Hallo zusammen, ich habe zu dem Bremsproblem am Gleis-Ende ein kleines Demo-Beispiel gemacht: Weiches Abbremsen am Gleisende.mbp Die Demo besteht aus 3 identischen Gleisabschnitten, die jeweils mit derselben Lok bestückt sind. Für eine weiche Verzögerung habe ich 0,4 m/s² eingestellt. Mit dem Taster im Vordergrund werden die Loks simultan vorwärts (Taster an) oder rückwärts (Taster aus) gestartet und auf 50 km/h beschleunigt. Der Unterschied zwischen den 3 Anordnungen besteht nun darin, dass beim der hinteren Lok die automatische Verzögerung eingeschaltet ist. Deshalb hält sie vor dem Prellbock (rechts) oder dem offenen Gleis-Ende (links) jeweils mt etwas Abstand an. Bei der mittlere Lok ist die automatische Verzögerung ausgeschaltet, weshalb sie mit unverminderter Geschwindigkeit auf den Prellbock auffährt und auch am anderen Gleis-Ende abrupt angehalten wird. Auch bei der vorderen Lok ist die automatische Verzögerung ausgeschaltet. Dort befinden sich aber unter dem Prellbock und auch am anderen Ende des Gleises jeweils ein Bremskontakt (gut sichtbar, wenn das Bild durch Anklicken vergrößert wird). Dieser bewirkt ein sanftes Abbremsen der Lok auch dann, wenn dort keine automatische Verzögerung eingestellt ist. Die Lok kommt dann mit dem Puffer genau in der Mitte des Bremskontakts sanft zum Stehen. Ich vermute, dass genau dies in der vorangehenden Diskussion angestrebt wurde. Viele Grüße BahnLand
EASY Geschrieben 17. Februar Autor Geschrieben 17. Februar Hallo an alle, ich wollte hier spezielle Lösungsansätze in lua vorstellen. Wenn es alternative Lösungsansätze gibt, macht das bitte in einem eigenen Thema, sonst wird dieses Thema aus dem Zusammenhang gerissen, wie leider schon viele Themen in diesem Forum. Gruß EASY
Hawkeye Geschrieben 18. Februar Geschrieben 18. Februar (bearbeitet) vor 20 Stunden schrieb EASY: ich wollte hier spezielle Lösungsansätze in lua vorstellen Hallo Easy, nimmst du denn Aufträge an? 😉 Ich versuche es einfach mal 😂 Eine nützliche Funktion wäre die Neusortierung einer Liste ab einem bestimmten Platz in der Liste. Beispiel: Ein Kreisverkehr oder eine Kreuzung gleichberechtigter Straßen (Rechts vor Links-Regel) hat an jeder Ein- und Ausfahrt Gleiskontakte die in Listen die Vorfahrtsregeln (Objekte sind Gleiskontakte) enthalten. In den Listen der Gleiskontakte sind die gleichen Objekte vorhanden. Die Listen unterscheiden sich nur in einer Reihenfolge, wie die Objekte in den Listen stehen müssen. Damit nicht in jedem Gleiskontakt eine Liste gespeichert werden muß, wäre ein Funktion nützlich, die anhand eines Parameters der vom Gleiskontakt gesetzt wird, nur auf eine Liste zurückgreift und die Liste in der gewünschten Reihenfolge sortiert zurückgibt. So das die Liste in der Kreuzung existiert und die Gleiskontakte über diese Funktion anhand ihres Parameters die Liste neu sortiert erhalten. Liste (gespeichert in der Kreuzung) mit den Objekten: 1 = GK-01 ; 2 = GK-02 ; 3 = GK-03 ; 4 = GK-04 Wird die Funktion vom jeweiligen Gleiskontakt aufgerufen, soll das folgende Ergebnis zurückgegebenen werden. Bei Aufruf von GK-1: Rückgabe (der Liste) in der Reihenfolge 2; 3; 4; 1 GK-2: Rückgabe in der Reihenfolge 3; 4; 1; 2 GK-3: Rückgabe in der Reihenfolge 4; 3; 2; 1 GK-4: Rückgabe in der Reihenfolge 1; 2; 3; 4 Wäre das was für dich? VG, Hawkeye Bearbeitet 18. Februar von Hawkeye
EASY Geschrieben 18. Februar Autor Geschrieben 18. Februar Hallo @Hawkeye, Ich könnte Dir folgende (logische) Reihe anbieten: [16:54:04] Gleiskontakt wird ausgelöst -> GK-1, Golf 1, 1 [16:54:04] Gleiskontakt wird ausgelöst [16:54:04] Gleiskontakt: GK-1 hat ausgelöst [16:54:04] Liste: [16:54:04] GK-2 [16:54:04] GK-3 [16:54:04] GK-4 [16:54:04] GK-1 [16:54:16] Gleiskontakt wird ausgelöst -> GK-2, Golf 1, 1 [16:54:16] Gleiskontakt wird ausgelöst [16:54:16] Gleiskontakt: GK-2 hat ausgelöst [16:54:16] Liste: [16:54:16] GK-3 [16:54:16] GK-4 [16:54:16] GK-1 [16:54:16] GK-2 [16:54:24] Gleiskontakt wird ausgelöst -> GK-3, Golf 1, 1 [16:54:24] Gleiskontakt wird ausgelöst [16:54:24] Gleiskontakt: GK-3 hat ausgelöst [16:54:24] Liste: [16:54:24] GK-4 [16:54:24] GK-1 [16:54:24] GK-2 [16:54:24] GK-3 [16:54:31] Gleiskontakt wird ausgelöst -> GK-4, Golf 1, 1 [16:54:31] Gleiskontakt wird ausgelöst [16:54:31] Gleiskontakt: GK-4 hat ausgelöst [16:54:31] Liste: [16:54:31] GK-1 [16:54:31] GK-2 [16:54:31] GK-3 [16:54:31] GK-4 ... dies wäre allerdings eine andere Reihenfolge bei GK-3 als Du angegeben hast. vor 3 Stunden schrieb Hawkeye: GK-3: Rückgabe in der Reihenfolge 4; 3; 2; 1 Hast Du Dich da vertippt oder muß es die von Dir angegebene Reihenfolge sein? Gruß EASY
Hawkeye Geschrieben 18. Februar Geschrieben 18. Februar vor 19 Minuten schrieb EASY: ... dies wäre allerdings eine andere Reihenfolge bei GK-3 als Du angegeben hast. vor 3 Stunden schrieb Hawkeye: GK-3: Rückgabe in der Reihenfolge 4; 3; 2; 1 Hast Du Dich da vertippt oder muß es die von Dir angegebene Reihenfolge sein? Hallo Easy, Du hast natürlich recht, da habe ich mich verschrieben. 🙄 Bei GK- 3 ist die Folge 4,1,2,3 das richtige Ergebnis. Aber genau um solche Fehler geht es auch. Wie schnell baut man beim stupiden Kopieren der Listen und Ändern der Reihenfolge logische Fehler ein, die man dann nur sehr schwer identifizieren kann. 😊 Super gemacht, danke. 👍👍👍😃 Ich finde, das solche kleinen Funktionen für Listen sehr hilfreich sein können. @Goetz hatte mal eine ähnliche Funktion zum Umkehren einer Liste geschrieben die aus 1,2,3,4 dann 4,3,2,1 macht. Diese ist auch sehr hilfreich. VG, Hawkeye
EASY Geschrieben 18. Februar Autor Geschrieben 18. Februar Hallo @Hawkeye, ... eine kleine Demoanlage zu Deinem Anliegen... Gleiskontakt wird betreten sieht so aus... * Die Funktion teilt einen String am Seperator in Teilstrings auf Beispiel: Gleiskuntaktname: "GK-1" -> Seperator="-" ergibt die beiden Teilstrings "GK" (a[1]) und "1" (a[2]) a[2] dient als Zahlengrundlage für das zyklische Anlegen der Ausgabeliste Achtung: Mit diesem Verfahren liegt die Referenzzahl im Namen des Gleiskontaktes! -> der Name darf im MBS Projekt nur einmal vorkommen! ** alternativ kann auch eine Zahlenvariable im Gleiskontakt verwendet werden die Zeile **(a) entfällt und bei **(b) a[2] durch die Variable ersetzen. --]] local ausgabe={}-- Ausgabeliste local a={}-- teporäre Liste für GK-x Namen zerlegen local gk=contact.name -- Name des Gleiskontaktes print("Gleiskontakt: "..gk.." hat ausgelöst") gk:gsub("[^-]+",function(c) table.insert(a,c) end)--* / **(a) local gkx=$("Kreuzung 1").variables["GK x"]--Liste in der Kreuzung n=#gkx --Anzahl der Einträge in der Liste print("Liste:") for i=1+a[2],n+a[2]do --Liste vom Anfangswert her zyklisch erstellen **(b) local x=math.tointeger((i % n))-- Ergibt den Rest einer Division if x==0 then -- Rest=0 table.insert(ausgabe,gkx[n])-- maximalen Wert nehmen else -- Rest>0 table.insert(ausgabe,gkx[x])-- Restwert nehmen end end for i,v in ipairs(ausgabe)do --Ausgabetabelle print(v.name) end Anmerkung: Ich habe das Ereignis allen 4 Gleiskontakten zugeordnet (sinnvoll wäre evtl. mit Schlagworten zu arbeiten)... 2024-02-18-Zyklische Liste erstellen 01.mbp Gruß EASY2024-02-18-Zyklische Liste erstellen 01.mbp2024-02-18-Zyklische Liste erstellen 01.mbp2024-02-18-Zyklische Liste erstellen 01.mbp2024-02-18-Zyklische Liste erstellen 01.mbp
Hawkeye Geschrieben 18. Februar Geschrieben 18. Februar Hallo Easy, vor 18 Minuten schrieb EASY: .. eine kleine Demoanlage zu Deinem Anliegen... super, vielen Dank. Perfektes Ergebnis vor 19 Minuten schrieb EASY: Anmerkung: Ich habe das Ereignis allen 4 Gleiskontakten zugeordnet (sinnvoll wäre evtl. mit Schlagworten zu arbeiten)... Ich baue es mir als function() für ein Skript-Ereignis um, dann kann ich es beliebig einsetzten. VG, Hawkeye
Hawkeye Geschrieben 19. Februar Geschrieben 19. Februar (bearbeitet) Hallo Easy, vor 14 Stunden schrieb EASY: gk:gsub("[^-]+",function(c) table.insert(a,c) end)--* / **(a) Wow, das geht über meinen Horizont und übersteigt meine Kenntnisse in Lua! vor 14 Stunden schrieb EASY: Achtung: Mit diesem Verfahren liegt die Referenzzahl im Namen des Gleiskontaktes! -> der Name darf im MBS Projekt nur einmal vorkommen! Danke für den Hinweis, deshalb ist mir diese Variante zu unsicher. Dann kann man die Kreuzung mit den Gleiskontakten nicht kopieren, ohne alle Bezeichnungen zu überarbeiten. Ich favorisiere deshalb deine zweite Variante mit Übergabe einer Nummer. Funktioniert super. Wieder was dazu gelernt. Nochmals danke. Damit lässt sich doch was anfangen. VG, Hawkeye Bearbeitet 19. Februar von Hawkeye
EASY Geschrieben 19. August Autor Geschrieben 19. August (bearbeitet) Hallo, ausgehend von diesem Thema von @Rotti hat mich eine Lösung in lua interessiert. Zwar gibt es in dem Thread schon Lösungen aber ich möchte es hier als Gesamtprojekt vorstellen. Die Aufgabenstellung ist ein Lauflicht mit Leuchtpaaren die in einer Linie nacheinander aufleuchten sollen... ... die Idee die Leuchtpaare durch eine Verbindung zu erzeugen stammt von @Phrontistes, so muß nur die untere Leuchte angesteuert werden... Ausgangslage: 2 Leisten (Ebenen) entlang derer die Leuchten platziert werden sollen und eine Leuchte ("Leuchtwürfel" 243FA8AB-7111-4545-98C4-5E168D686BDA) ... die Leuchte bekommt das Schlagwort "LW1"... ... durch Duplizieren die gewünschte Anzahl (muß durch 2 teilbar sein!) Leuchten erzeugen... ... in der Stückliste sieht es nun so aus... viele "Leuchtwürfel"... Nach "Init" betätigen sieht es nun so aus... ... die obere Leiste ("LS1b") ist in x (und z) an der unteren Leiste ("LS1a") ausgerichtet, die Leuchten sind gleichmäßig verteilt und mit eindeutigen Namen versehen ... und die Verbindungen wurden gesetzt (LW1a xx -> LW1b xx) ... in der unteren Leiste "LS1a" wurden diese Variablen gesetzt... ... als Leuchten "LW" diese... ... in der oberen Leiste "LS1b" wurde die Variable "LW" gesetzt... ... mit diesen Einträgen... ... mit "Start" kann nun das Lauflicht gestartet werden... ... sollte sich aus optischen Gründen herausstellen, daß z.B. zu wenig Leuchten vorhanden sind, können durch Duplizieren weitere Leuchten erzeugt werden... ... und mit "Init" erfolgt die Verteilung neu... Das lua Skipt von "Init"... -[[ * index a=Master ; Index b=Slave ** i= 1 2 3 4 5 6 ... LW1a= 1 - 2 - 3 - ... LW1b= - 1 - 2 - 3 ... --]] -- Funktion Leuchten auf Leiste ausrichten local function ausricht(ls) local l=ls.size.x -- Länge Leiste (ls) local r=ls.variables["LW"] -- Leuchten einlesen local d=r[1].size.x -- Abmessung erstes Element in x l=l-2*d -- Anfangs- und Endposition -> Versatz local dx=l/(#r-1) -- Berechnung Abstand der Elemente local pos=ls.transformation.position -- Hilfsvariable Position local x=pos.x-l/2 -- x-Position Hilfsvariable for i,v in ipairs(r) do -- Alle Elemente der Liste pos.x=x+(i-1)*dx -- x.Position berechnen v.transformation.position=pos -- Element positionieren v.link=ls -- Leuchte mit Leiste verknüpfen end end -- Leuchten Namen vergeben -- Leuchten als Objektvariablen (Liste) in Leisten schreiben local lwa=layout:getEntitiesByKeyword("LW1") -- alle Leuchten $("LS1a").variables.LW={} -- Leiste 1 * $("LS1b").variables.LW={} -- Leiste 2 * for i,lw in ipairs(lwa) do -- alle Leuchten lw.state=0 -- Leuchte ausschalten lw.connection=nil -- eventuelle Verbindungen löschen lw.link=nil -- eventuelle Verknüpfung löschen if i%2==1 then -- ungerade Zahl (Leuchten für LS1a) lw.name=string.format("LW1a %02d",i//2+i%2) --** table.insert($("LS1a").variables.LW,lw) -- Leuchten Namen * else -- gerade Zahl (Leuchten für LS1b) lw.name=string.format("LW1b %02d",i//2+i%2) --** table.insert($("LS1b").variables.LW,lw) -- Leuchten Namen * end end -- Leuchtenpaare erzeugen -- Duch die Verbindung von LW1a xx zu LW1b xx braucht nur LW1a angesteuert werden for i,lw in ipairs($("LS1a").variables.LW) do -- alle LW1a * lw.connection=$("LS1b").variables.LW[i] -- Verbinden mit LW1b (Leuchtenpaar bilden) * end -- Objektvariablen in LS1a schreiben $("LS1a").variables.LWnr=1 -- Zähler aktuelle Leuchte (LWa) $("LS1a").variables.Farben={1,2,5} -- mögliche Farben für Farbwechsel $("LS1a").variables.Farbnr=1 -- aktuelle Farbnummer -- Leisten LS1b zu LS1a ausrichten (x- und z-Position) -- die y-Position von LS1b bestimmt den Abstand der Leisten local posb=$("LS1b").transformation.position -- Sollposition LS1b posb.x=$("LS1a").transformation.position.x -- Linksbündig zu LS1a $("LS1b").transformation.position=posb --LS1b positionieren $("LS1b").link=$("LS1a") -- "LS1b" mit "Ls1a" verknüpfen -- Leuchten auf Leiste ausrichten ausricht($("LS1a")) ausricht($("LS1b")) ... "Start"... --[[ --]] $("LS1a").variables.LWnr=1 -- Zähler aktuelle Leuchte (LWa) zurücksetzen $("LS1a").variables.Farbnr=1 -- aktuelle Farbnummer zurücksetzen if state==1 then $("Ereignisse").timers["LS1"]:start(0.15,true) -- Timer Starten else $("Ereignisse").timers["LS1"]:stop() -- Timer anhalten for i,lw in ipairs($("LS1a").variables.LW) do -- alle Leuchten LW1a lw.state=0 -- Leuchten ausschalten end end ... "Timer läuft ab"... --[[ --]] if $("LS1a").variables.LWnr>#$("LS1a").variables.LW then -- Letzte Leuchte war aktiv? $("LS1a").variables.LWnr=1 -- Zähler aktuelle Leuchte (LWa) zurücksetzen local fnr=$("LS1a").variables.Farbnr -- Farbnummer fnr=fnr+1 if fnr>#$("LS1a").variables.Farben then -- Hilfsvariable Farbnummer > Anzahl Farben fnr=1 -- Farbnummer zurücksetzen end $("LS1a").variables.Farbnr=fnr -- Variable mit Hilfsvariabe setzen else local farbe=$("LS1a").variables.Farben[$("LS1a").variables.Farbnr] local lw=$("LS1a").variables.LW[$("LS1a").variables.LWnr] $("Lampe LS1 ein aus"):invoke(farbe,lw) -- Leuchte ein/aus schalten $("LS1a").variables.LWnr=$("LS1a").variables.LWnr+1 -- nächte Leuchte end ... benuterdefiniertes Ereignis "Lampe LS1 ein aus"... --[[ * Hinweis: Ist die Verzögerung <= der Timerzeit leucht ein Leuchtenpaar. Bei kleiner Verzögerung "blitzt" das Leuchtenpaar auf Ist die Verzögerung ein ganzzahliges Vielfaches der Timerzeit leuchten die entsprechende Anzahl an Leuchtenpaaren --]] if not deferredCall then lw.state=farbe -- Leuchte einschalten (Farbe) defer(0.1,"vz1") elseif deferredCall=="vz1" then -- * lw.state=0 -- Leuchte ausschalten end Die prinzipielle Idee mit dem benuterdefiniertem Ereignis "Lampe LS1 ein aus" stammt von @Goetz, damit kann man mit geeignetem Verhältnis von Timer-Zeit und Verzögerung gewisse Leuchteffekte erzeugen (Leuchte blitzt kurz auf, mehrere Leuchten leuchten gleichzeitig...) Zum Schluß noch das Projekt... Lauflicht Liste EASY.mbp Gruß EASY Nachtrag: Bei "Init" werden jetzt noch die Leuchten mit den entsprechenden Leisten und "LS1b" mit "LS1a" verknüpft. Damit wird bei Bewegung oder Drehung von "LS1a" alles andere mit bewegt. Bearbeitet 19. August von EASY
EASY Geschrieben 20. August Autor Geschrieben 20. August Hallo, ich wurde per PN noch darauf angesprochen, daß es nur bei horizontaler Ausrichtung funktioniert. Deshalb habe ich es noch auf eine beliebige Ausrichtung erweitert... Ausgangssituation: "LS1a" muß in Position und Rotation richtig platziert sein. Position und Rotation von "LS1b" müssen nicht genau sein. Der Mittelpunkt von "LS1b" bestimmt dem Parallelabstand. (Die Fläche (türkis) dient der optischen Orientierung) ... Ergebnis... ... das Projekt für eigene Versuche... Lauflicht Liste beliebiger Winkel EASY.mbp Gruß EASY
EASY Geschrieben 22. August Autor Geschrieben 22. August (bearbeitet) Hallo, Die Idee geistert mir schon lange im Kopf herum und irgendwann setze ich es dann doch um... Entlang dieser Strecke... ... sollen die "Hektometer-Tafeln" (D51CAB33-09EB-433D-80BF-A700E5665F9F) an "richtiger" Position gesetzt werden. Vorbereitung: ... am Streckenanfang... - als "Lok ref" wurde die "Peil-Lok" (AFE18725-9A8B-4DF7-87D2-C5D9BD4DDBE4) gewählt. Sie hat den Vorteil, daß sie ebenso wie die Tafeln in y-Richtung ausgerichtet ist. So kann die Orientierung der Lok problemlos von den Tafeln übernommen werden. - der Gleiskontakt am Anfang der Strecke bestimmt die Position der 1. Tafel - da man in lua keine Objekte kopieren kann, gibt er einen Vorrat an Tafeln zum Setzen. ...am Streckenende... ... der Gleiskontakt sollte etwas hinter dem Ende der Strecke liegen. Objektvariablen: ...der Lok... - Tname -> Name den die Tafeln erhalten sollen - Tsw -> Schlüsselwort der Tafeln, die gesetzt werden sollen - abstand -> Abstand der Tafeln zueinander in m (Da es sich um Hektometertafeln handelt sind nur Werte mit ganzen 100-er Zahlen sinnvoll [0, 100, 200...] ) - km_anfang -> Kilometeranzeige der 1. Tafel (ganze Zahl oder 1-stellig hinter dem Komma) ...Gleiskontakt am Anfang... ...Gleiskontakt am Ende... ...die Tafeln... Nach "Start" werden... ...die Tafeln "richtig" beschriftet... ...die Tafeln in einer Objektliste in der Lok hinterlegt... ... und die Tafeln umbenannt (Tname Kilometer[3 stellig] Hektometer)... so kann auch über den Namen im Projekt zu einer Stelle gefunden werden... Am ersten Gleiskontakt wird (beim Erreichen der Lok) die 1. Tafel gesetzt... ... auf der Strecke ist das Setzen gesteuert über einen Timer (Die Lokgeschwindigkeit darf nicht verändert werden!) Anmerkung: Die Tafeln werden mit dem Gleis, auf dem sich die Lok beim Setzen befindet, verknüpft und werden auch an einer Steigung immer senkrecht ausgerichtet. ...am Gleiskontakt hinter dem Streckenende stoppt die Lok... ...da nicht alle bevorrateten Tafeln gebracht wurden, sind noch ein paar übrig (wenn sie nicht gebraucht werden können sie gelöscht werden) Die Abweichung der letzten Tafel in der Position ist (nach meiner Meinung) sehr gering (nach 50 Zwischenschritten)... (Zur optischen Referenz, ist im Versuchsprojekt jedes Gleis der Strecke 100m lang) Hinweis: Die Genauigkeit ist abhängig von der Geschwindigkeit der Lok und ob die (sehr [>>>]) beschleunigte Animation im MBS aktiv war. Noch das Versuchsprojekt (alles schon vorbereitet...) 2024-08-21 Hektometertafel.mbp Gruß EASY Bearbeitet 22. August von EASY
EASY Geschrieben 27. August Autor Geschrieben 27. August (bearbeitet) Hallo, Manchmal finde ich folgendes bei einem Textfeld störend... Wenn einem Textfeld (C1040AD7-0E8B-493F-B7C7-AEAA19A41855)... ... z.B. Zeilen hinzugefügt werden, dann ändert sich die Höhe (bezogen auf den mittigen Nullpunkt) in beide Richtungen... ... dies kann z.B. bei einem geneigten Textfeld (Rotation in x-Richtung)... ...wenn z.B. Zeilen hinzugefügt werden dazu führen, daß das Textfeld teilweise in der Bodenplatte verschwindet... ... auch ist in diesem Fall das Platzieren von eventuellen Bedienelementen nicht ganz einfach... ... zumal, wenn die Drehung um mehrere Achsen erfolgt... Ausgangspunkt für mein Projekt (das prinzipielle Layout habe ich von einem Projekt von @prinz "entliehen")... ... die beiden Textfelder haben unterschiedliche Anforderungen, wenn Zeilen hinzugefügt oder gelöscht werden. Dazu wird jeweils ein Fixpunkt und eine Ausrichtung für die Größenänderung festgelegt. Ausgangspunkt für das Textfeld in Bild unten rechts: Ein Textfeld (gelb) und Bedienelemente (blau)... ... das Textfeld hat die Objektvariable "oben"... - oben=true -> Fixpunkt (Nullpunkt) = oben links - "oben=false" -> Fixpunkt (Nullpunkt) = unten links ... und die Bedienelemente sind in der Liste "TS" hinterlegt.... ... das Textfeld wird positioniert... ... und erweitert ["Liste einlesen" betätigen] sich nach unten... ... und beim löschen von Zeilen nach oben... ... wobei die Position des Fixpunktes erhalten bleibt. Bei einer im Raum gedrehten Liste (im Beispiel x und z) ... wird "oben" auf false gesetzt (Fixpunkt unten links)... ... dadurch erweitert sich das Textfeld nach oben und verschwindet nicht (teilweise) in der Bodenplatte (und die Bedienelemente werden "richtig" positieniert)... Im Skript wird die Höhe einer Zeile ermittelt so daß wenn das Textfeld... ... skaliert wird... ... werden die neuen Zeilenabstände für das Positionieren der Bedienelemente berücksichtigt (und die Bedienelemente werden mit skaliert)... Abschließend noch das Projekt für eigene Versuche... 2024-08-25-Depotliste 04.mbp Gruß EASY Bearbeitet 27. August von EASY
Phrontistes Geschrieben 27. August Geschrieben 27. August Bezüglich der TextBox, ist gut, dies zu wissen. Ich schreibe max. 23 Zeilen untereinander und mache dann, wenn nötig, eine zweite Spalte auf.
Rotti Geschrieben 27. August Geschrieben 27. August Am 19.8.2024 um 14:18 schrieb EASY: Hallo, ausgehend von diesem Thema von Rotti hat mich eine Lösung in lua interessiert. Zwar gibt es in dem Thread schon Lösungen aber ich möchte es hier als Gesamtprojekt vorstellen. Die Aufgabenstellung ist ein Lauflicht mit Leuchtpaaren die in einer Linie nacheinander aufleuchten sollen... ... die Idee die Leuchtpaare durch eine Verbindung zu erzeugen stammt von Phrontistes, so muß nur die untere Leuchte angesteuert werden... Ausgangslage: 2 Leisten (Ebenen) entlang derer die Leuchten platziert werden sollen und eine Leuchte ("Leuchtwürfel" 243FA8AB-7111-4545-98C4-5E168D686BDA) ... die Leuchte bekommt das Schlagwort "LW1"... ... durch Duplizieren die gewünschte Anzahl (muß durch 2 teilbar sein!) Leuchten erzeugen... ... in der Stückliste sieht es nun so aus... viele "Leuchtwürfel"... Nach "Init" betätigen sieht es nun so aus... ... die obere Leiste ("LS1b") ist in x (und z) an der unteren Leiste ("LS1a") ausgerichtet, die Leuchten sind gleichmäßig verteilt und mit eindeutigen Namen versehen ... und die Verbindungen wurden gesetzt (LW1a xx -> LW1b xx) ... in der unteren Leiste "LS1a" wurden diese Variablen gesetzt... ... als Leuchten "LW" diese... ... in der oberen Leiste "LS1b" wurde die Variable "LW" gesetzt... ... mit diesen Einträgen... ... mit "Start" kann nun das Lauflicht gestartet werden... ... sollte sich aus optischen Gründen herausstellen, daß z.B. zu wenig Leuchten vorhanden sind, können durch Duplizieren weitere Leuchten erzeugt werden... ... und mit "Init" erfolgt die Verteilung neu... Das lua Skipt von "Init"... -[[ * index a=Master ; Index b=Slave ** i= 1 2 3 4 5 6 ... LW1a= 1 - 2 - 3 - ... LW1b= - 1 - 2 - 3 ... --]] -- Funktion Leuchten auf Leiste ausrichten local function ausricht(ls) local l=ls.size.x -- Länge Leiste (ls) local r=ls.variables["LW"] -- Leuchten einlesen local d=r[1].size.x -- Abmessung erstes Element in x l=l-2*d -- Anfangs- und Endposition -> Versatz local dx=l/(#r-1) -- Berechnung Abstand der Elemente local pos=ls.transformation.position -- Hilfsvariable Position local x=pos.x-l/2 -- x-Position Hilfsvariable for i,v in ipairs(r) do -- Alle Elemente der Liste pos.x=x+(i-1)*dx -- x.Position berechnen v.transformation.position=pos -- Element positionieren v.link=ls -- Leuchte mit Leiste verknüpfen end end -- Leuchten Namen vergeben -- Leuchten als Objektvariablen (Liste) in Leisten schreiben local lwa=layout:getEntitiesByKeyword("LW1") -- alle Leuchten $("LS1a").variables.LW={} -- Leiste 1 * $("LS1b").variables.LW={} -- Leiste 2 * for i,lw in ipairs(lwa) do -- alle Leuchten lw.state=0 -- Leuchte ausschalten lw.connection=nil -- eventuelle Verbindungen löschen lw.link=nil -- eventuelle Verknüpfung löschen if i%2==1 then -- ungerade Zahl (Leuchten für LS1a) lw.name=string.format("LW1a %02d",i//2+i%2) --** table.insert($("LS1a").variables.LW,lw) -- Leuchten Namen * else -- gerade Zahl (Leuchten für LS1b) lw.name=string.format("LW1b %02d",i//2+i%2) --** table.insert($("LS1b").variables.LW,lw) -- Leuchten Namen * end end -- Leuchtenpaare erzeugen -- Duch die Verbindung von LW1a xx zu LW1b xx braucht nur LW1a angesteuert werden for i,lw in ipairs($("LS1a").variables.LW) do -- alle LW1a * lw.connection=$("LS1b").variables.LW[i] -- Verbinden mit LW1b (Leuchtenpaar bilden) * end -- Objektvariablen in LS1a schreiben $("LS1a").variables.LWnr=1 -- Zähler aktuelle Leuchte (LWa) $("LS1a").variables.Farben={1,2,5} -- mögliche Farben für Farbwechsel $("LS1a").variables.Farbnr=1 -- aktuelle Farbnummer -- Leisten LS1b zu LS1a ausrichten (x- und z-Position) -- die y-Position von LS1b bestimmt den Abstand der Leisten local posb=$("LS1b").transformation.position -- Sollposition LS1b posb.x=$("LS1a").transformation.position.x -- Linksbündig zu LS1a $("LS1b").transformation.position=posb --LS1b positionieren $("LS1b").link=$("LS1a") -- "LS1b" mit "Ls1a" verknüpfen -- Leuchten auf Leiste ausrichten ausricht($("LS1a")) ausricht($("LS1b")) ... "Start"... --[[ --]] $("LS1a").variables.LWnr=1 -- Zähler aktuelle Leuchte (LWa) zurücksetzen $("LS1a").variables.Farbnr=1 -- aktuelle Farbnummer zurücksetzen if state==1 then $("Ereignisse").timers["LS1"]:start(0.15,true) -- Timer Starten else $("Ereignisse").timers["LS1"]:stop() -- Timer anhalten for i,lw in ipairs($("LS1a").variables.LW) do -- alle Leuchten LW1a lw.state=0 -- Leuchten ausschalten end end ... "Timer läuft ab"... --[[ --]] if $("LS1a").variables.LWnr>#$("LS1a").variables.LW then -- Letzte Leuchte war aktiv? $("LS1a").variables.LWnr=1 -- Zähler aktuelle Leuchte (LWa) zurücksetzen local fnr=$("LS1a").variables.Farbnr -- Farbnummer fnr=fnr+1 if fnr>#$("LS1a").variables.Farben then -- Hilfsvariable Farbnummer > Anzahl Farben fnr=1 -- Farbnummer zurücksetzen end $("LS1a").variables.Farbnr=fnr -- Variable mit Hilfsvariabe setzen else local farbe=$("LS1a").variables.Farben[$("LS1a").variables.Farbnr] local lw=$("LS1a").variables.LW[$("LS1a").variables.LWnr] $("Lampe LS1 ein aus"):invoke(farbe,lw) -- Leuchte ein/aus schalten $("LS1a").variables.LWnr=$("LS1a").variables.LWnr+1 -- nächte Leuchte end ... benuterdefiniertes Ereignis "Lampe LS1 ein aus"... --[[ * Hinweis: Ist die Verzögerung <= der Timerzeit leucht ein Leuchtenpaar. Bei kleiner Verzögerung "blitzt" das Leuchtenpaar auf Ist die Verzögerung ein ganzzahliges Vielfaches der Timerzeit leuchten die entsprechende Anzahl an Leuchtenpaaren --]] if not deferredCall then lw.state=farbe -- Leuchte einschalten (Farbe) defer(0.1,"vz1") elseif deferredCall=="vz1" then -- * lw.state=0 -- Leuchte ausschalten end Die prinzipielle Idee mit dem benuterdefiniertem Ereignis "Lampe LS1 ein aus" stammt von Goetz, damit kann man mit geeignetem Verhältnis von Timer-Zeit und Verzögerung gewisse Leuchteffekte erzeugen (Leuchte blitzt kurz auf, mehrere Leuchten leuchten gleichzeitig...) Zum Schluß noch das Projekt... Lauflicht Liste EASY.mbp Gruß EASY Nachtrag: Bei "Init" werden jetzt noch die Leuchten mit den entsprechenden Leisten und "LS1b" mit "LS1a" verknüpft. Damit wird bei Bewegung oder Drehung von "LS1a" alles andere mit bewegt. Hallo easy, viel Dank für den Versuch mir hier zu helfen. Nur ich muss dazu sagen und mir ein eingestehen, dass mir was weiter oben erklärt wird überhaupt nichts sagt. Ich komme mir immer noch wie ein Erstklässler vor, deshalb bin über jede Hilfestellung dankbar. Folge dessen bin ich total unbescholten in Sachen Lua, Scripts und weis überhaupt nichts damit anzufangen. Die beiden beigefügten Dateien habe ich geöffnet, dann zunächst auf Init und auf Start geklickt. Aber nichts hat geblinkt oder ist gelaufen. Vielen Dank und schöne Grüße Rotti
EASY Geschrieben 27. August Autor Geschrieben 27. August Hallo, vor 26 Minuten schrieb Rotti: Die beiden beigefügten Dateien habe ich geöffnet, dann zunächst auf Init und auf Start geklickt. Aber nichts hat geblinkt oder ist gelaufen. ... kann ich Dir nichts dazu sagen... bei mir laufen beide Dateien (wenn ich zunächst auf Init und dann auf Start klicke). Welche MBS Version hat Du? vor 30 Minuten schrieb Rotti: Nur ich muss dazu sagen und mir ein eingestehen, dass mir was weiter oben erklärt wird überhaupt nichts sagt. Ich komme mir immer noch wie ein Erstklässler vor, deshalb bin über jede Hilfestellung dankbar. Folge dessen bin ich total unbescholten in Sachen Lua, Scripts und weis überhaupt nichts damit anzufangen. Du braucht Dich nicht fühlen wie ein Erstklässler, auch ich habe einmal ohne Ahnung von lua angefangen. Vielleicht spricht es Dich ja später einmal an Gruß EASY
EASY Geschrieben 27. August Autor Geschrieben 27. August Hallo, vor 3 Stunden schrieb Phrontistes: Bezüglich der TextBox, ist gut, dies zu wissen. Ich schreibe max. 23 Zeilen untereinander und mache dann, wenn nötig, eine zweite Spalte auf. ... wenn Du dies im gleichen Textfeld machst, hast Du (bei langen Namen) das gleiche Problem, die Beschränkung gilt für beide Richtungen (oder arbeitest Du dann schon mit 2 Textfeldern?) Gruß EASY
Phrontistes Geschrieben 27. August Geschrieben 27. August vor einer Stunde schrieb EASY: arbeitest Du dann schon mit 2 Textfeldern?
EASY Geschrieben 27. August Autor Geschrieben 27. August (bearbeitet) Hallo, vor 1 Stunde schrieb Phrontistes: vor 2 Stunden schrieb EASY: arbeitest Du dann schon mit 2 Textfeldern? ... prinzipiell geht es auch mit einem Textfeld, wenn man sehr lange Namen kürzt (meist ist die Bezeichnung trotzdem noch eindeutig)... ... so bleibt noch Platz für Steuerelemente... So sieht das Skript dazu aus... -[[ Hinweis: Es muß eine Monospace-Schrift verwendet werden! im Beispiel: MS-Gothic * max. Anzahl von Zeichen ist abhängig von verwendeter Schrift --]] local d=$("Depot 1a").count-1 -- Anzahl der Einträge im Depot local a="" -- Zeile Teil 1 local b="" -- Zeile Teil 2 local t="" -- Text local max=25 -- max. Anzahl von Zeichen von Name * for i=0,d,2 do -- Alle Depoteinträge a=$("Depot 1a").entries[i].name -- Zeile Teil 1 if string.len(a)>max+2 then -- Name zu lang? a=string.sub(a,1,max)..".." -- auf max Zeichen kürzen + ".." end if $("Depot 1a").entries[i+1]~=nil then -- Eintrag Zeile Teil 2? b=$("Depot 1a").entries[i+1].name -- Zeile Teil 2 if string.len(b)>max+2 then -- Name zu lang? b=string.sub(b,1,max)..".." -- auf max Zeichen kürzen + ".." end else b=" " end t=t..string.format("__>%-27s||__>%-27s",a,b) -- Format 2 Reihen if not ((d-2)<=i) then -- nicht letzte Zeile t=t.."\n" -- Zeilenumbruch end end $("Textfeld").text=t -- Text in Textfeld schreiben Gruß EASY Bearbeitet 27. August von EASY
Phrontistes Geschrieben 27. August Geschrieben 27. August Hallo, vor 31 Minuten schrieb EASY: prinzipiell geht es auch mit einem Textfeld schon, aber vor 3 Stunden schrieb EASY: die Beschränkung gilt für beide Richtungen also lieber mal vorsichtig sein und zwei Textfelder nehmen. vor 30 Minuten schrieb EASY: Monospace-Schrift Mach' ich sowieso damit die Gleisnummern ordentlich untereinander stehen. Ich nehme dafür immer Consolas, das finde ich gefälliger. Und die Breite mache ich mit einer Reihe "#" (großzügig) fix. Das Bedienpanel für einen Spar-SBf (mit Portalen, die Idee ist von Dir; Depots kommen mir nicht mehr ins Haus) mit hier 28 Gleisen sieht dann so aus: Meine Buttons sind rund, dann habe mit denen kein Rotationsproblem . Da man optional mit den Buttons (ansonsten via EV) einen Zug abrufen kann, ist er versteckt, wenn der Zug nicht im SBf ist. Enable/disable gibt es ja (noch?) nicht. Beste Grüße Phrontistes
Rotti Geschrieben 28. August Geschrieben 28. August vor 11 Stunden schrieb EASY: Hallo, ... kann ich Dir nichts dazu sagen... bei mir laufen beide Dateien (wenn ich zunächst auf Init und dann auf Start klicke). Welche MBS Version hat Du? Du braucht Dich nicht fühlen wie ein Erstklässler, auch ich habe einmal ohne Ahnung von lua angefangen. Vielleicht spricht es Dich ja später einmal an Gruß EASY Ich arbeite mit dre Vers. 8.5. Gruß Rotti
Empfohlene Beiträge
Erstelle ein Benutzerkonto oder melde dich an, um zu kommentieren
Du musst ein Benutzerkonto besitzen, um einen Kommentar verfassen zu können
Benutzerkonto erstellen
Neues Benutzerkonto für unsere Community erstellen.
Neues Benutzerkonto erstellenAnmelden
Du hast bereits ein Benutzerkonto? Melde dich hier an.
Jetzt anmelden