其实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=AX(θ0)IX(θ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=AI=[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(Lr)+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=CI=[λcos(θ)1λsin(θ)λsin(θ)λcos(θ)1]
我之前令 λ = k ∗ ( L − r ) + 1 \lambda= k* (L-r)+1 λ=k(Lr)+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(Lr)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 limx0cos(x)=0

所以在旋转角非常小的情况下有:

λ c o s ( θ ) − 1 = k ∗ ( L − r ) c o s ( θ ) \lambda cos(\theta) -1=k* (L-r)cos(\theta) λcos(θ)1=k(Lr)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(Lr)cos(θ)λsin(θ)λsin(θ)k(Lr)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(Lr)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=eay+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)x2sin(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(a1X1+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(Lr)+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(a1X1+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)=[x1y1x2y2,......],由当前时刻所有耦合的向量构成。

耦合的目的就是当系统受到干扰脱离稳态空间,会随时间自适应的回到稳态空间。

假设某个分量 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)

注意:使用我的模型请注明出处,商业用途先征得我的同意。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐