声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 2394|回复: 0

[综合讨论] 学点儿simulink(上)

[复制链接]
发表于 2016-3-31 16:45 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
(一)引言
·去冬今春以来,日渐对自己每天上上网、写写“博客”的常规生活有些厌倦。想:何不再搞点和已往业务有关的东西呢,不为论文,不为获奖,出自老有所学,自得其乐,发于个人兴趣,还可让头脑得到锻炼。于是在朋友、同事的建议下,在退休10年之后学了一点儿有关matlab/simulink的知识。
·学习有两种方式,一种是系统、循序,另一种便是蜜蜂采蜜式,东看看,西看看,觉得有趣就停下来。以笔者的情形,还是以后一种方式为宜。按照我的“一本书主义”,首先买了一两本认为较好的教材,抓住部分代表性内容,细读深思,边学边练。老年接触“新”领域,有些难度,但因自己原有一定的学术基础,经过反复琢磨,几个月之后,终算有了些许收获,取得了一点点“成就”。这么说,有点大了,实际上只是刚刚入门吧,对此心里颇有些快乐之感,而这也正是笔者当初的本意。
·关于绘图和非线性代数方程组求根问题的心得,已在前面的博文中说到了,标题是“学点儿MATLAB”,此处不赘。本文主要谈在Simulink方面的学习心得;下一篇博文将写一下在GUI方面的学习心得。 Simulink 与GUI 是Matlab的两个重要组成部分,因而本文和下一篇博文可算作是“学点儿MATLAB”的续集吧。
·以前人们搞动态系统仿真,得从手动编程做起,包括过程数学模型、积分解算器、积分步长确定和实时修改、数据输出与存储、动态过程时间历史曲线显示、等等,都靠研究者自己操劳,反复调试,十分繁琐累人。其中最为头痛的一件事就是画仿真结果曲线,因为前些时间Fortran语言不支持图形功能。笔者30年前在NTH做访问研究,最初大量的曲线都是在方格纸上手绘的,参见附图1,直到两年研究将结束时MTS(海洋工程中心)买了一台高级图形终端,学了一阵子,才绘出了笔者希望的曲线,并获得了“硬考贝”输出,见附图2。今天,在 Simulink环境下,进行系统仿真,在个人电脑上画仿真曲线可说是举手之劳,由此感到了时代的发展和技术的进步。
111.png   
                                                         
(二)simulink
·simulink是matlab中专门用于动态系统仿真的软件工具包。从字面上看,simulink = simu + link, “simu”是simulation(仿真)的缩写,也可以理解为model(模型);而“link”指的是连接;总的看这个软件是要把各种各样的模型(模块)连接在一起,像搭积木一样,以灵活多样的方式实现动态仿真任务。
·所谓动态仿真,指的是通过计算机,用数学算法,对表达动态过程的微分方程组求解,以获得在一定输入激励之下过程的动态响应,并将计算结果以图形、曲线或数据文件的形式表达之,从而让人们对所研究对象的行为性态有深入的了解。不言而喻,动态仿真的核心之点是过程(对象)的数学模型,也就是上述的微分方程组(状态方程)的建立,这是使用simulink首先要解决的,所得模型的具体形式显然与问题的物理特性紧密相关。此外,在仿真进程中simulink 还要实现与数学模型相关的数据的输入、输出、显示、存储等诸多任务。
·Simulink的工作风格与windows操作系统是一致的,利用图标进行操作。为各种建模素材分门别类建立模型库,库中每种模型类别里的每一种元件都有特定的图标,而每个图标的背后对应着它的功能或计算的代码。对模型库内的图标进行操作就等于编程,不过这是由系统完成的,设计者无需涉足,他们被彻底解放出来,以考虑仿真的整体事宜,这使得这个软件用起来方便、高效、畅快。
(三)仿真之例
·Simulink将仿真系统表述为一个模块图,称之为simulink 模块图(笔者习惯性地称之为系统“方框图”),附图3给出 simulink模块图的一个简单例子。整个模块图由几个子模块组合而成,包括:
222.png
                          附图3
过程模型模块 s.function1,此处取一个二阶振荡过程,它的状态方程为
dx1/dt=x2 ;
dx2/dt=9.81*sin(x1)-2*x2+u;
其中,x1,x2是两个状态变量,t是时间,u代表控制输入;
输入模块Step,代表了一个量值为1的脉冲激励信号;
显示模块Scope,仿真结束时绘出一个状态变量x1(t)的时间历史曲线;
显示模块Scope1,仿真结束时绘出另一个状态变量x2(t)的时间历史曲线;
显示模块XY Graph,仿真结束时绘出相轨迹图x1(t)~x2(t);
存储子模块 to workspace,将仿真结果~状态变量x1(t)以数组形式存储于matlab主工作空间内;
存储子模块 to workspace1, 将仿真结果~状态变量x2(t)以数组形式存储于matlab主工作空间内。
子模块之间通过线段连接起来,从而示出整个simulink仿真系统内的信号流。
·simulink模块图中各子模块是怎样产生的?非常简单:点击matlab/simulink library browser 打开模型库,在source项目栏,找到step图标; 在sink项目栏,找到scope与 xy graph图标;在user-defined functions 项目栏中,找到system-s function图标,后者代表用户自建动态过程子模块;最后,在sink项目栏中找到to workspace。用鼠标将以上各图标一个个地拖到事先打开的simulink模块窗口中,其中scope图标拖动两次,to workspace图标拖动两次,这样就得到附图 3 中所有的子模块。各模块互相之间的连接,与动态过程模型的实际输入、输出个数有关;具体操作时注意连接线是通过鼠标从下游模块的输入端引向上游模块的输出端,这样当连线存在分叉时便于操作,这些在教科书上都有细致的交待。
·如上所得的simulink模块图还只是仿真系统的一个框架,这个框架指出了各个子模块的一般特性以及其间的信号流进流出关系;我们对各个子模块还需要进一步做些细致的设定或编程工作,它们才能处于可工作状态。
·首先要做的当然是过程模型的建立,也就是确定附图3中“user-defined functions”方框内的数学模型sfunjia1的表达式。对于简单的过程,选用simulink 模型库内现成的图标(模块)就可以了,例如上述的二阶线性系统,采用两个积分器就能将过程模型模块搭建起来;而对于相对复杂的动态过程,用户就需要自编一个由m文件表述的子函数了。这方面有好几种方法可供选择。值得高兴的是,simulink发展了一套编写过程模型的规范化方法,所得模型称为S函数。S函数可以说就是一种扩展了的过程数学模型。
·S函数提供了在simulink 环境下编写过程模型子函数的“模板”,不管具体的过程是简单还是复杂,其数学模型子函数都需要按此统一规格编写,这对仿真运行的管理和调度会带来巨大好处。对本文前述的小例子,如此大动干戈好像有些故弄玄虚,而对那些中等以上复杂程度的动态过程,经此处理无疑将深获其益。
以下给出本文涉及的二阶动态过程的S函数源代码,这是笔者参考了同事张显库、张国庆关于船舶运动数学模型的一段程序,经与本例结合、简化而来:
…………………………………………………………………………………………………
  1. <p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">function [sys,x0,str,ts] = sfunjia1(t,x,u,flag)</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">switch flag,</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">case 0,</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">[sys,x0,str,ts]=mdlInitializeSizes;</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">case 1,</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">sys=mdlDerivatives(t,x,u);</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">case 3,</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">sys=mdlOutputs(t,x,u);</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">case {2,4,9},</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">sys=[];</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">otherwise</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">error(['Unhandled flag = ',num2str(flag)]);</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">end</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">function [sys,x0,str,ts]=mdlInitializeSizes</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">sizes = simsizes;</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">sizes.NumContStates = 2;</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">sizes.NumDiscStates = 0;</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">sizes.NumOutputs = 2;</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">sizes.NumInputs = 1;</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">sizes.DirFeedthrough = 1;</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">sizes.NumSampleTimes = 1;</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">sys = simsizes(sizes);</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">x0 = [0;0];</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">str = [];</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">ts = [0 0]; % sample time: [period, offset]</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">function sys=mdlDerivatives(t,x,u)</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">xdot=jia1def(t,x,u);</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">sys = xdot;</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">function sys=mdlOutputs(t,x,u)</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">sys=[x(1);x(2)];</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">function xdot=jia1def(t,x,u)</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">xdot(1)=x(2);</p><p style="margin-bottom: 5px; border: 0px; list-style: none; word-wrap: normal; word-break: normal;">xdot(2)=9.81*sin(x(1))-2*x(2)+u;</p>
复制代码

…………………………………………………………………………………………………
这段S函数的程序包含了五个函数,其中第一个是主函数,其余为子函数。
·第一个函数 function [sys,x0,str,ts] = sfunjia1(t,x,u,flag)
这是本动态过程主函数,名称sfunjia1是用户加的,它也就是simulink模块图中过程模块方框内的函数名;通过分支结构switch,将程序进程划分为5种情况,依据标记变量flag的值,在一个仿真周期里,程序分别进入相应的子函数进行有关处理,这些都由simulink自行操作,用户无需费神。需强调,利用S函数编写系统数学模型要求S函数名称与文件名同名,且命名只能出现数字或大小写字母,不能出现空格和一些不常用字符。
·第二个函数 function [sys,x0,str,ts] = mdlInitializeSizes;
定义S-function模块的基本特性,包括状态变量、输入变量、输出变量的个数,状态变量的初始条件,采样时间,等等。
·第三个函数 function sys = mdlDerivatives(t,x,u);
该子函数定义了系统状态变量的时间导数,其中,xdot = jia1def(t,x,u)的函数名称与第五个函数的名称对应。
·第四个函数 Function sys = mdlOutputs(t,x,u);
该子函数描述系统的输出变量。
·第五个函数 Function xdot = jia1def(t,x,u);
该子函数给出系统的状态方程组,即传统意义上的过程数学模型,函数名jia1def是设计者给起的。可见,第五个函数与第三个函数似有重复之处。在2010版本的 matlab中,就已将二者合并(本文采用的是R2007b版本)。建立过程状态方程,叫做modeling,凭的是研究者的专业知识,有不少著作探讨mathematical modeling方面的问题,在这里matlab 和 simulink本身都帮不上太多的忙,这是笔者的见解。

回复
分享到:

使用道具 举报

您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-4-27 11:53 , Processed in 0.086784 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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