Skip to content

Commit 0265bbd

Browse files
committed
Merge upstream main for operational acceleration validation
2 parents eeb4a73 + 879fb36 commit 0265bbd

27 files changed

Lines changed: 634 additions & 127 deletions

‎.github/workflows/docs.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
3636
- name: Install docs dependencies
3737
run: |
38-
pip install .[docs]
38+
pip install .[docs,qp] # qp for the IK_QP examples
3939
pip install sympy python-flint # for the analytic IK examples
4040
sudo apt-get install -y graphviz
4141

‎.github/workflows/release.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ jobs:
108108
- uses: actions/checkout@v7
109109

110110
- name: Build wheels
111-
uses: pypa/cibuildwheel@e090b81e30c4d855ea63bf4b6e59204c09a101ae # v4.2.1
111+
uses: pypa/cibuildwheel@f9b966cfadf4109556cadc5bb39ddb72d0ce664e # v4.3.5
112112
- uses: actions/upload-artifact@v7
113113
with:
114114
name: wheels-${{ matrix.os }}-${{ strategy.job-index }}

‎docs/lite/wasm_check/check_pyodide_install.mjs‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,27 @@ class _Matplotlib:
104104
module.matplotlib = _Matplotlib()
105105
106106
frames = []
107-
module._ipy_display = lambda frame, display_id=None: frames.append(frame.data)
107+
widgets = []
108+
109+
def _display(frame, display_id=None):
110+
# an inline frame is an image; a widget figure is displayed as its canvas
111+
if hasattr(frame, "data"):
112+
frames.append(frame.data)
113+
else:
114+
widgets.append(frame)
115+
116+
module._ipy_display = _display
108117
module._ipy_clear_output = lambda wait=False: None
109118
110119
robot = rtb.models.DH.Puma560()
111120
env = robot.plot(rtb.jtraj(robot.qz, robot.qn, 8).q, dt=0.0)
112121
assert env.render_mode == "notebook-inline", env.render_mode
113122
assert len(set(frames)) >= 8, f"{len(set(frames))} different frames pushed for 8 steps"
114-
assert robot.plot(robot.qn).render_mode == "notebook-widget"
123+
assert not widgets, "an animation displayed a widget"
124+
static = robot.plot(robot.qn)
125+
assert static.render_mode == "notebook-widget"
126+
# a static plot is one live figure, displayed once and not before it is drawn
127+
assert widgets == [static.fig.canvas], f"{len(widgets)} widgets displayed"
115128
print(f"plot of a trajectory: {env.render_mode}, {len(set(frames))} different frames")
116129
print("import roboticstoolbox: OK")
117130
`;

‎docs/notebooks/_rtb_nb_bootstrap.py‎

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,35 @@ async def ensure_installed(extras: tuple[str, ...] | list[str] = ()) -> bool:
7070
requirement = "roboticstoolbox-python"
7171
if extras:
7272
requirement += "[" + ",".join(extras) + "]"
73+
# Colab does not ship ipympl, which the notebooks select with
74+
# %matplotlib ipympl; matplotlib rejects the backend if it is missing.
7375
subprocess.run(
74-
[sys.executable, "-m", "pip", "install", "-q", requirement],
76+
[sys.executable, "-m", "pip", "install", "-q", requirement, "ipympl"],
7577
check=True,
7678
)
79+
# matplotlib renames the module://ipympl... backend to "widget", and looks
80+
# it up in a list of backends that it builds once, from the installed
81+
# packages, the first time it needs it. Colab imported matplotlib before
82+
# ipympl was installed, so %matplotlib ipympl is rejected ("... is not a
83+
# valid value for backend") until the session restarts. Make matplotlib
84+
# build the list again. Clearing the registry is what its own tests do,
85+
# and it is needed: only resetting the flag registers the backends that
86+
# were already there (matplotlib-inline's) twice, which is an error.
87+
# _clear is private, hence the guards.
88+
try:
89+
from matplotlib.backends import backend_registry
90+
except ImportError:
91+
pass # an older matplotlib has no registry to refresh
92+
else:
93+
clear = getattr(backend_registry, "_clear", None)
94+
if clear is not None:
95+
clear()
96+
97+
# ipympl figures need Colab's custom widget manager, enabled before the
98+
# first figure is created.
99+
from google.colab import output
100+
101+
output.enable_custom_widget_manager()
77102
where, colab = "on Colab", True
78103

79104
import roboticstoolbox

‎docs/notebooks/branched-robot.ipynb‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"<table>\n",
99
" <tr>\n",
1010
" <td><div align=\"left\"><font size=\"30\">Working with branched robots</font></div></td>\n",
11-
" <td><img src=\"https://github.com/petercorke/robotics-toolbox-python/raw/main/docs/notebooks/figs/RobToolBox_RoundLogoB.png?raw=1\" width=\"300\"></td>\n",
11+
" <td><img src=\"https://github.com/petercorke/robotics-toolbox-python/raw/main/docs/notebooks/figs/RobToolBox_RoundLogoB.png?raw=1\" width=\"200\" height=\"201\"></td>\n",
1212
" </tr>\n",
1313
"</table>\n",
1414
"\n",
@@ -66,7 +66,17 @@
6666
" requirement = 'roboticstoolbox-python'\n",
6767
" if extras:\n",
6868
" requirement += '[' + ','.join(extras) + ']'\n",
69-
" subprocess.run([sys.executable, '-m', 'pip', 'install', '-q', requirement], check=True)\n",
69+
" subprocess.run([sys.executable, '-m', 'pip', 'install', '-q', requirement, 'ipympl'], check=True)\n",
70+
" try:\n",
71+
" from matplotlib.backends import backend_registry\n",
72+
" except ImportError:\n",
73+
" pass\n",
74+
" else:\n",
75+
" clear = getattr(backend_registry, '_clear', None)\n",
76+
" if clear is not None:\n",
77+
" clear()\n",
78+
" from google.colab import output\n",
79+
" output.enable_custom_widget_manager()\n",
7080
" where, colab = ('on Colab', True)\n",
7181
" import roboticstoolbox\n",
7282
" version = getattr(roboticstoolbox, '__version__', 'unknown')\n",

‎docs/notebooks/dynamics.ipynb‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"<table>\n",
99
" <tr>\n",
1010
" <td><div align=\"left\"><font size=\"30\">Robot dynamics</font></div></td>\n",
11-
" <td><img src=\"https://github.com/petercorke/robotics-toolbox-python/raw/main/docs/notebooks/figs/RobToolBox_RoundLogoB.png?raw=1\" width=\"300\"></td>\n",
11+
" <td><img src=\"https://github.com/petercorke/robotics-toolbox-python/raw/main/docs/notebooks/figs/RobToolBox_RoundLogoB.png?raw=1\" width=\"200\" height=\"201\"></td>\n",
1212
" </tr>\n",
1313
"</table>\n",
1414
"\n",
@@ -65,7 +65,17 @@
6565
" requirement = 'roboticstoolbox-python'\n",
6666
" if extras:\n",
6767
" requirement += '[' + ','.join(extras) + ']'\n",
68-
" subprocess.run([sys.executable, '-m', 'pip', 'install', '-q', requirement], check=True)\n",
68+
" subprocess.run([sys.executable, '-m', 'pip', 'install', '-q', requirement, 'ipympl'], check=True)\n",
69+
" try:\n",
70+
" from matplotlib.backends import backend_registry\n",
71+
" except ImportError:\n",
72+
" pass\n",
73+
" else:\n",
74+
" clear = getattr(backend_registry, '_clear', None)\n",
75+
" if clear is not None:\n",
76+
" clear()\n",
77+
" from google.colab import output\n",
78+
" output.enable_custom_widget_manager()\n",
6979
" where, colab = ('on Colab', True)\n",
7080
" import roboticstoolbox\n",
7181
" version = getattr(roboticstoolbox, '__version__', 'unknown')\n",

‎docs/notebooks/ets.ipynb‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"<table>\n",
99
" <tr>\n",
1010
" <td><div align=\"left\"><font size=\"30\">Elementary transform sequences</font></div></td>\n",
11-
" <td><img src=\"https://github.com/petercorke/robotics-toolbox-python/raw/main/docs/notebooks/figs/RobToolBox_RoundLogoB.png?raw=1\" width=\"300\"></td>\n",
11+
" <td><img src=\"https://github.com/petercorke/robotics-toolbox-python/raw/main/docs/notebooks/figs/RobToolBox_RoundLogoB.png?raw=1\" width=\"200\" height=\"201\"></td>\n",
1212
" </tr>\n",
1313
"</table>\n",
1414
"\n",
@@ -67,7 +67,17 @@
6767
" requirement = 'roboticstoolbox-python'\n",
6868
" if extras:\n",
6969
" requirement += '[' + ','.join(extras) + ']'\n",
70-
" subprocess.run([sys.executable, '-m', 'pip', 'install', '-q', requirement], check=True)\n",
70+
" subprocess.run([sys.executable, '-m', 'pip', 'install', '-q', requirement, 'ipympl'], check=True)\n",
71+
" try:\n",
72+
" from matplotlib.backends import backend_registry\n",
73+
" except ImportError:\n",
74+
" pass\n",
75+
" else:\n",
76+
" clear = getattr(backend_registry, '_clear', None)\n",
77+
" if clear is not None:\n",
78+
" clear()\n",
79+
" from google.colab import output\n",
80+
" output.enable_custom_widget_manager()\n",
7181
" where, colab = ('on Colab', True)\n",
7282
" import roboticstoolbox\n",
7383
" version = getattr(roboticstoolbox, '__version__', 'unknown')\n",

‎docs/notebooks/graphics-test.ipynb‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"<table>\n",
99
" <tr>\n",
1010
" <td><div align=\"left\"><font size=\"30\">Graphics tests</font></div></td>\n",
11-
" <td><img src=\"https://github.com/petercorke/robotics-toolbox-python/raw/main/docs/notebooks/figs/RobToolBox_RoundLogoB.png?raw=1\" width=\"300\"></td>\n",
11+
" <td><img src=\"https://github.com/petercorke/robotics-toolbox-python/raw/main/docs/notebooks/figs/RobToolBox_RoundLogoB.png?raw=1\" width=\"200\" height=\"201\"></td>\n",
1212
" </tr>\n",
1313
"</table>\n",
1414
"\n",
@@ -64,7 +64,17 @@
6464
" requirement = 'roboticstoolbox-python'\n",
6565
" if extras:\n",
6666
" requirement += '[' + ','.join(extras) + ']'\n",
67-
" subprocess.run([sys.executable, '-m', 'pip', 'install', '-q', requirement], check=True)\n",
67+
" subprocess.run([sys.executable, '-m', 'pip', 'install', '-q', requirement, 'ipympl'], check=True)\n",
68+
" try:\n",
69+
" from matplotlib.backends import backend_registry\n",
70+
" except ImportError:\n",
71+
" pass\n",
72+
" else:\n",
73+
" clear = getattr(backend_registry, '_clear', None)\n",
74+
" if clear is not None:\n",
75+
" clear()\n",
76+
" from google.colab import output\n",
77+
" output.enable_custom_widget_manager()\n",
6878
" where, colab = ('on Colab', True)\n",
6979
" import roboticstoolbox\n",
7080
" version = getattr(roboticstoolbox, '__version__', 'unknown')\n",

‎docs/notebooks/icra2021.ipynb‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"<table>\n",
99
" <tr>\n",
1010
" <td><div align=\"left\"><font size=\"30\">Not your grandmother’s toolbox</font></div></td>\n",
11-
" <td><img src=\"https://github.com/petercorke/robotics-toolbox-python/raw/main/docs/notebooks/figs/RobToolBox_RoundLogoB.png?raw=1\" width=\"300\"></td>\n",
11+
" <td><img src=\"https://github.com/petercorke/robotics-toolbox-python/raw/main/docs/notebooks/figs/RobToolBox_RoundLogoB.png?raw=1\" width=\"200\" height=\"201\"></td>\n",
1212
" </tr>\n",
1313
"</table>\n",
1414
"\n",
@@ -68,7 +68,17 @@
6868
" requirement = 'roboticstoolbox-python'\n",
6969
" if extras:\n",
7070
" requirement += '[' + ','.join(extras) + ']'\n",
71-
" subprocess.run([sys.executable, '-m', 'pip', 'install', '-q', requirement], check=True)\n",
71+
" subprocess.run([sys.executable, '-m', 'pip', 'install', '-q', requirement, 'ipympl'], check=True)\n",
72+
" try:\n",
73+
" from matplotlib.backends import backend_registry\n",
74+
" except ImportError:\n",
75+
" pass\n",
76+
" else:\n",
77+
" clear = getattr(backend_registry, '_clear', None)\n",
78+
" if clear is not None:\n",
79+
" clear()\n",
80+
" from google.colab import output\n",
81+
" output.enable_custom_widget_manager()\n",
7282
" where, colab = ('on Colab', True)\n",
7383
" import roboticstoolbox\n",
7484
" version = getattr(roboticstoolbox, '__version__', 'unknown')\n",

‎docs/notebooks/icra2026.ipynb‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"<table>\n",
99
" <tr>\n",
1010
" <td><div align=\"left\"><font size=\"30\">Robotics Toolbox for Python</font></div></td>\n",
11-
" <td><img src=\"https://github.com/petercorke/robotics-toolbox-python/raw/main/docs/notebooks/figs/RobToolBox_RoundLogoB.png?raw=1\" width=\"300\"></td>\n",
11+
" <td><img src=\"https://github.com/petercorke/robotics-toolbox-python/raw/main/docs/notebooks/figs/RobToolBox_RoundLogoB.png?raw=1\" width=\"200\" height=\"201\"></td>\n",
1212
" </tr>\n",
1313
"</table>\n",
1414
"\n",
@@ -66,7 +66,17 @@
6666
" requirement = 'roboticstoolbox-python'\n",
6767
" if extras:\n",
6868
" requirement += '[' + ','.join(extras) + ']'\n",
69-
" subprocess.run([sys.executable, '-m', 'pip', 'install', '-q', requirement], check=True)\n",
69+
" subprocess.run([sys.executable, '-m', 'pip', 'install', '-q', requirement, 'ipympl'], check=True)\n",
70+
" try:\n",
71+
" from matplotlib.backends import backend_registry\n",
72+
" except ImportError:\n",
73+
" pass\n",
74+
" else:\n",
75+
" clear = getattr(backend_registry, '_clear', None)\n",
76+
" if clear is not None:\n",
77+
" clear()\n",
78+
" from google.colab import output\n",
79+
" output.enable_custom_widget_manager()\n",
7080
" where, colab = ('on Colab', True)\n",
7181
" import roboticstoolbox\n",
7282
" version = getattr(roboticstoolbox, '__version__', 'unknown')\n",

0 commit comments

Comments
 (0)