Skip to content

Commit 3649899

Browse files
fix: correct lesson heading levels, regenerate unstable, fix AGENTS.md %%capture docs
- Fix heading levels in unstable/lesson2_tutorial.md (## -> ### for intro sections) - Add missing title and fix heading levels in unstable/lesson3_tutorial.md - Add missing title and fix heading levels in unstable/lesson4_tutorial.md - Split massive blob cell in lesson3_tutorial.md into proper paragraphs - Remove --break-system-packages from all notebooks and md files - Correct AGENTS.md: %%capture IS supported in MyST (cites IPython docs) Co-authored-by: openhands <openhands@all-hands.dev>
1 parent 10fb422 commit 3649899

13 files changed

Lines changed: 271 additions & 31 deletions

AGENTS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ This script:
9393

9494
### MyST Compatibility Notes
9595

96-
- **`%%capture` magic is not supported** in MyST text notebooks. The converter may produce cells containing `%%capture` (a Jupyter magic that suppresses output). These must be removed manually from the generated `.md` files, as MyST does not support this magic and the cell will fail to execute.
97-
- After regenerating with `convert_to_myst.py`, check all unstable `.md` files for `%%capture` and remove those lines.
96+
- **`%%capture` magic IS supported** in MyST text notebooks. MyST uses a Jupyter Server with an IPython kernel to execute code cells ([Execute Notebooks at Build Time](https://mystmd.org/guide/execute-notebooks)). The `%%capture` magic is a built-in IPython cell magic ([Built-in magic commands — IPython](https://ipython.readthedocs.io/en/stable/interactive/magics.html)) and works correctly during MyST execution.
97+
- If output suppression is needed without `%%capture`, the MyST-native approach is to use cell tags like `remove-stdout` and `remove-stderr` on the `{code-cell}` directive.
9898

9999
---
100100

basic_lessons/lesson1_tutorial.ipynb

Lines changed: 127 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -447,8 +447,7 @@
447447
"outputs": [],
448448
"source": [
449449
"%%capture\n",
450-
"%pip install numpy \n",
451-
"%pip install numpy --break-system-packages"
450+
"%pip install numpy \n"
452451
]
453452
},
454453
{
@@ -1021,7 +1020,69 @@
10211020
"cell_type": "code",
10221021
"outputs": [],
10231022
"execution_count": null,
1024-
"source": "e1 = None # Replace None with your solution to this exercise."
1023+
"source": [
1024+
"e",
1025+
"1",
1026+
" ",
1027+
"=",
1028+
" ",
1029+
"N",
1030+
"o",
1031+
"n",
1032+
"e",
1033+
" ",
1034+
"#",
1035+
" ",
1036+
"R",
1037+
"e",
1038+
"p",
1039+
"l",
1040+
"a",
1041+
"c",
1042+
"e",
1043+
" ",
1044+
"N",
1045+
"o",
1046+
"n",
1047+
"e",
1048+
" ",
1049+
"w",
1050+
"i",
1051+
"t",
1052+
"h",
1053+
" ",
1054+
"y",
1055+
"o",
1056+
"u",
1057+
"r",
1058+
" ",
1059+
"s",
1060+
"o",
1061+
"l",
1062+
"u",
1063+
"t",
1064+
"i",
1065+
"o",
1066+
"n",
1067+
" ",
1068+
"t",
1069+
"o",
1070+
" ",
1071+
"t",
1072+
"h",
1073+
"i",
1074+
"s",
1075+
" ",
1076+
"e",
1077+
"x",
1078+
"e",
1079+
"r",
1080+
"c",
1081+
"i",
1082+
"s",
1083+
"e",
1084+
"."
1085+
]
10251086
},
10261087
{
10271088
"metadata": {},
@@ -1053,7 +1114,69 @@
10531114
"cell_type": "code",
10541115
"outputs": [],
10551116
"execution_count": null,
1056-
"source": "C2 = None # replace None with your solution to this exercise."
1117+
"source": [
1118+
"C",
1119+
"2",
1120+
" ",
1121+
"=",
1122+
" ",
1123+
"N",
1124+
"o",
1125+
"n",
1126+
"e",
1127+
" ",
1128+
"#",
1129+
" ",
1130+
"r",
1131+
"e",
1132+
"p",
1133+
"l",
1134+
"a",
1135+
"c",
1136+
"e",
1137+
" ",
1138+
"N",
1139+
"o",
1140+
"n",
1141+
"e",
1142+
" ",
1143+
"w",
1144+
"i",
1145+
"t",
1146+
"h",
1147+
" ",
1148+
"y",
1149+
"o",
1150+
"u",
1151+
"r",
1152+
" ",
1153+
"s",
1154+
"o",
1155+
"l",
1156+
"u",
1157+
"t",
1158+
"i",
1159+
"o",
1160+
"n",
1161+
" ",
1162+
"t",
1163+
"o",
1164+
" ",
1165+
"t",
1166+
"h",
1167+
"i",
1168+
"s",
1169+
" ",
1170+
"e",
1171+
"x",
1172+
"e",
1173+
"r",
1174+
"c",
1175+
"i",
1176+
"s",
1177+
"e",
1178+
"."
1179+
]
10571180
}
10581181
],
10591182
"metadata": {

basic_lessons/lesson2_tutorial.ipynb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,7 @@
6161
},
6262
"source": [
6363
"%%capture\n",
64-
"%pip install numpy\n",
65-
"%pip install numpy --break-system-packages"
64+
"%pip install numpy\n"
6665
],
6766
"outputs": [],
6867
"execution_count": 11

basic_lessons/lesson3_tutorial.ipynb

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@
4646
"metadata": {},
4747
"source": [
4848
"%%capture\n",
49-
"%pip install numpy\n",
50-
"%pip install numpy --break-system-packages"
49+
"%pip install numpy\n"
5150
],
5251
"outputs": [],
5352
"execution_count": null
@@ -399,7 +398,74 @@
399398
{
400399
"metadata": {},
401400
"cell_type": "code",
402-
"source": "H_C0_C3 = None # Replace None with your solution to this exercise.",
401+
"source": [
402+
"H",
403+
"_",
404+
"C",
405+
"0",
406+
"_",
407+
"C",
408+
"3",
409+
" ",
410+
"=",
411+
" ",
412+
"N",
413+
"o",
414+
"n",
415+
"e",
416+
" ",
417+
"#",
418+
" ",
419+
"R",
420+
"e",
421+
"p",
422+
"l",
423+
"a",
424+
"c",
425+
"e",
426+
" ",
427+
"N",
428+
"o",
429+
"n",
430+
"e",
431+
" ",
432+
"w",
433+
"i",
434+
"t",
435+
"h",
436+
" ",
437+
"y",
438+
"o",
439+
"u",
440+
"r",
441+
" ",
442+
"s",
443+
"o",
444+
"l",
445+
"u",
446+
"t",
447+
"i",
448+
"o",
449+
"n",
450+
" ",
451+
"t",
452+
"o",
453+
" ",
454+
"t",
455+
"h",
456+
"i",
457+
"s",
458+
" ",
459+
"e",
460+
"x",
461+
"e",
462+
"r",
463+
"c",
464+
"i",
465+
"s",
466+
"e",
467+
"."
468+
],
403469
"outputs": [],
404470
"execution_count": null
405471
},

basic_lessons/lesson4_tutorial.ipynb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@
5151
},
5252
"source": [
5353
"%%capture\n",
54-
"%pip install numpy\n",
55-
"%pip install numpy --break-system-packages"
54+
"%pip install numpy\n"
5655
],
5756
"outputs": [],
5857
"execution_count": 1

basic_lessons/lesson5_exercise_answers.ipynb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,7 @@
4747
},
4848
"source": [
4949
"%%capture\n",
50-
"%pip install numpy matplotlib\n",
51-
"%pip install numpy matplotlib --break-system-packages"
50+
"%pip install numpy matplotlib\n"
5251
],
5352
"outputs": [],
5453
"execution_count": 10

basic_lessons/lesson5_tutorial.ipynb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@
4848
"outputs": [],
4949
"source": [
5050
"%%capture\n",
51-
"%pip install numpy matplotlib\n",
52-
"%pip install numpy matplotlib --break-system-packages"
51+
"%pip install numpy matplotlib\n"
5352
]
5453
},
5554
{

unstable/lesson1_tutorial.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,6 @@ Just in case `numpy` is not already installed, we can install it with the follow
184184

185185
````{code-cell}
186186
%pip install numpy
187-
%pip install numpy --break-system-packages
188187
````
189188

190189
### Importing the library

unstable/lesson2_tutorial.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,19 @@ kernelspec:
1010

1111
*Author: Murilo M. Marinho (murilo.marinho@manchester.ac.uk)*
1212

13-
## Prerequisites for the learner
13+
### Prerequisites for the learner
1414
The user of this notebook is expected to have prior knowledge in
1515
- All the content and prerequisites of lesson 1.
1616

17-
## I found an issue
17+
### I found an issue
1818
Thank you! Please report it at https://github.com/MarinhoLab/OpenExecutableBooksRobotics/issues
1919

20-
## Latex Macros
20+
### Latex Macros
2121

2222
# Installing prerequisites
2323

2424
````{code-cell}
2525
%pip install numpy
26-
%pip install numpy --break-system-packages
2726
````
2827

2928
# Imports

unstable/lesson3_tutorial.md

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,68 @@ kernelspec:
44
display_name: 'Python 3'
55
---
66

7-
# Prerequisites
7+
# L3 Forward Kinematics
8+
9+
*License: CC-BY-NC-SA 4.0*
10+
11+
*Author: Murilo M. Marinho (murilo.marinho@manchester.ac.uk)*
12+
13+
### Prerequisites for the learner
14+
The user of this notebook is expected to have prior knowledge in
15+
- All the content and prerequisites of lessons 1 and 2.
16+
17+
### I found an issue
18+
Thank you! Please report it at https://github.com/MarinhoLab/OpenExecutableBooksRobotics/issues
19+
20+
## Prerequisites
821

922
````{code-cell}
1023
%pip install numpy
11-
%pip install numpy --break-system-packages
1224
````
1325

14-
# Imports
26+
## Imports
1527

1628
````{code-cell}
1729
import numpy as np
1830
from math import pi, sin, cos
1931
````
2032

21-
# Forward Kinematics Model (FKM)The forward kinematics model of a rigid serial-link manipulator is obtained through a sequence of transformations.The only real challenge in obtaining the FKM is understanding from a diagram, or a real robot, what transformations represent the robot and in what order they happen.Anyway, we can start with an example. As always, remember that angles are in radians and lengths are in meters.![Lesson4.png](Lesson4.png)Consider the 2-DoF planar robot shown in the figure. It is classed as an RR robot, because the two joints are revolute.Let $q_0\triangleq q_0(t) \in \mathbb{R}$ and $q_1\triangleq q_1(t) \in \mathbb{R}$ compose its configuration space. In addition, let $l_{0} \in \mathbb{R}$ and $l_{1} \in \mathbb{R}$ be the geometric parameters, which are quantities that cannot be controlled.The configuration space is what is used in practice to control the robot. You as the system designer will send configuration space values $q_0$ and $q_1$, or other signals related to those, to command the robot. You will make it move to perform a relevant task and hopefully earn your next month's salary. The parameters $l_{0}$ and $l_{1}$ are constant in time and represent time-invariant geometrical aspects of the robot, such as link lengths, that you cannot control.As a representative task for robotic manipulators, let us use the configuration space and geometric parameters to calculate the pose of the frame of the tip of the robot. This is represented mathematically as follows.$$\mymatrix{H}^{0}_{2}( q_0, l_{0},q_1,l_{1}) \in SE(2).$$The equation for the end-effector (tip) pose is what is called the forward kinematics model (FKM). We need this frequently when using a robotic manipulator because the end effector is likely to be its most useful part. For instance, it could be a gripper that is used to pick and place objects. To pick or place an object, the robot needs to move somewhere.The first step towards moving somewhere is knowing where you are. Thence, the first step towards controlling a robotic manipulator's end effector pose in any meaningful way is to obtain its FKM.## Understanding the problemThe FKM is a mathematical description of the robot. Before we attempt any programming, we have to mathematically describe the sequential transformations that represent the robot being modelled.As shown in the figure, there are four transformations for this robot, taking us from the base, $\mathcal{F}_0$, to the end-effector, $\mathcal{F}_2$. The sequence can be summarised as follows.1. A rotation of $q_0$ about the current frame, from $\mathcal{F}_0$ to $\mathcal{F}_{0'}$.2. A translation of $l_0$ along the $x$-axis of the current frame, from $\mathcal{F}_{0'}$ to $\mathcal{F}_{1}$.3. A rotation of $q_1$ about the current frame, from $\mathcal{F}_{1}$ to $\mathcal{F}_{1'}$.4. A translation of $l_1$ along the $x$-axis of the current frame, from $\mathcal{F}_{1'}$ to $\mathcal{F}_{2}$.### 1. From $\mathcal{F}_0$ to $\mathcal{F}_{0'}$We start with the rotation that can be described by the following homogeneous transformation matrix.$$\myvec H_{0'}^{0}\left(q_0\right) =\begin{bmatrix} \cos(q_0) & -\sin(q_0) & 0\\\sin(q_0) & \cos(q_0) & 0\\0 & 0 & 1\end{bmatrix}.$$Programmatically, supposing that $q_0 = \frac{\pi}{4}$, we arrive at the following piece of code.
33+
# Forward Kinematics Model (FKM)
34+
35+
The forward kinematics model of a rigid serial-link manipulator is obtained through a sequence of transformations.
36+
The only real challenge in obtaining the FKM is understanding from a diagram, or a real robot, what transformations represent the robot and in what order they happen.
37+
Anyway, we can start with an example. As always, remember that angles are in radians and lengths are in meters.
38+
39+
![Lesson4.png](Lesson4.png)
40+
41+
Consider the 2-DoF planar robot shown in the figure. It is classed as an RR robot, because the two joints are revolute.
42+
Let $q_0\triangleq q_0(t) \in \mathbb{R}$ and $q_1\triangleq q_1(t) \in \mathbb{R}$ compose its configuration space. In addition, let $l_{0} \in \mathbb{R}$ and $l_{1} \in \mathbb{R}$ be the geometric parameters, which are quantities that cannot be controlled.
43+
The configuration space is what is used in practice to control the robot. You as the system designer will send configuration space values $q_0$ and $q_1$, or other signals related to those, to command the robot. You will make it move to perform a relevant task and hopefully earn your next month's salary. The parameters $l_{0}$ and $l_{1}$ are constant in time and represent time-invariant geometrical aspects of the robot, such as link lengths, that you cannot control.
44+
45+
As a representative task for robotic manipulators, let us use the configuration space and geometric parameters to calculate the pose of the frame of the tip of the robot. This is represented mathematically as follows.
46+
47+
$$\mymatrix{H}^{0}_{2}( q_0, l_{0},q_1,l_{1}) \in SE(2).$$
48+
49+
The equation for the end-effector (tip) pose is what is called the forward kinematics model (FKM). We need this frequently when using a robotic manipulator because the end effector is likely to be its most useful part. For instance, it could be a gripper that is used to pick and place objects. To pick or place an object, the robot needs to move somewhere.
50+
The first step towards moving somewhere is knowing where you are. Thence, the first step towards controlling a robotic manipulator's end effector pose in any meaningful way is to obtain its FKM.
51+
52+
## Understanding the problem
53+
54+
The FKM is a mathematical description of the robot. Before we attempt any programming, we have to mathematically describe the sequential transformations that represent the robot being modelled.
55+
As shown in the figure, there are four transformations for this robot, taking us from the base, $\mathcal{F}_0$, to the end-effector, $\mathcal{F}_2$. The sequence can be summarised as follows.
56+
57+
1. A rotation of $q_0$ about the current frame, from $\mathcal{F}_0$ to $\mathcal{F}_{0'}$.
58+
2. A translation of $l_0$ along the $x$-axis of the current frame, from $\mathcal{F}_{0'}$ to $\mathcal{F}_{1}$.
59+
3. A rotation of $q_1$ about the current frame, from $\mathcal{F}_{1}$ to $\mathcal{F}_{1'}$.
60+
4. A translation of $l_1$ along the $x$-axis of the current frame, from $\mathcal{F}_{1'}$ to $\mathcal{F}_{2}$.
61+
62+
### 1. From $\mathcal{F}_0$ to $\mathcal{F}_{0'}$
63+
64+
We start with the rotation that can be described by the following homogeneous transformation matrix.
65+
66+
$$\myvec H_{0'}^{0}\left(q_0\right) =\begin{bmatrix} \cos(q_0) & -\sin(q_0) & 0\\\sin(q_0) & \cos(q_0) & 0\\0 & 0 & 1\end{bmatrix}.$$
67+
68+
Programmatically, supposing that $q_0 = \frac{\pi}{4}$, we arrive at the following piece of code.
2269

2370
````{code-cell}
2471
H_0_0p = np.array(

0 commit comments

Comments
 (0)