牛小贱 发表于 2014-3-20 19:42

【分享】如何Simulink的仿真结果实时动态显示到GUI界面(转)

本帖最后由 牛小贱 于 2014-4-2 16:43 编辑

关于Simulink与GUI连接,数据传递,动态显示之类的问题,想和大家分享一下!!
Simulink模型仿真时,完成下列动作:
1.自动创建Figure和axes以及text控件
2.将当前采样点输出值显示到text中
3.将仿真过程的数据动态绘制到axes上
4.仿真结束Figure自动关闭
5.使用M Level 1 S函数实现
程序代码:
function = gui_plot_sfun(t,x,u,flag)
%
switch flag,
%%%%%%%%%%%%%%%%%%
% Initialization %
%%%%%%%%%%%%%%%%%%
case 0,
    =mdlInitializeSizes;
%%%%%%%%%%%%%%%
% Derivatives %
%%%%%%%%%%%%%%%
case 1,
    sys=mdlDerivatives(t,x,u);
%%%%%%%%%%
% Update %
%%%%%%%%%%
case 2,
    sys=mdlUpdate(t,x,u);
%%%%%%%%%%%
% Outputs %
%%%%%%%%%%%
case 3,
    sys=mdlOutputs(t,x,u);
%%%%%%%%%%%%%%%%%%%%%%%
% GetTimeOfNextVarHit %
%%%%%%%%%%%%%%%%%%%%%%%
case 4,
    sys=mdlGetTimeOfNextVarHit(t,x,u);
%%%%%%%%%%%%%
% Terminate %
%%%%%%%%%%%%%
case 9,
    sys=mdlTerminate(t,x,u);
%%%%%%%%%%%%%%%%%%%%
% Unexpected flags %
%%%%%%%%%%%%%%%%%%%%
otherwise
    error(['Unhandled flag = ',num2str(flag)]);
end
% end sfuntmpl
%
%=============================================================================
% mdlInitializeSizes
% Return the sizes, initial conditions, and sample times for the S-function.
%=============================================================================
%
function =mdlInitializeSizes
%
% call simsizes for a sizes structure, fill it in and convert it to a
% sizes array.
%
% Note that in this example, the values are hard coded.This is not a
% recommended practice as the characteristics of the block are typically
% defined by the S-function parameters.
%
sizes = simsizes;
sizes.NumContStates= 0;
sizes.NumDiscStates= 0;
sizes.NumOutputs   = 0;
sizes.NumInputs      = 1;
sizes.DirFeedthrough = 1;   % u is used in Output function so it is 1 here.
sizes.NumSampleTimes = 1;   % at least one sample time is needed
sys = simsizes(sizes);
%
% initialize the initial conditions
%
x0= [];
%
% str is always an empty matrix
%
str = [];
%
% initialize the array of sample times
%
ts= ;
% init the ui controls
global t f vec
f = figure('Position', , 'MenuBar', 'none');
t = uicontrol(f,'Style','text','Position',);
vec = [];

% end mdlInitializeSizes
%
%=============================================================================
% mdlDerivatives
% Return the derivatives for the continuous states.
%=============================================================================
%
function sys=mdlDerivatives(t,x,u)
sys = [];
% end mdlDerivatives
%
%=============================================================================
% mdlUpdate
% Handle discrete state updates, sample time hits, and major time step
% requirements.
%=============================================================================
%
function sys=mdlUpdate(t,x,u)
sys=[];

% end mdlUpdate
%
%=============================================================================
% mdlOutputs
% Return the block outputs.
%=============================================================================
%
function sys=mdlOutputs(t,x,u)
pause(0.5);
global t vec f
vec = ;
set(t, 'string', num2str(u));
plot(vec);
sys = [];
% end mdlOutputs
%
%=============================================================================
% mdlGetTimeOfNextVarHit
% Return the time of the next hit for this block.Note that the result is
% absolute time.Note that this function is only used when you specify a
% variable discrete-time sample time [-2 0] in the sample time array in
% mdlInitializeSizes.
%=============================================================================
%
function sys=mdlGetTimeOfNextVarHit(t,x,u)
sampleTime = 1;    %Example, set the next hit to be one second later.
sys = t + sampleTime;
% end mdlGetTimeOfNextVarHit
%
%=============================================================================
% mdlTerminate
% Perform any end of simulation tasks.
%=============================================================================
%
function sys=mdlTerminate(t,x,u)
global f
close(f);
sys = [];
% end mdlTerminate在仿真过程中截了三个图,Display与GUI数据更新时间稍微有一点不同步,在动态过程中肉眼几乎看不出。效果如下图1、2、3所示:
其他补充:如何用GUI控制simulink,通过GUI设置simulink的参数,然后运行仿真。
通过GUI来控制Simulink进行系统仿真,仿真的对象是动态地钟摆系统.别看题目是GUI和Simulink,其实最重要的中心内容在于S-function.Math大哥说过,S-function的本质就是系统状态的更新,这话总结了一切,系统的更新也就是采样点的刷新,计算当前采样点的全部输出或者包含其微分积分信息,然后到下一个时间点,再刷新.而区分其工作阶段的标志flag的值分别对应各个工作状态:初始化,连续状态微分更新,离散状态更新,输出更新,采样时刻更新,仿真结束这六种状态.其调用格式就不详细介绍了,大家自己调用模版文件出来瞧瞧就很明白了(edit sfintempl.m或者open sfintempl.m或者type sfintempl.m).
  大概的原理就讲这么多,下面进入到我的作品,<<GUI控制Simulink演示钟摆动画>>.在这个作品中,我使用了两个S-function,一个是来描述钟摆本身的运动学特性,一个是模仿硬件(单片机的外部中断)来控制整个仿真的进行与终止.制作过程比较麻烦,程序大概四五百行,我大致说说核心的东西就应付过去吧.核心:S-function早软件中实现硬件支持的中断功能,通过刷新系统状态和检测全局变量stopf来确定是继续执行仿真还是终止动画进行.它的每次更新都把stopf变为0(继续仿真标志),但控制器的按钮按下把stopf变成1,在S-function每次计算输出时会对stopf检测,若为1,那么动画会静止.先给大家看看控制版面,带有仿真时间的输入,如果想保持仿真,那么可以输入inf.

打开模型按钮可以打开.mdl的单摆系统结构图,下面的就是检测停止状态stopf的S-function结构图,需要与系统本身放在一个.mdl文件中,否则只程序的编写是不足够的. 摆过去之后还回循环往复:

希望对那些学习这一块的人有所帮助!!!其实,将Simulink的实时仿真时间显示到GUI的控件上,还有一个比较简单方便的实现方法:S-Function。
使用Level-1 M S-Function可以方便地将每个步长的时间点动态的(估计那位会员所说实时就是这个意思)显示到一个figure的text控件上。这个S函数只用于仿真,不提供内联的TLC文件。S函数的初始化函数部分进行一个带有text控件figure的创建,输出函数则动态得奖时间量获取并写入到text上去。效果如下:
text的数据就是当前模型的时间点数据。
实现此功能的S函数代码如下:
function =gui_time_sfun(t,x,u,flag)
switch flag,
%Initialization
case 0,
    =mdlInitializeSizes;
%Outputs
case 3,
    sys=mdlOutputs(t,x,u);
%Unhandled flags
case {1, 2, 4, 9 }
    sys = [];
%Unexpected flags
otherwise
    error(['Unhandled flag = ',num2str(flag)]);
end
%mdlInitializeSizes
function =mdlInitializeSizes
sizes = simsizes;
sizes.NumContStates= 0;
sizes.NumDiscStates= 0;
sizes.NumOutputs   = 0;
sizes.NumInputs      = 0;
sizes.DirFeedthrough = 0;
sizes.NumSampleTimes = 0;
sys=simsizes(sizes);
x0=[];
str=[];
ts=[];
% 创建一个窗口显示时间
global f;
f = figure('Position',);
uicontrol('Parent', f, 'Style', 'text','String','Simulation Time');
%mdlOutputs
function sys=mdlOutputs(t,x,u)
global f;
% 将每次的仿真时间输出到figure
uicontrol('Parent', f, 'Style', 'text','String',num2str(t));
pause(0.2); %为了让人眼能看清动态过程而加入的时间延迟
sys=[];

Matlab及ADAMS集中营

Nicky_ONE 发表于 2014-3-20 21:59

LZ总结整理的不错,很实用!!赞一个!{:{39}:}

晓凡 发表于 2014-3-20 22:06

很不错……正好用到,谢谢楼主了!!!{:{39}:}

猫头鹰先生 发表于 2014-4-4 19:59

复制你的代码怎么老是有序号,好烦。想学习一下,simulink一直是弱项。

猫头鹰先生 发表于 2014-4-4 20:05

就是点击复制代码选项,每次都有序号,还得一个一个删除,好麻烦,怎么能没有序号

牛小贱 发表于 2014-4-4 20:14

猫头鹰先生 发表于 2014-4-4 20:05
就是点击复制代码选项,每次都有序号,还得一个一个删除,好麻烦,怎么能没有序号

不晓得你是怎么复制的,我刚才试了一下,没问题的。自己好好再试一下,这个是不会出问题的……

猫头鹰先生 发表于 2014-4-4 20:38

牛小贱 发表于 2014-4-4 20:14
不晓得你是怎么复制的,我刚才试了一下,没问题的。自己好好再试一下,这个是不会出问题的……

我又试了下,好了。不过出现点问题,我先看看,谢谢。
页: [1]
查看完整版本: 【分享】如何Simulink的仿真结果实时动态显示到GUI界面(转)