Jump to content

Befehlspriorität


Timba

Empfohlene Beiträge

Hallo,

vielleicht weiß jemand die Antwort auf meine Frage und erspart mir den Aufwand für eine Versuchsanordnung.

Ausgangslage: Der Bremskontakt vor einem Signal ist so justiert, dass ein Zug bei 150 kmh exakt davor zum Stehen kommt. Bei höheren Geschwindigekeiten wird der Verzögerungswert erhöht und bei niedrigeren Geschwindigkeiten wird der Zeitpunkt des Bremsbeginns verzögert, sodass in beiden Fällen ebenfalls der Zug exakt vorm Signal steht.

Wenn nach dem Auslösen des Bremskontakts das Signal öffnet, wird der Zug auf die gewünschte Geschwindigkeit beschleunigt.

Bei Geschwindigkeiten >=150 sehe ich kein Problem, Bremsen wurde eingeleitet und durch den neuen Befehl revidiert. Was passiert aber, wenn der Zug langsamer ankommt? Der Befehl, Aufschub errechnen ist ausgeführt und der Wert übernommen worden, der Bremsvorgang befindet sich quasi in der Warteschleife, wurde also noch nicht begonnen, in dem Moment kommt der Befehl "beschleunigen". Wird dann der Bremsbefehl ignoriert/überschrieben, oder wird der Zug gleich nachdem er versuchte, zu beschleunigen, direkt wieder abgebremst? Und wenn zweiteres der Fall sein sollte (was ich befürchte), kann man den Bremsbefehl programmtechnisch canceln?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Es ist jedenfalls so, dass ich noch keine Möglichkeit gesehen habe, einen einmal gestarteten deferredCall abzubrechen. Wenn der mal gestartet ist, läuft er und löst damit das aus, was dahinter steht. Ein Versuch die Verzögerung zu überschreiben, indem man (in Lua) das Kommando defer(0, "Verzögerung") eingibt, wird mit einem 'hängenden' Ereignis bestraft. Auch deferredCall = nil oder deferredCall = false bringt nichts.
Versuch's vorher abzufangen, wie BahnLand es beschrieben hat.

Bearbeitet von Andy
Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 16 Minuten schrieb BahnLand:

Dann bist Du auf der sicheren Seite.

Bin ich doch nie! :D;)

Aber im Ernst:

vor 16 Minuten schrieb BahnLand:

führe den Bremsbefehl nur unter der Bedingung aus, dass das Signal geschlossen ist.

Geht nicht so einfach, weil dann mein schönes ausgeklügeltes Konzept im Eimer ist. Es sieht jedenfalls bis jetzt cool aus, solange das Signal nicht zwischendurch öffnet. Die Möglichkeit habe ich zu spät bedacht, was mir aber auch nichts geholfen hätte.

Als Kompromiss sehe ich jetzt nur die Möglichkeit, statt einem deferredCall die Verzögerung durch einen Timer hervorzurufen, weil den kann man ja abbrechen. Oder?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo Timba,

in der Realität wird meines Erachtens kein Signal plötzlich geöffnet, wenn vorher an einem Vorsignal ein Halt angezeigt wird. Daher solltest du die Steuerung versuchen so umzustellen, dass das Öffnen des Signals „unterdrückt“ wird wenn ein Zug bereits ein Vorsignal passiert hat. Dies kannst du vielleicht ganz einfach einbauen indem du das Öffnen des Signals ebenfalls verzögerst, wenn sich ein Zug in einer gewissen Zone befindet und das Vorsignal bereits einen Halt angezeigt hat. Ich schreibe absichtlich Zone, denn diese sollte schon einiges vor dem Vorsignal anfangen.

Gruß Frank

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo @Timba,

vor 25 Minuten schrieb Timba:

Geht nicht so einfach, weil dann mein schönes ausgeklügeltes Konzept im Eimer ist. Es sieht jedenfalls bis jetzt cool aus, solange das Signal nicht zwischendurch öffnet. Die Möglichkeit habe ich zu spät bedacht, was mir aber auch nichts geholfen hätte.

das verstehe ich jetzt nicht.
Die Beschleunigung kann doch nur wirksam werden, wenn das Signal geöffnet ist - oder beschleunigst Du bei geschlossenem Signal ???

Wenn Du nun in der Ereignisdefinition einfach den Befehl "Zug abbremsen" (Geschwindigkeitszuweisung) in eine Bedingung "Signal geschlossen" einbettest,  wird die Abbremsung einfach nicht ausgeführt, wenn das Signal geöffnet ist. Außer der zusätzlich eingefügten Bedingung, welche nun die Aktion "Abbremsen" umschließt, ändert sich ja an der Ereignisdefinition nichts, womit die Semantik ja insgesamt erhalten bleibt.

Denn mit der zusätzlich eingfügten Bedingung wird erreicht, dass einerseits das Signal nicht geöffnet sein kann,wenn die Abbremsung wirksam wird, also auch keine Beschleunigung stattgefunden hat, und umgekehrt, dass dann, wenn die Beschleunigung eingeleitet wurde und deshalb das Signal geöffnet ist, das Abbremsen nicht ausgeführt wird.

Viele Grüße
BahnLand

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo @fzonk und @BahnLand,

es handelt sich in diesem Fall um das Einfahrsignal zum Bahnhof, das standardmäßig geschlossen ist. Ab Anforderung des Bahnhofslocks hat der Zug mindestens 7,45 s Zeit, das Lock zu erhalten. Geschieht das in der Zeit, würde das Signal öffnen und der Bremskontakt wäre wirkungslos. Bekommt er das Lock erst nachdem er schon steht, wäre es auch kein Problem, dann fährt er halt wieder an. Das Problem ergibt sich nur, wenn der Zug in der relativ kurzen Zeitspanne von Bremskontakt bis Bremsbeginn das Lock erhält und dadurch das Einfahrsignal geöffnet würde.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo @Timba

Als kleine Anregung, auf meiner Anlage wo Züge mit bis zu 240 km/h unterwegs sind habe ich auch zwangsläufig mir was einfallen lassen müssen dass dies mit dem Bremsen bei unterschiedlichen Geschwindigkeiten gut aussieht. Dazu bremse ich die Züge aber nicht auf null sondern auf 40km/h ab. So habe alle Züge an einen gewissen Punkt alle dieselbe Geschwindigkeit, dieser Punkt ist kurz vor dem Signal und erst da wird geprüft ob das Signal offen oder geschlossen ist und der Zug wird dementsprechend gestoppt oder fährt weiter. Da du ja auch von einem Einfahrtsignal zu einem Bahnhof schreibst wirst du ja bestimmt auch alle Züge vor dem Signal abbremsen wollen und nicht mit voller Geschwindigkeit in den Bahnhof einfahren lassen. Vielleicht ist dies ja eine Anregung für dich, dass du den Kontakt eventuell auch näher an das Signal verlegst, an einem Punkt wo ausgeschlossen ist das ein Zug noch in einer Verzögerungsschleife ist.

Gruß Frank

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich mache es noch anders. Wenn bei mir ein Zug lösfährt, werden alle Weichen und Signale geschaltet, bis zu einem Haltsignal. Daran kann dann auch nichts mehr geändert werden, muß auch nicht, weil die Strecke reserviert ist. Und bremsen tue ich wie Frank.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 1 Minute schrieb Andy:

Ich mache es noch anders. Wenn bei mir ein Zug lösfährt, werden alle Weichen und Signale geschaltet, bis zu einem Haltsignal.

Dies wende ich auch so an :P so kann nichts schief gehen :D, denn alle Blöcke die sich dazwischen befinden (bei mir ist ein Block auch mal „nur“ eine Kreuzungsweich) werden als belegt gemeldet und erst nach Verlassen des Bocks wird dieser wieder freigegeben.

Link zu diesem Kommentar
Auf anderen Seiten teilen

 

vor 1 Stunde schrieb fzonk:

Als kleine Anregung, auf meiner Anlage wo Züge mit bis zu 240 km/h unterwegs sind habe ich auch zwangsläufig mir was einfallen lassen müssen dass dies mit dem Bremsen bei unterschiedlichen Geschwindigkeiten gut aussieht. Dazu bremse ich die Züge aber nicht auf null sondern auf 40km/h ab. So habe alle Züge an einen gewissen Punkt alle dieselbe Geschwindigkeit, dieser Punkt ist kurz vor dem Signal und erst da wird geprüft ob das Signal offen oder geschlossen ist und der Zug wird dementsprechend gestoppt oder fährt weiter.

Ja, diese Variante habe ich in V4 mangels anderer Möglichkeiten ebenfalls genutzt. Allerdings, wenn dann ein Zug mit sagen wir mal nur 90 ankommt, fährt der dann eine ziemliche Strecke gleichförmig mit 40, bevor er dann endgültig hält. Meinem Empfinden nach sieht das auch nicht schön aus. Ich hätte eben gerne eine gleichmäßige Bremse von Anfang bis Ende. Darum habe ich ja für mich den Aufwand betrieben und dieses o.a. Konstrukt entwickelt.

vor 1 Stunde schrieb Andy:

Wenn bei mir ein Zug lösfährt, werden alle Weichen und Signale geschaltet, bis zu einem Haltsignal.

Die Strecke zwischen zwei Bahnhöfen ist sehr lang. Nach deinem System müsste ich im Abfahrbahnhof bereits Einfahrt und Gleis im Zielbahnhof reservieren. Das wäre dann ziemlich lange blockiert. Die Strecke hat je ein Gleis in jede Richtung und so spricht doch nichts dagegen, dass der Zug sich schon auf den Weg macht ohne zu wissen, ob und wann im Zielbahnhof das Haltegleis verfügbar ist. Dafür habe ich mich eingehend mit BahnLands Tutorial über den Lockmechanismus beschäftigt. Das werde ich damit auch hinbekommen. Nur meine etwas "verrückte" Art zu bremsen muss dabei noch gezähmt werden. Aber auch das werde ich lösen. Entweder mit Timer (s.o.) oder indem ich das Lock erst nach Einleitung des Bremsvorgangs anfordere. MBS würde ja auch nur halb so viel Spaß machen wenn jede Lösung sofort auf dem Tisch läge, nicht wahr? ;)

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 6 Stunden schrieb Timba:

Die Strecke zwischen zwei Bahnhöfen ist sehr lang

Ja, das ist nicht unproblematisch. Das Thema hatten wir auch schon mal. Um's extrem zu sagen: wenn ich Hamburg-München durchschalte, müßte Berlin-Köln ganz schön warten. Und der zweite Zug Hamburg-München auch. Dafür habe ich dann schon Zwischenknoten.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 11 Stunden schrieb fzonk:

in der Realität wird meines Erachtens kein Signal plötzlich geöffnet, wenn vorher an einem Vorsignal ein Halt angezeigt wird.

Doch, selbstverständlich. Der voraus liegende Block ist zum Beispiel beim Passieren des Vorsignals noch besetzt, wird aber kurz darauf frei. Nur den umgekehrten Fall gibt es nicht. Wenn das Vorsignal "Fahrt" zeigt, dann wird das Hauptsignal nicht kurz darauf auf "Halt" umschalten.

vor 12 Stunden schrieb Timba:

Als Kompromiss sehe ich jetzt nur die Möglichkeit, statt einem deferredCall die Verzögerung durch einen Timer hervorzurufen

Du kannst schon mit der Verzögerung arbeiten. Du musst nur hinter die Verzögerung eine weitere Prüfung des Signals setzen.

101070717_AuslserBedingung.thumb.JPG.e66c744e9623abb080f235dfe1b90e18.JPG

 

Demo-Anlage:    Demo - Verzweigung nach Verzögerung.mbp

 

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

Hallo @Goetz,

vielen Dank für die Anregung. Inzwischen habe ich mich bereits für die Version entschieden, das Lock erst nach Ausführungsverzögerung des Bremsens anzufordern. Das erschien mir in dem Moment einfacher und weniger aufwendig zu realisieren und nachdem ich es gestern Abend noch eingefügt und getestet habe, gefällt es mir gut und funktioniert tadellos. Der Code dazu sieht dann so aus:

if not deferredCall then

  if vehicle.currentSpeed > 150 then
      local A = (vehicle.currentSpeed/math.sqrt(2.25504*3563))^2
      vehicle.deceleration = A
      vehicle.targetSpeed = 0
      $("LockAnfordern"):invoke(vehicle)
  else
      local T = (3563 * 0.087 - ((vehicle.currentSpeed / 3.6) / 2.8)^2 * 2.8 * 0.5) / (vehicle.currentSpeed / 3.6)
      defer(T, "Verzögerung")
  end

elseif deferredCall == "Verzögerung" then
  vehicle.targetSpeed = 0
  $("LockAnfordern"):invoke(vehicle)
end

 

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hallo @Timba

dann hätte ich dazu noch einen anderen Tipp:

 

vor 41 Minuten schrieb Timba:

math.sqrt(2.25504*3563)

könntest du einmal zu Beginn als globale Konstante im Modul-Skript ablegen, statt es bei jedem Aufruf neu zu berechnen.

Den fixen Teil von folgendem Term natürlich auch.

vor 41 Minuten schrieb Timba:

(3563 * 0.087 - ((vehicle.currentSpeed / 3.6) / 2.8)^2 * 2.8 * 0.5) / (vehicle.currentSpeed / 3.6)

Und wenn du dabei den Zahlen 2.25504, 3563 etc. aussagekräftige Namen gibst, dann wäre das noch ein Bonus.

 

Beispiel:

Faktor1 = 2.25504
Faktor2 = 3536
decel_Faktor = Faktor1 / Faktor2

-- und an geeigneter Stelle
local A = vehicle.currentSpeed^2 / decel_Faktor

Ich kenne die Bedeutung der beiden Zahlen nicht. Drum habe ich sie im Beispiel Faktor1 und Faktor2 genannt.

Und ich habe in deiner A Formel aufgeräumt. Wenn du erst eine Wurzel ziehst und dann das Ergebnis wieder quadrierst, machst du unnötig viele Rechenschritte.

1851627196_WurzelzumQuadrat.jpg.e46880d3006d0f906e83c1f36c509209.jpg

Bearbeitet von Goetz
ausführlichere erste Erklärung
Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 2 Minuten schrieb Goetz:

könntest du einmal zu Beginn als Konstante ablegen, statt es bei jedem Aufruf neu zu berechnen.

Da hast zu einerseits völlig recht, aber andererseits bewahre ich mir Flexibilität. Die 3536 ist die Länge der Bremsstrecke von auslösendem GK bis zum Haltepunkt vorm Signal. Bei einer Konstante wäre ich dann an diese Länge gebunden, oder müsste mir für jede andere Länge eine neue Konstante anlegen. Dann kann ich sie auch gleich berechnen lassen. Weil sooooo lange braucht die Kiste dafür ja nicht. ;)

Die 2.25504 ist hingegen tatsächlich eine feste Größe. Aber ob ich die eine Zahl nun als Konstante ablege oder so verwende, wird nichts beschleunigen. Allenfalls würde es für Zweitnutzer übersichtlicher und verständlicher, das ja.

vor 16 Minuten schrieb Goetz:

Und ich habe in deiner A Formel aufgeräumt. Wenn du erst eine Wurzel ziehst und dann das Ergebnis wieder quadrierst, machst du unnötig viele Rechenschritte.

Möglich, und ich will deine arithmetischen Kenntnisse auch gar nicht in Frage stellen, aber wenn ich deine Vorschläge umsetze bekomme ich andere Ergebnisse.

Meine Formel

local A = (vehicle.currentSpeed/math.sqrt(2.25504*3563))^2

liefert mir bei Speed 150 völlig korrekt 2,8 als Verzögerungswert.

Nach deinem Vorschlag

Faktor1 = 2.25504
Faktor2 = 3536
decel_Faktor = Faktor1 / Faktor2

bekomme ich als decel_Faktor erstmal 0,000637738 - wenn ich den Wert in deinen Vorschlag

local A = vehicle.currentSpeed^2 / decel_Faktor

einbaue und wiederum mit Speed 150 rechnen lasse, liefert mir diese Formel 35280970,63 statt 2,8. Das ist schlicht falsch. Lieber mache ich einen Rechenschritt mehr.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Sorry - blöde Schlamperei von mir. 

Du multiplizierst die beiden Werte. Das muss ich dann natürlich auch tun (und sie nicht dividieren)

Faktor1 = 2.25504
Bremsweg = 3536
decel_Faktor = Faktor1 * Bremsweg

Speed = 150
local A = Speed ^ 2 / decel_Faktor

A == 2.8217336153442

 

Bei dieser Vereinfachung kann man natürlich auf die Berechnung vorab verzichten:

local Faktor1  = 2.25504
local Bremsweg = 3536

Speed = 150
local A = Speed ^ 2 / Faktor1 / Bremsweg

A == 2.8217336153442

 

Bearbeitet von Goetz
Link zu diesem Kommentar
Auf anderen Seiten teilen

Ja, ist klar. :D Excel rechnet intern mit 15 Nachkommastellen. Eine Abweichung von 0,76% kann man nicht mit Rundungsfehler erklären. Ist mir auch egal, mir ist nicht wichtig, darüber zu streiten. Mir ist wichtig, dass der Zug exakt dort zum Stehen kommt wo er soll und das tut er.

By the way, die Formel "wurzel(14,5678)^2" liefert in Excel exakt 14,5678. Eigenartig. Wo doch durch erst Wurzel ziehen und dann wieder quadrieren ein Rundungsfehler entstehen müsste.

Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 49 Minuten schrieb Timba:

Eigenartig. Wo doch durch erst Wurzel ziehen und dann wieder quadrieren ein Rundungsfehler entstehen müsste.

Und an dem Punkt bin ich raus. Das ist mir zu doof ...

Es stimmt zwar, dass der Unterschied nicht auf einen Rundungsfehler zurückzuführen ist, sondern auf einen Zahlendreher in meiner Formel:

Ich hatte 3536 anstelle von 3563 geschrieben.

Aber deine Häme ist einfach daneben gewesen!

861057460_WurzelzumQuadratLua.jpg.241b6b31ed75a90292ad7304d755278f.jpg

 

 

Bearbeitet von Goetz
Link zu diesem Kommentar
Auf anderen Seiten teilen

vor 49 Minuten schrieb Goetz:

Aber deine Häme ist einfach daneben gewesen!

Wenn du das so empfindest, deine Sache. Ich sehe das so: Du hast mir in oberlehrerhafter Weise meine angeblichen mathematischen Unzulänglichkeiten öffentlich unter die Nase reiben wollen und hast dabei zweimal einen Bock geschossen. Letzten Endes mag meine Formel vielleicht umständlich gewesen sein, aber sie war wenigstens korrekt. Da ich selber im Klugscheißen geübt bin kann ich dazu nur sagen: Wenn man schon klugscheißt, dann wenigstens richtig. Und wo wir schon mal dabei sind, deine Arroganz geht mir genauso gegen den Strich wie dir meine Häme.

Habe fertig!

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