(*version 5/30/2015, copyright by Nasser M. Abbasi*)
Manipulate[
tick;
Module[{debug = False, eq, r1 = 2, r2 = 1, r3 = .8, L1 = 5, L2 = 5,
L3 = 5, cq1, cq2, cq3, t, k1, k2, k3, k4},
If[state == "RUN" || state == "STEP",
k1 = zDot[{q1, q2, q3, dq1, dq2, dq3}, c1, c2, c3, m1, m2, m3, L1,
L2, L3, r1, r2, r3, torque1, torque2, torque3];
k2 = zDot[{q1, q2, q3, dq1, dq2, dq3} + 0.5*k1*delT, c1, c2, c3,
m1, m2, m3, L1, L2, L3, r1, r2, r3, torque1, torque2, torque3];
k3 = zDot[{q1, q2, q3, dq1, dq2, dq3} + 0.5*k2*delT, c1, c2, c3,
m1, m2, m3, L1, L2, L3, r1, r2, r3, torque1, torque2, torque3];
k4 = zDot[{q1, q2, q3, dq1, dq2, dq3} + k3*delT, c1, c2, c3, m1,
m2, m3, L1, L2, L3, r1, r2, r3, torque1, torque2, torque3];
{q1, q2, q3, dq1, dq2,
dq3} = {q1, q2, q3, dq1, dq2,
dq3} + (1/6)*(k1 + 2*k2 + 2*k3 + k4)*delT;
cq1 = q1;
cq2 = q2;
cq3 = q3;
vEnd = getV3[L1, L2, L3, q1, q2, q3, dq1, dq2, dq3];
(*Print["after setting q1=",q1];*)
ct = Mod[ct + delT, 1000];
If[state == "RUN",
tick = Not[tick]
]
,
cq1 = q1;
cq2 = q2;
cq3 = q3
];
g = Grid[{
(*{Grid[{{q1,q2,q3,dq1,dq2,dq3}},Frame\[Rule]All]},*)
{
Deploy@Graphics3D[
{
(*first link*)
Rotate[
{
{LightGray, Cylinder[{{0, 0, -0.3 r1}, {0, 0, 0}}, 2 r1]},
typeOne[r1, {0, 0, 0}, L1, False, True],
Rotate[
{typeOne[r2, {0, 0, L1}, L2, True, True],
Rotate[
{typeOne[r2, {0, 0, L1 + L2}, L3, True, False]
(*{Red,Arrowheads[Small],Arrow[{{0,0,L1+L2+L3},({0,0,
L1+L2+L3}+vEnd/(.85L3))}]}*)
},
cq3, {1, 0, 0}, {0, 0, L1 + L2 + 0.2 r3}
]
}, cq2, {1, 0, 0}, {0, 0, L1 + 0.2 r1}
]
}, cq1, {0, 0, 1}
]
},
PlotRange -> {{-L1 - 1.2 L2, L1 + 1.2 L2}, {-L2 - 1.2 L3,
L2 + 1.2 L3}, {-L2 - L3, L1 + L2 + 1.5 L3}},
ImageSize -> 300, Boxed -> False, Axes -> False,
SphericalRegion -> True, ViewPoint -> {0, 1, 1},
Method -> {"RotationControl" -> None}
]
},
{Grid[
{
{"time", "\!\(\*SubscriptBox[\(\[Theta]\), \(1\)]\)",
"\!\(\*SubscriptBox[\(\[Theta]\), \(2\)]\)",
"\!\(\*SubscriptBox[\(\[Theta]\), \(3\)]\)"},
{padIt2[ct, {5, 2}], padIt2[Mod[q1*180./Pi, 360], {3, 0}],
padIt2[Mod[q2*180./Pi, 360], {3, 0}],
padIt2[Mod[q3*180./Pi, 360], {3, 0}]}
}, Frame -> All]
}
}
];
(*FinishDynamic[];*)
g
],
Text@Style[Grid[{
{
Grid[{
{Button[
Text@Style["run", 12], {state = "RUN"; tick = Not[tick]},
ImageSize -> {50, 40}],
Button[
Text@Style["step", 12], {state = "STEP"; tick = Not[tick]},
ImageSize -> {50, 40}],
Button[
Text@Style["stop", 12], {state = "STOP"; tick = Not[tick]},
ImageSize -> {50, 40}],
Button[
Text@Style["reset", 12], {state = "STEP"; ct = 0; dq1 = 0.5;
dq2 = 1; dq3 = 1; q1 = angle1; q2 = angle2; q3 = angle3;
tick = Not[tick]}, ImageSize -> {50, 40}]
}}, Spacings -> {1, 1}
], SpanFromLeft
},
{
Grid[{{"Link 1 properties"},
{"mass (kg)",
Manipulator[
Dynamic[m1, {m1 = #; tick = Not[tick]} &], {1, 100, 1},
ImageSize -> Tiny], Dynamic[padIt2[m1, 4]]},
{"damping (Kg per sec)",
Manipulator[
Dynamic[c1, {c1 = #; tick = Not[tick]} &], {0, 1000, 1},
ImageSize -> Tiny], Dynamic[padIt2[c1, 4]]},
{"initial angle",
Manipulator[
Dynamic[angle1, {angle1 = #; q1 = angle1*Pi/180.;
state = "STOP"; tick = Not[tick]} &], {0, 360, 1},
ImageSize -> Tiny], Dynamic[angle1]},
{"applied joint torque",
Manipulator[
Dynamic[torque1, {torque1 = #; tick = Not[tick]} &], {-600,
600, 1},
ImageSize -> Tiny], Dynamic[padIt1[torque1, 3]], Spacer[2],
Button[Text@Style["zero", 10], {torque1 = 0;
tick = Not[tick]}, ImageSize -> {40, 40}]
, SpanFromLeft}
}, Frame -> True]
}
,
{
Grid[{{"Link 2 properties"},
{"mass (kg)",
Manipulator[
Dynamic[m2, {m2 = #; tick = Not[tick]} &], {1, 100, 1},
ImageSize -> Tiny], Dynamic[padIt2[m2, 4]]},
{"damping (Kg per sec)",
Manipulator[
Dynamic[c2, {c2 = #; tick = Not[tick]} &], {0, 1000, 1},
ImageSize -> Tiny], Dynamic[padIt2[c2, 4]]},
{"initial angle",
Manipulator[
Dynamic[angle2, {angle2 = #; q2 = angle2*Pi/180.;
state = "STOP"; tick = Not[tick]} &], {0, 165, 1},
ImageSize -> Tiny], Dynamic[angle2]},
{"applied joint torque",
Manipulator[Dynamic[torque2, {torque2 = #;
tick = Not[tick]} &], {-600, 600, 1},
ImageSize -> Tiny], Dynamic[padIt1[torque2, 3]], Spacer[2],
Button[Text@Style["zero", 10], {torque2 = 0;
tick = Not[tick]}, ImageSize -> {40, 40}],
SpanFromLeft}
}, Frame -> True]
},
{
Grid[{{"Link 3 properties"},
{"mass (kg)",
Manipulator[
Dynamic[m3, {m3 = #; tick = Not[tick]} &], {1, 100, 1},
ImageSize -> Tiny], Dynamic[padIt2[m3, 4]]},
{"damping (Kg per sec)",
Manipulator[
Dynamic[c3, {c3 = #; tick = Not[tick]} &], {0, 1000, 1},
ImageSize -> Tiny], Dynamic[padIt2[c3, 4]]},
{"initial angle", Manipulator[Dynamic[angle3, {angle3 = #;
q3 = angle3*Pi/180.; state = "STOP";
tick = Not[tick]} &], {-75, 75, 1},
ImageSize -> Tiny], Dynamic[angle3]},
{"applied joint torque",
Manipulator[
Dynamic[torque3, {torque3 = #; tick = Not[tick]} &], {-600,
600, 1},
ImageSize -> Tiny], Dynamic[padIt1[torque3, 3]], Spacer[2],
Button[Text@Style["zero", 10], {torque3 = 0;
tick = Not[tick]}, ImageSize -> {40, 40}], SpanFromLeft}
}, Frame -> True]
},
{
Grid[{{"simulation speed",
Manipulator[
Dynamic[delT, {delT = #; tick = Not[tick]} &], {0.001,
0.05, .001},
ImageSize -> Tiny], Dynamic[padIt2[delT, {2, 2}]]
}}]
}
}, Frame -> True, Alignment -> Center, Spacings -> {1, 1}
], 14],
{{g, 0}, None},(*graphics*)
{{state, "STOP"}, None},
{{ct, 0}, None},
{{q1, 45 Degree}, None},
{{q2, 45 Degree}, None},
{{q3, 45 Degree}, None},
{{dq1, 0.5}, None},
{{dq2, 0.5}, None},
{{dq3, 0.5}, None},
{{delT, 0.02}, None},
{{angle1, 45}, None},
{{angle2, 45}, None},
{{angle3, 45}, None},
{{m1, 100}, None},
{{m2, 100}, None},
{{m3, 100}, None},
{{c1, 10}, None},
{{c2, 1}, None},
{{c3, 1}, None},
{{zoom, 10}, None},
{{torque1, 0}, None},
{{torque2, 0}, None},
{{torque3, 0}, None},
{{tick, False}, None},
{{vEnd, {0, 0, 0}}, None},
TrackedSymbols :> {tick},
SynchronousUpdating -> False,
(*DisplayAllSteps\[Rule]True,*)
ControlPlacement -> Left,
Initialization :>
(
integerStrictPositive = (IntegerQ[#] && # > 0 &);
integerPositive = (IntegerQ[#] && # >= 0 &);
numericStrictPositive = (Element[#, Reals] && # > 0 &);
numericPositive = (Element[#, Reals] && # >= 0 &);
numericStrictNegative = (Element[#, Reals] && # < 0 &);
numericNegative = (Element[#, Reals] && # <= 0 &);
bool = (Element[#, Booleans] &);
numeric = (Element[#, Reals] &);
integer = (Element[#, Integers] &);
padIt1[v_?numeric, f_List] :=
AccountingForm[v, f, NumberSigns -> {"-", "+"},
NumberPadding -> {"0", "0"}, SignPadding -> True];
padIt1[v_?numeric, f_Integer] :=
AccountingForm[Chop[v], f, NumberSigns -> {"-", "+"},
NumberPadding -> {"0", "0"}, SignPadding -> True];
padIt2[v_?numeric, f_List] :=
AccountingForm[v, f, NumberSigns -> {"", ""},
NumberPadding -> {"0", "0"}, SignPadding -> True];
padIt2[v_?numeric, f_Integer] :=
AccountingForm[Chop[v], f, NumberSigns -> {"", ""},
NumberPadding -> {"0", "0"}, SignPadding -> True];
zDot[{q1_, q2_, q3_, qd1_, qd2_, qd3_}, c1_, c2_, c3_, m1_, m2_,
m3_, L1_, L2_, L3_, r1_, r2_, r3_, torque1_, torque2_,
torque3_] := Module[{D0, B0, C0, G0, friction, qdd},
D0 =
getMassMatrix[q1, q2, q3, c1, c2, c3, m1, m2, m3, L1, L2, L3,
r1, r2, r3];
B0 =
getB[q1, q2, q3, c1, c2, c3, m1, m2, m3, L1, L2, L3, r1, r2, r3];
C0 =
getC[q1, q2, q3, c1, c2, c3, m1, m2, m3, L1, L2, L3, r1, r2, r3];
G0 =
getG[q1, q2, q3, c1, c2, c3, m1, m2, m3, L1, L2, L3, r1, r2, r3];
friction = {c1*qd1, c2*qd2, c3*qd3};
qdd =
Inverse[D0].(-B0.{qd1*qd2, qd1*qd3, qd2*qd3} -
C0.{qd1^2, qd2^2, qd3^2} - G0 -
friction + {torque1, torque2, torque3});
Flatten@{qd1, qd2, qd3, qdd}
];
getMassMatrix[q1_, q2_, q3_, c1_, c2_, c3_, m1_, m2_, m3_, L1_,
L2_, L3_, r1_, r2_, r3_] :=
{{(1/24)*(4*L2^2*m2 + 12*L2^2*m3 + 4*L3^2*m3 + 12*m1*r1^2 +
9*m2*r2^2 +
9*m3*r3^2 + (4*L2^2*(m2 + 3*m3) - 3*m2*r2^2)*Cos[2*q2] +
12*L2*L3*m3*Cos[q3] +
4*L3^2*m3*Cos[2*(q2 + q3)] -
3*m3*r3^2*Cos[2*(q2 + q3)] + 12*L2*L3*m3*Cos[2*q2 + q3]), 0,
0},
{0, (1/12)*(4*L3^2*m3 + 4*L2^2*(m2 + 3*m3) + 3*m2*r2^2 +
3*m3*r3^2) + L2*L3*m3*Cos[q3], (1/12)*
m3*(4*L3^2 + 3*r3^2 + 6*L2*L3*Cos[q3])},
{0, (1/12)*m3*(4*L3^2 + 3*r3^2 + 6*L2*L3*Cos[q3]), (1/12)*
m3*(4*L3^2 + 3*r3^2)}};
getB[q1_, q2_, q3_, c1_, c2_, c3_, m1_, m2_, m3_, L1_, L2_, L3_,
r1_, r2_, r3_] :=
{{(1/12)*((-4*L2^2*(m2 + 3*m3) + 3*m2*r2^2)*Sin[2*q2] +
m3*((-4*L3^2 + 3*r3^2)*Sin[2*(q2 + q3)] -
12*L2*L3*Sin[2*q2 + q3])),
(-(1/6))*
m3*(6*L2*L3*Cos[q2] + (4*L3^2 - 3*r3^2)*Cos[q2 + q3])*
Sin[q2 + q3], 0}, {0, 0, (-L2)*L3*m3*Sin[q3]}, {0, 0, 0}};
getC[q1_, q2_, q3_, c1_, c2_, c3_, m1_, m2_, m3_, L1_, L2_, L3_,
r1_, r2_, r3_] :=
{{0, 0,
0}, {(1/24)*((4*L2^2*(m2 + 3*m3) - 3*m2*r2^2)*Sin[2*q2] +
m3*((4*L3^2 - 3*r3^2)*Sin[2*(q2 + q3)] +
12*L2*L3*Sin[2*q2 + q3])), 0,
(-(1/2))*L2*L3*m3*Sin[q3]}, {(1/12)*
m3*(6*L2*L3*Cos[q2] + (4*L3^2 - 3*r3^2)*Cos[q2 + q3])*
Sin[q2 + q3], (1/2)*L2*L3*m3*Sin[q3], 0}};
getG[q1_, q2_, q3_, c1_, c2_, c3_, m1_, m2_, m3_, L1_, L2_, L3_,
r1_, r2_, r3_] :=
{0, (1/2)*9.8*(L2*(m2 + 2*m3)*Cos[q2] + L3*m3*Cos[q2 + q3]), (1/
2)*9.8*L3*m3*Cos[q2 + q3]};
getV3[L1_, L2_, L3_, x1_, x2_, x3_, v1_, v2_,
v3_] := {-(L2 Cos[x2] + L3 Cos[x2 + x3]) Sin[x1] v1 -
Cos[x1] ((L2 Sin[x2] + L3 Sin[x2 + x3]) v2 +
L3 Sin[x2 + x3] v3),
Cos[x1] (L2 Cos[x2] + L3 Cos[x2 + x3]) v1 -
Sin[x1] ((L2 Sin[x2] + L3 Sin[x2 + x3]) v2 +
L3 Sin[x2 + x3] v3), (L2 Cos[x2] + L3 Cos[x2 + x3]) v2 +
L3 Cos[x2 + x3] v3};
o02[x1_, x2_, x3_, L1_, L2_, L3_] := {L2 Cos[x1] Cos[x2],
L2 Cos[x2] Sin[x1], L1 + L2 Sin[x2]};
o03[x1_, x2_, x3_, L1_, L2_,
L3_] := {L2 Cos[x1] Cos[x2] + L3 Cos[x1] Cos[x2] Cos[x3] -
L3 Cos[x1] Sin[x2] Sin[x3],
L2 Cos[x2] Sin[x1] + L3 Cos[x2] Cos[x3] Sin[x1] -
L3 Sin[x1] Sin[x2] Sin[x3],
L1 + L2 Sin[x2] + L3 Cos[x3] Sin[x2] + L3 Cos[x2] Sin[x3]};
typeOne[r_, {x_, y_, z_}, L0_, flag_, upper_] := Module[{},
(*flag says to add a cylinder at bottom,
upper is a flag to say to add a cylinder at top*)
{Cuboid[{x - r/2, y - r/2, z}, {x + r/2, y + r/2, z + L0}],
If[upper,
(*left and right cylinders*)
{
Cylinder[{{x - 0.5 r, y, z + L0 + 0.3 r}, {x - 0.4 r, y,
z + L0 + 0.3 r}}, .6 r],
Cylinder[{{x + 0.4 r, y, z + L0 + 0.3 r}, {x + 0.5 r, y,
z + L0 + 0.3 r}}, .6 r],
(*inner one*)
Cylinder[{{x - .8 r, y, z + L0 + 0.3 r}, {x + 0.8 r, y,
L0 + z + .3 r}}, .1 r]
}
,
{
Cuboid[{x - 0.5, y - r/2, z + L0}, {x - 0.4 r, y + r/2,
z + L0 + r}],
Cuboid[{x + 0.4, y - r/2, z + L0}, {x + 0.5 r, y + r/2,
z + L0 + r}]
}
],
If[flag,
Cylinder[{{x - .6 r, y, z}, {x + 0.6 r, y, z}}, .5 r], ## &[]]
}
];
)
]