Code Generation
Code Generation Use and Benefits
You can use the Phased Array System Toolbox™ software together with the MATLAB® Coder™ product to create C/C++ code that implements your MATLAB functions and models. With this software, you can
Create a MEX file to speed up your own MATLAB application.
Generate a stand-alone executable that runs independently of MATLAB on your own computer or another platform.
Include System objects in the same way as any other element.
In general, the code you generate using the toolbox is portable ANSI® C code. In order to use code generation, you need a MATLAB Coder license. Using Phased Array System Toolbox software requires licenses for both the DSP System Toolbox™ and the Signal Processing Toolbox™. See the Get Started with MATLAB Coder (MATLAB Coder) page for more information.
Creating a MATLAB Coder MEX-file can lead to substantial acceleration of your MATLAB algorithms. It is also a convenient first step in a workflow that ultimately leads to completely standalone code. When you create a MEX-file, it runs in the MATLAB environment. Its inputs and outputs are available for inspection just like any other MATLAB variable. You can use MATLAB visualization and other tools for verification and analysis.
Within your code, you can run specific commands either as generated C code or by
running using the MATLAB engine. In cases where an isolated command does not yet have code
generation support, you can use the coder.extrinsic
(MATLAB Coder) command to embed the
command in your code. This means that the generated code reenters the MATLAB environment when it needs to run that particular command. This also
useful if you wish to embed certain commands that cannot generate code (such as
plotting functions).
The simplest way to generate MEX-files from your MATLAB code is by using the codegen
(MATLAB Coder) function at the command
line. Often, generating a MEX-files involves nothing more than invoking the
coder
command on one of your existing functions. For example,
if you have an existing function, myfunction.m
, you can type the
commands at the command line to compile and run the MEX function. codegen
(MATLAB Coder) adds a platform-specific
extension to this name. In this case, the "mex"
suffix is added.
codegen myfunction.m
myfunction_mex;
You can generate standalone executables that run independently of the MATLAB environment. You can do this by creating a MATLAB
Coder project inside the MATLAB
Coder Integrated Development Environment (IDE). Alternatively, you can issue
the codegen
(MATLAB Coder) command in the command line
environment with appropriate configuration parameters. To create a standalone
executable, you must write your own main.c
or
main.cpp
function. See Generating Standalone C/C++ Executables from MATLAB Code (MATLAB Coder) for more information.
Set Up Your Compiler
Before using codegen
(MATLAB Coder) to compile your code,
you must set up your C/C++ compiler. For 32-bit Windows platforms, MathWorks® supplies a default compiler with MATLAB. If your installation does not include a default
compiler, you can supply your own compiler. For the current list of supported
compilers, see Supported and
Compatible Compilers on the MathWorks Web site. Install a compiler that is suitable for your platform.
Then, read Setting Up the C or C++ Compiler (MATLAB Coder).
After installation, at the MATLAB
command prompt, run mex -setup
. You can then use the
codegen
(MATLAB Coder) function to compile your
code.
Functions and System Objects That Support Code Generation
Almost all Phased Array System Toolbox functions and System objects are supported for code generation. For a list of supported functions and System objects, see Function List (C/C++ Code Generation).
Limitations Specific to Phased Array System Toolbox
Code Generation has the following limitations when used with the Phased Array System Toolbox software:
When you employ antennas and arrays that produce polarized fields, the
EnablePolarization
parameter for these System objects must be set totrue
:This requirement differs from regular MATLAB usage where you can set
EnablePolarization
property tofalse
even when you use a polarization-enabled antenna. For example, this code uses a polarized antenna, which requires thatEnablePolarization
property of thephased.Radiator
System object™ be set totrue
.function [y] = codegen_radiator() sSD = phased.ShortDipoleAntennaElement(... 'FrequencyRange',[100e6,600e6],'AxisDirection','Y'); c = physconst('LightSpeed'); fc = 200e6; lambda = c/fc; d = lambda/2; sURA = phased.URA('Element',sSD,... 'Size',[3,3],... 'ElementSpacing',[d,d]); sRad = phased.Radiator('Sensor',sURA,... 'OperatingFrequency',150e6,... 'CombineRadiatedSignals',true,... 'EnablePolarization',true); x = [1;2;1]; radiatingAngle = [10;0]; % One angle for one antenna y = sRad(x,radiatingAngle,eye(3,3));
Visualization methods for Phased Array System Toolbox System objects are not supported. These methods are
pattern
,patternAzimuth
,patternElevation
,plot
,plotResponse
, andviewArray
.When a System object contains another System object as a property value, you must set the contained System object in the constructor. You cannot use Object Property notation to set the property. For example
is valid forantenna = phased.ShortDipoleAntennaElement( ... 'FrequencyRange',[100e6,600e6],'AxisDirection','Y'); array = phased.URA('Element',antenna,'Size',[3,3], ... 'ElementSpacing',[0.75,0.75]);
codegen
(MATLAB Coder) butis not.antenna = phased.ShortDipoleAntennaElement( ... 'FrequencyRange',[100e6,600e6],'AxisDirection','Y'); array = phased.URA('Size',[3,3],'ElementSpacing',[0.75,0.75]); array.Element = antenna;
Code generation of Phased Array System Toolbox arrays that contain Antenna Toolbox™ antennas is not supported.
A list of the limitations on Phased Array System Toolbox functions and System objects is presented here:
Function or System Object Limitation plotResponse
This System object method is not supported. pattern
This System object method is not supported. patternAzimuth
This System object method is not supported. patternElevation
This System object method is not supported. plot
This System object method is not supported. viewArray
This System object method is not supported. ambgfun
Supported only when output arguments are specified. pambgfun
Supported only when output arguments are specified. polsignature
Supported only when output arguments are specified. rocpfa
Supported only when output arguments are specified.
The
NonfluctuatingNoncoherent
signal type is not supported.
rocsnr
Supported only when output arguments are specified.
The
NonfluctuatingNoncoherent
signal type is not supported.
stokes
Supported only when output arguments are specified. phased.ArrayGain
This System object cannot be used with arrays that contain antenna elements that create polarized signals, that is, phased.ShortDipoleAntennaElement
orphased.CrossedDipoleAntennaElement
phased.IntensityScope
This System object is not supported. phased.MatchedFilter
The CustomSpectrumWindow
property is not supported.phased.RangeDopplerResponse
The CustomRangeWindow
and theCustomDopplerWindow
properties are not supported.phased.ScenarioViewer
This System object is not supported.
General Limitations
Code Generation has some general limitations not specifically related to the Phased Array System Toolbox software. For a more complete discussion, see System Objects in MATLAB Code Generation (MATLAB Coder).
The data type and complexity (i.e., real or complex) of any input argument to a function or System object must always remain the same.
You cannot pass a System object to any method or function that you made extrinsic using
coder.extrinsic
(MATLAB Coder).You cannot load a MAT-file using
coder.load
(MATLAB Coder) when it contains a System object. For example, if you construct a System object in the MATLAB environment and save it to a MAT-filethen you cannot load the System object in your compiled MEX-file:sSD = phased.ShortDipoleAntennaElement(... 'FrequencyRange',[0.9e8,2e9],'AxisDirection','Y'); save x.mat sSD; clear sSD;
The compilationfunction codegen_load1() W = coder.load('x.mat'); sSD = W.sSD;
will produced an error message:codegen codegen_load1
'Found unsupported class for variable using function 'coder.load'. MATLAB class 'phased.ShortDipoleAntennaElement' found at 'W.sSD' is unsupported.'
To avoid this problem, you can save the object's properties to a MAT-file, then, use
coder.load
(MATLAB Coder) to load the object properties and re-create the object. For example, create and save a System object’s properties in the MATLAB environmentsSD = phased.ShortDipoleAntennaElement(... 'FrequencyRange',[0.9e8,2e9],'AxisDirection','Y'); FrequencyRange = sSD.FrequencyRange; AxisDirection = sSD.AxisDirection; save x.mat FrequencyRange AxisDirection;
Then, write a function
codegen_load2
to load the properties and create a System object.Then, issue the commands to create and execute the MEX-file,function codegen_load2() W = coder.load('x.mat'); sSD = phased.ShortDipoleAntennaElement(... 'FrequencyRange',W.FrequencyRange,... 'AxisDirection',W.AxisDirection);
codegen_load2_mex
.codegen codegen_load2; codegen_load2_mex
System object properties are either tunable or nontunable. Unless otherwise specified, System object properties are nontunable. Nontunable properties must be constant. A constant is a value that can be evaluated at compile-time. You can change tunable properties even if the object is locked. Refer to the object's reference page to determine whether an individual property is tunable or not. If you try to set a nontunable System object property and the compiler determines that it is not constant, you will get an error. For example, the
phased.URA
System object has a nontunable property,ElementSpacing
, which sets the distance between elements. You may want to create an array that is tuned to a frequency. You cannot pass in the frequency as an input argument because the frequency must be a constant.function [resp] = codegen_const1(fc) sSD = phased.ShortDipoleAntennaElement(... 'FrequencyRange',[100e6,600e6],'AxisDirection','Y'); c = physconst('LightSpeed'); lambda = c/fc; d = lambda/2; sURA = phased.URA('Element',sSD,... 'Size',[3,3],... 'ElementSpacing',[d,d]); ang = [30;0]; resp = sURA(fc,ang);
When you
codegen
this functionfc = 200e6; codegen codegen_const1 -args {fc}
the compiler responds that the value of the
'ElementSpacing'
property,d
, is not constant and generates the error message:"Failed to compute constant value for nontunable property 'ElementSpacing'. In code generation, nontunable properties can only be assigned constant values."
It is not constant because it depends upon a non-constant variable,fc
.To correct this problem, set
fc
to a constant within the function:and then compilefunction [resp] = codegen_const2() sSD = phased.ShortDipoleAntennaElement(... 'FrequencyRange',[100e6,600e6],'AxisDirection','Y'); c = physconst('LightSpeed'); fc = 200e6; lambda = c/fc; d = lambda/2; sURA = phased.URA('Element',sSD,... 'Size',[3,3],... 'ElementSpacing',[d,d]); ang = [30;0]; resp = sURA(fc,ang);
codegen codegen_const2
You can assign a nontunable System object property value only once before you call the object. This requirement differs from MATLAB usage where you can initialize these properties multiple times before calling the object.
This example sets the
Size
property twice.function codegen_property sSD = phased.ShortDipoleAntennaElement(... 'FrequencyRange',[0.9e8,2e9],'AxisDirection','Y'); sURA = phased.URA('Element',sSD,... 'Size',[3,3],... 'ElementSpacing',[0.15,0.15]); sURA.Size = [4,4];
When you issue the command
codegen codegen_property
the following error message is produced:
"A nontunable property may only be assigned once."
In certain cases, the compiler cannot determine the values of nontunable properties at compile time or the code may not even compile. Consider the following example that reads in the x,y,z-coordinates of a 5-element array from a file and then, creates a conformal array System object. The text file,
elempos.txt
, contains the element coordinatesThe file-0.5000 -0.2588 0 0.2588 0.5000 -0.8660 -0.9659 -1.0000 -0.9659 -0.8660 0 0 0 0 0
collectWave.m
contains reads the element coordinates and creates the object.Attempting to compilefunction y = collectWave(angle) elPos = calcElPos; cArr = phased.ConformalArray('ElementPosition',elPos); y = collectPlaneWave(cArr,randn(4,2),angle,1e8); end function elPos = calcElPos fid = fopen('elempos.txt','r'); el = textscan(fid, '%f'); n = length(el{1}); nelem = n/3; fclose(fid); elPos = reshape(el{1},nelem,3).'; end
produces the errorcodegen collectWave -args {[10 30]}
"Permissions 'r' and 'r+' are not supported"
.The following example is a work-around that uses
coder.extrinsic
(MATLAB Coder) andcoder.const
(MATLAB Coder) to ensure that the value for the nontunable property,'ElementPosition'
, is a compile time constant. The function in the file,collectWave1.m
, creates the object using thecalcElPos
function. This function runs inside the MATLAB interpreter at compile time.The filefunction y = collectWave1(angle) coder.extrinsic('calcElPos') elPos = coder.const(calcElPos); cArr = phased.ConformalArray('ElementPosition',elPos); y = collectPlaneWave(cArr,randn(4,2),angle,1e8); end
calcElPos.m
loads the element positions from the text filefunction elPos = calcElPos fid = fopen('elempos.txt','r'); el = textscan(fid, '%f'); n = length(el{1}); nelem = n/3; fclose(fid); elPos = reshape(el{1},nelem,3).';
Only the
collectWave1.m
file is compiled withcodegen
(MATLAB Coder). Compiling and runningwill succeed.codegen collectWave1 -args {[10 30]} collectWave1_mex([10,30])
An alternate work-around uses
coder.load
(MATLAB Coder) to ensure that the value of the nontunable property'ElementPosition'
is compile-time constant. In the MATLAB environment, runcalcElPos2
to save the array coordinates contained inelempos.txt
to a MAT-file. Then, load the contents of the MAT-file within the compiled code.The filefunction calcElPos2 fid = fopen('elempos.txt'); el = textscan(fid, '%f'); fclose(fid); elPos = reshape(el{1},[],3).'; save('positions', 'elPos'); end
collectWave2.m
loads the coordinate positions and creates the conformal array objectOnly thefunction y = collectWave2(angle) var = coder.load('positions'); cArr = phased.ConformalArray('ElementPosition',var.elPos); y = collectPlaneWave(cArr,randn(4,2),angle,1e8); end
collectWave2.m
file is compiled withcodegen
(MATLAB Coder). Compiling and runningcollectWave2.m
will succeed. This second approach is more general than the first since a MAT-file can contain any variables, except System objects.codegen collectWave2 -args {[10 30]} collectWave2_mex([10,30])
The System object
clone
method is not supported.
Limitations for System Objects that Require Dynamic Memory Allocation
System objects that require dynamic memory allocation cannot be used for code generation in the following cases:
Inside a MATLAB Function block in a Simulink® model. |
Inside a MATLAB function in a Stateflow® chart. |
When using MATLAB as the action language in a Stateflow chart. |
Inside a Truth Table block in a Simulink model. |
Inside a MATLAB System block (except for normal mode). |
When using Simulink Coder for code generation. |
When using MATLAB Coder for code generation and dynamic memory allocation is disabled. |