第一篇:Simulink一些知识总结
一、set_param 函数的应用
(一)函数调用格式:
set_param(object,param,value),其中object为模块句柄,param 为参数,value 为参数值。
(二)举例(1)启动模型仿真
set_param(gcs,'SimulationCommand','start')(2)精确控制模型仿真步长
set_param(gcs, 'SimulationCommand', 'step'),step 为仿真步长数。(3)设置模块在模型中的位置
set_param('mymodel/Gain','Position',[50 250 125 275])(4)设置模块的回调函数
set_param('mymodel/Gain','OpenFcn','my_open_cb')(5)设置模块的朝向
set_param('mymodel/Gain','Orientation','left')
二、实时改变模块的参数
单步仿真一次,改变一次参数的值,代码如下:
set_param(gcs,'SimulationCommand','start')while 1 set_param(gcs,'SimulationCommand','pause')set_param(你的模块名,'Resistance', 你想改变的值);%这一句你替换一下参数即可
set_param(gcs,'SimulationCommand','step')end
三、上次末状态作为本次初始状态进行仿真
问:已经建立好一个数据仿真模型 现在想单独改变一个参数去观察参数扰动对结果的影响,例如参数变化范围是1000 到1500,每7s 的时间让参数变化100,用什么方法可以实现 ?
答:分次仿真,每次仿真保存末状态,下一次仿真前更改参数,再倒入上次仿真的末状态作为初始状态,设置如下图:
四、模型加上标题
问:怎么给模型加上标题?
答:双击模型空白位置,即可输入text 文本,并可以设置字体大小颜色等。
五、模型仿真时间与实际运行时间
Simulink 在Normal 模式下的仿真时间是非实时的,如果希望得知自己的模型转换为实际产品时的运行时间,需要将模型生成C 代码,下载到硬件目标中去运行并使用Profiler Timer 进行时间的记录。如处理器在环仿真Processor in the Loop 可以测出模型实际的运行时间。
六、关于模块参数和模型解算配置的问题
(一)模块参数的配置:根据用户算法要求来配置,具体参数意义与使用方法可以双击模块打开对话框后在help 按钮获取详细帮助。
(二)模型结算方法配置:运行仿真的算法一般由解算器提供,分为变步长解算器和固定步长解算器。默认模型选择变步长解算器的ode45 算法,能够适应大多数模型应用场景。如果用户求解刚性模型,需要使用ode23s 之类算法。如果用户是使用simulink 进行控制算法建模,那么用户一般使用固定步长解算器以模拟与硬件芯片相同的时钟频率。
七、激活stateflow 状态图方法
(一)方法一:通过模型的调度时间周期性激活;
(二)方法二:通过trigger 信号去激活。
八、simulink 中过零问题讨论
问:simulink 中有哪些过零检测方法?是否有专门的过零检测模块? 答:只有自适应与非自适应两种选择,没有专门模块,但是很多模块里有是否使用过零检测的checkbox,如Relational Operator,switch 模块等。
九、模块采样时间与系统solver 最大步长关系
当模块的Sample time 设置为-1 时表示继承父层的采样时间,如果模块在子系统里就继承子系统的采样时间,如果模块在最上层模型,就继承系统solver 的步长作为采样时间间隔了。另外,如果模块的采样时间设置为-1 以外的值,如0 表示连续采样,这种时刻需要solver 解算器类型支持连续状态解算;当模块采样时间为0.5 这样的数字表示离散采样时间,每隔0.5 计算一次,这时要求模块的采样时间必须是solver 计算步长的整数倍。
十、solver 步长间隔对仿真的影响
在变步长解算器中,采样时间间隔(即步长)会根据前后两次计算值的误差动态改变。如果设置了最大步长,那么每次的步长就不会超出设置的这个上限。
十一、关于arduino 连接测温模块驱动的问题
问:在arduino 上连接一个测温模块(如DS18B20),查看DS18B20 的技术手册,说是利用单总线通讯协议就可以读取温度,我想问问在有相关的库函数及读取温度C 程序的情况下,怎么用simulink去驱动测温模块工作,并通过串口将温度传回PC?
答:有相关的库函数和C 例程的前提下,就把DS18B20 初始化的API 在model_initialize()中调用,在model_step()中使用读取温度的API、当然,在Model.c 文件中包含DS18B20 库函数所需要的头文件。
十二、使用S-Function 创建自定义模块如何避免重复初始化
问:使用S-Function 创建了一个自定义模块,编写了有关的模块TLC 文件,并成功添加入Simulink 函数库中,但是在使用时发现若同一模型文件中包含两个以上该模块,代码生成时会重复进行初始化,即TLC 文件中%functionStart(block, system)Output 中的内容,如何解决? 答:1.将这部分初始化放到BLockType 的tlc 函数中;
2.使用全局变量对Start 中的TLC 语句进行判断,仅第一次调用时生成,第二次以上屏蔽。
问:必须要在Start 中进行,全局变量怎么定义?在模块TLC 中进行定义吗? 答:是的,当这个变量为TLC_TRUE 时则不再执行Start 函数,直接跳出。否则执行。以保证此函数在整个编译过程中只执行一次。
十三、关于代码空间的讨论 问:在生成代码后,如何查看代码大概会占用多少RAM ROM,还有需要多少堆栈空间?
答:C 代码看不出来的,在编译完之后生成了map文件,就可以看到了。
十四、Embedded Coder、Simulink Coder 的关系 问:Embedded Coder 和Simulink Coder 有什么关系?
答:如果你想将Simulink 模型生成C 代码,那么你需要使用Simulink Coder,而Simulink Coder的运行需要依赖MATLAB Coder,所以,完整的讲,如果你需要将Simulink 模型生成C 代码,需要MATLAB Coder + Simulink Coder;如果你想将Simulink 模型生成为嵌入式C 代码,那么,除了上述两个Coder 之外,你还需要Embedded Coder。
十五、关于测量算法在处理器上执行时间问题
问:最近在看论文,看到作者利用示波器探针测量电机MTPA 算法在DSP 上在线计算时间。我现在做了一个标幺化定点后的电流指令表,怎么用示波器测量算法在处理器上执行时间?
答:算法在目标处理器上的执行时间是一个非常重要的数据,我们更多时候关心这个数据的最大值,示波器测量的方式,我觉得不一定能采集到最长时间的情形。在使用MBD 开发软件的时候,建议使用PIL 获取这个时间值,可以通过大量的测试用例,获得这个最大时间值。
答:是的,matlab 的help 关于PIL 的用处也讲到其中之一就是测量 execution time,把所需要的测量模块封装起来,给定一个输入向量,下载到目标板上,最后在matlab 窗口上输入命令,能够以图像形式给出关于在此输入向量下 average time maximum time。
十六、关于Simulink 模型的比较
问:在MBD 项目的工程管理中,模型的比较和差分是一个常见的问题。国外一些公司设计了专门用来对Simulink 模型进行比较和充分的工具,比如德国的medini unite。我想请教一下,各位在进行MBD 设计时,模型比较和差分的问题怎样解决,都有哪些好用的工具,是否有开放代码的工具。
答: MATLAB 产品提供了Simulink Report Generator,这个工具具有模型比较功能,也能实现一些模型合并。
十七、S-function builder 参数传递问题
问:怎么把s-function builder 中定义的参数传递到所集成的C 语言源文件中? 答:在Data Properties 的页面中定义参数的变量名何参数,如pvar。然后在Outputs, Discrete Update 等子页面中都可以使用变量名和下标访问参数值,如pvar[0]。使用这个变量名编写C代码,完成所有配置之后点击build,就可以将你写的C 代码打包集成到生成的C 文件中去了。
十八、快速原型和硬件在环的区别 问:快速原型和硬件在环的区别?
答:快速原型,也就是控制器快速原型的简称,顾名思义,就是对Simulink 算法进行控制器功能的快速实现。一般来讲,你可以通过工控机,快速实现控制算法,而不必对控制算法进行代码生成相关的配置和设置。然后,你可以用这个工控机实现的控制器和被控对象相连,形成闭环,实现在真实被控对象上对控制算法的验证或者参数调节。硬件在环,是对控制器进行测试的一个环节,在实现了控制器软件和硬件的集成之后,这时候我们并不能确保控制器一定是正确的,如果这个时候直接把控制器和一些被控对象连接,可能造成财产或者人身伤害,在这种情况下,我们一般会通过工控机去模拟一个被控对象,然后把控制器和这个工控机相连,进行控制器相关测试。
十九、tlc 文件该怎么编写 问:tlc 文件该怎么编写?
答:在Simulink Browser 中搜索S-Function,从example 模块中找到带有tlc 的例子,参考编写即可。另外可以阅读Embedded Coder 的User Guide 里面详细介绍了tlc 的编写方式。
二十、C MEX S-Function 延时功能
问:现在需要做一个PWM 波形输出的S 函数,想利用延时功能进行高低位的切换,但是不知道C-MEX 的S 函数怎么写延时。
答:
1、利用状态变量记录输入,在下几个采样时间后再输出;
2、直接输出,使用unit delay 实现延时。
二十一、S-Function 生成代码如何添加自定义的头文件
问:我用S 函数做了一个简单的s12xdp512 的Digital Output 的驱动模块,生成代码时一直报错Error Test.c: 28 undeclared identifier PORTA' Error Test.c: 41 undeclared identifier `DDRA'。显示的“PORTA”和“DDRA”都是在单片机的头文件“mc9s12xdp512.h”中完成定义的,如何在tlc 文件中定义该头文件,以便生成代码时不会报错,代码生成后不用手动添加?
答:PORTA”和“DDRA”都是在单片机的头文件“mc9s12xdp512.h”中完成定义的,你的Test.c 中有必要使用它们吗?当生成代码时S 函数主要完成将GUI 用户设定参数通过一系列中介文件传递到tlc 文件中去,最后生成的C 文件跟已有头文件Merge 之后再使用IDE 编译生成目标文件下载到硬件中去。二
十二、PIL 测试时主机和DSP 的连接问题
问:PIL 测试时,主机和DSP 的连接,到底是用串口,USB 口,还是下载程序的JTAG 口?
答:串口和USB 口都是可以用的,串口的话需要
提供DSP 的串口驱动代码,USB 的话,PC 端和DSP端的都需要编写,JTAG 就不确定了。
二十三、simulink 封装的模块Initialization有什么作用 问:simulink 封装模块Initialization 有什么作用,如何写这个Initialization?
答:模块的 Initialization Commands 执行的时刻包括以下几个情况:
1、在 Icon draw Commands 或 Initialization Commands 里更改封装的参数时;
2、当 Icon draw Commands 有内容时,翻转或旋转模块;
3、双击打开模块的参数对话框或点击参数对话框上的 Apply/OK/Cancel 关闭对话框时。
二十四、simulink 生成C 代码的问题
问:如果在simulink 中通过将模型生成C 代码,但又想通过其他软件如LabVIEW 调用此C 代码,那么在simulink 中生成的C 代码需要进行一些手动修改,还是说自动生成的C 代码就可以进行使用?
答:在选择系统TLC 文件时要根据你的需要进行选择。如果是为了生成嵌入式C,则选择ert.tlc文件; 如果是为了VC++ 环境使用,则选择grt.tlc(for VC++),Labview 里面你要调用此代码,是指调用其中某个函数吧,如model_step(),将生成的代码放到可搜索路径下直接调用应该就可以了。二
十五、simulink 生成C 代码再转化为DLL 文件的问题
问:通过simulink 中编写仿真模型,再将模型生成为C 代码,在VC 中生成DLL 文件,最后通过LabVIEW 调用DLL 文件,以实现混合编程的目的,应该怎样实现? 答:系统目标选择ert_shrlib.tlc,可以在生成代码的同时生成dll 文件。二
十五、Simulink 多个模块生成代码顺序问题
问:在自动代码生成的时候,把一个模块的代码放到最前面,想知道模块生成代码的放置顺序是通过什么来配置的?
答:如果有信号线连接的话,执行顺序按照信号流向(前提是DirectFeedThrough 设置正确)。没有信号连接的模块,邮件属性可以设置Priority。数字大表示优先级低。
二十六、如何封装手写底层代码
问:有没有一种方法能够将手写的底层c 代码封装在matlab 的库中,以后可以与simulink 自动生成的代码做接口的?
答:TSP 开发比较花费时间。Legacy Code Tool对既有驱动代码的耦合性有要求,太过复杂的结构无法直接应用LCT。但是可以手动开发。一般包括几个步骤: 1.模块和参数对话框制作 2.模块S 函数开发 3.模块TLC 文件开发
除了驱动模块之外,还有系统目标文件和一系列回调函数的开发。共同构成支持某一个目标芯片的驱动库。二
十七、生成代码该注意什么问题 问:生成代码该注意什么问题
答:要生成代码必须使用支持生成代码的模块,连续模块一般不支持代码生成,示波器等显示模块也不行。要生成代码,需要确定生成代码的类型,是嵌入式代码还是一般Windows 应用程序代码或其他类型代码,可以选择对应的System Target File,嵌入式通用代码选择ert.tlc, 快速原型代码使用grt.tlc.如果是为了使用各个芯片厂商提供的芯片,最好还要安装它们提供的TSP 工具箱和工具链,那里面会有配套的tlc 文件。二
十八、编写S 函数时,采样时间的设计
问:在编写S 函数时,初始化模块有关采样时间ts=[x1 x2],连续系统时设置为ts=[0 0];如果是离散系统,采样时间为h,那么可以写为ts=[h 0]吗?例如20us 采样一次,该怎么设计呢?
答:系统solver 设置为固定步长,设置为20us,然后在S 函数里设置采样ts = [-1, 0]来继承系统采样时间。二
十九、连续状态是否支持自动代码生成 问:连续状态是否支持自动代码生成? 答1:含有连续状态的模块不支持代码生成。因为要生成代码解算器必须是固定步长的,但是此种解算器不支持连续状态解算。答2:定步长连续1 阶积分好像可以生成代码,刚开始用dSPACE 的时候全选的是这个,后来才开始用离散。
答3:是的,ode3 等定步长算法也支持代码生成。看来连续模块不能生成代码的原因还需要讨论。
三
十、sine wave 模块中Sample based 和 Time based 的区别 问:sine wave 模块中Sample based Time based的区别在哪里?
答:Sample based 基于采样,Time based 基于时间,两种计算正弦的数学公式,根据你使用情况需要选择,如果你只有输入时间t 采用基于时间。如果是离散系统,一般使用采样点的序号来计算正弦。三
十一、simulink 中如何输入带参数的传递函数
问:如何输入分子为s+a,分母为s^2+2bs+b^2的传递函数?a,b 其实不是变量,只是由其他模块计算而来的。
答:transfer fcn 模块支持输入变量,变量只要定义在Workspace 里即可。三
十二、rtw 文件与tlc 文件的生成顺序 问:rtw 文件与tlc 文件的生成顺序是怎样的?
答:先写C 文件,编译成mex 之后才可以被模型调用,S 函数模块里的参数配置要正确,之后build 才能生产rtw。tlc 再从rtw 里面获取信息,进行代码生成。三
十三、M 语言编写的S 函数是否支持代码生成 问:M 语言编写的S 函数是否支持代码生成?
答:M 语言编写的S 函数也是有两种的,Level 1和Level2,Level1 仅支持仿真,不支持代码生成。Level2 支持代码生成。三
十四、如何在模型里面嵌入C 代码
问:某部分内容是c 代码封装的,如何在代码生成时把该部分代码直接连接添加?
答:可以使用custom code 模块,直接添加C 代码到模型中并生成到指定的位置,不进行仿真也不确保代码正确性。三
十五、Stateflow 如何代码生成共用体
问1:stateflow 的RTW 自动代码生成,怎么设置才能生成c 语言的共用体? 答1:楼主可以在Custom code 里面定义共同体,将此文件作为头文件包含,然后在Stateflow 模型里使用此共同体变量或其成员,生成代码时会自动Merge 在一起。
问2:Stateflow 使用的时候,signal 的属性怎么弄?比如:data type。答2:Stateflow 的运行都是要先生成C 代码,再编译成动态链接库文件(mex),然后才能运行的。所以,在custom code 设置通过C 代码或者C 文件定义出来的函数或者变量,只要符合C 语言语法规则,就可以被用到Stateflow 模型的各种action 里。
三
十六、如何将simulink 自动生成的代码中如何使用外部RAM 问:因为程序太大,想在SIMULINK 自动生成代码时直接将PAGE1 定位到外部RAM,请问如何设置?
答:通过数据对象的方式定义各类数据,使其定义到期望的RAM 区域。在手工编码的时候,遇到你说的这种情况,我们一般会通过在link 文件中定义RAM 段,然后在C 文件中定义变量的时候,通过pragma 关键字,把这些变量定义到预先设定的地址段里。所以,你做自动代码生成的时候,也需要生成出来通过pragma 定义的变量,这需要你通过数据对象的方式实现,并且,这种情况下,需要自定义Package,以及package 里的类,在类的属性storage class 里设置pragma。然后生成的代码里,就可以有类似于以下的代码: #pragma section_A begin int8_T var1;int16_T var2;............#pragma section_A end 这样var1、var2 等就被定义到section_A 存储区域了。
三
十七、如何拆分生成的代码中model_data.c里面定义的parameter 结构体? 问:在使用simulink embedded coder 生成的代码中,会将模型中的lookup table、constant 常数等统一放在了一个叫parameter 的结构体内(也就是在model_data.c 里面定义的数据)。由于整个模型中的lookup table 很多,导致这个结构体及其庞大,初步估计有7K byte 大小。请问有没有办法拆分这个结构体的体积?
答:使用数据对象定义这些参数,就可以不用放到model_data.c 文件了。三
十八、目标文件ert.tlc 与grt.tlc 的区别 问:grt 与ert 的区别在哪里?各自作用如何?
答:grt 中的g 表示general,ert 中的e 表示embedded,两个文件都是系统目标文件,使用grt.tlc 作为系统目标文件,生成的代码可以用作快速原型,而ert.tlc 生成的代码可以用于嵌入式系统。ert.tlc 生成的是更高效的代码。三
十九、关于触发子系统的总结 当系统内部不存在积分环节时:
1.触发子系统内外不能使用goto 和from 模块传递信号,这是由atomic 子系统属性决定的
2.触发子系统内的模块采样时间只能是inf 或者-1,即继承采样时间;当子系统内部有信号源时需注意该点
3.触发子系统的工作特性是在触发的一瞬间输出系统内该时刻的值,然后保持;触发子系统只可选择held 信号,而不能reset 信号。
4.触发子系统有信号源与外界接入信号源效果是一致的,但是内部信号源要修改采样时间为-1 5.子系统内的信号显示很有意思,是第一次触发开始的值到最后一次触发结束的值;中间数值都是保持状态。当系统内部存在积分环节时:触发子系统内部有积分环节并且需要改变积分初值,这个问题没有解决例如testforsubsystems中triggered subsystem。四
十、关于使能子系统的总结
1.当系统内部不存在积分环节时:使能触发子系统相当于一个触发子系统,使能环节的作用应包含在了触发子系统之内。
2.当系统内部存在积分环节时:使能触发子系统解决了触发子系统的有积分环节时不能解决的问题。四
十一、switch 的使用说明
该模块共有三个输入,其中第二个(即u2)为控制信号的输入,将其与阀值或者0 进行判断,判断类型有:大于等于阀值、大于阀值、不等于0 三种类型,默认判断为真时输出第一个信号,否则输出第三个信号。
第二篇:通信原理课设文档simulink
《通信原理》课程设计
开机,启动Matlab,在工作窗口Simulink。
模块库——>各个模块 Simulink:基本模块库
Commuinications Blockset:通信模块库 Signal Processing Blockset:信号处理模块库
基本原理:
1. 信源
通信工具箱:Communications Blockset——Comm Sources/Rondom Data Sources 选择:Bernoulli Binary Generator二进制伯努利序列产生器
Random Integer Generator 随机整数产生器 Signal Processing Blockset——signal Processing Sources
Sine Wave正弦波 2. 噪声源
Communications Blockset——Comm Sources/Noise Generators 选择:Gaussian Noise Generator高斯白噪声产生器
Rayleigh Noise Generator瑞利噪声产生器
Uniform Noise Generator均匀噪声产生器 3. 示波器
Simulink——〉Sinks——〉Scope 4. 相加器、增益、相乘器 Simulink——〉Math Operations——〉Add、Gain、Produc 5. 信道
高斯白噪声加性信道
Communications Blockset—〉Comm Sources—〉Noise Generators—〉Gaussian Noise Generator 6. 滤波器
Signal Processing Blockset——〉Filtering——〉Filter Designs——〉Digital Filter Design 低通滤波器的带宽:基带信号的带宽
带通滤波器的带宽:载波频率±基带信号的带宽 7. Relay(抽样判决器)
Simulink——〉Discontinuities——〉Relay 这是一个滞环比较器,一般用来作为调节有波动的系统时的缓冲。
parameters里的设置为:switch on point-阈值上限,switch off point-阈值下限,output when on-阈值上限输出值,output when off-阈值下限输出值。
例如某个信号的阈值上限为1.5,下限为0.5,上限输出为1,下限输出为0.当该信号上升到大于1.5时,relay的输出为1。若信号下一个周期小于1.5,但仍大于0.5时,其输出仍保持为1。只有当信号下降到小于0.5时,才会输出0。
它的意义是使信号调节有一个足够的范围宽度,而不至于因为每个周期都进行调节。8. 眼图、星座图、误码率
Communications Blockset—〉Comm Sinks——〉Discrete-Time Eye Diagram Scope Samples per symbol:每个符号的采样点数,自己计算1个二进制码元在系统中有多少个采样点,也就是要保证眼图窗口的时间宽度为整数个码元宽度(最好1、2个)。 Offset:非负整数,小于Samples per symbol和Samples per trace的乘积,指定在画第一个点时省略的采样点数。可调。
Samples per trace:正数,指定每一条轨迹的符号数目。如2,显示两个符号周期。 Traces displayed:叠加的轨迹的数目。
New traces per display:正整数,小于Traces displayed,指定每一次显示时新轨迹的数目。
Rendering Properties:线型和颜色设计 Axes Properties:x、y轴范围设计
Figure Properties:眼图显示的数据类型设计
Communications Blockset—〉Comm Sinks——〉Discrete-Time Scatter Plot Scope Communications Blockset—〉Comm Sinks——〉Error Rate Calculation
第三篇:实验报告 5 Simulink仿真
实验五 Simulink仿真
(一)一、实验目的
1、熟悉Simulink仿真环境
2、了解Simulink基本操作
3、了解Simulink系统建模基本方法
3、熟悉Simulink仿真系统参数设置和子系统封装的基本方法
二、实验内容
1、在matlab命令窗口中输入simulink,观察其模块库的构成;
2、了解模块库中常用模块的使用方法;
3、已知单位负反馈系统的开环传递函数为
G100s2s(s1)(s20)
建立系统的模型,输入信号为单位阶跃信号,用示波器观察输出。
4、建立一个包含Gain、Transfer Fcn、Sum、Step、Sine Wave、Zero-Pole、Integrator、Derivative等模块构成的自定义模块库Library1;
5、建立如图7-12所示的双闭环调速系统的Simulink的动态结构图,再把电流负反馈内环封装为子系统,建立动态结构图。
三、实验结果及分析:
图5-1
图5-2
图5-3
图5-4双闭环调速系统的Simulink的动态结构图
图5-5把电流负反馈内环封装为子系统的动态结构图
双击Subsystem模块,编辑反馈电流环Subsystem子系统,如图5-6所示:
图5-6
分析:Simulink是Mathworks开发的MATLAB中的工具之一,主要功能是实现动态系统建模、仿真与分析。可以在实际系统制作出来之前,预先对系统进行仿真与分析,并可对系统做适当的适时修正或按照仿真的最佳效果来调试及整定控制系统的参数,达到提高系统性能。减少涉及系统过程中的反复修改的时间、实现高效率地开发系统的目标。Simulink提供了建模、分析和仿真各种动态系统的交互环境,包括连续系统、离散系统和混杂系统,还提供了采用鼠标拖放的方法建立系统框图模型的图形交互界面。
第四篇:Matlab与Simulink仿真学习心得
Matlab与Simulink仿真学习心得
班级:07610 学号:072016 姓名:吕天雄
一 Matlab学习心得体会与编程实践
<1>学习Matlab的心得体会
真正开始接触Matlab是大二上就开始了,到现在已经一年多了,在此之间,Matlab的确为我提供了很多便利。Matlab的确不愧成为是草稿纸上的语言。我们不必去为很简单的显示效果图形去找一些什么其他软件或者研究比较复杂的计算机图形学,一个plot或者别的函数往往就可以得到很满意的效果。
其实最初开始学习matlab的时候感觉这个东西和C没什么两样,但是后来具体到一些 东西,比如信号处理和数学建模上以后才感觉到使用matlab编写程序去验证结果比C要节 省很多时间,而且matlab写东西基本都是按照自己的思路平铺直叙很少去考虑什么函数的 嵌套调用或者指针等等很头疼的东西。
关于matlab的学习,我感觉其实百度和matlab自带的help基本能够解决绝大数问题,而且一些比较好的论坛比如www.xiexiebang.com都会为你产生很大的帮助,关键是在于多动手实践,多思考。但是matlab毕竟只是一个工具,原理和一些基本的编程素质还是必须有的,否则matlab最多也只能是验证一些别人的东西而已,根本帮不上什么忙的。
<2>遇到的一些问题的思考方式与解决办法
最开始用matlab的时候是在大物实验,实验要求去根据测量得到的数据作出图。但是 手动用铅笔去画确实很麻烦,所以用matlab确实可以省去很大的麻烦。但是第一次遇到问 的时候是有关极化坐标下的曲线拟合。
首先是一个物理实验的问题;在做一个关于光的偏振的实验的时候,最后的结果要在一个极化坐标下显示出来;因为数据是离散的,所以显示出来的图像是一个折来折去的一个东东; 然后很自然的想法是对这个曲线进行插值处理。
但是极化坐标下MATLAB并未提供插值处理的函数,interp1这个函数只能在笛卡尔坐标系,也就是直角坐标系下使用。
然后就想到把极坐标的数据转换的直角坐标系下,pol2cart可以实现这个想法,但是随后而来,也就是最后导致整个问题失败的关键也在这里。
pol2cart以后产生的一串数据中出现了重复的数据,那么interp1这个东西也就无能为力了,因为interp1不能处理一串数据中有重复出现的情况。最后的处理办法是把这些数据c os,sin这些东西变换一下后,使其大致规则,然后再用polar画出极坐标下的图形。
接下来这个问题就有点超过我的范围了,可能会有点叙述不清楚。问题可以概要为:人脸网格插值。
这是一个用三角形网格表示的一个人脸模型。需要通过插值使其变得光滑,当然问题的复杂之处在于,插值会改变原本的网格结构。
对于这个问题许多人都给出了解决的办法,当然是一些关于人脸识别技术和运动图像处理的范畴之内的。
主要有两种,第一种是face—ls算法。这种算法是基于RBF(径向插值函数)和loop细分原则的一种算法,当然其精确程度比较差点。但是速度挺好。原理是:基于网格上的点,产生出顶点的迭代函数,从而产生出新的定点,进行细化。然后进行插值。也就是引进新的顶点。分为两个过程内部插值和边缘插值。具体可以去看兰州大学信息工程学院的学报。
第二种也就是基本的老办法RBF。首先解释一下什么叫做径向插值 径向基函数
主要是考虑多维空间的数据插值问题,径向基函数在三维图形的变形中常常被采用,用其来变分三维人脸的时候还应结合人脸的固有特征。确定该方法来实现三维人脸变形是可行的,但要构造好的基函数,以及解这些高维方程的解仍是难点。插值方法:
假设大多数人脸的形状都可以由一个拓扑原型变化得来,那么,通过调整一个一般模型的构造参数可以建立不同的面部模型。但是,这种参数模型仅仅局限于那些构造参数已知的情况,并且对特定人脸参数的调整非常困难。在离散数据的多变量插值问题方面,径向基函数(radial basis function,RBF)插值方法是一个行之有效的工具,所以也适用于类似人脸这样高维曲面的近似或平滑插值。现有的许多方法使用了基于RBF的插值技术,将一般人脸网格变化到特定人脸的形状。这种方法的优点在于:(1)通过插值可以得到丢失的数据点,所以源网格和目标网格不需要相同数目的结点;(2)如果选择了合适的匹配点,数学上可以保证能够将源网格变形到目标网格。
当然我也不是很懂,只是理解了部分。这种方法的关键是找到一个很好的核函数来计算出新的顶点。
最后问题解决的方式是查着了一些图书馆的学报。然后而且在网上找到了部分代码。然后做出来的。这是我校大四一个同学毕设中的一个东西。
其实这个事件最好的解决办法是在3D-MAX中,不过因为没能找到MATLAB与3D-MAX是怎么接口的,所以作罢了。
第三次遇到的问题是我在数学建模课上遇到的一个关于矩阵LU分解的问题:
Matlab作出的结果和手算的结果竟然不一样。
10111
U=1 一个矩阵 A= 经过三角分解为L=10111因为1/为一个极大数 则1—1/可以看成—1/;
设=0.***000000001%10的负24次方
从而L*U=则最后一位1没有了 变成了0
其中L=
U=Matlab 程序为
epusino=0.***000000001;U=[epusino 1;0-1/epusino];L=[1 0;1/epusino 1];L*U ans =
0.***
1.***
1.***
0 而直接用lu函数对矩阵A分解的结果为
A=[epusino 1;1 1] A =
0.0000
1.0000
1.0000
1.0000
>> [L,U]=lu(A)L =
0.0000
1.0000
1.0000
0
U =
0 我们老师当时的解释是这是由于我们所用matlab是破解版的缘故,破解版的计算精度 没正版的高所以导致运算结果的错误,后来我看了一些LU这个函数的help文档 psychologically lower triangular matrix"(i.e.a product of lower triangular and permutation matrices)in L。翻译过来是L是一个心理上的下三角矩阵,其实是下三角矩阵和置换矩阵也就是最后的结论。P*A = L*U.。由此可见这并不是什么精度的问题导致的结果只是LU分解的矩阵意义和书本上的不同而已。
以下是我自己写的一些程序的代码
1:网络随机拓扑图
目的是要生成一个度数随机、权值随机的拓扑图。首先的理解是利用邻接矩阵,先随机生成一个矩阵,该矩阵为一个对称矩阵。然后画出这个矩阵就行了。
随机拓扑图10026516398191 ***0430 ***065
%产生数组A用来存放表示两点之间权值的矩阵A,也就是临接矩阵,那么两点之间权值不为零元素的个数即为该点的度数
DEF=5;%设定一个东东 方便改变随机点的个数 A=rand(DEF,DEF);%产生DEF*DEF的随机矩阵 for i=1:DEF A(i,i)=0%将对角线上的数置为0 end A=10*A;A=floor(A);%向下去整 for i=1:DEF for j=1:i A(j,i)=A(i,j)%将A矩阵变为一个上三角或者下三角矩阵 end end x=100*rand(1,DEF);y=100*rand(1,DEF);%产生10个随机的点 plot(x,y,'r+');
for i=1:DEF a=find(A(i,:)>0)%将A矩阵每行大于0的数的在该行的地址找出来放在a中
for j=1:length(a)
c=num2str(A(i,j));%将A中的权值转化为字符型
if c~='0'%不显示为0的值 因为A矩阵为零代表两点不相连 text((x(i)+x(j))/2,(y(i)+y(j))/2,c,'Fontsize',18);%将权值显示在两点连线中间 end hold on;
line([x(i)x(a(j))],[y(i)y(a(j))]);%连线 end end
title('随机拓扑图');e=num2str(DEF);legend(e);%左上角显示节点的个数 for m=1:DEF A(m,m)=m;f=num2str(A(m,m));hold on;text((x(m)+x(m))/2,(y(m)+y(m))/2,f,'Fontsize',18);%将权值显示在两点连线中间 end 接下来是一个在信息安全课上写的一个关于256色图分层的程序,一副图像有m*n个像素然后每个像素是一个8bit的二进制数据换算为十进制是0-255之间。要做的就是把每bit的信息提取出来。
I=imread('bupt副本.bmp');%读入源图像
I=double(I);%将图像转换为double类型便于MATLAB中的计算 %确定图像的长宽 M=size(I,1);%长 N=size(I,2);%宽 l=M*N;%图像长宽之积 for n=1:8;%剔除每层 for i=1:M
for j=1:N
B=numdec2bin(I(i,j),8);%先将每个像素转换为8位2进制序列
B(n)=[];%删除相应位置的元素
y(i,j)=numbin2dec(B);%将剩下的7个元素转换为10进制数放入y矩阵中
end end
y=uint8(y);%将10进制的矩阵转换为无符号整形
subplot(4,2,9-n);%显示n个图像,每层是相应的剔除该层的结果
imshow(y);%显示这个图像
title(strcat('去除第',num2str(9-n),'层后的结果'));%显示标题 end
附带的两个函数:
function y=numdec2bin(x,n);%从函数将十进制数x转化为n位二进制 y=zeros(1,n);a=x;i=n;while a>0 y(i)=mod(a,2);a=floor(a/2);i=i-1;end function y=numbin2dec(x)%将二进制数转换为十进制数 a=0;lx=length(x);for i=1:lx a=a+x(i)*2^(lx-i);end y=a;
去除第1层后的结果去除第2层后的结果去除第3层后的结果去除第4层后的结果去除第5层后的结果去除第6层后的结果去除第7层后的结果去除第8层后的结果
Matlab的RGB转换为YCbCr之后转换回来和原图不符
这个是做JPEG图像压缩的时候遇到的一个问题,当时的代码是用C写的但是结果不对,后来想到用matlab进行验证结果发现通过公式转换得到的图是错的。
原理:BMP图像压缩为JPEG的第一步是将RGB色彩空间通过这个公式映射到YCbCr空间上。
Y=0.299 R + 0.587 G + 0.114 B Cb =0.3313G + 0.5 B + 128 Cr = 0.5 R0.0813 B + 128 然后再进行量化,DCT,编码等等步骤。JPEG解压时需要将YCbCr空间的图像又转化回来到RGB上。
R = Y + 1.402(Cr0.34414(Cb-128)128)
B = Y + 1.772(Cb-128)
但是通过书上给的公式和网上大部分公式却发现根本转化不会来。下面是写的程序代码以及测试得到的结果图像。
clc,clear;Source=imread('hl.jpg');%读入原始RGB图像
figure(1);subplot(1,2,1);imshow(Source):title('original image');%显示图像 [r c d]=size(Source);%计算图像大小 %------计算红色分量并显示分解图------% R(:,:,1)=Source(:,:,1);R(:,:,2)=zeros(r,c);R(:,:,3)=zeros(r,c);R=uint8(R);whos;figure(2);subplot(1,3,1);imshow(R)title('Red Component');%-------计算绿色分量并显示分解图-------% G(:,:,2)=Source(:,:,2);G(:,:,1)=zeros(r,c);G(:,:,3)=zeros(r,c);G=uint8(G);figure(2);subplot(1,3,2);imshow(G)title('Green Component');%--------计算蓝色分量并显示分解图-------% B(:,:,3)=Source(:,:,3);B(:,:,1)=zeros(r,c);B(:,:,2)=zeros(r,c);B=uint8(B);figure(2);subplot(1,3,3)imshow(B)title('Blue Component');%------------合成-------------% Comp(:,:,1)=R(:,:,1);Comp(:,:,2)=G(:,:,2);Comp(:,:,3)=B(:,:,3);figure(1);subplot(1,2,2);imshow(Comp):title('composition image');Y=0.229*R+0.587*G+0.114*B;Cb=0.5*B-0.1687*R-0.3313*G+128;Cr=0.5*R-0.4187*G-0.0813*B+128;red=Y+1.402*(Cr-128);green=Y-0.34414*(Cb-128)-0.71414*(Cr-128);blue=Y+1.772*(Cb-128);Comp2(:,:,1)=red(:,:,1);Comp2(:,:,2)=green(:,:,2);Comp2(:,:,3)=blue(:,:,3);figure(3);imshow(Comp2);title('RGB转换为YCrCb后又转换为RGB的图像');RD=R(:,:,1)-red(:,:,1);GD=G(:,:,2)-green(:,:,2);BD=B(:,:,3)-blue(:,:,3);figure(4);subplot(1,3,1);imshow(RD);title('红色分量差异');subplot(1,3,2);imshow(GD);title('绿色分量差异');subplot(1,3,3);imshow(BD);title('蓝色分量差异');
然而可以通过figure(4)的图像清楚看到R 和G分量转换后恢复 与以前的差别很大。而且看了一下matlab自带的rgb2ycbcr和ycbcr2rgb并且用了这两个函数测试后图像是一样的。很是不解
实验得到的图为: original imagecomposition image
将源图像分为RGB三个部分。
Red ComponentGreen ComponentBlue Component
将源图像的RGB分量转换到YCbCr上后又转化为RGB得到的三个分量差异的图。
红色分量差异绿色分量差异蓝色分量差异 公式转换的y分量公式转换的cb分量公式转换的Cr分量matlab函数转换的y分量matlab函数转换的Cb分量matlab函数转换的Cr分量
从最后的结果可以看出原图转换到YCbCr空间之后又转化回来得到的图像与原图不符….RGB转换为YCrCb后又转换为RGB的图像
以上只是我自己用Matlab做过的部分问题,还有一些比如场声源定位Music算法仿真,DES加密算法。神经网络滤波器等等,鉴于代码量太大,就不再敖述。二 Simulink学习心得与编程实践
SIMILINK模块库按功能进行分类,包括以下8类子库: Continuous(连续模块)Discrete(离散模块)
Function&Tables(函数和平台模块)Math(数学模块)
Nonlinear(非线性模块)
Signals&Systems(信号和系统模块)Sinks(接收器模块)Sources(输入源模块)
对于simulink来说其实没什么好说的,需要什么就把什么拖到Model里面,连线之后设定参数。不是很麻烦的。但是重要的是对于系统的设计与仿真思想才是最重要的。而且里面的S-Function也是比较好的一个设计,用S-Function可以自定义一些组件,使自己的仿真看上去更加清晰与精简。
Simulink的工作方式:
(1)模块内的参数值首先会送到Matlab中进行计算,得到的参数值会用来当做以后需要调用的参数。
(2)模型系统中的各个层级将被平展开来,每一个子系统将被相应的模块所代替。(3)模块按被处理的顺序排列,此时代数回路结构也被检查出来,此种排列产生一个列表,以确保具有代数回路的模块驱动输入的模块被更新后才更新。
(4)检查块之间的链接,是否每一个块的输出端口与它所连接的模块输入端口有相同的信号宽度。
现在可以准备执行仿真操作,仿真时使用数值迭代求的的结果,每种数值积分模型提供的连续状态的微分能力。
Simulink中的模型都是分级的,因此可以通过自上而下或者自下而上的方式建立模型。定义了一个模型以后,就可以通过Simulink的菜单或者在Matlab的Command中输入命令进行仿真。
关于学习的心得就写到这里了,接下来是一些自己做的仿真。
1:观察一个信号与积分之后的区别,目的是了解Scope的功能和用法。
仿真结果,左边为原始信号,右边为积分后的信号。
用XYGraph看到的对比
Rossler吸引子产生仿真:
Rossler 吸引子产生是服从下面这个方程的 1
212 331
仿真图 (xx)xxaxxbx(xc)xab0.2c5.7
仿真结果
LMS自适应滤波器: 仿真图:
遇到的问题
问题的解决办法:
将Spectrum Scope中的buffer input打勾就行了。
仿真结果图形:
1:Spectrum Scope的输出图形
2:Vector Scope的输出结果
3:Scope的输出结果图形
第五篇:MATLAB实验六《SIMULINK交互式仿真》
《计算机仿真及应用》实验教案
实验六 SIMULINK交互式仿真
一、实验目的
1、熟悉SIMULINK交互式仿真集成环境。
2、掌握连续时间系统建模的方法。
二、实验主要仪器与设备
装配有MATLAB7.6软件的计算机
三、预习要求
做实验前必须认真复习第七章SIMULINK交互式仿真集成环境。
四、实验内容及实验步骤
示的SIMULINK模块库浏览器。
《计算机仿真及应用》实验教案
图7.2 SIMULINK模块库浏览器
4、开启空白(新建)模型窗
单机Simulink模块库浏览器工具条上的图标“去的)。
5、从模块库复制所需模块到空白(新建)模型窗(见图7.3)
把连续模块子库中的积分器
”;或在选择下拉菜单项{File:
New},引出如图7.3所示的空白模型窗(注:窗中的模块是后一个步骤复制进
《计算机仿真及应用》实验教案
7.3 制进库模块的新建模型窗
6、新建模型窗中的模型再复制
在该新建模型窗中,可以通过再复制,产生建模所需的2个积分模块和2个增益 模块。具体操作方法是:按住[Ctrl]键,用鼠标“点亮并拖拉”积分模块
见一个所需的增益模块,可采用类似方法获得。
7、模块连接线的形成方法随信号起始端位置不同而不同,具体如下。
起始端位于模块输出口的信号线生成法。使光标靠近模块输出口;待光标变 为“单线十字叉”时,按下鼠标左键;移动十字叉,拖出一根“虚连线”;光标 与另一个模块输出口靠近到一定程度,单十字叉变为双十字叉;放开鼠标左键,”虚连线”便变为带箭头的信号连线。
起始端位于其他信号线上的信号线生成法。使光标置于已经存在的其他信号线 之上;按下鼠标右键,光标变为“单线十字叉”;运动鼠标,引出”虚连线”;当 鼠标与待连接模块输入口靠得足够近,单十字叉变为双十字叉;放开鼠标右键,“虚连线”便变为带箭头的信号连线。
双击相应的信号线,给信号线作标注,如x’’,x’,x等。
《计算机仿真及应用》实验教案
图7.4
已构建完成的新建模型窗
8、根据理论数学模型设置模块参数
为使构造的Simulink模型与理论数学模型一致,须对模块进行如下参数设置。
设置增益模块
《计算机仿真及应用》实验教案
修改求和模块输入口的代数符号:双击求和模块,引出如图7.1-6所示的参数设置窗; 把符号列表栏中的默认符号(++)修改成代数符号(--);单击【OK】键,完成设置;
图7.6 改变输出入口符号的求和模块参数设置窗
据初始位移x(0)=0.05m对积分模块
《计算机仿真及应用》实验教案
图7.7 实现初始化位移0.05设置的Integrator1设置窗
9仿真运行参数采用默认解算器“ode45”、默认“变步长”和默认仿真终止时间10.10把新建模型保存为exm070101.mdl.11试运行,以便发现问题加以改善。
双击
”仿真启动键,使该模型运行;在示波器上呈现
图7.8 坐标范围设置不当时的信号
《计算机仿真及应用》实验教案
单击Scope显示窗上的纵坐标范围自动设置图标“”,示波器显示窗改变为图7.9所
示。在显示窗中,可以看到位移x(t)的变化曲线。同时可以发现:纵坐标的适当范 围大致在【-0.06,0.06】;仿真时间取【0,5】即可;显示的曲线不够光滑。
图7.9 采用轴自动设置功能的信号显示
12、据试运行结果,进行仿真参数的再设置
示波器纵坐标设置:用鼠标单击示波器的黑色显示屏,在弹出菜单中选择Axes Properties,引出纵坐标设置对话窗7.10所示;把纵坐标的下限、上限分别设置为(-0.06)和(+0.06);单 击【OK】,完成设置。
示波器时间显示范围的修改:单击示波器的参数设置图标“
”,引出示波器参数设置窗;
在General卡片的Axes区的Time range栏中,填写5或auto;单击【OK】,完成设置。
图7.10 对显示屏的纵坐标范围进行设置
7.11 对示波器时间显示范围的设置
·仿真终止时间最简捷的修改方法:在exam070101模型窗“仿真终止时 间”栏“
”中的默认值10改变为5。
《计算机仿真及应用》实验教案
·显示曲线的光滑化设置:选中exam070101模型窗的下拉菜单项SimulationConfiguration Parameters,引出仿真参数配置窗,如图7.12所示;再在该窗左侧的选择栏中,选中Data Import/Export项,与之相应的参数设置栏便出现在窗口的右侧;把右半窗下方Save options 区中Refine factor栏中的默认值1改为5;单击OK,完成设置。
7.12 通过仿真参数配置窗设置输出光滑因子
《计算机仿真及应用》实验教案
完成以上修改后的模型窗如图7.13所示。再运行exam070101,可得比较满意的位移变化曲线(见图7.14所示)。顺便指出:模型运行后,在模块输出口的信号线上会出现double字样。这 表示该信号是采用“双精度”类型数据运算。如果用户不希望这类标识出现,那么应取消对下 拉菜单项FormatPort signal DisplaysPort Data Types的勾选。
图7.13
仿真参数调整运行后的exam070101模型
在模型窗中,x’’,x’,x等信号名称是模型创建者根据需要写入的。标识信号名称的操作方法 是:用鼠标双击信号附近的适当位置后,就会出现一个虚线框,该虚线框中允许输入任何 文字。
13、仿真结果显示
原本比较稀疏的解计算器数据,经设定的“光滑因子”下的插值,增加了用于描绘曲线的 数据点数,因此使示波器显示出更为光滑的曲线,如图7.14所示。
《计算机仿真及应用》实验教案
图7.14 适当地显示仿真所得的位移变化曲线
五、实验小结