wkh Geschrieben Samstag um 11:30 Uhr Geschrieben Samstag um 11:30 Uhr Ich suche nach einer Möglichkeit auf Objekte des MBS auf andere Art Zugriff zu bekommen als unten dargestellt: function AheadTrafficPedLightRed(Light, Lightlabel) if Light == "1" then $("AH001AA").state = 1 -- rot - red -- $(Lightlabel).state = 1 end end Die von mir oben auskommentierte Version funktioniert nicht. Auch verschiedene Varianten, die ich probiert habe nicht. Wenn etwas beim eingeben akzeptiert wurde, dann war der Eintrag hinterher gelöscht und das Ergebnis $(""). Muss ich den Weg über Variablenlisten gehen? Lösungen und Lösungsideen sind sehr willkommen. Viele Grüße wkh
Phrontistes Geschrieben Samstag um 11:37 Uhr Geschrieben Samstag um 11:37 Uhr (bearbeitet) Was ist Lightlabel für eine Art von Objekt und besitzt dieses Objekt einen state? Oder anders gefragt: Übergibst Du wirklich das was Du übergeben willst? Bearbeitet Samstag um 12:45 Uhr von Phrontistes typo
wkh Geschrieben Samstag um 11:58 Uhr Autor Geschrieben Samstag um 11:58 Uhr Lightlabel ist in diesem Fall das Label eines Fußgängerampel Objektes. Dieses Label möchte ich in ein Objekt umwandeln, über das ich dann den Status der Ampel ändern kann. Mein Ziel ist es eine einfache, möglichst generische Steuerung für Ampeln zu entwickeln. Die Anweisung für den ausgelösten Event soll über die Label der Objekte erfolgen. Muss ich vielleicht über den Weg über getEntityByName nutzen? Gruß wkh
EASY Geschrieben Samstag um 12:23 Uhr Geschrieben Samstag um 12:23 Uhr Hallo, nach deiner Beschreibung... vor 18 Minuten schrieb wkh: Lightlabel ist in diesem Fall das Label eines Fußgängerampel Objektes. Dieses Label möchte ich in ein Objekt umwandeln, über das ich dann den Status der Ampel ändern kann. ... mußt du diesen Weg gehen... vor 18 Minuten schrieb wkh: Muss ich vielleicht über den Weg über getEntityByName nutzen? Vielleicht möchtest du auch die Anlage exportieren und hier die .mbp Datei mit einstellen. Probleme mit der EV sind nach nur Beschreibungen meistens schwer nachzuvollziehen Gruß EASY
wkh Geschrieben Samstag um 12:38 Uhr Autor Geschrieben Samstag um 12:38 Uhr Hallo Easy, ich werde die Anlage, bzw. es ist nur eine Idee zur Ereignisverwaltung, einstellen, wenn ich damit fertig bin. Mein Versuch eine Steuerung zu entwickeln beinhaltet Routen und Vorfahrtsregelungen. Ich bin gerade am letzten Punkt, den Ampeln, angekommen. Der Hinweis, der mich in meinem letzten Gedanken bestätigt hat, hilft mir aber auf jeden Fall weiter. Gruß wkh
Phrontistes Geschrieben Samstag um 12:39 Uhr Geschrieben Samstag um 12:39 Uhr (bearbeitet) vor 41 Minuten schrieb wkh: Lightlabel ist in diesem Fall das Label Dann ist ja klar, dass das nicht geht. Ein Label hat keinen state. Bearbeitet Samstag um 12:39 Uhr von Phrontistes
Phrontistes Geschrieben Samstag um 12:43 Uhr Geschrieben Samstag um 12:43 Uhr (bearbeitet) vor 45 Minuten schrieb wkh: Muss ich vielleicht über den Weg über getEntityByName nutzen? Nein, wenn Du in Lightlabel das Objekt und nicht seinen Namen übergibst. Ersteres ist der sinnvolle Weg, denn Namen sind nicht eindeutig. Bearbeitet Samstag um 12:44 Uhr von Phrontistes typo
Goetz Geschrieben Samstag um 12:45 Uhr Geschrieben Samstag um 12:45 Uhr vor 41 Minuten schrieb wkh: Mein Ziel ist es eine einfache, möglichst generische Steuerung für Ampeln zu entwickeln. Hallo wkh, kennst du mein Video zu diesem Thema? Den Link dazu findet du in meiner Signatur. Die Anlage zum Video hat die Content-ID 20F2B5B8-FAC2-403A-A063-DC084515941A Selbst, wenn es noch weit von dem entfernt ist, was dir an generischer Prozedur vorschwebt, könnte das eventuell als Diskussionsgrundlage dienen? Und wenn du die EV in Lua umwandelst, siehst du schon eine ganze Reihe nützlicher Schreibweisen. Die Schreibweise mit dem vorangestellten $-Zeichen ist eine Besonderheit im Studio. Dahinter verbirgt sich eine Objekt-ID. Der Name in den Klammern soll dir nur zeigen, um welches Objekt es sich handelt. Du kannst das Objekt sogar umbenennen und wirst dann im Skript entsprechend den neuen Namen wiederfinden. Das heißt aber im Gegenzug, dass Objekte bei dieser Schreibweise nicht mit ihrem Namen angesprochen werden. Viele Grüße Götz
wkh Geschrieben Samstag um 13:31 Uhr Autor Geschrieben Samstag um 13:31 Uhr Hallo Goetz, danke für deine Antwort. Deine Beträge werde ich mir anschauen. Ich wollte über eine Variable die das Objektlabel enthält und die ich in $(" ... ") einfügen wollte, das Objekt aufrufen. Dafür gibt es aber getEntityByName. Das ist mir nicht gleich eingefallen. Mein fertiges Werk werde ich hoffentlich in ein paar Tagen vorstellen. Mich interessiert ob das, was ich mir ausgedacht habe einen gangbaren Weg beinhaltet oder vielleicht auch ein Performancekiller sein könnte. Viele Grüße wkh
Goetz Geschrieben Samstag um 13:46 Uhr Geschrieben Samstag um 13:46 Uhr (bearbeitet) vor 15 Minuten schrieb wkh: eine Variable die das Objektlabel enthält und die ich in $(" ... ") einfügen wollte Genau das funktioniert leider nicht und das wollte ich dir mit meiner Erläuterung zum $-Zeichen verdeutlichen. In der Klammer steht nichts, was du zum Adressieren des Objekts verwenden kannst. In der Klammer steht nur eine Rückmeldung vom Studio. Deshalb eignet sich die $-Schreibweise nicht zur dynamischen Adressierung von Objekten. Bearbeitet Samstag um 13:47 Uhr von Goetz
EASY Geschrieben Sonntag um 10:52 Uhr Geschrieben Sonntag um 10:52 Uhr Hallo @wkh, ich kenne deinen Anwendungsfall nicht, deshalb mal nur als Idee... Wenn du anstatt einer Funktion ein benutzerdefiniertes Ereignis definierst, dann kannst du als Übergabeparameter (Variable) direkt diese Variable als Typ "Objekt" definieren und mußt nicht eine "Rückumwandlung" über getEntityByName machen... Gruß EASY
wkh Geschrieben Sonntag um 12:01 Uhr Autor Geschrieben Sonntag um 12:01 Uhr Hallo Easy, ich bin vielleicht jetzt ein dreiviertel Jahr beim MBS. Deshalb kenne ich mich noch nicht hundertprozentig aus und entdecke immer wiedere neues. Da Programmieren meine Leidenschaft seit Jahrzenten ist, versuche ich meine Steuerung im MBS jetzt durch Lua-Scripte einzurichten. Damit du verstehst was ich mir darunter vorstelle, kopiere ich die beiden einzigen Ereignisse, die es für die Steurung von Straßenverkehr in meiner Vorstellung geben soll, die reagieren, wenn ein Kontakt betreten wird. Ereignis 1: Es reagiert nur wenn der Kontakt teil einer in einer Liste definierten Route ist. -- Initialisierungskontakt - Initialization contact? if string.sub(contact.name, 7, 7) == "I" then if HasVehicleRoute(vehicle, contact) == false then return end end print("Weiter") -- Zielkontakt - Destination contact? if vehicle.variables["Contact"] ~= contact then return end -- Dieser Kontakt ist der Zielkontakt - This contact is the target -- Fahrtunterbrechung ohne Richtungswechsel - Driving break without direction change if string.sub(contact.name, 7, 7) == "B" then vehicle.engine.active = false -- Weiterfahrt nach Wartezeit - Route to be continued after waiting time $("BreakEnd"):invoke(contact, vehicle) return end if string.sub(contact.name,7, 7) == "P" then -- Fahrzeug wird geparkt, Richtungswechsel - Vehicle will be parked, drive direction change vehicle.engine.active = false vehicle.drivingDirection = -vehicle.drivingDirection vehicle.target = GetNewDestination(vehicle) -- Weiterfahrt nach Wartezeit - Route to be continued after waiting time $("ParkingSlotExit"):invoke(contact, vehicle) return end -- Richtungswechsel - Direction change if string.sub(contact.name, 7, 7) == "R" then vehicle.engine.active = false vehicle.drivingDirection = -vehicle.drivingDirection vehicle.target = GetNewDestination(vehicle) $("DirectionChange"):invoke(contact, vehicle) return end vehicle.target = GetNewDestination(vehicle) Ereignis 2: Es reagiert immer, wenn der Kontakt mit dem Schlagwort ServiceContact betreten wird. -- 3-Ampel Steurung if string.sub(contact.name, 7, 7) == "3" then -- Fußgängerampeln auf rot - Switch pedestrian light to red ThreePedLightRed(string.sub(contact.name, 9, 15)) $("ThreeTrafficLightSwitching"):invoke(string.sub(contact.name, 9, 18)) end -- Ampel für gerade aus Verkehr schalten - Set traffic light for ahead traffic if string.sub(contact.name, 7, 7) == "A" then -- Fußgängerampeln auf rot - Switch pedestrian light to red AheadTrafficPedLightRed(string.sub(contact.name, 9, 15)) $("AheadTrafficLightSwitching"):invoke(string.sub(contact.name, 9, 18)) end -- "C" Zusammenstoß verhindern - "C" collision prevention if string.sub(contact.name, 7, 7) == "C" then local n = tonumber(string.sub(contact.name, 8, 9)) if $("Ereignisse").variables["ExitBlocked"][n] == nil then $("Ereignisse").variables["ExitBlocked"][n] = 0 end $("Ereignisse").variables["ExitBlocked"][n] = $("Ereignisse").variables["ExitBlocked"][n] + 1 -- Kann gelöscht oder auskommentiert werden - Comment out or delete $("DelayForCollisionPrevention"):invoke(n, tonumber(string.sub(contact.name, 11, 12))) return end -- Zeit zwischen zwei Fahrzeugen messen und Geschwindigkeit für das zweite Fahrzeug einstellen -- Get the time between two vehicles passing the contact and set speed for the second vehicle if string.sub(contact.name, 7, 7) == "D" then contact.variables["PreviousVehicle"] = contact.variables["CurrentVehicle"] contact.variables["CurrentVehicle"] = Seconds if contact.variables["CurrentVehicle"] - contact.variables["PreviousVehicle"] <= tonumber(string.sub(contact.name, 8, 9)) then vehicle.currentSpeed = tonumber(string.sub(contact.name, 11, 12)) end return end if string.sub(contact.name, 7, 7) == "H" then local desVar = string.sub(contact.name, 12, 16) local n = tonumber(string.sub(contact.name, 18, 19)) if $("Ereignisse").variables[desVar][n] > 0 then vehicle.engine.active = false $("Ereignisse").variables[desVar][n + 1] = $("Ereignisse").variables[desVar][n + 1] + 1 $("WaitForRouteContinue"):invoke(tonumber(string.sub(contact.name, 8, 10)), desVar, n, vehicle) end end -- Geschwindigkeit setzen - Set speed if string.sub(contact.name, 7, 7) == "S" then vehicle.currentSpeed = tonumber(string.sub(contact.name, 8, 10)) end -- Ampel für gerade aus Verkehr schalten - set traffic light for ahead traffic if string.sub(contact.name, 7, 7) == "T" then -- Fußgängerampeln auf rot - Switch pedestrian light to red TurnTrafficPedLightRed(string.sub(contact.name, 9, 15)) $("TurnTrafficLightSwitching"):invoke(string.sub(contact.name, 9, 18)) end if string.sub(contact.name, 7, 7) == "W" then print("W") local desVar = string.sub(contact.name, 11, 15) print(desVar) local n = tonumber(string.sub(contact.name, 17, 18)) $("Ereignisse").variables[desVar][n] = $("Ereignisse").variables[desVar][n] + 1 $("TF-Vorfahrt").text = $("Ereignisse").variables[desVar][n] $("HaltNoRightOfWay"):invoke(tonumber(string.sub(contact.name, 8, 9)), desVar, n) end if string.sub(contact.name, 7, 7) == "U" then n = tonumber(string.sub(contact.name, 8, 9)) if $("Ereignisse").variables["ExitBlocked"][n] > 0 then $("Ereignisse").variables["ExitBlocked"][n] = $("Ereignisse").variables["ExitBlocked"][n] - 1 end end Meine Vorstellung ist einen möglichst generischen Programmcode zu haben und über die Label der Kontakte festzulegen, was geschehen soll. Im Moment arbeite ich noch an einer Ampelsteurung. Das ist der komplizierteste Teil. Wenn ich damit fertig bin denke ich daran mein Projekt vorzustellen. Später möchte ich dann alles natürlich in einer Anlage einbauen. Ich wollte mit den Codeschnippseln nur meinen Lösungsansatz deutlich machen. Zum Verständnis, was da passiert braucht es vermutlich zusätzliche Erklärungen. Ich muss auc für michalles noch aufschreiben. Viele Grüße wkh
Goetz Geschrieben Sonntag um 12:27 Uhr Geschrieben Sonntag um 12:27 Uhr (bearbeitet) vor 36 Minuten schrieb wkh: Damit du verstehst was ich mir darunter vorstelle, kopiere ich die beiden einzigen Ereignisse, die es für die Steurung von Straßenverkehr in meiner Vorstellung geben soll Hallo wkh, wenn du dafür die Schaltfläche in der Kopfleiste deiner Antwort benutzt, ist der Code dank Syntax Highlighting im Posting besser lesbar: if string.sub(contact.name, 7, 7) == "I" then if HasVehicleRoute(vehicle, contact) == false then return end end print("Weiter") -- Zielkontakt - Destination contact? if vehicle.variables["Contact"] ~= contact then return end -- Dieser Kontakt ist der Zielkontakt - This contact is the target -- Fahrtunterbrechung ohne Richtungswechsel - Driving break without direction change if string.sub(contact.name, 7, 7) == "B" then vehicle.engine.active = false -- Weiterfahrt nach Wartezeit - Route to be continued after waiting time $("BreakEnd"):invoke(contact, vehicle) return end Und wenn du deine Kontakte unterscheiden willst, empfehle ich dir eine Objektvariable anstelle des siebten Zeichens im Namen. Die Variable nennst du immer gleich - z.B: Typ - und darin hinterlegst du einen Buchstaben oder eine Zahl. Eine Zahl hätte dann noch den Vorteil, dass du die als Index verwenden kannst, um direkt aus einer Liste die zugehörige Funktion zu holen. Das ist besser als mit einer Reihe von Vergleichen alle eventuellen Möglichkeiten abzuklappern. Falls du lieber bei deiner Variante mit dem Namenszusatz bleiben willst, lies ihn einmal aus und lege ihn in einer lokalen Variablen ab. Denn du brauchst dieses siebte Zeichen ja mehrfach. Nämlich für jeden der Vergleiche. Da lohnt es sich, wenn du den Namen nicht immer wieder neu auslesen und zerlegen musst, sondern auf die lokale Variable direkt (= im Prozessor-nahen Cache) zugreifen kannst. Viele Grüße Götz Bearbeitet Sonntag um 12:38 Uhr von Goetz Schreibfehler korrigiert
wkh Geschrieben Sonntag um 14:13 Uhr Autor Geschrieben Sonntag um 14:13 Uhr Hallo Goetz, vielen Dank für deine Antwort. Der Hinweis auf <> ist sehr hilfreich. Die Unterstützung, die man durch das Forum bekommt finde ich toll. Ob ich deinen Hinweis auf die Objektvariablen berücksichtigen kann muss ich mir noch überlegen. Ich bin noch nicht ganz durch, mit dem was ich erreichen will. Es ist aber so, dass über das Label auch für den gleichen Kontakttyp unterschiedliche Informationen an den Event übermittelt werden können. So kann über den Kontakt mit dem "S" auf der 7 Position, die Geschwindigkeit der Fahrzeuge beim Betreten eingestellt werden und die kann an jeder Stelle anders sein. Es gibt eine ganze Reihe von Kontakten, die sogar noch mehr Informationen vermitteln. Am Ende bin ich natürlich auch gespannt, ob das, was ich mit vorstelle sinnvoll und brauchbar ist. Gruß wkh
Goetz Geschrieben Sonntag um 14:32 Uhr Geschrieben Sonntag um 14:32 Uhr vor 5 Minuten schrieb wkh: Es ist aber so, dass über das Label auch für den gleichen Kontakttyp unterschiedliche Informationen an den Event übermittelt werden können. Hallo wkh, dennoch ist es bei dir immer nur ein Buchstabe an der siebten Stelle im Namen. Der könnte ebenso gut in einer Objektvariablen stehen. Wie du diese Information dann an unterschiedlichen Stellen im Programm auswertest, ist davon ganz unabhängig. Ganz allgemein haben alle Objekte im MBS eine Liste an Eigenschaften. Mit Objektvariablen kannst du diese Liste nach deinen Wünschen erweitern. Deshalb sind die das richtige Mittel für solche Unterscheidungen. Namen sind unzuverlässig und das Zerlegen des Namens ist unnötig umständlich. Du kannst übrigens in jedem Objekt eine beliebige Anzahl an Variablen haben. Und sie können Informationen ganz unterschiedlicher Art bereithalten: Zahlen, Strings, Objekte, Zeiten, Listen, Tabellen, Fahrstraßen, Ereignisse ... Jedes Objekt, also Fahrzeuge ebenso wie Kontakte, Signale, Gleisstücke usw., kann Objektvariablen speichern. So kannst du Informationen immer dort hinterlegen, wo sie logisch hingehören. Viele Grüße Götz
wkh Geschrieben Sonntag um 15:21 Uhr Autor Geschrieben Sonntag um 15:21 Uhr Hallo Goetz, danke für die Antwort. Ich benutze in meinem Projekt auch Objektvariablen. Die Vorteile sind mir auch bewußt. Ich kann mir ja einen bestimmten Kontakt als Template irgenwo aufs Brett legen und immer wieder kopieren und der Kontakt kann auch ein Bezeichnung haben, die aussagekräftig ist. Angefangen zu überlegen habe ich als ich gemerkt hatte das Fahrzeuge und/oder das MBS die Route wählen. Wenn ein Fahrzeug an einem Parkplatz vorbei fährt versucht es einzuparken, wenn man nicht dagegen unternimmt oder es fährt durch die Bushaltestelle. Dann kam eins zum anderen und mir fällt mir immer noch etwas neues ein. Ich hänge jetzt doch mal die Datei an. Es funktioniert noch nicht alles. Es gibt keine Beschreibung. Vielleicht vermittelt es aber einen Eindruck davon, was ich erreichen will. Die Label haben, wenn sie eine Bedeutung haben, erst eine ab Position 7. Die Ampeln bitte nicht beachten, die funktionieren noch nicht. Was auf dem Brett ist enspricht sicherlich auf keinen Fall der Realität. Die Probleme bei der Umsetzung einer Steurung werden aber meiner Meinung nach sehr deutlich. Gruß wkh Straßenverkehr.mbp
Goetz Geschrieben Sonntag um 16:55 Uhr Geschrieben Sonntag um 16:55 Uhr vor einer Stunde schrieb wkh: Die Probleme bei der Umsetzung einer Steurung werden aber meiner Meinung nach sehr deutlich. Hallo wkh, für mich wird vor allem deutlich, dass es nicht ratsam ist zwei Methoden zu vermischen. Alles, was du mit deinen Anhängseln an den Namen der Kontakte erzielst, kannst du ebenso gut mit Objektvariablen in diesen Kontakten erreichen. Die hätten dann - im Gegensatz zu deinen Anhängseln - aussagekräftige Namen. Das alleine würde die Lesbarkeit deiner experimentellen Anlage schon merklich verbessern. Diese Anhängsel lösen keins deiner Probleme, verursachen aber unnötige Komplikationen. Nimm zum Beispiel die Parkzeit: Wenn der Kontakt eine Variable Parkzeit enthielte, dann könnte in dieser Variablen der Wert als Zahl stehen. Damit sparst du dir schon die zweifache Umwandlung. Du prüfst, ob die Variable vorhanden ist und verwendest dann den Wert aus der Variablen für die Verzögerung. Fertig. if contact.Parkzeit ~= nil then -- Fahrzeug wird geparkt, Richtungswechsel - Vehicle will be parked, drive direction change vehicle.engine.active = false vehicle.drivingDirection = -vehicle.drivingDirection vehicle.target = GetNewDestination(vehicle) -- Weiterfahrt nach Wartezeit - Route to be continued after waiting time $("ParkingSlotExit"):invoke(contact.Parkzeit, vehicle) return end Anstelle des Kontakts übergibst du gleich den Wert der Variablen an das Ereignis ParkingSlotExit (und benennst den Parameter entsprechend): if not deferredCall then defer(Parkzeit, "Delay") elseif deferredCall == "Delay" then -- ... end Schon ist alles viel schlanker und lesbarer. Wenn du eh schon Objektvariablen einsetzt, dann bleibst du meines Erachtens besser konsequent dabei. Viele Grüße Götz
EASY Geschrieben Sonntag um 19:06 Uhr Geschrieben Sonntag um 19:06 Uhr (bearbeitet) Hallo @wkh, noch ein kleiner Nachtrag zu deiner Methode mit "string.sub". Die Funktion berücksichtigt nicht die utf-8 Codierung. Manche Zeichen (z.B. Umlaute) belegen 2 (oder mehr) Byte. Beispiel... local a="abcdef7ghi" local b="äbcdef7ghi" print(a,"a,7,7",string.sub(a,7,7)) print(b,"b,7,7",string.sub(b,7,7)) ...liefert als Ergebnis... [20:42:28] Ereignisprotokollierung gestartet [20:43:02] abcdef7ghi a,7,7 7 -- -> gewünschtes Ergebnis [20:43:02] äbcdef7ghi b,7,7 f -- -> falsches Ergebnis ...damit würde dein System der Extraktion von Parametern über den Namen nicht immer zuverlässig funktionieren. Gruß EASY Bearbeitet Sonntag um 19:20 Uhr von EASY
wkh Geschrieben Sonntag um 20:54 Uhr Autor Geschrieben Sonntag um 20:54 Uhr Hallo Easy, hallo Götz, vielen Dank nochmal für eure Hinweise. da ich sowohl beim MBS, als auch bei Lua noch im Anfängerstadium bin, vertraue ich jetzt darauf, dass ihr mit eureren Hinweisen recht habt. Ich werde es ändern. Durch das Video von Götz zu den Ampeln ist mir auch wieder deutlich geworden , dass ich doch vieles über die Möglichkeiten vom MBS noch lernen muss. Nochmals Dank für eure Mühe. Gruß wkh
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