MIT开源的四足机器人动力学建模主要是牛顿欧拉法

式(6.45)下一个关节的角速度=两个关节间的旋转变换矩阵*上一个关节的角速度+下一个关节的角速度

牛顿欧拉法通过外推来计算 各个连杆的质心受到的力和力矩。 计算过程式(6.49)计算连杆质心受到的力。

式(6.50)计算连杆质心收到的力矩;连杆质心受到的力和力矩由重力加非惯性力组成。

外推就是从基座向机械臂末端递推,各个关节的角速度,线速度,角加速度,线加速度,以及连杆质心的线加速度。

内推就是机械臂的末端的力和力矩向基座递推,求各个关节的力和力矩。

然后由牛顿欧拉方程整理得到机器人的动力学方程:

这个动力方程是机械臂末端没有与外界接触,不含接触力。

带接触力的动力学方程:

其中的第二项由上一个式子的后三项组成,这个式子的右边式关节力矩和接触力产生的力矩。

二、在代码中实现

FloatingBaseModel<float> _model; //定义浮动基模型变量
_model = _quadruped.buildModel();  //初始化浮动基模型

1.确定机机器人的质量长度信息

  cheetah._bodyMass = 3;  机身质量cheetah._bodyLength = 0.185 * 2;  身体的长  前后两个hip电机的中心距离cheetah._bodyWidth = 0.05025 * 2;  宽       左右两个abad电机的中心距离cheetah._bodyHeight = 0.05 * 2;    高cheetah._abadGearRatio = 6;        电机减速比cheetah._hipGearRatio = 6;         电机减速比cheetah._kneeGearRatio = 9.33;     电机和连杆的减速比cheetah._abadLinkLength = 0.072;    abad电机中心到hip电机的中心距离cheetah._hipLinkLength = 0.211;    大腿连杆长度cheetah._kneeLinkY_offset = 0;cheetah._kneeLinkLength = 0.20;    小腿连杆长cheetah._maxLegLength = 0.409;     大腿加小腿的总长

2.从solidworks中查看关节的惯性张量

  Mat3<T> abadRotationalInertia;abadRotationalInertia << 381, 58, 0.45, 58, 560, 0.95, 0.45, 0.95, 444;   //旋转轴DH系的Z轴abadRotationalInertia = abadRotationalInertia * 1e-6;Vec3<T> abadCOM(0, 0.036, 0);  // LEFTSpatialInertia<T> abadInertia(0.54, abadCOM, abadRotationalInertia);

髋关节hip的惯性张量

  Mat3<T> hipRotationalInertia;hipRotationalInertia << 1983, 245, 13, 245, 2103, 1.5, 13, 1.5, 408;hipRotationalInertia = hipRotationalInertia * 1e-6;Vec3<T> hipCOM(0, 0.016, -0.02);SpatialInertia<T> hipInertia(0.634, hipCOM, hipRotationalInertia);

SpatialInertia<T> 是将三维的惯性张量转换为空间六维的惯性张量

膝盖关节的惯性张量

 Mat3<T> kneeRotationalInertia, kneeRotationalInertiaRotated;kneeRotationalInertiaRotated << 6, 0, 0, 0, 248, 0, 0, 0, 245;kneeRotationalInertiaRotated = kneeRotationalInertiaRotated * 1e-6;kneeRotationalInertia = RY * kneeRotationalInertiaRotated * RY.transpose();Vec3<T> kneeCOM(0, 0, -0.061);    //当前关节在当前关节坐标系下的质心位置SpatialInertia<T> kneeInertia(0.064, kneeCOM, kneeRotationalInertia);

身体的惯性张量

  Mat3<T> bodyRotationalInertia;bodyRotationalInertia << 11253, 0, 0, 0, 36203, 0, 0, 0, 42673;bodyRotationalInertia = bodyRotationalInertia * 1e-6;Vec3<T> bodyCOM(0, 0, 0);SpatialInertia<T> bodyInertia(cheetah._bodyMass, bodyCOM, bodyRotationalInertia);

确定关节转子和关节刚接连杆的末端位置 ,在关节坐标系下

  cheetah._abadRotorLocation = Vec3<T>(0.125, 0.049, 0);cheetah._abadLocation =Vec3<T>(cheetah._bodyLength, cheetah._bodyWidth, 0) * 0.5;cheetah._hipLocation = Vec3<T>(0, cheetah._abadLinkLength, 0);cheetah._hipRotorLocation = Vec3<T>(0, 0.04, 0);cheetah._kneeLocation = Vec3<T>(0, 0, -cheetah._hipLinkLength);cheetah._kneeRotorLocation = Vec3<T>(0, 0, 0);

关节坐标系的建立图示:

本体系的坐标轴方向 x轴朝机身正前方,y轴朝机身左侧,z轴竖直向上,初始时各个关节与本体系的方向相同

3.构建浮动基模型

创建基座的物理模型: 浮动基座的编号为baseID = 5;

model.addBase(_bodyInertia);  //创建基座_nDof = 6;   // 基座的自由度  RPY XYZfor (size_t i = 0; i < 6; i++) {_parents.push_back(0);      //给基座创建刚体编号 0 0 0 0 0 0 6个0_gearRatios.push_back(0);_jointTypes.push_back(JointType::Nothing);  // doesn't actually matter_jointAxes.push_back(CoordinateAxis::X);    // doesn't actually matter_Xtree.push_back(eye6);     //刚体内部的空间变换矩阵_Ibody.push_back(zeroInertia);  //刚体的惯性张量_Xrot.push_back(eye6);_Irot.push_back(zeroInertia);_bodyNames.push_back("N/A");}//基座有用的参数 _jointTypes[5] = JointType::FloatingBase;    基座的关节类型_Ibody[5] = inertia;                         基座的惯性张量_gearRatios[5] = 1;                          基座的减速比_bodyNames[5] = "Floating Base";             基座的名称

给基座添加动力学参数

    _v.push_back(zero6);     //关节的空间速度_vrot.push_back(zero6);  //转子的空间速度_a.push_back(zero6);     //关节的空间加速度_arot.push_back(zero6);_avp.push_back(zero6);   //连杆质心加速度_avprot.push_back(zero6); //连杆转子质心加速度_c.push_back(zero6);        //非惯性力 包含科氏力与离心力_crot.push_back(zero6); _S.push_back(zero6);         //关节空间到运动空间的速度映射向量_Srot.push_back(zero6);_f.push_back(zero6);         //关节受到的空间力_frot.push_back(zero6);_fvp.push_back(zero6);      //连杆质心的空间力_fvprot.push_back(zero6);_ag.push_back(zero6);     //连杆所受到的重力_agrot.push_back(zero6);_IC.push_back(zeroInertia); //多刚体的惯性张量_Xup.push_back(eye6);      //从父刚体到子刚体的空间变换矩阵_Xuprot.push_back(eye6);_Xa.push_back(eye6);       //从世界系到当前关节坐标系的空间变换矩阵

给浮动基座添加8个点或者说叫做8个坐标 如下图

model.addGroundContactBoxPoints(5, bodyDims);

  addGroundContactPoint(bodyId, Vec3<T>( dims(0),  dims(1),  dims(2))/2);addGroundContactPoint(bodyId, Vec3<T>(-dims(0),  dims(1),  dims(2))/2);addGroundContactPoint(bodyId, Vec3<T>( dims(0), -dims(1),  dims(2))/2);addGroundContactPoint(bodyId, Vec3<T>(-dims(0), -dims(1),  dims(2))/2);addGroundContactPoint(bodyId, Vec3<T>(dims(0), dims(1), -dims(2)) / 2);addGroundContactPoint(bodyId, Vec3<T>(-dims(0), dims(1), -dims(2)) / 2);addGroundContactPoint(bodyId, Vec3<T>(dims(0), -dims(1), -dims(2)) / 2);addGroundContactPoint(bodyId, Vec3<T>(-dims(0), -dims(1), -dims(2)) / 2);

添加关节和连杆:一个电机及其固连的连杆视作一个刚体。

_parents[18]= 0 0 0 0 0 0 5 6 7 5 9 10 5 12 13 5 15 16   自由度与刚体编号的对应关系
前六个零代表浮动基座  后面12个每三个一组代表一条腿的三个刚体的编号
    if (sideSign < 0) {model.addBody(_abadInertia.flipAlongAxis(CoordinateAxis::Y),_abadRotorInertia.flipAlongAxis(CoordinateAxis::Y),_abadGearRatio, baseID, JointType::Revolute,CoordinateAxis::X, xtreeAbad, xtreeAbadRotor);     //右侧} else {model.addBody(_abadInertia, _abadRotorInertia, _abadGearRatio, baseID,JointType::Revolute, CoordinateAxis::X, xtreeAbad,xtreeAbadRotor);                                   //左侧}

sideSign表示这个关节是在身体的右侧还是在身体的左侧,-1表示右侧,+1表示左侧,由于abad这个电机与身体刚接,没有相对位移,因此它的编号为_parents[6]=5;  同理还有_parents[9]=_parents[12]=_parents[15]=5;

  _parents.push_back(parent);    //添加刚体编号_gearRatios.push_back(gearRatio);   //添加刚体关节电机的减速比_jointTypes.push_back(jointType);   //添加关节的类型_jointAxes.push_back(jointAxis);    //添加关节绕本体坐标系的旋转轴_Xtree.push_back(Xtree);            //添加刚体内部的常量空间变换_Xrot.push_back(Xrot);              //电机转子的_Ibody.push_back(inertia);          //刚体的惯性张量_Irot.push_back(rotorInertia);      _nDof++;                            //每创建一个刚体就加一个自由度
Mat6<T> xtreeAbad = createSXform(I3, withLegSigns<T>(_abadLocation, legID));
abad关节的内部的常量空间变换矩阵

添加hip髋关节和连杆 :

    Mat6<T> xtreeHip =createSXform(coordinateRotation<T>(CoordinateAxis::Z, T(M_PI)),withLegSigns<T>(_hipLocation, legID));    //刚体内的常量变换矩阵Mat6<T> xtreeHipRotor =createSXform(coordinateRotation<T>(CoordinateAxis::Z, T(M_PI)),withLegSigns<T>(_hipRotorLocation, legID));    //对应电机转子的常量变换矩阵if (sideSign < 0) {model.addBody(_hipInertia.flipAlongAxis(CoordinateAxis::Y),_hipRotorInertia.flipAlongAxis(CoordinateAxis::Y),_hipGearRatio, bodyID - 1, JointType::Revolute,CoordinateAxis::Y, xtreeHip, xtreeHipRotor);    //右侧} else {model.addBody(_hipInertia, _hipRotorInertia, _hipGearRatio, bodyID - 1,JointType::Revolute, CoordinateAxis::Y, xtreeHip,xtreeHipRotor);                左侧}// add knee ground contact pointmodel.addGroundContactPoint(bodyID, Vec3<T>(0, 0, -_hipLinkLength));  //初始时hip关节刚接连杆的末端在hip关节坐标系下的位置。

对应的刚体编号 _parents[7]=6    _parents[10]=9   _parents[13]=12     _parents[16]=15;

添加knee膝盖关节及其连杆:

Mat6<T> xtreeKnee = createSXform(I3, _kneeLocation);Mat6<T> xtreeKneeRotor = createSXform(I3, _kneeRotorLocation);if (sideSign < 0) {model.addBody(_kneeInertia.flipAlongAxis(CoordinateAxis::Y),_kneeRotorInertia.flipAlongAxis(CoordinateAxis::Y),_kneeGearRatio, bodyID - 1, JointType::Revolute,CoordinateAxis::Y, xtreeKnee, xtreeKneeRotor);model.addGroundContactPoint(bodyID, Vec3<T>(0, _kneeLinkY_offset, -_kneeLinkLength), true);   //右侧,同理是膝盖刚接连杆末端的坐标 在膝盖关节坐标系下的描述} else {model.addBody(_kneeInertia, _kneeRotorInertia, _kneeGearRatio, bodyID - 1,JointType::Revolute, CoordinateAxis::Y, xtreeKnee,xtreeKneeRotor);model.addGroundContactPoint(bodyID, Vec3<T>(0, -_kneeLinkY_offset, -_kneeLinkLength), true);  //坐标系为当前刚体坐标系}

添加重力参数

  Vec3<T> g(0, 0, -9.81);model.setGravity(g);

构建浮动基模型的目的是为了求解动力学方程的质量矩阵M,  非惯性和惯性力矩阵,以及接触雅可比矩阵。

利用forwardKinematics()这个函数 求出 父刚体到子刚体的空间变换矩阵、科氏力加速度,刚体i到世界系的空间变换矩阵   这样就可以求得足端在世界坐标系下的位置和速度

   _Xup[5] = createSXform(quaternionToRotationMatrix(_state.bodyOrientation),_state.bodyPosition);   //计算身体从世界系到本体系的运动状态的变换矩阵_v[5] = _state.bodyVelocity;   //身体在空间中的六维速度 由角速度和平动速度组成for (size_t i = 6; i < _nDof; i++) {// joint xformMat6<T> XJ = jointXform(_jointTypes[i], _jointAxes[i], _state.q[i - 6]);    //纯旋转矩阵  刚体的坐标系在关节处_Xup[i] = XJ * _Xtree[i];//计算从父刚体到子刚体的运动状态变换矩阵_S[i] = jointMotionSubspace<T>(_jointTypes[i], _jointAxes[i]);//关节运动子空间到空间速度的映射向量SVec<T> vJ = _S[i] * _state.qd[i - 6];  // total velocity of body i_v[i] = _Xup[i] * _v[_parents[i]] + vJ;  //子刚体的空间速度// Coriolis accelerations_c[i] = motionCrossProduct(_v[i], vJ);//子刚体的科氏力加速度// calculate from absolute transformationsfor (size_t i = 5; i < _nDof; i++) {if (_parents[i] == 0) {_Xa[i] = _Xup[i];  // float base   世界系到身体的空间变换矩阵} else {_Xa[i] = _Xup[i] * _Xa[_parents[i]];//世界系到刚体i的空间变换矩阵}}// ground contact points//  // TODO : we end up inverting the same Xa a few times (like for the 8//  points on the body). this isn't super efficient.for (size_t j = 0; j < _nGroundContact; j++) {if (!_compute_contact_info[j]) continue;size_t i = _gcParent.at(j);   Mat6<T> Xai = invertSXform(_Xa[i]);  // from link to absolute  从刚体i到世界系的空间变换矩阵SVec<T> vSpatial = Xai * _v[i];//在世界系下的空间速度// foot position in world_pGC.at(j) = sXFormPoint(Xai, _gcLocation.at(j));    //16个点在世界坐标系下的位置_vGC.at(j) = spatialToLinearVelocity(vSpatial, _pGC.at(j)); //16个点在世界系下的速度}

计算刚体质心的空间加速度:

由biasAccelerations()计算   由重力和非惯性力产生

  _avp[5] << 0, 0, 0, 0, 0, 0;  //基座的空间加速度for (size_t i = 6; i < _nDof; i++) {// Outward kinamtic propagtion_avp[i] = _Xup[i] * _avp[_parents[i]] + _c[i];    //刚体i质心的空间加速度}

求解接触雅可比

size_t i = _gcParent.at(k);   //i= 5 5 5 5 5 5 5 5 7 8 10 11 13 14 16 17

前面8个点表示的是四个hip电机的中心位置上下对称的点  后面八个点分别是四条腿的hip和knee关节刚接连杆的末端位置

 for (size_t k = 0; k < _nGroundContact; k++) {_Jc[k].setZero();   //每个都是3x18_Jcdqd[k].setZero();  //3x1// Skip it if we don't care about itif (!_compute_contact_info[k]) continue;size_t i = _gcParent.at(k);   //i= 5 5 5 5 5 5 5 5 7 8 10 11 13 14 16 17// Rotation to absolute coordsMat3<T> Rai = _Xa[i].template block<3, 3>(0, 0).transpose();   //从当前刚体坐标系到世界系的旋转变换矩阵Mat6<T> Xc = createSXform(Rai, _gcLocation.at(k)); //从当前刚体坐标系到世界系的空间变换矩阵  // Bias accelerationSVec<T> ac = Xc * _avp[i];   //刚体i在世界系下的空间加速度SVec<T> vc = Xc * _v[i];     //刚体i在世界系下空间速度// Correct to classical_Jcdqd[k] = spatialToLinearAcceleration(ac, vc);   //工作空间加速度// rows for linear velcoity in the worldD3Mat<T> Xout = Xc.template bottomRows<3>();    //3x6// from tips to basewhile (i > 5) {   //i的取值为  7 8 10 11 13 14 16 17 _Jc[k].col(i) = Xout * _S[i];Xout = Xout * _Xup[i];i = _parents[i];}_Jc[k].template leftCols<6>() = Xout;         //leftcols(6) 前六列 }

接触雅可比矩阵3x18的含义 雅可比矩阵的行是每条腿在空间中的自由度,hip和knee在空间中有两个自由度,abad电机垂直与hip电机,增加一个维度。雅可比矩阵的前六列是描述浮动基座的,

第6、7、8列是描述右前腿的,第9、10、11l列是描述左前腿的,第12、13、14列是描述右后腿的

第15、16、17列描述左后腿。这些列不是在用一个接触雅可比里面;

_Jc[8]表示的是从hip关节刚接连杆末端到浮动基的雅克比(或者说是从knee关节到浮动基的雅可比)

_Jc[9]表示的是从足端到浮动基的雅可比。_Jc[9]是右前腿的接触雅可比,同理_Jc[11]、_Jc[13]、_Jc[15]分别是左前、右后、左后的接触雅可比。

具体推算过程如下:

求解雅克的思想就是牛顿欧拉的内推法,由基座速度,角速度,推出末端的线速度和角速度。

四足机器人动力学建模(一)相关推荐

  1. 四足机器人(一)----MATLAB simulink对四足机器人物理建模

    四足机器人(一)----MATLAB simulink对四足机器人物理建模 一. 本设计中用的是网上下载的别人已经画好的四足机器狗的3D模型. 那么我们就需要将这些3D模型导入到MATLAB的建模中, ...

  2. 四足机器人 2.建模和步态规划

    1.建模 四足机器人建模: 运动学建模和动力学建模 四足机器人在运动过程中,与所处环境进行交互作用,为提高机器人运动的稳定性和适应性,需要整体考虑四足机器人的动力学模型.足-地接触模型和步态生成与变换 ...

  3. 四足机器人—matlab机器人工具箱DH建模

    目录 基于matlab机器人工具箱的四足机器人DH建模 模型展示 代码 参考博客 基于matlab机器人工具箱的四足机器人DH建模 模型展示 代码 %2021/10/28四足机器人DH建模 %碎弧的星 ...

  4. 【关于四足机器人那些事】零力矩点(zmp)

    根据零力矩点理论分析机器人行进过程的稳定条件,利用稳定裕度的概念,在支撑多边形中求取最优稳定点来规划零力矩点.可以为避免 walk步态中频繁调整躯干姿态导致的能耗和行进速度损失[1] 此外," ...

  5. matlab四足仿真,基于MATLAB的四足机器人建模与仿真.docx

    摘要:本课题讨论了一种利用MATLAB中Robotics Toolbox对机器人进行的仿真建模的技术,对四足机器人进行行仿真建模.通过设计确定主要研究对象为哺乳类四足机器人.确定了机器人的腿部关节结构 ...

  6. 【关于四足机器人那些事】腿部运动学建模(三维)

    本篇将会三维空间中,对四足机器人的腿部进行数学建模,求解器正逆运动学解,包含详细公式推导与计算 首先,我们来看三维空间中简图: 其中a表示髋关节距离主体得偏移,L1,L2共面,与a保持垂直关系,[x, ...

  7. 【关于四足机器人那些事】直驱四足机器人Minitaur运动学建模

    文章目录 一.结构参数 二.腿部运动空间 随着人类环境中对机器人交互的需求不断增长,动态四足机器人的发展正成为人们越来越感兴趣的话题,但是它们需要自适应的控制方案来应对穿越现实世界地形时遇到的挑战. ...

  8. 四足机器人|机器狗|仿生机器人|多足机器人|Adams仿真|Simulink仿真|基于CPG的四足机器人Simulink与Adams虚拟样机|源码可直接执行|绝对干货!需要资料及指导的可以联系我!

    四足机器人|机器狗|仿生机器人|多足机器人|基于CPG的四足机器人Simulink与Adams虚拟样机|源码可直接执行|绝对干货!需要资料及指导的可以联系我!QQ:1096474659 基于CPG的四 ...

  9. 四足机器人——12自由度舵机狗DIY(二)

    目录 一.四足机器人步态研究控制的现状 1.1目前的三种控制策略 <1>基于静态稳定的控制方法. <2>基于动力学模型的控制方法. <3>基于生物所具有的神经性调节 ...

  10. 史上最全 2019 ICRA顶会四足机器人文献整理

    史上最全 2019 ICRA顶会四足机器人文献整理 一.ICRA论文集中相关文献对应subsession时间 二.文献整理内容 一.ICRA论文集中相关文献对应subsession时间 15:15-1 ...

最新文章

  1. linux 将当前时间往后调整2分钟_自动调整linux系统时间和时区与Internet时间同步...
  2. Elicpse创建Maven项目
  3. 已知c语言程序有主程序模块prog.c,嵌入式系统试卷--A卷
  4. python编辑器_资深程序员:学Python我推荐你用这几款编辑器
  5. [Godot] v4.0.alpha1 GDScript 实现第三人称控制器
  6. Bootstrap3 面板 .panel 容器
  7. 3110: [Zjoi2013]K大数查询
  8. 扩展Reporting Services和SQL Server 2016中的更改
  9. [转载] 使用python 中的numpy创建数组
  10. 爬虫学习(七)——使用代理服务器进行数据爬取
  11. 验证码 工具 Kaptcha 配置参数
  12. 设计师出差必备的5款移动端设计软件
  13. 规则引擎Drools使用 第十一篇 Drools 的高级语法之LHS增强
  14. 想写一个供教育培训机构排课和教师管理的软件
  15. 如何将mp4视频压缩变小,视频压缩快速完成
  16. 苹果党福利!手机数据备份恢复使用攻略
  17. Dubbo官方入门实例
  18. 什么是ETL,ETL是什么技术?
  19. 圆上任意四点在同一个半圆上的概率
  20. 字符斜杠是合法常量吗_C语言中,下列不合法的字符常量是

热门文章

  1. Mac系统用命令打开ping端口的方法
  2. 小鬼授权系统源码全解密源码 附授权代码
  3. 后端提供的excel文档流如何下载?——前端基础知识
  4. 搭建docker监控平台
  5. adb命令——简单常用命令介绍:截图——adb shell screencap -p /sdcard/123.png...
  6. 8位单片机003兼容替换意法半导体STM8S003F3P6
  7. matlab符号运算求二阶微分方程,matlab二阶微分方程求解x 0.2x 0.4x=0.2u(t)
  8. vue3小兔鲜儿项目文档,视频
  9. GET和POST 区别
  10. 01企业网络高级解决方案