<*-CSTDLIB  *>
<*+NOHEADER *>
<*+M2EXTENSIONS *>
DEFINITION MODULE ["C"] gps;

FROM SYSTEM IMPORT CARD16, CARD8;

TYPE
(*
  GNSS_structKlobuchar=RECORD
    isValid:CARD16; (* Is this structure valid for use 1=YES, 0=NO.*)
    week:CARD16;    (* The GPS week corresponding to the correction parameters [weeks]. *)
    tow:CARDINAL;   (* The GPS time of week corresponding to the correction parameters [s]. *)
    alpha0,         (* coefficients of a cubic equation representing the amplitude of the ve *)
    alpha1,         (* coefficients of a cubic equation representing the amplitude of the ve *)
    alpha2,         (* coefficients of a cubic equation representing the amplitude of the ve *)
    alpha3,         (* coefficients of a cubic equation representing the amplitude of the ve *)
    beta0,          (* coefficients of a cubic equation representing the period of the model *)
    beta1,          (* coefficients of a cubic equation representing the period of the model *)
    beta2,          (* coefficients of a cubic equation representing the period of the model *)
    beta3:LONGREAL; (* coefficients of a cubic equation representing the period of the model *)
  END;
*)

(*
  GPS_structEphemeris=RECORD
    toe,                (* reference time ephemeris (0-604800) *)
    toc:CARDINAL;       (* reference time (clock)   (0-604800) *)
    prn,                (* GPS PRN number *)
    week,               (* 10 bit gps week 0-1023 (user must account for week rollove *)
    iodc,               (* 10 bit issue of data (clock) *)
    reserved1:CARD16;   (* reserved bytes *)
    iode,               (* 8 bit  issue of data (ephemeris) *)
    health,             (* 6 bit health parameter, 0 if healthy, unhealth othersize *)
    alert_flag,         (* 1 = URA may be worse than indicated *)
    anti_spoof,         (* anti-spoof flag from 0=off, 1=on *)
    code_on_L2,         (* 0=reserved, 1=P code on L2, 2=C/A on L2 *)
    L2_P_data_flag,     (* flag indicating if P is on L2 1=true *)
    fit_interval_flag,  (* fit interval flag (four hour interval or longer) 0=4 fours *)
    ura:CHAR;           (* User Range Accuracy lookup code, 0 is excellent, 15 is use *)
    age_of_data_offset, (* age of data offset *)
    tow_week:CARD16;    (* The week corresponding to tow (0-1024+). Can be one week l *)
    tow:CARDINAL;       (* The time of week derived formt the Z-count in the Hand Ove *)

(* clock parameters *)
    tgd,          (* group delay *)
    af2,          (* polynomial clock correction coefficient (rate of clock drift) *)
    af1,          (* polynomial clock correction coefficient (clock drift) *)
    af0:LONGREAL; (* polynomial clock correction coefficient (clock bias) *)

(* ephemeris parameters *)
    m0,         (* mean anomaly at reference time *)
    delta_n,    (* mean motion difference from computed value *)
    ecc,        (* eccentricity *)
    sqrta,      (* square root of the semi-major axis *)
    omega0,     (* longitude of ascending node of orbit plane at weekly epoch *)
    i0,         (* inclination angle at reference time *)
    w,          (* argument of perigee *)
    omegadot,   (* rate of right ascension *)
    idot,       (* rate of inclination angle *)
    cuc,        (* amplitude of the cosine harmonic correction term to the argument o *)
    cus,        (* amplitude of the sine harmonic correction term to the argument of *)
    crc,        (* amplitude of the cosine harmonic correction term to the orbit radi *)
    crs,        (* amplitude of the sine harmonic correction term to the orbit radius *)
    cic,        (* amplitude of the cosine harmonic correction term to the angle of i  *)
    cis:LONGREAL; (* amplitude of the sine harmonic correction term to the angle of inc *)
  END;

*)
PROCEDURE GPS_ComputeSatellitePositionVelocityAzimuthElevationDoppler_BasedOnAlmanacData(
  userX,          (* user X position WGS84 ECEF                                   [m] *)
  userY,          (* user Y position WGS84 ECEF                                   [m] *)
  userZ:LONGREAL; (* user Z position WGS84 ECEF                                   [m] *)
  gpsweek:CARD16; (* user gps week (0-1024+)                                      [week] *)
  gpstow,         (* user time of week                                            [s] *)
  toa:LONGREAL;   (* time of applicability                                        [s] *)
  almanac_week,   (* gps week of almanac (0-1024+)                                [week] *)
  prn:CARD16;     (* GPS prn number                                               [] *)
  ecc,            (* eccentricity                                                 [] *)
  i0,             (* orbital inclination at reference time                        [rad] *)
  omegadot,       (* rate of right ascension                                      [rad/s] *)
  sqrta,          (* square root of the semi-major axis                           [m^(1/2)] *)
  omega0,         (* longitude of ascending node of orbit plane at weekly epoch   [rad] *)
  w,              (* argument of perigee                                          [rad] *)
  m0,             (* mean anomaly at reference time                               [rad] *)
  af0,            (* polynomial clock correction coefficient (clock bias)         [s],   Note: parameters from ephemeris preferred vs almanac (22 vs 11 bits) *)
  af1:LONGREAL;   (* polynomial clock correction coefficient (clock drift)        [s/s], Note: parameters from ephemeris preferred vs almanac (16 vs 11 bits) *)
  VAR clock_correction, (* clock correction for this satellite for this epoch           [m] *)
  clock_drift,    (* clock drift correction for this satellite for this epoch     [m/s] *)
  satX,           (* satellite X position WGS84 ECEF                              [m] *)
  satY,           (* satellite Y position WGS84 ECEF                              [m] *)
  satZ,           (* satellite Z position WGS84 ECEF                              [m] *)
  satVx,          (* satellite X velocity WGS84 ECEF                              [m/s] *)
  satVy,          (* satellite Y velocity WGS84 ECEF                              [m/s] *)
  satVz,          (* satellite Z velocity WGS84 ECEF                              [m/s] *)
  azimuth,        (* satelilte azimuth                                            [rad] *)
  elevation,      (* satelilte elevation                                          [rad] *)
  doppler:LONGREAL (* satellite doppler with respect to the user position          [m/s], Note: User must convert to Hz *)
  );

PROCEDURE GPS_ComputeSatellitePositionVelocityAzimuthElevationDoppler_BasedOnEphmerisData(
  userX,          (* user X position WGS84 ECEF                                   [m] *)
  userY,          (* user Y position WGS84 ECEF                                   [m] *)
  userZ:LONGREAL; (* user Z position WGS84 ECEF                                   [m] *)
  gpsweek:CARD16; (* user gps week (0-1024+)                                      [week] *)
  gpstow:LONGREAL;(* user time of week                                            [s] *)
  ephem_week:CARD16; (* ephemeris: GPS week (0-1024+) *)
  toe,            (* ephemeris: time of week *)
  toc:CARDINAL;   (* ephemeris: clock reference time of week *)
  af0,            (* ephemeris: polynomial clock correction coefficient *)
  af1,            (* ephemeris: polynomial clock correction coefficient *)
  af2,            (* ephemeris: polynomial clock correction coefficient *)
  tgd,            (* ephemeris: group delay differential between L1 and L2 *)
  m0,             (* ephemeris: mean anomaly at reference time *)
  delta_n,        (* ephemeris: mean motion difference from computed value *)
  ecc,            (* ephemeris: eccentricity *)
  sqrta,          (* ephemeris: square root of the semi-major axis *)
  omega0,         (* ephemeris: longitude of ascending node of orbit plane at w *)
  i0,             (* ephemeris: inclination angle at reference time *)
  w,              (* ephemeris: argument of perigee *)
  omegadot,       (* ephemeris: rate of right ascension *)
  idot,           (* ephemeris: rate of inclination angle *)
  cuc,            (*  ephemeris: amplitude of the cosine harmonic correction ter *)
  cus,            (* ephemeris: amplitude of the sine   harmonic correction ter *) 
  crc,            (* ephemeris: amplitude of the cosine harmonic correction ter *)     
  crs,            (* ephemeris: amplitude of the sine   harmonic correction ter *)  
  cic,            (* ephemeris: amplitude of the cosine harmonic correction ter *)
  cis:LONGREAL;   (* ephemeris: amplitude of the sine   harmonic correction ter *)
  VAR clock_correction,  (* clock correction for this satellite for this epoch [m]*)
  clock_drift,    (* clock drift correction for this satellite for this epoch     [m/s] *)
  satX,           (* satellite X position WGS84 ECEF                              [m] *)
  satY,           (* satellite Y position WGS84 ECEF                              [m] *)
  satZ,           (* satellite Z position WGS84 ECEF                              [m] *)
  satVx,          (* satellite X velocity WGS84 ECEF                              [m/s] *)
  satVy,          (* satellite Y velocity WGS84 ECEF                              [m/s] *)
  satVz,          (* satellite Z velocity WGS84 ECEF                              [m/s] *)
  azimuth,        (* satelilte azimuth                                            [rad] *)
  elevation,      (* satelilte elevation                                          [rad] *)
  doppler:LONGREAL (* satellite doppler with respect to the user position  [m/s] *)
  );

END gps.
