CPG控制网络入门
从线性变换开始推导
其实CPG网络原理非常简单,我们先介绍一下线性变换中的旋转变换:
旋转变换
在x,y平面的逆时针旋转矩阵如下,角度为
θ
0
\theta_0
θ0的向量经过该旋转矩阵的变换则变为
θ
0
+
θ
\theta_0+\theta
θ0+θ的角度
X
(
θ
0
+
θ
)
=
[
c
o
s
(
θ
)
−
s
i
n
(
θ
)
s
i
n
(
θ
)
c
o
s
(
θ
)
]
∗
X
(
θ
0
)
X( \theta_0+ \theta) = \begin{bmatrix} cos(\theta) & -sin(\theta) \\ sin(\theta) & cos(\theta) \end{bmatrix} *X( \theta_0)
X(θ0+θ)=[cos(θ)sin(θ)−sin(θ)cos(θ)]∗X(θ0)
如果要求变化量,主要做差就找到了:
d
X
=
X
(
θ
0
+
θ
)
−
X
(
θ
0
)
dX=X( \theta_0+ \theta) -X( \theta_0)
dX=X(θ0+θ)−X(θ0)
令旋转矩阵为A,转化一下就是:
d
X
=
A
∗
X
(
θ
0
)
−
I
∗
X
(
θ
0
)
dX=A*X( \theta_0)-I*X( \theta_0)
dX=A∗X(θ0)−I∗X(θ0)
得到X变换为dX的矩阵B为:
B
=
A
−
I
=
[
c
o
s
(
θ
)
−
1
−
s
i
n
(
θ
)
s
i
n
(
θ
)
c
o
s
(
θ
)
−
1
]
B=A-I= \begin{bmatrix} cos(\theta)-1 & -sin(\theta) \\ sin(\theta) & cos(\theta)-1 \end{bmatrix}
B=A−I=[cos(θ)−1sin(θ)−sin(θ)cos(θ)−1]
当然,实际上由于每次旋转角度
θ
\theta
θ都是非常小的,所以
c
o
s
(
θ
)
cos(\theta)
cos(θ)非常接近于1
旋转向量的收敛
如果只是上面那样旋转,那么效果就是一个半径
r
=
x
2
+
y
2
r=\sqrt{x^2+y^2}
r=x2+y2的圆,x,y分别是X向量的坐标,由于只是旋转没有长度变化所以园是一个标准圆。现在我想让长度收敛到
L
L
L怎么办,很显然我们会用上矩阵特征值:
R
=
[
λ
1
0
0
λ
2
]
R= \begin{bmatrix} \lambda1 & 0 \\ 0 & \lambda2 \end{bmatrix}
R=[λ100λ2]
只要让特征值随着半径变化即可,这里需要用到负反馈知识:
如果向量长度r > 预期收敛长度L 则 特征值 λ < 1 \lambda<1 λ<1
如果向量长度r < 预期收敛长度L 则 特征值 λ > 1 \lambda>1 λ>1
所以我们可以设置 λ = k ∗ ( L − r ) + 1 \lambda= k* (L-r)+1 λ=k∗(L−r)+1,只不过得要求这个k非常小,必须让 λ \lambda λ能保持1附近,如在 [0.5,1.5]区间
这里的也就是拉伸的比例系数,k越大,收敛的越快,当然太大也不行,会发生震荡,想必这很容易理解。
另外为什么 λ \lambda λ不能小于0我就不说了,线性代数应该都熟悉。
接下来我们只要让R*A即可:
X
2
=
[
λ
0
0
λ
]
∗
[
c
o
s
(
θ
)
−
s
i
n
(
θ
)
s
i
n
(
θ
)
c
o
s
(
θ
)
]
∗
X
X2= \begin{bmatrix} \lambda & 0 \\ 0 & \lambda \end{bmatrix} * \begin{bmatrix} cos(\theta) & -sin(\theta) \\ sin(\theta) & cos(\theta) \end{bmatrix} *X
X2=[λ00λ]∗[cos(θ)sin(θ)−sin(θ)cos(θ)]∗X
我们将这个矩阵记为C,则有:
C
=
[
λ
c
o
s
(
θ
)
−
λ
s
i
n
(
θ
)
λ
s
i
n
(
θ
)
λ
c
o
s
(
θ
)
]
C= \begin{bmatrix} \lambda cos(\theta) & -\lambda sin(\theta) \\ \lambda sin(\theta) & \lambda cos(\theta) \end{bmatrix}
C=[λcos(θ)λsin(θ)−λsin(θ)λcos(θ)]
得到X变换为dX的矩阵D为
D
=
C
−
I
=
[
λ
c
o
s
(
θ
)
−
1
−
λ
s
i
n
(
θ
)
λ
s
i
n
(
θ
)
λ
c
o
s
(
θ
)
−
1
]
D=C-I= \begin{bmatrix} \lambda cos(\theta)-1 & -\lambda sin(\theta) \\ \lambda sin(\theta) & \lambda cos(\theta) -1 \end{bmatrix}
D=C−I=[λcos(θ)−1λsin(θ)−λsin(θ)λcos(θ)−1]
我之前令
λ
=
k
∗
(
L
−
r
)
+
1
\lambda= k* (L-r)+1
λ=k∗(L−r)+1,带入得:
λ c o s ( θ ) − 1 = k ∗ ( L − r ) c o s ( θ ) + [ c o s ( θ ) − 1 ] \lambda cos(\theta) -1=k* (L-r)cos(\theta) +[ cos(\theta) -1] λcos(θ)−1=k∗(L−r)cos(θ)+[cos(θ)−1]
假设单位旋转角 θ \theta θ非常小趋近于0,根据 c o s ( θ ) cos(\theta) cos(θ)的导数特性, [ c o s ( θ ) − 1 ] [cos(\theta) -1] [cos(θ)−1]就基本为0,这一项就可以忽略
l i m x → 0 c o s ′ ( x ) = 0 lim _{x\to0} cos'(x) = 0 limx→0cos′(x)=0
所以在旋转角非常小的情况下有:
λ c o s ( θ ) − 1 = k ∗ ( L − r ) c o s ( θ ) \lambda cos(\theta) -1=k* (L-r)cos(\theta) λcos(θ)−1=k∗(L−r)cos(θ)
我推导的变换矩阵就变成了
D
=
[
k
∗
(
L
−
r
)
c
o
s
(
θ
)
−
λ
s
i
n
(
θ
)
λ
s
i
n
(
θ
)
k
∗
(
L
−
r
)
c
o
s
(
θ
)
]
D= \begin{bmatrix} k* (L-r) cos(\theta) & -\lambda sin(\theta) \\ \lambda sin(\theta) & k* (L-r) cos(\theta) \end{bmatrix}
D=[k∗(L−r)cos(θ)λsin(θ)−λsin(θ)k∗(L−r)cos(θ)]
HOPF振荡器
先列一下公式:
d
x
d
t
=
α
(
μ
−
r
2
)
x
−
ω
y
\frac{dx}{dt}=α(μ−r^2)x−ωy
dtdx=α(μ−r2)x−ωy
d y d t = ω x + α ( μ − r 2 ) y \frac{dy}{dt}=ωx + α(μ−r^2)y dtdy=ωx+α(μ−r2)y
我们抽取一下形成矩阵:
d
X
=
[
α
(
μ
−
r
2
)
−
ω
ω
α
(
μ
−
r
2
)
]
∗
X
dX = \begin{bmatrix} α(μ−r^2) & −ω \\ ω & α(μ−r^2) \end{bmatrix} *X
dX=[α(μ−r2)ω−ωα(μ−r2)]∗X
有了我之前的模型,这个模型理解起来也非常容易,对照一下有:
k ∗ ( L − r ) c o s ( θ ) = α ( μ − r 2 ) k* (L-r) cos(\theta) = α(μ−r^2) k∗(L−r)cos(θ)=α(μ−r2)
λ s i n ( θ ) = ω \lambda sin(\theta) = ω λsin(θ)=ω
很明显两者实际上异曲同工,只不过我用的是L1范数,而他用的是L2范数。为了方便计算,不用开根号,我也用L2范数好了:
λ = k × ( μ − r 2 ) + 1 \lambda=k \times (μ−r^2)+1 λ=k×(μ−r2)+1
k × c o s ( θ ) × ( μ − r 2 ) = α ( μ − r 2 ) k \times cos(\theta)\times (μ−r^2)= α(μ−r^2) k×cos(θ)×(μ−r2)=α(μ−r2)
λ s i n ( θ ) = ω \lambda sin(\theta) = ω λsin(θ)=ω
我之前说过,k是特征值的拉伸系数,决定了长度L变化的快慢,实际上也就是收敛到圆环速度。我们再看HOPF的公式中的系数说明:
幅值: A = μ A = \sqrt{\mu} A=μ
周期: T = 2 π ω T = \frac{2\pi}{\omega} T=ω2π
收敛到圆环的速度: α 值 α值 α值
第一个很好理解,第三个也很好理解,和我的模型都一样,但第二个还有点不一样,我们再来取极限分析:
l i m θ → 0 s i n ( θ ) = θ lim_{\theta\to0}sin(\theta)=\theta limθ→0sin(θ)=θ
这个高数的等价无穷小,为什么我就不过多解释了,因为sin函数的导数在0附近是等于1的。
由于假设k取值较小,则 λ \lambda λ在1附近,我们按1算,所以我们近似得到:
λ s i n ( θ ) = θ \lambda sin(\theta) = \theta λsin(θ)=θ
单位旋转角为 θ \theta θ,一周是2π,所以周期T 自然是 2 π θ \frac{2π}{\theta} θ2π
所以说在各种系数非常小时,我的模型就蜕变为HOPF振荡器了。
注意:使用我的模型请注明出处,商业用途先征得我的同意。
相变
由于CPG通常用于机器人上,假设机器人的脚有一半时间是用来支撑地面的,另一半时间用来摆动,就是从地上提起来,换到另一个地方。这两段时间我们称为摆动相和支撑相。
其实这个在我的模型里非常好解决,就是角速度 θ \theta θ在不同区间,发生改变,这个改变可以参考绝对角度,比如角在[-90,90]区间, θ \theta θ变大一些,在[90,270]区间, θ \theta θ变小一些。
这个在CPG模型里,就不是特别好解决,引入了一个
β
\beta
β项和a参数,支撑相和摆动相的频率分别为
ω
s
t
\omega_{st}
ωst和
ω
s
w
\omega_{sw}
ωsw:
实际上也就是角速度是一个关于y的函数,我们来看一下系数
c
=
1
e
a
y
+
1
c=\frac{1}{e^{ay}+1}
c=eay+11
当y>0时, e a y 变得非常大 e^{ay}变得非常大 eay变得非常大,系数c非常小,区间为[ 0 , 0.5]
当y<0时, e a y 变得非常小 e^{ay}变得非常小 eay变得非常小,系数c非常大,区间为[ 0.5 ,1]
另一个系数 c 1 = 1 e − a y + 1 c1=\frac{1}{e^{-ay}+1} c1=e−ay+11,其实和c一样,相当于 c 1 = 1 e a ( − y ) + 1 c1=\frac{1}{e^{a(-y)}+1} c1=ea(−y)+11。这两个系数的作用,就是人y在变化的时候,使得角速度 ω \omega ω趋向于 ω s t \omega_{st} ωst或者 ω s w \omega_{sw} ωsw,原来式子改写为
ω = c 1 ∗ ω s t + c ∗ ω s w \omega= c1*\omega_{st}+ c*\omega_{sw} ω=c1∗ωst+c∗ωsw
当y>0时,系数c<0.5,c1>0.5, ω \omega ω趋向于 ω s t \omega_{st} ωst
当y<0时,系数c>0.5,c1<0.5, ω \omega ω趋向于 ω s w \omega_{sw} ωsw
当y=0时,系数c=0.5,c1=0.5, ω \omega ω为两者取平均
分析完系数的作用,我们来分析 ω s t = 1 − β β ω s w \omega_{st}=\frac{1-\beta}{\beta}\omega_{sw} ωst=β1−βωsw,我们移项一下得到:
β ∗ ω s t = ( 1 − β ) ∗ ω s w \beta*\omega_{st}=(1-\beta)*\omega_{sw} β∗ωst=(1−β)∗ωsw
我们假设有 1 = ω s t + ω s w 1=\omega_{st}+\omega_{sw} 1=ωst+ωsw,实际上我们换一个方式来理解:
ω s t = 1 − ω s w \omega_{st}=1-\omega_{sw} ωst=1−ωsw
也就是说 β \beta β和 ω s t \omega_{st} ωst是对偶形式,对原式变换有
( 1 − ω s w ) ∗ β = ( 1 − β ) ∗ ω s w (1-\omega_{sw})*\beta=(1-\beta)*\omega_{sw} (1−ωsw)∗β=(1−β)∗ωsw
两边各占半个周期,总周期为两边之和
调节
β
\beta
β越大,相当于调节支撑相的
ω
s
t
\omega_{st}
ωst越大(即 y<0时变化速度越快),如图所示:
由于向量是逆时针旋转,所以黄色部分是y>0时的状态,绿色部分是y<0时的状态。
黄色部分角速度趋向于 ω s w \omega_{sw} ωsw(摆动相),绿色部分趋向于 ω s t \omega_{st} ωst(支撑相)
耦合
其中
θ
j
=
2
π
(
φ
i
−
φ
j
)
\theta_j=2π(φ_i−φ_j)
θj=2π(φi−φj)
这个是相位差,比如 θ j = 45 度 \theta_j=45度 θj=45度,则说明向量Xi比Xj多转了45度,也就说Xj逆时针再旋转45度,将会和Xi的角度重合
假设我有两个旋转向量X1,X2,相位差 45度,那么上式就变为:
d x 1 d t = α ( μ − r 2 ) x 1 − ω y 1 + [ c o s ( 45 ) x 2 − s i n ( 45 ) y 2 ] \frac{dx1}{dt}=α(μ−r^2)x1−ωy1 + [ cos(45)x2 - sin(45) y2] dtdx1=α(μ−r2)x1−ωy1+[cos(45)x2−sin(45)y2]
d y 1 d t = ω x 1 + α ( μ − r 2 ) y 1 + [ s i n ( 45 ) x 2 + c o s ( 45 ) y 2 ] \frac{dy1}{dt}=ωx1 + α(μ−r^2)y1+ [ sin(45)x2 + cos(45) y2] dtdy1=ωx1+α(μ−r2)y1+[sin(45)x2+cos(45)y2]
我们把尾部的耦合项分离一下有:
d
X
1
=
D
X
1
+
M
X
2
dX_1= DX_1 + MX_2
dX1=DX1+MX2
我们来看一下后面的耦合项的含义:
δ
X
=
M
X
2
=
[
c
o
s
(
45
)
−
s
i
n
(
45
)
s
i
n
(
45
)
c
o
s
(
45
)
]
∗
X
2
\delta X =MX_2= \begin{bmatrix} cos(45) & −sin(45) \\ sin(45) & cos(45) \end{bmatrix} *X_2
δX=MX2=[cos(45)sin(45)−sin(45)cos(45)]∗X2
我们便抽取出了逆时针旋转45度的旋转矩阵,我们问为什么能这样做呢?
我们之前提到过,X2旋转45度,将会和X1的角度重合
不过这种耦合方式会引起联合反馈震荡,很容易会出相位震荡问题,如果要我来设计耦合模型,起码会换成如下形式:
d X 1 = D ( a 1 ∗ X 1 + a 2 ∗ ∣ ∣ X 1 ∣ ∣ ∗ M X 2 ∣ ∣ X 2 ∣ ∣ ) dX_1= D(a_1*X_1 + a_2*||X_1||*\frac{MX_2}{||X_2||}) dX1=D(a1∗X1+a2∗∣∣X1∣∣∗∣∣X2∣∣MX2)
其中a1取较大值,后面的a2,a3都取较小值,并且有a1+a2+a3… =1
注意:使用我的模型请注明出处,商业用途先征得我的同意。
我的模型大集会
X变换为dX的矩阵D为
d
X
1
=
D
X
1
=
[
λ
c
o
s
(
d
θ
)
−
1
−
λ
s
i
n
(
d
θ
)
λ
s
i
n
(
d
θ
)
λ
c
o
s
(
d
θ
)
−
1
]
X
1
dX_1=DX_1= \begin{bmatrix} \lambda cos(d\theta)-1 & -\lambda sin(d\theta) \\ \lambda sin(d\theta) & \lambda cos(d\theta) -1 \end{bmatrix} X_1
dX1=DX1=[λcos(dθ)−1λsin(dθ)−λsin(dθ)λcos(dθ)−1]X1
令 λ = k ∗ ( L − r ) + 1 \lambda= k* (L-r)+1 λ=k∗(L−r)+1,其中 r = ∣ ∣ X 1 ∣ ∣ r= ||X_1|| r=∣∣X1∣∣
若带旋转耦合项,则如下:
d
X
1
=
D
(
a
1
∗
X
1
+
a
2
∗
∣
∣
X
1
∣
∣
∗
M
X
2
∣
∣
X
2
∣
∣
)
dX_1= D(a_1*X_1 + a_2*||X_1||*\frac{MX_2}{||X_2||})
dX1=D(a1∗X1+a2∗∣∣X1∣∣∗∣∣X2∣∣MX2)
其中a1取较大值,后面的a2,a3都取较小值,并且有a1+a2+a3… =1
当然,我们要首先明确使用耦合的目的。
一个稳态系统必然有稳态解 [ X ( t 0 ) , X ( t 1 ) . . . . . . ] [X(t_0) ,X(t_1) ......] [X(t0),X(t1)......],这里的 X ( t ) X(t) X(t)是状态空间表示法, X ( t ) = [ x 1 , y 1 , x 2 , y 2 , . . . . . . ] X(t) =[x_1,y_1,x_2 ,y_2, ......] X(t)=[x1,y1,x2,y2,......],由当前时刻所有耦合的向量构成。
耦合的目的就是当系统受到干扰脱离稳态空间,会随时间自适应的回到稳态空间。
假设某个分量 x 1 ( t 0 ) x_1(t_0) x1(t0)由于外界干扰变成了 x 1 ( t 1 ) x_1(t_1) x1(t1),其他项如 y 1 ( t 0 ) y_1(t_0) y1(t0)也会自适应的变化到 y 1 ( t 1 ) y_1(t_1) y1(t1)。
注意:使用我的模型请注明出处,商业用途先征得我的同意。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)