def test_get_keplerian_parameters(self): """ get_keplerian_parameters test """ parameters = { "eccentricity": 0.0008641, "semimajor_axis": 6801395.04, "inclination": radians(87.0), "perigee_argument": radians(20.0), "right_ascension_of_ascending_node": radians(10.0), "anomaly": radians(0.0), "anomaly_type": "TRUE", "orbit_update_date":'2021-12-02T00:00:00.000', "frame": "EME"} propagator_1 = analytical_propagator(parameters) orbit = keplerian_orbit(parameters) new_state = SpacecraftState(orbit) new_parameters = orekit_utils.get_keplerian_parameters(new_state) propagator_2 = keplerian_orbit(new_parameters) new_time = absolute_time_converter_utc_string('2021-12-05T00:00:00.000') distance = orekit_utils.find_sat_distance(propagator_1, propagator_2, new_time) # parameters value change but define same orbit self.assertTrue(distance <= 0.000001)
def test_find_sat_distance(self): """ find_distance tests: test some well known distances and zero cases """ tle_line1 = "1 25544U 98067A 20174.66385417 .00000447 00000-0 16048-4 0 9992" tle_line2 = "2 25544 51.6446 321.3575 0002606 75.8243 105.9183 15.49453790232862" tle2_line1 = "1 44235U 19029A 20178.58335648 .01685877 00000-0 31131-1 0 9991" tle2_line2 = "2 44235 52.9995 164.3403 0009519 291.6111 354.0622 15.45232749 61668" prop1 = orekit_utils.str_tle_propagator(tle_line1, tle_line2) prop2 = orekit_utils.str_tle_propagator(tle2_line1, tle2_line2) time = orekit_utils.absolute_time_converter_utc_string('2020-12-02T00:00:00.000') self.assertEqual(orekit_utils.find_sat_distance(prop1,prop2,time),orekit_utils.find_sat_distance(prop1,prop2,time)) self.assertEqual(orekit_utils.find_sat_distance(prop1,prop1,time),0.) self.assertEqual(orekit_utils.find_sat_distance(prop2,prop2,time),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)