예제 #1
0
 def test_to_euler(self):
     """mtx -> euler -> mtx"""
     data = random_rotations(13, dtype=torch.float64)
     for convention in self._all_euler_angle_conventions():
         euler_angles = matrix_to_euler_angles(data, convention)
         mdata = euler_angles_to_matrix(euler_angles, convention)
         self.assertTrue(torch.allclose(data, mdata))
예제 #2
0
 def test_euler_grad_exists(self):
     """Euler angle calculations are differentiable."""
     rotation = random_rotation(dtype=torch.float64, requires_grad=True)
     for convention in self._all_euler_angle_conventions():
         euler_angles = matrix_to_euler_angles(rotation, convention)
         mdata = euler_angles_to_matrix(euler_angles, convention)
         [g] = torch.autograd.grad(mdata.sum(), rotation)
         self.assertTrue(torch.isfinite(g).all())
예제 #3
0
    def test_from_euler(self):
        """euler -> mtx -> euler"""
        n_repetitions = 10
        # tolerance is how much we keep the middle angle away from the extreme
        # allowed values which make the calculation unstable (Gimbal lock).
        tolerance = 0.04
        half_pi = math.pi / 2
        data = torch.zeros(n_repetitions, 3)
        data.uniform_(-math.pi, math.pi)

        data[:, 1].uniform_(-half_pi + tolerance, half_pi - tolerance)
        for convention in self._tait_bryan_conventions():
            matrices = euler_angles_to_matrix(data, convention)
            mdata = matrix_to_euler_angles(matrices, convention)
            self.assertTrue(torch.allclose(data, mdata))

        data[:, 1] += half_pi
        for convention in self._proper_euler_conventions():
            matrices = euler_angles_to_matrix(data, convention)
            mdata = matrix_to_euler_angles(matrices, convention)
            self.assertTrue(torch.allclose(data, mdata))