专栏目录
simucpp:C++搭建微分方程求解器框架(重写simulink)
simucpp系列教程(1)安装教程
simucpp系列教程(2)例程解析(第一部分)
simucpp系列教程(3)例程解析(第二部分)
simucpp系列教程(4)使用教程与程序说明
simucpp系列教程(5)各模块的简要介绍
simucpp系列教程(6)函数文档
目录
(摘要)simucpp的第一部分例程解读,包含各种类型的常微分方程(组)、连续/离散传递函数和简单滤波器等。主要使用单元模块以及由单元模块构成的组合模块,均使用单线连接。
部分图片未及时更新,保留了以前版本使用 gdi+ 的作图图片,目前使用的是 matplotlib。
demo1 一阶系统
F
(
s
)
=
1
s
+
0.5
F(s)=\frac{1}{s+0.5}
F(s)=s+0.51
y
(
t
)
=
2
−
2
e
−
0.5
t
y(t)=2-2\text{e}^{-0.5t}
y(t)=2−2e−0.5t,
y
(
10
)
=
1.986524106001829
y(10)=1.986524106001829
y(10)=1.986524106001829
demo2 多个单元模块
积分器、单位延迟模块、传输延迟模块、零阶保持器效果展示。
demo3 mathieu方程
d
2
u
d
ϵ
2
+
(
a
−
2
q
cos
2
ϵ
)
u
=
0
\frac{d^2u}{d\epsilon^2}+(a-2q\cos 2\epsilon)u=0
dϵ2d2u+(a−2qcos2ϵ)u=0
y
(
0
)
=
1
y(0)=1
y(0)=1,
y
′
(
0
)
=
0
y'(0)=0
y′(0)=0,
y
(
15
)
=
5.8219712843
y(15)=5.8219712843
y(15)=5.8219712843
demo4 将文件中的数据加载到输入端口并直连到输出端口显示
首先生成一个包含数据的文件,一行一个点。下面是python生成数据和读取数据的示例代码。
import numpy as np
f = open("sinewave", 'w')
for n in range(100):
print(np.sin(0.1*n), file=f)
f.close()
import numpy as np
with open('sinewave', 'r+') as r:
data = []
for n in range(100):
text = r.readline()
data.append(float(text))
data = np.array(data)
注意要将生成的数据文件放到生成的exe文件的同级目录下。
demo5 单摆
m
l
θ
′
′
=
−
m
g
sin
θ
−
k
l
θ
′
x
′
′
=
−
k
m
x
′
−
g
l
sin
x
ml\theta''=-mg\sin\theta-kl\theta' \\ x''=-\frac{k}{m}x'-\frac{g}{l}\sin x
mlθ′′=−mgsinθ−klθ′x′′=−mkx′−lgsinx
demo6 简谐振动与共振
例题出自《高等数学》同济版第七版的常系数非齐次线性微分方程。
d
2
x
d
t
2
+
2
n
d
x
d
t
+
K
2
x
=
h
sin
p
t
x
′
′
+
5
x
=
0.5
sin
2.2
t
\frac{d^2x}{dt^2}+2n\frac{dx}{dt}+K^2x=h\sin pt \\ x''+5x=0.5\sin 2.2t
dt2d2x+2ndtdx+K2x=hsinptx′′+5x=0.5sin2.2t
通解
x
=
A
sin
(
k
t
+
ϕ
)
+
h
k
2
−
p
2
sin
p
t
x=A\sin(kt+\phi)+\frac{h}{k^2-p^2}\sin pt
x=Asin(kt+ϕ)+k2−p2hsinpt
对该问题
x
(
0
)
=
0
x(0)=0
x(0)=0,
x
′
(
0
)
=
1
x'(0)=1
x′(0)=1的特解
x
=
25
8
sin
2.2
t
−
47
40
5
sin
5
t
x=\frac{25}{8}\sin 2.2t-\frac{47}{40}\sqrt{5}\sin\sqrt{5}t
x=825sin2.2t−40475sin5t
x
(
150
)
=
−
2.185724668757026
x(150)=-2.185724668757026
x(150)=−2.185724668757026,误差约
1.5
×
1
0
−
10
1.5\times 10^{-10}
1.5×10−10
import numpy as np
x=150
(25/8)*np.sin(2.2*x)-(47/40*np.sqrt(5))*np.sin(np.sqrt(5)*x)
demo7 传递函数
F ( s ) = s + 2 s 2 + 2 s + 3 F(s)=\frac{s+2}{s^2+2s+3} F(s)=s2+2s+3s+2
demo8 线性微分方程组
例题出自方保镕《矩阵论》第二版的若尔当标准形。
{
d
y
1
d
x
=
−
y
1
+
y
2
d
y
2
d
x
=
−
4
y
1
+
3
y
2
d
y
3
d
x
=
y
1
+
2
y
3
\begin{cases} \frac{\text{d}y_1}{\text{d}x}=-y_1+y_2 \\ \frac{\text{d}y_2}{\text{d}x}=-4y_1+3y_2 \\ \frac{\text{d}y_3}{\text{d}x}=y_1+2y_3 \end{cases}
⎩
⎨
⎧dxdy1=−y1+y2dxdy2=−4y1+3y2dxdy3=y1+2y3
{
y
1
=
e
x
(
k
3
x
+
k
2
)
y
2
=
e
x
(
2
k
3
x
+
2
k
2
+
k
3
)
y
3
=
k
1
e
2
x
−
e
x
(
k
3
x
+
k
2
+
k
3
)
\begin{cases} y_1=\text{e}^{x}(k_3x+k_2) \\ y_2=\text{e}^{x}(2k_3x+2k_2+k_3) \\ y_3=k_1\text{e}^{2x}-\text{e}^{x}(k_3x+k_2+k_3) \end{cases}
⎩
⎨
⎧y1=ex(k3x+k2)y2=ex(2k3x+2k2+k3)y3=k1e2x−ex(k3x+k2+k3)
在初始条件
y
1
(
0
)
=
y
2
(
0
)
=
y
3
(
0
)
=
1
y_1(0)=y_2(0)=y_3(0)=1
y1(0)=y2(0)=y3(0)=1下,
y
1
(
1
)
=
0
,
y
2
(
1
)
=
−
e
y_1(1)=0,y_2(1)=-e
y1(1)=0,y2(1)=−e。仿真结果
y
1
(
1
)
=
9.89828878584
×
1
0
−
14
y_1(1)=9.89828878584\times10^{-14}
y1(1)=9.89828878584×10−14,
y
2
(
1
)
=
−
2.71828182846
y_2(1)=-2.71828182846
y2(1)=−2.71828182846。
demo9 一阶非齐次线性微分方程
微分方程
y
′
+
2
x
+
1
y
=
sin
x
y'+\frac{2}{x+1}y=\sin x
y′+x+12y=sinx的通解为
y
=
1
(
x
+
1
)
2
[
(
2
x
+
2
)
sin
x
−
(
x
2
+
2
x
−
1
)
cos
x
+
C
]
y=\frac{1}{(x+1)^2}[(2x+2)\sin x-(x^2+2x-1)\cos x+C]
y=(x+1)21[(2x+2)sinx−(x2+2x−1)cosx+C]
y
(
0
)
=
1
y(0)=1
y(0)=1的初始条件下
C
=
0
C=0
C=0
import numpy as np
x=15
((2*x+2)*np.sin(x)-(x*x+2*x-1)*np.cos(x))/(x+1)**2
y ( 15 ) = 0.835038831059 y(15)=0.835038831059 y(15)=0.835038831059,步长 2 − 10 2^{-10} 2−10下仿真15秒误差 < 1 0 − 12 <10^{-12} <10−12。
demo10 零极点对消
G
1
(
s
)
=
s
−
3
s
2
+
2
s
,
G
2
(
s
)
=
1
s
−
3
G_1(s)=\frac{s-3}{s^2+2s},\ G_2(s)=\frac{1}{s-3}
G1(s)=s2+2ss−3, G2(s)=s−31
上图为仿真10秒的结果,下图为仿真20秒的结果,左图为被控对象输出,右图为被控对象输入。
demo11 时滞系统
例题出自胡寿松《自动控制原理》第六版例5-10。开环传递函数
G
(
s
)
H
(
s
)
=
2
e
−
τ
s
s
+
1
G(s)H(s)=\frac{2\text{e}^{-\tau s}}{s+1}
G(s)H(s)=s+12e−τs
延迟时间
τ
<
2
3
3
π
\tau<\frac{2}{3\sqrt{3}}\pi
τ<332π时闭环稳定。
τ
=
2
3
3
π
−
0.01
\tau=\frac{2}{3\sqrt{3}}\pi-0.01
τ=332π−0.01时仿真15秒见下图。
延迟时间
τ
=
15
\tau=15
τ=15时仿真100秒见下图。
图中展示了两条曲线,分别是惯性环节和延迟环节一前一后和一后一前的情况,100秒后的输出值分别为
−
37.7005907666
-37.7005907666
−37.7005907666和
−
37.7025631374
-37.7025631374
−37.7025631374,不知道这误差算不算大。结果基本相同所以第二条曲线覆盖了第一条。
demo12 定积分
∫
−
1
3
(
x
+
1
)
2
d
x
=
64
3
\int_{-1}^3(x+1)^2\text{d}x=\frac{64}{3}
∫−13(x+1)2dx=364
令
y
(
x
)
=
∫
−
1
x
(
t
+
1
)
2
d
t
y(x)=\int_{-1}^x(t+1)^2\text{d}t
y(x)=∫−1x(t+1)2dt
则
y
′
(
x
)
=
(
x
+
1
)
2
y'(x)=(x+1)^2
y′(x)=(x+1)2
将输入函数设置为
(
x
+
1
)
2
(x+1)^2
(x+1)2,然后将仿真器的起止时间分别设置为积分上下限,然后取积分器的输出即可。
demo13 离散低通滤波器
D
(
z
)
=
0.008125
1
+
2
z
−
1
+
z
−
2
1
−
1.7
z
−
1
+
0.7325
z
−
2
D(z)=0.008125\frac{1+2z^{-1}+z^{-2}}{1-1.7z^{-1}+0.7325z^{-2}}
D(z)=0.0081251−1.7z−1+0.7325z−21+2z−1+z−2
demo14 离散传递函数与单步仿真
例题出自奥本海姆《离散时间信号处理》第三版例6.4。其中
a
1
=
0.75
,
a
2
=
−
0.125
,
b
0
=
1
,
b
1
=
2
,
b
2
=
1
a_1=0.75,a_2=-0.125,b_0=1,b_1=2,b_2=1
a1=0.75,a2=−0.125,b0=1,b1=2,b2=1。
H
(
z
)
=
b
0
+
b
1
z
−
1
+
b
2
z
−
2
1
−
a
1
z
−
1
−
a
2
z
−
2
H(z)=\frac{b_0+b_1z^{-1}+b_2z^{-2}}{1-a_1z^{-1}-a_2z^{-2}}
H(z)=1−a1z−1−a2z−2b0+b1z−1+b2z−2
下面是输出各个时刻的值的python代码。
x0 = 0
x1 = 0
x2 = 0
for n in range(11):
x0 = 1 + 0.75*x1 - 0.125*x2
y = x0 + 2*x1 + x2
x2 = x1
x1 = x0
print(y)
下面是cpp中的输出结果。需要注意的是虽然只仿真了10秒,但是内部实际上生成了10001个采样点(假设采样周期为1ms)。
0, 1, 1
1, 1001, 3.75
2, 2001, 6.6875
3, 3001, 8.546875
4, 4001, 9.57421875
5, 5001, 10.1123046875
6, 6001, 10.3874511719
7, 7001, 10.526550293
8, 8001, 10.5964813232
9, 9001, 10.6315422058
10, 10001, 10.649096489
demo15 代数环
每个环路(如果有的话)都必须包含至少一个积分器或单位延迟模块,否则就会报代数环错误。代数环的进一步说明见 代数环简介与代数环检测算法。
该例子包含两个仿真,一个复杂一个简单,可以将两个仿真分别修改成包含和不包含代数环的形式。