Main Content

本页采用了机器翻译。点击此处可查看英文原文。

捕获模型作为需求并创建链接

在此步骤中,您使用 Requirements Toolbox™ 编程接口将 Simulink®模型中的元素捕获到一组与您的模型具有相同层次结构的代理 slreq.Requirement 对象中。然后,您可以使用代理需求对象的 DescriptionRationale属性来记录设计的每个元素。该示例还展示了如何在模型元素和代理需求对象之间创建链接以实现可追溯性。

打开模型

打开slvnvdemo_powerwindow_vsslvnvdemo_powerwindowController模型。slvnvdemo_powerwindow_vs 模型是一个规范模型,用于验证 slvnvdemo_powerwindowController 中设计的功能属性。

open_system("slvnvdemo_powerwindow_vs");
open_system("slvnvdemo_powerwindowController");

捕获模型作为代理需求

使用 Requirements Toolbox API 将 Simulink 模型捕获为需求编辑器slvnvdemo_powerwindow_vsslvnvdemo_powerwindowController 模型的代理 slreq.Requirement 对象。

首先,创建一个包含模型名称的数组,以便轻松对两个模型进行更改。

models = ["slvnvdemo_powerwindow_vs","slvnvdemo_powerwindowController"];

对于每个模型:

  • 使用 slreq.new 创建与模型同名的需求集。

  • 使用 add 添加与顶层模型相对应的 slreq.Requirement 对象。

  • 打开模型。

  • 使用 rmi 获取每个模型元素的属性,包括句柄、模型元素父级的索引、显示元素是否属于 Stateflow® 图的指示器以及 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);

对于模型中的每个元素,使用 getNameAndType 函数获取元素的名称和类型。要查看该函数的代码,请参阅辅助函数。在模型层次结构中模型元素父级的slreq.Requirement对象下添加一个slreq.Requirement对象。根据名称和类型向slreq.Requirement对象添加摘要。

    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

打开需求编辑器查看需求。

slreq.editor

Requirements Editor showing the created requirements.

链接需求和模型元素

slvnvdemo_powerwindow_vsslvnvdemo_powerwindowController需求集集中创建链接,以便在 slreq.Requirement 对象和相应的模型元素之间导航。

对于每个模型及其相关需求集,创建一个包含需求的数组。

for modelIndex = 1:numel(models)
    modelName = models(modelIndex);
    reqSetName = slreq.find(Type="ReqSet",Name=modelName);
    proxyRequirements = find(reqSetName,Type="Requirement");

对于需求集除顶级需求之外的每个需求:

  • 获取关联模型元素的 SID,然后获取该模型元素的句柄。

  • 在模型元素和需求之间创建链接。

  • 为链接添加描述,其中包括链接需求的索引。

  • 记录创建的链接数量。

    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

通过点击某个需求并在右侧窗格中滚动到链接部分,可以查看需求编辑器中的新链接。

A requirement is selected in the Requirements Editor and a link to the associated model element is displayed.保存链接集。

lsArray = slreq.find(Type="LinkSet");
save(lsArray(1));
save(lsArray(2));

辅助函数

该函数返回模型元素名称和类型。此函数跳过除 Stateflow.StateStateflow.Transition 之外的 Stateflow 对象类型。

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

另请参阅

App

函数

相关主题