Are there any alternatives to try/catch statements that are supported by code generation?

I am trying to prepare an application (prepared in App Designer and connected to a Simulink model) to be packaged as a standalone executable.
My Simulink model is fairly simple: using Interpreted MATLAB function blocks as input and output to an s-function block (which is connected to a much larger and complicated external model).
In order to create a standalone executable for an application connected to a Simulink model, I found that I have to use Simulink Compiler, which does not support Interpreted MATLAB functions, so I am trying to convert their functionality to MATLAB function blocks.
As it turns out, MATLAB function blocks are further subject to code generation limitations, which exclude try/catch statements. These try/catch statements are primarily used to catch and pass error code or correct user input with instructions, which is a core functionality of deploying a proprietary application in industry.
Therefore, I was wondering if there are any alternatives to try/catch statements that are supported by code generation? I could not find any simple fix in the documentation. Are there any options besides coding in more input validation?
Thanks!

3 Commenti

I don't have Simulink and what I could find in the online doc for Simulink Compiler didn't lead me to the conclusion try...catch...end isn't supported, but may you've run into it already whether it's documented where easily found or not...
But, I know for certain that an executable can be built with the Matlab compiler/AppDesigner that does include them for what (little?) that may be worth. I dunno if there would possibly be any way to use code from it with Simulink or not.
As far as substitutes, I am unawre of any other high-level coding construct that will help or that can simulate the effect; lacking the feature was what always caused building production code in Fortran to be such a pain before; the amount of diagnostic code required to be robust was always a tremendous effort.
When I use coder.screener to scan the files required for my application, it states "code generation does not support TRY/CATCH constructions."
As you said, I don't believe Matlab Compiler has this issue as I have also made executables with try/catch with Matlab Compiler (apps without Simulink model).
It seems like the issue is then with the Simulink Compiler. If there is no substitutes, would you recommend more robust input validation as opposed to relying on try/catch? That is the only other option of thinking of that I am dreading because who wants to do more work :( ...
Unfortunately, if you can't use try...catch construct, then ensuring the error doesn't happen first is really the only alternative because if you let any error happen, BOOM! goes the app and if's then too late to do anything; the horse has already left the barn.
About all you can do to help is probably write one or more helper functions that let you screen inputs for validity(*); the issue happens if such screening needs a lot of additional logice to be effective if you can't just select a range of valid inputs.
Of course, that also gets into how you let the user actually interact with your app, if they can type freely into a text field and you then convert to a number, the problem is much more complex than if it's a slider (which would be the way one could go for input that must be in a range to avoid/prevent the error if it is that simple).
(*) One of my generic utility functions is simply "syntactic sugar" to replace the logic construct in the top level user code with a function is
function flg=iswithin(x,lo,hi)
% returns T for values within range of input
% SYNTAX:
% [log] = iswithin(x,lo,hi)
% returns T for x between lo and hi values, inclusive
flg= (x>=lo) & (x<=hi);
end
This has the advantage of being able to be combined in logic combinations without the muss of the actual comparison to try to read plus is vectorized. Things such as this customized for your specific needs can help, but it's still going to be a lot of work to make something that is very robust unless you can otherwise control the way the user interacts with the app.

Accedi per commentare.

 Risposta accettata

Hi Roop,
Can you post the code of a simple Matab Function that illustrates how you're tyring to use a try/catch? I'm having trouble envisioning how such might be used in the context of a Simulink model.
In the interim, I think that one can use error inside a Matlab function. Maybe you can detect the error inside the Matab Function, call error, and catch the error outside of Simulink in the App.

4 Commenti

"..., I think that one can use error inside a Matlab function."
Yes, but the problem is that error simply allows the user to throw an error; if the system generates an error during execution outside a try...catch...end block it throws the system error message associated with the MException object automagically constructed and halts.
There isn't any other way to prevent an error from throwing the error; you can't run a piece of code that errors and then query the error status to take some further action; the app will have already closed.
You can do such things with warnings, but not errors; they're 100% fatal.
I was thinking about something along these lines
try
sim('mymodel'); % generates an error, throws the exception
catch ME
% take appropriate action
end
I think that calling error from inside the Matlab Function block inside Simulink generates an exception out to Matlab in the usual way. Unfortunately, I'm in no position at present to test my hypothesis.
It seems to work.
Generate a simple model
bdclose('all');
hsys = new_system('errtest');
hconstant = add_block('simulink/Sources/Constant','errtest/Input');
hfunc = add_block('simulink/User-Defined Functions/MATLAB Function','errtest/func');
hout = add_block('simulink/Sinks/To Workspace','errtest/output');
PH = 'PortHandles';
add_line(hsys, ...
get_param(hconstant,PH).Outport,...
get_param(hfunc,PH).Inport);
add_line(hsys, ...
get_param(hfunc,PH).Outport, ...
get_param(hout,PH).Inport);
Add a call to error inside the Matlab Function block
c = get(hfunc,'MATLABFunctionConfiguration');
c.FunctionScript = strrep(c.FunctionScript,'y = u','y = u; error(''foobar'')');
% Uncomment this line to open the model on the Simulink canvas for by-hand editing, execution, etc.
% open_system(hsys);
The exception generated from inside Simulink is caught (check ME.message)
try
out = sim('errtest');
catch ME
ME
end
ME =
MSLException with properties: handles: {[377.0012]} identifier: 'Stateflow:Runtime' message: 'foobar...' cause: {} stack: [3x1 struct] Correction: []
However, the try/catch may not be needed. We can also do this, which is probably a better approach.
out = sim('errtest','CaptureErrors','on');
out
out =
Simulink.SimulationOutput: simout: [1x1 timeseries] tout: [] SimulationMetadata: [1x1 Simulink.SimulationMetadata] ErrorMessage: [1x199 char]
out.ErrorMessage
ans =
'foobar Error in 'errtest/func' (line 3) y = u; error('foobar');'
hey @Paul, thanks for responding! While I cannot directly utilize the reasoning of your example, it did inspire my solution a bit- using the strrep and error functions in some use cases. The combination of this and more robust input validation as @dpb mentioned is good enough for my development purposes. Thank you @Paul and @dpb!

Accedi per commentare.

Più risposte (0)

Categorie

Scopri di più su Simulink Coder in Centro assistenza e File Exchange

Prodotti

Release

R2022a

Richiesto:

il 25 Giu 2024

Commentato:

il 1 Lug 2024

Community Treasure Hunt

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

Start Hunting!

Translated by