roboticstoolbox-python 1.4.2__py3-none-any.whl → 1.4.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -293,36 +293,21 @@ class IKSolver(ABC):
293
293
  linalg_error = 0
294
294
 
295
295
  # Initialise variables
296
- E = 0.0
296
+ E = np.inf
297
297
  q = q0[0]
298
298
 
299
299
  for search in range(self.slimit):
300
300
  q = q0[search].copy()
301
301
  i = 0
302
302
 
303
- while i < self.ilimit:
304
- i += 1
305
-
306
- # step() reports E for q as it was *before* this iteration's
307
- # update. An undamped update (GN/NR) can overshoot, so if E is
308
- # already below tol we must return this pre-step q, not the
309
- # mutated one step() hands back - otherwise we can report
310
- # success with a q whose actual residual is far above tol.
311
- q_prev = q.copy()
312
-
313
- # Attempt a step
314
- try:
315
- E, q[ets.jindices] = self.step(ets, Tep, q)
316
-
317
- except np.linalg.LinAlgError:
318
- # Abandon search and try again
319
- linalg_error += 1
320
- break
303
+ # Check the initial configuration before attempting an update.
304
+ # An exact or already-converged q0 must not enter a solver step,
305
+ # which can be singular even though the requested pose is solved.
306
+ _, E = self.error(ets.eval(q), Tep)
321
307
 
322
- # Check if we have arrived
308
+ while True:
309
+ # Check convergence for the current q before another update.
323
310
  if E < self.tol:
324
- q = q_prev
325
-
326
311
  # Wrap q to be within +- 180 deg
327
312
  # If your robot has larger than 180 deg range on a joint
328
313
  # this line should be modified in incorporate the extra range
@@ -344,6 +329,21 @@ class IKSolver(ABC):
344
329
  residual=E,
345
330
  reason="Success",
346
331
  )
332
+
333
+ if i >= self.ilimit:
334
+ break
335
+
336
+ i += 1
337
+
338
+ # Attempt a step. step() reports E for the updated q.
339
+ try:
340
+ E, q[ets.jindices] = self.step(ets, Tep, q)
341
+
342
+ except np.linalg.LinAlgError:
343
+ # Abandon search and try again
344
+ linalg_error += 1
345
+ break
346
+
347
347
  total_i += i
348
348
 
349
349
  # If we make it here, then we have failed
@@ -709,6 +709,7 @@ class IK_NR(IKSolver):
709
709
  else:
710
710
  q[ets.jindices] += np.linalg.inv(J) @ e + qnull
711
711
 
712
+ _, E = self.error(ets.eval(q), Tep)
712
713
  return E, q[ets.jindices]
713
714
 
714
715
 
@@ -941,6 +942,7 @@ class IK_LM(IKSolver):
941
942
 
942
943
  q[ets.jindices] += np.linalg.inv(J.T @ self.We @ J + Wn) @ g + qnull
943
944
 
945
+ _, E = self.error(ets.eval(q), Tep)
944
946
  return E, q[ets.jindices]
945
947
 
946
948
 
@@ -1121,6 +1123,7 @@ class IK_GN(IKSolver):
1121
1123
  else:
1122
1124
  q[ets.jindices] += np.linalg.inv(J) @ e + qnull
1123
1125
 
1126
+ _, E = self.error(ets.eval(q), Tep)
1124
1127
  return E, q[ets.jindices]
1125
1128
 
1126
1129
 
@@ -1388,6 +1391,7 @@ class IK_QP(IKSolver):
1388
1391
 
1389
1392
  q += xd[: ets.n]
1390
1393
 
1394
+ _, E = self.error(ets.eval(q), Tep)
1391
1395
  return E, q
1392
1396
 
1393
1397
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: roboticstoolbox-python
3
- Version: 1.4.2
3
+ Version: 1.4.3
4
4
  Summary: A Python library for robotics education and research
5
5
  Keywords: python,robotics,robotics-toolbox,kinematics,dynamics,motion-planning,trajectory-generation,jacobian,hessian,control,simulation,robot-manipulator,mobile-robot
6
6
  Author-Email: Jesse Haviland <j.haviland@qut.edu.au>, Peter Corke <rvc@petercorke.com>
@@ -584,82 +584,3 @@ K. He, R. Newbury, T. Tran, J. Haviland, B. Burgess-Limerick, D. Kulić, P. Cork
584
584
  <img src="https://raw.githubusercontent.com/petercorke/robotics-toolbox-python/main/docs/figs/mmc_youtube.png" width="560">
585
585
  </a>
586
586
  </p>
587
-
588
- <br>
589
-
590
- ## Build a JupyterLite/Pyodide Wasm wheel
591
-
592
- [Pyodide](https://pyodide.org/) is a full CPython distribution compiled to
593
- WebAssembly, which is what lets the "Try it Now" JupyterLite deployment above
594
- run this toolbox entirely client-side, no server required. Each Pyodide
595
- release embeds one specific CPython version, and a wasm wheel is tagged with
596
- the CPython version it was built for (`cp312`, `cp313`, ...) -— a wheel only
597
- loads if its tag matches the CPython embedded in the Pyodide runtime actually
598
- running. JupyterLite doesn't bundle Pyodide directly either: the
599
- `jupyterlite-pyodide-kernel` package pulls in a specific Pyodide version per
600
- its own release, so bumping that one package can silently change which wheel
601
- tag your deployment now needs -— this is the single sharpest edge in this
602
- whole pipeline. This repo's live deployment currently pins
603
- `jupyterlite-pyodide-kernel==0.6.1` (see `.github/workflows/ci.yml`), which
604
- embeds Pyodide 0.27.6 / CPython 3.12 — hence `cp312` below.
605
-
606
- Also note Pyodide's own version numbering changed in 2026: releases up to
607
- `0.29.x` used an independent `0.x` scheme, but from Pyodide `314.0.0` onward
608
- the version number tracks the embedded CPython version directly (`314` =
609
- Python 3.14). "Current" no longer means a `0.x` version.
610
-
611
- ### Use the published wheel (recommended)
612
-
613
- PyPI rejects the `pyodide_*` platform tag, so Wasm wheels can't be published
614
- there -— instead, every GitHub release attaches ready-built wheels (for each
615
- supported CPython version) as release assets. Download the one matching your
616
- deployment's CPython version, e.g.:
617
-
618
- ```shell script
619
- gh release download --repo petercorke/robotics-toolbox-python --pattern '*cp312*pyodide*'
620
- ```
621
-
622
- This is exactly what `ci.yml`'s `docs-build` job does to populate the live
623
- "Try it Now" site — most people should do this rather than building locally.
624
-
625
- ### Build locally
626
-
627
- Only needed to test an unreleased change, or to target a different
628
- CPython/Pyodide pin than the current release. Uses cibuildwheel's Pyodide
629
- platform:
630
-
631
- ```shell script
632
- make wheel-pyodide
633
- ```
634
-
635
- Optionally pin the Pyodide runtime to match a different JupyterLite
636
- deployment than this project's own:
637
-
638
- ```shell script
639
- PYODIDE_VERSION=0.27.6 make wheel-pyodide
640
- ```
641
-
642
- The target writes to `dist/` and runs `make wheel-pyodide-check`, which validates
643
- the wheel filename contains:
644
-
645
- - `cp312-cp312`
646
- - `wasm32`
647
- - `pyemscripten_<major>_<minor>` or `pyodide_<major>_<minor>`
648
-
649
- To inspect the produced artifact path:
650
-
651
- ```shell script
652
- ls -1 dist/*wasm32*.whl
653
- ```
654
-
655
- ### References
656
-
657
- - [Pyodide release notes](https://github.com/pyodide/pyodide/releases) —
658
- confirms what CPython version a given Pyodide tag embeds, including the
659
- 2026 versioning-scheme change.
660
- - [jupyterlite-pyodide-kernel changelog](https://github.com/jupyterlite/pyodide-kernel/blob/main/CHANGELOG.md) —
661
- the authoritative source for which Pyodide version a given kernel package
662
- release bundles.
663
- - [cibuildwheel Pyodide platform docs](https://cibuildwheel.pypa.io/en/stable/platforms/#pyodide-webassembly).
664
-
665
- <br>
@@ -571,7 +571,7 @@ roboticstoolbox/robot/Dynamics.py,sha256=iCplz4L1wT2OeXuS0acO9x8h4uxsifT67PV4TVi
571
571
  roboticstoolbox/robot/ELink.py,sha256=sgA-1c-U0Gz6TxABSJvfauq2L0Wu_1_pGJVKfLgrGP8,525
572
572
  roboticstoolbox/robot/ERobot.py,sha256=aUnSg91PwHyIHO6ipWtnNBNLYCftKGIxgYz1qX8wghg,567
573
573
  roboticstoolbox/robot/Gripper.py,sha256=CYyXFBYbEp52-RX-b6xGWS3EH-Y2BsYdtaR8Q0yAm3s,6954
574
- roboticstoolbox/robot/IK.py,sha256=eCov1k7ks-pJUj71_SwJKK61-fzgZS7XEdNHw7lj9qU,48380
574
+ roboticstoolbox/robot/IK.py,sha256=7CzondLtnZdETFJPC4MczdDz46Ar3n83OvJnMBauV6I,48515
575
575
  roboticstoolbox/robot/Link.py,sha256=m98nfpv61C5Z1GDrOV_iN6gxyh9qj8URwiju9ssKXxw,46283
576
576
  roboticstoolbox/robot/PoERobot.py,sha256=mByMjb3P5FrW3Z8zyLS5waYcKBy8lpHG44g2uBUyB70,11053
577
577
  roboticstoolbox/robot/Robot.py,sha256=-5SsVItMPKAd56lxPQrXlHHbdpMn-GMKGCUy73LeELw,78647
@@ -604,8 +604,8 @@ roboticstoolbox/tools/urdf/tests/data/ur5.urdf,sha256=9g0uYkRHRsWHWl6vn5lIK_JMHq
604
604
  roboticstoolbox/tools/urdf/tests/test_urdf.py,sha256=MoRP8DolFu7RXxrKkwEWJOSfVygX7UJwEv-hLZkdlKw,3445
605
605
  roboticstoolbox/tools/urdf/urdf.py,sha256=IE5EUSNjkOAZZUOkuhXKDhYRq2AuJGulIvfbsRHy7pI,58743
606
606
  roboticstoolbox/tools/urdf/utils.py,sha256=6g1uuI2u7CUaWhKavI7wDHT3a2T3ijb92JByQ1lNq6w,1483
607
- roboticstoolbox_python-1.4.2.dist-info/METADATA,sha256=lzbE1kRVqtmFbbmNyf8YsAcKWgF0gCN4Oa8jc9NiNfg,30215
608
- roboticstoolbox_python-1.4.2.dist-info/WHEEL,sha256=DJBbB-IMWy7eyPvSdm5L2t-BbrULtweJWf0YC-blkl0,95
609
- roboticstoolbox_python-1.4.2.dist-info/entry_points.txt,sha256=m9xEI6rJsYQL0HosyeS-4TUPzxOR3kqx4vbJVVxwo7k,214
610
- roboticstoolbox_python-1.4.2.dist-info/licenses/LICENSE,sha256=oXNGHTPcMKl8PPZWk_4NIWGAtiaQcTgVJ1hpnTcnKFA,1062
611
- roboticstoolbox_python-1.4.2.dist-info/RECORD,,
607
+ roboticstoolbox_python-1.4.3.dist-info/METADATA,sha256=5GYwYgEhenEQBNgrQtYgHuCprlkow1AIfxbxq_xNczE,27162
608
+ roboticstoolbox_python-1.4.3.dist-info/WHEEL,sha256=DJBbB-IMWy7eyPvSdm5L2t-BbrULtweJWf0YC-blkl0,95
609
+ roboticstoolbox_python-1.4.3.dist-info/entry_points.txt,sha256=m9xEI6rJsYQL0HosyeS-4TUPzxOR3kqx4vbJVVxwo7k,214
610
+ roboticstoolbox_python-1.4.3.dist-info/licenses/LICENSE,sha256=oXNGHTPcMKl8PPZWk_4NIWGAtiaQcTgVJ1hpnTcnKFA,1062
611
+ roboticstoolbox_python-1.4.3.dist-info/RECORD,,