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

📄 ogr_navsolve.c

📁 The OpenGPSRec receiver software runs on the real time operating system RTAI-Linux. It compiles with
💻 C
📖 第 1 页 / 共 4 页
字号:
  thet = atan( pos.z * EARTH_MAJ_AXIS / (p*EARTH_MIN_AXIS));  esq  = 1.0 - EARTH_MIN_AXIS*EARTH_MIN_AXIS / (EARTH_MAJ_AXIS*EARTH_MAJ_AXIS);  epsq = EARTH_MAJ_AXIS*EARTH_MAJ_AXIS / (EARTH_MIN_AXIS*EARTH_MIN_AXIS) - 1.0;  res.lat = atan( (pos.z + epsq*EARTH_MIN_AXIS * pow( sin( thet), 3.0)) /                  (p     - esq*EARTH_MAJ_AXIS*pow( cos( thet), 3.0)));  res.lon = atan2( pos.y, pos.x);  n = EARTH_MAJ_AXIS*EARTH_MAJ_AXIS /    sqrt( EARTH_MAJ_AXIS * EARTH_MAJ_AXIS * cos( res.lat) * cos( res.lat) +          EARTH_MIN_AXIS * EARTH_MIN_AXIS * sin( res.lat) * sin( res.lat));  res.hae = p / cos( res.lat) - n;  return (res);}/*******************************************************************************FUNCTION llh_to_ecef()RETURNS  position in Earth-centered, earth-fixed coordinatesPARAMETERS  Position in longitude/latitude/height coordinatesPURPOSE  transform from longitude/latitude/height coordinates to  Earth-centered, earth-fixed coordinatesWRITTEN BY  Clifford Kelley*******************************************************************************/ECEF llh_to_ecef( LLH pos){  double n;  ECEF res;  n = EARTH_MAJ_AXIS * EARTH_MAJ_AXIS /       sqrt( EARTH_MAJ_AXIS * EARTH_MAJ_AXIS *             cos( pos.lat) * cos( pos.lat) +             EARTH_MIN_AXIS * EARTH_MIN_AXIS *             sin( pos.lat) * sin( pos.lat));  res.x = (n+pos.hae) * cos( pos.lat) * cos( pos.lon);  res.y = (n+pos.hae) * cos( pos.lat) * sin( pos.lon);  res.z = (EARTH_MIN_AXIS*EARTH_MIN_AXIS /           (EARTH_MAJ_AXIS*EARTH_MAJ_AXIS)*n+pos.hae)*sin(pos.lat);  return (res);}#ifdef USE_OPENSRCGPS_NAVFIX/*******************************************************************************FUNCTION pos_vel_time( INT16)RETURNS  None.PARAMETERS   nsl : number of pseudoranges measuredPURPOSE  This routine processes the all-in-view pseudorange to arrive  at a receiver positionINPUTS:    pseudo_range[nsl] Vector of measured range from satellites to the receiver    sat_location[nsl][3] Array of satellite locations in ECEF when the signal was sent    nsl      number of satellites usedOUTPUTS:    RP[3]    VECTOR OF RECEIVER POSITION IN ECEF (X,Y,Z)    CBIAS    RECEIVER CLOCK BIAS FROM GPS TIMEVARIABLES USED:    C        SPEED OF LIGHT IN VACUUM IN M/S    S[6][5]  MATRIX USED FOR SOLVING FOR RECEIVER POSITION CORRECTION    B[5]     RESULTING RECEIVER CLOCK BIAS & POSITION CORRECTIONS    X,Y,Z    TEMPORARY RECEIVER POSITION    T        TEMPORARY RECEIVER CLOCK BIAS    R[5]     RANGE FROM RECEIVER TO SATELLITESIF THE POSITION CANNOT BE DETERMINED THE RESULT OF RPWILL BE (0,0,0) THE CENTER OF THE EARTHWRITTEN BY  Clifford Kelley*******************************************************************************/static PVT pos_vel_time( INT16 nsl, ECEF d_sat[]){  INT16  i, j, k,          nits;  double dd[5][5], r,          ms[5][13],          pm[5][13],          bm[13],          br[5],         correct_mag = 0.0, x, y, z, t,         a1, b1, c1, d1, e1, f1, g1, h1,          i1, j1, k1, l1, m1, n1, o1, p1,         denom, alpha;  PVT    res;////  USE ITERATIVE APPROACH TO SOLVING FOR THE POSITION OF//  THE RECEIVER//  nits = 0;  t = 0.0;  x = rec_pos_xyz.x;  y = rec_pos_xyz.y;  z = rec_pos_xyz.z;  do  {    for ( i=1; i<=nsl; i++)    {/* *   Compute range in ECI at the time of arrival at the receiver */      alpha = (dt[i]-t)*OMEGAE;      r = sqrt( pow( track_sat[i].x*cos(alpha) - track_sat[i].y*sin(alpha)-x, 2.0)+                pow( track_sat[i].y*cos(alpha) + track_sat[i].x*sin(alpha)-y, 2.0)+                pow( track_sat[i].z-z, 2.0));      bm[i] = r-(dt[i]-t)*LIGHTVEL;      ms[1][i] = (track_sat[i].x*cos(alpha) - track_sat[i].y*sin(alpha)-x)/r;      ms[2][i] = (track_sat[i].y*cos(alpha) + track_sat[i].x*sin(alpha)-y)/r;      ms[3][i] = (track_sat[i].z-z)/r;      ms[4][i] = 1.0;    }    a1=0.0; b1=0.0; c1=0.0; d1=0.0;    e1=0.0; f1=0.0; g1=0.0; h1=0.0;    i1=0.0; j1=0.0; k1=0.0; l1=0.0;    m1=0.0; n1=0.0; o1=0.0; p1=0.0;    for (k=1; k<=nsl; k++)    {      a1 += ms[1][k]*ms[1][k];      b1 += ms[1][k]*ms[2][k];      c1 += ms[1][k]*ms[3][k];      d1 += ms[1][k]*ms[4][k];//       e1+=ms[2][k]*ms[1][k];      f1 += ms[2][k]*ms[2][k];      g1 += ms[2][k]*ms[3][k];      h1 += ms[2][k]*ms[4][k];//       i1+=ms[3][k]*ms[1][k];//       j1+=ms[3][k]*ms[2][k];      k1 += ms[3][k]*ms[3][k];      l1 += ms[3][k]*ms[4][k];//       m1+=ms[1][k];//       n1+=ms[2][k];//       o1+=ms[3][k];      p1 += ms[4][k];    }    o1=l1;    m1=d1;    n1=h1;    e1=b1;    i1=c1;    j1=g1;////  SOLVE FOR THE MATRIX INVERSE//    denom = (k1*p1-l1*o1)*(a1*f1-b1*e1) +             (l1*n1-j1*p1)*(a1*g1-c1*e1) +             (j1*o1-k1*n1)*(a1*h1-d1*e1) +             (l1*m1-i1*p1)*(c1*f1-b1*g1) +             (i1*o1-k1*m1)*(d1*f1-b1*h1) +             (i1*n1-j1*m1)*(c1*h1-d1*g1);    dd[1][1] = f1*(k1*p1-l1*o1) + g1*(l1*n1-j1*p1) + h1*(j1*o1-k1*n1);    dd[1][2] = e1*(l1*o1-k1*p1) + g1*(i1*p1-l1*m1) + h1*(k1*m1-i1*o1);    dd[1][3] = e1*(j1*p1-n1*l1) - i1*(f1*p1-n1*h1) + m1*(f1*l1-j1*h1);    dd[1][4] = e1*(n1*k1-j1*o1) + i1*(f1*o1-n1*g1) + m1*(j1*g1-f1*k1);    dd[2][1] = b1*(l1*o1-k1*p1) + j1*(c1*p1-d1*o1) + n1*(d1*k1-c1*l1);    dd[2][2] = a1*(k1*p1-l1*o1) + c1*(l1*m1-i1*p1) + d1*(i1*o1-k1*m1);    dd[2][3] = a1*(l1*n1-j1*p1) + i1*(b1*p1-n1*d1) + m1*(j1*d1-b1*l1);    dd[2][4] = a1*(j1*o1-n1*k1) - i1*(b1*o1-n1*c1) + m1*(b1*k1-c1*j1);    dd[3][1] = b1*(g1*p1-h1*o1) - f1*(c1*p1-o1*d1) + n1*(c1*h1-d1*g1);    dd[3][2] = a1*(o1*h1-g1*p1) + e1*(c1*p1-o1*d1) + m1*(d1*g1-c1*h1);    dd[3][3] = a1*(f1*p1-h1*n1) + b1*(h1*m1-e1*p1) + d1*(e1*n1-f1*m1);    dd[3][4] = a1*(n1*g1-f1*o1) + e1*(b1*o1-c1*n1) + m1*(c1*f1-b1*g1);    dd[4][1] = b1*(h1*k1-g1*l1) + f1*(c1*l1-d1*k1) + j1*(d1*g1-c1*h1);    dd[4][2] = a1*(g1*l1-h1*k1) - e1*(c1*l1-d1*k1) + i1*(c1*h1-d1*g1);    dd[4][3] = a1*(j1*h1-f1*l1) + e1*(b1*l1-d1*j1) + i1*(d1*f1-b1*h1);    dd[4][4] = a1*(f1*k1-g1*j1) + b1*(g1*i1-e1*k1) + c1*(e1*j1-f1*i1);    if ( denom <= 0.0 )    {      res.x = 0.0;      // something went wrong      res.y = 0.0;      // set solution to center of earth      res.z = 0.0;      res.dt = 0.0;    }    else    {      for (i=1; i<=4; i++)      {        for (j=1; j<=4; j++)           dd[i][j] = dd[i][j] / denom;      }      for (i=1; i<=nsl; i++)      {        for (j=1; j<=4; j++)        {          pm[j][i] = 0.0;          for (k=1; k<=4; k++)            pm[j][i] += dd[j][k]*ms[k][i];        }      }      for ( i=1; i<=4; i++)      {        br[i] = 0.0;        for (j=1; j<=nsl; j++)          br[i] += bm[j]*pm[i][j];      }      nits++;      x += br[1];      y += br[2];      z += br[3];      t -= br[4] / LIGHTVEL;//   printf("%lf,%lf,%lf,%20.10lf\n",x,y,z,t);//   printf("%lf,%lf,%lf,%lf\n",br[1],br[2],br[3],br[4]);      correct_mag = sqrt( br[1] * br[1] + br[2] * br[2] + br[3] * br[3]);    }  } while ( correct_mag > 0.01 && correct_mag < 1.e8 && nits < 10);  res.x  = x;  res.y  = y;  res.z  = z;  res.dt = t;/* *  Now for Velocity */  for (i=1; i<=nsl; i++)  {    alpha = (dt[i]-t)*OMEGAE;    r = sqrt( pow( track_sat[i].x*cos(alpha)-track_sat[i].y*sin(alpha)-x, 2.0)+              pow( track_sat[i].y*cos(alpha)+track_sat[i].x*sin(alpha)-y, 2.0)+              pow( track_sat[i].z-z, 2.0));    bm[i] = ((track_sat[i].x * cos( alpha) -               track_sat[i].y * sin( alpha) - x) * d_sat[i].x +             (track_sat[i].y * cos( alpha) +               track_sat[i].x * sin( alpha) - y) * d_sat[i].y +             (track_sat[i].z - z) * d_sat[i].z) / r - meas_dop[i] * LAMBDA;//    fprintf(out," %d meas_dop= %f bm= %f\n",i,meas_dop[i],bm[i]);  }  for (i=1; i<=4; i++)  {    br[i] = 0.0;    for ( j=1; j<=nsl; j++)      br[i] += bm[j]*pm[i][j];  }//  fprintf(out," %f  %f  %f  %f\n",pm[1][1],pm[1][2],pm[1][3],pm[1][4]);//  fprintf(out," %f  %f  %f  %f\n",pm[2][1],pm[2][2],pm[2][3],pm[2][4]);//  fprintf(out," %f  %f  %f  %f\n",pm[3][1],pm[3][2],pm[3][3],pm[3][4]);//  fprintf(out," %f  %f  %f  %f\n",pm[4][1],pm[4][2],pm[4][3],pm[4][4]);  res.xv = br[1] + y*OMEGAE;    //  get rid of earth  res.yv = br[2] - x*OMEGAE;    //  rotation rate  res.zv = br[3];//  fprintf(out,"vel  x=%f,y=%f,z=%f\n",res.xv,res.yv,res.zv);  res.df = br[4] / LIGHTVEL * 1000000.0;  return (res);}#endif#ifdef USE_OPENSRCGPS_NAVFIX/*******************************************************************************FUNCTION dops( INT16 nsl)RETURNS  None.PARAMETERS None.PURPOSE  This routine computes the dopsINPUTS:  track_sat[nsl][3]  array of satellite locations in ECEF                      when the signal was sent  nsl                number of satellites used                     receiver positionOUTPUTS:  hdop : horizontal dilution of precision  vdop : vertical dilution of precision  tdop : time dilution of precision  pdop : position dilution of precision  gdop : geometric dilution of precision (rss of pdop & tdop)WRITTEN BY  Clifford Kelley*******************************************************************************/static void dops( INT16 nsl){  INT16  i, k;  double ddx, ddy, ddz,          ddt, r,          rxy,          ms[5][13],          x, y, z,         a1 = 0.0, b1 = 0.0, c1 = 0.0, d1 = 0.0,          e1 = 0.0, f1 = 0.0, g1 = 0.0, h1 = 0.0,         i1 = 0.0, j1 = 0.0, k1 = 0.0, l1 = 0.0,          m1 = 0.0, n1 = 0.0, o1 = 0.0, p1 = 0.0,          denom,         msx, msy, msz;  ECEF   north, east, up;  x       = rec_pos_xyz.x;  y       = rec_pos_xyz.y;  z       = rec_pos_xyz.z;  r       = sqrt( x*x + y*y + z*z);  rxy     = sqrt( x*x + y*y);  north.x = -x/rxy * z/r;  north.y = -y/rxy * z/r;  north.z = rxy/r;  east.x  = -y/rxy;  east.y  = x/rxy;//east.z=0.0; just for completeness  up.x    = x/r;  up.y    = y/r;  up.z    = z/r;  for (i=1; i<=nsl; i++)  {/* *   Compute line of sight vectors */    r = sqrt( pow( track_sat[i].x-x, 2.0) +              pow( track_sat[i].y-y, 2.0)+              pow( track_sat[i].z-z, 2.0));    ms[1][i] = (track_sat[i].x-x) / r;    ms[2][i] = (track_sat[i].y-y) / r;    ms[3][i] = (track_sat[i].z-z) / r;    ms[4][i] = 1.0;  }  for (i=1; i<=nsl; i++)  {    msx = ms[1][i]*north.x + ms[2][i]*north.y + ms[3][i]*north.z;    msy = ms[1][i]*east.x  + ms[2][i]*east.y;    msz = ms[1][i]*up.x    + ms[2][i]*up.y    + ms[3][i]*up.z;    ms[1][i] = msx;    ms[2][i] = msy;    ms[3][i] = msz;    ms[4][i] = 1.0;  }  for (k=1; k<=nsl; k++)  {    a1 += ms[1][k] * ms[1][k];    b1 += ms[1][k] * ms[2][k];    c1 += ms[1][k] * ms[3][k];    d1 += ms[1][k] * ms[4][k];//   e1+=ms[2][k]*ms[1][k];    f1 += ms[2][k] * ms[2][k];    g1 += ms[2][k] * ms[3][k];    h1 += ms[2][k] * ms[4][k];//   i1+=ms[3][k]*ms[1][k];//   j1+=ms[3][k]*ms[2][k];    k1 += ms[3][k] * ms[3][k];    l1 += ms[3][k] * ms[4][k];//   m1+=ms[1][k];//   n1+=ms[2][k];//   o1+=ms[3][k];    p1 += ms[4][k];  }  o1 = l1;  m1 = d1;  n1 = h1;  e1 = b1;  i1 = c1;  j1 = g1;/* *     SOLVE FOR THE DIAGONALS OF THE MATRIX INVERSE */  denom = (k1*p1-l1*o1) * (a1*f1-b1*e1) +           (l1*n1-j1*p1) * (a1*g1-c1*e1) +           (j1*o1-k1*n1) * (a1*h1-d1*e1) +           (l1*m1-i1*p1) * (c1*f1-b1*g1) +           (i1*o1-k1*m1) * (d1*f1-b1*h1) +          (i1*n1-j1*m1) * (c1*h1-d1*g1);  ddx = f1*(k1*p1-l1*o1) + g1*(l1*n1-j1*p1) + h1*(j1*o1-k1*n1);  ddy = a1*(k1*p1-l1*o1) + c1*(l1*m1-i1*p1) + d1*(i1*o1-k1*m1);  ddz = a1*(f1*p1-h1*n1) + b1*(h1*m1-e1*p1) + d1*(e1*n1-f1*m1);  ddt = a1*(f1*k1-g1*j1) + b1*(g1*i1-e1*k1) + c1*(e1*j1-f1*i1);  if ( denom <= 0.0 )  {    Dops.hdop = 1.0e6;      // something went wrong    Dops.vdop = 1.0e6;      // set dops to a large number    Dops.tdop = 1.0e6;    Dops.pdop = 1.0e6;    Dops.gdop = 1.0e6;  }  else  {    Dops.hdop = sqrt( (ddx+ddy) / denom);    Dops.vdop = sqrt( ddz / denom);    Dops.tdop = sqrt( ddt / denom);    Dops.pdop = sqrt( Dops.vdop*Dops.vdop + Dops.hdop*Dops.hdop);    Dops.gdop = sqrt( Dops.pdop*Dops.pdop + Dops.tdop*Dops.tdop);  }  return;}#endif#ifdef USE_OPENSRCGPS_NAVFIX/*******************************************************************************FUNCTION tropo_iono()RETURNS  None.PARAMETERS   az       - azimuth  el       - elevation  gps_time - timePURPOSE  This function corrects the pseudoranges with a tropospheric model  and the broadcast ionospheric message corrections.WRITTEN BY  Clifford Kelley*******************************************************************************/static double tropo_iono( double az, double el, double gps_time){  double d_Trop, d_Ion,          psi, phi,          lambdai, phim, per,          x, F, amp, t, alt_factor;// troposphere model  if ( current_loc.hae > 200000.0)     alt_factor = 0.0;  else if ( current_loc.hae < 0.0)     alt_factor = 1.0;  else     alt_factor = exp( -current_loc.hae * 1.33e-4);

⌨️ 快捷键说明

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