示例#1
0
    def test_generate_opm_with_defaults(self):
        o = OpmParams({'epoch': 'foo', 'state_vector': [1, 2, 3, 4, 5, 6]})
        expected_opm = """CCSDS_OPM_VERS = 2.0
ORIGINATOR = ADAM_User
COMMENT Cartesian coordinate system
OBJECT_NAME = dummy
OBJECT_ID = 001
CENTER_NAME = SUN
REF_FRAME = ITRF-97
TIME_SYSTEM = UTC
EPOCH = foo
X = 1
Y = 2
Z = 3
X_DOT = 4
Y_DOT = 5
Z_DOT = 6
MASS = 1000
SOLAR_RAD_AREA = 20
SOLAR_RAD_COEFF = 1
DRAG_AREA = 20
DRAG_COEFF = 2.2"""
        # Remove the CREATION_DATE stamp since that varies.
        opm = "\n".join([
            line for line in o.generate_opm().splitlines()
            if not line.startswith('CREATION_DATE')
        ])
        self.maxDiff = None  # Otherwise if the next line fails, we can't see the diff
        self.assertEqual(expected_opm, opm)
示例#2
0
    def test_generate_opm_with_defaults(self):
        o = OpmParams({'epoch': 'foo', 'state_vector': [1, 2, 3, 4, 5, 6]})
        expected_opm = """CCSDS_OPM_VERS = 2.0
ORIGINATOR = ADAM_User
COMMENT Cartesian coordinate system
OBJECT_NAME = dummy
OBJECT_ID = 001
CENTER_NAME = SUN
REF_FRAME = ICRF
TIME_SYSTEM = UTC
EPOCH = foo
X = 1
Y = 2
Z = 3
X_DOT = 4
Y_DOT = 5
Z_DOT = 6
MASS = 1000.0
SOLAR_RAD_AREA = 20.0
SOLAR_RAD_COEFF = 1.0
DRAG_AREA = 20.0
DRAG_COEFF = 2.2"""
        opm = OpmParamsTest.remove_non_static_fields(o.generate_opm())
        self.maxDiff = None  # Otherwise if the next line fails, we can't see the diff
        self.assertEqual(expected_opm, opm)
示例#3
0
    def make_cartesian_and_keplerian_batches(self, start_time_str,
                                             end_time_str):
        keplerian_elements = {
            'semi_major_axis_km': 3.1307289138037175E8,
            'eccentricity': 0.5355029800000188,
            'inclination_deg': 23.439676743246295,
            'ra_of_asc_node_deg': 359.9942693176405,
            'arg_of_pericenter_deg': 328.5584374618295,
            'true_anomaly_deg': -127.01778914927144,
            'gm': 1.327124400419394E11
        }

        cartesian_state_vector = [
            -3.0653634150102222e8,
            -1.1097955684640282e8,
            -4.8129706422527283e7,  # x, y, z
            15.7598552764090590,
            -10.5875673291958420,
            -4.5896734328869746  # dx, dy, dZ
        ]

        propagation_params = PropagationParams({
            'start_time':
            start_time_str,
            'end_time':
            end_time_str,
            'project_uuid':
            self.working_project.get_uuid(),
            'description':
            'Created by test at ' + start_time_str
        })
        opm_params_templ = {
            'epoch': start_time_str,
            # state_vector or keplerian_elements will be set later.
            'mass': 500.5,
            'solar_rad_area': 25.2,
            'solar_rad_coeff': 1.2,
            'drag_area': 33.3,
            'drag_coeff': 2.5
        }

        cartesian_opm_params = opm_params_templ.copy()
        cartesian_opm_params['state_vector'] = cartesian_state_vector

        keplerian_opm_params = opm_params_templ.copy()
        keplerian_opm_params['keplerian_elements'] = keplerian_elements

        cartesian = Batch(propagation_params, OpmParams(cartesian_opm_params))
        keplerian = Batch(propagation_params, OpmParams(keplerian_opm_params))
        return cartesian, keplerian
    def _new_batch_propagation(self):
        now = datetime.datetime.utcnow()
        later = now + datetime.timedelta(10 * 365)

        propagation_params = PropagationParams({
            'start_time':
            now.isoformat() + 'Z',
            'end_time':
            later.isoformat() + 'Z',
            'step_size':
            60 * 60,  # 1 hour.
            'description':
            'Created by test at ' + str(now) + 'Z'
        })

        state_vec = [
            130347560.13690618, -74407287.6018632, -35247598.541470632,
            23.935241263310683, 27.146279819258538, 10.346605942591514
        ]
        opm_params = OpmParams({
            'epoch': now.isoformat() + 'Z',
            'state_vector': state_vec,
            'mass': 500.5,
            'solar_rad_area': 25.2,
            'solar_rad_coeff': 1.2,
            'drag_area': 33.3,
            'drag_coeff': 2.5,
            'originator': 'Test',
            'object_name': 'TestObj',
            'object_id': 'TestObjId',
        })

        return BatchPropagation(propagation_params, opm_params)
    def new_targeted_propagation(self, initial_maneuver):
        start = '2013-05-25T00:00:02.000000Z'
        end = '2018-04-25T03:06:14.200000Z'
        propagation_params = PropagationParams({
            'start_time':
            start,
            'end_time':
            end,
            'project_uuid':
            self.working_project.get_uuid(),
            'description':
            'Created by test at ' + start
        })

        state_vec = [
            -1.4914794358536252e+8, 1.0582106861692128e+8,
            6.0492834101479955e+7, -11.2528789273597756, -22.3258231726462242,
            -9.7271222877710155
        ]
        opm_params = OpmParams({
            'epoch': start,
            'state_vector': state_vec,
            'initial_maneuver': initial_maneuver,
        })

        return TargetedPropagation(
            propagation_params, opm_params,
            TargetingParams({
                'target_distance_from_earth': 1.0e4,
                'tolerance': 1.0
            }))
    def make_batch(self, state_vec, start_time, end_time):
        start_time_str = start_time.isoformat() + 'Z'
        end_time_str = end_time.isoformat() + 'Z'

        propagation_params = PropagationParams({
            'start_time':
            start_time_str,
            'end_time':
            end_time_str,
            'step_size':
            0,
            'project_uuid':
            self.working_project.get_uuid(),
            'description':
            'Created by test at ' + start_time_str
        })
        opm_params = OpmParams({
            'epoch': start_time_str,
            'state_vector': state_vec,
            'mass': 500.5,
            'solar_rad_area': 25.2,
            'solar_rad_coeff': 1.2,
            'drag_area': 33.3,
            'drag_coeff': 2.5,
            'originator': 'Test',
            'object_name': 'TestObj',
            'object_id': 'TestObjId',
        })

        return Batch(propagation_params, opm_params)
示例#7
0
    def test_access(self):
        projects_module = self.service.get_projects_module()
        permissions_module = self.service.get_permissions_module()
        groups_module = self.service.get_groups_module()

        # Only prod has a public project.
        projects = projects_module.get_projects()
        if self.config.get_environment() == "prod":
            self.assertEqual(1, len(projects))
            self.assertEqual("public", projects[0].get_name())
        else:
            self.assertEqual(0, len(projects))
            print("Skipping check for public objects.")

        # Can't add a project to public project.
        public_project = "00000000-0000-0000-0000-000000000001"
        with (self.assertRaises(RuntimeError)):
            projects_module.new_project(public_project, "", "")

        # Can't run a batch in the public project.
        batches_module = self.service.get_batches_module()
        dummy_propagation_params = PropagationParams({
            'start_time': 'AAA',
            'end_time': 'BBB',
            'project_uuid': 'CCC'
        })
        dummy_opm_params = OpmParams({
            'epoch': 'DDD',
            'state_vector': [1, 2, 3, 4, 5, 6]
        })
        with (self.assertRaises(RuntimeError)):
            batches_module.new_batch(dummy_propagation_params,
                                     dummy_opm_params)

        # Anon should have no permissions.
        permissions = permissions_module.get_my_permissions()
        self.assertEqual(1, len(permissions))
        self.assertEqual(0, len(permissions[""]))

        # And anon is in no groups.
        groups = groups_module.get_my_memberships()
        self.assertEqual(0, len(groups))

        # Therefore anon can grant no permissions.
        with (self.assertRaises(RuntimeError)):
            permissions_module.grant_user_permission(
                "*****@*****.**", Permission("READ", "PROJECT",
                                             public_project))

        # And can add/modify no groups.
        with (self.assertRaises(RuntimeError)):
            groups_module.new_group("", "")
        all_group = "00000000-0000-0000-0000-000000000001"
        with (self.assertRaises(RuntimeError)):
            groups_module.add_user_to_group("*****@*****.**", all_group)

        # Not even allowed to see the members of the magic all group.
        with (self.assertRaises(RuntimeError)):
            groups_module.get_group_members(all_group)
示例#8
0
    def test_submit_batch(self, service):
        keplerian_elements = {
            'semi_major_axis_km': 448793612,
            'eccentricity': 0.1,
            'inclination_deg': 90,
            'ra_of_asc_node_deg': 91,
            'arg_of_pericenter_deg': 92,
            'true_anomaly_deg': 93,
            'gm': 132712440041.9394
        }

        keplerian_sigma = {
            'semi_major_axis': 100,
            'eccentricity': 0.001,
            'inclination': 1,
            'ra_of_asc_node': 2,
            'arg_of_pericenter': 3,
            'true_anomaly': 4,
        }

        # state_vec = [130347560.13690618,
        #              -74407287.6018632,
        #              -35247598.541470632,
        #              23.935241263310683,
        #              27.146279819258538,
        #              10.346605942591514]
        # sigma_vec = {'x': 1000,
        #              'y': 1001,
        #              'z': 1002,
        #              'x_dot': 10,
        #              'y_dot': 11,
        #              'z_dot': 12}
        draws = 5
        propagation_params = PropagationParams({
            'start_time': '2017-10-04T00:00:00Z',  # propagation start time in ISO format
            'end_time': '2017-10-11T00:00:00Z',  # propagation end time in ISO format

            'project_uuid': service.workspace,
            'keplerianSigma': keplerian_sigma,
            'monteCarloDraws': draws,
            'propagationType': 'MONTE_CARLO',
            'description': 'Integration Test Run',
            'stopOnImpact': True,
            'step_size': 86400,
            'stopOnCloseApproach': False,
            'stopOnImpactDistanceMeters': 500000,
            'closeApproachRadiusFromTargetMeters': 7000000000
        })

        opm_params = OpmParams({
            'epoch': '2017-10-04T00:00:00Z',
            'keplerian_elements': keplerian_elements,
        })

        response = service.processing_service.execute_batch_propagation(
            service.workspace, propagation_params, opm_params)
        assert response.job_id() is not None
    def new_batch_propagation(self):
        now = datetime.datetime.utcnow()
        later = now + datetime.timedelta(10 * 365)

        propagation_params = PropagationParams({
            'start_time':
            now.isoformat() + 'Z',
            'end_time':
            later.isoformat() + 'Z',
            'step_size':
            60 * 60,  # 1 hour.
            'description':
            'Created by test at ' + str(now) + 'Z'
        })

        state_vec = [
            130347560.13690618, -74407287.6018632, -35247598.541470632,
            23.935241263310683, 27.146279819258538, 10.346605942591514
        ]
        opm_params = OpmParams({
            'epoch': now.isoformat() + 'Z',
            'state_vector': state_vec,

            # Comment out state_vector and uncomment this to try with keplerian elements instead.
            # 'keplerian_elements': {
            #     'semi_major_axis_km': 3.1307289138037175E8,
            #     'eccentricity': 0.5355029800000188,
            #     'inclination_deg': 23.439676743246295,
            #     'ra_of_asc_node_deg': 359.9942693176405,
            #     'arg_of_pericenter_deg': 328.5584374618295,
            #     'true_anomaly_deg': -127.01778914927144,
            #     'gm': 1.327124400419394E11
            # },
            'mass': 500.5,
            'solar_rad_area': 25.2,
            'solar_rad_coeff': 1.2,
            'drag_area': 33.3,
            'drag_coeff': 2.5,
            'originator': 'Test',
            'object_name': 'TestObj',
            'object_id': 'TestObjId',

            # Uncomment this to try a hypercube propagation.
            # Lower triangular covariance matrix (21 elements in a list)
            # 'covariance': [
            #     3.331349476038534e-04,
            #     4.618927349220216e-04, 6.782421679971363e-04,
            #     -3.070007847730449e-04, -4.221234189514228e-04, 3.231931992380369e-04,
            #     -3.349365033922630e-07, -4.686084221046758e-07, 2.484949578400095e-07, 4.296022805587290e-10,  # NOQA (we want to keep the visual triangle)
            #     -2.211832501084875e-07, -2.864186892102733e-07, 1.798098699846038e-07, 2.608899201686016e-10, 1.767514756338532e-10,  # NOQA
            #     -3.041346050686871e-07, -4.989496988610662e-07, 3.540310904497689e-07, 1.869263192954590e-10, 1.008862586240695e-10, 6.224444338635500e-10],  # NOQA
            # 'perturbation': 3,
            # 'hypercube': 'FACES',
        })

        return BatchPropagation(propagation_params, opm_params)
示例#10
0
    def test_sun_ememe(self, service, working_project):
        start_time_str = "2000-01-01T11:58:55.816Z"
        end_time_str = "2009-07-21T21:55:08.813Z"

        sun_ememe_state_vec = [
            -306536346.18024945, -120966638.54521248, -12981.069369263947,
            15.759854830195243, -11.539570959741736, 0.0005481049628786039
        ]

        propagation_params = PropagationParams({
            'start_time':
            start_time_str,
            'end_time':
            end_time_str,
            'step_size':
            86400,
            'project_uuid':
            working_project.get_uuid(),
            'description':
            'Created by test at ' + start_time_str
        })
        opm_params = OpmParams({
            'epoch': start_time_str,
            'state_vector': sun_ememe_state_vec,
            'center_name': 'SUN',
            'ref_frame': 'EMEME2000',
        })

        batch = Batch(propagation_params, opm_params)
        runner = BatchRunManager(service.get_batches_module(), [batch])
        runner.run()
        end_state = batch.get_results().get_end_state_vector()
        # The output state is expected to be in ICRF.
        expected_end_state = [
            73978163.61069362, -121822760.05571477, -52811158.83249758,
            31.71000343989318, 29.9657246374751, .6754531613947713
        ]
        # These values are in EMEME. The resulting ephemeris is not expected to match these values.
        # expected_end_state = [73978158.47632701, -132777272.5255892, 5015.073123970032,
        #                       31.710003506237434, 27.761693311026138, -11.299967713192564]

        difference = np.subtract(expected_end_state, end_state)
        print("Difference is %s" % difference)
        print("End state: %s" % end_state)

        npt.assert_allclose(difference[0:3], [0, 0, 0], rtol=0, atol=.02)
        npt.assert_allclose(difference[3:6], [0, 0, 0], rtol=0, atol=.00002)

        # The returned ephemeris will be in Sun-centered ICRF, not EMEME. My best guess is that
        # the ephemeris file doesn't support all reference frames, so if it encounters one that
        # isn't supported, it'll choose a similar one.
        ephem = batch.get_results().get_parts()[-1].get_ephemeris()
        assert "ICRF" in ephem
        assert "EMEME" not in ephem
示例#11
0
def propagate_states(state_vectors, epoch_time, end_time):
    """Propagate states from one time to another

    Assume state epoch is the same as integration start time

    Args:
        sate_vectors (list of lists) - list of lists with 6 elements 
                                        [rx, ry, rz, vx, vy, vz]  [km, km/s]
        epoch_time (datetime.datetime) - epoch of state (UTC datetime)
        end_time (datetime.datetime) - time at which to end the simulation
                                        (UTC datetime)

    Returns:
        end_state_vectors (list of lists) - states at end of integration
                                            [rx, ry, rz, vx, vy, vz]  [km, km/s]
    """

    # Convert times to strings
    epoch_time_str = batch_time_string_from_datetime(epoch_time)
    start_time_str = epoch_time_str
    end_time_str = batch_time_string_from_datetime(end_time)
    print("Propagating %i states to propagate from %s to %s" %
          (len(state_vectors), start_time_str, end_time_str))

    url = "https://pro-equinox-162418.appspot.com/_ah/api/adam/v1"
    rest = RestRequests(url)
    batches_module = Batches(rest)

    # Create batches from statevectors
    batches = []
    propagation_params = PropagationParams({
        'start_time':
        start_time_str,
        'end_time':
        end_time_str,
        'project_uuid':
        'ffffffff-ffff-ffff-ffff-ffffffffffff'
    })
    for state_vector in state_vectors:
        opm_params = OpmParams({
            'epoch': start_time_str,
            'state_vector': state_vector
        })
        batches.append(Batch(propagation_params, opm_params))

    # submit batches and wait till they finish running
    BatchRunManager(batches_module, batches).run()

    # Get final states
    end_state_vectors = []
    for batch in batches:
        end_state_vectors.append(batch.get_results().get_end_state_vector())

    return end_state_vectors
    def test_config_in_use_pins_project(self):
        # Config management isn't very common, doesn't merit direct addition to service.
        configs = PropagatorConfigs(self.service.rest)
        projects = self.service.get_projects_module()

        project = self.service.new_working_project()
        project1 = projects.new_project(project.get_uuid(), "", "")
        self.assertIsNotNone(project1)
        project2 = projects.new_project(project.get_uuid(), "", "")
        self.assertIsNotNone(project2)
        print("Added child projects to working project: " + "[" +
              project1.get_uuid() + ", " + project2.get_uuid() + "]")

        config = configs.new_config({
            'project': project1.get_uuid(),
            'description': 'test config'
        })
        self.assertEqual(project1.get_uuid(), config.get_project())

        batch = Batch(
            PropagationParams({
                'start_time': '2017-10-04T00:00:00Z',
                'end_time': '2017-10-05T00:00:00Z',
                'project_uuid': project2.get_uuid(),
                'propagator_uuid': config.get_uuid()
            }),
            OpmParams({
                'epoch':
                '2017-10-04T00:00:00Z',
                'state_vector': [
                    130347560.13690618, -74407287.6018632, -35247598.541470632,
                    23.935241263310683, 27.146279819258538, 10.346605942591514
                ]
            }))
        BatchRunManager(self.service.get_batches_module(), [batch]).run()

        # Attempt to delete the project with the config in it. It should refuse because the
        # config is still in use by the batch.
        with self.assertRaises(RuntimeError):
            projects.delete_project(project1.get_uuid())

        # Then delete the batch. After that, the project with the config in it should
        # delete no problem.
        self.service.batches.delete_batch(batch.get_uuid())
        projects.delete_project(project1.get_uuid())

        # Clean up the batch holder project.
        projects.delete_project(project2.get_uuid())
示例#13
0
    def new_hypercube_batch(self, hypercube):
        now = datetime.datetime.utcnow()
        later = now + datetime.timedelta(365 * 10)  # 10 years

        propagation_params = PropagationParams({
            'start_time': now.isoformat() + 'Z',
            'end_time': later.isoformat() + 'Z',
            'step_size': 0,
            'project_uuid': self.working_project.get_uuid(),
            'description': 'Created by test at ' + str(now) + 'Z'
        })

        state_vec = [130347560.13690618,
                     -74407287.6018632,
                     -35247598.541470632,
                     23.935241263310683,
                     27.146279819258538,
                     10.346605942591514]
        opm_params = OpmParams({
            'epoch': now.isoformat() + 'Z',
            'state_vector': state_vec,

            'mass': 500.5,
            'solar_rad_area': 25.2,
            'solar_rad_coeff': 1.2,
            'drag_area': 33.3,
            'drag_coeff': 2.5,

            'originator': 'Test',
            'object_name': 'TestObj',
            'object_id': 'TestObjId',

            # Lower triangular covariance matrix (21 elements in a list)
            'covariance': [
                3.331349476038534e-04,
                4.618927349220216e-04, 6.782421679971363e-04,
                -3.070007847730449e-04, -4.221234189514228e-04, 3.231931992380369e-04,
                -3.349365033922630e-07, -4.686084221046758e-07, 2.484949578400095e-07, 4.296022805587290e-10,  # NOQA (we want to keep the visual triangle)
                -2.211832501084875e-07, -2.864186892102733e-07, 1.798098699846038e-07, 2.608899201686016e-10, 1.767514756338532e-10,  # NOQA
                -3.041346050686871e-07, -4.989496988610662e-07, 3.540310904497689e-07, 1.869263192954590e-10, 1.008862586240695e-10, 6.224444338635500e-10],  # NOQA
            'perturbation': 3,
            'hypercube': hypercube,
        })

        return Batch(propagation_params, opm_params)
示例#14
0
    def test_icrf(self, service, working_project):
        start_time_str = "2000-01-01T11:58:55.816Z"
        end_time_str = "2009-07-21T21:55:08.813Z"

        sun_icrf_state_vec = [
            -306536341.5010222, -110979556.84640282, -48129706.42252728,
            15.75985527640906, -10.587567329195842, -4.589673432886975
        ]

        propagation_params = PropagationParams({
            'start_time':
            start_time_str,
            'end_time':
            end_time_str,
            'step_size':
            86400,
            'project_uuid':
            working_project.get_uuid(),
            'description':
            'Created by test at ' + start_time_str
        })
        opm_params = OpmParams({
            'epoch': start_time_str,
            'state_vector': sun_icrf_state_vec,
            'center_name': 'SUN',
            'ref_frame': 'ICRF',
        })
        batch = Batch(propagation_params, opm_params)
        runner = BatchRunManager(service.get_batches_module(), [batch])
        runner.run()
        end_state = batch.get_results().get_end_state_vector()
        expected_end_state = [
            73978163.61069362, -121822760.05571477, -52811158.83249758,
            31.71000343989318, 29.9657246374751, .6754531613947713
        ]

        difference = np.subtract(expected_end_state, end_state)
        print("Difference is %s" % difference)
        print("End state: %s" % end_state)

        npt.assert_allclose(difference[0:3], [0, 0, 0], rtol=0, atol=.02)
        npt.assert_allclose(difference[3:6], [0, 0, 0], rtol=0, atol=.00002)

        ephem = batch.get_results().get_parts()[-1].get_ephemeris()
        assert "ICRF" in ephem
示例#15
0
    def new_dummy_batch(self, days_to_propagate):
        if (days_to_propagate > 36500):
            print(
                "Server has trouble handling propagation durations longer than 100 years. "
                + "Try something smaller.")
            return

        now = datetime.datetime.utcnow()
        later = now + datetime.timedelta(days_to_propagate)

        propagation_params = PropagationParams({
            'start_time':
            now.isoformat() + 'Z',
            'end_time':
            later.isoformat() + 'Z',
            'step_size':
            60 * 60,  # 1 hour.
            'project_uuid':
            self.working_project.get_uuid(),
            'description':
            'Created by test at ' + str(now) + 'Z'
        })

        state_vec = [
            130347560.13690618, -74407287.6018632, -35247598.541470632,
            23.935241263310683, 27.146279819258538, 10.346605942591514
        ]
        opm_params = OpmParams({
            'epoch': now.isoformat() + 'Z',
            'state_vector': state_vec,
            'mass': 500.5,
            'solar_rad_area': 25.2,
            'solar_rad_coeff': 1.2,
            'drag_area': 33.3,
            'drag_coeff': 2.5,
            'originator': 'Test',
            'object_name': 'TestObj',
            'object_id': 'TestObjId',
        })

        return Batch(propagation_params, opm_params)
    def test_generate_opm(self):
        o = OpmParams({
            'epoch':
            'foo',
            'state_vector': [1, 2, 3, 4, 5, 6],
            'keplerian_elements': {
                'semi_major_axis_km': 1,
                'eccentricity': 2,
                'inclination_deg': 3,
                'ra_of_asc_node_deg': 4,
                'arg_of_pericenter_deg': 5,
                'true_anomaly_deg': 6,
                'gm': 7
            },
            'originator':
            'a',
            'object_name':
            'b',
            'object_id':
            'c',
            'center_name':
            'EARTH',
            'ref_frame':
            'EMEME2000',
            'mass':
            1,
            'solar_rad_area':
            2,
            'solar_rad_coeff':
            3,
            'drag_area':
            4,
            'drag_coeff':
            5,
            'covariance': [
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
                18, 19, 20
            ],
            'perturbation':
            7,
            'hypercube':
            'CORNERS',
        })
        expected_opm = """CCSDS_OPM_VERS = 2.0
ORIGINATOR = a
COMMENT Cartesian coordinate system
OBJECT_NAME = b
OBJECT_ID = c
CENTER_NAME = EARTH
REF_FRAME = EMEME2000
TIME_SYSTEM = UTC
EPOCH = foo
X = 1
Y = 2
Z = 3
X_DOT = 4
Y_DOT = 5
Z_DOT = 6
SEMI_MAJOR_AXIS = 1
ECCENTRICITY = 2
INCLINATION = 3
RA_OF_ASC_NODE = 4
ARG_OF_PERICENTER = 5
TRUE_ANOMALY = 6
GM = 7
MASS = 1
SOLAR_RAD_AREA = 2
SOLAR_RAD_COEFF = 3
DRAG_AREA = 4
DRAG_COEFF = 5
CX_X = 0
CY_X = 1
CY_Y = 2
CZ_X = 3
CZ_Y = 4
CZ_Z = 5
CX_DOT_X = 6
CX_DOT_Y = 7
CX_DOT_Z = 8
CX_DOT_X_DOT = 9
CY_DOT_X = 10
CY_DOT_Y = 11
CY_DOT_Z = 12
CY_DOT_X_DOT = 13
CY_DOT_Y_DOT = 14
CZ_DOT_X = 15
CZ_DOT_Y = 16
CZ_DOT_Z = 17
CZ_DOT_X_DOT = 18
CZ_DOT_Y_DOT = 19
CZ_DOT_Z_DOT = 20
USER_DEFINED_ADAM_INITIAL_PERTURBATION = 7 [sigma]
USER_DEFINED_ADAM_HYPERCUBE = CORNERS"""
        # Remove the CREATION_DATE stamp since that varies.
        opm = "\n".join([
            line for line in o.generate_opm().splitlines()
            if not line.startswith('CREATION_DATE')
        ])
        self.maxDiff = None  # Otherwise if the next line fails, we can't see the diff
        self.assertEqual(expected_opm, opm)
示例#17
0
    def test_generate_opm(self):
        o = OpmParams({
            'epoch':
            'foo',
            'state_vector': [1, 2, 3, 4, 5, 6],
            'originator':
            'a',
            'object_name':
            'b',
            'object_id':
            'c',
            'mass':
            1,
            'solar_rad_area':
            2,
            'solar_rad_coeff':
            3,
            'drag_area':
            4,
            'drag_coeff':
            5,
            'covariance': [
                0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
                18, 19, 20
            ],
            'perturbation':
            7,
            'hypercube':
            'CORNERS',
        })
        expected_opm = """CCSDS_OPM_VERS = 2.0
ORIGINATOR = a
COMMENT Cartesian coordinate system
OBJECT_NAME = b
OBJECT_ID = c
CENTER_NAME = SUN
REF_FRAME = ITRF-97
TIME_SYSTEM = UTC
EPOCH = foo
X = 1
Y = 2
Z = 3
X_DOT = 4
Y_DOT = 5
Z_DOT = 6
MASS = 1
SOLAR_RAD_AREA = 2
SOLAR_RAD_COEFF = 3
DRAG_AREA = 4
DRAG_COEFF = 5
CX_X = 0
CY_X = 1
CY_Y = 2
CZ_X = 3
CZ_Y = 4
CZ_Z = 5
CX_DOT_X = 6
CX_DOT_Y = 7
CX_DOT_Z = 8
CX_DOT_X_DOT = 9
CY_DOT_X = 10
CY_DOT_Y = 11
CY_DOT_Z = 12
CY_DOT_X_DOT = 13
CY_DOT_Y_DOT = 14
CZ_DOT_X = 15
CZ_DOT_Y = 16
CZ_DOT_Z = 17
CZ_DOT_X_DOT = 18
CZ_DOT_Y_DOT = 19
CZ_DOT_Z_DOT = 20
USER_DEFINED_ADAM_INITIAL_PERTURBATION = 7 [sigma]
USER_DEFINED_ADAM_HYPERCUBE = CORNERS"""
        # Remove the CREATION_DATE stamp since that varies.
        opm = "\n".join([
            line for line in o.generate_opm().splitlines()
            if not line.startswith('CREATION_DATE')
        ])
        self.maxDiff = None  # Otherwise if the next line fails, we can't see the diff
        self.assertEqual(expected_opm, opm)
示例#18
0
 def test_invalid_keys(self):
     with self.assertRaises(KeyError):
         OpmParams({'unrecognized': 0})
示例#19
0
    def test_required_keys(self):
        with self.assertRaises(KeyError):
            OpmParams({'epoch': 'foo'})

        with self.assertRaises(KeyError):
            OpmParams({'state_vector': []})
示例#20
0
 def test_access_state_vector(self):
     o = OpmParams({'epoch': 'foo', 'state_vector': [1, 2, 3, 4, 5, 6]})
     self.assertEqual([1, 2, 3, 4, 5, 6], o.get_state_vector())
     o.set_state_vector([6, 5, 4, 3, 2, 1])
     self.assertEqual([6, 5, 4, 3, 2, 1], o.get_state_vector())
    def test_required_keys(self):
        with self.assertRaises(KeyError):
            OpmParams({'epoch': 'foo'})

        with self.assertRaises(KeyError):
            OpmParams({'state_vector': []})

        with self.assertRaises(KeyError):
            OpmParams({
                'keplerian_elements': {
                    'semi_major_axis_km': 1,
                    'eccentricity': 2,
                    'inclination_deg': 3,
                    'ra_of_asc_node_deg': 4,
                    'arg_of_pericenter_deg': 5,
                    'true_anomaly_deg': 6,
                    'gm': 7
                }
            })

        with self.assertRaises(KeyError):
            OpmParams({
                'epoch': 'foo',
                'keplerian_elements': {
                    'semi_major_axis_km': 1,
                    'eccentricity': 2,
                    'inclination_deg': 3,
                    'ra_of_asc_node_deg': 4,
                    'arg_of_pericenter_deg': 5,
                    'true_anomaly_deg': 6,
                    # Missing gm.
                }
            })

        with self.assertRaises(KeyError):
            OpmParams({
                'epoch': 'foo',
                'keplerian_elements': {
                    'semi_major_axis_km': 1,
                    'eccentricity': 2,
                    'inclination_deg': 3,
                    'ra_of_asc_node_deg': 4,
                    'arg_of_pericenter_deg': 5,
                    'true_anomaly_deg': 6,
                    'gm': 7,
                    'extra what is this': 8
                }
            })

        # No KeyError with no state vector.
        OpmParams({
            'epoch': 'foo',
            'keplerian_elements': {
                'semi_major_axis_km': 1,
                'eccentricity': 2,
                'inclination_deg': 3,
                'ra_of_asc_node_deg': 4,
                'arg_of_pericenter_deg': 5,
                'true_anomaly_deg': 6,
                'gm': 7
            }
        })
示例#22
0
class BatchesTest(unittest.TestCase):
    """Unit tests for batches module

    """

    dummy_propagation_params = PropagationParams({
        'start_time': 'AAA',
        'end_time': 'BBB',
        'project_uuid': 'CCC'
    })
    dummy_opm_params = OpmParams({
        'epoch': 'DDD',
        'state_vector': [1, 2, 3, 4, 5, 6]
    })

    def _check_input(self, data_dict):
        """Check input data

        Checks input data by asserting the following:
            - start time = 'AAA'
            - end time = 'BBB'
            - step size = 86400 (default)
            - opm string in data dictionary is not None
            - originator = 'ADAM_User'
            - object name = 'dummy'
            - object ID = '001'
            - epoch and state vector are 'CCC' and [1, 2, 3, 4, 5, 6], respectively
            - object mass = 1000 (default)
            - object solar radiation area = 20 (default)
            - object solar radiation coefficient = 1 (default)
            - object drag area = 20 (default)
            - object drag coefficient = 2.2 (default)
            - propagator ID is default (none specified)

        Args:
            data_dict (dict) - input data for POST

        Returns:
            True
        """
        self.assertEqual(data_dict['start_time'],
                         self.dummy_propagation_params.get_start_time())
        self.assertEqual(data_dict['end_time'],
                         self.dummy_propagation_params.get_end_time())
        self.assertEqual(data_dict['project'],
                         self.dummy_propagation_params.get_project_uuid())
        self.assertEqual(data_dict['step_duration_sec'], 86400)
        self.assertEqual(data_dict['propagator_uuid'],
                         "00000000-0000-0000-0000-000000000001")
        opm = data_dict['opm_string']
        self.assertIsNotNone(opm)
        self.assertIn('ORIGINATOR = ADAM_User', opm)
        self.assertIn('OBJECT_NAME = dummy', opm)
        self.assertIn('OBJECT_ID = 001', opm)
        self.assertIn('EPOCH = DDD', opm)
        self.assertIn('X = 1', opm)
        self.assertIn('Y = 2', opm)
        self.assertIn('Z = 3', opm)
        self.assertIn('X_DOT = 4', opm)
        self.assertIn('Y_DOT = 5', opm)
        self.assertIn('Z_DOT = 6', opm)
        self.assertIn('MASS = 1000', opm)
        self.assertIn('SOLAR_RAD_AREA = 20', opm)
        self.assertIn('SOLAR_RAD_COEFF = 1', opm)
        self.assertIn('DRAG_AREA = 20', opm)
        self.assertIn('DRAG_COEFF = 2.2', opm)
        return True

    def _check_inputs(self, inputs):
        for data_dict in inputs['requests']:
            self._check_input(data_dict)
        return True

    def test_new_batch(self):
        rest = _RestProxyForTest()
        batches = Batches(rest)

        # A successful run.
        rest.expect_post("/batch", self._check_input, 200, {
            'calc_state': 'PENDING',
            'uuid': '1'
        })

        state = batches.new_batch(self.dummy_propagation_params,
                                  self.dummy_opm_params)
        self.assertEqual('1', state.get_uuid())
        self.assertEqual('PENDING', state.get_calc_state())

        # Unsuccessful run.
        rest.expect_post("/batch", self._check_input, 400, {
            'calc_state': 'PENDING',
            'uuid': '1'
        })
        with self.assertRaises(RuntimeError):
            batches.new_batch(self.dummy_propagation_params,
                              self.dummy_opm_params)

    def test_new_batches(self):
        rest = _RestProxyForTest()
        batches = Batches(rest)

        # Successful run.
        rest.expect_post(
            "/batches", self._check_inputs, 200, {
                'requests': [{
                    'calc_state': 'PENDING',
                    'uuid': '1'
                }, {
                    'calc_state': 'RUNNING',
                    'uuid': '2'
                }]
            })
        states = batches.new_batches(
            [[self.dummy_propagation_params, self.dummy_opm_params],
             [self.dummy_propagation_params, self.dummy_opm_params]])
        self.assertEqual(2, len(states))
        self.assertEqual('1', states[0].get_uuid())
        self.assertEqual('PENDING', states[0].get_calc_state())
        self.assertEqual('2', states[1].get_uuid())
        self.assertEqual('RUNNING', states[1].get_calc_state())

        # Unsuccessful run.
        rest.expect_post("/batches", self._check_inputs, 400, {})
        with self.assertRaises(RuntimeError):
            batches.new_batches(
                [[self.dummy_propagation_params, self.dummy_opm_params],
                 [self.dummy_propagation_params, self.dummy_opm_params]])

    def test_delete_batch(self):
        rest = _RestProxyForTest()
        batches = Batches(rest)

        # Successful request.
        rest.expect_delete("/batch/aaa", 204)
        batches.delete_batch('aaa')

        # 200 isn't a valid return value for delete calls right now
        rest.expect_delete("/batch/aaa", 200)
        with self.assertRaises(RuntimeError):
            batches.delete_batch('aaa')

    def test_get_summary(self):
        rest = _RestProxyForTest()
        batches = Batches(rest)

        # Successful request.
        rest.expect_get('/batch/aaa', 200, {
            'uuid': 'aaa',
            'calc_state': 'RUNNING'
        })
        summary = batches.get_summary('aaa')
        self.assertEqual('aaa', summary.get_uuid())
        self.assertEqual('RUNNING', summary.get_calc_state())

        # Successfully found missing.
        rest.expect_get('/batch/aaa', 404, 'Not JSON wat')
        self.assertIsNone(batches.get_summary('aaa'))

        # Unsuccessful request.
        rest.expect_get('/batch/aaa', 503, 'Also not JSON wat')
        with self.assertRaises(RuntimeError):
            batches.get_summary('aaa')

    def test_get_summaries(self):
        rest = _RestProxyForTest()
        batches = Batches(rest)

        # Successful request.
        rest.expect_get(
            '/batch?project_uuid=' +
            self.dummy_propagation_params.get_project_uuid(), 200, {
                'items': [{
                    'uuid': 'aaa',
                    'calc_state': 'RUNNING'
                }, {
                    'uuid': 'bbb',
                    'calc_state': 'COMPLETED'
                }, {
                    'uuid': 'ccc',
                    'calc_state': 'FAILED'
                }]
            })
        summaries = batches.get_summaries(
            self.dummy_propagation_params.get_project_uuid())
        self.assertEqual(3, len(summaries))
        self.assertEqual('aaa', summaries['aaa'].get_uuid())
        self.assertEqual('RUNNING', summaries['aaa'].get_calc_state())
        self.assertEqual('bbb', summaries['bbb'].get_uuid())
        self.assertEqual('COMPLETED', summaries['bbb'].get_calc_state())
        self.assertEqual('ccc', summaries['ccc'].get_uuid())
        self.assertEqual('FAILED', summaries['ccc'].get_calc_state())

        # Unsuccessful request.
        rest.expect_get(
            '/batch?project_uuid=' +
            self.dummy_propagation_params.get_project_uuid(), 403, {})
        with self.assertRaises(RuntimeError):
            batches.get_summaries(
                self.dummy_propagation_params.get_project_uuid())

    def test_get_propagation_results(self):
        rest = _RestProxyForTest()
        batches = Batches(rest)

        # Parts count not specified. No result retrieval is attempted.
        state = StateSummary({
            'uuid': 'aaa',
            'calc_state': 'COMPLETED',
        })
        self.assertIsNone(batches.get_propagation_results(state))

        # Parts count is 0. No result retrieval is attempted.
        state = StateSummary({
            'uuid': 'aaa',
            'calc_state': 'COMPLETED',
            'parts_count': 0,
        })
        self.assertIsNone(batches.get_propagation_results(state))

        # Normal retrieval.
        state = StateSummary({
            'uuid': 'aaa',
            'calc_state': 'COMPLETED',
            'parts_count': 2,
        })
        rest.expect_get('/batch/aaa/1', 200, {
            'part_index': 'a',
            'calc_state': 'RUNNING'
        })
        rest.expect_get('/batch/aaa/2', 200, {
            'part_index': 'z',
            'calc_state': 'COMPLETED'
        })
        results = batches.get_propagation_results(state)
        self.assertEqual(2, len(results.get_parts()))
        self.assertEqual('a', results.get_parts()[0].get_part_index())
        self.assertEqual('z', results.get_parts()[1].get_part_index())

        # Some parts could not be found.
        state = StateSummary({
            'uuid': 'aaa',
            'calc_state': 'FAILED',
            'parts_count': 3,
        })
        rest.expect_get('/batch/aaa/1', 404, 'Not json')
        rest.expect_get('/batch/aaa/2', 200, {
            'part_index': 'z',
            'calc_state': 'COMPLETED'
        })
        rest.expect_get('/batch/aaa/3', 404, 'Not json')
        results = batches.get_propagation_results(state)
        self.assertEqual(3, len(results.get_parts()))
        self.assertIsNone(results.get_parts()[0])
        self.assertEqual('z', results.get_parts()[1].get_part_index())
        self.assertIsNone(results.get_parts()[2])

        # Complete failure.
        state = StateSummary({
            'uuid': 'aaa',
            'calc_state': 'COMPLETED',
            'parts_count': 2,
        })
        rest.expect_get('/batch/aaa/1', 403, 'irrelevant')
        with self.assertRaises(RuntimeError):
            batches.get_propagation_results(state)
示例#23
0
    'project_uuid': config.get_workspace(),

#     'step_size': 60 * 60,  # step size (seconds)
#     'propagator_uuid': '00000000-0000-0000-0000-000000000002',  # force model
#     'description': 'some description'       # description of run
})
opm_params = OpmParams({
    'epoch': '2017-10-04T00:00:00Z',
    'state_vector': state_vec,
            
#     'mass': 500.5,              # object mass
#     'solar_rad_area': 25.2,     # object solar radiation area (m^2)
#     'solar_rad_coeff': 1.2,     # object solar radiation coefficient
#     'drag_area': 33.3,          # object drag area (m^2)
#     'drag_coeff': 2.5,          # object drag coefficient
    
#     'covariance': covariance,   # object covariance
#     'perturbation': 3,          # sigma perturbation on state vector
#     'hypercube': 'FACES',       # hypercube propagation type
    
#     'originator': 'Robot',      # originator of run
#     'object_name': 'TestObj',   # object name
#     'object_id': 'test1234',    # object ID
})
batch = Batch(propagation_params, opm_params)
print("Submitting OPM:")
print(batch.get_opm_params().generate_opm())

# Submit and wait until batch run is ready
batches_module = Batches(auth_rest)
BatchRunManager(batches_module, [batch]).run()
示例#24
0
    def test_from_json(self):
        self.maxDiff = None
        json1 = {
            "header": {
                "originator": "Test",
                "creation_date": "2018-06-21 16:22:20.550672"
            },
            "metadata": {
                "comments": ["Cartesian coordinate system"],
                "object_name": "TestObj",
                "object_id": "TestObjId",
                "center_name": "SUN",
                "ref_frame": "ICRF",
                "time_system": "UTC"
            },
            "spacecraft": {
                "mass": 500.5,
                "solar_rad_area": 25.2,
                "solar_rad_coeff": 1.2,
                "drag_area": 33.3,
                "drag_coeff": 2.5
            },
            "ccsds_opm_vers": "2.0",
            "state_vector": {
                "epoch": "2018-06-21T16:22:20.550561Z",
                "x": 130347560.13690618,
                "y": -74407287.6018632,
                "z": -35247598.54147063,
                "x_dot": 23.935241263310683,
                "y_dot": 27.146279819258538,
                "z_dot": 10.346605942591514
            }
        }

        expected_opm1 = """CCSDS_OPM_VERS = 2.0
CREATION_DATE = 2018-06-21 16:25:33.374936
ORIGINATOR = Test
COMMENT Cartesian coordinate system
OBJECT_NAME = TestObj
OBJECT_ID = TestObjId
CENTER_NAME = SUN
REF_FRAME = ICRF
TIME_SYSTEM = UTC
EPOCH = 2018-06-21T16:22:20.550561Z
X = 130347560.13690618
Y = -74407287.6018632
Z = -35247598.54147063
X_DOT = 23.935241263310683
Y_DOT = 27.146279819258538
Z_DOT = 10.346605942591514
MASS = 500.5
SOLAR_RAD_AREA = 25.2
SOLAR_RAD_COEFF = 1.2
DRAG_AREA = 33.3
DRAG_COEFF = 2.5"""

        expected_opm1 = OpmParamsTest.remove_non_static_fields(expected_opm1)
        opm_params1 = OpmParams.fromJsonResponse(json1)
        actual_opm1 = OpmParamsTest.remove_non_static_fields(
            opm_params1.generate_opm())

        self.assertEqual(expected_opm1, actual_opm1)

        json2 = {
            "header": {
                "originator": "Test",
                "creation_date": "2018-06-21 17:43:20.984533"
            },
            "metadata": {
                "comments": ["Cartesian coordinate system"],
                "object_name": "TestObj",
                "object_id": "TestObjId",
                "center_name": "SUN",
                "ref_frame": "ICRF",
                "time_system": "UTC"
            },
            "spacecraft": {
                "mass": 500.5,
                "solar_rad_area": 25.2,
                "solar_rad_coeff": 1.2,
                "drag_area": 33.3,
                "drag_coeff": 2.5
            },
            "maneuvers": [{
                "duration": 0.0,
                "man_epoch_ignition": "2018-06-21T17:43:20.984304Z",
                "delta_mass": 0.0,
                "man_ref_frame": "TNW",
                "man_dv_1": 1.0,
                "man_dv_2": 2.0,
                "man_dv_3": 3.0,
            }],
            "covariance": {
                "cx_x": 0.0003331349476038534,
                "cy_x": 0.0004618927349220216,
                "cy_y": 0.0006782421679971363,
                "cz_x": -0.0003070007847730449,
                "cz_y": -0.0004221234189514228,
                "cz_z": 0.0003231931992380369,
                "cx_dot_x": -3.34936503392263e-07,
                "cx_dot_y": -4.686084221046758e-07,
                "cx_dot_z": 2.484949578400095e-07,
                "cx_dot_x_dot": 4.29602280558729e-10,
                "cy_dot_x": -2.211832501084875e-07,
                "cy_dot_y": -2.864186892102733e-07,
                "cy_dot_z": 1.798098699846038e-07,
                "cy_dot_x_dot": 2.608899201686016e-10,
                "cy_dot_y_dot": 1.767514756338532e-10,
                "cz_dot_x": -3.041346050686871e-07,
                "cz_dot_y": -4.989496988610662e-07,
                "cz_dot_z": 3.540310904497689e-07,
                "cz_dot_x_dot": 1.86926319295459e-10,
                "cz_dot_y_dot": 1.008862586240695e-10,
                "cz_dot_z_dot": 6.2244443386355e-10
            },
            "adam_fields": [{
                "key": "INITIAL_PERTURBATION",
                "value": "3"
            }, {
                "key": "HYPERCUBE",
                "value": "FACES"
            }],
            "ccsds_opm_vers":
            "2.0",
            "state_vector": {
                "epoch": "2018-06-21T17:43:20.984304Z",
                "x": 130347560.13690618,
                "y": -74407287.6018632,
                "z": -35247598.54147063,
                "x_dot": 23.935241263310683,
                "y_dot": 27.146279819258538,
                "z_dot": 10.346605942591514
            }
        }

        expected_opm2 = """CCSDS_OPM_VERS = 2.0
CREATION_DATE = 2018-06-21 17:43:20.984372
ORIGINATOR = Test
COMMENT Cartesian coordinate system
OBJECT_NAME = TestObj
OBJECT_ID = TestObjId
CENTER_NAME = SUN
REF_FRAME = ICRF
TIME_SYSTEM = UTC
EPOCH = 2018-06-21T17:43:20.984304Z
X = 130347560.13690618
Y = -74407287.6018632
Z = -35247598.54147063
X_DOT = 23.935241263310683
Y_DOT = 27.146279819258538
Z_DOT = 10.346605942591514
MASS = 500.5
SOLAR_RAD_AREA = 25.2
SOLAR_RAD_COEFF = 1.2
DRAG_AREA = 33.3
DRAG_COEFF = 2.5
CX_X = 0.0003331349476038534
CY_X = 0.0004618927349220216
CY_Y = 0.0006782421679971363
CZ_X = -0.0003070007847730449
CZ_Y = -0.0004221234189514228
CZ_Z = 0.0003231931992380369
CX_DOT_X = -3.34936503392263e-07
CX_DOT_Y = -4.686084221046758e-07
CX_DOT_Z = 2.484949578400095e-07
CX_DOT_X_DOT = 4.29602280558729e-10
CY_DOT_X = -2.211832501084875e-07
CY_DOT_Y = -2.864186892102733e-07
CY_DOT_Z = 1.798098699846038e-07
CY_DOT_X_DOT = 2.608899201686016e-10
CY_DOT_Y_DOT = 1.767514756338532e-10
CZ_DOT_X = -3.041346050686871e-07
CZ_DOT_Y = -4.989496988610662e-07
CZ_DOT_Z = 3.540310904497689e-07
CZ_DOT_X_DOT = 1.86926319295459e-10
CZ_DOT_Y_DOT = 1.008862586240695e-10
CZ_DOT_Z_DOT = 6.2244443386355e-10
USER_DEFINED_ADAM_INITIAL_PERTURBATION = 3 [sigma]
USER_DEFINED_ADAM_HYPERCUBE = FACES
MAN_EPOCH_IGNITION = 2018-06-21T17:43:20.984304Z
MAN_DURATION = 0.0
MAN_DELTA_MASS = 0.0
MAN_REF_FRAME = TNW
MAN_DV_1 = 1.0
MAN_DV_2 = 2.0
MAN_DV_3 = 3.0"""

        expected_opm2 = OpmParamsTest.remove_non_static_fields(expected_opm2)
        opm_params2 = OpmParams.fromJsonResponse(json2)
        actual_opm2 = OpmParamsTest.remove_non_static_fields(
            opm_params2.generate_opm())

        self.assertEqual(expected_opm2, actual_opm2)

        json3 = {
            "header": {
                "originator": "Test",
                "creation_date": "2018-06-21 17:56:58.406867"
            },
            "metadata": {
                "comments": ["Cartesian coordinate system"],
                "object_name": "TestObj",
                "object_id": "TestObjId",
                "center_name": "SUN",
                "ref_frame": "ICRF",
                "time_system": "UTC"
            },
            "keplerian": {
                "eccentricity": 0.5355029800000188,
                "inclination": 23.439676743246295,
                "gm": 132712440041.9394,
                "semi_major_axis": 313072891.38037175,
                "mean_motion": 0.0,
                "ra_of_asc_node": 359.9942693176405,
                "arg_of_pericenter": 328.5584374618295,
                "true_anomaly": -127.01778914927144,
                "mean_anomaly": 0.0
            },
            "spacecraft": {
                "mass": 500.5,
                "solar_rad_area": 25.2,
                "solar_rad_coeff": 1.2,
                "drag_area": 33.3,
                "drag_coeff": 2.5
            },
            "ccsds_opm_vers": "2.0",
            "state_vector": {
                "epoch": "2018-06-21T17:56:58.406556Z",
                "x": 0.0,
                "y": 0.0,
                "z": 0.0,
                "x_dot": 0.0,
                "y_dot": 0.0,
                "z_dot": 0.0
            }
        }

        expected_opm3 = """CCSDS_OPM_VERS = 2.0
CREATION_DATE = 2018-06-21 17:56:58.406717
ORIGINATOR = Test
COMMENT Cartesian coordinate system
OBJECT_NAME = TestObj
OBJECT_ID = TestObjId
CENTER_NAME = SUN
REF_FRAME = ICRF
TIME_SYSTEM = UTC
EPOCH = 2018-06-21T17:56:58.406556Z
X = 0.0
Y = 0.0
Z = 0.0
X_DOT = 0.0
Y_DOT = 0.0
Z_DOT = 0.0
SEMI_MAJOR_AXIS = 313072891.38037175
ECCENTRICITY = 0.5355029800000188
INCLINATION = 23.439676743246295
RA_OF_ASC_NODE = 359.9942693176405
ARG_OF_PERICENTER = 328.5584374618295
TRUE_ANOMALY = -127.01778914927144
GM = 132712440041.9394
MASS = 500.5
SOLAR_RAD_AREA = 25.2
SOLAR_RAD_COEFF = 1.2
DRAG_AREA = 33.3
DRAG_COEFF = 2.5"""

        expected_opm3 = OpmParamsTest.remove_non_static_fields(expected_opm3)
        opm_params3 = OpmParams.fromJsonResponse(json3)
        actual_opm3 = OpmParamsTest.remove_non_static_fields(
            opm_params3.generate_opm())

        self.assertEqual(expected_opm3, actual_opm3)
class TargetedPropagationsTest(unittest.TestCase):
    """Unit tests for TargetedPropagations module

    """

    @classmethod
    def remove_non_static_fields(cls, opm_string):
        # Remove the CREATION_DATE stamp since that varies.
        return "\n".join([line for line in opm_string.splitlines()
                          if not line.startswith('CREATION_DATE')])

    dummy_propagation_params = PropagationParams({
        'start_time': 'AAA',
        'end_time': 'BBB',
    })
    dummy_opm_params = OpmParams({
        'epoch': 'DDD',
        'state_vector': [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
    })
    dummy_targeting_params = TargetingParams({
        'target_distance_from_earth': 123
    })
    dummy_opm_params_as_api_response = {
        "header": {
            "originator": "ADAM_User",
            "creation_date": "2018-06-21 19:13:27.261813"
        },
        "metadata": {
            "comments": [
                "Cartesian coordinate system"
            ],
            "object_name": "dummy",
            "object_id": "001",
            "center_name": "SUN",
            "ref_frame": "ICRF",
            "time_system": "UTC"
        },
        "spacecraft": {
            "mass": 1000.0,
            "solar_rad_area": 20.0,
            "solar_rad_coeff": 1.0,
            "drag_area": 20.0,
            "drag_coeff": 2.2
        },
        "ccsds_opm_vers": "2.0",
        "state_vector": {
            "epoch": "DDD",
            "x": 1.0,
            "y": 2.0,
            "z": 3.0,
            "x_dot": 4.0,
            "y_dot": 5.0,
            "z_dot": 6.0
        }
    }

    def test_insert_targeted_propagation(self):
        dummy_rest = {'not': 'used'}
        targeted_props = TargetedPropagations(dummy_rest)

        # Override AdamObjects._insert to just dump out a copy of the data passed.
        passed_data = []

        def store_data(self, data, passed_data=passed_data):
            passed_data.append(data)
            return 'uuid'
        tmp_insert = AdamObjects._insert
        AdamObjects._insert = store_data

        prop = TargetedPropagation(
            self.dummy_propagation_params,
            self.dummy_opm_params,
            self.dummy_targeting_params)
        targeted_props.insert(prop, 'project_uuid')
        uuid = prop.get_uuid()

        self.assertEqual('uuid', uuid)

        self.assertEqual(
            self.dummy_propagation_params.get_description(),
            passed_data[0]['description'])

        passed_prop_params = passed_data[0]['initialPropagationParameters']
        self.assertEqual(
            self.dummy_propagation_params.get_start_time(),
            passed_prop_params['start_time'])
        self.assertEqual(
            self.dummy_propagation_params.get_end_time(),
            passed_prop_params['end_time'])
        self.assertEqual(
            self.dummy_propagation_params.get_propagator_uuid(),
            passed_prop_params['propagator_uuid'])
        self.assertEqual(
            self.dummy_propagation_params.get_step_size(),
            passed_prop_params['step_duration_sec'])

        self.assertEqual(
            TargetedPropagationsTest.remove_non_static_fields(
                self.dummy_opm_params.generate_opm()),
            TargetedPropagationsTest.remove_non_static_fields(
                passed_prop_params['opmFromString']))

        passed_targeting_params = passed_data[0]['targetingParameters']
        self.assertEqual(self.dummy_targeting_params.get_target_distance_from_earth(),
                         passed_targeting_params['targetDistanceFromEarth'])
        self.assertEqual(self.dummy_targeting_params.get_tolerance(),
                         passed_targeting_params['tolerance'])
        self.assertEqual(self.dummy_targeting_params.get_run_nominal_only(),
                         passed_targeting_params['runNominalOnly'])

        self.assertEqual('project_uuid', passed_data[0]['project'])

        AdamObjects._insert = tmp_insert

    def test_get_targeted_propagation(self):
        dummy_rest = {'not': 'used'}
        targeted_props = TargetedPropagations(dummy_rest)

        return_data = {
            "uuid": "uuid",
            "initialPropagationParameters": {
                "start_time": "AAA",
                "end_time": "BBB",
                "step_duration_sec": "0",
                "propagator_uuid": "00000000-0000-0000-0000-000000000001",
                "executor": "stk",
                "opm": {
                    "header": {
                        "originator": "ADAM_User",
                        "creation_date": "2018-06-21 19:28:47.304102"
                    },
                    "metadata": {
                        "comments": [
                            "Cartesian coordinate system"
                        ],
                        "object_name": "dummy",
                        "object_id": "001",
                        "center_name": "SUN",
                        "ref_frame": "ICRF",
                        "time_system": "UTC"
                    },
                    "spacecraft": {
                        "mass": 1000.0,
                        "solar_rad_area": 20.0,
                        "solar_rad_coeff": 1.0,
                        "drag_area": 20.0,
                        "drag_coeff": 2.2
                    },
                    "ccsds_opm_vers": "2.0",
                    "state_vector": {
                        "epoch": "DDD",
                        "x": 1.0,
                        "y": 2.0,
                        "z": 3.0,
                        "x_dot": 4.0,
                        "y_dot": 5.0,
                        "z_dot": 6.0
                    }
                }
            },
            "targetingParameters": {
                "targetDistanceFromEarth": 123.0,
                "tolerance": 1.0,
                "runNominalOnly": False
            },
            "description": "Created by test at 2018-06-21 19:28:47.303980Z",
            "maneuverX": 0.0,
            "maneuverY": 0.0,
            "maneuverZ": 0.0
        }

        def return_data(self, uuid, return_data=return_data):
            return return_data
        tmp_get_json = AdamObjects._get_json
        AdamObjects._get_json = return_data

        targeted_prop = targeted_props.get('uuid')

        self.assertEqual('uuid', targeted_prop.get_uuid())

        self.assertEqual(self.dummy_propagation_params.get_start_time(),
                         targeted_prop.get_propagation_params().get_start_time())
        self.assertEqual(self.dummy_propagation_params.get_end_time(),
                         targeted_prop.get_propagation_params().get_end_time())

        self.assertEqual(
            TargetedPropagationsTest.remove_non_static_fields(
                self.dummy_opm_params.generate_opm()),
            TargetedPropagationsTest.remove_non_static_fields(
                targeted_prop.get_opm_params().generate_opm()))

        self.assertEqual(self.dummy_targeting_params.get_target_distance_from_earth(),
                         targeted_prop.get_targeting_params().get_target_distance_from_earth())

        self.assertIsNone(targeted_prop.get_ephemeris())
        self.assertEqual([0, 0, 0], targeted_prop.get_maneuver())

        AdamObjects._get_json = tmp_get_json
示例#26
0
class BatchPropagationsTest(unittest.TestCase):
    """Unit tests for BatchPropagations module

    """
    @classmethod
    def remove_non_static_fields(cls, opm_string):
        # Remove the CREATION_DATE stamp since that varies.
        return "\n".join([
            line for line in opm_string.splitlines()
            if not line.startswith('CREATION_DATE')
        ])

    dummy_propagation_params = PropagationParams({
        'start_time': 'AAA',
        'end_time': 'BBB',
    })
    dummy_opm_params = OpmParams({
        'epoch': 'DDD',
        'state_vector': [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
    })
    dummy_opm_params_as_api_response = {
        "header": {
            "originator": "ADAM_User",
            "creation_date": "2018-06-21 19:13:27.261813"
        },
        "metadata": {
            "comments": ["Cartesian coordinate system"],
            "object_name": "dummy",
            "object_id": "001",
            "center_name": "SUN",
            "ref_frame": "ICRF",
            "time_system": "UTC"
        },
        "spacecraft": {
            "mass": 1000.0,
            "solar_rad_area": 20.0,
            "solar_rad_coeff": 1.0,
            "drag_area": 20.0,
            "drag_coeff": 2.2
        },
        "ccsds_opm_vers": "2.0",
        "state_vector": {
            "epoch": "DDD",
            "x": 1.0,
            "y": 2.0,
            "z": 3.0,
            "x_dot": 4.0,
            "y_dot": 5.0,
            "z_dot": 6.0
        }
    }

    def test_create_batch_propagation(self):
        dummy_rest = {'not': 'used'}
        batch_props = BatchPropagations(dummy_rest)

        # Override AdamObjects._insert to just dump out a copy of the data passed.
        passed_data = []

        def store_data(self, data, passed_data=passed_data):
            passed_data.append(data)
            return 'uuid'

        tmp_insert = AdamObjects._insert
        AdamObjects._insert = store_data

        batch_prop = BatchPropagation(self.dummy_propagation_params,
                                      self.dummy_opm_params)
        batch_props.insert(batch_prop, 'project_uuid')
        uuid = batch_prop.get_uuid()

        self.assertEqual('uuid', uuid)

        self.assertEqual(self.dummy_propagation_params.get_description(),
                         passed_data[0]['description'])

        passed_prop_params = passed_data[0]['templatePropagationParameters']
        self.assertEqual(self.dummy_propagation_params.get_start_time(),
                         passed_prop_params['start_time'])
        self.assertEqual(self.dummy_propagation_params.get_end_time(),
                         passed_prop_params['end_time'])
        self.assertEqual(self.dummy_propagation_params.get_propagator_uuid(),
                         passed_prop_params['propagator_uuid'])
        self.assertEqual(self.dummy_propagation_params.get_step_size(),
                         passed_prop_params['step_duration_sec'])

        self.assertEqual(
            BatchPropagationsTest.remove_non_static_fields(
                self.dummy_opm_params.generate_opm()),
            BatchPropagationsTest.remove_non_static_fields(
                passed_prop_params['opmFromString']))

        self.assertEqual('project_uuid', passed_data[0]['project'])

        AdamObjects._insert = tmp_insert

    def test_get_batch_propagation(self):
        dummy_rest = {'not': 'used'}
        batch_props = BatchPropagations(dummy_rest)

        return_data = {
            "uuid":
            "uuid",
            "templatePropagationParameters": {
                "start_time": "AAA",
                "end_time": "BBB",
                "step_duration_sec": "0",
                "propagator_uuid": "00000000-0000-0000-0000-000000000001",
                "executor": "stk",
                "opm": {
                    "header": {
                        "originator": "ADAM_User",
                        "creation_date": "2018-06-21 19:28:47.304102"
                    },
                    "metadata": {
                        "comments": ["Cartesian coordinate system"],
                        "object_name": "dummy",
                        "object_id": "001",
                        "center_name": "SUN",
                        "ref_frame": "ICRF",
                        "time_system": "UTC"
                    },
                    "spacecraft": {
                        "mass": 1000.0,
                        "solar_rad_area": 20.0,
                        "solar_rad_coeff": 1.0,
                        "drag_area": 20.0,
                        "drag_coeff": 2.2
                    },
                    "ccsds_opm_vers": "2.0",
                    "state_vector": {
                        "epoch": "DDD",
                        "x": 1.0,
                        "y": 2.0,
                        "z": 3.0,
                        "x_dot": 4.0,
                        "y_dot": 5.0,
                        "z_dot": 6.0
                    }
                }
            },
            "summary":
            "1000 2000 3000 4000 5000 6000 7000\n7000 6000 5000 4000 3000 2000 1000"
        }

        def return_data(self, uuid, return_data=return_data):
            return return_data

        tmp_get_json = AdamObjects._get_json
        AdamObjects._get_json = return_data

        batch_prop = batch_props.get('uuid')

        self.assertEqual('uuid', batch_prop.get_uuid())

        self.assertEqual(self.dummy_propagation_params.get_start_time(),
                         batch_prop.get_propagation_params().get_start_time())
        self.assertEqual(self.dummy_propagation_params.get_end_time(),
                         batch_prop.get_propagation_params().get_end_time())

        self.assertEqual(
            BatchPropagationsTest.remove_non_static_fields(
                self.dummy_opm_params.generate_opm()),
            BatchPropagationsTest.remove_non_static_fields(
                batch_prop.get_opm_params().generate_opm()))

        self.assertEqual(
            '1000 2000 3000 4000 5000 6000 7000\n7000 6000 5000 4000 3000 2000 1000',
            batch_prop.get_summary())
        self.assertEqual([[1, 2, 3, 4, 5, 6, 7], [7, 6, 5, 4, 3, 2, 1]],
                         batch_prop.get_final_state_vectors())

        AdamObjects._get_json = tmp_get_json
示例#27
0
    def test_basic_stm(self):
        state_vec = [
            130347560.13690618, -74407287.6018632, -35247598.541470632,
            23.935241263310683, 27.146279819258538, 10.346605942591514
        ]

        start_time = datetime.datetime(2017, 10, 4, 0, 0, 0, 123456)
        end_time = datetime.datetime(2018, 10, 4, 0, 0, 0, 123456)

        propagation_params = PropagationParams({
            'start_time':
            start_time.isoformat() + 'Z',
            'end_time':
            end_time.isoformat() + 'Z',
            'project_uuid':
            self.working_project.get_uuid(),
            'description':
            'Created by test at ' + start_time.isoformat() + 'Z'
        })

        opm_params = OpmParams({
            'epoch': start_time.isoformat() + 'Z',
            'state_vector': state_vec,
        })

        end_state, stm = self.stm_module.run_stm_propagation(
            propagation_params, opm_params)

        # Taken from printed output of ../state_stm_propagation.py
        expected_end_state = np.array([
            -37523497.931654416, 492950622.8491298, 204482176.63445434,
            -11.336957217854795, 7.18499733419028, 3.3597496059480085
        ])
        expected_stm = np.matrix(
            [[
                9.70874844e+00, -1.21563565e+00, -9.26967637e-01,
                5.34214567e+07, 1.64329953e+07, 5.30094892e+06
            ],
             [
                 7.11171945e+00, -3.24202476e+00, -5.93038128e-01,
                 3.90278376e+07, 3.82420496e+07, 9.62761631e+06
             ],
             [
                 2.50503331e+00, -3.00334152e-01, -2.62144498e+00,
                 1.46131045e+07, 1.04218322e+07, 1.53347450e+07
             ],
             [
                 2.14264136e-07, -2.82295666e-08, -2.23357566e-08,
                 1.33259336e+00, 6.98930318e-01, 2.41824966e-01
             ],
             [
                 4.69172199e-07, -2.03571494e-07, -6.32223023e-08,
                 2.52995851e+00, 2.04570983e+00, 7.47014439e-01
             ],
             [
                 1.82661672e-07, -4.57388872e-08, -1.15455121e-07,
                 9.96459361e-01, 8.11376173e-01, 3.16765622e-01
             ]])

        npt.assert_allclose(expected_end_state,
                            np.array(end_state),
                            rtol=1e-8,
                            atol=0)
        npt.assert_allclose(expected_stm.getA(), stm.getA(), rtol=1e-8, atol=0)