(* Inverse dynamics for a two joint mechanism using Newton Euler approach *) (* Moment of inertia about center of mass of each link *) (* Standard coordinate system. *) gravity = {0, -G} (*Define rotation matrices that allow us to do the forward kinematics.*) (*R01 rotates from the link 1 frame to the link 0 frame.*) r01={{Cos[a1],-Sin[a1]},{Sin[a1],Cos[a1]}} r10=Transpose[r01] r12={{Cos[a2],-Sin[a2]},{Sin[a2],Cos[a2]}} r21=Transpose[r12] (*Deal with time dependence *) SetAttributes [m1, Constant] SetAttributes [m2, Constant] SetAttributes [l1, Constant] SetAttributes [l2, Constant] SetAttributes [l1cm, Constant] SetAttributes [l2cm, Constant] SetAttributes [I1, Constant] SetAttributes [I2, Constant] a1/: Dt[a1, t] = a1d a2/: Dt[a2, t] = a2d a1d/: Dt[a1d, t] = a1dd a2d/: Dt[a2d, t] = a2dd (*Define link lengths.*) s1 = {l1,0} s2 = {l2,0} (*Define the location of the proximal end of each link (in world coordinates) *) p1 = {0, 0} p2 = r01 . s1 (* {l1 Cos[a1], l1 Sin[a1]} *) (*Define the location of the center of mass with respect to the proximal end of each link.*) cm1 = r01 . {l1cm,0} (* {l1cm Cos[a1], l1cm Sin[a1]} *) cm2 = r01 . r12 . {l2cm,0} (* {l2cm (Cos[a1] Cos[a2] - Sin[a1] Sin[a2]), l2cm (Cos[a2] Sin[a1] + Cos[a1] Sin[a2])} *) (*Compute the location of the center of mass of each link.*) q1 = p1 + cm1 (* {l1cm Cos[a1], l1cm Sin[a1]} *) q2 = p2 + cm2 (* {l1 Cos[a1] + l2cm (Cos[a1] Cos[a2] - Sin[a1] Sin[a2]), l1 Sin[a1] + l2cm (Cos[a2] Sin[a1] + Cos[a1] Sin[a2])} *) (*Compute the linear velocity and acceleration of each link cm.*) qd1 = Dt[q1,t] (* {-(a1d l1cm Sin[a1]), a1d l1cm Cos[a1]} *) qd2 = Dt[q2,t] (* {-(a1d l1 Sin[a1]) + l2cm > (-(a1d Cos[a2] Sin[a1]) - a2d Cos[a2] Sin[a1] - a1d Cos[a1] Sin[a2] - > a2d Cos[a1] Sin[a2]), a1d l1 Cos[a1] + > l2cm (a1d Cos[a1] Cos[a2] + a2d Cos[a1] Cos[a2] - a1d Sin[a1] Sin[a2] - > a2d Sin[a1] Sin[a2])} *) qdd1 = Dt[qd1,t] (* 2 {-(a1d l1cm Cos[a1]) - a1dd l1cm Sin[a1], 2 > a1dd l1cm Cos[a1] - a1d l1cm Sin[a1]} *) qdd2 = Dt[qd2,t] (* 2 {-(a1d l1 Cos[a1]) - a1dd l1 Sin[a1] + 2 > l2cm (-(a1d Cos[a1] Cos[a2]) - 2 a1d a2d Cos[a1] Cos[a2] - 2 > a2d Cos[a1] Cos[a2] - a1dd Cos[a2] Sin[a1] - a2dd Cos[a2] Sin[a1] - 2 > a1dd Cos[a1] Sin[a2] - a2dd Cos[a1] Sin[a2] + a1d Sin[a1] Sin[a2] + 2 > 2 a1d a2d Sin[a1] Sin[a2] + a2d Sin[a1] Sin[a2]), 2 > a1dd l1 Cos[a1] - a1d l1 Sin[a1] + > l2cm (a1dd Cos[a1] Cos[a2] + a2dd Cos[a1] Cos[a2] - 2 > a1d Cos[a2] Sin[a1] - 2 a1d a2d Cos[a2] Sin[a1] - 2 2 > a2d Cos[a2] Sin[a1] - a1d Cos[a1] Sin[a2] - 2 > 2 a1d a2d Cos[a1] Sin[a2] - a2d Cos[a1] Sin[a2] - > a1dd Sin[a1] Sin[a2] - a2dd Sin[a1] Sin[a2])} *) (*Compute net link forces.*) f1 = m1 * qdd1 - m1 * gravity (* 2 {m1 (-(a1d l1cm Cos[a1]) - a1dd l1cm Sin[a1]), 2 > G m1 + m1 (a1dd l1cm Cos[a1] - a1d l1cm Sin[a1])} *) f2 = m2 * qdd2 - m2 * gravity (* 2 {m2 (-(a1d l1 Cos[a1]) - a1dd l1 Sin[a1] + 2 > l2cm (-(a1d Cos[a1] Cos[a2]) - 2 a1d a2d Cos[a1] Cos[a2] - 2 > a2d Cos[a1] Cos[a2] - a1dd Cos[a2] Sin[a1] - > a2dd Cos[a2] Sin[a1] - a1dd Cos[a1] Sin[a2] - 2 > a2dd Cos[a1] Sin[a2] + a1d Sin[a1] Sin[a2] + 2 > 2 a1d a2d Sin[a1] Sin[a2] + a2d Sin[a1] Sin[a2])), 2 > G m2 + m2 (a1dd l1 Cos[a1] - a1d l1 Sin[a1] + > l2cm (a1dd Cos[a1] Cos[a2] + a2dd Cos[a1] Cos[a2] - 2 > a1d Cos[a2] Sin[a1] - 2 a1d a2d Cos[a2] Sin[a1] - 2 2 > a2d Cos[a2] Sin[a1] - a1d Cos[a1] Sin[a2] - 2 > 2 a1d a2d Cos[a1] Sin[a2] - a2d Cos[a1] Sin[a2] - > a1dd Sin[a1] Sin[a2] - a2dd Sin[a1] Sin[a2]))} *) (*Compute the angular velocity of each link.*) w1 = Dt[a1,t] (* a1d *) w2 = w1 + Dt[a2,t] (* a1d + a2d *) (*Compute the angular acceleration of each link.*) wd1 = Dt[w1,t] (* a1dd *) wd2 = Dt[w2,t] (* a1dd + a2dd *) (*Compute net link torques.*) n1 = I1*wd1 (* a1dd I1 *) n2 = I2*wd2 (* (a1dd + a2dd) I2 *) (*Compute forces at the joints.*) f12 = f2 (* Huge mess *) f01 = f1 + f12 (* Huge mess *) (*Define the 2D vector cross product.*) CP[X_,Y_] := X[[1]]*Y[[2]] - X[[2]]*Y[[1]] (*Compute torques at the joints.*) tau2 = n2 + CP [ cm2, f2 ] (* Huge mess *) tau1 = n1 + tau2 + CP [ cm1, f1 ] + CP[ p2-p1, f12 ] (* Huge mess *) (*Clean it up*) tau1 = Expand[tau1, Trig->True] (* 2 2 a1dd I1 + a1dd I2 + a2dd I2 + a1dd l1cm m1 + a1dd l1 m2 + 2 2 > a1dd l2cm m2 + a2dd l2cm m2 + G l1cm m1 Cos[a1] + G l1 m2 Cos[a1] + > 2 a1dd l1 l2cm m2 Cos[a2] + a2dd l1 l2cm m2 Cos[a2] + > G l2cm m2 Cos[a1] Cos[a2] - 2 a1d a2d l1 l2cm m2 Sin[a2] - 2 > a2d l1 l2cm m2 Sin[a2] - G l2cm m2 Sin[a1] Sin[a2] *) tau2 = Expand[tau2, Trig->True] (* 2 2 a1dd I2 + a2dd I2 + a1dd l2cm m2 + a2dd l2cm m2 + > a1dd l1 l2cm m2 Cos[a2] + G l2cm m2 Cos[a1] Cos[a2] + 2 > a1d l1 l2cm m2 Sin[a2] - G l2cm m2 Sin[a1] Sin[a2] *) (* To get C code use *) CForm[tau1] (* a1dd*I1 + a1dd*I2 + a2dd*I2 + a1dd*Power(l1cm,2)*m1 + a1dd*Power(l1,2)*m2 + a1dd*Power(l2cm,2)*m2 + a2dd*Power(l2cm,2)*m2 + G*l1cm*m1*Cos(a1) + G*l1*m2*Cos(a1) + 2*a1dd*l1*l2cm*m2*Cos(a2) + a2dd*l1*l2cm*m2*Cos(a2) + G*l2cm*m2*Cos(a1)*Cos(a2) - 2*a1d*a2d*l1*l2cm*m2*Sin(a2) - Power(a2d,2)*l1*l2cm*m2*Sin(a2) - G*l2cm*m2*Sin(a1)*Sin(a2) *) CForm[tau2] (* a1dd*I2 + a2dd*I2 + a1dd*Power(l2cm,2)*m2 + a2dd*Power(l2cm,2)*m2 + a1dd*l1*l2cm*m2*Cos(a2) + G*l2cm*m2*Cos(a1)*Cos(a2) + Power(a1d,2)*l1*l2cm*m2*Sin(a2) - G*l2cm*m2*Sin(a1)*Sin(a2) *)