Capture Model as Requirements and Create Links
In this step, you use the Requirements Toolbox™ programmatic interface to capture elements from your Simulink® model into a set of proxy slreq.Requirement
objects that have the same hierarchy as your model. You can then use the Description and Rationale properties of the proxy requirement objects to document each element of the design. The example also shows how to create links between the model elements and the proxy requirement objects for traceability.
Open the Models
Open the slvnvdemo_powerwindow_vs
and slvnvdemo_powerwindowController
models. The slvnvdemo_powerwindow_vs
model is a specification model that verifies the functional properties of the design in slvnvdemo_powerwindowController
.
open_system("slvnvdemo_powerwindow_vs"); open_system("slvnvdemo_powerwindowController");
Capture Model as Proxy Requirements
Use the Requirements Toolbox APIs to capture the Simulink models as proxy slreq.Requirement
objects in the Requirements Editor for the slvnvdemo_powerwindow_vs
and slvnvdemo_powerwindowController
models.
First, create an array with the model names to make it easy to make changes to both models.
models = ["slvnvdemo_powerwindow_vs","slvnvdemo_powerwindowController"];
For each model:
Create a requirement set with the same name as the model by using
slreq.new
.Add an
slreq.Requirement
object that corresponds to the top-level model by usingadd
.Open the model.
Use
rmi
to get properties for each model element, including the handle, the index of the parent of the model element, an indicator that shows if the element belongs to a Stateflow® chart, and the SID.
for modelIndex = 1:numel(models) modelName = models(modelIndex); reqSetName = modelName+".slreqx"; myReqSet = slreq.new(reqSetName); topProxy = add(myReqSet,Id=modelName,Summary=modelName+" Description"); open_system(modelName); [elementHandles,parentIndex,isSf,SID] = rmi("getObjectsInModel",modelName);
For each element in the models, get the name and type of the element by using the getNameAndType
function. To view the code for this function, see Helper Functions. Add an slreq.Requirement
object under the slreq.Requirement
object of the parent of the model element in the model hierarchy. Add a summary to the slreq.Requirement
object based on the name and type.
createdProxies(1) = topProxy; for elementIndex = 2:numel(elementHandles) [name,type] = getNameAndType(isSf(elementIndex),elementHandles(elementIndex), ... modelName,SID(elementIndex)); if ~isempty(name) && ~isempty(type) parentProxy = createdProxies(parentIndex(elementIndex)); createdProxies(elementIndex) = add(parentProxy,Id=SID{elementIndex}, ... Summary=name+" ("+type+")"); end end save(myReqSet); end
Open the Requirements Editor to view the requirements.
slreq.editor
Link Requirements and Model Elements
Create links in both the slvnvdemo_powerwindow_vs
and slvnvdemo_powerwindowController
requirement sets to navigate between the slreq.Requirement
object and the corresponding model element.
For each model and its associated requirement set, create an array that contains the requirements.
for modelIndex = 1:numel(models) modelName = models(modelIndex); reqSetName = slreq.find(Type="ReqSet",Name=modelName); proxyRequirements = find(reqSetName,Type="Requirement");
For each requirement in the requirement set other than the top-level requirement:
Get the SID of the associated model element and then get a handle to the model element.
Create a link between the model element and the requirement.
Add a description to the link that includes the index of the linked requirement.
Record the number of created links.
counter = 0; for reqIdx = 1:numel(proxyRequirements) myProxy = proxyRequirements(reqIdx); if ~contains(myProxy.Summary,modelName) sid = strcat(modelName,myProxy.Id); linkSrc = Simulink.ID.getHandle(sid); newLink = slreq.createLink(linkSrc,myProxy); newLink.Description = strcat("Link between requirement ",myProxy.Index, ... " and model element"); counter = counter + 1; end end disp(strcat("Created ",num2str(counter)," links for ",modelName)); end
Created 116 links for slvnvdemo_powerwindow_vs Created 66 links for slvnvdemo_powerwindowController
View the new links in the Requirements Editor by clicking a requirement and, in the right pane, scrolling to the Links section.
Save the link sets.
lsArray = slreq.find(Type="LinkSet");
save(lsArray(1));
save(lsArray(2));
Helper Functions
This function returns the model element name and type. This function skips Stateflow object types other than Stateflow.State
and Stateflow.Transition
.
function [name,type] = getNameAndType(isSf,elementHandle,modelName,SID) if ~isSf name = get_param(elementHandle,"Name"); type = get_param(elementHandle,"BlockType"); else sfObj = Simulink.ID.getHandle(strcat(modelName,SID)); sfType = class(sfObj); switch sfType case 'Stateflow.State' name = sf('get',elementHandle,'.name'); type = strrep(class(sfObj),"Stateflow.",""); case 'Stateflow.Transition' name = sf('get',elementHandle,'.labelString'); type = strrep(class(sfObj),"Stateflow.",""); otherwise warning('Stateflow object of type %s was skipped.',class(sfObj)); name = ""; type = ''; end end end