Mercurial > hg > ltpda
comparison m-toolbox/m/gui/gltpda/ltpdasim.m @ 0:f0afece42f48
Import.
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Wed, 23 Nov 2011 19:22:13 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f0afece42f48 |
---|---|
1 function ltpdasim(block) | |
2 | |
3 % This is the automatic function wrapper | |
4 % ======================================================================== | |
5 % ==================== level-2 M file S-function ========================= | |
6 % ======================================================================== | |
7 % This wrapper is the automatic function, called by every function block | |
8 % in Simulink, able to execute m-file functions retrieving from Simulink: | |
9 % (1) the pointer to the object(s) to be analyzed, coming in as input of | |
10 % the corresponding block (ie, the DATA), | |
11 % (2) the name of the function to be applied on those data, from the tag | |
12 % of the currently executed block (ie, the true FUNCTION), | |
13 % (3) the parameters for that particular block, retrieved from the global | |
14 % shared workspace by the handle of the block (ie, the PARAMETERS). | |
15 % | |
16 % The output is then generated as: | |
17 % OUTPUT = FUNCTION(DATA,PARAMETERS) | |
18 % | |
19 % This output in the end is saved into the global array containing all | |
20 % the AOs (ie, all the DATA go together with other data): thus this output | |
21 % will be freely accessible by all the other functions. | |
22 % | |
23 % The only real output to Simulink will be just the ordinal number of the | |
24 % so-generated AO into the global array of AOs. | |
25 % | |
26 % $Id: ltpdasim.m,v 1.37 2008/12/01 20:03:51 nicola Exp $ | |
27 | |
28 | |
29 setup(block); | |
30 | |
31 | |
32 %% Setup | |
33 | |
34 function setup(block) | |
35 | |
36 % Register dialog parameter: none, because they're retrieved directly | |
37 % from the memory. This will prevent the user to modify the parameters | |
38 % outside the proper parameters panel: | |
39 block.NumDialogPrms = 0; | |
40 | |
41 % Register number of input and output ports | |
42 block.NumInputPorts = 1; | |
43 block.NumOutputPorts = 1; | |
44 | |
45 % Setup functional port properties to dynamically inherited. | |
46 block.SetPreCompInpPortInfoToDynamic; | |
47 | |
48 block.InputPort(1).DirectFeedthrough = true; | |
49 block.InputPort(1).DatatypeID = 0; | |
50 block.InputPort(1).Complexity = 0; | |
51 block.OutputPort(1).DatatypeID = 0; | |
52 block.OutputPort(1).Complexity = 0; | |
53 block.SampleTimes = [0 0]; | |
54 block.SetAccelRunOnTLC(false); | |
55 | |
56 block.OutputPort(1).Dimensions = 1; | |
57 | |
58 % Register methods | |
59 block.RegBlockMethod('SetInputPortSamplingMode',@SetInpPortFrameData); | |
60 block.RegBlockMethod('SetInputPortDimensions', @SetInpPortDims); | |
61 block.RegBlockMethod('Outputs', @Outputs); | |
62 | |
63 function SetInpPortFrameData(block, idx, fd) %#ok<INUSL> | |
64 block.InputPort(1).SamplingMode = fd; | |
65 block.OutputPort(1).SamplingMode = fd; | |
66 | |
67 function SetInpPortDims(block, idx, di) | |
68 block.InputPort(idx).Dimensions = di; | |
69 | |
70 | |
71 %% Outputs | |
72 function Outputs(block) | |
73 global LTPDAinvar gl loop execModels %#ok<NUSED> | |
74 | |
75 % disp(['The name of the currently executed block is ',get_param(get_param(gcbh,'Parent'),'Name')]) | |
76 % disp(['The current size of LTPDAinvar is ',num2str(size(LTPDAinvar,1))]) | |
77 | |
78 currparent = get_param(gcbh,'Parent'); | |
79 subsyshandle = get_param(currparent, 'handle'); | |
80 | |
81 % Check if it's a partial execution: | |
82 if ismember('executionList',evalin('base','who')) | |
83 executionList = evalin('base','executionList'); | |
84 blockIndex = -1; | |
85 for i=1:size(executionList,1), if executionList(i)==gcbh, blockIndex = i; break; end; end | |
86 if blockIndex == -1 % this block is not included in the list of those to be executed. | |
87 disp([' . Partial execution: block ',get_param(subsyshandle,'Name'),' will be skipped.']) | |
88 block.OutputPort(1).Data = -1; | |
89 return | |
90 else | |
91 % Check if the block must receive data from Simulink or retrieve them from a previous calculation: | |
92 if block.InputPort(1).Data(1)==-1 | |
93 annotation = find_system(bdroot,'FindAll','on','Type','Annotation','Tag','ltpda model'); | |
94 execHistory = get_param(annotation,'UserData'); | |
95 blockIndex = -1; | |
96 for i=1:size(execHistory,1), if execHistory{i,2}==subsyshandle, blockIndex = i; end; end | |
97 if blockIndex == -1 % something's wrong: the selected block is not included in the previous execution history | |
98 warning(['*** Partial execution: impossible to retrieve inputs. The block ',get_param(subsyshandle,'Name'),' seems to have never been executed.']) | |
99 block.OutputPort(1).Data = -1; | |
100 return | |
101 end | |
102 j=3; | |
103 while ~isempty(execHistory{blockIndex,j}) | |
104 block.InputPort(1).Data(j-2) = execHistory{blockIndex,j}; | |
105 j = j+1; | |
106 end | |
107 disp([' . Partial execution: block ',get_param(subsyshandle,'Name'),' will now be executed with data retrieved from previous calculation.']) | |
108 else | |
109 disp([' . Partial execution: block ',get_param(subsyshandle,'Name'),' will now be executed.']) | |
110 end | |
111 end | |
112 end | |
113 | |
114 % Check if the user wants to stop the execution: | |
115 lastChar = get(findobj('Name','LTPDA Progress Bar'),'CurrentCharacter'); | |
116 if ~isempty(lastChar) && strcmp(lastChar,'x') | |
117 set_param(bdroot, 'SimulationCommand', 'stop') | |
118 return | |
119 end | |
120 | |
121 % Update the progress bar window: | |
122 progressBar = findobj('Tag','progressaxes'); | |
123 if ~isempty(progressBar) | |
124 blocksTotal = get(findobj('Tag','blockstotal'),'UserData'); | |
125 blocksDone = get(findobj('Tag','done'),'UserData'); | |
126 blocksToGo = get(findobj('Tag','togo'),'UserData'); | |
127 set(findobj('Tag','done'),'UserData',blocksDone+1); | |
128 set(findobj('Tag','togo'),'UserData',blocksToGo-1); | |
129 set(findobj('Tag','done'),'String',['Done: ',num2str(blocksDone+1)]); | |
130 set(findobj('Tag','togo'),'String',['To go: ',num2str(blocksToGo-1)]); | |
131 currblockname = get_param(get_param(gcbh,'Parent'),'Name'); | |
132 for i=1:numel(currblockname), if double(currblockname(i))==10, currblockname(i)=' '; end; end | |
133 set(findobj('Tag','currentexec'),'String',['Current block: ',currblockname]); | |
134 progressSize = get(progressBar,'UserData'); | |
135 progressPosition = get(progressBar,'Position'); | |
136 progressPosition(3) = 1+(progressSize(3)/blocksTotal)*(blocksDone+1); | |
137 set(progressBar,'Position',progressPosition) | |
138 progressBarLoop = findobj('Tag','progressaxes2'); | |
139 if ~isempty(progressBarLoop) | |
140 set(findobj('Tag','done'),'String',['Blocks done: ',num2str(blocksDone+1)]); | |
141 loopStatus = getappdata(0,'loopStatus'); | |
142 progressSize = get(progressBarLoop,'UserData'); | |
143 progressLoopPosition = get(progressBarLoop,'Position'); | |
144 progressLoopPosition(3) = 1+(progressSize(3)/loopStatus(1))*loopStatus(2); | |
145 set(progressBarLoop,'Position',progressLoopPosition) | |
146 end | |
147 drawnow | |
148 end | |
149 | |
150 % Retrieve the function name from the block tag: | |
151 blocktag = get_param(gcb, 'tag'); | |
152 if strcmp(blocktag,'generic') | |
153 paramcommand = get_param(get_param(get_param(gcbh,'Parent'), 'handle'),'Description'); | |
154 eval(paramcommand) | |
155 blocktag = functionName; | |
156 end | |
157 | |
158 % ======================================================================== | |
159 %% For arithmetic blocks | |
160 % ======================================================================== | |
161 | |
162 if strcmp(blocktag,'arithmetic') | |
163 eq = get_param(currparent,'MaskDescription'); | |
164 if strcmp(eq,'Arithmetic block: the user can type in the desidered equation.') | |
165 disp(sprintf('Error: in the ''%s'' arithmetic block no equation has been typed in.',get_param(currparent,'Name'))) | |
166 close(findobj('Name','LTPDA Progress Bar')) | |
167 error(['Error: in the ',get_param(currparent,'Name'),' arithmetic block no equation has been typed in.']) | |
168 end | |
169 equation = eq; | |
170 equation(strfind(equation,char(10))) = []; | |
171 | |
172 paramcommand = get_param(subsyshandle,'Description'); | |
173 if isempty(paramcommand), paramcommand = 'params=plist(''alpha'',''-->'',''beta'',''-->'');'; end | |
174 eval(paramcommand) | |
175 | |
176 for i=1:nparams(params) | |
177 inputBlock = find_system(currparent,'SearchDepth',1,'LookUnderMasks','all','Name',lower(params.params(i).key)); | |
178 if numel(inputBlock)>1, inputBlock(1)=[]; end % this can happen only when the currparent has the same name: then, ignore the 1st, ie. the currparent itself | |
179 inputNumb = get_param(inputBlock{1},'Tag'); | |
180 equation = strrep(equation,lower(params.params(i).key),['LTPDAinvar{block.InputPort(1).Data(',inputNumb,'),1}']); | |
181 end | |
182 | |
183 try | |
184 outdata = eval(equation); | |
185 | |
186 % Setting the output signal name: | |
187 ifsetName = get_param(currparent,'UserData'); | |
188 if ~isempty(ifsetName) && isa(ifsetName,'char') | |
189 % ifsetName = ifsetName; | |
190 else | |
191 ifsetName = get_param(currparent,'Name'); | |
192 end | |
193 if numel(outdata)==1 | |
194 outdata = setName(outdata,ifsetName); | |
195 else | |
196 for i=1:size(outdata,1) | |
197 for j=1:size(outdata,2) | |
198 outdata(i,j) = setName(outdata(i,j),[ifsetName,'_',num2str(i),'-',num2str(j)]); | |
199 end | |
200 end | |
201 end | |
202 | |
203 x = size(LTPDAinvar,1); | |
204 blockName = currparent; | |
205 for i=1:numel(blockName), if double(blockName(i))==10, blockName(i)=' '; end; end | |
206 LTPDAinvar = [LTPDAinvar;{outdata,0,blockName}]; | |
207 block.OutputPort(1).Data = x+1; | |
208 | |
209 probe = get_param(currparent,'MaskHelp'); | |
210 if ~isempty(probe) && isa(probe,'char') && strcmp(probe,'probe') | |
211 LTPDAinvar{size(LTPDAinvar,1),2} = 2; | |
212 end | |
213 | |
214 return | |
215 | |
216 catch err | |
217 disp(sprintf('Something''s wrong in the calculation of the results of the ''%s'' arithmetic block.',get_param(currparent,'Name'))) | |
218 disp('The inputs were:') | |
219 for i=1:nparams(params) | |
220 disp(['Input ',num2str(i),':']) | |
221 LTPDAinvar{block.InputPort(1).Data(i),1} %#ok<NOPRT> | |
222 end | |
223 disp('The equation was:') | |
224 disp(eq) | |
225 close(findobj('Name','LTPDA Progress Bar')) | |
226 | |
227 rethrow(err) | |
228 | |
229 end | |
230 end % for the arithmetic block | |
231 | |
232 % ======================================================================== | |
233 %% =================== RETRIEVE THE PARAMETERS LIST ====================== | |
234 % ======================================================================== | |
235 | |
236 % The command line to produce the proper parameters list for the block | |
237 % currently executed is retrieved from the description of this parent subsystem | |
238 paramcommand = get_param(subsyshandle,'Description'); | |
239 loopExecution = 0; | |
240 | |
241 if ~isempty(paramcommand) | |
242 eval(paramcommand); | |
243 | |
244 % Verify if a global variable or nested loop variable has been used: | |
245 for i=1:nparams(params) | |
246 currVal = params.params(i).val; | |
247 if ischar(currVal) && numel(currVal)>5 && strcmp(currVal(1:5),'loop.') | |
248 loopExecution = 1; | |
249 try %#ok<ALIGN> | |
250 setVal(params.params(i),eval(params.params(i).val)); | |
251 catch, end | |
252 end | |
253 if ischar(currVal) && numel(currVal)>3 && strcmp(currVal(1:3),'gl.') | |
254 try %#ok<ALIGN> | |
255 setVal(params.params(i),eval(params.params(i).val)); | |
256 catch, end | |
257 end | |
258 end | |
259 | |
260 if ~exist('paramEnabled','var'), paramEnabled = ones(1,nparams(params)); end | |
261 currparam = plist(); | |
262 for jj=1:nparams(params) | |
263 if paramEnabled(jj)==1 | |
264 if numel(params.params(jj).key)>6 && strcmpi(params.params(jj).key(1:7),'addPar_'), params.params(jj).setKey(params.params(jj).key(8:end)); end | |
265 currparam = append(currparam,params.params(jj)); | |
266 end | |
267 end | |
268 else | |
269 currparam = plist(); | |
270 end | |
271 | |
272 % Retrieve parameters from Simulink: | |
273 paramFromSimulink = 0; | |
274 for i=1:nparams(currparam) | |
275 paramKey2 = currparam.params(i).key; | |
276 if numel(paramKey2)>7 && strcmpi(paramKey2(1:7),'addPar_'), paramKey = paramKey2(8:end); else paramKey = paramKey2; end | |
277 paramVal = currparam.params(i).val; | |
278 if (isa(paramVal,'char') && strcmp(paramVal,'-->')) || (isa(paramVal,'cell') && numel(paramVal)==1 && isa(paramVal{1},'char') && strcmp(paramVal{1},'-->')) | |
279 paramFromSimulink = paramFromSimulink + 1; | |
280 mux = find_system(currparent,'SearchDepth',1,'LookUnderMasks','all','BlockType','Mux'); | |
281 muxWidths = get_param(mux{1},'CompiledPortWidths'); | |
282 muxWidths = muxWidths.Inport; | |
283 inputBlock = find_system(currparent,'SearchDepth',1,'LookUnderMasks','all','Name',lower(paramKey)); | |
284 if numel(inputBlock)>1, inputBlock(1)=[]; end % this can happen only when the currparent has the same name: then, ignore the 1st, ie. the currparent itself | |
285 inputNumb = str2double(get_param(inputBlock{1},'Tag')); | |
286 x = 0; | |
287 for j=1:inputNumb-1 | |
288 x=x+muxWidths(j); | |
289 end | |
290 paramVal = [LTPDAinvar{block.InputPort(1).Data(x+1)}]; | |
291 if muxWidths(inputNumb)>1 | |
292 for j=x+2:x+muxWidths(inputNumb) | |
293 paramVal = [paramVal,LTPDAinvar{block.InputPort(1).Data(j)}]; | |
294 end | |
295 end | |
296 currparam = pset(currparam,paramKey2,paramVal); | |
297 end | |
298 end | |
299 | |
300 % ======================================================================== | |
301 %% ======================== CALCULATE THE RESULTS ========================= | |
302 % ======================================================================== | |
303 | |
304 y = length(block.InputPort(1).Data) - paramFromSimulink; | |
305 | |
306 % Check to verify the type of function: | |
307 specFunc = {'display'}; | |
308 [meth,clas] = strtok(get(get_param(currparent,'Handle'),'Tag')); | |
309 category = ''; | |
310 if strcmp(meth,'method') | |
311 clas = strtrim(clas); | |
312 infoObj = eval([clas,'.getInfo(''',blocktag,''')']); | |
313 category = infoObj.mcategory; | |
314 end | |
315 | |
316 if ismember(blocktag,specFunc) | |
317 % Input, but no parameters and no output | |
318 type = 4; | |
319 % ====================================== | |
320 elseif strcmp(category,'Output') | |
321 % Input and parameters, but no output | |
322 type = 3; | |
323 % =================================== | |
324 elseif ~isempty(utils.prog.find_in_models(currparent,'SearchDepth',1,'LookUnderMasks','all','BlockType','Ground')) || block.InputPort(1).Data(1)==0 | |
325 % No input, but parameters and output | |
326 type = 2; | |
327 % =================================== | |
328 elseif nparams(currparam)==0 | |
329 % Input and output, but no parameters | |
330 type = 1; | |
331 % ============================ | |
332 else | |
333 % Input, parameters and output | |
334 type = 0; | |
335 % ============================ | |
336 end | |
337 | |
338 | |
339 switch type | |
340 % ==================================================================== | |
341 case 4 % Input, but no parameters and no output | |
342 command = 'feval(blocktag,'; | |
343 for i=1:y | |
344 dVal = block.InputPort(1).Data(i); | |
345 if dVal>0, command = [command sprintf('LTPDAinvar{%d},', dVal)]; end | |
346 end | |
347 command = [command(1:end-1) ');']; | |
348 try | |
349 eval(command) | |
350 catch err | |
351 disp('4') | |
352 disp(sprintf('Something''s wrong in the calculation of the results of the %s function.',blocktag)) | |
353 disp(sprintf('The name of the currently executed block is %s.',get_param(currparent,'Name'))) | |
354 disp(sprintf('The (first) input data ordinal number, in the list of objects, was %d.',block.InputPort(1).Data(1))) | |
355 close(findobj('Name','LTPDA Progress Bar')) | |
356 rethrow(err) | |
357 end | |
358 block.OutputPort(1).Data = 1; % this will be ignored: no output expected. | |
359 return; | |
360 | |
361 % ==================================================================== | |
362 case 3 % Input and parameters, but no output | |
363 try | |
364 command = 'feval(blocktag,'; | |
365 for i=1:y | |
366 dVal = block.InputPort(1).Data(i); | |
367 if dVal>0, command = [command sprintf('LTPDAinvar{%d},', dVal)]; end | |
368 end | |
369 command = [command 'currparam);']; | |
370 if strcmpi(blocktag,'plot'), figure; end; | |
371 eval(command); | |
372 catch err | |
373 disp('3') | |
374 disp(sprintf('Something''s wrong in the calculation of the results of the %s function.',blocktag)) | |
375 disp(sprintf('The name of the currently executed block is %s.',get_param(currparent,'Name'))) | |
376 disp(sprintf('The (first) input data ordinal number, in the list of objects, was %d.',block.InputPort(1).Data(1))) | |
377 disp('The plist passed was:') | |
378 currparam %#ok<NOPRT> | |
379 close(findobj('Name','LTPDA Progress Bar')) | |
380 rethrow(err) | |
381 end | |
382 block.OutputPort(1).Data = 1; % this will be ignored: no output expected. | |
383 return; | |
384 | |
385 % ==================================================================== | |
386 case 2 % No input, but parameters and output | |
387 try | |
388 outdata = feval(blocktag,currparam); | |
389 catch err | |
390 disp('2') | |
391 disp(sprintf('Something''s wrong in the calculation of the results of the %s function.',blocktag)) | |
392 disp(sprintf('The name of the currently executed block is %s.',get_param(currparent,'Name'))) | |
393 disp('The plist passed was:') | |
394 currparam %#ok<NOPRT> | |
395 close(findobj('Name','LTPDA Progress Bar')) | |
396 rethrow(err) | |
397 end | |
398 | |
399 % ==================================================================== | |
400 case 1 % Input and output, but no parameters | |
401 try | |
402 command = 'outdata = feval(blocktag,'; | |
403 for i=1:y | |
404 dVal = block.InputPort(1).Data(i); | |
405 if dVal>0, command = [command sprintf('LTPDAinvar{%d},', dVal)]; end | |
406 end | |
407 command = [command(1:end-1) ');']; | |
408 eval(command); | |
409 catch err | |
410 disp('1') | |
411 disp(sprintf('Something''s wrong in the calculation of the results of the %s function.',blocktag)) | |
412 disp(sprintf('The name of the currently executed block is %s.',get_param(currparent,'Name'))) | |
413 disp(sprintf('The (first) input data ordinal number, in the list of objects, was %d.',block.InputPort(1).Data(1))) | |
414 disp('The plist passed was:') | |
415 currparam %#ok<NOPRT> | |
416 close(findobj('Name','LTPDA Progress Bar')) | |
417 rethrow(err) | |
418 end | |
419 % ==================================================================== | |
420 case 0 % Input, parameters and output | |
421 try | |
422 command = 'outdata = feval(blocktag,'; | |
423 for i=1:y | |
424 dVal = block.InputPort(1).Data(i); | |
425 if dVal>0, command = [command sprintf('LTPDAinvar{%d},', dVal)]; end | |
426 end | |
427 command = [command 'currparam);']; | |
428 eval(command); | |
429 catch err | |
430 disp('1') | |
431 disp(sprintf('Something''s wrong in the calculation of the results of the %s function.',blocktag)) | |
432 disp(sprintf('The name of the currently executed block is %s.',get_param(currparent,'Name'))) | |
433 disp(sprintf('The (first) input data ordinal number, in the list of objects, was %d.',block.InputPort(1).Data(1))) | |
434 disp('The plist passed was:') | |
435 currparam %#ok<NOPRT> | |
436 close(findobj('Name','LTPDA Progress Bar')) | |
437 rethrow(err) | |
438 end | |
439 | |
440 end | |
441 | |
442 %========================================================================== | |
443 %% Cycle to remove objects from memory as soon as they're no longer necessary: | |
444 %========================================================================== | |
445 | |
446 if ~getappdata(0,'maintainresults'); | |
447 portConnectivity = get(subsyshandle,'PortConnectivity'); | |
448 for i = 1:numel(portConnectivity) | |
449 notUsedAnymore = 1; | |
450 if isempty(portConnectivity(i).DstBlock) | |
451 parentBlock = portConnectivity(i).SrcBlock; | |
452 childrenBlocks = utils.prog.findchildren(parentBlock); | |
453 for j = 1:numel(childrenBlocks) | |
454 if isempty(get_param(childrenBlocks(j),'MaskVariables')), notUsedAnymore = 0; end | |
455 end | |
456 % disp(sprintf('*** (Currently executing block %s)',get_param(currparent,'Name'))) | |
457 if notUsedAnymore && LTPDAinvar{block.InputPort(1).Data(i),2}==0 | |
458 % disp(['*** Removed object n°.',num2str(block.InputPort(1).Data(i)),', which was a ',class(LTPDAinvar{block.InputPort(1).Data(i),1}),'.']) | |
459 disp(sprintf('*** (Currently executing block %s)',get_param(currparent,'Name'))) | |
460 LTPDAinvar(block.InputPort(1).Data(i),:) = []; | |
461 | |
462 % Update the execution history: | |
463 ltpda_annotation = find_system(bdroot,'FindAll','on','Type','Annotation','Tag','ltpda model'); | |
464 execHistory = get_param(ltpda_annotation,'UserData'); | |
465 for xx=1:size(execHistory,1) | |
466 for yy=3:size(execHistory,2), | |
467 if execHistory{xx,yy} == block.InputPort(1).Data(i), execHistory{xx,yy} = -1; end | |
468 if execHistory{xx,yy} > block.InputPort(1).Data(i), execHistory{xx,yy} = execHistory{xx,yy}-1; end | |
469 end | |
470 if execHistory{xx,1} == block.InputPort(1).Data(i), execHistory{xx,1} = -1; end | |
471 if execHistory{xx,1} > block.InputPort(1).Data(i), execHistory{xx,1} = execHistory{xx,1}-1; end | |
472 end | |
473 set_param(ltpda_annotation,'UserData',execHistory); | |
474 | |
475 disp('*** LTPDA object cleared from memory, being now unused') | |
476 end | |
477 end | |
478 end | |
479 end | |
480 % ======================================================================== | |
481 %% =============================== OUTPUTS ================================ | |
482 % ======================================================================== | |
483 | |
484 % Set this block status to 'executed': | |
485 set(subsyshandle,'MaskVariables','1'); | |
486 set(gcbh,'MaskVariables','1'); | |
487 | |
488 signalName = get_param(currparent,'Name'); | |
489 ifsetName = get_param(currparent,'UserData'); | |
490 if ~isempty(ifsetName) && isa(ifsetName,'double') && ifsetName==1 | |
491 if numel(outdata)==1 | |
492 outdata = setName(outdata,signalName); | |
493 else | |
494 for i=1:size(outdata,1) | |
495 for j=1:size(outdata,2) | |
496 outdata(i,j) = set(outdata(i,j),'name',[signalName,'_',num2str(i),'-',num2str(j)]); | |
497 end | |
498 end | |
499 end | |
500 end | |
501 | |
502 try | |
503 % To prevent the result calculated here from being canceled at the | |
504 % end of the calculation: | |
505 probe = get_param(currparent,'MaskHelp'); | |
506 if ~isempty(probe) && isa(probe,'char') && strcmp(probe,'probe'), keepThis = 1; | |
507 else keepThis = 0; | |
508 end | |
509 | |
510 % Appending the results: | |
511 ltpda_annotation = find_system(bdroot,'FindAll','on','Type','Annotation','Tag','ltpda model'); | |
512 execHistory = get_param(ltpda_annotation,'UserData'); | |
513 % If there's a previous execution history, check if the current block belongs to it: | |
514 if ~isempty(execHistory) | |
515 member = 0; | |
516 for i=1:size(execHistory,1) | |
517 if execHistory{i,2}==subsyshandle, member = 1; index = i; break; end | |
518 end | |
519 end | |
520 if ~isempty(execHistory) && member && ~loopExecution | |
521 x = execHistory{index,1}; | |
522 if x==-1, x = size(LTPDAinvar,1)+1; end | |
523 for i=1:numel(currparent), if double(currparent(i))==10, currparent(i)=' '; end; end | |
524 LTPDAinvar(x,:) = {outdata,keepThis,currparent}; | |
525 block.OutputPort(1).Data = x; | |
526 execHistory{index,1} = x ; | |
527 execHistory{index,2} = subsyshandle ; | |
528 for i=1:y , execHistory{index,2+i} = block.InputPort(1).Data(i); end | |
529 else | |
530 if isempty(execHistory), execHistory = {}; end | |
531 x = size(LTPDAinvar,1); | |
532 LTPDAinvar = [LTPDAinvar;{outdata,keepThis,currparent}]; | |
533 block.OutputPort(1).Data = x+1; | |
534 execHistory{end+1,1} = x+1 ; | |
535 execHistory{end,2} = subsyshandle ; | |
536 for i=1:y , execHistory{end,2+i} = block.InputPort(1).Data(i); end | |
537 end | |
538 | |
539 % Update the execution history: | |
540 % Are stored the the output obj pointer, the handle of the current subsytem and the input obj pointers: | |
541 set_param(ltpda_annotation,'UserData',execHistory); | |
542 | |
543 | |
544 catch | |
545 disp('------------------============================================------------------') | |
546 disp('------------------============================================------------------') | |
547 disp('------------------============================================------------------') | |
548 disp(sprintf('Something''s wrong in appending to the global variable LTPDAinvar the results of the %s function.',blocktag)) | |
549 disp(sprintf('The name of the currently executed block is %s.',get_param(currparent,'Name'))) | |
550 disp('The data to be saved, calculated into this block, are:') | |
551 outdata %#ok<NOPRT> | |
552 disp('------------------============================================------------------') | |
553 disp('------------------============================================------------------') | |
554 disp('------------------============================================------------------') | |
555 end | |
556 | |
557 %========================================================================== | |
558 | |
559 % The output to Simulink is just the ordinal number (ONE AND ONLY ONE | |
560 % NUMBER) of the object appended to the global array LTPDAinvar. | |
561 | |
562 % endfunction |