通过编程方式检测和替换子系统克隆
克隆是将具有相同模块类型和连接的模型模式。您可以通过从子系统克隆创建库块,并将克隆替换为指向这些库块的链接来重构您的模型,这样您就可以重用组件。有关克隆的更多信息,请参阅使用克隆检测启用组件重用。
在模型提交过程中以编程方式检查克隆,有助于在模型部署到主产品分支之前,发现重用子系统的机会。更新模型时,您可以同时使用 克隆件检测器 应用和克隆检测器 API。当您使用克隆检测器 API 时,检测到的克隆会出现在 Simulink® 编辑器中。
本示例展示了如何使用克隆检测 API 来识别和替换单个模型中的克隆,方法是创建一个包含子系统模块的库文件,并将克隆替换为指向库文件中模块的链接。
在这个示例中,您将学习如何使用:
Simulink.CloneDetection.findClones 在模型中查找克隆。
Simulink.CloneDetection.replaceClones 替换模型中的克隆。
Simulink.CloneDetection.checkEquivalency 用于检查更新后的模型与原始模型的等效性。
Simulink.CloneDetection.Settings 为
findClones操作添加条件。Simulink.CloneDetection.ReplacementConfig 向
replaceClones操作添加条件。
通过编程方式识别模型中的克隆体
打开模型
ex_detect_clones_B。openExample('ex_detect_clones_B');将模型保存到当前工作目录。
要查找子系统克隆,请使用函数
Simulink.CloneDetection.findClones()。该函数创建一个名为cloneResults的对象。cloneResults = Simulink.CloneDetection.findClones('ex_detect_clones_B')cloneResults = Results with properties: Clones: [1×1 struct] ExceptionLog: ''cloneResults对象具有Clones,这是一个包含两个字段Summary和CloneGroups的结构体。cloneResults.Clones
ans = struct with fields: Summary: [1×1 struct] CloneGroups: [1×2 struct]查看
Summary字段。cloneResults.Clones.Summary
ans = struct with fields: CloneGroups: 2 SimilarClones: 5 ExactClones: 0 Clones: 5 PotentialReusePercentage: [1×1 struct]在这个示例中,模型有两个具有匹配子系统模式的
CloneGroups,五个SimilarClones,零个ExactClones,以及五个子系统Clones。查看
CloneGroups字段。cloneResults.Clones.CloneGroups
ans = 1×2 struct array with fields: Name Summary CloneList本例中的模型返回一个包含两个
CloneGroups的数组。每个数组都包含Name、Summary和CloneList。查看第一个克隆组的详细信息。
cloneResults.Clones.CloneGroups(1)
ans = struct with fields: Name: 'Similar Clone Group 1' Summary: [1×1 struct] CloneList: {3×1 cell}查看
Summary。cloneResults.Clones.CloneGroups(1).Summary
ans = struct with fields: ParameterDifferences: [1×1 struct] Clones: 3 BlocksPerClone: 8 CloneType: 'Similar' BlockDifference: 1查看第一个
CloneGroup的CloneList。cloneResults.Clones.CloneGroups(1).CloneList
ans = 3×1 cell array {'ex_detect_clones_B/Subsystem1'} {'ex_detect_clones_B/Subsystem2'} {'ex_detect_clones_B/Subsystem3'}同样地,您可以使用上述步骤找到其他
CloneGroups的结果。
通过编程方式替换模型中的克隆体
要替换模型中的克隆体,请使用函数
Simulink.CloneDetection.replaceClones()。此函数使用来自findClones函数的cloneResults对象。cloneReplacementResults = Simulink.CloneDetection.replaceClones(cloneResults)
cloneReplacementResults = ReplacementResults with properties: ReplacedClones: [1×5 struct] ExcludedClones: {}cloneReplacementResults对象包含两个属性,ReplacedClones和ExcludedClones。查看
ReplacedClones属性的内容。cloneReplacementResults.ReplacedClones
ans = 1×5 struct array with fields: Name ReferenceSubsystem1×5 数组表示该函数替换了模型中的五个子系统克隆。
查看已替换子系统克隆的列表。
struct2table(cloneReplacementResults.ReplacedClones)
ans = 5×2 table Name ReferenceSubsystem ___________________________________ _____________________________ {'ex_detect_clones_B/Subsystem1'} {'newLibraryFile/Subsystem1'} {'ex_detect_clones_B/Subsystem2'} {'newLibraryFile/Subsystem1'} {'ex_detect_clones_B/Subsystem3'} {'newLibraryFile/Subsystem1'} {'ex_detect_clones_B/SS3' } {'newLibraryFile/SS1' } {'ex_detect_clones_B/SS4' } {'newLibraryFile/SS1' }
利用库引用块识别克隆
将模型和库文件保存到当前工作目录。
ex_detect_clones_E clones_library
使用
Simulink.CloneDetection.Settings()类创建一个对象,该对象指定在模型中查找克隆的某些条件。cloneDetectionSettings = Simulink.CloneDetection.Settings()
cloneDetectionSettings = Settings with properties: IgnoreSignalName: 0 IgnoreBlockProperty: 0 ExcludeModelReferences: 0 ExcludeLibraryLinks: 0 ExcludeInactiveRegions: 0 SelectedSystemBoundary: '' DetectClonesAcrossModel: 0 FindClonesRecursivelyInFolders: 1 ParamDifferenceThreshold: 50 ReplaceExactClonesWithSubsystemReference: 0 Libraries: {} Folders: {}设置
ParamDifferenceThreshold参数。此参数指定子系统必须存在多少差异才能被视为克隆。cloneDetectionSettings.ParamDifferenceThreshold = 0
cloneDetectionSettings = Settings with properties: IgnoreSignalName: 0 IgnoreBlockProperty: 0 ExcludeModelReferences: 0 ExcludeLibraryLinks: 0 ExcludeInactiveRegions: 0 SelectedSystemBoundary: '' DetectClonesAcrossModel: 0 FindClonesRecursivelyInFolders: 1 ParamDifferenceThreshold: 0 ReplaceExactClonesWithSubsystemReference: 0 Libraries: {} Folders: {}值为 0 表示子系统必须完全相同。
添加一个参考库文件,用于匹配
cloneDetectionSettings对象中的克隆模式。在这个示例中,SSL1和SSL2是库clones_library中的子系统模式。cloneDetectionSettings = cloneDetectionSettings.addLibraries('clones_library')cloneDetectionSettings = Settings with properties: IgnoreSignalName: 1 IgnoreBlockProperty: 0 ExcludeModelReferences: 0 ExcludeLibraryLinks: 0 ExcludeInactiveRegions: 0 SelectedSystemBoundary: '' DetectClonesAcrossModel: 0 FindClonesRecursivelyInFolders: 1 ParamDifferenceThreshold: 50 ReplaceExactClonesWithSubsystemReference: 0 Libraries: {'C:\Users\Examples\clones_library.slx'} Folders: {}要查找克隆,请使用模型名称和
cloneDetectionSettings对象执行函数Simulink.CloneDetection.findClones()。cloneResults = Simulink.CloneDetection.findClones('ex_detect_clones_E', cloneDetectionSettings)cloneResults = Results with properties: Clones: [1×1 struct]cloneResults.Clones.Summary
ans = struct with fields: CloneGroups: 2 SimilarClones: 5 ExactClones: 0 Clones: 5 PotentialReusePercentage: [1×1 struct]在这个示例中,该模型有两个
CloneGroups,五个SimilarClones,零个ExactClones,以及五个子系统Clones。查看第一个
CloneGroup的详细信息。cloneResults.Clones.CloneGroups(1)
ans = struct with fields: Name: 'clones_library/SSL1' Summary: [1×1 struct] CloneList: {3×1 cell}
用条件替换克隆
1.要为
replaceClones函数指定条件,请使用Simulink.CloneDetection.ReplacementConfig()类创建一个句柄:cloneReplacementConfig = Simulink.CloneDetection.ReplacementConfig()
cloneReplacementConfig = ReplacementConfig with properties: LibraryNameToAddSubsystemsTo: 'newLibraryFile' IgnoredClones: {}将子系统添加到
IgnoredClones列表中。在这个示例中,忽略Subsystem1,以避免将其替换为克隆体。cloneReplacementConfig.addCloneToIgnoreList('ex_detect_clones_E/Subsystem1')ans = ReplacementConfig with properties: LibraryNameToAddSubsystemsTo: 'newLibraryFile' IgnoredClones: {'ex_detect_clones_E/Subsystem1'}要替换克隆,请使用
replaceClones函数,并将cloneResults和cloneReplacementConfig作为输入参量。cloneReplacementResults = Simulink.CloneDetection.replaceClones(cloneResults, cloneReplacementConfig)
cloneReplacementResults = ReplacementResults with properties: ReplacedClones: [1×4 struct] ExcludedClones: [1×1 struct]查看
ReplacedClones属性。struct2table(cloneReplacementResults.ReplacedClones)
ans = 4×2 table Name ReferenceSubsystem ___________________________________ __________________ {'ex_detect_clones_E/SS3' } {'clones_library/SSL1'} {'ex_detect_clones_E/SS4' } {'clones_library/SSL1'} {'ex_detect_clones_E/Subsystem1'} {'clones_library/SSL2'} {'ex_detect_clones_E/Subsystem2'} {'clones_library/SSL2'}参考库中的
SSL1和SSL2参考 Subsystem 模块替换了模型中的子系统克隆。查看
ExcludedClones属性。struct2table(cloneReplacementResults.ExcludedClones)
ans = 1×2 table Name ReferenceSubsystem ___________________________________ __________________ {'ex_detect_clones_E/Subsystem1'} {'unselected'}
检查模型的等效性
您可以使用 Simulink.CloneDetection.checkEquivalency() 函数检查更新后的模型是否与原始模型等效。该函数使用 Simulink Test 管理器将已保存的原始模型的仿真结果与更新后的模型进行比较,并将结果保存在 checkEquiResults 句柄中。
checkEquiResults = Simulink.CloneDetection.checkEquivalency(cloneReplacementResults)
[21-Dec-2020 16:35:13] Running simulations...
[21-Dec-2020 16:35:32] Completed 1 of 2 simulation runs
[21-Dec-2020 16:35:33] Completed 2 of 2 simulation runs
checkEquiResults =
EquivalencyCheckResults with properties:
List: [1×1 struct]
查看等效性检查结果。
checkEquiResults.List
ans =
struct with fields:
IsEquivalencyCheckPassed: 1
OriginalModel: 'm2m_ex_detect_clones_E/snapshot_2020_12_21_16_35_06_ex_detect_clones_E.slx'
UpdatedModel: 'ex_detect_clones_E.slx'
属性 IsEquivalencyCheckPassed 为 1,这表明这些模型是等价的。OriginalModel 和 UpdatedModel 属性显示了函数检查的模型。