📄 ogr_navsolve.c
字号:
#ifdef TROPO_CORR d_Trop = 2.47 / (sin( el) + 0.0121) * alt_factor / LIGHTVEL;#else d_Trop = 0.0;#endif// tropo[ch] = d_Trop;// if ( d_Trop < 0.0) // printf( "el=%lf, hae=%lf", el, current_loc.hae);// ionosphere model#ifdef IONO_CORR psi = 0.0137 / (el / PI + 0.11) - 0.022; phi = current_loc.lat / PI + psi * cos(az); if ( phi > 0.416) phi = 0.416; else if ( phi < -0.416 ) phi = -0.416; lambdai = current_loc.lon / PI + psi * sin( az) / cos( phi * PI); t = 43200.0 * lambdai + gps_time - (INT16)((43200.0 * lambdai + gps_time) / 86400.0)*86400.0; if ( t < 0.0) t = t + 86400.0; phim = phi + 0.064 * cos( (lambdai-1.617) * PI); per = Iono.b0 + Iono.b1 * phim + Iono.b2 * phim * phim + Iono.b3 * phim * phim * phim; amp = Iono.al0 + Iono.al1 * phim + Iono.al2 * phim * phim + Iono.al3 * phim * phim * phim; if ( per < 72000.0 ) per = 72000.0; x = 2.0 * PI * (t-50400.0) / per; F = 1.0 + 16.0 * pow( 0.53-el/PI, 3); if ( amp < 0.0 ) amp = 0.0; if ( fabs(x) < 1.5707) d_Ion=F*(5.0e-9+amp*(1.0-x*x/2.+x*x*x*x/24.0)); else d_Ion=F*5.0e-9;#else d_Ion = 0.0;#endif// iono[ch] = d_Ion; return ( d_Trop + d_Ion);#if 0 d_Trop = 2.47/(sin(el)+.0121) * exp(-current_loc.hae*1.33e-4) / LIGHTVEL;// If available from the nav message use its Ionosphere model if (Iono.b0 != 0.0 && Iono.al0 != 0.0) { psi=0.0137/(el/PI+0.11)-0.022; phi=current_loc.lat/PI+psi*cos(az); if (phi > 0.416) phi= 0.416; else if (phi <-0.416 ) phi=-0.416; lambdai=current_loc.lon/PI+psi*sin(az)/cos(phi*PI); t=(INT16)(43200.*lambdai+gps_time)%86400L; if (t<0.0) t=t+86400.0; phim=phi+0.064*cos((lambdai-1.617)*PI); per = Iono.b0 + Iono.b1*phim + Iono.b2*phim*phim + Iono.b3*phim*phim*phim; if ( per <72000.0 ) per=72000.0; x=2.*PI*(t-50400.)/per; F=1.0 + 16.0 * pow( 0.53-el/PI, 3.0); amp = Iono.al0 + Iono.al1*phim + Iono.al2*phim*phim + Iono.al3 * phim * phim * phim; if ( amp < 0.0 ) amp = 0.0; if ( fabs( x) < 1.5707) d_Ion = F*(5.0e-9+amp*(1.0-x*x/2.+x*x*x*x/24.0)); else d_Ion = F*5.0e-9; }// else try this else { d_Ion = 16.33 / sin( sqrt( el*el+0.1255)) / LIGHTVEL; }// fprintf(stream,"d_trop=%le,d_ion=%le,az=%f,el=%f\n",d_Trop,d_Ion,az,el); return (d_Trop + d_Ion);#endif}#endif/*******************************************************************************FUNCTION fix_atan2(long y,long x)RETURNS long integerPARAMETERS x in phase fixed point value y quadrature fixed point valuePURPOSE This function computes the fixed point arctangent represented by x and y in the parameter list 1 radian = 16384 based on the power series f-f^3*2/9WRITTEN BY Clifford Kelley Fixed for y==x added special code for x==0*******************************************************************************/#define SCALED_PI_ON_2 25736L#define SCALED_PI 51472Linline long fix_atan2(long y,long x){ long res = 0, n, n3; if ((x==0) && (y==0)) return(0); // invalid case if (x>0 && x>=labs(y)) { n=(y<<14)/x; n3=((((n*n)>>14)*n)>>13)/9; res=n-n3; } else if (x<=0 && -x>=labs(y)) { n=(y<<14)/x; n3=((((n*n)>>14)*n)>>13)/9; if ( y>0) res=n-n3+SCALED_PI; else if (y<=0) res=n-n3-SCALED_PI; } else if (y>0 && y>labs(x)) { n=(x<<14)/y; n3=((((n*n)>>14)*n)>>13)/9; res=SCALED_PI_ON_2-n+n3; } else if (y<0 && -y>labs(x)) { n=(x<<14)/y; n3=((((n*n)>>14)*n)>>13)/9; res=-n+n3-SCALED_PI_ON_2; } return(res);}/*******************************************************************************FUNCTION nav_fix()RETURNS None.PARAMETERS None.PURPOSE This function determines the pseudorange and doppler to each satellite and calls pos_vel_time to determine the position and velocity of the receiverWRITTEN BY Clifford Kelley*******************************************************************************/#ifdef USE_OPENSRCGPS_NAVFIXvoid nav_fix( void){ INT16 i, ch, n = 1, tr_ch[13]; unsigned long phase_counter;// long meas_bit_time; float clock_error; double transmit_time[13], t_cor[13], dtime[13], // tr_avg = 0.0,// tmax, transmit_time_min, transmit_time_max; static double time[3]; ECEF rp_ecef, d_sat[13]; ECEFT dm_gps_sat[13], dp_gps_sat[13]; LLH rp_llh; for ( ch=0; ch<NOFCHN; ch++) {// Use only satellites being tracked with valid ephemeris data// (valid subframe 1,2,3) and high enough raw SNR// if ( Chan[ch].state == track && // Chan[ch].CN0 > 30 &&// GPS_Eph[Chan[ch].prn].valid == 1 &&// GPS_Eph[Chan[ch].prn].health == 0 &&// Chan[ch].tow_sync == 1) if ( Chan[ch].state == track && GPS_Eph[Chan[ch].prn].valid == 1 && GPS_Eph[Chan[ch].prn].health == 0 && Chan[ch].tow_sync == 1) { tr_ch[n] = ch;// transmit_time[n] : transmission time in sec// 2nd to 5th term = time passed since arrival of TLM + n*sec// 1st term makes sure that 1 s < transmit_time < 2 s// transmit_time[n] = 2.0 - // ((Chan[ch].epoch_nav >> 8) / 50.0 + // (Chan[ch].epoch_nav & 0x1f) / 1000.0 + // Chan[ch].code_phase_nav / 2.046e6 + // Chan[ch].code_dco_phase_nav / 2.046e6 / 1024.0); transmit_time[n] = 2.0 - ((NavData.epoch[ch] >> 8) / 50.0 + (NavData.epoch[ch] & 0x1f) / 1000.0 + NavData.code_phase[ch] / 2.046e6 + NavData.code_dco_phase[ch] / 2.046e6 / 1024.0);// Chan[ch].epoch_nav & 0x1f; // 0,...,49// Chan[ch].epoch_nav >> 8; // 0,...,19// if ( out_debug)// fprintf( stream,// "ch= %d,epoch= %d,ms= %d,chip= %d,phase= %d,n= %d,bit* time= %ld,t= %20.10lf\n",// ch, (Chan[ch].epoch-ms)/256, ms, chip, phase, n,// Chan[ch].meas_bit_time % 50, transmit_time[n]);#if DBG_PRANGE if ( !fp_dbg_prange) { char tmpfile[64]; sprintf( tmpfile, "debug/pseudorange-%03d-%06ld.dat", gps_week, Ctrl->clock_tow); fp_dbg_prange = fopen( tmpfile, "w"); if ( !fp_dbg_prange) { printf( "error opening debug file %s\n", tmpfile); } } if ( fp_dbg_prange) fprintf( fp_dbg_prange, "%d %d %d %d %d %d %d %ld %20.10lf\n", ch, Chan[ch].prn, Chan[ch].epoch, ms, chip, phase, n, Chan[ch].meas_bit_time, transmit_time[n]);#endif#if 0 phase_counter = ( Chan[ch].carr_dco_phase_nav * 2) & 0x7ff; phase_counter += (Chan[ch].carr_cycle_l_nav << 11); phase_counter += (Chan[ch].carr_cycle_h_nav << 27);#endif if ( FpDmp) { phase_counter = ( NavData.carr_dco_phase[ch] * 2) & 0x7ff; phase_counter += (NavData.carr_cycle_lo[ch] << 11); phase_counter += (NavData.carr_cycle_hi[ch] << 27); write_msg_0x38( FpDmp, ch, transmit_time[n] * LIGHTVEL, phase_counter);#if 0 { gotoxy( 1, 22+ch); printf( "carr_dco = %d,", NavData.carr_dco_phase[ch]); printf( "carr_cycl_lo = %d, ", NavData.carr_cycle_lo[ch]); printf( "carr_cycl_hi = %d, ", NavData.carr_cycle_hi[ch]); printf( "phasecounter = %ld, ", phase_counter); printf( "\n"); }#endif }// gotoxy( 1, 24);// printf("*** transmit_time[%d] = %e *** \n", n, transmit_time[n]); n += 1; } // --- if () ... ---// else if ( Chan[ch].state == track)// {// printf( "(%d) valid = %d ", ch, GPS_Eph[Chan[ch].prn].valid);// printf( "health = %d ", GPS_Eph[Chan[ch].prn].health);// printf( "tow_sync = %d \n", Chan[ch].tow_sync);// } }// number of tracked satellites n_track = n - 1;// need at least four if ( n_track < 4) return; // *** FIXME: try a 2-dim nav solution for n_track == 3 *** transmit_time_max = -10.0; transmit_time_min = 10.0; for ( i=1; i<=n_track; i++) { if ( transmit_time[i] > transmit_time_max) transmit_time_max = transmit_time[i]; if ( transmit_time[i] < transmit_time_min) transmit_time_min = transmit_time[i]; }// check if nav_tic hit a boundary region if ( transmit_time_max - transmit_time_min > 0.5) { for ( i=1; i<=n_track; i++) { if ( transmit_time[i] - transmit_time_min > 0.5) transmit_time[i] -= 1.0; } }// default transmission time is 67 ms (30 000 km) transmit_time_max += 0.067; // if ( out_kalman)// fprintf( out, "%d\n", n_track);// if ( out_debug)// fprintf( stream, "%d\n", n_track); for ( i=1; i<=n_track; i++) { track_sat[i] = satpos_ephemeris( transmit_time[i], Chan[tr_ch[i]].prn); dm_gps_sat[i] = satpos_ephemeris( transmit_time[i]-0.5, Chan[tr_ch[i]].prn); dp_gps_sat[i] = satpos_ephemeris( transmit_time[i]+0.5, Chan[tr_ch[i]].prn);// if (out_debug)// fprintf( stream, "i=%d,az=%20.10lf,el=%20.10lf\n",// i, track_sat[i]. az, track_sat[i].el); t_cor[i] = track_sat[i].tb + tropo_iono( track_sat[i].az, track_sat[i].el, transmit_time[i]); dt[i] = transmit_time_max - (transmit_time[i] - t_cor[i]);// if (dt[i]>=1) printf("dt[%d]=%20.10lf\n",i,dt[i]);// if (out_debug)// fprintf( stream, "i=% d,tb= %20.10lf,tropo_iono= %20.10lf, dt= %20.10lf\n",// i,track_sat[i].tb,tropo_iono(track_sat[i].az,track_sat[i].el,transmit_time[i]),dt[i]);// if (out_debug)// fprintf( stream, "%20.10lf,%20.10lf,%20.10lf,%20.10lf\n",// track_sat[i].x,track_sat[i].y,track_sat[i].z,dt[i]); d_sat[i].x = dp_gps_sat[i].x - dm_gps_sat[i].x - track_sat[i].y*OMEGAE; d_sat[i].y = dp_gps_sat[i].y - dm_gps_sat[i].y + track_sat[i].x*OMEGAE; d_sat[i].z = dp_gps_sat[i].z - dm_gps_sat[i].z;// if ( out_kalman)// fprintf( out, "%20.10lf,%20.10lf,%20.10lf,%20.10lf\n",// track_sat[i].x,track_sat[i].y,track_sat[i].z,dt[i]);// if ( out_kalman)// fprintf( out,"%20.10lf,%20.10lf,%20.10lf,",// d_sat[i].x,d_sat[i].y,d_sat[i].z);// meas_dop[i] = (Chan[tr_ch[i]].doppler - 33010105l) * 42.574746268e-3; meas_dop[i] = (Chan[tr_ch[i]].carfrq - CARRIER_REF) * FREQRES;// if ( out_kalman)// fprintf( out, "%lf\n", meas_dop[i]); } // --- for (i=1; i<=n_track; i++) ---// calculate receiver position/velocity from pseudoranges rpvt = pos_vel_time( n_track, d_sat);// determine dilution of precision dops( n_track); cbias = rpvt.dt; clock_error = rpvt.df; time[1] = transmit_time[1] + dtime[1] - cbias; rp_ecef.x = rpvt.x; rp_ecef.y = rpvt.y; rp_ecef.z = rpvt.z; rp_llh = ecef_to_llh( rp_ecef);// a quick reasonableness check if ( rp_llh.hae > -2000.0 && rp_llh.hae < 1.0e6) { if ( fabs( clock_error) < 5.0) clock_offset = clock_error; if ( almanac_valid == 1) status = mode_navigate; rec_pos_llh.lon = rp_llh.lon; rec_pos_llh.lat = rp_llh.lat; rec_pos_llh.hae = rp_llh.hae; rec_pos_xyz.x = rp_ecef.x; rec_pos_xyz.y = rp_ecef.y; rec_pos_xyz.z = rp_ecef.z;// if ( out_pos)// fprintf(stream,"lat= %lf,long= %lf,hae= %lf,gdop= %f,hdop= %f,vdop= %f\n",// rec_pos_llh.lat*RAD2DEG,rec_pos_llh.lon*RAD2DEG,rec_pos_llh.hae,gdop,hdop,vdop);//// Since we have a valid position/velocity narrow the doppler search window// Ctrl->search_max_f = 5;//// Translate velocity into North, East, Up coordinates// velocity( rp_llh);// if ( out_kalman)// fprintf( out, " %20.10lf,%20.10lf,%20.10lf,%20.10lf\n",// rp_ecef.x, rp_ecef.y, rp_ecef.z, cbias);// if ( out_kalman)// fprintf( out, " %20.10lf,%20.10lf,%20.10lf,%10.10lf\n\n",// rpvt.xv,rpvt.yv,rpvt.zv,clock_error); time[0] = time[1]; } else { rec_pos_llh.lon = 0.0; rec_pos_llh.lat = 0.0; rec_pos_llh.hae = 0.0; rec_pos_xyz.x = 0.0; rec_pos_xyz.y = 0.0; rec_pos_xyz.z = 0.0; } return;}#endif/* ------------------------------- end of file ---------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -