From 5251dc02eda0db272c7555a94da7841e3d8d162a Mon Sep 17 00:00:00 2001 From: Peter Corke Date: Sun, 8 Nov 2026 17:17:51 +1100 Subject: [PATCH] fix: FDyn outputs a zero qdd before its first derivative call FDyn.qdd was None until deriv() had run once. bdsim records the type of every block output when it compiles a diagram and checks it at run time, so the first evaluation failed with 'output 2 changed signature: was NoneType, now ndarray'. Start from zeros, as the other dynamics block in this file does. Co-Authored-By: Claude Sonnet 5.5 --- src/roboticstoolbox/blocks/arm.py | 4 ++-- tests/test_blocks.py | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/roboticstoolbox/blocks/arm.py b/src/roboticstoolbox/blocks/arm.py index 9fd26ae1f..a3e7c2284 100644 --- a/src/roboticstoolbox/blocks/arm.py +++ b/src/roboticstoolbox/blocks/arm.py @@ -1463,13 +1463,13 @@ def __init__(self, robot: Any, q0: Any = None, **blockargs: Any) -> None: else: q0 = smb.getvector(q0, robot.n) self._x0 = np.r_[q0, np.zeros((robot.n,))] - self._qdd = None + self._qdd = np.zeros((robot.n,)) # placeholder until the first deriv() def output(self, t: Any, inports: Any, x: Any) -> Any: n = self.robot.n q = x[:n] qd = x[n:] - qdd = self._qdd # from last deriv + qdd = self._qdd # from last deriv(), or the zero placeholder return [q, qd, qdd] def deriv(self, t: Any, inports: Any, x: Any) -> Any: diff --git a/tests/test_blocks.py b/tests/test_blocks.py index 46576cf03..30d48e274 100644 --- a/tests/test_blocks.py +++ b/tests/test_blocks.py @@ -128,6 +128,16 @@ def test_fdyn(self): nt.assert_equal(block.test_output(tau, x=x)[0], q) nt.assert_equal(block.getstate0(), x) + def test_fdyn_qdd_before_deriv(self): + # bdsim records the type of each output when it compiles a diagram, so qdd + # must be an array of the right shape even before the first deriv() call + robot = rtb.models.DH.Puma560() + q = robot.configs["qn"] + block = FDyn(robot, q) + + qdd = block.test_output([0] * 6, x=np.r_[q, np.zeros((6,))])[2] + self.assertEqual(np.shape(qdd), (6,)) + @unittest.skip def test_fdyn_x(self): robot = rtb.models.DH.Puma560()