the trinterp() method does not make sure quaternions are valid before converting them to transforms. It calls qslerp which can sometimes generate invalid quaternions.
Repro:
from spatialmath import SE3
se3_1 = SE3()
se3_1.t = np.array([0.5705748101710814, 0.29623210833184527, 0.10764106509086407])
se3_1.R = np.array([[ 0.2852875203191073 , 0.9581330588259315 ,
-0.024332536551692617],
[ 0.9582072394229962 , -0.28568756930438033 ,
-0.014882844564011068],
[-0.021211248608609852, -0.019069722856395098,
-0.9995931315303468 ]])
assert SE3.isvalid(se3_1.A)
se3_2 = SE3()
se3_2.t = np.array([0.5150284150005691 , 0.25796537207802533, 0.1558725490743694])
se3_2.R = np.array([[ 0.42058255728234184 , 0.9064420651629983 ,
-0.038380919906699236 ],
[ 0.9070822373513454 , -0.4209501599465646 ,
-0.0016665901233428627],
[-0.01766712176680449 , -0.0341137119645545 ,
-0.9992617912561634 ]])
assert SE3.isvalid(se3_2.A)
path_se3 = se3_1.interp(end=se3_2, s=15, shortest=False)
print(path_se3[2])
-> 1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1
print(path_se3[3])
-> 0.3149 0.9487 -0.0275 0.5587
0.9489 -0.3153 -0.01222 0.288
-0.02027 -0.02225 -0.9995 0.118
0 0 0 1
The interp() method returns an SE3 object that holds the SE3 transformation matrices created from the interpolation:
|
# SO(3) or SE(3) |
|
return self.__class__( |
|
[ |
|
smb.trinterp(start=self.A, end=end, s=_s, shortest=shortest) |
|
for _s in s |
|
] |
|
) |
.
However, there is a validity check in the SE3 object that will turn any invalid transforms into identity matrices.
A possible solution is to modify the trinterp() method to turn all quaternions into unit quaternions before converting them into rotation matrices:
|
qr = qslerp(q0, q1, s, shortest=shortest) |
|
pr = p0 * (1 - s) + s * p1 |
|
|
|
return rt2tr(q2r(qr), pr) |
.
I am not sure if this is the only location in the spatialmath codebase that would benefit from this change.
the trinterp() method does not make sure quaternions are valid before converting them to transforms. It calls qslerp which can sometimes generate invalid quaternions.
Repro:
The interp() method returns an SE3 object that holds the SE3 transformation matrices created from the interpolation:
spatialmath-python/spatialmath/baseposematrix.py
Lines 449 to 455 in 4c68fa9
However, there is a validity check in the SE3 object that will turn any invalid transforms into identity matrices.
A possible solution is to modify the trinterp() method to turn all quaternions into unit quaternions before converting them into rotation matrices:
spatialmath-python/spatialmath/base/transforms3d.py
Lines 1697 to 1700 in 4c68fa9
I am not sure if this is the only location in the spatialmath codebase that would benefit from this change.