nostalgica 发表于 2008-7-30 10:42:11

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

    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',,'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=;

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

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

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

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

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

bainhome 发表于 2008-7-30 15:57:42

Excellent!!

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

[ 本帖最后由 bainhome 于 2008-7-30 16:00 编辑 ]

xuemx 发表于 2009-9-8 19:45:30

simulink里增加动画显示很有用的 可以实现简单的交互仿真
页: [1]
查看完整版本: 【原创】用S函数实现Simulink驱动的动画显示