Пример #1
0
    def _update_loop(self, stop_when_found=False):
        self.is_updating = True
        logger.debug("Starting _update_loop")
        while self.is_updating:
            try:
                result = str(self.serial_port.readline(), "utf-8")
                logger.debug("Got message from GPS: %s" % result)
                if result.find("GGA") > 0:
                    msg = pynmea2.parse(result)
                    self.latitude = msg.latitude
                    self.longitude = msg.longitude

                    now = datetime.datetime.now()

                    igrf = pyIGRF.igrf_value(self.latitude, self.longitude,
                                             msg.altitude, now.year)
                    self.declination = igrf[0]

                    logger.debug(
                        "Position Update: latitude: %s, longitude: %s, declination: %s"
                        % (self.latitude, self.longitude, self.declination))

                    self.has_position = True

                    if stop_when_found:
                        # Now we have a lock, just exit to free up resources
                        self.is_updating = False
                        logger.info(
                            "Position found and stop_when_found set. Exiting _update_loop"
                        )

            except Exception as ex:
                logger.error(ex)
Пример #2
0
def xyz2hdz(x, y, z, Date, lat, lon, alt=0.0):
    '''
	converts X,Y,Z coordinates to H,D,Z using the IGRF model to get the
	magnetic declination.
	
	'''

    #get the year
    year = DateToYear(Date)

    #find unique year/lat/lon combinations
    n = np.size(x)
    dlla = np.zeros((4, n), dtype='float32')
    dlla[0] = year
    dlla[1] = lat
    dlla[2] = lon
    dlla[3] = alt
    udlla = np.unique(dlla, axis=1)

    #get the declination
    nu = np.size(udlla[0])
    dec = np.zeros(n, dtype='float32')
    for i in range(0, nu):
        dc, _, _, _, _, _, _ = pyIGRF.igrf_value(udlla[1, i], udlla[2, i],
                                                 udlla[3, i], udlla[0, i])
        comp = (dlla.T == udlla.T[i]).all(axis=1)
        use = np.where(comp)[0]
        dec[use] = dc

    #rotate x and y
    dec = dec * np.pi / 180.0
    h = x * np.cos(dec) + y * np.sin(dec)
    d = x * np.sin(dec) - y * np.cos(dec)

    return h, d, z
Пример #3
0
def igrf_mag_vector_ecef(x_ecef, t_jd):

    # convert ecef to latitude and longitude
    xq = u.quantity.Quantity(x_ecef[0], u.km)
    yq = u.quantity.Quantity(x_ecef[1], u.km)
    zq = u.quantity.Quantity(x_ecef[2], u.km)
    loc = EarthLocation(x=xq, y=yq, z=zq)
    longitude, latitude, altitude = loc.to_geodetic()
    lon = longitude.value  # longitude in degrees
    lat = latitude.value  # latitude in degrees
    alt = (altitude.value / 1000) - R_e  # altitude in km

    # get decimal date
    delta = datetime.timedelta(
        days=t_jd)  # convert julian date to delta in days
    d = datetime.datetime(
        2000, 1, 1, 12, 0,
        0) + delta  # will depend on epoch -- currently using jd2000
    decimal_date = (float(d.strftime("%j")) - 1) / 366 + float(
        d.strftime("%Y"))

    # get magnetic field in ecef frame
    r = pyIGRF.igrf_value(lat, lon, alt,
                          decimal_date)  # get magnetic field parameters
    vector = np.array([
        r[3], r[4], r[5]
    ])  # save north, east, and vertical components of magnetic field in nT
    mag_vector_ecef = vector / np.linalg.norm(vector)  # normalize
    return mag_vector_ecef
Пример #4
0
def Mag_Dipole():
    lat = 0.0  ##right at the equator
    lon = 0.0  ##right at the prime meridian
    alt = 500.0  #I'm assuming this is in kilometers above the surface of the Earth
    date = 2021  ##I'm assuming this is the date in a int format and just the year
    result = IGRF.igrf_value(lat, lon, alt, date)
    return result
Пример #5
0
def get_B_field_at_point(r, year=2019):
    '''
    Find the North-East-Down B-field (in nT) in ECEF coordinates 
    '''
    # parse position
    x = r[0]
    y = r[1]
    z = r[2]
    # Convert ECEF position to geodetic
    # ecef = pyproj.Proj(proj='geocent', ellps='WGS84', datum='WGS84')
    # lla = pyproj.Proj(proj='latlong', ellps='WGS84', datum='WGS84')
    # lon, lat, alt = pyproj.transform(ecef, lla, x, y, z, radians=False)
    lat, lon, alt = fc.ecef2lla(r)
    lat = lat * 180 / math.pi
    lon = lon * 180 / math.pi
    # Calculate magnetic field properties
    D, I, H, Bx, By, Bz, F = pyIGRF.igrf_value(lat, lon, alt, year)

    return Bx, By, Bz
Пример #6
0
def bfield_arr(lat, lon, alt, date):
    #This function takes latitude and longitude arrays in degrees
    #Altitude in units of km above ground level (AGL) and a date in a
    #int format like 2020 or 2021
    if len(lat) != len(lon) or len(lon) != len(alt):
        print('Array length not correct')
        return 0, 0, 0, 0
    bx_arr = 0 * lat
    by_arr = 0 * lat
    bz_arr = 0 * lat
    btotal_arr = 0 * lat
    for i in range(0, len(lat)):
        ##Make the call to the IGRF module (assuming date is a constant)
        result = IGRF.igrf_value(lat[i], lon[i], alt[i], date)
        ##Parse out the result (mag field strength is in nT)
        bx_arr[i] = result[3]
        by_arr[i] = result[4]
        bz_arr[i] = result[5]
        btotal_arr[i] = result[6]
    return bx_arr, by_arr, bz_arr, btotal_arr
Пример #7
0
def get_orbit_magnetic(TLE, epoch, sec_past_epoch, wgs=wgs84):
    '''
    determine magnetic field properties from orbit state, in ECEF!!!!
    '''
    r = get_orbit_pos(TLE, epoch, sec_past_epoch, wgs)
    # parse orbit state
    x = r[0]
    y = r[1]
    z = r[2]
    epoch = epoch.split('-')
    year = int(epoch[0])
    # Convert ECEF position to geodetic
    # ecef = pyproj.Proj(proj='geocent', ellps='WGS84', datum='WGS84')
    # lla = pyproj.Proj(proj='latlong', ellps='WGS84', datum='WGS84')
    # lon, lat, alt = pyproj.transform(ecef, lla, x, y, z, radians=False)
    lat, lon, alt = fc.ecef2lla(r)
    # Calculate magnetic field properties
    lat = lat * 180 / math.pi
    lon = lon * 180 / math.pi
    D, I, H, Bx, By, Bz, F = pyIGRF.igrf_value(lat, lon, alt, year)

    return Bx, By, Bz
Пример #8
0
def igrffx(eci_vec, time):
    #import igrf12
    import numpy
    import pyIGRF
    import pymap3d
    from pymap3d import ecef2eci
    import navpy
    from navpy import ned2ecef
    import datetime
    from datetime import datetime
    import astropy
    #eci_vec is a xyz vector in ECI  km
    #output B_ECI is a 3 item array in units of T

    #get our lat long and alt from ECI
    geod = pymap3d.eci2geodetic(1000 * eci_vec, time, useastropy=True)

    latitude = geod[0][0]  #degrees
    longitude = geod[1][0]  #degrees
    altitude = geod[2]  #meters

    #call igrf to get b vector in NED
    #mag = igrf12.igrf('2019-01-12', glat=latitude, glon=longitude, alt_km=altitude/1000)
    b = pyIGRF.igrf_value(latitude, longitude, altitude / 1000, 2019)

    #combine NED components back into an array
    #NED = numpy.array([b_north,b_east,b_down])
    NED = b[3:6]

    #convert from NED to ECEF
    ECEF = navpy.ned2ecef(NED, latitude, longitude, altitude)

    #convert from ECEF to ECI
    B_ECI = (pymap3d.ecef2eci(ECEF, time, useastropy=True)) * 10**(-9)

    return B_ECI
Пример #9
0
                  & (Fulldata2[' Time LO    '] > mintime)]

#below was for checking my column headers names
#print(list(data2.columns.values))

time2 = data2[' Time LO    ']
Long = data2[' Longitude ']
Lat = data2[' Latitude  ']
Alt = data2[' Altitude  ']

#convert ft to km
Altkm = Alt * 0.0003048

EarthMagData = np.empty((len(time2), 8))
for i in range(len(time2)):
    A = pyIGRF.igrf_value(Lat.iloc[i], Long.iloc[i], Altkm.iloc[i], 2018)
    EarthMagData[i, 0] = time2.iloc[i]
    EarthMagData[i, 1] = A[0]
    EarthMagData[i, 2] = A[1]
    EarthMagData[i, 3] = A[2]
    EarthMagData[i, 4] = A[3]
    EarthMagData[i, 5] = A[4]
    EarthMagData[i, 6] = A[5]
    EarthMagData[i, 7] = A[6]

#saving magnetic field data and time
np.savetxt(
    'EarthMagdata.csv',
    EarthMagData,
    delimiter=', ',
    header='Time,D(east),I(down), H,X (north),Y (east),Z (down),F(total)')
Пример #10
0
import pyIGRF

if __name__ == '__main__':
    lat = 40
    lon = 116
    alt = 300
    date = 1999
    print(pyIGRF.igrf_value.__doc__)
    print(pyIGRF.igrf_variation.__doc__)
    print(pyIGRF.igrf_value(lat, lon, alt, date))
    print(pyIGRF.igrf_variation(lat, lon, alt, date))
    g, h = pyIGRF.loadCoeffs.get_coeffs(date)
    print(len(g))
    print(len(h))
max_lon = 180
delta = 2

lat_range = np.arange(min_lat, max_lat, delta)
lon_range = np.arange(min_lon, max_lon, delta)

mag_field_strength_cpp = np.zeros((np.size(lat_range), np.size(lon_range)))
mag_field_strength_igrf = np.zeros((np.size(lat_range), np.size(lon_range)))
err = np.zeros((np.size(lat_range), np.size(lon_range)))
for i, lat in enumerate(lat_range):
    for j, lon in enumerate(lon_range):

        B_vec = magnetic_field_cpp.get_magnetic_field(lat, lon, alt, year, 10)
        mag_field_strength_cpp[i, j] = np.linalg.norm(B_vec)

        D, I, H, Bx, By, Bz, F = pyIGRF.igrf_value(lat, lon, alt, year)
        mag_field_strength_igrf[i, j] = F
        err[i, j] = abs(mag_field_strength_cpp[i, j] -
                        mag_field_strength_igrf[i, j])

X, Y = np.meshgrid(lon_range, lat_range)

fig1, ax = plt.subplots()
CS = ax.contour(X, Y, mag_field_strength_cpp, 30)
CB = fig1.colorbar(CS, shrink=0.8, extend='both')
ax.set_title('5th Order IGRF (Our Model)')
# plt.show()

fig2, ax2 = plt.subplots()
CS = ax2.contour(X, Y, mag_field_strength_igrf, 30)
CB = fig2.colorbar(CS, shrink=0.8, extend='both')
Пример #12
0
        by_arr[i] = result[4]
        bz_arr[i] = result[5]
        btotal_arr[i] = result[6]
    return bx_arr, by_arr, bz_arr, btotal_arr


if __name__ == '__main__':
    print('Running Example Script')

    lat = 0.0  ##right at the equator
    lon = 0.0  ##right at the prime meridian
    alt = 100.0  #I'm assuming this is in kilometers above the surface of the Earth
    date = 2021  ##I'm assuming this is the date in a int format and just the year

    ##Make the call to the IGRF module
    result = IGRF.igrf_value(lat, lon, alt, date)

    ##Parse out the result (mag field strength is in nT)
    bx = result[3]
    by = result[4]
    bz = result[5]
    btotal = result[6]

    print('B-field = ', bx, by, bz, btotal)

    ##Plot out B-field as a function of a specific orbit
    #Using custom Earth_Orbit module
    rp = 400.0  #km
    ra = 160000.0  #km
    orbit = orb.Earth_Orbit(ra, rp)
Пример #13
0
def Satellite(t, state):

    x = state[0]
    y = state[1]
    z = state[2]
    q0 = state[6]
    q1 = state[7]
    q2 = state[8]
    q3 = state[9]
    q0123 = np.array([q0,q1,q2,q3])
    p = state[10]
    q = state[11]
    r = state[12]
    pqr = np.array([p,q,r])


    # intertia and mass
    m = globals.m # kg
    I = globals.I #kg-m^2
    invI = globals.invI

    # Translational Kinematics
    vel = np.array([state[3],state[4],state[5]])

    # Rotational Kinematics
    PQRMAT = np.array([
        [0, -p, -q, -r],
        [p, 0, r, -q],
        [q, -r, 0, p],
        [r, q, -p, 0]
    ])
    q0123dot = 0.5*np.dot(PQRMAT, q0123)

    # Gravity model
    r_st = np.array([state[0],state[1],state[2]]) # r = [x,y,z]
    rho = np.linalg.norm(r_st)
    rhat = np.divide(r_st,rho)
    Fgrav = -(G*M*m/np.power(rho,2))*rhat

    # Magnetic field model (pyIGRF)
    phiE = 0
    thetaE = np.arccos(z/rho)
    psiE = np.arctan2(y,x)
    latitude = 90-thetaE*180/np.pi
    longitude = psiE*180/np.pi
    igrf_output = pyIGRF.igrf_value(latitude, longitude, altitude, 2020)
    BN = igrf_output[3]
    BE = igrf_output[4]
    BD = igrf_output[5]
    BNED = np.array([BN,BE,BD])
    # Transform to ECI frame
    BI = np.dot(TIB(phiE, thetaE+np.pi, psiE), BNED)
    BB = np.dot(TIBquat(q0123),BI) * 1e-9
    globals.BB = BB

    # magnetorquer parameters
    n_aircore = 195 # turns
    n_rods = 440 # turns
    A_aircore = 0.006084 # m^2
    A_rod = 0.0001423 # m^2
    nA = np.array([n_rods*A_rod, n_rods*A_rod, n_aircore*A_aircore])

    # Control Block
    current = Control(BB,pqr)
    muB = np.array([current[0]*nA[0], current[1]*nA[1], current[2]*nA[2]])
    globals.current = current

    # Magnetorquer Model
    LMN_magtorquers = np.cross(muB,BB)
    #LMN_magtorquers = np.array([0,0,0])

    # Translational Dynamics
    F = Fgrav
    accel = np.divide(F,m)

    # Rotational Dynamics
    H = np.dot(I,pqr)
    pqrdot = np.dot(invI,(LMN_magtorquers - np.cross(pqr,H)))

    # Return derivatives vector
    dstatedt = np.empty((13,))
    dstatedt[0] = vel[0]
    dstatedt[1] = vel[1]
    dstatedt[2] = vel[2]
    dstatedt[3] = accel[0]
    dstatedt[4] = accel[1]
    dstatedt[5] = accel[2]
    dstatedt[6] = q0123dot[0]
    dstatedt[7] = q0123dot[1]
    dstatedt[8] = q0123dot[2]
    dstatedt[9] = q0123dot[3]
    dstatedt[10] = pqrdot[0]
    dstatedt[11] = pqrdot[1]
    dstatedt[12] = pqrdot[2]
    return dstatedt
Пример #14
0
 def mag_vector_ecef(self):
     value = pyIGRF.igrf_value(self.latitude, self.longitude, self.altitude,
                               self.decimal_date(datetime.datetime.now()))
     return np.array([value[3], value[4], value[5]])