网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
% 主函数结束
% 下面是各个子函数,即各个回调过程
function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes
% 初始化回调子函数
% 提供状态、输入、输出、采样时间数目和初始状态的值
% 初始化阶段,标志变量flag首先被置为0,S-function首次被调用时
% 该子函数首先被调用,且为S-function模块提供下面信息
% 该子函数必须存在
sizes = simsizes; % 生成sizes数据结构,信息被包含在其中
sizes.NumContStates = 0; % 连续状态数,缺省为0
sizes.NumDiscStates = 0; % 离散状态数,缺省为0
sizes.NumOutputs = 0; % 输出个数,缺省为0
sizes.NumInputs = 0; % 输入个数,缺省为0
sizes.DirFeedthrough = 1; % 是否存在直馈通道,1存在,0不存在
sizes.NumSampleTimes = 1; % 采样时间个数,至少是一个
sys = simsizes(sizes); % 返回size数据结构所包含的信息
x0 = []; % 设置初始状态
str = []; % 保留变量置空
ts = [0 0]; % 设置采样时间
simStateCompliance = ‘UnknownSimState’;
function sys=mdlDerivatives(t,x,u)
% 计算导数回调子函数
% 给定t,x,u计算连续状态的导数,可以在此给出系统的连续状态方程
% 该子函数可以不存在
sys = []; % sys表示状态导数,即dx
function sys=mdlUpdate(t,x,u)
% 状态更新回调子函数
% 给定t、x、u计算离散状态的更新
% 每个仿真步内必然调用该子函数,不论是否有意义
% 除了在此描述系统的离散状态方程外,还可以在此添加其他每个仿真步内都必须执行的代码
sys = []; % sys表示下一个离散状态,即x(k+1)
function sys=mdlOutputs(t,x,u)
% 计算输出回调函数
% 给定t,x,u计算输出,可以在此描述系统的输出方程
% 该子函数必须存在
sys = []; % sys表示输出,即y
function sys=mdlGetTimeOfNextVarHit(t,x,u)
% 计算下一个采样时间
% 仅在系统是变采样时间系统时调用
sampleTime = 1; % 设置下一次采样时间是在1s以后
sys = t + sampleTime; % sys表示下一个采样时间点
function sys=mdlTerminate(t,x,u)
% 仿真结束时要调用的回调函数
% 在仿真结束时,可以在此完成仿真结束所需的必要工作
sys = [];
## S函数实例
使用 M 文件编写S函数形式有两种,Level 1 和 Level 2,二者的包装模块是不同的。
| 类型 | 优点 | 缺点 |
| --- | --- | --- |
| Level 1 | 运行速度快,能处理矩阵数据 | 只能处理点数据,不能处理复数以及基于帧的数据 |
| Level 2 | 能够处理的数据类型多,包括矩阵、复数以及基于帧的数据 | 运行速度慢 |
Level 1 M 文件S函数----这种方式提供了一个简单的 M 文件接口,可以与少部分的S函数 API 交互。Matlab 对于这种方式的支持更多的是为了保持与以前版本的兼容,现在推荐采用的是 Level 2 M 文件S函数。
下面是几个 Level-1 M-file S-function 的例子
### 连续有限输出的积分器
% 实现一个连续有限积分器,其中输出受下限和上限限制,并包括初始条件。
function [sys,x0,str,ts,simStateCompliance]=limintm(t,x,u,flag,lb,ub,xi)
switch flag
case 0
[sys,x0,str,ts,simStateCompliance] = mdlInitializeSizes(lb,ub,xi);
case 1
sys = mdlDerivatives(t,x,u,lb,ub);
case {2,9}
sys = []; % do nothing
case 3
sys = mdlOutputs(t,x,u);
otherwise
DAStudio.error(‘Simulink:blocks:unhandledFlag’, num2str(flag));
end
function [sys,x0,str,ts,simStateCompliance] = mdlInitializeSizes(lb,ub,xi)
sizes = simsizes;
sizes.NumContStates = 1;
sizes.NumDiscStates = 0;
sizes.NumOutputs = 1;
sizes.NumInputs = 1;
sizes.DirFeedthrough = 0;
sizes.NumSampleTimes = 1;
sys = simsizes(sizes);
str = [];
x0 = xi;
ts = [0 0];
simStateCompliance = ‘DefaultSimState’;
function sys = mdlDerivatives(t,x,u,lb,ub)
if (x <= lb & u < 0) | (x>= ub & u>0 )
sys = 0;
else
sys = u;
end
function sys = mdlOutputs(t,x,u)
sys = x;
### 一连续系统
蹦极跳是一种挑战身体极限的运动,蹦极者系着一根弹力绳从高处的桥梁或山崖向下跳。如果蹦极者系在一个弹性系数为
k
k
k 的弹力绳索上。定义绳索下端的初始位置为 0,则蹦极者受到的弹性力是
![弹性力](https://img-blog.csdnimg.cn/20190408111025940.png#pic_center)
整个蹦极跳系统的数学模型为:
![数学模型](https://img-blog.csdnimg.cn/2019040811124413.png#pic_center)
其中
m
m
m 为物体的质量,
g
g
g 为重力加速度取 10,
x
x
x 为物体的位置,第二项为物体受到的弹性力,第三项和第四项表示空气的阻力。桥梁距离地面的高度为 50m,绳子的原长为 30m,弹性系数
k
k
k 为 50,
a
1
=
a
2
=
1
a\_1 = a\_2 = 1
a1=a2=1。试判断质量为 70kg 的人是否能够安全地享受此游戏带来的乐趣。下图为整个系统的示意图。
![系统示意图](https://img-blog.csdnimg.cn/20190408111740533.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjczNjEzMA==,size_16,color_FFFFFF,t_70#pic_center)
解:为了便于后面的仿真计算,可以将物理模型写成如下状态方程形式:
![状态空间方程](https://img-blog.csdnimg.cn/58c7cc224edf4ca8bec70848044d6cf7.png#pic_center)
function [sys,x0,str,ts,simStateCompliance] = jumping(t,x,u,flag,len,m,height,k)
switch flag,
case 0,
[sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes(len,m,height,k);
case 1,
sys=mdlDerivatives(t,x,u,len,m,height,k);
case 2,
sys=mdlUpdate(t,x,u);
case 3,
sys=mdlOutputs(t,x,u,len,m,height,k);
case 4,
sys=mdlGetTimeOfNextVarHit(t,x,u);
case 9,
sys=mdlTerminate(t,x,u);
otherwise
DAStudio.error(‘Simulink:blocks:unhandledFlag’, num2str(flag));
end
function [sys,x0,str,ts,simStateCompliance]=mdlInitializeSizes(len,m,height,k)
sizes = simsizes;
sizes.NumContStates = 2;
sizes.NumDiscStates = 0;
sizes.NumOutputs = 1;
sizes.NumInputs = 0;
sizes.DirFeedthrough = 1;
sizes.NumSampleTimes = 1;
sys = simsizes(sizes);
x0 = [-len;0];
str = [];
ts = [0 0];
simStateCompliance = ‘UnknownSimState’;
function sys=mdlDerivatives(t,x,u,len,m,height,k)
if x(1)>0
b=-kx(1);
else
b=0;
end
sys = [x(2);10+b/m-1/mx(2)-1/m*abs(x(2))*x(2)];
function sys=mdlUpdate(t,x,u)
sys = [];
function sys=mdlOutputs(t,x,u,len,m,height,k)
sys = [height-len-x(1)];
function sys=mdlGetTimeOfNextVarHit(t,x,u)
sampleTime = 1;
sys = t + sampleTime;
function sys=mdlTerminate(t,x,u)
sys = [];
s-function 参数的配置:
![S函数参数配置](https://img-blog.csdnimg.cn/1858a5c5f27f4156b7e780bdc7f3b2b7.png#pic_center)
搭建 simulink 框图观察上述系统输出
![蹦极输出](https://img-blog.csdnimg.cn/09215c915c3249d8ad002378fff954ab.png#pic_center)
综上所述,此蹦极系统并不能让 70kg 的人嗨。
### 一离散系统
用 S-function 实现下面的离散系统:
![离散方程](https://img-blog.csdnimg.cn/6781801ec42a4d16a03906b099987b90.png#pic_center)
function [sys,x0,str,ts] = dsfunc(t,x,u,flag)
A=[-1.3839 0.5097
1.0000 0];
B=[-2.5559 0
0 4.2382];
C=[ 0 2.0761
0 7.7891];
D=[ -0.8141 -2.9334
1.2426 0];
switch flag,
最后
不知道你们用的什么环境,我一般都是用的Python3.6环境和pycharm解释器,没有软件,或者没有资料,没人解答问题,都可以免费领取(包括今天的代码),过几天我还会做个视频教程出来,有需要也可以领取~
给大家准备的学习资料包括但不限于:
Python 环境、pycharm编辑器/永久激活/翻译插件
python 零基础视频教程
Python 界面开发实战教程
Python 爬虫实战教程
Python 数据分析实战教程
python 游戏开发实战教程
Python 电子书100本
Python 学习路线规划
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!