找回密码
 注册
Simdroid-非首页
查看: 405|回复: 2

【原创】用S函数实现Simulink驱动的动画显示

  [复制链接]
发表于 2008-7-30 10:42:11 | 显示全部楼层 |阅读模式 来自 河北廊坊
    Simulink可以很方便地实现各种领域的仿真,特别是控制包括动力学运动学的仿真。但要想不局限于通过Scope曲线的方式想象实物的运动情形,就要采用动画显示了。最直接的方法便是借助Matlab自身的图形能力,一种是驱于真实的"Virtual Reality Toolbox" ,可以直接由Simulink驱动,但是需要有一定的三维建模的能力,而且个人认为如果不作演示性仿真也是没有必要用到的;别一种便是用m文件的S函数,这对Matlab GUI熟悉的朋友可谓轻车熟路了,不熟GUI的朋友也很容易上手,通过绘图命令 line patch rotate以及set get 等很容易实现简单的动画。


    下面便以一个具体的小例子说明S函数实现Simulink驱动的动画显示的全过程。

    整体效果如第一张图所示,mdl模型及参数对话框如第二张图所示。由第一、二个输入数据"Data1"与"Data2"驱动两个点在轴上绘出一定形状的曲线,左边两个长条为数据显示区,其中第二个长条的数据是由输入数据"CustomData(Disp)"确定的,它们的维数及提示在参数对话框中给定,分别为"Custom Display Data Sizes"与"Custom Display Annotations";界面右下角"AutoAxisLim"选定后,轴的大小会根据数据的内容作适应性调整。参数对话框另几个参数分别为"Sample Time"表示每隔多少秒绘图一次(0为连续),"Record to Avi File"控制录象控能,可以选择不录像,对整个figure录像以及对轴录像,需要注意的是录像开始时figure与轴的大小就不能调整了。

    m文件S函数的源代码为sfun_Visual.m。首先在mdlInitializeSizes里作相应的初始化工作,比如初始化图形、录像以及其他GUI。

    录像的操作典型命令如:
        VisualAvi= avifile(avifilename);
        frame=getframe(ax);
        VisualAvi = addframe(VisualAvi,frame);
        VisualAvi=close(VisualAvi);


    GUI初始化时典型命令如:
        ldata1=line('parent',ax,'visible','off','xdata',[],'ydata',[],'zdata',[],'color',[1 0 0],'linewidth',1);
        uradio=uicontrol('parent',fi,'style','radio','unit','norm','pos',[.9 .007 .10 .02],'value',0,'fore','w','back',get(fi,'color'),'string','AutoAxisLim');


    需要注意的是无论是录像还是GUI的句柄生成后不能丢失,因为S函数是每个周期调用的,下一周期可能还要改写这些对象的属性,可以将它们存在figure的数据区,也可以存在工作空间或用全局变量,这里使用的是全局变量,如
        global fDat_Visual;
        fDat_Visual=[fi, ax, ldata1,ldata2,pdata1,pdata2];


    接下来,mdlOutputs是最核心的函数了,几乎所有动画都在这里实现。如果模型用Fixed-Step,它的调用频率就由S函数的Sample Time来决定,但如果是Varialble-Step,即使指定了Sample Time,mdlOutputs调用频率视模型的积分情况也可能高于Sample Time指定值。Sample Time由以下代码指定:
        ts  = [sampletime 0];


    绘制动画时用的最多的便是Set命令了,如:
        set(text1,'string',strr);
        set(ldata1,'visible','on','xdata',[get(ldata1,'xdata') data1],'ydata',[get(ldata1,'ydata') data2],'zdata',[get(ldata1,'zdata') 0]);
        set(ldata2,'visible','on','xdata',[get(ldata2,'xdata') data2],'ydata',[get(ldata2,'ydata') data1],'zdata',[get(ldata2,'zdata') 0]);


    绘制完成应记得用drawnow命令刷新显示。需要注意的是不能用plot,line,image等命令绘图,这样会产生很多新的对象,很可能几十秒就内存不足了,只能对初始化时生成对像的句柄进行操作,每条命令都应指定好所操作对像的句柄。

    最后是mdlTerminate,在仿真停止时做一些必要的工作,比如清除全局变量等。

    OK.代码和模型文件一并附上。曾做过多关节机械臂的运动控制显示,用rotate命令从头部到根部实现每个关节的三个欧拉角的转动。大家如果实现了好的动画也可以拿来共享。希望看到更多动力学闭环控制的动画显示。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

评分

1

查看全部评分

发表于 2008-7-30 15:57:42 | 显示全部楼层 来自 新疆乌鲁木齐

Excellent!!

Simdroid开发平台
精彩!鼓掌。
如果能做一个GUI来驱动该mdl文件,加上停止、运行等按钮,演示效果会更好。不过可能又会多些无谓的代码来说明数据传递的事情。
粗看了一下S-Function的代码,真的都是一些我们常用的命令,这个做法很值得借鉴,谢谢nostalgica兄的无私分享!

[ 本帖最后由 bainhome 于 2008-7-30 16:00 编辑 ]
回复 不支持

使用道具 举报

发表于 2009-9-8 19:45:30 | 显示全部楼层 来自 中国
simulink里增加动画显示很有用的 可以实现简单的交互仿真
回复 不支持

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|小黑屋|联系我们|仿真互动网 ( 京ICP备15048925号-7 )

GMT+8, 2024-5-23 13:57 , Processed in 0.040308 second(s), 17 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表