相对全面的四足机器人驱动规划MATLAB和Simulink实现方式(足端摆线规划,Hopf-CPG,Kimura-CPG)

        许久没更新四足机器人相关的博客文章,由于去年一整年都在干各种各样的~活,终于把硕士毕业论文给写好,才有点时间更新自己的所学和感悟。步态规划和足端规划只是为了在运动学层面获取四足机器人各关节的期望角位移和速度信号,再由底层的关节控制器输出控制律(角加速度或力矩)使得期望和现实信号的偏差在容许范围内,今天将来探讨下四足机器人的三种常见的驱动方式,并用数值仿真和simscape仿真的方式验证所提出方法的有效性,对比其优缺点。

 图1. 四足机器人simscape实时交互仿真

1. 四足机器人步态定义

        依据文献[8],四足动物的步态是指各个腿之间具有固定相位关系的行走模式,不同的动物由于自身条件的限制,如腿长、腿的位置、神经控制方式等,其步态也会变得不一样。就如双足动物的“行走”、“奔跑”,四足动物的行走(Walk)、对角小跑(Trot)、奔跑(Gallop)、溜步(Pace)、跳跑(Bound)、原地四足跳跃(Pronk)。以 LF(左前腿)、RF(右前腿)、RB(右后腿)、LB(左后腿)分别替代四足动物的四条腿,然后可以根据其步态的特点得出它们各自的相位关系(左前腿作为参考基准,φ_LF=0  ,即相位为0,一个周期为2*pi ),以上步态的相位关系如表1所示。 步态是实现仿生四足机器人运动性能的基础规划,步态的协调性、连续性与可调整性直接决定着仿生四足机器人运动性能的优劣。

表1. 各种步态相位关系

        步态可以由特定的几个参数表征,相位差φ_i 、负载因子β、步态周期T、步长S、抬腿高度h,定义一个步态周期T内,腿部离地的时间被称为摆动相,撑地的时间称为支撑相,具体参数有以下定义:

表2. 机器人步态参数定义

        通过对四足动物的运动观察与分析,总结出了四足动物的步态描述表,其中的节奏可以分为单拍、双拍、准双拍、四拍步态,可以从四足动物足端拍打地面的节拍进行区分,例如Trot是双拍步态,Walk是四拍步态。另外,负载因子(步态占空比)β衡量腿部与地面的接触时间与步态周期的比重,有着重要的意义,因为当β等于0.5时,机器人在任意时刻或者平均约有两条腿支撑地面,而当β大于或者等于0.5的时候,说明机器人在任意时刻或者平均至少有三条腿支撑地面,这对机器人的步态输出有着极其重要的作用。其中,walk 步态β值为 0.75,trot 和其余常规步态的β为0.5。

图1.四足动物行走步态示意

        如图1所示,四足机器人起步时,左前腿LF抬起后以一定的足端轨迹向前跨步,待LF落地后紧跟着右后腿RB跨腿,之后再轮到RF、LB进行相同的动作,行走的过程中,该动作重复循环,步态周期较长并且在走动的过程始终保持三条腿在支撑身体。而小跑步态,先是LF与RB同时抬起并同步抬腿运动,当LF与RB重新落到地面时候,RF与LB跨腿,重复循环,为身体保持平稳,步态周期较短,在小跑过程中的任意时刻都只有对角腿在支撑身体,具体的相位拓扑关系分析见我的另一个文章EzekielMok。

2. 单腿正-逆向运动学计算

        要实现四足机器人的精准控制,需获取精确的关节角度空间下的角位移-角速度-角加速度与笛卡尔坐标下足端的位置-速度-加速度之间的映射关系,不同腿部结构的四足机器人的映射关系不一样,如有些是串联式的多关节机械臂,某些是并联式的机械臂,它们都可依据机器人学[1]的建模方法求解分析。

图2.四足机器人机身坐标定义

2.1 正向运动学分析

        根据机器人学[1]中的连杆上坐标系建模原则进行坐标变换,可以推导出一个包含姿态信息与位置信息的齐次矩阵

         其中,R为旋转矩阵,表征位姿变换;P为位置矩阵,表征位置变换;O是透视矩阵,此处元素全为0;I是比例变换矩阵,没有长度变化的情况下为1;n=[nx,ny,nz],n=[ox,oy,oz],n=[ax,ay,az]表示相对坐标系X,Y,Z参考坐标系的方向余弦;在R矩阵中每一步变换,有三种变换方式,即是分别绕X、Y、Z轴旋转相应的角度。现定A为参考坐标系,B为变换目标的相对坐标系,θ表示变换的转角,根据正交原则有如下的变换矩阵:

        有了以上的机器人学建模分析基础后,将图所示常见机构简化为以下图所示的机身腿节坐标分析模型。

图3.四足机器人抽象关节坐标定义 

       定义机身坐标如图3所示,其中机身前进方向为X,左右侧移方向为Y,高度方向为Z,假设侧摆关节之间的距离W,前后髋关节之间的距离L,机器人三个腿节长度L1、L2、L3。并以此为分析基点,分析四足机器人单腿的正-逆向运动学分析。采用机器人学应用最广泛的建模方法DH(Denavit-Hartenberg)方法[1],重要的两个建模原则是:1.对于笛卡尔坐标系,第i+1旋转关节的轴线方向始终指向Zi轴的正方向;2.对于笛卡尔坐标系,尽量把连杆的方向定为X轴的正向,即是Xi坐标的轴沿着Zi与Zi-1的公垂线,且指向Zi-1轴的负方向。

        四足机器人机身的中心为坐标基点到左前腿LF的过渡矩阵B1的变换矩阵推导如下:

         其中,Trans(·)为坐标系的平移变换矩阵公式,Rot(·)为旋转变换公式,L为机器人机体的长度,W为机体的宽度。同理推导得其他三个腿的过渡变换矩阵为

         定义机身的中心为坐标基点,以左前腿为例,依据机器人学的DH建模法给出连杆参数如下:

表3. 单腿连杆DH参数定义

       其中,ai是沿着xi方向,从zi到zi+1平移的距离;αi是绕着xi方向,从zi到zi+1转过的角度;di 是沿着zi方向,从xi-1到xi平移的距离,θi是绕着zi 方向,从xi-1到xi 转过的角度。Offseti是第i个关节的补偿值,作为初始姿态角。因此,机身中心到左腿足端的坐标变换矩阵定义为

         其中,

         式子中, s1=sin(θ1),c1=cos(θ1),s2=sin(θ2),c2=cos(θ2),s3=sin(θ3),c3=cos(θ3)。

         单腿正向向运动学计算代码(此处从B1坐标系转换至足端,机身中心至B1加个矩阵就行):

function [T,R,P] = Kine(L1,L2,L3,alpha_du,beta_du,gama_du)% 
%输出角度为弧度
% du_trans = 180/pi;
rad_trans = pi/180;
alpha = alpha_du*rad_trans;
beta  = beta_du*rad_trans;
gama  = gama_du*rad_trans;
T_01 = [[cos(alpha) -sin(alpha) 0 0];[sin(alpha) cos(alpha) 0 0];[0          0          1 0];[0          0          0 1]];
T_12 = [[cos(beta) -sin(beta)   0 0];[0          0            0 L1];[-sin(beta) -cos(beta)   1 0];[0          0            0 1]];T_23 = [[cos(gama) -sin(gama)   0 L2];[sin(gama)   cos(gama)   0 0];[0           0           1 0];[0           0           0 1]];
T_34 = [[1  0       0        L3];[0   1       0        0];[0   0       1        0];[0   0       0        1]];
%% 正向运动学矩阵
T = T_01*T_12*T_23*T_34;%% 可以通过替换参数直接求取结果
R = T(1:3,1:3);
P = T(1:3,4);
end

        至此,正向运动学求解完毕,可实现关节空间到笛卡尔空间的映射计算。 

 2.2 逆向运动学分析

         逆向运动学分析为了获取笛卡尔空间至关节空间的映射关系,可以通过期望的足端轨迹给定期望的关节角位移、角速度和角加速度期望控制量,是做四足机器人行为和稳定性控制的重要基础,具体方法包括几何求解法和解析解法。 以下将参考文献[2][3],利用几何解析法来求解单腿的逆向运动学。

图4.四足机器人侧视和前视图

         如图4所示,θ1是侧摆角,绕X轴旋转,最大旋转角度约束为\pm20度,初始转角为0度(初始站立姿态的转角);θ2是髋关节转角,最大旋转关节角度约束为 \pm35度(我自己simscape仿真里给定的,根据自己具体工况设计),初始转角为45度;θ3为膝关节转角,最大旋转关节角度约束为 \pm45度,初始转角为135度。        

        给定足端的期望空间位置(以机身坐标原点为起始坐标),以及连杆长度,机体长度和宽度(以腿节计算),以右手定则(图5)判定各坐标的方位和关节旋转角的正负值,利用几何法求解θ1,θ2,θ3。

图5.坐标正负方向定义右手定则(逆时针为正方向)

        首先求θ1,几何关系如图6所示,简单明了,用小学初中三角函数知识便可求解,需要注意的是actan(·)的求解范围要定义好,根据上述的坐标图示可知,此处的y和z坐标均为负,由右手定则可规定θ1为负。给定足端相对侧摆关节坐标B_{1}的参考坐标P_{xyz},根据图中的几何关系,会有以下等式:

图6. 单腿几何关系分析图示

 R=\sqrt{P_{xyz}^{2}(2)+P_{xyz}^{2}(3)}

L_{yz}^{'}=\sqrt{R^{2}-L_{1}^{2}}

 \theta_{1yz}=-arctan(\frac{P_{xyz}(2)}{P_{xyz}(3)})))

\theta_{1a}=-arctan(\frac{-L_1}{L_{yz}^{'}})))

\theta_{1}=\theta_{1yz}-\theta_{1a}

        其中,L_{yz}^{'}L_{1}L_{2}的正视投影长度,与末端坐标P_{xyz}的具体值相关。

        再者求θ3,如图7所示,腿节关系可以抽象为一个三角形,依据坐标设定,足端x方向的坐标假设为正值,根据余弦定理就可以直接求取θ2如下

L_{xz}^{'}=\sqrt{L_{yz}^{'2}+P_{xyz}^{2}(1))}

\theta_{3}=-arcos(\frac{L_{xz}^{'2}-L_3^2-L_2^2}{2L_2L_{3}})

        最后求θ2,也依赖于上述的抽象三角形关系,θ2由θ2a和θ2b两部分构成,根据正切三角关系和余弦定理可以直接求取θ2如下

\theta_{2a}=-atan(P_{xyz}(1)/L_{yz}^{'})

\theta_{2b}=-arcos(\frac{L_3^2-L_2^2-L_{xz}^{'2}}{2L_2L_{xz}^{'}})

\theta_2=\theta_{2a}+\theta_{2b}

图7. 单腿几何关系分析图示 

        单腿逆向运动学计算代码:

%代码实现方式1
function [alfa, beta, gamma]=xyztoang(x, y, z)h_up=49.0;h_mid=125.5899;h_low=116.0+20;dyz=sqrt(y.^2+z.^2);lyz=sqrt(dyz.^2-h_up.^2);gamma_yz=-atan(y./z);gamma_h_offset=-atan(h_up./lyz);gamma=gamma_yz-gamma_h_offset;lxzp=sqrt(lyz.^2+x.^2);n=(lxzp.^2-h_low^2-h_mid.^2)/(2*h_mid*h_low);beta=-acos(n);alfa_xzp=-atan(x/lyz);alfa_off=acos((h_mid+n)/lxzp);alfa=(alfa_xzp+alfa_off);
end
%代码实现方式2
function [theta] = Kine_inv(L1,L2,L3,P)% 
theta = zeros(3,1);
du_trans = 180/pi;
rad_trans = pi/180;
True = 1;
phai = atan2(P(2),P(1));%求角度
rlo = sqrt(P(1).^2 + P(2).^2);
rlo1 = sqrt(P(1).^2 + P(2).^2 - L1.^2);
if Truetheta(1) = phai - atan2(L1, rlo1);theta(1) = theta(1)*du_trans;
end
theta(3) = -acos((P(1).^2 + P(2).^2 + P(3).^2 - L1.^2 - L2.^2 - L3.^2)/(2*L2*L3));
theta(3) = theta(3)*du_trans;
a = P(1)*cos(theta(1)*rad_trans) + P(2)*sin(theta(1)*rad_trans);
b = -P(3);
rlo2 = sqrt(a.^2 + b.^2);
theta(2) = pi-asin((L3.^2 - L2.^2 - a.^2 - b.^2)/(-2*L2*rlo2)) - asin(a/rlo2);
theta(2) = theta(2)*du_trans;
end

         至此,运动学逆解求解完毕。

3. 行走足端轨迹约束条件

        通用引用四足机器人相关的文献和资料[2][3][4][7],要实现足式机器人理想的步态行走,其足端的空间轨迹需要满足:

  • 1. 行进平稳和协调,无明显的上下波动、左右摇晃和前后冲击;
  • 2. 各关节在摆动相抬腿和落地瞬间无较大冲突,可以无冲击抬腿和平滑落地;
  • 3. 摆动相跨腿迅速,足端轨迹平滑,关节速度和加速度平滑连续无畸点;
  • 4. 避免足端与地面发生滑动和拖地现象。

         为了满足上述的四个要求,假定此时(为便于分析,与上述机身的整体坐标不一样,整体的坐标)的蹬腿前进方向为X,抬腿高度方向为Y,在笛卡尔空间下对给定足端轨迹状态方程施加约束条件如下:

 图8. 机器人足端坐标定义

p_x(t=0)=0;p_x(t=\frac{T}{2})=S;p_x(t=T)=0

v_x(t=0)=0;v_x(t=\frac{T}{2})=0;v_x(t=T)=0

 a_x(t=0)=0;a_x(t=\frac{T}{2})=0;a_x(t=T)=0

p_y(t=0)=0;p_y(t=\frac{T}{4})=H;p_y(\frac{T}{2}\leq t\leq =T)=0

v_y(t=0)=0;v_y(t=\frac{T}{4})=0;v_y(\frac{T}{2}\leq t\leq =T)=0

a_y(t=0)=0;a_y(t=\frac{T}{4})=0;a_y(\frac{T}{2}\leq t\leq =T)=0

        其中,p_x,p_y分别是X方向和Y方向的笛卡尔坐标位置,v_x,v_y为速度,a_x,a_y为加速度,S为抬腿,步长H为抬腿高度。

4.足端复合摆线规划

        足端摆线规划是当前四足机器人最常见的驱动方式[2][4],如波士顿动力学spotdog,MIT,绝影,宇树、淘宝上各种无刷电机狗以及舵机狗都是采用摆线规划,可见其实用性。足端摆线规划是将四足机器人行走时候的足端运动建模成一个空间中运动的摆线,这样能够尽量减少足端在触地瞬间的爆发冲击,更好地与地面摩擦,实现机身的前进驱动。

        摆线,又称旋轮线、圆滚线,在数学中,摆线(Cycloid)被定义为,一个圆沿一条直线运动时,圆边界上一定点所形成的轨迹。它是一般旋轮线的一种。标准摆线的参数方程为

\left\{\begin{array}{l} x=r (\theta-\sin (\theta)) \\ y=r (1-\cos (\theta)) \end{array}\right.

         其中,r表示摆线圆弧的半径,\theta为滚动角。摆线的MATLAB数值仿真绘制代码如下:

%Ezekiel
%2023年3月25日
%% 清理变量
clc;
clear;
close all;
n=2000;
r = 1;
for index = 0:1:ntheta = 5*pi/1000*index;x(index+1) = r*(theta - sin(theta));y(index+1) = r*(1 - cos(theta));
end
plot (x, y,'-r','linewidth',1);
axis equal
grid on
xlabel('X')
ylabel('Y')

 图9. 摆线数值仿真示意 

         单纯的摆线能够很好地满足足端轨迹状态方程的约束条件,但是与地面接触时候存在着滑动和行为时候出现拖地的现象,因此根据文献[11]对摆线规划进行针对性设计,为复合摆线规划,其参数方程定义为

\left\{\begin{array}{c} x(t)=\frac{S}{2 \pi}\left(2 \pi \frac{t}{T_{sw}}-\sin \left(2 \pi \frac{t}{T_{sw}}\right)\right) \\ y(t) =\frac{H}{2 \pi}\left(1-\cos \left(2 \pi \frac{t}{T_{sw}}\right)\right) \end{array}\right.

        其中,S为抬腿步长,H为抬腿高度,T_{sw}  为摆动相时间。具体的MATLAB代码实现如下

function [X, Y] = Gait_cal(S_0,H,Ty,Tst,index1,Point_num_Tt)
%% 改进的复合摆线规划
r = S_0/(2*pi); % 摆线的半径
Tt = Ty + Tst; % 计算周期长度,摆动相和支撑相
Tsa = Tt/(Point_num_Tt-1);%计算所处周期序列
n = 4;
%% 摆动相与支撑相分别规划
% 取模运算Trun = (index1 - 1)*Tsa;%时刻 if Trun >= 0 && Trun < Ty/2Sgn_1 = 1;elseSgn_1 = -1;endif Trun >= 0 && Trun < TyX = r*(2*pi*Trun/Ty - sin(2*pi*Trun/Ty)); % x方向if Trun  < Ty/2Fe = Trun/Ty - (1/(n*pi))*sin((n*pi*Trun)/(Ty));Y = 2*H*(Trun/Ty - (1/(n*pi))*sin((n*pi*Trun)/(Ty)));elseFe = Trun/Ty - (1/(n*pi))*sin((n*pi*Trun)/(Ty));Y = H*(Sgn_1*(2*Fe - 1) + 1);endelseX = 2*pi*r - r*(2*pi*(Trun - Ty)/(Tt - Ty) - sin(2*pi*(Trun - Ty)/(Tt - Ty))); % x方向Y =0;end 
end

        为了便于周期性输入控制接入,利用周期性的方波信号控制摆线的频率(周期),简单来说,就是利用方波的输入控制四足机器人的抬腿和落脚时间,可以通过占空比的形式直接控制摆动相和支撑相的比例,进而控制实现四足机器人各种不同的步态,具体的调制原理可见代码和simulink实现环节。

%Ezekiel
%2023年3月25日
%% 清理变量
clc;
clear;
close all;
n=2000;
t_total = 6*pi/2;
t=linspace(0,t_total,n);%转一圈
ts=t_total/n;
trace_sq = nan+t;%轨迹配置初始化,空值
trace_xyz = nan+[t;t;t];%轨迹配置初始化,空值
trace_abg= nan+[t;t;t];%轨迹配置初始化,空值
trace_triang = nan+t;%轨迹配置初始化,空值
k=0;
omega = 2*pi;% 控制步态周期
siggnal_sq_intergration1 = 0;
siggnal_sq_intergration2 = 0;
S = 50;
H = 40;
Tm = 0.5;
for j=tk=k+1;singnal_sq1_1 =0.5*square(omega*j)+0.5;singnal_sq1_2 =0.5*square(omega*j/2)+0.5;singnal_sq2_1 =0.5*square(2*omega*j)+0.5;singnal_sq2_2 =0.5*square(omega*j)+0.5;siggnal_sq_intergration1 = siggnal_sq_intergration1 + ts*logic_clock(singnal_sq1_1);singnal_triang1 = siggnal_sq_intergration1*logic_clock(singnal_sq1_2);siggnal_sq_intergration2 = siggnal_sq_intergration2 + ts*logic_clock(singnal_sq2_1);singnal_triang2 = siggnal_sq_intergration2*logic_clock(singnal_sq2_2);trace_triang(k)=  siggnal_sq_intergration1;x_3d = cycloid_x(singnal_triang1,Tm,S);z_3d = 150-cycloid_y(singnal_triang2,Tm,H);y_3d = 49;[alfa_dg, beta_dg, gamma_dg]=xyztoang( x_3d, y_3d,  z_3d);trace_xyz(:, k)= [x_3d;y_3d;z_3d];trace_abg(:, k)= [alfa_dg; beta_dg; gamma_dg];trace_sq(k)= singnal_sq1_1;
end
subplot(4,1,1)
plot(t,trace_sq(:),'red')
% title('Kimura振荡器输出')
ylabel('pulse')
axis([0,t_total ,-0.5,1.5])%XY坐标均衡
grid on;
subplot(4,1,2)
plot(t,trace_triang(:),'blue')
ylabel('trangpulse')
axis([0,t_total ,0,1])%XY坐标均衡
grid on;
subplot(4,1,3)
plot(trace_xyz(1, :),trace_xyz(3, :),'red')
ylabel('XY-plot')
axis([0,50 ,100,160])%XY坐标均衡
grid on;
subplot(4,1,4)
plot(t, trace_abg(1, :), 'blue', t, trace_abg(2, :), 'red',t, trace_abg(3, :), 'green')
ylabel('theta')
axis([0,t_total ,-3,2])%XY坐标均衡
grid on;
function y = logic_clock(u)
if u==0y = -1;
elsey=1;
end
end
function x = cycloid_x(u,Tm,S)if u>0x =S*(u/Tm-1/(2*pi)*sin(2*pi*u/Tm));else u=-u;x =S*(u/Tm-1/(2*pi)*sin(2*pi*u/Tm));end
end
function y = cycloid_y(u,Tm,H)n=4;if u>0y=2*H*(u/Tm-1/(n*pi)*sin(n*pi*u/Tm)).*(u>=0&u<Tm/2)+...2*H*(1-u/Tm+1/(n*pi)*sin(n*pi*u/Tm)).*(u>=Tm/2&u<Tm);else y=0;end
end
function [alfa, beta, gamma]=xyztoang(x, y, z)h_up=49.0;h_mid=125.5899;h_low=116.0+20;dyz=sqrt(y.^2+z.^2);lyz=sqrt(dyz.^2-h_up.^2);gamma_yz=-atan(y./z);gamma_h_offset=-atan(h_up./lyz);gamma=gamma_yz-gamma_h_offset;lxzp=sqrt(lyz.^2+x.^2);n=(lxzp.^2-h_low^2-h_mid.^2)/(2*h_mid);beta=-acos(n/h_low);alfa_xzp=-atan(x/lyz);alfa_off=acos((h_mid+n)/lxzp);alfa=(alfa_xzp+alfa_off);
end

 图10. 摆线规划数值仿真示意  

        至此,摆线规划设计完毕。

5. Hopf-CPG振荡器驱动

        生物的节律步态[7]是生物神经节律控制机理产生的一种自激振荡、相位互锁的运动模式,由生物低级神经中枢的中枢模式发生器 ( Central pattern Generator, CPG)产生的节律信号控制。常见的四足动物都是进行节律运动的。节律运动[1]是指空间和时间对称的周期性运动,譬如走、跑、跳等。因此,要实现四足机器人的稳定运动,就需要控制器能够产生具有周期性、对称性的节律信号,来控制各个关节(执行器)实现机体的节律运动。这种控制方式就是(CPG)中枢神经控制模式。
CPG是节律运动的中心控制器,不仅需要产生节律信号,控制执行器进行运动,还需要根据反馈信号进行识别,及时修改生成新的信号,使四足机器人能够稳定行走。

     根据第三节中行走足端轨迹约束条件,设计足间相位关系如下(参考文献[7][8][9])

        其中,\theta_{h} 为髋关节的角位移状态,\theta_{k}为膝关节位移状态,A_{h}为髋关节幅值,A_{k}膝关节幅值,\Psi为控制腿节布置关系的标志位。其中,A_{h}A_{k}的具体取值可以依据步长和抬腿高度,利用第2.2节中所设计的运动学逆解关系求解,如抬腿高度是H,步长为S,逆向运动学求出最大的关节摆动幅度即可。

       根据前两节足间与足内的拓扑关系可以构建出四足机器人的分层拓扑关系图(注:一般图论中箭头表示信号传递,但此处箭头表征指向方向与起始点腿的相位差)

 图11. 各腿关节的相位拓扑关系

        作为仿生机器人控制方式,CPG模型可以划分为两种,第一种是基于神经元的模型,十分贴切生物,但是模型复杂,如Kimura[5][6];第二种是基于非线性振荡器的模型[10],模型相对比较简单,模型运用相当成熟。数学上,常用的非线性振荡器有Hopf、Rayleigh、Matsuoka等振荡器,其中Hopf振荡器是一种谐波振荡器,结构简单,控制实现容易,因此本文采用 Hopf 振荡器来建立。

        单个Hopf振荡器的数学表达式:

        根据上节给定的拓扑关系构建的8路(髋关节4路、膝关节4路)Hopf振荡器的状态方程,可以利用积分器对该微分方程进行求解:

        坐标变换阵或者说是步态权重矩阵,这个矩阵利用坐标变换原理,使得不同腿、关节之间的信号相位可以按照步态矩阵θij(i=1,...,4;j=1,...,4,表示腿间相位关系)给定的相位关系生成。 

表4. Hopf-CPG配置参数

%Ezekiel Mok
%2023年3月29日
clc;
clear;
close all
tic
%CPG构建基本参数
Alpha=10;%收敛速度
leg_num=4;%腿的数量
gait=2;%步态选择,1walk,2trot,3pace,4gallop
u=1;%影响曲线幅值,幅值为开根号
a=50;%决定w在Wsw和Wst之间变化的速度
Psa=1;%关节形式,膝式-1,肘式1
Wsw=2*pi;%摆动相频率,影响信号周期,T为2*pi/Wsw
u1=0; u2=0;%误差,影响x,y的平衡位置%关节参数,此处参数需实测,试验数据参考书
h=0.02;  %抬腿高度
v=1;   %行走速度
T=0.4; %步态周期
S=v*T; %步长
l=0.4;   %腿节长度
theta0=30/180*pi;%髋关节和膝关节平衡位置与垂直线夹角 
L=2*l*cos(theta0);%髋关节与足端之间长度
Ah=8.3;%asin((Beta*S)/(2*L));%髋关节摆动幅度
Ak=5.3;%acos((l*cos(theta0)-h)/l)-theta0;%膝关节摆动幅度%负载系数对相关参数影响
switch gaitcase 1Beta=0.75;%负载系数,walk为0.75,trot,pace,gallop为0.5,影响振荡信号上升时间和下降时间Ah=8.3;%asin((Beta*S)/(2*L));%髋关节摆动幅度Ak=5.3;%acos((l*cos(theta0)-h)/l)-theta0;%膝关节摆动幅度case 2Beta=0.5;Ah=8.3;%髋关节摆动幅度Ak=5.3;%膝关节摆动幅度case 3Beta=0.5;Ah=10;%asin((Beta*S)/(2*L));%髋关节摆动幅度Ak=5.3;%acos((l*cos(theta0)-h)/l)-theta0;%膝关节摆动幅度case 4Beta=0.5;Ah=13.4;%asin((Beta*S)/(2*L));%髋关节摆动幅度Ak=10;%acos((l*cos(theta0)-h)/l)-theta0;%膝关节摆动幅度
endWst=((1-Beta)/Beta)*Wsw;%支撑相频率Rhk=(1-Beta)*[cos(pi) -sin(pi);sin(pi) cos(pi)];%髋关节和膝关节之间的耦合矩阵
%时间
Pon_num=5000;
t_begin=0; t_end=30; t_step=(t_end-t_begin)/(Pon_num-1);
t=zeros(Pon_num,1);
for  n=1:Pon_numt(n)=(n-1)*t_step+t_begin;
end
%初始值,非0即可
leg_x=zeros(leg_num,1);
leg_y=zeros(leg_num,1);
for i=1:leg_numleg_x(i)=0.5;leg_y(i)=0.5;
end%CPG曲线,左前1,右前2,右后3,左后4
leg_h_Point_x=zeros(Pon_num,leg_num);%髋关节
leg_h_Point_y=zeros(Pon_num,leg_num);
leg_k_Point_x=zeros(Pon_num,leg_num);%膝关节
leg_k_Point_y=zeros(Pon_num,leg_num);
Foot_end_x=zeros(Pon_num,leg_num);%足端
Foot_end_y=zeros(Pon_num,leg_num);Phi=zeros(leg_num,1);
switch gaitcase 1   %walk相位Phi(1)=0*2*pi;    %Phi_LFPhi(2)=0.5*2*pi;  %Phi_RFPhi(3)=0.25*2*pi; %Phi_RHPhi(4)=0.75*2*pi; %Phi_LHcase 2%trot相位矩阵Phi(1)=0*2*pi;Phi(2)=0.5*2*pi;Phi(3)=0*2*pi;Phi(4)=0.5*2*pi;case 3%pace相位矩阵Phi(1)=0*2*pi;Phi(2)=0.5*2*pi;Phi(3)=0.5*2*pi;Phi(4)=0*2*pi;case 4%gallop相位矩阵Phi(1)=0*2*pi;Phi(2)=0*2*pi;Phi(3)=0.5*2*pi;Phi(4)=0.5*2*pi;    
end %相对相位矩阵R_cell={leg_num,leg_num};for i=1:leg_numfor j=1:leg_numR_cell{j,i}=[cos(Phi(i)-Phi(j)) -sin(Phi(i)-Phi(j));sin(Phi(i)-Phi(j)) cos(Phi(i)-Phi(j))];endendfor  n=1:Pon_numfor i=1:leg_numr_seq=(leg_x(i)-u1)^2+(leg_y(i)-u2)^2;W=(Wst/(exp(-a*leg_y(i))+1))+(Wsw/(exp(a*leg_y(i))+1));V=[Alpha*(u-r_seq) -W;W Alpha*(u-r_seq)]*[leg_x(i)-u1;leg_y(i)-u2]+R_cell{1,i}*[leg_x(1)-u1;leg_y(1)-u1]+R_cell{2,i}*[leg_x(2)-u2;leg_y(2)-u2]+R_cell{3,i}*[leg_x(3)-u1;leg_y(3)-u2]+R_cell{4,i}*[leg_x(4)-u1;leg_y(4)-u2];leg_x(i)=leg_x(i)+V(1,1)*t_step;leg_y(i)=leg_y(i)+V(2,1)*t_step;leg_h_Point_x(n,i)=leg_x(i);leg_h_Point_y(n,i)=leg_y(i);if leg_y(i)>0leg_k_Point_x(n,i)=0;elseif(i<3)leg_k_Point_x(n,i)=-sign(Psa)*(Ak/Ah)*leg_y(i);elseleg_k_Point_x(n,i)=sign(Psa)*(Ak/Ah)*leg_y(i);endendFoot_end_x(n,i)=sin(leg_k_Point_x(n,i)/sqrt(u)*Ak*(pi/180)+theta0)*l-sin(theta0+leg_h_Point_x(n,i)/sqrt(u)*Ah*(pi/180))*l;Foot_end_y(n,i)=L-(cos(leg_h_Point_x(n,i)/sqrt(u)*Ah*(pi/180)+theta0)*l+cos(leg_k_Point_x(n,i)/sqrt(u)*Ak*(pi/180)+theta0)*l);end
end  
%画图
for i=1:4subplot(4,3,i+2*(i-1))plot(leg_h_Point_x(:,i),leg_h_Point_y(:,i))subplot(4,3,i+1+2*(i-1))hold onplot(t,leg_h_Point_x(:,i))plot(t,leg_k_Point_x(:,i))hold off
end
hold on
subplot(4,1,1)plot(t,leg_h_Point_x(:,1),'b');hold onplot(t,leg_k_Point_x(:,1),'red');grid onylabel('LF')axis([0,t_end,-1.5,1.5])%XY坐标均衡%title('Hopf振荡器的输出');legend('thetah','thetak');grid on;
subplot(4,1,2)  plot(t,leg_h_Point_x(:,2),'b');hold onplot(t,leg_k_Point_x(:,2),'red');grid onylabel('RF')axis([0,t_end,-1.5,1.5])%XY坐标均衡legend('thetah','thetak');
subplot(4,1,3)plot(t,leg_h_Point_x(:,3),'b');hold onplot(t,leg_k_Point_x(:,3),'red');grid onylabel('RB')axis([0,t_end,-1.5,1.5])%XY坐标均衡legend('thetah','thetak');
subplot(4,1,4)plot(t,leg_h_Point_x(:,4),'b');hold onplot(t,leg_k_Point_x(:,4),'red');grid onylabel('LB')xlabel('时间t/s')axis([0,t_end,-1.5,1.5])%XY坐标均衡legend('thetah','thetak');toc
figure(2)
tttemp=1630;
tttemp2=175;
plot(t(tttemp:tttemp+tttemp2),leg_h_Point_x(tttemp:tttemp+tttemp2,1),t(tttemp:tttemp+tttemp2),leg_k_Point_x(tttemp:tttemp+tttemp2,1));
grid on
xlabel('时间t/s')
ylabel('一个周期的信号')
axis([9.5,11,-1.5,1.5])%XY坐标均衡legend('thetah','thetak');
figure(3)
plot(Foot_end_x(tttemp:tttemp+tttemp2,3), Foot_end_y(tttemp:tttemp+tttemp2,3))
grid on
xlabel('x方向位移')
ylabel('y方向位移')
figure(4)
for i=1:leg_num
hold on
plot(t,leg_h_Point_x(:,i))
grid on
hold off
end
figure(5)
for i=1:leg_num
hold on
plot(t,leg_h_Point_y(:,i))
grid on
hold off
end

 

 图12. 各腿关节的角度变化曲线

  图13. 某腿关节的单个周期的角度变化曲线

 图14. 某腿关节的单个周期的足端轨迹曲线 

 图15. 振荡器的输出波形

 6. Kimura-CPG振荡器驱动

       Kimura神经振荡器的生物学意义明显,在控制层面模仿神经细胞突触连接中的神经兴奋和抑制控制,具有较强的理论研究意义。图X是Kimura神经振荡器的原理图[5][6],Kimura振荡器原作者与张秀丽教授的论文中均有呈现,图中连接方式为控制论的搭建形式,白色圆圈代表抑制(负效应),白色圆圈代表兴奋(正效应)。

图16. Kimura振荡器的物理含义示意图[5] 

        该相位的拓扑关系利用权重矩阵的形式表征腿间的相位关系,具体的步态权重矩阵取法可以参考文献[5][6][7]。

图17 Kimura振荡器的腿节相位关系拓扑[5]  

         式中,i、e、j代表第i个振荡器、第e个伸肌屈肌神经元和第j屈肌个神经元;Tr表示兴奋的上升时间常数、Ta代表自抑制的适应时间常数;ui为神经元内部的兴奋状态;vi是神经元的自抑制状态;a是神经元间的互相抑制系数;b是适应系数;yfi、yei分别表示屈肌与伸肌神经元的输出;wij代表i与j振荡器之间的连接权值;sik为反射系数;c为高层神经中枢的直流激励输入;yi为第i个神经元的输出。

        给定模型参数 ,状态方程积分可求得期望控制信号,足间协调的方式同HopfCPG中的设计, 再次强调的是,A_{h}A_{k}的具体取值可以依据步长和抬腿高度,利用第2.2节中所设计的运动学逆解关系求解,如抬腿高度是H,步长为S,逆向运动学求出最大的关节摆动幅度即可。具体参数给定如下

表5. Kimura-CPG配置参数 

%Ezekiel
%2023年3月25日
%% 清理变量
% clc;
% clear;
% close all;
%% 参数设置
leg_num=4;%足的个数
mm=8;%m项反馈信息
Tr=0.04;%上升时间参数
Ta=0.38;
c=0.23;%直流输入
b=-2.0;%适应系数
a=-1.0;%抑制系数
phai=1;
%%
gait=2;
w_w=zeros(leg_num,leg_num);%定义步态矩阵
switch(gait)case 1w_w=[0 -1 1 -1;-1 0 -1 1;1 -1 0 -1;-1 1 -1 0];case 2w_w=[0 -1 -1 1;-1 0 1 -1;-1 1 0 -1;1 -1 -1 0];case 3w_w=[0 1 -1 -1;1 0 -1 -1;-1 1 0 -1;-1 -1 1 0];case 4w_w=[0 -1 -1 -1;-1 0 -1 -1;-1 -1 0 -1;-1 -1 -1 0];otherwisew_w=[0 -1 1 -1;-1 0 -1 1;1 -1 0 -1;-1 1 -1 0];   
end
%%
vf=zeros(leg_num,1);
ve=zeros(leg_num,1);
Vfe=[vf,ve];
%%
yf=zeros(leg_num,1);
ye=zeros(leg_num,1);
Yfe=[yf,ye];
Yef=[ye,yf];
Y=zeros(leg_num,1);%输出的关节映射矩阵
%%
uf=rand(leg_num,1)*c/10;
ue=rand(leg_num,1)*c/10;
Ufe=[uf,ue];
%%
hf=zeros(mm,1);
he=zeros(mm,1);
Hfe=[hf,he];
%%
ss=zeros(leg_num,mm);
WYf=zeros(leg_num,1);
WYe=zeros(leg_num,1);
SHf=zeros(leg_num,1);
SHe=zeros(leg_num,1);
%%
E=zeros(leg_num,2);
for i=1:1:leg_numE(i,1)=1;E(i,2)=1;
end
%% 关节参数,此处参数需实测,试验数据参考书
h=0.02;  %抬腿高度
v=1;   %行走速度
T=0.4; %步态周期
S=v*T; %步长
l=0.4;   %腿节长度
theta0=30/180*pi;%髋关节和膝关节平衡位置与垂直线夹角 
L=2*l*cos(theta0);%髋关节与足端之间长度
Ah=8.3;%asin((Beta*S)/(2*L));%髋关节摆动幅度
Ak=5.3;%acos((l*cos(theta0)-h)/l)-theta0;%膝关节摆动幅度
%% 时间,分辨率设置
%对时间进行算法积分
u0=[0.009 0.0021 0.0134 0.0022;0.0272 0.0003 0.0206 0.0057;0.0199 0.0067 0.0171 0.0111;0.0022 0.0151 0.0149 0.0081;];%初值会影响相序
n=2000;
t_total = 8*pi/2;
t=linspace(0,t_total,n);%转一圈
ts=t_total/n;
% 积分计算uf = u0(:,1);vf = u0(:,2);ue = u0(:,3);ve = u0(:,4);shsum = zeros(leg_num,1);k = 0;trace_Y_Y = nan+[t;t;t;t];%轨迹配置初始化,空值
for j=tk=k+1;[WYf, WYe] = wye_sumeq(w_w, leg_num,  yf, ye);[uf_dot, vf_dot,ue_dot, ve_dot] = kimura_stateq(Tr, Ta, uf, vf, ue, ve, yf, ye,a, b, c,WYf, WYe, shsum);uf =uf + ts.*uf_dot;vf =vf + ts.*vf_dot;ue =ue + ts.*ue_dot;ve =ve + ts.*ve_dot;Y_Y = uf - ue;trace_Y_Y(:,k)= Y_Y ;[yf, ye] = returnyfe(uf, ue, leg_num);
end
yPlot = trace_Y_Y';
Judge1=diff(yPlot(:,1));
Judge2=diff(yPlot(:,2));
Judge3=diff(yPlot(:,3));
Judge4=diff(yPlot(:,4));
kplot=zeros(length(yPlot(:,1)),4);
thetah(1)=max(yPlot(:,1));
thetah(2)=max(yPlot(:,2));
thetah(3)=max(yPlot(:,3));
thetah(4)=max(yPlot(:,4));
for j=1:1:length(yPlot(:,1))-1if Judge1(j)>0kplot(j,1)=1*(Ak/Ah)*(1-(yPlot(j,1)/thetah(1))^2);elsekplot(j,1)=0;endif Judge2(j)>0kplot(j,2)=1*(Ak/Ah)*(1-(yPlot(j,2)/thetah(2))^2);elsekplot(j,2)=0;endif Judge3(j)>0kplot(j,3)=-1*(Ak/Ah)*(1-(yPlot(j,3)/thetah(3))^2);elsekplot(j,3)=0;endif Judge4(j)>0kplot(j,4)=-1*(Ak/Ah)*(1-(yPlot(j,4)/thetah(4))^2);elsekplot(j,4)=0;end
end
figure(2)
subplot(4,1,1)
plot(t,yPlot(:,1),t,kplot(:,1),'green')
% title('Kimura振荡器输出')
ylabel('LF')
axis([0,10,-2,2])%XY坐标均衡
grid on;
subplot(4,1,2)
plot(t,yPlot(:,2),t,kplot(:,2),'green')
ylabel('RF')
axis([0,10,-2,2])%XY坐标均衡
grid on;
subplot(4,1,3)
plot(t,yPlot(:,3),t,kplot(:,3),'green')
ylabel('RB')
axis([0,10,-2,2])%XY坐标均衡
grid on;
subplot(4,1,4)
plot(t,yPlot(:,4),t,kplot(:,4),'green')
xlabel('时间(t/s)')
ylabel('LB')
axis([0,10,-2,2])%XY坐标均衡
grid on;
function [yf, ye] = returnyfe(uf, ue,legnum)yf = zeros(legnum,1);ye= zeros(legnum,1);for i= 1:1:legnumyf(i) = max(uf(i), 0);ye(i) = max(ue(i), 0);end
end
function [uf_dot, vf_dot,ue_dot, ve_dot] = kimura_stateq(Tr, Ta, uf, vf, ue, ve, yf, ye,a, b, c,wyf_sum, wye_sum, shsum)uf_dot =(1/Tr)*(-uf+b*vf+a*ye+wyf_sum+shsum+c);vf_dot = (1/Ta)*(yf-vf);ue_dot = (1/Tr)*(-ue+b*ve+a*yf+wye_sum+shsum+c);ve_dot =  (1/Ta)*(ye-ve);
end
function [WYf, WYe] = wye_sumeq(w, legnum,  yfaugment, yeaugment)
WYf= zeros(legnum,1);
WYe= zeros(legnum,1);
for i_i =1:1:legnumfor j_j=1:1:legnumWYf(i_i)=WYf(i_i)+w(i_i, j_j)*yfaugment( j_j);WYe(i_i)=WYe(i_i)+w(i_i, j_j)*yeaugment( j_j);end
end
end
function shsum = shsumeq(s, legnum, haugment)
shsum = zeros(legnum,1);
for i =1:1:legnumfor j=1:1:legnumshsum(i)=shsum(i)+s(i,j)*haugment(j);end
end
end 

 

图18. Kimura振荡器的各腿节角度变化曲线拓扑

 

图19. Kimura振荡器的某腿节足端轨迹曲线拓扑 

 7. 三种驱动方式的Simulink搭建

        数值仿真阶段已经实现各驱动方式的信号输出,在simulink的实时仿真环境里,只需把数值仿真中的循环改成时钟信号或方波信号激励输入,把关键运算更改为Matlab-function或S-function即可。注:simulink的搭建思路见数值仿真,函数封装和信号关系均有体现。

7.1 足端摆线规划Simulink搭建

图20. 复合摆线规划simulink

 图21. 复合摆线规划simulink2

  图22. 复合摆线规划simulink2仿真的足端曲线

        核心环节的函数如下: 

% 函数1
function x = fcn(u,Tm,S)if u>0x =S*(u/Tm-1/(2*pi)*sin(2*pi*u/Tm));
else u=-u;x =S*(u/Tm-1/(2*pi)*sin(2*pi*u/Tm));
end
% 函数2
function y = fcn(u,S,Tm,H)
n=4;
if u>0y=2*H*(u/Tm-1/(n*pi)*sin(n*pi*u/Tm)).*(u>=0&u<Tm/2)+2*H*(1-u/Tm+1/(n*pi)*sin(n*pi*u/Tm)).*(u>=Tm/2&u<Tm);;
else y=0;
end
% 运动学逆解函数
function [alfa, beta, gamma]=xyztoang(x, y, z)h_up=49.0;h_mid=125.5899;h_low=116.0+20;dyz=sqrt(y.^2+z.^2);lyz=sqrt(dyz.^2-h_up.^2);gamma_yz=-atan(y./z);gamma_h_offset=-atan(h_up./lyz);gamma=gamma_yz-gamma_h_offset;lxzp=sqrt(lyz.^2+x.^2);n=(lxzp.^2-h_low^2-h_mid.^2)/(2*h_mid);beta=-acos(n/h_low);alfa_xzp=-atan(x/lyz);alfa_off=acos((h_mid+n)/lxzp);alfa=(alfa_xzp+alfa_off);
end

7.2 Hopf-CPG Simulink搭建

 图23. Hopf-CPG Simulink仿真

        核心积分环节的函数如下: 

function [X_dot,Y_dot] = fcn(Wsw,Wst,Phi,leg_x,leg_y,u1,u2)
%#codegen
X_dot = zeros(1,4);
Y_dot = zeros(1,4);
Alpha=10;%收敛速度
u=1;%影响曲线幅值,幅值为开根号
a=50;%决定w在Wsw和Wst之间变化的速度
for i = 1:4r_seq = (leg_x(i)-u1(i))^2+(leg_y(i)-u2(i))^2;W = (Wst/(exp(-a*leg_y(i))+1))+(Wsw/(exp(a*leg_y(i))+1));Vx = Alpha * (u - r_seq)* (leg_x(i) - u1(i))  -  W * (leg_y(i) - u2(i));Vy = Alpha * (u - r_seq) * (leg_y(i) - u2(i)) + W * (leg_x(i) - u1(i));for j = 1:4Vx = Vx + cos(Phi(i)-Phi(j))*(leg_x(j) - u1(i)) - sin(Phi(i)-Phi(j))*(leg_y(j) - u2(i));Vy = Vy + cos(Phi(i)-Phi(j))*(leg_y(j) - u2(i)) + sin(Phi(i)-Phi(j))*(leg_x(j) - u1(i));endX_dot(i) = Vx;Y_dot(i) = Vy;
end

7.2 Kimura-CPG Simulink搭建

 图24. Kimura-CPG Simulink仿真示意

        关键积分环节的函数如下:

function [uf_dot, vf_dot,ue_dot, ve_dot] = kimura_stateq(Tr,...Ta, uf, vf, ue, ve, yf, ye,a, b, c,wyf_sum, wye_sum, shsum)uf_dot = zeros(4, 1);ue_dot = zeros(4, 1);vf_dot = zeros(4, 1);ve_dot = zeros(4, 1);uf_dot =(1/Tr)*(-uf+b*vf+a*ye+wyf_sum+shsum+c);vf_dot = (1/Ta)*(yf-vf);ue_dot = (1/Tr)*(-ue+b*ve+a*yf+wye_sum+shsum+c);ve_dot =  (1/Ta)*(ye-ve);
end

8. simscape四足机器人仿真验证

        Simscape模型参考CSDN(四足机器人Simscape搭建)博客构建,单腿simscape模型和整机可视化模型示意如图24与图25。

 图24. 单腿  Simscape模型simulink建模示意

  图25. 整机  Simscape模型可视化示意

         经过的引入关节角位移和角速度期望信号至各关节的PID控制器中,三种步态规划方法均能实现机器人的多种步态行走,转弯设计,原地踏步以及阻抗控制器我之后有空再更新(画个饼先)。 

  图26. 四足机器人simcape模型实时仿真示意

9. 总结

        这三种方法的优缺点如下:复合摆线规划能很好地结合运动学逆解输出关节角位移和角速度的期望信号,十分实用且简单,很好地添加力反馈或姿态反馈控制,缺点是仿生学意义不突出。而CPG模型的优点是仿生学意义突出,可以不需要阶跃信号输入调制信号周期,能够通过在状态方程模型加入反馈项实现姿态反馈和力反馈,缺点是模型复杂,不能直接结合运动学逆解,在应用到工程上时,参数和初值对输出的性能影响较大,调参困难。

        感谢各位的仔细观看,我之后还会做一些强化学习和模型预测控制相关的四足机器人稳定控制策略,以及四足机器人关节阻抗控制器(正在学)设计相关的文章(之前阶段都是用步态规划给出期望的关节角位移和角速度,底层用PI控制去跟踪期望信号),假如有疑惑和问题的朋友,可以联系我,一起探讨交流。 

        在过去的一段日子里,我深刻体会到陈奕迅《苦瓜》歌词里面的“珍惜淡定的心境,苦过后更加清,万般过去亦无味但有领会留下”,生活的本质似乎是痛苦和挣扎,只有当逃离舒适区去体会某些艰辛才能领会苦后的甘甜。人生将迎来下个全新阶段,我将如往常一样义无反顾,秉承“拒绝平庸,敢于不同,有梦最美”的信仰,于雨夜中拥抱着星火,挣扎着前行,同时警醒自己别忘了来时的路。 

10. 参考文献

[1]Spong M W, Hutchinson S, Vidyasagar M. Robot modeling and control[M]. New York: Wiley, 2006.

[2] Bledt G, Powell M J, Katz B, et al. Mit cheetah 3: Design and control of a robust, dynamic quadruped robot[C]//2018 IEEE/RSJ International Conference on Intelligent Robots and Systems (IROS). IEEE, 2018: 2245-2252.

[3] Di Carlo J. Software and control design for the MIT Cheetah quadruped robots[D]. Massachusetts Institute of Technology, 2020.

[4] Seo K, Chung S J, Slotine J J E. CPG-based control of a turtle-like underwater vehicle[J]. Autonomous Robots, 2010, 28: 247-269.

[5] Kimura H, Fukuoka Y, Cohen A H. Biologically inspired adaptive walking of a quadruped robot[J]. Philosophical Transactions of the Royal Society A: Mathematical, Physical and Engineering Sciences, 2007, 365(1850): 153-170.

[6] Kimura H, Fukuoka Y, Nakamura H. Biologically inspired adaptive dynamic walking of the quadruped on irregular terrain[A]. Robotics Research[C].MIT press,2000,9,260-278.

[7] 张秀丽,郑浩峻,段广洪,动物运动控制机理对机器人控制的启示[J].机器人技术与应用,2002(5):24-26.

[8] 李华师.四足机器人仿生运动控制理论与方法的研究[D].北京:北京理工大学,2014:57-69

[9] 张秀丽. 四足机器人节律运动及环境适应性的生物控制研究[D].北京:清华大学,2004.

[10] 徐海东,干苏,任杰等.基于Hopf振荡器的四足机器人步态CPG调节[J].2017,12,29(12)1-6.

[11] 黄照翔,颉潭成,徐彦伟,王亚锋.基于Simulink/SimMechanics的四足机器人足端轨迹规划及动态仿真分析[J].制造业自动化,2022,44(04):77-82.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/773952.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nacos部署(二)Linux部署Nacos2.3.x集群环境

&#x1f60a; 作者&#xff1a; 一恍过去 &#x1f496; 主页&#xff1a; https://blog.csdn.net/zhuocailing3390 &#x1f38a; 社区&#xff1a; Java技术栈交流 &#x1f389; 主题&#xff1a; Nacos部署&#xff08;二&#xff09;Linux部署Nacos2.3.x集群环境 ⏱️…

Xshell连接虚拟机非常慢

问题&#xff1a; 打开虚拟机连接时发现过了几分钟依然卡着在&#xff0c;但是主机可以ping通虚拟机&#xff0c;虚拟机也可以ping通主机感觉很奇怪&#xff0c;查询后得知需要修改ssh设置 打开配置 vim /etc/ssh/sshd_config 修改配置 找到 UseDNS&#xff0c;去掉前面的#号…

React中 类组件 与 函数组件 的区别

类组件 与 函数组件 的区别 1. 类组件2. 函数组件HookuseStateuseEffectuseCallbackuseMemouseContextuseRef 3. 函数组件与类组件的区别3.1 表面差异3.2 最大不同原因 1. 类组件 在React中&#xff0c;类组件就是基于ES6语法&#xff0c;通过继承 React.component 得到的组件…

面试八股文之JAVA基础

JAVA基础 DNS、CDN&#xff1f;如何实现对象克隆?父子类静态代码块, 非静态代码块, 构造方法执行顺序?String s new String("abc") 创建了几个对象, 分别放到哪里?OSI网络模型七层&#xff1f;应用层协议&#xff1f;http协议和https协议区别&#xff1f;传输层协…

蓝桥杯小白月赛3.23

题目描述&#xff1a; AC代码&#xff1a; #include <iostream> #include<cstring> #include<algorithm>using namespace std;const int N 2e510; string str[N]; //写上&会速度更快一些 bool cmp(const string &s1,const string &s2) {//例…

苹果App Store上架工具介绍

文章目录 摘要引言正文1. Xcode2. [appuploder](https://www.applicationloader.net/)3. [克魔助手](https://keymob.com/) 4.[ipa guard](https://www.ipaguard.com/)总结参考资料 摘要 苹果App Store作为iOS应用程序的主要分发渠道&#xff0c;上架应用程序需要遵守规定和通…

华为数通方向HCIP-DataCom H12-821题库(多选题:201-220)

第201题 以下关于BGP中Orginator ID属性的描述,正确的是哪些项? A、Originator ID属于公认任意属性 B、当其他BGP Speaker接收到这条路由的时候,将比较收到的0nginator ID和本地的Router ID,如果两个ID相同BGP Speaker会忽略掉这条路由,不做处理 C、当一条路由第一次被RR…

输入与输出

输入(Scanner类) Scanner是java5的新特性&#xff0c;在java.util包里&#xff0c;可以完成用户输入。步骤&#xff1a; 导入java.util包&#xff1b;构造Scanner对象&#xff0c;参数为u标准输入流System.in&#xff1b;使用next()方法系列接收数据 nextBoolean()接收一个布…

后端基础篇- 社区 IDEA 手动 Maven 创建 SpringBoot 项目、Maven 安装与配置环境变量、IDEA 集成 Maven

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 Maven 安装与配置环境变量 1.1 下载并解压安装包 1.2 配置本地仓库 1.3 配置阿里云私服 1.4 配置环境变量 2.0 IDEA 集成 Maven 2.1 首先创建一个新项目 2.2 开始…

电商系列之满减

> 插&#xff1a;AI时代&#xff0c;程序员或多或少要了解些人工智能&#xff0c;前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家…

【4月】组队打卡《山有木Python特征工程极简入门》

活动名称 CDA Club 第2期《山有木兮Python数据分析极简入门》组队打卡 活动介绍 本次打卡活动由CDA俱乐部旗下学术部主办。目的是通过数据分析科普内容&#xff0c;为数据分析爱好者提供学习和交流的机会。方便大家利用碎片化时间在线学习&#xff0c;以组队打卡的形式提升学…

一文读懂:什么是工单系统?市面上有哪些好用的工单系统?

什么是工单管理系统&#xff1f;工单系统如何帮助企业解决管理问题&#xff1f;市面上有哪些好用的工单管理系统&#xff1f;不同工单管理系统适用于什么企业&#xff1f;工单管理系统如何定价&#xff1f; 5000字长文&#xff0c;我写了整整一天&#xff01;梳理了大家对工单…

framebuffer

framebuffer 1.framebuffer的理解 概念&#xff1a;FrameBuffer&#xff0c;可以译作"帧缓冲"&#xff0c;有时简称为 fbdrv&#xff0c;这是一种独立于硬件的抽象图形设备&#xff0c;是Linux为显示设备提供的一个接口&#xff0c;把显存抽象后的一种设备&#xf…

GitHub学生认证

文件、证明之类的一定要用英文。 我先是用有道网页翻译把学信网的报告翻译成了英文&#xff0c;然后截图传上去&#xff0c; 给我这个答复 所以要先2FA认证、支付信息填好。 2FA认证&#xff1a;Github开启2FA双重验证 - 知乎 (zhihu.com) 支付信息&#xff1a;点击Setting…

【学习】软件测试行业 ,有哪些以就业为主的学习侧重点

今天给所有入行软测的同学们&#xff0c;帮大家梳理下以就业为主的学习侧重点&#xff0c;简单来说就是【这些都是重点&#xff0c;圈起来&#xff0c;要考的】&#xff0c;有需要的小伙伴可以往下看。 建议一&#xff1a;一定要学习一门编程语言&#xff0c;再开始使用自动化测…

LC 100.相同的树

100. 相同的树 给你两棵二叉树的根节点 p 和 q &#xff0c;编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是相同的。 示例 1&#xff1a; 输入&#xff1a; p [1,2,3], q [1,2,3] 输出&#xff1…

PostgreSQL技术大讲堂 - 第48讲:PG高可用实现keepalived

PostgreSQL从小白到专家&#xff0c;是从入门逐渐能力提升的一个系列教程&#xff0c;内容包括对PG基础的认知、包括安装使用、包括角色权限、包括维护管理、、等内容&#xff0c;希望对热爱PG、学习PG的同学们有帮助&#xff0c;欢迎持续关注CUUG PG技术大讲堂。 第48讲&#…

IPv6-基础概念

IPv6基础概念 IPv6技术特点&#xff1a;精简报文格式、实现自动配置和重新编制、支持层次化网络编制、支持端对端安全、更好的支持Qos、支持移动特性。 五元组&#xff1a;源地址&#xff0c;目的地址&#xff0c;源端口&#xff0c;目的端口&#xff0c;协议。 IPv6报头优势…

gitee 本地文件提交到仓库

一、准备工作 1.下载Git Bash Git Bash官网下载地址 http://www.git-scm.com/download/ 点此跳转 2.注册或登录gitee gitee官网地址 https://gitee.com/ 点此跳转 没有账号选择注册有账号的话直接登陆 3.在gitee中新建一个空的仓库 登陆成功后点进个人主页&#xff0c;点击…

美国免税州详细地址:可用于ChatGPT、MJ、POE、AppStore等订阅服务账单地址填写!

地址1zip_Codecountriesstatecitystreet199654USAAKWasilla2075 E Chickaloon Rd236110USAAL MontgomeryMontgomery372034USAARConway617 Watkins St486303USAAZPrescott330 S Cortez St592805USACAAnaheim505 S Zeyn St680232USACOLakewood1390 S Zephyr St706109USACTWether…