⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ogr_navsolve2.c

📁 The OpenGPSRec receiver software runs on the real time operating system RTAI-Linux. It compiles with
💻 C
📖 第 1 页 / 共 4 页
字号:
 * * IN :   satellite ECEF XYZ * IN :   user ECEF XYZ * OUT: azimuth [rad] * OUT: elevation [rad] * OUT: calculation succeeded: stat = TRUE */static void calcAzEl(double *Xs, double *Xu,   double *Az, double *El, int *stat){  long i, k;  double R, p, x, y, z, s;  double e[3][3];  double d[3];  x = Xu[0];  y = Xu[1];  z = Xu[2];  p = sqrt( x * x + y * y);  if ( p == 0.0)    *stat = FALSE;  else    *stat = TRUE;  if ( !*stat)    return;  R = sqrt(x * x + y * y + z * z);  e[0][0] = -(y / p);  e[0][1] = x / p;  e[0][2] = 0.0;  e[1][0] = -(x * z / (p * R));  e[1][1] = -(y * z / (p * R));  e[1][2] = p / R;  e[2][0] = x / R;  e[2][1] = y / R;  e[2][2] = z / R;/* matrix multiply vector from user */  for (k = 0; k <= 2; k++)   {    d[k] = 0.0;    for (i = 0; i <= 2; i++)      d[k] += (Xs[i] - Xu[i]) * e[k][i];      }  s = d[2] / sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);  if (s == 1.0)    *El = 0.5 * M_PI;  else    *El = atan(s / sqrt( 1.0 - s * s));  if ( d[1] == 0.0 && d[0] > 0.0)     *Az = 0.5 * M_PI;  else if ( d[1] == 0.0 && d[0] < 0.0)     *Az = 1.5 * M_PI;  else  {    *Az = atan(d[0] / d[1]);    if (d[1] < 0.0)      *Az += M_PI;    else if (d[1] > 0.0 && d[0] < 0.0)      *Az += 2.0 * M_PI;  }  return;}#endif/* * ion     iono correction coefficients from nav message * * Latu    user's latitude [rad] * Lonu    user's longitude [rad] * Az      SV azimuth [rad] * El    SV elevation [rad] * Ttr    SV signal transmission time [sec] * dTiono  Ionospheric delay [sec] */static double ionocorr( IONO iono, double Latu, double Lonu, double Az,                         double El, double Ttr){  double phi,          Lati, Loni, Latm,          T, F_, x, per, amp,          a0, a1, a2, a3,          b0, b1, b2, b3,         res;/* for clarity copy array */  a0 = Iono.al0;  a1 = Iono.al1;  a2 = Iono.al2;  a3 = Iono.al3;  b0 = Iono.b0;  b1 = Iono.b1;  b2 = Iono.b2;  b3 = Iono.b3;/* convert from radians to semicircles */  Latu /= M_PI;  Lonu /= M_PI;  Az   /= M_PI;  El   /= M_PI;/* calculation */  phi  = 0.0137 / (El + 0.11) - 0.022;  Lati = Latu + phi * cos( Az * M_PI);  if ( Lati > 0.416)    Lati = 0.416;  else if (Lati < -0.416)    Lati = -0.416;  Loni = Lonu + phi * sin( Az * M_PI) / cos( Lati * M_PI);  Latm = Lati + 0.064 * cos( (Loni - 1.617) * M_PI);  T = 4.32e+4 * Loni + Ttr;  while ( T >= 86400.0)    T -= 86400.0;  while ( T < 0.0)    T += 86400.0;  F_ = 1.0 + 16.0 * (0.53 - El) * (0.53 - El) * (0.53 - El);  per = b0 + b1 * Latm + b2 * Latm * Latm + b3 * Latm * Latm * Latm;  if ( per < 72000.0)    per = 72000.0;  x = 2 * M_PI * (T - 50400.0) / per;  amp = a0 +         a1 * Latm +         a2 * Latm * Latm +         a3 * Latm * Latm * Latm;  if ( amp < 0.0)    amp = 0.0;  if ( fabs( x) >= 1.57)    res = F_ * 5.0e-9;  else    res = F_ * (5.0e-9 + amp *       (1.0 - x * x / 2.0 + x * x * x * x / 24.0));  return (res);}#if 0/* * ion     iono correction coefficients from nav message * * Latu    user's latitude [rad] * Lonu    user's longitude [rad] * Az      SV azimuth [rad] * El    SV elevation [rad] * Ttr    SV signal transmission time [sec] * dTiono  Ionospheric delay [sec] */static void ionocorr_old( double *ion, double Latu, double Lonu,   double Az, double El, double Ttr, double *dTiono){  double phi,          Lati, Loni, Latm,          T, F_, x, per, amp,          a0, a1, a2, a3,          b0, b1, b2, b3;/* for clarity copy array */  a0 = ion[0];  a1 = ion[1];  a2 = ion[2];  a3 = ion[3];  b0 = ion[4];  b1 = ion[5];  b2 = ion[6];  b3 = ion[7];//  printf("iono (a) = %.6e %.6e %.6e %.6e\n", a0, a1, a2, a3);//  printf("iono (b) = %.6e %.6e %.6e %.6e\n", b0, b1, b2, b3);/* convert from radians to semicircles */  Latu /= M_PI;  Lonu /= M_PI;  Az   /= M_PI;  El   /= M_PI;/* calculation */  phi  = 0.0137 / (El + 0.11) - 0.022;  Lati = Latu + phi * cos( Az * M_PI);  if (Lati > 0.416)    Lati = 0.416;  else if (Lati < -0.416)    Lati = -0.416;  Loni = Lonu + phi * sin( Az * M_PI) / cos( Lati * M_PI);  Latm = Lati + 0.064 * cos( (Loni - 1.617) * M_PI);  T = 4.32e+4 * Loni + Ttr;  while ( T >= 86400.0)    T -= 86400.0;  while ( T < 0.0)    T += 86400.0;  F_ = 1.0 + 16.0 * (0.53 - El) * (0.53 - El) * (0.53 - El);  per = b0 + b1 * Latm + b2 * Latm * Latm + b3 * Latm * Latm * Latm;  if ( per < 72000.0)    per = 72000.0;  x = 2 * M_PI * (T - 50400.0) / per;  amp = a0 +         a1 * Latm +         a2 * Latm * Latm +         a3 * Latm * Latm * Latm;  if ( amp < 0.0)    amp = 0.0;  if ( fabs( x) >= 1.57)    *dTiono = F_ * 5.0e-9;  else    *dTiono = F_ * (5.0e-9 + amp *       (1.0 - x * x / 2.0 + x * x * x * x / 24.0));  return;}#endif#if 0/*  the following data should be available: * *   1. Pseudorange with receiver time of reception for each SV *   2. Ephemeris and almanac for each SV *   3. Iono coefficients */static void stdalone_input_phase( double *Xlla, double *Trc, int *SV,   double eph[32][16], double clk[32][5], double ion[], double *Praw,   INT16 tr_ch[], INT16 n_tr, double transmit_time[]){  int i, prn; /* GPS time of reception (sampled at TIC) *//* *** CHECKME: n_tr > 0,  *              NavData.tow_tic_count[tr_ch[i]] the same  *              for i=0,...,n_tr-1 *///  for (i=0;i<n_tr;i++)//    printf( "tr_ch = %d, tow = %.9e  ", tr_ch[i], NavData.tow_tic_count[tr_ch[i]] / 10.0);//  printf( "\n");//  printf( "tow (param) = %.9e\n", Ctrl->tow_tic_count / 10.0);/* * NavData.tow_tic_count[tr_ch[0]],...,NavData.tow_tic_count[tr_ch[n_tr-1]] * contain the same value! Just take the first.... */  *Trc = NavData.tow_tic_count[tr_ch[0]] / 10.0;//  printf( "Trc %.9e\n", *Trc);/* iono coefficients */  ion[0] = Iono.al0;  ion[1] = Iono.al1;  ion[2] = Iono.al2;  ion[3] = Iono.al3;  ion[4] = Iono.b0;  ion[5] = Iono.b1;  ion[6] = Iono.b2;  ion[7] = Iono.b3;/* read pseudoranges */  for (prn = 1; prn <= 32; prn++)  {    SV[prn-1]   = FALSE;    Praw[prn-1] = 0.0;  }    for (i = 0; i < n_tr; i++)  {    prn = Chan[tr_ch[i]].prn;    SV[prn-1]   = TRUE;//    Praw[prn-1] = (transmit_time[i] - *Trc) * LIGHTVEL;    Praw[prn-1] = (*Trc - transmit_time[i]) * LIGHTVEL;//    printf( " SV[%d] = %d\n", prn, SV[prn-1]);/* ephemeris- and clock data */#if 0  Eph(1)  = EphData(Idx).Crs ;            % ampl. of sine harm. corr. to orbit radius  Eph(2)  = EphData(Idx).DeltaN / pi;     % mean motion difference  Eph(3)  = EphData(Idx).M0 / pi;         % mean anomaly at ref. time  Eph(4)  = EphData(Idx).Cuc ;            % ampl. of cosine harm. corr. to arg. of  lat.  Eph(5)  = EphData(Idx).Eccentricity;    % eccentricity  Eph(6)  = EphData(Idx).Cus;             % ampl. of sine harm. corr. to arg. of  lat.  Eph(7)  = EphData(Idx).SqrtA;           % square root of semi-major axis  Eph(8)  = EphData(Idx).TimeOfEphemeris; % time of ephemeris             Eph(9)  = EphData(Idx).Cic;             % ampl. of cosine harm. corr. to incl. angle  Eph(10) = EphData(Idx).OMEGA / pi;      % longitde of asc. node of orb. plane  Eph(11) = EphData(Idx).Cis;             % ampl. of sine harm. corr. to incl. angle  Eph(12) = EphData(Idx).InclinationRad / pi;  % incl. angle at ref. time  Eph(13) = EphData(Idx).Crc;             % ampl. of cosine harm. corr. to orbit radius  Eph(14) = EphData(Idx).omega / pi;      % argument of perigee  Eph(15) = EphData(Idx).OMEGADOT / pi;   % rate of right ascension  Eph(16) = EphData(Idx).IDOT / pi;       % rate of incl. angle  INT16  iode,             // issue of date (ephemeris)         iodc,             // issue of date (clock)         ura,         valid,         health,         week;  double dn,               // mean motion - correction         sqra,             // sqrt of semi-major axis         W0,               // longitude of asc node         Wdot,             // date of right ascension         w,                // argument of perigee         tgd,              // group dela differential         toe,              // reference time ephemeris         toc,              // sat clock data reference time [sec]         inc0,             // inclination correction         idot,         cuc, cus, crc, crs, cic, cis, // 2nrd harmonic perturbation         ma,               // mean anomaly         n0,               // computed mean motion         ety,              // eccentricity         af0, af1, af2;    // clock correction#endif    eph[prn-1][0]  = GPS_Eph[prn].crs;    eph[prn-1][1]  = GPS_Eph[prn].dn / PI;    eph[prn-1][2]  = GPS_Eph[prn].ma / PI;    eph[prn-1][3]  = GPS_Eph[prn].cuc;    eph[prn-1][4]  = GPS_Eph[prn].ety;    eph[prn-1][5]  = GPS_Eph[prn].cus;    eph[prn-1][6]  = GPS_Eph[prn].sqra;    eph[prn-1][7]  = GPS_Eph[prn].toe;    eph[prn-1][8]  = GPS_Eph[prn].cic;    eph[prn-1][9]  = GPS_Eph[prn].W0 / PI;    eph[prn-1][10] = GPS_Eph[prn].cis;    eph[prn-1][11] = GPS_Eph[prn].inc0 / PI;    eph[prn-1][12] = GPS_Eph[prn].crc;    eph[prn-1][13] = GPS_Eph[prn].w / PI;    eph[prn-1][14] = GPS_Eph[prn].Wdot / PI;    eph[prn-1][15] = GPS_Eph[prn].idot / PI;//    printf( "prn = %d, sqra = %e\n", prn, eph[prn-1][6]);#if 0      Clk(prn,1)  = EphData(Idx).TGD;             % group delay differential (T_GD)      Clk(prn,2)  = EphData(Idx).TimeOfClock;     % clock data ref time (t_oc)           Clk(prn,3)  = EphData(Idx).ClockDriftRate;  % drift rate      Clk(prn,4)  = EphData(Idx).ClockDrift;      % drift      Clk(prn,5)  = EphData(Idx).ClockBias;       % bias#endif    clk[prn-1][0]  = GPS_Eph[prn].tgd;    clk[prn-1][1]  = GPS_Eph[prn].toc;    clk[prn-1][2]  = GPS_Eph[prn].af2;    clk[prn-1][3]  = GPS_Eph[prn].af1;    clk[prn-1][4]  = GPS_Eph[prn].af0;  }  // --- for (n = 1; n <= n_tr; n++) ---/* user input of start position *//* Start position Lat [deg.dec], Lon [deg.dec], Alt [m] */  Xlla[0] = Rcvr_Info.llh.lat;  Xlla[1] = Rcvr_Info.llh.lon;  Xlla[2] = Rcvr_Info.llh.hae;   // height above ellipsoid  return;}#endif/*  * IN:   ephemeris  eph    *       satellite GPS time  Ttr * OUT:  relativistic correction term  Trel *       satellite position  X   */ECEF satellite_position( INT16 prn, double Ttr, double *Trel){  double     ec, A, T, n0, n, M, E, Eold,              snu, cnu, nu, phi, du, dr, di, u, r, i,             Xdash, Ydash, Wc;  ECEF       res;  EPHEMERIS *eph;//  select ephemeris data  eph = &GPS_Eph[prn];  A    = eph->sqra * eph->sqra;#if 0  Crs  = eph->crs;  dn   = eph->dn;  M0   = eph->ma;  Cuc  = eph->cuc;  ec   = eph->ety;  Cus  = eph->cus;  Toe  = eph->toe;  Cic  = eph->cic;  W0   = eph->W0;  Cis  = eph->cis;  i0   = eph->inc0;  Crc  = eph->crc;  w    = eph->w;  Wdot = eph->Wdot;  Idot = eph->idot;#endif#if 0  if ( first == 0)  {    first = 1;      printf(" dn=%e M0=%e A=%e Toe=%e W0=%e i0%e w=%e Wdot=%e Idot=%e\n",       dn, M0, A, Toe, W0, i0, w, Wdot, Idot);  }#endif  T = Ttr - eph->toe;  if ( T > 302400.0)    T -= 604800.0;  else if (T < -302400.0)    T += 604800.0;//  printf(" T=%.12e Toe=%.12e\n", T, Toe);  n0 = sqrt( GRAVCONST / (A * A * A));  n = n0 + eph->dn;  M = eph->ma + n * T;    E = M;   /* start value for E *///  printf(" dn=%.9e Mo=%.9e ec=%.9e A=%.9e Toe=%.9e W0=%.9e i0=%.9e w=%.9e Wdot=%.9e idot=%.9e\n", //    dn, M0, ec, A, Toe, W0, i0, w, Wdot, Idot);  ec = eph->ety;#if 0  if ( prn == SelPRN)  {    printf(" dn=%.8e M0=%.8e ec=%.8e A=%.8e Toe=%.8e W0=%.8e i0%.8e w=%.8e Wdot=%.8e Idot=%.8e\n",       eph->dn, eph->ma, ec, A, eph->toe, eph->W0, eph->inc0, eph->w, eph->Wdot, eph->idot);  }#endif  do   {    Eold = E;    E = M + ec * sin( E);  } while ( fabs( E - Eold) >= 1.0e-8);//  printf(" M0=%.12e n=%.12e T=%.12e Ttr=%.12e Toe=%.12e E=%.12e\n", M0, n, T, Ttr, Toe, E);//  printf(" E=%.9e M=%.9e ec=%.9e\n", E, M, ec);  snu = sqrt(1 - ec * ec) * sin( E) / (1 - ec * cos( E));  cnu = (cos( E) - ec) / (1 - ec * cos( E));  nu = atan2( snu, cnu);  phi = nu + eph->w;  du = eph->cuc * cos( 2 * phi) + eph->cus * sin( 2 * phi);  dr = eph->crc * cos( 2 * phi) + eph->crs * sin( 2 * phi);  di = eph->cic * cos( 2 * phi) + eph->cis * sin( 2 * phi);  u = phi + du;  r = A * (1 - ec * cos( E)) + dr;  i = eph->inc0 + eph->idot * T + di;  Xdash = r * cos( u);  Ydash = r * sin( u);  Wc = eph->W0 + (eph->Wdot - OMEGAE) * T - OMEGAE * eph->toe;  res.x = Xdash * cos( Wc) - Ydash * cos( i) * sin( Wc);  res.y = Xdash * sin( Wc) + Ydash * cos( i) * cos( Wc);  res.z = Ydash * sin( i);#if 0  if ( prn == SelPRN)  {    printf(" du=%.8e dr=%.8e di=%.8e Xd=%.8e Yd=%.8e Wc=%.8e X=[%.8e %.8e %.8e]\n",       du, dr, di, Xdash, Ydash, Wc, res.x, res.y, res.z);  }#endif  *Trel = FCONST * ec * eph->sqra * sin( E);   /* relativistic correction term */  return (res);}#if 0

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -