Code Generation Handle Object Not Defined for All Execution Paths

I have a problem where I am using a custom handle class that is allocated within an infinite while loop. At the end of each iteration through the loop, I need to store that object for use in the next time through the loop. Because these are handle obects and I am doing code generation, I can't preallocate the object before the loop. I have reduced my code to a simple example (below) where X represents this handle object. To keeps things simple, I am just making X a vector (not an instance of my class) for this example code.
As you can see below, I have tried to set up this Xhold variable on the first iteration through the loop, but I am still getting the error from coder: ??? Variable 'Xhold' is not fully defined on some execution paths.
I have seen this error in the past and have typically been able to figure out how to get around this, but in this instance I can't see how to fix this error. I don't understand why coder doesn't see that Xhold is set for the first iteration and then will be defined for other paths. If anyone has insights on why coder doesn't see Xhold as being fully defined on all execution paths I'd appreciate it.
function [] = detection_debug()
coder.varsize("dataReceived",[1025 1],[1 0]);
sampsForMaxPulses = 5800320;
asyncDataBuff = dsp.AsyncBuffer(sampsForMaxPulses);
%Initialize loop variables
framesReceived = 0;
segmentsProcessed = 0;
latch = false;
while true
% if strcmp(previousState, 'unspawned')
if ~latch
%Initialize; Can't do this outside (before) the loop because
%Xhold will actually be a handle objects allocated within a loop
%and thus can't be referenced outside the loop.
Xhold = rand(2,22);%Define twice so coder knows it might vary.
Xhold = rand(1,20);
latch = true;
end
%% Randomly generate random data. (Some times no data is generated)
[dataReceived] = rand(randi([0 1],1,1),1);%channelreceiver('0.0.0.0', Config.portData,resetUdp,false);
%% Wait for new data else put data in buffers
if isempty(dataReceived)
pause(0.25);
else
framesReceived = framesReceived + 1;
asyncDataBuff.write(dataReceived);
%% Process data if there is enough in the buffers
if asyncDataBuff.NumUnreadSamples >= 20
X = asyncDataBuff.read(20);%waveform();
if segmentsProcessed==0
X = X + 1 ;
else
X = X + Xhold;
end
segmentsProcessed = segmentsProcessed+1;
Xhold = X;
end
end
end
end

 채택된 답변

Walter Roberson
Walter Roberson 2022년 8월 25일
편집: Walter Roberson 2022년 8월 25일
Variables must be initiallized unconditionally in the flow they are used in, with one exception:
If the variable is declared persistent or global, then it may appear conditionally in an "if isempty()" clause and defined there. Simulink recognizes that construct as a initialization.
latch = false;
if ~latch
is too conditional for Simulink, especially with the test being inside a loop.

댓글 수: 8

...but "isempty(Xhold)" results in an error in code generation because:
??? Undefined function or variable 'Xhold'. The first assignment to a local variable determines its class.
Any ideas on how can I unconditionally initilize a variable that contains handle classes and thus can't be referenced outside of the loop?
Is the intention that there will be only one total objects of that handle class? If so then see https://www.mathworks.com/help/simulink/ug/memory-management-of-handle-objects-in-generated-code.html#buzy036
" Because these are handle obects and I am doing code generation, I can't preallocate the object before the loop" -- I am not convinced that is true. The initial allocation determines size and class, but if you are using multiple objects then you can initialize Xhold to an instance of the handle object with initial properties before the loop.
If you create new instances of the handle object inside the loop and you need the handle object after the loop, then Yes you could have problems -- but in that situation your approach is not going to work anyhow.
Do you know if preallocation before the loop counts as "A Variable Outside a Loop Cannot Refer to a Handle Object Allocated Inside a Loop"? For example, that help files says the following will produce an error in code generation. Do you know if it would if we eliminated the last line y = p.prop ?
function y = usehandle1
p = mycls(0); % Instance of mycls with prop value 10 created
for i = 1:10
p = mycls(i); % Handle object allocated inside loop
end
%=====>> y = p.prop; % Handle object referenced outside loop
end
Another layer of complication for me is that my handle object contains properties that are handle objects. Those objects are allocated by class methods that are executed within the loop. I'll figure that out later though if I can just get this first layer of preallocation figured out.
Inside the example loop p is being overwritten with new handle objects, and the final handle object is used after the loop.
The advice has no problem with creating a handle object before the loop and using and adjusting its properties within the loop.
It does have a problem with an Allocate / loop / replace / end loop / use handle flow
One way to get around this is to change my objects to structures at the end of each loop and just pull the properties I need from the structure on the next iteration of the loop. In theory, this would be as easy as calling Xstruct = struct(X), where X is my handle object. Unfortunately, I get the error "??? Struct with one argument is not supported for code generation." which means I'll need to manually code up a basic obj2struc function for this program ... Xstruct.prop1 = X.prop1 etc.
(The documentation on the struct function doesn't mention this limitation for code generation.)
Re your last post: Got it. Thanks. That clarifys things a bit.
Is it solved Michael? If so, please click the "Accept this answer" link to award Wlater reputation points and let others know it's solved.
Michael
Michael 2022년 8월 26일
편집: Michael 2022년 8월 26일
The initial question is answered (thanks Walter) and now accepted. I'm still a bit up a creek because I don't use my object after the loop.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

제품

릴리스

R2022a

질문:

2022년 8월 25일

편집:

2022년 8월 26일

Community Treasure Hunt

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

Start Hunting!

Translated by