Create Simulink Report Generator Reports
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
Run the following command to access the supporting files used in this example.
openExample('rptgenext/SimulinkReportGeneratorFilesExample');
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 useBlockFinder
.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 tosdd_
followed by the value of theName
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 theTitle
,Subtitle
, andAuthor
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 theImage
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 itsTitle
andContent
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 thefind
function of the block finder. Thefind
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 itsTitle
andContent
properties. Set the sectionTitle
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 asimulink.report.SimulinkObjectProperties
reporter. ThisSimulinkObjectProperties
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
andmlreportgen.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 aDiagram
reporter that creates a snapshot of the subsystem diagram.sysdiagFinder = SystemDiagramFinder(model); sysdiagFinder.IncludeRoot = false;
For more information, see
slreportgen.finder.SystemDiagramFinder
andslreportgen.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 finderhasNext
andnext
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
andslreportgen.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);