def test_visible_above_horizon(self): """ visible_above_horizon test """ #equitorial orbit tle_line1 = "1 44235U 19029A 20178.66667824 .02170155 00000-0 40488-1 0 9998" tle_line2 = "2 44235 00.0000 163.9509 0005249 306.3756 83.0170 15.45172567 61683" #high inclination orbit tle2_line1 = "1 44235U 19029A 20178.66667824 .02170155 00000-0 40488-1 0 9998" tle2_line2 = "2 44235 70.0000 163.9509 0005249 306.3756 83.0170 15.45172567 61683" prop1 = orekit_utils.str_tle_propagator(tle_line1, tle_line2) prop2 = orekit_utils.str_tle_propagator(tle2_line1, tle2_line2) time = AbsoluteDate(2020, 6, 26, 1, 40, 00.000, TimeScalesFactory.getUTC()) #verified with graphing overviews self.assertFalse(orekit_utils.visible_above_horizon( prop1, prop2, time)) self.assertTrue( orekit_utils.visible_above_horizon(prop1, prop2, time.shiftedBy(60. * 10.))) self.assertTrue( orekit_utils.visible_above_horizon( prop1, prop2, time.shiftedBy(60. * 10. + 45. * 60.))) time_period_visible = orekit_utils.visible_above_horizon( prop1, prop2, time, 60 * 30)[0] self.assertTrue( time.shiftedBy(60. * 10.).isBetween(time_period_visible[0], time_period_visible[1]))
def test_check_iot_in_range(self): """ check_iot_in_range test """ tle_line1 = "1 44235U 19029A 20178.66667824 .02170155 00000-0 40488-1 0 9998" tle_line2 = "2 44235 00.0000 163.9509 0005249 306.3756 270.0170 15.45172567 61683" prop1 = orekit_utils.str_tle_propagator(tle_line1, tle_line2) lat = 0. lon = 0. alt = 10. time = AbsoluteDate(2020, 6, 26, 1, 40, 00.000, TimeScalesFactory.getUTC()) self.assertTrue(check_iot_in_range(prop1, lat, lon, alt, time)) self.assertFalse(check_iot_in_range(prop1, lat, lon, alt, time.shiftedBy(60.*30.)))
def orekit_test_data(body, filename, satellite, stations, range_sigma=20.0, range_rate_sigma=0.001, range_base_weight=1.0, range_rate_base_weight=1.0, az_sigma=0.02, el_sigma=0.02): """Load test data from W3B.aer""" azels = [] ranges = [] rates = [] f = open(filename, 'r') for line in f: if line[0] == '#': continue elif len(line) < 25: continue fields = line.split() date_components = DateTimeComponents.parseDateTime(fields[0]) date = AbsoluteDate(date_components, TimeScalesFactory.getUTC()) if fields[1] == 'ONEWAY': two_way = False fields.pop(1) elif fields[1] == 'TWOWAY': two_way = True fields.pop(1) else: two_way = True mode = fields[1] station_name = fields[2] station = stations[station_name] if mode == 'RANGE': rho = float(fields[3]) range_obj = Range(station, True, date, rho, range_sigma, range_base_weight, satellite) ranges.append(range_obj) elif mode == 'AZ_EL': az = float(fields[3]) * math.pi / 180.0 el = float(fields[4]) * math.pi / 180.0 azel_obj = AngularAzEl(station, date, [az, el], [az_sigma, el_sigma], [az_base_weight, el_base_weight], satellite) azels.append(azel_obj) elif mode in ('RATE', 'RRATE'): rate_obj = RangeRate(station, date, float(fields[3]), range_rate_sigma, range_rate_base_weight, two_way, satellite) rates.append(rate_obj) else: raise SyntaxError("unrecognized mode '{}'".format(mode)) return stations, ranges, rates, azels
def absolute_time_converter_utc_string(time_string): """ turn time_string into orekit absolute time object Inputs: time scales in UTC Output: absolute time object from orekit """ return AbsoluteDate(time_string, TimeScalesFactory.getUTC())
def test_get_ground_passes(self): """ Testing whether OreKit finds ground passess """ # test will fail if setup_orekit fails utc = TimeScalesFactory.getUTC() ra = 500 * 1000 # Apogee rp = 400 * 1000 # Perigee i = radians(55.0) # inclination omega = radians(20.0) # perigee argument raan = radians(10.0) # right ascension of ascending node lv = radians(0.0) # True anomaly epochDate = AbsoluteDate(2020, 1, 1, 0, 0, 00.000, utc) initial_date = epochDate a = (rp + ra + 2 * Constants.WGS84_EARTH_EQUATORIAL_RADIUS) / 2.0 e = 1.0 - (rp + Constants.WGS84_EARTH_EQUATORIAL_RADIUS) / a ## Inertial frame where the satellite is defined inertialFrame = FramesFactory.getEME2000() ## Orbit construction as Keplerian initialOrbit = KeplerianOrbit(a, e, i, omega, raan, lv, PositionAngle.TRUE, inertialFrame, epochDate, Constants.WGS84_EARTH_MU) propagator = KeplerianPropagator(initialOrbit) durand_lat = 37.4269 durand_lat = -122.1733 durand_alt = 10.0 output = get_ground_passes(propagator, durand_lat, durand_lat, durand_alt, initial_date, initial_date.shiftedBy(3600.0 * 24), ploting_param=False) assert len(output) == 5
def test_field_of_view_detector(self): """ field_of_view_detector tests """ tle = TLE( "1 44235U 19029A 20178.66667824 .02170155 00000-0 40488-1 0 9998", "2 44235 00.0000 163.9509 0005249 306.3756 83.0170 15.45172567 61683" ) parameters = {"frame": "TEME"} attitudeProvider = orekit_utils.nadir_pointing_law(parameters) propogator_fov = TLEPropagator.selectExtrapolator( tle, attitudeProvider, 4.) startDate = AbsoluteDate(2020, 6, 26, 1, 40, 00.000, TimeScalesFactory.getUTC()) #should have one passes self.assertTrue( len( orekit_utils.field_of_view_detector(propogator_fov, 0, 0, 0, startDate, 20, 5400)) == 1) #should have zero passes self.assertTrue( len( orekit_utils.field_of_view_detector(propogator_fov, 0, 0, 0, startDate, 20, 100)) == 0) #test exact time input self.assertFalse( orekit_utils.field_of_view_detector(propogator_fov, 0, 0, 0, startDate, 20))
def itrs_gcrs_single(itrs): """ Transformation ITRS to GCRS. """ utc = TimeScalesFactory.getUTC() date = itrs.index[0] X = float(itrs['x[m]'][0]) Y = float(itrs['y[m]'][0]) Z = float(itrs['z[m]'][0]) Vx = float(itrs['vx[m/s]'][0]) Vy = float(itrs['vy[m/s]'][0]) Vz = float(itrs['vz[m/s]'][0]) ok_date = AbsoluteDate(date.year, date.month, date.day, date.hour, date.minute, date.second + float(date.microsecond) / 1000000., utc) PV_coordinates = PVCoordinates(Vector3D(X, Y, Z), Vector3D(Vx, Vy, Vz)) start_state = TimeStampedPVCoordinates(ok_date, PV_coordinates) state_itrf = AbsolutePVCoordinates(itrf, start_state) state_gcrf = AbsolutePVCoordinates(gcrf, state_itrf.getPVCoordinates(gcrf)) pos = state_gcrf.position vel = state_gcrf.velocity X = pos.getX() Y = pos.getY() Z = pos.getZ() Vx = vel.getX() Vy = vel.getY() Vz = vel.getZ() dframe = pd.DataFrame({'x[m]': [X], 'y[m]': [Y], 'z[m]': [Z], 'vx[m/s]': [Vx], 'vy[m/s]': [Vy], 'vz[m/s]': [Vz]}, index=itrs.index) return dframe
def __init__(self, name, mu, trj, att, model_file=None): """Currently hard implemented for Didymos.""" super().__init__(name, model_file=model_file) date = trj["date"] trj_date = AbsoluteDate(int(date["year"]), int(date["month"]), int(date["day"]), int(date["hour"]), int(date["minutes"]), float(date["seconds"]), self.timescale) # rotation axis self.axis_ra = math.radians(att["RA"]) if "RA" in att else 0. self.axis_dec = math.radians( att["Dec"]) if "Dec" in att else math.pi / 2 # rotation offset, zero longitude right ascension at epoch self.rotation_zlra = math.radians(att["ZLRA"]) if "ZLRA" in att else 0. # rotation angular velocity [rad/s] if "rotation_rate" in att: self.rotation_rate = att["rotation_rate"] * 2.0 * math.pi / 180.0 else: self.rotation_rate = 2. * math.pi / (2.2593 * 3600 ) # didymain by default # Define initial rotation, set rotation convention # - For me, FRAME_TRANSFORM order makes more sense, the rotations are applied from left to right # so that the following rotations apply on previously rotated axes +Olli self.rot_conv = RotationConvention.FRAME_TRANSFORM init_rot = Rotation(RotationOrder.ZYZ, self.rot_conv, self.axis_ra, math.pi / 2 - self.axis_dec, self.rotation_zlra) if "r" in trj: self.date_history = [trj_date] self.pos_history = [Vector3D(*trj["r"])] self.vel_history = [ Vector3D(*(trj["v"] if "v" in trj else [0., 0., 0.])) ] self.rot_history = [init_rot] return # Define trajectory/orbit self.trajectory = KeplerianOrbit( trj["a"] * ok_utils.Constants.IAU_2012_ASTRONOMICAL_UNIT, trj["e"], math.radians(trj["i"]), math.radians(trj["omega"]), math.radians(trj["Omega"]), math.radians(trj["M"]), PositionAngle.MEAN, self.ref_frame, trj_date, mu) rotation = ok_utils.AngularCoordinates( init_rot, Vector3D(0., 0., self.rotation_rate)) attitude = Attitude(trj_date, self.ref_frame, rotation) att_provider = FixedRate(attitude) # Create propagator self.propagator = KeplerianPropagator(self.trajectory, att_provider) # Loaded coma object, currently only used with OpenGL based rendering self.coma = None
def absolute_time_converter_utc_manual(year, month, day, hour=0, minute=0, second=0.0): """ turn time into orekit absolute time object Inputs: time scales in UTC Output: absolute time object from orekit """ return AbsoluteDate(int(year), int(month), int(day), int(hour), int(minute), float(second), TimeScalesFactory.getUTC())
def __init__(self, name, mu, trj, att, model_file=None): """Currently hard implemented for Didymos.""" super().__init__(name, model_file=model_file) date = trj["date"] trj_date = AbsoluteDate(int(date["year"]), int(date["month"]), int(date["day"]), int(date["hour"]), int(date["minutes"]), float(date["seconds"]), self.timescale) if "a" and "e" and "i" and "omega" and "Omega" and "M" not in trj: a = 1.644641475071416E+00 * utils.Constants.IAU_2012_ASTRONOMICAL_UNIT P = 7.703805051391988E+02 * utils.Constants.JULIAN_DAY e = 3.838774437558215E-01 i = math.radians(3.408231185574551E+00) omega = math.radians(3.192958853076784E+02) Omega = math.radians(7.320940216397703E+01) M = math.radians(1.967164895190036E+02) if "rotation_rate" not in att: rotation_rate = 2. * math.pi / (2.2593 * 3600) else: rotation_rate = att["rotation_rate"] * 2.0 * math.pi / 180.0 if "RA" not in att: self.RA = 0. else: self.RA = math.radians(att["RA"]) if "Dec" not in att: self.Dec = 0. else: self.Dec = math.radians(att["Dec"]) # Define trajectory/orbit self.trajectory = KeplerianOrbit( trj["a"] * utils.Constants.IAU_2012_ASTRONOMICAL_UNIT, trj["e"], math.radians(trj["i"]), math.radians(trj["omega"]), math.radians(trj["Omega"]), math.radians(trj["M"]), PositionAngle.MEAN, self.ref_frame, trj_date, mu) # Define attitude self.rot_conv = RotationConvention.valueOf("VECTOR_OPERATOR") rotation = utils.AngularCoordinates(Rotation.IDENTITY, Vector3D(0., 0., rotation_rate)) attitude = Attitude(trj_date, self.ref_frame, rotation) att_provider = FixedRate(attitude) # Create propagator self.propagator = KeplerianPropagator(self.trajectory, att_provider)
def simple_keplarian(initialOrbit, initialDate): """ :param initialOrbit: initial Keplarian orbit and central body :param initialDate: intial start date :return: plot xy orbit """ # Simple extrapolation with Keplerian motion kepler = KeplerianPropagator(initialOrbit) # Set the propagator to slave mode (could be omitted as it is the default mode) kepler.setSlaveMode() # Setup propagation time # Overall duration in seconds for extrapolation duration = 24 * 60.0**2 # Stop date finalDate = AbsoluteDate(initial_date, duration, utc) # Step duration in seconds stepT = 30.0 # Perform propagation # Extrapolation loop cpt = 1.0 extrapDate = initial_date px, py = [], [] while extrapDate.compareTo(finalDate) <= 0: currentState = kepler.propagate(extrapDate) print('step {}: time {} {}\n'.format(cpt, currentState.getDate(), currentState.getOrbit())) coord = currentState.getPVCoordinates().getPosition() px.append(coord.getX()) py.append(coord.getY()) # P[:,cpt]=[coord.getX coord.getY coord.getZ] extrapDate = AbsoluteDate(extrapDate, stepT, utc) cpt += 1 plt.plot(px, py) plt.show() pass
def npdt2absdate(dt): ''' Converts a numpy datetime64 value to an orekit AbsoluteDate ''' year, month, day, hour, minutes, seconds, microsecond = dpt.npdt2date(dt) return AbsoluteDate( int(year), int(month), int(day), int(hour), int(minutes), float(seconds + microsecond * 1e-6), utc, )
def to_orekit_date(epoch): """Convert UTC simulation time from python's datetime object to Orekit's AbsoluteDate object. Args: epoch (datetime.datetime): UTC simulation time Returns: AbsoluteDate: simulation time in UTC """ seconds = float(epoch.second) + float(epoch.microsecond) / 1e6 orekit_date = AbsoluteDate(epoch.year, epoch.month, epoch.day, epoch.hour, epoch.minute, seconds, TimeScalesFactory.getUTC()) return orekit_date
def kepler_gcrs_single(kep): date = kep.index[0] ok_date = AbsoluteDate(date.year, date.month, date.day, date.hour, date.minute, date.second + float(date.microsecond) / 1000000., utc) kep = kep.astype(float) a, e, f, i, raan, w, date = kep['a[m]'][0], kep['e'][0], kep['ta[rad]'][0], kep['i[rad]'][0], kep['raan[rad]'][0], kep['omega[rad]'][0], \ kep.index[0] kep_orbit = KeplerianOrbit(a, e, i, w, raan, f, PositionAngle.TRUE, teme_f, ok_date, muearth) state = AbsolutePVCoordinates(gcrf_f, kep_orbit.getPVCoordinates(gcrf_f)) pos = state.position vel = state.velocity X = pos.getX() Y = pos.getY() Z = pos.getZ() Vx = vel.getX() Vy = vel.getY() Vz = vel.getZ() dframe = pd.DataFrame({'x[m]': [X], 'y[m]': [Y], 'z[m]': [Z], 'vx[m/s]': [Vx], 'vy[m/s]': [Vy], 'vz[m/s]': [Vz]},index=kep.index) return dframe
def change_initial_conditions(self, initial_state, date, mass): """ Allows to change the initial conditions given to the propagator without initializing it again. Args: initial_state (Cartesian): New initial state of the satellite in cartesian coordinates. date (datetime): New starting date of the propagator. mass (float64): New satellite mass. """ # Redefine the start date self.date = date # Create position and velocity vectors as Vector3D p = Vector3D( float(initial_state.R[0]) * 1e3, float(initial_state.R[1]) * 1e3, float(initial_state.R[2]) * 1e3) v = Vector3D( float(initial_state.V[0]) * 1e3, float(initial_state.V[1]) * 1e3, float(initial_state.V[2]) * 1e3) # Initialize orekit date seconds = float(date.second) + float(date.microsecond) / 1e6 orekit_date = AbsoluteDate(date.year, date.month, date.day, date.hour, date.minute, seconds, TimeScalesFactory.getUTC()) # Extract frame inertialFrame = FramesFactory.getEME2000() # Evaluate new initial orbit initialOrbit = CartesianOrbit(PVCoordinates(p, v), inertialFrame, orekit_date, Cst.WGS84_EARTH_MU) # Create new spacecraft state newSpacecraftState = SpacecraftState(initialOrbit, mass) # Rewrite propagator initial conditions self.orekit_prop._propagator_num.setInitialState(newSpacecraftState)
def get_sun_max_elevation(self, year, month, day): """ Returns the maximum elevation angle (in radians) of the Sun (that is the zenith) a given day. Parameters ---------- year : int Year. month : int Month. day : int Day. Returns ------- current_ele0 : TYPE DESCRIPTION. currentutc_date : TYPE DESCRIPTION. """ currentutc_date = AbsoluteDate(year, month, day, 0, 0, 0.0, TimeScalesFactory.getUTC()) is_max_elevation = False time_step = 10.0 current_ele0 = self.get_sun_elevation(currentutc_date) current_ele1 = self.get_sun_elevation( currentutc_date.shiftedBy(time_step)) if current_ele0 > current_ele1: is_max_elevation = True while not is_max_elevation: current_ele0 = current_ele1 current_ele1 = self.get_sun_elevation( currentutc_date.shiftedBy(time_step)) if current_ele0 > current_ele1: is_max_elevation = True currentutc_date.shiftedBy(-time_step) currentutc_date = currentutc_date.shiftedBy(time_step) return current_ele0, currentutc_date
def osc_elems_transformation_ore(self, other, dir): self._orekit_lock.acquire() self.load_orekit() KepOrbElem.vm.attachCurrentThread() utc = TimeScalesFactory.getUTC() orekit_date = AbsoluteDate(2017, 1, 1, 12, 1, 1.0, utc) inertialFrame = FramesFactory.getEME2000() a = float(other.a) e = float(other.e) i = float(other.i) w = float(other.w) O = float(other.O) v = float(other.v) initialOrbit = KeplerianOrbit(a * 1000.0, e, i, w, O, v, PositionAngle.TRUE, inertialFrame, orekit_date, Constants.mu_earth * 1e9) initialState = SpacecraftState(initialOrbit, 1.0) #zonal_forces= DSSTZonal(provider,2,1,5) zonal_forces = DSSTZonal(KepOrbElem.provider, 6, 4, 6) forces = ArrayList() forces.add(zonal_forces) try: equinoctial = None if dir: equinoctial = DSSTPropagator.computeMeanState( initialState, None, forces) else: equinoctial = DSSTPropagator.computeOsculatingState( initialState, None, forces) newOrbit = KeplerianOrbit(equinoctial.getOrbit()) self.a = newOrbit.getA() / 1000.0 self.e = newOrbit.getE() self.i = newOrbit.getI() self.w = newOrbit.getPerigeeArgument() self.O = newOrbit.getRightAscensionOfAscendingNode() self.v = newOrbit.getAnomaly(PositionAngle.TRUE) # correct ranges if self.i < 0: self.i += 2 * np.pi if self.w < 0: self.w += 2 * np.pi if self.O < 0: self.O += 2 * np.pi if self.v < 0: self.v += 2 * np.pi finally: self._orekit_lock.release()
def __init__(self, res_dir, starcat_dir, instrument, with_infobox, with_clipping, sssb, sun, lightref, encounter_date, duration, frames, encounter_distance, relative_velocity, with_sunnyside, with_terminator, timesampler_mode, slowmotion_factor, exposure, samples, device, tile_size, oneshot=False, spacecraft=None, opengl_renderer=False): self.opengl_renderer = opengl_renderer self.brdf_params = sssb.get('brdf_params', None) self.root_dir = Path(__file__).parent.parent.parent data_dir = self.root_dir / "data" self.models_dir = utils.check_dir(data_dir / "models") self.res_dir = res_dir self.starcat_dir = starcat_dir self.inst = sc.Instrument(instrument) self.ts = TimeScalesFactory.getTDB() self.ref_frame = FramesFactory.getICRF() self.mu_sun = Constants.IAU_2015_NOMINAL_SUN_GM encounter_date = encounter_date self.encounter_date = AbsoluteDate(int(encounter_date["year"]), int(encounter_date["month"]), int(encounter_date["day"]), int(encounter_date["hour"]), int(encounter_date["minutes"]), float(encounter_date["seconds"]), self.ts) self.duration = duration self.start_date = self.encounter_date.shiftedBy(-self.duration / 2.) self.end_date = self.encounter_date.shiftedBy(self.duration / 2.) self.frames = frames self.minimum_distance = encounter_distance self.relative_velocity = relative_velocity self.with_terminator = bool(with_terminator) self.with_sunnyside = bool(with_sunnyside) self.timesampler_mode = timesampler_mode self.slowmotion_factor = slowmotion_factor self.render_settings = dict() self.render_settings["exposure"] = exposure self.render_settings["samples"] = samples self.render_settings["device"] = device self.render_settings["tile"] = tile_size self.sssb_settings = sssb self.with_infobox = with_infobox self.with_clipping = with_clipping # Setup rendering engine (renderer) self.setup_renderer() # Setup SSSB self.setup_sssb(sssb) # Setup SC self.setup_spacecraft(spacecraft, oneshot=oneshot) if not self.opengl_renderer: # Setup Sun self.setup_sun(sun) # Setup Lightref self.setup_lightref(lightref) logger.debug("Init finished")
# LOOP OVER THE FILE AND CREATE THE OBSERVATION OBJECTS # AngularRaDec objects hold Ra and Dec in this order dates = [] obs = [] # I use the list method here to append rows and then transpose it, the next for # loop displays a different method using np.arrays LOSversors = [] i = 0 for line in data_lines[1::]: dates.append(AbsoluteDate(yr_mo_day[0], yr_mo_day[1], yr_mo_day[2], int(line[1]), int(line[2]), float(line[3]), utc)) obs.append(AngularRaDec(GndStation, ITRF_Frame, dates[i], [radians(float(line[4])), radians(float(line[5]))], [0.0, 0.0], [0.0, 0.0], Sat)) LOSver = Get_LineOfSight_UnitVector(obs[i].getObservedValue()[0], obs[i].getObservedValue()[1]) LOSver_column = LOSver.toArray() LOSversors.append(LOSver_column) i += 1 # Could not find a better way to get the vectors in as column vectors, will have to investigate further LOSarray = np.array(LOSversors).T
setup_orekit_curdir() # To activate once if a problem of orekit.Exception appears. (.getUtc()) # orekit.pyhelpers.download_orekit_data_curdir() utc = TimeScalesFactory.getUTC() ra = 400 * 1000 # Apogee rp = 500 * 1000 # Perigee i = numpy.radians(87.0) # inclination # FIXME: Use Hipparchus Library instead of numpy omega = numpy.radians(20.0) # perigee argument raan = numpy.radians(10.0) # right ascension of ascending node lv = numpy.radians(0.0) # True anomaly epochDate = AbsoluteDate(2020, 1, 1, 0, 0, 00.000, utc) a = (rp + ra + 2 * Constants.WGS84_EARTH_EQUATORIAL_RADIUS) / 2.0 e = 1.0 - (rp + Constants.WGS84_EARTH_EQUATORIAL_RADIUS) / a # Inertial frame where the satellite is defined inertialFrame = FramesFactory.getEME2000() # Orbit construction as Keplerian initialOrbit = KeplerianOrbit(24464560.0, 0.7311, 0.122138, 3.10686, 1.00681, 0.048363, PositionAngle.MEAN, FramesFactory.getEME2000(), epochDate, Constants.GRS80_EARTH_MU) print(initialOrbit)
class Environment(): """ Simulation environment. This environment is used to propagate trajectories and render images at each simulation step. """ def __init__(self, res_dir, starcat_dir, instrument, with_infobox, with_clipping, sssb, sun, lightref, encounter_date, duration, frames, encounter_distance, relative_velocity, with_sunnyside, with_terminator, timesampler_mode, slowmotion_factor, exposure, samples, device, tile_size, oneshot=False, spacecraft=None, opengl_renderer=False): self.opengl_renderer = opengl_renderer self.brdf_params = sssb.get('brdf_params', None) self.root_dir = Path(__file__).parent.parent.parent data_dir = self.root_dir / "data" self.models_dir = utils.check_dir(data_dir / "models") self.res_dir = res_dir self.starcat_dir = starcat_dir self.inst = sc.Instrument(instrument) self.ts = TimeScalesFactory.getTDB() self.ref_frame = FramesFactory.getICRF() self.mu_sun = Constants.IAU_2015_NOMINAL_SUN_GM encounter_date = encounter_date self.encounter_date = AbsoluteDate(int(encounter_date["year"]), int(encounter_date["month"]), int(encounter_date["day"]), int(encounter_date["hour"]), int(encounter_date["minutes"]), float(encounter_date["seconds"]), self.ts) self.duration = duration self.start_date = self.encounter_date.shiftedBy(-self.duration / 2.) self.end_date = self.encounter_date.shiftedBy(self.duration / 2.) self.frames = frames self.minimum_distance = encounter_distance self.relative_velocity = relative_velocity self.with_terminator = bool(with_terminator) self.with_sunnyside = bool(with_sunnyside) self.timesampler_mode = timesampler_mode self.slowmotion_factor = slowmotion_factor self.render_settings = dict() self.render_settings["exposure"] = exposure self.render_settings["samples"] = samples self.render_settings["device"] = device self.render_settings["tile"] = tile_size self.sssb_settings = sssb self.with_infobox = with_infobox self.with_clipping = with_clipping # Setup rendering engine (renderer) self.setup_renderer() # Setup SSSB self.setup_sssb(sssb) # Setup SC self.setup_spacecraft(spacecraft, oneshot=oneshot) if not self.opengl_renderer: # Setup Sun self.setup_sun(sun) # Setup Lightref self.setup_lightref(lightref) logger.debug("Init finished") def setup_renderer(self): """Create renderer, apply common settings and create sc cam.""" render_dir = utils.check_dir(self.res_dir) raw_dir = utils.check_dir(render_dir / "raw") if self.opengl_renderer: from .opengl import rendergl self.renderer = rendergl.RenderController(render_dir, stardb_path=self.starcat_dir) self.renderer.create_scene("SssbOnly") else: from .render import BlenderController self.renderer = BlenderController(render_dir, raw_dir, self.starcat_dir, self.inst, self.sssb_settings, self.with_infobox, self.with_clipping) self.renderer.create_camera("ScCam") self.renderer.configure_camera("ScCam", self.inst.focal_l, self.inst.chip_w) if not self.opengl_renderer: self.renderer.create_scene("SssbConstDist") self.renderer.create_camera("SssbConstDistCam", scenes="SssbConstDist") self.renderer.configure_camera("SssbConstDistCam", self.inst.focal_l, self.inst.chip_w) self.renderer.create_scene("LightRef") self.renderer.create_camera("LightRefCam", scenes="LightRef") self.renderer.configure_camera("LightRefCam", self.inst.focal_l, self.inst.chip_w) else: # as use sispo cam model self.renderer.set_scene_config({ 'debug': False, 'flux_only': False, 'sispo_cam': self.inst, # use sispo cam model instead #of own (could use own if can give exposure & gain) 'stars': True, # use own star db 'lens_effects': False, # includes the sun 'brdf_params': self.brdf_params, }) self.renderer.set_device(self.render_settings["device"], self.render_settings["tile"]) self.renderer.set_samples(self.render_settings["samples"]) self.renderer.set_exposure(self.render_settings["exposure"]) self.renderer.set_resolution(self.inst.res) self.renderer.set_output_format() def setup_sun(self, settings): """Create Sun and respective render object.""" sun_model_file = Path(settings["model"]["file"]) try: sun_model_file = sun_model_file.resolve() except OSError as e: raise SimulationError(e) if not sun_model_file.is_file(): sun_model_file = self.models_dir / sun_model_file.name sun_model_file = sun_model_file.resolve() if not sun_model_file.is_file(): raise SimulationError("Given SSSB model filename does not exist.") self.sun = cb.CelestialBody(settings["model"]["name"], model_file=sun_model_file) self.sun.render_obj = self.renderer.load_object(self.sun.model_file, self.sun.name) def setup_sssb(self, settings): """Create SmallSolarSystemBody and respective blender object.""" sssb_model_file = Path(settings["model"]["file"]) try: sssb_model_file = sssb_model_file.resolve() except OSError as e: raise SimulationError(e) if not sssb_model_file.is_file(): sssb_model_file = self.models_dir / sssb_model_file.name sssb_model_file = sssb_model_file.resolve() if not sssb_model_file.is_file(): raise SimulationError("Given SSSB model filename does not exist.") self.sssb = sssb.SmallSolarSystemBody(settings["model"]["name"], self.mu_sun, settings["trj"], settings["att"], model_file=sssb_model_file) self.sssb.render_obj = self.renderer.load_object( self.sssb.model_file, settings["model"]["name"], ["SssbOnly"] + ([] if self.opengl_renderer else ["SssbConstDist"])) self.sssb.render_obj.rotation_mode = "AXIS_ANGLE" self.sssb.render_obj.location = (0.0, 0.0, 0.0) # Setup previously generated coma coma = settings.get('coma', None) if coma: with open(coma['file'], 'r') as fh: coma.update(json.load(fh)) assert self.opengl_renderer, '"coma" setting under "sssb" is currently only supported for opengl rendering' sssb_rot = coma.get('sssb_rot', False) if not sssb_rot: # if param missing and one shot mode, assumes that coma is created with same asteroid orientation assert self.sssb.rot_history, 'SSSB rotation state for cached coma is not given with "sssb_rot"' sssb_rot = self.sssb.rot_history[0] sssb_rot = (sssb_rot.getAngle(), *sssb_rot.getAxis(RotationConvention.FRAME_TRANSFORM).toArray()) self.sssb.coma = self.renderer.load_coma( coma['tiles_file'], coma['dimensions'], coma['resolution'], coma.get('intensity', 1e-4), sssb_rot ) def setup_spacecraft(self, spacecraft=None, oneshot=False): """Create Spacecraft and respective blender object.""" sc_state = None sc_rot_state = None if spacecraft is None: sssb_state = self.sssb.get_state(self.encounter_date) sc_state = sc.Spacecraft.calc_encounter_state(sssb_state, self.minimum_distance, self.relative_velocity, self.with_terminator, self.with_sunnyside) else: if 'r' in spacecraft: sc_state = PVCoordinates(Vector3D(spacecraft['r']), Vector3D(spacecraft.get('v', [0.0, 0.0, 0.0]))) if 'angleaxis' in spacecraft: sc_pxpz_rot = Rotation(Vector3D(spacecraft['angleaxis'][1:4]), spacecraft['angleaxis'][0], RotationConvention.FRAME_TRANSFORM) # transform camera where +x is forward and +z is up into -z is forward and +y is up mzpy_rot = self.pxpz_to_mzpy(sc_pxpz_rot) sc_rot_state = AngularCoordinates(mzpy_rot, Vector3D(0., 0., 0.)) self.spacecraft = sc.Spacecraft("CI", self.mu_sun, sc_state, self.encounter_date, rot_state=sc_rot_state, oneshot=oneshot) @staticmethod def pxpz_to_mzpy(pxpz_rot): pxpz_to_mzpy_rot = Rotation(0.5, 0.5, -0.5, -0.5, False) return pxpz_to_mzpy_rot.applyTo(pxpz_rot) @staticmethod def mzpy_to_pxpz(mzpy_rot): pxpz_to_mzpy_rot = Rotation(0.5, 0.5, -0.5, -0.5, False) return pxpz_to_mzpy_rot.applyInverseTo(mzpy_rot) def setup_lightref(self, settings): """Create lightreference blender object.""" lightref_model_file = Path(settings["model"]["file"]) try: lightref_model_file = lightref_model_file.resolve() except OSError as e: raise SimulationError(e) if not lightref_model_file.is_file(): lightref_model_file = self.models_dir / lightref_model_file.name lightref_model_file = lightref_model_file.resolve() if not lightref_model_file.is_file(): raise SimulationError("Given lightref model filename does not exist.") self.lightref = self.renderer.load_object(lightref_model_file, settings["model"]["name"], scenes="LightRef") self.lightref.location = (0.0, 0.0, 0.0) def simulate(self): """Do simulation.""" logger.debug("Starting simulation") logger.debug("Propagating SSSB") self.sssb.propagate(self.start_date, self.end_date, self.frames, self.timesampler_mode, self.slowmotion_factor) logger.debug("Propagating Spacecraft") self.spacecraft.propagate(self.start_date, self.end_date, self.frames, self.timesampler_mode, self.slowmotion_factor) logger.debug("Simulation completed") self.save_results() def render(self): """Render simulation scenario.""" logger.debug("Rendering simulation") scaling = 1. if self.opengl_renderer else 1000. N = len(self.spacecraft.date_history) # Render frame by frame print("Rendering in progress...") for i, (date, sc_pos, sc_rot, sssb_pos, sssb_rot) in enumerate(zip( self.spacecraft.date_history, self.spacecraft.pos_history, self.spacecraft.rot_history, self.sssb.pos_history, self.sssb.rot_history)): date_str = datetime.strptime(date.toString(), "%Y-%m-%dT%H:%M:%S.%f") date_str = date_str.strftime("%Y-%m-%dT%H%M%S-%f") # metadict creation metainfo = dict() metainfo["sssb_pos"] = np.asarray(sssb_pos.toArray()) metainfo["sc_pos"] = np.asarray(sc_pos.toArray()) metainfo["distance"] = sc_pos.distance(sssb_pos) metainfo["date"] = date_str # Set Rotation angle, axis = convert_rot_to_angle_axis(sssb_rot, RotationConvention.FRAME_TRANSFORM) self.renderer.set_object_rot(angle, axis , self.sssb.render_obj) # Update environment # Removed unnecessary conditional, opengl can omit the scaling self.renderer.set_sun_location(-np.asarray(sssb_pos.toArray()), scaling, getattr(self,"sun", None)) # Update sssb and spacecraft pos_sc_rel_sssb = np.asarray(sc_pos.subtract(sssb_pos).toArray()) / scaling self.renderer.set_camera_location("ScCam", pos_sc_rel_sssb) if self.spacecraft.auto_targeting: self.renderer.target_camera(self.sssb.render_obj, "ScCam") else: angle, axis = convert_rot_to_angle_axis(sc_rot, RotationConvention.FRAME_TRANSFORM) self.renderer.set_camera_rot(angle, axis, "ScCam") if not self.opengl_renderer: # Update scenes/cameras pos_cam_const_dist = pos_sc_rel_sssb * scaling / np.sqrt( np.dot(pos_sc_rel_sssb, pos_sc_rel_sssb)) self.renderer.set_camera_location("SssbConstDistCam", pos_cam_const_dist) self.renderer.target_camera(self.sssb.render_obj, "SssbConstDistCam") lightrefcam_pos = -np.asarray(sssb_pos.toArray()) * scaling \ / np.sqrt(np.dot(np.asarray(sssb_pos.toArray()), np.asarray(sssb_pos.toArray()))) self.renderer.set_camera_location("LightRefCam", lightrefcam_pos) self.renderer.target_camera(self.sun.render_obj, "CalibrationDisk") self.renderer.target_camera(self.lightref, "LightRefCam") # Render blender scenes self.renderer.render(metainfo) print('%d/%d' % (i+1, N)) logger.debug("Rendering completed") def save_results(self): """Save simulation results to a file.""" logger.debug("Saving propagation results") float_formatter = "{:.16f}".format np.set_printoptions(formatter={'float_kind': float_formatter}) vec2str = lambda v: str(np.asarray(v.toArray())) print_list = [ [str(v) for v in self.spacecraft.date_history], [vec2str(v) for v in self.spacecraft.pos_history], [vec2str(v) for v in self.spacecraft.vel_history], #[vec2str(v) for v in self.spacecraft.rot_history], [vec2str(v) for v in self.sssb.pos_history], [vec2str(v) for v in self.sssb.vel_history], #[vec2str(v) for v in self.sssb.rot_history], ] with open(str(self.res_dir / "DynamicsHistory.txt"), "w+") as file: for i in range(len(self.spacecraft.date_history)): line = "\t".join([v[i] for v in print_list]) + "\n" file.write(line) logger.debug("Propagation results saved")
# detector can properly function. Therefore, the Earth is instantiated from this # class although the flatteing factor is set to zero so it still becomes a # perfect sphere REarth_orekit = Constants.WGS84_EARTH_EQUATORIAL_RADIUS Earth_orekit = OneAxisEllipsoid( Constants.WGS84_EARTH_EQUATORIAL_RADIUS, float(0), FramesFactory.getITRF(IERSConventions.IERS_2010, True), ) # The COE for the orbit to be defined a, ecc, inc, raan, argp, nu = (6828137.0, 0.0073, 87.0, 20.0, 10.0, 0) # Define the orkeit and poliastro orbits to be used for all the event validation # cases in this script epoch0_orekit = AbsoluteDate(2020, 1, 1, 0, 0, 00.000, TimeScalesFactory.getUTC()) ss0_orekit = KeplerianOrbit( float(a), float(ecc), float(inc * DEG_TO_RAD), float(argp * DEG_TO_RAD), float(raan * DEG_TO_RAD), float(nu * DEG_TO_RAD), PositionAngle.TRUE, FramesFactory.getEME2000(), epoch0_orekit, Constants.WGS84_EARTH_MU, ) epoch0_poliastro = Time("2020-01-01", scale="utc") ss0_poliastro = Orbit.from_classical( Earth,
class Propagator: def __init__(self, initial_orbit, initial_date, shifted_date): self.shifted_date = shifted_date self.initial_orbit = initial_orbit self.initial_date = initial_date def __str__(self): return str(self.__dict__) def propagate_keplerian_elements(self): propagator = KeplerianPropagator(self.initial_orbit) return propagator.propagate(self.initial_date, self.shifted_date) if __name__ == "__main__": instance = KeplerianElements( 24464560.0, 0.7311, 0.122138, 3.10686, 1.00681, 0.048363, PositionAngle.MEAN, FramesFactory.getEME2000(), AbsoluteDate(2020, 1, 1, 0, 0, 00.000, TimeScalesFactory.getUTC()), Constants.GRS80_EARTH_MU) k = instance.init_keplerian_elements() init_date = AbsoluteDate(2020, 1, 1, 0, 0, 00.000, TimeScalesFactory.getUTC()) shift = init_date.shiftedBy(3600.0 * 48) kp = Propagator(k, init_date, shift) kp.propagate_keplerian_elements() print(k) print(kp)
def convert_cart_single_orekit(to_conv,ref_to_conv,target_ref): """ Coordinate frame transformation with Orekit modules. INPUTS ------ to_conv: dataframe Cartesian coordinates. ref_to_conv: string Initial reference frame ('itrf','gcrf','teme', 'eme2000') target_ref: string Final reference frame ('itrf','gcrf','teme', 'eme2000') RETURN ------ dframe: dataframe Cartesian coordinates. """ date = to_conv.index[0] X = float(to_conv['x[m]'][0]) Y = float(to_conv['y[m]'][0]) Z = float(to_conv['z[m]'][0]) Vx = float(to_conv['vx[m/s]'][0]) Vy = float(to_conv['vy[m/s]'][0]) Vz = float(to_conv['vz[m/s]'][0]) ok_date = AbsoluteDate(date.year, date.month, date.day, date.hour, date.minute, date.second + float(date.microsecond) / 1000000., utc) PV_coordinates = PVCoordinates(Vector3D(X, Y, Z), Vector3D(Vx, Vy, Vz)) start_state = TimeStampedPVCoordinates(ok_date, PV_coordinates) if ref_to_conv == 'itrf': frame_to_conv = itrf_f elif ref_to_conv == 'gcrf': frame_to_conv = gcrf_f elif ref_to_conv == 'teme': frame_to_conv = teme_f elif ref_to_conv == 'eme2000': frame_to_conv = eme2000_f else: print(f'Unknown reference frame: {ref_to_conv}') if target_ref == 'itrf': target_frame = itrf_f elif target_ref == 'gcrf': target_frame = gcrf_f elif target_ref == 'teme': target_frame = teme_f elif target_ref == 'eme2000': target_frame = eme2000_f else: print(f'Unknown reference frame: {target_ref}') state_to_conv = AbsolutePVCoordinates(frame_to_conv,start_state) target_state = AbsolutePVCoordinates(target_frame,state_to_conv.getPVCoordinates(target_frame)) pos = target_state.position vel = target_state.velocity X = pos.getX() Y = pos.getY() Z = pos.getZ() Vx = vel.getX() Vy = vel.getY() Vz = vel.getZ() dframe = pd.DataFrame({'x[m]': [X], 'y[m]': [Y], 'z[m]': [Z], 'vx[m/s]': [Vx], 'vy[m/s]': [Vy], 'vz[m/s]': [Vz]},index=to_conv.index) return dframe
def create_data_validity_checklist(): """Get files loader by DataProvider and create dict() with valid dates for loaded data. Creates a list with valid start and ending date for data loaded by the DataProvider during building. The method looks for follwing folders holding the correspoding files: Earth-Orientation-Parameters: EOP files using IERS2010 convetions MSAFE: NASA Marshall Solar Activity Future Estimation files Magnetic-Field-Models: magentic field model data files The list should be used before every propagation step, to check if data is loaded/still exists for current simulation time. Otherwise simulation could return results with coarse accuracy. If e.g. no EOP data is available, null correction is used, which could worsen the propagators accuracy. """ checklist = dict() start_dates = [] end_dates = [] EOP_file = _get_name_of_loaded_files('Earth-Orientation-Parameters') if EOP_file: EOPHist = FramesFactory.getEOPHistory(IERS.IERS_2010, False) EOP_start_date = EOPHist.getStartDate() EOP_end_date = EOPHist.getEndDate() checklist['EOP_dates'] = [EOP_start_date, EOP_end_date] start_dates.append(EOP_start_date) end_dates.append(EOP_end_date) CelesTrack_file = _get_name_of_loaded_files('CELESTRACK') if CelesTrack_file: ctw = CelesTrackWeather("(?:sw|SW)\\p{Digit}+\\.(?:txt|TXT)") ctw_start_date = ctw.getMinDate() ctw_end_date = ctw.getMaxDate() checklist['CTW_dates'] = [ctw_start_date, ctw_end_date] start_dates.append(ctw_start_date) end_dates.append(ctw_end_date) MSAFE_file = _get_name_of_loaded_files('MSAFE') if MSAFE_file: msafe = MarshallSolarActivityFutureEstimation( "(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)" + "\\p{Digit}\\p{Digit}\\p{Digit}\\p{Digit}F10\\" + ".(?:txt|TXT)", MarshallSolarActivityFutureEstimation.StrengthLevel.AVERAGE) MS_start_date = msafe.getMinDate() MS_end_date = msafe.getMaxDate() checklist['MSAFE_dates'] = [MS_start_date, MS_end_date] start_dates.append(MS_start_date) end_dates.append(MS_end_date) if FileDataHandler._mag_field_coll: coll_iterator = FileDataHandler._mag_field_coll.iterator() first = coll_iterator.next() GM_start_date = first.validFrom() GM_end_date = first.validTo() for GM in coll_iterator: if GM_start_date > GM.validFrom(): GM_start_date = GM.validFrom() if GM_end_date < GM.validTo(): GM_end_date = GM.validTo() # convert to absolute date for later comparison dec_year = GM_start_date base = datetime(int(dec_year), 1, 1) dec = timedelta(seconds=(base.replace(year=base.year + 1) - base).total_seconds() * (dec_year-int(dec_year))) GM_start_date = to_orekit_date(base + dec) dec_year = GM_end_date base = datetime(int(dec_year), 1, 1) dec = timedelta(seconds=(base.replace(year=base.year + 1) - base).total_seconds() * (dec_year-int(dec_year))) GM_end_date = to_orekit_date(base + dec) checklist['MagField_dates'] = [GM_start_date, GM_end_date] start_dates.append(GM_start_date) end_dates.append(GM_end_date) if checklist: # if any data loaded define first and last date # using as date zero 01.01.1850. Assuming no data before. absolute_zero = AbsoluteDate(1850, 1, 1, TimeScalesFactory.getUTC()) first_date = min(start_dates, key=lambda p: p.durationFrom(absolute_zero)) last_date = min(end_dates, key=lambda p: p.durationFrom(absolute_zero)) checklist['MinMax_dates'] = [first_date, last_date] mesg = "[INFO]: Simulation can run between epochs: " + \ str(first_date) + " & " + str(last_date) + \ " (based on loaded files)." print mesg FileDataHandler._data_checklist = checklist
def main(): a = 24396159.0 # semi major axis (m) e = 0.720 # eccentricity i = radians(10.0) # inclination omega = radians(50.0) # perigee argument raan = radians(150) # right ascension of ascending node lM = 0.0 # mean anomaly # Set inertial frame inertialFrame = FramesFactory.getEME2000() # Initial date in UTC time scale utc = TimeScalesFactory.getUTC() initial_date = AbsoluteDate(2004, 1, 1, 23, 30, 00.000, utc) # Setup orbit propagator # gravitation coefficient mu = 3.986004415e+14 # Orbit construction as Keplerian initialOrbit = KeplerianOrbit(a, e, i, omega, raan, lM, PositionAngle.MEAN, inertialFrame, initial_date, mu) initial_state = SpacecraftState(initialOrbit) # use a numerical propogator min_step = 0.001 max_step = 1000.0 position_tolerance = 10.0 propagation_type = OrbitType.KEPLERIAN tolerances = NumericalPropagator.tolerances(position_tolerance, initialOrbit, propagation_type) integrator = DormandPrince853Integrator(min_step, max_step, 1e-5, 1e-10) propagator = NumericalPropagator(integrator) propagator.setOrbitType(propagation_type) # force model gravity field provider = GravityFieldFactory.getNormalizedProvider(10, 10) holmesFeatherstone = HolmesFeatherstoneAttractionModel( FramesFactory.getITRF(IERSConventions.IERS_2010, True), provider) # SRP # ssc = IsotropicRadiationSingleCoefficient(100.0, 0.8) # Spacecraft surface area (m^2), C_r absorbtion # srp = SolarRadiationPressure(CelestialBodyFactory.getSun(), a, ssc) # sun, semi-major Earth, spacecraft sensitivity propagator.addForceModel(holmesFeatherstone) # propagator.addForceModel(ThirdBodyAttraction(CelestialBodyFactory.getSun())) # propagator.addForceModel(ThirdBodyAttraction(CelestialBodyFactory.getMoon())) # propagator.addForceModel(srp) propagator.setMasterMode(60.0, TutorialStepHandler()) propagator.setInitialState(initial_state) # propagator.setEphemerisMode() finalstate = propagator.propagate(initial_date.shiftedBy( 10. * 24 * 60**2)) # TIme shift in seconds
def __init__(self, lat=48.58, longi=7.75, alt=142.0, loc="Strasbourg", time_zone=1, gnomon_length=1.0, mural_angle=45.0, height=1.0, orient="Nord"): """ Initiate a MuralSundial instance, The defaut is located at Strasbourg. Parameters ---------- lat : float, optional Latitude of the murial sundial. The default is 48.58 (Strasbourg). longi : float, optional Longitude of the mural sundial. The default is 7.75 (Strasbourg). alt : float, optional Altitude of the mural sundial. The default is 142.0 (Strasbourg). loc : str, optional Name of the place where the murial sundial will stand. The default is "Strasbourg". time_zone : int, optional Time zone of the place where the murial sundial will stand . The default is 1 (Strasbourg). gnomon_length : float, optional Length of the gnomon of the murial Sundial. The default is 1.0. mural_angle : float, optional Angle between the wall and the East. The default is 45.0. height : float, optional Height of the mural sundial. The default is 1.0. orient : str, optional Orientation of the wall. The default is "Nord". Returns ------- None. """ super().__init__(lat, longi, alt, loc, time_zone, gnomon_length) self.mural_angle = radians(mural_angle) self.height = height if orient == "Nord": orientation = -1 elif orient == "Sud": orientation = 1 else: orientation = 0 print("Cannot read the orientation, put to 0") z_translation = Vector3D(0.0, 0.0, height) whenever = AbsoluteDate() z_transformation = Transform(whenever, z_translation) z_vector = Vector3D(0.0, 0.0, 1.0) horizontal_rotation = Rotation(z_vector, mural_angle, RotationConvention.VECTOR_OPERATOR) horizontal_ac = AngularCoordinates(horizontal_rotation, Vector3D(0.0, 0.0, 0.0)) z_rotation_tf = Transform(whenever, horizontal_ac) mural_transform = Transform(whenever, z_transformation, z_rotation_tf) x_vector = Vector3D(1.0, 0.0, 0.0) xm_rotation = Rotation(x_vector, orientation * pi / 2, RotationConvention.VECTOR_OPERATOR) xm_rot_ac = AngularCoordinates(xm_rotation, Vector3D(0.0, 0.0, 0.0)) xm_rot_tf = Transform(whenever, xm_rot_ac) sundial_transform = Transform(whenever, mural_transform, xm_rot_tf) self.sundial_frame = Frame(self.station_frame, sundial_transform, "Sundial Frame")
def orekit_time(ephemeris_time): return AbsoluteDate(AbsoluteDate.J2000_EPOCH, ephemeris_time)
def dlAndParseCpfData(username_edc, password_edc, url, datasetIdList, startDate, endDate): """ Downloads and parses CPF prediction data. A CPF file usually contains one week of data. Using both startDate and endDate parameters, it is possible to truncate this data. :param username_edc: str, username for the EDC API :param password_edc: str, password for the EDC API :param url: str, URL for the EDC API :param datasetIdList: list of dataset ids to download. :param startDate: datetime object. Data prior to this date will be removed :param endDate: datetime object. Data after this date will be removed :return: pandas DataFrame containing: - index: datetime object of the data point, in UTC locale - columns 'x', 'y', and 'z': float, satellite position in ITRF frame in meters """ import requests import json from org.orekit.time import AbsoluteDate from org.orekit.time import TimeScalesFactory from orekit.pyhelpers import absolutedate_to_datetime utc = TimeScalesFactory.getUTC() dl_args = {} dl_args['username'] = username_edc dl_args['password'] = password_edc dl_args['action'] = 'data-download' dl_args['data_type'] = 'CPF' import pandas as pd cpfDataFrame = pd.DataFrame(columns=['x', 'y', 'z']) for datasetId in datasetIdList: dl_args['id'] = str(datasetId) dl_response = requests.post(url, data=dl_args) if dl_response.status_code == 200: """ convert json string in python list """ data = json.loads(dl_response.text) currentLine = '' i = 0 n = len(data) while (not currentLine.startswith('10') ) and i < n: # Reading lines until the H4 header currentLine = data[i] i += 1 while currentLine.startswith('10') and i < n: lineData = currentLine.split() mjd_day = int(lineData[2]) secondOfDay = float(lineData[3]) position_ecef = [ float(lineData[5]), float(lineData[6]), float(lineData[7]) ] absolutedate = AbsoluteDate.createMJDDate( mjd_day, secondOfDay, utc) currentdatetime = absolutedate_to_datetime(absolutedate) if (currentdatetime >= startDate) and (currentdatetime <= endDate): cpfDataFrame.loc[currentdatetime] = position_ecef currentLine = data[i] i += 1 else: print(dl_response.status_code) print(dl_response.text) return cpfDataFrame
class Environment(): """ Simulation environment. This environment is used to propagate trajectories and render images at each simulation step. """ def __init__(self, res_dir, starcat_dir, instrument, with_infobox, with_clipping, sssb, sun, lightref, encounter_date, duration, frames, encounter_distance, relative_velocity, with_sunnyside, with_terminator, timesampler_mode, slowmotion_factor, exposure, samples, device, tile_size, ext_logger=None): if ext_logger is not None: self.logger = ext_logger else: self.logger = utils.create_logger() self.root_dir = Path(__file__).parent.parent.parent data_dir = self.root_dir / "data" self.models_dir = utils.check_dir(data_dir / "models") self.res_dir = res_dir self.starcat_dir = starcat_dir self.inst = Instrument(instrument) self.ts = TimeScalesFactory.getTDB() self.ref_frame = FramesFactory.getICRF() self.mu_sun = Constants.IAU_2015_NOMINAL_SUN_GM encounter_date = encounter_date self.encounter_date = AbsoluteDate(int(encounter_date["year"]), int(encounter_date["month"]), int(encounter_date["day"]), int(encounter_date["hour"]), int(encounter_date["minutes"]), float(encounter_date["seconds"]), self.ts) self.duration = duration self.start_date = self.encounter_date.shiftedBy(-self.duration / 2.) self.end_date = self.encounter_date.shiftedBy(self.duration / 2.) self.frames = frames self.minimum_distance = encounter_distance self.relative_velocity = relative_velocity self.with_terminator = bool(with_terminator) self.with_sunnyside = bool(with_sunnyside) self.timesampler_mode = timesampler_mode self.slowmotion_factor = slowmotion_factor self.render_settings = dict() self.render_settings["exposure"] = exposure self.render_settings["samples"] = samples self.render_settings["device"] = device self.render_settings["tile"] = tile_size self.sssb_settings = sssb self.with_infobox = with_infobox self.with_clipping = with_clipping # Setup rendering engine (renderer) self.setup_renderer() # Setup Sun self.setup_sun(sun) # Setup SSSB self.setup_sssb(sssb) # Setup SC self.setup_spacecraft() # Setup Lightref self.setup_lightref(lightref) def setup_renderer(self): """Create renderer, apply common settings and create sc cam.""" render_dir = utils.check_dir(self.res_dir) raw_dir = utils.check_dir(render_dir / "raw") self.renderer = render.BlenderController(render_dir, raw_dir, self.starcat_dir, self.inst, self.sssb_settings, self.with_infobox, self.with_clipping, ext_logger=self.logger) self.renderer.create_camera("ScCam") self.renderer.configure_camera("ScCam", self.inst.focal_l, self.inst.chip_w) self.renderer.create_scene("SssbConstDist") self.renderer.create_camera("SssbConstDistCam", scenes="SssbConstDist") self.renderer.configure_camera("SssbConstDistCam", self.inst.focal_l, self.inst.chip_w) self.renderer.create_scene("LightRef") self.renderer.create_camera("LightRefCam", scenes="LightRef") self.renderer.configure_camera("LightRefCam", self.inst.focal_l, self.inst.chip_w) self.renderer.set_device(self.render_settings["device"], self.render_settings["tile"]) self.renderer.set_samples(self.render_settings["samples"]) self.renderer.set_exposure(self.render_settings["exposure"]) self.renderer.set_resolution(self.inst.res) self.renderer.set_output_format() def setup_sun(self, settings): """Create Sun and respective render object.""" sun_model_file = Path(settings["model"]["file"]) try: sun_model_file = sun_model_file.resolve() except OSError as e: raise SimulationError(e) if not sun_model_file.is_file(): sun_model_file = self.models_dir / sun_model_file.name sun_model_file = sun_model_file.resolve() if not sun_model_file.is_file(): raise SimulationError("Given SSSB model filename does not exist.") self.sun = CelestialBody(settings["model"]["name"], model_file=sun_model_file) self.sun.render_obj = self.renderer.load_object( self.sun.model_file, self.sun.name) def setup_sssb(self, settings): """Create SmallSolarSystemBody and respective blender object.""" sssb_model_file = Path(settings["model"]["file"]) try: sssb_model_file = sssb_model_file.resolve() except OSError as e: raise SimulationError(e) if not sssb_model_file.is_file(): sssb_model_file = self.models_dir / sssb_model_file.name sssb_model_file = sssb_model_file.resolve() if not sssb_model_file.is_file(): raise SimulationError("Given SSSB model filename does not exist.") self.sssb = SmallSolarSystemBody(settings["model"]["name"], self.mu_sun, settings["trj"], settings["att"], model_file=sssb_model_file) self.sssb.render_obj = self.renderer.load_object( self.sssb.model_file, settings["model"]["name"], ["SssbOnly", "SssbConstDist"]) self.sssb.render_obj.rotation_mode = "AXIS_ANGLE" def setup_spacecraft(self): """Create Spacecraft and respective blender object.""" sssb_state = self.sssb.get_state(self.encounter_date) sc_state = Spacecraft.calc_encounter_state(sssb_state, self.minimum_distance, self.relative_velocity, self.with_terminator, self.with_sunnyside) self.spacecraft = Spacecraft("CI", self.mu_sun, sc_state, self.encounter_date) def setup_lightref(self, settings): """Create lightreference blender object.""" lightref_model_file = Path(settings["model"]["file"]) try: lightref_model_file = lightref_model_file.resolve() except OSError as e: raise SimulationError(e) if not lightref_model_file.is_file(): lightref_model_file = self.models_dir / lightref_model_file.name lightref_model_file = lightref_model_file.resolve() if not lightref_model_file.is_file(): raise SimulationError("Given SSSB model filename does not exist.") self.lightref = self.renderer.load_object(lightref_model_file, settings["model"]["name"], scenes="LightRef") self.lightref.location = (0, 0, 0) def simulate(self): """Do simulation.""" self.logger.debug("Starting simulation") self.logger.debug("Propagating SSSB") self.sssb.propagate(self.start_date, self.end_date, self.frames, self.timesampler_mode, self.slowmotion_factor) self.logger.debug("Propagating Spacecraft") self.spacecraft.propagate(self.start_date, self.end_date, self.frames, self.timesampler_mode, self.slowmotion_factor) self.logger.debug("Simulation completed") self.save_results() def set_rotation(self, sssb_rot, sispoObj): """Set rotation and returns original transformation matrix""" """Assumes that the blender scaling is set to 1""" #sssb_axis = sssb_rot.getAxis(self.sssb.rot_conv) sssb_angle = sssb_rot.getAngle() eul0 = mathutils.Euler((0.0, 0.0, sssb_angle), 'XYZ') eul1 = mathutils.Euler((0.0, sispoObj.Dec, 0.0), 'XYZ') eul2 = mathutils.Euler((0.0, 0.0, sispoObj.RA), 'XYZ') R0 = eul0.to_matrix() R1 = eul1.to_matrix() R2 = eul2.to_matrix() M = R2 @ R1 @ R0 original_transform = sispoObj.render_obj.matrix_world sispoObj.render_obj.matrix_world = M.to_4x4() return original_transform def render(self): """Render simulation scenario.""" self.logger.debug("Rendering simulation") # Render frame by frame for (date, sc_pos, sssb_pos, sssb_rot) in zip(self.spacecraft.date_history, self.spacecraft.pos_history, self.sssb.pos_history, self.sssb.rot_history): date_str = datetime.strptime(date.toString(), "%Y-%m-%dT%H:%M:%S.%f") date_str = date_str.strftime("%Y-%m-%dT%H%M%S-%f") # metadict creation metainfo = dict() metainfo["sssb_pos"] = np.asarray(sssb_pos.toArray()) metainfo["sc_pos"] = np.asarray(sc_pos.toArray()) metainfo["distance"] = sc_pos.distance(sssb_pos) metainfo["date"] = date_str self.set_rotation(sssb_rot, self.sssb) # Update environment self.sun.render_obj.location = -np.asarray( sssb_pos.toArray()) / 1000. # Update sssb and spacecraft pos_sc_rel_sssb = np.asarray( sc_pos.subtract(sssb_pos).toArray()) / 1000. self.renderer.set_camera_location("ScCam", pos_sc_rel_sssb) self.renderer.target_camera(self.sssb.render_obj, "ScCam") # Update scenes/cameras pos_cam_const_dist = pos_sc_rel_sssb * 1000. / np.sqrt( np.dot(pos_sc_rel_sssb, pos_sc_rel_sssb)) self.renderer.set_camera_location("SssbConstDistCam", pos_cam_const_dist) self.renderer.target_camera(self.sssb.render_obj, "SssbConstDistCam") lightrefcam_pos = -np.asarray( sssb_pos.toArray()) * 1000. / np.sqrt( np.dot(np.asarray(sssb_pos.toArray()), np.asarray(sssb_pos.toArray()))) self.renderer.set_camera_location("LightRefCam", lightrefcam_pos) self.renderer.target_camera(self.sun.render_obj, "CalibrationDisk") self.renderer.target_camera(self.lightref, "LightRefCam") # Render blender scenes self.renderer.render(metainfo) self.logger.debug("Rendering completed") def save_results(self): """Save simulation results to a file.""" self.logger.debug("Saving propagation results") print_list = [] print_list.append([self.spacecraft.date_history, "date"]) print_list.append([self.spacecraft.pos_history, "vector"]) print_list.append([self.spacecraft.vel_history, "vector"]) #print_list.append([self.spacecraft.rot_history,False]) print_list.append([self.sssb.pos_history, "vector"]) print_list.append([self.sssb.vel_history, "vector"]) #print_list.append([self.sssb.rot_history,False]) float_formatter = "{:.16f}".format np.set_printoptions(formatter={'float_kind': float_formatter}) with open(str(self.res_dir / "DynamicsHistory.txt"), "w+") as file: for i in range(0, len(self.spacecraft.date_history)): line = "" sepr = "\t" for history in print_list: if (history[1] == "date"): value = history[0][i] elif (history[1] == "vector"): value = np.asarray(history[0][i].toArray()) line = line + str(value) + sepr line = line + "\n" file.write(line) self.logger.debug("Propagation results saved")