def frame_tree(request): """ Test frame tree structure: 1 / \ / \ 2 4 / / 3 """ rotations = [ ConstantRotation(np.array([1, 0, 0, 0]), 2, 1), ConstantRotation(np.array([1.0 / np.sqrt(2), 0, 0, 1.0 / np.sqrt(2)]), 3, 2), ConstantRotation(np.array([1.0 / np.sqrt(2), 0, 0, 1.0 / np.sqrt(2)]), 4, 1) ] root_node = FrameNode(1) child_node_1 = FrameNode(2, parent=root_node, rotation=rotations[0]) child_node_2 = FrameNode(3, parent=child_node_1, rotation=rotations[1]) child_node_3 = FrameNode(4, parent=root_node, rotation=rotations[2]) nodes = [root_node, child_node_1, child_node_2, child_node_3] return (nodes, rotations)
def test_line_scan_driver(): j2000 = FrameNode(1) body_rotation = TimeDependentRotation( np.array([[0, 0, 0, 1], [0, 0, 0, 1]]), np.array([0, 1]), 100, 1 ) body_fixed = FrameNode(100, parent=j2000, rotation=body_rotation) spacecraft_rotation = TimeDependentRotation( np.array([[0, 0, 0, 1], [0, 0, 0, 1]]), np.array([0, 1]), 1000, 1 ) spacecraft = FrameNode(1000, parent=j2000, rotation=spacecraft_rotation) sensor_rotation = ConstantRotation(np.array([0, 0, 0, 1]), 1010, 1000) sensor = FrameNode(1010, parent=spacecraft, rotation=sensor_rotation) driver = TestLineScanner() driver.target_body_radii = (1100, 1000) driver.sensor_position = ( [[0, 1, 2], [3, 4, 5]], [[0, -1, -2], [-3, -4, -5]], [800, 900] ) driver.sun_position = ( [[0, 1, 2], [3, 4, 5]], [[0, -1, -2], [-3, -4, -5]], [800, 900] ) driver.sensor_frame_id = 1010 driver.target_frame_id = 100 driver.frame_chain = j2000 driver.sample_summing = 2 driver.line_summing = 4 driver.focal_length = 500 driver.detector_center_line = 0.5 driver.detector_center_sample = 512 driver.detector_start_line = 0 driver.detector_start_sample = 8 driver.focal2pixel_lines = [0.1, 0.2, 0.3] driver.focal2pixel_samples = [0.3, 0.2, 0.1] driver.usgscsm_distortion_model = { 'radial' : { 'coefficients' : [0.0, 1.0, 0.1] } } driver.image_lines = 10000 driver.image_samples = 1024 driver.platform_name = 'Test Platform' driver.sensor_name = 'Test Line Scan Sensor' driver.ephemeris_stop_time = 900 driver.ephemeris_start_time = 800 return driver
def frame_chain(self): """ Return the root node of the rotation frame tree/chain. The root node is the J2000 reference frame. The other nodes in the tree can be accessed via the methods in the FrameNode class. This property expects the ephemeris_time property/attribute to be defined. It should be a list of the ephemeris seconds past the J2000 epoch for each exposure in the image. Returns ------- FrameNode The root node of the frame tree. This will always be the J2000 reference frame. """ if not hasattr(self, '_root_frame'): j2000_id = 1 #J2000 is our root reference frame self._root_frame = FrameNode(j2000_id) sensor_quats = np.zeros((len(self.ephemeris_time), 4)) sensor_times = np.array(self.ephemeris_time) body_quats = np.zeros((len(self.ephemeris_time), 4)) body_times = np.array(self.ephemeris_time) for i, time in enumerate(self.ephemeris_time): sensor2j2000 = spice.pxform(spice.frmnam(self.sensor_frame_id), spice.frmnam(j2000_id), time) q_sensor = spice.m2q(sensor2j2000) sensor_quats[i, :3] = q_sensor[1:] sensor_quats[i, 3] = q_sensor[0] body2j2000 = spice.pxform(spice.frmnam(self.target_frame_id), spice.frmnam(j2000_id), time) q_body = spice.m2q(body2j2000) body_quats[i, :3] = q_body[1:] body_quats[i, 3] = q_body[0] sensor2j2000_rot = TimeDependentRotation(sensor_quats, sensor_times, self.sensor_frame_id, j2000_id) sensor_node = FrameNode(self.sensor_frame_id, parent=self._root_frame, rotation=sensor2j2000_rot) body2j2000_rot = TimeDependentRotation(body_quats, body_times, self.target_frame_id, j2000_id) body_node = FrameNode(self.target_frame_id, parent=self._root_frame, rotation=body2j2000_rot) return self._root_frame
def frame_chain(self): j2000 = FrameNode(1) body_rotation = TimeDependentRotation( np.array([[0, 0, 0, 1], [0, 0, 0, 1]]), np.array([0, 1]), 100, 1) body_fixed = FrameNode(100, parent=j2000, rotation=body_rotation) spacecraft_rotation = TimeDependentRotation( np.array([[0, 0, 0, 1], [0, 0, 0, 1]]), np.array([0, 1]), 1000, 1) spacecraft = FrameNode(1000, parent=j2000, rotation=spacecraft_rotation) sensor_rotation = ConstantRotation(np.array([0, 0, 0, 1]), 1010, 1000) sensor = FrameNode(1010, parent=spacecraft, rotation=sensor_rotation) return j2000
def test_path_to_self(): node = FrameNode(1) forward_path, reverse_path = node.path_to(node) assert forward_path == [node] assert reverse_path == []
def test_last_time_dependent_frame_between(): """ Test frame tree structure: 1 / \ / \ 2 4 / \ / \ 3 5 The rotations from 3 to 2 and 1 to 4 are time dependent. All other rotations are constant. """ rotations = [ ConstantRotation(np.array([1, 0, 0, 0]), 2, 1), TimeDependentRotation( np.array([1.0 / np.sqrt(2), 0, 0, 1.0 / np.sqrt(2)]), np.array([1]), 4, 1), TimeDependentRotation( np.array([1.0 / np.sqrt(2), 0, 0, 1.0 / np.sqrt(2)]), np.array([1]), 5, 4), ConstantRotation(np.array([1.0 / np.sqrt(2), 0, 0, 1.0 / np.sqrt(2)]), 3, 2) ] root_node = FrameNode(1) child_node_1 = FrameNode(2, parent=root_node, rotation=rotations[0]) child_node_2 = FrameNode(3, parent=child_node_1, rotation=rotations[1]) child_node_3 = FrameNode(4, parent=root_node, rotation=rotations[2]) child_node_4 = FrameNode(5, parent=child_node_3, rotation=rotations[3]) last_frame_from_root_to_child_2 = root_node.last_time_dependent_frame_between( child_node_2) last_frame_from_child_2_to_root = child_node_2.last_time_dependent_frame_between( root_node) last_frame_from_child_2_to_child_4 = child_node_2.last_time_dependent_frame_between( child_node_4) last_frame_from_child_4_to_child_2 = child_node_4.last_time_dependent_frame_between( child_node_2) assert last_frame_from_root_to_child_2 == child_node_2 assert last_frame_from_child_2_to_root == child_node_1 assert last_frame_from_child_2_to_child_4 == child_node_3 assert last_frame_from_child_4_to_child_2 == child_node_2
def test_self_rotation(): node = FrameNode(1) rotation = node.rotation_to(node) assert rotation.source == 1 assert rotation.dest == 1 np.testing.assert_equal(rotation.quat, np.array([0, 0, 0, 1]))