The Simulink® Report Generator™ Report API comprises a set of objects designed to find and format model and simulation data. You can use these objects with MATLAB® Report API and DOM API objects to create MATLAB programs that generate reports on Simulink models and simulations. The following example illustrates using the Simulink Report API and the MATLAB Report API to create a MATLAB program. This program generates a report on the contents of a Simulink model. The report contains these sections:
Title Page
Table of Contents
Root System Chapter — Contains the root block diagram and properties of each block in the root diagram
Subsystems Chapter -- Contains the diagram and block properties of each subsystem of the model
Stateflow® Charts Chapter -- Contains charts and chart object properties of each chart in the model
Import the API functions.
To eliminate the need to use fully qualified names of Report, Finder, and DOM API
functions, use these statements. For example, instead of using
slreportgen.finder.BlockFinder
, you can use
BlockFinder
.
import slreportgen.report.* import slreportgen.finder.* import mlreportgen.report.*
Load the sf_car
model.
model = load_system('sf_car');
Create a report object.
Use a Simulink report constructor (slreportgen.report.Report
) to create
a report object to hold the contents of the report. You must fully qualify the name
of the constructor to distinguish it from the MATLAB report constructor (mlreportgen.report.Report
). Set the
name of the report to sdd_
followed by the value of the
Name
property of the model.
rpt = slreportgen.report.Report(['sdd_'... get_param('sf_car','Name')],'pdf');
To customize properties that apply to the whole report, see slreportgen.report.Report
.
Add a title page.
Use a title page reporter constructor
(mlreportgen.report.TitlePage
) to create a title page reporter. This
reporter generates a title page based on its properties. Set the
Title
, Subtitle
, and
Author
properties to character arrays that specify the report
title, subtitle, and author, respectively.
Use a diagram reporter constructor (slreportgen.report.Diagram
) to
create a diagram reporter for this model. This reporter generates an image of the
block diagram of the model. To include this image on the report title page, assign
the diagram reporter to the Image
property of the title page
reporter. Then, add the title page to the report.
tp = TitlePage; tp.Title = upper(get_param(model,'Name')); tp.Subtitle = 'System Design Description'; tp.Author = 'MathWorks'; tp.Image = Diagram(model); append(rpt,tp);
To customize additional title page properties, see mlreportgen.report.TitlePage
.
Add a table of contents.
Use a table of contents (TOC) reporter constructor to create a TOC reporter. This reporter generates a TOC for the report. Add the TOC reporter to the report.
toc = TableOfContents; append(rpt,toc);
To customize the table of contents, see mlreportgen.report.TableOfContents
.
Add a chapter for the root system.
Use a chapter constructor (mlreportgen.report.Chapter
) to create a
chapter reporter. This reporter generates a chapter based on its
Title
and Content
properties. The
reporter automatically numbers the chapter title. The chapter reporter also generates
the chapter page headers and footers and its page numbers.
Add a model diagram reporter to the chapter. This reporter returns an image of the block diagram of the model that you add to the chapter.
ch = Chapter("Title","RootSystem"); append(ch,Diagram(model));
For information on customizing chapters, see mlreportgen.report.Chapter
.
Add chapter sections for each root system block.
Use the block finder constructor (slreportgen.report.BlockFinder
)
to create a block finder for the root diagram. Then, use the find
function of the block finder. The find
function returns an array of
block result objects (slreportgen.report.BlockResult
), each of which
contains a block.
Loop through the block result objects. For each result, construct a section
reporter (mlreportgen.report.Section
). This reporter generates a
numbered report section based on its Title
and
Content
properties. Set the section
Title
property to the name of the block on which it reports.
Add the current block result to the section reporter. Adding the result sets the
section reporter Content
property to a
simulink.report.SimulinkObjectProperties
reporter. This
SimulinkObjectProperties
reporter generates a table of the
properties of the current block, which is then added to the section. Add each
subsection to the parent chapter. Then add the chapter to the report.
blkFinder = BlockFinder(model); blocks = find(blkFinder); for block = blocks section = Section("Title", ... strrep(block.Name, newline,' ')); append(section,block); append(ch,section); end append(rpt,ch);
For information finding blocks and how to customize sections, see slreportgen.finder.BlockFinder
and mlreportgen.report.Section
, respectively.
Add a chapter for subsystems.
Create a chapter for the subsystems of the model and the blocks in each subsystem.
ch = Chapter("Title","Subsystems");
Find subsystem diagrams in the model.
Find all subsystem diagrams in the model. The finder returns an array of
DiagramResult
objects, each of which contains a
Diagram
reporter that creates a snapshot of the subsystem
diagram.
sysdiagFinder = SystemDiagramFinder(model); sysdiagFinder.IncludeRoot = false;
For more information, see slreportgen.finder.SystemDiagramFinder
and slreportgen.finder.DiagramResult
Add results to chapter sections.
Using loops, create a chapter section for each subsystem. Find the blocks and block elements in each subsystem. Add a table of block elements to each chapter section and add each section to the chapter. Then, add the chapter to the report.
while hasNext(sysdiagFinder) system = next(sysdiagFinder); section1 = Section("Title",system.Name); append(section1,system); blkFinder1 = BlockFinder(system); elems = find(blkFinder1); for elem = elems section2 = Section("Title",... strrep(elem.Name,newline,' ')); append(section2,elem); append(section1,section2); end append(ch,section1); end append(rpt,ch);
Note
Simulink finders can operate in either array or iterator mode. In array mode,
use the finder find
function to return the search results as an
array of results. In iterator mode, use the finder hasNext
and
next
functions to return the search results one-by-one. Use
iterator mode when searching for diagrams in models that have many model
references. Iterator mode closes a model after compiling and searching it, whereas
find mode keeps all the models that it searches open. Having many open models can
potentially consume all system memory and slow report generation. Although the
model used in this example does not contain model references, the example uses
iterator mode to illustrate its syntax.
Add a chapter for Stateflow charts and objects.
Find all Stateflow charts in the model. Create a chapter. Using loops, add subsections for each chart. Find all the elements in each chart and add them to the subsections. Then, add the section to the chapter and the chapter to the report.
ch = Chapter("Title", "Stateflow Charts"); chdiagFinder = ChartDiagramFinder(model); while hasNext(chdiagFinder) chart = next(chdiagFinder); section = Section("Title",chart.Name); append(section,chart); objFinder = StateflowDiagramElementFinder(chart); sfObjects = find(objFinder); for sfObj = sfObjects title = sfObj.Name; if isempty(title) title = sfObj.Type; end objSection = Section("Title",title); append(objSection,sfObj); append(section,objSection); end append(ch,section); end append(rpt,ch);
For information on chart and diagram element finders, see slreportgen.finder.ChartDiagramFinder
and slreportgen.finder.StateflowDiagramElementFinder
.
Close the report, run the report, and close the model.
close(rpt); rptview(rpt); close_system(model);
The complete code is:
import slreportgen.report.* import slreportgen.finder.* import mlreportgen.report.* model = load_system('sf_car'); rpt = slreportgen.report.Report(['sdd_'... get_param('sf_car','Name')],'pdf'); tp = TitlePage; tp.Title = upper(get_param(model,'Name')); tp.Subtitle = 'System Design Description'; tp.Author = 'MathWorks'; tp.Image = Diagram(model); append(rpt,tp); toc = TableOfContents; append(rpt,toc); ch = Chapter("Title","RootSystem"); append(ch,Diagram(model)); blkFinder = BlockFinder(model); blocks = find(blkFinder); for block = blocks section = Section("Title", ... strrep(block.Name, newline, ' ')); append(section,block); append(ch,section); end append(rpt,ch); ch = Chapter("Title","Subsystems"); sysdiagFinder = SystemDiagramFinder(model); sysdiagFinder.IncludeRoot = false; while hasNext(sysdiagFinder) system = next(sysdiagFinder); section1 = Section("Title",system.Name); append(section1,system); blkFinder1 = BlockFinder(system); elems = find(blkFinder1); for elem = elems section2 = Section("Title",... strrep(elem.Name, newline, ' ')); append(section2,elem); append(section1,section2); end append(ch,section1); end append(rpt,ch); ch = Chapter("Title", "Stateflow Charts"); chdiagFinder = ChartDiagramFinder(model); while hasNext(chdiagFinder) chart = next(chdiagFinder); section = Section("Title",chart.Name); append(section,chart); objFinder = StateflowDiagramElementFinder(chart); sfObjects = find(objFinder); for sfObj = sfObjects title = sfObj.Name; if isempty(title) title = sfObj.Type; end objSection = Section("Title",title); append(objSection,sfObj); append(section,objSection); end append(ch,section); end append(rpt,ch); close(rpt); rptview(rpt); close_system(model);