Modeling and Code Generation for a Robot Arm
Introduction
This application models a robot arm with three degrees of freedom. To model the arm, the worksheet does the following:
Analytically derives the Denavit & Hartenberg transformation matrix for each of the three joints
Generates optimized C code for the angle of the third joint, in terms of the position of the end effector
Lets the user specify a parametric path for the tip of the robot to follow
Animates the robot following the parametric path
Reference:
Adapted from http://www.maplesoft.com/applications/view.aspx?SID=6850
Transformation Matrix for One Joint
restart:withplots:withplottools:withColorTools:
A1≔cos⁡θ−sin⁡θ00sin⁡θcos⁡θ0000100001:A2≔10000100001d0001:B1≔A2.A1:A3≔10000cos⁡α−sin⁡α00sin⁡αcos⁡α00001:A4≔100a010000100001:B2≔A3.A4:H≔B1.B2;
_rtable18446746790769198014
Transformation Matrix of Tip wrt Base
Next, use parameters for a robot with a sequence of three arms and compute the transformation matrix for the tip of the robot with respect to its base.
H1≔evalH,θ=θ1,α=−π/2,a=0,d=lengthArm1:H2≔evalH,θ=θ2,α=0,d=0,a=lengthArm2:H3≔evalH,θ=θ3,α=0,a=lengthArm3+lengthTip,d=0:H14≔H1·H2·H3:
Path for Robot Tip to Follow
This is the required path for the end effector, as a function of time.
path ≔ x=350−50⋅sint+75⋅ sin3⋅ t, y=450−80⋅ cost+50⋅ sin5⋅ t, z=500−30⋅ sin2⋅ t+60⋅ cos5⋅ t:
Deriving Joint Angles
First Angle
v≔0,0,0,1:w≔H14·v:eq1≔w1w2=xy:Θ1≔solveeq1,θ1
Θ1≔arctan⁡yx
Second Angle
u≔w12+w22+w32−A:v≔w3−z:W≔simplifyu−2 lengthArm1⋅v:Θ≔solveW,θ3:Θ2≔evalΘ,A=z2+x2+y2
Θ2≔arccos⁡x2+y2+z2−2⁢z⁢lengthArm1+lengthArm12−lengthArm22−lengthArm32−2⁢lengthArm3⁢lengthTip−lengthTip22⁢lengthArm2⁢lengthArm3+lengthTip
Third Angle
W1≔w3−z:W2≔evalW1,θ3=Θ2:sol≔solveW2=0,θ2:
Θ3≔simplifysol1+π/2
Θ3≔arctan⁡−lengthArm2⁢x2+y2⁢x2+y2+z2−2⁢z⁢lengthArm1+lengthArm12+lengthArm22−lengthArm32−2⁢lengthArm3⁢lengthTip−lengthTip22⁢lengthArm3+lengthTip⁢−x2+y2+z2−2⁢z⁢lengthArm1+lengthArm12−lengthArm22+2⁢lengthArm3+2⁢lengthTip⁢lengthArm2−lengthArm32−2⁢lengthArm3⁢lengthTip−lengthTip2⁢x2+y2+z2−2⁢z⁢lengthArm1+lengthArm12−lengthArm22+−2⁢lengthArm3−2⁢lengthTip⁢lengthArm2−lengthArm32−2⁢lengthArm3⁢lengthTip−lengthTip2lengthArm22⁢lengthArm3+lengthTip2−z−lengthArm1⁢x2+y2+z2−2⁢z⁢lengthArm1+lengthArm12+lengthArm22−lengthArm32−2⁢lengthArm3⁢lengthTip−lengthTip22x2+y2+z2−2⁢z⁢lengthArm1+lengthArm12⁢lengthArm2⁢x2+y2+z2−2⁢z⁢lengthArm1+lengthArm12+lengthArm22−lengthArm32−2⁢lengthArm3⁢lengthTip−lengthTip2,−lengthArm2⁢lengthArm3+lengthTip⁢z−lengthArm1⁢−x2+y2+z2−2⁢z⁢lengthArm1+lengthArm12−lengthArm22+2⁢lengthArm3+2⁢lengthTip⁢lengthArm2−lengthArm32−2⁢lengthArm3⁢lengthTip−lengthTip2⁢x2+y2+z2−2⁢z⁢lengthArm1+lengthArm12−lengthArm22+−2⁢lengthArm3−2⁢lengthTip⁢lengthArm2−lengthArm32−2⁢lengthArm3⁢lengthTip−lengthTip2lengthArm22⁢lengthArm3+lengthTip2+x2+y2⁢x2+y2+z2−2⁢z⁢lengthArm1+lengthArm12+lengthArm22−lengthArm32−2⁢lengthArm3⁢lengthTip−lengthTip22x2+y2+z2−2⁢z⁢lengthArm1+lengthArm12⁢lengthArm2+π2
Code Generation
This is the C code for the angle of the third joint as a function of the position of the end effector, and the arm lengths.
CodeGenerationC⁡Θ3,optimize,deducetypes=false
t1 = x * x; t2 = y * y; t4 = z * z;
t6 = 0.2e1 * z * lengthArm1; t7 = lengthArm1 * lengthArm1; t8 = lengthArm2 * lengthArm2; t9 = lengthArm3 * lengthArm3; t11 = 0.2e1 * lengthArm3 * lengthTip; t12 = lengthTip * lengthTip; t13 = t1 + t2 + t4 - t6 + t7 + t8 - t9 - t11 - t12; t14 = t13 * t13; t16 = sqrt(t14 * (t1 + t2)); t18 = lengthArm3 + lengthTip; t25 = t18 * t18; t29 = sqrt(-0.1e1 / t25 / t8 * (-0.2e1 * lengthArm2 * t18 + t1 - t11 - t12 + t2 + t4 - t6 + t7 - t8 - t9) * (0.2e1 * lengthArm2 * t18 + t1 - t11 - t12 + t2 + t4 - t6 + t7 - t8 - t9)); t32 = z - lengthArm1; t36 = 0.1e1 / (t1 + t2 + t4 - t6 + t7); t38 = 0.1e1 / lengthArm2; t48 = atan2(0.1e1 / t13 * t38 * t36 * (-t29 * t18 * t16 * lengthArm2 - t14 * t32), t38 * t36 * (-t29 * t32 * lengthArm2 * t18 + t16)); t50 = t48 + 0.3141592654e1 / 0.2e1;
Animation
N≔200:
radiusBase≔150:radiusArm1≔70:radiusJoint2≔radiusArm1+5:radiusArm2≔60:radiusArm3≔50:
lengthArm1 ≔ 500: lengthArm2 ≔450: lengthArm3 ≔350: lengthTip≔200:
forpfrom0toNdo s≔2.0 π p/N; pathAtTime≔evalpath,t=s: pxp,pyp,pzp≔rhspathAtTime1,rhspathAtTime2,rhspathAtTime3;for i from 1 to 3 do θp,i≔evalsubspath,Θ∥i,t=s: end doend do:
pathTrace≔pointplot3dseq⁡pxu,pyu,pzu,u=0..N,color=ColorRGB,0/255,79/255,121/255,connect=true:
opts≔color=ColorRGB,108/255,122/255,137/255,grid=10,2:baseCyl≔cylinder0,0,0,radiusBase,80,opts:arm1≔cylinder0,0,0,radiusArm1,lengthArm1,opts:joint2≔translaterotatecylinder0,0,0,radiusJoint2,2 radiusJoint2,opts, π/2,0,0,0,−radiusJoint2,lengthArm1:arm2≔cylinder0,0,0,radiusArm2,lengthArm2,opts:joint3≔rotatecylinder0,0,0,radiusArm2,2 radiusArm2,opts, π/2,0,0:arm3≔cylinder0,0,0,radiusArm3,lengthArm3,opts:tip≔cone0,0,0,radiusArm3,lengthTip,opts:
robotAnim≔procp local Joint2, Arm2,Joint3,Arm3,Tip: Joint2≔rotatejoint2,0,0,−θp,1: Arm2≔rotatetranslate⁡rotate⁡arm2,0,−θp,3,0,0,0,lengthArm1,0,0,−θp,1: Joint3≔rotatetranslate⁡joint3,lengthArm2⋅sinθp,3,−radiusArm2,lengthArm1+lengthArm2⋅cosθp,3,0,0,−θp,1: Arm3≔rotatetranslate⁡rotatearm3,0,−θp,3 −θp,2,0,lengthArm2⋅sinθp,3,0,lengthArm1+lengthArm2⋅cosθp,3,0,0,−θp,1: Tip≔rotatetranslate⁡rotatetip,0,π − θp,3 − θp,2,0,lengthArm2⋅sinθp,3+lengthArm3+lengthTip⋅sinθp,3+θp,2,0,lengthArm1+lengthArm2⋅cosθp,3+lengthArm3+lengthTip⋅cosθp,3+θp,2,0,0,−θp,1:displaypathTrace,baseCyl,arm1,Joint2,Arm2,Joint3,Arm3,Tip,scaling=constrained,orientation=80,15,axes=none,style=patchnogridend proc:
animate⁡robotAnim,t,t=`$`⁡1..200
Download Help Document
What kind of issue would you like to report? (Optional)