注意方向问题!意方向问题!方向问题!向问题!问题!题!,以下所有分析皆是顺时针为正
单侧系统状态方程求解
首先双轮足式机器人可以将模型化简为一个倒立摆模型,如下
分块开始分析
轮子
水平方向上
竖直方向上
转矩
联立消去 $f$ 得到
摆杆
水平方向上
竖直方向上
转矩
机体
水平方向上
竖直方向上
转矩
根据上述得到的 $\textcircled{2}\textcircled{3}\textcircled{5}\textcircled{6}$ 联立,得到中间变量 $P_w,N_w,P_b,N_b$ 的表达式,得
带入 $\textcircled{1}\textcircled{4}\textcircled{7}$ 中,并且利用 matlab 的符号求解工具解。设定
最终求解对应的雅各比矩阵,就是 A 和 B
1 | clc |
最终得到结果,有点复杂,之前那个是解算出错了 T_T
这就是系统状态空间方程
腿部质心拟合
由于在分析和设计控制器的过程中,机器人的腿部连杆需要简化为一个直杆,所以就需要将原来的腿部连杆的转动惯量和质心拟合到虚拟的杆上,如图所示
这里使用机体坐标系,计算可以得到每个杆的坐标位置,这里借用一下下面的五连杆求解结果,根据得到的 $\varphi_2$ 和 $\varphi_3$ 带入解算
根据如下式子求解出四个连杆的质心位置为 $Z_1$
求解出的连杆质心之后,还要将其映射到虚拟杆上,这里选择直接对虚拟杆作垂线
最终求解得到虚拟杆的质心 $Z_l$ ,根据平行轴定理可以得到变换之后的质心处的转动惯量
同时也可以计算出所需要的 $L_w$ 和 $L_b$
LQR 控制器
首先是 LQR 控制器。是一个比较常用的控制器,设计起来也比较简单。
推导过程与一般的 LQR 无异,所以直接调用 matlab 函数来求得对应的 K,最终需要拟合出一个 K 关于杆长的函数
1 | %% 设置 |
其中的 Q 和 R 就是系统状态与系统输入的权重,越大表示越在意
最终需要将控制器反馈增益矩阵拟合为关于杆长的一元三次方程,具体的拟合代码为
1 | clc |
可以使用 Curve Fitting Toolbox,能清楚的可视化数据的变化情况
整体状态空间方程
与单侧的平衡状态空间方程的建立基本上是一致的,但是需要同时注意左右两侧,并且还有一些整体机器人的分析。
轮子
左侧
水平方向上
竖直方向上
转矩
右侧
水平方向上
竖直方向上
转矩
摆杆
左侧
水平方向上
竖直方向上
转矩
右侧
水平方向上
竖直方向上
转矩
机体
水平方向上
竖直方向上
转矩
假设机体两侧支持力大小一致
整车的航向角
对上述中所有式子进行机体倾角进行小角度近似,然后利用其中的 $\textcircled{1}\textcircled{4}\textcircled{7}\textcircled{8}\textcircled{10}\textcircled{11}\textcircled{13}\textcircled{14}\textcircled{16}\textcircled{17}$ 式求解出中间变量 $P_{w,l},N_{w,l},P_{b,l},N_{b,l},P_{w,r},N_{w,r},P_{b,r},N_{b,r},f_l,f_r$ 的表达式,并且进行小角度近似(令 $\theta_l, \theta_r, \phi$ 均为 0 )。
然后利用其中的 $\textcircled{3}\textcircled{6}\textcircled{9}\textcircled{12}\textcircled{15}$ 来求解 $\ddot{x}_l, \ddot{x}_r, \ddot{\theta}_l,\ddot{\theta}_r,\ddot{\varphi}$ 的表达式,然后根据 $\textcircled{18}$ 可以得到 $\ddot{\psi}$ 的表达式。
定义车子移动距离的表达式
可以得到 $\ddot{s}$ 的表达式
定义
其中 $\psi$ 为整车的航向角, $\varphi$ 为机体的俯仰角
最终可以得到系统状态方程的表达式。这里就不列出来了,太复杂了。直接上代码
电脑毁灭者——未进行小角度近似
1 | clc |
上式中的符号方程不容易解,但是带入数据之后就容易解出来了。下面的解法是直接进行机体倾角小角度近似,并且提前算好中间变量
实际上,上述代码是根据上海交通大学所分享的开源系统设计中所得到的,主要是因为自己算出来的直接求解对应的 $jacobian$ 矩阵所得到的系统状态空间方程是不可控的,我也不知道为啥(这个解算研究两天了),验证之后发现,并不是不可控的,可能是 $jacobian$ 求解时所用的矩阵的布局不一致?把状态空间方程的最后求解的部分给改掉就好了。需要注意,上海交通大学的开源系统设计中,所用到的机体的俯仰角是右视图中是顺时针为正,与我的分析中向上抬头为正好相反。
LQR 控制器设计
1 | C = eye(10); |
其中的 Q 和 R 就是系统状态与系统输入的权重,越大表示越在意
最终需要将状态反馈增益系数拟合为左右杆长的二元二次函数,下面是拟合分析的总体代码
1 | clc |
代码介绍
最上面一部分是对腿部质心,转动惯量等与腿长关系所拟合出的直线(一元一次方程),后面的 K 的拟合是利用 matlab 工具集 Curve Fitting Box 来做的。但是这个好像不能引用矩阵里面的某一块,只能直接引用一整个矩阵,所以才有了后面的一大段冗长的代码。
在 主页-附加功能 搜索这个工具集并且下载,然后在 APP 这个界面就会有这个曲线拟合器
加载数据,并且选择对应的数据,这里的话,如果只有两个变量,y 是因变量,而三个变量的话 z 就是因变量,x 和 y 就是自变量,权重不需选择
选择自定义方程,最后拟合得到的参数就是函数的系数(右下角)
有一点不太好的是,一次只能拟合一个 K 的系数,但是还是挺简单的,而且很直观,能很清楚的看到数据的拟合情况。
最后将这些数据写入代码中就可以了,需要注意的是 $u=-Kx$
控制器小结
半身控制器
比较简单,参数也比较少,但是必须要写 PID 来实现对机体整体的控制。左右两侧的身体都需要一个单独的半身控制器来进行控制,需要额外的 PID
- 腿部控制腿长 PID:输入当前腿长,目标腿长。输出为虚拟力。注意需要加一个前馈力,用以补偿重力和侧向惯性力矩
- 转向 PID:对于上述所得到的 LQR 控制器,发现并没有关于转向的 PID,所以需要自己写一个,输入就是当前转角,目标为目标角度,输出就是 Tw 的增益。注意方向
- 双腿夹角 PID:由于转向 PID 会影响左右轮子上的力矩,导致力矩不平衡,这就容易导致双腿劈叉,所以用双腿夹角 PID 来避免,最终输出结果叠加在 LQR 计算出的关节力矩上
全身控制器
比较复杂,系统状态空间方程会很难解算,只能说自己解了好久(2天,对应上面的半身控制器只用了一个小时),参数巨多,最终拟合出来的 K 的函数至少有 240 个参数,我只能说太魔鬼了。但是实际控制效果还是很不错的,需要的额外 PID 并不是很多
- 腿部控制腿长 PID:输入当前腿长,目标腿长。输出为虚拟力。注意需要加一个前馈力,用以补偿重力和侧向惯性力矩
比较
全身控制器相比半身控制器会更复杂,但是对系统的控制效果说实话还是很不错的,感觉控制的很细腻(不知道是不是好不容易解出来之后对自己的安慰)。可以都试试。
对于 ADRC 和 Hinfinty 控制器,并不是很好用,ADRC 来说,需要调试的参数太多,而且系统耦合性太强了,很不好调,而且也很复杂,主要是编程要写的太多了(doge)。Hinfinty 来说,也不需要调节参数,实际上只有一个 $\gamma$ 需要调节,但是最终的效果不尽人意啊,抖动太大,而且对于干扰的抗性并不是很好(也许是自己做的问题)。
但是不管怎么说,LQR 还算是一个不错的控制器的
在仿真中测试,整体上的控制是比单边控制要有更高的上限,并且对机体的控制确实更好
五连杆正运动学解算
以杆 $L_5$ 的中心为原点,建立两个坐标系,分别是基于机体坐标系 $y_b-x_b$ 和坐标系 $y-x$ ,首先是在坐标系 $y_b-x_b$ 中解算各个点的位置可以得到
通过五连杆左右两部分列写 C 点坐标,可以得到下列等式
将两边进行平方
两式相加得到
其中
利用倍角公式进行化简,此处用到的倍角公式为
化简过程如下
将 $2A\cos\varphi_2$ 和 $2C$ 拆解如下
将上面两个公式化简为
所以上述公式可以化简为
其中第三项可以化简为
所以公式可以化简为
可以求解这个一元二次方程,得到
这是有两个解的,当然连杆状态也是由两个解的,所以可以验算 $\varphi_2,\varphi_3$ 的解,所以需要保证 $\sin\varphi_2>0,\sin\varphi_3>0$ 。之后即可得到 C 点坐标
从而得到在机体坐标系下的腿长 $L$ 和腿部摆角 $\varphi_0$
将坐标映射到 $y-x$ 坐标系下
最终可以得到腿长 $L$ 和腿部摆角 $\theta$
VMC
作用是在每个需要控制的自由度上构造合适的虚拟构件来产生合适的虚拟力。虚拟力不是实际执行机构的作用力或力矩,而是通过执行机构的作用经过机构转换而成。对于一些控制问题,我们可能需要将工作空间 (Task Space) 的力或力矩映射成关节空间 (Joint Space) 的关节力矩
在五连杆中,需要获得机构末端沿腿的推力 $F$ 与沿中心轴的力矩 $T_b$,对应极坐标 $L_0,\theta_b$ 与 $A,E$ 两个关节转动副力矩 $T_A,T_E$ 的关系。这里选择使用机体坐标系来计算,所以定义
对正运动学模型 $x=f(q)$ 做微分得
这就是 x 对 q 的雅各比矩阵,记作 $J$。得到对应的全微分方程为
通过雅各比矩阵 $J$ 将关节速度 $\dot{q}$ 映射为五连杆姿态变化率 $\dot{x}$。根据虚功原理,可以得到
将全微分方程带入之后可得
但是上述推导中的正运动学模型直接求雅各比矩阵比较困难,因为模型中有大量的平方与三角函数的运算,结果比较复杂。所以进行改进,由于雅各比矩阵实际上描述的是两坐标微分的线性映射关系,所以可以计算速度映射来得到雅各比矩阵。由于 $L_0,\varphi_0$ 实际上就是 $C$ 点的极坐标,所以首先求出 $C$ 点直角坐标速度
通过五连杆左右两部分列写 C 点坐标求导可以得到 $\dot\varphi_2$
消去 $\dot\varphi_3$ 得到 $\dot\varphi_2$
其中
并且其中的 $\dot\varphi_1,\dot\varphi_4$ 都是直接测出来的,带入之后得到
化简之后得到
记作
由于速度雅各比矩阵是力矩雅各比矩阵的转置,则上述可以得到关节力矩 $T$ 与关节力矩和沿杆力的关系
依次带入得到最终的关节力矩与虚拟力之间的映射关系
令
最终带入得到
反向 VMC 如下
腿部摆角补偿
在腿部结构上,连杆结构的前后分布并不均匀,所以需要一个 $\theta$ 补偿来弥补,从而实现控制更精确,$\theta$ 补偿实际就是通过为目标 $\theta$ 添加一个前馈,使整个机器人的重心位于轮子的正上方,否则机器人由于重力与地面的支持力不在同一直线上时,会出现一个倾覆力矩,从而影响机器人的平衡性
首先在机器人坐标系 $x_b-y_b$ 上进行计算每个连杆部分的质心坐标
将重心坐标系转移到轮子坐标系 $x_w-y_w$ 中
假定此时的 $\theta_c$ 正好满足要求,此时根据重心公式可以得到
求解可以得到 $\theta$ 的补偿角度
在使用时可以直接添加到当前状态中,即状态空间方程变为
腿长控制
腿长控制是直接使用 PID 进行控制,但是一定要将控制腿长的 PID 调节的软一点,P 要小一点,D 要尽量小,I 尽量不给。需要保证腿最长的时候能够平衡前馈力和轮子的重力从而有向上拉的力,而腿长最短时保证腿部力能支撑起整个机体。最终 PID 的输出与前馈力之和作为腿部的沿杆的力参与 VMC 解算
腿长 PID 较大会造成很大的影响,PID 过大导致系统的控制腿长的输出太大,相对应的控制整个系统的平衡的输出就很小,从而导致系统稳定性不够
例如:电机的输出的力矩是有限的,当把 LQR + VMC 解算出来的力矩同腿长控制 PID 的输出相结合之后,就会比较大,那么进行力矩限制时,会导致限制之后的力矩不能保证机体平衡或者腿长的控制,最终控制效果不好
离地检测
根据图中可以得到
其中
并且其中的 $\ddot{z}_b$ 是机体重力加速度,可以通过机体上的传感器测得,但是需要结合机体姿态并且消去重力加速度得到
并且 $F$ 与 $T_b$ 都是根据关节电机反解出来的
得到
可以判断,当 $F_N$ 小于某个阈值,就认为地面给的摩擦力不足以支持机体平衡,也就是处于腾空状态,此时,就只保持腿部姿态角即可,也就是除了 $\theta,\dot\theta$ 之外的数据的系数均为 0 即可
1 | float A = l1 * sin(angle1 - angle2) / sin(angle2 - angle3); |
最终得到
跳跃控制
有些轮腿的控制中,是直接给一个比较大的力矩来使得机体跳跃,但是这样的话感觉并不是很好。所以有另一种方法:通过设定腿部杆长伸腿和蹬腿来实现跳跃
具体的腿部运动流程就是:收腿 $\rightarrow$ 蹬腿 $\rightarrow$ 收腿 $\rightarrow$ 伸腿
1 | switch(jump_process) { |
转角控制
转角可以直接利用 PID 进行控制,可以实现比较准确的控制,但是一般来说,这个 PID 的参数应当是一个 PD 控制器,这会保证系统不会因为卡住而出现大电流
由于机体的转角是受到轮子的差速转动实现的,所以 PID 的输出结果需要叠加到轮子的输出力矩上。但是如果转角比较大时,叠加到轮子的输出力矩上之后,左右两侧的机体可能出现运动不一致而导致机体发生劈叉等情况,所以还需要双腿角度 PID,用以防止双腿劈叉
横滚角控制
直接根据当前的横滚角,计算当机体保持平衡的时候两条腿的长度之差,然后叠加在当前腿长上,作为设定腿长来给左右两条腿进行控制
1 | float leg_dif = sin(roll) * l_body; |
后记
整个控制系统是断断续续的研究了很久才能实现,这个机器人的控制确实很难,对于菜鸟的我来说确实很痛苦,但是研究出来之后会发现,原来当时困扰自己的东西只是一些小问题
实际上是做了两代轮腿,第一代死于经验不足,调试了差不多一个月然后被去安排做其他事情了。然后第二代轮腿实际上只在 4 天就成功了(喜极而泣),其实就是因为对其原理的理解不够清晰(一直觉得是机械结构设计不好,其实应该是我的问题)
再者即使调不出来也别放弃,重新整理一下思路,总会发现不一样的东西的