Friday, March 29, 2024
HomeMatlabLeveraging Generated Code from MATLAB in a C++ Utility » Man on...

Leveraging Generated Code from MATLAB in a C++ Utility » Man on Simulink


At present I’m joyful to welcome visitor blogger Erin McGarrity. The principle motive why I’m excited to welcome Erin as visitor blogger is that he shall be speaking about producing C/C++ code from MATLAB code and Simulink fashions utilizing MATLAB Coder, Simulink Coder and Embedded Coder. Whereas I’ve traditionally targeted extra on simulation-related subjects on this weblog, I understand that code technology is a vital subject for a lot of readers of this weblog. We want to hear within the feedback under what you consider at the moment’s subject, and what different code technology associated subjects you want to see coated on this weblog.

Introduction

As an example we’ve got a flowery numerical routine that we have been engaged on in MATLAB that we wish to make the most of in an exterior C++ software. On this submit, we’ll present how we will generate a dynamic library from MATLAB code which we will name from a C++ program. This can permit us to harness a few of the energy of MATLAB in an exterior program.

The MATLAB Code

To display the workflow, let’s create a routine that performs a line match to some information. This perform can have 2 inputs, x and y, that are each vectors of knowledge to suit. These vectors ought to have the identical size N. The outputs for this perform are m and b, the slope and intercept of the road that most closely fits the information. We’ll carry out our match by minimizing the squares of the vertical distances of the factors to the road within the point-slope type which is given by this equation [1]:

ϕ(m,b)=i=1N(y(i)(mx(i)+b))2

The minimal of ϕ(m,b)might be discovered utilizing the standard strategy of taking the by-product of it with respect to m and b and setting these to zero. Doing so provides us the next system of two equations:

mϕ(m,b)=0=i=1N2(y(i)(mx(i)+b))x(i)

and

bϕ(m,b)=0=i=1N2(y(i)(mx(i)+b))1

Right here we’ve got used the truth that the by-product operator and sum commute. After dividing either side of each equations by -2, we will rearrange this method right into a matrix equation

[i=1Nx(i)2i=1Nx(i)i=1Nx(i)N][mb]=[i=1Nx(i)y(i)i=1Ny(i)].

This technique might be written in compact notation as

Hp=f.

To unravel for $ p=[m,b]^T $ , we will multiply either side by the inverse of H

H1Hp=H1f,

or just

p=H1f.

The MATLAB code to resolve for m and b appears like this:

perform [m, b] = lineFitter(x,y)

 

% Be sure that x and y have the identical variety of parts

assert(numel(x)==numel(y));

% Type the left hand matrix

H = [x(:)’*x(:) sum(x(:),1);

sum(x(:),1) numel(x)];

 

% Type the residual

f = [x(:)’*y(:)

sum(y(:),1)];

 

% Clear up the system

p = Hf;

% Assign the slopes

m = p(1);

b = p(2);

finish

Testing the Becoming Routine In MATLAB

To verify our code, let’s load some information, match the road and plot the whole lot.

d = readmatrix(“myData.csv”);

% Create the road from the fitted parameters

plot(xgrid, ygrid, “LineWidth”, 2);

Generate Code for the Becoming Routine

Now we will generate code and the whole lot we’ll must create a dynamic library from our lineFitter routine. We are going to use coder.config and coder.typeof

% Arrange coder object for a dynamic library

cfg = coder.config(‘dll’);

% Create pattern variables for the inputs. We wish to make these inputs

% dynamically sized as a result of we might have arbitrarily sized information information.

xarg = coder.typeof(1.0, [10000, 1], [1, 0]);

yarg = coder.typeof(1.0, [10000, 1], [1, 0]);

% Generate the code and a report

codegen -config cfg lineFitter.m -args {xarg,yarg} -nargout 2 -report

The code technology report in MATLAB R2022b has a neat characteristic referred to as “Hint Code” that exhibits what MATLAB code corresponds to what C code:

The related code that we’ll want later is the interface to lineFitter. The important thing code is in lineFitter.h:

/* Perform Declarations */

extern void lineFitter(const emxArray_real_T *x, const emxArray_real_T *y,

double *m, double *b);

The inputs are fixed array pointers and the outputs are tips to doubles. This can information our client-side implementation as we’ll present under.

Packaging the Code

Now that we’ve got our code, we will use codebuild and packNgo to generate and package deal construct artifacts that we will take over to our consumer software. On this case we’ll use the CMake and SHARED_LIBRARY choices to codebuild in order that we’ll be capable of use the CMake program to construct the whole lot on our consumer aspect. CMake is a instrument that permits us to carry out platform unbiased compilation of our code. In brief, we will present CMake with an inventory of issues to construct and it’ll carry out all of the checks and compilation for us.

codebuild(‘./codegen/dll/lineFitter’, ‘BuildMethod’, ‘CMake’, ‘BuildVariant’, ‘SHARED_LIBRARY’);

packNGo(‘./codegen/dll/lineFitter’, ‘PackType’, ‘hierarchical’, ‘fileName’, ‘lineFitter’);

This generates an archive file lineFitter.zip, which we will copy to our consumer codebase.

Create the Dynamic Library

Now that we’ve got our code, we’re able to construct it and create a routine to hyperlink to it on the consumer machine. After that we will add the code we have to name our line becoming routine within the consumer code. As an example we put our newly generated lineFitter.zip right here and unzip the whole lot. Unzipping lineFitter.zip will produce two information, mlrFiles.zip and sDirFiles.zip. Unzipping these will create two directories, R2022b and codegen.

C:worklineFitExample> dir /w

[codegen] lineFitter.zip mlrFiles.zip [R2022b] sDirFiles.zip

These include the required MATLAB headers and our generated code, respectively. To construct these, we’ll create a listing referred to as build_lib, then name cmake with the next instructions [2] (their outcomes are proven as properly):

C:worklineFitExample> mkdir build_lib

 

C:workLineFitExample> cmake -G “NMake Makefiles” -B ./build_lib -DCMAKE_BUILD_TYPE=Launch -DMATLAB_ROOT=./R2022b -S./codegen/dll/lineFitter

— The C compiler identification is MSVC 19.29.30137.0

<snip>

— Construct information have been written to: C:/work/LineFitExample/build_lib

 

C:workLineFitExample> cmake –build build_lib

[8/8] Linking CXX shared library codegendlllineFitterlineFitter_win64.dll

### Created library: C:/work/LineFitExample/build_lib/codegen/dll/lineFitter/lineFitter_win64.dll

Utilizing the Dynamic Library

Now that we’ve got generated our dynamic library lineFitter_win64.dll, it is time to create the appliance code that can use the lineFitter routine. Our consumer software reads within the csv file and locations the columns into two lists:

To make this code interface with our newly created dynamic library we have to allocate our arrays. These arrays are of kind emx_Array_real_T as proven above. We’ll write a perform to do the allocation, however first we’ll embrace two header information that we’ll want:

#embrace “lineFitter.h”

#embrace “lineFitter_emxAPI.h”

Now we’re prepared to write down our array allocation perform, which we’ll place above the primary routine. This perform takes an inventory of doubles and copies it into an emxArray_real_T that has been allotted to the correct measurement. An instance of this code might be discovered within the listing .codegendlllineFitterexamplesmain.c.

ArrayHelperFunc.png

Lastly, we’ll add the calls to allocate our vectors and remedy the system under the studying code in the primary routine however earlier than the ultimate return assertion:

LineFitCode.png

Our CMakeLists.txt file for our consumer appears like this:

CMakeFile.png
Now we’re able to compile our consumer software. You possibly can obtain the ensuing information right here: CMakeLists.txt and myFit.cpp. You will additionally want the information file, which is right here in myData.csv.

The process is much like compiling the library above, which is a part of the attraction of CMake. The instructions are:

C:workLineFitExample> mkdir construct

 

C:workLineFitExample> cmake -G “NMake Makefiles” -B construct -S . -DCMAKE_BUILD_TYPE=Launch

— The C compiler identification is MSVC 19.29.30137.0

<snip>

— Construct information have been written to: C:/work/LineFitExample/construct

 

C:workLineFitExample> cmake –build construct

[2/2] Linking CXX executable myFit.exe

Now we’ve got our executable, myFit.exe within the construct listing. The ultimate steps to check our code are:

C:workLineFitExample> set PATH=C:workLineFitExamplebuild_libcodegendlllineFitter;%PATH%

 

C:workLineFitExample> .buildmyFit.exe myData.csv

m,b = 4.04926, -0.0246821

As we will see, the slope and intercept are the identical as what we bought in MATLAB.

Notes

[1] This technique is used for illustration functions solely. In manufacturing, you must use polyfit to resolve this downside.

[2] On this instance, we use Visible Studio instruments to compile the code. To set this up for the command line, I ran the script:

C:Program Information (x86)Microsoft Visible Studio2019ProfessionalVCAuxiliaryBuildvcvars64.bat

Now it is your flip

We hope you loved this instance. Quickly we’ll observe up with a extra complicated instance constructing on this basis. If there are different Coder associated subjects you want to see coated on the weblog, tell us within the remark under.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments