机器人动力学方程(一):牛顿-欧拉法

1、牛顿-欧拉法

牛顿欧拉法分两步,首先向外迭代,计算出各个杆的角速度,角加速度,质心线加速度,进而计算出每个连杆的合外力(矩);再向内迭代,计算出每个连杆的内力,进而得到关节力矩。迭代过程如下:

牛顿-欧拉迭代法

2、Matlab代码

由于牛顿-欧拉法迭代的特性,使其对于编程来说比较方便实现。基于算法,笔者编写了Matlab函数NewtonEulerDynamics用于求解各个关节力矩的解析表达式:

function torque_list = NewtonEulerDynamics(dh_list, mass_list, mass_center_list, inertia_tensor_list, f_external)

% 输入参数:
% dh_list:机器人DH参数
% mass_list: 连杆的质量,单位kg
% mass_center_list:连杆质心在连杆坐标系下的位置,单位:m
% inertia_tensor_list:连杆关于质心坐标系的惯性张量,质心坐标系与连杆坐标系方位一致
% f_external:施加在末端连杆的外力和外力矩

% 输出参数:
% torque_list:用q,dq,ddq(关节位置、速度、加速度)表达的关节力矩

[rows, columns] = size(dh_list);
number_of_links = rows - 1;
if columns ~= 4
    error('wrong DH parameters!')
end

T = sym([]);
R = sym([]);
a = sym([]);
d = sym([]);
alpha = sym([]);
theta = sym([]);

for i = 1:rows
    % 定义关节位置,速度,加速度符号
    eval(['syms ','q',num2str(i),' real;']);
    eval(['syms ','dq',num2str(i),' real;']);
    eval(['syms ','ddq',num2str(i),' real;']);
    eval(['q(i)=','q',num2str(i),';']);
    eval(['dq(i)=','dq',num2str(i),';']);
    eval(['ddq(i)=','ddq',num2str(i),';']);
end

for i = 1:rows
    dh = dh_list(i,:);
    alpha(i) = dh(1);
    a(i) = dh(2);
    d(i) = dh(3);
    theta(i) = dh(4);
    if i == rows
        q(i) = 0;
    end
    T(:,:,i) = [cos(q(i)),            -sin(q(i)),           0,           a(i);
            sin(q(i))*cos(alpha(i)), cos(q(i))*cos(alpha(i)), -sin(alpha(i)), -sin(alpha(i))*d(i);
            sin(q(i))*sin(alpha(i)), cos(q(i))*sin(alpha(i)), cos(alpha(i)), cos(alpha(i))*d(i);
            0,                     0,                     0,          1];
    T = T(:,:,i);
    % 提取旋转矩阵并求逆
    R(:,:,i) = simplify(inv(T(1:3,1:3)));
    P(:,:,i) = T(1:3,4:4);
end

% 关节轴
z = [0,0,1]';
% 重力加速度符号
syms g real

% 外推 --->
for i = 0:number_of_links-1
    if i == 0
        wi = [0,0,0]';
        dwi = [0,0,0]';
        dvi = [0, g, 0]';
    else
        wi = w(:,i);
        dwi = dw(:,i);
        dvi = dv(:,i);
    end
    w(:,:,i+1) = R(:,:,i+1)*wi + dq(i+1)*z;
    dw(:,:,i+1) = R(:,:,i+1)*dwi + cross(R(:,:,i+1)*wi,dq(i+1)*z) + ddq(i+1)*z;
    dv(:,:,i+1) = R(:,:,i+1)*(cross(dwi,P(:,:,i+1)) + cross(wi,cross(wi,P(:,:,i+1))) + dvi);
    dvc(:,:,i+1) = cross(dw(:,:,i+1),mass_center_list(i+1,:)')...
                    + cross(w(:,:,i+1),cross(w(:,:,i+1),mass_center_list(i+1,:)'))...
                    + dv(:,:,i+1);
    F(:,:,i+1) = mass_list(i+1)*dvc(:,:,i+1);
    N(:,:,i+1) = inertia_tensor_list(:,:,i+1)*dw(:,:,i+1) + cross(w(:,:,i+1),inertia_tensor_list(:,:,i+1)*w(:,:,i+1));
end

f = sym([]);
n = sym([]);

% 内推 <---
for i = number_of_links:-1:1
    if i == number_of_links
        f(:,:,i+1) = f_external(1,:)';
        n(:,:,i+1) = f_external(2,:)';
    end
    f(:,:,i) = R(:,:,i+1)\f(:,:,i+1) + F(:,:,i);
    f(:,:,i) = simplify(f(:,:,i));
    n(:,:,i) = N(:,:,i) + R(:,:,i+1)\n(:,:,i+1) + cross(mass_center_list(i,:)',F(:,:,i))...
                + cross(P(:,:,i+1),R(:,:,i+1)\f(:,:,i+1));
    n(:,:,i) = simplify(n(:,:,i));
    torque_list(i) = dot(n(:,:,i),z);
end
torque_list = torque_list';

以上代码适用于修改的DH模型,如果是标准的DH模型需要做一点修改。代码运行后将给出各个关节扭矩的封闭解

下面的代码给出一个用例:

clc;
clear;
syms q1 q2 m1 m2 L1 L2 real

dh_params = [0, 0,  0, q1; 
             0, L1, 0, q2;
             0, L2, 0, 0];
mass_center = [L1, 0,  0; 
               L2, 0, 0;];
mass = [m1,m2];
inertia_1 = [0,0,0;
             0,0,0;
             0,0,0];
inertia_2 = [0,0,0;
             0,0,0;
             0,0,0];
inertia_tensor(:,:,1) = inertia_1;
inertia_tensor(:,:,2) = inertia_2;
f_ext = [0,0,0;
         0,0,0];
torque = NewtonEulerDynamics(dh_params, mass, mass_center, inertia_tensor, f_ext);

注意dh_params 第三行给出的是末端执行器相对于最后一根连杆的坐标表达。上述代码求解的问题是书中的例题6.7,求解平面二连杆的动力学方程:

平面二连杆

运行后输出:

torque =

 L1^2*ddq1*m1 + L1^2*ddq1*m2 + L2^2*ddq1*m2 + L2^2*ddq2*m2 + L2*g*m2*cos(q1 + q2) + L1*g*m1*cos(q1) + L1*g*m2*cos(q1) - L1*L2*dq2^2*m2*sin(q2) + 2*L1*L2*ddq1*m2*cos(q2) + L1*L2*ddq2*m2*cos(q2) - 2*L1*L2*dq1*dq2*m2*sin(q2)
                           L2*m2*(cos(q2)*(L1*ddq1 + g*cos(q1)) + sin(q2)*(L1*dq1^2 - g*sin(q1)) + L2*(ddq1 + ddq2))

书中的求解结果:

关节力矩

对比可以表明两者一致,证明计算是正确的。当然,编写的代码本身对于关节数目是没有限制的,可用于更多关节机器人的动力学方程计算。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容