我是靠谱客的博主 威武板栗,这篇文章主要介绍用Matlab脚本实现Simulink模块的自动整理,现在分享给大家,希望可以做个参考。

        作为模型工程师,在Simulink中建模时,总是希望把模块排列整齐从而更加美观。但是模型的反复修改使得我们没有太多的精力去做这些整理工作。因此笔者开发了如下脚本来自动实现Simulink模块的整理工作,效果如下图所示:

        大家可以自取使用,希望可以给大家的开发工作带来一点便利。使用方法是,在模型中点击想要被整理的模块(比如一个subsystem,使得gcbh为当前选中模块的句柄),再运行函数 arrangeit() 即可。

 代码如下:

复制代码
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
% 整理与所选模块的输入和输出连接的模块的位置,使之排布整齐 % 操作方法:先在simulink中点击选中目标模块,再运行该函数 function arrangeit() lineh = get(gcbh, 'LineHandles'); porth = get(gcbh, 'PortHandles'); blkDistance = 150; %% 设置输入接口模块 for i = 1:1:length(porth.Inport) % 如果当前port口上悬空,没有连线,则跳过 if isequal(lineh.Inport(i), -1) continue; end % 获取当前port口的位置 [portx, porty, ~, ~] = lgetpos(porth.Inport(i)); % 获取当前port口连线的源模块的句柄 curtLineSrcBlkH = get_param(lineh.Inport(i), 'SrcBlockHandle'); % 如果源模块是subsystem,则不对该subsystem的位置进行设置 if isequal('SubSystem', get_param(curtLineSrcBlkH, 'BlockType')) continue; end % 获取源模块的宽度和高度值 [~, ~, width, height] = lgetpos(curtLineSrcBlkH); % 重新设置源模块的位置,保持其宽度和高度值不变 newx = portx - blkDistance; newy = porty - height / 2; lsetpos(curtLineSrcBlkH, newx, newy, width, height); end %% 设置输出接口模块 for i = 1:1:length(porth.Outport) % 如果当前port口上悬空,没有连线,则跳过 if isequal(lineh.Outport(i), -1) continue; end % curtPortPos = get_param(porth.Outport(i), 'Position'); % 获取当前port口的位置 [portx, porty, ~, ~] = lgetpos(porth.Outport(i)); % 获取当前port口连线的目标模块的句柄 curtLineDstBlkH = get_param(lineh.Outport(i), 'DstBlockHandle'); % 如果目标模块是subsystem,则不对该subsystem的位置进行设置 if isequal('SubSystem', get_param(curtLineDstBlkH, 'BlockType')) continue; end % 如果目标模块是 swithc, 则不对该subsystem的位置进行设置 if isequal('Switch', get_param(curtLineDstBlkH, 'BlockType')) continue; end % 当前port连线的目标模块可能有多个模块,因此挨个处理 for j = 1:1:length(curtLineDstBlkH) % 获取源模块的宽度和高度值 [~, ~, width, height] = lgetpos(curtLineDstBlkH(j)); % newx = curtPortPos(1) + blkDistance; % newy = curtPortPos(2) - height / 2 + height * (j - 1); newx = portx + blkDistance; newy = porty - height / 2 + height * (j - 1); lsetpos(curtLineDstBlkH(j), newx, newy, width, height); end end %% 设置 enable 或 trigger 接口,两种类型的port合并后处理 EnableTriggerPortH = -1; EnableTriggerLineH = -1; if (~isequal(lineh.Enable, -1)) && (~isempty(lineh.Enable)) EnableTriggerPortH = porth.Enable; EnableTriggerLineH = lineh.Enable; end if (~isequal(lineh.Trigger, -1)) && (~isempty(lineh.Trigger)) EnableTriggerPortH = porth.Trigger; EnableTriggerLineH = lineh.Trigger; end if ~isequal(EnableTriggerPortH, -1) % 获取当前port口的位置 [portx, porty, ~, ~] = lgetpos(EnableTriggerPortH); % 获取当前port口连线的源模块的句柄 curtLineSrcBlkH = get_param(EnableTriggerLineH, 'SrcBlockHandle'); % 只有当enable port的源模块是 inport 类型的模块时,才对其位置进行优化 if isequal('Inport', get_param(curtLineSrcBlkH, 'BlockType')) % 获取源模块的宽度和高度值 [~, ~, width, height] = lgetpos(curtLineSrcBlkH); % 重新设置源模块的位置,保持其宽度和高度值不变 newx = portx - width * 3; newy = porty - height * 2; lsetpos(curtLineSrcBlkH, newx, newy, width, height); end end end

函数 arrangeit() 使用到了位置设置和位置读取的两个函数的代码如下:

复制代码
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
function lsetpos(blockH, x, y, width, height) % lsetpos(blockH, x, y, width, height) % blockH 可以是 目标模块句柄,或者是 目标模块路径 % blockH 不能是 port 或者 line 的句柄 % width 和 height 必须 ≥ 0 % 入参合法性检查 % 如果 blockH 是句柄,则维度必须是1 % 如果 blockH 是目标模块路径,则是字符串 if ((length(blockH) > 1) && (~ischar(blockH))) errordlg('函数 lsetpos 的入参 blockH 的长度大于1','错误','creatmode'); end if (width < 0) errordlg('错误信息:函数 lsetpos 的入参 width 小于0 ! 应 ≥ 0 ','错误','creatmode'); end if (height < 0) errordlg('错误信息:函数 lsetpos 的入参 height 小于0 ! 应 ≥ 0 ','错误','creatmode'); end set_param(blockH, 'Position', [x, y, x + width, y + height]); end function [x, y, width, height] = lgetpos(blockH) % [x, y, width, height] = lgetpos(目标模块句柄) % 如果 目标模块句柄 是一个 port 的句柄,则 width 和 height 返回-1 % 入参合法性检查 if (length(blockH) > 1) errordlg('函数 lgetpos 的入参 blockH 的长度大于1','错误','creatmode'); end pos = get_param(blockH, 'Position'); x = pos(1); y = pos(2); % 如果目标句柄是port的句柄,则pos只有两维,此时宽度和高度返回-1 if length(pos) == 4 width = pos(3) - pos(1); height = pos(4) - pos(2); else width = -1; height = -1; end end

如果大家觉得有点用处,还请点个赞,欢迎留言讨论~

最后

以上就是威武板栗最近收集整理的关于用Matlab脚本实现Simulink模块的自动整理的全部内容,更多相关用Matlab脚本实现Simulink模块内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(68)

评论列表共有 0 条评论

立即
投稿
返回
顶部