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

fmincon zur Parameteridentifikation

 

Palle947
Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 12.06.19
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.06.2019, 19:44     Titel: fmincon zur Parameteridentifikation
  Antworten mit Zitat      
Guten Abend,
ich habe folgendes Problem, und zwar möchte ich mittels der Funktion fmincon ein paar Parameter (m, cw...) meines Längsdynamikmodells so anpassen, dass der simulierte Batteriestrom besser zum gemessenen Strom passt. Ich bekomme es aber einfach nicht hin meinen Code, welcher aus mehreren Unterfunktionen besteht, in die passende Syntax zu formen bzw. komme ich mit anonymen Funktionen noch nicht ganz klar. Ich hoffe ihr könnt mir weiterhelfen meine objective function soll der MSE zwischen gemessener Größe und simulierter Größe sein.
Vielen Dank für eure Hilfe!

Code:
addpath('/Fahrdaten');

clearvars
clc

%% Parameter d. Fahrzeugs

parameter.m = 1280;                     % Fahrzeugmasse (BMW i3) [kg]
parameter.A = 2.38;                     % Fahrzeugstirnfläche (BMW i3) [m^2]
parameter.cw = 0.29;                    % Luftwiderstandsbeiwert (BMW i3) [1]
parameter.r = 0.155*0.70+19*0.0254/2;   % Radius d. Rades (155/70 R19) [m]
parameter.f_r = 0.008;                  % Rollwiderstand [1]
parameter.lambda = 1.1;                 % Drehmassenzuschlagsfaktor [1]
parameter.voltage_nom = 360;            % Nennspannung in V

parameter.eta_powertrain = 0.97;        % Wirkungsgrad Antriebsstrang
parameter.eta_motor = 0.87;             % Motorwirkungsgrad
parameter.eta_battery = 0.95;           % Wirkungsgrad Batterie

%% Umgebungsparameter

parameter.g = 9.81;              % Erdbeschleunigung [m/s^2]
parameter.rho = 1.293;           % Luftdichte (hier = const.) [kg/m^3]

%% Fahrdaten (Zeit, Geschwindigkeit, Beschleunigung (a_x_derived), kumulierte Distanz (distance_cum), Steigung (gradient))

% Laden der Fahrdaten

d =dir('xxx');     % nur *.mat-Dateien betrachten
Anzmat = length(d);                                                         % Anzahl der *.mat-Dateien

for i=1:Anzmat
    filename = d(i).name;
    load(filename)
   
    if isfield(data,'current')
        %% Beschleunigung & Steigung
       
        [data.a_x_derived,data.distance_cum,data.gradient] = Beschl_Steigung(data.velocity,data.time,data.srtm_height);
       
        %% Fahrwiderstandsleistungen
       
        [power.rolling_res,power.air_res,power.gradient_res,power.acc_res,power.all_res] = Widerstaende(parameter.m,parameter.g,parameter.f_r,data.gradient,data.velocity,data.a_x_derived,parameter.cw,parameter.A,parameter.rho,parameter.lambda);
       
        %% Grafische Visualisierung
       
        figure(1)
        subplot(3,1,1)
        plot(data.time,data.velocity*3.6);
        ylabel('v in km/h')
        subplot(3,1,2)
        plot(data.time,data.a_x_derived);
        ylabel('a in m/s^2')
        subplot(3,1,3)
        plot(data.time,power.rolling_res,data.time,power.air_res,data.time,power.gradient_res,data.time,power.acc_res,data.time,power.all_res);
        legend('F_R','F_{Luft}','F_{St}','F_{B}','F_{ges}')
        ylabel('P in W')
        xlabel('t in s')
       
        %% Bestimmen des gesamten Wirkungsgrads (Antriebsstrang, Motor, Batterie)
   
        parameter.eta_gesamt = parameter.eta_powertrain * parameter.eta_motor * parameter.eta_battery;
       
        %% Leistung für Fahranforderung Fahrzustand, Gesamte Batterieleistung, Strom Batterie
       
        [power.mech,power.aux,power.battery_res,results.current] = Leistung_Strom(power.all_res,parameter.eta_gesamt,parameter.voltage_nom);
 
        %% Gegenüberstellung Strom aus Modell & Messung
       
        figure(2)
        plot(data.time,-data.current_avg,data.time,results.current);
        legend('gemessener Strom','modellierter Strom')
        ylabel('I in A')
        xlabel('t in s')
       
        %% Fehler
       
        %[error.absoluteError,error.MAE(i,1),error.MSE(i,1),error.RMSE(i,1)] = Fehler(data.current_avg,results.current);
       
    end
end

clear d i Anzmat
 


Code:
function [a_x_derived,distance_cum,gradient] = Beschl_Steigung(velocity,time,srtm_height)

% Beschleunigung
a_x_derived = [0; diff(velocity)./diff(time)];   % Beschleunigung [m/s^2]

% Kumulierte Distanz
distance_cum = cumtrapz(time,velocity);

% Steigung in rad
% --- Deltas ---
delta_distance = [0; diff(distance_cum)];
delta_height = [0; diff(srtm_height)];
% --- Steigung ---
gradient = atan(delta_height./delta_distance);
% --- Korrektur Steigung bei kleinen Distanzen (Grenze: sample frequency) ---
idx_vel_zero = find(delta_distance < 1);
for i = 1:length(idx_vel_zero)
    if idx_vel_zero(i) == 1
        gradient(idx_vel_zero(i)) = 0;
    else
        gradient(idx_vel_zero(i)) = gradient(idx_vel_zero(i)-1);
    end
end
% --- Korrektur Steigung bei kleinen Distanzen (Grenze: sample frequency) ---
max_gradient = 0.29;    % Maximal zulässige Steigung in Deutschland beträgt 10% (0.01 rad) bzw. für Alpenstraßen 30% (0.29 rad)
gradient = max(-1*max_gradient,min(max_gradient,gradient));

end
 


Code:
function [rolling_res,air_res,gradient_res,acc_res,all_res] = Widerstaende(m,g,f_r,gradient,velocity,a_x_derived,cw,A,rho,lambda)

% Radwiderstandsleistung (hier gleich Rollwiderstand & f_r = const.)
rolling_res = m * g * f_r * cos(gradient) .* velocity;

% Luftwiderstandsleistung
air_res = cw * A * rho/2 * velocity.^3;

% Steigungswiderstandsleistung
gradient_res = m * g * sin(gradient) .* velocity;

% Beschleunigungswiderstandsleistung (ohne Schlupf)
acc_res = lambda * m * a_x_derived .* velocity;

% Gesamtfahrwiderstandsleistung (Summe der einzelnen Fahrwiderstandsleistungen)
all_res = rolling_res + air_res + gradient_res + acc_res;

end
 


Code:
function [mech,aux,battery_res,current] = Leistung_Strom(all_res,eta_gesamt,voltage_nom)

%% Leistung für Fahranforderung Fahrzustand

for n = 1:length(all_res)
    if all_res (n) >= 0                                      
        mech (n) = all_res (n) / eta_gesamt;     % Antrieb
    else
        mech (n) = all_res (n) * eta_gesamt;     % Rekuperation
    end
end

mech = mech.';

%% Gesamte Batterieleistung (Nebenverbraucherleistung berücksichtigen)

aux = (voltage_nom * 6.5) * ones(length(mech),1); % Nebenverbraucherleistung (2340W = const.)
battery_res = mech + aux;

%% Strom Batterie

current = battery_res ./ voltage_nom;

end
 


Code:
function [absoluteError,MAE,MSE,RMSE] = Fehler(current_avg,current)

% Absoluter Fehler
absoluteError = abs(-current_avg - current);
     
% Mean Absolute Error (MAE)
MAE = mae(-current_avg,current);
               
% Mean Squared Error (MSE)
MSE = immse(-current_avg,current);
               
% Root Mean Squared Error (RMSE)
RMSE = rms(-current_avg - current);
             
end
Private Nachricht senden Benutzer-Profile anzeigen


Harald
Forum-Meister

Forum-Meister


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

das ist nun einiges an Code, nur finde ich keinen Versuch eines fmincon-Aufrufs.
Bitte auch genauer spezifizieren, welche "Größen" denn betrachtet werden sollen.

Zudem solltest du darauf achten, Funktionsnamen wie power und gradient nicht als Variablennamen zu verwenden. Das kann übel enden, wenn man dann mal doch die Funktion aufrufen will.

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 ;)
Private Nachricht senden Benutzer-Profile anzeigen
 
Palle947
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 12.06.19
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.06.2019, 20:22     Titel:
  Antworten mit Zitat      
Vielen Dank für die schnelle Antwort! Beim Versuch fmincon aufzurufen gibt er mir immer den error "not enough Input Arguments", was ja auch irgendwie logisch erscheint, wenn er über den MSE nur die beiden Ströme betrachtet, jedoch keinen Zugriff auf die anzupassenden Parameter hat. Diese sind konkret die Masse m, der Luftwiderstandsbeiwert cw und der Drehmassenzuschlagsfaktor lambda. Habe mal meinen kläglichen Versuch fmincon aufzurufen unten beigefügt.. ich hoffe jemand kann mir weiterhelfen!

Einen schönen Gruß,
Pascal

Code:
% Startwert
p0 = [1,1000,0];     %für (lambda, m,cw)

% Zielfunktion
objective = immse(-current_avg - current);      %current_avg gemessen und current ist simuliert)

% optimize with fmincon
A = [];
b = [];
Aeq = [];
beq = [];

% bounds
lb = [0,0,0];
ub = [inf,inf,inf];

popt = fmincon(objective,p0,A,b,Aeq,beq,lb,ub);
 
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


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

immse ist eine Bildverarbeitungsfunktion. Die Verwendung hier wundert mich. norm erschiene mir sinnvoller.

Es sollte in die Richtung gehen:

Code:
objective = @(p) immse(-current_avg - currentValue(p));      


Dabei muss currentValue eine Funktion sein, die aus p den simulierten Wert errechnet.

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 ;)
Private Nachricht senden Benutzer-Profile anzeigen
 
Palle947
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 12.06.19
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.06.2019, 20:50     Titel:
  Antworten mit Zitat      
Okay danke schonmal, jedoch ist das genau das Problem.. ich weiß nicht genau wie ich an die Sache heran gehen soll, weil meine simulierte Größe (currentValue) ja die Endgröße der Simulation ist.. und diese lässt sich nicht so einfach in eine anonyme Funktion überführen.. muss ich das ganze Programm umschreiben oder hast du eine Idee wie das Problem schneller gelöst werden kann?

Vielen Dank für deine Hilfe!
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


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

für den Anfang brauchst du keine anonyme Funktion, sondern nur eine "normale" Funktion. Wenn ich das richtig sehe, ist das im wesentlichen das Skript, das du am Anfang erstellst. Dort wird ja z.B. mit Leistung_Strom das current berechnet. Letzte Zeile der benötigten Funktion ist also:

Code:
[~,~,~,current] = Leistung_Strom( Inputs abhängig von p)


Soll die Berechnung letztlich für eine .mat-Datei durchgeführt werden oder wirklich für mehrere?

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 ;)
Private Nachricht senden Benutzer-Profile anzeigen
 
Palle947
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 12.06.19
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 12.06.2019, 21:33     Titel:
  Antworten mit Zitat      
Es würde mir mehr als ausreichen, wenn ich für dieses Programm/mar Datei einen funktionierenden fmincon implementieren könnte.. deine letzte Antwort habe ich leider nicht ganz verstanden, bin noch Anfänger in Sachen Matlab und habe ja für meine Leistung_Strom Funktion schon die Inputs (all_res,eta_gesamt,voltage_nom), welche mir aber auch nicht weiterhelfen, da meine Parameter, die ich anpassen will in der Funktion Widerstaende stecken.. also quasi aus Widerstaende.m als all_res in die Funktion Leistung_Strom.m eingehen, welche daraus wiederum den Strom berechnet, welchen ich vergleiche mit den Messwerten die mir vorliegen.. etwas kompliziert, aber ich hoffe du weisst worauf ich hinaus möchte.

Danke!
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 12.06.2019, 23:07     Titel:
  Antworten mit Zitat      
Hallo,

Zitat:
Es würde mir mehr als ausreichen, wenn ich für dieses Programm/mar Datei einen funktionierenden fmincon implementieren könnte..

Das ist mir klar. Allerdings ist dein Code ziemlich verschachtelt. Vermutlich ist er nicht mit der Absicht entstanden, da mal was mit fmincon zu optimieren.

Zitat:
deine letzte Antwort habe ich leider nicht ganz verstanden,

Was genau hast du nicht verstanden?

Zitat:
da meine Parameter, die ich anpassen will in der Funktion Widerstaende stecken.. also quasi aus Widerstaende.m als all_res in die Funktion Leistung_Strom.m eingehen, welche daraus wiederum den Strom berechne

Dann musst du leider dich in der genannten Funktion durch all das durchwursteln. Wenn ich das richtig sehe, dürfte die Funktion etwa so aussehen:

Code:
function current = currentValue(p)

%% Parameter d. Fahrzeugs

parameter.m = p(2);                     % <-- soll ja optimiert werden
parameter.A = 2.38;                     % Fahrzeugstirnfläche (BMW i3) [m^2]
parameter.cw = p(3);                    % <-- soll ja optimiert werden
parameter.r = 0.155*0.70+19*0.0254/2;   % Radius d. Rades (155/70 R19) [m]
parameter.f_r = 0.008;                  % Rollwiderstand [1]
parameter.lambda = p(1);                 % <-- soll ja optimiert werden
parameter.voltage_nom = 360;            % Nennspannung in V

parameter.eta_powertrain = 0.97;        % Wirkungsgrad Antriebsstrang
parameter.eta_motor = 0.87;             % Motorwirkungsgrad
parameter.eta_battery = 0.95;           % Wirkungsgrad Batterie

% Damit werden jetzt Beschleunigungen, Widerstände etc. berechnet.
% Mit diesen Daten muss dann noch Leistung_Strom aufgerufen werden
[~,~,~,current] = Leistung_Strom( )


Bitte auch noch die Frage beantworten:
Zitat:
Soll die Berechnung letztlich für eine .mat-Datei durchgeführt werden oder wirklich für mehrere?


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 ;)
Private Nachricht senden Benutzer-Profile anzeigen
 
Palle947
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 12.06.19
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 13.06.2019, 10:15     Titel:
  Antworten mit Zitat      
Hallo und vielen Dank für deine Mühe!
Also es sollen eig. mehrere mat Dateien/Datensätze nacheinander geladen werden.. das macht das Programm auch schon und speichert dann die Ergebnisse ab. Also verstehe ich deinen Lösungsansatz richtig, dass ich direkt am Anfang meines Programmes eine Funktion definiere, mit den Optimierungsparametern p(1), p(2), P(3) und dann in dieser Funktion alle anderen (Widerstände, Leistung_Strom usw...) Unterfunktionen sind?

Gruß,
Pascal
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 13.06.2019, 19:04     Titel:
  Antworten mit Zitat      
Hallo,

Zitat:
und dann in dieser Funktion alle anderen (Widerstände, Leistung_Strom usw...) Unterfunktionen sind?

Unterfunktionen oder Funktionen in separaten Dateien.

Zitat:
dass ich direkt am Anfang meines Programmes eine Funktion definiere

Am Anfang würde ich eher den fmincon-Aufruf sehen. Die Zielfunktion wird dort definiert, und das kann dann wieder auf currentValue oder welche Funktionen auch immer verweisen.

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 ;)
Private Nachricht senden Benutzer-Profile anzeigen
 
Palle947
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 14
Anmeldedatum: 12.06.19
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 13.06.2019, 19:53     Titel:
  Antworten mit Zitat      
Alles klar habe es jetzt hinbekommen vielen Dank, hast mir echt geholfen! Hätte jetzt zum Abschluss noch eine Frage und zwar habe ich das Gefühl bei der Optimierung immer in einem lokalen Minimum zu landen, deshalb würde ich gerne MultiStart anwenden.. magst du mir dabei auch noch helfen das wäre super.

Liebe Grüße,
Pascal

Code:
% Startwert
p0 = [0.3,1];

% optimize with fmincon
A = [];
b = [];
Aeq = [];
beq = [];

% bounds
lb = [0.29,0.7];
ub = [0.5,2];

problem = createOptimProblem('fmincon',Laengsdynamik,'x0','lb','ub')

% [popt,MSE] = fmincon(@Laengsdynamik,p0,A,b,Aeq,beq,lb,ub);

ms = MultiStart

p = run(ms,problem,20)


so funktioniert es irgendwie noch nicht "Error in Optimization (line 16)
problem = createOptimProblem('fmincon',Laengsdynamik,'x0','lb','ub')"
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.448
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 13.06.2019, 22:21     Titel:
  Antworten mit Zitat      
Hallo,

nach 'fmincon' müssen Parameter-Wert - Paare folgen, siehe das Beispiel in der Doku. Etwa so:
Code:
problem = createOptimProblem('fmincon', 'objective', @Laengsdynamik,'x0', p0, 'lb', lb, 'ub', ub)


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 ;)
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.