WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Simulink - In Echtzeit Maximalwerte zwischenspeichern

 

BlackTiger
Forum-Anfänger

Forum-Anfänger


Beiträge: 32
Anmeldedatum: 19.06.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 27.03.2019, 12:44     Titel: Simulink - In Echtzeit Maximalwerte zwischenspeichern
  Antworten mit Zitat      
Hallo zusammen,
habe ein kleines Problemchen und würde um euren Rat bitten.

ich habe ein Signal (siehe Anhang) und möchte jedesmal wenn ein Sprung stattfindet den y-Wert dazu zwischenspeichern. Nach insgesamt acht "Sprüngen" möchte ich den betragsmäßig Größten Wert zwischenspeichern.
Mein Zwischenspeicher soll eine Art Ringspeicher sein und soll immer die letzten zehn Maximalwerte speichern.

In Matlab stelle ich mir das Ganze relativ einfach vor, indem ich beispielsweise ein Index mitlaufen lasse und mit Hilfe dessen ich den aktuellen Wert mit Vorherigen vergleichen kann. Aber in Simulink, erweist es sich meiner Meinung nach etwas schwieriger.

Mein Konkretes Problem hierzu ist:
-Wie erkenne ich im Matlab-Function Block einen Sprung und wie kann ich es zwischenspeichern? (Echtzeit)
- Wie erkenne ich anschließend den betragsmäßig größten Wert in diesem Vektor?

Würd mich sehr freuen, wenn mir jemand auf die Sprünge helfen könnte!

Besten Dank schon mal

1.PNG
 Beschreibung:

Download
 Dateiname:  1.PNG
 Dateigröße:  83.23 KB
 Heruntergeladen:  338 mal
Private Nachricht senden Benutzer-Profile anzeigen


fabianT
Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 84
Anmeldedatum: 31.10.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 27.03.2019, 14:48     Titel:
  Antworten mit Zitat      
Hallo,

der MATLAB Function Block ist an sich schon der richtige Weg.

Hier gibt es jedoch keine Zustände. Als Workaround verwendet man persistent Variablen. Ein Unit Delay Verhalten kannst du zB so programmieren:

function y = fcn(u)

persistent prevValue;
if isempty(prevValue)
prevValue = 0; % init
end

%detect change
if prevValue ~= u
% change detected
end

% Output
y = prevValue;

% Update
prevValue = u;


Den Sprung könnte man erkennen, wenn der aktuelle Wert sich vom vorherigen unterscheidet, siehe oben...

Der Buffer funktioniert ähnlich, mit etwas mehr Aufwand.

Der Buffer ist ja letztendlich nur ein Array, das ständig die Wert ändert. Mit max() bekommst du den größten Wert. Die Buffer Größe kannst du zB über eine Maske vorgeben.

Viele Grüße
Fabian
Private Nachricht senden Benutzer-Profile anzeigen
 
BlackTiger
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 32
Anmeldedatum: 19.06.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 27.03.2019, 15:59     Titel:
  Antworten mit Zitat      
Top!! Schon mal vielen vielen Dank! Kann damit echt viel anfangen!

Zum Buffer:

Den Buffer würde ich dann entsprechend auch mit einem persistent-Array realsieren oder?
Auf deinen Vorlschlag drauf aufbauend, habe ich nun den Array ergänzt. Stellt sich für mich nun die Frage, wie ich den nach dem FiFo-Prinzip fülle. Ich kann ja schließlich kein Index benutzen.
In meinem Beispiel unten erhalte ich wieder den exakten Verlauf.


"Die Buffer Größe kannst du zB über eine Maske vorgeben" -> Würd ich ja in meinem Fall während der Deklaration meines Arrays machen (siehe persistent maxValue)





function y = fcn(u)

persistent prevValue; %Eingangswert
if isempty(prevValue)
prevValue = 0; % init
end

persistent maxValue %Maximalwert
if isempty(maxValue)
maxValue = zeros(10,1); %init
end

%detect change
if prevValue ~= u
maxValue = u;
end

% Output
y = maxValue

% Update
prevValue = u;
Private Nachricht senden Benutzer-Profile anzeigen
 
fabianT
Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 84
Anmeldedatum: 31.10.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 27.03.2019, 16:13     Titel:
  Antworten mit Zitat      
Hi,

wieso kannst du denn keinen Index verwenden? Du könntest wieder eine persistent Variable nehmen, diese hochzählen lassen und den aktuellen Inputwert in den Buffer schreiben...

So ähnlich könnte man es machen:

persistent prevValue;
persistent buffer;
persistent bufferIndex;

if isempty(prevValue)
prevValue = 0; % init
buffer = zeros(BufferLength, 1, 'like', u);
bufferIndex = int32(0);
end

%detect change
if prevValue ~= u
% fill buffer
bufferIndex = bitand(bufferIndex+1, BufferLength-1);
buffer(bufferIndex+1) = u;
end

% Output
y = max(abs(buffer));
bufferOut = buffer;

% Update
prevValue = u;


Viele Grüße
Fabian
Private Nachricht senden Benutzer-Profile anzeigen
 
BlackTiger
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 32
Anmeldedatum: 19.06.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 27.03.2019, 18:20     Titel:
  Antworten mit Zitat      
Ich habe deinen Vorschlag leicht abgeändert (weil ich nicht wusste wie BufferLength zu deklarieren ist), erhalte jedoch ne Fehlermeldung.

Die Idee dahinter war, nachdem mein Buffer mit der vordefinierten Länge von 10 Einträgen vollständig befüllt ist, wird der betragsmäßig größte Eintrag ausgegeben.

Aber so wie ich es verstanden habe, kommt das Programm nicht so gut damit klar, dass mein Ausgabewert unter der If - Hirarchie ist.



function y = fcn(u)

%%%%%%%%%%% - Peristent Variables - %%%%%%%%%

persistent prevValue; %Eingangswert
if isempty(prevValue)
prevValue = 0; % init
end

persistent buffer %Maximalwert
if isempty(buffer)
buffer = zeros(10,1); %init
end

persistent bufferIndex % Index
if isempty(bufferIndex)
bufferIndex = 1;
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%detect change
if prevValue ~= u
buffer(bufferIndex) = u;
bufferIndex = bufferIndex+1;

if bufferIndex == 10
bufferIndex = 1;

% Output
y = max(abs(buffer)); <-- womöglich ist der Fehler hier

end
end


% Update
prevValue = u;



Erhalte folgende Fehlermeldung




Output argument 'y' is not assigned on some execution paths.

Function 'Subsystem2/Subsystem7/MATLAB Function' (#329.9.10), line 1, column 10:
"y"
Launch diagnostic report.

Component:MATLAB Function | Category:Coder error

Errors occurred during parsing of MATLAB function 'Dateienpfad'

Component:MATLAB Function | Category:Coder error

Errors occurred during parsing of MATLAB function
'Dateienpfad'
Private Nachricht senden Benutzer-Profile anzeigen
 
fabianT
Forum-Fortgeschrittener

Forum-Fortgeschrittener


Beiträge: 84
Anmeldedatum: 31.10.18
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 28.03.2019, 10:18     Titel:
  Antworten mit Zitat      
Hi,

BufferLength war bei mir ein Parameter in MATLAB Function block. Habe dann im Workspace den Wert dafür angelegt. Für y musste ich noch "variable size signal" aktivieren und die Size auf BufferLength setzen...

Ja, das Problem bei deinem Code ist, dass y nicht immer ausgeführt wird. Das ist so nicht erlaubt.

Viele Grüße
Fabian
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

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
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2024 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

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.