Verfasst am: 10.01.2008, 14:39
Titel: plot update Problem
Hallo,
ich habe gerade ein Problem damit einen Plot, welcher ein Bild überlagert, bevor er neu gezeichnet wird, erst zu löschen.
Hört sich kompleziert an, ist es aber eigendlich gar nicht.
Also, ich habe mir ein Matlab file erstelt (Datei.m) und binde es in Simulink nach dem Muster "SFUNTMPL" ein.
Unter "mdlInitializeSizes" erzeuge ich mit
img = imread('Bild.png');
imshow(img)
ein Bild, sozusagen als Grundlage.
Unter "mdlUpdate(t,x,u)" erzeuge ich eine zweite durchsichtige Achse auf der mein Plot angezeigt wird:
axes('units',get(gca,'units'),'position',position_tacho,'color','none','visible','off')
axis([-1 1 -1 1])
h = line(NaN,NaN,'linewidth',3,'Color',[1 0 0]);
set(h,'xdata',[0 cos(u*pi/180)],'ydata',[0 sin(u*pi/180)])
Als Eingang in Simulink habe ich eine Sinuswelle genommen. Funktioniert auch wunderbar, das Problem ist allerdings, das er die Linie zeichnet, und wenn er das nächste mal Upadate aufruft, zeichnet er zwar die neue Linie, läßt aber die Alte einfach stehen.
Es funktioniert halb, wenn ich
drawnow;
cla;
unter das set... schreibe, allerdings zeichnet er die Linie dann halt nur ganz kurz und nimmt sie dann sofort wieder weg. Anderherum wäre mir halt lieber, sprich erst löschen, dann neu zeichnen. Dann würde die Linie erstens nicht so flackern und ausserdem nach dem Simulations zyklus auch stehen bleiben. Aber das macht er nicht
Ich hab auch schon ein wenig mit dem Befehl "refresh" rumgespielt, aber anscheinend verstehe ich die Syntax des Befehls nicht.
wenn ich es richtig verstehe, erzeugst Du in jedem Aufruf von mdlUpdate eine neue unsichtbare axes, richtig? Man kann das Problem umgehen, indem man eine unsichtbare axes direkt nach dem imshow-Befehl erzeugt und dann in mdlUpdate nur jeweils h=line(...) macht. Wenn man nicht irgendwo hold on gesetzt hat, sollte dann ein neuer plot den alten ersetzen.
Hallo Bijick,
erstmal Danke für Deine Antwort, aber leider funktioniert das so nicht, sprich ist genau das selbe verhalten wie vorher. Ergibt halt nen gefüllten Halbkreis. Also nichts mit ersetzen, ist eher ein Erweitern.
Ausserdem wäre diese Möglichkeit eh nicht so richtig praktikabel in meinem Programm, da ich noch weitere Plots über dem Bild habe, die natürlich alle gleich heißen
Das wäre auch noch so ein Ding wie man die vielleicht von einander separieren könnte, ich hab schon versucht aus:
axes('units',get(gca,'units'),'position', position_gang,'color','none','visible','off')
zu machen, aber da meckert er immer rum. Eine Erklärung hab ich auch noch nicht zu "axes" gefunden, bis auf die Hilfe, die keine ist. Ich meine da soll 'PropertyName' rein... Objekt Name, genau, ich will ein Objekt Names PLOT_EINS erstellen mit den Axes Handel von Unites->sprich meinem Bild. Geht aber nicht...
ich versuche es nochmal. Ich bin nicht sicher, ob Du den axes-Befehl aus mdlUpdate gelöscht hast. Das hatte ich nämlich nicht ausdrücklich geschrieben, aber gemeint. Also:
Und noch etwas zum Axes-Befehl. Man gibt da immer Paare ein: Eine Eigenschaft und den Wert dieser Eigenschaft, so wie Größe, 180 cm, Gewicht, 79 kg, usw.
Auf den konkreten Fall bezogen heißt das, Du setzt die Einheiten (units) auf diejenigen der vorigen axes (get(gca,'units')), die Position auf position_tacho, die Farbe auf "keine Farbe" und die Sichtbarkeit auf "aus".
Um der axes einen "Namen" zuzuweisen, kannst Du schreiben
Später kannst Du sie mit axes(axes_1) wieder aktivieren. Der Name der Grafik in der axes ist h (wegen h=line(...)). Man kann diese Grafik auch mit delete(h) wieder löschen. Ist es jetzt etwas klarer? Sonst frag einfach weiter.
Herzliche Grüße
Bijick
_________________
Hallo Bijick,
hier an der FH ist gerade Klausuren Runde, und das Projekt hier ist eher ne Freizeit und Ablenkungs Geschichte von mir, von daher sorry wenn ich gestern nicht mehr geantwortet habe.
So nach langem hin und her hat es nun doch funktioniert, aber es bleibt trotzdem noch ein Problem
Ich wollte es ja nicht glauben, aber er zeichnet wohl tatsächlich bei jedem Update Aufruf einen neuen Plot, wenn ich den axes Befehl unter Update habe. Mit dem Axes Befehl in der Initialisierung und:
cla;
h = line(NaN,NaN,'linewidth',3,'Color',[1 0 0]);
set(h,'xdata',[0 cos(u*pi/180)],'ydata',[0 sin(u*pi/180)])
drawnow
in Update funktioniert es.
Problem ist nur das ich halt mehrere Axes über dem Bild habe. Ich müßte ihm jetzt halt beibringen wie er zwischen den verschiedenen Axes hin und her springen kann.
Hab schon probiert in der Initalisierung:
Tacho_Position=axes('units',get(gca,'units'),...
und dann halt bei Update:
axes(Tacho_Position);
cla;
h = line...
aber da sagt er, das er "Tacho_Position" nicht kennt (Undefined function or variable 'Tacho_Position')
hmm, aber die Lösung kann nicht mehr weit sein....
Wenn ich es richtig verstanden habe, ist mdlUpdate eine Function (function). Da Funktionen lokale Variablenräume haben, kennen sie nur die Variablen, die dort erzeugt werden oder die ihnen übergeben werden. Du könntest also mdlUpdate die Variable Tacho_Position übergeben:
hm, also das mit den lokalen Variablen Räumen sehe ich genauso, auch stimmt wohl das er die Übergabe nicht gebacken bekommt.
Das ich jetzt einfach eine Variable übergebe, geht leider nicht. Da ist Matlab schon sehr restriktiv mit seinen Übergabe Parametern.
switch flag,
%%%%%%%%%%%%%%%%%%
% Initialization %
%%%%%%%%%%%%%%%%%%
case 0,
[sys,x0,str,ts]=mdlInitializeSizes;
%%%%%%%%%%%%%%%
% Derivatives %
%%%%%%%%%%%%%%%
case 1,
sys=mdlDerivatives(t,x,u);
%%%%%%%%%%
% Update %
%%%%%%%%%%
case 2,
sys=mdlUpdate(t,x,u);
Wobei t immer für Zeit, x für irgendwas, und u der Übergabe Vektor ist.
Ich glaube nicht, das ich im Übergabe Vektor (der als Long ausgelegt ist) eine Axes Deklaration an Update übergeben kann.
Der Aufruf, im übrigen, geschieht auch vollständig automatisch durch das flag, darauf habe ich also auch keinen Einfluß.
Das ist halt, wie Eingangs schon erwähnt, das Template "SFUNTMPL" welches unter Simulink->UserDefinedFunctions->S-Funktion bzw. dort unter Examples->Templates zu finden ist.
ach ja, das hatte ich schon wieder vergessen. Wenn Du u frei belegen kannst, ist es aber kein Problem, die Variable Tacho_Position zu übergeben: das ist nämlich eine einfache double-Zahl. Wenn u ein numerischer Vektor ist, kannst Du also Tacho_Position einfach anhängen.
So, ne geht nicht, Variable u steht für einen Eingang im S-Function Block, Variablen übergabe von der Initalisierung zu Update ist wohl so nicht vorgesehen, zu mindest wüßte ich nicht wie.
Es muß doch auch anders zu lösen sein eine Axes Deklaration fest an einen Plot zu binden. Ich hab gerad schon versucht alles in eine Achse zu legen, spätestens bei der Positionierung der anderen Bilder brauche ich aber wieder andere Achsen, und damit merkt er sich nicht was er im vorherigen Aufruf von Update in den Plot gezeichnet hat und macht einfach einen neuen auf.
Was fehlt ist halt eine feste und dauerhafte Erzeugung mehrer Plots, die ich dann einfach bei jedem Aufruf von Update mit neuen Werten füttern kann.
Ich bekomme es nicht vernünftig hin. Hier mal der abgespeckte, jedoch voll lauffähige Code der das Problem hat.
Vielleicht wird dann einiges klarer wo die Probleme auftauchen...
Und nochmal ich, mir ist gerade noch was aufgefallen. Das Beispiel oben ist zwar gut, führt aber wahrscheinlich zu der Antwort:
Dann schreib eine Axes Deklaration in die Initialisierung und Plotte dann beide Graphen rein.
Das würde tatsächlich in diesem Beispiel gehen, allerdings werden ja noch zusätzlich Bilder mit eingeblendet und die könnte ich dann nicht mehr positionieren ohne neue Axen aufzumachen...
Naja, gute Nacht erstmal
Ralf
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.