OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
APID128.py
Go to the documentation of this file.
1 import numpy as np
2 from .. PacketUtils import *
3 from .. timestamp import *
4 
5 '''
6 Ephemeris: APID 128
7 OM_Ephem_Tlm packet (section 7.1)
8 '''
9 
10 Fields = np.dtype([
11  ('timestamp', CCSDS_timestamp),
12  ('Padding', '>u4'), # Padding to maintain packet alignment
13 
14  ('FSWTime', '>f8'), # seconds since TAI epoch
15  ('sunPosJ2000', '>f8', (3,)), # sun position wrt ECI (m)
16  ('moonPosJ2000', '>f8', (3,)), # moon position wrt ECI (m)
17  ('sunVelJ2000', '>f8', (3,)), # sun velocity wrt ECI (m/sec)
18  ('moonVelJ2000', '>f8', (3,)), # moon velocity wrt ECI (m/sec)
19  ('scPosJ2000', '>f8', (3,)), # PACE position wrt ECI (m)
20  ('scVelJ2000', '>f8', (3,)), # PACE velocity wrt ECI (m/sec)
21  ('PV_Time_GPS', '>f8'), # timestamp relative to GPS epoch (sec)
22  ('DCM_ecef2eci', '>f8', (3,3)), # Direction cosine matrix converting from ECEF to ECI J2000 frame
23  ('magfieldEci', '>f8', (3,)), # Earth mag field ECI (T)
24  ('magfieldEcef', '>f8', (3,)), # Earth mag field ECEF (T)
25  ('isEclipse', '|u1'), # boolean in eclipse flag
26  ('ephemValid', '|u1'), # spacecraft ephemeris validity flag
27  ('Padding2', '|u1', (6,)),
28 
29 ]) # total length = 298 bytes
30 
31 def APID128(data):
32  apid = 128
33  expected = Fields.itemsize
34  if len(data) != expected:
35  print('APID {}: expected={}, actual={}'.format(apid,expected,len(data)))
36 
37  tmp = np.frombuffer(data, dtype=Fields, count=1)
38  myDict = getDict(tmp)
39  myDict['timestamp'] = parse_CCSDS_timestamp(myDict['timestamp'])
40 
41  return myDict
42 
43 def derive_orbitparams(orb_recordlist):
44 
45  # adapted from Fred Patt's IDL routine get_ephem_from_hkt.pro
46  posr = [np.matmul(rec['DCM_ecef2eci'], rec['scPosJ2000']) for rec in orb_recordlist]
47  velr = [np.matmul(rec['DCM_ecef2eci'], rec['scVelJ2000']) for rec in orb_recordlist]
48 
49  omegae = 7.29211585494e-5
50  for i in np.arange(len(orb_recordlist)):
51  velr[i][0] += posr[i][1]*omegae
52  velr[i][1] -= posr[i][0]*omegae
53 
54  # adapted from Fred Patt's IDL routine orb2lla.pro
55  re = 6378.137 # Earth equatorial radius (km)
56  rem = 6371.0 # Earth mean radius (km)
57  f = 1./298.257 # Earth flattening factor
58  omf2 = (1.0-f) * (1.0-f)
59 
60  xyz = np.array([p/1000.0 for p in posr], dtype=np.float64) # convert meters to km
61  x, y, z = [xyz[:,i] for i in np.arange(3)] # separate coords
62 
63  # Compute longitude
64  lon = np.arctan2(y, x)
65 
66  # Compute geodetic latitude
67  rad = np.linalg.norm(xyz,axis=1) # Euclidean distance
68  omf2p = (omf2*rem + rad - rem)/rad
69  pxy = x*x + y*y
70  temp = np.sqrt(z*z + omf2p*omf2p*pxy)
71  lat = np.arcsin(z/temp)
72 
73  # Compute altitude
74  clatg = np.cos(np.arctan(omf2*np.tan(lat)))
75  rl = re*(1.0-f)/np.sqrt(1.0-(2.0-f)*f*clatg*clatg)
76  alt = rad - rl
77 
78  # return as dictionary
79  orbitparams = {}
80  orbitparams['posr'] = posr
81  orbitparams['velr'] = velr
82  orbitparams['lon'] = np.rad2deg(lon)
83  orbitparams['lat'] = np.rad2deg(lat)
84  orbitparams['alt'] = alt * 1000.0 # convert from km to meters
85 
86  return orbitparams
def derive_orbitparams(orb_recordlist)
Definition: APID128.py:43
def getDict(structured_array)
Definition: PacketUtils.py:4
def parse_CCSDS_timestamp(timestr)
Definition: timestamp.py:15
def APID128(data)
Definition: APID128.py:31