欧拉-拉格朗日方程的符号微分
Symbolic differentiation with Euler-Lagrange equation
我正在尝试计算机器人结构的欧拉-拉格朗日方程。
我将使用 q
来表示联合变量的向量。
在我的代码中,我使用
syms t;
q1 = sym('q1(t)');
q2 = sym('q2(t)');
q = [q1, q2];
声明q1
和q2
取决于时间t
。
在我计算拉格朗日 L
之后(在这种情况下,它是一个带有旋转关节的简单 link)
L = (I1z*diff(q1(t), t)^2)/2 + (L1^2*M1*diff(q1(t), t)^2)/8
问题是,当我尝试使用 diff(L, q)
区分 L
和 q
时,出现此错误
Error using sym/diff (line 69)
The second argument must be a variable or a nonnegative integer specifying the number of differentiations.
如何区分 L
和 q
以获得欧拉-拉格朗日方程的第一项?
我也试着把q
写成
syms q1 q2
q = [q1 q2]
没有时间依赖性但微分不起作用,即显然会给我 [0, 0]
这就是我在工作区中得到的(I1z 是 link 相对于 z 轴的惯性,M1 是 link 的质量,L1 是 link 的长度link)
q = [q1(t), q2(t)]
diff(q, t) = [diff(q1(t), t), diff(q2(t), t)]
L = (I1z*diff(q1(t), t)^2)/2 + (L1^2*M1*diff(q1(t), t)^2)/8
如果你想要运行完整的代码,你必须从here下载所有的.m文件,然后使用
[t, q, L, M, I] = initiate();
L = lagrangian(odof(q, L), q, M, I, t, 1)
否则下面的代码应该是一样的
syms t I1z L1 M1
q1 = sym('q1(t)');
q2 = sym('q2(t)');
q = [q1, q2];
qp = diff(q, t);
L = (I1z*qp(1)^2)/2 + (L1^2*M1*qp(1)^2)/8;
编辑
感谢我意识到了这个问题。
示例 1(AVK 的代码)
syms t q1 q2 q1t q2t I1z L1 M1 % variables
L = (I1z*q1t^2)/2 + (L1^2*M1*q1t^2)/8
dLdqt = [diff(L,q1t), diff(L,q2t)]
这将起作用,其结果将是
dLdqt = [(M1*q1t*L1^2)/4 + I1z*q1t, 0]
例2(错误)
syms t q1 q2 q1t q2t I1z L1 M1
L = (I1z*q1t^2)/2 + (L1^2*M1*q1t^2)/8;
qt = [q1t q2t];
dLdqt = diff(L, qt)
这 不会 工作,因为 diff
需要一个 单一 微分变量
示例 3(右)
syms t q1 q2 q1t q2t I1z L1 M1
L = (I1z*q1t^2)/2 + (L1^2*M1*q1t^2)/8;
qt = [q1t q2t];
dLdqt = jacobian(L, qt)
这将工作,因为jacobian
期望至少一个微分变量
编辑 2
似乎 MATLAB 的 Symbolit 工具箱无法处理关于 q(t)
的微分,所以你必须使用 变量 q
.
所以将这些用作函数
q = [q1(t), q2(t), q3(t), q4(t), q5(t), q6(t)]
qp = [diff(q1(t), t), diff(q2(t), t), diff(q3(t), t), diff(q4(t), t), diff(q5(t), t), diff(q6(t), t)]
这些作为变量
qv = [q1, q2, q3, q4, q5, q6];
qvp = [q1p, q2p, q3p, q4p, q5p, q6p];
解决了问题。
整个代码如下所示
syms q1 q2 q3 q4 q5 q6;
syms q1p q2p q3p q4p q5p q6p;
qv = [q1, q2, q3, q4, q5, q6];
qvp = [q1p, q2p, q3p, q4p, q5p, q6p];
Lagv = subs(Lag, [q, qp], [qv, qvp]);
dLdq = jacobian(Lagv, qv);
dLdqp = jacobian(Lagv, qvp);
dLdq = subs(dLdq, [qv, qvp], [q, qp]);
dLdqp = subs(dLdqp, [qv, qvp], [q, qp]);
m_eq = diff(dLdqp, t) - dLdq;
如果要对L求微分,q必须是变量。可以用 subs
换成函数计算
后来:
syms t q1 q2 q1t q2t I1z L1 M1 % variables
L = (I1z*q1t^2)/2 + (L1^2*M1*q1t^2)/8
dLdqt= [diff(L,q1t), diff(L,q2t)]
dLdq = [diff(L,q1), diff(L,q2)]
syms q1_f(t) q2_f(t) % functions
q1t_f(t)= diff(q1_f,t)
q2t_f(t)= diff(q2_f,t)
% replace the variables with the functions
dLdq_f= subs(dLdq,{q1 q2 q1t q2t},{q1_f q2_f q1t_f q2t_f})
dLdqt_f= subs(dLdqt,{q1 q2 q1t q2t},{q1_f q2_f q1t_f q2t_f})
% now we can solve the equation
dsolve(diff(dLdqt_f,t)-dLdq_f==0)
我在 MATLAB 中开发了 Euler-Lagrange 库,其中包含一系列说明性示例。您可以使用以下 link:
下载它
https://www.mathworks.com/matlabcentral/fileexchange/86563-matlab-euler-lagrange-library
我正在尝试计算机器人结构的欧拉-拉格朗日方程。
我将使用 q
来表示联合变量的向量。
在我的代码中,我使用
syms t;
q1 = sym('q1(t)');
q2 = sym('q2(t)');
q = [q1, q2];
声明q1
和q2
取决于时间t
。
在我计算拉格朗日 L
之后(在这种情况下,它是一个带有旋转关节的简单 link)
L = (I1z*diff(q1(t), t)^2)/2 + (L1^2*M1*diff(q1(t), t)^2)/8
问题是,当我尝试使用 diff(L, q)
区分 L
和 q
时,出现此错误
Error using sym/diff (line 69)
The second argument must be a variable or a nonnegative integer specifying the number of differentiations.
如何区分 L
和 q
以获得欧拉-拉格朗日方程的第一项?
我也试着把q
写成
syms q1 q2
q = [q1 q2]
没有时间依赖性但微分不起作用,即显然会给我 [0, 0]
这就是我在工作区中得到的(I1z 是 link 相对于 z 轴的惯性,M1 是 link 的质量,L1 是 link 的长度link)
q = [q1(t), q2(t)]
diff(q, t) = [diff(q1(t), t), diff(q2(t), t)]
L = (I1z*diff(q1(t), t)^2)/2 + (L1^2*M1*diff(q1(t), t)^2)/8
如果你想要运行完整的代码,你必须从here下载所有的.m文件,然后使用
[t, q, L, M, I] = initiate();
L = lagrangian(odof(q, L), q, M, I, t, 1)
否则下面的代码应该是一样的
syms t I1z L1 M1
q1 = sym('q1(t)');
q2 = sym('q2(t)');
q = [q1, q2];
qp = diff(q, t);
L = (I1z*qp(1)^2)/2 + (L1^2*M1*qp(1)^2)/8;
编辑
感谢
示例 1(AVK 的代码)
syms t q1 q2 q1t q2t I1z L1 M1 % variables
L = (I1z*q1t^2)/2 + (L1^2*M1*q1t^2)/8
dLdqt = [diff(L,q1t), diff(L,q2t)]
这将起作用,其结果将是
dLdqt = [(M1*q1t*L1^2)/4 + I1z*q1t, 0]
例2(错误)
syms t q1 q2 q1t q2t I1z L1 M1
L = (I1z*q1t^2)/2 + (L1^2*M1*q1t^2)/8;
qt = [q1t q2t];
dLdqt = diff(L, qt)
这 不会 工作,因为 diff
需要一个 单一 微分变量
示例 3(右)
syms t q1 q2 q1t q2t I1z L1 M1
L = (I1z*q1t^2)/2 + (L1^2*M1*q1t^2)/8;
qt = [q1t q2t];
dLdqt = jacobian(L, qt)
这将工作,因为jacobian
期望至少一个微分变量
编辑 2
似乎 MATLAB 的 Symbolit 工具箱无法处理关于 q(t)
的微分,所以你必须使用 变量 q
.
所以将这些用作函数
q = [q1(t), q2(t), q3(t), q4(t), q5(t), q6(t)]
qp = [diff(q1(t), t), diff(q2(t), t), diff(q3(t), t), diff(q4(t), t), diff(q5(t), t), diff(q6(t), t)]
这些作为变量
qv = [q1, q2, q3, q4, q5, q6];
qvp = [q1p, q2p, q3p, q4p, q5p, q6p];
解决了问题。
整个代码如下所示
syms q1 q2 q3 q4 q5 q6;
syms q1p q2p q3p q4p q5p q6p;
qv = [q1, q2, q3, q4, q5, q6];
qvp = [q1p, q2p, q3p, q4p, q5p, q6p];
Lagv = subs(Lag, [q, qp], [qv, qvp]);
dLdq = jacobian(Lagv, qv);
dLdqp = jacobian(Lagv, qvp);
dLdq = subs(dLdq, [qv, qvp], [q, qp]);
dLdqp = subs(dLdqp, [qv, qvp], [q, qp]);
m_eq = diff(dLdqp, t) - dLdq;
如果要对L求微分,q必须是变量。可以用 subs
换成函数计算
后来:
syms t q1 q2 q1t q2t I1z L1 M1 % variables
L = (I1z*q1t^2)/2 + (L1^2*M1*q1t^2)/8
dLdqt= [diff(L,q1t), diff(L,q2t)]
dLdq = [diff(L,q1), diff(L,q2)]
syms q1_f(t) q2_f(t) % functions
q1t_f(t)= diff(q1_f,t)
q2t_f(t)= diff(q2_f,t)
% replace the variables with the functions
dLdq_f= subs(dLdq,{q1 q2 q1t q2t},{q1_f q2_f q1t_f q2t_f})
dLdqt_f= subs(dLdqt,{q1 q2 q1t q2t},{q1_f q2_f q1t_f q2t_f})
% now we can solve the equation
dsolve(diff(dLdqt_f,t)-dLdq_f==0)
我在 MATLAB 中开发了 Euler-Lagrange 库,其中包含一系列说明性示例。您可以使用以下 link:
下载它https://www.mathworks.com/matlabcentral/fileexchange/86563-matlab-euler-lagrange-library