Jump to content

Empfohlene Beiträge

  • 3 Monate später...
Geschrieben (bearbeitet)

Interssanter Thread.
Aber wie macht man es nun am Besten, daß die Lok sicher und möglichst realistisch auf den Punkt stehen bleibt?
Leider kenne ich das MBS noch nicht gut genug, und weiß nicht, ob und wie man die benötigten Werte ermitteln kann.
Vielleicht könnt ihr mir helfen?

Annahmen:
Nur ein Gleiskontakt soll nötig sein.
Züge mit unterschiedlichen Geschw. kommen an einem Gleiskontakt an.
Sollen nicht gleich bremsen sondern erst nach einer gewissen Zeit.
Sollen dann linear runterbremsen auf 0.

Was braucht man in LUA?
Geschwindigkeit des Zugs. (Maßstab?)
Eingestellte Beschleunigung (negativ) des Zugs.
Abstand des Kontakts vom Haltepunkt (Irgendein Modell wie Signal oder was Unsichtbares) . (Maßstab?)
Timer starten bei Kontakauslösung (nach der Berechnung)
Einfluß von Steigung und Gefälle? Eventuell mit Faktortabelle?

Was muß man errechnen?
Bremsweg des Zugs bis auf 0, abhängig von der eingestellten negativen Beschleunigung.
Zeit, nach der die Zuggeschw. (tragetSpeed) über einen Timer (geht das, genau genug?) auf 0 gesetzt wird, um den Bremsweg zu erreichen.

Würde das funktionieren?
Kann man die Werte ermitteln?
 

Gruß
Thomas


 


 

 

 

 

Bearbeitet von HaNNoveraNer
Geschrieben
vor 38 Minuten schrieb HaNNoveraNer:

Würde das funktionieren?
Kann man die Werte ermitteln?

Ja und ja.

Beispiel und Erklärung folgen, wenn ich wieder am PC sitze.

vorweg. Die Bremskraft ist in Meter je Sekunde zum Quadrat angegeben. Damit kannst du die richtige Bremskraft für jede gegebene Geschwindigkeit und Entfernung zum Haltepunkt ausrechnen.

Persönlich finde ich es mit zwei Bremspunkten schöner und realistischer. Man bremst ab dem ersten Punkt so, dass man bei jeder Geschwindigkeit ein wenig vor dem zweiten Punkt eine Annäherungsgeschwindigkeit von z.B. 40 km/h erreicht. Und dann peilst du ab dem zweiten Punkt mit fester Bremskraft genau den Haltepunkt an.

Den Maßstab musst du nur berücksichtigen, wenn du eine allgemeine Formel aufstellen willst und die realen Abstände für die Berechnung der Bremskraft heran ziehst. Ansonsten genügt ein empirisch ermittelter Faktor für die Distanz.

Geschrieben

Hello HaNNoveraNer

(Please excuse English - regrettably, I do not speak German)
I use the following method to bring a train to a smooth halt. (The function GetDeceleration is set up for HO gauge.)

Event One:

    --[[
      EVENT NAME: ContactBrakeIn
      A track contact with keyword 'Brake' is triggered upon entering
    --]]
    -- ==================================
    function GetDeceleration(Loco, Distance)
        local k = Loco.currentSpeed
       return 0.443451 * k * k / Distance
    end
    -- ==================================
      if contact.variables['Signal'].state == RED then
        local Distance = contact.variables['Distance']
        vehicle.deceleration = GetDeceleration(vehicle, Distance)
        vehicle.targetSpeed = 5
      end
--

Event Two:

    --[[
      EVENT NAME: ContactExitIn
      A track contact with keyword 'Exit' is triggered upon entering
      This is the complete stop which replaces the need for Lock-Tracks
    --]]
      if contact.variables['Signal'].state == RED then
          vehicle.currentSpeed = 0
      end
  
"Distance" is the distance from the BrakeIn contact to the ContactExitIn contact. The BrakeIn decelerates the vehicle to 5kph. It then moves at 5kph until the ContactExitIn which stops it.

I hope this will help you. I am happy to answer any questions you may have.

Best wishes

Eric
   
 

Geschrieben

Hallo @HaNNoveraNer,

im Prinzip handhabe ich es so wie du es vorhast. Aber:

vor 1 Stunde schrieb HaNNoveraNer:

Nur ein Gleiskontakt soll nötig sein.

Wenn du wirklich punktgenau stehenbleiben willst wie du schreibst, dann brauchst du 2 GK. Einen, der das Bremsen auslöst und auf eine winzige Geschwindigkeit abbremst und dann einen, der dann den Zug tatsächlich stoppt. Mit einem wird's nicht punktgenau. Das gibt dann beim Anhalten einen kleinen Ruck, aber das ist durchaus realitätsbezogen, denn da gibt es auch oftmals einen kleinen Ruck beim Stoppen.

Ich habe im Bremskontakt den Abstand zum Haltepunkt als Variable hinterlegt. So bin ich variabel wenn es mal situationsbedingt kürzer sein muss.

if not deferredCall then

  if contact.variables["Signal"].state == 0 then

    vehicle.targetSpeed = vehicle.currentSpeed 

    local Speed = vehicle.currentSpeed / 3.6
    local Strecke = contact.variables["Strecke"]
    local factor = 5.7471264

    Bremsweg = (( Speed / 2.8 ) ^2 * 2.8 * 0.5 ) / 0.087

    if Bremsweg > Strecke then

      Decel = Speed ^2 * factor / Strecke
      vehicle.deceleration = Decel
      vehicle.targetSpeed = 0
      

    else

      Delay = (Strecke * 0.087 - ( Speed / 2.8 ) ^ 2 * 0.5 *2.8 ) / Speed
      defer(Delay, "Verzögerung")

    end

  end

elseif deferredCall == "Verzögerung" then

  if contact.variables["Signal"].state == 0 then
    vehicle.targetSpeed = 0
    
  end

end

Zu Beginn breche ich eventuelle Beschleunigungen ab (targetSpeed=currentSpeed), da sonst der errechnete Bremsweg nicht mehr stimmt.

Dann wird der Bremsweg mit der aktuellen Geschwindigkeit berechnet. Ist dieser länger als die Strecke, wird mit verstärkter Bremskraft sofort gebremst. Ist sie kürzer, wird die Verzögerung bis zum Einsatz der Bremse errechnet und eingeleitet. Arbeite da nicht mit Timern, sondern besser mit der Verzögerung.

Wenn die Verzögerung auslöst wird vorsichtshalber nochmal der Zustand des Signals abgefragt, da das Signal während der Verzögerung freigegeben worden sein kann und Bremsen dann überflüssig wäre.

Vielleicht kannst du was damit anfangen.

Gruß Timba

Geschrieben

Hi Eric

I am shure that works fine.
But that's not my way, because you are setting the deceleration to a value depending on the train speed and the distance.

The deceleration is a fixed value depending on the mass of the train.
My way is, that the train speed is not changing by passing the contact.

Each train should decelerate at his own position and with its parametered deceleration.

Thomas

Geschrieben (bearbeitet)

Hi Timba

Sieht gut aus.

Falls die Bremskraft geändert wird, würde ich aber den gemerkten Wert wieder zurückschreiben.
Ist ja nur im Notfall nötig.

Und wie positionierst Du den 2. Kontakt, so daß er garantiert immer besetzt wird?
Wenn er nicht ganz erreicht wird, würde er ja sonst beim Anfahren nochmal die Geschw. auf 0 setzen.
Die meisten Konstanten und den Faktor in Deinem Code habe ich auch noch nicht durchschaut :-)

 

Bearbeitet von HaNNoveraNer
Geschrieben (bearbeitet)

Du kannst doch Erics Methode ganz leicht umkehren, Thomas.

Auf der einen Seite hast du die Geschwindigkeit. Also km/h = 3.6 * m / s
Auf der anderen Seite hast du die Verzögerung. Also m / s² 
Damit kannst du bei gegebener Entfernung die Verzögerung ausrechnen. Oder bei gegebener Verzögerung und Entfernung die Dauer.

1 Meter je Sekunde sind 3.6 Kilometer je Stunde (= 60 Minuten mal 60 Sekunden)

Damit ist km/h geteilt durch 3.6 = m/s

g sei die gefahrene Geschwindigkeit umgeformt in m/s, also s = km / h / 3.6

v sei die Verzögerung

d sei die Entfernung bis zum Haltpunkt

mit g² / v bekommst du zur gefahrenen Geschwindigkeit den Bremsweg in Metern. Denn bei den Einheiten kürzen sich zwei s und ein m weg. Bleibt ein m übrig.

Wenn du den Bremsweg für eine gegebene Geschwindigkeit kennst und auch den Abstand zum Haltpunkt, dann ist die Differenz der beiden der Weg, den du noch mit unveränderter Geschwindigkeit zurücklegen musst. Und wie lange du für den Weg benötigst, errechnet sich aus deiner (umgeformten) Geschwindigkeit g

Also:

d - (g²/v) ist die Reststrecke vor dem Bremspunkt. Ich nenne sie r

Dann ist r / g die Zeit (in Sekunden) die du abwarten musst bevor du bremst.

 

Je nachdem, wie du deinen Bremsweg ausmisst, musst du noch den Maßstab der Anlage (z.B. 1:87) in die Berechnung einfließen lassen. Also zuerst aus der gemessenen Länge des Abstands bis zum Haltepunkt die maßstabsgetreuen Meter formen. Oder gleich den passenden Zollstock verwenden und maßstabsgetreue Meter ausmessen.

Bearbeitet von Goetz
Schreibfehler korrigiert
Geschrieben
vor 1 Stunde schrieb HaNNoveraNer:

Falls die Bremskraft geändert wird, würde ich aber den gemerkten Wert wieder zurückschreiben.
Ist ja nur im Notfall nötig. 

Das ist richtig! Beim Überfahren des Signals, das ja unabhängig vom Zustand in jedem Fall geschieht, wird die Bremskraft wieder auf Standard gesetzt.

 

vor 1 Stunde schrieb HaNNoveraNer:

Und wie positionierst Du den 2. Kontakt, so daß er garantiert immer besetzt wird?

Der ist bei mir 55 mm vorm Signal positioniert. Die Variable "Strecke" im Bremskontakt bezieht sich auf den Abstand zwischen den beiden Kontakten. Normalerweise. Bei meinem  Beispiel oben ist es nicht der Fall, zu sehen daran, dass der Zug direkt auf 0 gebremst wird. In dem Fall war es nicht nötig, punktgenau zu halten, sondern es ist egal ob der Zug 55 mm oder 80 mm vorm Signal steht. Der Haltekontakt hat trotzdem einen Not-Stopmechanismus für den Fall, dass der Zug versehentlich zu schwach oder gar nicht bremst. Im Bahnhof bremse ich auf 4 kmh, da ist die Bremsstrecke so berechnet, dass der Zug ein paar mm vor dem Haltepunkt diese 4 kmh erreicht, um dann auf dem Punkt endgültig zu stoppen.

vor 2 Stunden schrieb HaNNoveraNer:

Wenn er nicht ganz erreicht wird, würde er ja sonst beim Anfahren nochmal die Geschw. auf 0 setzen.

Nein, das würde er nicht, weil der Stopkontakt nur greift, wenn das zugehörige Signal auf "Halt" steht. Der Zug fährt erst an, wenn das Signal auf "Frei" gestellt wird und dann wird der Stopkontakt ignoriert. Du musst da eine Bedingung einbauen, die auf das Signal verweist.

 

Gruß Timba

Geschrieben (bearbeitet)

@ Goetz: Ja, so hatte ich mir das gedacht.

Bei der Anlage habe ich 1:1 eingetragen.

Gebaut wurde sie mal in H0.

if not deferredCall then

  if $("Signal2").state == 0 then

    vehicle.targetSpeed = vehicle.currentSpeed

    local Speed = vehicle.currentSpeed / 3.6       -- [m/s aus km/h]
    local Strecke = 60                             -- [m]

    local Decel = vehicle.deceleration

    Bremsweg = ((Speed ^ 2)  / Decel ) * 0.5  -- warum halbieren?

    if Bremsweg > Strecke then
      Decel = ((Speed ^ 2) / Strecke)  * 0.5  -- warum halbieren?
      vehicle.deceleration = Decel
      vehicle.targetSpeed = 0
    else
      Delay = (Strecke - Bremsweg) / Speed
      defer(Delay, "Verzögerung")
    end
  end

elseif deferredCall == "Verzögerung" then

  if $("Signal2").state == 0 then
    vehicle.targetSpeed = 0
  end

end

 

Bearbeitet von HaNNoveraNer
Geschrieben (bearbeitet)

Ich experimentiere auch gerade damit und stelle fest, dass ich das Ergebnis von Speed * Speed / Decel halbieren muss, um den tatsächlichen Bremsweg zu erhalten.
(Maßstab ist auch bei mir 1:1 um die Sache nicht unnötig kompliziert zu machen)

Alle Achtung übrigens, Thomas, wie schnell du die Sache mit dem "deferred call" durchschaut hast. (y)

Bearbeitet von Goetz
Geschrieben (bearbeitet)

Hier ist mein kleines Beispiel:   BremsProbe 02.mbp

  • Der angepeilte Haltepunkt ist durch eine Rufsäule (gegenüber vom Stellwerk) markiert.
  • Das Vorsignal dient als Auslöser. Hier wird anhand der Geschwindigkeit und Bremskraft ermittelt, wann der Zug gestoppt werden muss.
  • Das Hauptsignal schickt den Zug wieder auf die Reise.
  • Dabei bekommt er eine zufällige Geschwindigkeit zwischen 80 und 300 km/h
  • und eine zufällige Bremskraft zwischen 2 und 45 m/s²

Der Abstand zwischen Vor- und Hauptsignal beträgt 2 Kilometer! (Das reicht knapp bei 300 km/h und 2 m/s² Verzögerung)
Ich habe ein paar Kameras aufgestellt, mit denen sich das Geschehen beobachten lässt.

Kamera 4 zeigt die Telemetriedaten jeder Runde

1600715134_BremsProbe02.thumb.jpg.1743d7da369262a0a7f18ac172de085e.jpg

 

Die Genauigkeit, mit der ein Zug in diesem Szenario den Haltepunkt trifft, finde ich bemerkenswert.

Bearbeitet von Goetz
Anlage gegen schönere getauscht
Geschrieben (bearbeitet)
vor 9 Stunden schrieb Goetz:

Ich experimentiere auch gerade damit und stelle fest, dass ich das Ergebnis von Speed * Speed / Decel halbieren muss, um den tatsächlichen Bremsweg zu erhalten.
(Maßstab ist auch bei mir 1:1 um die Sache nicht unnötig kompliziert zu machen)

Alle Achtung übrigens, Thomas, wie schnell du die Sache mit dem "deferred call" durchschaut hast. (y)

Hallo Götz

Ich habe meinen Code oben angepaßt.
Funktioniert jetzt einwandfrei mit nur EINEM Kontakt.
Es lag nur an dem Faktor 0,5 für den Bremsweg. Das kann ich mir nicht erklären. Woher kommt der?

Jetzt müßte man nur noch automatisch den Abstand zwischen dem Kontakt und dem Signal berechnen können.
Also mit LUA die Gleislänge dazwischen auslesen können.

Nochmal was anderes:
WIe kann ich ein bißchen debuggen?
Also print(irgendwas) oder Variablen anzeigern. Geht das?

Gruß
Thomas

Bearbeitet von HaNNoveraNer
Geschrieben (bearbeitet)
vor 57 Minuten schrieb HaNNoveraNer:

mit Lua die Koordinaten auslesen ...

kannst du auch. Nämlich so, wie ich in meinem Beispiel die Position auslese, an welcher der Zug zum Stehen kam.
Mit $(Object).transformation.position.x etc.

Für deine print() Ausgaben hast du das "Ereignisprotokoll". Dafür ist das Icon rechts neben dem für die EV.

Ereignisprotokoll.jpg.4c0a8f643e2b53171a7605bb96e89c9f.jpg

Das Protokoll kann auch Objekt- und Modul-Variablen, Timer etc. anzeigen. 

Für den Faktor 2 beim Bremsweg habe ich auch (noch) keine geometrische Erklärung.
Vielleicht steckt irgendwo in den Zusammenhängen ein a² + 2ab + b²?
Aber das ist einfach nur ins Blaue hinein geraten und ohne irgendwelche Erkenntnisse dahinter..

Bearbeitet von Goetz
Ergänzungen
Geschrieben (bearbeitet)

Durch den Bremsvorgang legt er  0.5 * a * t^2 weniger Strecke zurück, als ohne den Bremsvorgang.
Das muß man berücksichtigen, daher der Faktor 0.5

Hier die Anlage dazu.
Ich habe dafür eine Tutorial Anlage umgebaut, um zu zeigen wie kompliziert es früher war und wie einfach es mit dem Kontakt und LUA geht. :)

P.S. Signal auf HALT lassen, Zug manuell Geschwindigkeit geben. Nur das automatische Bremsen ist realisiert.

Bremsen.mbp

Bearbeitet von HaNNoveraNer
Geschrieben
vor 37 Minuten schrieb HaNNoveraNer:

Hier die Anlage dazu.

Funktioniert prima. Und Relikte vom Original zeigen wirklich plakativ, wie viel eleganter man solche Aufgaben jetzt angehen kann.

Geschrieben (bearbeitet)

Das kommt von Timba.
Ich habe versucht aus seinen, Deinen und meinen Ideen das Beste zusammenzufügen.
Ich baue aber noch ein paar Variablen ein für Signalname, Zugname, Beschleunigungsreset, ABstand u.s.w.
Dann braucht man das nur an einer Stelle zu editieren.
Außerdem vielleicht ein Flag, das bewirkt, daß der Abstand auf gerader Strecke automatisch berechnet wird.

Und irgendwie sollte noch eine Belegtmeldung realisiert werden, so daß vorhergehende Blöcke erkennen können, ob das Zielgleis frei ist.

Bearbeitet von HaNNoveraNer
Geschrieben
vor 1 Stunde schrieb HaNNoveraNer:

irgendwie sollte noch eine Belegtmeldung realisiert werden

Dazu sind vielleicht folgende Hinweise nützlich:

  1. Du kannst in Objekten auch Listen und Tabellen speichern, nicht nur Variablen.
  2. Wenn du mehrere Modelle markiert hast, dann kannst du diese Auswahl klassisch mit Strg-C kopieren und beim Erstellen einer Liste unter "bearbeiten" mit einem Klick auf das Insert Icon oder mit Strg-V einfügen.
  3. Mit einem Doppelklick auf ein Gleis bekommst du automatisch alle angeschlossenen Gleise bis zu den nächsten Knotenpunkten (Weichen, Endgleise) als eine Gruppenauswahl.

In Summe heißt das:
Doppelklick aufs Gleis, Strg-C und dann als Liste an relevanter Stelle einfügen, damit du im Bedarfsfall flott in einer Wiederholung alle Gleise auf "besetzt" prüfen kannst.

Geschrieben (bearbeitet)

Vorher habe ich das Modul weiter optimiert, so daß es jetzt für beliebige Kontakte und Signale nur EIN Modul gibt.
Das MBS scheint ja dann verschiedene Instanzen für die Variablen und Verzögerungen anzulegen. Sehr schön.

Gesteuert wird es über Schlagwörter "Brems, Stop, Bremssignal".
Die Variablen am Bremskontakt, Stopkontakt und am Signal parametrieren das Ganze. (Zielgeschwindigkeit, Abstand, Signalname des zugehörenden Bremssignals)
Die original Deceleration wird auch wieder hergestellt.
Daher ist keine Codeänderung in LUA mehr nötig.
Bremsen.mbp

Bearbeitet von HaNNoveraNer
Geschrieben (bearbeitet)

Ich habe jetzt dazu passend ein Fahrstraßenmodul gebaut.

Neue Fahrstraßen erzeugt man durch kopieren der betroffenen Gleise in globale Listen: FS1, FS2, FS3 u.s.w. für alle Fahrstraßen.
Wichtig ist, die Startsignale alle korrekt zu benennen: FSSig0001 bis FSSig9999. Das steuert den ganzen Ablauf!
Nur ein Anforderungskontakt und ein Aufhebungskontakt werden benötigt. Die möglichen Fahrstraßen stehen im Signal.
Aktivierte Fahrstraßen verriegeln sich gegenseitig.

Ich werde das noch um unterschiedliche Routen für unterschiedliche Züge und um eine autom. Weichenschaltung erweitern.

Hier die Testanlage: (Wenn Du den Wagen wegnimmst, fährt der Zug weiter. Natürlich vorher die Anlage starten!)
(Bitte ein Gleis besetzen BEVOR der Zug den Anforderungskontakt überfahren hat, dann hält er wieder an)

Bremsen.mbp

Bearbeitet von HaNNoveraNer
Geschrieben

@HaNNoveraNer

Hallo Thomas,

ich habe dein Bremsen angeschaut.

Läuft leider auf einen Fehler bei Zug stoppen.

Du hast ein Schlagwort in den GK.

zweimal STOP und einmal Stop -> das gibt den Fehler: Skriptfehler (1): attempt to index a nil value (fiel 'signal') 

Du hast ja das Ereignis: Ein Gleiskontakt mit Schlagwort STOP wird beim Betreten ausgelöst.

Lua ist leider sehr heikel bei Groß- und Kleinschreibung.

Gruß Martin

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...