Jump to content

Straßenbahn Steuerung mittels Lua - als Video auf YouTube


Empfohlene Beiträge

Am 15.10.2019 um 00:34 schrieb h.w.stein-info:

Versuche die Animationen der einzelnen Trams mit Verzögerung zu Steuern .

Das wäre Blinker , Bremslicht und Türen über einen Gleiskontakt als Auslöser zu Starten . 

Alleine mit der grafischen EV wäre das zwar theoretisch möglich. Aber in der Praxis scheitert man - wie Metallix schon in deinem Thread erklärt hat - daran, dass man die Achsen nicht zu fassen bekommt, wenn man über den generischen "Auslöser" jede Straßenbahn ansprechen möchte, welche die Haltestelle anfährt.

Diese Hürde kann man mit Lua sehr leicht nehmen. Und es ist äußerst praktisch, dass man zuerst das Gerüst mit der grafischen EV bauen und anschließend in ein Skript umwandeln kann. So hat man im Skript schon alle Schreibweisen für die benötigten Befehle und muss nur noch Anpassungen vornehmen.

In einer Twitch Sendung habe ich heute gezeigt, wie man solch eine Sequenz Stück für Stück aufbauen kann.

 

Hier ist die bereinigte Aufnahme auf YouTube

 
 

Das Skript, welches in der Sendung entstanden ist (für diejenigen, die nur was nachlesen möchten):

local Blinker = {
  vehicle.animations["Blinker rechts"],
  vehicle.variables["Hinterteil"].animations["Blinker rechts"],
}

local Tueren = {
  vehicle.animations["Tür rechts vorne"],
  vehicle.variables["Mittelteil"].animations["Tür rechts vorne"],
  vehicle.variables["Hinterteil"].animations["Tür rechts hinten"]
}

if not deferredCall then

  vehicle.deceleration = 2
  vehicle.acceleration = 3
  vehicle.targetSpeed = 0

  defer(3, "Blinker an")

elseif deferredCall == "Blinker an" then

  Blinker[1]:play(0, 1)
  Blinker[2]:play(0, 1)

  defer(4, "Tür auf")

elseif deferredCall == "Tür auf" then

  for Index , Tuer in ipairs(Tueren) do
    Tuer:play(0, 1)
  end

  defer(7, "Tür zu")

elseif deferredCall == "Tür zu" then

  for Index , Tuer in ipairs(Tueren) do
    Tuer:play(1, -1)
  end

  defer(2, "Abfahrt")

elseif deferredCall == "Abfahrt" then

  vehicle.targetSpeed = 50

  defer(1.5, "Blinker aus")

elseif deferredCall == "Blinker aus" then

  Blinker[1]:stop(0)
  Blinker[2]:stop(0)

end

 

Und das hier sind drei Versionen der Anlage

Ohne Steuerung:  StraBa Sequenz 00.mbp

mit grafischer EV: StraBa Sequenz 01.mbp

und die finale Version mit Lua Skript: StraBa Sequenz 02.mbp

 

Ich hoffe, dass ich dem einen oder anderen damit ein bisschen Inspiration bieten kann. :)

Bearbeitet von Goetz
Skript und Anlagen hinzugefügt
Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo Modellbahnfreunde

Ohne Hilfe hatte ich einiges doch gerade hinbekommen , doch sind da auch noch bei mir einige stolper Fallen . Also noch nicht reibungslos !

Hallo Götz

Jetzt werde ich die Tipps und auch die Mühe von Götz ( Video und Testanlage ) vornehmen .

Wenn es schon für die Tram geht , müsste es auch genau so für Busse gelten ( Bezeichnungen können ähnlich sein ) .

Bei Shuttle der DB wär es nur die Türen !

 

Ich war schon froh das ich die Ampelsteuerung hinbekommen habe und die sind nicht alle miteinander verbunden .

Nur mal eine kleine Nebenfrage - geht auch mit Verzögerungen eine Ampelsteuerung ?

Oder ! 

Wäre es besser eine Ampelsteuerung mit Verzögerung auf zubauen .

Meine Ampelanlage sind ( doch dem realen ) immer unterschiedlich . 

Ich könnte hier mal ein Beispiel später zeigen - müsste es noch vorbereiten .

 

Aber ich hab noch eine Idee gehabt  !

Steht die Tram an der Haltestelle und war abfahrbereit , fuhr sie einen kleinen Stück vor zur nächsten Gleiskontakt ( Auslöser ) für die Ampelsteuerung .

Das heisst , wenn die Ampel auf Freie Fahrt umgeschaltet hat , dann konnte die Tram über die Kreuzung ( Ampel ) abfahren . 

An den Haltestellen muss ich noch Besetzeinrichtung vornehmen , das die nächste Tram die kommt nicht auffährt .

Oder , es ist schon bedacht worden von Götz - was ich noch nicht weis - ich hab seine Arbeit noch nicht angeschaut .

Dies werde ich jetzt machen und in wie weit ich weiter kommen kann .

Erstmal vielen Dank für die Tipps und Hilfsstellungen .

 

Viele Grüße

H:xnS

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo Götz

Ich hab mir dein Video angesehen - super gemacht ( sehr Verständlich ! ) . 

Vom Grundprinzip lag ich noch nicht mal falsch , bin auch Schrittweise vorgegangen , aber mit Lua nicht ausprobiert .

Bei mir ist es noch die grafische EV - Aufbau  !

 

Werde deine Beispielanlage noch einzeln studieren - da habe ich für mich noch was entdeckt .

 

Vielen Dank und viele Grüße (y)

H:xnS

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 15 Minuten schrieb h.w.stein-info:

da habe ich für mich noch was entdeckt

Das freut mich, Hans

Genau so war das gedacht. Es ist gar nicht wichtig, welche Dinge du dir rauspickst, solange du nur Kleinigkeiten entdeckst, die nützlich für dich sind.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo Goetz,

 

nochmals vielen Dank für diese Demonstration und Anleitung.

 

Das ist jetzt ein Joke:

Aber, und das ist ein großes ABER... die Linie heißt U79 und die Stationen

St. Anna Krankenhaus (nicht Huckingen)

(Kesselsberg)

Froschenteich

Wittlaer          

(Kalkumer Schloßallee)

Klemensplatz (nicht Kaiserswerth)

:):):):):):):):):):):):)

 

Wir kennen ja beide diese Straßenbahn aus eigener Erfahrung...

 

Gruß,

Michael

 

P.S. Ich hoffe, es gelingt mir jetzt, mittels Lua alle meine Laternen auf einen Schlag ein zu schalten. Ich versuche es jedenfalls.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor einer Stunde schrieb Tesla (former m.weber):

Wir kennen ja beide diese Straßenbahn aus eigener Erfahrung...

Ich kenne sie als D-Bahn und bin damit täglich zur Schule gefahren.

Damals hatte die noch ein Speiseabteil in der Mitte.
Und damals hieß die Station in Huckingen noch Huckingen und war ebenerdig. 

Bearbeitet von Goetz
Link hinzugefügt
Link zu diesem Kommentar
Auf anderen Seiten teilen

Mir fehlte der richtige Funktionsaufruf um zu einem auslösenden Fahrzeug in Lua den kompletten Zugverband zu erhalten.

Deshalb hatte ich den Umweg in Kauf genommen, Mittel- und Hinterteil in Objekt-Variablen im Vorderteil zu speichern. Vielleicht war das auch für den Anfang ganz gut so, weil nachvollziehbar.

Aber inzwischen habe ich Neo um den nötigen Tipp gebeten. Die Funktion heißt layout:getVehiclesGroup(Fahrzeug_im_Zugverband)
Richtiger: In der Tabelle layout steht eine Funktion getVehiclesGroup(), der man beim Aufruf ein Element aus dem Zugverband übergeben muss. Man bekommt eine Liste aller Objekte zurück, die den Zugverband ergeben. Bitte achtet auf den Doppelpunkt zwischen layout und getVehiclesGroup() damit die Funktion Zugriff auf die Tabelle aller Elemente der Anlage hat.

Damit kann man auf die Variablen im Vorderteil verzichten. Vorteil: Es besteht kein Unterschied mehr zwischen Einzel- und Doppeltraktionen.

StrabaTabellen.jpg.b1005c4df7eef318af4853747c72ef2a.jpg

Hier ist eine neue Beispielanlage, in der ich diese Liste nutze. Das enthaltene Skript sieht so aus:

local Blinker = {}
local Tueren = {}
local Zug = layout:getVehicleGroup(vehicle)

for k, Waggon in ipairs(Zug) do
  if Waggon.animations["Blinker rechts"] then
    table.insert(Blinker, Waggon.animations["Blinker rechts"])
  end
  if Waggon.animations["Tür rechts vorne"] then
    table.insert(Tueren, Waggon.animations["Tür rechts vorne"])
  end
  if Waggon.animations["Tür rechts hinten"] then
    table.insert(Tueren, Waggon.animations["Tür rechts hinten"])
  end
end

local Bremslicht = Zug[#Zug].animations["Bremslicht hinten"]
                                                         
if not deferredCall then

  vehicle.deceleration = 2
  vehicle.acceleration = 3
  vehicle.targetSpeed = 0
  Bremslicht:stop(1)

  defer(3, "Blinker an")

elseif deferredCall == "Blinker an" then

  for k, Blink in ipairs(Blinker) do
    Blink:play(0, 1)
  end

  defer(4, "Tür auf")

elseif deferredCall == "Tür auf" then

  for k, Tuer in ipairs(Tueren) do
    Tuer:play(0, 1)
  end

  defer(7, "Tür zu")

elseif deferredCall == "Tür zu" then

  for k, Tuer in ipairs(Tueren) do
    Tuer:play(1, -1)
  end

  defer(2, "Abfahrt")

elseif deferredCall == "Abfahrt" then

  vehicle.targetSpeed = 50
  Bremslicht:stop(0)

  defer(1.5, "Blinker aus")

elseif deferredCall == "Blinker aus" then

  for k, Blink in ipairs(Blinker) do
    Blink:stop(0)
  end

end

Ich habe mich entschlossen, zunächst die Adressen der Blinker und Türen des auslösenden Zuges in lokalen Tabellen zu sammeln. Das hat meines Erachtens den Vorteil, dass ich anschließend diese Tabelle in einem Rutsch ansprechen kann. 

In Zeile 3 fordere ich die Fahrzeugliste zum auslösenden vehicle an.

In den Zeilen 5 bis 15 prüfe ich, welches der Fahrzeuge überhaupt einen "Blinker rechts", eine "Tür rechts vorne" oder eine "Tür rechts hinten" hat. Alle Blinker und Türen, die ich dabei finde, übertrage ich in zwei lokale Tabellen "Blinker" und "Tueren"

Ab Zeile 19 passiert dann weiter nichts neues im Vergleich zur ersten Version. Ich bediene mich jetzt nur aus den oben angelegten Tabellen und nicht mehr aus Variablen im Vorderteil.

Zeile 17 ist noch eine kleine Besonderheit. Mit Zug[#Zug] bekomme ich das letzte Element der Tabelle. Denn #Zug ist die Anzahl der Elemente in der Tabelle Zug. Und weil Lua Tabellen mit 1 beginnen, ist die Anzahl zugleich auch der Index des letzten Elements. Das bedeutet: Mit dem Konstrukt in der Zeile 17 merke ich mir die Adresse des Bremslichts im letzten Waggon.

Beispielanlage mit obigem Skript: StraBa Tabellen 01.mbp

Bearbeitet von Goetz
Schreibfehler korrigiert
Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo @Goetz,

vor 4 Stunden schrieb Goetz:

Zeile 17 ist noch eine kleine Besonderheit. Mit Zug[#Zug] bekomme ich das letzte Element der Tabelle. Denn #Zug ist die Anzahl der Elemente in der Tabelle Zug. Und weil Lua Tabellen mit 1 beginnen, ist die Anzahl zugleich auch der Index des letzten Elements. Das bedeutet: Mit dem Konstrukt in der Zeile 17 merke ich mir die Adresse des Bremslichts im letzten Waggon.

super klasse gemacht! (y)

Aber woher weißt Du, dass das Fahrzeug mit der höchsten Nummer in der Tabelle auch wirklich das hinterste Fahrzeug des Zugverbands ist?
Bei umgekehrter Fahrtrichtung würde dies sicher nicht mehr stimmen. Und wie sieht es mit der Fahrzeugzählung ais, wenn sich das angetriebene Fahrzeug in der Zugmitte befindet?

Viele Grüße
BahnLand

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor einer Stunde schrieb BahnLand:

woher weißt Du, dass das Fahrzeug mit der höchsten Nummer in der Tabelle auch wirklich das hinterste Fahrzeug des Zugverbands ist?

Das weiß ich nicht.

Und es ist nicht der einzige Fehler in diesem Zusammenhang. Wenn es nämlich kein Bremslicht gibt (weil man ein anderes Straßenbahn-Modell benutzt), steigt die EV bei der ersten Anwendung des Bremslichts aus der Routine aus, weil unter der angegebenen Adresse kein stop() Befehl gefunden wird.

 

Ich denke nur, dass es so schon genügend Stoff für eine Lektion ist. Mir ist nicht daran gelegen das perfekte Skript für alle Fälle vorzustellen. Ich suche vielmehr nach überschaubaren Beispielen, anhand derer man die einzelnen Bausteine der EV besser begreifen kann. Man muss die Werkzeuge kennenlernen, bevor man damit etwas richtiges baut. Und zum Kennenlernen eigenen sich "Gesellenstücke" mit geringem Nutzen besser, weil man sich auf die Anwendung der Werkzeuge konzentrieren kann.

vor einer Stunde schrieb BahnLand:

wie sieht es mit der Fahrzeugzählung ais, wenn sich das angetriebene Fahrzeug in der Zugmitte befindet?

Um genau solche Fragen geht es.

Das Beispiel ist so klein und überschaubar gehalten, dass man es mit Leichtigkeit selbst ausprobieren kann.

Nimm ein leeres Oval, setzt einen Kontakt darauf und bastle dir mit den Erkenntnissen aus meinem Beispiel deine eigene EV, die einfach nur die Namen der Fahrzeuge im Zugverband auflistet. Dann ändere deinen Zug immer wieder kunterbunt, fahre über den Kontakt und schau, was passiert.

Wagenreihung.thumb.JPG.62c96889bc61df08d5bb84065bbad9bc.JPG

Bearbeitet von Goetz
Bild hinzugefügt
Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo,

die Logik bei "layout:getVehicleGroup" ist ganz einfach... die Auflistung erfolgt in Richtung eines gedachten Pfeils von der vorderen zur hinteren Kupplung der Bezugslok...

L1,W1,W2,W3,W4...
197295658_Bild001.thumb.jpg.c582a0034a00d0586ce62e8b7dcb88c0.jpg

W1,W2,W3,W4,L1...
33251976_Bild002.thumb.jpg.dbfa73f99bc91e17280afce9305c0795.jpg

W1,W2,L1,W3,W4...
1563699142_Bild003.thumb.jpg.cc73ade4bfd094807ec768e6a5d660af.jpg

W4,W3,W2,W1,L1...
1267685146_Bild004.thumb.jpg.b427a517ddf3c9a0554a9efd7c489c52.jpg

L1,W4,W3,W2,W1...
766397508_Bild005.thumb.jpg.87128958c01d941990f4b9792e7ed231.jpg

W4,W3,L1,W2,W1...
963950469_Bild006.thumb.jpg.5971beb4af85f89e0b7dd51ba38f75cb.jpg

Gruß
EASY

 

 

Bearbeitet von EASY
Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 7 Minuten schrieb EASY:

die Logik bei "layout:getVehicleGroup" ist ganz einfach...

Aber das bleibt nicht hängen, wenn man es gesagt bekommt. Weil die Information damit beliebig ist und mit nichts verknüpft wird.


Probiert man es hingegen selber aus, dann sammelt man erstens Erfahrung mit Lua im Allgemeinen und getVehicleGroup() im Speziellen. Und freut sich zweitens über das, was man herausfindet. Mit der Freude bekommt es Gewicht und mit dem Gewicht (und der aktiven Beschäftigung) findet es im Hirn Stellen, an denen es andocken kann. Assoziationen sind ein wichtiger Klebstoff für Erinnerungen. 

vor 7 Minuten schrieb EASY:

von der vorderen zur hinteren Kupplung

3275230_vordereKupplung.thumb.JPG.79443f441d8241ba28540c75000c9e48.JPG

Welche Kupplung ist die vordere und welche die hintere?

Bearbeitet von Goetz
Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo zusammen,

interessante Schlussfolgerungen - und hieraus schlussgefolgert auch gleich die Antwort auf die letzte Frage:

vor 2 Stunden schrieb Goetz:

Welche Kupplung ist die vordere und welche die hintere?

Es kommt darauf an, welche Lok die "aktive" ist. Also Reihenfolge von rechts nach links, wenn die rechte Lok "fährt", und umgekehrt bei der linken Lok. Es versteht sich hierbei von selbst, dass nur einer Lok zu einem Zeitpunkt eine Geschwindigkeit <> 0 zugewiesen sein darf. Denn auch bei der grafischen Schnittstelle (EV) kann das Modellbahn-Studio den "Auslöser" nicht eindeutig bestimmen, wenn es mehrere "angetriebene" Fahrzeuge im Zugverband gibt.

Viele Grüße
BahnLand

Bearbeitet von BahnLand
Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo Bahnland,

wenn Dampfloks im Spiel sind, haben alle Loks im Zug eine Geschwindigkeit, damit auch der Schornstein raucht. (Vielleicht gibt es da ja ne Möglichkeit in der Zukunft, dies über Animation zu steuern.) Man müsste also jeder fahrenden Lok im Zug eine Variable einpflanzen, welche die "zugführende" Lok ist. Diese ist aber natürlich nicht unbedingt die Lok "Auslöser". Wenn alle fahrenden Loks im Zug die Variable "1. Lok" (wie auch immer genannt) besitzen, kann die EV auch auf alle Variablen in dieser "1. Lok" hinterlegten Variablen zurückgreifen. Dann also: Auslöser löst aus...Variable "Lok 1" ... hinterlegte Waggonfolge... In Lua müsste man wohl dann die Liste oder Tabelle der Reihenfolge der Waggons - die natürlich auch die anderen Loks enthält - über eine Variable in der "1. Lok" hinterlegen. Müssen dann die anderen Loks herausdefiniert werden? Na klar, kommt drauf an, was man erreichen möchte. Vielleicht kann man auch schon zu Beginn der Waggonreihenfolge sagen, dass nur Wagen aufgenommenh werden, die keine definierte Geschwindigkeit besitzen.

Gruß, Berlioz

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo,

Am 17.10.2019 um 20:49 schrieb Goetz:

Aber das bleibt nicht hängen, wenn man es gesagt bekommt. Weil die Information damit beliebig ist und mit nichts verknüpft wird.

... finde ich etwas derbe in der Antwort so abgewürgt zu werden. Würde ich mir das (wörtlich) verinnerlichen, dann müßte ich mir bei manchen Antworten überlegen, ob ich sie überhaupt geben soll. Alles was ich über das MBS weiß, habe ich auch nur als Erfahrungswerte zum Teil mühsam zusammengetragen... soll doch jeder seine Erfahungen machen!... dies entspricht allerdings nicht meiner Einstellung Wissen zu teilen...

Gruß
EASY

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo Goetz,

vor einer Stunde schrieb Goetz:

Oh, Easy - das hast du in den falschen Hals gekriegt

... dann hab ich mal kräftig gehustet...

vor einer Stunde schrieb Goetz:

Tut mir leid.

... und Du hast von hinten etwas geklopft...

... alles gut.

Gruß
EASY

Link zu diesem Kommentar
Auf anderen Seiten teilen

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 erstellen

Anmelden

Du hast bereits ein Benutzerkonto? Melde dich hier an.

Jetzt anmelden
×
×
  • Neu erstellen...