Jump to content

[Aufbau] Stack-Emulation/Simulation


AuronX

Recommended Posts

Hallo,

 

einfach um mal darauf aufmerksam zu machen:

 

https://github.com/NobodysNightmare/TFStackEmulator

 

Quasi seit gestern Abend arbeite ich an einem Stückchen Software das per TCP ansprechbar ist und so tut als wäre es ein Brick-Stack. Das heißt man kann mit beliebigen Bindings (oder auch dem Brickv) eine Verbindung dazu aufbauen.

 

Wozu das ganze?

Naja, eigentlich wollte ich mich nur noch weiter mit dem TF-Protokoll vertraut machen und rumprogrammieren. Aber wenn das ganze etwas umfangreicher wird könnte es tatsächlich auch anderen Leuten etwas nützen, weil sie ohne die echte Hardware ihre Programme und Tools testen können.

 

Was kann es schon?

Der aktuelle Stand ist eher knapp, das Wesentliche:

- Eine Klasse zur Simulation des Stacks

- Eine Klasse um den so einen Stack per TCP verfügbar zu machen

- Ein Bricklet: Temperatur (unterstützt GetTemperature, den TemperatureCallback und Enumerate)

- Ein Testprogramm das einen Stack mit zwei Bricklets startet (auf Port 4224)

- ein wenig Architektur drumherum

 

Das ganze ist recht modular angelegt, aber der Code ist durchaus noch durchwachsen. Clean Code mischt sich mit hacky Code :D

 

Was habe ich vor?

Mein Fancy-Ziel ist es ein paar Standard-Bricklets zu implementieren und dann ein per Datei konfigurierbares Programm dafür zu schreiben. In der Art:

<stack>
<brick type="master" uid="myu1d">
  <someMoreConfig />
</brick>
<bricklet type="temperature"  uid="myu2d">
  <range min="20.0" max="24.0" />
</bricklet>
</stack>

 

Für einige Bricks würde sich vermutlich auch eine Visualisierung des aktuellen Zustands anbieten, ich glaube da kann man sich noch tausend Dinge ausdenken :D

 

Falls euch das nicht alles zu langweilig klingt höre ich gerne noch mehr verrückte Ideen oder Feedback :D

Link to comment
Share on other sites

Cool.

 

Ich hab gleich mal eine Klasse gemacht: SinTemperatureBricklet.

Sieht gut aus. Die Sprünge zwischen den Kurven kamen vom debuggen.

 

Mein Vorschlag:

Abstrakte Basisklassen für alle Brickles welche nur noch die aktuell benannte RandomizeTemperature Method, die OnTick und eine neue Methode "Init" implementieren müssen.

 

OnTick -> wird wie bisher Aufgerufen.

RandomizeTemperature -> SetNewValue kann per hand aufgerufen werden und ist allgemein benannt, dass es für alle Bricklets mit einen Wert gelten kann.

Init -> wird einmal nach den Konstruktor oder beim hinzufügen zum Emulator einmal aufgerufen hier kann man alle eigenen Variablen initialisieren.

 

Nur so eine Idee ^^

 

Die Basisklassen könnten dann sicher per Generator für alle Bricklets erzeugt werden.

Oder wie wäre es die gleich im C# Code zu erzeugen?

Per Reflection alle Bricklets auslesen die Konstanten auslesen und mit den Namen dann als dateien abspeichern... Ich glaub ich überlege mir da mal was...

SinTest.png.00cc95547f8cb668c2a13e77ab08f134.png

Link to comment
Share on other sites

Ich bin erstmal total begeistert, dass das Feedback so positiv ist :D

 

@The_Real_Black: Was die Wiederverwendbarkeit innerhalb der Bricklets angeht habe ich auch schon hin und her überlegt. Das Problem ist, dass auch die "einfachen" Bricklets sich dann in Details unterscheiden können. Ich denke Unterschiede wie int, uint und short kriege ich noch über Templates beseitigt... Aber was ist mit unterschiedlichen Callbacks usw.?

 

Wegen Randomize/SetNewValue: Lässt sich denke ich so umsetzen, hier bin ich mir noch unsicher ob es eine gute Idee ist das im "Tick" zu machen oder ob es davon unabhängig sein sollte. Glaube aber schon, dass es okay ist.

Eine andere Möglichkeit wäre es den Setter für den Wert auch public zu machen und dann kann es von außen auf dem Device gesetzt werden. Macht aber vieles unbequemer glaube ich...

 

Danke euch :)

Link to comment
Share on other sites

Zu der Wiederverwendbarkeit in den "einfachen" Bricklets:

 

Ich habe gerade mal ein AmbientLight-Bricklet auf Grundlage einer neuen Basisklasse implementiert. Sagt mal ob das cool ist (also insbesondere wie die Subklasse dann implementiert wird).

 

Viele Grüße

Jan

 

P.S.: Das Konzept "Callback" werde ich auch noch versuchen etwas wiederverwendbarer zu machen...

 

Nachtrag: Ich habe gerade eben noch ein Barometer-Bricklet auf Grundlage des Decorator-Pattern erstellt. Ich glaube das ist bisher meine liebste Variante. Sie ist sehr mächtig und trotzdem recht übersichtlich.

 

Schaut es euch mal an, wenn es keine Gegenstimmen gibt werde ich das existierende Temperature-Bricklet und das AmbientLight-Bricklet auch auf dieser Grundlage bauen.

Link to comment
Share on other sites

Hi ich hab mal etwas getestet und eine kleine Oberfläche gebastelt. Funktioniert ganz gut bis auf einen Restart der Simulation... ich sollte die Threads sauber beenden und neu anlegen. Als ersten Schritt bisher habe ich beim Emulator eine Stop Methode hinzugefügt und die while(true)-Schleifen durch abbrechbare ersetzt. Mir gefällt die Lösung mit dem generischen Klassen ("SingleValueDevice<T>") auch wenn ich mir noch eine Zwischenstufe (abstrakte Klasse) zwischen "EnumeratableDevice" und "RandomTemperatureBricklet"  wünsche. AbstraktTemperatureBricklet -> bei welchen man dann die bereits genannten Methoden implementieren kann.  Davon kann man dann das RandomTemperatureBricklet ableiten oder auch ein "RemoteTemperatureBricklet" welches dann werte von außen annimmt.

 

Wurde schon etwas in Richtung Bricks geplant? IMU, Servo, DC...?

Damit könnte man dann eine ganze Testumgebung aufsetzen... ich sehe schon kleine virtuelle Roboter welche durch 3D Umgebungen fahren... mit Rückkopplungen damit die Simulation auf die Eingaben des zu testenden Programms reagieren kann... KNN welche dann damit trainiert werden können... und so das Selbst fahren lernen können.

 

:o:-\;)

 

ok da ist noch viel viel zu Coden dafür.

 

 

SinTest_Form.png.9bf1e7e5b3c2cc357d215cb4a5062902.png

TFStackEmulator-Black.7z

Link to comment
Share on other sites

Ich würde eher vom SingleValueDevice abgehen wollen und den Decorator umsetzen. Das Device ist nicht flexibel genug, was passiert bei mehr als einem Wert? Was wenn ich ein Device habe das mehr kann (Bricks) UND außerdem noch einen Wert mit Callbacks usw. anbietet.

 

Aber falls dir das mit dem Decorator gar nciht gefällt sag es mir bitte ;)

Link to comment
Share on other sites

@AuronX: Mir gingen noch die anderen Brickletimplementierungen durch den Kopf. Deine Lösung ist gut. Ich bin mir noch nicht sicher was der beste Weg ist, aber ich würde es auch erst wie im "RandomAmbientLightBricklet" machen.

 

 

Edit: Noch eine Idee: Binde die TF Bindings mit ein und verwende ihre Konstanten anstelle es selbst hard zu Coden.

Link to comment
Share on other sites

Edit: Noch eine Idee: Binde die TF Bindings mit ein und verwende ihre Konstanten anstelle es selbst hard zu Coden.

 

Tatsächlich habe ich schon überlegt die Bricklets zu generieren... aber das wird nicht gut gehen. Ich weiß nicht so recht, ob es sich lohnt die Bindings einzubinden, nur um einen Stapel wohl dokumentierter ints zu erhalten.

 

...

 

Ha, Idee! In diesem Pull Request habe ich einen Generator für ein DeviceIdentifier-enum gebaut. Dieses enum werde ich nutzen!

 

Viele Grüße

Jan

 

P.S.: Habe jetzt auf Decorators umgestellt und dem AmbientLightBricklet direkt noch den Analog-Wert spendiert.

 

P.P.S: Mir ist grad aufgefallen, sobald die Reached-Callbacks unterstützt werden sind ja ganz viele Bricklets feature-mäßig abgedeckt :D

Link to comment
Share on other sites

  • 7 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...