Simulink Coder: Why is my Matlab function input array not generated properly when the Inport dimension is -1 ?
28 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Hello,
I'm trying to generate C++ code from a Matlab function, I have a script that converts my Matlab function into a Simulink model and then generates code using Simulink Coder.
I found something strange when using an array as input. Here's a simple Matlab function:
function [outputArg1,outputArg2] = interpretArray(inputArg1)
arguments
inputArg1 (1,2)
end
outputArg1 = inputArg1(1);
outputArg2 = inputArg1(2);
end
It's the only block in my Simulink model, connected to one Inport and two Outports. I expect the generated C++ code to use the value of both indexes for the output. But with the default configuration of the Inport (PortDimensions to -1 (inherited)), inputArg1 is generated as a scalar:
/* External inputs (root inport signals with default storage) */
struct ExtU_interpret_T {
real_T inputArg1; /* '<Root>/inputArg1' */
};
/* External outputs (root outports fed by signals with default storage) */
struct ExtY_interpret_T {
real_T outputArg1; /* '<Root>/outputArg1' */
real_T outputArg2; /* '<Root>/outputArg2' */
};
/* Model step function */
void interpret_step(void)
{
/* Outport: '<Root>/outputArg1' incorporates:
* Inport: '<Root>/inputArg1'
*/
interpret_Y.outputArg1 = interpret_U.inputArg1;
/* Outport: '<Root>/outputArg2' incorporates:
* Inport: '<Root>/inputArg1'
*/
interpret_Y.outputArg2 = interpret_U.inputArg1;
After setting the Inport PortDimensions to 2, I get the expected result:
/* External inputs (root inport signals with default storage) */
struct ExtU_interpret_T {
real_T inputArg1[2]; /* '<Root>/inputArg1' */
};
/* External outputs (root outports fed by signals with default storage) */
struct ExtY_interpret_T {
real_T outputArg1; /* '<Root>/outputArg1' */
real_T outputArg2; /* '<Root>/outputArg2' */
};
/* Model step function */
void interpret_step(void)
{
/* Outport: '<Root>/outputArg1' incorporates:
* Inport: '<Root>/inputArg1'
* MATLAB Function: '<Root>/MATLAB Function'
*/
interpret_Y.outputArg1 = interpret_U.inputArg1[0];
/* Outport: '<Root>/outputArg2' incorporates:
* Inport: '<Root>/inputArg1'
* MATLAB Function: '<Root>/MATLAB Function'
*/
interpret_Y.outputArg2 = interpret_U.inputArg1[1];
I thought that declaring the input array dimensions in my Matlab function arguments would propagate the expected dimensions to the Inport but it doesn't seem to be the case. Is this expected or is it a bug? Is there a way to automatically set the Inport dimensions to the expected arguments of the downstream block?
Interestingly, setting the Inport dimensions to an unexpected value (here 3 for example) will cause the code generation to fail.
I know the workaround would be to set the Inport PortDimensions accordingly, but with our script that generates the Simulink model from the Matlab function to generate the C++ code automatically, it would be a bit tricky.
Best regards,
0 Kommentare
Antworten (1)
Ruchika Parag
am 28 Nov. 2024 um 9:48
Hi @Maxime, when generating C++ code from a MATLAB function using Simulink Coder, it is important to ensure your Simulink model accurately reflects the expected dimensions of inputs and outputs. The behavior you are experiencing is expected because Simulink does not automatically inherit dimension specifications from MATLAB code.
The MATLAB function block in Simulink doesn't automatically take dimension specifications from the MATLAB code. It relies on the Simulink model configuration. The default setting for Inport dimensions (-1 for inherited) means Simulink tries to deduce dimensions from the context, which can lead to unexpected results if not explicitly defined. Simulink Coder generates code based on the Simulink model, not directly from MATLAB function specifications.
To address this, you have several options. One approach is to explicitly set the port dimensions in your Simulink model. This ensures that both the model and generated code reflect the correct signal dimensions. Alternatively, you can create a masked block in Simulink that wraps the MATLAB function and explicitly sets input dimensions. This can be automated in your script that converts MATLAB functions to Simulink models. You can also enhance your script to automate the setting of port dimensions based on the expected input dimensions. Using the Simulink API, you can modify block parameters programmatically, like this:
% Example script to set port dimensions
load_system('your_model');
blockPath = 'your_model/your_block';
set_param(blockPath, 'PortDimensions', '2'); % Set to the desired dimension
save_system('your_model');
Another option is to use Simulink parameters to define and manage dimensions across your model. This provides a centralized way to control dimensions and makes updates easier. While the current behavior is expected, these solutions can help you manage input dimensions more effectively. Automating the dimension setting in your script is likely the most scalable approach, especially if you frequently generate Simulink models from MATLAB functions.
0 Kommentare
Siehe auch
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!