Hinweis 1: Am besten Code-Blöcke erstmal ausblenden und Problembeschreibung lesen.
Problemstellung: Ich möchte eine Klassendefinition für eine Rotationsspule, d.h. eine rotationssymmetrische Spule/Drossel, welche auf einer mechanischen Welle mitrotieren kann, schreiben.
Diese besteht aus einer Wicklung (Wickelkörper und Kupferwindungen) und zwei identischen Topfkernen.
Für Wicklung und Topfkern habe ich jeweils eine Klasse geschrieben, welche autark erstmal funktionieren.
Klasse "RotWicklung":
Code:
% Wicklung umfasst Wickelkörper und aufgewickelten Kupferlackdraht
classdef RotWicklung
%% Konstanten properties(Constant = true, Hidden = true) % Standard-Nenndurchmesser des Kupferlackdrahtes; [d_Cu_std] = m
d_Cu_std = 1e-3;
%% Set-Methoden function obj = set.d_Cu(obj, d_Cu) if d_Cu <= 0
obj.d_Cu = obj.d_Cu_std;
else
obj.d_Cu = d_Cu;
end end function obj = set.N_ax(obj, N_ax) if N_ax < 1
obj.N_ax = obj.N_std;
else
obj.N_ax = uint8(N_ax);
end end function obj = set.N_rad(obj, N_rad) if N_rad < 1
obj.N_rad = obj.N_std;
else
obj.N_rad = uint8(N_rad);
end end function obj = set.b_ax(obj, b_ax) if b_ax <= 0
obj.b_ax = obj.b_std;
else
obj.b_ax = b_ax;
end end function obj = set.b_rad(obj, b_rad) if b_rad <= 0
obj.b_rad = obj.b_std;
else
obj.b_rad = b_rad;
end end
%% Get-Methoden für Dependent-Attribute function N = get.N(obj)
N = uint16(obj.N_ax) * uint16(obj.N_rad);
end function l_ax = get.l_ax(obj)
l_ax = 2 * obj.b_ax + double(obj.N_ax) * obj.d_Cu;
end function l_rad = get.l_rad(obj)
l_rad = obj.b_rad + double(obj.N_rad) * obj.d_Cu;
end function r_a = get.r_a(obj)
r_a = obj.r_i + obj.l_rad;
end
%% Get-Methoden für versteckte Dependent-Attribute function WK_KO_ax = get.WK_KO_ax(obj)
WK_KO_ax = [(0)(obj.l_ax)(obj.l_ax)(obj.l_ax - obj.b_ax)(obj.l_ax - obj.b_ax)(0 + obj.b_ax)(0 + obj.b_ax)(0)];
end function WK_KO_rad = get.WK_KO_rad(obj)
WK_KO_rad = [(obj.r_i)(obj.r_i)(obj.r_a)(obj.r_a)(obj.r_i + obj.b_rad)(obj.r_i + obj.b_rad)(obj.r_a)(obj.r_a)];
end function WF_KO_ax = get.WF_KO_ax(obj)
WF_KO_ax = [(0 + obj.b_ax)(obj.l_ax - obj.b_ax)(obj.l_ax - obj.b_ax)(0 + obj.b_ax)];
end function WF_KO_rad = get.WF_KO_rad(obj)
WF_KO_rad = [(obj.r_i)(obj.r_i)(obj.r_a)(obj.r_a)];
end
%% Set-Methoden function obj = set.r_i(obj, r_i) if r_i <= 0
obj.r_i = obj.r_i_std;
else
obj.r_i = r_i;
end end function obj = set.b_ax_i(obj, b_i) if b_i <= 0
obj.b_ax_i = obj.b_ax_i_std;
else
obj.b_ax_i = b_i;
end end function obj = set.l_ax_i(obj, l_ax_i) if l_ax_i <= 0
obj.l_ax_i = obj.l_ax_i_std;
else
obj.l_ax_i = l_ax_i;
end end function obj = set.l_WK_rad(obj, l_WK_rad) if l_WK_rad <= 0
obj.l_WK_rad = obj.l_WK_rad_std;
else
obj.l_WK_rad = l_WK_rad;
end end
%% Get-Methoden für Dependent-Attribute function r_i_a = get.r_i_a(obj)
r_i_a = obj.r_i + obj.b_ax_i;
end function r_a_i = get.r_a_i(obj)
r_a_i = obj.r_i_a + obj.l_WK_rad;
end function r_a = get.r_a(obj)
r_a = sqrt(obj.r_i_a^2 - obj.r_i^2 + obj.r_a_i^2);
end function b_ax_a = get.b_ax_a(obj)
b_ax_a = obj.r_a - obj.r_a_i;
end function A_ax = get.A_ax(obj)
A_ax = pi * (obj.r_i_a^2 - obj.r_i^2);
end function b_rad = get.b_rad(obj)
b_rad = obj.A_ax / (2 * pi * obj.r_m_i);
end function l_ax = get.l_ax(obj)
l_ax = obj.l_ax_i + obj.b_rad;
end function r_m_i = get.r_m_i(obj)
r_m_i = sqrt(0.5 * (obj.r_i_a^2 + obj.r_i^2));
end function l_m_ax = get.l_m_ax(obj)
l_m_ax = 0.5 * (obj.l_ax_i + obj.l_ax);
end
%% Get-Methoden für versteckte Dependent-Attribute function TK_KO_ax = get.TK_KO_ax(obj)
TK_KO_ax = [(0)(obj.l_ax)(obj.l_ax)(obj.l_ax - obj.l_ax_i)(obj.l_ax - obj.l_ax_i)(obj.l_ax)(obj.l_ax)(0)];
end function TK_KO_rad = get.TK_KO_rad(obj)
TK_KO_rad = [(obj.r_i)(obj.r_i)(obj.r_i_a)(obj.r_i_a)(obj.r_a_i)(obj.r_a_i)(obj.r_a)(obj.r_a)];
end
%% Darstellungs-Methoden function ZeichneQuerschnittPur(obj, Deltaz, gespiegelt) % Topfkern-Polygone definieren if ~gespiegelt
TK_Polygon_oben = polyshape(obj.TK_KO_ax - Deltaz, obj.TK_KO_rad);
TK_Polygon_unten = polyshape(obj.TK_KO_ax - Deltaz, -1 * obj.TK_KO_rad);
else
TK_Polygon_oben = polyshape(-1 * obj.TK_KO_ax - Deltaz, obj.TK_KO_rad);
TK_Polygon_unten = polyshape(-1 * obj.TK_KO_ax - Deltaz, -1 * obj.TK_KO_rad);
end
Die Klasse "RotSpule" soll nun jeweils ein Objekt der Klassen "RotWicklung" und "RotTopfkern" besitzen.
Die beiden Objekte besitzen Attribute, deren Wert vom Attributwert der jeweils anderen Klasse abhängig ist.
Beispiel: Der innere Radius des Wickelkörpers ist vom inneren Radius des Topfkerns abhängig.
Wie erreiche ich konsistente Werte bei den Attributen?
Mit den get-Methoden in folgendem Code erzeuge ich eine Endlosschleife:
Code:
% Rotationsspule besteht aus einer Wicklung und zwei geometrisch identischen Topfkernen mit Luftspalt
% Standard-Dicke des nichtferromagnetischen Abstandhalters zwischen Welle und Topfkernen % [b_Abtandhalter_std] = m
b_Abstandhalter_std = 1e-3;
% Standard-Länge (gesamt) beider Luftspalte in axialer Richtung % [l_Luft_ax_std] = m
l_Luft_ax_std = 1e-3;
end
%% Lese-Attribute properties(GetAccess = public, SetAccess = protected) % Name der Instanz
Name = '';
end
%% freie Attribute properties(Access = public) % Radius der Welle % [r_Welle] = m
r_Welle;
% Dicke des nichtferromagnetischen Abstandhalters zwischen Welle und Topfkernen % [b_Abtandhalter] = m
b_Abstandhalter;
% Länge (gesamt) beider Luftspalte in axialer Richtung % [l_Luft_ax] = m
l_Luft_ax;
%% Methoden methods
%% Konstruktor function obj = RotSpule(Name)
obj.Name = Name;
obj.r_Welle = obj.r_Welle_std;
obj.b_Abstandhalter = obj.b_Abstandhalter_std;
obj.l_Luft_ax = obj.l_Luft_ax_std;
obj.W = RotWicklung('Wicklung in RotSpule');
obj.TK = RotTopfkern('Topfkern in RotSpule');
end
%% Set-Methoden function obj = set.r_Welle(obj, r_Welle) if r_Welle <= 0
obj.r_Welle = obj.r_Welle_std;
else
obj.r_Welle = r_Welle;
end end function obj = set.b_Abstandhalter(obj, b_Abstandhalter) if b_Abstandhalter <= 0
obj.b_Abstandhalter = obj.b_Abstandhalter_std;
else
obj.b_Abstandhalter = b_Abstandhalter;
end end function obj = set.l_Luft_ax(obj, l_Luft_ax) if l_Luft_ax < 0
obj.l_Luft_ax = obj.l_Luft_ax_std;
else
obj.l_Luft_ax = l_Luft_ax;
end end
%% Get-Methoden function W = get.W(obj) % Aktualisierung des inneren Radius der Wicklung
obj.W.r_i = obj.TK.r_i_a;
% Ausgabe
W = obj.W;
end function TK = get.TK(obj) % Aktualisierung des inneren Radius der Topfkerne
obj.TK.r_i = obj.r_Welle + obj.b_Abstandhalter;
% Aktualisierung der inneren axialen Länge der Topfkerne
obj.TK.l_ax_i = 0.5 * obj.W.l_ax - 0.25 * obj.l_Luft_ax;
%% Get-Methoden für Dependent-Attribute function l_ax = get.l_ax(obj)
l_ax = 2 * obj.TK.l_ax + 0.5 * obj.l_Luft_ax;
end function r_a = get.r_a(obj)
r_a = obj.TK.r_a;
end end end
Hinweis 2: Ich bin Elektroingenieur und kein Informatiker. Die Grundlagen der OOP (Attribute, Methoden, Vererbung) kenne ich, aber bei doppelten Pointern oder Begriffen wie "Handles" endet meine Vorstellungskraft schnell. Daher bitte ich ggf. um etwas Nachsicht.
Die beiden Objekte besitzen Attribute, deren Wert vom Attributwert der jeweils anderen Klasse abhängig ist.
Beispiel: Der innere Radius des Wickelkörpers ist vom inneren Radius des Topfkerns abhängig.
Du verwendest Attribute hier wohl in anderem Kontext als normal in OOP?
Ich würde das im Konstruktor bzw. in der set-Methode dieser neuen Properties regeln. Dann muss ein rotWicklung einen inneren Radius haben, der zum rotTopfkern passt und umgekehrt.
Eine wechselseitige Abhängigkeit ist mit Dependent nicht umsetzbar.
Grüße,
Harald
_________________
1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Code Analyzer has identified a reference to a second property within a set method for a non-Dependent property. If the set method of one property accesses another non-dependent property, initialization of the property can fail because MATLAB does not guarantee the initialization order.
Harald hat Folgendes geschrieben:
Du verwendest Attribute hier wohl in anderem Kontext als normal in OOP?
Ich habe noch nicht soviel Erfahrung in der Anwendung von OOP - wie ist "normal" in diesem Zusammenhang zu verstehen?
Edit/Zusatzfrage: Wird die set-Methode bereits aufgerufen, wenn ein Attribut im Konstruktor einen Wert zugewiesen bekommt oder nur bei späteren Schreibzugriff auf das Attribut?
Edit 2/Antwort auf Zusatzfrage: Ja, set-Methode wird auch beim Konstruktor-Aufruf ausgeführt.
1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
classdef RotSpule
%% Lese-Attribute properties(GetAccess = public, SetAccess = protected) % Name der Instanz
Name(1,:)char = '';
end
%% freie Attribute properties(Access = public) % Objekt/Instanz der Klasse "RotWicklung"
W(1,1) RotWicklung = RotWicklung('Wicklung in RotSpule');
% Objekt/Instanz der Klasse "RotTopfkern"
TK(1,1) RotTopfkern = RotTopfkern('Topfkern in RotSpule');
% Radius der Welle % [r_Welle] = m
r_Welle(1,1)double{mustBeNonnegative} = 2e-3;
% Dicke des nichtferromagnetischen Abstandhalters zwischen Welle und Topfkernen % [b_Abtandhalter] = m
b_Abstandhalter(1,1)double{mustBeNonnegative} = 1e-3;
% Länge (gesamt) beider Luftspalte in axialer Richtung % [l_Luft_ax] = m
l_Luft_ax(1,1)double{mustBeNonnegative} = 1e-3;
end
Wenn ich innerhalb der Methode "AktualisiereAttrRad" per disp-Befehl die Attributwerte von W und TK anzeigen lasse, sind sie richtig.
Nach Ausführen der Methode, also quasi "außerhalb", sind dann auf einmal wieder die Standardwerte vorhanden.
Eine Alternative zur set-Methode kann sein, bei der Eigenschaft Access = private zu setzen und für den Zugriff von außen eine Methode update_r_Welle zu schreiben, die quasi denselben Inhalt hat.
Zur momentanen Frage: ein Problem dürfte sein, dass du obj nicht zurückgibst.
obj = ... (sowohl in der Deklaration als auch im Aufruf)
Grüße,
Harald
_________________
1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
das ist nur der Fall, wenn du von handle vererbst.
Solange du das nicht machst, immer obj = bei Deklaration oder Aufruf von Methoden, die das Objekt verändern.
Grüße,
Harald
_________________
1.) Ask MATLAB Documentation
2.) Search gomatlab.de, google.de or MATLAB Answers
3.) Ask Technical Support of MathWorks
4.) Go mad, your problem is unsolvable ;)
Einstellungen und Berechtigungen
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.