我是靠谱客的博主 激动小鸭子,这篇文章主要介绍【APPdesigner】使用appdesigner设计的一个潮流计算器,现在分享给大家,希望可以做个参考。

文章目录

    • 基本面板组成
    • 多窗口组成
    • 功能实现
      • (1)节点绘制
      • (2)导线和变压器绘制
      • (3)数据添加
      • (4)保存
      • (5)加载
      • (6)运行潮流计算
    • 数据结构
      • (1)节点数据
      • (2)导线数据
      • (3)变压器数据
      • (4)整数类型pen
      • (5)选择目标

基本面板组成

使用APPdesinger自带的菜单栏、工具栏、三个表、一个面板、一个坐标区、两个文本编辑字段以及若干个标签等组件。菜单栏中可进行新建、加载、保存等操作。工具栏用于选择所绘制的目标,以及开始潮流计算。三个表分别展示已经绘制的节点、导线、变压器的信息,面板为坐标区的父图窗,用于固定坐标区位置及属性。两个文本编辑字段用于展示所选节点和所选工具。
主界面

多窗口组成

分为主界面、用于填写节点信息的Node Data界面、用于填写导线信息的Transm Line Data界面、用于填写变压器信息的Transformer Data界面,以及展示潮流计算结果的Result界面。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

功能实现

(1)节点绘制

通过app.UIFigure.CurrentPoint属性获得鼠标在图窗中的位置,再在该位置创建一个uiimage实体,并在该实体的ImageClickedFcn属性下,通过createCallbackFcn添加节点回调函数。

复制代码
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
function DrawImage(app,x,y,pen) switch pen case 1 DrawNode(app,x,y); %画点 app.UITable.Data = app.node{2}(:,3:12); %更新表 case 2 DrawTransf(app,x,y); case 3 DrawLine(app,x,y); end end %画节点 %app.node{3}为元胞数组,每个cell记录一个imgae对象,用于删除和修改属性 function DrawNode(app,x,y) app.node{1}=app.node{1}+1; %计数 app.node{2}=[app.node{2};zeros(1,13)]; %添加新行 app.node{2}(app.node{1},1:2)=[x y]; %记录点坐标 app.node{2}(app.node{1},3)=app.node{1}; %记录点的编号 app.node{3}{app.node{1}} = uiimage(app.Panel); app.node{3}{app.node{1}}.ImageClickedFcn = createCallbackFcn(app, @NodeClicked, true); app.node{3}{app.node{1}}.Position = [x-app.nodeimgw/2 y-app.nodeimgh/2 30 30]; app.node{3}{app.node{1}}.ImageSource = 'node.png'; end

(2)导线和变压器绘制

通过点选两个不同位置的节点以确定所要绘制的线段的起始点和终止点坐标,再将该坐标通过比例转换为坐标区的坐标,随后使用plot函数创建线段实体,并在该实体的ButtonDownFcn属性下通过createCallbackFcn函数添加相应的回调函数。

复制代码
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
%画变压器 function DrawTransf(app,x,y) persistent i; persistent p1; if isempty(i) i=1; %初始化i p1=0; end % app.UIAxes.Visible = 'on'; % [ax,ay] = MousePointInAxis(app); % app.UIAxes.Visible = 'off'; if i == 1 p1 = app.SelectedPoint; % app.SelectedPointEditField.Value = num2str(p1); i = i+1; elseif i == 2 p2 = app.SelectedPoint; %避免重复 for i=1:app.transf{1} if (app.node{2}(p1,3) == app.transf{2}(i,1) && app.node{2}(p2,3) == app.transf{2}(i,2))... ||(app.node{2}(p1,3) == app.transf{2}(i,2) && app.node{2}(p2,3) == app.transf{2}(i,1)) i=1; return; end end for i=1:app.line{1} if (app.node{2}(p1,3) == app.line{2}(i,1) && app.node{2}(p2,3) == app.line{2}(i,2))... ||(app.node{2}(p1,3) == app.line{2}(i,2) && app.node{2}(p2,3) == app.line{2}(i,1)) i=1; return; end end if p1 ~= p2 %不能是同一个点 x1 = (app.node{2}(p1,1)/1003); y1 = (app.node{2}(p1,2)/599); x2 = (app.node{2}(app.SelectedPoint,1)/1003); y2 = (app.node{2}(app.SelectedPoint,2)/599); app.transf{1} = app.transf{1} + 1; app.transf{2} = [app.transf{2};zeros(1,9)]; app.transf{2}(app.transf{1},8) = 220; app.transf{2}(app.transf{1},9) = 220; if(app.node{2}(p1,3) < app.node{2}(p2,3)) app.transf{2}(app.transf{1},1:2)=[app.node{2}(p1,3),app.node{2}(p2,3)]; else app.transf{2}(app.transf{1},1:2)=[app.node{2}(p2,3),app.node{2}(p1,3)]; end app.transf{3}(app.transf{1})=plot(app.UIAxes,[x1,x2],[y1,y2],"LineStyle","-","LineWidth",3,"Color",'r'); app.transf{3}(app.transf{1}).ButtonDownFcn = createCallbackFcn(app,@TransfClicked,true); hold(app.UIAxes,"on"); app.UITable3.Data = app.transf{2}; i = 1; else i=1; return; end end end %画线 function DrawLine(app,x,y) persistent i; persistent p1; if isempty(i) i=1; %初始化i p1=0; end % app.UIAxes.Visible = 'on'; % [ax,ay] = MousePointInAxis(app); % app.UIAxes.Visible = 'off'; if i == 1 p1 = app.SelectedPoint; % app.SelectedPointEditField.Value = num2str(p1); i = i+1; elseif i == 2 p2 = app.SelectedPoint; %避免重复 for i=1:app.line{1} if (app.node{2}(p1,3) == app.line{2}(i,1) && app.node{2}(p2,3) == app.line{2}(i,2))... ||(app.node{2}(p1,3) == app.line{2}(i,2) && app.node{2}(p2,3) == app.line{2}(i,1)) i=1; return; end end for i=1:app.transf{1} if (app.node{2}(p1,3) == app.transf{2}(i,1) && app.node{2}(p2,3) == app.transf{2}(i,2))... ||(app.node{2}(p1,3) == app.transf{2}(i,2) && app.node{2}(p2,3) == app.transf{2}(i,1)) i=1; return; end end if p1 ~= p2 %不能是同一个点 x1 = (app.node{2}(p1,1)/1003); y1 = (app.node{2}(p1,2)/599); x2 = (app.node{2}(app.SelectedPoint,1)/1003); y2 = (app.node{2}(app.SelectedPoint,2)/599); app.line{1} = app.line{1} + 1; app.line{2} = [app.line{2};zeros(1,7)]; app.line{2}(app.line{1},7) = 1; if(app.node{2}(p1,3) < app.node{2}(p2,3)) app.line{2}(app.line{1},1:2)=[app.node{2}(p1,3),app.node{2}(p2,3)]; else app.line{2}(app.line{1},1:2)=[app.node{2}(p2,3),app.node{2}(p1,3)]; end app.line{3}(app.line{1})=plot(app.UIAxes,[x1,x2],[y1,y2],"LineStyle","-","LineWidth",3,"Color",'b'); app.line{3}(app.line{1}).ButtonDownFcn = createCallbackFcn(app,@LineClicked,true); hold(app.UIAxes,"on"); app.UITable2.Data = app.line{2}(:,1:7); i = 1; else i=1; return; end end end

(3)数据添加

在鼠标点击选择目标后,通过回调函数打开相应的数据填写图窗,同时将原有数据传给图窗,在图窗中填写完信息并点击Save后通过DataUpdata_node、DataUpdata_line、DataUpdata_transf等函数将数据传回主窗口并存放在各类数据矩阵中。

复制代码
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
%更新node数据 %seq-序号;type-节点类型; function DataUpdata_node(app,seq,type,Pd,Qd,Gs,Bs,Vm,Va,Gen,Pg,Qg) app.node{2}(app.SelectedPoint,3)=seq; app.node{2}(app.SelectedPoint,4)=type; app.node{2}(app.SelectedPoint,5)=Pd; app.node{2}(app.SelectedPoint,6)=Qd; app.node{2}(app.SelectedPoint,7)=Gs; app.node{2}(app.SelectedPoint,8)=Bs; app.node{2}(app.SelectedPoint,9)=Vm; app.node{2}(app.SelectedPoint,10)=Va; app.node{2}(app.SelectedPoint,11)=Gen; app.node{2}(app.SelectedPoint,12)=Pg; app.node{2}(app.SelectedPoint,13)=Qg; app.UITable.Data = app.node{2}(:,3:13); %更新表 end %更新line数据 % function DataUpdata_line(app,rou,req,Dm,L,n) app.line{2}(app.SelectedLine,3)=rou; app.line{2}(app.SelectedLine,4)=req; app.line{2}(app.SelectedLine,5)=Dm; app.line{2}(app.SelectedLine,6)=L; app.line{2}(app.SelectedLine,7)=n; app.UITable2.Data = app.line{2}(:,1:7); end %更新transf数据 % function DataUpdata_transf(app,Sn,Pk,Uk,Po,Io,Uf,Us) app.transf{2}(app.SelectedTransf,3)=Sn; app.transf{2}(app.SelectedTransf,4)=Pk; app.transf{2}(app.SelectedTransf,5)=Uk; app.transf{2}(app.SelectedTransf,6)=Po; app.transf{2}(app.SelectedTransf,7)=Io; app.transf{2}(app.SelectedTransf,8)=Uf; app.transf{2}(app.SelectedTransf,9)=Us; app.UITable3.Data = app.transf{2}; end

(4)保存

通过save函数生成nodedata.txt和linedata.txt分别存放节点数据和导线以及变压器信息。

复制代码
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
%保存数据 function [file,path] = SaveFile_txt(app) [file,path] = uiputfile('*.txt','NodeData','NodeData.txt'); filename = fullfile(path,file); if isequal(file,0) || isequal(path,0) disp('User clicked Cancel.') else nodedata = [] nodepoint = [] for i=1:app.node{1} for j=1:app.node{1} if app.node{2}(j,3) == i nodedata = [nodedata;app.node{2}(j,3:6),app.node{2}(j,11:12),app.node{2}(j,7:10)]; nodepoint = [nodepoint;app.node{2}(j,1:2)]; end end end save(filename,'nodedata',"-ascii"); save("NodePoint.txt",'nodepoint',"-ascii"); end [file,path] = uiputfile('*.txt','LineData','LineData.txt'); filename = fullfile(path,file); if isequal(file,0) || isequal(path,0) disp('User clicked Cancel.') else linedata = [app.line{2},zeros(app.line{1},2);app.transf{2}]; save(filename,'linedata',"-ascii"); end end

(5)加载

通过load函数读取nodedata.txt和linedata.txt获得节点数据和导线以及变压器信息,并绘制相应图像。

复制代码
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
function Openfile_txt(app) [file,path] = uigetfile('*.txt'); filename = fullfile(path,file); if isequal(file,0) || isequal(path,0) disp('User clicked Cancel.') else if strcmp(file,'NodeData.txt') == 1 content=load(filename); [m,~] = size(content); app.node{1} = m; app.node{2} = zeros(m,13); app.node{2}(:,3:6) = content(:,1:4); app.node{2}(:,7:10) = content(:,7:10); app.node{2}(:,11:12) = content(:,5:6); content=load("NodePoint.txt"); [m,~] = size(content); app.node{2}(:,1:2) = content; for i=1:m app.node{3}{i} = uiimage(app.Panel); app.node{3}{i}.ImageClickedFcn = createCallbackFcn(app, @NodeClicked, true); app.node{3}{i}.Position = [app.node{2}(i,1)-app.nodeimgw/2 app.node{2}(i,2)-app.nodeimgh/2 30 30]; app.node{3}{i}.ImageSource = 'node.png'; end app.UITable.Data = app.node{2}(:,3:12); elseif strcmp(file,'LineData.txt') == 1 content=load(filename); [m,~] = size(content); i = 1; while ~content(i,8) i=i+1; if i>m break; end end i = i - 1; app.line{1} = i; app.line{2} = zeros(i,7); app.line{2} = content(1:i,1:7); for j=1:app.line{1} x1 = (app.node{2}(app.line{2}(j,1),1)/1003); y1 = (app.node{2}(app.line{2}(j,1),2)/599); x2 = (app.node{2}(app.line{2}(j,2),1)/1003); y2 = (app.node{2}(app.line{2}(j,2),2)/599); app.line{3}(j)=plot(app.UIAxes,[x1,x2],[y1,y2],"LineStyle","-","LineWidth",3,"Color",'b'); app.line{3}(j).ButtonDownFcn = createCallbackFcn(app,@LineClicked,true); hold(app.UIAxes,"on"); end app.UITable2.Data = app.line{2}(:,1:7); app.transf{1} = m-i; app.transf{2} = zeros(m-i,9); app.transf{2} = content(i+1:m,1:9); for j=1:app.transf{1} x1 = (app.node{2}(app.transf{2}(j,1),1)/1003); y1 = (app.node{2}(app.transf{2}(j,1),2)/599); x2 = (app.node{2}(app.transf{2}(j,2),1)/1003); y2 = (app.node{2}(app.transf{2}(j,2),2)/599); app.transf{3}(j)=plot(app.UIAxes,[x1,x2],[y1,y2],"LineStyle","-","LineWidth",3,"Color",'r'); app.transf{3}(j).ButtonDownFcn = createCallbackFcn(app,@TransfClicked,true); hold(app.UIAxes,"on"); end app.UITable3.Data = app.transf{2}; end end end

(6)运行潮流计算

先保存两个名为nodedata.txt和linedata.txt的文件,随后使用py.importlib.import_module调用算法程序,再打开result窗口展示运算结果。

复制代码
1
2
3
4
5
6
SaveFile_txt(app); obj = py.importlib.import_module('runpf'); py.importlib.reload(obj); obj.runpf(); run result_info.mlapp;

数据结构

(1)节点数据

使用matlab特有的元组,创建一个名为node的1*3元组。在node{1}中记录节点个数,每次绘制节点或删除节点时进行加一或减一;在node{2}中创建一个矩阵,矩阵初始长度为1*13,每列分别记录节点的figure横坐标、figure纵坐标、序号、节点类型、Pd、Qd、Gs、Bs、Vm、Va、Gen、Pg、Qg,在每次绘制节点或删除节点时添加一行或删除某一行;node{3}用于存放每次绘制图像时创建的实体。

(2)导线数据

同样使用元组,创建一个名为line的1*3元组。line{1}中记录导线个数,每次绘制导线或删除导线时进行加一或减一;line{2}中创建一个初始为1*7的矩阵,每列分别记录fbus、sbus、ρ、req、Dm、L、n,在每次绘制导线或删除导线时添加一行或删除某一行;line{3}用于存放每次绘制线段时创建的实体。

(3)变压器数据

同样使用元组,创建一个名为transf的1*3元组。transf{1}中记录导线个数,每次绘制导线或删除导线时进行加一或减一;transf{2}中创建一个初始为1*9的矩阵,每列分别记录fbus、sbus、Sn、Pk、Uk、Po、Io、Uf、Us,在每次绘制变压器或删除变压器时添加一行或删除某一行;transf{3}用于存放每次绘制线段时创建的实体。

(4)整数类型pen

Pen变量用于存放所选绘制图像,在选择工具时改变。

(5)选择目标

SelectedPoint、SelectedLine、SelectedTransf通过PickOn函数,使用传入的各类实体句柄确定所选目标。

最后

以上就是激动小鸭子最近收集整理的关于【APPdesigner】使用appdesigner设计的一个潮流计算器的全部内容,更多相关【APPdesigner】使用appdesigner设计内容请搜索靠谱客的其他文章。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部