Skip to content

Commit 31f8ecc

Browse files
committed
Update 01_Stewart_Py_Inverse_Kinematics.ipynb
1 parent c65bdf8 commit 31f8ecc

File tree

1 file changed

+19
-19
lines changed

1 file changed

+19
-19
lines changed

01_Stewart_Py_Inverse_Kinematics.ipynb

+19-19
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@
55
"metadata": {},
66
"source": [
77
"\n",
8-
"[<img align=\"right\" src='./doc/jupyter_nb/Hexapod_general_Anim.gif' width=\"10%\" height=\"10%\">](./doc/jupyter_nb/Hexapod_general_Anim.gif)\n",
8+
"[<img align=\"right\" src=\"./doc/jupyter_nb/Hexapod_general_Anim.gif\" width=\"10%\" height=\"10%\">](./doc/jupyter_nb/Hexapod_general_Anim.gif)\n",
99
" \n",
1010
"## Using Stewart Platform as a tool to understand key robotic concepts\n",
1111
"\n",
1212
"The most basic configuration of Stewart Platforms uses 6 legs, each connecting the **base** to the **platform**. They are arranged in 3 pairs, connected with universal joints and actuated linearly. The locations where the legs connect to the base and platforms are called **anchors**.\n",
1313
"\n",
1414
"In this tutorial you will learn to solve the inverse kinematics of stewart platforms with (1) **linear actuators** (left), then (2) **rotational actuators** (right).\n",
1515
"\n",
16-
"[<img src=\".\\doc\\jupyter_nb\\plot_linear.png\" width=\"40%\" height=\"40%\">](.\\doc\\jupyter_nb\\plot_linear.png)\n",
17-
"[<img src=\".\\doc\\jupyter_nb\\plot_rotational.png\" width=\"40%\" height=\"40%\">](.\\doc\\jupyter_nb\\plot_rotational.png)\n",
16+
"[<img src=\"./doc/jupyter_nb/plot_linear.png\" width=\"40%\" height=\"40%\">](./doc/jupyter_nb/plot_linear.png)\n",
17+
"[<img src=\"./doc/jupyter_nb/plot_rotational.png\" width=\"40%\" height=\"40%\">](./doc/jupyter_nb/plot_rotational.png)\n",
1818
"\n",
1919
"\n",
2020
"#### Base and Platform Anchors \n",
@@ -33,7 +33,7 @@
3333
"\n",
3434
"Given $r_B$ and $r_P$, we can define $B \\in \\R ^{6 \\times 3}$ and $P \\in \\R ^{6 \\times 3}$ which are the coordinates of the anchors in their respective local frames in cartesian space. For example, the anchor points on the base, B are illustrated below:\n",
3535
"\n",
36-
"[<img src=\".\\doc\\jupyter_nb\\base_kinematic_1.png\" width=\"50%\" height=\"50%\">](.\\doc\\jupyter_nb\\base_kinematic_1.png)\n"
36+
"[<img src=\"./doc/jupyter_nb/base_kinematic_1.png\" width=\"50%\" height=\"50%\">](./doc/jupyter_nb/base_kinematic_1.png)\n"
3737
]
3838
},
3939
{
@@ -168,7 +168,7 @@
168168
"\n",
169169
"We also need to define the rotation matrices following the standard notation\n",
170170
"\n",
171-
"[<img src=\".\\doc\\jupyter_nb\\rotation_matrices.png\">](.\\doc\\jupyter_nb\\rotation_matrices.png)\n"
171+
"[<img src=\"./doc/jupyter_nb/rotation_matrices.png\">](./doc/jupyter_nb/rotation_matrices.png)\n"
172172
]
173173
},
174174
{
@@ -222,18 +222,18 @@
222222
"Since the role of each leg is to connect the anchor on the base to the anchor on the platform, the desired vector for each leg (direction and length) is simply the leg's position in 3D space with reference to their respective base anchor\n",
223223
"\n",
224224
"\n",
225-
"[<img src=\".\\doc\\jupyter_nb\\leg_math.png\" width=\"80%\" height=\"80%\">](.\\doc\\jupyter_nb\\leg_math.png)\n",
225+
"[<img src=\"./doc/jupyter_nb/leg_math.png\" width=\"80%\" height=\"80%\">](./doc/jupyter_nb/leg_math.png)\n",
226226
"\n",
227227
"\n",
228228
"Where $T$ and $H$ are in $\\R ^ {3 \\times 1}$ replicated 6 times to have dimensions $\\R ^ {3 \\times 6}$ to facilitate matrix calculations\n",
229229
"\n",
230230
"This can be understood as \n",
231231
"\n",
232-
"[<img src=\".\\doc\\jupyter_nb\\leg_maths.png\" width=\"80%\" height=\"80%\">](.\\doc\\jupyter_nb\\leg_maths.png)\n",
232+
"[<img src=\"./doc/jupyter_nb/leg_maths.png\" width=\"80%\" height=\"80%\">](./doc/jupyter_nb/leg_maths.png)\n",
233233
"\n",
234234
"The length of a leg is simply the magnitude of the leg vector \n",
235235
"\n",
236-
"[<img src=\".\\doc\\jupyter_nb\\leg_length_mag.png\" width=\"80%\" height=\"80%\">](.\\doc\\jupyter_nb\\leg_length_mag.png)\n",
236+
"[<img src=\"./doc/jupyter_nb/leg_length_mag.png\" width=\"80%\" height=\"80%\">](./doc/jupyter_nb/leg_length_mag.png)\n",
237237
"\n",
238238
"\n",
239239
"\n",
@@ -242,7 +242,7 @@
242242
"And that's all to solve for the inverse kinematics of stewart platforms when using linear actuators. Mad simple.\n",
243243
"\n",
244244
"\n",
245-
"[<img src=\".\\doc\\jupyter_nb\\legs_only_pseudocode.png\" width=\"80%\" height=\"80%\">](.\\doc\\jupyter_nb\\legs_only_pseudocode.png)\n"
245+
"[<img src=\"./doc/jupyter_nb/legs_only_pseudocode.png\" width=\"80%\" height=\"80%\">](./doc/jupyter_nb/legs_only_pseudocode.png)\n"
246246
]
247247
},
248248
{
@@ -287,7 +287,7 @@
287287
"\n",
288288
"You should see an interactive plot like this pop out on a separate window\n",
289289
"\n",
290-
"[<img src=\".\\doc\\jupyter_nb\\plot_linear.png\" width=\"30%\" height=\"30%\">](.\\doc\\jupyter_nb\\plot_linear.png)\n",
290+
"[<img src=\"./doc/jupyter_nb/plot_linear.png\" width=\"30%\" height=\"30%\">](./doc/jupyter_nb/plot_linear.png)\n",
291291
"\n"
292292
]
293293
},
@@ -333,23 +333,23 @@
333333
"\n",
334334
"What if instead of linear motors, we are to use rotational servos? To do this we replace the leg of a linear actuator with a rotating servo horn and a rod. From this we can work out a (considerably more complex) analytical solution as follows. \n",
335335
"\n",
336-
"[<img src=\".\\doc\\jupyter_nb\\rod_kinematics_1.png\" width=\"90%\" height=\"90%\">](.\\doc\\jupyter_nb\\rod_kinematics_1.png)\n",
336+
"[<img src=\"./doc/jupyter_nb/rod_kinematics_1.png\" width=\"90%\" height=\"90%\">](./doc/jupyter_nb/rod_kinematics_1.png)\n",
337337
"\n",
338338
"The most obvious variable is $H_k$. It is simply $h_k$ translated by $B_k$ to the global reference frame; whereas $h_k$ is simply the servo arm of length |h| lying on the x axis, rotated by $\\beta_k$ offset in the z axis, then rotated by desired angle $\\alpha_k$ by the y axis. Note: standard notation of rotation matrices follows a right-hand-rule convention for rotation, hence in the diagram, when we are rotating the servos 'upwards, we are rotating $-\\alpha_k$. Here's a post that helped me understand [link](https://robotics.stackexchange.com/questions/10702/rotation-matrix-sign-convention-confusion)\n",
339339
"\n",
340-
"[<img src=\".\\doc\\jupyter_nb\\rod_kinematics_2.png\" width=\"80%\" height=\"80%\">](.\\doc\\jupyter_nb\\rod_kinematics_2.png)\n",
340+
"[<img src=\"./doc/jupyter_nb/rod_kinematics_2.png\" width=\"80%\" height=\"80%\">](./doc/jupyter_nb/rod_kinematics_2.png)\n",
341341
"\n",
342342
"From here we can solve the system of equations of consisting of the magnitude of each of these variables in question \n",
343343
"\n",
344-
"[<img src=\".\\doc\\jupyter_nb\\rod_kinematics_3.png\" width=\"80%\" height=\"80%\">](.\\doc\\jupyter_nb\\rod_kinematics_3.png)\n",
344+
"[<img src=\"./doc/jupyter_nb/rod_kinematics_3.png\" width=\"80%\" height=\"80%\">](./doc/jupyter_nb/rod_kinematics_3.png)\n",
345345
"\n",
346-
"[<img src=\".\\doc\\jupyter_nb\\rod_kinematics_4.png\" width=\"80%\" height=\"80%\">](.\\doc\\jupyter_nb\\rod_kinematics_4.png)\n",
346+
"[<img src=\"./doc/jupyter_nb/rod_kinematics_4.png\" width=\"80%\" height=\"80%\">](./doc/jupyter_nb/rod_kinematics_4.png)\n",
347347
"\n",
348348
"Converting the vector into the form of an equation, we can simplify the variables into three variables, g, e and f. These three variables are not dependent on $\\alpha_k$. The remaining terms can be simplified using trigonometric identity $e \\cdot \\sin \\varphi+f \\cdot \\cos \\varphi=\\sqrt{e^{2}+f^{2}} \\sin (\\varphi+\\operatorname{atan} 2(f, e))$\n",
349349
"\n",
350-
"[<img src=\".\\doc\\jupyter_nb\\rod_kinematics_5.png\" width=\"80%\" height=\"80%\">](.\\doc\\jupyter_nb\\rod_kinematics_5.png)\n",
350+
"[<img src=\"./doc/jupyter_nb/rod_kinematics_5.png\" width=\"80%\" height=\"80%\">](./doc/jupyter_nb/rod_kinematics_5.png)\n",
351351
"\n",
352-
"[<img src=\".\\doc\\jupyter_nb\\rod_kinematics_6.png\" width=\"80%\" height=\"80%\">](.\\doc\\jupyter_nb\\rod_kinematics_6.png)\n",
352+
"[<img src=\"./doc/jupyter_nb/rod_kinematics_6.png\" width=\"80%\" height=\"80%\">](./doc/jupyter_nb/rod_kinematics_6.png)\n",
353353
"\n",
354354
"and that is it. The final equation the solved inverse kinematic solution"
355355
]
@@ -369,7 +369,7 @@
369369
"beta - angle between xz plane and the servo arms. \n",
370370
"Inspired by hbartle's stewart platform implementation, we don't declare the orientations of the servo shafts, but directly define the offset angles of the servo shafts, when looking at the platform from above. \n",
371371
"\n",
372-
"[<img src=\".\\doc\\jupyter_nb\\beta_visualized.png\" width=\"60%\" height=\"60%\">](.\\doc\\jupyter_nb\\beta_visualized.png)\n"
372+
"[<img src=\"./doc/jupyter_nb/beta_visualized.png\" width=\"60%\" height=\"60%\">](./doc/jupyter_nb/beta_visualized.png)\n"
373373
]
374374
},
375375
{
@@ -413,7 +413,7 @@
413413
"Black lines: Rods, d\n",
414414
"\n",
415415
"\n",
416-
"[<img src=\".\\doc\\jupyter_nb\\plot_rotational.png\" width=\"30%\" height=\"30%\">](.\\doc\\jupyter_nb\\plot_rotational.png)\n",
416+
"[<img src=\"./doc/jupyter_nb/plot_rotational.png\" width=\"30%\" height=\"30%\">](./doc/jupyter_nb/plot_rotational.png)\n",
417417
"\n",
418418
"\n"
419419
]
@@ -497,7 +497,7 @@
497497
"\n",
498498
"In the next part we learn how to write a standard controller in order to utilize the outputs of this inverse kinematic solver in a stable and reasonable manner. It can be found this same github repo. \n",
499499
"\n",
500-
"[<img src=\".\\doc\\jupyter_nb\\servo_horn_pseudocode.png\" width=\"80%\" height=\"80%\">](.\\doc\\jupyter_nb\\servo_horn_pseudocode.png)\n",
500+
"[<img src=\"./doc/jupyter_nb/servo_horn_pseudocode.png\" width=\"80%\" height=\"80%\">](./doc/jupyter_nb/servo_horn_pseudocode.png)\n",
501501
"\n",
502502
"\n",
503503
"#### Credits\n",

0 commit comments

Comments
 (0)