Verfasst am: 13.08.2018, 10:19
Titel: Gleitende Berechnung des Durchschnitts einer Spalte
Hallo liebe Community,
nach langem Zögern und vieler Stunden ohne nennenswerter Fortschritte muss ich Euch nun doch um Hilfe fragen.
Worum geht es?
Ich habe ein Lastprofil gegeben (3260x2 double) indem jede 0,5 Sekunden ein Leistungswert angegeben ist. Die erste Spalte besteht also aus Zeitpunkten 0 0.5 1 1.5 usw. während die zweite Spalte aus Leistungswerten besteht.
Mein Ziel ist es einen kleinen Code zu schreiben, der iterativ für jeden Zeitpunkt den Durschnittswert der Leistung der letzten 5 Sekunden (also 10 Werte) berechnet und mit dem aktuellen Wert (i-te Stelle der zweiten Spalte) vergleicht.
Je nachdem ob die Differenz größer und kleiner Null ist, soll dann ein weiterer Verbraucher HVH_neu (auch 3260x2 double) für diesen Zeitpunkt zu Null gesetzt werden, um das Lastprofil zu glätten.
Folgenden Code habe ich bereits geschrieben:
Code:
function P = fcn(P) % Berechnung Durchschnittsleistung der letzten 5 sec - aktuelle Leistung for a = 0:1:size(P_neu)
i = a;
sum = 0;
for i = i-10:1:i
sum = sum + P_neu(i);
end end
average(i) = sum/10;
Leistung = average(i) - P_neu(i); %Durchschnitt - aktuelle Leistung
if Leistung < 0% aktuelle Leistung größer als Durchschnitt
HVH_neu(i:,2) = 0; % HVH aus elseif Leistung > 0% aktuelle Leistung kleiner als Durchschnitt
HVH_neu(i:,2) = HVH_neu(i:,2); % HVH unverändert end
P_neu besteht nur aus den Leistungswerten.
Folgende Fehlermeldungen entstehen, die ich nicht nachvollziehen kann:
Für average: "Code generation requires variable 'average' to be fully defined before subscripting it." Dabei habe ich diesen mit der zeros-Funktion zu einem 3260x1 gemacht.
Des Weiteren stimmt bei HVH_neu(i:,2) wohl die Syntax nicht... dabei möchte ich damit auf den i-ten Wert der zweiten Spalte eingehen.
Die for-Schleifen sind mit einem Kommilitonen entstanden, der schon ein bisschen Erfahrung mit Matlab hat. Fällt hier jemandem ein Fehler auf?
Bin über jeden Input sehr dankbar!
Viele Grüße
Philip
_________________
Um gut zu werden, musst Du zuerst annehmen, dass Du schlecht bist.
die Fehlermeldung lässt erahnen, dass du die Funktion als MATLAB-Function in Simulink verwendest. Das wäre eine wichtige Information.
Zitat:
Dabei habe ich diesen mit der zeros-Funktion zu einem 3260x1 gemacht.
Wo? Das muss in der MATLAB-Function passieren.
Für gleitende Mittelwerte gibt es auch die Funktion movmean.
sum würde ich als Variablennamen vermeiden, da damit die (häufig verwendete) Funktion sum überlagert wird.
HVH_neu(i:,2) = 0; ist ein Syntaxfehler. Entweder die komplette Spalte ohne i oder das i-te Element ohne :
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 ;)
Tatsächlich handelt es sich um eine Matlab-Function, die in Simulink verwendet wird.
Ich bin mittlerweile schon einen Schritt weiter (das denke ich zumindest ):
Für folgenden Code bekomme ich Ausgabewerte:
Code:
% Glättung von Lastspitzen durch momentane Regelstrategie
P_neu = randi(10,50,1);
HVH_neu = randi(10,50,1);
% Berechnung Durchschnittsleistung der letzten 5 sec - aktuelle Leistung for i = 1:size(P_neu,1)
Average(i) = (sum(P_neu(max(1,i-9):i)))/(i-max(1,i-10)+1);
end Power = Average - P_neu;
% Algorithmus for i = 1:size(P_neu,1) ifPower(i) < 0% aktuelle Leistung über Durchschnitt
HVH_neu(i,1) = 0; % Heizung komplett aus end end
Das einzige Problem ist hier aber, dass es bei den Variablen P_neu und HVH_neu um Nx1 double handelt, ich aber wegen dem Simulink "From Workspace" Block einen Vektor mit mindestens zwei Spalten also Nx2 benötige (1. Spalte Zeit, 2. Spalte die Leistungswerte).
Die Adaption des Codes oben haut aber noch nicht hin.
Das wäre mein Ansatz:
Code:
function P_neu = fcn(P_neu) % Glättung von Lastspitzen durch momentane Regelstrategie
coder.extrinsic('evalin');
HVH_neu = evalin('Workspace', 'HVH_neu');
P_neu = evalin('Workspace', 'P_neu');
Average = zeros(3260,1);
% Berechnung Durchschnittsleistung der letzten 5 sec - aktuelle Leistung for i = 1:size(P_neu,2)
Average(i) = (sum(P_neu(max(2,i-9):i)))/(i-max(2,i-10)+1);
end Power = Average - P_neu;
% Algorithmus for i = 1:size(P_neu,2) ifPower(i) < 0% aktuelle Leistung über Durchschnitt
HVH_neu(i,2) = 0; % Heizung komplett aus end end
das evalin ist unnötig. Du kannst in einer MATLAB-Function Parameter angeben.
Gut möglich, dass sich dadurch die Fehlermeldung auch löst.
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 ;)
Tatsächlich konnte ich diese mögliche Fehlerstelle jetzt komplett eliminieren.
Folgender Code steht mittlerweile, wobei ich jetzt am letzten (wohl auch einfachen) Schritt stehe:
Code:
S = load('001 Fahrt.mat');
U = S.eGolf.Spannungen.Spannung_Batteriepack(1:5:end,:);
I = S.eGolf.Stroeme.Strom_Batterie(1:5:end,:);
I_HVH = S.eGolf.Stroeme.Strom_Nebenverbraucher_Ladegerae(1:5:end,:);
P = U; % Bringe P auf die Größe von U
P_HVH = U; % Bringe P_HVH auf die Größe von U
P(:,2) = U(:,2).*I(:,2); % Berechnung P
P_HVH(:,2) = U(:,2).*I_HVH(:,2); % Berechnung P_HVH Power = P(:,2);
x=P(:,2);
for i = (10:1:3260)'
y=tsmovavg(x,'s',10,1); % Berechnung des Durchschnitts end Power(i) = y(i) - P(i,2);
for i = (10:1:3260)'
ifPower(i) < 0% aktuelle Leistung größer als Durchschnitt
P_HVH(i,2) = - P_HVH(i,2); % Heizung ausgeschaltet end end
Ich habe eine 3260x1 double Variable 'Power', die mit positiven und negativen Werten gefüllt ist. 'P_HVH' hat zwei Spalten 3260x2 double, wobei nur die zweite Spalte von Relevanz für mich ist und nur positive Werte enthält.
Ich möchte jetzt für jeden negativen i-ten Wert der Variable Power den i-ten Wert der zweiten Spalte von P_HVH negativ setzen.
Mit obiger Schleife bleibt die Variable P_HVH aber unverändert.
Was läuft falsch? Kann es mir nicht erklären, da das eigentlich nicht schwer sein darf.
Vielleicht habt ihr ja eine Idee.
Danke und viele Grüße
Philip
_________________
Um gut zu werden, musst Du zuerst annehmen, dass Du schlecht bist.
Debuggen hilft meist. Warum transponierst du denn den Vektor bei der for-Schleife?? Aus der Doku:
Zitat:
valArray — Create a column vector, index, from subsequent columns of array valArray on each iteration. For example, on the first iteration, index = valArray(:,1). The loop executes a maximum of n times, where n is the number of columns of valArray, given by numel(valArray(1,:)).
Ist doch wohl kaum deine Absicht?
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 ;)
den Vektor habe ich transponiert, da mir i im Workspace dadurch auf den Wert von 3260 gelegt wurde und ich davon ausgegangen bin einen Vektor erwarten zu können. Habe mir jedoch jetzt auch mal das Ergebnis davon angesehen und nun ja.. es ist richtig
Danke!
Viele Grüße
Philip
_________________
Um gut zu werden, musst Du zuerst annehmen, dass Du schlecht bist.
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.