From 8d78b276a9fee4ca0c7a756cbe18464e054f08c9 Mon Sep 17 00:00:00 2001 From: Peter Corke Date: Mon, 19 Oct 2026 18:22:01 +1000 Subject: [PATCH] fix(robot): qlim and printing work for a robot with symbolic parameters Co-Authored-By: Claude Sonnet 5.5 --- src/roboticstoolbox/robot/BaseRobot.py | 10 ++++------ tests/test_symbolic_qlim.py | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 tests/test_symbolic_qlim.py diff --git a/src/roboticstoolbox/robot/BaseRobot.py b/src/roboticstoolbox/robot/BaseRobot.py index f1bf12a7c..21ca93846 100644 --- a/src/roboticstoolbox/robot/BaseRobot.py +++ b/src/roboticstoolbox/robot/BaseRobot.py @@ -1017,14 +1017,12 @@ def qlim(self) -> NDArray: for link in self.links: if link.isrevolute: - if ( - link.qlim is None - or link.qlim[0] is None - or np.any(np.isnan(link.qlim)) - ): + # a symbolic model holds SymPy numbers, which np.isnan rejects + qlim = None if link.qlim is None else np.asarray(link.qlim, dtype=float) + if qlim is None or np.any(np.isnan(qlim)): v = [-np.pi, np.pi] else: - v = link.qlim + v = qlim elif link.isprismatic: if link.qlim is None: raise ValueError("Undefined prismatic joint limit") diff --git a/tests/test_symbolic_qlim.py b/tests/test_symbolic_qlim.py new file mode 100644 index 000000000..a46d9caa2 --- /dev/null +++ b/tests/test_symbolic_qlim.py @@ -0,0 +1,25 @@ +"""The joint limits and the display of a robot with symbolic parameters.""" + +import numpy as np +import numpy.testing as nt + +import roboticstoolbox as rtb + + +def test_symbolic_robot_qlim(): + robot = rtb.models.DH.Puma560(symbolic=True) + numeric = rtb.models.DH.Puma560() + + nt.assert_allclose(robot.qlim, numeric.qlim) + + +def test_symbolic_robot_can_be_printed(): + robot = rtb.models.DH.Puma560(symbolic=True) + + assert "DHRobot" in str(robot) + + +def test_unset_revolute_limits_are_the_default(): + robot = rtb.DHRobot([rtb.RevoluteDH(a=1.0)], name="one") + + nt.assert_allclose(robot.qlim, [[-np.pi], [np.pi]])