Hallo zusammen, ich bin an einem sehr softwarelastigen Hobbyprojekt, das unter der Last seiner eigenen Komplexität stöhnt. Die Komplexität liegt 50:50 in der Mensch-Maschine-Schnittstelle und im eigentlichen Regelprozeß. Zur Mensch-Maschine-Schnittstelle habe ich vor längerer Zeit einen eigenen Thread aufgemacht. Hier geht es nur um den Regelprozeß. Komplexität läßt sich ja am besten dadurch handhaben, daß sie sorgfältig in Teile zerlegt wird. Für eine gute Handhabung dieser Teile ist auch eine sinnvolle Benennung hilfreich. Auf der untersten Ebene ist das die Benennung der Variablen. In meinem Regelprozeß scheint es sechs Arten von Variablen zur Unterscheidung zu geben: Settings Variablen, wie sie im Einstellungs-Menü eingestellt und im nichtflüchtigen Speicher hinterlegt werden. Parameters Variablen, die aus den Settings errechnet werden, um vom Regelprozeß genutzt werden können. Für den Regelprozeß sind sie Konstanten. Inputs Variablen, die Sensorwerte und/oder physikalische Größen widerspiegeln. Für den Regelprozeß sind sie nur-lesbare Variablen. Outputs Variablen, die an einer höhere Ebene des Regelprozesses oder weitergegeben werden oder unmittelbar an einen Aktuator geschickt werden. Für den Regelprozeß sind sie les- und schreibbare Variablen. Signals (???) allgemeine flüchtige Variablen, die die Verbindung zwischen den Funktionsblöcken in einem Durchlauf der Regelschleife bilden. Dazu zählen auch Funktionsparameter und Rückgabewerte. Status Zustandsvariablen, die aus dem bisherigen Verlauf der Signale errechnet wurden und sich zwischen den Durchläufen der Regelschleife nicht ändern. Sie sind meist als „static“ oder (seltener) als „global“ implementiert. Die Namen habe ich mir aus den Fingern gesaugt. Insbesondere mit der Benennung „Signals“ bin ich aber nicht glücklich. Ich habe es von Simulink übernommen, wo jede Art von Variable zwischen den Funktionsblöcken so bezeichnet wird. Gibt es bessere Bezeichnungen? Oder habe ich vielleicht sogar eine Art vergessen, weil er in meinem Projekt nicht vorkommt?
Ich habe mal die Zeit genutzt, die Skizze noch etwas zu verfeinern. Ich denke, die Unterscheidung Settings und Parameters funktioniert - auch wenn ich nicht vermute, dass es im allgemeinen Sprachgebrauch diese Unterscheidung gibt. Mit der Unterscheidung Signals und Status bin ich immer noch nicht ganz glücklich - aber ich vermute, ich werde mich daran gewöhnen. Mit der ersten Unterscheidung dürfte sich das Durcheinander bei den Variablen außerhalb des Control -Blocks in den Griff bekommen lassen. Noch bin ich mir unsicher, ob für die Input -Variablen ein großer Stapel "get"-Funktionen oder ein dickes globales Struct Mittel der Wahl ist. Der nächste Schritt wird es dann sein, innerhalb des Control -Blocks Ordnung zu schaffen. Edit: Bitte entschuldigt die Dateigröße. Wie aus einer 81 kB großen CorelDraw-Datei ohne Einbettung der Schriften eine 1,4 MB-PDF werden kann, ist mir selbst ein Rätsel. Kann ein Moderator bitte die überflüssigen Bilder löschen?
Moin, was ist das, so was wie ein Blog oder versuchst du deine Gedanken zu ordnen?
Eigentlich hatte ich gehofft, ein paar Tipps zur üblichen Nomenklatur und zur Implementierung zu bekommen. So selten sind ja regelungstechnische Systeme auch nicht. Aber wenn außer mir keiner etwas schreibt, wird es tatsächlich eine Art "Rubber Duck Debugging". Funktioniert auch.
Walter T. schrieb: > Für eine gute Handhabung dieser Teile ist auch > eine sinnvolle Benennung hilfreich. Die Namensgebung ist sehr vom persönlichen Geschmack abhängig. Eine generelle Empfehlung kann man daher nicht geben. Ich würde Variablen auf keinen Fall nach ihrem Typ benennen, sondern ausschließlich ihre Funktion beschreibend, z.B. reg_par_i für den I-Anteil usw. Funktional zusammenhängende Variablen fasse ich in eine Struct zusammen, d.h. reg_par.i, reg_par.d usw. Camelcase mag ich nicht, ich bevorzuge Unterstriche.
Peter D. schrieb: > reg_par_i bloß nicht so. Da hast du in einem halben Jahr keine Ahnung mehr, was das bedeuten soll. Schreib die aus. Das kostet grad ein wenig Platz. Die IDE hilft beim tippen mit Code Completion und du kannst einfach drüber lesen ohne Nachdenken zu müssen
Bezeichnung der Variablennamen ist ein Thema, wo jeder eine andere Meinung hat. Deswegen ist es auch gar nicht so ergiebig. Zumal in den meisten IDEs eine Umbenennung mit wenigen Handgriffen erledigt ist. Interessanter finde ich Fragen wie: Wie organisiert man sinnvollerweise Inputs? - Großes globales struct und eine große update_input()-Funktion? - Viele einzelne Get-Funktionen? Haben solche Funktionen Nebenwirkungen? - Oder vielleicht sogar eine Funktionstabelle? - Oder gar eine noch schönere Lösung? Wann hat welche Lösung einen Vorteil?
Walter T. schrieb: > Wie organisiert man sinnvollerweise Inputs? Ganz wie Du willst. Sind es ADC-Kanäle, lese ich die immer reihum ein und schreibe sie in ein Array. Das gleiche nur umgekehrt mache ich mit DAC-Ausgängen. Das erfolgt im Hintergrund, z.B. im 1ms Timerinterrupt. Der Vorteil ist, die Mainloop muß nicht darauf warten. Sie schnappt sich die Werte und legt die Ergebnisse ab (EVA-Prinzip).
Der Control-Block würde bei uns wie folgt aussehen: S-Switch, PID, V-Limiter und R-Limiter wären Module mit folgenden Attributen: * einen modulspezifischen Status (z.B. Init, Run, Restart, ...) * einen allgemeinen Status (Für alle gleiche Werte, z.B. Aktiv, Idle, Aus, ..) * verschiedene modulspezfische Bits oder Werte, z.B. verschiedene Error-Flags, Regelwerte etc. Jedes Modul bekommt Rechenzeit analog einer SPS-Loop. Eine Programmierung sieht dann in etwa so aus:
1 | /* in V-Limiter */
|
2 | if(Input.Vcc.Value > Par.VccMax.Value) |
3 | {
|
4 | Set(V_Limiter.ErrBits.VccOFL); |
5 | V_Limiter.State = Z_VL_OFL; |
6 | V_Limiter.Out.EngVal = 0; |
7 | Set(Output.Leds.ErrLedVccOFL); |
8 | }
|
Wobei das natürlich arg verkürzt ist, wir haben z.B. die Parameter Modulspezifisch und setzen/lesen Input/Output hingegen zentral (weil es halt nur einen physikalischen Kontext gibt) So Kurz-Notation wie Z_VL_xx für "Zustand_V_Limiter_xx" sind erst mit größeren Projekten sinnvoll, wenn das Muster erkennbar und gewohnt ist. Bei nur ein paar Tausend Zeilen Code verwirrt das zu sehr, da lieber ausschreiben.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.