def test_from_matrix(): mat = [[0, 0, 1], [1, 0, 0], [0, 1, 0]] rot = ConstantRotation.from_matrix(mat, 0, 1) expected_quats = np.asarray([0.5, 0.5, 0.5, 0.5]) np.testing.assert_almost_equal(rot.quat, expected_quats) assert rot.source == 0 assert rot.dest == 1
def create_rotations(rotation_table): """ Convert an ISIS rotation table into rotation objects. Parameters ---------- rotation_table : dict The rotation ISIS table as a dictionary Returns ------- : list A list of time dependent or constant rotation objects from the table. This list will always have either 1 or 2 elements. The first rotation will be time dependent and the second rotation will be constant. The rotations will be ordered such that the reference frame the first rotation rotates to is the reference frame the second rotation rotates from. """ rotations = [] root_frame = rotation_table['TimeDependentFrames'][-1] last_time_dep_frame = rotation_table['TimeDependentFrames'][0] # Case 1: It's a table of quaternions and times if 'J2000Q0' in rotation_table: # SPICE quaternions are (W, X, Y, Z) and ALE uses (X, Y, Z, W). quats = np.array([ rotation_table['J2000Q1'], rotation_table['J2000Q2'], rotation_table['J2000Q3'], rotation_table['J2000Q0'] ]).T time_dep_rot = TimeDependentRotation(quats, rotation_table['ET'], root_frame, last_time_dep_frame) rotations.append(time_dep_rot) # Case 2: It's a table of Euler angle coefficients elif 'J2000Ang1' in rotation_table: ephemeris_times = np.linspace(rotation_table['CkTableStartTime'], rotation_table['CkTableEndTime'], rotation_table['CkTableOriginalSize']) base_time = rotation_table['J2000Ang1'][-1] time_scale = rotation_table['J2000Ang2'][-1] scaled_times = (ephemeris_times - base_time) / time_scale coeffs = np.array([ rotation_table['J2000Ang1'][:-1], rotation_table['J2000Ang2'][:-1], rotation_table['J2000Ang3'][:-1] ]).T angles = polyval(scaled_times, coeffs).T # ISIS is hard coded to ZXZ (313) Euler angle axis order. # SPICE also interprets Euler angle rotations as negative rotations, # so negate them before passing to scipy. time_dep_rot = TimeDependentRotation.from_euler( 'zxz', -angles, ephemeris_times, root_frame, last_time_dep_frame) rotations.append(time_dep_rot) if 'ConstantRotation' in rotation_table: last_constant_frame = rotation_table['ConstantFrames'][0] rot_mat = np.reshape(np.array(rotation_table['ConstantRotation']), (3, 3)) constant_rot = ConstantRotation.from_matrix(rot_mat, last_time_dep_frame, last_constant_frame) rotations.append(constant_rot) return rotations