![1da02061d424ce82f6cd066b6a9a39f1.png](https://i-blog.csdnimg.cn/blog_migrate/6bbba554cfe4414669ff0ed97c1d40fe.jpeg)
ABB机器人高级编程-String机器人程序的自我更新
上一次教程和大家探讨了机器人如何自己升级代码,可能有人会说:不就是简单的用之前写文件的模块,写一串奇怪的字符到文件里面就结束了。如果总这么理解我只能说,朋友你领悟到精髓了。但是我还是需要补充一句,我昨天遇到的一个真真的大师级别的人物,和编写代码没有任何关系的设计大师,曾是2008奥运会的舞美总设计,他和我说了一段这样的话,大概就是:美就是你要用黑盒子罩起来,让别人知道了就没有神秘,没有了神秘就没有美感了。我顿时略有顿悟,嗯大学一直追不到女生,估计就是她们为了保持神秘保持美。我们理工男应该坚信我们是好人,我们可以接盘。
好的下面是上期的重点部分是机器人自己给自己编写了一套代码,那下面应该让机器人自己运行代码,不管机器人想自己运行充值的代码还是想运行给自己加Buff的代码,都需要执行一个很重要的部分:
机器人自己把自己编写好的代码加载到控制器里面,然后在愉快的运行。
下面我给大家讲讲如何加载模块。加载模块在行业的应用还是很广的,比如我在汽车流水线今天是A款车型,明天是B款车型,每一款车型需要大量的轨迹代码,但是如果一次性全部加载到控制器对控制器来说是一个不小的负载。严重的可能影响到轴计算器的计算资源,导致示教器反应迟钝,甚至卡死。那这时候动态加载模块就尤其重要,只要PCL或者上位机告诉机器人什么车型,机器人提前加载模块,等汽车过来就可以很愉快的运行了。
下面是我的思路:
- 加载模块
- 执行模块中的代码
- 卸载加载的模块
思路就是这么简单,已于既往的简单思路。简约简单。下面我大家可以和我一起执行下面的操作。
首先在Home文件下新建一个模块(~~~~~~ ~)。
前几天雨夜拯救的小猫在蹭我的电脑散热器。
好模块名字有了就是:CatModule.mod 记得新建在Home文件下。
第一步:
在里面写下如下的内容:
MODULE CatModule
LOCAL PERS num AgeofCat:=0;
PROC Voice()
TPWrite"Miao Miao ~~~~~~~";
TPWrite"I am "+ValToStr(AgeofCat)+" years old";
Incr AgeofCat;
ENDPROC
ENDMODULE
这个代码我就不解释了,这几行代码太简单了,好第一步完成了。
下面开始激动人心的第二个步:
设计LoadModule的数据结构,这个是我比较喜欢的一个部分。
RECORD LoadType
!记录模块的名字
string ModuleName;
!是否采用动态加载
bool Dynamic;
!加载后是否进行检查
bool CheckRef;
!模块后缀名 .Mod
string extension;
ENDRECORD
下一步是驱动程序的的设计编写:
MODULE LoadModuleHelper
【函数名称】:LoadModule
【函数功能】:实现函数模块的加载
PROC LoadModule(var LoadType Ltype)
IF Ltype.Dynamic =TRUE AND Ltype.CheckRef = TRUE THEN
LoadDynamic, "HOME:/"+Ltype.ModuleName+LType.extensionCheckRef;
ELSEIF Ltype.Dynamic =TRUE AND Ltype.CheckRef = FALSE THEN
LoadDynamic, "HOME:/"+Ltype.ModuleName+LType.extension;
ELSEIF Ltype.Dynamic =FALSE AND Ltype.CheckRef = TRUE THEN
Load "HOME:/"+Ltype.ModuleName+LType.extensionCheckRef;
ELSEIF Ltype.Dynamic =FALSE AND Ltype.CheckRef = FALSE THEN
Load "HOME:"file:=Ltype.ModuleName+LType.extension;
ENDIF
ENDPROC
【函数名称】:UnLoadModule
【函数功能】:实现函数模块的卸载
PROC UnLoadModule(var LoadType Ltype,bool Save)
IF Save =TRUE THEN
UnLoad Save, "HOME:",file:=Ltype.ModuleName+Ltype.extension;
ELSE
UnLoad "HOME:",file:=Ltype.ModuleName+Ltype.extension;
ENDIF
ENDPROC
【函数名称】:IsModuleExist
【函数功能】:检测内存中是否存在该模块
FUNC bool IsModuleExist(var LoadType Ltype)
return ModExist(Ltype.ModuleName);
ENDFUNC
ENDMODULE
还是我一如既往的编写风格
最后一步Main函数的编写
MODULE MainModule
PROC main()
!初始化Module变量
VAR bool isExist:=false;
loadCat.ModuleName:="CatModule";
LoadCat.extension:=".Mod";
loadCat.Dynamic:=False;
!加载模块
LoadModule loadCat;
!调用模块中的函数
%"Voice"%;
!卸载模块
UnLoadModule loadCat,FALSE;
ENDPROC
ENDMODULE
运行结果如下:
![2a14b34bce89a3a0b42b91cb89df48e3.png](https://i-blog.csdnimg.cn/blog_migrate/ccfd5accd22d1d13e07a93a8b6004269.png)
如果你反复执行就会发现我的小猫为什么一直都是0岁为什么不长大。会出现下面的结果。
![3929c1f8b67e1f09910c4195ce7d1210.png](https://i-blog.csdnimg.cn/blog_migrate/d66205a57a4035cfaf7cb10f80a821eb.png)
但是在代码里面明明添加了每执行一次就会给小猫的年龄+1的代码的呀。
下面我叫大家一个神奇的操作,刚才的的UloadModule修改如下:
修改前:
UnLoadModule loadCat,FALSE;
修改后:
UnLoadModule loadCat,TRUE;
运行一下:
你会发现小猫长大了,记得不要运行太多次,猫的寿命大概就是10几年,如果给他结扎了他能多活几年,所以要么选择给他来一刀,如何?接盘晚才能活得久。
下面是修改后运行的结果。
![01de285ef2e45cd25a0ae032b2eb0415.png](https://i-blog.csdnimg.cn/blog_migrate/8855c926fae86e9743906c350f854b4a.jpeg)
可能大家运行的时候会出现类似“该模块已经存在或者该模块已经加载的报错信息”
原因其实就是运行的模块只运行了加载却没有卸载。那应该怎么解决呢?
可能嗅觉领命的朋友已经发现了刚才编写的模块有这样一行代码?
【函数名称】:IsModuleExist
【函数功能】:检测内存中是否存在该模块
FUNC bool IsModuleExist(var LoadType Ltype)
return ModExist(Ltype.ModuleName);
ENDFUNC
通过运行这个代码确认模块是否已经在内存中加载过,如果加载了就不用继续加载。修改后的代码如下:
MODULE MainModule
PROC main()
var LoadType loadCat;
VAR bool isExist:=false;
loadCat.ModuleName:="CatModule";
LoadCat.extension:=".Mod";
loadCat.Dynamic:=False;
isExist:=IsModuleExist(loadCat);
IF isExist THEN
TPWrite "Cat has been load";
ELSE
LoadModule loadCat;
%"Voice"%;
UnLoadModule loadCat,TRUE;
ENDIF
ENDPROC
ENDMODULE
大家运行一下看看怎么样,也可以和上一次的代码配合使用加载一组点位,这样最近的两个章节的探讨就实现了机器人自己生成升级代码,自己加载代码,自己运行的效果。
下面是源码的链接:
链接:https://pan.baidu.com/s/1u6amVm1mAnlHtS46mjw3gQ
提取码:7b11
愉快五一-灰太狼
2019-5-2