using fmincon (and optimset) in embedded matlab function

3 ビュー (過去 30 日間)
Rohit  Hippalgaonkar
Rohit Hippalgaonkar 2012 年 3 月 7 日
i have a large simulink model of a stiff system with numerous layers and sub-systems. i'd like to use an embedded matlab function module to find an optimal set of parameters at every step of the simulation, and these would be used as inputs to another part of my model.
here is my code within the embedded Matlab file:
function [beta_ref, uce_opt, Mce_opt] = generate_commands(M_cp, M_sw, n_eng, n_sw, Q_meas, dt, dp, beta1_prev, uce_prev, Mce_prev, engine, design)
%% initial guess X0 = [100; 100];
%% bounds on controls : LB and UB LB = [0; -100]; UB = [100; 100]; [beta_DC MDC_load beta_sw Q_sw] = cycle_def_ctrls(n_eng,n_sw,dp,Q_meas,M_sw, M_cp, design);
%% optimization algorithm %options = optimset('Algorithm','sqp'); problem.objective = 'engine_poly_model'; problem.Aineq = []; problem.bineq = []; problem.Aeq = []; problem.beq = []; problem.X0 = [100 100]; % X_prev % X0 set to full throttle and max. storage pump displacement problem.lb = LB; problem.ub = UB; problem.nonlcon = 'non_lin_constr'; problem.options = options; problem.solver = 'fmincon';
% call fmincon and unwrap controls x = fmincon(@engine_poly_model,X0,[],[],[],[],LB,UB, @non_lin_constr);
beta_ref = zeros(1,5); uce_opt = X(1); beta_ref(1) = X(2); beta_ref(2) = beta_sw; beta_ref(3:5) = beta_DC;
% engine torque calculations M_WOT = interp1(speed,torque,n_eng); % max. possible torque of full-size engine Mce_friction =engine.V/(2*6.28)*(75+48*n_eng/1000+.4*(2*engine.L*w_eng)^2); Mce = (u_thr/100)*(M_WOT + Mce_friction); %[Nm] %Engine torque Mce_opt = (Mce - Mce_friction)*esf; % [Nm] net engine torque output (scaled)
end
function [beta_DC MDC_load beta_sw Q_sw] = cycle_def_ctrls(n_eng,n_sw,dp,Q_meas,M_sw,M_cp,design)
w_sw = n_sw*pi/30; P_sw = M_sw*w_sw; % calculate swing power requirement
% design parameters Vd_sim = design.V1; Vd_S = design.V2; % displacements of units 1 and 2 i_belt = design.ibelt; eta_belt = design.etabelt;% belt : speed ratio and torque efficiency
% Pre-allocate pump commands, losses and displacements beta_DC = zeros(1,3); T_pump = zeros(1,5); Ms = zeros(1,5); Qs = zeros(1,5); Vi = zeros(1,5); % pre-allocate
% Determine command for unit 2 [beta_sw flag_2] = beta_from_M(M_sw, n_sw, dp(1),Vd_S,'sauer42'); [Ms_sw,Qs_sw,Vi_sw] = unitlosses(n_sw,dp(1),beta_sw,Vd_S,'sauer42'); if P_sw > 0 Q_sw = beta_sw*Vd_S*n_sw/1e5; % actually use Vi_sw here? else Q_sw = beta_sw*Vd_S*n_sw/1e5 + Qs_sw; % actually use Vi_sw here? end
% Determine DC pump commands (units 3, 4, 5) % for k = 3:5 % [beta_DC(k-2), flag(k-2)] = beta_from_Q(Q_meas(k-1),n_eng/i_belt,dp(k-1),Vd_sim,'pca018'); % [Ms(k), Qs(k), Vi(k)] = unitlosses(n_eng/i_belt,dp(k-1),beta_DC(k-2),Vd_sim,'pca018'); % T_pump(k) = (beta_ref(k)*Vd_sim*dp(k-1)/(20*pi) + Ms(k)); % end
MDC_load = sum(T_pump)/(eta_belt*i_belt) + M_cp; % DC load + charge pump load end
function [p_hp_next n_eng_next] = state_model_sph(x, n_eng, dp, dt, design, engine) % inputs : throttle (%), beta_1 (%), p_hp, n_eng, design, engine, MDC_load % outputs : pressure and speed at next instant
beta_ref_sto = x(2); u_thr = x(1); % controls
% design parameters esf = design.esf; % engine scaling factor i_belt = design.ibelt; eta_belt = design.etabelt; % belt speed ratio and torque efficiency Vd_sim = design.V1; Vd_S = design.V2; % displacements of units 1 and 2 V0 = design.V0; p0 = design.p0; n = design.n; % accumulator pre-charge volume, pressure and isotropic coefficient C_H = design.Vls/design.Koil; %[L/bar] % Hydraulic line capacitance (C_H) p_hp = dp(1) + 0.5; C_accu = V0/n*(p0/p_hp^(n+1))^(1/n); %[L/bar] %Accumulator capacitance
% engine parameters TorqueCurve = engine.TorqueCurve; % Engine torque curve (....) torque = [TorqueCurve.torque; -10.76]; speed = [TorqueCurve.speed; engine.n_max]; Jce = engine.Jce; % kg*m^2 effective mass moment of inertia of engine ne_max = engine.n_max;
% engine torque calculations M_WOT = interp1(speed,torque,n_eng); % max. possible torque of full-size engine Mce_friction =engine.V/(2*6.28)*(75+48*n_eng/1000+.4*(2*engine.L*w_eng)^2); Mce = (u_thr/100)*(M_WOT + Mce_friction); %[Nm] %Engine torque Mce_net = (Mce - Mce_friction)*esf; % [Nm] net engine torque output (scaled)
% engine load calculation [Ms_sto,Qs_sto,Vi_sto] = unitlosses(n_eng,dp(1),beta_ref_sto,Vd_sim,'pca018'); M_sto = beta_ref_sto*Vd_sim*dp(1)/(20*pi) + Ms_sto; % Storage Pump torque if beta_ref_sto > 0 Q_sto = beta_ref_sto*Vd_sim*n_eng/1e5 - Qs_sto; else Q_sto = beta_ref_sto*Vd_sim*n_eng/1e5; end M_load = MDC_load + M_sto;
% engine dynamics weng_dot = 1/Jce*(Mce_net-M_load); w_eng_next = weng_dot*dt+w_eng; n_eng_next = w_eng_next*30/pi;
%% Accumulator Pressure Build-Up p_hp_dot = (Q_sto - Q_sw)/(60*(C_H + C_accu)); %[bar/s] p_hp_next = p_hp_dot*dt+p_hp;
end
%% nonlinear inequality constraints : NONLCON (C, Ceq) % C(X) < 0, Ceq(X) = 0 function [C Ceq] = non_lin_constr(x,n_eng,p_hp,dt,design,engine)
[p_hp_next n_eng_next] = state_model_sph(x, n_eng,p_hp, dt, MDC_load, Q_sw, design, engine);
% lower limit on engine speed ne_d = zeros(4,1); for k = 2:4 ne_d(k) = abs(Q_meas(k))*1000/(0.95*Vd_sim); % minimum engine speed to meet i^th pump's flow requirement end ne_min_flow = max(ne_d); ne_min = max(ne_min_flow,engine.n_min);
% lower limit on accumulator pressure dp_min_sw = abs(M_sw)*20*pi/(Vd_S); % min. pressure (in bar) required to meet load on swing motor p_hp_min = max(design.p0/0.9,(dp_min_Msw+0.5));
C = zeros(6,1);
C(1) = p_hp_next - design.p_sto_r; C(2) = p_hp_min - p_hp_next; C(3) = ne_min - n_eng_next; C(4) = n_eng_next - engine.n_max; C(5) = (n_eng_next - n_eng)/dt - engine.acc_rl; C(6) = (n_eng_next - n_eng)/dt + engine.dec_rl;
Ceq = []; end
%% objective function function [fuel] = engine_poly_model(x,n_eng,engine,design) % inputs : engine throttle (%), storage pump torque (%) TorqueCurve= engine.TorqueCurve; speed = TorqueCurve.speed; torque = TorqueCurve.torque; w_eng = n_eng*pi/30; M_WOT = interp1(speed,torque,n_eng); % max. possible torque of full-size engine Mce_friction =engine.V/(2*6.28)*(75+48*n_eng/1000+.4*(2*engine.L*w_eng)^2);
u_thr = x(1); Mce = (u_thr/100)*(M_WOT + Mce_friction); %[Nm] %Engine torque Mce_net = (Mce - Mce_friction)*esf; % [Nm] net engine torque output (scal% output : fuel rate
Mce_net = Mce_net/design.esf; % scale torque up (can only use fuel model for full-sized engine) X1 = n_eng; X2 = Mce_net; fuel = 1.5832e-6*X1^2 + 1.6088e-5*X1*X2 - 0.0056207*X1 - 3.1954e-5*X2^2 + 0.024848*X2 + 5.6585; % fuel = design.esf*fuel; % scale fuel down end
When I try to check the model (Ctrl+D) I am seeing an error saying that fmincon (and optimset) is not supported for code generation, and that I should try using coder.extrinsic. I tried defining fmincon and optimset (coder.extrinsic('fmincon','optimset')) in the command prompt but this did not work either. same error.
Is there an alternate way to do this?

回答 (0 件)

カテゴリ

Help Center および File ExchangeSolver-Based Nonlinear Optimization についてさらに検索

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by