https://www.cnblogs.com/bokeyuan-dlam/articles/14419070.html
一、RTKLIB中模糊度固定中instantaneous、continuous和fix-and-hold三种固定模式的比较
instantaneous不继承上一个历元估计的模糊度的结果,每个历元单独初始化模糊度
/* reset phase-bias if instantaneous AR or expire obs outage counter */
for (i=1;i<=MAXSAT;i++) {
reset=++rtk->ssat[i-1].outc[f]>(unsigned int)rtk->opt.maxout;
if (rtk->opt.modear==ARMODE_INST&&rtk->x[IB(i,f,&rtk->opt)]!=0.0) {
initx(rtk,0.0,0.0,IB(i,f,&rtk->opt));
}
else if (reset&&rtk->x[IB(i,f,&rtk->opt)]!=0.0) {
initx(rtk,0.0,0.0,IB(i,f,&rtk->opt));
trace(3,"udbias : obs outage counter overflow (sat=%3d L%d n=%d)\n",
i,f+1,rtk->ssat[i-1].outc[f]);
rtk->ssat[i-1].outc[f]=0;
}
if (rtk->opt.modear!=ARMODE_INST&&reset) {
rtk->ssat[i-1].lock[f]=-rtk->opt.minlock;
}
}
/* reset phase-bias if detecting cycle slip */
for (i=0;i<ns;i++) {
j=IB(sat[i],f,&rtk->opt);
rtk->P[j+j*rtk->nx]+=rtk->opt.prn[0]*rtk->opt.prn[0]*fabs(tt);
slip=rtk->ssat[sat[i]-1].slip[f];
if (rtk->opt.ionoopt==IONOOPT_IFLC) slip|=rtk->ssat[sat[i]-1].slip[1];
if (rtk->opt.modear==ARMODE_INST||!(slip&1)) continue;
rtk->x[j]=0.0;
rtk->ssat[sat[i]-1].lock[f]=-rtk->opt.minlock;
}
模糊度的浮点解储存在数组 rtk->x 中,固定解储存在数组 rtk->xa 中 。continuous模式是让当前历元估计出的模糊度浮点解(rtk->x )当做下一个历元状态量中的模糊度(或称为下一个历元模糊度的初值); fix-and-hold模式用结算出的固定解( rtk->xa)当量测对估计出的模糊度浮点解(rtk->x )进行了约束(或叫更新、融合),然后将约束后的模糊度浮点解(rtk->x )当做下一个历元状态量中的模糊度(或称为下一个历元模糊度的初值)
/* hold integer ambiguity ----------------------------------------------------*/
static void holdamb(rtk_t *rtk, const double *xa)
{
double *v,*H,*R;
int i,n,m,f,info,index[MAXSAT],nb=rtk->nx-rtk->na,nv=0,nf=NF(&rtk->opt);
trace(3,"holdamb :\n");
v=mat(nb,1); H=zeros(nb,rtk->nx);
for (m=0;m<4;m++) for (f=0;f<nf;f++) {
for (n=i=0;i<MAXSAT;i++) {
if (!test_sys(rtk->ssat[i].sys,m)||rtk->ssat[i].fix[f]!=2||
rtk->ssat[i].azel[1]<rtk->opt.elmaskhold) {
continue;
}
index[n++]=IB(i+1,f,&rtk->opt);
rtk->ssat[i].fix[f]=3; /* hold */
}
/* constraint to fixed ambiguity */
for (i=1;i<n;i++) {
v[nv]=(xa[index[0]]-xa[index[i]])-(rtk->x[index[0]]-rtk->x[index[i]]);
H[index[0]+nv*rtk->nx]= 1.0;
H[index[i]+nv*rtk->nx]=-1.0;
nv++;
}
}
if (nv>0) {
R=zeros(nv,nv);
for (i=0;i<nv;i++) R[i+i*nv]=VAR_HOLDAMB;
/* update states with constraints */
if ((info=filter(rtk->x,rtk->P,H,v,R,rtk->nx,nv))) {
errmsg(rtk,"filter error (info=%d)\n",info);
}
free(R);
}
free(v); free(H);
}
/* resolve integer ambiguity by LAMBDA */
else if (stat!=SOLQ_NONE&&resamb_LAMBDA(rtk,bias,xa)>1) {
if (zdres(0,obs,nu,rs,dts,svh,nav,xa,opt,0,y,e,azel)) {
/* post-fit reisiduals for fixed solution */
nv=ddres(rtk,nav,dt,xa,NULL,sat,y,e,azel,iu,ir,ns,v,NULL,R,vflg);
/* validation of fixed solution */
if (valpos(rtk,v,R,vflg,nv,4.0)) {
/* hold integer ambiguity */
if (++rtk->nfix>=rtk->opt.minfix&&
rtk->opt.modear==ARMODE_FIXHOLD) {
holdamb(rtk,xa);
}
stat=SOLQ_FIX;
}
}
}
二、整周模糊度求解(resamb_LAMBDA),通过LAMBDA算法求解整周模糊度
1、static int resamb_LAMBDA(rtk_t *rtk, double *bias, double *xa)
*rtk——rtk解决方案结构、*bias——利用lambda算法计算得到的双差整周模糊度、*xa——固定状态。
2、
if (rtk->opt.mode<=PMODE_DGPS||rtk->opt.modear==ARMODE_OFF||
rtk->opt.thresar[0]<1.0) {
return 0;
}
如果模糊度求解方式:ARMODE_OFF 或定位模式为 PMODE_DGPS及以下,则跳出函数
3、单差转双差矩阵 D
/* single to double-difference transformation matrix (D') */
D=zeros(nx,nx);
if ((nb=ddmat(rtk,D))<=0) {
errmsg(rtk,"no valid double-difference\n");
free(D);
return 0;
}
4、lambda/mlambda整数最小二乘估计
if (!(info=lambda(nb,2,y+na,Qb,b,s))) {
trace(4,"N(1)="); tracemat(4,b ,1,nb,10,3);
trace(4,"N(2)="); tracemat(4,b+nb,1,nb,10,3);
rtk->sol.ratio=s[0]>0?(float)(s[1]/s[0]):0.0f;
if (rtk->sol.ratio>999.9) rtk->sol.ratio=999.9f;
/* validation by popular ratio-test */
if (s[0]<=0.0||s[1]/s[0]>=opt->thresar[0]) {
/* transform float to fixed solution (xa=xa-Qab*Qb\(b0-b)) */
for (i=0;i<na;i++) {
rtk->xa[i]=rtk->x[i];
for (j=0;j<na;j++) rtk->Pa[i+j*na]=rtk->P[i+j*nx];
}
for (i=0;i<nb;i++) {
bias[i]=b[i];
y[na+i]-=b[i];
}
if (!matinv(Qb,nb)) {
matmul("NN",nb,1,nb, 1.0,Qb ,y+na,0.0,db);
matmul("NN",na,1,nb,-1.0,Qab,db ,1.0,rtk->xa);
/* covariance of fixed solution (Qa=Qa-Qab*Qb^-1*Qab') */
matmul("NN",na,nb,nb, 1.0,Qab,Qb ,0.0,QQ);
matmul("NT",na,na,nb,-1.0,QQ ,Qab,1.0,rtk->Pa);
trace(3,"resamb : validation ok (nb=%d ratio=%.2f s=%.2f/%.2f)\n",
nb,s[0]==0.0?0.0:s[1]/s[0],s[0],s[1]);
/* restore single-differenced ambiguity */
restamb(rtk,bias,nb,xa);
}
else nb=0;
}
else { /* validation failed */
errmsg(rtk,"ambiguity validation failed (nb=%d ratio=%.2f s=%.2f/%.2f)\n",
nb,s[1]/s[0],s[0],s[1]);
nb=0;
}
}
else {
errmsg(rtk,"lambda error (info=%d)\n",info);
}
free(D); free(y); free(Qy); free(DP);
free(b); free(db); free(Qb); free(Qab); free(QQ);
return nb; /* number of ambiguities */
}