mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-14 20:20:35 +00:00
Add rtkpos
This commit is contained in:
parent
07ecbd2f5e
commit
ce8869c5c5
@ -25,6 +25,7 @@ set(RTKLIB_LIB_SOURCES
|
|||||||
rtklib_sbas.cc
|
rtklib_sbas.cc
|
||||||
rtklib_ionex.cc
|
rtklib_ionex.cc
|
||||||
rtklib_pntpos.cc
|
rtklib_pntpos.cc
|
||||||
|
rtklib_rtkpos.cc
|
||||||
rtklib_conversions.cc
|
rtklib_conversions.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -54,4 +55,3 @@ target_link_libraries(
|
|||||||
${BLAS}
|
${BLAS}
|
||||||
${LAPACK}
|
${LAPACK}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
759
src/algorithms/libs/rtklib/rtklib_rtkpos.cc
Normal file
759
src/algorithms/libs/rtklib/rtklib_rtkpos.cc
Normal file
@ -0,0 +1,759 @@
|
|||||||
|
/*!
|
||||||
|
* \file rtklib_rtkpos.cc
|
||||||
|
* \brief rtklib ppp-related functions
|
||||||
|
* \authors <ul>
|
||||||
|
* <li> 2007-2013, T. Takasu
|
||||||
|
* <li> 2017, Javier Arribas
|
||||||
|
* <li> 2017, Carles Fernandez
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* This is a derived work from RTKLIB http://www.rtklib.com/
|
||||||
|
* The original source code at https://github.com/tomojitakasu/RTKLIB is
|
||||||
|
* released under the BSD 2-clause license with an additional exclusive clause
|
||||||
|
* that does not apply here. This additional clause is reproduced below:
|
||||||
|
*
|
||||||
|
* " The software package includes some companion executive binaries or shared
|
||||||
|
* libraries necessary to execute APs on Windows. These licenses succeed to the
|
||||||
|
* original ones of these software. "
|
||||||
|
*
|
||||||
|
* Neither the executive binaries nor the shared libraries are required by, used
|
||||||
|
* or included in GNSS-SDR.
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Copyright (C) 2007-2013, T. Takasu
|
||||||
|
* Copyright (C) 2017, Javier Arribas
|
||||||
|
* Copyright (C) 2017, Carles Fernandez
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "rtklib_rtkpos.h"
|
||||||
|
#include "rtklib_rtkcmn.h"
|
||||||
|
#include "rtklib_sbas.h"
|
||||||
|
#include "rtklib_ionex.h"
|
||||||
|
#include "rtklib_ephemeris.h"
|
||||||
|
#include "rtklib_pntpos.h"
|
||||||
|
|
||||||
|
/* pseudorange measurement error variance ------------------------------------*/
|
||||||
|
double varerr(const prcopt_t *opt, double el, int sys)
|
||||||
|
{
|
||||||
|
double fact, varr;
|
||||||
|
fact = sys == SYS_GLO ? EFACT_GLO : (sys == SYS_SBS ? EFACT_SBS : EFACT_GPS);
|
||||||
|
varr = std::pow(opt->err[0], 2.0)*(std::pow(opt->err[1], 2.0)+std::pow(opt->err[2], 2.0) / sin(el));
|
||||||
|
if (opt->ionoopt == IONOOPT_IFLC) varr *= std::pow(3.0, 2.0); /* iono-free */
|
||||||
|
return std::pow(fact, 2.0)*varr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* get tgd parameter (m) -----------------------------------------------------*/
|
||||||
|
double gettgd(int sat, const nav_t *nav)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i<nav->n; i++)
|
||||||
|
{
|
||||||
|
if (nav->eph[i].sat!=sat) continue;
|
||||||
|
return SPEED_OF_LIGHT*nav->eph[i].tgd[0];
|
||||||
|
}
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* psendorange with code bias correction -------------------------------------*/
|
||||||
|
double prange(const obsd_t *obs, const nav_t *nav, const double *azel,
|
||||||
|
int iter, const prcopt_t *opt, double *var)
|
||||||
|
{
|
||||||
|
const double *lam = nav->lam[obs->sat-1];
|
||||||
|
double PC, P1, P2, P1_P2, P1_C1, P2_C2, gamma;
|
||||||
|
int i = 0, j = 1, sys;
|
||||||
|
|
||||||
|
*var = 0.0;
|
||||||
|
|
||||||
|
if (!(sys = satsys(obs->sat, NULL))) return 0.0;
|
||||||
|
|
||||||
|
/* L1-L2 for GPS/GLO/QZS, L1-L5 for GAL/SBS */
|
||||||
|
if (NFREQ >= 3 && (sys & (SYS_GAL | SYS_SBS))) j = 2;
|
||||||
|
|
||||||
|
if (NFREQ<2 || lam[i] == 0.0 || lam[j] == 0.0) return 0.0;
|
||||||
|
|
||||||
|
/* test snr mask */
|
||||||
|
if (iter>0)
|
||||||
|
{
|
||||||
|
if (testsnr(0, i, azel[1], obs->SNR[i]*0.25, &opt->snrmask))
|
||||||
|
{
|
||||||
|
trace(4, "snr mask: %s sat=%2d el=%.1f snr=%.1f\n",
|
||||||
|
time_str(obs->time, 0), obs->sat, azel[1]*R2D, obs->SNR[i]*0.25);
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
if (opt->ionoopt == IONOOPT_IFLC)
|
||||||
|
{
|
||||||
|
if (testsnr(0, j, azel[1], obs->SNR[j]*0.25, &opt->snrmask)) return 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gamma = std::pow(lam[j], 2.0) / std::pow(lam[i], 2.0); /* f1^2/f2^2 */
|
||||||
|
P1 = obs->P[i];
|
||||||
|
P2 = obs->P[j];
|
||||||
|
P1_P2 = nav->cbias[obs->sat-1][0];
|
||||||
|
P1_C1 = nav->cbias[obs->sat-1][1];
|
||||||
|
P2_C2 = nav->cbias[obs->sat-1][2];
|
||||||
|
|
||||||
|
/* if no P1-P2 DCB, use TGD instead */
|
||||||
|
if (P1_P2 == 0.0 && (sys&(SYS_GPS|SYS_GAL|SYS_QZS)))
|
||||||
|
{
|
||||||
|
P1_P2 = (1.0-gamma)*gettgd(obs->sat, nav);
|
||||||
|
}
|
||||||
|
if (opt->ionoopt == IONOOPT_IFLC)
|
||||||
|
{ /* dual-frequency */
|
||||||
|
|
||||||
|
if (P1 == 0.0 || P2 == 0.0) return 0.0;
|
||||||
|
if (obs->code[i] == CODE_L1C) P1 += P1_C1; /* C1->P1 */
|
||||||
|
if (obs->code[j] == CODE_L2C) P2 += P2_C2; /* C2->P2 */
|
||||||
|
|
||||||
|
/* iono-free combination */
|
||||||
|
PC = (gamma*P1-P2) / (gamma-1.0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* single-frequency */
|
||||||
|
if (P1 == 0.0) return 0.0;
|
||||||
|
if (obs->code[i] == CODE_L1C) P1 += P1_C1; /* C1->P1 */
|
||||||
|
PC = P1-P1_P2 / (1.0-gamma);
|
||||||
|
}
|
||||||
|
if (opt->sateph == EPHOPT_SBAS) PC -= P1_C1; /* sbas clock based C1 */
|
||||||
|
|
||||||
|
*var = std::pow(ERR_CBIAS, 2.0);
|
||||||
|
|
||||||
|
return PC;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ionospheric correction ------------------------------------------------------
|
||||||
|
* compute ionospheric correction
|
||||||
|
* args : gtime_t time I time
|
||||||
|
* nav_t *nav I navigation data
|
||||||
|
* int sat I satellite number
|
||||||
|
* double *pos I receiver position {lat,lon,h} (rad|m)
|
||||||
|
* double *azel I azimuth/elevation angle {az,el} (rad)
|
||||||
|
* int ionoopt I ionospheric correction option (IONOOPT_???)
|
||||||
|
* double *ion O ionospheric delay (L1) (m)
|
||||||
|
* double *var O ionospheric delay (L1) variance (m^2)
|
||||||
|
* return : status(1:ok,0:error)
|
||||||
|
*-----------------------------------------------------------------------------*/
|
||||||
|
int ionocorr(gtime_t time, const nav_t *nav, int sat, const double *pos,
|
||||||
|
const double *azel, int ionoopt, double *ion, double *var)
|
||||||
|
{
|
||||||
|
trace(4, "ionocorr: time=%s opt=%d sat=%2d pos=%.3f %.3f azel=%.3f %.3f\n",
|
||||||
|
time_str(time, 3), ionoopt, sat, pos[0]*R2D, pos[1]*R2D, azel[0]*R2D,
|
||||||
|
azel[1]*R2D);
|
||||||
|
|
||||||
|
/* broadcast model */
|
||||||
|
if (ionoopt == IONOOPT_BRDC)
|
||||||
|
{
|
||||||
|
*ion = ionmodel(time, nav->ion_gps, pos, azel);
|
||||||
|
*var = std::pow(*ion*ERR_BRDCI, 2.0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* sbas ionosphere model */
|
||||||
|
if (ionoopt == IONOOPT_SBAS)
|
||||||
|
{
|
||||||
|
return sbsioncorr(time, nav, pos, azel, ion, var);
|
||||||
|
}
|
||||||
|
/* ionex tec model */
|
||||||
|
if (ionoopt == IONOOPT_TEC)
|
||||||
|
{
|
||||||
|
return iontec(time, nav, pos, azel, 1, ion, var);
|
||||||
|
}
|
||||||
|
/* qzss broadcast model */
|
||||||
|
if (ionoopt == IONOOPT_QZS && norm(nav->ion_qzs, 8)>0.0)
|
||||||
|
{
|
||||||
|
*ion = ionmodel(time, nav->ion_qzs, pos, azel);
|
||||||
|
*var = std::pow(*ion*ERR_BRDCI, 2.0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* lex ionosphere model */
|
||||||
|
if (ionoopt == IONOOPT_LEX)
|
||||||
|
{
|
||||||
|
return lexioncorr(time, nav, pos, azel, ion, var);
|
||||||
|
}
|
||||||
|
*ion = 0.0;
|
||||||
|
*var = ionoopt == IONOOPT_OFF ? std::pow(ERR_ION, 2.0) : 0.0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tropospheric correction -----------------------------------------------------
|
||||||
|
* compute tropospheric correction
|
||||||
|
* args : gtime_t time I time
|
||||||
|
* nav_t *nav I navigation data
|
||||||
|
* double *pos I receiver position {lat,lon,h} (rad|m)
|
||||||
|
* double *azel I azimuth/elevation angle {az,el} (rad)
|
||||||
|
* int tropopt I tropospheric correction option (TROPOPT_???)
|
||||||
|
* double *trp O tropospheric delay (m)
|
||||||
|
* double *var O tropospheric delay variance (m^2)
|
||||||
|
* return : status(1:ok,0:error)
|
||||||
|
*-----------------------------------------------------------------------------*/
|
||||||
|
int tropcorr(gtime_t time, const nav_t *nav, const double *pos,
|
||||||
|
const double *azel, int tropopt, double *trp, double *var)
|
||||||
|
{
|
||||||
|
trace(4, "tropcorr: time=%s opt=%d pos=%.3f %.3f azel=%.3f %.3f\n",
|
||||||
|
time_str(time, 3), tropopt, pos[0]*R2D, pos[1]*R2D, azel[0]*R2D,
|
||||||
|
azel[1]*R2D);
|
||||||
|
|
||||||
|
/* saastamoinen model */
|
||||||
|
if (tropopt == TROPOPT_SAAS || tropopt == TROPOPT_EST || tropopt == TROPOPT_ESTG)
|
||||||
|
{
|
||||||
|
*trp = tropmodel(time, pos, azel, REL_HUMI);
|
||||||
|
*var = std::pow(ERR_SAAS / (sin(azel[1])+0.1), 2.0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* sbas troposphere model */
|
||||||
|
if (tropopt == TROPOPT_SBAS)
|
||||||
|
{
|
||||||
|
*trp = sbstropcorr(time, pos, azel, var);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* no correction */
|
||||||
|
*trp = 0.0;
|
||||||
|
*var = tropopt == TROPOPT_OFF ? std::pow(ERR_TROP, 2.0) : 0.0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* pseudorange residuals -----------------------------------------------------*/
|
||||||
|
int rescode(int iter, const obsd_t *obs, int n, const double *rs,
|
||||||
|
const double *dts, const double *vare, const int *svh,
|
||||||
|
const nav_t *nav, const double *x, const prcopt_t *opt,
|
||||||
|
double *v, double *H, double *var, double *azel, int *vsat,
|
||||||
|
double *resp, int *ns)
|
||||||
|
{
|
||||||
|
double r, dion, dtrp, vmeas, vion, vtrp, rr[3], pos[3], dtr, e[3], P, lam_L1;
|
||||||
|
int i, j, nv = 0, sys, mask[4] = {0};
|
||||||
|
|
||||||
|
trace(3, "resprng : n=%d\n", n);
|
||||||
|
|
||||||
|
for (i = 0; i<3; i++) rr[i] = x[i]; dtr = x[3];
|
||||||
|
|
||||||
|
ecef2pos(rr, pos);
|
||||||
|
|
||||||
|
for (i=*ns = 0; i<n && i<MAXOBS; i++)
|
||||||
|
{
|
||||||
|
vsat[i] = 0; azel[i*2] = azel[1+i*2] = resp[i] = 0.0;
|
||||||
|
|
||||||
|
if (!(sys = satsys(obs[i].sat, NULL))) continue;
|
||||||
|
|
||||||
|
/* reject duplicated observation data */
|
||||||
|
if (i<n-1 && i<MAXOBS-1 && obs[i].sat == obs[i+1].sat)
|
||||||
|
{
|
||||||
|
trace(2, "duplicated observation data %s sat=%2d\n",
|
||||||
|
time_str(obs[i].time, 3), obs[i].sat);
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* geometric distance/azimuth/elevation angle */
|
||||||
|
if ((r = geodist(rs+i*6, rr, e)) <= 0.0 ||
|
||||||
|
satazel(pos, e, azel+i*2)<opt->elmin) continue;
|
||||||
|
|
||||||
|
/* psudorange with code bias correction */
|
||||||
|
if ((P = prange(obs+i, nav, azel+i*2, iter, opt, &vmeas)) == 0.0) continue;
|
||||||
|
|
||||||
|
/* excluded satellite? */
|
||||||
|
if (satexclude(obs[i].sat, svh[i], opt)) continue;
|
||||||
|
|
||||||
|
/* ionospheric corrections */
|
||||||
|
if (!ionocorr(obs[i].time, nav, obs[i].sat, pos, azel+i*2,
|
||||||
|
iter>0 ? opt->ionoopt : IONOOPT_BRDC, &dion, &vion)) continue;
|
||||||
|
|
||||||
|
/* GPS-L1 -> L1/B1 */
|
||||||
|
if ((lam_L1 = nav->lam[obs[i].sat-1][0])>0.0)
|
||||||
|
{
|
||||||
|
dion *= std::pow(lam_L1/lam_carr[0], 2.0);
|
||||||
|
}
|
||||||
|
/* tropospheric corrections */
|
||||||
|
if (!tropcorr(obs[i].time, nav, pos, azel+i*2,
|
||||||
|
iter>0 ? opt->tropopt : TROPOPT_SAAS, &dtrp, &vtrp))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* pseudorange residual */
|
||||||
|
v[nv] = P-(r+dtr-SPEED_OF_LIGHT*dts[i*2]+dion+dtrp);
|
||||||
|
|
||||||
|
/* design matrix */
|
||||||
|
for (j = 0; j<NX; j++) H[j+nv*NX] = j<3 ? -e[j] : (j == 3 ? 1.0 : 0.0);
|
||||||
|
|
||||||
|
/* time system and receiver bias offset correction */
|
||||||
|
if (sys == SYS_GLO) {v[nv] -= x[4]; H[4+nv*NX] = 1.0; mask[1] = 1;}
|
||||||
|
else if (sys == SYS_GAL) {v[nv] -= x[5]; H[5+nv*NX] = 1.0; mask[2] = 1;}
|
||||||
|
else if (sys == SYS_BDS) {v[nv] -= x[6]; H[6+nv*NX] = 1.0; mask[3] = 1;}
|
||||||
|
else mask[0] = 1;
|
||||||
|
|
||||||
|
vsat[i] = 1; resp[i] = v[nv]; (*ns)++;
|
||||||
|
|
||||||
|
/* error variance */
|
||||||
|
var[nv++] = varerr(opt, azel[1+i*2], sys)+vare[i]+vmeas+vion+vtrp;
|
||||||
|
|
||||||
|
trace(4, "sat=%2d azel=%5.1f %4.1f res=%7.3f sig=%5.3f\n", obs[i].sat,
|
||||||
|
azel[i*2]*R2D, azel[1+i*2]*R2D, resp[i], sqrt(var[nv-1]));
|
||||||
|
}
|
||||||
|
/* constraint to avoid rank-deficient */
|
||||||
|
for (i = 0; i<4; i++)
|
||||||
|
{
|
||||||
|
if (mask[i]) continue;
|
||||||
|
v[nv] = 0.0;
|
||||||
|
for (j = 0; j<NX; j++) H[j+nv*NX] = j == i+3 ? 1.0 : 0.0;
|
||||||
|
var[nv++] = 0.01;
|
||||||
|
}
|
||||||
|
return nv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* validate solution ---------------------------------------------------------*/
|
||||||
|
int valsol(const double *azel, const int *vsat, int n,
|
||||||
|
const prcopt_t *opt, const double *v, int nv, int nx,
|
||||||
|
char *msg)
|
||||||
|
{
|
||||||
|
double azels[MAXOBS*2], dop[4], vv;
|
||||||
|
int i, ns;
|
||||||
|
|
||||||
|
trace(3, "valsol : n=%d nv=%d\n", n, nv);
|
||||||
|
|
||||||
|
/* chi-square validation of residuals */
|
||||||
|
vv = dot(v, v, nv);
|
||||||
|
if (nv>nx && vv>chisqr[nv-nx-1])
|
||||||
|
{
|
||||||
|
sprintf(msg, "chi-square error nv=%d vv=%.1f cs=%.1f", nv, vv, chisqr[nv-nx-1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* large gdop check */
|
||||||
|
for (i = ns = 0; i<n; i++)
|
||||||
|
{
|
||||||
|
if (!vsat[i]) continue;
|
||||||
|
azels[ ns*2] = azel[ i*2];
|
||||||
|
azels[1+ns*2] = azel[1+i*2];
|
||||||
|
ns++;
|
||||||
|
}
|
||||||
|
dops(ns, azels, opt->elmin, dop);
|
||||||
|
if (dop[0] <= 0.0 || dop[0]>opt->maxgdop)
|
||||||
|
{
|
||||||
|
sprintf(msg, "gdop error nv=%d gdop=%.1f", nv, dop[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* estimate receiver position ------------------------------------------------*/
|
||||||
|
int estpos(const obsd_t *obs, int n, const double *rs, const double *dts,
|
||||||
|
const double *vare, const int *svh, const nav_t *nav,
|
||||||
|
const prcopt_t *opt, sol_t *sol, double *azel, int *vsat,
|
||||||
|
double *resp, char *msg)
|
||||||
|
{
|
||||||
|
double x[NX] = {0}, dx[NX], Q[NX*NX], *v, *H, *var, sig;
|
||||||
|
int i, j, k, info, stat, nv, ns;
|
||||||
|
|
||||||
|
trace(3, "estpos : n=%d\n", n);
|
||||||
|
|
||||||
|
v = mat(n+4, 1); H = mat(NX, n+4); var = mat(n+4, 1);
|
||||||
|
|
||||||
|
for (i = 0; i<3; i++) x[i] = sol->rr[i];
|
||||||
|
|
||||||
|
for (i = 0; i<MAXITR; i++)
|
||||||
|
{
|
||||||
|
/* pseudorange residuals */
|
||||||
|
nv = rescode(i, obs, n, rs, dts, vare, svh, nav, x, opt, v, H, var, azel, vsat, resp,
|
||||||
|
&ns);
|
||||||
|
|
||||||
|
if (nv<NX)
|
||||||
|
{
|
||||||
|
sprintf(msg, "lack of valid sats ns=%d", nv);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* weight by variance */
|
||||||
|
for (j = 0; j<nv; j++)
|
||||||
|
{
|
||||||
|
sig = sqrt(var[j]);
|
||||||
|
v[j] /= sig;
|
||||||
|
for (k = 0; k<NX; k++) H[k+j*NX] /= sig;
|
||||||
|
}
|
||||||
|
/* least square estimation */
|
||||||
|
if ((info = lsq(H, v, NX, nv, dx, Q)))
|
||||||
|
{
|
||||||
|
sprintf(msg, "lsq error info=%d", info);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (j = 0; j<NX; j++) x[j] += dx[j];
|
||||||
|
|
||||||
|
if (norm(dx, NX)<1E-4)
|
||||||
|
{
|
||||||
|
sol->type = 0;
|
||||||
|
sol->time = timeadd(obs[0].time, -x[3] / SPEED_OF_LIGHT);
|
||||||
|
sol->dtr[0] = x[3] / SPEED_OF_LIGHT; /* receiver clock bias (s) */
|
||||||
|
sol->dtr[1] = x[4] / SPEED_OF_LIGHT; /* glo-gps time offset (s) */
|
||||||
|
sol->dtr[2] = x[5] / SPEED_OF_LIGHT; /* gal-gps time offset (s) */
|
||||||
|
sol->dtr[3] = x[6] / SPEED_OF_LIGHT; /* bds-gps time offset (s) */
|
||||||
|
for (j = 0; j<6; j++) sol->rr[j] = j<3 ? x[j] : 0.0;
|
||||||
|
for (j = 0; j<3; j++) sol->qr[j] = (float)Q[j+j*NX];
|
||||||
|
sol->qr[3] = (float)Q[1]; /* cov xy */
|
||||||
|
sol->qr[4] = (float)Q[2+NX]; /* cov yz */
|
||||||
|
sol->qr[5] = (float)Q[2]; /* cov zx */
|
||||||
|
sol->ns = (unsigned char)ns;
|
||||||
|
sol->age = sol->ratio = 0.0;
|
||||||
|
|
||||||
|
/* validate solution */
|
||||||
|
if ((stat = valsol(azel, vsat, n, opt, v, nv, NX, msg)))
|
||||||
|
{
|
||||||
|
sol->stat = opt->sateph == EPHOPT_SBAS ? SOLQ_SBAS : SOLQ_SINGLE;
|
||||||
|
}
|
||||||
|
free(v); free(H); free(var);
|
||||||
|
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i >= MAXITR) sprintf(msg, "iteration divergent i=%d", i);
|
||||||
|
|
||||||
|
free(v); free(H); free(var);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* raim fde (failure detection and exclution) -------------------------------*/
|
||||||
|
int raim_fde(const obsd_t *obs, int n, const double *rs,
|
||||||
|
const double *dts, const double *vare, const int *svh,
|
||||||
|
const nav_t *nav, const prcopt_t *opt, sol_t *sol,
|
||||||
|
double *azel, int *vsat, double *resp, char *msg)
|
||||||
|
{
|
||||||
|
obsd_t *obs_e;
|
||||||
|
sol_t sol_e = {{0}};
|
||||||
|
char tstr[32], name[16], msg_e[128];
|
||||||
|
double *rs_e, *dts_e, *vare_e, *azel_e, *resp_e, rms_e, rms = 100.0;
|
||||||
|
int i, j, k, nvsat, stat = 0, *svh_e, *vsat_e, sat = 0;
|
||||||
|
|
||||||
|
trace(3, "raim_fde: %s n=%2d\n", time_str(obs[0].time, 0), n);
|
||||||
|
|
||||||
|
if (!(obs_e = (obsd_t *)malloc(sizeof(obsd_t)*n))) return 0;
|
||||||
|
rs_e = mat(6, n); dts_e = mat(2, n); vare_e = mat(1, n); azel_e = zeros(2, n);
|
||||||
|
svh_e = imat(1, n); vsat_e = imat(1, n); resp_e = mat(1, n);
|
||||||
|
|
||||||
|
for (i = 0; i<n; i++)
|
||||||
|
{
|
||||||
|
/* satellite exclution */
|
||||||
|
for (j = k = 0; j<n; j++)
|
||||||
|
{
|
||||||
|
if (j == i) continue;
|
||||||
|
obs_e[k] = obs[j];
|
||||||
|
matcpy(rs_e +6*k, rs +6*j, 6, 1);
|
||||||
|
matcpy(dts_e+2*k, dts+2*j, 2, 1);
|
||||||
|
vare_e[k] = vare[j];
|
||||||
|
svh_e[k++] = svh[j];
|
||||||
|
}
|
||||||
|
/* estimate receiver position without a satellite */
|
||||||
|
if (!estpos(obs_e, n-1, rs_e, dts_e, vare_e, svh_e, nav, opt, &sol_e, azel_e,
|
||||||
|
vsat_e, resp_e, msg_e))
|
||||||
|
{
|
||||||
|
trace(3, "raim_fde: exsat=%2d (%s)\n", obs[i].sat, msg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (j = nvsat = 0, rms_e = 0.0; j<n-1; j++)
|
||||||
|
{
|
||||||
|
if (!vsat_e[j]) continue;
|
||||||
|
rms_e += std::pow(resp_e[j], 2.0);
|
||||||
|
nvsat++;
|
||||||
|
}
|
||||||
|
if (nvsat<5)
|
||||||
|
{
|
||||||
|
trace(3, "raim_fde: exsat=%2d lack of satellites nvsat=%2d\n",
|
||||||
|
obs[i].sat, nvsat);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
rms_e = sqrt(rms_e / nvsat);
|
||||||
|
|
||||||
|
trace(3, "raim_fde: exsat=%2d rms=%8.3f\n", obs[i].sat, rms_e);
|
||||||
|
|
||||||
|
if (rms_e>rms) continue;
|
||||||
|
|
||||||
|
/* save result */
|
||||||
|
for (j = k = 0; j<n; j++)
|
||||||
|
{
|
||||||
|
if (j == i) continue;
|
||||||
|
matcpy(azel+2*j, azel_e+2*k, 2, 1);
|
||||||
|
vsat[j] = vsat_e[k];
|
||||||
|
resp[j] = resp_e[k++];
|
||||||
|
}
|
||||||
|
stat = 1;
|
||||||
|
*sol = sol_e;
|
||||||
|
sat = obs[i].sat;
|
||||||
|
rms = rms_e;
|
||||||
|
vsat[i] = 0;
|
||||||
|
strcpy(msg, msg_e);
|
||||||
|
}
|
||||||
|
if (stat)
|
||||||
|
{
|
||||||
|
time2str(obs[0].time, tstr, 2); satno2id(sat, name);
|
||||||
|
trace(2, "%s: %s excluded by raim\n", tstr+11, name);
|
||||||
|
}
|
||||||
|
free(obs_e);
|
||||||
|
free(rs_e ); free(dts_e ); free(vare_e); free(azel_e);
|
||||||
|
free(svh_e); free(vsat_e); free(resp_e);
|
||||||
|
return stat;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* doppler residuals ---------------------------------------------------------*/
|
||||||
|
int resdop(const obsd_t *obs, int n, const double *rs, const double *dts,
|
||||||
|
const nav_t *nav, const double *rr, const double *x,
|
||||||
|
const double *azel, const int *vsat, double *v, double *H)
|
||||||
|
{
|
||||||
|
double lam, rate, pos[3], E[9], a[3], e[3], vs[3], cosel;
|
||||||
|
int i, j, nv = 0;
|
||||||
|
|
||||||
|
trace(3, "resdop : n=%d\n", n);
|
||||||
|
|
||||||
|
ecef2pos(rr, pos); xyz2enu(pos, E);
|
||||||
|
|
||||||
|
for (i = 0; i<n && i<MAXOBS; i++)
|
||||||
|
{
|
||||||
|
lam = nav->lam[obs[i].sat-1][0];
|
||||||
|
|
||||||
|
if (obs[i].D[0] == 0.0 || lam == 0.0 || !vsat[i] || norm(rs+3+i*6, 3) <= 0.0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* line-of-sight vector in ecef */
|
||||||
|
cosel = cos(azel[1+i*2]);
|
||||||
|
a[0] = sin(azel[i*2])*cosel;
|
||||||
|
a[1] = cos(azel[i*2])*cosel;
|
||||||
|
a[2] = sin(azel[1+i*2]);
|
||||||
|
matmul("TN", 3, 1, 3, 1.0, E, a, 0.0, e);
|
||||||
|
|
||||||
|
/* satellite velocity relative to receiver in ecef */
|
||||||
|
for (j = 0; j<3; j++) vs[j] = rs[j+3+i*6]-x[j];
|
||||||
|
|
||||||
|
/* range rate with earth rotation correction */
|
||||||
|
rate = dot(vs, e, 3)+DEFAULT_OMEGA_EARTH_DOT / SPEED_OF_LIGHT*(rs[4+i*6]*rr[0]+rs[1+i*6]*x[0]-
|
||||||
|
rs[3+i*6]*rr[1]-rs[ i*6]*x[1]);
|
||||||
|
|
||||||
|
/* doppler residual */
|
||||||
|
v[nv]=-lam*obs[i].D[0]-(rate+x[3]-SPEED_OF_LIGHT*dts[1+i*2]);
|
||||||
|
|
||||||
|
/* design matrix */
|
||||||
|
for (j = 0; j<4; j++) H[j+nv*4] = j<3 ? -e[j] : 1.0;
|
||||||
|
|
||||||
|
nv++;
|
||||||
|
}
|
||||||
|
return nv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* estimate receiver velocity ------------------------------------------------*/
|
||||||
|
void estvel(const obsd_t *obs, int n, const double *rs, const double *dts,
|
||||||
|
const nav_t *nav, const prcopt_t *opt, sol_t *sol,
|
||||||
|
const double *azel, const int *vsat)
|
||||||
|
{
|
||||||
|
double x[4] = {0}, dx[4], Q[16], *v, *H;
|
||||||
|
int i, j, nv;
|
||||||
|
|
||||||
|
trace(3, "estvel : n=%d\n", n);
|
||||||
|
|
||||||
|
v = mat(n, 1); H = mat(4, n);
|
||||||
|
|
||||||
|
for (i = 0; i<MAXITR; i++)
|
||||||
|
{
|
||||||
|
/* doppler residuals */
|
||||||
|
if ((nv = resdop(obs, n, rs, dts, nav, sol->rr, x, azel, vsat, v, H))<4)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* least square estimation */
|
||||||
|
if (lsq(H, v, 4, nv, dx, Q)) break;
|
||||||
|
|
||||||
|
for (j = 0; j<4; j++) x[j] += dx[j];
|
||||||
|
|
||||||
|
if (norm(dx, 4)<1E-6)
|
||||||
|
{
|
||||||
|
for (i = 0; i<3; i++) sol->rr[i+3] = x[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(v); free(H);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int lexioncorr(gtime_t time, const nav_t *nav, const double *pos,
|
||||||
|
const double *azel, double *delay, double *var)
|
||||||
|
{
|
||||||
|
const double re = 6378.137, hion = 350.0;
|
||||||
|
#if 0
|
||||||
|
const double dl1=(141.0-129.0) / (45.5-34.7);
|
||||||
|
const double dl2=(129.0-126.7) / (34.7-26.0);
|
||||||
|
#endif
|
||||||
|
double tt, sinlat, coslat, sinaz, cosaz, cosel, rp, ap, sinap, cosap, latpp, lonpp;
|
||||||
|
double dlat, dlon, Enm, F;
|
||||||
|
int n, m;
|
||||||
|
|
||||||
|
trace(4, "lexioncorr: time=%s pos=%.3f %.3f azel=%.3f %.3f\n", time_str(time, 3),
|
||||||
|
pos[0]*R2D, pos[1]*R2D, azel[0]*R2D, azel[1]*R2D);
|
||||||
|
|
||||||
|
*delay = *var = 0.0;
|
||||||
|
|
||||||
|
if (pos[2]<-100.0 || azel[1] <= 0.0) return 1;
|
||||||
|
|
||||||
|
tt = timediff(time, nav->lexion.t0);
|
||||||
|
|
||||||
|
/* check time span */
|
||||||
|
if (fabs(tt)>nav->lexion.tspan)
|
||||||
|
{
|
||||||
|
trace(2, "lex iono age error: tt=%.0f tspan=%.0f\n", tt, nav->lexion.tspan);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* check user position range (ref [1] 4.1.5) */
|
||||||
|
#if 0
|
||||||
|
if (pos[0]> 45.5*D2R||pos[0]< 26.0*D2R||
|
||||||
|
pos[1]>146.0*D2R||
|
||||||
|
pos[1]<129.0*D2R+dl1*(pos[0]-34.7*D2R)||
|
||||||
|
pos[1]<126.7*D2R+dl2*(pos[0]-26.0*D2R)) {
|
||||||
|
trace(2,"lex iono out of coverage pos=%.3f %.3f\n",pos[0]*R2D,pos[1]*R2D);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* ionospheric pierce point position */
|
||||||
|
sinlat = sin(pos[0]);
|
||||||
|
coslat = cos(pos[0]);
|
||||||
|
sinaz = sin(azel[0]);
|
||||||
|
cosaz = cos(azel[0]);
|
||||||
|
cosel = cos(azel[1]);
|
||||||
|
rp = re / (re+hion)*cosel;
|
||||||
|
ap = PI / 2.0-azel[1]-asin(rp);
|
||||||
|
sinap = sin(ap);
|
||||||
|
cosap = cos(ap);
|
||||||
|
latpp = asin(sinlat*cosap+coslat*sinap*cosaz);
|
||||||
|
lonpp = pos[1]+atan(sinap*sinaz / (cosap*coslat-sinap*cosaz*sinlat));
|
||||||
|
|
||||||
|
trace(4, "lexioncorr: pppos=%.3f %.3f\n", latpp*R2D, lonpp*R2D);
|
||||||
|
|
||||||
|
/* inclination factor */
|
||||||
|
F = 1.0 / sqrt(1.0-rp*rp);
|
||||||
|
|
||||||
|
/* delta latitude/longitude (rad) */
|
||||||
|
dlat = latpp-nav->lexion.pos0[0];
|
||||||
|
dlon = lonpp-nav->lexion.pos0[1];
|
||||||
|
trace(4, "lexioncorr: pos0=%.1f %.1f dlat=%.1f dlon=%.1f\n",
|
||||||
|
nav->lexion.pos0[0]*R2D, nav->lexion.pos0[1]*R2D, dlat*R2D, dlon*R2D);
|
||||||
|
|
||||||
|
/* slant ionosphere delay (L1) */
|
||||||
|
for (n = 0; n <= 2; n++) for (m = 0; m <= 1; m++)
|
||||||
|
{
|
||||||
|
Enm = nav->lexion.coef[n][m];
|
||||||
|
*delay += F*Enm*pow(dlat, n)*pow(dlon, m);
|
||||||
|
|
||||||
|
trace(5, "lexioncorr: F=%8.3f Enm[%d][%d]=%8.3f delay=%8.3f\n", F, n, m, Enm,
|
||||||
|
F*Enm*pow(dlat, n)*pow(dlon, m));
|
||||||
|
}
|
||||||
|
trace(4, "lexioncorr: time=%s delay=%.3f\n", time_str(time, 0), *delay);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* single-point positioning ----------------------------------------------------
|
||||||
|
* compute receiver position, velocity, clock bias by single-point positioning
|
||||||
|
* with pseudorange and doppler observables
|
||||||
|
* args : obsd_t *obs I observation data
|
||||||
|
* int n I number of observation data
|
||||||
|
* nav_t *nav I navigation data
|
||||||
|
* prcopt_t *opt I processing options
|
||||||
|
* sol_t *sol IO solution
|
||||||
|
* double *azel IO azimuth/elevation angle (rad) (NULL: no output)
|
||||||
|
* ssat_t *ssat IO satellite status (NULL: no output)
|
||||||
|
* char *msg O error message for error exit
|
||||||
|
* return : status(1:ok,0:error)
|
||||||
|
* notes : assuming sbas-gps, galileo-gps, qzss-gps, compass-gps time offset and
|
||||||
|
* receiver bias are negligible (only involving glonass-gps time offset
|
||||||
|
* and receiver bias)
|
||||||
|
*-----------------------------------------------------------------------------*/
|
||||||
|
int pntpos(const obsd_t *obs, int n, const nav_t *nav,
|
||||||
|
const prcopt_t *opt, sol_t *sol, double *azel, ssat_t *ssat,
|
||||||
|
char *msg)
|
||||||
|
{
|
||||||
|
prcopt_t opt_ = *opt;
|
||||||
|
double *rs, *dts, *var, *azel_, *resp;
|
||||||
|
int i, stat, vsat[MAXOBS] = {0}, svh[MAXOBS];
|
||||||
|
|
||||||
|
sol->stat = SOLQ_NONE;
|
||||||
|
|
||||||
|
if (n <= 0) {strcpy(msg, "no observation data"); return 0;}
|
||||||
|
|
||||||
|
trace(3, "pntpos : tobs=%s n=%d\n", time_str(obs[0].time, 3), n);
|
||||||
|
|
||||||
|
sol->time = obs[0].time; msg[0] = '\0';
|
||||||
|
|
||||||
|
rs=mat(6, n); dts = mat(2, n); var = mat(1, n); azel_ = zeros(2, n); resp = mat(1, n);
|
||||||
|
|
||||||
|
if (opt_.mode!=PMODE_SINGLE)
|
||||||
|
{ /* for precise positioning */
|
||||||
|
#if 0
|
||||||
|
opt_.sateph =EPHOPT_BRDC;
|
||||||
|
#endif
|
||||||
|
opt_.ionoopt = IONOOPT_BRDC;
|
||||||
|
opt_.tropopt = TROPOPT_SAAS;
|
||||||
|
}
|
||||||
|
/* satellite positons, velocities and clocks */
|
||||||
|
satposs(sol->time, obs, n, nav, opt_.sateph, rs, dts, var, svh);
|
||||||
|
|
||||||
|
/* estimate receiver position with pseudorange */
|
||||||
|
stat = estpos(obs, n, rs, dts, var, svh, nav, &opt_, sol, azel_, vsat, resp, msg);
|
||||||
|
|
||||||
|
/* raim fde */
|
||||||
|
if (!stat && n >= 6 && opt->posopt[4])
|
||||||
|
{
|
||||||
|
stat = raim_fde(obs, n, rs, dts, var, svh, nav, &opt_, sol, azel_, vsat, resp, msg);
|
||||||
|
}
|
||||||
|
/* estimate receiver velocity with doppler */
|
||||||
|
if (stat) estvel(obs, n, rs, dts, nav, &opt_, sol, azel_, vsat);
|
||||||
|
|
||||||
|
if (azel)
|
||||||
|
{
|
||||||
|
for (i = 0; i<n*2; i++) azel[i] = azel_[i];
|
||||||
|
}
|
||||||
|
if (ssat)
|
||||||
|
{
|
||||||
|
for (i = 0; i<MAXSAT; i++)
|
||||||
|
{
|
||||||
|
ssat[i].vs = 0;
|
||||||
|
ssat[i].azel[0] = ssat[i].azel[1] = 0.0;
|
||||||
|
ssat[i].resp[0] = ssat[i].resc[0] = 0.0;
|
||||||
|
ssat[i].snr[0] = 0;
|
||||||
|
}
|
||||||
|
for (i = 0; i<n; i++)
|
||||||
|
{
|
||||||
|
ssat[obs[i].sat-1].azel[0] = azel_[ i*2];
|
||||||
|
ssat[obs[i].sat-1].azel[1] = azel_[1+i*2];
|
||||||
|
ssat[obs[i].sat-1].snr[0] = obs[i].SNR[0];
|
||||||
|
if (!vsat[i]) continue;
|
||||||
|
ssat[obs[i].sat-1].vs = 1;
|
||||||
|
ssat[obs[i].sat-1].resp[0] = resp[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(rs); free(dts); free(var); free(azel_); free(resp);
|
||||||
|
return stat;
|
||||||
|
}
|
104
src/algorithms/libs/rtklib/rtklib_rtkpos.h
Normal file
104
src/algorithms/libs/rtklib/rtklib_rtkpos.h
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/*!
|
||||||
|
* \file rtklib_rtkpos.h
|
||||||
|
* \brief rtklib ppp-related functions
|
||||||
|
* \authors <ul>
|
||||||
|
* <li> 2007-2013, T. Takasu
|
||||||
|
* <li> 2017, Javier Arribas
|
||||||
|
* <li> 2017, Carles Fernandez
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* This is a derived work from RTKLIB http://www.rtklib.com/
|
||||||
|
* The original source code at https://github.com/tomojitakasu/RTKLIB is
|
||||||
|
* released under the BSD 2-clause license with an additional exclusive clause
|
||||||
|
* that does not apply here. This additional clause is reproduced below:
|
||||||
|
*
|
||||||
|
* " The software package includes some companion executive binaries or shared
|
||||||
|
* libraries necessary to execute APs on Windows. These licenses succeed to the
|
||||||
|
* original ones of these software. "
|
||||||
|
*
|
||||||
|
* Neither the executive binaries nor the shared libraries are required by, used
|
||||||
|
* or included in GNSS-SDR.
|
||||||
|
*
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
* Copyright (C) 2007-2013, T. Takasu
|
||||||
|
* Copyright (C) 2017, Javier Arribas
|
||||||
|
* Copyright (C) 2017, Carles Fernandez
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef GNSS_SDR_RTKLIB_RKTPOS_H_
|
||||||
|
#define GNSS_SDR_RTKLIB_RKTPOS_H_
|
||||||
|
|
||||||
|
#include "rtklib.h"
|
||||||
|
|
||||||
|
double varerr(const prcopt_t *opt, double el, int sys);
|
||||||
|
double gettgd(int sat, const nav_t *nav);
|
||||||
|
double prange(const obsd_t *obs, const nav_t *nav, const double *azel,
|
||||||
|
int iter, const prcopt_t *opt, double *var);
|
||||||
|
int ionocorr(gtime_t time, const nav_t *nav, int sat, const double *pos,
|
||||||
|
const double *azel, int ionoopt, double *ion, double *var);
|
||||||
|
|
||||||
|
int tropcorr(gtime_t time, const nav_t *nav, const double *pos,
|
||||||
|
const double *azel, int tropopt, double *trp, double *var);
|
||||||
|
|
||||||
|
int rescode(int iter, const obsd_t *obs, int n, const double *rs,
|
||||||
|
const double *dts, const double *vare, const int *svh,
|
||||||
|
const nav_t *nav, const double *x, const prcopt_t *opt,
|
||||||
|
double *v, double *H, double *var, double *azel, int *vsat,
|
||||||
|
double *resp, int *ns);
|
||||||
|
|
||||||
|
int valsol(const double *azel, const int *vsat, int n,
|
||||||
|
const prcopt_t *opt, const double *v, int nv, int nx,
|
||||||
|
char *msg);
|
||||||
|
|
||||||
|
int estpos(const obsd_t *obs, int n, const double *rs, const double *dts,
|
||||||
|
const double *vare, const int *svh, const nav_t *nav,
|
||||||
|
const prcopt_t *opt, sol_t *sol, double *azel, int *vsat,
|
||||||
|
double *resp, char *msg);
|
||||||
|
|
||||||
|
int raim_fde(const obsd_t *obs, int n, const double *rs,
|
||||||
|
const double *dts, const double *vare, const int *svh,
|
||||||
|
const nav_t *nav, const prcopt_t *opt, sol_t *sol,
|
||||||
|
double *azel, int *vsat, double *resp, char *msg);
|
||||||
|
|
||||||
|
int resdop(const obsd_t *obs, int n, const double *rs, const double *dts,
|
||||||
|
const nav_t *nav, const double *rr, const double *x,
|
||||||
|
const double *azel, const int *vsat, double *v, double *H);
|
||||||
|
|
||||||
|
void estvel(const obsd_t *obs, int n, const double *rs, const double *dts,
|
||||||
|
const nav_t *nav, const prcopt_t *opt, sol_t *sol,
|
||||||
|
const double *azel, const int *vsat);
|
||||||
|
|
||||||
|
int pntpos(const obsd_t *obs, int n, const nav_t *nav,
|
||||||
|
const prcopt_t *opt, sol_t *sol, double *azel, ssat_t *ssat,
|
||||||
|
char *msg);
|
||||||
|
|
||||||
|
int lexioncorr(gtime_t time, const nav_t *nav, const double *pos,
|
||||||
|
const double *azel, double *delay, double *var);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user