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

1. Schleife bis Grenze, dann Wechsel in 2. Schleife

 

Ole_85

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.05.2016, 16:28     Titel: 1. Schleife bis Grenze, dann Wechsel in 2. Schleife
  Antworten mit Zitat      
Hallo zusammen,

ich will den Ladezustand einer Batterie über Matlab nachbilden. Die Batterie ist zu Beginn voll geladen und wird dann Schrittweise entladen. Wenn der Ladezustand 20% erreicht hat, soll die Batterie geladen werden bis zu einem Ladezustand von 80%, dann soll sie wieder entladen werden, also immer abwechselnd bis ans Ende von k.

Jetzt weiß ich leider nicht, wie ich dieses Abwechselnde programmieren soll. Zuerst dachte ich an if-Bedingungen, dass ich quasi sage, wenn der SOC abnehmend und über 20% dann mache das, wenn zunehmend und unter 80% dann das (SOC = Ladezustand), also wie folgt:

Code:


for k=1:n
%% hier sind noch weitere Teile des Modells, im Folgenden nur ein kleiner Ausschnitt. Der neue Wert des Ladezustands wird später im Modell berechnet.

if  SOC(k-1)>SOC(k)>=0.2;                                          
    P(k,1)=P_MF+P_elektr(k);                
    t_entladen(k,1)=(t_entladen(k)+1)*Zeit;
    t_laden(k,1)=0;
   
elseif SOC(k-1)<SOC(k)<=0.8;
    P(k,1)=P_laden;
    t_entladen(k,1)=0;
    t_laden(k,1)=(t_laden(k)+1)*Zeit;
 
end
end

 


Das klappt aber nicht wie gewünscht und zumdem ist das SOC(k-1) sehr unschön, wenn ich ab k=1 modelliere, da es ja dann zu einer Fehlermeldung kommt.
Beim Recherchieren bin ich auf die Option von while-Schleifen gekommen. Leider kenne ich mich mit while-Schleifen noch gar nicht aus. Kann mir da jemand helfen? Oder gibt es vielleicht noch eine super Lösung ohne Schleifen? Ich habe insgesamt sehr viele Daten und das Modell ist sowieso schon sehr langsam.

Ich freue mich über jede Idee. Vielen lieben Dank!!!


Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 10.05.2016, 16:47     Titel:
  Antworten mit Zitat      
Hallo,

zunächst ein Problem: Anweisungen wie if SOC(k-1)>SOC(k)>=0.2 werden von links nach rechts abgearbeitet, d.h. 0 oder 1 wird mit 0.2 verglichen. Das ist ziemlich sicher nicht das, was du möchtest.
Im Editor ist - neben weiteren Warnungen - dieser Codeteil auch orange unterlegt.
Schreiben solltest du:
Code:
if SOC(k)>=0.2 && SOC(k-1)> SOC(k)


Vorteil: wenn SOC(1) >= 0.2 ist, wird der zweite Teil aufgrund des Short-Circuit-Operators && gar nicht mehr abgearbeitet, d.h. das Problem mit k=1 löst sich so automatisch.

Aufpassen wirst du insofern müssen, dass du den neuen Ladezustand ja abhängig vom alten berechnen musst unter Verwendung der Information, ob aufgeladen oder entladen wird. Das muss also in die for-Schleife hinein.

Zitat:
Das klappt aber nicht wie gewünscht

Eine solche Aussage ist wenig aussagekräftig, da wir bei nicht lauffähigem Code ja nicht wissen können, was das Ergebnis ist - geschweige denn inwiefern es von den Erwartungen abweicht.

Bitte also mal den Vorschlag von oben umsetzen und dann, falls es weiterhin Probleme gibt, diese genauer erläutern.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Ole_85

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.05.2016, 17:51     Titel:
  Antworten mit Zitat      
Hallo Harald,

danke für deine super schnelle Antwort. Ich habe deinen Vorschlag mit den SOC umgesetzt. Allerdings kommt trotzdem die folgende Fehlermeldung
Code:
Attempted to access SOC(0); index must be a positive integer or logical.

Das liegt wohl am elseif. Das habe ich zu
Code:
elseif SOC(k)<=SOC_max && SOC(k-1)<SOC(k)

umgeschrieben

Damit diese Fehlermeldung erstmal nicht mein Hinderungsgrund ist, habe die Schleife jetzt von 2 an laufen lassen, das ist auch in Ordnung.

Zitat:
Aufpassen wirst du insofern müssen, dass du den neuen Ladezustand ja abhängig vom alten berechnen musst unter Verwendung der Information, ob aufgeladen oder entladen wird. Das muss also in die for-Schleife hinein.


Ich denke genau das ist mein Problem. Ich berechne meinen Ladezustand wie folgt:

Code:

I(k,1)=P(k)/U(k);
SOC(k,1)=SOC(k-1)+1/C(k)*I(k)*t;    
 


Die Leistung ist je nach Laden oder Entladen positiv oder negativ. Dementsprechend ergibt sich auch das Vorzeichen des Stroms und damit dachte ich, dass der SOC beim Laden größer wird und beim Entladen geringer. Was ich bisher noch nicht schaffe, ist den Wechsel zwischen laden und entladen. Aktuell entlädt mein Modell bis in den negativen SOC-Bereich, obwohl ja dann eigentlich nicht mehr die if-Bedingungen erfüllt ist, da SOC<0.2

Hat noch jemand einen Tipp, wie ich diesen Wechsel schaffe?

Vielen herzlich Dank!
 
Mmmartina
Forum-Meister

Forum-Meister


Beiträge: 745
Anmeldedatum: 30.10.12
Wohnort: hier
Version: R2020a
     Beitrag Verfasst am: 10.05.2016, 19:37     Titel:
  Antworten mit Zitat      
Matlab indexiert ab 1 - du versuchst aber mit k-1 auf des nullte element zuzugreifen.
_________________

LG
Martina

"Wenn wir bedenken, daß wir alle verrückt sind, ist das Leben erklärt." (Mark Twain))
Private Nachricht senden Benutzer-Profile anzeigen
 
Ole_85

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 10.05.2016, 19:48     Titel:
  Antworten mit Zitat      
Danke für die Antwort. Wie bereits im vorherigen Beitrag geschrieben, lasse ich die Schleife aktuell ab k=2 durchlaufen, sodass die Fehlermeldung nicht mehr erscheint.

Meine Problem bzgl. des Wechsels zwischen Laden und Entladen habe ich leider noch nicht gelöst.
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 10.05.2016, 20:26     Titel:
  Antworten mit Zitat      
Hallo,

ich hatte einen Denkfehler. Bei A && B wird B dann nicht ausgeführt, wenn A nicht erfüllt ist - denn dann ist das Ergebnis bereits klar.

Zum Problem von Laden und Entladen habe ich dir ja schon etwas geschrieben.
Als Pseudo-Code:

Code:
for I = 2:n-1 % Anzahl Zeitschritte
if (anhand bisheriger SOC testen, ob geladen werden soll)
laden(I) = 1;
SOC(I+1) = % Berechnung neues SOC
elseif (anhand bisheriger SOC testen, ob geladen werden soll)
laden(I) = 0;
SOC(I+1) = % andere Berechnung neues SOC
end


Was soll eigentlich passieren, wenn keine der Bedingungen erfüllt ist?

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Ole_85

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 11.05.2016, 15:04     Titel:
  Antworten mit Zitat      
Hallo,

Harald, danke für deine erneute Antwort. Ich habe mir das ganze jetzt zurecht gebastelt, allerdings mit unglaublich vielen if-Bedingungen und ziemlich unelegant. Vielleicht hat ja jemand eine Idee, wie ich diesen Prozess abkürzen kann? Das wäre toll!

Code:


for k= 2:n-1 % Anzahl Zeitschritte

I(k,1)=P(k)/U(k);
C(k,1)=C_0*(1-(1-E)*(1-SH(k)));
SOC(k,1)=SOC(k-1)+1/C(k)*I(k)*t;

% Hier wird geprüft ob die Batterie bis zum max. SOC geladen bzw. bis zum minimalen entladen ist, wenn ja, wird auf entladen bzw. laden umgestellt (Anhand der Leistung P_B, diese geht in den Strom I ein, dieser in den Ladezustand SOC)
   
if SOC(k)<=SOC_min
    SOC(k)=SOC_min;
    P_B(k+1)=P_lad;
    t_ent(k,1)=(t_ent(k-1)+1)*dt;
   
elseif SOC(k)>=SOC_max
       SOC(k)=SOC_max;
       P_B(k+1)=-P_MF-P_el(k);
       t_lad(k,1)=(t_lad(k-1)+1)*dt;
       P_DG(k,1)=0;
end

% Hier wird geladen oder entladen
if SOC(k-1)<SOC(k)
   P_B(k+1)=P_lad;
   t_lad(k,1)=(t_lad(k-1)+1)*dt;
   t_DG(k,1)=t_DG(k)+1;

elseif SOC(k-1)>SOC(k);
     P_B(k+1)=-P_MF-P_el(k);
     t_lad(k,1)=(t_lad(k-1)+1)*dt;
     P_DG(k,1)=0;
end
 
 


Vielen lieben Dank.
Harald, ich denke, damit hat sich auch die Frage geklärt, was gemacht werden soll, wenn die beiden Beziehungen nicht erfüllt sind?!

VG und Danke! Ole
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 11.05.2016, 15:26     Titel:
  Antworten mit Zitat      
Hallo,

Sollte es im ersten Codeteil t_lad statt t_ent heißen?

Zitat:
ich denke, damit hat sich auch die Frage geklärt, was gemacht werden soll, wenn die beiden Beziehungen nicht erfüllt sind?!

Jein. Wenn SOC(k) zwischen SOC_min und SOC_max liegt, wird beispielsweise P_B(k+1) nicht belegt. Ist das so beabsichtigt?

Wie sind deine Variablen vorbelegt?

Der Übersicht halber würde ich konsequent lineare Indizierung verwenden, also z.B.
SOC(k) statt SOC(k,1).

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Ole_85

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 11.05.2016, 15:48     Titel:
  Antworten mit Zitat      
Hallo Harald,
danke für deine Antwort.

Code:

if SOC(k)<=SOC_min
    SOC(k)=SOC_min;
    P_B(k+1)=P_lad;
    t_ent(k,1)=(t_ent(k-1)+1)*dt;
 


Hier soll es tatsächlich t_ent sein. t_ent steht für die Entladezeit, t_lad für die Ladezeit. Heißt einfach nur, dass wenn SOC_min erreicht wird, wurde in diesem Zeitschritt ja weiter entladen und deshalb geht der Zähler hier eins hoch. t_lad(k) wäre für diesen Schritt Null.
Ein Fehler steckte im letzten Codeteil, hier wird ja auch entladen, d.h. statt t_lad muss hier t_ent stehen.

Code:

elseif SOC(k-1)>SOC(k);
     P_B(k+1)=-P_MF-P_el(k);
     t_ent(k)=(t_ent(k-1)+1)*dt;
     P_DG(k)=0;
 


Zitat:
Wenn SOC(k) zwischen SOC_min und SOC_max liegt, wird beispielsweise P_B(k+1) nicht belegt. Ist das so beabsichtigt?


Die Belegung von P_B(k+1) zwischen SOC_min und SOC_max wollte ich über die letzten zwei Codeteile schaffen. Also wenn der vorherige Ladezustand kleiner ist als der vom aktuellen Zeitschritt, dann wird geladen. P_B ist in diesem Fall belegt. Dadurch, dass ich durch die vorherige if-Bedingungen schon festgelegt habe, dass SOC zwischen Min und Max liegt, dachte ich, dass ich das nicht nochmal festlegen muss.
Code:

if SOC(k-1)<SOC(k)
   P_B(k+1)=P_lad;
...
 


I berechnet sich aus P_B nicht aus P (war zuvor beim Kopieren verschollen)
Code:

I(k,1)=P_B(k)/U(k);  



Zitat:
Wie sind deine Variablen vorbelegt?


Code:

SOC=ones(n_t,1)*SOC1; % wobei SOC1= 80% Anfangsladezustand
P_B=ones(n_t+1,1)*-P_MF; % wobei P_MF=1500W
P_elektr=zeros(n_t,1);
P_lad=4800 % W
t_ent=zeros(n_t,1);
t_lad=zeros(n_t,1);
iw.C_0=300;
 


VG und danke!
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.501
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 11.05.2016, 16:01     Titel:
  Antworten mit Zitat      
Hallo,

mir scheint, dass einiges doppelt berechnet wird.
Ist es für die obere Schleife nicht ausreichend, SOC(k) entsprechend zu setzen?
Kompakter wäre dann
Code:
SOC(k) = max( min(SOC(k), SOC_max), SOC_min );


Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
Ole_85

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 11.05.2016, 16:45     Titel:
  Antworten mit Zitat      
Hallo Harald,
super, ja das geht. Allerdings muss ich dann trotzdem noch sicherstellen, dass sobald SOC_min erreicht ist, mit dem Laden begonnen wird. Also P_B(k+1) umgestellt wird.

Code:


SOC(k)=max(min(SOC(k),SOC_max), SOC_min);
if SOC(k)==SOC_min
   P_B(k+1)=P_lad;
       
elseif SOC(k)==SOC_max
       P_B(k+1)=-P_MF-P_elektr(k);

 


Jetzt habe ich allerdings leider weiterhin das Problem, wie ich mit dem Bereich zwischen SOC_min und SOC_max umgehe. Zuerst dachte ich, ich könnte einfach als dritte Bedingung den Zwischenbereich zwischen SOC_min und SOC_max nehmen. Allerdings hängt die Wahl der Leistung halt davon ab, ob gerade geladen oder entladen wird.

Hast du da noch eine Idee, wie ich das möglichst kompakt darstellen könnte, statt wieder über

Code:

elseif SOC(k-1)>SOC(k);
     P_B(k+1)=-P_MF-P_el(k);
     t_ent(k)=(t_ent(k-1)+1)*dt;
     P_DG(k)=0;
 


gehen zu müssen.

Tausend Dank nochmal für deine super Hilfe! VG!
 
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 - 2025 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.