@@ -1107,14 +1107,18 @@ def __mul__(
11071107 Twist3 scalar Twist3 element-wise product
11081108 scalar Twist3 Twist3 element-wise product
11091109 Twist3 SE3 Twist3 exponential x SE3
1110+ Twist3 SpatialVector SpatialVector adjoint/coadjoint product
11101111 ======== ==================== =================== ========================
11111112
11121113 .. note::
11131114
11141115 #. scalar x Twist is handled by ``__rmul__``
11151116 #. scalar multiplication is commutative but the result is not a group
11161117 operation so the result will be a matrix
1117- #. Any other input combinations result in a ValueError.
1118+ #. ``Twist3 * SpatialVector`` (velocity, acceleration, force, momentum)
1119+ is handled by falling back to
1120+ :meth:`~spatialmath.spatialvector.SpatialVector.__rmul__`.
1121+ #. Any other input combination raises a ``TypeError``.
11181122
11191123 For pose composition the ``left`` and ``right`` operands may be a sequence
11201124
@@ -1147,7 +1151,11 @@ def __mul__(
11471151 # return Twist(left.S * right)
11481152 return Twist3 (left .binop (right , lambda x , y : x * y ))
11491153 else :
1150- raise ValueError ("twist *, incorrect right operand" )
1154+ # not a type we handle directly -- return NotImplemented so Python
1155+ # falls back to right.__rmul__(left), which SpatialVector (velocity,
1156+ # acceleration, force, momentum) defines. If right has no __rmul__
1157+ # either, Python raises its own TypeError.
1158+ return NotImplemented
11511159
11521160 def __rmul__ (
11531161 right , left
0 commit comments