コード例 #1
0
async def simulation_timepulse_propagate(message, nats_handler, shared_storage,
                                         logger):
    """
    Propagates the satellites current orbit and attitude

    Args:
        message (natsmessage): message
            message.data dictionary with structure as described in message_structure.json
            message.data["time"] is the time update
        nats_handler (natsHandler): distributes callbacks according to the message subject
        shared_storage: dictionary containing information on on the entire swarm, the time, and the particular satellites phonebook
    """
    # Distance that will prevent satellites from communicating
    max_range = shared_storage["range"]

    # Updating time
    shared_storage["time"] = message.data["time"]

    cubesat_id = nats_handler.sender_id

    #  Making a propagator for satellite running this service
    self_orbit_propagator = orekit_utils.analytical_propagator(
        shared_storage["swarm"][cubesat_id]["orbit"])

    # Each satellite's state will be upated and the phonebook will be updated
    for satellite in shared_storage["swarm"]:
        # Info about each satellite state is accessed to propagate orbit and attitude
        orbit_propagator = orekit_utils.analytical_propagator(
            shared_storage["swarm"][satellite]["orbit"])
        attitude = shared_storage["swarm"][satellite]["orbit"]["attitude"]
        attitude_param = dict()
        frame = shared_storage["swarm"][satellite]["orbit"]["frame"]

        # Info about satellite attitude is accessed
        if attitude in shared_storage["swarm"]:
            attitude_provider_type = orekit_utils.utils.MOVING_BODY_TRACKING
            attitude_param = shared_storage["swarm"][attitude]["orbit"]

        elif attitude in shared_storage["grstns"]:
            attitude_provider_type = orekit_utils.utils.GROUND_TRACKING
            attitude_param = shared_storage["grstns"][attitude]["location"]

        elif attitude in shared_storage["iots"]:
            attitude_provider_type = orekit_utils.utils.GROUND_TRACKING
            attitude_param = shared_storage["iots"][attitude]["location"]

        elif attitude == orekit_utils.utils.NADIR_TRACKING:
            attitude_provider_type = attitude
        else:
            raise Exception("attitude unknown")

        # storing/updating reference frame
        attitude_param["frame"] = frame

        # constructing a attitude provider from info gathered above
        attitude_provider = orekit_utils.attitude_provider_constructor(
            attitude_provider_type, attitude_param)

        # the orbit propagator and attitude provider are consolidated
        orbit_propagator.setAttitudeProvider(attitude_provider)

        time = orekit_utils.absolute_time_converter_utc_string(
            shared_storage["time"])

        # new satellite state containg attitude and orbit info
        new_state = orbit_propagator.propagate(time)

        # the shared storage is updated as necessary
        shared_storage["swarm"][satellite][
            "orbit"] = orekit_utils.get_keplerian_parameters(new_state)
        shared_storage["swarm"][satellite]["orbit"].update({"frame": frame})
        shared_storage["swarm"][satellite]["orbit"].update(
            {"attitude": attitude})
        shared_storage["swarm"][satellite][
            "last_update_time"] = shared_storage["time"]

        # Checking if the satellites target is in view and upating shared storage accordingly
        if attitude_provider_type == orekit_utils.utils.GROUND_TRACKING:
            shared_storage["swarm"][satellite][
                "target_in_view"] = orekit_utils.check_iot_in_range(
                    orbit_propagator, attitude_param["latitude"],
                    attitude_param["longitude"], attitude_param["altitude"],
                    time)
        elif attitude_provider_type == orekit_utils.utils.NADIR_TRACKING:
            shared_storage["swarm"][satellite]["target_in_view"] = True

        elif attitude_provider_type == orekit_utils.utils.MOVING_BODY_TRACKING:
            tracked_propagator = orekit_utils.analytical_propagator(
                attitude_param)
            shared_storage["swarm"][satellite][
                "target_in_view"] = orekit_utils.visible_above_horizon(
                    orbit_propagator, tracked_propagator, time)
        else:
            raise Exception("attitude_provider unknown")

        # Updating phonebook based on the location of the satellites
        if satellite != cubesat_id:
            cur_orbit_propagator = orekit_utils.analytical_propagator(
                shared_storage["swarm"][satellite]["orbit"])

            time = orekit_utils.absolute_time_converter_utc_string(
                shared_storage["time"])

            distance = orekit_utils.find_sat_distance(self_orbit_propagator,
                                                      cur_orbit_propagator,
                                                      time)

            if distance < max_range and orekit_utils.visible_above_horizon(
                    self_orbit_propagator, cur_orbit_propagator, time):
                shared_storage["sat_phonebook"][satellite] = True
            else:
                shared_storage["sat_phonebook"][satellite] = False

    # Message contaning data on the updated state of a satellite is sent for each sent
    for sat_id in shared_storage["swarm"]:
        msg = nats_handler.create_message(
            {"state": {
                sat_id: shared_storage["swarm"][sat_id]
            }}, MessageSchemas.STATE_MESSAGE)
        subject = "state"
        await nats_handler.send_message(subject, msg)

    # The satellites updated phonebook is sent
    sat_phonebook_message = nats_handler.create_message(
        shared_storage["sat_phonebook"], MessageSchemas.PHONEBOOK_MESSAGE)
    await nats_handler.send_message("internal.phonebook",
                                    sat_phonebook_message)

    # IOT PHONEBOOK UPDATER
    for iot_id in shared_storage["iots"]:
        latitude = shared_storage["iots"][iot_id]["location"]["latitude"]
        longitude = shared_storage["iots"][iot_id]["location"]["longitude"]
        altitude = shared_storage["iots"][iot_id]["location"]["altitude"]

        if orekit_utils.check_iot_in_range(
                self_orbit_propagator, latitude, longitude, altitude,
                orekit_utils.absolute_time_converter_utc_string(
                    shared_storage["time"])):
            shared_storage["iot_phonebook"][iot_id] = True
        else:
            shared_storage["iot_phonebook"][iot_id] = False
    # Sending updated phonebook
    iot_phonebook_message = nats_handler.create_message(
        shared_storage["iot_phonebook"], MessageSchemas.PHONEBOOK_MESSAGE)
    await nats_handler.send_message("internal.iot_phonebook",
                                    iot_phonebook_message)

    #Groundstation Phonebook Updater
    for ground_id in shared_storage["grstns"]:
        latitude = shared_storage["grstns"][ground_id]["location"]["latitude"]
        longitude = shared_storage["grstns"][ground_id]["location"][
            "longitude"]
        altitude = shared_storage["grstns"][ground_id]["location"]["altitude"]
        if orekit_utils.check_iot_in_range(
                self_orbit_propagator, latitude, longitude, altitude,
                orekit_utils.absolute_time_converter_utc_string(
                    shared_storage["time"])):
            shared_storage["grstn_phonebook"][ground_id] = True
        else:
            shared_storage["grstn_phonebook"][ground_id] = False
    # Sending updated phonebook
    grstn_phonebook_message = nats_handler.create_message(
        shared_storage["grstn_phonebook"], MessageSchemas.PHONEBOOK_MESSAGE)
    await nats_handler.send_message("internal.grnst_phonebook",
                                    grstn_phonebook_message)
コード例 #2
0
    def test_attitude_provider_constructor(self):
        """
        attitude_provider_constructor test
        """
        moving_body = "moving_body_tracking"
        moving_body_param = {
                    "eccentricity": 0.0008641,
                    "semimajor_axis": 6801395.04,
                    "inclination": 87.0,
                    "perigee_argument": 10.0,
                    "right_ascension_of_ascending_node": 10.0,
                    "anomaly": 0.0,
                    "anomaly_type": "TRUE",
                    "orbit_update_date":"2021-12-02T00:00:00.000",
                    "frame": "EME"}

        orbit_params = {
                    "eccentricity": 0.0008641,
                    "semimajor_axis": 6801395.04,
                    "inclination": 87.0,
                    "perigee_argument": 20.0,
                    "right_ascension_of_ascending_node": 10.0,
                    "anomaly": 0.0,
                    "anomaly_type": "TRUE",
                    "orbit_update_date":'2021-12-02T00:00:00.000',
                    "frame": "EME"}

        orbit_propagator_1 = analytical_propagator(orbit_params)
        orbit_propagator_2 = analytical_propagator(orbit_params)

        attitude_m_body = attitude_provider_constructor(moving_body, moving_body_param)
        attitude_m_body_1 = moving_body_pointing_law(analytical_propagator(moving_body_param),moving_body_param)

        orbit_propagator_1.setAttitudeProvider(attitude_m_body)
        orbit_propagator_2.setAttitudeProvider(attitude_m_body_1)

        time_to_propagate = orekit_utils.absolute_time_converter_utc_string('2022-05-02T00:00:00.000')

        state_1 = orbit_propagator_1.propagate(time_to_propagate)
        state_2 = orbit_propagator_2.propagate(time_to_propagate)

        self.assertTrue((state_1.getAttitude().getSpin().toString() == state_2.getAttitude().getSpin().toString()))

        ground = "ground_tracking"
        ground_param = {
            "latitude": 12.0,
            "altitude": 2343.0,
            "longitude":12.0
            }
        parameters = {
                    "eccentricity": 0.0008641,
                    "semimajor_axis": 6801395.04,
                    "inclination": 87.0,
                    "perigee_argument": 10.0,
                    "right_ascension_of_ascending_node": 10.0,
                    "anomaly": radians(0.0),
                    "anomaly_type": "TRUE",
                    "orbit_update_date":'2021-12-02T00:00:00.000',
                    "frame": "EME"}

        orbit_propagator_1 = analytical_propagator(parameters)
        orbit_propagator_2 = analytical_propagator(parameters)
        ground_param["frame"] = orekit_utils.frame_to_string(orbit_propagator_1.getFrame())

        attitude_provider_1 = attitude_provider_constructor(ground, ground_param)
        attitude_provider_2 = ground_pointing_law(ground_param)

        orbit_propagator_1.setAttitudeProvider(attitude_provider_1)
        orbit_propagator_2.setAttitudeProvider(attitude_provider_2)

        time_to_propagate = orekit_utils.absolute_time_converter_utc_string('2022-05-02T00:00:00.000')
        state_1 = orbit_propagator_1.propagate(time_to_propagate)
        state_2 = orbit_propagator_2.propagate(time_to_propagate)

        self.assertTrue((state_1.getAttitude().getSpin().toString() == state_2.getAttitude().getSpin().toString()))
コード例 #3
0
    async def test_simulation_timepulse_propagate(self):
        """
        Test the simulation_timepulse_propagate() callback
        """
        # Creating variables that will be used as arguments for the callback
        logger = FakeLogger()
        loop = asyncio.get_running_loop()
        nats = FakeNatsHandler("cubesat_1",
                               "4222",
                               loop=loop,
                               user="******",
                               password="******")
        await nats.connect()

        # opening a file that contains a sample shared storage
        f = open("test_orbits_config.json")
        shared_storage = json.load(f)

        # Testing the callback across mulitple timesteps
        for i in range(10, 59):
            # creating sample data
            data = {
                "sender_ID": "cubesat_2",
                "time_sent": "2021-12-05T00:" + str(i) + ":00.000",
                "data": {
                    "time": "2021-12-05T00:" + str(i) + ":00.000"
                }
            }

            orbit_1 = shared_storage["swarm"]["cubesat_1"]["orbit"]
            orbit_2 = shared_storage["swarm"]["cubesat_2"]["orbit"]

            attitude_provider_1 = {
                "type":
                "moving_body_tracking",
                "parameters":
                shared_storage["swarm"][shared_storage["swarm"]["cubesat_1"]
                                        ["orbit"]["attitude"]]["orbit"]
            }
            attitude_provider_2 = {
                "type":
                "moving_body_tracking",
                "parameters":
                shared_storage["swarm"][shared_storage["swarm"]["cubesat_2"]
                                        ["orbit"]["attitude"]]["orbit"]
            }

            message = Message.decode_json(data,
                                          MessageSchemas.TIMESTEP_MESSAGE)
            await orbit_service.simulation_timepulse_propagate(
                message, nats, shared_storage, logger)

            time = absolute_time_converter_utc_string(data["data"]["time"])

            # Creating propagators and attitude provider from orbit configuration of satellites
            propagator_1 = orekit_utils.analytical_propagator(orbit_1)
            propagator_2 = orekit_utils.analytical_propagator(orbit_2)
            attitude_provider_1 = orekit_utils.attitude_provider_constructor(
                attitude_provider_1["type"], attitude_provider_1["parameters"])
            attitude_provider_2 = orekit_utils.attitude_provider_constructor(
                attitude_provider_2["type"], attitude_provider_2["parameters"])

            # Setting attitude and propagating the orbit
            propagator_1.setAttitudeProvider(attitude_provider_1)
            propagator_2.setAttitudeProvider(attitude_provider_2)
            state_1 = propagator_1.propagate(time)
            state_2 = propagator_2.propagate(time)

            # Updating param
            cubesat_1_param = orekit_utils.get_keplerian_parameters(state_1)
            cubesat_1_param.update({"attitude": "cubesat_2"})
            cubesat_1_param.update({"frame": "EME"})
            cubesat_2_param = orekit_utils.get_keplerian_parameters(state_2)
            cubesat_2_param.update({"attitude": "cubesat_1"})
            cubesat_2_param.update({"frame": "EME"})

            # Checking to see if simulation_timestep_propagate updated params correctly
            self.assertTrue(shared_storage["swarm"]["cubesat_1"]["orbit"] ==
                            cubesat_1_param)
            self.assertTrue(shared_storage["swarm"]["cubesat_2"]["orbit"] ==
                            cubesat_2_param)
            self.assertTrue(shared_storage["swarm"]["cubesat_1"]["orbit"]
                            ["attitude"] == "cubesat_2")
            self.assertTrue(shared_storage["swarm"]["cubesat_2"]["orbit"]
                            ["attitude"] == "cubesat_1")
            print(shared_storage["swarm"]["cubesat_1"]["target_in_view"])
            print(shared_storage["swarm"]["cubesat_2"]["target_in_view"])
            # Making sure that phonebook gets updated properly
            if i <= 48:
                self.assertTrue(shared_storage["sat_phonebook"]["cubesat_2"])
                self.assertTrue(
                    shared_storage["swarm"]["cubesat_2"]["target_in_view"])
            else:
                self.assertFalse(shared_storage["sat_phonebook"]["cubesat_2"])
                self.assertFalse(
                    shared_storage["swarm"]["cubesat_2"]["target_in_view"])