Skip to content

Commit 1c4ffe6

Browse files
tandedepetercorke
authored andcommitted
fix: compute accel_x with analytical Jacobian derivative
1 parent d243d48 commit 1c4ffe6

2 files changed

Lines changed: 41 additions & 16 deletions

File tree

src/roboticstoolbox/robot/Dynamics.py

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,21 +1256,23 @@ def accel_x(
12561256
:returns: Operational space accelerations of the end-effector
12571257
:rtype: ndarray(6,)
12581258
1259-
``xdd = accel_x(q, qd, wrench)`` is the operational space acceleration
1259+
``xdd = accel_x(q, xd, wrench)`` is the operational space acceleration
12601260
due to ``wrench`` applied to the end-effector of a robot in joint
1261-
configuration ``q`` and joint velocity ``qd``.
1261+
configuration ``q`` and operational space velocity ``xd``.
12621262
12631263
.. math::
12641264
1265-
\ddot{x} = \mathbf{J}(q) \mathbf{M}(q)^{-1} \left(
1266-
\mathbf{J}(q)^T w - \mathbf{C}(q)\dot{q} - \mathbf{g}(q)
1265+
\ddot{x} = \dot{\mathbf{J}}_a(q, \dot{q})\dot{q}
1266+
+ \mathbf{J}_a(q) \mathbf{M}(q)^{-1} \left(
1267+
\mathbf{J}_a(q)^T w - \mathbf{C}(q)\dot{q}
1268+
- \mathbf{g}(q)
12671269
\right)
12681270
12691271
**Trajectory operation**
12701272
1271-
If `q`, `qd`, torque are matrices (m,n) then ``qdd`` is a matrix (m,n)
1272-
where each row is the acceleration corresponding to the equivalent rows
1273-
of q, qd, wrench.
1273+
If ``q`` is a matrix (m,n), and ``xd`` and ``wrench`` are matrices
1274+
(m,6), then ``xdd`` is a matrix (m,6) where each row is the acceleration
1275+
corresponding to the equivalent rows of ``q``, ``xd``, and ``wrench``.
12741276
12751277
.. rubric:: Notes
12761278
@@ -1294,7 +1296,7 @@ def accel_x(
12941296
if q.shape[1] != 6:
12951297
pinv = True
12961298

1297-
xdd = np.zeros((q.shape[0], self.n))
1299+
xdd = np.zeros((q.shape[0], 6))
12981300

12991301
for k, (qk, xdk, wk) in enumerate(zip(q, xd, w)):
13001302
Ja = self.jacob0_analytical(qk, representation=representation)
@@ -1322,16 +1324,10 @@ def accel_x(
13221324

13231325
# xd = Ja qd
13241326
# xdd = Jad qd + Ja qdd
1325-
#
1326-
# Ja = T J
1327-
# Jad = Td J + T Jd
1328-
# assume Td = 0, not sure how valid that is
1329-
1330-
# need Jacobian dot
13311327
qdk = Ji @ xdk
1332-
Jd = self.jacob0_dot(qk, qdk, J0=Ja)
1328+
Jad = self.jacob0_dot(qk, qdk, representation=representation)
13331329

1334-
xdd[k, :] = T @ (Jd @ qdk + J @ qdd)
1330+
xdd[k, :] = Jad @ qdk + Ja @ qdd
13351331

13361332
if q.shape[0] == 1:
13371333
return xdd[0, :]

tests/test_DHRobot.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,35 @@ def test_accel(self):
11381138
nt.assert_array_almost_equal(qdd1[0, :], res, decimal=4)
11391139
nt.assert_array_almost_equal(qdd1[1, :], res, decimal=4)
11401140

1141+
def test_accel_x(self):
1142+
puma = rp.models.DH.Puma560()
1143+
q = np.array([0.2, -0.7, 0.4, 0.3, 0.5, -0.2])
1144+
xd = np.array([0.1, -0.2, 0.15, 0.05, -0.1, 0.2])
1145+
wrench = np.array([1.0, -0.5, 0.25, 0.1, -0.2, 0.3])
1146+
1147+
xdd = puma.accel_x(q, xd, wrench)
1148+
xdd_traj = puma.accel_x(
1149+
np.vstack((q, q)),
1150+
np.vstack((xd, xd)),
1151+
np.vstack((wrench, wrench)),
1152+
)
1153+
1154+
nt.assert_allclose(
1155+
xdd,
1156+
[-1.645157, 4.489468, -4.854711, 3.818259, 6.472284, -2.428306],
1157+
rtol=1e-5,
1158+
atol=1e-6,
1159+
)
1160+
nt.assert_allclose(xdd_traj, np.vstack((xdd, xdd)))
1161+
1162+
def test_accel_x_redundant_robot_returns_cartesian_acceleration(self):
1163+
panda = rp.models.DH.Panda()
1164+
1165+
xdd = panda.accel_x(panda.qr, np.zeros(6), np.zeros(6))
1166+
1167+
self.assertEqual(xdd.shape, (6,))
1168+
self.assertTrue(np.isfinite(xdd).all())
1169+
11411170
def test_inertia(self):
11421171
puma = rp.models.DH.Puma560()
11431172
puma.q = puma.qn

0 commit comments

Comments
 (0)