Simulink - Embedded Matlab function - Size of function not bounded

3 views (last 30 days)
Hi all,
I am trying to use an embedded Matlab function block to calculate a time delay such as: x(t) - x(t - tn) = constant
My code is below where 'x' and 't' are input vectors of 21x1 (created using the 'Tapped Delay' block) and I require 'tn' as a scalar output.
function tn = fcn(x, t)
tn = zeros(1, 'double'); %#ok<*PREALL>
if x(end) < 1
tn = 1.1;
return
end
coder.extrinsic('csapi', 'fnval')
coder.varsize('tn', 1)
tq = min(t):0.001:max(t);
b = csapi(t, x);
xq = zeros(size(tq), 'double');
xq = fnval(b, tq);
a = xq(end) - xq - 1;
idx = find(min(abs(a)) == abs(a), 1, 'last');
tn = tq(end) - tq(idx(1));
So the first error I was getting was: Data 'tn' (#62) is inferred as a variable size matrix, while its specified type is something else.
I'm not 100% sure why this error is occurring because I would assume 'tn' would always be scalar, well that's my intention. However, I set 'tn' as a variable size matrix but set its size to '1'.
The next error: Dimension 2 is fixed on the left-hand side but varies on the right ([1 x 1] ~= [1 x :?]).
I looked here (<http://uk.mathworks.com/matlabcentral/answers/79386>) but I couldn't see any option to make the variable 'Tunable'.
So instead another thread (<http://uk.mathworks.com/matlabcentral/answers/154282>) mentioned changing the 'tq(idx)' to 'tq(idx(1))'.
But now I'm stuck at the following error: Computed maximum size of the output of function 'colon' is not bounded. Static memory allocation requires all sizes to be bounded. The computed size is [1 x :?].
Function 'MATLAB Function1' (#60.182.201), line 12, column 6: "min(t):0.001:max(t)"
One thread (<http://uk.mathworks.com/matlabcentral/newsreader/view_thread/310599>) mentioned using the assert function but I have had no luck with this.
Anyone know of a potential fix? Or have I just missed something prior to my other fixes that would also work?
Cheers Carl

Accepted Answer

Denis Gurchenkov
Denis Gurchenkov on 2 Apr 2015
Hi Carl,
Since csapi and fnval do not support code generation (that's why you used extrinsic on those), you can as well move all your code into an extrinsic function. I mean:
- create myfnc.m like this:
function tn = myfcn(t, x)
tq = min(t):0.001:max(t);
b = csapi(t, x);
xq = zeros(size(tq), 'double');
xq = fnval(b, tq);
a = xq(end) - xq - 1;
idx = find(min(abs(a)) == abs(a), 1, 'last');
tn = tq(end) - tq(idx(1));
- replace your block body by an extrinsic call to myfcn:
function tn = fcn(x, t)
tn = zeros(1, 'double'); %#ok<*PREALL>
if x(end) < 1
tn = 1.1;
return
end
coder.extrinsic('myfcn');
tn = myfcn(x, t);
This should do the trick.
An alternative solution is to keep csapi and fnval extrinsic, but write the rest of the code inside the block, the way you did that. You can make it work by
- Removing coder.varsize('tn',1) (tn is a scalar, so why varsize it?) - Then you will get an error about colon range being unknown, so you'd have to replace
tq = min(t):0.001:max(t);
with something like
t0 = min(t);
t1 = max(t);
assert(t0 > 0);
assert(t1 < 10); % put your own bounds instead of 0 and 1
tq = t0:0.001:t1;
But frankly I think you should just use an extrinsic myfcn trick.
Does this make sense?
Denis.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!

Translated by