Skip to content

Commit e778eb6

Browse files
petercorkeclaude
andauthored
docs(notebooks): modernise two-link-dynamics.ipynb, including the sign convention of gravity (#853)
Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
1 parent 2d8abf1 commit e778eb6

1 file changed

Lines changed: 38 additions & 31 deletions

File tree

‎docs/notebooks/two-link-dynamics.ipynb‎

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,29 @@
44
"cell_type": "markdown",
55
"metadata": {},
66
"source": [
7-
"# Dynamics of 2-link manipulator\n",
7+
"<!-- RTB_HEADER -- generated from the notebook metadata (rtb_header) by sync_bootstrap.py, do not hand-edit -->\n",
8+
"<table>\n",
9+
" <tr>\n",
10+
" <td><div align=\"left\"><font size=\"30\">Robotics Toolbox for Python</font></div></td>\n",
11+
" <td><img src=\"figs/RobToolBox_RoundLogoB.png\" width=\"300\"></td>\n",
12+
" </tr>\n",
13+
"</table>\n",
814
"\n",
15+
"<p></p>\n",
16+
"<div align=\"center\" style=\"font-size: 1.5em;\">Dynamics of a 2-link manipulator</div>\n",
17+
"<p></p>\n",
18+
"\n",
19+
"(c) Peter Corke 2026\n",
20+
"\n",
21+
"The gravity and velocity torques of the two-link planar arm in Spong, Hutchinson and Vidyasagar, computed by the Toolbox from a DH model and from an ETS model, and compared with the analytic Euler-Lagrange equations.\n",
22+
"\n",
23+
"> **Modernised 2026-10-19** to address API drift: this notebook was written for an earlier release of the Toolbox, and has been updated so that it runs with the current one."
24+
]
25+
},
26+
{
27+
"cell_type": "markdown",
28+
"metadata": {},
29+
"source": [
930
"![Spong book](figs/spong-2link.png)\n",
1031
"\n",
1132
"Reference:\n",
@@ -75,7 +96,7 @@
7596
"metadata": {},
7697
"outputs": [],
7798
"source": [
78-
"from roboticstoolbox import DHRobot, RevoluteDH, ERobot, ELink, ETS\n",
99+
"from roboticstoolbox import DHRobot, RevoluteDH, Robot, Link, ET\n",
79100
"from math import pi, sin, cos\n",
80101
"import numpy as np\n",
81102
"\n",
@@ -119,14 +140,14 @@
119140
"source": [
120141
"L1 = RevoluteDH(a=l1, m=m1, r=[-lc1, 0, 0])\n",
121142
"L2 = RevoluteDH(a=l2, m=m2, r=[-lc2, 0, 0])\n",
122-
"robot = DHRobot([L1, L2], gravity=[0, g, 0])"
143+
"robot = DHRobot([L1, L2], gravity=[0, -g, 0])"
123144
]
124145
},
125146
{
126147
"cell_type": "markdown",
127148
"metadata": {},
128149
"source": [
129-
"The DH notation only allows rotation about the z-axis, which is out of the page in the Figure above. Gravity acts downward so we set the gravity acceleration to be `[0, g, 0]` - accelerating upward at `g` provides the weight force experienced on Earth."
150+
"The DH notation only allows rotation about the z-axis, which is out of the page in the Figure above. The `gravity` argument is the acceleration due to gravity, a vector in the world frame. Gravity acts downward, in the $-y$ direction of the figure, so we set it to `[0, -g, 0]` (the default is `[0, 0, -9.81]`). The gravity load is the torque the joints must exert to hold the arm still against gravity, so it is positive for an arm stretched out horizontally."
130151
]
131152
},
132153
{
@@ -136,7 +157,7 @@
136157
"outputs": [],
137158
"source": [
138159
"print(robot)\n",
139-
"print(robot.dyntable())"
160+
"print(robot.dynamics())"
140161
]
141162
},
142163
{
@@ -268,7 +289,7 @@
268289
"\n",
269290
"L1 = RevoluteDH(a=l1, m=m1, r=[-lc1, 0, 0])\n",
270291
"L2 = RevoluteDH(a=l2, m=m2, r=[-lc2, 0, 0])\n",
271-
"robot = DHRobot([L1, L2], gravity=[0, g, 0], symbolic=True)\n",
292+
"robot = DHRobot([L1, L2], gravity=[0, -g, 0], symbolic=True)\n",
272293
"\n",
273294
"\n",
274295
"q = symbol(\"q_:2\")\n",
@@ -280,7 +301,7 @@
280301
"cell_type": "markdown",
281302
"metadata": {},
282303
"source": [
283-
"## ERobot notation"
304+
"## ETS notation"
284305
]
285306
},
286307
{
@@ -324,9 +345,9 @@
324345
"metadata": {},
325346
"outputs": [],
326347
"source": [
327-
"L1 = ELink(ets=ETS.rz(), m=1, r=[0.5, 0, 0], name=\"L1\")\n",
328-
"L2 = ELink(ets=ETS.tx(1) * ETS.rz(), m=1, r=[0.5, 0, 0], parent=L1, name=\"L2\")\n",
329-
"robot = ERobot([L1, L2], gravity=[0, g, 0])"
348+
"L1 = Link(ets=ET.Rz(), m=1, r=[0.5, 0, 0], name=\"L1\")\n",
349+
"L2 = Link(ets=ET.tx(1) * ET.Rz(), m=1, r=[0.5, 0, 0], parent=L1, name=\"L2\")\n",
350+
"robot = Robot([L1, L2], gravity=[0, -g, 0])"
330351
]
331352
},
332353
{
@@ -340,27 +361,6 @@
340361
" tau_el = EL_grav(q)\n",
341362
" print(tau_rne, \"vs\", tau_el)"
342363
]
343-
},
344-
{
345-
"cell_type": "code",
346-
"execution_count": null,
347-
"metadata": {},
348-
"outputs": [],
349-
"source": []
350-
},
351-
{
352-
"cell_type": "code",
353-
"execution_count": null,
354-
"metadata": {},
355-
"outputs": [],
356-
"source": []
357-
},
358-
{
359-
"cell_type": "code",
360-
"execution_count": null,
361-
"metadata": {},
362-
"outputs": [],
363-
"source": []
364364
}
365365
],
366366
"metadata": {
@@ -409,6 +409,13 @@
409409
"_Feature"
410410
],
411411
"window_display": false
412+
},
413+
"rtb_header": {
414+
"title": "Dynamics of a 2-link manipulator",
415+
"paragraphs": [
416+
"The gravity and velocity torques of the two-link planar arm in Spong, Hutchinson and Vidyasagar, computed by the Toolbox from a DH model and from an ETS model, and compared with the analytic Euler-Lagrange equations."
417+
],
418+
"modernised": "2026-10-19"
412419
}
413420
},
414421
"nbformat": 4,

0 commit comments

Comments
 (0)