Beispiel #1
0
def continue_sim(sim_dataset, num_iter, file_name):
    import copy
    original_params = eval(sim_dataset.simulation_parameters)
    sim_params = copy.deepcopy(original_params)
    sim_params['end_time_index'] = num_iter
    sim_params['start_time'] = sim_params['final_time']
    last_data = sim_dataset.isel(time=-1)
    sim_params[
        'omega0_body'] = last_data.dcm_bn.values @ last_data.angular_vel.values
    sim_params['sigma0'] = tr.dcm_to_mrp(last_data.dcm_bn.values)
    cubesat_params = eval(sim_dataset.cubesat_parameters)
    new_data = sim_attitude(sim_params,
                            cubesat_params,
                            'easter_egg',
                            save=False,
                            ret=True)
    new_data['time'] = np.arange(
        len(sim_dataset.time),
        len(sim_dataset.time) +
        sim_params['end_time_index'] * sim_params['save_every'], 1)
    a = xr.concat([sim_dataset, new_data], dim='time')
    true_sim_params = eval(a.simulation_parameters)
    true_sim_params[
        'end_time_index'] = original_params['end_time_index'] + num_iter
    true_sim_params['final_time'] = eval(
        new_data.simulation_parameters)['final_time']
    a.attrs['simulation_parameters'] = str(true_sim_params)
    a.to_netcdf(
        os.path.join(os.path.dirname(__file__), f'../../{file_name}.nc'))
Beispiel #2
0
 def test_mrp_valid_dcm():
     dcm1 = ut.random_dcm()
     b = tr.dcm_to_mrp(dcm1)
     dcm2 = tr.mrp_to_dcm(b)
     np.testing.assert_almost_equal(dcm2 @ dcm2.T, np.identity(3))
     np.testing.assert_almost_equal(np.linalg.det(dcm2), 1)
     for i in (0, 1, 2):
         np.testing.assert_almost_equal(np.linalg.norm(dcm2[i]), 1)
         np.testing.assert_almost_equal(np.linalg.norm(dcm2[:, i]), 1)
def mrp_triad_with_noise(sigma, v1n, v2n, arbitrary_error1, arbitrary_error2):
    # TODO: make the error not arbitrary (e.g. This function could produce a random unit vector in a conical section defined by some angle input)

    dcm_bn = tr.mrp_to_dcm(sigma)
    v1b = dcm_bn @ v1n + np.random.random_sample(3) * arbitrary_error1
    v2b = dcm_bn @ v2n + np.random.random_sample(3) * arbitrary_error2
    v1b = v1b / np.linalg.norm(v1b)
    v2b = v2b / np.linalg.norm(v2b)

    dcm_bn_triad = triad(v1n, v2n, v1b, v2b)
    return tr.dcm_to_mrp(dcm_bn_triad)
Beispiel #4
0
def get_mrp_br(dcm_rn, sigma):
    dcm_br = tr.mrp_to_dcm(sigma) @ dcm_rn.T
    return tr.dcm_to_mrp(dcm_br)
Beispiel #5
0
save_data = xr.open_dataset('orbit_pre_process.nc')
time_tracks = [datetime(2019, 3, 24, 18, 35, 1, tzinfo=utc) + timedelta(seconds=time_step*i) for i in range(len(time))]
saved_data = save_data.interp(time=time_tracks)
sun_vec = saved_data.sun.values
mag_field = saved_data.mag.values
density = saved_data.atmos.values
lons = saved_data.lons.values
lats = saved_data.lats.values
alts = saved_data.alts.values
positions = saved_data.positions.values
velocities = saved_data.velocities.values


# initialize attitude so that z direction of body frame is aligned with nadir
dcm0 = ut.initial_align_gravity_stabilization(positions[0], velocities[0])
sigma0 = tr.dcm_to_mrp(dcm0)
# initialize angular velocity so that it is approximately the speed of rotation around the earth
omega0_body = np.array([0, -0.1, 0.05])
omega0 = dcm0.T @ omega0_body
states[0] = [sigma0, omega0]
dcm_bn[0] = tr.mrp_to_dcm(states[0][0])
dcm_on[0] = ut.inertial_to_orbit_frame(positions[0], velocities[0])
dcm_bo[0] = dcm_bn[0] @ dcm_on[0].T

# get initial b field so that hysteresis rods can be initialized properly
mag_field[0] = geomag.GeoMag(np.array([lats[0], lons[0], alts[0]]), time_tracks[0], output_format='inertial')
mag_field_body[0] = (dcm_bn[0] @ mag_field[0]) * 10 ** -9  # in the body frame in units of T
# cubesat.hyst_rods[0].h_current = mag_field_body[0][0]/cubesat.hyst_rods[0].u0

# the integration
for i in tqdm(range(len(time) - 1)):
states_bn[0] = [sigma0, omega0]
controls = np.zeros((len(time), 3))
# states_br[0] = [sigma0, omega0]
dcm_br = np.zeros((len(time), 3, 3))
# dcm_br[0] = tr.mrp_to_dcm(states_br[0][0])
dcm_bn = np.zeros((len(time), 3, 3))
for i in range(len(time) - 1):
    # do attitude determination (this needs to change now that the state is defined in the reference frame)
    # sigma_estimated = ae.mrp_triad_with_noise(states_br[i][0], sun_vec, mag_vec, 0.01, 0.01)
    # sigma_estimated = ae.mrp_triad_with_noise(states_br[i][0], sun_vec, mag_vec, 0.0, 0.0)
    # sigma_estimated = states_br[i][0]

    dcm_bn[i] = tr.mrp_to_dcm(states_bn[i][0])
    dcm_rn[i] = rf.get_dcm_rn(time[i])
    dcm_br[i] = dcm_bn[i] @ dcm_rn[i].T
    sigma_br = tr.dcm_to_mrp(dcm_br[i])

    # get reference frame velocities
    omega_r = dcm_br[i] @ rf.get_omega_r(time[i])  # convert from reference frame to body frame
    omega_dot_r = dcm_br[i] @ rf.get_omega_r_dot(time[i])  # convert from reference frame to body frame
    # next step: numerically approximate these from reference frame position wrt time?

    # get control torques
    controls[i] = cl.control_torque_ref_frame(sigma_br, states_bn[i][1], omega_r, omega_dot_r, inertia, K, P, i,
                                              controls[i - 1], max_torque=max_torque)

    # propagate attitude state
    states_bn[i + 1] = it.rk4(st.state_dot_ref_frame, time_step, states_bn[i], controls[i], omega_r, inertia,
                              inertia_inv)

    # do 'tidy' up things at the end of integration (needed for many types of attitude coordinates)
Beispiel #7
0
 def test_mrp_reverse():
     dcm1 = ut.random_dcm()
     b = tr.dcm_to_mrp(dcm1)
     dcm2 = tr.mrp_to_dcm(b)
     np.testing.assert_almost_equal(dcm1, dcm2)