////////////////////////////////////////////////////////////////////// // L2-L5における整数値バイアス決定 ////////////////////////////////////////////////////////////////////// #include #include #include const double pi = 3.1415926535898;//円周率 const double cs = 299792458.0;//光速 const double F1 = 1575420000.0; const double F2 = 1227600000.0; const double F5 = 1176450000.0; const int SATMAX = 36;//GPSの最大総数 const int GPS = 32;//GPSの最大総数 #define DIV1 1//何個(縦横)にグリッドを区切るか #define DIVMAX 4//グリッドを格納する配列の最大値を設定 extern FILE *can,*satv,*dd_code,*change,*fix_info,*final,*temp; extern int MSV[16]; extern int Ref_sat,RTK_satn; extern int CHANGE_FLAG,QZSS; extern int Pre_sv[4],UN_FIX,NO_RTK,Initialization_time; extern int Correct_wide_integer[SATMAX],Correct_uwide_integer[SATMAX]; extern double Sat_xpos[SATMAX],Sat_ypos[SATMAX],Sat_zpos[SATMAX];//地球中心座標系 extern double POSx[DIVMAX][DIVMAX],POSy[DIVMAX][DIVMAX],POSz[DIVMAX][DIVMAX];//解析位置 extern double DD_carrier1[SATMAX],DD_code1[SATMAX],DD_carrier2[SATMAX],DD_code2[SATMAX]; extern double DD_carrier5[SATMAX],DD_code5[SATMAX]; extern double Dx_code,Dy_code,Dz_code; extern double RHDOP,GPSTIME,RGDOP,RVDOP; extern double End_latitude,End_longitude; extern double Ultra_wide_carrier[SATMAX]; int flag_unresolve_ultra; int minver2(double [],double); int seisu(double); void trans_xyz_llh(double,double,double,double[]); void choose_primary(int,int []); void w_inverse(double[],int,double); int remove_candidate(int,double[],int[],int[]); void ambiguity_ultra_wide() { int i,j; int sv[16],max_prn,prn; int flag_iter=0; double n1[SATMAX]={0}; double lrl[3],lrln[3],lrk[3][16],lrkn[3][16]; double g[36],st_dx,st_dy; double n1_ultra_wide[SATMAX]; double u_wide_carrier[SATMAX]; double ppp[128][3]={0}; static int n_int[3],stock_n[3]; static int Kaisu=0,Pass[1332]={0}; static int resolution_iter=0; static int unresolve=0,fix=0; static int fix_on = 0; static int reconsider = 0; static double Start; static int fix_time = 0; static int total_time=0; //使用衛星を代入する個所 for(i=0;i<16;i++) sv[i] = MSV[i]; // CHANGE_FLAG = 1; // if(sv[0]==Pre_sv[0] && sv[1]==Pre_sv[1] && sv[2]==Pre_sv[2] && sv[3]==Pre_sv[3]) // CHANGE_FLAG = 0; CHANGE_FLAG = 0; if((int(GPSTIME)%Initialization_time)==0){ CHANGE_FLAG = 1; fix_time=0; } //1時刻前の主衛星をストック // if(CHANGE_FLAG == 1){ Pre_sv[0] = sv[0]; Pre_sv[1] = sv[1]; Pre_sv[2] = sv[2]; Pre_sv[3] = sv[3]; // } max_prn = Ref_sat; //衛星の方向の単位ベクトルを算出 //基準局と基準衛星の単位ベクトル lrl[0] = Sat_xpos[max_prn]-POSx[0][0]; lrl[1] = Sat_ypos[max_prn]-POSy[0][0]; lrl[2] = Sat_zpos[max_prn]-POSz[0][0]; lrln[0] = lrl[0]/sqrt(lrl[0]*lrl[0]+lrl[1]*lrl[1]+lrl[2]*lrl[2]); lrln[1] = lrl[1]/sqrt(lrl[0]*lrl[0]+lrl[1]*lrl[1]+lrl[2]*lrl[2]); lrln[2] = lrl[2]/sqrt(lrl[0]*lrl[0]+lrl[1]*lrl[1]+lrl[2]*lrl[2]); //基準局と選択衛星の単位ベクトル //衛星数分まわす(主衛星+従衛星分) //最大仰角の衛星はすでに選択されている for(i=0;i=1) fix_time++; if(total_time>=1) total_time++; if(CHANGE_FLAG == 1 || reconsider==1){ n_int[0] = seisu(n1_ultra_wide[sv[1]]); n_int[1] = seisu(n1_ultra_wide[sv[2]]); n_int[2] = seisu(n1_ultra_wide[sv[3]]); stock_n[0]=n_int[0]; stock_n[1]=n_int[1]; stock_n[2]=n_int[2]; Start = GPSTIME; Kaisu=0; for(i=0;i<=1331;i++) Pass[i]=0; fprintf(change,"%f,%d,%d\n",GPSTIME,CHANGE_FLAG,reconsider); // resolution_flag = 0; reconsider=0; fix_time++; total_time++; // if(GPSTIME==43299) // stock_n[1] = 210; } if(GPSTIME>=Start) Kaisu++; fprintf(can,"%f,%d",GPSTIME,RTK_satn); /////////////////////////////////////////////////////////////////////////////// //ambiguityのsearchを行う部分 int bias1,bias2,bias3; int amb[3]; int nsv = RTK_satn-1;//自由度に応じて変更 int iter=0,kaisu; int sat=3; int n5,n6,n7,n8,n9,n10,n11,n12,n13,n14; int pass_amb[128]={0}; double pass_res[128]={0}; int pass_check=0,aaa=0; double dx_ultra_wide,dy_ultra_wide,dz_ultra_wide; double ref_diff[16],rov_diff[16],r0[16],y[16]; double v[16],res; double diff_code_carrier,diff_height; double c_obs[512]; double vv[16]; //調整値 double std = 0.1; double keisu=1.00;//1-2 double ddd,eee,fff; ddd=F2/(F2-F5); eee=F5/(F2-F5); fff=sqrt(ddd*ddd+eee*eee); //二重位相差の観測誤差共分散行列を求めておく w_inverse(c_obs,nsv,std); //下記のチェックで主衛星によるRHDOP,RVDOPが必要 choose_primary(2,sv); //実際に探索空間内で解を探すルーチン for(bias1=-2;bias1<=2;bias1++){ for(bias2=-2;bias2<=2;bias2++){ for(bias3=-2;bias3<=2;bias3++){ iter++; //一度候補から抜けた場合、時間の節約のため以下の計算を行わないようにする if(Kaisu != Pass[iter]+1 && iter != resolution_iter) continue; amb[0]=stock_n[0]+bias1; amb[1]=stock_n[1]+bias2; amb[2]=stock_n[2]+bias3; dx_ultra_wide=0; dy_ultra_wide=0; dz_ultra_wide=0; //衛星の方向の単位ベクトルを算出 //基準局と基準衛星の単位ベクトル lrl[0] = Sat_xpos[max_prn]-POSx[0][0]; lrl[1] = Sat_ypos[max_prn]-POSy[0][0]; lrl[2] = Sat_zpos[max_prn]-POSz[0][0]; lrln[0] = lrl[0]/sqrt(lrl[0]*lrl[0]+lrl[1]*lrl[1]+lrl[2]*lrl[2]); lrln[1] = lrl[1]/sqrt(lrl[0]*lrl[0]+lrl[1]*lrl[1]+lrl[2]*lrl[2]); lrln[2] = lrl[2]/sqrt(lrl[0]*lrl[0]+lrl[1]*lrl[1]+lrl[2]*lrl[2]); //基準局と選択衛星の単位ベクトル //衛星数分まわす(主衛星+従衛星分) //最大仰角の衛星はすでに選択されている for(i=0;i=5) n5 = seisu(y[3]); if(RTK_satn>=6) n6 = seisu(y[4]); if(RTK_satn>=7) n7 = seisu(y[5]); if(RTK_satn>=8) n8 = seisu(y[6]); if(RTK_satn>=9) n9 = seisu(y[7]); if(RTK_satn>=10) n10 = seisu(y[8]); if(RTK_satn>=11) n11 = seisu(y[9]); if(RTK_satn>=12) n12 = seisu(y[10]); if(RTK_satn>=13) n13 = seisu(y[11]); if(RTK_satn>=14) n14 = seisu(y[12]); ////////////////////////////////////////////////////////////////////// v[3] = y[3]-n5; v[4] = y[4]-n6; v[5] = y[5]-n7; v[6] = y[6]-n8; v[7] = y[7]-n9; v[8] = y[8]-n10; v[9] = y[9]-n11; v[10] = y[10]-n12; v[11] = y[11]-n13; v[12] = y[12]-n14; //////////////////////////////////////////////////////////////////////////// //最大8個の従衛星にしている if(nsv>=11) nsv=11; ////////////////////////////////////////////////////////////////////////////// //チェック用の従衛星が8個の場合 if(nsv == 11){ vv[3] = v[3]*c_obs[0]+v[4]*c_obs[1]+v[5]*c_obs[1]+v[6]*c_obs[1]+v[7]*c_obs[1]+v[8]*c_obs[1]+v[9]*c_obs[1]+v[10]*c_obs[1]; vv[4] = v[3]*c_obs[1]+v[4]*c_obs[0]+v[5]*c_obs[1]+v[6]*c_obs[1]+v[7]*c_obs[1]+v[8]*c_obs[1]+v[9]*c_obs[1]+v[10]*c_obs[1]; vv[5] = v[3]*c_obs[1]+v[4]*c_obs[1]+v[5]*c_obs[0]+v[6]*c_obs[1]+v[7]*c_obs[1]+v[8]*c_obs[1]+v[9]*c_obs[1]+v[10]*c_obs[1]; vv[6] = v[3]*c_obs[1]+v[4]*c_obs[1]+v[5]*c_obs[1]+v[6]*c_obs[0]+v[7]*c_obs[1]+v[8]*c_obs[1]+v[9]*c_obs[1]+v[10]*c_obs[1]; vv[7] = v[3]*c_obs[1]+v[4]*c_obs[1]+v[5]*c_obs[1]+v[6]*c_obs[1]+v[7]*c_obs[0]+v[8]*c_obs[1]+v[9]*c_obs[1]+v[10]*c_obs[1]; vv[8] = v[3]*c_obs[1]+v[4]*c_obs[1]+v[5]*c_obs[1]+v[6]*c_obs[1]+v[7]*c_obs[1]+v[8]*c_obs[0]+v[9]*c_obs[1]+v[10]*c_obs[1]; vv[9] = v[3]*c_obs[1]+v[4]*c_obs[1]+v[5]*c_obs[1]+v[6]*c_obs[1]+v[7]*c_obs[1]+v[8]*c_obs[1]+v[9]*c_obs[0]+v[10]*c_obs[1]; vv[10] = v[3]*c_obs[1]+v[4]*c_obs[1]+v[5]*c_obs[1]+v[6]*c_obs[1]+v[7]*c_obs[1]+v[8]*c_obs[1]+v[9]*c_obs[1]+v[10]*c_obs[0]; } //チェック用の従衛星が7個の場合 if(nsv == 10){ vv[3] = v[3]*c_obs[0]+v[4]*c_obs[1]+v[5]*c_obs[1]+v[6]*c_obs[1]+v[7]*c_obs[1]+v[8]*c_obs[1]+v[9]*c_obs[1]; vv[4] = v[3]*c_obs[1]+v[4]*c_obs[0]+v[5]*c_obs[1]+v[6]*c_obs[1]+v[7]*c_obs[1]+v[8]*c_obs[1]+v[9]*c_obs[1]; vv[5] = v[3]*c_obs[1]+v[4]*c_obs[1]+v[5]*c_obs[0]+v[6]*c_obs[1]+v[7]*c_obs[1]+v[8]*c_obs[1]+v[9]*c_obs[1]; vv[6] = v[3]*c_obs[1]+v[4]*c_obs[1]+v[5]*c_obs[1]+v[6]*c_obs[0]+v[7]*c_obs[1]+v[8]*c_obs[1]+v[9]*c_obs[1]; vv[7] = v[3]*c_obs[1]+v[4]*c_obs[1]+v[5]*c_obs[1]+v[6]*c_obs[1]+v[7]*c_obs[0]+v[8]*c_obs[1]+v[9]*c_obs[1]; vv[8] = v[3]*c_obs[1]+v[4]*c_obs[1]+v[5]*c_obs[1]+v[6]*c_obs[1]+v[7]*c_obs[1]+v[8]*c_obs[0]+v[9]*c_obs[1]; vv[9] = v[3]*c_obs[1]+v[4]*c_obs[1]+v[5]*c_obs[1]+v[6]*c_obs[1]+v[7]*c_obs[1]+v[8]*c_obs[1]+v[9]*c_obs[0]; } //チェック用の従衛星が6個の場合 if(nsv == 9){ vv[3] = v[3]*c_obs[0]+v[4]*c_obs[1]+v[5]*c_obs[1]+v[6]*c_obs[1]+v[7]*c_obs[1]+v[8]*c_obs[1]; vv[4] = v[3]*c_obs[1]+v[4]*c_obs[0]+v[5]*c_obs[1]+v[6]*c_obs[1]+v[7]*c_obs[1]+v[8]*c_obs[1]; vv[5] = v[3]*c_obs[1]+v[4]*c_obs[1]+v[5]*c_obs[0]+v[6]*c_obs[1]+v[7]*c_obs[1]+v[8]*c_obs[1]; vv[6] = v[3]*c_obs[1]+v[4]*c_obs[1]+v[5]*c_obs[1]+v[6]*c_obs[0]+v[7]*c_obs[1]+v[8]*c_obs[1]; vv[7] = v[3]*c_obs[1]+v[4]*c_obs[1]+v[5]*c_obs[1]+v[6]*c_obs[1]+v[7]*c_obs[0]+v[8]*c_obs[1]; vv[8] = v[3]*c_obs[1]+v[4]*c_obs[1]+v[5]*c_obs[1]+v[6]*c_obs[1]+v[7]*c_obs[1]+v[8]*c_obs[0]; } //チェック用の従衛星が5個の場合 if(nsv == 8){ vv[3] = v[3]*c_obs[0]+v[4]*c_obs[1]+v[5]*c_obs[1]+v[6]*c_obs[1]+v[7]*c_obs[1]; vv[4] = v[3]*c_obs[1]+v[4]*c_obs[0]+v[5]*c_obs[1]+v[6]*c_obs[1]+v[7]*c_obs[1]; vv[5] = v[3]*c_obs[1]+v[4]*c_obs[1]+v[5]*c_obs[0]+v[6]*c_obs[1]+v[7]*c_obs[1]; vv[6] = v[3]*c_obs[1]+v[4]*c_obs[1]+v[5]*c_obs[1]+v[6]*c_obs[0]+v[7]*c_obs[1]; vv[7] = v[3]*c_obs[1]+v[4]*c_obs[1]+v[5]*c_obs[1]+v[6]*c_obs[1]+v[7]*c_obs[0]; } //チェック用の従衛星が4個の場合 if(nsv == 7){ vv[3] = v[3]*c_obs[0]+v[4]*c_obs[1]+v[5]*c_obs[1]+v[6]*c_obs[1]; vv[4] = v[3]*c_obs[1]+v[4]*c_obs[0]+v[5]*c_obs[1]+v[6]*c_obs[1]; vv[5] = v[3]*c_obs[1]+v[4]*c_obs[1]+v[5]*c_obs[0]+v[6]*c_obs[1]; vv[6] = v[3]*c_obs[1]+v[4]*c_obs[1]+v[5]*c_obs[1]+v[6]*c_obs[0]; } //チェック用の従衛星が3個の場合 if(nsv == 6){ vv[3] = v[3]*c_obs[0]+v[4]*c_obs[1]+v[5]*c_obs[1]; vv[4] = v[3]*c_obs[1]+v[4]*c_obs[0]+v[5]*c_obs[1]; vv[5] = v[3]*c_obs[1]+v[4]*c_obs[1]+v[5]*c_obs[0]; } //チェック用の従衛星が2個の場合 if(nsv == 5){ vv[3] = v[3]*c_obs[0]+v[4]*c_obs[1]; vv[4] = v[3]*c_obs[1]+v[4]*c_obs[0]; } //////////////////////////////////////////////////////////////////////////// //チェック用の従衛星が8個の場合 if(nsv == 11){ res = v[3]*vv[3]+v[4]*vv[4]+v[5]*vv[5]+v[6]*vv[6]+v[7]*vv[7]+v[8]*vv[8]+v[9]*vv[9]+v[10]*vv[10]; res = sqrt(res); } //チェック用の従衛星が7個の場合 if(nsv == 10){ res = v[3]*vv[3]+v[4]*vv[4]+v[5]*vv[5]+v[6]*vv[6]+v[7]*vv[7]+v[8]*vv[8]+v[9]*vv[9]; res = sqrt(res); } //チェック用の従衛星が6個の場合 if(nsv == 9){ res = v[3]*vv[3]+v[4]*vv[4]+v[5]*vv[5]+v[6]*vv[6]+v[7]*vv[7]+v[8]*vv[8]; res = sqrt(res); } //チェック用の従衛星が5個の場合 if(nsv == 8){ res = v[3]*vv[3]+v[4]*vv[4]+v[5]*vv[5]+v[6]*vv[6]+v[7]*vv[7]; res = sqrt(res); } //チェック用の従衛星が4個の場合 if(nsv == 7){ res = v[3]*vv[3]+v[4]*vv[4]+v[5]*vv[5]+v[6]*vv[6]; res = sqrt(res); } //チェック用の従衛星が3個の場合 if(nsv == 6){ res = v[3]*vv[3]+v[4]*vv[4]+v[5]*vv[5]; res = sqrt(res); } //チェック用の従衛星が2個の場合 if(nsv == 5){ res = v[3]*vv[3]+v[4]*vv[4]; res = sqrt(res); } //チェック用の従衛星が1個の場合 if(nsv == 4){ res = v[3]*v[3]*c_obs[0]; res = sqrt(res); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// //(95.0%) 1:3.8415 2:5.9915 3:7.8147 4:9.4877 //(97.5%) 1:5.0239 2:7.3778 3:9.3484 4:11.143 //(99.0%) 1:6.6349 2:9.2103 3:11.345 4:13.277 //(99.5%) 1:7.8794 2:10.597 3:12.838 4:14.860 double vnyu; /* switch(nsv){ case 4:vnyu = 7.8794;break; case 5:vnyu = 10.597;break; case 6:vnyu = 12.838;break; case 7:vnyu = 14.860;break; case 8:vnyu = 16.750;break; case 9:vnyu = 18.548;break; case 10:vnyu = 20.278;break; case 11:vnyu = 21.955;break; default:break; } */ /* switch(nsv){ case 4:vnyu = 6.6349;break; case 5:vnyu = 9.2103;break; case 6:vnyu = 11.345;break; case 7:vnyu = 13.277;break; case 8:vnyu = 15.086;break; case 9:vnyu = 16.812;break; case 10:vnyu = 18.475;break; case 11:vnyu = 20.090;break; default:break; }*/ /* switch(nsv){ case 4:vnyu = 5.0239;break; case 5:vnyu = 7.3778;break; case 6:vnyu = 9.3484;break; case 7:vnyu = 11.143;break; case 8:vnyu = 12.833;break; case 9:vnyu = 14.449;break; case 10:vnyu = 16.013;break; case 11:vnyu = 17.535;break; default:break; }*/ switch(nsv){ case 4:vnyu = 3.8415;break; case 5:vnyu = 5.9915;break; case 6:vnyu = 7.8147;break; case 7:vnyu = 9.4877;break; case 8:vnyu = 11.070;break; case 9:vnyu = 12.592;break; case 10:vnyu = 14.067;break; case 11:vnyu = 15.507;break; default:break; } //DGPS測位結果の変換 double a1,a2,a3;//地球中心のx,y,z double llh[3],llh2[3],llh3[3]; a1=POSx[0][0]+Dx_code; a2=POSy[0][0]+Dy_code; a3=POSz[0][0]+Dz_code; trans_xyz_llh(a1,a2,a3, llh); //基線解析結果の変換 //double llh2[3];//地球中心のx,y,z a1=dx_ultra_wide+POSx[0][0]; a2=dy_ultra_wide+POSy[0][0]; a3=dz_ultra_wide+POSz[0][0]; trans_xyz_llh(a1,a2,a3, llh2); //基準局の緯度、経度、高度 //double llh2[3];//地球中心のx,y,z a1=POSx[0][0]; a2=POSy[0][0]; a3=POSz[0][0]; trans_xyz_llh(a1,a2,a3, llh3); double lat_diff,lon_diff; double d_lat,d_lon; lat_diff = (llh[0]-llh2[0])*111319.49; lon_diff = (llh[1]-llh2[1])*cos(llh2[0]*pi/180.0)*111319.49; diff_code_carrier = sqrt(lat_diff*lat_diff+lon_diff*lon_diff); diff_height = fabs(llh2[2]-llh[2]); //試しに計算(DGPSの水平方向精度) d_lat = (llh[0]-36)*111319.49; d_lon = (llh[1]-140)*cos(llh[0]*pi/180.0)*111319.49; d_lat = (llh2[0]-End_latitude)*111319.49; d_lon = (llh2[1]-End_longitude)*cos(llh2[0]*pi/180.0)*111319.49; //コードDGPS測位結果との差を計算 //diff_code_l1 = sqrt((dx-dx_code)*(dx-dx_code)+(dy-dy_code)*(dy-dy_code)+(dz-dz_code)*(dz-dz_code)); if(iter==63) fprintf(temp,"%f,%f,%f,%f,%f,%d\n",GPSTIME,d_lat,d_lon,llh2[2],RGDOP,RTK_satn); //#if 0 //実際の検定部分 if(res0 && RVDOP*2-diff_height>0){ //if(res <=vnyu*keisu){ //全ての整数値バイアス候補で、検定を通り続けた回数をカウント Pass[iter]++; //ambiguity候補のみを書き出し if(Kaisu == Pass[iter]){ fprintf(can,",%d",iter); resolution_iter = iter; pass_amb[aaa++]=iter; pass_res[iter]=res; pass_check++; ppp[iter][0]=d_lat; ppp[iter][1]=d_lon; ppp[iter][2]=llh2[2]; } unresolve++; //dxをストックすること st_dx = dx_ultra_wide; st_dy = dy_ultra_wide; } dx_ultra_wide=d_lat; dy_ultra_wide=d_lon; dz_ultra_wide=llh2[2]; if(nsv+1<8) v[6]=0; if(nsv+1<7) v[5]=0; if(nsv+1<6) v[4]=0; //#endif }//bias1 -5 to 5 }//bias2 -5 to 5 }//bias3 -5 to 5 //ambiguity候補が5個以下になったときに残りの候補の残差で比較する // int flag_unresolve=0; flag_iter=0; flag_unresolve_ultra=0; if(pass_check>=2 && pass_check<=50){ flag_iter=remove_candidate(pass_check,pass_res,pass_amb,Pass); } //0のときも指定しておく必要がある if(pass_check==1) flag_iter=pass_amb[0]; if(flag_unresolve_ultra==1) unresolve=1; if(unresolve == 1){ fix_on = 1; if(fix_time!=0){ fprintf(final,"%f,%d,%d,FIX,%f,%f,%f\n",GPSTIME,fix_time,RTK_satn,ppp[flag_iter][0],ppp[flag_iter][1],ppp[flag_iter][2]); printf("%f,%d,%d,%f,%f,%f\n",GPSTIME,fix_time,RTK_satn,ppp[flag_iter][0],ppp[flag_iter][1],ppp[flag_iter][2]); } fix_time = 0; total_time = 0; } if(CHANGE_FLAG == 1 && unresolve != 1 && total_time>1){ fprintf(final,"%f,%d,%d,nofix\n",GPSTIME,fix_time,RTK_satn); printf("%f,%d,%d,nofix\n",GPSTIME,fix_time,RTK_satn); } if(CHANGE_FLAG == 1) fix_on = 0; if(fix_on==1) fix++; else UN_FIX++; if(unresolve==0) st_dx=dx_ultra_wide; //複数の候補が同時に落ちたときは最初からやり直す必要がある if(fix_on==0 && unresolve==0) reconsider = 1; fprintf(satv,"%f",GPSTIME); for(i=0;i