how to call a custom C-mex from an Embedded MATLAB Function block in a Simulink model?

5 views (last 30 days)
I have been using cvxgen to generate a csolve.mexw32 file. If we have a matlab mfile(there-in-after) in which I call the mexw32 file, the operation of the program can be realized well, but failed in Embedded MATLAB Function block. Many errors have been made. How should I modify ?For more please see annex. Thanks, Xiwen
%if true
% code
%end
params.eta=.98;
params.kappac=.98;
params.kappad=.98;
params.Cmax=10;
params.Dmax=10;
params.C=50;
params.gamma=.02;
params.q_0=0;
params.p_0=1;
params.Q_t=ones(20);
params.b_t=ones(20,1);
params.q_t=ones(20,1);
params.s_t=ones(20,1);
params.x_t=ones(20,1);
for i=1:50, params.p{i}=rand(1)*10;
end
[vars, status]=csolve(params);

Accepted Answer

Alexander Bottema
Alexander Bottema on 8 Jul 2014
Hi yuan,
There are multiple problems in your example, so I'll enumerate the changes I've made.
First it is odd to call a MEX function from MATLAB Coder (formerly Embedded MATLAB). Normally you can call C functions directly using coder.ceval (formerly eml.ceval). However, it looks that the code you're calling is auto generated and someone has made an infrastructure to automatically generate MEX functions for MATLAB.
Using your function block code I rewrote it like this:
function [vars_u_t, vars_z_t, optval, gap, steps, converged]=myfcn(eta)
%#eml
params.eta=eta;
params.kappac=.98;
params.kappad=.98;
params.Cmax=10;
params.Dmax=10;
params.C=50;
params.gamma=.02;
params.q_0=0;
params.p_0=1;
params.Q_t=ones(20);
params.b_t=ones(20,1);
params.q_t=ones(20,1);
params.s_t=ones(20,1);
params.x_t=ones(20,1);
% MATLAB Coder don't support growing matrices through iteration
% (only by complete assignment). That's why we preallocate here.
params.p = zeros(50,1);
for i=1:50
params.p(i)=rand(1)*10;
end
% It's no longer called eml. (they are now all renamed to coder.)
% I don't touch this, becuase I don't know which version you're
% using.
eml.extrinsic('csolve_mex');
% We need to initialize these variables, because inference can
% not figure out the output types on extrinsic function calls.
status.optval = 0;
status.gap = 0;
status.steps = 0;
status.converged = 0;
vars.u_t = zeros(20, 1);
vars.z_t = zeros(20, 1);
[vars, status]=csolve_mex(params);
% To avoid Simulink bus types I extracted all elements in parts
vars_u_t = vars.u_t;
vars_z_t = vars.z_t;
optval = status.optval;
gap = status.gap;
steps = status.steps;
converged = status.converged;
Look at the comments and you'll see the changes I've made. To summarize:
1) I renamed the MEX function to csolve_mex because otherwise you get shadowing of csolve.m. MATLAB Coder in Simulink always use source files as precedence. Normally, you never call MEX functions in MATLAB Coder. You usually call C functions directly through coder.ceval and directly on native types (never through mxArrays and MEX API). Note that eml.extrinsic has been changed to csolve_mex, and I renamed the file csolve.mexw32 to csolve_mex.mexw32. (Actually mexw64 on my machine, but you get my point).
2) params.p(i) = ... You can see that I preinitialized that field. MATLAB Coder doesn't support growing except through complete assignment. To avoid this problem I preallocated the matrix before filling it.
3) If you use eml.extrinsic, then we don't analyze the function it calls, so it becomes impossible for us to figure out the MATLAB types. That's why you need to preinitialize the outputs before calling the extrinsic function (status.optval = 0; ...)
4) To avoid using Simulink buses I just ripped apart the structures into their parts. Then I just connected 5 scopes (one for each output).
I got this running on my machine after those changes. Whether the results are correct or not is beyond my knowledge.
  4 Comments
Kai Wu
Kai Wu on 6 Mar 2018
Dear Alexander, I found that the error is due to the use of array instead of cell array on p(i), but if i use cell array, Matlab says Code generation does not support cell arrays in structure fields
Alexander Bottema
Alexander Bottema on 7 Mar 2018
Hi Kai,
Can you provide a code excerpt, and what version are you running? Cell arrarys inside structures worked fine in R2017b (I even tried in R2016a.)
Thanks, Alexander

Sign in to comment.

More Answers (0)

Categories

Find more on MATLAB Coder in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!