www.pudn.com > opengpssim.zip > ogslibrary.c
/* ************************************************************************ * * * GPS Simulation * * * * -------------------------------------------------------------------- * * * * Module: ogslibrary.cpp * * * * Version: 0.1 * * * * Date: 02.03.02 * * * * Author: G. Beyerle * * * * -------------------------------------------------------------------- * * * * Copyright (C) 2002 Georg Beyerle * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * * * -------------------------------------------------------------------- * * * * The files 'gpsfuncs.cpp', 'gpsrcvr.cpp' and 'gp2021.cpp' are modi- * * fied versions of the files with the same name from Clifford Kelley's * * OpenSourceGPS distribution. The unmodified files can be obtained * * from http://www.home.earthlink.net/~cwkelley * * * * -------------------------------------------------------------------- * * * * Library routines for OpenSourceGPS GPS simulator * * * ************************************************************************ */ /* ******************************* changes ******************************** dd.mm.yy - ************************************************************************ */ /* ------------------------------- includes ------------------------------- */ #include#include #include #include #include #ifdef unix #include #endif #define OSGLIBRY_H #include "ogsdefine.h" #include "ogsstructs.h" #include "ogsextern.h" #include "ogslibrary.h" /* ------------------------------- defines -------------------------------- */ /* ------------------------------- globals -------------------------------- */ /* -------------------------- prototypes (global) ------------------------- */ static int exor_long( unsigned long x); /* ------------------------------ procedures ------------------------------ */ // // read key:value pair from parameter file // int read_key_value_pair_double( char *tok, char pattern[], double *val, char sep[]) { char *token; int ret = 0; if ( strstr( tok, pattern)) { token = strtok( NULL, sep); if ( token) { sscanf( token, "%e", val); printf( "%s = %f\n", pattern, *val); ret = 1; } } return (ret); } // // read key:value pair from parameter file // int read_key_value_pair_float( char *tok, char pattern[], float *val, char sep[]) { char *token; int ret = 0; if ( strstr( tok, pattern)) { token = strtok( NULL, sep); if ( token) { sscanf( token, "%f", val); printf( "%s = %f\n", pattern, *val); ret = 1; } } return (ret); } int read_key_value_pair_int( char *tok, char pattern[], int *val, char sep[]) { char *token; int ret = 0; if ( strstr( tok, pattern)) { token = strtok( NULL, sep); if ( token) { sscanf( token, "%d", val); printf( "%s = %d\n", pattern, *val); ret = 1; } } return (ret); } int read_key_value_pair_uint( char *tok, char pattern[], unsigned int *val, char sep[]) { char *token; int ret = 0; if ( strstr( tok, pattern)) { token = strtok( NULL, sep); if ( token) { sscanf( token, "%d", val); printf( "%s = %d\n", pattern, *val); ret = 1; } } return (ret); } int read_key_value_pair_long( char *tok, char pattern[], long *val, char sep[]) { char *token; int ret = 0; if ( strstr( tok, pattern)) { token = strtok( NULL, sep); if ( token) { sscanf( token, "%d", val); printf( "%s = %d\n", pattern, *val); ret = 1; } } return (ret); } // // create C/A code and write to global variable CACODE[][] // // adapted from MATLAB routine written by // Fredrik Johansson, Rahman Mollaei, Jonas Thor, Joergen Uusitalo // Lulea University of Technology, Sweden // http://www.sm.luth.se/csee/courses/sms/019/1998/navstar/navstar.html // void calc_cacode( void) { int prn; // 1,...,32 int s1, s2; int i, j, tmp; int tap[32][2] = {{2, 6}, {3, 7}, {4, 8}, {5, 9}, {1, 9}, {2, 10}, {1, 8}, {2, 9}, {3,10}, {2, 3}, {3, 4}, {5, 6}, {6, 7}, {7, 8}, {8, 9}, {9, 10}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {5, 8}, {6, 9}, {1, 3}, {4, 6}, {5, 7}, {6, 8}, {7, 9}, {8,10}, {1, 6}, {2, 7}, {3, 8}, {4, 9}}; // loop over all PRNs for ( prn=1; prn<=NOFSAT; prn++) { // initial state int g1[11] = {0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, // we don't use first element g2[11] = {0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; // select taps for G2 delay s1 = tap[prn-1][0]; s2 = tap[prn-1][1]; for ( i=0; i 1; j--) g1[j] = g1[j-1]; g1[1] = tmp; // Generator 2 - shift reg 2 (1+X^2+X^3+X^6+X^8+X^9+X^10) tmp = g2[2]*g2[3]*g2[6]*g2[8]*g2[9]*g2[10]; for ( j=10; j>1; j--) g2[j] = g2[j-1]; g2[1] = tmp; } } return; } #if 0 // // encode navigation data to array sf2[][] and copy to message[1500] buffer // void encode_navmess( char prn, char ch, int i4satid, int i5satid, IONODATA *iono, UTCDATA *utc) { char schar; short unsigned int sint; short int ssint; int k, j, sfr, word, isv; char uchar; unsigned long ulong; // clear subframe array for ( sfr=1; sfr<=5; sfr++) { for ( word=1; word<=10; word++) { sf2[sfr][word] = 0; } } // // copy ephemeris & almanac data to subframe array sf2[][] // // // EPHEMERIS ENCODE subframes 1 to 3 // // subframe 1 // // iodc = int(((sf2[1][3] & 0x3) <<8 ) | ((sf2[1][8] & 0xFF0000L) >> 16)); // iweek = int(sf2[1][3] >> 14); // gps_eph[prn].week = iweek; ulong = gps_eph[prn].week & 0x3FF; // 10 bits sf2[1][3] = sf2[1][3] | (ulong << 14); // iura = int(( sf2[1][3] & 0xF00 ) >> 8); // gps_eph[prn].ura = iura; ulong = gps_eph[prn].ura & 0xF; // 4 bits sf2[1][3] = sf2[1][3] | (ulong << 8); // ihealth = int(( sf2[1][3] & 0xFC ) >> 2); // gps_eph[prn].health = ihealth; ulong = gps_eph[prn].health & 0x3F; // 6 bits sf2[1][3] = sf2[1][3] | (ulong << 2); // iodc = int(((sf2[1][3] & 0x3) << 8 ) | ((sf2[1][8] & 0xFF0000L) >> 16)); ulong = gps_eph[prn].iodc & 0x300; // 10 bits, 2 MSB sf2[1][3] = sf2[1][3] | (ulong >> 8); ulong = gps_eph[prn].iodc & 0xFF; // 10 bits, 8 LSB sf2[1][8] = sf2[1][8] | (ulong << 16); // gps_eph[prn].iodc = iodc; // itgd = int( sf2[1][7] & 0xFF); // gps_eph[prn].tgd = itgd*4.656612873e-10; schar = char( gps_eph[prn].tgd/4.656612873e-10); // 8 bits, scale 2^-31 ulong = long( schar) & 0xFF; sf2[1][7] = sf2[1][7] | (ulong); // itoc = int( sf2[1][8] & 0xFFFF); // gps_eph[prn].toc = itoc*16.0; ulong = long( gps_eph[prn].toc/16.0) & 0xFFFF; // 16 bits sf2[1][8] = sf2[1][8] | (ulong); // iaf2 = int( sf2[1][9] >> 16); // gps_eph[prn].af2 = iaf2*2.775557562e-17; schar = char( gps_eph[prn].af2/2.775557562e-17); // 8 bits, scale 2^-55 ulong = long( schar) & 0xFF; sf2[1][9] = sf2[1][9] | (ulong << 16); // iaf1 = int( sf2[1][9] & 0xFFFF); // gps_eph[prn].af1 = iaf1*1.136868377e-13; ssint = int( gps_eph[prn].af1/1.136868377e-13); // 16 bits, scale 2^-43 ulong = long( ssint) & 0xFFFF; sf2[1][9] = sf2[1][9] | (ulong); // iaf0 = sf2[1][10] >> 2; // if ( bit_test_l( iaf0, 22)) // iaf0 = iaf0 | 0xFFC00000L; // gps_eph[prn].af0 = iaf0*4.656612873e-10; ulong = long(gps_eph[prn].af0/4.656612873e-10) & 0x3FFFFF; // 22 bits, scale 2^-31 if ( ulong & (0x1L << (22-1))) // test bit 22 ulong = ulong | 0xFFC00000L; sf2[1][10] = sf2[1][10] | (ulong << 2); // // subframe 2 // // icrs = int(sf2[2][3] & 0xFFFF); // gps_eph[prn].crs = icrs*.03125; ssint = int( gps_eph[prn].crs/.03125); // 16 bits, scale 2^-5 ulong = long( ssint) & 0xFFFF; sf2[2][3] = sf2[2][3] | (ulong); // idn = int(sf2[2][4] >> 8); // gps_eph[prn].dn = idn*1.136868377e-13*pi; ssint = int( gps_eph[prn].dn/(1.136868377e-13*pi)); // (Delta n) 16 bits, scale 2^-43, rad ulong = long( ssint) & 0xFFFF; sf2[2][4] = sf2[2][4] | (ulong << 8); // im0 = ((sf2[2][4] & 0xFF) << 24) | sf2[2][5]; // gps_eph[prn].ma = im0*4.656612873e-10*pi; ulong = long( gps_eph[prn].ma/(4.656612873e-10*pi)); // 32 bits, scale 2^-31, rad sf2[2][4] = sf2[2][4] | ((ulong & 0xFF000000) >> 24); sf2[2][5] = sf2[2][5] | (ulong & 0xFFFFFF); // icuc = int(sf2[2][6] >> 8); // gps_eph[prn].cuc = icuc*1.862645149e-9; ssint = int( gps_eph[prn].cuc/(1.862645149e-9)); // 16 bits, scale 2^-29 ulong = long( ssint) & 0xFFFF; sf2[2][6] = sf2[2][6] | (ulong << 8); // ie = ((sf2[2][6] & 0xFF) << 24) | sf2[2][7]; // gps_eph[prn].ety = ie*1.164153218e-10; ulong = long( gps_eph[prn].ety/(1.164153218e-10)); // 32 bits, scale 2^-33 sf2[2][6] = sf2[2][6] | ((ulong & 0xFF000000) >> 24); sf2[2][7] = sf2[2][7] | (ulong & 0xFFFFFF); // icus = int(sf2[2][8] >> 8); // gps_eph[prn].cus = icus*1.862645149e-9; ssint = int( gps_eph[prn].cus/1.862645149e-9); // 16 bits, scale 2^-29 ulong = long( ssint) & 0xFFFF; sf2[2][8] = sf2[2][8] | (ulong << 8); // isqra = (((sf2[2][8] & 0xFF) << 24) | sf2[2][9]); // gps_eph[prn].sqra = isqra*1.907348633e-6; // if (gps_eph[prn].sqra>0.0) // gps_eph[prn].wm = 19964981.84/pow(gps_eph[prn].sqra,3); ulong = long( gps_eph[prn].sqra/(1.907348633e-6)); // 32 bits, scale 2^-19 sf2[2][8] = sf2[2][8] | ((ulong & 0xFF000000) >> 24); sf2[2][9] = sf2[2][9] | (ulong & 0xFFFFFF); // itoe = int(sf2[2][10] >> 8); // gps_eph[prn].toe = itoe*16.; ssint = int( gps_eph[prn].toe/16.); // 16 bits, scale 2^4 ulong = long( ssint) & 0xFFFF; sf2[2][10] = sf2[2][10] | (ulong << 8); // // subframe 3 // // icic = int(sf2[3][3] >> 8); // gps_eph[prn].cic = icic*1.862645149e-9; ssint = int( gps_eph[prn].cic/1.862645149e-9); // 16 bits, scale 2^-29 ulong = long( ssint) & 0xFFFF; sf2[3][3] = sf2[3][3] | (ulong << 8); // iomega0 = ((sf2[3][3] & 0xFF) << 24) | sf2[3][4]; // gps_eph[prn].w0 = iomega0*4.656612873e-10*pi; ulong = long( gps_eph[prn].w0/(4.656612873e-10*pi)); // 32 bits, scale 2^-31, rad sf2[3][3] = sf2[3][3] | ((ulong & 0xFF000000) >> 24); sf2[3][4] = sf2[3][4] | (ulong & 0xFFFFFF); // icis = int(sf2[3][5] >> 8); // gps_eph[prn].cis = icis*1.862645149e-9; ssint = int( gps_eph[prn].cis/1.862645149e-9); // 16 bits, scale 2^-29 ulong = long( ssint) & 0xFFFF; sf2[3][5] = sf2[3][5] | (ulong << 8); // inc0 = ((sf2[3][5] & 0xFF) << 24) | sf2[3][6]; // gps_eph[prn].inc0 = inc0*4.656612873e-10*pi; ulong = long( gps_eph[prn].inc0/(4.656612873e-10*pi)); // 32 bits, scale 2^-31, rad sf2[3][5] = sf2[3][5] | ((ulong & 0xFF000000) >> 24); sf2[3][6] = sf2[3][6] | (ulong & 0xFFFFFF); // icrc = int(sf2[3][7] >> 8); // gps_eph[prn].crc = icrc*.03125; ssint = int( gps_eph[prn].crc/.03125); // 16 bits, scale 2^-5 ulong = long( ssint) & 0xFFFF; sf2[3][7] = sf2[3][7] | (ulong << 8); // iw = ((sf2[3][7] & 0xFF) << 24) | sf2[3][8]; // gps_eph[prn].w = iw*4.656612873e-10*pi; ulong = long( gps_eph[prn].w/(4.656612873e-10*pi)); // 32 bits, scale 2^-31, rad sf2[3][7] = sf2[3][7] | ((ulong & 0xFF000000) >> 24); sf2[3][8] = sf2[3][8] | (ulong & 0xFFFFFF); // iomegadot = sf2[3][9]; // if (bit_test_l(iomegadot,24)) // iomegadot = iomegadot | 0xFF000000L; // gps_eph[prn].omegadot = iomegadot*1.136868377e-13*pi; ulong = long(gps_eph[prn].omegadot/(1.136868377e-13*pi)) & 0xFFFFFF; // 24 bits, scale 2^-43, rad if ( ulong & (0x1L << (24-1))) // test bit 24 ulong = ulong | 0xFF000000L; sf2[3][9] = sf2[3][9] | (ulong << 2); // idot=int((sf2[3][10] & 0xFFFC) >> 2); // if (bit_test_l(idot,14)) // idot=idot | 0xC000; // gps_eph[prn].idot = idot*1.136868377e-13*pi; ssint = int( gps_eph[prn].idot/(1.136868377e-13*pi)); // 14 bits, scale 2^-43, rad ulong = long( ssint) & 0x3FFF; sf2[3][10] = sf2[3][10] | (ulong << 2); // // ALMANAC ENCODE subframes 4 and 5 // // SUBFRAME 4 // // i4p = int((sf2[4][3] & 0x3F0000L) >> 16); // if ( i4p != i4satid) // { // i4satid=i4p; ulong = i4satid & 0x3F; sf2[4][3] = sf2[4][3] | (ulong << 16); if (i4satid > 24 && i4satid < 33) { // // almanac data for satellite 25 thru 32 (frame 5, pages 2,3,4,5,7,8,9,10) // isv = i4satid; // gps_alm[isv].week=gps_week; // iae=int(sf2[4][3] & 0x00FFFFL); // gps_alm[isv].ety=iae*4.768371582E-7; ssint = int( gps_alm[isv].ety/(4.768371582E-7)); // 16 bits, scale 2^-21 ulong = long( ssint) & 0xFFFF; sf2[4][3] = sf2[4][3] | (ulong); // iatoa=int(sf2[4][4] >> 16); // gps_alm[isv].toa=iatoa*4096.0; schar = char( gps_alm[isv].toa/4096.0); // 8 bits, scale 2^12 ulong = long( schar) & 0xFF; sf2[4][4] = sf2[4][4] | (ulong << 16); // iadeli=sf2[4][4] & 0x00FFFFL; // if (bit_test_l(iadeli,16)) // iadeli=iadeli | 0xFFFF0000L; // gps_alm[isv].inc=(iadeli*1.907348633E-6+0.3)*pi; ssint = int( (gps_alm[isv].inc/pi-0.3)/1.907348633E-6); // 16 bits, scale 2^-19 ulong = long( ssint) & 0xFFFF; sf2[4][4] = sf2[4][4] | (ulong); // iomegad=int(sf2[4][5] >> 8); // gps_alm[isv].rra=iomegad*3.637978807E-12*pi; ssint = int( gps_alm[isv].rra/(3.637978807E-12*pi)); // 16 bits, scale 2^-38 ulong = long( ssint) & 0xFFFF; sf2[4][5] = sf2[4][5] | (ulong << 8); // gps_alm[isv].health=int(sf2[4][5] & 0x0000FF); ulong = long( gps_alm[isv].health) & 0xFF; sf2[4][5] = sf2[4][5] | (ulong); // iasqr=sf2[4][6]; // gps_alm[isv].sqa=iasqr*4.8828125E-4; // if (gps_alm[isv].sqa>0.0) // gps_alm[isv].w=19964981.84/pow(gps_alm[isv].sqa,3); ssint = int( gps_alm[isv].sqa/(4.8828125E-4)); // 16 bits, scale 2^-11 ulong = long( ssint) & 0xFFFF; sf2[4][6] = sf2[4][6] | (ulong); // iaomega0=sf2[4][7]; // if (bit_test_l(iaomega0,24)) // iaomega0=iaomega0 | 0xFF000000L; // gps_alm[isv].lan=iaomega0*1.192092896E-7*pi; ulong = long( gps_alm[isv].lan/(1.192092896E-7*pi)) & 0xFFFFFF; // 24 bits, scale 2^-23, rad if ( ulong & (0x1L << (24-1))) // test bit 24 ulong = ulong | 0xFF000000L; sf2[4][7] = sf2[4][7] | (ulong); // iaw=sf2[4][8]; // if (bit_test_l(iaw,24)) // iaw=iaw | 0xFF000000L; // gps_alm[isv].aop=iaw*1.192092896E-7*pi; ulong = long( gps_alm[isv].aop/(1.192092896E-7*pi)) & 0xFFFFFF; // 24 bits, scale 2^-23, rad if ( ulong & (0x1L << (24-1))) // test bit 24 ulong = ulong | 0xFF000000L; sf2[4][8] = sf2[4][8] | (ulong); // iam0=sf2[4][9]; // if (bit_test_l(iam0,24)) // iam0=iam0 | 0xFF000000L; // gps_alm[isv].ma=iam0*1.192092896E-7*pi; ulong = long( gps_alm[isv].ma/(1.192092896E-7*pi)) & 0xFFFFFF; // 24 bits, scale 2^-23, rad if ( ulong & (0x1L << (24-1))) // test bit 24 ulong = ulong | 0xFF000000L; sf2[4][9] = sf2[4][9] | (ulong); // iaaf0=(sf2[4][10] >> 13) | (sf2[4][10] & 0x1C); // if ( bit_test_l( iaaf0, 11)) // iaaf0=iaaf0 | 0xFFFFF800L; // gps_alm[isv].af0=iaaf0*9.536743164E-7; ulong = long( gps_alm[isv].af0/(9.536743164E-7)) & 0x7FF; // 11 bits, scale 2^-20 if ( ulong & (0x1L << (11-1))) // test bit 11 ulong = ulong | 0xFFFFF800L; sf2[4][10] = sf2[4][10] | ((ulong & 0x7) << 2); sf2[4][10] = sf2[4][10] | ((ulong & 0x7F8) << 13); // iaaf1=(sf2[4][10] | 0xFFE0) >> 5; // if (bit_test_l(iaaf1,11)) // iaaf1=iaaf1 | 0xFFFFF800L; // gps_alm[isv].af1=iaaf1*3.637978807E-12; ulong = long( gps_alm[isv].af1/(3.637978807E-12)) & 0x7FF; // 11 bits, scale 2^-38 if ( ulong & (0x1L << (11-1))) // test bit 11 ulong = ulong | 0xFFFFF800L; sf2[4][10] = sf2[4][10] | (ulong << 5); } else if ( i4satid == 55) { // // special messages (22 ASCII chars) (frame 4, page 17) // // gps_alm[prn].text_message[0]=char((sf2[4][3] & 0x00FF00) >> 8); ulong = long( gps_alm[prn].text_message[0]) & 0xFF; // 8 bits sf2[4][3] = sf2[4][3] | (ulong << 8); // gps_alm[prn].text_message[1]=char( sf2[4][3] & 0x0000FF); ulong = long( gps_alm[prn].text_message[1]) & 0xFF; // 8 bits sf2[4][3] = sf2[4][3] | (ulong); for ( k=1; k<=7; k++) { // gps_alm[prn].text_message[3*k-1] = char(sf2[4][k+3] >> 16); ulong = long( gps_alm[prn].text_message[3*k-1]) & 0xFF; // 8 bits sf2[4][k+3] = sf2[4][k+3] | (ulong << 16); // gps_alm[prn].text_message[3*k ] = char((sf2[4][k+3] & 0x00FF00) >> 8); ulong = long( gps_alm[prn].text_message[3*k]) & 0xFF; // 8 bits sf2[4][k+3] = sf2[4][k+3] | (ulong << 8); // gps_alm[prn].text_message[3*k+1] = char(sf2[4][k+3] & 0x0000FF); ulong = long( gps_alm[prn].text_message[3*k+1]) & 0xFF; // 8 bits sf2[4][k+3] = sf2[4][k+3] | (ulong); } } else if ( i4satid == 56) { // // ionospheric and UTC data (frame 4, page 18) // // ial0=int((sf2[4][3] & 0x00FF00) >> 8); // al0=ial0*9.313225746e-10; schar = char( iono->al0/(9.313225746e-10)); // 8 bits, scale 2^-30 ulong = long( schar) & 0xFF; sf2[4][3] = sf2[4][3] | (ulong << 8); // ial1= int(sf2[4][3] & 0x0000FF); // al1=ial1*7.4505806e-9; schar = char( iono->al1/(7.4505806e-9)); // 8 bits, scale 2^-27 ulong = long( schar) & 0xFF; sf2[4][3] = sf2[4][3] | (ulong); // ial2= int(sf2[4][4] >> 16); // al2=ial2*5.960464478e-8; schar = char( iono->al2/(5.960464478e-8)); // 8 bits, scale 2^-24 ulong = long( schar) & 0xFF; sf2[4][4] = sf2[4][4] | (ulong << 16); // ial3=int((sf2[4][4] & 0x00FF00) >> 8); // al3=ial3*5.960464478e-8; schar = char( iono->al3/(5.960464478e-8)); // 8 bits, scale 2^-24 ulong = long( schar) & 0xFF; sf2[4][4] = sf2[4][4] | (ulong << 8); // ibt0= int(sf2[4][4] & 0x0000FF); // b0=ibt0*2048.; schar = char( iono->b0/(2048.)); // 8 bits, scale 2^11 ulong = long( schar) & 0xFF; sf2[4][4] = sf2[4][4] | (ulong); // ibt1= int(sf2[4][5] >> 16); // b1=ibt1*16384.; schar = char( iono->b1/(16384.)); // 8 bits, scale 2^14 ulong = long( schar) & 0xFF; sf2[4][5] = sf2[4][5] | (ulong << 16); // ibt2=int((sf2[4][5] & 0x00FF00) >> 8); // b2=ibt2*65536.; schar = char( iono->b2/(65536.)); // 8 bits, scale 2^16 ulong = long( schar) & 0xFF; sf2[4][5] = sf2[4][5] | (ulong << 8); // ibt3= int(sf2[4][5] & 0x00FF); // b3=ibt3*65536.; schar = char( iono->b3/(65536.)); // 8 bits, scale 2^16 ulong = long( schar) & 0xFF; sf2[4][5] = sf2[4][5] | (ulong); // ia1= sf2[4][6]; // if (bit_test_l(ia1,24)) ia1=ia1 | 0xFF000000L; // a1=ia1*8.881784197e-16; ulong = long( utc->a1/(8.881784197e-16)) & 0xFFFFFF; // 24 bits, scale 2^-50 if ( ulong & (0x1L << (24-1))) // test bit 24 ulong = ulong | 0xFF000000L; sf2[4][6] = sf2[4][6] | (ulong); // ia0= (sf2[4][7] << 8) | (sf2[4][8] >> 16); // a0=ia0*9.31322574615e-10; ulong = long( utc->a0/(9.31322574615e-10)); // 32 bits, scale 2^-30 sf2[4][7] = sf2[4][7] | ((ulong & 0xFFFFFF00) >> 8); sf2[4][8] = sf2[4][8] | ((ulong & 0xFF) << 16); // itot= int((sf2[4][8] & 0x00FF00) >> 8); // tot=itot*4096; schar = char( utc->tot/(4096.)); // 8 bits, scale 2^12 ulong = long( schar) & 0xFF; sf2[4][8] = sf2[4][8] | (ulong << 8); // iWNt= int(sf2[4][8] & 0xFF); // WNt=iWNt; schar = char( utc->WNt); // 8 bits, scale 1 ulong = long( schar) & 0xFF; sf2[4][8] = sf2[4][8] | (ulong); // idtls= int(sf2[4][9] >> 16); // if (idtls > 128) idtls = idtls |0xFF00; // dtls=idtls; schar = char( utc->dtls); // 8 bits, scale 1 ulong = long( schar) & 0xFF; sf2[4][9] = sf2[4][9] | (ulong); // iWNlsf=int((sf2[4][9] & 0x00FF00) >> 8); // WNlsf=iWNlsf; schar = char( utc->WNlsf); // 8 bits, scale 1 ulong = long( schar) & 0xFF; sf2[4][9] = sf2[4][9] | (ulong << 8); // iDN = int(sf2[4][9] & 0x0000FF); // DN=iDN; schar = char( utc->DN); // 8 bits, scale 1 ulong = long( schar) & 0xFF; sf2[4][9] = sf2[4][9] | (ulong); // idtlsf= int(sf2[4][10] >> 16); // if (idtlsf >128) idtlsf=idtlsf |0xFF00; // dtlsf=idtlsf; schar = char( utc->dtlsf); // 8 bits, scale 1 ulong = long( schar) & 0xFF; sf2[4][9] = sf2[4][9] | (ulong << 16); } else if ( i4satid == 63 ) { // // satellite configuration for 32 satellites (frame 4, page 25) // // ASV[1] = int((sf2[4][3] & 0x00F000) >>12); // ASV[2]= int((sf2[4][3] & 0x000F00) >>8); // ASV[3]= int((sf2[4][3] & 0x0000F0) >>4); // ASV[4]= int( sf2[4][3] & 0x00000F); for ( k=2; k<6; k++) { sf2[4][3] = sf2[4][3] | (long( ASV[-1+k]) << (20-(4*k))); } // ASV[5]= int( sf2[4][4] >> 20); // ASV[6]= int((sf2[4][4] & 0x0F0000L) >>16); // ASV[7]= int((sf2[4][4] & 0x00F000) >>12); // ASV[8]= int((sf2[4][4] & 0x000F00) >> 8); // ASV[9]= int((sf2[4][4] & 0x0000F0) >> 4); // ASV[10]=int(sf2[4][4] & 0x00000F); for ( k=0; k<6; k++) { sf2[4][4] = sf2[4][4] | (long( ASV[5+k]) << (20-(4*k))); } // ASV[11]=int(sf2[4][5] >>20); // ASV[12]=int((sf2[4][5] & 0x0F0000L) >>16); // ASV[13]=int((sf2[4][5] & 0x00F000) >>12); // ASV[14]=int((sf2[4][5] & 0x000F00) >> 8); // ASV[15]=int((sf2[4][5] & 0x0000F0) >> 4); // ASV[16]=int(sf2[4][5] & 0x00000F); for ( k=0; k<6; k++) { sf2[4][5] = sf2[4][5] | (long( ASV[11+k]) << (20-(4*k))); } // ASV[17]=int(sf2[4][6] >>20); // ASV[18]=int((sf2[4][6] & 0x0F0000L) >>16); // ASV[19]=int((sf2[4][6] & 0x00F000) >>12); // ASV[20]=int((sf2[4][6] & 0x000F00) >> 8); // ASV[21]=int((sf2[4][6] & 0x0000F0) >> 4); // ASV[22]=int(sf2[4][6] & 0x00000F); for ( k=0; k<6; k++) { sf2[4][6] = sf2[4][6] | (long( ASV[17+k]) << (20-(4*k))); } // ASV[23]=int(sf2[4][7] >>20); // ASV[24]=int((sf2[4][7] & 0x0F0000L) >>16); // ASV[25]=int((sf2[4][7] & 0x00F000) >>12); // ASV[26]=int((sf2[4][7] & 0x000F00) >> 8); // ASV[27]=int((sf2[4][7] & 0x0000F0) >> 4); // ASV[28]=int( sf2[4][7] & 0x00000F); for ( k=0; k<6; k++) { sf2[4][7] = sf2[4][7] | (long( ASV[23+k]) << (20-(4*k))); } // ASV[29]=int( sf2[4][8] >>20); // ASV[30]=int((sf2[4][8] & 0x0F0000L) >>16); // ASV[31]=int((sf2[4][8] & 0x00F000) >>12); // ASV[32]=int((sf2[4][8] & 0x000F00) >> 8); for ( k=0; k<4; k++) { sf2[4][8] = sf2[4][8] | (long( ASV[29+k]) << (20-(4*k))); } // SVh[25]=int(sf2[4][8] & 0x00003F); // if( SVh[25]==0x3f) gps_alm[25].inc=0.0; sf2[4][8] = sf2[4][8] | (long( SVh[25])); // SVh[26]=int(sf2[4][9] >>18); // if( SVh[26]==0x3f) gps_alm[26].inc=0.0; sf2[4][9] = sf2[4][9] | (long( SVh[26]) << 18); // SVh[27]=int((sf2[4][9] & 0x03F000L) >>12); // if( SVh[27]==0x3f) gps_alm[27].inc=0.0; sf2[4][9] = sf2[4][9] | (long( SVh[27]) << 12); // SVh[28]=int((sf2[4][9] & 0x000FC0) >>6); // if( SVh[28]==0x3f) gps_alm[28].inc=0.0; sf2[4][9] = sf2[4][9] | (long( SVh[28]) << 6); // SVh[29]= int(sf2[4][9] & 0x00003F); // if( SVh[29]==0x3f) gps_alm[29].inc=0.0; sf2[4][9] = sf2[4][9] | (long( SVh[29])); // SVh[30]= int(sf2[4][10] >>18); // if( SVh[30]==0x3f) gps_alm[30].inc=0.0; sf2[4][10] = sf2[4][10] | (long( SVh[30]) << 18); // SVh[31]=int((sf2[4][10]& 0x03F000L) >>12); // if( SVh[31]==0x3f) gps_alm[31].inc=0.0; sf2[4][10] = sf2[4][10] | (long( SVh[31]) << 12); // SVh[32]=int((sf2[4][10]& 0x000FC0) >>6); // if( SVh[32]==0x3f) gps_alm[32].inc=0.0; sf2[4][10] = sf2[4][10] | (long( SVh[32]) << 6); } // // SUBFRAME 5 // // i5p = int((sf2[5][3] & 0x3F0000L) >> 16); // chan[ch].page5 = i5p; // if ( i5satid != i5p) // { // i5satid=i5p; if ( i5satid == 51 ) { // // satellite health data for sats 1 thru 24, almanac reference time, // and almanac reference week number (frame 5, page 25) // // iatoa = int((sf2[5][3] & 0xFF00) >>8); // atoa = iatoa*4096; // SVh[1] = int(sf2[5][4] >>18); // if( SVh[1]==0x3f) gps_alm[1].inc=0.0; // SVh[2] = int((sf2[5][4] & 0x03F000L)>>12); // if( SVh[2]==0x3f) gps_alm[2].inc=0.0; // SVh[3] = int((sf2[5][4] & 0x000FC0)>>6); // if( SVh[3]==0x3f) gps_alm[3].inc=0.0; // SVh[4] = int(sf2[5][4] & 0x00003F); // if( SVh[4]==0x3f) gps_alm[4].inc=0.0; for ( k=0; k<4; k++) { sf2[5][4] = sf2[5][4] | (long( SVh[1+k]) << (18-(6*k))); } // SVh[5] = int(sf2[5][5] >>18); // if( SVh[5]==0x3f) gps_alm[5].inc=0.0; // SVh[6] = int((sf2[5][5] & 0x03F000L)>>12); // if( SVh[6]==0x3f) gps_alm[6].inc=0.0; // SVh[7] = int((sf2[5][5] & 0x000FC0)>>6); // if( SVh[7]==0x3f) gps_alm[7].inc=0.0; // SVh[8] = int(sf2[5][5] & 0x00003F); // if( SVh[8]==0x3f) gps_alm[8].inc=0.0; for ( k=0; k<4; k++) { sf2[5][5] = sf2[5][5] | (long( SVh[5+k]) << (18-(6*k))); } // SVh[9] = int(sf2[5][6] >> 18); // if( SVh[9]==0x3f) gps_alm[9].inc=0.0; // SVh[10] = int((sf2[5][6] & 0x03F000L)>>12); // if( SVh[10]==0x3f) gps_alm[10].inc=0.0; // SVh[11] = int((sf2[5][6] & 0x000FC0)>>6); // if( SVh[11]==0x3f) gps_alm[11].inc=0.0; // SVh[12] = int(sf2[5][6] & 0x00003F); // if( SVh[12]==0x3f) gps_alm[12].inc=0.0; for ( k=0; k<4; k++) { sf2[5][6] = sf2[5][6] | (long( SVh[9+k]) << (18-(6*k))); } // SVh[13] = int(sf2[5][7] >>18); // if( SVh[13]==0x3f) gps_alm[13].inc=0.0; // SVh[14] = int((sf2[5][7] & 0x03F000L)>>12); // if( SVh[14]==0x3f) gps_alm[14].inc=0.0; // SVh[15] = int((sf2[5][7] & 0x000FC0)>>6); // if( SVh[15]==0x3f) gps_alm[15].inc=0.0; // SVh[16] = int(sf2[5][7] & 0x00003F); // if( SVh[16]==0x3f) gps_alm[16].inc=0.0; for ( k=0; k<4; k++) { sf2[5][7] = sf2[5][7] | (long( SVh[13+k]) << (18-(6*k))); } // SVh[17] = int(sf2[5][8] >>18); // if( SVh[17]==0x3f) gps_alm[17].inc=0.0; // SVh[18] = int((sf2[5][8] & 0x03F000L)>>12); // if( SVh[18]==0x3f) gps_alm[18].inc=0.0; // SVh[19] = int((sf2[5][8] & 0x000FC0)>>6); // if( SVh[19]==0x3f) gps_alm[19].inc=0.0; // SVh[20] = int(sf2[5][8] & 0x00003F); // if( SVh[20]==0x3f) gps_alm[20].inc=0.0; for ( k=0; k<4; k++) { sf2[5][8] = sf2[5][8] | (long( SVh[17+k]) << (18-(6*k))); } // SVh[21] = int(sf2[5][9] >>18); // if( SVh[21]==0x3f) gps_alm[21].inc=0.0; // SVh[22] = int((sf2[5][9] & 0x03F000L)>>12); // if( SVh[22]==0x3f) gps_alm[22].inc=0.0; // SVh[23] = int((sf2[5][9] & 0x000FC0)>>6); // if( SVh[23]==0x3f) gps_alm[23].inc=0.0; // SVh[24] = int(sf2[5][9] & 0x00003F); // if( SVh[24]==0x3f) gps_alm[24].inc=0.0; for ( k=0; k<4; k++) { sf2[5][9] = sf2[5][9] | (long( SVh[21+k]) << (18-(6*k))); } } else { // // almanac data for satellite 1 thru 24 (frame 5, pages 1-24) // isv = i5satid; // gps_alm[isv].week=gps_week; // iae=int(sf2[5][3] & 0xFFFF); // gps_alm[isv].ety=iae*4.768371582E-7; // iatoa=int(sf2[5][4] >> 16); // gps_alm[isv].toa=iatoa*4096.0; // iadeli=int(sf2[5][4] & 0xFFFF); // gps_alm[isv].inc=(iadeli*1.907348633E-6+0.3)*pi; // iaomegad=int(sf2[5][5] >> 8); // gps_alm[isv].rra=iaomegad*3.637978807E-12*pi; // gps_alm[isv].health=int(sf2[5][5] & 0xFF); // iasqr=sf2[5][6]; // gps_alm[isv].sqa=iasqr*4.8828125E-4; // if (gps_alm[isv].sqa>0.0) gps_alm[isv].w=19964981.84/pow(gps_alm[isv].sqa,3); // iaomega0=sf2[5][7]; // if (bit_test_l(iaomega0,24)) iaomega0=iaomega0 | 0xFF000000L; // gps_alm[isv].lan=iaomega0*1.192092896E-7*pi; // iaw=sf2[5][8]; // if (bit_test_l(iaw,24)) iaw=iaw | 0xFF000000L; // gps_alm[isv].aop=iaw*1.192092896E-7*pi; // iam0=sf2[5][9]; // if (bit_test_l(iam0,24)) iam0=iam0 | 0xFF000000L; // gps_alm[isv].ma=iam0*1.192092896E-7*pi; // iaaf0=int((sf2[5][10] >> 13) | (sf2[5][10] & 0x1C)); // if (bit_test_l(iaaf0,11)) iaaf0=iaaf0 | 0xF800; // gps_alm[isv].af0=iaaf0*9.536743164E-7; // iaaf1=int((sf2[5][10] & 0xFFE0) >> 5); // if (bit_test_l(iaaf1,11)) // iaaf1=iaaf1 | 0xF800; // gps_alm[isv].af1=iaaf1*3.637978807E-12; // // copied from subframe4, pages 1-24 // ssint = int( gps_alm[isv].ety/(4.768371582E-7)); // 16 bits, scale 2^-21 ulong = long( ssint) & 0xFFFF; sf2[5][3] = sf2[5][3] | (ulong); schar = char( gps_alm[isv].toa/4096.0); // 8 bits, scale 2^12 ulong = long( schar) & 0xFF; sf2[5][4] = sf2[5][4] | (ulong << 16); ssint = int( (gps_alm[isv].inc/pi-0.3)/1.907348633E-6); // 16 bits, scale 2^-19 ulong = long( ssint) & 0xFFFF; sf2[5][4] = sf2[5][4] | (ulong); ssint = int( gps_alm[isv].rra/(3.637978807E-12*pi)); // 16 bits, scale 2^-38 ulong = long( ssint) & 0xFFFF; sf2[5][5] = sf2[5][5] | (ulong << 8); ulong = long( gps_alm[isv].health) & 0xFF; sf2[5][5] = sf2[5][5] | (ulong); ssint = int( gps_alm[isv].sqa/(4.8828125E-4)); // 16 bits, scale 2^-11 ulong = long( ssint) & 0xFFFF; sf2[5][6] = sf2[5][6] | (ulong); ulong = long( gps_alm[isv].lan/(1.192092896E-7*pi)) & 0xFFFFFF; // 24 bits, scale 2^-23, rad if ( ulong & (0x1L << (24-1))) // test bit 24 ulong = ulong | 0xFF000000L; sf2[5][7] = sf2[5][7] | (ulong); ulong = long( gps_alm[isv].aop/(1.192092896E-7*pi)) & 0xFFFFFF; // 24 bits, scale 2^-23, rad if ( ulong & (0x1L << (24-1))) // test bit 24 ulong = ulong | 0xFF000000L; sf2[5][8] = sf2[5][8] | (ulong); ulong = long( gps_alm[isv].ma/(1.192092896E-7*pi)) & 0xFFFFFF; // 24 bits, scale 2^-23, rad if ( ulong & (0x1L << (24-1))) // test bit 24 ulong = ulong | 0xFF000000L; sf2[5][9] = sf2[5][9] | (ulong); ulong = long( gps_alm[isv].af0/(9.536743164E-7)) & 0x7FF; // 11 bits, scale 2^-20 if ( ulong & (0x1L << (11-1))) // test bit 11 ulong = ulong | 0xFFFFF800L; sf2[5][10] = sf2[5][10] | ((ulong & 0x7) << 2); sf2[5][10] = sf2[5][10] | ((ulong & 0x7F8) << 13); ulong = long( gps_alm[isv].af1/(3.637978807E-12)) & 0x7FF; // 11 bits, scale 2^-38 if ( ulong & (0x1L << (11-1))) // test bit 11 ulong = ulong | 0xFFFFF800L; sf2[5][10] = sf2[5][10] | (ulong << 5); } // // add to each 24 bit word 6 parity bits // add_parity_bits(); // // 5 subframe a 300 bits; 10 words a 30 bits // // copy from sf2[][] to chan[ch].message[1500] buffer unsigned long scale; j=0; for ( sfr=1; sfr<=5; sfr++) { for ( word=1; word<=10; word++) { // scale = 536870912L; // 536870912L = 2^29 scale = 0x1L << 29; // sf2[sfr][word] = 0; for ( k=0; k<=29; k++) { // if ( chan[ch].message[(j+chan[ch].offset)%1500] == 1) // sf2[sfr][word] += scale; if ( sf2[sfr][word] & scale) chan[ch].message[(j+chan[ch].offset)%1500] = 1; else chan[ch].message[(j+chan[ch].offset)%1500] = -1; scale = scale >> 1; j++; } } } // --- for ( sfr=1; sfr<=5; sfr++) --- return; } // // add 6 parity bits to sf2[][] // // based on gpsrcvr.cpp/parity_check() // Clifford Kelley cwkelley@earthlink.net // Copyright (c) 1996-2001 Clifford Kelley // void add_parity_bits( void) { unsigned long x; int parity; char d29=1, d30=1, // assume that last 2 bits from last frame are one sfm, word, b1, b2, b3, b4, b5, b6; long mask1 = 0xEC7CD2L, mask2 = 0x763E69L, mask3 = 0xBB1F34L, mask4 = 0x5D8F9AL, mask5 = 0xAEC7CDL, mask6 = 0x2DEA27L; for ( sfm = 1; sfm <= 5; sfm++) { for ( word=1; word<=10; word++) { x = (sf2[sfm][word] & mask1) | (d29 << 31); // bit 31 of sf2[][] is unused b1 = exor_long( x) << 5; x = (sf2[sfm][word] & mask2) | (d30 << 31); // bit 31 of sf2[][] is unused b2 = exor_long( x) << 4; x = (sf2[sfm][word] & mask3) | (d29 << 31); // bit 31 of sf2[][] is unused b3 = exor_long( x) << 3; x = (sf2[sfm][word] & mask4) | (d30 << 31); // bit 31 of sf2[][] is unused b4 = exor_long( x) << 2; x = (sf2[sfm][word] & mask5) | (d30 << 31); // bit 31 of sf2[][] is unused b5 = exor_long( x) << 1; x = (sf2[sfm][word] & mask6) | (d29 << 31); // bit 31 of sf2[][] is unused b6 = exor_long( x); parity = b1 + b2 + b3 + b4 + b5 + b6; if ( d30 == 1) sf2[sfm][word] = ~sf2[sfm][word] & 0x03fffffc0L; // add 6 parity bits sf2[sfm][word] = (sf2[sfm][word] << 6) | (parity & 0x3F); // update d29/d30 bits d29 = (parity & 0x2) >> 1; d30 = parity & 0x1; } } } // // xor all 32 bits in a long variable (b31^b30^b29^...^b2^b1^b0) // static int exor_long( unsigned long x) { char i; int res = 0; for ( i=0; i<32; i++) { res = res ^ (x & 0x1); x = x >> 1; } return res; } inline double frem( double x, double y) { double res; if ( x >= 0.0) res = fmod( x, y); else res = -fmod( -x, y); return res; } #endif /******************************************************************************* FUNCTION bit_test_long() RETURNS int PARAMETERS Data bit_n PURPOSE This function returns a 1 if bit number bit_n of long Data is set else it returns a 0 NOTE: bit_n = 1,...,32 WRITTEN BY Clifford Kelley *******************************************************************************/ int bit_test_long( unsigned long data, int bit_n) { return ( data & (0x1L << (bit_n-1))); } /******************************************************************************* FUNCTION parity_exor_7to30( int bit, long parity) RETURNS GPS parity PARAMETERS parity : long word to be processed PURPOSE xor bits 7 to 30 in nav msg word and xor result with parameter 'bit' WRITTEN BY Clifford Kelley *******************************************************************************/ int parity_exor_7to30( int bit, long parity) { int i; int res = 0; for ( i=7; i<=30; i++) { if ( bit_test_long( parity, i)) res++; } // res = res % 2; res = (bit^res) & 0x1; return (res); } // // controlled malloc() // char *conmalloc( size_t len) { char *ptr; ptr = (char*) malloc( len); if ( !ptr) { printf( "malloc() failed!\n"); exit(-1); } return (ptr); } #define DIRBUFLEN 512 // // extract position of 'bin' and 'data' dir and write to global variable // void set_directories( char *ptr) { char *ptr2, *ptr3; #ifdef unix // if relative pathname we need to add current working dir if ( ptr[0] != '/') { char workdir[DIRBUFLEN]; ptr2 = getcwd( workdir, DIRBUFLEN); if ( !ptr2 || strlen( workdir)+strlen( ptr) > DIRBUFLEN-1) { printf( "Increase dir buffer size!\n"); exit(-1); } strcat( workdir, "/"); strcat( workdir, ptr); ptr = workdir; } #endif // printf(">%s<\n", ptr); // getchar(); OGSBinDir = (char*) conmalloc( strlen( ptr) + 1); OGSDataDir = (char*) conmalloc( strlen( ptr) + 1); strcpy( OGSBinDir, ptr); // printf("%s\n", OGSBinDir); #ifdef __TURBOC__ ptr2 = OGSBinDir; while ( *ptr2) { if (*ptr2 == '\\') *ptr2 = '/'; ptr2++; } #endif // printf( "%s\n", OGSBinDir); ptr2 = strrchr( OGSBinDir, '/'); if ( !ptr2) { printf( "invalid OGS directory structure! (%s)\n", OGSBinDir); exit(-1); } *ptr2 = '\0'; strcpy( OGSDataDir, OGSBinDir); ptr2 = strrchr( OGSDataDir, '/'); if ( !ptr2) { printf( "invalid OGS directory structure! (%s)\n", OGSBinDir); exit(-1); } *ptr2 = '\0'; strcat( OGSBinDir, "/"); strcat( OGSDataDir, "/data/"); // printf("%s\n", OGSBinDir); // printf("%s\n", OGSDataDir); // getchar(); return; } #ifndef __TURBOC__ void clrscr( void) { printf( "\x1B[2J\x1B[0d\x1B[0G"); return; } void gotoxy( int x, int y) { printf( "\x1B[%dd \x1B[%dG", y, x); return; } // don't know how to do these... #ifdef linux // // from kbhit.c, WROX book "Beginning LINUX Programming" (www.wrox.com) // #include #include #include #include static struct termios initial_settings, new_settings; static int peek_character = -1; void init_keyboard( void) { tcgetattr( 0, &initial_settings); new_settings = initial_settings; new_settings.c_lflag &= ~ICANON; new_settings.c_lflag &= ~ECHO; new_settings.c_lflag &= ~ISIG; new_settings.c_cc[VMIN] = 1; new_settings.c_cc[VTIME] = 0; tcsetattr( 0, TCSANOW, &new_settings); } void close_keyboard( void) { tcsetattr(0, TCSANOW, &initial_settings); } int kbhit( void) { char ch; int nread; if ( peek_character != -1) return 1; new_settings.c_cc[VMIN]=0; tcsetattr( 0, TCSANOW, &new_settings); nread = read(0,&ch,1); new_settings.c_cc[VMIN]=1; tcsetattr( 0, TCSANOW, &new_settings); if ( nread == 1) { peek_character = ch; return 1; } return 0; } int readch( void) { char ch; if ( peek_character != -1) { ch = peek_character; peek_character = -1; return ch; } read( 0, &ch, 1); return ch; } #else // not linux int kbhit( void) { return 0; } char getch( void) { return '0'; } #endif #endif /* ------------------------------ end of file ----------------------------- */