LinxVIEW论坛-斯科道

标题: JKI状态机最佳操练 [打印本页]

作者: Scadao    时间: 2018-1-29 15:01
标题: JKI状态机最佳操练
本帖最后由 Scadao 于 2018-1-29 23:29 编辑



近来JKI团队讨论了状态机的最佳操练模式,帮助LabVIEW开发者创建一款强劲的状态机模板,从而快速方便编写代码,同时也对LabVIEW工程师通过CLD考试颇有助益。



讨论结果,大家贡献了很多奇妙想法,这里从5个角度来梳理表述:
1. 不要在子VI中隐藏状态字符串;
2. 不要在事件结构中添加代码和逻辑判断;
3. 保留原生架构尺度(比如不要去催生壮大架构);

4.    使用宏替代链式序列状态;
5. 左对齐替代右对齐状态字符串


我们倾听大伙在JKI状态机操练过程的使用心得,请尽情建议,有什么好点子也敬请奉献,也许后续JKI状态机模板就会添加进你的想法。





作者: Scadao    时间: 2018-1-29 17:12
本帖最后由 Scadao 于 2018-1-29 17:38 编辑

1. 不要在子VI中隐藏状态字符串

下面两截图说明了:
较好的习惯:保留状态字符串在程序框图


不好的习惯:将状态字符串封装进子VI


我们JKI状态机在程序框图保留状态字符串,比封装在子VI,具备这些方面的关键好处:
A)提升代码可读性——在JKI状态机中,你没必要通过子VI去了解整个程序的逻辑流程,这使得你编码更快,也是JKI状态机关键目的所在之一。如果将代码放在子VI里面,将使得代码可读性和可维护性很差;

B)可在LabVIEW中创建“Find”对话框——你可在JKI状态机中通过指定状态字符串,从而在程序框图中查找到这部份VI内容。
举例来说,在程序框图中通过按“Ctrl+F”键,可搜索查找对象和类似“UI:Initialize”那样的文本内容,确保查找内容处于VI搜索范围。

单击“Find”就会在你的VI框图中寻找到所有包含“UI:Initialize”字符VI片段内容。


VI程序框图的状态字符串查找(替代)功能是款强劲的工具,如果你将状态字符串封装进子VI中,就显示不了这种功能。



C)状态转移的逻辑性与其应用代码其余部份之间的耦合是松散的——驻留在软件中的JKI状态机逻辑流程是松散耦合的,这意味着对某个VI的更改不会无意中影响到其他地方代码的功能。
要点:要保留好JKI状态机在程序框图中的状态字符串,请多加利用这种优势,而不要隐藏封装在子VI中!


作者: Scadao    时间: 2018-1-29 21:51
2. 不要在事件结构中添加代码和逻辑判断

将代码依逻辑放在条件分支结构中,不要在事件结构中添加代码和逻辑。

我们这里的意思是要养成两种好习惯:
a) 事件结构仅产生状态字符串队列;

b) 条件分支结构做具体工作

a) 在事件结构中,通过简单添加状态到队列中来处理用户接口事件(即不要做具体事情)


b) 在条件分支结构中,嵌入代码做具体工作


不好的习惯:事件结构中包揽所有的工作
这种坏习惯就象下面这般将所有工作细节放在事件结构当中:


为什么?因为1)比较难复用代码;2)它锁住了用户接口。
有些细微差别:

1)条件结构中的代码比较容易复用
因为这样能简化状态机中的状态调用——那也是JKI状态机被设计成怎样工作的。与之相反,在事件结构中复用代码是比较困难的,你不得不通过调用Signal Value值属性来处理事件。这是人们普遍不喜欢的做法,因为读取调试这种代码是比较困难的,你不知道UI事件到底是用户还是编程代码引起的。

2)条件结构中的执行代码没有锁住用户接口
事件结构中的代码执行锁住了UI,因此给软件终端用户的体验度很差。某些情况下,这种糟糕被锁看起来好像软件崩溃了。
要点:通常来说,你应该只使用事件结构来捕获前面板和动态事件,事件结构添加状态字符串到队列中,条件分支结构调用状态字符串,功能代码放在其中。

这里需要指出下在事件结构中针对状态/条件进行判断切换是允许的,值得推介。


上文综述如下:不要在事件结构中添加代码和逻辑序列,要将这些功能码放在条件结构语句当中。

作者: Scadao    时间: 2018-1-30 01:26
本帖最后由 Scadao 于 2018-1-30 01:31 编辑

3. 保留原生架构尺度(比如不要去催生壮大架构)

JKI状态机窗口尺寸要在程序框图中小心设计成合理大小,“LabVIEW风格程序框图清单”告诉我们:

“避免创建太大的程序框图,[...]程序框图内容窗口大小会影响LabVIEW代码的可读性,确保其尺寸不要大于屏幕边框。”

当然,显示屏的尺寸是越来越大,如所谓的雷电屏,程序框图同时也随着变得越来越大。


还有,在你的JKI状态机演练中,你要小心避免窗口变化,因为我们限制它的尺寸,模块化你的代码是种好事,下面我们就要讨论,这些相互对应方法来实现……

首要注意的是确保JKI状态机尺寸发生变化:
·避免使用Ctrl拖曳方式插入到LabVIEW程序框图中;
·在JKI状态机中,针对所有结构将“自动扩展”功能关闭,有While循环、Case条件语句和事件结构。


第二点,随着你的应用逻辑和代码复杂度会越来越扩展,你可能需要模块化你的代码,比如不要试着在一个条件框中去做所有事情。可采取下面方法:
·将代码嵌入到子VI中
·针对你的状态机创建附加状态,以便组织分类到各自相关区域


记住,一旦你扩展你的JKI状态机,要想去缩小其规模,这几乎是不可能的,但通过我们的思想交流碰撞,这在将来是有可能的!


作者: Scadao    时间: 2018-1-31 10:10
4. 使用宏替代链式序列状态


宏是其它状态列表的一个简单集合,调用宏就如同调用所有列表中的状态。


有必要说下,在宏条件分支结构中,是没有做具体工作的,我们仅是简单罗列了一下队列状态序列。

这儿我们使用三个状态来作为范例演示下宏的作用:


使用宏会让我们对代码流程的理解更清晰;很明显调用宏即是执行状态序列,也很容易看到状态序列。

不太好的习惯是使用链式状态。

这里展示下链式状态序列,每个状态依次调用下一个状态:


跟宏相比,这就很没必要,因为:

a)链式各个状态间调用不是那么一目了然——也即不能一眼看出调用完“State 1”后是调用“State 2”,然后是调用“State 3”。


b) 在其他序列操作中要复用这些状态是相当困难的。因为链式序列中的每个状态都是紧密耦合的,比如要调用“State 3”,必须先调用“State 2”.

为什么要使用宏?为什么链式状态会将我们陷入困境?现在我们已经相当清楚了。

综观上述,你在实际案例中可能会动态按需按项目条件来切换配置宏的内容,这依赖系统状态,在构建宏时,可能这些信息不太具备。在这些情况下,我们可以使用一些特殊的技术,这将在以后的论坛中讨论这些技术。敬请关注!


作者: Scadao    时间: 2018-1-31 11:29
5. 左对齐替代右对齐状态字符串

这次发帖,我们聊聊简单的,当然在实际项目中也是很重要的,这将使得你的代码可读性较佳,方便你后续开发和其他工程师的调用。

左对齐文本可读性较友好


右对齐文本可读性较困难


左对齐有助于多行文本目录标题分类/分组,一目了然。

这里我们预览下左对齐字符串常量的操作,首先从状态机左边拷贝“Macro:Initialize”字符串常量,下图操作过程展示其起点:


作者: Scadao    时间: 2018-1-31 14:33
JKI状态机编辑器

JKI近来发布了JKI状态机编辑器,这是款新型强大工具,使得LabVIEW工程师更加容易管理开发使用JKI状态机,比如通常添加、删除、拷贝状态任务,当前可添加动态事件。

随着试用反馈测试,近期版本的更新发布,作了几个方面的提升:

·使用体验启动更快
·UI反应更敏捷,更流水线化
·修复了几个繁琐操作


现下载使用JKI状态机编辑器

也可通过VIPM进行下载:


作者: Scadao    时间: 2018-1-31 14:49
JKI状态机编辑器——Quick Search Filter Box



Quick Search Filter Box的新功能可使LabVIEW工程师过滤输出相应状态,使窗口只显示你要的状态内容,经过测试反馈没发生状态丢失现象,在大型状态机的开发设计中尤其优势明显。



作者: Scadao    时间: 2018-1-31 15:20
JKI状态机编辑器——添加动态事件



目前,LabVIEW工程师可通过JKI状态机中的条件分支右击快捷键选择“Add Dynamic Events”来添加动态用户事件注册到状态机当中,经测试可完好创建事件驱动应用。


也可通过状态机编辑器界面右键选择:


一旦选择,事件注册和事件注销将会在JKI状态机右键快捷菜单中添加上,从而每个状态都会有相应连线。



作者: Scadao    时间: 2018-1-31 17:15
本帖最后由 Scadao 于 2018-1-31 17:19 编辑

JKI状态机右键快捷菜单新功能



LabVIEW2015以后版本才拥有下面所述新近添加的右键快捷菜单新功能,要理解快捷菜单插件的开发用法,可浏览NI官网的帮助文档

·通过树形主题来可视化选择JKI状态机条件事件帧结构
·JKI状态机编辑器UI界面就是树形化状态显示,可通过左键单击选择查看每个状态帧的程序框图内容
·JKI状态机编辑器的向前、向后按钮可切换查看相应历史状态,第三按钮为清除历史记录
·可在JKI状态机编辑器中用鼠标拖拽状态主题进行重新分类编排
·右击状态主题可重命名、创建副本、删除等等
注意:JKI状态重命名将对整个VI状态发生更改
·在状态字符串上鼠标右键选择“Goto State”,可跳转切换到此状态的条件帧




作者: Scadao    时间: 2018-3-7 15:07
JKI状态机编辑器——查找访问数据来源点

目前,状态机间共享数据访问时,可通过簇名称绑定(解绑)来实现,解绑数据访问来源可右键快捷菜单选项Find Data Accessors,从而弹出对话框列表出读写此数据所有相关条件状态帧,点击即可。





作者: Scadao    时间: 2018-3-7 15:27




作者: Scadao    时间: 2018-3-9 17:57
默认自带的Case名称如下:

---------- Core ----------
Default:若一个state名称没有对应的case,执行这个Default,报错,告知开发者,state名称有误。
Initialize Core Data:绑定本VI的引用和是否退出时关闭前面板的信息到簇里面。
Error Handler:一旦某个case出错,下个状态就到这里执行报错程序,默认的比较简单,可以自行修改。
Exit:退出程序时最后执行的case。停止While循环。
---------- Data ----------
Data: Initialize:变量初始化
Data: Cleanup:退出之前清除一些信息,引用,串口引用,DAQ引用,其它的信息需要清除的。
---------- UI ----------
UI: Initialize:启动此VI时放置初始化UI的代码。
UI: Cursor Set:鼠标形状设置,暂没用过。
UI: Front Panel State:控制前面板打开,关闭,隐藏,最大化,最小化的case,默认只有打开和关闭的代码。
---------- Macro ----------
Macro: Initialize:调用此VI时首先执行的case,里面放置接下来要执行的state。
Macro: Exit:退出时首先执行的case,放置退出之前需要执行的state的命令。
---------- New Category ----------
New Category: 1:自行添加的自定义case名称。

作者: Scadao    时间: 2018-3-9 18:02
网友达人上传到优酷的教学视频:

视频上:http://8du.in/0N32au
视频下:http://8du.in/0N32bj

作者: 难乙    时间: 2019-7-23 14:46
我见过的最详细的解释了~~   不知道Actor Framework 有没这么详细的介绍啊
作者: 阿豪博士    时间: 2019-7-23 17:08
这个结构,用了一段时间。如果说需要轮询一些网络、串口、或者采集卡的数据,这种情况该添加在什么地方?




欢迎光临 LinxVIEW论坛-斯科道 (http://iiotview.com/) Powered by Discuz! X3.2