首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐
2025年6月14日 星期六 9:42am

Matlab编程技巧:自定义Model Advisor检查规则

  • 23-09-22 00:44
  • 2925
  • 8653
blog.csdn.net

文章目录

  • 1 Model Advisor简介
  • 2 自定义Model Advisor检查规则
    • 2.1 需求目标
    • 2.2 脚本代码及含义解释
      • sl_customization函数
      • defineModelAdvisorTasks回调函数
      • defineModelAdvisorChecks回调函数
      • 4 CheckGainCallback回调函数
    • 2.3 验证自定义检查规则
  • 3 参考资料

1 Model Advisor简介

Model Advisor是Simulink自带的模型静态检查工具。Model Advisor可以根据预先设定好的检查规则,对Simulink模型进行检查,可检查对象包括模块&信号线配置参数、数据类型、数据字典等。汽车行业相关的一些检查规范包括MAAB,JMAAB等。

在Simulink环境下,点击Analysis——Model Advisor——Model Advisor,然后选择子系统或者整个模型,即可进入Model Advisor界面。
在这里插入图片描述
选中左侧浏览器的检查项目,右侧就会切换为相应的介绍以及检查按钮。也可以同时选择多条检查项目进行检查。点击Run This Check后会显示检查结果。
在这里插入图片描述

2 自定义Model Advisor检查规则

团队在开发模型的过程中,会逐渐积累经验,形成一套适用于自己项目的开发标准。通过Matlab编程,可以将这些标准融入Model Advisor中,形成一套自定义的检查规则。本文以Gain模块的输出类型为例,说明自定义Model Advisor检查规则的方法。

2.1 需求目标

假设现在要做一个检查规范:所有gain模块的输出数据类型必须指定明确的类型,而不能继承。相关配置在Gain模块中的Block Parameters中。
在这里插入图片描述
最终效果如图所示,在一个自定义Group中定义了一个规范Check the output type of Gain,点击其中的Run This Check后,就能将不符合规范的Gain模块路径显示出来。
在这里插入图片描述

2.2 脚本代码及含义解释

首先,在Matlab的当前路径或搜索路径下建立m文件sl_customization.m,写入以下源代码并保存。

function sl_customization(cm)
cm.addModelAdvisorCheckFcn(@defineModelAdvisorChecks);%添加自定义检查项
cm.addModelAdvisorTaskAdvisorFcn(@defineModelAdvisorTasks);%添加自定义任务(用于封装检查项)
end

function defineModelAdvisorTasks
%获取ModelAdvisor的Root对象用于注册
mdladvRoot = ModelAdvisor.Root;
%创建ModelAdvisor的Group对象
MAG = ModelAdvisor.Group('com.mathworks.sample.GroupSample1');
MAG.DisplayName = 'Customization Group';
MAG.Description = 'Group of Customization Checks';
%创建ModelAdvisor的Task对象
MAT = ModelAdvisor.Task('com.mathworks.sample.TaskSample1');
MAT.DisplayName = 'Check output data type of Gain Block.';
MAT.setCheck('CheckSample1'); %这里指定了该Task包含的Check ID,与后面的defineModelAdvisorChecks函数对应
mdladvRoot.register(MAT);
MAG.addTask(MAT);
%发布Group对象
mdladvRoot.publish(MAG);
end

function defineModelAdvisorChecks
%获取ModelAdvisor的Root对象用于注册
mdladvRoot = ModelAdvisor.Root;
%创建ModelAdvisor的Check对象
rec = ModelAdvisor.Check('CheckSample1');%声明自定义检查项,括号内为CheckID,必须唯一且固定,之后用于查找该检查项
rec.Title = 'Check output data type of Gain Block.';%检查项的显示标题
rec.TitleTips = 'Check output data type of Gain Block.If output datatype is inherited,the check result will be set to Fail.';%检查项的辅助标题
rec.setCallbackFcn(@CheckGainCallback,'None','StyleOne');%检查项的执行函数,CheckGainCallback是后面定义的函数
%发布Check对象
mdladvRoot.publish(rec,'Demo');
end

function ResultDescription = CheckGainCallback(system) %检查项的执行函数
mdladvObj = Simulink.ModelAdvisor.getModelAdvisor(system);
%初始化检查状态为true
ResultStatus = true;
ResultDescription = {};
mdladvObj.setCheckResultStatus(ResultStatus);
%创建ModelAdvisor的FormatTemplate对象,该对象为检查结果模板
ft = ModelAdvisor.FormatTemplate('ListTemplate');
checkDescStr = 'Check the output type of Gain';
setCheckText(ft,checkDescStr);
%参考信息
docLinksFunction{1} = {'Modeling Standard xxxx'};
setRefLink(ft,docLinksFunction);
setSubBar(ft,false);
%检查方法定义,ErrorBlockCell存储所有未通过检查的模块的路径(重要)
BlockCell = find_system(system,'BlockType','Gain');%搜索出所有Gain模块
ErrorBlockCell = {};
for index = 1:length(BlockCell)
    Block = BlockCell{index};
    OutDataType = get_param(Block,'OutDataTypeStr');
    if contains(OutDataType,'Inherit')%判断OutDataTypeStr是否是Inherit,是则加入ErrorBlockCell
        ErrorBlockCell{end+1} = Block;
    end
end
%检查结果显示
if isempty(ErrorBlockCell)  %ErrorBlockCell为空则说明全部通过检查
    setSubResultStatus(ft,'Pass');
    setSubResultStatusText(ft,'All of output data types are correct.');
    ResultStatus = true;
else
    setSubResultStatus(ft,'Fail');
    setSubResultStatusText(ft,'Data types should not be inherited from others.');
    setRecAction(ft,'Modify data types.');
    setListObj(ft,ErrorBlockCell);%列出所有Gain路径
    ResultStatus = false;
end
ResultDescription{end+1} = ft;
mdladvObj.setCheckResultStatus(ResultStatus);
mdladvObj.setCheckErrorSeverity(1);
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74

脚本中包含了4个函数。

sl_customization函数

第一个函数sl_customization与脚本名称对应,是Simulink的自定义函数。用户可以通过该函数自定义一些Simulink的功能。该函数下分别调用了addModelAdvisorCheckFcn和addModelAdvisorTaskAdvisorFcn函数。

function sl_customization(cm)
cm.addModelAdvisorCheckFcn(@defineModelAdvisorChecks);%添加自定义检查项
cm.addModelAdvisorTaskAdvisorFcn(@defineModelAdvisorTasks);%添加自定义任务(用于封装检查项)
end
  • 1
  • 2
  • 3
  • 4

addModelAdvisorCheckFcn函数用于添加Model Advisor检查函数,他的第一个参数为检查的回调函数defineModelAdvisorChecks,这个回调函数会在后面定义。

defineModelAdvisorTasks函数用于添加Model Advisor任务函数,他的第一个参数为任务的回调函数defineModelAdvisorTasks,这个回调函数也会在后面定义。

defineModelAdvisorTasks回调函数

该函数为任务函数,用于定义Model中的Group和Task。

1.首先获取ModelAdvisor的Root对象用于注册。

%获取ModelAdvisor的Root对象用于注册
mdladvRoot = ModelAdvisor.Root;
  • 1
  • 2

2.在函数中定义Group。Group可以理解为装有检查规范的文件夹。

%创建ModelAdvisor的Group对象
MAG = ModelAdvisor.Group('com.mathworks.sample.GroupSample1');
MAG.DisplayName = 'Customization Group';
MAG.Description = 'Group of Customization Checks';
  • 1
  • 2
  • 3
  • 4

Group的名字为Customization Group,描述为Group of Customization Checks。最后会生成到Model Advisor界面中。
在这里插入图片描述
3.创建ModelAdvisor的Task对象。Task对象代表每一条检查任务。

%创建ModelAdvisor的Task对象
MAT = ModelAdvisor.Task('com.mathworks.sample.TaskSample1');
MAT.DisplayName = 'Check output data type of Gain Block.';
MAT.setCheck('CheckSample1'); %这里指定了该Task包含的Check ID,与后面的defineModelAdvisorChecks函数对应
mdladvRoot.register(MAT);
MAG.addTask(MAT);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

其中,定义了Task ID号,显示名称以及其包含的Check ID。Check ID会在后面的Check函数中定义。最后将Task对象添加到各个定义的Group中。

4.发布Group对象。

%发布Group对象
mdladvRoot.publish(MAG);
  • 1
  • 2

defineModelAdvisorChecks回调函数

该函数为检查函数,用于定义Model Advisor中的检查项。这里只是定义该检查项在Model Advisor中的显示,而不具备检查执行的功能。执行的功能会在该函数内再调用第四个回调函数。

1.获取ModelAdvisor的Root对象用于注册。

%获取ModelAdvisor的Root对象用于注册
mdladvRoot = ModelAdvisor.Root;
  • 1
  • 2

2.创建ModelAdvisor的Check对象

%创建ModelAdvisor的Check对象
rec = ModelAdvisor.Check('CheckSample1');%声明自定义检查项,括号内为CheckID,必须唯一且固定,之后用于查找该检查项
rec.Title = 'Check output data type of Gain Block.';%检查项的显示标题
rec.TitleTips = 'Check output data type of Gain Block.If output datatype is inherited,the check result will be set to Fail.';%检查项的辅助标题
rec.setCallbackFcn(@CheckGainCallback,'None','StyleOne');%检查项的执行函数,CheckGainCallback是后面定义的函数
  • 1
  • 2
  • 3
  • 4
  • 5

这一步中会创建Check对象的ID号,这个ID必须和上文中Task的ID对应起来。然后会定义其显示标题和副标题。最后设置回调函数,这里调用的回调函数CheckGainCallback才是真正执行检查的函数。
在这里插入图片描述
3.发布Check对象

%发布Check对象
mdladvRoot.publish(rec,'Demo');
  • 1
  • 2

4 CheckGainCallback回调函数

CheckGainCallback回调函数是具备检查功能的执行函数,它会输出检查结果是否通过,以及哪些地方不通过。
1.定义一个变量ResultStatus用于存放检查结果,初始化为true。

%初始化检查状态为true
ResultStatus = true;
ResultDescription = {};
mdladvObj.setCheckResultStatus(ResultStatus);
  • 1
  • 2
  • 3
  • 4

2.创建ModelAdvisor的FormatTemplate对象,该对象为检查结果模板

%创建ModelAdvisor的FormatTemplate对象,该对象为检查结果模板
ft = ModelAdvisor.FormatTemplate('ListTemplate');
checkDescStr = 'Check the output type of Gain';
setCheckText(ft,checkDescStr);
%参考信息
docLinksFunction{1} = {'Modeling Standard xxxx'};
setRefLink(ft,docLinksFunction);
setSubBar(ft,false);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

检查结果模板中定义了检查描述,参考信息等。在后面的检查脚本完成后还会对其增加新的属性描述。

3.检查方法定义。

%检查方法定义,ErrorBlockCell存储所有未通过检查的模块的路径(重要)
BlockCell = find_system(system,'BlockType','Gain');%搜索出所有Gain模块
ErrorBlockCell = {};
for index = 1:length(BlockCell)
    Block = BlockCell{index};
    OutDataType = get_param(Block,'OutDataTypeStr');
    if contains(OutDataType,'Inherit')%判断OutDataTypeStr是否是Inherit,是则加入ErrorBlockCell
        ErrorBlockCell{end+1} = Block;
    end
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

这一部分是整个检查的功能核心,它对Simulink模块进行搜索并判断输出类型。完成后,将不符合规范的类型放入ErrorBlockCell中。

这一部分会用到许多通过Matlab脚本获取Simulink模型信息的方法,详见我之前的几篇博客:
Matlab技巧(二) 通过脚本获取/修改Simulink模块参数
Matlab技巧(三) 通过脚本获取/修改Simulink信号线参数
Matlab技巧(四) 通过脚本创建/修改Simulink数据字典
Matlab技巧(五) 通过脚本获取/修改Stateflow参数
3.检查结果显示。

%检查结果显示
if isempty(ErrorBlockCell)  %ErrorBlockCell为空则说明全部通过检查
    setSubResultStatus(ft,'Pass');
    setSubResultStatusText(ft,'All of output data types are correct.');
    ResultStatus = true;
else
    setSubResultStatus(ft,'Fail');
    setSubResultStatusText(ft,'Data types should not be inherited from others.');
    setRecAction(ft,'Modify data types.');
    setListObj(ft,ErrorBlockCell);%列出所有Gain路径
    ResultStatus = false;
end
ResultDescription{end+1} = ft;
mdladvObj.setCheckResultStatus(ResultStatus);
mdladvObj.setCheckErrorSeverity(1);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

这一部分会判断检查结果是否通过,决定在Model Advisor中显示什么。假如未通过,就会在结果中显示Failed,列出未通过检查的模块,提出修改建议。列出的模块是超链接的形式,可以直接点击链接到模型中去。
在这里插入图片描述

2.3 验证自定义检查规则

1.将写好的sl_customization.m文件保存在Matlab当前路径或搜索路径下,在命令行输入sl_refresh_customizations,刷新自定义脚本。

>> sl_refresh_customizations  % 刷新自定义脚本
  • 1

2.新建一个Simulink模型,建立若干Gain模块。点击Analysis——Model Advisor——Preference,再点击界面中的Update Check Information cache更新一下显示界面。
在这里插入图片描述
3.打开Model Advisor,运行自定义的检查项。能够成功地检查出模块。
在这里插入图片描述

3 参考资料

[1]Matlab帮助文档

>>返回个人博客总目录

注:本文转载自blog.csdn.net的chhttty的文章"https://blog.csdn.net/u013288925/article/details/105342629"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top