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

请问:Simulink中怎样实现实时仿真?

[复制链接]
发表于 2005-2-23 23:19:06 | 显示全部楼层 |阅读模式 来自 上海交通大学
请问:Simulink中怎样实现实时仿真?也就是说假如在仿真参数对话框中设了Start time:0 s,Stop time:10 s的话,仿真时Simulink也运行10秒时间。
dddlzg 该用户已被删除
发表于 2005-3-19 12:27:44 | 显示全部楼层 来自 上海普陀区
提示: 作者被禁止或删除 内容自动屏蔽
发表于 2005-3-19 20:23:52 | 显示全部楼层 来自 大连理工大学

Re:请问:Simulink中怎样实现实时仿真?

这要用到RTW(REAL TIME WORKSHOP),并且要有硬件支持运行,也就是说要有A/D,D/A。估计你是把“实时”的概念给弄错了!
发表于 2005-3-31 23:02:30 | 显示全部楼层 来自 西华大学

Re:请问:Simulink中怎样实现实时仿真?

可以简单的利用增加或减小仿真的步长值来实现,但不是非常的精确。
发表于 2005-7-7 19:41:06 | 显示全部楼层 来自 同济大学

Re:请问:Simulink中怎样实现实时仿真?

sinoli,希望有机会和一起探讨RTW方面的问题
发表于 2007-10-16 18:31:36 | 显示全部楼层 来自 陕西西安
很希望获得解决办法,据说可以采用windows多媒体定时器。
回复 不支持

使用道具 举报

发表于 2007-10-16 18:31:48 | 显示全部楼层 来自 陕西西安
很希望获得解决办法,据说可以采用windows多媒体定时器。

评分

1

查看全部评分

回复 不支持

使用道具 举报

发表于 2007-10-17 08:16:29 | 显示全部楼层 来自 江苏南京
众所周知,基于simulink的仿真属于伪实时仿真,其仿真时间并不与实际时间同步,而与机器执行速度和模型复杂度有关。那么怎样实现simulink环境下的实时仿真呢。Matlab提供一个实时工作环境(RTW)用于将simulink模型转化成C程序,在外部模式下这个C程序
是可以和simulink进行数据交换的。如果在C程序中加入时钟中断,就可实现simulink下的实时仿真。下面谈谈这种方法的具体实现
步骤。
第一步、新建模型,这个模型要包含信号显示的模块(scope等);

第二步、设置模型参数。
1.求解器参数设置
Solver->Solver options->Type=Fixed-step(必须) 仿真算法为ode5  Fixed step size设置为任意值(0~1)
2.实时工作空间参数设置
当Category为Target configuration时,单击Browse选择生成代码的类型,这里我们选择通用实时malloc代码格式--grt_malloc.tlc,同时修改模板联编文件(Template makefile)为:grt_malloc_vc.tmf,其他默认。将Category切换至GRT code generation options,选择External mode复选框,使产生的代码支持外部模式。

第三步、修改grt_main.c文件,在其中加入时钟中断代码。
grt_malloc_main.c是通用实时malloc c程序的main函数实现文件,RTW在代码生成过程将自动将其与模型代码编译链接成可执行文件。grt_malloc_main.c位于<matlabroot>\rtw\c\grt_malloc目录下。关于时钟中断代码的添加问题,参看下面关于"添加时间中断代码"的介绍。

第四步、生成代码。
保存好参数设置后单击Build按钮或者单击工具栏的Build All图标生成代码。

第五步、运行仿真程序,查看仿真结果。
首先在命令提示符下运行仿真程序,命令为 mdlname -tf -inf -w
mdlname为第一步新建的模型,参数-tf指定仿真时间,inf表示无限执行,具体时间可任意指定(单位为S);参数-w表示等待simulink启动仿真的命令.然后将simulink切换至外部模式(External,默认为Normal),这时可以看到工具栏的图标发生了一点变化,单击Connect to real-time target图标与实时仿真程序建立链接,链接建立好之后,单击start the real-time code启动实时仿真程序。这时mdlname.exe接收到simulink启动仿真的命令,开始执行模型代码,直至接收到simulink停止仿真的命令或者指定的仿真时间。仿真期间,从模型的信号显示模块中看到动态实时仿真结果.通过External Mode Control Panel 还可实现在线参数调整等功能.


添加时间中断代码
windows提供四种定时的方法:计时器、多媒体定时器、高精度运行计数器、虚拟设备驱动直接管理的实时时钟。计时器的分辨率不高,不能满足稍高采样频率的要求;虚拟设备驱动直接管理的实时时钟需编写虚拟设备驱动,编程复杂,实现起来不易。下面给出用
多媒体定时器和高精度计数器实现时间中断代码。
grt_malloc_main.c

1.使用多媒体定时器
//多媒体定时器的回调函数--以固定的频率推进仿真
void CALLBACK DoSimulation(UINT uID,UINT uMsg,DWORD dwUser,DWORD dw1,DWORD dw2){
  rt_OneStep(S);      
}
在main函数中添加时间中断代码
int_T main(int_T argc, const char_T *argv[])
{
UINT wTimerRes=TIMER_ACCURACY; //定义时间间隔,
UINT wAccuracy; //定义分辨率,可取模型的仿真步长
UINT TimerID; //定义定时器句柄
TIMECAPS tc;
............
............
//下面这段代码加在模型初始化代码后,即InitializeModel(S,finaltime)后
if(timeGetDevCaps(&tc,sizeof(TIMECAPS))==TIMERR_NOERROR)
{
  wAccuracy=min(max(tc.wPeriodMin,TIMER_ACCURACY),tc.wPeriodMax);
  timeBeginPeriod(wAccuracy);  //设置定时器分辨率
}

if((TimerID=timeSetEvent(wTimerRes,wAccuracy,(LPTIMECALLBACK)DoSimulation,0,TIME_PERIODIC))==0)
{
  exit(0);
}

.............
............

}
在文件开始先定义TIMER_ACCURACY
#define TIMER_ACCURACY 100  //100ms

2.使用高精度运行计数器(high resolution performance counter)
int_T main(int_T argc, const char_T *argv[])
{
LARGE_INTEGER Frequency,LastCount,CurrentCount;
...........
...........

//下面的代码添加到执行模型(Execute the model)代码相应的部位
if(!QueryPerformanceFrequency(&Frequency))  //获取系统高精度运行计数器的频率
{
  exit(EXIT_FAILURE);
}
QueryPerformanceCounter(&LastCount);   //查询高精度运行计数器的计数值,并将结果保存在LastCount中
while (!GBLbuf.stopExecutionFlag &&
           (rtmGetTFinal(S) == RUN_FOREVER ||
            rtmGetTFinal(S)-rtmGetT(S) > rtmGetT(S)*DBL_EPSILON))
{
        rtExtModePauseIfNeeded(rtmGetRTWExtModeInfo(S),
                               (boolean_T *)&rtmGetStopRequested(S));
if (rtmGetStopRequested(S)) break;
do
{
  QueryPerformanceCounter(&CurrentCount); //查询当前高精度运行计数器的计数值
}while((CurrentCount.QuadPart-LastCount.QuadPart)/Frequency.QuadPart<0.1); //0.1为仿真步长
rt_OneStep(S);
QueryPerformanceCounter(&LastCount);            
        }
        ..........
}

注意:
1.无论是多媒体定时器还是高精度运行计数器,都使用了windowsAPI所以要在grt_malloc_main.c中include <windows.h>;
2.使用多媒体定时器需要winmm.lib的支持,所以需将winmm.lib添加到编译链接的LIBS路径中.具体做法是:
将(VC_ROOT)\lib目录下的winmm.lib拷贝到(MATLAB_ROOT)\rtw\c\lib\win32目录下,然后对(MATLAB_ROOT)\rtw\c\grt_malloc目录下的grt_malloc_vc.tmf进行修改,将(MATLAB_ROOT)\rtw\c\lib\win32\winmm.lib添加到LIBS中.修改之后的Additional Libraries下的内容如下所示:
LIBS =
|>START_PRECOMP_LIBRARIES<|
!if "$(OPT_OPTS)" == "$(DEFAULT_OPT_OPTS)"
LIBS = $(LIBS) |>EXPAND_LIBRARY_LOCATION<|\|>EXPAND_LIBRARY_NAME<|_vc.lib $(MATLAB_ROOT)\rtw\c\lib\win32\winmm.lib
!else
LIBS = $(LIBS) |>EXPAND_LIBRARY_NAME<|.lib $(MATLAB_ROOT)\rtw\c\lib\win32\winmm.lib
!endif |>END_PRECOMP_LIBRARIES<|
|>START_EXPAND_LIBRARIES<|
LIBS = $(LIBS) |>EXPAND_LIBRARY_NAME<|.lib |>END_EXPAND_LIBRARIES<|
3.使用高精度运行计数器时,新建一个线程执行仿真任务,将会发生错误.使用多媒体定时器则没有这个,虽然其回调函数也是在一个新的线程中执行.
4.仿真步长(step size)可由rtmGetStepSize(S)或者(S)->Timing.stepSize获得.

上面是以通用实时malloc格式代码为例,要生成其他格式实时仿真程序,其做法与之完全相同.

评分

1

查看全部评分

回复 不支持

使用道具 举报

发表于 2011-3-30 19:13:46 | 显示全部楼层 来自 天津
我是matlab2008a,采用以上方法实验时,发现修改grt_malloc_main.c不能进行extern mode仿真,于是采用grt_main.c,多媒体计时器方法编译失败,高精度计数器方法成功,但是仿真是按simulink中设定的仿真步长在运行,而不是实时的仿真。另外实验了如果不修改grt_main.c,直接用原始的编译也能成功,也是按设定的仿真步长在仿真,想请高手们能看看问题在哪,怎么解决,十分感谢。
回复 不支持

使用道具 举报

发表于 2011-4-3 11:03:51 | 显示全部楼层 来自 陕西西安
马上要用RTW学习下先
回复 不支持

使用道具 举报

发表于 2011-4-3 11:24:01 | 显示全部楼层 来自 陕西西安
我认为把时间步长设置合适即可。
回复 不支持

使用道具 举报

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

本版积分规则

Simapps系列直播

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

GMT+8, 2024-10-4 23:23 , Processed in 0.047115 second(s), 15 queries , Gzip On, MemCache On.

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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