相位缠绕(Phase Wind-Up)是发射端与接收端之间的相对运动导致的载波相位变化。对 GPS 系统来说,因为GPS卫星发送的是右旋圆极化(RHCP: Right Hand Circularly Polarized)的信号,在这种情况下,接收机或者卫星天线的旋转会导致载波相位发生改变,这个值可能达到一个载波周期,我们把这种现象叫做相位缠绕。
因为卫星的太阳能电池板必须对着太阳,这样才能尽可能的吸收太阳能。为了把太阳能电池板对准太阳,在卫星经过远日点和近日点附近时,卫星姿态需要发生近 180° 的剧烈翻转,称为正午、子夜机动(noon, midnight turns),这会导致相位缠绕。而卫星的天线必须对地球,以尽量节省发射能量。这也会导致相位缠绕。所以卫星一定会旋转,相位缠绕无法避免。
所幸相位缠绕只影响载波相位测量,不影响码相位测量,在非精密定位中可以忽略其影响。对差分定位来说其影响一般也可以忽略,尤其是短基线的时候。然而对精密单点定位来说,其影响就不能忽略了,因其影响可能会达到分米级。
下面介绍常用的相位缠绕模型。如下图所示是卫星、地球与太阳的位置关系:
void windupcorr(gtime_t time, const double *rs, const double *rr,
double *phw)
{
double ek[3],exs[3],eys[3],ezs[3],ess[3],exr[3],eyr[3],eks[3],ekr[3],E[9];
double dr[3],ds[3],drs[3],r[3],pos[3],rsun[3],cosp,ph,erpv[5]={0};
int i;
trace(4,"windupcorr: time=%s\n",time_str(time,0));
/* sun position in ecef */
sunmoonpos(gpst2utc(time),erpv,rsun,NULL,NULL);
/* unit vector satellite to receiver */
for (i=0;i<3;i++) r[i]=rr[i]-rs[i];
if (!normv3(r,ek)) return;
/* unit vectors of satellite antenna */
for (i=0;i<3;i++) r[i]=-rs[i];
if (!normv3(r,ezs)) return;
for (i=0;i<3;i++) r[i]=rsun[i]-rs[i];
if (!normv3(r,ess)) return;
cross3(ezs,ess,r);
if (!normv3(r,eys)) return;
cross3(eys,ezs,exs);
/* unit vectors of receiver antenna */
ecef2pos(rr,pos);
xyz2enu(pos,E);
exr[0]= E[1]; exr[1]= E[4]; exr[2]= E[7]; /* x = north */
eyr[0]=-E[0]; eyr[1]=-E[3]; eyr[2]=-E[6]; /* y = west */
/* phase windup effect */
cross3(ek,eys,eks);
cross3(ek,eyr,ekr);
for (i=0;i<3;i++) {
ds[i]=exs[i]-ek[i]*dot(ek,exs,3)-eks[i];
dr[i]=exr[i]-ek[i]*dot(ek,exr,3)+ekr[i];
}
cosp=dot(ds,dr,3)/norm(ds,3)/norm(dr,3);
if (cosp<-1.0) cosp=-1.0;
else if (cosp> 1.0) cosp= 1.0;
ph=acos(cosp)/2.0/PI;
cross3(ds,dr,drs);
if (dot(ek,drs,3)<0.0) ph=-ph;
*phw=ph+floor(*phw-ph+0.5); /* in cycle */
}